/* ClientBase · design tokens */

/* ============================================================
   TYPOGRAPHIE · Coolvetica (titres) + Geist (corps)
   ============================================================
   C'EST LA TYPOGRAPHIE D'ORIGINE DU SITE. Ne pas la remplacer sans
   demande explicite de Noah — elle a déjà fait l'aller-retour deux fois.

   HISTORIQUE, POUR QUE PERSONNE NE REFASSE L'ERREUR
   Le 26 juillet 2026, les titres sont passés en Manrope, puis en Gabarito
   le 27, dans le cadre de l'alignement sur la DA de PrépaEntretien. Le
   même jour j'ai cru revenir « à l'origine » en mettant tout en Geist :
   c'était faux. Geist n'a jamais été que la police de CORPS. Les titres
   du site ont toujours été en Coolvetica. Le 27 juillet au soir, Noah a
   demandé l'état d'avant le 26 : c'est celui-ci.

   RÉPARTITION
   · Titres, chiffres premium, topbar de l'espace pro → Coolvetica
     (auto-hébergée, app/assets/fonts/, un seul poids : Regular 400)
   · Corps, interface, boutons, formulaires → Geist (Google Fonts, variable)
   · Logo → Geist (demande explicite : ne jamais changer la police du logo)
   · Code / valeurs monospace → Geist Mono

   POURQUOI LES TITRES SONT EN POIDS 400
   Coolvetica ne possède qu'un Regular. Un `font-weight: 700` sur un titre
   ferait fabriquer au navigateur un faux-gras baveux. D'où
   `font-synthesis-weight: none` ci-dessous : les titres restent fins même
   si un font-weight élevé traîne dans un style inline. C'est voulu, c'est
   la DA du site — ce n'est pas un bug à « corriger ».

   DEUX FICHIERS CHARGÉS SUR CINQ
   L'original chargeait les 5 .otf (~330 Ko). Les variantes Condensed,
   Crammed et Heavy ont ZÉRO appel dans tout le code (vérifié) : seuls le
   Regular et son Italique sont déclarés ici. Les 3 autres restent sur le
   disque au cas où. Économie : ~198 Ko par visite, à rendu identique.
   ============================================================ */
@font-face {
  font-family: "Coolvetica";
  src: url("/app/assets/fonts/Coolvetica_Rg.otf") format("opentype");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Coolvetica";
  src: url("/app/assets/fonts/Coolvetica_Rg_It.otf") format("opentype");
  font-weight: 400; font-style: italic; font-display: swap;
}

/* Coupe le faux-gras de synthèse (cf. l'explication ci-dessus). Geist étant
   une police variable à vrais poids, elle n'est pas concernée : son gras
   réel continue de s'afficher normalement. */
html { font-synthesis-weight: none; }

