/*
 * Composants réutilisables — construits exclusivement à partir de
 * tokens.css. Aucune valeur brute ici : toujours var(--...).
 */

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--color-background);
  color: var(--color-text);
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
}

/* Défilement doux vers une ancre de page (ex: "Voir le détail" /conformite/
   vers une question de la FAQ ou vers #infrastructure) au lieu du saut sec
   natif. Désactivé si l'utilisateur a demandé moins de mouvement. */
html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* Focus clavier — aucun style dédié n'existait auparavant : au clavier, les
   boutons/liens n'affichaient que l'anneau bleu par défaut du navigateur,
   qui jure avec la charte et ne respecte pas le contraste minimum requis
   (3:1, WCAG 1.4.11) partout sur le site. `:focus-visible` (pas `:focus`)
   pour ne montrer l'anneau qu'à la navigation clavier, jamais au clic
   souris. Marine par défaut (contraste ~14:1 sur fond clair) ; jaune dans
   .section--dark où le marine se fondrait dans son propre fond (contraste
   ~9:1 sur fond marine) — un seul système à deux variantes, pas un anneau
   différent par section. */
:focus-visible {
  outline: 2px solid var(--color-accent-secondary);
  outline-offset: 2px;
}

.section--dark :focus-visible {
  outline-color: var(--color-accent);
}

/* Titres */

h1,
h2,
h3,
h4 {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-family-heading);
  line-height: var(--line-height-heading);
  color: var(--color-heading);
}

h1 {
  font-size: var(--font-size-h1);
  font-weight: 700;
}

h2 {
  font-size: var(--font-size-h2);
  font-weight: 700;
}

h3 {
  font-size: var(--font-size-h3);
  font-weight: 600;
}

h4 {
  font-size: var(--font-size-h4);
  font-weight: 700;
}

/* Styles visuels h1-h4 découplés du tag Hn — pour piloter le rendu visuel
   indépendamment du niveau de titre SEO (ou de l'absence de titre), sans
   changer ce rendu (validé par Sébastien, home 2026-09-14). */
.heading-style-h1 {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-family-heading);
  line-height: var(--line-height-heading);
  color: var(--color-heading);
  font-size: var(--font-size-h1);
  font-weight: 700;
}

.heading-style-h2 {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-family-heading);
  line-height: var(--line-height-heading);
  color: var(--color-heading);
  font-size: var(--font-size-h2);
  font-weight: 700;
}

.heading-style-h3 {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-family-heading);
  line-height: var(--line-height-heading);
  color: var(--color-heading);
  font-size: var(--font-size-h3);
  font-weight: 600;
}

.heading-style-h4 {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-family-heading);
  line-height: var(--line-height-heading);
  color: var(--color-heading);
  font-size: var(--font-size-h4);
  font-weight: 700;
}

p {
  margin: 0 0 var(--space-sm);
  color: var(--color-text);
}

.text-secondary {
  color: var(--color-text-secondary);
}

.text-tertiary {
  color: var(--color-text-tertiary);
}

/* .hero__highlight — met en valeur "CGP" directement dans le H1 (home pro),
   surlignage marqueur jaune façon Linear/Attio/Ashby, plutôt qu'un eyebrow
   séparé au-dessus (option validée par Elena parmi 5 propositions). Unités
   en em pour que l'épaisseur du surlignage suive la taille du H1 (qui
   change entre mobile 36px et desktop 50px, voir tokens.css). */
.hero__highlight {
  position: relative;
  white-space: nowrap;
}

.hero__highlight::before {
  content: "";
  position: absolute;
  left: -0.04em;
  right: -0.04em;
  bottom: 0.02em;
  height: 0.36em;
  background: var(--color-accent);
  z-index: -1;
}

/* .hero__lede — sous-titre du hero (home pro). Remplace l'ancien <h2> en
   heading-style-h3 (gras, noir, collé au H1) qui créait deux titres empilés
   de même poids visuel au lieu d'un vrai rapport headline/texte de
   soutien — registre "deux gros titres" plutôt que "titre + lede", peu lisible
   à la Stripe. Même taille que --font-size-h3 mais poids réduit et couleur
   secondaire : se lit clairement comme la phrase de soutien du H1. */
.hero__lede {
  margin: 0 0 var(--space-sm);
  font-size: var(--font-size-h3);
  font-weight: 500;
  line-height: var(--line-height-heading);
  color: var(--color-text-secondary);
}

/* .rating-badge — pastille "★★★★★ 4,9/5 par nos clients" (hero), unifie le
   texte brut de la home et l'image Google de /page-conformite/, validé
   Sébastien */
.rating-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  background: var(--color-background);
  padding: var(--space-xs) var(--space-md);
  color: var(--color-text-secondary);
}

.rating-badge__stars {
  color: var(--color-accent);
  letter-spacing: 1px;
}

/* Liens — par défaut identiques au texte environnant (choix de design
   existant, validé). --color-link est STRICTEMENT réservé au contenu
   d'article : n'appliquer .prose qu'au wrapper du corps d'article
   (étape 1b), jamais sur une page marketing (home/service/offres). */

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

/* Menu mobile plein écran (structure dans layout.css) — couleurs. */
.site-header__mobile-icon span {
  background: var(--color-heading);
}

.site-header__mobile-toggle nav {
  background: var(--color-background);
}

.site-header__mobile-toggle li a:not(.btn) {
  color: var(--color-heading);
  border-bottom: 1px solid var(--color-border);
}

.site-header__mobile-toggle li a:not(.btn):hover {
  color: var(--color-accent-secondary);
}

.prose a {
  color: var(--color-link);
  text-decoration: underline;
}

/* Boutons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  border: none;
  font-family: var(--font-family-body);
  font-weight: 500;
  font-size: var(--font-size-body);
  text-decoration: none;
  cursor: pointer;
  /* Un bouton ne doit jamais passer son texte à la ligne (ex: header pile
     à 1024px, juste à la bascule nav mobile -> desktop, où l'espace est
     tendu) — s'il manque de place, c'est au conteneur de céder, pas au
     label de casser en deux lignes dans une pilule prévue pour une seule. */
  white-space: nowrap;
}

