Files
AgentCompany/landing/components/layout/navbar.tsx
T
ZacharyZhang-NY c0f677ccc9 Rebuild navbar, hero, and feature sections in adaline style
- navbar: sticky, transparent to blur-on-scroll, wordmark + mono nav links +
  theme toggle + Download CTA, Reicon Menu/Xmark icons (components/layout)
- theme-toggle: Reicon Sun/Moon icons
- hero: meadow badge, tight Instrument Sans headline, Download + How-it-works
  CTAs, availability line, framed dashboard shot (components/sections)
- features: five stacked heading-over-panel sections mapping the org chart,
  office, messages, connectors and cost-control screens
- ui/media-frame: shared framed product-shot panel
- reveal: progressive enhancement — content is visible without JS and only
  hidden once the js class is present, then revealed on scroll
- remove the superseded flat navbar/hero/features components

Verified: next build green; desktop + mobile screenshots reviewed.
2026-07-07 22:08:31 -04:00

115 lines
3.9 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { Menu } from "reicon-react/icons/Menu";
import { Xmark } from "reicon-react/icons/Xmark";
import { Container } from "../ui/container";
import { Button } from "../ui/button";
import { IconMark } from "../icon-mark";
import { ThemeToggle } from "../theme-toggle";
const navLinks = [
{ label: "Features", href: "#features" },
{ label: "How it works", href: "#how-it-works" },
{ label: "FAQ", href: "#faq" },
];
export function Navbar() {
const [mobileOpen, setMobileOpen] = useState(false);
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 8);
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();
return () => window.removeEventListener("scroll", onScroll);
}, []);
useEffect(() => {
const onResize = () => {
if (window.innerWidth >= 768) {
setMobileOpen(false);
}
};
window.addEventListener("resize", onResize, { passive: true });
return () => window.removeEventListener("resize", onResize);
}, []);
return (
<nav
className={[
"enter-nav sticky top-0 z-50 transition-colors duration-300",
scrolled
? "border-b border-[var(--border)] bg-[var(--bg)]/85 backdrop-blur-xl"
: "border-b border-transparent bg-transparent",
].join(" ")}
>
<Container>
<div className="flex h-16 items-center justify-between">
<a href="#" className="flex shrink-0 items-center gap-2.5" aria-label="AgentCompany home">
<IconMark size={28} />
<span className="text-lg font-medium tracking-[-0.02em] text-[var(--text)]">AgentCompany</span>
</a>
<div className="hidden items-center gap-1 md:flex">
{navLinks.map(({ label, href }) => (
<a
key={href}
href={href}
className="eyebrow rounded-full px-3 py-2 text-sm text-[var(--muted)] transition-colors hover:text-[var(--text)]"
>
{label}
</a>
))}
</div>
<div className="hidden items-center gap-2 md:flex">
<ThemeToggle />
<Button href="#download" size="sm">
Download
</Button>
</div>
<div className="flex items-center gap-1 md:hidden">
<ThemeToggle />
<button
type="button"
onClick={() => setMobileOpen((value) => !value)}
aria-label={mobileOpen ? "Close navigation menu" : "Open navigation menu"}
aria-expanded={mobileOpen}
aria-controls="mobile-nav"
className="inline-flex h-10 w-10 cursor-pointer items-center justify-center rounded-full text-[var(--text)] transition-colors hover:bg-[var(--panel-soft)]"
>
{mobileOpen ? <Xmark size={22} /> : <Menu size={22} />}
</button>
</div>
</div>
</Container>
<div
id="mobile-nav"
className={[
"overflow-hidden border-b transition-all duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] md:hidden",
mobileOpen ? "max-h-72 border-[var(--border)] bg-[var(--bg)]/95 backdrop-blur-xl" : "max-h-0 border-transparent",
].join(" ")}
>
<Container className="flex flex-col gap-1 pb-4 pt-1">
{navLinks.map(({ label, href }) => (
<a
key={href}
href={href}
onClick={() => setMobileOpen(false)}
className="eyebrow rounded-lg px-3 py-2.5 text-sm text-[var(--muted)] transition-colors hover:bg-[var(--panel-soft)] hover:text-[var(--text)]"
>
{label}
</a>
))}
<Button href="#download" size="sm" className="mt-2 w-full">
Download
</Button>
</Container>
</div>
</nav>
);
}