Commit Graph
278 Commits
Author SHA1 Message Date
williamandClaude Sonnet 5 6c7675fad0 Audit complet de mise en forme — Titre/Paragraphe (1er élément du tableau)
Nouveau module partagé document_engine/rendering/box_style.py
(padding/margin/background_color/border_radius/border par côté/height/
min-height/max-height/min-width/box-shadow/opacity/align_self) —
réutilisable tel quel par tous les kinds suivants du tableau d'audit.

Titre/Paragraphe gagnent : barré, police de caractère, taille de
police, hauteur de ligne, espacement des lettres, majuscules/
minuscules/capitales, ombre du texte, et tous les attributs de boîte
partagés ci-dessus. Interface entièrement à base de curseurs/cases à
cocher/listes déroulantes/sélecteurs de couleur natifs — plus aucun
champ de texte libre pour une valeur CSS (retour utilisateur).

Deux bugs transversaux corrigés au passage (concernent tout
l'éditeur) :
- Le panneau Propriétés n'était jamais reconstruit après un clic sur un
  bouton (gras/alignement/segments...) — il fallait recharger la page
  pour voir l'état réel. Corrigé dans forgeDocUpdateAttributes, point
  d'entrée unique de toute mise à jour d'attribut.
- Les cases à cocher et curseurs héritaient à tort le style d'un champ
  de texte (padding/bordure/fond/largeur 100%) via la règle générique
  .docField input.

Ajoute docs/plan/AUDIT_MISE_EN_FORME.md : suivi de l'audit élément par
élément (Titre/Paragraphe traité, Image ensuite).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 09:25:30 +02:00
williamandClaude Sonnet 5 e03bea39c5 Ajoute icône/largeur/arrondi/gras/majuscules à l'étiquette (badge)
Nouveaux attributs par élément (svg_markup/width/border_radius/bold/
uppercase, tous vides ou False par défaut = comportement historique
inchangé), réglables depuis le panneau Propriétés — même esprit que
bold/align/color déjà présents sur titre/paragraphe. Fixer une largeur
implique toujours de sortir de l'étirement pleine largeur par défaut
(align-self:flex-start posé automatiquement avec elle).

Le kicker "Module obligatoire" du thème Sécurité Incendie s'en sert
maintenant (icône flamme, largeur au contenu, arrondi complet, gras,
majuscules) pour être conforme à la maquette d'origine — la puce
décorative CSS générique qui la remplaçait disparaît du thème.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 11:36:30 +02:00
williamandClaude Sonnet 5 1296edc2f8 Ajoute une largeur maximale optionnelle aux blocs de texte (titre/paragraphe)
Nouvel attribut max_width (vide par défaut = pleine largeur, inchangé)
sur les kinds titre/paragraphe, réglable depuis leur panneau
Propriétés. Le sous-titre de la page de garde du thème Sécurité
Incendie l'utilise (60ch) pour rester conforme à la maquette d'origine,
qui ne l'étirait pas sur toute la largeur de la page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 10:39:18 +02:00
williamandClaude Sonnet 5 746feb3796 Ajoute l'alignement vertical du contenu d'une page, réglable depuis l'onglet "Pages"
Nouvelle colonne _document_pages.vertical_align (top/center/bottom,
"top" par défaut, migration incluse pour les supports existants).
Quand l'onglet "Pages" du panneau gauche est actif, le panneau
Propriétés (droite) affiche maintenant l'alignement de la page active
au lieu des propriétés d'un élément — un contrôle segmenté qui persiste
via une nouvelle route dédiée et met à jour le canevas immédiatement.

Le contenu-seed des thèmes porte désormais aussi ce réglage par page
(seed_pages devient une liste de {vertical_align, blocks} plutôt qu'une
liste de listes de blocs) : la page de titre du thème "Sécurité
Incendie" est centrée verticalement, comme demandé, cohérente avec la
maquette d'origine. L'aperçu de thème (iframe de la modale) reflète
aussi ce réglage par page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 10:24:48 +02:00
williamandClaude Sonnet 5 be62275675 Met la page entière à l'échelle dans l'aperçu de modèle, sans barre de défilement
La page a une largeur/un ratio fixes côté moteur (960px, A4 paysage) —
sans mise à l'échelle, elle débordait verticalement de la fenêtre
d'aperçu (plus petite qu'un canevas d'édition en plein écran) et
défilait/rognait au lieu de tenir entière. Un script calcule maintenant
le facteur d'échelle qui la fait toujours tenir en entier (transform:
scale, jamais un agrandissement au-delà de 1), recalculé au
redimensionnement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 10:02:47 +02:00
williamandClaude Sonnet 5 7730b3688f Corrige la modale "Utiliser un modèle" : aucune sélection par défaut, aperçu plein espace, navigation entre pages
Trois retours distincts :
- Plus de présélection du thème déjà appliqué à l'ouverture — un choix
  toujours explicite de l'utilisateur.
- L'état vide (.docTemplatePreviewEmpty) restait visible EN MÊME TEMPS
  que l'iframe une fois un thème sélectionné : `display:flex` posé
  directement dessus battait le `display:none` natif de [hidden]
  (même bug déjà rencontré pour .docSidebarTabPanel[hidden] plus tôt
  dans le projet) — les deux se partageaient flex:1, coupant l'aperçu
  en deux au lieu de lui laisser tout l'espace.
- L'aperçu ne montrait que la première page du modèle sans aucun moyen
  d'en voir les autres : la route /document/<slug>/theme/<id>/preview
  rend désormais TOUTES les pages, une barre Précédent/Suivant
  (entièrement côté client, aucun aller-retour serveur supplémentaire)
  permet de naviguer entre elles.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 09:58:31 +02:00
williamandClaude Sonnet 5 bd8f1d4b1e Modale "Utiliser un modèle" en plein écran, deux colonnes égales
Demande explicite : la modale occupe maintenant tout l'écran (100vw/
100vh, plus de padding/coins arrondis hérités de la modale générique),
divisée en deux colonnes strictement égales (grid-template-columns:
1fr 1fr) — la liste des thèmes devient une grille de cartes à gauche,
l'aperçu occupe toute la colonne de droite.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 09:43:22 +02:00
williamandClaude Sonnet 5 56afe77bd4 Corrige la modale "Utiliser un modèle" : fond transparent et aperçu minuscule
Deux bugs distincts :
- #docTemplateModal n'était jamais ajoutée au sélecteur qui définit les
  tokens --doc-* (--doc-bg-2/--doc-border/--doc-text/...) — ces tokens
  n'existaient nulle part sur elle, donc toutes les couleurs de fond de
  la modale résolvaient à rien (transparence totale). Corrigé en
  l'ajoutant à ce sélecteur (et au data-theme posé par
  forgeDocApplyTheme, pour suivre le thème clair/sombre de l'éditeur).
