/* Jetons de couleur du site, en deux palettes.
 *
 * Les pages n'ecrivent jamais une couleur en dur : elles n'utilisent que des
 * noms de roles (--bg, --fg2, --line...), et basculent donc d'un theme a
 * l'autre sans rien changer chez elles. Meme principe que src/theme.tsx dans
 * l'app, et les valeurs claires sont les siennes, deja calibrees au contraste.
 *
 * Trois etats possibles, dans cet ordre de priorite :
 *   1. [data-theme] pose sur <html> par le choix de l'utilisateur ;
 *   2. sinon, la preference du systeme ;
 *   3. sinon, le sombre, qui reste l'identite du site.
 *
 * `color-scheme` accompagne chaque palette : c'est lui qui met les ascenseurs,
 * les champs de formulaire et les menus natifs dans le bon sens.
 */

:root {
  color-scheme: dark;

  --bg:        #0E0F11;
  --surface:   #16181B;
  --surface2:  #1E2125;
  --line:      rgba(255, 255, 255, 0.08);
  --line2:     rgba(255, 255, 255, 0.12);

  --fg:        #F2F4F7;
  --fg2:       #A8AEB7;
  --fg3:       #868C95;

  /* Marque. `--lime` ne sert qu'aux APLATS, `--accent` a tout ce qui porte du
   * texte ou une icone : sur du blanc le vert plein tombe a 2,2:1, illisible.
   * En sombre les deux se confondent, d'ou la duplication apparente. */
  --lime:      #D7FF3A;
  --accent:    #D7FF3A;
  --on-lime:   #0E0F11;
  --gold:      #FFB23A;
  --gold-text: #FFB23A;
  --gold-soft: rgba(255, 178, 58, 0.08);
  --lime-soft: rgba(215, 255, 58, 0.10);
  --lime-line: rgba(215, 255, 58, 0.20);
  --lime-dim:  #A8C82C;

  /* Halos de marque de la page d'accueil. Ils portent l'identite sur du noir ;
   * sur du blanc un halo sature bave, d'ou des valeurs bien plus discretes en
   * clair. */
  --glow-lime: rgba(215, 255, 58, 0.25);
  --glow-gold: rgba(255, 178, 58, 0.20);
  /* Ombre laterale d'un tableau qui deborde. */
  --scroll-shadow: rgba(0, 0, 0, 0.45);

  /* Barre superieure collante : translucide pour laisser jouer le flou, elle
   * doit donc reprendre la couleur de la page et non un noir fixe. */
  --bg-blur:   rgba(14, 15, 17, 0.85);
  --verre:       rgba(22, 24, 27, 0.62);
  --verre-line:  rgba(255, 255, 255, 0.10);
  --verre-ombre: 0 10px 34px rgba(0, 0, 0, 0.45);
}

/* Clair par preference systeme, sauf choix explicite du sombre. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) {
    color-scheme: light;

    --bg:        #EFEFEC;
    --surface:   #FFFFFF;
    --surface2:  #E4E4E0;
    --line:      rgba(14, 15, 17, 0.08);
    --line2:     rgba(14, 15, 17, 0.14);

    --fg:        #0E0F11;
    --fg2:       #565B63;
    --fg3:       #63686F;

    --lime:      #5BC68A;
    --accent:    #177B4A;
    --on-lime:   #0E0F11;
    --gold:      #FFB23A;
    --gold-text: #9A6200;
    --gold-soft: rgba(154, 98, 0, 0.10);
  --lime-soft: rgba(23, 123, 74, 0.12);
  --lime-line: rgba(23, 123, 74, 0.30);
  --lime-dim:  #3FA872;
  --glow-lime: rgba(23, 123, 74, 0.14);
  --glow-gold: rgba(154, 98, 0, 0.12);
  --scroll-shadow: rgba(14, 15, 17, 0.18);
    --lime-soft: rgba(23, 123, 74, 0.12);
    --lime-line: rgba(23, 123, 74, 0.30);
    --lime-dim:  #3FA872;
    --glow-lime: rgba(23, 123, 74, 0.14);
    --glow-gold: rgba(154, 98, 0, 0.12);
    --scroll-shadow: rgba(14, 15, 17, 0.18);
    --bg-blur:   rgba(239, 239, 236, 0.85);
    --verre:       rgba(255, 255, 255, 0.65);
    --verre-line:  rgba(14, 15, 17, 0.08);
    --verre-ombre: 0 10px 34px rgba(14, 15, 17, 0.10);
  }
}

/* Choix explicite du clair : doit gagner meme si le systeme est en sombre. */
:root[data-theme='light'] {
  color-scheme: light;

  --bg:        #EFEFEC;
  --surface:   #FFFFFF;
  --surface2:  #E4E4E0;
  --line:      rgba(14, 15, 17, 0.08);
  --line2:     rgba(14, 15, 17, 0.14);

  --fg:        #0E0F11;
  --fg2:       #565B63;
  --fg3:       #63686F;

  --lime:      #5BC68A;
  --accent:    #177B4A;
  --on-lime:   #0E0F11;
  --gold:      #FFB23A;
  --gold-text: #9A6200;
  --gold-soft: rgba(154, 98, 0, 0.10);
  --bg-blur:   rgba(239, 239, 236, 0.85);
  --verre:       rgba(255, 255, 255, 0.65);
  --verre-line:  rgba(14, 15, 17, 0.08);
  --verre-ombre: 0 10px 34px rgba(14, 15, 17, 0.10);
}

