/* ══════════════════════════════════════════════════════════════════
   LES TROIS VITRINES — boutique/vitrines.css
   La feuille de vitrines.js : « Faire un cadeau », « Derrière
   l'objet », « Les collections portées ».
   ──────────────────────────────────────────────────────────────────
   ELLE SE CHARGE APRÈS presse.css et ne réécrit rien du socle : elle
   ne fait que CONSOMMER les variables de la rotative — --papier,
   --encre, --vermillon, --b20, les trois encres d'univers
   --u1/--u2/--u3, et les trois familles de caractères. Si presse.css
   manquait, tout ici retomberait sur les valeurs du socle : plus
   sombre, mais entier.

   LA GRAMMAIRE, la même que le reste du journal :
   · blocs CARRÉS — border-radius:0 partout, sans exception ;
   · des FILETS pour séparer : 1px --b20 entre les lignes, 8px --u2
     en tête de section, comme un pavé d'imprimerie ;
   · aucune ombre douce, aucun dégradé sucré ;
   · le titre en Bricolage capitales serrées, la prose en Georgia,
     les étiquettes en mono capitales espacées .12em.

   LE MOUVEMENT : opacity et transform, rien d'autre. Pas une seule
   règle n'anime filter, backdrop-filter, width, height, top ni left.
   L'unique interrupteur est :root[data-calme='1'] — il n'y a
   volontairement PAS de bloc @media (prefers-reduced-motion) ici,
   ce réglage est désarmé dans tout le projet parce que les
   économiseurs de batterie le posent sans que personne l'ait demandé.

   RIEN NE DÉBORDE LA PAGE : les rails de collections portent leur
   propre overflow-x. Le corps de page ne défile jamais de côté.
   ══════════════════════════════════════════════════════════════════ */

/* ══ 0. LE RÉVÉLATEUR ══
   Un seul geste, partagé par les trois vitrines : l'élément arrive
   de 14 px plus bas, en fondu. Le rang de passage est posé par le JS
   dans --v-rang (plafonné à 6) et ne sert qu'ici. */
.v-rev{
  opacity:0;
  transform:translate3d(0,14px,0);
  transition:opacity 450ms cubic-bezier(.16,1,.3,1),
             transform 450ms cubic-bezier(.16,1,.3,1);
  transition-delay:calc(var(--v-rang, 0) * 70ms);
  will-change:opacity, transform;
}
.v-rev.v-vu{ opacity:1; transform:translate3d(0,0,0) }
/* Une fois posé, l'élément n'a plus rien à promettre au compositeur. */
.v-rev.v-vu{ will-change:auto }

/* L'interrupteur de calme : le contenu reste ENTIER, seul le
   mouvement s'arrête. On ne coupe jamais le contenu. */
:root[data-calme='1'] .v-rev{
  opacity:1;
  transform:none;
  transition:none;
}
/* Les cartes et les tuiles SONT des .v-rev : la règle ci-dessus leur
   coupe aussi le soulèvement au survol, ce qui est exactement ce
   qu'on veut. Le bouton « Voir la fiche », lui, n'en est pas un —
   on le calme à la main, sinon il resterait le seul objet de la
   page à bouger quand on a demandé que rien ne bouge. */
:root[data-calme='1'] .v-rec__voir{ transition:none }
:root[data-calme='1'] .v-rec__voir:hover{ transform:none }

/* ══ 1. LE CADRE COMMUN DES TROIS SECTIONS ══
   Même gouttière que .coquille du socle, pour que les sections
   s'alignent au pixel sur celles qui les entourent. */
.v-sec{
  max-width:1320px;
  margin:0 auto;
  padding:clamp(46px,7vw,86px) clamp(18px,5vw,56px) clamp(38px,6vw,72px);
  background:var(--papier, var(--nuit));
  color:var(--encre);
  border-radius:0;
}

/* L'entête : le filet épais à l'encre du rayon, puis le sur-titre,
   puis le grand titre. C'est la tête de section d'un journal. */
