From a6be3c26d28ed5d915cefe815b862f9ade516b17 Mon Sep 17 00:00:00 2001 From: moh Date: Sun, 20 Sep 2026 19:34:57 +0200 Subject: [PATCH] IMPROVED - Collapse dock controls into one settings tile that fans out in an arc --- components/layout/site-dock.tsx | 299 +++++++++++++++++++------------- 1 file changed, 176 insertions(+), 123 deletions(-) diff --git a/components/layout/site-dock.tsx b/components/layout/site-dock.tsx index 3ee148b..66714b3 100644 --- a/components/layout/site-dock.tsx +++ b/components/layout/site-dock.tsx @@ -1,10 +1,12 @@ "use client"; -import { ShieldCheck } from "lucide-react"; +import { AnimatePresence, motion, useReducedMotion } from "framer-motion"; +import { Settings, ShieldCheck } from "lucide-react"; import Image from "next/image"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useLocale, useTranslations } from "next-intl"; +import { useState, type ReactNode } from "react"; import { LocaleToggle } from "@/components/layout/locale-toggle"; import { SoundToggle } from "@/components/sound-toggle"; @@ -41,12 +43,17 @@ const navItems: NavItem[] = [ { key: "contact", path: "/contact" }, ]; -// Graphite squircle that matches the SVG page icons, used for the live control -// tiles (theme / sound / language / admin) so the whole dock reads as one set. +// Graphite squircle matching the SVG page icons, used for the settings tile. const controlTile = "group relative overflow-visible rounded-[26%] bg-gradient-to-b from-[#3f4551] to-[#191d24] shadow-[0_6px_14px_-6px_rgba(0,0,0,0.5)] ring-1 ring-white/10 transition-shadow duration-200 hover:shadow-[0_10px_22px_-8px_rgba(0,0,0,0.6)]"; -const controlButton = - "h-full w-full rounded-[inherit] border-0 bg-transparent text-white hover:bg-white/10 hover:text-white"; +// Glass pill used for each control that fans out along the arc. +const fanPill = + "flex h-11 w-11 items-center justify-center rounded-full border border-transparent bg-background/90 text-foreground/85 shadow-panel backdrop-blur-chrome transition-colors hover:bg-accent hover:text-foreground"; + +// Radius (px) and opening angles of the arc the controls fan out along. +const ARC_RADIUS = 74; +const ARC_START = 46; +const ARC_END = 134; function isNavItemActive(currentPath: string, itemPath: string) { if (itemPath === "/") { @@ -59,140 +66,186 @@ export function SiteDock({ defaultLocale, isSuperAdmin = false }: SiteDockProps) const locale = useLocale(); const pathname = usePathname(); const t = useTranslations("navigation"); + const reducedMotion = useReducedMotion(); + const [settingsOpen, setSettingsOpen] = useState(false); const currentPath = stripLocalePrefix(pathname); const homeHref = getLocalizedPath(locale, "/", defaultLocale); + const fanItems: ReactNode[] = [ + , + , + , + ]; + + if (isSuperAdmin) { + fanItems.push( + + + , + ); + } + + const arcPosition = (index: number) => { + const count = fanItems.length; + const angle = count === 1 ? 90 : ARC_START + ((ARC_END - ARC_START) * index) / (count - 1); + const radians = (angle * Math.PI) / 180; + return { x: Math.cos(radians) * ARC_RADIUS, y: -Math.sin(radians) * ARC_RADIUS }; + }; + return ( -
- + {/* click-away scrim (below the dock, above the page) */} + {settingsOpen ? ( + + + {settingsOpen ? null : } - ) : null} - -
+ + + ); }