/* ==========================================================================
   Thème du site, palette de marque
   ==========================================================================

   Chargé APRÈS taga.webflow.css dans layout.tsx.
   À spécificité égale, la dernière déclaration gagne : redéfinir une variable
   ici suffit, sans toucher au CSS Webflow d'origine.

   Ne pas modifier les couleurs dans le fichier Webflow : la valeur définie ici
   la remplacerait silencieusement. Tout se passe dans ce fichier.

   --------------------------------------------------------------------------
   MÉTHODE
   --------------------------------------------------------------------------
   Couleur de base demandée : #117C78 = hsl(178, 76%, 28%).
   Les couleurs compagnes sont dérivées de cette teinte 178, pas choisies à
   l'œil, puis leur luminosité est résolue pour le seuil WCAG que leur rôle
   réel impose dans cette feuille de style.

   Tons sombres : la luminosité d'origine est conservée, seule la teinte est
   réalignée. Les valeurs Webflow dépassaient déjà largement AAA ; les
   « ramener » vers un seuil aurait dégradé la lisibilité, pas l'inverse.
   ========================================================================== */

:root {
  /* ------------------------------------------------------------------------
     Échelle tonale de la teinte 178, non utilisée par le CSS Webflow.
     Disponible pour les prochains ajustements : nuances de survol, bordures,
     fonds de section. Contraste indiqué face au blanc.
     ------------------------------------------------------------------------ */
  --brand-50: #f1fbfb;   /*  1.05:1  fond de section très clair */
  --brand-100: #dff9f8;  /*  1.10:1  fond clair, badges */
  --brand-200: #bdf2f0;  /*  1.23:1  bordures, séparateurs */
  --brand-300: #8be4e1;  /*  1.47:1  états désactivés */
  --brand-400: #3edad5;  /*  1.72:1  décoratif uniquement */
  --brand-500: #1dafab;  /*  2.70:1  décoratif, insuffisant pour du texte */
  --brand-600: #117c78;  /*  5.03:1  COULEUR DE BASE */
  --brand-700: #0c6461;  /*  6.97:1  survol du primaire */
  --brand-800: #084947;  /* 10.22:1  texte sur fond clair */
  --brand-900: #042f2d;  /* 14.49:1  titres */
  --brand-950: #011b1a;  /* 17.90:1  fonds sombres */

  /* ------------------------------------------------------------------------
     Variables réellement consommées par le CSS Webflow
     ------------------------------------------------------------------------ */

  /* Couleur de base. 41 usages : boutons principaux, bandeau CTA, hover des
     liens, blocs de contact.
     Webflow : #025747 */
  --_colors---color--primary-color: #117c78;

  /* Nom Webflow trompeur : ce n'est plus un jaune. Double rôle, 17 usages, 
     texte sur fond primaire (.primary-button, .contact-submit) ET surface
     teintée (.navbar-menu-wrap, .contact-single-block, .secondary-button).
     Les deux rôles imposent la MÊME paire de contraste face au primaire,
     puisque .secondary-button inverse simplement fond et texte.
     Plafond structurel : sur #117C78, même du blanc pur ne dépasse pas
     5,03:1. Cette valeur atteint 4,66:1 tout en restant visiblement aqua
     (1,08:1 face au blanc).
     Webflow : #e4ffb8 (vert-jaune pâle) */
  --_colors---color--light-yellow-color: #e4fbfa;

  /* Accent sémantique. 2 usages, dont .less-price (prix affiché en texte).
     CORRIGE UNE ERREUR D'ACCESSIBILITÉ DU TEMPLATE : le #46ca83 d'origine ne
     donnait que 2,09:1 sur blanc, très en dessous des 4,5:1 requis pour du
     texte. Teinte décalée à 158 pour se distinguer du primaire tout en
     restant dans la même famille. Désormais 4,64:1.
     Webflow : #46ca83 */
  --_colors---color--accent-color: #1f845f;

  /* Fond sombre (.footer-section). Réalignement de teinte uniquement :
     l'écart avec l'original est imperceptible à l'œil, il ne sert que la
     cohérence de la palette. Texte blanc dessus : 20,04:1.
     Webflow : #000a08 */
  --_colors---color--black-bg: #000a0a;

  /* Texte principal. 64 usages : body, h1-h6, liens. Même remarque :
     réalignement de teinte, différence imperceptible, lisibilité préservée
     à 19,62:1 sur blanc.
     Webflow : #010c0a */
  --_colors---color--black-text-color: #010e0e;

  /* Texte secondaire, 17 usages. Même couleur que ci-dessus à 70% d'opacité.
     Réaligné pour rester cohérent avec le texte principal.
     Webflow : #010c0ab3 */
  --_colors---color--dark-text-primary: #010e0eb3;
}

