/* ══ Polices ═══════════════════════════════════════════════════════════════
   Charte d'octobre 2026 : deux familles, pas une de plus.

   Geist (400, 500, 700) porte tout le site : titres en 700 à approche
   serrée, texte en 400, micro-lignes en 500 capitales espacées.
   EB Garamond italique 400 ne sert qu'à la « chute » : trois ou quatre mots
   en fin de titre, jamais un paragraphe.

   Auto-hébergées en WOFF2 (Fontsource 5.3.0, licence OFL 1.1, voir
   /fonts/LICENSE-*.txt). Le sous-ensemble latin-ext ne se télécharge que si
   la page en contient un caractère. */
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/geist-latin-ext-400-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/geist-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/geist-latin-ext-500-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/geist-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/fonts/geist-latin-ext-700-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/fonts/geist-latin-700-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'EB Garamond'; font-style: italic; font-weight: 400; font-display: swap;
  src: url('/fonts/eb-garamond-latin-ext-400-italic.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'EB Garamond'; font-style: italic; font-weight: 400; font-display: swap;
  src: url('/fonts/eb-garamond-latin-400-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }


/* ══ Base, reprise du design ═══════════════════════════════════════════════
   Région générée par tools/import-canvas.mjs à partir du bloc <style> du
   canvas : elle se resynchronise à chaque import. Ne pas éditer à la main —
   ce bloc était recopié, et il est resté sur la palette sombre quand le canvas
   est passé au thème clair. */
/*canvas-base:start*/
@keyframes v3-breathe { 0%, 100% { opacity: 0.4; transform: scale(1); } 50% { opacity: 1; transform: scale(1.22); } }
@keyframes v3-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* landing */
html[data-page="landing"] { scroll-behavior: smooth; overflow-x: clip; }
html[data-page="landing"], html[data-page="landing"] body { margin: 0; padding: 0; background: #F0EAE0; -webkit-font-smoothing: antialiased; }
html[data-page="landing"] a { color: #0B0A09; text-decoration: none; }
html[data-page="landing"] a:hover { color: #0B0A09; }
html[data-page="landing"] ::selection { background: #0B0A09; color: #F0EAE0; }
html[data-page="landing"] img { max-width: 100%; }
html[data-page="landing"] :focus-visible { outline: 2px solid #0B0A09; outline-offset: 3px; }
html[data-page="landing"] [data-hscroll]::-webkit-scrollbar { display: none; }
/* affiliate */
html[data-page="affiliate"] { scroll-behavior: smooth; }
html[data-page="affiliate"], html[data-page="affiliate"] body { margin: 0; padding: 0; background: #0B0A09; -webkit-font-smoothing: antialiased; }
html[data-page="affiliate"] a { color: #F0EAE0; text-decoration: underline; text-decoration-color: rgba(240,234,224,0.35); text-underline-offset: 0.2em; }
html[data-page="affiliate"] a:hover { color: #F0EAE0; }
html[data-page="affiliate"] ::selection { background: #F0EAE0; color: #0B0A09; }
/* partners */
html[data-page="partners"] { scroll-behavior: smooth; }
html[data-page="partners"], html[data-page="partners"] body { margin: 0; padding: 0; background: #0B0A09; -webkit-font-smoothing: antialiased; }
html[data-page="partners"] a { color: #F0EAE0; text-decoration: underline; text-decoration-color: rgba(240,234,224,0.35); text-underline-offset: 0.2em; }
html[data-page="partners"] a:hover { color: #F0EAE0; }
html[data-page="partners"] ::selection { background: #F0EAE0; color: #0B0A09; }
/* cgu */
html[data-page="cgu"] { scroll-behavior: smooth; }
html[data-page="cgu"], html[data-page="cgu"] body { margin: 0; padding: 0; background: #0B0A09; -webkit-font-smoothing: antialiased; }
html[data-page="cgu"] a { color: #F0EAE0; text-decoration: underline; text-decoration-color: rgba(240,234,224,0.35); text-underline-offset: 0.2em; }
html[data-page="cgu"] a:hover { color: #F0EAE0; }
html[data-page="cgu"] ::selection { background: #F0EAE0; color: #0B0A09; }
html[data-page="cgu"] :focus-visible { outline: 2px solid #F0EAE0; outline-offset: 3px; }
/* mentions-legales */
html[data-page="mentions-legales"] { scroll-behavior: smooth; }
html[data-page="mentions-legales"], html[data-page="mentions-legales"] body { margin: 0; padding: 0; background: #0B0A09; -webkit-font-smoothing: antialiased; }
html[data-page="mentions-legales"] a { color: #F0EAE0; text-decoration: underline; text-decoration-color: rgba(240,234,224,0.35); text-underline-offset: 0.2em; }
html[data-page="mentions-legales"] a:hover { color: #F0EAE0; }
html[data-page="mentions-legales"] ::selection { background: #F0EAE0; color: #0B0A09; }
html[data-page="mentions-legales"] :focus-visible { outline: 2px solid #F0EAE0; outline-offset: 3px; }
/* letter */
html[data-page="letter"] { scroll-behavior: smooth; }
html[data-page="letter"], html[data-page="letter"] body { margin: 0; padding: 0; background: #0B0A09; -webkit-font-smoothing: antialiased; }
html[data-page="letter"] a { color: #F0EAE0; text-decoration: underline; text-decoration-color: rgba(240,234,224,0.35); text-underline-offset: 0.2em; }
html[data-page="letter"] a:hover { color: #F0EAE0; }
html[data-page="letter"] ::selection { background: #F0EAE0; color: #0B0A09; }
/*canvas-base:end*/

/* Charte d'octobre 2026 : sur les pages sombres, un lien dans le texte se
   reconnaît à son soulignement, plus à une couleur fluo. Les liens dessinés
   en boutons, cartes ou navigation portent leur propre style en ligne et ne
   sont pas soulignés. */
html:not([data-page="landing"]) a[style] { text-decoration: none; }
html { scrollbar-color: #6E665C transparent; }
html:not([data-page="landing"]) { scrollbar-color: #A79E92 #0B0A09; }
::selection { background: #0B0A09; color: #F0EAE0; }
html:not([data-page="landing"]) ::selection { background: #F0EAE0; color: #0B0A09; }

/* ══ Ajouts pour la page en production ═════════════════════════════════════
   Le canvas n'avait pas de visiteur réel : ni clavier, ni placeholder rendu
   par le navigateur, ni préférence de mouvement. Rien ici ne modifie
   l'apparence du design. */

input::placeholder { color: rgba(240, 234, 224, 0.5); }

/* Tous les contrôles de la page sont des boutons ou des liens stylés en
   inline : l'anneau de focus doit être déclaré une fois ici. */
/* Le canvas déclare un anneau vert foncé, lisible sur les sections claires
   mais presque invisible sur les sections sombres (#11100E, #17150F), qui
   alternent maintenant dans la page. Un anneau fluo doublé d'un halo sombre
   reste contrasté sur les deux : ≥5:1 dans les deux cas. Visible au clavier
   seulement — l'apparence de la page ne change pas. */
:focus-visible {
  outline: 2px solid #C6E84E;
  outline-offset: 3px;
  border-radius: 4px;
  box-shadow: 0 0 0 5px rgba(11, 10, 9, 0.75);
}

/* Cibles tactiles (WCAG 2.2 – 2.5.8, minimum 24x24 px).
   Les liens de navigation et de pied de page font 18 px de haut dans le
   design : on élargit la zone touchable sans toucher à la typographie ni aux
   espacements visibles. */
/* `pointer: coarse` seul ne suffit pas : une tablette en navigation bureau, ou
   un portable tactile, tombe entre les deux. On ajoute le critère de largeur. */
@media (pointer: coarse), (max-width: 940px) {
  [aria-pressed] { min-height: 32px; }
  #app header nav a,
  #app footer a {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
  }
}

/* ══ Barre de téléchargement ════════════════════════════════════════════════
   Élément ajouté au design, absent du canvas. Elle reste masquée tant que le
   script ne l'a pas montrée : un promo qui apparaît sans que rien ne le
   déclenche vaut moins qu'un promo absent, et surtout il ne doit jamais
   recouvrir le bouton du hero au chargement.

   `env(safe-area-inset-bottom)` la remonte au-dessus de la barre système des
   téléphones sans bouton d'accueil. */

[data-barre-app] {
  /* La barre est volontairement posée hors du conteneur racine, qui rogne les
     éléments en position fixe. Mais c'est ce conteneur qui porte la fonte du
     site : dehors, la barre héritait du <body> et se composait en Times. Elle
     déclare donc sa propre famille, comme tout élément qui vit à côté de
     l'arbre du design. */
  font-family: 'Geist', system-ui, -apple-system, sans-serif;
  font-weight: 400;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  justify-content: center;
  padding: 0 clamp(12px, 3vw, 24px) clamp(12px, 2vw, 22px);
  padding-bottom: calc(clamp(12px, 2vw, 22px) + env(safe-area-inset-bottom, 0px));
  pointer-events: none;              /* seule la capsule reçoit les clics */
  transform: translateY(130%);
  transition: transform 460ms cubic-bezier(.2, .8, .25, 1);
}
[data-barre-app][hidden] { display: none; }
[data-barre-app].est-visible { transform: none; }

/* Réservée au mobile/tablette : sur ordinateur, le geste "télécharger
   l'app" n'a pas de destination immédiate — on n'installe pas une appli
   mobile depuis son poste de travail. Même palier que le menu burger. */
@media (min-width: 941px) {
  [data-barre-app] { display: none !important; }
}

/* La capsule flotte : elle ne touche aucun bord, ce qui la détache du contenu
   sans le barrer. Le fond est translucide et flouté, pour qu'on devine la page
   derrière plutôt que de la masquer. */
[data-barre-capsule] {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: clamp(12px, 2vw, 24px);
  max-width: 680px;
  padding: 10px 10px 10px clamp(18px, 3vw, 26px);
  border-radius: 999px;
  background: rgba(11, 10, 9, 0.94);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(240, 234, 224, 0.16);
  box-shadow: 0 18px 44px -20px rgba(0, 0, 0, 0.75);
}

[data-barre-texte] { flex: 1; min-width: 0; line-height: 1.35; }
[data-barre-titre] {
  display: block;
  font-size: 15px;
  font-weight: 500;
  color: #F0EAE0;
}
/* La phrase peut passer à la ligne plutôt que d'être coupée par des points
   de suspension : elle est trop longue pour tenir sur une ligne dès que la
   fenêtre se resserre, et « Meet inspiring founders IRL dire… » ne dit rien.
   La capsule grandit d'une ligne, ce qui est le moindre mal. */
[data-barre-sous] {
  display: block;
  font-size: 13.5px;
  line-height: 1.4;
  color: rgba(240, 234, 224, 0.6);
  text-wrap: pretty;
}

/* Élevé sous html[data-page="landing"] : sans ce préfixe, la règle
   générale des liens de la page — moins spécifique en apparence mais plus
   "lourde" en sélecteur (html + attribut + a) — l'emportait sur ce bloc et
   repeignait le texte du bouton en vert lien sur le fond fluo : 3,7:1, sous
   le seuil AA de 4,5:1. Trouvé en mesurant le contraste réellement rendu,
   pas en relisant la feuille de style. */
html[data-page="landing"] [data-barre-cta] {
  flex: none;
  display: inline-flex;
  align-items: center;
  height: 44px;
  padding: 0 24px;
  border-radius: 999px;
  background: #C6E84E;
  color: #0B0A09;
  font-size: 14.5px;
  font-weight: 500;
  white-space: nowrap;
}
html[data-page="landing"] [data-barre-cta]:hover { background: #D5EE7B; color: #0B0A09; }

/* Discret, mais présent : une barre qu'on ne peut pas refermer finit par être
   contournée plutôt que lue. */
[data-barre-fermer] {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: none;
  background: none;
  color: rgba(240, 234, 224, 0.45);
  cursor: pointer;
}
[data-barre-fermer]:hover { color: #F0EAE0; }

/* Sous 430 px, la capsule prend toute la largeur disponible et la phrase
   passe à la trappe : elle se faisait couper en plein mot. Le titre et
   l'appel à l'action se suffisent. */
@media (max-width: 430px) {
  [data-barre-capsule] { width: 100%; padding-left: 18px; gap: 12px; }
  [data-barre-sous] { display: none; }
  [data-barre-titre] { font-size: 14px; }
  [data-barre-cta] { height: 42px; padding: 0 18px; font-size: 13.5px; }
}

@media (prefers-reduced-motion: reduce) {
  [data-barre-app] { transition: none; }
}

/* ══ Apparitions au défilement ═════════════════════════════════════════════
   L'état masqué n'est appliqué que si JavaScript a posé .reveal-ready : sans
   JS — et pour un robot — tout le contenu reste visible. Uniquement opacity
   et transform, donc aucun décalage de mise en page. */

.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 620ms cubic-bezier(.22,.61,.36,1), transform 620ms cubic-bezier(.22,.61,.36,1);
  will-change: opacity, transform;
}
.reveal-ready [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Apparition « Baseline » — la section monte depuis le bas en se dévoilant.

   Le bloc part 72 px plus bas, entièrement masqué, et se découvre par le haut
   pendant qu'il remonte : le contenu semble se lever plutôt que glisser. Le
   masque est un `clip-path`, donc rien ne déborde et aucune mise en page n'est
   recalculée — seuls la composition et le masque changent.

   Cette variante ne se déclenche qu'en descendant. Arriver dessus en remontant
   affiche le bloc sans animation : une animation qui se joue à l'envers du
   sens de lecture se remarque, et mal. */
.reveal-ready [data-reveal="baseline"] {
  opacity: 0;
  transform: translateY(72px);
  clip-path: inset(100% 0 0 0);
  transition:
    opacity 620ms cubic-bezier(.22, .7, .24, 1),
    transform 900ms cubic-bezier(.16, .84, .24, 1),
    clip-path 900ms cubic-bezier(.16, .84, .24, 1);
  will-change: transform, clip-path;
}
.reveal-ready [data-reveal="baseline"].is-revealed {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
  will-change: auto;
}
.reveal-ready [data-reveal="baseline"].sans-animation {
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal-ready [data-reveal] { opacity: 1; transform: none; transition: none; }
  .reveal-ready [data-reveal="baseline"] { clip-path: none; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Avant peinture, la page est déjà à la couleur de fond. */
#app:empty { min-height: 100vh; }

/* ══ Typographie du hero en mobile ═════════════════════════════════════════
   Le titre et le chapô ne descendent pas au même rythme : sous ~600 px, le
   titre a atteint son plancher (33 px) alors que le chapô est encore à 17 px —
   le rapport passe de 1:5 en desktop à 1:2 en mobile, et le chapô prend le
   dessus sur le titre. On lui donne son propre plancher, en continuité :
   17 px exactement à 600 px, puis décroissance jusqu'à 13,5 px sur les petits
   écrans, avec un interligne resserré (1,55 au lieu de 1,65) pour alléger le
   bloc. Style inline dans le gabarit du canvas, d'où le !important. */
@media (max-width: 600px) {
  #app #top p {
    font-size: clamp(13.5px, 3.6vw, 17px) !important;
    line-height: 1.55 !important;
  }
}

/* ══ Point de rupture de la navigation ═════════════════════════════════════
   Le canvas bascule barre desktop / menu burger via l'état JavaScript. Piloté
   en CSS, le même HTML est correct aux deux largeurs : rien à reconstruire au
   chargement sur mobile (l'élément LCP n'est pas remplacé) et la bascule
   fonctionne même sans JavaScript. */
@media (max-width: 940px) {
  #app [data-desk] { display: none !important; }
  #app [data-burger] { display: flex !important; }
}

/* ══ Filet sans JavaScript ═════════════════════════════════════════════════
   Le canvas gère désormais le mobile avec un vrai menu burger, piloté par
   JavaScript (matchMedia). Sans JS, l'état `narrow` reste faux : la barre
   desktop s'affiche donc, en une seule ligne flex nowrap qui dépasse un écran
   étroit. On l'autorise alors à passer à la ligne, pour que les liens et le
   bouton restent atteignables. Sans effet quand JS tourne (la barre desktop
   est masquée) ni en desktop. */
@media (max-width: 940px) {
  #app > div > header > nav { flex-wrap: wrap; row-gap: 12px; }
  #app > div > header > nav > div[style*="flex: 1"] { flex-basis: 100%; }
}

/* ══ Hero en mobile : lisibilité du texte sur la photo ═════════════════════
   La maquette assombrit la photo de gauche à droite, ce qui suffit en
   desktop où le texte occupe la moitié gauche. En portrait, le texte prend
   toute la largeur et le chapô passait sur la nappe blanche. Le voile devient
   vertical, plus dense en bas où se trouve le texte. */
@media (max-width: 600px) {
  #app #top > div[aria-hidden="true"] > div {
    background: linear-gradient(0deg, rgba(11,10,9,0.9) 0%, rgba(11,10,9,0.72) 45%, rgba(11,10,9,0.35) 75%, rgba(11,10,9,0.15) 100%) !important;
  }
}

/* Micro-ligne du hero (« Un social club réservé aux fondateurs ») plus discrète
   en mobile : c'est la seule capitale espacée du hero. */
@media (max-width: 600px) {
  #app #top [style*="text-transform: uppercase"] {
    font-size: 9.5px !important;
    letter-spacing: 0.16em !important;
  }
}

/* « Nos façons de nous retrouver » en mobile : toujours le titre, puis les
   photos. En desktop les blocs alternent gauche/droite ; empilés, cette
   alternance faisait passer une fois sur deux les photos avant le titre. */
@media (max-width: 800px) {
  #app #experiences div[style^="order:"] { order: 2 !important; }
  #app #experiences div[style^="order:"]:first-child { order: 0 !important; }
}
