{ "name": "Widoo", "version": 37, "meta": { "source": "wiki Inprogress-Agency/widoo-app, Direction-Artistique et Design-Changelog D-003 à D-076", "updated": "2026-09-29", "ticket": "https://github.com/Inprogress-Agency/widoo-app/issues/81", "themes": "light validé ; dark = proposition non validée (thème sombre après le MVP)" }, "color": { "themes": [ { "id": "light", "name": "Clair" }, { "id": "dark", "name": "Sombre (proposition)" } ], "tokens": [ { "name": "bg", "value": { "light": "#FFFFFF", "dark": "#111318" }, "usage": "Fond de tous les écrans, des sheets, de la fiche et de la barre d'onglets. Blanc pur (D-003)." }, { "name": "surface", "value": { "light": "#F6F5F1", "dark": "#1B1D23" }, "usage": "Gris chaud : cards, disques de boutons, tuiles, encarts, champ de recherche dans la sheet, chips au repos dans la sheet, bouton secondaire « Programmer »." }, { "name": "surface-strong", "value": { "light": "#14171F", "dark": "#2C3039" }, "usage": "Seule surface sombre, réservée à : chip active, onglet actif, tooltip de la carte, bouton et pastille Premium, pastille « Fin du parcours », toast (D-025), page immersive du parcours en cours et mini-lecteur (E-07, D-029), segment actif de l'onglet Parcours (E-08, D-035). Rien d'autre." }, { "name": "ink", "value": { "light": "#14171F", "dark": "#F2F1ED" }, "usage": "Texte principal, icônes, titres, chiffres." }, { "name": "muted", "value": { "light": "#5F6B80", "dark": "#A1A9B8" }, "usage": "Texte secondaire : sous-titres, métadonnées, libellés de tuile, lignes d'état discrètes, icônes secondaires. 5,38:1 sur bg, 4,93:1 sur surface." }, { "name": "on-strong", "value": { "light": "#FFFFFF", "dark": "#FFFFFF" }, "usage": "Texte et icônes posés sur surface-strong, blue (clair), une famille d'activité ou une photo voilée." }, { "name": "on-strong-muted", "value": { "light": "#D5D8E0", "dark": "#C9CDD6" }, "usage": "Texte secondaire sur surface-strong (ligne d'étape ou « 4 étapes en 7 h » dans la tooltip)." }, { "name": "line", "value": { "light": "#ECEBE7", "dark": "#2A2D34" }, "usage": "Filets : bord haut des barres collées, séparateurs de listes et d'avis. Décoratif." }, { "name": "handle", "value": { "light": "#D9DCE3", "dark": "#3B3F49" }, "usage": "Poignée des sheets. Décoratif." }, { "name": "skeleton", "value": { "light": "#E8E7E2", "dark": "#2A2C32" }, "usage": "Squelettes de chargement, fond du bouton désactivé « Aucun parcours »." }, { "name": "rail", "value": { "light": "#D0D4DC", "dark": "#454A55" }, "usage": "Pointillés de la timeline entre les étapes. Décoratif." }, { "name": "control-border", "value": { "light": "#7F8A9C", "dark": "#8E97A8" }, "usage": "Contour d'un radio ou d'une case non cochés (D-007 : #C3C8D3 échouait à 3:1) ; étoiles non choisies de la note, en contour (E-15, D-034)." }, { "name": "control-border-disabled", "value": { "light": "#C3C8D3", "dark": "#4B505B" }, "usage": "Contour d'un contrôle désactivé (tri par distance sans position). Composant inactif, hors exigence." }, { "name": "scrim", "value": { "light": "rgba(20, 23, 31, 0.40)", "dark": "rgba(0, 0, 0, 0.55)" }, "usage": "Voile sous une sheet modale (filtres, tri)." }, { "name": "photo-shade", "value": { "light": "rgba(20, 23, 31, 0.45)", "dark": "rgba(20, 23, 31, 0.45)" }, "usage": "Haut du dégradé posé sur la photo de la fiche, pour la barre d'état blanche." }, { "name": "photo-veil", "value": { "light": "rgba(20, 23, 31, 0.62)", "dark": "rgba(20, 23, 31, 0.62)" }, "usage": "Fond du compteur de photos « 1 / 6 » (blanc dessus : 5,03:1 au pire cas)." }, { "name": "blue", "value": { "light": "#4E74C8", "dark": "#7C9BE0" }, "usage": "Action principale : boutons pleins (« C'est parti », « Voir N parcours »), liens sur bg, marqueur sélectionné, tracé du parcours, compteur de filtres, « Voir tout », anneaux de chargement. 4,51:1 sur bg ; jamais en texte sur surface (4,1:1)." }, { "name": "on-blue", "value": { "light": "#FFFFFF", "dark": "#0F1115" }, "usage": "Texte et icônes sur blue." }, { "name": "blue-on-strong", "value": { "light": "#5A7FCF", "dark": "#8FA9E3" }, "usage": "Icône pleine de l'onglet actif, sur surface-strong. Aussi le bleu du logo : fond de l'icône d'app et de l'écran de lancement (E-18, D-060). Jamais derrière un texte blanc : 3,91:1 (la page Premium garde blue, choix d'Ilan, D-060)." }, { "name": "blue-ink", "value": { "light": "#3A4FA8", "dark": "#A9BEEE" }, "usage": "Texte bleu sur surface ou blue-soft : lien « Activer », « Voir le profil », suggestions « +12 », texte de la pastille Signature, initiale d'avatar (D-007)." }, { "name": "blue-soft", "value": { "light": "#E4ECFA", "dark": "#25324F" }, "usage": "Fond d'avatar, fond de la pastille Signature (translucide sur photo)." }, { "name": "badge-signature-bg", "value": { "light": "rgba(228, 236, 250, 0.86)", "dark": "rgba(37, 50, 79, 0.94)" }, "usage": "Pastille Signature posée sur photo (parcours de l'équipe Widoo, D-014). Contraste mesuré sur le fond de pastille (règle D-007) : 6,17:1 ; 4,49:1 au pire cas sur une photo noire." }, { "name": "green-soft", "value": { "light": "#E3F3EC", "dark": "#17362B" }, "usage": "Fond de la chip Nature et de la pastille Vérifié." }, { "name": "green-ink", "value": { "light": "#1F6B52", "dark": "#8FD9BD" }, "usage": "Texte vert : « Vérifié », « Ouvert », « Vérifié par N visiteurs », chip Nature. 6,40:1 sur bg." }, { "name": "badge-verified-bg", "value": { "light": "rgba(227, 243, 236, 0.86)", "dark": "rgba(23, 54, 43, 0.86)" }, "usage": "Pastille Vérifié posée sur photo. Contraste mesuré sur le fond de pastille (règle D-007) : 5,57:1 ; 4,05:1 au pire cas sur une photo noire." }, { "name": "coral", "value": { "light": "#F2592A", "dark": "#FF7A4D" }, "usage": "Cœur du favori actif (3,37:1, composant)." }, { "name": "coral-soft", "value": { "light": "#FFE4D9", "dark": "#3B2218" }, "usage": "Fond de la chip Gastronomie." }, { "name": "coral-ink", "value": { "light": "#A63D12", "dark": "#FFB08F" }, "usage": "Texte de la chip Gastronomie." }, { "name": "amber", "value": { "light": "#F5B301", "dark": "#F5B301" }, "usage": "Étoiles de note, soleil de la météo, couronne Premium. Icône seulement, jamais du texte (1,85:1 sur bg)." }, { "name": "alert", "value": { "light": "#8C5A00", "dark": "#F2C14E" }, "usage": "Alerte « lieu signalé » : texte, icône triangle, point « ! » sur la pastille d'étape (fiche et parcours en cours). 5,87:1 sur bg (D-014, D-033)." }, { "name": "alert-soft", "value": { "light": "#FFF4D6", "dark": "#3A2E10" }, "usage": "Encadré d'alerte en tête d'une étape signalée (fiche) et alerte d'étape de E-07, lieu signalé ou bientôt fermé (alert dessus : 5,36:1, D-033)." }, { "name": "error-ink", "value": { "light": "#B42318", "dark": "#FF9B8E" }, "usage": "Rouge du refus : texte et icône de la pastille « Refusé » (parcours refusé par la modération, onglet Parcours). 5,75:1 sur error-soft, 6,57:1 sur bg (D-038). Jamais pour une alerte de lieu (alert). Erreur sous un champ (E-19 : texte, `warning-circle` plein et bord de 2 px du champ, D-062)." }, { "name": "error-soft", "value": { "light": "#FDECEA", "dark": "#3B1D1A" }, "usage": "Fond de la pastille « Refusé » (D-038)." }, { "name": "plum-soft", "value": { "light": "#F3E4EC", "dark": "#3A1F2B" }, "usage": "Fond de la chip Culture." }, { "name": "plum-ink", "value": { "light": "#7A2A4A", "dark": "#E8A9C2" }, "usage": "Texte de la chip Culture, point d'ambiance Culture." }, { "name": "violet-soft", "value": { "light": "#ECE7F8", "dark": "#2C2648" }, "usage": "Fond de la chip Shopping (D-010)." }, { "name": "violet-ink", "value": { "light": "#5A3FA8", "dark": "#C5B8F0" }, "usage": "Texte de la chip Shopping (6,40:1 sur violet-soft)." }, { "name": "family-food", "value": { "light": "#F2592A", "dark": "#F2592A" }, "usage": "Famille Gastronomie : restaurant, café, bar, boulangerie. Pastille d'étape et marqueur (icône blanche 3,37:1)." }, { "name": "family-culture", "value": { "light": "#7A2A4A", "dark": "#7A2A4A" }, "usage": "Famille Culture : musée, galerie, monument." }, { "name": "family-nature", "value": { "light": "#2A8A62", "dark": "#2A8A62" }, "usage": "Famille Nature : parc, point de vue, balade. Aussi point d'ambiance Nature (D-016, remplace #4FA88B)." }, { "name": "family-shop", "value": { "light": "#5A3FA8", "dark": "#5A3FA8" }, "usage": "Famille Shopping : boutique." }, { "name": "family-leisure", "value": { "light": "#128A87", "dark": "#128A87" }, "usage": "Famille Loisirs : activité, spectacle." }, { "name": "family-other", "value": { "light": "#5F6B80", "dark": "#5F6B80" }, "usage": "Famille Autre : tout lieu hors des familles." }, { "name": "mood-romantic", "value": { "light": "#D0405F", "dark": "#E0607A" }, "usage": "Point d'ambiance Romantique (4,58:1 sur bg, 4,20:1 sur surface)." }, { "name": "mood-unusual", "value": { "light": "#9A3FC0", "dark": "#B77EE0" }, "usage": "Point d'ambiance Insolite (5,46:1 sur bg, 5,00:1 sur surface)." }, { "name": "mood-instagrammable", "value": { "light": "#BC3797", "dark": "#D867B4" }, "usage": "Point d'ambiance Instagrammable (5,08:1 sur bg, 4,66:1 sur surface)." }, { "name": "mood-relax", "value": { "light": "#1F87B5", "dark": "#4FA7D6" }, "usage": "Point d'ambiance Détente (4,05:1 sur bg, 3,71:1 sur surface)." }, { "name": "mood-sport", "value": { "light": "#5E8F12", "dark": "#86B93A" }, "usage": "Point d'ambiance Sportif (3,88:1 sur bg, 3,56:1 sur surface)." }, { "name": "mood-romantic-soft", "value": { "light": "#F9E6EA", "dark": "#4C2332" }, "usage": "Fond de la chip Romantique (D-050)." }, { "name": "mood-romantic-ink", "value": { "light": "#9A2F46", "dark": "#E4768D" }, "usage": "Texte et icône de la chip Romantique (6,11:1 sur mood-romantic-soft, D-050)." }, { "name": "mood-unusual-soft", "value": { "light": "#F2E6F7", "dark": "#3C234F" }, "usage": "Fond de la chip Insolite (D-050)." }, { "name": "mood-unusual-ink", "value": { "light": "#7E349D", "dark": "#B77EE0" }, "usage": "Texte et icône de la chip Insolite (6,09:1 sur mood-unusual-soft, D-050)." }, { "name": "mood-instagrammable-soft", "value": { "light": "#F6E5F1", "dark": "#462143" }, "usage": "Fond de la chip Instagrammable (D-050)." }, { "name": "mood-instagrammable-ink", "value": { "light": "#952B77", "dark": "#DB73BA" }, "usage": "Texte et icône de la chip Instagrammable (6,02:1 sur mood-instagrammable-soft, D-050)." }, { "name": "mood-relax-soft", "value": { "light": "#E2EFF5", "dark": "#17394C" }, "usage": "Fond de la chip Détente (D-050)." }, { "name": "mood-relax-ink", "value": { "light": "#165E7F", "dark": "#4FA7D6" }, "usage": "Texte et icône de la chip Détente (6,08:1 sur mood-relax-soft, D-050)." }, { "name": "mood-sport-soft", "value": { "light": "#EAF0E0", "dark": "#2A3B1B" }, "usage": "Fond de la chip Sportif (D-050)." }, { "name": "mood-sport-ink", "value": { "light": "#40610C", "dark": "#86B93A" }, "usage": "Texte et icône de la chip Sportif (6,15:1 sur mood-sport-soft, D-050)." }, { "name": "success-on-strong", "value": { "light": "#4CC38A", "dark": "#4CC38A" }, "usage": "Icône du toast de succès sur surface-strong (8,09:1 ; 6,12:1 sur sa pastille) ; « Ouvert » dans les sections de E-07 (D-029)." }, { "name": "info-on-strong", "value": { "light": "#8EA8F0", "dark": "#8EA8F0" }, "usage": "Icône du toast d'information sur surface-strong (7,69:1 ; 5,82:1 sur sa pastille) ; liens, icônes et numéros des sections de E-07 (D-029)." }, { "name": "error-on-strong", "value": { "light": "#FF6B5A", "dark": "#FF6B5A" }, "usage": "Icône du toast d'erreur sur surface-strong (6,40:1 ; 4,84:1 sur sa pastille). Le toast d'attention prend amber." }, { "name": "toast-disc", "value": { "light": "rgba(255, 255, 255, 0.10)", "dark": "rgba(255, 255, 255, 0.10)" }, "usage": "Pastille de l'icône du toast, sur surface-strong." }, { "name": "surface-strong-raised", "value": { "light": "rgba(255, 255, 255, 0.06)", "dark": "rgba(255, 255, 255, 0.06)" }, "usage": "Cartes des sections sur encre de E-07 (Pratique, Le mot…), radius-section ; texte on-strong 15,3:1, info-on-strong 6,6:1, success-on-strong 6,9:1 (D-029)." }, { "name": "toast-action", "value": { "light": "rgba(255, 255, 255, 0.14)", "dark": "rgba(255, 255, 255, 0.14)" }, "usage": "Pilule de l'action du toast (« Réessayer ») et boutons en verre de E-07 (« Itinéraire », Oui, Signaler), texte on-strong (11,88:1)." }, { "name": "badge-premium-bg", "value": { "light": "rgba(20, 23, 31, 0.86)", "dark": "rgba(44, 48, 57, 0.92)" }, "usage": "Pastille Premium posée sur photo : « Premium » en on-strong et couronne amber (D-014)." }, { "name": "map-base", "value": { "light": "#F0EFEC", "dark": "#1A1D22" }, "usage": "Fond de carte." }, { "name": "map-road", "value": { "light": "#FFFFFF", "dark": "#2A2E36" }, "usage": "Voirie." }, { "name": "map-park", "value": { "light": "#E2ECDF", "dark": "#1E2A23" }, "usage": "Parcs et jardins." }, { "name": "map-water", "value": { "light": "#C9DCEF", "dark": "#1B2A3B" }, "usage": "Eau (Seine, canaux)." }, { "name": "map-block", "value": { "light": "#E8E6E0", "dark": "#22252B" }, "usage": "Îlots bâtis." }, { "name": "map-label", "value": { "light": "#5F6B80", "dark": "#A1A9B8" }, "usage": "Noms de quartiers en capitales (4,68:1 sur map-base)." } ] }, "type": { "fonts": [ { "family": "Plus Jakarta Sans", "file": "fonts/PlusJakartaSans-400.woff2", "weight": "400" }, { "family": "Plus Jakarta Sans", "file": "fonts/PlusJakartaSans-500.woff2", "weight": "500" }, { "family": "Plus Jakarta Sans", "file": "fonts/PlusJakartaSans-600.woff2", "weight": "600" }, { "family": "Plus Jakarta Sans", "file": "fonts/PlusJakartaSans-700.woff2", "weight": "700" }, { "family": "Plus Jakarta Sans", "file": "fonts/PlusJakartaSans-800.woff2", "weight": "800" } ], "families": { "sans": "\"Plus Jakarta Sans\", system-ui, -apple-system, \"Segoe UI\", sans-serif" }, "groups": [ { "name": "Titres", "family": "sans", "styles": [ { "name": "title-xl", "fontSize": "26px", "lineHeight": "32px", "fontWeight": 800, "letterSpacing": "-0.02em", "usage": "Titre de la fiche, grand titre d'une liste (« À proximité »).", "sample": "Montmartre sans les touristes" }, { "name": "title-l", "fontSize": "22px", "lineHeight": "28px", "fontWeight": 800, "letterSpacing": "-0.02em", "usage": "Titre d'une sheet modale (« Filtres »).", "sample": "Filtres" }, { "name": "title-m", "fontSize": "20px", "lineHeight": "26px", "fontWeight": 800, "letterSpacing": "-0.01em", "usage": "Titre de section de la fiche (« Les étapes », « Avis »).", "sample": "Les étapes" }, { "name": "title-s", "fontSize": "17px", "lineHeight": "22px", "fontWeight": 800, "letterSpacing": "-0.01em", "usage": "Titre de section de la sheet, groupe de filtres, salutation, titre d'un message d'état.", "sample": "À proximité" }, { "name": "title-card", "fontSize": "16px", "lineHeight": "21px", "fontWeight": 800, "letterSpacing": "-0.01em", "usage": "Titre de card (deux lignes au plus), titre de la barre du haut compacte.", "sample": "Canal Saint-Martin au fil de l'eau" } ] }, { "name": "Chiffres", "family": "sans", "styles": [ { "name": "number-l", "fontSize": "20px", "lineHeight": "24px", "fontWeight": 800, "letterSpacing": "-0.02em", "usage": "Chiffre clé du budget sur la card (« 40 € »), unité en label à côté.", "sample": "40 €" }, { "name": "number-m", "fontSize": "17px", "lineHeight": "22px", "fontWeight": 800, "letterSpacing": "-0.01em", "usage": "Valeur des tuiles d'infos de la fiche.", "sample": "6,1 km" }, { "name": "number-s", "fontSize": "13px", "lineHeight": "18px", "fontWeight": 800, "usage": "Note en pastille, compteur de filtres, étiquette de durée des marqueurs.", "sample": "4,9" } ] }, { "name": "Texte", "family": "sans", "styles": [ { "name": "item", "fontSize": "16px", "lineHeight": "21px", "fontWeight": 700, "usage": "Nom d'étape, ligne de résultat de recherche.", "sample": "Musée de Montmartre" }, { "name": "button-l", "fontSize": "16px", "lineHeight": "20px", "fontWeight": 700, "usage": "Bouton principal de 52 px (panneau de filtres).", "sample": "Voir 9 parcours" }, { "name": "button", "fontSize": "15px", "lineHeight": "20px", "fontWeight": 700, "usage": "Boutons de 48 px (barre de la fiche, « Voir le parcours »). 600 pour le bouton d'un message d'état.", "sample": "C'est parti" }, { "name": "body", "fontSize": "15px", "lineHeight": "22px", "fontWeight": 400, "usage": "Description, saisie, avis.", "sample": "Le Montmartre des habitants, loin de la place du Tertre." }, { "name": "body-medium", "fontSize": "15px", "lineHeight": "20px", "fontWeight": 500, "usage": "Lignes de liste et d'options (« En pratique », tri).", "sample": "Marche" }, { "name": "body-s", "fontSize": "14px", "lineHeight": "20px", "fontWeight": 500, "usage": "Sous-titres, lignes de détail d'étape, ambiance · quartier dans la fiche.", "sample": "Départ conseillé à 10:00" }, { "name": "tab", "fontSize": "14px", "lineHeight": "20px", "fontWeight": 500, "usage": "Libellé de l'onglet actif.", "sample": "Accueil" }, { "name": "label", "fontSize": "13px", "lineHeight": "18px", "fontWeight": 500, "usage": "Chips, métadonnées, tags, trajets, créateur « Par Widoo ».", "sample": "15 min à pied (1,1 km)" }, { "name": "label-strong", "fontSize": "13px", "lineHeight": "18px", "fontWeight": 700, "usage": "Heures et durées de la timeline, liens discrets.", "sample": "10:35" }, { "name": "status", "fontSize": "13px", "lineHeight": "18px", "fontWeight": 600, "usage": "Lignes d'état discrètes, pastilles sur photo (Vérifié, Signature, Premium, Privé).", "sample": "Café Lomi signalé, peut-être fermé" }, { "name": "caption", "fontSize": "12px", "lineHeight": "16px", "fontWeight": 500, "usage": "Libellé sous la valeur d'une tuile. Plus petit texte autorisé (plafond 1,3).", "sample": "Par pers." }, { "name": "map-label", "fontSize": "13px", "lineHeight": "16px", "fontWeight": 800, "letterSpacing": "0.1em", "textTransform": "uppercase", "usage": "Noms de quartiers sur la carte (map-label).", "sample": "Montmartre" } ] } ] }, "spacing": { "tokens": [ { "name": "space-4", "value": "4px", "usage": "Écart icône-texte serré, marge sous un titre." }, { "name": "space-6", "value": "6px", "usage": "Écart icône-texte dans une chip, entre pastilles sur photo." }, { "name": "space-8", "value": "8px", "usage": "Entre chips, entre boutons d'une barre, entre lignes d'un détail." }, { "name": "space-10", "value": "10px", "usage": "Entre cards d'un carrousel, entre deux boutons de la barre collée." }, { "name": "space-12", "value": "12px", "usage": "Entre cards d'une liste, padding vertical de la barre collée." }, { "name": "space-16", "value": "16px", "usage": "Marge d'écran, padding d'un encart." }, { "name": "space-18", "value": "18px", "usage": "Entre les blocs du haut de la fiche." }, { "name": "space-20", "value": "20px", "usage": "Padding haut de la feuille de la fiche." }, { "name": "space-24", "value": "24px", "usage": "Entre sections de la fiche." }, { "name": "space-28", "value": "28px", "usage": "Entre groupes du panneau de filtres." }, { "name": "space-32", "value": "32px", "usage": "Respiration avant une section isolée." } ] }, "radius": { "tokens": [ { "name": "radius-thumb", "value": "10px", "usage": "Vignette photo de 48 px dans la tooltip." }, { "name": "radius-photo", "value": "12px", "usage": "Photo dans une card, photo d'étape dépliée, encadré d'alerte, conseil du créateur." }, { "name": "radius-block", "value": "16px", "usage": "Tooltip de la carte, tuiles d'infos, encarts (créateur, Premium)." }, { "name": "radius-card", "value": "18px", "usage": "Cards de parcours, marqueur photo de la carte." }, { "name": "radius-section", "value": "20px", "usage": "Sections sur encre de E-07, mini-lecteur, bloc de l'étape sur la carte (D-029)." }, { "name": "radius-sheet", "value": "24px", "usage": "Haut des sheets et de la feuille de la fiche." }, { "name": "radius-pill", "value": "999px", "usage": "Boutons, chips, pastilles, disques, barre d'onglets, champ de recherche." } ] }, "size": { "note": "Dimensions des composants validés.", "tokens": [ { "name": "touch-min", "value": "44px", "usage": "Zone tactile minimale (hitSlop sur les chips de 36 px et les petites pastilles)." }, { "name": "chip-h", "value": "36px", "usage": "Hauteur d'une chip (D-004)." }, { "name": "badge-h", "value": "26px", "usage": "Hauteur d'une pastille sur photo, étiquette de durée des marqueurs." }, { "name": "button-h", "value": "48px", "usage": "Bouton courant (barre de la fiche, messages d'état)." }, { "name": "button-l-h", "value": "52px", "usage": "Bouton principal du panneau de filtres, éléments de la barre d'onglets." }, { "name": "disc", "value": "44px", "usage": "Bouton rond (fermer, partager, favori, filtres)." }, { "name": "disc-s", "value": "34px", "usage": "Favori posé sur la photo d'une card." }, { "name": "avatar-s", "value": "22px", "usage": "Avatar ou logo de la ligne créateur." }, { "name": "avatar-m", "value": "32px", "usage": "Initiale d'un avis." }, { "name": "avatar-l", "value": "44px", "usage": "Logo ou avatar de l'encart créateur." }, { "name": "step-dot", "value": "28px", "usage": "Pastille d'étape (carte et timeline)." }, { "name": "step-dot-active", "value": "34px", "usage": "Pastille d'étape tapée, départ d'un parcours Premium sans abonnement." }, { "name": "marker", "value": "56px", "usage": "Marqueur photo de la carte (liseré blanc de 3 px)." }, { "name": "marker-active", "value": "68px", "usage": "Marqueur de la card en tête du carrousel (liseré blue) ; le parcours sélectionné n'a plus de marqueur (E-04, D-071)." }, { "name": "marker-border", "value": "3px", "usage": "Liseré blanc du marqueur photo (D-071)." }, { "name": "route-stroke", "value": "5px", "usage": "Trait blue du tracé d'un parcours (D-071)." }, { "name": "route-casing", "value": "9px", "usage": "Liseré blanc sous le tracé, 2 px de chaque côté (D-071)." }, { "name": "thumb", "value": "48px", "usage": "Vignette de la tooltip." }, { "name": "tooltip-min-w", "value": "260px", "usage": "Largeur minimale de la tooltip de la carte ; elle prend la largeur de son titre sur une ligne, 80 % de l'écran au plus (mappings.mapTooltip, D-041)." }, { "name": "card-w", "value": "270px", "usage": "Card de carrousel (hauteur 348)." }, { "name": "card-h", "value": "348px", "usage": "Hauteur de la card de carrousel." }, { "name": "card-list-w", "value": "358px", "usage": "Card de liste « Voir tout » (hauteur 388, tag public en plus)." }, { "name": "card-list-h", "value": "388px", "usage": "Hauteur de la card de liste." }, { "name": "sheet-rest", "value": "120px", "usage": "Partie visible de la sheet au repos, au-dessus de la barre d'onglets." }, { "name": "sheet-half-top", "value": "296px", "usage": "Haut de la sheet à mi-hauteur, depuis le haut de l'écran (HALF_TOP, D-071)." }, { "name": "sheet-empty-top", "value": "470px", "usage": "Haut de la sheet « Aucun résultat » (E-01, D-071)." }, { "name": "card-photo", "value": "150px", "usage": "Hauteur de la photo de la card de carrousel (D-071)." }, { "name": "card-list-photo", "value": "190px", "usage": "Hauteur de la photo de la card de liste (D-071)." }, { "name": "hero-h", "value": "380px", "usage": "Photo de tête de la fiche." }, { "name": "icon-s", "value": "16px", "usage": "Icône des lignes d'état et des pastilles (D-054)." }, { "name": "icon-m", "value": "20px", "usage": "Icône des chips (D-054)." }, { "name": "icon-l", "value": "24px", "usage": "Icône des onglets de la barre d'onglets (D-054)." } ] }, "shadow": { "tokens": [ { "name": "shadow-tabbar", "value": { "light": "0 8px 24px rgba(20, 23, 31, 0.10)", "dark": "0 8px 24px rgba(0, 0, 0, 0.40)" }, "usage": "Seule ombre de l'interface : barre d'onglets flottante (D-003), toast (D-025) et mini-lecteur du parcours en cours (D-029), les éléments qui flottent au-dessus du contenu. Tout le reste est à plat." } ] }, "mappings": { "note": "Correspondances du design system Widoo : familles d'activité, catégories de lieu (places.category), icônes des filtres et de l'interface (Phosphor 2, style Regular, Fill pour les états actifs), pastilles. Les noms de tokens renvoient à color.tokens. Les libellés des catégories et des filtres sont ceux de packages/shared (labels/fr.ts).", "iconSet": { "name": "Phosphor", "version": "2.1", "package": "phosphor-react-native", "style": "regular", "activeStyle": "fill", "note": "Tracés officiels (@phosphor-icons/core 2.1.1) dans toutes les maquettes depuis le 24/09 (D-025), aucune icône dessinée à la main ; liste complète sur la planche « Icônes » du canevas ; le code utilise ces noms." }, "activityFamilies": [ { "key": "food", "label": "Gastronomie", "color": "family-food", "chip": { "bg": "coral-soft", "ink": "coral-ink" }, "moodDot": "coral" }, { "key": "culture", "label": "Culture", "color": "family-culture", "chip": { "bg": "plum-soft", "ink": "plum-ink" }, "moodDot": "plum-ink" }, { "key": "nature", "label": "Nature", "color": "family-nature", "chip": { "bg": "green-soft", "ink": "green-ink" }, "moodDot": "family-nature" }, { "key": "shop", "label": "Shopping", "color": "family-shop", "chip": { "bg": "violet-soft", "ink": "violet-ink" }, "moodDot": "violet-ink" }, { "key": "leisure", "label": "Loisirs", "color": "family-leisure", "chip": null, "moodDot": null }, { "key": "other", "label": "Autre", "color": "family-other", "chip": null, "moodDot": null } ], "placeCategories": [ { "category": "restaurant", "label": "Restaurant", "family": "food", "icon": "fork-knife", "mockupGlyph": "couverts" }, { "category": "cafe", "label": "Café", "family": "food", "icon": "coffee", "mockupGlyph": "tasse" }, { "category": "bar", "label": "Bar", "family": "food", "icon": "wine", "mockupGlyph": "verre" }, { "category": "bakery", "label": "Boulangerie", "family": "food", "icon": "bread", "mockupGlyph": "pain" }, { "category": "museum", "label": "Musée", "family": "culture", "icon": "bank", "mockupGlyph": "colonnes" }, { "category": "gallery", "label": "Galerie", "family": "culture", "icon": "frame-corners", "mockupGlyph": "cadre" }, { "category": "monument", "label": "Monument", "family": "culture", "icon": "castle-turret", "mockupGlyph": "tour" }, { "category": "park", "label": "Parc", "family": "nature", "icon": "tree", "mockupGlyph": "arbre" }, { "category": "viewpoint", "label": "Point de vue", "family": "nature", "icon": "mountains", "mockupGlyph": "sommets" }, { "category": "walk", "label": "Balade", "family": "nature", "icon": "person-simple-walk", "mockupGlyph": "marcheur" }, { "category": "shop", "label": "Boutique", "family": "shop", "icon": "shopping-bag", "mockupGlyph": "sac" }, { "category": "activity", "label": "Activité", "family": "leisure", "icon": "lightning", "mockupGlyph": "éclair" }, { "category": "event_venue", "label": "Spectacle", "family": "leisure", "icon": "ticket", "mockupGlyph": "billet" }, { "category": "other", "label": "Autre", "family": "other", "icon": "map-pin", "mockupGlyph": "épingle" } ], "filterIcons": { "audiences": [ { "value": "Solo", "icon": "user" }, { "value": "Couple", "icon": "heart" }, { "value": "Famille", "icon": "users" }, { "value": "Entre amis", "icon": "users-three" }, { "value": "Dog friendly", "icon": "paw-print" }, { "value": "Kids friendly", "icon": "balloon" } ], "budget": [ { "value": "Gratuit", "icon": "tag" }, { "value": "Jusqu'à 25 €", "icon": null }, { "value": "25 à 70 €", "icon": null }, { "value": "Plus de 70 €", "icon": null } ], "duration": [ { "value": "Jusqu'à 2 h 30", "icon": null }, { "value": "2 h 30 à 5 h", "icon": null }, { "value": "5 à 12 h", "icon": null }, { "value": "Plus de 12 h", "icon": null } ], "transport": [ { "value": "À pied", "icon": "person-simple-walk" }, { "value": "Vélo", "icon": "bicycle" }, { "value": "Métro", "icon": "subway" }, { "value": "Voiture", "icon": "car" } ], "moods": [ { "value": "Culture", "icon": "bank" }, { "value": "Nature", "icon": "tree" }, { "value": "Shopping", "icon": "shopping-bag" }, { "value": "Gastronomie", "icon": "fork-knife" }, { "value": "Romantique", "icon": "flower-tulip" }, { "value": "Insolite", "icon": "sparkle" }, { "value": "Instagrammable", "icon": "camera" }, { "value": "Détente", "icon": "armchair" }, { "value": "Sportif", "icon": "barbell" } ], "conditions": [ { "value": "Sans réservation", "icon": "calendar-slash" }, { "value": "Accessible PMR", "icon": "wheelchair" }, { "value": "Intérieur", "icon": "house" }, { "value": "Extérieur", "icon": "park" }, { "value": "Beau temps", "icon": "sun" }, { "value": "Jour de pluie", "icon": "cloud-rain" } ] }, "filterIconsNote": "Une icône par valeur, sauf Budget et Durée (montants et heures en texte), à une exception : « Gratuit » prend tag, dans la chip rapide de E-01 et le panneau E-03 (D-053). Culture, Nature, Shopping et Gastronomie reprennent l'icône et la teinte de leur famille ; Romantique, Insolite, Instagrammable, Détente et Sportif, une teinte tirée de leur point d'ambiance (mood-*-soft, mood-*-ink, D-050). Extérieur prend un banc (park) : le soleil est réservé à la météo et à Beau temps.", "moodDots": [ { "mood": "culture", "label": "Culture", "dot": "plum-ink" }, { "mood": "nature", "label": "Nature", "dot": "family-nature" }, { "mood": "shopping", "label": "Shopping", "dot": "violet-ink" }, { "mood": "food", "label": "Gastronomie", "dot": "coral" }, { "mood": "romantic", "label": "Romantique", "dot": "mood-romantic", "chip": { "bg": "mood-romantic-soft", "ink": "mood-romantic-ink" } }, { "mood": "unusual", "label": "Insolite", "dot": "mood-unusual", "chip": { "bg": "mood-unusual-soft", "ink": "mood-unusual-ink" } }, { "mood": "instagrammable", "label": "Instagrammable", "dot": "mood-instagrammable", "chip": { "bg": "mood-instagrammable-soft", "ink": "mood-instagrammable-ink" } }, { "mood": "relax", "label": "Détente", "dot": "mood-relax", "chip": { "bg": "mood-relax-soft", "ink": "mood-relax-ink" } }, { "mood": "sport", "label": "Sportif", "dot": "mood-sport", "chip": { "bg": "mood-sport-soft", "ink": "mood-sport-ink" } } ], "moodDotsNote": "Point de 8 px devant « ambiance · quartier », décoratif (le nom suit), au moins 3:1 sur bg et surface. Clés de packages/shared (moods). Neuf couleurs distinctes, écart minimal ΔE2000 11,5 (D-016).", "uiIcons": { "search": "magnifying-glass", "filters": "sliders-horizontal", "notifications": "bell", "recenter": "navigation-arrow", "refresh": "arrows-clockwise", "favorite": "heart (fill quand actif, coral)", "verified": "seal-check", "premium": "crown-simple (fill, amber)", "private": "lock-simple", "alert": "warning", "duration": "clock", "budget": "wallet", "distance": "person-simple-walk", "steps": "flag", "close-sheet": "caret-down", "expand-step": "caret-down", "collapse-step": "caret-up", "share": "export", "map": "map-trifold", "offline": "wifi-slash", "error": "cloud-slash", "removed": "eye-slash", "info": "info", "tab-home": "house (fill quand actif)", "tab-outings": "map-trifold (fill quand actif)", "tab-profile": "user (fill quand actif)", "settings": "gear-six", "back": "caret-left", "open-row": "caret-right", "edit": "pencil-simple", "camera": "camera", "reorder": "dots-six-vertical", "anecdote": "quotes (fill)", "sort": "arrows-down-up", "add": "plus (bold)", "done": "check-circle (fill, green-ink)", "todo": "circle", "certified": "seal-check (fill, blue)", "email": "envelope-simple", "sign-out": "sign-out", "delete": "trash", "legal": "file-text", "privacy": "shield-check", "help": "question", "clear": "x-circle", "remove": "x (bold)", "empty": "binoculars", "loading": "circle-notch", "location-off": "gps-slash", "external": "arrow-square-out", "public-profile": "eye", "login-method": "key", "language": "globe-simple", "link-expired": "link-break", "email-sent": "envelope-simple-open", "toast-success": "check-circle (fill, success-on-strong)", "toast-info": "info (fill, info-on-strong)", "toast-warning": "warning (fill, amber)", "toast-error": "warning-circle (fill, error-on-strong)", "go-minimize": "caret-down", "go-map": "map-trifold", "go-back": "caret-left", "itinerary": "arrow-square-out", "arrived": "check (bold)", "listen": "headphones (fill)", "play": "play (fill)", "practical": "info (fill)", "must-see": "star (fill)", "creator-word": "quotes (fill)", "next-step": "arrow-right (fill)", "plan-date": "calendar-check (fill)", "other-date": "calendar-blank", "cancel-outing": "calendar-x", "to-prepare": "list-checks", "suggested-time": "clock-counter-clockwise (bold)", "earlier": "minus (bold)", "later": "plus (bold)", "signal-closed": "door (fill)", "signal-hours": "clock (fill)", "signal-address": "map-pin (fill)", "signal-works": "barricade (fill)", "signal-crowded": "users-three (fill)", "signal-description": "smiley-meh (fill)", "signal-other": "dots-three (fill)", "closed-today": "calendar-x (fill)", "closed-temporarily": "hourglass-medium (fill)", "closed-permanently": "prohibit (fill)", "rejected": "x-circle (fill, error-ink)", "missed": "calendar-slash (fill)", "empty-upcoming": "calendar-blank", "empty-past": "flag", "close": "x (bold)", "ends": "hourglass-medium", "last-check": "seal-check (green-ink)", "report-route": "flag", "route-reported": "flag (fill)", "field-work": "seal-check (green-ink)", "reminders-off": "bell-slash", "analytics": "chart-bar", "sign-in": "user (disque blanc, accueil sans compte)", "notif-reminders": "calendar-check", "notif-next-day": "star", "notif-my-routes": "flag", "notifications-off": "bell-slash", "field-error": "warning-circle (fill, error-ink)", "phone-language": "device-mobile", "privacy-settings": "hand-palm", "export-data": "download-simple", "rating": "star (fill, amber)", "unlocked-routes": "lock-open", "translated": "translate" }, "badges": { "verified": { "bg": "badge-verified-bg", "ink": "green-ink", "icon": "seal-check", "label": "Vérifié", "where": "photo, en bas à gauche" }, "signature": { "bg": "badge-signature-bg", "ink": "blue-ink", "icon": null, "label": "Signature", "meaning": "Parcours créé par l'équipe Widoo (D-014).", "where": "photo, en bas (à droite sur les cards)" }, "premium": { "bg": "badge-premium-bg", "ink": "on-strong", "icon": "crown-simple", "iconColor": "amber", "label": "Premium", "meaning": "Parcours réservé aux abonnés, de Widoo ou d'un utilisateur (D-014).", "where": "card : à côté de la note, en haut à gauche ; fiche : après Signature" }, "private": { "bg": "bg", "ink": "ink", "icon": "lock-simple", "label": "Privé", "where": "fiche : à la place de Vérifié et Signature" }, "new": { "bg": "bg", "ink": "ink", "icon": null, "label": "Nouveau", "meaning": "Parcours publié sans avis (D-023).", "where": "card : à la place de la note, en haut à gauche" }, "certified": { "bg": null, "ink": "blue-ink", "icon": "seal-check", "iconColor": "blue", "iconStyle": "fill", "label": "Créateur certifié", "meaning": "Créateur qui remplit les critères (au moins 3 parcours vérifiés, note moyenne ≥ 4,5, au moins 3 parcours réalisés) ou certifié par l'équipe (D-023).", "where": "profil : sceau à côté du prénom et « Créateur certifié » dessous ; ligne créateur des cards et de la fiche : sceau après le prénom" } }, "mapTooltip": { "note": "Tooltip encre de la carte (E-04), un seul gabarit (D-041, ticket #155).", "width": "largeur du titre sur une ligne", "minWidth": "tooltip-min-w", "maxWidthRatio": 0.8, "titleLines": "une ligne si elle tient, deux au plus", "screenMarginPx": 16, "placement": "centrée sur son ancre, ramenée dans l'écran si besoin", "arrow": "toujours sur l'ancre", "fontScale150": "largeur maximale, nom et note seulement" }, "darkSurfaces": [ "chip active", "onglet actif", "tooltip de la carte", "bouton et pastille Premium", "pastille Fin du parcours", "toast", "page immersive E-07", "mini-lecteur", "segment actif (onglet Parcours)", "bouton « Essayer gratuitement » de E-17" ], "immersive": { "note": "E-07, parcours en cours (D-029) : une seule page qui défile ; photo plein cadre, puis en-tête compact et sections sur encre.", "bg": "surface-strong", "photoHeight": 600, "veil": "linear-gradient(180deg, rgba(20,23,31,.72) 0%, rgba(20,23,31,.60) 15%, rgba(20,23,31,.15) 26%, rgba(20,23,31,.10) 42%, rgba(20,23,31,.90) 72%, #14171F 100%)", "veilNote": "Haut renforcé (D-034) : le titre de la barre du haut passait à 1,90:1 au pire cas (photo blanche).", "textVeil": { "note": "D-034 : voile ancré au haut du bloc de texte (statut, nom, ligne, progression, commandes) ; il suit le bloc quand le texte grandit (150 %).", "gradient": "linear-gradient(180deg, rgba(20,23,31,0) 0px, rgba(20,23,31,.75) 96px, rgba(20,23,31,.92) 100%)", "from": "96 px au-dessus du statut jusqu'au bas du bloc" }, "scrollDarken": "photo assombrie jusqu'à 65 % d'encre pendant le défilement vers le contenu (D-034)", "photoText": "textes sur photo contrôlés au pire cas, photo remplacée par du blanc sous les voiles : 4,5:1 texte, 3:1 grand texte (D-034)", "section": { "bg": "surface-strong-raised", "radius": "radius-section", "title": "on-strong 17/22 800", "icon": "info-on-strong", "link": "info-on-strong", "ok": "success-on-strong" }, "commands": { "order": "Itinéraire à gauche, J'y suis à droite, toujours", "secondary": "toast-action + on-strong", "primary": "on-strong en fond, ink en texte", "height": 52 }, "discOnPhoto": "rgba(20, 23, 31, 0.40), icône on-strong", "progress": "un segment par étape, 4 px, on-strong sur blanc à 28 %, pastille 12 px", "miniPlayer": { "bg": "surface-strong", "radius": "radius-section", "height": 64, "shadow": "shadow-tabbar", "progress": "3 px en bas" }, "stepAlert": { "note": "D-033 : lieu signalé fermé ou bientôt fermé, au-dessus du titre", "bg": "alert-soft", "ink": "alert", "radius": 16, "icon": "warning ou clock-countdown, plein", "action": "Passer cette étape, soulignée" }, "skippedStep": { "progressSegment": "on-strong à 45 %", "timeline": "tiret à la place de l'heure, « Passée » en muted, pastille surface avec skip-forward" }, "offlinePill": { "bg": "rgba(20, 23, 31, 0.55)", "ink": "on-strong", "icon": "wifi-slash", "text": "Hors connexion, la sortie continue" }, "toastPlacement": "sur la sheet blanche, jamais sur la page sombre" }, "toast": { "note": "Résultat d'une action (enregistré, envoyé, erreur), jamais un état durable : hors connexion, chargement et erreurs de chargement restent en lignes ou en blocs (D-025).", "bg": "surface-strong", "title": "on-strong", "subtitle": "on-strong-muted", "disc": "toast-disc", "action": { "bg": "toast-action", "ink": "on-strong" }, "shape": "pilule à la largeur du texte, centrée, 358 px au plus, rayon plein sur une ligne et 22 px sur deux ; titre 14/20 800, sous-titre 13/18 500", "position": "en bas : au-dessus de la barre d'onglets, du clavier ou d'une barre collée ; un seul à la fois ; glisser vers le bas pour fermer", "shadow": "shadow-tabbar", "states": { "success": { "icon": "check-circle", "color": "success-on-strong", "role": "status", "seconds": 4 }, "info": { "icon": "info", "color": "info-on-strong", "role": "status", "seconds": 4 }, "warning": { "icon": "warning", "color": "amber", "role": "alert", "seconds": 6 }, "error": { "icon": "warning-circle", "color": "error-on-strong", "role": "alert", "seconds": null, "until": "action ou glissé" } }, "undo": { "seconds": 6, "note": "toast avec « Annuler » (étape ajoutée, retirée, ordre changé) : 6 s, comme l'attention ; au lecteur d'écran, « Annuler » est atteignable au balayage et le toast reste tant que le focus est dessus (D-051)" } }, "planning": { "note": "E-06 Programmer et E-08 onglet Parcours (D-035, états D-038, 150 % D-039).", "sheet": "sheet modale sur la fiche, sans croix (M-05) ; bouton collé « Programmer samedi 26 à 10:00 »", "dayChips": "Aujourd'hui, Demain, surlendemain, Autre date ; choisi : surface-strong + coche, comme une chip active", "timeStepper": { "bg": "surface", "buttons": "disques bg de 44 px, minus et plus en gras", "stepMinutes": 15, "default": "départ conseillé du parcours", "text": "24/30 800" }, "okLine": "green-ink, check-circle plein", "closedAlert": { "bg": "alert-soft", "ink": "alert", "icon": "warning plein", "action": "heure suggérée soulignée, clock-counter-clockwise gras, alignée à droite (D-039)" }, "checklist": { "box": 24, "radius": 7, "border": "control-border", "checked": "blue, coche on-blue en gras", "order": "toujours avant le programme" }, "reminders": [ "la veille à 18:00", "une heure avant le départ" ], "dateCard": "surface, rayon 16, icône et « Changer » centrés verticalement", "tab": "onglet « Parcours », icône map-trifold", "segmented": { "track": "surface", "height": 44, "padding": 4, "segment": 36, "active": "surface-strong, on-strong 14/20 700", "inactive": "ink 14/20 600", "labels": [ "À venir", "Favoris", "Passés", "Créés" ] }, "row": "photo 64 px radius-photo, titre 16/21 700, date 13/18 muted", "smallButton": { "height": 36, "primary": "blue + on-blue (Noter)", "secondary": "surface + ink (Relancer)" }, "status": { "size": "24 px, 12/16 700", "draft": [ "surface", "muted", "pencil-simple plein" ], "pending": [ "blue-soft", "blue-ink", "clock plein" ], "published": [ "green-soft", "green-ink", "check-circle plein" ], "changes_requested, needs_fix": [ "alert-soft", "alert", "warning plein" ], "private": [ "surface", "ink", "lock-simple plein" ], "stopped": [ "surface", "muted" ], "rejected": [ "error-soft", "error-ink", "x-circle plein" ], "unpublished": [ "surface", "muted", "eye-slash plein" ], "missed": [ "surface", "muted", "calendar-slash plein" ] }, "statusNote": "Refusé : motif sous le titre et « Reprendre » (redevient brouillon) ; retiré : raison sous le titre, la ligne ouvre l'éditeur ; pas fait : « Prévu le… » et « Reprogrammer » (D-038).", "rowAction": "titre long : l'action (bouton secondaire de 36 px) passe sous le texte, alignée à droite, côté pouce (D-039) ; la ligne et le bouton restent deux contrôles", "empty": { "disc": "surface, 56 px, icône 28 regular ink", "title": "17/22 800", "text": "14/20 400 muted, équilibré sur ses lignes", "button": "blue, 48 px", "icons": { "upcoming": "calendar-blank", "favorites": "heart", "past": "flag", "created": "pencil-simple" } }, "signedOut": "invitation pleine page comme le Profil sans compte : trois photos, « Vos sorties, toutes au même endroit », trois avantages, « Créer un compte ou se connecter » ; pas de segments", "premiumLapsed": "sortie Premium gardée après la fin de l'abonnement ou du pass : encart de la fiche (mappings.premium.routeCard), « Abonnement Premium terminé » ou « Pass Premium terminé », achat du parcours seul et lien du pass (« Reprendre un pass 7 jours » après un pass) ; « Débloquer avec Premium » (surface-strong) à la place de « C'est parti », pas de « Changer » (D-073)", "cancel": "alerte système à boutons empilés (« Annuler la sortie » rouge système en haut, « Garder » en bas) ; toast « Sortie annulée » avec « Rétablir »", "favoriteRemoved": "un appui sur le cœur retire tout de suite ; toast « Retiré des favoris » avec « Annuler »", "offline": "ligne discrète wifi-slash muted 13/18 600 ; E-06 : bouton inactif (skeleton, muted) et « Reconnectez-vous pour programmer la sortie. » ; E-08 : tout reste lisible, « C'est parti » compris", "calcError": "bloc surface rayon 16 : warning-circle, « Programme indisponible pour l'instant », texte muted, « Réessayer » (arrows-clockwise gras, blue-ink) aligné à droite ; on peut programmer quand même", "change": "« Changer » rouvre la sheet, titrée « Modifier la sortie », bouton « Déplacer au dimanche 27 à 11:00 » ; toast « Sortie déplacée » avec « Voir »" }, "signal": { "note": "Sheet « Signaler » façon Waze (D-036), E-07, E-15, E-05.", "tile": { "disc": 72, "bg": "surface", "icon": "36, plein, couleur décorative", "label": "14/18 600, trois lignes au plus" }, "selected": "anneau blue de 3 px et pastille coche blue de 24 px", "motifs": [ [ "closed", "Fermé", "door", "#F2592A" ], [ "wrong_hours", "Horaires faux", "clock", "#4E74C8" ], [ "wrong_address", "Mal placé", "map-pin", "#5A3FA8" ], [ "works", "Travaux ou accès difficile", "barricade", "#F5B301" ], [ "crowded", "Complet ou longue attente", "users-three", "#128A87" ], [ "not_as_described", "Plus comme décrit", "smiley-meh", "#7A2A4A" ], [ "other", "Autre", "dots-three", "#5F6B80" ] ], "closed": [ [ "closed_today", "Aujourd'hui", "calendar-x" ], [ "closed_temporarily", "Temporairement", "hourglass-medium" ], [ "closed_permanently", "Définitivement", "prohibit" ] ], "otherText": 80, "oneTap": "un appui envoie sauf closed et other ; toast avec « Annuler »" }, "accessibility": { "textContrast": 4.5, "uiContrast": 3.0, "touchMin": 44, "maxFontSizeMultiplierDense": 1.3, "reflowFontScale": 1.3, "reflows": [ "tooltip de la carte réduite au nom et à la note", "résumé de parcours avec « Voir le parcours » remonté sous le titre", "bulle d'un lieu sur la carte de l'éditeur (E-12) réduite à la photo, au nom, à la catégorie et à « Ajouter au parcours » (D-051)" ], "denseComponents": [ "chips", "barre d'onglets", "étiquettes de marqueurs", "compteur de filtres", "pilule de tri", "pastilles sur photo", "tuiles d'infos", "barre collée de la fiche", "barre du haut des pages secondaires", "toast entier (titre, sous-titre, action, D-046)", "bouton « Continuer avec un e-mail »", "barre du haut et en-tête compact de E-07", "mini-lecteur (nom sur une ligne, nom complet dans le libellé)", "tuiles et barre collée de E-15", "segments de l'onglet Parcours", "pastilles de statut des lignes", "petits boutons de 36 px (Noter, Relancer, Reprendre, Reprogrammer)", "barres collées de la sheet Programmer et de « Votre sortie »", "barre du haut et étapes de l'assistant de création (E-11 à E-14, D-051)", "étiquettes de trajet sur la carte de l'éditeur (D-051)", "pastille « Couverture » des photos du parcours (D-051)", "idées à toucher de « À prévoir » (D-051)", "pastille « Suggéré » de la fenêtre du trajet (D-051)" ], "wrapRows": "ligne libellé et valeur (Réglages) en flexWrap : la valeur passe sous le libellé ; e-mail jamais coupé (D-028) ; titre de section et valeur à droite (« 1 sur 2 », « Départ 10:00, fin vers 17:00 ») en flexWrap, la valeur passe dessous ; « Réserver » (base 260) et « Changer » (base 240) passent sous leur texte (D-039)", "tallSheet": "sheet plus haute que l'écran : maxHeight sous la barre d'état, contenu qui défile, bouton collé en bas (D-028)", "sdkButtons": "Apple et Google : boutons des SDK, texte à taille fixe", "textOpacity": "jamais d'opacité sur un texte (D-028) ; seule exception : le crédit d'une photo libre (mappings.photoCredit, D-052)", "immersiveText": "E-07 à 150 % : le bloc grandit vers le haut sur la photo, qui ne change pas ; commandes en flexWrap wrap-reverse, J'y suis au-dessus quand elles ne tiennent plus (D-034)", "ratingInput": "note à donner (E-15) : étoile choisie pleine amber, non choisie en contour control-border (3,49:1), libellé de la note écrit ; jamais la teinte seule (D-034)", "thumbSide": "actions côté pouce : une action qui passe à la ligne s'aligne à droite (action d'une ligne, « Réserver », « Changer », « Réessayer », « Partir à 14:00 ») (D-039)", "referenceFontScale": 1.353, "referenceNote": "plus grand réglage standard (iOS xxxLarge, fontScale 1,353 dans React Native) ; Android jusqu'à 200 %, non linéaire depuis Android 14 (D-046)", "maxFontSizeMultiplierTitle": 1.2, "titleMinFontSize": 22, "scrollEdge": "page qui défile sous une barre collée : fondu de 32 px de la couleur du fond, le haut du bloc suivant dépasse au premier écran (D-046)", "mapNoScale": "fond de carte, noms de quartiers et numéros dans les pastilles d'étape ne suivent pas la taille du texte (D-051)", "twoActions": "deux actions de même poids côte à côte (« Enregistrer en privé » et « Soumettre ») : rangée en flexWrap wrap-reverse, chaque bouton flex 1 et au moins à la largeur de son libellé ; côte à côte à 100 %, l'action principale passe au-dessus en pleine largeur quand elles ne tiennent plus (D-051)", "dragAlternatives": "chaque geste a son équivalent d'un toucher (WCAG 2.5.7) : réordonner les étapes, « Monter » et « Descendre » du menu de l'étape ; glisser pour retirer, « Retirer du parcours » ; ordre des photos, toucher une photo ouvre « En faire la couverture » (« Mettre en premier » dans En images), « Déplacer à gauche », « Déplacer à droite », « Retirer » ; épingle du lieu, toucher la carte la pose ; mêmes actions au lecteur d'écran (accessibilityActions) (D-051)", "fieldBorder": "champ : filet line sur fond blanc, reconnu par son libellé ; si un audit demande 3:1 sur le contour, passer le filet en control-border dans le composant champ, partout (D-051)", "centeredLinks": "deux liens d'action centrés (« Renvoyer dans 30 s », « Annuler », E-19) : rangée flexWrap centrée, columnGap 120 ; l'un sous l'autre, centrés, 44 px chacun, quand ils ne tiennent plus (D-064)", "decorAboveText": "marque au-dessus d'un texte qui grandit (W de E-20) : ne bouge que si le texte arrive à moins de 24 px, jamais sous la barre d'état (D-064)" }, "motion": { "note": "Mouvement sobre et natif, identique sur iOS et Android (D-030) ; à ajuster sur appareil selon le ressenti. Catalogue M-01 à M-13 : Direction-Artistique › Mouvement.", "durationsMs": { "press": 100, "pressRelease": 200, "fade": 200, "base": 300, "page": 350, "map": 500, "shimmer": 1200, "loadingDelay": 300 }, "easings": { "standard": [ 0.2, 0, 0, 1 ], "exit": [ 0.3, 0, 1, 1 ], "linear": [ 0, 0, 1, 1 ] }, "springGesture": { "damping": 500, "stiffness": 1000, "mass": 3, "overshootClamping": true, "restDisplacementThreshold": 10, "restSpeedThreshold": 10 }, "springTabBar": { "stiffness": 380, "damping": 28, "mass": 1, "overshootClamping": false }, "press": { "filled": "voile ink à 8 %", "cardsAndDiscs": "échelle 0,97", "linksAndIcons": "opacité 0,6" }, "page": { "android": "ios_from_right", "ios": "default", "leaving": "recule d'un tiers, voile ink à 10 %", "open": "page + standard", "back": "base + standard", "backGesture": "bord gauche, iOS et Android" }, "modal": { "animation": "slide_from_bottom", "open": "page + standard", "close": "base + exit", "swipeDownToClose": true }, "cardToDetail": { "open": "page + standard", "close": "base + standard", "photoRadius": "12 → 0", "detailFade": true, "fallback": "modal", "implementation": "à la main (transitions partagées de Reanimated expérimentales)" }, "sheet": { "gesture": "springGesture", "programmatic": "base + standard", "detentHaptic": "selection", "modalVeil": "0 → 40 %", "animationConfigs": "explicite, identique iOS et Android" }, "toast": { "in": "base + standard, montée de 16 px et fondu", "out": "fade, sur place", "swipe": "vers le bas" }, "map": { "camera": "map + standard (Mapbox easeTo)", "tooltip": "fade depuis l'ancre", "summary": "fondu enchaîné fade" }, "state": { "fade": "fade + standard", "height": "base + standard", "crossfade": "fade" }, "scroll": { "photoParallax": 0.5, "barFadeDistancePx": 48 }, "miniPlayer": { "reduce": "page + standard", "reopen": "page + standard" }, "keyActions": { "favorite": "cœur plein en fondu, échelle 1 → 1,2 → 1 en 300 ms", "rating": "étoiles en cascade, 50 ms d'écart", "arrived": "bouton à 0,97 pendant l'appui, statut en fondu enchaîné" }, "tabBar": { "pill": "springTabBar : position et largeur, les autres onglets suivent", "labelOut": "100 ms + exit", "labelIn": "fade + standard, 80 ms après le départ, glissement de 6 px depuis l'icône", "icon": "fondu enchaîné fade, du trait ink au plein blue-on-strong", "content": "sans animation", "activeTabPress": "sans effet", "interrupt": "repart de la position et de la vitesse du moment", "haptics": "aucune", "reduce": "largeurs sans mouvement, pastille en fondu fade sur place", "implementation": "Reanimated sur le fil d'interface : withSpring (pastille), withTiming (libellé, icône)" }, "haptics": { "favoriteOn": { "ios": "impactAsync(Light)", "android": "Toggle_On" }, "arrived": { "ios": "impactAsync(Medium)", "android": "Confirm" }, "ratingStar": { "ios": "selectionAsync()", "android": "Clock_Tick" }, "sheetDetent": { "ios": "selectionAsync()", "android": "Clock_Tick" }, "toastSuccess": { "ios": "notificationAsync(Success)", "android": "Confirm" }, "toastError": { "ios": "notificationAsync(Error)", "android": "Reject" }, "nothingElse": true }, "reduceMotion": { "moves": "fondu fade sur place", "loops": "arrêtées (squelettes fixes)", "parallaxBounceCascade": "supprimés", "camera": "sans animation", "gestures": "suivi du doigt, sans ressort", "haptics": "conservés", "reanimated": "ReduceMotion.System saute à la fin ; fondus de remplacement en ReduceMotion.Never", "tabBar": "largeurs sans mouvement, pastille en fondu fade sur place" }, "rules": [ "changement d'onglet : seule la barre bouge (M-13), le contenu change sans animation", "ce qui est posé sur le clavier suit son animation", "alertes et fenêtres système : animations du système", "rien au-delà de 500 ms sauf les boucles de chargement" ], "patterns": { "M-01": "card vers fiche", "M-02": "modale qui monte", "M-03": "page poussée", "M-04": "sheet à crans", "M-05": "sheet modale et voile", "M-06": "toast", "M-07": "carte : sélection et recadrage", "M-08": "changements d'état", "M-09": "chargement", "M-10": "défilement : de la photo à la barre", "M-11": "mini-lecteur", "M-12": "actions clés et retours tactiles", "M-13": "barre d'onglets" } }, "copy": { "address": "vous", "note": "Vouvoiement partout (décision d'Ilan, 2026-09-23). Pas de point médian hors de la ligne ambiance · quartier. Heures en 10:00, durées « 7 h », « 2 h 30 », distances « 1,1 km », budget « ≈ 40 € par pers. », arrondi à 5 € (D-032)." }, "premium": { "note": "E-17 Premium (D-040) : seule page au fond bleu de l'app, piste A retenue par Ilan.", "page": { "bg": "blue", "text": "on-blue", "modal": "plein écran, M-02, croix en haut à gauche, sans barre d'onglets" }, "ribbon": { "asset": "design/design-system/ruban-widoo.svg", "fill": "ink", "opacity": 0.16, "size": 980, "left": -330, "top": 10, "note": "ruban du logo en filigrane, encre à 16 % (blanc à 16 % jusqu'à D-046 : texte blanc dessus à 3,40:1 ; en encre, 5,65:1), décoratif, masqué au lecteur d'écran" }, "hero": { "route": "photo du parcours 270 × 112, bord blanc de 4, inclinée de -3°, pastille Premium", "discover": "trois photos inclinées" }, "title": "28/34 800 on-blue", "sub": "15/22 500 on-blue", "benefits": { "disc": "blanc à 16 %, 40 px", "icons": [ "crown-simple (fill, amber)" ], "text": "15/20 700 et 13/18 500 on-blue", "where": "depuis un encart seulement, sous les formules (D-072)" }, "planSelected": { "bg": "bg", "ink": "ink", "radio": "blue, coche on-blue" }, "planUnselected": { "bg": "rgba(20, 23, 31, 0.22) sur blue", "ink": "on-blue", "radio": "contour on-blue 2 px" }, "bestTag": { "bg": "amber", "ink": "ink", "text": "12/16 800", "label": "Le plus avantageux" }, "cta": { "bg": "surface-strong", "icon": "crown-simple (fill, amber)", "label": "suit la formule : « Essayer gratuitement » (« S'abonner » sans essai), « Prendre le pass 7 jours », « Débloquer ce parcours »" }, "trialLine": "13/18 500 on-blue, au-dessus du bouton : « 7 jours gratuits, puis {prix}. Sans engagement, annulable jusqu'à 24 h avant la fin de l'essai. »", "links": [ "Restaurer les achats", "Conditions", "Confidentialité" ], "prices": { "monthly": "3,99 € par mois", "annual": "29,99 € par an", "annualPerMonth": "soit 2,50 € par mois", "source": "store, jamais en dur", "trialDays": 7, "pass": "2,99 €", "unit": "1,99 €" }, "states": { "note": "États de l'achat (D-044, ticket #75 planche 2), repris pour les quatre formules (D-074, #210 planche 3).", "busy": "fenêtre du store par-dessus ; bouton surface-strong avec anneau on-blue et « Achat en cours » (aria-busy) ; croix et liens à 45 %, cartes à 60 %, inactifs", "cancelled": "retour à E-17 sans message", "success": "E-17 redescend (M-02), retour à l'origine avec l'action faite ; toast success : abonnement « Bienvenue dans Premium » ; pass « Pass Premium activé », « Jusqu'au {date}, {heure}. » ; parcours seul « Parcours débloqué », « Les {n} étapes sont à vous. »", "failed": "toast error « Achat impossible », « Le store n'a pas pu finaliser l'achat. », action « Réessayer »", "pending": "toast info « Achat en attente » : abonnement « Premium s'activera dès sa validation. » ; pass « Le pass s'activera dès sa validation. » ; parcours seul « Le parcours se débloquera dès sa validation. »", "noTrial": "annuel et mensuel seulement : bouton « S'abonner », ligne « {prix}, renouvelé automatiquement. Sans engagement, annulable à tout moment. » ; pass et parcours seul inchangés", "restoring": "lien « Restauration en cours » avec anneau on-blue, bouton à 45 %", "restored": "comme success : abonnement, toast success « Premium restauré » ; pass en cours, « Pass Premium restauré », « Jusqu'au {date}, {heure}. » ; les parcours achetés seuls suivent le compte Widoo, hors restauration du store (D-073)", "nothingToRestore": "toast info « Rien à restaurer », « Aucun pass ni abonnement Widoo sur ce compte {store}. »", "restoreFailed": "toast error « Restauration impossible », action « Réessayer »", "offline": "ligne wifi-slash on-blue « Hors connexion : reconnectez-vous pour acheter. » à la place de la ligne d'offre ; bouton skeleton, texte muted ; « Restaurer les achats » à 45 %", "pricesMissing": "squelette à la place des prix" }, "textContrast": "blanc sur blue 4,51:1, sur le ruban 5,65:1 ; aucun voile clair sous du texte blanc (D-046)", "largeText": { "hero": "photo 96 px de haut ; trois photos réduites à 104 px", "plans": "quatre cartes à hauteur libre, prix sous le libellé", "stickyBar": "ligne d'essai et bouton seulement, bouton plafonné à 1,3 ; liens en fin de page", "scrollEdge": "quand le contenu passe dessous : fond blue, fondu de 32 px ; le haut de la carte Annuel dépasse au premier écran", "priceButton": "bouton « libellé · prix » qui ne tient plus sur une ligne : prix sous le libellé, centré, sans le point ; hauteur selon le contenu, 48 px au moins (D-074)" }, "plans": { "note": "Formules (D-072, #210) : trois cartes sur le même plan ; depuis un parcours, en plus, « Seulement ce parcours ».", "pass": { "label": "Pass 7 jours", "price": "2,99 €", "priceSub": "une seule fois", "tag": "passTag", "cta": "Prendre le pass 7 jours", "line": "2,99 € une seule fois. Premium pendant 7 jours, sans abonnement : rien ne se renouvelle." }, "annual": { "label": "Annuel", "price": "29,99 € par an", "priceSub": "soit 2,50 € par mois", "tag": "bestTag", "cta": "Essayer gratuitement", "line": "trialLine" }, "monthly": { "label": "Mensuel", "price": "3,99 € par mois", "cta": "Essayer gratuitement", "line": "trialLine" }, "unit": { "label": "Seulement ce parcours", "price": "1,99 €", "minHeight": 52, "where": "depuis un parcours", "cta": "Débloquer ce parcours", "line": "1,99 € une seule fois. Ce parcours reste débloqué, sans limite de durée." }, "order": { "visitor": [ "pass", "annual", "monthly", "unit" ], "resident": [ "annual", "monthly", "pass", "unit" ], "preselected": "le premier", "visitorRule": "langue du téléphone autre que le français, ou région hors de France ; calculé sur le téléphone, rien n'est envoyé", "fromPassLink": "pass présélectionné" }, "account": "aucun compte demandé pour acheter (App Store 5.1.1(v)) ; le compte garde les achats sur tous les appareils" }, "passTag": { "bg": "blue-soft", "ink": "blue-ink", "text": "12/16 800", "label": "Idéal pour un séjour" }, "routeCard": { "note": "Encart d'un parcours Premium sur la fiche (E-05, D-072, choix d'Ilan).", "bg": "surface", "icon": "crown-simple (fill, amber) sur disque ink de 40 px", "title": "Parcours Premium", "text": "Débloquez les {n} autres étapes.", "unitButton": { "label": "Débloquer ce parcours · {prix}", "bg": "bg", "border": "control-border", "height": 48, "action": "achat direct, fenêtre du store" }, "passLink": { "label": "De passage à Paris ? Pass 7 jours, {prix}", "ink": "blue-ink", "icon": "caret-right", "action": "E-17, pass présélectionné" }, "busy": "bouton : anneau et « Achat en cours » (aria-busy) ; lien et barre inactifs (barre skeleton, texte muted)", "success": "fiche déployée sur place, toast « Parcours débloqué »", "lapsed": { "titles": [ "Abonnement Premium terminé", "Pass Premium terminé" ], "text": "La sortie reste programmée. Débloquez ce parcours pour retrouver les étapes et le départ.", "passLink": [ "Pass 7 jours, {prix}", "Reprendre un pass 7 jours, {prix}" ] } }, "promoCard": { "note": "Encart Widoo Premium (Réglages, bas de mon profil, Modifier le profil ; compte gratuit), révisé en D-073.", "text": "Tous les parcours Premium, en entier : un pass de 7 jours à {prix du pass}, ou l'abonnement dès {prix annuel ramené au mois} par mois.", "cta": "Découvrir les formules", "hiddenFor": [ "abonné", "pass en cours", "profil vu par un visiteur" ] }, "settingsSection": { "title": "Premium", "pass": { "icon": "crown-simple (fill, amber)", "label": "Pass Premium 7 jours", "sub": "Jusqu'au {date}, {heure}", "action": "Prolonger (blue, caret-right), ouvre E-17" }, "unlocked": { "icon": "lock-open", "label": "Parcours débloqués", "value": "{n}", "opens": "page Parcours débloqués", "when": "dès un parcours acheté seul, avec ou sans pass ou abonnement" }, "noAccountCard": "Créez un compte pour garder vos parcours débloqués sur tous vos appareils.", "largeText": "fin du pass sous le libellé, « Prolonger » dessous, à droite ; « Parcours débloqués » : le nombre passe dessous s'il ne tient pas (D-074)" }, "unlockedPage": { "intro": "Achetés un par un, ils restent à vous, sans limite de durée. Votre compte les garde sur tous vos appareils.", "introNoAccount": "Sans compte, ils restent sur ce téléphone seulement.", "row": "photo 64 (radius-photo), titre 15/20 700, quartier et « Débloqué le {date} » 13/18 muted, chevron ; min 84 px", "order": "du plus récent au plus ancien" }, "passExtend": { "from": "Prolonger (Réglages, toast de fin)", "order": "pass en tête et présélectionné, sans pastille", "heading": "Votre pass se termine le {date} à {heure}. Prolongez-le, ou passez à l'abonnement.", "passSub": "Jusqu'au {date + 7 jours}", "line": "2,99 € une seule fois. 7 jours de plus, jusqu'au {date}, {heure} ; rien ne se renouvelle.", "cta": "Prolonger de 7 jours", "toast": "success « Pass prolongé », « Jusqu'au {date}, {heure}. »", "subscription": "commence tout de suite" }, "passEnded": { "toast": "info « Votre pass est terminé », « Les parcours Premium sont de nouveau verrouillés. », action « Prolonger »", "seconds": 6, "once": true, "where": "première ouverture après la fin, au-dessus de la barre d'onglets ; aucune notification" }, "passAlert": { "where": "E-06, parcours Premium programmé après la fin du pass", "bg": "alert-soft", "ink": "alert", "icon": "hourglass-medium", "title": "Votre pass se termine avant cette sortie", "text": "Il prend fin le {date} à {heure}. Le {jour}, ce parcours sera de nouveau réservé à Premium.", "button": "Débloquer ce parcours · {prix} (bg, control-border, 44 px, achat direct)", "largeText": "titre sur deux lignes, bouton à hauteur libre, prix sous le libellé (largeText.priceButton)" }, "accountPrompt": { "where": "juste après un parcours débloqué à l'unité sans compte (sheet E-10)", "check": "check-circle (fill, green-ink) « Parcours débloqué »", "title": "Créez un compte pour garder ce parcours", "text": "Sans compte, il reste sur ce téléphone seulement et se perd si vous en changez.", "later": "Plus tard (15/20 700, ink, 44 px)", "success": "toast success « Ce parcours est gardé sur votre compte. »", "notAfter": "pass, abonnement", "largeText": "Apple et Google à la taille du système, « Continuer avec un e-mail » et « Plus tard » à 1,3" }, "sharedLink": { "note": "Parcours Premium partagé, site widoo.app /r/ (E-21, D-074, choix d'Ilan : pastille et une ligne, sans prix).", "badge": "pastille Premium sur la photo (badge-premium-bg, couronne amber)", "line": "Parcours Premium : toutes ses étapes dans l'app, avec un pass, un abonnement ou ce parcours seul.", "lineStyle": "14/20 500 muted, couronne amber 16, filet line au-dessus", "lockedSteps": "étapes 2 à 4 : catégorie et cadenas (lock, muted), sans le nom ; départ nommé ; l'API du site n'envoie pas les noms" } }, "photoCredit": { "note": "crédit d'une photo libre de Wikimedia Commons (media.source = commons), posé sur la photo partout où elle s'affiche ; les photos des créateurs n'en ont pas (D-052)", "bg": "rgba(20, 23, 31, 0.40)", "ink": "rgba(255, 255, 255, 0.72)", "text": "© {auteur}", "type": "11/22 600 (12/26 sur la couverture de la fiche, à côté du compteur)", "placement": "bas à droite de la photo, à 8 px (couverture : à gauche du compteur « 1 / 6 ») ; photo en grand de E-07 : sous le bouton carte, en haut à droite", "pressed": { "bg": "surface-strong", "ink": "on-strong" }, "bubble": "bulle surface-strong au-dessus de la pastille : « Photo de {auteur} » (14/20 700, on-strong), licence (13/18 500, on-strong-muted), « Voir sur Wikimedia Commons » (13/18 700, info-on-strong, icône arrow-square-out) ; toucher ailleurs la ferme", "contrast": "hors exigence, choix d'Ilan : discret ; le crédit complet est dans la bulle et dans le libellé du lecteur d'écran ; seule exception à « jamais d'opacité sur un texte »" }, "affiliate": { "note": "« Lien affilié » sous « Réserver » quand steps.booking_is_affiliate ou pour un lien partenaire de Widoo (D-052)", "text": "Lien affilié", "type": "12/16 500", "ink": { "light": "muted", "immersive": "on-strong-muted" }, "placement": "collé sous « Réserver », aligné comme lui : à gauche dans la fiche et la page de l'étape en cours, à droite dans « À préparer » (E-06, « Votre sortie »)", "a11y": "lu avec le lien : « Réserver, lien affilié, ouvre le site du lieu »" }, "ephemeral": { "note": "étape ou lieu éphémère (steps.ends_on, sinon places.ends_on) (D-052)", "icon": "hourglass-medium", "row": "« Jusqu'au 17 janv. » après la catégorie ou l'état de la ligne, gris, en flexWrap (timeline de la fiche, programme, sheet du parcours en cours)", "detail": "« Jusqu'au dimanche 17 janvier 2027 » sous les horaires (fiche) et dans Pratique (E-07) ; l'année seulement si ce n'est pas l'année en cours", "afterDate": "E-06 : alerte de lieu fermé (alert sur alert-soft, sablier) avec la dernière date possible, qui règle le jour ; fiche : parcours à corriger, ligne alert sous les tuiles comme un lieu signalé" }, "transitModes": { "note": "libellé d'un trajet selon le mode choisi par le créateur (D-052)", "format": "{durée} {libellé} ({distance})", "modes": [ { "mode": "walk", "label": "à pied", "icon": "person-simple-walk", "maps": "walking" }, { "mode": "bike", "label": "à vélo", "icon": "bicycle", "maps": "bicycling" }, { "mode": "metro", "label": "en métro", "icon": "subway", "maps": "transit" }, { "mode": "car", "label": "en voiture", "icon": "car", "maps": "driving" } ], "detail": "ligne et stations dans Google Maps, qu'« Itinéraire » ouvre dans le mode du trajet" }, "access": { "note": "« Accès » de « En pratique » (E-05), calculé (computed) : station la plus proche de la première étape, données ouvertes d'Île-de-France Mobilités (D-052)", "value": "« Métro Abbesses, ligne 12 » puis « à 50 m du départ » (13/18 500, muted), à droite, sur deux lignes" }, "communityCheck": { "note": "Vérification communautaire sur la fiche (D-056 à D-058, ticket #77). On ne confirme ni ne signale un lieu depuis la fiche : un lieu se confirme ou se signale sur place (E-07) ou après la sortie (E-15) ; depuis la fiche, on signale le parcours.", "lastCheck": { "where": "E-05, sous la ligne d'une étape stale, repliée ou dépliée ; jamais répétée dans le détail, qui n'a alors pas de ligne « Vérifié par… »", "icon": "seal-check (green-ink)", "iconSize": "icon-s", "text": "13/18 500 muted", "copy": [ "Dernière vérification il y a {n} mois", "Pas encore vérifié" ], "neverVerified": "« Pas encore vérifié », sans sceau", "cards": "rien sur les cards (E-01, E-04)" }, "routeReport": { "entry": "lien « Signaler ce parcours » sous « Voir les N avis », 14/20 600 muted, flag 16, hauteur 44", "reported": "« Vous avez signalé ce parcours », flag (fill), non cliquable", "reasons": [ [ "place_changed", "Un lieu a fermé ou a changé" ], [ "inappropriate", "Contenu choquant ou inapproprié" ], [ "dangerous_place", "Lieu dangereux ou interdit d'accès" ], [ "hidden_ad", "Publicité déguisée" ], [ "copied_content", "Photos ou textes copiés" ], [ "false_info", "Informations fausses" ], [ "other", "Autre" ] ], "list": "radios de 24 px, lignes de 48 px au moins, filet line entre deux", "otherText": 80, "placeStep": "place_changed : le bouton devient « Choisir le lieu », puis « Quel lieu ? » (étapes en radios avec pastille de catégorie, retour caret-left), précision facultative de 80 caractères, « Envoyer »", "privacy": "Lu seulement par l'équipe Widoo. Le créateur ne sait pas qui a signalé.", "toast": [ "success", "Merci, c'est signalé.", "L'équipe Widoo va regarder ce parcours." ], "states": { "signedOut": "sheet E-10 « Connectez-vous pour signaler ce parcours », « Le compte est gratuit. Il nous aide à écarter les faux signalements. », puis reprise sur les motifs, rien de choisi", "sendDisabled": "« Envoyer » en #E8E7E2, texte muted, tant qu'aucun motif n'est choisi (et sans texte pour « Autre »)", "alreadyReported": "« Vous avez signalé ce parcours le {date} », flag (fill), non cliquable, 7 jours ou jusqu'à la décision de l'équipe ; ensuite le lien revient", "offline": "signalement gardé sur le téléphone, envoyé au retour du réseau ; toast info « Signalement enregistré », « Il partira au retour du réseau. » ; la ligne « Vous avez signalé ce parcours » s'affiche tout de suite", "ownRoute": "pas de lien sur ses propres parcours" } }, "reporterNotice": "notification quand un signalement (lieu ou parcours) mène à une correction : « Merci pour votre signalement », puis ce qui change ; rien quand il n'est pas retenu", "fieldWork": { "where": "E-09 et E-16, section « Sur le terrain » entre les anecdotes et les parcours ; absente à zéro", "count": "lieux distincts confirmés sur place (E-07) ou après la sortie (E-15)", "card": "surface, radius 16, padding 14/16", "disc": "44, bg, seal-check (green-ink) 22", "title": "15/20 700", "text": "13/18 500 muted", "copy": [ "{n} lieux vérifiés sur place", "Confirmés pendant vos sorties. Les prochains visiteurs savent à quoi s'attendre.", "Confirmés pendant ses sorties. Les prochains visiteurs savent à quoi s'attendre." ] }, "placeRepeat": "pendant une sortie (E-07, E-15), « Tout allait bien ici ? » est reposé même pour un lieu confirmé il y a moins de 7 jours ; la réponse est acceptée mais ne compte pas (D-057)", "largeText": { "lastCheck": "passe à la ligne, jamais coupée ; le sceau s'aligne sur la première ligne (margin-top 4 au réglage de référence)", "routeReport": "sheet des motifs plus haute que l'écran : sous la barre d'état, contenu qui défile au-dessus d'un fondu de 32 px, « Envoyer » collé (accessibility.tallSheet, scrollEdge) ; « Quel lieu ? » garde sa hauteur tant qu'il tient", "fieldWork": "texte sur plusieurs lignes, disque de 44 px fixe, en haut de la carte", "screenReader": "la ligne « Dernière vérification » est dite dans le libellé de l'étape et masquée seule ; motifs et lieux en groupes radio ; « Envoyer » estompé tant qu'aucun motif n'est choisi ; toasts annoncés (status) ; « Sur le terrain » en un seul élément" } }, "firstLaunch": { "note": "Premier lancement (E-18, ticket #185, D-060 et D-061). Rien n'est demandé avant d'être utile ; jamais deux fenêtres l'une sur l'autre.", "order": [ "splash", "location", "analyticsConsent" ], "logo": { "source": "design/design-system/logo-widoo.svg", "background": "blue-on-strong (#5A7FCF)", "stroke": { "width": 126.013, "cap": "round", "gradient": [ "#FAF9F6", "#BFD7EA" ] }, "shadow": "8,7 px, flou 13, noir à 12 %", "squareRadius": 218, "rule": "Toute reprise du logo part de ce fichier ; les deux branches du W sortent du cadre. À l'export, retirer shape-rendering=\"crispEdges\"." }, "appIcon": { "ios": { "size": 1024, "alpha": false, "corners": "carrés (iOS pose son masque)" }, "iosDark": { "background": "transparent", "stroke": [ "#C9D6F5", "#6F8FD8" ], "shadow": true }, "iosTinted": { "background": "transparent", "stroke": [ "#FFFFFF", "#8E8E93" ], "shadow": false }, "androidAdaptive": { "background": "#5A7FCF", "layerDp": 108, "visibleDp": 72, "safeZoneDp": 66, "foreground": "le W au cadrage du logo, branches au-delà du calque" }, "androidMonochrome": { "shadow": false } }, "splash": { "background": "#5A7FCF", "framing": "carré du logo à la largeur de l'écran, centré ; les deux branches sortent de l'écran", "darkMode": "identique", "statusBar": "claire", "fadeOutMs": 200, "until": "carte prête, au plus tard 2 s ; ensuite l'accueil en chargement (E-01)", "iosImage": "W seul, fond transparent, 1290 × 2796, cover", "android12": { "icon": "icône adaptative dans le disque de 192 dp", "windowBackground": "blue (#4E74C8)", "secondScreen": false }, "maxMs": 2000 }, "home": { "withoutAccount": { "greeting": "Bonjour", "signIn": "sign-in (ouvre E-10)", "quickFilters": "aucun actif" } }, "location": { "when": "premier affichage de la carte", "prompt": "fenêtre du système, sans écran avant", "usage": "Widoo s'en sert pour centrer la carte sur vous, trier les parcours par distance et vous guider pendant une sortie. Elle n'est jamais enregistrée sur nos serveurs.", "scope": "quand l'app est active", "denied": "E-01, accueil sans position" }, "analyticsConsent": { "when": "carte centrée (sur Paris si la position est refusée)", "component": "sheet sur l'accueil, sans poignée, non fermable sans choix", "title": "Mesure d'audience", "link": "Politique de confidentialité (arrow-square-out, page web dans l'app)", "buttons": { "refuse": { "label": "Refuser", "background": "surface", "text": "ink" }, "accept": { "label": "Accepter", "background": "blue", "text": "on-blue" }, "height": 48, "order": "Refuser à gauche, Accepter à droite" }, "beforeChoice": "seuls les rapports de plantage partent", "withdraw": "Réglages › Confidentialité (E-19, D-063) : interrupteur, coupure sans confirmation" }, "reminderPermission": { "when": "premier « Programmer » (E-06), autorisation jamais demandée ; une seule fois", "component": "sheet sur la fiche, avec poignée", "icon": "bell (fill, blue-ink) dans un disque blue-soft de 64 px", "title": "Recevoir un rappel ?", "text": "Nous vous prévenons la veille à 18:00, puis une heure avant le départ.", "primary": "Activer les rappels (blue, 52 px) → fenêtre du système", "secondary": "Plus tard (texte, 48 px)", "after": "toast « Sortie programmée »", "off": { "where": "E-08 › Votre sortie, à la place de la ligne des rappels", "icon": "bell-slash (muted)", "text": "Rappels désactivés", "action": "Activer (blue-ink) : fenêtre du système si jamais montrée, sinon réglages de Widoo dans le téléphone" } }, "systemDialogs": "iOS dessinées ; Android : boîtes du système du même rôle, non dessinées", "states": { "offlineFirstLaunch": { "map": "fond uni #F0EFEC, sans rues ni marqueurs", "header": "wifi-slash + « Hors connexion », ni quartier ni météo", "sheet": "gabarit des états de E-01 : icône offline, « Pas de connexion », « Widoo a besoin d'internet pour charger les parcours autour de vous. », « Réessayer »", "retry": "recharge seul au retour du réseau", "location": "demandée quand même" }, "consentTiming": "après le premier accueil chargé, à ce lancement ou au suivant ; jamais sur un état d'erreur ou hors connexion ; rien n'est envoyé d'ici là", "approximateLocation": { "zone": "blue à 12 %, bord blue plein 1,5 px (3,92:1 sur la carte)", "header": "Autour de {quartier}", "banner": false, "preciseRequest": "au lancement d'une sortie (E-07), pour cette sortie seulement : « Pour vous guider d'une étape à l'autre pendant cette sortie. »" }, "privacyOffline": { "removed": "D-063", "reason": "textes légaux en écrans natifs, gardés dans l'app : la politique s'ouvre hors connexion, sans toast" }, "analyticsOff": { "switch": "piste #7F8A9C", "toast": "info", "title": "Mesure d'audience coupée", "text": "Plus aucune donnée d'usage n'est envoyée.", "on": "toast « Mesure d'audience activée », sans second texte" }, "notificationsOff": { "settingsRow": "valeur « Désactivées » (muted) sur la ligne Notifications des Réglages", "outing": "E-08 « Rappels désactivés » + « Activer »", "sheetAgain": false } }, "largeText": { "rule": "D-046 : ×1,353, titres de 22 px et plus à 1,2 ; barre d'état fixe ; barre collée, toast, chips et barre d'onglets à 1,3", "consent": "la sheet grandit et tient dans l'écran ; Refuser et Accepter côte à côte, 48 px au moins ; au-delà, règle des sheets hautes", "reminder": "texte sur deux lignes, boutons pleine largeur", "offline": "la sheet d'état monte (haut à 408 px) pour garder « Réessayer » au-dessus de la barre d'onglets", "outing": "« Rappels désactivés » sur une ligne, « Activer » à droite", "settings": "libellé et aide sur deux lignes, interrupteur centré" }, "screenReader": { "consent": "dialogue, focus sur le titre ; le geste d'échappement ne ferme pas (choix demandé)", "reminder": "dialogue, focus sur le titre ; geste d'échappement = Plus tard", "signIn": "« Se connecter, bouton »", "approximateZone": "« Votre position, approximative »", "activate": "« Activer les rappels, bouton » (Votre sortie)", "analyticsSwitch": "« Mesure d'audience, interrupteur, activé. Aide à améliorer l'app. »", "toasts": "annoncés sans déplacer le focus" } }, "settings": { "note": "Pages des Réglages (E-19, ticket #186, D-062 et D-063). Pages poussées (M-03), sans barre d'onglets, titre court identique à la ligne des Réglages.", "email": { "change": "par lien de confirmation envoyé à la nouvelle adresse ; l'ancienne reste active jusqu'au clic", "resendAfterS": 30, "pending": { "background": "blue-soft", "icon": "envelope-simple-open (blue-ink)", "actions": "« Renvoyer dans 30 s » (muted) et « Annuler » (blue-ink), centrés, 120 px d'écart (retouche d'Ilan)", "screenReader": "Annuler le changement d'adresse" }, "errors": { "inUse": "Cette adresse est déjà utilisée par un autre compte Widoo.", "format": "Vérifiez l'adresse : elle semble incomplète.", "offline": "Hors connexion : reconnectez-vous pour changer d'adresse." }, "appleRelay": "Masquée par Apple" }, "signIn": { "editable": false, "disc": 44, "apple": "logo Apple officiel (image de « Continuer avec Apple », E-10), blanc sur disque ink ; jamais apple-logo de Phosphor", "google": "G du kit Google sur disque blanc", "email": "envelope-simple sur disque blanc" }, "notifications": { "rowHeight": 64, "default": true, "types": [ { "key": "reminders", "label": "Rappels de sortie", "icon": "notif-reminders" }, { "key": "next_day", "label": "Le lendemain d'une sortie", "icon": "notif-next-day" }, { "key": "my_routes", "label": "Vos parcours et signalements", "icon": "notif-my-routes" } ], "phoneOff": "encart surface en status (notifications-off), « Ouvrir les réglages » ; interrupteurs inactifs à 40 %, état gardé" }, "language": { "options": [ "device", "fr", "en" ], "default": "device", "rowHeight": 56, "flags": { "size": 28, "shape": "rond", "ring": "ink à 12 %", "format": "svg", "fr": "tricolore", "en": "Union Jack" }, "phone": "phone-language (16 px) dans un disque surface de 28 px", "labels": "dans la langue de l'interface, nom natif en petit dessous (lang balisé)", "apply": "tout de suite, sans redémarrer", "routes": "traduits automatiquement, version d'origine disponible (D-063)" }, "privacy": { "row": "privacy-settings, dans Préférences, à la place de l'interrupteur Mesure d'audience", "sections": [ "Mesure d'audience (sans titre de section)", "Vos données", "En savoir plus" ], "export": { "button": "surface, export-data, 48 px", "busy": "Préparation du fichier… (loading)", "file": "widoo-donnees-AAAA-MM-JJ.json", "delivery": "feuille de partage du téléphone", "offline": "bouton skeleton inactif + texte muted" }, "withoutAccount": "pas d'export : « Sans compte, Widoo ne garde aucun profil sur vous : vos réglages restent sur ce téléphone. »" }, "legal": { "render": "écran natif, texte servi par l'API et gardé dans l'app, copie livrée avec l'app", "type": { "title": "26/32 800", "updated": "13/18 500 muted", "heading": "17/22 800", "body": "15/22 400 ink" }, "summary": "encart surface, rayon 16, « L'essentiel » (politique)", "headerTitle": "vide au repos, monte au défilement" }, "support": { "topics": [ "question", "problem", "data", "other" ], "topicChip": 36, "messageMax": 1000, "attach": [ "appVersion", "device" ], "sent": "toast success « Message envoyé »", "error": "toast error « Envoi impossible », « Réessayer »" }, "withoutAccount": { "rows": [ "language", "privacy", "legal", "help" ], "card": "« Vous n'êtes pas connecté », bouton blue vers E-10" }, "largeText": { "cap": { "pageBar": 1.3, "toast": 1.3, "chips": 1.3, "titles": 1.2 }, "fixed": [ "icônes 22 px", "drapeaux et disque 28 px", "interrupteurs", "radios" ], "pending": "actions l'une sous l'autre quand elles ne tiennent plus", "legal": "titre 31 px, texte 20/30, page qui défile", "screens": 6 } }, "update": { "note": "E-20 (ticket #186, D-063). Versions minVersion et recommendedVersion de GET /config, par plateforme.", "forced": { "background": "blue (#4E74C8), pas blue-on-strong : texte blanc à 4,51:1", "mark": "W du logo source, carré à la largeur de l'écran, centre à 350 px (la branche droite passe à 8 px sous la batterie, D-065)", "title": "28/34 800 blanc", "body": "16/24 500 blanc", "button": "blanc, texte blue-ink, 52 px", "exit": false, "statusBarClearance": 8 }, "recommended": { "component": "sheet fermable sur l'accueil chargé", "icon": 64, "button": "blue, 52 px", "later": "Plus tard, 48 px", "frequency": "une fois par version", "never": "au-dessus de la mesure d'audience ou des rappels" }, "largeText": { "forced": "titre 34 px (1,2), texte 22/32 ; W fixe tant que l'écart au texte reste ≥ 24 px (95 px au plus grand réglage standard, 150 px à la taille normale)", "recommended": "titre sur deux lignes, icône 64 px, boutons pleine largeur" } }, "mapLabels": { "note": "Noms de quartiers sur la carte (D-071, #167).", "font": "Plus Jakarta Sans 800, téléversée dans le compte Mapbox (action d'Ilan)", "case": "capitales", "letterSpacing": "0.1em", "size": 13, "color": "map-label" }, "rankingReason": { "note": "Raison du classement sur la card, tri Recommandé seulement (E-01, E-04 ; D-071, #222).", "shown": { "good_timing": { "fr": "Moment idéal", "en": "Perfect timing" }, "fresh": { "fr": "Récent", "en": "Recent" } }, "hidden": [ "top_rated", "verified", "official", "near_you" ], "placement": "à droite du budget, sur la même ligne", "style": { "size": 12, "weight": 600, "lineHeight": 16, "color": "blue-ink", "icon": null, "background": null }, "overflow": "si la ligne déborde, la card du carrousel n'affiche pas la raison ; la card de liste l'affiche toujours", "fontScale150": "seule sur la ligne sous le budget, 16 px", "screenReader": "termine le libellé unique de la card, après la distance" }, "submitLimit": { "note": "E-14, trois parcours en relecture au plus (settings.max_pending_routes, D-073)", "icon": "hourglass-medium (alert sur alert-soft)", "sub": "Votre parcours est prêt, mais il faudra attendre un peu.", "title": "3 parcours en relecture, c'est le maximum", "text": "Vous pourrez soumettre celui-ci dès que l'équipe aura répondu pour l'un d'eux, sous 72 h.", "primary": "Enregistrer en privé (blue)", "opens": "Parcours › Créés" }, "translation": { "note": "Traduction automatique des parcours et des avis (D-076, ticket #203, choix d'Ilan). Un parcours lu dans sa langue d'origine ne change pas.", "where": "E-05 : sous la description ; au-dessus des avis, sous la note ; E-07 : en bas du contenu de chaque étape, sous Ensuite", "icon": "translate", "iconSize": "icon-s", "text": "label 13/18 500 muted (E-07 : on-strong-muted)", "action": "13/18 700 blue-ink (E-07 : info-on-strong), alignée à droite ; 32 px dessinés, hitSlop 44", "layout": "rangée flexWrap, columnGap 12 ; l'action passe dessous, à droite (D-039)", "toggle": "« Voir l'original » bascule tout le parcours (fiche, étapes, parcours en cours), choix gardé sur le téléphone pour ce parcours ; avis : bascule globale, gardée pour les avis de ce parcours, indépendante", "notTranslated": "noms des lieux, étiquettes (Pour qui, Conditions, En pratique), chiffres, audio", "audio": "jamais traduit : « En {langue}, à écouter en marchant » sous le titre ; libellé « Écouter {prénom}, en {langue}, {durée} »", "offline": "un parcours lancé garde sa traduction et son original ; la bascule marche sans réseau", "copy": { "fr": { "route": "Traduit automatiquement {de la langue}", "seeOriginal": "Voir l'original", "original": "Texte d'origine, en {langue}", "seeTranslation": "Voir la traduction", "reviews": "Avis traduits automatiquement", "seeOriginals": "Voir les originaux", "reviewsOriginal": "Avis dans leur langue d'origine", "seeTranslations": "Voir les traductions", "reviewTranslated": "{date}, traduit {de la langue}", "originalShown": "Texte d'origine affiché", "translationShown": "Traduction affichée" }, "en": { "route": "Automatically translated from {language}", "seeOriginal": "See original", "original": "Original text, in {language}", "seeTranslation": "See translation", "reviews": "Reviews automatically translated", "seeOriginals": "See originals", "reviewsOriginal": "Reviews in their original language", "seeTranslations": "See translations", "reviewTranslated": "{date}, translated from {language}", "originalShown": "Original text shown", "translationShown": "Translation shown" } }, "a11y": { "seeOriginal": "Afficher le texte d'origine, en {langue}", "seeTranslation": "Afficher la traduction en {langue de l'app}", "seeOriginals": "Afficher les avis dans leur langue d'origine", "seeTranslations": "Afficher les avis traduits en {langue de l'app}", "afterToggle": "focus gardé sur le bouton ; « Texte d'origine affiché » ou « Traduction affichée » annoncé (status)", "language": "textes d'origine balisés dans leur langue (accessibilityLanguage) ; icône masquée" }, "largeText": "la ligne suit le réglage, l'action passe dessous à droite ; E-07 : « Étape suivante » de Ensuite plafonné à 1,3, deux lignes centrées, nom du lieu insécable" } } }