Skip to content

Navbar Overlay

Minimal bar (wordmark + ink MENU button with animated burger) that opens a full-screen yellow overlay with giant numbered links sliding on hover, a contact line and CTA. Same menu on every screen size.

brutalist/section/navbar-overlay
Open ↗

Source

"use client";

import { useEffect, useId, useRef, useState } from "react";
import { cn } from "@/lib/utils";

export interface NavbarOverlayLink {
  label: string;
  href: string;
  /** Small mono note next to the big link, e.g. "New". */
  note?: string;
}

export interface NavbarOverlayProps {
  brand?: string;
  brandHref?: string;
  links?: NavbarOverlayLink[];
  cta?: { label: string; href: string };
  contact?: { label: string; href: string };
  className?: string;
}

export function NavbarOverlay({
  brand = "Shipyard",
  brandHref = "/",
  links = [
    { label: "Product", href: "#product" },
    { label: "Changelog", href: "#changelog", note: "v4.2" },
    { label: "Customers", href: "#customers" },
    { label: "Pricing", href: "#pricing" },
    { label: "Docs", href: "#docs" },
  ],
  cta = { label: "Start free", href: "#signup" },
  contact = { label: "hello@shipyard.dev", href: "mailto:hello@shipyard.dev" },
  className,
}: NavbarOverlayProps) {
  const [open, setOpen] = useState(false);
  const panelId = useId();
  const toggleRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    if (!open) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        setOpen(false);
        toggleRef.current?.focus();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);

  return (
    <header className={cn("relative z-40 text-da-fg", className)}>
      <div className="da-container flex h-20 items-center justify-between">
        <a href={brandHref} className="da-focus font-da-display text-2xl tracking-da-display uppercase">
          {brand}
          <span aria-hidden className="text-da-secondary">.</span>
        </a>
        <div className="flex items-center gap-3">
          <a
            href={cta.href}
            className="da-focus da-transition da-stroke hidden bg-da-primary px-4 py-2 text-sm font-bold text-da-primary-fg shadow-da-sm hover:translate-x-[3px] hover:translate-y-[3px] hover:shadow-none sm:block"
          >
            {cta.label}
          </a>
          <button
            ref={toggleRef}
            type="button"
            aria-expanded={open}
            aria-controls={panelId}
            onClick={() => setOpen((o) => !o)}
            className="da-focus da-stroke relative z-50 flex h-11 items-center gap-3 bg-da-fg px-4 font-da-mono text-xs font-bold tracking-da-label text-da-bg uppercase shadow-da-sm"
          >
            {open ? "Close" : "Menu"}
            <span aria-hidden className="flex w-5 flex-col gap-1">
              <span className={cn("h-[3px] bg-current transition-transform duration-(--da-duration)", open && "translate-y-[7px] rotate-45")} />
              <span className={cn("h-[3px] bg-current transition-opacity duration-(--da-duration)", open && "opacity-0")} />
              <span className={cn("h-[3px] bg-current transition-transform duration-(--da-duration)", open && "-translate-y-[7px] -rotate-45")} />
            </span>
          </button>
        </div>
      </div>

      <div
        id={panelId}
        hidden={!open}
        className="fixed inset-0 z-40 overflow-y-auto bg-da-primary text-da-primary-fg transition-[clip-path] duration-(--da-duration-slow) ease-da-emphasized starting:[clip-path:inset(0_0_100%_0)] [clip-path:inset(0)] motion-reduce:transition-none"
      >
        <div className="da-container flex min-h-full flex-col pt-28 pb-10">
          <nav aria-label="Main">
            <ol className="da-stroke-t">
              {links.map((l, i) => (
                <li key={l.href} className="da-stroke-b">
                  <a
                    href={l.href}
                    onClick={() => setOpen(false)}
                    className="da-focus group flex items-baseline gap-4 py-3 font-da-display text-[clamp(2.5rem,9vw,6rem)] leading-none tracking-da-display uppercase"
                  >
                    <span className="font-da-mono text-sm font-bold">{String(i + 1).padStart(2, "0")}</span>
                    <span className="da-transition group-hover:translate-x-4">{l.label}</span>
                    {l.note && (
                      <span className="da-stroke ml-auto self-center bg-da-fg px-2 py-1 font-da-mono text-xs font-bold text-da-bg">{l.note}</span>
                    )}
                  </a>
                </li>
              ))}
            </ol>
          </nav>
          <div className="mt-auto flex flex-wrap items-center justify-between gap-4 pt-10 font-da-mono text-sm font-bold">
            <a href={contact.href} className="da-focus underline decoration-[3px] underline-offset-4">
              {contact.label}
            </a>
            <a href={cta.href} className="da-focus da-stroke bg-da-fg px-5 py-3 text-da-bg shadow-da-sm">
              {cta.label} →
            </a>
          </div>
        </div>
      </div>
    </header>
  );
}

export default NavbarOverlay;

modules/brutalist/section/navbar-overlay/index.tsx

Props

