/* ==========================================================================
   Habillage "page posée sur fond blanc"
   Pour désactiver cette fonctionnalité : retirer la ligne
   {{ 'upgrade.css' | stylesheet_tag }} dans app/views/pages/index.liquid
   ========================================================================== */

/* Titres de section (Selected Works, Works, Bio, Contact) légèrement
   adoucis, pour rester dans la même direction "douce" que le reste
   (panneaux semi-transparents, logo assourci). Pour désactiver : remettre
   à 1. */

h2.text-shadow.font-gotham.uppercase {
  opacity: 0.8;
}

:root {
  --site-card-max-width: 1000px;
  --site-card-shadow: 0 2px 14px rgba(0, 0, 0, 0.24);
  /* hauteur native de fd01.jpg : les raccords entre copies de l'image
     tombent tous les 1200px, on y feathère un fondu pour les rendre
     invisibles (voir .site-wrap ci-dessous) */
  --cloud-tile-height: 1200px;
  --cloud-seam-feather: 110px;
}

html {
  background: #ffffff;
}

body {
  /* la texture nuages/aquarelle est déplacée du body vers .site-wrap,
     mais reste rigoureusement identique (même image, même répétition) */
  background: #ffffff;
  margin: 0px;
}

.site-wrap {
  position: relative;
  max-width: var(--site-card-max-width);
  margin: 0 auto;
  box-shadow: var(--site-card-shadow);
  /* "clip" masque le débordement de la couche de fond sans créer de
     conteneur scrollable ("hidden" le fait, ce qui cassait
     videoPlayer.scrollIntoView() : il scrollait .site-wrap au lieu de
     la page et le logo disparaissait). Mais "clip" seul n'empêche pas
     les marges des enfants (mt-4, my-8, ...) de "traverser" la carte
     et créer un espace blanc en haut/bas — d'où "flow-root", qui gère
     spécifiquement ce point sans aucun effet de bord sur le scroll. */
  overflow: clip;
  display: flow-root;
}

/* Couche de fond séparée : texture nuages + voile blanc doux répété
   tous les 1200px (hauteur de l'image) pour fondre les raccords entre
   les copies de l'image. Déplacée via "transform" (accéléré par la
   carte graphique, fluide) par public/javascripts/upgrade-parallax.js
   pour le léger effet de parallax — voir ce fichier pour activer/
   désactiver ou régler la vitesse. top/height par défaut ci-dessous
   sont un repli correct si le JS ne s'exécute pas (pas de parallax,
   mais pas de trou visible non plus). */
.site-wrap__bg {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 100%;
  background-image:
    repeating-linear-gradient(
      to bottom,
      rgba(255, 255, 255, 0.6) 0,
      rgba(255, 255, 255, 0) var(--cloud-seam-feather),
      rgba(255, 255, 255, 0) calc(var(--cloud-tile-height) - var(--cloud-seam-feather)),
      rgba(255, 255, 255, 0.6) var(--cloud-tile-height)
    ),
    url(/sites/4c082a9393d4330812000002/theme/images/fd01.jpg?1790763859);
  background-repeat: repeat-y, repeat-y;
  background-position: center top, center top;
  will-change: transform;
  pointer-events: none;
  z-index: 0;
}

.site-wrap > *:not(.site-wrap__bg) {
  position: relative;
  z-index: 1;
}

@media (max-width: 767px) {
  .site-wrap {
    box-shadow: none;
  }
}

/* ==========================================================================
   Lecteur vidéo : fond noir + spinner de chargement (au lieu du flash
   gris par défaut du navigateur), avec un fondu enchaîné entre l'ancienne
   et la nouvelle vidéo (voir upgrade-video-loading.js pour la durée).
   Pour désactiver : retirer la classe "video-frame" ajoutée sur le div
   vidéo dans index.liquid (et la ligne upgrade-video-loading.js).
   ========================================================================== */
.video-frame {
  background: #000;
  /* la hauteur est verrouillée en JS (upgrade-video-loading.js) sur la
     taille réelle de la vidéo affichée, pour qu'aucun changement de
     vidéo ne fasse "sauter" le reste de la page. "clip" et non
     "hidden" : ne crée jamais de conteneur scrollable, cf. .site-wrap
     plus haut pour la même remarque. */
  overflow: clip;
}

.video-frame video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
  display: block;
}

.video-frame__spinner {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.video-frame.is-loading .video-frame__spinner {
  display: flex;
}

.video-frame__spinner::after {
  content: '';
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.25);
  border-top-color: #ffffff;
  animation: video-frame-spin 0.8s linear infinite;
}

