Skip to content
Development
Skill

/compose-screens-footguns

Compose screen and interaction traps: navigation, adaptive layout, window insets, pagers, toolbars, sheets, list drag and selection, sliders, text fields, settings UI, one-shot effects. Use when layout, gestures or navigation misbehave.

BOOST
From plugin
kotlin-footguns
1.3k10 skills
Install
$ npx -y skills add maxrave-dev/kotlin-footguns --skill compose-screens-footguns --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/compose-screens-footguns

Context preview

The summary Claude sees to decide when to auto-load this skill.

Compose screen and interaction traps: navigation, adaptive layout, window insets, pagers, toolbars, sheets, list drag and selection, sliders, text fields, settings UI, one-shot effects. Use when layout, gestures or navigation misbehave.

SKILL.md

compose-screens-footguns.SKILL.md
name: compose-screens-footguns
description: "Compose screen and interaction traps: navigation, adaptive layout, window insets, pagers, toolbars, sheets, list drag and selection, sliders, text fields, settings UI, one-shot effects. Use when layout, gestures or navigation misbehave."

Compose screens footguns: layout, navigation and interaction

32 traps mined from a production Kotlin and Compose Multiplatform app, one short file each under `references/`. Every file gives the working pattern, the **Traps** (the specific ways it fails in practice, and why), and a **Verifying it** section with commands to run against the user's own tree.

**How to use this index.** Match the code about to be written, or the symptom being chased, against the entries below: each names its topic and the symptom that should send you to it. Read every file that plausibly applies with the Read tool before proposing code or a fix; each is under 150 lines. Where a Verifying command names the source project's paths, substitute the equivalent paths in the user's tree.

**Cross-references.** A backticked trap name inside a file that is not listed here lives in a sibling area skill: glob `../*/references/<name>.md` to open it.

Screens, navigation and adaptive layout

  • [`responsive-gate-size-not-platform`](references/responsive-gate-size-not-platform.md) — Gate an adaptive layout on the window's own width-versus-height, never on the platform, and flip every geometry value the gate owns in the same breath — frame sizing, content scale and scrim height. Use when a layout is right on a phone and wrong in a narrow or resized desktop window, when forcing an adaptive flag to one value breaks a different platform's screen, or when artwork swallows the whole page on a wide window.
  • [`nav-tab-registration-drift`](references/nav-tab-registration-drift.md) — A top-level tab has to be registered in every navigation surface that holds its own copy of the tab list — bottom bar, rail, and a stylized bar that keeps two lists — plus the graph and the flag that gates it, or the tab exists in code and never renders. The same drift catches a status entry point carried by more than one top app bar, where the missing badge reads as "nothing is running" rather than as a bug. Covers why a tab's ordinal is an identity rather than a position, what a conditional tab needs when it disappears under the user, and why a badge dot needs a ring of the page colour. Use when a newly added tab or badge shows on one surface but not another, when selection highlights the wrong tab after reordering, or when a tab bar overflows once one more tab appears.
  • [`type-safe-nav-graph-organization`](references/type-safe-nav-graph-organization.md) — Lay out a type-safe Navigation-Compose graph so it stays readable as the destination list grows — one serializable route object per file grouped by area, area graphs as extension functions on the graph builder, a single transition set on the host, and per-route theming applied by wrapping the screen inside its own entry. Use when a navigation file has grown to hundreds of lines, when route arguments start needing custom types, or when transitions or theming differ between destinations for no stated reason.
  • [`collapsing-parallax-toolbar`](references/collapsing-parallax-toolbar.md) — Build a collapsing header from five siblings in one box — four sharing a single scroll state, one driven by a boolean instead — with artwork moved by a graphics layer at half the scroll rate, a title interpolated along a two-segment curve into the pinned bar, and a derived flip point that swaps the floating back button for a real top bar. Use when a parallax header jitters or re-measures while scrolling, when the collapsing title drifts off its intended path, or when the pinned bar appears at the wrong scroll offset after a window resize.
  • [`fullscreen-video-gesture-overlay`](references/fullscreen-video-gesture-overlay.md) — The gesture and chrome layers of a fullscreen video screen — tap anywhere to toggle the controls, double-tap either half to seek, an auto-hide timer that every interaction postpones, and a picture-in-picture (PiP) guard that removes both layers. Use when single taps work on only half the screen, when the controls vanish while the user is dragging the seek bar, when the seek thumb snaps back under the finger, when a double-tap produces no ripple or a ripple that never fades, or when app chrome is still drawn over the video inside a small floating window.
  • [`nowplaying-pager-no-feedback-loop`](references/nowplaying-pager-no-feedback-loop.md) — A now-playing artwork pager that both follows the player and drives it, without the two writing to each other in a loop — the in-progress-scroll flag covers programmatic animation as well as drags, the seek is dispatched from the settled page only, and the page-difference decision is a pure function outside the UI runtime. Use when a swipe bounces back to the page it came from, when one swipe skips two tracks, when the pager stops following the player after a fast swipe, when swiping backwards restarts the current track instead of going back one, or when a far swipe under shuffle lands on the wrong song.
  • [`layered-video-backdrop-pager`](references/layered-video-backdrop-pager.md) — Building a swipeable now-playing page whose layers — a colour backdrop, a full-bleed looping video or image, and a centred square cover — all belong to one pager, with per-page colours taken from the bitmap that page actually painted and a scrim spanning the whole page. Use when a swipe makes the background and the cover slide out of step, when video from one track bleeds into the neighbouring page mid-swipe, when the backdrop colour belongs to the wrong track or flashes black between pages, when the bottom of the video shows through the controls, or when a tap overlay stops the pager from being dragged at all.
  • [`desktop-mini-player-window`](references/desktop-mini-player-window.md) — A
Read more
Ships withkotlin-footguns

By maxrave-dev — creator and maintainer of SimpMusic, the 10.8k-star cross-platform music app every lesson in this repository was mined from.

Get the whole plugin

Other skills on kotlin-footguns.