/* ===========================================================
   Gestion · Design tokens + shared layout
   Source de vérité: DESIGN.md à la racine.
   Système institutionnel calme: pill CTAs, rounded-xl cards,
   accent unique (Vert primaire #0a0b0d), Inter + JetBrains Mono.
   =========================================================== */

@import url('https://api.fontshare.com/v2/css?f[]=satoshi@400,500,700,900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');

:root {
  /* ===== Surfaces ===== */
  --canvas:                 #ffffff;
  --surface-soft:           #f7f7f7;
  --surface-strong:         #eef0f3;
  --surface-dark:            #0a0b0d;
  --surface-dark-elevated:  #1f2228;  /* Cartes/topbar en dark mode (était #16181c, bumpé pour plus de contraste vs. surface-dark) */
  --input-bg:               #fafbfc;  /* Très pâle, juste-pas-blanc · fond des inputs */

  /* Aliases retro-compatibilité (anciens noms) */
  --bg-app:                 var(--canvas);
  --bg-surface:             var(--canvas);
  --bg-muted:               var(--surface-soft);
  --bg-sidebar:             var(--surface-dark);

  /* ===== Hairlines ===== */
  --hairline:               #dee1e6;
  --hairline-soft:          #eef0f3;
  --border:                 var(--hairline);
  --border-soft:            var(--hairline-soft);

  /* ===== Texte ===== */
  --ink:                    #0a0b0d;
  --body:                   #5b616e;
  --body-strong:            #0a0b0d;
  --muted:                  #7c828a;
  --muted-soft:             #a8acb3;
  --on-primary:             var(--canvas);
  --on-dark:                #ffffff;
  --on-dark-soft:           #a8acb3;

  /* Aliases retro-compatibilité */
  --text-strong:            var(--ink);
  --text:                   var(--body);
  --text-muted:             var(--muted);
  --text-subtle:            var(--muted-soft);

  /* ===== Brand ===== */
  --primary:                var(--ink);
  --primary-active:         #343a40;
  --primary-disabled:       #c2c5ca;
  --primary-soft:           #e8eaed;
  --primary-hover:          var(--primary-active);
  --primary-fg:             var(--primary);
  --accent-yellow:          #f4b000;

  /* ===== Trading / status sémantiques ===== */
  --semantic-up:            #5b616e;
  --semantic-down:          #cf202f;
  --semantic-down-on-dark:  #fca5a5;  /* Rouge clair lisible sur surface-dark */
  --semantic-success:       #16a34a;  /* Vert succès (crochet de confirmation) */
  --semantic-success-soft:  #dcfce7;  /* Vert pastel pâle (fond du crochet) */
  --ok:                     var(--semantic-up);
  --danger:                 var(--semantic-down);
  --warn:                   var(--accent-yellow);

  /* ===== Graphiques (rampe monochrome · surchargeable par theme-client.css)
     Lus au runtime par les pages à charts (stats, workflow). ===== */
  --chart-1:                #0a0b0d;
  --chart-2:                #5b616e;
  --chart-3:                #a8acb3;
  --chart-4:                #343a40;
  --chart-5:                #7c828a;
  --chart-6:                #c2c5ca;
  --chart-7:                #1f2228;
  --chart-8:                #8d939b;
  --chart-9:                #494f57;
  --chart-10:               #6b7178;

  /* ===== Spacing (base 4px) ===== */
  --space-xxs:              4px;
  --space-xs:               8px;
  --space-sm:               12px;
  --space-base:             16px;
  --space-md:               20px;
  --space-lg:               24px;
  --space-xl:               32px;
  --space-xxl:              48px;
  --space-section:          96px;

  /* ===== Layout ===== */
  --sidebar-w:              64px;
  --topbar-h:               72px;
  --content-max:            1200px;

  /* ===== Radius ===== */
  --r-xs:                   4px;
  --r-sm:                   8px;
  --r-md:                   12px;
  --r-lg:                   16px;
  --r-xl:                   24px;
  --r-pill:                 100px;
  --r-full:                 9999px;

  /* ===== Shadows (echelle unique) ===== */
  --shadow-card:            none;
  --shadow:                 0 1px 3px rgba(16,24,40,0.03), 0 24px 48px -20px rgba(16,24,40,0.13);  /* carte flottante (defaut) */
  --shadow-hover:           0 4px 12px rgba(0, 0, 0, 0.04);

  /* ===== Fonts ===== */
  --font-display:           'Satoshi', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-body:              'Satoshi', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono:              'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Monaco, monospace;
  --font:                   var(--font-body);

  /* ===== Echelle typo (6 paliers · source de verite des tailles de texte) =====
     Echelle "Confort" (montee d'un cran le 17 juin · avant: 11/13/14/18/24/32).
     Plancher absolu 12px. Aucun texte ecran sous --text-caption.
     Le contraste titre-de-carte vs corps se fait par le POIDS (semibold vs regular),
     pas par une taille de plus. Chiffres tabulaires: toujours var(--font-mono).
     Pour rechanger toute l'echelle d'un coup, modifier UNIQUEMENT ces 6 valeurs. */
  --text-display:           38px;  /* hero plein ecran, gros chiffre KPI vedette */
  --text-h1:                28px;  /* titre de page (injecte par mountLayout) */
  --text-h2:                20px;  /* en-tete de section, titre de modal/drawer */
  --text-body:              15px;  /* texte courant, input, titre de carte (en w600) */
  --text-label:             14px;  /* label, nav, meta, cellule de tableau, bouton compact */
  --text-caption:           12px;  /* badge, compteur, en-tete de tableau, sur-label uppercase */
  --tracking-display:       -0.8px;

  /* ===== Poids (plafond 600 · jamais 700) ===== */
  --weight-regular:         400;
  --weight-medium:          500;
  --weight-semibold:        600;
}

/* ============================================================
   Dark mode · set [data-theme="dark"] sur <html>.
   Seules les variables qui doivent changer avec le thème sont
   redéfinies. Tout le reste (--primary, --semantic-*, --surface-dark,
   --on-dark, --space-*, --r-*, --font-*) reste constant.
   Toutes les pages qui utilisent var(--canvas), var(--ink), etc.
   suivent automatiquement le thème · aucun refactor par page.
   ============================================================ */
