engine/liquid_glass library

The Liquid Glass family (spec §5.3 #2; motion brief §2.3 "Liquid Glass"): translucent keys over a vivid, slowly drifting mesh-gradient background, with specular highlights, a refraction hint and a jelly press. Glass is for the controls: the display sits on a solid-enough backing panel.

  • Background: a mesh of a deep (dark themes) or pale (light themes) base and three vivid colour blobs (BackgroundKind.meshGradient), hues from the harmony scheme. It drifts on a 40–60 s cycle at runtime (never under Reduce Motion or with ambient motion off).
  • Keys: glass tints — translucent KeyColors.face ARGB — smoky dark glass (dark themes) or milky white glass (light themes) for digits, a second tone for function keys, vivid accent glass for the operators and a denser jewel =. Rims (KeyColors.edge) are decorative light catchers, or opaque and ≥ 3:1 under the Accessible lock.
  • Display: the palette surface, translucent but dense; every display text is solved on the surface composited over the background (displayBackdrops).

Guardrails on composited colours (research theme-engine.md: contrast over translucent surfaces). A mesh blends its colours in every proportion, so its samples are its colour hull (meshHullSamples): the stops, every pairwise quarter point and every three-way centroid in encoded sRGB (what the renderer's gradients blend in). Its darkest and lightest points can lie between stops (encoded-sRGB blends of two saturated colours are darker than either), which is why the stops alone are not enough. Labels are checked on each tint composited over every hull sample (4.5:1, 7:1 accessible), the display on the surface over every sample, plus the glass rules in validateGlass: labels ≥ 3:1 under the peak press glow, operator / = tints distinct from the digit tint over the same sample (ΔEOK ≥ 0.08 under every CVD), an honest weight cue, and opaque ≥ 3:1 rims under the Accessible lock.

The renderer keeps those numbers true: the label zone (the middle 40 % of the key's height, glassLabelZoneTop–glassLabelZoneBottom) shows exactly the tint over the background; the specular highlight and bottom caustic stay outside it; edge thickening only moves the face away from its label; the frost underlay (KeyStyleSpec.frostPermille) is the background's base colour, so a frosted face is still the tint over a point of the hull; Reduce Transparency's solid tint is the tint composited over the base colour, itself a hull sample.

Every draw comes from the generator's named sub-streams (palette with its retry streams, background, shape, style, type, motion, name), so a theme is a pure function of (seed, engineVersion, accessible). The constants here are part of engine version 2's Liquid Glass definition: changing one changes generated themes.

Constants

glassAccessibleRimMinCdp → const int
Smallest rim width the Accessible lock accepts, dp × 100.
glassBlobChromaCapMilli → const int
Blob absolute chroma caps (thousandths), dark and light.
glassDarkBlobChroma → const IntRange
Blob relative chroma, dark and light.
glassDarkBlobLMilli → const IntRange
Dark mesh: blob lightness (× 1000) and relative chroma (× 1000 of maxChroma, capped at glassBlobChromaCapMilli).
glassDarkDigitAlpha → const IntRange
Tint alphas (0–255) per role, dark and light.
glassDarkEqualsAlpha → const IntRange
glassDarkFrost → const IntRange
Frost (backdrop diffusion) × 1000, dark and light.
glassDarkFunctionAlpha → const IntRange
glassDarkOperatorAlpha → const IntRange
glassDarkRanges → const RoleRanges
Liquid Glass dark ranges (only what buildGlassCandidate reads): the mesh base (background), the digit, function, operator and = tints, label start and chroma. Tints are composited over the background, so their lightness is the glass's colour, not the face the eye sees.
glassDarkSurfaceAlpha → const IntRange
glassDarkSurfaceLMilli → const IntRange
Display surface (the backing panel): lightness × 1000 and the starting alpha; the alpha then rises in steps of 10 until the display text reaches its floor (+ 0.15) on every composited sample — glass where the background allows it, denser where it must be.
glassDriftPeriodMs → const IntRange
Mesh drift period range, ms (motion brief §4.13: a cycle of ≥ 40 s).
glassGlowAlpha → const IntRange
Peak press-glow alpha range (Palette.highlight's alpha, 0–255): the motion brief's "+12 % luminance" glow core.
glassHighlight → const IntRange
Specular highlight and refraction strengths × 1000.
glassLabelZoneBottom → const double
Bottom of the label zone (see glassLabelZoneTop).
glassLabelZoneTop → const double
Top of the label zone as a fraction of the key's height: the renderer paints nothing but the tint (and the press glow) between this and glassLabelZoneBottom.
glassLightBlobChroma → const IntRange
glassLightBlobChromaCapMilli → const int
glassLightBlobLMilli → const IntRange
Light mesh: blob lightness (× 1000).
glassLightDigitAlpha → const IntRange
glassLightEqualsAlpha → const IntRange
glassLightFrost → const IntRange
glassLightFunctionAlpha → const IntRange
glassLightOperatorAlpha → const IntRange
glassLightRanges → const RoleRanges
Liquid Glass light ranges (see glassDarkRanges).
glassLightSurfaceAlpha → const IntRange
glassLightSurfaceLMilli → const IntRange
glassPressedLabelRatio → const double
The floor for key labels while the press glow lights the face (a transient state under the finger; WCAG 1.4.11 level).
glassRefraction → const IntRange
liquidGlassDefinition → const FamilyDefinition
Liquid Glass (spec §5.3 #2; motion brief §2.3 "Liquid Glass"): translucent glass keys over a vivid drifting mesh, specular highlight and refraction rim, display on a solid-enough backing.

Functions

buildGlassCandidate(int seed, FamilyDefinition def, int engineVersion, {int attempt = 0, bool accessible = false}) → ThemeSpec
Builds one unvalidated Liquid Glass candidate (the generator repairs and validates it, retries with palette/retry/n and finally falls back to a Liquid Glass hero).
densifyGlassSurface(int surface, int text, GuardrailLimits lim, List<int> bgs) → int
The display backing surface made denser (alpha + 10 at a time) until a text of text's polarity reaches the display and preview floors (+ 0.15) on it composited over every background sample.
fitGlassGlow(Palette p, int glow, List<int> bgs) → int
The press glow glow dimmed (alpha in steps of 4) until every label of p keeps glassPressedLabelRatio under it.
glassBlobOffsets(HarmonyScheme scheme) → List<int>
Blob hue offsets (tenths) per harmony scheme: blob 1, blob 2, blob 3. Operators take blob 2's hue, = blob 3's.
glassDiffuseColor(BackgroundSpec bg) → int
The colour glass diffuses the background to: the three-way centroid of a mesh's blobs (exactly one of meshHullSamples) — the vivid middle of the mesh — or the base colour for other backgrounds. The renderer's frost underlay and Reduce Transparency's solid tint (the tint composited over it) use it, so both are checked colours.
glassPressedLabelContrast(KeyColors k, int glow, List<int> bgs) → double
Smallest label contrast of k under the peak press glow glow.
glassPressedSamples(int face, int glow, List<int> bgs) → List<int>
The colours a glass face shows under the press glow glow at its peak: the glow composited over the tint over every background sample.
glassTintDistance(int face, int digit, List<int> bgs) → double
Smallest ΔEOK (normal + CVD) between face and digit composited over the same background sample.
meshHullSamples(List<int> stops) → List<int>
The colour hull of a mesh with opaque stops, sampled: every stop, every pairwise ¼ / ½ / ¾ point and every three-way centroid, blended in encoded sRGB (integer arithmetic, bit-exact). The darkest and lightest colours a mesh can paint are among (or within a hair of) these.
repairGlassExtras(Palette p, ThemeSpec spec, GuardrailLimits lim, List<int> bgs) → Palette?
Repairs the glass extras: the press glow (dimmed until labels keep 3:1 under it) and, under the Accessible lock, opaque rims solved to ≥ 3:1 on every background sample. Null when a rim is unreachable.
repairGlassKeys(Palette p, GuardrailLimits lim, List<int> bgs) → Palette?
Repairs translucent glass keys whose labels miss the floor on some composited sample: re-solves the label, then moves and densifies the tint (solveGlassKey). Opaque keys are left to the generic repair. Null when a key cannot reach the floor.
separateGlassEquals(KeyColors eq, KeyColors op, KeyColors digit, GuardrailLimits lim, List<int> bgs) → KeyColors?
Keeps the = glass apart from the operators over any two background samples (the generic equalsVsOperator rule compares every pair) and from the digit tint over the same sample (glassOperatorTint): when it is too close, its tint moves 0.06 at a time in lightness — away from the operator's first, then the other way — at an alpha of at least 230 (a denser jewel varies less across the mesh), re-solving the label each step. Null when no step works.
solveGlassKey({required Lch tint, required int alpha, required Lch label, required List<int> bgs, required double target, required int edge, int rounds = 14}) → KeyColors?
Solves a glass key: the label (from label) on tint at alpha composited over every one of bgs, to target. When no label of the same polarity reaches it, the tint moves away from the label (0.04 in lightness) and densifies (+14 alpha) for up to rounds rounds. Null when unreachable.
validateGlass(ThemeSpec spec, GuardrailLimits lim, List<int> bgs) → List<GuardrailViolation>
The Liquid Glass rules (see the library docs); validateTheme adds them for the family. bgs are the background samples.