.v-tete{
  border-top:8px solid var(--u2);
  padding-top:clamp(14px,2vw,22px);
  margin-bottom:clamp(26px,4vw,44px);
  max-width:56ch;
}
.v-tete__sur{
  font-family:var(--f-mono);
  font-size:.7rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--vermillon, var(--or));
  margin:0 0 10px;
}
.v-tete__t{
  font-family:var(--f-titre);
  font-weight:800;
  font-size:clamp(2.1rem,5.4vw,4.2rem);
  line-height:.96;
  letter-spacing:-.03em;
  text-transform:uppercase;
  color:var(--encre);
  margin:0;
}
.v-tete__mot{
  font-family:var(--f-corps);
  font-size:clamp(.98rem,1.15vw,1.08rem);
  line-height:1.62;
  color:var(--encre2);
  margin:14px 0 0;
  max-width:52ch;
}

/* ══ 2. LA CARTE-PRODUIT (« Faire un cadeau ») ══
   Un rectangle de papier bordé d'un filet. La photo est une DÉCOUPE
   posée entière sur la teinte claire du rayon : jamais recadrée —
   un produit coupé au bord est un produit qu'on ne reconnaît pas. */
.v-carte{
  display:flex;
  flex-direction:column;
  background:var(--papier, var(--nuit));
  border:1px solid var(--b20);
  border-radius:0;
  text-decoration:none;
  color:inherit;
  overflow:hidden;
  /* ⚠ CETTE CARTE EST AUSSI UN .v-rev, et `transition` est une
     propriété RACCOURCIE : écrire ici « transition:transform 220ms »
     effacerait purement et simplement la transition d'apparition
     posée plus haut (même spécificité, règle plus bas = elle gagne),
     et l'opacité sauterait d'un coup au lieu de monter en fondu.
     On garde donc la courbe d'entrée tant que la carte n'est pas
     arrivée, et on ne passe à la courbe de survol qu'après — d'où
     la règle .v-vu juste en dessous. */
  transition:opacity 450ms cubic-bezier(.16,1,.3,1),
             transform 450ms cubic-bezier(.16,1,.3,1);
  transition-delay:calc(var(--v-rang, 0) * 70ms);
}
.v-carte.v-vu{
  transition:transform 220ms cubic-bezier(.16,1,.3,1);
  transition-delay:0s;
}
/* Le survol soulève d'un cheveu — transform seul, jamais une ombre
   qui se met à respirer. Le focus clavier a droit au même signal,
   plus un cerne net pour qu'on sache où l'on est. */
@media (hover:hover){
  .v-carte:hover{ transform:translate3d(0,-3px,0) }
}
.v-carte:focus-visible{
  outline:2px solid var(--vermillon, var(--or));
  outline-offset:2px;
  transform:translate3d(0,-3px,0);
}
/* Un élément qui doit ARRIVER en glissant ne peut pas, en même
   temps, être soulevé par le survol : la seconde transformation
   effacerait la première. Tant qu'il n'est pas révélé, on ne le
   soulève pas. */
.v-carte.v-rev:not(.v-vu):hover{ transform:translate3d(0,14px,0) }

.v-carte__cadre{
  display:block;
  background:var(--u3);
  aspect-ratio:1 / 1;
  overflow:hidden;
}
.v-carte__cadre img{
  display:block;
  width:100%;
  height:100%;
  object-fit:contain;
  padding:8%;
  box-sizing:border-box;
}
.v-carte__bas{
  display:flex;
  flex-direction:column;
  gap:6px;
  padding:14px 14px 16px;
  border-top:1px solid var(--b20);
  flex:1 1 auto;
}
.v-carte__rayon{
  font-family:var(--f-mono);
  font-style:normal;
  font-size:.6rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--encre3, var(--encre2));
}
.v-carte__t{
  font-family:var(--f-corps);
  font-weight:400;
  font-size:.95rem;
  line-height:1.35;
  color:var(--encre);
  /* Deux lignes au plus : les titres du catalogue vont de trois mots
     à trente, et une carte qui pousse ses voisines casse la rangée. */
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
  flex:1 1 auto;
}
.v-carte__prix{
  font-family:var(--f-titre);
  font-weight:800;
  font-style:normal;
  font-size:1.12rem;
  letter-spacing:-.02em;
  color:var(--vermillon, var(--or));
}

