/* =========================================================================
   BRIDE. — accessoires de mariée
   Modèle « Rose découpe » · famille photo L (aplat de couleur, paramètre rose)

   Le parti pris : le rose est PASTEL sur la page et SATURÉ dans les photos.
   C'est le même rose, à deux intensités, et c'est ce qui tient tout l'écran.
   L'accent #EA3B76 est relevé au compte-gouttes sur le fond des photos, pour
   que la page et les images ne se contredisent pas.

   Trois gestes portent le modèle, et rien d'autre :
     1. le volet    — tout apparaît en scaleY depuis le bas, jamais en fondu
     2. la découpe  — un masque PNG au bord déchiré, jamais un bord CSS
     3. la coupe    — les mots sortent du cadre, on les laisse sortir
   ========================================================================= */

:root {
  --rose:        #F9DCE4;  /* le sol de la page */
  --rose-2:      #F2C9D6;  /* les surfaces posées dessus */
  --rose-vif:    #EA3B76;  /* l'accent, relevé sur le fond des photos */
  --encre:       #0E0D10;
  --encre-2:     #5A4650;  /* gris chaud, penché vers l'accent */
  --craie:       #FFFFFF;

  --volet:       cubic-bezier(0.75, 0, 0.25, 1);  /* la seule courbe du site */

  --marge:       clamp(16px, 4vw, 56px);
  --filet:       1px solid rgba(14, 13, 16, 0.18);
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--rose);
  color: var(--encre);
  font-family: 'DM Mono', ui-monospace, 'Courier New', monospace;
  font-weight: 400;
  font-size: 15px;
  line-height: 1.66;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--encre);
  outline-offset: 3px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--encre); color: var(--rose);
  padding: 12px 18px; text-transform: uppercase; letter-spacing: .08em;
}
.skip-link:focus { left: 0; }

/* ---------- typographie ------------------------------------------------ */

.titre {
  font-family: Anton, 'Arial Narrow', Impact, sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  line-height: .84;
  letter-spacing: -.005em;
  margin: 0;
  text-wrap: balance;
}

.mo {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .14em;
  font-weight: 500;
}

.mo-vif { color: var(--rose-vif); }

p { margin: 0 0 1em; max-width: 58ch; }

/* ---------- en-tête ---------------------------------------------------- */

.entete {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 14px var(--marge);
  background: var(--rose);
  border-bottom: var(--filet);
}

.marque {
  font-family: Anton, 'Arial Narrow', Impact, sans-serif;
  font-size: 22px; text-transform: uppercase; letter-spacing: .02em;
  text-decoration: none; line-height: 1;
}

.nav-liens { display: flex; gap: 22px; list-style: none; margin: 0; padding: 0; }
.nav-liens a { text-decoration: none; padding: 6px 0; }
.nav-liens a:hover { color: var(--rose-vif); }

@media (max-width: 860px) { .nav-liens { display: none; } }

.entete-cta {
  border: 1px solid var(--encre);
  padding: 9px 16px; text-decoration: none;
  background: var(--encre); color: var(--rose);
  transition: background .2s var(--volet), color .2s var(--volet);
}
.entete-cta:hover { background: var(--rose-vif); border-color: var(--rose-vif); color: var(--craie); }

/* ---------- héros ------------------------------------------------------ */

.heros { padding: clamp(28px, 6vw, 64px) 0 0; }

.heros-haut {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 20px; padding: 0 var(--marge) 10px; flex-wrap: wrap;
}

/* Le titre sort volontairement du cadre à gauche : à cette taille, une marge
   confortable ferait un titre sage, et le modèle n'est pas sage. */
/* 33vw n'est pas une valeur au hasard : dans Anton, « BRIDE. » mesure environ
   2,64 fois sa taille de police. Sur une page qui laisse 92vw entre ses marges,
   le mot remplit donc la ligne exactement à 92 / 2,64 ≈ 34vw. On reste un cran
   en dessous pour l'italien et les écrans étroits. Le plafond n'existe que pour
   les très grands écrans, où le mot cesserait d'être un titre. */
.heros-titre {
  font-size: clamp(52px, 33vw, 560px);
  padding: 0 var(--marge);
  margin-left: -.045em;
}
.heros-titre .point { color: var(--rose-vif); }

