/* ============================================================================
   SCÈNE — le socle.
   ============================================================================

   Un thème pour tout ce qui se vend en ligne sans passer par un panier :
   agences, studios, coachs, cabinets, logiciels, artisans qui soignent leur
   image. Le modèle assumé est celui des landing pages de 2026 — pas celui
   des gabarits de site vitrine de 2015.

   ## LA DÉCISION QUI TIENT TOUT LE RESTE : LE CANEVAS ET LA DALLE

   La page n'est pas une pile de bandes pleine largeur. C'est un CANEVAS —
   une couleur de fond unie — sur lequel sont posées des DALLES : des blocs
   très arrondis, en retrait de quelques pixels des bords, qui portent le
   contenu.

       ┌──────────────────────────────┐  ← le canevas
       │  ╭────────────────────────╮  │
       │  │       une dalle        │  │
       │  ╰────────────────────────╯  │
       │  ╭────────────────────────╮  │
       │  │       une dalle        │  │
       │  ╰────────────────────────╯  │
       └──────────────────────────────┘

   Trois choses en découlent, et ce sont exactement celles qui manquaient :

   1. La séparation entre deux sections ne demande plus de filet gris. Le
      vide du canevas la fait. Un filet horizontal entre deux blancs est la
      signature du gabarit ; aucun des sites qu'on cherche à égaler n'en a.

   2. Un bloc de couleur pleine — le bandeau d'accueil, l'appel à l'action —
      cesse d'être une bande qui coupe la page en deux : c'est un objet posé,
      avec ses quatre coins. C'est ce que font Focus, Leedflow et la moitié
      du Theme Store de Shopify, et c'est ce qui distingue une page dessinée
      d'une page empilée.

   3. L'en-tête peut FLOTTER. Puisque le canevas dépasse partout de quelques
      pixels, une pilule collante posée à `top: var(--marge)` garde toujours
      son liseré de fond autour d'elle. Elle ne se colle jamais au bord de la
      fenêtre — le défaut le plus voyant d'une en-tête `sticky` naïve.

   ## LES QUATRE SURFACES, ET POURQUOI PAS QUATRE PALETTES

   Une section ne choisit pas trois couleurs. Elle choisit une SURFACE :

       .s-canevas   transparente — elle coule sur le fond de page
       .s-dalle     la dalle neutre
       .s-profond   la dalle contrastée
       .s-accent    la dalle en couleur

   Chaque surface pose elle-même son encre, son gris, son filet, son fond de
   carte et sa version locale de l'accent. Une section ne peut donc pas
   fabriquer un mariage de couleurs qui ne va pas : elle n'a pas la main
   dessus. C'est le remède au défaut le plus fréquent des thèmes générés —
   quatre palettes librement réglables, donc quatre occasions de se tromper.

   Deux points méritent d'être écrits noir sur blanc.

   SUR LA SURFACE ACCENT, L'ACCENT N'EST PLUS UTILISÉ. Le bouton y devient
   blanc, la pastille y devient un violet plus sombre. Poser du violet sur du
   violet ne fait pas un point d'attention, ça fait une tache.

   ET SUR CETTE MÊME SURFACE, TOUTES LES NUANCES VONT VERS LE NOIR. Ailleurs
   une carte s'éclaircit pour flotter ; sur une couleur saturée, l'éclaircir
   la rapproche du texte blanc qu'elle porte. C'est le seul endroit du thème
   où la règle s'inverse, et c'est la MESURE qui l'a imposé : à l'œil, sur la
   maquette, ça passait.

   ## CE QU'IL N'Y A PAS

   Aucun `<script>`. Les dépliants sont des `<details>`, l'apparition au
   défilement passe par `animation-timeline: view()`, les carrousels par
   `scroll-snap`, le ruban de logos par une animation CSS. Un thème sans
   script ne peut pas laisser un visiteur devant une page à moitié affichée.

   Aucune police distante. La pile système donne SF Pro sur Apple et Segoe
   UI Variable sur Windows : deux grotesques géométriques, exactement la
   famille que les sites de référence achètent. Une police téléchargée
   coûterait un aller-retour réseau avant le premier texte lisible.

   Aucun halo de couleur sous les boutons. Une ombre colorée qui s'allume au
   survol est le tic qui fait « fait par une machine » — les vrais sites
   assombrissent le fond de deux crans et laissent la flèche avancer.
   ========================================================================= */

/* ── Remise à zéro ──────────────────────────────────────────────────── */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* L'en-tête flottante recouvre ce vers quoi on saute. Sans cette réserve,
     cliquer « Tarifs » amène le titre SOUS la pilule : on atterrit au bon
     endroit et on croit s'être trompé. */
  scroll-padding-top: 7rem;
  /* Permet d'animer `height: auto` — c'est ce qui rend le dépliement des
     questions fluide sans une ligne de script. Ignoré ailleurs. */
  interpolate-size: allow-keywords;
}

body {
  margin: 0;
  background: var(--g-canevas);
  color: var(--g-encre);
  font-family: var(--f-texte);
  font-size: var(--t-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img,
svg,
video,
iframe { display: block; max-width: 100%; }

a { color: inherit; text-decoration-thickness: from-font; }
button,
input,
select,
textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--accent, var(--g-accent));
  outline-offset: 3px;
  border-radius: 4px;
}

::selection {
  background: var(--g-accent);
  color: var(--g-sur-accent);
}

.saut {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--g-encre);
  color: var(--g-canevas);
  border-radius: 0 0 0.75rem 0;
  text-decoration: none;
}
.saut:focus { left: 0; }

/* ── Le vocabulaire du socle ────────────────────────────────────────── */

