/* ═══════════════════════════════════════════════════════════════════════════
   MIBsoft — RELIEF
   Boutons qui s'enfoncent, champs qui se creusent.

   Michel : « il faut que ça claque, il faut un effet waou […] je veux de la 3D,
   du relief dans les champs, effet creusé, quelque chose qui se démarque de
   tout ce que je vois fait par l'IA. »

   CE QU'ON NE FAIT PAS, ET POURQUOI
   ───────────────────────────────────────────────────────────────────────────
   Les boutons vitrifiés des captures — gros reflet blanc en demi-lune, biseau
   marqué, dégradé du clair au foncé — sont du skeuomorphisme de 2008. Repris
   tels quels, ils ne font pas « neuf » : ils datent la page. Et le dégradé
   violet translucide sur fond flou, c'est précisément ce que produit toute IA
   à qui l'on demande « un beau bouton » ; s'en démarquer, c'est ne pas le
   faire.

   CE QU'ON FAIT À LA PLACE
   ───────────────────────────────────────────────────────────────────────────
   Le relief vient de la LUMIÈRE et du MOUVEMENT, pas du vernis :

     • un socle plein sous le bouton — l'épaisseur d'une vraie touche ;
     • une arête de lumière d'un pixel sur le bord haut, comme sur une pièce
       moulée éclairée par le dessus ;
     • une ombre portée douce et lointaine, qui décolle l'objet du fond ;
     • au clic, le bouton DESCEND sur son socle et le socle disparaît. C'est ce
       déplacement qui fait le « waou » — l'œil ne croit pas à un objet parce
       qu'il brille, il y croit parce qu'il bouge comme un objet.

   Les champs sont l'inverse exact : ombre INTERNE en haut, lumière interne en
   bas. La rainure et la touche partagent la même source lumineuse, sinon
   l'écran se contredit et l'ensemble paraît sale sans qu'on sache dire pourquoi.

   TOUT EST BÂTI SUR « design-tokens.css ». Aucune couleur en dur : changer la
   charte change le relief. Une couleur écrite ici serait une seconde charte,
   et un jour l'une des deux aurait raison.

   COMMENT L'ACTIVER
   ───────────────────────────────────────────────────────────────────────────
   Il suffit d'inclure ce fichier APRÈS mib-design.css. Il ne crée aucune
   classe à poser dans le HTML : il reprend les sélecteurs existants — button,
   .btn-choose, .demo-envoyer, input, select, textarea. Une page déjà écrite
   change d'aspect sans qu'on y touche.
   ═══════════════════════════════════════════════════════════════════════════ */


/* POURQUOI CHAQUE SÉLECTEUR EST PRÉFIXÉ PAR « :root »
   ───────────────────────────────────────────────────────────────────────────
   Sans lui, le relief perdait contre toute règle de même force écrite plus
   loin — « mib-tarifs.css », chargé après, ou le bloc <style> propre à chaque
   page. Mesuré avant correction : 96 % des champs prenaient le relief, mais
   9 % des boutons. Le fichier était pourtant inclus sur les 62 pages, et rien
   ne signalait la différence : elles s'affichaient, simplement sans relief.

   « :root » ajoute un cran de spécificité (0,2,0 au lieu de 0,1,0) : le relief
   l'emporte quel que soit l'ordre de chargement. Un style écrit dans un
   attribut « style= » gagne toujours — c'est voulu : ce sont eux qui portent
   les cas particuliers, comme les boutons-icônes sans fond.
   ─────────────────────────────────────────────────────────────────────────── */
