# Remly Glass: design spec and starter kit

Start here. Everything needed to keep designing the Remly owner app in the "glass" direction is in this folder. You do not need any earlier chat history.

- **Live concepts:** https://remly-ui-concepts.pages.dev (side-by-side picker at https://remly-ui-concepts.pages.dev/pick)
- **This spec online:** https://remly-ui-concepts.pages.dev/spec/
- **Starter prototype online:** https://remly-ui-concepts.pages.dev/spec/starter/

## What Remly is (5 lines)

1. Remly is an AI front desk for trade businesses. The first pilot is an electrician, "Bright Spark Electric" in our fake data.
2. Customers reach the business by phone call, SMS, WhatsApp or a website chat. **Remy**, the AI assistant, answers all of them.
3. Remy captures leads, books jobs, texts back missed calls, and either suggests replies or sends them itself (the owner picks per business, and can pause Remy in any one conversation).
4. Missed calls become voicemail cards with a player and a transcript. The owner sees leads, conversations, calls, jobs and customers, and gets push alerts.
5. There is an iPhone app (SwiftUI), an Android app (Jetpack Compose) and a web dashboard. **All three must behave the same.** This spec is for all three.

## The design direction (one paragraph)

The look is **Liquid Glass over a soft wallpaper**: frosted, light-catching layers in the style of iOS 26, taken from concept 6. The client and product owner, Sruly, liked it. The rule that keeps it usable for a tradesperson standing in sunlight: **glass is for chrome, solid is for content.** Glass is used for the nav bar, the floating tab bar, sheets and floating buttons. Lists, threads, transcripts and forms sit on near-opaque solid surfaces, so text is always readable. There is **one accent colour** (Remly orange), used only for actions and "this needs you". Remy has its own iridescent mark, but that mark is an identity, not an action colour. Motion is quick, springy and restrained. Nothing decorative moves while the owner is reading. Every glass layer has a solid fallback for Reduce Transparency, Increase Contrast and older Android phones.

## File map

| File | What it is |
|---|---|
| `README.md` | This file |
| `GROK_PROMPT.md` | The one prompt to paste into Grok Build to start |
| `01-principles.md` | Readable glass: when to use glass, contrast floors, the one accent, motion restraint |
| `02-tokens.md` | Token reference with sources and decisions |
| `tokens.css` | CSS custom properties: light, dark, reduced transparency, increased contrast, reduced motion |
| `tokens.json` | The same values, platform-neutral, for generating SwiftUI and Compose later |
| `03-components.md` | Every component: anatomy, states, sizes, do/don't |
| `04-screens.md` | Every screen: purpose, layout, actions, states, API route |
| `05-flows.md` | Key flows, step by step, with Mermaid diagrams |
| `06-data.md` | The fake dataset and how it maps onto the API contract |
| `07-accessibility.md` | Dynamic Type, VoiceOver, 44pt targets, contrast on glass, sunlight, one-handed use |
| `08-native-mapping.md` | Tokens and components mapped to SwiftUI (iOS 26 glass, iOS 17–25 fallback) and Compose; risks |
| `09-build-plan.md` | Phases with checklists and acceptance criteria |
| `index.html` | A phone-friendly page that links all of the above |
| `starter/` | The working HTML/CSS/JS prototype kit to extend |
| `starter/index.html` | Phone shell, glass tab bar, hash router, prototype controls |
| `starter/tokens.css` | Copy of `tokens.css`. Keep them identical |
| `starter/components.css` | Every component in `03-components.md`, built from tokens only |
| `starter/app.js` | Router, transitions, sheets, toasts, shared UI helpers |
| `starter/data.js` | Fake data for Bright Spark Electric. Field names match the API contract |
| `starter/screens/today.js`, `inbox.js`, `thread.js` | Three finished screens. Copy their pattern |
| `starter/screens/stubs.js` | Every other screen as a marked stub with a build checklist |

The visual source of truth is in the parent folder (`../`): `6-liquid-glass.html` (the primary base), `2-beautiful.html` (Today dashboard), `8-glass-pipeline.html` (job pipeline) and `10-calendar-glass.html` (calendar). They are also live at the URLs above.

## How to use this with Grok Build

### Phases

