/* Charte vousyetes v4 (2026-08-16). Chargé APRÈS le <style> de chaque page, donc il gagne.
   Source : memory/chartes-marques.md + la charte v4 validée par David le 2026-08-16.

   CE QUI CHANGE DEPUIS LA v3, et pourquoi.
   Le crème #F0EEE6 n'est plus le sol : il virait au jaune et David l'a dit
   deux fois. Il devient une matière ponctuelle (--creme). Le sol passe à un
   gris froid. L'orange entre comme accent, le bleu et l'inox ne bougent pas.

   LA MESURE QUI A DECIDE DU SYSTEME. L'orange #E8622A donne 2.71 de contraste
   sur le crème et 2.88 sur le gris, quand il en faut 4.5. Le foncer pour
   sauver le clair le tue sur le sombre (#A93E12 tombe à 2.86 sur charbon).
   AUCUN orange ne passe les deux fonds. Donc l'orange ne vit QUE sur charbon,
   et tout ce qui est technique (prompt, code, bouton principal) bascule sur
   panneau sombre. Le clair reste pour lire.
   Corollaire non négociable : un bouton orange porte du texte CHARBON. Le
   blanc sur orange tombe à 3.38.

   LES NOMS DE JETONS NE CHANGENT PAS, seulement leurs valeurs. --paper est
   utilisé 201 fois, --accent 1000 fois, --ink 775 fois : renommer aurait
   cassé sept pages pour un gain nul.

   Teal #2ED9C3 toujours interdit (rejeté 2x). Zéro halo décoratif. */
:root{
  --paper:#ECEDEE;        /* LE SOL. Gris froid (R-B = -2). Remplace le crème #F0EEE6 */
  --card:#E4E4E1;         /* surface posée sur le sol : cartes, encadrés */
  --creme:#E7E3D8;        /* la matière chaude de la v3, GARDEE mais ponctuelle */
  --ink:#15171C;          /* encre. L'ancien #0b0b0d était un neutre pur de
                             saturation 2, il n'appartenait à aucune famille.
                             Celui-ci porte la même dérive bleue que le charbon.
                             15.30 de contraste sur le sol. */
  --body:#22252C;
  --soft:#5A6070;         /* texte secondaire. 5.36 sur le sol.
                             Remplace #5C6975, calé sur le crème disparu. */
  --line:#D2D4D7;         /* filet. Froid comme le sol, l'ancien #DAD6CA était crème */

  /* --- LE CHARBON : c'est ici que vit la machine --- */
  --charbon:#16181D;      /* panneau technique, le SOL de l'orange.
                             Assez froid (B-R = +7) pour que l'orange brûle au
                             lieu de virer marron. Le piège vérifié sur
                             drink.withdavid : un charbon brun + orange = boue. */
  --charbon-2:#1F2229;    /* surface DANS le charbon */
  --line-d:#2C3038;       /* filet sur charbon */
  --sur-charbon:#E8E9EB;  /* texte sur charbon. 14.62 */
  --inox:#C3CED8;         /* texte doux sur charbon. 11.11. Etait en dur 5 fois */

  /* --- L'ORANGE : accent, sur charbon uniquement --- */
  --orange:#E8622A;       /* 5.25 sur charbon. INTERDIT sur fond clair */
  --orange-ink:#A93E12;   /* le même, encré, pour petit texte sur clair. 5.29 */

  --accent:#1F5BFF;       /* bleu signal. INCHANGE, demande de David */
  --accent-2:#3A62E8;
  /* Bleu de TEXTE, ajoute le 2026-08-10. Le bleu de marque #1F5BFF passe tout
     juste sur le creme clair (4.52) mais tombe a 4.21 sur le creme dense --card
     et sur le badge #DDE6FF, donc sous le seuil de 4.5 des qu'il sert de texte
     en petit corps. Cette nuance garde la meme teinte, un cran plus foncee :
     5.19 sur card, 5.20 sur badge, 5.58 sur paper.
     --accent reste inchange pour les fonds de boutons et les gros elements.
     EXTENSION de charte, pas un changement : a valider par David. */
  --accent-ink:#1A4FE0;
  /* Sombre de SURFACE, ajoute le 2026-08-12. Le site n'avait qu'une valeur
     sombre, #0b0b0d, de saturation 2 : un quasi-noir neutre, qui n'appartient a
     aucune famille de la charte. Pose en grand (le hero d'ai-stack, le pied de
     page, les boites de prompt, les cartes sombres) ca fait un aplat mort, et
     l'ecran bleu nuit des mascottes y semblait etranger.
     Cette nuance garde la meme profondeur avec une derive bleue : elle parle au
     bleu de marque et aux ecrans des mascottes, et le blanc y passe a 17.9 de
     contraste, donc tres au-dessus du seuil.
     On ne teinte PAS --ink : il sert de couleur de TEXTE a 48 endroits et
     seulement 7 fois de fond. Meme logique que --accent contre --accent-ink. */
  --dark:#0F1422;
}
body{background:var(--paper)}