/* ── Bouton de bascule ───────────────────────────────────────────────────── */

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--line2);
  border-radius: 999px;
  background: transparent;
  color: var(--fg2);
  cursor: pointer;
  flex-shrink: 0;
  transition: color .15s, border-color .15s;
}
.theme-toggle:hover { color: var(--fg); border-color: var(--fg3); }
.theme-toggle svg   { width: 17px; height: 17px; display: block; }

/* Une seule des deux icones est visible, selon le theme actif. Le CSS suit la
 * meme cascade que les palettes ci-dessus : pas de JavaScript pour ca. */
.theme-toggle .icon-sun  { display: block; }
.theme-toggle .icon-moon { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) .theme-toggle .icon-sun  { display: none; }
  :root:not([data-theme='dark']) .theme-toggle .icon-moon { display: block; }
}
:root[data-theme='light'] .theme-toggle .icon-sun  { display: none; }
:root[data-theme='light'] .theme-toggle .icon-moon { display: block; }
:root[data-theme='dark']  .theme-toggle .icon-sun  { display: block; }
:root[data-theme='dark']  .theme-toggle .icon-moon { display: none; }

/* Le bouton se range a cote du selecteur de langue, dans l'en-tete. */
.head-actions { display: flex; align-items: center; gap: 10px; }

/* Badges des boutiques.
 *
 * Apple fournit deux variantes et impose la noire sur fond clair, la blanche
 * sur fond sombre. On sert donc les deux images et on cache la mauvaise, en
 * suivant exactement les trois etats du theme ci-dessus : sans ca, un badge
 * blanc sur fond blanc disparaitrait pour qui a choisi le theme clair.
 *
 * Google n'en publie qu'une seule, noire a liseré gris, prevue pour tenir sur
 * les deux fonds. Elle ne porte donc aucune de ces classes.
 */
.badge-sombre { display: block; }
.badge-clair  { display: none; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) .badge-sombre { display: none; }
  :root:not([data-theme='dark']) .badge-clair  { display: block; }
}

:root[data-theme='light'] .badge-sombre { display: none; }
:root[data-theme='light'] .badge-clair  { display: block; }

/* Cartes d'articles de la page d'accueil. Le liseré au survol ne peut pas être
   une classe Tailwind : `hover:border-lime/30` n'est pas dans le CSS compilé,
   et l'y ajouter obligerait à régénérer tailwind.css. */
.carte-article:hover { border-color: rgba(215, 255, 58, 0.30); }
:root[data-theme='light'] .carte-article:hover,
:root:not([data-theme='dark']) .carte-article:hover { border-color: rgba(63, 168, 114, 0.45); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .carte-article:hover { border-color: rgba(215, 255, 58, 0.30); }
}

/* ── Verre du menu flottant ────────────────────────────────────────────────
 * Une pastille detachee des bords, translucide, FLOUTEE ET SURSATUREE. La
 * saturation est ce qui distingue un vrai verre d'un fond semi-opaque : c'est
 * elle qui fait vibrer les couleurs qui defilent dessous, comme la GlassView
 * de l'app.
 *
 * Ici et pas dans le style des accueils : le menu est repris par TOUTES les
 * pages, et theme.css est le seul fichier qu'elles chargent en commun.
 */