:root {
  /* L'épaisseur du socle. Trois pixels : assez pour se voir, assez peu pour ne
     pas transformer un bouton en brique. */
  --relief-socle: 5px;
  --relief-socle-hover: 7px;
  /* Le socle prend le ton le plus sombre de la charte. En 800 il se confondait
     avec le bouton et l'épaisseur ne se lisait pas : on voyait une bordure, pas
     une tranche. */
  /* LA TRANCHE EST UN NOIR TRANSLUCIDE, ET C'EST LA CLÉ DE TOUT.
     Une tranche verte n'irait qu'aux boutons verts. Les applications ont leurs
     propres couleurs — .btn-green, .btn-blue, .btn-gray — et il aurait fallu
     une tranche par famille, puis une de plus à chaque couleur ajoutée. La
     première oubliée aurait donné un bouton plat au milieu de boutons en
     relief, sans que personne ne sache pourquoi. Du noir à 42 % sous n'importe
     quelle couleur en donne exactement l'ombre. */
  --relief-tranche: rgba(0, 0, 0, 0.42);
  --relief-tranche-neutre: rgba(15, 23, 42, 0.28);

  /* La lumière vient d'en haut. Une seule fois, ici, pour toute la plateforme. */
  /* Deux pixels de lumière au lieu d'un : à un pixel, l'arête disparaît dès
     que l'écran n'est pas parfaitement calibré. */
  --relief-lumiere: inset 0 2px 0 rgba(255, 255, 255, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.9);
  --relief-lumiere-forte: inset 0 2px 0 rgba(255, 255, 255, 0.75), inset 0 1px 0 rgba(255, 255, 255, 1);
  --relief-ombre-interne: inset 0 -2px 0 rgba(0, 0, 0, 0.18);

  /* L'ombre portée : basse et diffuse, pour que l'objet flotte sans halo. */
  --relief-portee: 0 8px 18px -6px rgba(15, 23, 42, 0.38);
  --relief-portee-haute: 0 16px 30px -8px rgba(15, 23, 42, 0.44);

  /* La rainure des champs. */
  /* Quatre couches : l'ombre profonde du fond de rainure, l'ombre courte de la
     lèvre haute, le trait sombre de l'arête, et la lumière de la lèvre basse.
     Avec deux couches seulement on obtenait un champ gris, pas un creux. */
  --relief-creux:
    inset 0 4px 8px rgba(15, 23, 42, 0.20),
    inset 0 2px 3px rgba(15, 23, 42, 0.16),
    inset 0 1px 0 rgba(15, 23, 42, 0.22),
    inset 0 -2px 0 rgba(255, 255, 255, 1);

  --relief-transition: 120ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ───────────────────────────────────────────────────────────────────────────
   LES BOUTONS
   ─────────────────────────────────────────────────────────────────────────── */

:root .btn,
:root .btn-green,
:root .btn-blue,
:root .btn-primary,
:root .btn-login,
:root .btn-nouveau,
:root .btn-logout,
:root .btn-back,
:root .btn-reset,
:root .btn-orange,
:root .btn-retirer,
:root .mib-btn-primary,
:root .mib-btn-lg,
:root .btn-choose,
:root .btn-demo,
:root .demo-envoyer,
:root .btn-relief,
:root button.btn-primary,
:root .mib-btn {
  position: relative;
  border: none;
  border-radius: var(--radius-md, 10px);
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  isolation: isolate;
  overflow: hidden;

  /* Le dégradé est TRÈS court — du clair au ton de base sur les 55 premiers
     pour cent. Un dégradé qui court sur toute la hauteur fait le bouton
     plastique de 2008 ; arrêté tôt, il fait une surface légèrement bombée. */
  /* NI COULEUR NI DÉGRADÉ ICI, et la seconde interdiction est la moins
     évidente. Beaucoup d'applications colorent leur bouton avec
     « background: linear-gradient(...) ». Un « background-image » posé ici,
     plus spécifique, REMPLACE ce dégradé : le bouton perd sa couleur et
     devient transparent. Mesuré sur formateur.html et pricing.html — les
     boutons portaient bien leur socle, mais sur du vide.

     Le bombé est donc obtenu par les seules ombres INTERNES, qui ne touchent
     à aucun fond : une arête de lumière en haut, une ombre en bas. Le relief
     est une matière, pas une couleur — et surtout pas un fond. */

  box-shadow:
    0 var(--relief-socle) 0 var(--relief-tranche),  /* le socle */
    var(--relief-portee),
    var(--relief-lumiere),
    var(--relief-ombre-interne);

  transform: translateY(0);
  transition:
    transform var(--relief-transition),
    box-shadow var(--relief-transition),
    filter var(--relief-transition);
}

/* Nos propres boutons portent la couleur de la charte. Les autres gardent la
   leur. */
:root .btn-choose,
:root .btn-demo,
:root .demo-envoyer,
:root .btn-relief,
:root .mib-btn:not(.secondaire) {
  background-color: var(--vigil-600, #059669);
  /* Ici seulement, parce que nous savons ce qu'il y a dessous. */
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.32) 0%,
    rgba(255, 255, 255, 0.14) 42%,
    rgba(0, 0, 0, 0.02) 68%,
    rgba(0, 0, 0, 0.14) 100%);
  color: #fff;
}