/* ==========================================================================
   BANDE DÉFILANTE, COMTÉS ET SERVICES
   ==========================================================================

   Le template y plaçait six lockups gris d'entreprises inventées, en guise de
   « nos partenaires ». Les slots portent désormais les comtés et les services.

   L'animation n'est pas touchée : IX2 se déclenche sur `.marquee-section` par
   classe et translate chaque `.marquee-single-wrap` de 0 à −100 % sur 25 s.
   Aucun `data-w-id` n'entre en jeu, donc changer le contenu des slots est sans
   effet sur le défilement.

   `.marquee-logo-wrap` était calibré pour une image (`max-width: 133px`) : le
   texte doit définir sa propre largeur, sinon les libellés se rognent.
   ========================================================================== */

.marquee-logo-wrap.taga-marquee-item {
  display: flex;
  align-items: center;
  gap: 26px;
  width: auto;
  max-width: none;
  /* La marge d'origine était énorme (spacing-massive) pour espacer des logos ;
     le point de séparation joue ce rôle plus proprement pour du texte. */
  margin-right: 26px;
}

.taga-marquee-text {
  font-family: var(--_typography---font-family--secondary-font);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--_colors---color--primary-color);
}

.taga-marquee-dot {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background-color: var(--_colors---color--accent-color);
}

/* ==========================================================================
   ZONE DESSERVIE, CARTE ET BULLES DE COMTÉ
   ==========================================================================

   Le template affichait une carte du monde en pointillés avec les 5 cartes
   positionnées en absolu : `_01 { top: 24px; left: 309px }` et compagnie
   correspondaient à Dubaï, Sydney, Singapour, Londres et Toronto sur ce
   planisphère. Les coordonnées ne voulaient donc rien dire pour quatre comtés
   de l'Indiana, mais la DISPOSITION, elle, restait bonne. On ne remplace que
   la carte et les coordonnées, pas le principe.

   Carte : `indiana-service-area.svg`, composée depuis les fonds de carte de
   comté du domaine public de David Benbennick (Wikimedia Commons). Les 92
   comtés en tint clair, les 4 desservis en couleur primaire, halo pulsé au
   centre. Elle est en format portrait (ratio 0,654) : posée au centre du bloc,
   elle laisse ~490 px de gouttière de chaque côté à 1350 px de conteneur, où
   les bulles de 318 px se placent sans jamais recouvrir la carte.

   Les décalages horizontaux sont volontairement inégaux (0, 2 %, 0 à gauche ;
   0, 1,5 % à droite) : c'est ce qui donnait au template son aspect dispersé
   plutôt que tabulaire.

   Sous 992 px le template passe de lui-même en grille 2 colonnes avec les
   blocs en `position: static` ; on garde ce comportement et on retire
   simplement le planisphère qu'il posait en `background-image`.

   La forme signature de la bulle est conservée
   (`border-radius: 100px 60px 8px 100px`) ; seuls la couleur, la profondeur et
   le mouvement changent.
   ========================================================================== */

/* ---- desktop : carte centrée, bulles dispersées autour ---------------- */

