/*
 * Mise en page structurelle — grilles/flex de positionnement propres à
 * chaque page/composant de layout (header, footer, hero...). Ne définit
 * AUCUNE valeur de design (couleur, radius, ombre) : uniquement des
 * dimensions/espacements, toujours via var(--space-*) de tokens.css.
 * tokens.css et base.css restent la seule source de vérité pour la DA.
 */

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-md);
}

/* Header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--color-background);
  border-bottom: 1px solid var(--color-border);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  max-width: 1400px;
  margin: 0 auto;
  padding: var(--space-sm) var(--space-md);
}

.site-header__logo img {
  display: block;
  height: 47px;
  width: auto;
}

.site-nav {
  display: none;
  align-items: center;
  gap: var(--space-lg);
}

/* Item de nav (lien plein ou déclencheur de sous-menu) — fond gris au survol */
.site-nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  background: none;
  border: none;
  font: inherit;
  font-size: 14px;
  color: inherit;
  cursor: pointer;
  text-decoration: none;
}

.site-nav__link:hover {
  background: var(--color-background-alt);
  color: var(--color-accent-secondary);
}

.site-nav__chevron {
  transition: transform 0.15s ease;
}

.site-nav__dropdown:hover .site-nav__chevron,
.site-nav__dropdown:focus-within .site-nav__chevron {
  transform: rotate(180deg);
}

.site-nav__dropdown {
  position: relative;
}

/* Sous-menu : apparaît au survol (ou au focus clavier), pas au clic */
.site-nav__dropdown ul {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 60;
  margin: 0;
  padding: var(--space-xs);
  list-style: none;
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
  min-width: 200px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
}

.site-nav__dropdown:hover ul,
.site-nav__dropdown:focus-within ul {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.site-nav__dropdown ul a {
  display: block;
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  font-size: 14px;
  color: inherit;
  text-decoration: none;
}

.site-nav__dropdown ul a:hover {
  background: var(--color-background-alt);
}

.site-nav__dropdown li + li {
  margin-top: var(--space-2xs);
}

.site-header__actions {
  display: none;
  align-items: center;
  gap: var(--space-md);
}

/* .site-header__mobile-toggle — panneau plein écran (pas un simple
   dropdown inline) : un ancien essai en <details> ouvert dans le flux
   normal du header (lui-même sticky) débordait horizontalement dès que le
   contenu du menu dépassait la largeur restante à côté du logo (ex: le
   bouton "Réserver une démo" en white-space:nowrap, voir .btn plus bas) —
   le menu se retrouvait coupé sur le bord droit de l'écran. Un panneau
   fixed pleine largeur/hauteur ne dépend plus de la largeur du logo à côté
   de lui : plus de conflit possible. z-index élevé pour rester cliquable
   au-dessus du panneau une fois ouvert (fermeture en re-cliquant dessus). */
.site-header__mobile-toggle {
  position: relative;
  z-index: 110;
  margin-left: auto;
}

/* Zone cliquable ~44px (icône 20px + marge négative en bleed, même
   technique que .card-faq > summary). */
.site-header__mobile-toggle summary {
  position: relative;
  /* Doit dépasser le z-index de <nav> (100) : sans z-index propre ici, un
     enfant positionné plus tard dans le DOM (nav) passe devant même si le
     parent .site-header__mobile-toggle a lui-même un z-index élevé — le
     z-index du parent ne règle que l'ordre entre .mobile-toggle et le
     reste de la page, pas l'ordre entre ses propres enfants. Sans ça, le
     panneau ouvert recouvre le bouton et on ne peut plus recliquer pour
     fermer. */
  z-index: 101;
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -12px -12px -12px 0;
}

.site-header__mobile-toggle summary::-webkit-details-marker {
  display: none;
}

/* Icône hamburger (3 barres) qui se transforme en croix quand ouvert —
   seul signal qu'il faut au panneau plein écran pour se fermer (pas de
   texte "Fermer" séparé). */
.site-header__mobile-icon {
  position: relative;
  width: 20px;
  height: 14px;
  flex-shrink: 0;
}

.site-header__mobile-icon span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: 1px;
  transition: transform 0.2s ease, opacity 0.15s ease, top 0.2s ease;
}

.site-header__mobile-icon span:nth-child(1) {
  top: 0;
}

.site-header__mobile-icon span:nth-child(2) {
  top: 6px;
}

.site-header__mobile-icon span:nth-child(3) {
  top: 12px;
}

