/* =============================================================================
   CROSSTENSOR — COMPOSANTS DE PRODUCTION
   Généré à partir de ct-ui/ct-ui.css (design-system/), namespace .ct-ui retiré :
   tous les sélecteurs sont globaux, prêts à charger tels quels sur le site.
   Nécessite tokens.css (voir design-system/tokens.css) chargé avant ce fichier.

   Le reset ci-dessous (§02) est désormais global — ce fichier n'est plus
   pensé pour coexister avec un autre design system sur la même page.
   ========================================================================== */

/* =============================================================================
   Ordre du fichier :
     02. Reset (global)
     03. Layout & conteneurs
     04. Typographie
     05. Éléments de base (boutons, liens, badges, listes)
     06. Blocs
     07. Utilitaires
     09. Patte graphique (deck ressources graphiques)
     10. Composants repris du design system site
     11. Couche éditoriale (article-template)
     12. Fonds signature, icônes, cartes à CTA, liens fléchés
     14. Alignement des composants similaires côte à côte
     15. Rythme interne des composants
     16. Aperçu produit d'en-tête
     17. Comparatif avant / après
     18. Réassurance détaillée
     19. Blocs 47–56
     08. Accessibilité, motion, print
   (Numérotation conservée telle quelle depuis ct-ui.css pour rester traçable.
   La section 13, Thème sombre, est passée dans tokens.css — ce ne sont que
   des redéfinitions de tokens.)
   ========================================================================== */

/* =============================================================================
   02. RESET — désormais global (le fichier n'a plus besoin de coexister
   avec un autre design system sur la même page). Reprend intégralement
   l'ancien css/reset.css (retiré de la publication, voir ECARTS.md) : ce
   fichier ne pouvait rester incomplet en supposant qu'un autre reset le
   complèterait en silence.
   ========================================================================== */
*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  font-family: var(--ct-font-family);
  font-size: var(--ct-font-size-base);
  line-height: var(--ct-line-height-base);
  color: var(--ct-color-text);
  background-color: var(--ct-color-bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
fieldset { border: none; }

/* docs/regles/accessibilite.md garantit déjà scroll-behavior: auto sous
   prefers-reduced-motion — cette règle globale n'existait nulle part
   avant (ni ici, ni dans l'ancienne CSS historique) : ajoutée pour que la
   documentation et le code se rejoignent enfin sur ce point précis. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd {
  margin: 0;
}
ul, ol { margin: 0; padding: 0; }
img, svg, video { max-width: 100%; height: auto; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
table { border-collapse: collapse; width: 100%; }

/* =============================================================================
   03. LAYOUT & CONTENEURS
   ========================================================================== */
.ct-container {
  width: 100%;
  max-width: var(--ct-container-max);
  margin-inline: auto;
  padding-inline: var(--ct-container-pad);
}
.ct-container--narrow { max-width: var(--ct-container-narrow); }

/* Lien d'évitement (skip-link) — présent en tête de chaque page, porté ici
   plutôt que dans la CSS historique (retirée du site, voir ECARTS.md) :
   c'est le seul composant du bundle historique qui chargeait sur 100% des
   pages plutôt que sur un sous-ensemble. */
.skip-link {
  position: absolute;
  top: -100%;
  left: var(--ct-space-md);
  padding: var(--ct-space-xs) var(--ct-space-md);
  background-color: var(--ct-color-secondary);
  color: var(--ct-color-on-secondary);
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-bold);
  border-radius: var(--ct-radius-md);
  z-index: 9999;
  text-decoration: none;
  transition: top var(--ct-transition-fast);
}
.skip-link:focus { top: var(--ct-space-md); }

.ct-section { padding-block: var(--ct-space-xxl); }
.ct-section--tight { padding-block: var(--ct-space-xl); }
.ct-section--alt { background-color: var(--ct-color-bg-alt); }
/* .ct-section--dark : voir section 13 (scope de theme sombre). */

.ct-section__header { max-width: 720px; margin-bottom: var(--ct-space-xl); }
.ct-section__header--center { margin-inline: auto; text-align: center; }

.ct-grid { display: grid; gap: var(--ct-space-lg); }
.ct-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ct-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ct-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 1024px) {
  .ct-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 768px) {
  .ct-grid--2,
  .ct-grid--3,
  .ct-grid--4 { grid-template-columns: minmax(0, 1fr); }
  .ct-section { padding-block: var(--ct-space-xl); }
}

/* =============================================================================
   04. TYPOGRAPHIE
   ========================================================================== */
.ct-title-hero,
.ct-title-section,
.ct-title-card,
.ct-title-sub {
  font-weight: var(--ct-font-weight-bold);
  color: inherit;
}
.ct-title-hero {
  font-size: clamp(30px, 5vw, var(--ct-font-size-xxl));
  line-height: var(--ct-line-height-tight);
  letter-spacing: var(--ct-tracking-tight);
}
.ct-title-section {
  font-size: clamp(23px, 3.4vw, var(--ct-font-size-xl));
  line-height: var(--ct-line-height-snug);
  letter-spacing: var(--ct-tracking-tight);
}
.ct-title-card { font-size: 22px; line-height: var(--ct-line-height-snug); }
.ct-title-sub { font-size: 18px; line-height: var(--ct-line-height-snug); }

.ct-lead {
  font-size: var(--ct-font-size-lg);
  line-height: var(--ct-line-height-relaxed);
  color: var(--ct-color-text-light);
}
.ct-text { font-size: var(--ct-font-size-base); line-height: var(--ct-line-height-relaxed); }
.ct-text--sm { font-size: var(--ct-font-size-sm); }
.ct-text--muted { color: var(--ct-color-text-light); }

/* .ct-eyebrow : defini en section 09 (patte graphique du deck). */

/* Surfaces sombres — `.ct-section--dark`, `.ct-hero` et `.ct-cta-primary`
   partagent les mêmes inversions. Sans cela l'eyebrow reste en bleu foncé
   sur le navy (2,3:1) : échec de contraste. */
.ct-section--dark .ct-lead,
.ct-hero .ct-lead,
.ct-cta-primary .ct-lead,
.ct-section--dark .ct-text--muted,
.ct-hero .ct-text--muted,
.ct-cta-primary .ct-text--muted { color: var(--ct-color-text-on-dark-muted); }


/* Paragraphes en flux dans un bloc de prose */
.ct-prose > p + p { margin-top: var(--ct-space-md); }
.ct-prose > h3 { margin-top: var(--ct-space-xl); margin-bottom: var(--ct-space-sm); }

/* =============================================================================
   05. ÉLÉMENTS DE BASE
   ========================================================================== */

/* ---- Liens ---- */
.ct-link {
  color: var(--ct-color-secondary-aaa);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--ct-transition-fast);
}
.ct-link:hover { color: var(--ct-color-primary); }
.ct-section--dark .ct-link,
.ct-hero .ct-link,
.ct-cta-primary .ct-link { color: var(--ct-color-accent-green); }

/* ---- Boutons ----
   Un seul bouton à fort poids visuel par écran : `.ct-btn--primary`.
   `.ct-btn--secondary` et `.ct-btn--ghost` pour tout le reste. */
.ct-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ct-space-sm);
  padding: 12px 24px;
  border: 1px solid transparent;
  border-radius: var(--ct-radius-md);
  font-size: var(--ct-font-size-base);
  font-weight: var(--ct-font-weight-medium);
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--ct-transition-base),
              border-color var(--ct-transition-base),
              color var(--ct-transition-base),
              transform var(--ct-transition-fast);
}
.ct-btn--primary {
  background-color: var(--ct-color-secondary);
  border-color: var(--ct-color-secondary);
  color: var(--ct-color-on-secondary);
  margin-top: var(--ct-space-sm);
  margin-bottom: var(--ct-space-sm);
}
/* Exception : le bouton primaire du menu (navbar) ne doit jamais porter
   cette marge — hauteur de la barre de navigation déjà fixée, alignement
   avec le reste du .ct-btn-group. height: 44px (hauteur fixe, pas un
   plancher) posé ici hors media query, donc à toute largeur, pour égaler
   celle déjà posée sur .ct-btn--secondary du menu (même règle, voir plus
   bas) — un simple min-height ne suffisait pas : le padding/line-height
   naturels du primaire sur desktop (46px) dépassaient déjà le plancher de
   44px, les deux boutons n'étaient donc pas systématiquement à la même
   hauteur (signalé directement, 2026-09-18, ex. iPhone 12 Pro/390px, où
   le mobile forçait déjà les deux à 44px mais pas le desktop). */
.ct-navbar .ct-btn-group .ct-btn--primary {
  margin-top: 0;
  margin-bottom: 0;
  height: 44px;
}
.ct-btn--primary:hover {
  background-color: var(--ct-color-secondary-hover);
  border-color: var(--ct-color-secondary-hover);
}
.ct-btn--secondary {
  background-color: var(--ct-color-bg-alt);
  border-color: var(--ct-color-border-strong);
  color: var(--ct-color-primary);
}
.ct-btn--secondary:hover {
  background-color: var(--ct-color-surface-hover);
  border-color: var(--ct-color-primary);
}
.ct-btn--ghost {
  background-color: transparent;
  border-color: transparent;
  color: var(--ct-color-secondary-aaa);
  text-decoration: underline;
  text-underline-offset: 3px;
  padding-inline: var(--ct-space-sm);
}
.ct-btn--ghost:hover { color: var(--ct-color-primary); }

/* Variante bordée du ghost : sur fond sombre, un simple souligné se perd. Le
   filet à 15 % de blanc donne au CTA secondaire une assise sans le faire
   concurrencer le CTA primaire. */
.ct-btn--ghost.ct-btn--outline {
  border-color: rgba(255, 255, 255, 0.15);
  text-decoration: none;
  padding-inline: var(--ct-space-md);
}
.ct-btn--ghost.ct-btn--outline:hover,
.ct-btn--ghost.ct-btn--outline:focus-visible { border-color: rgba(255, 255, 255, 0.35); }

/* La flèche avance de 3px au survol : le mouvement est porté par un élément
   dédié, jamais par le bouton entier, pour ne pas décaler le libellé. */
.ct-btn__arrow {
  display: inline-block;
  margin-left: 8px;
  transition: transform var(--ct-transition-fast, 150ms) ease;
}
.ct-btn:hover .ct-btn__arrow,
.ct-btn:focus-visible .ct-btn__arrow { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .ct-btn__arrow { transition: none; }
  .ct-btn:hover .ct-btn__arrow { transform: none; }
  .ct-card--offer:hover .ct-btn__arrow,
  .ct-card--offer:focus-within .ct-btn__arrow { transform: none; }
}
.ct-section--dark .ct-btn--ghost,
.ct-hero .ct-btn--ghost,
.ct-cta-primary .ct-btn--ghost { color: var(--ct-color-text-on-dark); }
.ct-section--dark .ct-btn--ghost:hover,
.ct-hero .ct-btn--ghost:hover,
.ct-cta-primary .ct-btn--ghost:hover { color: var(--ct-color-accent-green); }
.ct-section--dark .ct-btn--secondary,
.ct-hero .ct-btn--secondary,
.ct-cta-primary .ct-btn--secondary {
  background-color: transparent;
  border-color: var(--ct-color-border-on-dark);
  color: var(--ct-color-text-on-dark);
}
.ct-section--dark .ct-btn--secondary:hover,
.ct-hero .ct-btn--secondary:hover,
.ct-cta-primary .ct-btn--secondary:hover {
  background-color: var(--ct-color-surface-hover-on-dark);
  border-color: var(--ct-color-text-on-dark);
}
.ct-btn:active { transform: translateY(1px); }
.ct-btn--block { width: 100%; }
.ct-btn[aria-disabled='true'] { opacity: 0.5; pointer-events: none; }

.ct-btn-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ct-space-md);
  align-items: center;
}

/* ---- Badges ---- Point de couleur + libellé court. */
.ct-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-pill);
  background-color: var(--ct-color-bg-alt);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-text);
  white-space: nowrap;
}
.ct-badge::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--ct-color-text-light);
  flex-shrink: 0;
}
.ct-badge--ok::before { background-color: var(--ct-color-accent-green); }
.ct-badge--warn::before { background-color: var(--ct-color-accent-orange); }
.ct-badge--blocked::before { background-color: var(--ct-color-accent-red); }
.ct-badge--info::before { background-color: var(--ct-color-secondary); }

/* ---- Cartes ---- */
.ct-card {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  box-shadow: var(--ct-shadow-xs);
  padding: var(--ct-space-lg);
}
.ct-card__icon {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-secondary-soft);
  color: var(--ct-color-secondary-aaa);
  margin-bottom: var(--ct-space-md);
}
.ct-card__title { margin-bottom: var(--ct-space-sm); }
.ct-card__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }

/* ---- Listes ---- */
.ct-list { list-style: none; display: flex; flex-direction: column; gap: var(--ct-space-sm); }
.ct-list__item {
  position: relative;
  padding-left: 28px;
  line-height: var(--ct-line-height-relaxed);
}
.ct-list__item::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--ct-color-accent-green);
}
.ct-list--risk .ct-list__item::before { background-color: var(--ct-color-accent-red); }
.ct-list--neutral .ct-list__item::before { background-color: var(--ct-color-text-light); }

/* ---- Figures ---- */
.ct-figure { margin: 0; }
.ct-figure__media {
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  overflow: hidden;
  background-color: var(--ct-color-bg-alt);
}
.ct-figure figcaption {
  margin-top: var(--ct-space-sm);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
}

/* =============================================================================
   06. BLOCS
   ========================================================================== */

/* ---- 01. ct-hero ---------------------------------------------------------- */
.ct-hero {
  color: var(--ct-color-text-on-dark);
  padding-block: var(--ct-space-xxl);
  /* fond : voir section 12 (surface signature) */
}
/* Variante resserrée : même fond signature, hauteur réduite — pour un hero
   qui n'a pas besoin de porter autant de contenu (ex. page Tarifs). */
.ct-hero--tight { padding-block: var(--ct-space-xl); }
/* Deux colonnes : promesse et actions à gauche, aperçu KPI à droite.
   La colonne droite est la plus large — le widget porte trois cartes. */
.ct-hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);
  gap: var(--ct-space-xl);
  align-items: center;
}
.ct-hero__title { margin-bottom: var(--ct-space-md); }
.ct-hero__subtitle {
  font-size: var(--ct-font-size-lg);
  line-height: var(--ct-line-height-relaxed);
  color: var(--ct-color-text-on-dark-muted);
  margin-bottom: var(--ct-space-xl);
  max-width: 56ch;
}
.ct-hero__actions { margin-bottom: var(--ct-space-md); }
.ct-hero__note { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-on-dark-muted); }
/* Logos fournisseurs dans la hero note (demande directe, 2026-09-08) :
   groupe traité comme une seule image (role="img" + aria-label composite)
   plutôt que quatre logos aria-hidden isolés — plus fiable pour un lecteur
   d'écran qu'une suite de title="" par <svg>. Couleurs de marque
   conservées telles quelles (fill explicite par logo), sauf OpenAI dont le
   tracé source est déjà en currentColor : c'est la convention réelle de
   cette marque (logo monochrome), pas une incohérence. */
.ct-hero__logos {
  display: inline-flex;
  align-items: center;
  gap: var(--ct-space-sm);
  margin-right: var(--ct-space-sm);
  vertical-align: -4px;
}
.ct-hero__logo { display: block; flex-shrink: 0; }
/* Sous 1200px, la colonne droite devient trop étroite pour trois colonnes de
   KPI lisibles : le hero s'empile et le widget reprend toute la largeur. */
@media (max-width: 1200px) {
  .ct-hero__inner { grid-template-columns: minmax(0, 1fr); }
  .ct-hero__aside { order: 2; margin-top: var(--ct-space-lg); }
}

/* Carte de score — indice de maîtrise IA */
.ct-score {
  background-color: var(--ct-color-bg-alt);
  border-radius: var(--ct-radius-lg);
  padding: var(--ct-space-lg);
  box-shadow: var(--ct-shadow-md);
  color: var(--ct-color-text);
  max-width: 320px;
}
.ct-score__ring { display: block; margin-inline: auto; }
.ct-score__value {
  font-size: var(--ct-font-size-xxl);
  font-weight: var(--ct-font-weight-bold);
  line-height: 1;
  text-align: center;
}
.ct-score__label {
  text-align: center;
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
  margin-top: var(--ct-space-xs);
}
.ct-score__insight {
  margin-top: var(--ct-space-md);
  padding: var(--ct-space-sm) var(--ct-space-md);
  background-color: var(--ct-color-green-soft);
  border-radius: var(--ct-radius-sm);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-accent-green-aaa);
}

/* ---- 02. ct-toc (Sommaire) ------------------------------------------------ */
/* .ct-toc : defini en section 12 (liens fleches facon .card__link). */

/* ---- 03. ct-meta ---------------------------------------------------------- */
.ct-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ct-space-md);
  align-items: center;
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
  padding-block: var(--ct-space-md);
  border-block: 1px solid var(--ct-color-border);
}
.ct-meta__item { display: inline-flex; align-items: center; gap: 6px; }
.ct-meta__term { font-weight: var(--ct-font-weight-medium); color: var(--ct-color-text); }

/* ---- 04. ct-quick-answer (Réponse rapide) --------------------------------- */
.ct-quick-answer {
  background-color: var(--ct-color-secondary-soft);
  border-left: 4px solid var(--ct-color-secondary);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
}
.ct-quick-answer__title {
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-secondary-aaa);
  margin-bottom: var(--ct-space-sm);
}
.ct-quick-answer__text { font-size: var(--ct-font-size-lg); line-height: var(--ct-line-height-relaxed); }

/* ---- 05. ct-mini-answer --------------------------------------------------- */
.ct-mini-answer {
  border-left: 3px solid var(--ct-color-border-strong);
  padding-left: var(--ct-space-md);
  color: var(--ct-color-text-light);
  font-size: var(--ct-font-size-sm);
  line-height: var(--ct-line-height-relaxed);
}
.ct-mini-answer__term { font-weight: var(--ct-font-weight-bold); color: var(--ct-color-text); }

/* ---- 06. ct-problem ------------------------------------------------------- */
.ct-problem__intro { margin-bottom: var(--ct-space-xl); }
.ct-problem__item {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-top: 3px solid var(--ct-color-accent-red);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
}
.ct-problem__title { margin-bottom: var(--ct-space-sm); }
.ct-problem__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }

/* ---- 07/08. ct-scenarios (Shadow AI / finance) ---------------------------- */
.ct-scenarios__list { list-style: none; display: grid; gap: var(--ct-space-lg); }
@media (min-width: 768px) {
  .ct-scenarios__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.ct-scenario {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
  height: 100%;
}
.ct-scenario__who {
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-text);
  margin-bottom: var(--ct-space-xs);
}
.ct-scenario__gesture { line-height: var(--ct-line-height-relaxed); margin-bottom: var(--ct-space-md); }
.ct-scenario__risk {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-accent-red-ink);
}
.ct-scenarios--finance .ct-scenario { border-top: 3px solid var(--ct-color-accent-orange); }
.ct-scenarios--finance .ct-scenario__risk { color: var(--ct-color-accent-orange-ink); }
.ct-scenarios--shadow-ai .ct-scenario { border-top: 3px solid var(--ct-color-accent-red); }

/* ---- 09. ct-benefits ------------------------------------------------------ */
.ct-benefit-card {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  box-shadow: var(--ct-shadow-xs);
  padding: var(--ct-space-lg);
  height: 100%;
}
.ct-benefit-card__icon {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-green-soft);
  color: var(--ct-color-accent-green-aaa);
  margin-bottom: var(--ct-space-md);
}
.ct-benefit-card__title { margin-bottom: var(--ct-space-sm); }
.ct-benefit-card__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
.ct-benefit-card__outcome {
  display: block;
  margin-top: var(--ct-space-sm);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-text);
}

/* ---- 10. ct-proofs -------------------------------------------------------- */
.ct-proof {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--ct-space-md);
}
.ct-proof__quote { font-size: var(--ct-font-size-lg); line-height: var(--ct-line-height-relaxed); }
.ct-proof__author { display: flex; flex-direction: column; gap: 2px; margin-top: auto; }
.ct-proof__name { font-weight: var(--ct-font-weight-bold); }
.ct-proof__role { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); }
.ct-proof__figures {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ct-space-xl);
  padding-top: var(--ct-space-md);
  border-top: 1px solid var(--ct-color-border);
}
.ct-proof__figure-value {
  font-size: var(--ct-font-size-xl);
  font-weight: var(--ct-font-weight-bold);
  line-height: 1;
  color: var(--ct-color-secondary-aaa);
}
.ct-proof__figure-label { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); margin-top: var(--ct-space-xs); }

/* ---- 11. ct-reassurance --------------------------------------------------- */
.ct-reassurance {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
}
.ct-reassurance__list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--ct-space-md);
  margin-bottom: var(--ct-space-md);
}
.ct-reassurance__note { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); }

/* ---- 12/13/14. ct-module (Toolbox / Gateway / Guard) ---------------------- */
.ct-module {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--ct-space-xl);
  align-items: center;
}
.ct-module--reverse .ct-module__media { order: -1; }
@media (max-width: 1024px) {
  .ct-module { grid-template-columns: minmax(0, 1fr); }
  .ct-module--reverse .ct-module__media { order: 0; }
}
.ct-module__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--ct-space-sm);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  margin-bottom: var(--ct-space-sm);
}
.ct-module__title { margin-bottom: var(--ct-space-md); }
.ct-module__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); margin-bottom: var(--ct-space-md); }
.ct-module--toolbox .ct-module__eyebrow { color: var(--ct-color-secondary-aaa); }
.ct-module--gateway .ct-module__eyebrow { color: var(--ct-color-accent-green-aaa); }
.ct-module--guard .ct-module__eyebrow { color: var(--ct-color-accent-orange-ink); }

/* ---- 15. ct-flow-schema (Schéma point de passage) ------------------------- */
.ct-flow-schema__figure { margin: 0; }
.ct-flow-schema__svg { width: 100%; height: auto; display: block; }
.ct-flow-schema__legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--ct-space-lg);
  margin-top: var(--ct-space-md);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
}
.ct-flow-schema__legend-item { display: inline-flex; align-items: center; gap: var(--ct-space-sm); }
.ct-flow-schema__swatch { width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; }

/* ---- 16. ct-pricing ------------------------------------------------------- */
.ct-pricing__grid { display: grid; gap: var(--ct-space-lg); grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1024px) { .ct-pricing__grid { grid-template-columns: minmax(0, 1fr); } }
.ct-plan {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-lg);
  padding: var(--ct-space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--ct-space-md);
}
/* L'offre mise en avant garde une bordure de 1px : une bordure plus épaisse
   décalerait son contenu d'un pixel et casserait l'alignement avec les autres
   offres. L'épaisseur apparente vient d'un anneau interne, sans géométrie. */
.ct-plan--featured {
  border-color: var(--ct-color-secondary);
  box-shadow: inset 0 0 0 1px var(--ct-color-secondary);
}
.ct-plan__name { font-size: var(--ct-font-size-lg); font-weight: var(--ct-font-weight-bold); }
.ct-plan__target { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); }
.ct-plan__price { font-size: var(--ct-font-size-xxl); font-weight: var(--ct-font-weight-bold); line-height: 1; }
.ct-plan__period { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); }
.ct-plan__cta { margin-top: auto; }

/* ---- 16bis. ct-pricing-configurator ---------------------------------------
   Curseur d'abonnement continu. `--ct-cfg-fill` est posée en JS sur l'input
   (pourcentage de remplissage du track) : c'est la seule valeur que le
   script écrit sur `style`, faute d'équivalent déclaratif pour un
   <input type="range"> natif. Le reste du composant ne lit que des tokens. */
.ct-pricing-configurator {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-lg);
  box-shadow: var(--ct-shadow-md);
  max-width: 720px;
  margin-inline: auto;
  padding: var(--ct-space-xl) var(--ct-space-lg) var(--ct-space-lg);
}