[data-theme="dark"] {
  /* Surfaces (cartes et page) */
  --canvas:           var(--surface-dark-elevated);  /* cartes #1f2228 (élevées vs. page) */
  --surface-soft:     var(--surface-dark);           /* page bg #0a0b0d (plus sombre) */
  --surface-strong:   rgba(255,255,255,0.10);        /* boutons secondaires, badges */
  --input-bg:         rgba(255,255,255,0.06);        /* inputs (visible sur cartes) */

  /* Hairlines (bordures plus marquées pour bien délimiter les blocs) */
  --hairline:         rgba(255,255,255,0.14);
  --hairline-soft:    rgba(255,255,255,0.08);

  /* Texte */
  --ink:              #ffffff;
  --body:             rgba(255,255,255,0.78);
  --muted:            #a8acb3;
  --muted-soft:       rgba(255,255,255,0.4);

  /* Accent monochrome · le bouton blanc s'assombrit au survol en dark */
  --primary-active:   #e4e4e6;
  --primary-soft:     rgba(255,255,255,0.14);
}


/* fix pour flash lorsque pas loggé */

body.auth-guard
{
  display: flex;
  background-color: var(--surface-soft);
  font-family: var(--font-body);
  color: var(--body);
  display: flex;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
body:not(.auth-guard) {
  display: none;
  background-color: #000000;
}

body:not(.auth-guard) > * {
  display: none;
}

a { color: inherit; text-decoration: none; }

/* ===== Type display (poids 400, letter-spacing négatif) ===== */
h1, h2, h3, h4 { font-family: var(--font-display); color: var(--ink); font-weight: 400; }
h1 { font-size: 52px; line-height: 1.0;  letter-spacing: -1.3px; }
h2 { font-size: 36px; line-height: 1.11; letter-spacing: -0.5px; }
h3 { font-size: 24px; line-height: 1.2;  letter-spacing: -0.3px; }
h4 { font-size: 18px; line-height: 1.33; font-weight: 600; letter-spacing: 0; }

/* ===== Chevron unifie pour TOUS les <select> =====
   Beaucoup de pages laissaient le chevron natif (colle au bord droit) ou
   redefinissaient le leur a des positions differentes. Cette regle force un
   chevron custom unique, bien espace du bord, partout. !important pour passer
   par-dessus les `background:` shorthand des selects par page (qui sinon
   effacent l'image). La couleur de fond du select reste geree par chaque page. */
select {
  -webkit-appearance: none !important;
  -moz-appearance: none !important;
  appearance: none !important;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 6l4 4 4-4' stroke='%237c828a' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: right 14px center !important;
  background-size: 16px 16px !important;
  padding-right: 38px !important;
}

/* ===== SIDEBAR (transparente, icônes flottantes · pas de boîte) ===== */
.sidebar {
  width: var(--sidebar-w);
  background: transparent;
  border-right: none;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  position: fixed;
  top: 0; left: 0;
  height: 100vh;
  z-index: 100;
  overflow: visible;
}
.sidebar-logo {
  height: var(--topbar-h); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
/* Initial de marque dans un carré noir arrondi (comme l'image de réf) */
.sidebar-brand {
  width: 40px; height: 40px;
  border-radius: var(--r-md);
  background: var(--primary);
  color: var(--on-primary);
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: var(--weight-semibold); letter-spacing: -0.5px;
  flex-shrink: 0;
}
/* Logo image du client (config logoImage · white-label) · fond transparent
   pour les PNG détourés (sinon carré noir derrière), image jamais rognée. */
.sidebar-brand.has-img { background: transparent; }
.sidebar-brand img { width: 100%; height: 100%; object-fit: contain; border-radius: inherit; display: block; }
/* Legacy logo-text/logo-sub masqués en mode étroit */
.sidebar-logo .logo-text,
.sidebar-logo .logo-sub { display: none; }

.sidebar-nav {
  flex: 1;
  /* ⚠ EN HAUT, ALIGNÉES SUR LE CONTENU · elles étaient centrées dans toute la
     hauteur de la fenêtre (`justify-content: center`), donc elles flottaient
     au milieu du vide, sans rapport avec quoi que ce soit à côté. Le
     propriétaire : « je pense que c'est laid, est-ce qu'on peut les monter et
     les mettre égal au contenu ? ».
     Le padding du haut reprend celui de `.page-head` (--space-lg) · la
     première icône se pose donc exactement sur la ligne du fil d'Ariane, et
     l'oeil retrouve un alignement au lieu d'un flottement. */
  padding: var(--space-lg) 0 8px;
  overflow-y: auto; overflow-x: visible;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 6px;
  scrollbar-width: none;
}
.sidebar-nav::-webkit-scrollbar { display: none; }

/* Les labels de section sont masqués en mode étroit */
.nav-section-label { display: none; }

.nav-item {
  display: flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; padding: 0;
  border-radius: var(--r-full);
  background: var(--hairline);
  color: var(--body);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  position: relative;
  white-space: nowrap; text-decoration: none;
}
/* Rond gris TOUJOURS présent · icône foncée au survol (comme l'image de réf) */
.nav-item:hover { background: var(--muted-soft); color: var(--ink); }
/* Item actif = rond NOIR, icône blanche (comme l'image de réf) */
.nav-item.active {
  background: var(--primary); color: var(--on-primary);
}
.nav-item svg { width: 20px; height: 20px; flex-shrink: 0; }

/* Badge compteur : petite pastille verte en haut à droite de l'icône */
.nav-item .badge {
  position: absolute; top: 4px; right: 4px;
  background: var(--primary); color: var(--on-primary);
  font-size: var(--text-caption); font-weight: var(--weight-semibold);
  min-width: 15px; height: 15px; padding: 0 4px;
  border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono);
  line-height: 1;
  border: 1.5px solid var(--canvas);
}
.nav-item.active .badge { border-color: var(--primary); }
.nav-item .nav-count {
  position: absolute; top: 3px; right: 3px;
  min-width: 15px; height: 15px; padding: 0 3px;
  font-size: var(--text-caption); font-weight: var(--weight-semibold); line-height: 15px;
  text-align: center;
  color: var(--on-primary); background: var(--primary);
  border-radius: var(--r-pill);
  font-family: var(--font-mono);
  border: 1.5px solid var(--canvas);
}
.nav-item.active .nav-count { border-color: var(--primary); }
/* Masque les compteurs à zéro / vides */
.nav-item .nav-count:empty { display: none; }

.sidebar-footer {
  padding: 10px 0;
  border-top: none;
  display: flex; justify-content: center;
}
.user-menu-wrap {
  position: relative;
}
.user-pill {
  display: flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; padding: 0;
  border-radius: var(--r-md);
  cursor: pointer;
  transition: background 0.15s;
  user-select: none;
}
.user-pill:hover { background: var(--surface-soft); }
.user-pill.open { background: var(--surface-strong); }
/* Nom/rôle/chevron masqués en mode étroit */
.user-pill-info { display: none; }
.user-pill-chev { display: none; }
.user-avatar {
  width: 32px; height: 32px; border-radius: var(--r-full);
  background: var(--primary);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600; color: var(--on-primary);
  flex-shrink: 0;
  position: relative;
}

/* Point vert "en ligne" · pose en absolu sur les avatars (n'importe quels).
   Le selecteur :has rend automatiquement le parent position: relative. */
:has(> .presence-dot) { position: relative; }
.presence-dot {
  position: absolute;
  bottom: -1px; right: -1px;
  width: 10px; height: 10px;
  background: var(--semantic-up);
  border: 2px solid var(--canvas);
  border-radius: var(--r-full);
  pointer-events: none;
}
[data-theme="dark"] .presence-dot { border-color: var(--canvas); }
/* Variante quand l'avatar est dans le sidebar clair */
.user-pill .presence-dot,
.sidebar .presence-dot {
  border-color: var(--canvas);
}
/* Petite variante pour mini-avatars (dropdowns) */
.mini-avatar { position: relative; }
.mini-avatar .presence-dot {
  width: 8px; height: 8px;
  bottom: -1px; right: -1px;
  border-width: 1.5px;
}
.user-name { font-size: 13px; font-weight: 600; color: var(--on-dark); }
.user-role { font-size: 11px; color: var(--on-dark-soft); }

/* Menu deroulant qui apparait au-dessus de la pill */
.user-menu {
  display: none;
  position: absolute;
  bottom: 0;
  left: calc(100% + 10px);
  right: auto;
  min-width: 200px;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  padding: 4px;
  z-index: 150;
  box-shadow: 0 8px 28px rgba(0,0,0,0.12);
}
.user-menu.open { display: block; }
.user-menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  background: transparent;
  border: none;
  border-radius: var(--r-sm);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 13px; font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  width: 100%;
  text-align: left;
  transition: background 0.12s, color 0.12s;
}
.user-menu-item svg { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.6; }
.user-menu-item:hover { background: var(--surface-soft); }
.user-menu-item:hover svg { opacity: 1; }
.user-menu-item.user-menu-danger { color: var(--semantic-down); }
.user-menu-item.user-menu-danger:hover { background: var(--err-soft, #fde8e8); }
.user-menu-divider {
  height: 1px;
  background: var(--hairline-soft);
  margin: 4px 0;
}

/* ===== MAIN + TOPBAR ===== */
.main {
  margin-left: var(--sidebar-w);
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-width: 0;
  background: var(--surface-soft);
}
.topbar {
  background: var(--surface-soft);
  padding: 0 var(--space-xl);
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 50;
}
.topbar-title { font-size: 16px; font-weight: 600; color: var(--ink); letter-spacing: -0.2px; }

/* Onglets pilule du haut (look démo) · sections principales */
.top-tabs {
  display: flex; align-items: center; gap: 2px;
  background: var(--surface-strong);
  padding: 5px; border-radius: var(--r-pill);
  overflow-x: auto; scrollbar-width: none; max-width: 100%;
}
.top-tabs::-webkit-scrollbar { display: none; }
.top-tab {
  display: inline-flex; align-items: center;
  padding: 9px 18px; border-radius: var(--r-pill);
  font-size: 14px; font-weight: 500; color: var(--body);
  text-decoration: none; white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}
.top-tab:hover { color: var(--ink); }
.top-tab.active { background: var(--primary); color: var(--on-primary); }

/* ---- Tableaux CACHÉS · le « … » au bout de la barre (layout.js) ---- */
/* Un tableau caché fonctionne, on y va juste rarement (Annulés). Il quitte les
   onglets mais garde une porte · sans elle, « caché » voudrait dire « perdu ».
   Discret par construction : pas de fond, ton sourdine, comme « Gérer ». */
/* ---- Gestion des tableaux (admin · board-tableaux.js) ---- */
/* Bouton « Gérer les tableaux » · icône discrète à droite des onglets. Ouvre le
   volet qui porte TOUT (ajouter, réordonner, cacher, renommer, supprimer). */
.top-tab-manage {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--r-full);
  /* PAS DE POINTILLÉS · ils annonçaient « emplacement à remplir » alors que
     c'est un vrai bouton, permanent. Il se tient comme les autres ronds de la
     topbar : pas de bordure, un fond qui s'allume au survol. */
  background: transparent; border: none;
  color: var(--muted); cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.top-tab-manage svg { width: 18px; height: 18px; }
.top-tab-manage:hover { color: var(--ink); background: var(--surface-soft); }

/* Volet « Gérer les tableaux » · liste verticale, glisser fiable. */
.app-tableaux-panel {
  z-index: 1200; width: 360px; max-height: 72vh; overflow-y: auto;
  background: var(--canvas); color: var(--ink);
  border: 1px solid var(--hairline); border-radius: var(--r-lg, var(--r-md));
  box-shadow: var(--shadow); padding: 12px;
}
/* Barre de défilement fine et discrète · l'ancienne était brute et collée au
   bord. Ne s'affiche que si le contenu dépasse (overflow auto). Le liseré de la
   couleur du fond détache le pouce du bord. */
.app-tableaux-panel { scrollbar-width: thin; scrollbar-color: var(--hairline-strong, var(--hairline)) transparent; }
.app-tableaux-panel::-webkit-scrollbar { width: 10px; }
.app-tableaux-panel::-webkit-scrollbar-track { background: transparent; }
.app-tableaux-panel::-webkit-scrollbar-thumb {
  background: var(--hairline-strong, var(--hairline)); border-radius: 100px;
  border: 3px solid var(--canvas); background-clip: padding-box;
}
.app-tableaux-head { font-family: var(--font-display); font-size: 16px; font-weight: 600; margin-bottom: 2px; }
.app-tableaux-hint { font-size: 11px; color: var(--muted); line-height: 1.4; margin-bottom: 12px; }
.app-tableaux-section-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted); margin: 10px 4px 6px;
}
.app-tableaux-list { display: flex; flex-direction: column; gap: 4px; min-height: 34px; border-radius: var(--r-md); }
.app-tableaux-list:empty::after {
  content: attr(data-empty); display: flex; align-items: center; justify-content: center;
  min-height: 34px; font-size: 12px; color: var(--muted-soft); font-style: italic;
  border: 1px dashed var(--hairline); border-radius: var(--r-md);
}
/* Ligne · mini-carte grise (le look que le proprio aime). Ce qui pechait, c'etait
   l'etat OUVERT · pas la carte fermee. Donc on garde la carte, on ne retouche que
   le menu (plus bas · .app-tableau-menu). */
