Arc 6 Quête A6

L'Atelier des Enlumineurs

Git pour le design, LFS, SVG et design tokens

Dans l'aile ouest de la Citadelle, baignée par la lumière douce des vitraux, se trouve l'Atelier des Enlumineurs. C'est ici que les artistes du royaume créent les ornements, les illustrations et les interfaces qui donnent vie aux parchemins. Leurs pinceaux numériques produisent des oeuvres visuelles qui ne se résument pas à du texte - et c'est précisément le défi.

La Maîtresse Enlumineuse t'observe avec curiosité. « Tu sais versionner du code, Versionneur. Mais sais-tu versionner de l'art ? Un fichier Photoshop de 200 Mo ? Un design system complet ? Des tokens de couleurs partagés entre dix applications ? Bienvenue dans notre monde. Il est magnifique, mais il ne suit pas tes règles habituelles. »

Le problème des assets graphiques

Dans un projet logiciel, les designers produisent des fichiers très différents du code source :

  • Fichiers source volumineux : .psd (Photoshop), .ai (Illustrator), .sketch, .fig (Figma) - de 10 Mo à 500 Mo chacun
  • Formats binaires : Git ne peut pas calculer de diff textuel
  • Modifications fréquentes : un designer peut sauvegarder 50 fois par jour
  • Nombreuses variantes : icon-v1.psd, icon-v2.psd, icon-v2-final.psd, icon-v2-final-VRAI.psd...

Sans solution adaptée, un dépôt avec des assets graphiques devient rapidement ingérable :

# Un repo sans Git LFS, après 6 mois de design :
du -sh .git/
# 4.7 GB    .git/

# Chaque version de chaque PSD est stockée en entier dans l'historique.
# Le clone prend 45 minutes.
# Personne n'est content.

Les assets graphiques ne sont pas comme du code. Ils sont gros, binaires, et changent souvent. Il faut des outils et des workflows adaptés pour les versionner correctement.

Git LFS pour le design

Tu as peut-être déjà croisé Git LFS (Large File Storage) dans d'autres quêtes. Voici un rappel rapide et les patterns spécifiques au design.

Rappel du principe

Git LFS remplace les gros fichiers dans ton dépôt par de petits fichiers "pointeurs". Les vrais fichiers sont stockés sur un serveur LFS séparé. Résultat : le dépôt reste léger, les clones sont rapides.

# Installation (une seule fois par machine)
git lfs install

# Dans ton projet, tracker les fichiers design
git lfs track "*.psd"
git lfs track "*.ai"
git lfs track "*.sketch"
git lfs track "*.fig"
git lfs track "*.xd"
git lfs track "*.tiff"
git lfs track "*.raw"

# Cela modifie .gitattributes
cat .gitattributes
# *.psd filter=lfs diff=lfs merge=lfs -text
# *.ai filter=lfs diff=lfs merge=lfs -text
# *.sketch filter=lfs diff=lfs merge=lfs -text
# *.fig filter=lfs diff=lfs merge=lfs -text
# *.xd filter=lfs diff=lfs merge=lfs -text
# *.tiff filter=lfs diff=lfs merge=lfs -text
# *.raw filter=lfs diff=lfs merge=lfs -text

Patterns LFS complets pour le design

# .gitattributes - patterns recommandés pour un repo design

# Fichiers source design
*.psd filter=lfs diff=lfs merge=lfs -text
*.psb filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.sketch filter=lfs diff=lfs merge=lfs -text
*.fig filter=lfs diff=lfs merge=lfs -text
*.xd filter=lfs diff=lfs merge=lfs -text

# Images haute résolution
*.tiff filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
*.raw filter=lfs diff=lfs merge=lfs -text
*.bmp filter=lfs diff=lfs merge=lfs -text

# Images exportées (optionnel - certains préfèrent ne pas LFS les PNG)
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text

# Polices
*.otf filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.woff filter=lfs diff=lfs merge=lfs -text
*.woff2 filter=lfs diff=lfs merge=lfs -text

# Vidéos et animations
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text