/* Boutons avec un peu de matière (demandé explicitement) : léger dégradé
   (à peine perceptible, pas un effet "glossy" too much) + liseré intérieur
   clair en haut (le bord qui "attrape" la lumière) donnent du volume au
   repos ; l'état survol ne soulève plus le bouton mais le fait "s'enfoncer"
   (translateY positif + ombre qui passe à l'intérieur) pour un retour plus
   tactile, presque une pression physique. */
.btn-primary {
  background: linear-gradient(180deg, #2b2b2b 0%, var(--color-primary) 100%);
  color: var(--color-primary-text);
  border-radius: var(--radius-sm);
  padding: var(--padding-btn-compact);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 1px 2px rgba(0, 0, 0, 0.18);
  transition: background 0.2s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.btn-primary:hover {
  background: linear-gradient(180deg, #333333 0%, var(--color-primary-hover) 100%);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.35);
  transform: translateY(1px);
}

.btn-primary--large {
  border-radius: var(--radius-md);
  padding: var(--padding-btn-large);
}

.btn-secondary {
  background: var(--color-secondary-bg);
  color: var(--color-secondary-text);
  border-radius: var(--radius-sm);
  /* Horizontal élargi (ronde 5) pour laisser respirer le texte des pilules
     de filtre (hero) — vertical inchangé. Survol volontairement minimal
     (demandé explicitement) : juste le changement de couleur, pas d'ombre
     ni de mouvement. */
  padding: var(--padding-btn-compact) var(--space-md);
  transition: background-color 0.25s ease;
}

.btn-secondary:hover {
  background: var(--color-secondary-bg-hover);
}

.btn-ghost {
  background: transparent;
  color: var(--color-heading);
  padding: var(--padding-btn-compact) 0;
}

.btn-ghost:hover {
  color: var(--color-accent-secondary);
  text-decoration: underline;
}

/* .btn-info — CTA fond bleu clair (ex: "En savoir plus sur le Dossier
   Fiscal"). Ne réutilise que des tokens déjà validés, aucune nouvelle
   couleur : --color-background-info + --color-heading. */
.btn-info {
  background: var(--color-background-info);
  color: var(--color-heading);
  border-radius: var(--radius-sm);
  padding: var(--padding-btn-compact) var(--space-md);
}

/* Cards
   Quatre familles de cards mesurées séparément (voir docs/da-exploration.md,
   section "Cards — quatre blocs de DA") + .card générique en repli pour le
   contenu qui ne correspond à aucune des quatre. */

/* .card — générique/repli, encadrés de contenu d'article (key takeaways,
   exemple chiffré, étapes, tableau comparatif) */
.card {
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-card);
}

/* .reveal — utilitaire générique d'apparition au scroll (fondu + léger
   décalage vers le haut), posé par js/scroll-reveal.js sur tout élément
   marqué [data-reveal] (étapes "Comment ça marche ?", cards "Conçu pour
   s'intégrer à votre pratique"...). La classe n'est ajoutée que par ce
   script : sans JS, rien n'est masqué, tout reste visible par défaut. */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.reveal.is-revealed {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* .preview-placeholder — mockup neutre en attendant les vrais visuels
   (rapport, import, calcul...) : un en-tête + des lignes de texte + un
   mini-graphique en niveaux de gris suggèrent un document réel, plutôt
   qu'une boîte vide avec un texte en italique qui donne un rendu inachevé.
   Le libellé passe en petite pastille dans le coin (moins dominant qu'un
   texte centré). À retirer dès que les vrais visuels sont fournis. */
.preview-placeholder {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-lg);
  position: relative;
  overflow: hidden;
}

.preview-placeholder__tag {
  position: absolute;
  top: var(--space-sm);
  right: var(--space-sm);
  background: var(--color-background-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: var(--padding-badge);
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--color-text-tertiary);
}

.preview-placeholder__header {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.preview-placeholder__mark {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-sm);
  background: var(--color-accent);
  flex-shrink: 0;
}

.preview-placeholder__header span:not(.preview-placeholder__mark),
.preview-placeholder__lines span {
  display: block;
  height: 8px;
  border-radius: var(--radius-sm);
  background: var(--color-border);
}

.preview-placeholder__header span:not(.preview-placeholder__mark) {
  height: 12px;
}

.preview-placeholder__lines {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.preview-placeholder__chart {
  display: flex;
  align-items: flex-end;
  gap: var(--space-xs);
  height: 96px;
}

.preview-placeholder__chart span {
  flex: 1;
  border-radius: 3px 3px 0 0;
  background: var(--color-background-alt-dark);
}

/* .preview-placeholder__rows — variante "liste de connexions" (étape
   Importez) : suggère des comptes/courtiers reliés plutôt qu'un document,
   pour différencier ce panneau des deux autres étapes. */
.preview-placeholder__rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.preview-placeholder__row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.preview-placeholder__row-icon {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  background: var(--color-background-alt-dark);
  flex-shrink: 0;
}

.preview-placeholder__row-bar {
  display: block;
  height: 8px;
  border-radius: var(--radius-sm);
  background: var(--color-border);
}

/* .preview-placeholder__ring — variante "calcul en cours" (étape Laissez
   DeclarAid calculer) : anneau de progression en dégradé conique, plus
   parlant qu'un graphique en barres pour une étape de traitement. */
.preview-placeholder__ring {
  width: 96px;
  height: 96px;
  margin: 0 auto;
  border-radius: 50%;
  background: conic-gradient(var(--color-accent) 0deg 252deg, var(--color-border) 252deg 360deg);
  display: flex;
  align-items: center;
  justify-content: center;
}

.preview-placeholder__ring::after {
  content: "";
  width: 66px;
  height: 66px;
  border-radius: 50%;
  background: var(--color-background);
}

/* .step-visual — visuels des 3 étapes "Comment ça marche ?". Un seul
   langage graphique pour les 3 : diagramme de flux animé (nœuds reliés
   par des lignes en pointillés qui défilent, sur une trame de points en
   fond) plutôt qu'une capture d'UI. Raconte "entrées → traitement →
   sortie" d'un panneau à l'autre : (1) plusieurs sources convergent vers
   un nœud DeclarAid ; (2) le nœud DeclarAid irrigue les modules fiscaux ;
   (3) le document assemblé part vers le téléchargement. Charte DeclarAid
   (tokens), pas celle du hero-doc. */
.step-visual {
  position: relative;
  overflow: hidden;
  background-image: radial-gradient(var(--color-border) 1px, transparent 1px);
  background-size: 20px 20px;
}

.step-visual__lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.step-visual__lines path {
  fill: none;
  stroke: var(--color-border);
  stroke-width: 1.5;
}

.step-visual__lines path.is-flow {
  stroke: var(--color-accent-secondary);
  stroke-width: 2;
  stroke-dasharray: 5 7;
  opacity: .6;
  animation: stepVisualFlow 1.6s linear infinite;
}

@keyframes stepVisualFlow {
  to {
    stroke-dashoffset: -24;
  }
}

.step-visual__node {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--color-background);
  border: 1.5px solid var(--color-border);
  box-shadow: var(--shadow-card);
  color: var(--color-text-secondary);
  z-index: 1;
  /* Ces nœuds ne sont pas cliquables (purement illustratifs) : le curseur
     reste normal, mais un léger "pop" au survol suggère qu'ils réagissent
     — rend le diagramme plus vivant/tactile. */
  transition: transform .25s cubic-bezier(.34, 1.56, .64, 1), box-shadow .25s ease, border-color .25s ease;
}

.step-visual__node:hover {
  transform: translate(-50%, -50%) scale(1.18);
  border-color: var(--color-accent-secondary);
  box-shadow: var(--shadow-card-marketing);
}

/* --hub/--action ont déjà leur propre box-shadow animé (pulsation) : au
   survol, on ne touche qu'au transform pour ne pas entrer en conflit avec
   l'animation (chacun garde son halo de couleur respective). */
.step-visual__node--hub:hover {
  transform: translate(-50%, -50%) scale(1.15);
  border-color: transparent;
}

.step-visual__node--action:hover {
  transform: translate(-50%, -50%) scale(1.15);
  border-color: transparent;
}

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

.step-visual__node--sm {
  width: 27px;
  height: 27px;
}

.step-visual__node--muted {
  border-style: dashed;
  color: var(--color-text-tertiary);
  font-size: 9px;
  font-weight: 700;
}

.step-visual__node--hub {
  width: 46px;
  height: 46px;
  background: var(--color-accent-secondary);
  border-color: var(--color-accent-secondary);
  color: var(--color-accent-secondary-text);
  box-shadow: 0 0 0 6px rgba(30, 42, 94, .08), var(--shadow-card-marketing);
  animation: stepVisualPulse 2.6s ease-in-out infinite;
}

.step-visual__node--action {
  width: 40px;
  height: 40px;
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-heading);
  box-shadow: 0 0 0 6px rgba(254, 206, 0, .18), var(--shadow-card-marketing);
  animation: stepVisualPulseAction 2.6s ease-in-out infinite;
}

@keyframes stepVisualPulse {
  0%, 100% { box-shadow: 0 0 0 6px rgba(30, 42, 94, .08), var(--shadow-card-marketing); }
  50% { box-shadow: 0 0 0 11px rgba(30, 42, 94, .03), var(--shadow-card-marketing); }
}

@keyframes stepVisualPulseAction {
  0%, 100% { box-shadow: 0 0 0 6px rgba(254, 206, 0, .18), var(--shadow-card-marketing); }
  50% { box-shadow: 0 0 0 11px rgba(254, 206, 0, .06), var(--shadow-card-marketing); }
}

@media (prefers-reduced-motion: reduce) {
  .step-visual__lines path.is-flow,
  .step-visual__node--hub,
  .step-visual__node--action {
    animation: none;
  }
}

/* .card-compare — comparatif risque/bénéfice (FIFO vs DeclarAid,
   /page-conformite/), validé Sébastien */
.card-compare {
  border-radius: var(--radius-lg);
  padding: var(--space-card);
  text-align: center;
}

.card-compare--bad {
  background: var(--color-error-bg);
}

.card-compare--good {
  background: var(--color-success-bg);
}

.card-compare--bad .icon-outline {
  color: var(--color-error-text);
}

.card-compare--good .icon-outline {
  color: var(--color-success-text);
}

/* .card-pricing — /nos-offres/. Affinée après premier rendu, validée par
   Sébastien : titre agrandi, période/description resserrées et hiérarchisées,
   séparateur avant la checklist, hauteur de card et bas de bouton alignés
   entre les 4 offres (voir .card-pricing__description et .card-pricing__cta
   ci-dessous). */
.card-pricing {
  display: flex;
  flex-direction: column;
  background: var(--color-background-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pricing);
  box-shadow: none;
  padding: var(--space-lg);
  text-align: left;
  position: relative;
}

/* .card-pricing--featured — offre mise en avant (Sérénité) : fond blanc pur
   (vs. --color-background-alt des 3 autres cards) + ombre, pour ressortir
   du lot. Demandé explicitement par Sébastien. */
.card-pricing--featured {
  background: var(--color-background);
  box-shadow: var(--shadow-card-marketing);
}

.card-pricing__price {
  font-family: var(--font-family-heading);
  font-size: var(--font-size-h2);
  font-weight: 500;
  color: var(--color-heading);
  margin: var(--space-sm) 0 0;
}

.card-pricing__title {
  font-size: 24px;
}

.card-pricing__period {
  font-size: 13px;
  letter-spacing: -0.2px;
  color: var(--color-text-secondary);
}

.card-pricing__description {
  font-size: 12px;
  line-height: 1.25;
  color: var(--color-text-tertiary);
  /* Réserve une hauteur égale entre les 4 cards (la description la plus
     longue, Sérénité, fait ~5 lignes) pour que le séparateur et la
     checklist démarrent à la même hauteur sur les 4 offres. */
  min-height: 6.25em;
}

.card-pricing__separator {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: var(--space-sm) 0;
}

.card-pricing__cta {
  margin-top: auto;
}

/* Checklist des fonctionnalités par offre : réutilise .split-section__checklist
   (layout) avec une coche verte (incluse) / une croix atténuée (non incluse),
   scoping sous .card-pricing pour ne pas affecter les autres usages de
   .split-section__checklist (page-conformite, home) qui n'ont pas cette
   distinction inclus/exclu. */
.card-pricing .split-section__checklist li svg {
  color: var(--color-success-text);
}

.card-pricing .split-section__checklist li.text-tertiary {
  opacity: 0.55;
}

.card-pricing .split-section__checklist li.text-tertiary svg {
  color: var(--color-text-tertiary);
}

/* .badge — pilule (ex: badge en haut des cards pricing). Non cliquable par
   défaut (span) ; utiliser <a class="badge"> pour la variante cliquable
   utilisée sur les cards des articles de blog. */
a.badge {
  cursor: pointer;
}

/* .badge-outline — pilule à fond clair + bordure/texte colorés (hero:
   "Bourse : calculs PMP" / "Crypto : 150-VH du CGI"). Couleurs validées
   ronde 3, distinctes de --color-background-info. */
.badge-outline {
  display: inline-block;
  border-radius: var(--radius-pill);
  padding: var(--padding-badge);
  font-size: var(--font-size-xs);
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
  border: 1px solid transparent;
}

.badge-outline--success {
  background: var(--color-success-bg);
  color: var(--color-success-text);
  border-color: var(--color-success-text);
}

.badge-outline--info {
  background: var(--color-info-bg);
  color: var(--color-info-text);
  border-color: var(--color-info-text);
}

/* .badge-outline--neutral — tags sans portée sémantique (catégories d'actifs
   hero pro : Location Nue, LMNP...). Les couleurs success/info seraient
   trompeuses ici (elles signalent un état) ; gris neutre pour ne pas
   concurrencer visuellement le bouton CTA (seul élément qui doit rester en
   noir plein dans le hero). */
.badge-outline--neutral {
  background: var(--color-background-alt);
  color: var(--color-text-secondary);
  border-color: var(--color-border);
  text-transform: none;
}

/* .badge-step — cercle numéroté (1/2/3), distinct de .badge (pilule) */
.badge-step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--size-badge-step);
  height: var(--size-badge-step);
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-accent-text);
  font-weight: 700;
  font-size: var(--font-size-body);
}

