Power-User Systems
Mirage
Live, fully interactive HTML seen through moving air. An animated turbulence field displaces the real DOM subtree per pixel — no snapshot, no canvas replica — so the text stays selectable, the button still takes focus and the link is still a link while the whole panel shimmers.
Install
# Mirage needs no npm packagesThen copy 2 files into your project:
- components/registry/mirage/mirage.tsx
- hooks/use-animation-loop.ts
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| mode | "haze" | "liquify" | "shatter" | "tear" | "haze" | How the air moves. The four differ by the anisotropy of the noise rather than by strength: equal frequencies on both axes give soup, and a strongly biased axis is what makes a tear read as a tear instead of as more haze. |
| intensity | number | 0.4 | How far the content is pushed. This is genuine per-pixel displacement rather than a transform — a transform can only move the whole box, which is why skew-based heat haze never convinces. Past about one the text stops being readable, which is a legitimate look and a terrible default. |
| speed | number | 0.35 | Rate the field drifts. The noise is rasterised once as a seamless tile and scrolled, never re-seeded — stepping a turbulence seed swaps in an entirely unrelated field each time, which reads as a component tearing itself apart rather than as air moving. The wrap at one tile is invisible because the tile is seamless. |
| scale | number | 2.2 | Size of the turbulence cells, measured against a scrolling tile rather than against the element — so the same setting is the same air whether the panel is a card or a page. This sizes the tile itself, because a tile can hold no feature larger than its own period and the noise lattice only wraps on a whole number of cells; free the cell count instead and the field stops tiling, which shows up as the whole panel jumping to a different distortion once a wrap. Small cells shred the glyphs and large ones move the whole block as a unit; the interesting band is where a cell is roughly the height of a line of text. |
| chroma | number | 0.25 | Strength of the colour cast the shimmer carries, gathered where the pointer is. Hot air refracts, so a little colour separation is the cue that sells it as air rather than as a wobbling image. |
| trigger | "always" | "hover" | "always" | What turns the effect on. Whichever you pick it eases rather than switches — a displacement that snaps on reads as the element being swapped out, one that rises reads as air beginning to move. |
| edgeHold | number | 0.35 | How much of the element's own silhouette is protected. Displacing evenly moves the border too, so a rounded card dissolves into an amoeba and the one edge a reader uses to locate it is the first thing destroyed. This tapers the push toward neutral near the boundary — at zero the outline shreds, and past about half the shimmer is confined to the middle of the panel. |
| tintColor | string (hex) | "#a855f7" | The colour the shimmer carries. |
What It Demonstrates
- Hover effect
- Visual change when the cursor moves over an element.
- Blur
- A blur filter used to soften an element or mask tiny imperfections.
- Mask
- Hiding or revealing parts of an element using a shape or gradient — like clip-path, but with soft, fadeable edges.
- Idle animation
- Subtle motion that plays while an element is just sitting there, waiting to be interacted with.
- Compositing
- Letting the GPU move or fade an element on its own layer without redoing layout or paint.
- Hardware acceleration
- Animating transform and opacity lets the GPU keep motion smooth.
Related Components
Submerge
Live content held under water. A slow current bends it continuously, a press drops a stone and a drag leaves a wake that trails behind the cursor — and the text underneath stays selectable, the button still answers and the link is still a link, because the water bends the real tree rather than a picture of it.
Parallax Rail
A pinned section where scrolling down drives content sideways across depth planes moving at different rates.
Ascii Engine
A lit, raymarched 3D solid rendered at exactly one pixel per character cell, then quantised into a glyph ramp drawn once with fillText. Drag to orbit it through a full three-sixty. Real geometry underneath, terminal on top — and no scene graph, no mesh, and no second library to get there.
Swarm
Up to a quarter of a million particles integrated entirely on the GPU, morphing between words and solids, with a drag-orbit camera. Position and velocity live in floating-point textures and never come back to the CPU; text targets are sampled once out of an offscreen canvas, so the shape can be any string with no font atlas.
Telemetry
A metric board that behaves as one instrument instead of eight sparklines. Hovering any tile broadcasts a single timestamp and every other tile resolves its own value at that same instant, so a latency spike and a queue backing up are visibly the same event rather than two coincidences. Threshold breaches are recorded on the sample rather than on a pixel, so the scar travels with its data and is still there forty seconds after the value recovered.
Command Palette
A cmdk command menu with a plain or liquid-glass surface and hotkey trigger.