/* ══ 3. « FAIRE UN CADEAU » ══ */

/* Les onglets : des étiquettes de classeur, pas des pilules. Le
   destinataire actif est en encre pleine. */
.v-cad__onglets{
  display:flex;
  flex-wrap:wrap;
  gap:0;
  border-bottom:1px solid var(--b20);
  margin-bottom:clamp(22px,3vw,34px);
}
.v-cad__onglet{
  appearance:none;
  border:1px solid var(--b20);
  border-bottom:none;
  border-radius:0;
  background:transparent;
  color:var(--encre2);
  font-family:var(--f-mono);
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  padding:12px 16px;
  margin-right:-1px;      /* les filets se touchent, un seul trait */
  cursor:pointer;
  /* Pas de transition ici : la règle de la maison n'anime que
     transform et opacity. Le changement de couleur au survol est
     donc net — et c'est très bien, un onglet doit répondre sec. */
}
.v-cad__onglet:hover{ color:var(--encre) }
.v-cad__onglet[aria-selected='true']{
  background:var(--encre);
  color:var(--papier, var(--nuit));
  border-color:var(--encre);
}
.v-cad__onglet:focus-visible{
  outline:2px solid var(--vermillon, var(--or));
  outline-offset:-4px;
}

/* Le panneau caché doit VRAIMENT disparaître : [hidden] perd contre
   un display: posé ici, et le panneau resterait visible sous les
   autres. C'est la panne classique des onglets. */
.v-cad__panneau[hidden]{ display:none }

.v-cad__palier{ margin-bottom:clamp(26px,4vw,44px) }
.v-cad__palier:last-child{ margin-bottom:0 }

/* L'étiquette de budget : le nom du palier à gauche, la fourchette
   RÉELLE à droite — elle est calculée sur les prix du catalogue au
   moment où la page se peint, jamais écrite en dur. */
.v-cad__palierTete{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:14px;
  border-bottom:1px solid var(--b20);
  padding-bottom:8px;
  margin-bottom:16px;
}
.v-cad__palierTete b{
  font-family:var(--f-titre);
  font-weight:800;
  font-size:clamp(1.1rem,2vw,1.5rem);
  letter-spacing:-.02em;
  text-transform:uppercase;
  color:var(--encre);
}
.v-cad__palierTete i{
  font-family:var(--f-mono);
  font-style:normal;
  font-size:.68rem;
  letter-spacing:.1em;
  color:var(--vermillon, var(--or));
  white-space:nowrap;
}

.v-cad__grille{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(10px,1.6vw,20px);
}

/* ══ 4. LES RÉCITS ══
   Un pavé éditorial par objet : la photo d'un côté, la prose de
   l'autre, et l'alternance qui empêche la page de ronronner. */
.v-recs .v-rec{
  display:grid;
  grid-template-columns:minmax(0,5fr) minmax(0,7fr);
  gap:clamp(20px,3.5vw,52px);
  align-items:start;
  padding:clamp(28px,4vw,52px) 0;
  border-top:1px solid var(--b20);
}
.v-recs .v-rec:first-of-type{ border-top:none; padding-top:0 }
/* Un pavé sur deux se retourne : l'image passe à droite. On échange
   les COLONNES DE GRILLE, jamais l'ordre du DOM — le lecteur d'écran
   et le clavier lisent toujours titre, texte, prix, lien. */
.v-recs .v-rec:nth-of-type(even) .v-rec__vue{ grid-column:2 }
.v-recs .v-rec:nth-of-type(even) .v-rec__texte{ grid-column:1; grid-row:1 }