:root {
  /* Piles système. `-apple-system` sort SF Pro, `Segoe UI Variable` sort la
     grotesque de Windows 11 : les deux sont des géométriques resserrées,
     c'est-à-dire la famille des sites qu'on prend pour modèle. */
  --f-grotesque: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display",
                 "Segoe UI", Inter, system-ui, "Helvetica Neue", Arial, sans-serif;
  --f-serif: "New York", ui-serif, Georgia, "Iowan Old Style",
             "Times New Roman", serif;
  --f-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* ── L'échelle ──
     Le titre de bandeau monte HAUT — 5,2 rem sur grand écran. C'est le
     contraire du choix précédent, et c'est délibéré : sur les sites de
     référence, la première chose qu'on voit est un mot énorme. Ce qui les
     empêche d'être criards n'est pas la taille, c'est le RESSERREMENT :
     interlignage à 0,95 et approche négative. Un grand titre lâche fait
     amateur ; un grand titre serré fait affiche. */
  --t-base: calc(1.0625rem * var(--k-texte, 1));
  --t-petit: calc(0.9375rem * var(--k-texte, 1));
  --t-menu: calc(0.875rem * var(--k-texte, 1));
  --t-oeil: calc(0.8125rem * var(--k-texte, 1));

  --t-affiche: calc(clamp(2.6rem, 6.4vw, 5.2rem) * var(--k-titre, 1));
  --t-1: calc(clamp(2rem, 4.2vw, 3.4rem) * var(--k-titre, 1));
  --t-2: calc(clamp(1.45rem, 2.3vw, 2rem) * var(--k-titre, 1));
  --t-3: calc(clamp(1.125rem, 1.5vw, 1.3rem) * var(--k-titre, 1));
  --t-4: calc(clamp(1rem, 1.2vw, 1.0625rem) * var(--k-titre, 1));

  /* ── Les rythmes ── */
  --y: calc(clamp(3.5rem, 6vw, 6.5rem) * var(--k-densite, 1));
  --y-bloc: calc(clamp(2rem, 3.4vw, 3.25rem) * var(--k-densite, 1));
  --gout: calc(clamp(0.85rem, 1.4vw, 1.35rem) * var(--k-densite, 1));

  /* ── La géométrie du canevas ──
     `--marge` est la gouttière visible entre une dalle et le bord de la
     fenêtre. Elle est petite exprès : ce qu'on veut, c'est un liseré, pas
     une marge de cahier. */
  --r-carte: clamp(0.75rem, 1vw, 1rem);
  --r-petit: 0.6rem;

  --courbe: cubic-bezier(0.22, 0.61, 0.36, 1);
  --courbe-douce: cubic-bezier(0.4, 0, 0.2, 1);

  /* ── Les ombres ──
     Neutres, jamais teintées. Une ombre colorée sous une carte est la
     signature du gabarit ; les sites qu'on vise posent une ombre grise très
     basse et très diffuse, celle d'un objet posé sur une table. */
  --ombre-1: 0 1px 2px rgb(10 10 15 / 0.04),
             0 3px 10px -4px rgb(10 10 15 / 0.07);
  --ombre-2: 0 2px 4px rgb(10 10 15 / 0.04),
             0 16px 36px -14px rgb(10 10 15 / 0.16);
  --ombre-3: 0 8px 16px -8px rgb(10 10 15 / 0.10),
             0 40px 80px -28px rgb(10 10 15 / 0.30);

  /* Un grain très fin, en SVG intégré. C'est ce qui empêche une grande
     surface de couleur pleine de paraître plate — le détail qu'on ne voit
     pas et qu'on remarque quand il manque. Aucune requête réseau. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* ============================================================================
   LES SURFACES
   ========================================================================= */

.s-canevas,
.s-dalle,
.s-profond,
.s-accent {
  background: var(--fond);
  color: var(--encre);
  position: relative;
  isolation: isolate;
}

.s-canevas { --fond: var(--g-canevas); --encre: var(--g-encre); }
.s-dalle   { --fond: var(--g-dalle);   --encre: var(--g-encre); }
.s-profond { --fond: var(--g-profond); --encre: var(--g-profond-encre); }
.s-accent  { --fond: var(--g-accent);  --encre: var(--g-sur-accent); }

/* Les dérivées, communes aux quatre. Elles se calculent depuis le couple
   fond/encre de la surface, donc elles sont justes par construction — y
   compris dans une édition sombre, où « 8 % de noir » aurait donné un gris
   plus clair que le fond. */
.s-canevas,
.s-dalle,
.s-profond,
.s-accent {
  --doux: color-mix(in oklab, var(--encre) 62%, var(--fond));
  --doux-fort: color-mix(in oklab, var(--encre) 80%, var(--fond));
  --filet: color-mix(in oklab, var(--encre) 12%, transparent);
  --filet-fort: color-mix(in oklab, var(--encre) 26%, transparent);
  --sur: color-mix(in oklab, var(--encre) 6%, var(--fond));
  --sur-forte: color-mix(in oklab, var(--encre) 11%, var(--fond));
  --carte-fond: color-mix(in oklab, var(--encre) 4%, var(--fond));
  --carte-filet: color-mix(in oklab, var(--encre) 10%, transparent);
  /* Le fond des pastilles — l'œil de section, les étiquettes légères. Il est
     une variable de surface et non une formule écrite sur place, parce que
     sur une surface de COULEUR SATURÉE il faut l'inverser : voir plus bas. */
  --pastille-fond: color-mix(in oklab, var(--accent) 13%, transparent);
  --pastille-filet: color-mix(in oklab, var(--accent) 22%, transparent);
  --accent: var(--g-accent);
  --sur-accent: var(--g-sur-accent);

  /* ── L'ACCENT LISIBLE, et pourquoi il existe ──
     Un accent est choisi pour REMPLIR : un vert vif, un violet électrique,
     un orange. Écrit en petit sur un fond clair, le même vert vif tombe à
     un rapport de contraste de 1,9 — c'est-à-dire illisible, et pas
     seulement pour qui voit mal.

     Plutôt que d'ajouter un second réglage « accent pour le texte » que
     personne ne remplirait, on le calcule : l'accent tiré vers l'encre de
     la surface. Sur fond clair il fonce, sur fond sombre il éclaircit. Le
     client garde donc UNE couleur, et le texte reste lisible partout.

     Règle d'usage : `--accent` pour ce qu'on REMPLIT (fonds, puces, filets
     épais), `--accent-lisible` pour ce qu'on ÉCRIT. */
  /* 62 % et non 72 % : à 72 %, l'accent écrit en 13 px plafonnait à 3,7 ou
     4,1 sur les quatre éditions — sous le seuil AA de 4,5, mesuré sur la
     page rendue. Huit points de plus vers l'encre suffisent à passer, et la
     couleur reste parfaitement reconnaissable. */
  --accent-lisible: color-mix(in oklab, var(--accent) 62%, var(--encre));
}

/* ── Le fond d'une carte posée sur le CANEVAS ──
   Il vaut la couleur de la dalle neutre, et non « un peu d'encre par-dessus
   le canevas ». La nuance n'est pas cosmétique : dans une édition claire,
   mélanger de l'encre au canevas ASSOMBRIT la carte, qui se creuse au lieu
   de flotter — trois formules de tarif grises sur un fond gris. En prenant
   la dalle, la carte devient blanche sur un canevas teinté dans les
   éditions claires, et gris ardoise sur du noir dans les éditions sombres.
   La même ligne, le bon résultat dans les deux sens. */
.s-canevas { --carte-fond: var(--g-dalle); }

/* Sur la dalle neutre, une carte ne peut plus s'éclaircir — la dalle est
   déjà le point clair de la page. C'est l'ombre et le filet qui la
   décollent. */
.s-dalle { --carte-fond: var(--fond); }

/* La dalle contrastée n'est PAS forcément sombre : dans les éditions de
   nuit — Ring, Studio — c'est le seul panneau clair de la page. On ne
   touche donc pas à l'accent ici : `--accent-lisible`, calculé depuis
   l'encre de la surface, s'en charge tout seul et dans les deux sens. */
.s-profond { --carte-fond: color-mix(in oklab, var(--encre) 6%, var(--fond)); }

/* LA RÈGLE : sur la surface accent, l'accent disparaît. Il est remplacé par
   l'encre de la surface — blanche le plus souvent. Un bouton violet sur une
   dalle violette ne signale rien. */
/* ── LA RÈGLE DE LA SURFACE SATURÉE ──
   Sur un violet, un vert ou un orange de milieu de gamme, on ne gagne du
   contraste QU'EN ALLANT VERS LE SOMBRE. Poser une pastille à « 13 % de
   blanc » sur du violet ÉCLAIRCIT le fond alors que le texte, lui, est déjà
   blanc : mesuré, le couple tombait à 3,3. Idem pour le gris de texte à
   78 %, et pour le fond de carte des vignettes flottantes.

   Toutes ces valeurs mélangent donc vers le NOIR ici, et vers l'encre
   ailleurs. C'est le seul endroit du thème où la règle s'inverse, et c'est
   la mesure qui l'a imposé — à l'œil, sur la maquette, ça passait. */
.s-accent {
  --accent: var(--encre);
  --sur-accent: var(--fond);
  --doux: color-mix(in oklab, var(--encre) 96%, var(--fond));
  --filet: color-mix(in oklab, var(--encre) 26%, transparent);
  --filet-fort: color-mix(in oklab, var(--encre) 46%, transparent);
  --sur: color-mix(in oklab, var(--fond) 88%, #000);
  --sur-forte: color-mix(in oklab, var(--fond) 78%, #000);
  --carte-fond: color-mix(in oklab, var(--fond) 80%, #000);
  --carte-filet: color-mix(in oklab, var(--encre) 20%, transparent);
  --pastille-fond: var(--g-profond);
  --pastille-filet: transparent;
  --pastille-encre: var(--g-profond-encre);
}

/* Le grain, et le halo de lumière du haut. Les deux ne s'appliquent qu'aux
   surfaces pleines : sur la dalle neutre ils ne se verraient pas et
   coûteraient une couche de composition pour rien. */
.s-profond::before,
.s-accent::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--grain);
  opacity: 0.055;
  mix-blend-mode: overlay;
}
.s-profond::after,
.s-accent::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(120% 70% at 50% -20%,
      color-mix(in oklab, var(--encre) 16%, transparent) 0%,
      transparent 62%);
}
.s-profond > *,
.s-accent > * { position: relative; z-index: 1; }

/* ── La dalle ───────────────────────────────────────────────────────── */

.dalle {
  margin-inline: var(--marge);
  border-radius: var(--r-dalle);
  overflow: hidden;
}
/* Deux dalles qui se suivent se touchent presque : le canevas doit rester
   visible entre elles, sinon on retrouve la bande pleine largeur qu'on
   voulait quitter. */
.dalle + .dalle { margin-top: var(--marge); }

/* Une dalle qui prolonge la précédente — un appel à l'action collé à son
   pied de page, par exemple — ne rejoue pas ses coins du haut. */
.dalle--haut-droit { border-start-start-radius: 0; border-start-end-radius: 0; }
.dalle--bas-droit { border-end-start-radius: 0; border-end-end-radius: 0; }

.section { padding-block: var(--y); }
.section--serre { padding-block: calc(var(--y) * 0.58); }
.section--ras { padding-block: 0; }
.section--haute { padding-block: calc(var(--y) * 1.35); }

/* ── Les conteneurs ─────────────────────────────────────────────────── */

.enveloppe {
  width: min(100% - var(--gouttiere) * 2, var(--largeur));
  margin-inline: auto;
}
.enveloppe--large { width: min(100% - var(--gouttiere) * 2, calc(var(--largeur) + 200px)); }
.enveloppe--etroite { width: min(100% - var(--gouttiere) * 2, 68ch); }

:root { --gouttiere: clamp(1.15rem, 4vw, 3rem); }

/* ============================================================================
   TYPOGRAPHIE
   ========================================================================= */

.titre {
  font-family: var(--f-titre);
  font-weight: var(--titre-graisse, 760);
  letter-spacing: -0.032em;
  line-height: 1.08;
  text-transform: var(--titre-casse, none);
  text-wrap: balance;
  margin: 0;
}
.affiche {
  font-size: var(--t-affiche);
  line-height: 0.98;
  letter-spacing: -0.042em;
}
.titre-1 { font-size: var(--t-1); line-height: 1.04; letter-spacing: -0.036em; }
.titre-2 { font-size: var(--t-2); line-height: 1.14; }
.titre-3 { font-size: var(--t-3); line-height: 1.25; letter-spacing: -0.022em; }
.titre-4 { font-size: var(--t-4); line-height: 1.35; letter-spacing: -0.015em; }

/* ── LE MOT ACCENTUÉ ──────────────────────────────────────────────────
   Une section écrit `<em>` dans son titre, ou le client tape des
   *astérisques* autour d'un mot. Trois habillages au choix, réglés une fois
   pour tout le site :

     crochets   quatre équerres autour du mot — le geste de Focus, et le
                plus élégant des trois : il montre sans repeindre.
     pastille   le mot dans un bloc de couleur.
     souligne   un trait épais sous le mot.
   ──────────────────────────────────────────────────────────────────── */

.titre em,
.accent-mot {
  font-style: normal;
  position: relative;
  display: inline-block;
  color: inherit;
}

[data-accentuation="crochets"] .titre em,
[data-accentuation="crochets"] .accent-mot {
  padding: 0.02em 0.3em;
  margin-inline: 0.06em;
}
[data-accentuation="crochets"] .titre em::before,
[data-accentuation="crochets"] .titre em::after,
[data-accentuation="crochets"] .accent-mot::before,
[data-accentuation="crochets"] .accent-mot::after {
  content: "";
  position: absolute;
  inset-block: 0;
  width: 0.42em;
  border: 0.055em solid var(--accent-lisible);
  pointer-events: none;
}
[data-accentuation="crochets"] .titre em::before,
[data-accentuation="crochets"] .accent-mot::before {
  left: 0;
  border-right: 0;
}
[data-accentuation="crochets"] .titre em::after,
[data-accentuation="crochets"] .accent-mot::after {
  right: 0;
  border-left: 0;
}

[data-accentuation="pastille"] .titre em,
[data-accentuation="pastille"] .accent-mot {
  padding: 0.04em 0.32em 0.1em;
  margin-inline: -0.04em;
  border-radius: 0.28em;
  background: var(--accent);
  color: var(--sur-accent);
}

[data-accentuation="souligne"] .titre em,
[data-accentuation="souligne"] .accent-mot {
  color: var(--accent-lisible);
}
[data-accentuation="souligne"] .titre em::after,
[data-accentuation="souligne"] .accent-mot::after {
  content: "";
  position: absolute;
  left: 0.02em;
  right: 0.02em;
  bottom: -0.02em;
  height: 0.09em;
  border-radius: 999px;
  background: var(--accent);
  opacity: 0.42;
}

/* ── L'œil — la petite ligne au-dessus d'un titre ──────────────────── */

.oeil {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: var(--t-oeil);
  font-weight: 640;
  letter-spacing: 0.02em;
  color: var(--accent-lisible);
  width: fit-content;
}
.oeil--pastille {
  padding: 0.42rem 0.85rem 0.45rem;
  border-radius: 999px;
  background: var(--pastille-fond);
  border: 1px solid var(--pastille-filet);
  /* `--pastille-encre` n'est posée QUE par la surface accent, où la pastille
     emprunte le couple profond. Ailleurs, le texte garde l'accent lisible. */
  color: var(--pastille-encre, var(--accent-lisible));
}
.oeil--barre::before {
  content: "";
  width: 0.2rem;
  height: 0.9em;
  border-radius: 999px;
  background: var(--accent);
  flex: none;
}

.chapo {
  margin: 0;
  font-size: calc(var(--t-base) * 1.12);
  line-height: 1.55;
  color: var(--doux);
  max-width: 56ch;
  text-wrap: pretty;
}
.chapo--large { max-width: 72ch; }

.petit { font-size: var(--t-petit); }
.mini { font-size: var(--t-oeil); }
.doux { color: var(--doux); }
.gras { font-weight: 660; }
.centre { text-align: center; }
.centre .oeil,
.centre .chapo,
.centre .actions { margin-inline: auto; }
.centre .actions { justify-content: center; }

/* Le texte long — ce que le client tape dans un champ riche. */
.texte { max-width: 68ch; }
.texte > :first-child { margin-top: 0; }
.texte > :last-child { margin-bottom: 0; }
.texte p { margin: 0 0 1em; }
.texte h2 { font-family: var(--f-titre); font-size: var(--t-2); letter-spacing: -0.028em; margin: 1.8em 0 0.5em; }
.texte h3 { font-family: var(--f-titre); font-size: var(--t-3); letter-spacing: -0.02em; margin: 1.6em 0 0.4em; }
.texte a { color: var(--accent-lisible); text-underline-offset: 0.22em; }
.texte ul,
.texte ol { margin: 0 0 1em; padding-left: 1.2rem; }
.texte li { margin-bottom: 0.4em; }
.texte blockquote {
  margin: 1.5em 0;
  padding-left: 1.15rem;
  border-left: 3px solid var(--accent);
  font-size: calc(var(--t-base) * 1.08);
  color: var(--doux-fort);
}
.texte strong { font-weight: 660; }
.texte hr { border: 0; border-top: 1px solid var(--filet); margin: 2em 0; }

/* ── La tête d'une section ──────────────────────────────────────────── */

.tete {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin-bottom: var(--y-bloc);
  max-width: 60ch;
}
.tete--centree { align-items: center; text-align: center; margin-inline: auto; }
.tete--large { max-width: none; }

/* Le titre à gauche, le chapô et l'action à droite : la mise en page de
   tête la plus fréquente sur les sites de référence, parce qu'elle remplit
   la largeur au lieu de laisser une moitié vide. */
.tete--duo {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: var(--gout) calc(var(--gout) * 2);
  align-items: end;
  max-width: none;
}
.tete--duo > .tete-a { display: flex; flex-direction: column; gap: 0.9rem; }
.tete--duo > .tete-b { display: flex; flex-direction: column; gap: 1.1rem; }
@media (max-width: 860px) {
  .tete--duo { grid-template-columns: 1fr; align-items: start; }
}

/* ============================================================================
   LES BOUTONS — sans halo, sans clignotement
   ========================================================================= */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 0.85rem 1.45rem;
  border: 1px solid transparent;
  border-radius: var(--r-bouton);
  background: var(--encre);
  color: var(--fond);
  font-size: var(--t-petit);
  font-weight: 620;
  letter-spacing: -0.006em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  /* Une seule propriété animée, et c'est la couleur. Pas d'ombre qui
     s'allume, pas de translation, pas de filtre : c'est ce qui produisait
     le « flash » sous les boutons, et aucun site sérieux ne le fait. */
  transition: background-color 0.18s var(--courbe-douce),
              border-color 0.18s var(--courbe-douce),
              color 0.18s var(--courbe-douce);
}
.bouton:hover {
  background: color-mix(in oklab, var(--encre) 82%, var(--accent));
}
.bouton:active { background: color-mix(in oklab, var(--encre) 92%, var(--fond)); }

