# Wobbleby Mobile Canary — Design Contract

Status: visual canary, not production billing  
Target: iPhone 17 Pro, 402 × 874 CSS points at 3× capture (1206 × 2622 pixels)  
Screens: welcome, child profile, tracking choices, Pro purchase, Home, First saved/share  
Primary objective: prove one coherent modern Wobbleby system before Nyx generates a broader candidate set.

## 1. Product feeling

Wobbleby should feel joyful, capable, private, and current. It is a confident consumer app for
parents, not a beige baby journal and not a clinical health dashboard.

The interface has four emotional rules:

1. Reassure without diagnosing.
2. Celebrate the child without comparing them to another child.
3. Make the next action obvious without trapping the parent.
4. Use bright color with discipline: saturated fields and accents, true-white reading surfaces,
   and high-contrast ink.

The visual reference category is the product confidence of Cash App, Uber, Airbnb, and Duolingo:
simple type, strong hierarchy, generous rounding, decisive color, and controls that feel native.
The interface must not copy their exact assets or layouts.

## 2. Non-negotiable product rules

- Parent-facing copy never uses `delay`, `behind`, `concern`, or `abnormal`.
- The product is for reassurance, not diagnosis.
- CDC checkpoints are windows based on the CDC 75th-percentile standard, never averages.
- Firsts never show a target age, expected window, comparison, percentile, or judgment.
- An achieved age may appear as historical memory data.
- Photos stay on-device by default.
- Exact trust statement: “Photos are never sent to any AI model.”
- Safety routing, milestone logging, photo capture, and the free experience are never paywalled.
- The Pro screen always exposes a visible close control and “Continue with free.”
- The mascot never appears on medical or CDC checkpoint surfaces.
- This canary simulates purchasing. Production price and trial data must come from RevenueCat.

## 3. Color system

Color is product-owned. These values are a Wobbleby direction, not a global Nyx default.

| Token | Value | Use |
|---|---:|---|
| `--white` | `#FFFFFF` | page canvas, cards, input surfaces |
| `--ink` | `#0A0B0D` | primary text, icon strokes |
| `--muted` | `#596170` | secondary copy only |
| `--soft` | `#F4F5F7` | contained control fills, never a full-screen “cream” |
| `--line` | `#E4E7EC` | dividers and input borders |
| `--blue` | `#2457FF` | product primary, welcome field, selected state |
| `--blue-pressed` | `#153ED1` | pressed primary controls |
| `--orange` | `#FF7300` | celebration and the single hot accent |
| `--yellow` | `#FFD84D` | optimistic supporting field |
| `--green` | `#00A94F` | success and completed states only |
| `--red` | `#D92D20` | destructive/error only |
| `--violet` | `#6D3BFF` | Pro / share-video support, never a second primary |

Rules:

- Full-screen foundations are either true white, vivid blue, or deep ink.
- No cream, beige, dusty blue, sage, pale peach, low-opacity primary, or gray-white page canvas.
- A screen gets one dominant hue and at most two supporting accents.
- Text on blue uses white. Text on yellow or orange uses ink.
- Gray communicates hierarchy, not brand.
- The mascot retains natural charcoal, white, and orange coloring on every screen.
- Color must remain readable at WCAG AA contrast for normal text.

## 4. Typography

### Primary family

`Inter`, loaded as a real web font with the system stack as fallback.

Inter is used for all UI copy. It has the neutral, modern consumer-product tone the target apps
share without turning Wobbleby into a tech dashboard.

### Display family

`Inter Tight` for large editorial headlines only. Its tighter proportions create more character
without introducing a decorative serif or forcing every heading to be extra-bold.

### Data family

`IBM Plex Mono` for ages, time, pricing breakdowns, and capture/render progress only.

### Scale

| Role | Family | Size / line | Weight | Tracking |
|---|---|---:|---:|---:|
| Hero | Inter Tight | 44 / 46 | 750 | `-0.045em` |
| Screen title | Inter Tight | 34 / 38 | 740 | `-0.035em` |
| Section title | Inter | 22 / 28 | 700 | `-0.02em` |
| Card title | Inter | 18 / 23 | 650 | `-0.015em` |
| Body | Inter | 16 / 23 | 450 | `-0.006em` |
| Control | Inter | 16 / 20 | 650 | `-0.012em` |
| Secondary | Inter | 14 / 20 | 450 | `0` |
| Label | Inter | 12 / 16 | 650 | `0.04em` |
| Data | IBM Plex Mono | 12–16 / 18–22 | 500 | `-0.02em` |

Rules:

- Paragraphs are never bold.
- Large headlines may be 740–760; body text stays 400–500.
- Avoid all-caps except tiny status labels.
- Use a maximum of three type sizes inside one card.
- Maintain at least 8px between a title and its supporting copy.

## 5. Shape, space, and depth

### Spacing

