/* ---------- Ambiance de section ---------- */
/* Aucune section ne repose sur un aplat nu : chaque .section reçoit soit un
   halo d'accent très bas (--lit), soit un fond relevé en carte (--raised),
   soit elle respire nue juste après une image pleine largeur / mosaïque —
   jamais deux sections consécutives avec le même traitement. */
.section {
  position: relative;
  /* Bas légèrement supérieur au haut : optiquement plus juste. */
  padding-block: var(--sp-6) var(--sp-7);
}

/* Halo en z-index: 0 plutôt que -1 : sur ce site, .section ne crée pas
   toujours un contexte d'empilement propre (pas de z-index explicite), donc
   un ::before en -1 peut se retrouver peint sous le fond du body. On passe
   plutôt le contenu direct au-dessus (z-index: 1) : la comparaison entre
   frères ::before/enfants reste correcte quel que soit le contexte englobant. */
.section--lit::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(70% 55% at var(--lit-x, 20%) 0%,
              rgba(244, 244, 244, 0.06) 0%, transparent 70%);
  pointer-events: none;
}

.section--lit > * { position: relative; z-index: 1; }

/* Trois positions de halo, réparties sur les pages pour ne jamais répéter
   le même point lumineux d'une section relevée à l'autre. */
.section--lit-15 { --lit-x: 15%; }
.section--lit-50 { --lit-x: 50%; }
.section--lit-80 { --lit-x: 80%; }

.section--raised {
  background: var(--bg-raised);
  border-radius: var(--r-lg);
  margin-inline: var(--gutter);
  padding-inline: var(--gutter);
  box-shadow: var(--shadow-lift);
}

/* .container centre déjà la largeur (margin-inline: auto) et pose son propre
   padding-inline : sans ce correctif, .section--raised ajoute un second
   retrait par-dessus et la carte devient plus étroite que ses voisines. */
.section--raised.container {
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Le filet de séparation entre sections n'a pas sa place contre une carte
   relevée : la couleur, l'arrondi et l'ombre suffisent à marquer la limite. */
.section--raised + .section,
.section + .section--raised { border-top: 0; }

/* ---------- Boot sequence ---------- */
.boot {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--bg);
  pointer-events: none;
  /* Voile qui s'efface : c'est une sortie, --ease-out reste juste ici. */
  transition: opacity var(--d-reveal) var(--ease-out);
}

.boot__bar {
  position: absolute;
  inset: 0 auto auto 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: var(--accent);
  /* Barre qui traverse l'écran : un déplacement, pas une entrée. Durée
     volontairement hors de l'échelle d-press/d-ui/d-reveal — moment de
     marque, unique par chargement, pas une interaction répétée. */
  transition: transform 900ms var(--ease-in-out);
}

.boot.is-loading .boot__bar { transform: scaleX(1); }
.boot.is-done { opacity: 0; }

/* ---------- Révélation au scroll ---------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--d-reveal) var(--ease-out), transform var(--d-reveal) var(--ease-out);
}

[data-reveal].is-visible { opacity: 1; transform: none; }

/* Décalage de groupe : les rangées des composants de données révélés en
   bloc entrent en cascade plutôt que toutes au même instant. 60ms entre
   chaque élément, dans la fourchette 30-80ms du cadre Emil Kowalski. Le
   sélecteur porte sur le conteneur de chaque composant (tuiles, chiffres,
   registre, séquence, extrait de rapport, fiche technique) : sa marque
   change, jamais la structure des pages. */
[data-reveal] :is(.tile-grid, .figures, .ledger, .numbered-list, .finding-list, .spec-table) > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--d-reveal) var(--ease-out), transform var(--d-reveal) var(--ease-out);
}

[data-reveal].is-visible :is(.tile-grid, .figures, .ledger, .numbered-list, .finding-list, .spec-table) > * {
  opacity: 1;
  transform: none;
}