.heros-def {
  padding: 14px var(--marge) 26px;
  display: grid; grid-template-columns: 1fr; gap: 6px;
  border-bottom: var(--filet);
}
.heros-def dt { font-size: 11px; text-transform: uppercase; letter-spacing: .14em; color: var(--encre-2); }
.heros-def dd { margin: 0; max-width: 46ch; }
@media (min-width: 900px) {
  .heros-def { grid-template-columns: 200px 1fr; gap: 0 40px; align-items: baseline; }
}

/* La découpe : deux fois la même image, celle du dessous en niveaux de gris,
   celle du dessus en couleur et masquée par un PNG au bord déchiré.
   Le bord n'est donc jamais dessiné en CSS : il vit dans le masque.

   ⚠️ Le `mask-image` lui-même est dans css/masques.css, en data-URI. Ce n'est
   pas un caprice : un masque CSS est soumis au contrôle d'origine, et un
   fichier ouvert en file:// est une origine opaque. Un url() vers le PNG fait
   donc DISPARAÎTRE le héros dès qu'on ouvre le modèle au double-clic, sans
   la moindre erreur en console. Ici on ne règle que sa taille. */
/* ⚠️ `width: 100%` n'est pas superflu. Sans lui, `aspect-ratio` et `min-height`
   se liguent : sur un téléphone de 391 px, le ratio 16/9 donne 220 px de haut,
   le min-height le remonte à 320, et le navigateur RÉTABLIT le ratio en
   élargissant le bloc à 569 px. L'image sortait donc de l'écran. Avec une
   largeur imposée, le ratio ne pilote plus que la hauteur. */
.decoupe {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 320px;
  background: var(--encre);
  overflow: hidden;
}
.decoupe img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.decoupe .gris { filter: grayscale(1) contrast(1.12); }
.decoupe .couleur {
  mask-size: 100% 100%;
  mask-repeat: no-repeat;
}
.decoupe-legende {
  position: absolute; left: var(--marge); bottom: 16px;
  color: var(--craie); mix-blend-mode: normal;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .5);
}

/* ---------- l'arrivée --------------------------------------------------
   Tout entre scaleY depuis le bas, comme les volets : ce modele ne fond
   jamais, il se deplie. L'ordre est celui de la lecture : la ligne de
   metier, le nom BRIDE., la definition, puis la decoupe photographique -
   chacun attend un cran que le precedent soit pose.
   La classe `arrive` est posee par un script inline des le <body>, avant la
   premiere peinture (voir l'index) : sans lui, aucune regle ne s'applique
   et la page est montree finie - une page qui cache son contenu quand un
   script echoue est une page vide. */
body.arrive .heros-haut  { animation: monter .5s var(--volet) both; transform-origin: bottom; }
body.arrive .heros-titre { animation: monter .55s var(--volet) .06s both; transform-origin: bottom; }
body.arrive .heros-def   { animation: monter .5s var(--volet) .14s both; transform-origin: bottom; }
body.arrive .decoupe     { animation: monter .75s var(--volet) .24s both; transform-origin: bottom; }
@keyframes monter { from { transform: scaleY(0); } }

/* ---------- bandeau défilant ------------------------------------------- */

.bandeau {
  background: var(--encre); color: var(--rose-vif);
  overflow: hidden; padding: 13px 0;
  border-block: 1px solid var(--encre);
}
.bandeau-piste {
  display: flex; width: max-content;
  animation: defile 34s linear infinite;
}
.bandeau-piste span {
  font-family: Anton, 'Arial Narrow', Impact, sans-serif;
  font-size: 19px; text-transform: uppercase; letter-spacing: .06em;
  padding-right: 28px; white-space: nowrap;
}
.bandeau-piste span::after { content: '·'; padding-left: 28px; color: var(--rose); }
@keyframes defile { to { transform: translateX(-50%); } }
.bandeau:hover .bandeau-piste { animation-play-state: paused; }

/* ---------- titres de section ------------------------------------------ */

.section { padding: clamp(56px, 9vw, 130px) var(--marge); }

.section-entete {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  padding-bottom: 22px; margin-bottom: clamp(30px, 5vw, 58px);
  border-bottom: var(--filet);
}
.section-titre { font-size: clamp(38px, 7vw, 96px); }
.section-note { max-width: 34ch; margin: 0; color: var(--encre-2); font-size: 14px; }

/* ---------- le vestiaire : la grille déstructurée ---------------------- */

/* Six cartes sur douze colonnes, jamais alignées deux à deux. Les décalages
   verticaux sont écrits à la main, pas calculés : c'est une composition, pas
   une grille. Sous 900 px tout retombe sur deux colonnes régulières, parce
   qu'un décalage sur un écran de téléphone ne se lit pas, il casse. */
