All docs

Docs

Personal Loan AppFlow — Master Plan & Implementation Status

Last reviewed: June 2026
Audience: Designers, product managers, engineers, AI agents
Purpose: Single source of truth for the gallery implementation of the Personal Loan application flow — what exists today, how tokens and components propagate, what remains, and how to complete a live end-to-end prototype without backend work.


Table of contents

  1. How this document relates to other docs
  2. Executive summary
  3. Project scope
  4. Environment and architecture
  5. Investigated items
  6. Step inventory (full audit)
  7. Design tokens — how changes apply
  8. Components — state and token coverage
  9. End-to-end connectivity today
  10. Risks and concerns
  11. Implementation plan (step-by-step)
  12. Validation and maintenance
  13. Appendix

1. How this document relates to other docs

DocumentRole
personal-loans-flow.mdProduct routing spec — production step order, branches, footnotes (*, , ), and assumptions
This documentGallery implementation tracker — code status, gaps, token/component workflows, and phased build plan
personalLoanFlow.tsRuntime registry — slugs, metadata, screen components, flow-map data
workflow-contracts.mdEngineering contracts — file placement, token change rules, validation commands
review-checklist.mdPre-delivery quality gate

When production routing changes, update personal-loans-flow.md first, then the registry, then this master plan.


2. Executive summary

The Spring Design Library already contains a strong visual prototype of the Personal Loan AppFlow: 22 of 24 steps have authored screen bodies, shared chrome (AppFlowShell), token-backed components from @spring/ds-react, and a flow map with live iframe previews.

MetricValue
Registry steps24
Screens with Body component22
Placeholder only (planned)2 — start, complete-skipped-steps
Status ready20
Status new (built, not yet promoted)2 — loan-amount, purpose-of-loan
Full journey manual QANone

Feasibility

GoalRatingNotes
Visual prototype steps 2 → 19HighClick-through works with real screens
Full path through terminal outcomesMediumOutcome screens exist; analyzing → outcomes routing is missing
All production branches/variantsMedium–LowPartial; needs demo routing layer
Global restyle via tokensHighSync pipeline is solid; a few hardcoded literals remain
Production applicationOut of scopeNo API, persistence, Flinks, or Twilio

Top three gaps blocking a demo narrative

  1. Analyzing → outcomes — step 20 has no forward navigation or demo controls.
  2. Step 1 landing (start) — no real UI; PlaceholderStep only.
  3. Step 21 recovery (complete-skipped-steps) — not built.

3. Project scope

In scope

  • Live, clickable Personal Loan flow in the design library from landing through terminal outcomes
  • Consistent mobile shell: floating bottom CTA, scrollable content, hidden scrollbar
  • Token-driven visual consistency across all steps and components
  • Demo routing for branches and outcomes without backend APIs
  • Flow map + PageMapPopup as visual source-of-truth preview
  • Documentation for non-technical stakeholders (token change workflow)

Out of scope

  • Production APIs, database, session persistence, analytics
  • Real Flinks bank connection, Twilio SMS, or eligibility polling
  • Returning customer paths (welcome-back, verify-otp, deeper prepop)
  • Full Foundation cross-sell flow (PL declined screen links out only)
  • Plan selection step (exists as a component screen but is not in the Personal Loan registry)

4. Environment and architecture

Monorepo layout

