/* ==========================================================================
   cgexpertools.com — feuille de style unique
   --------------------------------------------------------------------------
   Direction : l'univers du graphisme broadcast. Le motif récurrent est la
   "safe area" d'un moniteur de régie — cadre pointillé + équerres d'angle.
   Le logo isométrique existant fournit la géométrie et la palette.

   Sommaire
     01. Tokens (clair / sombre)
     02. Reset et bases
     03. Typographie
     04. Utilitaires et accessibilité
     05. En-tête et navigation
     06. Sélecteur de thème
     07. Hero "viewport"
     08. Logo animé
     09. Cartes de contenu
     10. Pages légales (sections numérotées)
     11. Newsletters
     12. Statistiques
     13. Pied de page
     14. Animations d'apparition
     15. Bidirectionnalité et scripts non latins
   ========================================================================== */

/* ==========================================================================
   01. TOKENS
   ========================================================================== */

:root {
  color-scheme: light;

  /* Palette claire — le périwinkle de marque, assombri pour passer WCAG AA */
  --ink:        #16182b;
  --ink-soft:   #474b66;
  --ink-faint:  #656a88;   /* 4.9:1 sur --paper */
  --paper:      #f4f5fb;
  --paper-deep: #eaecf7;
  --surface:    #ffffff;
  --surface-2:  #fafbff;
  --line:       #dee1f0;
  --line-soft:  #eaecf7;

  --iris:       #4f4dd4;  /* 6.4:1 sur blanc */
  --iris-deep:  #3b39ad;
  --iris-tint:  #eeeefc;
  --plum:       #8a3aad;
  --mint:       #0a6f61;   /* 6.1:1 avec du blanc */
  --pulse:      #0f90b6;   /* le cyan du logo, assez soutenu pour du fond clair */

  --shadow-sm:  0 1px 2px rgba(22, 24, 43, .06), 0 2px 8px rgba(22, 24, 43, .04);
  --shadow-md:  0 2px 4px rgba(22, 24, 43, .05), 0 12px 28px -8px rgba(22, 24, 43, .12);
  --shadow-lg:  0 4px 8px rgba(22, 24, 43, .05), 0 24px 48px -12px rgba(79, 77, 212, .22);

  /* Typographie */
  --font-display: 'Space Grotesk', 'Segoe UI Semibold', system-ui, sans-serif;
  --font-body:    'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --fs-micro:  0.75rem;
  --fs-small:  0.875rem;
  --fs-body:   clamp(1rem, 0.975rem + 0.12vw, 1.0625rem);
  --fs-lead:   clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  --fs-h3:     clamp(1.0625rem, 1rem + 0.35vw, 1.1875rem);
  --fs-h2:     clamp(1.375rem, 1.22rem + 0.8vw, 1.8125rem);
  --fs-h1:     clamp(2rem, 1.45rem + 2.6vw, 3.25rem);

  /* Rythme */
  --gap:        clamp(1rem, 0.6rem + 1.6vw, 1.5rem);
  --block:      clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
  --measure:    68ch;
  --radius:     14px;
  --radius-lg:  20px;
  --radius-pill: 999px;
  --head-h:     4.25rem;

  --ease:       cubic-bezier(.22, .8, .3, 1);
  --dur:        .28s;
}

:root[data-theme='dark'] {
  color-scheme: dark;

  --ink:        #e7e9f8;
  --ink-soft:   #a9aecb;
  --ink-faint:  #7e84a4;
  --paper:      #0b0c16;
  --paper-deep: #06070e;
  --surface:    #14162a;
  --surface-2:  #191c33;
  --line:       #292d4b;
  --line-soft:  #202339;

  --iris:       #a3a4ff;  /* 8.1:1 sur --surface */
  --iris-deep:  #c6c7ff;
  --iris-tint:  #1d1f3c;
  --plum:       #d193ee;
  --mint:       #3ed9bd;
  --pulse:      #6cf1fa;   /* le cyan vif des arêtes du logo */

  --shadow-sm:  0 1px 2px rgba(0, 0, 0, .4);
  --shadow-md:  0 2px 4px rgba(0, 0, 0, .3), 0 12px 28px -8px rgba(0, 0, 0, .55);
  --shadow-lg:  0 4px 8px rgba(0, 0, 0, .3), 0 24px 48px -12px rgba(0, 0, 0, .7);
}

