/* v6 — Flip Loop
   Aucun scroll. Même layout split que v5 (titre à gauche de la couture, corps à
   droite), mais la rotation est pilotée par la VÉLOCITÉ de la souris, pas sa
   position. À chaque passage sur la tranche la face cachée prend le statement
   suivant — boucle infinie sur les 4 statements.

   Deux sliders (speed + text size) en position fixe, bas gauche.
   Encre noire des deux côtés (cf. decisions.md #16/#22/#27). */

html, body { height: 100%; overflow: hidden; }

/* Retrait des quatre coins, nommé une seule fois. Le logo et l'email portaient deux
   valeurs écrites séparément (30px contre var(--gutter)) : leurs bords hauts ne
   tombaient pas au même endroit. */
:root { --corner-x: 40px; --corner-y: 30px; --edge: 15px; --sun-inset: 16px; /* (44 px - disque 12 px) / 2 */ }
@media (max-width: 640px) {
  :root { --corner-x: var(--gutter); --corner-y: var(--gutter); --edge: calc(var(--gutter) / 2); }
}

/* ---- Grain papier ----
   Bruit fractal généré en SVG et embarqué en data URI : aucun fichier à charger, et
   ça reste net à n'importe quelle densité d'écran. Posé au-dessus de tout (splash
   compris, d'où 9500 > 9000) pour que le voile soit continu.

   Pas de mix-blend-mode : multiply disparaîtrait sur le noir du mode sombre et overlay
   s'éteint aussi sur les valeurs extrêmes. Une simple opacité très basse fonctionne sur
   les aplats de charte comme sur le noir. */
.grain {
  position: fixed;
  inset: 0;
  z-index: 9500;
  pointer-events: none;
  opacity: 0.045;
  /* En base64 et non en SVG échappé : sous cette forme le `url(#n)` interne du filtre
     n'était pas résolu et le voile restait vide, même à pleine opacité. */
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyMDAnIGhlaWdodD0nMjAwJz48ZmlsdGVyIGlkPSduJyB4PScwJyB5PScwJyB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJz48ZmVUdXJidWxlbmNlIHR5cGU9J2ZyYWN0YWxOb2lzZScgYmFzZUZyZXF1ZW5jeT0nMC44NScgbnVtT2N0YXZlcz0nNCcgc3RpdGNoVGlsZXM9J3N0aXRjaCcvPjwvZmlsdGVyPjxyZWN0IHdpZHRoPScyMDAnIGhlaWdodD0nMjAwJyBmaWx0ZXI9J3VybCgjbiknLz48L3N2Zz4=");
  background-size: 200px 200px;
}

body {
  background: var(--half-l, var(--bab-magenta));
}

/* ---- Les deux moitiés ---- */
.split {
  position: fixed;
  inset: 0;
  display: flex;
  z-index: 1;
  pointer-events: none;
}
.split__half { width: 50vw; height: 100vh; }
/* En mode sombre/clair les deux moitiés prennent la même couleur : sans cette couture
   le split disparaîtrait complètement. --site-seam suit donc le mode (posée par
   shared/splash.js), et vaut le liseré d'origine tant qu'on est aux couleurs de charte. */
.split__half--l { background: var(--half-l, var(--bab-magenta)); border-right: 1px solid var(--site-seam, rgba(0,0,0,0.06)); }
.split__half--r { background: var(--half-r, var(--bab-blue)); }

/* ---- Galerie scroll-magnétique (moitié gauche uniquement) ----
   Derrière le flip-loop (z-index 20) mais devant les aplats de couleur (z-index 1).
   pointer-events: none — la détection souris/scroll se fait au niveau du document
   dans main.js, pas via le hover CSS de cet élément. Un item à la fois est visible :
   il pivote depuis la charnière côté couture (bord droit de la moitié gauche), comme
   les blocs de dialogue de la référence thirdsubjectivitytoday.robynn.xyz (mécanique
   B, cf. docs/research.md §2) — snap net, ease-out, sans rebond. */
.gallery {
  position: fixed;
  inset: 0 50vw 0 0;
  z-index: 10;
  overflow: hidden;
  pointer-events: none;
  perspective: 900px;
}
.gallery__item {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: rotateY(78deg);
  transform-origin: 100% 50%;
  transition: opacity 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}
.gallery__item.is-active { opacity: 1; transform: rotateY(0deg); }

.is-still .gallery { display: none; }

/* ---- Coins ---- */
/* Taille/position du logo alignées sur v7-block-flow (.header/.logo-main) :
   top/left 30px 40px, largeur clamp(50px, 11vw, 150px) au lieu du var(--gutter)
   générique des autres versions. */
