/* ============================================================
   ATELIER FABLE — Feuille de style du site vitrine
   Ton : artisanal, haut de gamme, chaleureux, sobre.
   Palette : ivoire, brun profond, laiton doré.
   ============================================================ */

:root {
  --ivoire: #faf6ef;
  --creme: #f3ecdf;
  --brun: #2e2620;
  --brun-doux: #5c5046;
  --or: #b08d57;
  --or-clair: #d3b787;
  --blanc: #fffdf9;
  --serif: 'Cormorant Garamond', Georgia, serif;
  --sans: 'Jost', 'Segoe UI', sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--sans);
  font-weight: 300;
  color: var(--brun);
  background: var(--ivoire);
  line-height: 1.7;
  font-size: 16.5px;
}
h1, h2, h3, .nom-marque { font-family: var(--serif); font-weight: 500; line-height: 1.2; }
h1 { font-size: clamp(2.2rem, 5vw, 3.4rem); }
h2 { font-size: clamp(1.7rem, 3.5vw, 2.4rem); margin-bottom: .8rem; }
a { color: var(--or); text-decoration: none; transition: color .2s; }
a:hover { color: var(--brun); }
img { max-width: 100%; display: block; }
.conteneur { max-width: 1180px; margin: 0 auto; padding: 0 1.4rem; }

/* ---------- En-tête ---------- */
.entete-site {
  background: var(--ivoire);
  border-bottom: 1px solid rgba(176,141,87,.25);
  position: sticky; top: 0; z-index: 50;
}
.entete-interieur { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.4rem; gap: 1rem; }
.marque { display: flex; align-items: center; gap: 1.1rem; line-height: 1.15; flex-shrink: 0; }
.marque-texte { display: flex; flex-direction: column; }
.nom-marque { white-space: nowrap; }
/* Le logo occupe toute la hauteur du bandeau (texte ≈ 58px + 2 × 1rem de
   padding) : les marges négatives le font déborder dans le padding vertical. */
.logo { height: 86px; margin: -1rem 0; width: auto; object-fit: contain; }
.nom-marque { font-size: 1.7rem; color: var(--brun); letter-spacing: .04em; }
.slogan { font-size: .62rem; text-transform: uppercase; letter-spacing: .2em; color: var(--or); }
.nav-site { display: flex; gap: .5rem 1.05rem; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.nav-site a {
  color: var(--brun); font-size: .8rem; text-transform: uppercase;
  letter-spacing: .14em; padding-bottom: .2rem; border-bottom: 1px solid transparent;
}
.nav-site a:hover { border-color: var(--or); color: var(--or); }
.nav-contact { border: 1px solid var(--or) !important; padding: .45rem 1.1rem !important; }
.nav-contact:hover { background: var(--or); color: var(--blanc) !important; }
.langues { font-size: .78rem; color: var(--brun-doux); }
.langues .actif { color: var(--brun); font-weight: 500; }
.burger { display: none; background: none; border: none; font-size: 1.6rem; color: var(--brun); cursor: pointer; }

/* ---------- Héros ---------- */
.heros {
  background: linear-gradient(rgba(46,38,32,.55), rgba(46,38,32,.55)),
              radial-gradient(ellipse at 30% 20%, #6b5a48, #2e2620 75%);
  color: var(--ivoire);
  text-align: center;
  padding: clamp(5rem, 14vw, 9rem) 1.4rem;
}
.heros .filet { width: 70px; height: 1px; background: var(--or-clair); margin: 1.4rem auto; }
.heros p { max-width: 580px; margin: 0 auto 2rem; font-size: 1.1rem; color: var(--creme); }
.heros h1 em { font-style: italic; color: var(--or-clair); }

/* ---------- Héros ciné piloté par le défilement (scroll-scrub vidéo) ---------- */
/* Reset Lenis : neutralise le scroll-behavior natif quand le smooth scroll est actif */
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

.hero-scrub { position: relative; width: 100%; height: 500vh; }
.hero-scrub__sticky {
  position: sticky; top: 0; height: 100vh; width: 100%;
  overflow: hidden; background: var(--brun);
}
.hero-scrub__video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 1;
}
/* Voile dégradé pour la lisibilité du texte par-dessus la vidéo.
   Deux couches : un dégradé haut/bas + une ombre centrale qui pose le bloc de
   texte sur un fond calme quelle que soit l'image de la vidéo. */
.hero-scrub__scrim {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background:
    radial-gradient(ellipse 70% 55% at 50% 50%, rgba(24,19,15,.62), rgba(24,19,15,0) 70%),
    linear-gradient(rgba(46,38,32,.68), rgba(46,38,32,.42) 45%, rgba(46,38,32,.82));
}
.hero-scrub__overlay {
  position: absolute; inset: 0; z-index: 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 0 1.4rem; color: var(--ivoire); will-change: opacity;
}
.hero-scrub__overlay .sur-titre {
  color: var(--or-clair);
  text-shadow: 0 1px 12px rgba(24,19,15,.8);
}
.hero-scrub__overlay h1 {
  color: var(--ivoire); max-width: 18ch;
  text-shadow: 0 2px 26px rgba(24,19,15,.72), 0 1px 3px rgba(24,19,15,.5);
}
/* Le membre en italique reçoit un léger dégradé laiton, comme un reflet sur le métal.
   Sous @supports : sans découpe du fond sur le texte, on garde l'or plein. */
.hero-scrub__overlay h1 em { font-style: italic; color: var(--or-clair); }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-scrub__overlay h1 em {
    background: linear-gradient(100deg, var(--or) 10%, #f0dcb4 45%, var(--or-clair) 80%);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
    /* l'ombre du h1 traverserait le texte évidé : on la remplace par une ombre portée */
    text-shadow: none;
    filter: drop-shadow(0 2px 18px rgba(24,19,15,.7));
  }
}
.hero-scrub__overlay .filet {
  width: 70px; height: 1px; margin: 1.4rem auto;
  background: linear-gradient(90deg, transparent, var(--or-clair), transparent);
}
.hero-scrub__overlay p {
  max-width: 560px; margin: 0 auto 2rem; font-size: 1.1rem; color: var(--creme);
  text-shadow: 0 1px 16px rgba(24,19,15,.8);
}
.hero-scrub__overlay .btn {
  color: var(--or-clair); border-color: rgba(211,183,135,.75);
  background: rgba(24,19,15,.28);
  backdrop-filter: blur(2px);
  text-shadow: 0 1px 10px rgba(24,19,15,.6);
}
.hero-scrub__overlay .btn:hover {
  background: var(--or-clair); color: var(--brun); border-color: var(--or-clair);
  text-shadow: none; box-shadow: 0 6px 28px rgba(211,183,135,.28);
}
/* Entrée du texte au chargement : montée discrète, décalée d'un élément à l'autre */
.hero-scrub__overlay > * {
  animation: heroScrubEntree 1.1s cubic-bezier(.22, .61, .36, 1) both;
}
.hero-scrub__overlay > *:nth-child(1) { animation-delay: .15s; }
.hero-scrub__overlay > *:nth-child(2) { animation-delay: .3s; }
.hero-scrub__overlay > *:nth-child(3) { animation-delay: .5s; }
.hero-scrub__overlay > *:nth-child(4) { animation-delay: .62s; }
.hero-scrub__overlay > *:nth-child(5) { animation-delay: .78s; }
@keyframes heroScrubEntree {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-scrub__overlay > * { animation: none; }
}
/* Indication « défilez pour explorer » */
.hero-scrub__hint {
  position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%);
  z-index: 3; color: var(--ivoire); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .28em; display: flex; flex-direction: column; align-items: center; gap: .7rem;
  will-change: opacity;
}
.hero-scrub__hint::after {
  content: ""; width: 1px; height: 42px;
  background: linear-gradient(var(--or-clair), transparent);
  animation: heroScrubHint 1.8s ease-in-out infinite;
}
@keyframes heroScrubHint {
  0%, 100% { opacity: .3; transform: scaleY(.6); transform-origin: top; }
  50%      { opacity: 1;  transform: scaleY(1);  transform-origin: top; }
}
/* Écran de chargement léger jusqu'à la première image, puis fondu */
.hero-scrub__loading {
  position: absolute; inset: 0; z-index: 4;
  display: flex; align-items: center; justify-content: center;
  background: var(--brun); color: var(--or-clair);
  font-size: .78rem; letter-spacing: .26em; text-transform: uppercase;
  transition: opacity .6s ease;
}
.hero-scrub__loading.is-hidden { opacity: 0; pointer-events: none; }
/* prefers-reduced-motion : image fixe sur une seule fenêtre, pas de scrubbing */
.hero-scrub--static { height: 100vh; }
.hero-scrub--static .hero-scrub__sticky { position: relative; }
.hero-scrub--static .hero-scrub__hint { display: none; }
@media (max-width: 768px) { .hero-scrub__overlay p { font-size: 1rem; } }

/* ---------- Boutons ---------- */
.btn {
  display: inline-block; padding: .8rem 2.2rem;
  font-size: .82rem; text-transform: uppercase; letter-spacing: .18em;
  border: 1px solid var(--or); color: var(--or); background: transparent;
  cursor: pointer; transition: all .25s; font-family: var(--sans);
}
.btn:hover { background: var(--or); color: var(--blanc); }
.btn-plein { background: var(--or); color: var(--blanc); }
.btn-plein:hover { background: var(--brun); border-color: var(--brun); }

/* ---------- Sections ---------- */
.section { padding: clamp(3.5rem, 8vw, 6rem) 0; }
.section-creme { background: var(--creme); }
.section-sombre { background: var(--brun); color: var(--ivoire); }
.section-sombre h2 { color: var(--or-clair); }
.sur-titre {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .3em;
  color: var(--or); display: block; margin-bottom: .6rem;
}
.entete-section { text-align: center; max-width: 640px; margin: 0 auto 3rem; }

/* Chapô : une ligne en serif italique sous le titre, qui donne le ton de la
   rubrique avant d'y entrer. Partagé par le Journal, l'Agenda et le Contact. */
.chapo {
  font-family: var(--serif); font-style: italic;
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  color: var(--brun-doux); max-width: 46ch; margin: .9rem auto 0;
}

/* ---------- Filet à losange ----------
   La ponctuation gravée du site : le filet du héros refendu en deux traits qui
   s'effacent vers l'extérieur, avec un losange au centre. Il ferme les en-têtes
   de rubrique et sépare les blocs des cartons. */
.filet-losange {
  display: flex; align-items: center; justify-content: center;
  gap: .8rem; margin-top: 1.5rem;
}
.filet-losange::before, .filet-losange::after {
  content: ""; height: 1px; width: 56px;
  background: linear-gradient(90deg, transparent, rgba(176,141,87,.55));
}
.filet-losange::after { background: linear-gradient(90deg, rgba(176,141,87,.55), transparent); }
.filet-losange__losange {
  width: 5px; height: 5px; flex: none;
  border: 1px solid var(--or); transform: rotate(45deg);
}
/* Version courte, pour l'intérieur d'un carton. */
.filet-losange--court::before, .filet-losange--court::after { width: 32px; }

/* ---------- Fond de rubrique ----------
   Halo ton sur ton derrière l'en-tête + grain de papier. Le grain est un
   feTurbulence en data-URI : aucune requête, aucun fichier, et son opacité le
   place au seuil du perceptible — on le devine, on ne le voit pas.
   Le modificateur --creme pose la rubrique sur le crème plutôt que l'ivoire. */
.fond-atelier { position: relative; overflow: hidden; }
.fond-atelier::before {
  content: "";
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 75% 55% at 50% 30%, rgba(255,253,249,.9), transparent 72%);
}
.fond-atelier::after {
  content: "";
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  opacity: .025; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");
}
.fond-atelier > .conteneur { position: relative; z-index: 1; }
.fond-atelier--creme { background: var(--creme); }
.fond-atelier--creme::before {
  background: radial-gradient(ellipse 70% 60% at 50% 45%, rgba(250,246,239,.75), transparent 70%);
}
.fond-atelier--creme::after { opacity: .03; }

/* ---------- Grille produits ---------- */
/* Les cartes épousent la hauteur de leur photo : `start` évite que la grille
   les étire toutes à la hauteur de la plus haute de la rangée. */
/* `position: relative` fait de la grille le repère (offsetParent) des cartes :
   js/pieces-pile.js mesure leurs offsetLeft/offsetTop pour bâtir le paquet. */
.grille-pieces { position: relative; display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 2.2rem; align-items: start; }
.carte-piece {
  position: relative; overflow: hidden;
  background: var(--blanc); box-shadow: 0 1px 0 rgba(46,38,32,.08);
  transition: translate .25s, box-shadow .25s;
}
/* Le soulèvement passe par `translate` et non `transform` : sur l'accueil, GSAP
   écrit `transform` en style inline pour l'empilement, ce qui écraserait le survol.
   Les deux propriétés se composent au lieu de se disputer la même déclaration. */
.carte-piece:hover { translate: 0 -4px; box-shadow: 0 14px 34px rgba(46,38,32,.14); }
.carte-piece__lien { display: block; position: relative; }
.carte-piece .visuel { overflow: hidden; background: var(--creme); }
/* Pas d'aspect-ratio imposé : la photo donne son format à la carte, sans recadrage. */
.carte-piece .visuel img { width: 100%; height: auto; display: block; transition: transform .5s; }
.carte-piece:hover .visuel img { transform: scale(1.04); }
/* Seules les pièces sans photo ont besoin d'un cadre : on retombe sur l'initiale. */
.carte-piece .visuel--sans-photo {
  aspect-ratio: 3/2;
  display: flex; align-items: center; justify-content: center;
  color: var(--or); font-family: var(--serif); font-size: 3.2rem; font-style: italic;
}

/* Bandeau ivoire qui glisse depuis le bas de la photo au survol */
.carte-piece__voile {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: .75rem 1.1rem .8rem;
  background: rgba(250,246,239,.92);   /* --ivoire */
  border-top: 1px solid var(--or);
  /* Deux colonnes : nature à gauche, prix à droite, alignés sur la même ligne. */
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  /* Interligne resserré : les photos sont en paysage, donc les cartes sont
     basses — le bandeau doit rester une bande, pas recouvrir la pièce. */
  line-height: 1.3;
  transform: translateY(100%);
  transition: transform .35s ease;
}
.carte-piece__nature { min-width: 0; }   /* autorise la troncature plutôt que de pousser le prix */
.carte-piece:hover .carte-piece__voile,
.carte-piece__lien:focus-visible .carte-piece__voile,
.carte-piece.carte-piece--revelee .carte-piece__voile { transform: translateY(0); }
.carte-piece__categorie {
  font-size: .9rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--brun); margin: 0;
}
.carte-piece__matiere {
  font-size: .88rem; color: var(--brun-doux); margin: .15rem 0 0;
}
/* Le prix ne doit jamais passer à la ligne ni se faire écraser par une longue matière. */
.carte-piece__prix {
  font-size: 1.3rem; font-family: var(--serif); color: var(--or);
  margin: 0; white-space: nowrap; flex-shrink: 0;
}

@media (prefers-reduced-motion: reduce) {
  .carte-piece__voile { transition: none; }
}

/* ---------- Catalogue : grille pleine largeur ----------
   La grille s'échappe du conteneur (max 1180px) pour occuper toute la largeur
   de l'écran : le nombre de colonnes suit alors la place disponible (auto-fill),
   au lieu de rester bloqué à ~3 colonnes. Les marges négatives tirent les bords
   jusqu'au viewport, le padding rétablit une gouttière sur les côtés. */