/* ==========================================================================
   02. RESET ET BASES
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-block-start: calc(var(--head-h) + 1rem);
}

body {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  font-feature-settings: 'cv11', 'ss01';
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

main { flex: 1 0 auto; }

img, svg { display: block; max-width: 100%; }

a { color: var(--iris); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--iris-deep); }

button, select { font: inherit; color: inherit; }

:where(a, button, select, input, [tabindex]):focus-visible {
  outline: 2px solid var(--iris);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection { background: var(--iris); color: var(--paper); }

/* ==========================================================================
   03. TYPOGRAPHIE
   ========================================================================== */

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); letter-spacing: -0.01em; }

p { text-wrap: pretty; }

/* L'étiquette monospace — le "timecode" de la mise en page.
   C'est le seul endroit où l'on parle le langage de l'outil. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-block-end: 1rem;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--iris);
}

.eyebrow::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(to right, var(--line), transparent);
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 46ch;
  margin-inline: auto;
}

/* ==========================================================================
   04. UTILITAIRES ET ACCESSIBILITÉ
   ========================================================================== */

.shell {
  width: 100%;
  max-width: 74rem;
  margin-inline: auto;
  padding-inline: var(--gap);
}

.shell--narrow { max-width: 58rem; }

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: fixed;
  inset-block-start: 0.5rem;
  inset-inline-start: 0.5rem;
  z-index: 200;
  padding: 0.6rem 1rem;
  background: var(--surface);
  color: var(--iris);
  border: 1px solid var(--iris);
  border-radius: var(--radius-pill);
  font-size: var(--fs-small);
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--shadow-md);
  transform: translateY(-160%);
  transition: transform var(--dur) var(--ease);
}

.skip:focus-visible { transform: translateY(0); }

/* Boutons ------------------------------------------------------------------ */

.btn {
  --btn-bg: var(--iris);
  --btn-fg: #fff;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.8rem 1.5rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              background-color var(--dur) var(--ease);
}

.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .28) 50%, transparent 70%);
  transform: translateX(-110%);
  transition: transform .6s var(--ease);
}

.btn:hover {
  color: var(--btn-fg);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.btn:hover::before { transform: translateX(110%); }
.btn:active { transform: translateY(0); }

.btn__arrow { transition: transform var(--dur) var(--ease); }
.btn:hover .btn__arrow { transform: translateX(3px); }

.btn--lg { padding: 0.95rem 1.9rem; font-size: var(--fs-body); }

/* ==========================================================================
   05. EN-TÊTE ET NAVIGATION
   ========================================================================== */

.site-head {
  position: sticky;
  inset-block-start: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  border-block-end: 1px solid var(--line-soft);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
}

@supports not (background: color-mix(in srgb, red, blue)) {
  .site-head { background: var(--paper); }
}

.head-inner {
  display: flex;
  align-items: center;
  gap: var(--gap);
  min-height: var(--head-h);
  max-width: 74rem;
  margin-inline: auto;
  padding-inline: var(--gap);
}

/* Marque ------------------------------------------------------------------- */

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-inline-end: auto;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.brand:hover { color: var(--ink); }
.brand-mark { width: 27px; height: auto; }
.brand:hover .brand-mark { animation: markTilt 1.4s var(--ease); }

@keyframes markTilt {
  40% { transform: translateY(-3px) rotate(-4deg); }
  100% { transform: none; }
}

/* Navigation --------------------------------------------------------------- */

.nav {
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 1.4vw, 1.25rem);
}

.nav-list {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  list-style: none;
  padding: 0;
}

.nav-link {
  position: relative;
  display: block;
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}

.nav-link:hover { color: var(--ink); background: var(--iris-tint); }

.nav-link[aria-current='page'] { color: var(--iris); font-weight: 600; }

.nav-link[aria-current='page']::after {
  content: '';
  position: absolute;
  inset-block-end: 0.15rem;
  inset-inline-start: 0.75rem;
  width: calc(100% - 1.5rem);
  height: 2px;
  border-radius: 2px;
  background: var(--iris);
}

.nav-link--store {
  color: var(--iris);
  font-weight: 600;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding-inline: 1rem;
}

.nav-link--store:hover { border-color: var(--iris); background: var(--iris-tint); }

