/* ==========================================================================
   Stackly — Shell applicatif
   Barre laterale, rail reduit, zone de contenu, notifications.
   Charge APRES style.css : ce fichier gagne sur l'ancien shell.
   Ne style que le chassis. Le contenu des pages reste a style.css tant que
   son module n'a pas ete repris.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Reprise des jetons ecrases par style.css
   --------------------------------------------------------------------------
   style.css est charge APRES tokens.css et redeclare --success, --warning et
   --danger avec l'ancienne palette (#0ED455, #f97316, #ef4444). Les trois
   jetons semantiques etaient donc perdus partout dans l'application : c'est
   la cause des couleurs legacy qui subsistaient sur les boutons et les
   pastilles. On les repose ici, shell.css etant charge apres style.css.

   A supprimer le jour ou style.css disparaitra.
   -------------------------------------------------------------------------- */

:root {
  --success: #2F8558;
  --warning: #BE8724;
  --danger:  #C0392B;
}

/* ---------- Base ---------------------------------------------------------- */

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--text-body);
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, .app-title {
  font-family: var(--font-display);
  letter-spacing: var(--track-title);
  color: var(--ink);
}

/* Tout chiffre s'aligne. Montants, quantites, dates, references. */
.tn,
.amount,
td.amount,
.stat-value,
.sidebar-badge {
  font-variant-numeric: tabular-nums;
}

/* La fleche du bouton de pliage pivote d'un demi-tour. Elle etait auparavant
   deux SVG permutes par JavaScript — voir le commentaire du gabarit. */
.sidebar-toggle-icon {
  transition: transform var(--duration) var(--ease);
}

.sidebar-pre-collapsed .sidebar-toggle-icon,
.sidebar.collapsed .sidebar-toggle-icon {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .sidebar-toggle-icon { transition: none; }
}

/* ---------- Barre laterale ------------------------------------------------ */

.sidebar {
  width: var(--sidebar-width);
  background: var(--surface);
  border-right: 1px solid var(--border);
  box-shadow: none;
  padding: 0 var(--space-3);
  display: flex;
  flex-direction: column;
  transition: width var(--duration) var(--ease);
}

.sidebar-pre-collapsed .sidebar,
.sidebar.collapsed {
  width: var(--sidebar-rail);
  padding: 0 var(--space-4);
}

body.has-sidebar .main-content,
.main-content {
  margin-left: var(--sidebar-width);
  background: var(--canvas);
  transition: margin-left var(--duration) var(--ease);
}

.sidebar-pre-collapsed .main-content,
.sidebar.collapsed ~ .main-content {
  margin-left: var(--sidebar-rail);
}

/* --- carte flottante arrondie, reprise de l'ancienne barre -------------------
   L'ancienne version ne detachait la barre qu'une fois repliee, ce qui donnait
   deux formes pour un meme meuble. Elle est detachee dans les deux etats : le
   contenu interieur ne change pas, seule l'enveloppe le fait. Reservee au
   bureau — sous 992 px la barre redevient un tiroir plein ecran qui glisse.
   --------------------------------------------------------------------------- */

@media (min-width: 993px) {
  .sidebar {
    top: var(--sidebar-gap);
    left: var(--sidebar-gap);
    height: calc(100vh - (var(--sidebar-gap) * 2));
    border: 1px solid var(--border);
    border-radius: var(--radius-sidebar);
    box-shadow: var(--shadow-2);
    /* Le bouton de repli chevauche le bord : rien ne doit le rogner. */
    overflow: visible;
    transition: width var(--duration) var(--ease);
  }

  body.has-sidebar .main-content,
  .main-content {
    margin-left: calc(var(--sidebar-width) + (var(--sidebar-gap) * 2));
  }

  .sidebar-pre-collapsed .main-content,
  .sidebar.collapsed ~ .main-content {
    margin-left: calc(var(--sidebar-rail) + (var(--sidebar-gap) * 2));
  }

  /* style.css detache deja la barre une fois repliee, mais avec ses propres
     valeurs (95vh, rayon 16, ombre noire) et une specificite superieure a la
     regle ci-dessus. On la realigne sur les jetons pour que les deux etats
     aient exactement la meme enveloppe. */
  .sidebar-pre-collapsed .sidebar,
  .sidebar.collapsed {
    top: var(--sidebar-gap);
    left: var(--sidebar-gap);
    height: calc(100vh - (var(--sidebar-gap) * 2));
    border: 1px solid var(--border);
    border-radius: var(--radius-sidebar);
    box-shadow: var(--shadow-2);
  }
}