.site-header__mobile-toggle[open] .site-header__mobile-icon span:nth-child(1) {
  top: 6px;
  transform: rotate(45deg);
}

.site-header__mobile-toggle[open] .site-header__mobile-icon span:nth-child(2) {
  opacity: 0;
}

.site-header__mobile-toggle[open] .site-header__mobile-icon span:nth-child(3) {
  top: 6px;
  transform: rotate(-45deg);
}

/* Filet de sécurité : le comportement natif de <details> (masquer le
   contenu autre que <summary> quand fermé) ne s'applique pas de façon
   fiable partout — sans cette règle, le panneau resterait présent en mise
   en page même fermé (même bug déjà identifié et corrigé sur
   declaraid-web-site, audit responsive du 2026-09-18). Sert aussi de repli
   sans JS : le panneau apparaît/disparaît instantanément, juste sans
   transition (voir @media (scripting: enabled) dans base.css). */
.site-header__mobile-toggle:not([open]) nav {
  display: none;
}

.site-header__mobile-toggle nav {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 88px var(--space-lg) var(--space-xl);
}

.site-header__mobile-nav-logo {
  margin-bottom: var(--space-xl);
}

.site-header__mobile-toggle ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

/* :not(.btn) — sans l'exclusion, ces règles (display:block, padding
   recalculé) gagnent sur .btn par spécificité et cassent son propre
   centrage flex interne (justify-content:center) : le texte des boutons
   "Réserver une démo"/"Vous êtes un particulier ?" se retrouvait collé en
   haut à gauche de la pilule au lieu d'être centré. */
.site-header__mobile-toggle li a:not(.btn) {
  display: block;
  padding: var(--space-sm) 0;
  font-size: 18px;
}

.site-header__mobile-toggle li:has(.btn) {
  margin-top: var(--space-md);
}

.site-header__mobile-toggle li .btn {
  width: 100%;
}

/* Le panneau doit rester accessible/fonctionnel même sans JS pour poser la
   classe .is-open (dégradation propre) : la transition n'est donc câblée
   que si du JS tourne réellement — sinon opacity:0 resterait bloqué à 0
   pour toujours, panneau invisible bien qu'ouvert. */
@media (scripting: enabled) {
  .site-header__mobile-toggle nav {
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity 0.22s ease, transform 0.22s ease;
  }

  .site-header__mobile-toggle nav.is-open {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Bloque le scroll de la page derrière le panneau plein écran tant qu'il
   est ouvert (posé par mobile-menu.js). */
body.has-mobile-nav-open {
  overflow: hidden;
}

/* Bascule nav mobile -> desktop à 1200px, pas 1024px comme le reste du
   site (seule exception) : le contenu du header (logo + 4 liens + 2 CTA)
   mesure ~1133px de large sur une seule ligne (logo 193 + nav 452 +
   actions 408 + gaps/padding) — en bascule desktop dès 1024px, les CTA
   "Vous êtes un particulier ?"/"Réserver une démo" n'ont plus la place et
   wrappent leur texte sur 2 lignes dans leur pilule (ou débordent une fois
   ce wrap empêché, voir .btn { white-space: nowrap } dans base.css). */
@media (min-width: 1200px) {
  .site-nav,
  .site-header__actions {
    display: flex;
  }
  .site-header__mobile-toggle {
    display: none;
  }
}

/* Hero */

/* Même largeur que .site-header__inner (max-width: 1400px) et que le hero
   de la home declaraid-web-site (référence B2C, identique) — corrigé après
   un essai en pleine largeur qui dépassait la largeur du header, ce n'était
   pas l'effet voulu. */
.hero {
  padding: var(--space-xl) var(--space-md);
  max-width: 1400px;
  margin: 0 auto;
}

.hero__grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.hero__badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
}

.hero h1 {
  margin-bottom: var(--space-md);
}

.hero__filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin: var(--space-lg) 0;
}

.hero__ctas,
.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
}

/* Wrapper vidéo responsive 16:9 (iframe pleine taille en position absolue).
   .hero__video (hero) et .video-embed (plus bas, contenu éditorial
   d'article) partagent cette même mécanique — seul .video-embed ajoute une
   marge verticale, utile en plein corps de texte. */
.hero__video,
.video-embed {
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.hero__video iframe,
.video-embed iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* .hero__press et .press-grid (plus bas, section Presse) partagent la même
   base flex — seul .hero__press ajoute une marge (collé sous les CTAs du
   hero) et .press-grid centre son contenu (section autonome). */
.hero__press,
.press-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xl);
}

