Design lab

Liquid Glass

The living reference for the site's glass material system — elevation tiers, the scene light and rim glint, the frosted edge bevel, and the liquid sheen, all rendered over the real aurora canvas. Move your mouse: the rims glint, the sheen drifts, the backdrop has depth.

L1–L4 elevationrim glintedge bevelclarity 2 · Default
§2

Elevation tiers

Blur and shadow co-vary with height, and each tier declares whether it carries an optics ring. Every swatch below is the named glass class applied directly, over the aurora — read the material, then the class beneath it.

L1 · Fill
.glass-fill

Repeated content — cards, rows, tiles. Tint + rim, no blur. No ring. Cheap, unlimited.

L2 · Pane
.glass-pane

Singular panels — heroes, composer, settings. Blur + noise + optics ring. Budgeted.

L3 · Chrome
.glass-chrome

Persistent chrome — sidebar, sticky headers, dock. Thinner bevel; brightens on scroll.

L4 · Overlay
.glass-overlay

Floating UI — dialogs, popovers, palette, toasts. Ring glint on; opaque enough for text.

Inset
.glass-inset

Recessed wells — inputs, search fields. A hole in the glass — no ring, no slab.

§4

Scene light & rim glint

One light, sitewide. On a fine pointer the light is the cursor (viewport coords, written to --light-x/--light-y); on touch or under reduced motion it rests at the scene's “sun” (top centre). Every pane, chrome bar and overlay paints a viewport-anchored specular rim glint in its optics ring, so as you sweep the cursor across the page each surface's rim brightens on the side facing the light and dims as it passes — all three panes below answer the same light at once, with zero per-element JS.

Pane Awatch the rim track
Pane Bwatch the rim brighten
Pane Cwatch the rim track
§4.1

Hover response — interactive glass

The glass no longer tracks your cursor. .glass-interactive used to grow a soft radial hotspot that followed the pointer inside the hovered card; moving a gradient's centre repaints the whole element, at pointer rate, so a grid of cards spent its frame budget on a highlight. What answers hover now costs nothing per frame: the tint raises, and the L1 rim glint lifts from its ambient rest to full — so the hovered card is still unmistakably the lit one. The glint itself answers a static sun. Hover a card.

Nav pillhover me
Dashboard cardhover me
Shop tilehover me
§3

Edge bevel — on vs off

.glass-refract frosts a masked band at the pane's edge, so the sheet reads as thick: the lip scatters the aurora while the centre stays optically flat. The displacement lens that used to bend the backdrop through that band is currently parked — Chromium composites the map itself into the band instead of sampling through it (see the note in app/globals.css) — so every engine gets the same honest frosted lip today. Rationed to hero / chrome only, never in scroll containers.

Bevel on.glass-pane .glass-refractwatch the edge band frost the aurora inward
Bevel off.glass-paneclean, optically flat edge
§3.7

Reactive lens — press-flex refraction

The lens has discrete intensity states — no per-frame filter animation (that stays banned). Pressing a refract surface swaps to a ×1.6 displacement map so the glass flexes under the finger, riding the same spring press. The left pane toggles rest ↔ press by hand (it points --glass-lens at the static #glass-lens-press); the right pane is on the real :active path — press and hold it. Both skip the swap under reduced motion.

Restscale ×1manual state toggle
Press me.glass-refract:activepress & hold — the bend deepens
§5.2

Liquid sheen — living material

.glass-liquid (or <GlassPane liquid>) drifts a slow specular band across the surface like light travelling over wet glass — now a background layer, so it composes freely with refraction and the pointer light on the same pane. Signature surfaces only; ration it. The right card uses .glass-sheen-hover, the one-shot sweep signature CTAs (and Button default/accent) fire on hover.

Ambient sheen.glass-liquida band drifts across every ~9s
Hover sweep.glass-sheen-hoverone pass, per hover
§5.47

Liquid morph

The active tab capsule does not slide, it flows: a layoutId spring carries the capsule while an SVG metaball underlay (#glass-goo, components/ui/liquid-morph.tsx) fuses it with a trailing droplet into a stretching teardrop. Velocity drives the squash and stretch. There was a second renderer here — a WebGPU/WebGL2 canvas drawing the same merge as SDF bodies. It is deleted: its entry point had no caller anywhere in the repo, so it never ran, and the SVG path below was always what shipped.

Switch tabs and watch the active capsule: the capsule and its trailing droplet fuse into a stretching teardrop, drawn as an SVG metaball underlay (#glass-goo) beneath the DOM capsule. Velocity drives the squash and stretch; reduced motion, perf-lite and high-contrast strip the underlay and leave the plain capsule slide.

components/ui/liquid-glass.tsx

GlassPane — the pane helper

GlassPane wraps the L2 .glass-pane class with opt-in interactive, refract (sets data-glass-lens), and liquid props — all composable on one pane. Site chrome uses the raw classes; this helper is for one-off panes.

<GlassPane>
interactive
refract + liquid
Internal design-lab reference · Liquid Glass v2 optics · every surface uses --site-* tokens and the .glass-* classes only.