/* =====================================================================
   Police Inter, HEBERGEE EN LOCAL
   ---------------------------------------------------------------------
   POURQUOI. Elle etait chargee depuis Google Fonts, ce qui coutait, AVANT
   le moindre pixel affiche : une resolution DNS, une poignee de main TLS et
   une feuille de style vers `fonts.googleapis.com`, puis une SECONDE
   connexion vers `fonts.gstatic.com` pour le fichier lui-meme. Sur une
   connexion a forte latence (400 ms d'aller-retour), cela representait
   plusieurs secondes de pure attente reseau sur le chemin critique, et
   cette feuille de style tierce BLOQUAIT l'affichage.
   Servie depuis le meme domaine, elle voyage sur la connexion deja ouverte.

   C'est aussi la ligne de conduite deja retenue pour Alpine.js, sorti du
   CDN pour la meme raison (cf. base.html).

   CE QUE C'EST. Une police VARIABLE : un seul fichier couvre toutes les
   graisses de 400 a 800, celles que le site utilise reellement (400, 500,
   600, 700 et 800). Aucun rendu ne change.

   `font-display: swap` conserve : le texte s'affiche immediatement dans la
   police de secours, puis bascule sur Inter des qu'elle arrive. On ne voit
   jamais une page vide en attendant une police.

   Les `unicode-range` sont ceux de Google : le sous-ensemble « latin-ext »
   n'est telecharge que si la page contient un caractere qui l'exige, ce qui
   n'arrive ni en francais, ni en allemand, ni en anglais.
   ===================================================================== */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* =====================================================================
   Socle de style commun a TOUTES les pages de Caelys.
   ---------------------------------------------------------------------
   Ce fichier etait, jusqu'au chantier mobile, un bloc <style> ecrit dans
   templates/base.html : 40 Ko renvoyes par le serveur a CHAQUE ouverture de
   page, jamais mis en cache. Sorti ici, il est telecharge une fois puis
   servi depuis le cache du navigateur (nginx : 30 jours), et la page
   d'accueil passe de 145 a environ 105 Ko.

   Il contient, dans l'ordre : les variables de couleur, les composants
   partages (cartes, boutons, champs, icones), puis le SOCLE MOBILE du
   chantier responsive (zones sures, hauteurs en dvh, cibles tactiles,
   tableaux en cartes, menus plein ecran...).

   ATTENTION : ce fichier est charge par asset_url() donc versionne par sa
   date de modification. Aucune etape de compilation, on l'edite directement.

   Copyright (c) 2026 Yohann Bordin. Tous droits reserves.
   ===================================================================== */

