/* ═════════════════════════════════════════════════════════════════════════
   Askline — la page d'accueil.

   Chargée APRÈS styles.css, qu'elle surcharge pour les sections refaites.
   styles.css reste seul maître de l'application (/app) et des modales, qui
   ne chargent pas ce fichier.

   Identité : fond clair, verre dépoli, bleu #1d9bf0, logo cercle ouvert et
   point détaché. Le shader vit dans le fond clair ; le backdrop-filter le
   ramène, saturé, à travers chaque panneau. Sans lui le verre n'a rien à
   filtrer et redevient une boîte blanche.
   ═════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────────────────
   Askline — banc d'essai, itération 2.
   Identité conservée : fond clair, verre dépoli, bleu #1d9bf0, logo cercle
   ouvert + point détaché. Le shader vit dans le fond CLAIR ; le
   backdrop-filter le ramène, saturé, à travers chaque panneau. Sans lui, le
   verre n'a rien à filtrer et redevient une boîte blanche.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  --bg: #f4f7fb;
  --paper: #ffffff;
  --ink: #0f1419;
  --muted: #536471;
  --faint: #8b98a5;
  --blue: #1d9bf0;
  --blue-deep: #1a8cd8;
  --blue-ink: #0c4a6e;
  /* Un seul accent sur toute la page. La hiérarchie se joue sur l'intensité,
     pas sur la teinte : sur blanc, un bleu profond lit comme plus appuyé
     qu'un bleu clair, et rien ne vient concurrencer la marque. */
  --blue-strong: #0f6fb5;

  --glass: rgba(255, 255, 255, 0.58);
  --glass-strong: rgba(255, 255, 255, 0.78);
  --line: rgba(15, 20, 25, 0.08);
  --hair: rgba(15, 20, 25, 0.06);

  --sans: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --r-md: 16px;
  --nav-h: 68px;
  --k: 1;                  /* échelle du contenu, ajustée à la hauteur par JS */

  /* En design clair, l'ombre est le marqueur de qualité : jamais du noir pur,
     toujours teintée de l'accent, toujours en plusieurs couches. */
  --lift-1: 0 1px 2px rgba(12, 74, 110, 0.05), 0 2px 6px rgba(12, 74, 110, 0.04);
  --lift-2: 0 2px 4px rgba(12, 74, 110, 0.05), 0 12px 28px rgba(12, 74, 110, 0.08),
            0 1px 0 rgba(255, 255, 255, 0.9) inset;
  --lift-3: 0 3px 8px rgba(12, 74, 110, 0.06), 0 20px 44px rgba(12, 74, 110, 0.10),
            0 56px 110px -30px rgba(12, 74, 110, 0.26), 0 1px 0 rgba(255, 255, 255, 0.95) inset;
}

* { box-sizing: border-box; }

html { overscroll-behavior: none; }   /* le rebond de fin de course déplaçait le champ fixe */
body {
  margin: 0;
  overscroll-behavior: none;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

/* Le champ, le voile et le grain vivent dans styles.css : ils appartiennent
   à la marque et l'application les partage. */

.shell { position: relative; z-index: 3; }

/* Le contenu se centre sur la hauteur restante, sous la barre de navigation.
   Les deux entretoises souples font le travail à la place de
   justify-content: center, qui coupe le haut de la page — et le rend
   inatteignable au défilement — dès que le contenu dépasse. Elles retombent à
   zéro quand il n'y a plus de place. */
/* Le contenu est centré sur la fenêtre ENTIÈRE, barre comprise.
   L'entretoise du haut ne descend jamais sous la hauteur de la barre : quand
   la place vient à manquer, le contenu se pose juste dessous plutôt que de
   glisser derrière. C'est le seul cas où le centrage cède, et il cède du bon
   côté. */
.page {
  min-height: 100vh;
  min-height: 100svh;      /* évite le saut lié à la barre d'URL mobile */
  display: flex;
  flex-direction: column;
}
.page > * { flex: none; }
/* Échelle unique pilotée par la hauteur disponible. `zoom` — et non
   `transform: scale` — parce qu'il agit sur la mise en page : le centrage,
   le clic et le défilement restent justes. Sans JavaScript, --k vaut 1 et les
   clamp() en vh font le travail à peu près. */
.hero, .proof { zoom: var(--k, 1); }
.page::before { content: ""; flex: 1 1 0; min-height: var(--nav-h); }
.page::after  { content: ""; flex: 1 1 0; min-height: 0; }
.wrap { width: min(1180px, 100% - 48px); margin-inline: auto; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── navigation ────────────────────────────────────────────────────────── */
.nav {
  /* Fixe et non plus dans le flux : tant qu'elle occupait de la hauteur, le
     contenu ne pouvait être centré que dans la zone restante, et son centre
     tombait une demi-barre trop bas. */
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  backdrop-filter: blur(22px) saturate(1.6);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  background: rgba(255, 255, 255, 0.55);
  border-bottom: 1px solid var(--hair);
}
.nav-in { display: flex; align-items: center; gap: 28px; height: var(--nav-h); }
.brand {
  display: flex; align-items: center; gap: 9px;
  font-weight: 600; letter-spacing: -0.025em; font-size: 18px;
  margin-inline-end: auto;
}
.brand svg { width: 28px; height: 28px; display: block; }
.nav a:not(.btn) { color: var(--muted); text-decoration: none; font-size: 14.5px; font-weight: 500; transition: color 0.2s var(--ease); }
.nav a:not(.btn):hover { color: var(--ink); }

/* ── hero, centré ──────────────────────────────────────────────────────── */
.hero {
  /* Le rythme vertical suit la hauteur de l'écran, pas la largeur : en
     1920×1080 la page doit tenir sans défilement, et un padding indexé sur vw
     grossissait justement là où la place manque. */
  padding: clamp(10px, 1.6vh, 22px) 0 clamp(8px, 1.2vh, 18px);
  text-align: center;
  display: flex; flex-direction: column; align-items: center;
  position: relative;
}
/* Le scrim garantit le contraste du texte sans éteindre le champ ailleurs. */
.hero::before {
  content: "";
  position: absolute;
  left: 50%; top: 2%;
  width: min(1000px, 108%); height: 86%;
  transform: translateX(-50%);
  z-index: -1;
  background: radial-gradient(58% 62% at 50% 42%, rgba(255,255,255,0.94) 0%,
              rgba(255,255,255,0.74) 46%, rgba(255,255,255,0) 78%);
  filter: blur(8px);
  pointer-events: none;
}

.eyebrow {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono);
  font-size: 11.5px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--blue-ink);
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(1.5);
  -webkit-backdrop-filter: blur(18px) saturate(1.5);
  border: 1px solid rgba(29, 155, 240, 0.20);
  border-radius: 999px; padding: 7px 15px 7px 12px;
  box-shadow: var(--lift-1);
}
.dot-live {
  width: 7px; height: 7px; border-radius: 50%; background: var(--blue);
  box-shadow: 0 0 0 3px rgba(29,155,240,0.18);
  animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(29,155,240,0.18); }
  50%      { box-shadow: 0 0 0 7px rgba(29,155,240,0); }
}