.grille-pieces--compacte {
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 1.5rem;
  width: auto;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding: 0 clamp(1.4rem, 4vw, 3.5rem);
}

/* Cartes de taille uniforme : dans le catalogue on impose un ratio fixe au
   visuel (au lieu de laisser chaque photo donner sa hauteur). Les images
   verticales, sinon deux fois plus hautes, sont recadrées au centre en `cover`
   pour remplir le même cadre paysage que les autres. Le bandeau __voile étant
   en position absolue, la carte fait exactement la hauteur du visuel. */
.grille-pieces--compacte .visuel { aspect-ratio: 3 / 2; }
.grille-pieces--compacte .visuel img { height: 100%; object-fit: cover; }

/* Accueil « Disponibles à l'atelier » : même format uniforme qu'au catalogue.
   Sans ratio fixe, les photos verticales rendaient les cartes deux fois plus
   hautes et l'empilement dépareillé. Recadrage centré en `cover`. */
#piecesPile .visuel { aspect-ratio: 3 / 2; }
#piecesPile .visuel img { height: 100%; object-fit: cover; }

/* ---------- Pagination ---------- */
.pagination { display: flex; flex-wrap: wrap; justify-content: center; gap: .4rem; margin-top: 3rem; }
.pagination-lien {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.2rem; padding: .4rem .7rem; font-size: .9rem;
  color: var(--brun); background: var(--blanc); border: 1px solid rgba(46,38,32,.14);
  transition: background .2s, color .2s, border-color .2s;
}
.pagination-lien:hover { border-color: var(--or); color: var(--or); }
.pagination-lien.actif { background: var(--or); color: var(--blanc); border-color: var(--or); }

.etiquette {
  display: inline-block; font-size: .68rem; text-transform: uppercase;
  letter-spacing: .14em; padding: .22rem .65rem; margin-bottom: .5rem;
}
.etiquette-disponible { background: #e8efe3; color: #4a6741; }
.etiquette-vendu { background: #efe3e3; color: #8a4b4b; }
.etiquette-reserve { background: #f0ead9; color: #8a6d2f; }
.etiquette-en_creation { background: #e5e8ef; color: #44557e; }
.etiquette-unique { background: var(--brun); color: var(--or-clair); }

/* ---------- Filtres catalogue ---------- */
.filtres { display: flex; flex-wrap: wrap; gap: .8rem; margin-bottom: 2.5rem; align-items: center; }
.filtres select {
  padding: .55rem .9rem; border: 1px solid rgba(176,141,87,.4);
  background: var(--blanc); color: var(--brun); font-family: var(--sans); font-size: .88rem;
}

/* ---------- Bascule de vue (cartes / galerie 3D) ---------- */
/* Le [hidden] doit primer sur .grille-pieces { display: grid } */
[data-vue-panneau][hidden] { display: none !important; }
.bascule-vue {
  display: inline-flex; gap: .3rem; margin-bottom: 2rem;
  padding: .3rem; border: 1px solid rgba(176,141,87,.4); background: var(--blanc);
}
.bascule-vue__btn {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .5rem 1.1rem; border: 0; background: transparent; cursor: pointer;
  color: var(--brun-doux); font-family: var(--sans); font-size: .82rem;
  text-transform: uppercase; letter-spacing: .12em;
  transition: background .2s, color .2s;
}
.bascule-vue__btn:hover { color: var(--or); }
.bascule-vue__btn.actif { background: var(--or); color: var(--blanc); }
.bascule-vue__icone { font-size: 1rem; line-height: 1; }

/* ---------- Placeholder galerie 3D ---------- */
.galerie-3d__a-venir {
  text-align: center; padding: 4.5rem 1.5rem;
  border: 1px dashed rgba(176,141,87,.5); background: var(--creme);
}
.galerie-3d__icone { font-size: 3rem; color: var(--or); display: block; margin-bottom: 1rem; }
.galerie-3d__a-venir h2 { color: var(--brun); margin-bottom: .6rem; }
.galerie-3d__a-venir p { max-width: 34rem; margin: 0 auto; color: var(--brun-doux); }

/* ---------- Galerie 3D — moteur d'anneau (orbit transform-origin) ---------- */
/* Scène fixe sous l'en-tête du site (z-index 50). Fond ivoire = physionomie du site. */
.g3d-scene { position: fixed; inset: 0; overflow: hidden; perspective: 1600px; perspective-origin: 50% 50%; background: var(--ivoire); z-index: 40; }
.g3d-gallery { position: absolute; top: 50%; left: 50%; width: 0; height: 0; transform-style: preserve-3d; will-change: transform; }

/* CARTE = hitbox stable. IMPORTANT : PAS de backface-visibility:hidden (sinon demi-anneau / "C"). */
.g3d-item { position: absolute; top: 0; left: 0; width: 78px; height: 60px; transform-style: preserve-3d; }
.g3d-item-card { position: absolute; inset: 0; transform-style: preserve-3d; pointer-events: none;
  border: 1px solid rgba(255,255,255,0.65); transition: box-shadow .4s ease; }
.g3d-item-card img { width: 100%; height: 100%; object-fit: cover; display: block; filter: saturate(0.95) brightness(0.99); }
.g3d-item-card.is-active { box-shadow: 0 6px 16px -10px rgba(0,0,0,0.4); }

.g3d-center { position: absolute; top: 43%; left: 50%; transform: translate(-50%,-50%); width: min(520px,42vw);
  text-align: center; pointer-events: none; z-index: 5; }
.g3d-eyebrow { font-family: var(--sans); font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--brun-doux); margin-bottom: 1.4em; }
.g3d-title { font-family: var(--serif); font-size: clamp(34px,4.4vw,60px); font-weight: 500; line-height: 1.02; letter-spacing: -0.01em; color: var(--brun); }
.g3d-title em { font-style: italic; font-weight: 400; color: var(--or); }
.g3d-sub { margin-top: 1.3em; font-size: 14px; color: var(--brun-doux); }
.g3d-center-default, .g3d-center-project { transition: opacity .55s ease; }
.g3d-center-project { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; opacity: 0; }
.g3d-center.show-project .g3d-center-default { opacity: 0; }
.g3d-center.show-project .g3d-center-project { opacity: 1; }
.g3d-preview-img { width: 380px; height: 210px; max-width: 42vw; flex-shrink: 0; overflow: hidden; background: var(--creme); }
.g3d-preview-img img { width: 100%; height: 100%; object-fit: cover; }
.g3d-preview-cat { margin-top: 1.1em; font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--brun-doux); }
.g3d-preview-title { margin-top: 0.4em; font-family: var(--serif); font-size: clamp(20px,2vw,26px); font-weight: 500; color: var(--brun); }
.g3d-preview-ref { margin-top: 0.5em; font-size: 12px; letter-spacing: 0.08em; color: var(--brun-doux); min-height: 1em; }
.g3d-preview-view { display: inline-block; margin-top: 1.1em; font-size: 13px; font-weight: 600; letter-spacing: 0.04em;
  border-bottom: 1px solid var(--brun); padding-bottom: 2px; color: var(--brun); opacity: 0;
  transition: opacity .4s ease, color .25s ease; }
.g3d-preview-view i { font-style: normal; margin-left: 0.35em; }
/* Photo verrouillée au centre : cliquable pour ouvrir la fiche (achat), comme la vue carte */
.g3d-center.is-locked .g3d-preview-img { pointer-events: auto; cursor: pointer; }
.g3d-center.is-locked .g3d-preview-img img { transition: transform .5s ease; }
.g3d-center.is-locked .g3d-preview-img:hover img { transform: scale(1.03); }
.g3d-center.is-locked .g3d-preview-view { opacity: 1; pointer-events: auto; cursor: pointer; }
.g3d-center.is-locked .g3d-preview-view:hover { color: var(--or); }

.g3d-labels { position: absolute; top: 50%; right: 2.4em; left: auto; bottom: auto;
  transform: translateY(-50%); display: flex; flex-direction: column; align-items: flex-end;
  gap: 0.55em; pointer-events: none; z-index: 6; }
.g3d-label { position: static; transform: none; white-space: nowrap; font-family: var(--sans);
  font-size: 14px; font-weight: 500; pointer-events: auto; cursor: pointer; opacity: 0.85; color: var(--brun);
  text-align: right; transition: opacity .25s ease, color .25s ease; }
.g3d-label:hover { opacity: 1; color: var(--or); }
.g3d-label.is-active { opacity: 1; color: var(--or); font-weight: 600; }
.g3d-label--reset { margin-bottom: 0.5em; padding-bottom: 0.55em; border-bottom: 1px solid rgba(0,0,0,0.12);
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; }
.g3d-label .ul { border-bottom: 1px solid var(--brun); padding-bottom: 2px; transition: border-color .25s ease; }
.g3d-label:hover .ul, .g3d-label.is-active .ul { border-bottom-color: var(--or); }
.g3d-label sup { font-size: 10px; color: var(--brun-doux); margin-left: 3px; }

.g3d-loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: var(--ivoire); z-index: 8; transition: opacity .5s ease; }
.g3d-loading.is-hidden { opacity: 0; pointer-events: none; }
.g3d-loading span { font-family: var(--sans); font-size: 11px; letter-spacing: 0.26em; text-transform: uppercase; color: var(--brun-doux); }

/* Toggle flottant en bas de l'écran quand la 3D est active */
body.galerie3d-active .bascule-vue { position: fixed; top: auto; bottom: 2em; left: 50%; transform: translateX(-50%);
  z-index: 60; margin: 0; box-shadow: 0 8px 30px -16px rgba(0,0,0,0.45); }

/* Curseur point (desktop pointeur fin uniquement, actif seulement en mode 3D) */
.g3d-cursor { display: none; }
@media (pointer: fine) and (hover: hover) {
  body.galerie3d-active { cursor: none; }
  body.galerie3d-active .g3d-cursor { display: block; position: fixed; top: 0; left: 0; width: 13px; height: 13px;
    border-radius: 999px; background: var(--brun); pointer-events: none; z-index: 99999; will-change: transform; transition: opacity .3s ease; }
  body.galerie3d-active .g3d-cursor.is-hidden { opacity: 0; }
}

/* Bloc preview mobile + hitbox tactile */
.g3d-mobile-preview { display: none; }
.g3d-hitbox { display: none; }

@media (max-width: 768px) {
  .g3d-center, .g3d-labels { display: none; }
  .g3d-mobile-preview { display: block; position: fixed; top: 6.4em; left: 0; right: 0; z-index: 45; padding: 0 1em; pointer-events: none; }
  .g3d-mp-cat { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--brun-doux); margin-bottom: 5px; }
  .g3d-mp-title { font-family: var(--serif); font-size: 23px; line-height: 1.05; font-weight: 500; margin-bottom: 14px; color: var(--brun); }
  .g3d-mp-img { width: 100%; aspect-ratio: 16/10; overflow: hidden; background: var(--creme); pointer-events: auto; cursor: pointer; }
  .g3d-mp-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .g3d-mp-ref { margin-top: 8px; font-size: 11px; letter-spacing: 0.08em; color: var(--brun-doux); }
  .g3d-mp-view { display: inline-block; margin-top: 8px; font-size: 14px; font-weight: 600;
    border-bottom: 1px solid var(--brun); padding-bottom: 2px; pointer-events: auto; color: var(--brun); }
  .g3d-mp-view i { font-style: normal; margin-left: 0.35em; }
  .g3d-hitbox { display: block; position: fixed; left: 0; right: 0; bottom: 0; top: 50%; z-index: 20; touch-action: none; pointer-events: auto; }
  body.galerie3d-active .bascule-vue { top: auto; bottom: 1.1em; }
}

/* ---------- Fiche produit ---------- */
.fiche { display: grid; grid-template-columns: 1.1fr .9fr; gap: 3.5rem; align-items: start; }
.fiche-galerie img { width: 100%; margin-bottom: 1rem; }
.fiche-details h1 { margin-bottom: .4rem; }
.fiche-ref { font-size: .78rem; letter-spacing: .2em; text-transform: uppercase; color: var(--brun-doux); }
.fiche-prix { font-size: 1.7rem; font-family: var(--serif); color: var(--or); margin: 1.1rem 0; }
.fiche-specs { border-top: 1px solid rgba(176,141,87,.3); margin-top: 1.6rem; }
.fiche-specs div { display: flex; justify-content: space-between; gap: 1rem; padding: .65rem 0; border-bottom: 1px solid rgba(176,141,87,.18); font-size: .92rem; }
.fiche-specs dt { color: var(--brun-doux); text-transform: uppercase; font-size: .74rem; letter-spacing: .16em; padding-top: .15rem; }
.bloc-histoire { background: var(--creme); padding: 1.5rem 1.7rem; margin-top: 1.8rem; font-style: italic; font-family: var(--serif); font-size: 1.08rem; }
.avant-apres { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 2rem; }
.avant-apres figcaption { text-align: center; font-size: .75rem; text-transform: uppercase; letter-spacing: .2em; color: var(--brun-doux); margin-top: .5rem; }