[data-reveal] :is(.tile-grid, .figures, .ledger, .numbered-list, .finding-list, .spec-table) > *:nth-child(2) { transition-delay: 60ms; }
[data-reveal] :is(.tile-grid, .figures, .ledger, .numbered-list, .finding-list, .spec-table) > *:nth-child(3) { transition-delay: 120ms; }
[data-reveal] :is(.tile-grid, .figures, .ledger, .numbered-list, .finding-list, .spec-table) > *:nth-child(4) { transition-delay: 180ms; }
[data-reveal] :is(.tile-grid, .figures, .ledger, .numbered-list, .finding-list, .spec-table) > *:nth-child(5) { transition-delay: 240ms; }
[data-reveal] :is(.tile-grid, .figures, .ledger, .numbered-list, .finding-list, .spec-table) > *:nth-child(6) { transition-delay: 300ms; }

/* ---------- Lien d'évitement ---------- */
.skip-link {
  position: fixed;
  top: var(--sp-2);
  left: var(--sp-2);
  z-index: 1100;
  padding: 0.75rem 1.25rem;
  background: var(--bg-raised);
  color: var(--fg);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-lift);
  opacity: 0;
  transform: translateY(-140%);
  transition: opacity var(--d-ui) var(--ease-out), transform var(--d-ui) var(--ease-out);
  pointer-events: none;
}

.skip-link:focus {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ---------- Navigation ---------- */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--gutter);
  mix-blend-mode: difference;
}

.nav__brand {
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

.nav__links { display: flex; gap: var(--sp-4); }

/* Étiquettes techniques : le registre vient des capitales et de l'interlettrage
   large, pas d'une police à chasse fixe. */
.nav__link {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.65;
  transition: opacity var(--d-ui) var(--ease-out);
}

.nav__link[aria-current="page"] { opacity: 1; }

.nav__link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

@media (hover: hover) and (pointer: fine) {
  .nav__link:hover { opacity: 1; }
}

@media (max-width: 720px) {
  .nav__links { display: none; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding-block: var(--sp-6);
  overflow: hidden;
}

.hero__media { position: absolute; inset: 0; z-index: 0; }

.hero__media img,
.hero__media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* La photo (ou la vidéo) reste une photo : quasi aucune désaturation,
     luminosité pleine. La lisibilité du titre (posé en bas, .hero
     align-items: flex-end) vient du dégradé localisé de .hero__media::after,
     pas d'un assombrissement global qui écraserait l'image ou la vidéo
     entière. Même traitement chromatique pour les deux : la vidéo garde ses
     couleurs, elle n'est pas écrasée en texture grise. */
  filter: grayscale(0.05) contrast(1.04) brightness(1.05);
}

/* Fondu localisé vers le fond de page : fort juste derrière le titre (bas),
   quasi absent en haut de l'image pour laisser la photo respirer. */
.hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 70% 20%, transparent 0%, rgba(11,11,11,0.22) 70%, rgba(11,11,11,0.4) 100%),
    linear-gradient(to top, var(--bg) 0%, rgba(11,11,11,0.65) 30%, transparent 62%);
}

.hero__inner { position: relative; z-index: 1; width: 100%; }

/* Ombre douce, pas un fond plaqué : elle détache le titre de la photo sans
   revenir à un assombrissement global de l'image. */
.hero__title {
  font-size: var(--fs-h1);
  margin-block: var(--sp-3) var(--sp-3);
  text-shadow: 0 2px 24px rgba(7, 7, 7, 0.55);
}

.hero__actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-4); }

/* Mise en page à deux colonnes : titre à gauche, corps à droite */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-5);
  align-items: start;
}

@media (max-width: 860px) {
  .split { grid-template-columns: 1fr; gap: var(--sp-4); }
}

/* ---------- Bloc éditorial (posture, sans encadré) ---------- */
/* Bande pleine largeur, teintée --bg-raised : un moment de conviction entre
   deux composants de données, pas une carte. Aucun bord, aucun rayon, aucune
   ombre, seule la nuance de fond et l'échelle du texte le distinguent de
   ses voisins. La section garde le filet standard de séparation entre deux
   .section (base.css), rien de plus. */
.section--statement { background: var(--bg-raised); }

.statement {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: var(--sp-5);
  align-items: center;
}

