/* ════════════════════════════════════════════════════════════════════
 * gs-components.css — Kit de composants .gsa-* (SOURCE UNIQUE)
 * --------------------------------------------------------------------
 * EXTRAIT de public/theme/gs-app.css (audit design 2026-06-29) pour être
 * chargé sur TOUTES les pages, pas seulement les ~36 vues layouts.app :
 *   • layouts/app.blade.php le lie explicitement (avant gs-app.css)
 *   • App\Http\Middleware\InjectDesignTokens l'injecte sur les autres
 * → les 54 vues AUTONOMES (login, cpanel, canvass, dashboards…) peuvent
 *   enfin consommer .gsa-btn / .gsa-card / .gsa-field au lieu de
 *   redessiner un bouton chacune (constat audit : 8 paddings + 6 rayons
 *   différents pour « un bouton »).
 *
 * PÉRIMÈTRE : tokens --gs-* + composants .gsa-* UNIQUEMENT.
 * Aucun reset, aucun sélecteur d'élément nu → injectable partout sans
 * risque de régression : les classes .gsa-* n'existent nulle part ailleurs.
 * Le reset + le shell applicatif (body.gsa, .gsa-header, .gsa-main)
 * restent dans gs-app.css, qui n'est chargé que par layouts.app.
 *
 * RTL : props logiques (padding-inline / border-inline-start / text-align:start)
 * → bascule automatique sous <html dir="rtl">, pas de feuille RTL séparée.
 * ════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Brand (navy + teal, matches login & tracking-v2) ─────────────── */
  --gs-accent:        #041E3F;
  --gs-accent-ink:    #ffffff;
  --gs-accent-2:      #12E7AD;
  --gs-accent-3:      #0AC795;
  --gs-accent-soft:   #e6fbf5;

  /* ── Neutrals (light) ─────────────────────────────────────────────── */
  --gs-bg:            #f6f7f9;
  --gs-surface:       #ffffff;
  --gs-surface-2:     #fafbfc;
  --gs-border:        #e5e7eb;
  --gs-border-soft:   #f1f3f5;
  --gs-text:          #0b1320;
  --gs-text-muted:    #5b6776;
  --gs-text-faint:    #6b7787;   /* AA ~4.6:1 on white */

  /* ── Status ───────────────────────────────────────────────────────── */
  --gs-success:       #0f9d6b;
  --gs-warn:          #b9760a;
  --gs-danger:        #c81e1e;
  --gs-info:          #2563c9;
  --gs-success-soft:  #e7f6ef;
  --gs-warn-soft:     #fdf3e3;
  --gs-danger-soft:   #fde8e8;
  --gs-info-soft:     #e8effb;

  /* ── Statut, en TEXTE ──────────────────────────────────────────────
     Les quatre jetons ci-dessus sont des REMPLISSAGES : un bouton danger
     les porte en fond avec du texte blanc, et ils doivent rester sombres
     pour ça. Employés comme couleur de TEXTE ils échouaient deux fois —
     --gs-success rendait 3,47:1 sur blanc et --gs-warn 3,71:1, sous le
     seuil AA de 4,5:1 dès le mode clair ; et comme aucun des quatre ne
     bascule en sombre, ils tombaient à 2,9:1 sur la surface sombre.
     D'où une paire distincte, qui bascule, et dont les huit valeurs
     passent 4,5:1 sur la surface ET sur le fond adouci de leur thème. */
  --gs-success-text:  #0a7d54;   /* 5,15:1 sur blanc · 4,62:1 sur adouci */
  --gs-warn-text:     #9a6208;   /* 5,09:1 · 4,63:1 */
  --gs-danger-text:   #c81e1e;   /* 5,74:1 · 4,89:1 */
  --gs-info-text:     #2563c9;   /* 5,67:1 · 4,90:1 */

  /* ── Statut, en BORDURE ────────────────────────────────────────────
     Le motif « fond adouci + bordure d'un ton plus soutenu » revenait dans
     six vues, chacune avec sa valeur écrite à la main, parce qu'aucun jeton
     ne le couvrait. */
  --gs-success-border: #86efac;
  --gs-warn-border:    #fdba74;
  --gs-danger-border:  #fca5a5;
  --gs-info-border:    #93c5fd;

  /* ── Bloc de code ──────────────────────────────────────────────────
     Un extrait de code se lit clair sur fond sombre dans LES DEUX thèmes.
     La page du widget livreur peignait son fond avec --gs-text, qui devient
     clair en mode sombre : le fond passait en clair sous un texte clair. */
  --gs-code-bg:        #0b1320;
  --gs-code-fg:        #d1e0f5;

  /* ── Geometry ─────────────────────────────────────────────────────── */
  --gs-radius:        14px;
  --gs-radius-sm:     8px;
  --gs-radius-lg:     20px;

  /* ── Shadows ──────────────────────────────────────────────────────── */
  /* Échelle d'élévation alignée sur css/gs-tokens.css (--shadow-*), qui la
     porte à 2 couches. Les deux vocabulaires sont rendus CÔTE À CÔTE (23
     consommateurs un-préfixés, 14 en --gs-*) : une carte du kit et un panneau
     de vue autonome doivent flotter à la même hauteur. */
  --gs-shadow-sm:     0 1px 2px rgba(4,30,63,.06), 0 1px 3px rgba(4,30,63,.08);
  --gs-shadow:        0 4px 12px rgba(4,30,63,.10);
  --gs-shadow-lg:     0 12px 32px rgba(4,30,63,.16);
  /* Documenté par /cpanel/design-system mais jamais défini : l'échantillon
     d'élévation la plus haute s'y affichait donc sans ombre. */
  --gs-shadow-xl:     0 24px 64px rgba(4,30,63,.22);

  /* ── Typography ───────────────────────────────────────────────────── */
  --gs-font:          'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Noto Sans Arabic', sans-serif;
  --gs-font-mono:     'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --gs-text-xs:       11px;
  --gs-text-sm:       12.5px;
  --gs-text-base:     14px;
  --gs-text-lg:       16px;
  --gs-text-xl:       20px;
  --gs-text-xxl:      28px;

  /* ── Spacing ──────────────────────────────────────────────────────── */
  --gs-space-1:       4px;
  --gs-space-2:       8px;
  --gs-space-3:       12px;
  --gs-space-4:       16px;
  --gs-space-5:       24px;
  --gs-space-6:       32px;

  /* ── Layout metrics ───────────────────────────────────────────────── */
  --gs-header-h:      56px;
  --gs-content-max:   1200px;

  /* ── Canonical breakpoint scale (audit: stop the 760/768/800/900/980 drift) */
  --gs-bp-sm:         640px;
  --gs-bp-md:         860px;
  --gs-bp-lg:         1100px;

  --gs-ease:          cubic-bezier(.4, 0, .2, 1);
}

