Refonte design system — Phase A : Bulma auto-hébergé compilé via Sass

Met en place les fondations du template Bulma décrit dans
regles/FORGE_ENGINE_TEMPLATE_BULMA.md : palette orange/ambre Forge
(--accent:#ff5f2e/--accent-2:#ffb020), typographie, rayons — appliqués
en recompilant Bulma lui-même plutôt qu'en le surchargeant après coup en
CSS, pour recolorer automatiquement ses composants internes (tags,
notifications, dropdowns...) sans avoir à les surcharger un par un.

- Bulma 0.9.4 vendoré en local (styles/bulma/, source Sass classique
  $variable + @import) — PAS 1.0.2 (la version jusqu'ici en CDN) : 1.0.2
  utilise le nouveau système de modules @use/@forward, que libsass (choisi
  pour rester 100% Python, sans Node/npm) ne sait pas compiler (testé :
  il ignore silencieusement le @use au lieu de le traiter). 0.9.4 est la
  dernière version compatible avec libsass et couvre à l'identique tous
  les composants utilisés ici (boutons, tableaux, onglets, modales,
  formulaires, navbar).
- requirements.txt : +libsass (pip pur, aucun binaire/Node.js).
- styles/forge-theme.scss (nouveau, point d'entrée) : variables Sass
  Bulma ($primary, $radius...) posées avant l'import, tokens Forge exposés
  en :root (--forge-bg, --accent, --gradient, --status-*...) avec des
  alias vers les noms de variables déjà utilisés par tout le CSS custom
  existant (--bg/--panel/--border/--text/--danger...) — pas besoin de
  renommer les ~600 lignes de règles déjà écrites, seules leurs VALEURS
  changent.
- styles/forge-custom.scss : ancien static/style.css, structurellement
  inchangé — seuls les hex/rgba en dur qui échappaient aux variables
  (ancien accent bleu #5b8cff, danger #e2685f, couleurs de types de
  nœuds du graphe de logique, fond du QR code recovery...) sont
  remplacés par les tokens de la charte.
- build_css.py (nouveau) : compile styles/forge-theme.scss en
  static/style.css via libsass — un seul fichier, un seul <link>
  inchangé dans les templates, à relancer manuellement après toute
  modification sous styles/.
- base.html/play.html : suppression du <link> CDN Bulma (auto-hébergé
  désormais), ajout d'un favicon (absent jusqu'ici) et du vrai logo Forge
  dans la navbar (assets/*.svg copiés dans static/branding/, seul dossier
  réellement servi par Flask).

197 tests toujours verts (aucune assertion sur des valeurs CSS).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-08-29 08:01:32 +02:00
co-authored by Claude Sonnet 5
parent dedbda422c
commit f2a73f2c73
80 changed files with 20010 additions and 350 deletions
+183
View File
@@ -0,0 +1,183 @@
// forge-theme.scss — point d'entrée unique compilé par build_css.py en
// static/style.css (voir regles/FORGE_ENGINE_TEMPLATE_BULMA.md, §6).
//
// Bulma est vendoré en local (styles/bulma/, version 0.9.4 — la dernière
// compatible avec libsass, voir build_css.py) : ses variables Sass
// ($primary, $radius...) sont posées ICI, AVANT `@import "bulma"`, pour
// que Bulma recompile ses propres composants (boutons, tags,
// notifications, dropdowns...) avec la palette Forge plutôt que de les
// surcharger un par un après coup en CSS.
// ---------- Variables Sass consommées par Bulma ----------
$family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
$body-background-color: #0b0e14;
$scheme-main: #0b0e14;
$scheme-main-bis: #11151d;
$scheme-main-ter: #161b25;
$text: #e8ecf4;
$text-light: #8b95a7;
$border: #232a38;
$border-light: #232a38;
$link: #ff5f2e;
$primary: #ff5f2e;
$info: #3b82f6;
$success: #10b981;
$warning: #ffb020;
$danger: #f04438;
$radius: 10px;
$radius-small: 8px;
$radius-large: 16px;
$radius-rounded: 999px;
$box-radius: 16px;
$card-radius: 16px;
$navbar-height: 3.5rem;
@import "bulma/bulma";
// ---------- Tokens Forge (variables CSS runtime — voir §1 du document de
// règles) : exposées en :root pour rester inspectables/utilisables telles
// quelles par du JS ou du style inline, indépendamment de la compilation
// Sass. Les alias --bg/--panel/--panel2/--border/--text/--text-dim/
// --danger reprennent les noms déjà utilisés par tout le CSS custom de
// l'app (voir forge-custom.scss, importé juste après) — pas besoin de
// renommer les ~600 lignes de règles déjà écrites, seules les VALEURS
// changent. ----------
:root {
--forge-bg: #0b0e14;
--forge-bg-secondary: #11151d;
--forge-card: #161b25;
--forge-border: #232a38;
--forge-text: #e8ecf4;
--forge-text-muted: #8b95a7;
--accent: #ff5f2e;
--accent-2: #ffb020;
--gradient: linear-gradient(120deg, var(--accent), var(--accent-2));
--glow: rgba(255, 95, 46, 0.25);
--status-success: #10b981;
--status-warning: #ffb020;
--status-danger: #f04438;
--status-info: #3b82f6;
// Alias historiques (voir commentaire ci-dessus).
--bg: var(--forge-bg);
--panel: var(--forge-card);
--panel2: var(--forge-bg-secondary);
--border: var(--forge-border);
--text: var(--forge-text);
--text-dim: var(--forge-text-muted);
--danger: var(--status-danger);
}
html, body {
background: var(--forge-bg);
color: var(--forge-text);
}
// ---------- Composants Bulma que la recompilation seule ne couvre pas
// (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 {
background: transparent;
color: var(--forge-text);
}
.table thead th {
background: var(--forge-bg-secondary);
color: var(--forge-text-muted);
border-color: var(--forge-border);
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.04em;
font-weight: 600;
position: sticky;
top: 0;
z-index: 2;
}
.table td, .table th { border-color: var(--forge-border); vertical-align: middle; }
.table.is-striped tbody tr:nth-child(even) { background: var(--forge-bg-secondary); }
.table tbody tr:hover { background: var(--forge-card); }
.tabs a { color: var(--forge-text-muted); border-bottom-color: var(--forge-border); }
.tabs li.is-active a { color: var(--accent); border-bottom-color: var(--accent); }
.tabs.is-toggle a { border-color: var(--forge-border); background: var(--forge-bg-secondary); }
.tabs.is-toggle li.is-active a { background: var(--accent); border-color: var(--accent); color: #14100c; }
.title, h1, h2, h3 { color: var(--forge-text); }
.subtitle { color: var(--forge-text-muted); font-weight: 400; }
.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));
border: 1px solid var(--forge-border);
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: rgba(255, 95, 46, 0.1);
border: 1px solid rgba(255, 95, 46, 0.35);
color: var(--accent);
font-size: 0.78rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.forge-badge.is-success { background: rgba(16, 185, 129, 0.12); border-color: rgba(16, 185, 129, 0.35); color: var(--status-success); }
.forge-badge.is-danger { background: rgba(240, 68, 56, 0.12); border-color: rgba(240, 68, 56, 0.35); color: var(--status-danger); }
.input, .textarea, .select select {
background: var(--forge-bg-secondary);
border-color: var(--forge-border);
color: var(--forge-text);
}
.input:focus, .textarea:focus, .select select:focus {
border-color: var(--accent);
box-shadow: 0 0 0 2px rgba(255, 95, 46, 0.2);
}
label.label { color: var(--forge-text-muted); font-size: 0.85rem; font-weight: 600; }
.modal-card, .modal-content { background: var(--forge-card); border: 1px solid var(--forge-border); }
.modal-card-head, .modal-card-foot { background: var(--forge-bg-secondary); border-color: var(--forge-border); }
.notification { color: var(--forge-text); }
.notification.is-success { background: rgba(16, 185, 129, 0.12); color: var(--status-success); }
.notification.is-danger { background: rgba(240, 68, 56, 0.12); color: var(--status-danger); }
.notification.is-warning { background: rgba(255, 176, 32, 0.12); color: var(--status-warning); }
.notification.is-info { background: rgba(59, 130, 246, 0.12); color: var(--status-info); }
// Titre H1 en dégradé signature — réservé aux pages d'accueil/marketing et
// à l'écran de connexion (§5), voir .authHero (templates/auth/*.html,
// Phase B).
.forge-gradient-title {
background: var(--gradient);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
// ---------- CSS custom de l'app (floatPanel, canvas, arbre d'éléments,
// graphe de logique, timeline, éditeurs de jeu...) — structurellement
// inchangé, consomme les tokens ci-dessus via les alias historiques.
// ----------
@import "forge-custom";