Symptom

The “Connect” button in the PIN entry dialog was clipped at the bottom — its lower ~8–12dp (fill, shadow, padding) were swallowed by the Card’s rounded-corner mask. The primary CTA was never fully rendered across all three ftue__pin-entry__* screenshot scenarios.

Root cause

The Button was placed inside a verticalScroll Column that occupied the full height of the Card’s content area. With approximately 340dp of content in a density-2.0 viewport the scrollable column pushed the button to the very bottom of the Card, where the Card’s corner-radius clip removed its lower edge. Adding bottom padding to the column interior had no effect: the button’s position within the column did not change, only the space below it (which was already being clipped).

Fix

Moved the Button outside the verticalScroll Column into a sticky footer using the Material3 AlertDialog structural pattern: an outer Column holds a weight(1f, fill = false) scrollable inner Column for the text and input, and the Button sits below it as a second child of the outer column with PADDING_LARGE on all sides. This guarantees the button is always fully rendered regardless of content height or viewport density. Also changed TextAlign.JustifyTextAlign.Start on both body paragraphs (Finding 5 from the same audit: justified text produces ragged word gaps in narrow columns), and changed empty PIN slot dot color from outlineVariant to onSurfaceVariant for legibility in dark mode (Finding 3).

Prevention

When a primary CTA must be persistently visible regardless of scrollable content height, keep it outside the scroll container as a column sibling — not as the last item inside the scroll. Placing action buttons inside a verticalScroll Column is structurally unsafe: the button is only guaranteed to be visible if the content is short enough to leave room, which is viewport-density-dependent. The Material3 AlertDialog pattern (scrollable body + sticky footer) is the correct model for modal content with a primary action.