.content-wrapper {
  padding: var(--space-6) var(--space-8);
  max-width: none;
}

/* --- en-tete : marque a sept couleurs --- */

.sidebar-header {
  height: var(--topbar-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--space-3);
  border-bottom: none;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  min-width: 0;
}

.sidebar-brand img { display: none; }

.brand-mark {
  display: grid;
  grid-template-columns: repeat(3, 6px);
  gap: 2px;
  flex-shrink: 0;
}

.brand-mark i {
  width: 6px;
  height: 6px;
  border-radius: 1.5px;
  display: block;
  background: var(--border);
}

.brand-mark i:nth-child(1) { background: var(--mod-documents); }
.brand-mark i:nth-child(2) { background: var(--mod-stock); }
.brand-mark i:nth-child(3) { background: var(--mod-crm); }
.brand-mark i:nth-child(4) { background: var(--mod-planning); }
.brand-mark i:nth-child(5) { background: var(--mod-finance); }
.brand-mark i:nth-child(6) { background: var(--mod-expenses); }
.brand-mark i:nth-child(7) { background: var(--mod-assistant); }

.sidebar-brand-text {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: var(--weight-bold);
  letter-spacing: -0.035em;
  color: var(--ink);
  white-space: nowrap;
}

/* --- navigation --- */

.sidebar-nav {
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
  overflow-x: hidden;
}

.sidebar-section {
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: var(--space-5) var(--space-3) var(--space-2);
  white-space: nowrap;
}

.sidebar-pre-collapsed .sidebar-section,
.sidebar.collapsed .sidebar-section {
  height: 1px;
  padding: var(--space-4) 0 0;
  overflow: hidden;
  color: transparent;
  border-top: 1px solid var(--border-subtle);
  margin: var(--space-2) var(--space-1) 0;
}

.sidebar-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--control-md);
  padding: 0 var(--space-3);
  border-radius: var(--radius-button);
  font-size: 14.5px;
  font-weight: var(--weight-medium);
  color: var(--ink-secondary);
  text-decoration: none;
  position: relative;
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}

/* `:not(.sidebar-badge)` : sans lui, la pastille de notification — elle aussi
   un span enfant direct — heritait de `flex-grow: 1` et s'etirait a 57px de
   large pour un seul chiffre. Elle cessait d'etre ronde. */
