# Hello Ted — Design System

**Hello Ted** is a mobile running-coaching app: *« application mobile de coaching running qui s'adapte vraiment à ta vie et tes objectifs »*. The product's differentiator is Ted himself — a pixel-art coach who talks to you, notices when life gets in the way, and rewrites your plan instead of guilt-tripping you.

The brand is **pixel art**: everything is built on a 4px grid, corners are square, shadows are hard offsets, and the illustration set is a sprite of Ted in seven moods. The palette is loud (orange + green on cream) and the type is monospaced, so the interface reads like a friendly game HUD rather than a fitness dashboard.

Language: **French, tutoiement.** Every string in this system is written in French.

## Sources given

| Source | Used for |
| --- | --- |
| `uploads/Logo (1).svg`, `uploads/Logo - fond foncé.svg` | The real lockups → `assets/logo.svg` (ink wordmark, transparent) and `assets/logo-on-dark.svg` (cream wordmark on its own ink plate). Supersede the earlier PDF exports. |
| `uploads/Picto (2).svg`, `uploads/Picto (1).svg`, `uploads/Picto.png` | The pixel "T" mark → `assets/picto.svg` (transparent, trimmed) and `assets/picto-on-cream.svg` (with its cream plate). |
| `uploads/ted_*.png` (7) | Ted sprites → `assets/ted/ted-<mood>.png`. |
| `uploads/1.png` | Social post reference → `assets/brand/social-post-example.png`. |
| Written charte graphique (chat) | Colours, fonts, "pixel art" direction. |
| https://github.com/halfmage/pixelarticons | Icon set. 50 glyphs copied to `assets/icons/` (MIT). |

No codebase, Figma file, or product screenshots were provided. There is no shipped-UI ground truth, so `ui_kits/app/` applies the foundations rather than recreating existing screens.

## CONTENT FUNDAMENTALS

**Who speaks.** Two voices, never blurred:

- **Ted** — first person, *tu*, warm and unbothered. He speaks only inside `TedBubble`, in the dialogue font, 1–2 sentences: « Compris, je gère. On garde le cap ! », « Pas grave, ça arrive. On décale à demain matin ? », « Encore 200 m à cette allure. Tu tiens, je le vois. »
- **The interface** — impersonal and short. Labels are nouns, not sentences: `Distance`, `Volume de la semaine`, `Séance du jour`. Buttons are imperative verbs: `Démarrer la séance`, `Terminer`, `Enregistrer`.

**Tone.** Encouraging without cheerleading. The brand's core promise is that missing a session is normal, so copy never scolds and never uses streak-loss threats. Ted's answer to "je ne peux pas" is a plan change, not a lecture. The supplied social post is the model: the user says *« Désolé Ted, je vais devoir décaler ma séance de running. »* and Ted answers *« Compris, Je gère. On garde le cap ! »*

