Onboarding artwork: four of the seven steps have none #29
Labels
No Label
P0
P1
P2
release-blocker
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: null/Privacy-Period-Tracker#29
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Onboarding is where this app makes its first impression, and it currently starts warm and then turns into a form.
What is true now
app/src/main/kotlin/dev/privacyllc/period/feature/onboarding/OnboardingScreen.kthas seven steps. Three carry an illustration and four are bare:Welcome(:121)WelcomeIllustration— three overlapping ringsLastPeriod(:134)PeriodEnd(:154)PreviousHistory(:182)LearningIllustration— scattered dotsPrivacyPromise(:221)PrivacyIllustration— shield and ringNotificationPrivacyStep(:244)FirstForecast(:300)Confirmed by driving the whole flow by hand on the
PeriodMinSdk26emulator at7f7513e, not by reading the file: steps 2, 3, 6 and 7 render as a heading, a control and a large empty area below it.The existing three are placeholders from #15, drawn as Compose
Canvaspaths incore/designsystem/src/main/kotlin/dev/privacyllc/period/designsystem/art/Illustrations.ktbehind replaceable names.What it costs
Steps 2 and 3 are where a new user does the only real work in onboarding, and they are the barest screens in the product. Step 7 is the payoff — the first forecast — and it is a card on an empty background. First run is the single moment the app has to establish both things at once: that it is welcoming, and that it is private. Right now the privacy half is asserted on exactly one screen and the warmth stops after the first.
The brief
Welcoming and visibly private, in the same picture rather than alternating between them. §42 asks for subtle vector illustrations built from overlapping circular forms, phase and cycle progression, soft abstract curves. The privacy idea already has a vocabulary in
PrivacyIllustration(a shield enclosing a ring) — the enclosure reads as protection without a padlock, and extending that idea is cheaper than inventing a second visual language.What to do
Illustrations.ktbehind replaceable names so call sites do not change.docs/design/README.md— its "The in-app artwork is placeholder" section stops being true for onboarding the moment this lands.Traps
Illustrations.ktKDoc, indocs/design/README.md, and the reason is that this app gets opened in public and a shoulder-glance should learn nothing.contentDescriptionvia asemanticsblock. TalkBack has never actually been run on this app, so do not assume the existing descriptions read well in sequence — new ones should be written expecting that check to happen.Why filed and not fixed
An agent can draw more circles; it cannot decide what this product's first impression should feel like. That is the owner's call, and the brand guide arrived from a person for the same reason.
Verify: All seven steps in
OnboardingScreen.ktrender an illustration, driven by hand on bothPeriodQAandPeriodMinSdk26, with the primary button still reachable without scrolling at default font scale, and no item from §42's forbidden list present.The owner supplied a seven-card concept set at
docs/design/dist/— one card per onboarding step, numbered 1 to 7, matching the steps inOnboardingScreen.ktexactly, including all four that had no art. They are on-brand by construction:BRAND_GUIDE.md§22 holds the master prompt that produced them, and it sanctions the botanicals, crescents, shields and palette used.What this settles
The direction, which is the half this issue said needed a person rather than an agent. There is now a decided answer for every step, and the welcoming-and-visibly-private brief is met — privacy appears on cards 5, 6 and 7 rather than only on one screen.
What it does not settle
The concepts are not the assets. Five things stand between these images and shipping, and the first three are why this issue stays open rather than closing:
Raster, ~12 MB for the seven. The release APK is 1.9 MB today (
app/build/outputs/apk/release/app-release-unsigned.apk). Even aggressively optimised these would dominate it, and §42's asset preference is explicit: Compose vector paths or VectorDrawable, avoid unnecessary raster.The titles and subtitles are baked into the pixels. The app already renders all seven itself —
Heading("Know what's coming.", ...)at :128,Heading("When did your last period start?")at :136, and so on through :302. Dropping these in as-is prints every title twice. Baked text is also untranslatable, cannot scale with the user's font size (never tested, and the Today hero is 72sp), and is invisible to TalkBack (never run). Two of those are open QA gaps indocs/qa/ClaudeQACoverage.md.Light mode only, and dark mode is inbound. Each card is a near-white surface over a pale landscape; on a dark theme they render as bright rectangles.
BRAND_GUIDE.md§22 already names the dark palette — midnight plum/eggplant with luminous rose and lavender accents — anddocs/design/README.mdrequires a light/dark preview pair for every screen, a rule that exists because dark mode was silently broken for all of Batch 01. Raster means drawing the set twice and keeping two sets in step; vector recolours from theme tokens for free.Card 7 shows fertility the app deliberately refuses at that moment. Its forecast panel lists Period, Fertile window and Ovulation. Driven by hand on
PeriodMinSdk26at7f7513e, the real first-forecast screen shows next period, expected window and confidence Low with no fertility at all, and Today reads "Not enough history to estimate". Onboarding art promising an estimate that the next screen declines to make is what §11 and §18 exist to prevent — this one is a product-truth conflict, not a style note.Card copy differs from shipped copy. "Last period start" against "When did your last period start?", and similar on card 3. Whichever wins,
PRODUCT_PLAN.mdowns the screen copy and the two must be reconciled rather than left to diverge.What remains, in order
Illustrations.ktbehind the existing replaceable names, taking colour from theme tokens so one set serves both themes.docs/design/README.md.The concept set should be kept as the reference these are drawn from, not deleted once the vectors exist.
Verify: unchanged — all seven steps in
OnboardingScreen.ktrender an illustration, driven by hand on bothPeriodQAandPeriodMinSdk26, with the primary button still reachable without scrolling at default font scale, and no item from §42's forbidden list present.The direction is now fully settled, in both themes. Committed at
081257fasdocs/design/dist/Light/anddocs/design/dist/Dark/— seven illustrations each, identical dimensions per card so a theme switch does not move the layout.Every objection raised in the comment above is resolved in the delivered set:
BRAND_GUIDE.md§22 specifies, a real dark composition rather than the light one dimmed07_Forecastis a calendar and a cycle arc naming no fields at allTwo further corrections came out of review and are worth not undoing:
LearningIllustrationis also the Insights empty state, where a "4" means nothing, and baked numbers freeze a running order this flow has already changed once. A step indicator belongs in live UI where TalkBack can read it.07_Forecastnames no fields deliberately. An intermediate draft named the correct ones but painted Confidence — Low permanently, which is wrong for anyone with a settled cycle. Naming nothing is the only version that cannot contradict the live forecast.docs/design/dist/README.mdrecords all of it, so a careless regeneration does not quietly reintroduce them.What is left on this issue
The concepts are decided; the assets are not drawn. The fertility question that led the previous ordering has been answered by the artwork, by omission. What remains:
Illustrations.ktbehind the existing replaceable names, taking colour from theme tokens — one set for both themes rather than two raster sets to keep in step.docs/design/README.md.PRODUCT_PLAN.md, which owns the screen wording.Note that
EmptyStateIllustration— Today's "nothing logged yet" state — has no card in the set. Without one, onboarding ships real art while Today keeps a placeholder a user sees in the same session.Verify: unchanged.
Shipped in
5fc9453. All eight illustrations are in core/designsystem/src/main/res/ as drawable/ + drawable-night/ pairs; every one of the seven onboarding steps now renders art, verified by driving the whole flow on PeriodMinSdk26 in both themes. Not redrawn as vectors, deliberately: gradient landscapes have no honest VectorDrawable and §42 objects only to unnecessary raster — the whole set costs 130 KB (release APK 1.90 to 2.03 MB). CycleMarkers.kt keeps its vectors because those are drawn from data. ./gradlew check, schema-guard.sh and doc-claims.sh all pass.