- .docModalDialog--wide n'avait qu'un max-height, jamais un height
  explicite : le dialogue flex se limitait à la hauteur naturelle de
  son contenu, et l'iframe d'aperçu (flex:1) retombait à sa hauteur
  intrinsèque minuscule faute de référence pour se déployer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 09:35:20 +02:00
williamandClaude Sonnet 5 09449fe911 Corrige le style du thème Sécurité Incendie — plusieurs éléments n'avaient aucune mise en page par défaut
Signalé par capture d'écran : le rendu réel ne ressemblait pas du tout
à la maquette. Causes trouvées :
- .docImage (mode SVG inline) et .docCard n'ont AUCUNE règle de mise en
  page côté moteur (seuls .docImagePlaceholder et <img class="docImage">
  en ont une) — le thème doit leur donner leur forme, pas seulement leurs
  couleurs.
- --doc-accent/--doc-accent-2 (barre de progression et survol du Quiz)
  n'étaient jamais redéfinis, gardant l'orange générique du chrome de
  l'éditeur au lieu du rouge du thème.
- Le liseré décoratif en haut de page et la puce de l'étiquette (icône)
  avaient été omis en pensant, à tort, qu'ils relevaient du FORMAT de
  .docPage — ce ne sont que des flourishes visuels, aucun rapport avec
  la taille/le format A4 paysage qui doit rester intouchable.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 09:25:32 +02:00
williamandClaude Sonnet 5 64ee7292d4 Documente document_engine/themes/ et replace_document_content, corrige la liste des sous-dossiers dans document_engine.md
document_engine.md listait encore seulement 3 sous-dossiers alors que
pages/ existait déjà avant cette session — corrigé au passage.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 09:14:29 +02:00
williamandClaude Sonnet 5 864ae697fd Ajoute le système de modèles/thèmes de document ("Utiliser un modèle")
Nouveau bouton dans le topbar de l'éditeur, à côté d'Aperçu, qui ouvre
une modale listant les thèmes du catalogue (document_engine/themes/).
Cliquer un thème charge un VRAI aperçu (rendu serveur réel dans un
iframe, jamais une resucée CSS côté client) avec le choix de garder le
contenu actuel ou de le remplacer par le contenu de démonstration du
modèle.

Architecture pensée pour une centaine de thèmes futurs : chaque thème
est une feuille de style externe (static/document/themes/<id>.css) qui
habille les classes fixes du moteur, jamais du code qui en changerait
la structure. Premier thème implémenté pour valider le mécanisme :
"Sécurité Incendie" (6 pages de contenu réel, quiz inclus).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 09:12:57 +02:00
williamandClaude Sonnet 5 a34bcf4159 Ajoute 4 mécanismes moteur manquants pour le thème sécurité incendie : étiquette, carte, image SVG inline, bouton avec pièce jointe
Contenu et mécanisme uniquement, aucun style ajouté (voir consigne du
24/09/2026) : deux nouveaux kinds de contenu (badge/carte, rendu en
div brutes sans CSS), un mode SVG inline pour l'image (svg_markup,
nettoyé par un nouveau sanitizer allow-list avant chaque rendu) et un
fichier téléchargeable joignable à un bouton (upload/download routes,
stockage sous db.support_dir). Le futur système de templates portera
l'habillage visuel de ces éléments.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 08:12:29 +02:00
williamandClaude Sonnet 5 e7c6ed7159 Ajoute les listes à puces et numérotées dans la bibliothèque de contenu
Retour utilisateur du 24/09/2026 : "dans la section contenu il manque
la possibilité d'utiliser une liste à puce ou ordonnée".

- Deux nouveaux kinds "liste_puces"/"liste_numerotee" dans
  CONTENT_KINDS, chacun sélectionnable directement dans la bibliothèque
  (comme titre/paragraphe/image/bouton) — partagent la même structure
  d'attributs (`items`, une liste de chaînes), c'est le kind lui-même
  qui décide <ul> ou <ol> au rendu (_render_list), pas un attribut
  "ordered" redondant à tenir synchronisé.
- Rendu : un <li> par item, échappé (html.escape) comme tout le
  contenu texte du document — une liste vide rend <ul>/<ol> sans
  enfant plutôt qu'un placeholder (état normal, pas une image sans
  fichier).
- Panneau Propriétés : même patron répéteur que l'Association/Memory
  (ajouter/renommer/supprimer une ligne, rechargé après chaque
  modification).
- Icônes de bibliothèque (☰/①) + style .docList (puces/numéros
  visibles, espacement entre items).

6 nouveaux tests Python (attributs par défaut, rendu <ul>/<ol>,
échappement, liste vide, route d'ajout) + vérifié par un test jsdom
dédié contre un vrai support (bibliothèque, panneau Propriétés :
ajout/modification/suppression d'item réellement fonctionnels).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 07:19:01 +02:00
williamandClaude Sonnet 5 eac45f1c9d Corrige la vraie cause du plein écran incomplet : max-height du format A4 oublié en Aperçu
Diagnostic console à l'appui (document.fullscreenElement confirmé
actif, .docEditor3/.docBodyWrap/.docCanvasArea mesurés à 960px =
window.innerHeight, mais .docPage seule à 678.78px) : ma précédente
tentative (width/height:100vh sur .docEditor3) ciblait le mauvais
niveau — toute la chaîne jusqu'à .docCanvasArea remplissait déjà
correctement l'écran. Le vrai plafond venait de max-height posé sur
.docPage pour le format A4 en édition (960 * 210/297 ≈ 678.79px,
exactement la valeur mesurée) : la règle Aperçu changeait bien
width/height/aspect-ratio mais oubliait max-height, qui continue de
gagner sur height:100% quelle que soit sa valeur. Neutralisé
(max-height:none, min-height:0) uniquement dans la règle Aperçu — le
plafond A4 reste actif en édition.

Vérifié par getComputedStyle (max-height résolu à "none" en Aperçu,
toujours actif en édition).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 07:05:30 +02:00
williamandClaude Sonnet 5 b633126a7e 3 correctifs Aperçu : bords carrés des mini-jeux, titres en noir, vrai plein écran
Capture utilisateur à l'appui du 24/09/2026.

- border-radius:0 sur toutes les cartes/boutons/cases du JOUEUR de
  mini-jeu (.docMinigame, .docQuizCard/.docQuizResultCard,
  .docQuizOption, .docQuizFeedback, .docQuizNextBtn/.docQuizRestartBtn,
  .docAssocCard, .docAssocItem/.docAssocSlot,
  .docMinigameRestartBar button, .docMemoryCardWrap/.docMemoryCardFace,
  .docMotsCell/.docMotsWordChip) — "les bord des mini jeu ne doivent
  plus etre arrondie". Le badge rond A/B (.docQuizOptionLetter, un
  cercle volontaire) et le graphe d'édition du Scénario (outil de
  configuration, pas le joueur) restent hors scope.