:root { --mark-w: calc(clamp(50px, 11vw, 150px) * var(--mark-scale, 0.5)); } /* logo à 50 % par défaut */
.mark {
  position: fixed;
  /* Même retrait en haut et à gauche (--edge), comme le rond en bas à gauche. */
  top: var(--edge); left: var(--edge);
  z-index: 30;
  width: var(--mark-w);
  color: var(--note-l, var(--bab-blue));
  cursor: pointer; /* il change le duo de couleurs */
}
.mail {
  position: fixed;
  top: var(--edge); right: var(--edge); /* miroir du logo */
  margin-top: -0.33em; /* interligne + approche : le haut des lettres, pas de la boîte, tombe à --edge */
  z-index: 30;
  color: var(--site-ink-r, var(--bab-black)); /* coin haut droit = moitié droite */
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: lowercase;
  letter-spacing: 0.02em;
  opacity: 0.85;
  transition: opacity var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
/* Au survol l'email bascule sur l'opposé de l'aplat qu'il surplombe : noir sur un fond
   clair, blanc sur un fond sombre. La valeur est calculée dans shared/splash.js à partir
   de la luminance réelle de la moitié droite — le CSS seul ne sait pas la déduire. */
.mail:hover { opacity: 1; color: var(--site-contrast-r, var(--bab-black)); }
.mail:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }

/* Le lien ne fait que 20 px de haut : on étend la zone tapable à ~44 px sans bouger
   le texte ni son souligné. Il est seul dans son coin, aucun risque de chevauchement. */
.mail::after { content: ''; position: absolute; inset: -12px -10px; }

/* ---- Scène 3D ---- */
.stage {
  position: fixed;
  inset: 0;
  z-index: 20;
  pointer-events: none;
  perspective: 1100px;
  perspective-origin: 50% 50%;
}

.axis {
  position: absolute;
  top: 50%;
  left: 50vw;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  will-change: transform;
}

/* Deux faces (front / back), chacune avec texte gauche + droite de la couture. */
.row {
  position: absolute;
  top: 0; left: 0;
  width: 100vw;
  transform: translate(-50%, -50%);
  display: flex;
  justify-content: center;
  align-items: center;
  will-change: transform;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.row--back { transform: translate(-50%, -50%) rotateY(180deg); }

.row__inner {
  display: flex;
  width: 100vw;
  justify-content: center;
  align-items: center;
}

/* Encre par moitié : dès que les deux aplats n'ont pas la même valeur (mode sombre =
   noir à gauche, blanc à droite), une encre unique en rendrait une des deux illisible.
   .row__l va de 6vw à 50vw et .row__r de 50vw à 94vw : chaque bloc reste dans sa moitié,
   et la rotation autour de l'axe central ne les fait jamais traverser (backface-
   visibility: hidden — la face visible garde toujours sa gauche à gauche). */
.row__l, .row__r {
  width: 44vw;
  line-height: 1.35;
}
.row__l { color: var(--site-ink-l, var(--bab-black)); }
.row__r { color: var(--site-ink-r, var(--bab-black)); }

.row__l {
  padding-right: 3rem;
  padding-left: 5vw;
  text-align: right;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 0.6rem + 1.8vw, 2rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--tracking-tight);
  transform-origin: 100% 50%;
}
.row__r {
  padding-left: 3rem;
  padding-right: 5vw;
  text-align: left;
  font-family: var(--font-body);
  font-size: clamp(1rem, 0.55rem + 1.5vw, 1.7rem);
  font-weight: 500;
  transform-origin: 0% 50%;
}

/* ---- Bascule clair/sombre ----
   ● est un glyphe d'Inter : le picto est de la typo, pas une icône rapportée. Encre
   de la moitié gauche, puisque c'est là qu'il se pose. */
.sun {
  position: fixed;
  /* Le disque est plus petit que sa cible de 44 px : on décale la boîte pour que le
     disque lui-même soit à --edge du bas et de la gauche. */
  bottom: calc(var(--edge) - var(--sun-inset, 0px)); left: calc(var(--edge) - var(--sun-inset, 0px));
  z-index: 40;
  display: grid;
  place-items: center;
  min-width: 44px; min-height: 44px; /* cible tactile */
  padding: 0;
  border: 0;
  background: none;
  color: var(--site-ink-l, var(--bab-black));
  font-family: var(--font-body);
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.75;
  transition: opacity var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.sun:hover { opacity: 1; }
.sun:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }


/* ---- Repli à plat (mobile ≤ 640 px ou prefers-reduced-motion) ---- */
html.is-still, html.is-still body { overflow-x: hidden; overflow-y: auto; cursor: auto; height: auto; }
.is-still .stage { display: none; }