.vestiaire {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(20px, 3vw, 46px);
}

.piece { grid-column: span 6; margin: 0; }

@media (min-width: 900px) {
  .piece:nth-child(1) { grid-column: 1 / span 5; }
  .piece:nth-child(2) { grid-column: 7 / span 4;  margin-top: 96px; }
  .piece:nth-child(3) { grid-column: 2 / span 4;  margin-top: -40px; }
  .piece:nth-child(4) { grid-column: 8 / span 5;  margin-top: 20px; }
  .piece:nth-child(5) { grid-column: 1 / span 4;  margin-top: 40px; }
  .piece:nth-child(6) { grid-column: 6 / span 5;  margin-top: -30px; }

  /* Deux cartes seulement sont désaxées. Au-delà, ce n'est plus une intention,
     c'est un bug. */
  .piece:nth-child(3) { transform: rotate(-1.4deg); }
  .piece:nth-child(6) { transform: rotate(1.1deg); }
}

.piece-vue {
  position: relative; overflow: hidden;
  background: var(--rose-2);
  aspect-ratio: 3 / 4;
}
.piece-vue img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .9s var(--volet), filter .5s var(--volet);
}
.piece:hover .piece-vue img { transform: scale(1.06); }

.piece-num {
  position: absolute; top: 10px; right: 12px;
  color: var(--craie); font-size: 11px; letter-spacing: .14em;
  text-shadow: 0 1px 5px rgba(0, 0, 0, .45);
}

.piece-nom {
  font-family: Anton, 'Arial Narrow', Impact, sans-serif;
  font-size: clamp(24px, 3.4vw, 42px);
  text-transform: uppercase; line-height: .9;
  margin: 16px 0 10px;
}

.piece-specs { list-style: none; margin: 0; padding: 0; border-top: var(--filet); }
.piece-specs li {
  display: flex; justify-content: space-between; gap: 14px;
  padding: 7px 0; border-bottom: var(--filet);
  font-size: 13px;
}
.piece-specs b { font-weight: 500; color: var(--encre-2); text-transform: uppercase; letter-spacing: .1em; font-size: 11px; }
.piece-specs span { text-align: right; }

/* ---------- la bande de matière, déchirée en bas ----------------------- */

/* Masque à deux couches : la première est un aplat opaque qui couvre tout sauf
   les 90 derniers pixels, la seconde porte la déchirure. `mask-composite: add`
   les additionne. C'est plus fiable que d'étirer un seul masque sur toute la
   hauteur, où la déchirure atterrirait au milieu de l'image. */
.bande {
  position: relative;
  height: clamp(240px, 42vw, 460px);
  mask-size: 100% calc(100% - 89px), 100% 90px;
  mask-position: top, bottom;
  mask-repeat: no-repeat, no-repeat;
  mask-composite: add;
}
.bande img { width: 100%; height: 100%; object-fit: cover; }

.bande-mot {
  position: absolute; left: var(--marge); bottom: 96px;
  font-family: Anton, 'Arial Narrow', Impact, sans-serif;
  font-size: clamp(40px, 9vw, 150px);
  text-transform: uppercase; line-height: .82;
  color: var(--craie);
  margin: 0;
  text-shadow: 0 2px 20px rgba(0, 0, 0, .35);
}

/* ---------- l'essayage : la colonne collante -------------------------- */

.essayage { display: grid; grid-template-columns: 1fr; gap: clamp(30px, 4vw, 60px); }
@media (min-width: 900px) {
  .essayage { grid-template-columns: 1fr 1fr; align-items: start; }
  .essayage-vue { position: sticky; top: 96px; }
}
.essayage-vue img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }

.etapes { list-style: none; margin: 0; padding: 0; counter-reset: e; }
.etapes li { padding: 26px 0; border-bottom: var(--filet); }
.etapes li:first-child { padding-top: 0; }
.etapes h3 {
  font-family: Anton, 'Arial Narrow', Impact, sans-serif;
  font-size: clamp(22px, 3vw, 34px); text-transform: uppercase;
  margin: 0 0 10px; line-height: .95;
}
.etapes h3::before {
  counter-increment: e; content: counter(e, decimal-leading-zero);
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 12px; letter-spacing: .14em; color: var(--rose-vif);
  display: block; margin-bottom: 8px;
}
.etapes p { margin: 0; font-size: 14px; }