@media (min-width: 992px) {
  .location-wrap {
    /* Hauteur du plus grand des deux : la carte (~524 px à 1350 px de
       conteneur) ou la pile de bulles (3 rangées, la dernière à 72 %). */
    min-height: 620px;
  }

  /* La carte occupe tout le bloc et se centre dedans, ce qui la garde alignée
     avec les gouttières quelle que soit la largeur. */
  .location-bg-wrap {
    z-index: 1;
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /* 25 % laisse 37,5 % de gouttière de chaque côté. La bulle mesure 318 px, donc
     le cas le plus serré est le tout début du desktop (bloc de 962 px) : il reste
     23 px de dégagement, et ça ne fait que s'ouvrir plus haut. */
  .location-bg {
    width: 25%;
    min-width: 240px;
    max-width: 380px;
    height: auto;
    /* Garde-fou : si la hauteur disponible devient le facteur limitant,
       `contain` réduit la carte au lieu de l'écraser. */
    max-height: 94%;
    object-fit: contain;
  }

  /* Colonne de gauche. */
  .location-single-block._01 {
    inset: 0 auto auto 0;
  }

  .location-single-block._02 {
    inset: 36% auto auto 2%;
  }

  .location-single-block._04 {
    inset: 72% auto auto 0;
  }

  /* Colonne de droite. */
  .location-single-block._05 {
    inset: 6% 0 auto auto;
  }

  .location-single-block._03 {
    inset: 46% 1.5% auto auto;
  }
}

/* ---- sous 992 px : la grille du template, sans le planisphère --------- */

@media (max-width: 991px) {
  .location-wrap {
    background-image: none;
  }

  .location-details-wrap {
    width: 100%;
    max-width: none;
  }
}

/* ---- la bulle --------------------------------------------------------- */

.location-details-wrap {
  gap: 16px;
  padding: 10px;
  /* Le gris #f4f4f4 du template devient le ton clair de la marque. */
  background-color: var(--_colors---color--light-yellow-color);
  box-shadow: 0 1px 2px rgb(1 14 14 / 6%);
  transition:
    transform 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    background-color 0.45s ease;
}

.location-single-block:hover .location-details-wrap {
  transform: translateY(-6px);
  background-color: #eefdfc;
  box-shadow: 0 18px 40px -18px rgb(17 124 120 / 45%);
}

/* ---- la pastille photo ------------------------------------------------ */

.location-image-wrap {
  position: relative;
  /* Deux anneaux : un liseré blanc puis un halo à la couleur primaire. */
  box-shadow:
    0 0 0 3px #ffffff,
    0 0 0 5px rgb(17 124 120 / 20%);
  transition:
    box-shadow 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.location-single-block:hover .location-image-wrap {
  transform: scale(1.04);
  box-shadow:
    0 0 0 3px #ffffff,
    0 0 0 6px var(--_colors---color--primary-color);
}

.location-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Léger surdimensionnement au repos pour que le zoom n'expose aucun bord. */
  transform: scale(1.03);
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.location-single-block:hover .location-image {
  transform: scale(1.14);
}

.location-name {
  transition: color 0.35s ease;
}

.location-single-block:hover .location-name {
  color: var(--_colors---color--primary-color);
}

/* ---- apparition au défilement ----------------------------------------- */
/* Déclenché par <CountyReveal>, qui pose `taga-reveal-armed` puis
   `taga-reveal-in` quand la section entre dans la fenêtre.

   La première version utilisait `animation-timeline: view()`, en CSS pur. Deux
   erreurs : Firefox garde les animations pilotées par le défilement derrière un
   drapeau et Safari ne les a qu'à partir de la 26, donc le `@supports`
   n'animait rien du tout au lieu d'animer moins ; et chaque bulle avait sa
   propre timeline, ce qui les déclenchait à des positions de défilement
   différentes, du bruit, pas une vague.

   L'état masqué dépend de `.taga-reveal-armed`, que seul le JS ajoute. Aucune
   feuille de style ne cache donc quoi que ce soit d'elle-même : sans JS, sans
   IntersectionObserver ou en cas d'erreur, les bulles restent visibles. C'est
   la leçon du texte de hero du template, livré en `opacity: 0` et révélé
   uniquement par une interaction qui pouvait ne jamais tourner. */

.location-wrap.taga-reveal-armed .location-single-block {
  opacity: 0;
  transform: translateY(30px) scale(0.94);
  transition:
    opacity 0.5s ease-out,
    transform 0.75s cubic-bezier(0.22, 1, 0.36, 1);
  /* 5 bulles × 110 ms = 440 ms d'étalement, plus 750 ms de course : la vague
     dure ~1,2 s, assez lente pour être vue, assez courte pour ne pas retenir. */
  transition-delay: calc(var(--taga-reveal-i, 0) * 110ms);
}

.location-wrap.taga-reveal-armed.taga-reveal-in .location-single-block {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .location-details-wrap,
  .location-image-wrap,
  .location-image,
  .location-name {
    transition: none;
  }
}

/* ==========================================================================
   ICÔNES SOCIALES DU FOOTER
   ==========================================================================

   Le bloc social du template était conçu pour un fond CLAIR : bordure
   `dark-stroke`, icône noire visible au repos (les deux icônes empilées dans un
   cadre de 16px en `overflow: hidden`, `justify-content: flex-end` ne laissant
   voir que la dernière). Sur le footer sombre, la bordure et l'icône noire
   seraient invisibles.

   Cette variante inverse la logique : icône blanche au repos, icône sombre au
   survol sur un fond clair qui se remplit.

   L'échange se fait en CSS, pas via IX2 : l'animation d'origine était liée à
   des `data-w-id` précis, qui ne portent aucune donnée d'interaction pour de
   nouveaux éléments comme ceux-ci.
   ========================================================================== */

/* Toujours sur une seule ligne : `nowrap` plutôt que `wrap`, sinon la 4ᵉ icône
   passe à la ligne dès que la colonne se resserre. */
.taga-social-wrap {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 8px;
}

/* Cercle repris de `.social-link` mais agrandi (32 -> 40px) et rendu plus
   présent : un fond translucide au repos détache le bouton du footer sombre. */
.taga-social {
  width: 40px;
  min-width: 40px;
  height: 40px;
  border-color: rgb(255 255 255 / 22%);
  background-color: rgb(255 255 255 / 8%);
  transition:
    background-color 0.25s ease,
    border-color 0.25s ease;
}

.taga-social-icon {
  width: 20px;
  height: 20px;
  /* Jamais masquée, ni au repos ni au survol. */
  opacity: 1;
}

/* Le survol renforce le contour et le fond, sans jamais toucher à l'icône.
   L'effet d'origine échangeait une icône blanche contre une sombre derrière un
   fond qui se remplissait : à mi-transition les deux étaient partiellement
   transparentes et l'icône semblait disparaître. */
.taga-social:hover {
  border-color: var(--_colors---color--light-yellow-color);
  background-color: rgb(255 255 255 / 18%);
}

/* Le titre « Follow Us » tient sur une ligne. La colonne fait environ 205px,
   largement de quoi l'accueillir, c'est le retour à la ligne automatique qui
   le coupait. */
.taga-nowrap {
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .taga-social {
    transition: none;
  }
}

/* ==========================================================================
   TUILE NUMÉROTÉE (section « HOW SUPPORT IS DELIVERED » sur /about)
   ==========================================================================

   Cette section était la grille d'équipe du template : 4 portraits de personnes
   réelles présentées comme le personnel de Taga's. Aucun nom n'ayant été
   communiqué, elle présente désormais les 4 étapes d'accompagnement du client.

   `.team-image-wrap` n'a pas de hauteur propre, c'était l'image qui la
   donnait. Sans elle, la zone s'effondrait à zéro. `aspect-ratio` sur la tuile
   restitue la proportion portrait d'origine.
   ========================================================================== */

.taga-step-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 5;
  background-color: var(--_colors---color--light-yellow-color);
  color: var(--_colors---color--primary-color);
  font-family: var(--_typography---font-family--primary-font);
  font-size: clamp(40px, 6vw, 76px);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
}

/* ==========================================================================
   LIENS DU MENU ET DU FOOTER, FENÊTRE DE DÉFILEMENT
   ==========================================================================

   Chaque lien empile deux copies du libellé (`[text-top]` et `[text-bottom]`).
   IX2 fait glisser l'une hors du cadre et l'autre dedans au survol ; le cadre
   ne doit donc laisser voir qu'une seule ligne.

   Webflow fixait ce cadre à `height: 24px`. Deux problèmes :

   1. Les polices concernées vont de 15 à 18px avec un line-height de 144–150 %,
      soit jusqu'à 26px par ligne. À 18px, une ligne unique dépassait déjà les
      24px : le libellé était rogné et on apercevait la copie suivante.
   2. Un libellé plus long que la colonne passait à la ligne, occupait 2 lignes
      et se faisait couper au milieu.

   Correction : la hauteur du cadre est exprimée en `em`, donc elle suit
   exactement le line-height à chaque palier, et les libellés ne peuvent plus
   passer à la ligne.
   ========================================================================== */

.nav-link {
  /* paragraph-02 line-height = 150% */
  height: 1.5em;
}

.footer-link {
  /* text-medium line-height = 144% */
  height: 1.44em;
}

.nav-link-text,
.footer-link-text {
  display: block;
  white-space: nowrap;
}

/* ==========================================================================
   LOGO DE MARQUE
   ==========================================================================

   Le template livrait deux marques Serenova : brand-logo.svg dans le header et
   footer-logo.svg répété dans la bande défilante du footer. Les deux ont porté
   le nom de l'entreprise en texte le temps que le client fournisse son logo,
   puis ont été remplacées par le vrai logo.

   Deux variantes, et le choix se fait au contraste, pas au goût : le lettrage
   de la version couleur est en teal foncé, il tient sur blanc et disparaît à la
   fois sur le fond quasi noir du footer et sur le teal primaire. Donc :

     header : `.navbar` a `background-color: white`  -> version COULEUR
     footer : `.footer-section` est sur `black-bg`   -> version BLANCHE

   Les fichiers sont produits par `tools/brand/build-brand.py` depuis les
   masters du client. Ils sont détourés : le contenu utile du logo ne faisait
   que 3060×887 dans un canevas de 3734×1683, donc tel quel il aurait paru
   petit au milieu de marges transparentes.
   ========================================================================== */

/* `.brand-logo` n'avait aucune règle : le SVG d'origine s'affichait à sa taille
   naturelle. Le ratio détouré est de 3,45, donc 190px de logo donnent 55px de
   haut, le header ajoute 20px de padding en haut et en bas.

   La cellule fait 214px et non 190 : `.brand-logo-wrap` porte le filet vertical
   du template (`border-right`), et comme `* { box-sizing: border-box }`, les
   24px de `padding-right` se déduisent de la largeur. Le logo garde donc ses
   190px et respire avant le trait, qui était sinon collé au lettrage. 24px, la
   même valeur que la gouttière de `.navbar-left-wrap` de l'autre côté du
   filet. */
.brand-logo-wrap {
  max-width: 214px;
  padding-right: 24px;
}

.brand-logo {
  display: block;
  width: 100%;
  height: auto;
}

/* Le template ne rétrécissait la cellule que via `.brand-logo-wrap.w--current`,
   c'est-à-dire uniquement quand le lien de marque pointe sur la page courante, 
   donc seulement sur l'accueil. Le logo était plus petit sur une page que sur
   toutes les autres. On aligne les deux cas.

   Le padding retombe à zéro ici : le template supprime le filet en dessous de
   992px (`border-right-style: none`), donc l'espace réservé n'aurait plus rien
   à séparer. */
@media screen and (max-width: 991px) {
  .brand-logo-wrap,
  .brand-logo-wrap.w--current {
    max-width: 168px;
    padding-right: 0;
  }
}

@media screen and (max-width: 479px) {
  .brand-logo-wrap,
  .brand-logo-wrap.w--current {
    max-width: 148px;
  }
}

/* Bande défilante du footer. Le slot d'origine imposait `max-width: 501px` et
   `overflow: hidden` ; c'est la hauteur qui doit piloter ici, la largeur suit
   le ratio. */
.footer-logo-wrap.taga-mark {
  width: auto;
  max-width: none;
  overflow: visible;
}

.taga-footer-logo {
  display: block;
  width: auto;
  /* Passé de clamp(30px, 4.4vw, 54px) : trop imposant. Le ratio est de 3,45,
     donc 40px de haut font 138px de large par exemplaire, la bande en défile
     douze, ce qui suffit largement à couvrir la largeur. */
  height: clamp(24px, 3vw, 40px);
}

/* ==========================================================================
   HERO, HAUTEUR NON BLOQUANTE
   ==========================================================================

   Webflow fixe `.hero-wrapper { height: 92vh }` avec le contenu aligné en bas
   (`justify-content: flex-end`), et `.hero-section` est en `overflow: hidden`.
   Comme `.header-section` est en `position: relative`, il occupe sa place :
   header + 92vh dépasse déjà la fenêtre.

   Conséquence : dès que le texte du hero est plus long que la copie Serenova
   d'origine (et celui de Taga's l'est), il s'étend vers le haut et se fait
   couper. Le texte devenait partiellement illisible.

   `height: auto` + `min-height` garde exactement le même rendu quand le texte
   est court, mais laisse le bloc grandir au lieu de rogner le contenu. Le
   padding haut évite que le texte vienne coller au menu sur petits écrans.
   ========================================================================== */

.hero-wrapper {
  height: auto;
  min-height: 92vh;
  padding-top: 32px;
}

/* ==========================================================================
   LISIBILITÉ SANS ANIMATION
   ==========================================================================

   Webflow livre les textes de héros avec `style="opacity:0"` en inline et
   compte entièrement sur l'interaction IX2 pour les révéler. C'est fragile :
   quand `prefers-reduced-motion` est actif, Webflow saute l'animation et
   l'élément reste à zéro indéfiniment, bug d'accessibilité connu de la
   plateforme.

   Du contenu ne doit jamais dépendre d'une animation pour être lisible.
   `!important` est nécessaire ici : seule cette déclaration bat un style
   inline.

   Liste explicite plutôt que `[data-w-id]` en bloc : tous les éléments ci-
   dessous sont des révélations de contenu. Forcer aveuglément tous les
   `[data-w-id]` risquerait d'afficher un élément légitimement masqué, comme un
   menu déroulant.

   WebflowRuntime.revealStuckElements() couvre les autres causes de blocage
   (bundle manquant, échec d'IX2) après un délai de 1200 ms.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  /* Every IX2 target, not a hand-kept class list: under reduced motion Webflow
     skips all animations, so everything that would have been revealed must
     simply be visible. A list would silently miss elements as pages change, 
     the restored About page alone has a dozen more.

     Safe here because Webflow's genuinely-hidden UI (nav menu, dropdowns,
     tabs) is toggled with `display`, not `opacity`. */
  [data-w-id] {
    opacity: 1 !important;
  }
}