.app-tableau-row {
  display: flex; flex-direction: column; align-items: stretch; gap: 6px;
  padding: 8px 10px; border-radius: var(--r-md);
  background: var(--surface-soft);
}
.app-tableau-row.app-tableau-ghost { opacity: 0.4; }
/* Ligne principale · poignée + nom + engrenage. */
.app-tableau-main { display: flex; align-items: center; gap: 8px; }
.app-tableau-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; margin-left: auto; }
.app-tableau-grip { flex: 0 0 auto; cursor: grab; color: var(--muted-soft); font-size: 13px; user-select: none; }
.app-tableau-grip:active { cursor: grabbing; }
.app-tableau-name {
  flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: text; outline: none; border-radius: var(--r-sm); padding: 2px 4px;
}
.app-tableau-name[contenteditable="true"] { box-shadow: inset 0 0 0 2px var(--ink); overflow: visible; text-overflow: clip; background: var(--canvas); }
.app-tableau-name:empty::before { content: attr(data-placeholder); color: var(--muted-soft); }
/* Boutons d'action ÉTIQUETÉS · Archiver / Rétablir / Supprimer définitivement. */
.app-tableau-action {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  padding: 5px 11px; border-radius: var(--r-pill);
  font-family: inherit; font-size: 12px; font-weight: 600;
  border: 1px solid var(--hairline); background: var(--canvas); color: var(--body);
  cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.app-tableau-action svg { width: 14px; height: 14px; }
.app-tableau-action:hover { color: var(--ink); border-color: var(--ink); }
.app-tableau-action.delete { color: var(--semantic-down); border-color: transparent; }
.app-tableau-action.delete:hover { color: var(--semantic-down); border-color: var(--semantic-down); background: color-mix(in srgb, var(--semantic-down) 12%, transparent); }
/* 2e ligne · réglages (actifs) ou actions Rétablir/Supprimer (archivés). */
.app-tableau-settings,
.app-tableau-actions-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  padding-left: 22px;   /* aligné sous le nom, après la poignée */
}

