A print studio's header. The rail under it runs to whichever link you point at and parks under the current page when you leave.
registry/demos/dot-rail-header-demo.tsx
"use client";
import * as React from "react";
import { DotRail } from "@/components/ui/dot-rail";
const links = [
{ label: "Prints", href: "#prints" },
{ label: "Studio", href: "#studio" },
{ label: "Workshops", href: "#workshops" },
{ label: "Journal", href: "#journal" },
];
function Mark() {
return (
<svg viewBox="0 0 20 20" aria-hidden className="size-5">
<circle cx="10" cy="10" r="8.25" className="fill-none stroke-current" strokeWidth="1.5" />
<circle cx="10" cy="10" r="3.25" className="fill-[var(--dot-rail-accent)]" />
</svg>
);
}
export function DotRailHeaderDemo() {
const navRef = React.useRef<HTMLElement>(null);
const [current, setCurrent] = React.useState("#studio");
return (
<div className="@container w-full max-w-4xl overflow-hidden rounded-2xl border border-[#0b0b0d]/10 bg-[#fafaf9] text-[#0b0b0d] [--dot-rail-accent:#ff5a1f] dark:border-white/10 dark:bg-[#07080c] dark:text-[#f4f4f6] dark:[--dot-rail-accent:#ff6a2b]">
<header className="px-5 pt-4 @[44rem]:px-8">
<div className="flex flex-wrap items-center justify-between gap-x-6 gap-y-2">
<a
href="#"
onClick={(e) => e.preventDefault()}
className="flex items-center gap-2 rounded-md text-[15px] font-semibold tracking-tight focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-current"
>
<Mark />
Pressroom
</a>
<nav
ref={navRef}
aria-label="Main"
className="order-last -mx-3 flex w-[calc(100%+1.5rem)] justify-between @[28rem]:mx-0 @[28rem]:w-full @[28rem]:justify-center @[28rem]:gap-2 @[44rem]:order-none @[44rem]:w-auto"
>
{links.map((link) => (
<a
key={link.href}
href={link.href}
aria-current={current === link.href ? "page" : undefined}
onClick={(e) => {
e.preventDefault();
setCurrent(link.href);
}}
className="rounded-full px-3 py-2 text-[13px] font-medium text-[#0b0b0d]/60 transition-colors duration-150 hover:text-[#0b0b0d] focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:outline-current aria-[current=page]:text-[#0b0b0d] dark:text-[#f4f4f6]/60 dark:hover:text-[#f4f4f6] dark:aria-[current=page]:text-[#f4f4f6]"
>
{link.label}
</a>
))}
</nav>
<a
href="#book"
onClick={(e) => e.preventDefault()}
className="rounded-full bg-[#0b0b0d] px-4 py-2 text-[13px] font-medium text-[#fafaf9] transition-transform duration-150 active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current dark:bg-[#f4f4f6] dark:text-[#07080c]"
>
Book a print run
</a>
</div>
<DotRail trackRef={navRef} className="mt-2" />
</header>
<section className="px-5 pt-10 pb-12 text-center @[44rem]:px-8 @[44rem]:pt-14 @[44rem]:pb-16">
<h2 className="font-serif text-4xl tracking-tight text-balance @[44rem]:text-[3.25rem] @[44rem]:leading-[1.05]">
Small runs, <em className="text-[#2747ff] dark:text-[#8292ff]">loud</em> colors
</h2>
<p className="mx-auto mt-4 max-w-md text-[15px] leading-relaxed text-[#0b0b0d]/70 dark:text-[#f4f4f6]/70">
Zines, posters and lookbooks printed a hundred at a time on two riso drums, in a back room off Calder Street.
</p>
<p className="mt-6 font-mono text-[11px] tracking-[0.18em] text-[#0b0b0d]/60 uppercase dark:text-[#f4f4f6]/60">
Riso · 2 drums · 11 inks
</p>
</section>
</div>
);
}
Live preview, examples and props: https://keyframeui.com/components/dot-rail#dot-rail-header-demo
