/* Accueil — nathancomte.fr — « Réseau vivant »
 * Calques : ambiance (repli sans WebGL) < scène (canvas) < grain < page < portail
 */

:root {
  --fond: #0B0B0F;
  --texte: #F5F5F7;
  --texte-2: #A1A1AA;      /* 7,9:1 sur le fond ; ≥ 4,7:1 même sous la lueur d'un survol */
  --filet: rgba(255, 255, 255, .13);
  --chaud-1: #FF7A30;
  --chaud-2: #FF3D7F;
  --chaud-3: #9B5CFF;
  --gouttiere: clamp(16px, 3.6vw, 56px);
  --ecart-col: clamp(28px, 3.6vw, 64px);
  --police: "Inter Tight", -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --sortie: cubic-bezier(.16, 1, .3, 1);   /* expo, arrivée très douce */
  --entree: cubic-bezier(.7, 0, .84, 0);   /* accélération (portail) */
  --douce: cubic-bezier(.65, 0, .35, 1);
  color-scheme: dark;
}

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

html {
  background: var(--fond);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  background: var(--fond);
  color: var(--texte);
  font-family: var(--police);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  overflow-x: clip;
}

::selection { background: rgba(255, 122, 48, .38); color: #fff; }

:focus-visible { outline: 2px solid var(--texte); outline-offset: 4px; }

/* lu par les lecteurs d'écran, invisible à l'écran */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Petites étiquettes : seule la mono système, en petites capitales */
.etiquette,
.espaces__entete,
.espace__meta,
.entete__demo,
.entete__mouvement {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--texte-2);
}

/* ---------- Calques de fond ---------- */

.scene {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100vh;
  height: 100lvh;
  pointer-events: none;
  transition: opacity .8s ease;
}
/* réseau lent : la scène arrive en fondu par-dessus les orbes CSS déjà affichées */
.scene--entree { opacity: 0; transition: none; }

/* Orbes CSS : avant le script, puis seulement si la scène WebGL ne les dessine pas
   elle-même (le script les masque une fois la scène affichée) */