Astuce : Pour les PNG et JPG, la décision dépend de ta situation. Si ce sont de petites icônes (quelques Ko), pas besoin de LFS. Si ce sont des maquettes haute résolution (plusieurs Mo), LFS est recommandé. La règle : LFS pour tout fichier de plus de 500 Ko.

Diff visuel d'images

Quand un designer modifie une maquette, comment savoir ce qui a changé ? Les outils de diff visuel comparent deux versions d'une image et montrent les différences.

git-diff-image

git-diff-image est un outil open source qui s'intègre directement dans git diff pour afficher les différences visuelles entre deux versions d'une image :

# Installation
git clone https://github.com/ewanmellor/git-diff-image.git
cd git-diff-image
./install.sh

# Après installation, git diff affiche automatiquement
# les différences visuelles pour les images
git diff HEAD~1 -- assets/hero-banner.png
# Ouvre une fenêtre avec les deux versions côte à côte
# et une vue en surimpression montrant les pixels modifiés

Beyond Compare et Kaleidoscope

Pour un usage professionnel, des outils comme Beyond Compare (multiplateforme) ou Kaleidoscope (macOS) offrent des fonctionnalités avancées :

  • Mode côte à côte : les deux versions l'une à côté de l'autre
  • Mode superposition : une image par-dessus l'autre avec un slider
  • Mode différence : seuls les pixels différents sont affichés
  • Zoom synchronisé : zoomer sur un détail dans les deux versions
# Configurer Beyond Compare comme outil de diff pour les images
git config --global diff.tool bc4
git config --global difftool.bc4.cmd '"C:/Program Files/Beyond Compare 4/BComp.exe" "$LOCAL" "$REMOTE"'

# Utilisation
git difftool HEAD~1 -- assets/hero-banner.png
# PowerShell - configuration identique
git config --global diff.tool bc4
git config --global difftool.bc4.cmd '"C:\Program Files\Beyond Compare 4\BComp.exe" "$LOCAL" "$REMOTE"'

SVG dans Git - le format rêvé

Le format SVG (Scalable Vector Graphics) est un cas spécial et merveilleux pour le versionnement : c'est du XML, donc du texte. Git peut calculer des diffs, et tu peux voir exactement ce qui a changé.

# Un fichier SVG, c'est du texte :
cat icon-home.svg
# <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
#   <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
# </svg>

# Git diff fonctionne parfaitement :
git diff icon-home.svg
# -  <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
# +  <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"
# +        fill="#333333"/>

Avantages du SVG dans Git

  • Diffs lisibles : tu vois exactement quel attribut a changé
  • Fichiers légers : pas besoin de Git LFS
  • Scalable : pas de perte de qualité, parfait pour les icônes et illustrations
  • Mergeable : en théorie, Git peut merger des modifications SVG (avec prudence)

Optimisation avec SVGO

SVGO (SVG Optimizer) nettoie et optimise les fichiers SVG exportés des logiciels de design. Les SVG exportés depuis Illustrator ou Figma contiennent souvent du code inutile :

# Installation
npm install -g svgo

# Optimiser un fichier SVG
svgo icon-home.svg
# icon-home.svg : 1.24 KB -> 0.45 KB (63.7% de réduction)

# Optimiser tout un dossier
svgo -f assets/icons/ -o assets/icons-optimized/

# Configuration personnalisée (.svgo.config.js)
cat > .svgo.config.js << 'EOF'
module.exports = {
  plugins: [
    'preset-default',
    'removeDimensions',         // Utiliser viewBox au lieu de width/height
    {
      name: 'removeAttrs',
      params: {
        attrs: ['data-name']    // Supprimer les attributs Illustrator
      }
    }
  ]
}
EOF

# Astuce : ajouter SVGO en hook pre-commit
# pour optimiser automatiquement les SVG avant chaque commit

Astuce : Privilégie le SVG pour tout ce qui peut l'être : icônes, logos, illustrations simples, graphiques. Réserve les formats bitmap (PNG, JPG) aux photos et images complexes qui ne se vectorisent pas bien.