.nav-tools {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* Sélecteur de langue ------------------------------------------------------ */

.lang-select {
  appearance: none;
  -webkit-appearance: none;
  padding-block: 0.5rem;
  padding-inline: 0.75rem 2rem;
  max-width: 9.5rem;
  background-color: var(--surface);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7'%3E%3Cpath fill='%236f7492' d='M5 7 0 1.4 1.3 0 5 4.1 8.7 0 10 1.4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.lang-select:hover { border-color: var(--iris); color: var(--ink); }

:root[data-theme='dark'] .lang-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7'%3E%3Cpath fill='%23a9aecb' d='M5 7 0 1.4 1.3 0 5 4.1 8.7 0 10 1.4z'/%3E%3C/svg%3E");
}

/* Bouton menu (mobile) ----------------------------------------------------- */

.menu-btn {
  display: none;
  place-items: center;
  width: 2.6rem; height: 2.6rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  color: var(--ink-soft);
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.menu-btn:hover { border-color: var(--iris); color: var(--iris); }

.menu-btn__bars { width: 18px; height: 12px; position: relative; }

.menu-btn__bars span {
  position: absolute;
  inset-inline: 0;
  height: 1.75px;
  border-radius: 2px;
  background: currentColor;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

.menu-btn__bars span:nth-child(1) { top: 0; }
.menu-btn__bars span:nth-child(2) { top: 5px; }
.menu-btn__bars span:nth-child(3) { top: 10px; }

.menu-btn[aria-expanded='true'] { color: var(--iris); border-color: var(--iris); }
.menu-btn[aria-expanded='true'] .menu-btn__bars span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.menu-btn[aria-expanded='true'] .menu-btn__bars span:nth-child(2) { opacity: 0; }
.menu-btn[aria-expanded='true'] .menu-btn__bars span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* ==========================================================================
   06. SÉLECTEUR DE THÈME
   ========================================================================== */

.theme-switch {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--paper-deep);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
}

.theme-btn {
  display: grid;
  place-items: center;
  width: 1.9rem; height: 1.9rem;
  background: none;
  border: 0;
  border-radius: 50%;
  color: var(--ink-faint);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.theme-btn:hover { color: var(--ink); }

.theme-btn[aria-pressed='true'] {
  background: var(--surface);
  color: var(--iris);
  box-shadow: var(--shadow-sm);
}

.theme-btn svg { width: 15px; height: 15px; }

/* ==========================================================================
   07. HERO "VIEWPORT"
   --------------------------------------------------------------------------
   L'élément signature : le hero est cadré comme l'image d'un moniteur de
   régie — grille discrète, cadre de zone protégée, équerres d'angle.

   Quatre couches, du fond vers l'avant :
     .hero::before        halos ambiants
     .hero::after         grille de fond (pages SANS cadre uniquement)
     .viewport__grid      grille du cadre + onde lumineuse   (z-index -1)
     contenu en flux      logo, titre, sous-titre, bouton
     .viewport::before    cadre pointillé
     .viewport::after     équerres d'angle
   ========================================================================== */

.hero {
  position: relative;
  padding-block: clamp(2.5rem, 1rem + 6vw, 5.5rem) var(--block);
  overflow: hidden;
  text-align: center;
  isolation: isolate;
}

/* Halos ambiants */
.hero::before {
  content: '';
  position: absolute;
  inset: -30% -10% auto;
  height: 130%;
  z-index: -2;
  background:
    radial-gradient(42% 50% at 26% 18%, color-mix(in srgb, var(--iris) 16%, transparent), transparent 70%),
    radial-gradient(38% 46% at 78% 8%, color-mix(in srgb, var(--plum) 13%, transparent), transparent 70%);
  pointer-events: none;
}

/* Grille de fond, pour les heros sans cadre (À propos, Newsletters, légal). */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image:
    linear-gradient(to right, var(--line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line) 1px, transparent 1px);
  background-size: 68px 68px;
  -webkit-mask-image: radial-gradient(70% 60% at 50% 32%, #000 0%, transparent 78%);
          mask-image: radial-gradient(70% 60% at 50% 32%, #000 0%, transparent 78%);
  opacity: .5;
  pointer-events: none;
}

/* Quand le hero a un cadre, la grille descend dans le cadre : c'est la seule
   façon d'aligner l'onde lumineuse sur les traits au pixel près. */
.hero--framed::after { display: none; }

/* --------------------------------------------------------------------------
   Le cadre
   -------------------------------------------------------------------------- */

.viewport {
  --grid: 64px;
  position: relative;
  isolation: isolate;
  padding: clamp(1.75rem, 1rem + 3vw, 3.25rem) clamp(1rem, 0.4rem + 2.5vw, 2.75rem);
  border-radius: var(--radius-lg);
}

/* Le cadre pointillé de zone protégée. */
.viewport::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px dashed var(--line);
  border-color: color-mix(in srgb, var(--iris) 30%, transparent);
  border-radius: var(--radius-lg);
  pointer-events: none;
}

/* Les quatre équerres d'angle, sans balisage superflu : huit dégradés plats
   posés aux quatre coins. */
.viewport::after {
  content: '';
  position: absolute;
  inset: -1px;
  pointer-events: none;
  --tick: linear-gradient(var(--iris), var(--iris));
  background-image: var(--tick), var(--tick), var(--tick), var(--tick),
                    var(--tick), var(--tick), var(--tick), var(--tick);
  background-repeat: no-repeat;
  background-size: 1.5px 20px, 20px 1.5px,   /* haut-gauche */
                   1.5px 20px, 20px 1.5px,   /* haut-droite */
                   1.5px 20px, 20px 1.5px,   /* bas-gauche */
                   1.5px 20px, 20px 1.5px;   /* bas-droite */
  background-position: left top, left top,
                       right top, right top,
                       left bottom, left bottom,
                       right bottom, right bottom;
}

/* --------------------------------------------------------------------------
   La grille du cadre et l'onde qui la révèle
   --------------------------------------------------------------------------
   Une seule couche, dont le MASQUE est la grille : rien de ce qu'elle peint
   ne peut apparaître ailleurs que sur les traits. Deux pseudo-éléments, donc
   forcément alignés entre eux au pixel :

     ::after   la grille au repos — discrète, estompée vers les bords
     ::before  le front lumineux, au-dessus

   C'est aussi pour cela que la grille n'est pas le fond de .viewport : il lui
   faut son propre estompage, et un masque posé sur .viewport masquerait le
   logo et le texte avec.

   ATTENTION : cette couche a besoin de l'élément
   <span class="viewport__grid"></span> dans le HTML. Si tu remplaces la
   feuille de style sans reprendre les pages, grille et onde disparaissent.
   tools/verify.js contrôle cette correspondance.
   -------------------------------------------------------------------------- */

.viewport__grid {
  /* --- grille au repos --- */
  --grid-rest: .5;      /* opacité ; la valeur d'origine du site */
  --grid-focus: 44%;    /* hauteur du point le plus visible, derrière le logo */
  --grid-fade: 78%;     /* où l'estompage arrive à zéro */

  /* --- onde --- */
  --pulse-reach: 190%;
  --pulse-cycle: 7.5s;
  --pulse-delay: 1.7s;

  position: absolute;
  inset: 0;
  z-index: -1;          /* derrière le logo et le texte */
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;

  -webkit-mask-image:
    linear-gradient(to right, #000 1px, transparent 1px),
    linear-gradient(to bottom, #000 1px, transparent 1px);
          mask-image:
    linear-gradient(to right, #000 1px, transparent 1px),
    linear-gradient(to bottom, #000 1px, transparent 1px);
  -webkit-mask-size: var(--grid) var(--grid);
          mask-size: var(--grid) var(--grid);
  -webkit-mask-position: 50% 50%;
          mask-position: 50% 50%;
  -webkit-mask-repeat: repeat;
          mask-repeat: repeat;
}

/* La grille au repos.
   Les rayons (58% / 54%) sont volontairement PLUS PETITS que la demi-boîte :
   l'estompage doit être terminé avant d'atteindre le cadre, sinon les traits
   restent présents jusqu'aux bords et le fondu ne se voit pas. */
.viewport__grid::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: var(--grid-rest);
  background: radial-gradient(58% 54% at 50% var(--grid-focus),
      var(--line) 0%,
      color-mix(in srgb, var(--line) 48%, transparent) 44%,
      transparent var(--grid-fade));
}

/* Le front lumineux.
   Géométrie : le dégradé est elliptique et suit le rapport du cadre, donc
   l'onde atteint les quatre bords en même temps quelle que soit la largeur
   d'écran. En unités normalisées (1 = demi-cadre), le front se situe à
   0,76 x --pulse-reach. À 190 % il franchit les bords à 69 % de sa course et
   arrive sur les coins juste à la fin.

   L'expansion se fait par transform: scale(), pas par background-size : c'est
   composité par le GPU et interpolable partout, sans @property à enregistrer. */
.viewport__grid::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;            /* centrage géométrique : pas de logique RTL ici */
  z-index: 1;           /* au-dessus de la grille au repos */
  width: var(--pulse-reach);
  height: var(--pulse-reach);
  background: radial-gradient(closest-side,
      transparent 30%,
      color-mix(in srgb, var(--pulse) 14%, transparent) 54%,
      color-mix(in srgb, var(--pulse) 90%, transparent) 76%,
      transparent 90%);
  transform: translate(-50%, -50%) scale(.06);
  animation: gridPulse var(--pulse-cycle) var(--ease) var(--pulse-delay) infinite;
}

/* En thème sombre, la grille au repos a besoin d'un peu plus de présence pour
   rester lisible sur le fond foncé. */
:root[data-theme='dark'] .viewport__grid { --grid-rest: .62; }

/* La course occupe les 38 premiers pour cent du cycle (~2,85 s), le reste est
   une pause. À scale .06 le front tient dans l'empreinte du logo : l'onde
   émerge donc littéralement de derrière lui. */
@keyframes gridPulse {
  0%   { transform: translate(-50%, -50%) scale(.06); opacity: 0; }
  5%   { opacity: 1; }
  30%  { opacity: .8; }
  38%  { transform: translate(-50%, -50%) scale(1); opacity: 0; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}

/* --------------------------------------------------------------------------
   Contenu du hero
   -------------------------------------------------------------------------- */

.hero__title { margin-block-end: 0.85rem; }

.hero__title .grad {
  background: linear-gradient(100deg, var(--iris) 8%, var(--plum) 92%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.eyebrow--center { justify-content: center; }
.eyebrow--center::after { display: none; }

.hero__eyebrow {
  justify-content: center;
  margin-block-end: 1.25rem;
  color: var(--ink-faint);
}

.hero__eyebrow::after { display: none; }

.hero__eyebrow b { color: var(--iris); font-weight: 500; }

.hero__cta { margin-block-start: 1.9rem; }

/* Variante compacte : pages internes */
.hero--slim { padding-block: clamp(2rem, 1rem + 4vw, 3.5rem) clamp(1.5rem, 1rem + 2vw, 2.5rem); }
.hero--slim .hero__title { margin-block-end: 0.6rem; }

/* ==========================================================================
   08. LOGO
   --------------------------------------------------------------------------
   Deux usages, deux fichiers.

   La marque monochrome (barre, pied de page) est peinte en currentColor :
   un seul fichier suffit, la couleur vient du thème. Plus besoin d'une
   version blanche et d'une version noire à permuter.

   Le logo couleur du hero s'assemble comme un viewport 3D qui change de mode
   d'affichage : le filaire se trace, puis les faces se remplissent, puis les
   détails d'arête apparaissent. C'est le vocabulaire des logiciels 3D, donc
   la référence dit quelque chose du sujet au lieu de décorer.
   ========================================================================== */

.logo-mark {
  flex: none;
  color: var(--ink);
  transition: color var(--dur) var(--ease);
}

.logo-hero {
  width: clamp(104px, 25vw, 168px);
  height: auto;
  margin: 0 auto 1.6rem;
  overflow: visible;
}

/* Le logo est dessiné pour un fond clair : il contient du noir pur et du bleu
   très sombre. En thème sombre, un halo doux le décolle du fond sans ajouter
   de cadre qui jurerait. */
:root[data-theme='dark'] .logo-hero {
  background: radial-gradient(58% 54% at 50% 47%,
              rgba(150, 180, 225, .15), transparent 72%);
  filter: drop-shadow(0 0 22px rgba(108, 241, 250, .20));
}

/* --- Phase 1 : le filaire se trace ------------------------------------- */

/* pathLength="1" sur chaque tracé permet d'animer le pointillé sans avoir à
   mesurer la longueur réelle : 1 = tracé entier. */
.js .logo-hero .lg-line {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: lgDraw .85s var(--ease) forwards;
  animation-delay: calc(var(--i) * 70ms + 120ms);
}

@keyframes lgDraw { to { stroke-dashoffset: 0; } }

/* --- Phase 2 : les faces se remplissent -------------------------------- */

/* Pas de translation ici : décaler des faces isométriques les désolidarise
   du volume. Un simple fondu enchaîné lit comme un passage en mode rendu. */
.js .logo-hero .lg-face {
  opacity: 0;
  animation: lgFill .6s var(--ease) forwards;
  animation-delay: calc(var(--i) * 55ms + 440ms);
}

/* --- Phase 3 : les détails d'arête ------------------------------------- */

.js .logo-hero .lg-edge {
  opacity: 0;
  animation: lgFill .5s var(--ease) forwards;
  animation-delay: calc(var(--i) * 80ms + 1040ms);
}

@keyframes lgFill { to { opacity: 1; } }

/* --- Dérive ambiante, une fois l'assemblage terminé -------------------- */

.logo-hero__group {
  animation: isoDrift 9s ease-in-out 1.9s infinite;
  transform-origin: 50% 50%;
}

@keyframes isoDrift {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}

/* ==========================================================================
   09. CARTES DE CONTENU
   --------------------------------------------------------------------------
   Rappel du motif : deux équerres en diagonale, qui s'allongent au survol.
   ========================================================================== */

.section { padding-block-end: var(--block); }

.card {
  position: relative;
  padding: clamp(1.5rem, 1rem + 2vw, 2.25rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}

.card::after {
  content: '';
  position: absolute;
  inset: 10px;
  pointer-events: none;
  --tick: linear-gradient(var(--iris), var(--iris));
  background-image: var(--tick), var(--tick), var(--tick), var(--tick);
  background-repeat: no-repeat;
  background-size: 1.5px 12px, 12px 1.5px, 1.5px 12px, 12px 1.5px;
  background-position: right top, right top, left bottom, left bottom;
  opacity: 0;
  transition: opacity var(--dur) var(--ease), background-size var(--dur) var(--ease);
}

.card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--iris) 35%, var(--line));
  box-shadow: var(--shadow-md);
}

.card:hover::after {
  opacity: .85;
  background-size: 1.5px 22px, 22px 1.5px, 1.5px 22px, 22px 1.5px;
}

.card__title {
  margin-block-end: 0.7rem;
  color: var(--ink);
}

.card__body {
  color: var(--ink-soft);
  max-width: var(--measure);
}

.card__body + .card__body { margin-block-start: 0.9rem; }

/* Grille de cartes */
.grid {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
}

/* ==========================================================================
   10. PAGES LÉGALES
   --------------------------------------------------------------------------
   Ici le numéro de section EST une information (on se réfère à "l'article 7"),
   donc le compteur est affiché. Ailleurs sur le site, non.
   ========================================================================== */

.legal { counter-reset: clause; }

.legal .card {
  counter-increment: clause;
  padding-inline-start: clamp(1.5rem, 1rem + 2vw, 2.25rem);
}

.legal .card__title {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
}

.legal .card__title::before {
  content: counter(clause, decimal-leading-zero);
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--iris);
  background: var(--iris-tint);
  padding: 0.15rem 0.5rem;
  border-radius: 6px;
  letter-spacing: 0.04em;
}

/* Les puces "•" vivent dans les chaînes de traduction : on les met en page
   sans toucher au contenu traduit. */
.rule-list {
  margin-block-start: 0.9rem;
  padding: 1rem 1.15rem;
  background: var(--surface-2);
  border-inline-start: 2px solid var(--iris);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--ink-soft);
  font-size: var(--fs-small);
  line-height: 1.9;
}

.callout {
  margin-block-start: 0.9rem;
  padding: 1rem 1.15rem;
  background: var(--iris-tint);
  border-radius: var(--radius);
  color: var(--ink-soft);
}

.callout strong { color: var(--ink); }

.external-link {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  overflow-wrap: anywhere;
}

.updated {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.updated::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--mint);
}

/* ==========================================================================
   11. NEWSLETTERS
   ========================================================================== */

.issues { display: grid; gap: var(--gap); }

.issue {
  position: relative;
  display: grid;
  gap: 0.5rem;
  padding: clamp(1.35rem, 1rem + 1.5vw, 1.9rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  color: inherit;
  text-decoration: none;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}

.issue:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--iris) 40%, var(--line));
  box-shadow: var(--shadow-md);
  color: inherit;
}

.issue--latest { border-color: color-mix(in srgb, var(--iris) 45%, var(--line)); }

.issue__flag {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  width: max-content;
  padding: 0.2rem 0.6rem;
  background: var(--mint);
  color: #fff;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.issue__flag::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: tally 2.4s ease-in-out infinite;
}

@keyframes tally { 50% { opacity: .35; } }

.issue__date {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--iris);
}

