# 09 · Build plan

There are four phases. Each one has a checklist and acceptance criteria, and a phase is done only when every box is ticked.

---

## Phase 1: clickable HTML prototype of every screen (Grok Build)

Work in `spec/starter/`. Follow the pattern of `today.js`, `inbox.js` and `thread.js`. Move each stub out of `stubs.js` into its own `screens/<name>.js`.

**Order of work** (matches `GROK_PROMPT.md`):

- [ ] 1. Leads list (search, status chips, grouped list) + lead detail (summary, action tiles, status menu, notes sheet, Book a job sheet, quote/invoice sheets)
- [ ] 2. Jobs › Calendar: Day timeline with NOW line, Week grid, Remy ghost slots + their sheet, event sheet, "+" Book a job
- [ ] 3. Jobs › Pipeline: columns by contract status, job cards, stuck state, long-press drag, "Move to…" sheet, Show lost toggle; job detail with Call off confirmation
- [ ] 4. Inbox › Calls polish: keypad sheet, call banner, call-failed dialog; voicemail flow end to end
- [ ] 5. Customers (A–Z rail, search, add contact sheet with required consent) + customer file (account tiles, notes, timeline)
- [ ] 6. More + all settings pages (business details, opening hours, alerts, your assistant, teach Remy + answer sheet, how much Remy answers, your calls ring, team/billing web links, about, sign-out confirm)
- [ ] 7. Sign in (all error strings, session-expired notice, forgot password rule), alerts primer, Remy sheet, setup flow (6 steps, incl. texting-approval waiting state)
- [ ] 8. Thread extras: consent sheet, template picker, continue-by-text sheet, forward sheet, failed-send retry, photo viewer
- [ ] 9. Full pass: every screen × (live, loading, empty, error, offline) × (light, dark) × (glass, no glass, high contrast) × (text M, XXL) × (motion, reduced motion)

**Acceptance criteria**
- [ ] Every screen in `04-screens.md` exists at its route, and there are no dead ends (each tap does something real or shows a toast describing the real behaviour).
- [ ] Every flow in `05-flows.md` can be clicked through from start to finish.
- [ ] Every screen draws all five states. `?state=loading|empty|error|offline` works on each.
- [ ] Light/dark, Reduce Transparency, Increase Contrast, Reduce Motion and XXL text all look correct (no clipped text, no overlap, no unreadable glass).
- [ ] No horizontal page scroll at 320px wide. Full screen on a phone, framed on desktop.
- [ ] No console errors or warnings, opened as `file://` and from https://remly-ui-concepts.pages.dev/spec/starter/.
- [ ] `data.js` contract objects are unchanged. New needs are under `proposed` and listed in `06-data.md`.
- [ ] Tokens only. No raw colours in `screens/*.js` except the Remy mark. `spec/tokens.css` == `spec/starter/tokens.css`. `tokens.json` matches.
- [ ] Hit targets ≥ 44pt; text contrast ≥ 4.5:1 (spot-check with a contrast tool on the vivid wallpaper).
- [ ] Spec files updated wherever a decision was made during the build.

## Phase 2: Sruly review

- [ ] Jack sends Sruly the live link (https://remly-ui-concepts.pages.dev/spec/starter/) and a one-page summary of what's new.
- [ ] Sruly reviews on his own phone, in daylight, in both light and dark.
- [ ] Decisions needed from Sruly (each as lettered plain-English options with a recommendation):
  - [ ] A. The new tab order (Today · Inbox · Leads · Jobs · More; Calls inside Inbox) vs keeping the shipping app's tabs
  - [ ] B. Vivid wallpaper on Today only vs everywhere vs nowhere
  - [ ] C. Which proposed data to ask the backend for first (suggestions, estimates, digest, drive times, suggestion mode, onboarding)
  - [ ] D. The new business setup flow: build it in the app, or keep setup on the website
- [ ] Changes from the review are made in the prototype and spec, then re-checked.

**Acceptance:** Sruly signs off in writing (Trello comment) on the screens and the decisions A–D.

## Phase 3: port the tokens

- [ ] A script generates `RemlyTokens.swift` (colours, type, space, radius, motion) and `RemlyTokens.kt` from `tokens.json`. The generated files are committed. Nobody hand-edits them.
- [ ] iOS: extend `DesignSystem/Palette.swift`, `Typography.swift` and `Motion.swift` to read the generated tokens. Glass materials follow `08-native-mapping.md` (iOS 26 `.glassEffect`, iOS 17–25 materials).
- [ ] Android: `RemlyTheme` with light/dark `RemlyColors`, `RemlyTypography`, and the Haze-based glass modifier with an opaque fallback.
- [ ] Web dashboard: imports `tokens.css`.
- [ ] Everything sits behind the existing Appearance switch (Classic / Glass), so nothing changes for users until it's turned on.

**Acceptance:** all three apps build. A token sample screen (the existing `DesignSystemScreen`) shows every token in both themes, and Reduce Transparency, Increase Contrast and Reduce Motion each switch correctly on a real device.

## Phase 4: native build, screen by screen (after the 30 Oct pilot)

**The pilot app is frozen. Don't touch it before or during the pilot.** Start on a branch after the pilot is over.

Order (highest owner value first). For each screen, iOS and Android in the same sprint, and web to match:

- [ ] Inbox (Messages + Calls) → Thread (incl. voicemail card, suggestion card, paused banner, composer states)
- [ ] Today
- [ ] Leads + lead detail
- [ ] Jobs calendar → pipeline → job detail
- [ ] Customers + customer file
- [ ] More + settings, sign in, alerts primer, Remy sheet
- [ ] Setup flow (only if decision D says so)

**Acceptance per screen:**
- [ ] Matches the prototype in layout, copy and every state.
- [ ] Behaviour is identical on iOS, Android and web, or the difference is listed in `08-native-mapping.md`.
- [ ] VoiceOver/TalkBack labels as in `07-accessibility.md`. AX3 text works. Reduce Transparency/Motion work.
- [ ] No new API fields used unless the contract has them (proposed items wait for their contract change).
- [ ] Scrolling is smooth on a mid-range Android and an older iPhone, and the device doesn't heat noticeably during 5 minutes of use.
- [ ] A TestFlight / APK build is cut, with a note saying what's in it.
