KQ-1790 · MERCURY/GATE

Mercury Gate

A metal ring hanging in a place, a membrane of liquid mercury across it — a WebGL2 height field shaded as a near-perfect mirror with a crisp reflected horizon, slowly wobbling — drawing a faint stream of motes in from the card's edges. Hover or focus it and ripples run out from the pointer while the mercury parts on the springs.glide constants into a clear disc with a beaded meniscus, showing the place the gate leads to; a click or Enter dives through — a breath back, then the ring rushes past on an accelerating tween with streaks pouring outward and a soft flash — and the destination fills the card as the value changes. The ring re-forms behind you on springs.glide, still clear and showing where you came from, before the mercury flows back in on springs.drift. Arrow keys on the gate, or the marks beneath it (a radiogroup with roving focus), choose where it leads.

KQ-1790 · MERCURY/GATE

Waylight Travel

Pick a door

The field

To Coldbrook Shore

The gate leads to

Arrow keys choose where the gate leads; Enter goes through.

at The field · gate leads to Coldbrook Shore

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/mercury-gate

Props

destinations
MercuryGateDestination[]
default four invented places
The places the gate connects: { id, title, caption?, kind?, tone?, scene? }. Without scene a built-in painting (field, shore, dunes, peaks, grove) is drawn from tone.
value / defaultValue
string
default the first destination
Where you are: a destination id; controlled or uncontrolled.
onValueChange
(id: string) => void
default —
Fires when a dive arrives, with the new place's id.
target / defaultTarget
string
default the next destination
Where the gate leads: a destination id; controlled or uncontrolled. After a dive it leads back where you came from.
onTargetChange
(id: string) => void
default —
Fires from the key or mark that pointed the gate somewhere else, and on arrival when it turns to lead back.
onDive
(from: string, to: string) => void
default —
Fires as a dive begins, with where from and where to.
ripple
number
default 0.55
How high the hover ripples run and how wide the mercury parts, 0 to 1.
glow
number
default 0.5
How strongly the ring glows, 0 to 1.
pull
number
default 0.5
How many motes the gate draws in, and how fast, 0 to 1.
ringSize
number
default 0.8
The ring's diameter as a share of the box's short side, 0.4 to 1.
metalColor
string
default a cool silver from the accent token
The ring's metal, any CSS colour.
glowColor
string
default "var(--accent-bright)"
The ring's glow and the motes, any CSS colour.
showLabels
boolean
default true
Show where you are and where the gate leads, as text over the scene.
sound
boolean
default false
A whoosh as you dive, and a softer one as the ring re-forms.
paused
boolean
default false
Hold the mercury and the motes still.
seed
number
default 1
Seeds the motes and the built-in paintings' stars and ridges.
dpr
number
default 2
Cap on the canvases' device pixel ratio, at most 2.
label
string
default "Go through"
The gate's accessible name, before "to" and the place.
disabled
boolean
default false
No diving and no changing where it leads.
className
string
default —
Sizes the gate; it fills its parent by default.