.hero__press {
  margin-top: var(--space-xl);
}

/* Grille de cards logo (hero /declaration-impot-crypto/ : plateformes
   compatibles eToro/Revolut/Coinbase/... — chaque logo dans une .card
   existante, ici seulement la grille qui les positionne). Générique,
   réutilisable par les pages de service soeurs (bourse/crowdfunding/trading). */
.logo-card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
}

.logo-card-grid .card {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100px;
}

.logo-card-grid .card img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* `justify-content: space-between` avait été essayé pour épingler le
   visuel au bord droit du hero : sur un hero large (1400px) avec un texte
   qui ne dépasse jamais ~600px de large, ça laissait un vide mort de
   400px+ entre les deux blocs — corrigé. `gap` fixe entre les deux blocs,
   et le groupe (texte + visuel) est centré dans le hero plutôt que collé à
   gauche : l'espace excédentaire se répartit des deux côtés au lieu de
   s'accumuler uniquement à droite — plus équilibré sur grand écran. */
@media (min-width: 1024px) {
  .hero__grid {
    flex-direction: row;
    justify-content: center;
    align-items: center;
    gap: var(--space-3xl);
  }
}

.hero__copy {
  max-width: 640px;
}

/* .hero__visual — largeur fixe cohérente avec un document au format A4
   (aspect-ratio 210/297, voir plus bas) plutôt qu'une fraction de grille
   qui grandirait avec la largeur du hero. Centré sur mobile ; largeur fixe
   sur desktop, juste après le texte (pas épinglé au bord). */
.hero__visual {
  width: 100%;
  max-width: 360px;
  margin: 0 auto;
}

@media (min-width: 1024px) {
  .hero__visual {
    flex-shrink: 0;
    width: 400px;
    max-width: 400px;
    margin: 0;
  }
}

/* Légère rotation + ombre portée en plusieurs couches (proche + diffuse +
   ambiante) sur la card du hero : la pose visuellement sur la page au lieu
   de la coller à plat, plus de profondeur qu'une simple .card standard.
   Demandé explicitement pour donner du style au hero. */
.hero__visual .card {
  transform: rotate(2deg);
  box-shadow:
    0 4px 8px rgba(0, 0, 0, 0.06),
    0 16px 32px rgba(0, 0, 0, 0.1),
    0 40px 64px rgba(0, 0, 0, 0.08);
}

/* Footer */

.site-footer {
  background: var(--color-background);
  padding: var(--space-xl) var(--space-md) var(--space-md);
}

/* Sans ça, l'image reste en display:inline (défaut) : sa boîte de ligne
   colle à la hauteur du texte environnant (~17px) au lieu de la hauteur
   réelle du logo (41px) — zone cliquable bien plus petite que le logo
   visible. Même correctif que .site-header__logo img plus haut. */
.site-footer__logo {
  display: inline-block;
}

.site-footer__logo img {
  display: block;
  height: 41px;
  width: auto;
}

.site-footer__top {
  max-width: 1400px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-xl);
  padding-bottom: var(--space-xl);
}

.site-footer__social {
  display: flex;
  gap: var(--space-2xs);
  list-style: none;
  padding: 0;
  margin: var(--space-md) 0 0;
}

/* L'icône SVG (20px) reste petite, mais la zone cliquable de son lien est
   élargie à ~40px (padding) : sans ça, le lien en display:inline colle à
   la taille exacte du SVG — bien en dessous d'une cible tactile confortable. */
.site-footer__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin: -10px;
}

.site-footer__heading {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--color-text-tertiary);
  margin: 0 0 var(--space-sm);
}

.site-footer__col ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.site-footer__col li + li {
  margin-top: var(--space-sm);
}

.site-footer__disclaimer {
  max-width: 1400px;
  margin: 0 auto;
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
  font-size: 13px;
  color: var(--color-text-tertiary);
}

.site-footer__copyright {
  max-width: 1400px;
  margin: var(--space-md) auto 0;
  text-align: right;
  font-size: 13px;
  color: var(--color-text-tertiary);
}

@media (min-width: 1024px) {
  /* 2 colonnes (brand + nav) depuis que le footer pro ne reprend plus les
     4 colonnes B2C (Services/Offres/Courtiers/Ressources) — voir footer du
     site B2C (declaraid-web-site) pour la version à 5 colonnes d'origine. */
  .site-footer__top {
    grid-template-columns: 1.4fr 1fr;
  }
}

/* Sections génériques de contenu (stats, features...) */

