Signature
GlitchText
Per-character scramble/decode headline over a persistent ambient signal-noise field — resolves on hover, in-view, or as a continuous pulse (reduced-motion aware).
● LIVE
System OnlineDecodes on view; ambient signal-noise keeps churning behind it
Signal HUDHover to re-run the decode
Signal LockContinuous pulse — re-scrambles on a loop
Ghost Modeambient={false} — plain heading, decode on hover only
"use client";import { CoordLabel } from "@/registry/okibi/ui/coord-label";import { GlitchText } from "@/registry/okibi/ui/glitch-text";export default function GlitchTextDemo() { return ( <div className="flex flex-col gap-6"> <div className="flex flex-col gap-1"> <GlitchText trigger="view" className="font-display text-3xl font-extrabold uppercase tracking-tight sm:text-4xl" > System Online </GlitchText> <CoordLabel> Decodes on view; ambient signal-noise keeps churning behind it </CoordLabel> </div> <div className="flex flex-col gap-1"> <GlitchText trigger="hover" className="font-display text-3xl font-extrabold uppercase tracking-tight sm:text-4xl" > Signal HUD </GlitchText> <CoordLabel>Hover to re-run the decode</CoordLabel> </div> <div className="flex flex-col gap-1"> <GlitchText trigger="always" className="font-display text-2xl font-bold uppercase tracking-tight" > Signal Lock </GlitchText> <CoordLabel>Continuous pulse — re-scrambles on a loop</CoordLabel> </div> <div className="flex flex-col gap-1"> <GlitchText ambient={false} trigger="hover" className="font-display text-2xl font-bold uppercase tracking-tight" > Ghost Mode </GlitchText> <CoordLabel>ambient={"{false}"} — plain heading, decode on hover only</CoordLabel> </div> </div> );}npx shadcn@latest add https://okibi.cndr.dev/r/glitch-text.jsonInstallation
Install the theme first, then add the component:
npx shadcn@latest add https://okibi.cndr.dev/r/glitch-text.jsonCopy the source from the Code tab above into components/ui/glitch-text.tsx. It uses the cn helper and the okibi theme tokens — install the theme first if you haven't.
Usage
import { GlitchText } from "@/components/ui/glitch-text"
<GlitchText trigger="hover">DECODING SIGNAL</GlitchText>Examples
Triggers
trigger controls when the decode runs — hover to resolve on pointer-in, view on scroll-into-view, or always for a continuous pulse.
● LIVE
trigger // hoverSignal HUD
trigger // viewSystem Online
trigger // alwaysSignal Lock
"use client";import { CoordLabel } from "@/registry/okibi/ui/coord-label";import { GlitchText } from "@/registry/okibi/ui/glitch-text";export default function TriggersDemo() { return ( <div className="flex flex-col gap-4"> <div className="flex flex-col gap-1"> <CoordLabel>trigger // hover</CoordLabel> <GlitchText trigger="hover" className="font-display text-3xl font-extrabold uppercase tracking-tight" > Signal HUD </GlitchText> </div> <div className="flex flex-col gap-1"> <CoordLabel>trigger // view</CoordLabel> <GlitchText trigger="view" className="font-display text-3xl font-extrabold uppercase tracking-tight" > System Online </GlitchText> </div> <div className="flex flex-col gap-1"> <CoordLabel>trigger // always</CoordLabel> <GlitchText trigger="always" className="font-display text-3xl font-extrabold uppercase tracking-tight" > Signal Lock </GlitchText> </div> </div> );}Tuning
Tune the decode with a custom glyphs pool, a slower speed and a wider stagger on an always headline.
● LIVE
glyphs // speed // stagger
Decode Sequence
"use client";import { CoordLabel } from "@/registry/okibi/ui/coord-label";import { GlitchText } from "@/registry/okibi/ui/glitch-text";export default function GlitchTextTuningDemo() { return ( <div className="flex flex-col gap-1"> <CoordLabel>glyphs // speed // stagger</CoordLabel> <GlitchText as="h2" trigger="always" glyphs="01︎▮▯◢◣◤◥╱╲" speed={680} stagger={110} className="font-display text-3xl font-extrabold uppercase tracking-tight" > Decode Sequence </GlitchText> </div> );}API Reference
GlitchText
| Prop | Type | Default | Description |
|---|---|---|---|
trigger | "hover" | "view" | "always" | "hover" | What drives the decode reveal. |
ambient | boolean | true | Persistent ghost-noise field behind the text. |
glyphs | string | ░▒▓█▚▞01<>/\\|=+*#%·:.— | Glyph pool the characters churn through. Defaults to a built-in block / box-drawing set (░▒▓█▚▞ plus digits and ASCII symbols). |
speed | number | 420 | Per-character resolve window, in ms. |
stagger | number | 55 | Per-character stagger, in ms. |
as | ElementType | "span" | Render element. |
Accessibility
- The resolved text is the real accessible content: it lives in a single
sr-onlynode, so assistive tech reads it once, cleanly, and never the scramble. - The ambient ghost-noise field and the decode overlay are both
aria-hidden, so the churn is never announced. - Under
prefers-reduced-motionthe effect is skipped and the plain, fully-resolved text renders static. - Randomness runs only post-mount, so the server and first client render both show the resolved text — no hydration mismatch.
- The default
hovertrigger fires on pointer enter/leave only; for keyboard or touch reach prefertrigger='view'ortrigger='always', and note[data-glitching]is exposed while a reveal runs.
Guidelines
Do
- Use it for short decoding-terminal headlines and wordmarks where a live, signal-noise identity is wanted.
- Choose the
triggerfor context:'hover'for pointer reveal,'view'for a scroll-in decode,'always'for a continuous pulse. - Tune the feel with
glyphs,speedandstagger, and target[data-glitching]for run-scoped styling.
Don't
- Do not rely on
hoverto expose meaning — the resolved text is always present for assistive tech, but the visible decode is pointer-only. - Do not run it on long paragraphs; the per-character scramble is built for short headline-length strings.