h1 {
  margin: clamp(14px, 2vh, 24px) 0 0;
  /* Bornée aussi par la hauteur : à 1920×1080 le titre tenait sur trois
     lignes et mangeait 228px à lui seul. */
  font-size: clamp(34px, min(5.2vw, 6.9vh), 64px);
  line-height: 1.02;
  letter-spacing: -0.045em;
  font-weight: 600;
  text-wrap: balance;
  max-width: 21ch;
}
h1 em {
  font-style: normal;
  background: linear-gradient(100deg, var(--blue) 8%, var(--blue-ink) 92%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* Le glyphe X : le réseau est nommé dans le slogan, en toutes lettres. */
/* Le X doit lire comme une capitale, pas comme une minuscule. La hauteur de
   capitale d'Inter Tight est d'environ 0.72em ; le glyphe est aligné sur la
   ligne de base plutôt que sur le milieu de l'x. */
.x-glyph {
  display: inline-block;
  width: 0.72em; height: 0.72em;
  margin-inline-start: 0.12em;
  vertical-align: baseline;
  position: relative;
  bottom: -0.015em;
  fill: var(--blue-ink);
}
.lede {
  margin: clamp(10px, 1.4vh, 16px) 0 0;
  font-size: clamp(15.5px, 1.35vw, 18px);
  line-height: 1.52;
  color: var(--muted);
  max-width: 56ch;
  text-wrap: pretty;
}
.lede b { color: var(--ink); font-weight: 600; }

/* ── l'entrée unique ───────────────────────────────────────────────────── */
.ask { margin-top: clamp(16px, 2.2vh, 26px); width: min(620px, 100%); }
.ask-field {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 8px 8px 20px;
  border-radius: 999px;
  background: var(--glass-strong);
  backdrop-filter: blur(24px) saturate(1.7);
  -webkit-backdrop-filter: blur(24px) saturate(1.7);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--lift-2);
  transition: box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
.ask-field:focus-within {
  border-color: rgba(29, 155, 240, 0.55);
  box-shadow: 0 0 0 4px rgba(29, 155, 240, 0.14), var(--lift-3);
}
.ask-field input {
  flex: 1; min-width: 0;
  font: inherit; font-size: 16px; color: var(--ink);
  background: none; border: 0; outline: 0; padding: 11px 0;
}
.ask-field input::placeholder { color: var(--faint); }

.ask-hint { margin: 10px 0 0; font-size: 13px; color: var(--faint); }
.ask-hint a:not(.btn) { color: var(--muted); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* ── preuve : de vrais posts X qui flottent ────────────────────────────── */
.proof { margin-top: clamp(18px, 2.6vh, 44px); }
.proof-label {
  text-align: center;
  font-family: var(--mono);
  font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--faint);
  margin: 0 0 clamp(10px, 1.4vh, 16px);
}
/* Deux rangées qui dérivent en sens inverse : la page respire même à l'arrêt,
   et on comprend qu'il y en a beaucoup d'autres derrière. */
.lanes {
  display: grid; gap: 12px; overflow: hidden;
  /* Marge du haut = débord de la pastille + amplitude du flottement + 2px.
     Pastille : top -12px. Flottement : -8px. Donc 22px, jamais moins — c'est
     la troisième fois que ce calcul se fait rogner en récupérant de la
     hauteur, et à chaque fois la couronne se retrouve coupée en mouvement.
     Le facteur d'échelle absorbe désormais ces pixels sans les reprendre ici.
     Valeur retenue par la mesure, pas par le calcul : à 22px la couronne était
     encore coupée de 4px au sommet du flottement. */
  padding: 30px 0 12px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
/* Pas de `gap` ici : l'écart est porté par la carte elle-même. Avec un gap,
   N cartes ont N-1 écarts, donc translateX(-50%) ne tombait PAS exactement sur
   une copie et la boucle sautait de quelques pixels à chaque tour.
   Pas de `will-change` non plus : il promeut la couche, et Safari échoue alors
   à composer le masque au-dessus — la rangée disparaît par intermittence. La
   transformation animée promeut déjà ce qu'il faut. */
.lane { display: flex; width: max-content; }
.lane-a { animation: drift-a 68s linear infinite; }
.lane-b { animation: drift-b 84s linear infinite; }
@keyframes drift-a { from { transform: translate3d(0,0,0); }     to { transform: translate3d(-50%,0,0); } }
@keyframes drift-b { from { transform: translate3d(-50%,0,0); }  to { transform: translate3d(0,0,0); } }
/* translateX reste physique : un pourcentage négatif pousse toujours vers la
   gauche. Or en lecture droite-à-gauche la rangée s'étend déjà vers la gauche,
   si bien que l'animation l'évacuait au lieu de la boucler — on voyait la fin
   passer puis le vide. Le sens est inversé, la boucle redevient continue. */
[dir="rtl"] .lane-a { animation-name: drift-a-rtl; }
[dir="rtl"] .lane-b { animation-name: drift-b-rtl; }
@keyframes drift-a-rtl { from { transform: translate3d(0,0,0); }    to { transform: translate3d(50%,0,0); } }
@keyframes drift-b-rtl { from { transform: translate3d(50%,0,0); }  to { transform: translate3d(0,0,0); } }
.lanes:hover .lane { animation-play-state: paused; }

/* La carte reprend la grammaire de X — avatar rond, nom gras, arobase et date
   en gris, corps à 15px. Le post est réel ; seul le score est de nous, et son
   débord hors du cadre le dit. */
.xp {
  position: relative; flex: none;
  /* Réduites proportionnellement : deux rangées doivent tenir dans le tiers
     bas d'un 1080 sans écraser le texte. */
  width: 324px;
  margin-inline-end: 14px;
  padding: 11px 13px 10px;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.84);
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  border: 1px solid rgba(255, 255, 255, 0.92);
  box-shadow: var(--lift-2);
  /* Chaque carte a son propre décalage : sans ça la rangée entière bouge
     comme un bloc et le flottement meurt. */
  animation: float 7.5s ease-in-out infinite;
  animation-delay: calc(var(--f) * -0.9s);
}
@keyframes float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-8px) rotate(-0.3deg); }
}
.xp-head { display: flex; align-items: center; gap: 10px; }
.xp-av {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  object-fit: cover; background: var(--hair);
  box-shadow: 0 1px 3px rgba(12,74,110,0.12);
}
.xp-id { min-width: 0; flex: 1; line-height: 1.3; }
.xp-name {
  display: flex; align-items: center; gap: 4px;
  font-weight: 600; font-size: 14px; letter-spacing: -0.012em; color: var(--ink);
  white-space: nowrap; overflow: hidden;
}
.xp-name span { overflow: hidden; text-overflow: ellipsis; }
.xp-check { width: 15px; height: 15px; flex: none; fill: var(--blue); }
.xp-meta { font-size: 13px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.xp-body {
  margin: 8px 0 0; font-size: 14px; line-height: 1.34;
  color: var(--ink); text-wrap: pretty;
  /* Les posts sont choisis pour tenir en trois lignes, mais la rangée est
     étirée par sa carte la plus haute : ce plafond évite qu'un post plus long
     entré plus tard fasse grandir les deux rangées d'un coup. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(3 * 1.34em);
}
.xp-foot {
  margin-top: 10px; padding-top: 9px;
  border-top: 1px solid var(--hair);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 12px; color: var(--faint);
}
.xp-foll { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.xp-urg { font-weight: 500; }
/* « asking now » est l'information la plus forte de la carte : elle passe en
   noir, la seule valeur qui domine le bleu sans lui disputer la teinte. */
.u-now { color: var(--ink); font-weight: 600; }
.u-this_week { color: var(--blue); }

/* Le score flotte au-dessus de la carte et déborde le coin : il appartient à
   Askline, pas au post. C'est le « score flottant », posé sur du réel. */
.xp-score {
  --v: 0;
  position: absolute; top: -12px; right: -10px;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: conic-gradient(from -90deg, var(--blue) calc(var(--v) * 1%), rgba(15,20,25,0.08) 0);
  box-shadow: 0 4px 14px rgba(12, 74, 110, 0.20), 0 1px 3px rgba(12,74,110,0.14);
  transition: background 1s var(--ease);
}
.xp-score::before { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: #fff; }
.xp-score b {
  position: relative;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 14.5px; font-weight: 600; letter-spacing: -0.03em;
  color: var(--blue-ink); line-height: 1;
}
/* Au-delà de 90 la couronne fonce et le chiffre passe en noir. Même teinte,
   deux crans d'intensité : on lit la hiérarchie d'un coup d'œil. */
.xp[data-hot] .xp-score { background: conic-gradient(from -90deg, var(--blue-strong) calc(var(--v) * 1%), rgba(15,20,25,0.09) 0); }
.xp[data-hot] .xp-score b { color: var(--ink); }

.proof-foot {
  margin: clamp(10px, 1.2vh, 16px) auto 0;
  text-align: center; font-size: 13.5px; color: var(--faint); max-width: 64ch;
}

@media (max-width: 720px) {
  .wrap { width: calc(100% - 28px); }
  .nav a:not(.nav-cta) { display: none; }
  .xp { width: 286px; }
  .eyebrow { font-size: 10.5px; letter-spacing: 0.1em; }
  /* Sur mobile le bandeau tenait sur deux lignes : on garde le chiffre, qui
     est l'information, et on laisse tomber l'étiquette. */
  .eyebrow .eyebrow-long { display: none; }

  /* Le champ et son bouton empilés. En ligne, le placeholder était tronqué à
     mi-mot et le bouton mangeait la largeur : le premier geste de la page
     était inutilisable. */
  .ask-field {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    border-radius: 22px;
    padding: 8px;
  }
  .ask-field input { padding: 12px 12px 4px; font-size: 16px; }
  .ask-go { width: 100%; padding: 14px 18px; }
}

/* Sur un écran court, les deux rangées font 390px que la hauteur ne comprime
   pas. C'est donc la seconde qui cède : la rangée A porte déjà les quatre
   meilleurs scores, la preuve reste entière, et la page tient d'un seul tenant
   au lieu de couper une rangée en deux. */
@media (min-width: 721px) and (max-height: 980px) {
  .lane-b { display: none; }
}
/* Le facteur d'échelle rend inutiles les resserrages manuels sur écran court :
   il réduit tout proportionnellement, sans tronquer une citation ni rogner la
   marge qui protège la pastille. La règle qui vivait ici a été retirée — c'est
   elle qui coupait la couronne de 4px sur les portables. */

/* Le mouvement est un supplément, jamais une condition. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .field { display: none; }
  .lanes { overflow-x: auto; }
}

/* ═══ la suite de la page ══════════════════════════════════════════════════
   Même système que le hero : fond clair, verre, un seul bleu. Ces sections
   défilent normalement — l'échelle --k ne s'applique qu'au premier écran, qui
   lui doit tenir d'un bloc.
   ═══════════════════════════════════════════════════════════════════════════ */

section.band { padding: clamp(64px, 9vh, 128px) 0; position: relative; }

.sec-label {
  font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--blue);
  margin: 0 0 14px;
}
.band h2 {
  margin: 0;
  font-size: clamp(28px, 3.4vw, 46px);
  line-height: 1.06;
  letter-spacing: -0.038em;
  font-weight: 600;
  text-wrap: balance;
  max-width: 22ch;
}
.sec-lede {
  margin: 16px 0 0;
  font-size: clamp(15.5px, 1.2vw, 18px);
  line-height: 1.55;
  color: var(--muted);
  max-width: 60ch;
  text-wrap: pretty;
}
.sec-head { margin-bottom: clamp(34px, 4.5vh, 56px); }

/* Révélation au défilement : discrète, une seule fois, jamais bloquante.
   L'état caché n'existe QUE si le script a pris la main (.js-rise sur <html>).
   Sans lui — JavaScript coupé, moteur de rendu statique, robot d'indexation —
   toute la page reste visible. C'est la deuxième fois que je pose ce piège :
   la première, les cartes X disparaissaient pour la même raison. */
html.js-rise .rise { opacity: 0; transform: translateY(18px); }
html.js-rise .rise.seen {
  opacity: 1; transform: none;
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
html.js-rise .rise.d1.seen { transition-delay: 0.09s; }
html.js-rise .rise.d2.seen { transition-delay: 0.18s; }
/* Échelonnement automatique : chaque enfant arrive un cran après le précédent.
   Un groupe qui apparaît d'un bloc paraît plaqué ; décalé, il paraît vivant. */
html.js-rise .stagger > * { opacity: 0; transform: translateY(14px); }
html.js-rise .stagger.seen > * {
  opacity: 1; transform: none;
  transition: opacity 0.62s var(--ease), transform 0.62s var(--ease);
}
html.js-rise .stagger.seen > *:nth-child(1) { transition-delay: 0.02s; }
html.js-rise .stagger.seen > *:nth-child(2) { transition-delay: 0.07s; }
html.js-rise .stagger.seen > *:nth-child(3) { transition-delay: 0.12s; }
html.js-rise .stagger.seen > *:nth-child(4) { transition-delay: 0.17s; }
html.js-rise .stagger.seen > *:nth-child(5) { transition-delay: 0.22s; }
html.js-rise .stagger.seen > *:nth-child(6) { transition-delay: 0.27s; }
html.js-rise .stagger.seen > *:nth-child(n+7) { transition-delay: 0.32s; }

/* ── le passage : un vrai post, de bout en bout ────────────────────────── */
.walk-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  align-items: start;
}
.step {
  position: relative;
  border-radius: var(--r-md);
  background: var(--glass);
  backdrop-filter: blur(22px) saturate(1.6);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--lift-2);
  padding: 22px;
  min-height: 260px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.step-n {
  font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--faint);
  display: flex; align-items: center; gap: 8px;
}
.step-n b {
  font-weight: 600; color: var(--blue-ink);
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(29,155,240,0.14);
  font-size: 11px;
}
/* La flèche entre les étapes : dit qu'il s'agit d'un enchaînement, pas de
   trois fonctionnalités posées côte à côte. */
.step + .step::before {
  content: "";
  position: absolute;
  inset-inline-start: -13px; top: 46px;
  width: 8px; height: 8px;
  border-block-start: 1.5px solid rgba(29,155,240,0.5);
  border-inline-end: 1.5px solid rgba(29,155,240,0.5);
  transform: rotate(45deg);
}

.step-post { font-size: 14.5px; line-height: 1.42; color: var(--ink); text-wrap: pretty; }
.step-who { display: flex; align-items: center; gap: 9px; }
.step-av { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; background: var(--hair); }
.step-name { font-weight: 600; font-size: 13.5px; line-height: 1.25; display: flex; align-items: center; gap: 4px; }
.step-at { font-family: var(--mono); font-size: 12px; color: var(--muted); }

.read-row { display: flex; align-items: center; gap: 12px; }
.read-score {
  --v: 0;
  position: relative; width: 52px; height: 52px; flex: none;
  display: grid; place-items: center; border-radius: 50%;
  background: conic-gradient(from -90deg, var(--blue-strong) calc(var(--v) * 1%), rgba(15,20,25,0.09) 0);
  box-shadow: 0 3px 10px rgba(12,74,110,0.16);
  transition: background 1.1s var(--ease);
}
.read-score::before { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: #fff; }
.read-score b {
  position: relative; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 17px; font-weight: 600; color: var(--ink); letter-spacing: -0.03em;
}
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip-t {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 999px;
  background: rgba(29,155,240,0.10); color: var(--blue-ink);
  border: 1px solid rgba(29,155,240,0.18);
}
.step-why { font-size: 14px; line-height: 1.5; color: var(--muted); }
.step-why b { color: var(--ink); font-weight: 600; }

/* La zone de réponse reprend la forme d'un champ de saisie X : on comprend
   sans légende que c'est prêt à partir. */
.compose {
  margin-top: auto;
  border-radius: 14px;
  border: 1px solid rgba(29,155,240,0.28);
  background: #fff;
  padding: 13px 14px;
  box-shadow: 0 2px 8px rgba(12,74,110,0.06) inset;
}
.compose p { margin: 0; font-size: 14.5px; line-height: 1.45; color: var(--ink); }
.compose-foot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--hair);
}
.compose-count { font-family: var(--mono); font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; }