.nav-verre, .topbar {
  background: var(--verre);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid var(--verre-line);
  box-shadow: var(--verre-ombre);
  border-radius: 999px;
}
/* Sans backdrop-filter, un fond a 62 % laisserait lire le texte au travers :
 * on retombe sur le fond opaque de l'ancien bandeau. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav-verre, .topbar { background: var(--bg-blur); }
}

/* ── Menu de site, identique sur TOUTES les pages ──────────────────────────
 * Ecrit sans Tailwind : les pages legales et d'aide ne le chargent pas, et
 * seule une feuille commune peut garantir que le menu soit vraiment le meme
 * partout, et non trois variantes qui derivent.
 *
 * Il remplace les trois formes qui coexistaient : l'en-tete Tailwind des
 * accueils, la `.topbar` des dix pages legales, et le `<header>` nu de aide/
 * et help/.
 */
.nav-flottant {
  position: fixed; top: 12px; left: 0; right: 0; z-index: 50;
  padding: 0 12px;
  /* Les pages d'aide et legales gardent un `header{display:flex}` local. Sans
   * ce rappel, la pastille devient un element flex : elle se dimensionne alors
   * a son contenu (620 px) au lieu de remplir jusqu'a ses 768, et la marque se
   * retrouve collee aux liens. */
  display: block;
  pointer-events: none;            /* seule la pastille capte les clics */
}
.nav-menu {
  pointer-events: auto;
  max-width: 768px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 14px 9px 18px;
  border-radius: 999px;
  font-size: 14px;
}
.nav-marque {
  display: flex; align-items: center; gap: 10px;
  color: var(--fg); text-decoration: none; font-weight: 600; font-size: 16px;
}
.nav-marque img { width: 30px; height: 30px; border-radius: 8px; }
.nav-liens { display: flex; align-items: center; gap: 22px; }
.nav-liens a { color: var(--fg2); text-decoration: none; font-weight: 500; transition: color .2s; }
/* Les dix pages legales soulignent leurs liens de corps de texte :
 *   a { border-bottom: 1px solid rgba(215,255,58,.3) }
 *   a:hover { border-bottom-color: var(--accent) }
 * Un `a` nu ne pese rien, mais `a:hover` (0,1,1) bat `.nav-marque` (0,1,0) :
 * les liens du menu heritaient donc du trait pale en permanence, et de
 * l'accent au survol. On passe a (0,2,1) pour couvrir les deux etats.
 * La pastille de langue est exclue : sa bordure complete, elle, est voulue. */
.nav-menu a:not(.nav-lang) { border-bottom: none; }
.nav-liens a:hover { color: var(--fg); }
.nav-actions { display: flex; align-items: center; gap: 8px; }
.nav-lang {
  color: var(--fg2); text-decoration: none; font-weight: 500; font-size: 13px;
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--line);
  transition: color .2s, border-color .2s;
}
.nav-lang:hover { color: var(--fg); border-color: var(--lime-line); }
.nav-cta {
  background: var(--lime); color: var(--on-lime); text-decoration: none;
  font-weight: 700; font-size: 14px; padding: 8px 16px; border-radius: 999px;
  white-space: nowrap;
}
/* Sous 900 px la pastille ne peut plus tout loger : les liens de section
 * disparaissent, le reste demeure. Le menu n'est jamais SIMPLIFIE sur grand
 * ecran, il se replie seulement quand la place manque physiquement.
 *
 * Le Blog fait exception et reste affiche. Les trois autres liens ne font que
 * defiler la page ou l'on est deja ; le blog, lui, est la seule autre partie
 * du site, et sans ce lien elle devenait introuvable au telephone. On cible
 * les ancres plutot que le blog : dans les quinze navigations du site, les
 * liens de section portent tous un `#` et le blog n'en porte jamais.
 *
 * « Fonctionnalites » est devenu une page a part entiere et ne porte donc plus
 * de `#` : il reste affiche tant qu'il tient, et cede la place au telephone.
 *
 * Ces deux regles ne sont plus que le REPLI SANS JAVASCRIPT : avec lui, sous
 * 900 px, tous les liens passent dans le tiroir (cf. « Tiroir du menu »). */
@media (max-width: 900px) {
  .nav-liens { display: flex; }
  .nav-liens a[href*="#"] { display: none; }
}
@media (max-width: 640px) {
  .nav-liens a[href$="/fonctionnalites/"], .nav-liens a[href$="/features/"] { display: none; }
}
@media (max-width: 460px) { .nav-cta { display: none; } }