.sidebar-link > span:not(.sidebar-badge) {
  flex-grow: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-link i[class^="bi-"],
.sidebar-link i[class*=" bi-"] {
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
  color: var(--ink-muted);
  transition: color var(--duration-fast) var(--ease);
}

.sidebar-link:hover {
  background: rgba(22, 21, 15, 0.04);
  color: var(--ink);
  transform: none;
}

.sidebar-link.active {
  background: var(--nav-tint, rgba(22, 21, 15, 0.055));
  color: var(--nav-ink, var(--ink));
  font-weight: var(--weight-semibold);
  box-shadow: none;
}

.sidebar-link.active i[class^="bi-"],
.sidebar-link.active i[class*=" bi-"] {
  color: var(--nav-color, var(--ink));
}

/* La teinte du module colore son icone, active ou non. C'est le reperage. */
.sidebar-link[data-module] i[class^="bi-"],
.sidebar-link[data-module] i[class*=" bi-"] { color: var(--nav-color); }

.sidebar-link[data-module="documents"] { --nav-color: var(--mod-documents); --nav-ink: var(--mod-documents-ink); --nav-tint: var(--mod-documents-tint); }
.sidebar-link[data-module="stock"]     { --nav-color: var(--mod-stock);     --nav-ink: var(--mod-stock-ink);     --nav-tint: var(--mod-stock-tint); }
.sidebar-link[data-module="crm"]       { --nav-color: var(--mod-crm);       --nav-ink: var(--mod-crm-ink);       --nav-tint: var(--mod-crm-tint); }
.sidebar-link[data-module="planning"]  { --nav-color: var(--mod-planning);  --nav-ink: var(--mod-planning-ink);  --nav-tint: var(--mod-planning-tint); }
.sidebar-link[data-module="finance"]   { --nav-color: var(--mod-finance);   --nav-ink: var(--mod-finance-ink);   --nav-tint: var(--mod-finance-tint); }
.sidebar-link[data-module="expenses"]  { --nav-color: var(--mod-expenses);  --nav-ink: var(--mod-expenses-ink);  --nav-tint: var(--mod-expenses-tint); }
.sidebar-link[data-module="assistant"] { --nav-color: var(--mod-assistant); --nav-ink: var(--mod-assistant-ink); --nav-tint: var(--mod-assistant-tint); }

/* --- pastilles de la navigation --- */

.sidebar-link .badge,
.sidebar-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 19px;
  height: 19px;
  padding: 0 6px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: var(--weight-bold);
  line-height: 1;
  flex-shrink: 0;
  position: static;
  background: var(--warning-tint);
  color: var(--warning-ink);
}

.sidebar-link .badge.bg-success,
.sidebar-badge--info {
  background: var(--info-tint);
  color: var(--info-ink);
}

.sidebar-badge--danger {
  background: var(--danger-tint);
  color: var(--danger-ink);
}

.trial-badge {
  font-size: 10.5px;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
  padding: 3px 7px;
  border-radius: var(--radius-chip);
  background: var(--warning-tint);
  color: var(--warning-ink);
  white-space: nowrap;
  flex-shrink: 0;
}

/* --- pied de barre laterale --- */

.sidebar-footer {
  margin-top: auto;
  padding: var(--space-4) 0;
  border-top: none;
}

.sidebar-account {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-muted);
  padding: 13px 14px;
}

.sidebar-account-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.sidebar-avatar {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--ink);
  color: var(--ink-on-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  flex-shrink: 0;
}

.sidebar-user-info { min-width: 0; flex-grow: 1; }

.sidebar-user-name {
  font-size: 13.5px;
  font-weight: var(--weight-semibold);
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-user-plan {
  font-size: 11.5px;
  color: var(--ink-muted);
  white-space: nowrap;
}

.sidebar-sync {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: var(--space-3);
  padding-top: 11px;
  border-top: 1px solid var(--border-subtle);
  font-size: var(--text-xs);
  color: var(--ink-secondary);
}

.sidebar-sync .status-indicator { width: 6px; height: 6px; margin: 0; }

/*  L'ETAT REPLIE EST UNE PREFERENCE DE BUREAU, ET SEULEMENT DE BUREAU.
 *
 *  Il est memorise dans `localStorage` et repose sur le body des la premiere
 *  peinture. Or ce meme reglage suivait l'utilisateur sur telephone, ou la
 *  barre n'est plus une colonne qu'on retrecit mais un TIROIR qui s'ouvre en
 *  entier : on obtenait un panneau de 280 px de large ne montrant que des
 *  icones centrees, sans un seul libelle.
 *
 *  D'ou le palier. Sous 992 px ces regles ne s'appliquent pas du tout, plutot
 *  que de s'appliquer puis d'etre defaites une par une — ce qui laisse
 *  toujours une regle oubliee derriere.  */
@media (min-width: 993px) {
  .sidebar-pre-collapsed .sidebar-account,
  .sidebar.collapsed .sidebar-account {
    border: none;
    background: transparent;
    padding: 0;
    display: flex;
    justify-content: center;
  }

  .sidebar-pre-collapsed .sidebar-user-info,
  .sidebar-pre-collapsed .sidebar-brand-text,
  .sidebar-pre-collapsed .sidebar-link > span,
  .sidebar-pre-collapsed .trial-badge,
  .sidebar-pre-collapsed .sidebar-sync,
  .sidebar.collapsed .sidebar-user-info,
  .sidebar.collapsed .sidebar-brand-text,
  .sidebar.collapsed .sidebar-link > span,
  .sidebar.collapsed .trial-badge,
  .sidebar.collapsed .sidebar-sync {
    display: none;
  }

  .sidebar-pre-collapsed .sidebar-link,
  .sidebar.collapsed .sidebar-link {
    justify-content: center;
    padding: 0;
    width: var(--touch-target);
    height: var(--touch-target);
    border-radius: 11px;
  }
}

/* --- bouton de repli --- */

/* Pastille ronde a cheval sur le bord de la barre, comme l'ancienne version.
   Elle sort de l'en-tete : `justify-content: space-between` laisse alors la
   marque seule a gauche, ce qui est le rendu voulu. */
.sidebar-toggle-btn {
  width: 26px;
  height: 26px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink-secondary);
  box-shadow: var(--shadow-2);
  transition: background var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease);
}

