/*
 * calli-ds.css — Système de design du portail Calli (lots 1 à 8)
 * Direction artistique, 04.10.2026. Audit : ~/vps-docs/decisions/2026-10-04-calli-design/audit-apple-design.md
 *
 * Chargé APRÈS styles.css et portal.css, uniquement dans les pages du portail (pas sur la
 * landing publique). Réversible : retirer le <link> suffit.
 *
 * Principes appliqués (référence apple-design) :
 *  - un seul niveau de matière translucide : barre latérale, barre d'onglets mobile, menus
 *    flottants et carte de connexion ; tout le contenu est opaque (lisibilité + GPU) ;
 *  - l'orange de la charte (#FF8A1F) est réservé à l'action principale, avec l'encre
 *    #2A1F17 dessus ; la sélection (segmenté, puces, filtres) est neutre ;
 *  - retour immédiat à l'appui (scale .97, 100 ms), aucun soulèvement au survol ;
 *  - seuls transform et opacity sont animés ;
 *  - prefers-reduced-motion / -transparency / -contrast pris en charge.
 *
 * Spécificité : certains sélecteurs de portal.css sont repris À L'IDENTIQUE pour gagner par
 * l'ordre de chargement (ex. .modal:not(#configInlineModal) .modal-card,
 * body[data-copy-page="login"] #loginBtn). Ne pas les « simplifier ».
 * Les sélecteurs dépendant d'un gabarit JS ou HTML précis sont marqués [FRAGILE].
 */


/* ==========================================================================
   LOT 1 — Fondations : jetons, focus, schéma sombre, préférences d'accessibilité
   Aucun changement de mise en page attendu, hormis les anneaux de focus.
   ========================================================================== */

:root {
  color-scheme: dark; /* menus natifs, remplissage auto et barres de défilement en sombre */

  /* Surfaces (nuit) */
  --c-bg: #070B14;
  --c-surface-1: #0E131F;      /* cartes de premier niveau, feuilles */
  --c-surface-2: #161C2A;      /* tuiles imbriquées, listes groupées, piste du segmenté */
  --c-surface-3: #1F2637;      /* bouton secondaire */
  --c-surface-3-hover: #262E42;
  --c-surface-3-press: #2C3549;
  --c-field: #0A0F1A;          /* champs (en creux) */
  --c-material: rgba(12, 16, 26, 0.80);           /* seule matière translucide */
  --c-material-filter: blur(24px) saturate(160%);
  --c-scrim: rgba(3, 5, 10, 0.64);

  /* Texte — contrastes WCAG vérifiés */
  --c-text-1: #F5F2EE;   /* 16,6:1 sur surface-1 */
  --c-text-2: #B9BFCB;   /* 9,2:1 sur surface-2 ; 7,9:1 sur la matière au-dessus du halo */
  --c-text-3: #8E96A6;   /* 5,7:1 sur surface-2 ; 6,4:1 sur champ ; 4,9:1 sur matière/halo */
  --c-text-disabled: #5E6677;

  /* Marque (brand.yaml) */
  --c-orange: #FF8A1F;
  --c-orange-hover: #FF9A3D;
  --c-orange-press: #F07A10;
  --c-on-orange: #2A1F17;      /* 6,8:1 ; 7,6:1 au survol ; 5,7:1 appuyé */
  --c-orange-text: #FFA04A;    /* texte orange sur nuit : 8,4:1 sur surface-2 */
  --c-orange-tint: rgba(255, 138, 31, 0.14);
  --c-focus: #FF9A3D;          /* anneau 2 px : 8,8:1 sur surface-1 */

  /* Statuts (texte coloré sur sa teinte : ≥ 5,4:1) */
  --c-success: #3DD68C;  --c-success-tint: rgba(61, 214, 140, 0.14);
  --c-warning: #F5B83D;  --c-warning-tint: rgba(245, 184, 61, 0.14);
  --c-danger: #FF6B6B;   --c-danger-tint: rgba(255, 107, 107, 0.16);
  --c-danger-fill: #C93636;    /* texte blanc 5,2:1 */
  --c-info: #6CB8FF;     --c-info-tint: rgba(108, 184, 255, 0.14);
  --c-neutral-tint: rgba(255, 255, 255, 0.08);

  /* Traits */
  --c-separator: rgba(255, 255, 255, 0.08);  /* décoratif */
  --c-border-control: #646E83; /* contour de champ / état : 3,3–3,7:1 (WCAG 1.4.11) */
  --c-thumb: #5C6880;          /* curseur de sélection : 3,0:1 sur la piste, texte-1 dessus 5,0:1 */

  /* Rayons (concentriques : intérieur = extérieur − marge) */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-full: 999px;

  /* Élévation : sur nuit, la profondeur vient de la clarté de surface + un liseré haut.
     « Aucune ombre » = 0 0 0 0 transparent (valeur valide dans les listes de box-shadow). */
  --e-0: 0 0 0 0 transparent;
  --e-1: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 1px 2px rgba(0, 0, 0, 0.35);
  --e-2: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 8px 24px rgba(0, 0, 0, 0.40);
  --e-3: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 24px 64px rgba(0, 0, 0, 0.55);

  /* Espacements (grille de 4, en rem) */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.25rem;
  --s-6: 1.5rem;
  --s-8: 2rem;
  --s-10: 2.5rem;
  --s-12: 3rem;

  /* Contrôles */
  --control-h: 40px;
  --control-h-lg: 48px;
  --control-h-sm: 32px;

  /* Mouvement */
  --dur-press: 100ms;
  --dur-fast: 160ms;
  --dur-base: 240ms;
  --dur-spring: 440ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
  --ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1);
  --ease-spring: var(--ease-out);

  /* Polices (décision utilisateur du 04.10.2026) :
     - police SYSTÈME pour le texte courant, les libellés, les champs, les boutons et TOUS
       les chiffres : elle a des chiffres tabulaires et un réglage optique natif ;
     - Cabinet Grotesk réservée aux titres d'affichage (h1/h2, titres de cartes), avec
       approche négative. Cabinet Grotesk n'a pas de « tnum » (chiffres proportionnels).
     Aucune police téléchargée en plus. */
  --font-system: system-ui, -apple-system, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-numeric: var(--font-system);
}

/* Remappage des familles et graisses de styles.css : le corps et l'interface passent en
   police système (graisses standard 400/500/600, disponibles partout, y compris Segoe UI) ;
   --font-heading (Cabinet Grotesk) reste inchangée pour les titres. */
:root {
  --font-body: var(--font-system);
  --font-ui: var(--font-system);
  --font-weight-body: 400;
  --font-weight-ui: 500;
  --font-weight-label: 600;
}

/* Montants, compteurs et tableaux : chiffres tabulaires partout où la police système
   est utilisée (sans effet visible sur le texte non numérique). */
body {
  font-variant-numeric: tabular-nums;
}

/* Ressort à amortissement critique (damping 1.0, réponse 0,3 s), échantillonné. */
@supports (transition-timing-function: linear(0, 1)) {
  :root {
    --ease-spring: linear(0, 0.094, 0.274, 0.456, 0.609, 0.726, 0.813, 0.874, 0.916,
      0.945, 0.964, 0.977, 0.985, 0.99, 0.994, 0.996, 0.998, 1);
  }
}

/* Remappage des variables existantes de styles.css / portal.css vers les jetons */
:root {
  --text: var(--c-text-1);
  --muted: var(--c-text-2);              /* .hint, .subtle, libellés : 7,6 → 9,2:1 et stable sur halo */
  --accent: var(--c-orange);             /* charte : #FF8A1F au lieu de #f97316 */
  --accent-2: var(--c-orange-text);
  --danger: var(--c-danger);
  --ok: var(--c-success);
}

/* Police des titres (Cabinet Grotesk) : affichage immédiat avec la police de repli au lieu
   d'un texte invisible jusqu'à 3 s (font-display: block dans styles.css). Même fichier, déjà
   préchargé : cette déclaration, postérieure, remplace celle de styles.css. */
@font-face {
  font-family: "Cabinet Grotesk";
  src: url("/assets/fonts/cabinet-grotesk/CabinetGrotesk-Variable.woff2") format("woff2-variations"),
    url("/assets/fonts/cabinet-grotesk/CabinetGrotesk-Variable.ttf") format("truetype-variations");
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
}

/* Focus visible unique (orange, 2 px, décalé). !important assumé : l'anneau doit
   l'emporter sur les ~20 « outline: none » de portal.css. Les champs ont leur propre
   anneau (lot 3). */
:focus-visible:not(input):not(select):not(textarea) {
  outline: 2px solid var(--c-focus) !important;
  outline-offset: 2px;
}

/* Dans les conteneurs qui rognent (défilement, listes groupées), l'anneau passe à l'intérieur */
.portal-float-nav__items :focus-visible,
.portal-mobile-tabbar :focus-visible,
.admin-cockpit-list :focus-visible,
.crm-list :focus-visible {
  outline-offset: -2px;
}

/* Fond : la version 2 couches de l'architecte est conservée telle quelle sur la connexion.
   Pages de travail : même ambiance, atténuée (h1 sur le halo : 2,5:1 mesuré, ≥ 7:1 visé)
   et dérive 3× plus lente (calme, moins de recalcul sous la barre latérale en verre).
   Seules l'opacité du conteneur et la durée changent ; aucune propriété animée ajoutée. */