.issue__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.25;
}

.issue__excerpt { color: var(--ink-soft); font-size: var(--fs-small); max-width: var(--measure); }

.issue__more {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-block-start: 0.3rem;
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--iris);
}

.issue__more svg { transition: transform var(--dur) var(--ease); }
.issue:hover .issue__more svg { transform: translateX(4px); }

/* En RTL, la flèche pointe dans l'autre sens */
[dir='rtl'] .issue__more svg { transform: scaleX(-1); }
[dir='rtl'] .issue:hover .issue__more svg { transform: scaleX(-1) translateX(4px); }
[dir='rtl'] .btn__arrow { transform: scaleX(-1); }
[dir='rtl'] .btn:hover .btn__arrow { transform: scaleX(-1) translateX(3px); }

/* ==========================================================================
   12. STATISTIQUES (page privée, noindex)
   ========================================================================== */

.stats-grid {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
}

.stat {
  display: grid;
  gap: 0.85rem;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.stat__label {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.stat__value { min-height: 34px; }
.stat__value img { height: 30px; width: auto; }

.admin-toggle {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1.15rem 1.35rem;
  background: var(--surface-2);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  cursor: pointer;
}

.admin-toggle input {
  flex: none;
  width: 1.1rem; height: 1.1rem;
  margin-block-start: 0.2rem;
  accent-color: var(--iris);
  cursor: pointer;
}

.admin-toggle strong { display: block; color: var(--ink); }

.kbd {
  display: inline-block;
  padding: 0.1rem 0.4rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-block-end-width: 2px;
  border-radius: 5px;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--ink);
}

.note {
  font-size: var(--fs-small);
  color: var(--ink-faint);
}

/* ==========================================================================
   13. PIED DE PAGE
   ========================================================================== */

.site-foot {
  margin-block-start: auto;
  padding-block: 2rem;
  background: var(--surface);
  border-block-start: 1px solid var(--line);
}

.foot-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem var(--gap);
  max-width: 74rem;
  margin-inline: auto;
  padding-inline: var(--gap);
}

