/* ============================================================
   ClientBase · Design system de l'ESPACE CONNECTÉ
   ============================================================
   Ce fichier habille tout ce qui est derrière la connexion :
   l'espace professionnel, l'espace client, et la page publique
   de réservation.

   POURQUOI UN FICHIER À PART
   `tokens.css` porte l'histoire du site : la vitrine, ses trois
   couleurs canoniques, et des couches successives (dont un ancien
   habillage « Fresha »). Y ajouter la nouvelle DA aurait mélangé
   deux systèmes. Ici, tout est neuf, et tout est préfixé `e-`
   (pour « espace »). Rien de ce fichier ne peut abîmer la vitrine :
   les tokens sont déclarés sur `.cb-espace`, pas sur `:root`.

   LA DIRECTION ARTISTIQUE, EN CINQ RÈGLES
   1. Le fond n'est jamais blanc : un dégradé pastel très clair,
      fixe, derrière toute la page. C'est lui qui donne la
      profondeur — pas les ombres.
   2. Les panneaux de structure (menu, en-tête) sont du blanc
      translucide avec un flou d'arrière-plan. Ils flottent.
   3. Les cartes de contenu, elles, sont du blanc franc avec une
      bordure fine. Elles portent l'information, elles ne
      décorent pas.
   4. Une seule couleur d'accent : l'indigo de la marque, décliné
      en dégradé vers un violet clair. Les ombres colorées
      remplacent les ombres noires.
   5. Les titres sont gros et serrés, les étiquettes petites et
      espacées. Ce contraste typographique porte la hiérarchie,
      ce qui permet de garder très peu d'éléments à l'écran.
   ============================================================ */