body:not([data-copy-page="login"]) .bg {
  opacity: 0.6;
}

body:not([data-copy-page="login"]) .bg::after {
  animation-duration: 40s;
}

body:not([data-copy-page="login"]) .bg .bg-layer {
  animation-duration: 34s;
}

@media (prefers-reduced-transparency: reduce) {
  :root {
    --c-material: #0E131F;
    --c-material-filter: none;
    --c-scrim: rgba(3, 5, 10, 0.86);
  }
}

@media (prefers-contrast: more) {
  :root {
    --c-text-2: #D5DAE3;
    --c-text-3: #B3BAC7;
    --c-separator: rgba(255, 255, 255, 0.24);
    --c-border-control: #8D97AB;
    --c-material: #0E131F;
    --c-material-filter: none;
  }

  .bg::before,
  .bg::after,
  .bg .bg-layer {
    display: none !important;
  }
}

@media (forced-colors: active) {
  .bg {
    display: none;
  }
}


/* ==========================================================================
   LOT 2 — Matières : contenu opaque, verre réservé à ce qui flotte
   Corrige la lisibilité (gris 2,8–3,7:1 sur cartes translucides au-dessus du halo)
   et supprime les passes de flou restantes sur le contenu.
   ========================================================================== */

:root {
  /* Plus aucun flou sur les surfaces de contenu ni sur les boutons */
  --panel-filter: none;
  --btn-glass-filter: none;
  --glass-filter-panel: none;
  --glass-filter-strong: none;

  /* Surfaces de contenu opaques */
  --panel-surface: var(--c-surface-1);
  --panel-surface-strong: var(--c-surface-1);
  --panel-border: var(--c-separator);
  --panel-border-strong: var(--c-separator);
  --panel-shadow: var(--e-1);
  --panel-shadow-strong: var(--e-1);
  --border: var(--c-separator);
  --shadow: var(--e-3);

  /* Reflets décoratifs neutralisés (utilisés dans les ::before/::after des panneaux) */
  --panel-ambient: linear-gradient(transparent, transparent);
  --panel-highlight: linear-gradient(transparent, transparent);
  --panel-grain: linear-gradient(transparent, transparent);
}

.card,
.hero-card {
  border-radius: var(--r-lg);
}

.card::before,
.card::after,
.hero-card::before,
.hero-card::after,
.stats .stat::before,
.stats .stat::after,
.metric-card::before,
.metric-card::after {
  content: none;
}

/* Une carte posée dans une carte : tuile en surface-2, sans bord ni ombre (pas de 3e niveau) */
.card .card:not(.admin-cockpit-card),
.stats .stat,
.metric-card {
  background: var(--c-surface-2);
  border-color: transparent;
  box-shadow: var(--e-0);
}

.stats .stat {
  border-radius: var(--r-md);
}

/* Les seuls éléments en verre (une couche) */
.portal-float-nav__inner,
.portal-mobile-tabbar,
.profile-menu,
.notif-dropdown {
  background: var(--c-material);
  -webkit-backdrop-filter: var(--c-material-filter);
  backdrop-filter: var(--c-material-filter);
  border: 1px solid var(--c-separator);
}

.portal-mobile-tabbar::before,
.portal-mobile-tabbar::after {
  content: none;
}

/* Flous codés en dur sur du contenu ou sur des surfaces déjà opaques à 94 % */
.crm-row,
.segmented,
.portal-mobile-tabbar__support,
.modal-loader__pill,
.page-loader,
.portal-float-nav__roleview,
.portal-float-nav__roleview-field select {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* Modales : carte opaque + voile simple (« dim to focus »), pas de flou sur flou.
   Les en-têtes/pieds collants internes gardent leur flou (contenu qui défile dessous). */
.modal-backdrop,
.modal:not(#configInlineModal) .modal-backdrop,
#configInlineModal .modal-backdrop,
#itemModal .modal-backdrop,
html.embed-mode.config-inline-mode .modal .modal-backdrop,
.support-ticket-modal__backdrop,
.portal-float-nav-backdrop {
  background: var(--c-scrim);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.modal-card,
.modal:not(#configInlineModal) .modal-card,
#configInlineModal .modal-card.modal-xl,
.account-modal-card,
.pdf-modal-card,
.support-ticket-modal__card {
  background: var(--c-surface-1);
  border: 1px solid var(--c-separator);
  box-shadow: var(--e-3);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}


/* ==========================================================================
   LOT 3 — Contrôles : boutons, champs, segmenté, puces, badges + page de connexion
   ========================================================================== */

:root {
  --btn-size-md: var(--control-h);
  --btn-size-sm: var(--control-h-sm);
  --btn-size-icon: 44px;
  --field-control-height: var(--control-h-lg);
  --field-control-radius: var(--r-md);
  --field-control-compact-height: 44px;
  --field-control-compact-radius: var(--r-md);

  /* Niveau 1 : action principale — aplat de marque, encre dessus (charte) */
  --btn-l1-bg: var(--c-orange);
  --btn-l1-border: transparent;
  --btn-l1-text: var(--c-on-orange);
  --btn-l1-shadow: var(--e-0);

  /* Niveau 2 : état SÉLECTIONNÉ (segmenté, puce active, filtre) — neutre */
  --btn-l2-bg: var(--c-thumb);
  --btn-l2-border: var(--c-border-control);
  --btn-l2-text: var(--c-text-1);
  --btn-l2-shadow: var(--e-1);

  /* Niveau 3 : secondaire — surface opaque */
  --btn-l3-bg: var(--c-surface-3);
  --btn-l3-border: var(--c-separator);
  --btn-l3-text: var(--c-text-1);
  --btn-l3-shadow: var(--e-0);

  /* Niveau 4 : lien */
  --btn-l4-text: var(--c-orange-text);

  /* Destructif */
  --btn-danger-bg: var(--c-danger-fill);
  --btn-danger-border: transparent;
  --btn-danger-text: #ffffff;
  --btn-danger-shadow: var(--e-0);
}

@media (pointer: coarse) {
  :root {
    --control-h: 44px;
    --control-h-sm: 40px;
  }
}

/* --- Boutons --- */
.btn,
.icon-btn {
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0;
  transition:
    transform var(--dur-press) var(--ease-out),
    background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard);
}

.btn {
  padding-inline: var(--s-4);
}

.btn::before,
.btn::after,
.icon-btn::before,
.icon-btn::after {
  content: none;
}

.icon-btn {
  width: 44px;
  height: 44px;
}

/* Pas de soulèvement au survol (bruit visuel, et survol « collé » au doigt) */
.btn:hover:not(:disabled),
.icon-btn:hover {
  transform: none;
  filter: none;
  box-shadow: var(--btn-shadow-color);
  border-color: var(--btn-border-color);
}

/* Retour immédiat à l'appui */
.btn:active:not(:disabled),
.icon-btn:active {
  transform: scale(0.97);
}

.btn.primary,
.btn.primary:visited,
body[data-copy-page="login"] #loginBtn {
  color: var(--c-on-orange);
}

.btn.primary:hover:not(:disabled) {
  --btn-bg: var(--c-orange-hover);
}

.btn.primary:active:not(:disabled) {
  --btn-bg: var(--c-orange-press);
}

.btn.ghost:hover:not(:disabled),
.btn.secondary:hover:not(:disabled),
.icon-btn:hover {
  --btn-bg: var(--c-surface-3-hover);
}

.btn.ghost:active:not(:disabled),
.btn.secondary:active:not(:disabled),
.icon-btn:active {
  --btn-bg: var(--c-surface-3-press);
}

.btn.danger:hover:not(:disabled) {
  --btn-bg: #D84040;
}

.btn:focus-visible {
  border-color: var(--btn-border-color);
  box-shadow: var(--btn-shadow-color);
}

.btn:disabled {
  opacity: 0.4;
}

.btn-link,
.btn-link:hover:not(:disabled) {
  color: var(--c-orange-text);
}

/* Chargement : le JS pose aria-busy="true" pendant l'envoi */
.btn[aria-busy="true"] {
  color: transparent !important;
  pointer-events: none;
}

.btn[aria-busy="true"]::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--c-text-1);
  border-right-color: transparent;
  background: none;
  opacity: 1;
  z-index: 1;
  animation: spin 700ms linear infinite;
}

.btn.primary[aria-busy="true"]::after {
  border-color: var(--c-on-orange);
  border-right-color: transparent;
}

/* --- Champs --- */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
select,
textarea {
  background-color: var(--c-field);
  border: 1px solid var(--c-border-control);   /* 1,4:1 → 3,3–3,7:1 */
  color: var(--c-text-1);
  font-size: 1rem;                              /* 16 px : pas de zoom auto iOS */
  transition:
    border-color var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-standard);
}

::placeholder {
  color: var(--c-text-3);
  opacity: 1;
}

input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):hover,
select:hover,
textarea:hover {
  border-color: #7A849A;
}

/* Focus : anneau de marque (remplace l'anneau bleu natif) */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: none;
  border-color: var(--c-orange);
  box-shadow: 0 0 0 3px rgba(255, 138, 31, 0.30);
}

input:user-invalid,
select:user-invalid,
textarea:user-invalid,
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: var(--c-danger);
  box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.22);
}