**Casing.** Mono labels and button text are UPPERCASE with 0.08em tracking. Headings and body are sentence case. Never title case (it doesn't exist in French anyway).

**Numbers.** French conventions: decimal comma (`10,4 km`), space before units, 24-hour clock, pace as `4:35 /km`, durations as `1 h 25`. Distances to one decimal, pace never rounded.

**Length.** Card titles ≤ 3 words. Ted's lines ≤ 120 characters. Helper copy one sentence. If a screen needs a paragraph, it belongs in Ted's voice instead.

**Emoji: no.** The pixel icon set and Ted's expressions carry all the affect. The only "emoji-like" marks are the sprite's own pixel effects (💤-style Z's, sparkles) which are baked into the artwork.

**Words we use / avoid.** Use: séance, plan, allure, volume, sortie longue, fractionné, repos, série (streak), objectif. Avoid: workout, run (as a noun), performance, "brûler des calories", anything body-composition related.

## VISUAL FOUNDATIONS

**Logo backgrounds.** Cream, white or ink only. **Never on orange** — the picto contains orange pixels and loses its edges.

**Colour.** Four primaries — orange `#e94e1c` (the loud one: primary CTAs, effort, records), green `#18c647` (done, go, progress), ink `#252525` (every outline, all text), cream `#fefce8` (the page — never pure white; white `#ffffff` is only a card/field fill). Three secondaries — yellow `#faca03`, lime `#9fde05`, amber `#fa8c01` — exist mainly to complete the **effort ramp** green → lime → yellow → amber → orange, which is the system's only gradient-like device (and it's stepped, not blended). There is **no red**: errors and destructive states use orange. Ted's own colours (navy hoodie, sky disc, lavender bubble shadow, indigo social bands) are character colours and never used for UI chrome. One coloured surface per screen; everything else is cream, white or ink.

**Type.** Space Mono Bold for titles and metrics, Space Mono Regular for subtitles, DM Sans for body, Megapixel for Ted's dialogue, Gliker for loud "fun" headlines (social, celebration). Display sizes are tracked in at −0.02em; mono labels are tracked out at +0.08em and uppercased. Metrics are always mono — a number in DM Sans is a bug.

**Spacing.** 4px grid, no exceptions. Screen gutter 20px, card padding 16px, stack gap 16px, tile gap 8px. Touch targets 44px minimum; controls are 36 / 44 / 56px tall.

**Backgrounds.** Flat cream. No gradients, no textures, no patterns, no blur, no glass. Full-bleed photography exists only in social/marketing (see the reference post), where it is paired with indigo `#201351` text bands and an orange bottom band; in-app there is no photography at all.

**Borders and corners.** Everything is outlined in ink: 2px on cards, fields and badges; 3px on buttons; 4px on modals and speech bubbles. Radius is **0** everywhere. The only round things in the whole system are Ted's avatar disc and the `--radius-pill` escape hatch (used almost never).

**Shadows.** Hard offsets only, colour = ink, no blur, no spread: 2px / 4px / 6px. Speech bubbles use the lavender `--shadow-dialogue`. There are no inner shadows and no elevation scale beyond those three steps — a "higher" element gets a thicker border, not a softer shadow.

**Animation.** Stepped, like sprite frames: `steps(2)` / `steps(4)` easing for state changes and progress fills, 80–220ms. No fades on entry, no springs, no parallax. Progress fills snap to 5% increments so the bar always lands on the grid.

**Hover.** Fill darkens one step (`--orange-600`); the shadow does not grow. **Press.** The element translates 2px down-right and its shadow collapses to 0 — it physically falls into its own shadow. **Focus.** 3px dashed orange outline, 3px offset. **Disabled.** 40% opacity, no shadow change.

**Cards.** White or cream fill, 2px ink border, square corners, 4px ink shadow, 16px padding. Coloured cards (orange/green/ink) are for the single most important block on a screen.

**Transparency and blur.** Only one use: the dialog scrim, ink at 55%. Never `backdrop-filter`.

**Layout.** Mobile-first, single column, 390px design width. Fixed elements: 44px status bar at top, `TabBar` pinned to the bottom with a 4px ink top rule. Live-session takeover screens drop the tab bar and invert to ink.

**Imagery vibe.** Warm, saturated, everyday-life photography for social (kids shouting, kitchen, running kit) — never studio athletics. In-app imagery is pixel art only, rendered with `image-rendering: pixelated` and sized in multiples of the sprite's pixel so it never blurs.

## ICONOGRAPHY

- The icon set is **[pixelarticons](https://github.com/halfmage/pixelarticons)** (MIT). 50 glyphs used across the kit are copied into `assets/icons/` as 24×24 SVGs with `fill="#000"` (swapped to `currentColor` when inlined by the `Icon` component, so a plain `<img src>` also renders correctly).
- One weight, one style: filled pixel blocks on a 24px grid. Never restyle to strokes, never add rounding, never scale to non-multiples of 4 (16 / 20 / 24 / 32 / 48 are the sanctioned sizes).
- Rendered through the `Icon` component, which fetches the SVG and inlines it so the glyph inherits `currentColor`. Set `window.HELLO_TED_ICON_BASE` once per page so the URLs resolve. (CSS `mask-image` is not reliable across the renderers this system is previewed in — inline SVG or a plain `<img>` are the two supported paths.)
- If a needed glyph is missing from the copied subset, take it from the upstream repo (`svg/<name>.svg`) rather than drawing one. Hand-rolled SVG icons are not allowed in this brand — the pixel grid is the whole point.
- Emoji are never used as icons. Unicode symbols are limited to `·` as a separator and `×` in interval notation (`6 × 400 m`).
- Ted's sprites are illustration, not iconography: they carry emotion, icons carry function.

## Typography — fonts and substitutions

| Role | Specified | Status |
| --- | --- | --- |
| Titles | Space Mono **Bold** | ✅ Google Fonts |
| Subtitles | Space Mono Regular | ✅ Google Fonts |
| Body | DM Sans | ✅ Google Fonts |
| Ted's dialogue | **Megapixel** | ⚠️ **Substituted with Silkscreen** — font files needed |
| Fun / display | **Gliker** | ⚠️ **Substituted with Baloo 2** — font files needed |

Fonts load from the Google Fonts CDN in `tokens/fonts.css`. Send the Megapixel and Gliker `.woff2`/`.otf` files and they will be self-hosted with real `@font-face` rules, replacing the two stand-ins.

## Components

Reusable primitives, grouped by concern. Each directory has `<Name>.jsx`, `<Name>.d.ts`, `<Name>.prompt.md` and one `@dsCard` demo page.

- `components/core/` — **Icon**, **Button**, **IconButton**, **Card**, **Badge**, **Tag**
- `components/forms/` — **Input**, **Select**, **Checkbox**, **Switch**, **SegmentedControl**
- `components/data/` — **StatTile**, **ProgressBar**, **EffortMeter**
- `components/navigation/` — **TabBar**, **ListRow**
- `components/feedback/` — **Dialog**
- `components/ted/` — **TedAvatar**, **TedBubble**
- `components/brand/` — **Logo**

### Intentional additions

No component library was supplied, so this is an authored standard set sized to the app. Three additions are brand-specific rather than generic: **EffortMeter** (the effort ramp needs a home), **TedAvatar** / **TedBubble** (Ted is a first-class UI element, not decoration), and **Logo** (the lockup is live type, so it has to be a component — see below).

### Logo

All marks are the client's supplied SVG artwork, trimmed to their ink bounding box — nothing is redrawn or re-set in live type. `Logo` simply renders the right file at the right aspect ratio: `lockup` (ink wordmark, for cream/light), `lockup-cream` (cream wordmark, transparent, for ink surfaces — the dark file with its plate removed), `lockup-dark` (the supplied dark-plate version — don't place it on another colour), `picto` (mark alone). `assets/picto-on-cream.svg` is the picto with its own cream plate.

## Index

| Path | What |
| --- | --- |
| `styles.css` | Global entry — imports every token file. Consumers link this. |
| `tokens/fonts.css` | Font families + CDN import, substitution notes. |
| `tokens/colors.css` | Palette, ramps, semantic aliases. |
| `tokens/typography.css` | Sizes, leading, tracking, composite type roles. |
| `tokens/spacing.css` | 4px scale, gutters, control heights. |
| `tokens/shape.css` | Borders, radii (0), pixel shadows, focus ring. |
| `tokens/motion.css` | Stepped easings, durations, press offset. |
| `tokens/base.css` | Element defaults (body, headings, links, selection). |
| `guidelines/*.card.html` | 21 foundation specimen cards (Colors, Type, Spacing, Shape, Brand). |
| `components/<group>/` | Reusable primitives + their demo cards. |
| `ui_kits/app/` | Mobile app kit — 5 screens, click-through `index.html`. See its README. |
| `assets/logo.svg`, `assets/logo-cream.svg`, `assets/logo-on-dark.svg` | Lockups: ink, cream (transparent), and the supplied dark-plate version. |
| `assets/picto.svg`, `assets/picto-on-cream.svg`, `assets/picto.png` | The pixel "T" mark. |
| `assets/ted/` | Ted sprites: neutre, content, fier, coach, compatissant, malicieux, fatigue. |
| `assets/icons/` | 50 pixelarticons glyphs. |
| `assets/brand/social-post-example.png` | Supplied social reference. |
| `thumbnail.html` | Homepage tile. |
| `SKILL.md` | Agent-Skills entry point for use outside this project. |
