/* ---- LE FOND D'ATTENTE ----

   Ce que l'on voit AVANT que WebGPU ait peint la premiere image — et ce que
   l'on voit tout court si le GPU n'est pas la. C'est le degrade CSS de
   tokens.css, qui etait reste sur l'ancienne ambiance bleu clair / peche :
   au chargement, l'ancien fond apparaissait une fraction de seconde avant
   d'etre remplace par le nouveau. Un raccord, pas un fondu.

   Les valeurs ci-dessous sont les quatre teintes du shader (fond(), dans
   verre-statue.js) portees en CSS. Elles ne sont PAS derivees des ancres
   OKLCH de tokens.css : celles-la servent aux pages sans statue, qui gardent
   l'aurore claire. C'est une surcharge locale, volontairement independante.

   Si tu changes la palette du shader, change-les ici aussi — c'est le seul
   endroit du projet ou la meme couleur est ecrite deux fois, et c'est
   assume : l'une est du WGSL, l'autre du CSS. */
:root {
  --color-bg: #4A5F63;
  --degrade-abysse: rgb(33, 61, 69);
  --degrade-bleu:   rgb(61, 117, 128);
  --degrade-gris:   rgb(102, 130, 135);
  --degrade-peche:  rgb(189, 128, 66);
  --degrade-orange: rgb(189, 128, 66);
  --degrade-socle:  rgb(120, 148, 153);

  /* ---- L'ENCRE DE LA SCENE ----
     Blanche. Un seul endroit pour le dire, et toutes les pieces posees sur le
     decor le lisent : le bandeau du H1, la ligne de posture, l'heure, le
     logotype, les titres des travaux.

     Ce qui n'en depend PAS, et c'est voulu : les etiquettes de l'en-tete
     (pave noir), la barre de chat (verre fume) et le pied (noir plein). Ces
     trois-la portent leur propre fond, donc leur propre encre — ils tiennent
     sur n'importe quelle scene. C'est tout l'interet de les avoir faits
     opaques.

     L'OMBRE. Le degre de clarte du fond n'est pas uniforme : le cuivre
     remonte par endroits, et du blanc y perd le peu d'avance qu'il a. Une
     ombre portee tres douce — noire, large, a 38 % — tient les lettres sans
     se voir. Elle ne remplace pas le contraste, elle rattrape les zones les
     plus claires du degrade. */
  --encre-scene: #FFFFFF;
  --encre-scene-attenuee: rgba(255, 255, 255, 0.72);
  /* Une ombre discrete, une seule couche. Elle pose juste ce qu'il faut de
     sombre sous les lettres pour qu'elles ne se dissolvent pas dans le
     degrade — pas un halo. */
  --ombre-scene: 0 1px 8px rgba(0, 0, 0, 0.16);
}

/* ============================================================
   HERO EAU — surcharge de la page d'accueil (chargee apres styles.css).
   Le canvas WebGPU (assets/verre-statue.js) peint le fond, l'objet d'eau et le
   logotype derriere ; le mur d'aurore et le cube ne sont plus affiches.
   ============================================================ */

/* le canvas : plein ecran, sous tout le reste (les brumes z4, la section 2 z5,
   l'en-tete et la barre z6 passent dessus : la narration au scroll est intacte) */
.liquide {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  /* TRANSPARENT AUX CLICS. Meme panne que .shell dans styles.css : ce canvas
     couvre tout l'ecran, en permanence, et il recevait donc les clics de
     toute la page — le bouton « Activer le son » de la vitrine ne repondait
     pas (elementFromPoint sur le bouton renvoyait CANVAS.liquide).

     Sans consequence pour la statue : le suivi du curseur — le dome, le
     ligament, le pivot du toucan — n'ecoute PAS sur le canvas mais sur
     window et document (voir les pointermove de verre-statue.js). Il continue
     de recevoir tous les mouvements. Ce que le canvas cesse de faire, c'est
     uniquement de VOLER les clics destines a ce qu'il y a dessous. */
  pointer-events: none;
}