- Bug réel trouvé : .docQuizPlayerTitle/.docQuizQuestionText/
  .docAssocTitle (et autres titres sans `color` propre) restaient
  quasi invisibles sur la page blanche — `color` est une propriété
  HÉRITÉE, et redéfinir la custom property --doc-text sur .docPage (fait
  la session précédente) ne "recoupe" pas une couleur DÉJÀ CALCULÉE plus
  haut sur .docEditor3 (palette sombre). Ajoute color:var(--doc-text)
  explicitement sur .docPage, qui relance la résolution avec la bonne
  valeur locale pour tout descendant sans `color` propre.
- La page ne remplissait pas toute la hauteur en Aperçu (bande noire en
  bas) : .docEditor3 s'appuie sur flex:1 1 auto pour sa taille, valide
  seulement comme enfant d'un flex container normal — une fois
  réellement en plein écran (peint hors du flux normal par le
  navigateur), ce mécanisme perd son contexte. width/height explicites
  en secours sur .docEditor3:fullscreen et .docEditor3.docEditor3--preview.

Vérifié par getComputedStyle (border-radius à 0, --doc-text résolu en
sombre au niveau de .docPage, dimensions 100vw/100vh en preview).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 06:45:17 +02:00
williamandClaude Sonnet 5 fff098c60c Style des mini-jeux revu pour la page blanche fixe
Retour utilisateur du 24/09/2026 : "le style des mini jeux dois etre
revue pour etre sur fond blanc" — les cartes/options/boutons des
mini-jeux (Quiz/Association/Memory/Mots mêlés/Scénario) s'appuient sur
les tokens --doc-* (--doc-card, --doc-bg-2, --doc-text, --doc-border,
succès/échec du Quiz), sombres par défaut et assortis au CHROME de
l'éditeur plutôt qu'à la page. Redéfinit ces tokens dans le scope de
.docPage avec les mêmes valeurs déjà établies pour
.docEditor3[data-theme="light"] (palette claire déjà conçue et
éprouvée dans ce fichier, pas une troisième version inventée) : la
page étant désormais toujours blanche, son contenu utilise toujours
cette palette, peu importe le thème choisi pour le chrome autour.

Vérifié par getComputedStyle (tokens résolus en valeurs claires dans
le scope de .docPage).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 06:32:30 +02:00
williamandClaude Sonnet 5 71e6302503 La page du document est blanche fixe, en édition ET en Aperçu
Retour utilisateur du 24/09/2026 : "je veux que la page dans l'éditeur
et l'apercu soi blanche comme dans tous éditeur normale" — .docPage
utilisait var(--doc-card), qui suit le thème clair/sombre de
L'ÉDITEUR (chrome autour), pas de la page elle-même. Passe à #fff
fixe. Redéfinit --forge-text/--forge-text-muted dans le scope de
.docPage (le texte de contenu par défaut écrit color:var(--forge-text)
en style inline, qui vaut #e8ecf4 quasi blanc partout ailleurs dans le
site — illisible sur blanc sans cette redéfinition locale). Les
mini-jeux (options quiz, cartes association...) restent lisibles sans
changement : ils ont chacun leur propre fond sombre (--doc-bg-2),
indépendant du fond de la page. Vérifié par getComputedStyle.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 06:26:45 +02:00
williamandClaude Sonnet 5 7cb8986f58 Empêche le contenu de se compresser pour tenir sur la page — il doit déborder pour déclencher la pagination
Capture utilisateur à l'appui du 23/09/2026 : en ajoutant un 3e bloc,
les images (pourtant height:190px) rétrécissaient visiblement au lieu
d'aller sur une nouvelle page. Cause réelle : flex-shrink vaut 1 par
défaut pour tout enfant flex — une fois .docPage plafonnée en hauteur
(commit précédent), les enfants top-niveau de .docPageContent se
compressaient tous pour continuer à tenir, sans jamais réellement
déborder. Sans ce débordement réel, forgeDocCheckPageOverflow
(scrollHeight vs clientHeight) ne détectait jamais rien à paginer.
flex-shrink:0 sur .docPageContent > [data-element-id] : le contenu
garde sa taille naturelle et déborde franchement quand il n'y a plus
de place, ce qui déclenche la pagination automatique.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 12:04:46 +02:00
williamandClaude Sonnet 5 6056a263da La page ne grandit plus verticalement avec son contenu ; les mots trop longs se coupent
- .docPage n'avait que aspect-ratio pour dériver sa hauteur depuis sa
  largeur — insuffisant en pratique : la page grandissait pour
  accueillir tout le contenu au lieu de le clipser (overflow:hidden)
  et laisser forgeDocCheckPageOverflow gérer la pagination (retour
  utilisateur du 23/09/2026 : "le contenu ne dois jamais s'adapter
  verticalement"). Ajoute un filet de sécurité : max-height calculé
  explicitement (calc() à partir d'une nouvelle variable
  --doc-page-width, source unique partagée avec width et le mode
  aperçu à largeur fixe) + min-height:0 explicite, qui plafonnent
  la hauteur quoi qu'il arrive.
- .docText n'avait aucune gestion de mot trop long sans espace —
  débordait hors de la page au lieu de se couper (retour utilisateur
  du 23/09/2026 : "les élément paragraphe ne vont pas a la ligne").
  Ajoute overflow-wrap:break-word (jamais word-break:break-all, qui
  casserait aussi les mots normaux sans raison).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:56:10 +02:00
williamandClaude Sonnet 5 c6e173589f Pagination automatique : le contenu qui déborde part sur une nouvelle page
Retour utilisateur du 23/09/2026 : "si il n'y a plus de place sur la
page il faut automatiquement créer une autre page [et y] coller le
contenu et amener l'utilisateur sur la page" — remplace le
comportement précédent (overflow:hidden, contenu clipsé, à gérer
manuellement).

- Nouvelle capacité serveur : document_engine.move_document_element_to_page
  (+ route POST /document/<slug>/elements/<id>/move-to-page) déplace un
  élément (et ses enfants de rangée en cascade) vers une AUTRE page —
  jusqu'ici move_document_element ne gérait que le réordonnancement DANS
  la même page.
- Client : forgeDocCheckPageOverflow, appelée à la fin de CHAQUE
  forgeDocRefreshCanvas (point d'entrée unique après toute mutation) :
  mesure le débordement réel (scrollHeight vs clientHeight), trouve le
  premier élément top-niveau qui dépasse le bas de la page
  (getBoundingClientRect, tient compte du zoom), déplace cet élément et
  tout ce qui le suit vers une page neuve, puis y bascule l'utilisateur.
  Jamais déclenché sur une page mini-jeu (toujours seule sur sa page,
  aucun débordement pertinent à corriger).

Vérifié par un test jsdom dédié (géométrie simulée via
getBoundingClientRect/scrollHeight/clientHeight, jsdom n'ayant pas de
vrai moteur de mise en page) : ordre des déplacements, page inchangée
si le contenu tient, page mini-jeu jamais scindée. 6 nouveaux tests
Python (document_engine + route). 711/711 tests passent.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:50:23 +02:00
williamandClaude Sonnet 5 0e8c6efb06 Retire l'espace entre le cadre du mini-jeu et le bord de sa page
Précision utilisateur du 23/09/2026 : pas les marges du canevas
(déjà annulées, "remet la page comme elle était") mais celles À
L'INTÉRIEUR de la page — le padding:24px posé sur .docQuizPlayer/
.docAssocPlayer/.docMemoryPlayer/.docMotsPlayer/.docScenarioPlayer
lors du centrage créait un espace visible entre le composant
(.docAssocCard etc.) et le bord de .docPage. Retiré : la carte touche
désormais les 4 bords de la page (son propre padding interne, 1.8rem,
reste intact pour la lisibilité de son contenu).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:29:33 +02:00
william cf349be030 Revert "Retire les marges du canevas autour d'une page mini-jeu, même hors Aperçu"
This reverts commit 7a0efe5c63.
2026-09-23 11:26:05 +02:00
williamandClaude Sonnet 5 7a0efe5c63 Retire les marges du canevas autour d'une page mini-jeu, même hors Aperçu
.docCanvasArea gardait son padding confortable (36px 40px) autour
d'une page mini-jeu en mode édition — seul .docPage lui-même (son
padding interne) avait été mis à plat jusqu'ici. Nouvelle règle
:has() conditionnée à la présence d'un mini-jeu, jamais globale : une
page de contenu normal garde ses marges habituelles. Vérifié par
getComputedStyle (0 avec mini-jeu, 36px 40px sans).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:22:36 +02:00
williamandClaude Sonnet 5 20ee8ef35b Aperçu en plein écran réel, sans espace autour du mini-jeu, contenu aligné en haut
- Mode Aperçu bascule désormais en VRAI plein écran (Fullscreen API,
  forgeDocSetPreviewMode) au lieu d'un simple agrandissement CSS —
  contourne d'un coup le clipping par overflow:hidden de main.content
  documenté ailleurs dans ce fichier. .docTopbar est masqué comme le
  reste du chrome ; un nouveau bouton flottant .docPreviewExitBtn
  (visible seulement en Aperçu) permet de revenir à l'éditeur, en plus
  d'Échap (natif, resynchronisé via fullscreenchange).
- .docCanvasArea perd son padding et .docPage abandonne son format A4
  fixe en Aperçu (width/height:100%, aspect-ratio:unset) — le mini-jeu
  remplit tout l'écran, sans bordure vide autour (retour utilisateur
  du 23/09/2026 : "il doit prendre toute la place").