.ct-pricing-configurator__row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--ct-space-sm);
  margin-bottom: var(--ct-space-lg);
}
.ct-pricing-configurator__price {
  font-size: clamp(32px, 6vw, var(--ct-font-size-xxl));
  font-weight: var(--ct-font-weight-bold);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.ct-pricing-configurator__price small { font-size: var(--ct-font-size-lg); font-weight: var(--ct-font-weight-medium); color: var(--ct-color-text-light); }
.ct-pricing-configurator__credits-col { display: flex; flex-direction: column; align-items: flex-end; gap: var(--ct-space-sm); }
.ct-pricing-configurator__credits {
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-secondary-aaa);
  background-color: var(--ct-color-secondary-soft);
  padding: 4px 12px;
  border-radius: var(--ct-radius-pill);
  font-variant-numeric: tabular-nums;
}
.ct-pricing-configurator__bonus {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-accent-green-aaa);
  background-color: var(--ct-color-green-soft);
  padding: 5px 12px;
  border-radius: var(--ct-radius-pill);
  font-variant-numeric: tabular-nums;
}
.ct-pricing-configurator__bonus[hidden] { display: none; }
.ct-pricing-configurator__bonus .ct-icon { color: currentColor; }

.ct-pricing-configurator__reco { font-size: var(--ct-font-size-base); color: var(--ct-color-text-light); margin-bottom: 4px; }
.ct-pricing-configurator__reco strong { color: var(--ct-color-text); font-weight: var(--ct-font-weight-medium); }
.ct-pricing-configurator__reco-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--ct-color-accent-green);
  margin-right: var(--ct-space-sm);
  vertical-align: middle;
}
.ct-pricing-configurator__reco-note {
  font-size: var(--ct-font-size-xs);
  color: var(--ct-color-text-light);
  margin-bottom: var(--ct-space-lg);
  padding-left: var(--ct-space-md);
}

.ct-pricing-configurator__slider-wrap { position: relative; margin-bottom: var(--ct-space-sm); }
.ct-pricing-configurator__slider {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  height: 8px;
  border-radius: var(--ct-radius-pill);
  background: linear-gradient(to right,
    var(--ct-color-secondary) 0%, var(--ct-color-secondary) var(--ct-cfg-fill, 0%),
    var(--ct-color-border) var(--ct-cfg-fill, 0%), var(--ct-color-border) 100%);
  outline: none;
  cursor: pointer;
}
.ct-pricing-configurator__slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-color: var(--ct-color-bg-alt);
  border: 3px solid var(--ct-color-secondary);
  box-shadow: var(--ct-shadow-sm);
  cursor: grab;
  transition: transform var(--ct-transition-fast);
}
.ct-pricing-configurator__slider::-webkit-slider-thumb:hover { transform: scale(1.08); }
.ct-pricing-configurator__slider::-moz-range-thumb {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-color: var(--ct-color-bg-alt);
  border: 3px solid var(--ct-color-secondary);
  box-shadow: var(--ct-shadow-sm);
  cursor: grab;
}

.ct-pricing-configurator__scale {
  display: flex;
  justify-content: space-between;
  font-size: var(--ct-font-size-xs);
  color: var(--ct-color-text-light);
  margin-bottom: var(--ct-space-lg);
  font-variant-numeric: tabular-nums;
}

.ct-pricing-configurator__contact {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  background-color: var(--ct-color-surface-dark);
  color: var(--ct-color-text-on-dark);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
  font-size: var(--ct-font-size-sm);
  margin-bottom: var(--ct-space-lg);
  flex-wrap: wrap;
}
.ct-pricing-configurator__contact[hidden] { display: none; }
.ct-pricing-configurator__contact a {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--ct-color-accent-green);
  font-weight: var(--ct-font-weight-medium);
  text-decoration: none;
  white-space: nowrap;
}
.ct-pricing-configurator__contact a:hover { text-decoration: underline; }

.ct-pricing-configurator__actions {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--ct-space-lg);
  border-top: 1px solid var(--ct-color-border);
  padding-top: var(--ct-space-lg);
}
.ct-pricing-configurator__cta-col { display: flex; flex-direction: column; align-items: center; gap: var(--ct-space-sm); }
.ct-pricing-configurator__cta-note { font-size: var(--ct-font-size-xs); color: var(--ct-color-text-light); text-align: center; }
.ct-pricing-configurator__note {
  flex: 1;
  min-width: 220px;
  font-size: var(--ct-font-size-xs);
  color: var(--ct-color-text-light);
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
}
.ct-pricing-configurator__note .ct-icon { flex-shrink: 0; color: var(--ct-color-text-light); }

@media (max-width: 620px) {
  .ct-pricing-configurator { padding: var(--ct-space-lg) var(--ct-space-md); }
  .ct-pricing-configurator__actions { flex-direction: column; }

  /* Retour sur les tours précédents (n°160-161, puis la tentative
     « même ligne que le prix » ci-dessus) : signalé directement,
     2026-09-21, que le texte était devenu trop petit pour caler les
     pastilles à côté du prix. Priorité désormais donnée à la lisibilité
     et à la stabilité de la position plutôt qu'au partage de la ligne 1 :
     - Tailles de texte ramenées à des valeurs du système de tokens
       (docs/03-design-system.md), jamais en dessous de
       --ct-font-size-xs (12px, déjà le plus petit texte utilisé
       ailleurs sur le site, ex. .ct-pricing-configurator__reco-note) —
       « cohérent par rapport au reste de la page ». Pastilles crédits et
       bonus alignées sur la MÊME taille (12px) l'une que l'autre —
       « cohérent au sein du slider » — au lieu de deux tailles
       différentes comme avant.
     - flex-basis: 100% rétabli (mécanisme du n°161) : force
       systématiquement credits-col sur sa propre ligne, quelle que soit
       la largeur du nombre de crédits affiché — position fixe (toujours
       la 2ᵉ ligne du bloc, juste sous le prix), jamais de saut visible en
       déplaçant le curseur ou en changeant de profil, conforme à
       « chaque élément doit rester à sa place ». align-items: flex-end
       (déjà posé sur credits-col, hors media query) aligne les pastilles
       à droite de cette ligne pleine largeur.
     - min-height posé sur credits-col, réservée pour LA PLUS HAUTE des
       deux configurations (crédits seuls, sous 100 €, vs crédits + bonus
       au-delà) : sans ça, le badge bonus qui apparaît/disparaît selon le
       prix (CONFIG.bonusAbovePrice) change la hauteur de cette ligne, ce
       qui décale verticalement tout ce qui suit (repère de recommandation,
       curseur, échelle...) en déplaçant simplement le curseur — exactement
       le décalage que « prévoir la position avec les données les plus
       hautes » demande d'éliminer. Valeur calculée pour 2 pastilles
       empilées à cette taille de police (marge de sécurité incluse). */
  .ct-pricing-configurator__credits-col {
    flex-basis: 100%;
    min-height: 60px;
    /* Alignées à gauche sur mobile (demande directe, 2026-09-21) —
       remplace align-items: flex-end (droite, hérité de la règle hors
       media query ci-dessus, pensé pour le placement à côté du prix sur
       desktop). Sous le prix plutôt qu'à côté (flex-basis: 100% ci-
       dessus, déjà en place), les pastilles suivent désormais le même
       bord gauche que le prix et le sélecteur mensuel/annuel juste
       au-dessus, plutôt que de rester collées à droite de la carte. */
    align-items: flex-start;
  }
  .ct-pricing-configurator__credits {
    font-size: var(--ct-font-size-xs);
    padding: 4px 10px;
  }
  .ct-pricing-configurator__bonus {
    font-size: var(--ct-font-size-xs);
    padding: 4px 10px;
  }
  /* Prix ramené à une taille plus modérée (remplaçait
     clamp(28px, 8vw, var(--ct-font-size-xl)), 28-40px) — reste le plus
     grand texte de la carte (hiérarchie visuelle conservée) sans
     dominer excessivement sur les plus petits écrans. */
  .ct-pricing-configurator__price { font-size: clamp(24px, 7vw, 28px); }
  .ct-pricing-configurator__price small { font-size: var(--ct-font-size-sm); }
}

/* ---- 17. ct-credits-table (Comparatif crédits) ---------------------------- */
.ct-credits-table__scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.ct-credits-table__table { min-width: 560px; font-size: var(--ct-font-size-sm); }
.ct-credits-table__table caption {
  caption-side: top;
  text-align: left;
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
  padding-bottom: var(--ct-space-sm);
}
.ct-credits-table__table th,
.ct-credits-table__table td {
  padding: var(--ct-space-sm) var(--ct-space-md);
  border: 1px solid var(--ct-color-border);
  text-align: left;
}
.ct-credits-table__table thead th {
  background-color: var(--ct-color-bg);
  font-weight: var(--ct-font-weight-bold);
}
.ct-credits-table__table tbody th { font-weight: var(--ct-font-weight-medium); }

/* ---- 18. ct-persona-problems --------------------------------------------- */
.ct-persona-problems__list { list-style: none; display: grid; gap: var(--ct-space-md); }
.ct-persona-problem {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-left: 4px solid var(--ct-color-accent-red);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
}
.ct-persona-problem__title { font-weight: var(--ct-font-weight-bold); margin-bottom: var(--ct-space-xs); }
.ct-persona-problem__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }

/* ---- 19. ct-persona-solutions -------------------------------------------- */
.ct-persona-solutions__list { list-style: none; display: grid; gap: var(--ct-space-md); }
.ct-persona-solution {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-left: 4px solid var(--ct-color-accent-green);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
}
.ct-persona-solution__title { font-weight: var(--ct-font-weight-bold); margin-bottom: var(--ct-space-xs); }
.ct-persona-solution__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
.ct-persona-solution__outcome {
  display: block;
  margin-top: var(--ct-space-sm);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-accent-green-aaa);
}

/* ---- 20. ct-faq ----------------------------------------------------------
   Implémenté avec <details>/<summary> : natif, accessible au clavier,
   sans JavaScript, et le texte reste dans le DOM et visible par défaut
   (attribut `open`) — exigence SEO « pas de texte caché ».             */
.ct-faq__list { display: flex; flex-direction: column; gap: var(--ct-space-md); }
/* Renvoi vers la FAQ complète, en bas de chaque bloc FAQ de page (hors la
   page /faq/ elle-même) — 2026-09-13, demande directe. */
.ct-faq__more { margin-top: var(--ct-space-lg); text-align: center; color: var(--ct-color-text-light); }
.ct-faq__item {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
}
.ct-faq__question {
  font-size: var(--ct-font-size-lg);
  font-weight: var(--ct-font-weight-bold);
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--ct-space-md);
}
.ct-faq__question::-webkit-details-marker { display: none; }
.ct-faq__question::after {
  content: '';
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  margin-top: 8px;
  border-right: 2px solid var(--ct-color-secondary-aaa);
  border-bottom: 2px solid var(--ct-color-secondary-aaa);
  transform: rotate(45deg);
  transition: transform var(--ct-transition-base);
}
.ct-faq__item[open] .ct-faq__question::after { transform: rotate(-135deg); }
.ct-faq__answer {
  margin-top: var(--ct-space-md);
  color: var(--ct-color-text-light);
  line-height: var(--ct-line-height-relaxed);
}
.ct-faq__answer > p + p { margin-top: var(--ct-space-md); }

/* ---- 21. ct-cta-primary --------------------------------------------------- */
.ct-cta-primary {
  color: var(--ct-color-text-on-dark);
  border-radius: var(--ct-radius-lg);
  padding: var(--ct-space-xxl) var(--ct-space-xl);
  text-align: center;
  /* Carte détachée des bords de page et des sections voisines (le
     border-radius n'a de sens que si le bloc ne touche ni les côtés ni
     le haut/bas) : même gouttière horizontale que .ct-container, plus
     une marge verticale propre au lieu d'un bandeau plein largeur collé
     aux sections adjacentes. */
  width: calc(100% - (var(--ct-container-pad) * 2));
  max-width: var(--ct-container-max);
  margin: var(--ct-space-xl) auto;
  /* fond : voir section 12 (surface signature) */
}
.ct-cta-primary__title { margin-bottom: var(--ct-space-md); }
.ct-cta-primary__text {
  color: var(--ct-color-text-on-dark-muted);
  max-width: 56ch;
  margin-inline: auto;
  margin-bottom: var(--ct-space-xl);
  line-height: var(--ct-line-height-relaxed);
}
.ct-cta-primary__actions { justify-content: center; }
.ct-cta-primary__note {
  margin-top: var(--ct-space-md);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-on-dark-muted);
}

/* ---- 22. ct-cta-ghost ----------------------------------------------------- */
.ct-cta-ghost {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--ct-space-md);
  padding: var(--ct-space-lg);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-bg-alt);
}
.ct-cta-ghost__text { color: var(--ct-color-text-light); }

/* =============================================================================
   07. UTILITAIRES
   ========================================================================== */
.ct-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.ct-skip-link {
  position: absolute;
  top: -100%;
  left: var(--ct-space-md);
  z-index: 999;
  padding: var(--ct-space-sm) var(--ct-space-md);
  background-color: var(--ct-color-secondary);
  color: var(--ct-color-bg-alt);
  border-radius: var(--ct-radius-sm);
  text-decoration: none;
}
.ct-skip-link:focus { top: var(--ct-space-md); }

.ct-stack > * + * { margin-top: var(--ct-space-md); }
.ct-stack--lg > * + * { margin-top: var(--ct-space-lg); }
.ct-text-center { text-align: center; }

/* =============================================================================
   09. PATTE GRAPHIQUE — extraite de Crosstensor_ressources_graphiques.pptx
   -----------------------------------------------------------------------------
   Les gestes visuels du deck sont exprimés avec les tokens existants, jamais
   avec de nouvelles couleurs de marque : le système reste mono-palette et
   bascule d'un bloc sur la palette de marque via l'override du §0.1 de la
   documentation. Seuls les neutres froids et le halo sont ajoutés ici.
   ========================================================================== */

/* ---- Eyebrow : filet + capitales très espacées ----------------------------
   Geste signature du deck. Le filet est généré en CSS : ne pas écrire le
   tiret dans le HTML. Le libellé s'écrit en minuscules, la capitalisation
   est faite ici — si la casse est retirée un jour, le texte reste correct. */
.ct-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.28em;
  color: var(--ct-color-accent-green-aaa);
  margin-bottom: var(--ct-space-sm);
}
.ct-eyebrow::before {
  content: '';
  width: 1.4em;
  height: 2px;
  background-color: currentColor;
  border-radius: 2px;
  flex-shrink: 0;
}
.ct-section--dark .ct-eyebrow,
.ct-hero .ct-eyebrow,
.ct-cta-primary .ct-eyebrow { color: var(--ct-color-accent-green); }

/* ---- Surbrillance de titre ------------------------------------------------
   Le titre est d'une seule couleur SAUF le segment qui porte la promesse.
   Un seul segment par titre. Jamais cumulé avec du gras ou un soulignement. */
.ct-title__hl { color: var(--ct-color-secondary-aaa); }
.ct-theme-dark .ct-title__hl,
.ct-section--dark .ct-title__hl,
.ct-hero .ct-title__hl,
.ct-cta-primary .ct-title__hl { color: var(--ct-color-accent-green); }

/* ---- Halo sur les surfaces sombres ---------------------------------------- */
.ct-hero--glow,
.ct-section--glow,
.ct-cta-primary--glow { position: relative; isolation: isolate; overflow: hidden; }
.ct-hero--glow::before,
.ct-section--glow::before,
.ct-cta-primary--glow::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--ct-glow);
  pointer-events: none;
}

/* ---- Dégradé signature ---------------------------------------------------- */
.ct-gradient-text {
  background-image: linear-gradient(135deg, var(--ct-color-secondary) 0%, var(--ct-color-accent-green) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.ct-gradient-bar {
  width: 48px;
  height: 3px;
  border-radius: var(--ct-radius-pill);
  background-image: linear-gradient(90deg, var(--ct-color-secondary), var(--ct-color-accent-green));
  margin-bottom: var(--ct-space-md);
}
@media print {
  .ct-gradient-text { color: var(--ct-color-secondary-aaa); background-image: none; }
}

/* ---- Tag : pastille outline compacte -------------------------------------- */
.ct-tag {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-pill);
  background-color: var(--ct-color-bg-alt);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-secondary-aaa);
  white-space: nowrap;
}
.ct-tag--mono { font-family: var(--ct-font-family-mono); text-transform: lowercase; }
.ct-tag--neutral { color: var(--ct-color-text-light); }
.ct-tag-list { list-style: none; display: flex; flex-wrap: wrap; gap: var(--ct-space-sm); }
.ct-section--dark .ct-tag,
.ct-hero .ct-tag {
  background-color: transparent;
  border-color: var(--ct-color-border-on-dark);
  color: var(--ct-color-text-on-dark-muted);
}

/* ---- Node : pastille de schéma -------------------------------------------- */
.ct-node {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  padding: 10px var(--ct-space-md);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-bg-alt);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text);
  box-shadow: var(--ct-shadow-xs);
}
.ct-node__icon { color: var(--ct-color-secondary-aaa); flex-shrink: 0; display: flex; }
/* Logo de marque dans un nœud : les tracés portent déjà leur propre
   couleur (ou currentColor pour un logo mono comme OpenAI) — neutralise
   la teinte bleue par défaut pour ne jamais altérer un logo réel. */
.ct-node__icon--brand { color: var(--ct-color-text); }
.ct-node-list { list-style: none; display: flex; flex-direction: column; gap: var(--ct-space-sm); }
.ct-node-group__label {
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-text-light);
  margin-bottom: var(--ct-space-sm);
}

/* ---- Légende de schéma ---------------------------------------------------- */
.ct-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--ct-space-lg);
  margin-top: var(--ct-space-md);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
}
.ct-legend__item { display: inline-flex; align-items: center; gap: var(--ct-space-sm); }
.ct-legend__line { width: 28px; height: 0; border-top: 2px solid var(--ct-color-secondary); flex-shrink: 0; }
.ct-legend__line--dashed { border-top-style: dashed; border-top-color: var(--ct-color-accent-green); }

/* ---- 23 · ct-hub — schéma du point de passage ----------------------------- */
/* Cinq colonnes : entrée · connecteur · cœur · connecteur · sortie */
.ct-hub__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(40px, 6vw, 90px) minmax(0, 1.25fr) clamp(40px, 6vw, 90px) minmax(0, 1fr);
  align-items: center;
  gap: var(--ct-space-sm);
}
.ct-hub__link { align-self: stretch; display: flex; align-items: center; min-width: 0; }
.ct-hub__link svg { width: 100%; height: 240px; display: block; }
.ct-hub__core {
  background-color: var(--ct-color-surface-dark);
  color: var(--ct-color-text-on-dark);
  border-radius: var(--ct-radius-lg);
  padding: var(--ct-space-lg);
}
.ct-hub__brand {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  font-weight: var(--ct-font-weight-bold);
  letter-spacing: var(--ct-tracking-caps);
  text-transform: uppercase;
  font-size: var(--ct-font-size-sm);
  padding-bottom: var(--ct-space-md);
  border-bottom: 1px solid var(--ct-color-border-on-dark);
  margin-bottom: var(--ct-space-md);
}
.ct-hub__row { display: grid; gap: var(--ct-space-xs); padding-block: var(--ct-space-md); }
.ct-hub__row + .ct-hub__row { border-top: 1px solid var(--ct-color-border-on-dark); }
.ct-hub__row-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--ct-space-sm); }
.ct-hub__name { font-size: var(--ct-font-size-lg); font-weight: var(--ct-font-weight-bold); }
.ct-hub__for {
  font-size: var(--ct-font-size-xs);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-accent-green);
}
.ct-hub__desc { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-on-dark-muted); line-height: var(--ct-line-height-relaxed); }
.ct-hub__icon { color: var(--ct-color-accent-green); display: flex; flex-shrink: 0; }
.ct-hub__caption {
  text-align: center;
  margin-top: var(--ct-space-lg);
  font-weight: var(--ct-font-weight-medium);
}
@media (max-width: 1024px) {
  .ct-hub:not(.ct-hub--ecosystem) .ct-hub__inner { grid-template-columns: minmax(0, 1fr); }
  .ct-hub:not(.ct-hub--ecosystem) .ct-hub__link { display: none; }        /* connecteurs décoratifs */
  .ct-hub:not(.ct-hub--ecosystem) .ct-hub__core { order: -1; }
}

/* ---- 24 · ct-hub — variante « écosystème », fidèle au schéma de référence --
   Trois colonnes (équipes/outils · cœur Crosstensor · IA du marché) avec
   plusieurs groupes empilés par colonne. Reste en 3 colonnes à toute
   largeur (jamais empilée) : sur petit écran, .ct-hub__scroll défile
   horizontalement dans son propre conteneur plutôt que de casser la
   disposition gauche/centre/droite qui porte le sens du schéma. */
.ct-hub--ecosystem .ct-hub__scroll {
  overflow-x: auto;
  padding-bottom: var(--ct-space-sm);
}
.ct-hub--ecosystem .ct-hub__inner {
  grid-template-columns: 280px 56px minmax(300px, 1fr) 56px 280px;
  align-items: stretch;
}
.ct-hub--ecosystem .ct-hub__link svg { width: 100%; height: 32px; }

.ct-hub__col { display: flex; flex-direction: column; gap: var(--ct-space-lg); min-width: 0; }

.ct-node-list--grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ct-space-xs); }
.ct-node--compact { padding: 8px var(--ct-space-sm); font-size: var(--ct-font-size-xs); gap: 6px; }
.ct-node--compact .ct-node__icon svg { width: 14px; height: 14px; }

.ct-hub__feature-card {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--ct-space-md);
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md);
  box-shadow: var(--ct-shadow-xs);
}
.ct-hub__feature { display: flex; gap: var(--ct-space-sm); align-items: flex-start; }
.ct-hub__feature-icon { color: var(--ct-color-accent-green-ink); flex-shrink: 0; display: flex; margin-top: 2px; }
.ct-hub__feature-title { font-size: var(--ct-font-size-sm); font-weight: var(--ct-font-weight-bold); color: var(--ct-color-text); }
.ct-hub__feature-text { font-size: var(--ct-font-size-xs); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }

.ct-hub__badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--ct-radius-pill);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  white-space: nowrap;
}
.ct-hub__badge--top {
  background-color: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--ct-color-border-on-dark);
  color: var(--ct-color-accent-green);
}
.ct-hub__badge--row {
  background-color: rgba(255, 255, 255, 0.06);
  color: var(--ct-color-text-on-dark-muted);
  margin-left: auto;
}

.ct-hub--ecosystem .ct-hub__brand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--ct-space-sm);
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--ct-font-size-base);
}
.ct-hub__brand-name { display: inline-flex; align-items: center; gap: var(--ct-space-sm); }

.ct-hub__market-card {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md);
  box-shadow: var(--ct-shadow-xs);
}
.ct-hub__market-title { font-size: var(--ct-font-size-sm); font-weight: var(--ct-font-weight-bold); color: var(--ct-color-text); margin-bottom: var(--ct-space-xs); }
.ct-hub__brand-row { list-style: none; display: flex; flex-wrap: wrap; gap: var(--ct-space-sm); margin-bottom: var(--ct-space-xs); }
.ct-hub__brand-row li { display: flex; }
.ct-hub__market-text { font-size: var(--ct-font-size-xs); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }

.ct-hub__highlight-card {
  background-color: var(--ct-color-green-soft);
  border: 1px solid rgba(0, 200, 150, 0.25);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md);
}
.ct-hub__highlight-title {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-accent-green-ink);
  margin-bottom: var(--ct-space-sm);
}
.ct-hub__highlight-list { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.ct-hub__highlight-list li {
  position: relative;
  padding-left: var(--ct-space-md);
  font-size: var(--ct-font-size-xs);
  color: var(--ct-color-text);
  line-height: var(--ct-line-height-relaxed);
}
.ct-hub__highlight-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: var(--ct-color-accent-green-ink);
}

.ct-hub__caption-hl { color: var(--ct-color-accent-green-ink); }