.content-section {
  /* Le padding vertical vient de .section (--space-3xl) — ici seulement
     l'horizontal, pour ne pas doubler l'écart entre sections. */
  padding: 0 var(--space-md);
  max-width: 1200px;
  margin: 0 auto;
  text-align: center;
}

.content-section__eyebrow {
  color: var(--color-text-tertiary);
  font-size: 14px;
  margin: 0 0 var(--space-xs);
}

.content-section__lead {
  max-width: 640px;
  margin: 0 auto var(--space-xl);
}

/* .page-hero — même voile radial extrêmement subtil que .credibility-bar
   ci-dessous (même technique, même dosage ~2-3%), pour que le chapô et le
   bandeau de confiance qui le suit s'enchaînent visuellement plutôt que de
   juxtaposer un aplat blanc pur puis un fond légèrement texturé. */
.page-hero {
  position: relative;
}

.page-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 900px 320px at 50% 0%, rgba(0, 0, 0, 0.025), transparent 70%);
  pointer-events: none;
}

/* .credibility-bar — bandeau de confiance sous le hero (home pro). Pas de
   card ni de panneau encadré (ni ombre, ni bordure fermée, ni coins
   arrondis) : juste des filets horizontaux/verticaux directement sur le
   fond de la page, à la manière des bandeaux de stats "trust bar" des
   sites SaaS de référence (Stripe...) — la donnée porte la structure, rien
   ne la fait flotter dans une boîte. Empilé sur mobile (filet horizontal),
   3 colonnes à filets verticaux à partir de 1024px.
   Chiffres en chasse fixe (tabular-nums) : nécessaire pour que le compteur
   animé (js/count-up.js) ne fasse pas vibrer la largeur du texte pendant
   que les chiffres défilent. Libellés en petites capitales espacées, façon
   fiche technique/dashboard plutôt que texte de légende classique.
   Au survol d'un chiffre : seul moment de couleur de tout le bandeau — le
   chiffre lui-même passe en jaune accent, rien d'autre ne bouge (pas de
   fond, pas de filet). Volontairement minimal. */
.credibility-bar {
  position: relative;
  background: var(--color-background);
  padding: var(--space-xl) var(--space-md);
}

/* Voile radial extrêmement subtil (~1-2 % d'opacité) pour donner un peu de
   profondeur au fond blanc sans y introduire une vraie couleur. */
.credibility-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 800px 240px at 50% 0%, rgba(0, 0, 0, 0.02), transparent 70%);
  pointer-events: none;
}

.credibility-bar__panel {
  position: relative;
  max-width: 900px;
  margin: 0 auto;
}

.credibility-bar__stats {
  display: grid;
  grid-template-columns: 1fr;
}

.credibility-bar__stat {
  text-align: center;
  padding: var(--space-lg) var(--space-md);
}

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

.credibility-bar__value {
  margin: 0;
  font-size: 36px;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
  transition: color 0.15s ease;
}

.credibility-bar__stat:hover .credibility-bar__value {
  color: var(--color-accent);
}

.credibility-bar__label {
  margin: var(--space-xs) 0 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  text-wrap: balance;
}

.credibility-bar__hosting {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  margin: 0;
  padding: var(--space-md) 0 0;
  text-align: center;
  font-size: 13px;
  color: var(--color-text-secondary);
}

/* 3 colonnes dès 640px (tablette) : le seul point de rupture du site est à
   1024px, ce qui forçait une tablette (iPad portrait 768px...) à recevoir
   la mise en page mobile empilée alors qu'elle a largement la place pour 3
   colonnes de chiffres — ajouté après audit responsive. */
@media (min-width: 640px) {
  .credibility-bar__stats {
    grid-template-columns: repeat(3, 1fr);
  }

  /* .credibility-bar__stats--2 — variante à 2 chiffres (/conformite/, après
     retrait du "prestataires certifiés" jugé trop vague en tête de page,
     déjà couvert en détail par la section infrastructure plus bas). */
  .credibility-bar__stats--2 {
    grid-template-columns: repeat(2, 1fr);
    max-width: 560px;
    margin: 0 auto;
  }

  .credibility-bar__stat + .credibility-bar__stat {
    border-top: none;
    border-left: 1px solid var(--color-border);
  }
}

/* Stats ("Des résultats qui parlent") */

.stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-lg);
  max-width: 1000px;
  margin: 0 auto;
}

.stats-grid__item h2 {
  margin-bottom: var(--space-2xs);
}

.stats-grid__item p {
  margin: 0;
}

