Sakani

Glass & Liquid Glass

Frosted glass and Apple-style liquid glass, built into Sakani as a theme layer, not added component by component.

Next to light and dark, Sakani has a second theme axis: Surface. It has three modes: Solid (the default), Glass (frosted translucency, the look usually called glassmorphism) and Liquid (Apple-style liquid glass: the backdrop bends at the edges like a lens, with a faint color fringe, rim light and depth). Components read a small set of --surface-* tokens, so switching an area from Solid to Glass or Liquid re-themes everything inside it at once. There are no per-component glass variants to keep in sync, and Solid stays pixel-identical to before.

The same system exists in the Figma file (a Surface variable collection plus effect styles), so a design and its code use the same modes. For a complete screen, see the Liquid Glass Dashboard block.

Three surfaces, one component

The same Card over the same photo. Glass only reads over something colorful and detailed, which is why every demo here sits on a photograph.

Revenue

Last 30 days

Solid — the default

Revenue

Last 30 days

Glass — data-surface="glass"

Revenue

Last 30 days

Liquid — <LiquidGlass>

The recipe: photo → overlay → components

Build every glass screen in the same order. One glass overlay bends the photo for the whole canvas, so each component doesn't blur it again (stacked blurs go muddy and cost performance). Navigation and floating layers sit on it with no fills of their own; anything people have to read closely, like tables and data cards, stays solid.

1 · Background — the photo

2 · Overlay — one glass sheet

Card on the glass

3 · Components — on top

Choosing a strength

Strength is two independent choices: the lens (how much the backdrop bends and frosts) and the tint (how much of the backdrop you can see through). Contrast figures are measured from the render of our Figma samples, as typical / worst 5% of the area behind the text.

TierUse forMeasured contrast
Frosted · data-surface="glass"Everyday translucency across an app: cards, menus, sidebars. Cheap, works in every browser.Muted text uses a stronger token on glass (neutral-600 light / neutral-300 dark).
Liquid · clearIcons, large labels, floating controls, full-bleed overlays over dark or busy imagery.No guarantee: it depends entirely on the photo. White text over bright sky measured 1.3:1.
Liquid · regular (66%)Sidebars and panels with copy.Body text 9.9 / 8.3 (light) and 12.5 / 8.6 (dark).
Liquid · tinted 52–64%Cards, modals and popovers that carry copy.Titles 7–13 typical; the worst 5% dips to about 3 on very bright spots.

Rule of thumb: Glass for everyday translucency across an app; Liquid for a few large hero surfaces, such as a floating sidebar, a toolbar or a full-screen overlay, where the effect is worth its cost. If the row says "depends on the photo", measure before you ship.

LiquidGlass

The material as a component. Put regular Sakani components inside it; they drop their own fills and sit on the glass. Wrap the screen in <LiquidBackdrop src={photo}> and every lens inside refracts the photo itself, sharp, the way Figma's glass does: glass stacked on glass still bends real detail (its veil lays a color over the photo for every lens, such as a dark-mode scrim). Also exported: useLiquidGlass(ref, { enabled, refraction, source }) and liquidGlassClass(variant, tint) for elements you own (the Modal card uses the hook when it is opened from inside a liquid area).

PropTypeDefaultDescription
variant'regular' | 'clear''regular'Tint strength. regular carries copy; clear is for icons, large labels and imagery.
tint'regular' | 'clear' | 'subtle' | 'none'the variant'sThe fill. subtle is Figma's glass/bg-subtle (5%), for a full-bleed overlay; none draws no tint.
radiusnumber20Corner radius in px. Use 0 for a full-bleed overlay. The lens follows it exactly.
effect{ refraction, depth, dispersion, frost, lightIntensity, lightAngle }the variant'sAny of Figma's Glass properties for this element, in Figma's units.
sourcebooleantrueInside a LiquidBackdrop: refract its photo (true) or the UI painted below (false: slider knobs, selection droplets).
refraction'auto' | 'off''auto''off' forces the frosted fallback, e.g. to preview Safari or Firefox in Chrome.
interactivebooleanfalseSquishes slightly when pressed (buttons, toolbar pills). No squish with reduced motion.
…restHTMLAttributes<HTMLDivElement>Anything a <div> accepts is forwarded.