.v-rec__vue{
  background:var(--u3);
  border:1px solid var(--b20);
  aspect-ratio:4 / 5;
  position:relative;
  overflow:hidden;
}
/* 17/08 : l'image est en ABSOLU, plus un enfant de grille. En grille,
   la rangée `auto` se mesure sur le contenu : le height:100% de
   l'image devenait cyclique, retombait sur `auto`, et l'image gardait
   sa hauteur de ratio — 592 px dans une case de 577 (mesuré), moitié
   du produit coupée en mobile. En absolu, 100 % se résout contre la
   case (hauteur définie par aspect-ratio) : le produit tient entier. */
.v-rec__vue img{
  display:block;
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:contain;
  padding:7%;
  box-sizing:border-box;
}

.v-rec__no{
  font-family:var(--f-mono);
  font-size:.7rem;
  letter-spacing:.24em;
  color:var(--vermillon, var(--or));
  margin:0 0 8px;
}
.v-rec__t{
  font-family:var(--f-titre);
  font-weight:800;
  font-size:clamp(1.7rem,3.6vw,2.9rem);
  line-height:1;
  letter-spacing:-.03em;
  text-transform:uppercase;
  color:var(--encre);
  margin:0 0 16px;
}
.v-rec__p{
  font-family:var(--f-corps);
  font-size:clamp(1rem,1.15vw,1.08rem);
  line-height:1.7;
  color:var(--encre);
  margin:0 0 14px;
  max-width:62ch;
}
/* La première ligne du récit porte une lettrine : le signal « ceci
   se lit » d'un journal imprimé. */
.v-rec__p:first-of-type::first-letter{
  font-family:var(--f-titre);
  font-weight:800;
  font-size:3.1em;
  line-height:.82;
  float:left;
  margin:2px 10px 0 0;
  color:var(--vermillon, var(--or));
}

/* Les repères : ce que le récit avance et qu'on peut vérifier.
   Chaque ligne commence par un filet court, pas par une puce ronde. */
.v-rec__reperes{
  list-style:none;
  margin:20px 0 0;
  padding:0;
  border-top:1px solid var(--b20);
}
.v-rec__reperes li{
  font-family:var(--f-mono);
  font-size:.68rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--encre2);
  padding:9px 0 9px 26px;
  border-bottom:1px solid var(--b20);
  position:relative;
}
.v-rec__reperes li::before{
  content:'';
  position:absolute;
  left:0;
  top:1.05em;
  width:14px;
  height:2px;
  background:var(--u2);
}

.v-rec__pied{
  display:flex;
  align-items:center;
  gap:18px;
  flex-wrap:wrap;
  margin:20px 0 0;
}
.v-rec__prix{
  font-family:var(--f-titre);
  font-weight:800;
  font-size:clamp(1.4rem,2.4vw,2rem);
  letter-spacing:-.02em;
  color:var(--vermillon, var(--or));
}
.v-rec__voir{
  font-family:var(--f-mono);
  font-size:.7rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--encre);
  text-decoration:none;
  padding:12px 20px;
  border:1.5px solid var(--encre);
  border-radius:0;
  transition:transform 200ms cubic-bezier(.16,1,.3,1);
}
@media (hover:hover){
  .v-rec__voir:hover{ transform:translate3d(0,-2px,0) }
}
.v-rec__voir:focus-visible{
  outline:2px solid var(--vermillon, var(--or));
  outline-offset:2px;
}

/* ══ 5. LES COLLECTIONS PORTÉES ══
   Un rail par famille. Les tuiles sont grandes et en portrait 3/4 :
   c'est le format d'une planche de lookbook, et c'est le seul qui
   laisse voir un vêtement en entier sur quelqu'un. */
.v-col__famille{
  padding:clamp(24px,3.4vw,40px) 0;
  border-top:1px solid var(--b20);
}
.v-col__famille:first-of-type{ border-top:none; padding-top:0 }

