/* =========================================================
   DESIGNER BY NATURE — 08. DE L'IDÉE À L'ESPACE
   Section haute, contenu épinglé, timeline pilotée au scrub.
   Sept passes de dessin, cinq jalons de lecture.

   La hauteur de la section n'est PAS la hauteur de ce qu'on voit :
   on voit un écran, on parcourt six. C'est ce rapport qui donne à la
   construction le temps de se faire.
   ========================================================= */

.experience {
  position: relative;

  /* Cinq écrans de course. Le dépliage en volume tombe au milieu — vers
     le troisième écran. Plus haut, on attendait trois écrans et demi
     avant qu'il ne se passe quoi que ce soit de spectaculaire. */
  height: 500svh;

  background-color: var(--brun);
  color: var(--blanc-casse);
}

/* Texture chaude très légère, pour que le brun ne soit pas un aplat mort. */
/* Les trois blocs — jalons, scène, en-tête — sont des cellules d'une
   même grille, jamais des éléments positionnés en absolu les uns
   par-dessus les autres. Posés en absolu, le titre recouvrait la partie
   droite du plan dès 1440 px ; en grille, le chevauchement est
   impossible par construction, à n'importe quelle largeur. */
.experience__pin {
  position: relative;
  height: 100svh;
  overflow: hidden;
  display: grid;
  place-items: center;
  background-image:
    radial-gradient(64rem 44rem at 76% 16%, rgba(182, 154, 104, .12), transparent 62%),
    radial-gradient(52rem 38rem at 10% 90%, rgba(17, 17, 15, .46), transparent 60%);
}

/* ---------- JALONS ---------- */
/* Progression à gauche. Chaque jalon s'allume quand la timeline entre
   dans son segment ; l'attribut est posé par construction.js. */

.jalons {
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-4) var(--sp-5);
}

/* Le rail vertical n'a de sens qu'en colonne : sous 1024 px les jalons
   passent en ligne et il est masqué, l'état actif suffisant à situer la
   progression. */
.jalons__rail,
.jalons__progres {
  display: none;
  position: absolute;
  left: 0;
  top: .35rem;
  bottom: .35rem;
  width: var(--trait);
}

.jalons__rail { background-color: rgba(250, 248, 243, .18); }

.jalons__progres {
  background-color: var(--or-clair);
  transform: scaleY(0);
  transform-origin: top;
}

.jalon {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  color: rgba(250, 248, 243, .42);
  transition: color var(--dur-moyen) var(--ease-net);
}

/* Pastille sur le rail, en regard du jalon. Comme le rail, elle n'a de
   sens qu'en colonne. */
.jalon::before {
  content: "";
  display: none;
  position: absolute;
  left: calc(var(--sp-5) * -1);
  top: .5em;
  width: 5px;
  height: 5px;
  margin-left: -2px;
  border-radius: var(--rayon-rond);
  background-color: rgba(250, 248, 243, .3);
  transition:
    background-color var(--dur-moyen) var(--ease-net),
    transform var(--dur-moyen) var(--ease-sortie);
}

.jalon[data-actif="true"] { color: var(--blanc-casse); }

.jalon[data-actif="true"]::before {
  background-color: var(--or-clair);
  transform: scale(1.8);
}

.jalon[data-passe="true"] { color: rgba(250, 248, 243, .68); }
.jalon[data-passe="true"]::before { background-color: var(--or-clair); }

.jalon__num {
  font-family: var(--sans);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-micro);
  color: var(--or-clair);
}

.jalon__nom {
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  white-space: nowrap;
}

/* ---------- EN-TÊTE ---------- */

.experience__entete {
  position: relative;
  z-index: 3;
  text-align: center;
}

.experience__entete .filet { margin-inline: auto; }

/* La typographie vient de `.label`, comme dans Projets. Ne restent ici
   que la mise en page et la couleur : le beige tient mieux que le gris
   sourd sur la surface brune de cette section.

   La hauteur minimale évite que la scène ne saute d'une phase à l'autre
   quand la légende change de longueur. Quatre lignes et demie à ce corps
   couvrent la plus longue des cinq. */
.experience__legende {
  max-width: 30ch;
  margin-inline: auto;
  color: var(--beige);
  min-height: 4.2em;
}

/* ---------- SCÈNE ---------- */

