/* ==========================================================================
   FINITION — resoha.ma, 05/11/2026
   Botuha : « ca ne fait pas assez pro ». La direction visuelle ne change pas
   (nuit #0f2e70, or #c9a961, Playfair + Inter) : ce fichier ne traite que les
   details de fabrication qui separent un modele d'un produit.

   Mesure AVANT, sur les 6 pages, au navigateur (audit_finition.py) :
     - transition: all .................. 42 fois
     - titres sans text-wrap balance .... 81 / 81
     - images sans contour neutre ....... 37 / 37
     - prix non tabulaires .............. 9
     - apparitions animees .............. 0
     - prefers-reduced-motion ........... absent des 6 pages
     - controles sous 44 px au telephone  13

   SPECIFICITE : Tailwind arrive par CDN et pose ses regles a une classe
   (0,1,0). Une regle d'ici qui doit la battre porte donc l'element en plus
   (a.transition = 0,1,1). Aucun !important hors du bloc reduced-motion : si
   une regle ne mord pas, c'est sa specificite qu'il faut corriger.

   NOM DES CLASSES : prefixe `fx-` ou nom compose. Jamais un mot francais
   courant — « appar » aurait ramasse « apparait » a chaque grep de controle.
   ========================================================================== */

/* --- 1. Rendu du texte ---------------------------------------------------
   Les titres Playfair en gros corps paraissent gras et sales sans lissage. */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* balance sur les titres : evite la derniere ligne d'un seul mot.
   pretty sur les textes courts : evite le mot orphelin en fin de paragraphe.
   Ni l'un ni l'autre sur la prose longue, ou ils coutent sans rien donner. */
h1, h2, h3,
.font-serif {
  text-wrap: balance;
}

p, li, dd, figcaption, summary {
  text-wrap: pretty;
}

/* Les chiffres qui se comparent d'une ligne a l'autre ne doivent pas danser.
   `.price` et `.annuel-note` existent deja dans tarifs.html et CHANGENT au
   clic sur Mensuel / Annuel : sans chasse fixe, la colonne saute a chaque
   bascule. C'est la que le reglage se voit le plus. */