PropTypeDefaultDescription
brand / brandHrefstring"Shipyard" / "/"Wordmark and its link.
linksNavbarOverlayLink[]—{ label, href, note? } shown as giant numbered links.
cta{ label: string; href: string }—CTA in the bar and in the overlay.
contact{ label: string; href: string }—Contact link at the bottom of the overlay.
classNamestring—Classes on the <header>.

Other navbar variants in Brutalist

Navbar in other art directions

Navbar Bar

Full-width sticky frosted bar with a Features dropdown that opens a glass panel of four icon cards, plain links and a gradient pill CTA; stacked mobile menu.

GlassNavbar

Navbar Dock

macOS-style floating bottom dock: a glass pill of round icon links that magnify with a spring when hovered (neighbours too), tooltips, a gradient active item with dot and an ink CTA.

GlassNavbar

Navbar Floating

Floating frosted pill navbar detached from the top edge: gradient orb logo, centered links, gradient CTA. On mobile the pill opens a frosted dropdown panel that fades in.

GlassNavbar

Navbar Islands

Three separate floating glass islands — brand pill, centered links pill, actions pill with gradient CTA — that merge into a single button and frosted panel on mobile.

GlassNavbar

Navbar Announcement

Two-tier header: a dismissible ink announcement bar with a link, above a hairline navbar with links, a ⌘K search trigger (wired to onSearch) and log in / demo actions.

MinimalNavbar

Navbar Blur

Sticky 56px top bar that is transparent at the top of the page and turns into a translucent blurred bar with a hairline once scrolled. Muted links, ink CTA, compact mobile menu.

MinimalNavbar

Navbar Mega

Navbar with a full-width Product mega menu: six icon + description items in a 3-column grid and a featured launch card, closes on outside click and Escape; grouped mobile menu.

MinimalNavbar

Navbar Pill

Floating, centered pill navbar with backdrop blur: logo, links with a shared hover/active pill indicator, ink CTA; collapses into a dropdown sheet with Escape support on mobile.

MinimalNavbar

Navbar Fullscreen

Minimal bar (logo + “Menu”) that opens a full-screen ink overlay with giant stacked links sliding up line by line, mono notes and contact details; Escape closes and scroll is locked.

Mono CleanNavbar

Navbar Index

Studio-style index navbar: numbered links “(01) Work”, a live local clock with city in mono, availability dot in the signal color and an underlined text CTA; stacked list on mobile.

Mono CleanNavbar

Navbar Meta

Two-tier editorial header: a mono meta strip (version, status with signal dot, changelog link) over a nav bar closed by a full-ink rule; oversize logo wordmark on desktop; stacked menu on mobile.

Mono CleanNavbar

Navbar Mono

Clean monochrome navbar on a hairline: square logo, links whose underline wipes in on hover (orange dot marks the active one), text sign-in and an ink button; text “Menu/Close” toggle opens a ruled list on mobile.

Mono CleanNavbar

Navbar Corporate

Corporate navbar: logo, two dropdown menus (items with descriptions), plain links, “Sign in”, bordered “Contact sales” and a blue primary; mobile accordion menu.

Neo CorporateNavbar

Navbar Mega

Navbar with a wide “Platform” mega menu: three titled columns of icon links plus a navy promo card, closing on Escape/outside click; stacked on mobile.

Neo CorporateNavbar

Navbar Scroll

Sticky navbar that starts tall and transparent and condenses on scroll into a white bordered bar with a subtle shadow and a smaller CTA.

Neo CorporateNavbar

Navbar Utility

Two-tier enterprise header: a slim surface-2 utility bar (system status, sales phone, language select, support/login) above the main navbar.

Neo CorporateNavbar

Navbar Announce

Sage announcement strip (leaf icon, message, link, dismiss) above a simple cream navbar with a terracotta-tinted secondary pill and sage primary pill; drop-down menu on mobile.

Organic SoftNavbar

Navbar Floating

Floating pill navbar: a rounded, softly blurred surface bar detached from the top edge, with centered links and an arrow CTA; expands into a rounded panel on mobile.

Organic SoftNavbar

Navbar Organic

Calm cream navbar: round leaf logo + serif wordmark, links with a hand-drawn underline on the active one, text sign-in and a sage pill CTA; rounded sheet menu on mobile.

Organic SoftNavbar

Navbar Split

Editorial symmetric navbar: links split on both sides of a centered logo + large serif wordmark, a thin warm rule below, outlined pill CTA; full-width stacked menu on mobile.

Organic SoftNavbar

Navbar Centered

Symmetric navbar inside a soft rounded well: links split left and right of a centered wordmark with two overlapping dots, ink pill CTA at the far right; stacked sheet on mobile.

Soft FlatNavbar

Navbar Sheet

Minimal bar with a wordmark and a big “Menu” pill that unfolds a grid of pastel link tiles (title, description, arrow) with a staggered bouncy entrance, on every screen size.

Soft FlatNavbar

Navbar Soft

Friendly sticky navbar: rounded pastel logo mark, pill links with a soft lavender active fill, text log-in and a periwinkle pill CTA; rounded drop-down sheet on mobile.

Soft FlatNavbar

Navbar Tabs

Two-row header: brand and CTA on top, then a horizontally scrollable strip of pill tabs with emoji where the active tab is an ink-filled pill.

Soft FlatNavbar