/* ── l'index de la demande ─────────────────────────────────────────────── */
.index-top { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 24px; }
.tally { display: flex; gap: clamp(20px, 3vw, 44px); }
.tally div { text-align: end; }
.tally b {
  display: block;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: clamp(26px, 2.6vw, 38px); font-weight: 600;
  letter-spacing: -0.04em; color: var(--blue-ink); line-height: 1;
}
.tally span {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--faint);
}
.cats {
  margin-top: clamp(28px, 4vh, 46px);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(212px, 1fr));
  gap: 10px;
}
.cat {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 15px;
  border-radius: 12px;
  background: rgba(255,255,255,0.62);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  border: 1px solid rgba(255,255,255,0.85);
  box-shadow: var(--lift-1);
  text-decoration: none; color: inherit;
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease), border-color 0.22s var(--ease);
}
.cat:hover { transform: translateY(-2px); box-shadow: var(--lift-2); border-color: rgba(29,155,240,0.35); }
.cat span { font-size: 14px; font-weight: 500; }
.cat b {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 13px; font-weight: 600; color: var(--blue-ink);
  background: rgba(29,155,240,0.10);
  padding: 3px 8px; border-radius: 999px;
}

/* ── les plans ─────────────────────────────────────────────────────────── */
.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; align-items: stretch; }
.plan {
  display: flex; flex-direction: column; gap: 16px;
  padding: 26px 24px;
  border-radius: var(--r-md);
  background: var(--glass);
  backdrop-filter: blur(22px) saturate(1.6);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  border: 1px solid rgba(255,255,255,0.9);
  box-shadow: var(--lift-2);
}
.plan[data-featured] {
  background: var(--glass-strong);
  border-color: rgba(29,155,240,0.42);
  box-shadow: 0 0 0 1px rgba(29,155,240,0.16), var(--lift-3);
}
.plan-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.plan-name { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.plan-tag {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.13em; text-transform: uppercase;
  color: #fff; background: var(--blue); padding: 3px 9px; border-radius: 999px;
}
.plan-price {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 40px; font-weight: 600; letter-spacing: -0.045em; line-height: 1;
  color: var(--ink);
}
.plan-price s { text-decoration: none; font-size: 14px; color: var(--faint); letter-spacing: 0; margin-left: 4px; }
.plan ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.plan li { display: flex; gap: 9px; font-size: 14.5px; line-height: 1.4; color: var(--muted); }
.plan li b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.plan li::before {
  content: ""; flex: none; margin-top: 7px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--blue);
}
.plan .btn { justify-content: center; width: 100%; }