/* Sur la surface accent, `--accent` VAUT `--encre` : le mélange de survol
   ci-dessus ne changerait donc rien du tout, et le bouton principal du
   bandeau — celui sur lequel tout le monde clique — n'aurait aucun retour
   visuel. On teinte alors vers le fond de la dalle. */
.s-accent .bouton:hover { background: color-mix(in oklab, var(--encre) 86%, var(--fond)); }

.bouton--accent {
  background: var(--accent);
  color: var(--sur-accent);
}
.bouton--accent:hover { background: color-mix(in oklab, var(--accent) 86%, var(--encre)); }

.bouton--clair {
  background: var(--fond);
  color: var(--encre);
}
.bouton--clair:hover { background: color-mix(in oklab, var(--fond) 88%, var(--encre)); }

.bouton--nu {
  background: transparent;
  color: var(--encre);
  border-color: var(--filet-fort);
}
.bouton--nu:hover {
  background: var(--sur);
  border-color: var(--encre);
}

.bouton--large { padding: 1.05rem 1.9rem; font-size: var(--t-base); }
.bouton--pleine { width: 100%; }

/* Le lien d'action : pas un bouton, une flèche qui avance. */
.bouton--lien {
  padding: 0.2rem 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--accent-lisible);
  font-weight: 620;
}
.bouton--lien:hover { background: none; color: var(--accent-lisible); }
.bouton--lien::after {
  content: "→";
  transition: transform 0.22s var(--courbe);
}
.bouton--lien:hover::after { transform: translateX(4px); }

