Backdrop
Use this skill for Kototoro's io.github.kyant0:backdrop integration. The app uses Backdrop for the iOS interface style and Haze for the other runtime glass path; do not substitute Haze APIs when the affected code imports com.kyant.backdrop.
Workflow
- Locate the
drawBackdropcall and identify its source (LocalLiquidGlassBackdrop,rememberLayerBackdrop, orlayerBackdrop). Confirm the source and destination are in the same window; Popup/Dialog content normally needs the regularGlassSurfacefallback. - Read the complete modifier chain. Backdrop effects transform the sampled backdrop, but they do not provide an opaque semantic container color. Add a theme-derived surface tint with
onDrawSurfacewhen content needs stable contrast. - Keep effect order as
color filter -> blur -> lens.lensrequires aCornerBasedShape; use a simpler shape or omit lens for arbitrary shapes. - Keep colors theme-aware. Never use an opaque/fixed white surface as the iOS default. Derive the base from
MaterialTheme.colorScheme.surfaceContainer(or a more suitable surface role), then apply a modest alpha afterdrawBackdrop. - Preserve content color separately from the surface tint. Use
MaterialTheme.colorScheme.onSurfacefor standard iOS glass controls unless the component has a stronger semantic role. - Remember that
drawBackdropenablesHighlight.DefaultandShadow.Defaultunless explicitly overridden. Prefer those Backdrop-native layers over wrapping the same glass shape in a Compose elevation shadow. - Do not place a same-shape
clipoutsidedrawBackdrop; the modifier already clips the glass content toshape, while an outer clip can cut off Backdrop's expanding shadow and highlight. - Do not animate alpha on a parent that contains an out-of-bounds Backdrop shadow. Compose uses an offscreen
layer while alpha is below
1f, clipping the expanded shadow to the parent's bounds. Prefer translation-only entrance and exit animations for glass chrome. - Validate with
./gradlew :app:compileDebugKotlin --no-daemon. Add or update a focused unit test when extracting pure color or modifier-policy logic.
Kototoro conventions
- iOS detection is
LocalInterfaceStyle.current == InterfaceStyle.IOS. - The active Backdrop is provided by
LocalLiquidGlassBackdrop.current. - Existing shared glass code belongs in
core/ui/glassorcore/ui/compose; prefer a smallModifierhelper over duplicating a longbackground + drawBackdrop + borderchain. drawBackdropcan useexportedBackdrop = rememberLayerBackdrop()when a child surface should feed another Backdrop surface.- Surface tint must be drawn after the visual effect. Prefer
onDrawSurfaceso the surface participates in the same shaped glass layer; otherwise place a.background(...)modifier after.drawBackdrop(...). - A uniform white or black backdrop remains nearly uniform after blur and lens. Regular navigation glass must establish a subtle internal luminance difference with a semantic surface tint; shadow is only a secondary depth cue.
- Treat
GlassStyle.containerAlphaas a material-density input. It must influence the final surface tint, but it does not need to be copied one-to-one because Backdrop surface compositing becomes nearly opaque at the values used by stable Material surfaces. - If
drawBackdropuses its default or an explicit Backdropshadow, do not also callglassContainerShadoworModifier.shadowfor the same shape. - Place top-bar controls inside the shared
mainTopBarHeightslot and size them withtopBarButtonSize; the difference is required shadow breathing room. If a tag rail follows the bar, clip only the collapsing slot while it is actually collapsed, not the fully expanded chrome column. - Popup windows have a different coordinate space. Do not assume the root Backdrop is valid inside a Popup; use the existing root overlay route or fallback surface pattern.
Diagnosis checklist
- Is the control's surface tint fixed to
Color.WhiteorColor.Black? - Is the tint before
drawBackdrop, and therefore potentially hidden by the effect? - Is the control inheriting a transparent container from Material components?
- Is
onDrawSurfacealready drawing a tint, causing an overly opaque double layer? - Is a
.background(...)duplicating a tint already drawn byonDrawSurface? - Is an outer
clipcutting off Backdrop's native shadow or highlight? - Is a parent fade temporarily clipping the expanding shadow in an alpha offscreen layer?
- Are Backdrop
Shadowand ComposeModifier.shadowboth active for the same glass container? - On a pure-white test background, does the surface itself differ in luminance, or is only the shadow visible?
- Does the selected icon/text color match the polarity of the theme surface?
- Does a
lenseffect receive aCornerBasedShapeand valid dimensions?
References
Read references/backdrop-api.md for the upstream API facts used by this skill, especially when changing effect order, backdrop sources, or surface drawing.