input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):disabled,
select:disabled,
textarea:disabled {
  color: var(--c-text-disabled);
  border-color: #343B4C;
}

/* Remplissage automatique : garder le champ sombre */
input:-webkit-autofill,
input:-webkit-autofill:hover {
  -webkit-text-fill-color: var(--c-text-1);
  caret-color: var(--c-text-1);
  box-shadow: inset 0 0 0 100px var(--c-field);
}

input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--c-text-1);
  box-shadow: inset 0 0 0 100px var(--c-field), 0 0 0 3px rgba(255, 138, 31, 0.30);
}

.field label,
label {
  letter-spacing: 0;
  font-weight: 500;
}

.hint.error {
  color: var(--c-danger);
}

/* --- Segmenté / onglets : sélection neutre --- */
.tab-bar,
.view-mode-toggle,
.crm-view-toggle,
.account-tabs,
.segmented {
  background: var(--c-surface-2);
  border: 0;
  box-shadow: var(--e-0);
  padding: 2px;
  border-radius: var(--r-full);
}

.tab-bar .segmented-indicator,
.view-mode-toggle .segmented-indicator,
.crm-view-toggle .segmented-indicator,
.account-tabs .segmented-indicator,
.segmented .segmented-indicator {
  background: var(--c-thumb);
  border: 0;
  box-shadow: var(--e-1);
  /* transform + opacity seulement : la largeur se met à jour sans animation */
  transition:
    transform var(--dur-spring) var(--ease-spring),
    opacity var(--dur-fast) var(--ease-standard);
}

.crm-view-btn,
.account-tabs .tab-btn,
.segmented-btn,
.tab-btn {
  min-height: 36px;
  color: var(--c-text-2);
  font-weight: 600;
}

.crm-view-btn.active,
.account-tabs .tab-btn.active,
.segmented-btn.active,
.tab-btn.active,
.crm-view-btn:not(.active):hover,
.account-tabs .tab-btn:not(.active):hover,
.segmented-btn:not(.active):hover,
.tab-btn:not(.active):hover {
  color: var(--c-text-1);
}

@media (pointer: coarse) {
  .crm-view-btn,
  .account-tabs .tab-btn,
  .segmented-btn,
  .tab-btn {
    min-height: 44px;
  }
}

/* --- Puces de filtre : neutres ; sélection = surface claire + contour (3,6:1) --- */
.chip,
.status-chip {
  min-height: var(--control-h-sm);
  background: var(--c-surface-2);
  border: 1px solid transparent;
  color: var(--c-text-2);
  box-shadow: var(--e-0);
  transition:
    transform var(--dur-press) var(--ease-out),
    background-color var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard);
}

.chip::before,
.chip::after,
.status-chip::before,
.status-chip::after {
  content: none;
}

.chip:hover,
.status-chip:hover {
  transform: none;
  filter: none;
  box-shadow: var(--e-0);
  border-color: transparent;
  background: var(--c-surface-3);
  color: var(--c-text-1);
}

.chip:active,
.status-chip:active {
  transform: scale(0.97);
}

.chip.active,
.status-chip.active,
.status-chip.action.active {
  background: var(--c-surface-3);
  border-color: var(--c-border-control);
  color: var(--c-text-1);
  box-shadow: var(--e-0);
  transform: none;
}

.status-chip .dot { background: var(--c-text-3); }
.status-chip.action .dot { background: var(--c-orange); }
.status-chip.waiting .dot { background: var(--c-text-3); }
.status-chip.won .dot { background: var(--c-success); }
.status-chip.lost .dot { background: var(--c-danger); }

/* --- Badges (lecture seule) : toujours couleur + texte --- */
.pill {
  min-height: 24px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-full);
  background: var(--c-neutral-tint);
  color: var(--c-text-2);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0;
}

.pill.info,
.pill[data-tone="info"] { background: var(--c-info-tint); color: var(--c-info); }
.pill[data-tone="success"] { background: var(--c-success-tint); color: var(--c-success); }
.pill[data-tone="warning"] { background: var(--c-warning-tint); color: var(--c-warning); }
.pill[data-tone="danger"] { background: var(--c-danger-tint); color: var(--c-danger); }

/* --- Page de connexion (C1, C2) --- */
body[data-copy-page="login"] .portal-shell {
  max-width: 480px;
  gap: var(--s-6);
}

body[data-copy-page="login"] .brand-logo {
  height: clamp(64px, 7vw, 88px);
}

body[data-copy-page="login"] .hero-left h1 {
  font-size: 2rem;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 740;
  color: var(--c-text-1);
}

/* La carte de connexion flotte seule sur le fond : c'est la matière de la page */
body[data-copy-page="login"] .login-card {
  max-width: 440px;
  padding: var(--s-8) var(--s-6) var(--s-6);
  border-radius: var(--r-xl);
  background: var(--c-material);
  -webkit-backdrop-filter: var(--c-material-filter);
  backdrop-filter: var(--c-material-filter);
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow: var(--e-3);
}

body[data-copy-page="login"] #loginForm {
  gap: var(--s-4);
}

body[data-copy-page="login"] .login-actions {
  flex-direction: column;
  align-items: stretch;
  gap: var(--s-2);
  margin-top: var(--s-2);
}

body[data-copy-page="login"] .login-submit {
  width: 100%;
  min-width: 0;
  min-height: 48px;
  font-size: 1rem;
}

/* Une seule action principale : « Mot de passe oublié » devient un lien texte */
body[data-copy-page="login"] .login-forgot,
body[data-copy-page="login"] .login-forgot:hover:not(:disabled),
body[data-copy-page="login"] .login-forgot:active:not(:disabled) {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  background: none;
  border: 0;
  box-shadow: none;
  color: var(--c-orange-text);
  font-weight: 500;
}

body[data-copy-page="login"] #loginError:not(:empty) {
  margin: 0;
  padding: 10px 14px;
  text-align: left;
  border-radius: var(--r-md);
  background: var(--c-danger-tint);
  color: var(--c-danger);
  font-size: 0.875rem;
  line-height: 1.4;
}


/* ==========================================================================
   LOT 4 — Typographie et en-tête
   Hiérarchie par graisse + taille + interligne ; approche négative sur les grands titres,
   légèrement positive sur les petits textes ; chiffres tabulaires.
   ========================================================================== */

:root {
  --portal-card-title-size: 1.375rem;      /* 22 px (était 26–34, en concurrence avec h1) */
  --portal-section-title-size: 1.0625rem;  /* 17 px */
  --portal-section-title-line: 1.3;
  --portal-modal-title-size: 1.75rem;      /* 28 px */
  --portal-modal-title-line: 1.14;
}

/* Titre de page */
.portal-shell .hero-left h1,
.agent-shell .hero-left h1,
.advanced-shell .hero h1,
.kpi-shell .hero h1 {
  font-size: clamp(2rem, 1.5rem + 1.2vw, 2.5rem);
  line-height: 1.08;
  letter-spacing: -0.025em;
  font-weight: 760;
  color: var(--c-text-1);
}

/* Titres de carte */
#metricsSection .metrics-title h2,
.portal-shell > .card > .card-head h2,
.portal-shell > .card > .card-head h3,
.portal-shell .grid > .card > .card-head h2,
.portal-shell .grid > .card > .card-head h3,
.crm-overview .card-head h3,
.crm-prospects .card-head h3,
.kpi-panel .card-head h3,
.pricing-section-head h3 {
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--c-text-1);
}

/* Titres de section */
.portal-section-title,
.config-section summary > span:first-child,
.config-section__head > span:first-child,
.config-panel-intro h3,
.panel-section__head h3,
.crm-form-section-head h5,
.crm-quote h4,
.service-metrics-head h3,
.settings-group__header h4,
.advanced-shell .card-head h3,
.billing-admin-card .card-head h3,
.admin-cockpit-card .card-head h3 {
  letter-spacing: -0.01em;
  color: var(--c-text-1);
}

/* Titres de modale */
.portal-modal-title,
.modal:not(#configInlineModal) .modal-head h3,
#configInlineModal .modal-head h3,
.account-modal-title,
.pdf-modal-title {
  letter-spacing: -0.02em;
  color: var(--c-text-1);
}

/* Aides et sous-titres de carte */
.card-head .hint,
.card-head .subtle {
  font-size: 0.8125rem;
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--c-text-2);
}

/* Compteurs : police système à chiffres tabulaires (voir --font-numeric) */
.admin-cockpit-kpi strong,
.admin-cockpit-mode-metrics strong,
.admin-cockpit-row b,
.stats .value,
.stat .value,
.stat-value,
.metrics-value,
.summary-value,
.kpi-card-value,
.rank-count,
.plan-price,
.pricing-price-cell strong {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  font-weight: 600;
}

/* Surtitre (« SUPER ADMIN ») : orange 12 px sur halo 2,2:1 → texte-2 */
.restaurant-name,
.acting-as-context {
  color: var(--c-text-2);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
}

/* Actions d'en-tête : pastilles opaques, plus de verre orange (l'orange = action principale) */
.hero-actions .cta-open,
.hero-actions .notif-btn {
  min-height: 44px;
  background: var(--c-surface-3);
  border: 1px solid var(--c-separator);
  color: var(--c-text-1);
  box-shadow: var(--e-0);
}