[data-theme="dark"] {
  --gs-bg:            #0b1320;
  --gs-surface:       #161e2e;
  --gs-surface-2:     #1c2434;
  --gs-border:        #283246;
  --gs-border-soft:   #1f273a;
  --gs-text:          #f1f5fb;
  --gs-text-muted:    #95a3b8;
  --gs-text-faint:    #818ea0;
  --gs-accent:        #0AC795;
  --gs-accent-ink:    #06231b;
  --gs-accent-2:      #12E7AD;
  --gs-accent-3:      #5AEEC4;
  --gs-accent-soft:   #0a2a25;
  --gs-success-soft:  #0e2a20;
  --gs-warn-soft:     #2c2310;
  --gs-danger-soft:   #2c1414;
  --gs-info-soft:     #11203b;

  /* Les remplissages (--gs-danger &c.) restent sombres : un bouton plein
     garde son texte blanc dans les deux thèmes. Seul le TEXTE bascule. */
  --gs-success-text:  #34d399;   /* 8,67:1 sur la surface sombre */
  --gs-warn-text:     #fbbf24;   /* 9,99:1 */
  --gs-danger-text:   #f87171;   /* 6,03:1 */
  --gs-info-text:     #7dabf8;   /* 7,19:1 */

  /* En sombre la bordure se fonce : sur un fond adouci sombre, une bordure
     claire ferait un liseré lumineux au lieu d'un contour. */
  --gs-success-border: #1f5240;
  --gs-warn-border:    #5c4520;
  --gs-danger-border:  #5c2626;
  --gs-info-border:    #24406b;
  --gs-shadow-sm:     0 1px 2px rgba(0,0,0,.30);
  --gs-shadow:        0 4px 14px rgba(0,0,0,.40);
  --gs-shadow-lg:     0 12px 34px rgba(0,0,0,.55);
}

/* ── Page header ────────────────────────────────────────────────────── */
.gsa-page-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--gs-space-4); flex-wrap: wrap; margin-block-end: var(--gs-space-5);
}
.gsa-page-header h1 { font-size: var(--gs-text-xl); }
.gsa-page-header .gsa-page-sub { color: var(--gs-text-muted); font-size: var(--gs-text-sm); margin-block-start: 4px; }
.gsa-page-header .gsa-page-actions { display: flex; gap: var(--gs-space-2); flex-wrap: wrap; }