/* ---------- les prix --------------------------------------------------- */

.prix-liste { list-style: none; margin: 0 0 20px; padding: 0; }
.prix-liste li {
  display: flex; align-items: baseline; gap: 12px;
  padding: 13px 0; border-bottom: var(--filet);
}
.prix-liste dfn { font-style: normal; font-weight: 500; text-transform: uppercase; letter-spacing: .06em; }
.prix-liste .filet { flex: 1; border-bottom: 1px dotted rgba(14, 13, 16, .35); transform: translateY(-4px); }
.prix-liste .montant { font-variant-numeric: tabular-nums; white-space: nowrap; }

.avertissement {
  border-left: 3px solid var(--rose-vif);
  padding: 12px 0 12px 16px;
  font-size: 13px; color: var(--encre-2); max-width: 56ch;
}

/* ---------- pied de page ----------------------------------------------- */

.pied { background: var(--encre); color: var(--rose); padding: clamp(56px, 8vw, 110px) var(--marge) 30px; }
.pied a { color: var(--rose); }
.pied a:hover { color: var(--rose-vif); }
.pied :focus-visible { outline-color: var(--rose); }

.pied-titre { font-size: clamp(40px, 9vw, 140px); margin-bottom: 26px; }
.pied-titre .point { color: var(--rose-vif); }

.pied-cta {
  display: inline-block; text-decoration: none;
  background: var(--rose-vif); color: var(--craie);
  padding: 15px 30px; text-transform: uppercase; letter-spacing: .1em; font-size: 13px;
  transition: transform .3s var(--volet);
}
.pied-cta:hover { transform: translateY(-3px); color: var(--craie); }

.pied-grille {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 32px; margin-top: clamp(44px, 7vw, 90px);
  padding-top: 30px; border-top: 1px solid rgba(249, 220, 228, .22);
}
.pied-grille h3 { font-size: 11px; text-transform: uppercase; letter-spacing: .14em; margin: 0 0 12px; color: var(--rose-vif); }
.pied-grille ul { list-style: none; margin: 0; padding: 0; }
.pied-grille li { margin-bottom: 7px; }
.pied-grille a { text-decoration: none; }
.pied-grille p { font-size: 13px; margin: 0 0 7px; max-width: 34ch; }

.pied-bas {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  margin-top: 40px; padding-top: 18px;
  border-top: 1px solid rgba(249, 220, 228, .22);
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(249, 220, 228, .62);
}

/* ---------- le volet ---------------------------------------------------
   Le seul mécanisme d'apparition du site. Il n'est armé que si le JS a posé
   la classe `js` sur <html> : sans JS, tout est visible d'emblée, ce qui est
   la règle qui a coûté le plus cher au catalogue (un reveal qui ne se
   déclenche jamais laisse la page vide pour toujours).
   Le héros n'est JAMAIS armé : son image doit être peinte au premier rendu. */

.js [data-volet] {
  transform: scaleY(0);
  transform-origin: 50% 100%;
  will-change: transform;
}
.js [data-volet].ouvert {
  transform: scaleY(1);
  transition: transform .7s var(--volet);
}
.js [data-volet][data-retard="1"].ouvert { transition-delay: .08s; }
.js [data-volet][data-retard="2"].ouvert { transition-delay: .16s; }
.js [data-volet][data-retard="3"].ouvert { transition-delay: .24s; }

/* ---------- le curseur ------------------------------------------------- */

.curseur {
  position: fixed; top: 0; left: 0; z-index: 60;
  width: 92px; height: 92px; border-radius: 50%;
  background: var(--rose-vif); color: var(--craie);
  display: grid; place-items: center;
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  pointer-events: none; opacity: 0;
  transform: translate(-50%, -50%) scale(.4);
  transition: opacity .18s var(--volet), transform .18s var(--volet);
}
.curseur.visible { opacity: 1; transform: translate(-50%, -50%) scale(1); }
@media (hover: none), (max-width: 900px) { .curseur { display: none; } }

/* ---------- réglages d'accessibilité ----------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .bandeau-piste { animation: none; }
  body.arrive .heros-haut,
  body.arrive .heros-titre,
  body.arrive .heros-def,
  body.arrive .decoupe { animation: none; }
  .js [data-volet] { transform: none; }
  .js [data-volet].ouvert { transition: none; }
  .piece-vue img { transition: none; }
  .curseur { display: none; }
}