.hero-actions .cta-open {
  padding-inline: var(--s-5);
}

.hero-actions .notif-btn {
  width: 44px;
  height: 44px;
}

.hero-actions .cta-open::before,
.hero-actions .cta-open::after {
  content: none;
}

.hero-actions .cta-open:hover,
.hero-actions .notif-btn:hover,
.hero-actions .notif-btn:focus-visible {
  background: var(--c-surface-3-hover);
  border-color: var(--c-separator);
  color: var(--c-text-1);
  box-shadow: var(--e-0);
}

.hero-actions .cta-open:active,
.hero-actions .notif-btn:active {
  background: var(--c-surface-3-press);
  transform: scale(0.97);
}

.notif-dot {
  top: 9px;
  right: 9px;
  width: 9px;
  height: 9px;
  background: var(--c-danger);
  box-shadow: 0 0 0 2px var(--c-surface-3);
}

/* Navigation : correctifs de lisibilité minimaux (refonte complète = lot 6).
   L'élément actif garde une teinte de marque (lieu courant), le libellé de section passe
   de 2,95:1 à 5,7:1. */
.portal-float-nav__section-label {
  color: var(--c-text-3);
  letter-spacing: 0.08em;
}

.portal-float-nav__item.is-active,
.portal-float-nav__calli.is-active {
  border-color: transparent;
  background: var(--c-orange-tint);
}

.portal-float-nav__item.is-active .portal-float-nav__item-icon,
.portal-float-nav__calli.is-active .portal-float-nav__calli-icon {
  color: var(--c-orange-text);
}


/* ==========================================================================
   LOT 5 — Tableau de bord (cockpit superadmin, vues restaurant et ambassadeur)
   Un seul niveau de boîte par carte, listes groupées, contenu aligné en haut,
   états vides calmes, squelette au premier rendu.
   ========================================================================== */

/* [FRAGILE] Supprime la boîte qui enveloppe tout le cockpit superadmin (carte dans carte
   dans carte). Cible : <section id="metricsSection"><div class="card"> de portal/index.html,
   uniquement quand la vue admin est visible (les autres rôles gardent leur carte). */
#metricsSection > .card:has(#adminMetrics:not(.hidden)) {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  overflow: visible;
}

.admin-cockpit-hero::before,
.admin-cockpit-hero::after,
.admin-cockpit-card::before,
.admin-cockpit-card::after,
.admin-cockpit-kpi::before,
.admin-cockpit-kpi::after {
  content: none;
}

/* Cartes : hauteur selon le contenu, contenu en haut (plus de vides de 292 px) */
.admin-cockpit-card {
  min-height: 0;
  padding: var(--s-5);
  gap: var(--s-4);
  border-radius: var(--r-lg);
  background: var(--c-surface-1);
  border: 1px solid var(--c-separator);
}

.admin-cockpit-card--wide {
  min-height: 0;
}

.admin-cockpit-list,
.admin-cockpit-table,
.admin-cockpit-mode-table {
  margin-top: 0;
}

/* KPI : imbriqués en surface-2 ; premier niveau en surface-1 */
.admin-cockpit-kpi {
  min-height: 0;
  gap: 6px;
  padding: 14px 16px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--c-surface-2);
  box-shadow: var(--e-0);
}

.admin-cockpit-kpis > .admin-cockpit-kpi {
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--c-separator);
  border-radius: var(--r-lg);
  background: var(--c-surface-1);
  box-shadow: var(--e-1);
}

/* Libellés en casse de phrase (11 px capitales graisse 800 → 13 px graisse 600) */
.admin-cockpit-kpi span {
  min-height: 0;
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--c-text-2);
}

.admin-cockpit-kpi strong {
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--c-text-1);
}

.admin-cockpit-kpis > .admin-cockpit-kpi strong {
  font-size: 2rem;
  letter-spacing: -0.02em;
}

.admin-cockpit-kpi small {
  font-size: 0.75rem;
  letter-spacing: 0;
  color: var(--c-text-3);
}

/* Valeur nulle sur la période (le JS pose data-empty) : discrète, pas en vedette */
.admin-cockpit-kpi[data-empty] strong {
  color: var(--c-text-3);
}

/* Répartition / Top : liste groupée, séparateurs en retrait */
.admin-cockpit-list {
  gap: 0;
  border-radius: var(--r-md);
  background: var(--c-surface-2);
  overflow: hidden;
}

.admin-cockpit-list:has(> .admin-cockpit-empty) {
  background: none;
  overflow: visible;
}

.admin-cockpit-row {
  position: relative;
  min-height: 56px;
  padding: 12px 16px;
  border: 0;
  border-radius: 0;
  background: none;
}

.admin-cockpit-row + .admin-cockpit-row::before {
  content: "";
  position: absolute;
  top: 0;
  left: 16px;
  right: 0;
  height: 1px;
  background: var(--c-separator);
}

.admin-cockpit-row strong {
  color: var(--c-text-1);
  font-weight: 600;
}

.admin-cockpit-row span {
  color: var(--c-text-3);
}

.admin-cockpit-row b {
  font-weight: 600;
  min-width: 4ch;
  text-align: right;
  color: var(--c-text-1);
}

.admin-cockpit-track {
  height: 6px;
  background: var(--c-neutral-tint);
}

.admin-cockpit-track span {
  margin-top: 0;
  background: var(--c-orange);
  box-shadow: none;
}

/* Activité par mode : un seul niveau de boîte */
.admin-cockpit-mode-card {
  min-height: 0;
  padding: var(--s-4);
  border: 0;
  border-radius: var(--r-md);
  background: var(--c-surface-2);
}

.admin-cockpit-mode-head span,
.admin-cockpit-mode-metrics span {
  color: var(--c-text-2);
  letter-spacing: 0.04em;
}

.admin-cockpit-mode-metrics div {
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}

.admin-cockpit-mode-metrics div + div {
  padding-left: var(--s-4);
  border-left: 1px solid var(--c-separator);
}

/* Santé clients / Upsell / Onboarding : un vrai tableau, plus des « champs de saisie » */
.admin-cockpit-table {
  gap: 0;
}

.admin-cockpit-table span {
  min-height: 44px;
  padding: 10px 12px;
  border: 0;
  border-top: 1px solid var(--c-separator);
  border-radius: 0;
  background: none;
  color: var(--c-text-1);
  font-size: 0.875rem;
}

.admin-cockpit-table .head {
  min-height: 0;
  padding: 0 12px 8px;
  border-top: 0;
  color: var(--c-text-3);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

/* États vides : centrés, sans cadre pointillé ; pictogramme décoratif (le texte informe) */
.admin-cockpit-empty {
  min-height: 120px;
  flex-direction: column;
  gap: var(--s-2);
  border: 0;
  background: none;
  color: var(--c-text-3);
  font-size: 0.875rem;
  text-align: center;
}

.admin-cockpit-empty::before {
  content: "";
  width: 28px;
  height: 28px;
  background: currentColor;
  opacity: 0.6;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 13h4l1.5 2.5h5L16 13h4'/%3E%3Cpath d='M5.5 5h13L20 13v6H4v-6z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 13h4l1.5 2.5h5L16 13h4'/%3E%3Cpath d='M5.5 5h13L20 13v6H4v-6z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* [FRAGILE] Squelette du premier rendu : texte « Chargement du cockpit superadmin. » de
   portal/index.html, seul enfant de .admin-cockpit. Garde la hauteur réservée par
   l'architecte (560 px) et dessine la forme du cockpit (4 KPI + 2 cartes).
   Le texte reste lu par les lecteurs d'écran. */
#adminMetrics > .admin-cockpit > .admin-cockpit-empty:only-child {
  color: transparent;
  border-radius: var(--r-lg);
  background:
    linear-gradient(var(--c-surface-1), var(--c-surface-1)) 0 0 / calc(25% - 9px) 112px no-repeat,
    linear-gradient(var(--c-surface-1), var(--c-surface-1)) calc(100% / 3) 0 / calc(25% - 9px) 112px no-repeat,
    linear-gradient(var(--c-surface-1), var(--c-surface-1)) calc(200% / 3) 0 / calc(25% - 9px) 112px no-repeat,
    linear-gradient(var(--c-surface-1), var(--c-surface-1)) 100% 0 / calc(25% - 9px) 112px no-repeat,
    linear-gradient(var(--c-surface-1), var(--c-surface-1)) 0 128px / calc(50% - 8px) 300px no-repeat,
    linear-gradient(var(--c-surface-1), var(--c-surface-1)) 100% 128px / calc(50% - 8px) 300px no-repeat;
}

#adminMetrics > .admin-cockpit > .admin-cockpit-empty:only-child::before {
  content: none;
}

/* Vues restaurant / ambassadeur : blocs en surface-1, tuiles en surface-2 (lot 2),
   libellés lisibles, valeurs en chiffres tabulaires (lot 4). */
.service-metrics-block {
  border-radius: var(--r-lg);
}

.stats .label {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--c-text-2);              /* gris 75 % (~4:1) → 9,2:1 */
}

.stats .value {
  letter-spacing: -0.01em;
  color: var(--c-text-1);
}

.rank-row {
  border-bottom-color: var(--c-separator);
}

