Plan pour terminer la migration - PDN 1:1, QA backoffice sur 3 marques, defauts structurels
A lire au debut de toute session sur cet effort. Non importe dans CLAUDE.md : c'est le plan de reference qui remplace
pdn-resume.md(fidelite PDN) etbackoffice-qa-plan.md(modele de contenu) en les reunissant dans un ordre d'execution unique. Le journal d'avancement est en bas de ce fichier : le mettre a jour a la fermeture de chaque phase, pour qu'une reprise ne depende jamais de l'historique de conversation.Ecrit le 2026-07-30. Branche
develop, dernier commit3ae6e43.
ETAT D'AVANCEMENT - tableau de bord (mis a jour le 2026-08-03)
Ou on en est : phase 5 (fidelite PDN page par page) en cours. Les phases 0, 1 et 4 sont closes ; la phase 2 n'est faite qu'a moitie ; les phases 3, 6 et 7 ne sont pas commencees.
| phase | objet | etat |
|---|---|---|
| 0 | Poser le plan, solder l'en-cours, retirer les pieges | ✅ FAIT |
| 1 | UN audit mesure exhaustif (agents paralleles + sweep contre le live) | ✅ FAIT - registre §A/§B/§C. ⚠️ ~50 % des lignes [AGENT] se revelent fausses : re-mesurer avant d'agir |
| 2.1 | Pickers de categorie | ✅ FAIT (2026-07-30) |
| 2.2 | factsPanel | ✅ FAIT 2026-08-04 (§C23) - re-mesuree d'abord, et sa description etait FAUSSE - la description ci-dessous etait FAUSSE.** factsPanel est un ELEMENT (un bloc), pas une composition, et il MARCHE : la bande "Détails" des 7 pages de vin en est faite. Il ne reste donc aucune composition a creer. Ce qui reste est de la SUPPRESSION de schema mort : les 6 proprietes de productFacts ne sont ecrites nulle part (0 SetValue), aucune marque n'instancie product, et _pageFacts.cshtml ne rend rien sur les 3 marques. A arbitrer : c'est le contrat UPSTREAM du gabarit, pas du code de projet (regle #7) |
| 2.3 | Repeteur de champs de formulaire | ⬜ a faire |
| 2.4 | Reste de la phase 4 (bandes en dur, dictionnaire, fr-FR en dur) | ⬜ a faire |
| 2.5 | Images hotlinkees (17 + 5 emoji), elagage des WXR | ⬜ a faire |
| 2.6 | Favicons + la fuite du .ico de Gilliard | ✅ FAIT - un jeu par marque sur disque (wwwroot/images/favicons/<theme>/, tire du live), layout par @theme avec override siteSettings.Favicon, fuite .ico/manifest supprimee. Pas de seed (favicons figees, decision utilisateur) |
| 3 | Reconciliation du contenu PDN depuis le WXR (FR) | ⬜ a faire |
| 4 | Corrections systemiques structure + interaction | ✅ FAIT - carte d'activite, pied, souligne de nav, halo d'ombre, interligne. 2 items clos en FAUX POSITIFS |
| 5 | Fidelite PDN page par page | 🔵 EN COURS - voir le detail ci-dessous |
| 6 | L'arbre allemand - Gilliard, Chevaliers, PDN (PAS Gilliarday) | 🔵 EN COURS, gros avancement 2026-08-17 - routage /de FAIT, chrome + dictionnaire DE FAITS, contenu DE de Chevaliers et PDN FAIT depuis un scrape du live. Reste Gilliard (voir plus bas : pas de scraper) |
| 7 | Validation finale (sweep complet, parcours backoffice, docs, hygiene du harnais) | ⬜ a faire |
Phase 5 en detail - ce qui est ferme et ce qui reste
| item | etat |
|---|---|
| Hero deux colonnes des 7 pages de vin | ✅ FAIT (pdn-wine-detail-spec.md §A) |
| Bande « Détails » des pages de vin | ✅ FAIT (§C8) |
| Carte de listing + carte d'archive | ✅ FAIT (§C9, §C10) |
| Echelle typographique / echelle de conteneur | ✅ FAIT (§C11, §C12) |
Grille produits /goodies/, /idees-cadeaux/ | ✅ FAIT (§C13) |
| B3-2 l'intro dans le hero (11 pages) | ✅ FAIT (§C14) |
| B2-9 la paire de photos de la bande 2 | ✅ FAIT 2026-08-03 (§C15) |
| B3-14 la couleur du texte courant | ✅ FAIT 2026-08-03 (§C17) |
B3-1 le formulaire d'adhesion de /club/ | ✅ FAIT 2026-08-03 (§C18) - bande a 602 contre 601 |
| B3-3 intitules de la confidentialite | ✅ FAIT 2026-08-03 (§C19) - ce n'etait pas la taille du titre : la page entiere etait rendue avec le composant "intro de section". Chaque paragraphe tombe desormais au y du live aux 4 largeurs |
| B3-4 largeur de la colonne de texte | 🔵 MOITIE FAITE (§C19) - la confidentialite est close (1290 = le conteneur). Restent les 2 articles : le live y pose 65.116 % du content_wrap des 1024 (850 est un PLAFOND, pas une constante - le registre disait "850" et "nous 722", les DEUX chiffres sont faux ailleurs qu'a 1440) |
-> /contact/ | ⬜ REPORTE EN PHASE 2.3 (decision utilisateur 2026-08-03). Ce n'est pas un habillage : le live a un jeu de champs DIFFERENT ("Sujet" contre notre "Adresse", pas de case de consentement), une colonne de 645 @x671 contre nos 873 centrees, deux colonnes des 601px, et une icone par champ. Le construire avant le repeteur formField reviendrait a ecrire un 7e preset code en dur que 2.3 supprimerait. Icones : SVG en ligne (decision utilisateur), pas la fonte fontello du live |
-> /club/ | ⬜ petit lot bien specifie (§C21) : couleur/opacite du placeholder, padding-left des champs pleine largeur, trio de date centre a letter-spacing: 1px, et palier deux colonnes a 769 chez le live contre 1024 chez nous. Aucun defaut d'habillage au-dela |
| -> pied, newsletter | ⬜ RECLASSE EN B2-7 (§C22) : ce n'est pas l'habillage (nous sommes deja blanc/rose) mais la GRILLE du pied - nos 3 premieres colonnes sont figees aux valeurs du live A 1440, donc le champ tombe a 98px a 992 et ne redevient juste qu'a 1440. Restent deux vrais ecarts d'habillage, independants : le placeholder "Votre e-mail" totalement absent chez nous, et la hauteur 54 contre 48 (padding 15px 10px contre 12px 15px) |
| B3-8 survol des cartes | ⬜ 6 pages de listing |
B3-13 /contact/ bande finale qui grandit | ⬜ +586 a 1440 |
| B3-5 bande "Articles récents" absente | ⬜ SPECIFIEE : section.related_wrap, H3 38.39 a gauche, 2 cartes (image + categorie + titre, NI date NI extrait), 2 colonnes des 768, ~616 a 1440 marge comprise |
| Bande d'en-tete d'article du live (sur-titre de categorie + photo a la une 848x600 centree) | ⬜ absente du registre, vue en mesurant B3-5 |
| Accueil : survol de la grille de vins | ⬜ |
| Accueil : echelle de bouteille + fondu du slider | ⬜ ⚠️ region MASQUEE : invisible au pourcentage de pixels, se juge a interact.mjs |
| Accueil : l'illustration de raisin de la bande 3 (trop grande, chevauche le titre a 768) | ⬜ vue a la capture, absente du registre |
Dettes et constats hors phase - LE registre de ce qui n'a pas de case ailleurs
Tout ce qui est repere « en passant » atterrit ICI, jamais dans la prose d'un journal : une note de journal n'est pas suivie, et ce depot a deja paye ce defaut (3994a28, « solder les deviations que j'avais CONSIGNEES sans les corriger »). Une ligne n'est fermee que par une mesure, et la mesure a le droit de la SUPPRIMER plutot que de la corriger.
| dette | etat |
|---|---|
formBlock : 6 presets de champs codes en dur (contact/inquiry/booking/activity/newsletter/membership) | ⬜ phase 2.3 les convertit en formField. membership est le dernier ajoute (2026-08-03) |
ButtonPicker Core - Media Text Display sans wine ni product-detail | ✅ CORRIGE 2026-08-03 |
pdn-gen.mjs : overlay « jamais emis » | ✅ FAUSSE ALERTE, supprimee 2026-08-03 - son addMedia() enregistre la bouteille du hero. Avertissement pose sur la ligne |
_pageFacts.cshtml : 6 libelles codes en dur + productfacts.config porte 6 proprietes d'affichage | ✅ SUPPRIMES 2026-08-04 (§C23) - c'etait du schema MORT (0 ecriture, 0 rendu), pas une migration |
Event.cshtml:18 code fr-FR en dur | ⬜ phase 2.4 - devient un vrai bug a la phase 6 |
Event.cshtml:34 supprime la liste de faits si le RTE contient un <strong> | ⬜ phase 2.4a - MESURE (§C24) : le rendu d'aujourd'hui est JUSTE (live et local rendent les memes lignes sur caves-ouvertes), et le commentaire du fichier se trompe de marque. Le defaut est le MECANISME, pas le rendu : remplacer le sniff par une propriete explicite sur scheduleFacts, posee a true la ou le sniff est vrai, pour un rendu identique au pixel |
_MasterLayout.cshtml:105-106 servent la favicon et le manifeste de Gilliard a TOUTES les marques | ⬜ phase 2.6 |
Hygiene du harnais (README 47 pages contre 54, ~20 sondes a chemin absolu, measure.mjs en networkidle) | ⬜ phase 7 |
Degrade de page interieure fige a 686px au lieu du 16.18% -> 34% du live (donc proportionnel a la bande) - touche TOUTES les pages interieures de PDN | ⬜ phase 5, vu a la capture le 2026-08-03 (§C19) |
Au defilement, le live peint une barre d'en-tete fixe que nous ne peignons pas. Les deux header mesurent position:absolute et sortent de l'ecran a l'identique : la barre du live est un CLONE, element distinct, non identifie | ⬜ phase 5, a mesurer (§C19) |
Pied de PDN : 1225 contre nos 668 a 1024, et la CAUSE est mesuree (§C22) - grille figee aux valeurs de 1440 + palier a 992 au lieu de 1025. Le conteneur suit fenetre - 60 plafonne a 1350, gouttiere 40 constante, 4 colonnes fluides | ⬜ B2-7, desormais specifie |
PDN /club/ renvoie 404 en local : le noeud s'appelle « Le Club », donc Umbraco sert /le-club/ alors que le live et tools/fidelity/pages.js disent /club/. Anteriorite verifiee : present dans HEAD, ce n'est pas une regression du chantier DE. Le harnais diffe donc cette page contre une 404 depuis toujours. Correction : poser umbracoUrlName (que pdnContentPage compose deja) dans pdn-gen.mjs. Les 19 autres chemins PDN du harnais repondent 200 | ⬜ a trancher - change une URL FR, donc a mesurer et committer a part |
| Les 10 articles rendaient leur corps DEUX FOIS | ✅ CORRIGE 2026-08-03 (§C20) - le generateur emettait les bandes classees ET le post.html verbatim. Retire apres verification mot a mot des dix ; le bouton de fin d'article devient un vrai ctaLink |
Portes en vigueur
- Reference locale :
ref-20260804(270 captures, prise apres la suppression de la phase 2.2). Non visuel -> zero pixel contre elle. - ATTENTION une reference n'est valide que jusqu'au prochain changement visuel par construction.
ref-20260803ba servi une fois de trop, apres les commits confidentialite et articles : elle a signale 15 "regressions" qui etaient exactement les 3 pages changees VOLONTAIREMENT. Re-baseliner fait partie du commit visuel, pas du suivant. - Visuel par construction ->
diff.mjscontre le LIVE, saufpdn/home(§C16 : non deterministe, +/-11 points). - Toute edition de
base/ou d'un jeton partage -> re-passer la porte sur gilliard ET chevaliers avant de committer.
Contexte
Trois chantiers inacheves doivent atterrir ensemble, parce qu'ils touchent les memes vues, les memes seeders et la meme porte de qualite :
pdn-resume.md- Porte de Novembre est mesuree mais pas finie. Son accueil a ete valide sur le harnais pixel, qui est aveugle a (a) l'interieur des regions masquees et (b) aux transitions hover / focus / apparition. La porte d'interaction CDP n'a jamais ete passee sur PDN.backoffice-qa-plan.md- le modele est encore en texte la ou il devrait etre en entites (categories en TextBox, libelles de faits codes en dur, listes d'options de formulaire codees en dur, bandes editoriales codees en dur, chaines de chrome dans les vues). A faire pour Gilliard, Chevaliers ET Porte de Novembre.- Defauts structurels qui ont survecu a plusieurs passes - l'utilisateur a pointe les cartes "Nos Activites" de l'accueil Gilliard. Mesurees dans cette session : le diagnostic est en phase 4, c'est un vrai bug reproductible, pas un faux positif.
Nouveau depuis le dernier passage de main : tools/portedenovembre.WordPress.2026-07-30.xml (4,17 Mo, WXR 1.2, 358 items) debloque la P6 du plan PDN.
Decisions prises (utilisateur, 2026-07-30)
- Feu vert accorde. Build, redemarrage,
/generate-models, re-seed et ecritures en base sont autorises - le travail backoffice se fait dans cette session. - Le contenu est GELE pour Gilliard et Chevaliers. Le live derive en permanence ; on ne le court pas apres. Seuls les defauts de mise en page / geometrie / typographie / interaction sont corriges. Consequence acceptee : notre accueil Gilliard continue d'afficher deux cartes d'activite que le live n'affiche plus. A consigner comme deviation deliberee dans
assets-substitues.md, pas en silence. - PDN : reconciliation ciblee depuis le WXR (FR) + construction de l'arbre allemand.
La barre d'acceptation (inchangee, decision du 2026-07-27)
Les pages riches en photos sont validees sur la STRUCTURE : hauteurs de bandes dans une tolerance, geometrie par element, typographie, completude du registre de couverture, audit chrome + interaction. Le diff pixel n'est qu'un outil de reperage (doublement, mauvaise taille, decalage, bande manquante). Les pages de chrome peu photographiques peuvent encore tenir un pixel bas. Ne jamais rapporter "porte verte" comme "conforme au live".
Mesures etablies dans cette session (ne pas re-deriver)
Cartes "Nos Activites" de l'accueil Gilliard - le defaut signale
Live /fr/ @1440 contre local :
| live | local | verdict | |
|---|---|---|---|
| forme de la bande | deux sections : section.experiences-2 tete 1440x381 @y1962 + section sans classe cartes 1440x482 @y2343 (total 863) | une seule section.card-collection--grid-3 1440x839 @y1962 | -24, paddings de tete differents |
| conteneur de carte | .col-xl-4.col-md-4 450x462, pad 0 22 22 22 | .g-card--activity 450x413, meme pad | ok |
| media | img 406x271 | .g-card__media 406x271 | conforme |
| bloc titre | div.title-wrap 406x80, position:relative, margin-top:-10px (chevauche l'image) | .g-card__title 406x80, aucun chevauchement, commence pile au bas de l'image | chevauchement absent |
| bloc adresse | 12.8px (12px @375), or rgb(142,120,76), epingle <img> 18x18, boite de ligne 26px | 16px, gris rgb(50,50,50), sans epingle, boite de ligne 24px | taille, couleur, icone, interlignage |
⚠️ CORRECTION (2026-07-30, apres mesure directe du local). Ce tableau disait d'abord que notre .g-card__location est en white-space:nowrap et tronque, avec des cartes figees a 413px. C'etait faux : je l'avais tire du message du commit 9d16cd5, pas d'une mesure. Le nowrap a ete retire depuis. Mesure : les deux cotes sont en white-space: normal et passent a la ligne ; le live ne tient sur une ligne a 1440/1920/375 que parce que sa chaine fait 283px a 12.8px, et il passe tout seul a deux lignes a 1024 et 768. La correction ne doit poser aucune regle white-space - seulement la taille, la couleur, l'epingle et la boite de ligne. Detail complet et tableau par largeur : fidelity-defect-ledger.md §B1bis.
Contenu du live derive aussi (cartes 1 et 3 ont change : "Spa La Vigne - Vinotherapie / des CHF 205.-" et "Wine Walk"). Gele par decision utilisateur : on ne re-synchronise pas, on corrige la structure.
Autres faits mesures a ne pas re-deriver
- Les doctypes portent deja
<Variations>Culture</Variations>partout (pdncontentpage,pdnarticle,pageHero,pageSettings,pdnCanvas,siteSettings). Une seule langue existe (uSync/v17/Languages/fr.config) ;en-us.configest une pierre tombaleChange="Delete". L'allemand est donc "ajouter une Langue + des valeurs par culture + une ligne de domaine", pas une refonte du modele. DevSeedRootsController.BindDomainspilote dejaIDomainService.UpdateDomainsAsyncavecDomainModel { DomainName, IsoCode }- maisRootSpec.Domainsest unstring[]plat partageant un seul IsoCode. Il faut un IsoCode par domaine pour ajouter/de.- Le nouvel export PDN n'a aucun ACF (Elementor, pas aa-base-theme), des extraits sur 4 articles seulement (les cocktails), 181 pieces jointes toutes sur
portedenovembre.ch, et Polylang (pas WPML).wxr-extract.mjsne connait quegilliard/chevalierset sondetectLang()est WPML uniquement. - Les enfants "vins" FR et DE de PDN partagent des slugs identiques (
ice-pdn,mousseux, ...), distingues seulement par le parent - ce que les noeuds a variantes de culture d'Umbraco donnent gratuitement. - Le harnais couvre 54 pages (
tools/fidelity/pages.js: gilliard 22, chevaliers 12, pdn 20 ;gilliardayest configure mais n'a aucune page). Reference locale courante : baselineref(270 captures, 2026-07-30, harnais corrige -currentetphase0ont ete supprimes, perimes).
Phase 0 - Poser le plan, faire atterrir l'en-cours, retirer les pieges
- Ecrire ce plan dans le depot (fait : ce fichier), le referencer dans la liste "Documentation detaillee" de
CLAUDE.mdcomme doc non importe. Tenir le journal d'avancement en bas de ce fichier. - Finir l'increment
SeedLibrarynon commite. 7 fichiers modifies :src/Web/Seed/SeedSession.cs(SeedLibrary, :119), les 3 sites d'appel dans les seeders,chevaliersvacancy.config(+chevaliersCanvas), son modele genere,CLAUDE.md. Build -> redemarrer ->/generate-models-> build -> rejouer les 4 seeders ->baseline.mjs --label check --against current(zero pixel attendu) -> commit. - Corriger le piege du controleur genere AVANT de toucher aux generateurs.
DevSeedPdnController.csestGENERATED by tools/seed-gen/pdn-gen.mjs, et pourtant l'appelSeedLibrarya ete ajoute a la main en:1213. Rejouer le generateur le detruit en silence. EmettreSeedLibrarydepuispdn-gen.mjs; idemchevaliers-gen.py->DevSeedChevaliersController.cs:1462. Verifier en rejouant les deux generateurs : diff a zero. - Corriger l'en-tete de generateur perime dans
DevSeedChevaliersController.cs:19(scratchpad/chev/gen.py->tools/seed-gen/chevaliers-gen.py). - Sondes : committer
audit_form.mjsetfooter_social.mjs(generiques, multi-marques) ; generaliser les ancres texte codees en dur d'audit_cardtitle.mjsen CSV argv puis committer ; supprimerchev_home.mjs(jetable, une seule page). - Trancher la contradiction du port chevaliers.
config.js:43dit:12953alors que son propre commentaire,probes/README.mdet 8 sondes affirment:44360. Une mauvaise valeur mesure Gilliard en silence et ressemble a un echec de seed. - Refaire une baseline
--label currentpropre apres tout ce qui precede.
Phase 1 - UN audit mesure exhaustif (lecture seule, agents paralleles)
C'est le manque de rigueur reproche a la derniere passe. On ne corrige rien dans cette phase. Sortie : un registre de defauts unique commite dans .claude/docs/domain/fidelity-defect-ledger.md, classe systemique / par-page, chaque entree portant sa mesure live.
Les agents de mesure paralleles en lecture seule sont pre-approuves (decision (b) du 2026-07-25) ; les corrections restent serielles dans la session principale pour eviter les conflits SCSS. Les agents produisent environ 50 % de faux positifs : chaque candidat est verifie contre le live, avant ET apres.
Par page, aux 375 / 768 / 1024 / 1440 / 1920, et par region et par controle :
- capture live vs local + DOM + CSS calcule (geometrie, typographie, couleur, echelle d'image) ;
probes/heights.mjs(porte structurelle),probes/bands.mjs,probes/tree.mjs(structure d'abord),probes/css.mjs,probes/ancestry.mjs;interact.mjspour hover / focus / active sur chaque element interactif - CDPCSS.forcePseudoState, jamais un.hover()nu (il rate en silence les elements hors ecran). Pour les etats declenches par le parent (li:hover > a::after), faire confiance au hover souris d'un agent ;- animations d'apparition / transitions - aucune geometrie, aucun pixel statique : le harnais ne les voit pas du tout ;
- les regions masquees sont auditees quand meme, a l'oeil et par le DOM. Le masque exempte les pixels, pas la justesse. Le hero Slider Revolution de PDN est l'exemple type.
Perimetre :
- PDN - les 20 pages de
pages.js(accueil, vins, 7 detail-vin, cocktails, news, evenements, news-events, club, goodies, idees-cadeaux, contact, confidentialite, 2 articles). Premiere passe d'interaction CDP de l'histoire de PDN. - Gilliard - 22 pages et Chevaliers - 12 pages : re-audit structure + chrome + interaction. Les ecarts de contenu sont consignes mais pas traites (contenu gele).
- Audit de contenu PDN contre le nouvel export : seed actuel vs
portedenovembre.WordPress.2026-07-30.xml- titre, corps, id media, categorie, date, par noeud. Alimente la phase 3.
Integrer les items PDN deja mesures (pdn-resume.md §4b/§4c) au lieu de les redecouvrir : echelle de la bouteille de la slide SHARE, transition hover de la grille de vins (la sonde precedente a vise le mauvais element live - le re-identifier), apparition en fondu du slider, hero deux colonnes du detail-vin, mise en page des cartes de listing, structure du pied de page, balisage Elementor dans les corps d'articles.
Phase 2 - Modele de contenu / backoffice, les 3 marques
Porte par nature de changement : non visuel -> baseline.mjs --against current, zero pixel ; visuel par construction -> diff.mjs contre le LIVE, pas pire qu'avant, puis re-baseline. Verifier la parite entre marques a CHAQUE commit - c'est exactement comme ca que chevaliersVacancy a perdu sa grille de blocs en silence.
2.1 Pickers de categorie (tout doit changer d'un bloc, sinon le filtre du blog casse)
Les DataTypes existent deja et sont correctement ancres : CorePickerCategorie.config (f1d22002-...-021, max 1) et CorePickerCategories.config (...-022, illimite), filtres sur articleCategory via dynamicRoot originAlias:"Site". Rien ne les reference encore.
articlefields.config:27-29category->...-021;childlisting.config:91-93filterCategory->...-022.childListing.cshtmllit la categorie en chaine en :54, :59, :66, :239, :252 (plus le split virgule en:52). Remplacer par un helperCat(child) => child.Value<IPublishedContent>("category")et comparer par cle de noeud, jamais par chaine accent-repliee : aujourd'hui une faute de frappe vide la liste en silence.- Garder le helper
Slug()sur le NOM de la categorie pour?category=afin que les URL ne changent pas (childListing.cshtml:23-34,:124). - Pastilles :
ListCard.Badge/Kickerdeviennent le nom resolu ;_listCard.cshtml:18-30etBlogPost.cshtml:134suivent. - Seeders :
DevSeedPagesController.cs:963(1 site, 6 articles) etDevSeedPdnController.cs(10 sitescategory+ 6 sitesfilterCategory, dont deux fois l'agregat"News,Event").SeedLibraryretourne dejanom -> Guid; lescategoryKeyscaptures ne servent a rien aujourd'hui. DevSeedSupport.ContentPickemet unUmbraco.ContentPickeralors que les nouveaux DataTypes sont des MNTP - il faut un helperNodePick(params Guid[])emettant une liste d'UDI separee par des virgules.DevSeedPagesController.cs:967reutilise la categorie commeheroPretitle(le live imprime la categorie au-dessus du H1). Ne pas casser ca.locationreste volontairement un TextBox : un picker devenueserait vide sur 3 marques sur 4.
2.2 factsPanel - VISUEL PAR CONSTRUCTION
⚠️ CORRIGE le 2026-08-04, voir §C23. Les deux premieres puces ci-dessous etaient fausses et auraient fait construire un doublon. factsPanel est un ELEMENT (IsElement: true), donc un BLOC, pas une composition - et il est deja en service : la bande "Détails" des 7 pages de vin de PDN en est faite et rend ses 7 lignes en 2 colonnes (§C8). factItem et CoreFacts sont donc references, par lui. Il n'y a aucune composition a creer.
Ce qui reste est une SUPPRESSION, sans migration ni risque de perte : les 6 proprietes de productFacts ne sont ecrites nulle part (0 SetValue et 0 ["alias"] dans tous les seeders), aucune marque n'instancie le doctype product, et _pageFacts.cshtml ne rend rien sur les trois marques (0 product-facts / activity-facts dans le HTML rendu). Idem activityPrice et activityLocation.
A ARBITRER AVANT DE SUPPRIMER : product / productFacts / activityFacts sont de l'echafaudage du GABARIT. Ils sont morts sur ces trois marques, pas forcement sur un projet aval. La regle #7 protege le contrat upstream.
- Supprimer les 6 proprietes d'affichage de
productFacts(productfacts.config: appellation, nez, bouche, analyse, idealAvec, garde) et les 6 libelles codes en dur de_pageFacts.cshtml:8-16. - Garder les champs types qui portent de la LOGIQUE :
startDate/endDate(tri),applyEmail(mailto),closingDate,location.
2.3 Repeteur de champs de formulaire - VISUEL PAR CONSTRUCTION
Ni formfield.config ni Core - Form Fields n'existent.
formBlock.cshtml:118-124code en dur 5 noms de salles qui dupliquent de vrais noeudsvenue;:105-107et:111-115codent aussi les listes de langues et de menus. Nouvel elementformField- BlockList
Core - Form FieldssurformBlock, avecoptionsSource(MNTP) pointant sur les vrais noeudsvenue.
- BlockList
- Rendre
fieldss'il est rempli, retomber sur les presets actuels s'il est vide pour ne rien casser ; supprimer les presets une fois les seeders a jour. - Ajouter le JSON-LD
FAQPagepourfaqList-_structuredData.cshtmln'emet aujourd'hui qu'unWebPageet n'a aucun point d'accroche par bloc.
2.4 Reste de la phase 4
BlogPost.cshtml: supprimer les bandes codees en dur et les re-composer en blocs dans lecontentBlocksdeja cable en:78-82. Vrais numeros de ligne ::92-100(la recherche parUrlSegment == "vins" / "activites"- renommer la page Vins tue la bande en silence),:113-118(« Partager notre passion » / « Nos Activites »),:140(« Retrouvez d'autres articles »). (Le plan d'origine citait :59-60/:81-82/:105 - perimes.)- Chaines de chrome vers le Dictionnaire (handler en
CreateOnly, confirmeappsettings.json:77-83, donc sans risque) :_listCard.cshtml:41,51;childListing.cshtml:120et:208(« En savoir plus », absent de la liste d'origine) ;Event.cshtml:55,59et:78(« Je reserve ma place ») et:93(« retour aux ... ») ;Vacancy.cshtml:11-14,35;_footer.cshtml:93;map.cshtml:28-29. Lecture :Umbraco.GetDictionaryValue("Cle.Pointee"); les 34 entrees actuelles ne couvrent que cookies / accessibilite / pied de page. Event.cshtml:18codefr-FRen dur quelle que soit la culture - devient un vrai bug des que l'allemand arrive en phase 6. Corriger ici.Event.cshtml:34supprime toute la liste de faits si le RTE contient un<strong>: un editeur qui met un mot en gras fait disparaitre dates et lieu.- Liens morts :
_header.cshtml:114(compte) et:121(panier),_footer.cshtml:48etnewsletterSignup.cshtml:20(action="#"). Cabler, masquer derriere un interrupteursiteSettings, ou retirer. Le compteur « 0 fige » du plan d'origine n'existe pas - aucun compteur n'est rendu. Vacancy.cshtml:closingDateest saisissable et n'est rendu nulle part (seule declaration,vacancyfacts.config:107).
2.5 Reste de la phase 5
- Importer les images hotlinkees. Le compte reel est de 17 URL
<img src>distinctes versgilliard.ch(pas 21), toutes danssrc/Web/Seed/GilliardPostData.cs, plus 5 hotlinks emojis.w.orgdans le meme fichier - que le plan d'origine oublie. ReutiliserDevSeedSupport.ImportMediaAsync(:43) puis reecrire lessrc. Laisser les 4 iconeshttp://chevaliers.chdeDevSeedChevaliersController.cs:1274: ce sont des defauts du live, reproduits fidelement (cf. defauts client plus bas). - Elaguer les exports WXR de
tools/. Seuls 4 sont reellement vides ((2) (3) (4) (9), 6 170 octets d'en-tete) ; les autres sont des tranches distinctes par type de contenu, avec des md5 differents - « 15 doublons » est faux. Supprimer les 4 vides et les tranches PII / e-commerce qu'on ne lit jamais ((7) (8) (12)), documenter pourquoi les autres restent.
2.6 Favicons
Le commit 3ae6e43 a deja fait de la favicon un contenu de siteSettings. Reste : seeder la vraie favicon de chaque marque (jeu live PDN = portedenovembre.ch/wp-content/uploads/2024/11/cropped-favicon_porte_de_novembre-1-{32x32,192x192,180x180}.jpg ; Gilliard et Chevaliers depuis leur <link rel=icon> live), et refermer la fuite : _MasterLayout.cshtml:105-106 emettent le favicon.ico et le site.webmanifest de Gilliard inconditionnellement, hors du if/else - une marque qui televerse sa favicon sert encore le .ico de Gilliard (que la plupart des navigateurs privilegient pour l'onglet) et son manifeste.
Phase 3 - Reconciliation du contenu PDN depuis l'export (FR)
Faite avant les corrections de fidelite par page, parce que le contenu deplace la mise en page et qu'on ne regle pas la geometrie deux fois. Methode eprouvee sur Chevaliers (cont.22) : auditer l'existant contre l'export et combler les vrais manques - l'export n'est pas une source de seed naive.
- Ajouter
pdn: { prefix: "portedenovembre.WordPress." }auxBRANDSdewxr-extract.mjs, plus deux changements propres a PDN : un passthrough desmetasbruts (le seul contenu structure de PDN est_elementor_data, 69 items -acfsera{}sur chaque enregistrement) et une detection de langue Polylang (post_translations/term_language), parce quedetectLang()est WPML uniquement et que les vins FR/DE partagent leurs slugs. - Reconcilier dans
tools/seed-gen/data/pdn.json/pdn-gen.mjs; ne jamais editerDevSeedPdnController.csa la main. - Corriger par noeud : corps de texte verbatim, vrais titres (les noeuds portent aujourd'hui le slug brut -
ice-0-0au lieu de « Ice 0.0% »,pink-watermelonau lieu de « Pink Watermelon » - ce qui est une mauvaise experience editeur et releve pleinement de la QA backoffice), ids media exacts, categories, dates, et les 4 vrais extraits (les articles cocktails ; les 13 autres n'en ont reellement aucun, donc l'extrait doit venir du corps). Le nom du noeud pilote l'URL. Renommer en vrais titres deplacerait/vins/ice-0-0/vers/vins/ice-00/et casserait la correspondance 1:1 des chemins. PoserumbracoUrlNamepar noeud pour figer le slug du live, puis renommer librement. - Aplatir le balisage Elementor hors des corps d'articles (
pdn-gen.mjs~:556 emet unrichIntrodepuisp.post.html). Regle permanente : porter le resultat rendu, jamais le plugin.SeedHtml.Clean()dansDevSeedSupport.Rich()est le point de passage existant - l'etendre ou aplatir en amont dans le generateur, en conservant sa garantie que le nombre d'elements ne peut jamais changer. - Ne pas seeder l'article prive
snow-vibes-...ni le brouillonGallery Party; ni les restescpt_layouts/tribe_*/ demo Events Calendar. - Re-seeder, puis relancer le sweep PDN pour re-baseliner avant le reglage de la phase 5.
Phase 4 - Corrections systemiques structure + interaction (toutes marques)
Pire d'abord, a l'altitude partagee, un commit par cause racine. Verifier la non-regression sur chaque marque a chaque changement partage - une correction juste pour Gilliard l'est generalement pour Chevaliers (clone), mais ne jamais le supposer.
4.1 La carte d'activite - le defaut signale par l'utilisateur
D'apres la mesure ci-dessus :
.g-card--activity .g-card__location: retirerwhite-space:nowrap, poser la boite de ligne a 26px, autoriser le retour a la ligne. Gardermin-width:0sur l'element de grille (ce garde-fou a corrige un vrai debordement horizontal a 768 dans6f5a8a5) et re-verifier l'absence de debordement a 768 apres retrait du nowrap.- Avant de changer quoi que ce soit, mesurer le meme element sur les pages live
/fr/activites/et/fr/activites-oenotouristiques/-9d16cd5y avait ete mesure puis generalise a tort. Si le live y rend bien une seule ligne, la difference tient a la longueur de l'adresse, pas a une regle : la correction doit satisfaire les deux pages. - Retablir le chevauchement du bloc titre sur l'image (
position:relative+ marge haute negative) et laisser la hauteur de carte varier avec le contenu au lieu d'etre figee. - Reconcilier le decoupage de bande : le live a deux sections (tete 381 + cartes 482 = 863) la ou nous en avons une de 839. Aligner les paddings, pas le nombre de sections.
4.2 Les items de l'accueil PDN (pdn-resume.md §4b), dans un vrai audit
- Echelle de la bouteille SHARE. Live 686w @1440 / 860w @1920 (~44-48vw) ; local bloque a 593w aux deux. Deux causes :
153f348a remplace le dimensionnement en largeur (width:min(47.6vw,860px), qui correspondait) parheight:62%/max-width:46%; et l'image de premier plan localeaccueil-hero-1.pnga un rapport 1,26 (593x471) contre 1,86 (686x369) pourgamme_portedenovembre_gilliarddu live - ce n'est pas le meme recadrage. Verifier l'asset d'abord, puis dimensionner par slide, en largeur.153f348etait passe en hauteur precisement pour empecher Enjoy/Cheers d'exploser : reconcilier slide par slide, ne pas revert a l'aveugle. - Hover de la grille « Decouvrez nos vins ». Le local ne transitionne que
box-shadow. La sonde precedente a vise.sc_blogger_item(un teaser de blog) - re-identifier le vrai element de grille du live et mesurer son delta repos->hover en CDP avant de repliquer quoi que ce soit. - Apparition en fondu du slider. Mesurer l'entree Slider Revolution du live et la repliquer sur les images de notre hero-slider.
4.3 Tout ce que la phase 1 classe comme systemique
Tokens partages, partials partages, SCSS partage. Deux drapeaux ouverts a trancher au passage : le souligne de navigation est centre-vers-l'exterieur sur demande explicite de l'utilisateur alors que le live mesure une origine a gauche (signale depuis cont.19), et les icones sociales du pied de page sont des glyphes PNG plats sur le live contre nos SVG inline dans un cercle.
Phase 5 - Fidelite PDN page par page
Les quatre items structurels de pdn-resume.md §4c, contre le contenu reconcilie :
- Hero deux colonnes du detail-vin (7 pages - le plus gros). La bande 1 du live @1440 est UNE section rose : a gauche titre Yeseva blanc 60px @x85,y267 + corps blanc + ACHETER (fond blanc / texte noir, x85,y597, 134x55) ; a droite
johannis.png@x649,y177 290x567 chevauchant la photo paysagejohannisberg.jpg@x806,y150 500x619. Nous rendons le titre du pageHero a l'echelle 150px du listing, centre, plus unmediaText--product-detailempile en dessous - donc titre duplique, mauvaise echelle, mauvaise mise en page. Correction : replier la bande 1 dans le pageHero et ne plus emettre le mediaText pour la bande 1.pageHeroest une composition partagee par 4 marques - porter le deux-colonnes / 60px / blanc derriere un modificateur limite au detail-vin et verifier la non-regression Gilliard et Chevaliers. - Mise en page des cartes de listing (evenements / cocktails / news / news-events / idees-cadeaux). Live = image + sur-titre rose « EVENT » + titre Yeseva noir + extrait + fleche, transparent sur ambre. Nous =
cards-blog: pastille sur l'image + barre blanche. La mise en page est corrigeable maintenant ; le texte de l'extrait vient de la phase 3 pour les 4 articles cocktails, et du corps ailleurs. - Structure du pied de page. Live = [logo + « Vins de la Maison Gilliard » + sous-logo MAISON GILLIARD] [contact] [Liens] [Newsletter] + barre sombre avec les reseaux dans la barre. Nous = [Liens][Newsletter][contact][reseaux] + barre sombre, pas de colonne logo. Demande une evolution du
_footer.cshtmlpartage - risque multi-marques, donc valider les trois marques, ou documenter la deviation. - Tout ce que la phase 1 liste comme par-page, pire d'abord.
Phase 6 - L'arbre allemand (Gilliard, Chevaliers, PDN - PAS Gilliarday)
Additif, et en dernier, pour ne pas destabiliser la porte 1:1 francaise. Mesure du live (2026-08-13) : le DE n'est PAS que PDN. Les trois marques (hors Gilliarday) ont une version allemande, avec des structures d'URL differentes :
| marque | FR live | DE live | notre cible |
|---|---|---|---|
| Gilliard | /fr/ | /de/ | racine -> fr, /de -> de |
| Chevaliers | /fr/ | racine (defaut DE) | racine -> fr, /de -> de |
| PDN | racine | /de/ | racine -> fr, /de -> de |
Decision utilisateur (2026-08-13) : on NORMALISE - racine -> fr + /de -> de pour les trois. Cela DEVIE du live pour Chevaliers (racine = DE) et Gilliard (FR en /fr/, pas a la racine) : deviation deliberee, a consigner dans assets-substitues.md. **Gilliarday reste FR, sans domaine DE
- ne pas y toucher.**
Etat du code (mesure 2026-08-13) :
uSync/v17/Languages/de.config: FAIT (de, non defaut).Name= "German", a passer en "Allemand"._MasterLayouthreflang : DEJA FAIT - le switch mappe dejade -> de-ch(etit). Rien a ajouter.Event.cshtml:18fr-FRen dur : CORRIGE le 2026-08-13 ->CultureInfo.CurrentCulture.SiteResolvergere deja les domaines path-scoped (/fr,/de) - aucun changement de code.
Reste a faire :
RootSpec.DomainsdeDevSeedRootsController: d'unstring[]plat a un IsoCode par domaine, pour poser<marque>.../de->dea cote de la ligne racine FR, sur les TROIS marques.- Seeder la culture DE sur les noeuds existants (Polylang = traductions : meme noeud, seconde culture, pas de nouveaux noeuds) des trois arbres. Slugs FR/DE identiques ->
umbracoUrlNamepar culture. - Proprietes invariantes (
Variations=Nothing) : 7 sursiteSettings, 2 surpageHero, 1 surpageSettings- celle qui porte du TEXTE affiche doit passer enCulture. - Chrome DE par marque : nav, footer, popup (export PDN :
Header Sticky - DE,Footer Main - DE,MailChimp Popup - DE). - Dictionnaire : valeurs DE des 35 entrees de chrome.
- Ajouter les pages DE a
tools/fidelity/pages.jset les balayer aux memes 5 largeurs.
Phase 7 - Validation finale
sweep.mjscomplet sur tous les sites aux 375 / 768 / 1024 / 1440 / 1920, plusinteract.mjssur chaque page, plus le registre de couverture. « Vert » signifie : structure conforme, geometrie et typographie propres, registre complet, audit chrome et interaction passe, residus expliques par ecrit.- Parcours backoffice - phase 6 de
backoffice-qa-plan.md, checklist dans.claude/docs/modules/backoffice.md(« Revue "experience editeur" »). Aucune commande ne la remplace. - Docs, dans les memes commits que le code (protocole CLAUDE.md) :
content-model.md(chaque composition / DataType / champ nouveau),extensibility.md,frontend-build.md,business-rules.md,assets-substitues.md(la deviation du contenu gele, chaque raison de masque, les cartes d'activite Gilliard que le live n'affiche plus),pdn-block-map.md,conventions-redaction.md,workflows.md(le parcours de seed DE), et une reecriture depdn-resume.md/backoffice-qa-plan.mdconforme a la realite. - Hygiene du harnais :
tools/fidelity/README.mdannonce 47 pages (il y en a 54) ;probes/README.mddocumente 14 sondes sur 36 ;measure.mjset une vingtaine de sondes codent en durfile:///C:/Users/dkoch/Documents/Projects/gilliard/...;measure.mjsutilisewaitUntil:"networkidle"qui ne se stabilise jamais sur le live et annonce un--jsonqu'il ne lit jamais ; environ 9 dossiers de rapport orphelins et 3.txtegares sousreports/. - Signaler les defauts de contenu CLIENT (chevaliers
/fr/contact/: mailto/tel mal libelles,srcd'icones enhttp://) comme constats. Le live les porte lui-meme ; les reproduire est correct pour une migration 1:1 et les corriger releve d'une decision du client.
Regles de travail pour tout l'effort
- La source de verite est le DOM + le CSS calcule du live. Jamais l'oeil, jamais un commentaire de code - les commentaires ont deja eu tort ici (la « re-mesure » du hero de
153f348etait une regression ; lenowrapde9d16cd5en est une autre, encore ouverte). - Mesurer chaque candidat contre le live AVANT et APRES. Les audits d'agents produisent ~50 % de faux positifs.
- Les agents mesurent ; je verifie et je corrige serialement dans la session principale - des editions SCSS paralleles entrent en conflit.
- Corriger la CAUSE, systemique d'abord, un commit par cause racine. Utilisateur seul auteur, PAS de trailer
Co-Authored-By. Ne pas pousser. - Verification de parite a chaque commit :
grep -l "<Alias>contentBlocks</Alias>" *.configet la liste des compositions. Noter l'asymetrie structurelle a l'origine de la derniere derive : Chevaliers, PDN et Gilliarday passent chacun par UNE composition canvas, alors que Gilliard n'en a aucune - ses 12 doctypes declarentcontentBlocksen ligne, donc il n'existe aucun point d'ancrage partage a modifier. Gilliarday est hors perimetre mais herite des changements partages : ne pas le retirer des grilles ni des compositions. - Regle #10 : un doctype ecrit dans uSync n'a pas de modele tant que le site n'a pas demarre et que le type n'a pas ete sauvegarde. Ne jamais contourner par
Model.Value<T>("alias")- s'arreter et demander la regeneration. - Regle #8 : ASCII uniquement dans tout ce qu'on ecrit, accents francais obligatoires.
Verification
# changement non visuel -> zero pixel obligatoire
cd tools/fidelity && MSYS_NO_PATHCONV=1 node baseline.mjs --label wip --against current --site pdn --widths 1440
# visuel par construction -> contre le LIVE
MSYS_NO_PATHCONV=1 node diff.mjs --site pdn --path /vins/mousseux/ --local-path /vins/mousseux/ --widths 1440 --report-only
# etats d'interaction (CDP, la seule porte hover fiable)
MSYS_NO_PATHCONV=1 node interact.mjs --site pdn --path / --local-path /
# porte structurelle
MSYS_NO_PATHCONV=1 node probes/heights.mjs https://portedenovembre.ch/ http://portedenovembre.localtest.me:12953/ 375,768,1024,1440,1920
# porte complete avant chaque commit (~40 min, 54 pages x 5 largeurs)
MSYS_NO_PATHCONV=1 node baseline.mjs --label check --against currentBoucle build/run : taskkill //IM Web.exe //F -> dotnet build Gilliard.sln -> dotnet run --no-build --project src/Web/Web.csproj -> attendre un 200 -> /seed-pdn, /seed-pages, /seed-chevaliers. Un changement SCSS seul ne demande que npm run --prefix src/Web build. Les .cshtml et le C# exigent le rebuild complet + redemarrage - Razor ne se recharge pas a chaud ici.
Flottement connu du harnais : pdn/goodies @375 a une fois diffe de 512 px sur une region de 121x81 sans qu'aucun rendu n'ait change. Un nombre de pixels identique qui se repete (302, 327, 3072) est du bruit (UN element qui bascule), pas une regression - relancer un diff isole avant de le traiter comme telle.
Journal d'avancement
Mettre a jour a la fermeture de chaque phase. Une reprise doit pouvoir partir d'ici seul.
| Phase | Etat | Note |
|---|---|---|
| 0 - Plan + en-cours + pieges | FAIT | 6 commits. Voir le detail ci-dessous. |
| 1 - Audit mesure exhaustif | FAIT | fidelity-defect-ledger.md §A (contenu) + §B (navigateur, ~90 defauts) + pdn-wine-detail-spec.md. Les 3 contradictions de §C sont TRANCHEES le 2026-08-01 - l'agent avait tort 3 fois sur 3. |
| 2 - Modele de contenu / backoffice | 2.1 FAIT (aca3812) | 2.2 a 2.6 a faire. |
| 3 - Reconciliation contenu PDN (FR) | a faire | |
| 4 - Corrections systemiques | a faire | |
| 5 - Fidelite PDN par page | a faire | |
| 6 - Arbre allemand | EN COURS | Routage, chrome, dictionnaire et contenu DE de Chevaliers + PDN faits le 2026-08-17 (non commite). Reste Gilliard. |
| 7 - Validation finale | a faire |
Detail au 2026-07-30
Phase 0 - fait
- Plan ecrit dans le depot + reference dans
CLAUDE.md. - L'increment
SeedLibrarya ete commite par l'utilisateur lui-meme (370a697..b40540f), avec en prime la 5e cause de non-determinisme du harnais (images de fond CSS) - le harnais n'a plus de cause connue de flottement. - Le piege du controleur genere a mordu pour de vrai : regenerer
DevSeedChevaliersController.csa SUPPRIME 5 lignes ajoutees a la main (les 4 champs du portail d'age +newsletterConsent). Elles vivent maintenant danschevaliers-gen.py, et les deux generateurs emettentSeedLibrary. Verifie : une regeneration ne change plus rien. - En-tete de generateur perime corrige (
scratchpad/chev/gen.py->tools/seed-gen/). - Sondes :
audit_form.mjs+footer_social.mjsgardees,audit_cardtitle.mjsgeneralisee (ancres en argv, sortie 1 si une ancre manque),chev_home.mjssupprimee.probes/README.mddocumente desormais les 18 sondes parametrees, plus seulement les 14 a cible codee en dur. - Port chevaliers tranche par la mesure : les DEUX ports servent chevaliers (
DevSeedRootsControllerlie chaque marque a:12953ET:44360). Le commentaire deconfig.jset celui deprobes/README.mdetaient perimes ; les 9 sondes passent sur:12953(pas de certificat de dev a gerer).
Phase 1 - volet contenu fait
- Nouveau
tools/seed-gen/pdn-content-audit.mjs(lecture seule) +wxr-extract.mjsetendu a PDN (passthroughmetaspour_elementor_data,trGroupPolylang pour l'appariement FR/DE,parent,date,terms, et un seauotherpour que rien ne disparaisse en silence). - Resultats dans
fidelity-defect-ledger.md§A. Couverture et medias sont PROPRES (28/28 pages, 0 media orphelin). Le defaut net : les 7 pages de detail de vin sont amputees de 25-33 % du texte, et 19 des 28 noeuds portent un slug au lieu d'un titre. - Verifie sans regression sur gilliard et chevaliers (memes compte de pages/articles/personnes).
⭐ Une SIXIEME cause de non-determinisme du harnais, trouvee et corrigee (47cd400) La porte a signale une regression sur pdn/vins @1024 (35012 px). C'est la REFERENCE qui avait tort : une bouteille presente dans la nouvelle capture, absente de l'ancienne. Nos vues livrent loading="lazy" et le harnais forcait le lazy de b-lazy mais jamais le lazy NATIF. Mesure : vins-bottle-6.png ne chargeait que dans 1 execution sur 5. Corrige (+ l'apparition .js-reveal remontee avant le defilement et le balayage des fonds). Resultat : une passe complete de 54 pages x 5 largeurs est desormais identique a l'octet pres a travers un rebuild, un redemarrage du serveur et un re-seed des trois marques. La reference courante est le label ref (current et phase0, captures avant la correction, sont perimes et supprimables).
Phase 2.1 - pickers de categorie : FAIT, porte verte (aca3812)articlefields.config + childlisting.config (TextBox -> MNTP), childListing.cshtml (helper Cat(), appariement par cle de noeud, Slug() conserve sur le NOM pour ne pas deplacer les URL ?category=), BlogPost.cshtml, DevSeedSupport.NodePick(), DevSeedPagesController (SeedLibrary remonte AVANT les articles) et pdn-gen.mjs. Verifie : ?category= inchange, agregat PDN juste (25 + 5 = 30), porte a zero pixel sur 54 pages x 5 largeurs.
Phase 1 - AUDIT NAVIGATEUR : FAIT (2026-07-30)
Six agents de mesure en lecture seule, en parallele : accueil PDN, 7 detail-vin PDN, listings PDN, gilliard (22 pages), chevaliers (12 pages), chrome partage + interaction. Aucun n'a rien modifie. Sortie : fidelity-defect-ledger.md §B (~90 defauts chiffres) + pdn-wine-detail-spec.md.
Ce que l'audit a change dans notre comprehension (au-dela d'allonger la liste) :
- Quatre notes « connues » du projet etaient PERIMEES ou FAUSSES : le souligne de nav n'est plus centre-out chez nous ; les icones sociales gilliard/chevaliers ne sont plus des SVG en cercle ; l'icone de compte chevaliers n'existe plus ni ici ni la ; et
evenements +598 @375est devenu +120 avec le surplus passe cote desktop. - La carte de listing PDN n'est pas ce que decrit
pdn-resume.md: liste en une colonne, pas de sur-titre rose, categorie noire sous le titre. Construire d'apres l'ancienne description aurait produit un composant faux. - Mon entree B1 sur le
nowrapetait fausse : je l'avais tiree d'un message de commit et non d'une mesure. Corrigee en B1bis. - Le piege de portee est le risque n°1 : la gouttiere de 10px entre items de nav, mesuree sur gilliard et posee dans
base/, est fausse pour PDN. Chaque ligne du registre porte donc sa portee.
▶ REPRISE - par ou continuer
ETAPE 0 - FAIT le 2026-08-01. Les 3 contradictions sont tranchees (fidelity-defect-ledger.md §C1/C2/C3), par mesure de premiere main. Les 3 verdicts vont dans le meme sens : c'est l'AGENT qui avait tort a chaque fois.
- C1 souligne de nav : le live en peint bien un, sur gilliard ET chevaliers. L'agent chevaliers avait force
:hoversur le<a>alors que le live declenche depuis le<li>parent - faux negatif. Et cela corrige la note B0-1 : le live est CENTRE-OUT (left:0;right:0;margin:auto), nous sommes left-origin. Quatre defauts reels : origine, largeur (texte contrecalc(100%-15px)), easing, declencheur. - C2 ombre des cartes : cont.19 avait raison, notre CSS est deja exact au repos comme au survol. Ne rien changer - B5-5 est clos comme faux positif (l'agent n'avait matche aucune carte et a rapporte « aucune ombre »).
- C3 texte de la confidentialite PDN : parite, 731 mots contre 732. Les 274 mots d'ecart apparent etaient 209 mots de tableau de cookies genere par un plugin WordPress plus 66 mots de pied non filtre. Aucune correction de contenu ; le defaut de la page est typographique.
⚠️ Deux garde-fous qui en decoulent, a appliquer a toute ligne [AGENT] restante : un survol se force sur l'element ET ses ancetres ; et « selecteur sans correspondance » n'est jamais « propriete absente ».
Phase 4 - etat au 2026-08-01
| item | etat |
|---|---|
| (a) hauteur de l'en-tete | FAUX POSITIF, clos (§C4). L'en-tete est exact aux 5 largeurs, aux deux etats de defilement, accueil et page interieure, sur les deux marques. Ecart maximal 1px. |
| (b) interlignage du corps a 375 | FAIT (1947ec9). Le live porte un 24px absolu aux 5 largeurs sur les deux marques ; notre ratio ne decrochait qu'a mobile. Pose par THEME (le corps du live PDN varie de 24.48 a 30.6 selon la largeur - un 24px partage serait faux). Marge de paragraphe passee de 1rem a 1em au passage : elle vaut la taille de police du live, donc 20px sur chevaliers et non 16. |
(c) plafond max-width:772px du texte riche | NON REPRODUIT sur /nos-valeurs/ - les rangees mediaText y sont identiques au live au pixel pres aux 5 largeurs (paragraphe 540 dans une colonne plafonnee a 570, des deux cotes). B4-1 doit etre re-localise avant d'agir : le residu de cette page est ailleurs. A re-mesurer par page. |
| (d) le pied | FAIT (913b6c6). Modele complet du live reconstruit ; chevaliers passe de -48.3 a -1.0 @1440. Residu de gilliard -7.5 = le badge Trusted Shops du live, donc 1:1 atteint. Detail et decomposition : registre §C5. |
| (e) la carte d'activite | FAIT (9d8170c). Registre §B1ter. Ferme aussi B4-3. |
| (f) etats de survol et de focus | souligne de nav FAIT (c49a6a9) : origine CENTREE, largeur exactement 50% de la boite du lien (49.99% sur les 8 liens testes des deux marques), ease-in-out, declenche par li:hover. Restent : l'anneau de focus des champs (B1-1), la transition et le padding des boutons (B1-18), et le residu ease-out contre ease des cartes (§C2). |
| (g) halo d'ombre des cartes - signale par l'utilisateur | FAIT (c9c1cdb). L'ombre de 99px etait portee par la COLONNE (450x411) et non par la CARTE (406x389) : un halo a bords francs 22px au-dela de la photo, lu comme un panneau traverse d'un filet. Toute la geometrie interne etait pourtant exacte au pixel. Voir §C6 : c'est la classe de defaut qu'aucune sonde par element ne peut trouver. Le pas de rangee est reconstruit au passage (ecart de 47.0px entre boites de carte a toutes les largeurs, mesure sur le live). |
⚠️ Verifier la portee de chaque ligne avant d'ecrire dans base/ et re-mesurer les trois marques apres : c'est la seule protection contre le piege qui a produit la gouttiere de nav.
Puis, dans cet ordre :
- Phase 2.2
factsPanel- motive par une mesure, pas seulement par l'experience editeur : c'est ce qui repare la bande « Détails » supprimee a tort sur les 7 pages de vin. Specification complete danspdn-wine-detail-spec.md§B. Ne pas rendre les 3 lignes queice-0-0masque. - Phase 5 - PDN par page, en commencant par le hero deux colonnes des 7 detail-vin (
pdn-wine-detail-spec.md§A, complet aux 5 largeurs) et la carte de listing refaite d'apres la vraie structure (§B3), puis l'accueil (echelle de bouteille par slide, fondu enchaine du slider, survol de la grille de vins) et le formulaire d'adhesion de /club/, jamais migre. - Puis 2.3 a 2.6, phase 3 (contenu PDN depuis l'export), phase 6 (allemand), phase 7.
Etat du serveur : builde, demarre sur :12953, les trois marques seedees. Web.csproj est bien revenu a son etat normal (Razor compile au build) apres le cycle de regeneration. Reference du harnais : label ref (270 captures, harnais corrige). Commande de porte : cd tools/fidelity && MSYS_NO_PATHCONV=1 node baseline.mjs --label <nom> --against ref. ⚠️ La reference ref est PERIMEE depuis le 2026-08-01 : sept commits visuels par construction sont passes depuis. Refaire une baseline avant de s'en servir comme porte a zero pixel.
Session du 2026-08-01 - ce qui a ete fait
Sept commits, tous mesures contre le live avant ET apres, aucun pousse.
| commit | objet |
|---|---|
1afec5c | Les 3 contradictions de §C tranchees - l'agent avait tort 3 fois sur 3 |
913b6c6 | Le pied de page reconstruit sur le modele mesure du live (chevaliers -48.3 -> -1.0 @1440) |
1947ec9 | Interligne de corps absolu et marge de paragraphe en em (les deux marques) |
9d8170c | Carte d'activite : repere, echelle 0.8em, chevron, chevauchement du titre |
c49a6a9 | Souligne de nav : centre, 50% exactement, ease-in-out, declenche par li:hover |
c9c1cdb | Le halo d'ombre signale par l'utilisateur + le pas de rangee des grilles de cartes |
8f51e7e | §C6 (pourquoi une mesure par element rate ce defaut) + 3 sondes de composition |
Deux items du plan se sont reveles etre des FAUX POSITIFS et sont clos sans correction : la hauteur de l'en-tete (§C4) et l'ombre des cartes (§C2). Un troisieme est a re-localiser : le plafond max-width:772px (4c) ne se reproduit pas sur /nos-valeurs/, ou les rangees mediaText sont identiques au live au pixel pres aux 5 largeurs.
Suite de la session - le passage a la mesure CONTRE LE LIVE
Sur demande de l'utilisateur (« tu dois correspondre au live, alors pourquoi ne verifies-tu pas le live ? »), bascule de « sonde ciblee » a sweep.mjs / diff.mjs sur les 52 pages des 3 marques, puis agregation des registres de couverture. Referentiel et limites : registre §C7.
| commit | objet |
|---|---|
c2ba7a0 | Icones d'en-tete = les vrais fichiers du live + masquage du popup Mailchimp qui rendait la porte non deterministe (±11 points) |
792e901 | Le pied de PDN, absent sur 25 pages sur 25 - les 4 colonnes tombent sur les x et largeurs du live |
1cd95ca | Typographie du pied PDN (rien n'y est rose, rien n'y ride le corps de 20.4px) |
37627d7 | La bande « Détails » des 7 pages de vin, restauree - chaque nombre identique au live |
⚠️ Lire le diff pixel PDN avec la bonne cle. Apres la restauration de la bande, les pages de vin montent en pourcentage de pixels (johannisberg 40.3 -> 48.8) et c'est attendu : la bande est identique au live, mais elle se pose a Y2013 chez nous contre Y1017 sur le live, parce que le hero deux colonnes n'est pas encore construit au-dessus. Tout ce qui suit est donc decale. Le signal juste est l'alignement du registre, qui monte (johannisberg 50.4 -> 59.5 %, ice-rose 51.2 -> 59.6, evenements 50.5 -> 54.4) : davantage de noeuds du live ont un correspondant.
Session du 2026-08-01 (suite) - la carte de listing terminee, et deux defauts qu'elle a reveles
| commit | objet |
|---|---|
6563127 | L'extrait de la carte de listing, vide sur les six pages : la source (excerpt -> body -> texte des BLOCS), l'extrait manuel des 4 cocktails repris de l'export, et la longueur en donnee de bloc (excerptWords : 16 Gilliard, 30 PDN) |
1e9f1d2 | cards-archive, affichage a part - et Gilliard cesse d'imprimer « 1 janvier 0001 » a cote de chaque titre de son blog (regression de ff70347). publishDate seede depuis le WXR : la date ET le tri date-desc |
dbbc2b1 | L'echelle typographique de PDN (B3-9) : le ROOT descend a 16px sous 768, le 1.2rem n'arrive qu'a 1280 |
Carte de /cocktails/ @1440 : 848x739 @x296 contre les 848x740 @x296 du live, titre / meta / extrait / fleche aux quatre memes offsets. Diff pixel de la page >=29 % -> 18.09 %. Porte de hauteur de la page aux 4 largeurs : -31 / +11 / -599 / -80. Registre : §C10 (la carte + la regression Gilliard) et §C11 (l'echelle typographique).
⚠️ Deux enseignements de methode, encore les memes : le defaut « extrait vide » n'etait pas du CSS mais un CHAMP vide, trouve en lisant la donnee et non la feuille de style ; et la regression Gilliard n'a ete vue qu'a la capture d'ecran - toutes les sondes par element la traversaient sans rien dire, parce qu'aucun element n'etait faux (§C6 encore).
Session du 2026-08-01 (fin) - le CADRE de PDN, la grille produits, et 4c enfin ferme
| commit | objet |
|---|---|
de9fb92 | L'echelle de conteneur de PDN est FLUIDE, pas un escalier Bootstrap (registre §C12) |
c477a4c | La grille produits de /goodies/ et /idees-cadeaux/ (§C13) |
e594b38 | 4c ferme : la colonne du richIntro suit la proportion du live aux trois largeurs |
Deux de ces trois defauts ont ete trouves en mesurant autre chose : le conteneur en mesurant la grille produits, le doublon de titre a la capture d'ecran. Aucun n'apparaissait dans le registre tel quel.
Referentiel PDN a jour, diff pixel contre le live :
| page | 375 | 768 | 1024 | 1440 |
|---|---|---|---|---|
| cocktails | 46.0 | 32.0 | 24.4 | 18.1 |
| goodies | 20.6 | 18.9 | 19.9 | 19.6 |
| idees-cadeaux | 38.2 | 37.3 | 41.1 | 48.0 |
| home | 53.6 | 46.0 | 60.4 | 29.1 |
| vins | 60.1 | 49.7 | 33.3 | 27.6 |
| detail-vin (x7) | 29-32 | 39-41 | 46-51 | 17-21 |
| club | 38.8 | 43.8 | 43.9 | 31.3 |
| privacy | 54.2 | 40.0 | 49.8 | 40.5 |
| contact | 33.2 | 34.6 | 33.7 | 36.0 |
Gilliard et chevaliers a 1440 : inchanges par rapport au referentiel §C7 (verifie page par page apres le changement de base/ de 4c).
Dernier commit de la session - B3-2, l'intro dans le hero (f49c9fa)
Le residu de /idees-cadeaux/ etait bien « ailleurs sur la page » : c'etait B3-2, et il valait +181 a +346px sur onze pages. L'intro du live est DANS la bande de titre, pas sous elle. Detail, tableau de mesures et les trois pieges de portee rencontres : registre §C14.
Sweep des 20 pages PDN apres : -27.6 points a 1440 et -60.6 a 375 au total. goodies 44.7 -> 23.2 / 40.2 -> 14.7 · idees-cadeaux 56.3 -> 35.9 / 56.4 -> 32.4 · accueil 53.6 -> 43.1 a 375 · cocktails 18.1 -> 14.1 a 1440.
▶ CE QUI RESTE, dans l'ordre de valeur
- Accueil PDN - 43.1 a 375 / 29.1 a 1440. Trois items deja mesures en §B2 : l'echelle de la bouteille par slide, le fondu enchaine du slider (le live fond SUR PLACE, nous faisons glisser un Swiper horizontal - un autre mecanisme), le survol de la grille de vins. Plus B2-9 (la bande 2 du live porte deux images 270x461.7 aux x135 et x435 ; nous en rendons une de 643x428.7 @x77) et B2-1 (bande 2 en deux colonnes a 768, nous empilons).
- Le formulaire d'adhesion de
/club/, jamais migre (11 champs, B3-1). C'est 932px de hauteur manquante a 1440, et/club/est la page qui a le plus recule au dernier commit precisement parce qu'elle est deja la plus courte. - B3-13
/contact/: notre bande finale GRANDIT avec la fenetre (+586 a 1440) alors que le live est constant a 2545 de 1440 a 1920. C'est le seul endroit ou la correction du conteneur a coute des pixels, et la cause est cette bande. - B3-5 : la bande « Articles récents » manque sur les deux articles PDN (-552 a -1236 a la porte de hauteur). C'est ce qui rend les pages d'article si courtes.
- Puis les phases 2.3 a 2.6, 3 (contenu PDN depuis l'export), 6 (allemand), 7.
Prochain item, et il debloque les 7 pages d'un coup : le HERO DEUX COLONNES du detail-vin (pdn-wine-detail-spec.md §A, complet aux 5 largeurs). C'est lui qui remettra la bande « Détails » a la hauteur du live et fera retomber le pourcentage de pixels. Ensuite : la carte de listing (§B3), l'accueil PDN, puis 2.3 a 2.6.
Avant de declarer une bande conforme, appliquer la regle de §C6.
Session du 2026-08-03 - B2-9 et la couleur du texte courant
| commit | objet |
|---|---|
05f3bb7 | La bande 2 de l'accueil porte DEUX photos : nouvel affichage duo + propriete secondImage sur mediaText (registre §C15) |
efc5635 | Le texte courant de PDN est NOIR, pas gris fonce - $pdn-ink-light declaree une fois (§C17) |
Ce que la mesure a corrige dans le registre lui-meme :
- B2-9 etait mal localise. La ligne le chiffrait a 1440, ou il vaut +21px. Le vrai poids est a 768 (+418) et 1024 (+552) : le live passe en deux colonnes des 768, nous empilions jusqu'a 1440. Contre le live : 768 46.0 -> 20.6, 1024 60.4 -> 46.7, 1440 29.1 -> 26.0.
- B2-4 (« la photo de la bande 4 ne s'affiche pas, 466x0 ») est PERIME :
media-text--panelporte depuis une specification mesuree qui vise exactement 466x596. A verifier avant d'agir. - §C16 : le diff pixel de
pdn/homen'est PAS deterministe (49.4 / 49.4 / 38.3 sur trois passes du meme build). Le 43.1 @375 consigne a la session precedente n'est donc pas comparable a un nombre mesure aujourd'hui. Cette page se juge par bande, pas au pourcentage.
Corrections a ce fichier : le paragraphe « Prochain item ... le HERO DEUX COLONNES du detail-vin ... Ensuite la carte de listing, l'accueil PDN » (fin de la section precedente) etait perime - le hero et la carte de listing sont faits depuis. Et la liste « CE QUI RESTE » saute le numero 3 et devrait lire « 2.2 (moitie restante) a 2.6 », parce que la phase 2.2 n'est faite que du cote PDN : factsPanel n'est compose dans aucun doctype, productfacts.config porte encore ses 6 proprietes d'affichage et _pageFacts.cshtml leurs 6 libelles codes en dur.
Reste sur l'accueil PDN : l'echelle de bouteille par slide et le fondu enchaine du slider (tous deux dans la region masquee, donc invisibles au pourcentage de pixels - ce sont des items d'interaction, a juger a interact.mjs), le survol de la grille de vins, B2-1 (bande 2 en deux colonnes a 768 - fait avec §C15), et l'illustration de raisin de la bande 3, trop grande et chevauchant le titre a 768 (vu a la capture, absent du registre).
Deux dettes reperees en passant. VERIFIEES puis SOLDEES le meme jour - et l'une des deux etait une fausse alerte de ma part :
- ❌ «
pdn-gen.mjsposeoverlaysur des specs quecase "mediaText"n'emet jamais, image silencieusement perdue » - C'ETAIT FAUX, deux fois. Mesure : les deux visuels peignent des deux cotes (photo 500x619 @y150, bouteille 290x567 @y177, live et local identiques). Et ce n'est meme pas du code mort : l'addMedia()de cette ligne est ce qui ENREGISTRE l'asset<slug>-bottle-<i>que le hero produit consomme ensuite par son nom viaheroOverlayImage. La « nettoyer » aurait fait disparaitre la bouteille des SEPT pages de vin. Un avertissement est desormais pose sur la ligne. Rien a corriger : la dette est SUPPRIMEE du registre. - ✅ ButtonPicker
Core - Media Text Display- reelle :wineetproduct-detailsont emis par le generateur et absents du selecteur, donc invisibles a l'editeur. Corrige : les deux valeurs y sont ajoutees.
Regle qui en decoule, et c'est le point : une ligne « dette reperee en passant » n'est PAS un constat, c'est une hypothese. Elle se verifie avant d'etre portee, et la verification la corrige ou la supprime aussi souvent qu'elle la confirme. Voir le commit 3994a28, dont le message est litteralement « solder les deviations que j'avais CONSIGNEES sans les corriger » : ce depot a deja paye ce defaut de methode.
Fin de session du 2026-08-03 - le formulaire du club, et les dettes soldees
| commit | objet |
|---|---|
e1238e0 | Le formulaire d'adhesion de /club/ (B3-1), jamais migre - la bande DISPARAISSAIT (embed Mailchimp dans un widget html qu'aucune branche ne reconnaissait). Bande a 602 contre 601. Registre §C18 |
35f3831 | Les deux dettes de la veille soldees - dont une qui etait FAUSSE, et dont le « nettoyage » aurait casse les 7 pages de vin. Nouveau tableau « Dettes et constats hors phase » |
Bilan de la session : 5 correctifs (B2-9, B3-14, B3-1, ButtonPicker, et une fausse dette supprimee), 4 notes perimees corrigees, 0 regression sur les 3 marques.
⚠️ La reference ref-20260803 est desormais PERIMEE : trois commits visuels par construction sont passes depuis (B2-9, l'encre, le formulaire du club). Refaire une baseline complete AVANT de s'en servir comme porte a zero pixel. Les labels b29-*, club-*, ink-*, picker-* sont des brouillons de session, supprimables.
Session du 2026-08-17 - l'arbre allemand : Chevaliers et PDN portes, un bug de fond trouve
Etat : non commite. Tout ce qui suit est dans l'arbre de travail.
Le bug qui rendait tout le travail DE invisible. DevSeedSupport.BuildBlockEditorValue ecrivait culture: null dans expose ET dans chaque valeur de bloc. Sur une propriete qui varie par culture, cela stocke, publie et affiche correctement dans le backoffice - et rend une page vide dans toute culture autre que la langue par defaut. Mesure : chevaliers /de/vinothek/ = 11,3 Ko de chrome contre 23,7 Ko pour la page FR, sans une seule erreur nulle part. C'est pour ca que le DE de PDN commite le 14 aout (024b27f) ne rendait rien : les 7 articles avaient leur contenu en base, publie, et servaient une page vide. Corrige aux deux niveaux, avec Grid(blocs, culture) et ListIn(culture, blocs) ; sans culture, le comportement par defaut est inchange. Regle et symptome a reconnaitre : ../modules/content-model.md, section « Blocs et cultures ».
Racines (DevSeedRootsController) : la culture de est posee et publiee sur toute marque qui a un domaine /de. C'etait le blocage du routage - les domaines etaient lies depuis le 13 aout, mais une racine sans nom allemand n'a aucune variante a servir, d'ou le 404. EnsureCultures rattrape aussi les racines deja creees, sinon le chemin « already correct - untouched » les aurait laissees FR pour toujours.
Contenu, methode. Le DOM du live fait foi, comme pour le francais : scrape allemand puis generation.
| marque | source | resultat |
|---|---|---|
| Chevaliers | chevaliers-bands.py --lang de (le DE est a la RACINE du live, le FR sous /fr/) | 10 pages DE : accueil, Marken, Vinothek, Wohnung, Kontakt, Domaines Chevaliers, 2 listings, 2 pages legales |
| PDN | pdn-bands.mjs --lang de (Playwright, 22 pages) | accueil, Weine + 7 detail-vin, Der Club, Kontakt, Geschenkideen, Goodies, confidentialite, cocktails, news, 6 articles |
| Gilliard | aucune | rien - voir ci-dessous |
Structure mesuree avant de generer : 20/20 pages identiques cote PDN (meme suite de bandes FR/DE), 5/6 cote Chevaliers - la sixieme (domaines-chevaliers) a une rangee de plus en allemand sur le live. Comme contentBlocks varie par culture, l'allemand porte sa propre liste de blocs : aucun alignement par index n'est necessaire, et l'ecart du live est reproduit tel quel.
Chrome et dictionnaire. Nav, pied, newsletter et portail d'age en allemand sur les deux marques (toutes ces proprietes de siteSettings varient par culture). Les liens de la nav DE sont resolus par NOEUD, pas par URL - une nav allemande qui lie par URL fait sortir le visiteur de l'arbre /de. Dictionnaire : 28 entrees traduites + 8 libelles de chrome codes en dur sortis des vues vers le dictionnaire (_header, _footer, _footerSocials, newsletterSignup) - c'etait de l'aria-label francais sur une page allemande, et c'est un item de la phase 2.4 solde au passage.
Non-regression francaise, verifiee et pas supposee : sans les fichiers -de, les deux generateurs reproduisent exactement le controleur d'avant ; avec eux, git diff ne montre que des ajouts et le registre media FR est identique a HEAD. Une premiere version de la passe allemande s'etait glissee avant la francaise dans l'enregistrement des medias et avait renomme cucumber-november-hero en cocktails-hero-de (meme fichier, meme rendu, mais un media francais nomme d'apres une page allemande dans la bibliotheque) : la passe DE tourne desormais apres toutes les pages francaises.
Verification : base SQLite supprimee et refaite de zero, les 5 seeders rejoues, puis 21/21 pages FR et 25/25 pages DE en 200, chrome et popup cookies dans la bonne langue de chaque cote.
Ce qui reste sur la phase 6 :
- Gilliard. Ses 39 pages allemandes sont dans l'export, mais ses pages francaises sont composees a la main en C# (
DevSeedPagesController, 1308 lignes) : ni scrape, ni generateur, donc aucun chemin mecanique. Mesure faite avant d'abandonner cette piste : une table FR -> DE construite depuis l'ACF de l'export ne couvre que 28 % des chaines du seeder, avec 89 conflits - elle produirait des pages « allemandes » majoritairement francaises. La voie propre est un scraper DE sur le modele depdn-bands.mjs, dont les blocs DE seraient generes pendant que le FR reste ecrit a la main. - Les listings DE de Chevaliers (
/de/events/,/de/aktivitaeten/) rendent leur bloc de requete mais listent des enfants qui n'ont pas de culture allemande : evenements et activites restent FR. - Deviations d'URL consignees dans
assets-substitues.md§12.

