Tabs, segmented controls, links, the site header and the command palette.
Ways to move around: tabs and segmented controls follow the WAI-ARIA patterns, links change pages without a reload, and ⌘K finds anything on the site.
6 parts
Switch between views of the same thing. A lit pill or a hairline glides to the selected tab; arrow keys move between tabs.
import { useState } from 'react'import { Icon } from '@rchursin/product/icons/Icon'import { SampleBadge } from '@rchursin/product/shell/layout'import { Switch, Tabs } from '@rchursin/product/ui'
/** * The pill variant: a lit pill glides to the selected tab. ← → move and select, Home / End * jump. Two panels hold only text, so focusablePanels puts every panel in the Tab order. */const facts = [ ['Status', 'In progress'], ['Due', 'Oct 24'], ['Tasks', '12 of 18 done'],]
const activity = [ { icon: 'status-progress', text: 'Status changed to In progress', when: '2 hours ago' }, { icon: 'plus', text: 'Three tasks added from the launch checklist', when: 'Yesterday' }, { icon: 'calendar', text: 'Due date set to Oct 24', when: 'Oct 9' },] as constA small router with no dependencies: Link changes page without a reload, useRouter says where you are, in history or hash mode.
import { Icon } from '@rchursin/product/icons/Icon'import { Link } from '@rchursin/product/lib/router'
/** * Real pages of this site: each Link changes page without a reload. The one you are on gets * aria-current="page", drawn here as a solid square. A full URL renders a plain <a>. */const pages = [ { to: '/', label: 'Home' }, { to: '/about', label: 'About' }, { to: '/library', label: 'Library' }, { to: '/library/navigation', label: 'Navigation' }, { to: '/library/navigation/link', label: 'Link & router' },]
export default function LinkList() { return ( <div className="flex w-full max-w-sm flex-col gap-3"> <ul className="flex flex-col"> {pages.map((p) => (One search field over every page and action, opened with ⌘K, grouped and ranked, run with Enter.
import { useMemo, useState } from 'react'import { Button, CommandPalette, useToast, type CommandItem } from '@rchursin/product/ui'
/** * Open it, type, then ↑ ↓ and Enter. Before you type it shows the suggested commands; typing * searches all of them. These commands show a toast instead of doing the real thing. */export default function CommandPaletteBasic() { const [open, setOpen] = useState(false) const toast = useToast()
const items = useMemo<CommandItem[]>(() => { const demo = (title: string) => () => toast({ title, description: 'Demo command: nothing changed.' }) return [ { id: 'go-projects', group: 'Go to', label: 'Projects', icon: 'folder', hint: 'G then P', onSelect: demo('Opened Projects') }, { id: 'go-inbox', group: 'Go to', label: 'Inbox', icon: 'inbox', hint: 'G then I', onSelect: demo('Opened Inbox') }, { id: 'go-calendar', group: 'Go to', label: 'Calendar', icon: 'calendar', keywords: ['schedule', 'events'], onSelect: demo('Opened Calendar') }, { id: 'new-task', group: 'Create', label: 'New task', icon: 'plus', hint: 'C', keywords: ['add', 'todo', 'issue'], onSelect: demo('Task created') }, { id: 'new-note', group: 'Create', label: 'New note', icon: 'note', keywords: ['write', 'memo'], onSelect: demo('Note created') }, { id: 'new-event', group: 'Create', label: 'New event', icon: 'calendar-plus', keywords: ['meeting', 'schedule'], onSelect: demo('Event created') },The home pages’ sticky header in three styles: a full bar, a floating glass pill and a minimal mono row.
import { HeaderLink, SiteFooter, SiteHeader, SkipLink } from '@rchursin/home/Chrome'import { ButtonLink, Container } from '@rchursin/home/ui'
/** * The bar header on a whole page. It sticks to the top, is clear until the window scrolls, then * frosts with a hairline. Its four default links point at sections of the page, so they work. * Below 768px the links fold into a menu button. */const sections = [ { id: 'product', title: 'Product', body: 'Reads the sessions your coding agents already write and shows which skills they use, skip or repeat.' }, { id: 'how', title: 'How it works', body: 'Run one command in a repository. It reads the agent folders locally and prints a short report.' }, { id: 'pricing', title: 'Pricing', body: 'The local scan is free. Team mode keeps the history and adds everyone’s machines.' }, { id: 'docs', title: 'Docs', body: 'Set-up, the report explained line by line, and how to share it with your team.' },]
export default function HeaderBarPage() { return ( <div id="top" className="bg-surface text-fg"> <SkipLink /> <SiteHeader secondary={<HeaderLink href="#start">Sign in</HeaderLink>} />The home pages’ footer: three link columns with a cropped wordmark, or one simple row.
import { SiteFooter } from '@rchursin/home/Chrome'
/** * The columns footer that ends the home pages: logo and tagline, three link columns, the year, * a contact placeholder, and the wordmark set huge and cropped by the edge. Its words and links * live in Chrome.tsx (the links are href="#" placeholders): copy the file to make it yours. */export default function FooterColumns() { return ( <div className="flex min-h-[180px] w-full flex-col justify-end bg-surface"> <SiteFooter /> </div> )}A “Skip to content” link that stays hidden until the first Tab, then jumps past the header to #main.
import { useRef } from 'react'import { Logo } from '@rchursin/brand/Logo'import { SkipLink } from '@rchursin/home/Chrome'import { Button } from '@rchursin/product/ui'import { Link } from '@rchursin/product/lib/router'
/** * The top of a page, with the skip link first. It is hidden until it has focus: press Tab from * the Copy button above, or use the button below. Enter jumps to #main, which on this site is * the start of this page's content. */export default function SkipLinkFocus() { const page = useRef<HTMLDivElement>(null) const show = () => page.current?.querySelector<HTMLAnchorElement>('a[href="#main"]')?.focus()
return ( <div className="flex w-full max-w-lg flex-col items-center gap-5"> <div ref={page} className="relative w-full overflow-hidden rounded-xl bg-surface ring-1 ring-line"> <SkipLink /> <div className="flex h-14 items-center gap-6 border-b border-line px-4">The new home page, the docs and a contact form, ready for the first visitors.
An email every Monday with what moved.
Anyone with the link can read the project.
Sample page
Scroll this page: the header stays at the top and frosts once the content passes under it.
See how it worksReads the sessions your coding agents already write and shows which skills they use, skip or repeat.
Run one command in a repository. It reads the agent folders locally and prints a short report.
The local scan is free. Team mode keeps the history and adds everyone’s machines.
Set-up, the report explained line by line, and how to share it with your team.