AreaPathRole
Design system packagepackages/spring-ds-react/Reusable UI + tokens → @spring/ds-react
Design library appapps/design-library/Next.js gallery at /library/*
Token sourcepackages/spring-ds-react/src/components/tokens/design-tokens.mjsVisual source of truth
Generated CSSpackages/spring-ds-react/src/components/tokens/generated/css-variables.css--spring-* variables
AppFlow registryapps/design-library/src/gallery/page/appflow/personalLoanFlow.tsStep metadata + Body imports
AppFlow screensapps/design-library/src/gallery/page/appflow/screens/Step body implementations
AppFlow shellapps/design-library/src/gallery/page/appflow/AppFlowShell.tsxShared chrome
Flow mapapps/design-library/src/gallery/page/appflow/PersonalLoanFlowChart.tsxVisual map
Step popupapps/design-library/src/gallery/page/appflow/PageMapPopup.tsxLive preview + source-of-truth panel

How a step renders

flowchart LR
  registry[personalLoanFlow.ts] --> route["/library/page/appflow/personal-loan/slug"]
  route --> layout["[slug]/layout.tsx"]
  layout --> shell[AppFlowShell]
  shell --> body[Step Body or PlaceholderStep]
  ds["@spring/ds-react"] --> shell
  ds --> body

Route entry: apps/design-library/src/app/library/page/appflow/personal-loan/[slug]/page.tsx

  • If step.Body exists → render screen component
  • Else → render PlaceholderStep.tsx (shell CTA advances to next registry step)

URL modes

ModeQueryEffect
NormalFull library chrome or AppFlow page
Embed?embed=1No library header/sidebar; for iframes
Map thumbnail?preview=mapTight shell layout for flow-map tiles
Viewport?viewport=mobileMobile artboard in popup iframe
Variantse.g. ?frequency=, ?variant=manual, ?phone=Step-specific preview state

Gallery root: /library/page/appflow/personal-loan
Step URL pattern: /library/page/appflow/personal-loan/<slug>

Navigation model (prototype)

  • Each screen calls router.push() to the next gallery slug on Continue
  • No shared application state — data entered on one step is not available on later steps (intentional for design-library prototype)
  • Branching is implemented locally via *Options.ts helper files

5. Investigated items

Audit performed against the codebase in June 2026. Items reviewed:

#AreaFiles / artifacts
1Step registry (24 entries)personalLoanFlow.ts
2Screen implementations (22)screens/AppFlow*.tsx
3Placeholder fallbackPlaceholderStep.tsx, [slug]/page.tsx
4Next-step routing*Options.ts, inline NEXT_HREF constants
5Employment branchesemploymentStatusOptions.ts
6CTA patternsAppFlowShell.tsxuseAppFlowCta, AppFlowInlineCta
7Token pipelinedesign-tokens.mjs, scripts/sync-tokens.js, app/layout.tsx
8Component exportspackages/spring-ds-react/src/index.ts
10Mobile responsivenessAppFlowShell.tsx, per-screen max-md: usage
11Flow map + popupPersonalLoanFlowChart.tsx, PageMapPopup.tsx
12Product spec cross-checkdocs/ux/personal-loans-flow.md footnotes
13Decision / outcome metadataPERSONAL_LOAN_DECISIONS in registry

Key findings

  • Registry and screens are aligned for all steps except start and complete-skipped-steps.
  • Linear happy path (name → verify-income → analyzing) is wired with router.push.
  • Employment branching matches the UX doc for the common cases.
  • Analyzing is a dead end in the gallery — no CTA, no auto-advance, no outcome simulator.
  • Verify bank is a dead end — static Flinks mockup by design; no prototype Continue.
  • Mobile body layouts are only refined on name and purpose-of-loan; shell provides floating CTA globally.
  • Token sync updates all --spring-* consumers; documented literals still bypass sync (see §7).

6. Step inventory (full audit)

Gallery URL base: /library/page/appflow/personal-loan/

StepLabelSlugPhaseStatusScreenNext route(s)CTAMobile bodyBlocker
1LandingstartAplannedname (via PlaceholderStep)ShellNo landing UI
2NamenameAreadyAppFlowWhatsYourNameScreen.tsxloan-amountuseAppFlowCtaYes
3Loan Amountloan-amountAnewAppFlowLoanAmountScreen.tsxpurpose-of-loanInline submitNoAlways routes to step 4*
4Loan Purposepurpose-of-loanAnewAppFlowLoanPurposeScreen.tsxcredit-ratingInline submitYes
5Credit Ratingcredit-ratingAreadyAppFlowCreditRatingScreen.tsxemployment-statusInline submitNo
6Employmentemployment-statusAreadyAppFlowEmploymentStatusScreen.tsxBranchedInline submitNo
7Income Frequencyincome-details-frequencyAreadyAppFlowIncomeDetailsFrequencyScreen.tsxincome-details-amount?frequency=Inline submitNo
8Income Amountincome-details-amountAreadyAppFlowIncomeDetailsAmountScreen.tsxincome-durationInline submitNo
9Income Durationincome-durationAreadyAppFlowIncomeDurationScreen.tsxhome-addressInline submitNo
10Home Addresshome-addressAreadyAppFlowHomeAddressScreen.tsxhomeowner-statusInline submitNo?variant=manual
11Homeownerhomeowner-statusAreadyAppFlowHomeownerStatusScreen.tsxdate-of-birthInline submitNo
12Date of Birthdate-of-birthAreadyAppFlowDateOfBirthScreen.tsxcontact-phoneInline submitNo
13Contact Phonecontact-phoneBreadyAppFlowContactPhoneScreen.tsxcontact-code?phone=Inline submitNo
14Verify Codecontact-codeBreadyAppFlowContactCodeScreen.tsxfinancial-selectorInline submitNo
15Select Bankfinancial-selectorBreadyAppFlowFinancialSelectorScreen.tsxverify-bankInline onClickNo
16Verify Bankverify-bankBreadyAppFlowVerifyBankScreen.tsxNoneNoneNoNo forward nav
17Verify Identityverify-identityBreadyAppFlowVerifyIdentityScreen.tsxverify-addressInline onClickNo
18Verify Addressverify-addressCreadyAppFlowVerifyAddressScreen.tsxverify-incomeInline onClickNoSkip → same
19Verify Incomeverify-incomeCreadyAppFlowVerifyIncomeScreen.tsxanalyzing-applicationInline onClickNoSkip → analyzing
20Analyzinganalyzing-applicationCreadyAppFlowAnalyzingApplicationScreen.tsxNoneNoneNoNo outcome routing
21Complete Skippedcomplete-skipped-stepsCplannedShell (placeholder)Screen not built
22-1Successapplication-successDreadyAppFlowApplicationSuccessScreen.tsxTerminalIn-body buttonNoNot linked from 20
22-2Try Foundationdeclined-try-foundationDreadyAppFlowDeclinedTryFoundationScreen.tsxFoundation flowIn-body buttonNoNot linked from 20
22-3Declined Sorrydeclined-sorryDreadyAppFlowDeclinedSorryScreen.tsxTerminalNoneNoNot linked from 20

* Footnote *: when purposeOfLoanVariant === 'false', production skips step 4; gallery always routes loan-amount → purpose-of-loan.

† Footnote — employment branches (employmentStatusOptions.ts):

Employment selectionNext slug
Employed, Self Employedincome-details-frequency
No Current Incomehome-address (skips income steps)
Retired/Pension, LTD, EI, Otherincome-details-amount (skips frequency)

‡ Footnote : production may skip verify-address when POA not required; gallery always shows the screen.

CTA pattern reference

PatternWhen usedMobile behaviour
useAppFlowCta({ … })Name step; PlaceholderStepShell fixed bottom bar
AppFlowInlineCtaMost form stepsFixed bottom on mobile; inline on desktop
useAppFlowCta(null) + inlineVerify upload steps, financial selectorInline only (shell CTA hidden)
In-body SpringButtonSuccess, declined, analyzingNo shell CTA

7. Design tokens — how changes apply

Architecture

flowchart TB
  source[design-tokens.mjs]
  sync["npm run tokens:sync"]
  css[css-variables.css]
  layout["app/layout.tsx import"]
  components["DS components + AppFlow screens"]
  source --> sync --> css --> layout --> components

Global import in apps/design-library/src/app/layout.tsx:

import '@spring/ds-react/tokens/generated/css-variables.css'

Components consume tokens as CSS variables, e.g. var(--spring-semantic-color-text-text-primary, #242621).


Step-by-step: for designers and PMs (non-technical)

When a colour, font size, or spacing value changes in the design system:

  1. Identify what changed — e.g. primary purple, body text size, card border colour.
  2. Request an engineering update — token changes require approval and must be applied in design-tokens.mjs (not in individual screens).
  3. Engineer runs sync — they run npm run tokens:sync and restart the preview server.
  4. Verify visually — open any AppFlow step (e.g. Name, Loan Purpose) and any component doc page (e.g. TextField, SpringButton). The new values should appear everywhere that uses the token.
  5. Understand limits — layout widths (e.g. 630px tile grid), screen copy, and routing are not controlled by tokens. A few error colours and bank tints are still hardcoded (see below).

What updates automatically after sync

  • Button colours and sizes
  • Input field borders, backgrounds, error states
  • Progress bar gradient
  • Page title typography (via AppFlowPageTitle token bindings)
  • Shell wash and footer styling
  • All component doc preview pages

What does not update automatically

  • Fixed layout dimensions in screen files (400px form width, 630px grid)
  • Screen text/copy
  • Icons and illustration assets
  • Hardcoded literals listed in the table below

Step-by-step: for engineers and AI agents (technical)

  1. Get approval for token changes (workflow-contracts.md § Token Change Contract).
  2. Edit packages/spring-ds-react/src/components/tokens/design-tokens.mjs.
  3. Regenerate artifacts:
    npm run tokens:sync
    
  4. Restart the dev server if running (npm run dev).
  5. Before production build validation, clear the Next.js cache:
    rm -rf apps/design-library/.next
    npm run build
    
  6. Lint:
    npm run lint
    
  7. Optional Figma pull (requires .env with FIGMA_TOKEN, FIGMA_FILE_ID):
    npm run tokens:figma
    npm run tokens:sync
    

See also: CONTRIBUTING.md, Design Tokens hub in the running gallery.

Known non-token literals (will NOT auto-update)

LocationValue / note
packages/spring-ds-react/src/components/inputs/TileSelector.tsxError text #dd233e (Figma AppFlow error)
packages/spring-ds-react/src/components/inputs/financialSelectorBankOptions.tsxBank tile surface rgba/hex tints
packages/spring-ds-react/src/components/inputs/TileSelector.tsxDefault tile surface rgba(255,255,255,0.5)
Various AppFlow screensShadow/opacity values using color-mix with token fallbacks (partial)

Address these in Phase P2 if full token purity is required.


8. Components — state and token coverage

All Personal Loan screens import from @spring/ds-react (index.ts).

ComponentAppFlow stepsStates implementedGallery docs
SpringButtonShell CTA, success, declinedprimary, disabled, loading, block, href/library/components/actions/spring-button
SpringProgressShellvalue, caption/library/components/feedback-indicators/spring-progress
SpringHeaderShellapp variant/library/components/navigations/spring-header
SpringFooterLegalShell (desktop)appflow variant/library/components/navigations/spring-footer
TextFieldName, DOB, address, incomedefault, active, error/library/components/inputs/text-field
BoxSelectorCredit, employment, homeowner, frequencydefault, selected, keyboard nav/library/components/inputs/box-selector
TileSelectorPurpose, financial selectordefault, selected, error, mobile fluid/library/components/inputs/tile-selector
LoanAmountSliderLoan amountvalidation min/max/library/components/inputs/loan-amount-slider
SplitPillInputIncome durationdefault, error/library/components/inputs/split-pill-input
PhoneNumberFieldContact phonedefault, error/library/components/inputs/phone-number-field
OtpFieldContact codedefault, error, timer/library/components/inputs/otp-field
ConsentBoxContact phonechecked/unchecked/library/components/actions/consent-box
DropdownFieldHome address (manual)default, error, menu/library/components/inputs/dropdown-field
SearchFieldHome address (search)default/library/components/inputs/search-field
FileUploaderVerify identity/address/incomedefault, error, file chosen/library/components/inputs/file-uploader
FaqAccordionDeclined try Foundationexpand/collapse/library/components/modules/faq-accordion

Component quality gaps

  • Error states: not every screen surfaces validation in the UI during normal demo walkthrough (some only on submit).
  • Mobile layouts: only name and purpose-of-loan bodies have dedicated max-md: spacing; others use desktop-centric widths inside the mobile shell.
  • Disabled states: loan amount disables Continue when invalid; most other steps do not disable the CTA.

9. End-to-end connectivity today

What works (gallery demo)

Flow segmentStatus
nameloan-amount → … → verify-incomeContinue chain works
employment-status branchesImplemented
income-details-frequency → amount with ?frequency=Implemented
home-address search vs manual?variant=manual
contact-phone → code with ?phone=Implemented
financial-selectorverify-bankWorks; bank step is terminal
Flow map click → popup previewWorks with mobile/desktop toggle
start placeholder → namePlaceholderStep shell CTA

What is incomplete for a full demo

GapImpactWorkaround today
No start landing UICannot demo step 1 designStart at /name or use placeholder
verify-bank has no ContinueBreaks linear walk at step 16Navigate manually to verify-identity URL
analyzing-application has no forward navCannot reach outcomes by clickingOpen outcome URLs directly or use flow map
No complete-skipped-steps screenRecovery path missingN/A
Purpose variant skip not wiredAlways shows step 4N/A
No cross-step data{firstName} on step 21 won't populateN/A

Recommended demo path (today)

  1. Open /library/page/appflow/personal-loan/name
  2. Click Continue through each step through verify-income
  3. Continue to analyzing-application
  4. Manually open /library/page/appflow/personal-loan/application-success (or other outcome) from flow map popup or URL bar

10. Risks and concerns

RiskSeverityDescriptionMitigation (see §11)
Analyzing dead-endHighBreaks end-to-end demo narrativeP0: outcome simulator or query param
Missing landing + recovery screensHighSteps 1 and 21 are placeholdersP0 / P1 builds
Verify bank dead-endMediumLinear walk stops at step 16P0: prototype Continue
Mobile desktop layoutsHigh20 screens lack mobile body refinementsP1 mobile pass
Registry vs UX doc driftMediumFootnotes and branches may divergeUpdate both when changing order
Hardcoded literalsLow–MedToken sync misses some coloursP2 cleanup
Dual CTA patternsMediumAuthors mix useAppFlowCta and inlineDocumented in §6; standardize in P1
PlaceholderStep linear advanceLowstartname OK; won't respect branchesUse direct URLs for branch testing
No journey manual QAMediumRegressions may go unnoticedP2 manual browser journey
Stale CSS after token syncMediumDev server cache§7 restart + .next clear
Scope creep to productionHighBackend/API work expands scope§3 out-of-scope list

11. Implementation plan (step-by-step)

Each task includes: owner role, files, acceptance criteria, validation.


Phase P0 — Demo-ready end-to-end (must have)

P0-1 — Build step 1 landing screen

OwnerAppFlow engineer + designer
FilesNew AppFlowStartScreen.tsx; update personalLoanFlow.ts (Body, status: 'ready')
FigmaApplication-Flow-2026 landing node (production /personal-loans)
AcceptanceEmail/value prop + CTA → name; shell progress 7%; mobile floating CTA
Validatenpm run lint && npm run build; manual walk start → name

P0-2 — Analyzing → outcome demo routing

OwnerAppFlow engineer
FilesAppFlowAnalyzingApplicationScreen.tsx; optional analyzingApplicationOptions.ts
Approach (choose one)(A) Query param `?outcome=success
AcceptanceFrom analyzing, user reaches each of the three outcome slugs without manual URL entry
ValidateManual + document query param in §13

P0-3 — Verify bank prototype Continue

OwnerAppFlow engineer
FilesAppFlowVerifyBankScreen.tsx
AcceptancePrototype “Continue” (or auto-link) → verify-identity; labelled as demo-only in code comment
ValidateWalk steps 15 → 16 → 17

P0-4 — Manual walkthrough checklist

OwnerQA / PM
DeliverableChecklist in this doc’s appendix or team wiki
AcceptanceHappy path + three outcomes verified on mobile and desktop popup

P0-5 — Automated validation

npm run lint
npm run build

Optional: add one manual browser spec for nameloan-amountpurpose-of-loan chain.


Phase P1 — Spec completeness

P1-1 — Build complete-skipped-steps (step 21)

FilesNew AppFlowCompleteSkippedStepsScreen.tsx; registry update
AcceptanceMatches UX doc recovery prompt; links back to verify-address / verify-income
ValidateBuild + manual skip flow

P1-2 — Wire skip/recovery paths

FilesverifyAddressOptions.ts, verifyIncomeOptions.ts, verify screen components
AcceptanceWhen both POA and POI skipped, route to complete-skipped-steps before analyzing (per UX doc)
ValidateCross-check with personal-loans-flow.md

P1-3 — Purpose variant flag

FilesAppFlowLoanAmountScreen.tsx; optional gallery query param e.g. ?purposeVariant=false
AcceptanceWhen variant false, loan-amount Continue → credit-rating (skips step 4)
ValidateBoth paths manually

P1-4 — Mobile layout pass (remaining 20 screens)

PatternFollow AppFlowWhatsYourNameScreen.tsx + AppFlowLoanPurposeScreen.tsx + shell max-md:
FigmaMobile nodes in Application-Flow-2026 (106-xxxx series)
AcceptanceEach step readable on 393px width; no clipped CTAs; scroll where needed
ValidatePageMapPopup mobile viewport for each slug

P1-5 — Promote registry status

FilespersonalLoanFlow.ts
Changeloan-amount and purpose-of-loan: newready

Phase P2 — Quality and maintainability

P2-1 — Optional demo context

FilesNew AppFlowDemoContext.tsx; wire name step to provide firstName for step 21 title
Acceptance{firstName} renders on complete-skipped when context set

P2-2 — Token literal cleanup

FilesTileSelector.tsx, financialSelectorBankOptions.tsx
AcceptanceError and bank tints use semantic tokens where equivalents exist

P2-3 — Expand manual QA coverage

AcceptanceFull journey name → analyzing; one outcome path; employment branch spot-check

P2-4 — Flow map / registry sync

FilespersonalLoanFlow.ts, PersonalLoanFlowChart.tsx
AcceptanceOutcome labels 22-1, 22-2, 22-3 match popup and map tiles after P0–P1

12. Validation and maintenance

Pre-PR checklist

Use review-checklist.md. Minimum for AppFlow changes:

  • Screen registered in personalLoanFlow.ts with Body, sourcePath, status
  • Route resolves at /library/page/appflow/personal-loan/<slug>
  • Uses @spring/ds-react components (no raw hex in new code)
  • CTA follows shell pattern (§6)
  • npm run lint && npm run build pass
  • Update this master plan if step status or connectivity changed

How to preview a step

MethodURL / action
Directhttp://localhost:3000/library/page/appflow/personal-loan/<slug>
Flow map/library/page/appflow/personal-loan → click tile → Open view
Mobile popupOpen view → Mobile toggle
EmbedAdd ?embed=1 for iframe-style preview

When to update which doc

ChangeUpdate
Production routing / branchespersonal-loans-flow.md
Gallery implementation statusThis master plan
Slug, order, screen componentpersonalLoanFlow.ts
Token valuesdesign-tokens.mjs + run sync
New reusable componentpackages/spring-ds-react + gallery component page

13. Appendix

A. Quick commands

npm install
npm run dev                    # local gallery → http://localhost:3000/library/...
npm run tokens:sync            # after token edits
npm run lint
npm run build

B. Glossary

TermMeaning
AppFlowGallery implementation of a product application flow
RegistryPERSONAL_LOAN_STEPS in personalLoanFlow.ts
ShellAppFlowShell — header, progress, CTA, footer
BodyStep-specific centre column component
Embed?embed=1 preview mode for iframes
OutcomeTerminal step after analyzing (success, declined variants)

C. Figma reference

  • Application Flow 2026: Figma file
  • Key mobile nodes: Name 106-995, Purpose 106-1115
  • Key desktop nodes: Purpose 100-778, Credit 88-573, Analyzing 141-3664

D. Demo outcome URLs (after P0-2)

OutcomeGallery URL
Approved/library/page/appflow/personal-loan/application-success
Declined → Foundation/library/page/appflow/personal-loan/declined-try-foundation
Declined (all)/library/page/appflow/personal-loan/declined-sorry

E. Manual walkthrough checklist (P0-4)

  • Flow map loads without horizontal clip
  • start or name → Continue works on mobile (floating CTA visible)
  • Loan purpose: 10 tiles, validation error when empty submit
  • Employment: employed → income frequency; no income → home address
  • Contact code: OTP accepts 4 digits; phone shown from query
  • Financial selector: bank required validation
  • Verify bank → verify identity (after P0-3)
  • Verify income → analyzing
  • Analyzing → each outcome (after P0-2)
  • PageMapPopup: mobile + desktop toggle per step
  • Token spot-check: change one semantic colour, sync, confirm button updates

F. Investigated file index

apps/design-library/src/gallery/page/appflow/
├── personalLoanFlow.ts          # Registry
├── AppFlowShell.tsx             # Chrome + CTA
├── PersonalLoanFlowChart.tsx    # Flow map
├── PageMapPopup.tsx             # Live preview
├── screens/
│   ├── AppFlow*.tsx             # 22 step bodies
│   ├── PlaceholderStep.tsx      # Fallback
│   └── *Options.ts              # Routing + copy constants
apps/design-library/src/app/library/page/appflow/personal-loan/[slug]/
├── layout.tsx                   # Shell wrapper
└── page.tsx                     # Body vs placeholder
packages/spring-ds-react/src/
├── index.ts                     # Public exports
└── components/tokens/
    ├── design-tokens.mjs        # Token source
    └── generated/css-variables.css
docs/ux/personal-loans-flow.md   # Product spec

End of master plan. For questions about agent workflow, see operational-manifesto.md.