/* ============================================================
   LA PAGE CONTACT — la table

   Une table lumineuse d'architecte, tracee sur le ciel : des filets
   fins qui decoupent la page en zones nommees, des croix aux
   intersections, les coordonnees du studio posees aux angles comme
   des cotes sur un plan.

   Au repos, la scene centrale ne porte que l'invitation. Au premier
   message, l'invitation s'efface, la conversation prend le centre, et
   les ailes s'eteignent a demi.

   La page NE DEFILE PAS : la table occupe l'ecran, la conversation
   defile a l'interieur. C'est pourquoi cette page n'a ni brume, ni
   Lenis, ni section 2.
   ============================================================ */

/* Le corps de CETTE page seulement : la table est fixe, rien ne
   defile derriere elle. */
body[data-page="contact"] {
  --barre-vide-hauteur: clamp(136px, 17vh, 164px);
  --barre-vide-largeur: min(610px, calc(100vw - 2 * var(--f-34)));
  --barre-vide-centre: 62%;
  overflow: hidden;
}

/* ---- L'ETAT VIDE ------------------------------------------------
   Avant le premier message, la barre devient le point d'ancrage de la page :
   une grande surface d'ecriture au centre, accompagnee d'une invitation
   discrete. Le libelle est un texte, jamais une action supplementaire. */