/* Menu déplié · une CARTE BLANCHE distincte à l'intérieur de la mini-carte grise
   du tableau. C'est ce qui reglait le reproche : avant, le menu etait a plat dans
   le gris (gros bloc lourd) · maintenant il se detache comme un vrai menu, avec
   son fond canvas et son filet. Liste verticale, items pleine largeur. */
.app-tableau-menu {
  display: flex; flex-direction: column; gap: 2px;
  padding: 4px;
  background: var(--canvas); border: 1px solid var(--hairline);
  border-radius: var(--r-md);
}
.app-tableau-menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border-radius: var(--r-md);
  font-family: inherit; font-size: var(--text-label); font-weight: 400; text-align: left;
  border: none; background: transparent; color: var(--body);
  cursor: pointer; text-decoration: none;
  transition: background 0.12s, color 0.12s;
}
.app-tableau-menu-item svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--muted); }
.app-tableau-menu-item > span:first-of-type { flex: 1 1 auto; }
.app-tableau-menu-item:hover { background: var(--surface-soft); color: var(--ink); }
.app-tableau-menu-item:hover svg { color: var(--ink); }
/* État courant à droite (Suivi activé/éteint, déplacement bloqué/permis). */
.app-tableau-menu-state {
  flex: 0 0 auto; font-size: var(--text-caption); color: var(--muted-soft);
  font-family: var(--font-mono);
}
.app-tableau-menu-item.on .app-tableau-menu-state { color: var(--primary); }
.app-tableau-menu-item.on svg { color: var(--primary); }
/* Mise en évidence INLINE (pas un pop-up) · juste après qu'on a allumé le suivi,
   « Configurer le workflow » ressort DOUCEMENT pour dire « c'est ici que ça se
   passe ». Surlignage gris clair + liseré, pas de noir plein (trop fort). Retombe
   au calme dès qu'on change de menu. */
.app-tableau-menu-item.is-cta {
  background: color-mix(in srgb, var(--ink) 6%, var(--canvas));
  color: var(--ink); font-weight: 500;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 16%, transparent);
}
.app-tableau-menu-item.is-cta svg { color: var(--ink); }
.app-tableau-menu-item.is-cta:hover { background: color-mix(in srgb, var(--ink) 10%, var(--canvas)); }
/* Action destructive (Supprimer) · rouge, mais discrète tant qu'on ne la survole pas. */
.app-tableau-menu-item.danger { color: var(--semantic-down); }
.app-tableau-menu-item.danger svg { color: var(--semantic-down); }
.app-tableau-menu-item.danger:hover { background: color-mix(in srgb, var(--semantic-down) 12%, transparent); color: var(--semantic-down); }
.app-tableau-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: var(--r-pill);
  font-family: inherit; font-size: 12px; font-weight: 500;
  border: 1px solid var(--hairline); background: var(--canvas); color: var(--muted);
  cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.app-tableau-chip svg { width: 13px; height: 13px; }
