/* ==========================================================================
   Styles spécifiques aux 4 séquences vidéo.
   - Hero : video/video9.mp4 plein écran en fond, boucle ping-pong, titre
     "Le Café" / "Boutique" en overlay, chacun sur sa moitié d'un même
     arc SVG (<textPath>), espace vide au centre au-dessus de la vapeur,
     grand dôme sur desktop (les mots retombent à côté de la tasse) vs
     dôme plat sur mobile (SVG dédié, pas un simple scale) — pas de
     carte de fond ni d'ombre portée, texte marron uni (les deux mots
     dans la même couleur).
   - Salon de Thé / Bar à Chaussettes / Épicerie Fine : vidéo plein écran en
     arrière-plan, badge + titre + texte descriptif regroupés en overlay
     latéral directement sur la vidéo (pas de carte de fond, lisibilité via
     ombre portée seule), alternant gauche/droite d'une section à l'autre
     (Thé: gauche, Chaussettes: droite, Épicerie: gauche). Chaque vidéo est
     un <video muted playsinline> déclenché en JS à l'entrée dans le
     viewport (voir js/utils/autoplay-video.js), puis en boucle ping-pong
     comme le hero (voir js/utils/pingpong-video.js) — aucun
     scroll-scrubbing, aucun canvas.
   Dans tous les cas, la vidéo est plafonnée à sa résolution native
   (1904×1088) via max-width/max-height + aspect-ratio : jamais agrandie
   au-delà, donc jamais floue, quelle que soit la taille de l'écran.
   ========================================================================== */

/* Ping-pong sans seek (voir js/utils/pingpong-video.js) : la vidéo "revers"
   (video/*-reverse.mp4) est superposée exactement à sa vidéo forward —
   même classe de taille (.hero__video / .video-section__video) partagée,
   mais positionnée en absolu + centrée par inset:0/margin:auto (au lieu du
   flex du parent, comme la forward) pour occuper très exactement le même
   espace. Bascule visible/masquée par opacity (jamais display:none, pour
   ne pas couper son préchargement en arrière-plan pendant qu'elle attend
   son tour) — un simple ajout/retrait de classe, pas de transition/fondu :
   revers et forward partagent la même image à la frontière (dernière frame
   forward = première frame revers, par construction), donc une bascule
   instantanée suffit à rester fluide, sans qu'un fondu croisé n'introduise
   un effet de fantôme. */
.pingpong-video--reverse {
  position: absolute;
  inset: 0;
  margin: auto;
}

.is-hidden {
  opacity: 0;
}

/* --- Hero --------------------------------------------------------------
   video/video9.mp4 en fond plein écran (même traitement que les 3 sections
   suivantes : full-bleed, object-fit: cover, plafonné à sa résolution
   native), en boucle infinie aller-retour (ping-pong, seule séquence du
   site à utiliser cet effet — voir js/utils/pingpong-video.js). Le titre
   "Le Café Boutique" est en overlay, courbé en SVG et ancré au-dessus
   de la tasse/vapeur (voir .hero__title-wrap plus bas) — pas de carte
   de fond ni d'ombre portée, contrairement aux panneaux de texte des
   3 sections suivantes (qui gardent leur halo d'ombre, nécessaire là où
   le texte peut tomber sur une zone sombre de l'illustration). */
.hero {
  position: relative;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-cream-deep);
}

.hero__bg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero__video {
  width: 100%;
  height: 100%;
  max-width: 1904px;
  max-height: 1088px;
  aspect-ratio: 1904 / 1088;
  object-fit: cover;
  display: block;
}