.experience__scene {
  position: relative;
  width: min(92vw, 62rem);

  /* Le rapport du viewBox. Le figer ici évite que la scène change de
     hauteur quand la photographie remplace le dessin — un changement de
     hauteur en cours d'épinglage ferait sauter toute la timeline. */
  aspect-ratio: 800 / 560;
  display: grid;
  place-items: center;
}

/* La perspective vit sur le parent : appliquée à la pièce elle-même,
   elle serait recalculée à chaque image de la bascule. */
.experience__scene { perspective: 1700px; }

/* ---------- LA PIÈCE ---------- */
/* Repère commun au plan et aux murs : 800 × 560 unités, identiques au
   viewBox du SVG. Le cadrage met ce repère à l'échelle de l'écran, la
   pièce ne fait que tourner. Un seul élément pour les deux rôles et la
   mise à l'échelle serait écrasée à chaque image de la rotation. */

/* Le repère fait 800 × 560 px de large quelle que soit la taille de la
   scène : seule la mise à l'échelle le réduit. Il doit donc être retiré
   du flux et centré sur ses propres marges négatives. Laissé dans le
   flux, il occupait 800 px de largeur réelle dans une cellule bien plus
   étroite : la pièce se retrouvait décalée vers la droite, et sur un
   écran de 375 px la moitié sortait du cadre. */
.piece__cadrage {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  width: 800px;
  height: 560px;
  margin: -280px 0 0 -400px;
  transform: scale(var(--echelle, 1));
  transform-origin: center center;
  transform-style: preserve-3d;
}

.piece {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
}

/* ---------- SOL ---------- */

.piece__sol {
  position: absolute;
  inset: 0;
  color: var(--or-clair);
  transform-style: preserve-3d;
}

.piece__sol svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* ---------- MURS ---------- */
/* Chaque mur est un plan posé à plat sur son arête au sol, puis relevé
   de 90° autour d'elle. À plat il se confond avec le plan : la bascule
   ne fait pas apparaître de matière, elle en révèle l'épaisseur.

   Les deux orientations n'utilisent pas la même rotation. Un mur porté
   par une arête horizontale se relève autour de X depuis son bord haut ;
   un mur porté par une arête verticale se relève autour de Y depuis son
   bord gauche. Dans les deux cas la rotation vaut +90° dans le repère
   local, ce qui envoie le mur vers le haut de la pièce. */

.piece__mur {
  position: absolute;
  left: calc(var(--x) * 1px);
  top: calc(var(--y) * 1px);
  backface-visibility: visible;
  opacity: 0;

  /* Face intérieure : un dégradé qui s'éclaircit vers le sol, comme une
     paroi prenant la lumière rasante. Le filet doré marque l'arête
     haute — l'acrotère du dessin d'architecte. */
  background-image:
    linear-gradient(to top,
      rgba(201, 177, 137, .16) 0%,
      rgba(201, 177, 137, .05) 55%,
      rgba(201, 177, 137, .02) 100%);
  border-top: var(--trait) solid rgba(201, 177, 137, .5);
}

.piece__mur[data-axe="h"] {
  width: calc(var(--l) * 1px);
  height: calc(var(--h) * 1px);
  transform-origin: top center;
}

.piece__mur[data-axe="v"] {
  width: calc(var(--h) * 1px);
  height: calc(var(--l) * 1px);
  transform-origin: left center;

  /* Sur un mur porté par une arête verticale, c'est le bord gauche qui
     touche le sol : le dégradé et le filet doivent tourner avec lui. */
  background-image:
    linear-gradient(to left,
      rgba(201, 177, 137, .16) 0%,
      rgba(201, 177, 137, .05) 55%,
      rgba(201, 177, 137, .02) 100%);
  border-top: 0;
  border-right: var(--trait) solid rgba(201, 177, 137, .5);
}

.piece__mur--refend {
  background-image:
    linear-gradient(to top,
      rgba(201, 177, 137, .09) 0%,
      rgba(201, 177, 137, .02) 100%);
  border-top-color: rgba(201, 177, 137, .32);
}

.piece__mur--refend[data-axe="v"] {
  background-image:
    linear-gradient(to left,
      rgba(201, 177, 137, .09) 0%,
      rgba(201, 177, 137, .02) 100%);
  border-right-color: rgba(201, 177, 137, .32);
}