- Le contenu des cartes de mini-jeu (.docQuizCard/.docAssocCard/
  .docMemoryCardWrap) passe de justify-content:center à flex-start —
  aligné en haut, pas centré verticalement (retour utilisateur du
  23/09/2026 : "le contenu aligner en haut").

Vérifié par getComputedStyle dans les deux modes (padding/aspect-ratio
de la page, visibilité du bouton de sortie et du bandeau, alignement
du contenu, gating pointer-events des mini-jeux — tout reste cohérent
simultanément).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:18:12 +02:00
williamandClaude Sonnet 5 152d10fc33 Retire complètement le badge (nom/"2 paires") d'une page mini-jeu plein-page
Le badge (.docMinigameBadge) restait visible au-dessus du joueur même
quand le mini-jeu occupe seul toute la page — retour utilisateur du
23/09/2026 : "ces éléments [...] doivent disparaitre et le composant
mini jeu pren toute la place". display:none (au lieu d'un simple
flex-shrink:0) : le joueur récupère toute la hauteur libérée. Vérifié
par getComputedStyle (badge display:none, joueur flex-grow:1,
gating pointer-events/plein-cadre de la page toujours corrects).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:08:05 +02:00
williamandClaude Sonnet 5 fadddb7113 Le mini-jeu remplit toute la hauteur/largeur du document, pas juste une carte centrée
Retour utilisateur du 23/09/2026 : une carte à largeur confortable
(même centrée) ne suffisait pas, "le mini jeu dois prendre toute la
hauteur et la largeur du document". Retire le max-width des cartes
internes (.docQuizCard/.docQuizResultCard/.docAssocCard/
.docMemoryCardWrap) — leur fond/bordure couvre désormais toute la
page (width:100% + align-items:stretch côté joueur pour la hauteur) —
et centre leur CONTENU à l'intérieur via display:flex +
justify-content:center sur la carte elle-même, plutôt que de le
laisser collé en haut d'une grande surface vide. Vérifié par
getComputedStyle (max-width devient bien "none", pointer-events et
plein-cadre de la page toujours corrects dans les deux modes).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:03:33 +02:00
williamandClaude Sonnet 5 82223171a9 Centre le contenu des mini-jeux plein-page au lieu de le laisser tassé en haut
Le joueur (.docQuizPlayer/.docAssocPlayer/.docMemoryPlayer/
.docMotsPlayer/.docScenarioPlayer) remplissait déjà toute la hauteur
de la page (flex:1) mais sa carte interne restait en flux normal,
collée en haut-gauche — passage du joueur en display:flex + centrage,
avec une largeur confortable (max-width) sur les cartes internes
plutôt qu'un étirement bord à bord. Vérifié par getComputedStyle
(display:flex/centrage du joueur, max-width de la carte, gating
pointer-events et plein-cadre de la page toujours corrects).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 10:58:46 +02:00
williamandClaude Sonnet 5 33d90e896e Les mini-jeux restent visibles en édition, jouables seulement en Aperçu
Le joueur réel (Quiz/Association/Memory/Mots mêlés/Scénario) n'est
plus display:none hors Aperçu — visible en permanence, édition ET
Aperçu, et occupe toute la page dans les deux modes (déjà garanti
depuis la règle plein-cadre :only-child, vérifié inchangé). Seule
l'interactivité (répondre/glisser/retourner une carte) reste réservée
au Mode Aperçu, via pointer-events:none par défaut / auto en Aperçu —
remplace l'ancien display:none/block qui masquait tout hors Aperçu.
Vérifié par getComputedStyle (display/pointer-events dans les deux
modes, padding/border-radius plein-cadre toujours à 0 en Aperçu).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 10:47:21 +02:00
williamandClaude Sonnet 5 1a80cb32b5 Page au format A4 paysage à taille fixe ; un mini-jeu occupe toute la page à lui seul
- .docPage passe à une taille FIXE (960px, ratio A4 paysage 297:210
  via aspect-ratio) au lieu de grandir avec le contenu, et
  overflow:hidden — le contenu qui dépasse ne défile plus, au
  créateur de le répartir sur une autre page (comme une vraie
  diapositive, jamais de reflow automatique).