/* ==========================================================================
   ICÔNES SVG
   ==========================================================================
   Les 45 icônes du jeu codaient les couleurs en dur (hex figé, pas
   currentColor). Changer les variables CSS seules les aurait laissées dans
   l'ancienne palette verte. Elles ont donc été réécrites dans
   public/assets/images/, 104 remplacements :

     #025747 -> #117c78   50x   ancien primaire
     #e4ffb8 -> #e4fbfa   46x   ancien ton pâle
     #010c0a -> #010e0e    8x   ancien texte

   Cela inclut brand-logo.svg et footer-logo.svg, qui portent le logo du
   template Serenova et seront de toute façon remplacés par celui de Taga.

   Conséquence : ces icônes ne suivront PAS un futur changement de palette
   automatiquement. Pour les rendre pilotables par le CSS, il faudrait
   remplacer leurs valeurs figées par `currentColor`.
   ========================================================================== */

/* ==========================================================================
   CONTRASTES VÉRIFIÉS
   ==========================================================================
   paire                                    ratio    seuil   verdict
   ---------------------------------------------------------------------
   texte clair sur primaire (boutons)       4,66:1    4,5     OK
   texte primaire sur ton clair             4,66:1    4,5     OK
   texte principal sur blanc               19,62:1    7,0     OK (AAA)
   texte principal sur ton clair           18,20:1    4,5     OK
   accent en texte sur blanc                4,64:1    4,5     OK  (avant : 2,09 ECHEC)
   blanc sur fond sombre                   20,04:1    4,5     OK
   primaire en texte sur blanc              5,03:1    4,5     OK
   visibilité du ton clair sur blanc        1,08:1    1,05    OK

   Note : les boutons font 16px semi-bold, ce qui n'est PAS du « grand texte »
   au sens WCAG (seuil 24px, ou 18,7px en gras). Le seuil applicable est donc
   4,5:1 et non 3:1.
   ========================================================================== */