/* ── la clôture ────────────────────────────────────────────────────────── */
.close { text-align: center; display: flex; flex-direction: column; align-items: center; }
.close h2 { max-width: 20ch; }
.close .ask { margin-top: 28px; }

.site-foot {
  border-top: 1px solid var(--hair);
  padding: 26px 0 34px;
  background: rgba(255,255,255,0.5);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}
.foot-in { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; font-size: 13.5px; color: var(--muted); }
.foot-in a:not(.btn) { color: var(--muted); text-decoration: none; }
.foot-in a:not(.btn):hover { color: var(--ink); }
.foot-in .sp { margin-left: auto; color: var(--faint); font-size: 12.5px; }

@media (max-width: 980px) {
  .walk-grid, .plans { grid-template-columns: 1fr; }
  .step + .step::before { left: 50%; top: -13px; transform: rotate(135deg); }
}

/* ── l'inbox : la surface qu'on achète ─────────────────────────────────── */
.inbox {
  border-radius: var(--r-lg);
  background: var(--glass);
  backdrop-filter: blur(26px) saturate(1.7);
  -webkit-backdrop-filter: blur(26px) saturate(1.7);
  border: 1px solid rgba(255,255,255,0.9);
  box-shadow: var(--lift-3);
  overflow: hidden;
}
.inbox-bar {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--hair);
  background: rgba(255,255,255,0.5);
}
.inbox-title { font-weight: 600; font-size: 14.5px; letter-spacing: -0.01em; }
.inbox-stat {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--faint);
}
.inbox-stat b { color: var(--blue-ink); font-variant-numeric: tabular-nums; }
.inbox-live { margin-left: auto; display: flex; align-items: center; gap: 7px; }

