Défaut 4 — la page /recherche restait en thème sombre en dur (data-theme="dark") quel que soit le réglage de l'utilisateur.
Mécanisme audité (preuves dans le code) : le thème ObsiGate n'est PAS une préférence serveur. La SPA le lit dans localStorage au démarrage — frontend/js/ui.js initTheme (mode seul, première peinture) puis frontend/js/sync.js init() -> frontend/js/themes.js initThemes (clé + mode, palette complète en variables inline sur :root). Clés : obsigate-theme (clé : spark, dracula, … ou historiquement un mode) et obsigate-theme-mode (dark | light | high-contrast | sepia). 16 thèmes intégrés, modes high-contrast/sepia générés, thèmes personnalisés importables.
Correctif (3 fichiers, aucun autre dépôt/fichier touché) :
frontend/recherche.html — étape 1 : script synchrone en tête, avant les feuilles, pose data-theme = mode persisté avant la première peinture (obsigate-theme-mode, repli obsigate-theme historique si c'est déjà un mode, sinon dark, le défaut SPA) ; étape 2 : module différé qui appelle initThemes() de themes.js (seule source de vérité, aucune table recopiée) pour la palette complète, avec garde historique et échec silencieux (la page garde alors le mode de l'étape 1).
frontend/recherche.css — color-scheme par mode ; barre déclinée pour light/high-contrast/sepia (draco-barre.css, fichier commun vendangé, NON modifié : il ne connaît que [data-theme="dark"], sinon sa media query prefers-color-scheme:dark imposerait une barre sombre sur une page claire) ; bordures/accents .rp-* branchés sur var(--border)/var(--accent) avec les anciennes valeurs en repli.
Non touchés, volontairement : backend/main.py et sa CSP stricte (les 2 scripts inline reçoivent le nonce via inject_csp_nonce, vérifié en test ; aucune police externe ajoutée, repli typographique système inchangé), frontend/js/recherche.js (partagé avec les 3 autres hôtes), frontend/js/themes.js, style.css, draco-barre.css. Pas de bump de version, pas de merge, pas de changement d'état d'issue.
Tests sandbox (chiffres réels) : 7/7 tests pytest livrés passent (exécutés sans pytest, indisponible en sandbox, par appel direct des fonctions) ; harnais Node étape 1 : 11/11 cas (light/dark/sepia/high-contrast, clé dracula -> dark, historique light -> light, vide -> dark, stockage indisponible -> dark) ; node --check OK pour les 2 scripts inline et themes.js ; accolades CSS équilibrées (42/42).
Non exécutable en sandbox : pytest via la CI du dépôt, et validation déployée (rendu réel clair/sombre/sépia/high-contrast + thème personnalisé, capture) — à faire par Bruno après merge/redéploiement. Delta explicite : en high-contrast/sepia ou thème personnalisé, la première peinture utilise le mode style.css (sombre par défaut pour HC) puis la palette exacte s'applique dès le chargement différé de themes.js ; impossible de faire mieux sans dupliquer la table de 50 Ko de themes.js.
Défaut 4 — la page /recherche restait en thème sombre en dur (data-theme="dark") quel que soit le réglage de l'utilisateur.
Mécanisme audité (preuves dans le code) : le thème ObsiGate n'est PAS une préférence serveur. La SPA le lit dans localStorage au démarrage — frontend/js/ui.js initTheme (mode seul, première peinture) puis frontend/js/sync.js init() -> frontend/js/themes.js initThemes (clé + mode, palette complète en variables inline sur :root). Clés : obsigate-theme (clé : spark, dracula, … ou historiquement un mode) et obsigate-theme-mode (dark | light | high-contrast | sepia). 16 thèmes intégrés, modes high-contrast/sepia générés, thèmes personnalisés importables.
Correctif (3 fichiers, aucun autre dépôt/fichier touché) :
- frontend/recherche.html — étape 1 : script synchrone en tête, avant les feuilles, pose data-theme = mode persisté avant la première peinture (obsigate-theme-mode, repli obsigate-theme historique si c'est déjà un mode, sinon dark, le défaut SPA) ; étape 2 : module différé qui appelle initThemes() de themes.js (seule source de vérité, aucune table recopiée) pour la palette complète, avec garde historique et échec silencieux (la page garde alors le mode de l'étape 1).
- frontend/recherche.css — color-scheme par mode ; barre déclinée pour light/high-contrast/sepia (draco-barre.css, fichier commun vendangé, NON modifié : il ne connaît que [data-theme="dark"], sinon sa media query prefers-color-scheme:dark imposerait une barre sombre sur une page claire) ; bordures/accents .rp-* branchés sur var(--border)/var(--accent) avec les anciennes valeurs en repli.
- tests/test_recherche_theme.py — 7 tests (étapes 1/2, garde historique, nonces CSP des 3 scripts inline, déclinaisons barre, accents, invariants).
Non touchés, volontairement : backend/main.py et sa CSP stricte (les 2 scripts inline reçoivent le nonce via inject_csp_nonce, vérifié en test ; aucune police externe ajoutée, repli typographique système inchangé), frontend/js/recherche.js (partagé avec les 3 autres hôtes), frontend/js/themes.js, style.css, draco-barre.css. Pas de bump de version, pas de merge, pas de changement d'état d'issue.
Tests sandbox (chiffres réels) : 7/7 tests pytest livrés passent (exécutés sans pytest, indisponible en sandbox, par appel direct des fonctions) ; harnais Node étape 1 : 11/11 cas (light/dark/sepia/high-contrast, clé dracula -> dark, historique light -> light, vide -> dark, stockage indisponible -> dark) ; node --check OK pour les 2 scripts inline et themes.js ; accolades CSS équilibrées (42/42).
Non exécutable en sandbox : pytest via la CI du dépôt, et validation déployée (rendu réel clair/sombre/sépia/high-contrast + thème personnalisé, capture) — à faire par Bruno après merge/redéploiement. Delta explicite : en high-contrast/sepia ou thème personnalisé, la première peinture utilise le mode style.css (sombre par défaut pour HC) puis la palette exacte s'applique dès le chargement différé de themes.js ; impossible de faire mieux sans dupliquer la table de 50 Ko de themes.js.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Défaut 4 — la page /recherche restait en thème sombre en dur (data-theme="dark") quel que soit le réglage de l'utilisateur.
Mécanisme audité (preuves dans le code) : le thème ObsiGate n'est PAS une préférence serveur. La SPA le lit dans localStorage au démarrage — frontend/js/ui.js initTheme (mode seul, première peinture) puis frontend/js/sync.js init() -> frontend/js/themes.js initThemes (clé + mode, palette complète en variables inline sur :root). Clés : obsigate-theme (clé : spark, dracula, … ou historiquement un mode) et obsigate-theme-mode (dark | light | high-contrast | sepia). 16 thèmes intégrés, modes high-contrast/sepia générés, thèmes personnalisés importables.
Correctif (3 fichiers, aucun autre dépôt/fichier touché) :
Non touchés, volontairement : backend/main.py et sa CSP stricte (les 2 scripts inline reçoivent le nonce via inject_csp_nonce, vérifié en test ; aucune police externe ajoutée, repli typographique système inchangé), frontend/js/recherche.js (partagé avec les 3 autres hôtes), frontend/js/themes.js, style.css, draco-barre.css. Pas de bump de version, pas de merge, pas de changement d'état d'issue.
Tests sandbox (chiffres réels) : 7/7 tests pytest livrés passent (exécutés sans pytest, indisponible en sandbox, par appel direct des fonctions) ; harnais Node étape 1 : 11/11 cas (light/dark/sepia/high-contrast, clé dracula -> dark, historique light -> light, vide -> dark, stockage indisponible -> dark) ; node --check OK pour les 2 scripts inline et themes.js ; accolades CSS équilibrées (42/42).
Non exécutable en sandbox : pytest via la CI du dépôt, et validation déployée (rendu réel clair/sombre/sépia/high-contrast + thème personnalisé, capture) — à faire par Bruno après merge/redéploiement. Delta explicite : en high-contrast/sepia ou thème personnalisé, la première peinture utilise le mode style.css (sombre par défaut pour HC) puis la palette exacte s'applique dès le chargement différé de themes.js ; impossible de faire mieux sans dupliquer la table de 50 Ko de themes.js.