From 5c918af3d5a30b4ab594d630027c5d7f777f0a1a Mon Sep 17 00:00:00 2001 From: Matthew Feroz <136640686+MatthewFeroz@users.noreply.github.com> Date: Mon, 5 Oct 2026 17:18:27 -0700 Subject: [PATCH] feat(clients): pinned threads stand out in the thread list --- ...rated-uniwind-default-theme-variables.json | 8 ++++ apps/mobile/generated-uniwind-themes.css | 48 +++++++++++++++++++ .../features/threads/thread-list-v2-items.tsx | 9 +++- .../thread-list-v2-row-appearance.android.ts | 7 +++ .../threads/thread-list-v2-row-appearance.ts | 9 ++++ .../src/lib/materialYouTheme.android.ts | 5 ++ apps/mobile/src/lib/materialYouTheme.test.ts | 13 +++++ apps/mobile/src/lib/mobileTheme.ts | 12 +++++ apps/web/src/components/Sidebar.tsx | 17 ++++--- apps/web/src/index.css | 5 ++ 10 files changed, 125 insertions(+), 8 deletions(-) diff --git a/apps/mobile/generated-uniwind-default-theme-variables.json b/apps/mobile/generated-uniwind-default-theme-variables.json index 961a0df24cd4..3c34aa7e0dd6 100644 --- a/apps/mobile/generated-uniwind-default-theme-variables.json +++ b/apps/mobile/generated-uniwind-default-theme-variables.json @@ -12,6 +12,8 @@ "--color-thread-selected-foreground": "#27272a", "--color-thread-selected-foreground-muted": "#71717b", "--color-thread-hover": "#fcfcfc", + "--color-thread-pin": "#1b4ed8", + "--color-thread-pin-outline": "rgba(27, 78, 216, 0.2)", "--color-row-hover": "#f4f4f5", "--color-composer-panel": "rgba(252, 252, 252, 0.88)", "--color-composer-surface": "rgba(244, 244, 245, 0.94)", @@ -82,6 +84,8 @@ "--color-drawer": "#fafafa", "--color-drawer-foreground": "#27272a", "--color-drawer-foreground-muted": "#71717b", + "--color-drawer-pin": "#1b4ed8", + "--color-drawer-pin-outline": "rgba(27, 78, 216, 0.2)", "--color-drawer-border": "#e4e4e7", "--color-drawer-shadow": "rgba(0, 0, 0, 0.12)", "--color-dot-separator": "rgba(113, 113, 123, 0.35)", @@ -101,6 +105,8 @@ "--color-thread-selected-foreground": "#f1f3f7", "--color-thread-selected-foreground-muted": "#a3a3a3", "--color-thread-hover": "#131313", + "--color-thread-pin": "#4b7cf3", + "--color-thread-pin-outline": "rgba(75, 124, 243, 0.2)", "--color-row-hover": "#141414", "--color-composer-panel": "rgba(10, 10, 10, 0.92)", "--color-composer-surface": "rgba(26, 27, 27, 0.9)", @@ -171,6 +177,8 @@ "--color-drawer": "#000000", "--color-drawer-foreground": "#f1f3f7", "--color-drawer-foreground-muted": "#a3a3a3", + "--color-drawer-pin": "#4b7cf3", + "--color-drawer-pin-outline": "rgba(75, 124, 243, 0.2)", "--color-drawer-border": "#141414", "--color-drawer-shadow": "rgba(0, 0, 0, 0.32)", "--color-dot-separator": "rgba(129, 129, 129, 0.35)", diff --git a/apps/mobile/generated-uniwind-themes.css b/apps/mobile/generated-uniwind-themes.css index 82e7ad85d6cf..3187e9b2e52f 100644 --- a/apps/mobile/generated-uniwind-themes.css +++ b/apps/mobile/generated-uniwind-themes.css @@ -14,6 +14,8 @@ --color-thread-selected-foreground: #27272a; --color-thread-selected-foreground-muted: #71717b; --color-thread-hover: #fcfcfc; + --color-thread-pin: #1b4ed8; + --color-thread-pin-outline: rgba(27, 78, 216, 0.2); --color-row-hover: #f4f4f5; --color-composer-panel: rgba(252, 252, 252, 0.88); --color-composer-surface: rgba(244, 244, 245, 0.94); @@ -84,6 +86,8 @@ --color-drawer: #fafafa; --color-drawer-foreground: #27272a; --color-drawer-foreground-muted: #71717b; + --color-drawer-pin: #1b4ed8; + --color-drawer-pin-outline: rgba(27, 78, 216, 0.2); --color-drawer-border: #e4e4e7; --color-drawer-shadow: rgba(0, 0, 0, 0.12); --color-dot-separator: rgba(113, 113, 123, 0.35); @@ -173,6 +177,8 @@ --color-thread-selected-foreground: #f1f3f7; --color-thread-selected-foreground-muted: #a3a3a3; --color-thread-hover: #131313; + --color-thread-pin: #4b7cf3; + --color-thread-pin-outline: rgba(75, 124, 243, 0.2); --color-row-hover: #141414; --color-composer-panel: rgba(10, 10, 10, 0.92); --color-composer-surface: rgba(26, 27, 27, 0.9); @@ -243,6 +249,8 @@ --color-drawer: #000000; --color-drawer-foreground: #f1f3f7; --color-drawer-foreground-muted: #a3a3a3; + --color-drawer-pin: #4b7cf3; + --color-drawer-pin-outline: rgba(75, 124, 243, 0.2); --color-drawer-border: #141414; --color-drawer-shadow: rgba(0, 0, 0, 0.32); --color-dot-separator: rgba(129, 129, 129, 0.35); @@ -332,6 +340,8 @@ --color-thread-selected-foreground: #454554; --color-thread-selected-foreground-muted: #ac1668; --color-thread-hover: #f8f8f7; + --color-thread-pin: #b11f60; + --color-thread-pin-outline: rgba(177, 31, 96, 0.2); --color-row-hover: #eccfe3; --color-composer-panel: rgba(253, 247, 253, 0.88); --color-composer-surface: rgba(250, 243, 251, 0.94); @@ -402,6 +412,8 @@ --color-drawer: #f2e1f4; --color-drawer-foreground: #454554; --color-drawer-foreground-muted: #ac1668; + --color-drawer-pin: #c2236a; + --color-drawer-pin-outline: rgba(194, 35, 106, 0.2); --color-drawer-border: #eceae9; --color-drawer-shadow: rgba(0, 0, 0, 0.12); --color-dot-separator: rgba(172, 22, 104, 0.35); @@ -491,6 +503,8 @@ --color-thread-selected-foreground: #f4f4f5; --color-thread-selected-foreground-muted: #e7d0dd; --color-thread-hover: #261922; + --color-thread-pin: #eb88b4; + --color-thread-pin-outline: rgba(235, 136, 180, 0.2); --color-row-hover: #463753; --color-composer-panel: rgba(31, 26, 36, 0.92); --color-composer-surface: rgba(41, 35, 45, 0.9); @@ -561,6 +575,8 @@ --color-drawer: #171018; --color-drawer-foreground: #f4f4f5; --color-drawer-foreground-muted: #e7d0dd; + --color-drawer-pin: #e14c8e; + --color-drawer-pin-outline: rgba(225, 76, 142, 0.2); --color-drawer-border: #322028; --color-drawer-shadow: rgba(0, 0, 0, 0.32); --color-dot-separator: rgba(231, 208, 221, 0.35); @@ -650,6 +666,8 @@ --color-thread-selected-foreground: #241523; --color-thread-selected-foreground-muted: #5d585e; --color-thread-hover: #cae0d5; + --color-thread-pin: #166642; + --color-thread-pin-outline: rgba(22, 102, 66, 0.2); --color-row-hover: #d5e6dd; --color-composer-panel: rgba(243, 247, 244, 0.88); --color-composer-surface: rgba(243, 247, 244, 0.94); @@ -720,6 +738,8 @@ --color-drawer: #e2ede7; --color-drawer-foreground: #241523; --color-drawer-foreground-muted: #645f64; + --color-drawer-pin: #166642; + --color-drawer-pin-outline: rgba(22, 102, 66, 0.2); --color-drawer-border: #cbd3d0; --color-drawer-shadow: rgba(0, 0, 0, 0.12); --color-dot-separator: rgba(116, 108, 115, 0.35); @@ -809,6 +829,8 @@ --color-thread-selected-foreground: #fffaff; --color-thread-selected-foreground-muted: #bbc0bf; --color-thread-hover: #2a4938; + --color-thread-pin: #79dba5; + --color-thread-pin-outline: rgba(121, 219, 165, 0.2); --color-row-hover: #325c46; --color-composer-panel: rgba(27, 40, 33, 0.92); --color-composer-surface: rgba(27, 40, 33, 0.9); @@ -879,6 +901,8 @@ --color-drawer: #21362b; --color-drawer-foreground: #fffaff; --color-drawer-foreground-muted: #aab0af; + --color-drawer-pin: #69d69a; + --color-drawer-pin-outline: rgba(105, 214, 154, 0.2); --color-drawer-border: #6f7a75; --color-drawer-shadow: rgba(0, 0, 0, 0.32); --color-dot-separator: rgba(145, 149, 149, 0.35); @@ -968,6 +992,8 @@ --color-thread-selected-foreground: #241523; --color-thread-selected-foreground-muted: #5e5862; --color-thread-hover: #cdddea; + --color-thread-pin: #1f5d90; + --color-thread-pin-outline: rgba(31, 93, 144, 0.2); --color-row-hover: #d8e4ee; --color-composer-panel: rgba(245, 247, 248, 0.88); --color-composer-surface: rgba(245, 247, 248, 0.94); @@ -1038,6 +1064,8 @@ --color-drawer: #e4ecf2; --color-drawer-foreground: #241523; --color-drawer-foreground-muted: #655e69; + --color-drawer-pin: #1f5d90; + --color-drawer-pin-outline: rgba(31, 93, 144, 0.2); --color-drawer-border: #cdd2d9; --color-drawer-shadow: rgba(0, 0, 0, 0.12); --color-dot-separator: rgba(116, 108, 117, 0.35); @@ -1127,6 +1155,8 @@ --color-thread-selected-foreground: #fffaff; --color-thread-selected-foreground-muted: #b0b4ba; --color-thread-hover: #283e50; + --color-thread-pin: #81c2f0; + --color-thread-pin-outline: rgba(129, 194, 240, 0.2); --color-row-hover: #324e66; --color-composer-panel: rgba(23, 33, 43, 0.92); --color-composer-surface: rgba(23, 33, 43, 0.9); @@ -1197,6 +1227,8 @@ --color-drawer: #1e2d3b; --color-drawer-foreground: #fffaff; --color-drawer-foreground-muted: #a2a5ae; + --color-drawer-pin: #74bbee; + --color-drawer-pin-outline: rgba(116, 187, 238, 0.2); --color-drawer-border: #6d757f; --color-drawer-shadow: rgba(0, 0, 0, 0.32); --color-dot-separator: rgba(141, 143, 151, 0.35); @@ -1286,6 +1318,8 @@ --color-thread-selected-foreground: #241523; --color-thread-selected-foreground-muted: #62575d; --color-thread-hover: #ead8cf; + --color-thread-pin: #8e4622; + --color-thread-pin-outline: rgba(142, 70, 34, 0.2); --color-row-hover: #eee0d9; --color-composer-panel: rgba(249, 247, 245, 0.88); --color-composer-surface: rgba(249, 247, 245, 0.94); @@ -1356,6 +1390,8 @@ --color-drawer: #f3eae5; --color-drawer-foreground: #241523; --color-drawer-foreground-muted: #6a5d64; + --color-drawer-pin: #8e4622; + --color-drawer-pin-outline: rgba(142, 70, 34, 0.2); --color-drawer-border: #dad0ce; --color-drawer-shadow: rgba(0, 0, 0, 0.12); --color-dot-separator: rgba(118, 108, 116, 0.35); @@ -1445,6 +1481,8 @@ --color-thread-selected-foreground: #fffaff; --color-thread-selected-foreground-muted: #b9b1b0; --color-thread-hover: #4f3528; + --color-thread-pin: #f2aa7c; + --color-thread-pin-outline: rgba(242, 170, 124, 0.2); --color-row-hover: #644330; --color-composer-panel: rgba(41, 30, 26, 0.92); --color-composer-surface: rgba(41, 30, 26, 0.9); @@ -1515,6 +1553,8 @@ --color-drawer: #39281f; --color-drawer-foreground: #fffaff; --color-drawer-foreground-muted: #aca2a1; + --color-drawer-pin: #f1a06c; + --color-drawer-pin-outline: rgba(241, 160, 108, 0.2); --color-drawer-border: #7e716e; --color-drawer-shadow: rgba(0, 0, 0, 0.32); --color-dot-separator: rgba(150, 142, 143, 0.35); @@ -1604,6 +1644,8 @@ --color-thread-selected-foreground: #241523; --color-thread-selected-foreground-muted: #605662; --color-thread-hover: #ded8ed; + --color-thread-pin: #6449a2; + --color-thread-pin-outline: rgba(100, 73, 162, 0.2); --color-row-hover: #e5e0f0; --color-composer-panel: rgba(248, 247, 249, 0.88); --color-composer-surface: rgba(248, 247, 249, 0.94); @@ -1674,6 +1716,8 @@ --color-drawer: #edeaf4; --color-drawer-foreground: #241523; --color-drawer-foreground-muted: #685d6a; + --color-drawer-pin: #6449a2; + --color-drawer-pin-outline: rgba(100, 73, 162, 0.2); --color-drawer-border: #d5d0db; --color-drawer-shadow: rgba(0, 0, 0, 0.12); --color-dot-separator: rgba(118, 108, 118, 0.35); @@ -1763,6 +1807,8 @@ --color-thread-selected-foreground: #fffaff; --color-thread-selected-foreground-muted: #a6a2ae; --color-thread-hover: #352c4f; + --color-thread-pin: #b39bf5; + --color-thread-pin-outline: rgba(179, 155, 245, 0.2); --color-row-hover: #433765; --color-composer-panel: rgba(29, 25, 41, 0.92); --color-composer-surface: rgba(29, 25, 41, 0.9); @@ -1833,6 +1879,8 @@ --color-drawer: #272139; --color-drawer-foreground: #fffaff; --color-drawer-foreground-muted: #9b97a4; + --color-drawer-pin: #af95f4; + --color-drawer-pin-outline: rgba(175, 149, 244, 0.2); --color-drawer-border: #736d7e; --color-drawer-shadow: rgba(0, 0, 0, 0.32); --color-dot-separator: rgba(142, 138, 149, 0.35); diff --git a/apps/mobile/src/features/threads/thread-list-v2-items.tsx b/apps/mobile/src/features/threads/thread-list-v2-items.tsx index 92ffbcd23f56..1345e9d74d82 100644 --- a/apps/mobile/src/features/threads/thread-list-v2-items.tsx +++ b/apps/mobile/src/features/threads/thread-list-v2-items.tsx @@ -952,7 +952,7 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: { ) : null} @@ -1131,6 +1131,13 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: { }} style={rowAppearance.cardStyle} > + {pinnedRow && rowAppearance.pinnedOutlineStyle ? ( + + ) : null} {sidebarPane ? ( cardContent ) : ( diff --git a/apps/mobile/src/features/threads/thread-list-v2-row-appearance.android.ts b/apps/mobile/src/features/threads/thread-list-v2-row-appearance.android.ts index 8be6b240755d..524a41b5f9fc 100644 --- a/apps/mobile/src/features/threads/thread-list-v2-row-appearance.android.ts +++ b/apps/mobile/src/features/threads/thread-list-v2-row-appearance.android.ts @@ -51,6 +51,13 @@ export function getThreadListV2RowAppearance( tertiaryIconTintClassName: sidebarPane ? "accent-drawer-foreground-muted" : "accent-foreground-tertiary", + pinIconTintClassName: sidebarPane ? "accent-drawer-pin" : "accent-thread-pin", + // Every Android row is a rounded card, so pinned rows always get the hairline. + pinnedOutlineStyle: { + borderRadius: 20, + borderWidth: 1, + borderColor: theme[sidebarPane ? "--color-drawer-pin-outline" : "--color-thread-pin-outline"], + } satisfies ViewStyle, style, cardStyle: sidebarPane ? { ...style, paddingHorizontal: 12, paddingVertical: 10 } : style, swipeContainerStyle, diff --git a/apps/mobile/src/features/threads/thread-list-v2-row-appearance.ts b/apps/mobile/src/features/threads/thread-list-v2-row-appearance.ts index b73f87b86a2a..4901007eee7a 100644 --- a/apps/mobile/src/features/threads/thread-list-v2-row-appearance.ts +++ b/apps/mobile/src/features/threads/thread-list-v2-row-appearance.ts @@ -49,6 +49,15 @@ export function getThreadListV2RowAppearance( tertiaryIconTintClassName: sidebarPane ? "accent-drawer-foreground-muted" : "accent-foreground-tertiary", + pinIconTintClassName: sidebarPane ? "accent-drawer-pin" : "accent-thread-pin", + // Pinned cards get a hairline; flat native rows carry the pin by color alone. + pinnedOutlineStyle: sidebarPane + ? ({ + borderRadius: 12, + borderWidth: 1, + borderColor: theme["--color-drawer-pin-outline"], + } satisfies ViewStyle) + : undefined, style, cardStyle: sidebarPane ? { ...style, paddingHorizontal: 12, paddingVertical: 10 } : undefined, swipeContainerStyle, diff --git a/apps/mobile/src/lib/materialYouTheme.android.ts b/apps/mobile/src/lib/materialYouTheme.android.ts index 311518428efb..5d2a6d05573d 100644 --- a/apps/mobile/src/lib/materialYouTheme.android.ts +++ b/apps/mobile/src/lib/materialYouTheme.android.ts @@ -54,6 +54,11 @@ export function materialYouPaletteToMobileThemeVariables( "--color-foreground-tertiary": withAlpha(palette.onSurfaceVariant, 0.58), "--color-border": withAlpha(palette.outlineVariant, dark ? 0.5 : 0.65), "--color-focus": palette.primary, + // Material tonal palettes keep primary legible on their own surfaces. + "--color-thread-pin": palette.primary, + "--color-thread-pin-outline": withAlpha(palette.primary, 0.2), + "--color-drawer-pin": palette.primary, + "--color-drawer-pin-outline": withAlpha(palette.primary, 0.2), "--color-border-subtle": withAlpha(palette.outlineVariant, dark ? 0.34 : 0.46), "--color-separator": withAlpha(palette.outlineVariant, dark ? 0.24 : 0.34), "--color-subtle": withAlpha(palette.onSurface, 0.05), diff --git a/apps/mobile/src/lib/materialYouTheme.test.ts b/apps/mobile/src/lib/materialYouTheme.test.ts index d803a161ad87..8b701c3d8d81 100644 --- a/apps/mobile/src/lib/materialYouTheme.test.ts +++ b/apps/mobile/src/lib/materialYouTheme.test.ts @@ -59,6 +59,19 @@ describe("Material You system colors", () => { expect(variables["--color-placeholder"]).toBe("#1C1B1F9E"); }); + it("tints pinned thread rows with the system primary", () => { + const variables = materialYouPaletteToMobileThemeVariables( + palette, + "light", + getMobileThemeRuntimeVariables("t3-code", "light", "android"), + ); + + expect(variables["--color-thread-pin"]).toBe(palette.primary); + expect(variables["--color-drawer-pin"]).toBe(palette.primary); + expect(variables["--color-thread-pin-outline"]).toBe("#6750A433"); + expect(variables["--color-drawer-pin-outline"]).toBe("#6750A433"); + }); + it("uses the Messages-style RCS tones for sent messages", () => { const base = getMobileThemeRuntimeVariables("t3-code", "dark", "android"); const dark = materialYouPaletteToMobileThemeVariables( diff --git a/apps/mobile/src/lib/mobileTheme.ts b/apps/mobile/src/lib/mobileTheme.ts index 4159232fe7ab..a1c1960b3f21 100644 --- a/apps/mobile/src/lib/mobileTheme.ts +++ b/apps/mobile/src/lib/mobileTheme.ts @@ -243,6 +243,14 @@ export function createMobileThemeVariables( const c = nativeColors(colors); const groupedCard = themeColorToNativeColor(groupedCardColor); const textSurfaces = [c.canvas, c.surface, c.surfaceRaised, c.chrome, groupedCard]; + // Pinned thread rows: the theme's focus accent, solved for contrast on every + // background the row can sit on (rest, pressed, selected). + const threadPin = readableTextColor(c.focus, [ + ...textSurfaces, + c.toolbarControlHover, + c.sidebarRowActive, + ]); + const drawerPin = readableTextColor(c.focus, [c.sidebar, c.sidebarRowHover, c.sidebarRowActive]); return { "--color-screen": c.canvas, "--color-sheet": withAlpha(c.chrome, 0.98), @@ -259,6 +267,8 @@ export function createMobileThemeVariables( c.sidebarRowActive, ), "--color-thread-hover": c.sidebarRowHover, + "--color-thread-pin": threadPin, + "--color-thread-pin-outline": themeColorWithAlpha(threadPin, 0.2), "--color-row-hover": c.toolbarControlHover, "--color-composer-panel": themeColorWithAlpha(c.canvas, appearance === "dark" ? 0.92 : 0.88), "--color-composer-surface": themeColorWithAlpha( @@ -338,6 +348,8 @@ export function createMobileThemeVariables( c.sidebar, c.sidebarRowHover, ]), + "--color-drawer-pin": drawerPin, + "--color-drawer-pin-outline": themeColorWithAlpha(drawerPin, 0.2), "--color-drawer-border": c.sidebarBorder, "--color-drawer-shadow": withAlpha("#000000", appearance === "dark" ? 0.32 : 0.12), "--color-dot-separator": withAlpha(c.textMuted, 0.35), diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx index 667f87b8df96..80251c63c225 100644 --- a/apps/web/src/components/Sidebar.tsx +++ b/apps/web/src/components/Sidebar.tsx @@ -1531,7 +1531,8 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { // All sidebar rows share one surface model. Live threads used to look // like elevated cards while settled threads were plain rows, leaving neither // a useful hierarchy nor a reliable hover cue. Status now lives in the row - // content; surface is reserved for interaction (hover, multi-select, route). + // content; background fills mark interaction (hover, multi-select, route) and + // unsent drafts. Pinned rows add a hairline outline instead of a fill. 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", @@ -1549,6 +1550,12 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { shouldRecede && status === "working" && "opacity-70 transition-opacity hover:opacity-100 focus-within:opacity-100 motion-reduce:transition-none", + // Pin-colored hairline; in the built-in palettes it stays fainter than the + // focus and file-drop rings. + props.isPinned && + !isFileDragOver && + !props.sortable?.isDragging && + "ring-1 ring-inset ring-sidebar-pin/20", isFileDragOver && "ring-1 ring-inset ring-primary/70", isFileDragOver && !props.isActive && !isSelected && "bg-sidebar-row-hover", // The lifted row is an opaque card so the rows beneath it never show @@ -1714,7 +1721,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { type="button" aria-label="Unpin thread" onClick={handleUnpinClick} - className="group/unpin inline-flex cursor-pointer items-center rounded-sm text-muted-foreground/65 outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring" + className="group/unpin inline-flex cursor-pointer items-center rounded-sm text-sidebar-pin outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring" /> } > @@ -1732,11 +1739,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { Unpin thread ) : ( - + ) ) : null; diff --git a/apps/web/src/index.css b/apps/web/src/index.css index a4b80193dce2..d553840b8ffb 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -274,6 +274,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil --color-sidebar-row-active: var(--sidebar-row-active); --color-sidebar-row-selected: var(--sidebar-row-selected); --color-sidebar-border: var(--contrast-sidebar-border); + --color-sidebar-pin: var(--sidebar-pin); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); @@ -1582,6 +1583,10 @@ html[data-theme-id="t3-chat"] [data-app-sidebar] { color-mix(in srgb, var(--sidebar-border) var(--appearance-contrast-base), transparent), var(--sidebar-foreground) var(--appearance-contrast-border-boost) ); + /* Pinned threads take the theme's focus accent, pulled mostly toward the + sidebar text so the pin stays legible in the built-in palettes and follows + the contrast setting. Theme action colors are fills and can vanish here. */ + --sidebar-pin: color-mix(in oklab, var(--ring) 40%, var(--contrast-sidebar-foreground)); } body {