.statement__lead {
  font-size: var(--fs-display);
  font-weight: 500;
  letter-spacing: -0.04em;
  line-height: 0.98;
}

.statement__body {
  font-size: clamp(1.125rem, 1.7vw, 1.5rem);
  max-width: 46ch;
}

@media (max-width: 860px) {
  .statement { grid-template-columns: 1fr; gap: var(--sp-3); }
}

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.9rem 1.75rem;
  /* Fond, couleur et police explicites : sur un <button>, le navigateur pose
     sinon ses propres valeurs (fond gris clair, police système), et le bouton
     fantôme d'un formulaire ne ressemble plus à celui d'un lien. */
  background: transparent;
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border: 1px solid var(--fg-faint);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--d-ui) var(--ease-out),
              color var(--d-ui) var(--ease-out),
              border-color var(--d-ui) var(--ease-out),
              transform var(--d-press) var(--ease-out);
}

.btn:active { transform: scale(0.98); }

.btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* L'accent n'est jamais un fond de bouton — le contraste vient du blanc cassé */
.btn--primary { background: var(--fg); color: var(--bg); border-color: var(--fg); }

@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover { background: transparent; color: var(--fg); }
  .btn--ghost:hover { border-color: var(--fg); }
}

/* Respiration entre un paragraphe et un bouton qui le suit, hors hero */
.spec-copy + .btn,
.lede + .btn { margin-top: var(--sp-3); }

/* ---------- CTA final en deux colonnes ---------- */
/* Les deux moitiés sont désormais deux cartes sombres posées sur un bandeau
   creusé (--bg-sunken), différenciées par --bg-raised sur l'une et --bg sur
   l'autre — jamais de panneau clair au milieu d'un site sombre. */
.cta-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--gutter);
  background: var(--bg-sunken);
}

.cta-split__half {
  padding: var(--sp-6) var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  align-items: flex-start;
  background: var(--bg);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lift);
}

.cta-split__half--invert { background: var(--bg-raised); }

@media (max-width: 860px) {
  .cta-split { grid-template-columns: 1fr; }
}

/* ---------- Registre (lignes de cadre légal) ---------- */
/* Seul composant de données à garder le filet d'un pixel entre les rangées :
   c'est un registre légal, la métaphore du filet lui redonne un sens précis. */
.ledger { border-top: 1px solid var(--rule); }

/* Un titre posé juste au-dessus d'un composant de données a besoin d'air :
   sans ça, le filet du registre vient toucher la descendante du titre. */
h2 + .ledger, h2 + .numbered-list, h2 + .spec-table { margin-top: var(--sp-4); }

.ledger__row {
  display: grid;
  grid-template-columns: 4rem 1fr 13rem;
  gap: var(--sp-3);
  align-items: baseline;
  padding-block: var(--sp-3);
  border-bottom: 1px solid var(--rule);
}

.ledger__num,
.ledger__ref {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.ledger__ref { text-align: right; }
.ledger__title { font-size: var(--fs-h3); font-weight: 500; }
.ledger__body { font-size: var(--fs-small); color: var(--fg-muted); margin-top: var(--sp-1); max-width: 62ch; }

@media (max-width: 720px) {
  .ledger__row { grid-template-columns: 1fr; gap: var(--sp-1); }
  .ledger__ref { text-align: left; }
}

/* ---------- Tableau de chiffres ---------- */
/* Aucun filet : les rangées se séparent par l'espace, pas par une ligne.
   Le chiffre porte l'attention (très grand, graisse 600) ; le libellé et la
   note descendent d'un niveau de gris pour rester en arrière-plan. */
.figures {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  margin-top: var(--sp-5);
}

.figures__row {
  display: grid;
  grid-template-columns: 9rem 1fr 16rem;
  gap: var(--sp-3);
  align-items: baseline;
}

.figures__num {
  font-size: clamp(2.5rem, 5vw, 4.25rem);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
}

.figures__num--accent { color: var(--accent); }

.figures__label { font-size: var(--fs-h3); font-weight: 500; color: var(--fg-muted); }

.figures__note {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-faint);
  text-align: right;
}