.contact-intro {
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
.contact-intro-titre {
  position: absolute;
  left: 50%;
  top: calc(var(--barre-vide-centre) - (var(--barre-vide-hauteur) / 2) - var(--f-55));
  width: max-content;
  max-width: calc(100vw - 2 * var(--f-34));
  margin: 0;
  color: #fff;
  font-family: var(--font-main);
  font-size: clamp(21px, 2.5vw, 34px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.12;
  text-align: center;
  transform: translate(-50%, -50%);
}
.contact-intro-emphase { color: var(--encre, #0B1416); }
body[data-conversation] .contact-intro {
  opacity: 0;
  visibility: hidden;
}

@media (max-width: 610px) {
  .contact-intro-titre { font-size: var(--f-28); }
}

/* ==================================================================
   LA TABLE DE CONTACT

   LE PARTI PRIS. Une table lumineuse d'architecte, tracee sur le
   ciel : des filets fins qui decoupent la page en zones nommees,
   des croix aux intersections, les coordonnees du studio posees
   aux angles comme des cotes sur un plan.

   AU CENTRE, LA SCENE. Tant que personne n'a parle, elle ne porte
   que l'invitation — titre et sous-titre au milieu du vide, les
   trois portes d'entree en dessous.

   AU PREMIER MESSAGE, LA TABLE CHANGE DE METIER : l'invitation
   s'efface, la conversation prend le centre, et les zones des
   angles s'eteignent a demi — elles restent lisibles, mais la
   lumiere est sur l'echange.

   Tout est du systeme : echelle Fibonacci, pave noir pour les
   instruments, filets a l'encre diluee, coin 3.
   ================================================================== */


/* ---- LA TABLE ---------------------------------------------------
   Trois colonnes : deux ailes de 233, la scene au centre. Trois
   rangees : l'en-tete, la matiere, le cartouche du bas. Les filets
   ne sont pas des bordures de boites — ce sont des LIGNES DE LA
   TABLE, posees par des elements dedies, pour traverser la page
   entiere comme sur un calque. */
.table {
  position: fixed;
  inset: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: var(--f-233) minmax(0, 1fr) var(--f-233);
  grid-template-rows: var(--l-76) minmax(0, 1fr) var(--l-76);
  padding: 0 var(--menu-inset);
}

/* Les deux verticales et les deux horizontales de la table. A
   l'encre tres diluee : on lit une table, pas une cage. */
.table::before, .table::after,
.table-lignes::before, .table-lignes::after {
  content: "";
  position: absolute;
  background-color: color-mix(in oklab, var(--encre, #0B1416) 13%, transparent);
  pointer-events: none;
  opacity: 0;
}
.table::before  { top: 0; bottom: 0; left: calc(var(--menu-inset) + var(--f-233)); width: var(--border-hair); }
.table::after   { top: 0; bottom: 0; right: calc(var(--menu-inset) + var(--f-233)); width: var(--border-hair); }
.table-lignes::before { left: 0; right: 0; top: var(--l-76); height: var(--border-hair); }
.table-lignes::after  { left: 0; right: 0; bottom: var(--l-76); height: var(--border-hair); }

/* Les croix des intersections : le geste du calque d'architecte.
   Dessinees par un degrade en deux passes, aucune image. */
.croix {
  position: absolute;
  width: var(--l-11);
  height: var(--l-11);
  transform: translate(-50%, -50%);
  background:
    linear-gradient(color-mix(in oklab, var(--encre, #0B1416) 34%, transparent), color-mix(in oklab, var(--encre, #0B1416) 34%, transparent)) 50% 0 / var(--border-hair) 100% no-repeat,
    linear-gradient(color-mix(in oklab, var(--encre, #0B1416) 34%, transparent), color-mix(in oklab, var(--encre, #0B1416) 34%, transparent)) 0 50% / 100% var(--border-hair) no-repeat;
  pointer-events: none;
  opacity: 0;
}
.croix[data-a="hg"] { left: calc(var(--menu-inset) + var(--f-233)); top: var(--l-76); }
.croix[data-a="hd"] { right: calc(var(--menu-inset) + var(--f-233)); top: var(--l-76); transform: translate(50%, -50%); }
.croix[data-a="bg"] { left: calc(var(--menu-inset) + var(--f-233)); top: calc(100% - var(--l-76)); }
.croix[data-a="bd"] { right: calc(var(--menu-inset) + var(--f-233)); top: calc(100% - var(--l-76)); transform: translate(50%, -50%); }

/* ---- LES PLAQUES DES AILES --------------------------------------
   Les coordonnees, posees comme des cotes : un titre en capitales
   espacees, puis du texte leger. Chaque plaque vit dans une aile,
   calee contre la ligne de la table. */
.aile {
  grid-row: 2;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--f-34) var(--f-21) var(--f-34) 0;
  transition: opacity 610ms cubic-bezier(0.33, 0, 0.67, 1);
}
.aile-droite { grid-column: 3; padding: var(--f-34) 0 var(--f-34) var(--f-21); text-align: right; }
.aile-gauche { grid-column: 1; }

/* Pendant la conversation, les ailes s'eteignent a demi : encore
   la, plus en lumiere. */
body[data-conversation] .aile { opacity: 0.45; }

.plaque-titre {
  margin: 0 0 var(--f-8);
  font-size: var(--text-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: color-mix(in oklab, var(--encre, #0B1416) 45%, transparent);
}
.plaque-corps, .plaque-corps a {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--lh-sm);
  font-weight: var(--fw-light);
  color: var(--encre, #0B1416);
  text-decoration: none;
}
.plaque-corps a:hover { text-decoration: underline; text-underline-offset: 3px; }
.plaque-corps + .plaque-titre { margin-top: var(--l-29); }

/* ---- LA SCENE ---------------------------------------------------
   La colonne centrale. Une pile : le totem (l'objet), le fil, les
   suggestions, la barre. Avant la conversation le fil est vide et
   l'objet occupe tout ; apres, les hauteurs changent et TOUT EST
   ANIME par la meme courbe — la table se recompose, elle ne saute
   pas. */
.scene {
  grid-column: 2;
  grid-row: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* AU REPOS, LE TITRE EST AU MILIEU : rien d'autre n'occupe la scene,
     il ne doit pas flotter en haut d'une colonne vide. En conversation
     la pile repart du haut, et c'est le fil qui prend la place. */
  justify-content: center;
  min-height: 0;
  /* LA BARRE TRAVERSE LA LIGNE BASSE DE LA TABLE : elle est fixee a la
     fenetre (comme partout sur le site) et vit donc SOUS le filet. La
     scene n'a pas a lui reserver sa hauteur — seulement un souffle : les
     suggestions se posent juste au-dessus du filet, a 21 de la barre. */
  padding: 0 var(--f-34) var(--f-13);
}
body[data-conversation] .scene { justify-content: flex-start; }

/* La legende de la piece, sous l'objet, comme au musee. Elle
   s'efface quand la conversation commence : le titre a fait son
   travail. */
.legende {
  flex: 0 0 auto;
  margin: 0;
  text-align: center;
  transition: opacity 610ms cubic-bezier(0.33, 0, 0.67, 1), margin 987ms cubic-bezier(0.33, 0, 0.67, 1);
}
/* L'invitation n'est plus affichée au repos : la sculpture est le seul
   élément visuel de la scène avant l'ouverture du chat. */
body[data-page="contact"] .legende { display: none; }
.legende h1 {
  margin: 0;
  padding: 0;
  /* Le h1 global reserve la hauteur du titre de page (min-height x
     --titre-lignes) : ici le titre vit dans la scene, pas dans la
     sidebar — la reserve est annulee. */
  min-height: 0;
  font-size: var(--l-29);
  line-height: var(--f-34);
  font-weight: var(--fw-extralight, 200);
  color: var(--encre, #0B1416);
}
.legende p {
  margin: var(--f-5) 0 0;
  font-size: var(--text-sm);
  line-height: var(--lh-sm);
  font-weight: var(--fw-light);
  color: color-mix(in oklab, var(--encre, #0B1416) 62%, transparent);
}
body[data-conversation] .legende { opacity: 0; margin: 0; height: 0; overflow: hidden; }

/* ---- LE FIL -----------------------------------------------------
   La conversation du Manager, transposee : l'assistant ecrit sur
   la table, le visiteur a un pave discret a droite. Fondu par
   masque aux deux bords. */
.echange {
  --fondu-haut: 0px;
  --fondu-bas: 0px;
  /* au repos il ne pese rien (il est vide) : sans cela il pousserait le
     titre hors du milieu */
  flex: 0 0 auto;
  min-height: 0;
  width: 100%;
  /* LA LARGEUR DE LA COLONNE, pas celle d'un paragraphe. Le fil s'etend
     d'un filet a l'autre ; c'est chaque MESSAGE qui garde sa mesure de
     lecture (.msg), pas le fil. Les paves du visiteur vont donc vraiment
     a droite, et l'echange occupe la table au lieu de flotter au milieu. */
  max-width: none;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--f-13);
  margin-top: var(--f-21);
  overflow-y: auto;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0, #000 var(--fondu-haut),
    #000 calc(100% - var(--fondu-bas)), transparent 100%);
  mask-image: linear-gradient(to bottom,
    transparent 0, #000 var(--fondu-haut),
    #000 calc(100% - var(--fondu-bas)), transparent 100%);
  transition: --fondu-haut 233ms linear, --fondu-bas 233ms linear;
}
.echange::-webkit-scrollbar { display: none; }
/* EN CONVERSATION le fil prend la hauteur libre, mais il ne colle pas au
   plafond : la lecture commence a un cinquieme de l'ecran, plus pres de la
   barre ou la main ecrit. Quand le fil se remplit, il defile — le retrait
   ne coute rien aux longues conversations. */
body[data-conversation] .echange {
  flex: 1 1 auto;
  justify-content: flex-start;
  padding-top: clamp(var(--f-34), 9vh, var(--f-89));
}
@property --fondu-haut { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --fondu-bas  { syntax: "<length>"; inherits: false; initial-value: 0px; }

.msg {
  /* Le fil est une colonne scrollable : un item flex ne doit jamais se
     comprimer quand la conversation dépasse la hauteur disponible, sinon
     le texte sort visuellement de sa pill. */
  flex: 0 0 auto;
  margin: 0;
  /* la mesure de lecture : une ligne de texte ne depasse pas ~70 signes,
     meme quand la colonne est large */
  max-width: min(72%, var(--l-521));
  /* CORPS DE LECTURE, pas corps de legende : c'est le contenu principal de
     la page. 15 px, interligne genereux. */
  font-size: var(--text-sm);
  line-height: var(--l-18);
  font-weight: var(--fw-light);
  letter-spacing: var(--ls-normal);
  white-space: pre-wrap;
  animation: msg-parait 377ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes msg-parait {
  from { opacity: 0; transform: translateY(var(--f-8)); }
  to { opacity: 1; transform: translateY(0); }
}
/* L'ASSISTANT ECRIT SUR UNE SURFACE. Le fond de la page est un ciel anime :
   du texte pose a nu y perd son contraste a chaque mouvement. Un voile
   blanc translucide — pas du verre flou (backdrop-filter, piege connu du
   site), juste une eau de lait — porte les lettres partout. */
.msg[data-de="assistant"] {
  align-self: flex-start;
  /* Même gabarit vertical et mêmes retraits que le pavé noir de la chatbar.
     La hauteur reste extensible pour les réponses sur plusieurs lignes. */
  padding: calc((var(--barre-hauteur, 34px) - var(--l-18)) / 2) var(--f-21)
    calc((var(--barre-hauteur, 34px) - var(--l-18)) / 2) var(--f-13);
  min-height: var(--barre-hauteur, 34px);
  box-sizing: border-box;
  background-color: color-mix(in oklab, #FFFFFF 55%, transparent);
  border-radius: var(--radius-xs);
  color: var(--encre, #0B1416);
}
.msg[data-de="assistant"] a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.msg[data-de="visiteur"] {
  align-self: flex-end;
  padding: calc((var(--barre-hauteur, 34px) - var(--l-18)) / 2) var(--f-21)
    calc((var(--barre-hauteur, 34px) - var(--l-18)) / 2) var(--f-13);
  min-height: var(--barre-hauteur, 34px);
  box-sizing: border-box;
  background-color: var(--etiquette-fond, #000000);
  color: var(--etiquette-encre, #FFFFFF);
  border-radius: var(--radius-xs);
}

/* Le travail qui se voit : les consultations, petites et pales. */
.acte {
  align-self: flex-start;
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--f-8);
  font-size: var(--text-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--ls-wide);
  color: color-mix(in oklab, var(--encre, #0B1416) 52%, transparent);
  animation: acte-parait 233ms cubic-bezier(0.33, 0, 0.67, 1) both;
}
.acte + .acte { margin-top: calc(var(--f-5) - var(--f-13)); }
.acte::before {
  content: "";
  flex: none;
  width: var(--f-3);
  height: var(--f-3);
  border-radius: 50%;
  background-color: currentColor;
}
@keyframes acte-parait {
  from { opacity: 0; transform: translateY(var(--f-3)); }
  to { opacity: 1; transform: none; }
}

.attente {
  align-self: flex-start;
  display: flex;
  gap: var(--f-5);
  align-items: center;
  height: var(--lh-sm);
}
.attente b {
  width: var(--f-5);
  height: var(--f-5);
  border-radius: 50%;
  background-color: var(--encre, #0B1416);
  opacity: 0.28;
  animation: attente-respire 1220ms ease-in-out infinite;
}
.attente b:nth-child(2) { animation-delay: 203ms; }
.attente b:nth-child(3) { animation-delay: 406ms; }
@keyframes attente-respire { 50% { opacity: 1; } }

/* ---- LA BARRE --------------------------------------------------- */

/* La barre : celle du site, aux memes mesures — 34 au repos, cales
   en bas, coin 3 — mais EN PLACE dans la scene, pas fixee a la
   fenetre : elle appartient a la table. */
.scene-barre {
  position: fixed;
  left: 50%;
  top: var(--barre-vide-centre);
  bottom: auto;
  transform: translate(-50%, -50%);
  z-index: 3;
  box-sizing: border-box;
  display: grid;
  grid-template-areas: "champ" "pied";
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  align-items: stretch;
  gap: var(--f-8);
  width: var(--barre-vide-largeur);
  max-width: calc(100vw - 2 * var(--menu-inset));
  min-height: var(--barre-vide-hauteur);
  padding: var(--f-13);
  background-color: var(--etiquette-fond, #0B1416);
  color: var(--etiquette-encre, #fff);
  border-radius: var(--radius-xs);
  cursor: text;
  /* L'etat vide est visible directement a sa taille de travail : aucune
     animation de deploiement au chargement de la page. */
  animation: none;
  transition: none;
}
body[data-conversation] .scene-barre {
  top: auto;
  bottom: var(--barre-bas);
  display: flex;
  align-items: flex-end;
  gap: var(--f-8);
  width: var(--barre-largeur);
  min-height: var(--barre-hauteur, 34px);
  padding: 0 var(--f-5) 0 var(--f-13);
  border-radius: var(--radius-xs);
  transform: translateX(-50%);
}
body[data-conversation] .scene-barre textarea {
  flex: 1;
  width: auto;
}
body[data-conversation] .scene-barre-pied { flex: none; }
/* En sortie, la barre redevient simplement son petit pave. Le nom de
   transition native est retire apres cette reduction pour eviter toute
   interpolation de geometrie avec la barre de la page suivante. */
html[data-contact-barre-leaving] body[data-page="contact"] .scene-barre {
  width: var(--barre-fermee);
  animation: none;
  view-transition-name: none;
}
html[data-passage="part"][data-contact-barre-leaving] body[data-page="contact"] .table {
  opacity: 1;
  filter: none;
  transform: none;
}
/* Le champ et l'envoi paraissent pendant la seconde moitie de l'etirement,
   comme le champ de la barre du site. */
.scene-barre textarea,
.scene-barre button { opacity: 1; }
@keyframes barre-deploiement { from { width: var(--barre-fermee); } }
@keyframes barre-contenu-parait { from { opacity: 0; } }
.scene-barre textarea {
  grid-area: champ;
  width: 100%;
  height: 100%;
  align-self: stretch;
}
.scene-barre-pied {
  grid-area: pied;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--f-8);
}
.scene-barre-outils {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--f-8);
}
body:not([data-conversation]) .scene-barre-pied,
body:not([data-conversation]) .scene-barre-outils {
  align-items: flex-end;
}
.scene-barre input[type="file"] { display: none; }
.scene-barre-url {
  box-sizing: border-box;
  flex: 0 1 190px;
  min-width: 0;
  width: min(190px, 30vw);
  height: var(--f-21);
  padding: var(--f-2) var(--f-21) var(--f-2) var(--f-5);
  color: var(--etiquette-encre, #fff);
  background-color: var(--etiquette-fond, #0B1416);
  border: var(--border-hair) solid transparent;
  border-radius: var(--radius-xs);
  font: inherit;
  font-size: var(--text-caption);
  line-height: var(--lh-caption);
  display: flex;
  align-items: center;
  overflow: hidden;
}
.scene-barre-url-prefix,
.scene-barre-url input::placeholder {
  color: color-mix(in oklab, var(--etiquette-encre, #fff) 34%, transparent);
}
.scene-barre-url-prefix {
  flex: none;
  white-space: nowrap;
}
.scene-barre-url input {
  box-sizing: border-box;
  min-width: 0;
  width: 100%;
  padding: 0;
  color: inherit;
  background: none;
  border: 0;
  box-shadow: none;
  outline: none;
  font: inherit;
  font-size: inherit;
  line-height: inherit;
}
.scene-barre-url:hover,
.scene-barre-url:focus-within {
  border-color: color-mix(in oklab, var(--etiquette-encre, #fff) 42%, transparent);
}
.scene-barre-ajouter,
.scene-barre-envoyer {
  flex: none;
  width: var(--f-34);
  height: var(--f-34);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
  color: var(--etiquette-encre, #fff);
  background: color-mix(in oklab, var(--etiquette-encre, #fff) 10%, transparent);
  border: 0;
  border-radius: var(--radius-sm);
  transition: opacity 233ms, background-color 233ms;
}
.scene-barre-ajouter:hover,
.scene-barre-ajouter:focus-visible {
  background: transparent;
  opacity: 0.68;
  outline: none;
}
.scene-barre-ajouter {
  width: var(--f-21);
  height: var(--f-21);
  background: transparent;
  border-radius: 0;
}
.scene-barre-fichiers-noms {
  min-width: 0;
  overflow: hidden;
  color: color-mix(in oklab, currentColor 62%, transparent);
  font-size: var(--text-caption);
  line-height: var(--lh-caption);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.scene-barre textarea {
  box-sizing: border-box;
  min-width: 0;
  padding: 0;
  max-height: calc(var(--f-21) * 5 + var(--f-13));
  overflow-y: auto;
  resize: none;
  font-family: inherit;
  font-size: var(--text-sm);
  line-height: var(--f-21);
  font-weight: var(--fw-light);
  color: inherit;
  background: none;
  border: 0;
  scrollbar-width: none;
}
.scene-barre textarea::-webkit-scrollbar { display: none; }
.scene-barre textarea:focus { outline: none; }
.scene-barre textarea::placeholder { color: color-mix(in oklab, currentColor 50%, transparent); }
body[data-conversation] .scene-barre textarea {
  height: auto;
  padding: calc((var(--barre-hauteur, 34px) - var(--f-21)) / 2) 0;
}
.scene-barre-envoyer {
  flex: none;
  align-self: flex-end;
  margin-bottom: calc((var(--barre-hauteur, 34px) - var(--f-21)) / 2);
  width: var(--f-21);
  height: var(--f-21);
  color: var(--etiquette-fond, #0B1416);
  background-color: var(--etiquette-encre, #fff);
  border-radius: var(--radius-xs);
}
.scene-barre-envoyer:hover, .scene-barre-envoyer:focus-visible { opacity: 0.72; outline: none; }
.scene-barre-envoyer svg {
  width: 18px;
  height: 18px;
}
body:not([data-conversation]) .scene-barre-envoyer {
  width: 32px;
  height: 32px;
  margin-bottom: 0;
  border-radius: var(--radius-sm);
}

/* ---- LE CARTOUCHE DU BAS ----------------------------------------
   La rangee sous la ligne basse : le logotype a gauche, la mention
   a droite — la signature du plan. */
.cartouche {
  grid-column: 1 / -1;
  grid-row: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.cartouche .logo { margin: 0; }

/* LE LOGOTYPE DU CARTOUCHE, REPRIS A HERO-EAU.CSS.

   Cette page charge hero-eau.css pour l'eau (le canvas, les tons de la
   scene). Cette feuille-la est ecrite pour l'accueil, ou le petit logotype
   est CACHE parce que le shader le repeint en grand derriere le toucan.
   Ici le canvas porte data-sans-logo — rien n'est repeint — donc le
   cartouche garde le sien, avec les couleurs d'encre de la page (le blanc
   de la scene serait invisible sur le ciel clair). */
.cartouche .logo { visibility: visible; }
.cartouche .logo-graphen { color: var(--logo-encre); text-shadow: none; }

/* LE LOGOTYPE DE L'EN-TETE, en haut a gauche, comme sur /graphen/. Meme
   raison que le cartouche : hero-eau.css cache .logo parce qu'a l'accueil
   le shader le repeint en grand ; ici rien ne le repeint, donc on le rend
   — avec l'encre de la page, le blanc de la scene serait invisible sur le
   ciel clair. */
.entete-logo.logo { visibility: visible; }
.entete-logo .logo-graphen { color: var(--logo-encre); text-shadow: none; }

/* le cartouche ne porte plus que sa mention : elle reste a droite. */
.cartouche { justify-content: flex-end; }
.cartouche-note {
  margin: 0;
  font-size: var(--text-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--ls-wide);
  color: color-mix(in oklab, var(--encre, #0B1416) 40%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .legende, .aile { transition: none; }
  .acte { animation: none; }
  .msg { animation: none; }
  /* la barre parait d'un bloc, a sa largeur de travail */
  .scene-barre, .scene-barre textarea, .scene-barre button { animation: none; }
  .scene-barre { transition: none; }
}

@media (max-width: 610px) {
  .scene-barre {
    --barre-vide-hauteur: clamp(138px, 22vh, 168px);
    --barre-vide-largeur: calc(100vw - 2 * var(--f-34));
  }
  body[data-page="contact"] {
    --barre-vide-hauteur: clamp(138px, 22vh, 168px);
    --barre-vide-largeur: calc(100vw - 2 * var(--f-34));
  }
  .scene-barre-fichiers-noms { max-width: 46vw; }
}

/* Les cercles de repli et de positionnement des blobs d'eau (comme la page Graphen) */
.banniere-cercle {
  --bulle-d: min(38.2vh, 21vw);
  position: absolute;
  width: var(--bulle-d);
  height: var(--bulle-d);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.21);
  transform: translate(-50%, -50%);
  z-index: 0;
}
.bc-1 { left: 38.2%; top: 48%; }
.bc-2 { left: 61.8%; top: 48%; }
html.eau-attente .banniere-cercle,
.table.eau-active .banniere-cercle { visibility: hidden; }

/* Transition en douceur de l'affichage de l'eau une fois WebGPU prêt */
.liquide { opacity: 0; transition: opacity 610ms cubic-bezier(0.22, 1, 0.36, 1); }
body:has(.table.eau-active) .liquide { opacity: 1; }