/* ---- 24 · ct-split — comparaison deux colonnes clair / sombre -------------- */
.ct-split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 900px) { .ct-split { grid-template-columns: minmax(0, 1fr); } }
.ct-split__panel { padding: var(--ct-space-xl); }
.ct-split__panel--light { background-color: var(--ct-color-bg-alt); }
.ct-split__panel--dark {
  background-color: var(--ct-color-surface-dark);
  color: var(--ct-color-text-on-dark);
}
.ct-split__head {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  font-size: var(--ct-font-size-lg);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-secondary-aaa);
  margin-bottom: var(--ct-space-lg);
}
.ct-split__panel--dark .ct-split__head { color: var(--ct-color-accent-green); }
.ct-split__claims { list-style: none; margin-bottom: var(--ct-space-lg); }
.ct-split__claim {
  padding-block: var(--ct-space-sm);
  border-bottom: 1px solid var(--ct-color-line-cool);
  font-weight: var(--ct-font-weight-medium);
}
.ct-split__panel--dark .ct-split__claim { border-bottom-color: var(--ct-color-border-on-dark); }
.ct-split__label {
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-secondary-aaa);
  margin-bottom: var(--ct-space-sm);
}
.ct-split__panel--dark .ct-split__label { color: var(--ct-color-text-on-dark-muted); }
.ct-split__cases { list-style: none; display: flex; flex-direction: column; gap: var(--ct-space-sm); }
.ct-split__case {
  background-color: var(--ct-color-bg);
  border-left: 3px solid var(--ct-color-secondary);
  border-radius: var(--ct-radius-sm);
  padding: var(--ct-space-sm) var(--ct-space-md);
}
.ct-split__panel--dark .ct-split__case {
  background-color: rgba(255, 255, 255, 0.06);
  border-left-color: var(--ct-color-accent-green);
}
.ct-split__who {
  display: block;
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ct-color-secondary-aaa);
  margin-bottom: var(--ct-space-xs);
}
.ct-split__panel--dark .ct-split__who { color: var(--ct-color-accent-green); }
.ct-split__gesture { font-size: var(--ct-font-size-sm); line-height: var(--ct-line-height-relaxed); }
.ct-split__panel--dark .ct-split__gesture { color: var(--ct-color-text-on-dark); }
.ct-split__foot {
  margin-top: var(--ct-space-lg);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
}
.ct-split__panel--dark .ct-split__foot { color: var(--ct-color-text-on-dark-muted); }

/* ---- 25 · ct-showcase — capture au-dessus d'une carte --------------------- */
.ct-showcase { display: grid; gap: var(--ct-space-lg); grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1024px) { .ct-showcase { grid-template-columns: minmax(0, 1fr); } }
.ct-showcase__item { display: flex; flex-direction: column; gap: var(--ct-space-md); }
.ct-showcase__shot {
  margin: 0;
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  overflow: hidden;
  background-color: var(--ct-color-bg-alt);
  box-shadow: var(--ct-shadow-sm);
}
.ct-showcase__card {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--ct-space-sm);
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
}
.ct-showcase__icon { color: var(--ct-color-secondary-aaa); display: flex; }
.ct-showcase__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
.ct-showcase__tags { margin-top: auto; padding-top: var(--ct-space-sm); }


/* =============================================================================
   10. COMPOSANTS REPRIS DU DESIGN SYSTEM SITE (guide développeur v3)
   ========================================================================== */

/* ---- 26 · ct-stats — bandeau de chiffres ---------------------------------- */
.ct-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background-color: var(--ct-color-line-cool);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-lg);
  overflow: hidden;
}
@media (max-width: 768px) { .ct-stats { grid-template-columns: minmax(0, 1fr); } }
.ct-stat { background-color: var(--ct-color-bg-alt); padding: var(--ct-space-xl) var(--ct-space-lg); text-align: center; }
.ct-stat__value {
  font-size: var(--ct-font-size-xxl);
  font-weight: var(--ct-font-weight-bold);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ct-color-secondary-aaa);
  margin-bottom: var(--ct-space-sm);
}
.ct-stat__label { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
.ct-stat__source { display: block; margin-top: var(--ct-space-xs); font-size: var(--ct-font-size-xs); color: var(--ct-color-text-light); }

/* ---- 27 · ct-alert — message sémantique ----------------------------------- */
.ct-alert {
  display: flex;
  gap: var(--ct-space-md);
  align-items: flex-start;
  padding: var(--ct-space-md) var(--ct-space-lg);
  border: 1px solid;
  border-radius: var(--ct-radius-md);
  font-size: var(--ct-font-size-sm);
  line-height: var(--ct-line-height-relaxed);
}
.ct-alert__icon { flex-shrink: 0; display: flex; margin-top: 2px; }
.ct-alert--info    { background-color: var(--ct-color-secondary-soft); border-color: rgba(74, 90, 255, 0.25); color: var(--ct-color-secondary-aaa); }
.ct-alert--success { background-color: var(--ct-color-green-soft);     border-color: rgba(0, 200, 150, 0.35); color: var(--ct-color-accent-green-aaa); }
.ct-alert--warning { background-color: var(--ct-color-orange-soft);    border-color: rgba(255, 138, 0, 0.40); color: var(--ct-color-accent-orange-ink); }
.ct-alert--error   { background-color: var(--ct-color-red-soft);       border-color: rgba(255, 77, 79, 0.35); color: var(--ct-color-accent-red-ink); }
.ct-alert strong { font-weight: var(--ct-font-weight-bold); }
/* .ct-alert force display:flex : sans cet override, l'attribut [hidden]
   natif (display:none, styles user-agent) est écrasé par cette règle
   d'auteur et l'alerte reste visible malgré [hidden] — même correctif
   que .ct-pricing-configurator__bonus[hidden] ci-dessus. */
.ct-alert[hidden] { display: none; }

/* ---- 28 · ct-form -------------------------------------------------------- */
.ct-form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ct-space-lg); }
@media (max-width: 640px) { .ct-form-grid { grid-template-columns: minmax(0, 1fr); } }
.ct-field { display: flex; flex-direction: column; gap: var(--ct-space-sm); }
.ct-field--full { grid-column: 1 / -1; }
.ct-label { font-size: var(--ct-font-size-sm); font-weight: var(--ct-font-weight-medium); color: var(--ct-color-text); }
.ct-label__required { color: var(--ct-color-accent-red-ink); margin-left: 2px; }
.ct-input {
  width: 100%;
  padding: 12px var(--ct-space-md);
  border: 1px solid var(--ct-color-border-strong);
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-bg-alt);
  color: var(--ct-color-text);
  font-size: var(--ct-font-size-base);
  line-height: var(--ct-line-height-base);
  transition: border-color var(--ct-transition-fast), box-shadow var(--ct-transition-fast);
}
.ct-input::placeholder { color: var(--ct-color-text-light); }
.ct-input:focus {
  outline: none;
  border-color: var(--ct-color-secondary);
  box-shadow: 0 0 0 3px rgba(74, 90, 255, 0.18);
}
textarea.ct-input { min-height: 120px; resize: vertical; }
select.ct-input { cursor: pointer; }
.ct-input[aria-invalid='true'] { border-color: var(--ct-color-accent-red-ink); }
.ct-input[disabled] { background-color: var(--ct-color-bg); color: var(--ct-color-text-light); cursor: not-allowed; }
.ct-field__hint { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); }
.ct-field__error { font-size: var(--ct-font-size-sm); color: var(--ct-color-accent-red-ink); font-weight: var(--ct-font-weight-medium); }

/* Honeypot anti-spam (contact, démo, newsletter…) : positionné hors écran
   plutôt que display:none — certains bots ignorent les champs display:none/
   visibility:hidden mais remplissent quand même ceux-ci. Repris ici en
   version .ct-ui native (déjà utilisé côté legacy css/components.css). */
.hp-field {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---- 29 · ct-navbar ------------------------------------------------------- */
.ct-navbar {
  background-color: var(--ct-color-surface-dark);
  color: var(--ct-color-text-on-dark);
  border-bottom: 1px solid var(--ct-color-border-on-dark);
}
.ct-navbar__inner {
  display: flex;
  align-items: center;
  /* Deux groupes seulement désormais (.ct-navbar__left et le
     .ct-btn-group des CTA) : un seul espace flexible entre eux, plutôt
     que trois éléments distribués — c'est ce qui rapproche la nav du
     logo (demande directe, 2026-09-09). */
  justify-content: space-between;
  gap: var(--ct-space-lg);
  min-height: 68px;
}
/* Regroupe la marque et la navigation : elles restent visuellement
   proches l'une de l'autre quelle que soit la largeur de l'écran, au
   lieu de se répartir sur toute la largeur de la barre. */
.ct-navbar__left {
  display: flex;
  align-items: center;
  gap: var(--ct-space-lg);
  min-width: 0;
}
.ct-navbar__brand {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-text-on-dark);
  text-decoration: none;
  flex-shrink: 0;
}
/* flex-wrap: nowrap (était wrap) : le menu tient toujours sur une seule
   ligne, en desktop comme en mobile (demande directe, 2026-09-30, ajout
   du 6ᵉ lien « Ressources »). Avec 6 liens, la liste repassait sur deux
   lignes entre 981 et ~1050px et faisait grandir le header (69 → 79px) ;
   le cran 981-1100px ci-dessous resserre le padding horizontal des liens
   pour que marque + 6 liens + duo CTA tiennent côte à côte dès 981px. */
.ct-navbar__list { list-style: none; display: flex; align-items: center; gap: var(--ct-space-xs); flex-wrap: nowrap; }
.ct-navbar__link {
  display: inline-block;
  padding: var(--ct-space-sm) var(--ct-space-md);
  border-radius: var(--ct-radius-sm);
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-text-on-dark-muted);
  text-decoration: none;
  transition: color var(--ct-transition-fast), background-color var(--ct-transition-fast);
}
.ct-navbar__link:hover { color: var(--ct-color-text-on-dark); background-color: rgba(255, 255, 255, 0.08); }
.ct-navbar__link[aria-current='page'] { color: var(--ct-color-accent-green); font-weight: var(--ct-font-weight-bold); }
/* Les deux CTA réutilisent .ct-btn-group (déjà utilisé partout ailleurs
   sur le site pour un groupe de boutons) plutôt qu'une classe dédiée :
   même gap, même alignement vertical que le reste du menu (hérité de
   .ct-navbar__inner { align-items: center }). */
.ct-navbar .ct-btn-group { flex-wrap: nowrap; flex-shrink: 0; }

/* « Se connecter » reste un texte simple cliquable à toute taille d'écran
   (demande directe, 2026-09-17) — jamais un bouton, sur mobile comme sur
   desktop. Remplace l'apparence par défaut de .ct-btn--secondary (fond
   blanc, bordure) dans ce contexte précis par le même traitement que
   .ct-navbar__link (couleur -on-dark-muted, léger fond au survol/focus
   plutôt qu'une bordure) ; reste le même <a>, focusable, même destination.
   Règle non conditionnelle (hors media query) : s'applique identiquement
   à toutes les largeurs. */
.ct-navbar .ct-btn-group .ct-btn--secondary {
  background-color: transparent;
  border-color: transparent;
  padding: 10px;
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-on-dark-muted);
  height: 44px;
}
.ct-navbar .ct-btn-group .ct-btn--secondary:hover,
.ct-navbar .ct-btn-group .ct-btn--secondary:focus-visible {
  background-color: rgba(255, 255, 255, 0.08);
  border-color: transparent;
  color: var(--ct-color-text-on-dark);
}

/* Desktop étroit (981-1100px) : seul le padding horizontal des liens
   change (16px → 8px, token --ct-space-sm) et l'écart marque/liste
   (24 → 16px). Hauteur des liens, taille de police, marque et duo CTA
   inchangés — le header garde ses 68px. Mesuré (Playwright) : sans ce
   cran, 6 liens à 16px de padding manquent de ~41px (FR) / ~48px (EN) à
   981px. */
@media (min-width: 981px) and (max-width: 1100px) {
  .ct-navbar__left { gap: var(--ct-space-md); }
  .ct-navbar__link { padding-inline: var(--ct-space-sm); }
}

@media (max-width: 980px) {
  /* Deux lignes fixes, demande directe du 2026-09-18 (voir ECARTS.md) :
     ligne 1 = marque à gauche, duo « Se connecter »/« Créer un compte »
     toujours groupé en haut à droite (jamais séparé l'un de l'autre, ni
     de la ligne de la marque) ; ligne 2 = liens du menu, toujours sur une
     seule ligne, jamais de repli interne (le lien EN passait auparavant
     seul sur une 3ᵉ ligne à 390px — corrigé ici).
     .ct-navbar__left passe en display:contents : marque et liste
     deviennent des enfants flex directs de .ct-navbar__inner, qui garde
     son justify-content: space-between (posé hors media query) — avec
     seulement marque + .ct-btn-group sur la ligne 1 (la liste en est
     retirée par flex-basis: 100%, voir plus bas), cela suffit à pousser
     le duo CTA à l'extrémité droite sans further réglage.
     .ct-navbar__list reçoit flex-basis: 100% : un enfant flex à largeur
     de base 100% ne tient jamais à côté d'un autre sur la même ligne (il
     réclame toute la largeur disponible), donc passe systématiquement
     seul sur sa propre ligne — mécanisme robuste, indépendant de l'ordre
     ou de la largeur exacte du reste du contenu.
     Seuil à 980px, pas 768px (--ct-breakpoint-md) : écart documenté,
     demande directe (2026-09-14, voir ECARTS.md) — historique des
     mesures (873px puis 967px) conservé dans ECARTS.md plutôt que
     répété ici à chaque révision. */
  /* column-gap resserré à 4px (défaut : --ct-space-lg, 24px) : marque +
     duo CTA doivent tenir ensemble sur la ligne 1 sur iPhone 12 Pro
     (390px) sans réduire la taille du logo/nom (demande directe,
     2026-09-18, voir ECARTS.md) — l'espace entre la marque et le duo est
     économisé en premier, avant la taille des CTA. row-gap (entre les 2
     lignes) inchangé. */
  .ct-navbar__inner { flex-wrap: wrap; gap: var(--ct-space-xs) 4px; padding-block: var(--ct-space-sm); }
  .ct-navbar__left { display: contents; }
  .ct-navbar .ct-btn-group { order: 1; }

  /* Ligne 2, toujours une seule ligne : flex-basis force son propre
     retour à la ligne (voir commentaire ci-dessus) ; flex-wrap: nowrap +
     gap et padding resserrés (au lieu de --ct-space-xs/sm/md par défaut)
     pour que les 5 liens (Produit/Tarifs/FAQ/Contact/EN) tiennent dans la
     largeur disponible à 320px sans jamais repasser sur deux lignes ni
     déborder horizontalement — mesuré et vérifié par balayage Playwright
     320-980px (voir ECARTS.md). Produit/Tarifs/FAQ/Contact groupés à
     gauche (justify-content par défaut, flex-start, plus de
     space-between qui les répartissait sur toute la largeur — demande
     directe, 2026-09-18) ; le sélecteur de langue EN/FR séparé du
     groupe et poussé à droite via margin-left: auto sur son <li>. */
  .ct-navbar__list {
    order: 2;
    flex-basis: 100%;
    flex-wrap: nowrap;
    gap: 8px;
  }
  .ct-navbar__list li:has([data-lang-switch]) { margin-left: auto; }
  .ct-navbar__link {
    padding: 6px 3px;
    font-size: 12px;
    white-space: nowrap;
  }
  /* 6 liens depuis le 2026-09-30 (Produit/Tarifs/Ressources/FAQ/Contact
     + EN/FR) : gap 10 → 8px et padding horizontal 4 → 3px pour tenir sur
     une seule ligne à 360px (débordement mesuré de 2px FR / 8px EN avant
     ce resserrement). Hauteur de ligne et taille de police inchangées. */

  /* Duo CTA resserré pour tenir sur la ligne 1 aux côtés de la marque à
     taille normale (demande directe, 2026-09-18, ex. iPhone 12 Pro,
     390px) : seule la taille des CTA change, jamais celle du logo/nom.
     height: 44px (WCAG 2.5.8 — voir docs/regles/accessibilite.md) déjà
     posé hors media query, s'applique donc toujours ici aussi malgré le
     padding réduit. */
  .ct-navbar .ct-btn-group .ct-btn--primary {
    width: auto;
    flex-shrink: 0;
    padding: 8px 8px;
    font-size: 11px;
  }
  .ct-navbar .ct-btn-group .ct-btn--secondary { padding: 8px 4px; font-size: 11px; }
}

/* Très petits écrans (< 360px, ex. 320px) : second cran pour les 6 liens
   du menu — police 12 → 11px et gap 8 → 6px, uniquement sur la ligne 2
   (liens), jamais sur la marque ni sur le duo CTA. Mesuré : à 320px les
   6 liens débordaient de 38px (FR) / 44px (EN) avec les valeurs 360px+ ;
   ce cran dégage ~50px. */
@media (max-width: 359px) {
  .ct-navbar__list { gap: 6px; }
  .ct-navbar__link { font-size: 11px; }
}

/* Le nom « Crosstensor » du logo (.ct-navbar__brand-text) reste toujours
   visible et à sa taille normale, y compris sur mobile (demande directe,
   2026-09-18 — annule le masquage sous 410px du n°151 ; la taille du
   logo/nom ne doit jamais être réduite, seule celle des CTA le peut).
   Grâce au resserrement du gap et des CTA ci-dessus, marque + duo CTA
   tiennent ensemble sur la ligne 1 dès 372px (mesuré) — couvre l'iPhone
   12 Pro (390px, cas signalé directement) et l'iPhone SE (375px). En
   dessous de 372px, sans plus de compression possible côté CTA sans
   nuire à la lisibilité/cible tactile ni toucher à la marque
   (explicitement exclu), le duo CTA retombe naturellement sur sa propre
   ligne, juste sous la marque (aucune règle forcée nécessaire :
   .ct-btn-group n'a pas de flex-basis: 100% contrairement à
   .ct-navbar__list — il reste sur la ligne 1 tant qu'il y tient, sinon
   .ct-navbar__inner { flex-wrap: wrap } le fait passer seul à la ligne
   suivante). Le duo CTA reste néanmoins toujours groupé (jamais séparé
   l'un de l'autre, `.ct-btn-group { flex-wrap: nowrap }` posé hors media
   query) et toujours aligné à droite (`justify-content: space-between`
   sur `.ct-navbar__inner`, hors media query également). */

/* ---- 29 bis · .ct-navbar--sticky — header sticky intelligent --------------
   Modificateur explicite plutôt qu'ajouté à .ct-navbar directement : limite
   le nouveau comportement aux pages qui le déclarent (prototype sur 3 pages
   avant généralisation, demande directe du 2026-09-09 — voir ECARTS.md).
   États pilotés par js/ct-sticky-header.js :
   - .is-compact : réduit le padding vertical au-delà d'un petit seuil de
     défilement (24px) — s'applique mobile ET desktop.
   - .is-hidden : masque le header par translation — desktop uniquement
     (≥768px). Sur mobile, le CTA et le menu doivent rester accessibles en
     permanence (choix produit direct) : le header ne se masque jamais,
     seul .is-compact s'y applique.
   Sans JS : .ct-navbar--sticky reste simplement collé en haut de page au
   défilement (position: sticky pur CSS), jamais compact ni masqué — état
   par défaut correct et non dégradé, même logique que les autres
   composants JS du site (accordéons, onglets). */
/* Sélecteur composé (.ct-navbar.ct-navbar--sticky) plutôt que la seule
   classe modificateur : la règle plus bas du fichier (§ fond signature,
   « .ct-navbar { position: relative; ... } » partagée avec le hero/CTA/
   footer) a la même spécificité qu'un sélecteur à une classe et gagnerait
   par ordre de source, cassant silencieusement le sticky. Deux classes =
   spécificité plus élevée, gagne quel que soit l'ordre dans le fichier. */
.ct-navbar.ct-navbar--sticky {
  position: sticky;
  top: 0;
  z-index: 100;
  transform: translateY(0);
  transition: transform var(--ct-transition-base);
}
.ct-navbar--sticky.is-compact .ct-navbar__inner { min-height: 52px; }
@media (max-width: 768px) {
  .ct-navbar--sticky.is-compact .ct-navbar__inner { padding-block: var(--ct-space-sm); }
}
@media (min-width: 768px) {
  .ct-navbar--sticky.is-hidden { transform: translateY(-100%); }
}
.ct-navbar--sticky .ct-navbar__inner { transition: min-height var(--ct-transition-base), padding-block var(--ct-transition-base); }
@media (prefers-reduced-motion: reduce) {
  .ct-navbar--sticky,
  .ct-navbar--sticky .ct-navbar__inner { transition: none; }
}

/* ---- 30 · ct-site-footer -------------------------------------------------- */
.ct-site-footer {
  background-color: var(--ct-color-surface-dark);
  color: var(--ct-color-text-on-dark-muted);
  padding-block: var(--ct-space-xxl) var(--ct-space-lg);
}
.ct-site-footer__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) repeat(3, minmax(0, 1fr));
  gap: var(--ct-space-xl);
  padding-bottom: var(--ct-space-xl);
  border-bottom: 1px solid var(--ct-color-border-on-dark);
}
@media (max-width: 1024px) { .ct-site-footer__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .ct-site-footer__inner { grid-template-columns: minmax(0, 1fr); } }
.ct-site-footer__tagline { font-size: var(--ct-font-size-sm); line-height: var(--ct-line-height-relaxed); margin-top: var(--ct-space-md); }
.ct-site-footer__heading {
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-text-on-dark);
  margin-bottom: var(--ct-space-md);
}
.ct-site-footer__list { list-style: none; display: flex; flex-direction: column; gap: var(--ct-space-sm); }
.ct-site-footer__list a { color: var(--ct-color-text-on-dark-muted); text-decoration: none; font-size: var(--ct-font-size-sm); }
.ct-site-footer__list a:hover { color: var(--ct-color-text-on-dark); text-decoration: underline; }
.ct-site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--ct-space-md);
  padding-top: var(--ct-space-lg);
  font-size: var(--ct-font-size-xs);
}


/* =============================================================================
   11. COUCHE ÉDITORIALE — reprise de css/article-template.css
   Pour les pages Ressources, Preuves et tout contenu rédactionnel long.
   ========================================================================== */

/* ---- 31 · ct-keyfigure — chiffre sourcé ----------------------------------- */
.ct-keyfigure {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--ct-space-lg);
  background-color: var(--ct-color-surface-dark);
  border-radius: var(--ct-radius-lg);
  padding: var(--ct-space-lg) var(--ct-space-xl);
}
.ct-keyfigure__number {
  font-size: var(--ct-font-size-xxl);
  font-weight: var(--ct-font-weight-bold);
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--ct-color-accent-green);
}
.ct-keyfigure__body { flex: 1; min-width: 200px; color: var(--ct-color-text-on-dark); }
.ct-keyfigure__body p { font-size: var(--ct-font-size-sm); line-height: var(--ct-line-height-relaxed); }
.ct-keyfigure__source {
  display: block;
  margin-top: var(--ct-space-sm);
  font-size: var(--ct-font-size-xs);
  color: var(--ct-color-text-on-dark-muted);
}
.ct-keyfigure__source a { color: var(--ct-color-accent-green); }

/* ---- 32 · ct-steps — étapes numérotées ------------------------------------ */
.ct-steps { list-style: none; counter-reset: ct-step; }
.ct-steps > li { counter-increment: ct-step; position: relative; padding: 0 0 var(--ct-space-lg) 56px; }
.ct-steps > li::before {
  content: counter(ct-step);
  position: absolute;
  left: 0;
  top: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: var(--ct-color-secondary);
  color: var(--ct-color-bg-alt);
  font-weight: var(--ct-font-weight-bold);
  font-size: var(--ct-font-size-sm);
  display: flex;
  align-items: center;
  justify-content: center;
}
.ct-steps > li:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 17px;
  top: 42px;
  bottom: 4px;
  width: 2px;
  background-color: var(--ct-color-line-cool);
}
.ct-steps__title { display: block; font-weight: var(--ct-font-weight-bold); color: var(--ct-color-text); margin-bottom: var(--ct-space-xs); }
.ct-steps p { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }

/* Variante trajectoire : le connecteur passe du dégradé indigo → menthe
   plutôt que du gris neutre, pour lire la progression comme une montée
   plutôt qu'une simple liste (ex. bloc « trajectoire en 5 étapes »). */
.ct-steps--gradient > li:not(:last-child)::after {
  background: linear-gradient(to bottom, var(--ct-color-secondary), var(--ct-color-accent-green));
}

/* ---- 33 · ct-takeaway — à retenir ----------------------------------------- */
.ct-takeaway {
  background-color: var(--ct-color-green-soft);
  border: 1px solid var(--ct-color-accent-green);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
}
.ct-takeaway__title {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  font-size: var(--ct-font-size-lg);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-accent-green-aaa);
  margin-bottom: var(--ct-space-md);
}
.ct-takeaway ul { padding-left: 1.3em; }
.ct-takeaway li { font-size: var(--ct-font-size-sm); line-height: var(--ct-line-height-relaxed); margin-bottom: var(--ct-space-xs); }
.ct-takeaway li:last-child { margin-bottom: 0; }

/* ---- 34 · ct-definition — glossaire --------------------------------------- */
.ct-definition {
  background-color: var(--ct-color-bg);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
}
.ct-definition dt {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-text);
  margin-bottom: var(--ct-space-xs);
}
.ct-definition dt::before {
  content: 'DÉF.';
  font-size: 10px;
  font-weight: var(--ct-font-weight-bold);
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-secondary-aaa);
  background-color: var(--ct-color-secondary-soft);
  padding: 2px 8px;
  border-radius: var(--ct-radius-pill);
}
.ct-definition dd { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
.ct-definition dd + dt { margin-top: var(--ct-space-md); }

/* ---- 35 · ct-visual-placeholder — visuel à produire ----------------------- */
.ct-visual-placeholder {
  border: 2px dashed var(--ct-color-border-strong);
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-bg);
  padding: var(--ct-space-xxl) var(--ct-space-lg);
  text-align: center;
  color: var(--ct-color-text-light);
}
.ct-visual-placeholder svg { margin: 0 auto var(--ct-space-md); opacity: 0.6; }
.ct-visual-placeholder p { font-size: var(--ct-font-size-sm); }
.ct-visual-placeholder strong { color: var(--ct-color-text); }

/* ---- 36 · ct-mini-faq — FAQ compacte -------------------------------------- */
.ct-mini-faq {
  background-color: var(--ct-color-bg);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
}
.ct-mini-faq__title {
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-bold);
  letter-spacing: var(--ct-tracking-caps);
  text-transform: uppercase;
  color: var(--ct-color-text-light);
  margin-bottom: var(--ct-space-md);
}
.ct-mini-faq dt { font-weight: var(--ct-font-weight-medium); color: var(--ct-color-text); font-size: var(--ct-font-size-sm); }
.ct-mini-faq dt + dd { margin-top: var(--ct-space-xs); }
.ct-mini-faq dd { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
.ct-mini-faq dd + dt { margin-top: var(--ct-space-md); }

/* ---- 37 · ct-related — pour aller plus loin ------------------------------- */
.ct-related__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--ct-space-md);
  margin-top: var(--ct-space-md);
}
.ct-related__card {
  display: block;
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
  background-color: var(--ct-color-bg-alt);
  text-decoration: none;
  transition: border-color var(--ct-transition-fast), box-shadow var(--ct-transition-fast);
}
.ct-related__card:hover { border-color: var(--ct-color-secondary); box-shadow: var(--ct-shadow-md); }
.ct-related__tag {
  display: block;
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  letter-spacing: var(--ct-tracking-caps);
  text-transform: uppercase;
  color: var(--ct-color-secondary-aaa);
  margin-bottom: var(--ct-space-xs);
}
.ct-related__title { font-size: var(--ct-font-size-sm); color: var(--ct-color-text); line-height: var(--ct-line-height-snug); }

/* ---- 38 · ct-sources — références ----------------------------------------- */
.ct-sources { border-top: 1px solid var(--ct-color-line-cool); padding-top: var(--ct-space-lg); }
.ct-sources__title { font-size: var(--ct-font-size-base); font-weight: var(--ct-font-weight-bold); margin-bottom: var(--ct-space-sm); }
.ct-sources ol { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); padding-left: 1.3em; }
.ct-sources li { margin-bottom: var(--ct-space-xs); line-height: var(--ct-line-height-relaxed); }

/* ---- 39 · ct-author — signature E-E-A-T ---------------------------------- */
.ct-author {
  display: flex;
  gap: var(--ct-space-lg);
  align-items: flex-start;
  background-color: var(--ct-color-bg);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
}
.ct-author__avatar { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.ct-author__name { font-weight: var(--ct-font-weight-bold); color: var(--ct-color-text); font-size: var(--ct-font-size-sm); }
.ct-author__role { font-size: var(--ct-font-size-sm); color: var(--ct-color-secondary-aaa); font-weight: var(--ct-font-weight-medium); margin-bottom: var(--ct-space-xs); }
.ct-author__bio { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }

/* ---- 40 · ct-product-card — mini-carte produit ---------------------------- */
.ct-product-card {
  display: flex;
  align-items: center;
  gap: var(--ct-space-md);
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
  text-decoration: none;
  transition: border-color var(--ct-transition-fast), box-shadow var(--ct-transition-fast);
}
.ct-product-card:hover { border-color: var(--ct-color-secondary); box-shadow: var(--ct-shadow-md); }
.ct-product-card__icon {
  width: 44px;
  height: 44px;
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-secondary-soft);
  color: var(--ct-color-secondary-aaa);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.ct-product-card__body { flex: 1; min-width: 0; }
.ct-product-card__name { font-weight: var(--ct-font-weight-bold); color: var(--ct-color-text); font-size: var(--ct-font-size-sm); }
.ct-product-card__desc { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); margin-top: 2px; }
.ct-product-card__arrow { color: var(--ct-color-secondary-aaa); flex-shrink: 0; display: flex; }

/* ---- 41 · ct-code — bloc technique ---------------------------------------- */
.ct-code {
  background-color: var(--ct-color-surface-dark);
  border-radius: var(--ct-radius-md);
  overflow: hidden;
}
.ct-code__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ct-space-md);
  padding: var(--ct-space-sm) var(--ct-space-lg);
  background-color: rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid var(--ct-color-border-on-dark);
  font-size: var(--ct-font-size-xs);
  color: var(--ct-color-text-on-dark-muted);
  font-family: var(--ct-font-family-mono);
}
.ct-code pre {
  margin: 0;
  padding: var(--ct-space-md) var(--ct-space-lg);
  overflow-x: auto;
  font-family: var(--ct-font-family-mono);
  font-size: 13.5px;
  line-height: var(--ct-line-height-relaxed);
  color: #DCE6F5;
}
.ct-code code { font-family: inherit; }
.ct-code-inline {
  font-family: var(--ct-font-family-mono);
  font-size: 0.9em;
  background-color: var(--ct-color-secondary-soft);
  color: var(--ct-color-secondary-aaa);
  padding: 2px 6px;
  border-radius: var(--ct-radius-sm);
}


/* =============================================================================
   12. FONDS SIGNATURE, ICÔNES, CARTES À CTA, LIENS FLÉCHÉS
   Version 1.2.0
   ========================================================================== */

/* ---- Fond signature -------------------------------------------------------
   `assets/header-bg.svg` : champ navy low-poly de la charte. Utilisé sur le
   hero d'ouverture et le CTA de fin de page. Toujours doublé d'un voile en
   dégradé : sans lui, le texte passe sur des facettes claires et le contraste
   n'est plus garanti. La couleur de repli s'applique si le SVG ne charge pas. */

.ct-hero,
.ct-cta-primary,
.ct-navbar,
.ct-site-footer,
.ct-error,
.ct-section--signature {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background-color: var(--ct-color-surface-dark);
  background-image: var(--ct-surface-signature);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.ct-hero::after,
.ct-cta-primary::after,
.ct-navbar::after,
.ct-site-footer::after,
.ct-section--signature::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--ct-veil);
  pointer-events: none;
}
/* Nav et footer sont bas et larges plutôt que hauts : le voile plein
   (pensé pour un hero en portrait) les assombrirait uniformément côté
   texte sans jamais laisser voir le motif côté opposé. Un fondu doux et
   symétrique garde la texture visible aux deux bouts tout en assurant le
   contraste au centre, où vivent les liens. */
.ct-navbar::after,
.ct-site-footer::after {
  background-image: linear-gradient(90deg,
    rgba(26, 31, 54, 0.75) 0%,
    rgba(26, 31, 54, 0.35) 50%,
    rgba(26, 31, 54, 0.75) 100%);
}
/* .ct-section--signature : pose le fond signature du hero (champ low-poly +
   voile) sur une section de page — demande directe (2026-10-20), bandeau
   « Les avantages » de l'accueil. Se combine avec .ct-theme-dark pour les
   couleurs de texte ; le voile est forcé sur sa valeur de base pour rendre
   exactement comme le hero, même si le scope sombre redéfinit --ct-veil. */
.ct-section--signature {
  --ct-veil: linear-gradient(100deg,
              rgba(26, 31, 54, 0.88) 0%,
              rgba(26, 31, 54, 0.62) 45%,
              rgba(26, 31, 54, 0.10) 100%);
}
/* Le halo teal se superpose au voile, pas l'inverse. */
.ct-hero--glow::before,
.ct-cta-primary--glow::before { z-index: -1; }

/* ---- Icônes ---------------------------------------------------------------
   Toutes les icônes viennent de `assets/icons/` (Lucide, tracé 1.5,
   `currentColor`). Deux usages : `<use>` sur le sprite en production,
   SVG inline dans le catalogue pour le copier-coller. */
.ct-icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ct-icon--sm { width: 16px; height: 16px; }
.ct-icon--lg { width: 32px; height: 32px; stroke-width: 2; }

/* ---- Lien fléché ----------------------------------------------------------
   Reprise de `.card__link` du design system site : la flèche s'écarte du
   texte au survol (transition sur `gap`, pas sur `transform`). */
.ct-arrow-link {
  display: inline-flex;
  align-items: center;
  gap: var(--ct-space-xs);
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-secondary-aaa);
  text-decoration: none;
  transition: gap var(--ct-transition-base);   /* `gap` seul, comme .card__link */
}
.ct-arrow-link:hover { gap: var(--ct-space-sm); color: var(--ct-color-primary); }
.ct-arrow-link .ct-icon { width: 16px; height: 16px; }
.ct-section--dark .ct-arrow-link,
.ct-hero .ct-arrow-link,
.ct-cta-primary .ct-arrow-link { color: var(--ct-color-accent-green); }
.ct-section--dark .ct-arrow-link:hover,
.ct-hero .ct-arrow-link:hover,
.ct-cta-primary .ct-arrow-link:hover { color: var(--ct-color-text-on-dark); }
@media (prefers-reduced-motion: reduce) {
  .ct-arrow-link { transition: none; }
  .ct-arrow-link:hover { gap: var(--ct-space-xs); }
}

/* ---- Sommaire : liens fléchés, alignés sur l'identité du site ------------- */
.ct-toc {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-line-cool);
  border-left: 3px solid var(--ct-color-secondary);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
}
.ct-toc__title {
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-text-light);
  margin-bottom: var(--ct-space-md);
}
.ct-toc__title .ct-icon { width: 16px; height: 16px; }
.ct-toc__list { list-style: none; display: flex; flex-direction: column; gap: 2px; counter-reset: ct-toc; }
.ct-toc__item { counter-increment: ct-toc; }
.ct-toc__link {
  display: flex;
  align-items: center;
  gap: var(--ct-space-xs);
  padding: var(--ct-space-sm) 0;
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-secondary-aaa);
  text-decoration: none;
  border-bottom: 1px solid var(--ct-color-line-cool);
  transition: gap var(--ct-transition-base);   /* `gap` seul, comme .card__link */
}
.ct-toc__item:last-child .ct-toc__link { border-bottom: none; }
.ct-toc__link::before {
  content: counter(ct-toc, decimal-leading-zero);
  font-family: var(--ct-font-family-mono);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-text-light);
  margin-right: var(--ct-space-sm);
  flex-shrink: 0;
}
.ct-toc__link .ct-icon { width: 16px; height: 16px; margin-left: auto; }
.ct-toc__link:hover { gap: var(--ct-space-sm); color: var(--ct-color-primary); }
.ct-toc__link:hover::before { color: var(--ct-color-secondary-aaa); }
@media (prefers-reduced-motion: reduce) {
  .ct-toc__link { transition: none; }
  .ct-toc__link:hover { gap: var(--ct-space-xs); }
}

/* ---- 43 · ct-card-grid — cartes à icône et appel à l'action --------------- */
.ct-card-grid { display: grid; gap: var(--ct-space-lg); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ct-card-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1024px) { .ct-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 768px)  { .ct-card-grid, .ct-card-grid--2 { grid-template-columns: minmax(0, 1fr); } }

/* La carte est un conteneur, pas une commande : aucun état de survol.
   L'affordance appartient au bouton qu'elle contient. Un survol sur un
   élément non cliquable promet une interaction qui n'existe pas. */
.ct-card--cta {
  display: flex;
  flex-direction: column;
  gap: var(--ct-space-sm);
  height: 100%;
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  box-shadow: var(--ct-shadow-xs);
  /* Proportions réduites d'~20% (2026-09-08, demande directe) : dérivé du
     token par calc() plutôt qu'une valeur en dur, pour rester rattaché à
     l'échelle --ct-space-* — voir aussi le bloc de rythme interne §15 et
     .ct-card__icon/.ct-title-card ci-dessous, mis à l'échelle ensemble. */
  padding: calc(var(--ct-space-lg) * 0.8);
}
.ct-card--cta .ct-card__icon {
  width: calc(48px * 0.8);
  height: calc(48px * 0.8);
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-secondary-soft);
  color: var(--ct-color-secondary-aaa);
  display: grid;
  place-items: center;
  margin-bottom: calc(var(--ct-space-sm) * 0.8);
}
.ct-card--cta .ct-card__icon .ct-icon { width: calc(24px * 0.8); height: calc(24px * 0.8); }
.ct-card--cta .ct-title-card { font-size: calc(22px * 0.8); }
.ct-card--cta .ct-card__icon--green { background-color: var(--ct-color-green-soft); color: var(--ct-color-accent-green-aaa); }
.ct-card--cta .ct-card__icon--orange { background-color: var(--ct-color-orange-soft); color: var(--ct-color-accent-orange-ink); }
.ct-card--cta .ct-card__icon--red { background-color: var(--ct-color-red-soft); color: var(--ct-color-accent-red-ink); }
.ct-card__eyebrow {
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-text-light);
}
.ct-card__list { list-style: none; display: flex; flex-direction: column; gap: var(--ct-space-xs); margin-top: var(--ct-space-xs); }
.ct-card__list li {
  position: relative;
  padding-left: 22px;
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
  line-height: var(--ct-line-height-relaxed);
}
.ct-card__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: var(--ct-color-accent-green);
}
/* Le pied est poussé en bas : les CTA d'une même rangée s'alignent. */
.ct-card__footer { margin-top: auto; padding-top: var(--ct-space-md); }
.ct-card--cta .ct-btn { width: 100%; }

/* Variante média : capture en tête de carte */
.ct-card--media { padding: 0; overflow: hidden; }
.ct-card--media .ct-card__media { margin: 0; border-bottom: 1px solid var(--ct-color-line-cool); background-color: var(--ct-color-bg); }
.ct-card--media .ct-card__media img { width: 100%; height: auto; display: block; }
.ct-card--media .ct-card__inner {
  display: flex;
  flex-direction: column;
  gap: var(--ct-space-sm);
  flex: 1;
  padding: var(--ct-space-lg);
}

/* @deprecated depuis 1.3.1 — retrait en 2.0.0.
   Cette variante servait à distinguer UNE carte de ses voisines. C'est
   précisément ce qu'interdit la règle de thème : une section est claire ou
   sombre, un bloc de cartes ne panache pas. Pour mettre une carte en avant,
   utiliser la hiérarchie de boutons (un seul `--primary` par rangée) ou
   `.ct-plan--featured`. Pour une rangée sombre, poser `.ct-theme-dark` sur
   la SECTION, pas sur une carte.
   Conservée sans changement jusqu'à la 2.0.0 pour ne rien casser. */
.ct-card--cta.ct-card--dark {
  background-color: var(--ct-color-surface-dark);
  border-color: var(--ct-color-border-on-dark);
  color: var(--ct-color-text-on-dark);
}
.ct-card--dark .ct-card__text,
.ct-card--dark .ct-card__list li { color: var(--ct-color-text-on-dark-muted); }
.ct-card--dark .ct-card__eyebrow { color: var(--ct-color-accent-green); }
.ct-card--dark .ct-card__icon { background-color: rgba(255, 255, 255, 0.08); color: var(--ct-color-accent-green); }

/* ---- Variante « offer » : carte-lien cliquable sur toute sa surface ------
   Demande directe (2026-09-08), bloc « Deux points d'entrée » de la page
   d'accueil. Le CTA en pied de carte reste le SEUL <a> réel de la carte
   (nom accessible court, contenu entièrement lisible au clavier/lecteur
   d'écran dans l'ordre naturel) ; js/ct-card-link.js relaie un clic ailleurs
   sur la carte vers ce lien. La carte est donc réellement interactive au
   clic, pas une simple promesse visuelle : un survol sur le conteneur est
   ici justifié, à la différence de .ct-card--cta seule (aucun survol,
   affordance réservée au bouton) — écart documenté, voir ECARTS.md. */
.ct-card--offer {
  cursor: pointer;
  transition: border-color var(--ct-transition-fast), background-color var(--ct-transition-fast);
}
.ct-card--offer:hover,
.ct-card--offer:focus-within {
  border-color: var(--ct-color-secondary);
  background-color: var(--ct-color-secondary-soft);
}
.ct-card--offer.ct-card--offer-mint:hover,
.ct-card--offer.ct-card--offer-mint:focus-within {
  border-color: var(--ct-color-accent-green);
  background-color: var(--ct-color-green-soft);
}
.ct-card--offer > .ct-card__eyebrow { color: var(--ct-color-secondary-aaa); }
.ct-card--offer.ct-card--offer-mint > .ct-card__eyebrow { color: var(--ct-color-accent-green-aaa); }
.ct-card--offer:hover .ct-btn__arrow,
.ct-card--offer:focus-within .ct-btn__arrow { transform: translateX(3px); }

/* ---- Figures de capture applicative --------------------------------------- */
.ct-shot {
  margin: 0;
  border: 1px solid var(--ct-color-line-cool);
  border-radius: var(--ct-radius-md);
  overflow: hidden;
  background-color: var(--ct-color-bg-alt);
  box-shadow: var(--ct-shadow-sm);
}
.ct-shot img { width: 100%; height: auto; display: block; }
.ct-shot figcaption {
  padding: var(--ct-space-sm) var(--ct-space-md);
  border-top: 1px solid var(--ct-color-line-cool);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
  background-color: var(--ct-color-bg);
}


/* =============================================================================
   13. THÈMES DE BLOC — White / Grey / Dark
   -----------------------------------------------------------------------------
   Le système n'ayant aucune valeur en dur dans ses composants, une déclinaison
   de thème ne demande pas de modificateur par bloc : on redéfinit les tokens
   sémantiques sur un scope, et les 56 blocs suivent.

   Trois thèmes, un seul mécanisme (tokens redéfinis dans ct-tokens.css) :
     .ct-theme-light  White — fond blanc pur (défaut du site hors classe).
     .ct-theme-grey   Grey  — fond `#F7F8FA`, écart très ténu avec le blanc
                      (l'ancienne valeur par défaut de White) ; même palette
                      de texte/accents/boutons que White, seuls le fond et
                      les tokens qui en dépendent (bordures, texte
                      secondaire, accents-texte, survol) sont recalculés,
                      restent AA sur ce fond.
     .ct-theme-dark   Dark  — fond sombre, voir redéfinitions ci-dessous.
   Trois façons de poser n'importe lequel des trois :
     - sur un conteneur — une section, une carte, un aside ;
     - sur <body> pour la page entière ;
     - `.theme-auto` (dark uniquement) suit `prefers-color-scheme` du système.

   RÈGLE — une section est claire (White ou Grey) OU sombre, jamais les deux.
   Le thème se pose sur un conteneur de section, pas sur un enfant isolé.
   Un bloc de cartes ne mélange pas une carte d'un thème avec des cartes d'un
   autre : toutes les cartes d'une grille héritent du thème de leur section.
   Pour alterner, on enchaîne deux sections. Pour mettre une carte en avant à
   l'intérieur d'une rangée, on utilise la hiérarchie de boutons ou
   `.ct-plan--featured`, jamais un changement de thème.

   Les ajustements de blocs ci-dessous (hero, CTA, navbar, footer, code,
   score, split, stats, glow…) ciblent spécifiquement `.ct-theme-dark` /
   `.ct-section--dark` : ce sont des surfaces intrinsèquement sombres
   (`--ct-color-surface-dark`, inchangé entre White et Grey) qui n'ont besoin
   d'un traitement particulier que lorsque la page ambiante est ELLE-MÊME
   sombre (sinon le contraste hero-sur-page suffit déjà). Grey n'a donc pas
   besoin d'équivalent : comme White, il ne redéfinit que des tokens.

   Toutes les paires texte/fond ont été vérifiées : minimum 4,5:1 sur leur
   propre fond (White et Grey), la plupart au-dessus de 5:1 ou 7:1.
   ========================================================================== */


/* -----------------------------------------------------------------------------
   Ajustements des blocs dont l'apparence sombre est intrinsèque.
   Sans eux, ces blocs se confondraient avec la page en thème sombre.
   -------------------------------------------------------------------------- */

/* Hero et CTA : plus profonds que la page, liseré pour détacher le bloc. */
.ct-theme-dark .ct-hero,
.ct-theme-dark .ct-cta-primary,
.ct-theme-dark .ct-pricing-configurator__contact {
  background-color: var(--ct-color-surface-dark);
  border: 1px solid var(--ct-color-border);
}
.ct-theme-dark .ct-hero { border-inline: none; border-top: none; }

/* Cœur du schéma, chiffre clé, bloc de code : surface la plus profonde. */
.ct-theme-dark .ct-hub__core,
.ct-theme-dark .ct-flow-radial__core,
.ct-theme-dark .ct-keyfigure,
.ct-theme-dark .ct-code,
.ct-theme-dark .ct-navbar,
.ct-theme-dark .ct-site-footer {
  background-color: var(--ct-color-surface-dark);
  border: 1px solid var(--ct-color-border);
}
.ct-theme-dark .ct-navbar,
.ct-theme-dark .ct-site-footer { border-inline: none; }

/* Panneau clair d'une comparaison : redevient une surface, pas un blanc pur. */
.ct-theme-dark .ct-split__panel--light { background-color: var(--ct-color-bg-alt); }
.ct-theme-dark .ct-split__panel--dark { background-color: var(--ct-color-surface-dark); }

/* Carte sombre : sur page sombre elle s'inverse, sinon elle disparaît. */
.ct-theme-dark .ct-card--dark {
  background-color: var(--ct-color-surface-dark);
  border-color: var(--ct-color-accent-green);
}

/* Bandeau de statistiques : les filets sont dessinés par le `gap`. */
.ct-theme-dark .ct-stats { background-color: var(--ct-color-border); }

/* Captures applicatives : elles restent claires. Un léger retrait de
   luminance évite l'effet « rectangle blanc qui flotte » sur fond sombre.
   Valeur fixe : une image n'est pas cliquable, elle n'a pas d'état de survol. */
.ct-theme-dark .ct-shot img,
.ct-theme-dark .ct-card__media img,
.ct-theme-dark .ct-showcase__shot img { opacity: 0.92; }


/* Bouton principal : sur fond sombre l'aplat s'éclaircit, le texte s'assombrit. */
.ct-btn--primary { color: var(--ct-color-on-secondary, var(--ct-color-bg-alt)); }