:root {
  /* Color · neutrals (warm-tinted, very low chroma) */
  --bg: #FFFFFF;
  --bg-alt: oklch(97.5% 0.003 260);
  /* Gris de démarcation · le fond des sections paires de l'accueil et du
     pied de page. Neutre exprès : Noah, 1er août 2026 — « un gris très clair
     plutôt qu'un bleu ». Deux points de luminosité sous le blanc, c'est ce
     qui se voit sans jamais faire tache. */
  --bg-gris: oklch(96.2% 0.002 260);
  --warn-soft:   oklch(96% 0.025 55);
  --warn-soft-2: oklch(90% 0.05 55);
  --warn-ink:    oklch(45% 0.14 55);
  --bg-section: oklch(98% 0.004 260);
  --surface: #ffffff;
  --ink: oklch(18% 0.012 260);
  --ink-2: oklch(32% 0.015 260);
  --ink-3: oklch(48% 0.012 260);
  --ink-4: oklch(65% 0.01 260);
  --line: oklch(91% 0.005 80);
  --line-strong: oklch(84% 0.007 80);

  /* Accent · ClientBase indigo (matches logo #5A50E6) */
  --accent: oklch(55% 0.22 278);
  --accent-ink: oklch(42% 0.22 278);
  --accent-soft: oklch(96% 0.035 278);
  --accent-soft-2: oklch(92% 0.06 278);
  --accent-strong: #3C2FBD;               /* indigo profond (theme-color, dégradés) */

  /* Status · succès / étoiles / destructif (alignés sur la DA) */
  --success:     #10B981;
  --gold:        #F59E0B;                  /* ★ notes */
  --danger:      oklch(55% 0.18 25);
  --danger-line: oklch(86% 0.06 25);

  /* =========================================================
     PALETTE VITRINE CANONIQUE (2026-05-16)
     -----------------------------------------------------------
     3 couleurs uniquement sur le site marketing : INDIGO (--accent),
     ROSE POUDRÉ (--rose), SAUGE (--sage). Toujours préférer la version
     -soft pour les fonds / hovers. Les neutres (--ink, --line) restent
     pour le texte et la structure. NE PAS ré-introduire teal/orange/
     ambre/lavande dans la vitrine · ces tokens sont conservés pour
     l'espace pro (cartes, badges modules) mais sont marqués legacy.
     =========================================================  */

  /* Sauge · accent calme, naturel. Légèrement éclairci par rapport à l'ancienne valeur
     pour bien lire en contraste avec l'indigo et passer en pastel. */
  --sage: oklch(78% 0.08 160);
  --sage-ink: oklch(40% 0.10 160);
  --sage-soft: oklch(96% 0.025 160);
  --sage-soft-2: oklch(92% 0.05 160);

  --warn: oklch(70% 0.13 55);
  --warn-soft: oklch(96% 0.03 55);

  /* Rose poudré · chaud, doux, accueillant. Désaturé volontairement pour
     éviter le bonbon. Utilisé en accent secondaire et comme couleur
     dominante sur la vitrine client. */
  --rose:        oklch(76% 0.10 12);
  --rose-ink:    oklch(45% 0.12 12);
  --rose-soft:   oklch(97% 0.025 12);
  --rose-soft-2: oklch(93% 0.05 12);

  /* === Legacy · gardés pour compatibilité avec l'espace pro, à NE PAS
     utiliser dans les pages vitrine (home-hero, home-rest, pages-a, pages-b). === */
  --teal:        oklch(55% 0.15 200);
  --teal-ink:    oklch(40% 0.12 200);
  --teal-soft:   oklch(95% 0.04 200);
  --teal-soft-2: oklch(91% 0.07 200);
  --orange:      oklch(64% 0.17 35);
  --orange-ink:  oklch(45% 0.16 35);
  --orange-soft: oklch(96% 0.04 35);
  --orange-soft-2: oklch(92% 0.07 35);
  --ambre:       oklch(72% 0.14 75);
  --ambre-ink:   oklch(50% 0.14 75);
  --ambre-soft:  oklch(96% 0.04 75);
  --ambre-soft-2: oklch(93% 0.08 75);
  --lavande:     oklch(58% 0.16 290);
  --lavande-ink: oklch(45% 0.14 290);
  --lavande-soft: oklch(96% 0.04 290);
  --lavande-soft-2: oklch(92% 0.07 290);

  /* Vitrine · audience switch : 2 teintes voisines pour rester dans la même
     famille (cohérence forte) tout en différenciant l'audience.
     Pro = indigo de marque (oklch hue 278), Client = violet clair (hue 295)
     juste à côté dans la roue chromatique · distinct mais cousin.
     Les neutres et le rose/sauge restent disponibles pour les accents. */
  --cli-accent:   oklch(55% 0.22 295);   /* violet client · aligné DA (consumer) */
  --cli-ink:      oklch(45% 0.18 295);
  --cli-soft:     oklch(96% 0.05 295);
  --cli-soft-2:   oklch(92% 0.06 295);
  --v-pro-accent: var(--accent);
  --v-pro-soft:   var(--accent-soft);
  --v-pro-ink:    var(--accent-ink);
  --v-cli-accent: var(--cli-accent);
  --v-cli-soft:   var(--cli-soft);
  --v-cli-ink:    var(--cli-ink);

  /* Type · Titres = Coolvetica, corps = Geist. Cf. l'en-tête de ce fichier
     pour la répartition complète et l'historique. */
  --ff-display: "Coolvetica", "Geist", -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", system-ui, sans-serif;
  /* Déclinaisons Condensed / Crammed / Heavy : zéro appel dans le code, et
     les .otf correspondants ne sont plus chargés (cf. en-tête). Ces trois
     tokens retombent donc sur le Regular. Gardés pour qu'un appel oublié
     quelque part ne casse rien. */
  --ff-display-cond: var(--ff-display);
  --ff-display-cram: var(--ff-display);
  --ff-display-comp: var(--ff-display);
  --ff-text: "Geist", -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
  --ff-mono: "Geist Mono", "SF Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* --ff-adresse · L'ADRESSE DE RÉSERVATION D'UN PRO, ses liens, ses codes
     et les heures affichées à ses clients. C'était --ff-mono (Geist Mono).
     Noah, 1er août 2026 : « je n'aime pas cette police d'écriture et je veux
     plus l'avoir » — sur la vitrine, dans l'espace pro, et sur les heures de
     la carte « Votre journée ». C'est donc Geist, la police du site, avec des
     chiffres à chasse fixe là où des heures doivent s'aligner
     (font-variant-numeric: tabular-nums, à poser au cas par cas).
     --ff-mono reste, mais UNIQUEMENT pour ce qui est vraiment technique :
     messages d'erreur bruts, blocs de journal, badges de raccourci clavier. */
  --ff-adresse: var(--ff-text);
  /* Chiffres · SORA, et enfin réellement chargée.
     Ce token a menti deux fois. Il annonçait Sora depuis le début alors que
     Sora n'était PAS dans index.html : il retombait donc sur Geist gras. Je
     l'ai ensuite basculé sur Coolvetica, qui a l'inconvénient d'être
     condensée : un « 217 € » y devient étroit et se confond avec un titre.
     Sora est maintenant chargée pour de bon, avec deux graisses.

     POURQUOI UNE POLICE DÉDIÉE AUX CHIFFRES, ET PAS CELLE DES TITRES
     Un compteur (« 14 pros actifs »), un montant (« 217 € »), une
     statistique : ce ne sont ni des titres ni du texte courant. Ils doivent se
     lire d'un coup d'œil, s'aligner en colonne, et ne jamais laisser hésiter
     entre un 1 et un 7 ou entre un 0 et un O. Sora est géométrique, ses
     chiffres sont larges et ouverts, et elle a de vraies figures tabulaires.
     Elle ne sert QUE là : ne pas l'utiliser pour du texte. */
  --ff-num: "Sora", "Geist", -apple-system, "Segoe UI", system-ui, sans-serif;
  /* Alias historique, 14 appels dans l'espace pro. Redevient bien
     Coolvetica, comme son nom l'annonce. */
  --ff-coolvetica: var(--ff-display);
  /* Logo wordmark · conservé en Geist (demande explicite : ne pas changer la police du logo). */
  --ff-logo: "Geist", -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", system-ui, sans-serif;

  /* Space */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px;
  --s-9: 96px; --s-10: 128px;

  /* Radius · coins très arrondis (DA) : cartes 16-24, images 22-28, pilules 999 */
  --r-1: 6px; --r-2: 10px; --r-3: 14px; --r-4: 20px;
  --r-card: 18px; --r-card-lg: 24px; --r-pill: 999px;

  /* Shadow · barely-there */
  --sh-1: 0 1px 2px rgba(15, 18, 30, 0.04), 0 1px 1px rgba(15, 18, 30, 0.02);
  --sh-2: 0 6px 18px -6px rgba(15, 18, 30, 0.10), 0 2px 4px rgba(15, 18, 30, 0.04);
  --sh-3: 0 24px 48px -18px rgba(15, 18, 30, 0.18), 0 6px 14px rgba(15, 18, 30, 0.05);

  --container: 1200px;
}