/* === Design Tokens (dark mode premium, accent orange MAT) === */
:root {
  /* Backgrounds */
  --bg-primary: #0A0A0A;
  --bg-elevated-1: #111111;
  --bg-elevated-2: #161616;

  /* SURFACE DE LA VITRINE : bandeau du haut, pied de page, etiquettes.
     Exprimee en composantes R,G,B pour pouvoir etre utilisee telle quelle
     (`rgb(var(--mkt-surface-rgb))`) ou avec une transparence
     (`rgba(var(--mkt-surface-rgb), 0.82)`).
     UN SEUL ENDROIT A CHANGER pour reteinter toute la vitrine. */
  --mkt-surface-rgb: 26, 20, 18;

  /* Borders */
  --border-default: #1F1F1F;
  --border-active: #C44A1E;

  /* Accent (orange mat premium, moins flashy) */
  --accent: #C44A1E;
  --accent-hover: #A33C13;
  --accent-light: #E66B3C;
  --accent-deep: #7E2E0C;
  --accent-translucent: rgba(196, 74, 30, 0.85);
  --accent-tint: rgba(196, 74, 30, 0.08);
  /* Gradients pour bordures/cards : foncis sur les bords */
  --accent-grad: linear-gradient(135deg, #E66B3C 0%, #C44A1E 50%, #7E2E0C 100%);
  --accent-grad-soft: linear-gradient(135deg, rgba(196, 74, 30, 0.18) 0%, rgba(126, 46, 12, 0.10) 100%);
  --border-grad: linear-gradient(135deg, #C44A1E 0%, #7E2E0C 100%);

  /* Texte */
  --text-primary: #F5F5F5;
  --text-secondary: #A0A0A0;
  --text-tertiary: #6B6B6B;
  --text-on-accent: #FFFFFF;

  /* Semantique */
  --success: #22C55E;
  --warning: #F59E0B;
  --error: #EF4444;

  /* Legacy aliases (retro-compat, pointent vers les nouveaux tokens) */
  --bordeaux: var(--accent);
  --bordeaux-hover: var(--accent-hover);
  --anthracite: var(--bg-primary);
  --anthracite-2: var(--bg-elevated-1);
  --anthracite-3: var(--border-default);
}
/* Ancrage couleur sombre AVANT toute autre chose pour eviter flash blanc */
html {
  color-scheme: dark;
  background-color: #050505;
}
body {
  font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  background: transparent;
  /* 100vh d'abord comme repli pour les moteurs anciens, puis 100dvh qui
     suit la hauteur visible quand la barre d'URL de Chrome Android se
     retracte. Voir le socle mobile plus bas. */
  min-height: 100vh;
  min-height: 100dvh;
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* === Fond anime en particules (canvas) === */
#bgMesh {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  height: 100dvh;
  z-index: -1;
  pointer-events: none;
  display: block;
}

/* === Override global pour limiter le cout GPU du backdrop-filter
   quand le canvas s'anime au-dessous. blur(20px) -> blur(10px) divise
   par 2-3 le travail compositing tout en conservant l'effet verre.
   Le !important bat les styles inline sur les <header>. === */
.card-glass,
[style*="backdrop-filter"] {
  backdrop-filter: blur(6px) saturate(120%) !important;
  -webkit-backdrop-filter: blur(6px) saturate(120%) !important;
}

/* === Icones SVG (remplacent les emojis, meme DA orange chaud) ===
   Trait fin 1.6, fill none, currentColor (par defaut orange #F2531B
   sauf si override locale via color: ...). Inline avec viewBox 64x64.
   NB : on style directement svg.ico pour eviter qu'une regle .ico svg
   n'ecrase la taille quand le svg porte lui-meme la classe .ico. */
svg.ico {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.18em;
  color: var(--accent);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
  flex-shrink: 0;
}
svg.ico.ico-lg { width: 1.4em; height: 1.4em; }
svg.ico.ico-xl { width: 1.8em; height: 1.8em; }
svg.ico.ico-2xl { width: 2.4em; height: 2.4em; }
/* Variantes couleur (override currentColor) */
svg.ico.ico-muted { color: var(--text-tertiary); }
svg.ico.ico-success { color: var(--success); }
svg.ico.ico-warning { color: var(--warning); }
svg.ico.ico-error { color: var(--error); }
svg.ico.ico-white { color: #fff; }

/* === View Transitions API (Chrome 111+, Edge 111+) ===
   Cross-fade simultane (pas de flash blanc) : old et new tournent en
   parallele, l'ancienne descend en opacite pendant que la nouvelle monte.
   Pas de gap visuel transparent. */
@view-transition {
  navigation: auto;
}
/* Empile les snapshots et fais un cross-fade simultane */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;            /* desactive l'animation par defaut (fade auto) */
  mix-blend-mode: normal;
  background-color: var(--bg-primary); /* fond toujours sombre */
}
::view-transition-old(root) {
  animation: 120ms linear both vt-fade-out;
}
::view-transition-new(root) {
  animation: 120ms linear both vt-fade-in;
}
@keyframes vt-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes vt-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}

/* === Optimisation rendu : sections below-fold paintees lazy ===
   Browser skip le layout des sections hors viewport
   => first paint plus rapide, scroll fluide. */
.mkt-section,
/* PAS le pied de page : il est TOUJOURS le dernier element de la page, donc
   sauter son rendu ne fait gagner presque rien, alors que la hauteur
   reservee (600 px ci-dessous) ne correspondait pas a sa hauteur reelle
   (environ 315 px). Resultat : un grand vide pendant le defilement, un saut
   de mise en page a son apparition, et toute retouche de ses marges qui
   semblait sans effet. Verifie le 2026-07-22. */
.tarifs-shell > section,
.why-section,
.faq-section {
  content-visibility: auto;
  contain-intrinsic-size: 600px;   /* hauteur estimee avant render */
}
.card-glass {
  background: rgba(17, 17, 17, 0.85);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--border-default);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
  transition: border-color 0.25s ease;
}
.card-glass:hover {
  border-color: rgba(196, 74, 30, 0.25);
}
.hero-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--border-default);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  background: var(--bg-elevated-1);
}
.hero-left-panel {
  background:
    radial-gradient(circle at 30% 20%, rgba(230, 107, 60, 0.35), transparent 60%),
    linear-gradient(135deg, #C44A1E 0%, #A33C13 100%);
  padding: 48px 40px;
  position: relative;
  overflow: hidden;
  min-height: 480px;
}
.hero-left-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 80% 80%, rgba(255, 255, 255, 0.1), transparent 50%);
  pointer-events: none;
}
@media (max-width: 760px) {
  .hero-split { grid-template-columns: 1fr; }
  .hero-left-panel { min-height: auto; padding: 32px 24px; }
}
.input-mp {
  width: 100%;
  padding: 14px 16px;
  font-size: 1rem;
  font-family: inherit;
  border: 1px solid var(--border-default);
  border-radius: 12px;
  background: var(--bg-elevated-1);
  color: var(--text-primary);
  transition: border-color 0.2s, box-shadow 0.2s;
}
.input-mp::placeholder { color: var(--text-tertiary); }
.input-mp:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(196, 74, 30, 0.15);
}
.btn-primary {
  padding: 12px 22px;
  font-size: 0.95rem;
  font-weight: 600;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  background: var(--accent);
  color: var(--text-on-accent);
  transition: all 0.2s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}
.btn-primary:hover:not(:disabled) {
  background: var(--accent-hover);
  transform: translateY(-1px);
  box-shadow: 0 8px 24px rgba(196, 74, 30, 0.32);
}
.btn-primary:disabled { background: var(--border-default); color: var(--text-tertiary); cursor: not-allowed; opacity: 1; }
.btn-secondary {
  padding: 12px 22px;
  font-size: 0.95rem;
  font-weight: 600;
  border: 1px solid var(--accent);
  border-radius: 10px;
  cursor: pointer;
  background: transparent;
  color: var(--accent);
  transition: all 0.2s ease;
}
.btn-secondary:hover:not(:disabled) { background: var(--accent-tint); }
/* Ghost (tertiary) */
.btn-ghost {
  padding: 10px 18px;
  font-size: 0.9rem;
  font-weight: 500;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  background: transparent;
  color: var(--text-primary);
  transition: background 0.2s ease;
}
.btn-ghost:hover:not(:disabled) { background: var(--bg-elevated-2); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg-primary); }
::-webkit-scrollbar-thumb { background: var(--border-default); border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); }
[x-cloak] { display: none !important; }