/* ---------- Formulaires ---------- */
.formulaire-public { max-width: 620px; margin: 0 auto; display: grid; gap: 1.1rem; }
.formulaire-public label { font-size: .8rem; text-transform: uppercase; letter-spacing: .16em; color: var(--brun-doux); display: block; margin-bottom: .3rem; }
.formulaire-public input, .formulaire-public textarea, .formulaire-public select {
  width: 100%; padding: .75rem .9rem; border: 1px solid rgba(176,141,87,.45);
  background: var(--blanc); font-family: var(--sans); font-size: .95rem; color: var(--brun);
}
.formulaire-public input:focus, .formulaire-public textarea:focus { outline: none; border-color: var(--or); }
/* Choix du mode de livraison : libellé aligné avec le bouton radio */
.choix-livraison {
  display: flex; align-items: center; gap: .6rem; margin: 0;
  padding: .75rem .9rem; border: 1px solid rgba(176,141,87,.45); cursor: pointer;
  text-transform: none; letter-spacing: 0; font-size: .95rem; color: var(--brun);
}
.choix-livraison input { width: auto; padding: 0; margin: 0; }
.choix-livraison:has(input:checked) { border-color: var(--or); background: var(--creme); }
.flash { max-width: 720px; margin: 1.2rem auto; padding: .9rem 1.3rem; font-size: .92rem; }
.flash-ok { background: #e8efe3; color: #41502f; border-left: 3px solid #7a9468; }
.flash-warn, .flash-erreur { background: #f4e6df; color: #7c4a2d; border-left: 3px solid #c08552; }

/* ---------- Contact — « Écrire à l'atelier » ----------
   Le formulaire à gauche, les coordonnées de l'atelier gravées sur un carton à
   droite. Les champs perdent leur boîte à quatre bords : il ne reste qu'un
   filet, que le focus redessine de gauche à droite. */
.contact-grille {
  display: grid; grid-template-columns: 1fr 340px;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
  max-width: 1020px; margin: 0 auto;
}
/* Dans la grille, le formulaire n'a plus à se centrer lui-même. */
.contact-grille .formulaire-public { max-width: none; margin: 0; gap: clamp(1.4rem, 3vw, 1.9rem); }

/* Le type de demande : trois cartons plutôt qu'un menu déroulant. Le visiteur
   choisit ce qu'il vient chercher, et le formulaire annonce d'entrée ce que
   l'atelier sait faire. */
.contact-types { display: grid; grid-template-columns: repeat(3, 1fr); gap: .7rem; }
.contact-type {
  position: relative; display: block; margin: 0;
  text-align: center; cursor: pointer;
  padding: 1.25rem .8rem 1.15rem;
  background: var(--blanc);
  border: 1px solid rgba(176,141,87,.3);
  text-transform: none; letter-spacing: 0;
  transition: transform .55s cubic-bezier(.22,.61,.36,1),
              border-color .55s cubic-bezier(.22,.61,.36,1),
              background .55s cubic-bezier(.22,.61,.36,1),
              box-shadow .55s cubic-bezier(.22,.61,.36,1);
}
/* Le bouton radio reste dans le flux du clavier, invisible à l'œil. */
.contact-type input { position: absolute; opacity: 0; width: 0; height: 0; }
.contact-type__glyphe {
  display: block; font-size: 1.05rem; color: var(--or);
  margin-bottom: .55rem; line-height: 1;
  transition: transform .6s cubic-bezier(.22,.61,.36,1);
}
.contact-type__nom {
  display: block; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .18em; color: var(--brun);
}
.contact-type__note {
  display: block; margin-top: .4rem;
  font-family: var(--serif); font-style: italic;
  font-size: .88rem; line-height: 1.35; color: var(--brun-doux);
}
.contact-type:hover { transform: translateY(-3px); border-color: rgba(176,141,87,.6); }
.contact-type:hover .contact-type__glyphe { transform: rotate(45deg); }
.contact-type:has(input:checked) {
  background: var(--creme); border-color: var(--or);
  box-shadow: 0 14px 34px -20px rgba(46,38,32,.22);
}
.contact-type:has(input:focus-visible) { outline: 2px solid var(--or); outline-offset: 3px; }

/* Champs à filet : le libellé est posé dans le champ et monte en petites
   capitales dorées à la saisie. Le placeholder d'une espace insécable est ce
   qui rend :not(:placeholder-shown) utilisable — il ne s'affiche jamais. */
.contact-grille .champ { position: relative; }
.contact-grille .champ input,
.contact-grille .champ textarea,
.contact-grille .champ select {
  width: 100%; border: 0; border-radius: 0;
  border-bottom: 1px solid rgba(176,141,87,.35);
  background: transparent;
  padding: 1.4rem 0 .5rem;
  font-family: var(--sans); font-weight: 300; font-size: 1rem; color: var(--brun);
}
.contact-grille .champ textarea { resize: vertical; }
.contact-grille .champ input:focus,
.contact-grille .champ textarea:focus,
.contact-grille .champ select:focus { outline: none; border-bottom-color: rgba(176,141,87,.35); }
.contact-grille .champ__label {
  position: absolute; left: 0; top: 1.35rem; margin: 0;
  pointer-events: none;
  font-size: .98rem; font-weight: 300;
  text-transform: none; letter-spacing: 0; color: var(--brun-doux);
  transition: top .5s cubic-bezier(.22,.61,.36,1),
              font-size .5s cubic-bezier(.22,.61,.36,1),
              letter-spacing .5s cubic-bezier(.22,.61,.36,1),
              color .5s cubic-bezier(.22,.61,.36,1);
}
.contact-grille .champ input:focus ~ .champ__label,
.contact-grille .champ input:not(:placeholder-shown) ~ .champ__label,
.contact-grille .champ textarea:focus ~ .champ__label,
.contact-grille .champ textarea:not(:placeholder-shown) ~ .champ__label {
  top: 0; font-size: .66rem; text-transform: uppercase; letter-spacing: .2em; color: var(--or);
}
.champ__filet {
  position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--or);
  transform: scaleX(0); transform-origin: left;
  transition: transform .6s cubic-bezier(.22,.61,.36,1);
}
.contact-grille .champ input:focus ~ .champ__filet,
.contact-grille .champ textarea:focus ~ .champ__filet { transform: scaleX(1); }
.champ__requis { color: var(--or); }

/* Le bouton « cacheter » : remplissage doré qui monte du bas (comme .rdv-cta)
   et disque de cire qui tourne à gauche du libellé. */
.btn-cachet {
  position: relative; overflow: hidden; isolation: isolate;
  display: inline-flex; align-items: center; gap: .85rem;
  justify-self: start; margin-top: .6rem;
  transition: color .55s cubic-bezier(.22,.61,.36,1),
              letter-spacing .55s cubic-bezier(.22,.61,.36,1),
              border-color .55s cubic-bezier(.22,.61,.36,1);
}
.btn-cachet::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--or);
  transform: scaleY(0); transform-origin: bottom;
  transition: transform .55s cubic-bezier(.22,.61,.36,1);
}
.btn-cachet:hover, .btn-cachet:focus-visible {
  background: transparent;   /* neutralise le remplissage instantané de .btn */
  color: var(--blanc); border-color: var(--or);
  letter-spacing: .22em;     /* .18em au repos : le mot s'ouvre en s'éclairant */
}
.btn-cachet:hover::before, .btn-cachet:focus-visible::before { transform: scaleY(1); }
.btn-cachet__sceau {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; flex: none;
  border: 1px solid currentColor; border-radius: 50%;
  font-size: .62rem; letter-spacing: 0;
  transition: transform .7s cubic-bezier(.22,.61,.36,1);
}
.btn-cachet:hover .btn-cachet__sceau { transform: rotate(180deg); }

/* La carte de visite : le carton gravé du site, appliqué aux coordonnées de
   l'atelier. Elle reste dans le champ pendant que l'on remplit le formulaire. */
.carte-visite {
  position: sticky; top: 6.5rem;
  background: var(--ivoire);
  border: 1px solid rgba(176,141,87,.3);
  padding: clamp(1.8rem, 4vw, 2.4rem) clamp(1.4rem, 3vw, 1.9rem);
  box-shadow: 0 18px 50px -24px rgba(46,38,32,.16);
  text-align: center;
}
/* `position: sticky` fait déjà de la carte un élément positionné : le second
   liseré s'y accroche sans repère supplémentaire. */
.carte-visite::before {
  content: ""; position: absolute; inset: 8px; pointer-events: none;
  border: 1px solid rgba(176,141,87,.16);
}
.carte-visite__nom { font-size: 1.5rem; margin-top: .2rem; }
.carte-visite .filet-losange { margin-top: 1rem; }
.carte-visite__lignes { margin-top: 1.9rem; text-align: left; }
.carte-visite__lignes > div { padding: .85rem 0; border-bottom: 1px solid rgba(176,141,87,.16); }
.carte-visite__lignes > div:last-child { border-bottom: 0; }
.carte-visite dt {
  font-size: .64rem; text-transform: uppercase; letter-spacing: .22em;
  color: var(--brun-doux); margin-bottom: .3rem;
}
.carte-visite dd { font-size: .95rem; color: var(--brun); line-height: 1.55; }
.carte-visite dd a {
  color: var(--brun);
  border-bottom: 1px solid rgba(176,141,87,.4); padding-bottom: .1rem;
  transition: color .4s, border-color .4s;
}
.carte-visite dd a:hover { color: var(--or); border-color: var(--or); }
.carte-visite__reseaux { display: flex; justify-content: center; gap: 1rem; margin-top: 1.6rem; }
.carte-visite__reseaux a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border: 1px solid rgba(176,141,87,.35); color: var(--or);
  transition: background .5s cubic-bezier(.22,.61,.36,1),
              color .5s cubic-bezier(.22,.61,.36,1),
              border-color .5s cubic-bezier(.22,.61,.36,1);
}
.carte-visite__reseaux svg { width: 1.05rem; height: 1.05rem; display: block; }
.carte-visite__reseaux a:hover { background: var(--or); border-color: var(--or); color: var(--blanc); }
.carte-visite__note {
  margin-top: 1.6rem; padding-top: 1.3rem;
  border-top: 1px solid rgba(176,141,87,.16);
  font-family: var(--serif); font-style: italic;
  font-size: 1rem; color: var(--brun-doux); line-height: 1.5;
}

/* L'accusé de réception remplace le bandeau vert : un carton gravé, centré, qui
   répond sur le même ton que le reste de la page. */
.contact-accuse {
  position: relative; max-width: 560px;
  margin: 0 auto clamp(2.4rem, 5vw, 3.6rem);
  text-align: center; background: var(--ivoire);
  border: 1px solid rgba(176,141,87,.3);
  padding: clamp(2.4rem, 5vw, 3.4rem) clamp(1.6rem, 5vw, 3rem);
  box-shadow: 0 18px 50px -24px rgba(46,38,32,.16);
}
.contact-accuse::before {
  content: ""; position: absolute; inset: 8px; pointer-events: none;
  border: 1px solid rgba(176,141,87,.16);
}
.contact-accuse__sceau {
  display: inline-flex; align-items: center; justify-content: center;
  width: 54px; height: 54px; margin-bottom: 1.2rem;
  border: 1px solid var(--or); border-radius: 50%;
  color: var(--or); font-size: 1.1rem;
}
.contact-accuse h2 { font-size: 1.7rem; margin-bottom: .4rem; }
.contact-accuse p { color: var(--brun-doux); font-family: var(--serif); font-style: italic; font-size: 1.1rem; }

/* ---------- Apparition au défilement ----------
   État de repos posé par js/contact-reveal.js. Sans JS, tout s'affiche. */
.contact-formulaire--anime > * {
  opacity: 0; transform: translateY(16px);
  transition: opacity 1.2s cubic-bezier(.22,.61,.36,1),
              transform 1.2s cubic-bezier(.22,.61,.36,1);
}
.contact-formulaire--anime.est-visible > * { opacity: 1; transform: none; }
.contact-formulaire--anime.est-visible > *:nth-child(1) { transition-delay: .05s; }
.contact-formulaire--anime.est-visible > *:nth-child(2) { transition-delay: .15s; }
.contact-formulaire--anime.est-visible > *:nth-child(3) { transition-delay: .25s; }
.contact-formulaire--anime.est-visible > *:nth-child(4) { transition-delay: .35s; }
.contact-formulaire--anime.est-visible > *:nth-child(5) { transition-delay: .45s; }
.contact-formulaire--anime.est-visible > *:nth-child(6) { transition-delay: .55s; }
.contact-formulaire--anime.est-visible > *:nth-child(7) { transition-delay: .65s; }
.contact-formulaire--anime.est-visible > *:nth-child(8) { transition-delay: .75s; }
.carte-visite--anime {
  opacity: 0; transform: translateX(26px);
  transition: opacity 1.5s cubic-bezier(.22,.61,.36,1),
              transform 1.5s cubic-bezier(.22,.61,.36,1);
}
.carte-visite--anime.est-visible { opacity: 1; transform: none; transition-delay: .25s; }

@media (max-width: 900px) {
  /* La carte de visite passe sous le formulaire : elle n'a plus de colonne où
     rester accrochée, et son apparition vient du bas comme le reste. */
  .contact-grille { grid-template-columns: 1fr; }
  .carte-visite { position: static; max-width: 480px; margin: 0 auto; }
  .carte-visite--anime { transform: translateY(20px); }
}
@media (max-width: 560px) {
  /* Les trois cartons se dépilent : le glyphe passe à gauche du libellé. */
  .contact-types { grid-template-columns: 1fr; }
  .contact-type {
    display: grid; grid-template-columns: auto 1fr; gap: .2rem .9rem;
    text-align: left; align-items: center; padding: 1rem 1.1rem;
  }
  .contact-type__glyphe { grid-row: span 2; margin: 0; font-size: 1.2rem; }
  .contact-type__note { margin-top: .15rem; }
  .btn-cachet { justify-self: stretch; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .contact-formulaire--anime > *,
  .carte-visite--anime { opacity: 1; transform: none; transition: none; }
  .contact-type, .contact-type__glyphe,
  .champ__label, .champ__filet,
  .btn-cachet, .btn-cachet::before, .btn-cachet__sceau { transition: none; }
  .contact-type:hover { transform: none; }
}

/* ---------- Journal / blog ----------
   La rubrique est un espace de lecture, pas une grille d'articles : la section
   pose un halo et un grain (.fond-atelier), l'en-tête s'ouvre sur un filet à
   losange, et chaque billet devient un carton gravé qui respire au survol.
   Toutes les valeurs restent dans les amplitudes du site : filets de 1px,
   ombres très diffuses, or discret, transitions longues. */

/* En-tête : reprend .entete-section, augmenté du chapô et du filet. */
.journal-entete { text-align: center; max-width: 640px; margin: 0 auto clamp(2.6rem, 5vw, 3.6rem); }

/* Filtres par catégorie : des étiquettes gravées, pas des onglets. Le filtrage
   se fait côté navigateur (js/journal-filtres.js), sans rechargement. */
.journal-filtres {
  display: flex; flex-wrap: wrap; gap: .55rem; justify-content: center;
  margin-bottom: clamp(2rem, 4vw, 2.8rem);
}
.journal-filtre {
  font-family: var(--sans); font-size: .68rem; font-weight: 300;
  text-transform: uppercase; letter-spacing: .2em;
  color: var(--brun-doux); background: transparent;
  border: 1px solid rgba(176,141,87,.3);
  padding: .42rem 1.05rem; cursor: pointer;
  transition: color .5s cubic-bezier(.22,.61,.36,1),
              border-color .5s cubic-bezier(.22,.61,.36,1),
              background .5s cubic-bezier(.22,.61,.36,1);
}
.journal-filtre:hover { color: var(--or); border-color: var(--or); }
.journal-filtre.actif { background: var(--or); border-color: var(--or); color: var(--blanc); }
/* Un billet écarté par un filtre se retire sans laisser de trou dans la grille. */
.carte-billet[hidden] { display: none; }

/* ---------- La une ----------
   Le billet le plus récent sort de la grille et prend la largeur : photo d'un
   côté, récit de l'autre, séparés par le filet vertical du carton d'invitation.
   La rubrique gagne une couverture de revue. */
.journal-une {
  position: relative;
  display: grid; grid-template-columns: 1.1fr 1px .9fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  background: var(--blanc);
  border: 1px solid rgba(176,141,87,.22);
  padding: clamp(1.2rem, 3vw, 1.8rem);
  margin-bottom: clamp(2.2rem, 5vw, 3.4rem);
  transition: transform .8s cubic-bezier(.22,.61,.36,1),
              box-shadow .8s cubic-bezier(.22,.61,.36,1),
              border-color .8s cubic-bezier(.22,.61,.36,1);
}
.journal-une::before {
  content: ""; position: absolute; inset: 7px; z-index: 2; pointer-events: none;
  border: 1px solid rgba(176,141,87,0);
  transition: inset .8s cubic-bezier(.22,.61,.36,1), border-color .8s cubic-bezier(.22,.61,.36,1);
}
.journal-une:hover, .journal-une:focus-within {
  transform: translateY(-5px);
  box-shadow: 0 30px 70px -30px rgba(46,38,32,.26);
  border-color: rgba(176,141,87,.4);
}
.journal-une:hover::before, .journal-une:focus-within::before { inset: 11px; border-color: rgba(176,141,87,.16); }
.journal-une__visuel { display: block; overflow: hidden; aspect-ratio: 4/3; background: var(--creme); }
.journal-une__visuel img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.6s cubic-bezier(.22,.61,.36,1);
}
.journal-une:hover .journal-une__visuel img { transform: scale(1.045); }
.journal-une__filet {
  align-self: stretch; width: 1px;
  background: linear-gradient(transparent, rgba(176,141,87,.4) 12%, rgba(176,141,87,.4) 88%, transparent);
}
.journal-une__corps { padding: clamp(.6rem, 2vw, 1.4rem) clamp(.4rem, 2vw, 1.2rem); }
/* La marque « La une » : un losange, un mot, une règle courte qui s'éloigne. */
.journal-une__marque {
  display: inline-flex; align-items: center; gap: .6rem;
  font-size: .66rem; text-transform: uppercase; letter-spacing: .26em;
  color: var(--or); margin-bottom: 1rem;
}
.journal-une__marque::before {
  content: ""; width: 5px; height: 5px; flex: none;
  border: 1px solid var(--or); transform: rotate(45deg);
}
.journal-une__marque::after {
  content: ""; height: 1px; width: 38px;
  background: linear-gradient(90deg, rgba(176,141,87,.55), transparent);
}
.journal-une time { font-size: .74rem; text-transform: uppercase; letter-spacing: .2em; color: var(--brun-doux); }
.journal-une h2, .journal-une h3 { font-size: clamp(1.7rem, 3.6vw, 2.4rem); margin: .5rem 0 .8rem; }
.journal-une h2 a, .journal-une h3 a { color: var(--brun); transition: color .5s cubic-bezier(.22,.61,.36,1); }
.journal-une:hover h2 a, .journal-une:hover h3 a { color: var(--or); }
.journal-une__extrait { color: var(--brun-doux); font-size: 1rem; }

