Loading page…
Loading page…
The animated sidebar's menu rows, flying the wallet's Privateer colours: the active row hoists a swallow-tailed pennant — a clipped brand-primary field with a halftone print pass and press lighting — and the pennant glides between rows on the shared-layout spring when the selection moves. Hovered rows raise a faint ghost of the same shape. This styleguide's own sidebar runs the treatment; so does anything that passes highlight="pennant".
Same menu primitives, two highlight treatments. The pennant is opt-in per row — the default pill stays for quiet chrome. Click between rows to see the shared-layout glide; hover for the ghost.
Rough-clipped flag field with halftone and paper mottle — inky, not shiny.
The shadcn-flavoured rounded tint — unchanged.
<AnimatedSidebarMenu pillClassName="ch-pennant-soft">
<AnimatedSidebarMenuItem>
<AnimatedSidebarMenuLink href="/vaults" isActive highlight="pennant" icon={<Vault />}>
Vaults
</AnimatedSidebarMenuLink>
</AnimatedSidebarMenuItem>
</AnimatedSidebarMenu>--ch-primary--ch-primary-fg--ch-focusThe pennant flies --ch-flag-field: the house red in the base scheme, re-derived from the skin's primary under data-brand — no per-brand assets. Ink is --ch-flag-ink bone.
<div data-brand="corsair">
{/* pennants inside now fly corsair red */}
</div>The row itself stays rectangular and unclipped — the clip-path lives on the highlight layer only, so the focus ring, hit target, and truncating label are untouched. The active layer is a shared-layout motion span (layoutId), the halftone and press lighting are its pseudo-elements, and the hover ghost is the row's own ::before.
/* styles.css — the shape, one place */
.ch-pennant {
clip-path: var(--ch-pennant-shape); /* rough swallow-tail polygon */
background: var(--ch-flag-field); /* house red; per-skin under data-brand */
}
.ch-pennant::before { /* halftone ink pass */ }
.ch-pennant::after { /* multiplied paper mottle */ }--ch-primary--ch-primary-fg--ch-motion-duration-fastThe rail is borderless and separator-free by default, sits at z-30 (a BannerNavbar at z-40 always passes over it, docked or not), and can undock: autoHide collapses it when pointer and focus leave, and a thin edge hot-strip summons it back.
{/* docked (default) */}
<AnimatedSidebar collapsible="offcanvas" />
{/* undocked — hides on blur, returns when the pointer nears the edge */}
<AnimatedSidebar collapsible="offcanvas" autoHide />For layouts with no navbar, the rail itself carries the material: SidebarStock lays the banner's print texture behind the menu, re-inked to monotone (or the brand flag), with a torn outer edge and a silhouette shadow. Drop it in as the first child of an AnimatedSidebar with panelClassName='relative'.
<AnimatedSidebar collapsible="offcanvas" panelClassName="relative">
<SidebarStock tone="monotone" /> {/* or tone="flag" to match the banner */}
<AnimatedSidebarContent>…</AnimatedSidebarContent>
</AnimatedSidebar>--ch-sidebar-stock--ch-flag-field--ch-flag-ink