Workflow designers + développeurs

Le plus grand défi n'est pas technique - c'est humain. Comment faire travailler ensemble des designers (qui pensent en pixels) et des développeurs (qui pensent en code) sur le même dépôt ?

Qui touche quoi ?

# Structure claire avec séparation des responsabilités
mon-projet/
├── src/                    # Développeurs : code applicatif
├── assets/
│   ├── raw/                # Designers : fichiers sources (PSD, AI, Sketch)
│   │   └── hero-banner.psd
│   ├── exported/           # Designers : exports finaux
│   │   ├── hero-banner.png
│   │   ├── hero-banner@2x.png
│   │   └── icons/
│   │       ├── home.svg
│   │       └── search.svg
│   └── fonts/              # Partagé : polices utilisées
├── tokens/                 # Partagé : design tokens (JSON/YAML)
└── docs/
    └── design/             # Designers : documentation visuelle

Conventions de nommage

Des conventions strictes évitent le chaos :

  • Minuscules avec tirets : hero-banner.png, pas Hero Banner.png ou HeroBanner.png
  • Pas d'espaces : les espaces dans les noms de fichiers causent des problèmes partout
  • Suffixes de taille : icon@1x.png, icon@2x.png, icon@3x.png
  • Pas de "final" dans le nom : c'est Git qui gère les versions, pas le nom du fichier

Anti-pattern : logo-v3-final-FINAL-corrige-2.psd. Avec Git, la dernière version est toujours logo.psd sur la branche main. Point.

File locking pour les assets binaires

Deux designers ne peuvent pas modifier le même fichier PSD en même temps - il n'y a pas de merge possible sur un binaire. La solution : le file locking de Git LFS.

# Configurer le locking dans .gitattributes
# *.psd filter=lfs diff=lfs merge=lfs -text lockable
# *.ai filter=lfs diff=lfs merge=lfs -text lockable

# Avant de modifier un fichier, le verrouiller
git lfs lock assets/raw/hero-banner.psd
# Locked assets/raw/hero-banner.psd

# Voir les fichiers verrouillés
git lfs locks
# ID    Path                           Owner      Locked At
# 1234  assets/raw/hero-banner.psd     alice      2026-03-09T14:30:00Z

# Après le commit, déverrouiller
git lfs unlock assets/raw/hero-banner.psd

# Si un collègue essaie de modifier un fichier verrouillé :
git push
# Forbidden: assets/raw/hero-banner.psd is locked by alice

Intégration Figma et design tokens

Figma est l'outil de design dominant aujourd'hui. Ses fichiers sont stockés dans le cloud (pas dans Git), mais on peut créer un pont entre Figma et Git grâce aux design tokens.

Qu'est-ce qu'un design token ?

Un design token est une valeur de design abstraite : une couleur, une taille de police, un espacement, un rayon de bordure. Au lieu d'écrire #3B82F6 partout, tu écris color.primary.500.

# tokens/colors.json - Design tokens au format W3C
{
  "color": {
    "primary": {
      "50":  { "$value": "#EFF6FF", "$type": "color" },
      "100": { "$value": "#DBEAFE", "$type": "color" },
      "500": { "$value": "#3B82F6", "$type": "color" },
      "700": { "$value": "#1D4ED8", "$type": "color" },
      "900": { "$value": "#1E3A5F", "$type": "color" }
    },
    "neutral": {
      "0":   { "$value": "#FFFFFF", "$type": "color" },
      "100": { "$value": "#F3F4F6", "$type": "color" },
      "900": { "$value": "#111827", "$type": "color" }
    }
  },
  "spacing": {
    "xs":  { "$value": "4px",  "$type": "dimension" },
    "sm":  { "$value": "8px",  "$type": "dimension" },
    "md":  { "$value": "16px", "$type": "dimension" },
    "lg":  { "$value": "24px", "$type": "dimension" },
    "xl":  { "$value": "32px", "$type": "dimension" }
  },
  "font": {
    "family": {
      "heading": { "$value": "Inter, sans-serif", "$type": "fontFamily" },
      "body":    { "$value": "Inter, sans-serif", "$type": "fontFamily" },
      "mono":    { "$value": "JetBrains Mono, monospace", "$type": "fontFamily" }
    },
    "size": {
      "sm":  { "$value": "14px", "$type": "dimension" },
      "md":  { "$value": "16px", "$type": "dimension" },
      "lg":  { "$value": "20px", "$type": "dimension" },
      "xl":  { "$value": "24px", "$type": "dimension" }
    }
  },
  "border": {
    "radius": {
      "sm":   { "$value": "4px",  "$type": "dimension" },
      "md":   { "$value": "8px",  "$type": "dimension" },
      "full": { "$value": "9999px", "$type": "dimension" }
    }
  }
}

