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
+215
View File
@@ -0,0 +1,215 @@
$label-color: $text-strong !default
$label-weight: $weight-bold !default
$help-size: $size-small !default
$label-colors: $form-colors !default
.label
color: $label-color
display: block
font-size: $size-normal
font-weight: $label-weight
&:not(:last-child)
margin-bottom: 0.5em
// Sizes
&.is-small
font-size: $size-small
&.is-medium
font-size: $size-medium
&.is-large
font-size: $size-large
.help
display: block
font-size: $help-size
margin-top: 0.25rem
@each $name, $pair in $label-colors
$color: nth($pair, 1)
&.is-#{$name}
color: $color
// Containers
.field
&:not(:last-child)
margin-bottom: 0.75rem
// Modifiers
&.has-addons
display: flex
justify-content: flex-start
.control
&:not(:last-child)
+ltr-property("margin", -1px)
&:not(:first-child):not(:last-child)
.button,
.input,
.select select
border-radius: 0
&:first-child:not(:only-child)
.button,
.input,
.select select
+ltr
border-bottom-right-radius: 0
border-top-right-radius: 0
+rtl
border-bottom-left-radius: 0
border-top-left-radius: 0
&:last-child:not(:only-child)
.button,
.input,
.select select
+ltr
border-bottom-left-radius: 0
border-top-left-radius: 0
+rtl
border-bottom-right-radius: 0
border-top-right-radius: 0
.button,
.input,
.select select
&:not([disabled])
&:hover,
&.is-hovered
z-index: 2
&:focus,
&.is-focused,
&:active,
&.is-active
z-index: 3
&:hover
z-index: 4
&.is-expanded
flex-grow: 1
flex-shrink: 1
&.has-addons-centered
justify-content: center
&.has-addons-right
justify-content: flex-end
&.has-addons-fullwidth
.control
flex-grow: 1
flex-shrink: 0
&.is-grouped
display: flex
justify-content: flex-start
& > .control
flex-shrink: 0
&:not(:last-child)
margin-bottom: 0
+ltr-property("margin", 0.75rem)
&.is-expanded
flex-grow: 1
flex-shrink: 1
&.is-grouped-centered
justify-content: center
&.is-grouped-right
justify-content: flex-end
&.is-grouped-multiline
flex-wrap: wrap
& > .control
&:last-child,
&:not(:last-child)
margin-bottom: 0.75rem
&:last-child
margin-bottom: -0.75rem
&:not(:last-child)
margin-bottom: 0
&.is-horizontal
+tablet
display: flex
.field-label
.label
font-size: inherit
+mobile
margin-bottom: 0.5rem
+tablet
flex-basis: 0
flex-grow: 1
flex-shrink: 0
+ltr-property("margin", 1.5rem)
text-align: right
&.is-small
font-size: $size-small
padding-top: 0.375em
&.is-normal
padding-top: 0.375em
&.is-medium
font-size: $size-medium
padding-top: 0.375em
&.is-large
font-size: $size-large
padding-top: 0.375em
.field-body
.field .field
margin-bottom: 0
+tablet
display: flex
flex-basis: 0
flex-grow: 5
flex-shrink: 1
.field
margin-bottom: 0
& > .field
flex-shrink: 1
&:not(.is-narrow)
flex-grow: 1
&:not(:last-child)
+ltr-property("margin", 0.75rem)
.control
box-sizing: border-box
clear: both
font-size: $size-normal
position: relative
text-align: inherit
// Modifiers
&.has-icons-left,
&.has-icons-right
.input,
.select
&:focus
& ~ .icon
color: $input-icon-active-color
&.is-small ~ .icon
font-size: $size-small
&.is-medium ~ .icon
font-size: $size-medium
&.is-large ~ .icon
font-size: $size-large
.icon
color: $input-icon-color
height: $input-height
pointer-events: none
position: absolute
top: 0
width: $input-height
z-index: 4
&.has-icons-left
.input,
.select select
padding-left: $input-height
.icon.is-left
left: 0
&.has-icons-right
.input,
.select select
padding-right: $input-height
.icon.is-right
right: 0
&.is-loading
&::after
@extend %loader
position: absolute !important
+ltr-position(0.625em)
top: 0.625em
z-index: 4
&.is-small:after
font-size: $size-small
&.is-medium:after
font-size: $size-medium
&.is-large:after
font-size: $size-large