- Un mini-jeu ne peut plus partager sa page avec un autre élément, ni
  l'inverse : vérifié côté serveur (routes/document/
  document_element_add.py, point d'entrée unique de tout ajout),
  jamais dupliqué côté client qui se contente d'afficher l'erreur
  renvoyée (forgeDocApiAdd). Un mini-jeu ne peut pas non plus rejoindre
  une rangée. 4 nouveaux tests de non-régression.
- CSS : quand un mini-jeu est l'unique enfant de la page
  (.docPageContent > .docMinigame:only-child, invariant garanti par le
  serveur), il s'étire en plein cadre (padding de la page à 0, coins
  non arrondis, joueur en flex:1).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 10:36:10 +02:00
williamandClaude Sonnet 5 60047a3658 Corrige le trait de l'onglet actif : il suivait des coins arrondis au lieu d'être plat
Le <button> générique Bulma (static/style.css) pose
border-radius:var(--bulma-control-radius) sur TOUT bouton, jamais
annulé par notre seule déclaration border-bottom (la cascade CSS
s'applique propriété par propriété, pas règle par règle) : le trait
du bas remontait donc visiblement sur les côtés au lieu de rester
plat. Ajoute border-radius:0 explicite sur .docSidebarTab. Vérifié
via getComputedStyle (border-radius devient bien 0px).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 10:16:50 +02:00
williamandClaude Sonnet 5 2de22ff674 Ajoute un padding au conteneur de la liste de pages
Espace autour des rangées, notamment à droite pour ne pas coller la
barre de défilement fine au texte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 10:10:22 +02:00
williamandClaude Sonnet 5 47c0f9e85c Barre de défilement fine et discrète pour la liste de pages
scrollbar-width:thin/scrollbar-color (Firefox/Chromium récents) +
::-webkit-scrollbar (WebKit/Blink plus anciens) sur .docPageManagerList
au lieu de la barre large par défaut du navigateur.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 10:03:03 +02:00
williamandClaude Sonnet 5 763d26c1f1 Ajuste l'onglet Pages : bouton d'ajout fixe en haut, retire les flèches de réordonnancement, style d'onglet simplifié
- "+ Ajouter une page" passe avant la liste et reste toujours visible
  (flex-shrink:0), seule la liste défile désormais.
- Retire les boutons ↑/↓ par rangée : le glisser-déposer suffit pour
  réordonner, ce qui laisse plus de place à l'affichage du nom de la
  page. forgeDocMovePage devient mort (plus aucun appelant) et est
  supprimé.
- Style de l'onglet actif simplifié : seul le border-bottom change de
  couleur, le texte reste neutre (plus de changement de couleur du
  libellé).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 09:33:45 +02:00
williamandClaude Sonnet 5 b8e7a4c672 Corrige les onglets du panneau gauche : les deux panneaux restaient visibles en même temps
.docSidebarTabPanel { display:flex; } (règle auteur) gagnait
systématiquement sur le display:none natif de l'attribut [hidden]
(règle du navigateur) — l'origine "auteur" l'emporte toujours sur
l'origine "navigateur" en cascade CSS, peu importe l'ordre des
règles ou leur spécificité. forgeDocSwitchSidebarTab posait bien
l'attribut hidden (vérifié par un test jsdom qui, lui, ne teste que
la propriété DOM .hidden — angle mort qui a laissé passer ce bug),
mais son effet visuel était annulé : les deux onglets ("Pages" et
"Mise en page") s'affichaient empilés en permanence. Ajoute
.docSidebarTabPanel[hidden] { display:none; } pour reprendre la main.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 09:20:03 +02:00
williamandClaude Sonnet 5 b4e4e80b7c Panneau gauche à onglets : "Pages" (gestion complète) et "Mise en page" (bibliothèque)
Build and deploy / test-python (push) Successful in 10m10s
Build and deploy / test-js (push) Successful in 51s
Build and deploy / lint-python (push) Successful in 4m44s
Build and deploy / lint-js (push) Failing after 1m27s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 4m8s
Remplace le carrousel une-page-à-la-fois par un panneau dédié plein
hauteur : liste verticale scrollable de toutes les pages, réordonnage
par glisser OU boutons haut/bas (accessibilité clavier), renommer
(crayon, édition en ligne), supprimer (protégé contre la suppression
de la dernière page), ajouter. La bibliothèque d'éléments passe dans
un second onglet "Mise en page", contenu inchangé. "Mise en page"
actif par défaut au chargement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 09:03:21 +02:00
williamandClaude Sonnet 5 14ca9e32a8 Élargit le carré de page pour occuper toute la largeur disponible
Build and deploy / test-python (push) Successful in 5m54s
Build and deploy / test-js (push) Successful in 49s
Build and deploy / lint-python (push) Successful in 3m49s
Build and deploy / lint-js (push) Failing after 1m17s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 3m43s
.docPageListItem/.docPageListSquare passent en width:100% (le carré
suit via aspect-ratio:1) au lieu d'une taille fixe étroite ; les
flèches ‹/› de navigation s'étirent en hauteur (align-items:stretch)
pour accompagner la carte désormais plus haute.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 15:20:08 +02:00
williamandClaude Sonnet 5 e33b11458c Bande de pages : un seul carré visible (la page active), les flèches changent de page
Build and deploy / test-python (push) Successful in 9m16s
Build and deploy / test-js (push) Successful in 51s
Build and deploy / lint-python (push) Successful in 4m11s
Build and deploy / lint-js (push) Failing after 1m23s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 4m14s
Remplace le bandeau scrollable multi-cartes par un vrai carrousel
une-page-à-la-fois : un seul carré affiché (la page active), les
grandes flèches ‹/› aux extrémités changent directement la page
affichée (au lieu de juste faire défiler la vue). Les petites flèches
←/→ au-dessus du carré restent pour réordonner la page active parmi
ses sœurs, sans changer l'affichage — distinctes des flèches de
navigation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 15:08:09 +02:00
williamandClaude Sonnet 5 a2b95bd547 Améliore l'UX de la bande de pages : carré + nom en dessous, flèches précédent/suivant, défilement au survol
Build and deploy / test-python (push) Successful in 7m22s
Build and deploy / test-js (push) Successful in 51s
Build and deploy / lint-python (push) Successful in 5m15s
Build and deploy / lint-js (push) Failing after 1m14s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 5m23s
Chaque carte devient carré (numéro) + nom tronqué SOUS le carré, avec
les actions (réordonner/renommer/supprimer) au-dessus plutôt que sur
le côté. Ajoute deux flèches aux extrémités de la bande pour faire
défiler la VUE (distinct du réordonnancement par carte). Un titre
tronqué défile au survol de la souris (marquee), mesuré dynamiquement
— jamais pour un titre qui tient déjà.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 15:23:19 +02:00
williamandClaude Sonnet 5 8dc4b35dcf Supprime la couche de formes libres, déplace la navigation de page dans le panneau gauche
Build and deploy / test-python (push) Successful in 7m43s
Build and deploy / test-js (push) Successful in 57s
Build and deploy / lint-python (push) Successful in 5m29s
Build and deploy / lint-js (push) Failing after 1m16s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 5m42s
Formes libres (rectangle/cercle/triangle/trait) retirées de bout en
bout (bibliothèque, rendu, panneau Propriétés, grille d'accroche,
JS/CSS associés) — fonctionnalité non retenue.

