Textes projet éditables suivant Grav + écriture atomique du store

- Champ Présentation prérempli avec le texte Grav, suivi modifié/synchro
  (textOverride undefined = suit Grav, sinon figé ; bouton Réinitialiser)
- Fix génération PDF : savePortfolio écrit en atomique (temp+rename) pour
  éviter la corruption de lecture par l'autosave concurrent du rendu print
- Toast d'échec de génération explicite (message serveur)
- Refonte architecture visuelle, fond unifié white/tint/full, dispositions
  couverture bandeau/colonne, instantané public complet, index 3 lignes
This commit is contained in:
2026-07-06 13:26:06 +02:00
parent 59dfbe4155
commit ef1f14335d
22 changed files with 750 additions and 334 deletions
+25 -5
View File
@@ -40,11 +40,18 @@ Mot de passe dev : `figureslibres` (`PORTFOLIO_PASSWORD`).
## Modèle de données (résumé)
Un `Portfolio` = `cover` (CoverConfig) + `pages[]`. Types de page : `cover`,
`toc`, `project` (couverture bandeau + image), `project-grid` (grille d'images
entières), `free`. Le contenu Grav (`Project`, `MediaAsset`) est **en lecture
seule**. À la génération, le contenu utilisé est **figé** dans `data/frozen/<id>/`
(`FrozenSnapshot`) : régénérer redonne le même PDF ; « Réactualiser depuis Grav »
resynchronise volontairement.
`toc`, `project` (couverture d'un projet, disposition `band` = bandeau haut **ou**
`split` = colonne texte + image pleine hauteur à droite), `project-grid` (grille
d'images entières), `free`. Le contenu Grav (`Project`, `MediaAsset`) est **en
lecture seule**. À la génération, le contenu utilisé est **figé** dans
`data/frozen/<id>/` (`FrozenSnapshot`) : régénérer redonne le même PDF ;
« Réactualiser depuis Grav » resynchronise volontairement.
Chaque page porte un **fond unifié** `background` à trois modes :
`white` | `tint` (aplat beige fixe `#efece3`) | `full` (la page — ou le bandeau /
la colonne d'une couverture projet — prend la couleur du filet `bandColor`, défaut
encre `FL_INK`). Il n'y a **plus** de couleur automatique par catégorie
(`bandColorOf`/`stripColorOf` retombent sur `FL_INK`).
## Contraintes fermes
@@ -53,6 +60,19 @@ resynchronise volontairement.
- Les vidéos ne sont pas sélectionnables dans les grilles.
- Format PDF : A3 paysage aux dimensions exactes du gabarit.
## Conventions de rendu (templates)
- **Fond `background`** : `useTheme` → `backgroundColorOf(bg, fullColor)` /
`backgroundStyle(bg, fullColor)`. Le mode `full` **dérive** sa couleur du filet
au rendu (`fullColor`) — ne rien stocker en dur ; le `BackgroundEditor` (Blanc /
Teinté / Plein) est le même sur tous les types de page.
- **Syne toujours en Regular** (poids 400), y compris titres et gras de prose ;
seule exception : le mot « Figures Libres » de la couverture (Bold).
- **Liens Grav** : `stripTargetParam` retire le `?target=_blank` que Grav accole à
chaque URL (lien projet + liens dans les corps de texte), à l'affichage.
- Filet : `--fl-strip` (5 mm, couverture/sommaire/page libre) ou `--fl-strip-light`
(2 mm, filet fin des grilles et des couvertures projet non « plein »).
## Pièges Chromium print (avant de toucher aux templates)
- **`columns-*` (CSS multicol) = page PDF blanche** dans Chromium print. Ne pas