/* ── Buttons ────────────────────────────────────────────────────────── */
.gsa-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 9px 16px; border: 1px solid transparent; border-radius: var(--gs-radius-sm);
  font-family: inherit; font-size: var(--gs-text-sm); font-weight: 600; line-height: 1;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: filter .15s, background .15s, border-color .15s, transform .08s;
}
.gsa-btn:hover { text-decoration: none; }
.gsa-btn:active { transform: scale(.98); }
.gsa-btn[disabled], .gsa-btn:disabled { opacity: .55; cursor: not-allowed; }
.gsa-btn--primary   { background: var(--gs-accent); color: var(--gs-accent-ink); }
.gsa-btn--primary:hover { filter: brightness(1.12); }
.gsa-btn--secondary { background: var(--gs-surface); color: var(--gs-text); border-color: var(--gs-border); }
.gsa-btn--secondary:hover { background: var(--gs-surface-2); border-color: var(--gs-text-faint); }
.gsa-btn--ghost     { background: transparent; color: var(--gs-text-muted); }
.gsa-btn--ghost:hover { background: var(--gs-border-soft); color: var(--gs-text); }
.gsa-btn--danger    { background: var(--gs-danger); color: #fff; }
.gsa-btn--danger:hover { filter: brightness(1.08); }
.gsa-btn--sm { padding: 6px 11px; font-size: var(--gs-text-xs); }
/* --lg = le bouton TACTILE. Le kit n'avait que --sm et la taille canonique
   (~34px de haut) : trop petit pour un pouce, ce qui forçait les vues mobiles
   (dvir, portail chauffeur) à réécrire leurs boutons à la main. min-height porte
   le contrat 44px (WCAG 2.5.5 / Apple HIG) INDÉPENDAMMENT des métriques de
   police — un padding seul se ferait rogner par un font-size plus petit. */
.gsa-btn--lg { min-height: 44px; padding: 12px 20px; font-size: var(--gs-text-base); }
.gsa-btn--block { width: 100%; }
/* Focus clavier porté par le COMPOSANT, pas par le shell. gs-app.css pose
   `.gsa :focus-visible` mais c'est scopé au <body class="gsa"> de layouts.app ;
   or le kit sert maintenant des pages AUTONOMES (settings/hub, account/*) dont
   le <body> n'a pas cette classe → sans ceci, un .gsa-btn n'y aurait aucun
   anneau de focus au clavier. Mêmes valeurs que la règle du shell → sur
   layouts.app le rendu est inchangé. */
.gsa-btn:focus-visible { outline: 2px solid var(--gs-accent-2); outline-offset: 2px; }

/* ── Card ───────────────────────────────────────────────────────────── */
.gsa-card {
  background: var(--gs-surface); border: 1px solid var(--gs-border);
  border-radius: var(--gs-radius); box-shadow: var(--gs-shadow-sm);
  padding: var(--gs-space-5);
}
.gsa-card--pad-sm { padding: var(--gs-space-4); }
.gsa-card-title { font-size: var(--gs-text-lg); font-weight: 700; margin-block-end: var(--gs-space-3); }
.gsa-grid { display: grid; gap: var(--gs-space-4); grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.gsa-stack > * + * { margin-block-start: var(--gs-space-4); }   /* vertical rhythm between cards */

/* ── Table (responsive: horizontal scroll wrapper, no fixed widths) ──── */
.gsa-table-wrap { width: 100%; overflow-x: auto; border: 1px solid var(--gs-border); border-radius: var(--gs-radius); background: var(--gs-surface); -webkit-overflow-scrolling: touch; }
.gsa-table { width: 100%; border-collapse: collapse; font-size: var(--gs-text-sm); }
.gsa-table th, .gsa-table td { padding: 10px 14px; text-align: start; border-block-end: 1px solid var(--gs-border-soft); white-space: nowrap; }
.gsa-table thead th { background: var(--gs-surface-2); color: var(--gs-text-muted); font-weight: 600; position: sticky; inset-block-start: 0; }
.gsa-table tbody tr:hover { background: var(--gs-accent-soft); }
.gsa-table tbody tr:last-child td { border-block-end: 0; }
.gsa-table--num td.gsa-num, .gsa-table .gsa-num { text-align: end; font-variant-numeric: tabular-nums; }

/* ── Form field ─────────────────────────────────────────────────────── */
.gsa-field { display: flex; flex-direction: column; gap: 6px; margin-block-end: var(--gs-space-4); }
.gsa-label { font-size: var(--gs-text-sm); font-weight: 600; color: var(--gs-text); }
.gsa-label .gsa-req { color: var(--gs-danger-text); margin-inline-start: 2px; }
.gsa-input, .gsa-select, .gsa-textarea {
  width: 100%; padding: 10px 12px;
  font-family: inherit; font-size: var(--gs-text-base); color: var(--gs-text);
  background: var(--gs-surface); border: 1px solid var(--gs-border);
  border-radius: var(--gs-radius-sm); transition: border-color .15s, box-shadow .15s;
}
.gsa-input::placeholder, .gsa-textarea::placeholder { color: var(--gs-text-faint); }
.gsa-input:focus, .gsa-select:focus, .gsa-textarea:focus {
  outline: none; border-color: var(--gs-accent-3);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gs-accent-2) 30%, transparent);
}
.gsa-field--error .gsa-input, .gsa-field--error .gsa-select, .gsa-field--error .gsa-textarea { border-color: var(--gs-danger-text); }
.gsa-error { font-size: var(--gs-text-xs); color: var(--gs-danger-text); }
.gsa-hint  { font-size: var(--gs-text-xs); color: var(--gs-text-muted); }