.rank-count {
  text-align: right;
  color: var(--c-text-1);
}

.rank-index {
  background: var(--c-neutral-tint);
  color: var(--c-text-2);
}


/* ==========================================================================
   LOT 6 — Navigation, menus flottants, toast
   La barre latérale est la seule matière : ses éléments sont plats (pas de carte dans le
   verre). Menus ancrés à leur déclencheur, toast qui entre et sort par le même chemin.
   ========================================================================== */

/* --- Barre latérale : coque --- */
.portal-float-nav {
  transition: none;          /* largeur : bascule nette, pas de reflow animé du contenu */
  will-change: auto;
}

.portal-float-nav::before,
.portal-float-nav__sheen {
  display: none;
}

.portal-float-nav__inner {
  box-shadow: var(--e-2);
  transition: none;
}

/* --- Éléments de navigation : rangées plates --- */
.portal-float-nav__item,
.portal-float-nav__calli,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__calli {
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  box-shadow: var(--e-0);
  color: var(--c-text-2);
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard),
    transform var(--dur-press) var(--ease-out);
}

.portal-float-nav__item::before,
.portal-float-nav__item::after,
.portal-float-nav__calli::before,
.portal-float-nav__calli::after,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item::before,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__calli::before {
  content: none;
}

.portal-float-nav__item:hover,
.portal-float-nav__calli:hover,
.portal-float-nav__item:focus-visible,
.portal-float-nav__calli:focus-visible,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item:hover,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__calli:hover {
  background: var(--c-neutral-tint);
  border-color: transparent;
  box-shadow: var(--e-0);
  color: var(--c-text-1);
  transform: none;
}

.portal-float-nav__item:active,
.portal-float-nav__calli:active,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item:active,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__calli:active {
  transform: scale(0.97);
}

/* Lieu courant : teinte de marque (complète le lot 4, spécificité de l'état replié) */
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item.is-active,
.portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__calli.is-active,
.portal-float-nav .portal-float-nav__item.is-active,
.portal-float-nav .portal-float-nav__calli.is-active {
  background: var(--c-orange-tint);
  border-color: transparent;
  box-shadow: var(--e-0);
  color: var(--c-text-1);
}

/* Pictogrammes : plus de pastille, plus de halo ni de saut au survol */
.portal-float-nav__item-icon,
.portal-float-nav__calli-icon {
  background: none;
  border-color: transparent;
  box-shadow: none;
  color: inherit;
  transition: color var(--dur-fast) var(--ease-standard);
}

.portal-float-nav__item.is-active .portal-float-nav__item-icon,
.portal-float-nav__calli.is-active .portal-float-nav__calli-icon {
  background: none;
  border-color: transparent;
  box-shadow: none;
}

.portal-float-nav__item:hover .portal-float-nav__item-icon,
.portal-float-nav__calli:hover .portal-float-nav__calli-icon,
.portal-float-nav__item:focus-visible .portal-float-nav__item-icon,
.portal-float-nav__calli:focus-visible .portal-float-nav__calli-icon,
.portal-float-nav__item.is-active .portal-float-nav__item-icon,
.portal-float-nav__calli.is-active .portal-float-nav__calli-icon {
  transform: none;
  filter: none;
}

.portal-float-nav__item-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--c-text-1);
}

.portal-float-nav__item-subtitle,
.portal-float-nav__brand-copy small,
.portal-float-nav__identity-copy small,
.portal-float-nav__calli-copy small {
  color: var(--c-text-3);
}

.portal-float-nav__item-arrow {
  color: var(--c-text-3);
}

.portal-float-nav__item:hover .portal-float-nav__item-arrow,
.portal-float-nav__item:focus-visible .portal-float-nav__item-arrow {
  transform: none;
  color: var(--c-text-2);
}

/* Libellés : fondu (opacity) après la bascule de largeur */
.portal-float-nav__brand-copy,
.portal-float-nav__identity-copy,
.portal-float-nav__item-copy,
.portal-float-nav__calli-copy {
  transition: opacity var(--dur-fast) var(--ease-out);
}

/* Identité (avatar + nom) */
.portal-float-nav__identity {
  border-color: transparent;
  background: transparent;
  box-shadow: var(--e-0);
  transition: background-color var(--dur-fast) var(--ease-standard), transform var(--dur-press) var(--ease-out);
}

.portal-float-nav__identity::before,
.portal-float-nav__identity::after {
  content: none;
}

.portal-float-nav__identity:hover,
.portal-float-nav__identity:focus-visible {
  background: var(--c-neutral-tint);
  border-color: transparent;
  box-shadow: var(--e-0);
  transform: none;
}

.portal-float-nav__identity:active {
  transform: scale(0.97);
}

.portal-float-nav__identity-avatar {
  box-shadow: none;
  border-color: var(--c-separator);
}

/* Bouton de pliage et bascule de contexte : boutons pictogrammes discrets */
.portal-float-nav__toggle,
body:not(.portal-nav-mobile) .portal-float-nav.is-expanded .portal-float-nav__toggle,
.portal-float-nav__roleview-compact {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--c-text-2);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transition: background-color var(--dur-fast) var(--ease-standard), transform var(--dur-press) var(--ease-out);
}

.portal-float-nav__toggle:hover,
.portal-float-nav__toggle:focus-visible,
.portal-float-nav__roleview-compact:hover,
.portal-float-nav__roleview-compact:focus-visible {
  background: var(--c-neutral-tint);
  border-color: transparent;
  box-shadow: none;
  color: var(--c-text-1);
  transform: none;
}

.portal-float-nav__toggle:active,
.portal-float-nav__roleview-compact:active {
  transform: scale(0.95);
}

.portal-float-nav__toggle svg {
  transition: transform var(--dur-base) var(--ease-out);
}

/* Panneau « Connexion en tant que » : surface opaque (flotte hors de la barre si repliée) */
.portal-float-nav__roleview {
  background: var(--c-surface-1);
  border: 1px solid var(--c-separator);
  border-radius: var(--r-lg);
  box-shadow: var(--e-2);
}

.portal-float-nav__roleview-title {
  color: var(--c-text-3);
}

.portal-float-nav__roleview-note,
.portal-float-nav__roleview-label {
  color: var(--c-text-2);
}

/* [FRAGILE] Infobulle en barre repliée : réutilise .portal-float-nav__item-copy, déjà rendu
   par portal-layout-manager.js et masqué (max-width:0 ; opacity:0). Le conteneur doit
   laisser déborder, sinon l'infobulle est rognée par le défilement de la liste. */
@media (hover: hover) and (min-width: 981px) and (min-height: 640px) {
  .portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__items {
    overflow: visible;
  }

  .portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item:is(:hover, :focus-visible) .portal-float-nav__item-copy {
    position: absolute;
    left: calc(100% + 12px);
    top: 50%;
    z-index: 2;
    max-width: none;
    padding: 6px 10px;
    border-radius: var(--r-sm);
    background: var(--c-surface-3);
    box-shadow: var(--e-2);
    color: var(--c-text-1);
    white-space: nowrap;
    pointer-events: none;
    opacity: 1;
    transform: translateY(-50%);
    transition: opacity var(--dur-fast) var(--ease-out) 250ms;
  }

  .portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item-copy small,
  .portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item-subtitle {
    display: none;
  }
}

/* --- Mobile : bouton de menu et barre d'onglets --- */
.portal-float-nav-mobile-toggle,
.portal-mobile-tabbar__support {
  background: var(--c-material);
  -webkit-backdrop-filter: var(--c-material-filter);
  backdrop-filter: var(--c-material-filter);
  border: 1px solid var(--c-separator);
  box-shadow: var(--e-2);
  color: var(--c-text-1);
  transition: transform var(--dur-press) var(--ease-out), background-color var(--dur-fast);
}

.portal-float-nav-mobile-toggle:hover,
.portal-float-nav-mobile-toggle:focus-visible,
.portal-mobile-tabbar__support:hover,
.portal-mobile-tabbar__support:focus-visible {
  transform: none;
  border-color: var(--c-separator);
  background: var(--c-material);
  box-shadow: var(--e-2);
}

.portal-float-nav-mobile-toggle:active,
.portal-mobile-tabbar__support:active {
  transform: scale(0.95);
}

.portal-mobile-tabbar {
  box-shadow: var(--e-2);
}

.portal-mobile-tabbar__item {
  border-color: transparent;
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    transform var(--dur-press) var(--ease-out);
}

.portal-mobile-tabbar__item:hover,
.portal-mobile-tabbar__item:focus-visible {
  transform: none;
  border-color: transparent;
  background: var(--c-neutral-tint);
  box-shadow: none;
}

.portal-mobile-tabbar__item:active {
  transform: scale(0.95);
}

.portal-mobile-tabbar__item.is-active {
  border-color: transparent;
  background: var(--c-orange-tint);
  box-shadow: none;
}

.portal-mobile-tabbar__item:hover .portal-mobile-tabbar__item-icon,
.portal-mobile-tabbar__item:focus-visible .portal-mobile-tabbar__item-icon,
.portal-mobile-tabbar__item.is-active .portal-mobile-tabbar__item-icon {
  transform: none;
  filter: none;
}

.portal-mobile-tabbar__item.is-active .portal-mobile-tabbar__item-icon {
  color: var(--c-orange-text);
}

