ADR 0024 – Mise en page « Atlas dense » de la maquette C3
Accepté (2026-10-15, mode autonome)
ADR 0024 – Mise en page « Atlas dense » de la maquette C3
Statut : Accepté (2026-10-15, mode autonome)
Le 2026-10-15, Aurélien a demandé de rapprocher très fort le design de la charte graphique, et notamment du canevas « C3 · Atlas dense Anorys ». Cette tranche passe avant les lignes du jalon 2. L’ADR 0021 avait posé les couleurs, les polices et une coquille simple. Elle avait reporté les onglets, l’arbre, la grille de propriétés, le panneau de contexte et la bascule de thème : ce sont eux que cette tranche apporte.
Décision
Coquille (app.ts), de haut en bas
- En-tête de 40 px, de gauche à droite :
- le logo, qui mène à l’accueil ;
- « Second Brain ▾ », un menu : Accueil, Nouveau nœud, Définitions, Données ;
- « Vue :
▾ », un menu des entrées de navigation, compteur de l’inbox compris ; - un faux champ de recherche, qui ouvre la palette Ctrl+K ;
- « + Capturer », un menu qui contient la capture rapide vers l’inbox (ADR 0014) ;
- Paramètres, qui contient le thème : système, clair ou sombre, mémorisé.
- Barre d’outils gauche de 40 px :
- Arborescence, Inbox et Tags affichent ou masquent le panneau gauche ;
- Favoris est désactivé, avec l’infobulle « bientôt », car il n’existe pas encore de donnée réelle ;
- en bas, les pages Accueil, Nœuds, Définitions et Données. C’est un écart à la maquette, assumé : aucune fonction de navigation n’est perdue.
- Panneau gauche de 256 px :
- Arborescence : la hiérarchie (ADR 0007), chargée niveau par niveau, en lignes de 24 px avec un caret, une pastille de type, un titre tronqué et une méta (l’état de workflow ou le nombre d’enfants). Le chemin du nœud courant est déplié et surligné. Les tags les plus utilisés suivent l’arbre ;
- Inbox : les 30 dernières captures ;
- Tags : tous les tags en usage, avec leur compte.
- Zone centrale :
- une barre d’onglets de 34 px, un onglet par nœud ouvert, gardé pour la session du navigateur et limité à 20. Une page qui n’est pas un nœud a un onglet non fermable. Fermer l’onglet affiché ouvre son voisin ; la garde des modifications non enregistrées s’applique ;
- la page.
- Panneau de contexte, de 300 à 330 px, en sections repliables (
details/summary) : Rétroliens, Liens sortants (avec ajout et retrait), Sous-nœuds (avec création et dépôt), Fichiers et Historique (les 8 derniers événements du journalnode_event). La page du nœud le renseigne par le serviceNodeContext. - Barre d’outils droite :
- Contexte du nœud affiche ou masque le panneau de contexte ;
- Graphe local est désactivé, « bientôt » ;
- Fichiers ouvre le panneau sur sa section Fichiers.
- Barre d’état de 24 px :
- l’état réel de l’enregistrement du nœud affiché : enregistré, modifié ou enregistrement en cours. En création et hors d’un nœud, la barre montre le compteur de l’inbox ;
- un résumé « type · sous-nœuds · rétroliens · fichiers », où un compte inconnu est omis ;
- le mode de l’éditeur ;
- le seul raccourci qui existe vraiment (Ctrl+K). La maquette affichait aussi Ctrl N et Ctrl / : ils ne sont pas affichés, car ils n’existent pas (et Ctrl N appartient au navigateur).
- Les panneaux sont chargés en différé (
@defer). Le bundle initial passe de 2,02 à 2,08 Mo, et l’avertissement de budget existait déjà.
Fiche d’un nœud
- Ligne de titre :
- la pastille pleine du type (28 px) ;
- le titre, un champ sans cadre en Signika 700 24 px ;
- le segment Visuel / Source, qui pilote l’éditeur Markdown (
switchModepasse par le garde-fou de l’ADR 0008) ; - les actions (déplacer, remettre dans l’inbox, corbeille) et « Enregistrer ». La maquette ne les montrait pas ; elles restent visibles pour ne rien perdre.
- Propriétés en grille de deux colonnes, avec des libellés de 96 px et des lignes de 28 px :
- le type, en puce, avec « Classer comme… » ou « Changer le type » ;
- le parent, en lien ;
- les dates de création et de modification ;
- les tags, avec une saisie compacte et les tags du contenu en puces ;
- puis, pour chaque aspect porté, un intertitre (avec retrait possible) et ses champs.
- Rendu des champs d’aspect : le wrapper Formly
sb-prop(shared/forms/prop-wrapper.ts) met le libellé à gauche, relié parfor, et le contrôle à droite. Le champ Material, en apparenceoutline, n’a pas de cadre au repos : le cadre apparaît au survol et au focus (« clic = édition »). Une valeur d’énumération, comme un statut, s’affiche en puce. - Corps : document sans cadre, avec une barre de mise en forme discrète. Les titres sont en Signika, h2 à 17 px.
- Le reste : le bloc Fichier est aplati ; le fil d’Ariane forme une barre de 26 px en bas de la zone centrale, nœud courant compris.
Accessibilité
- Arbre et onglets : simples listes de liens. L’arbre porte
aria-expandedsur le bouton de dépliage etaria-currentsur le nœud affiché. Les onglets forment une navigation avecaria-current. Les rôlestreeettablistattendent une navigation aux flèches : ils ne seront déclarés qu’avec elle. - Grille de propriétés : le libellé de gauche nomme le contrôle. C’est un
<label for>pour un champ de saisie. Une liste Material est nommée pararia-labelledby, qu’un<label for>ne nomme pas. Une case à cocher est nommée par soninput, et son propre libellé est masqué pour éviter le doublon. - Signes décoratifs : les triangles des sections et la pastille de la barre d’état ne sont pas lus.
Pastille de type (app-type-badge)
La pastille reprend l’icône du type définie dans config/. Sa couleur et sa forme viennent de data-node-type (charte-c3.css, ADR 0021) :
- projet : carré 4 px ;
- tâche : rond ;
- note : 3 px ;
- personne : rond ;
- ressource : 2 px ;
- tout autre type : neutre.
Elle existe en trois tailles (14, 16 et 28 px pleine) et sert partout : arbre, onglets, contexte, inbox, palette, titre. La liste AG Grid garde sa pastille sans icône.
Arborescence côté serveur
GET /api/nodes/tree?parent= renvoie les enfants directs de parent, hors corbeille, triés par titre et limités à 500. Sans parent, il renvoie les racines : les nœuds sans parent, et ceux dont le parent est dans la corbeille, qui restent ainsi visibles (ADR 0007). Pour chacun :
childCount, le nombre d’enfants hors corbeille ;state, la valeur du champworkflow.fielddu premier aspect porté qui déclare un workflow (ADR 0023), dans l’ordre des noms d’aspect (Workflows.stateOf). Une donnée illisible est ignorée : tolérer à la lecture.
Aucune connaissance du domaine n’est nécessaire. La section Sous-nœuds utilise aussi cet endpoint, pour afficher l’état de chaque enfant.
Petit écran (moins de 900 px)
- Les barres d’outils disparaissent. Dans l’en-tête, un bouton de menu ouvre le panneau gauche en tiroir, et un bouton « Contexte du nœud » ouvre le panneau de contexte. Le tiroir gauche commence par un sélecteur Arborescence / Inbox / Tags et par les pages.
- Le focus entre dans le tiroir ouvert et revient au bouton à la fermeture ; Échap ferme le tiroir.
- Les panneaux passent par-dessus la zone centrale, avec un fond assombri, et une navigation les referme.
- Les onglets défilent.
- Sous 600 px, le nom « Second Brain » s’efface devant le menu « Vue ».
Reporté
- Favoris et graphe local : boutons désactivés, en attendant leurs données.
- Navigation au clavier dans l’arbre (flèches) : les lignes sont aujourd’hui des liens tabulables.
- Redimensionnement des panneaux à la souris.
- Valeurs d’état affichées par leurs libellés (
x-labels, ADR 0023). - Liste et définitions refaites en lignes denses : elles prennent la coquille et des cartes plates, et leur contenu sera repris avec le moteur de vues du jalon 2.
Conséquences
- L’arbre ne relit tout qu’après un enregistrement, un déplacement ou un changement de type du nœud affiché (
NodeContext.saveVersion) ou une capture. Ouvrir un autre nœud ne charge que les niveaux d’ancêtres manquants. Une réponse plus ancienne qu’une demande en cours est ignorée. - La fiche efface
NodeContextdès qu’elle passe à un autre nœud, ferme l’onglet d’un nœud mis à la corbeille et republie le contexte après un déplacement. - La coquille lit trois services :
WorkspaceStore(panneaux, mémorisés dans le navigateur),TabsStore(onglets de la session) etNodeContext(nœud affiché). Une page qui affiche un nœud doit renseignerNodeContextet l’effacer en partant. - Les tests utilisent un stockage en mémoire (
installMemoryStorage), car jsdom n’a pas delocalStoragesans origine.