/* Warm theme variant */
:root[data-theme="warm"] {
  --bg: oklch(98.2% 0.012 70);
  --bg-alt: oklch(95.8% 0.02 70);
  --bg-gris: oklch(95.4% 0.012 70);
  --bg-section: oklch(96.8% 0.015 70);
  --accent: oklch(58% 0.13 40);
  --accent-ink: oklch(42% 0.13 40);
  --accent-soft: oklch(96% 0.035 40);
  --accent-soft-2: oklch(92% 0.06 40);
}

/* Dark theme variant */
:root[data-theme="dark"] {
  --bg: oklch(16% 0.012 260);
  --bg-alt: oklch(20% 0.014 260);
  --bg-gris: oklch(19% 0.012 260);
  --bg-section: oklch(18% 0.013 260);
  --surface: oklch(22% 0.015 260);
  --ink: oklch(98% 0.005 80);
  --ink-2: oklch(88% 0.006 80);
  --ink-3: oklch(70% 0.008 80);
  --ink-4: oklch(55% 0.01 80);
  --line: oklch(28% 0.015 260);
  --line-strong: oklch(38% 0.02 260);
  --accent: oklch(72% 0.16 268);
  --accent-ink: oklch(82% 0.14 268);
  --accent-soft: oklch(28% 0.08 268);
  --accent-soft-2: oklch(34% 0.12 268);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }
/* Touch feedback without the grey rectangle flash */
button, a, [role="button"], .btn {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--ff-text);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  letter-spacing: -0.005em;
}

/* Titres = Coolvetica au poids naturel (400) + tracking serré.

   LE POIDS 400 EST VOLONTAIRE, PAS UN OUBLI. Coolvetica ne possède que ce
   poids ; demander 700 ne donnerait qu'un faux-gras, qu'on désactive de
   toute façon (font-synthesis-weight, en haut du fichier). La DA du site
   repose sur des titres GRANDS et FINS, pas sur du gras.

   LES TAILLES SONT PLUS GÉNÉREUSES QU'AVEC UNE POLICE NORMALE (72 px sur
   h1) parce que Coolvetica est condensée : à taille égale elle occupe
   moins de largeur. Si un jour la police change, il faut redescendre ces
   tailles, sinon les titres débordent. C'est exactement ce qui s'est passé
   les 26 et 27 juillet. */
h1, h2, h3, h4 {
  font-family: var(--ff-display);
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: clamp(44px, 5.2vw, 72px); line-height: 0.98; letter-spacing: -0.015em; font-weight: 400; }
h2 { font-size: clamp(32px, 3.4vw, 46px); line-height: 1.0;  letter-spacing: -0.012em; font-weight: 400; }
h3 { font-size: 22px; line-height: 1.2; letter-spacing: -0.006em; font-weight: 400; }
h4 { font-size: 17px; line-height: 1.3; letter-spacing: 0; font-weight: 400; }
p  { margin: 0; color: var(--ink-2); text-wrap: pretty; }
a  { color: inherit; text-decoration: none; }

/* Prevent iOS Safari from zooming into focused form fields.
   iOS triggers the zoom when the input's computed font-size is < 16px. */
@media (max-width: 768px) {
  input, select, textarea {
    font-size: 16px !important;
  }
}

.eyebrow {
  font-size: 13px;
  color: var(--accent-ink);
  font-weight: 580;
  letter-spacing: -0.005em;
}
.muted { color: var(--ink-3); }
.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

/* Animation du dot pulsant utilisée par les boutons « Voir la démo »
   (vitrine pro et vitrine client). Définie globalement pour rester
   accessible quelle que soit la page rendue. */
@keyframes cbDemoDot {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in oklab, var(--sage) 25%, transparent); }
  50%      { box-shadow: 0 0 0 6px color-mix(in oklab, var(--sage) 10%, transparent); }
}

/* Bouton « Voir la démo » · style partagé vitrine pro + vitrine client.
   Défini globalement pour que le hover marche sur toutes les pages. */
.cb-demo-btn {
  transition: transform .14s ease, box-shadow .2s ease, background .15s ease;
}
.cb-demo-btn:hover {
  transform: translateY(-2px);
  background: color-mix(in oklab, var(--sage) 22%, var(--surface)) !important;
  box-shadow: 0 14px 30px -12px color-mix(in oklab, var(--sage) 70%, transparent) !important;
}