/* Titre en overlay, courbé le long d'un arc SVG (même galbe que le haut de
   la tasse/la vapeur en arrière-plan) via <textPath> — technique la plus
   robuste cross-browser pour du texte sur une courbe (bien plus fiable que
   `offset-path` par lettre). Pas de carte de fond, pas de contour
   "autocollant", pas d'ombre portée : texte marron uni, net (retour
   utilisateur explicite — la vidéo/fond crème suffit à la lisibilité ici).
   "Le Café" et "Boutique" suivent chacun leur moitié de l'arc, avec un espace
   vide au centre (au-dessus du filet de vapeur) — pas un seul mot continu.

   Échelle et position : un vrai titre de hero, pas une légende — cf. retour
   utilisateur après une 1ère version jugée trop petite/tassée. Sur desktop,
   la tasse est plus étroite que l'écran (bords vides de part et d'autre) :
   le dôme est donc large et profond, et les deux mots retombent dans cet
   espace libre à côté de la tasse plutôt que d'être coincés entre le header
   et la vapeur. Sur mobile, la vidéo ne rogne qu'horizontalement (jamais
   verticalement — voir .hero__video) : la tasse occupe quasi toute la
   largeur de l'écran, donc plus d'espace libre sur les côtés. Deux SVG
   distincts (desktop/mobile, bascule par media query) plutôt qu'un simple
   agrandissement uniforme : le mobile utilise un dôme bien plus plat, tenu
   dans la seule bande libre au-dessus de la vapeur. */
.hero__title-wrap {
  position: absolute;
  top: calc(var(--header-height) + 8px);
  left: 0;
  /* La tasse n'est pas exactement centrée dans la vidéo source (mesuré par
     analyse de pixels : centre de la tasse à 902.5px sur 1904px de large,
     soit 49.5px à gauche du centre réel de la vidéo). Comme la vidéo est
     recadrée symétriquement (object-fit: cover) et que sa hauteur affichée
     = hauteur du viewport (jamais rognée verticalement — voir .hero__video),
     ce décalage se traduit à l'écran par 49.5/1088 = 4.55% de la hauteur de
     viewport, quelle que soit sa taille (desktop ou mobile). D'où le
     `right` asymétrique ci-dessous (2x ce décalage) plutôt que 0 : recentre
     le titre sur la tasse plutôt que sur le viewport, sans passer par
     `transform` (qui entrerait en conflit avec l'animation [data-reveal],
     laquelle anime déjà `transform: translateY(...)` — voir content.css). */
  right: 9.1vh;
  z-index: 2;
  display: flex;
  justify-content: center;
}

/* Cartouche "produit du moment" sous la tasse : même repère horizontal
   que .hero__title-wrap ci-dessus (right: 9.1vh, recentré sur la tasse
   plutôt que sur le viewport). Verticalement, la vidéo n'étant jamais
   rognée en hauteur (object-fit: cover, hauteur = 100% du viewport —
   voir .hero__video), une position en vh reste alignée sur le même
   point de la tasse quelle que soit la taille d'écran : mesuré sur la
   vidéo source, le bas de la tasse se situe vers 72-73% de la hauteur,
   les icônes de fond (bocal, poisson) vers 78-86% — 82vh élargit
   davantage l'espace sous la tasse tout en restant avant cette zone. */
.hero__badge-wrap {
  position: absolute;
  top: 82vh;
  left: 0;
  right: 9.1vh;
  z-index: 2;
  display: flex;
  justify-content: center;
}

.hero__title-svg {
  width: auto;
  height: auto;
  display: block;
  overflow: visible;
}

.hero__title-svg--desktop {
  max-width: min(74vw, 1180px);
  max-height: 25vh;
  aspect-ratio: 1400 / 240;
}

.hero__title-svg--mobile {
  display: none;
  max-width: min(94vw, 620px);
  max-height: 13vh;
  aspect-ratio: 700 / 140;
}

@media (max-width: 640px) {
  .hero__title-svg--desktop {
    display: none;
  }
  .hero__title-svg--mobile {
    display: block;
  }
}

.hero__title-text {
  font-family: 'Baloo 2', sans-serif;
  font-weight: 700;
}

.hero__title-svg--desktop .hero__title-text {
  font-size: 130px;
  stroke-width: 4px;
}

.hero__title-svg--mobile .hero__title-text {
  font-size: 68px;
  stroke-width: 2px;
}

/* Contour vert fin autour des lettres, remplissage marron inchangé.
   paint-order: stroke fill place le trait SOUS le remplissage (peint
   d'abord), pour qu'il ne mange pas sur le marron et reste net aux angles
   des lettres — sans ça, un stroke SVG classique est centré sur le tracé
   et empiète pour moitié sur le fill, épaississant/déformant les lettres
   fines. stroke-width défini ci-dessus par breakpoint (desktop/mobile),
   proportionnellement à leur font-size respectif (même unités que le
   viewBox de chaque SVG), pour un trait fin cohérent aux deux tailles. */