/* Compatibilité : les anciennes règles ciblaient .experience__plan. */
.experience__plan {
  color: var(--or-clair);
}

/* Tous les tracés partagent le même traitement ; seules l'épaisseur et
   l'opacité distinguent les couches. Le JavaScript ne fait que dérouler
   stroke-dashoffset — aucune règle d'ici n'est à réécrire. */
/* UN MUR EST UN TRAIT ÉPAIS, PAS UNE LIGNE
   C'est l'épaisseur du trait qui fait le mur : il suit l'axe de la
   maçonnerie et sa largeur EST la largeur du mur. Le dessin précédent
   traçait deux parements fins ; il se lisait comme un croquis, jamais
   comme un plan.

   Le bout est droit — stroke-linecap: butt — pour que chaque segment
   s'arrête net à l'ouverture qu'il laisse. Un bout arrondi déborderait
   dans le vide de la porte et refermerait le passage.

   Pas de vector-effect : non-scaling-stroke recalculerait la géométrie
   de chaque trait à chaque image de la bascule 3D. Ici les épaisseurs
   sont exprimées dans le repère du dessin et suivent donc l'échelle —
   c'est justement ce qu'on attend d'un mur. */
.piece__sol [data-trait] {
  fill: none;
  stroke: currentColor;
  stroke-linecap: butt;
  stroke-linejoin: miter;
}

.piece__sol [data-trait="trame"] {
  stroke-width: 1;
  stroke-dasharray: 14 9;
  opacity: .3;
}

/* Enveloppe : 13 unités, soit environ 24 cm à l'échelle du plan. */
.piece__sol [data-trait="mur"] { stroke-width: 13; }

/* Refends : plus minces que l'enveloppe, comme sur un vrai relevé. */
.piece__sol [data-trait="cloison"] { stroke-width: 9; opacity: .92; }

/* Le vitrage traverse le vide laissé dans le mur. */
.piece__sol [data-trait="fenetre"] { stroke-width: 3; opacity: .9; }

.piece__sol [data-trait="porte"] { stroke-width: 1.6; opacity: .85; }
.piece__sol [data-trait="escalier"] { stroke-width: 1.4; opacity: .8; }
.piece__sol [data-trait="mobilier"] { stroke-width: 1.4; opacity: .72; }
.piece__sol [data-trait="luminaire"] { stroke-width: 1.2; opacity: .7; }
.piece__sol [data-trait="plante"] { stroke-width: 1.2; opacity: .7; }
.piece__sol [data-trait="cote"] { stroke-width: 1; opacity: .5; }

/* ---------- NOMS DE PIÈCES ---------- */
/* Ce qui fait qu'un plan se lit comme un logement et non comme un
   assemblage de rectangles. Révélés avec la phase « plan ». */

.piece__sol [data-couche="pieces"] text,
.piece__sol [data-couche="cotes"] text {
  fill: currentColor;
  stroke: none;
  text-anchor: middle;
  opacity: 0;
}

.piece__sol .piece-nom {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 400;
  letter-spacing: .1em;
}

.piece__sol .piece-aire,
.piece__sol .cote-texte {
  font-family: var(--sans);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
}

.piece__sol [data-couche="matieres"] { opacity: 0; }
.piece__sol [data-remplissage] { stroke: none; }

.piece__sol [data-couche="matieres"] text {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  fill: currentColor;
  stroke: none;
  opacity: .8;
  text-anchor: middle;
}

.piece__sol [data-couche="lumiere"] { opacity: 0; }
.piece__sol [data-couche="lumiere"] [data-ombre] {
  fill: rgba(17, 17, 15, .38);
  stroke: none;
}

/* ---------- PHOTOGRAPHIE FINALE ---------- */

.experience__photo {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  border-radius: 2px;
  opacity: 0;
}

