User Story
As a new user opening Pyrycode Mobile for the first time, I want a welcoming landing screen that tells me what the app is and offers a clear next step (either pair with an existing pyrycode CLI or set one up), so I'm not dropped into a blank app with no context.
Context
This is the first onboarding-flow ticket. The screen is built as a pure Composable taking navigation callbacks; the actual routing (NavHost in #8) and destination wiring (Scanner + external browser in #14) land in follow-up tickets. The visual reference is Figma node 6:32 (412×892 baseline).
#8 will render this screen at the welcome route (or a placeholder if #7 hasn't merged yet), and #14 will pass real callbacks for the two CTAs. Keeping this ticket free of NavController / Intent code is what makes that parallel work clean.
Acceptance Criteria
Technical Notes
- Pure stateless Composable; no
ViewModel, no remember-based state needed for this ticket.
- Use a placeholder for the logo (e.g. a sized
Box with colorScheme.primary or Icon with a stock vector) — the real logo asset is not part of this ticket.
- The Figma export's React+Tailwind output is a reference, not literal: adapt to Compose + Material 3 conventions.
Out of Scope
Depends On
None — runs in parallel with the data-layer chain. #8 and #14 depend on this.
Size Estimate
S — single stateless Composable file with layout tree + two preview composables; <100 LOC, no logic.
User Story
As a new user opening Pyrycode Mobile for the first time, I want a welcoming landing screen that tells me what the app is and offers a clear next step (either pair with an existing pyrycode CLI or set one up), so I'm not dropped into a blank app with no context.
Context
This is the first onboarding-flow ticket. The screen is built as a pure Composable taking navigation callbacks; the actual routing (NavHost in #8) and destination wiring (Scanner + external browser in #14) land in follow-up tickets. The visual reference is Figma node
6:32(412×892 baseline).#8 will render this screen at the
welcomeroute (or a placeholder if #7 hasn't merged yet), and #14 will pass real callbacks for the two CTAs. Keeping this ticket free of NavController / Intent code is what makes that parallel work clean.Acceptance Criteria
ui/onboarding/namedWelcomeScreen, with signature@Composable fun WelcomeScreen(onPaired: () -> Unit, onSetup: () -> Unit)(signature is fixed because feat(ui): set up Navigation Compose with Welcome → ChannelList placeholder #8 and feat(ui): wire Welcome screen CTAs to Scanner navigation + external browser #14 consume it).6:32at the 412×892 baseline: hero section (logo placeholder, "Pyrycode Mobile" title, subtitle), primary CTA "I already have pyrycode" invokingonPaired, secondary CTA "Set up pyrycode first" invokingonSetup, open-source footer line at the bottom.MaterialTheme.colorScheme.*andMaterialTheme.typography.*only — no hardcodedColor(0x...)literals or hardcoded font sizes / weights / families.NavControllerimport or reference anywhere in the file — navigation is invoked through the two callback parameters only.@Previewcomposables render the screen, one with light scheme and one with dark scheme (uiMode = UI_MODE_NIGHT_YES), both wrapped in the app'sMaterialTheme../gradlew assembleDebugpasses.Technical Notes
ViewModel, noremember-based state needed for this ticket.BoxwithcolorScheme.primaryorIconwith a stock vector) — the real logo asset is not part of this ticket.Out of Scope
NavHost/NavControllerwiring (feat(ui): set up Navigation Compose with Welcome → ChannelList placeholder #8)Depends On
None — runs in parallel with the data-layer chain. #8 and #14 depend on this.
Size Estimate
S — single stateless Composable file with layout tree + two preview composables; <100 LOC, no logic.