.foot-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
}

.foot-mark { width: 22px; height: auto; }

.foot-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 1.15rem;
  list-style: none;
  padding: 0;
}

.foot-nav a {
  font-size: var(--fs-small);
  color: var(--ink-soft);
  text-decoration: none;
}

.foot-nav a:hover { color: var(--iris); text-decoration: underline; }

.foot-nav a.is-admin { color: var(--mint); font-family: var(--font-mono); font-size: var(--fs-micro); }

.foot-legal {
  flex-basis: 100%;
  padding-block-start: 1rem;
  border-block-start: 1px solid var(--line-soft);
  font-size: var(--fs-micro);
  color: var(--ink-faint);
}

/* ==========================================================================
   14. ANIMATIONS D'APPARITION
   ========================================================================== */

/* La classe .js n'existe que si le JavaScript tourne : sans lui, tout
   reste visible. */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .reveal.is-in { opacity: 1; transform: none; }

/* Séquence d'arrivée du hero */
.js .hero__eyebrow, .js .hero__title, .js .hero__lead, .js .hero__cta {
  animation: riseIn .7s var(--ease) both;
}

.js .hero__eyebrow { animation-delay: .05s; }
.js .hero__title   { animation-delay: .14s; }
.js .hero__lead    { animation-delay: .23s; }
.js .hero__cta     { animation-delay: .32s; }