/* Le reflet qui balaie la surface à l'approche. Il ne s'allume pas : il
   TRAVERSE. Un reflet fixe est une décoration, un reflet qui passe est un
   mouvement de lumière sur une surface — c'est ce que fait un objet réel
   qu'on incline. */
:root .btn::after,
:root .btn-green::after,
:root .btn-blue::after,
:root .btn-primary::after,
:root .btn-login::after,
:root .btn-nouveau::after,
:root .btn-logout::after,
:root .btn-back::after,
:root .btn-reset::after,
:root .btn-orange::after,
:root .btn-retirer::after,
:root .mib-btn-primary::after,
:root .mib-btn-lg::after,
:root .btn-choose::after,
:root .btn-demo::after,
:root .demo-envoyer::after,
:root .btn-relief::after,
:root button.btn-primary::after,
:root .mib-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(105deg,
    transparent 35%,
    rgba(255, 255, 255, 0.28) 48%,
    transparent 62%);
  transform: translateX(-120%);
  transition: transform 620ms cubic-bezier(0.25, 0.6, 0.2, 1);
  pointer-events: none;
}

:root .btn:hover::after,
:root .btn-green:hover::after,
:root .btn-blue:hover::after,
:root .btn-primary:hover::after,
:root .btn-login:hover::after,
:root .btn-nouveau:hover::after,
:root .btn-logout:hover::after,
:root .btn-back:hover::after,
:root .btn-reset:hover::after,
:root .btn-orange:hover::after,
:root .btn-retirer:hover::after,
:root .mib-btn-primary:hover::after,
:root .mib-btn-lg:hover::after,
:root .btn-choose:hover::after,
:root .btn-demo:hover::after,
:root .demo-envoyer:hover::after,
:root .btn-relief:hover::after,
:root button.btn-primary:hover::after,
.mib-btn:hover::after { transform: translateX(120%); }

:root .btn:hover,
:root .btn-green:hover,
:root .btn-blue:hover,
:root .btn-primary:hover,
:root .btn-login:hover,
:root .btn-nouveau:hover,
:root .btn-logout:hover,
:root .btn-back:hover,
:root .btn-reset:hover,
:root .btn-orange:hover,
:root .btn-retirer:hover,
:root .mib-btn-primary:hover,
:root .mib-btn-lg:hover,
:root .btn-choose:hover,
:root .btn-demo:hover,
:root .demo-envoyer:hover,
:root .btn-relief:hover,
:root button.btn-primary:hover,
:root .mib-btn:hover {
  /* Le bouton monte ET son socle grandit : c'est ce qui donne la hauteur.
     Monter sans épaissir le socle donnerait un objet qui glisse, pas qui se
     soulève. */
  transform: translateY(-2px);
  box-shadow:
    0 var(--relief-socle-hover) 0 var(--relief-tranche),
    var(--relief-portee-haute),
    var(--relief-lumiere-forte),
    var(--relief-ombre-interne);
  filter: saturate(1.06);
}