.hero__title-text--brown {
  fill: var(--color-brown);
  stroke: #000;
  paint-order: stroke fill;
}

/* --- Sections vidéo plein écran (Thé / Chaussettes / Épicerie) ----------- */
.video-section {
  position: relative;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-cream-deep);
}

.video-section__bg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.video-section__video {
  width: 100%;
  height: 100%;
  max-width: 1904px;
  max-height: 1088px;
  aspect-ratio: 1904 / 1088;
  object-fit: cover;
  display: block;
}

/* Titre : badge "eyebrow" + <h2>, directement en overlay sur la vidéo
   (pas de carte/fond derrière — retour utilisateur explicite après une
   version jugée trop "encadrée"). Lisibilité assurée par un halo d'ombre
   portée crème (text-shadow empilé : rayons courts et opaques pour un
   contour net + rayons larges pour un halo diffus), pas par un bloc plein.
   Nécessaire y compris sur les zones sombres de l'illustration (ex. la
   boîte à thé en gros plan sur mobile) — un halo trop léger y devient
   illisible, constaté en testant. */
.video-section__eyebrow {
  display: inline-block;
  font-family: var(--font-subtitle);
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-green);
  margin-bottom: 6px;
  text-shadow:
    0 0 2px rgba(253, 251, 247, 1),
    0 0 5px rgba(253, 251, 247, 1),
    0 0 10px rgba(253, 251, 247, 0.9),
    0 0 18px rgba(253, 251, 247, 0.8);
}

.video-section__title {
  font-family: var(--font-title);
  font-size: clamp(1.8rem, 4.5vw, 3rem);
  color: var(--color-brown);
  margin-bottom: 14px;
  text-shadow:
    0 0 3px rgba(253, 251, 247, 1),
    0 0 7px rgba(253, 251, 247, 1),
    0 0 14px rgba(253, 251, 247, 0.9),
    0 0 24px rgba(253, 251, 247, 0.8);
}

/* Panneau de texte : overlay latéral (gauche ou droite selon la section),
   directement sur la vidéo — pas de carte/fond derrière (retour utilisateur
   explicite). Centré verticalement via flexbox (pas via transform) pour ne
   pas entrer en conflit avec l'animation d'apparition [data-reveal], qui
   anime elle aussi "transform" (translateY) — voir content.css. */
.video-section__panel {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  max-width: 400px;
}

.video-section__panel--left {
  left: clamp(20px, 6vw, 88px);
}

.video-section__panel--right {
  right: clamp(20px, 6vw, 88px);
}

.video-section__panel-card {
  padding: 30px 32px;
}

.video-section__description {
  font-family: var(--font-title);
  font-size: clamp(1rem, 1.5vw, 1.1rem);
  line-height: 1.65;
  color: var(--color-brown);
  text-shadow:
    0 0 2px rgba(253, 251, 247, 1),
    0 0 5px rgba(253, 251, 247, 1),
    0 0 10px rgba(253, 251, 247, 0.9),
    0 0 18px rgba(253, 251, 247, 0.85);
}

/* Second paragraphe de description (ex. mention de partenariat, voir
   Épicerie Fine) : même style, juste séparé du premier par le même
   espacement que celui déjà utilisé entre le titre et la description
   (.video-section__title { margin-bottom: 14px }), pour rester dans le
   même rythme vertical du bloc. */
.video-section__description + .video-section__description {
  margin-top: 14px;
}

@media (max-width: 780px) {
  /* Mobile : le panneau quitte le côté gauche/droite pour se poser en bas,
     pleine largeur — pas de sens de garder l'alternance sur un écran étroit.
     "top: auto" (au lieu de 0) fait que la boîte ne s'étire plus sur toute
     la hauteur : elle redevient hauteur-auto, ancrée par "bottom". */
  .video-section__panel,
  .video-section__panel--left,
  .video-section__panel--right {
    left: 16px;
    right: 16px;
    top: auto;
    bottom: 24px;
    max-width: none;
  }
}