@keyframes riseIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* Respect des préférences système : on coupe tout mouvement. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  .js .reveal { opacity: 1; transform: none; }

  /* On coupe l'onde, pas la grille au repos. */
  .viewport__grid::before { display: none; }

  .js .logo-hero .lg-line { stroke-dashoffset: 0; }
  .js .logo-hero .lg-face,
  .js .logo-hero .lg-edge { opacity: 1; }
  .logo-hero__group { animation: none; }
}

/* ==========================================================================
   15. BIDIRECTIONNALITÉ ET SCRIPTS NON LATINS
   --------------------------------------------------------------------------
   Tout le fichier utilise des propriétés logiques (inline-start/end), donc
   dir="rtl" sur <html> suffit : plus de row-reverse qui annule le rtl.
   ========================================================================== */

[dir='rtl'] .lang-select { background-position: left 0.7rem center; }
[dir='rtl'] .eyebrow::after { background: linear-gradient(to left, var(--line), transparent); }

/* Piles de polices par écriture : Space Grotesk et Inter ne couvrent pas
   l'arabe, le persan, le géorgien, le chinois ni le japonais. */
:lang(ar), :lang(fa) {
  --font-display: 'Noto Kufi Arabic', 'Segoe UI', Tahoma, system-ui, sans-serif;
  --font-body: 'Noto Naskh Arabic', 'Segoe UI', Tahoma, system-ui, sans-serif;
  --font-mono: 'Segoe UI', Tahoma, system-ui, sans-serif;
  line-height: 1.85;
}