Export depuis Figma vers Git

Plusieurs plugins Figma permettent d'exporter les tokens directement dans un format exploitable :

  • Tokens Studio for Figma : le plus populaire. Synchronise les tokens entre Figma et un dépôt Git (GitHub, GitLab). Les designers modifient dans Figma, les tokens sont automatiquement mis à jour dans le repo.
  • Figma Tokens : export manuel ou automatisé vers JSON
  • API Figma : scripts custom pour extraire les styles
# Workflow avec Tokens Studio
# 1. Le designer modifie une couleur dans Figma
# 2. Tokens Studio détecte le changement
# 3. Tokens Studio crée une Pull Request sur GitHub
#    avec le fichier tokens.json mis à jour
# 4. Le développeur revoit et merge la PR
# 5. Le CI/CD génère les variables CSS/SCSS/JS

Style Dictionary - transformer les tokens

Style Dictionary (par Amazon) transforme les design tokens JSON en variables utilisables dans n'importe quelle plateforme :

# Installation
npm install -g style-dictionary

# Configuration (config.json)
cat > config.json << 'EOF'
{
  "source": ["tokens/**/*.json"],
  "platforms": {
    "css": {
      "transformGroup": "css",
      "buildPath": "build/css/",
      "files": [{
        "destination": "variables.css",
        "format": "css/variables"
      }]
    },
    "scss": {
      "transformGroup": "scss",
      "buildPath": "build/scss/",
      "files": [{
        "destination": "_variables.scss",
        "format": "scss/variables"
      }]
    },
    "js": {
      "transformGroup": "js",
      "buildPath": "build/js/",
      "files": [{
        "destination": "tokens.js",
        "format": "javascript/es6"
      }]
    }
  }
}
EOF

# Générer les variables pour toutes les plateformes
style-dictionary build

# Résultat CSS :
cat build/css/variables.css
# :root {
#   --color-primary-50: #EFF6FF;
#   --color-primary-500: #3B82F6;
#   --spacing-sm: 8px;
#   --spacing-md: 16px;
#   --font-size-md: 16px;
#   --border-radius-md: 8px;
# }

# Résultat SCSS :
cat build/scss/_variables.scss
# $color-primary-50: #EFF6FF;
# $color-primary-500: #3B82F6;
# $spacing-sm: 8px;

Les design tokens sont le pont entre design et code. Versionnés dans Git en JSON, ils sont la source de vérité partagée entre designers et développeurs. Quand un designer change une couleur, le git diff montre exactement : "#3B82F6" -> "#2563EB".

Le format W3C Design Tokens

Le W3C Design Tokens Community Group travaille sur un standard pour les design tokens. Le format que nous avons utilisé plus haut ($value, $type) est le format W3C émergent. Il vise à devenir le standard universel.

Structure du format

# Format W3C Design Tokens
{
  "group-name": {
    "token-name": {
      "$value": "...",          # La valeur du token
      "$type": "color",         # Le type (color, dimension, fontFamily, etc.)
      "$description": "..."     # Description optionnelle
    }
  }
}