@media (max-width: 720px) {
  .figures__row { grid-template-columns: 1fr; gap: var(--sp-1); }
  .figures__note { text-align: left; }
}

/* ---------- Fiche technique ---------- */
/* Un seul bloc relevé (--bg-raised, --r-lg) qui lit comme une carte, pas
   comme un tableau : les filets internes qui restent sont volontairement
   très discrets (--rule atténué), et n'apparaissent qu'à l'intérieur du bloc. */
.spec-table {
  background: var(--bg-raised);
  border-radius: var(--r-lg);
  padding: var(--sp-1) var(--sp-4);
  box-shadow: var(--shadow-lift);
}

.spec-table__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  padding-block: var(--sp-3);
  border-bottom: 1px solid color-mix(in srgb, var(--rule) 55%, transparent);
  align-items: baseline;
}

.spec-table__row:last-child { border-bottom: 0; }

.spec-table__key {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.spec-table__val { font-size: var(--fs-h3); font-weight: 400; letter-spacing: -0.01em; }

@media (max-width: 640px) {
  .spec-table__row { grid-template-columns: 1fr; gap: var(--sp-1); }
}

/* ---------- Liste numérotée (séquence) ---------- */
/* Une séquence, pas un catalogue : aucun filet, l'espace vertical porte la
   progression d'une étape à l'autre. Le numéro devient un très grand repère
   de fond (--fg-faint) plutôt qu'une colonne de référence ; la colonne de
   contenu se resserre pour lire comme un temps de récit, pas comme une ligne. */
.numbered-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
}

.numbered-list__item {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: var(--sp-4);
  align-items: start;
}

.numbered-list__num {
  font-size: clamp(2.75rem, 5vw, 4.5rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--fg-faint);
}

.numbered-list__title { font-size: var(--fs-h3); font-weight: 500; margin-bottom: var(--sp-1); }
.numbered-list__body { font-size: var(--fs-small); color: var(--fg-muted); max-width: 42ch; }

@media (max-width: 640px) {
  .numbered-list { gap: var(--sp-5); }
  .numbered-list__item { grid-template-columns: 1fr; gap: var(--sp-1); }
  .numbered-list__num { font-size: clamp(2.25rem, 12vw, 3rem); }
}

/* ---------- Pied de page ---------- */
.footer { border-top: 1px solid var(--rule); padding-block: var(--sp-5) var(--sp-4); }

.footer__grid {
  display: grid;
  grid-template-columns: 2fr repeat(3, 1fr);
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}

.footer__brand {
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.28em;
}

.footer__col-title {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: var(--sp-2);
}

.footer__link {
  display: block;
  font-size: var(--fs-small);
  color: var(--fg-muted);
  padding-block: 0.35rem;
  transition: color var(--d-ui) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .footer__link:hover { color: var(--fg); }
}

.footer__legal {
  font-size: var(--fs-small);
  color: var(--fg-faint);
  border-top: 1px solid var(--rule);
  padding-top: var(--sp-3);
}

/* ---------- Hero de page produit — gabarit type fiche ---------- */
.hero--product { align-items: center; }

/* Ce hero n'a pas de photo (.hero__media est vide) : sans halo, il n'est
   qu'un aplat de --bg avec le grain global, exactement le défaut diagnostiqué.
   z-index: 1, pas -1 ni 0 : .hero__media est déjà en z-index: 0 et son propre
   fond (le dégradé de .hero__media::after) est opaque, donc un halo à -1 ou 0
   se peindrait sous lui et resterait invisible. hero__inner reste en
   z-index: 1 mais après ce ::before dans l'ordre du DOM, donc toujours
   au-dessus du halo. */
.hero--product::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(60% 50% at 72% 8%,
              rgba(244, 244, 244, 0.06) 0%, transparent 70%);
  pointer-events: none;
}

.hero__display {
  font-size: var(--fs-display);
  font-weight: 500;
  letter-spacing: -0.05em;
  line-height: 0.86;
  margin-bottom: var(--sp-5);
}

.hero__meta {
  display: grid;
  grid-template-columns: 16rem 1fr;
  gap: var(--sp-4);
  align-items: start;
}