.sidebar-toggle-btn:hover {
  background: var(--surface-sunken);
  color: var(--ink);
  box-shadow: var(--shadow-3);
  transform: scale(1.06);
}

.sidebar-toggle-btn:active { transform: scale(0.94); }

.sidebar-toggle-btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring), var(--shadow-2);
}

.sidebar-toggle-btn svg { width: 15px; height: 15px; }

/* ---------- Mode hors ligne ----------------------------------------------- */

.offline-toggle-section {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-3) 0;
  font-size: var(--text-sm);
  color: var(--ink-secondary);
}

.offline-toggle-label { display: flex; align-items: center; gap: var(--space-2); }

.offline-toggle-slider {
  background: #E9E4DB;
  border-radius: var(--radius-pill);
}

.offline-toggle input:checked + .offline-toggle-slider { background: var(--accent); }

.status-indicator {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
}

.status-indicator.online  { background: var(--success); }
.status-indicator.offline { background: var(--ink-muted); }

/* ---------- Notifications -------------------------------------------------- */

/*  Les regles de la fenetre de message vivaient ici en redefinition partielle
    de shell-legacy.css. Les deux blocs sont reunis dans components.css.  */


/* ---------- Mobile --------------------------------------------------------- */

.mobile-menu-toggle {
  width: var(--touch-target);
  height: var(--touch-target);
  border-radius: var(--radius-button);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-1);
}

.mobile-overlay { background: rgba(22, 21, 15, 0.38); }

@media (max-width: 992px) {
  .main-content,
  body.has-sidebar .main-content,
  .sidebar-pre-collapsed .main-content { margin-left: 0; }

  .content-wrapper { padding: var(--space-5) var(--gutter-page); }

  /*  SUR TELEPHONE, C'EST UN RAIL.
   *
   *  Un tiroir de 280 px mange 72 % d'un ecran de 390 : il ne laisse qu'un
   *  bandeau de contenu derriere lui, ni ouvert ni ferme. Avant la refonte
   *  l'application avait un rail de 70 px — 18 % — et c'etait le bon geste.
   *
   *  On y revient, mais habille comme le reste : la largeur est celle du
   *  `--sidebar-rail` du bureau, les pictogrammes sont des carres tactiles de
   *  44 px, et les titres de section deviennent de simples filets, exactement
   *  comme dans l'etat replie. Un seul langage, deux contextes.
   *
   *  Sa largeur ET son glissement vivent ici. Ils etaient repartis entre deux
   *  feuilles, avec des valeurs concurrentes (-100 %, -220px, -60px) dont
   *  celle qui l'emportait dependait de l'ordre de chargement : une barre
   *  repliee sur ordinateur laissait 220 px d'elle-meme en travers de l'ecran
   *  du telephone.  */
  .sidebar,
  .sidebar.collapsed,
  .sidebar-pre-collapsed .sidebar {
    width: var(--sidebar-rail);
    padding: 0 var(--space-3);
    box-shadow: var(--shadow-3);
    transform: translateX(-100%);
  }

  .sidebar.mobile-open { transform: translateX(0); }

  /*  Ce qui n'a pas sa place dans 76 px de large. */
  .sidebar .sidebar-user-info,
  .sidebar .sidebar-brand-text,
  .sidebar .trial-badge,
  .sidebar .sidebar-sync { display: none; }

  /*  LE LIBELLE QUITTE L'OEIL, PAS LE DOCUMENT.
   *
   *  `display: none` le retirerait de l'arbre d'accessibilite : le lien
   *  n'aurait plus alors AUCUN nom, juste un pictogramme. Il est donc
   *  seulement rendu invisible.  */
  .sidebar .sidebar-link > span,
  .sidebar .offline-toggle-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  .sidebar .sidebar-link {
    justify-content: center;
    padding: 0;
    width: var(--touch-target);
    height: var(--touch-target);
    border-radius: 11px;
  }

  /*  Le titre de section devient un filet : il separe sans prendre de place. */
  .sidebar .sidebar-section {
    height: 1px;
    padding: var(--space-4) 0 0;
    overflow: hidden;
    color: transparent;
    border-top: 1px solid var(--border-subtle);
    margin: var(--space-2) var(--space-1) 0;
  }

  .sidebar .sidebar-account {
    border: none;
    background: transparent;
    padding: 0;
    display: flex;
    justify-content: center;
  }

}

