Bouch.ee · Design System v2 · Variante D adoptée

Le carnet de Camille.

Ce document est la spécification de référence pour Claude Code (dev technique). Il liste les tokens design, atomes, composants et leur comportement. Chaque composant est documenté avec ses props, variants et états. Les patterns produits (onboarding, paywall, présence Camille) sont décrits en fin de document.

01 · Principes

Cinq lignes directrices

1. Mobile-first, web second

L'app principale est iOS (consultation, cuisine, courses en magasin). Le web sert 3 cas seulement : la home marketing, l'URL famille publique, l'impression A4. Pas de version desktop pour l'onboarding ni pour le mode cuisine.

2. Camille s'efface

L'IA n'est pas le produit, c'est l'opérateur. Une fois la semaine validée, elle disparaît dans un FAB. Elle revient si on l'appelle. Pas de chat omniprésent, pas de notifications agressives.

3. Papier lumineux, jamais sombre par défaut

Tout part d'un fond #fbf7ee crème. Pas de dark mode v1. Les contrastes sont obtenus par --ink (presque noir) sur --paper. Joyeux, pas saturé.

4. Une seule famille de marque visuelle

Fraunces italique pour les titres et le manuscrit, Inter pour le corps, JetBrains Mono pour les eyebrows et données chiffrées. Caveat pour les notes manuscrites de Camille. Pas d'autre fonte.

5. Tampons & surligneur, pas d'icônes décoratives

Les tampons (rouges/olive/bleu encre) servent à classer (régime, batch, rapide). Le surligneur jaune souligne les mots-clés du discours produit. Les icônes sont fonctionnelles uniquement (line, 1.6px stroke). Pas d'emojis sauf 1-2 dans les messages de Camille (🌿 🥖 🥧).

02 · Tokens

Variables CSS

Tous les tokens vivent dans variant-d/tokens-d.css sous :root. La règle .bouch-d applique le fond, la fonte et le smoothing à tout sous-arbre. Les tweaks runtime (teinte de marque, ton du papier) overrident ces variables via document.documentElement.style.setProperty().

03 · Typographie

Quatre fontes, des rôles clairs

TokenFamilleUsageÉchelle
--font-displayFraunces (variable)Titres H1–H4, valeurs chiffrées en italique (qty, prix, durée)14 → 64px · italique souvent
--font-bodyInterCorps de texte, boutons, labels11 → 18px
--font-monoJetBrains MonoEyebrows, dates, métadonnées, données techniques9 → 12px · letter-spacing 0.06–0.16em · UPPERCASE
--font-scriptCaveatNotes manuscrites de Camille (« le mot du dimanche ») — réservé14 → 19px
Exemples
H1 · Fraunces italic 60/1.04
Quoi manger, cette semaine ?
H2 · Fraunces italic 36
Quatre choses, et c'est tout.
H3 · Fraunces 22 italic
Curry de pois chiches, riz basmati
Body · Inter 14/1.55
Bouch.ee est un assistant cuisine pour votre famille. Il connaît qui mange chez vous, propose chaque semaine vos prochains menus.
Eyebrow · JetBrains Mono 11 / 0.16em / UPPER
Foyer Bouvier · 4 personnes
Manuscrit Camille · Caveat 17 · ink-blue
Léa va adorer le curry de mardi.
04 · Couleurs

Palette papier

Surfaces

--paper
#fbf7ee · fond global
--paper-warm
#f5efde · sections alt, eyebrows
--paper-card
#ffffff · cards, bulles AI
--line
#e0d5b8 · bordures cards

Encres (texte)

--ink
#1f1a14 · titres, body
--ink-soft
#443c2f · paragraphes
--ink-faint
#7d7361 · meta, eyebrows
--ink-ghost
#b9b09a · placeholders

Accents

--brand
#c87a3c · ambre chaleureux
--brand-deep
#9a5a26 · titres alt
--stamp
#b23029 · tampon rouge, today
--olive
#5a6b3d · végé, success
--ink-blue
#1f3d5e · script, sans lactose

