/* ============================================================
   Manifst, landing v2 (prototype)
   Feuille autonome : ne dépend pas de assets/css/landing.css
   ============================================================ */

:root {
  --primary:      #6366f1;
  --primary-dark: #4f46e5;
  --primary-soft: #eef2ff;
  --ink:          #0f172a;
  --text:         #334155;
  --muted:        #64748b;
  --line:         #e2e8f0;
  --bg:           #ffffff;
  --bg-alt:       #f8fafc;
  --surface:      #ffffff;
  --success:      #10b981;
  --warning:      #f59e0b;
  --danger:       #ef4444;
  --radius:       12px;
  --radius-lg:    18px;
  --shadow:       0 1px 3px rgba(15,23,42,.06), 0 1px 2px rgba(15,23,42,.04);
  --shadow-lg:    0 12px 32px -8px rgba(15,23,42,.14);
  --maxw:         1120px;
}



/* Parti pris : la landing reste en clair, quel que soit le theme du systeme.
   Aucun bloc prefers-color-scheme n'est donc defini. */

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: var(--bg);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 { color: var(--ink); line-height: 1.18; margin: 0 0 .5em; font-weight: 800; letter-spacing: -.02em; }
h1 { font-size: clamp(2rem, 4.6vw, 3.4rem); }
h2 { font-size: clamp(1.6rem, 3vw, 2.35rem); }
h3 { font-size: 1.15rem; font-weight: 700; letter-spacing: -.01em; }
p  { margin: 0 0 1em; }
a  { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }
strong { color: var(--ink); font-weight: 650; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.section { padding: 88px 0; }
.section.alt { background: var(--bg-alt); border-block: 1px solid var(--line); }
.center { text-align: center; }
.lead { font-size: 1.15rem; color: var(--muted); max-width: 62ch; }
.center .lead { margin-inline: auto; }

/* ---------- eyebrow ---------- */
.eyebrow {
  display: inline-block;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 14px;
}

/* ---------- nav ---------- */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.nav-in {
  max-width: var(--maxw); margin: 0 auto; padding: 12px 24px;
  display: flex; align-items: center; gap: 28px;
}
.brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 800; color: var(--ink); font-size: 1.1rem; letter-spacing: -.02em;
}
.brand:hover { text-decoration: none; }
.brand img { border-radius: 8px; }
.nav-links { display: flex; gap: 22px; margin-left: auto; align-items: center; flex-wrap: wrap; }
.nav-links a { color: var(--text); font-size: .93rem; font-weight: 500; }
.nav-links a:hover { color: var(--primary); text-decoration: none; }
.nav-links a[aria-current="page"] { color: var(--primary); font-weight: 650; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 22px; border-radius: 10px;
  font-weight: 650; font-size: .95rem; border: 1px solid transparent;
  cursor: pointer; transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn-primary { background: var(--primary); color: #fff; box-shadow: 0 6px 16px -6px rgba(99,102,241,.7); }
.btn-primary:hover { background: var(--primary-dark); color: #fff; }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--primary); color: var(--primary); }
.btn-sm { padding: 9px 16px; font-size: .88rem; }
.btn-row { display: flex; gap: 12px; flex-wrap: wrap; }
.center .btn-row { justify-content: center; }

/* ---------- modale de contact publique ----------
   Même hiérarchie que la modale Enterprise de Settings, avec les champs
   d'identité nécessaires lorsqu'aucune session n'est ouverte. */
.contact-dialog {
  width: min(590px, calc(100% - 32px));
  max-height: calc(100dvh - 32px);
  margin: auto;
  padding: 0;
  overflow: auto;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 28px 70px rgba(15,23,42,.24);
}
.contact-dialog::backdrop { background: rgba(15,23,42,.58); backdrop-filter: blur(2px); }
.contact-dialog[open] { animation: contact-dialog-in .18s ease-out; }
@keyframes contact-dialog-in {
  from { opacity: 0; transform: translateY(8px) scale(.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.contact-dialog__header {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 18px 22px; border-bottom: 1px solid var(--line);
}
.contact-dialog__title { display: flex; align-items: center; gap: 9px; margin: 0; font-size: 1.05rem; }
.contact-dialog__title i { color: #0f766e; }
.contact-dialog__close {
  display: grid; place-items: center; flex: 0 0 auto; width: 34px; height: 34px;
  padding: 0; border: 0; border-radius: 8px; background: transparent;
  color: var(--muted); font: inherit; font-size: 1.15rem; cursor: pointer;
}
.contact-dialog__close:hover { background: var(--bg-alt); color: var(--ink); }
.contact-dialog__body { padding: 20px 22px; }
.contact-dialog__intro { margin: 0 0 12px; color: var(--muted); font-size: .84rem; line-height: 1.6; }
.contact-dialog__context {
  display: inline-flex; align-items: center; gap: 6px; margin: 0 0 17px;
  padding: 5px 9px; border-radius: 999px; background: var(--primary-soft);
  color: var(--primary-dark); font-size: .76rem; font-weight: 700;
}
.contact-dialog__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 13px; }
.contact-field { display: grid; gap: 6px; margin-bottom: 13px; }
.contact-field label { color: var(--ink); font-size: .78rem; font-weight: 650; }
.contact-field input,
.contact-field textarea {
  width: 100%; padding: 10px 12px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 8px; outline: 0;
  font: inherit; font-size: .86rem; line-height: 1.5; resize: vertical;
  transition: border-color .15s, box-shadow .15s;
}
.contact-field input:focus,
.contact-field textarea:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(99,102,241,.13); }
.contact-captcha {
  display: grid; grid-template-columns: minmax(0,1fr) 112px; gap: 10px;
  align-items: end; margin-bottom: 13px;
}
.contact-captcha__question {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  min-height: 43px; padding: 9px 11px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--bg-alt); color: var(--ink);
  font-size: .86rem; font-weight: 700;
}
.contact-captcha__refresh {
  display: grid; place-items: center; flex: 0 0 auto; width: 28px; height: 28px;
  padding: 0; border: 0; border-radius: 6px; background: transparent;
  color: var(--primary-dark); font: inherit; cursor: pointer;
}
.contact-captcha__refresh:hover { background: var(--primary-soft); }
.contact-captcha .contact-field { margin-bottom: 0; }
.contact-honeypot {
  position: absolute !important; left: -10000px !important; top: auto !important;
  width: 1px !important; height: 1px !important; overflow: hidden !important;
}
.contact-feedback { display: none; margin-top: 4px; padding: 10px 12px; border-radius: 8px; font-size: .82rem; }
.contact-feedback.is-error { display: block; color: #b91c1c; background: #fef2f2; }
.contact-feedback.is-success { display: block; color: #15803d; background: #f0fdf4; }
.contact-dialog__footer {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 14px 22px; border-top: 1px solid var(--line);
}
.contact-dialog__footer .btn { min-height: 40px; }
.contact-dialog__spinner {
  width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: contact-spin .65s linear infinite;
}
@keyframes contact-spin { to { transform: rotate(360deg); } }
body.contact-dialog-open { overflow: hidden; }
@media (max-width: 560px) {
  .contact-dialog { width: calc(100% - 20px); max-height: calc(100dvh - 20px); }
  .contact-dialog__header, .contact-dialog__body, .contact-dialog__footer { padding-inline: 16px; }
  .contact-dialog__grid { grid-template-columns: 1fr; gap: 0; }
  .contact-captcha { grid-template-columns: minmax(0,1fr) 96px; }
  .contact-dialog__footer .btn { flex: 1; justify-content: center; }
}

/* ---------- hero ---------- */
.hero { padding: 76px 0 72px; position: relative; }
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(900px 380px at 12% -8%, var(--primary-soft), transparent 65%),
    radial-gradient(700px 320px at 92% 4%, color-mix(in srgb, var(--success) 12%, transparent), transparent 65%);
}
.hero h1 { max-width: 17ch; }
.hero .lead { font-size: 1.22rem; max-width: 60ch; }
.hero-note { font-size: .88rem; color: var(--muted); margin-top: 18px; }

.kicker {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 14px;
  font-size: .84rem; font-weight: 600; color: var(--muted);
  margin-bottom: 22px; box-shadow: var(--shadow);
}
.kicker .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success); }

/* ---------- grids ---------- */
.grid { display: grid; gap: 20px; }
.g2 { grid-template-columns: repeat(2, 1fr); }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .g3, .g4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .g2, .g3, .g4 { grid-template-columns: 1fr; } }

/* Trois par rangee, mais la rangee incomplete se recentre.
   Une grille a colonnes fixes laisse les cartes orphelines calees a gauche,
   avec un trou a droite qui se lit comme un oubli. En boite flexible elles se
   recentrent d'elles-memes, et a tous les points de rupture : cinq cartes font
   3+2 en grand, 2+2+1 en moyen, et l'orpheline est centree dans les deux cas.
   Les largeurs maximales reproduisent le rythme de .g3, sinon deux cartes
   seules s'etaleraient sur toute la largeur. */
.g3-center { display: flex; flex-wrap: wrap; justify-content: center; }
/* La base doit valoir la largeur visee, et pas une valeur plus petite : c'est
   elle qui decide du nombre de cartes par rangee, la largeur maximale ne fait
   que brider la croissance ensuite. Avec une base de 240px, quatre cartes
   tenaient encore sur la premiere rangee et le decoupage donnait 4+1. */
.g3-center > * {
  flex: 1 1 calc((100% - 40px) / 3);
  max-width: calc((100% - 40px) / 3);
}
@media (max-width: 900px) {
  .g3-center > * { flex-basis: calc((100% - 20px) / 2); max-width: calc((100% - 20px) / 2); }
}
@media (max-width: 640px) {
  .g3-center > * { flex-basis: 100%; max-width: 100%; }
}

/* ---------- cards ---------- */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 26px;
}
.card h3 { margin-bottom: 8px; }
.card p:last-child { margin-bottom: 0; }
.card p { font-size: .95rem; }
.card .ico {
  width: 40px; height: 40px; border-radius: 10px;
  display: grid; place-items: center; font-size: 1.15rem;
  background: var(--primary-soft); color: var(--primary); margin-bottom: 16px;
}

.pillar { border-top: 3px solid var(--primary); }
.pillar .step { font-size: .75rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.pillar ul { margin: 14px 0 0; padding-left: 18px; font-size: .93rem; }
.pillar li { margin-bottom: 5px; }

/* ---------- "avant / après" ---------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: stretch; }
@media (max-width: 780px) { .split { grid-template-columns: 1fr; } }
.stack-box { border-radius: var(--radius); padding: 26px; border: 1px solid var(--line); background: var(--surface); }
.stack-box.before { border-style: dashed; }
.stack-box h3 { font-size: 1rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 750; }
.stack-line { display: flex; align-items: flex-start; gap: 12px; padding: 11px 0; border-bottom: 1px dashed var(--line); font-size: .95rem; }
.stack-line:last-child { border-bottom: 0; }
.stack-line i { font-size: 1.05rem; line-height: 1.5; }
.ko i { color: var(--danger); }
.ok i { color: var(--success); }
.stack-box.after { border-color: var(--primary); box-shadow: var(--shadow-lg); }

/* ---------- KPI / metrics ---------- */
.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
@media (max-width: 820px) { .kpis { grid-template-columns: repeat(2, 1fr); } }
.kpi {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px 20px;
}
.kpi .label { font-size: .78rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); font-weight: 700; }
.kpi .val { font-size: 1.7rem; font-weight: 800; color: var(--ink); letter-spacing: -.03em; line-height: 1.2; margin-top: 4px; }
.kpi .hint { font-size: .8rem; color: var(--muted); }
.kpi.good .val { color: var(--success); }
.kpi.bad  .val { color: var(--danger); }
.kpi.warn .val { color: var(--warning); }

/* ---------- tables ---------- */
.table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
table.cmp { width: 100%; border-collapse: collapse; min-width: 760px; font-size: .93rem; }
table.cmp th, table.cmp td { padding: 14px 16px; text-align: center; border-bottom: 1px solid var(--line); }
table.cmp thead th { font-size: .82rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 750; background: var(--bg-alt); }
table.cmp tbody th, table.cmp td:first-child { text-align: left; font-weight: 600; color: var(--ink); }
table.cmp .me { background: var(--primary-soft); }
table.cmp thead .me { color: var(--primary); }
table.cmp tr:last-child td { border-bottom: 0; }
.yes { color: var(--success); font-weight: 700; }
.no  { color: var(--danger); opacity: .75; }
.part { color: var(--warning); font-weight: 700; }
.cell-note { display: block; font-size: .76rem; color: var(--muted); font-weight: 400; margin-top: 2px; }

/* ---------- pricing ---------- */
/* La grille de prix est le seul bloc plus large que --maxw : a 1120px, quatre
   cartes tombent a 255px et tous les libelles cassent sur deux lignes. */
.wrap-wide { max-width: 1240px; }

/* align-items: stretch, pour que les cartes aient la meme hauteur et que les
   boutons d'appel a l'action s'alignent en bas, quel que soit le nombre de lignes. */
.price-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; align-items: stretch; }
@media (max-width: 1160px) { .price-grid { grid-template-columns: repeat(2, 1fr); max-width: 780px; margin-inline: auto; gap: 22px; } }
@media (max-width: 640px)  { .price-grid { grid-template-columns: 1fr; max-width: 440px; } }