/* La flèche en rond — la signature de Leedflow. Elle vit DANS le bouton, ce
   qui lui donne un poids que la flèche typographique n'a pas. */
.rond {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.55em;
  height: 1.55em;
  margin-right: -0.55em;
  border-radius: 999px;
  background: color-mix(in oklab, currentColor 16%, transparent);
  flex: none;
  transition: transform 0.22s var(--courbe);
}
.rond svg { width: 0.72em; height: 0.72em; }
.bouton:hover .rond { transform: translateX(3px); }

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem;
}

/* ============================================================================
   PILES, RANGS, GRILLES
   ========================================================================= */

.pile { display: flex; flex-direction: column; gap: 1rem; align-items: flex-start; }
.pile--s { gap: 0.55rem; }
.pile--m { gap: 1.3rem; }
.pile--l { gap: 1.9rem; }
.pile--centre { align-items: center; text-align: center; }

.rang { display: flex; flex-wrap: wrap; align-items: center; gap: 0.9rem; }
.rang--espace { justify-content: space-between; }
.rang--centre { justify-content: center; }

.grille {
  display: grid;
  gap: var(--gout);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min, 260px)), 1fr));
}
.grille--2 { --min: 360px; }
.grille--3 { --min: 280px; }
.grille--4 { --min: 210px; }
.grille--5 { --min: 170px; }
.grille--serree { gap: calc(var(--gout) * 0.6); }

/* Grilles fixes — pour ce qui ne doit PAS se recomposer tout seul, comme
   un bento dont le dessin est le sujet. */
.grille--fixe-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grille--fixe-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 860px) {
  .grille--fixe-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .grille--fixe-2,
  .grille--fixe-3 { grid-template-columns: 1fr; }
}