La bande de vignettes visuelles des pages au-dessus du canevas est
remplacée par une section "Pages" dans le panneau de gauche (liste
simple : ajouter/renommer/réordonner (haut/bas)/supprimer), à la
place de l'ex-catégorie "Mise en page" de la bibliothèque. La route
document_edit ne rend plus qu'une seule page (celle affichée) au
chargement, au lieu de toutes les pages pour alimenter les anciennes
vignettes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 14:40:33 +02:00
williamandClaude Sonnet 5 57c4de3d8a Remplace les onglets texte de pages par de vraies vignettes miniatures
Build and deploy / test-python (push) Successful in 7m23s
Build and deploy / test-js (push) Successful in 1m24s
Build and deploy / lint-python (push) Successful in 6m29s
Build and deploy / lint-js (push) Failing after 1m31s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 5m18s
Les vignettes réutilisent le HTML réellement rendu de chaque page
(CSS scale trick) et sont centrées dans le conteneur du milieu, au
lieu d'une barre pleine largeur.

Corrige au passage deux bugs réels trouvés en écrivant les tests :
- une page contenant un mini-jeu (bouton Suivant/Recommencer) cassait
  le parsing HTML car .docPageThumbCard était un <button> englobant
  un autre <button> ; passage en div role="button" + équivalent
  clavier, contenu copié rendu inert.
- le renommage d'une page par double-clic ne fonctionnait plus du
  tout (sélecteur .docPageTab oublié lors du renommage des classes).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 13:50:05 +02:00