.grille-journal { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: clamp(1.8rem, 3.5vw, 2.6rem); }

/* La grille décalée : une colonne sur deux descend, pour casser l'alignement au
   cordeau — un rangement posé à la main plutôt qu'au cordeau d'imprimeur.
   Le décalage passe par une variable car trois états écrivent la même
   propriété `transform` : le repos, le survol et l'apparition. */
.grille-journal--decalee > .carte-billet { --decal: 0px; }
@media (min-width: 641px) {
  .grille-journal--decalee > .carte-billet:nth-child(even) { --decal: 40px; }
  .grille-journal--decalee > .carte-billet { transform: translateY(var(--decal)); }
  .grille-journal--decalee > .carte-billet:hover,
  .grille-journal--decalee > .carte-billet:focus-within { transform: translateY(calc(var(--decal) - 6px)); }
  .grille-journal--decalee > .carte-billet--anime { transform: translateY(calc(var(--decal) + 22px)); }
  .grille-journal--decalee > .carte-billet--anime.est-visible { transform: translateY(var(--decal)); }
}

/* La carte : un carton posé sur l'ivoire, cerné d'un liseré, qui s'élève d'un
   rien au survol. :focus-within double chaque effet de survol — la carte réagit
   identiquement à la souris et au clavier. */
.carte-billet {
  position: relative;
  overflow: hidden;   /* borne le coin corné au ras du carton */
  background: var(--blanc);
  border: 1px solid rgba(176,141,87,.2);
  transition: transform .8s cubic-bezier(.22,.61,.36,1),
              box-shadow .8s cubic-bezier(.22,.61,.36,1),
              border-color .8s cubic-bezier(.22,.61,.36,1);
}
/* Second liseré, en retrait : la marque de cuvette d'une gravure. Invisible au
   repos (alpha 0), il ne fait qu'affleurer au survol. */
.carte-billet::before {
  content: "";
  position: absolute; inset: 7px; z-index: 2; pointer-events: none;
  border: 1px solid rgba(176,141,87,0);
  transition: inset .8s cubic-bezier(.22,.61,.36,1),
              border-color .8s cubic-bezier(.22,.61,.36,1);
}
.carte-billet:hover, .carte-billet:focus-within {
  transform: translateY(-6px);
  box-shadow: 0 26px 60px -26px rgba(46,38,32,.24);
  border-color: rgba(176,141,87,.4);
}
.carte-billet:hover::before, .carte-billet:focus-within::before {
  inset: 10px; border-color: rgba(176,141,87,.16);
}

/* Le numéro d'archive : le journal se lit comme une collection numérotée, et
   non comme un flux. Il vire à l'or au survol. */
.carte-billet__numero {
  position: absolute; top: .5rem; right: .9rem; z-index: 3;
  font-family: var(--serif); font-style: italic;
  font-size: clamp(1.6rem, 3vw, 2.2rem); line-height: 1;
  color: rgba(176,141,87,.28); pointer-events: none;
  transition: color .8s cubic-bezier(.22,.61,.36,1),
              transform .8s cubic-bezier(.22,.61,.36,1);
}
.carte-billet:hover .carte-billet__numero,
.carte-billet:focus-within .carte-billet__numero { color: var(--or); transform: translateY(-2px); }

/* Le coin corné : deux dégradés superposés dans un carré qui grandit — le pli
   du papier, sans aucun fichier image. */
.carte-billet::after {
  content: "";
  position: absolute; right: 0; bottom: 0; z-index: 3; pointer-events: none;
  width: 0; height: 0;
  background:
    linear-gradient(225deg, var(--creme) 0 50%, transparent 50%),
    linear-gradient(315deg, transparent 0 50%, rgba(46,38,32,.1) 50%);
  border-left: 1px solid rgba(176,141,87,.28);
  border-top: 1px solid rgba(176,141,87,.28);
  transition: width .7s cubic-bezier(.22,.61,.36,1), height .7s cubic-bezier(.22,.61,.36,1);
}
.carte-billet:hover::after, .carte-billet:focus-within::after { width: 28px; height: 28px; }

.carte-billet .visuel { position: relative; aspect-ratio: 16/10; background: var(--creme); overflow: hidden; }
/* Zoom lent et très court (1.045) : on doit sentir la photo respirer, pas la
   voir bouger. */
.carte-billet .visuel img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.4s cubic-bezier(.22,.61,.36,1);
}
.carte-billet:hover .visuel img, .carte-billet:focus-within .visuel img { transform: scale(1.045); }
/* Voile crème qui se lève au survol : la photo gagne un souffle de lumière. */
.carte-billet .visuel::after {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  background: rgba(243,236,223,.22);
  transition: opacity 1.1s cubic-bezier(.22,.61,.36,1);
}
.carte-billet:hover .visuel::after, .carte-billet:focus-within .visuel::after { opacity: 0; }

.carte-billet .infos { padding: 1.4rem 1.5rem 1.6rem; }
.carte-billet time { font-size: .76rem; text-transform: uppercase; letter-spacing: .2em; color: var(--or); }
/* La catégorie se range en regard de la date, séparée par un point médian :
   c'est une précision, pas une information de même rang. */
.carte-billet__categorie { font-size: .76rem; text-transform: uppercase; letter-spacing: .2em; color: var(--brun-doux); }
.carte-billet__categorie::before { content: "·"; margin: 0 .45rem; color: var(--or); }
/* Le titre est de l'encre, pas un lien doré : la hiérarchie de lecture prime, et
   l'or ne revient qu'au survol. */
.carte-billet h3 { margin: .4rem 0 .6rem; font-size: 1.45rem; }
.carte-billet h3 a { color: var(--brun); transition: color .5s cubic-bezier(.22,.61,.36,1); }
.carte-billet:hover h3 a, .carte-billet h3 a:focus-visible { color: var(--or); }
/* Extrait borné à 3 lignes : les cartes d'une même rangée gardent le même
   rythme, quelle que soit la longueur du texte. L'invite « Lire le récit » est
   un <p> du même bloc : sans :not(), ce sélecteur (plus spécifique qu'une simple
   classe) lui imposerait sa couleur et son line-clamp. */
