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
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.
| Tier | Use for | Measured 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 · clear | Icons, 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).
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | 'regular' | 'clear' | 'regular' | Tint strength. regular carries copy; clear is for icons, large labels and imagery. |
| tint | 'regular' | 'clear' | 'subtle' | 'none' | the variant's | The fill. subtle is Figma's glass/bg-subtle (5%), for a full-bleed overlay; none draws no tint. |
| radius | number | 20 | Corner radius in px. Use 0 for a full-bleed overlay. The lens follows it exactly. |
| effect | { refraction, depth, dispersion, frost, lightIntensity, lightAngle } | the variant's | Any of Figma's Glass properties for this element, in Figma's units. |
| source | boolean | true | Inside 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. |
| interactive | boolean | false | Squishes slightly when pressed (buttons, toolbar pills). No squish with reduced motion. |
| …rest | HTMLAttributes<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.
| Token | Solid | Glass |
|---|---|---|
| --surface-bg | var(--color-bg-surface) | var(--glass-bg) (72% white · 72% near-black) |
| --surface-bg-overlay | var(--color-bg-surface) | var(--glass-bg-overlay) (82%) |
| --surface-bg-chrome | transparent | var(--glass-bg-chrome) (60%) |
| --surface-bg-subtle | var(--color-bg-subtle) | var(--glass-bg-subtle) |
| --surface-border | var(--color-border-subtle) | var(--glass-border) |
| --surface-highlight | none | var(--glass-highlight) (1px top light edge) |
| --surface-blur | none | blur(16px) saturate(160%) |
| --surface-blur-overlay | none | blur(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.
| Token | Default | Controls |
|---|---|---|
| --liquid-tint-regular | white 66% | The regular tint |
| --liquid-tint-clear | white 28% | The clear tint |
| --liquid-tint-subtle | 5% ink | The subtle tint: Figma's glass/bg-subtle, for a full-bleed overlay (white 8% in dark) |
| --liquid-refraction-regular | -clear | 0.55 | 0.8 | Figma Glass · Refraction (0–1): how hard the rim bends |
| --liquid-depth-regular | -clear | 16 | 20 | Figma Glass · Depth: how far in the bend reaches |
| --liquid-dispersion-regular | -clear | 0.3 | 0.4 | Figma Glass · Dispersion (0–1): red bends more, blue less |
| --liquid-frost-regular | -clear | 4 | 1 | Figma Glass · Frost: blur before the bend |
| --liquid-light-intensity-regular | -clear | 0.7 | 0.8 | Figma Glass · Light intensity (0–1): rim, shade and glow, added |
| --liquid-fallback-blur | blur(14px) saturate(180%) | The look in browsers without refraction |
| --liquid-light-angle | -45 | Figma Glass · Light angle: degrees clockwise from the top |
| --liquid-overlay-tint | var(--liquid-tint-subtle) | The dashboard overlay (a 72% scrim in dark) |
| --liquid-panel-tint | white 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-mutedin Figma;--color-fg-mutedis 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-filtersupport yet ignoresurl()filters. - Performance. Each
LiquidGlassruns its own SVG filter. Use one full-size overlay and a few floating surfaces per screen, not one per card or row.
In Figma
- Set the frame's Surface variable mode to Glass (or place a Liquid overlay), with Semantic on Light or Dark.
- Add the photo as the frame's image fill.
- Add a full-size rectangle named
Overlayabove it: fillglass/bg-subtle, effect styleliquid/regular. - Place the sidebar and top bar on it at a 5% fill; keep data cards on the solid surface.
- 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.