@media (min-width: 1024px) {
  .stats-grid {
    grid-template-columns: repeat(5, 1fr);
  }
}

/* Colonnes à 3 (features "C'est quoi DeclarAid ?") */

.feature-columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-xl);
  text-align: center;
  margin: 0 auto var(--space-xl);
  max-width: 1000px;
}

/* Léger soulèvement au survol (réassurance, home pro) — micro-interaction
   courante sur les grilles de features SaaS B2B, donne un retour "vivant"
   à des cards par ailleurs statiques. Scopé à .feature-columns__item.card-
   marketing (pas .card-marketing en général) pour ne pas affecter les
   autres usages de la card (ex: tarification) — et pas la variante
   .feature-columns--dark (panneau technique sans cards, voir plus bas). */
/* display:flex column + hauteur 100% (le grid parent étire déjà les items
   à la hauteur de la ligne) : aligne "Voir le détail" au même niveau entre
   cards dont les paragraphes font 2 ou 3 lignes. */
.feature-columns__item.card-marketing {
  display: flex;
  flex-direction: column;
  height: 100%;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.feature-columns__item.card-marketing:hover {
  transform: translateY(-4px);
  /* Variante plus prononcée de --shadow-card-marketing pour l'état survol. */
  box-shadow: rgba(0, 0, 0, 0.35) 0px 12px 28px -6px;
}

.feature-columns__item ul {
  list-style: none;
  padding: 0;
  margin: var(--space-md) 0 0;
  text-align: left;
  display: inline-block;
}

.feature-columns__item li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  margin-bottom: var(--space-sm);
}

.feature-columns__item li svg {
  flex-shrink: 0;
  margin-top: 3px;
  color: var(--color-accent);
}

/* 3 colonnes dès 640px (tablette) — même raisonnement que
   .credibility-bar__stats ci-dessus : 3 courtes cards passent très bien
   sur un iPad portrait (768px), pas besoin d'attendre 1024px. */
@media (min-width: 640px) {
  .feature-columns {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* .feature-columns--4 — grille 2×2 ("Nos engagements", /page-conformite/),
   items en .card-marketing (cards à ombre ambiante, registre "SaaS premium"
   plutôt que l'encadré générique .card). Texte aligné à gauche (au lieu du
   centrage par défaut de .feature-columns). 2 colonnes dès 640px et jusqu'à
   la largeur max du conteneur (920px) : à 4 colonnes pleines, chaque carte
   ne fait plus que ~220px et le texte wrappe sur 4-5 lignes — beaucoup
   moins aéré/pro qu'une carte deux fois plus large qui tient en 2 lignes.
   Gap et padding de card élargis (cf. plus bas) pour la même raison. */
.feature-columns--4 {
  text-align: left;
  gap: var(--space-2xl);
}

@media (min-width: 640px) {
  .feature-columns--4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Registre "fiche technique" (cf. .credibility-bar plus haut) plutôt que la
   card flottante générique : filet fin en plus de l'ombre pour un bord net,
   ombre resserrée/plus basse (moins "posée en l'air"), et léger accent en
   haut de card au survol — signal d'activation discret, cohérent avec le
   bleu marine de l'icon-badge au survol (voir .feature-columns__item.card-
   marketing:hover .icon-badge). */
.feature-columns--4 .card-marketing {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--color-border);
  padding: var(--space-2xl);
  box-shadow: rgba(23, 23, 23, 0.06) 0px 2px 10px -2px;
}

.feature-columns--4 .card-marketing::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--color-accent-secondary);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease;
}

.feature-columns--4 .card-marketing:hover::before {
  transform: scaleX(1);
}

.feature-columns--4 .card-marketing:hover {
  box-shadow: rgba(23, 23, 23, 0.1) 0px 8px 20px -6px;
}

/* .feature-columns--dark — variante "panneau technique" (réassurance, home
   pro, dans .section--dark) : pas de cards flottantes ni d'ombre, un seul
   panneau sombre divisé par des filets fins entre colonnes — registre plus
   sobre/infra que les cards blanches utilisées ailleurs sur la page.
   Contenu aligné à gauche (au lieu du centrage par défaut de
   .feature-columns) : lecture "fiche technique" plutôt que "bloc marketing". */
.feature-columns--dark {
  text-align: left;
}