.cb-espace {
  /* --- Couleur --- */
  /* L'indigo est celui du logo (#5A50E6). Le violet clair ne sert
     qu'à terminer les dégradés : jamais seul, jamais en aplat. */
  --e-accent: #5A50E6;
  --e-accent-2: #8B5BFF;
  --e-accent-deep: #3C2FBD;
  --e-grad: linear-gradient(110deg, var(--e-accent), var(--e-accent-2));
  --e-grad-soft: linear-gradient(125deg, #F0EDFF 0%, #F6F1FF 100%);

  /* Teintes dérivées de l'accent. En color-mix : si l'accent
     change un jour, toute l'interface suit. */
  --e-tint: color-mix(in srgb, var(--e-accent) 12%, transparent);
  --e-tint-2: color-mix(in srgb, var(--e-accent) 20%, transparent);
  --e-glow: color-mix(in srgb, var(--e-accent) 40%, transparent);

  /* --- Encre --- */
  --e-ink: #141416;
  --e-ink-2: #45454B;
  --e-sub: #6B6B70;
  --e-ink-4: #9A9AA2;

  /* --- Surfaces --- */
  --e-surface: #FFFFFF;
  --e-panel: rgba(255, 255, 255, 0.82);
  --e-line: #E6E8F2;
  --e-line-2: #F0F1F6;
  --e-hover: #FAFBFE;

  /* --- Statuts --- */
  /* Le vert et le rouge ne servent qu'à dire « c'est bon » et
     « attention ». Jamais en décoration. */
  --e-ok: #2BAB63;
  --e-ok-tint: #E4F7EC;
  --e-warn: #C77A0A;
  --e-warn-tint: #FDF3E2;
  --e-danger: #E0304A;
  --e-danger-tint: #FDECEE;

  /* --- Rayons --- */
  /* Trois valeurs seulement. Au-delà, l'œil ne suit plus. */
  --e-r-card: 14px;    /* cartes de contenu */
  --e-r-panel: 24px;   /* panneaux flottants, modales */
  --e-r-pill: 999px;   /* boutons, étiquettes, filtres */

  /* --- Ombres --- */
  /* Diffuses, teintées de bleu, jamais noires. Une ombre noire
     sur un fond pastel fait sale. */
  --e-sh-card: 0 1px 2px rgba(20, 20, 60, 0.03);
  --e-sh-panel: 0 20px 45px -28px rgba(30, 30, 80, 0.45), 0 2px 8px -4px rgba(30, 30, 80, 0.12);
  --e-sh-lift: 0 14px 30px -16px rgba(30, 30, 80, 0.22);
  --e-sh-accent: 0 10px 22px -10px var(--e-glow);

  /* --- Typographie --- */
  /* Geist pour le CORPS de l'espace : menus, étiquettes, boutons, tableaux,
     formulaires. Variable, donc les vrais poids fonctionnent.

     LES TITRES, EUX, SONT EN COOLVETICA — ET C'EST NORMAL. `tokens.css`
     applique `font-family: var(--ff-display)` à TOUS les h1/h2/h3/h4 du
     site, et --ff-display vaut Coolvetica. Les titres d'ici étant de vrais
     <h1>/<h2>, ils héritent de cette règle et ignorent le --e-ff déclaré
     juste en dessous. Ce n'est pas un accident : c'est la répartition
     d'origine du site (titres condensés et fins, corps neutre et lisible).

     CONSÉQUENCE À NE PAS « CORRIGER » : un font-weight: 700 posé sur un
     <h1> de l'espace ne produit rien de visible, parce que Coolvetica n'a
     qu'un Regular et que le faux-gras est coupé. Pour épaissir un titre,
     il faut soit le sortir de la balise h1/h2, soit lui donner
     explicitement `font-family: var(--e-ff)`. */
  --e-ff: "Geist", -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;

  font-family: var(--e-ff);
  color: var(--e-ink);
  -webkit-font-smoothing: antialiased;
}

/* ============================================================
   1 · LE FOND
   ============================================================
   Posé en `fixed` derrière tout, il passe SOUS l'en-tête flottant.
   Sans lui, la page démarrerait par une bande blanche au-dessus de
   la pilule d'en-tête.
   ============================================================ */
.e-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(180deg, #F1EEFF 0%, #F5F2FF 45%, #FAFAFE 100%);
}
/* Le même dégradé porté par le conteneur lui-même, en filet de sécurité :
   l'élément `fixed` ci-dessus ne couvre que la fenêtre, et si la page est
   plus longue, le bas se retrouvait blanc pendant le rendu (visible aussi
   sur les captures pleine hauteur). `attachment: fixed` garde le dégradé
   calé sur la fenêtre, donc les deux se superposent exactement. */
.cb-espace {
  background: linear-gradient(180deg, #F1EEFF 0%, #F5F2FF 45%, #FAFAFE 100%);
  background-attachment: fixed;
}
/* L'espace client · même construction, mais sur le violet consommateur
   (`--cli-accent`) au lieu de l'indigo pro. Les deux publics ont chacun
   leur couleur depuis le début du projet : on la respecte plutôt que
   d'imposer l'indigo partout. */
.cb-espace-client {
  --e-accent: var(--cli-accent, #8B5BFF);
  --e-accent-2: color-mix(in oklab, var(--cli-accent, #8B5BFF) 68%, #E3D0FF);
  --e-accent-deep: var(--cli-ink, #6B3FD4);
  --e-grad: linear-gradient(110deg, var(--e-accent), var(--e-accent-2));
  --e-grad-soft: linear-gradient(125deg, #F3EDFF 0%, #F8F2FF 100%);
  --e-tint: color-mix(in srgb, var(--cli-accent, #8B5BFF) 12%, transparent);
  background: linear-gradient(180deg, #F4EEFF 0%, #F7F1FF 45%, #FBFAFE 100%);
  background-attachment: fixed;
}
.cb-espace-client .e-bg {
  background: linear-gradient(180deg, #F4EEFF 0%, #F7F1FF 45%, #FBFAFE 100%);
}

/* ============================================================
   LA PAGE PUBLIQUE DE RÉSERVATION
   ============================================================
   Cas particulier : ce n'est pas notre couleur qui commande, c'est celle
   que le professionnel a choisie dans « Ma page ». Le système de thèmes
   existant (`[data-cb-theme]`) redéfinit `--accent` ; on fait donc
   dériver toute la DA de cette variable au lieu de l'indigo ClientBase.

   Conséquence : un pro qui passe sa page en vert obtient des boutons
   verts, un dégradé de fond verdâtre et des étiquettes vertes, sans que
   rien ne soit codé en dur. Et si le thème ne définit rien, on retombe
   sur l'indigo de marque.
   ============================================================ */
.cb-espace-book {
  --e-accent: var(--accent, #5A50E6);
  /* Le second ton du dégradé : la même couleur, éclaircie et pivotée.
     color-mix garde la teinte du pro tout en donnant du relief. */
  --e-accent-2: color-mix(in oklab, var(--accent, #5A50E6) 72%, #C9B6FF);
  --e-accent-deep: color-mix(in oklab, var(--accent, #5A50E6) 78%, #000);
  --e-grad: linear-gradient(110deg, var(--e-accent), var(--e-accent-2));
  --e-grad-soft: linear-gradient(125deg,
    color-mix(in oklab, var(--accent, #5A50E6) 10%, #fff) 0%,
    color-mix(in oklab, var(--accent, #5A50E6) 5%, #fff) 100%);
  /* Fond de page : un voile de la couleur du pro, très dilué. */
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--accent, #5A50E6) 8%, #fff) 0%,
    color-mix(in oklab, var(--accent, #5A50E6) 4%, #fff) 42%,
    #FCFCFE 100%);
  background-attachment: fixed;
}
/* Le pro peut choisir un fond personnalisé (crème, sauge, blush, sombre…)
   dans « Ma page ». Ce réglage écrit `--bg` en !important sur `.cb-booking`
   et doit gagner contre notre dégradé : on s'efface alors.
   `--cb-bg-perso` est posé par BookingThemeStyles quand un fond est choisi. */
.cb-espace-book[data-cb-bg-perso="1"] {
  background: var(--bg);
}
.e-above { position: relative; z-index: 1; }

/* ============================================================
   2 · PANNEAUX FLOTTANTS (en-tête, menu latéral)
   ============================================================ */
.e-panel {
  background: var(--e-panel);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: var(--e-r-panel);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
}
.e-topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  padding: 12px 16px;
}
/* La pilule d'en-tête ne remplit pas toute la hauteur de `.e-topbar` : il
   reste une bande transparente au-dessus (12 px, 20 px sur ordinateur).
   Sur un écran long, le contenu défilait donc À TRAVERS cette bande, bien
   net, au-dessus de l'en-tête — vu d'abord sur « Ma page », dont le
   panneau de réglages fait 4 000 px de haut.
   On floute ce qui passe derrière, avec un masque qui s'estompe vers le
   bas pour ne pas dessiner une arête franche sur le dégradé de fond. */
.e-topbar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
}
.e-topbar-inner {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  /* Le titre collait le bord gauche de la pilule (14 px sur mobile, 22 px
     sur ordinateur, pour un panneau qui fait toute la largeur). Remonté à
     20/32 px : sur un bloc aussi large, il faut plus d'air pour que le
     texte ne semble pas plaqué contre le bord. Demande de Noah,
     27 juillet 2026 — il l'a signalé deux fois, sur les deux tailles. */
  padding: 10px 14px 10px 20px;
  border-radius: var(--e-r-pill);
  background: rgba(255, 255, 255, 0.82);
  border: 1px solid #FFFFFF;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--e-sh-panel);
}
@media (min-width: 768px) {
  .e-topbar { padding: 20px 32px 8px; }
  .e-topbar-inner { padding: 12px 22px 12px 32px; }
}

/* ============================================================
   3 · CARTES DE CONTENU
   ============================================================ */
.e-card {
  background: var(--e-surface);
  border: 1px solid var(--e-line);
  border-radius: var(--e-r-card);
  box-shadow: var(--e-sh-card);
}
/* Une carte cliquable se soulève. 2 px : assez pour être senti,
   pas assez pour sauter. */
.e-card-link {
  cursor: pointer;
  text-align: left;
  width: 100%;
  transition: transform .16s ease, box-shadow .16s ease;
}
.e-card-link:hover { transform: translateY(-2px); box-shadow: var(--e-sh-lift); }
.e-card-link:active { transform: translateY(0); }

/* La carte « mise en avant » : fond pastel dégradé au lieu du blanc.
   Réservée à UN bloc par écran (le prochain rendez-vous, l'objectif
   du mois). Deux, et plus rien ne ressort. */
.e-card-hero {
  background: var(--e-grad-soft);
  border: 1px solid #E3E0F8;
  border-radius: var(--e-r-card);
}
.e-card-pad { padding: 18px; }
@media (min-width: 768px) { .e-card-pad { padding: 20px; } }

/* En-tête de carte : titre à gauche, action à droite, filet dessous. */
.e-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 18px;
  border-bottom: 1px solid var(--e-line-2);
}

/* ============================================================
   4 · TYPOGRAPHIE
   ============================================================
   `e-eyebrow` (petit, capitales, espacé) au-dessus de `e-h1`
   (gros, serré) : c'est ce couple qui donne le côté premium.

   LES TITRES SONT EN COOLVETICA, PAS EN GEIST GRAS · 27 juillet 2026
   Ils étaient tous en Geist 800. Noah : « j'aime pas la police d'écriture
   en gras, je la trouve pas belle ». Il a raison, et le problème est réel :
   Geist est une police d'INTERFACE, dessinée pour être lisible à 13 px.
   Poussée à 800 sur un titre de 28 px, elle devient massive et molle — les
   lettres se touchent, les contreformes se bouchent. Coolvetica est une
   police d'AFFICHAGE : condensée, un seul poids, faite pour les grandes
   tailles. C'est elle qui porte les titres du site depuis toujours ; les
   titres de l'espace connecté n'avaient simplement jamais suivi.

   Le poids 400 n'est donc pas un affaiblissement, c'est le seul poids que
   Coolvetica possède — et le rendu est plus contrasté qu'avant, parce que
   la forme des lettres fait le travail que le gras faisait mal.

   `e-eyebrow` RESTE en Geist gras : à 11 px en capitales espacées, ce
   n'est pas un titre mais une étiquette, et Coolvetica condensée y serait
   illisible. C'est la ligne de partage : la taille, pas le poids.
   ============================================================ */
.e-eyebrow {
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--e-sub);
}
.e-eyebrow-accent { color: var(--e-accent); }
.e-h1 {
  font-family: var(--ff-display);
  font-size: 30px;
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.04;
  color: var(--e-ink);
  margin: 0;
}
.e-h2 {
  font-family: var(--ff-display);
  font-size: 21px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--e-ink);
  margin: 0;
}
.e-h3 {
  font-family: var(--ff-display);
  font-size: 16.5px;
  font-weight: 400;
  letter-spacing: -0.008em;
  color: var(--e-ink);
  margin: 0;
}
.e-sub { font-size: 13.5px; line-height: 1.5; color: var(--e-sub); }
/* Les chiffres ont leur propre police : Sora, via --ff-num (cf. tokens.css).
   Ni la police des titres — condensée, un « 217 € » y devient étroit et se
   confond avec un titre — ni celle du corps de texte. Un montant se lit d'un
   coup d'œil et s'aligne en colonne : c'est un troisième usage. */
.e-num {
  font-family: var(--ff-num);
  font-size: 27px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--e-ink);
}
/* Sur mobile le titre peut grossir : il n'y a rien à sa droite. */
@media (max-width: 767px) {
  .e-h1 { font-size: 32px; letter-spacing: -0.018em; line-height: 1.08; }
}

/* ============================================================
   5 · BOUTONS
   ============================================================
   Tous en pilule. Le primaire est le seul élément en dégradé
   plein de l'écran — c'est ce qui le rend évident.
   ============================================================ */
.e-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 18px;
  border-radius: var(--e-r-pill);
  border: none;
  /* POLICE DE TEXTE · cf. l'explication complète dans tokens.css.
     Les boutons sont passés par Geist 800 (trop gras), puis Coolvetica
     (pas assez lisible), et se posent ici : Geist en 600. Assez marqué
     pour qu'un bouton se distingue, assez neutre pour se lire d'un coup.
     NE PAS remettre la police d'affichage sur les boutons. */
  font-family: var(--e-ff);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  cursor: pointer;
  white-space: nowrap;
  transition: transform .14s ease, background-color .14s ease, box-shadow .14s ease;
}
.e-btn:active { transform: scale(0.97); }
.e-btn-primary {
  background: var(--e-grad);
  color: #fff;
  box-shadow: var(--e-sh-accent);
}
.e-btn-primary:hover { transform: translateY(-1px); }
.e-btn-ghost {
  background: var(--e-surface);
  color: var(--e-ink);
  border: 1.5px solid var(--e-line);
}
.e-btn-ghost:hover { background: var(--e-hover); }
.e-btn-quiet {
  background: #F4F4F6;
  color: var(--e-ink-2);
}
.e-btn-quiet:hover { background: #ECECEE; }
.e-btn-danger { background: var(--e-danger-tint); color: var(--e-danger); }
/* Tailles. 46 px de haut sur mobile : c'est le minimum confortable
   au pouce. */
.e-btn-lg { min-height: 52px; padding: 0 26px; font-size: 15px; width: 100%; }
/* PETITS BOUTONS : RETOUR À GEIST · 27 juillet 2026.
   Noah, sur les pastilles de section de « Ma page » : « on arrive mal à les
   lire ». Il a raison, et c'est ma règle de partage qui était mal appliquée.

   J'avais posé : la taille décide, pas le poids — au-delà de 17 px c'est un
   titre, donc Coolvetica. Mais j'ai mis Coolvetica sur TOUS les boutons, y
   compris les petits. Or un petit bouton n'est pas un titre : c'est une
   étiquette de navigation. À 12,5 px, une display condensée à graisse unique
   perd, surtout en blanc sur indigo et surtout sur un libellé long comme
   « Disponibilités & congés ».

   Les gros boutons gardent Coolvetica (libellés courts, grande taille, ce
   sont de vraies actions). Les petits reviennent à Geist, en 600 : lisible
   sans être le gras massif que Noah n'aime pas. */
.e-btn-sm {
  min-height: 34px; padding: 0 14px;
  font-family: var(--e-ff);
  font-size: 13px; font-weight: 600; letter-spacing: -0.005em;
}
/* Bouton rond, icône seule. */
.e-btn-icon {
  width: 40px;
  min-height: 40px;
  padding: 0;
  border-radius: 50%;
  background: var(--e-surface);
  border: 1px solid var(--e-line);
  color: var(--e-ink-2);
}
.e-btn-icon:hover { background: var(--e-hover); }

/* ============================================================
   6 · ÉTIQUETTES ET PASTILLES
   ============================================================ */
.e-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border-radius: var(--e-r-pill);
  font-size: 11.5px;
  font-weight: 800;
  white-space: nowrap;
}
.e-tag-accent { background: var(--e-tint); color: var(--e-accent-deep); }
.e-tag-grad { background: var(--e-grad); color: #fff; }
.e-tag-ok { background: var(--e-ok-tint); color: var(--e-ok); }
.e-tag-warn { background: var(--e-warn-tint); color: var(--e-warn); }
.e-tag-danger { background: var(--e-danger-tint); color: var(--e-danger); }
.e-tag-quiet { background: #F4F4F6; color: var(--e-sub); }
/* Pastille de 6 px qui précède une statistique. Elle code la
   catégorie sans ajouter de texte. */
.e-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; display: inline-block; }

/* ============================================================
   7 · AVATARS
   ============================================================ */
.e-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  border-radius: 50%;
  background: var(--e-grad);
  color: #fff;
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* ============================================================
   8 · NAVIGATION LATÉRALE (ordinateur)
   ============================================================
   Le repère actif est un trait vertical de 3 px à gauche, plus un
   fond très pâle. Pas de pilule pleine : trop lourd répété huit fois.
   ============================================================ */
.e-nav { display: flex; flex-direction: column; gap: 2px; padding: 10px; }
.e-nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  border: none;
  background: transparent;
  border-radius: 16px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  color: var(--e-sub);
  text-align: left;
  cursor: pointer;
  transition: background-color .14s ease, color .14s ease;
}
.e-nav-item:hover { background: #F2F0FB; color: var(--e-ink-2); }
/* PAS DE BARRE VERTICALE SUR L'ITEM ACTIF · retirée le 27 juillet 2026.
   Noah : « le petit repère, la petite barre à gauche de couleur, je veux bien
   que tu me la supprimes ». Elle faisait doublon : la pastille de fond et
   l'encre plus foncée disent déjà lequel est actif, deux fois. Un troisième
   signal pour la même information, c'est du bruit.
   La pastille est renforcée en compensation (fond un peu plus dense, icône à
   la couleur d'accent) pour que l'état actif reste évident sans la barre.
   ⚠️ Ne pas remettre un ::before ici : c'est une demande explicite. */
.e-nav-item[aria-current="page"] {
  background: #E9E5FC;
  color: var(--e-ink);
}
.e-nav-item[aria-current="page"] svg { color: var(--e-accent); }
.e-nav-label {
  padding: 14px 14px 6px;
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--e-ink-4);
}

/* ============================================================
   9 · BARRE DU BAS (mobile)
   ============================================================
   Quatre onglets et un bouton d'action central surélevé. Le
   `padding-bottom` suit la zone sûre de l'iPhone, sinon la barre
   passe sous l'indicateur d'accueil.
   ============================================================ */
.e-bottomnav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 80;
  display: flex;
  align-items: flex-end;
  justify-content: space-around;
  gap: 4px;
  padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(18px) saturate(1.6);
  -webkit-backdrop-filter: blur(18px) saturate(1.6);
  border-top: 1px solid rgba(20, 20, 60, 0.07);
}
.e-bottomnav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  flex: 1;
  min-width: 0;
  padding: 6px 2px;
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: 10px;
  font-weight: 700;
  color: var(--e-ink-4);
  cursor: pointer;
}
.e-bottomnav-item[aria-current="page"] { color: var(--e-accent); }
.e-bottomnav-fab {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin-bottom: 4px;
  flex: none;
  border: none;
  border-radius: 50%;
  background: var(--e-grad);
  color: #fff;
  cursor: pointer;
  box-shadow: 0 10px 24px -8px var(--e-glow);
}

/* ============================================================
   10 · FORMULAIRES
   ============================================================
   16 px minimum sur mobile : en dessous, iOS zoome au focus et
   l'utilisateur perd la page.
   ============================================================ */
.e-label {
  display: block;
  margin-bottom: 6px;
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--e-sub);
}
.e-input,
.cb-espace input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
.cb-espace select,
.cb-espace textarea {
  width: 100%;
  min-height: 46px;
  padding: 0 13px;
  border: 1px solid #E3E5EE;
  border-radius: 10px;
  background: var(--e-surface);
  font-family: var(--e-ff);
  font-size: 16px;
  color: var(--e-ink);
  outline: none;
  transition: border-color .14s ease, box-shadow .14s ease;
}
.cb-espace textarea { padding: 12px 13px; min-height: 92px; line-height: 1.5; resize: vertical; }
.e-input:focus,
.cb-espace input:focus,
.cb-espace select:focus,
.cb-espace textarea:focus {
  border-color: var(--e-accent);
  box-shadow: 0 0 0 3px var(--e-tint);
}
@media (min-width: 768px) {
  .e-input,
  .cb-espace input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  .cb-espace select,
  .cb-espace textarea { min-height: 42px; font-size: 13.5px; }
}
.e-field + .e-field { margin-top: 16px; }

/* Interrupteur. */
.e-switch {
  position: relative;
  width: 44px; height: 26px;
  flex: none;
  border: none;
  border-radius: var(--e-r-pill);
  background: #E1E1E8;
  cursor: pointer;
  transition: background-color .18s ease;
}
.e-switch[aria-checked="true"] { background: var(--e-accent); }
.e-switch::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
  transition: transform .18s cubic-bezier(0.22, 1, 0.36, 1);
}
.e-switch[aria-checked="true"]::after { transform: translateX(18px); }

/* ============================================================
   11 · LIGNES DE LISTE
   ============================================================
   Aucune bordure verticale, un filet horizontal fin, un survol
   très pâle. C'est ce qui rend une liste longue lisible.
   ============================================================ */
.e-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 46px;
  padding: 12px 16px;
  border: none;
  border-bottom: 1px solid var(--e-line-2);
  background: transparent;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color .12s ease;
}
.e-row:last-child { border-bottom: none; }
.e-row:hover { background: var(--e-hover); }
.e-row-static { cursor: default; }
.e-row-static:hover { background: transparent; }
/* Le texte d'une ligne doit pouvoir se tronquer, sinon un nom long
   pousse la ligne et fait déborder la page à droite. */
.e-row-body { min-width: 0; flex: 1; }
.e-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ============================================================
   12 · ÉTAT VIDE
   ============================================================
   Un compte neuf n'a rien à montrer, et il doit le dire
   franchement : jamais de fausse donnée pour « remplir ».
   ============================================================ */
.e-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 44px 24px;
}
.e-empty-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px; height: 60px;
  margin-bottom: 16px;
  border-radius: 50%;
  background: var(--e-grad-soft);
  color: var(--e-accent);
}
.e-empty-title { font-size: 16px; font-weight: 800; letter-spacing: -0.02em; color: var(--e-ink); }
.e-empty-body { margin-top: 7px; max-width: 380px; font-size: 13px; line-height: 1.55; color: var(--e-sub); }

/* ============================================================
   13 · GRILLES
   ============================================================ */
.e-stats-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (min-width: 768px) { .e-stats-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.e-grid-2 { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
@media (min-width: 900px) { .e-grid-2 { grid-template-columns: minmax(0, 1fr) 330px; gap: 20px; } }

/* Coquille ordinateur : menu fixe à gauche, contenu à droite.
   `align-items: start` pour que le menu reste collé en haut. */
.e-shell {
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  align-items: start;
  gap: 28px;
  max-width: 1480px;
  margin: 0 auto;
  padding: 12px 32px 90px;
}
.e-shell-nav { position: sticky; top: 96px; display: flex; flex-direction: column; gap: 14px; }
/* Sur mobile, plus de grille : une colonne, et de la place en bas
   pour la barre d'onglets. */
.e-shell-mob { padding: 8px 16px 130px; }

/* ============================================================
   14 · MOUVEMENT
   ============================================================
   Une seule animation d'entrée, discrète. Le brief de Noah est
   clair : pas d'animations répétitives et prévisibles.
   ============================================================ */
@keyframes eFadeUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.e-enter { animation: eFadeUp .38s cubic-bezier(0.22, 1, 0.36, 1) both; }

@media (prefers-reduced-motion: reduce) {
  .cb-espace *, .cb-espace *::before, .cb-espace *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* ============================================================
   15 · LA PAGE NE BOUGE PAS LATÉRALEMENT
   ============================================================
   Deux pièges se sont succédé ici, autant les écrire.

   1. `overflow-x: hidden` crée un conteneur de défilement et casse tous
      les `position: sticky` à l'intérieur. C'est le bug qu'on a eu sur
      l'accueil mobile, où l'en-tête collant cessait de suivre.

   2. `overflow-x: clip` ne crée pas de conteneur de défilement — mais il
      établit un BLOC CONTENEUR pour les descendants `position: fixed`.
      Posé sur `.cb-espace`, il transformait donc toute barre fixe
      (barre du bas mobile, carte de fidélité plein écran) en élément
      positionné par rapport au conteneur : la carte était bien dans le
      DOM, simplement invisible à l'écran.

   La règle va donc sur `html`, jamais sur un conteneur intermédiaire —
   c'est aussi ce que fait PrépaEntretien. `overscroll-behavior-x: none`
   supprime en plus le rebond horizontal de Safari sur iPhone.
   ============================================================ */
html {
  overflow-x: clip;
  overscroll-behavior-x: none;
}
.cb-espace {
  max-width: 100%;
}

/* ============================================================
   « MA PAGE » · l'éditeur de la page publique
   ============================================================
   Deux colonnes : l'aperçu téléphone (collé en haut, `order: -1` donc
   affiché à gauche) et le panneau de réglages. L'éditeur n'existe qu'au-
   dessus de 900 px — en dessous, `PageMobileNotice` prend le relais, parce
   qu'un aperçu en direct de 300 px à côté des réglages n'a plus de sens.

   Entre 900 et 1180 px, la colonne des réglages se resserre pour laisser
   le téléphone entier : sinon l'aperçu se faisait rogner, et c'est
   justement la seule chose qu'on vient regarder ici.
   ============================================================ */
@media (max-width: 1180px) {
  .cb-mapage-grid {
    grid-template-columns: minmax(0, 330px) minmax(0, 1fr) !important;
    gap: 18px !important;
  }
}
