Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/web/src/components/ComposerPromptEditorTiptap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1839,7 +1839,7 @@ function ComposerPromptEditorTiptapInner(
{isEmpty && contextRecords.size === 0 && placeholder ? (
<div
className={cn(
"pointer-events-none absolute inset-0 leading-relaxed text-placeholder/75",
"pointer-events-none absolute inset-0 leading-relaxed text-placeholder",
placeholderClassName,
)}
>
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/components/chat/ComposerSurface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ function Shell({
);
}

// Focus sets the border directly so named themes, which override the outline variable, still show it.
const outlineClasses =
"after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:border after:border-(--chat-composer-outline) dark:after:inset-shadow-2xs dark:after:inset-shadow-(color:--chat-composer-highlight)";
"after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:border after:border-(--chat-composer-outline) dark:after:inset-shadow-2xs dark:after:inset-shadow-(color:--chat-composer-highlight) group-has-[[contenteditable]:focus]/composer-surface:after:border-ring/65 dark:group-has-[[contenteditable]:focus]/composer-surface:after:border-ring/90";

const contextSeamClasses =
"group-data-with-context/composer-surface:after:[clip-path:polygon(0_0,100%_0,100%_100%,calc(100%-22px)_100%,calc(100%-22px)_calc(100%-2px),22px_calc(100%-2px),22px_100%,0_100%)]";
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/components/settings/SettingsSidebarNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) {
aria-selected={index === activeResultIndex}
tabIndex={-1}
size="sm"
variant="option"
isActive={index === activeResultIndex}
className="h-auto min-h-10 items-start"
onMouseMove={() => setActiveResultIndex(index)}
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/sidebar/SidebarThreadRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -896,9 +896,9 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP
!props.isActive &&
"[&:not(:hover):not(:focus-within)_*]:text-secondary-label/70",
props.isActive
? "bg-sidebar-row-active text-sidebar-foreground light:shadow-xs light:ring-1 light:ring-inset light:ring-sidebar-border/70"
? "bg-sidebar-row-active text-sidebar-foreground light:shadow-xs light:ring-1 light:ring-inset light:ring-sidebar-row-ring light:sidebar-row-tinted-text"
: isSelected || props.sweepAction !== null
? "bg-sidebar-row-selected text-sidebar-foreground light:ring-1 light:ring-inset light:ring-sidebar-border/70"
? "bg-sidebar-row-selected text-sidebar-foreground light:ring-1 light:ring-inset light:ring-sidebar-row-ring light:sidebar-row-tinted-text"
: hasUnsentDraft
? cn(draftSurfaceClassName, "text-sidebar-foreground")
: shouldRecede
Expand Down
9 changes: 6 additions & 3 deletions apps/web/src/components/ui/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
}

const sidebarMenuButtonVariants = cva(
"peer/menu-button flex w-full cursor-pointer items-center gap-[var(--sidebar-control-gap)] overflow-hidden text-left outline-hidden ring-ring transition-[width,height,padding] hover:bg-sidebar-row-hover hover:text-sidebar-foreground focus-visible:ring-2 focus-visible:ring-inset active:bg-sidebar-row-active active:text-sidebar-foreground disabled:pointer-events-none disabled:opacity-64 aria-disabled:pointer-events-none aria-disabled:opacity-64 data-[active=true]:bg-sidebar-row-selected data-[active=true]:font-medium data-[active=true]:text-sidebar-foreground data-[state=open]:hover:bg-sidebar-row-hover data-[state=open]:hover:text-sidebar-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-[var(--sidebar-content-inset)]! [&>span:last-child]:truncate [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0 [&>svg]:text-[var(--sidebar-icon-color)] hover:[&>svg]:text-sidebar-foreground active:[&>svg]:text-sidebar-foreground data-[active=true]:[&>svg]:text-sidebar-foreground",
"peer/menu-button flex w-full cursor-pointer items-center gap-[var(--sidebar-control-gap)] overflow-hidden text-left outline-hidden ring-ring transition-[width,height,padding] hover:bg-sidebar-row-hover hover:text-sidebar-foreground focus-visible:ring-2 focus-visible:ring-inset active:bg-sidebar-row-hover active:text-sidebar-foreground disabled:pointer-events-none disabled:opacity-64 aria-disabled:pointer-events-none aria-disabled:opacity-64 data-[active=true]:bg-sidebar-row-active data-[active=true]:font-medium data-[active=true]:text-sidebar-foreground data-[state=open]:hover:bg-sidebar-row-hover data-[state=open]:hover:text-sidebar-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-[var(--sidebar-content-inset)]! [&>span:last-child]:truncate [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0 [&>svg]:text-[var(--sidebar-icon-color)] hover:[&>svg]:text-sidebar-foreground active:[&>svg]:text-sidebar-foreground data-[active=true]:[&>svg]:text-sidebar-foreground",
{
defaultVariants: {
size: "default",
Expand All @@ -699,6 +699,9 @@ const sidebarMenuButtonVariants = cva(
variant: {
default: "font-medium text-sidebar-muted-foreground/80",
outline: "bg-sidebar-control-surface ring-1 ring-sidebar-border",
// Listbox results: the highlight follows the pointer, so it stays neutral; blue marks the current page.
option:
"font-medium text-sidebar-muted-foreground/80 data-[active=true]:bg-sidebar-row-hover",
},
},
},
Expand Down Expand Up @@ -795,8 +798,8 @@ function SidebarMenuSubButton({
}) {
const defaultProps = {
className: cn(
"-translate-x-px flex h-7 min-w-0 cursor-pointer items-center gap-2 overflow-hidden rounded-lg px-2 text-sidebar-foreground outline-hidden ring-ring hover:bg-sidebar-row-hover hover:text-sidebar-foreground focus-visible:ring-2 focus-visible:ring-inset active:bg-sidebar-row-active active:text-sidebar-foreground disabled:pointer-events-none disabled:opacity-64 aria-disabled:pointer-events-none aria-disabled:opacity-64 [&>span:last-child]:truncate [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-muted-foreground",
"data-[active=true]:bg-sidebar-row-selected data-[active=true]:text-sidebar-foreground",
"-translate-x-px flex h-7 min-w-0 cursor-pointer items-center gap-2 overflow-hidden rounded-lg px-2 text-sidebar-foreground outline-hidden ring-ring hover:bg-sidebar-row-hover hover:text-sidebar-foreground focus-visible:ring-2 focus-visible:ring-inset active:bg-sidebar-row-hover active:text-sidebar-foreground disabled:pointer-events-none disabled:opacity-64 aria-disabled:pointer-events-none aria-disabled:opacity-64 [&>span:last-child]:truncate [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-muted-foreground",
"data-[active=true]:bg-sidebar-row-active data-[active=true]:text-sidebar-foreground",
size === "sm" && "text-xs",
size === "md" && "text-sm",
"group-data-[collapsible=icon]:hidden",
Expand Down
105 changes: 87 additions & 18 deletions apps/web/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--color-sidebar-row-hover: var(--sidebar-row-hover);
--color-sidebar-row-active: var(--sidebar-row-active);
--color-sidebar-row-selected: var(--sidebar-row-selected);
--color-sidebar-row-ring: var(--sidebar-row-ring);
--color-sidebar-border: var(--contrast-sidebar-border);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
Expand Down Expand Up @@ -339,6 +340,41 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
}
}

/* Tinted current rows: muted text steps toward the foreground to keep 4.5:1
on the light accent fill, inside the same contrast wrap as other text. */
@utility sidebar-row-tinted-text {
--contrast-secondary-label: color-mix(
in oklab,
color-mix(
in oklab,
color-mix(in oklab, var(--secondary-label), var(--sidebar-foreground) 30%)
var(--appearance-contrast-base),
var(--background)
),
var(--appearance-contrast-target) var(--appearance-contrast-boost)
);
--contrast-muted-foreground: color-mix(
in oklab,
color-mix(
in oklab,
color-mix(in oklab, var(--muted-foreground), var(--sidebar-foreground) 30%)
var(--appearance-contrast-base),
var(--background)
),
var(--appearance-contrast-target) var(--appearance-contrast-boost)
);
--contrast-sidebar-muted-foreground: color-mix(
in oklab,
color-mix(
in oklab,
color-mix(in oklab, var(--sidebar-muted-foreground), var(--sidebar-foreground) 30%)
var(--appearance-contrast-base),
var(--sidebar)
),
var(--appearance-contrast-target) var(--appearance-contrast-boost)
);
}

@utility surface-glass {
background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
Expand Down Expand Up @@ -1123,6 +1159,8 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--message-action: var(--primary);
--message-action-foreground: var(--primary-foreground);
--message-action-hover: color-mix(in srgb, var(--primary) 90%, var(--background));
/* Links share the action color so blue always means "clickable". */
--link: var(--primary);
--accent: var(--color-zinc-100);
--accent-foreground: var(--color-zinc-900);
--error: var(--color-red-500);
Expand Down Expand Up @@ -1155,8 +1193,10 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--sidebar-muted-foreground: var(--muted-foreground);
--sidebar-control-surface: var(--color-zinc-100);
--sidebar-row-hover: var(--color-zinc-25);
--sidebar-row-active: var(--color-white);
--sidebar-row-selected: var(--color-white);
/* The current row and settings page carry the accent: blue means "you are here". */
--sidebar-row-active: color-mix(in oklab, var(--primary) 18%, var(--color-white));
--sidebar-row-selected: color-mix(in oklab, var(--primary) 12%, var(--color-white));
--sidebar-row-ring: color-mix(in oklab, var(--primary) 35%, transparent);
--sidebar-border: var(--border);
--sidebar-stage-fade: var(--sidebar);
--code-background: color-mix(in srgb, var(--card) 90%, var(--background));
Expand All @@ -1168,16 +1208,17 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil

@variant dark {
color-scheme: dark;
/* Keep controls and floating surfaces close to the neutral-black canvas.
Borders and hover states provide separation without milky gray fills. */
/* Raised surfaces (composer, cards, popovers) sit one step above the
neutral-black canvas; menus separate by border and shadow. */
--background: var(--color-neutral-950);
--surface-raised: color-mix(in srgb, var(--background) 97%, var(--color-white));
--surface-raised: color-mix(in srgb, var(--background) 93%, var(--color-white));
--foreground: var(--color-neutral-100);
--card: color-mix(in srgb, var(--background) 97%, var(--color-white));
--card: color-mix(in srgb, var(--background) 93%, var(--color-white));
--card-foreground: var(--color-neutral-100);
--popover: color-mix(in srgb, var(--background) 97%, var(--color-white));
--popover: color-mix(in srgb, var(--background) 93%, var(--color-white));
--popover-foreground: var(--color-neutral-100);
--primary: oklch(0.571 0.21 264);
--link: color-mix(in oklab, var(--primary), var(--color-white) 28%);
--secondary: --alpha(var(--color-white) / 3%);
--secondary-foreground: var(--color-neutral-100);
--muted: --alpha(var(--color-white) / 3%);
Expand All @@ -1197,20 +1238,22 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--warning-surface: color-mix(in srgb, var(--warning) 16%, transparent);
--update-foreground: var(--color-blue-400);
--update-surface: color-mix(in srgb, var(--update) 18%, transparent);
--sidebar: var(--card);
/* Sidebar surfaces outside [data-app-sidebar] (mobile sheet) keep the flat
step instead of following the lifted card. */
--sidebar: color-mix(in srgb, var(--background) 97%, var(--color-white));
--sidebar-control-surface: var(--muted);
--sidebar-row-hover: var(--accent);
--sidebar-row-active: var(--accent);
--sidebar-row-selected: var(--muted);
--sidebar-stage-fade: var(--card);
--sidebar-row-active: color-mix(in oklab, var(--primary) 24%, transparent);
--sidebar-row-selected: color-mix(in oklab, var(--primary) 14%, transparent);
--sidebar-stage-fade: var(--sidebar);
--terminal-cursor: rgb(180 203 255);
--terminal-selection-background: rgb(180 203 255 / 25%);
}
}

/* Keep both sidebar implementations (default and legacy) on the same quiet
zinc hierarchy: zinc-50 navigation, zinc-25 hover, and white selected/raised
surfaces. */
zinc hierarchy: zinc-50 navigation, zinc-25 hover, white raised surfaces,
and accent-tinted current rows. */
[data-app-sidebar] {
--background: var(--color-zinc-25);
--foreground: var(--color-zinc-900);
Expand All @@ -1227,8 +1270,9 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--sidebar-muted-foreground: var(--color-zinc-500);
--sidebar-control-surface: var(--color-zinc-100);
--sidebar-row-hover: var(--color-zinc-25);
--sidebar-row-active: var(--color-white);
--sidebar-row-selected: var(--color-white);
--sidebar-row-active: color-mix(in oklab, var(--primary) 18%, var(--color-white));
--sidebar-row-selected: color-mix(in oklab, var(--primary) 12%, var(--color-white));
--sidebar-row-ring: color-mix(in oklab, var(--primary) 35%, transparent);
--sidebar-border: var(--color-zinc-200);
--sidebar-stage-fade: var(--sidebar);

Expand All @@ -1248,8 +1292,8 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--sidebar-muted-foreground: var(--muted-foreground);
--sidebar-control-surface: var(--muted);
--sidebar-row-hover: color-mix(in srgb, var(--contrast-foreground) 8%, transparent);
--sidebar-row-active: color-mix(in srgb, var(--contrast-foreground) 11%, transparent);
--sidebar-row-selected: color-mix(in srgb, var(--contrast-foreground) 7%, transparent);
--sidebar-row-active: color-mix(in oklab, var(--primary) 24%, transparent);
--sidebar-row-selected: color-mix(in oklab, var(--primary) 14%, transparent);
--sidebar-border: var(--border);
--sidebar-stage-fade: var(--card);
}
Expand Down Expand Up @@ -1283,6 +1327,9 @@ html[data-theme-id]:not([data-theme-id=""]) {
a distinct action color make these identical. */
--primary: var(--app-theme-message-action);
--primary-foreground: var(--app-theme-message-action-foreground);
/* Theme action colors are tuned for filled buttons, not text, so themed
links keep the info color. */
--link: var(--info-foreground);
--secondary: var(--app-theme-secondary);
--secondary-foreground: var(--app-theme-secondary-foreground);
--muted: var(--app-theme-muted);
Expand Down Expand Up @@ -1319,6 +1366,17 @@ html[data-theme-id]:not([data-theme-id=""]) {
--sidebar-row-hover: var(--app-theme-sidebar-row-hover);
--sidebar-row-active: var(--app-theme-sidebar-row-active);
--sidebar-row-selected: var(--app-theme-sidebar-row-selected);
--sidebar-row-ring: color-mix(in oklab, var(--primary) 35%, transparent);

/* Light theme row fills can sit near white, so the current row also takes
the theme's action color. */
@variant light {
--sidebar-row-active: color-mix(
in oklab,
var(--primary) 20%,
var(--app-theme-sidebar-row-active)
);
}
--sidebar-border: var(--app-theme-sidebar-border);
--sidebar-stage-fade: var(--app-theme-sidebar);
--code-background: var(--app-theme-code-background);
Expand Down Expand Up @@ -1519,6 +1577,17 @@ html[data-theme-id] [data-app-sidebar] {
--sidebar-row-hover: var(--app-theme-sidebar-row-hover);
--sidebar-row-active: var(--app-theme-sidebar-row-active);
--sidebar-row-selected: var(--app-theme-sidebar-row-selected);
--sidebar-row-ring: color-mix(in oklab, var(--primary) 35%, transparent);

/* Light theme row fills can sit near white, so the current row also takes
the theme's action color. */
@variant light {
--sidebar-row-active: color-mix(
in oklab,
var(--primary) 20%,
var(--app-theme-sidebar-row-active)
);
}
--sidebar-border: var(--app-theme-sidebar-border);
--sidebar-stage-fade: var(--app-theme-sidebar);
border-color: color-mix(in srgb, var(--contrast-sidebar-foreground) 10%, transparent);
Expand Down Expand Up @@ -1973,7 +2042,7 @@ code {

/* File links and context chips own their color and focus ring. */
.chat-markdown a:not(.chat-markdown-file-link, :has([data-slot="context-chip-label"])) {
color: var(--info-foreground);
color: var(--link);
}

.chat-markdown
Expand Down
Loading