/* ── Pastille reduite au defilement ────────────────────────────────────────
 * Passe le haut de page, le menu n'a plus a montrer le sommaire : il se ramene
 * a la marque, la bascule de theme et le bouton. Tombent les liens de section
 * et le choix de langue, qui se decide a l'arrivee et pas en pleine lecture.
 *
 * L'etat se leve des qu'on remonte (cf. js/theme.js), pas seulement au sommet :
 * sur une page longue, les liens restent joignables d'un coup de molette.
 *
 * DEUX PRECAUTIONS CONTRE LES A-COUPS
 *
 * 1. Les liens sortent du flux. En element flex, chaque image de l'animation
 *    relayoutait la rangee entiere et repositionnait quatre textes ; hors flux,
 *    la largeur ne deplace plus que le groupe de droite.
 * 2. La largeur est seule a s'animer. Animer aussi le rembourrage et la taille
 *    du logo obligeait le navigateur a remesurer les enfants a chaque image,
 *    et la pastille porte un `backdrop-filter` qu'il faut alors recalculer sur
 *    une surface qui change de taille : c'est ce qui coutait le plus cher.
 *
 * `overflow: hidden` garde les liens dans le galet pendant que la largeur
 * court : ils se decouvrent avec lui au lieu de deborder de ses bords.
 */
.nav-menu {
  position: relative;
  overflow: hidden;
  transition: max-width .38s cubic-bezier(.4, 0, .2, 1);
}
.nav-liens {
  position: absolute; left: 50%; transform: translateX(-50%);
  transition: opacity .22s ease;
}
.nav-lang { transition: opacity .22s ease; }

.nav-flottant.est-reduit .nav-menu { max-width: 340px; }
.nav-flottant.est-reduit .nav-liens,
.nav-flottant.est-reduit .nav-lang { display: none; }

/* Etat intermediaire pose par js/theme.js : les liens ont deja leur place mais
 * restent transparents. La pastille s'elargit d'abord, ils paraissent ensuite,
 * et au repli l'ordre s'inverse. */
.nav-flottant.liens-attente .nav-liens,
.nav-flottant.liens-attente .nav-lang { opacity: 0; transition-duration: .16s; }

/* Au telephone, la pastille ne se resserre pas. Elle y occupe deja toute la
 * largeur utile et n'a que le Blog a montrer : le repli ne gagnait donc rien,
 * il ne faisait que retirer ce lien puis le rendre a chaque changement de sens
 * du defilement. On neutralise l'apparence plutot que la pose des classes :
 * le JS peut continuer a les ecrire, le redimensionnement reste juste sans
 * qu'aucun etat n'ait a etre resynchronise.
 * `max-width` reprend sa valeur de base et non `none`, pour que la transition
 * garde deux longueurs interpolables et ne saute pas. */