/* cartes : radius 26, pas de bordure dure sur crème */
.card,.starthere-card,.how,.firststep,.note,.promptbox{border-radius:26px}
.card{background:#F7F5EF;border-color:var(--line)}
.card.feat{background:var(--card);border-color:#D2CDBE}
.card:hover{border-color:var(--accent)}

/* boutons et pills : 999px */
button.sub,.copybtn,.starthere-go,.missing-link,.filters button,.lang button{border-radius:999px}
.filters button.on,.lang button.on{background:var(--ink);border-color:var(--ink)}

/* sections claires qui étaient blanches */
.drops{background:var(--card);border-top-color:var(--line)}
nav,.vye-nav{background:rgba(240,238,230,.92)!important;border-bottom-color:var(--line)!important}

/* champs */
input[type=email]{border-radius:999px;background:#F7F5EF;border-color:var(--line)}

/* plus d'air, façon novitckii */
.hero{padding-top:76px}
.grid{gap:20px}

/* restes d'indigo en dur. Sur fond sombre le kicker passe en inox :
   la charte réserve le bleu au signal seul (données, LED, boutons). */
.starthere-k,.hero.dark .kicker,.tb-links a{color:#C3CED8}
/* kicker sur fond clair : le bleu principal passe le contraste (4.52), pas l'accent-2 (4.42) */
.hero:not(.dark) .kicker,.kicker{color:var(--accent)}
.hero.dark .kicker{color:#C3CED8}
.starthere-card p{color:#B9C2CC}
.b-local{background:#DDE6FF;color:#1F5BFF}
.card.feat,.box.good,.mode.feat{border-color:#D2CDBE}
input[type=email]:focus{box-shadow:0 0 0 3px rgba(31,91,255,.15)}
.missing-link:focus-visible{outline-color:rgba(31,91,255,.35)}

/* charte : zéro halo décoratif (box-shadow coloré = réflexe UI générée) */
.tier.featured{box-shadow:none}

/* pied de carte : le libellé ne doit pas écraser le lien */
.meta{gap:12px}
.meta .go{white-space:nowrap}

/* Texte bleu en petit corps sur fond dense : on prend --accent-ink.
   Concerne les 11 cas releves a l'audit du 2026-08-10. */
.box.good .tag,
.map a .num,
#free .note a{color:var(--accent-ink)}
.b-local{background:#DDE6FF;color:var(--accent-ink)}

/* =========================================================================
   L'ECHELLE, posee le 2026-08-10 apres releve sur le site en ligne.

   Ce qu'on a mesure sur les 7 pages : 51 tailles de police distinctes,
   47 valeurs d'espacement, 14 rayons. Un systeme sain en a une poignee.
   La cause : chaque page a invente ses valeurs en rem a decimales
   (.86rem, .92rem, .94rem, .95rem...), et les em imbriques ont produit des
   monstres comme 12.512px et 0.015625px.

   Ces tokens sont la reference. Toute nouvelle regle s'y branche. Les pages
   anciennes y sont ramenees progressivement, sans tout casser d'un coup.
   ========================================================================= */
:root{
  /* Typo : rapport d'environ 1.2 entre les crans, arrondi au demi-pixel pres
     pour ne jamais retomber sur des decimales de rendu. */
  --t-xs:12px;     /* mentions legales, meta de carte */
  --t-sm:14px;     /* texte secondaire, libelles */
  --t-sm2:15.5px;  /* texte de carte : le cran ou tombe la moitie du site */
  --t-base:17px;   /* le corps de texte, la taille de reference */
  --t-md:19px;     /* chapeau, texte d'introduction */
  --t-lg:24px;     /* titre de carte */
  --t-xl:31px;     /* titre de section */
  --t-2xl:40px;    /* gros titre */
  --t-3xl:56px;    /* titre de page */
  /* les eyebrow en majuscules espacees, plus petits que --t-xs assume */
  --t-eyebrow:11.5px;

  /* Espacement : une seule suite, chaque cran vaut environ 1.5 fois le
     precedent. Tout ce qui n'est pas dedans est un accident. */
  --e-1:4px;
  --e-2:8px;
  --e-3:12px;
  --e-4:18px;
  --e-5:26px;
  --e-6:40px;
  --e-7:60px;
  --e-8:88px;

  /* Rayons : passes a l'angle vif le 2026-08-16 avec la charte v4.
     David sur la direction 5 : «trop rond les bouton», et sur la 4 :
     «bouton simple carre angle aigu». Les quatre crans restent declares
     pour ne rien casser (--r-lg est appele 177 fois), ils valent zero.
     Un seul endroit a changer si on veut revenir en arriere.
     Les rares cercles vrais (avatars, pastilles) sont ecrits en 50% en dur
     dans les pages : ils ne passent pas par ces jetons et restent ronds. */
  --r-sm:0;
  --r-md:0;
  --r-lg:0;
  --r-full:0;

  /* -----------------------------------------------------------------------
     Le motion, pose le 2026-08-12. Meme defaut que les couleurs, un cran
     plus discret : les trois courbes vivaient en double dans index,
     plug-codex et 404, et manquaient dans les quatre autres pages.

     Releve sur le site : 18 durees distinctes, et surtout la courbe la plus
     utilisee du site etait `ease` avec 214 usages, devant la courbe maison
     (175). Personne ne l'avait choisie : toute transition ecrite en
     raccourci sans courbe (`transition:.14s`) retombe silencieusement sur
     le defaut du navigateur. C'est une omission, pas une intention.

     Les durees se regroupent en quatre. 0.60 / 0.62 / 0.64 / 0.66 etaient
     quatre valeurs pour une seule chose : l'oeil ne les distingue pas.
     ----------------------------------------------------------------------- */
  --out:cubic-bezier(.22,1,.36,1);      /* entrees et reveals : part franc, se pose */
  --settle:cubic-bezier(.16,1.02,.3,1); /* ce qui se pose, avec un depassement leger */
  --snap:cubic-bezier(.4,0,.2,1);       /* aller-retour d'interface, symetrique */

  --d-fast:.14s;   /* couleur, bordure, survol : juste sous le seuil de perception */
  --d-ui:.22s;     /* un element d'interface qui bouge, s'ouvre ou se ferme */
  --d-med:.4s;     /* un mouvement qu'on regarde : zoom d'image au survol, carte
                      qui se souleve. Ce cran existe parce que le ramener a
                      --d-ui rend le zoom sec et le pousser a --d-in le rend
                      mou : cinq durees qui tiennent valent mieux que quatre
                      qui abiment deux effets. */
  --d-in:.62s;     /* arrivee a l'ecran, reveal au defilement */
  --d-slow:.9s;    /* le titre du hero, joue une fois */
}

/* =========================================================================
   LA TYPO, posee le 2026-08-16 avec la charte v4.

   AVANT : une seule declaration, -apple-system. Le site n'avait donc AUCUNE
   identite typographique en ligne. La charte v3 designait Michroma en
   display, mais elle n'a jamais ete chargee nulle part : le choix existait
   sur le papier et pas a l'ecran. C'est une des raisons pour lesquelles le
   site paraissait fade.

   LE CHOIX : une seule superfamille, Archivo, differenciee par l'axe de
   LARGEUR (wdth 62-125) et la graisse. C'est le geste suisse : un seul
   caractere, deux roles. Elle remplace Michroma (large et technique, mais
   incapable de faire du texte courant) ET Inter Tight.

   POURQUOI INTER SAUTE. Inter est la police par defaut de la quasi-totalite
   des sites generes par IA. Sur un site dont le SUJET est l'IA, c'est
   exactement le signal a ne pas envoyer. Archivo en largeur 100 fait le
   texte courant aussi bien, et le fichier en moins fait gagner 44 Ko.

   SERVIES DEPUIS LE DOMAINE, pas depuis Google : zero aller-retour reseau
   en plus, et l'IP des visiteurs ne part pas chez un tiers.
   font-display:swap pour que le texte s'affiche tout de suite en police
   systeme puis bascule, plutot que de laisser une page blanche.
   ========================================================================= */
@font-face{
  font-family:Archivo;
  src:url(/fonts/archivo.woff2) format("woff2");
  font-weight:400 800; font-stretch:62% 125%; font-display:swap;
}
@font-face{
  font-family:"JetBrains Mono";
  src:url(/fonts/jetbrains-mono.woff2) format("woff2");
  font-weight:400 500; font-display:swap;
}

/* La police se pose sur html, pas seulement sur body. Sans ca l'element
   racine reste en Times, le defaut du navigateur : invisible tant que tout
   le contenu vit dans body, mais c'est une base qui n'est pas posee. */
html{
  font-family:Archivo,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  font-variation-settings:"wdth" 100;
}
code,pre,kbd,samp,.mono{font-family:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace}

/* TITRES EN CAPITALES, demande de David le 2026-08-16, sur tout le site.
   La largeur monte a 112 : en capitales, un caractere elargi tient la ligne
   sans devenir un pave. Le crenage se resserre a mesure que le corps grossit,
   parce que des capitales en gros corps paraissent trop espacees sinon. */
h1,h2,h3,.kicker,.starthere-k,.eyebrow{
  font-family:Archivo,sans-serif;
  font-variation-settings:"wdth" 112;
  text-transform:uppercase;
}
h1{font-weight:800; letter-spacing:-.015em; line-height:1.02}
h2{font-weight:700; letter-spacing:.005em; line-height:1.08}
h3{font-weight:700; letter-spacing:.02em}
/* Les eyebrow etaient DEJA en capitales dans les pages : on ne double pas
   leur interlettrage, on l'harmonise. */
.kicker,.starthere-k,.eyebrow{font-weight:600; letter-spacing:.14em}

/* LE PIEGE DES CAPITALES ELARGIES, releve sur /plug-codex apres bascule.
   «They are not interchangeable.» tient sur une ligne en minuscules. En
   capitales a wdth 112 le meme titre demande 372px dans un conteneur de 342,
   et fait deborder toute la page de 6px. Les capitales sont plus larges que
   les bas-de-casse, et l'axe elargi ajoute encore 12%.

   Sur telephone la largeur revient donc a 100. Le caractere reste, la casse
   reste, seul l'axe se resserre la ou il n'y a pas la place.
   break-word est le filet de securite : il ne se declenche que sur un mot
   plus long que sa colonne, et garantit qu'aucun titre ne pourra plus rogner
   la page, quel que soit le texte ecrit plus tard. */
h1,h2,h3{overflow-wrap:break-word; text-wrap:balance}
@media(max-width:640px){
  h1,h2,h3{font-variation-settings:"wdth" 100}
}

/* Ancres et barre collante, pose le 2026-08-12.
   shell.js injecte la meme barre collante sur toutes les pages. Sans marge de
   defilement, un lien d'ancre amene la cible SOUS cette barre. Mesure sur le
   guide : la cible arrivait a 18px du haut alors que la barre en fait 63 (73
   sur telephone), donc le libelle du niveau et son filet passaient dessous et
   on croyait avoir mal cliqué.
   La regle vit ici et pas dans une page : la barre est globale, la
   compensation doit l'etre aussi. Elle porte sur tout ce qui a un id, pas sur
   :target seul, parce que la valeur doit etre connue AVANT que le navigateur
   calcule ou s'arreter. */
[id]{scroll-margin-top:88px}

/* Petit repere au trait devant un titre de section, pose le 2026-08-12.
   Discret mais pas fantome : c'est un dessin a l'encre, il doit se lire comme
   un pictogramme, pas comme une tache. multiply pour qu'il appartienne au
   papier au lieu de se poser dessus. Purement decoratif, donc aria-hidden et
   jamais dans le flux de lecture. */
/* .55 et pas .40 : a 40% le repere ne se lisait plus du tout sur le creme.
   Discret ne veut pas dire invisible. */
.vye-ic{display:block; margin-bottom:15px; mix-blend-mode:multiply; opacity:.55;
  pointer-events:none; user-select:none}
/* Taille par la HAUTEUR et pas par la largeur. Les douze motifs n'ont pas le
   meme rapport de forme : la pile de blocs fait 120x247, la loupe 220x222.
   En les calant sur une largeur commune, les blocs sortaient deux fois plus
   petits que les autres a l'oeil. La hauteur est l'ancre juste pour une
   rangee de pictogrammes. width:auto ecrase l'attribut width du HTML, qui ne
   sert donc plus que de valeur de repli. */
.vye-ic img{display:block; height:44px; width:auto}

/* =========================================================================
   LE BLOC DE PROMPT, repense le 2026-08-15.

   Il etait noir. Sur un site dont toute la direction est «papier creme
   editorial», un aplat noir de 400px de haut ecrase la page : c'est la
   premiere chose que l'oeil voit, avant le titre.

   Le parti pris : un prompt est de la PROSE qu'on lit et qu'on copie, pas du
   code qu'on execute. Il prend donc le costume d'une citation en pleine page,
   filet d'accent a gauche, texte a l'encre sur creme dense. Le terminal reste
   noir la ou c'en est vraiment un (les commandes de /plug-codex) : ce sont
   deux objets differents, ils n'ont pas a se ressembler.

   Contraste mesure sur --card : le corps passe a 12.9, tres au-dessus du
   seuil, la ou le gris sur noir plafonnait bien plus bas.
   ========================================================================= */
.promptbox,
.boite{
  position:relative; background:var(--card); border:1px solid var(--line);
  border-top:3px solid var(--accent); overflow:hidden;
  /* Bord gauche DROIT : un filet de 3px qui suit un arrondi se courbe aux
     coins et donne un aspect mou. Un filet doit etre un filet. */
  border-radius:0 var(--r-md) var(--r-md) 0;
}
/* Le bloc defile a l'interieur quand le prompt est long. Sans indice visuel il
   a juste l'air coupe : ce degrade dit qu'il y a une suite. */
.promptbox:after,
.boite:after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:44px;
  pointer-events:none;
  background:linear-gradient(to bottom, rgba(233,230,220,0), var(--card));
}
.promptbox pre,
.boite pre{
  color:var(--body); font-size:var(--t-sm);
  padding:26px 26px 28px; line-height:1.68;
}
/* Le bouton copier ne crie plus. Il etait en bleu plein, donc plus visible que
   le prompt lui-meme : il devient un contour discret qui se remplit au survol. */
.promptbox .copybtn,
.boite .copier{
  background:transparent; color:var(--accent-ink); border:1px solid var(--line);
  font-weight:700;
}
.promptbox .copybtn:hover,
.boite .copier:hover{ background:var(--accent); color:#fff; border-color:var(--accent) }
/* Le depliant du guide empilait un bandeau BLANC puis le bloc creme : deux
   conteneurs pour une seule chose, et un bouton bleu vif qui pesait plus que
   le prompt. Le bandeau prend la meme matiere que le bloc et le bouton se
   calme comme les autres. */
details.pw{ background:transparent; border-color:var(--line) }
details.pw summary{ background:var(--card) }
details.pw[open] summary{ border-bottom:1px solid var(--line) }
details.pw .promptbox{ border:0; border-top:3px solid var(--accent); border-radius:0 }
details.pw .promptbox:after{ display:none }
details.pw .copybtn{
  background:transparent; color:var(--accent-ink); border:1px solid var(--line); font-weight:700;
}
details.pw .copybtn:hover{ background:var(--accent); color:#fff; border-color:var(--accent) }

/* La zone de lecture respire : sans marge en haut, le texte passait sous le
   bouton copier. */
.boite pre{ padding-top:52px }
@media(min-width:620px){ .boite pre{ padding-top:26px; padding-right:104px } }

@media(max-width:640px){ .vye-ic{margin-bottom:10px} .vye-ic img{height:36px} }

/* #########################################################################
   CHARTE v4, 2026-08-16. Ce bloc arrive EN DERNIER, donc il gagne sur les
   regles v3 ci-dessus. Elles restent en place : elles documentent pourquoi
   chaque decision a ete prise, et servent de point de retour.
   ######################################################################### */

/* -------------------------------------------------------------------------
   1. LE BLOC DE PROMPT REPASSE SUR CHARBON.

   La v3 l'avait sorti du noir pour une bonne raison : un aplat noir de 400px
   ecrasait la page creme. Cette raison tombe avec la v4, parce que le fond
   n'est plus creme et parce que le charbon devient une MATIERE du systeme et
   non plus un accident. Et surtout l'orange, qui est desormais l'accent, ne
   peut vivre que la : 5.25 sur charbon contre 2.71 sur creme.

   Direction 1 de David pour l'ambiance, direction 4 pour la geometrie.
   ------------------------------------------------------------------------- */
/* L'ACCENT PASSE EN HAUT, valide par David le 2026-08-16.
   Il etait a gauche. Un filet colore epais sur le cote d'un bloc est le
   marqueur le plus reconnaissable d'une interface generee par IA, et sur un
   site dont le sujet EST l'IA c'est le signal a ne pas envoyer.
   Meme couleur, meme epaisseur, meme force visuelle : seule la position
   change. Un trait en haut se lit comme l'onglet d'un dossier ou l'entete
   d'un document technique, ce qui va au sujet. */
.promptbox,
.boite{
  background:var(--charbon); border:0;
  border-top:3px solid var(--orange);
  border-radius:0;
}
.promptbox pre,
.boite pre{ color:var(--sur-charbon); font-family:"JetBrains Mono",monospace }
/* Le degrade de fin de bloc suivait l'ancien creme en dur. Il suit le charbon. */
.promptbox:after,
.boite:after{ background:linear-gradient(to bottom, rgba(22,24,29,0), var(--charbon)) }

/* Le bouton copier redevient plein, mais en ORANGE a texte CHARBON.
   Le blanc sur orange tombe a 3.38, le charbon monte a 5.25. */
.promptbox .copybtn,
.boite .copier,
details.pw .copybtn{
  background:var(--orange); color:var(--charbon); border:0; font-weight:700;
  border-radius:0;
}
.promptbox .copybtn:hover,
.boite .copier:hover,
details.pw .copybtn:hover{ background:#F2854F; color:var(--charbon); border:0 }

details.pw summary{ background:var(--card) }
details.pw .promptbox{ border-top:3px solid var(--orange) }

/* -------------------------------------------------------------------------
   2. L'ENCADRE D'INFO prend le meme accent orange, version encree parce
   qu'il vit sur fond clair (#A93E12, 5.29). Direction 4.
   ------------------------------------------------------------------------- */
.note,.box.good,.firststep{
  background:var(--creme); border-top:3px solid var(--orange-ink);
  border-radius:0;
}

/* -------------------------------------------------------------------------
   3. BOUTONS ET PILLS : angle vif partout.
   Les pills passaient par 999px en dur dans la regle v3 ci-dessus, pas par
   --r-full : il faut donc les reprendre nommement.
   ------------------------------------------------------------------------- */
button.sub,.copybtn,.starthere-go,.missing-link,
.filters button,.lang button,input[type=email]{ border-radius:0 }
.filters button.on,.lang button.on{ background:var(--charbon); border-color:var(--charbon) }
.card,.starthere-card,.how,.firststep,.note,.promptbox{ border-radius:0 }

/* Le bouton principal du site devient orange sur charbon.
   Il n'existe qu'a l'interieur d'une zone sombre, jamais sur le sol clair.

   SELECTEUR RESTREINT AUX VRAIS BOUTONS, corrige apres releve en production.
   La premiere version disait `.dark .sub`, en croyant que .sub designait
   toujours le bouton d'inscription. Sur /ai-stack, .sub est un PARAGRAPHE de
   sous-titre : il a donc pris un aplat orange sous du texte pale, a 2.38 de
   contraste. Une classe courte ne suffit pas a designer un bouton, il faut
   nommer l'element. */
.hero.dark .starthere-go,.dark button.sub,.dark a.btn-go,.dark button.btn-go{
  background:var(--orange); color:var(--charbon); border:0; font-weight:700;
}

/* -------------------------------------------------------------------------
   3bis. LE BLEU DE TEXTE SUR LE NOUVEAU SOL.

   --accent #1F5BFF passait tout juste sur l'ancien creme (4.52). Le sol gris
   est legerement plus clair, et il tombe a 4.48 : sous le seuil de 4.5.
   Quatre points de detail, mais un seuil est un seuil.

   --accent-ink #1A4FE0 est la meme teinte un cran plus foncee : 5.53 sur le
   sol et 5.09 sur les surfaces. Il sert donc partout ou le bleu est du
   TEXTE. --accent reste pour les fonds de boutons et les gros aplats, ou le
   seuil n'est pas le meme.
   ------------------------------------------------------------------------- */
/* ⚠️ REGLE DE METHODE, apprise deux fois de suite ici.
   Une premiere version de ce bloc peignait `.cat`, `.tag` et `.hero.dark a`.
   Ces noms de classe ne disent RIEN du fond sur lequel ils se posent :
   `.cat` est un badge a fond bleu sur /prompt-bank (donc bleu sur bleu, 1.23)
   et `.hero.dark a` attrapait le bouton principal d'/ai-stack, lui aussi a
   fond bleu (1.59). Mesure sur le site : 60 elements casses d'un coup.
   On ne repeint QUE des elements dont on a verifie le fond, et on les nomme. */
.kicker,.hero:not(.dark) .kicker,
.go,.level-tag,
h2 a,h3 a,.map a,.faq a{ color:var(--accent-ink) }
.hero.dark .kicker,.starthere-k{ color:var(--inox) }
.dark .go{ color:#5B87FF }

/* Un element qui porte SON PROPRE fond porte AUSSI son texte : rien de ce qui
   precede ne doit lui passer dessus. */
.btn-primary,.b-feat,.pill.on,.filters button.on{ color:#fff }

/* Les derniers bleus a 4.48, soit deux centiemes sous le seuil : des liens de
   texte courant, le surtitre du 404 et l'oeil-de-boeuf des fiches.

   `a:not([class])` est volontaire et verifie : un lien SANS classe ne peut pas
   etre un bouton, donc il ne peut pas porter de fond. C'est le seul selecteur
   large que je m'autorise apres avoir casse 60 elements en devinant.
   Verifie avant ecriture sur les 8 pages en ligne : 45 elements touches, zero
   avec un fond propre. Le test avait d'ailleurs attrape les cartes du slider,
   ecrites sans classe sur du charbon : elles s'appellent .pcard depuis.
   `.cat:not(.b)` separe l'oeil-de-boeuf des fiches (fond clair) du badge de
   /prompt-bank (fond bleu), qui portent le meme nom de classe. */
a:not([class]),.k,.cat:not(.b){ color:var(--accent-ink) }
.dark a:not([class]),.dark .k,.dark .cat:not(.b){ color:#5B87FF }

/* -------------------------------------------------------------------------
   3ter. LES COMMANDES DES CARTES DE /prompt-bank.

   Elles vivent DANS le bloc de prompt, qui vient de passer au charbon : leur
   gris de fond clair (--soft) y tombe a 2.83 et le bleu encre a 1.9. Trente
   cartes, trois commandes chacune. C'est la contrepartie directe du passage
   du bloc sur charbon, il fallait la traiter en meme temps.
   ------------------------------------------------------------------------- */
.promptbox .copy,.promptbox .expand,.boite .copy,.boite .expand{ color:var(--inox) }
.promptbox .copy:hover,.promptbox .expand:hover,
.boite .copy:hover,.boite .expand:hover{ color:var(--sur-charbon) }
.promptbox .fiche,.boite .fiche{ color:#5B87FF }

/* -------------------------------------------------------------------------
   4. LES APLATS SOMBRES prennent le charbon de charte.
   --dark valait #0F1422, un bleu nuit cale sur les ecrans des mascottes.
   Le charbon v4 est un cran plus neutre pour que l'orange y brule.
   ------------------------------------------------------------------------- */
  /* on garde --dark comme alias pour ne rien casser dans les pages */
:root{ --dark:#16181D }

/* -------------------------------------------------------------------------
   4bis. LES SURFACES CLAIRES ECRITES EN DUR EN v3.
   Elles ne passaient pas par un jeton, donc revaloriser :root ne les a pas
   touchees : elles seraient restees creme au milieu du gris. Releve fait
   apres bascule, sur le site en fonctionnement.
   ------------------------------------------------------------------------- */
nav,.vye-nav{ background:rgba(236,237,238,.92)!important; border-bottom-color:var(--line)!important }
.card{ background:#EFEFED }
input[type=email]{ background:#EFEFED }
.card.feat,.box.good,.mode.feat{ border-color:#C9CBCE }
.drops{ background:var(--card); border-top-color:var(--line) }

/* -------------------------------------------------------------------------
   5. OUVERTURE DE PAGE, demandee par David le 2026-08-16.

   ATTENTION AU PIEGE, deja documente dans motion.js : un hero en fondu
   retarde la lecture de la promesse, c'est la premiere chose que voit
   quelqu'un qui arrive d'Instagram. Cette raison reste vraie.

   La sortie : le TITRE ne prend que du deplacement, jamais de fondu. Il est
   donc lisible des la premiere image. Seuls les elements qui l'entourent
   (surtitre, chapeau, boutons) prennent le fondu, en cascade courte.
   Rien ne depasse 0.42s de retard : au-dela ca se voit comme une attente.
   ------------------------------------------------------------------------- */
@keyframes vye-pose{ from{transform:translateY(10px)} to{transform:none} }
@keyframes vye-monte{ from{opacity:0; transform:translateY(14px)} to{opacity:1; transform:none} }

/* ⚠️ RETIRE LE 2026-08-16, LE JOUR MEME OU JE L'AI ECRIT. A NE PAS REMETTRE.

   J'avais pose ici une ouverture de page generique sur `.hero h1`,
   `.hero .kicker` et `.hero p`. C'etait une faute : l'accueil a DEJA sa
   propre ouverture, ecrite a la main et bien meilleure (volet masque qui fait
   remonter chaque ligne du titre depuis un `overflow:hidden`, cascade sur le
   chapeau et les preuves, classe `.ready` posee sur <html> au chargement).

   Deux systemes animaient donc les MEMES elements. Resultat observe sur le
   site en ligne : le titre et la mascotte ne se peignaient plus au
   chargement, et le surtitre restait a moitie transparent. Chaque
   «correction» que j'ajoutais deplacait le symptome au lieu de le regler.

   La lecon est celle que motion.js applique deja et que j'aurais du lire
   avant d'ecrire : `if (document.querySelector('[data-rise]')) return;` —
   une page qui a deja son motion, on n'y touche pas. Le CSS ne sait pas
   faire ce test, donc la regle est de ne pas poser d'animation d'ouverture
   globale du tout. Les pages sans motion propre sont couvertes par motion.js.

   Les deux @keyframes restent au-dessus : elles ne coutent rien et servent
   aux pages qui voudraient s'en servir NOMMEMENT, une par une. */

/* -------------------------------------------------------------------------
   5bis. LE RYTHME VERTICAL SUR TELEPHONE.

   Releve sur l'accueil a 390px, sur le site en ligne :
     - le hero fait 853px pour un ecran de 844, soit 101% : on ne voit RIEN
       d'autre que lui sans faire defiler ;
     - la mascotte a elle seule prend 23% du premier ecran ;
     - le premier bouton est a 1216px, soit 372px sous la ligne de flottaison.
   Sur un site dont le trafic vient d'Instagram avec trente secondes
   d'attention, la premiere action ne peut pas etre a un ecran et demi.

   Et les paddings de section ne venaient d'aucune echelle : 76/12, 34/6,
   58/58, alors que l'echelle du site est 4 8 12 18 26 40 60 88. On les y
   ramene, ce qui resserre ET rend le rythme lisible.
   ------------------------------------------------------------------------- */
@media(max-width:640px){
  .hero{ padding-top:var(--e-5); padding-bottom:var(--e-3) }
  .starthere{ padding-top:var(--e-6); padding-bottom:var(--e-4) }
  .drops{ padding-top:var(--e-6); padding-bottom:var(--e-6) }
  section.block{ padding-top:var(--e-6); padding-bottom:var(--e-6) }
  /* La mascotte passe au second plan : elle accompagne, elle n'annonce plus.
     Le retrait negatif la fait mordre sur le surtitre au lieu de lui prendre
     une ligne entiere. */
  .hero-art img{ width:96px }
  .hero-art{ margin-bottom:calc(-1 * var(--e-5)) }
}

/* -------------------------------------------------------------------------
   6. PARALLAX, demande par David, sous condition de ne pas ralentir.

   La condition est tenue PAR CONSTRUCTION et pas par reglage : ce parallax
   passe par animation-timeline, une fonctionnalite CSS qui fait tourner
   l'animation sur le compositeur du navigateur. Pas d'ecouteur de scroll,
   pas de JavaScript, donc rien qui puisse saccader ni ralentir le
   chargement. Cout reseau : zero octet.

   Le @supports n'est pas une precaution de style : sans lui, un navigateur
   qui ignore animation-timeline jouerait l'animation en boucle du debut a
   la fin, ce qui ferait flotter le panneau tout seul. Avec, il ne se passe
   simplement rien et le bloc reste fixe.

   26px de course, pas plus. Au-dela on voit le truc au lieu de voir la page.
   ------------------------------------------------------------------------- */
@supports (animation-timeline:view()){
  @keyframes vye-derive{ from{transform:translateY(24px)} to{transform:translateY(-24px)} }
  .hero.dark,.drops,.vye-para{
    animation:vye-derive linear both;
    animation-timeline:view();
    animation-range:cover;
  }
}

/* -------------------------------------------------------------------------
   7. LA PISTE QUI GLISSE, pour les pages de prompt.

   scroll-snap natif : ca glisse au doigt sur telephone et au trackpad sur
   ordinateur, sans une ligne de JavaScript. Donc rien a charger, rien qui
   rame, et ca continue de marcher si un script casse.

   La largeur de carte s'adapte a l'ecran par clamp, pas par media query :
   une carte occupe 78% de l'ecran sur telephone (donc on voit qu'il y en a
   une suivante, ce qui invite a tirer) et se fige a 318px sur grand ecran,
   ou trois et demie tiennent cote a cote. Mesure : 304px a 390 de large,
   318px et 3.5 cartes a 1280.
   ------------------------------------------------------------------------- */
.vye-piste{
  display:flex; gap:2px; overflow-x:auto; scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch; scrollbar-width:thin;
  padding-bottom:var(--e-4);
}
.vye-piste::-webkit-scrollbar{ height:3px }
.vye-piste::-webkit-scrollbar-thumb{ background:var(--line) }
.vye-piste > *{
  flex:0 0 clamp(238px,78vw,318px);
  scroll-snap-align:start;
}

/* Le bord droit s'estompe au lieu d'etre coupe net, pose le 2026-08-16.
   Une carte tranchee au ras du conteneur ressemble a un defaut de mise en
   page. Estompee, elle dit «ca continue» : c'est le seul indice qui invite a
   tirer, et il remplace une fleche ou une barre de defilement.

   mask-image et pas un degrade pose par-dessus : le masque suit le fond quel
   qu'il soit, alors qu'un degrade en surimpression doit connaitre la couleur
   du sol et casse des qu'on change de section.
   40px seulement, et rien a gauche : masquer les deux bords rognerait la
   premiere carte alors qu'on est justement en debut de piste. */
.vye-piste,.piste{
  -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 40px),transparent 100%);
  mask-image:linear-gradient(to right,#000 calc(100% - 40px),transparent 100%);
}

/* -------------------------------------------------------------------------
   8. LE GARDE-FOU. Non negociable, et il ferme le bloc pour qu'aucune regle
   d'animation ajoutee plus haut ne lui echappe.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001s!important; animation-delay:0s!important;
    transition-duration:.001s!important;
  }
  .hero.dark,.drops,.vye-para{ animation:none!important; transform:none!important }
}