/* .icon-badge — cercle plein + icône ligne blanche centrée (SVG en enfant).
   Deux variantes de fond : noire par défaut, jaune (--icon-badge--accent).
   Ombre portée teintée (même noir que le fond, pas un gris neutre) pour un
   léger effet de flottaison plutôt qu'un aplat posé à plat sur la card. */
.icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--size-icon-badge);
  height: var(--size-icon-badge);
  margin-bottom: var(--space-md);
  border-radius: 50%;
  background: var(--color-primary);
  color: var(--color-primary-text);
  box-shadow: rgba(23, 23, 23, 0.22) 0px 8px 16px -6px;
  transition: background-color 0.2s ease;
}

.icon-badge svg {
  width: 28px;
  height: 28px;
}

.icon-badge--accent {
  background: var(--color-accent);
}

/* .card-marketing — cards marketing classiques (home/service/offres, hors
   FAQ et pricing — ex: encadré liste de courtiers) */
.card-marketing {
  background: var(--color-background);
  border: none;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card-marketing);
  padding: var(--padding-card-marketing);
}

/* .tech-panel — liste des sous-traitants d'infrastructure ("Pour aller plus
   loin", /conformite/). Panneau bordé unique + filets internes entre lignes,
   même grammaire que .pricing-panel/.compare-table/.credibility-bar__panel
   : la structure vient des filets, pas de cards flottantes. Volontairement
   très différent de .card-faq juste au-dessus (cards à ombre) — cette
   section est une fiche de référence (sous-traitant, région, certifs), pas
   une FAQ, et juxtaposer deux accordéons identiques donnait une impression
   de contenu dupliqué. Pas de <details> ici : liste toujours dépliée,
   comme une table de sous-traitants publiée par un éditeur SaaS sérieux. */