/* le mur d'aurore, le cube, l'orbe : remplaces par le canvas */
.fond { display: none; }

/* le DEGRADE DE SECOURS : les memes tons que le fond peint par le shader (craie, bleu, abysse,
   peche). Il est la des le premier rendu — avant le JS, avant WebGPU — et reste sous le canvas :
   sans WebGPU, c'est lui la page. Coût nul. */
body {
  /* le meme dessin que fond() du shader : craie au foyer haut-gauche (25 %, 30 %) qui vire au bleu a
     0.9 hauteur d'ecran, un voile d'abysse au-dela, une tache peche au foyer bas-droit (75 %, 65 %),
     le tout desature de 18 % comme dans le shader — rayons en vh : le shader mesure en hauteurs d'ecran */
  background:
    radial-gradient(circle 80vh at 75% 65%, rgba(228, 191, 166, 0.85), rgba(228, 191, 166, 0) 100%),
    radial-gradient(circle 130vh at 25% 30%, rgba(45, 54, 74, 0) 38%, rgba(45, 54, 74, 0.6) 100%),
    radial-gradient(circle 90vh at 25% 30%, rgb(237, 240, 242), rgb(122, 139, 175) 100%);
  /* FIXE au viewport : sur body, le dessin se place sinon sur tout le document (plusieurs ecrans de
     haut) et l'on ne voit en haut que sa zone externe — un aplat (mesure) */
  background-attachment: fixed;
}

/* le panneau de texte : a DROITE, transparent, texte aligne a droite */
.shell { justify-content: flex-end; }
.sidebar {
  background-color: transparent;
  padding-right: var(--menu-inset);
  /* le bas du panneau = la ligne de la barre (comme la dalle de la maquette) */
  padding-bottom: calc(var(--barre-bas) + var(--barre-hauteur) + var(--f-34));
  justify-items: end;
  text-align: right;
}

/* le logotype de la page : il est repris en grand derriere l'objet par le shader
   (qui lit cet element) ; le petit ne s'affiche pas. « graphen » en blanc sur l'eau */
.logo { visibility: hidden; }
.logo-graphen { color: var(--encre-scene); text-shadow: var(--ombre-scene); }

/* LA LIGNE DE POSTURE. Elle quitte le panneau et se pose SOUS LE MOT
   « studio » du grand logotype peint derriere la statue.

   Ou est ce mot ? verre-statue.js dessine le logotype centre a l'ecran, au
   corps 120 (TAILLE_LOGO), ligne de base au milieu : « graphen » occupe la
   moitie gauche, « studio » commence donc a peu pres sur l'axe. D'ou
   left: 50%, et 89px sous le centre — la moitie du corps plus une
   respiration. Ces valeurs sont posees A L OEIL et pas mesurees : le texte
   est peint dans le canvas, on ne peut pas l'interroger depuis le DOM. */
.sidebar .hero-titre {
  position: fixed;
  left: calc(50% + var(--f-34));
  top: calc(50% + var(--f-89));
  z-index: 5;
  grid-row: auto;
  align-self: auto;
  justify-self: auto;
  text-align: left;
  max-width: 21em;
  /* 26 : entre deux termes de la suite (21 et 34). Assume — 34 faisait un
     titre, 21 une legende, et cette ligne n'est ni l'un ni l'autre. */
  font-size: 26px;
  line-height: var(--f-34);
  font-weight: var(--fw-light);
  color: var(--encre-scene);
  text-shadow: var(--ombre-scene);
}

/* plus de paragraphe dans le hero */
.hero-texte { display: none; }

/* « Scroll » juste sous le h1 (rangee 4), a droite */
/* « Scroll » quitte le panneau : coin BAS DROIT de l'ecran. Meme retrait que
   le bandeau du H1 en bas a gauche — les deux tiennent la meme ligne basse,
   le titre a gauche, l'invite a droite, la chatbar entre les deux. */