.duo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(var(--gout) * 1.7);
  align-items: center;
}
.duo--texte { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
.duo--image { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
.duo--haut { align-items: start; }
.duo--inverse > :first-child { order: 2; }
@media (max-width: 900px) {
  .duo,
  .duo--texte,
  .duo--image { grid-template-columns: 1fr; gap: calc(var(--gout) * 1.3); }
  .duo--inverse > :first-child { order: 0; }
}

.pleine { grid-column: 1 / -1; }

/* ============================================================================
   LES CARTES
   ========================================================================= */

.carte {
  position: relative;
  background: var(--carte-fond);
  border: 1px solid var(--carte-filet);
  border-radius: var(--r-carte);
  padding: clamp(1.25rem, 2vw, 1.85rem);
  box-shadow: var(--ombre-1);
  transition: border-color 0.22s var(--courbe-douce),
              box-shadow 0.28s var(--courbe),
              transform 0.28s var(--courbe);
}
/* Une ombre grise sous une carte posée sur du bleu nuit ou du violet ne se
   voit pas — elle salit. Sur ces deux surfaces, c'est le fond légèrement
   éclairci et le filet qui décollent la carte. */
.s-profond .carte,
.s-accent .carte { box-shadow: none; }

a.carte,
.carte--cliquable { text-decoration: none; }
a.carte:hover,
.carte--cliquable:hover {
  border-color: var(--filet-fort);
  transform: translateY(-3px);
  box-shadow: var(--ombre-2);
}
.s-profond a.carte:hover,
.s-profond .carte--cliquable:hover,
.s-accent a.carte:hover,
.s-accent .carte--cliquable:hover {
  box-shadow: none;
  background: color-mix(in oklab, var(--encre) 10%, var(--fond));
}

/* La carte nue — pour une grille où le contenu se suffit. */
.carte--nue { background: none; border: 0; box-shadow: none; padding: 0; }
a.carte--nue:hover { transform: none; box-shadow: none; }

/* La carte remarquée — une formule de tarif, un bénéfice principal. */
.carte--relief {
  background: var(--g-profond);
  color: var(--g-profond-encre);
  border-color: transparent;
  box-shadow: var(--ombre-3);
  --doux: color-mix(in oklab, var(--g-profond-encre) 64%, var(--g-profond));
  --filet: color-mix(in oklab, var(--g-profond-encre) 16%, transparent);
  --filet-fort: color-mix(in oklab, var(--g-profond-encre) 30%, transparent);
  --encre: var(--g-profond-encre);
  --fond: var(--g-profond);
  /* La carte en relief renverse la surface : son accent lisible doit se
     recalculer depuis SON encre, sinon il reste réglé pour la page. */
  --accent-lisible: color-mix(in oklab, var(--g-accent) 72%, var(--g-profond-encre));
}

/* La carte de verre — sur une dalle profonde ou accent seulement. */
.carte--verre {
  background: color-mix(in oklab, var(--encre) 9%, transparent);
  border-color: color-mix(in oklab, var(--encre) 16%, transparent);
  backdrop-filter: blur(10px);
  box-shadow: none;
}

.carte--compacte { padding: clamp(1rem, 1.5vw, 1.35rem); }
.carte--serree { padding: 0; overflow: hidden; }
.carte--serree .carte-corps { padding: clamp(1.15rem, 1.8vw, 1.6rem); }

/* ── Étiquettes et pastilles ────────────────────────────────────────── */

.etiquette {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.34rem 0.7rem 0.36rem;
  border-radius: 999px;
  border: 1px solid var(--filet);
  background: var(--sur);
  font-size: var(--t-oeil);
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}
.etiquette--accent {
  background: var(--accent);
  color: var(--sur-accent);
  border-color: transparent;
}
.etiquette--vide { background: none; }

.numero {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.35rem;
  height: 2.35rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--sur-accent);
  font-family: var(--f-titre);
  font-size: var(--t-petit);
  font-weight: 700;
  flex: none;
}
.numero--nu {
  background: none;
  color: var(--accent-lisible);
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
}

/* ── Les listes à puces ─────────────────────────────────────────────── */

:root {
  --coche: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.4l3.6 3.6 7.4-8' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --barre-oblique: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E");
}

.puces { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.7rem; }
.puces li { display: flex; align-items: flex-start; gap: 0.7rem; }

/* La coche est un MASQUE, pas une image : sa couleur est celle du fond du
   pseudo-élément, donc elle suit l'accent de la surface toute seule. Sans
   ça il faudrait servir une icône par couleur et par édition. */
.puces li::before {
  content: "";
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.2em;
  flex: none;
  background-color: var(--accent-lisible);
  -webkit-mask: var(--coche) center / contain no-repeat;
  mask: var(--coche) center / contain no-repeat;
}

/* La variante en pastille : la coche se creuse dans un rond plein. */
.puces--rond li::before {
  width: 1.35rem;
  height: 1.35rem;
  margin-top: 0.1em;
  border-radius: 999px;
  background-color: color-mix(in oklab, var(--accent) 16%, transparent);
  background-image: none;
  -webkit-mask: none;
  mask: none;
  box-shadow: inset 0 0 0 999px color-mix(in oklab, var(--accent) 16%, transparent);
  position: relative;
}
.puces--rond li { position: relative; }
.puces--rond li::after {
  content: "";
  position: absolute;
  left: 0.32rem;
  top: 0.42em;
  width: 0.72rem;
  height: 0.72rem;
  background-color: var(--accent-lisible);
  -webkit-mask: var(--coche) center / contain no-repeat;
  mask: var(--coche) center / contain no-repeat;
}

.puces--serree { gap: 0.45rem; }
.puces--rang { display: flex; flex-wrap: wrap; gap: 0.55rem 1.5rem; }

/* La ligne barrée d'un comparatif : ce que les autres ne font pas. */
.puces li.non::before {
  background-color: var(--filet-fort);
  -webkit-mask: var(--barre-oblique) center / contain no-repeat;
  mask: var(--barre-oblique) center / contain no-repeat;
}
.puces li.non { color: var(--doux); }

/* ============================================================================
   MÉDIAS
   ========================================================================= */

.media {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-media, var(--r-carte));
  background: var(--sur-forte);
  /* Une image absente ne doit pas faire un trou : le fond de repli tient la
     place et garde la mise en page juste. */
}
.media > img,
.media > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--cadrage, center);
}
.media--carre { aspect-ratio: 1; }
.media--paysage { aspect-ratio: 16 / 10; }
.media--large { aspect-ratio: 2 / 1; }
.media--panorama { aspect-ratio: 21 / 9; }
.media--portrait { aspect-ratio: 3 / 4; }
.media--haut { aspect-ratio: 4 / 5; }
.media--libre { aspect-ratio: auto; }

.media--grande { --r-media: calc(var(--r-dalle) * 0.7); }

/* L'emplacement vide : un damier très pâle plutôt qu'un rectangle gris. Le
   damier dit « il manque une image ici » ; le gris uni ressemble à un bloc
   voulu, et on ne le remplit jamais. */
.media-vide {
  display: block;
  position: absolute;
  inset: 0;
  border: 1px dashed var(--filet-fort);
  border-radius: inherit;
  background-image:
    linear-gradient(45deg, var(--sur-forte) 25%, transparent 25%),
    linear-gradient(-45deg, var(--sur-forte) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--sur-forte) 75%),
    linear-gradient(-45deg, transparent 75%, var(--sur-forte) 75%);
  background-size: 18px 18px;
  background-position: 0 0, 0 9px, 9px -9px, -9px 0;
  opacity: 0.6;
}

[data-zoom="oui"] a.media > img,
[data-zoom="oui"] .media--zoom > img { transition: transform 0.7s var(--courbe); }
[data-zoom="oui"] a.media:hover > img,
[data-zoom="oui"] .media--zoom:hover > img { transform: scale(1.045); }

/* Le voile — du texte posé sur une image doit rester lisible quelle que
   soit la photo, y compris une photo claire. */