/* Anneau de focus : le bleu foncé manque de contraste sur une page sombre. */
.ct-theme-dark a:focus-visible,
.ct-theme-dark button:focus-visible,
.ct-theme-dark summary:focus-visible,
.ct-theme-dark input:focus-visible,
.ct-theme-dark select:focus-visible,
.ct-theme-dark textarea:focus-visible { outline-color: var(--ct-color-accent-green); }

/* Champ de formulaire : le halo de focus reprend l'accent éclairci. */
.ct-theme-dark .ct-input:focus { box-shadow: 0 0 0 3px rgba(110, 123, 255, 0.30); }

/* Le score et les cartes qui portaient un blanc en dur suivent la surface. */
.ct-theme-dark .ct-score {
  background-color: var(--ct-color-bg-alt);
  color: var(--ct-color-text);
  border: 1px solid var(--ct-color-border);
}

/* En thème sombre, le halo teal est déjà porté par le fond : on l'atténue. */
.ct-theme-dark .ct-hero--glow::before,
.ct-theme-dark .ct-section--glow::before { opacity: 0.55; }


/* =============================================================================
   14. ALIGNEMENT DES COMPOSANTS SIMILAIRES CÔTE À CÔTE
   -----------------------------------------------------------------------------
   Règle : quand plusieurs composants du même type sont alignés, chacune de
   leurs parties doit se trouver au même niveau — icône, sur-titre, titre,
   description, liste, chiffre, capture, bouton.

   Mécanique : la grille parente déclare N lignes ; chaque carte les partage
   (`grid-template-rows: subgrid`) et chaque partie reçoit une ligne explicite.
   Conséquence utile : une carte à laquelle il manque une partie laisse sa
   ligne vide au lieu de décaler tout ce qui suit — l'alignement tient même
   quand les cartes n'ont pas exactement le même contenu.

   `row-gap` de la grille pilote l'espacement INTERNE des cartes (elles occupent
   toutes la même bande de lignes) ; `column-gap` reste l'espace ENTRE les
   cartes. D'où les deux valeurs distinctes.

   L'alignement ne s'applique qu'au-delà du point de rupture où la grille est
   réellement multi-colonnes : empilées, les cartes n'ont plus rien à aligner.

   Repli : sans `subgrid`, on garde la mise en page en colonne flex et
   `margin-top: auto` sur le pied — les boutons restent alignés, le reste suit
   le fil du texte.
   ========================================================================== */

@supports (grid-template-rows: subgrid) {

  /* ---- Cartes à CTA : icône · sur-titre · titre · texte · liste · pied ---- */
  @media (min-width: 769px) {
    .ct-card-grid:not(:has(> .ct-card--media)) {
      grid-template-rows: auto auto auto auto auto auto;
      row-gap: 0;
      column-gap: var(--ct-space-lg);
      align-items: start;
    }
    .ct-card-grid:not(:has(> .ct-card--media)) > .ct-card--cta {
      display: grid;
      grid-row: span 6;
      grid-template-rows: subgrid;
      height: auto;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-card-grid > .ct-card--cta > .ct-card__icon    { grid-row: 1; }
    .ct-card-grid > .ct-card--cta > .ct-card__eyebrow { grid-row: 2; }
    .ct-card-grid > .ct-card--cta > .ct-title-card    { grid-row: 3; }
    .ct-card-grid > .ct-card--cta > .ct-card__text    { grid-row: 4; }
    .ct-card-grid > .ct-card--cta > .ct-card__list    { grid-row: 5; }
    .ct-card-grid > .ct-card--cta > .ct-card__footer  { grid-row: 6; align-self: end; }
    /* Variante --offer : badge avant icône (ordre demandé), inverse de
       l'ordre partagé ci-dessus — override scopé à cette seule variante,
       la règle générale de .ct-card--cta reste inchangée sur les 14 pages
       qui la réutilisent. */
    .ct-card-grid > .ct-card--offer > .ct-card__eyebrow { grid-row: 1; }
    .ct-card-grid > .ct-card--offer > .ct-card__icon    { grid-row: 2; }
  }

  /* ---- Cartes à capture : média · sur-titre · titre · texte · pied ------- */
  @media (min-width: 769px) {
    .ct-card-grid:has(> .ct-card--media) {
      grid-template-rows: auto auto auto auto auto;
      row-gap: 0;
      column-gap: var(--ct-space-lg);
      align-items: start;
    }
    .ct-card-grid > .ct-card--media {
      display: grid;
      grid-row: span 5;
      grid-template-rows: subgrid;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-card-grid > .ct-card--media > .ct-card__media { grid-row: 1; }
    .ct-card-grid > .ct-card--media > .ct-card__inner {
      grid-row: 2 / span 4;
      display: grid;
      grid-template-rows: subgrid;
      row-gap: 0;
    }
    .ct-card--media > .ct-card__inner > .ct-card__eyebrow { grid-row: 1; }
    .ct-card--media > .ct-card__inner > .ct-title-card    { grid-row: 2; }
    .ct-card--media > .ct-card__inner > .ct-card__text    { grid-row: 3; }
    .ct-card--media > .ct-card__inner > .ct-card__footer  { grid-row: 4; align-self: end; }
    /* Les captures n'ont pas toujours le même ratio : on les cadre pour que
       le bas de l'image tombe au même niveau d'une carte à l'autre. */
    .ct-card--media > .ct-card__media img { aspect-ratio: 16 / 10; object-fit: cover; object-position: top center; }
  }

  /* ---- Cartes bénéfice : icône · titre · texte -------------------------- */
  @media (min-width: 769px) {
    .ct-grid:has(> .ct-benefit-card) {
      grid-template-rows: auto auto auto;
      row-gap: 0;
      column-gap: var(--ct-space-lg);
      align-items: start;
    }
    .ct-grid > .ct-benefit-card {
      display: grid;
      grid-row: span 3;
      grid-template-rows: subgrid;
      height: auto;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-grid > .ct-benefit-card > .ct-benefit-card__icon  { grid-row: 1; }
    .ct-grid > .ct-benefit-card > .ct-benefit-card__title { grid-row: 2; }
    .ct-grid > .ct-benefit-card > .ct-benefit-card__text  { grid-row: 3; }
  }

  /* ---- Vitrine : capture · icône · titre · texte · tags ----------------- */
  @media (min-width: 1025px) {
    .ct-showcase {
      grid-template-rows: auto auto auto auto auto;
      row-gap: 0;
      column-gap: var(--ct-space-lg);
      align-items: start;
    }
    .ct-showcase > .ct-showcase__item {
      display: grid;
      grid-row: span 5;
      grid-template-rows: subgrid;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-showcase__item > .ct-showcase__shot { grid-row: 1; }
    .ct-showcase__item > .ct-showcase__card {
      grid-row: 2 / span 4;
      display: grid;
      grid-template-rows: subgrid;
      row-gap: 0;
    }
    .ct-showcase__card > .ct-showcase__icon { grid-row: 1; }
    .ct-showcase__card > .ct-title-card     { grid-row: 2; }
    .ct-showcase__card > .ct-showcase__text { grid-row: 3; }
    .ct-showcase__card > .ct-showcase__tags { grid-row: 4; align-self: end; }
    .ct-showcase__shot img { aspect-ratio: 16 / 10; object-fit: cover; object-position: top center; }
  }

  /* ---- Offres : badge · nom · cible · prix · période · liste · action ---
     Le badge « le plus choisi » n'existe que sur une offre : sa ligne reste
     vide sur les autres, ce qui aligne quand même les noms et les prix. */
  @media (min-width: 1025px) {
    .ct-pricing__grid {
      grid-template-rows: auto auto auto auto auto auto auto;
      row-gap: 0;
      column-gap: var(--ct-space-lg);
      align-items: start;
    }
    .ct-pricing__grid > .ct-plan {
      display: grid;
      grid-row: span 7;
      grid-template-rows: subgrid;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-pricing__grid > .ct-plan > .ct-plan__badge  { grid-row: 1; }
    .ct-pricing__grid > .ct-plan > .ct-plan__name   { grid-row: 2; }
    .ct-pricing__grid > .ct-plan > .ct-plan__target { grid-row: 3; }
    .ct-pricing__grid > .ct-plan > .ct-plan__price  { grid-row: 4; }
    .ct-pricing__grid > .ct-plan > .ct-plan__period { grid-row: 5; }
    .ct-pricing__grid > .ct-plan > .ct-list         { grid-row: 6; }
    .ct-pricing__grid > .ct-plan > .ct-plan__cta    { grid-row: 7; align-self: end; }
  }

  /* ---- Preuves : en-tête · corps · signature ---------------------------- */
  @media (min-width: 769px) {
    .ct-grid:has(> .ct-proof) {
      grid-template-rows: auto 1fr auto;
      row-gap: 0;
      column-gap: var(--ct-space-lg);
      align-items: start;
    }
    .ct-grid > .ct-proof {
      display: grid;
      grid-row: span 3;
      grid-template-rows: subgrid;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-grid > .ct-proof > *                  { grid-row: 2; }
    .ct-grid > .ct-proof > :first-child       { grid-row: 1; }
    .ct-grid > .ct-proof > .ct-proof__author,
    .ct-grid > .ct-proof > .ct-proof__figures { grid-row: 3; align-self: end; }
  }

  /* ---- Scénarios : le <li> relaie la grille jusqu'à l'article ----------- */
  @media (min-width: 768px) {
    .ct-scenarios__list {
      grid-template-rows: auto 1fr auto;
      row-gap: 0;
      column-gap: var(--ct-space-lg);
      align-items: start;
    }
    .ct-scenarios__list > li {
      display: grid;
      grid-row: span 3;
      grid-template-rows: subgrid;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-scenarios__list > li > .ct-scenario {
      display: grid;
      grid-row: span 3;
      grid-template-rows: subgrid;
      height: auto;
    }
    .ct-scenario > .ct-scenario__who     { grid-row: 1; }
    .ct-scenario > .ct-scenario__gesture { grid-row: 2; }
    .ct-scenario > .ct-scenario__risk    { grid-row: 3; align-self: end; }
  }

  /* ---- Statistiques : chiffre · libellé --------------------------------- */
  @media (min-width: 769px) {
    .ct-stats { grid-template-rows: auto auto; align-items: start; }
    .ct-stats > .ct-stat {
      display: grid;
      grid-row: span 2;
      grid-template-rows: subgrid;
      row-gap: 0;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-stats > .ct-stat > .ct-stat__value { grid-row: 1; }
    .ct-stats > .ct-stat > .ct-stat__label { grid-row: 2; }
  }

  /* ---- Renvois : étiquette · titre -------------------------------------- */
  @media (min-width: 769px) {
    .ct-related__grid {
      grid-template-rows: auto auto;
      row-gap: 0;
      column-gap: var(--ct-space-md);
      align-items: start;
    }
    .ct-related__grid > .ct-related__card {
      display: grid;
      grid-row: span 2;
      grid-template-rows: subgrid;
      margin-bottom: var(--ct-space-md);
    }
    .ct-related__card > .ct-related__tag   { grid-row: 1; }
    .ct-related__card > .ct-related__title { grid-row: 2; }
  }

  /* Les listes persona sont sur une seule colonne : il n'y a rien à aligner
     latéralement. Leur rythme est porté par les marges de la section 15. */
}


/* =============================================================================
   15. RYTHME INTERNE DES COMPOSANTS
   -----------------------------------------------------------------------------
   Un espacement uniforme entre toutes les parties d'une carte se lit mal : rien
   ne dit ce qui va ensemble. L'écart doit nommer la relation.

     flow-xs  4px   deux parties d'une même unité   (sur-titre ↔ titre)
     flow-sm  8px   titre ↔ sa description
     flow-md 16px   bloc ↔ bloc                     (icône, liste, capture)
     flow-lg 24px   avant l'action                  (bouton, lien de fin)

   Les écarts sont portés par des `margin-top` sur chaque partie, jamais par le
   `gap` de la carte : avec `subgrid`, le `gap` est unique pour toutes les
   lignes et ne permet aucun rythme différencié. Les cartes sont donc en
   `gap: 0`, ce qui rend le rythme IDENTIQUE côte à côte et empilé.
   ========================================================================== */

/* ---- Cartes à CTA ---------------------------------------------------------- */
.ct-card--cta { gap: 0; }
.ct-card--cta > .ct-card__icon    { margin: 0; }
/* Rythme interne mis à l'échelle avec le reste de la carte (~20% en moins,
   voir .ct-card--cta ci-dessus) : sinon un padding/icône resserrés avec des
   écarts internes inchangés paraîtrait déséquilibré. */
.ct-card--cta > .ct-card__eyebrow { margin-top: calc(var(--ct-flow-md) * 0.8); }
.ct-card--cta > .ct-title-card    { margin-top: calc(var(--ct-flow-xs) * 0.8); }
.ct-card--cta > .ct-card__text    { margin-top: calc(var(--ct-flow-sm) * 0.8); }
.ct-card--cta > .ct-card__list    { margin-top: calc(var(--ct-flow-md) * 0.8); }
.ct-card--cta > .ct-card__footer  { margin-top: calc(var(--ct-flow-lg) * 0.8); padding-top: 0; }
/* Une carte sans sur-titre : le titre reprend l'écart du bloc précédent. */
.ct-card--cta > .ct-card__icon + .ct-title-card { margin-top: calc(var(--ct-flow-md) * 0.8); }
/* Variante --offer : badge en premier enfant (repli sans subgrid), l'icône
   reprend l'écart que portait jusqu'ici le sur-titre. */
.ct-card--offer > .ct-card__eyebrow { margin-top: 0; }
.ct-card--offer > .ct-card__icon    { margin-top: calc(var(--ct-flow-md) * 0.8); }
.ct-card__list { gap: var(--ct-flow-sm); }
.ct-card--cta .ct-card__list { gap: calc(var(--ct-flow-sm) * 0.8); }

/* ---- Cartes à capture ------------------------------------------------------ */
.ct-card--media > .ct-card__inner { gap: 0; }
.ct-card--media > .ct-card__inner > .ct-card__eyebrow { margin-top: 0; }
.ct-card--media > .ct-card__inner > .ct-title-card    { margin-top: var(--ct-flow-xs); }
.ct-card--media > .ct-card__inner > .ct-card__text    { margin-top: var(--ct-flow-sm); }
.ct-card--media > .ct-card__inner > .ct-card__footer  { margin-top: var(--ct-flow-lg); padding-top: 0; }

/* ---- Cartes bénéfice ------------------------------------------------------- */
.ct-benefit-card > .ct-benefit-card__icon  { margin: 0; }
.ct-benefit-card > .ct-benefit-card__title { margin-top: var(--ct-flow-md); margin-bottom: 0; }
.ct-benefit-card > .ct-benefit-card__text  { margin-top: var(--ct-flow-sm); }
.ct-benefit-card__outcome { margin-top: var(--ct-flow-sm); }

/* ---- Offres ---------------------------------------------------------------- */
.ct-plan { gap: 0; }
/* Le badge n'existe que sur une offre : son écart doit être porté par sa
   propre `margin-bottom`, qui alimente la hauteur de la ligne partagée. Une
   `margin-top` sur le nom ne pousserait pas la ligne, elle décalerait le nom
   à l'intérieur — et les noms ne seraient plus alignés d'une offre à l'autre.
   Règle générale : pour une partie OPTIONNELLE, l'écart va sur l'élément
   précédent, pas sur le suivant. */
.ct-plan > .ct-plan__badge  { margin: 0 0 var(--ct-flow-md); }
.ct-plan > .ct-plan__name   { margin-top: 0; margin-bottom: 0; }
.ct-plan > .ct-plan__target { margin-top: var(--ct-flow-xs); margin-bottom: 0; }
.ct-plan > .ct-plan__price  { margin-top: var(--ct-flow-md); margin-bottom: 0; }
.ct-plan > .ct-plan__period { margin-top: var(--ct-flow-xs); }
.ct-plan > .ct-list         { margin-top: var(--ct-flow-md); }
.ct-plan > .ct-plan__cta    { margin-top: var(--ct-flow-lg); }
/* Sans badge, le nom n'a pas de bloc au-dessus de lui. */

/* ---- Vitrine --------------------------------------------------------------- */
.ct-showcase__item { gap: var(--ct-flow-md); }
.ct-showcase__card { gap: 0; }
.ct-showcase__card > .ct-showcase__icon { margin: 0; }
.ct-showcase__card > .ct-title-card     { margin-top: var(--ct-flow-md); }
.ct-showcase__card > .ct-showcase__text { margin-top: var(--ct-flow-sm); }
.ct-showcase__card > .ct-showcase__tags { margin-top: var(--ct-flow-md); padding-top: 0; }

/* ---- Scénarios ------------------------------------------------------------- */
.ct-scenario > .ct-scenario__who     { margin-bottom: 0; }
.ct-scenario > .ct-scenario__gesture { margin-top: var(--ct-flow-sm); margin-bottom: 0; }
.ct-scenario > .ct-scenario__risk    { margin-top: var(--ct-flow-md); }

/* ---- Statistiques ---------------------------------------------------------- */
.ct-stat > .ct-stat__value { margin-bottom: 0; }
.ct-stat > .ct-stat__label { margin-top: var(--ct-flow-md); }
.ct-stat__source { margin-top: var(--ct-flow-sm); }

/* ---- Renvois --------------------------------------------------------------- */
.ct-related__card > .ct-related__tag   { margin-bottom: 0; }
.ct-related__card > .ct-related__title { margin-top: var(--ct-flow-xs); }

/* ---- Persona --------------------------------------------------------------- */
.ct-persona-problem > .ct-persona-problem__title,
.ct-persona-solution > .ct-persona-solution__title { margin-bottom: 0; }
.ct-persona-problem > .ct-persona-problem__text,
.ct-persona-solution > .ct-persona-solution__text { margin-top: var(--ct-flow-sm); }
.ct-persona-solution__outcome { margin-top: var(--ct-flow-sm); }

/* ---- Preuves --------------------------------------------------------------- */
.ct-proof { gap: 0; }
.ct-proof > * + * { margin-top: var(--ct-flow-md); }
.ct-proof > .ct-proof__author { margin-top: var(--ct-flow-lg); }
.ct-proof__figures { margin-top: var(--ct-flow-md); padding-top: var(--ct-flow-md); }

/* ---- En-tête de section ---------------------------------------------------- */
.ct-section__header > .ct-eyebrow { margin-bottom: var(--ct-flow-xs); }
.ct-section__header > .ct-lead    { margin-top: var(--ct-flow-sm); }

/* ---- Listes de puces : lisibilité ------------------------------------------ */
.ct-list { gap: var(--ct-flow-sm); }
.ct-card__list li,
.ct-list__item { line-height: var(--ct-line-height-relaxed); }

/* -----------------------------------------------------------------------------
   Empilées, les cartes retrouvent l'écart qui les sépare les unes des autres.
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {
  .ct-card-grid,
  .ct-grid { row-gap: var(--ct-space-lg); }
}


/* =============================================================================
   16. APERÇU PRODUIT D'EN-TÊTE - .ct-glance
   -----------------------------------------------------------------------------
   Carte unique, dense et hiérarchisée, posée dans la colonne droite du hero.
   Elle remplace l'ancien `.ct-kpi` (trois colonnes juxtaposées) qui occupait
   deux fois trop de hauteur et diluait le message de maîtrise.

   Hiérarchie : un seul chiffre héros (l'enveloppe de crédits), trois KPI de
   conformité sur une ligne, puis deux colonnes de détail. Une seule couleur
   d'accent — le violet de marque — et trois paliers d'encre pour tout le reste.

   Carte claire posée sur le hero sombre : le contraste de matière la détache
   sans lui donner de contour appuyé. Le hero étant sombre dans les deux thèmes,
   la carte reste identique en clair comme en sombre.
   ========================================================================== */
.ct-glance {
  position: relative;
  container-type: inline-size;
  container-name: ct-glance;

  /* Trois paliers d'encre, déclinés du primaire Ink. Le brief prévoyait
     1 / 0,7 / 0,5 ; les deux paliers bas sont remontés à 0,72 et 0,65 pour
     tenir le 4,5:1 sur tout texte porteur d'information (0,58 tombait à
     4,09:1). 0,62 est réservé au chrome — le libellé « Vue d'ensemble ». */
  --ct-glance-ink:      rgb(26, 31, 54);
  --ct-glance-ink-2:    rgba(26, 31, 54, 0.72);
  --ct-glance-ink-3:    rgba(26, 31, 54, 0.65);
  --ct-glance-ink-mute: rgba(26, 31, 54, 0.62);

  --ct-glance-line-soft: rgba(26, 31, 54, 0.10);
  --ct-glance-rail:      rgba(26, 31, 54, 0.10);

  /* Sur fond clair, le violet de marque tient le contraste tel quel : #4A5AFF
     donne 5,00:1 sur blanc. C'est exactement la couleur du CTA — la carte et
     le bouton parlent enfin la même langue.

     Valeur littérale et non `var(--ct-color-secondary)` : ce token s'éclaircit
     en thème sombre (#6E7BFF) alors que la carte, elle, reste blanche. Le suivre
     ferait tomber le « % » à 3,54:1. La carte fige la palette claire. */
  --ct-glance-accent: #4A5AFF;
  --ct-glance-bar:    #4A5AFF;
}

/* Halo violet diffus derrière la carte : profondeur, sans contour visible. */
.ct-glance__halo {
  position: absolute;
  inset: 12% -8% -12% -8%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(60% 60% at 50% 50%, #4A5AFF 0%, rgba(74, 90, 255, 0) 70%);
  filter: blur(120px);
  opacity: 0.45;
}

.ct-glance__card {
  /* Aplat opaque : le fond composité est déterministe, donc les contrastes
     calculables, quelle que soit la facette du SVG signature qui passe
     derrière. Le très léger dégradé creuse la carte sans la teinter. */
  background-color: #FFFFFF;
  background-image: linear-gradient(180deg, #FFFFFF 0%, #F7F8FA 100%);
  border: 1px solid rgba(26, 31, 54, 0.08);
  border-radius: 16px;
  /* Ombre longue et douce : c'est elle qui pose la carte au-dessus du hero.
     Le liseré interne haut simule la lumière rasante sur une arête. */
  box-shadow:
    0 24px 60px -20px rgba(0, 0, 0, 0.55),
    0 2px 8px -2px rgba(0, 0, 0, 0.25),
    inset 0 1px 0 rgba(255, 255, 255, 0.9);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 15px;
  font-size: 13px;
  line-height: 1.35;
  color: var(--ct-glance-ink);
}

/* ---- Zone 1 · barre d'en-tête (~32px) ------------------------------------ */
.ct-glance__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ct-space-sm);
  min-height: 32px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--ct-glance-line-soft);
}
.ct-glance__live {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-size: 11px;
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ct-glance-ink-2);
}
.ct-glance__pulse {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  background-color: var(--ct-color-accent-green);
  box-shadow: 0 0 0 0 rgba(0, 200, 150, 0.55);
  animation: ct-glance-pulse 2s ease-out infinite;
}
@keyframes ct-glance-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(0, 200, 150, 0.55); }
  70%  { box-shadow: 0 0 0 7px rgba(0, 200, 150, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 200, 150, 0); }
}
.ct-glance__scope {
  margin: 0;
  font-size: 11px;
  color: var(--ct-glance-ink-mute);
}
/* Icône remplaçant la pastille "Live" sur l'en-tête de la diapositive
   Guard : cet évènement est un scan ponctuel, pas un compteur continu. */
.ct-glance__live-icon {
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--ct-glance-accent);
}

/* ---- Zone 2 · enveloppe, l'élément héros --------------------------------- */
.ct-glance__kicker {
  margin: 0 0 6px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ct-glance-ink-3);
}
.ct-glance__gauge {
  display: flex;
  align-items: center;
  gap: 16px;
}
.ct-glance__figure {
  margin: 0;
  flex-shrink: 0;
  font-size: 40px;
  line-height: 1;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ct-glance-accent);
}
.ct-glance__unit { font-size: 22px; font-weight: 500; }

.ct-glance__gauge-body { flex: 1; min-width: 0; }

/* Piste : `div` + `role="progressbar"`. Le `<progress>` natif ne peut pas
   porter d'enfant, or il faut y placer le marqueur de seuil. */
.ct-glance__track {
  position: relative;
  height: 6px;
  border-radius: 999px;
  background-color: var(--ct-glance-rail);
  overflow: hidden;
}
.ct-glance__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background-color: var(--ct-glance-bar);
  transform-origin: left center;
  animation: ct-glance-grow 900ms 300ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes ct-glance-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Marqueur de seuil : matérialise le budget maîtrisé (80 % par défaut,
   seul seuil utilisé jusqu'ici). Généralisé par modificateur plutôt que
   dupliqué : .ct-glance__threshold--99 déplace le repère pour la
   diapositive Intégrations (seuil SLA), 2026-09-11. */
.ct-glance__threshold {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 80%;
  width: 1px;
  background-color: rgba(26, 31, 54, 0.35);
}
.ct-glance__threshold--99 { left: 99%; }
.ct-glance__hint {
  margin: 6px 0 0;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--ct-glance-ink-3);
}

/* ---- Zone 3 · trois KPI de conformité sur une ligne ---------------------- */
.ct-glance__kpis {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0;
}
.ct-glance__kpi {
  /* `column-reverse` : le libellé précède la valeur dans le DOM — un `<dl>`
     exige `dt` puis `dd` — mais le chiffre s'affiche au-dessus. */
  display: flex;
  flex-direction: column-reverse;
  gap: 2px;
  padding-inline: 12px;
}
.ct-glance__kpi:first-child { padding-left: 0; }
.ct-glance__kpi:last-child  { padding-right: 0; }
.ct-glance__kpi + .ct-glance__kpi { border-left: 1px solid var(--ct-glance-line-soft); }
.ct-glance__num {
  margin: 0;
  font-size: 20px;
  line-height: 1.15;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ct-glance-ink);
  white-space: nowrap;
}
.ct-glance__cap {
  margin: 0;
  font-size: 10.5px;
  letter-spacing: 0.03em;
  color: var(--ct-glance-ink-3);
  white-space: nowrap;
}

