feat: glassmorphism sidebar toggle (P5-3)

Settings → Appearance: "Glassmorphism Sidebar" toggle (off by default).
When enabled, applies backdrop-filter: blur(12px) and a semi-transparent
background to the left sidebar so chat background patterns show through.
SidebarGlass vanilla-extract class in Sidebar.css.ts; wired in
SidebarNav.tsx via classNames conditional.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 22:02:18 -04:00
parent 517e992dec
commit c6932b45fb
6 changed files with 41 additions and 2 deletions
@@ -16,6 +16,13 @@ export const Sidebar = style([
},
]);
export const SidebarGlass = style({
backgroundColor: 'rgba(3, 5, 8, 0.55)',
backdropFilter: 'blur(12px)',
WebkitBackdropFilter: 'blur(12px)',
borderRight: '1px solid rgba(255,255,255,0.06)',
});
export const SidebarStack = style([
DefaultReset,
{
@@ -327,6 +327,10 @@ function Appearance() {
const [lotusTerminal, setLotusTerminal] = useSetting(settingsAtom, 'lotusTerminal');
const [nightLightEnabled, setNightLightEnabled] = useSetting(settingsAtom, 'nightLightEnabled');
const [nightLightOpacity, setNightLightOpacity] = useSetting(settingsAtom, 'nightLightOpacity');
const [glassmorphismSidebar, setGlassmorphismSidebar] = useSetting(
settingsAtom,
'glassmorphismSidebar',
);
return (
<Box direction="Column" gap="100">
@@ -431,6 +435,20 @@ function Appearance() {
)}
</SequenceCard>
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
<SettingTile
title="Glassmorphism Sidebar"
description="Semi-transparent sidebar with frosted glass effect. Works best with custom chat backgrounds."
after={
<Switch
variant="Primary"
value={glassmorphismSidebar}
onChange={setGlassmorphismSidebar}
/>
}
/>
</SequenceCard>
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
<SettingTile
title="Lotus Terminal Mode"
+6 -1
View File
@@ -1,5 +1,6 @@
import React, { useRef } from 'react';
import { Scroll } from 'folds';
import classNames from 'classnames';
import {
Sidebar,
@@ -7,6 +8,7 @@ import {
SidebarStackSeparator,
SidebarStack,
} from '../../components/sidebar';
import { SidebarGlass } from '../../components/sidebar/Sidebar.css';
import {
DirectTab,
HomeTab,
@@ -19,12 +21,15 @@ import {
BookmarksTab,
} from './sidebar';
import { CreateTab } from './sidebar/CreateTab';
import { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
export function SidebarNav() {
const scrollRef = useRef<HTMLDivElement>(null) as React.RefObject<HTMLDivElement>;
const [glassmorphismSidebar] = useSetting(settingsAtom, 'glassmorphismSidebar');
return (
<Sidebar>
<Sidebar className={classNames(glassmorphismSidebar && SidebarGlass)}>
<SidebarContent
scrollable={
<Scroll ref={scrollRef} variant="Background" size="0">
+4
View File
@@ -89,6 +89,8 @@ export interface Settings {
nightLightEnabled: boolean;
nightLightOpacity: number;
glassmorphismSidebar: boolean;
deafenKey: string;
warnOnUnverifiedDevices: boolean;
@@ -150,6 +152,8 @@ const defaultSettings: Settings = {
nightLightEnabled: false,
nightLightOpacity: 30,
glassmorphismSidebar: false,
deafenKey: 'KeyM',
warnOnUnverifiedDevices: false,