/* ---------- Pied de page public -------------------------------------------- */

footer .footer-text {
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

/* Bouton de synchronisation, dans le pied de barre laterale */
.sidebar-sync-btn {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink-secondary);
  border-radius: var(--radius-chip);
  padding: 4px 9px;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  font-family: inherit;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease);
}

.sidebar-sync-btn:hover { background: var(--surface-sunken); }
.sidebar-sync-btn i { font-size: 12px; }

/* Corrections d'heritage : l'ancien style.css imposait des capitales
   et une police display sur des elements qui n'en veulent pas. */
.sidebar-brand-text {
  text-transform: none;
  font-size: 21px;
}

.sidebar-sync-label {
  font-family: var(--font-ui);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0;
  text-transform: none;
  color: inherit;
}

.sidebar-sync [data-offline-manager-target="status"] {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-secondary);
  background: none;
  padding: 0;
  border-radius: 0;
}

/* Le bouton chevauche le bord droit de la barre, dans les deux etats. */
/* Le positionnement du bouton vit plus bas, avec `.sidebar-header` devant,
   pour passer les regles heritees. */

/* ==========================================================================
   Barre du haut
   Titre de page a gauche, outils globaux a droite. Collante.
   Ne s'affiche que si la page declare {% block page_title %}.
   ========================================================================== */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  min-height: var(--topbar-height);
  padding: var(--space-3) var(--space-8);
  background: var(--canvas);
  border-bottom: 1px solid var(--border);
}

.topbar-heading {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.topbar-icon {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  background: var(--accent-tint);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 19px;
  flex-shrink: 0;
}

.topbar-title {
  font-family: var(--font-display);
  font-size: var(--text-title-1);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-title);
  line-height: 1.15;
  color: var(--ink);
  margin: 0;
}

.topbar-subtitle {
  font-size: var(--text-sm);
  color: var(--ink-muted);
  margin: 2px 0 0;
}

.topbar-tools {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

.topbar-search {
  display: flex;
  align-items: center;
  gap: 9px;
  height: var(--control-md);
  width: 270px;
  padding: 0 13px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-button);
  background: var(--surface);
  color: var(--ink-faint);
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease);
}

.topbar-search:hover { border-color: var(--ink-muted); }
.topbar-search > span { flex-grow: 1; text-align: left; }
.topbar-search i { color: var(--ink-muted); font-size: 15px; }

.topbar-search kbd {
  font-family: inherit;
  font-size: 11px;
  font-weight: var(--weight-semibold);
  color: var(--ink-faint);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 2px 6px;
  background: none;
}

.topbar-icon-btn {
  position: relative;
  width: var(--control-md);
  height: var(--control-md);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-button);
  background: var(--surface);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  text-decoration: none;
  transition: background var(--duration-fast) var(--ease);
}