.app-tableau-chip:hover { color: var(--ink); border-color: var(--ink); }
.app-chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted-soft); flex: 0 0 auto; }
/* Puce « Suivi » allumée · pastille pleine. */
.app-tableau-suivi.on { color: var(--on-primary); background: var(--primary); border-color: var(--primary); }
.app-tableau-suivi.on .app-chip-dot { background: var(--on-primary); }
/* Puce « Bloquer le déplacement » active (bloqué) · rouge. */
.app-tableau-manuel.on { color: var(--on-dark); background: var(--semantic-down); border-color: var(--semantic-down); }
/* Lien « Modifier le workflow → ». */
.app-tableau-wf-link { font-size: 12px; font-weight: 500; color: var(--body); text-decoration: none; padding: 4px 4px; border-radius: var(--r-sm); }
.app-tableau-wf-link:hover { color: var(--ink); text-decoration: underline; }
/* Roue « réglages avancés » (suivi/workflow) · repliée par défaut. */
.app-tableau-adv {
  flex: 0 0 auto; position: relative; width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: var(--r-full);
  background: transparent; color: var(--muted); cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.app-tableau-adv svg { width: 15px; height: 15px; }
.app-tableau-adv:hover { color: var(--ink); background: var(--surface-strong); }
.app-tableau-adv.is-open { color: var(--ink); background: var(--surface-strong); border-color: var(--hairline); }
/* Oeil · cacher / afficher dans la barre. Même gabarit que la roue (ils se
   suivent). Un tableau CACHÉ reste en service · sa ligne pâlit sans se barrer,
   pour ne pas se confondre avec « archivé ». */
.app-tableau-eye {
  flex: 0 0 auto; width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: var(--r-full);
  background: transparent; color: var(--muted); cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.app-tableau-eye svg { width: 15px; height: 15px; }
.app-tableau-eye:hover { color: var(--ink); background: var(--surface-strong); }
.app-tableau-row.is-hidden .app-tableau-name { color: var(--muted); }
.app-tableau-row.is-hidden .app-tableau-eye { color: var(--ink); }

/* Repère · ce tableau a un suivi (workflow) allumé · point d'accent sur la roue. */
.app-tableau-adv.has-suivi::after {
  content: ''; position: absolute; top: 3px; right: 3px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--primary); border: 1.5px solid var(--surface-soft);
}
/* Phrase d'aide en tête des réglages avancés dépliés. */
.app-tableau-adv-hint { flex: 1 1 100%; font-size: 11px; color: var(--muted); line-height: 1.4; margin-bottom: 2px; }
/* « + Ajouter un tableau » · au bas du volet. Crée une ligne éditable en place. */
.app-tableau-add {
  display: flex; align-items: center; gap: 6px; width: 100%;
  margin-top: 10px; padding: 9px 12px; border-radius: var(--r-md);
  font-family: inherit; font-size: 13px; font-weight: 600;
  color: var(--muted); background: transparent;
  border: 1px dashed var(--hairline-strong, var(--hairline));
  cursor: pointer; transition: color 0.15s, border-color 0.15s;
}
.app-tableau-add:hover { color: var(--ink); border-color: var(--ink); }
.app-tableau-add-plus { font-size: 15px; line-height: 1; }
/* Pied du volet · lien vers les FICHES archivées (récupération de cartes) · séparé
   par un filet pour bien le distinguer de la section « Archivés » des TABLEAUX. */
.app-tableaux-foot-link {
  display: flex; align-items: center; gap: 8px; width: 100%;
  margin-top: 10px; padding: 10px 12px 10px 10px;
  border-top: 1px solid var(--hairline); border-radius: 0;
  color: var(--body); text-decoration: none;
  transition: color 0.15s;
}
.app-tableaux-foot-link svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--muted); }
.app-tableaux-foot-link:hover { color: var(--ink); }
.app-tableaux-foot-link:hover svg { color: var(--ink); }
.app-tableaux-foot-main { font-size: 13px; font-weight: 600; }
.app-tableaux-foot-cap { font-size: 11px; color: var(--muted-soft); margin-left: auto; text-align: right; }

/* ---- Ombre des cartes · douce et JAMAIS coupée ----
   `.col-cards` scrolle (overflow) et hugge les cartes · une grosse ombre en
   dépassait toujours → ligne de coupe. Deux temps :
   1. Ombre de carte COURTE et douce (tient dans ~14px au repos, ~22px au survol),
      au lieu de l'ombre « soulevée » de 24px/48px du token global.
   2. Assez de marge (padding) dans `.col-cards` pour la contenir entièrement.
   Sélecteur `.kanban-board …` · plus spécifique que les CSS par tableau, gagne. */
.kanban-board .col-cards { padding: 2px 4px 24px 4px; }
.kanban-board .fiche-card,
.kanban-board .demande-card {
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05), 0 4px 10px -4px rgba(16, 24, 40, 0.10);
}
.kanban-board .fiche-card:hover,
.kanban-board .demande-card:hover {
  box-shadow: 0 2px 4px rgba(16, 24, 40, 0.06), 0 8px 18px -6px rgba(16, 24, 40, 0.12);
}

/* ---- « + » d'ajout d'une fiche dans une colonne (board.js · générique) ----
   Neutre au repos (se distingue du « + Nouveau lead » noir plein de Leads),
   se remplit d'encre au survol. Présent sur chaque colonne de chaque tableau. */
.col-add {
  width: 22px; height: 22px; flex-shrink: 0; margin-left: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--hairline); border-radius: var(--r-full);
  background: var(--canvas); color: var(--muted); cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.col-add:hover { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
.col-add:disabled { opacity: 0.5; cursor: default; }

/* ---- « + Ajouter une colonne » (admin · board-columns.js) ----
   Pastille COMPACTE alignée avec les en-têtes de colonnes, à droite de la
   dernière (au lieu d'un gros pavé). Clic → devient un champ de saisie propre
   EN PLACE. Remplace l'ancien bouton loin à droite + son popup. */
.kanban-col-add {
  flex: 0 0 auto; align-self: flex-start; margin-top: 2px;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 15px; border-radius: var(--r-pill);
  border: 1.5px dashed var(--hairline);
  color: var(--muted); background: transparent; cursor: pointer;
  white-space: nowrap; font-size: 14px; font-weight: 500; line-height: 1;
  user-select: none;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.kanban-col-add:hover { border-color: var(--ink); color: var(--ink); }
.kanban-col-add-plus { font-size: 16px; line-height: 1; }
/* En cours de saisie · même gabarit, bord plein + champ avec placeholder. */
.kanban-col-add.editing {
  border-style: solid; border-color: var(--ink);
  background: var(--canvas); color: var(--ink); cursor: default;
}
.kanban-col-add .col-add-input { outline: none; min-width: 120px; cursor: text; }
.kanban-col-add .col-add-input:empty::before { content: attr(data-placeholder); color: var(--muted-soft); }

/* Séparateur DANS le groupe de pastilles · marque la frontière entre les étapes
   de travail (Leads/Projets/Production) et les archives (Terminé/Annulés).
   Rendu seulement s'il y a des pastilles des deux côtés (voir topbarHTML). */
.top-tabs-sep {
  flex: 0 0 auto; width: 1px; align-self: stretch;
  margin: 4px 6px; background: var(--hairline);
}

/* Accueil · HORS du groupe de pastilles. Le tableau de bord n'est pas une étape
   du pipeline · il ne partage pas leur groupe visuel. */
.topbar-home {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--r-full);
  color: var(--body); background: var(--hairline);
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}
.topbar-home svg { width: 18px; height: 18px; }
.topbar-home:hover { background: var(--muted-soft); color: var(--ink); }
.topbar-home.active { background: var(--ink); color: var(--canvas); }

/* ===== Toggle de vue (carte / liste) · COMPOSANT PARTAGÉ =====
   Une seule source de vérité · utilisé sur Leads, Projets et tous les
   stages. Avant : recopié (et divergent) dans 5 fichiers CSS de page. */
.view-toggle {
  display: inline-flex; align-items: stretch; gap: 2px;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  padding: 4px;
  height: 47px;
  flex-shrink: 0;
}
.view-btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; cursor: pointer;
  padding: 0 14px;
  border-radius: var(--r-pill);
  color: var(--muted);
  font-family: inherit;
  transition: background 0.15s, color 0.15s;
}
.view-btn svg { width: 14px; height: 14px; pointer-events: none; }
.view-btn:hover:not(.active) { color: var(--ink); }
.view-btn.active { background: var(--primary); color: var(--on-primary); }

