'use client'
import { useEffect, useState } from 'react'
import { NavbarSidebarHybrid } from '@/components/blocks/navbar-sidebar-hybrid'
const GROUPS = [
{
label: 'Getting started',
items: [
{ label: 'Introduction', href: '#intro' },
{ label: 'Installation', href: '#install' },
{ label: 'Project structure', href: '#structure' },
],
},
{
label: 'Core concepts',
items: [
{ label: 'Tokens', href: '#tokens' },
{ label: 'Motion', href: '#motion' },
{ label: 'Composition', href: '#composition' },
],
},
{
label: 'Components',
items: [
{ label: 'Buttons', href: '#buttons' },
{ label: 'Navbars', href: '#navbars' },
{ label: 'Forms', href: '#forms' },
],
},
]
const INTRO_PAGE = {
title: 'Introduction',
body: 'Field Notes is the internal design system for Atlas Cloud. Every surface ships as a self-contained registry block, no app shell required, no provider tree to wire.',
}
const PAGES: Record<string, { title: string; body: string }> = {
'#intro': INTRO_PAGE,
'#install': {
title: 'Installation',
body: 'Add blocks with the registry CLI. Each item brings its own motion constants and token usage so themes re-skin live without rebuilds.',
},
'#structure': {
title: 'Project structure',
body: 'Blocks live under registry/<category>/<name>. A component file, a production demo, and meta.json are the only required artifacts.',
},
'#tokens': {
title: 'Tokens',
body: 'Semantic shadcn tokens only, background, foreground, primary, muted, border. Champagne ink is the default preset; seven more ship as registry themes.',
},
'#motion': {
title: 'Motion',
body: 'One choreographed sequence per component. EASE_OUT for entrances, SPRING_SETTLE for layout morphs, reduced-motion paths that still look designed.',
},
'#composition': {
title: 'Composition',
body: 'Hairlines over shadows. One accent moment per viewport. Mono micro-labels where others use colored pills.',
},
'#buttons': {
title: 'Buttons',
body: 'Primary fills use the accent once. Secondary and ghost stay neutral. Focus rings are mandatory on every interactive control.',
},
'#navbars': {
title: 'Navbars',
body: 'Site chrome is a first-class category, glass bars, pill docks, command sheets, and this docs hybrid all share the same drafting-table language.',
},
'#forms': {
title: 'Forms',
body: 'Inputs inherit focus and border tokens. Validation speaks in destructive without drowning the layout in color.',
},
}
export default function NavbarSidebarHybridDemo() {
const [active, setActive] = useState('#intro')
const page = PAGES[active] ?? INTRO_PAGE
// Demo-only: keep the rail keyline in sync without a real router
useEffect(() => {
const onClick = (e: MouseEvent) => {
const a = (e.target as HTMLElement).closest('a')
if (!a) return
const href = a.getAttribute('href')
if (href && href.startsWith('#') && PAGES[href]) {
e.preventDefault()
setActive(href)
}
}
document.addEventListener('click', onClick)
return () => document.removeEventListener('click', onClick)
}, [])
return (
<NavbarSidebarHybrid
brand={
<span className="inline-flex items-baseline gap-1.5">
Field
<span className="font-mono text-[10px] uppercase tracking-[0.2em] text-muted-foreground">
notes
</span>
</span>
}
groups={GROUPS}
active={active}
contentId="docs-main"
>
<div className="mx-auto max-w-3xl px-4 py-10 sm:px-6 sm:py-14">
<p className="font-mono text-[11px] uppercase tracking-[0.2em] text-muted-foreground">
Documentation
</p>
<h1 className="mt-2 text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
{page.title}
</h1>
<p className="mt-4 text-base leading-relaxed text-muted-foreground">
{page.body}
</p>
<div className="mt-10 space-y-3">
{[
'Skip link is the first tab stop, focus it to jump past the rail.',
'Active item uses weight plus a primary keyline, never color alone.',
'On large screens the rail sticks; on small screens a glass drawer opens.',
].map((line) => (
<div
key={line}
className="rounded-2xl border border-border/60 bg-card px-5 py-4 text-sm text-muted-foreground"
>
{line}
</div>
))}
</div>
</div>
</NavbarSidebarHybrid>
)
}