@media (max-width: 720px) {
  .hero__meta { grid-template-columns: 1fr; gap: var(--sp-2); }
}

/* ---------- Image pleine largeur ---------- */
.fullbleed { position: relative; height: 70svh; overflow: hidden; }

.fullbleed img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Aucun texte ne repose sur cette image : elle reste pleinement
     photographique, seuls les bords se fondent dans la page. */
  filter: grayscale(0.05) contrast(1.04) brightness(1.05);
}

.fullbleed::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, var(--bg) 0%, transparent 18%, transparent 82%, var(--bg) 100%);
}

/* ---------- Modificateurs ponctuels ---------- */
/* Évitent les attributs style= inline dans les pages. */
.eyebrow--faint { color: var(--fg-faint); margin-top: var(--sp-1); }
.page-head { padding-top: var(--sp-7); }
.maquette-note { text-align: center; padding-block: var(--sp-3); }

@media (max-width: 860px) {
  .footer__grid { grid-template-columns: 1fr 1fr; }
}

/* Tablette (860px) : deux colonnes lisibles. Mobile (640px) : une seule,
   sinon les quatre blocs du footer restent en grille 2x2 trop dense. */
@media (max-width: 640px) {
  .footer__grid { grid-template-columns: 1fr; }
}

/* ---------- Extrait de rapport ---------- */
/* Aucun filet : chaque finding est sa propre carte relevée (--bg-raised,
   --r-sm), séparée de la suivante par de l'espace — pas par une ligne. */
.finding-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.finding {
  display: grid;
  grid-template-columns: 8rem 1fr 6rem;
  gap: var(--sp-3);
  align-items: baseline;
  padding: var(--sp-3);
  background: var(--bg-raised);
  border-radius: var(--r-sm);
}

.finding__sev {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.finding__sev--critical { color: var(--sev-critical); }
.finding__sev--high     { color: var(--sev-high); }
.finding__sev--medium   { color: var(--sev-medium); }

.finding__desc { font-size: var(--fs-small); }

.finding__conf {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--fg-faint);
  text-align: right;
}

@media (max-width: 720px) {
  .finding { grid-template-columns: 1fr; gap: var(--sp-1); }
  .finding__conf { text-align: left; }
}

/* ---------- Formulaires (maquette : non fonctionnelle) ---------- */
.form { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-4); }

.field { display: flex; flex-direction: column; gap: var(--sp-1); }

.field__label {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

/* Champ plein (fond --bg-sunken, cadre --rule, --r-sm) plutôt qu'un simple
   soulignement : les deux moitiés du CTA étant désormais sombres toutes les
   deux, un seul jeu de styles suffit — plus de correctif de contraste dédié
   à une moitié inversée. */
.field__input {
  width: 100%;
  background: var(--bg-sunken);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  padding: 0.7rem 0.9rem;
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: 400;
  transition: border-color var(--d-ui) var(--ease-out), background var(--d-ui) var(--ease-out);
}

.field__input:focus { outline: none; border-color: var(--accent); }

.field__input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.field__input::placeholder { color: var(--fg-faint); }

textarea.field__input { resize: vertical; min-height: 6rem; }

/* ---------- Tuiles photographiques ---------- */
/* ---------- Mosaïque de tuiles ---------- */
/* Tailles volontairement inégales : une grille régulière lit comme un tableau,
   une mosaïque lit comme un catalogue de produits. Chaque tuile est une carte
   relevée (--r-lg, ombre teintée), pas une case de tableau. */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 34svh;
  gap: var(--sp-1);
}

.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--sp-4);
  background: var(--bg-raised);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
  isolation: isolate;
}

.tile:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.tile--feature { grid-column: span 2; grid-row: span 2; }
.tile--band { grid-column: span 3; }

.tile__media { position: absolute; inset: -8% 0; z-index: 0; will-change: transform; }

.tile__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* La couleur distingue les tuiles entre elles : quasi aucune désaturation,
     luminosité pleine. Le nom de la tuile reste lisible grâce au dégradé
     localisé de .tile::after, pas grâce à un assombrissement de l'image. */
  filter: grayscale(0.05) contrast(1.06) brightness(1.03);
  transition: transform 900ms var(--ease-out), filter 900ms var(--ease-out);
}