.hero-scroll {
  position: fixed;
  right: var(--menu-inset);
  bottom: var(--menu-inset);
  z-index: 5;
  grid-row: auto;
  align-self: auto;
  justify-self: auto;
  margin: 0;
  color: var(--encre-scene-attenuee);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

/* l'heure locale du visiteur : coin haut gauche, a la taille et a la ligne des
   etiquettes de l'en-tete */
.horloge {
  position: fixed;
  top: calc(var(--f-13) + var(--f-2));
  left: var(--menu-inset);
  z-index: 6;
  margin: 0;
  font-family: var(--font-main);
  font-size: var(--text-sm);
  line-height: var(--l-18);
  font-weight: var(--fw-light);
  letter-spacing: var(--ls-normal);
  color: var(--encre-scene-attenuee);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}


/* ---- LA SEQUENCE D'ENTREE ----
   Le toucan ne fond pas a l'ecran : un blob d'eau se materialise, s'etend en toucan, puis le
   logotype parait mot a mot (tout cela dans le canvas, verre-statue.js). La DESCRIPTION du
   panneau (« Design digital / et experiences / immersives. », puis « Scroll ») vient APRES :
   ses animations sont tenues en pause par html.attente-statue (posee dans le HTML, retiree
   par verre-statue.js a 3.4 s de sequence — ou tout de suite sans WebGPU, ou au plus tard a
   8 s), et leurs delais de styles.css (4181 ms...) sont remis a zero : des que la classe tombe,
   la phrase entre d'un bloc (un seul span — Quentin n'a pas voulu de mot a mot), puis « Scroll ». */
.sidebar .hero-titre { animation-delay: 0ms; }
.sidebar .hero-titre .mot-titre:nth-child(1) { animation-delay: 0ms; }
.sidebar .hero-titre .mot-titre:nth-child(2) { animation-delay: 233ms; }
.sidebar .hero-titre .mot-titre:nth-child(3) { animation-delay: 466ms; }
.sidebar .hero-titre .mot-titre:nth-child(4) { animation-delay: 699ms; }
.sidebar .hero-titre .mot-titre:nth-child(5) { animation-delay: 932ms; }
.hero-scroll { animation-delay: 900ms; }
/* La barre de l'assistant parait AVEC « Scroll » : le meme fondu, le meme
   creneau — la scene est posee, les commandes arrivent. */
.barre {
  animation: paraitre 2100ms cubic-bezier(0.22, 1, 0.36, 1) 900ms both;
}
html.attente-statue .sidebar .hero-titre,
html.attente-statue .sidebar .hero-titre .mot-titre,
html.attente-statue .hero-scroll,
html.attente-statue .barre {
  animation-play-state: paused;
}

/* Les ETIQUETTES de l'en-tete paraissent TOUT DE SUITE, ensemble (leurs delais
   echelonnes de styles.css — 610, 1597, 2584, 3571 ms — sont remis a zero).

   Elles attendaient « graphen » (2.7 s de sequence, sous html.attente-logo).
   Demande de Quentin : au demarrage on ne montre QUE l'en-tete et le h1 du
   coin bas gauche, et rien d'autre. Ces deux-la sont le CADRE de la page —
   ou l'on est, ce qu'on peut faire. Le cadre est la des la premiere image ;
   c'est ce qui se joue DEDANS qui se donne dans l'ordre : le blob, le
   toucan, les deux mots, la phrase, « Scroll ».

   html.attente-logo ne retient donc plus rien ici. La classe reste posee et
   retiree par verre-statue.js — elle ne coute rien, et une entree qui la
   redemanderait un jour la retrouverait branchee. */
html .entete-nav .etiquette:nth-child(n),
html .entete-droite .etiquette { animation-delay: 0ms; }

/* ---- LA SORTIE AU DEFILEMENT ----
   Pilotee par --sortie (ecrite par verre-statue.js : scrollY / hauteur d'ecran, 0 en haut, 1 un ecran
   plus bas — brume.js et sa variable --defilement ne sont plus charges sur l'accueil), reversible en remontant.
   L'en-tete REMONTE et s'efface ; « Scroll » et le bloc h1 du bas montent et fondent ; la description
   glisse vers la GAUCHE et fond (le logotype, peint dans le canvas, glisse vers la droite et fond —
   verre-statue.js) ; le toucan se dematerialise en un gros blob qui sort par le haut (idem). */
.entete {
  transform: translateY(calc(-130% * clamp(0, var(--sortie, 0) / 0.35, 1)));
  opacity: clamp(0, calc(1 - (var(--sortie, 0) - 0.05) / 0.25), 1);
}
.hero-scroll {
  transform: translateY(calc(-40px * clamp(0, var(--sortie, 0) / 0.12, 1)));
  /* filter: opacity() et non opacity : l'animation d'entree « paraitre » (fill both) tient opacity a 1 pour toujours */
  filter: opacity(clamp(0, calc(1 - var(--sortie, 0) / 0.12), 1));
}
/* « Scroll » et le h1 du bas s'en vont TOUT DE SUITE (0 -> 12 %) : ce sont les premiers a partir */
.bandeau {
  transform: translateY(calc(-40px * clamp(0, var(--sortie, 0) / 0.12, 1)));
  opacity: clamp(0, calc(1 - var(--sortie, 0) / 0.12), 1);
}
/* LA SORTIE DE LA DESCRIPTION.
   Elle glisse MOINS LOIN — 47px au lieu de 110 — et avec de l'inertie.

   L'inertie ne demande pas de JavaScript : --sortie est reecrite a chaque
   image, et une transition longue posee sur `transform` agit exactement
   comme un filtre passe-bas. La ligne part donc en retard sur le doigt et
   continue de couler apres l'arret. 987ms et une courbe qui s'ecrase a la
   fin (0.22, 1, 0.36, 1) : elle decelere longtemps, ce qui EST la sensation
   de glissement.

   L'opacite, elle, n'a pas de transition : le fondu doit suivre le
   defilement au pixel, sinon le texte reste visible alors qu'on l'a deja
   quitte. On ralentit le mouvement, pas la disparition. */
.sidebar .hero-titre {
  transform: translateX(calc(-47px * clamp(0, (var(--sortie, 0) - 0.03) / 0.45, 1)));
  filter: opacity(clamp(0, calc(1 - (var(--sortie, 0) - 0.15) / 0.28), 1));
  transition: transform 987ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* L'HEURE s'en va avec le reste. Elle est `position: fixed` et vit hors du
   panneau : sans cette regle, elle restait seule en haut a gauche pendant
   que toute la scene s'effaçait. Meme fenetre de fondu que la description,
   et le meme glissement, en plus court — c'est une mention, pas un titre. */
.horloge {
  transform: translateX(calc(-21px * clamp(0, (var(--sortie, 0) - 0.03) / 0.45, 1)));
  filter: opacity(clamp(0, calc(1 - (var(--sortie, 0) - 0.15) / 0.28), 1));
  transition: transform 987ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---- PAS DE DEFILEMENT AVANT « SCROLL » ----
   Tant que le mot « Scroll » n'est pas apparu (fin de la sequence d'entree, ~6 s apres le champ pret),
   la page ne defile pas : html.attente-scroll (posee dans le HTML) bloque le defilement — molette,
   clavier, doigt (Lenis anime le vrai scroll, qui reste a 0). verre-statue.js la retire ; sans WebGPU
   ou si le champ tarde, les garde-fous la retirent avec les autres. */
html.attente-scroll { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .sidebar .hero-titre,
  .horloge { transition: none; }
}


/* ---- LE DEPART VERS CONTACT ----
   Pose par depart-contact.js quand on part vers la page contact : la barre
   et le fil de la chatbar fondent avec le reste — --sortie s'occupe deja de
   l'en-tete, du titre, de la description et du logotype. Les gestes sont
   coupes : on est en train de partir, plus rien ne se clique. */
html[data-depart] .barre,
html[data-depart] .fil {
  opacity: 0;
  transition: opacity 610ms cubic-bezier(0.33, 0, 0.67, 1);
  pointer-events: none;
}
