Navigation
Headers
Tawny, Art, and Dev in one frame. Open a header in the sidebar for its own source.
components/headers
Tawny
DarkBrowse designs
Hugo Lin
lin hugo
aboutblogprojects
Source
Copy the files below into your project.
apps/web/components/landing/showcases/headers-demo.tsx
import { ArtHeaderDemo, ArtHeaderDetail } from '@/components/landing/showcases/art-header-demo'
import { DevHeaderDemo, DevHeaderDetail } from '@/components/landing/showcases/dev-header-demo'
import { TawnyHeaderDemo, TawnyHeaderDetail } from '@/components/landing/showcases/tawny-header-demo'
/**
* Tawny, Art, and Dev in one frame. Each band keeps its own desktop canvas
* and clips to the bar, so the three headers share a single 16:9 card.
*/
export function HeadersDemo() {
return (
<div className="flex h-full flex-col">
<div className="min-h-0 flex-1 overflow-hidden border-b border-border">
<TawnyHeaderDemo />
</div>
<div className="min-h-0 flex-1 overflow-hidden border-b border-border">
<ArtHeaderDemo />
</div>
<div className="min-h-0 flex-1 overflow-hidden">
<DevHeaderDemo />
</div>
</div>
)
}
/** Detail page: the three bars at a readable size, still one frame. */
export function HeadersDetail() {
return (
<div className="flex h-full flex-col">
<div className="min-h-0 flex-1 overflow-hidden border-b border-border">
<TawnyHeaderDetail />
</div>
<div className="min-h-0 flex-1 overflow-hidden border-b border-border">
<ArtHeaderDetail />
</div>
<div className="min-h-0 flex-1 overflow-hidden">
<DevHeaderDetail />
</div>
</div>
)
}apps/web/components/landing/showcases/tawny-header-demo.tsx
import { Logo } from '@/components/logo'
import { ScaledDesignCanvas } from '@/components/landing/scaled-design-canvas'
import { cn } from '@tawny/ui/lib/utils'
/**
* Desktop-fidelity Tawny navbar twin — fixed canvas scaled into the frame.
* Inert visual twin; no mobile menu.
*/
export function TawnyHeaderDemo({ className }: { className?: string }) {
return (
<div
role="img"
aria-label="Tawny navigation bar preview"
inert
className={cn('h-full select-none', className)}
>
<ScaledDesignCanvas height={240}>
<div className="flex h-full flex-col bg-background">
<header className="shrink-0 border-b border-border bg-background/80 backdrop-blur-xl">
{/*
Static twin of the live math:
side ≈ max(logo, theme+cta) + gap → ~268px at this canvas.
nav band = total − 2 × side, flex-centered.
*/}
<div className="relative mx-auto flex h-14 max-w-340 items-center px-6">
<div className="relative z-10 flex items-center gap-2.5">
<Logo className="size-8 rounded-md" />
<span className="font-serif text-xl italic tracking-tight text-foreground">
Tawny
</span>
</div>
<nav
className="absolute inset-y-0 flex items-center justify-center"
style={{ left: 268, right: 268 }}
aria-hidden="true"
>
<div className="flex items-center gap-1">
{['Designs', 'Components', 'Writeups'].map((label, i) => (
<span
key={label}
className={cn(
'rounded-md px-3 py-1.5 text-sm',
i === 0
? 'bg-muted text-foreground'
: 'text-muted-foreground',
)}
>
{label}
</span>
))}
</div>
</nav>
<div className="relative z-10 ml-auto flex items-center gap-2">
<span className="inline-flex h-8 items-center rounded-full border border-border bg-muted/40 px-3 text-sm font-medium text-muted-foreground">
Dark
</span>
<span className="inline-flex items-center gap-1.5 rounded-full bg-foreground px-4 py-1.5 text-sm font-medium text-background">
Browse designs
</span>
</div>
</div>
</header>
<div
aria-hidden="true"
className="min-h-0 flex-1 bg-linear-to-b from-muted/30 to-background"
/>
</div>
</ScaledDesignCanvas>
</div>
)
}
/** Detail page: the bar at real size, with a page body under it. */
export function TawnyHeaderDetail({ className }: { className?: string }) {
return (
<div
className={cn('flex h-full select-none flex-col bg-background', className)}
inert
>
<header className="shrink-0 border-b border-border bg-background/80">
<div className="flex h-16 items-center justify-between gap-4 px-6">
<div className="flex items-center gap-2.5">
<Logo className="size-8 rounded-md" />
<span className="font-serif text-2xl italic tracking-tight text-foreground">
Tawny
</span>
</div>
<nav className="flex items-center gap-1" aria-hidden="true">
{['Designs', 'Components', 'Writeups'].map((label, i) => (
<span
key={label}
className={cn(
'rounded-md px-3 py-1.5 text-sm',
i === 0 ? 'bg-muted text-foreground' : 'text-muted-foreground',
)}
>
{label}
</span>
))}
</nav>
<div className="flex items-center gap-2">
<span className="inline-flex h-8 items-center rounded-full border border-border bg-muted/40 px-3 text-sm font-medium text-muted-foreground">
Dark
</span>
<span className="inline-flex items-center rounded-full bg-foreground px-4 py-1.5 text-sm font-medium text-background">
Browse designs
</span>
</div>
</div>
</header>
<div className="min-h-0 flex-1 bg-linear-to-b from-muted/30 to-background" />
</div>
)
}apps/web/components/landing/showcases/art-header-demo.tsx
import { DM_Sans, JetBrains_Mono, Playfair_Display } from 'next/font/google'
import { ScaledDesignCanvas } from '@/components/landing/scaled-design-canvas'
import { cn } from '@tawny/ui/lib/utils'
const artDisplay = Playfair_Display({
subsets: ['latin'],
variable: '--font-art-serif-display',
})
const artSans = DM_Sans({
subsets: ['latin'],
variable: '--font-art-sans-body',
})
const artMono = JetBrains_Mono({
subsets: ['latin'],
variable: '--font-art-mono',
})
/**
* Desktop-fidelity Art header twin — fixed canvas scaled into the frame.
* Inert visual twin; no navigation.
*/
export function ArtHeaderDemo({ className }: { className?: string }) {
return (
<div
className={cn(
artDisplay.variable,
artSans.variable,
artMono.variable,
artSans.className,
'h-full font-(family-name:--font-art-sans-body)',
className,
)}
>
<div
role="img"
aria-label="Art navigation header preview"
inert
className="h-full select-none"
>
<ScaledDesignCanvas height={240}>
<div className="art-root flex h-full flex-col overflow-hidden bg-black text-art-bento-ink antialiased">
<header className="shrink-0 bg-art-bento-bg pt-3">
<div className="relative flex items-center justify-between gap-4 px-6 pb-3">
<span className="text-lg font-bold tracking-tight text-art-bento-ink">
Hugo Lin
</span>
<nav className="flex flex-wrap items-center justify-end gap-5">
<ul className="flex items-center gap-5 text-sm font-bold">
{['Notes', 'Projects', 'About'].map((label) => (
<li key={label}>
<span className="opacity-90">{label}</span>
</li>
))}
</ul>
<span className="font-mono text-xs font-bold tracking-wide">
<span>EN</span>
<span className="mx-1 opacity-40">|</span>
<span className="opacity-40">中</span>
</span>
</nav>
</div>
</header>
<div aria-hidden="true" className="min-h-0 flex-1 bg-black" />
</div>
</ScaledDesignCanvas>
</div>
</div>
)
}
export function ArtHeaderDetail({ className }: { className?: string }) {
return (
<div
className={cn(
artDisplay.variable,
artSans.variable,
artMono.variable,
artSans.className,
'flex h-full flex-col font-(family-name:--font-art-sans-body)',
className,
)}
inert
>
<div className="art-root flex h-full flex-col bg-black text-art-bento-ink">
<header className="shrink-0 bg-art-bento-bg pt-4">
<div className="flex items-center justify-between gap-4 px-8 pb-4">
<span className="text-2xl font-bold tracking-tight">Hugo Lin</span>
<nav className="flex items-center gap-6 text-base font-bold">
{['Notes', 'Projects', 'About'].map((label) => (
<span key={label}>{label}</span>
))}
<span className="font-mono text-sm">
EN
<span className="mx-1 opacity-40">|</span>
<span className="opacity-40">中</span>
</span>
</nav>
</div>
</header>
<div className="min-h-0 flex-1 bg-black" />
</div>
</div>
)
}apps/web/components/landing/showcases/dev-header-demo.tsx
import { JetBrains_Mono } from 'next/font/google'
import { ScaledDesignCanvas } from '@/components/landing/scaled-design-canvas'
import { cn } from '@tawny/ui/lib/utils'
const devMono = JetBrains_Mono({
subsets: ['latin'],
variable: '--font-dev-mono',
})
/**
* Desktop-fidelity Dev header twin — fixed canvas scaled into the frame.
* Inert visual twin; no navigation.
*/
export function DevHeaderDemo({ className }: { className?: string }) {
return (
<div
className={cn(
devMono.variable,
devMono.className,
'h-full font-mono',
className,
)}
>
<div
role="img"
aria-label="Dev navigation header preview"
inert
className="h-full select-none"
>
<ScaledDesignCanvas height={240}>
<div
className="dev-root flex h-full flex-col bg-(--dev-background,#09090b) text-(--dev-foreground,#e4e4e7) antialiased"
data-theme="dark"
>
<div className="mx-auto w-full max-w-2xl px-10 pt-14">
<nav>
<div className="flex items-center justify-between font-extrabold">
<span className="inline-flex items-center text-2xl">
lin hugo
<span
aria-hidden="true"
className="ml-1 inline-block animate-pulse text-red-500"
>
_
</span>
</span>
</div>
<div className="mt-1.5 flex gap-4">
{(['about', 'blog', 'projects'] as const).map((label, i) => (
<span
key={label}
className={cn(
'text-lg',
i === 0
? 'font-extrabold text-(--dev-foreground,#e4e4e7)'
: 'font-normal text-(--dev-muted,#a1a1aa)',
)}
>
{label}
</span>
))}
</div>
</nav>
</div>
<div aria-hidden="true" className="min-h-0 flex-1" />
</div>
</ScaledDesignCanvas>
</div>
</div>
)
}
export function DevHeaderDetail({ className }: { className?: string }) {
return (
<div
className={cn(
devMono.variable,
devMono.className,
'flex h-full flex-col font-mono',
className,
)}
inert
>
<div
className="dev-root flex h-full flex-col bg-(--dev-background,#09090b) text-(--dev-foreground,#e4e4e7)"
data-theme="dark"
>
<div className="mx-auto w-full max-w-2xl px-10 pt-16">
<div className="flex items-center text-4xl font-extrabold">
lin hugo
<span aria-hidden="true" className="ml-1 inline-block animate-pulse text-red-500">
_
</span>
</div>
<div className="mt-3 flex gap-6 text-xl">
{(['about', 'blog', 'projects'] as const).map((label, i) => (
<span
key={label}
className={
i === 0
? 'font-extrabold text-(--dev-foreground,#e4e4e7)'
: 'font-normal text-(--dev-muted,#a1a1aa)'
}
>
{label}
</span>
))}
</div>
</div>
</div>
</div>
)
}