| Phase | Who | Output | Done when |
|---|---|---|---|
| 1. Clickable prototype | Grok Build | Every screen in `04-screens.md` built in `starter/`, in every state | The checklist in `09-build-plan.md` §1 passes |
| 2. Review | Sruly (product owner) | Comments and decisions | Sruly signs off on the screens, or lists changes |
| 3. Port the tokens | Remly engineers | `tokens.json` generated into SwiftUI and Compose | Both apps build with the new tokens behind a switch |
| 4. Native build | Remly engineers | Screen-by-screen native build | Starts after the 30 Oct pilot. The pilot app is frozen |

### What "done" looks like for phase 1

- Every route in `04-screens.md` opens from the tab bar or a link, on a phone and on desktop. Nothing is a dead end.
- Every screen draws **live, loading, empty, error and offline**. Use the dev bar, or add `?state=` to the URL.
- Light, dark, Reduce Transparency, Increase Contrast, Reduce Motion and text size XXL all still look right.
- There are no console errors. It opens as a plain file (`file://`) and from the live URL.
- The flows in `05-flows.md` can be clicked through end to end.

### Rules

1. **Fake data only.** Use `starter/data.js`. Never type a real customer's name, number, address or message. Use 555-01xx numbers.
2. **Don't change the API shapes.** Objects in `data.js` follow `openapi.yaml` exactly. Things the design wants that the API does not have go under `proposed` in `data.js`, and each screen must still look right without them. When you add one, list it in `06-data.md` under "Proposed".
3. **Tokens first.** Add any new value to `tokens.css` (and `tokens.json`) before you use it. No raw colours in screen files.
4. **Glass for chrome, solid for content.** See `01-principles.md`. This is the rule most likely to be broken by accident.
5. **One accent.** Orange means "act" or "needs you". Remy's gradient is only the Remy mark and Remy's own surfaces.
6. **Copy the server's words.** Refusals, opt-outs and errors that come from the API show the server text unchanged. The exact strings are in `04-screens.md`.
7. **No build step, no frameworks.** Use vanilla JS and classic `<script>` tags. If you ever need a CDN library, pin an exact version.
8. **No business terms.** Leave out pricing between partners, contracts and private notes. Billing in the app links to the website and shows no prices.

## Decisions taken where the concepts disagreed

| Topic | Concepts said | Spec uses |
|---|---|---|
| Accent colour | `#ff5a1f` (6) vs `#ff6a2b` (2, 10) | `#ff5a1f` for fills and icons. `#c2410c` for accent text and primary buttons (5.2:1 with white) |
| Lists | On glass (6) | On a **solid** surface. Glass stays on chrome |
| Wallpaper | Vivid (6), pastel (10), dark navy (8) | Vivid on Today only; calm pastel everywhere else. Concept 8's navy is dropped |
| Decoration | Floating orbs, drifting wallpaper, pointer sheen, tilt (6) | Dropped. The Remy orb still rotates, and stops under Reduce Motion |
| Sheet | Radius 38 / 0.5s (6), 34 / 0.45s (8), 32 / 0.45s (10) | Radius 38, 0.45s with less overshoot |
| Scrim | .18 (6), .35 (8), .20 (10) | .18 light, .35 dark |
| Small text | 10.5–13.5px | Raised for sunlight: meta 14, tag 12, tab 11 |
| Press scale | .965 / .975 / .97 | .97 |
| Side gutter | 16 (6) / 18 (2) | 16 |
| Pipeline columns | New, Quoted, Booked, Done, **Paid** (8) | The contract's statuses: New, Contacted, Quoted, Booked, Done, To collect. Urgent is a flag, Lost is hidden, Junk never shows. Money only when `proposed` has it |
| Channel colours | Concept avatar gradients | The shipping apps' channel colours |
| Tabs | Home, Inbox, Jobs + orb (6); shipping app: Home, Messages, Calls, Leads, More | **Today · Inbox · Leads · Jobs · More + Remy orb.** Calls is a segment inside Inbox; Customers is under More. Needs Sruly's OK in phase 2 |
| Remy orb | "Ask Remy anything" (6) | Opens a Remy status sheet. There is no chat-with-Remy API |
| Calendar ghost slots | Invented suggestions (10) | Appointments with `status: pending`. Accept = confirm, Not this one = cancel |