Base grid: 4px. Allowed steps: 4, 8, 12, 16, 20, 24, 32, 40, 48.

- Screen horizontal gutter: 20px.
- Major section separation: 28–32px.
- Card internal padding: 16–20px.
- Input row separation: 12px.
- Bottom content clears the home indicator by at least 24px.

### Radius

Radius communicates component type; it is not one repeated factory value.

| Component | Radius |
|---|---:|
| tiny status marker | 8px |
| chip / compact segmented item | 12px |
| input / standard button | 18px |
| content card | 24px |
| media card / bottom sheet | 30–32px |
| avatar / circular icon action | 999px |

No jagged square cards. No ribbon overlays. A rounded card may contain a square media crop only
when the parent clips it.

### Depth

- Default cards use a `1px` line, not a shadow.
- A surface receives a shadow only when it floats above another surface.
- Standard elevation: `0 10px 30px rgba(10, 11, 13, 0.10)`.
- Modal elevation: `0 24px 64px rgba(10, 11, 13, 0.18)`.
- Never stack multiple soft shadows to fake dimensionality.

## 6. Controls and icons

- Google Material Symbols Rounded provide the icon grammar.
- Controls use icons only when the icon is universally understood or paired with text.
- Minimum tap target: 44 × 44px.
- Primary button height: 56px, 18px radius.
- Secondary button height: 52px, 18px radius or text-only when hierarchy requires.
- Primary action uses the dominant screen color. Only one primary action appears in a viewport.
- Disabled controls are visibly disabled and do not respond.
- Pressed states shift 2px down and use a darker fill.
- Selection cards use a 2px blue border, a blue check control, and a subtle white/blue fill.
- Fields use a persistent label and real value. Placeholder text never replaces the label.
- Toggle and plan controls update visually and expose `aria-pressed` or native checked state.

## 7. Mascot system

The mascot is a generated raster asset, not CSS or SVG clip art.

Required construction:

- Minimalist 2D only.
- Flat vector-like shapes.
- No gradients, gloss, volume, bevel, realistic light, or 3D plastic rendering.
- Near-black charcoal head, back, and flippers.
- Pure-white face and belly.
- Vivid orange beak and feet.
- White eye shapes with black pupils and a small flat catchlight.
- Round chick body in a joyful, slightly unstable wobble.

Usage:

- Welcome: hero-scale, approximately 190–220px visual width.
- Profile / preferences: absent; let the task lead.
- Paywall: small supporting appearance only.
- Home: small nudge or empty-state helper, never a decorative watermark.
- First/share: may appear only in the simulated 1.5-second Wobbleby end-card preview.
- Never place the mascot on CDC checkpoint or medical guidance screens.

## 8. Motion

- Screen entry: 280ms, `cubic-bezier(.2,.8,.2,1)`, 12px upward settle.
- Button press: 100ms scale to `0.98`; release at 180ms.
- Selection: 180ms border/fill transition.
- Bottom-sheet purchase surface: 360ms spring-like ease, no bounce loop.
- Share render progress: 1.8s deterministic simulation, then show Save and Share.
- Mascot welcome motion: subtle 3-degree wobble, once every 2.8 seconds; stop when reduced motion is requested.
- No parallax, infinite confetti, automatic carousels, or decorative scroll-jacking.

## 9. Screen contracts

### 9.1 Welcome

Purpose: communicate the product in under five seconds and establish trust.

Composition:

- Vivid blue full-screen field.
- White Wobbleby wordmark at the upper left.
- Compact “Private by default” chip at upper right.
- Mascot sits within a yellow circular field in the upper-middle.
- Hero: “Every little first, kept.”
- Body: “Milestones, daily photos, and the moments between.”
- Primary white button: “Get started.”
- Trust row: lock icon plus “Photos are never sent to any AI model.”
- Footer: “No account required.”

Interaction:

- `Get started` navigates to child profile.
- Trust row is informational.

### 9.2 Child profile

Purpose: collect only what is needed to personalize timing and memory labels.

Composition:

- Back control, progress `1 of 2`.
- Title: “Who are we celebrating?”
- Optional circular photo action with camera badge.
- Name field populated with `Leo` in the canary.
- Birthday field populated with `August 18, 2025`.
- Optional due-date control.
- Explanation: “This helps with early or late arrivals. Feel free to skip it.”
- Primary `Continue` button anchored above the safe area.

Interaction:

- Tapping the avatar toggles a visible “Photo ready” state.
- Name can be edited.
- Continue is disabled if name or birthday is empty.
- Continue navigates to tracking choices.

### 9.3 Tracking choices

Purpose: avoid a large feature questionnaire while configuring the daily quick log.

Composition:

- Back control, progress `2 of 2`.
- Title: “What would help today?”
- Body: “Start with one. Add or stop any time.”
- Exactly three selectable controls: Sleep, Feeds, Diapers.
- Each control has an icon, short one-line value statement, and independent selection state.
- Sleep is selected by default.
- Primary `Finish setup`.
- Secondary `Skip for now`.

Interaction:

- Multi-select is supported.
- At least one option selected enables `Finish setup`.
- `Finish setup` opens the Pro offer.
- `Skip for now` opens Home.

### 9.4 Pro purchase

Purpose: explain the paid artifact and backup value without obscuring the free product.

Composition:

- Saturated blue-to-violet header field with small 2D mascot.
- Close control remains visible.
- Title: “Keep every memory safe.”
- White sheet with four benefit rows:
  - Encrypted cloud backup
  - Share videos without the Wobbleby end card
  - Monthly report and growth charts
  - Multiple children
- Annual plan selected by default:
  - `$80 / year`
  - `$6.67 per month`
  - orange `Save 67%` chip
- Monthly alternative: `$20 / month`.
- Primary: `Start 21-day free trial`.
- Secondary: `Continue with free`.
- Footer: `Restore purchases · Terms · Privacy`.

Interaction:

- Plan controls update selection and primary helper copy.
- Trial CTA shows a local success toast, then opens Home.
- Close and `Continue with free` open Home immediately.
- No payment is charged in the canary.

Data rule:

- The 21-day value follows the newest product direction for this canary.
- `SPEC.md` and `BILLING.md` still contain a 14-day conflict that must be reconciled before ship.
- Production plan pricing and trial duration come from RevenueCat, not literal UI strings.

### 9.5 Home

Purpose: make today’s memory and quick logs available in the first viewport.

Composition:

- `Wobbleby` wordmark and child avatar.
- `Leo · 11m 3d` in mixed UI + mono data type.
- Seven-day memory strip. Completed days use blue; today uses orange.
- Large blue Today card:
  - `TODAY`
  - “One photo makes the day.”
  - white `Add today’s photo` control
- Three compact quick logs in one horizontal row:
  - Sleep — `7h 40m`
  - Feed — `42m ago`
  - Diaper — `2h ago`
- Caregiver attribution appears in supporting text.
- This-week row with `2 new memories`.
- `Log a First` orange action.
- Fixed tabs: Home, Track, Capture, Firsts, Growth.

Interaction:

- Photo button shows a simulated saved state.
- Quick logs update their timestamp and display a confirmation toast.
- `Log a First` opens the celebration screen.
- Tab controls update pressed state; canary routes Home and Firsts.

### 9.6 First saved / share

Purpose: prove that milestone capture becomes a desirable share artifact.

Composition:

- Deep-ink full-screen celebration composition, not a dashboard.
- Back control and `Saved` status.
- Headline: “One for the memory book.”
- Media preview with vivid blue/orange/yellow fields and end-card framing.
- Milestone: `First steps`.
- Historical age in mono: `11m 3d`.
- Format segmented control: `Story 9:16` and `Feed 1:1`.
- Primary orange action: `Make the video`.
- Secondary: `Save without sharing`.
- After render, replace the primary with `Share video` and expose `Save video`.

Interaction:

- Format selection recomposes the preview.
- Render button shows deterministic progress and completion.
- Save shows a confirmation toast.
- Mascot appears only in the Wobbleby end-card portion of the preview.

## 10. Responsive behavior

- The app canvas is designed at 402 × 874 CSS points.
- Content supports widths from 360 to 430 points without scaling the entire interface.
- At 360px, gutters reduce to 16px and quick logs remain three columns with shorter labels.
- At 430px, content remains centered and gutters grow; type does not scale up automatically.
- Dynamic type can enlarge body copy to 120% without clipping the primary path.
- No horizontal page scrolling.
- The browser capture uses device scale factor 3, producing 1206 × 2622 pixel images.

## 11. Evidence and acceptance

The canary passes only if:

- all six routes render at 402 × 874 without overflow;
- captures are 1206 × 2622 pixels;
- Inter, Inter Tight, IBM Plex Mono, and Material Symbols actually finish loading;
- the generated penguin is a real PNG with alpha and is visibly 2D;
- every primary button works;
- plan choice, tracking choice, and format choice visibly change state;
- Home photo and quick-log actions produce feedback;
- the share render reaches a completed state;
- `document.fonts.ready` resolves before screenshots;
- no screen uses cream/off-white as its full canvas;
- no ribbon overlay appears;
- no button, card, and sheet all share one radius;
- screenshots are reviewed as images, not inferred from passing HTML tests.

## 12. What this canary decides

This canary is a quality gate. It does not authorize twenty parallel builds by itself.

If it looks and behaves right, Nyx may treat this contract as a product-specific design artifact,
then generate broader Wobbleby directions or begin the full redesign. If it does not, the team
changes this one system and reruns six captures. It must not spend another large candidate wave
trying to solve an unresolved visual thesis.