.v-col__familleTete{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:18px;
  flex-wrap:wrap;
  margin-bottom:clamp(14px,2vw,22px);
}
.v-col__familleMots h3{
  font-family:var(--f-titre);
  font-weight:800;
  font-size:clamp(1.5rem,3vw,2.3rem);
  line-height:1;
  letter-spacing:-.03em;
  text-transform:uppercase;
  color:var(--encre);
  margin:0;
}
.v-col__familleMots p{
  font-family:var(--f-corps);
  font-size:.95rem;
  line-height:1.5;
  color:var(--encre2);
  margin:8px 0 0;
  max-width:44ch;
}
.v-col__tout{
  font-family:var(--f-mono);
  font-size:.68rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--encre);
  text-decoration:none;
  border-bottom:2px solid var(--u2);
  padding-bottom:3px;
  white-space:nowrap;
}
.v-col__tout:focus-visible{
  outline:2px solid var(--vermillon, var(--or));
  outline-offset:3px;
}

/* LE RAIL. Il porte SON overflow — la page, elle, ne défile jamais
   de côté. scroll-snap pour que les tuiles se calent, et une marge
   de fin pour que la dernière ne colle pas au bord. */
.v-col__rail{
  display:grid;
  grid-auto-flow:column;
  grid-auto-columns:minmax(220px, 27%);
  gap:clamp(10px,1.4vw,18px);
  overflow-x:auto;
  overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;
  padding-bottom:10px;
  /* le clavier peut défiler le rail : il faut voir qu'il l'a saisi */
  scrollbar-width:thin;
}
.v-col__rail:focus-visible{
  outline:2px solid var(--vermillon, var(--or));
  outline-offset:4px;
}

.v-col__tuile{
  display:flex;
  flex-direction:column;
  scroll-snap-align:start;
  text-decoration:none;
  color:inherit;
  border:1px solid var(--b20);
  border-radius:0;
  background:var(--papier, var(--nuit));
  /* même précaution que sur .v-carte : la tuile est un .v-rev, et le
     raccourci `transition` écraserait sa courbe d'apparition. */
  transition:opacity 450ms cubic-bezier(.16,1,.3,1),
             transform 450ms cubic-bezier(.16,1,.3,1);
  transition-delay:calc(var(--v-rang, 0) * 70ms);
}
.v-col__tuile.v-vu{
  transition:transform 240ms cubic-bezier(.16,1,.3,1);
  transition-delay:0s;
}
@media (hover:hover){
  .v-col__tuile:hover{ transform:translate3d(0,-4px,0) }
}
.v-col__tuile:focus-visible{
  outline:2px solid var(--vermillon, var(--or));
  outline-offset:2px;
  transform:translate3d(0,-4px,0);
}
.v-col__tuile.v-rev:not(.v-vu):hover{ transform:translate3d(0,14px,0) }

.v-col__vue{
  display:block;
  aspect-ratio:3 / 4;          /* le portrait demandé */
  background:var(--u3);
  overflow:hidden;
}
.v-col__vue img{
  display:block;
  width:100%;
  height:100%;
  /* contain, pas cover : ces photos sont des silhouettes entières
     détourées sur blanc. Un cadrage « cover » couperait les pieds ou
     la tête, et c'est justement le corps entier qu'on vient voir. */
  object-fit:contain;
  padding:4% 6%;
  box-sizing:border-box;
}
.v-col__bas{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:10px;
  padding:12px 12px 14px;
  border-top:1px solid var(--b20);
  flex:1 1 auto;
}
.v-col__bas b{
  font-family:var(--f-corps);
  font-weight:400;
  font-size:.88rem;
  line-height:1.3;
  color:var(--encre);
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
}
.v-col__bas em{
  font-family:var(--f-titre);
  font-weight:800;
  font-style:normal;
  font-size:1rem;
  letter-spacing:-.02em;
  color:var(--vermillon, var(--or));
  white-space:nowrap;
}