/* ==========================================================================
   COULEUR DES ICÔNES
   ==========================================================================

   Les icônes sont passées de Phosphor (poids `fill`, MIT) et sont posées en SVG
   inline via <Icon>, avec `fill="currentColor"`. La couleur se règle donc ici,
   au même endroit que le reste du thème.

   C'est ce qui supprime la duplication du template : `service-icon-1w` et
   `service-icon-1` étaient la même forme en deux fichiers, l'un en blanc pour
   la carte sombre de l'accueil, l'autre en couleur primaire pour la carte
   claire de la page Services. Une seule entrée sert maintenant les deux.

   Ces valeurs reprennent exactement les remplissages qui étaient figés dans les
   fichiers, donc l'apparence ne change pas, seule la mécanique change.
   ========================================================================== */

/* Pastilles rondes à fond primaire : valeurs, « why choose », mission, awards. */
.value-icon,
.choose-icon,
.mission-icon,
.award-icon {
  color: var(--_colors---color--light-yellow-color);
}

/* Accueil : cercle bordé `lite-stroke` sur carte sombre. */
.service-icon-wrap .service-icon {
  color: #ffffff;
}

/* Page Services : cercle bordé `dark-stroke` sur carte claire. */
.service-icon-block .service-icon {
  color: var(--_colors---color--primary-color);
}

