/* ============================================================
   RÉALISATIONS — index des chantiers + 4 fiches
   ------------------------------------------------------------
   Épuré le 29/07/2026 : le rail cinématique qui défilait en
   parallaxe (affiches 4/5, voile de projection, barre de
   travelling) est remplacé par une grille de quatre couvertures.
   La planche photo justifiée et la visionneuse sont conservées
   telles quelles : ce sont des outils pour regarder les photos,
   pas des effets.
   ============================================================ */

/* ---------- Index : quatre couvertures, quatre ancres ---------- */
.index{
  list-style:none; margin:0; padding:0;
  display:grid; gap:clamp(1.5rem,3vw,2.5rem);
  grid-template-columns:repeat(4,minmax(0,1fr));
}
.index a{
  display:grid; gap:.75rem; text-decoration:none;
  grid-template-rows:auto auto auto auto;
}
.index img{
  width:100%; aspect-ratio:4/5; object-fit:cover;
  background:var(--chaux);
  transition:opacity .25s;
}
.index a:hover img{ opacity:.88; }
.index__num{
  font-family:var(--f-cote); font-size:.66rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--beton);
}
.index h3{ margin:0; }
.index a:hover h3{ text-decoration:underline; text-decoration-color:var(--accent); text-underline-offset:3px; }

@media (max-width:900px){
  .index{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@media (max-width:520px){
  .index{ grid-template-columns:1fr; }
  .index img{ aspect-ratio:16/10; }
}

/* ============================================================
   FICHES CHANTIER
   ============================================================ */
.chantier{ scroll-margin-top:calc(var(--entete-h) + 1.5rem); }

.chantier__tete{
  display:grid;
  grid-template-columns:minmax(0,1.5fr) minmax(0,.8fr);
  gap:clamp(2rem,5vw,4.5rem);
  align-items:start;
}
@media (max-width:900px){ .chantier__tete{ grid-template-columns:1fr; } }

.chantier__intro h2{ margin-bottom:1.4rem; }
.chantier__intro .chapo{ margin-bottom:2rem; }

/* --- les lots réalisés : chaque point est un ouvrage, pas un argument --- */
.lots{ list-style:none; margin:0; padding:0; display:grid; gap:1.05rem; max-width:64ch; }
.lots li{
  position:relative;
  padding-left:1.7rem;
  font-size:.97rem; line-height:1.6;
}
.lots li::before{
  content:''; position:absolute; left:0; top:.68em;
  width:9px; height:1px; background:var(--accent);
}
.lots b{ color:var(--graphite); font-weight:600; }

/* --- le cartouche de repères : les valeurs du chantier, en mono --- */
.reperes{
  margin:0;
  border-top:1px solid var(--graphite);
}
.reperes > div{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);
  gap:.9rem; padding:.7rem 0;
  border-bottom:1px solid var(--trait);
}
.reperes dt{
  font-family:var(--f-cote); font-size:.61rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--beton); align-self:center;
}
.reperes dd{
  margin:0; font-family:var(--f-cote); font-size:.86rem;
  color:var(--graphite); font-weight:500; line-height:1.4;
}

/* --- la planche photo : rangées JUSTIFIÉES ---------------------------
   Refaite le 28/07/2026. Avant, chaque photo était enfermée dans une case
   4/3 (et la première dans un 16/9), avec object-fit:cover : les 28 photos
   ont onze proportions différentes, de 1,09 à 1,78 — jusqu'à un quart de
   l'image passait à la trappe, et toujours par les bords, là où se trouve
   précisément le contexte du chantier.

   Ici c'est l'inverse : la CASE prend la proportion de la PHOTO, et la
   mise en page s'arrange autour. Le mécanisme tient en deux déclarations —
   chaque photo reçoit `--ar` (sa proportion réelle, écrite dans le HTML) ;
   sa largeur de base ET son coefficient d'étirement sont proportionnels à
   `--ar`. Résultat : dans une rangée, largeur_i = ar_i × h, donc toutes
   les photos ont exactement la même hauteur h et AUCUNE n'est déformée ni
   recadrée. C'est la mise en page « justifiée » des banques d'images, en
   flexbox pur, sans une ligne de JavaScript.                            */