.carte-billet .infos p:not(.carte-billet__lire) {
  color: var(--brun-doux); font-size: .95rem;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
/* Invitation à lire : la flèche avance d'un pas au survol. */
.carte-billet__lire {
  display: inline-flex; align-items: center; gap: .5rem;
  margin-top: 1.1rem;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .22em; color: var(--or);
}
.carte-billet__lire span {
  transition: transform .6s cubic-bezier(.22,.61,.36,1);
}
.carte-billet:hover .carte-billet__lire span, .carte-billet:focus-within .carte-billet__lire span { transform: translateX(5px); }
/* Lien discret vers la rubrique complète (accueil). */
.journal-tout { text-align: center; margin-top: clamp(2.2rem, 4vw, 3rem); }
.journal-tout a {
  font-size: .76rem; text-transform: uppercase; letter-spacing: .22em;
  border-bottom: 1px solid rgba(176,141,87,.4); padding-bottom: .3rem;
  transition: color .4s, border-color .4s;
}
.journal-tout a:hover { color: var(--brun); border-color: var(--brun); }

/* ---------- Apparition au défilement ----------
   État de repos posé par JS (.journal-entete--anime / .carte-billet--anime) et
   non en dur : sans JS, l'en-tête et les cartes s'affichent normalement au lieu
   de rester invisibles. */
.journal-entete--anime .sur-titre,
.journal-entete--anime h1,
.journal-entete--anime h2,
.journal-entete--anime .chapo {
  opacity: 0; transform: translateY(14px);
  transition: opacity 1.5s cubic-bezier(.22,.61,.36,1),
              transform 1.5s cubic-bezier(.22,.61,.36,1),
              letter-spacing 1.8s cubic-bezier(.22,.61,.36,1);
}
/* Micro-mouvement : la chasse du sur-titre se resserre en se posant, comme une
   ligne de titre qu'on ajuste. */
.journal-entete--anime .sur-titre { letter-spacing: .42em; }
.journal-entete--anime .filet-losange::before,
.journal-entete--anime .filet-losange::after {
  transform: scaleX(0);
  transition: transform 1.6s cubic-bezier(.22,.61,.36,1);
}
.journal-entete--anime .filet-losange::before { transform-origin: right; }
.journal-entete--anime .filet-losange::after  { transform-origin: left; }
.journal-entete--anime .filet-losange__losange {
  opacity: 0;
  transition: opacity 1.2s cubic-bezier(.22,.61,.36,1);
}
/* Le décalage raconte la lecture de l'en-tête : l'annonce, le titre, le chapô,
   puis le filet qui se referme dessous. */
.journal-entete--anime.est-visible .sur-titre,
.journal-entete--anime.est-visible h1,
.journal-entete--anime.est-visible h2,
.journal-entete--anime.est-visible .chapo { opacity: 1; transform: none; }
.journal-entete--anime.est-visible .sur-titre { letter-spacing: .3em; transition-delay: .15s; }
.journal-entete--anime.est-visible h1,
.journal-entete--anime.est-visible h2 { transition-delay: .3s; }
.journal-entete--anime.est-visible .chapo { transition-delay: .45s; }
.journal-entete--anime.est-visible .filet-losange::before,
.journal-entete--anime.est-visible .filet-losange::after { transform: scaleX(1); transition-delay: .6s; }
.journal-entete--anime.est-visible .filet-losange__losange { opacity: 1; transition-delay: .95s; }

/* La une monte d'un bloc, avant les cartons de la grille. */
.journal-une--anime {
  opacity: 0; transform: translateY(26px);
  transition: opacity 1.5s cubic-bezier(.22,.61,.36,1),
              transform 1.5s cubic-bezier(.22,.61,.36,1),
              box-shadow .8s cubic-bezier(.22,.61,.36,1),
              border-color .8s cubic-bezier(.22,.61,.36,1);
}
.journal-une--anime.est-visible { opacity: 1; transform: none; }

/* La carte monte en fondu. Le délai de cascade est posé en ligne par
   js/journal-reveal.js, puis retiré : il ne doit pas retarder le survol. */
.carte-billet--anime {
  opacity: 0; transform: translateY(22px);
  transition: opacity 1.4s cubic-bezier(.22,.61,.36,1),
              transform 1.4s cubic-bezier(.22,.61,.36,1),
              box-shadow .8s cubic-bezier(.22,.61,.36,1),
              border-color .8s cubic-bezier(.22,.61,.36,1);
}
.carte-billet--anime.est-visible { opacity: 1; transform: none; }

@media (max-width: 860px) {
  /* La une dépliée : la photo passe au-dessus du récit, le filet vertical
     redevient une règle horizontale courte. */
  .journal-une { grid-template-columns: 1fr; gap: 1.4rem; }
  .journal-une__filet {
    justify-self: center; align-self: auto;
    width: 46px; height: 1px;
    background: linear-gradient(90deg, transparent, rgba(176,141,87,.45), transparent);
  }
  .journal-une__visuel { aspect-ratio: 16/9; }
}

@media (max-width: 640px) {
  /* Une colonne : la carte n'a plus de voisine avec qui s'aligner, l'élévation
     se réduit et le filet à losange se resserre. */
  .grille-journal { grid-template-columns: 1fr; }
  .carte-billet:hover, .carte-billet:focus-within { transform: translateY(-3px); }
  .filet-losange::before, .filet-losange::after { width: 38px; }
  .carte-billet h3 { font-size: 1.3rem; }
}

@media (prefers-reduced-motion: reduce) {
  .journal-entete--anime .sur-titre,
  .journal-entete--anime h1,
  .journal-entete--anime h2,
  .journal-entete--anime .chapo,
  .journal-entete--anime .filet-losange::before,
  .journal-entete--anime .filet-losange::after,
  .journal-entete--anime .filet-losange__losange,
  .carte-billet--anime,
  .journal-une--anime {
    opacity: 1; transform: none; transition: none;
  }
  .journal-entete--anime .sur-titre { letter-spacing: .3em; }
  .carte-billet, .carte-billet::before, .carte-billet::after,
  .carte-billet__numero, .carte-billet .visuel img,
  .carte-billet .visuel::after, .carte-billet h3 a, .carte-billet__lire span,
  .journal-une, .journal-une::before, .journal-une__visuel img,
  .journal-filtre, .journal-tout a { transition: none; }
  .journal-une:hover, .journal-une:focus-within { transform: none; }
  /* Le survol garde sa lisibilité (couleur, liseré) mais perd tout mouvement. */
  .carte-billet:hover, .carte-billet:focus-within { transform: none; }
  .carte-billet:hover .visuel img, .carte-billet:focus-within .visuel img { transform: none; }
  .carte-billet:hover .carte-billet__lire span,
  .carte-billet:focus-within .carte-billet__lire span { transform: none; }
}
.contenu-billet { max-width: 760px; margin: 0 auto; font-size: 1.06rem; }
.contenu-billet::after { content: ''; display: block; clear: both; } /* clôt les images flottantes */
.contenu-billet p { margin-bottom: 1.2rem; }
/* Mise en forme produite par l'éditeur du backoffice (js/editeur.js) :
   mêmes règles que la zone d'édition pour un rendu identique des deux côtés. */
.contenu-billet h2 { font-size: 1.65rem; margin: 2rem 0 .8rem; }
.contenu-billet h3 { font-size: 1.3rem; margin: 1.6rem 0 .6rem; color: var(--brun-doux); }
.contenu-billet ul, .contenu-billet ol { margin: 0 0 1.2rem 1.5rem; }
.contenu-billet li { margin-bottom: .3rem; }
.contenu-billet blockquote {
  border-left: 3px solid var(--or); padding: .4rem 0 .4rem 1.4rem; margin: 1.6rem 0;
  font-family: var(--serif); font-size: 1.25rem; font-style: italic; color: var(--brun-doux);
}
.contenu-billet hr { border: none; border-top: 1px solid var(--or-clair); margin: 2.2rem auto; width: 50%; }
.contenu-billet a { text-decoration: underline; }
.contenu-billet .al-centre { text-align: center; }
.contenu-billet .al-droite { text-align: right; }
.contenu-billet img { margin: 1.6rem auto; }
.contenu-billet img.img-gauche { float: left; max-width: 45%; margin: .4rem 1.6rem 1rem 0; }
.contenu-billet img.img-droite { float: right; max-width: 45%; margin: .4rem 0 1rem 1.6rem; }
.contenu-billet img.img-pleine { width: 100%; }
.contenu-billet table { border-collapse: collapse; width: 100%; margin: 1.6rem 0; font-size: .98rem; }
.contenu-billet th, .contenu-billet td { border: 1px solid rgba(176,141,87,.45); padding: .55rem .8rem; text-align: left; vertical-align: top; }
.contenu-billet th { background: var(--creme); font-family: var(--serif); font-size: 1.1rem; font-weight: 500; }
.contenu-billet td p, .contenu-billet th p { margin-bottom: 0; }
@media (max-width: 640px) {
  .contenu-billet img.img-gauche, .contenu-billet img.img-droite { float: none; max-width: 100%; margin: 1.2rem auto; }
  .contenu-billet table { display: block; overflow-x: auto; }
}

/* ---------- Carte vidéo YouTube (billets) ----------
   Façade légère : miniature + bouton lecture ; js/video.js insère le lecteur au clic.
   Styles partagés avec l'aperçu de l'éditeur, voir .edt-zone .bloc-video (admin.css). */
.bloc-video {
  clear: both;
  margin: 2rem auto;
  padding: .55rem;
  background: var(--blanc);
  border: 1px solid var(--or-clair);
  border-radius: 6px;
  box-shadow: 0 2px 14px rgba(46,38,32,.06);
}
.bloc-video figcaption {
  font-family: var(--serif);
  font-size: 1.25rem;
  color: var(--brun);
  text-align: center;
  margin: .2rem 0 .6rem;
}
.bloc-video > a {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 4px;
  background: var(--brun);
}
.bloc-video > a img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  margin: 0;
  display: block;
  transition: transform .4s, filter .3s;
}
.bloc-video > a::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 68px; height: 48px;
  background: no-repeat center / contain
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 48"><path d="M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z" fill="%23212121" fill-opacity=".85"/><path d="M45 24 27 14v20z" fill="%23fff"/></svg>');
  transition: transform .25s;
  pointer-events: none;
}
.bloc-video > a:hover img { transform: scale(1.03); filter: brightness(.92); }
.bloc-video > a:hover::after {
  transform: translate(-50%, -50%) scale(1.08);
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 48"><path d="M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z" fill="%23f00"/><path d="M45 24 27 14v20z" fill="%23fff"/></svg>');
}
.bloc-video__lecteur {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 4px;
  overflow: hidden;
  background: #000;
}
.bloc-video__lecteur iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ---------- Événements — « L'agenda gravé » ----------
   Un fil doré descend la page ; chaque rendez-vous s'y accroche par un losange.
   Le premier est annoncé comme un faire-part (même grammaire que .rdv-carton
   sur l'accueil), les suivants restent des lignes d'agenda. */
.agenda {
  /* --rail : distance du fil au bord des cartons. Une seule valeur pilote le
     retrait, la position des losanges et le repli mobile. */
  --rail: clamp(2.2rem, 5vw, 3.4rem);
  position: relative;
  max-width: 880px; margin: 0 auto;
  padding-left: var(--rail);
}
/* Le fil du temps. Il s'efface à ses deux extrémités : la ligne ne commence ni
   ne finit nulle part, elle traverse. */
.agenda::before {
  content: "";
  position: absolute; left: 0; top: .4rem; bottom: 2.4rem; width: 1px;
  background: linear-gradient(transparent, rgba(176,141,87,.5) 5%, rgba(176,141,87,.5) 92%, transparent);
}

/* Le mois en filigrane : un tampon d'archive posé derrière les cartons, que
   js/agenda-reveal.js fait dériver de quelques pixels au défilement. */
.agenda-mois { position: relative; padding-top: clamp(2.2rem, 5vw, 3.4rem); }
.agenda-mois:first-child { padding-top: 0; }
.agenda-mois__filigrane {
  position: absolute; right: -.4rem; top: clamp(.6rem, 3vw, 1.4rem);
  z-index: 0; pointer-events: none; user-select: none;
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(3.4rem, 9vw, 6.6rem); line-height: 1;
  letter-spacing: -.02em; white-space: nowrap;
  color: rgba(176,141,87,.13);
  /* Les mois s'écrivent en minuscules en français ; en filigrane, c'est une
     initiale de titre qu'on attend. */
  text-transform: capitalize;
}

.agenda-item {
  position: relative; z-index: 1;
  background: var(--blanc);
  border: 1px solid rgba(176,141,87,.2);
  padding: clamp(1.4rem, 3vw, 1.9rem) clamp(1.3rem, 3vw, 2.1rem);
  margin-bottom: clamp(.9rem, 2vw, 1.3rem);
  transition: transform .8s cubic-bezier(.22,.61,.36,1),
              box-shadow .8s cubic-bezier(.22,.61,.36,1),
              border-color .8s cubic-bezier(.22,.61,.36,1);
}
/* Le second liseré du carton gravé, invisible au repos. */
.agenda-item::before {
  content: "";
  position: absolute; inset: 6px; pointer-events: none;
  border: 1px solid rgba(176,141,87,0);
  transition: inset .8s cubic-bezier(.22,.61,.36,1),
              border-color .8s cubic-bezier(.22,.61,.36,1);
}
.agenda-item:hover, .agenda-item:focus-within {
  transform: translateY(-4px);
  box-shadow: 0 24px 54px -26px rgba(46,38,32,.22);
  border-color: rgba(176,141,87,.42);
}
.agenda-item:hover::before, .agenda-item:focus-within::before {
  inset: 10px; border-color: rgba(176,141,87,.16);
}

/* Le losange accroché au fil. Son fond opaque perce la ligne : le nœud est posé
   sur le fil, il ne le chevauche pas. */
.agenda-item__noeud {
  position: absolute; top: clamp(1.9rem, 4vw, 2.4rem);
  left: calc(var(--rail) * -1);
  width: 9px; height: 9px; margin-left: -4px;
  background: var(--ivoire);
  border: 1px solid var(--or);
  transform: rotate(45deg);
  transition: background .7s cubic-bezier(.22,.61,.36,1),
              transform .7s cubic-bezier(.22,.61,.36,1);
}
.agenda-item:hover .agenda-item__noeud { background: var(--or); transform: rotate(45deg) scale(1.25); }
/* Le trait de raccord entre le fil et le carton. */
.agenda-item__noeud::after {
  content: "";
  position: absolute; top: 50%; left: 50%;
  width: calc(var(--rail) - 10px); height: 1px;
  background: rgba(176,141,87,.4);
  transform: rotate(-45deg); transform-origin: left center;
}

/* Date | filet | infos — la grammaire du carton d'invitation de l'accueil. */
.agenda-item__corps {
  display: grid; grid-template-columns: auto 1px 1fr;
  gap: clamp(1.2rem, 3.5vw, 2.1rem);
  align-items: center;
}
.agenda-item__filet {
  align-self: stretch; width: 1px;
  background: linear-gradient(transparent, rgba(176,141,87,.45) 15%, rgba(176,141,87,.45) 85%, transparent);
}

.agenda-date { display: block; font-family: var(--serif); line-height: 1; text-align: center; }
.agenda-date__jour {
  display: block;
  font-size: clamp(2.3rem, 5vw, 3rem);
  color: var(--or); font-weight: 500;
  letter-spacing: -.02em;   /* le Cormorant en grand corps respire trop */
  transition: color .7s cubic-bezier(.22,.61,.36,1);
}
.agenda-item:hover .agenda-date__jour { color: var(--or-clair); }
.agenda-date__mois {
  display: block; margin-top: .45rem;
  font-family: var(--sans); font-size: .72rem;
  text-transform: uppercase; letter-spacing: .24em; color: var(--brun);
}
.agenda-date__annee {
  display: block; margin-top: .15rem;
  font-family: var(--sans); font-size: .68rem;
  letter-spacing: .24em; color: var(--brun-doux);
}
/* Le compte à rebours : c'est lui qui fait d'une liste de dates un agenda. */
.agenda-compte {
  display: block; margin-top: .6rem;
  font-family: var(--serif); font-style: italic;
  font-size: .92rem; color: var(--brun-doux); white-space: nowrap;
}

.agenda-type {
  display: inline-block; margin-bottom: .7rem;
  font-size: .62rem; text-transform: uppercase; letter-spacing: .22em;
  color: var(--or); border: 1px solid rgba(176,141,87,.42);
  padding: .2rem .75rem;
  transition: background .6s cubic-bezier(.22,.61,.36,1),
              color .6s cubic-bezier(.22,.61,.36,1);
}
.agenda-item:hover .agenda-type { background: var(--or); color: var(--blanc); }
.agenda-nom { font-size: clamp(1.25rem, 2.6vw, 1.65rem); margin-bottom: .35rem; }
.agenda-lieu { color: var(--brun-doux); line-height: 1.5; font-size: .95rem; }
/* Le stand est une précision, pas une information de même rang que le lieu. */
.agenda-stand { white-space: nowrap; }
.agenda-stand::before { content: "·"; margin: 0 .5rem; color: var(--or); }

/* Le premier rendez-vous est une annonce, pas une ligne. */
.agenda-item--prochain {
  background: var(--ivoire);
  border-color: rgba(176,141,87,.34);
  padding: clamp(1.9rem, 4vw, 2.6rem) clamp(1.5rem, 4vw, 2.4rem);
  box-shadow: 0 18px 50px -24px rgba(46,38,32,.16);
  margin-bottom: clamp(1.5rem, 3vw, 2.2rem);
}
.agenda-item--prochain::before { inset: 8px; border-color: rgba(176,141,87,.16); }
.agenda-item--prochain .agenda-date__jour { font-size: clamp(3rem, 7vw, 4.1rem); }
.agenda-item--prochain .agenda-nom { font-size: clamp(1.5rem, 3.2vw, 2.1rem); }
.agenda-item--prochain .agenda-item__noeud {
  width: 12px; height: 12px; margin-left: -5.5px;
  background: var(--or);
  top: clamp(2.6rem, 5vw, 3.4rem);
}
.agenda-annonce { display: block; margin-bottom: 1.4rem; }

/* Rien à l'agenda : un carton gravé plutôt qu'une phrase orpheline. */
.agenda-vide {
  position: relative;
  max-width: 560px; margin: 0 auto;
  text-align: center; background: var(--ivoire);
  border: 1px solid rgba(176,141,87,.28);
  padding: clamp(2.4rem, 5vw, 3.4rem) clamp(1.6rem, 5vw, 3rem);
  box-shadow: 0 18px 50px -24px rgba(46,38,32,.14);
}
.agenda-vide::before {
  content: ""; position: absolute; inset: 8px; pointer-events: none;
  border: 1px solid rgba(176,141,87,.16);
}
.agenda-vide h2 { font-size: 1.5rem; margin-bottom: .5rem; }
.agenda-vide p { color: var(--brun-doux); font-family: var(--serif); font-style: italic; font-size: 1.1rem; }
/* Le filet du carton ouvre le bloc au lieu de le fermer. */
.agenda-vide .filet-losange { margin: 0 0 1.2rem; }

/* ---------- Apparition au défilement ----------
   État de repos posé par js/agenda-reveal.js et non en dur : sans JS, l'agenda
   s'affiche normalement au lieu de rester invisible. */
.agenda--anime::before {
  transform: scaleY(0); transform-origin: top;
  transition: transform 2.4s cubic-bezier(.22,.61,.36,1);
}
.agenda--anime.est-visible::before { transform: scaleY(1); }
.agenda-item--anime {
  opacity: 0; transform: translateY(20px);
  transition: opacity 1.4s cubic-bezier(.22,.61,.36,1),
              transform 1.4s cubic-bezier(.22,.61,.36,1),
              box-shadow .8s cubic-bezier(.22,.61,.36,1),
              border-color .8s cubic-bezier(.22,.61,.36,1);
}
.agenda-item--anime.est-visible { opacity: 1; transform: none; }
/* Le losange s'allume après que son carton s'est posé. */
.agenda-item--anime .agenda-item__noeud {
  opacity: 0;
  transition: opacity 1s cubic-bezier(.22,.61,.36,1),
              background .7s cubic-bezier(.22,.61,.36,1),
              transform .7s cubic-bezier(.22,.61,.36,1);
}
.agenda-item--anime.est-visible .agenda-item__noeud { opacity: 1; transition-delay: .35s; }
.agenda-mois__filigrane--anime { opacity: 0; transition: opacity 2s cubic-bezier(.22,.61,.36,1); }
.agenda-mois__filigrane--anime.est-visible { opacity: 1; }

@media (max-width: 700px) {
  /* Le fil et les losanges n'ont plus de sens en pleine largeur : l'agenda
     redevient une pile de cartons. */
  .agenda { padding-left: 0; }
  .agenda::before, .agenda-item__noeud { display: none; }
  .agenda-item__corps { grid-template-columns: 1fr; gap: 1.2rem; text-align: center; }
  .agenda-item__filet {
    justify-self: center; align-self: auto;
    width: 46px; height: 1px;
    background: linear-gradient(90deg, transparent, rgba(176,141,87,.45), transparent);
  }
  .agenda-mois__filigrane { font-size: 3rem; right: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .agenda-item--anime,
  .agenda-mois__filigrane--anime { opacity: 1; transform: none; transition: none; }
  /* Le fil reste tendu et le losange garde sa rotation : ce sont des formes,
     pas des mouvements. */
  .agenda--anime::before { transform: scaleY(1); transition: none; }
  .agenda-item--anime .agenda-item__noeud { opacity: 1; transition: none; }
  .agenda-item, .agenda-item::before, .agenda-item__noeud,
  .agenda-date__jour, .agenda-type { transition: none; }
  .agenda-item:hover, .agenda-item:focus-within { transform: none; }
}

/* ---------- Prochain rendez-vous (carton d'invitation) ----------
   Le bloc reprend la grammaire de .agenda-item (date en serif à gauche, filet
   doré, infos à droite) mais au rang d'annonce : un carton posé sur le crème,
   cerné d'un double liseré, comme un faire-part. Toutes les valeurs restent dans
   les amplitudes du site : filets de 1px, ombres très diffuses, or discret.
   Le halo et le grain viennent de .fond-atelier--creme, posé dans le balisage. */

/* Un seul rendez-vous : le carton reste centré (max-width posé plus bas).
   Deux : côte à côte sur desktop, chacun gardant sa largeur maximale, la grille
   se rabat en colonne dès que la place manque. */
.rdv-cartons--duo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(1.6rem, 4vw, 2.6rem);
  align-items: start;
}

.rdv-carton {
  position: relative;
  max-width: 660px; margin: 0 auto;
  padding: clamp(2.6rem, 5vw, 3.6rem) clamp(1.6rem, 5vw, 3.4rem);
  text-align: center;
  background: var(--ivoire);
  border: 1px solid rgba(176,141,87,.28);
  /* Ombre portée très diffuse et très pâle : le carton repose sur le crème,
     il ne flotte pas au-dessus. */
  box-shadow: 0 18px 50px -22px rgba(46,38,32,.16);
  transition: box-shadow .7s cubic-bezier(.22,.61,.36,1),
              border-color .7s cubic-bezier(.22,.61,.36,1);
}
/* Second liseré, en retrait de 8px : le double filet du carton gravé. */
.rdv-carton::before {
  content: "";
  position: absolute; inset: 8px; pointer-events: none;
  border: 1px solid rgba(176,141,87,.16);
  transition: inset .7s cubic-bezier(.22,.61,.36,1), border-color .7s cubic-bezier(.22,.61,.36,1);
}
.rdv-carton:hover {
  box-shadow: 0 26px 64px -24px rgba(46,38,32,.22);
  border-color: rgba(176,141,87,.42);
}
.rdv-carton:hover::before { inset: 11px; border-color: rgba(176,141,87,.26); }

.rdv-carton__annonce { margin-bottom: 2rem; }

/* Date | filet | infos — la colonne de date se dimensionne sur son contenu
   (« 12 » ou « 12–14 ») sans jamais comprimer le nom de l'événement. */
.rdv-carton__corps {
  display: grid; grid-template-columns: auto 1px 1fr;
  gap: clamp(1.4rem, 4vw, 2.4rem);
  align-items: center; text-align: left;
}
.rdv-carton__filet {
  align-self: stretch; width: 1px;
  background: linear-gradient(transparent, rgba(176,141,87,.45) 18%, rgba(176,141,87,.45) 82%, transparent);
}

.rdv-date { display: block; font-family: var(--serif); line-height: 1; }
.rdv-date__jour {
  display: block;
  font-size: clamp(3.2rem, 8vw, 4.4rem);
  color: var(--or); font-weight: 500;
  letter-spacing: -.02em;   /* le Cormorant en grand corps respire trop */
}
.rdv-date__mois {
  display: block; margin-top: .5rem;
  font-family: var(--sans); font-size: .78rem;
  text-transform: uppercase; letter-spacing: .24em; color: var(--brun);
}
.rdv-date__annee {
  display: block; margin-top: .2rem;
  font-family: var(--sans); font-size: .72rem;
  letter-spacing: .24em; color: var(--brun-doux);
}

.rdv-infos__type {
  display: block; margin-bottom: .5rem;
  font-size: .68rem; text-transform: uppercase; letter-spacing: .22em;
  color: var(--brun-doux);
}
.rdv-infos__nom { font-size: clamp(1.5rem, 3.2vw, 2.1rem); margin-bottom: .5rem; }
.rdv-infos__lieu { color: var(--brun-doux); line-height: 1.5; }
/* Le stand est une précision, pas une information de même rang que le lieu :
   il s'en détache par un point médian plutôt que par une pastille. */
.rdv-infos__stand { white-space: nowrap; }
.rdv-infos__stand::before { content: "·"; margin: 0 .5rem; color: var(--or); }

/* CTA : le .btn du site, dont le remplissage doré monte du bas au lieu de
   basculer d'un coup. Le fond reste transparent — la couche est un ::before. */
.rdv-cta {
  position: relative; overflow: hidden; isolation: isolate;
  margin-top: 2.4rem;
  transition: color .55s cubic-bezier(.22,.61,.36,1),
              letter-spacing .55s cubic-bezier(.22,.61,.36,1),
              border-color .55s cubic-bezier(.22,.61,.36,1);
}
.rdv-cta::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: var(--or);
  transform: scaleY(0); transform-origin: bottom;
  transition: transform .55s cubic-bezier(.22,.61,.36,1);
}
.rdv-cta:hover, .rdv-cta:focus-visible {
  background: transparent;   /* neutralise le remplissage instantané de .btn */
  color: var(--blanc); border-color: var(--or);
  letter-spacing: .22em;     /* .18em au repos : le mot s'ouvre en s'éclairant */
}
.rdv-cta:hover::before, .rdv-cta:focus-visible::before { transform: scaleY(1); }
.rdv-cta__texte { position: relative; }