/* ══ 6. LES DEUX PORTES — HOMME / FEMME ══
   « 2 catégories en gros côte à côte, en carré, avec image d'un
   mannequin du produit, homme et femme, avec catégorie homme et
   femme, découvrir etc. »

   DEUX BLOCS CARRÉS, et carrés pour de bon : aspect-ratio sur la
   tuile entière, pas sur la seule image. La tuile est une colonne
   flexible — le lit de la photo prend ce qui reste, la bande de
   texte prend sa hauteur naturelle. C'est la seule construction qui
   tienne quand le mot passe sur deux lignes en très petit écran ;
   une bande posée en absolu obligerait à réserver sa place en
   pourcentage, et le pourcentage ment dès que la tuile change de
   proportion.

   ⚠ LA PHOTO EST EN ABSOLU DANS SON LIT, même leçon que les récits
   le 17/08 : `height:100%` sur une image enfant d'une case dont la
   hauteur se mesure sur le contenu est un raisonnement circulaire —
   le navigateur retombe sur la hauteur intrinsèque et le produit
   déborde. En absolu, 100 % se résout contre le lit, dont la hauteur
   est définie par le carré de la tuile.

   LES COULEURS SONT CELLES DU JOURNAL, PAS CELLES D'UN UNIVERS.
   Le rayon femme n'a pas encore d'encre déclarée : lui prêter --u2
   ou --u3 lui donnerait la couleur du rayon voisin, c'est-à-dire une
   couleur fausse. Papier, encre, vermillon — ça marche des deux
   côtés et ça ne périme pas.

   LE MOUVEMENT : transform et opacity, rien d'autre. La tuile monte
   de 4 px au survol, la photo respire de 3 %. Aucun bloc
   prefers-reduced-motion — il est désarmé dans tout le projet ;
   l'unique interrupteur est :root[data-calme='1']. */

.v-portes__duo{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(12px,1.8vw,24px);
}
/* UNE SEULE PORTE (le rayon d'en face n'existe pas encore, ou sa
   photo n'a pas chargé) : elle prend toute la largeur. Un carré de
   1320 px de côté serait un mur — le bloc s'allonge donc en bandeau.
   La classe est posée par le JS : `:has()` ferait le même travail,
   mais pas sur les navigateurs qu'on doit encore servir. */
.v-portes__duo--seule{ grid-template-columns:minmax(0,1fr) }
.v-portes__duo--seule .v-porte{ aspect-ratio:21 / 9 }

.v-porte{
  display:flex;
  flex-direction:column;
  aspect-ratio:1 / 1;
  overflow:hidden;
  border:1px solid var(--b20);
  border-radius:0;
  background:var(--nuit2,#EAE1D0);
  text-decoration:none;
  color:inherit;
  /* ⚠ MÊME PIÈGE QUE .v-carte : la tuile EST un .v-rev, et
     `transition` est une propriété raccourcie. Écrire ici
     « transition:transform 240ms » effacerait la transition
     d'apparition et l'opacité sauterait d'un coup. On garde donc la
     courbe d'entrée, et on ne passe à celle du survol qu'une fois la
     tuile arrivée (.v-vu, juste en dessous). */
  transition:opacity 450ms cubic-bezier(.16,1,.3,1),
             transform 450ms cubic-bezier(.16,1,.3,1);
  transition-delay:calc(var(--v-rang, 0) * 70ms);
}
.v-porte.v-vu{
  transition:transform 240ms cubic-bezier(.16,1,.3,1);
  transition-delay:0s;
}
@media (hover:hover){
  .v-porte:hover{ transform:translate3d(0,-4px,0) }
}
.v-porte:focus-visible{
  outline:2px solid var(--vermillon, var(--or));
  outline-offset:2px;
  transform:translate3d(0,-4px,0);
}
/* Tant qu'elle n'est pas révélée, on ne la soulève pas : la seconde
   transformation effacerait la première. */
.v-porte.v-rev:not(.v-vu):hover{ transform:translate3d(0,14px,0) }

.v-porte__vue{
  display:block;
  position:relative;
  flex:1 1 auto;
  min-height:0;          /* sans lui, l'image pousse la bande dehors */
  overflow:hidden;
}
.v-porte__vue img{
  display:block;
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  /* contain, jamais cover : ce sont des silhouettes entières
     détourées. Un cadrage « cover » couperait la tête ou les pieds,
     et c'est précisément le vêtement porté en entier qu'on vient
     voir. */
  object-fit:contain;
  padding:5% 6%;
  box-sizing:border-box;
  transition:transform 320ms cubic-bezier(.16,1,.3,1);
}
@media (hover:hover){
  .v-porte:hover .v-porte__vue img{ transform:scale(1.03) }
}

/* LA BANDE. Elle est en papier plein et séparée par un filet épais :
   c'est le bandeau d'une une de journal, pas une légende posée sur
   la photo. Le mot de la catégorie est le plus gros caractère de la
   section après le titre. */
.v-porte__bas{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:14px;
  flex:0 0 auto;
  padding:clamp(12px,1.6vw,20px) clamp(14px,2vw,24px);
  background:var(--papier, var(--nuit));
  border-top:2px solid var(--encre);
}
.v-porte__mots{
  display:flex;
  flex-direction:column;
  gap:4px;
  min-width:0;
}
.v-porte__mot{
  font-family:var(--f-titre);
  font-weight:800;
  font-size:clamp(1.6rem,3.6vw,3rem);
  line-height:.94;
  letter-spacing:-.03em;
  text-transform:uppercase;
  color:var(--encre);
}
.v-porte__compte{
  font-family:var(--f-mono);
  font-style:normal;
  font-size:.66rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--encre3, var(--encre2));
}
.v-porte__appel{
  display:inline-flex;
  align-items:center;
  gap:8px;
  flex:0 0 auto;
  font-family:var(--f-mono);
  font-size:.7rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--encre);
  border-bottom:2px solid var(--vermillon, var(--or));
  padding-bottom:4px;
  white-space:nowrap;
}
.v-porte__fleche{
  font-style:normal;
  color:var(--vermillon, var(--or));
  transition:transform 240ms cubic-bezier(.16,1,.3,1);
}
@media (hover:hover){
  .v-porte:hover .v-porte__fleche{ transform:translate3d(4px,0,0) }
}