/* En-tête de page partagé (look démo) · fil d'Ariane + gros titre.
   Frère de .content (pas dedans) · padding propre constant pour aligner
   identiquement sur toutes les pages. */
.page-head { padding: var(--space-lg) var(--space-xl) var(--space-base); }
.page-head .breadcrumb {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--muted); margin-bottom: 8px;
}
.page-head .breadcrumb svg { width: 14px; height: 14px; }
.page-head .crumb { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); text-decoration: none; transition: color 0.15s; }
.page-head .crumb:hover { color: var(--ink); }
.page-head .crumb-current { color: var(--ink); font-weight: 500; }
.page-head .bc-sep { opacity: 0.55; }
.page-head h1 {
  font-size: var(--text-h1); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-display);
  line-height: 1.1; color: var(--ink); margin: 0;
}
.page-head .sub { font-size: var(--text-body); color: var(--muted); margin-top: 6px; }

/* ===== RETOUR · composant partagé (un seul endroit) =====
   Meme bouton de retour PARTOUT (Punch + Inventaire, seul ou combine) :
   un rond ‹, optionnellement suivi d'un titre dans un .panel-head. */
.nav-back {
  width: 40px; height: 40px; flex-shrink: 0;
  border-radius: var(--r-full);
  background: var(--surface-soft); border: 1px solid var(--hairline);
  color: var(--ink);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
  align-self: flex-start;
  transition: background 0.15s, transform 0.08s;
}
.nav-back:hover { background: var(--surface-strong); }
.nav-back:active { transform: scale(0.94); }
.nav-back svg { width: 20px; height: 20px; }
.panel-head {
  display: flex; align-items: center; gap: var(--space-sm);
  margin: var(--space-sm) 0 var(--space-base);
}
.panel-title {
  font-family: var(--font-display);
  font-size: 22px; font-weight: var(--weight-regular);
  letter-spacing: -0.4px; color: var(--ink);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar-breadcrumb { font-size: 13px; color: var(--muted); }
.topbar-breadcrumb strong { color: var(--ink); font-weight: 600; }
.topbar-left { display: flex; align-items: center; gap: var(--space-base); }
/* Zone des onglets · la nav des tableaux ET le « … » des tableaux cachés, EN
   LIGNE. Introduite au refactor de la barre (isolée pour se redessiner en direct)
   sans sa règle flex : le conteneur restait en `block`, donc le « … » tombait
   SOUS la barre dès qu'un tableau était caché. Flex = nav et « … » côte à côte,
   comme avant le wrapper. */
.topbar-boards { display: flex; align-items: center; gap: var(--space-base); }
.topbar-right { display: flex; align-items: center; gap: var(--space-sm); }

/* Icon-only buttons (sidebar toggle, theme toggle) */
.topbar-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  border-radius: var(--r-sm);
  transition: background 0.15s, color 0.15s;
  padding: 0;
}
.topbar-icon-btn:hover { background: var(--surface-strong); color: var(--ink); }
.topbar-icon-btn svg { width: 18px; height: 18px; }

/* Theme toggle · switch pilule (lune en clair, soleil en sombre).
   "On" (sombre) se remplit avec l'encre · notre accent monochrome. */
.theme-switch {
  position: relative;
  width: 52px; height: 28px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  background: var(--surface-strong);
  border: 1px solid var(--hairline);
  cursor: pointer;
  padding: 0;
  transition: background 0.2s, border-color 0.2s;
}
.theme-switch-knob {
  position: absolute;
  top: 2px; left: 2px;
  width: 22px; height: 22px;
  border-radius: var(--r-full);
  background: var(--canvas);
  color: var(--body);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 2px rgba(16,24,40,0.18);
  transition: transform 0.2s ease;
}
.theme-switch-knob svg { width: 13px; height: 13px; }
.theme-switch .theme-icon-dark { display: none; }
.theme-switch .theme-icon-light { display: inline-flex; }
[data-theme="dark"] .theme-switch { background: var(--ink); border-color: var(--ink); }
[data-theme="dark"] .theme-switch-knob { transform: translateX(24px); }
[data-theme="dark"] .theme-switch .theme-icon-light { display: none; }
[data-theme="dark"] .theme-switch .theme-icon-dark { display: inline-flex; }

/* ===== Cloche de notifications ===== */
.notif-wrap {
  position: relative;
}
.notif-badge {
  position: absolute;
  top: 2px; right: 2px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  background: var(--semantic-down);
  color: #fff;
  border-radius: var(--r-full);
  font-family: var(--font-mono);
  font-size: var(--text-caption); font-weight: var(--weight-semibold);
  line-height: 16px;
  text-align: center;
  pointer-events: none;
  box-shadow: 0 0 0 2px var(--canvas);
}
[data-theme="dark"] .notif-badge { box-shadow: 0 0 0 2px var(--canvas); }

.notif-panel {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 380px; max-width: 92vw;
  max-height: 70vh;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  box-shadow: 0 10px 40px rgba(0,0,0,0.12);
  z-index: 200;
  overflow: hidden;
  flex-direction: column;
}
.notif-panel.open { display: flex; }
/* Sur mobile : panel sort en plein ecran (avec marges) au lieu d'etre ancre
   au coin droit de la cloche · evite que ca deborde a gauche. */
@media (max-width: 640px) {
  .notif-panel {
    position: fixed;
    top: 64px;
    right: 12px;
    left: 12px;
    width: auto;
    max-width: none;
    max-height: 75vh;
  }
}

.notif-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--hairline-soft);
}
.notif-panel-title {
  font-size: 13px; font-weight: 600;
  color: var(--ink);
}
.notif-mark-all {
  background: transparent; border: none;
  color: var(--primary);
  font-size: 11px; font-weight: 600;
  cursor: pointer;
  padding: 0;
}
.notif-mark-all:hover { text-decoration: underline; }
.notif-settings-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  color: var(--muted);
  text-decoration: none;
  border-radius: var(--r-sm);
  transition: background 0.12s, color 0.12s;
}
.notif-settings-link:hover {
  background: var(--surface-soft);
  color: var(--ink);
}
.notif-settings-link svg { width: 14px; height: 14px; }