.ambiance {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.orbe {
  position: absolute;
  width: 80vmax;
  height: 80vmax;
  border-radius: 50%;
  will-change: transform;
}
.orbe--1 {
  left: 38%;
  top: -46vmax;
  background: radial-gradient(closest-side, rgba(255, 56, 122, .18), rgba(255, 56, 122, 0));
  animation: derive-1 27s var(--douce) infinite alternate;
}
.orbe--2 {
  left: 30%;
  top: 8vmax;
  width: 60vmax;
  height: 60vmax;
  background: radial-gradient(closest-side, rgba(158, 77, 255, .09), rgba(158, 77, 255, 0));
  animation: derive-2 23s var(--douce) infinite alternate;
}
.orbe--3 {
  left: -40vmax;
  top: 40%;
  background: radial-gradient(closest-side, rgba(117, 77, 255, .2), rgba(117, 77, 255, 0));
  animation: derive-3 31s var(--douce) infinite alternate;
}
@keyframes derive-1 { to { transform: translate3d(-8vmax, 5vmax, 0); } }
@keyframes derive-2 { to { transform: translate3d(9vmax, -4vmax, 0); } }
@keyframes derive-3 { to { transform: translate3d(7vmax, -6vmax, 0); } }
/* sans script, rien ne peut mettre le mouvement en pause : les orbes restent immobiles */
html:not(.js) .orbe { animation: none; }

.grain {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image: var(--grain, none);
  background-size: 160px 160px;
  opacity: .055;
}

/* ---------- Page ---------- */

.page {
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  padding: 0 max(var(--gouttiere), env(safe-area-inset-right)) 0 max(var(--gouttiere), env(safe-area-inset-left));
  transform-origin: var(--portail-x, 50%) var(--portail-y, 50%);
  touch-action: manipulation;
}

.entete {
  display: flex;
  align-items: center;
  justify-content: flex-end;   /* le nom, en grand juste en dessous, suffit comme marque */
  gap: 16px;
  min-height: 44px;
  padding-top: max(clamp(14px, 3vh, 30px), env(safe-area-inset-top));
}

.principal {
  display: flex;
  flex: 1;
  flex-direction: column;
}

.hero { padding-top: clamp(36px, 9.5vh, 128px); }

.titre {
  margin: 0 0 0 -0.052em;
  font-size: 128px;
  font-size: clamp(72px, min(12.8vw, 20.5vh), 212px);
  font-weight: 650;
  line-height: .86;
  letter-spacing: -0.045em;
  font-kerning: normal;
}
[data-espaces="grille"] .titre,
[data-espaces="index"] .titre { font-size: clamp(64px, min(11.6vw, 17.5vh), 196px); }
.mot {
  display: block;
  width: -webkit-fit-content;
  width: fit-content;
  padding-right: .06em;
}
.mot--chaud {
  background: linear-gradient(90deg, var(--chaud-1) 0%, var(--chaud-2) 52%, var(--chaud-3) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.accroche {
  width: -webkit-fit-content;
  width: fit-content;
  margin: clamp(20px, 3.4vh, 34px) 0 0;
  max-width: 34ch;
  font-size: clamp(17px, 1.42vw, 21px);
  line-height: 1.4;
  letter-spacing: -0.012em;
  color: var(--texte-2);
}

.entete__demo { margin-right: auto; white-space: nowrap; }

/* Pause de l'animation : une étiquette, comme les autres, sans icône */
.entete__mouvement {
  flex: none;
  min-width: 44px;
  margin: -14px -2px -14px 0;   /* grande zone de toucher, sans grandir l'en-tête */
  padding: 16px 2px 16px 14px;
  border: 0;
  background: none;
  text-align: right;
  cursor: pointer;
  transition: color .3s ease;
  -webkit-tap-highlight-color: transparent;
}
.entete__mouvement:hover,
.entete__mouvement:focus-visible { color: var(--texte); }
/* focus clavier : l'anneau entoure le mot, pas la grande zone de toucher */
.entete__mouvement:focus-visible { outline: none; }
.entete__mouvement:focus-visible .entete__mouvement-texte {
  outline: 2px solid var(--texte);
  outline-offset: 6px;
  border-radius: 3px;
}
.entete__mouvement[hidden] { display: none; }

/* ---------- Espaces ---------- */

.espaces {
  margin-top: auto;
  padding: clamp(40px, 7vh, 76px) 0 max(clamp(16px, 4vh, 44px), env(safe-area-inset-bottom));
}
.espaces[hidden] { display: none; }
/* avec le script, la section n'apparaît qu'une fois remplie (sans script : message <noscript>) */
.js .espaces:not(.espaces--pret) { display: none; }

.espaces__erreur {
  margin: 0;
  padding: 22px 0 6px;
  border-top: 1px solid var(--filet);
  font-size: 15px;
  line-height: 1.45;
  color: var(--texte-2);
}

.espaces__entete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 22px;
}
.espaces__entete h2 { margin: 0; font: inherit; letter-spacing: inherit; }

.espaces__liste {
  --cols: 1;
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  column-gap: var(--ecart-col);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* chaque entrée remplit sa rangée : filets alignés d'une colonne à l'autre */
.espaces__item { display: grid; min-width: 0; }

@media (min-width: 760px) {
  .espaces__liste { --cols: var(--cols-m, 2); }
}
@media (min-width: 1180px) {
  .espaces__liste { --cols: var(--cols-l, 2); }
}
/* un seul espace : une colonne, pas toute la largeur (en-tête compris) */
@media (min-width: 760px) {
  .espaces--seul .espaces__entete,
  .espaces--seul .espaces__liste { max-width: min(640px, 50%); }
}
/* cinq espaces : 2 + 3 (première rangée plus large), jamais de trou en bas à droite */
@media (min-width: 760px) and (max-width: 1179px) {
  .espaces__liste--cinq > .espaces__item:first-child { grid-column: 1 / -1; }
}
@media (min-width: 1180px) {
  .espaces__liste--cinq { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .espaces__liste--cinq > .espaces__item { grid-column: span 2; }
  .espaces__liste--cinq > .espaces__item:nth-child(-n+2) { grid-column: span 3; }
}

.espace {
  position: relative;
  display: block;
  padding: 24px 0 30px;
  color: inherit;
  text-decoration: none;
  container-type: inline-size;
  -webkit-tap-highlight-color: transparent;
}

/* Filet neutre (tracé à l'arrivée) et filet de l'accent (au survol) */
.espace::before,
.espace::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  transform-origin: left center;
  pointer-events: none;
}
.espace::before { background: var(--filet); }
.espace::after {
  background: var(--accent);
  opacity: .7;
  transform: scaleX(0);
  transition: transform .9s var(--sortie);
}

/* Le nœud : là où le réseau vient se brancher */
.espace__noeud {
  position: absolute;
  left: 0;
  top: 0;
  width: 11px;
  height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  background: var(--fond);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .78);
  transition: background-color .45s var(--sortie), box-shadow .45s var(--sortie);
}
.espace__noeud::before,
.espace__noeud::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--accent);
  opacity: 0;
}