/* === Items LIVRES (utilisés sidebar admin + agent) === */
.book-item {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  margin-bottom: 6px;
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.06);
  transition: all 0.18s ease;
  text-decoration: none;
  color: inherit;
}
.book-item:not(.disabled):hover {
  background: rgba(196, 74, 30, 0.08);
  border-color: rgba(196, 74, 30, 0.5);
  transform: translateX(2px);
}
.book-item.disabled { opacity: 0.45; }
.book-spine {
  width: 4px; height: 32px;
  border-radius: 2px;
  background: linear-gradient(180deg, #C44A1E, #E66B3C);
  flex-shrink: 0;
  box-shadow: 0 0 6px rgba(196, 74, 30, 0.4);
}
.book-spine.off { background: rgba(255, 255, 255, 0.15); box-shadow: none; }
.book-info { flex: 1; min-width: 0; }
.book-tome { font-weight: 700; color: #F5F5F5; font-size: 0.95rem; line-height: 1.1; }
.book-size { font-size: 0.7rem; color: rgba(255, 255, 255, 0.5); margin-top: 2px; }
.book-arrow { color: #C44A1E; font-weight: 700; font-size: 1.1rem; }

/* === Logo (avec fallback texte stylisé si .png absent) === */
.mp-logo-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px;
  border-radius: 999px;
  background: linear-gradient(135deg, #C44A1E 0%, #A33C13 100%);
  box-shadow: 0 4px 12px rgba(196, 74, 30, 0.4);
}
.mp-logo-badge .mp-spiral {
  width: 28px; height: 28px; flex-shrink: 0;
  background: white;
  border-radius: 50%;
  position: relative;
  box-shadow: inset 0 -2px 4px rgba(196, 74, 30, 0.3);
}
.mp-logo-badge .mp-spiral::before,
.mp-logo-badge .mp-spiral::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  border: 3px solid #C44A1E;
  border-top-color: transparent;
  border-left-color: transparent;
}
.mp-logo-badge .mp-spiral::after {
  inset: 9px;
  border-width: 2px;
  border-top-color: #0A0A0A;
  transform: rotate(45deg);
}
.mp-logo-badge .mp-text {
  display: flex; flex-direction: column; line-height: 1;
}
.mp-logo-badge .mp-name { color: white; font-weight: 800; font-size: 1rem; letter-spacing: -0.01em; }
.mp-logo-badge .mp-tagline { color: rgba(255,255,255,0.85); font-size: 0.65rem; font-style: italic; margin-top: 2px; }
.mp-logo-badge.large { padding: 10px 18px; }
.mp-logo-badge.large .mp-spiral { width: 36px; height: 36px; }
.mp-logo-badge.large .mp-name { font-size: 1.3rem; }
.mp-logo-badge.large .mp-tagline { font-size: 0.75rem; }
.mp-logo-badge.xlarge { padding: 14px 24px; }
.mp-logo-badge.xlarge .mp-spiral { width: 50px; height: 50px; }
.mp-logo-badge.xlarge .mp-name { font-size: 1.7rem; }
.mp-logo-badge.xlarge .mp-tagline { font-size: 0.85rem; }

/* =====================================================================
   SOCLE MOBILE (chantier responsive Galaxy S25 Ultra)
   ---------------------------------------------------------------------
   Regles communes a TOUTES les pages du site (tout herite de base.html).
   Principe : mobile d'abord, fluide de 320 a 480 px de large, jamais cale
   sur une largeur unique. Le desktop (>= 1024 px) n'est jamais touche par
   ce bloc : chaque regle est soit universelle et sans effet visible en
   grand, soit enfermee dans une requete media mobile.
   ===================================================================== */

:root {
  /* Zones sures : poinçon de camera en haut, barre de gestes en bas.
     Valent 0 partout ailleurs, donc utilisables sans condition. */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  /* Hauteur d'une barre d'action collante, marge de gestes comprise. */
  --barre-basse: calc(56px + var(--safe-b));
}

/* --- Hauteur d'ecran : 100dvh, jamais 100vh --------------------------
   Sur Chrome Android la barre d'URL se retracte au defilement : `100vh`
   vaut la hauteur AVEC barre retractee, donc un bloc en 100vh depasse
   toujours l'ecran au chargement et fait apparaitre un defilement inutile.
   `100dvh` suit la hauteur reellement visible. Le `100vh` reste en premier
   comme repli pour les moteurs anciens qui ignorent `dvh`. */
.h-ecran   { height: 100vh; height: 100dvh; }
.minh-ecran { min-height: 100vh; min-height: 100dvh; }

/* --- Typographie fluide ---------------------------------------------
   Paliers brutaux remplaces par une interpolation continue : le titre
   reste lisible a 320 px sans devenir minuscule, et garde sa taille
   d'origine en grand ecran (la borne haute du clamp est l'ancienne
   valeur desktop, l'affichage large est donc inchange). */
.h1-fluid { font-size: clamp(1.75rem, 6vw, 3.5rem); line-height: 1.15; }
.h2-fluid { font-size: clamp(1.375rem, 4.5vw, 2.25rem); line-height: 1.2; }
.h3-fluid { font-size: clamp(1.125rem, 3.4vw, 1.5rem); line-height: 1.25; }

/* --- Rien ne depasse jamais en largeur -------------------------------
   On corrige la CAUSE, on ne masque pas le symptome : pas d'
   `overflow-x: hidden` sur `body`. Ces trois regles empechent seulement
   les contenus remplaçables (images, videos, cadres, tableaux) d'imposer
   une largeur superieure a leur conteneur. */
img, video, canvas, svg:not(.ico), iframe, embed, object {
  max-width: 100%;
}
/* `svg.ico` EXCLU volontairement. Ces icones sont dimensionnees en `em` et
   ne peuvent pas deborder ; en revanche, quand une icone est un element de
   flex, `max-width: 100%` se resout contre une largeur elle-meme deduite
   du contenu, et Chrome retient une valeur legerement plus petite
   (14 px -> 12,3 px mesures). Le texte voisin gagnait alors deux pixels et
   changeait de retour a la ligne : une difference reelle en grand ecran,
   pour une regle censee n'agir que sur les contenus remplaçables. */
img, video { height: auto; }
/* `min-width: auto` est la valeur par defaut d'un element flex/grid : une
   cellule de texte long refuse alors de retrecir et pousse toute la ligne
   hors de l'ecran. On autorise le retrecissement, mais SEULEMENT sous
   1024 px : la regle n'est pas neutre en grand ecran (un element qui peut
   retrecir prend une largeur legerement differente, ce qui deplace des
   retours a la ligne — constate sur l'ecran de resultats, ou une mention
   passait a la ligne suivante). Au-dessus de 1024 px, rien ne change. */
/* Rangee « icone + texte + action ». Sur telephone l'action passe sous le
   texte, pleine largeur : un bouton refuse de se couper (`whitespace-nowrap`)
   et prend la moitie de l'ecran, ce qui comprime le texte a un mot par ligne.
   Le texte d'abord, le bouton ensuite : c'est aussi l'ordre de lecture. */
@media (max-width: 767px) {
  .rangee-action > :last-child {
    flex: 1 0 100%;
    text-align: center;
  }
}

@media (max-width: 1023px) {
  /* EXCEPTION : une rangee qui a le droit de passer a la ligne (`flex-wrap`)
     ne doit PAS etre incluse. Elle se replie justement parce que ses cellules
     refusent de retrecir sous leur contenu ; en les autorisant a retrecir, on
     lui retire sa raison de se replier et elle se comprime a la place. Vu sur
     l'ecran de resultats : le titre « Votre rapport personnalise est pret »
     tombait a 11 px de large sur 992 px de haut, une lettre par ligne, parce
     que le bouton voisin, lui, ne se coupe jamais.

     L'exclusion passe par `:where()`, qui ne compte PAS dans la specificite.
     Ecrite en `:not(...)`, elle faisait monter le selecteur de (0,1,0) a
     (0,3,0) : `min-width: 0` ecrasait alors `.tap-44` et la croix de fermeture
     des messages retombait a 16 px de large. */
  .grid > *,
  .flex:where(:not(.flex-wrap)):where(:not(.flex-wrap-reverse)) > * { min-width: 0; }
}

/* --- Champs de saisie : 16 px minimum sur tactile --------------------
   Sous 16 px, Safari iOS et Chrome Android ZOOMENT automatiquement a la
   prise de focus : la mise en page saute, l'utilisateur se retrouve
   decale et doit dezoomer a la main. Regle appliquee au pointeur grossier
   seulement : les densites de l'admin en grand ecran ne changent pas. */
@media (pointer: coarse) {
  input, select, textarea, button {
    font-size: max(16px, 1em);
  }
  /* Un champ qui porte une CLASSE echappe a la regle generale ci-dessus :
     `.text-sm` (14 px), `.text-xs` (12 px), `.msg-champ`, `.draft-input`
     l'emportent par leur specificite, et le navigateur mobile se remet a
     zoomer a la prise de focus.
     Le selecteur retenu (`input[class]`) vaut element + attribut, soit une
     specificite superieure a n'importe quelle regle de CLASSE unique :
     il rattrape donc aussi bien `.text-sm` de Tailwind que les classes
     maison (`.msg-champ`, `.draft-input`, `.input-mp`...) sans avoir a
     toutes les enumerer, et sans `!important`. */
  input[class], select[class], textarea[class] {
    font-size: 1rem;
  }

  /* Champs et boutons : hauteur de doigt. */
  input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]),
  select, textarea {
    min-height: 44px;
  }
  input[type="checkbox"], input[type="radio"] {
    width: 22px; height: 22px;
  }
  /* Une case a cocher de 22 px reste petite : c'est son LIBELLE qui porte
     la surface tactile, on lui donne donc la hauteur reglementaire.
     Le selecteur ne demande PAS un enfant direct : depuis que les cases
     isolees sont enveloppees d'une etiquette de 44 px (`.case-tap`), la
     case est un petit-enfant du libelle qui la decrit. */
  label:has(input[type="checkbox"]),
  label:has(input[type="radio"]) {
    display: flex; align-items: center; gap: 10px;
    min-height: 44px;
  }

  /* Commande a ICONE SEULE (oeil, telechargement, corbeille des tableaux
     d'administration) : environ 30 x 28 px, soit une cible manquable.
     Le second `:not(:has(...))` ecarte les cartes cliquables qui
     contiennent une illustration en plus d'autres elements : elles sont
     de type bloc et changer leur affichage les casserait. */
  a:has(> svg):not(:has(> :not(svg))),
  button:has(> svg):not(:has(> :not(svg))) {
    min-height: 44px; min-width: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
}

/* --- Cibles tactiles : 44 x 44 px -----------------------------------
   Applique aux commandes AUTONOMES (boutons, liens de navigation, icones
   cliquables, elements de menu). Les liens poses au milieu d'une phrase
   en sont exclus : la WCAG 2.5.8 prevoit explicitement cette exception,
   et les agrandir deformerait l'interlignage du texte courant. */
@media (pointer: coarse) {
  button, [role="button"], summary,
  .btn-primary, .btn-secondary, .btn-ghost,
  nav a, header a, footer a, .tap-44 {
    min-height: 44px;
  }
  button, [role="button"], summary,
  .btn-primary, .btn-secondary, .btn-ghost, .tap-44 {
    min-width: 44px;
  }
  /* Un lien de menu n'est pas un bouton : on lui donne la hauteur par le
     remplissage vertical, pour que la zone touchee suive le texte. */
  nav a, header a, .tap-44, .tap-haut-44 {
    display: inline-flex; align-items: center;
  }
  /* `tap-haut-44` : la HAUTEUR reglementaire, sans largeur minimale. Pour une
     commande dont la largeur vient de son libelle et qui vit dans une colonne
     etroite : imposer 44 px de large y tronquait le texte (« Telecharger »
     mesurait 70 px pour une boite ramenee a 44). */
  .tap-haut-44 { min-height: 44px; }
  /* Liens en LISTE (pied de page, menus verticaux) : ils prennent toute la
     largeur de leur colonne. Sans cela, « CGV » ne fait que 30 px de large
     et reste une cible manquable, meme avec 44 px de haut. En bloc, la zone
     touchee couvre la ligne entiere, ce qui est aussi plus previsible pour
     le doigt. Sur grand ecran, `pointer: coarse` est faux : le pied de page
     garde exactement son apparence actuelle. */
  footer li > a, nav ul li > a, .liste-liens > a {
    display: flex; align-items: center; width: 100%;
  }
  /* Lien SEUL dans son bloc, resté en affichage « en ligne » : c'est une
     commande autonome (« Retour », « En savoir plus », une entree de
     liste), et 22 px de haut ne se visent pas au doigt. On l'agrandit par
     un REMPLISSAGE VERTICAL et non en changeant son mode d'affichage :
     `padding` sur un element en ligne agrandit sa zone tactile sans
     toucher a la hauteur de ligne, donc sans deplacer une virgule de la
     mise en page. Changer `display` ici casserait au passage toutes les
     cartes cliquables, qui sont, elles, des liens en bloc.
     Le selecteur `:only-child` fait le tri : un lien pose au milieu d'une
     phrase a forcement des freres (les noeuds de texte comptent). */
  p > a:only-child, li > a:only-child,
  dd > a:only-child, td > a:only-child {
    /* 13 px de part et d'autre : une ligne de texte courante mesure une
       vingtaine de pixels, on depasse donc les 44 px requis meme sur la
       police la plus etroite. A 12 px on retombait a 43. */
    padding-block: 13px;
  }
  /* Boutons a icone seule : centres dans leur carre. */
  button:not(:has(> *:not(svg))) { justify-content: center; }
  /* Un lien qui est ELEMENT D'UNE RANGEE (flex ou grille) est une
     commande autonome : « Reinitialiser » a cote de « Filtrer »,
     « Annuler » a cote de « Enregistrer ». Un lien pose au milieu d'une
     phrase n'est jamais element de flex. Seule la hauteur est imposee :
     un element de flex est deja de type bloc, inutile de toucher a son
     mode d'affichage (ce qui casserait les cartes cliquables). */
  .flex > a, .inline-flex > a, .grid > a { min-height: 44px; }

  /* Paragraphe en `text-xs` (12 px) : c'est une phrase qui se lit, pas un
     badge. Les badges et pastilles sont des <span>, ils ne sont pas
     concernes. Regle bornee au pointeur grossier : la densite de
     l'administration en grand ecran est inchangee. */
  p.text-xs { font-size: 0.875rem; line-height: 1.5; }

  /* Espacement minimal entre deux cibles voisines (8 px). */
  footer li + li { margin-top: 4px; }
}

/* --- Survol : jamais la seule facon d'atteindre une information ------
   Sur un ecran tactile il n'y a pas de survol ; un effet `:hover` y reste
   « colle » apres le tap. On neutralise les transformations decoratives
   et on rend l'etat ACTIF (doigt pose) visible a la place. */
@media (hover: none) {
  .btn-primary:hover, .btn-secondary:hover, .mkt-btn-primary:hover,
  .book-item:not(.disabled):hover, .mkt-nav-brand:hover {
    transform: none;
  }
  .btn-primary:active, .mkt-btn-primary:active { filter: brightness(0.88); }
  a:active, button:active { opacity: 0.85; }
}

/* --- Defilement de fond verrouille quand un menu plein ecran est ouvert
   `position: fixed` sur le corps de page fait perdre la position de
   defilement : on la memorise dans `--scroll-y` et on la restitue a la
   fermeture (cf. le script `verrouScroll` plus bas). */
body.menu-ouvert {
  position: fixed;
  top: calc(var(--scroll-y, 0px) * -1);
  left: 0; right: 0;
  width: 100%;
  overflow: hidden;
}

/* --- Texte secondaire lisible sur un appareil tenu en main -----------
   A poser sur une phrase rendue en 12 px pour gagner en densite : sur un
   ecran d'ordinateur elle passe, sur un telephone elle se plisse les yeux.
   La regle vise l'APPAREIL et non la largeur : un telephone couche fait
   915 px de large et echapperait a un palier `sm:` de Tailwind. */
/* Mention dont la taille etait ecrite EN LIGNE (donc insupplantable) :
   la valeur passe en variable, la regle vit ici. Grand ecran : taille
   d'origine au pixel pres. Appareil tenu en main : plancher de 14 px. */
.note-fluide { font-size: var(--fs-note, 0.8rem); }

@media (hover: none) and (pointer: coarse) {
  .lisible-tactile { font-size: 0.875rem; line-height: 1.5; }
  .note-fluide { font-size: 0.875rem; line-height: 1.5; }
}

/* --- Case a cocher isolee : zone tactile de 44 px --------------------
   Une case de 20 px ne se vise pas au doigt. On l'enveloppe d'une
   etiquette de 44 px (tapoter l'etiquette coche la case, c'est le
   comportement natif de <label>), et une marge negative ramene son
   encombrement de MISE EN PAGE a celui de la case : l'alignement des
   colonnes de l'administration ne bouge donc pas d'un pixel, ni sur
   telephone ni sur ordinateur. Seule la surface sensible grandit.
   Reserve au pointeur grossier : a la souris, viser 20 px ne pose
   aucun probleme et une zone debordante genererait des clics surprenants. */
/* `display: contents` a la souris : l'etiquette ne cree AUCUNE boite, la
   case a cocher est donc positionnee exactement comme avant l'ajout de
   cette enveloppe (une boite `inline-flex` decalait la ligne de base de
   deux pixels, mesurable sur les fiches d'agent). Le comportement est
   inchange : c'est la case elle-meme qu'on vise a la souris. */
.case-tap { display: contents; }
@media (pointer: coarse) {
  .case-tap {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px;
    margin: -11px;
    flex-shrink: 0;
  }
}

/* --- Champs « denses » de l'administration ---------------------------
   Les formulaires de l'administration serrent volontairement leurs champs
   pour tenir plus d'informations a l'ecran. Cette taille etait ecrite EN
   LIGNE (`style="font-size:0.85rem"`), ce qui la rendait impossible a
   supplanter depuis une feuille de style sans `!important`. Elle passe
   donc par une variable : la valeur reste portee par l'element (l'aspect
   en grand ecran est rigoureusement identique), mais la REGLE vit ici et
   peut etre remontee a 16 px sur pointeur grossier (voir plus haut).
   Sans quoi le navigateur mobile zoome a chaque prise de focus. */
.champ-dense { font-size: var(--fs-dense, 0.9rem); }

/* --- Barre d'en-tete des espaces authentifies -------------------------
   L'administration et l'espace formateur redefinissent leur en-tete page
   par page (une vingtaine de gabarits), sans partiel commun. Plutot que de
   reecrire chacun, on leur pose la meme paire de classes et le
   comportement mobile vit ICI, en un seul endroit.

   Ce qui n'allait pas : une rangee unique en `flex` avec quatre a six
   liens et un ressort `flex-1` au milieu. Sur telephone, la rangee
   depassait l'ecran (mesure : 454 px pour 412) et « Deconnexion » sortait
   du champ. Le contenu ne peut PAS etre reduit : ce sont les seules
   navigations de ces espaces.

   Ce qu'on fait : la rangee passe a la ligne, le ressort disparait (il
   empeche tout retour a la ligne utile), et chaque lien recoit sa hauteur
   de doigt via la regle generale `header a`. Au-dessus de 768 px, la barre
   est rigoureusement identique a avant. */
.mp-topbar {
  /* Fond et flou, jusqu'ici ecrits en ligne sur chaque en-tete. Ramenes
     ici pour deux raisons :
       - `backdrop-filter` fait de la barre le BLOC CONTENEUR de ses
         descendants en `position: fixed` : le tiroir plein ecran s'y
         trouvait rogne a la hauteur de la barre ;
       - un flou permanent sur toute la largeur coute cher au processeur
         graphique d'un telephone, pour un effet a peine visible.
     L'aspect en grand ecran est celui d'avant, au pixel pres. */
  background: rgba(10, 10, 10, 0.7);
  /* blur(6px) saturate(120%) et NON blur(20px), qui etait la valeur ecrite
     en ligne : une regle plus haut dans cette feuille
     (`[style*="backdrop-filter"]`) ramenait DEJA tout flou en ligne a 6 px
     pour limiter le cout du compositing au-dessus du canevas anime. En
     sortant le flou de l'attribut `style`, cette regle ne s'appliquait
     plus et l'en-tete repassait a 20 px : c'etait la SEULE difference
     mesurable en 1440 px entre avant et apres. Valeur alignee ici, donc
     rendu identique. */
  backdrop-filter: blur(6px) saturate(120%);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  padding-top: var(--safe-t);
  padding-left: var(--safe-l);
  padding-right: var(--safe-r);
}
@media (max-width: 767px) {
  .mp-topbar {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    /* Sans flou, il faut un fond franc, sinon le contenu de la page se
       lit par transparence sous la barre. */
    background: rgba(10, 10, 10, 0.96);
  }
}
@media (max-width: 767px) {
  /* Une seule rangee : la marque (ou l'etiquette de l'espace) a gauche, le
     bouton de menu a droite. Tous les liens sont dans le tiroir. */
  .mp-topbar-inner {
    flex-wrap: nowrap;
    gap: 10px;
    min-height: 60px;
    padding-top: 8px;
    padding-bottom: 8px;
  }
  /* Le ressort `flex-1` vide n'a plus d'objet : le tiroir se plaque a
     droite par sa propre marge automatique. */
  .mp-topbar-inner > div.flex-1:empty { display: none; }
  /* L'etiquette de l'espace ne pousse pas le bouton hors de l'ecran. */
  .mp-topbar-inner > div:first-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Le reste (compteurs, mentions secondaires) descend dans le tiroir ou
     disparait de la BARRE seulement : l'information reste sur la page. */
  .mp-topbar-inner > div:not(:first-child):not(.menu-espace) { display: none; }
}

/* --- Menu des espaces authentifies (voir _menu_espace.html) ----------
   Bouton a trois barres visible seulement sous 768 px ; au-dessus, la
   barre d'en-tete d'origine reste affichee telle quelle. */
/* Au-dessus de 768 px, le menu de l'espace n'existe pas du tout : c'est
   l'enveloppe ENTIERE qui disparait, et non seulement son bouton. Une
   enveloppe vide restait un element de la rangee `flex` de l'en-tete et
   lui ajoutait un intervalle : les liens de droite se decalaient d'une
   vingtaine de pixels par rapport a l'affichage d'origine. */
.menu-espace { display: none; }
.menu-espace-btn { display: none; }
.menu-espace-panneau { display: none; }

@media (max-width: 767px) {
  .menu-espace { display: block; }
}

@media (max-width: 767px) {
  .menu-espace { margin-left: auto; }
  .menu-espace-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; flex-shrink: 0;
    background: transparent; cursor: pointer;
    border: 1px solid rgba(255,255,255,0.18); border-radius: 10px;
    color: #F5F5F5;
  }
  .menu-espace-btn svg { width: 20px; height: 20px; }

  .menu-espace-panneau {
    display: flex; flex-direction: column;
    position: fixed; inset: 0; z-index: 80;
    background: rgba(10, 8, 7, 0.98);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    padding: calc(12px + var(--safe-t)) calc(16px + var(--safe-r))
             calc(16px + var(--safe-b)) calc(16px + var(--safe-l));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .menu-espace-tete {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-bottom: 10px;
  }
  .menu-espace-titre {
    font-weight: 800; color: var(--accent-light);
    font-size: 0.95rem; letter-spacing: 0.04em;
    overflow-wrap: anywhere;
  }
  .menu-espace-fermer {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; flex-shrink: 0;
    background: transparent; cursor: pointer;
    border: 1px solid rgba(255,255,255,0.18); border-radius: 10px;
    color: #F5F5F5;
  }
  .menu-espace-fermer svg { width: 18px; height: 18px; }

  .menu-espace-panneau nav { display: flex; flex-direction: column; }
  .menu-espace-lien {
    display: flex; align-items: center; min-height: 52px;
    padding: 6px 8px;
    color: rgba(255,255,255,0.86); text-decoration: none;
    font-size: 1.02rem; font-weight: 600;
    border-bottom: 1px solid rgba(255,255,255,0.06);
  }
  .menu-espace-lien.active { color: var(--accent-light); }
  .menu-espace-lien:active { background: rgba(255,255,255,0.06); }

  /* La deconnexion vit SEULE en bas : c'est une action de sortie, elle ne
     doit pas se trouver collee a une destination courante. */
  .menu-espace-sortie { margin-top: auto; padding-top: 18px; }
  .menu-espace-sortie a {
    display: flex; align-items: center; justify-content: center;
    min-height: 52px; border-radius: 12px;
    border: 1px solid rgba(255,255,255,0.22);
    color: #F5F5F5; text-decoration: none; font-weight: 700;
  }

  /* Les liens de la barre passent dans le tiroir : on ne les montre pas
     deux fois. Ils restent atteignables, c'est la meme liste.
     Les liens du tiroir ne sont PAS concernes : ils vivent dans
     `.menu-espace`, ils ne sont donc pas enfants DIRECTS de la barre. */
  .mp-topbar-inner > a { display: none; }
  /* Sauf la marque, qui ramene a l'accueil de l'espace. */
  .mp-topbar-inner > a:first-child { display: inline-flex; }
}
@media (max-width: 767px) and (max-height: 520px) {
  .menu-espace-lien { min-height: 44px; }
  .menu-espace-sortie a { min-height: 44px; }
}

/* --- Messages flash : jamais sous la barre de navigation --------------
   Ils sont en `position: fixed` a 16 px du haut, alors que la barre du site
   est collante et haute de 64 px : sur telephone, le message passait
   DESSOUS et devenait illisible. On le descend sous la barre, on le cale
   dans la zone sure et on lui donne la priorite d'empilement.
   Sur grand ecran (`min-width: 1024px`), la position d'origine est
   retablie plus bas : l'affichage y est inchange. */
.zone-flash {
  top: calc(var(--safe-t) + 76px);
  right: calc(var(--safe-r) + 12px);
  left: calc(var(--safe-l) + 12px);
  z-index: 70;
  max-width: none;
}
@media (min-width: 1024px) {
  .zone-flash {
    top: 1rem; right: 1rem; left: auto;
    max-width: 28rem;
  }
}

/* --- Barre d'action collante en bas d'ecran --------------------------
   Le remplissage integre la barre de gestes Android : sans lui, le bouton
   « Suivant » d'un quiz se retrouve sous la barre du systeme. */
.barre-collante-basse {
  position: sticky; bottom: 0; z-index: 40;
  padding-bottom: calc(10px + var(--safe-b));
  padding-left: calc(12px + var(--safe-l));
  padding-right: calc(12px + var(--safe-r));
}

/* --- Tableaux : cartes empilees sous `md` ----------------------------
   Patron partage (cf. docs/mobile/DECISIONS.md). La vue carte et la vue
   tableau vivent dans le meme gabarit ; le tableau desktop n'est jamais
   modifie. */
.table-cartes { display: block; }
.table-tableau { display: none; }
@media (min-width: 768px) {
  .table-cartes { display: none; }
  .table-tableau { display: block; }
}
/* Carte de ligne : titre + statut en tete, puis couples libelle / valeur. */
.ligne-carte {
  border: 1px solid rgba(255, 255, 255, 0.10);
  background: rgba(255, 255, 255, 0.04);
  border-radius: 14px;
  padding: 14px;
}
.ligne-carte + .ligne-carte { margin-top: 12px; }
.ligne-carte dl {
  display: grid; grid-template-columns: auto 1fr;
  gap: 6px 12px; margin-top: 10px; font-size: 0.9rem;
}
.ligne-carte dt { color: rgba(255, 255, 255, 0.55); }
.ligne-carte dd { margin: 0; text-align: right; overflow-wrap: anywhere; }

/* --- Tableau qui devient une pile de cartes sous `md` ----------------
   Meme resultat que le patron « vue mobile + vue desktop » du cahier des
   charges, mais avec UN SEUL balisage : la vue carte est obtenue en
   changeant le mode d'affichage du tableau, les libelles de colonnes etant
   repris depuis `data-libelle` sur chaque cellule. Un seul balisage veut
   dire une seule verite : impossible qu'une colonne ajoutee apparaisse
   d'un cote et pas de l'autre.

   Mode d'emploi :
     <table class="table-adaptative">
       <td data-libelle="Score moyen">…</td>
   La PREMIERE cellule de chaque ligne fait le titre de la carte : elle ne
   recoit pas de libelle. A partir de `md`, le tableau redevient un tableau,
   strictement identique a ce qu'il etait. */
@media (max-width: 767px) {
  .table-adaptative,
  .table-adaptative > tbody,
  .table-adaptative > tbody > tr,
  .table-adaptative > tbody > tr > td {
    display: block;
    width: 100%;
  }
  .table-adaptative > thead { display: none; }
  .table-adaptative > tbody > tr {
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: rgba(255, 255, 255, 0.04);
    border-radius: 14px;
    padding: 14px;
    margin-bottom: 12px;
  }
  .table-adaptative > tbody > tr > td {
    border: 0;
    padding: 5px 0;
    text-align: left;
  }
  /* Couple libelle / valeur : le libelle a gauche, la valeur a droite,
     comme dans une fiche. */
  .table-adaptative > tbody > tr > td[data-libelle] {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    gap: 6px 14px;
    align-items: start;
  }
  .table-adaptative > tbody > tr > td[data-libelle]::before {
    content: attr(data-libelle);
    color: rgba(255, 255, 255, 0.55);
    font-size: 0.9rem;
  }
  .table-adaptative > tbody > tr > td[data-libelle] > * { justify-self: end; }
  .table-adaptative > tbody > tr > td[data-libelle] { text-align: right; }
  /* Premiere cellule : c'est le titre de la carte. */
  .table-adaptative > tbody > tr > td:first-child {
    font-weight: 600;
    padding-bottom: 8px;
    margin-bottom: 4px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    overflow-wrap: anywhere;
  }
  /* Cellule d'actions : les boutons reprennent la pleine largeur. */
  .table-adaptative > tbody > tr > td[data-libelle="Actions"] {
    display: block; text-align: left; margin-top: 6px;
  }
  .table-adaptative > tbody > tr > td[data-libelle="Actions"]::before {
    content: none;
  }
}

/* --- Conteneur defilant horizontalement (exception justifiee) --------
   Reserve aux tableaux de comptabilite ou la comparaison colonne a
   colonne est indispensable. La premiere colonne reste collee, et un
   degrade sur le bord droit signale qu'il reste du contenu. */
.table-defilante {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.table-defilante table { min-width: max-content; }
.table-defilante th:first-child, .table-defilante td:first-child {
  position: sticky; left: 0; z-index: 1;
  background: var(--bg-elevated-1);
}

/* --- Longs mots : jamais de debordement ------------------------------
   Une adresse e-mail ou un identifiant sans espace depasse la colonne sur
   un ecran etroit. On autorise la cesure la ou c'est necessaire. */
@media (max-width: 767px) {
  h1, h2, h3, h4, p, li, dd, td, th, a, span, label { overflow-wrap: break-word; }
}

/* --- Carrousels horizontaux : une carte tient dans l'ecran -----------
   Les rails de cartes (profils, modules) sont volontairement defilants ;
   ce qui n'allait pas, c'est qu'une carte faisait plus large que l'ecran
   et se retrouvait coupee en plein mot. */
@media (max-width: 767px) {
  .rail-cartes {
    scroll-snap-type: x mandatory;
    scroll-padding-left: 16px;
  }
  .rail-cartes > * {
    scroll-snap-align: start;
    flex: 0 0 86vw;
    max-width: 86vw;
  }
}

/* Si logo.png est present, on le prefere ; sinon le fallback badge s'affiche */
.mp-logo-img-with-fallback { display: block; }
.mp-logo-img-with-fallback ~ .mp-logo-badge { display: none; }
.mp-logo-img-with-fallback[data-broken="1"] { display: none; }
.mp-logo-img-with-fallback[data-broken="1"] ~ .mp-logo-badge { display: inline-flex; }

/* ============================================================
   MODE « APPAREIL MODESTE » (classe `eco` sur <html>)
   ============================================================
   Posee par base.html quand la machine est petite (4 coeurs ou moins, 4 Go ou
   moins, economiseur de donnees, 2G/3G) ou quand le visiteur refuse le
   mouvement. Objectif : rendre au processeur tout ce qui ne sert qu'a decorer.

   Ce qui tombe : le fond anime, les flous d'arriere-plan (les plus chers a
   peindre sur un telephone d'entree de gamme), les animations sans fin et les
   grandes ombres portees. Ce qui reste : la mise en page, les couleurs, les
   transitions courtes au clic. Le contenu n'est jamais ampute. */
html.eco #bgMesh { display: none !important; }

/* Bandes defilantes (avis Google, offres de l'accueil, themes) : en `eco` la
   bande ne defile plus et se parcourt au doigt. ATTENTION : couper l'animation
   sans remettre `transform: none` laisserait la bande figee en plein milieu de
   sa course, donc a moitie vide. */
html.eco .rv-track,
html.eco .of-piste,
html.eco .of-themes-rang {
  animation: none !important;
  transform: none !important;
}
html.eco .rv-marquee,
html.eco .of-bande,
html.eco .of-themes {
  overflow-x: auto;
  -webkit-mask-image: none !important;
          mask-image: none !important;
  scrollbar-width: none;
}
html.eco .rv-marquee::-webkit-scrollbar,
html.eco .of-bande::-webkit-scrollbar,
html.eco .of-themes::-webkit-scrollbar { display: none; }

html.eco [class*="glass"],
html.eco .module-card,
html.eco .mkt-nav,
html.eco .qa-panneau,
html.eco .lsw-btn {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* Une ombre tres large se repeint sur une grande surface : on la resserre. */
html.eco .card-glass,
html.eco .module-card,
html.eco .mkt-card { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35) !important; }

/* === Ecran tactile : pas de flou d'arriere-plan =============================
   `backdrop-filter` est l'effet le plus cher a peindre : le navigateur doit
   copier ce qu'il y a DERRIERE l'element, le flouter, puis le recomposer, a
   chaque image et sur toute la surface. Sur un telephone d'entree de gamme,
   cela suffit a faire saccader un defilement.
   On l'enleve donc sur les appareils tactiles et on rend les fonds un peu plus
   opaques a la place : a l'oeil, la difference est minime ; a la main, le
   defilement redevient franc. Les ecrans a souris gardent l'effet verre. */
@media (hover: none) and (pointer: coarse) {
  .card-glass,
  .module-card,
  .mkt-nav,
  .qa-panneau,
  .qa-couche,
  [style*="backdrop-filter"] {
    -webkit-backdrop-filter: none !important;
            backdrop-filter: none !important;
  }
  .card-glass { background: rgba(17, 17, 17, 0.94); }
  /* `!important` : la barre definit son fond dans le gabarit vitrine, charge
     apres cette feuille. Sans flou, il lui faut un fond franc. */
  .mkt-nav { background: rgba(19, 19, 23, 0.96) !important; }
}


/* ==========================================================================
   Renvoi vers la page pilier « certification AFA »
   --------------------------------------------------------------------------
   Sert le partiel templates/marketing/_lien_certification.html, inclus sur
   l'accueil, les tarifs et le guide. La regle vit ICI et non dans un gabarit :
   les styles vitrine sont definis page par page, une regle posee dans l'un
   d'eux ne s'appliquerait pas dans les autres.
   ========================================================================== */
.lien-certif {
  display: block;
  max-width: 720px;
  margin: 18px auto 0;
  padding: 14px 18px;
  border: 1px solid rgba(230, 107, 60, 0.28);
  border-left: 3px solid #C44A1E;
  border-radius: 12px;
  background: rgba(196, 74, 30, 0.07);
  text-decoration: none;
  transition: background 0.18s, border-color 0.18s;
}
.lien-certif:hover,
.lien-certif:focus-visible {
  background: rgba(196, 74, 30, 0.13);
  border-color: rgba(230, 107, 60, 0.5);
}
.lien-certif-titre {
  display: block;
  font-weight: 700;
  font-size: 0.98rem;
  color: #E66B3C;
  margin-bottom: 2px;
}
.lien-certif-texte {
  display: block;
  font-size: 0.88rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.62);
}
