Centered Logo Navbar

minimal

A symmetrical navbar with the logo centered and navigation links split evenly on both sides. Elegant for fashion, luxury, and editorial brands.

#centered#symmetric#minimal#elegant

Preview

centered-logo-navbar
Interactive Preview
S
Studio.
Hover over navigation items to see flip button animations.

Installation

Add this navbar component directly to your project using the shadcn CLI:

$npx shadcn@latest add https://navcn-phi.vercel.app/r/centered-logo-navbar.json

The component source code is added directly to your project so you can customize it freely.

Source Code

src/components/previews/centered-logo-navbar.tsx
tsx
"use client";

import React, { useState } from "react";
import { motion, AnimatePresence } from "motion/react";
import Link from "next/link";
import { Menu, X } from "lucide-react";

interface FlipButtonProps {
  children: React.ReactNode;
  hoverText: React.ReactNode;
}

const FlipButton: React.FC<FlipButtonProps> = ({ children, hoverText }) => {
  return (
    <motion.button
      initial="initial"
      whileHover="hovered"
      whileTap={{ scale: 0.96 }}
      className="relative h-9 px-5 rounded-full bg-foreground text-background text-xs font-semibold overflow-hidden cursor-pointer flex items-center justify-center shadow-xs select-none group"
    >
      <motion.span
        variants={{
          initial: { y: "0%", opacity: 1 },
          hovered: { y: "-100%", opacity: 0 },
        }}
        transition={{ duration: 0.25, ease: [0.33, 1, 0.68, 1] }}
        className="block whitespace-nowrap leading-none"
      >
        {children}
      </motion.span>

      <motion.span
        variants={{
          initial: { y: "100%", opacity: 0 },
          hovered: { y: "0%", opacity: 1 },
        }}
        transition={{ duration: 0.25, ease: [0.33, 1, 0.68, 1] }}
        className="absolute inset-0 flex items-center justify-center whitespace-nowrap font-semibold text-xs leading-none"
      >
        {hoverText}
      </motion.span>
    </motion.button>
  );
};

export function CenteredLogoNavbar() {
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const [hoveredLeftNav, setHoveredLeftNav] = useState<string | null>(null);
  const [hoveredRightNav, setHoveredRightNav] = useState<string | null>(null);

  const leftLinks = [
    { label: "Work", href: "#" },
    { label: "About", href: "#" },
    { label: "Services", href: "#" },
  ];
  const rightLinks = [
    { label: "Journal", href: "#" },
    { label: "Pricing", href: "#" },
  ];

  return (
    <div className="w-full relative py-2 select-none">
      <div className="max-w-6xl mx-auto px-2 sm:px-4">
        {/* Main Navbar Container */}
        <div className="w-full bg-background/95 backdrop-blur-md border border-border/80 rounded-full shadow-sm px-6 h-16 flex items-center justify-between relative z-30">
          {/* Desktop Left Links */}
          <div className="hidden lg:flex items-center space-x-1 flex-1">
            {leftLinks.map((link) => {
              const isHovered = hoveredLeftNav === link.label;
              return (
                <Link
                  key={link.label}
                  href={link.href}
                  onClick={(e) => e.preventDefault()}
                  onMouseEnter={() => setHoveredLeftNav(link.label)}
                  onMouseLeave={() => setHoveredLeftNav(null)}
                  className="relative px-3.5 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors rounded-full"
                >
                  {isHovered && (
                    <motion.span
                      layoutId="centeredLeftNavPill"
                      className="absolute inset-0 bg-muted/80 rounded-full -z-10 shadow-xs"
                      transition={{ type: "spring", stiffness: 400, damping: 28 }}
                    />
                  )}
                  <span>{link.label}</span>
                </Link>
              );
            })}
          </div>

          {/* Center Logo */}
          <div className="flex-shrink-0 text-center flex items-center gap-2 mx-auto lg:mx-0">
            <div className="w-6.5 h-6.5 rounded-full bg-foreground flex items-center justify-center shadow-xs">
              <span className="text-[11px] font-bold text-background font-mono">S</span>
            </div>
            <span className="text-base font-bold tracking-tight text-foreground">
              Studio<span className="text-primary font-black">.</span>
            </span>
          </div>

          {/* Desktop Right Links + CTA */}
          <div className="hidden lg:flex items-center justify-end space-x-2 flex-1">
            {rightLinks.map((link) => {
              const isHovered = hoveredRightNav === link.label;
              return (
                <Link
                  key={link.label}
                  href={link.href}
                  onClick={(e) => e.preventDefault()}
                  onMouseEnter={() => setHoveredRightNav(link.label)}
                  onMouseLeave={() => setHoveredRightNav(null)}
                  className="relative px-3.5 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors rounded-full"
                >
                  {isHovered && (
                    <motion.span
                      layoutId="centeredRightNavPill"
                      className="absolute inset-0 bg-muted/80 rounded-full -z-10 shadow-xs"
                      transition={{ type: "spring", stiffness: 400, damping: 28 }}
                    />
                  )}
                  <span>{link.label}</span>
                </Link>
              );
            })}
            <div className="pl-2">
              <FlipButton hoverText="Let's Talk →">Get in touch</FlipButton>
            </div>
          </div>

          {/* Mobile Toggle Button */}
          <div className="lg:hidden">
            <button
              onClick={() => setMobileMenuOpen((prev) => !prev)}
              className="p-2 rounded-full text-foreground hover:bg-muted transition-colors w-9 h-9 flex items-center justify-center cursor-pointer"
              aria-label={mobileMenuOpen ? "Close menu" : "Open menu"}
            >
              {mobileMenuOpen ? <X size={18} /> : <Menu size={18} />}
            </button>
          </div>
        </div>

        {/* Mobile Menu Drawer */}
        <AnimatePresence>
          {mobileMenuOpen && (
            <motion.div
              initial={{ height: 0, opacity: 0 }}
              animate={{ height: "auto", opacity: 1 }}
              exit={{ height: 0, opacity: 0 }}
              transition={{ duration: 0.25, ease: "easeInOut" }}
              className="lg:hidden mt-2 border border-border/80 rounded-2xl bg-background overflow-hidden shadow-lg p-5 space-y-4"
            >
              <div className="space-y-2">
                <span className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground/60">
                  Navigation
                </span>
                <div className="grid grid-cols-2 gap-2">
                  {[...leftLinks, ...rightLinks].map((link) => (
                    <a
                      key={link.label}
                      href={link.href}
                      onClick={(e) => {
                        e.preventDefault();
                        setMobileMenuOpen(false);
                      }}
                      className="block text-xs font-medium text-foreground p-2 rounded-lg hover:bg-muted transition-colors"
                    >
                      {link.label}
                    </a>
                  ))}
                </div>
              </div>

              <div className="pt-3 border-t border-border/40 flex items-center justify-between">
                <span className="text-xs text-muted-foreground font-mono">Ready to start?</span>
                <FlipButton hoverText="Let's Talk →">Get in touch</FlipButton>
              </div>
            </motion.div>
          )}
        </AnimatePresence>
      </div>
    </div>
  );
}

export default CenteredLogoNavbar;

This is the exact source file installed into your project. You own and control the code.