.notif-panel-list {
  flex: 1; min-height: 0;
  overflow-y: auto;
}
.notif-item {
  display: flex; gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--hairline-soft);
  text-decoration: none;
  color: inherit;
  transition: background 0.1s;
  position: relative;
}
.notif-item:last-child { border-bottom: none; }
.notif-item:hover { background: var(--surface-soft); }
.notif-item.unread { background: var(--primary-soft); }
.notif-item.unread:hover { background: color-mix(in srgb, var(--primary-soft) 70%, var(--primary) 5%); }
.notif-item-delete {
  position: absolute;
  top: 8px; right: 8px;
  background: transparent; border: none; cursor: pointer;
  width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm);
  color: var(--muted-soft);
  opacity: 0;
  transition: opacity 0.15s, background 0.15s, color 0.15s;
}
.notif-item:hover .notif-item-delete { opacity: 1; }
.notif-item-delete:hover { background: var(--surface-strong); color: var(--semantic-down); }
.notif-item-delete svg { width: 14px; height: 14px; display: block; }

.notif-dot {
  width: 8px; height: 8px;
  border-radius: var(--r-full);
  background: transparent;
  margin-top: 6px;
  flex-shrink: 0;
}
.notif-item.unread .notif-dot {
  background: var(--primary);
}

.notif-body {
  flex: 1; min-width: 0;
}
.notif-title {
  font-size: 13px; font-weight: 600;
  color: var(--ink);
  margin-bottom: 2px;
  line-height: 1.35;
}
.notif-snippet {
  font-size: 12px; color: var(--body);
  line-height: 1.45;
  margin-bottom: 2px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.notif-context {
  font-size: 11px; color: var(--muted);
  font-family: var(--font-mono);
  margin-bottom: 2px;
}
.notif-time {
  font-size: var(--text-caption); color: var(--muted);
  font-family: var(--font-mono);
}

.notif-panel-empty {
  padding: 32px 16px;
  text-align: center;
  display: none;
}
.notif-panel-list:empty + .notif-panel-empty { display: block; }

/* ===== Toast popup quand une notif arrive en live ===== */
.notif-toast {
  position: fixed;
  top: 80px; right: 24px;
  width: 360px; max-width: calc(100vw - 48px);
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--primary);
  border-radius: var(--r-md);
  box-shadow: 0 10px 40px rgba(0,0,0,0.15);
  padding: 14px 14px 14px 16px;
  display: flex; gap: 12px; align-items: flex-start;
  text-decoration: none;
  color: inherit;
  z-index: 999;
  opacity: 0;
  transform: translateX(20px);
  transition: opacity 0.25s, transform 0.25s;
  cursor: pointer;
}
.notif-toast.show { opacity: 1; transform: translateX(0); }
.notif-toast:hover { border-color: var(--primary); }

.notif-toast-icon {
  width: 32px; height: 32px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--primary-soft);
  border-radius: var(--r-full);
  color: var(--primary);
}
.notif-toast-icon svg { width: 16px; height: 16px; }

.notif-toast-body { flex: 1; min-width: 0; }
.notif-toast-title {
  font-size: 13px; font-weight: 600;
  color: var(--ink);
  line-height: 1.35;
  margin-bottom: 2px;
}
.notif-toast-snippet {
  font-size: 12px; color: var(--body);
  line-height: 1.45;
  margin-bottom: 2px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.notif-toast-context {
  font-size: 11px; color: var(--muted);
  font-family: var(--font-mono);
}

.notif-toast-close {
  background: transparent; border: none;
  color: var(--muted);
  width: 22px; height: 22px;
  border-radius: var(--r-full);
  cursor: pointer;
  font-size: 16px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background 0.12s, color 0.12s;
}
.notif-toast-close:hover {
  background: var(--surface-soft);
  color: var(--ink);
}

/* Empile plusieurs toasts si plusieurs arrivent en meme temps */
.notif-toast + .notif-toast { top: calc(80px + 100px); }
.notif-toast + .notif-toast + .notif-toast { top: calc(80px + 200px); }

/* ===== Boutons (pill geometry) ===== */
.btn,
.topbar-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 40px;
  padding: 0 var(--space-md);
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-size: var(--text-body); font-weight: var(--weight-semibold); letter-spacing: 0;
  line-height: 1.15;
  cursor: pointer;
  border: 1px solid transparent;
  background: var(--surface-strong);
  color: var(--ink);
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  white-space: nowrap;
}
.btn:hover,
.topbar-btn:hover { background: var(--hairline); }
.btn.primary,
.topbar-btn.primary,
.btn-primary {
  background: var(--primary);
  color: var(--on-primary);
  border-color: var(--primary);
}
.btn.primary:hover,
.topbar-btn.primary:hover,
.btn-primary:hover { background: var(--primary-active); border-color: var(--primary-active); }
.btn.outline-dark,
.btn-outline-on-dark {
  background: transparent;
  color: var(--on-dark);
  border: 1px solid rgba(255,255,255,0.4);
}
.btn-tertiary {
  background: transparent;
  color: var(--primary);
  height: auto; padding: 0;
}

/* Topbar btn variant compacte (héritage) */
.topbar-btn.sm { height: 32px; font-size: 13px; padding: 0 14px; }

.content { padding: var(--space-xl); flex: 1; min-width: 0; }

/* ===== Composants partagés ===== */

/* Feature card (carte produit/outil) */
.feature-card {
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  padding: var(--space-xl);
  transition: box-shadow 0.15s, transform 0.15s;
  display: block;
}
.feature-card:hover {
  box-shadow: var(--shadow-hover);
  transform: translateY(-1px);
}

/* Badge pill (étiquettes section / status) */
.badge-pill {
  display: inline-block;
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.04em;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--surface-strong);
  color: var(--ink);
  text-transform: uppercase;
}
.badge-pill.up    { color: var(--semantic-up);   background: var(--surface-strong); }
.badge-pill.down  { color: var(--semantic-down); background: var(--surface-strong); }

/* Hairline divider */
.hairline { height: 1px; background: var(--hairline); border: 0; }

/* Mono utility (chiffres tabulaires) */
.mono, .num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ===== UTILITIES ===== */
.internal-only {}