@media (max-width: 900px) {
  .nav-flottant.est-reduit .nav-menu { max-width: 768px; }
  .nav-flottant.est-reduit .nav-liens { display: flex; }
  .nav-flottant.est-reduit .nav-lang { display: inline-block; }
  .nav-flottant.liens-attente .nav-liens,
  .nav-flottant.liens-attente .nav-lang { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .nav-menu, .nav-liens, .nav-lang { transition: none; }
}

/* ── Tiroir du menu, sous 900 px ───────────────────────────────────────────
 * La pastille n'y loge plus les liens : un bouton ouvre un tiroir qui les
 * porte TOUS, plus le telechargement, que la pastille perd sous 460 px.
 *
 * Bouton et tiroir sont poses par js/theme.js a partir des liens de
 * `.nav-liens` : aucune des navigations du site n'est a retoucher, et un lien
 * ajoute au menu arrive tout seul dans le tiroir. C'est aussi pourquoi tout
 * depend de `.a-tiroir`, que le script pose : sans JavaScript, la pastille
 * garde ses liens visibles comme avant.
 *
 * Le tiroir est un FRERE de la pastille, pas son enfant : elle porte
 * `overflow: hidden` pour son animation de largeur et le rognerait. */
.nav-burger { display: none; }
.nav-tiroir { display: none; }
@media (max-width: 900px) {
  .nav-flottant.a-tiroir .nav-liens { display: none; }
  .nav-flottant.a-tiroir .nav-burger { display: inline-flex; }
  .nav-burger {
    align-items: center; justify-content: center;
    width: 34px; height: 34px; padding: 0; flex-shrink: 0;
    border: 1px solid var(--line2); border-radius: 999px;
    background: transparent; color: var(--fg2); cursor: pointer;
    transition: color .15s, border-color .15s;
  }
  .nav-burger:hover { color: var(--fg); border-color: var(--fg3); }
  .nav-burger svg { width: 17px; height: 17px; display: block; }
  .nav-burger .icon-fermer { display: none; }
  .nav-burger[aria-expanded="true"] .icon-ouvrir { display: none; }
  .nav-burger[aria-expanded="true"] .icon-fermer { display: block; }

  .nav-tiroir.nav-verre {
    pointer-events: auto;
    max-width: 768px; margin: 8px auto 0; padding: 8px;
    border-radius: 22px;
    flex-direction: column; gap: 2px;
    max-height: calc(100vh - 96px); overflow-y: auto;
  }
  .nav-tiroir.est-ouvert { display: flex; }
  /* (0,2,1), comme pour la pastille : les pages legales soulignent leurs `a`. */
  .nav-tiroir a:not(.nav-cta) {
    display: block; padding: 13px 14px; border-radius: 14px; border-bottom: none;
    color: var(--fg); text-decoration: none; font-weight: 500; font-size: 16px;
  }
  .nav-tiroir a:not(.nav-cta):hover { background: var(--line); }
  .nav-tiroir .nav-cta {
    display: block; margin-top: 6px; padding: 13px 16px; border-bottom: none;
    text-align: center; font-size: 16px; border-radius: 14px;
  }
}

/* Le menu est FIXE, donc hors du flux : sans reserve, le contenu des pages
 * secondaires passerait dessous. La pastille fait 12 px de haut plus environ
 * 48 de hauteur, on reserve 84 pour qu'il reste de l'air.
 * Les deux accueils et le blog ont deja leur propre decalage. */
.nav-flottant + h1,
.nav-flottant + .container { padding-top: 124px; }
/* Toutes les pages enveloppent leur contenu dans un <main>. Les pages
 * secondaires y prennent la meme reserve que ci-dessus. Le blog en demande
 * davantage : son h1 y perd la marge haute que les autres pages lui donnent,
 * et son interlignage serre fait deborder l'encre au-dessus de la boite ;
 * sans rattrapage son titre arrive 35 px plus haut que partout ailleurs.
 * Les deux accueils, eux, posent deja leur propre decalage sur le hero
 * (pt-32) : la reserve ne doit pas s'y empiler. */
.nav-flottant + main { padding-top: 124px; }
.nav-flottant + main.blog { padding-top: 152px; }
.nav-flottant + main.accueil { padding-top: 0; }
@media (max-width: 640px) {
  .nav-flottant + h1,
  .nav-flottant + .container,
  .nav-flottant + main { padding-top: 104px; }
  .nav-flottant + main.blog { padding-top: 130px; }
  .nav-flottant + main.accueil { padding-top: 0; }
}

/* ── Rythme editorial ──────────────────────────────────────────────────────
 * Trois pieces, dans l'esprit des pages d'app les mieux tenues : un intertitre
 * en capitales qui annonce le chapitre, un titre nettement plus lourd et plus
 * serre que ce que donne `font-bold tracking-tight`, et une revelation mot a
 * mot au defilement.
 *
 * Ces titres ne passent PAS par des classes utilitaires. `css/tailwind.css`
 * est un build fige regenere a la main : une taille ecrite en `xl:text-6xl`
 * depend du scan, alors qu'un `clamp()` tient tout seul entre 360 et 1440 px
 * sans point de rupture. Corollaire : les h1/h2 concernes ont perdu leurs
 * classes de taille, de graisse, d'interlignage et d'approche, sans quoi
 * Tailwind — charge APRES ce fichier — reprendrait la main.
 */

.kicker {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-bottom: .85rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fg3);
}
.kicker::before {
  content: "";
  flex: none;
  width: 20px;
  height: 1px;
  background: var(--accent);
}
/* Sur l'aplat lime, `--fg3` et `--accent` sont hors sujet : le chapitre y est
 * un retrait de l'encre locale, pas une couleur de plus. */
.kicker--aplat { color: currentColor; opacity: .58; }
.kicker--aplat::before { background: currentColor; }

