Liquid UI

Cards that fuse where they meet, the corner between them curving inward like poured liquid.

npx skills add https://design.how/vault/liquid-ui

Installs the template, the brief and a check script as one skill.

What it is

White cards on a pale grey ground step through three little scenes: a grid panel with a "Grid" tab on its top edge, a chat bubble with its tail, and a share card with a "Share" button on its right edge. The playground adds a search bar with a round go button. Where a small piece meets a large one they are one surface: the corner between them curves inward, like they were poured together. Every 1.8 seconds the pieces ease to their next places over 0.56 seconds, with the content swapping at the midpoint, and a slow drift keeps the tab flexing against its panel.

There is no drawing by hand. Each card is a rounded box, and the surface is the union of their signed-distance fields taken with a polynomial smooth minimum, so near a seam the fields blend and that blend is the concave fillet. One number, the blend k, spans the look: about 20 is a crisp inverse-rounded joint, 60 a gooey neck, and 0 a hard seam.

The field is sampled on a 6px grid, marching squares traces its zero contour with linear interpolation along each edge, the loose segments are stitched into closed loops, and two passes of Chaikin smoothing turn the staircase into a fluid curve. The result is one SVG path behind the cards, and the real content, placeholder blocks, lines and labels, sits on top in normal DOM. Each scene is laid out in its own design space and scaled to the card; a phone gets a tighter layout of its own instead of a shrunken one.

How it works

  • Give every piece a box: centre, half-extents and corner radius, and evaluate sdRoundBox for each.
  • Combine the pieces with smin(a, b, k) = mix(b, a, h) - k h (1 - h), with h = clamp(0.5 + 0.5 (b - a) / k, 0, 1).
  • Sample the field on a grid of cell px over the pieces' bounds plus a margin, and run marching squares at 0 with edge interpolation.
  • Stitch the segments into loops, Chaikin-smooth them SMOOTH times, and write one path d; recompute only when a box or k changed.
  • Draw the path in an SVG behind the pieces and place each piece's content absolutely on top.
  • To animate, ease each piece's box and k between scenes and add a small drift to the tab; to drag, move a piece's box.
  • Under reduced motion, hold the first scene.

What you can change

  • CARD_SCENES (grid panel, chat bubble, share card): The scenes the card steps through, with each piece's box and content, in scenes.tsx.
  • k (20 to 60 per scene): The blend: low is a crisp inverse-rounded joint, high a gooey melt.
  • HOLD_MS, MORPH_MS (1800, 560): How long a scene holds and how long the pieces travel.
  • SKIN, GROUND (#ffffff, #f7f7f7): The fused surface and the card behind it.
  • SMOOTH (2): Chaikin passes over the traced outline.