.portal-mobile-tabbar__item-label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--c-text-2);
}

.portal-mobile-tabbar__item.is-active .portal-mobile-tabbar__item-label {
  color: var(--c-text-1);
}

/* --- Menu profil : popover ancré à l'avatar ---
   Entrée animée en CSS (@starting-style). Sortie : instantanée tant que
   profile-menu-manager.js efface top/left au même moment que .hidden (voir liste JS). */
.profile-menu {
  min-width: 248px;
  padding: 6px;
  gap: 2px;
  border-radius: var(--r-lg);
  box-shadow: var(--e-2);
  transform-origin: top right;
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-spring) var(--ease-spring);
}

.profile-menu--portal {
  transform-origin: top left;   /* ouvert à droite de la barre latérale, aligné sur l'avatar */
}

@starting-style {
  .profile-menu:not(.hidden) {
    opacity: 0;
    transform: scale(0.96);
  }
}

.profile-menu-header {
  margin-bottom: 4px;
  padding: 10px 12px 12px;
  border-radius: 0;
  border-bottom: 1px solid var(--c-separator);
  background: none;
}

.profile-menu-name {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--c-text-1);
}

.profile-menu-role {
  font-size: 0.75rem;
  color: var(--c-text-2);
}

.profile-menu-item,
.profile-menu-item:visited,
.profile-menu-item:focus {
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  box-shadow: none;
  color: var(--c-text-1);
  font-weight: 500;
  font-size: 0.875rem;
  transition: background-color var(--dur-fast) var(--ease-standard);
}

.profile-menu-item::before,
.profile-menu-item::after {
  content: none;
}

.profile-menu-item:hover,
.profile-menu-item:focus-visible {
  background: var(--c-neutral-tint);
  box-shadow: none;
  color: var(--c-text-1);
}

.profile-menu-item:active {
  background: var(--c-surface-3);
}

/* Déconnexion : action destructive en texte rouge, séparée, pas un bloc rouge plein */
.profile-menu-item.danger,
.profile-menu-item.danger:visited,
.profile-menu-item.danger:focus,
.profile-menu-item.danger:hover {
  position: relative;
  margin-top: 5px;
  border: 0;
  background: transparent;
  box-shadow: none;
  color: var(--c-danger);
}

.profile-menu-item.danger::before {
  content: "";
  position: absolute;
  inset: -3px 12px auto;
  height: 1px;
  background: var(--c-separator);
  opacity: 1;
}

.profile-menu-item.danger:hover,
.profile-menu-item.danger:focus-visible {
  background: var(--c-danger-tint);
}

/* --- Notifications : popover ancré à la cloche, entrée ET sortie par le même chemin --- */
.notif-dropdown {
  width: min(92vw, 380px);
  padding: var(--s-2);
  border-radius: var(--r-lg);
  box-shadow: var(--e-2);
  transform-origin: top right;
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-spring) var(--ease-spring),
    display var(--dur-base) allow-discrete;
}

@media (min-width: 721px) {
  .notif-dropdown {
    top: calc(100% + 8px);
  }
}

.notif-dropdown.hidden {
  opacity: 0;
  transform: translateY(-4px) scale(0.96);
  transition-timing-function: var(--ease-in);
  transition-duration: 180ms;
}

@starting-style {
  .notif-dropdown:not(.hidden) {
    opacity: 0;
    transform: translateY(-4px) scale(0.96);
  }
}

.notif-drop-head {
  margin: 0;
  padding: var(--s-2) var(--s-2) var(--s-3);
}

.notif-drop-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--c-text-1);
}

.notif-list {
  gap: 0;
}

.notif-item {
  border: 0;
  border-radius: var(--r-md);
  background: none;
  padding: 12px 12px 12px 26px;
  transition: background-color var(--dur-fast) var(--ease-standard);
}

.notif-item + .notif-item {
  box-shadow: inset 0 1px 0 var(--c-separator);
}

.notif-item:hover {
  background: var(--c-neutral-tint);
}

.notif-item.unread {
  border-color: transparent;
}

.notif-item.unread::before {
  content: "";
  position: absolute;
  left: 10px;
  top: 18px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c-orange);
}

.notif-item .notif-title {
  font-weight: 500;
  color: var(--c-text-2);
}

.notif-item.unread .notif-title {
  font-weight: 600;
  color: var(--c-text-1);
}

.notif-item .notif-meta {
  font-size: 0.75rem;
  color: var(--c-text-3);
}

/* Fermer une notification : visuel 32 px, zone d'appui 44 px */
.notif-dismiss {
  position: relative;
  width: 32px;
  height: 32px;
  color: var(--c-text-3);
}

.notif-dismiss::after {
  content: "";
  position: absolute;
  inset: -6px;
}

.notif-dismiss:hover,
.notif-dismiss:focus {
  background: var(--c-neutral-tint);
  border-color: transparent;
  color: var(--c-text-1);
}

/* Actions du menu : liens texte */
.notif-drop-head .btn,
.notif-drop-head [data-role="mark-all"],
#notifMarkAll,
.notif-clear {
  min-height: 36px;
  background: none;
  border-color: transparent;
  box-shadow: none;
  color: var(--c-orange-text);
  opacity: 1;
}

/* --- Toast : bas centre, entrée et sortie par le même chemin --- */
.toast {
  top: auto;
  right: auto;
  left: 50%;
  bottom: max(24px, env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-radius: var(--r-full);
  color: var(--c-text-1);
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0;
  box-shadow: var(--e-2);
  transform: translate(-50%, 12px);
  transition:
    opacity 180ms var(--ease-in),
    transform 180ms var(--ease-in);
}

.toast.show {
  transform: translate(-50%, 0);
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-spring) var(--ease-spring);
}

.toast.toast-ok,
.toast.toast-error {
  border-color: var(--c-separator);
  box-shadow: var(--e-2);
}

/* Repère décoratif : le texte du toast porte l'information */
.toast.toast-ok::before,
.toast.toast-error::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.toast.toast-ok::before { background: var(--c-success); }
.toast.toast-error::before { background: var(--c-danger); }

body.portal-nav-mobile .toast {
  bottom: calc(env(safe-area-inset-bottom) + 104px);
}


/* --- Menu profil : sortie animée (ajout architecte-it, 05.10.2026) ---
   profile-menu-manager.js pose .hidden puis n'efface top/left qu'au transitionend
   (ou après 200 ms), ce qui laisse jouer ce fondu de sortie. */
.profile-menu {
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-spring) var(--ease-spring),
    display var(--dur-base) allow-discrete;
}

.profile-menu.hidden {
  opacity: 0;
  transform: scale(0.96);
  transition-duration: 160ms;
  transition-timing-function: var(--ease-in);
}


/* --- Transition vers DigiNovae : fondu seul (ajout architecte-it, 05.10.2026) ---
   portal-layout-manager.js crée .portal-dnv-warp--fade sans halo ni logo et navigue à
   ~250 ms. On neutralise ici les dégradés bleu/rose, le reflet et le flou d'arrière-plan. */
.portal-dnv-warp--fade,
.portal-dnv-warp--fade.is-active {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transition: opacity var(--dur-base) var(--ease-out);
}

.portal-dnv-warp--fade.is-active {
  background-color: var(--c-bg);
}

.portal-dnv-warp--fade::before,
.portal-dnv-warp--fade::after {
  content: none;
}


/* ==========================================================================
   LOT 7 — CRM, Configuration, KPI
   Listes groupées, un seul orange par écran, statuts calmes (pastille + texte).
   ========================================================================== */

/* --- CRM : métriques --- */
.metric-label {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--c-text-2);
}

.metric-value {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--c-text-1);
}

.metric-sub {
  color: var(--c-text-3);
}

/* --- CRM : barre de recherche --- */
.crm-toolbar {
  gap: var(--s-2);
}

#crmSearch {
  flex: 1 1 280px;
  min-width: 0;
  padding-left: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238E96A6' stroke-width='1.8' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='m16 16 4 4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 14px center;
  background-size: 18px;
}

/* --- CRM : liste groupée (plus de cadre coloré par ligne ; le statut est dans le badge) --- */
.crm-list {
  gap: 0;
  border-radius: var(--r-md);
  background: var(--c-surface-2);
  overflow: hidden;
}

.crm-list:empty {
  display: none;
}

/* :is(.crm-row, .crm-row-action.stale) aligne la spécificité sur la variante la plus forte
   de portal.css tout en ciblant toutes les lignes. */
.crm-list > .crm-row:is(.crm-row, .crm-row-action.stale) {
  position: relative;
  width: 100%;
  min-height: 60px;
  padding: 12px 16px;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  transition: background-color var(--dur-fast) var(--ease-standard);
}

.crm-list > .crm-row + .crm-row::before {
  content: "";
  position: absolute;
  top: 0;
  left: 16px;
  right: 0;
  height: 1px;
  background: var(--c-separator);
}

.crm-list > .crm-row:is(.crm-row, .crm-row-action.stale):hover {
  background: var(--c-neutral-tint);
  transform: none;
}

.crm-list > .crm-row:is(.crm-row, .crm-row-action.stale):active {
  background: var(--c-surface-3);
}

.crm-list > .crm-row.active:is(.crm-row, .crm-row-action.stale) {
  background: var(--c-orange-tint);
  box-shadow: none;
}