.row {
  display: grid;
  grid-template-columns: 54px 1fr auto;
  align-items: center;
  gap: 16px;
  padding: 15px 18px;
  border-bottom: 1px solid var(--hair);
  transition: background 0.2s var(--ease);
}
.row:last-child { border-bottom: 0; }
.row:hover { background: rgba(255,255,255,0.66); }
.row[data-top] { background: rgba(29,155,240,0.045); }
.row-score {
  --v: 0;
  position: relative; width: 44px; height: 44px;
  display: grid; place-items: center; border-radius: 50%;
  background: conic-gradient(from -90deg, var(--blue) calc(var(--v) * 1%), rgba(15,20,25,0.08) 0);
  transition: background 1.1s var(--ease);
}
.row[data-top] .row-score { background: conic-gradient(from -90deg, var(--blue-strong) calc(var(--v) * 1%), rgba(15,20,25,0.09) 0); }
.row-score::before { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: #fff; }
.row-score b {
  position: relative; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 14.5px; font-weight: 600; color: var(--blue-ink); letter-spacing: -0.03em;
}
.row[data-top] .row-score b { color: var(--ink); }
.row-main { min-width: 0; }
.row-who { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.row-av { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; background: var(--hair); flex: none; }
.row-name { font-weight: 600; font-size: 13.5px; letter-spacing: -0.01em; }
.row-at { font-family: var(--mono); font-size: 12px; color: var(--faint); }
.row-text {
  font-size: 14px; line-height: 1.4; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.inbox-foot {
  padding: 13px 18px; border-top: 1px solid var(--hair);
  background: rgba(255,255,255,0.42);
  font-size: 13px; color: var(--faint); text-align: center;
}

/* ── le comparatif : ce qu'on n'est pas ────────────────────────────────── */
.versus { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--hair);
  border-radius: var(--r-md); overflow: hidden; border: 1px solid rgba(255,255,255,0.9);
  box-shadow: var(--lift-2); }
.vs-col { background: rgba(255,255,255,0.58); padding: 22px 20px; display: flex; flex-direction: column; gap: 12px; }
.vs-col[data-us] { background: rgba(255,255,255,0.86); }
.vs-kind {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--faint);
}
.vs-col[data-us] .vs-kind { color: var(--blue); }
/* Promu en h3 pour la structure : la mise en forme reste celle de la classe. */
h3.vs-what { margin: 0; }
.vs-what { font-size: 16px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.25; }
.vs-gap { font-size: 14px; line-height: 1.48; color: var(--muted); }
.vs-col[data-us] .vs-gap { color: var(--ink); }

/* ── la FAQ ────────────────────────────────────────────────────────────── */
.qa { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px 40px; }
.q { border-top: 1px solid var(--line); padding-top: 16px; }
.q h3 { margin: 0 0 8px; font-size: 16px; font-weight: 600; letter-spacing: -0.018em; }
.q p { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--muted); }