/* Global smooth scroll + focus ring */
html {
  scroll-behavior: smooth;
  /* LA PLACE DE LA BARRE DE DÉFILEMENT EST TOUJOURS RÉSERVÉE · 27 juillet 2026.

     Noah : « quand on passe de Accueil à Rendez-vous dans le compte client,
     j'ai l'impression que la page s'élargit légèrement ».

     Ce n'était pas une impression, et ce n'était pas la mise en page : j'ai
     mesuré les deux écrans, tous les conteneurs font exactement la même
     largeur (1440 et 1376 px, identiques). La différence est la HAUTEUR —
     Accueil tient dans la fenêtre (900 px), Rendez-vous non (1478 px). La
     barre de défilement apparaît donc en arrivant sur Rendez-vous, prend une
     quinzaine de pixels, et tout le contenu centré se décale. C'est le
     mouvement qu'il voyait.

     `scrollbar-gutter: stable` réserve la gouttière en permanence : la
     largeur utile ne change plus jamais d'un écran à l'autre, sur tout le
     site et pas seulement ici. Le coût est une bande de 15 px sur les pages
     qui ne défilent pas ; le bénéfice est qu'aucune navigation ne fait plus
     sauter la mise en page. */
  scrollbar-gutter: stable;
}
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
  transition: outline-offset .15s ease;
}

/* Liens cliquables dans le texte */
a { transition: color .15s ease, opacity .15s ease; }
a:hover { opacity: 0.82; }

/* Inputs · focus animé */
input, select, textarea {
  transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent) !important;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 44px; padding: 0 20px;
  border-radius: var(--r-pill, 999px);
  /* LIBELLÉS DE BOUTONS · POLICE DE TEXTE, PAS LA DISPLAY.

     J'avais mis Coolvetica sur tous les boutons le matin du 27 juillet, en
     me disant qu'un libellé de bouton est un petit titre. Noah a tranché le
     soir même : « je ne veux plus que dans les boutons ce soit celle-là ».

     Il a raison et l'argument est simple : un bouton se CLIQUE, il ne se
     contemple pas. Une display condensée à graisse unique y gagne en
     caractère ce qu'elle perd en lisibilité immédiate — et sur un libellé
     long (« Créer mon compte gratuit », « Voir la démo client ») la
     condensation devient franchement gênante.

     La police d'affichage reste où elle a un sens : les titres et les
     grands chiffres. NE PAS LA REMETTRE SUR LES BOUTONS. */
  font-family: var(--ff-text);
  font-size: 15px; font-weight: 600;
  letter-spacing: -0.005em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform .22s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow .22s cubic-bezier(0.22, 1, 0.36, 1),
              background-color .18s ease,
              border-color .18s ease,
              color .18s ease,
              opacity .18s ease;
  white-space: nowrap;
  will-change: transform;
}
.btn:active { transform: translateY(1px) scale(0.98); transition-duration: .08s; }
.btn:disabled { cursor: not-allowed; opacity: 0.6; }
.btn-primary {
  background: var(--ink);
  color: var(--bg);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: var(--sh-2); }
.btn-accent {
  background: var(--accent);
  color: white;
}
.btn-accent:hover { transform: translateY(-2px); box-shadow: 0 14px 32px -10px var(--accent); }
.btn-ghost {
  background: transparent; color: var(--ink);
  border-color: var(--line-strong);
}
.btn-ghost:hover { background: var(--bg-alt); border-color: var(--ink-4); transform: translateY(-1px); }
.cb-btn-destructive { color: var(--danger); border-color: var(--danger-line); margin-right: auto; }
.cb-btn-destructive:hover { background: oklch(97% 0.025 25); border-color: oklch(70% 0.16 25); color: oklch(48% 0.20 25); transform: translateY(-1px); }
/* Bouton plein destructif · 31 juillet 2026.
   Les écrans « réinitialiser » et « supprimer mon compte » se peignaient
   chacun leur rouge à la main, avec quatre valeurs oklch écrites dans le
   JSX et introuvables ailleurs. Résultat : deux rouges légèrement
   différents, aucun des deux aligné sur --danger, et un écran qui ne
   ressemblait plus au reste du site. Une classe, les tokens de la DA, et
   les mêmes gestes de survol que les autres boutons. */
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 14px 32px -12px var(--danger); }
.btn-danger:disabled { background: var(--bg-alt); color: var(--ink-4); }
.btn-lg { height: 52px; padding: 0 26px; font-size: 15.5px; border-radius: var(--r-pill, 999px); }
/* Petits boutons de la vitrine : Geist, pas la display condensée.
   Même raison que .e-btn-sm dans espace.css — un petit bouton est une
   étiquette, pas un titre, et une condensée à graisse unique y perd en
   lisibilité. Les gros boutons gardent la display. */