williamandClaude Sonnet 5 ecd483f352 Implemente un systeme de pages pour le support de formation
Build and deploy / test-python (push) Successful in 7m48s
Build and deploy / test-js (push) Successful in 52s
Build and deploy / lint-python (push) Successful in 5m44s
Build and deploy / lint-js (push) Failing after 1m52s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 5m5s
Retour utilisateur : "il faut implementer un systeme de page". Un
support est desormais compose de PLUSIEURS pages (_document_pages),
chacune un document independant affiche seul sur le canevas -- chaque
element appartient a exactement une page via page_id (document_engine/
elements/*, routes/document/document_element_add.py/document_render.py
revalident desormais un page_id explicite). Migration automatique et
silencieuse pour les supports crees avant cette fonctionnalite
(db/supports/ensure_document_pages_schema.py, meme convention que les
ensure_X_schema.py existants) : leurs elements deviennent tous les
enfants d'une "Page 1" creee a la volee, aucune perte de contenu.

Nouveau paquet document_engine/pages/ (add/list/get/rename/move/delete)
et 4 routes dediees (routes/document/document_page_*.py) -- supprimer
la DERNIERE page restante est refuse (garde-fou pose a la route, meme
decoupage que routes/game/screens/screen_delete.py cote jeu, jamais
dans la fonction bas niveau).

Cote editeur : une bande d'ONGLETS au-dessus du canevas (jamais un
panneau lateral, choix explicite de l'utilisateur) -- clic pour changer
de page, double-clic pour renommer (contenteditable), glisser pour
reordonner, "+" pour ajouter, "x" pour supprimer. Changer de page vide
la pile Annuler/Retablir (une commande empilee sur une autre page n'a
plus de sens). Mode Apercu : navigation Page precedente/suivante avec
indicateur "Page X / N" (choix explicite : page par page, pas de
defilement continu), jamais affichee s'il n'y a qu'une seule page.

Verifie : suite pytest complete (702 tests, dont 14 nouveaux pour les
routes de pages), simulation DOM reelle (jsdom, 25 assertions couvrant
tout le cycle de vie cote client -- creation/bascule/renommage/
reordonnancement/suppression de page, portee correcte des elements par
page, pile Annuler/Retablir videe au changement de page, pilule de
navigation en Apercu), et un test de fumee HTTP reel contre le serveur
de dev en marche (creation/ajout d'element/rendu/renommage/suppression
d'une page, refus de supprimer la derniere page, page inconnue -> 404).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 13:24:23 +02:00
williamandClaude Sonnet 5 ecea430ee2 Terminologie coherente dans le graphe du Scenario : Situation, pas Nœud
Build and deploy / test-python (push) Successful in 9m47s
Build and deploy / test-js (push) Successful in 53s
Build and deploy / lint-python (push) Successful in 5m44s
Build and deploy / lint-js (push) Failing after 1m31s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 5m0s
Retour utilisateur : "il y a situation => choix => le choix devient la
situation => avec des choix ... il faut bien choisir les termes". Le
vocabulaire technique de graphe ("Nœud N", "Départ") ne correspond pas
au modele mental du createur : chaque point du graphe EST une
situation (initiale, ou atteinte via un choix precedent), qui a ses
propres choix. Renomme dans toute l'UI (labels des cartes, bouton
d'ajout, indices de la modale de connexion, etiquette de destination,
etat vide de l'inspecteur, texte par defaut d'une nouvelle situation) -
aucun changement de la structure de donnees (x/y/id/text/choices reste
identique), uniquement la terminologie affichee.

Verifie via simulation DOM reelle avec le VRAI sanitize_scenario_config
Python (jamais une reimplementation JS approximative) que l'ajout
d'une situation et l'ajout d'un choix fonctionnent bien de bout en
bout : la fonctionnalite marchait deja (la modale transparente du
commit precedent explique tres probablement le "ca ne marche pas" -
aucun retour visuel rendait les clics invisibles).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 11:57:49 +02:00
williamandClaude Sonnet 5 0babad5018 Corrige la modale d'arbre du Scenario transparente
Build and deploy / test-python (push) Successful in 6m59s
Build and deploy / test-js (push) Successful in 45s
Build and deploy / lint-python (push) Successful in 5m8s
Build and deploy / lint-js (push) Failing after 1m45s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 4m20s
Retour utilisateur : "la modale est transparente". Cause : les tokens
--doc-* (couleurs de fond/bordure/texte de l'editeur) sont definis
uniquement sur .docEditor3 ; #docScenarioTreeModal est volontairement
un FRERE de .docEditor3 dans le HTML (jamais un descendant, sinon
position:fixed serait rogne par le overflow:hidden de main.content --
meme bug deja trouve le 20/09/2026 pour le bandeau d'outils), donc ne
les heritait jamais -- var(--doc-bg-2) etc. retombaient sur transparent
partout dans la modale (fond du dialogue, mais aussi toutes les
couleurs d'accent/bordures/succes du graphe visuel).

Duplique la definition des tokens --doc-* sur #docScenarioTreeModal
(meme valeurs, meme variante [data-theme="light"]) plutot que de
deplacer la modale dans le DOM. forgeDocApplyTheme pose desormais le
meme data-theme sur les deux elements pour qu'ils restent synchronises.

Verifie via simulation DOM reelle (jsdom) : les deux elements recoivent
bien le meme data-theme apres un changement de theme.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 09:35:54 +02:00
williamandClaude Sonnet 5 d92f75a803 Remplace la modale liste+menus deroulants du Scenario par un vrai graphe visuel
Build and deploy / test-python (push) Successful in 7m32s
Build and deploy / test-js (push) Successful in 49s
Build and deploy / lint-python (push) Successful in 5m21s
Build and deploy / lint-js (push) Failing after 1m12s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 3m53s
Retour utilisateur : "passons a un veritable graphe visuel". Chaque
nœud gagne une position x/y (document_engine/labels/scenario_config.py
: un x/y manquant/invalide retombe sur un quadrillage en cascade derive
de l'index du nœud, jamais (0, 0) pour tous les nœuds qui les
empilerait au meme endroit).

Cote editeur (static/document/js/document-editor.js) : les nœuds sont
des cartes deplacables a la souris sur un canevas (glisser-deposer reel,
meme principe que le glisser des formes libres), les choix relies a une
cible sont dessines comme des fleches SVG etiquetees par leur texte
(jamais un menu deroulant). Editer le texte/les choix d'un nœud se fait
dans un panneau inspecteur (colonne de droite) pour le nœud
selectionne ; relier un choix se fait en cliquant "Relier" puis le nœud
cible sur le graphe (mode connexion, Echap annule sans fermer la
modale). La modale generique (.docModal*) est agrandie specifiquement
pour ce graphe (jusqu'a 1180px) sans toucher sa taille par defaut.

Verifie via simulation DOM reelle (jsdom) : rendu des nœuds/positions,
glisser-deposer avec persistance au relachement, traces des fleches SVG
+ etiquettes, workflow complet du mode connexion, suppression d'un nœud
avec reparation des references pendantes, et les 3 façons de fermer la
modale (bouton/fond/Echap) y compris l'annulation du mode connexion
sans fermer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 09:03:47 +02:00
williamandClaude Sonnet 5 7e504b7865 Sanitize les attributs en LECTURE aussi, pas seulement a l'ecriture
Build and deploy / test-python (push) Successful in 11m5s
Build and deploy / test-js (push) Successful in 55s
Build and deploy / lint-python (push) Successful in 6m29s
Build and deploy / lint-js (push) Failing after 1m39s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 5m18s
Bug reel constate le 21/09/2026 : un element Scenario cree avant la
refonte en arbre de decision (ancien schema plat "situation"/"choices"/
"correct_index") faisait planter silencieusement le panneau Proprietes
cote client des la selection - scenario.nodes etait inexistant sur
l'ancienne forme, aucune erreur visible, juste "il ne se passe rien".
Cause : document_edit.py et document_render.py renvoyaient les
attributs BRUTS de la base au client, jamais revalides - contrairement
a la route d'ecriture qui, elle, sanitize deja avant de persister.

Ajoute document_engine.sanitize_element_attributes(kind, attributes),
point d'entree unique de dispatch kind -> sanitize_X_config, utilise
desormais a la fois en ecriture (document_element_update.py, qui
reutilise ce nouveau dispatch au lieu de son if/elif duplique) ET en
lecture (document_edit.py/document_render.py). Elimine toute la classe
de bug "schema devenu obsolete apres une evolution du modele de
donnees d'un mini-jeu, donnee jamais retouchee depuis" - present et
futur, pas seulement pour Scenario.

Migre les donnees reelles deja affectees (support de test, element 46)
vers le nouveau schema en arbre, en preservant integralement le
contenu deja redige par l'utilisateur (situation + 3 choix/consequences
du scenario "chat sur la route").

Ajoute un test de non-regression qui ecrit delibirement l'ancien schema
en base (en contournant le sanitize de la route d'ecriture, pour
simuler une donnee reellement ancienne jamais nettoyee) puis verifie
que /edit et /render renvoient une structure saine au client.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 08:07:06 +02:00
williamandClaude Sonnet 5 a529857379 Refonte du Scenario en arbre de decision (modale dediee, plus de vrai/faux
Build and deploy / test-python (push) Failing after 1m15s
Build and deploy / test-js (push) Successful in 54s
Build and deploy / lint-python (push) Failing after 1m12s
Build and deploy / lint-js (push) Failing after 1m8s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m4s
Retour utilisateur : "une consequence peut mener a d'autres choix et
ainsi de suite, il n'y a pas de notion vrai/faux, il faut une modale
avec la possibilite de construire un veritable arbre de choix
consequence". Remplace le modele plat (situation + 2-4 choix + un seul
bon choix + une consequence terminale) par un vrai graphe de nœuds :
{"title", "nodes": [{"id", "text", "choices": [{"text", "target_id"}]}]}
- nodes[0] est la situation initiale, chaque choix peut pointer vers
n'importe quel autre nœud (branchement, convergence, fins multiples),
un nœud sans choix est une fin de branche valide. Aucune notion de
bonne/mauvaise reponse.

L'arbre se construit desormais dans une modale dediee (trop de
structure pour la colonne etroite du panneau Proprietes) : liste de
nœuds, chaque choix avec un menu deroulant "mene a" listant les autres
nœuds ou "fin de branche". La modale est un composant generique
(.docModal*) independant de tout framework externe.

sanitize_scenario_config degrade silencieusement tout target_id
orphelin (nœud supprime) vers None plutot que de faire echouer le
scenario entier. Le lecteur cote client navigue le graphe nœud par
nœud, le texte du nœud visite remplace le precedent (toujours pas un
Quiz), jusqu'a une fin de branche puis passage au scenario suivant.

Verifie via simulation DOM reelle (jsdom) : navigation ramifiee
(branchement, convergence, fin via nœud vide ET via choix sans cible),
plusieurs arbres a la suite, et l'editeur modal complet (ouverture,
ajout/suppression de nœud avec reparation des references pendantes,
changement de cible, fermeture bouton/fond/Echap).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 17:29:24 +02:00
williamandClaude Sonnet 5 c04a81cfec La consequence du Scenario remplace la situation, pas un feedback Quiz
Build and deploy / test-python (push) Failing after 1m2s
Build and deploy / test-js (push) Successful in 51s
Build and deploy / lint-python (push) Failing after 58s
Build and deploy / lint-js (push) Failing after 51s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m1s
Retour utilisateur : "ce n'est pas un quiz, la consequence s'affiche a
la place de la situation precedente". L'ancien design affichait la
situation ET les choix en permanence avec un encart de feedback separe
en dessous (calque sur le Quiz). Desormais un seul bloc de texte
(.docScenarioSituation) sert successivement a la situation PUIS, une
fois un choix fait, a la consequence a sa place ; les boutons de choix
disparaissent avec elle. Supprime l'element .docScenarioConsequence
devenu inutile.

Verifie via simulation DOM reelle (jsdom) : la consequence remplace bien
le texte de la situation (jamais affichee a cote), les choix
disparaissent, le retour a une situation neutre au scenario suivant/au
redemarrage fonctionne.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 17:10:56 +02:00
williamandClaude Sonnet 5 b2292de122 Implemente le mini-jeu Scenario (situation, choix, consequences)
Build and deploy / test-python (push) Failing after 59s
Build and deploy / test-js (push) Successful in 50s
Build and deploy / lint-python (push) Failing after 59s
Build and deploy / lint-js (push) Failing after 1m1s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 59s
Cinquieme mini-jeu du support de formation : le createur ecrit une
situation initiale, definit 2 a 4 choix, indique lequel est le bon, et
redige la consequence de chaque choix. Plusieurs scenarios peuvent etre
crees, joues dans l'ordre d'ecriture (jamais melanges, contrairement a
Association/Memory/Mots meles : ce sont des mises en situation
sequentielles). En Apercu, l'apprenant lit la situation, choisit une
option, decouvre la consequence de SON choix et si c'etait le bon, puis
passe au scenario suivant. Comme Association/Memory/Mots meles, le
dernier scenario reste affiche une fois repondu : seul le bouton
Recommencer apparait, jamais un ecran de resultat separe (reserve au
Quiz). Reutilise les classes visuelles du Quiz (docQuizOptions/
docQuizFeedback/docQuizNextBar) plutot que de dupliquer ces regles.

Verifie via simulation DOM reelle (jsdom) : progression entre plusieurs
scenarios, choix correct/incorrect avec revelation de la bonne reponse,
comportement de fin de partie, panneau Proprietes (ajout/suppression de
scenario, changement du nombre de choix, selection du bon choix).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 16:50:10 +02:00
williamandClaude Sonnet 5 d8be80ebd1 Implemente le mini-jeu Mots meles (grille reelle, placement 4 directions)
Build and deploy / test-python (push) Failing after 1m0s
Build and deploy / test-js (push) Failing after 50s
Build and deploy / lint-python (push) Failing after 1m2s
Build and deploy / lint-js (push) Failing after 1m7s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m1s
Quatrieme mini-jeu du support de formation : le createur ecrit 5 a 10
mots (recommandation souple, comme MIN_PAIRS/MIN_CARDS), places par le
serveur dans une grille carree horizontalement, verticalement, ou en
diagonale (deux sens seulement, jamais a l'envers) via un vrai
algorithme de placement avec retry/agrandissement de grille en cas de
conflit. La grille ET la position exacte de chaque mot sont calculees
cote serveur puis embarquees en JSON ; le client valide chaque
selection (glisser ou cliquer-cliquer) par comparaison de coordonnees
exactes, jamais une simple comparaison de texte (qui se tromperait sur
des lettres partagees entre deux mots qui se croisent). Comme
Association/Memory, la grille reste affichee une fois tous les mots
trouves : seul le bouton Recommencer (.docMinigameRestartBar, partage)
apparait.

Verifie via simulation DOM reelle (jsdom) : selection au glisser ET au
clic-clic, mot invalide sans crash, barre de fin qui bascule, panneau
Proprietes (ajout/suppression de mot avec revalidation serveur).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 15:31:46 +02:00
williamandClaude Sonnet 5 1b1307bb85 Association et Memory restent affiches une fois termines, seul Recommencer bascule
Build and deploy / test-python (push) Failing after 59s
Build and deploy / test-js (push) Failing after 52s
Build and deploy / lint-python (push) Failing after 59s
Build and deploy / lint-js (push) Failing after 1m1s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m4s
Les deux mini-jeux gardaient jusqu'ici un ecran de resultat separe qui
remplacait le plateau de jeu (comme le Quiz). Le plateau reste desormais
visible en permanence ; seule une barre partagee .docMinigameRestartBar
apparait/disparait. Le Quiz garde son propre comportement (ecran de
resultat separe), inchange.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 14:43:26 +02:00