:lang(ka) {
  --font-display: 'BPG Nino Mtavruli', 'Noto Sans Georgian', system-ui, sans-serif;
  --font-body: 'Noto Sans Georgian', system-ui, sans-serif;
}

:lang(zh) {
  --font-display: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', system-ui, sans-serif;
  --font-body: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', system-ui, sans-serif;
  letter-spacing: 0;
}

:lang(ja) {
  --font-display: 'Hiragino Kaku Gothic ProN', 'Yu Gothic', 'Meiryo', system-ui, sans-serif;
  --font-body: 'Hiragino Kaku Gothic ProN', 'Yu Gothic', 'Meiryo', system-ui, sans-serif;
  letter-spacing: 0;
}

/* Les articles légaux se numérotent en chiffres arabes en ar/fa */
:lang(ar) .legal .card__title::before,
:lang(fa) .legal .card__title::before { content: counter(clause, arabic-indic); }

/* L'arabe, le persan et le géorgien n'aiment pas les majuscules forcées */
:lang(ar) .eyebrow, :lang(fa) .eyebrow, :lang(ka) .eyebrow,
:lang(ar) .issue__date, :lang(fa) .issue__date, :lang(ka) .issue__date,
:lang(ar) .updated, :lang(fa) .updated, :lang(ka) .updated {
  text-transform: none;
  letter-spacing: 0;
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 60rem) {
  .nav {
    /* absolute et non fixed : le backdrop-filter du header en ferait de
       toute façon son conteneur de référence. Autant l'écrire. */
    position: absolute;
    inset-block-start: 100%;
    inset-inline: 0;
    z-index: 90;
    flex-direction: column;
    align-items: stretch;
    gap: 1.25rem;
    padding: 1.25rem var(--gap) 1.75rem;
    background: var(--surface);
    border-block-end: 1px solid var(--line);
    box-shadow: var(--shadow-md);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
                visibility var(--dur);
  }

  .nav.is-open { visibility: visible; opacity: 1; transform: none; }

  .nav-list { flex-direction: column; align-items: stretch; gap: 0.15rem; }

  .nav-link { padding: 0.7rem 0.85rem; font-size: var(--fs-body); }

  .nav-link[aria-current='page']::after { display: none; }

  .nav-link--store {
    margin-block-start: 0.5rem;
    justify-content: center;
    text-align: center;
  }

  .nav-tools {
    justify-content: space-between;
    padding-block-start: 1.25rem;
    border-block-start: 1px solid var(--line-soft);
  }

  .lang-select { max-width: none; flex: 1; }

  .menu-btn { display: grid; }
}

@media (max-width: 30rem) {
  :root { --head-h: 3.85rem; }

  .brand { font-size: 1.05rem; }
  .brand-mark { width: 22px; height: 26px; }

  .hero::after { background-size: 48px 48px; }

  .viewport { --grid: 44px; padding-inline: 0.75rem; }

  .foot-inner { justify-content: center; text-align: center; }
  .foot-nav { justify-content: center; }
}

/* Impression : les pages légales doivent rester lisibles sur papier. */
@media print {
  .site-head, .site-foot, .skip, .hero::before, .hero::after { display: none !important; }

  body { background: #fff; color: #000; }
  .card { break-inside: avoid; border-color: #ccc; box-shadow: none; }
  .card::after, .viewport::before, .viewport::after,
  .viewport__grid { display: none; }
}
