BracketFrame
Wraps content in corner-bracket reticles with optional corner labels; the brackets can converge onto the content as an animated targeting lock.
Target Acquired
SEC // 0x4A2 :: SIGNAL NOMINAL
"use client";import { BracketFrame } from "@/registry/okibi/ui/bracket-frame";export default function BracketFrameDemo() { return ( <BracketFrame label="TARGET // LOCK" corners={{ tr: "TR", bl: "BL", br: "BR" }} className="max-w-sm" > <h3 className="font-display text-xl font-extrabold uppercase tracking-tight"> Target Acquired </h3> <p className="mt-1 font-mono text-xs text-muted-foreground"> SEC // 0x4A2 :: SIGNAL NOMINAL </p> </BracketFrame> );}npx shadcn@latest add https://okibi.cndr.dev/r/bracket-frame.jsonInstallation
Install the theme first, then add the component:
npx shadcn@latest add https://okibi.cndr.dev/r/bracket-frame.jsonCopy the source from the Code tab above into components/ui/bracket-frame.tsx. It uses the cn helper and the okibi theme tokens — install the theme first if you haven't.
Usage
import { BracketFrame } from "@/components/ui/bracket-frame"
<BracketFrame label="SEC // 01" color="primary">
Framed content
</BracketFrame>Anatomy
<BracketFrame label="SEC // 01" color="border-strong">
{/* four decorative corner brackets + optional label bands
wrap your content — the content stays fully interactive */}
Framed content
</BracketFrame>Examples
Corner labels
Set a header label and any of the four corners, and switch the reticle color (primary / magenta / cyan) to frame a panel with HUD annotations.
Grid Reference
SEC // 0x4A2 :: SIGNAL NOMINAL
import { BracketFrame } from "@/registry/okibi/ui/bracket-frame";export default function CornersDemo() { return ( <BracketFrame label="TARGET // LOCK" corners={{ tl: "TL", tr: "TR", bl: "BL", br: "BR" }} color="cyan" className="max-w-sm p-6" > <h3 className="font-display text-xl font-extrabold uppercase tracking-tight"> Grid Reference </h3> <p className="mt-1 font-mono text-xs text-muted-foreground"> SEC // 0x4A2 :: SIGNAL NOMINAL </p> </BracketFrame> );}Lock-on
Set animate to make the corner brackets converge onto the content with a hard snap — a HUD reticle acquiring its target. Drive it with trigger: on hover, on focus, when scrolled into view, or held always. Reduced motion renders the brackets already-locked.
import { BracketFrame } from "@/registry/okibi/ui/bracket-frame";import { Readout } from "@/registry/okibi/ui/readout";export default function BracketFrameLockDemo() { return ( <div className="flex flex-wrap items-center justify-center gap-10"> <BracketFrame animate trigger="hover" label="TGT // 01"> <Readout label="Throughput" value="847" unit="req/s" delta={12.4} className="w-48" /> </BracketFrame> <BracketFrame animate trigger="always" label="LOCKED"> <Readout label="Latency" value="38" unit="ms" delta={-3.1} className="w-48" /> </BracketFrame> </div> );}Reticle colors
Every reticle color side by side — primary, magenta, cyan, and the neutral border-strong.
RETICLE :: primary
RETICLE :: magenta
RETICLE :: cyan
RETICLE :: border-strong
import { BracketFrame } from "@/registry/okibi/ui/bracket-frame";const COLORS = [ { color: "primary", label: "PRIMARY // SPARK" }, { color: "magenta", label: "MAGENTA // 0xF2" }, { color: "cyan", label: "CYAN // 0x3C" }, { color: "border-strong", label: "BORDER-STRONG // GRAPHITE" },] as const;export default function BracketFrameColorDemo() { return ( <div className="flex flex-wrap items-center justify-center gap-10"> {COLORS.map(({ color, label }) => ( <BracketFrame key={color} color={color} label={label} className="w-48"> <p className="font-mono text-xs text-muted-foreground"> RETICLE :: {color} </p> </BracketFrame> ))} </div> );}API Reference
BracketFrame
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | – | Mono header label, top-left. |
corners | { tl?, tr?, bl?, br?: string } | – | Small mono labels pinned near each corner. |
color | "primary" | "magenta" | "cyan" | "border-strong" | "primary" | Reticle color — accent hues or the neutral graphite border-strong. |
animate | boolean | false | Converge the brackets onto the content. |
trigger | "hover" | "focus" | "view" | "always" | "hover" | What drives the converge when animate. |
as | ElementType | "div" | Render element. |
Accessibility
- The corner brackets are decorative —
pointer-events-noneandaria-hidden, so the framed content stays fully interactive. - Corner and header labels are
aria-hiddentoo; they read as visual chrome, not announced content. - Selection semantics (e.g.
aria-selected) stay on the host element — the reticle never owns state. - The lock-on is CSS-only at
--duration-fastwith no overshoot, and renders already-locked underprefers-reduced-motion.
Guidelines
Do
- Use
color='border-strong'for a neutral graphite reticle, orprimary/magenta/cyanfor an accent. - Drive the converge with
animate+trigger—hover/focusreset on leave,view/alwaysstay locked. - Keep real semantics (selection, focus, roles) on the content you wrap, not on the frame.
Don't
- Don't hang interactive behavior or accessible state on the brackets — they're
aria-hiddendecoration. - Don't expect
trigger='view'to re-arm; it locks once on first intersect and stays. - Don't put essential copy in the corner labels — they're hidden from assistive tech.