.topbar-icon-btn:hover { background: var(--surface-sunken); }

.topbar-dot {
  position: absolute;
  top: 8px;
  right: 9px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--danger);
  border: 1.5px solid var(--surface);
}

/* Bouton primaire du chassis. Encre, pas couleur de module :
   « Creer » n'appartient a aucun outil. */
.btn-primary-new {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--control-md);
  padding: 0 18px;
  border: none;
  border-radius: var(--radius-button);
  background: var(--ink);
  color: var(--ink-on-dark);
  font-family: inherit;
  font-size: 14px;
  font-weight: var(--weight-semibold);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease);
}

.btn-primary-new:hover { background: #2F2E26; color: var(--ink-on-dark); }
.btn-primary-new i { font-size: 14px; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 992px) {
  .topbar {
    padding: var(--space-3) var(--gutter-page);
    padding-left: 72px;          /* place pour le bouton menu */

    /*  LA BARRE DEBORDAIT HORIZONTALEMENT SUR TELEPHONE.
     *
     *  `.topbar` etait un `flex` sur une seule ligne, `.topbar-tools` portait
     *  `flex-shrink: 0`, et `{% block page_actions %}` y pose deux a quatre
     *  boutons selon la page — « Exporter », « Excel », « Importer »,
     *  « Ajouter » sur /stock. A 390 px, la rangee mesurait plus large que
     *  l'ecran : la page entiere defilait lateralement, et le dernier bouton
     *  sortait du cadre.
     *
     *  On laisse la rangee passer a la ligne plutot que de pousser. Le titre
     *  garde sa priorite ; les actions descendent dessous quand il le faut. */
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    row-gap: var(--space-2);
  }
  .topbar-heading { flex: 1 1 auto; min-width: 0; }
  .topbar-title {
    font-size: var(--text-title-1);
    /* Un titre long ne doit pas elargir la barre : il se coupe. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .topbar-search { display: none; }

  /*  Les actions peuvent retrecir et passer a la ligne ; elles ne poussent
   *  plus la barre au-dela de l'ecran. */
  .topbar-tools {
    flex: 0 1 auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    min-width: 0;
  }
}

/*  Sur un vrai telephone, les actions prennent leur propre ligne, pleine
 *  largeur : a 390 px, quatre boutons ne tiennent pas a cote d'un titre. */
@media (max-width: 560px) {
  .topbar { padding-left: 64px; }
  .topbar-tools {
    flex: 1 0 100%;
    justify-content: flex-start;
  }
}

/* ==========================================================================
   Corrections du chassis — retours d'usage
   ========================================================================== */

/* Pastille ronde a cheval sur le bord droit, comme l'ancienne barre. Le
   selecteur porte `.sidebar-header` pour passer devant les regles heritees de
   style.css, qui posent leurs propres couleurs en dur. */
.sidebar-header .sidebar-toggle-btn {
  width: 26px;
  height: 26px;
  padding: 0;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink-secondary);
  box-shadow: var(--shadow-2);
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease);
}

.sidebar-header .sidebar-toggle-btn:hover {
  background: var(--surface-sunken);
  color: var(--ink);
  box-shadow: var(--shadow-3);
  transform: scale(1.06);
}

.sidebar-header .sidebar-toggle-btn:active { transform: scale(0.94); }

.sidebar-header .sidebar-toggle-btn svg { width: 15px; height: 15px; }

@media (min-width: 993px) {
  .sidebar-header .sidebar-toggle-btn {
    position: absolute;
    right: -13px;
    top: 33px;
    z-index: 2;
  }
}

@media (max-width: 992px) {
  .sidebar-header .sidebar-toggle-btn { position: static; right: auto; top: auto; }
}

/* En rail, l'en-tete se recentre. Le bouton, lui, reste a cheval sur le bord :
   il n'est plus dans le flux, l'en-tete ne porte donc que la marque. */
.sidebar-pre-collapsed .sidebar-header,
.sidebar.collapsed .sidebar-header {
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2);
  height: auto;
  padding: var(--space-4) 0 var(--space-2);
}