.voile::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    to top,
    color-mix(in oklab, #000 78%, transparent) 0%,
    color-mix(in oklab, #000 38%, transparent) 42%,
    color-mix(in oklab, #000 6%, transparent) 76%);
}
.voile--doux::after {
  background: linear-gradient(
    to top,
    color-mix(in oklab, #000 62%, transparent) 0%,
    transparent 62%);
}
.voile > .sur-image { position: relative; z-index: 2; }

/* ── Le texte posé sur une photo ──
   Il faut redéclarer TOUT le vocabulaire de surface, l'accent compris. Sans
   les trois dernières lignes, `--accent` n'était défini nulle part au-dessus
   d'une image : `color-mix(in oklab, var(--accent) 13%, transparent)` devenait
   une valeur invalide, et la pastille de contexte perdait purement et
   simplement son fond — dans quatre sections à la fois, sans que rien ne
   signale l'erreur puisqu'une déclaration CSS invalide est ignorée en
   silence.

   L'accent y vaut BLANC, et non la couleur de marque : une photo peut être
   de n'importe quelle teinte, et seul le blanc se lit à coup sûr par-dessus
   n'importe laquelle. */
.sur-image {
  color: #fff;
  --encre: #fff;
  --fond: #000;
  --doux: color-mix(in oklab, #fff 82%, transparent);
  --filet: color-mix(in oklab, #fff 22%, transparent);
  --filet-fort: color-mix(in oklab, #fff 46%, transparent);
  --sur: color-mix(in oklab, #fff 12%, transparent);
  --sur-forte: color-mix(in oklab, #fff 20%, transparent);
  --carte-fond: color-mix(in oklab, #fff 14%, transparent);
  --carte-filet: color-mix(in oklab, #fff 24%, transparent);
  --accent: #fff;
  --accent-lisible: #fff;
  --sur-accent: #101014;
}

/* Le cadre de fenêtre : la façon dont les sites de logiciel montrent une
   capture. Ce qui la fait lire comme un objet, c'est la barre de titre et
   l'ombre — pas l'image. */
.fenetre {
  border-radius: calc(var(--r-dalle) * 0.55);
  overflow: hidden;
  background: color-mix(in oklab, var(--encre) 9%, var(--fond));
  border: 1px solid var(--filet);
  box-shadow: var(--ombre-3);
}
.fenetre-barre {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--filet);
}
.fenetre-pastille {
  width: 0.62rem;
  height: 0.62rem;
  border-radius: 999px;
  background: var(--filet-fort);
}
.fenetre-corps { background: var(--fond); }

/* ============================================================================
   LE RUBAN — logos et bandeaux qui défilent, sans script
   ========================================================================= */

.ruban {
  display: flex;
  overflow: hidden;
  /* Les bords s'effacent : sans ce fondu, les logos apparaissent et
     disparaissent d'un coup au ras du cadre, ce qui se lit comme un bug. */
  -webkit-mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.ruban-piste {
  display: flex;
  align-items: center;
  gap: var(--ruban-gout, 3.5rem);
  padding-right: var(--ruban-gout, 3.5rem);
  flex: none;
  min-width: 100%;
  justify-content: space-around;
  animation: ruban var(--ruban-duree, 38s) linear infinite;
}
.ruban:hover .ruban-piste { animation-play-state: paused; }
.ruban--envers .ruban-piste { animation-direction: reverse; }

@keyframes ruban {
  from { transform: translateX(0); }
  to { transform: translateX(-100%); }
}

@media (prefers-reduced-motion: reduce) {
  .ruban-piste { animation: none; }
  .ruban {
    overflow-x: auto;
    -webkit-mask: none;
    mask: none;
  }
}

/* Le logo d'un client : monochrome, discret, il reprend sa couleur au
   survol. Poser sept logos en couleur sous un bandeau fait un patchwork. */
.logo-client {
  height: var(--logo-h, 30px);
  width: auto;
  max-width: 160px;
  object-fit: contain;
  opacity: 0.62;
  filter: grayscale(1);
  transition: opacity 0.25s, filter 0.25s;
}
.logo-client:hover { opacity: 1; filter: grayscale(0); }

.logo-mot {
  font-family: var(--f-titre);
  font-size: calc(var(--t-3) * 0.95);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--doux);
  white-space: nowrap;
  opacity: 0.72;
}

/* Le bandeau de texte défilant, en gros. */
.defile-mot {
  font-family: var(--f-titre);
  font-size: clamp(2rem, 6vw, 4.5rem);
  font-weight: var(--titre-graisse, 760);
  letter-spacing: -0.04em;
  line-height: 1;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 1.5rem;
}
.defile-mot--creux {
  color: transparent;
  -webkit-text-stroke: 1.5px var(--filet-fort);
}
.defile-point {
  width: 0.28em;
  height: 0.28em;
  border-radius: 999px;
  background: var(--accent);
  flex: none;
}

/* ============================================================================
   LE RAIL — carrousels à défilement, sans script
   ========================================================================= */

.rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--rail-l, min(84%, 26rem));
  gap: var(--gout);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gouttiere);
  padding-bottom: 0.6rem;
  scrollbar-width: thin;
  scrollbar-color: var(--filet-fort) transparent;
  /* Le rail déborde de l'enveloppe pour venir mourir au bord de l'écran :
     c'est ce qui dit « ça continue à droite » sans une flèche. */
  margin-inline: calc(var(--gouttiere) * -1);
  padding-inline: var(--gouttiere);
}
.rail > * { scroll-snap-align: start; }
.rail::-webkit-scrollbar { height: 6px; }
.rail::-webkit-scrollbar-thumb { background: var(--filet-fort); border-radius: 999px; }
.rail::-webkit-scrollbar-track { background: transparent; }

/* Au-delà d'une certaine largeur, un rail de trois éléments n'a plus de
   raison de défiler : il devient une grille. */
@media (min-width: 1000px) {
  .rail--grille-3 {
    grid-auto-flow: row;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    overflow: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
  .rail--grille-4 {
    grid-auto-flow: row;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    overflow: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
}

/* ============================================================================
   LES DÉPLIANTS
   ========================================================================= */

.depliant {
  border-bottom: 1px solid var(--filet);
}
.depliant:first-of-type { border-top: 1px solid var(--filet); }
.depliant-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.35rem 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--f-titre);
  font-size: var(--t-3);
  font-weight: 640;
  letter-spacing: -0.02em;
  transition: color 0.2s;
}
.depliant-tete::-webkit-details-marker { display: none; }
.depliant-tete:hover { color: var(--accent-lisible); }
.depliant-signe {
  position: relative;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 999px;
  border: 1px solid var(--filet-fort);
  flex: none;
  transition: transform 0.3s var(--courbe), background-color 0.25s, border-color 0.25s;
}
.depliant-signe::before,
.depliant-signe::after {
  content: "";
  position: absolute;
  inset: 50% 25%;
  border-top: 1.5px solid currentColor;
  transform: translateY(-50%);
}
.depliant-signe::after { transform: translateY(-50%) rotate(90deg); transition: opacity 0.25s; }
.depliant[open] .depliant-signe { transform: rotate(180deg); background: var(--accent); border-color: transparent; color: var(--sur-accent); }
.depliant[open] .depliant-signe::after { opacity: 0; }
.depliant-corps { padding: 0 0 1.5rem; max-width: 74ch; color: var(--doux); }

/* Le dépliement animé, là où le navigateur le sait faire. Ailleurs il
   s'ouvre d'un coup — ce qui est le comportement natif, donc jamais cassé. */
@supports selector(::details-content) {
  @media (prefers-reduced-motion: no-preference) {
    .depliant::details-content {
      block-size: 0;
      overflow: clip;
      transition: block-size 0.32s var(--courbe), content-visibility 0.32s allow-discrete;
    }
    .depliant[open]::details-content { block-size: auto; }
  }
}

/* ============================================================================
   FORMULAIRES
   ========================================================================= */

.champ { display: grid; gap: 0.4rem; }
.champ > span {
  font-size: var(--t-oeil);
  font-weight: 600;
  color: var(--doux-fort);
}
.champ input,
.champ select,
.champ textarea {
  width: 100%;
  padding: 0.8rem 0.95rem;
  border: 1px solid var(--filet-fort);
  border-radius: var(--r-petit);
  background: color-mix(in oklab, var(--encre) 5%, var(--fond));
  font-size: var(--t-base);
  transition: border-color 0.18s, box-shadow 0.18s, background-color 0.18s;
}
.champ textarea { resize: vertical; min-height: 8rem; line-height: 1.55; }
.champ select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5l5-5' fill='none' stroke='%23888' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  background-size: 0.7rem;
  padding-right: 2.4rem;
}
.champ input:focus,
.champ select:focus,
.champ textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}
.champ input::placeholder,
.champ textarea::placeholder { color: color-mix(in oklab, var(--encre) 40%, var(--fond)); }

/* ============================================================================
   L'APPARITION AU DÉFILEMENT
   ========================================================================= */

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    [data-apparition] .monte {
      animation: monte linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 26%;
    }
    [data-apparition="fondu"] .monte { animation-name: fondu; }
    [data-apparition="echelle"] .monte { animation-name: echelle; }

    /* Un décalage en cascade dans une grille. Il se règle par une variable
       posée en ligne — c'est le seul moyen sans script, et c'est peu de
       chose à écrire dans une boucle Liquid. */
    [data-apparition] .monte[style*="--rang"] {
      animation-range: entry calc(0% + var(--rang, 0) * 3%) cover calc(26% + var(--rang, 0) * 3%);
    }
  }
}

@keyframes monte {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: none; }
}
@keyframes fondu {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes echelle {
  from { opacity: 0; transform: scale(0.965); }
  to { opacity: 1; transform: none; }
}

/* ============================================================================
   UTILITAIRES
   ========================================================================= */

.hors-ecran {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.filet { border: 0; border-top: 1px solid var(--filet); margin: 0; }
.mt-s { margin-top: 0.6rem; }
.mt-m { margin-top: 1.4rem; }
.mt-l { margin-top: var(--y-bloc); }

/* Le chiffre d'une statistique. Il doit être ÉNORME et serré : c'est le
   seul endroit d'une page où un nombre porte à lui seul. */
.chiffre {
  font-family: var(--f-titre);
  font-size: clamp(2.5rem, 5vw, 4rem);
  font-weight: var(--titre-graisse, 760);
  letter-spacing: -0.05em;
  line-height: 0.92;
  display: block;
}
.chiffre-suffixe { font-size: 0.55em; letter-spacing: -0.02em; }

/* Les étoiles d'une note. Dessinées en dégradé pour rendre les demies. */
.etoiles {
  display: inline-block;
  width: 6.2em;
  height: 1.1em;
  vertical-align: -0.15em;
  background: linear-gradient(90deg,
    var(--accent-lisible) 0 calc(var(--note, 5) / 5 * 100%),
    color-mix(in oklab, var(--encre) 18%, transparent) calc(var(--note, 5) / 5 * 100%));
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 20'%3E%3Cpath d='M10 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L10 15l-5.3 2.8 1.1-6.1L1.4 7.4l6-.8z' fill='%23000'/%3E%3Cpath d='M30 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L30 15l-5.3 2.8 1.1-6.1-4.4-4.3 6-.8z' fill='%23000'/%3E%3Cpath d='M50 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L50 15l-5.3 2.8 1.1-6.1-4.4-4.3 6-.8z' fill='%23000'/%3E%3Cpath d='M70 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L70 15l-5.3 2.8 1.1-6.1-4.4-4.3 6-.8z' fill='%23000'/%3E%3Cpath d='M90 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L90 15l-5.3 2.8 1.1-6.1-4.4-4.3 6-.8z' fill='%23000'/%3E%3C/svg%3E") left center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 20'%3E%3Cpath d='M10 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L10 15l-5.3 2.8 1.1-6.1L1.4 7.4l6-.8z' fill='%23000'/%3E%3Cpath d='M30 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L30 15l-5.3 2.8 1.1-6.1-4.4-4.3 6-.8z' fill='%23000'/%3E%3Cpath d='M50 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L50 15l-5.3 2.8 1.1-6.1-4.4-4.3 6-.8z' fill='%23000'/%3E%3Cpath d='M70 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L70 15l-5.3 2.8 1.1-6.1-4.4-4.3 6-.8z' fill='%23000'/%3E%3Cpath d='M90 1l2.6 5.6 6 .8-4.4 4.3 1.1 6.1L90 15l-5.3 2.8 1.1-6.1-4.4-4.3 6-.8z' fill='%23000'/%3E%3C/svg%3E") left center / contain no-repeat;
}

/* Les icônes de section : un carré arrondi teinté, pas un émoji. */
.pictogramme {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: calc(var(--r-carte) * 0.7);
  background: color-mix(in oklab, var(--accent) 13%, transparent);
  color: var(--accent-lisible);
  flex: none;
}
.pictogramme svg { width: 1.35rem; height: 1.35rem; }
.pictogramme--plein { background: var(--accent); color: var(--sur-accent); }

/* ============================================================================
   LES ÉDITIONS
   ----------------------------------------------------------------------------
   Tout ce qui précède se règle par un nombre ou une couleur : les sept
   éditions changent déjà de teinte, d'arrondi de dalle, de liseré, de police
   et de densité sans qu'une seule ligne soit écrite ici.

   Ce qui suit est ce qu'un réglage ne sait PAS dire : un filet DOUBLÉ sous
   une tête de section, un cadre au trait autour de chaque image, une image
   en arche, une hachure à la place du grain, un tiret cadratin devant un œil.
   Ce sont des règles entières, elles vivent donc derrière `data-edition` —
   l'attribut que la coquille pose sur `<html>` à partir du réglage « Édition ».

   ── DEUX RÈGLES DE MÉTIER ──

   1. UNE SIGNATURE PAR ÉDITION, et elle doit se voir sur une vignette de
      trois cents pixels. Une édition qui empile cinq effets cesse d'être le
      thème ; une édition dont la marque ne survit pas à la miniature ne sert
      à rien, puisque c'est en miniature qu'on choisit.

   2. ELLES SONT ÉCRITES `html[data-edition="…"]`, et ce n'est pas une
      coquetterie. Les sections de Scène portent leur propre `<style>` dans le
      corps du document, donc APRÈS cette feuille : à spécificité égale, c'est
      la section qui gagne et l'interrupteur ne brancherait rien. L'élément
      `html` en tête donne le point de spécificité qui manque.

   ── ET UNE CONVENTION ──

   Une édition sans ombre écrit `0 0 rgb(0 0 0 / 0)` et non `none` : les
   ombres sont des variables reprises DANS des listes — l'en-tête flottante
   écrit `box-shadow: inset …, var(--ombre-2)` — et `none` au milieu d'une
   liste rend la déclaration entière invalide. Elle serait alors ignorée en
   silence, emportant au passage le filet clair de la tranche.
   ========================================================================= */

/* ── CHANTIER — l'équerre et le filet doublé ──────────────────────────
   L'édition a déjà ses dalles à zéro d'arrondi et son liseré à zéro : elles
   touchent les bords et se soudent l'une à l'autre. Ce qui restait rond,
   c'est tout ce que la dalle ne commande pas — les cartes, les pastilles,
   les champs, les pictogrammes. On les met à l'équerre, on éteint les
   ombres, et on double le filet sous les têtes de section : la page se lit
   comme un plan coté. */
html[data-edition="chantier"] {
  --r-carte: 0;
  --r-petit: 0;
  --ombre-1: 0 0 rgb(0 0 0 / 0);
  --ombre-2: 0 0 rgb(0 0 0 / 0);
  --ombre-3: 0 0 rgb(0 0 0 / 0);
}
html[data-edition="chantier"] .oeil--pastille,
html[data-edition="chantier"] .etiquette,
html[data-edition="chantier"] .numero,
html[data-edition="chantier"] .pictogramme,
html[data-edition="chantier"] .depliant-signe,
html[data-edition="chantier"] .entete-plie > summary { border-radius: 0; }

/* Le filet doublé : deux traits pleins séparés d'un pixel. Il est posé en
   pseudo-élément et non en `border-bottom` parce qu'un `border-style: double`
   à 5 px donne trois épaisseurs égales, ce qui n'est pas le geste. */
html[data-edition="chantier"] .tete::after {
  content: "";
  align-self: stretch;
  grid-column: 1 / -1;
  height: 5px;
  margin-top: 0.45rem;
  border-top: 2px solid var(--filet-fort);
  border-bottom: 2px solid var(--filet-fort);
}
html[data-edition="chantier"] .oeil,
html[data-edition="chantier"] .etiquette,
html[data-edition="chantier"] .pied-titre {
  text-transform: uppercase;
  letter-spacing: 0.09em;
}

/* ── ATELIER — le trait, et rien que le trait ─────────────────────────
   Un métier d'art montre des planches montées sur carton : chaque image est
   cernée d'un filet d'un cheveu, aucune n'est ombrée. L'œil de section perd
   sa pastille et redevient une mention gravée, ouverte d'un trait de laiton.

   C'est ce qui sépare ATELIER de TABLE, les deux éditions à empattements du
   thème : sans marque propre à chacune, on les confondrait sur une vignette,
   et c'est exactement ce qu'un sélecteur d'éditions ne doit pas permettre. */
html[data-edition="atelier"] {
  --ombre-1: 0 0 rgb(0 0 0 / 0);
  --ombre-2: 0 0 rgb(0 0 0 / 0);
  --ombre-3: 0 0 rgb(0 0 0 / 0);
}
html[data-edition="atelier"] .media {
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--encre) 24%, transparent);
}
html[data-edition="atelier"] .oeil {
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: calc(var(--t-oeil) * 0.9);
  font-weight: 600;
}
html[data-edition="atelier"] .oeil--pastille {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-lisible);
}
html[data-edition="atelier"] .oeil::before {
  content: "";
  width: 1.75rem;
  height: 1px;
  border-radius: 0;
  background: var(--accent);
  flex: none;
}