.crm-name {
  font-weight: 600;
  color: var(--c-text-1);
}

.crm-meta {
  font-size: 0.8125rem;
  color: var(--c-text-3);
}

.avatar-badge {
  width: 32px;
  height: 32px;
  background: var(--c-surface-3);
  border-color: transparent;
  color: var(--c-text-2);
  font-size: 0.75rem;
}

/* --- CRM : Kanban — colonnes neutres, statut par pastille dans le titre --- */
.crm-kanban-column,
.crm-kanban-column.tone-action,
.crm-kanban-column.tone-waiting,
.crm-kanban-column.tone-won,
.crm-kanban-column.tone-lost,
.crm-kanban-group,
.crm-kanban-group-action,
.crm-kanban-group-waiting,
.crm-kanban-group-won,
.crm-kanban-group-lost {
  border-color: transparent;
  border-radius: var(--r-lg);
  background: var(--c-surface-2);
}

.crm-kanban-group-title,
.crm-kanban-group-action .crm-kanban-group-title,
.crm-kanban-group-waiting .crm-kanban-group-title,
.crm-kanban-group-won .crm-kanban-group-title,
.crm-kanban-group-lost .crm-kanban-group-title,
.crm-kanban-column-title {
  color: var(--c-text-1);
}

.crm-kanban-column[class*="tone-"] .crm-kanban-column-title::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 8px;
  border-radius: 50%;
  vertical-align: 0.05em;
  background: var(--c-text-3);
}

.crm-kanban-column.tone-action .crm-kanban-column-title::before { background: var(--c-orange); }
.crm-kanban-column.tone-won .crm-kanban-column-title::before { background: var(--c-success); }
.crm-kanban-column.tone-lost .crm-kanban-column-title::before { background: var(--c-danger); }

.crm-kanban-card {
  border-color: transparent;
  border-radius: var(--r-md);
  background: var(--c-surface-1);
  box-shadow: var(--e-1);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transition:
    transform var(--dur-press) var(--ease-out),
    background-color var(--dur-fast) var(--ease-standard),
    opacity var(--dur-fast) var(--ease-standard);
}

.crm-kanban-card:hover {
  transform: none;
  border-color: transparent;
  background: #121827;
}

.crm-kanban-card.active {
  border-color: transparent;
  background: var(--c-orange-tint);
  box-shadow: var(--e-1);
}

.crm-kanban-card.stale {
  border-color: transparent;
}

.crm-kanban-title {
  color: var(--c-text-1);
}

.crm-kanban-meta {
  color: var(--c-text-3);
}

/* --- Configuration : cartes d'entrée --- */
.config-hub-card {
  border: 1px solid var(--c-separator);
  border-radius: var(--r-lg);
  background: var(--c-surface-1);
  box-shadow: var(--e-1);
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    transform var(--dur-press) var(--ease-out);
}

.config-hub-card::before {
  filter: none;             /* plus de filtre animé au survol */
  opacity: 0.35;
  transition: opacity var(--dur-base) var(--ease-standard);
}

.config-hub-card:hover {
  transform: none;
  background: #121827;
  border-color: rgba(255, 255, 255, 0.14);
  box-shadow: var(--e-1);
}

.config-hub-card:hover::before,
.config-hub-card:focus-visible::before {
  opacity: 0.5;
  transform: none;
  filter: none;
}

.config-hub-card:active {
  transform: scale(0.985);
}

.config-hub-card__title {
  font-size: 1.625rem;
  line-height: 1.1;            /* 0,98 rognait les accents sur deux lignes */
  letter-spacing: -0.02em;
}

.config-hub-card__eyebrow {
  color: var(--c-text-3);
  letter-spacing: 0.08em;
}

.config-hub-card__meta {
  color: var(--c-text-2);
}

.config-hub-card:hover .config-hub-card__meta,
.config-hub-card:focus-visible .config-hub-card__meta,
.config-hub-card:hover .config-hub-card__footer,
.config-hub-card:focus-visible .config-hub-card__footer,
.config-hub-card:hover .config-hub-card__badge,
.config-hub-card:focus-visible .config-hub-card__badge {
  transform: none;
}

/* Le lien de pied de carte se lit comme une action */
.config-hub-card__footer {
  border-top-color: var(--c-separator);
  color: var(--c-orange-text);
}

.config-hub-card__badge {
  min-height: 24px;
  border: 0;
  background: var(--c-neutral-tint);
  color: var(--c-text-2);
  letter-spacing: 0;
}

/* --- Configuration : sections de formulaire --- */
.config-section {
  border-color: transparent;
  border-radius: var(--r-lg);
  background: var(--c-surface-2);
  box-shadow: none;
}

.config-section summary,
.config-section__head {
  background: none;
}

.config-section__head {
  border-bottom-color: var(--c-separator);
}

.panel-section {
  border-top-color: var(--c-separator);
}

/* --- KPI --- */
/* Sous-titre de page sur le halo : texte-2 12 px → texte-1 14 px */
.portal-shell .hero-left > p.hint,
.portal-shell .hero-left > .hint.subtle {
  font-size: 0.875rem;
  color: var(--c-text-1);
}

/* Tuiles neutres ; le ton devient une pastille avant le libellé (plus de bordures
   rouge/vert/orange multiples). Le texte de .kpi-card-meta explique le statut. */
.kpi-card,
.kpi-card.tone-good,
.kpi-card.tone-warn,
.kpi-card.tone-bad {
  gap: 6px;
  padding: 14px 16px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: var(--c-surface-2);
  box-shadow: none;
}

.kpi-card-label {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--c-text-2);
}

.kpi-card[class*="tone-"]:not(.tone-neutral) .kpi-card-label::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 8px;
  border-radius: 50%;
  vertical-align: 0.05em;
}

.kpi-card.tone-good .kpi-card-label::before { background: var(--c-success); }
.kpi-card.tone-warn .kpi-card-label::before { background: var(--c-warning); }
.kpi-card.tone-bad .kpi-card-label::before { background: var(--c-danger); }

.kpi-card-value {
  font-size: 1.5rem;
  letter-spacing: -0.01em;
  color: var(--c-text-1);
}

.kpi-card-meta {
  color: var(--c-text-3);
}

/* Alertes KPI : rangées neutres, le verdict (texte) porte la couleur */
.kpi-alert-row,
.kpi-alert-row.is-ok,
.kpi-alert-row.is-alert {
  padding: 12px 16px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--c-surface-2);
}

.kpi-alert-row span {
  font-size: 0.8125rem;
  color: var(--c-text-2);
}

.kpi-alert-row strong {
  font-size: 0.8125rem;
  font-weight: 600;
}

.kpi-alert-row.is-ok strong { color: var(--c-success); }
.kpi-alert-row.is-alert strong { color: var(--c-danger); }


/* ==========================================================================
   LOT 8 — Feuilles modales, chargements, squelettes
   Entrée et sortie interruptibles en CSS seul : transitions (réversibles depuis la valeur
   courante) + @starting-style + display en transition discrète. Les navigateurs anciens
   affichent et masquent sans animation, sans dommage.
   ========================================================================== */

/* Conteneurs-voiles de account-modal / pdf-modal (le conteneur EST le voile) */
.account-modal,
.pdf-modal {
  background: var(--c-scrim);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.modal,
.support-ticket-modal,
.account-modal,
.pdf-modal {
  transition:
    display var(--dur-base) allow-discrete,
    opacity var(--dur-base) var(--ease-out);
}

.account-modal.hidden,
.pdf-modal.hidden {
  opacity: 0;
}

@starting-style {
  .account-modal:not(.hidden),
  .pdf-modal:not(.hidden) {
    opacity: 0;
  }
}

/* Voiles */
.modal .modal-backdrop,
.support-ticket-modal__backdrop {
  transition: opacity var(--dur-base) var(--ease-out);
}

.modal.hidden .modal-backdrop,
.support-ticket-modal.hidden .support-ticket-modal__backdrop {
  opacity: 0;
}

/* Cartes */
.modal .modal-card,
.modal:not(#configInlineModal) .modal-card,
.account-modal-card,
.pdf-modal-card,
.support-ticket-modal__card {
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-spring) var(--ease-spring);
}

.modal.hidden .modal-card,
.account-modal.hidden .account-modal-card,
.pdf-modal.hidden .pdf-modal-card,
.support-ticket-modal.hidden .support-ticket-modal__card {
  opacity: 0;
  transform: translateY(16px) scale(0.98);
  transition-duration: 200ms;
  transition-timing-function: var(--ease-in);
}

@starting-style {
  .modal:not(.hidden) .modal-backdrop,
  .support-ticket-modal:not(.hidden) .support-ticket-modal__backdrop {
    opacity: 0;
  }

  .modal:not(.hidden) .modal-card,
  .account-modal:not(.hidden) .account-modal-card,
  .pdf-modal:not(.hidden) .pdf-modal-card,
  .support-ticket-modal:not(.hidden) .support-ticket-modal__card {
    opacity: 0;
    transform: translateY(16px) scale(0.98);
  }
}

/* L'ancienne animation d'ouverture (keyframe non interruptible) est remplacée */
.modal.modal-opening .modal-card,
.account-modal.modal-opening .account-modal-card,
.pdf-modal.modal-opening .pdf-modal-card {
  animation: none;
}

/* Bouton fermer : neutre (plus de verre orange), 40 px, zone 44 px en tactile */
.btn.modal-close,
.modal:not(#configInlineModal) .btn.modal-close,
.account-modal-card .btn.modal-close,
.pdf-modal-card .btn.modal-close,
#configInlineModal .modal-close {
  width: var(--control-h);
  height: var(--control-h);
  border-color: transparent;
  background: var(--c-surface-3);
  box-shadow: none;
  color: var(--c-text-1);
}

.btn.modal-close:hover:not(:disabled),
#configInlineModal .modal-close:hover {
  background: var(--c-surface-3-hover);
  border-color: transparent;
}