:root .btn:active,
:root .btn-green:active,
:root .btn-blue:active,
:root .btn-primary:active,
:root .btn-login:active,
:root .btn-nouveau:active,
:root .btn-logout:active,
:root .btn-back:active,
:root .btn-reset:active,
:root .btn-orange:active,
:root .btn-retirer:active,
:root .mib-btn-primary:active,
:root .mib-btn-lg:active,
:root .btn-choose:active,
:root .btn-demo:active,
:root .demo-envoyer:active,
:root .btn-relief:active,
:root button.btn-primary:active,
:root .mib-btn:active {
  /* L'enfoncement. Le bouton descend EXACTEMENT de l'épaisseur du socle, qui
     tombe à zéro : la touche est au fond de sa course. L'ombre portée se
     resserre parce qu'un objet posé n'a plus d'ombre lointaine. */
  transform: translateY(var(--relief-socle));
  box-shadow:
    0 0 0 var(--relief-tranche),
    0 1px 3px rgba(15, 23, 42, 0.30),
    inset 0 2px 5px rgba(0, 0, 0, 0.22);
  transition-duration: 40ms;   /* l'appui est net, le relâchement est doux */
}

:root .btn:focus-visible,
:root .btn-green:focus-visible,
:root .btn-blue:focus-visible,
:root .btn-primary:focus-visible,
:root .btn-login:focus-visible,
:root .btn-nouveau:focus-visible,
:root .btn-logout:focus-visible,
:root .btn-back:focus-visible,
:root .btn-reset:focus-visible,
:root .btn-orange:focus-visible,
:root .btn-retirer:focus-visible,
:root .mib-btn-primary:focus-visible,
:root .mib-btn-lg:focus-visible,
:root .btn-choose:focus-visible,
:root .btn-demo:focus-visible,
:root .demo-envoyer:focus-visible,
:root .btn-relief:focus-visible,
:root button.btn-primary:focus-visible,
:root .mib-btn:focus-visible {
  outline: none;
  box-shadow:
    0 var(--relief-socle) 0 var(--relief-tranche),
    var(--relief-portee),
    var(--relief-lumiere),
    var(--shadow-focus, 0 0 0 3px rgba(16, 185, 129, 0.25));
}

