diff --git a/app/[locale]/(site)/layout.tsx b/app/[locale]/(site)/layout.tsx
index bed2e1d..6f964a3 100644
--- a/app/[locale]/(site)/layout.tsx
+++ b/app/[locale]/(site)/layout.tsx
@@ -4,8 +4,8 @@ import { getLocale } from "next-intl/server";
import { redirect } from "next/navigation";
import { SiteAmbientBackdrop } from "@/components/layout/site-ambient-backdrop";
+import { SiteDock } from "@/components/layout/site-dock";
import { SiteFooter } from "@/components/layout/site-footer";
-import { SiteHeader } from "@/components/layout/site-header";
import { ScrollSmootherProvider } from "@/components/scroll-smoother-provider";
import { isSuperAdmin } from "@/lib/admin-auth";
import { getMaintenanceMode, getSiteSettings, getSiteSettingsMediaBindings } from "@/lib/app-config";
@@ -44,7 +44,7 @@ export default async function SiteLayout({ children, params }: SiteLayoutProps)
<>
- ;
+ disabled?: boolean;
+};
+
+const navItems: NavItem[] = [
+ { key: "home", path: "", Icon: Home },
+ { key: "about", path: "/about", Icon: User },
+ { key: "portfolio", path: "/portfolio", Icon: FolderKanban },
+ { key: "products", path: "/products", Icon: Package, disabled: true },
+ { key: "contact", path: "/contact", Icon: Mail },
+];
+
+function isNavItemActive(currentPath: string, itemPath: string) {
+ if (itemPath === "/") {
+ return currentPath === "/";
+ }
+ return currentPath === itemPath || currentPath.startsWith(`${itemPath}/`);
+}
+
+function MenuClock({ locale }: { locale: string }) {
+ const [time, setTime] = useState("");
+
+ useEffect(() => {
+ const format = () =>
+ setTime(
+ new Date().toLocaleTimeString(locale === "ar" ? "ar" : locale, {
+ hour: "2-digit",
+ minute: "2-digit",
+ }),
+ );
+ format();
+ const id = setInterval(format, 20_000);
+ return () => clearInterval(id);
+ }, [locale]);
+
+ return (
+
+ {time || "--:--"}
+
+ );
+}
+
+export function SiteDock({
+ lightLogoUrl,
+ darkLogoUrl,
+ defaultLocale,
+ isSuperAdmin = false,
+}: SiteDockProps) {
+ const locale = useLocale();
+ const pathname = usePathname();
+ const t = useTranslations("navigation");
+ const { theme, resolvedTheme } = useTheme();
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ const isArabic = locale === "ar";
+ const currentPath = stripLocalePrefix(pathname);
+ const homeHref = getLocalizedPath(locale, "/", defaultLocale);
+ const adminHref = buildAdminUrl("/");
+
+ const activeTheme = theme === "system" ? resolvedTheme : theme;
+ const isDark = mounted && activeTheme === "dark";
+ const logoSrc = isDark
+ ? darkLogoUrl || lightLogoUrl || "/logos/dark-primary.svg"
+ : lightLogoUrl || darkLogoUrl || "/logos/light-primary.svg";
+
+ const brandSubtitle = isArabic
+ ? "مطوّر ويب · فريلانسر"
+ : "Webdesigner Bremen · Freelancer";
+
+ const controlButtonClassName =
+ "h-8 w-8 rounded-full border border-transparent text-foreground/70 hover:bg-accent hover:text-foreground";
+
+ return (
+ <>
+ {/* ===== Top menu bar (macOS-style utility strip) ===== */}
+
+
+
+
+
+ {isArabic ? (
+ <>
+ محمد{" "}
+ فرواتي
+ >
+ ) : (
+ <>
+ MOH
+ FARAWATI
+ >
+ )}
+
+
+
+
+ {brandSubtitle}
+
+
+
+
+
+
+
+ {isSuperAdmin ? (
+
+
+ Admin
+
+ ) : null}
+
+
+
+
+ {/* ===== Bottom dock (Magic UI) — primary navigation ===== */}
+
+
+ {/* Logo — first icon in the dock */}
+
+
+
+
+
+
+
+
+
+ {navItems.map(({ key, path, Icon, disabled }) => {
+ const itemPath = path || "/";
+ const isActive = isNavItemActive(currentPath, itemPath);
+ const label = t(key);
+
+ const inner = (
+
+
+
+ );
+
+ return (
+
+ {disabled ? (
+
+ {inner}
+
+ ) : (
+
+ {inner}
+
+ )}
+
+
+
+ {isActive ? (
+
+ ) : null}
+
+ );
+ })}
+
+
+ >
+ );
+}
+
+function DockTip({ label, soon }: { label: string; soon?: string }) {
+ return (
+
+ {label}
+ {soon ? {soon} : null}
+
+ );
+}
diff --git a/components/ui/dock.tsx b/components/ui/dock.tsx
new file mode 100644
index 0000000..696c5b9
--- /dev/null
+++ b/components/ui/dock.tsx
@@ -0,0 +1,150 @@
+"use client";
+
+import React, { useRef, type PropsWithChildren } from "react";
+import { cva, type VariantProps } from "class-variance-authority";
+import {
+ motion,
+ useMotionValue,
+ useSpring,
+ useTransform,
+ type MotionValue,
+ type MotionProps,
+} from "framer-motion";
+
+import { cn } from "@/lib/utils";
+
+export interface DockProps extends VariantProps {
+ className?: string;
+ iconSize?: number;
+ iconMagnification?: number;
+ disableMagnification?: boolean;
+ iconDistance?: number;
+ direction?: "top" | "middle" | "bottom";
+ children: React.ReactNode;
+}
+
+const DEFAULT_SIZE = 40;
+const DEFAULT_MAGNIFICATION = 60;
+const DEFAULT_DISTANCE = 140;
+const DEFAULT_DISABLEMAGNIFICATION = false;
+
+const dockVariants = cva(
+ "supports-backdrop-blur:bg-white/10 supports-backdrop-blur:dark:bg-black/10 mx-auto flex w-max items-center justify-center gap-2 rounded-2xl border p-2 backdrop-blur-md",
+);
+
+const Dock = React.forwardRef(
+ (
+ {
+ className,
+ children,
+ iconSize = DEFAULT_SIZE,
+ iconMagnification = DEFAULT_MAGNIFICATION,
+ disableMagnification = DEFAULT_DISABLEMAGNIFICATION,
+ iconDistance = DEFAULT_DISTANCE,
+ direction = "bottom",
+ ...props
+ },
+ ref,
+ ) => {
+ const mouseX = useMotionValue(Infinity);
+
+ const renderChildren = () => {
+ return React.Children.map(children, (child) => {
+ if (React.isValidElement(child) && child.type === DockIcon) {
+ return React.cloneElement(child, {
+ ...child.props,
+ mouseX: mouseX,
+ size: iconSize,
+ magnification: iconMagnification,
+ disableMagnification: disableMagnification,
+ distance: iconDistance,
+ });
+ }
+ return child;
+ });
+ };
+
+ return (
+ mouseX.set(e.pageX)}
+ onMouseLeave={() => mouseX.set(Infinity)}
+ {...props}
+ className={cn(dockVariants({ className }), {
+ "items-start": direction === "top",
+ "items-center": direction === "middle",
+ "items-end": direction === "bottom",
+ })}
+ >
+ {renderChildren()}
+
+ );
+ },
+);
+
+Dock.displayName = "Dock";
+
+export interface DockIconProps
+ extends Omit, "children"> {
+ size?: number;
+ magnification?: number;
+ disableMagnification?: boolean;
+ distance?: number;
+ mouseX?: MotionValue;
+ className?: string;
+ children?: React.ReactNode;
+ props?: PropsWithChildren;
+}
+
+const DockIcon = ({
+ size = DEFAULT_SIZE,
+ magnification = DEFAULT_MAGNIFICATION,
+ disableMagnification,
+ distance = DEFAULT_DISTANCE,
+ mouseX,
+ className,
+ children,
+ ...props
+}: DockIconProps) => {
+ const ref = useRef(null);
+ const padding = Math.max(6, size * 0.2);
+ const defaultMouseX = useMotionValue(Infinity);
+
+ const distanceCalc = useTransform(mouseX ?? defaultMouseX, (val: number) => {
+ const bounds = ref.current?.getBoundingClientRect() ?? { x: 0, width: 0 };
+ return val - bounds.x - bounds.width / 2;
+ });
+
+ const targetSize = disableMagnification ? size : magnification;
+
+ const sizeTransform = useTransform(
+ distanceCalc,
+ [-distance, 0, distance],
+ [size, targetSize, size],
+ );
+
+ const scaleSize = useSpring(sizeTransform, {
+ mass: 0.1,
+ stiffness: 150,
+ damping: 12,
+ });
+
+ return (
+
+ {children}
+
+ );
+};
+
+DockIcon.displayName = "DockIcon";
+
+export { Dock, DockIcon, dockVariants };