"""Version HTML des emails — même thème que l'appli (couleurs/typographie de `frontend/tailwind.config.js`), logo de l'édition en en-tête si défini. Chaque email reste envoyé en `multipart/alternative` (texte + HTML, voir `app/email/sender.py:build_message`) : le texte brut reste la source de vérité (accessibilité, clients sans HTML, RGPD — rien de plus dans le HTML que dans le texte déjà journalisable). Pas de CSS externe ni de police web (rarement chargées par les clients mail) : mise en page par tableau, styles en ligne, polices système en repli du style « Archivo »/« DM Mono ».""" import html as _html _INK = "#14110E" _CREAM = "#F5EFE1" _PAPER = "#FFFDF7" _YELLOW = "#FFD23F" _FONT_DISPLAY = "Arial, Helvetica, sans-serif" _FONT_MONO = "'Courier New', Courier, monospace" # Identifiant de la pièce jointe « inline » du logo (voir # `app/email/sender.py:build_message`) — jamais une URL externe avec le # `access_token` du formulaire public en requête : n'importe quel # destinataire d'un email (lien magique, confirmation d'inscription…) aurait # pu lire ce jeton depuis la source du message, pas seulement la coordination. LOGO_CID = "edition-logo" def _paragraphs(body: str) -> str: """`\n\n` sépare les paragraphes, un simple `\n` reste un retour à la ligne — même convention que les modèles texte (`app/email/templates.py`).""" blocks = body.strip().split("\n\n") return "".join( f'
{_html.escape(block).replace(chr(10), "
")}
|