.btn-sm {
  height: 36px; padding: 0 16px; border-radius: var(--r-pill, 999px);
  font-family: var(--ff-text);
  font-size: 13.5px; font-weight: 600; letter-spacing: -0.005em;
}

/* Utility */
.hstack { display: flex; align-items: center; gap: var(--s-3); }
.vstack { display: flex; flex-direction: column; gap: var(--s-3); }
.grid   { display: grid; gap: var(--s-5); }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card, 18px);
  transition: transform .3s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow .3s cubic-bezier(0.22, 1, 0.36, 1),
              border-color .2s ease;
}

/* Liens de navigation · l'état actif est géré en JSX (pill background) */

/* Transition de page · fade-in léger au changement de route */
@keyframes cbPageIn {
  from { opacity: 0; transform: translateY(6px) scale(0.995); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
main[data-screen-label] {
  animation: cbPageIn .32s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Mobile · press feedback sur tous les éléments tactiles */
@media (hover: none) and (pointer: coarse) {
  .btn:active,
  button:active,
  [role="button"]:active {
    transform: scale(0.97);
    transition-duration: 0.08s;
  }
}

/* Respecter la préférence système "reduce motion" */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

.section { padding: var(--s-10) 0; }
.section-sm { padding: var(--s-8) 0; }

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px 5px 8px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: 12.5px; font-weight: 500;
  border: 1px solid var(--accent-soft-2);
}
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

.kbd {
  font-family: var(--ff-mono);
  font-size: 11.5px;
  padding: 2px 6px;
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--surface);
  color: var(--ink-2);
}

/* Divider line */
.hr { height: 1px; background: var(--line); border: 0; margin: 0; }

/* Focus */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* Scrollbar light touch */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 10px; }
::-webkit-scrollbar-track { background: transparent; }

/* ============================================================
   DA Fresha/iOS/Airbnb · espace pro (juin 2026)
   Implémentation du design kit Claude Design.
   Pattern : floating white card on soft canvas, sidebar transparente,
   sélection cellule élevée, CTA noir pill, Coolvetica sur les titres.
   Helpers cb-fresha-* utilisables dans tout l'espace pro.
   ============================================================ */

/* Layout shell plein écran : le contenu occupe toute la zone disponible,
   sans marges visibles ni effet de carte flottante. */
.cb-fresha-frame {
  display: flex; height: 100vh;
  padding: 0; gap: 0;
  background: var(--bg-section);
}
.cb-fresha-maincard {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
  background: var(--surface);
  border: none;
  border-left: 1px solid var(--line);
  border-radius: 0;
  overflow: hidden;
  box-shadow: none;
}

/* Boutons Fresha-style (pill 999, CTA principal noir signature) */
.cb-fresha-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 44px; padding: 0 18px;
  border-radius: 999px;
  font-family: var(--ff-text);
  font-size: 14px; font-weight: 560; letter-spacing: -0.005em;
  border: 1px solid transparent;
  cursor: pointer; white-space: nowrap;
  transition: transform .18s cubic-bezier(.22,1,.36,1), box-shadow .18s, background .15s, border-color .15s;
}
.cb-fresha-btn:active { transform: scale(0.97); }
.cb-fresha-btn-sm { height: 38px; padding: 0 15px; font-size: 13.5px; }
.cb-fresha-btn-accent {
  background: var(--ink);  /* CTA NOIR signature Fresha */
  color: #fff;
}
.cb-fresha-btn-accent:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 26px -12px rgba(15, 18, 30, 0.5);
}
.cb-fresha-btn-ghost {
  background: var(--surface); color: var(--ink);
  border-color: var(--line-strong);
}
.cb-fresha-btn-ghost:hover {
  background: var(--bg-alt);
  border-color: var(--ink-4);
}

/* Bouton icône rond ghost (topbar notif, etc.) */
.cb-fresha-icon-btn {
  position: relative;
  width: 40px; height: 40px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-3);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s;
}
.cb-fresha-icon-btn:hover {
  background: var(--bg-alt);
  color: var(--ink);
}

/* Card sobre Fresha-style */
.cb-fresha-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 18px;
}