Règle d'usage des accents

  • --stamp = signal critique (today, action, alerte) + tampon "rouge"
  • --olive = succès, validation, tag végétarien
  • --ink-blue = signature manuscrite Camille + tag sans lactose
  • --brand / --brand-deep = highlight discret de marque (ambre), titres italiques alt, jamais comme signal
  • --highlight = surligneur jaune uniquement sur les mots-clés du discours (ex. "vos prochains menus")
05 · Espace, rayons, ombres

Système 4-base

Spacing

TokenPxUsage
--s-14gap interne icônes
--s-28gap entre éléments inline
--s-312padding cards compactes
--s-416padding card standard
--s-524padding écran mobile L/R
--s-632séparation sections
--s-748section hero
--s-864marge desktop large

Rayons

TokenPxUsage
--r-xs4tampons, checkboxes papier
--r-sm8thumbnails, inputs interne
--r-md12cards principales
--r-lg18card hero pricing
--r-pill999boutons primary, chips, FAB

Ombres

--shadow-card · cards, meal cards
--shadow-pop · FAB, pricing, modaux
06 · Atoms

Briques de base

DLogo

Bouch.ee Bouch.ee

Props

  • size: number · default 22 · taille en px du nom

Comportement

  • .ee est toujours en --stamp
  • Italique Fraunces, font-weight 500

DStamp · tampons sémantiques

végé batch cooking sans lactose rapide

Props

  • variant: "red" | "olive" | "blue" · default "red"
  • tilt: bool · rotation -1.5° style tampon de marché

Mapping sémantique

  • red → today, action, signal · "rapide", "amis"
  • olive → végé, success, batch · "végé"
  • blue → calme, sans lactose · "s. lactose"

DCamilleAvatar

C C P

Props

  • size: number · default 32
  • name: string · default "Camille" — la première lettre s'affiche
  • glow: bool · halo ambré, à utiliser pour la première rencontre, mode actif

Critique

  • Le prénom est tweakable (cf. §Tweaks). L'avatar doit s'adapter.
  • Gradient ambre fixe : #f6c879 → #c87a3c → #9a5a26

Boutons

Hiérarchie

  • Primary (ink) · background: --ink, color: --paper · 1 par écran max
  • Ghost · border: --line-strong, color: --ink-soft · actions secondaires
  • Text · color: --brand-deep, weight: 600 · liens d'affinage, footer

Forme

  • Rayon = --r-pill sur tous les boutons (cohérence)
  • Padding 13–15px V · 22px H
  • Font 14–15px weight 600

DVoiceWave

Props

  • active: bool · default false
  • size: number · hauteur en px, default 28

Règle critique

  • L'animation ne se joue que si active est true (l'utilisateur parle vraiment).
  • État idle = traits gris discrets, immobiles.
  • Active = traits rouges (--stamp), oscillation 1.1s.

DBubble · message chat

On est 4 à la maison, Léa est végé.
Bien sûr 🌿. Voilà ta semaine 👇

Props

  • from: "user" | "assistant" · default "assistant"
  • animateIn: bool · animation d'entrée (translate Y + fade)
  • name: string · prénom de l'IA pour l'avatar (assistant uniquement)

Style

  • User : --ink bg, paper text, radius asymétrique 16/16/4/16
  • AI : --paper-card bg, ink text, border --line, radius 16/16/16/4
  • Max-width 88%, font 14–15px line-height 1.45

Surligneur · .dhighlight

Bouch.ee propose chaque semaine vos prochains menus sur mesure.

Usage

  • Linear-gradient bas 55–92% en rgba(244,211,94,0.55)
  • Réservé au discours produit (homepage, paywall, "le mot de Camille"). 1× par paragraphe max.
07 · Composants

Briques produit

MealCard (mobile)

Mardi 22 aujourd'hui
Curry de pois chiches, riz basmati
⏱ 30 min végé batch

Props

  • meal: { id, day, date, title, photo, time, badges[] }
  • delay: number · pour stagger l'animation d'entrée