.plan {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 30px 24px 26px;
  position: relative; display: flex; flex-direction: column;
}
.plan.featured { border-color: var(--primary); box-shadow: var(--shadow-lg); }
.plan .badge {
  position: absolute; top: -12px; left: 50%; transform: translateX(-50%);
  background: var(--primary); color: #fff; font-size: .72rem; font-weight: 750;
  padding: 5px 12px; border-radius: 999px; letter-spacing: .03em; white-space: nowrap;
}

/* Hauteur réellement commune (et pas seulement minimale) : une description
   qui passe sur plusieurs lignes ne doit pas décaler le bandeau de crédits IA. */
.plan .phead { height: 200px; padding-bottom: 22px; border-bottom: 1px solid var(--line); }
@media (max-width: 1160px) {
  .plan .phead { height: 178px; }
}
@media (max-width: 640px) {
  .plan .phead { height: auto; }
}
.plan .pname {
  font-size: .74rem; font-weight: 750; color: var(--muted);
  text-transform: uppercase; letter-spacing: .1em;
}
.plan.featured .pname { color: var(--primary); }
/* min-height : « Sur devis » est compose plus petit que « 24 € ». Sans hauteur
   plancher, la modalite et la description de cette carte remonteraient. */
.plan .pprice {
  font-size: 2.35rem; font-weight: 850; color: var(--ink);
  letter-spacing: -.04em; line-height: 1.05; margin: 12px 0 0; min-height: 40px;
}
.plan .pprice small { font-size: .78rem; font-weight: 500; color: var(--muted); letter-spacing: 0; }
.plan .pprice.quote { font-size: 1.75rem; letter-spacing: -.025em; }
/* Ligne de modalite (engagement, absence de carte bancaire, delai de reponse). */
.plan .pyear { font-size: .78rem; color: var(--muted); margin-top: 7px; min-height: 18px; }
.plan .pyear b { color: var(--ink); font-weight: 650; }
.plan .pdesc { font-size: .855rem; line-height: 1.5; color: var(--muted); margin: 13px 0 0; }

/* Bandeau credits IA, sorti de la liste a coups sur. Deux raisons : c'est le
   seul poste consommable de la grille, donc celui que le prospect compare en
   premier entre deux paliers ; et c'est le seul axe d'expansion en dehors du
   passage au palier superieur. Noye en neuvieme puce, il ne se lisait pas. */
/* min-height : la hauteur du bandeau suivrait sinon sa plus grosse police, et
   le palier sans chiffre serait plus plat que les autres, ce qui decalerait le
   debut de sa liste. */
.plan .pcredits {
  display: flex; align-items: center; gap: 9px; min-height: 47px;
  margin: 20px 0 0; padding: 11px 13px; border-radius: 10px;
  background: var(--primary-soft); color: var(--primary-dark);
  font-size: .8rem; font-weight: 600; line-height: 1.3;
}
.plan .pcredits i { font-size: .95rem; flex: 0 0 auto; }
.plan .pcredits b { font-size: 1.2rem; font-weight: 850; letter-spacing: -.025em; }
/* Palier sans credits : meme boite, ton neutre. La ligne reste presente pour
   que les listes des quatre cartes demarrent a la meme hauteur. */
.plan .pcredits.none { background: var(--bg-alt); color: var(--muted); font-weight: 500; }

/* ---------- bareme des credits IA ---------- */
/* Un prospect ne sait pas ce que vaut « 100 credits ». Ce bloc traduit
   l'enveloppe en actions, sinon le chiffre du bandeau ne veut rien dire. */
.credits-tarif { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 20px; }
@media (max-width: 800px) { .credits-tarif { grid-template-columns: 1fr; } }
.credits-tarif .card { padding: 26px 24px; }
.credits-tarif h3 { margin-bottom: 16px; }

.cr-list { list-style: none; margin: 0; padding: 0; }
.cr-list li {
  display: flex; align-items: baseline; gap: 12px;
  padding: 9px 0; font-size: .9rem;
  border-top: 1px solid var(--line);
}
.cr-list li:first-child { border-top: 0; padding-top: 0; }
/* Colonne de cout a largeur fixe : les libelles s'alignent quel que soit le
   nombre de chiffres. Dimensionnee sur le cas le plus large, la fourchette du
   Launchpad (« 18 a 32 cr. »), qui ne doit jamais passer a la ligne. */