.planche{
  margin-top:clamp(2.4rem,5vw,3.8rem);
  display:flex; flex-wrap:wrap;
  gap:clamp(.45rem,.85vw,.8rem);
  /* la dernière rangée, forcément incomplète, se centre sous les autres :
     un reliquat centré se lit comme une fin de série, un reliquat collé à
     gauche se lit comme un bug de mise en page */
  justify-content:center;
}
.vue{
  position:relative; display:block; overflow:hidden;
  margin:0; padding:0; border:0; cursor:zoom-in;
  background:var(--chaux);
  /* largeur ∝ proportion → hauteurs égales dans la rangée */
  flex:var(--ar,1.333) 1 calc(var(--ar,1.333) * 12.5rem);
  /* Plafond d'étirement : sans lui, une photo seule en fin de série
     occuperait toute la largeur — trois fois plus grande que ses voisines,
     pour la seule raison qu'elle est la dernière. 21rem est sa hauteur
     maximale ; la largeur suit la proportion. */
  max-width:calc(var(--ar,1.333) * 21rem);
  aspect-ratio:var(--ar,1.333);
  min-width:0;
}

.vue img{
  width:100%; height:100%;
  object-fit:cover;      /* sans effet : la case a déjà la proportion de l'image */
  display:block;
  transition:opacity .25s;
}
.vue:hover img,.vue:focus-visible img{ opacity:.86; }

@media (max-width:640px){
  /* une photo par rangée : la base doit dépasser la moitié de la largeur,
     sinon deux paysages se tassent côte à côte et deviennent illisibles */
  .vue{ flex-basis:calc(var(--ar,1.333) * 18rem); }
}
@media (prefers-reduced-motion: reduce){
  .vue img{ transition:none; }
  .vue:hover img{ opacity:1; }
}

/* ============================================================
   VISIONNEUSE PLEIN ÉCRAN
   ============================================================ */
.loupe{
  position:fixed; inset:0; z-index:200;
  display:grid; grid-template-columns:auto 1fr auto; align-items:center;
  gap:clamp(.4rem,2vw,1.4rem);
  padding:clamp(.8rem,3vw,2.2rem);
  background:rgba(19,22,25,.94);
  animation:loupe-entre .18s ease-out;
}
.loupe[hidden]{ display:none; }
@keyframes loupe-entre{ from{ opacity:0 } to{ opacity:1 } }

.loupe__scene{
  margin:0; min-width:0; height:100%;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:1rem;
}
.loupe__scene img{
  max-width:100%; max-height:calc(100vh - 9rem);
  width:auto; height:auto; object-fit:contain;
}
.loupe__scene figcaption{
  display:flex; flex-wrap:wrap; align-items:baseline; justify-content:center;
  gap:.4rem 1.2rem;
  max-width:70ch; text-align:center;
  color:#DAD8D2; font-size:.93rem;
}
.loupe__compte{
  font-family:var(--f-cote); font-size:.68rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--accent);
}

.loupe__fermer,.loupe__nav{
  border:1px solid rgba(255,255,255,.28); background:transparent; color:#fff;
  cursor:pointer; line-height:1;
  transition:background .2s, border-color .2s;
}
.loupe__nav{
  width:clamp(38px,6vw,54px); height:clamp(60px,12vh,110px);
  font-size:clamp(1.6rem,3vw,2.4rem);
}
.loupe__nav:hover{ background:var(--accent); border-color:var(--accent); color:var(--graphite); }
.loupe__fermer{
  position:absolute; top:clamp(.8rem,3vw,2.2rem); right:clamp(.8rem,3vw,2.2rem);
  width:42px; height:42px; font-size:1.05rem; z-index:1;
}
.loupe__fermer:hover{ background:var(--accent); border-color:var(--accent); color:var(--graphite); }

@media (max-width:600px){
  .loupe{ grid-template-columns:1fr; grid-template-rows:1fr auto; }
  .loupe__nav{ height:46px; width:100%; }
  .loupe{ grid-template-areas:'scene' 'nav'; }
  .loupe__scene{ grid-area:scene; }
  .loupe__nav--prec,.loupe__nav--suiv{ grid-area:nav; }
  .loupe__nav--prec{ justify-self:start; width:46%; }
  .loupe__nav--suiv{ justify-self:end; width:46%; }
  .loupe__scene img{ max-height:calc(100vh - 13rem); }
}