États

  • default — bordure --line
  • today — bordure gauche 3px --stamp + label rouge + script "aujourd'hui"
  • past — opacity 0.6, photo en niveaux de gris (à implémenter)
  • swap-loading — skeleton shimmer pendant que Camille remplace le plat

Variant desktop (W4)

  • Même structure verticale (photo top, texte bottom). 7 cards en grid auto-fit. Rotation -0.3°/+0.3° pour effet papier.

ShoppingItemRow

300g Riz basmati
1 botte Coriandre fraîche Tom · sans lactose ✓

Props

  • qty: string · "300g", "1 botte", "—" si non chiffré
  • item: string
  • checked: bool
  • note?: string · note famille (ex. "Tom · sans lactose ✓")

Comportement

  • Tap sur la row toggle checked
  • Checked → opacity 0.45, line-through, checkbox --olive
  • Bordure tirets 1px dashed --line-soft (effet liste papier)

Inline Action Card (dans le chat)

Suggestion
Pâtes au pesto, courgettes, noisettes torréfiées

Variants

  • Suggestion · plat ou tweak proposé par Camille — Adopter / Autre idée / Affiner
  • Recipe peek · mini photo + titre + temps · Voir détail
  • Week summary · 7 photos rondes en grid + stats
  • Timer · cercle SVG + temps restant + pause/play
  • Course · n produits + budget · Voir liste

Layout

  • Indenté de 38px (alignement avec bulle AI)
  • Max-width 84–92% du conteneur
  • Animation dfade 0.35s à l'apparition

DCamilleFAB

Position

  • Sticky position: absolute, right: 16, bottom: 86 (au-dessus du tab bar)

Comportement

  • Tap → ouvre le bottom-sheet M7 (modal Camille)
  • Affiché uniquement sur l'écran "Cette semaine" (M2). Tweakable on/off.
  • S'efface (translate-y) quand l'utilisateur scrolle vers le bas, revient au scroll up.

DTabBar (4 onglets)

Props

  • active: "home" | "list" | "fam" | "set"

Comportement

  • Active : color --stamp, weight 600, stroke 1.9
  • Inactive : color --ink-faint, stroke 1.5
  • Safe-area iOS : padding bottom 22px

Chat Composer

Anatomie

  • Pill rounded, border --line-strong, bg --paper-card
  • Input à gauche · Mic au milieu (32px) · Send à droite (36px ink)
  • Mic ouvre le mode vocal (DVoiceWave actif)
08 · Patterns produits

Comportements transverses

Onboarding · 6 étapes

ÉtapeObjectifComposantValidation
1/6 BienvenuePitch en 2 phrases · "2 min" · CTA CommencerD_Onb1_Welcome
2/6 VousPrénom de l'utilisateurD_Onb2_YouChamp requis
3/6 Nommer l'IA ⭐Choisir le prénom de l'assistant — moment d'adoption critiqueD_Onb3_NameIASuggestions cliquables (Camille, Paul, Joséphine, Jacques…) + champ libre
4/6 FoyerMembres + régimes/allergiesD_Onb4_Foyer≥ 1 membre
5/6 Goûts (chat)Conversation libre avec l'IA fraichement nommée — ce qu'on aime, ce qu'on fuitD_Onb5_Tastes≥ 2 messages échangés
6/6 Voilà ta semaineGénération + reveal de la 1ère semaineD_Onb6_Done

Présence de Camille

3 niveaux d'intensité

  • Whisper — bandeau discret en haut de M2 ("Le mot de Camille")
  • FAB — bouton flottant "Parler à Camille" sur M2 uniquement
  • Modal plein — bottom-sheet 78% écran (M7) sur tap FAB