/* ── les plans, refaits ────────────────────────────────────────────────── */
.plan { position: relative; padding: 28px 26px; }
.plan-price { display: flex; align-items: baseline; gap: 2px; }
.plan-sub {
  font-size: 13px; color: var(--faint); margin: -8px 0 0;
}
.plan ul { margin: 4px 0 0; }
/* Le bouton fantôme sur une carte en verre devenait invisible et lisait comme
   un lien texte. Chaque plan a désormais un bouton qui se voit : plein pour
   celui qu'on recommande, contour franc pour les autres. */
/* Les boutons viennent de styles.css : une seule grammaire pour l'application,
   la page d'accueil et les modales. Ici on ne règle que ce qui tient à la
   place qu'ils occupent, jamais leur finition. */
.plan .btn { margin-top: 4px; }

.plan-note {
  margin: 0; text-align: center; font-size: 12.5px; color: var(--faint);
}
.price-foot {
  margin: 26px auto 0; text-align: center; font-size: 13.5px; color: var(--muted);
  display: flex; flex-wrap: wrap; gap: 8px 22px; justify-content: center;
}
.price-foot span { display: inline-flex; align-items: center; gap: 7px; }
.price-foot span::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--blue);
}

/* ── l'index, sans compteurs ───────────────────────────────────────────── */
/* Afficher « 12 », « 11 », « 10 » par catégorie faisait maigre. Le chiffre qui
   compte est le total ; les catégories, elles, disent l'étendue. */