# Types supportés :
# color       - couleurs (#hex, rgb, hsl)
# dimension   - tailles (px, rem, em)
# fontFamily  - familles de polices
# fontWeight  - graisses (400, 700, bold)
# duration    - durées d'animation (200ms)
# cubicBezier - courbes d'animation
# shadow      - ombres portées
# gradient    - dégradés

L'avantage d'utiliser le format W3C : tous les outils convergent vers ce standard. Tokens Studio, Style Dictionary, et de nombreux autres outils le supportent déjà.

Organisation d'un repo design

mon-design-system/
├── assets/
│   ├── raw/                     # Sources design (PSD, AI, Sketch)
│   │   ├── illustrations/       # Illustrations haute résolution
│   │   ├── photography/         # Photos de référence
│   │   └── mockups/             # Maquettes d'écrans
│   └── exported/                # Exports optimisés prêts à l'emploi
│       ├── icons/               # Icônes SVG optimisées
│       │   ├── home.svg
│       │   ├── search.svg
│       │   └── user.svg
│       ├── logos/               # Logos en différents formats
│       │   ├── logo-full.svg
│       │   ├── logo-icon.svg
│       │   └── logo-full.png
│       └── images/              # Images pour le produit
├── tokens/                      # Design tokens (source de vérité)
│   ├── colors.json
│   ├── spacing.json
│   ├── typography.json
│   └── shadows.json
├── build/                       # Fichiers générés (dans .gitignore)
│   ├── css/variables.css
│   ├── scss/_variables.scss
│   └── js/tokens.js
├── components/                  # Composants documentés
│   ├── button/
│   │   ├── button.md            # Documentation du composant
│   │   └── button-preview.png   # Aperçu visuel
│   └── card/
│       ├── card.md
│       └── card-preview.png
├── docs/                        # Documentation du design system
│   ├── getting-started.md
│   └── contribution-guide.md
├── .gitattributes               # Patterns LFS
├── .gitignore
├── config.json                  # Config Style Dictionary
└── package.json

Astuce : Le dossier build/ doit être dans le .gitignore - il est généré automatiquement par Style Dictionary. Seuls les fichiers tokens/ (la source de vérité) sont versionnés.

Exercice pratique - Repo design avec LFS et tokens

Crée un dépôt pour un design system fictif (le "Grimoire Visuel" de la Citadelle) avec Git LFS pour les assets et des design tokens versionnés :

  1. Crée la structure recommandée
  2. Configure Git LFS pour les fichiers design
  3. Ajoute des design tokens en JSON (format W3C)
  4. Crée des icônes SVG et optimise-les
  5. Simule un changement de couleur et observe le diff

Étape 1 - Créer la structure

# Créer le dépôt
mkdir grimoire-visuel
cd grimoire-visuel
git init -b main

# Créer l'arborescence
mkdir -p assets/raw/illustrations
mkdir -p assets/raw/mockups
mkdir -p assets/exported/icons
mkdir -p assets/exported/logos
mkdir -p assets/exported/images
mkdir -p tokens
mkdir -p components/button
mkdir -p components/card
mkdir -p docs

Étape 2 - Configurer Git LFS

# Initialiser Git LFS
git lfs install

# Tracker les fichiers design
git lfs track "*.psd"
git lfs track "*.ai"
git lfs track "*.sketch"
git lfs track "*.tiff"
git lfs track "*.raw"
git lfs track "assets/exported/images/*.png"
git lfs track "assets/exported/images/*.jpg"

# Créer le .gitignore
cat > .gitignore << 'EOF'
# Fichiers générés
build/
node_modules/

# OS
.DS_Store
Thumbs.db
Desktop.ini

# Éditeurs
*.swp
*.swo
*~
EOF

# Premier commit
git add .gitattributes .gitignore
git commit -m "Configuration initiale : Git LFS + .gitignore"

Étape 3 - Ajouter les design tokens