/* Quick action row (boutons rapides Accueil) */
.cb-fresha-quick {
  display: flex; align-items: center; gap: 11px;
  width: 100%;
  padding: 13px 15px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  font-family: inherit;
  font-size: 13.5px; font-weight: 540;
  color: var(--ink-2);
  transition: border-color .15s, background .15s, transform .12s;
}
.cb-fresha-quick:hover {
  border-color: var(--ink);
  background: var(--bg-alt);
  color: var(--ink);
  transform: translateY(-1px);
}
.cb-fresha-quick svg:first-child { color: var(--accent); }

/* NavCell · item sidebar : actif = white elevated cell (signature iOS) */
.cb-fresha-navcell {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 10px 12px;
  border-radius: 13px;
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 14.5px;
  text-align: left;
  background: transparent;
  color: var(--ink-2);
  transition: background .16s, color .16s, box-shadow .16s;
}
.cb-fresha-navcell:hover:not([data-on="true"]) {
  background: color-mix(in oklab, var(--surface) 60%, transparent);
}
.cb-fresha-navcell[data-on="true"] {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: 600;
}
.cb-fresha-navcell[data-on="true"] .cb-fresha-navcell-icon {
  color: var(--accent);
}
.cb-fresha-navcell-icon {
  color: var(--ink-3);
  transition: color .16s;
}

/* Label de groupe sidebar */
.cb-fresha-navgroup-label {
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--ink-4);
  padding: 2px 12px 8px;
}

/* Search pill (topbar) */
.cb-fresha-search {
  display: flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 14px;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-4);
  font-size: 13.5px;
  width: 240px;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.cb-fresha-search:hover {
  background: var(--surface);
  border-color: var(--line-strong);
}
.cb-fresha-search-kbd {
  margin-left: auto;
  font-family: var(--ff-mono);
  font-size: 11px;
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  padding: 1px 5px;
}

/* Title de page Coolvetica · line-height généreux + padding bas pour ne PAS
   couper les jambages (j, g, p) de Coolvetica avec un overflow:hidden. */
.cb-fresha-title {
  font-family: var(--ff-coolvetica);
  font-size: 26px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--ink);
  line-height: 1.3;
  padding-bottom: 2px;
}

/* Account row au bas de la sidebar */
.cb-fresha-account {
  display: flex; align-items: center; gap: 11px;
  width: 100%;
  padding: 9px 11px;
  margin-top: 4px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  font-family: inherit;
  box-shadow: var(--sh-1);
  transition: background .14s;
}
.cb-fresha-account:hover { background: var(--bg-alt); }
.cb-fresha-account-avatar {
  width: 34px; height: 34px; border-radius: 11px;
  flex-shrink: 0;
  background: linear-gradient(135deg, oklch(91% 0.05 278), oklch(74% 0.10 282));
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--ff-display);
  font-size: 16px; font-weight: 600;
}

/* ============================================================
   Print · nimprimer que la facture
   Active : un parent ajoute la classe .cb-print-invoice à <body>,
   ou on cible directement #cb-invoice-print quand lutilisateur lance window.print().
   ============================================================ */
@media print {
  /* Cache toute lapp */
  body * { visibility: hidden !important; }
  /* Affiche uniquement la facture imprimable et ses descendants */
  #cb-invoice-print, #cb-invoice-print * { visibility: visible !important; }
  /* Sort la facture du flux modal/overlay et laffiche en pleine page */
  #cb-invoice-print {
    position: absolute !important;
    top: 0; left: 0;
    width: 100%;
    margin: 0 !important;
    padding: 24mm 18mm !important;
    border: none !important;
    border-radius: 0 !important;
    background: white !important;
    color: #111 !important;
    box-shadow: none !important;
  }
  /* Marges papier A4 raisonnables */
  @page { size: A4; margin: 12mm; }
  /* Retire les overlays/modale autour */
  .cb-modal-overlay, .cb-modal-shell { background: transparent !important; box-shadow: none !important; padding: 0 !important; }
}

/* ============================================================
   Bannière démo (pro + client) · masque le message sur mobile
   pour laisser de la place aux CTAs "Créer mon compte" + "Quitter"
   ============================================================ */
@media (max-width: 600px) {
  .cb-demo-msg { display: none !important; }
}