.feature-columns--dark .feature-columns__item {
  padding-top: var(--space-lg);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.feature-columns--dark .feature-columns__item:first-child {
  padding-top: 0;
  border-top: none;
}

/* Synchronisé avec le passage à 3 colonnes de .feature-columns (640px,
   voir plus haut) — sinon les filets resteraient horizontaux dans une
   grille déjà passée à 3 colonnes entre 640 et 1023px. */
@media (min-width: 640px) {
  .feature-columns--dark .feature-columns__item {
    padding-top: 0;
    padding-left: var(--space-xl);
    border-top: none;
    border-left: 1px solid rgba(255, 255, 255, 0.12);
  }

  .feature-columns--dark .feature-columns__item:first-child {
    padding-left: 0;
    border-left: none;
  }
}

.feature-columns--dark .icon-outline {
  transition: color 0.2s ease;
}

.feature-columns--dark .feature-columns__item:hover .icon-outline {
  color: var(--color-text-on-dark);
}

/* .section-divider — séparateur horizontal entre deux sections (hero /
   "Courtiers étrangers", /page-conformite/), validé Sébastien */
.section-divider {
  max-width: 1200px;
  margin: 0 auto;
  border: none;
  border-top: 1px solid var(--color-border);
}

/* Étapes (4 colonnes, "Comment ça marche ?" / dossier fiscal) */

/* Une seule colonne à toutes les tailles d'écran, y compris desktop —
   confirmé sur l'original (grid-template-columns à une seule valeur même
   à 1440px de large), pas de bascule en 4 colonnes. */
.steps-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-xl);
  text-align: center;
  max-width: 720px;
  margin: 0 auto;
}

/* .steps-layout — variante 2 colonnes de "Comment ça marche ?" (home pro) :
   étapes à gauche + encart visuel qui change par étape à droite (voir
   .steps-scrollspy__panel dans base.css). .steps-grid reste inchangée
   (centrée, colonne unique — voir commentaire ci-dessus, toujours valable
   pour son autre usage) ; l'override ci-dessous est scopé à l'intérieur de
   .steps-layout uniquement.

   Mobile : flex (pas grid) — un item CSS Grid auto-placé dans sa propre
   ligne n'a pas de "hauteur partagée" pour que position:sticky ait de la
   marge pour coller (sa ligne ne fait que sa propre hauteur). En flex column
   partagé, l'encart (réordonné en premier via `order`, voir base.css) colle
   dans la hauteur totale du conteneur (encart + étapes), comme un sommaire
   sticky classique. Desktop : grid 2 colonnes, l'encart colle nativement
   dans la hauteur de la ligne (déterminée par la colonne étapes, plus
   grande) — `order` n'a alors aucun effet, non défini à cette taille. */
.steps-layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-md);
}

.steps-layout .steps-grid {
  text-align: left;
  max-width: none;
  margin: 0;
  /* Le filet de connexion (.steps-scrollspy__connector) assure l'espacement
     vertical entre étapes ; un gap ici le couperait par un blanc entre
     chaque ligne de la grille. */
  gap: 0;
}

@media (min-width: 1024px) {
  /* align-items reste stretch (défaut) — .steps-scrollspy__panel doit
     occuper toute la hauteur de la ligne pour que position:sticky ait de la
     marge sur laquelle coller en scrollant ; avec align-items:center,
     l'encart se réduit à sa hauteur de contenu et n'a presque plus de marge
     de défilement, ce qui empêchait le changement d'étape d'être visible en
     scrollant. Le centrage vertical de l'encart se fait maintenant à
     l'intérieur de .steps-scrollspy__panel (base.css), pas ici. */
  .steps-layout {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
  }
}

/* Team grid */

.team-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-lg);
  max-width: 900px;
  margin: 0 auto;
}

.team-grid img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius-lg);
  display: block;
}

@media (min-width: 1024px) {
  .team-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Presse (logos) */

.press-grid {
  justify-content: center;
}

/* Dimensions par logo posées en attribut width/height sur chaque <img>
   (mesurées sur l'original — pas de ratio uniforme entre logos). Partagé
   entre le hero (.hero__press) et la section Presse autonome (.press-grid). */
.hero__press img,
.press-grid img {
  height: auto;
  display: block;
}

/* Conformité légale (2 colonnes texte / photo) */

.split-section {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-xl);
  align-items: center;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-md);
}

.split-section__checklist {
  list-style: none;
  padding: 0;
  margin: var(--space-md) 0;
}

.split-section__checklist li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  margin-bottom: var(--space-sm);
}

.split-section__checklist li svg {
  flex-shrink: 0;
  margin-top: 3px;
}

.split-section__photo {
  position: relative;
}

.split-section__photo img {
  width: 100%;
  border-radius: var(--radius-lg);
  display: block;
}