.tech-panel {
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-align: left;
}

.tech-panel__row {
  padding: var(--space-lg);
}

.tech-panel__row + .tech-panel__row {
  border-top: 1px solid var(--color-border);
}

.tech-panel__row-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}

.tech-panel__index {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--color-text-tertiary);
}

.tech-panel__title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--color-heading);
}

.tech-panel__vendor {
  font-weight: 400;
  color: var(--color-text-secondary);
}

.tech-panel__desc {
  margin: 0 0 var(--space-sm);
  color: var(--color-text-secondary);
}

.tech-panel__row > .tech-panel__tags:last-child,
.tech-panel__row > .tech-panel__desc:last-child {
  margin-bottom: 0;
}

.tech-panel__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-xs);
}

.tech-panel__note {
  margin: var(--space-xs) 0 0;
  font-size: 13px;
  color: var(--color-text-tertiary);
}

/* .pricing-panel — remplace les 2 cards à ombre empilées (Tarification,
   home pro) par UN panneau bordé unique (fond blanc, filet fin, pas
   d'ombre) — même grammaire que .compare-table et .credibility-bar__panel
   : la structure vient des filets internes entre sous-blocs, pas de cards
   flottantes. Sous-sections : liste des modules inclus (coche), puis
   "Sans risque"/"Offre de lancement" (icône + titre + texte), puis CTA —
   chacune séparée par un filet horizontal. */
.pricing-panel {
  max-width: 760px;
  margin: 0 auto;
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  text-align: left;
}

.pricing-panel__modules {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-lg);
  padding: var(--space-lg);
  border-bottom: 1px solid var(--color-border);
}

.pricing-panel__module {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-weight: 600;
  font-size: 14px;
  color: var(--color-text);
}

.pricing-panel__module svg {
  flex-shrink: 0;
  color: var(--color-accent-secondary);
}

.pricing-panel__module--soon {
  color: var(--color-text-tertiary);
}

.pricing-panel__module--soon svg {
  color: var(--color-text-tertiary);
}

.pricing-panel__row {
  display: flex;
  gap: var(--space-md);
  align-items: flex-start;
  padding: var(--space-lg);
}

.pricing-panel__row + .pricing-panel__row {
  border-top: 1px solid var(--color-border);
}

