fix(ui): stronger frosted glass + frosted settings backdrop; declutter header

- Increase .glass blur (32px) so overlay menus (account) read as proper frosted glass.
- Blur the settings modal backdrop (overlay backdrop-blur) so the panel reliably
  frosts the content behind it instead of showing a sharp video through.
- Remove the now-redundant header buttons (dark/light, color scheme, grid/list) —
  they live in Settings → Appearance. Header keeps search, sync, bell, account.
This commit is contained in:
npeter83 2026-06-11 22:16:07 +02:00
parent 550deeab99
commit 78128a83b6
4 changed files with 8 additions and 116 deletions

View file

@ -1,98 +1,25 @@
import { useRef, useState } from "react";
import {
Home,
LayoutGrid,
List,
LogOut,
Moon,
Palette,
Search,
Settings,
Shield,
Sun,
Tv,
} from "lucide-react";
import { SCHEMES, type Scheme, type ThemePrefs } from "../lib/theme";
import { Home, LogOut, Search, Settings, Shield, Tv } from "lucide-react";
import type { FeedFilters, Me } from "../lib/api";
import type { Page } from "../lib/urlState";
import SyncStatus from "./SyncStatus";
import NotificationCenter from "./NotificationCenter";
function IconBtn(props: React.ButtonHTMLAttributes<HTMLButtonElement>) {
const { className = "", ...rest } = props;
return (
<button
{...rest}
className={`p-2 rounded-lg text-muted hover:text-fg hover:bg-card transition ${className}`}
/>
);
}
function ThemeMenu({
theme,
setTheme,
}: {
theme: ThemePrefs;
setTheme: (t: ThemePrefs) => void;
}) {
return (
<div className="glass absolute right-0 mt-2 w-60 rounded-xl p-3 z-30 animate-[popIn_0.16s_ease]">
<div className="text-xs uppercase tracking-wide text-muted mb-2">Color scheme</div>
<div className="grid grid-cols-4 gap-2 mb-3">
{SCHEMES.map((s) => (
<button
key={s.id}
onClick={() => setTheme({ ...theme, scheme: s.id as Scheme })}
title={s.name}
className={`h-9 rounded-lg border-2 transition ${
theme.scheme === s.id ? "border-fg" : "border-transparent"
}`}
style={{ background: s.swatch }}
/>
))}
</div>
<div className="text-xs uppercase tracking-wide text-muted mb-2">Text size</div>
<input
type="range"
min={0.9}
max={1.3}
step={0.02}
value={theme.fontScale}
onChange={(e) => setTheme({ ...theme, fontScale: Number(e.target.value) })}
className="w-full accent-accent"
/>
<div className="text-right text-xs text-muted">
{Math.round(theme.fontScale * 100)}%
</div>
</div>
);
}
export default function Header({
me,
theme,
setTheme,
filters,
setFilters,
view,
setView,
page,
setPage,
onOpenSettings,
}: {
me: Me;
theme: ThemePrefs;
setTheme: (t: ThemePrefs) => void;
filters: FeedFilters;
setFilters: (f: FeedFilters) => void;
view: "grid" | "list";
setView: (v: "grid" | "list") => void;
page: Page;
setPage: (p: Page) => void;
onOpenSettings: () => void;
}) {
const [menuOpen, setMenuOpen] = useState(false);
async function logout() {
await fetch("/auth/logout", { method: "POST", credentials: "include" });
location.reload();
@ -125,34 +52,7 @@ export default function Header({
)}
<div className="flex items-center gap-1">
{page === "feed" && (
<IconBtn
onClick={() => setView(view === "grid" ? "list" : "grid")}
title={view === "grid" ? "List view" : "Grid view"}
>
{view === "grid" ? <List className="w-5 h-5" /> : <LayoutGrid className="w-5 h-5" />}
</IconBtn>
)}
<IconBtn
onClick={() => setTheme({ ...theme, mode: theme.mode === "dark" ? "light" : "dark" })}
title="Toggle dark / light"
>
{theme.mode === "dark" ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
</IconBtn>
<div className="relative">
<IconBtn onClick={() => setMenuOpen((o) => !o)} title="Theme">
<Palette className="w-5 h-5" />
</IconBtn>
{menuOpen && (
<>
<div className="fixed inset-0 z-20" onClick={() => setMenuOpen(false)} />
<ThemeMenu theme={theme} setTheme={setTheme} />
</>
)}
</div>
<NotificationCenter filters={filters} setFilters={setFilters} />
<div className="pl-1">
<AccountMenu
me={me}
@ -205,11 +105,7 @@ function AccountMenu({
"w-full flex items-center gap-2 text-sm px-2 py-2 rounded-lg text-muted hover:text-fg hover:bg-card transition";
return (
<div
className="relative"
onMouseEnter={openNow}
onMouseLeave={closeSoon}
>
<div className="relative" onMouseEnter={openNow} onMouseLeave={closeSoon}>
<button
onClick={() => setOpen((o) => !o)}
title={me.email}

View file

@ -54,7 +54,7 @@ export default function SettingsPanel({
return (
<div className="fixed inset-0 z-40 flex justify-end">
<div
className={`absolute inset-0 bg-black/40 ${
className={`absolute inset-0 bg-black/30 backdrop-blur-lg ${
closing ? "animate-[overlayOut_0.19s_ease_forwards]" : "animate-[overlayIn_0.2s_ease]"
}`}
onClick={close}