/* Un signal parcourt le filet : du nœud vers l'espace */
.espace__lueur {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  overflow: hidden;
  pointer-events: none;
}
.espace__lueur::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: linear-gradient(90deg, transparent calc(100% - 110px), var(--accent) calc(100% - 12px), #fff);
  opacity: 0;
  transform: translateX(-100%);
}

.espace__corps {
  position: relative;
  z-index: 1;               /* les ondes du nœud passent sous les textes */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "meta meta"
    "titre action"
    "accroche accroche";
  align-items: end;
}

.espace__meta {
  grid-area: meta;
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 12px;
}
/* numéro : seulement en mode index (7 espaces et plus), où il aide à se repérer */
.espace__num { display: none; font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.espace__statut {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
.espace__statut i {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
.espace--bientot .espace__statut i {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--accent);
}

.espace__titre {
  grid-area: titre;
  justify-self: start;
  margin-top: 22px;
  font-size: clamp(36px, 4.2vw, 60px);
  font-size: clamp(34px, 8.8cqi, 64px);
  font-weight: 620;
  line-height: .96;
  letter-spacing: -0.042em;
  overflow-wrap: anywhere;
  transition: color .5s ease;
}
/* Bientôt : en retrait mais élégant — l'espace en ligne domine (titre à ~52 %, contraste 5:1) */
.espace--bientot .espace__titre { color: rgba(245, 245, 247, .52); font-weight: 580; }
.espace--bientot .espace__accroche { color: #7C7C84; }
.espace--bientot.actif .espace__titre { color: rgba(245, 245, 247, .66); }

.espace__accroche {
  grid-area: accroche;
  justify-self: start;
  max-width: 46ch;
  margin-top: 14px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--texte-2);
  transition: color .5s ease;
}

/* Le bouton pilule blanc, sans brillance */
.espace__action {
  grid-area: action;
  justify-self: end;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 40px;
  margin-left: 16px;
  padding: 0 16px 0 20px;
  border-radius: 999px;
  background: var(--texte);
  color: var(--fond);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  transition: background-color .35s ease, color .35s ease, box-shadow .35s ease;
}
.espace__action svg {
  width: 14px;
  height: 14px;
  transition: transform .7s var(--sortie);
}

/* ----- Grille (4 à 6 espaces) : plus compacte, flèche seule ----- */
.espaces__liste--grille .espace { padding: 22px 0 26px; }
.espaces__liste--grille .espace__titre { margin-top: 18px; font-size: clamp(28px, 4vw, 40px); font-size: clamp(28px, 10cqi, 44px); }
.espaces__liste--grille .espace__accroche { margin-top: 10px; font-size: 14px; }

/* ----- Index (7 espaces et plus) : numéro, titre, accroche dessous, flèche à droite ;
   toutes les accroches partent du même axe, chaque rangée a la même structure ----- */
.espaces__liste--index .espace { padding: 16px 0 18px; }
.espaces__liste--index .espace__corps {
  grid-template-columns: 2.6em minmax(0, 1fr) auto 34px;
  grid-template-areas:
    "num titre statut action"
    ". accroche accroche action";
  align-items: center;
  column-gap: 18px;
  row-gap: 5px;
}
.espaces__liste--index .espace__meta { display: contents; }
.espaces__liste--index .espace__num { display: block; grid-area: num; }
.espaces__liste--index .espace__statut { grid-area: statut; }
.espaces__liste--index .espace__titre { margin: 0; font-size: 26px; font-size: clamp(22px, 4.6cqi, 28px); letter-spacing: -0.035em; }
.espaces__liste--index .espace__accroche {
  justify-self: stretch;
  margin: 0;
  max-width: 60ch;
  font-size: 14px;
  line-height: 1.4;
}
/* modes compacts : l'accroche passe à la ligne (2 lignes au plus : 60 caractères tiennent) */
.espaces__liste--index .espace__accroche,
.espaces__liste--grille .espace__accroche {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
/* index sur deux colonnes : lu de haut en bas (01 à 05 à gauche, 06 à 10 à droite) ;
   l'ordre du document, la numérotation et la tabulation coïncident */
@media (min-width: 1180px) {
  .espaces__liste--index { grid-auto-flow: column; grid-template-rows: repeat(var(--rangs, 5), auto); }
}

/* Grille et index : la pilule devient une flèche dans un cercle fin */
.espaces__liste--grille .espace__action,
.espaces__liste--index .espace__action {
  width: 34px;
  height: 34px;
  padding: 0;
  margin-left: 14px;
  background: transparent;
  color: var(--texte);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
}
.espaces__liste--grille .espace__action-texte,
.espaces__liste--index .espace__action-texte { display: none; }
.espaces__liste--grille .espace__action svg,
.espaces__liste--index .espace__action svg { width: 13px; height: 13px; }
.espaces__liste--index .espace__action { grid-area: action; margin-left: 0; }

/* ----- Ordinateur et tablette : grille alignée, index compact ----- */
@media (min-width: 760px) {
  /* Grille : un titre sur deux lignes ne décale rien. La flèche se cale sur la première
     ligne du titre, et les accroches d'une même rangée partent de la même hauteur (sous-grille). */
  .espaces__liste--grille .espace__titre {
    align-self: start;
    font-size: clamp(26px, 8.5cqi, 40px);
    text-wrap: balance;
  }
  .espaces__liste--grille .espace__action {
    align-self: start;
    margin-top: calc(18px + (clamp(26px, 8.5cqi, 40px) * .96 - 34px) / 2);
  }
  .espaces__liste--grille .espace__accroche { align-self: start; }
  /* La sous-grille demande une entrée sans conteneur de taille (il isolerait sa mise en
     page) : la taille du titre suit alors la largeur d'une colonne, calculée ici. */
  @supports (grid-template-rows: subgrid) {
    .espaces__liste--grille {
      --col-l: calc((100vw - 2 * var(--gouttiere) - (var(--cols) - 1) * var(--ecart-col)) / var(--cols));
      --titre-g: clamp(26px, calc(var(--col-l) * .085), 40px);
    }
    .espaces__liste--grille > .espaces__item { grid-row: span 3; grid-template-rows: subgrid; }
    .espaces__liste--grille .espace { container-type: normal; grid-row: 1 / -1; display: grid; grid-template-rows: subgrid; }
    .espaces__liste--grille .espace__corps { grid-row: 1 / -1; grid-template-rows: subgrid; }
    .espaces__liste--grille .espace__meta { grid-row: 1; grid-column: 1 / -1; }
    .espaces__liste--grille .espace__titre { grid-row: 2; grid-column: 1; font-size: var(--titre-g); }
    .espaces__liste--grille .espace__action { grid-row: 2; grid-column: 2; margin-top: calc(18px + (var(--titre-g) * .96 - 34px) / 2); }
    .espaces__liste--grille .espace__accroche { grid-row: 3; grid-column: 1 / -1; }
  }

  /* Index (7 espaces et plus) : rangées de 64 à 68 px ; dix espaces tiennent en
     1440 × 900, et quatre rangées au moins se lisent en 1280 × 720 */
  [data-espaces="index"] .titre { font-size: clamp(60px, min(10vw, 15vh), 180px); }
  [data-espaces="index"] .espaces { padding-top: clamp(24px, 4vh, 48px); }
  .espaces__liste--index .espace { padding: 10px 0 12px; }
  .espaces__liste--index .espace__corps { row-gap: 3px; }
  .espaces__liste--index .espace__titre { font-size: clamp(20px, 4cqi, 24px); }
}

/* Survol, focus clavier, toucher : même état. Le focus clavier n'ajoute pas de cadre autour
   de l'entrée (pas de « carte ») : un anneau net entoure la pilule (ou la flèche). */
.espace:focus-visible { outline: none; }
.espace:focus-visible .espace__action { outline: 2px solid var(--texte); outline-offset: 4px; }
.espace.actif::after,
.espace:focus-visible::after { transform: scaleX(1); }
.espace.actif .espace__accroche,
.espace:focus-visible .espace__accroche { color: var(--texte); }
.espace--bientot.actif .espace__accroche { color: var(--texte-2); }
.espace.actif .espace__action svg,
.espace:focus-visible .espace__action svg { transform: translateX(3px); }
.espaces__liste--grille .espace.actif .espace__action,
.espaces__liste--index .espace.actif .espace__action,
.espaces__liste--grille .espace:focus-visible .espace__action,
.espaces__liste--index .espace:focus-visible .espace__action {
  background: var(--texte);
  color: var(--fond);
  box-shadow: none;
}
.espace.actif .espace__noeud,
.espace:focus-visible .espace__noeud {
  background: var(--accent);
  box-shadow: inset 0 0 0 1.5px var(--accent), 0 0 0 4px var(--fond);
}
.espace.actif .espace__noeud::before,
.espace:focus-visible .espace__noeud::before { animation: onde 2s var(--sortie) infinite; }
.espace.actif .espace__noeud::after,
.espace:focus-visible .espace__noeud::after { animation: onde 2s var(--sortie) 1s infinite; }
.js .espace.actif .espace__lueur::before,
.js .espace:focus-visible .espace__lueur::before { animation: route 1.6s cubic-bezier(.45, 0, .2, 1) .12s infinite; }

/* les ondes s'arrêtent avant les petites étiquettes voisines (numéro, « Espaces ») */
@keyframes onde {
  0% { transform: scale(1); opacity: .95; }
  100% { transform: scale(var(--onde, 3.6)); opacity: 0; }
}
@keyframes route {
  0% { transform: translateX(-100%); opacity: 1; }
  72% { transform: translateX(0); opacity: 1; }
  100% { transform: translateX(0); opacity: 0; }
}
/* signal de repos : lent et discret (accent à 50 %), du nœud vers la pilule */
@keyframes signal {
  0% { transform: translateX(-100%); opacity: 0; }
  9% { opacity: .5; }
  50% { transform: translateX(0); opacity: .5; }
  60%, 100% { transform: translateX(0); opacity: 0; }
}

/* ---------- Chorégraphie d'arrivée (jamais bloquante, jamais floue) ----------
   Le nom d'abord, puis l'accroche, puis les espaces : la liste attend le signal de la
   scène (classe espaces--montre, vers 1,45 s de l'intro) ; filets, nœuds, puis entrées.
   En attendant, elle est transparente mais cliquable et atteignable au clavier. */

.js .entete { animation: apparition .9s ease .05s both; }
.js .espaces:not(.espaces--montre) .espaces__entete,
.js .espaces:not(.espaces--montre) .espace__corps,
.js .espaces:not(.espaces--montre) .espace__lueur { opacity: 0; }
.js .espaces:not(.espaces--montre) .espace::before { transform: scaleX(0); }
.js .espaces:not(.espaces--montre) .espace__noeud { transform: scale(0); }
.js .espaces--montre .espaces__entete { animation: monter 1s var(--sortie) both; }
.js .espaces--montre .espace::before { animation: tracer 1.3s var(--sortie) calc(.05s + var(--i, 0) * .07s) both; }
.js .espaces--montre .espace__noeud { animation: eclore .9s var(--sortie) calc(.16s + var(--i, 0) * .07s) both; }
.js .espaces--montre .espace__corps { animation: monter 1.1s var(--sortie) calc(.24s + var(--i, 0) * .07s) both; }
/* En ligne : de loin en loin (toutes les 7,6 s), un signal parcourt le filet, du nœud
   vers la pilule. « Bientôt » reste immobile : au repos, l'œil va à ce qui s'ouvre. */
.js a.espace .espace__lueur::before { animation: signal 7.6s var(--douce) calc(3.2s + var(--i, 0) * 1.3s) infinite; }

/* le texte n'attend jamais un script : au pire, il apparaît au bout de 3,5 s
   (quand la scène pilote l'intro, le script a son propre filet de sécurité) */
.js .titre,
.js .accroche { animation: secours 0s linear 3.5s forwards; }
.intro-pilotee .titre,
.intro-pilotee .accroche { animation: none; }
.js .titre { opacity: 0; }
.js .titre.net { opacity: 1; transition: opacity .32s ease; }
.js .accroche { opacity: 0; transform: translateY(10px); }
.js .accroche.net {
  opacity: 1;
  transform: none;
  transition: opacity .6s ease, transform .9s var(--sortie);
}

@keyframes secours { to { opacity: 1; transform: none; } }
@keyframes apparition { from { opacity: 0; } }
@keyframes monter { from { opacity: 0; transform: translateY(16px); } }
@keyframes tracer { from { transform: scaleX(0); } }
@keyframes eclore { from { transform: scale(0); } }

/* ---------- Portail ---------- */

.portail {
  position: fixed;
  inset: 0;
  z-index: 20;
  overflow: hidden;
  pointer-events: none;
  visibility: hidden;
}
.portail__disque {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: 50%;
  background: var(--dest, #0B0B0F);
  transform: scale(0);
  will-change: transform;
}
@supports (background: color-mix(in srgb, red 50%, blue)) {
  .portail__disque {
    background: radial-gradient(closest-side, var(--dest, #0B0B0F) 84%, color-mix(in srgb, var(--accent-portail, #fff) 16%, var(--dest, #0B0B0F)) 99.4%, transparent 100%);
  }
  /* une lumière d'accent au cœur du disque (l'espace s'ouvre), éteinte avant la fin */
  .portail__disque::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--accent-portail, #fff) 34%, transparent), transparent 70%);
    opacity: var(--lueur, 0);
  }
}
.en-portail .portail { visibility: visible; pointer-events: auto; }
/* la page avance d'un pas vers le point cliqué ; tout s'efface sauf l'entrée choisie,
   que le disque recouvre ensuite */
.en-portail .page {
  transform: scale(1.05);
  pointer-events: none;
  transition: transform .8s var(--entree);
}
.en-portail .entete,
.en-portail .hero,
.en-portail .espaces__entete,
.en-portail .espaces__item:not(.source) {
  opacity: 0;
  animation: none;
  transition: opacity .3s ease;
}
.en-portail .grain { opacity: 0; transition: opacity .6s ease; }
.portail--fondu .portail__disque {
  inset: 0;
  width: auto !important;
  height: auto !important;
  border-radius: 0;
  background: var(--dest, #0B0B0F);
  transform: none !important;
  opacity: 0;
  transition: opacity .22s ease;
}
.en-portail .portail--fondu .portail__disque { opacity: 1; }

/* ---------- Téléphone ---------- */

@media (max-width: 759px) {
  .titre,
  [data-espaces="grille"] .titre,
  [data-espaces="index"] .titre {
    margin-left: -0.05em;
    font-size: clamp(64px, 27vw, 132px);
  }
  .hero { padding-top: clamp(40px, 9.5vh, 100px); }
  .accroche { font-size: 17px; }
  .espaces { padding-top: 44px; }
  .espace { padding: 22px 0 26px; }
  .espace__titre { margin-top: 20px; font-size: clamp(34px, 10.4vw, 46px); }
  .espace__action { height: 38px; padding: 0 14px 0 17px; font-size: 14px; }

  /* 4 espaces et plus : des lignes compactes */
  .espaces__liste--grille .espace,
  .espaces__liste--index .espace { --onde: 2.6; padding: 15px 0 16px; }
  .espaces__liste--grille .espace__corps,
  .espaces__liste--index .espace__corps {
    grid-template-columns: minmax(0, 1fr) minmax(30px, auto);
    grid-template-areas:
      "titre statut"
      "accroche action";
    align-items: center;
    column-gap: 10px;
    row-gap: 4px;
  }
  /* index : le numéro garde sa colonne */
  .espaces__liste--index .espace__corps {
    grid-template-columns: 2.4em minmax(0, 1fr) minmax(30px, auto);
    grid-template-areas:
      "num titre statut"
      ". accroche action";
  }
  .espaces__liste--grille .espace__meta { display: contents; }
  .espaces__liste--grille .espace__statut { grid-area: statut; }
  .espaces__liste--grille .espace__titre,
  .espaces__liste--index .espace__titre { margin: 0; font-size: 24px; letter-spacing: -0.035em; }
  /* l'accroche prend toute la largeur sous le titre (la flèche se loge à sa droite)
     et passe à la ligne autant qu'il faut : jamais coupée */
  .espaces__liste--grille .espace__accroche,
  .espaces__liste--index .espace__accroche {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: stretch;
    display: block;
    margin: 0;
    font-size: 14px;
    line-height: 1.4;
    overflow: visible;
    -webkit-line-clamp: none;
    line-clamp: none;
  }
  .espaces__liste--index .espace__accroche { grid-column: 2 / -1; }
  .espaces__liste--grille a.espace .espace__accroche,
  .espaces__liste--index a.espace .espace__accroche { padding-right: 42px; }
  .espaces__liste--grille .espace__action,
  .espaces__liste--index .espace__action {
    grid-column: -2;
    grid-row: 2;
    justify-self: end;
    width: 30px;
    height: 30px;
    margin: -6px 0;          /* la flèche ne grandit pas la ligne : même rythme avec ou sans lien */
  }
}

/* ---------- Pause demandée par le visiteur ---------- */

.pause .orbe { animation-play-state: paused; }
html.pause .espace__lueur::before { animation: none !important; opacity: 0; }
html.pause .espace__noeud::before,
html.pause .espace__noeud::after { animation: none !important; opacity: 0; }

/* ---------- Mouvement réduit : statique, fondus courts ---------- */

@media (prefers-reduced-motion: reduce) {
  .js .entete,
  .js .espaces--montre .espaces__entete,
  .js .espaces--montre .espace__corps,
  .js .espaces--montre .espace__noeud,
  .js .espaces--montre .espace::before { animation: apparition .35s ease both; }
  .js .espace__lueur::before,
  .js a.espace .espace__lueur::before,
  .js .espace.actif .espace__lueur::before { animation: none; opacity: 0; }
  .js .titre.net { transition: opacity .3s ease; }
  .js .accroche { transform: none; }
  .js .accroche.net { transition: opacity .35s ease; }
  .espace::after,
  .espace__titre,
  .espace__action svg { transition-duration: .2s; }
  .espace.actif .espace__noeud::before,
  .espace.actif .espace__noeud::after,
  .espace:focus-visible .espace__noeud::before,
  .espace:focus-visible .espace__noeud::after { animation: none; }
  .orbe { animation: none; }
  .en-portail .page { transform: none; transition: none; }
}

@media (forced-colors: active) {
  .mot--chaud { color: CanvasText; -webkit-text-fill-color: CanvasText; background: none; }
  .scene, .grain, .ambiance { display: none; }
}