/* Card flottante superposée à la photo (ex: "Tous vos justificatifs
   inclus..." sur la photo de /declaration-impot-crypto/), réutilise
   .split-section__checklist à l'intérieur. */
.split-section__photo-badge {
  position: absolute;
  left: calc(-1 * var(--space-lg));
  bottom: var(--space-lg);
  max-width: 260px;
  background: var(--color-background);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card-marketing);
  padding: var(--space-md) var(--space-lg);
  display: none;
}

@media (min-width: 1024px) {
  .split-section__photo-badge {
    display: block;
  }
}

.split-section__seal {
  width: 112px;
  height: auto;
  margin-bottom: var(--space-md);
}

@media (min-width: 1024px) {
  /* Colonne texte plus large que la colonne photo (ronde 5 : la photo
     prenait trop de place par rapport à l'original). */
  .split-section {
    grid-template-columns: 1.3fr 1fr;
  }
  .split-section--reverse {
    direction: rtl;
  }
  .split-section--reverse > * {
    direction: ltr;
  }
}

/* Panneau clair à icônes (Isolation Bancaire / Souveraineté et
   localisation des données / Chiffrement de Grade Militaire — même
   pattern répété 3x sous la section sombre "Sécurité et Confidentialité").
   Padding mesuré ~50px sur l'original (--space-2xl). */

.isolation-panel {
  background: var(--color-background-alt);
  border-radius: var(--radius-lg);
  padding: var(--space-2xl);
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
  align-items: center;
}

.isolation-panel + .isolation-panel {
  margin-top: var(--space-lg);
}

/* Panneau "Chiffrement de Grade Militaire" : fond gris plus foncé que les
   2 autres panneaux — mesuré/validé ronde 5 (voir --color-background-alt-dark). */
.isolation-panel--reverse {
  background: var(--color-background-alt-dark);
}

.isolation-panel__cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

/* Icône ligne simple (pas de cercle plein) utilisée dans ces sous-cards */
.icon-outline {
  color: var(--color-text-tertiary);
  display: inline-block;
  margin-bottom: var(--space-sm);
}

@media (min-width: 1024px) {
  .isolation-panel {
    grid-template-columns: 1fr 2fr;
  }
  .isolation-panel--reverse {
    grid-template-columns: 2fr 1fr;
  }
  .isolation-panel--reverse > :first-child {
    order: 2;
  }
  .isolation-panel__cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Personas ("pour toutes les personnes qui investissent") */

.persona-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
  max-width: 1100px;
  margin: 0 auto;
}

.persona-card {
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  text-align: left;
}

/* 4 fonds pastel distincts, mesurés/validés ronde 5 — le 4e réutilise
   --color-success-bg (déjà identique), pas de nouveau token pour celui-ci. */
.persona-card--yellow { background: var(--color-persona-yellow-bg); }
.persona-card--blue { background: var(--color-persona-blue-bg); }
.persona-card--pink { background: var(--color-persona-pink-bg); }
.persona-card--green { background: var(--color-success-bg); }

@media (min-width: 1024px) {
  .persona-grid {
    /* minmax(0, 1fr), pas juste 1fr : un enfant au contenu large et
       non-cassable (ex: badge nowrap des cards pricing, /nos-offres/) sinon
       étire sa colonne au-delà des 3 autres via le min-width:auto implicite
       des pistes 1fr — cassait l'alignement des checklists entre les 4
       offres. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* CTA bandeau centré */

.cta-banner {
  text-align: center;
  padding: var(--space-xl) var(--space-md);
}

/* .cta-banner__avatar — photo de Sébastien (fondateur) au-dessus du CTA de
   démo finale : personnalise la prise de rendez-vous (on sait avec qui on
   parle) plutôt qu'un CTA anonyme. Même traitement (rond, 1 bordure fine)
   que les avatars .card-quote/.card-testimonial déjà utilisés ailleurs sur
   la marque DeclarAid. */
.cta-banner__avatar {
  width: var(--size-avatar-md);
  height: var(--size-avatar-md);
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--color-border);
  margin: 0 auto var(--space-md);
}

/* Article de blog — sommaire + CTA en colonne latérale collante à côté du
   corps de l'article (desktop), empilés en pleine largeur en dessous de
   1024px. Composant ajouté suite à demande explicite de Sébastien (voir
   docs/missing-components.md) — les cards elles-mêmes (.card-toc) ne
   changent pas, seule la disposition est nouvelle. */
.article-layout {
  display: block;
  align-items: flex-start;
  gap: var(--space-xl);
}

.article-layout__sidebar > .card-toc + .card-toc {
  margin-top: var(--space-lg);
}

@media (min-width: 1024px) {
  .article-layout {
    display: flex;
  }

  /* La colonne latérale est bornée à la hauteur de l'écran : le sommaire
     (1er .card-toc) défile en interne si la liste est trop longue, la
     carte CTA (2e .card-toc) garde sa taille naturelle et reste toujours
     visible en entier — jamais rognée par la limite de hauteur. */
  .article-layout__sidebar {
    flex: 0 0 280px;
    position: sticky;
    top: var(--space-lg);
    align-self: flex-start;
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - var(--space-lg) * 2);
  }

  .article-layout__sidebar > .card-toc:first-child {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
  }

  .article-layout__sidebar > .card-toc:first-child nav {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
  }

  .article-layout__sidebar > .card-toc + .card-toc {
    flex-shrink: 0;
  }

  .article-layout__content {
    flex: 1 1 auto;
    min-width: 0;
  }
}