.cr-cost {
  flex: 0 0 84px; text-align: right; white-space: nowrap;
  font-weight: 800; color: var(--primary-dark); letter-spacing: -.02em;
}
.cr-cost small { font-weight: 600; font-size: .74rem; color: var(--muted); letter-spacing: 0; }
.cr-what { color: var(--text); }
.cr-note {
  margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: .82rem; line-height: 1.5; color: var(--muted);
}

.cr-mix { margin: 0 0 18px; font-size: .9rem; }
.cr-mix:last-child { margin-bottom: 0; }
.cr-mix b { display: block; color: var(--ink); font-size: .82rem; font-weight: 750; margin-bottom: 3px; }
.cr-mix span { color: var(--muted); }

/* Rythme de liste : marge basse plutot que padding symetrique, pour que les
   items sur deux lignes ne creusent pas d'ecart avec leurs voisins. */
.plan ul { list-style: none; padding: 0; margin: 22px 0 26px; font-size: .865rem; flex: 1 0 auto; }
.plan li { position: relative; padding-left: 23px; margin-bottom: 11px; line-height: 1.45; color: var(--text); }
.plan li::before {
  content: "\2713"; position: absolute; left: 0; top: 0;
  color: var(--success); font-weight: 800; font-size: .84rem;
}
.plan li.off { color: #94a3b8; }
.plan li.off::before { content: "\2013"; color: #cbd5e1; }
.plan li.head {
  padding-left: 0; margin-bottom: 15px; font-size: .82rem;
  font-weight: 700; color: var(--ink);
}
.plan li.head::before { content: none; }
.plan .btn { width: 100%; justify-content: center; margin-top: auto; }

/* ---------- FAQ ---------- */
.faq { max-width: 780px; margin: 0 auto; }
.faq details { border-bottom: 1px solid var(--line); padding: 18px 0; }
.faq summary { cursor: pointer; font-weight: 650; color: var(--ink); list-style: none; display: flex; justify-content: space-between; gap: 16px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--primary); font-weight: 800; font-size: 1.3rem; line-height: 1; }
.faq details[open] summary::after { content: "\2212"; }
.faq p { margin: 12px 0 0; font-size: .95rem; }

/* ---------- callout ---------- */
.callout {
  border-left: 3px solid var(--primary); background: var(--primary-soft);
  padding: 18px 22px; border-radius: 0 var(--radius) var(--radius) 0; font-size: .95rem;
}
.callout.warn { border-left-color: var(--warning); background: color-mix(in srgb, var(--warning) 10%, transparent); }
.callout p:last-child { margin-bottom: 0; }

/* ---------- CTA band ----------
   Le bandeau ferme la page : il doit se lire comme une surface, pas comme un
   aplat. Trois couches, de la plus lointaine a la plus proche :
     1. un degrade de base sombre, qui porte le contraste du texte ;
     2. deux halos radiaux poses dans les angles opposes, meme geste que
        .hero::before : la page ouvre et ferme sur la meme grammaire lumineuse ;
     3. une trame fine, estompee vers les bords par un masque radial.
   Le centre reste le point le plus sombre du bandeau, et c'est la que le texte
   se pose : blanc pur a 9,9:1, texte secondaire a 7,8:1. Les halos clairs sont
   repousses assez loin des angles pour ne jamais remonter sous les lignes. */
.cta-band {
  position: relative;
  isolation: isolate;          /* confine les couches decoratives au bandeau */
  overflow: hidden;
  padding: 96px 0;
  text-align: center;
  color: #fff;
  background:
    radial-gradient(680px 340px at 14% 0%,   #6366f1, transparent 60%),
    radial-gradient(620px 320px at 88% 104%, #7c3aed, transparent 58%),
    linear-gradient(150deg, #312e81 0%, #3730a3 46%, #4338ca 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14);  /* arete haute */
}

/* Trame : 5,5 pour cent de blanc, invisible en tant que motif, suffisante pour
   que la surface accroche la lumiere. Le masque la dissout avant les bords,
   sinon les lignes coupees au ras du bandeau se voient. */
.cta-band::before {
  content: ""; position: absolute; inset: 0; z-index: -3; pointer-events: none;
  background-image:
    linear-gradient(rgba(255,255,255,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.055) 1px, transparent 1px);
  background-size: 56px 56px;
  -webkit-mask-image: radial-gradient(120% 92% at 50% 50%, #000 10%, transparent 74%);
          mask-image: radial-gradient(120% 92% at 50% 50%, #000 10%, transparent 74%);
}

/* Halo mobile : une derive de 26 secondes, si lente qu'on ne la voit pas
   bouger. Elle ne raconte rien, elle empeche seulement le fond de figer. */
.cta-band::after {
  content: ""; position: absolute; z-index: -2; pointer-events: none;
  left: 50%; top: -32%;
  width: 620px; height: 620px; margin-left: -310px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(165,180,252,.26), transparent 66%);
  filter: blur(14px);
  animation: cta-drift 26s ease-in-out infinite alternate;
  transition: opacity .4s ease;
}
@keyframes cta-drift {
  from { transform: translate3d(-9%, -4%, 0) scale(1); }
  to   { transform: translate3d( 9%,  5%, 0) scale(1.12); }
}
@media (prefers-reduced-motion: reduce) {
  .cta-band::after { animation: none; }
}

/* ---- lampe au pointeur ----
   Une lumiere dirigee qui suit la souris et ravive la trame sur son passage.
   La couche est creee par le script (v2.js) : sans JavaScript elle n'existe
   pas, et le bandeau reste exactement celui decrit plus haut.

   La trame y est redessinee trois fois plus claire, au meme pas de 56px et
   avec la meme origine que celle du fond. Les deux doivent se superposer au
   pixel pres : au moindre decalage on verrait deux grilles, pas une grille
   eclairee. D'ou la reprise du pas dans chaque point de rupture.

   Deux radiaux de meme rayon, l'un pour la lumiere, l'autre pour le masque :
   le masque coupe la trame la ou la lumiere s'eteint, sinon la grille claire
   couvrirait tout le bandeau. */
.cta-spot {
  --mx: 50%; --my: 50%;
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  opacity: 0; transition: opacity .35s ease;
  background-image:
    /* .17 et pas plus : la lampe eclaircit le fond, donc elle rapproche le
       fond du blanc du texte. A .22, le paragraphe survole tombait a 4,36:1,
       sous le seuil AA. Mesure faite curseur pose sur le texte, texte masque
       pour echantillonner le fond a l'endroit exact des glyphes. */
    radial-gradient(300px 300px at var(--mx) var(--my), rgba(199,210,254,.17), transparent 70%),
    linear-gradient(rgba(255,255,255,.16) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.16) 1px, transparent 1px);
  background-size: 100% 100%, 56px 56px, 56px 56px;
  -webkit-mask-image: radial-gradient(300px 300px at var(--mx) var(--my), #000 12%, rgba(0,0,0,.4) 52%, transparent 76%);
          mask-image: radial-gradient(300px 300px at var(--mx) var(--my), #000 12%, rgba(0,0,0,.4) 52%, transparent 76%);
}
.cta-band.cta-lit .cta-spot { opacity: 1; }
/* Le halo ambiant se retire quand une lumiere dirigee prend le relais : deux
   sources de meme intensite se neutralisent, le fond redevient plat. */
.cta-band.cta-lit::after { opacity: .5; }

.cta-band .wrap { position: relative; }
/* 36ch : mesure relevee sur les six titres du site. C'est la valeur a partir de
   laquelle tous tiennent sur une ligne jusqu'a 900px. Plus etroit, le titre
   d'accueil cassait entre « un » et « sprint. », au milieu de la phrase. */
.cta-band h2 {
  color: #fff;
  font-size: clamp(1.75rem, 3.4vw, 2.6rem);
  max-width: 36ch; margin-inline: auto;
  text-wrap: balance;          /* sous 900px, repartit les lignes a egalite */
}
.cta-band p {
  /* .92 et non .86 : c'est l'element le plus juste du bandeau en contraste,
     et la lampe au pointeur lui prend sa marge. Voir .cta-spot. */
  color: rgba(255,255,255,.92);
  font-size: 1.06rem;
  max-width: 58ch; margin-inline: auto;
  text-wrap: pretty;
}
.cta-band a:not(.btn) {
  color: #e0e7ff;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cta-band a:not(.btn):hover {
  color: #ffffff;
}

.cta-band .btn { padding: 13px 26px; }
.cta-band .btn-primary {
  background: #fff; color: #3730a3;
  box-shadow: 0 12px 28px -12px rgba(15,23,42,.6), 0 2px 6px rgba(15,23,42,.16);
}
.cta-band .btn-primary:hover { background: #eef2ff; color: #3730a3; }
.cta-band .btn-ghost {
  color: #fff;
  background: rgba(255,255,255,.10);
  border-color: rgba(255,255,255,.32);
  backdrop-filter: blur(4px);
}
.cta-band .btn-ghost:hover { color: #fff; background: rgba(255,255,255,.2); border-color: rgba(255,255,255,.6); }
/* Le contour de focus par defaut du navigateur est sombre : illisible ici. */
.cta-band .btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

@media (max-width: 640px) {
  .cta-band { padding: 68px 0; }
  .cta-band::after { width: 380px; height: 380px; margin-left: -190px; }
  .cta-band::before { background-size: 40px 40px; }
  /* Le pas de la lampe suit celui du fond, sinon les deux grilles se decalent. */
  .cta-spot { background-size: 100% 100%, 40px 40px, 40px 40px; }
}
/* Les deux boutons passent l'un sous l'autre bien avant 480px, mais avec des
   largeurs dictees par leur libelle : deux blocs decales, ca fait desordre.
   En pleine largeur ils redeviennent une pile. */
@media (max-width: 480px) {
  .cta-band .btn-row { flex-direction: column; align-items: stretch; }
  .cta-band .btn { width: 100%; justify-content: center; }
}

/* ---------- footer ---------- */
.foot { background: var(--bg-alt); border-top: 1px solid var(--line); padding: 54px 0 34px; font-size: .9rem; }
.foot-grid { display: grid; grid-template-columns: 2fr repeat(4, 1fr); gap: 32px; }
@media (max-width: 1040px) { .foot-grid { grid-template-columns: 2fr 1fr 1fr; } }
@media (max-width: 780px) { .foot-grid { grid-template-columns: 1fr 1fr; } }
.foot h4 { font-size: .82rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 750; }
.foot ul { list-style: none; padding: 0; margin: 0; }
.foot li { margin-bottom: 8px; }
.foot a { color: var(--text); }
.foot-bottom { margin-top: 36px; padding-top: 20px; border-top: 1px solid var(--line); color: var(--muted); display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }

/* ---------- proto banner ---------- */
.proto {
  background: #fef3c7; color: #78350f;
  border-bottom: 1px solid #fcd34d;
  text-align: center;
  padding: 9px 16px; font-size: .84rem; font-weight: 600;
}
.proto a { color: #7c2d12; text-decoration: underline; }

/* ---------- breadcrumb ---------- */
.crumb { font-size: .85rem; color: var(--muted); padding-top: 26px; }
.crumb a { color: var(--muted); }
.crumb span { margin: 0 7px; opacity: .6; }

/* ============================================================
   Ajouts : visuels produit, preuve sociale, navigation par role
   ============================================================ */

/* ---------- captures produit ---------- */
.shot {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}
.shot img { display: block; width: 100%; height: auto; }
.shot figcaption {
  padding: 12px 18px;
  font-size: .82rem;
  color: var(--muted);
  border-top: 1px solid var(--line);
  background: var(--bg-alt);
}
.shot-tilt { transform: perspective(1600px) rotateX(2.2deg); transform-origin: top center; }
.shot-crop { max-height: 460px; overflow: hidden; }
.shot-crop img { object-fit: cover; object-position: top; }

/* bandeau navigateur factice */
.shot-chrome {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 14px; background: var(--bg-alt); border-bottom: 1px solid var(--line);
}
.shot-chrome i { width: 10px; height: 10px; border-radius: 50%; background: var(--line); display: block; }

/* moitie texte / moitie visuel */
.duo { display: grid; grid-template-columns: minmax(0,.85fr) minmax(0,1.15fr); gap: 44px; align-items: center; }
.duo.rev > :first-child { order: 2; }
@media (max-width: 940px) { .duo { grid-template-columns: 1fr; gap: 30px; } .duo.rev > :first-child { order: 0; } }
.duo h2 { font-size: clamp(1.45rem, 2.4vw, 2rem); }
.duo p { font-size: .98rem; }
.duo ul { padding-left: 18px; font-size: .95rem; margin: 0 0 18px; }
.duo li { margin-bottom: 6px; }

/* ---------- preuve sociale ---------- */
.proof { border-block: 1px solid var(--line); background: var(--bg-alt); padding: 30px 0; }
.proof-in { display: flex; align-items: center; justify-content: center; gap: 40px; flex-wrap: wrap; }
.proof-stat { text-align: center; }
.proof-stat .n { font-size: 1.5rem; font-weight: 850; color: var(--ink); letter-spacing: -.03em; line-height: 1.1; }
.proof-stat .l { font-size: .8rem; color: var(--muted); font-weight: 600; }
.proof-sep { width: 1px; height: 34px; background: var(--line); }
@media (max-width: 700px) { .proof-sep { display: none; } .proof-in { gap: 26px 34px; } }

/* emplacement a remplir (prototype) */
.todo-slot {
  border: 1px dashed var(--warning); border-radius: var(--radius);
  padding: 14px 18px; font-size: .85rem; color: var(--muted);
  background: color-mix(in srgb, var(--warning) 7%, transparent);
}
.todo-slot strong { color: var(--warning); }

/* ---------- navigation par role ---------- */
.chips { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface);
  font-size: .89rem; font-weight: 600; color: var(--text);
  transition: border-color .12s ease, color .12s ease, transform .12s ease;
}
.chip:hover { text-decoration: none; border-color: var(--primary); color: var(--primary); transform: translateY(-1px); }
.chip i { color: var(--primary); }

/* ---------- navigation mobile ---------- */
.nav-burger {
  display: none;
  margin-left: auto;
  width: 42px; height: 42px;
  align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--ink);
  font-size: 1.35rem; line-height: 1; cursor: pointer;
}
.nav-burger:hover { border-color: var(--primary); color: var(--primary); }
.nav-burger:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

@media (max-width: 940px) {
  .nav-in { position: relative; flex-wrap: nowrap; }
  .nav-burger { display: inline-flex; }
  .nav-links {
    display: none;
    position: absolute; top: calc(100% + 12px); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 2px;
    margin-left: 0; padding: 12px 4px 16px;
    background: var(--bg); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow-lg);
  }
  .nav.open .nav-links { display: flex; }
  .nav-links a { padding: 11px 14px; font-size: 1rem; border-radius: 8px; }
  .nav-links a:hover { background: var(--bg-alt); }
  .nav-links .btn { justify-content: center; margin-top: 8px; }
}

/* focus visible generique */
a:focus-visible, .btn:focus-visible, summary:focus-visible {
  outline: 2px solid var(--primary); outline-offset: 3px; border-radius: 4px;
}

/* ============================================================
   Accessibilite : jetons de couleur dedies au TEXTE.
   L'indigo de marque (#6366f1) plafonne a 4,47:1 sur blanc, sous
   le seuil AA de 4,5. On le garde pour le decoratif (bordures,
   fonds doux, degrades) et on introduit des teintes conformes
   pour tout ce qui doit etre lu.
   ============================================================ */
:root {
  --primary-text:  #4f46e5;  /* 6,29:1 sur blanc */
  --success-text:  #047857;  /* 5,48:1 sur blanc */
  --warning-text:  #b45309;  /* 5,02:1 sur blanc */
  --danger-text:   #dc2626;
}


a,
.eyebrow,
.card .ico,
.pillar ul li::marker,
.chip i,
.faq summary::after,
.nav-links a:hover,
table.cmp thead .me { color: var(--primary-text); }

.btn-primary { background: var(--primary-text); }
.btn-primary:hover { background: #4338ca; }
.btn-ghost:hover { border-color: var(--primary-text); color: var(--primary-text); }
.chip:hover { border-color: var(--primary-text); color: var(--primary-text); }

/* Le bouton de la nav heritait de `.nav-links a` (specificite 0,1,1),
   plus forte que `.btn-primary` (0,1,0) : le libelle passait en texte
   sombre sur fond indigo, soit 2,32:1. */
.nav-links a.btn-primary { color: #fff; }
.nav-links a.btn-ghost   { color: var(--ink); }
.nav-links a.btn-primary:hover { color: #fff; }

.kpi.good .val { color: var(--success-text); }
.kpi.bad  .val { color: var(--danger-text); }
.kpi.warn .val { color: var(--warning-text); }
.yes  { color: var(--success-text); }
.part { color: var(--warning-text); }
.no   { color: var(--danger-text); opacity: .85; }
.todo-slot strong { color: var(--warning-text); }
.pillar { border-top-color: var(--primary-text); }
.callout { border-left-color: var(--primary-text); }
.plan.featured, .shot.after { border-color: var(--primary-text); }
.plan .badge { background: var(--primary-text); }
.kicker .dot { background: var(--success-text); }

/* Le bandeau CTA n'a plus de correctif ici : son bloc porte deja le fond
   assombri et les couleurs de bouton conformes. Redeclarer `background` a cet
   endroit ecrasait les trois couches du degrade et rendait l'aplat. */

/* ============================================================
   Schema de la chaine de calcul (SVG inline, thematise)
   ============================================================ */
.diagram { margin: 0; }
.diagram svg { display: block; width: 100%; height: auto; max-width: 960px; margin-inline: auto; }
.dg-col      { fill: var(--surface); stroke: var(--line); stroke-width: 1.5; }
.dg-col-accent { fill: var(--primary-soft); stroke: var(--primary-text); stroke-width: 1.5; }
.dg-chip     { fill: var(--bg-alt); stroke: var(--line); stroke-width: 1; }
.dg-stage    { fill: var(--muted); font-size: 12px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; }
.dg-label    { fill: var(--text); font-size: 14px; font-weight: 500; }
.dg-strong   { fill: var(--ink); font-size: 15px; font-weight: 700; }
.dg-note     { fill: var(--muted); font-size: 12px; }
.dg-val      { fill: var(--primary-text); font-size: 20px; font-weight: 800; }
.dg-val-bad  { fill: var(--danger-text); font-size: 20px; font-weight: 800; }
.dg-arrow    { stroke: var(--muted); stroke-width: 1.5; fill: none; opacity: .75; }
.dg-head     { fill: var(--muted); opacity: .75; }

/* ------------------------------------------------------------------
   Mise en mouvement du schema

   Le schema raconte une chaine de causes : l'equipe produit, Manifst
   calcule, le comite lit. L'animation suit cet ordre de gauche a droite
   au lieu de tout faire apparaitre d'un bloc, pour que le lecteur voie
   le lien plutot que de le deviner.

   Etat par defaut : tout est visible. Rien n'est masque tant que le JS
   n'a pas ajoute .dg-anim, donc sans JS le schema reste complet.
   Sous prefers-reduced-motion, ce bloc entier ne s'applique pas.
   ------------------------------------------------------------------ */
.dg-a1 { --len: 98; }
.dg-a2 { --len: 107; }
.dg-a3 { --len: 100; }
.dg-a4 { --len: 107; }
.dg-a5 { --len: 111; }

@media (prefers-reduced-motion: no-preference) {

  /* --- retards : une etape = une valeur, le reste se calcule --- */
  .dg-s1 { --t: 0ms; }
  .dg-s2 { --t: 580ms; }
  .dg-s3 { --t: 1300ms; }

  /* --- etat arme --- */
  svg.dg-anim .dg-s > text,
  svg.dg-anim .dg-s > rect,
  svg.dg-anim .dg-item,
  svg.dg-anim .dg-arrow,
  svg.dg-anim .dg-head,
  svg.dg-anim .dg-foot { opacity: 0; }
  /* la legende conclut, elle ne precede pas ce qu'elle commente */
  .diagram.dg-anim figcaption { opacity: 0; }
  .diagram.dg-anim.dg-play figcaption { animation: dg-fade 500ms ease-out 2000ms forwards; }

  /* --- 1. le cadre de l'etape --- */
  svg.dg-anim.dg-play .dg-s > text,
  svg.dg-anim.dg-play .dg-s > rect {
    animation: dg-fade 420ms ease-out var(--t) forwards;
  }
  /* la colonne du comite recoit en plus une lueur, c'est la chute */
  svg.dg-anim.dg-play .dg-s3 > rect {
    animation: dg-fade 420ms ease-out var(--t) forwards,
               dg-glow 1200ms ease-out calc(var(--t) + 260ms);
  }

  /* --- 2. les blocs, l'un apres l'autre --- */
  svg.dg-anim.dg-play .dg-item {
    animation: dg-rise 460ms cubic-bezier(.22,.68,.36,1) forwards;
  }
  svg.dg-anim.dg-play .dg-item:nth-of-type(1) { animation-delay: calc(var(--t) +  90ms); }
  svg.dg-anim.dg-play .dg-item:nth-of-type(2) { animation-delay: calc(var(--t) + 170ms); }
  svg.dg-anim.dg-play .dg-item:nth-of-type(3) { animation-delay: calc(var(--t) + 250ms); }

  /* --- 3. les fleches se tracent --- */
  svg.dg-anim.dg-play .dg-arrow {
    stroke-dasharray: var(--len);
    animation: dg-draw 470ms cubic-bezier(.4,0,.25,1) forwards;
  }
  svg.dg-anim.dg-play .dg-a1 { animation-delay: 360ms; }
  svg.dg-anim.dg-play .dg-a2 { animation-delay: 440ms; }
  svg.dg-anim.dg-play .dg-a3 { animation-delay: 520ms; }
  svg.dg-anim.dg-play .dg-a4 { animation-delay: 960ms; }
  svg.dg-anim.dg-play .dg-a5 { animation-delay: 1035ms; }

  /* --- 4. la pointe surgit une fois le trait arrive --- */
  svg.dg-anim.dg-play .dg-head {
    transform-box: fill-box; transform-origin: 0% 50%;
    animation: dg-tip 240ms cubic-bezier(.2,1.5,.4,1) forwards;
  }
  svg.dg-anim.dg-play .dg-h1 .dg-head { animation-delay: 780ms; }
  svg.dg-anim.dg-play .dg-h2 .dg-head { animation-delay: 860ms; }
  svg.dg-anim.dg-play .dg-h3 .dg-head { animation-delay: 940ms; }
  svg.dg-anim.dg-play .dg-h4 .dg-head { animation-delay: 1385ms; }
  svg.dg-anim.dg-play .dg-h5 .dg-head { animation-delay: 1460ms; }

  /* --- 5. la note de bas de schema --- */
  svg.dg-anim.dg-play .dg-foot {
    animation: dg-fade 500ms ease-out 1880ms forwards;
  }
}

@keyframes dg-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes dg-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes dg-draw {
  from { opacity: .75; stroke-dashoffset: var(--len); }
  to   { opacity: .75; stroke-dashoffset: 0; }
}
@keyframes dg-tip {
  from { opacity: 0; transform: scale(.2); }
  to   { opacity: .75; transform: none; }
}
@keyframes dg-glow {
  0%   { filter: drop-shadow(0 0 0 rgba(79,70,229,0)); }
  35%  { filter: drop-shadow(0 0 13px rgba(79,70,229,.55)); }
  100% { filter: drop-shadow(0 0 0 rgba(79,70,229,0)); }
}

/* ---------- hierarchie visuelle ---------- */
.section-major { padding: 104px 0; }
.card-major {
  border-width: 2px; border-color: var(--primary-text);
  box-shadow: var(--shadow-lg); padding: 32px;
}
.limits { background: var(--bg-alt); border-block: 1px solid var(--line); }
.limits .card {
  background: var(--surface);
  border-color: color-mix(in srgb, var(--warning-text) 32%, var(--line));
  border-left: 3px solid var(--warning-text);
}
.limits .eyebrow { color: var(--warning-text); }


/* ---------- finitions typographiques ---------- */
/* Evite les lignes orphelines dans les titres : le navigateur repartit
   les mots au lieu de remplir la premiere ligne au maximum. */
h1, h2, h3 { text-wrap: balance; }
.lead, .hero-note, figcaption { text-wrap: pretty; }

/* Correction : la classe est .stack-box.after, pas .shot.after. */
.stack-box.after { border-color: var(--primary-text); }

/* Le bandeau de note du prototype ne doit pas concurrencer le contenu. */
.todo-slot {
  border-style: dashed; border-width: 1px;
  border-color: color-mix(in srgb, var(--warning-text) 45%, transparent);
  background: transparent; color: var(--muted);
  font-size: .82rem; line-height: 1.55;
}

/* ============================================================
   Captures annotees : pastilles numerotees sur l'image, legende
   numerotee sous l'image. La legende porte le texte, donc le
   lecteur d'ecran et le mobile ne perdent rien.
   ============================================================ */
.shot-media { position: relative; display: block; }
.shot-media img { display: block; width: 100%; height: auto; }

.pin {
  position: absolute;
  left: var(--x); top: var(--y);
  transform: translate(-50%, -50%);
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--primary-text); color: #fff;
  font-size: .82rem; font-weight: 800; line-height: 1;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary-text) 28%, transparent),
              0 2px 8px rgba(15,23,42,.35);
  pointer-events: none;
}

.pin-legend {
  list-style: none; margin: 0; padding: 14px 18px;
  display: grid; gap: 10px;
  border-top: 1px solid var(--line); background: var(--bg-alt);
}
.pin-legend li {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: .88rem; color: var(--text); line-height: 1.5;
}
.pin-legend li > span:first-child {
  flex: 0 0 auto;
  width: 21px; height: 21px; margin-top: 1px;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--primary-text); color: #fff;
  font-size: .72rem; font-weight: 800;
}
.pin-legend strong { color: var(--ink); }

@media (max-width: 560px) {
  .pin { width: 24px; height: 24px; font-size: .72rem; box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-text) 28%, transparent); }
}

/* ============================================================
   Pastilles interactives : le texte de la legende apparait au
   survol et au focus clavier.

   Regle d'accessibilite : le survol n'existe ni au doigt ni au
   clavier. La legende sous l'image reste donc affichee partout,
   et n'est masquee que sur les appareils qui savent survoler.
   ============================================================ */
button.pin {
  border: 0; padding: 0; cursor: help;
  pointer-events: auto;
  transition: transform .16s ease, box-shadow .16s ease;
}
/* Retour visuel par l'anneau, pas par un scale. Un scale sur le bouton
   s'appliquait aussi a la bulle, qui est son enfant : elle etait grossie de
   12 pour cent et decalee, ce qui la faisait sortir du cadre et faussait tout
   calcul de repositionnement. */
button.pin:hover, button.pin:focus-visible {
  box-shadow: 0 0 0 7px color-mix(in srgb, var(--primary-text) 30%, transparent),
              0 3px 12px rgba(15,23,42,.4);
}
button.pin:focus-visible {
  outline: 3px solid var(--ink); outline-offset: 3px;
}

/* halo pulsant : signale que la pastille est explorable */
@media (prefers-reduced-motion: no-preference) {
  button.pin::before {
    content: ""; position: absolute; inset: -6px;
    border-radius: 50%; border: 2px solid var(--primary-text);
    opacity: .55; animation: pin-pulse 2.6s ease-out infinite;
  }
  button.pin:hover::before, button.pin:focus-visible::before { animation: none; opacity: 0; }
}
@keyframes pin-pulse {
  0%   { transform: scale(.85); opacity: .55; }
  70%  { transform: scale(1.5);  opacity: 0; }
  100% { transform: scale(1.5);  opacity: 0; }
}

/* Bulle posee SOUS la pastille, pas a cote. Le placement lateral d'origine ne
   pouvait pas tenir : une bulle de 300px a cote d'une pastille au milieu d'une
   capture de 590px depasse forcement, et .shot a overflow: hidden, donc elle
   se faisait couper au bord du cadre. En vertical, la largeur disponible est
   celle de la capture entiere.
   --nudge est pose par v2.js : il recale horizontalement la bulle quand la
   pastille est trop pres d'un bord. Valeur par defaut 0, donc le placement
   reste correct meme sans JavaScript. */
.pin-tip {
  position: absolute; top: calc(100% + 13px); left: 50%;
  transform: translateX(calc(-50% + var(--nudge, 0px))) translateY(-4px);
  width: max-content; max-width: var(--tip-max, 300px);
  padding: 12px 14px; border-radius: 10px;
  background: var(--ink); color: #f1f5f9;
  font-size: .84rem; font-weight: 400; line-height: 1.5; text-align: left;
  white-space: normal;
  box-shadow: 0 12px 28px -8px rgba(15,23,42,.5);
  opacity: 0; visibility: hidden;
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
  z-index: 5;
}
.pin-tip strong { color: #fff; }
/* La fleche suit la pastille, pas la bulle : elle compense le recalage. */
.pin-tip::after {
  content: ""; position: absolute; bottom: 100%;
  left: 50%; transform: translateX(calc(-50% - var(--nudge, 0px)));
  border: 7px solid transparent; border-bottom-color: var(--ink);
}
/* Pastille dans la moitie basse de la capture : la bulle passe au-dessus. */
.pin--above .pin-tip {
  top: auto; bottom: calc(100% + 13px);
  transform: translateX(calc(-50% + var(--nudge, 0px))) translateY(4px);
}
.pin--above .pin-tip::after {
  bottom: auto; top: 100%;
  border-bottom-color: transparent; border-top-color: var(--ink);
}

button.pin:hover .pin-tip,
button.pin:focus-visible .pin-tip {
  opacity: 1; visibility: visible;
  transform: translateX(calc(-50% + var(--nudge, 0px))) translateY(0);
}

.pin-hint {
  display: none;
  padding: 10px 18px; border-top: 1px solid var(--line);
  background: var(--bg-alt);
  font-size: .82rem; color: var(--muted);
}
.pin-hint i { color: var(--primary-text); }

/* Appareils capables de survoler : la bulle remplace la legende. */
@media (hover: hover) and (pointer: fine) and (min-width: 861px) {
  .pin-legend { display: none; }
  .pin-hint   { display: block; }
}

/* ---------- comparateur a curseur ---------- */
/* Deux captures superposees, la seconde revelee par balayage horizontal. Le
   controle reel est un <input type="range"> rendu transparent par-dessus :
   c'est ce qui donne gratuitement le clavier, le tactile et l'annonce vocale.
   Le trait et la poignee ne sont que du decor, d'ou leur pointer-events: none. */
/* Pas de border-radius ici : .shot arrondit et rogne deja, un second rayon
   imbrique se voit au raccord. */
/* Selecteur qualifie : `table.cmp` est le tableau comparatif, deja stylise plus
   haut. Un `.cmp` nu attrapait les deux et posait overflow: hidden sur ces
   tableaux. */
/* container-type : l'habillage se regle sur la largeur du COMPARATEUR, pas sur
   celle de la fenetre. Les deux ne varient pas ensemble : sur agilite-scrum le
   comparateur occupe la colonne etroite d'un .duo.rev et ne fait que ~437px
   alors que la fenetre en fait 1440. Une requete de media aurait laisse les
   etiquettes en taille bureau dans un cadre deux fois trop petit. */
div.cmp { position: relative; overflow: hidden; container-type: inline-size; }
div.cmp img { display: block; width: 100%; height: auto; }
/* L'image du dessus est rognee a droite de la position du curseur. */
div.cmp .cmp-top {
  position: absolute; inset: 0;
  clip-path: inset(0 calc(100% - var(--pos, 50%)) 0 0);
}

.cmp-handle {
  position: absolute; top: 0; bottom: 0; left: var(--pos, 50%);
  width: 3px; margin-left: -1.5px;
  background: #fff; box-shadow: 0 0 0 1px rgba(15,23,42,.18), 0 2px 10px rgba(15,23,42,.35);
  pointer-events: none;
}
/* Fleche double en caractere Unicode plutot qu'en police d'icones : les
   points de code de Bootstrap Icons changent d'une version a l'autre, et un
   mauvais glyphe est passe en production a l'essai precedent. */
.cmp-handle::after {
  content: "\2194";
  font-size: 1.25rem; font-weight: 700; line-height: 1;
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: #fff; color: var(--primary-text, var(--primary));
  box-shadow: 0 3px 14px rgba(15,23,42,.3);
}

/* Etiquettes de role. En blanc sur fond blanc, elles se lisaient comme un
   element de l'application capturee. En sombre et translucide, elles se lisent
   pour ce qu'elles sont : une annotation posee PAR-DESSUS la capture.
   Typographie reprise de .eyebrow, en plus petit, pour rester dans le
   vocabulaire du site.
   Posees en bas : en haut elles tombaient sur la barre de navigation de
   l'application. Elles s'effacent quand le curseur les recouvre, sinon elles se
   lisent par-dessus la mauvaise moitie. */
.cmp-label {
  position: absolute; bottom: 14px; z-index: 2;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 11px; border-radius: 7px;
  background: rgba(15, 23, 42, .8);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  color: #fff;
  font-size: .66rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .09em; line-height: 1;
  pointer-events: none; transition: opacity .15s ease;
}
/* Pastille de couleur : elle distingue les deux roles sans ajouter de mot, et
   reprend le vert deja utilise dans la capture pour les votants. */
.cmp-label::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex: 0 0 auto;
}
.cmp-label--a { left: 14px; }
.cmp-label--a::before { background: #a5b4fc; }
.cmp-label--b { right: 14px; }
.cmp-label--b::before { background: #6ee7b7; }

/* Cadre etroit : a taille constante, les deux etiquettes couvraient plus de la
   moitie de la largeur et se rejoignaient sur la poignee. Poignee comprise,
   tout l'habillage est reduit.
   Seuil en largeur de CADRE et non de fenetre : il attrape aussi bien le
   telephone que la colonne etroite d'un .duo sur grand ecran. */
@container (max-width: 520px) {
  .cmp-label {
    bottom: 9px; padding: 4px 8px; gap: 5px;
    font-size: .56rem; letter-spacing: .06em; border-radius: 5px;
  }
  .cmp-label::before { width: 5px; height: 5px; }
  .cmp-label--a { left: 9px; }
  .cmp-label--b { right: 9px; }
  .cmp-handle { width: 2px; margin-left: -1px; }
  .cmp-handle::after { width: 32px; height: 32px; font-size: .95rem; }
}

.cmp-range {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; padding: 0; opacity: 0; cursor: ew-resize;
  -webkit-appearance: none; appearance: none; background: transparent;
}
.cmp-range::-webkit-slider-thumb { -webkit-appearance: none; width: 46px; height: 100%; }
.cmp-range::-moz-range-thumb { width: 46px; height: 100%; border: 0; opacity: 0; }
.cmp-range:focus-visible { outline: none; }
.cmp-range:focus-visible ~ .cmp-handle::after {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary-text, var(--primary)) 45%, transparent),
              0 3px 14px rgba(15,23,42,.3);
}

/* ---------- infobulle en version claire ---------- */
.pin-tip {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--line);
  box-shadow: 0 16px 34px -10px rgba(15,23,42,.28),
              0 2px 6px rgba(15,23,42,.08);
}
.pin-tip strong { color: var(--ink); }
/* Fleches en version claire. Elles pointent vers le haut par defaut, la bulle
   etant posee sous la pastille, et se retournent avec .pin--above. */
.pin-tip::after { border-bottom-color: var(--surface); }
.pin--above .pin-tip::after { border-bottom-color: transparent; border-top-color: var(--surface); }
/* liseré de la flèche, pour qu'elle suive la bordure de la bulle */
.pin-tip::before {
  content: ""; position: absolute; bottom: 100%;
  left: 50%; transform: translateX(calc(-50% - var(--nudge, 0px)));
  border: 8px solid transparent; border-bottom-color: var(--line);
}
.pin--above .pin-tip::before {
  bottom: auto; top: 100%;
  border-bottom-color: transparent; border-top-color: var(--line);
}

/* ---------- correction : blanc residuel sous les figures annotees ----------
   .pin-hint est un <p> : il heritait du margin-bottom global, ce qui laissait
   un vide sous la ligne d'invitation. Les conteneurs d'image passent aussi en
   line-height 0, pour qu'aucun retour a la ligne du source ne cree de boite
   de ligne parasite. */
.pin-hint { margin: 0; }
.pin-legend { margin: 0; }
.shot figcaption { margin: 0; }
.shot, .shot-media { line-height: 0; }
.shot figcaption, .shot .pin-hint, .shot .pin-legend { line-height: 1.5; }
.pin { line-height: 1; }

/* ---------- qualification : la colonne « pour vous » domine ----------
   En 50/50, l'argument « restez chez le concurrent » avait exactement la
   meme autorite visuelle que l'argument de vente. On garde les deux, mais
   on leur donne le poids qu'ils meritent. */
.split-major { display: grid; grid-template-columns: 1.45fr .95fr; gap: 24px; align-items: start; }
@media (max-width: 820px) { .split-major { grid-template-columns: 1fr; } }

.split-major .stack-box.after { padding: 30px; }
.split-major .stack-box.after h3 { font-size: 1.05rem; color: var(--ink); letter-spacing: 0; text-transform: none; font-weight: 750; }
.split-major .stack-box.after .stack-line { font-size: 1rem; padding: 13px 0; }

.split-major .stack-box.before { padding: 22px; background: transparent; }
.split-major .stack-box.before h3 { font-size: .78rem; }
.split-major .stack-box.before .stack-line { font-size: .88rem; padding: 9px 0; color: var(--muted); }
.split-major .stack-box.before .stack-line strong { color: var(--text); font-weight: 600; }
.split-major .stack-box.before .stack-line i { font-size: .9rem; color: var(--muted); }

/* ---------- legende du tableau comparatif ---------- */
.cmp-legend {
  list-style: none; margin: 16px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px 26px;
  font-size: .84rem; color: var(--muted);
}
.cmp-legend li { display: flex; align-items: baseline; gap: 8px; }
.cmp-legend .yes,
.cmp-legend .part,
.cmp-legend .no {
  font-size: .78rem; font-weight: 700;
  padding: 2px 8px; border-radius: 5px; white-space: nowrap;
}
.cmp-legend .yes  { background: color-mix(in srgb, var(--success-text) 12%, transparent); }
.cmp-legend .part { background: color-mix(in srgb, var(--warning-text) 14%, transparent); }
.cmp-legend .no   { background: color-mix(in srgb, var(--danger-text) 10%, transparent); opacity: 1; }

/* ---------- tableau comparatif : icone + libelle ----------
   L'icone donne la lecture en diagonale, le libelle garde le sens.
   Sous 820 px le libelle passe en texte masque : la largeur du tableau
   baisse la ou elle genait, sans perte pour les lecteurs d'ecran. */
.v { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; font-size: .88rem; white-space: nowrap; }
.v i { font-size: 1.02rem; line-height: 1; }
.v-yes   { color: var(--success-text); }
.v-part  { color: var(--warning-text); }
.v-addon { color: var(--primary-text); }
.v-no    { color: var(--danger-text); opacity: .8; font-weight: 600; }

table.cmp td { vertical-align: top; }
table.cmp .v + .cell-note { margin-top: 3px; }

@media (max-width: 820px) {
  .v-label {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  .v i { font-size: 1.2rem; }
  .cmp-legend .v-label { position: static; width: auto; height: auto; margin: 0; clip: auto; clip-path: none; }
}

/* Le min-width de 760 px annulait le gain des icones sur mobile. */
@media (max-width: 820px) {
  table.cmp { min-width: 0; font-size: .86rem; }
  table.cmp th, table.cmp td { padding: 11px 8px; }
  table.cmp thead th { font-size: .7rem; letter-spacing: .03em; }
  table.cmp .cell-note { font-size: .7rem; }
}

@media (max-width: 820px) {
  table.cmp th, table.cmp td { padding: 10px 5px; }
  table.cmp td:first-child, table.cmp thead th:first-child { max-width: 132px; padding-left: 10px; }
  table.cmp td:first-child { font-size: .8rem; line-height: 1.35; }
  table.cmp .cell-note { display: block; line-height: 1.3; }
}

@media (max-width: 820px) {
  table.cmp td:first-child, table.cmp thead th:first-child { max-width: 108px; }
  table.cmp th, table.cmp td { padding: 10px 4px; }
}

/* ============================================================
   Tableau comparatif : icone seule, explication en infobulle.
   Le libelle texte disparait de la cellule mais reste dans le DOM
   via l'infobulle, reliee par aria-describedby.
   ============================================================ */
table.cmp .v { position: relative; cursor: help; gap: 0; outline-offset: 3px; }
table.cmp .v-label { display: none; }
table.cmp .v i { font-size: 1.2rem; }
table.cmp .v:focus-visible { outline: 2px solid var(--ink); border-radius: 50%; }

.v-tip {
  position: absolute; bottom: calc(100% + 11px); left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content; max-width: 230px;
  padding: 9px 12px; border-radius: 9px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line);
  box-shadow: 0 14px 30px -10px rgba(15,23,42,.3), 0 2px 6px rgba(15,23,42,.08);
  font-size: .8rem; font-weight: 500; line-height: 1.45; text-align: left;
  white-space: normal;
  opacity: 0; visibility: hidden;
  transition: opacity .14s ease, transform .14s ease, visibility .14s;
  z-index: 20;
}
.v-tip::after,
.v-tip::before {
  content: ""; position: absolute; top: 100%; left: 50%;
  transform: translateX(-50%);
  border: 7px solid transparent;
}
.v-tip::before { border-top-color: var(--line); }
.v-tip::after  { border-top-color: var(--surface); margin-top: -1px; }

table.cmp .v:hover .v-tip,
table.cmp .v:focus .v-tip,
table.cmp .v:focus-within .v-tip {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
}

/* premiere et derniere colonne : la bulle rentre vers l'interieur */
table.cmp td:nth-child(2) .v-tip { left: 0; transform: translateX(0) translateY(4px); }
table.cmp td:nth-child(2) .v:hover .v-tip,
table.cmp td:nth-child(2) .v:focus .v-tip { transform: translateX(0) translateY(0); }
table.cmp td:nth-child(2) .v-tip::after,
table.cmp td:nth-child(2) .v-tip::before { left: 20px; }

table.cmp td:last-child .v-tip { left: auto; right: 0; transform: translateX(0) translateY(4px); }
table.cmp td:last-child .v:hover .v-tip,
table.cmp td:last-child .v:focus .v-tip { transform: translateX(0) translateY(0); }
table.cmp td:last-child .v-tip::after,
table.cmp td:last-child .v-tip::before { left: auto; right: 20px; transform: none; }

/* Les infobulles doivent pouvoir sortir du cadre : sans notes, le tableau
   tient dans la largeur, le conteneur n'a plus besoin de rogner. */
.table-scroll { overflow: visible; }
@media (max-width: 700px) { .table-scroll { overflow-x: auto; } }

/* ============================================================
   Correction d'alignement des infobulles du tableau.
   Les regles de bord decalaient la fleche de 20 px alors que
   l'icone fait 19 px : 17 px d'ecart mesures sur les colonnes 2 et 4.
   La bulle est desormais centree sur l'icone dans tous les cas.
   ============================================================ */
table.cmp td:nth-child(2) .v-tip,
table.cmp td:last-child .v-tip {
  left: 50%; right: auto;
  transform: translateX(-50%) translateY(4px);
}
table.cmp td:nth-child(2) .v:hover .v-tip,
table.cmp td:nth-child(2) .v:focus .v-tip,
table.cmp td:last-child .v:hover .v-tip,
table.cmp td:last-child .v:focus .v-tip {
  transform: translateX(-50%) translateY(0);
}
table.cmp td:nth-child(2) .v-tip::after,
table.cmp td:nth-child(2) .v-tip::before,
table.cmp td:last-child .v-tip::after,
table.cmp td:last-child .v-tip::before {
  left: 50%; right: auto; transform: translateX(-50%);
}

/* Sous 700 px, une bulle centree sur la derniere colonne sortirait de
   l'ecran. On l'ancre alors a la ligne, sur toute la largeur utile. */
@media (max-width: 700px) {
  table.cmp tbody tr { position: relative; }
  table.cmp .v-tip,
  table.cmp td:nth-child(2) .v-tip,
  table.cmp td:last-child .v-tip {
    position: absolute;
    left: 8px; right: 8px; width: auto; max-width: none;
    bottom: calc(100% + 6px);
    transform: translateY(4px);
    text-align: center;
  }
  table.cmp .v:hover .v-tip,
  table.cmp .v:focus .v-tip,
  table.cmp td:nth-child(2) .v:hover .v-tip,
  table.cmp td:nth-child(2) .v:focus .v-tip,
  table.cmp td:last-child .v:hover .v-tip,
  table.cmp td:last-child .v:focus .v-tip { transform: translateY(0); }
  table.cmp .v-tip::after, table.cmp .v-tip::before { display: none; }
}

/* ============================================================
   La fleche appartient desormais a l'icone, plus a la bulle.
   Elle pointe donc toujours l'icone, quelle que soit la position
   de la bulle. C'est ce decouplage qui rend l'alignement fiable
   sur les colonnes de bord comme au centre.
   ============================================================ */
table.cmp .v-tip::after,
table.cmp .v-tip::before { display: none; }

table.cmp .v::after {
  content: ""; position: absolute; left: 50%; bottom: calc(100% + 4px);
  transform: translateX(-50%);
  border: 7px solid transparent; border-top-color: var(--surface);
  filter: drop-shadow(0 1px 0 var(--line));
  opacity: 0; visibility: hidden;
  transition: opacity .14s ease, visibility .14s;
  z-index: 21; pointer-events: none;
}
table.cmp .v:hover::after,
table.cmp .v:focus::after,
table.cmp .v:focus-within::after { opacity: 1; visibility: visible; }

/* Sous 700 px : la bulle se cale sur le bord interieur de sa colonne
   pour rester dans l'ecran, la fleche continuant de viser l'icone. */
@media (max-width: 700px) {
  table.cmp tbody tr { position: static; }
  table.cmp .v-tip {
    position: absolute; bottom: calc(100% + 11px);
    left: 50%; right: auto; width: max-content; max-width: 150px;
    transform: translateX(-50%) translateY(4px); text-align: left;
  }
  table.cmp .v:hover .v-tip,
  table.cmp .v:focus .v-tip { transform: translateX(-50%) translateY(0); }

  table.cmp td:nth-child(2) .v-tip { left: 0; right: auto; transform: translateX(0) translateY(4px); }
  table.cmp td:nth-child(2) .v:hover .v-tip,
  table.cmp td:nth-child(2) .v:focus .v-tip { transform: translateX(0) translateY(0); }

  table.cmp td:last-child .v-tip { left: auto; right: 0; transform: translateX(0) translateY(4px); }
  table.cmp td:last-child .v:hover .v-tip,
  table.cmp td:last-child .v:focus .v-tip { transform: translateX(0) translateY(0); }
}


/* ============================================================
   TEMOIGNAGES : emplacements reserves
   ============================================================
   Un temoignage ne vaut que par son attribution. Le gabarit
   reserve donc la place de tout ce qui rend la parole verifiable
   (prenom, role, societe, secteur, taille d'equipe) et celle
   d'une photo dont l'absence ne decale pas la mise en page.

   Deux etats, un seul gabarit :
     .tm            temoignage publie
     .tm.is-slot    emplacement vide, visible en interne
   Remplir un emplacement = retirer is-slot, retirer le bloc
   .slot-brief, remplacer les textes. Rien d'autre a toucher.
   ============================================================ */

.tm-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 20px; align-items: stretch;
}
@media (max-width: 940px) {
  .tm-grid { grid-template-columns: 1fr; max-width: 560px; margin-inline: auto; }
}

/* margin: 0 obligatoire : .tm est un <figure>, et la feuille par defaut du
   navigateur lui applique margin: 1em 40px. Sans ce reset, chaque carte perdait
   80px de large sur sa colonne de grille, ce qui faisait casser les lignes de
   role sur quatre ou cinq lignes. */
.tm {
  margin: 0;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 28px;
  display: flex; flex-direction: column; gap: 16px;
  box-shadow: var(--shadow);
}
/* La citation occupe la place restante : les attributions restent
   alignees d'une carte a l'autre meme si les textes different. */
.tm-quote {
  margin: 0;
  font-size: 1.02rem; line-height: 1.62; color: var(--ink);
}
/* Le fait marquant de la citation, surligne au lieu d'etre gras :
   l'oeil l'attrape sans que la phrase perde son ton parle. */
.tm-quote b {
  font-weight: 650;
  background: linear-gradient(transparent 60%, var(--primary-soft) 60%);
}

/* Chiffre extrait de la citation. Optionnel : une carte sans
   avant/apres chiffre se passe de cette ligne. */
.tm-stat {
  margin: 0;
  font-size: .84rem; line-height: 1.5;
  color: var(--muted); font-weight: 600;
}
.tm-stat b { color: var(--primary-dark); font-size: 1.02rem; font-weight: 800; letter-spacing: -.02em; }

.tm-who {
  margin-top: auto;
  display: flex; align-items: flex-start; gap: 13px;
  border-top: 1px solid var(--line); padding-top: 16px;
}
/* Meme boite pour une photo ou pour des initiales : la carte a la
   meme hauteur avant et apres reception des photos. */
.tm-av {
  width: 44px; height: 44px; flex: 0 0 44px; border-radius: 50%;
  object-fit: cover; overflow: hidden;
  display: grid; place-items: center;
  background: var(--primary-soft); color: var(--primary-dark);
  font-size: .88rem; font-weight: 800; letter-spacing: .02em;
}
img.tm-av { display: block; }
.tm-id { min-width: 0; }
.tm-name, .tm-role { display: block; }
.tm-name { font-size: .95rem; font-weight: 700; color: var(--ink); }
.tm-role {
  font-size: .81rem; color: var(--muted); line-height: 1.4;
  /* Trois lignes reservees. Deux ne suffisaient pas : une attribution exacte
     (titre complet, organisation) depasse presque toujours 45 caracteres, et
     tronquer les references de quelqu'un decredibilise sa citation. */
  min-height: 4.2em;
}

/* Une citation seule, au fil d'une page profonde. */
.tm-solo { max-width: 760px; margin-inline: auto; padding: 32px 34px; }
.tm-solo .tm-quote { font-size: 1.12rem; line-height: 1.6; }
.tm-solo .tm-who { margin-top: 0; align-items: center; }
.tm-solo .tm-role { min-height: 0; }

/* ---------- etat "emplacement vide" ---------- */
.tm.is-slot {
  border-style: dashed; background: transparent; box-shadow: none;
}
.tm.is-slot .tm-quote { color: var(--muted); font-style: italic; }
.tm.is-slot .tm-name,
.tm.is-slot .tm-role,
.tm.is-slot .tm-stat { color: var(--muted); font-weight: 500; }
.tm.is-slot .tm-stat b { color: var(--muted); font-weight: 700; }
.tm.is-slot .tm-av {
  background: var(--bg-alt); color: var(--muted);
  border: 1px dashed var(--line); font-weight: 700;
}

.slot-tag {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  font-size: .67rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: #78350f; background: #fef3c7; border: 1px solid #fcd34d;
  border-radius: 999px; padding: 3px 10px;
}
/* Le cahier des charges du temoignage a recueillir. Se supprime
   avec la classe is-slot. */
.slot-brief {
  margin: 0; padding-left: 12px; border-left: 2px solid var(--line);
  font-size: .78rem; line-height: 1.5; color: var(--muted);
}
.slot-brief b { color: var(--text); font-weight: 700; }
