xpeditis2.0/apps/frontend/DESIGN_SYSTEM.md
2025-10-31 12:38:05 +01:00

16 KiB

Xpeditis Design System

📐 Charte Graphique

Ce document définit la charte graphique officielle de Xpeditis pour assurer la cohérence visuelle de l'application.


🎨 Palette de Couleurs

Couleurs Principales

Nom Hex RGB Usage
Navy Blue #10183A rgb(16, 24, 58) Couleur principale, headers, textes importants
Turquoise #34CCCD rgb(52, 204, 205) Couleur d'accent, CTAs, liens, highlights
Green #067224 rgb(6, 114, 36) Success states, confirmations, statuts positifs
Light Gray #F2F2F2 rgb(242, 242, 242) Backgrounds, sections, cards
White #FFFFFF rgb(255, 255, 255) Backgrounds principaux, texte sur foncé

Couleurs Sémantiques (Dérivées)

/* Success */
--color-success: #067224;
--color-success-light: #08a131;
--color-success-dark: #044f19;

/* Info (Turquoise) */
--color-info: #34CCCD;
--color-info-light: #5dd9da;
--color-info-dark: #2a9fa0;

/* Warning */
--color-warning: #f59e0b;
--color-warning-light: #fbbf24;
--color-warning-dark: #d97706;

/* Error */
--color-error: #dc2626;
--color-error-light: #ef4444;
--color-error-dark: #b91c1c;

/* Neutral (Navy Blue based) */
--color-neutral-900: #10183A;
--color-neutral-800: #1e2859;
--color-neutral-700: #2c3978;
--color-neutral-600: #3a4a97;
--color-neutral-500: #5a6bb8;
--color-neutral-400: #8590c9;
--color-neutral-300: #b0b6da;
--color-neutral-200: #dadbeb;
--color-neutral-100: #edeef5;
--color-neutral-50: #f8f9fc;

🔤 Typographie

Polices Principales

Manrope - Titres et Headers

  • Usage: Titres (H1-H6), labels importants, navigation
  • Poids disponibles: 200 (ExtraLight), 300 (Light), 400 (Regular), 500 (Medium), 600 (SemiBold), 700 (Bold), 800 (ExtraBold)
  • Caractéristiques: Police moderne, géométrique, excellent lisibilité

Montserrat - Corps de texte

  • Usage: Paragraphes, corps de texte, descriptions, formulaires
  • Poids disponibles: 100 (Thin), 200 (ExtraLight), 300 (Light), 400 (Regular), 500 (Medium), 600 (SemiBold), 700 (Bold), 800 (ExtraBold), 900 (Black)
  • Caractéristiques: Police sans-serif classique, très lisible, polyvalente

Hiérarchie Typographique