/* La tuile principale porte un nom plus grand que les autres. */
.tile--feature .tile__name { font-size: var(--fs-h1); }

/* Dégradé de lisibilité, au-dessus de l'image et sous le texte : concentré
   sur le tiers bas où vit .tile__body (justify-content: flex-end), transparent
   au-dessus pour laisser la photo pleinement visible ailleurs dans la tuile. */
.tile::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to top, var(--bg) 0%, rgba(11,11,11,0.72) 42%, transparent 78%);
}

.tile__body { position: relative; z-index: 2; }

/* L'étiquette de section, dans une tuile, se pose parfois sur la zone la
   plus claire de la photo (le dégradé s'atténue avant elle) : elle passe de
   --fg-faint à --fg-muted et gagne une ombre douce pour rester lisible sans
   rivaliser avec le nom de la tuile. */
.tile__body .eyebrow {
  color: var(--fg-muted);
  text-shadow: 0 1px 10px rgba(7, 7, 7, 0.85);
}

.tile__name {
  font-size: var(--fs-h2);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
  margin-top: var(--sp-2);
  text-shadow: 0 2px 20px rgba(7, 7, 7, 0.6);
}

.tile__tag {
  margin-top: var(--sp-2);
  font-size: var(--fs-small);
  color: var(--fg-muted);
  max-width: 40ch;
  text-shadow: 0 1px 12px rgba(7, 7, 7, 0.7);
}

.tile__arrow {
  position: absolute;
  right: var(--sp-4);
  bottom: var(--sp-4);
  z-index: 2;
  font-size: 1.35rem;
  line-height: 1;
  color: var(--fg-muted);
  transition: transform var(--d-ui) var(--ease-out), color var(--d-ui) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .tile:hover .tile__media img {
    transform: scale(1.04);
    filter: grayscale(0) contrast(1.06) brightness(1.08);
  }

  .tile:hover .tile__arrow { transform: translate(4px, -4px); color: var(--fg); }
}

@media (max-width: 900px) {
  .tile-grid { grid-template-columns: 1fr; grid-auto-rows: 44svh; }
  .tile--feature, .tile--band { grid-column: auto; grid-row: auto; }
  .tile--feature .tile__name { font-size: var(--fs-h2); }
}

/* ---------- Texte suivi (mentions légales) ---------- */
/* Une colonne étroite et un interlignage plus ouvert que le reste du site :
   ces pages se lisent, elles ne se parcourent pas. */
.prose { max-width: 68ch; }

.prose h2 {
  font-size: var(--fs-h3);
  font-weight: 500;
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-2);
}

.prose > h2:first-child { margin-top: 0; }

.prose p, .prose li { color: var(--fg-muted); margin-bottom: var(--sp-2); }
.prose ul { margin-left: 1.1rem; }
.prose strong { color: var(--fg); font-weight: 500; }

.prose a {
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--fg-faint);
  transition: text-decoration-color var(--d-ui) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .prose a:hover { text-decoration-color: var(--fg); }
}

.prose__updated { font-size: var(--fs-small); color: var(--fg-faint); }

/* ---------- États de formulaire ---------- */
/* Le champ piège : invisible et hors du parcours clavier, rempli seulement
   par les robots qui remplissent tout ce qu'ils trouvent. */
.hp {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.field__input[aria-invalid="true"] { border-color: var(--sev-critical); }

.field__error {
  font-size: var(--fs-small);
  color: var(--sev-critical);
}

.form__status {
  font-size: var(--fs-small);
  color: var(--fg-muted);
  min-height: 1.5rem;
}

.form__status--ok { color: var(--fg); }
.form__status--ko { color: var(--sev-critical); }

.btn[disabled] { opacity: 0.5; pointer-events: none; }

/* Lien en cours de texte : souligné, parce qu'un simple changement de couleur
   ne se voit pas dans une palette monochrome. */
.link {
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--fg-faint);
  transition: text-decoration-color var(--d-ui) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .link:hover { text-decoration-color: var(--fg); }
}