/* ── SALON — l'arche et l'ombre longue ────────────────────────────────
   Rien n'a d'arête. Les ombres cessent d'être des liserés courts et
   deviennent des nappes basses : les blocs se POSENT sur la page au lieu d'y
   être découpés — c'est la différence exacte avec CABINET, qui a le même
   principe d'arrondi et aucune ombre.

   Et les portraits prennent l'arche : le haut de l'image se referme en
   demi-cercle. C'est la forme des vitrines d'institut, elle survit à la
   miniature, et elle ne se règle par aucun nombre du panneau. */
html[data-edition="salon"] {
  --r-carte: clamp(1.25rem, 2vw, 1.75rem);
  --r-petit: 1rem;
  --ombre-1: 0 12px 26px -20px rgb(30 10 16 / 0.42);
  --ombre-2: 0 28px 58px -34px rgb(30 10 16 / 0.5);
  --ombre-3: 0 44px 92px -46px rgb(30 10 16 / 0.55);
}
/* Le rayon est BORNÉ à 12 rem et non posé à 999 px. Le navigateur réduit
   proportionnellement des rayons qui débordent : à 999 px, la vignette d'une
   grille devient un demi-cercle — c'est le geste voulu — mais la réalisation
   mise en avant sur deux colonnes devient un dôme de cinq cents pixels qui
   mange la moitié de la photo. Borné, le même trait donne un plein cintre
   sur une petite vignette et un arc segmentaire sur une grande. */