/* ---------- Apparition au défilement ----------
   État de repos posé par JS (.rdv-carton--anime) et non en dur : sans JS, le
   carton s'affiche normalement au lieu de rester invisible. */
.rdv-carton--anime .rdv-carton__annonce,
.rdv-carton--anime .rdv-date,
.rdv-carton--anime .rdv-infos,
.rdv-carton--anime .rdv-cta {
  opacity: 0; transform: translateY(14px);
  transition: opacity 1.5s cubic-bezier(.22,.61,.36,1),
              transform 1.5s cubic-bezier(.22,.61,.36,1);
}
.rdv-carton--anime .rdv-carton__filet {
  transform: scaleY(0); transform-origin: center;
  transition: transform 1.6s cubic-bezier(.22,.61,.36,1);
}
.rdv-carton--anime {
  opacity: 0; transform: translateY(26px);
  transition: opacity 1.6s cubic-bezier(.22,.61,.36,1),
              transform 1.6s cubic-bezier(.22,.61,.36,1),
              box-shadow .7s cubic-bezier(.22,.61,.36,1),
              border-color .7s cubic-bezier(.22,.61,.36,1);
}
/* Le décalage des enfants raconte la lecture du carton : l'annonce, la date,
   l'événement, puis l'invitation. */
.rdv-carton--anime.est-visible { opacity: 1; transform: none; }
.rdv-carton--anime.est-visible .rdv-carton__annonce,
.rdv-carton--anime.est-visible .rdv-date,
.rdv-carton--anime.est-visible .rdv-infos,
.rdv-carton--anime.est-visible .rdv-cta { opacity: 1; transform: none; }
.rdv-carton--anime.est-visible .rdv-carton__filet { transform: scaleY(1); }
.rdv-carton--anime.est-visible .rdv-carton__annonce { transition-delay: .15s; }
.rdv-carton--anime.est-visible .rdv-date          { transition-delay: .35s; }
.rdv-carton--anime.est-visible .rdv-carton__filet { transition-delay: .5s; }
.rdv-carton--anime.est-visible .rdv-infos         { transition-delay: .55s; }
.rdv-carton--anime.est-visible .rdv-cta           { transition-delay: .8s; }

@media (max-width: 640px) {
  /* Le filet vertical n'a plus de sens une fois la grille dépilée : il redevient
     une règle horizontale courte, centrée, entre la date et l'événement. */
  .rdv-carton__corps { grid-template-columns: 1fr; gap: 1.5rem; text-align: center; }
  .rdv-carton__filet {
    justify-self: center; align-self: auto;
    width: 46px; height: 1px;
    background: linear-gradient(90deg, transparent, rgba(176,141,87,.45), transparent);
  }
  .rdv-carton--anime .rdv-carton__filet { transform: scaleX(0); }
  .rdv-carton--anime.est-visible .rdv-carton__filet { transform: scaleX(1); }
  .rdv-date__jour { font-size: 3.4rem; }
  /* Le bouton prend toute la largeur du carton. Le padding de .btn (2.2rem) est
     taillé pour une mise en page libre : ici il enserre le libellé au point de le
     couper en deux lignes — on le desserre pour garder l'invitation d'un seul tenant. */
  .rdv-cta { display: block; padding-left: 1.4rem; padding-right: 1.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .rdv-carton--anime,
  .rdv-carton--anime .rdv-carton__annonce,
  .rdv-carton--anime .rdv-date,
  .rdv-carton--anime .rdv-infos,
  .rdv-carton--anime .rdv-cta,
  .rdv-carton--anime .rdv-carton__filet {
    opacity: 1; transform: none; transition: none;
  }
  .rdv-carton, .rdv-carton::before, .rdv-cta, .rdv-cta::before { transition: none; }
}

/* ============================================================
   PAGE ? L'ATELIER ?
   ------------------------------------------------------------
   Le parcours en sept temps : heros epingle, triptyque en
   split-scroll, xylotheque, frise horizontale du geste, reperes
   chiffres, mosaique et certificat.

   Meme grammaire que .fond-atelier et .rdv-carton : filets de
   1px, ombres tres diffuses, or discret, transitions longues en
   cubic-bezier(.22,.61,.36,1), grain feTurbulence en data-URI.
   Ce qui change, c'est l'ampleur : ici on epingle, on scrube et
   on defile a l'horizontale (voir js/atelier.js).
   Les visuels se reglent dans le backoffice, module
   ? Page L'Atelier ? (lib/page_atelier.php).
   ============================================================ */

/* ------------------------------------------------------------
   FONDATIONS PARTAGÉES
   ------------------------------------------------------------ */

/* Grain de papier — identique à celui de .fond-atelier, hissé en
   classe utilitaire parce que six blocs de la page s'en servent. */
.at-grain { position: relative; }
.at-grain::after {
  content: "";
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  opacity: .03; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");
}
/* Sur fond brun, le multiply avale le grain : on repasse en screen
   et on baisse l'opacité, sinon la section sombre devient sale. */
.at-grain--sombre::after { mix-blend-mode: screen; opacity: .04; }
.at-grain > * { position: relative; z-index: 1; }

/* Filet à losange — la ponctuation gravée du Journal, reprise telle
   quelle pour lier les blocs entre eux. */
.at-losange {
  display: flex; align-items: center; justify-content: center;
  gap: .8rem; margin: 1.5rem 0;
}
.at-losange::before, .at-losange::after {
  content: ""; height: 1px; width: 56px;
  background: linear-gradient(90deg, transparent, rgba(176,141,87,.55));
}
.at-losange::after { background: linear-gradient(90deg, rgba(176,141,87,.55), transparent); }
.at-losange i {
  width: 5px; height: 5px; flex: none;
  border: 1px solid var(--or); transform: rotate(45deg);
}

/* Étiquette verticale collante : la marque d'imprimeur dans la marge.
   Elle accompagne le bloc pendant qu'on le parcourt, puis disparaît.
   Masquée sous 1400px — en dessous, la gouttière n'existe plus. */
.at-marge {
  position: absolute; top: 0; left: max(1.4rem, calc(50vw - 700px));
  height: 100%; width: 1px; pointer-events: none; z-index: 2;
}
.at-marge__texte {
  position: sticky; top: 45vh;
  display: block; white-space: nowrap;
  transform: rotate(-90deg); transform-origin: left top;
  font-size: .64rem; text-transform: uppercase; letter-spacing: .34em;
  color: rgba(176,141,87,.6);
}
.at-marge__texte::after {
  content: ""; display: inline-block; vertical-align: middle;
  width: 46px; height: 1px; margin-left: 1.2rem;
  background: linear-gradient(90deg, rgba(176,141,87,.5), transparent);
}
@media (max-width: 1399px) { .at-marge { display: none; } }

/* ------------------------------------------------------------
   1. HÉROS ÉPINGLÉ — « l'entrée dans l'atelier »
   ------------------------------------------------------------
   Le titre se révèle ligne par ligne au clip-path, la lueur dérive
   comme une lampe qu'on déplace au-dessus de l'établi, puis le bloc
   entier s'échappe vers le haut pendant que la suite monte.
   L'épinglage est posé par GSAP ; sans JS la section fait 100vh et
   tout est déjà visible (voir .at-heros__ligne par défaut).       */

.at-heros {
  position: relative;
  height: 220vh;                 /* la course d'épinglage */
  background: var(--brun);
}
.at-heros__cadre {
  position: sticky; top: 0;
  height: 100vh; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  text-align: center; color: var(--ivoire);
}
/* Photogramme d'atelier en fond, très assombri : on doit deviner le
   bois et le laiton, pas lire l'image. */
.at-heros__fond {
  position: absolute; inset: -6%;
  background-size: cover; background-position: center;
  filter: brightness(.34) saturate(.85);
  will-change: transform;
}
/* La lampe : un halo chaud qui dérive en boucle lente. C'est le seul
   mouvement autonome de la page — tout le reste répond au scroll. */
.at-heros__lampe {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 42% 46% at 50% 42%,
              rgba(211,183,135,.30), rgba(176,141,87,.10) 45%, transparent 72%);
  animation: atLampe 19s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes atLampe {
  0%   { transform: translate3d(-7%, -4%, 0) scale(1); }
  50%  { transform: translate3d(4%, 3%, 0) scale(1.09); }
  100% { transform: translate3d(8%, -2%, 0) scale(1.02); }
}
/* Vignette : les bords se referment sur le centre. */
.at-heros__cadre::after {
  content: "";
  position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: radial-gradient(ellipse 78% 70% at 50% 50%, transparent 42%, rgba(20,15,11,.62));
}
.at-heros__contenu {
  position: relative; z-index: 3;
  padding: 0 1.4rem; max-width: 900px;
  will-change: opacity, transform;
}
.at-heros__contenu .sur-titre { color: var(--or-clair); }

/* Le titre : une <span> par ligne, chacune masquée par son parent en
   overflow. GSAP fait monter la ligne depuis le bas ; sans JS elle est
   déjà en place (translate: 0 par défaut). */
.at-heros__titre {
  font-size: clamp(2.6rem, 7vw, 5.2rem);
  line-height: 1.08; margin: .4rem 0 0;
}
.at-heros__ligne { display: block; overflow: hidden; padding-bottom: .08em; }
.at-heros__ligne > span { display: block; will-change: transform; }
.at-heros__titre em { font-style: italic; color: var(--or-clair); }

.at-heros__filet {
  width: 0; height: 1px; margin: 2rem auto;
  background: linear-gradient(90deg, transparent, var(--or-clair) 22%, var(--or-clair) 78%, transparent);
}
/* Sans JS, le filet doit exister : GSAP écrase cette largeur au scrub. */
.at-heros:not(.at-heros--anime) .at-heros__filet { width: 220px; }

.at-heros__chapo {
  max-width: 52ch; margin: 0 auto;
  font-family: var(--serif); font-style: italic;
  font-size: clamp(1.1rem, 2.2vw, 1.45rem);
  color: var(--creme);
}
.at-heros__indice {
  position: absolute; bottom: 2.2rem; left: 50%; transform: translateX(-50%);
  z-index: 3; color: rgba(250,246,239,.75);
  font-size: .68rem; text-transform: uppercase; letter-spacing: .3em;
  display: flex; flex-direction: column; align-items: center; gap: .8rem;
}
.at-heros__indice::after {
  content: ""; width: 1px; height: 46px;
  background: linear-gradient(var(--or-clair), transparent);
  animation: atIndice 2s ease-in-out infinite;
}
@keyframes atIndice {
  0%, 100% { opacity: .25; transform: scaleY(.55); transform-origin: top; }
  50%      { opacity: 1;   transform: scaleY(1);   transform-origin: top; }
}

/* ------------------------------------------------------------
   2. TRIPTYQUE EN SPLIT-SCROLL — « La main, la matière, le temps »
   ------------------------------------------------------------
   Colonne gauche épinglée : les visuels se relaient en fondu croisé.
   Colonne droite : trois temps qui défilent, chacun coiffé d'un
   chiffre romain en filigrane. Sur mobile la colonne d'images passe
   au-dessus de chaque temps, en pleine largeur.                    */

.at-triptyque { position: relative; background: var(--ivoire); }
.at-triptyque__grille {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 5rem); align-items: start;
}
.at-triptyque__media {
  position: sticky; top: 12vh;
  aspect-ratio: 4/5; overflow: hidden;
  background: var(--creme);
  border: 1px solid rgba(176,141,87,.25);
}
/* Second liseré en retrait : la cuvette de la gravure, comme sur les
   cartons de rendez-vous. Ici il est permanent, le bloc ne se survole pas. */
.at-triptyque__media::after {
  content: ""; position: absolute; inset: 10px; z-index: 3;
  border: 1px solid rgba(250,246,239,.22); pointer-events: none;
}
.at-triptyque__vue {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  opacity: 0; transition: opacity 1.1s cubic-bezier(.22,.61,.36,1);
  will-change: opacity, transform;
}
/* La première vue porte .est-active dès le HTML : sans JS, la colonne
   n'est jamais vide, elle ne change simplement pas. */
.at-triptyque__vue.est-active { opacity: 1; }