.pricing-panel__row-icon {
  flex-shrink: 0;
  margin-top: 2px;
}

.pricing-panel__row-title {
  margin: 0 0 var(--space-2xs);
}

.pricing-panel__row p:last-child {
  margin: 0;
  color: var(--color-text-secondary);
}

.pricing-panel__footer {
  padding: var(--space-lg);
  text-align: center;
  border-top: 1px solid var(--color-border);
}

/* .card-blog — card de la grille "Derniers articles" (/articles-blog/).
   Fond gris (au lieu du blanc+bordure de .card générique) + ombre pour
   ressortir sur le fond blanc de la page, demandé explicitement par
   Sébastien. Ne réutilise que des tokens déjà validés : pas de nouvelle
   couleur ni de nouvelle ombre. */
.card-blog {
  background: var(--color-background-alt);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card-marketing);
  padding: var(--space-card);
}

.card-blog__badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-bottom: var(--space-sm);
}

.card-blog h4 {
  margin: 0 0 var(--space-sm);
}

.card-blog p {
  margin: 0;
  font-size: 13px;
}

/* .press-card — mentions presse (/media-presse/, home pro). Remplace
   .card-blog pour cette page uniquement (.card-blog n'est utilisée nulle
   part ailleurs sur le site pro, laissée intacte pour un usage blog futur).
   Vignette pleine largeur qui déborde jusqu'aux bords de la card (au lieu
   d'être encadrée par le padding) + ratio 16/9 forcé (object-fit: cover)
   pour une grille visuellement alignée malgré des captures d'écran
   d'origine toutes de tailles différentes — sans ça la grille avait des
   cards de hauteurs très inégales. Zoom léger sur l'image + soulèvement de
   la card au survol, même registre que .feature-columns__item.card-marketing. */
.press-card {
  display: block;
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.press-card:hover {
  transform: translateY(-4px);
  box-shadow: rgba(0, 0, 0, 0.35) 0px 12px 28px -6px;
}

.press-card__thumb {
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--color-background-alt);
}

.press-card__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.press-card:hover .press-card__thumb img {
  transform: scale(1.05);
}

.press-card__body {
  padding: var(--space-card);
}

.press-card__meta {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-xs);
  font-size: 13px;
  color: var(--color-text-tertiary);
}

.press-card__outlet {
  font-weight: 700;
  color: var(--color-text);
}

.press-card__title {
  margin: 0 0 var(--space-sm);
}

.press-card__title a {
  color: var(--color-heading);
  text-decoration: none;
}

.press-card__title a:hover {
  color: var(--color-accent-secondary);
}

.press-card__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-accent-secondary);
  text-decoration: none;
}

.press-card__link svg {
  transition: transform 0.2s ease;
}

.press-card__link:hover svg {
  transform: translateX(2px);
}

/* .feature-columns__link — lien "Voir le détail" des cards de synthèse
   (/conformite/), même registre que .press-card__link (texte + flèche qui
   glisse au survol) plutôt que le soulignement générique de .btn-ghost. */
.feature-columns__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-top: auto;
  padding-top: var(--space-xs);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-accent-secondary);
  text-decoration: none;
}

.feature-columns__link svg {
  transition: transform 0.2s ease;
}

.feature-columns__link:hover svg {
  transform: translateX(2px);
}

/* Icon-badge passe en bleu marine (accent secondaire de la marque) au
   survol de la card entière — même déclic de couleur que .press-card__title
   au survol, pour lier l'icône au mouvement de soulèvement de la card. */
.feature-columns__item.card-marketing:hover .icon-badge {
  background: var(--color-accent-secondary);
}

/* .card-toc — sommaire d'article de blog */
.card-toc {
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-toc);
  box-shadow: var(--shadow-toc);
  padding: var(--space-card);
}

/* .toc-link — lien du sommaire d'article (dans .card-toc). Surlignage de
   la section en cours de lecture ajouté suite à demande explicite de
   Sébastien (scroll-spy, voir docs/missing-components.md et
   src/js/toc-scrollspy.js) — réutilise uniquement des tokens existants. */
.toc-link {
  display: block;
  padding: var(--space-xs) 0 var(--space-xs) var(--space-xs);
  font-size: 13px;
  line-height: 1.4;
  color: var(--color-text-secondary);
  border-left: 2px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}

li + li > .toc-link {
  margin-top: var(--space-2xs);
}

.toc-link.is-active {
  color: var(--color-heading);
  border-left-color: var(--color-accent);
  font-weight: 700;
}

/* .card-faq — FAQ, présente sur les pages marketing et en fin d'article de
   blog. Padding non mesuré précisément par le script d'extraction (porté
   par un élément interne non capturé) — valeur approximative. */
.card-faq {
  background: var(--color-background);
  border: none;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-faq);
  padding: var(--space-md);
  /* Clippe le survol de <summary> (voir details.card-faq > summary dans
     layout.css) aux coins arrondis de la card. */
  overflow: hidden;
  /* Compense le header sticky (~87px) pour qu'une ancre directe (ex: "Voir
     le détail" /conformite/) n'atterrisse pas masquée dessous. */
  scroll-margin-top: 100px;
}

details.card-faq > summary:hover {
  background: var(--color-background-alt);
}

/* .faq-group — regroupe les questions de la FAQ (/conformite/) par pilier
   thématique (mêmes 4 catégories que les cartes de synthèse en haut de
   page : Sécurité des données / Rigueur fiscale / Protection RGPD /
   Périmètre clair), pour que la FAQ se lise comme une documentation
   structurée plutôt qu'une liste plate de 8 questions sans hiérarchie. */
.faq-group + .faq-group {
  margin-top: var(--space-xl);
}

/* Compense le header sticky pour une ancre directe (cartes de synthèse
   "Voir le détail" /conformite/ vers le groupe FAQ correspondant). */
.faq-group {
  scroll-margin-top: 100px;
}

.faq-group__label {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-sm);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-accent-secondary);
}

.faq-group__label svg {
  flex-shrink: 0;
}