/* Display - Manrope */
.text-display-lg {
  font-family: 'Manrope', sans-serif;
  font-size: 4.5rem; /* 72px */
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.text-display-md {
  font-family: 'Manrope', sans-serif;
  font-size: 3.75rem; /* 60px */
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.text-display-sm {
  font-family: 'Manrope', sans-serif;
  font-size: 3rem; /* 48px */
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

/* Headings - Manrope */
.text-h1 {
  font-family: 'Manrope', sans-serif;
  font-size: 2.5rem; /* 40px */
  font-weight: 700;
  line-height: 1.25;
}

.text-h2 {
  font-family: 'Manrope', sans-serif;
  font-size: 2rem; /* 32px */
  font-weight: 600;
  line-height: 1.3;
}

.text-h3 {
  font-family: 'Manrope', sans-serif;
  font-size: 1.5rem; /* 24px */
  font-weight: 600;
  line-height: 1.35;
}

.text-h4 {
  font-family: 'Manrope', sans-serif;
  font-size: 1.25rem; /* 20px */
  font-weight: 600;
  line-height: 1.4;
}

.text-h5 {
  font-family: 'Manrope', sans-serif;
  font-size: 1.125rem; /* 18px */
  font-weight: 500;
  line-height: 1.45;
}

.text-h6 {
  font-family: 'Manrope', sans-serif;
  font-size: 1rem; /* 16px */
  font-weight: 500;
  line-height: 1.5;
}

/* Body - Montserrat */
.text-body-lg {
  font-family: 'Montserrat', sans-serif;
  font-size: 1.125rem; /* 18px */
  font-weight: 400;
  line-height: 1.6;
}

.text-body {
  font-family: 'Montserrat', sans-serif;
  font-size: 1rem; /* 16px */
  font-weight: 400;
  line-height: 1.6;
}

.text-body-sm {
  font-family: 'Montserrat', sans-serif;
  font-size: 0.875rem; /* 14px */
  font-weight: 400;
  line-height: 1.55;
}

.text-body-xs {
  font-family: 'Montserrat', sans-serif;
  font-size: 0.75rem; /* 12px */
  font-weight: 400;
  line-height: 1.5;
}

/* Labels and UI - Montserrat */
.text-label-lg {
  font-family: 'Montserrat', sans-serif;
  font-size: 0.875rem; /* 14px */
  font-weight: 600;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.text-label {
  font-family: 'Montserrat', sans-serif;
  font-size: 0.75rem; /* 12px */
  font-weight: 600;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.text-label-sm {
  font-family: 'Montserrat', sans-serif;
  font-size: 0.6875rem; /* 11px */
  font-weight: 600;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

🎯 Guidelines d'Utilisation

Couleurs

Navy Blue (#10183A)

À utiliser pour:

  • Headers et navigation principale
  • Titres importants (H1, H2)
  • Texte sur fond clair
  • Éléments de structure principale

À éviter:

  • Texte de petite taille (< 14px)
  • Arrière-plans étendus (trop sombre)

Turquoise (#34CCCD)

À utiliser pour:

  • Boutons CTA principaux
  • Liens et éléments interactifs
  • Highlights et badges
  • Icônes d'action
  • Progress indicators

À éviter:

  • Texte long (fatigue visuelle)
  • Messages d'erreur ou d'alerte

Green (#067224)

À utiliser pour:

  • Confirmations et success states
  • Statuts "Confirmed", "Delivered"
  • Badges de statut positif
  • Icônes de validation

À éviter:

  • Éléments neutres
  • CTAs principaux (réservé à turquoise)

Light Gray (#F2F2F2)

À utiliser pour:

  • Backgrounds de sections
  • Cards et containers
  • Séparateurs subtils
  • Inputs désactivés

À éviter:

  • Texte principal
  • Éléments nécessitant contraste élevé

Typographie

Quand utiliser Manrope

  • Tous les titres (H1-H6)
  • Navigation (menu items)
  • Boutons (button labels)
  • Table headers
  • Dashboard KPI numbers
  • Logos et branding

Quand utiliser Montserrat

  • Tout le corps de texte
  • Descriptions
  • Labels de formulaires
  • Messages d'aide
  • Placeholders
  • Table body content
  • Tooltips

📦 Intégration dans le Projet

1. Tailwind CSS Configuration

Modifier tailwind.config.ts:

import type { Config } from 'tailwindcss';

const config: Config = {
  content: [
    './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
    './src/components/**/*.{js,ts,jsx,tsx,mdx}',
    './src/app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {
      colors: {
        // Primary colors
        primary: {
          DEFAULT: '#10183A',
          navy: '#10183A',
        },
        accent: {
          DEFAULT: '#34CCCD',
          turquoise: '#34CCCD',
        },
        success: {
          DEFAULT: '#067224',
          light: '#08a131',
          dark: '#044f19',
        },
        // Neutral scale (Navy-based)
        neutral: {
          50: '#f8f9fc',
          100: '#edeef5',
          200: '#dadbeb',
          300: '#b0b6da',
          400: '#8590c9',
          500: '#5a6bb8',
          600: '#3a4a97',
          700: '#2c3978',
          800: '#1e2859',
          900: '#10183A',
        },
        background: {
          DEFAULT: '#FFFFFF',
          secondary: '#F2F2F2',
        },
      },
      fontFamily: {
        manrope: ['Manrope', 'sans-serif'],
        montserrat: ['Montserrat', 'sans-serif'],
        // Aliases for semantic usage
        heading: ['Manrope', 'sans-serif'],
        body: ['Montserrat', 'sans-serif'],
      },
      fontSize: {
        // Display sizes
        'display-lg': ['4.5rem', { lineHeight: '1.1', letterSpacing: '-0.02em', fontWeight: '800' }],
        'display-md': ['3.75rem', { lineHeight: '1.15', letterSpacing: '-0.02em', fontWeight: '700' }],
        'display-sm': ['3rem', { lineHeight: '1.2', letterSpacing: '-0.01em', fontWeight: '700' }],

        // Heading sizes
        'h1': ['2.5rem', { lineHeight: '1.25', fontWeight: '700' }],
        'h2': ['2rem', { lineHeight: '1.3', fontWeight: '600' }],
        'h3': ['1.5rem', { lineHeight: '1.35', fontWeight: '600' }],
        'h4': ['1.25rem', { lineHeight: '1.4', fontWeight: '600' }],
        'h5': ['1.125rem', { lineHeight: '1.45', fontWeight: '500' }],
        'h6': ['1rem', { lineHeight: '1.5', fontWeight: '500' }],

        // Body sizes
        'body-lg': ['1.125rem', { lineHeight: '1.6', fontWeight: '400' }],
        'body': ['1rem', { lineHeight: '1.6', fontWeight: '400' }],
        'body-sm': ['0.875rem', { lineHeight: '1.55', fontWeight: '400' }],
        'body-xs': ['0.75rem', { lineHeight: '1.5', fontWeight: '400' }],

        // Label sizes
        'label-lg': ['0.875rem', { lineHeight: '1.4', fontWeight: '600', letterSpacing: '0.05em' }],
        'label': ['0.75rem', { lineHeight: '1.4', fontWeight: '600', letterSpacing: '0.05em' }],
        'label-sm': ['0.6875rem', { lineHeight: '1.4', fontWeight: '600', letterSpacing: '0.05em' }],
      },
    },
  },
  plugins: [],
};

export default config;

2. Google Fonts Integration

Modifier app/layout.tsx:

import { Manrope, Montserrat } from 'next/font/google';

const manrope = Manrope({
  subsets: ['latin'],
  weight: ['200', '300', '400', '500', '600', '700', '800'],
  variable: '--font-manrope',
  display: 'swap',
});

const montserrat = Montserrat({
  subsets: ['latin'],
  weight: ['100', '200', '300', '400', '500', '600', '700', '800', '900'],
  variable: '--font-montserrat',
  display: 'swap',
});

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="fr" className={`${manrope.variable} ${montserrat.variable}`}>
      <body className="font-body text-body text-neutral-900 bg-background">
        {children}
      </body>
    </html>
  );
}

3. Global CSS (app/globals.css)

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  /* Set default font to Montserrat */
  body {
    @apply font-montserrat;
  }

  /* Apply Manrope to all headings */
  h1, h2, h3, h4, h5, h6 {
    @apply font-manrope;
  }

  h1 { @apply text-h1 text-primary-navy; }
  h2 { @apply text-h2 text-primary-navy; }
  h3 { @apply text-h3 text-neutral-800; }
  h4 { @apply text-h4 text-neutral-800; }
  h5 { @apply text-h5 text-neutral-700; }
  h6 { @apply text-h6 text-neutral-700; }
}

@layer components {
  /* Button styles */
  .btn-primary {
    @apply bg-accent-turquoise text-white font-manrope font-semibold px-6 py-3 rounded-lg hover:bg-accent-turquoise/90 transition-colors;
  }

  .btn-secondary {
    @apply bg-primary-navy text-white font-manrope font-semibold px-6 py-3 rounded-lg hover:bg-neutral-800 transition-colors;
  }

  .btn-success {
    @apply bg-success text-white font-manrope font-semibold px-6 py-3 rounded-lg hover:bg-success-dark transition-colors;
  }

  /* Card styles */
  .card {
    @apply bg-white rounded-lg shadow-md p-6;
  }

  .card-header {
    @apply font-manrope font-semibold text-h4 text-primary-navy mb-4;
  }

  /* Badge styles */
  .badge {
    @apply inline-flex items-center px-3 py-1 rounded-full text-label font-montserrat;
  }

  .badge-success {
    @apply badge bg-success/10 text-success;
  }

  .badge-info {
    @apply badge bg-accent-turquoise/10 text-accent-turquoise;
  }

  /* Link styles */
  .link {
    @apply text-accent-turquoise hover:text-accent-turquoise/80 transition-colors underline-offset-2 hover:underline;
  }
}

🎨 Exemples d'Utilisation

Exemple 1: Header Component

export function Header() {
  return (
    <header className="bg-primary-navy text-white">
      <div className="container mx-auto px-4 py-4 flex items-center justify-between">
        <h1 className="font-heading text-h3 font-bold">Xpeditis</h1>
        <nav className="flex gap-6 font-heading font-medium">
          <a href="#" className="hover:text-accent-turquoise transition-colors">
            Dashboard
          </a>
          <a href="#" className="hover:text-accent-turquoise transition-colors">
            Bookings
          </a>
        </nav>
      </div>
    </header>
  );
}

Exemple 2: Card with Typography

export function BookingCard() {
  return (
    <div className="card">
      <h3 className="card-header">Booking Details</h3>
      <div className="space-y-3">
        <div>
          <label className="text-label text-neutral-600 block mb-1">
            BOOKING NUMBER
          </label>
          <p className="text-body font-semibold text-neutral-900">
            WCM-2024-ABC123
          </p>
        </div>
        <div>
          <label className="text-label text-neutral-600 block mb-1">
            STATUS
          </label>
          <span className="badge-success">CONFIRMED</span>
        </div>
        <div>
          <label className="text-label text-neutral-600 block mb-1">
            DESCRIPTION
          </label>
          <p className="text-body-sm text-neutral-700">
            Maritime freight from Le Havre to Shanghai. Container type: 20FT.
          </p>
        </div>
      </div>
    </div>
  );
}

Exemple 3: Hero Section

export function Hero() {
  return (
    <section className="bg-primary-navy text-white py-20">
      <div className="container mx-auto px-4 text-center">
        <h1 className="text-display-md font-heading mb-6">
          Maritime Freight Made Simple
        </h1>
        <p className="text-body-lg font-body max-w-2xl mx-auto mb-8 text-neutral-200">
          Book, track, and manage your LCL shipments with real-time rates
          from the world's leading shipping lines.
        </p>
        <div className="flex gap-4 justify-center">
          <button className="btn-primary">
            Get Started
          </button>
          <button className="btn-secondary">
            View Demo
          </button>
        </div>
      </div>
    </section>
  );
}

📊 Accessibilité

Contraste des Couleurs (WCAG AA Compliance)

Combinaison Ratio Conforme
Navy (#10183A) sur White (#FFFFFF) 14.2:1 AAA
Turquoise (#34CCCD) sur White (#FFFFFF) 2.8:1 ⚠️ AA Large
Turquoise (#34CCCD) sur Navy (#10183A) 5.1:1 AA
Green (#067224) sur White (#FFFFFF) 6.8:1 AA
Navy (#10183A) sur Light Gray (#F2F2F2) 13.5:1 AAA

Recommandations:

  • Utiliser Turquoise uniquement pour les éléments interactifs (boutons, liens) ou texte large (≥18px)
  • Préférer Navy Blue pour le texte principal
  • Éviter Green pour le texte de petite taille sur fond blanc

Taille Minimale des Polices

  • Texte principal: 16px (1rem) minimum
  • Texte secondaire: 14px (0.875rem) minimum
  • Labels/Captions: 12px (0.75rem) minimum

🚀 Checklist d'Implémentation

  • Installer les polices Google Fonts (Manrope + Montserrat)
  • Configurer Tailwind avec les couleurs custom
  • Configurer Tailwind avec les font families
  • Ajouter les classes CSS globales
  • Créer des composants Button avec les styles
  • Créer des composants Card avec les styles
  • Créer des composants Badge avec les styles
  • Tester l'accessibilité des contrastes
  • Documenter les composants dans Storybook (optionnel)

📚 Ressources