/* Animation : plus longue et amortie. 180 ms donnait un a-coup. */
.sidebar,
.main-content,
body.has-sidebar .main-content {
  transition: width var(--duration-slow) cubic-bezier(0.32, 0.72, 0, 1),
              margin-left var(--duration-slow) cubic-bezier(0.32, 0.72, 0, 1),
              padding var(--duration-slow) cubic-bezier(0.32, 0.72, 0, 1);
}

/* Les libelles s'effacent avant que la largeur ne bouge, sinon ils sont
   compresses pendant la transition. */
.sidebar-brand-text,
.sidebar-link > span,
.sidebar-user-info,
.sidebar-sync,
.trial-badge {
  transition: opacity var(--duration-fast) var(--ease);
}

/* Pastilles : elles restent dans le flux du lien, jamais en absolu.
   L'ancien CSS les posait en absolu par selecteur d'identifiant, ce qui
   ecrasait l'icone du module. */
.sidebar-link .notif-badge,
.sidebar-link .sidebar-badge,
#planningNotificationBadge {
  position: static !important;
  top: auto !important;
  left: auto !important;
  right: auto !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 19px;
  height: 19px;
  padding: 0 6px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: var(--weight-bold);
  line-height: 1;
  flex-shrink: 0;
  background: var(--danger-tint);
  color: var(--danger-ink);
  font-variant-numeric: tabular-nums;
}

#planningNotificationBadge[hidden] { display: none !important; }

/*  En rail, la pastille devient un point pose sur l'icone : il n'y a plus la
    place pour un chiffre sans ecraser l'icone.

    LE RAIL MOBILE EST CONCERNE AU MEME TITRE. Il ne l'etait pas : la pastille
    y restait dans le flux du lien, a cote de l'icone, et poussait celle-ci de
    14 px vers la gauche. Inventaire et Planning — les deux seuls a porter un
    compteur — avaient donc leur icone desalignee de toutes les autres.
    Le chiffre reste dans le document : il nomme le lien pour un lecteur
    d'ecran (« Inventaire 1 »), seul son affichage disparait.  */
@media (max-width: 992px) {
  .sidebar .sidebar-link { position: relative; }
}

.sidebar-pre-collapsed .sidebar-link .notif-badge,
.sidebar-pre-collapsed .sidebar-link .sidebar-badge,
.sidebar.collapsed .sidebar-link .notif-badge,
.sidebar.collapsed .sidebar-link .sidebar-badge,
.sidebar.collapsed #planningNotificationBadge {
  position: absolute !important;
  top: 6px !important;
  right: 6px !important;
  min-width: 8px;
  width: 8px;
  height: 8px;
  padding: 0;
  font-size: 0;
  background: var(--danger);
  border: 1.5px solid var(--surface);
  /* style.css pose `opacity: 0` sur tout span d'un .sidebar-link en rail, pour
     escamoter les libelles. La pastille est un span : elle disparaissait avec
     eux, et le point n'etait jamais visible replie. On la remet. */
  opacity: 1;
}

.sidebar-pre-collapsed .sidebar-link,
.sidebar.collapsed .sidebar-link { position: relative; }

@media (max-width: 992px) {
  .sidebar .sidebar-link .notif-badge,
  .sidebar .sidebar-link .sidebar-badge,
  .sidebar #planningNotificationBadge {
    position: absolute !important;
    top: 6px !important;
    right: 6px !important;
    min-width: 8px;
    width: 8px;
    height: 8px;
    padding: 0;
    font-size: 0;
    background: var(--danger);
    border: 1.5px solid var(--surface);
    opacity: 1;
  }
}

/*  Il y avait ici deux regles rattrapant les chevrons permutes :
    `.sidebar-toggle-btn svg[hidden]` et `svg:not([hidden])`. Elles ne pouvaient
    pas aboutir : le JavaScript pilotait `style.display` sans jamais retirer
    l'attribut `hidden` du gabarit. Le bouton n'a plus qu'une fleche, que le
    CSS fait pivoter.  */
