# huddlie app kit

The styled screens and branding layer for the huddlie app. Every screen and state is here, drawn with real copy and seed data, so the app team only has to add the functionality.

- **Gallery of every screen:** `index.html` (served locally at http://localhost:8813/huddlie/kit/)
- **Design system (tokens, type, icons, components):** `system.html`
- **The clickable behaviour prototype these screens come from:** `../app/`

Status as of 2026-09-29: **complete for layout and states, brand v1 applied.** Colours, the mark, the logotype lockup, the dark brand bar, tips and the gradient action come from the huddlie mark (see `../brand/BRANDING.md`), ported from the prototype rebrand. Fonts (Fraunces + Inter), icons and the pattern are still the provisional set.

## What is in here

| Path | What it is |
|---|---|
| `index.html` | Gallery: 86 screens in 10 groups, each with its behaviour notes and a light/dark switch |
| `screens/<id>.html` | One standalone HTML file per screen or state. On a phone it fills the screen; on a desktop it sits in a device frame |
| `system.html` | Tokens, type scale, spacing, icons and every component in one place |
| `assets/tokens.css` | Generated CSS custom properties, light and dark |
| `assets/tokens.json` | The same tokens as JSON, for importing into any platform (Swift, Kotlin, React Native, Flutter) |
| `assets/kit.css` | The components. Reads only from tokens |
| `assets/icons/*.svg` | Each icon as its own 24pt SVG |
| `brand/` | Brand slots: `huddlie-mark.svg` (written by `../brand/build-mark.mjs`, inlined at build), `sample-avatar.jpg` (sample player face for the previews), `avatars/*.svg` (the six drawn player avatars), `huddlie-reveal.json` (animated logo), `pattern.svg` |
| `src/` | Sources: `tokens.json`, `icons.mjs`, `kit.css`, `ui.mjs` (shared markup), `screens/*.mjs` |
| `store/ios/` | iOS app icon set (`AppIcon.appiconset` for Xcode: default, dark, tinted), a night option, 180 px icon, review sheet. Spec: `store/ASSET-SPEC.md` |
| `build.mjs` | Rebuilds everything from `src/`: `node build.mjs` (Node 18+) |

## For developers

1. **Treat each screen file as the visual spec.** The markup is plain and semantic, so structure, spacing and classes can be read straight from it. Elements with `os-status` and `os-home` are the phone's status bar and home indicator, drawn for realism. Skip them: the OS provides them.
2. **Port the tokens, not the pixels.** `assets/tokens.json` holds every colour (light and dark), type role, spacing step, radius, shadow, easing curve and size. Map these into your platform's theme once, and build components against the names (`accent`, `ink-2`, `title-1`, `space-4`) rather than raw values. The rebrand then becomes a token swap.
3. **Read the notes under each screen in the gallery.** They carry the behaviour the prototype encoded (when a state appears, what a button does, which toast follows).
4. **"Added for launch" screens** (launch screen, form errors, loading, offline, confirm-destructive, error) are states the prototype skipped but a shipping app needs. Their copy is provisional.
5. **Accessibility floor built into the styles:** 44pt minimum touch targets, secondary text at 4.5:1 or better, visible focus rings, reduced motion respected (the one celebration shows its finished state), system text sizes should scale the type roles.

### Type roles in points

| Role | Font | Size / line | Used for |
|---|---|---|---|
| display | display serif | 34 / 37 | Celebration beat, score headline |
| title-1 | display serif | 28 / 31 | Screen identity: the player's name, the event |
| title-2 | display serif | 22 / 26 | Month chapters on the timeline |
| title-3 | display serif | 19 / 23 | Lens name, sheet titles, empty-state titles |
| caption-serif | display serif italic | 17 / 24 | A moment's caption |
| team | Instrument Sans at 85% width | 16-17 (titles 28, score 44) | Team names, event titles and scores (bold, tabular figures) |
| headline | sans | 16 / 22 | Event titles |
| callout | sans | 15 / 22 | Row titles, buttons, inputs |
| subhead / footnote / caption | sans | 14 / 13 / 12 | Explanations, row subtitles, meta |

## The design idea

huddlie is a keepsake, closer to a fine photo book than a sports app. Brand v1 takes its colours from the mark: two people (warm and blue), their speech bubbles (violet), the hug (magenta) and the logotype (plum).

- **Brand placement rule:** a page with room carries the colour mark with a quick tip or benefit (`tip()`: a speech bubble whose one sharp corner, the tail, points at the mark). A page without room carries the **dark brand bar** with the colour logo: every hub (logo left, the player lens and gear right) and Get set up (logo centred). Splash, Welcome, Create account, Sign in, the invitation and the foot of Settings show the lockup (mark over logotype).
- **Team names, event titles and scores** use Instrument Sans at 85% width: narrow, classy, fits long names on a phone.
- **Team hub:** each team in a boxed card (a list that scrolls) under a pinned "Add another team" action.
- **Primary actions** use the warm action gradient (coral, magenta, violet). Magenta is the one accent for links, toggles, steps and focus.
- **Whose event:** every event card carries the player's avatar floating on its corner; the ring colour says the type (game magenta, practice blue, tournament violet, personal coral).
- **The moment "print":** a photo mounted on a paper mat, its caption set in the display italic like a photo-book caption, with the context in small type beneath.
- **The Season hub is drawn as a spine:** a thread down the left, a chapter per month.
- **Celebration is rationed.** There is exactly one animated celebration (the "You're all set" seal). The splash plays the brand reveal (`../brand/huddlie-reveal.json`).

## Rebranding when the final brand arrives

1. **Colours, fonts, type scale, radii:** edit `src/tokens.json`. Keep the token names; change the values. Add the new font URL (or local font files) in `font.googleFontsUrl`.
2. **Logo:** the mark is inlined from `brand/huddlie-mark.svg`. To change its colours, edit PALETTES in `../app/intro.js`, run `node ../brand/build-mark.mjs`, then rebuild here.
3. **Icons:** drop the brand's icons into `src/icons/<slot-name>.svg`. A file there wins over the provisional drawing. Slot names and their uses are listed on `system.html`.
4. **Pattern:** replace `brand/pattern.svg`. The size and opacity are tokens (`--pattern-size`, `--pattern-opacity`).
5. **Imagery:** the photo placeholders are tokens (`photo-a/b/c`). Real app media replaces them; for store screenshots we use the brand's approved imagery.
6. Run `node build.mjs`. Check `index.html` in light and dark.

App icon and store files are generated after that step. See `store/ASSET-SPEC.md`.

## Copy notes for the client

Screen copy is carried over word for word from the prototype, with these exceptions and flags:

- **Welcome** no longer carries the "Benefit 1/2/3" placeholders: the benefits live in the four-page intro that plays before it (prototype).
- **Internal notes shown as UI in the prototype were left out** (for example "An honest limitation at launch", "a rough edge we know about", "Simulate accept", the "Built in Stage 5" stubs) and kept in the screen notes instead.
- **The follower home's footer says "nothing about any other child".** The brand vision reserves "child" for the parent's own layer, so suggest "nothing about anyone else on the team".
- **The get-set-up line** now uses a colon ("worth remembering: add a photo").
- **Tips** (brand v1) reuse prototype copy; "Your account is free, and only the family you invite can see your player's moments" and "Once your player is in, invite the family" are new lines to confirm.
- **Position placeholders name hockey positions.** That's fine for launch, but lasting copy should stay activity-neutral.
- **New copy written for added states is marked provisional** in each screen's notes.