/* ── Alert ──────────────────────────────────────────────────────────── */
.gsa-alert {
  display: flex; gap: var(--gs-space-3); align-items: flex-start;
  padding: 12px 16px; border-radius: var(--gs-radius-sm);
  border-inline-start: 3px solid var(--gs-info); background: var(--gs-info-soft);
  color: var(--gs-text); font-size: var(--gs-text-sm); margin-block-end: var(--gs-space-4);
}
.gsa-alert--success { border-inline-start-color: var(--gs-success-text); background: var(--gs-success-soft); }
.gsa-alert--warn    { border-inline-start-color: var(--gs-warn-text);    background: var(--gs-warn-soft); }
.gsa-alert--danger  { border-inline-start-color: var(--gs-danger-text);  background: var(--gs-danger-soft); }

/* ── Badge ──────────────────────────────────────────────────────────── */
.gsa-badge { display: inline-flex; align-items: center; gap: 4px; padding: 2px 9px; border-radius: 999px; font-size: var(--gs-text-xs); font-weight: 600; background: var(--gs-border-soft); color: var(--gs-text-muted); }
.gsa-badge--success { background: var(--gs-success-soft); color: var(--gs-success-text); }
.gsa-badge--warn    { background: var(--gs-warn-soft);    color: var(--gs-warn-text); }
.gsa-badge--danger  { background: var(--gs-danger-soft);  color: var(--gs-danger-text); }

/* ── État vide ────────────────────────────────────────────────────────
   Le motif le plus réécrit du dépôt (25 vues avant le 2026-09-05). Un écran
   vide est une invitation à agir : titre affirmatif, une phrase au plus, une
   seule action. Pas d'illustration — elle vieillit mal et se traduit mal. */
.gsa-empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--gs-space-2);
  padding: var(--gs-space-6) var(--gs-space-4);
  text-align: center; color: var(--gs-text-muted);
}
.gsa-empty-title { margin: 0; font-size: var(--gs-text-lg); font-weight: 600; color: var(--gs-text); }
.gsa-empty-text  { margin: 0; font-size: var(--gs-text-sm); max-width: 46ch; line-height: 1.55; }
.gsa-empty .gsa-btn { margin-block-start: var(--gs-space-2); }

/* ── Tuile de statistique ─────────────────────────────────────────────
   Deuxième motif le plus réécrit (22 vues). Chiffres TABULAIRES : sans eux,
   une rangée de tuiles qui se rafraîchit fait danser ses colonnes. */
.gsa-stat {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--gs-space-3) var(--gs-space-4);
  background: var(--gs-surface); border: 1px solid var(--gs-border);
  border-radius: var(--gs-radius-sm);
}
.gsa-stat-value {
  font-size: var(--gs-text-xxl); font-weight: 700; line-height: 1.05;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em; color: var(--gs-text);
}
.gsa-stat-label { font-size: var(--gs-text-sm); color: var(--gs-text-muted); }
.gsa-stat-hint  { font-size: var(--gs-text-xs); color: var(--gs-text-faint); }
.gsa-stat--success .gsa-stat-value { color: var(--gs-success-text); }
.gsa-stat--warn    .gsa-stat-value { color: var(--gs-warn-text); }
.gsa-stat--danger  .gsa-stat-value { color: var(--gs-danger-text); }
.gsa-stat--info    .gsa-stat-value { color: var(--gs-info-text); }

/* ── Responsive (breakpoint canonique unique --gs-bp-md) ────────────── */
@media (max-width: 860px) {
  .gsa-page-header { flex-direction: column; align-items: stretch; }
  .gsa-grid { grid-template-columns: 1fr; }
}