.titre-hero {
  font-weight: 800;
  /* Plafond a 4.5rem et non 4.75 : au-dela de 1435 px la colonne du hero se
   * fige a 593 px pendant que la police continuait de grandir, et « Bats tes
   * records. » reclamait 594. Un pixel de trop, donc un retour a la ligne au
   * milieu de la phrase sur presque tous les ecrans de bureau.
   *
   * Le plafond seul est abaisse : 5.6vw vaut 72 px des 1286 px de large, donc
   * rien ne change en dessous. Au-dessus, la ligne francaise garde 30 px de
   * marge et l'anglaise 50, au lieu de -1 et 20. */
  font-size: clamp(2.25rem, 5.6vw, 4.5rem);
  line-height: .95;
  letter-spacing: -.04em;
}
.titre {
  font-weight: 800;
  font-size: clamp(2rem, 5.6vw, 3.75rem);
  line-height: .95;
  letter-spacing: -.035em;
}
.titre-3 {
  font-weight: 800;
  font-size: clamp(1.75rem, 3.4vw, 2.75rem);
  line-height: 1;
  letter-spacing: -.035em;
}

/* Revelation mot a mot. Le decoupage est fait par le script de la page et
 * jamais ecrit dans le HTML : sans JavaScript le titre reste une phrase, pour
 * les moteurs comme pour les lecteurs d'ecran.
 *
 * `overflow: hidden` sur le mot fait le masque d'ou le texte monte. Il couperait
 * les jambages des g, p et y : la paire padding/marge de .14em rend au mot la
 * place qu'il faut sans decaler l'interlignage. */
.mots .mot {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: .14em;
  margin-bottom: -.14em;
}
.mots .mot > span {
  display: inline-block;
  opacity: 0;
  transform: translateY(105%);
  transition: opacity .7s cubic-bezier(.22,.61,.36,1),
              transform .7s cubic-bezier(.22,.61,.36,1);
  transition-delay: var(--d, 0s);
}
.mots.on .mot > span { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .mots .mot { overflow: visible; }
  .mots .mot > span { opacity: 1; transform: none; transition: none; }
}

/* Le hero garde sa cascade d'entree, mais pas sur le titre : la classe `.mots`
 * n'arrive que si le script a decoupe, donc sans JavaScript le titre monte
 * comme avant. Avec, la revelation mot a mot remplace la montee du bloc, qui
 * ferait deux animations pour un seul geste. */
.entree > .mots { animation: none; opacity: 1; transform: none; }

/* `.gradient-text` peint son degrade derriere SA boite, clippe sur son texte.
 * Un mot qu'on translate sort de ce clip et part invisible : chaque mot porte
 * donc son propre degrade des lors qu'il est decoupe. */
.mots .gradient-text .mot > span {
  background: linear-gradient(135deg, var(--lime) 0%, var(--lime-dim) 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ── Panneau ───────────────────────────────────────────────────────────────
 * Une rangee d'ecran n'est plus posee a meme la page : elle tient dans une
 * carte, un demi pour le texte, un demi pour le visuel. C'est ce qui donne au
 * chapitre son decoupage sans avoir besoin d'un filet entre chaque bloc.
 *
 * Le rapport de valeurs est le meme dans les deux themes — la carte est d'un
 * cran plus claire que la page — donc rien a conditionner : #16181B sur
 * #0E0F11 en sombre, blanc sur #EFEFEC en clair.
 *
 * La section portait un degrade vertical qui passait par `--surface` en son
 * milieu : les panneaux y auraient disparu. Il a saute, les cartes font
 * desormais le rythme a sa place.
 */
.panneau {
  /* Le rembourrage devient une variable : le telephone doit le reprendre en
   * negatif pour descendre jusqu'au bord, et il est en `clamp`, donc illisible
   * depuis une classe utilitaire. */
  --pan-pad: clamp(1.75rem, 4vw, 4rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: clamp(22px, 2.6vw, 40px);
  padding: var(--pan-pad);
  /* Garde-fou : si le telephone depassait d'un pixel, l'arrondi de la carte le
   * rognerait au lieu de le laisser saillir. */
  overflow: hidden;
}

/* Telephone colle au bas de la carte. Il mange le rembourrage bas, si bien que
 * sa coupe franche se confond avec l'arete de la carte au lieu de flotter au
 * milieu du blanc. La rangee se resserre d'autant. */
.tel-colle { margin-bottom: calc(var(--pan-pad) * -1); }
