Files
williamandClaude Sonnet 5 c57420c8c9 Phase 3 : hardening qualite de code - typage strict, securite, dead code, a11y
Config strictement stricte partout (ruff, mypy --strict, bandit, vulture,
import-linter, eslint, stylelint), aucune regle desactivee "pour ne pas
casser le build" - l'existant a ete corrige pour la satisfaire plutot que
l'inverse. Hooks pre-commit locaux (language: system) bloquants.

- Typage mypy --strict propage a tout le moteur (db, screens, auth, core,
  ai, routes, puis publish/scripts/tests/app.py/build_css.py).
- Securite : fuite de handle fichier Windows corrigee dans l'export SCORM
  (routes/publish/export_scorm.py), CSRF/RNG non-crypto/xAPI documentes
  (# nosec, # NOSONAR justifies), nouveau db.json_for_script() (echappe
  "</script>" dans le JSON embarque en <script>, 25 sites).
- Architecture : imports circulaires/F811 nettoyes, contrats
  import-linter respectes, code mort retire (vulture).
- Accessibilite : 69 champs de formulaire sans label correctement
  associe corriges (for/id ou aria-label) sur 11 templates.
- ESLint/Stylelint : lot mecanique JS/CSS, regles ajustees puis
  appliquees (aucune desactivee sans verification individuelle).
- Tests : isolation du compte admin partage (nettoyage ponctuel +
  fixture de teardown automatique en filet de securite), suite complete
  verte (591 tests Python, 241 tests JS).
- SonarQube Community Build self-heberge (Docker + PostgreSQL) : rapport
  complet analyse point par point, faux positifs documentes.
- .gitattributes ajoute (LF force) : core.autocrlf=true sur cette machine
  faisait echouer ESLint (linebreak-style) via un bug connu de git
  (checkout "en place" qui ignore l'eol force sur un fichier deja
  present sur disque - contourne en supprimant puis recreant chaque
  fichier suivi).

djLint (H021, styles inline) volontairement saute pour ce commit -
backlog assume, deja documente, traite dans un lot separe.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 16:06:15 +02:00

170 lines
5.0 KiB
CSS