.at-temps {
  position: relative;
  min-height: 78vh;
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(2rem, 5vw, 4rem) 0;
}
/* Le chiffre romain en filigrane : très grand, très pâle, derrière le
   texte. Il donne du fond au bloc sans rien ajouter à lire. */
.at-temps__chiffre {
  position: absolute; top: 50%; right: -.06em; transform: translateY(-58%);
  font-family: var(--serif); font-style: italic;
  font-size: clamp(9rem, 22vw, 17rem); line-height: .8;
  color: rgba(176,141,87,.09);
  pointer-events: none; user-select: none; z-index: 0;
}
.at-temps > *:not(.at-temps__chiffre) { position: relative; z-index: 1; }
.at-temps__titre { font-size: clamp(1.9rem, 4vw, 2.9rem); margin: .3rem 0 1rem; }
.at-temps__texte { color: var(--brun-doux); max-width: 46ch; }
/* Le filet vertical qui pousse du haut : il marque le temps en cours. */
.at-temps__filet {
  position: absolute; left: -1.6rem; top: 18%; bottom: 18%; width: 1px;
  background: rgba(176,141,87,.5); transform-origin: top;
  transform: scaleY(0); transition: transform 1.3s cubic-bezier(.22,.61,.36,1);
}
.at-temps.est-visible .at-temps__filet { transform: scaleY(1); }
@media (max-width: 1100px) { .at-temps__filet { display: none; } }

@media (max-width: 860px) {
  .at-triptyque__grille { grid-template-columns: 1fr; }
  .at-triptyque__media { position: relative; top: auto; aspect-ratio: 16/10; margin-bottom: 1.5rem; }
  .at-temps { min-height: auto; }
  .at-temps__chiffre { font-size: 9rem; opacity: .7; }
}

/* ------------------------------------------------------------
   3. LA XYLOTHÈQUE — planche de botanique
   ------------------------------------------------------------
   78 essences en base. Trop peu de photos pour un mur d'images, mais
   assez de noms latins pour une planche d'herbier. Deux rubans qui
   défilent en sens contraire annoncent le nombre ; l'index en dessous
   se lit, et le cartouche collant montre l'essence survolée.        */

.at-xylo { position: relative; background: var(--creme); overflow: hidden; }
.at-xylo::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 70% 55% at 50% 25%, rgba(250,246,239,.85), transparent 72%);
}
.at-xylo > .conteneur, .at-xylo > .at-ruban { position: relative; z-index: 1; }

/* Les rubans : pleine largeur, hors conteneur. Deux pistes identiques
   accolées et translatées de -50% donnent une boucle sans couture. */
.at-ruban {
  position: relative;
  margin: clamp(2rem, 5vw, 3.4rem) 0;
  padding: .9rem 0;
  border-top: 1px solid rgba(176,141,87,.22);
  border-bottom: 1px solid rgba(176,141,87,.22);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.at-ruban__piste {
  display: flex; width: max-content;
  animation: atRuban 78s linear infinite;
  will-change: transform;
}
.at-ruban--inverse .at-ruban__piste { animation-direction: reverse; animation-duration: 96s; }
@keyframes atRuban { to { transform: translate3d(-50%, 0, 0); } }
/* Au survol le ruban ne s'arrête pas net, il se traîne : on peut lire
   un nom sans que le mouvement casse. */
.at-ruban:hover .at-ruban__piste { animation-duration: 400s; }
.at-ruban__mot {
  flex: none; padding: 0 1.5rem;
  font-family: var(--serif); font-size: clamp(1.15rem, 2vw, 1.6rem);
  color: var(--brun); white-space: nowrap;
}
.at-ruban__mot em { font-style: italic; color: rgba(176,141,87,.85); }
.at-ruban__mot::after { content: "·"; margin-left: 1.5rem; color: var(--or); }

/* Les essences photographiées, en vedette. */
.at-xylo__vedettes {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: clamp(1rem, 2.5vw, 1.8rem);
  margin-bottom: clamp(2.4rem, 5vw, 3.6rem);
}
.at-essence { position: relative; background: var(--ivoire); border: 1px solid rgba(176,141,87,.22); }
.at-essence__visuel { aspect-ratio: 1/1; overflow: hidden; background: var(--creme); }
.at-essence__visuel img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.4s cubic-bezier(.22,.61,.36,1), filter .8s;
  filter: saturate(.85);
}
.at-essence:hover .at-essence__visuel img { transform: scale(1.06); filter: saturate(1.05); }
.at-essence__infos { padding: .9rem 1rem 1.1rem; text-align: center; }
.at-essence__nom { font-family: var(--serif); font-size: 1.3rem; color: var(--brun); }
.at-essence__latin { font-family: var(--serif); font-style: italic; font-size: .92rem; color: var(--brun-doux); }

/* L'index : abécédaire, fenêtre de lecture, fiche. Les trois colonnes
   partagent exactement la même hauteur (--at-xylo-h), de sorte que la
   fiche reste sous les yeux quelle que soit l'essence atteinte — y
   compris la dernière de la liste. C'est la liste qui défile en interne,
   pas la page. */
.at-xylo__index {
  --at-xylo-h: clamp(24rem, 54vh, 33rem);
  display: grid;
  grid-template-columns: auto minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(1.2rem, 3vw, 2.6rem);
  align-items: start;
}

/* L'abécédaire : les seules initiales réellement présentes en base.
   Une colonne fine, en chiffres de titre, qui sert de raccourci. */
.at-abc {
  display: flex; flex-direction: column; align-items: center;
  gap: .1rem; height: var(--at-xylo-h);
  padding-right: clamp(.4rem, 1vw, .9rem);
  border-right: 1px solid rgba(176,141,87,.22);
  overflow: hidden;
}
.at-abc__lettre {
  flex: 1 1 0; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  width: 1.5rem;
  font-family: var(--serif); font-size: .95rem; line-height: 1;
  color: rgba(92,80,70,.5); cursor: pointer;
  background: none; border: 0; padding: 0;
  transition: color .3s, transform .4s cubic-bezier(.22,.61,.36,1);
}
.at-abc__lettre:hover { color: var(--or); transform: scale(1.28); }
.at-abc__lettre.est-actif { color: var(--or); font-weight: 600; transform: scale(1.35); }
.at-abc__lettre:focus-visible { outline: 1px solid var(--or); outline-offset: 2px; }

/* La fenêtre de lecture. Le fondu haut/bas dit qu'il y a de la suite ;
   il se retire au ras des extrémités pour ne pas voiler le premier ou
   le dernier nom (classes posées par le JS au défilement). */