/* ---- Zone 4 · deux colonnes de détail ------------------------------------ */
.ct-glance__split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  padding-top: 15px;
  border-top: 1px solid var(--ct-glance-line-soft);
}
.ct-glance__col + .ct-glance__col {
  border-left: 1px solid var(--ct-glance-line-soft);
  padding-left: 18px;
}
.ct-glance__col-title {
  margin: 0 0 8px;
  font-size: 10px;
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ct-glance-ink-3);
}
.ct-glance__list { margin: 0; }
.ct-glance__row {
  /* Élément <dl> depuis la correction d'arborescence d'accessibilité
     (voir ECARTS.md) : margin:0 neutralise la marge par défaut du
     navigateur sur <dl>, absente auparavant quand c'était un <div>. */
  margin: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--ct-space-sm);
  min-height: 22px;
}
.ct-glance__name {
  margin: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  color: var(--ct-glance-ink-2);
}
.ct-glance__val {
  margin: 0;
  flex-shrink: 0;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ct-glance-ink);
}

/* Micro-barre de proportion sous chaque fournisseur. Décorative : la valeur
   chiffrée est déjà dans la ligne au-dessus. */
.ct-glance__micro {
  display: block;
  height: 3px;
  border-radius: 999px;
  background-color: var(--ct-glance-bar);
  margin-bottom: 7px;
  transform-origin: left center;
  animation: ct-glance-grow 900ms 300ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
.ct-glance__item:last-child .ct-glance__micro { margin-bottom: 0; }

/* Largeurs de barre en classes : la CSP stricte du §8 interdit
   `style=""`. Les paliers étant connus à l'avance, une classe par valeur suffit. */
.ct-w-100 { width: 100%; }
.ct-w-99 { width: 99%; }
.ct-w-64 { width: 64%; }
.ct-w-57 { width: 57%; }
.ct-w-43 { width: 43%; }
.ct-w-42 { width: 42%; }
.ct-w-38 { width: 38%; }
.ct-w-35 { width: 35%; }
.ct-w-31 { width: 31%; }
.ct-w-27 { width: 27%; }
.ct-w-22 { width: 22%; }
.ct-w-19 { width: 19%; }
.ct-w-10 { width: 10%; }
.ct-w-6  { width: 6%; }

/* Opacités dégressives : même teinte, cinq rangs de lecture (généralisé de
   trois à cinq paliers pour la liste à 5 lignes « Connecteurs par type »,
   2026-09-11 — même progression, paliers supplémentaires prolongeant la
   dégressive existante plutôt qu'une nouvelle échelle). */
.ct-glance__micro--1 { opacity: 1; }
.ct-glance__micro--2 { opacity: 0.7; }
.ct-glance__micro--3 { opacity: 0.45; }
.ct-glance__micro--4 { opacity: 0.3; }
.ct-glance__micro--5 { opacity: 0.2; }

/* ---- Entrée : fade + montée, 60ms de décalage par zone ------------------- */
.ct-glance__bar,
.ct-glance__env,
.ct-glance__kpis,
.ct-glance__split {
  animation: ct-glance-in 520ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
.ct-glance__env   { animation-delay: 60ms; }
.ct-glance__kpis  { animation-delay: 120ms; }
.ct-glance__split { animation-delay: 180ms; }
@keyframes ct-glance-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* ---- Adaptation à la largeur de la carte, pas à celle de la fenêtre ------ */
@container ct-glance (max-width: 400px) {
  .ct-glance__card { padding: 18px; font-size: 12px; }
  .ct-glance__figure { font-size: 34px; }
  .ct-glance__unit { font-size: 19px; }
  .ct-glance__num { font-size: 18px; }
  .ct-glance__cap { font-size: 10px; }
  .ct-glance__split { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .ct-glance__col + .ct-glance__col {
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--ct-glance-line-soft);
    padding-top: 14px;
  }
}
/* Repli sans `@container`. */
@supports not (container-type: inline-size) {
  @media (max-width: 560px) {
    .ct-glance__split { grid-template-columns: minmax(0, 1fr); }
    .ct-glance__col + .ct-glance__col { border-left: none; padding-left: 0; }
  }
}

/* Sous 768px, plus aucune animation en boucle : la pastille reste allumée. */
@media (max-width: 767px) {
  .ct-glance__pulse { animation: none; }
}

/* Mouvement reduit : tout s'arrête, rien ne disparaît. */
@media (prefers-reduced-motion: reduce) {
  .ct-glance__pulse,
  .ct-glance__fill,
  .ct-glance__micro,
  .ct-glance__bar,
  .ct-glance__env,
  .ct-glance__kpis,
  .ct-glance__split { animation: none; }
}

/* ---- Slider de 4 diapositives (demande directe, 2026-09-09) --------------
   Aucun bloc du catalogue ne correspond à un carrousel auto-défilant avec
   pastilles de progression — voir ECARTS.md. Construit à partir du
   vocabulaire déjà établi ci-dessus (.ct-glance__row, __list, __col…),
   étendu pour les trois nouveaux types de contenu (Guard, Multi-LLM,
   Visibilité). Le cadre (.ct-glance__card : fond, bordure, ombre, radius,
   padding) n'est pas touché — seul son contenu direct change : un h2 cadre
   toujours la carte, suivi d'un conteneur de diapositives à la place de
   l'ancien contenu unique. */
.ct-glance__slides {
  position: relative;
  /* Hauteur figée sur celle de la diapositive 1 (mesurée) : les 4
     diapositives ont un gabarit de contenu volontairement comparable,
     cette hauteur évite un redimensionnement visible de la carte au
     changement de diapositive — la consigne demande justement un cadre
     identique. */
  min-height: 336px;
}
.ct-glance__slide {
  display: flex;
  flex-direction: column;
  gap: 15px;
}
.ct-glance__slide[hidden] { display: none; }

/* ---- Pastilles de progression, sous la carte ------------------------------ */
.ct-glance__dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: var(--ct-space-md);
}
.ct-glance__dot {
  width: 24px;
  height: 8px;
  padding: 0;
  border: none;
  border-radius: var(--ct-radius-pill);
  background-color: rgba(255, 255, 255, 0.28);
  cursor: pointer;
  transition: background-color var(--ct-transition-fast);
}
.ct-glance__dot:hover { background-color: rgba(255, 255, 255, 0.45); }
.ct-glance__dot[aria-current='true'] { background-color: var(--ct-color-text-on-dark); }
.ct-glance__dot:focus-visible {
  outline: var(--ct-focus-width) solid var(--ct-color-text-on-dark);
  outline-offset: var(--ct-focus-offset);
}

/* ---- Diapositive Guard : liste de champs détectés + extrait anonymisé ----
   Redessinée pour se rapprocher de la vraie modale Guard (demande directe,
   2026-09-10, référence images/chat-modale-guard.png) : case cochée pleine
   plutôt qu'un simple coche, et valeur détectée affichée à côté du tag
   plutôt qu'un type seul. Contenu resté volontairement neutre (message de
   prise de contact) — la modale de référence illustre un cas RH/licenciement
   explicitement écarté pour ce slider (voir ECARTS.md). */
.ct-glance__check-list { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.ct-glance__check-item {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--ct-glance-ink-2);
}
.ct-glance__check-box {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 15px;
  height: 15px;
  border-radius: 4px;
  background-color: var(--ct-glance-accent);
}
.ct-glance__check-box svg {
  width: 10px;
  height: 10px;
  fill: none;
  stroke: #fff;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ct-glance__check-value {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 11px;
  color: var(--ct-glance-ink-3);
}
.ct-glance__check-count {
  flex-shrink: 0;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ct-glance-ink-3);
}
.ct-glance__snippet {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--ct-glance-ink-2);
  background-color: var(--ct-glance-rail);
  border-radius: 10px;
  padding: 12px;
}
.ct-glance__tag {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ct-glance-accent);
  background-color: rgba(74, 90, 255, 0.12);
  border-radius: 5px;
  padding: 1px 6px;
  font-variant-numeric: tabular-nums;
}

/* Pied de la diapositive Guard : compteur + deux pseudo-boutons, comme le
   pied de la vraie modale. Rendus en <span>, jamais en <button> : rien ici
   n'est réellement actionnable (aperçu illustratif), un élément au chrome
   de bouton sans action serait une fausse affordance — voir la règle de
   survol dans docs/regles/accessibilite.md (aucun cursor:pointer ici). */
.ct-glance__guard-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--ct-glance-line-soft);
}
.ct-glance__guard-footer .ct-glance__hint { margin: 0; }
.ct-glance__guard-actions { display: flex; gap: 6px; flex-shrink: 0; }
.ct-glance__guard-btn {
  display: inline-flex;
  align-items: center;
  font-size: 10.5px;
  font-weight: 600;
  padding: 5px 10px;
  border-radius: var(--ct-radius-pill);
  border: 1px solid var(--ct-glance-line-soft);
  color: var(--ct-glance-ink-2);
  white-space: nowrap;
}
.ct-glance__guard-btn--primary {
  border-color: transparent;
  background-color: var(--ct-glance-accent);
  color: #fff;
}

/* ---- Diapositive Multi-LLM : cartes de modèle ---------------------------- */
/* Fournisseur mis en avant (OpenAI) : reprend le panneau surligné de la
   vraie modale de sélection — même famille visuelle que .ct-glance__tag. */
.ct-glance__row--active {
  margin-inline: -8px;
  padding: 3px 8px;
  border-radius: 7px;
  background-color: rgba(74, 90, 255, 0.08);
}
.ct-glance__row--active .ct-glance__name { color: var(--ct-glance-accent); font-weight: 600; }
.ct-glance__models { display: flex; flex-direction: column; gap: 8px; }
.ct-glance__model {
  border: 1px solid var(--ct-glance-line-soft);
  border-radius: 10px;
  padding: 8px 10px;
}
.ct-glance__model-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-bottom: 5px; }
.ct-glance__model-price {
  flex-shrink: 0;
  font-size: 10.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ct-glance-ink-3);
}
.ct-glance__level {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ct-color-on-secondary);
  background-color: var(--ct-glance-accent);
  border-radius: 4px;
  padding: 2px 6px;
  margin-bottom: 5px;
}
.ct-glance__model-head .ct-glance__level { margin-bottom: 0; }
/* Même convention que .ct-glance__micro--1/2/3 : une seule teinte, trois
   paliers d'opacité pour distinguer les rangs sans inventer une palette. */
.ct-glance__level--2 { opacity: 0.7; }
.ct-glance__level--3 { opacity: 0.45; }
.ct-glance__model-desc { margin: 0; font-size: 11.5px; color: var(--ct-glance-ink-3); }

/* ---- Diapositive Conformité : incidents récents + badge de statut -------
   Remplace l'ancien graphique en barres (demande directe, 2026-09-10,
   référence images/dashboard-conformite.png) : la colonne « Incidents par
   équipe » réutilise telle quelle la mécanique liste + micro-barre déjà
   posée pour la diapositive 1 (.ct-glance__list/__item/__row/__micro) ;
   seule la colonne « Incidents récents » (texte + badge de statut) est
   nouvelle. Couleurs sémantiques reprises des jetons déjà calibrés AA sur
   fond blanc (docs/03-design-system.md, « accents-texte ») — la carte du
   hero est elle-même blanche, donc directement compatibles sans recalcul. */
.ct-glance__incidents { display: flex; flex-direction: column; gap: 8px; }
.ct-glance__incident { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ct-glance__incident-text {
  margin: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 11.5px;
  color: var(--ct-glance-ink-2);
}
.ct-glance__badge {
  flex-shrink: 0;
  display: inline-block;
  font-size: 9.5px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: var(--ct-radius-pill);
}
.ct-glance__badge--warn  { background-color: var(--ct-color-orange-soft);   color: var(--ct-color-accent-orange-ink); }
.ct-glance__badge--ok    { background-color: var(--ct-color-green-soft);    color: var(--ct-color-accent-green-ink); }
/* Généralisation à 4 états (diapositive Intégrations, 2026-09-11) : mêmes
   paires jeton fond doux / texte AA que .ct-alert--info et .ct-alert--error,
   pour rester sur la même palette sémantique que le reste du site plutôt
   que d'inventer de nouvelles teintes. */
.ct-glance__badge--info  { background-color: var(--ct-color-secondary-soft); color: var(--ct-color-secondary-aaa); }
.ct-glance__badge--error { background-color: var(--ct-color-red-soft);      color: var(--ct-color-accent-red-ink); }

@container ct-glance (max-width: 400px) {
  .ct-glance__slides { min-height: 392px; }
}

@media (prefers-reduced-motion: reduce) {
  .ct-glance__dot { transition: none; }
}

/* ---- Place du composant dans le hero ------------------------------------- */
/* La carte est bien plus compacte que l'ancien widget : la colonne droite peut
   être plafonnée, et le hero tient en deux colonnes dès 1024px. */
.ct-hero__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 560px); }

@media (max-width: 1023px) {
  .ct-hero__inner { grid-template-columns: minmax(0, 1fr); }
  .ct-hero__aside {
    order: 2;
    margin-top: var(--ct-space-lg);
    width: 100%;
    max-width: 560px;
    margin-inline: auto;
  }
}

/* Variante empilée : promesse pleine largeur, aperçu dessous. */
.ct-hero--stacked .ct-hero__inner { grid-template-columns: minmax(0, 1fr); }
.ct-hero--stacked .ct-hero__aside { margin-top: var(--ct-space-xl); max-width: 560px; }
.ct-hero--stacked .ct-hero__subtitle { max-width: 68ch; }

/* Cartes de bifurcation intégrées directement dans le hero (ex. /produit/) :
   même bloc 43 .ct-card-grid, simplement posé dans .ct-hero__content plutôt
   que dans sa propre section. La carte reste une île claire (fond
   --ct-color-bg-alt) sur le hero sombre : son titre et son bouton
   secondaire doivent garder les couleurs "sur fond clair", pas celles que
   .ct-hero impose à ses enfants directs pour flotter sur le fond sombre
   (texte on-dark, bouton secondaire transparent) — sans quoi titre et
   bouton deviennent blanc sur blanc, donc invisibles. */
.ct-hero__cards { margin-top: var(--ct-space-xl); }
.ct-hero__cards .ct-title-card { color: var(--ct-color-primary); }
.ct-hero__cards .ct-btn--secondary {
  background-color: var(--ct-color-bg-alt);
  border-color: var(--ct-color-border-strong);
  color: var(--ct-color-primary);
}
.ct-hero__cards .ct-btn--secondary:hover {
  background-color: var(--ct-color-surface-hover);
  border-color: var(--ct-color-primary);
}

/* Configurateur de prix intégré directement dans le hero (ex. /tarifs/) :
   même île claire que .ct-hero__cards ci-dessus. Plutôt que de traquer
   chaque sous-élément un par un (le prix affiché et le texte de la liste
   d'attente n'ont pas de couleur propre, ils hériteraient sinon du blanc
   ambiant du hero — blanc sur la carte blanche, donc invisibles), la
   couleur encre est réappliquée une fois sur le conteneur : les éléments
   qui ont déjà leur propre couleur (prix par crédits, badge bonus,
   boutons) ne sont pas affectés, seuls ceux qui héritaient du blanc
   ambiant retrouvent un texte lisible. */
.ct-hero .ct-pricing-configurator { color: var(--ct-color-text); }
.ct-hero .ct-pricing-configurator a:focus-visible,
.ct-hero .ct-pricing-configurator button:focus-visible {
  outline-color: var(--ct-color-secondary);
}
/* Bouton secondaire posé dans cette île claire (ex. déclencheur du
   configurateur guidé, /tarifs/) : même correctif que .ct-hero__cards
   .ct-btn--secondary ci-dessus — sans lui, .ct-hero lui impose ses
   couleurs "sur fond sombre" (bordure quasi transparente, texte blanc),
   invisible sur la carte blanche. */
.ct-hero .ct-pricing-configurator .ct-btn--secondary {
  background-color: var(--ct-color-bg-alt);
  border-color: var(--ct-color-border-strong);
  color: var(--ct-color-primary);
}
.ct-hero .ct-pricing-configurator .ct-btn--secondary:hover {
  background-color: var(--ct-color-surface-hover);
  border-color: var(--ct-color-primary);
}
/* Un peu plus large que le plafond par défaut (720px) : le slider est
   censé être la pièce maîtresse du hero, pas un widget secondaire. */
.ct-hero__pricing { margin-top: var(--ct-space-xl); max-width: 840px; }

/* Réassurance en 5 étapes sous le slider, dans le hero (ex. /tarifs/) :
   bloc 46 .ct-trust réutilisé tel quel (icône + titre + preuve, déjà
   pensé pour un rendu horizontal et compact). Le texte hérite du blanc
   ambiant du hero sans problème ici (pas de carte à fond clair en jeu,
   contrairement à .ct-hero__cards/.ct-hero__pricing) ; seul un léger
   panneau est ajouté à chaque item pour qu'il ressorte un peu du fond
   sombre, avec le token déjà prévu pour ce cas (survol sur fond sombre,
   ici détourné en repère visuel statique plutôt qu'un état de survol). */
.ct-hero__reassurance { margin-top: var(--ct-space-lg); }
.ct-hero__reassurance .ct-trust__grid { counter-reset: ct-reassurance-step; }
.ct-hero__reassurance .ct-trust__item {
  counter-increment: ct-reassurance-step;
  position: relative;
  background-color: var(--ct-color-surface-hover-on-dark);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md);
}
/* Numéro d'étape : sans lui, les 5 items lisent comme des badges de
   réassurance indépendants plutôt qu'une démarche qui se déroule dans le
   temps. Même traitement que le badge numéroté du bloc 33 .ct-steps
   (fond indigo, texte clair) pour rattacher visuellement cette
   réassurance à la même idée de progression. */
.ct-hero__reassurance .ct-trust__item::before {
  content: counter(ct-reassurance-step);
  position: absolute;
  top: var(--ct-space-sm);
  right: var(--ct-space-sm);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background-color: var(--ct-color-secondary);
  color: var(--ct-color-bg-alt);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
/* Variante sans numéro : items de réassurance indépendants, sans idée de
   progression/étapes (ex. Platform, Embed) — le badge numéroté n'a de
   sens que pour une démarche séquentielle comme le slider de /tarifs/. */
.ct-hero__reassurance--unnumbered .ct-trust__item::before { display: none; }


/* =============================================================================
   17. COMPARATIF AVANT / APRÈS — .ct-compare
   -----------------------------------------------------------------------------
   Deux états du MÊME sujet séparés par le temps : sans la plateforme, puis
   avec. À ne pas confondre avec `.ct-split` (§12), qui montre deux facettes
   simultanées d'un même problème et joue sur l'opposition clair / sombre.

   Ici les deux panneaux partagent la même surface : la section est claire ou
   sombre, jamais les deux. Ce qui les oppose, c'est l'accent — rouge encre
   pour l'avant, vert encre pour l'après — et l'icône de chaque item. Cette
   contrainte évite qu'un panneau paraisse « le bon » avant même d'être lu.

   Aucun panneau n'est cliquable : aucun état de survol, aucun `cursor`.
   ========================================================================== */
.ct-compare {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: var(--ct-space-lg);
  align-items: stretch;
}

/* Repère directionnel entre les deux panneaux. Purement décoratif : les
   sur-titres « Avant » et « Après » portent déjà le sens. */
.ct-compare__arrow {
  align-self: center;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-line-cool);
  color: var(--ct-color-text-light);
}
.ct-compare__arrow .ct-icon { width: 18px; height: 18px; }

@media (max-width: 900px) {
  .ct-compare { grid-template-columns: minmax(0, 1fr); }
  .ct-compare__arrow { justify-self: center; transform: rotate(90deg); }
}

/* ---- Panneau ------------------------------------------------------------- */
/* Demande directe (2026-09-08) : l'aplat de 3px en tête de panneau retiré,
   la couleur qu'il portait (rouge « avant », vert « après ») reprise sur
   la bordure du panneau plutôt qu'un élément décoratif séparé. */
.ct-compare__panel {
  position: relative;
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-compare-accent, var(--ct-color-line-cool));
  border-radius: var(--ct-radius-lg);
  /* Proportions réduites d'~20% (2026-09-08, demande directe), même
     principe que .ct-card--cta : calc() sur le token plutôt qu'une valeur
     en dur. Titre, icônes et rythme interne mis à l'échelle ensemble
     ci-dessous ; le texte courant des items ne change pas. */
  padding: calc(var(--ct-space-lg) * 0.8);
  overflow: hidden;
}
.ct-compare__panel--before { --ct-compare-accent: var(--ct-color-accent-red-ink); }
.ct-compare__panel--after  { --ct-compare-accent: var(--ct-color-accent-green-aaa); }

.ct-compare__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--ct-space-xs);
  margin: 0 0 calc(var(--ct-flow-sm) * 0.8);
  padding-top: var(--ct-space-xs);
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-compare-accent);
}
.ct-compare__title {
  margin: 0 0 calc(var(--ct-flow-md) * 0.8);
  font-size: calc(var(--ct-font-size-lg) * 0.8);
  line-height: var(--ct-line-height-snug);
  color: var(--ct-color-text);
}

/* ---- Liste d'items ------------------------------------------------------- */
.ct-compare__list { list-style: none; margin: 0; padding: 0; }
.ct-compare__item {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--ct-space-sm) * 0.8);
  color: var(--ct-color-text-light);
  line-height: var(--ct-line-height-base);
}
.ct-compare__item + .ct-compare__item { margin-top: calc(var(--ct-flow-md) * 0.8); }
.ct-compare__item .ct-icon {
  width: calc(18px * 0.8);
  height: calc(18px * 0.8);
  flex-shrink: 0;
  /* aligne l'icône sur la première ligne de texte, pas sur le bloc entier
     — offset calé sur la ligne de texte (inchangée), pas sur l'icône. */
  margin-top: 3px;
  color: var(--ct-compare-accent);
}

/* ---- Conclusion du panneau ----------------------------------------------- */
.ct-compare__outcome {
  margin: calc(var(--ct-flow-lg) * 0.8) 0 0;
  padding-top: calc(var(--ct-flow-md) * 0.8);
  border-top: 1px solid var(--ct-color-line-cool);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-text);
  line-height: var(--ct-line-height-snug);
}