html[data-edition="salon"] .real > .media,
html[data-edition="salon"] .gal-item > .media,
html[data-edition="salon"] .equipe-membre > .media {
  border-radius: 12rem 12rem var(--r-carte) var(--r-carte);
}
html[data-edition="salon"] .pictogramme { border-radius: 999px; }

/* ── CABINET — rien ne brille ─────────────────────────────────────────
   Un métier réglementé n'a droit ni au superlatif ni à l'effet. Aucune ombre,
   aucun halo, aucun grain : une couleur pleine reste une couleur pleine. Rien
   ne bouge au survol. Ce qu'on donne à la place, c'est de l'air dans les
   cartes — la seule générosité qu'un document s'autorise. */
html[data-edition="cabinet"] {
  --ombre-1: 0 0 rgb(0 0 0 / 0);
  --ombre-2: 0 0 rgb(0 0 0 / 0);
  --ombre-3: 0 0 rgb(0 0 0 / 0);
}
html[data-edition="cabinet"] .s-profond::before,
html[data-edition="cabinet"] .s-accent::before,
html[data-edition="cabinet"] .s-profond::after,
html[data-edition="cabinet"] .s-accent::after { content: none; }
html[data-edition="cabinet"] a.carte:hover,
html[data-edition="cabinet"] .carte--cliquable:hover,
html[data-edition="cabinet"] .bouton:hover .rond,
html[data-edition="cabinet"] .bouton--lien:hover::after { transform: none; }
/* `--serree` vide sa propre boîte au profit de `.carte-corps`, `--nue` n'a
   pas de boîte du tout : les regonfler remettrait une marge blanche autour
   d'une image qui doit toucher son cadre. */
html[data-edition="cabinet"] .carte:not(.carte--serree):not(.carte--nue):not(.carte--compacte) {
  padding: clamp(1.7rem, 2.8vw, 2.5rem);
}

/* ── RING — la trame ──────────────────────────────────────────────────
   Le grain fin qui empêche une grande couleur de paraître plate devient une
   HACHURE : des filets obliques qui traversent les dalles pleines, comme un
   marquage de sol. Les étiquettes passent en aplat carré, les filets
   doublent d'épaisseur, et tout ce qui est court passe en capitales larges. */
html[data-edition="ring"] {
  --r-carte: 0;
  --r-petit: 0;
}
html[data-edition="ring"] .s-profond::before,
html[data-edition="ring"] .s-accent::before {
  background-image: repeating-linear-gradient(45deg,
    currentColor 0 2px, transparent 2px 10px);
  mix-blend-mode: normal;
  opacity: 0.1;
}
html[data-edition="ring"] .oeil,
html[data-edition="ring"] .etiquette,
html[data-edition="ring"] .bouton {
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
html[data-edition="ring"] .oeil--pastille,
html[data-edition="ring"] .etiquette {
  background: var(--accent);
  color: var(--sur-accent);
  border-color: transparent;
  border-radius: 0;
}
html[data-edition="ring"] .carte {
  border-width: 2px;
  border-color: var(--filet-fort);
}
html[data-edition="ring"] .depliant,
html[data-edition="ring"] .depliant:first-of-type { border-width: 2px; }

/* ── TABLE — la carte de menu ─────────────────────────────────────────
   Un filet fin sous chaque tête de section : la page se lit plat par plat.
   L'œil n'est plus une petite capitale espacée mais une mention manuscrite —
   italique, dans la police des titres, ouverte d'un tiret cadratin. Et les
   listes de prix se séparent d'un pointillé serré, comme une vraie carte. */
html[data-edition="table"] .tete {
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--filet-fort);
}
html[data-edition="table"] .oeil {
  font-family: var(--f-titre);
  font-style: italic;
  font-weight: 400;
  font-size: calc(var(--t-base) * 0.98);
  letter-spacing: 0;
  text-transform: none;
}
html[data-edition="table"] .oeil--pastille {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-lisible);
}
html[data-edition="table"] .oeil::before {
  content: "—";
  width: auto;
  height: auto;
  border-radius: 0;
  background: none;
}
html[data-edition="table"] .presta-ligne,
html[data-edition="table"] .presta-ligne:last-child,
html[data-edition="table"] .hor-ligne,
html[data-edition="table"] .hor-ligne:first-child,
html[data-edition="table"] .depliant,
html[data-edition="table"] .depliant:first-of-type { border-style: dotted; }

/* ── STUDIO — presque rien ────────────────────────────────────────────
   Le vocabulaire du book : la page se retire des bords, les grilles
   s'écartent, les cartes perdent leur tranche et leur ombre. L'œil n'a plus
   de pastille — il ne reste que le mot, étiré sur toute sa largeur. Ce qui
   tient la page, c'est le blanc ; tout le reste lui prendrait de la place. */
html[data-edition="studio"] {
  --gouttiere: clamp(1.5rem, 6vw, 5rem);
  --ombre-1: 0 0 rgb(0 0 0 / 0);
  --ombre-2: 0 0 rgb(0 0 0 / 0);
  --ombre-3: 0 0 rgb(0 0 0 / 0);
}
html[data-edition="studio"] .carte { border-color: transparent; }
html[data-edition="studio"] .grille,
html[data-edition="studio"] .reals,
html[data-edition="studio"] .gal--grille,
html[data-edition="studio"] .equipe-grille { gap: calc(var(--gout) * 1.7); }
html[data-edition="studio"] .tete { margin-bottom: calc(var(--y-bloc) * 1.5); }
html[data-edition="studio"] .oeil {
  text-transform: uppercase;
  letter-spacing: 0.3em;
  font-size: calc(var(--t-oeil) * 0.88);
  font-weight: 600;
}
html[data-edition="studio"] .oeil--pastille {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-lisible);
}