# Créer les tokens de couleur
cat > tokens/colors.json << 'EOF'
{
  "color": {
    "primary": {
      "500": { "$value": "#7C3AED", "$type": "color", "$description": "Violet principal du Grimoire" },
      "700": { "$value": "#5B21B6", "$type": "color", "$description": "Violet foncé" }
    },
    "accent": {
      "500": { "$value": "#F59E0B", "$type": "color", "$description": "Or des enluminures" }
    },
    "neutral": {
      "0":   { "$value": "#FFFFFF", "$type": "color" },
      "900": { "$value": "#1F2937", "$type": "color" }
    }
  }
}
EOF

# Créer les tokens d'espacement
cat > tokens/spacing.json << 'EOF'
{
  "spacing": {
    "xs": { "$value": "4px",  "$type": "dimension" },
    "sm": { "$value": "8px",  "$type": "dimension" },
    "md": { "$value": "16px", "$type": "dimension" },
    "lg": { "$value": "24px", "$type": "dimension" },
    "xl": { "$value": "32px", "$type": "dimension" }
  }
}
EOF

git add tokens/
git commit -m "Ajout des design tokens couleurs et espacements"

Étape 4 - Créer des icônes SVG

# Créer une icône SVG simple
cat > assets/exported/icons/shield.svg << 'EOF'

  

EOF

cat > assets/exported/icons/scroll.svg << 'EOF'

  
  
  
  

EOF

git add assets/exported/icons/
git commit -m "Ajout des icônes SVG shield et scroll"

Étape 5 - Simuler un changement de couleur

# Le designer décide de changer le violet principal
sed -i 's/#7C3AED/#8B5CF6/' tokens/colors.json
sed -i 's/#5B21B6/#6D28D9/' tokens/colors.json

# Observer le diff - parfaitement lisible !
git diff tokens/colors.json
# -      "500": { "$value": "#7C3AED", "$type": "color", ...
# +      "500": { "$value": "#8B5CF6", "$type": "color", ...
# -      "700": { "$value": "#5B21B6", "$type": "color", ...
# +      "700": { "$value": "#6D28D9", "$type": "color", ...

# Commiter le changement
git add tokens/colors.json
git commit -m "Mise à jour couleur primaire : violet plus clair"

# L'historique montre clairement l'évolution
git log --oneline
# abc1234 Mise à jour couleur primaire : violet plus clair
# def5678 Ajout des icônes SVG shield et scroll
# ghi9012 Ajout des design tokens couleurs et espacements
# jkl3456 Configuration initiale : Git LFS + .gitignore

Récapitulatif des concepts

Concept Description
Git LFS pour le design Tracker les PSD, AI, Sketch et autres binaires volumineux
File locking Verrouiller un fichier binaire pour éviter les conflits
Diff visuel Outils pour comparer visuellement deux versions d'une image
SVG Format vectoriel en texte - diffs parfaits dans Git
SVGO Optimiseur de SVG, élimine le code inutile
Design tokens Valeurs de design abstraites (couleurs, tailles) en JSON
Format W3C Standard émergent pour les design tokens ($value, $type)
Tokens Studio Plugin Figma pour synchroniser les tokens avec Git
Style Dictionary Outil pour transformer les tokens JSON en CSS/SCSS/JS
Conventions de nommage Minuscules, tirets, pas d'espaces, pas de "final"

La Maîtresse Enlumineuse examine ton dépôt avec un sourire approbateur. « Tu as compris l'essentiel : le design et le code ne vivent pas dans des mondes séparés. Ils partagent la même source de vérité - les tokens. Ils vivent dans le même dépôt - avec LFS pour les gros fichiers. Ils parlent le même langage - celui de Git. »

« Trop de projets échouent parce que les designers travaillent dans leur coin et les développeurs dans le leur. Les couleurs ne correspondent pas, les espacements sont incohérents, les icônes ont trois noms différents. Avec ce que tu sais maintenant, tu peux bâtir un pont entre ces deux mondes. »

Elle te tend un pinceau dont le manche est gravé de branches d'arbre Git. « Ceci est le symbole des Enlumineurs Versionneurs. Tu sais désormais que l'art, comme le code, mérite un historique. Que chaque pixel changé soit documenté. Que chaque couleur ait sa source de vérité. Va, et que tes designs soient aussi propres que tes commits. »