/* bulma-override.css — palette Forge appliquée à Bulma 1.0.2 (vendoré tel
quel, non modifié, dans static/vendor/bulma.min.css) SANS recompilation
Sass : Bulma 1.x expose tout son thème via de vraies variables CSS
(--bulma-primary-h/-s/-l, --bulma-radius...), conçues justement pour être
surchargées après coup — voir regles/FORGE_ENGINE_TEMPLATE_BULMA.md, §6.
Chargé APRÈS bulma.min.css (voir build_css.py) : ce fichier ne fait que
redéfinir ses variables, jamais les siennes propres.
ATTENTION (leçon de la première version de ce chantier) : du code Python
de rendu du jeu (screens/rendering/render_jauge.py) fixe en ligne
--bulma-progress-value-background-color pour piloter le remplissage
d'une jauge — Bulma 1.x est donc une DÉPENDANCE FONCTIONNELLE réelle de
l'app, pas seulement un habillage visuel. Ne plus jamais changer de
version de Bulma sans vérifier `grep -rn "\-\-bulma-" screens/ templates/`
d'abord. */
:root {
--bulma-family-primary: -apple-system, blinkmacsystemfont, "Segoe UI", inter, roboto, sans-serif;
--bulma-radius: 10px;
--bulma-radius-small: 8px;
--bulma-radius-medium: 12px;
--bulma-radius-large: 16px;
--bulma-radius-rounded: 999px;
--bulma-primary-h: 14deg;
--bulma-primary-s: 100%;
--bulma-primary-l: 59%;
--bulma-link-h: 14deg;
--bulma-link-s: 100%;
--bulma-link-l: 59%;
--bulma-info-h: 217deg;
--bulma-info-s: 91%;
--bulma-info-l: 60%;
--bulma-success-h: 160deg;
--bulma-success-s: 84%;
--bulma-success-l: 39%;
--bulma-warning-h: 39deg;
--bulma-warning-s: 100%;
--bulma-warning-l: 56%;
--bulma-danger-h: 4deg;
--bulma-danger-s: 86%;
--bulma-danger-l: 58%;
/* Un seul teinte partagée par tous les fonds (main/bis/ter/bordures),
seule la LUMINOSITÉ varie — c'est le modèle natif de Bulma 1.x, calé
ici sur les valeurs de la charte Forge (--forge-bg/-bg-secondary/
-card/-border, voir bulma-tokens.css). */
--bulma-scheme-h: 220deg;
--bulma-scheme-s: 26%;
--bulma-scheme-main-l: 6%;
--bulma-scheme-main-bis-l: 9%;
--bulma-scheme-main-ter-l: 12%;
--bulma-background-l: 12%;
--bulma-border-weak-l: 15%;
--bulma-border-l: 18%;
--bulma-text-weak-l: 60%;
--bulma-text-l: 93%;
--bulma-text-strong-l: 97%;
--bulma-text-title-l: 100%;
--bulma-box-radius: var(--bulma-radius-large);
--bulma-card-radius: var(--bulma-radius-large);
--bulma-navbar-height: 3.5rem;
}
/* Composants dont Bulma ne prévoit pas de variable dédiée (mise en page
propre au navbar/tableaux/onglets de l'app, badges maison) — voir §6 du
document de règles. */
.navbar {
background: var(--forge-bg-secondary);
border-bottom: 1px solid var(--forge-border);
}
.navbar-item.brand {
gap: 8px;
font-size: 1rem;
}
.navbar-item, .navbar-link { color: var(--forge-text); }
.navbar-item.is-active, .navbar-item:hover, .navbar-link:hover {
color: var(--accent);
background: var(--forge-card);
}
.table thead th {
position: sticky;
top: 0;
z-index: 2;
text-transform: uppercase;
letter-spacing: 0.04em;
font-size: 0.75rem;
}
.tabs.is-toggle li.is-active a { color: #14100c; }
.button.is-primary, button.primary {
background: var(--gradient);
border: none;
color: #14100c;
font-weight: 700;
}
.button.is-primary:hover, button.primary:hover { box-shadow: 0 6px 16px -6px var(--glow); }
.box, .card {
background: linear-gradient(180deg, var(--forge-card), var(--forge-bg-secondary));
box-shadow: none;
transition: box-shadow .15s ease;
}
.box:hover, .card:hover { box-shadow: 0 10px 25px -8px var(--glow); }
.forge-badge {
display: inline-block;
padding: 0.4rem 1rem;
border-radius: 999px;
background: rgb(255 95 46 / 10%);
border: 1px solid rgb(255 95 46 / 35%);
color: var(--accent);
font-size: 0.78rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.forge-badge.is-success {
background: rgb(16 185 129 / 12%);
border-color: rgb(16 185 129 / 35%);
color: var(--status-success);
}
.forge-badge.is-danger {
background: rgb(240 68 56 / 12%);
border-color: rgb(240 68 56 / 35%);
color: var(--status-danger);
}
/* Titre H1 en dégradé signature — réservé aux pages d'accueil/marketing et
à l'écran de connexion (§3/§5). */
.forge-gradient-title {
background: var(--gradient);
background-clip: text;
color: transparent;
}
/* Pages d'authentification (login/register/2FA/mot de passe oublié) :
seul endroit du site, avec l'accueil marketing, où le H1 en dégradé et
la grille de fond fine sont autorisés — absents de tous les écrans de
travail (tableau de bord, éditeur...). */
body.authBody {
background:
radial-gradient(circle at 1px 1px, rgb(232 236 244 / 6%) 1px, transparent 0) 0 0/26px 26px,
var(--forge-bg);
}
.authScreen {
display: flex;
align-items: center;
justify-content: center;
min-height: calc(100vh - 3.5rem);
padding: 2rem 1rem;
}
.authCard {
width: 100%;
max-width: 440px;
}
.authCard.authCard-wide { max-width: 500px; }
.authTitle {
font-size: clamp(1.75rem, 3.5vw, 2.5rem);
margin-bottom: 0.5rem;
}