/* ---- Alignement des deux panneaux (cf. §14) ------------------------------ */
/* Sur-titre, titre, liste et conclusion se répondent d'un panneau à l'autre,
   même quand les listes n'ont pas le même nombre d'items. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 901px) {
    .ct-compare {
      grid-template-rows: auto auto 1fr auto;
      row-gap: 0;
    }
    .ct-compare__panel {
      display: grid;
      grid-row: span 4;
      grid-template-rows: subgrid;
    }
    /* Colonnes explicites : la flèche s'étend sur toutes les lignes, ce qui
       désactive le placement automatique des panneaux. Sans ces trois règles,
       elle se loge dans la première colonne et déséquilibre le bloc. */
    .ct-compare__panel--before { grid-column: 1; }
    .ct-compare__arrow         { grid-column: 2; grid-row: 1 / -1; }
    .ct-compare__panel--after  { grid-column: 3; }
    .ct-compare__badge   { grid-row: 1; }
    .ct-compare__title   { grid-row: 2; }
    .ct-compare__list    { grid-row: 3; }
    .ct-compare__outcome { grid-row: 4; align-self: end; }
  }
}


/* =============================================================================
   18. RÉASSURANCE DÉTAILLÉE — .ct-trust
   -----------------------------------------------------------------------------
   Bandeau de signaux de confiance : une icône, un engagement, une phrase qui
   le rend vérifiable. Complète `.ct-reassurance` (§06) sans la remplacer :
   celle-ci aligne des badges en pied de page, celle-là développe chaque
   engagement et peut donc se placer sous un hero ou avant un CTA.

   Un signal qui ne peut pas être étayé n'a rien à faire ici : la phrase de
   dessous est la preuve, pas un habillage.

   Aucun item n'est cliquable — sauf le lien de la note, qui l'est vraiment.
   ========================================================================== */
.ct-trust__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--ct-space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* Variante à 5 colonnes : mêmes items, un cinquième engagement sur la même
   ligne plutôt qu'un repli isolé en dessous. */
.ct-trust__grid--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 1024px) { .ct-trust__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .ct-trust__grid { grid-template-columns: minmax(0, 1fr); } }

.ct-trust__item { display: flex; flex-direction: column; }

.ct-trust__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--ct-flow-md);
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-wash-cool);
  color: var(--ct-color-secondary-aaa);
}
.ct-trust__icon .ct-icon { width: 20px; height: 20px; }
/* Bandeau « Les avantages » de la homepage (.ct-trust.ct-theme-grey,
   demande directe 2026-09-08) : fond blanc plutôt que le lavis bleu par
   défaut, pour ressortir sur le fond gris du panneau. Scopé à ce bloc
   précis (FR + EN), les autres usages de .ct-trust__icon sur le site
   gardent le lavis par défaut. */
.ct-trust.ct-theme-grey .ct-trust__icon { background-color: var(--ct-color-bg-alt); }

.ct-trust__title {
  margin: 0 0 var(--ct-flow-sm);
  font-size: var(--ct-font-size-base);
  font-weight: var(--ct-font-weight-bold);
  line-height: var(--ct-line-height-snug);
  color: var(--ct-color-text);
}
.ct-trust__text {
  margin: 0;
  font-size: var(--ct-font-size-sm);
  line-height: var(--ct-line-height-base);
  color: var(--ct-color-text-light);
}

/* Note de bas de bandeau : c'est là que vit le lien vers les preuves. */
.ct-trust__note {
  margin: var(--ct-space-lg) 0 0;
  padding-top: var(--ct-space-md);
  border-top: 1px solid var(--ct-color-line-cool);
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
}

/* ---- Variante compacte : une seule ligne, sous un hero ------------------- */
/* Pas de phrase de preuve ici : la ligne compacte rappelle des engagements
   déjà démontrés ailleurs sur la page. */
.ct-trust--inline .ct-trust__grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ct-space-md) var(--ct-space-lg);
}
.ct-trust--inline .ct-trust__item {
  flex-direction: row;
  align-items: center;
  gap: var(--ct-space-sm);
}
.ct-trust--inline .ct-trust__icon {
  width: auto;
  height: auto;
  margin-bottom: 0;
  background-color: transparent;
  border-radius: 0;
  color: var(--ct-color-accent-green-aaa);
}
.ct-trust--inline .ct-trust__icon .ct-icon { width: 16px; height: 16px; }
.ct-trust--inline .ct-trust__title {
  margin: 0;
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-text-light);
}

/* ---- Alignement des items côte à côte (cf. §14) -------------------------- */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 621px) {
    .ct-trust:not(.ct-trust--inline) .ct-trust__grid {
      grid-template-rows: auto auto auto;
      row-gap: 0;
      column-gap: var(--ct-space-lg);
      align-items: start;
    }
    .ct-trust:not(.ct-trust--inline) .ct-trust__item {
      display: grid;
      grid-row: span 3;
      grid-template-rows: subgrid;
      margin-bottom: var(--ct-space-lg);
    }
    .ct-trust__item > .ct-trust__icon  { grid-row: 1; }
    .ct-trust__item > .ct-trust__title { grid-row: 2; }
    .ct-trust__item > .ct-trust__text  { grid-row: 3; }
  }
}

/* Sur fond sombre, les deux blocs suivent la surface de section : la pastille
   d'icône passe en voile blanc, les filets en bordure sur sombre. */
.ct-section--dark .ct-trust__icon,
.ct-cta-primary .ct-trust__icon {
  background-color: var(--ct-color-surface-hover-on-dark);
  color: var(--ct-color-text-on-dark);
}
.ct-section--dark .ct-trust__note,
.ct-section--dark .ct-compare__outcome {
  border-top-color: var(--ct-color-border-on-dark);
}
.ct-section--dark .ct-trust__title,
.ct-section--dark .ct-compare__title,
.ct-section--dark .ct-compare__outcome { color: var(--ct-color-text-on-dark); }
.ct-section--dark .ct-trust__text,
.ct-section--dark .ct-trust__note,
.ct-section--dark .ct-compare__item { color: var(--ct-color-text-on-dark-muted); }


/* =============================================================================
   19. BLOCS 47–56, analyse concurrentielle Prox.ia
   Uniquement des tokens existants : la déclinaison sombre suit sans code
   supplémentaire, à l'exception de `.ct-flow-radial__core`, qui reprend
   la surface la plus profonde au même titre que `.ct-hub__core` (§13).
   ========================================================================== */

/* ---- 47. ct-flow-radial ---------------------------------------------------- */
.ct-flow-radial__figure { margin: 0; }
.ct-flow-radial__grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(200px, 280px) minmax(0, 1fr);
  grid-template-areas:
    ".    n    ."
    "w   core  e"
    ".    s    .";
  align-items: center;
  gap: var(--ct-space-lg);
}
.ct-flow-radial__connectors { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.ct-flow-radial__connectors svg { width: 100%; height: 100%; display: block; }
.ct-flow-radial__connectors line { stroke: var(--ct-color-border-strong); stroke-width: 1; vector-effect: non-scaling-stroke; }
.ct-flow-radial__core {
  grid-area: core;
  position: relative;
  z-index: 1;
  background-color: var(--ct-color-surface-dark);
  color: var(--ct-color-text-on-dark);
  border-radius: var(--ct-radius-lg);
  padding: var(--ct-space-lg);
  text-align: center;
}
.ct-flow-radial__core-label {
  font-size: var(--ct-font-size-xs);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-text-on-dark-muted);
}
.ct-flow-radial__core-title { font-size: var(--ct-font-size-lg); font-weight: var(--ct-font-weight-bold); margin-top: var(--ct-space-xs); }
.ct-flow-radial__branch {
  position: relative;
  z-index: 1;
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
  max-width: 280px;
  justify-self: center;
  text-align: center;
}
.ct-flow-radial__branch--n { grid-area: n; }
.ct-flow-radial__branch--e { grid-area: e; }
.ct-flow-radial__branch--s { grid-area: s; }
.ct-flow-radial__branch--w { grid-area: w; }
.ct-flow-radial__icon { color: var(--ct-color-accent-green-aaa); margin-bottom: var(--ct-space-sm); display: inline-flex; }
.ct-flow-radial__branch-title { font-weight: var(--ct-font-weight-bold); margin-bottom: var(--ct-space-xs); }
.ct-flow-radial__branch-text { font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
.ct-flow-radial__legend { text-align: center; margin-top: var(--ct-space-lg); font-size: var(--ct-font-size-sm); color: var(--ct-color-text-light); }
@media (max-width: 768px) {
  .ct-flow-radial__grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "core" "n" "e" "s" "w"; }
  .ct-flow-radial__connectors { display: none; }
  .ct-flow-radial__branch { max-width: none; justify-self: stretch; }
}

/* ---- 48. ct-scenarios-tabs -------------------------------------------------- */
.ct-scenarios-tabs__bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ct-space-sm);
  margin-bottom: var(--ct-space-lg);
  border-bottom: 1px solid var(--ct-color-border);
}
.ct-scenarios-tabs__tab {
  appearance: none;
  border: none;
  border-bottom: 3px solid transparent;
  background: none;
  cursor: pointer;
  margin-bottom: -1px;
  padding: var(--ct-space-sm) var(--ct-space-lg);
  font: inherit;
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-text-light);
}
.ct-scenarios-tabs__tab:hover { color: var(--ct-color-text); }
.ct-scenarios-tabs__tab[aria-selected="true"] { color: var(--ct-color-text); border-bottom-color: var(--ct-color-secondary); }
.ct-scenarios-tabs__panel[hidden] { display: none; }
.ct-scenarios-tabs__grid { display: grid; gap: var(--ct-space-lg); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 768px) { .ct-scenarios-tabs__grid { grid-template-columns: minmax(0, 1fr); } }
.ct-scenarios-tabs__card {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
  height: 100%;
}
.ct-scenarios-tabs__card--response { border-color: var(--ct-color-accent-green); }
.ct-scenarios-tabs__actor { margin-bottom: var(--ct-space-sm); }
.ct-scenarios-tabs__label {
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-text-light);
  margin-bottom: var(--ct-space-xs);
}
.ct-scenarios-tabs__text { line-height: var(--ct-line-height-relaxed); }

/* ---- 49. ct-product-tour ---------------------------------------------------- */
.ct-product-tour__steps { display: flex; flex-wrap: wrap; gap: var(--ct-space-sm); margin-bottom: var(--ct-space-lg); }
.ct-product-tour__step {
  appearance: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--ct-space-sm);
  border: 1px solid var(--ct-color-border);
  background-color: var(--ct-color-bg-alt);
  border-radius: var(--ct-radius-pill);
  padding: var(--ct-space-sm) var(--ct-space-md);
  font: inherit;
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
}
.ct-product-tour__step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background-color: var(--ct-color-border);
  color: var(--ct-color-text);
  font-weight: var(--ct-font-weight-bold);
  font-size: var(--ct-font-size-xs);
  flex-shrink: 0;
}
.ct-product-tour__step[aria-selected="true"] { border-color: var(--ct-color-secondary); color: var(--ct-color-text); }
.ct-product-tour__step[aria-selected="true"] .ct-product-tour__step-num { background-color: var(--ct-color-secondary); color: var(--ct-color-on-secondary); }
.ct-product-tour__panel[hidden] { display: none; }
.ct-product-tour__frame {
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  overflow: hidden;
  background-color: var(--ct-color-bg-alt);
}
.ct-product-tour__bar {
  display: flex;
  gap: 6px;
  padding: var(--ct-space-sm) var(--ct-space-md);
  background-color: var(--ct-color-bg);
  border-bottom: 1px solid var(--ct-color-border);
}
.ct-product-tour__bar span { width: 10px; height: 10px; border-radius: 50%; background-color: var(--ct-color-border-strong); }
.ct-product-tour__shot { margin: 0; }
.ct-product-tour__shot img { width: 100%; height: auto; display: block; }
.ct-product-tour__text { margin-top: var(--ct-space-md); color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
.ct-product-tour__nav { display: flex; justify-content: flex-end; gap: var(--ct-space-sm); margin-top: var(--ct-space-md); }
.ct-product-tour__prev,
.ct-product-tour__next {
  appearance: none;
  cursor: pointer;
  border: 1px solid var(--ct-color-border);
  background-color: var(--ct-color-bg-alt);
  color: var(--ct-color-text);
  border-radius: 50%;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ct-product-tour__prev:hover,
.ct-product-tour__next:hover { background-color: var(--ct-color-surface-hover); }

/* ---- 50. ct-compare-matrix -------------------------------------------------- */
.ct-compare-matrix__table th.ct-compare-matrix__col--featured,
.ct-compare-matrix__table td.ct-compare-matrix__col--featured {
  background-color: var(--ct-color-secondary-soft);
  border-left: 2px solid var(--ct-color-secondary);
  border-right: 2px solid var(--ct-color-secondary);
}
.ct-compare-matrix__table thead th.ct-compare-matrix__col--featured { color: var(--ct-color-secondary-aaa); }

/* ---- 51. ct-tiers-trajectory ------------------------------------------------ */
.ct-tiers-trajectory__row { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr; align-items: start; gap: var(--ct-space-md); }
.ct-tiers-trajectory__arrow { display: flex; align-items: center; padding-top: var(--ct-space-xl); color: var(--ct-color-border-strong); }
.ct-tiers-trajectory__tier {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-top: 4px solid var(--ct-color-border-strong);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
  height: 100%;
}
.ct-tiers-trajectory__tier--1 { border-top-color: var(--ct-color-border-strong); }
.ct-tiers-trajectory__tier--2 { border-top-color: var(--ct-color-secondary); }
.ct-tiers-trajectory__tier--3 { border-top-color: var(--ct-color-accent-green); }
.ct-tiers-trajectory__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-color: var(--ct-color-bg);
  border: 1px solid var(--ct-color-border);
  font-weight: var(--ct-font-weight-bold);
  margin-bottom: var(--ct-space-md);
}
.ct-tiers-trajectory__name { margin-bottom: var(--ct-space-sm); }
.ct-tiers-trajectory__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }
@media (max-width: 900px) {
  .ct-tiers-trajectory__row { grid-template-columns: minmax(0, 1fr); }
  .ct-tiers-trajectory__arrow { justify-self: center; padding-top: 0; transform: rotate(90deg); }
}

/* ---- 52. ct-persona-archetype ------------------------------------------------ */
.ct-persona-archetype__card {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
  height: 100%;
}
.ct-persona-archetype__role {
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-text-light);
  margin-bottom: var(--ct-space-sm);
}
.ct-persona-archetype__name { font-size: var(--ct-font-size-lg); margin-bottom: var(--ct-space-md); }
.ct-persona-archetype__label { color: var(--ct-color-secondary-aaa); }
.ct-persona-archetype__quote {
  border-left: 3px solid var(--ct-color-border-strong);
  padding-left: var(--ct-space-md);
  font-style: italic;
  color: var(--ct-color-text-light);
  margin-bottom: var(--ct-space-md);
}
.ct-persona-archetype__text { line-height: var(--ct-line-height-relaxed); }

/* ---- 53. ct-segment-size ------------------------------------------------------ */
.ct-segment-size__card {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-lg);
  height: 100%;
}
.ct-segment-size__icon {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--ct-radius-md);
  background-color: var(--ct-color-secondary-soft);
  color: var(--ct-color-secondary-aaa);
  margin-bottom: var(--ct-space-md);
}
.ct-segment-size__tag {
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--ct-tracking-caps);
  color: var(--ct-color-accent-green-aaa);
  margin-bottom: var(--ct-space-xs);
}
.ct-segment-size__name { margin-bottom: var(--ct-space-sm); }
.ct-segment-size__text { color: var(--ct-color-text-light); line-height: var(--ct-line-height-relaxed); }

/* ---- 54. ct-risk-accordion ----------------------------------------------------
   Bouton + panneau : registre « alerte », premier item ouvert par défaut.
   Chevron identique à `.ct-faq__question::after` (§20), icône et bordure
   gauche en plus pour marquer le registre d'alerte. */
.ct-risk-accordion__list { display: flex; flex-direction: column; gap: var(--ct-space-md); }
.ct-risk-accordion__item {
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-left: 3px solid var(--ct-color-accent-orange);
  border-radius: var(--ct-radius-md);
  padding: var(--ct-space-md) var(--ct-space-lg);
}
.ct-risk-accordion__heading { margin: 0; }
.ct-risk-accordion__trigger {
  appearance: none;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  padding: 0;
  font: inherit;
  font-size: var(--ct-font-size-lg);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-text);
  display: flex;
  align-items: flex-start;
  gap: var(--ct-space-md);
  cursor: pointer;
}
.ct-risk-accordion__icon { color: var(--ct-color-accent-orange-ink); flex-shrink: 0; margin-top: 2px; }
.ct-risk-accordion__label { flex: 1; }
.ct-risk-accordion__chevron {
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  margin-top: 8px;
  border-right: 2px solid var(--ct-color-secondary-aaa);
  border-bottom: 2px solid var(--ct-color-secondary-aaa);
  transform: rotate(45deg);
  transition: transform var(--ct-transition-base);
}
.ct-risk-accordion__trigger[aria-expanded="true"] .ct-risk-accordion__chevron { transform: rotate(-135deg); }
.ct-risk-accordion__panel {
  margin-top: var(--ct-space-md);
  padding-left: calc(20px + var(--ct-space-md));
  color: var(--ct-color-text-light);
  line-height: var(--ct-line-height-relaxed);
}
.ct-risk-accordion__panel[hidden] { display: none; }

/* ---- 55. ct-screenshot-annotated, variante composable du Hero (bloc 01) ---- */
.ct-screenshot-annotated { position: relative; margin: 0; border-radius: var(--ct-radius-md); overflow: hidden; }
.ct-screenshot-annotated__img { width: 100%; height: auto; display: block; }
.ct-screenshot-annotated__badge {
  position: absolute;
  display: flex;
  align-items: center;
  gap: var(--ct-space-sm);
  max-width: 260px;
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border);
  border-radius: var(--ct-radius-md);
  box-shadow: var(--ct-shadow-md);
  padding: var(--ct-space-sm) var(--ct-space-md);
}
.ct-screenshot-annotated__badge-icon { color: var(--ct-color-accent-green-aaa); flex-shrink: 0; }
.ct-screenshot-annotated__badge-text { font-size: var(--ct-font-size-sm); font-weight: var(--ct-font-weight-medium); color: var(--ct-color-text); }
.ct-screenshot-annotated__badge--top-right { top: var(--ct-space-md); right: var(--ct-space-md); }
.ct-screenshot-annotated__badge--top-left { top: var(--ct-space-md); left: var(--ct-space-md); }
.ct-screenshot-annotated__badge--bottom-right { bottom: var(--ct-space-md); right: var(--ct-space-md); }
.ct-screenshot-annotated__badge--bottom-left { bottom: var(--ct-space-md); left: var(--ct-space-md); }
@media (max-width: 640px) {
  .ct-screenshot-annotated__badge { position: static; margin-top: var(--ct-space-sm); max-width: none; }
}

/* ---- 56. ct-manifesto ----------------------------------------------------- */
.ct-manifesto__list { list-style: none; display: flex; flex-direction: column; gap: var(--ct-space-lg); margin-bottom: var(--ct-space-xl); }
.ct-manifesto__item { display: flex; gap: var(--ct-space-md); align-items: flex-start; }
.ct-manifesto__badge {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-color: var(--ct-color-secondary-soft);
  color: var(--ct-color-secondary-aaa);
  font-weight: var(--ct-font-weight-bold);
  font-size: var(--ct-font-size-sm);
}
.ct-manifesto__text { line-height: var(--ct-line-height-relaxed); padding-top: 4px; }
.ct-manifesto__quote {
  border-left: 3px solid var(--ct-color-accent-green);
  padding-left: var(--ct-space-lg);
  font-size: var(--ct-font-size-lg);
  font-style: italic;
  color: var(--ct-color-text);
}


/* =============================================================================
   08. ACCESSIBILITÉ, MOTION, IMPRESSION
   ========================================================================== */

/* Focus visible sur tout élément interactif du namespace.
   Anneau à fort contraste, jamais supprimé. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: var(--ct-focus-width) solid var(--ct-color-secondary);
  outline-offset: var(--ct-focus-offset);
  border-radius: var(--ct-radius-sm);
}
/* Sur fond sombre l'anneau bleu manque de contraste : on passe au blanc. */
.ct-section--dark a:focus-visible,
.ct-section--dark button:focus-visible,
.ct-hero a:focus-visible,
.ct-hero button:focus-visible,
.ct-cta-primary a:focus-visible,
.ct-cta-primary button:focus-visible {
  outline-color: var(--ct-color-bg-alt);
}
/* Cartes de bifurcation dans le hero : îles claires, l'anneau blanc y
   redevient invisible (blanc sur blanc) — on revient à l'anneau par défaut. */
.ct-hero__cards a:focus-visible,
.ct-hero__cards button:focus-visible {
  outline-color: var(--ct-color-secondary);
}

/* Cible tactile minimale 44×44 (WCAG 2.5.8) */
.ct-btn,
.ct-faq__question { min-height: 44px; }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@media (forced-colors: active) {
  .ct-btn { border: 1px solid ButtonText; }
  .ct-card,
  .ct-benefit-card,
  .ct-faq__item,
  .ct-node,
  .ct-tag,
  .ct-alert,
  .ct-input { border: 1px solid CanvasText; }
}