.price,
.annuel-note,
.pill,
.fx-tabulaire,
table td, table th {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* --- 2. Mouvement --------------------------------------------------------
   Transitions pour les changements d'etat : elles savent se re-cibler quand
   le curseur change d'avis en cours de route. Images-cles reservees aux
   entrees en une passe.

   `transition: all` anime tout ce qui change, y compris ce qu'on n'a pas
   voulu, et empeche ce re-ciblage. On nomme les proprietes. */
a.transition,
button.transition,
summary.transition,
div.transition,
span.transition,
li.transition {
  transition-property: color, background-color, border-color, box-shadow,
                       transform, opacity;
  transition-duration: 180ms;
  transition-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Etat enfonce : un bouton doit repondre au doigt. Court et discret. */
a[class*="rounded-full"]:active,
button:active {
  transform: scale(0.97);
  transition-duration: 90ms;
}

/* Survol des cartes : une ombre en deux couches porte mieux qu'une seule, et
   reste lisible sur fond blanc comme sur fond brume.

   On vise les cartes PAR CE QU'ELLES FONT DEJA — les 10 elements qui portent
   `hover:shadow-lg` ou `hover:shadow-md` — plutot que d'aller poser une classe
   a la main dans six pages. Un seul endroit a corriger si la regle evolue. */
[class*="hover:shadow"],
.fx-carte {
  transition-property: box-shadow, transform, border-color;
  transition-duration: 220ms;
  transition-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
}
[class*="hover:shadow"]:hover,
.fx-carte:hover {
  transform: translateY(-2px);
  box-shadow: 0 1px 2px rgba(15, 46, 112, 0.06),
              0 12px 28px -8px rgba(15, 46, 112, 0.14);
}

/* Anneau de focus visible au clavier seulement : un clic a la souris ne doit
   pas le declencher, sinon on le supprime et l'accessibilite part avec. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
  outline: 2px solid #0f2e70;
  outline-offset: 2px;
  border-radius: 4px;
}

/* --- 3. Apparition au defilement ----------------------------------------
   Le site posait tout d'un bloc. Les sections montent de 14 px en apparaissant.

   LE CONTENU NE DOIT JAMAIS DEPENDRE DU JS POUR ETRE VU : le masquage ne
   s'applique que sous `.fx-actif`, classe posee par un script synchrone en
   tete de page. Sans JS, sans cette classe, tout reste visible. */
.fx-actif .fx-monte {
  opacity: 0;
  transform: translateY(14px);
  will-change: opacity, transform;
}
.fx-actif .fx-monte.fx-vu {
  opacity: 1;
  transform: none;
  transition-property: opacity, transform;
  transition-duration: 480ms;
  transition-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: auto;
}
/* En grappe : chaque element d'une rangee suit le precedent de 60 ms.
   Au-dela du 7e on n'echelonne plus, sinon le bas de la rangee traine. */
.fx-actif .fx-monte.fx-vu:nth-child(2)  { transition-delay:  60ms; }
.fx-actif .fx-monte.fx-vu:nth-child(3)  { transition-delay: 120ms; }
.fx-actif .fx-monte.fx-vu:nth-child(4)  { transition-delay: 180ms; }
.fx-actif .fx-monte.fx-vu:nth-child(5)  { transition-delay: 240ms; }
.fx-actif .fx-monte.fx-vu:nth-child(6)  { transition-delay: 300ms; }
.fx-actif .fx-monte.fx-vu:nth-child(n+7){ transition-delay: 340ms; }

/* --- 4. Images -----------------------------------------------------------
   Une capture claire sur fond blanc perd son bord. Un contour neutre, jamais
   teinte a la couleur de marque, le rend sans l'encadrer. */
img {
  outline: 1px solid rgba(15, 23, 42, 0.10);
  outline-offset: -1px;
}
/* sauf logos et pictogrammes, qui n'ont pas de bord a tenir */
img.fx-sans-contour,
img[src$=".svg"] {
  outline: none;
}

/* --- 5. Zones tactiles --------------------------------------------------
   Mesure a 375 px : 13 controles sous 44 px, dont une case a cocher de
   13x13. On agrandit la zone atteignable sans grossir ce qui se voit. */
@media (max-width: 767px) {
  /* `#burger` mesurait 42x42 : deux pixels manquaient. `.pill` (les pastilles
     de plan de fonctionnalites.html) et les deux boutons de bascule de
     tarifs.html plafonnaient a 28 et 36 px de haut. */
  #burger,
  .pill,
  #btnMensuel,
  #btnAnnuel,
  .fx-doigt {
    min-height: 44px;
    min-width: 44px;
  }
  /* une pastille garde son texte centre quand on la fait grandir.
     `fx-doigt` EST ICI AUSSI : min-height ne mord pas sur un element en
     ligne. Sans display, la hauteur posee plus haut reste lettre morte. */
  .pill,
  #btnMensuel,
  #btnAnnuel,
  .fx-doigt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* LE PIED DE PAGE AU TELEPHONE (05/11/2026, demande de Botuha).
     Mesure : 10 liens, de 15 a 17 px de haut, espaces de 8 px par
     `ul.space-y-2` — un pas de 25 px, et 10 cibles sous 44 px.

     On porte chaque lien a 44 px et on ABSORBE l'espacement existant : le
     pas passe de 25 a 44 px, pas de 25 a 52. Le pied gagne ~133 px au lieu
     de 189. Sans ca, un pied de 716 px depasserait la hauteur d'un ecran.

     LE RYTHME SE TIENT SUR LA LIGNE, PAS SUR LE LIEN : « Casablanca, Maroc »
     est un <li> SANS lien. Agrandir les seuls liens le laissait a 17 px au
     milieu de voisins a 44, et la colonne Contact partait de travers. On pose
     donc la hauteur sur le <li>, lien ou pas. */
  footer ul li {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
  footer ul li > a {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 44px;
  }
  footer ul.space-y-2 > li + li {
    margin-top: 0;
  }
  /* La ligne du bas (mentions, CGV, confidentialite) tient sur une ligne a
     375 px : on l'epaissit sans la casser.
     LA LARGEUR COMPTE AUSSI : « CGV » faisait 26 px de large pour 44 de haut.
     Un mot court reste une cible etroite tant qu'on ne regarde que la hauteur. */
  footer .space-x-4 > a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
  }

  /* Le logo de l'en-tete est un lien : 64x28, il ramene a l'accueil et se
     vise au pouce comme les autres. */
  header a[href="index.html"],
  header a[href="/"] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* LES QUESTIONS DE LA FAQ (06/11/2026, demande de Botuha).
     Mesure a 375 px : 13 questions depliables. Celles dont le titre passe
     sur deux lignes font 48 px et vont bien ; les 5 qui tiennent sur UNE
     ligne tombent a 293x24. C'est la longueur du titre qui decide de la
     taille de la cible — on ne peut pas s'en remettre a elle.

     `summary` porte deja `flex` et `items-center` dans faq.html : la
     hauteur suffit, le titre et le chevron restent centres. Les 48 px ne
     bougent pas, min-height n'impose qu'un plancher. Aucune autre page du
     site n'a de <summary>, la regle ne porte donc que sur la FAQ. */
  summary {
    min-height: 44px;
  }

  /* LA CASE A COCHER (06/11/2026). `width: 20px` etait deja posee et ne
     mordait pas : mesuree, la case sortait a 13x20. La cause n'est pas la
     specificite — ma regle gagne bien — mais le FLEX. Son etiquette est un
     conteneur flex, la case en est un element, et flex-shrink vaut 1 par
     defaut : le texte long la comprimait de 20 a 13 px sur l'axe horizontal.
     La hauteur, elle, n'est pas sur l'axe de compression, d'ou le 20 intact.
     Le remede est donc flex-shrink, pas une largeur de plus. */
  input[type="checkbox"],
  input[type="radio"] {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
  }
  /* La VRAIE cible est l'etiquette, qui fait 277x44 : c'est elle qu'on
     touche, la case ne fait que montrer l'etat.

     JE NE FORCE PLUS align-items ICI : essai.html pose `items-start` pour
     que le texte, qui tient sur deux lignes, s'aligne en haut avec la case.
     Mon `align-items: center` d'hier ecrasait ce choix sans le dire. On
     laisse la page decider de son alignement et on ne garde que la hauteur. */
  label:has(input[type="checkbox"]),
  label:has(input[type="radio"]) {
    min-height: 44px;
    display: flex;
  }
}

/* --- 6. Qui ne veut pas de mouvement n'en recoit pas -------------------
   Reglage systeme (Windows, Android, iOS). Obligatoire des qu'on anime :
   sans ca, le site impose son mouvement a qui l'a refuse. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .fx-actif .fx-monte,
  .fx-actif .fx-monte.fx-vu {
    opacity: 1;
    transform: none;
    transition: none;
    will-change: auto;
  }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