/* .accordion-group--faq — registre légèrement plus "engineered" que
   .card-faq générique (fin d'article de blog...) : filet fin au lieu de
   l'ombre, marqueur en pastille ronde plutôt qu'un simple caractère +/-,
   accent marine sur la question active. Scopé pour ne pas affecter .card-
   faq ailleurs sur le site. */
.accordion-group--faq .card-faq {
  border: 1px solid var(--color-border);
  box-shadow: none;
  transition: border-color 0.2s ease;
}

.accordion-group--faq .card-faq:hover {
  border-color: var(--color-text-tertiary);
}

.accordion-group--faq details.card-faq[open] {
  border-color: var(--color-accent-secondary);
}

.accordion-group--faq details.card-faq[open] > summary strong {
  color: var(--color-accent-secondary);
}

.accordion-group--faq details.card-faq > summary::after {
  content: '+';
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  font-size: 16px;
  font-weight: 400;
  line-height: 1;
  color: var(--color-text-secondary);
  transition: all 0.2s ease;
}

.accordion-group--faq details.card-faq[open] > summary::after {
  content: '\2212';
  background: var(--color-accent-secondary);
  border-color: var(--color-accent-secondary);
  color: #fff;
}

/* .card-quote — bloc citation avec avatar (fondateur/expert). Deux
   variantes : blanche avec ombre (défaut) et fond bleu clair (--info,
   réutilise --color-background-info déjà validé). */
.card-quote {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  background: var(--color-background);
  border: none;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card-marketing);
  padding: var(--space-card);
  /* Texte toujours aligné à gauche, y compris dans un parent centré
     (ex: .content-section) — validé ronde 5. */
  text-align: left;
}

.card-quote--info {
  background: var(--color-background-info);
  box-shadow: none;
}

.card-quote__avatar {
  flex-shrink: 0;
  width: var(--size-avatar-sm);
  height: var(--size-avatar-sm);
  border-radius: 50%;
  object-fit: cover;
}

/* .card-testimonial — avis client (nom/rôle + titre + citation + étoiles,
   dans cet ordre — pas d'avatar dans le contenu réel du site). Prévue pour
   être utilisée dans un carrousel .testimonial-marquee (voir plus bas). */
.card-testimonial {
  flex: 0 0 320px;
  background: var(--color-background);
  border: none;
  border-radius: var(--radius-md);
  /* Pas d'ombre (ronde 5) : le carrousel doit se fondre dans le fond de la
     page, sans démarcation visuelle entre les cards et la section. */
  box-shadow: none;
  padding: var(--space-card);
}

.card-testimonial__author {
  margin: 0 0 var(--space-sm);
}

.card-testimonial__title {
  margin: 0 0 var(--space-xs);
}

.card-testimonial__quote {
  margin: 0 0 var(--space-sm);
}

.card-testimonial__stars {
  color: var(--color-accent);
  letter-spacing: 2px;
  margin: 0;
}

/* .testimonial-marquee — carrousel à défilement continu (2 rangées, sens
   opposés) avec fondu sur les bords. Le contenu de .testimonial-track doit
   être dupliqué une fois dans le HTML (2 jeux de cards identiques à la
   suite) pour boucler sans coupure — l'animation va de 0 à -50%. */
.testimonial-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
}

.testimonial-track {
  display: flex;
  width: max-content;
  gap: var(--space-md);
  animation: marquee-left var(--duration-marquee) linear infinite;
}

@keyframes marquee-left {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .testimonial-track {
    animation: none;
  }
}

/* .press-marquee — carrousel de logos presse (home, "DeclarAid dans la
   presse"), même mécanique que .testimonial-marquee/.testimonial-track
   ci-dessus (fondu sur les bords, animation marquee-left partagée), +
   pause au survol et logos en niveaux de gris, demandés explicitement.
   Comme .testimonial-track, le contenu de .press-track doit être dupliqué
   une fois dans le HTML pour boucler sans coupure. */
.press-marquee {
  overflow: hidden;
  /* Réserve la hauteur des logos (32px) avant leur chargement : sans ça,
     la ligne s'affaisse à 0 puis saute à sa hauteur finale une fois les 20
     images chargées (CLS). */
  min-height: 32px;
  -webkit-mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
}

.press-track {
  display: flex;
  align-items: center;
  width: max-content;
  gap: var(--space-3xl);
  animation: marquee-left var(--duration-marquee) linear infinite;
}

.press-marquee:hover .press-track {
  animation-play-state: paused;
}

.press-track img {
  height: 32px;
  width: auto;
  filter: grayscale(100%);
  opacity: 0.7;
  transition: filter 0.2s ease, opacity 0.2s ease;
}

.press-track img:hover {
  filter: grayscale(0%);
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .press-track {
    animation: none;
  }
}

/* .steps-scrollspy__panel — encart visuel de "Comment ça marche ?" (home
   pro). Un seul .steps-scrollspy__visual visible à la fois (.is-active) ;
   sans JS, seul le premier reste affiché (dégradation propre, comme
   .tag-cycle). Toujours collant (position:sticky) pour rester visible
   pendant qu'on parcourt les étapes, mais le déclencheur du changement
   d'encart diffère par taille d'écran (voir js/steps-scrollspy.js) :
   - desktop : au survol de l'étape (mouseenter) — sticky ici sert juste à
     garder l'encart visible pendant qu'on survole différentes étapes.
   - mobile : au scroll, quand une étape disparaît SOUS l'encart (collé en
     haut) — l'encart bascule alors sur l'étape suivante (JS calcule la
     zone d'exclusion à partir de la hauteur réelle de l'encart, mesurée,
     pas devinée).
   Centrage vertical (desktop) via flex interne plutôt que align-items sur
   le parent : voir .steps-layout dans layout.css — un align-items:center
   sur le parent réduirait l'encart à sa hauteur de contenu et le
   priverait de marge de défilement, empêchant tout collage utile (bug
   constaté, corrigé ici). */
/* top: 100px, pas var(--space-md) (20px) — le header est lui-même sticky
   (~80-87px de haut) : un encart collé trop haut passe SOUS le header une
   fois accroché, et son bord/badge se retrouve masqué (même marge que
   scroll-margin-top ailleurs sur le site pour compenser ce header). Le JS
   (steps-scrollspy.js) lit cette valeur dynamiquement via getComputedStyle
   plutôt que de la dupliquer en dur, pour ne pas se désynchroniser si elle
   change ici. */