.cat { justify-content: flex-start; }
.cat b { display: none; }
.cat::after {
  content: ""; margin-left: auto; flex: none;
  width: 6px; height: 6px;
  border-block-start: 1.5px solid rgba(29,155,240,0.45);
  border-inline-end: 1.5px solid rgba(29,155,240,0.45);
  transform: rotate(45deg);
  transition: transform 0.2s var(--ease), border-color 0.2s var(--ease);
}
.cat:hover::after { transform: rotate(45deg) translate(2px, -2px); border-color: var(--blue); }

@media (max-width: 980px) {
  .versus { grid-template-columns: 1fr 1fr; }
  .qa { grid-template-columns: 1fr; gap: 14px; }
  .row { grid-template-columns: 44px 1fr; }
  .row-act { display: none; }
}
@media (max-width: 620px) {
  .versus { grid-template-columns: 1fr; }
}

/* ── la lecture du site ────────────────────────────────────────────────────
   Elle prend plusieurs secondes : le bouton doit montrer qu'il travaille,
   sinon on le croit mort et on le frappe. L'anneau tourne pendant toute la
   requête et le champ passe en lecture seule pour qu'on ne modifie pas
   l'adresse en cours de route.
   ───────────────────────────────────────────────────────────────────────── */
#siteFill[data-reading] {
  cursor: progress;
  opacity: 1;               /* le bouton est occupé, pas indisponible */
}
#siteFill[data-reading]::before {
  content: "";
  display: inline-block;
  width: 13px; height: 13px;
  margin-inline-end: 8px;
  vertical-align: -2px;
  border-radius: 50%;
  border: 2px solid rgba(29, 155, 240, 0.25);
  border-top-color: var(--blue, #1d9bf0);
  animation: siteSpin 0.72s linear infinite;
}
@keyframes siteSpin { to { transform: rotate(360deg); } }

/* Le champ verrouillé le dit visuellement, sinon on tape dedans sans effet. */
#siteUrl:read-only { background: rgba(15, 20, 25, 0.03); cursor: progress; }

/* Le message de progression respire pendant l'attente. */
#siteFillMsg:not(.is-ok):not(.is-error) { animation: briefBreathe 1.9s ease-in-out infinite; }
@keyframes briefBreathe { 0%, 100% { opacity: 0.62; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  #siteFill[data-reading]::before { animation: none; border-top-color: var(--blue, #1d9bf0); }
  #siteFillMsg { animation: none !important; }
}

/* ── la modale d'identification ────────────────────────────────────────────
   Elle reste stylée par styles.css ; on ne corrige ici que deux choses.
   ───────────────────────────────────────────────────────────────────────── */

/* La marque est centrée et porte son nom : un symbole seul, aligné à gauche,
   ne dit pas où l'on est au moment où on confie son mot de passe. */
#authModal .modal-brand,
#waitModal .modal-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  margin-bottom: 18px;
}
#authModal .modal-logo,
#waitModal .modal-logo { width: 30px; height: 30px; margin-bottom: 0; }
#authModal .modal-word,
#waitModal .modal-word {
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -0.03em;
  color: var(--ink, #0f1419);
}

/* Les deux onglets occupent toute la largeur, comme le bouton Google en
   dessous : deux boutons au gabarit de leur texte, posés au-dessus d'un
   bouton pleine largeur, cassaient l'alignement de la colonne. */
#authModal .tabs { display: flex; gap: 8px; }
#authModal .tabs .authTab {
  flex: 1 1 0;
  min-width: 0;
  justify-content: center;
  text-align: center;
}

/* ── contenu d'autrui dans une page qui n'est pas dans sa langue ──────────
   Un post anglais rendu dans une page arabe hérite de direction: rtl. La
   ponctuation neutre — point d'interrogation final, deux-points — prend alors
   la direction du paragraphe et saute en tête de phrase : « Sentry? » devient
   « ?Sentry », et « 1.2K followers » devient « followers 1.2K ».

   unicode-bidi: plaintext fait déterminer la direction de chaque élément par
   son propre premier caractère fort. Un post anglais s'affiche donc en
   gauche-à-droite, un post arabe en droite-à-gauche, sans rien savoir à
   l'avance de la langue — ce qui est exactement notre cas : ces textes
   viennent de X, on ne les choisit pas.
   ───────────────────────────────────────────────────────────────────────── */
.xp-body, .xp-meta, .xp-foll, .xp-name,
.row-text, .row-at, .row-name,
.step-post, .step-at, .step-name,
.compose p, .compose-count {
  unicode-bidi: plaintext;
}