.at-xylo__liste {
  position: relative;
  height: var(--at-xylo-h);
  overflow-y: auto; overscroll-behavior: contain;
  padding-right: .9rem;
  -webkit-mask-image: linear-gradient(transparent, #000 5%, #000 93%, transparent);
          mask-image: linear-gradient(transparent, #000 5%, #000 93%, transparent);
  transition: -webkit-mask-image .4s, mask-image .4s;
  scrollbar-width: thin;
  scrollbar-color: rgba(176,141,87,.55) transparent;
}
.at-xylo__liste.est-en-haut {
  -webkit-mask-image: linear-gradient(#000 93%, transparent);
          mask-image: linear-gradient(#000 93%, transparent);
}
.at-xylo__liste.est-en-bas {
  -webkit-mask-image: linear-gradient(transparent, #000 5%);
          mask-image: linear-gradient(transparent, #000 5%);
}
.at-xylo__liste.est-entiere {
  -webkit-mask-image: none; mask-image: none;
}
/* Barre de défilement discrète, dans l'or du site (WebKit ; Firefox est
   servi par scrollbar-color plus haut). */
.at-xylo__liste::-webkit-scrollbar { width: 3px; }
.at-xylo__liste::-webkit-scrollbar-track { background: rgba(176,141,87,.12); }
.at-xylo__liste::-webkit-scrollbar-thumb { background: rgba(176,141,87,.55); }
.at-xylo__liste::-webkit-scrollbar-thumb:hover { background: var(--or); }

/* Un groupe = une lettre en gouttière + ses noms en grille. La lettre
   reste collée en haut tant qu'on parcourt son groupe : on sait toujours
   dans quelle section de l'index on se trouve. */
.at-groupe {
  display: grid; grid-template-columns: 2.2rem minmax(0, 1fr);
  gap: 0 .8rem;
  padding: .5rem 0;
  border-top: 1px solid rgba(176,141,87,.16);
}
.at-groupe:first-child { border-top: 0; }
.at-groupe__lettre {
  position: sticky; top: 0; align-self: start;
  font-family: var(--serif); font-size: 1.5rem; line-height: 1.4;
  color: rgba(176,141,87,.75);
}
.at-groupe__noms {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0 1.2rem;
}

.at-nom {
  position: relative; display: block;
  padding: .3rem 0 .3rem 0; cursor: pointer;
  font-family: var(--serif); font-size: 1.08rem; color: var(--brun);
  transition: color .35s, padding-left .45s cubic-bezier(.22,.61,.36,1);
}
/* Le trait qui pousse depuis la gauche : la marque de sélection, à la
   place d'un fond coloré qui alourdirait l'index. */
.at-nom::before {
  content: ""; position: absolute; left: 0; top: 50%;
  width: .32rem; height: 1px; background: var(--or);
  transform: scaleX(0); transform-origin: left;
  transition: transform .45s cubic-bezier(.22,.61,.36,1);
}
.at-nom:hover, .at-nom.est-actif { color: var(--or); padding-left: .62rem; }
.at-nom:hover::before, .at-nom.est-actif::before { transform: scaleX(1); }
.at-nom.est-actif { font-weight: 500; }
.at-nom:focus-visible { outline: 1px solid var(--or); outline-offset: 2px; }

/* La fiche d'herbier, à hauteur de la fenêtre de lecture. Elle ne défile
   pas : son texte s'ajuste, et déborde en interne si la description est
   longue. */
.at-cartouche {
  position: relative;
  display: flex; flex-direction: column;
  height: var(--at-xylo-h);
  background: var(--ivoire); border: 1px solid rgba(176,141,87,.28);
  padding: clamp(1.4rem, 2.6vw, 2rem);
  box-shadow: 0 18px 50px -24px rgba(46,38,32,.18);
}
.at-cartouche::before {
  content: ""; position: absolute; inset: 8px; pointer-events: none;
  border: 1px solid rgba(176,141,87,.16);
}
.at-cartouche__ref { font-size: .68rem; text-transform: uppercase; letter-spacing: .24em; color: var(--or); }
.at-cartouche__nom { font-family: var(--serif); font-size: clamp(1.5rem, 2.6vw, 2.05rem); color: var(--brun); margin: .5rem 0 .1rem; line-height: 1.1; }
.at-cartouche__latin { font-family: var(--serif); font-style: italic; font-size: 1.05rem; color: var(--brun-doux); }
.at-cartouche__desc { margin-top: 1rem; font-size: .91rem; color: var(--brun-doux); }
/* Le contenu se remplace en fondu court : la fiche change, elle ne clignote pas. */
.at-cartouche__corps {
  flex: 1; min-height: 0; overflow-y: auto;
  transition: opacity .3s ease;
  scrollbar-width: thin; scrollbar-color: rgba(176,141,87,.4) transparent;
}
.at-cartouche__corps::-webkit-scrollbar { width: 3px; }
.at-cartouche__corps::-webkit-scrollbar-thumb { background: rgba(176,141,87,.4); }
.at-cartouche.est-en-transition .at-cartouche__corps { opacity: 0; }

/* Pied de fiche : le rang de l'essence dans la collection, et les deux
   flèches qui parcourent la xylothèque sans revenir à la liste. */
.at-cartouche__pied {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-top: 1rem; padding-top: .9rem;
  border-top: 1px solid rgba(176,141,87,.25);
}
.at-cartouche__rang {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .2em;
  color: var(--brun-doux); font-variant-numeric: tabular-nums;
}
.at-cartouche__nav { display: flex; gap: .4rem; }
.at-cartouche__fleche {
  width: 2rem; height: 2rem; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid rgba(176,141,87,.4);
  color: var(--or); font-family: var(--serif); font-size: 1rem;
  cursor: pointer; transition: background .3s, color .3s, border-color .3s;
}
.at-cartouche__fleche:hover { background: var(--or); color: var(--blanc); border-color: var(--or); }

@media (max-width: 980px) {
  /* La fiche passe au-dessus : sur un écran étroit, on veut voir ce
     qu'on a choisi avant de continuer à fouiller la liste. */
  .at-xylo__index { grid-template-columns: auto minmax(0, 1fr); }
  .at-cartouche { grid-column: 1 / -1; grid-row: 1; height: auto; min-height: 15rem; }
}
@media (max-width: 560px) {
  .at-xylo__index { --at-xylo-h: 20rem; gap: .8rem; }
  .at-groupe { grid-template-columns: 1.6rem minmax(0, 1fr); }
  .at-groupe__noms { grid-template-columns: 1fr; }
  .at-abc__lettre { width: 1.2rem; font-size: .82rem; }
}

/* ------------------------------------------------------------
   4. LA FRISE — « le temps d'un stylo », défilement horizontal
   ------------------------------------------------------------
   Section épinglée : le scroll vertical pousse la frise à l'horizontale.
   Le filet doré se trace au même rythme, les étapes s'allument au
   passage. Sans JS (ou en mouvement réduit), la frise redevient une
   liste verticale ordinaire — voir .at-frise--statique.            */

.at-frise { position: relative; background: var(--brun); color: var(--ivoire); overflow: hidden; }
.at-frise__cadre { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; padding: clamp(3rem, 7vw, 5rem) 0; }
.at-frise .sur-titre { color: var(--or-clair); }
.at-frise__titre { color: var(--ivoire); text-align: center; margin-bottom: clamp(2.5rem, 6vw, 4rem); }
.at-frise__titre em { font-style: italic; color: var(--or-clair); }

.at-frise__piste {
  position: relative;
  display: flex; align-items: stretch; gap: clamp(2rem, 5vw, 4rem);
  padding: 0 max(1.4rem, calc(50vw - 560px));
  width: max-content;
  will-change: transform;
}
/* Le rail : un filet qui traverse toute la piste, doublé d'une couche
   dorée que GSAP fait croître au scrub. */
.at-frise__rail {
  position: absolute; left: 0; right: 0; top: 3.05rem; height: 1px;
  background: rgba(243,236,223,.16);
}
.at-frise__rail span {
  position: absolute; inset: 0; transform-origin: left; transform: scaleX(0);
  background: linear-gradient(90deg, var(--or), var(--or-clair));
}
.at-frise--statique .at-frise__rail span { transform: scaleX(1); }

.at-etape { flex: none; width: min(19rem, 68vw); }
.at-etape__pastille {
  position: relative; z-index: 1;
  width: 2.1rem; height: 2.1rem; margin: 2rem 0 1.6rem;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(243,236,223,.3); border-radius: 50%;
  background: var(--brun);
  font-family: var(--serif); font-size: 1rem; color: rgba(243,236,223,.55);
  transition: color .6s, border-color .6s, background .6s, transform .6s cubic-bezier(.22,.61,.36,1);
}
.at-etape.est-active .at-etape__pastille {
  color: var(--brun); background: var(--or-clair);
  border-color: var(--or-clair); transform: scale(1.14);
}
.at-etape__nom {
  font-family: var(--serif); font-size: clamp(1.4rem, 2.4vw, 1.85rem);
  color: rgba(243,236,223,.5); margin-bottom: .6rem;
  transition: color .6s cubic-bezier(.22,.61,.36,1);
}
.at-etape.est-active .at-etape__nom { color: var(--ivoire); }
.at-etape__texte {
  font-size: .93rem; color: rgba(243,236,223,.4);
  transition: color .6s cubic-bezier(.22,.61,.36,1);
}
.at-etape.est-active .at-etape__texte { color: rgba(243,236,223,.72); }
.at-etape__duree {
  display: block; margin-top: .9rem;
  font-size: .66rem; text-transform: uppercase; letter-spacing: .24em;
  color: var(--or-clair); opacity: 0; transition: opacity .7s;
}
.at-etape.est-active .at-etape__duree { opacity: 1; }

/* Le point final. La piste ne s'achève pas sur une étape mais sur la
   sortie d'atelier — un carton clair après sept blocs sombres, la lumière
   au bout de l'établi.

   Sa largeur n'est pas décorative : elle rallonge la course d'autant, et
   c'est ce qui permet à la septième étape de venir jusqu'au tiers gauche
   de l'écran. Sans elle, la piste s'arrêtait dès que son bord droit
   touchait celui de l'écran et les deux dernières étapes restaient
   coincées à droite. */
.at-fin {
  /* Au-dessus du rail : le filet doré s'arrête net au bord du carton
     plutôt que de le traverser. */
  position: relative; z-index: 1;
  flex: none; align-self: start;
  width: min(27rem, 80vw);
  margin-top: 2rem;
  padding: clamp(1.6rem, 3vw, 2.2rem);
  background: var(--ivoire); color: var(--brun);
  border: 1px solid rgba(176,141,87,.4);
  box-shadow: 0 30px 64px -30px rgba(0,0,0,.6);
}
/* Le second liseré du carton gravé, comme sur .rdv-carton. */
.at-fin::before {
  content: ""; position: absolute; inset: 8px; pointer-events: none;
  border: 1px solid rgba(176,141,87,.2);
}
.at-fin .sur-titre { color: var(--or); }
.at-fin__titre {
  font-family: var(--serif); font-size: clamp(1.6rem, 3vw, 2.1rem);
  line-height: 1.15; margin: .2rem 0 .7rem; color: var(--brun);
}
.at-fin__titre em { font-style: italic; color: var(--or); }
.at-fin__texte { color: var(--brun-doux); font-size: .95rem; margin-bottom: 1.5rem; }
.at-fin .at-losange { margin: 0 0 1.1rem; justify-content: flex-start; }
.at-fin .at-losange::before { display: none; }

/* Repli vertical : mobile, absence de JS, mouvement réduit. */
.at-frise--statique .at-frise__piste { flex-direction: column; width: auto; padding: 0 1.4rem; transform: none !important; }
/* Dépilé, le carton n'a plus de course à financer : il prend la largeur
   et s'aligne sur les étapes. */
.at-frise--statique .at-fin {
  width: auto; align-self: stretch;
  margin: 1.4rem 0 0 2.6rem; opacity: 1 !important;
}
.at-frise--statique .at-frise__rail { left: 1.4rem; right: auto; top: 0; bottom: 0; width: 1px; height: auto; }
.at-frise--statique .at-frise__rail span { background: linear-gradient(var(--or), var(--or-clair)); transform: none; }
.at-frise--statique .at-etape { width: auto; padding-left: 2.6rem; }
.at-frise--statique .at-etape__pastille { position: absolute; left: 0; margin-top: 0; }
.at-frise--statique .at-etape,
.at-frise--statique .at-etape__nom,
.at-frise--statique .at-etape__texte { position: relative; color: inherit; }

/* ------------------------------------------------------------
   5. LES REPÈRES — chiffres qui montent au passage
   ------------------------------------------------------------ */
.at-reperes { background: var(--ivoire); }
.at-reperes__grille {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: clamp(1.6rem, 4vw, 3rem); text-align: center;
}
.at-repere { position: relative; padding: 0 1rem; }
/* Filet séparateur entre deux repères, jamais avant le premier. */
.at-repere + .at-repere::before {
  content: ""; position: absolute; left: 0; top: 12%; bottom: 12%; width: 1px;
  background: linear-gradient(transparent, rgba(176,141,87,.4) 25%, rgba(176,141,87,.4) 75%, transparent);
}
.at-repere__nombre {
  font-family: var(--serif); font-size: clamp(2.8rem, 6vw, 4.2rem);
  line-height: 1; color: var(--or); letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;   /* le compteur ne doit pas gigoter */
}
.at-repere__nombre small { font-size: .45em; margin-left: .1em; }
.at-repere__libelle {
  margin-top: .8rem;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .24em;
  color: var(--brun-doux);
}
@media (max-width: 620px) { .at-repere + .at-repere::before { display: none; } }

/* ------------------------------------------------------------
   6. LA MOSAÏQUE — grille asymétrique et parallaxe
   ------------------------------------------------------------
   Motif fixe de 7 cases : deux hautes, une large, quatre carrées. Les
   images glissent légèrement à contre-scroll dans leur cadre, ce qui
   suffit à donner de la profondeur sans que rien ne bouge vraiment.  */

.at-mosaique { background: var(--creme); }
.at-mosaique__grille {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 15vw;
  gap: clamp(.7rem, 1.4vw, 1.1rem);
}
.at-case { position: relative; overflow: hidden; background: var(--ivoire); }
.at-case:nth-child(1) { grid-column: span 2; grid-row: span 2; }
.at-case:nth-child(4) { grid-row: span 2; }
.at-case:nth-child(6) { grid-column: span 2; }
/* Le cadre gravé, révélé au survol comme sur .carte-billet. */
.at-case::after {
  content: ""; position: absolute; inset: 8px; z-index: 2; pointer-events: none;
  border: 1px solid rgba(250,246,239,0);
  transition: inset .9s cubic-bezier(.22,.61,.36,1), border-color .9s cubic-bezier(.22,.61,.36,1);
}
.at-case:hover::after { inset: 12px; border-color: rgba(250,246,239,.42); }
/* L'image déborde de 12% en haut et en bas : c'est cette réserve que
   la parallaxe consomme, sinon le cadre se viderait par un bord. */
.at-case__img {
  position: absolute; top: -12%; left: 0; width: 100%; height: 124%;
  object-fit: cover;
  transition: transform 1.2s cubic-bezier(.22,.61,.36,1), filter .9s;
  filter: saturate(.9);
  will-change: transform;
}
.at-case:hover .at-case__img { filter: saturate(1.05); }
/* Une case « pièce » est cliquable en entier : le lien couvre le cadre, par
   dessus le voile, plutôt que d'envelopper l'image (ce qui casserait la
   géométrie de la parallaxe). Les cases « photo » n'en ont pas. */
.at-case__lien { position: absolute; inset: 0; z-index: 2; }
.at-case__voile {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 1.2rem 1.3rem;
  background: linear-gradient(transparent 45%, rgba(46,38,32,.72));
  opacity: 0; transition: opacity .7s cubic-bezier(.22,.61,.36,1);
}
.at-case:hover .at-case__voile { opacity: 1; }
.at-case__legende {
  color: var(--ivoire); font-family: var(--serif); font-size: 1.25rem;
  transform: translateY(10px); transition: transform .7s cubic-bezier(.22,.61,.36,1);
}
.at-case__matiere {
  color: var(--or-clair); font-size: .7rem; text-transform: uppercase; letter-spacing: .22em;
  transform: translateY(10px); transition: transform .7s cubic-bezier(.22,.61,.36,1) .06s;
}
.at-case:hover .at-case__legende, .at-case:hover .at-case__matiere { transform: none; }

@media (max-width: 900px) {
  .at-mosaique__grille { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 32vw; }
  .at-case:nth-child(1) { grid-column: span 2; grid-row: span 1; }
  .at-case:nth-child(4) { grid-row: span 1; }
  .at-case:nth-child(6) { grid-column: span 2; }
}

/* ------------------------------------------------------------
   7. LE CERTIFICAT — carton incliné et dorure qui balaie
   ------------------------------------------------------------
   Le bloc sombre actuel énonce une promesse en texte plat. Ici le
   certificat devient un objet : il s'incline de quelques degrés sous
   la souris (JS écrit --rx/--ry) et un reflet de dorure traverse son
   liseré au survol, comme un marquage à chaud.                      */

.at-certificat { position: relative; background: var(--brun); color: var(--ivoire); overflow: hidden; }
.at-certificat::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 55% 60% at 68% 45%, rgba(176,141,87,.20), transparent 70%);
}
.at-certificat__grille {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(2.4rem, 6vw, 5rem); align-items: center;
}
.at-certificat .sur-titre { color: var(--or-clair); }
.at-certificat h2 { color: var(--ivoire); }
.at-certificat h2 em { font-style: italic; color: var(--or-clair); }
.at-certificat p { color: rgba(243,236,223,.72); max-width: 44ch; }

.at-carton-scene { perspective: 1100px; }
.at-carton {
  --rx: 0deg; --ry: 0deg;
  position: relative;
  aspect-ratio: 1/1.41;                /* format A, c'est un document */
  max-width: 24rem; margin: 0 auto;
  padding: clamp(1.6rem, 3vw, 2.4rem);
  display: flex; flex-direction: column; justify-content: space-between;
  text-align: center;
  background: linear-gradient(158deg, #f7f1e6, var(--ivoire) 40%, #efe6d6);
  color: var(--brun);
  border: 1px solid rgba(176,141,87,.45);
  box-shadow: 0 40px 80px -40px rgba(0,0,0,.7);
  transform: rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform .5s cubic-bezier(.22,.61,.36,1), box-shadow .6s;
  transform-style: preserve-3d;
}
.at-carton:hover { box-shadow: 0 52px 96px -42px rgba(0,0,0,.78); }
.at-carton::before {
  content: ""; position: absolute; inset: 9px; pointer-events: none;
  border: 1px solid rgba(176,141,87,.35);
}
/* La dorure : une bande claire, très inclinée, qui traverse le carton.
   Au repos elle est hors-champ à gauche. */
.at-carton::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(255,252,244,.85) 47%,
              rgba(211,183,135,.55) 52%, transparent 62%);
  transform: translateX(-115%);
  transition: transform 1.15s cubic-bezier(.32,.06,.28,1);
  mix-blend-mode: screen;
}
.at-carton:hover::after { transform: translateX(115%); }

.at-carton__entete { font-size: .62rem; text-transform: uppercase; letter-spacing: .3em; color: var(--or); }
.at-carton__corps { display: flex; flex-direction: column; align-items: center; gap: .3rem; }
.at-carton__titre { font-family: var(--serif); font-size: clamp(1.5rem, 3vw, 2rem); line-height: 1.15; }
.at-carton__ref { font-size: .68rem; letter-spacing: .2em; color: var(--brun-doux); }
.at-carton__filet { width: 46px; height: 1px; background: var(--or); margin: .7rem 0; }
.at-carton__essence { font-family: var(--serif); font-style: italic; font-size: 1.05rem; color: var(--brun-doux); }
/* Le QR, dessiné en CSS : une grille de modules, pas une image. C'est
   un gabarit de maquette — à remplacer par le vrai QR de la pièce. */
.at-carton__qr {
  width: 4.6rem; height: 4.6rem; margin: 0 auto;
  background:
    conic-gradient(from 0deg, var(--brun) 25%, transparent 0 50%, var(--brun) 0 75%, transparent 0),
    conic-gradient(from 90deg, var(--brun) 25%, transparent 0 50%, var(--brun) 0 75%, transparent 0);
  background-size: 0.92rem 0.92rem, 0.46rem 0.46rem;
  opacity: .82;
  border: 3px solid var(--brun);
}
.at-carton__signature {
  font-family: var(--serif); font-style: italic; font-size: 1.15rem; color: var(--brun);
  border-top: 1px solid rgba(176,141,87,.35); padding-top: .7rem;
}

@media (max-width: 860px) {
  .at-certificat__grille { grid-template-columns: 1fr; }
  .at-carton { max-width: 20rem; }
}

/* ------------------------------------------------------------
   RÉVÉLATIONS AU DÉFILEMENT
   ------------------------------------------------------------
   Même parti pris que journal-reveal.js : l'état de repos est posé
   par JS via .at-reveal, jamais en dur. Sans JS, rien n'est caché.  */
/* L'état caché porte sur --arme, classe ajoutée par le JS : si le script
   ne tourne pas, .at-reveal seul ne masque rien. */
.at-reveal--arme {
  opacity: 0; transform: translateY(24px);
  transition: opacity 1.3s cubic-bezier(.22,.61,.36,1),
              transform 1.3s cubic-bezier(.22,.61,.36,1);
}
.at-reveal--arme.est-visible { opacity: 1; transform: none; }

/* ------------------------------------------------------------
   MOUVEMENT RÉDUIT
   ------------------------------------------------------------
   Tout ce qui bouge tout seul s'arrête, tout ce qui est révélé reste
   visible. La page garde ses cadres, ses filets et ses couleurs.    */
@media (prefers-reduced-motion: reduce) {
  .at-heros { height: auto; }
  .at-heros__cadre { position: relative; height: 100vh; }
  .at-heros__lampe, .at-heros__indice::after { animation: none; }
  .at-heros__filet { width: 220px; }
  .at-ruban__piste { animation: none; transform: none; }
  .at-triptyque__media { position: relative; top: auto; }
  .at-reveal--arme, .at-temps__filet, .at-frise__rail span { opacity: 1; transform: none; transition: none; }
  .at-etape__duree { opacity: 1; }
  .at-carton, .at-carton::after, .at-case__img, .at-case__voile,
  .at-case__legende, .at-case__matiere, .at-essence__visuel img { transition: none; }
  .at-carton { transform: none; }
}

/* ---------- Pied de page ---------- */
.pied-site { background: var(--brun); color: var(--creme); margin-top: 4rem; }
.pied-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 2.5rem; padding: 3.5rem 1.4rem 2.5rem; }
.pied-titre { font-size: 1.25rem; color: var(--or-clair); margin-bottom: .8rem; }
.pied-site a { color: var(--or-clair); }
.pied-site a:hover { color: var(--ivoire); }
.pied-discret { font-size: .8rem; color: rgba(243,236,223,.55); }
.pied-bas { border-top: 1px solid rgba(243,236,223,.15); padding: 1.1rem 0; font-size: .82rem; color: rgba(243,236,223,.6); }
.pied-reseaux { display: flex; flex-wrap: wrap; gap: .7rem; margin-bottom: 1rem; }
.pied-reseau {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.4rem; height: 2.4rem; border-radius: 50%;
  border: 1px solid rgba(243,236,223,.25); color: var(--or-clair);
  transition: color .2s, border-color .2s, background .2s, transform .2s;
}
.pied-reseau svg { width: 1.15rem; height: 1.15rem; display: block; }
.pied-reseau:hover { color: var(--brun); background: var(--or-clair); border-color: var(--or-clair); transform: translateY(-2px); }

/* ---------- Responsive ---------- */
@media (max-width: 860px) {
  .burger { display: block; }
  .entete-interieur { padding: 1rem 1rem; }
  .logo { height: 48px; margin: -.6rem 0; }
  .marque { gap: .7rem; }
  .nom-marque { font-size: 1.25rem; }
  .slogan { font-size: .55rem; letter-spacing: .14em; }
  .nav-site {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    background: var(--ivoire); flex-direction: column; padding: 1.4rem;
    border-bottom: 1px solid rgba(176,141,87,.3); gap: 1.1rem;
  }
  .nav-site.ouvert { display: flex; }
  .fiche { grid-template-columns: 1fr; gap: 2rem; }
}