/* ==========================================================================
   GRILLE DU BLOC IMAGE + TEXTE
   ==========================================================================

   `.mission-grid-wrap` du template est figé en `1fr 1fr`, calibré pour les deux
   items de la page About (« Our Focus » / « Our Approach »). Avec trois items,
   le troisième se retrouve seul sur une deuxième ligne, dans la cellule de
   gauche.

   `auto-fit` fait tenir à la grille le nombre d'items qu'elle a réellement.
   Dans la colonne de 704 px avec 44 px de gouttière : trois colonnes de 205 px
   (3 × 180 + 2 × 44 = 628 ≤ 704, alors que quatre demanderaient 852 px), et le
   repli vers deux puis une colonne se fait tout seul quand la place manque.
   ========================================================================== */

.mission-grid-wrap.taga-mission-grid-auto {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

/* ==========================================================================
   BLOC TITRE À GAUCHE + LISTE À DROITE
   ==========================================================================

   Colonne de gauche de `<SplitList>`, qui réutilise le `.choose-wrap` du
   template (flex `space-between`, et qui passe seul en colonne sous 992 px).

   Le template mettait une image dans ce créneau, donc il n'existe pas de classe
   pour un bloc de texte à cet endroit. On ne réemploie pas `.section-title-wrap`
   parce qu'elle porte `margin-bottom: spacing-massive`, calibré pour un titre
   posé AU-DESSUS d'une section, pas à côté d'elle : dans une ligne flex, cette
   marge décale la colonne vers le haut.

   580 px pour la liste (`.choose-flex-wrap`) + 560 px ici tient dans le
   conteneur de 1320 px avec la gouttière du template.
   ========================================================================== */

.taga-split-intro {
  width: 100%;
  max-width: 560px;
}

/* ==========================================================================
   LISIBILITÉ DU TEXTE SUR LES VIDÉOS DE HERO
   ==========================================================================

   Le texte des héros de pages internes se lisait mal sur la vidéo. Mesuré sur
   les images-poster, en compositant le dégradé et en calculant le contraste
   WCAG dans la zone où le texte tombe réellement (bas centré, `flex-end` +
   48 px de padding) :

     hero                            titre   paragraphe
     ----------------------------------------------------
     interne, sans overlay            3,9:1     2,8:1   ECHEC
     interne, dégradé du template     9,5:1     5,7:1
     accueil (référence)             10,5:1     6,1:1
     interne, réglage ci-dessous     11,9:1     9,1:1

   Valeurs moyennes sur la zone de texte. Pour le réglage retenu, les 5 % de
   pixels les plus clairs de cette zone donnent encore 5,5:1 sur le titre et
   4,5:1 sur le paragraphe, donc au-dessus du seuil même dans le pire cas.

   Le paragraphe est le maillon faible, pas le titre : `.hero-details` est en
   `lite-text-secondary` = #ffffffb3, du blanc à 70 %, dont la couleur rendue
   dépend donc du fond. Sur une image claire il se rapproche du fond et le
   rapport s'effondre. D'où deux leviers, et le second ne coûte rien à l'image :
   on assombrit un peu, et on rend le paragraphe un peu plus opaque.

   Contre-intuitif, et c'est la mesure qui l'a montré : assombrir DAVANTAGE
   dégrade le pire cas. Une variante à 22 % / 88 % retombe à 4,35:1 là où
   celle-ci tient 4,51:1, parce que le pixel le plus clair de la zone se trouve
   en HAUT de la bande de texte, où le genou à 55 % compte plus que le pied du
   dégradé.

   Les chiffres « au pire des cas » portent sur les 5 % de pixels les plus
   clairs de la zone. L'accueil n'est pas retouché : sa valeur vous convient.
   ========================================================================== */

/* Partagé par le hero de la page Services et par <PageHero>. */
.service-video-overlay {
  background-image: linear-gradient(
    rgb(0 0 0 / 18%) 0%,
    rgb(0 0 0 / 26%) 55%,
    rgb(0 0 0 / 85%) 100%
  );
}

/* 85 % de blanc au lieu de 70 %. Le titre, lui, est déjà blanc opaque. */
.hero-details.service {
  color: #ffffffd9;
}

/* ==========================================================================
   GRILLE DES TUILES DE VALEURS
   ==========================================================================

   `.value-wrap` du template est figé en `1fr 1fr 1fr 1fr`, calibré pour les
   quatre valeurs de l'accueil. Les pages de service y placent les cinq
   exclusions de périmètre, et le cinquième item se retrouvait seul dans la
   cellule de gauche d'une deuxième ligne.

   `auto-fit` supprime les pistes vides, donc le nombre de colonnes suit la
   place disponible au lieu d'être figé. Avec la gouttière de 20 px du template
   et un conteneur de 1320 px : 5 × 230 + 4 × 20 = 1230 px, donc les cinq
   tiennent sur une ligne. En dessous, la grille descend à 4 puis 3 colonnes.

   Ce n'est pas parfait à toutes les largeurs, entre ~1170 et ~1230 px de
   conteneur on obtient 4 colonnes, donc un 5ᵉ item seul. Mais la version figée
   donnait ce même 4+1 à TOUTES les largeurs desktop, alors qu'ici c'est 5 sur
   une ligne au format plein et 3+2 en dessous de 1170 px.
   ========================================================================== */

.value-wrap.taga-value-grid-auto {
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

/* ==========================================================================
   IMAGE PAYSAGE DANS LE BLOC IMAGE + TEXTE
   ==========================================================================

   `.mission-image-wrap` du template impose une hauteur fixe sous 992 px :
   600 px, puis 440 px sous 768 px, puis 300 px sous 480 px. Ces valeurs ont ete
   calibrees pour une image en portrait, celle de la page About faisant 0,897.

   Avec une image en paysage, l'image ne remplit plus la hauteur imposee et le
   reste du panneau apparait vide. Ce modificateur libere la hauteur pour que le
   bloc suive le ratio de l'image.

   Sur desktop il n'y a rien a faire : la regle de base ne fixe aucune hauteur.
   ========================================================================== */

@media screen and (max-width: 991px) {
  .mission-image-wrap.taga-mission-image-landscape {
    height: auto;
  }
}

/* ==========================================================================
   PANNEAUX DE CONFIRMATION ET D'ERREUR DU FORMULAIRE
   ==========================================================================

   Ces deux blocs apparaissent juste sous le bouton d'envoi, une fois le
   formulaire soumis. Le template les laissait collés à lui :

     .success-message  aucune marge du tout
     .error-message    margin-top: 20px

   Deux incoherences a la fois, donc : le panneau vert touchait le bouton, et
   les deux etats ne s'alignaient pas entre eux.

   La valeur retenue est `spacing-xlarge`, qui est exactement la gouttiere que
   `.contact-form` applique déjà entre le bloc des champs et le bouton. Le
   panneau se cale ainsi sur le rythme vertical du formulaire au lieu d'une
   valeur choisie a l'oeil.

   Le jeton est responsive et declare sur `:root`, donc herite bien jusqu'ici :
   ces deux panneaux sont freres de `<form>`, pas enfants, et une variable
   scopee sur `.contact-form` n'aurait pas resolu. Valeurs effectives : 40 px
   au-dela de 991 px, 36 px en dessous, puis 24 px sous 767 px.
   ========================================================================== */

.success-message,
.error-message {
  margin-top: var(--_responsive---element-spacing--spacing-xlarge);
}

.taga-inline-tel {
  color: inherit;
  font-weight: var(--_typography---font-weight--semi-bold);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.taga-inline-tel:hover {
  text-decoration: none;
}

/* ==========================================================================
   BOUTON D'APPEL FLOTTANT, PRESENT SUR TOUTES LES PAGES
   ==========================================================================

   Le telephone est le canal principal de ce prestataire, pas un recours : la
   page Contact s'intitule « Start with a call », le formulaire ne fait que
   demander un rappel, et la copie dit que tout ce qui est clinique se traite
   par telephone. Le numero n'etait pourtant atteignable qu'en pied de page ou
   dans une carte d'une seule page.

   --------------------------------------------------------------------------
   POURQUOI EN BAS A GAUCHE, ET POURQUOI NE PAS LE « CORRIGER »
   --------------------------------------------------------------------------
   La convention place ce type de bouton en bas a droite. Ici ce coin est deja
   pris : le controle play/pause des videos de fond de Webflow est en
   `position: absolute; bottom: 1em; right: 1em` DANS son propre conteneur, et
   deux de ces conteneurs remplissent le viewport, le hero de l'accueil et la
   scene sticky `values` qui se fige sur un ecran entier sur quatre pages. Un
   bouton a droite se poserait donc sur le bouton pause de la premiere chose
   que voit un visiteur. La gauche evite aussi la fleche de defilement du hero.

   --------------------------------------------------------------------------
   EMPILEMENT
   --------------------------------------------------------------------------
   1200 : au-dessus du contenu et des menus deroulants (`.w-dropdown` = 900,
   `.w-nav` = 1000), en dessous de la lightbox (2000) et de `.header-section`
   (9999). Le menu mobile ouvert doit recouvrir ce bouton, pas l'inverse.
   ========================================================================== */

.taga-call-fab {
  position: fixed;
  z-index: 1200;
  bottom: 20px;
  left: 20px;

  display: inline-flex;
  align-items: center;
  gap: 10px;

  /* 14px vertical + une icone de 22px = 50px de haut, donc au-dela des 44px
     de cible tactile recommandes sans avoir a forcer une hauteur. */
  padding: 14px 20px;
  border: 1px solid var(--_colors---color--primary-color);
  border-radius: 100px;
  background-color: var(--_colors---color--primary-color);
  color: var(--_colors---color--light-yellow-color);

  font-family: var(--_typography---font-family--secondary-font);
  font-size: var(--_typography---paragraph-02--font-size);
  font-weight: var(--_typography---font-weight--semi-bold);
  line-height: 1;
  letter-spacing: var(--_typography---paragraph-02--letter-spacing);
  text-decoration: none;
  white-space: nowrap;

  /* Assez d'ombre pour se detacher d'une photo ou d'une video, ce qui arrive
     sur la majorite des pages. */
  box-shadow: 0 6px 24px #0000002e;
  transition: color .3s, background-color .3s, box-shadow .3s;
}

.taga-call-fab:hover,
.taga-call-fab:focus-visible {
  background-color: var(--_colors---color--light-yellow-color);
  color: var(--_colors---color--primary-color);
  box-shadow: 0 8px 28px #00000040;
}

/* Le focus clavier ne doit pas reposer sur le seul changement de couleur.
   Double anneau, et ce n'est pas une coquetterie : au focus le fond du bouton
   PASSE en light-yellow, donc un contour de cette meme couleur, ce qu'une
   premiere version faisait, etait litteralement invisible. Le contour est donc
   en couleur primaire, immediatement contre la pilule claire, puis un halo
   blanc le detache des fonds sombres et des photos, que ce bouton survole sur
   la majorite des pages. */
.taga-call-fab:focus-visible {
  outline: 3px solid var(--_colors---color--primary-color);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px #ffffffd9, 0 8px 28px #00000040;
}

.taga-call-fab-icon {
  width: 22px;
  height: 22px;
  flex: none;
  /* `currentColor` dans icons.ts : l'icone suit la couleur du texte, donc le
     survol la fait basculer sans regle supplementaire. */
  fill: currentColor;
}

/* Sous 480px le libelle disparait et le bouton devient un cercle : a cette
   largeur une pilule portant dix chiffres mange une part reelle de l'ecran.
   Le nom accessible reste complet, il est porte par l'aria-label et non par ce
   texte, donc rien n'est perdu pour un lecteur d'ecran. */
@media screen and (max-width: 479px) {
  .taga-call-fab {
    padding: 15px;
    gap: 0;
  }

  .taga-call-fab-label {
    display: none;
  }
}

/* Pas de marge ajoutee au pied de page pour « faire de la place » a ce bouton.
   Une premiere version mettait `padding-bottom: 84px` sur `.footer-wrap` :
   c'etait faux deux fois. Ce jeton vaut 80px au desktop mais 40px sous 480px,
   donc la valeur fixe doublait l'espacement en mobile, et `.footer-wrap` n'est
   de toute facon pas le dernier bloc du pied de page, la ligne de copyright
   vient apres. Un bouton flottant qui chevauche le tout dernier pixel d'une
   page est le comportement normal de ce motif ; le corriger a l'aveugle
   coutait une regression de mise en page sur toutes les pages. */