Custom elements read the --surface-* tokens; they never hard-code glass values.

Tokens

Components read --surface-*; the Surface mode decides what those point to. Solid aliases the semantic tokens, so nothing changes unless an area opts in.

TokenSolidGlass
--surface-bgvar(--color-bg-surface)var(--glass-bg) (72% white · 72% near-black)
--surface-bg-overlayvar(--color-bg-surface)var(--glass-bg-overlay) (82%)
--surface-bg-chrometransparentvar(--glass-bg-chrome) (60%)
--surface-bg-subtlevar(--color-bg-subtle)var(--glass-bg-subtle)
--surface-bordervar(--color-border-subtle)var(--glass-border)
--surface-highlightnonevar(--glass-highlight) (1px top light edge)
--surface-blurnoneblur(16px) saturate(160%)
--surface-blur-overlaynoneblur(24px) saturate(180%)

The liquid material is Figma's Glass effect, property for property: the tokens below are the liquid/regular and liquid/clear effect styles in Figma's own units (refraction, depth, dispersion, frost, light), and LiquidGlass turns them into pixels by rules measured from Figma's renders. To change one element, pass effect={{ refraction: 0.8, depth: 20 }} or set the unprefixed name (--liquid-depth, …) on it. Pick a tint with <LiquidGlass tint="subtle"> (regular, clear, subtle or none), and put data-on-photo on any subtree that sits straight on a photo to switch it to light text.

TokenDefaultControls
--liquid-tint-regularwhite 66%The regular tint
--liquid-tint-clearwhite 28%The clear tint
--liquid-tint-subtle5% inkThe subtle tint: Figma's glass/bg-subtle, for a full-bleed overlay (white 8% in dark)
--liquid-refraction-regular | -clear0.55 | 0.8Figma Glass · Refraction (0–1): how hard the rim bends
--liquid-depth-regular | -clear16 | 20Figma Glass · Depth: how far in the bend reaches
--liquid-dispersion-regular | -clear0.3 | 0.4Figma Glass · Dispersion (0–1): red bends more, blue less
--liquid-frost-regular | -clear4 | 1Figma Glass · Frost: blur before the bend
--liquid-light-intensity-regular | -clear0.7 | 0.8Figma Glass · Light intensity (0–1): rim, shade and glow, added
--liquid-fallback-blurblur(14px) saturate(180%)The look in browsers without refraction
--liquid-light-angle-45Figma Glass · Light angle: degrees clockwise from the top
--liquid-overlay-tintvar(--liquid-tint-subtle)The dashboard overlay (a 72% scrim in dark)
--liquid-panel-tintwhite 76%A panel of glass that holds solid cards

Accessibility and browsers

  • Contrast. Text color follows the photo behind it, not the theme. Dark text on the tinted tiers held well; white text on a clear tier over a bright photo did not. Check each label against the real image, in light and dark. For secondary text on glass, use the stronger muted token (--surface-fg-muted in Figma; --color-fg-muted is already switched on glass in code).
  • Reduced transparency. With prefers-reduced-transparency, glass and liquid surfaces render as plain opaque surfaces, with no tint, blur or refraction.
  • Reduced motion. The pointer-following glare and the press squish are turned off.
  • Browsers. Refraction renders in Chromium (Chrome, Edge, Arc, Opera). Safari and Firefox get a frosted fallback with the same tint, rim and depth, but no bending. Detection is by engine rather than feature query, because Safari reports backdrop-filter support yet ignores url() filters.
  • Performance. Each LiquidGlass runs its own SVG filter. Use one full-size overlay and a few floating surfaces per screen, not one per card or row.

In Figma

  1. Set the frame's Surface variable mode to Glass (or place a Liquid overlay), with Semantic on Light or Dark.
  2. Add the photo as the frame's image fill.
  3. Add a full-size rectangle named Overlay above it: fill glass/bg-subtle, effect style liquid/regular.
  4. Place the sidebar and top bar on it at a 5% fill; keep data cards on the solid surface.
  5. Float menus, modals and popovers with a tint and a lens from the strength table above.

The theming and tokens pages cover the rest of the token system.