:root .btn:disabled,
:root .btn-green:disabled,
:root .btn-blue:disabled,
:root .btn-primary:disabled,
:root .btn-login:disabled,
:root .btn-nouveau:disabled,
:root .btn-logout:disabled,
:root .btn-back:disabled,
:root .btn-reset:disabled,
:root .btn-orange:disabled,
:root .btn-retirer:disabled,
:root .mib-btn-primary:disabled,
:root .mib-btn-lg:disabled,
:root .btn-choose:disabled,
:root .demo-envoyer:disabled,
:root .btn-relief:disabled,
:root .mib-btn:disabled {
  /* Désactivé, l'objet est POSÉ : plus de socle, plus d'ombre portée. On le
     voit avant de le lire. Un bouton grisé qui garde son relief invite encore
     au clic. */
  transform: translateY(var(--relief-socle));
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.12);
  background-color: var(--n-300, #CBD5E1);
  background-image: none;
  color: var(--n-500, #64748B);
  cursor: not-allowed;
  filter: none;
}
:root .btn-choose:disabled::after,
:root .demo-envoyer:disabled::after,
.mib-btn:disabled::after { display: none; }

/* Le bouton secondaire : même relief, matière différente. Il ne s'agit pas de
   le rendre fade mais de le rendre AUTRE — un bouton pâle à côté d'un bouton
   coloré se lit comme désactivé. */
:root .btn-contact,
:root .btn-second,
:root .btn-gray,
:root .mib-btn-ghost,
:root .demo-annuler,
:root .btn-relief-neutre,
:root .mib-btn.secondaire {
  background-color: var(--n-100, #F1F5F9);
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.9) 0%,
    rgba(255, 255, 255, 0.35) 55%,
    rgba(15, 23, 42, 0.04) 100%);
  color: var(--text-primary, #0F172A);
  box-shadow:
    0 var(--relief-socle) 0 var(--relief-tranche-neutre),
    var(--relief-portee),
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 -1px 0 rgba(15, 23, 42, 0.08);
}
:root .btn-contact:hover,
:root .demo-annuler:hover,
:root .btn-relief-neutre:hover,
:root .mib-btn.secondaire:hover {
  box-shadow:
    0 var(--relief-socle-hover) 0 var(--relief-tranche-neutre),
    var(--relief-portee-haute),
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 -1px 0 rgba(15, 23, 42, 0.08);
}
:root .btn-contact:active,
:root .demo-annuler:active,
:root .btn-relief-neutre:active,
:root .mib-btn.secondaire:active {
  box-shadow:
    0 0 0 var(--relief-tranche-neutre),
    0 1px 2px rgba(15, 23, 42, 0.2),
    inset 0 2px 5px rgba(15, 23, 42, 0.14);
}

/* ───────────────────────────────────────────────────────────────────────────
   LES CHAMPS — creusés dans la surface
   ─────────────────────────────────────────────────────────────────────────── */

/* « input » sans attribut « type » vaut « text » pour le navigateur, mais
   AUCUN sélecteur « input[type=...] » ne l'atteint. Il y en a 107 dans le
   dépôt : sans cette ligne, un champ sur quatre serait resté plat. */
:root input:not([type]),
:root input[type="text"],
:root input[type="email"],
:root input[type="password"],
:root input[type="search"],
:root input[type="tel"],
:root input[type="url"],
:root input[type="number"],
:root input[type="date"],
:root input[type="time"],
:root select,
:root textarea,
:root .champ-relief {
  border: 1px solid rgba(15, 23, 42, 0.16);
  border-top-color: rgba(15, 23, 42, 0.30);   /* la lèvre haute est plus sombre */
  border-bottom-color: rgba(255, 255, 255, 0.95);
  border-radius: var(--radius-md, 10px);

  /* Un fond LÉGÈREMENT plus sombre que la carte qui le porte : c'est ce qui
     fait le trou. Un champ blanc sur carte blanche ne peut pas être creux,
     quelle que soit l'ombre qu'on lui met. */
  /* Le haut de la rainure est franchement plus sombre que la carte : c'est LUI
     qui crée le trou. À 4 % d'opacité on ne voyait qu'un champ légèrement gris. */
  background: linear-gradient(180deg,
    rgba(15, 23, 42, 0.11) 0%,
    rgba(15, 23, 42, 0.05) 30%,
    rgba(15, 23, 42, 0.01) 62%,
    rgba(255, 255, 255, 0.75) 100%);

  box-shadow: var(--relief-creux);
  color: var(--text-primary, #0F172A);
  transition: box-shadow var(--relief-transition), background var(--relief-transition);
}

:root input::placeholder,
:root textarea::placeholder {
  /* Au fond d'une rainure, la lumière arrive moins : le texte d'exemple doit
     y paraître en retrait, sinon la profondeur n'est pas crédible. */
  color: var(--text-tertiary, #94A3B8);
  opacity: 1;
}

:root input:not([type]):focus,
:root input:focus,
:root select:focus,
:root textarea:focus,
:root .champ-relief:focus {
  outline: none;
  /* Au focus la rainure ne se rebouche pas — elle s'ÉCLAIRE. Un champ qui
     s'aplatit quand on écrit dedans perd sa nature sous les doigts. */
  background: linear-gradient(180deg,
    rgba(15, 23, 42, 0.03) 0%,
    rgba(255, 255, 255, 0.4) 40%,
    rgba(255, 255, 255, 0.8) 100%);
  border-color: var(--vigil-500, #10B981);
  border-top-color: var(--vigil-600, #059669);
  box-shadow:
    inset 0 2px 4px rgba(15, 23, 42, 0.10),
    inset 0 -1px 0 rgba(255, 255, 255, 0.9),
    var(--shadow-focus, 0 0 0 3px rgba(16, 185, 129, 0.25));
}

:root input:disabled,
:root select:disabled,
:root textarea:disabled {
  background: var(--n-100, #F1F5F9);
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.06);
  color: var(--text-tertiary, #94A3B8);
  cursor: not-allowed;
}

/* Le champ en erreur creuse dans du rouge, il ne se contente pas d'un liseré :
   sur un formulaire long, un liseré se rate. */
:root input[aria-invalid="true"],
:root input.en-erreur,
:root textarea.en-erreur {
  border-color: var(--danger-500, #DC2626);
  border-top-color: var(--danger-600, #B91C1C);
  background: linear-gradient(180deg,
    rgba(220, 38, 38, 0.10) 0%,
    rgba(220, 38, 38, 0.03) 40%,
    rgba(255, 255, 255, 0.5) 100%);
}

/* ───────────────────────────────────────────────────────────────────────────
   LES CARTES — surélevées, pas dessinées
   ─────────────────────────────────────────────────────────────────────────── */

:root .plan,
:root .carte-relief {
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 1) inset,
    0 10px 28px -14px rgba(15, 23, 42, 0.30),
    0 2px 6px -2px rgba(15, 23, 42, 0.10);
  transition: transform 220ms cubic-bezier(0.2, 0.7, 0.3, 1),
              box-shadow 220ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
:root .plan:hover,
:root .carte-relief:hover {
  transform: translateY(-4px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 1) inset,
    0 22px 44px -20px rgba(15, 23, 42, 0.38),
    0 4px 10px -4px rgba(15, 23, 42, 0.12);
}

/* La carte mise en avant reçoit un liseré de couleur, PAS une ombre colorée :
   une ombre teintée sous un objet fait toujours un halo de néon, jamais de la
   profondeur. */
:root .plan.featured {
  border-color: var(--vigil-400, #34D399);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 1) inset,
    0 0 0 1px var(--vigil-300, #6EE7B7),
    0 18px 40px -18px rgba(6, 95, 70, 0.35),
    0 3px 8px -3px rgba(15, 23, 42, 0.12);
}

/* ───────────────────────────────────────────────────────────────────────────
   CE QUI SE PASSE QUAND L'ANIMATION N'EST PAS SOUHAITÉE
   ───────────────────────────────────────────────────────────────────────────
   Certaines personnes règlent leur système pour réduire les animations —
   troubles vestibulaires, migraines. Le relief reste, seul le MOUVEMENT
   s'arrête : la profondeur est une information, pas un effet. */
@media (prefers-reduced-motion: reduce) {
  .btn-choose, .btn-demo, .demo-envoyer, .btn-relief, .mib-btn,
  .plan, .carte-relief, input, select, textarea {
    transition: none !important;
  }
  .btn-choose::after, .btn-demo::after, .demo-envoyer::after,
  .btn-relief::after, .mib-btn::after { display: none; }
  .plan:hover, .carte-relief:hover { transform: none; }
}

/* Sur écran tactile il n'y a pas de survol : le reflet ne passerait jamais et
   le bouton resterait plat. On lui donne son relief haut au repos. */
@media (hover: none) {
  .btn-choose, .btn-demo, .demo-envoyer, .btn-relief, .mib-btn {
    box-shadow:
      0 var(--relief-socle) 0 var(--relief-tranche),
      var(--relief-portee-haute),
      var(--relief-lumiere-forte),
      var(--relief-ombre-interne);
  }
}

/* ───────────────────────────────────────────────────────────────────────────
   CE QUI NE DOIT PAS PRENDRE DE RELIEF
   Un socle sous un élément sans fond donne une barre sombre flottant dans le
   vide : l'œil y voit un défaut d'affichage, pas un bouton. On écarte donc les
   liens écrits comme du texte, et l'on pose « .sans-relief » à la main sur les
   cas particuliers — pour n'avoir pas à rouvrir cette feuille au premier
   bouton qui sort du lot.
   ─────────────────────────────────────────────────────────────────────────── */
:root .btn-link,
:root .sans-relief {
  box-shadow: none !important;
  background-image: none !important;
  transform: none !important;
}
:root .btn-link::after,
.sans-relief::after { display: none !important; }