/* Grille "Derniers articles" (/articles-blog/) — 1 colonne en dessous de
   1024px, 3 colonnes à partir de 1024px, confirmé par Sébastien. Layout
   seul (aucune valeur de design), voir .card-blog dans base.css pour le
   style des cards elles-mêmes. */
.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}

/* 2 colonnes dès la tablette (640px) plutôt que d'attendre 1024px — même
   raisonnement que .credibility-bar__stats/.feature-columns (voir plus
   haut) : pas de raison de rester en 1 colonne sur un iPad portrait. */
@media (min-width: 640px) {
  .card-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .card-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Tableau des courtiers (/page-courtiers/) — wrapper de défilement
   horizontal pour ne pas casser la mise en page sur petit écran. Aucune
   valeur de design ici, voir .broker-table dans base.css. */
.table-scroll {
  overflow-x: auto;
}

/* Vidéo YouTube intégrée en plein corps d'article (guides longs) — mécanique
   16:9 partagée avec .hero__video, voir plus haut. Dédié au contenu
   éditorial (.prose) plutôt qu'au hero : seul ajout ici, une marge
   verticale. Voir docs/missing-components.md. */
.video-embed {
  margin: var(--space-xl) 0;
}

/* FAQ — accordion natif <details>/<summary> sur .card-faq, marqueur +/- */

/* Étend la zone cliquable au bandeau entier de .card-faq (pas seulement le
   texte/marqueur) : marge négative = padding de la card pour que <summary>
   occupe toute sa boîte, puis padding équivalent pour retrouver visuellement
   le même espacement — <summary> est le seul déclencheur natif du toggle. */
details.card-faq > summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin: calc(-1 * var(--space-md));
  padding: var(--space-md);
  cursor: pointer;
}

details.card-faq > summary::-webkit-details-marker {
  display: none;
}

details.card-faq > summary::after {
  content: '+';
  flex-shrink: 0;
  font-size: 20px;
  color: var(--color-text-tertiary);
}

details.card-faq[open] > summary::after {
  content: '\2212';
}

/* .accordion-group — regroupe une liste de .card-faq (FAQ et détail
   technique de /conformite/) : espace vertical entre items + scope pour
   faq-accordion.js (un seul <details> ouvert à la fois par groupe). */
.accordion-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* Réservation (/reservation/) — iframe de prise de rendez-vous Google
   Calendar. Hauteur plus généreuse que le rendu par défaut de l'embed
   Google pour limiter le scroll interne ; plus grande sur desktop, où
   l'espace vertical disponible sous le header est plus large. */
.reservation__iframe {
  display: block;
  border: 0;
  margin-bottom: var(--space-2xl);
  height: 1300px;
}

/* Le widget Google Calendar passe à une mise en page calendrier+créneaux
   côte à côte (plus compacte) dès qu'il a assez de largeur — à 768px, une
   hauteur pensée pour un mobile étroit (1600px, où tout est empilé)
   laissait ~700px de vide avant le footer. Point de rupture propre au
   composant, pas aligné sur les 640/1024px du reste du site : c'est
   Google qui décide de son seuil de mise en page, pas nous, donc mesuré
   empiriquement sur le rendu réel du widget. */
@media (min-width: 640px) {
  .reservation__iframe {
    height: 730px;
  }
}

@media (min-width: 1024px) {
  .reservation__iframe {
    height: 900px;
    margin-bottom: var(--space-xs);
  }
}