@media print {
  body { background: #fff; color: #000; }
  .ct-hero,
  .ct-cta-primary,
  .ct-hero::after,
  .ct-cta-primary::after,
  .ct-section--dark,
  .ct-hub__core,
  .ct-flow-radial__core,
  .ct-pricing-configurator__contact,
  .ct-keyfigure,
  .ct-code,
  .ct-split__panel--dark,
  .ct-navbar,
  .ct-site-footer { background: #fff !important; background-image: none !important; color: #000 !important; }
  .ct-card--cta, .ct-shot { break-inside: avoid; }
  .ct-theme-dark,
  .ct-theme-dark .ct-hero, .ct-theme-dark .ct-cta-primary,
  .ct-theme-dark .ct-card--dark, .ct-theme-dark .ct-hub__core {
    background: #fff !important; background-image: none !important; color: #000 !important;
  }
  .ct-theme-dark .ct-shot img, .ct-theme-dark .ct-card__media img { opacity: 1 !important; }
  .ct-faq__item { break-inside: avoid; }
  .ct-btn { border: 1px solid #000; }
}

/* =============================================================================
   UTILITAIRES D'ESPACEMENT — .ct-mt-* / .ct-mb-*
   -----------------------------------------------------------------------------
   Volontairement en toute fin de fichier : à spécificité égale, un composant
   qui se remet à zéro (ex. .ct-trust__grid { margin: 0 }) est défini plus tôt
   dans la cascade et l'emporterait sinon sur ces utilitaires par simple ordre
   de source, malgré l'intention explicite de l'utilitaire posé dans le HTML.
   ========================================================================== */
.ct-mt-lg { margin-top: var(--ct-space-lg); }
.ct-mt-xl { margin-top: var(--ct-space-xl); }
.ct-mt-xxl { margin-top: var(--ct-space-xxl); }
.ct-mb-lg { margin-bottom: var(--ct-space-lg); }

/* =============================================================================
   RÉVÉLATION PROGRESSIVE MOBILE — cartes (43) et réassurance (46)
   -----------------------------------------------------------------------------
   Ajout ciblé (js/ct-mobile-progressive.js) : sur mobile, un .ct-card-grid de
   plus de 3 éléments réduit l'empilement à 3 cartes + un bouton « Voir plus » ;
   un .ct-trust__grid de plus de 3 éléments devient un accordéon mono-ouverture,
   premier engagement ouvert par défaut. Purement additif et progressif : sans
   JS, seules les 3 premières cartes / le premier engagement de réassurance
   restent visibles — état par défaut correct sans script, même logique que
   .ct-risk-accordion (§54) et .ct-scenarios-tabs (§48).
   ========================================================================== */

/* ---- Cartes : seuil 767px, sans collision avec le subgrid de §43 (≥769px) */
@media (max-width: 767px) {
  .ct-card-grid > :nth-child(n+4) { display: none; }
  .ct-card-grid.is-expanded > :nth-child(n+4) { display: flex; }
}

.ct-mobile-reveal {
  display: none;
  width: 100%;
  align-items: center;
  justify-content: center;
  gap: var(--ct-space-sm);
  margin-top: var(--ct-space-lg);
  margin-bottom: var(--ct-space-lg);
  padding: var(--ct-space-sm) var(--ct-space-lg);
  min-height: 44px;
  background-color: var(--ct-color-bg-alt);
  border: 1px solid var(--ct-color-border-strong);
  border-radius: var(--ct-radius-pill);
  font: inherit;
  font-weight: var(--ct-font-weight-medium);
  color: var(--ct-color-secondary-aaa);
  cursor: pointer;
}
@media (max-width: 767px) {
  .ct-mobile-reveal { display: flex; }
}
.ct-mobile-reveal:hover { background-color: var(--ct-color-surface-hover); }
.ct-mobile-reveal__chevron {
  width: 10px;
  height: 10px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--ct-transition-base);
}
.ct-mobile-reveal[aria-expanded="true"] .ct-mobile-reveal__chevron { transform: rotate(-135deg); }

/* ---- Grille d'icônes/numéros + panneau partagé — composant générique ------
   Introduit pour la réassurance (bloc 46, demande directe 2026-09-10,
   inspiré d'une maquette fournie images/reassurance-mobile.html), étendu
   aux étapes numérotées (bloc 33, demande directe 2026-09-10, section
   #solution) : deux blocs différents, même mécanique — grille compacte de
   déclencheurs (tous visibles, aucun replié par défaut) + un panneau de
   détail unique sous la grille, rempli au clic sur un déclencheur.
   Classes `.ct-mobile-tiles`/`.ct-mobile-tile`/`.ct-mobile-panel-*`
   partagées par les deux blocs (seuil d'utilisation de deux blocs pour
   entrer dans le design system commun, voir contraintes-techniques.md) ;
   seuls le contenu du « slot » icône (icône réassurance clonée vs. numéro
   d'étape généré) et le seuil de bascule diffèrent, gérés par bloc
   ci-dessous. Entièrement additif dans les deux cas : construit en JS à
   côté du contenu original (jamais muté), qui reste la version servie
   sans JS et au-delà du seuil — voir js/ct-mobile-progressive.js. */
.ct-mobile-tiles {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ct-mobile-tiles--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.ct-mobile-tiles--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
/* Au-delà de 5 déclencheurs (ex. réassurance à 8 items, /essai-gratuit/,
   2026-09-29), une seule rangée de tuiles serait trop étroite : on reste
   sur 4 colonnes et on laisse la grille passer à la ligne (repli identique
   à --4, sans le --N littéral au-delà de 5 — le nombre de colonnes n'a pas
   à égaler le nombre d'items). */
.ct-mobile-tiles--6,
.ct-mobile-tiles--7,
.ct-mobile-tiles--8 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.ct-mobile-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 6px 2px 8px;
  border: none;
  background: transparent;
  border-radius: var(--ct-radius-md);
  font: inherit;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--ct-transition-fast);
}
.ct-mobile-tile:hover { background-color: var(--ct-color-surface-hover); }
.ct-section--dark .ct-mobile-tile:hover,
.ct-cta-primary .ct-mobile-tile:hover { background-color: var(--ct-color-surface-hover-on-dark); }
.ct-mobile-tile-label {
  font-size: 10.5px;
  line-height: 1.2;
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-text);
  text-align: center;
}
.ct-mobile-tile[aria-expanded="true"] .ct-mobile-tile-label { color: var(--ct-color-secondary-aaa); }

.ct-mobile-panel-wrap {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--ct-transition-base);
}
.ct-mobile-panel-wrap.is-open { grid-template-rows: 1fr; }
.ct-mobile-panel-inner { overflow: hidden; }
.ct-mobile-panel {
  margin-top: var(--ct-space-sm);
  padding: var(--ct-space-sm) var(--ct-space-md);
  background-color: var(--ct-color-bg-alt);
  border-left: 3px solid var(--ct-color-secondary);
  border-radius: 4px var(--ct-radius-md) var(--ct-radius-md) 4px;
}
.ct-mobile-panel-title {
  margin: 0 0 4px;
  font-size: var(--ct-font-size-sm);
  font-weight: var(--ct-font-weight-bold);
  color: var(--ct-color-secondary-aaa);
}
.ct-mobile-panel-text {
  margin: 0;
  font-size: var(--ct-font-size-sm);
  line-height: var(--ct-line-height-relaxed);
  color: var(--ct-color-text-light);
}
@media (prefers-reduced-motion: reduce) {
  .ct-mobile-reveal__chevron { transition: none; }
  .ct-mobile-tile,
  .ct-mobile-panel-wrap { transition: none; }
}

/* ---- Réassurance (bloc 46) : icône existante réutilisée dans le slot ------
   Seuil propre à ce bloc (≤620px) : au-delà, .ct-trust__grid s'aligne en
   subgrid par ligne dès 621px (.ct-trust__item > .ct-trust__text, voir §46
   ci-dessus) ; en 2 colonnes (621–1024px) l'empilement long est de toute
   façon déjà résorbé par la mise en page — voir ECARTS.md. */
.ct-trust--tiled .ct-trust__grid { display: none; }
@media (min-width: 621px) {
  .ct-trust--tiled .ct-trust__grid { display: grid; }
}
.ct-mobile-tile .ct-trust__icon { margin-bottom: 0; }
.ct-mobile-tile[aria-expanded="true"] .ct-trust__icon {
  background-color: var(--ct-color-secondary);
  color: var(--ct-color-on-secondary);
}
/* Placées après les déclarations de base ci-dessus : à spécificité égale
   (une seule classe), une règle plus tôt dans le fichier perd contre une
   règle plus tard, quelle que soit sa media query — voir le bug déjà
   rencontré pour .ct-navbar.ct-navbar--sticky, ECARTS.md n°82. */
@media (min-width: 621px) {
  .ct-trust--tiled .ct-mobile-tiles,
  .ct-trust--tiled .ct-mobile-panel-wrap { display: none; }
}

/* ---- Étapes (bloc 33, section #solution) : numéro à la place de l'icône ---
   Aucun conflit de sous-grille pour ce bloc (absent de la liste des dix
   familles alignées en subgrid, docs/regles/responsive.md) : seuil
   standard ≤767px repris tel quel, sans la restriction propre au bloc 46.
   .ct-steps--tiled posé directement sur le <ol> original (pas besoin d'un
   conteneur englobant dédié comme .ct-trust--tiled : rien d'autre à
   coordonner) ; la grille de tuiles et le panneau, insérés juste après en
   tant que frères, sont ciblés par combinateur de frères généraux plutôt
   que par ascendant commun. */
.ct-steps.ct-steps--tiled { display: none; }
@media (min-width: 768px) {
  .ct-steps.ct-steps--tiled { display: block; }
  .ct-steps--tiled ~ .ct-mobile-tiles,
  .ct-steps--tiled ~ .ct-mobile-panel-wrap { display: none; }
}
.ct-steps__tile-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: var(--ct-color-secondary);
  color: var(--ct-color-bg-alt);
  font-weight: var(--ct-font-weight-bold);
  font-size: var(--ct-font-size-sm);
}

/* =============================================================================
   FIL D'ARIANE — .ct-breadcrumb (nouveau composant, pas dans le catalogue
   56 blocs — voir ECARTS.md). Réservé aux pages profondes (Solutions par
   rôle, Offres, Ressources) : une page de niveau 1 n'a rien à y gagner.
   Fondu dans le header plutôt que posé comme bande claire séparée (demande
   directe, 2026-09-10) : même surface sombre et mêmes tokens `-on-dark`
   que .ct-navbar juste au-dessus, pour lire comme une deuxième ligne du
   même bloc plutôt qu'une section à part. Pas de copie du fond signature
   du header (l'image se recadre par élément — une seconde occurrence
   créerait une coupure visible dans le motif au lieu de le prolonger) ;
   un aplat de la même couleur de base suffit à raccorder les deux zones. */
.ct-breadcrumb {
  background-color: var(--ct-color-surface-dark);
  border-bottom: 1px solid var(--ct-color-border-on-dark);
  overflow-x: auto;
}
.ct-breadcrumb__list {
  display: flex;
  align-items: center;
  gap: var(--ct-space-xs);
  list-style: none;
  margin: 0;
  padding: var(--ct-space-sm) var(--ct-container-pad);
  max-width: var(--ct-container-max);
  margin-inline: auto;
  white-space: nowrap;
  font-size: var(--ct-font-size-sm);
}
.ct-breadcrumb__item { display: flex; align-items: center; gap: var(--ct-space-xs); color: var(--ct-color-text-on-dark-muted); }
.ct-breadcrumb__item a { color: var(--ct-color-text-on-dark-muted); text-decoration: none; border-radius: var(--ct-radius-sm); }
.ct-breadcrumb__item a:hover { color: var(--ct-color-text-on-dark); background-color: rgba(255, 255, 255, 0.08); }
.ct-breadcrumb__item[aria-current="page"] { color: var(--ct-color-accent-green); font-weight: var(--ct-font-weight-bold); }
.ct-breadcrumb__item:not(:last-child)::after {
  content: "/";
  color: var(--ct-color-border-on-dark);
}

/* =============================================================================
   VISIONNEUSE D'IMAGE — .ct-lightbox (nouveau composant, pas dans le
   catalogue 56 blocs — voir ECARTS.md). Injecté par js/ct-lightbox.js sur
   les pages qui le chargent, jamais présent en HTML statique. Rend
   cliquables les captures d'écran existantes (.ct-shot,
   .ct-product-tour__shot, .ct-showcase__shot...) sans changer leur mise en
   page : le bouton `.ct-lightbox-trigger` est neutre (pas de bordure, pas
   de fond), l'image garde exactement le style déjà défini pour son bloc
   d'origine. */
.ct-lightbox-trigger {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  text-align: left;
}
.ct-lightbox-trigger:hover img { opacity: 0.92; }

.ct-lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--ct-space-xl) var(--ct-space-lg);
}
/* L'attribut [hidden] doit rester prioritaire sur le display:flex ci-dessus
   (sinon la visionneuse reste visible, cliquable et interceptant les clics,
   même masquée à l'écran par endroits — bug constaté à l'implémentation). */
.ct-lightbox[hidden] { display: none; }
.ct-lightbox__backdrop {
  position: absolute;
  inset: 0;
  background-color: rgba(11, 14, 27, 0.9);
}
.ct-lightbox__panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ct-space-sm);
  max-width: min(92vw, 1200px);
  max-height: 100%;
}
.ct-lightbox__img {
  max-width: 100%;
  max-height: 80vh;
  width: auto;
  height: auto;
  border-radius: var(--ct-radius-md);
  box-shadow: var(--ct-shadow-md);
}
.ct-lightbox__caption {
  color: var(--ct-color-text-on-dark-muted);
  font-size: var(--ct-font-size-sm);
  text-align: center;
  max-width: 70ch;
}
.ct-lightbox__close {
  position: fixed;
  top: var(--ct-space-md);
  right: var(--ct-space-md);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--ct-radius-pill);
  border: 1px solid var(--ct-color-border-on-dark);
  background-color: rgba(255, 255, 255, 0.08);
  color: var(--ct-color-text-on-dark);
  cursor: pointer;
}
.ct-lightbox__close:hover { background-color: rgba(255, 255, 255, 0.16); }

body.ct-lightbox-open { overflow: hidden; }

/* =============================================================================
   ANCRES SOUS HEADER STICKY — évite qu'un lien du type #faq n'atterrisse
   caché sous .ct-navbar--sticky. Valeurs alignées sur la hauteur réelle du
   header (mesurée) à chaque palier ; à ajuster si le contenu du header
   change. Sans effet sur les pages sans header sticky (repose sur la
   présence de la classe posée sur <html>, voir ECARTS.md). */
html.has-sticky-nav { scroll-padding-top: 84px; }
@media (max-width: 768px) {
  html.has-sticky-nav { scroll-padding-top: 190px; }
}

/* =============================================================================
   PAGES D'ERREUR — .ct-error (404/500/403/401/503, demande directe)
   -----------------------------------------------------------------------------
   Nouveau composant, hors catalogue 56 blocs (voir ECARTS.md). Rejoint le
   groupe de sélecteurs du fond signature ci-dessus (§ hero/CTA/navbar/
   footer, même aplat + même image, mêmes tokens) pour l'arrière-plan ;
   voile radial centré propre à .ct-error ci-dessous, plutôt que le voile
   directionnel du hero — celui-ci est pensé pour un texte à gauche /
   visuel à droite, non pertinent pour un contenu centré.
   ========================================================================== */
.ct-error {
  display: flex;
  align-items: center;
  min-height: 70vh;
}
.ct-error::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(120% 100% at 50% 40%, rgba(26, 31, 54, 0.55) 0%, rgba(26, 31, 54, 0.85) 100%);
  pointer-events: none;
}
.ct-error__inner {
  width: 100%;
  text-align: center;
  padding-block: var(--ct-space-xxl);
}
.ct-error__code {
  margin: 0 0 var(--ct-space-sm);
  font-size: clamp(64px, 14vw, 140px);
  font-weight: var(--ct-font-weight-bold);
  line-height: 1;
  letter-spacing: var(--ct-tracking-tight);
  color: var(--ct-color-text-on-dark);
}
.ct-error__title { margin: 0 0 var(--ct-space-md); color: var(--ct-color-text-on-dark); }
.ct-error__text {
  margin: 0 auto var(--ct-space-xl);
  max-width: 46ch;
  color: var(--ct-color-text-on-dark-muted);
  font-size: var(--ct-font-size-lg);
  line-height: var(--ct-line-height-relaxed);
}
.ct-error__actions { justify-content: center; }
/* Bouton "retour" : action JS (historique du navigateur), jamais une
   destination — <button>, pas <a href>, conformément à CLAUDE.md principe
   6. Sans JS, ce bouton secondaire n'a pas d'effet (dégradation mineure
   assumée) ; le CTA principal, lui, est un vrai lien et fonctionne dans
   tous les cas. */
.ct-error__back { cursor: pointer; }

@media (max-width: 640px) {
  .ct-error__actions { flex-direction: column; align-items: stretch; }
}

/* =============================================================================
   57. ct-ecosystem (écosystème : EuraTechnologies, Campus Cyber, French Tech
   Lille), demande directe 2026-10-20, voir ECARTS.md n°200.
   Trois variantes : --band (bandeau sous le hero), --cards (grille À propos),
   --compact (formulaires, pied de page). Logos en niveaux de gris, couleur au
   survol et au focus ; l'affordance appartient au lien, pas au conteneur.
   ========================================================================== */
.ct-ecosystem__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: var(--ct-space-xl);
}
.ct-ecosystem__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--ct-space-sm);
  min-width: 0;
}
.ct-ecosystem__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border-radius: var(--ct-radius-sm);
}
.ct-ecosystem__logo {
  display: block;
  width: auto;
  height: 56px;
  max-width: 220px;
  object-fit: contain; /* boîte stable avant chargement : hauteur fixe + ratio des attributs */
  filter: grayscale(1);
  opacity: 0.7;
  transition: filter var(--ct-transition-base), opacity var(--ct-transition-base);
}
.ct-ecosystem__link:hover .ct-ecosystem__logo,
.ct-ecosystem__link:focus-visible .ct-ecosystem__logo { filter: none; opacity: 1; }
.ct-ecosystem__caption {
  margin: 0;
  font-size: var(--ct-font-size-sm);
  color: var(--ct-color-text-light);
}
.ct-ecosystem__label {
  margin: 0;
  font-size: var(--ct-font-size-xs);
  font-weight: var(--ct-font-weight-bold);
  letter-spacing: var(--ct-tracking-caps);
  text-transform: uppercase;
  color: var(--ct-color-text-light);
}

/* Bandeau (accueil, tarifs) : bande discrète, fond gris très clair du thème
   grey, filet bas. */
.ct-ecosystem--band {
  padding-block: var(--ct-space-xl);
  border-bottom: 1px solid var(--ct-color-border);
  text-align: center;
}
.ct-ecosystem--band .ct-eyebrow { justify-content: center; }
.ct-ecosystem--band .ct-ecosystem__title {
  margin: 0 0 var(--ct-space-lg);
  font-size: var(--ct-font-size-lg);
  font-weight: var(--ct-font-weight-bold);
  line-height: var(--ct-line-height-snug);
  letter-spacing: var(--ct-tracking-tight);
  color: var(--ct-color-text);
}
.ct-ecosystem--quiet { padding-block: var(--ct-space-lg); }
.ct-ecosystem--quiet .ct-ecosystem__logo { height: 48px; max-width: 180px; }

/* Cartes (À propos) : le logo en tête de carte, le texte en dessous. */
.ct-ecosystem__media {
  display: flex;
  align-items: center;
  min-height: 68px;
  margin: 0 0 var(--ct-flow-md);
}
.ct-ecosystem--cards .ct-ecosystem__logo { height: 48px; max-width: 200px; }

/* Compact (formulaires, pied de page). */
.ct-ecosystem--compact {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ct-space-md) var(--ct-space-lg);
}
.ct-ecosystem--compact .ct-ecosystem__list { justify-content: flex-start; gap: var(--ct-space-lg); }
.ct-ecosystem--compact .ct-ecosystem__logo { height: 32px; max-width: 150px; }
.ct-ecosystem--compact .ct-ecosystem__link { min-height: 32px; }

/* Pied de page : fond sombre, logos en monochrome clair. */
.ct-site-footer__legal .ct-ecosystem--compact {
  flex-basis: 100%;
  order: 2;
  justify-content: center;
  padding-top: var(--ct-space-md);
  border-top: 1px solid var(--ct-color-border-on-dark);
}
.ct-site-footer .ct-ecosystem__label { color: var(--ct-color-text-on-dark-muted); }
.ct-site-footer .ct-ecosystem__logo {
  height: 24px;
  max-width: 130px;
  filter: brightness(0) invert(1);
  opacity: 0.6;
}
.ct-site-footer .ct-ecosystem__link:hover .ct-ecosystem__logo,
.ct-site-footer .ct-ecosystem__link:focus-visible .ct-ecosystem__logo { filter: brightness(0) invert(1); opacity: 1; }
/* Le logo French Tech Lille a un fond blanc plein dans son pictogramme : en
   silhouette inversée le coq disparaît. On le garde en niveaux de gris, sans
   inversion, ce qui reste lisible sur le fond sombre. */
.ct-site-footer .ct-ecosystem__logo--portrait,
.ct-site-footer .ct-ecosystem__link:hover .ct-ecosystem__logo--portrait,
.ct-site-footer .ct-ecosystem__link:focus-visible .ct-ecosystem__logo--portrait { filter: grayscale(1); }

/* Logo de format portrait (French Tech Lille) : hauteur relevée pour rester
   lisible à côté des logos horizontaux, même alignement de base. */
.ct-ecosystem__logo--portrait { height: 80px; }
.ct-ecosystem--quiet .ct-ecosystem__logo--portrait,
.ct-ecosystem--cards .ct-ecosystem__logo--portrait { height: 68px; }
.ct-ecosystem--compact .ct-ecosystem__logo--portrait { height: 44px; }
.ct-site-footer .ct-ecosystem__logo--portrait { height: 32px; }
/* Boîte de lien à hauteur fixe par variante : les logos se centrent dedans et
   les légendes restent alignées sur une même ligne de base. */
.ct-ecosystem--band .ct-ecosystem__link { height: 80px; }
.ct-ecosystem--quiet .ct-ecosystem__link,
.ct-ecosystem--cards .ct-ecosystem__link { height: 68px; }
.ct-ecosystem--compact .ct-ecosystem__link { height: 44px; min-height: 0; }
.ct-site-footer .ct-ecosystem__link { height: 32px; }

@media (max-width: 640px) {
  .ct-ecosystem__list { gap: var(--ct-space-lg); }
  .ct-ecosystem--band .ct-ecosystem__item { flex: 1 1 40%; }
  .ct-ecosystem--band .ct-ecosystem__logo { height: 48px; max-width: 160px; }
  .ct-ecosystem--band .ct-ecosystem__logo--portrait { height: 68px; }
  .ct-ecosystem--band .ct-ecosystem__link { height: 68px; }
  .ct-ecosystem--compact { justify-content: center; }
  .ct-ecosystem--compact .ct-ecosystem__list { justify-content: center; }
}
/* Bande de confiance de l'accueil (--strip, demande directe 2026-10-20) :
   libellé centré au-dessus, puis trois colonnes logo + légende centrées,
   gap fixe, rangée centrée (demande du 2026-10-20, après-midi).
   Hauteurs optiques réglées logo par logo (poids visuels comparables) ;
   boîte de logo fixe (--ct-eco-box) pour centrer les logos sur une même
   ligne et aligner le libellé sur cette ligne, pas sur logo + légende. */
.ct-ecosystem--strip {
  --ct-eco-box: 56px;
  padding-block: var(--ct-space-lg);
  border-bottom: 1px solid var(--ct-color-border);
  background-color: var(--ct-color-bg-alt);
}
.ct-ecosystem--strip .ct-ecosystem__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ct-space-md);
}
.ct-ecosystem__lead {
  margin: 0;
  text-align: center;
  font-size: var(--ct-font-size-sm);
  line-height: var(--ct-line-height-snug);
  color: var(--ct-color-text);
}
.ct-ecosystem--strip .ct-ecosystem__list {
  flex: 0 1 auto;
  justify-content: center;
  align-items: flex-start;
  gap: var(--ct-space-xl);
}
.ct-ecosystem--strip .ct-ecosystem__item { flex: 0 0 auto; align-items: center; text-align: center; gap: var(--ct-space-xs); }
.ct-ecosystem--strip .ct-ecosystem__link { height: var(--ct-eco-box); min-height: 0; justify-content: center; }
.ct-ecosystem--strip .ct-ecosystem__logo { opacity: 0.8; }
.ct-ecosystem--strip .ct-ecosystem__logo--campus { height: 40px; max-width: 120px; }
.ct-ecosystem--strip .ct-ecosystem__logo--eura { height: 24px; max-width: 190px; }
.ct-ecosystem--strip .ct-ecosystem__logo--ftl { height: 36px; max-width: 120px; }
.ct-ecosystem--strip .ct-ecosystem__caption {
  font-size: var(--ct-font-size-xs);
  line-height: var(--ct-line-height-snug);
  color: var(--ct-color-text-light);
  white-space: nowrap;
}

@media (max-width: 1024px) {
  .ct-ecosystem--strip .ct-ecosystem__inner { align-items: stretch; }
  .ct-ecosystem--strip .ct-ecosystem__caption { white-space: normal; max-width: 22ch; }
}
@media (max-width: 640px) {
  .ct-ecosystem--strip { --ct-eco-box: 40px; }
  .ct-ecosystem--strip .ct-ecosystem__list { flex-wrap: nowrap; justify-content: space-between; gap: var(--ct-space-xs); width: 100%; }
  .ct-ecosystem--strip .ct-ecosystem__item { flex: 1 1 0; min-width: 0; }
  .ct-ecosystem--strip .ct-ecosystem__item:nth-child(1) { flex-grow: 1.5; }  /* largeur des colonnes proportionnée à la longueur des légendes, */
  .ct-ecosystem--strip .ct-ecosystem__item:nth-child(2) { flex-grow: 1.3; }  /* pour deux lignes maximum à partir de 375 px */
  .ct-ecosystem--strip .ct-ecosystem__logo--campus { height: 30px; }
  .ct-ecosystem--strip .ct-ecosystem__logo--eura { height: 18px; max-width: 100%; }
  .ct-ecosystem--strip .ct-ecosystem__logo--ftl { height: 26px; }
  .ct-ecosystem--strip .ct-ecosystem__caption { max-width: none; font-size: var(--ct-font-size-xxs); }
}

@media (prefers-reduced-motion: reduce) {
  .ct-ecosystem__logo { transition: none; }
}
@media print {
  .ct-ecosystem__logo,
  .ct-site-footer .ct-ecosystem__logo { filter: none; opacity: 1; }
}