/* Colonne de 4 photos à droite du bloc panier/texte (Épicerie) — même
   style de cadre que les cartes de la galerie 3D (voir .galerie__card
   dans content.css : border-radius, bordure marron, ombre portée
   réutilisés tels quels). Simple empilement statique ici (pas de
   rotation/3D), symétrique à .video-section__panel--right (même valeur
   de right). */
.epicerie__photos {
  position: absolute;
  top: 0;
  bottom: 0;
  right: clamp(20px, 8vw, 120px);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

/* Piège évité : si c'est la CARTE (.epicerie__photo) elle-même qui
   devient position:fixed et se recentre au survol, elle s'échappe de
   sous le curseur — :hover s'arrête aussitôt (plus rien sous la souris),
   la carte revient à sa place, le curseur s'y retrouve, :hover repart...
   un clignotement en boucle (constaté). La carte reste donc le
   déclencheur du survol, immobile dans la colonne ; seule l'<img> à
   l'intérieur devient fixed/recentrée comme une lightbox — le curseur
   reste en permanence au-dessus de la carte (qui n'a pas bougé), donc
   :hover ne se coupe jamais pendant que l'image grandit. */
.epicerie__photo {
  position: relative;
  width: clamp(130px, 13vw, 190px);
  aspect-ratio: 4 / 3;
  margin: 0;
  border-radius: 12px;
  border: 3px solid var(--color-brown);
  box-shadow: 0 10px 24px rgba(99, 53, 19, 0.2);
  background: var(--color-cream);
}

.epicerie__photo img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 9px;
  transition: width 0.25s ease, height 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

/* Fond semi-transparent derrière la photo agrandie, pour la détacher du
   reste de la page — un seul ::before par carte, invisible (opacity: 0,
   pointer-events: none) tant qu'elle n'est pas survolée. Reste sur la
   carte (déclencheur stable du survol), pas sur l'image qui se déplace. */
.epicerie__photo::before {
  content: '';
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  z-index: 998;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

/* .is-active : équivalent tactile de :hover, posé par
   js/utils/photo-lightbox.js au tap (uniquement sur les appareils sans
   vrai hover — voir ce fichier), puisque :hover seul n'est pas fiable au
   doigt sur mobile. */
.epicerie__photo:hover::before,
.epicerie__photo.is-active::before {
  opacity: 1;
}

/* L'image détachée porte son propre cadre (bordure/ombre) : une fois
   position: fixed, elle n'est plus visuellement "dans" la carte d'origine
   (qui garde la sienne, inchangée, dans la colonne), donc le cadre doit
   être répété ici pour rester cohérent avec le reste de la charte. */
.epicerie__photo:hover img,
.epicerie__photo.is-active img {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 60vw;
  height: auto;
  max-width: 800px;
  aspect-ratio: 4 / 3;
  transform: translate(-50%, -50%);
  z-index: 999;
  border-radius: 9px;
  border: 3px solid var(--color-brown);
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.45);
}

@media (max-width: 780px) {
  /* Le panneau texte (voir règle ci-dessus) descend en bas d'écran sur
     mobile ; les 4 photos passent en grille 2x2, ancrées en haut de
     section (sous le header) plutôt qu'à droite — l'alternance gauche/
     droite façon desktop n'a pas de sens sur un écran étroit, et une
     grille compacte en haut laisse le panneau respirer en bas sans que
     les deux se chevauchent. */
  .epicerie__photos {
    top: calc(var(--header-height) + 16px);
    bottom: auto;
    left: 16px;
    right: 16px;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    max-width: 280px;
    margin: 0 auto;
  }

  .epicerie__photo {
    width: 100%;
  }
}

/* Colonne de 3 photos à gauche du bloc texte (Bar à Chaussettes) — même
   traitement que .epicerie__photos/.epicerie__photo (voir ci-dessus :
   cadre identique, agrandissement de base identique, effet de survol en
   lightbox identique), en miroir horizontal (left au lieu de right,
   panneau texte à droite ici — voir .video-section__panel--right).
   gap: 12px, même espacement régulier que sur épicerie (le gap à 24px
   n'était qu'une compensation pour les 2 premières photos, plus
   nécessaire à 3). Ne PAS ajouter data-reveal sur .chaussettes__photos :
   un transform sur cet ancêtre (même résolu à l'identité) créerait un
   nouveau contexte de positionnement pour l'<img> en position:fixed au
   survol, cassant son centrage sur le viewport (bug rencontré et corrigé
   sur épicerie — voir plus haut). */
.chaussettes__photos {
  position: absolute;
  top: 0;
  bottom: 0;
  left: clamp(20px, 8vw, 120px);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.chaussettes__photo {
  position: relative;
  width: clamp(130px, 13vw, 190px);
  aspect-ratio: 4 / 3;
  margin: 0;
  border-radius: 12px;
  border: 3px solid var(--color-brown);
  box-shadow: 0 10px 24px rgba(99, 53, 19, 0.2);
  background: var(--color-cream);
}

.chaussettes__photo img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 9px;
  transition: width 0.25s ease, height 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

.chaussettes__photo::before {
  content: '';
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  z-index: 998;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

.chaussettes__photo:hover::before,
.chaussettes__photo.is-active::before {
  opacity: 1;
}

.chaussettes__photo:hover img,
.chaussettes__photo.is-active img {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 60vw;
  height: auto;
  max-width: 800px;
  aspect-ratio: 4 / 3;
  transform: translate(-50%, -50%);
  z-index: 999;
  border-radius: 9px;
  border: 3px solid var(--color-brown);
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.45);
}

@media (max-width: 780px) {
  /* Même principe que pour épicerie : sur mobile, la colonne quitte le
     côté gauche pour se poser en haut de section (sous le header), en
     rangée de 2 (repeat(2,1fr) donne naturellement une seule ligne pour
     2 éléments) ; le panneau texte descend en bas d'écran (voir la media
     query générale plus haut). */
  .chaussettes__photos {
    top: calc(var(--header-height) + 16px);
    bottom: auto;
    left: 16px;
    right: 16px;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    max-width: 280px;
    margin: 0 auto;
  }

  .chaussettes__photo {
    width: 100%;
  }
}

/* Colonne de 3 photos à droite du bloc texte/théière (Salon de Thé &
   Barista) — même traitement que .epicerie__photos/.epicerie__photo et
   .chaussettes__photos/.chaussettes__photo (cadre, agrandissement de
   base, effet de survol en lightbox identiques), même sens que sur
   épicerie (right, panneau texte à gauche ici — voir
   .video-section__panel--left). gap: 12px, espacement régulier comme sur
   épicerie/chaussettes. Ne PAS ajouter data-reveal sur .the__photos —
   même piège que sur épicerie/chaussettes (un transform sur cet ancêtre
   casserait le centrage de l'<img> en position:fixed au survol). */
.the__photos {
  position: absolute;
  top: 0;
  bottom: 0;
  right: clamp(20px, 8vw, 120px);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.the__photo {
  position: relative;
  width: clamp(130px, 13vw, 190px);
  aspect-ratio: 4 / 3;
  margin: 0;
  border-radius: 12px;
  border: 3px solid var(--color-brown);
  box-shadow: 0 10px 24px rgba(99, 53, 19, 0.2);
  background: var(--color-cream);
}

.the__photo img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 9px;
  transition: width 0.25s ease, height 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

.the__photo::before {
  content: '';
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  z-index: 998;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

.the__photo:hover::before,
.the__photo.is-active::before {
  opacity: 1;
}

.the__photo:hover img,
.the__photo.is-active img {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 60vw;
  height: auto;
  max-width: 800px;
  aspect-ratio: 4 / 3;
  transform: translate(-50%, -50%);
  z-index: 999;
  border-radius: 9px;
  border: 3px solid var(--color-brown);
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.45);
}

@media (max-width: 780px) {
  /* Même principe que pour épicerie/chaussettes : sur mobile, la colonne
     quitte le côté droit pour se poser en haut de section (sous le
     header), en grille 2x2 (3 éléments : 2 sur la première ligne, 1 sur
     la seconde) ; le panneau texte descend en bas d'écran (voir la media
     query générale plus haut). */
  .the__photos {
    top: calc(var(--header-height) + 16px);
    bottom: auto;
    left: 16px;
    right: 16px;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    max-width: 280px;
    margin: 0 auto;
  }

  .the__photo {
    width: 100%;
  }
}