@keyframes video-frame-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Calque éphémère pour activer le son au premier clic (desktop, lecture
   automatique muette — voir upgrade-hero-autoplay.js) : retiré du DOM
   dès qu'il a servi, pour laisser les clics suivants atteindre la vidéo
   normalement (pause/lecture natives). */
.video-frame__click-catcher {
  position: absolute;
  inset: 0;
  z-index: 2;
  cursor: pointer;
}

/* ==========================================================================
   Animation d'ouverture (une fois par session, voir upgrade-intro.js) :
   1) écran blanc, seul le motif ornemental du haut du logo est visible
      (masqué par hauteur) ; 2) il se déplie pour révéler le texte + la
      ligne du bas, pendant que le bloc logo remonte légèrement ; 3) le
      logo s'efface symétriquement depuis ses deux bords vers le centre
      (clip-path, jamais de scale — pas de déformation du dessin) ; 4) une
      fois le logo entièrement refermé, une fine ligne verticale prend le
      relais à sa place puis s'étend jusqu'à couvrir tout l'écran ; 5) les
      deux moitiés du voile blanc reculent chacune vers son propre bord
      RÉEL d'écran (celui de la carte, pas celui du viewport) — la
      révélation part donc du centre et s'étend vers l'extérieur, PAS
      l'inverse —, pendant que les vignettes "Sélection" (+ vidéo
      principale) apparaissent en pop échelonné.

   Pas d'ombre "fabriquée" sur les panneaux : .site-wrap garde sa vraie
   ombre en permanence (jamais cachée, seulement recouverte par ces
   panneaux blancs opaques) — elle se révèle donc toute seule au fur et
   à mesure qu'ils reculent, exactement comme le reste du contenu, sans
   avoir besoin d'apparaître ni d'être repositionnée.

   Le voile blanc est composé de DEUX panneaux indépendants
   (.intro-overlay__panel--left/--right, chacun la moitié de l'écran) au
   lieu d'un seul élément : un clip-path unique ne peut pas représenter
   "un trou qui grandit au centre" (il ne peut définir qu'UN rectangle),
   d'où la nécessité de deux éléments qui reculent chacun vers son bord
   (transform:scaleX depuis leur propre bord extérieur, voir
   upgrade-intro.js). La page réelle en dessous (.site-wrap) n'a besoin
   d'aucun état caché propre, elle est juste masquée par ces panneaux.
   La ligne (.intro-overlay__seam) est un enfant du voile, centrée : elle
   reste donc visible tant que les panneaux ne l'ont pas dépassée.

   .intro-active sur <html> (posée en JS, AVANT le rendu du <body>, pour
   éviter tout flash) cache seulement les vignettes tant que l'animation
   tourne. Sans JS (ou classe jamais posée), rien n'est caché : la page
   s'affiche normalement.

   Pour désactiver définitivement : retirer la ligne
   {{ 'upgrade-intro.js' | javascript_tag }} dans index.liquid (la classe
   intro-active ne sera alors jamais posée, la page s'affiche normalement,
   au prix d'un <div id="intro-overlay"> vide et inerte laissé dans le DOM).
   ========================================================================== */
.intro-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  align-items: center;
  justify-content: center;
}

.intro-overlay__panel {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  background: #fff;
  transform: scaleX(1);
}

.intro-overlay__panel--left {
  left: 0;
  transform-origin: left center;
}

.intro-overlay__panel--right {
  right: 0;
  transform-origin: right center;
}

.intro-overlay__mask {
  overflow: hidden;
}

.intro-overlay__logo {
  display: block;
}

.intro-overlay__seam {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1px;
  height: 0;
  background: #1f2937;
  opacity: 0;
  transform: translate(-50%, -50%);
}

.intro-active .intro-tile {
  opacity: 0;
  transform: scale(0.92) translateY(10px);
}

.intro-tile {
  transition: opacity 550ms ease, transform 550ms ease;
}

/* Zoom/fondu bien plus léger que .intro-tile : pour le logo et les titres
   (traits fins/texte), un zoom aussi marqué que sur les photos rendrait
   flou pendant la transition. Sert juste à suggérer un peu de mouvement
   plutôt que de laisser ces zones totalement statiques pendant l'ouverture. */
.intro-active .intro-fade {
  opacity: 0;
  transform: scale(0.96) translateY(6px);
}

.intro-fade {
  transition: opacity 550ms ease, transform 550ms ease;
}