/* L'interrupteur de calme : le contenu reste ENTIER, seul le
   mouvement s'arrête. La règle générale sur .v-rev tient déjà la
   tuile ; l'image et la flèche ne sont pas des .v-rev, on les calme
   à la main — sinon elles resteraient les seules choses qui bougent
   quand on a demandé que rien ne bouge. */
:root[data-calme='1'] .v-porte__vue img,
:root[data-calme='1'] .v-porte__fleche{ transition:none }
:root[data-calme='1'] .v-porte:hover .v-porte__vue img,
:root[data-calme='1'] .v-porte:hover .v-porte__fleche{ transform:none }

/* ══ 7. LES ÉCRANS ÉTROITS ══
   Rien ne disparaît, tout se remet en colonne. Les tailles sont déjà
   fluides (clamp) : il ne reste ici que ce qui change de forme. */
@media (max-width:900px){
  .v-recs .v-rec{
    grid-template-columns:minmax(0,1fr);
    gap:20px;
  }
  /* L'alternance n'a plus de sens sur une colonne : on annule les
     placements, sinon le texte du pavé pair irait en ligne 1 et
     recouvrirait l'image. */
  .v-recs .v-rec:nth-of-type(even) .v-rec__vue,
  .v-recs .v-rec:nth-of-type(even) .v-rec__texte{
    grid-column:auto;
    grid-row:auto;
  }
  .v-rec__vue{ aspect-ratio:3 / 2 }
}

/* LES DEUX PORTES S'EMPILENT. Elles restent carrées : sur un
   téléphone, un carré pleine largeur est exactement la bonne taille
   pour une silhouette en pied. La porte restée seule redevient carrée
   elle aussi — le bandeau 21/9 n'a de sens que sur grand écran. */
@media (max-width:720px){
  .v-portes__duo{ grid-template-columns:minmax(0,1fr) }
  .v-portes__duo--seule .v-porte{ aspect-ratio:1 / 1 }
}

@media (max-width:640px){
  .v-cad__grille{ grid-template-columns:repeat(2,minmax(0,1fr)) }
  .v-cad__palierTete{
    flex-direction:column;
    align-items:flex-start;
    gap:4px;
  }
  .v-col__rail{ grid-auto-columns:minmax(190px, 66%) }
  .v-carte__cadre{ aspect-ratio:4 / 5 }
}