.steps-scrollspy__panel {
  position: sticky;
  top: 100px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

@media (max-width: 1023.98px) {
  .steps-scrollspy__panel {
    order: -1;
  }
}

.steps-scrollspy__visual {
  display: none;
}

.steps-scrollspy__visual.is-active {
  display: flex;
}

/* .steps-scrollspy__step — restructuré en repère + contenu (au lieu du
   badge seul au-dessus du texte) pour porter un vrai filet de connexion
   vertical entre les 3 numéros (parcours "1 → 2 → 3" lisible en un coup
   d'œil, pas 3 blocs de texte sans lien visuel).
   L'étape .is-active (survol desktop ou scroll mobile, voir
   js/steps-scrollspy.js) ressort à pleine opacité ; les étapes non actives
   perdent légèrement en intensité (texte, badge et tags ensemble — la
   différence reste volontairement subtile, pas un effet "désactivé"). Le
   badge garde sa couleur accent habituelle (.badge-step) dans tous les
   cas : un badge noir par défaut avait été testé mais donnait un contraste
   trop dur par rapport au reste du bloc atténué.
   L'opacité de survol/focus est portée par .steps-scrollspy__rail et
   .steps-scrollspy__content (pas .steps-scrollspy__step lui-même), pour
   rester indépendante de l'apparition au scroll (.reveal, voir plus haut
   dans ce fichier), qui, elle, anime .steps-scrollspy__step — deux
   animations sur le même élément se seraient écrasées l'une l'autre. */
.steps-scrollspy__step {
  display: flex;
  gap: var(--space-md);
}

.steps-scrollspy__rail,
.steps-scrollspy__content {
  opacity: 0.7;
  transition: opacity 0.2s ease;
}

.steps-scrollspy__step.is-active .steps-scrollspy__rail,
.steps-scrollspy__step.is-active .steps-scrollspy__content {
  opacity: 1;
}

.steps-scrollspy__rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
}

.steps-scrollspy__rail .badge-step {
  box-shadow: 0 0 0 4px transparent;
  transition: box-shadow 0.2s ease;
}

.steps-scrollspy__step.is-active .steps-scrollspy__rail .badge-step {
  /* Anneau léger (teinte de --color-accent à faible opacité) : repère "vous
     êtes ici" en plus du retour à pleine opacité, sans ajouter de nouvelle
     couleur à la charte. */
  box-shadow: 0 0 0 4px rgba(254, 206, 0, 0.25);
}

.steps-scrollspy__connector {
  flex: 1;
  width: 2px;
  min-height: var(--space-md);
  background: var(--color-border);
  margin: var(--space-xs) 0;
}

.steps-scrollspy__step:last-child .steps-scrollspy__connector {
  display: none;
}

.steps-scrollspy__content {
  padding-bottom: var(--space-xl);
}

.steps-scrollspy__step:last-child .steps-scrollspy__content {
  padding-bottom: 0;
}

/* .tag-cycle — mot/expression qui alterne dans une liste (ex: plateformes
   compatibles sous un titre de catégorie, hero /declaration-impots-bourse/).
   Le JS (js/tag-cycle.js) swap le texte et bascule cette classe pour le
   fondu ; en CSS seul, le mot reste affiché sans alterner (dégradation
   propre, pas de contenu qui disparaît si le JS ne charge pas). */
.tag-cycle {
  display: inline-block;
  color: var(--color-accent);
  font-weight: 700;
  transition: opacity 0.25s ease;
}

.tag-cycle--fade {
  opacity: 0;
}

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

/* Sections */

.section {
  padding: var(--space-3xl) 0;
  background: var(--color-background);
}

.section--alt {
  background: var(--color-background-alt);
}

.section--muted {
  background: var(--color-surface-muted);
}

.section--info {
  background: var(--color-background-info);
}

/* .section--dark — "Sécurité et Confidentialité". Couleur validée ronde 3. */
.section--dark {
  background: var(--color-background-dark);
  color: var(--color-text-on-dark);
}

/* .section--dark--bordered — filets haut/bas (même teinte que les filets
   internes de .feature-columns--dark) : referme la section comme un vrai
   panneau délimité plutôt qu'un simple aplat de couleur pleine largeur,
   dans l'esprit des bandeaux "trust bar" bordés (Stripe...). Modificateur
   scopé (pas .section--dark seul) pour ne pas imposer ce filet aux autres
   usages futurs de .section--dark. Fond bleu marine (accent secondaire) au
   lieu du charbon neutre de .section--dark : cette section parle justement
   de confiance/sécurité, la couleur renforce le propos plutôt que de
   décorer — .section--dark reste inchangée pour ses autres usages. */