/* Mobile : feuille par le bas, sortie par le bas (même chemin) */
@media (max-width: 720px) {
  .modal:not(#configInlineModal) {
    align-items: flex-end;
    padding-inline: 0;
    padding-bottom: 0;
  }

  .modal:not(#configInlineModal) .modal-card:is(.modal-card, .modal-xl, .modal-restaurant-width, .modal-md, .wide) {
    width: 100%;
    max-width: none;
    max-height: calc(100dvh - 24px);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }

  .modal.hidden .modal-card {
    transform: translateY(100%);
  }

  @starting-style {
    .modal:not(.hidden) .modal-card {
      transform: translateY(100%);
    }
  }
}

/* Chargeur de page (déjà différé de 300 ms par profile-pill.js) : voile plein, pas de flou */
.page-loader {
  background: rgba(7, 11, 20, 0.92);
}

.page-loader__inner {
  border: 1px solid var(--c-separator);
  border-radius: var(--r-lg);
  background: var(--c-surface-1);
  box-shadow: var(--e-3);
}

.page-loader__logo-wrap {
  background: var(--c-surface-3);
  box-shadow: none;
}

.page-loader__spinner,
.modal-loader__spinner {
  border-color: var(--c-neutral-tint);
  border-top-color: var(--c-orange);
}

.page-loader__label {
  letter-spacing: 0;
  color: var(--c-text-2);
}

.modal-loader__pill {
  border-color: var(--c-separator);
  background: var(--c-surface-1);
  box-shadow: var(--e-2);
  color: var(--c-text-1);
  letter-spacing: 0;
}

/* Squelette de chargement réutilisable (classe à poser par le JS sur un bloc aux
   dimensions finales, pour éviter tout saut de mise en page) */
.skeleton {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-sm);
  background: var(--c-surface-2);
  color: transparent;
}

.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.05), transparent);
  transform: translateX(-100%);
  animation: calli-shimmer 1.6s var(--ease-standard) infinite;
}

@keyframes calli-shimmer {
  to {
    transform: translateX(100%);
  }
}


/* ==========================================================================
   Préférences d'accessibilité — composants (lots 3 à 8)
   Placées en fin de fichier pour l'emporter sur toutes les règles de composants.
   Les préférences au niveau des jetons et du fond restent dans le LOT 1 (pas de doublon :
   le LOT 1 change les variables, ce bloc-ci change les composants).
   Mouvement réduit : aucune translation ni mise à l'échelle ajoutée par ce fichier
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .btn:active:not(:disabled),
  .icon-btn:active,
  .chip:active,
  .status-chip:active,
  .hero-actions .cta-open:active,
  .hero-actions .notif-btn:active {
    transform: none;
  }

  .tab-bar .segmented-indicator,
  .view-mode-toggle .segmented-indicator,
  .crm-view-toggle .segmented-indicator,
  .account-tabs .segmented-indicator,
  .segmented .segmented-indicator {
    transition: opacity var(--dur-fast) var(--ease-standard);
  }

  .btn[aria-busy="true"]::after {
    animation-duration: 1.6s;
  }

  /* Lots 6-8 : plus d'appui réduit, fondus seuls pour les menus, toasts et feuilles */
  .portal-float-nav__item:active,
  .portal-float-nav__calli:active,
  .portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__item:active,
  .portal-float-nav:not(.is-expanded):not(.is-mobile-open) .portal-float-nav__calli:active,
  .portal-float-nav__identity:active,
  .portal-float-nav__toggle:active,
  .portal-float-nav__roleview-compact:active,
  .portal-float-nav-mobile-toggle:active,
  .portal-mobile-tabbar__support:active,
  .portal-mobile-tabbar__item:active,
  .config-hub-card:active,
  .crm-kanban-card {
    transform: none;
  }

  .profile-menu.hidden,
  .notif-dropdown.hidden,
  .modal.hidden .modal-card,
  .account-modal.hidden .account-modal-card,
  .pdf-modal.hidden .pdf-modal-card,
  .support-ticket-modal.hidden .support-ticket-modal__card {
    transform: none;
  }

  .toast,
  .toast.show {
    transform: translateX(-50%);
  }

  @starting-style {
    .profile-menu:not(.hidden),
    .notif-dropdown:not(.hidden),
    .modal:not(.hidden) .modal-card,
    .account-modal:not(.hidden) .account-modal-card,
    .pdf-modal:not(.hidden) .pdf-modal-card,
    .support-ticket-modal:not(.hidden) .support-ticket-modal__card {
      transform: none;
    }
  }

  .skeleton::after {
    animation: none;
  }
}

/* Contraste renforcé : surfaces délimitées par un contour net */
@media (prefers-contrast: more) {
  .card,
  .hero-card,
  .stats .stat,
  .admin-cockpit-kpi,
  .admin-cockpit-card,
  .admin-cockpit-mode-card,
  .chip,
  .status-chip,
  .kpi-card,
  .kpi-alert-row,
  .config-section,
  .config-hub-card,
  .crm-kanban-column,
  .crm-kanban-card,
  .crm-list,
  .profile-menu,
  .notif-dropdown,
  .toast {
    border: 1px solid var(--c-border-control);
  }
}

/* 05.10.2026 : champ « Téléphone du commerce » masqué (rappel uniquement, transfert désactivé) — valeur conservée. */
.business-phone-field[hidden] { display: none !important; }

/* ==========================================================================
   11.10.2026 — Liste de réglages (composant réutilisable) et interrupteur harmonisé.
   Même matière que la liste groupée du cockpit (.admin-cockpit-list) : surface-2, rayon md,
   rangées de 56 px, séparateurs en retrait. Premier usage : Compte > Notifications.
   ========================================================================== */
.notifications-prefs { border: 0; padding: 0; background: none; gap: var(--s-4); }
.settings-list { display: grid; gap: var(--s-5); }
.settings-section { display: grid; gap: var(--s-2); }
.settings-section__title {
  margin: 0;
  padding-inline: var(--s-4);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text-2);
}
.settings-group { margin: 0; padding: 0; list-style: none; border-radius: var(--r-md); background: var(--c-surface-2); overflow: hidden; }
.settings-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 56px;
  padding: 12px 16px;
}
.settings-row + .settings-row::before {
  content: "";
  position: absolute;
  top: 0;
  left: 16px;
  right: 0;
  height: 1px;
  background: var(--c-separator);
}
.settings-row--child { padding-inline-start: 40px; }
.settings-row--child::before { left: 40px; }
.settings-row__text { display: grid; gap: 2px; min-width: 0; }
.settings-row__label { font-size: 0.9375rem; font-weight: 500; line-height: 1.3; color: var(--c-text-1); cursor: pointer; }
.settings-row__detail { font-size: 0.8125rem; line-height: 1.35; color: var(--c-text-3); }
.settings-row.is-disabled .settings-row__label { color: var(--c-text-disabled); cursor: not-allowed; }
.settings-note { margin: 0; font-size: 0.8125rem; line-height: 1.4; color: var(--c-text-2); }
.settings-status { margin: 0; min-height: 1.2em; font-size: 0.8125rem; color: var(--c-text-3); }
.settings-status[data-state="saved"] { color: var(--c-success); }

/* Interrupteur (CRM, réglages) : piste neutre, orange quand actif, pastille au ressort. */
.switch { position: relative; flex: none; inline-size: 46px; block-size: 28px; }
.switch input { position: absolute; inset: 0; z-index: 1; inline-size: 100%; block-size: 100%; margin: 0; opacity: 0; cursor: pointer; }
.switch .slider { background: var(--c-neutral-tint); transition: background-color var(--dur-fast) var(--ease-out); }
.switch .slider::before {
  inline-size: 22px;
  block-size: 22px;
  top: 3px;
  left: 3px;
  background: var(--c-thumb);
  box-shadow: var(--e-1);
  transition: transform var(--dur-spring) var(--ease-spring), inline-size var(--dur-fast) var(--ease-out);
}
.switch input:checked + .slider { background: var(--c-orange); }
.switch input:checked + .slider::before { transform: translateX(18px); }
.switch input:active + .slider::before { inline-size: 26px; }
.switch input:checked:active + .slider::before { transform: translateX(14px); }
.switch input:focus-visible + .slider { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.switch input:disabled { cursor: not-allowed; }
.switch input:disabled + .slider { opacity: 0.45; }
@media (prefers-reduced-motion: reduce) {
  .switch .slider, .switch .slider::before { transition: none; }
}
@media (prefers-contrast: more) {
  .switch .slider { outline: 1px solid var(--c-border-control); }
}