.experience__photo-img {
  width: 100%;
  height: 100%;
  background-color: #1C1611;
  /* Placeholder : remplacer par une photographie du projet livré.
     Mêmes masses lumineuses que le hero, pour que la substitution
     plan → espace réel se juge dès maintenant. */
  background-image:
    radial-gradient(30rem 20rem at 68% 58%, rgba(216, 158, 82, .44), transparent 62%),
    radial-gradient(26rem 26rem at 40% 30%, rgba(200, 182, 152, .28), transparent 66%),
    radial-gradient(34rem 30rem at 16% 84%, rgba(52, 40, 30, .88), transparent 68%),
    linear-gradient(162deg, #271E17 0%, #4A3928 44%, #17110D 100%);
  background-size: cover;
  background-position: center;
}

/* ---------- INDICATION DE DÉFILEMENT ---------- */

.experience__indice {
  position: absolute;
  left: 50%;
  bottom: var(--sp-6);
  transform: translateX(-50%);
  z-index: 3;
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--beige);
  white-space: nowrap;
}

/* ---------- RESPONSIVE ---------- */

@media (min-width: 64rem) {

  /* Trois colonnes : jalons, scène, en-tête. Chacun sa cellule, donc
     aucun recouvrement possible. */
  .experience__pin {
    grid-template-columns:
      minmax(8rem, auto)
      minmax(0, 1fr)
      minmax(24rem, 26rem);
    grid-template-rows: minmax(0, 1fr);
    align-items: center;
    align-content: center;
    gap: clamp(1.5rem, 3vw, 4rem);
    padding: calc(var(--h-nav) + var(--sp-6)) var(--marge) var(--sp-8);
  }

  /* LA COLONNE S'ÉLARGIT, LE TITRE NE RÉTRÉCIT PAS
     Ce titre vit dans la troisième colonne, pas sur toute la page. Il a
     d'abord été descendu d'un cran pour y tenir ; maintenant que tous
     les titres de section partagent le même corps — trente-huit pixels —
     c'est la colonne qui s'élargit. « DU PLAN TRACÉ » y mesure 358 px :
     la colonne en réserve 384 au minimum. */
  .experience__titre { font-size: 2.375rem; }

  /* Rangée explicite pour les trois blocs. Le placement automatique ne
     revient jamais en arrière : l'en-tête occupant la colonne 3, la
     scène — déclarée après lui dans le balisage — était renvoyée à une
     seconde rangée et débordait du cadre épinglé. */
  .jalons,
  .experience__scene,
  .experience__entete { grid-row: 1; }

  .jalons {
    grid-column: 1;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: center;
    align-items: flex-start;
    gap: var(--sp-6);
    padding-left: var(--sp-5);
  }

  .jalons__rail,
  .jalons__progres,
  .jalon::before { display: block; }

  .experience__scene {
    grid-column: 2;
    width: 100%;

    /* La scène ne doit jamais dépasser la hauteur disponible : sa
       largeur est plafonnée par ce que son propre rapport autorise.
       Sans cela, sur un écran large et bas, le plan déborderait du
       cadre épinglé. */
    max-width: calc((100svh - 16rem) * (800 / 560));
    margin-inline: auto;
  }

  .experience__entete {
    grid-column: 3;
    text-align: left;
  }

  .experience__entete .filet { margin-inline: 0; }
  .experience__legende { margin-inline: 0; }
}

/* Sous 1024 px la section reste épinglée, avec une course plus courte.
   Elle occupait auparavant une hauteur libre de 707 px : les sept phases
   s'y jouaient en moins d'un écran et demi de défilement, et la
   construction devenait illisible. Trois écrans laissent le temps de
   voir chaque passe, sans faire de la section un tunnel. */
@media (max-width: 63.99rem) {
  .experience { height: 320svh; }

  .experience__pin {
    height: 100svh;
    padding: calc(var(--h-nav) + var(--sp-4)) var(--marge) var(--sp-5);
    gap: var(--sp-5);
    grid-template-columns: minmax(0, 1fr);
    align-content: center;
  }

  /* Ordre de lecture sur écran étroit : le titre, puis la scène, puis
     la progression — qui devient une simple ligne de jalons. */
  .experience__entete { order: 1; }
  .experience__scene { order: 2; width: 100%; }
  .jalons { order: 3; }

  .experience__indice { display: none; }
}

/* La photographie du projet livré remplace le placeholder. */
.experience__photo-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- TITRE DE SECTION ---------- */
/* Deux lignes composées à la main. Chacune est un bloc : le retour à la
   ligne est une décision de composition, pas le hasard de la largeur
   disponible. */

.experience__titre span {
  display: block;
}

.experience__titre span:last-child {
  color: var(--or-clair);
}