Ce qu'on évite

  • Pas de notif push non-sollicitée
  • Pas de tooltips qui poussent vers le chat
  • Pas de chatbot toujours visible (Camille s'efface)
  • Pas de voice wave animée en idle

URL famille publique

Une URL canonique bouch.ee/foyer-{slug} est partageable sans compte. Les invités peuvent voir + commenter mais pas modifier. Banner "Vue partagée par {prénom}" en haut. CTA discret "Découvrir Bouch.ee" en haut à droite.

  • Vues : W2 (desktop), M10 (mobile)
  • Pas d'authentification — comments en tant qu'invité avec prénom + emoji avatar
  • Toggle on/off depuis M6 (page famille du propriétaire)

Paywall · jour 7

L'écran M11 s'affiche au lancement de l'app le 7e jour. Pas avant. Pas de fenêtres modales pendant les 6 jours d'essai.

  • Hook émotionnel : "On a passé une belle semaine ensemble"
  • Proof : 3 stats personnalisées (plats faits, € économisés, préférences capturées)
  • Single offer : 5 €/mois, pas de plans multiples, pas de réduction artificielle
  • Sortie honorable : "Non merci, je supprime mon compte" en lien souligné, mêmes données exportables

Impression A4

La liste de courses doit pouvoir s'imprimer telle quelle pour les seniors / le frigo. Format 794×1123. Lignes horizontales discrètes (effet papier ligné). Tampon "32 produits · ≈ 84 €" en haut à droite, rotation -6°. Notes manuscrites Camille en bas en Caveat.

09 · Système de Tweaks

Variables modifiables à chaud

Le panneau Tweaks (toggle dans la barre du host) expose les variables suivantes. Modifications persistées via __edit_mode_set_keys dans le bloc EDITMODE-BEGIN/END de index-d.html.

CléTypeDefaultEffet
botNamestring"Camille"Renomme l'IA partout (avatar initial, FAB, header chat, dialogues onboarding)
brandHue0–36028Ré-écrit --brand/--brand-deep en oklch
paperTone"warm" | "cool" | "white""warm"Change le fond papier (3 nuances)
showFABbooltrueAffiche/masque le FAB Camille sur M2
showStampsbooltrueCache tous les .dstamp (test densité visuelle)
italicTitlesbooltrueDésactive l'italique Fraunces sur titres
10 · Stack & fichiers

Pour Claude Code

FichierRôleLignes
tokens-d.cssVariables CSS (couleurs, type, spacing, ombres) + classes utilitaires (.dstamp, .dscript, .dhighlight, .dwave)~110
components-d.jsxAtoms : DIcon, DLogo, DCamilleAvatar, DStamp, DBubble, DVoiceWave, DPhone, DTabBar, DCamilleFAB + données mock D_PHOTOS, D_WEEK~210
onboarding-d.jsx6 écrans onboarding (D_Onb1_Welcome → D_Onb6_Done) + OnbShell~410
screens-mobile-d.jsx8 écrans mobile principaux (M1–M8)~915
screens-desktop-d.jsxHomepage W1 + Famille publique W2 + Liste imprimable W3 + HomepageChat + DNameRoll~525
screens-extra-d.jsxM9 mobile homepage + M10 mobile famille + M11 paywall + W4 desktop semaine~430
index-d.htmlShell + DesignCanvas + TweaksPanel~140

Conventions React (à respecter pour la prod)

  • Tous les composants partagés sont préfixés D (Camille avatar, Bubble, etc.)
  • Tous les écrans sont préfixés D_M{n}, D_W{n}, D_Onb{n}
  • Données mockées dans D_WEEK (7 plats) et D_PHOTOS (URLs Unsplash). À remplacer par appels API réels en prod.
  • Aucun routing en l'état — chaque écran est un artboard indépendant. Le routing produit (Stack iOS) est à créer côté natif.
  • Le prénom de l'IA (name) descend en prop dans tous les écrans depuis l'App. Toujours le passer en prop, jamais hardcoder "Camille".

À implémenter côté backend (hors design)

  • à faire Génération de la semaine via LLM (input : foyer + contraintes + budget + magasins, output : 7 plats avec photos)
  • à faire Liste de courses agrégée à partir des recettes (regroupement, tri par magasin)
  • à faire Mode vocal · Whisper/STT pour la dictée + TTS pour les recettes
  • à faire URL famille publique · slug unique, lecture seule, comments en tant qu'invité
  • à faire Paywall jour 7 · Stripe direct, pas d'IAP Apple
  • design ok Tous les écrans listés ci-dessus, statiques