/* La pastille garde son écart ; le reste du bandeau se contente du gap. */
.eyebrow .dot-live { margin-inline-end: 4px; }
.eyebrow-sep { opacity: 0.55; }

/* Géométrie propre à chaque emplacement — la finition, elle, est commune. */
.ask-go { padding: 13px 22px; font-size: 15px; white-space: nowrap; flex: none; }
.row-act { padding: 6px 14px; font-size: 12.5px; white-space: nowrap; }
.compose-send { padding: 7px 15px; font-size: 13px; }
/* Le bouton de la barre est le même que celui des cartes : il ne garde
   ici que sa taille, sa finition vient de .btn-lime. */
/* Le bouton de la barre est le même que celui des cartes : il ne garde
   ici que sa taille, sa finition vient de .btn-lime. */
/* .nav a impose une graisse de 500 et l'emporte en spécificité :
   le bouton doit la reprendre pour rester dans la famille. */
/* .nav a impose sa couleur et sa graisse, et l'emporte en spécificité sur
   .btn-lime : le texte du bouton redevenait sombre sur son fond bleu. Il faut
   les reprendre ici, au survol comme au repos. */
.nav .nav-cta,
.nav .nav-cta:hover { color: #fff; padding: 9px 17px; font-size: 14.5px; font-weight: 600; }

/* ── la section formulaire ─────────────────────────────────────────────────
   Le formulaire vient de l'ancienne page et son balisage est intouchable :
   landing.js s'appuie sur ses identifiants et ses noms de champ. On ne
   change donc que la mise en forme, portée sur #scanBand pour que le même
   formulaire dans l'application garde la sienne.
   ───────────────────────────────────────────────────────────────────────── */
/* Deux colonnes : l'argument à gauche, l'instrument à droite. La section
   prend ainsi toute la largeur des autres au lieu d'une colonne centrée, et
   le texte reste lisible au lieu de courir sur 1180px. */
#scanBand .form-split {
  display: grid;
  grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}
#scanBand .sec-head {
  margin-bottom: 0;
  position: sticky;
  top: calc(var(--nav-h) + 28px);
}
#scanBand .sec-head h2 { max-width: 15ch; }
#scanBand .sec-head .sec-lede { max-width: 40ch; }
#scanBand .form-shell { min-width: 0; }

@media (max-width: 980px) {
  #scanBand .form-split { grid-template-columns: 1fr; }
  #scanBand .sec-head { position: static; margin-bottom: 4px; }
  #scanBand .sec-head h2, #scanBand .sec-head .sec-lede { max-width: none; }
}
@media (max-width: 620px) {
  /* Côte à côte, l'adresse et son bouton se partagent 347px : il reste à peine
     deux cents pixels pour taper une URL. Empilés, comme le champ du hero. */
  #scanBand .url-fill { flex-direction: column; }
  #scanBand #siteFill { width: 100%; }
}

#scanBand #scanForm {
  border-radius: var(--r-md);
  background: var(--glass);
  backdrop-filter: blur(22px) saturate(1.6);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--lift-3);
  padding: clamp(22px, 3vw, 32px);
}

/* Le titre interne faisait doublon avec celui de la section : il devient la
   première étiquette du formulaire au lieu d'un second titre. */
#scanBand #scanForm > h3 {
  font-family: var(--mono);
  font-size: 11px; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--blue); margin: 0 0 6px;
}
#scanBand #scanForm > .hint-tight:first-of-type { margin-top: 0; }

/* Les étiquettes prennent le vocabulaire des sections : mono, capitales,
   très espacées. C'est ce qui fait lire un formulaire comme un instrument
   plutôt que comme un questionnaire administratif. */
#scanBand #scanForm label {
  font-family: var(--mono);
  font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--faint);
  margin-top: 18px; margin-bottom: 7px;
  display: block;
}

#scanBand #scanForm input,
#scanBand #scanForm textarea {
  background: #fff;
  border: 1.5px solid rgba(15, 20, 25, 0.10);
  border-radius: 14px;
  padding: 12px 15px;
  font-size: 15px;
  box-shadow: 0 1px 2px rgba(12, 74, 110, 0.04);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
#scanBand #scanForm input:focus,
#scanBand #scanForm textarea:focus {
  outline: 0;
  border-color: rgba(29, 155, 240, 0.55);
  box-shadow: 0 0 0 4px rgba(29, 155, 240, 0.13);
}
#scanBand #scanForm textarea { min-height: 104px; line-height: 1.5; }

/* Le séparateur « or write it yourself » devient une vraie ligne de partage. */
#scanBand .brief-or {
  display: flex; align-items: center; gap: 14px;
  margin: 22px 0 4px;
  font-family: var(--mono);
  font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--faint);
}
#scanBand .brief-or::before,
#scanBand .brief-or::after {
  content: ""; flex: 1; height: 1px; background: var(--hair);
}

/* Le champ d'adresse et son bouton, au même gabarit que le champ du hero. */
#scanBand .url-fill { display: flex; gap: 10px; align-items: stretch; }
#scanBand .url-fill input { flex: 1; min-width: 0; }
#scanBand #siteFill { flex: none; white-space: nowrap; }

#scanBand #scanBtn { margin-top: 4px; }
#scanBand .hint { color: var(--faint); font-size: 13px; }