.fallback { display: none; }
.is-still .fallback {
  display: block;
  position: relative;
  z-index: 20;
  padding: calc(var(--gutter) * 3) var(--gutter) var(--sp-6);
}
.fallback__item {
  color: var(--site-ink-l, var(--bab-black)); /* le repli tombe sur l'aplat de gauche */
  margin-bottom: var(--sp-5);
}
.fallback__item__title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.1rem, 0.6rem + 1.8vw, 2rem);
  text-transform: uppercase;
  letter-spacing: var(--tracking-tight);
  margin-bottom: 0.4em;
}
.fallback__item__body {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(1rem, 0.55rem + 1.5vw, 1.7rem);
}



/* ============================================================
   Téléphone : le texte tourne au doigt (swipe)
   ============================================================
   Le repli à plat restait figé, « un peu sec ». Sur téléphone le stage est donc
   activé — mais recomposé : le split gauche/droite ne laisse qu'une centaine de
   pixels par côté sur 375 px, illisible. Un seul aplat, texte empilé et centré. */
@media (max-width: 640px) {
  /* Un seul aplat : un texte centré à cheval sur la couture serait illisible d'un
     des deux côtés dès que les moitiés n'ont pas la même valeur (mode sombre). */
  .split__half--l { width: 100vw; border-right: 0; }
  .split__half--r { display: none; }

  .row__inner {
    flex-direction: column;
    width: 92vw;
    gap: 0.6rem;
  }
  .row__l, .row__r {
    width: 100%;
    padding: 0;
    text-align: center;
    transform-origin: 50% 50%;
    color: var(--site-ink-l, var(--bab-black)); /* un seul aplat, une seule encre */
  }
  .row__l { font-size: clamp(1.3rem, 6vw, 2.2rem); }
  /* Plancher à 1rem : à 375 px le 4.2vw tombait à 15,75 px, sous le minimum de 16 px
     pour du corps de texte sur téléphone. */
  .row__r { font-size: clamp(1rem, 4.2vw, 1.5rem); }

  /* Le wordmark est nettement plus grand sur téléphone. Sa position, elle, vient déjà
     des variables de coin communes avec l'email. */
  :root { --mark-w: calc(clamp(90px, 30vw, 200px) * var(--mark-scale, 0.5)); }

  /* Gras plein face à un wordmark devenu grand. Le 800 reste réservé aux titres
     display par la charte, le 700 est déjà chargé. */
  .mail { font-weight: 700; color: var(--site-ink-l, var(--bab-black)); }
  .mail:hover { color: var(--site-contrast-l, var(--bab-black)); }

}

/* ---- Téléphone, variante deux couleurs (?m=split) ----
   Coupe haut / bas plutôt que gauche / droite : 375 px ne tiennent pas deux colonnes.
   Titre centré dans la moitié haute (aplat gauche), texte dans la moitié basse
   (aplat droit), chacun avec l'encre de son aplat. */
@media (max-width: 640px) {
  .m-split .split { flex-direction: column; }
  /* dvh : la hauteur VISIBLE du téléphone (barre du navigateur exclue), sinon la couture
     et les textes glissent sous la barre et ne sont plus au milieu. */
  .m-split .split__half { width: 100vw; height: 50vh; height: 50dvh; }
  .m-split .split__half--l { border-right: 0; border-bottom: 1px solid var(--site-seam, rgba(0,0,0,0.06)); }
  .m-split .split__half--r { display: block; }

  .m-split .row__inner { height: 100vh; height: 100dvh; gap: 0; }
  .m-split .row__l, .m-split .row__r {
    height: 50vh; height: 50dvh;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .m-split .row__r { color: var(--site-ink-r, var(--bab-black)); }

  /* Le cercle et la pastille sont en bas : sur l'aplat droit. */
  .m-split .sun { color: var(--site-ink-r, var(--bab-black)); }
}


/* Titre / texte intervertis au hasard sur téléphone (cf. fillFace dans main.js) :
   chaque bloc prend la typo de ce qu'il porte. */
@media (max-width: 640px) {
  .row__l.as-body {
    font-family: var(--font-body); font-weight: 500;
    text-transform: none; letter-spacing: normal;
    font-size: clamp(1rem, 4.2vw, 1.5rem);
  }
  .row__r.as-title {
    font-family: var(--font-display); font-weight: 800;
    text-transform: uppercase; letter-spacing: var(--tracking-tight);
    font-size: clamp(1.3rem, 6vw, 2.2rem);
  }
}