/* ===== Side drawer (panneau latéral droit) =====
   Réutilisable: voir DESIGN.md. Utilisé par le modal Taux du Cost Sheet.
*/
.drawer-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 200;
  display: none; opacity: 0;
  transition: opacity 0.2s ease;
}
.drawer-overlay.open { display: block; opacity: 1; }
.drawer-panel {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: clamp(640px, 50vw, 820px);
  background: var(--canvas);
  border-left: 1px solid var(--hairline);
  box-shadow: -20px 0 60px rgba(0,0,0,0.35);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.25s ease;
}
.drawer-overlay.open .drawer-panel { transform: translateX(0); }
@media (max-width: 768px) {
  .drawer-panel { width: 100vw; }
}
.drawer-head {
  padding: 18px 24px;
  border-bottom: 1px solid var(--hairline);
  display: flex; align-items: center; justify-content: space-between;
  flex-shrink: 0;
}
.drawer-head-text h2 {
  font-size: var(--text-h2); font-weight: var(--weight-semibold); color: var(--ink);
  letter-spacing: -0.01em; margin: 0;
}
.drawer-head-text .drawer-sub {
  font-size: 13px; color: var(--muted); margin-top: 2px;
}
.drawer-close {
  background: none; border: none;
  font-size: 22px; color: var(--muted);
  cursor: pointer; padding: 4px 10px; line-height: 1;
}
.drawer-close:hover { color: var(--ink); }
.drawer-body {
  padding: 22px 24px;
  overflow-y: auto;
  flex: 1 1 auto;
}
.drawer-foot {
  padding: 14px 24px;
  border-top: 1px solid var(--hairline);
  display: flex; justify-content: flex-end; gap: 10px;
  background: var(--surface-soft);
  flex-shrink: 0;
}
.drawer-section { margin-bottom: 22px; }
.drawer-section:last-child { margin-bottom: 0; }
.drawer-section-title {
  font-size: 11px; font-weight: var(--weight-semibold);
  color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.08em;
  margin-bottom: 10px;
}
.drawer-cols-2 {
  display: grid; grid-template-columns: 1fr 1fr; gap: 22px;
}
@media (max-width: 720px) {
  .drawer-cols-2 { grid-template-columns: 1fr; gap: 16px; }
}

/* ============================================================
   Sidebar collapse · set data-sidebar="hidden" sur <body> (desktop)
   ou data-sidebar="open" sur <body> (mobile, overlay).
   ============================================================ */
.sidebar { transition: transform 0.2s ease; }
.main    { transition: margin-left 0.2s ease; }

/* Desktop: sidebar visible par défaut, masquée si data-sidebar="hidden" */
body[data-sidebar="hidden"] .sidebar { transform: translateX(-100%); }
body[data-sidebar="hidden"] .main    { margin-left: 0; }

@media (max-width: 768px) {
  /* Mobile: sidebar masquée par défaut, visible si data-sidebar="open" */
  .sidebar { transform: translateX(-100%); }
  .main    { margin-left: 0; }
  body[data-sidebar="open"] .sidebar { transform: translateX(0); z-index: 200; box-shadow: 4px 0 24px rgba(0,0,0,0.3); }
  .content { padding: var(--space-lg); }
  h1 { font-size: 36px; letter-spacing: -0.5px; }
  h2 { font-size: 28px; }

  /* ===== Pages inventaire en mobile · les wrappers mountLayout n'ajoutent
           PAS de padding ni de chrome (topbar etc.). La page gere son
           layout interne. S'applique en standalone PWA ET en browser ·
           pas dependant de @media display-mode (qui peut ne pas matcher
           si le PWA a ete installe avec un ancien scope). ===== */
  body.has-inv-mobile-nav .topbar { display: none !important; }
  body.has-inv-mobile-nav .content {
    padding-top: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    /* padding-bottom: 96px gere par inventaire-nav.js · pas touche */
  }
}

/* ============================================================
   PWA standalone · adapte le layout quand l'app est installée
   (Punch PWA notamment · l'user a quitté son scope /punch/ pour
   naviguer ailleurs, on veut un feel app pur sans sidebar/topbar).

   Détection · @media (display-mode: standalone) match si l'user
   a lancé via l'icône du home screen (iOS/Android/Chrome desktop).
   Si ouvert dans un onglet de navigateur · ne match pas, layout
   normal préservé.

   On cache la sidebar + topbar et on affiche un bouton "Punch"
   en haut à gauche pour revenir au shell principal du PWA.
   ============================================================ */
.pwa-back-to-punch { display: none; }

@media (display-mode: standalone) {
  .sidebar { display: none !important; }
  .topbar  { display: none !important; }
  .main    { margin-left: 0 !important; }

  /* ===== Pages WITHOUT leur propre mobile-nav (ex. /cost/, /projets/,
           /employes/) · floating pill "← Punch" en haut a gauche pour
           revenir au punch. .content garde un padding-top qui reserve
           la place sous le pill. ===== */
  body:not(.has-inv-mobile-nav) .content {
    padding-top: calc(var(--space-lg) + 56px + env(safe-area-inset-top, 0)) !important;
  }
  body:not(.has-inv-mobile-nav) .pwa-back-to-punch {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    position: fixed;
    top: calc(var(--space-sm) + env(safe-area-inset-top, 0));
    left: calc(var(--space-sm) + env(safe-area-inset-left, 0));
    z-index: 300;
    height: 40px;
    padding: 0 14px 0 10px;
    background: var(--ink);
    color: var(--canvas);
    border-radius: var(--r-pill);
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
    transition: transform 0.08s, background 0.15s;
  }
  body:not(.has-inv-mobile-nav) .pwa-back-to-punch:active {
    transform: scale(0.96);
  }
  body:not(.has-inv-mobile-nav) .pwa-back-to-punch svg {
    width: 16px; height: 16px;
    flex-shrink: 0;
  }

  /* ===== Pages AVEC leur propre mobile-nav (inventaire) · le pill
           flottant est cache · la page fournit son propre pill inline
           dans son header (ex. .accueil-to-punch dans le greeting).
           Evite le double element + le floating pill qui prend de la
           place verticale au-dessus du header de la page. ===== */
  body.has-inv-mobile-nav .pwa-back-to-punch {
    display: none !important;
  }

  /* .content devient transparent sur l'inventaire · le wrapper .inv-page
     (cree par inventaire-nav.js) fournit deja le padding lateral. Sans
     ce reset, on doublait le padding (24px .content + 24px .inv-page =
     48px sides) · le contenu etait pogne au milieu de l'ecran au lieu
     d'aller pleine largeur comme sur le punch. */
  body.has-inv-mobile-nav .content {
    padding-top: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    /* padding-bottom: 96px conserve · gere par inventaire-nav.js pour
       reserver la place de la floating bottom-nav. */
  }
}
