App Shell UI
Vous implémentez App Shell UI : une compétence de design front-end réutilisable avec deux modes. Choisissez la surface avant de choisir les pixels. Ne transformez pas chaque demande en interface de bureau, et ne transformez pas chaque application en page marketing générique.
Choisissez la surface d'abord
| Mode | Utiliser pour | Structure par défaut | Ne pas utiliser pour |
|---|---|---|---|
| Mode App | Outils connectés, paramètres, consoles, chat, email, postes de travail, flux opérationnels | Navigation latérale persistante + canevas de tâches | Marketing public, lecture, commerce ou surfaces de portfolio |
| Mode Site Web | Sites marketing, lancements de produits, portfolios, pages éditoriales, catalogues, docs, contenu public | Une macrostructure spécifique à la page sélectionnée en fonction du parcours utilisateur | Un modèle générique héros + trois cartes + CTA, ou une fausse interface d'application |
Si la demande comprend les deux surfaces, concevez-les séparément : le mode Site Web pour l'acquisition ou les informations publiques, le mode App pour le produit connecté. Partagez les jetons de marque si nécessaire, mais n'imposez pas la même mise en page ou la même densité pour les deux.
Pré-vol (les deux modes)
Avant de prendre des décisions visuelles dans un projet existant, inspectez la route et sa source
de vérité visuelle la plus proche : jetons actuels, typographie, mécanisme de thème, actifs, framework,
primitives de composants et bibliothèques d'icônes/animations installées. Préservez un système établi
sauf si l'utilisateur demande une refonte. Vérifiez package.json avant d'ajouter une dépendance ; ne
supposez pas qu'une bibliothèque existe ou ne mélangez pas deux systèmes de design non liés dans une même surface.
Si le brief est véritablement ambigu entre deux résultats matériellement différents, posez exactement une question courte. Sinon, énoncez l'inférence en une phrase et continuez. Ne transformez pas une petite demande d'implémentation en une interview d'exigences.
Flux de travail du mode App
- Choisissez un modèle de mise en page (obligatoire avant les pixels) :
- 设置型 — navigation latérale étroite + formulaire / liste de bascules
- 控制台型 — navigation latérale + grille de cartes / liste d'état
- 工作台型 — arbre de session + état vide centré + carte de composition
- IM / 三栏型 — barre d'icônes + liste + détails
- Définissez le budget du viewport — définissez le viewport de bureau cible (minimum 1280×800) et la tâche principale unique pour la route avant d'ajouter du contenu. Voir
references/layouts.md→ Viewport budget / 单页容量. - Verrouillez les jetons de thème double — utilisez
references/tokens.md(clair + sombre sont tous deux requis par défaut). - Composez à partir de recettes — utilisez
references/components.md(élément de navigation, carte, ligne de liste, bascule, pilule, vide/composeur). Les recettes sont indépendantes du thème ; seules les variables changent. - Implémentez avec des variables CSS +
data-theme="light"|"dark"; ajoutez une bascule de thème ; mappage Tailwind/shadcn optionnel. - Auto-vérification — exécutez la liste de contrôle à la fin de ce fichier dans les deux thèmes et au viewport cible avant la livraison.
Pile par défaut lorsque vous êtes libre de choisir :
| Couche | Par défaut |
|---|---|
| Balisage | HTML sémantique ou React |
| Style | Variables CSS + utilitaire léger / Tailwind |
| Composants | shadcn / style @coss (New York + neutres type zinc) |
| Icônes | Style Lucide 1,5–2 px de trait, une seule famille |
| Thème | Clair + Sombre (bascule + prefers-color-scheme OS optionnel) |
Préférez un fichier HTML unique autonome pour les démos, sauf si l'utilisateur souhaite une intégration dans un projet.
Architecture du mode App
L0 Chrome de fenêtre (feux de signalisation optionnels / barre de titre / outils en haut + bascule de thème)
L1 Barre latérale ou barre d'icônes
L2 Canevas de contenu (gris doux clair / charbon doux foncé)
L3 Surfaces (cartes surélevées, panneaux, listes)
Largeur de la barre latérale : 220–260px (navigation textuelle) ou 48–56px (barre d'icônes). Remplissage du contenu : 20–28px. Espacement sur grille de 4px.
Budget de page par défaut : l'état de bureau initial doit accomplir sa tâche principale dans un viewport après l'inclusion du chrome de l'interface. Laissez un petit espace de respiration en bas ; ne faites pas défiler verticalement toute la page juste pour révéler le contenu secondaire de routine. Les longues collections peuvent utiliser une zone de défilement interne limitée lorsque le produit en a véritablement besoin. 中文偏好:每个页面尽量一屏完成,内容达到首屏容量就停止继续堆叠。
Non-négociables du mode App
- Deux thèmes : livrez des ensembles de jetons clair et sombre sauf si l'utilisateur souhaite explicitement un seul.
- Une seule couleur primaire de marque pour : boutons primaires, bascule ON, remplissage de progression, bordure/arrière-plan sélectionné, liens. Le primaire sombre peut être un jumeau légèrement plus clair (par exemple
#007AFF→#0A84FF). - Échelle de surfaces (les deux thèmes) : fond d'application → fond de barre latérale → surface surélevée (contraste faible). Clair : gris doux + cartes blanches. Sombre : charbon doux + cartes grises surélevées — pas de page
#000pure + cartes#fffpures. - Échelle de texte : primaire / secondaire / tertiaire (valeurs différentes selon le thème).
- Hiérarchie via des bordures de 1px d'abord ; ombre optionnelle et spécifique au thème.
- Échelle de rayon : 8 / 12 / 16 / 999 (partagée entre les thèmes).
- Motif de copie : titre + une ligne de sous-titre atténué.
- Mouvement : 150–200 ms couleur/arrière-plan uniquement ; pas de théâtre de rebond.
- Bascule de thème :
data-themesur la racine + bascule visible ; persister aveclocalStoragesi possible. - Contrainte des icônes (contenu) : le contenu à droite par défaut est texte + icônes de trait + pilules d'état. Les émojis/illustrations sont des accents optionnels uniquement — jamais le défaut pour chaque ligne de liste ou carte. Préférez zéro émoji dans les listes denses ; au maximum un marqueur décoratif dans une bannière ou un état vide.
- Hauteurs égales des paires côte à côte : toute paire de contenu côte à côte (liste + composeur, panneau + panneau, statistiques sœurs qui forment une paire de cartes dans une ligne) doit partager le même bord inférieur extérieur. Utilisez grid/flex
stretch+ flex colonne +flex: 1sur les surfaces — jamaisalign-items: startqui laisse une carte courte. Voirreferences/layouts.md→ Equal-height side-by-side columns. - Budget de contenu sur un seul viewport : sur le bureau, la route par défaut ne doit pas nécessiter de défilement vertical au niveau de la page. Remplissez le canevas utilisable avec du contenu priorisé, mais arrêtez-vous avant que le premier viewport ne soit dépassé. Si le contenu ne tient pas, supprimez, raccourcissez, paginez, divulguez, onglettez ou scindez-le dans une autre route ; ne coupez jamais les contrôles et ne réduisez pas le texte en dessous de la lisibilité. Sur mobile, gardez l'action principale et l'état dans le premier viewport ; le défilement naturel est réservé au contenu vraiment long.
Mode App À faire / À ne pas faire
| À faire | À ne pas faire |
|---|---|
| Navigation latérale gauche + contenu droit | Art héros à pleine largeur comme toute l'application |
| Canevas doux + cartes surélevées dans les deux thèmes | Foncé cyber néon ou noir OLED pur par défaut |
| Accent unique (paire clair/sombre) | Icônes de navigation arc-en-ciel comme multiples primaires |
| Icônes de trait (style Lucide) dans la navigation + contenu | Ensembles d'icônes remplis et de trait mélangés |
| Cartes/listes textuelles d'abord ; pilule pour l'état | Émoji sur chaque ligne / carte / en-tête de section |
| État comme petites pilules / texte atténué | Bannières d'alerte bruyantes pleine largeur pour les états normaux |
| Bascule de thème dans le chrome | Mode sombre via filter: invert() |
| Séparation par bordures via des jetons | Couleurs de chrome #fff / #000 codées en dur |
| Espacement aéré | Conditionnement dense de type feuille de calcul |
| ≤1 accent émoji par région majeure (ou aucun) | Bannière + cartes + listes tous lourds en émojis |
| Cartes côte à côte de hauteur égale (stretch) | Un pair grand / un petit (align-items: start) |
| Route sur un seul écran avec blocs priorisés | Défilement de page illimité pour le contenu de routine |
| Défilement interne limité pour les longues collections | Masquer ou couper le contenu avec des hauteurs fixes |
Ordre d'assemblage des pages en mode App
- Shell (fenêtre + barre latérale + principal)
- Bloc de marque dans la barre latérale
- Groupes de navigation + élément actif
- En-tête de page (H1 + sous-titre atténué + actions)
- Bascule de thème dans la barre de titre ou les paramètres (obligatoire pour les démos)
- Barre d'outils optionnelle (recherche + filtre segmenté)
- Blocs de contenu par priorité : bannière → statistiques → grille/liste principale → secondaire deux colonnes. Arrêtez-vous lorsque le budget du viewport est plein ; déplacez les blocs de priorité inférieure vers des onglets, la divulgation, la pagination ou une autre route.
- Pour chaque ligne de paires deux colonnes : appliquez la recette hauteur égale (stretch + surfaces flex) sans forcer le débordement.
- Câblez l'interaction : changement de navigation, sélection, bascules, filtres, bascule de thème
Notes d'implémentation du mode App
- Mettez les jetons clairs sur
:root, :root[data-theme="light"]et les sombres sur:root[data-theme="dark"](voirreferences/tokens.md). - Les composants ne consomment que des variables — pas de hex de marque/surface codé en dur dans les règles des composants.
- Navigation sélectionnée : lavis primaire doux + texte primaire, rayon 8px (le mélange du lavis diffère selon le thème).
- Cartes :
--bg-surface+ 1px--border+ rayon 12 ; sélectionné : anneau/bordure primaire. Marque de tête = icône de trait dans une plaque atténuée ou aucune marque — pas d'émoji par défaut. - Lignes de paramètres / flux : icône de trait de 16–18px (plaque douce optionnelle) + titre + description atténuée + contrôle à droite. Évitez les icônes de liste émoji.
- Session vide / nouvelle : titre centré + grand composeur arrondi ; chips + CTA primaire. Le filigrane vide peut être une icône de trait faible ou un seul glyphe sobre — pas une pile d'émojis.
- Bannière : texte d'abord ; maximum optionnel un petit carreau d'accent (souvent aucun).
- Zone d'ajout en pointillés pour "collection vide + créer" (signe plus, pas d'émoji).
- Les boutons secondaires, les pistes de segments, les pistes de bascule OFF doivent utiliser les jetons de thème (
--secondary-btn-bg,--seg-track,--toggle-off) — le rgba gris clair ne fonctionne pas sur le sombre. - Gardez le shell de page fixe (
min-height: 0; overflow: hidden) par défaut. Si une liste, un journal, un tableau ou un historique de messages est intrinsèquement long, placez le défilement sur une région enfant limitée avec un budget de hauteur clair ; ne faites pas du corps du document ou du canevas de contenu entier le conteneur de défilement par défaut. - Validez l'état au premier chargement sur un viewport de bureau d'au moins 1280×800 (et un viewport mobile étroit). Vérifiez que la tâche principale, les contrôles et l'état sont visibles sans défilement de page et qu'aucun texte ou contrôle n'est coupé.
API de thème (canonique)
// data-theme = "light" | "dark"
// clé localStorage : "app-shell-theme"
// la bascule modifie l'attribut ; init lit le stockage puis prefers-color-scheme
Bloc de jetons CSS minimal
Copiez le bloc double-thème de references/tokens.md.
Squelette HTML minimal
<html data-theme="light">
…
<div class="window">
<header class="titlebar">
…
<button type="button" data-theme-toggle aria-label="切换深浅色">…</button>
</header>
<div class="shell">
<aside class="sidebar">…</aside>
<main class="main">…</main>
</div>
</div>
Mode App Amorce de prompt
Clair
Interface utilisateur légère de bureau macOS : barre latérale gris doux de 240px (icônes de trait + étiquette, sélectionné = lavis primaire léger + rayon 8px), canevas principal gris doux avec cartes blanches arrondies ; primaire unique #007AFF pour les boutons, bascules, progression, anneau de sélection ; trois gris de texte ; rayon 8–16px ; presque pas d'ombre, bordures claires de 1px ; lignes de paramètres/liste avec petites icônes de trait (pas d'émoji) + titre/desc + bascule droite ou pilule d'état ; zone de contenu textuelle d'abord, émoji minimal ou absent ; état vide = titre centré + grand composeur arrondi.
Sombre
Même interface en mode sombre : canevas charbon doux #1C1C1E, barre latérale #161617, cartes surélevées #2C2C2E, bordures blanc 8% alpha, texte #F5F5F7 / #A1A1A6 / #6C6C70, primaire #0A84FF, navigation sélectionnée = primaire 22% mélangé dans la surface de la carte ; pas de page noire pure ; pas de filtre d'inversion ; inclure la bascule de thème.
Échangez uniquement les noms métiers ; gardez les règles de l'interface + double thème.
Flux de travail du mode Site Web
Le mode Site Web est destiné au travail web public. Il peut utiliser le défilement normal du document et ne
doit pas hériter du canevas fixe, de la barre latérale, du chrome de fenêtre artificiel ou de la limite de
contenu sur un viewport du mode App. Lisez references/web-frontend.md avant d'implémenter le mode Site Web.
- Faites une lecture de design — indiquez le type de page, le public, la tâche principale et un ton concret. "Propre et moderne" n'est pas une direction. Déduisez du brief et de la marque existante ; posez une question courte uniquement lorsque deux directions produiraient un travail matériellement différent.
- Choisissez le mode de surface — Persuader pour une page de conversion ou un lancement, Lire pour les docs ou le contenu éditorial, Expérience pour le portfolio/galerie/événement, ou Catalogue pour naviguer et acheter. Le produit connecté reste en mode App.
- Choisissez une macrostructure avant les composants — choisissez une forme de page qui correspond à la tâche, comme la révélation de produit, l'histoire basée sur des preuves, le récit éditorial, l'index de travail, le catalogue, le guide de lecture ou l'affiche de campagne. Ne choisissez pas par défaut le héros centré -> trois cartes égales -> CTA.
- Engagez-vous sur un système visuel — verrouillez une palette, des rôles typographiques, des règles d'espacement/rayon, un traitement d'image et un différenciateur visible. Réutilisez les jetons de marque existants ; sinon, définissez des variables CSS sémantiques et consommez-les plutôt que d'improviser des couleurs ou des polices par section.
- Planifiez la vérité et les médias — utilisez des faits fournis, des captures d'écran/états de produits réels, des actifs sous licence ou des visuels bitmap générés adaptés au brief. N'inventez pas de clients, de métriques, de témoignages, de logos, de tableaux de bord factices, de chrome de navigateur ou de données de remplacement qui semblent réelles. Les affirmations inconnues restent visiblement marquées comme des espaces réservés ou sont omises.
- Construisez le parcours d'information — utilisez des repères sémantiques et une hiérarchie qui rendent la prochaine action évidente. Laissez les sections varier en composition lorsque leurs tâches diffèrent ; les cartes sont pour des éléments répétés et limités, plutôt qu'un wrapper de section de page par défaut.
- Implémentez un comportement complet — utilisez des contrôles et des liens natifs, un focus visible, un chargement,
des états vides, d'erreur, désactivés et de succès si nécessaire. Le mouvement doit expliquer le retour ou le
changement spatial, utiliser
transform/opacity, respecterprefers-reduced-motionet rester en dehors des flux à haute fréquence sauf s'il est effectivement instantané. - Inspectez le rendu de sortie — validez les captures d'écran de bureau et mobile, les extrêmes de contenu réel, le contraste, la navigation au clavier, les dimensions des images de chargement, le débordement et le premier viewport. La proposition du héros, l'action principale et le point focal visuel doivent tenir à 1280x800 ; le défilement de la page en dessous est normal pour un site web.
Non-négociables du mode Site Web
- N'enveloppez pas un site web public dans le chrome du mode App, sauf si l'utilisateur demande explicitement un aperçu de produit ou une route d'application connectée.
- Donnez à chaque public
…
[suite tronquée pour la traduction]