/* Fondu seul (sans transform), pour les éléments qui ont déjà leur propre
   transform (ex. .site-nav, centré verticalement via translateY(-50%)) :
   un transform ajouté ici l'écraserait et casserait leur positionnement. */
.intro-active .intro-fade-opacity {
  opacity: 0;
}

.intro-fade-opacity {
  transition: opacity 550ms ease;
}

@media (prefers-reduced-motion: reduce) {
  .intro-active .intro-fade,
  .intro-active .intro-fade-opacity {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* échelonnement du "pop" des vignettes, par ordre d'apparition dans le DOM :
   assez marqué pour être clairement visible (ni instantané, ni traînant) */
.intro-tile:nth-child(2) { transition-delay: 90ms; }
.intro-tile:nth-child(3) { transition-delay: 180ms; }
.intro-tile:nth-child(4) { transition-delay: 270ms; }
.intro-tile:nth-child(5) { transition-delay: 360ms; }
.intro-tile:nth-child(6) { transition-delay: 450ms; }
.intro-tile:nth-child(7) { transition-delay: 540ms; }
.intro-tile:nth-child(8) { transition-delay: 630ms; }
.intro-tile:nth-child(9) { transition-delay: 720ms; }
.intro-tile:nth-child(10) { transition-delay: 810ms; }
.intro-tile:nth-child(11) { transition-delay: 900ms; }
.intro-tile:nth-child(12) { transition-delay: 990ms; }
.intro-tile:nth-child(n+13) { transition-delay: 1080ms; }

@media (prefers-reduced-motion: reduce) {
  .intro-active .intro-tile {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ==========================================================================
   Menu (WORKS | BIO | CONTACT) : positionné au niveau vertical du logo,
   aligné à droite du cadre (position:absolute dans la section du logo,
   qui n'affecte donc pas son centrage). Pas de sticky : reste en haut,
   défile normalement avec le reste de la page. Même police que les gros
   titres de section (font-gotham + text-shadow, classes appliquées dans
   index.liquid), mais plus légère (opacité réduite), et qui fonce
   au survol.
   Pour désactiver : retirer le bloc <nav class="site-nav"> dans
   index.liquid.
   ========================================================================== */
.site-nav {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.site-nav__link {
  color: #1f2937;
  opacity: 0.45;
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  text-decoration: none;
  transition: opacity 200ms ease;
}

.site-nav__link:hover {
  opacity: 0.9;
}

.site-nav__sep {
  color: #d1d5db;
  font-size: 0.8rem;
}

@media (max-width: 767px) {
  .site-nav {
    display: none;
  }
}

/* ==========================================================================
   Bouton retour en haut : discret, apparaît en fondu une fois qu'on a
   scrollé (voir upgrade-page-nav.js), scroll fluide vers le haut (Lenis).
   Pour désactiver : retirer le bloc <button id="back-to-top"> dans
   index.liquid.
   ========================================================================== */
.back-to-top {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  width: 44px;
  height: 44px;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.85);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #4b5563;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transform: translateY(6px);
  transition: opacity 300ms ease, transform 300ms ease, box-shadow 300ms ease;
  z-index: 30;
}

.back-to-top.is-visible {
  opacity: 0.85;
  pointer-events: auto;
  transform: translateY(0);
}

.back-to-top:hover {
  opacity: 1;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
}

/* ==========================================================================
   Grille "Sélection" : léger agrandissement + ombre douce au survol des
   vignettes, pour les mettre en valeur sans effet brusque. Seulement
   sur les appareils à souris (hover: hover) : pas d'effet "collé" au
   doigt sur tactile. Pour désactiver : retirer la classe "thumb-frame"
   sur le div qui entoure chaque vignette dans index.liquid.
   ========================================================================== */
@media (hover: hover) and (pointer: fine) {
  .thumb-frame {
    transition: transform 300ms ease, box-shadow 300ms ease;
  }

  .thumb-frame:hover {
    transform: scale(1.035);
    box-shadow: 0 10px 18px rgba(0, 0, 0, 0.16);
  }

  /* le zoom au survol suffit à signaler que c'est cliquable : l'icône
     play devient superflue sur les appareils à souris (gardée sur
     tactile, où il n'y a pas de survol) */
  .play-button__icon {
    display: none;
  }
}

/* ==========================================================================
   Bascule de langue de la Bio (FR / EN) : même traitement visuel que les
   onglets WORKS (gris + 80% d'opacité au repos, foncé quand actif) et
   fondu enchaîné piloté par upgrade-bio-lang.js au lieu du basculement
   instantané d'origine.
   ========================================================================== */
.lang-tab {
  color: #9ca3af;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  opacity: 0.8;
  text-decoration: none;
  transition: color 200ms ease;
}

.lang-tab.is-active {
  color: #1f2937;
}

.bio-lang-panel {
  transition: opacity 200ms ease;
  opacity: 1;
}

.bio-lang-panel.is-fading {
  opacity: 0;
}

.bio-lang-panels {
  overflow: hidden;
}

/* ==========================================================================
   Panneau WORKS : onglets (TV/Commercials, Web/Various, Artists) + fondu
   entre les listes. Pour désactiver : voir upgrade-works-tabs.js.
   ========================================================================== */
.works-tab {
  color: #9ca3af; /* gris (inactif) */
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  opacity: 0.8;
  transition: color 200ms ease;
}

.works-tab svg {
  fill: currentColor;
}

/* Bureau : titres empilés à gauche (colonne), alignés en haut du cadre ;
   crédits à droite. Mobile : titres empilés au-dessus de la liste (voir
   media query plus bas). Dans les deux cas .works-tabs reste une
   colonne verticale — ça évite l'ambiguïté "colonne de crédits =
   rubrique du dessus" qu'on avait avec les onglets en ligne au-dessus
   d'une grille à plusieurs colonnes. */
.works-body {
  display: flex;
  align-items: stretch;
  gap: 2.5rem;
}

.works-tabs {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 1.25rem;
  flex: 0 0 auto;
}

.works-tab.is-active {
  color: #1f2937; /* gris foncé (actif), identique à text-gray-800 */
}

.works-panel {
  /* durée précise fixée en JS (upgrade-works-tabs.js) : différente pour
     la disparition (rapide) et l'apparition (un peu plus lente) */
  transition: opacity 200ms ease;
  opacity: 1;
}

.works-panel.is-fading {
  opacity: 0;
}

.works-panels {
  /* le glissé de redimensionnement est piloté en JS via "transform"
     (upgrade-works-tabs.js), pas "height" — voir ce fichier */
  overflow: hidden;
  flex: 1 1 auto;
  min-width: 0;
}

@media (max-width: 767px) {
  /* Mobile : vrai accordéon — chaque liste de crédits est déplacée par
     upgrade-works-tabs.js juste après son propre titre (au lieu d'une
     zone de contenu partagée plus bas), pour que le contenu révélé
     reste toujours collé à ce qui l'a ouvert. */
  .works-body {
    flex-direction: column;
    gap: 0.5rem;
  }

  .works-tabs {
    /* reste en colonne : "les 3 titres l'un en dessous de l'autre" —
       mais en pleine largeur désormais (align-items:stretch, pas
       center) : les crédits qui s'intercalent entre les titres ont
       besoin de toute la largeur disponible, pas seulement celle du
       texte du titre. */
    justify-content: flex-start;
    align-items: stretch;
    gap: 0.5rem;
  }

  .works-tab {
    /* le bouton (flex, icône + libellé — voir index.liquid) s'étire
       désormais sur toute la largeur (align-items du parent) : il faut
       donc centrer son propre contenu interne, sinon il se cale à
       gauche (justify-content par défaut d'un conteneur flex) */
    justify-content: center;
  }
}

/* Liste de crédits : espacement resserré (comme le site actuel) + colonnes
   indépendantes au-delà de 20 titres, pour respecter l'ordre d'importance
   (le plus important en premier, lu de gauche à droite) SANS lier la
   hauteur des colonnes entre elles (contrairement à une grille CSS, où
   ouvrir le détail d'un crédit aurait aussi poussé la colonne voisine :
   une grille partage la hauteur de chaque rangée entre toutes ses
   colonnes). Chaque colonne est une <ul class="works-list__col">
   indépendante, réparties en JS — voir upgrade-works-tabs.js. */
.works-list {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.works-list__col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.works-list li {
  margin-bottom: 0;
}

/* ==========================================================================
   Légère transparence sur les cadres Works/Bio/Contact, pour laisser
   deviner la texture nuages derrière. Réglable via --panel-opacity.
   Pour désactiver : remettre à 1 (opaque).
   ========================================================================== */
:root {
  --panel-opacity: 0.80;
}

.panel-card.bg-custom-gray {
  background-color: rgba(229, 229, 229, var(--panel-opacity));
}

.panel-card.bg-white {
  background-color: rgba(255, 255, 255, var(--panel-opacity));
}