.section--dark--bordered {
  background: var(--color-accent-secondary);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

/* Marge horizontale plus généreuse sur mobile/tablette (demandé
   explicitement) : le fond marine, contrairement au blanc des autres
   sections, rend les 20px de .content-section (--space-md) très visibles
   contre le bord de l'écran — texte qui semble collé au bord. Desktop
   inchangé (déjà assez d'air via le gap de la grille). */
.section--dark--bordered .content-section {
  padding-left: var(--space-lg);
  padding-right: var(--space-lg);
}

@media (min-width: 640px) {
  .section--dark--bordered .content-section {
    padding-left: var(--space-xl);
    padding-right: var(--space-xl);
  }
}

@media (min-width: 1024px) {
  .section--dark--bordered .content-section {
    padding-left: var(--space-md);
    padding-right: var(--space-md);
  }
}

.section--dark h1,
.section--dark h2,
.section--dark h3,
.section--dark h4 {
  color: var(--color-text-on-dark);
}

.section--dark p {
  color: rgba(255, 255, 255, 0.7);
}

.section--dark .btn-ghost {
  color: var(--color-text-on-dark);
}

/* .table-search — champ de recherche au-dessus de .broker-table (filtre par
   nom de courtier, voir js/broker-search.js). Validé explicitement par
   Sébastien pour /page-courtiers/ (voir docs/missing-components.md). */
.table-search {
  display: block;
  width: 100%;
  max-width: 400px;
  margin: 0 auto var(--space-lg);
  padding: var(--padding-btn-compact);
  font: inherit;
  font-size: var(--font-size-body);
  color: var(--color-text);
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  outline: none;
  transition: border-color 0.2s ease;
}

.table-search:focus {
  border-color: var(--color-tag-cto-bg);
}

.table-search__no-results {
  display: none;
  text-align: center;
  padding: var(--space-lg);
  color: var(--color-text-tertiary);
}

/* .broker-table — tableau des courtiers (/page-courtiers/). En-tête gris,
   lignes zébrées, colonnes Pays/Import centrées — repris du widget
   d'origine, validé explicitement par Sébastien (voir
   docs/missing-components.md). */
.broker-table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.broker-table th,
.broker-table td {
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
}

.broker-table thead tr {
  background: var(--color-secondary-bg);
  font-weight: 600;
  color: var(--color-heading);
}

.broker-table th:nth-child(2),
.broker-table td:nth-child(2),
.broker-table th:nth-child(3),
.broker-table td:nth-child(3) {
  text-align: center;
}

.broker-table tbody tr:nth-child(even) {
  background: var(--color-background-alt);
}

.broker-table tbody tr[hidden] {
  display: none;
}

/* .compare-table — comparatif "Aujourd'hui / Avec DeclarAid Pro" (home
   pro). Couleur volontairement concentrée sur une seule colonne : "Aujourd'hui"
   reste en gris neutre (état, pas une alerte — le rouge est réservé aux
   vraies erreurs ailleurs sur le site), "Avec DeclarAid Pro" porte seule le
   vert + la teinte/bordure marine. Registre plus sobre, cohérent avec une
   audience B2B (CGP/experts-comptables) qu'un vrai/faux rouge-vert. */
.compare-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.compare-table th,
.compare-table td {
  padding: var(--space-md) var(--space-lg);
  text-align: left;
  vertical-align: middle;
}

.compare-table thead th {
  padding-top: var(--space-md);
  padding-bottom: var(--space-md);
}

.compare-table tbody tr + tr td {
  border-top: 1px solid var(--color-border);
}

.compare-table tbody tr {
  transition: background-color .2s ease;
}

.compare-table tbody tr:hover td.compare-table__before {
  background-color: var(--color-background-alt);
}

.compare-table tbody tr:hover td.compare-table__after {
  background-color: rgba(30, 42, 94, 0.08);
}

.compare-table th {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-tertiary);
}

.compare-table__after {
  background: rgba(30, 42, 94, 0.04);
  border-left: 3px solid var(--color-accent-secondary);
}

.compare-table th.compare-table__after {
  color: var(--color-accent-secondary);
}

.compare-table__cell {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: 15px;
  line-height: 1.5;
}

.compare-table__icon-badge {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.compare-table td.compare-table__before .compare-table__icon-badge {
  /* Gris neutre plutôt que rouge : la colonne "aujourd'hui" décrit un
     état, pas une alerte — le rouge est réservé aux vraies erreurs
     ailleurs sur le site (formulaires, /page-conformite/). La couleur
     reste concentrée sur la colonne "Avec DeclarAid Pro". */
  background: var(--color-background-alt);
  color: var(--color-text-tertiary);
}

.compare-table td.compare-table__after .compare-table__icon-badge {
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.compare-table td.compare-table__before {
  color: var(--color-text-secondary);
}

.compare-table td.compare-table__after {
  color: var(--color-heading);
  font-weight: 500;
}

@media (max-width: 640px) {
  /* Sous 640px, une paire avant/après par ligne côte à côte n'a plus assez
     de largeur pour rester confortable (texte écrasé sur 3-5 lignes très
     étroites, voir l'ancienne version resserrée ici même) : chaque paire
     devient une carte en pleine largeur, "aujourd'hui" au-dessus (gris,
     séparé par un filet pointillé) et "avec DeclarAid Pro" en dessous
     (mis en valeur) — le texte retrouve toute la largeur de l'écran pour
     respirer, la table reste un <table> sémantique (accessibilité,
     défilement de secours) mais n'a plus besoin d'être lue en grille. */
  .compare-table,
  .compare-table tbody,
  .compare-table tr,
  .compare-table td {
    display: block;
    width: 100%;
  }

  .compare-table thead {
    /* Les intitulés de colonnes n'ont plus de sens une fois empilé : les
       pastilles ✕/✓ + la mise en valeur de "Avec DeclarAid Pro" portent
       déjà cette distinction. */
    display: none;
  }

  .compare-table tbody tr {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
  }

  .compare-table tbody tr + tr {
    margin-top: var(--space-sm);
  }

  .compare-table tbody tr + tr td {
    /* Le filet horizontal vivait entre deux <tr> (colonnes empilées) ;
       chaque paire est maintenant sa propre carte bordée, ce filet ne
       s'applique plus. */
    border-top: none;
  }

  .compare-table td.compare-table__before,
  .compare-table td.compare-table__after {
    padding: var(--space-sm) var(--space-md);
  }

  .compare-table td.compare-table__before {
    border-bottom: 1px dashed var(--color-border);
  }

  .compare-table__after {
    border-left: none;
    border-top: 3px solid var(--color-accent-secondary);
  }

  .compare-table__cell {
    align-items: flex-start;
  }
}

/* .tag — pilule de catégorie dans .broker-table (une ou plusieurs par
   ligne). Distinct de .badge (réservé aux cards pricing) : 5 couleurs
   propres à cette colonne, non réutilisables ailleurs sans revalidation. */
.tag {
  display: inline-block;
  padding: 2px 8px;
  margin: 2px;
  border-radius: var(--radius-sm);
  font-size: var(--font-size-xs);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--color-tag-text);
}

.tag--cto { background: var(--color-tag-cto-bg); }
.tag--pea { background: var(--color-tag-pea-bg); }
.tag--crypto { background: var(--color-tag-crypto-bg); }
.tag--crowdfunding { background: var(--color-tag-crowdfunding-bg); }
.tag--compte { background: var(--color-tag-compte-bg); }
