/* ============================================================
   Eddri Films — Studio de production audiovisuelle
   Feuille de style unique. Aucune dépendance externe.
   Sommaire :
     00. Polices
     01. Variables
     02. Réinitialisation et base
     03. Typographie commune
     04. Traînée du curseur
     05. Grain de film
     06. Animations d'apparition
     07. Section 1 — Hero
     08. Section 2 — Positionnement
     09. Section 3 — Films
     10. Section 4 — Offres
     11. Section 5 — Contact
     12. Pied de page
     13. Responsive
     14. Accessibilité et mouvement réduit
     15. Page Mentions légales
   ============================================================ */


/* ============================================================
   00. POLICES
   Deux graisses maximum : 300 (Light) et 400 (Regular).
   Les fichiers .woff2 sont attendus dans ./fonts/ (voir README).
   Si les fichiers sont absents, le repli Inter puis system-ui
   s'applique sans casser la mise en page.
   ============================================================ */
@font-face {
  font-family: "Satoshi";
  src: url("fonts/Satoshi-Light.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Satoshi";
  src: url("fonts/Satoshi-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}


/* ============================================================
   01. VARIABLES
   ============================================================ */
:root {
  /* Palette */
  --noir:       #08090B;   /* fond principal */
  /* Les deux bleus ne sont plus utilisés nulle part depuis le
     12/08/2026 : Victor a demandé que tout ce qui était bleu passe au
     noir. Le dernier usage était le fond des cartes de la section
     Offres, refondue sans fond coloré. Variables conservées pour
     mémoire de la palette d'origine — ne pas les réintroduire sans
     demande explicite. */
  --bleu-nuit:  #0D1420;   /* plus utilisé */
  --bleu-eleve: #141C2B;   /* plus utilisé */
  --blanc:      #EDEBE6;   /* texte principal */
  --gris:       #8B93A1;   /* texte secondaire */
  --or:         #C8A24A;   /* accent uniquement */
  --or-fonce:   #8F7332;   /* bordures et survols */

  /* Bordures très faibles */
  --filet:      rgba(237, 235, 230, 0.08);

  /* Typographie */
  --font: "Satoshi", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Rythme vertical */
  --section-y: clamp(6rem, 14vh, 11rem);
  --wrap: 1180px;
  --gutter: clamp(1.5rem, 5vw, 4rem);

  /* Transitions */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}


/* ============================================================
   02. RÉINITIALISATION ET BASE
   ============================================================ */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--noir);
  color: var(--blanc);
  font-family: var(--font);
  font-weight: 400;
  font-size: 17px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img,
video { display: block; max-width: 100%; }

ul { list-style: none; margin: 0; padding: 0; }

/* L'attribut hidden doit l'emporter sur les display: des composants */
[hidden] { display: none !important; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a {
  color: inherit;
  text-decoration: none;
  transition: color 200ms var(--ease);
}
a:hover,
a:focus-visible { color: var(--or); }

:focus-visible {
  outline: 1px solid var(--or);
  outline-offset: 4px;
}

.wrap {
  position: relative;
  z-index: 2;   /* passe devant #cursor-trail (z-index: 1) */
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}


/* ============================================================
   03. TYPOGRAPHIE COMMUNE
   ============================================================ */

/* Petit label de section, seul endroit avec du texte en or */
.label {
  margin: 0 0 1.5rem;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--or);
}
.label__num {
  margin-right: 0.9em;
  opacity: 0.7;
}

/* Titres de section */
h2 {
  margin: 0 0 2.5rem;
  font-weight: 300;
  font-size: clamp(1.6rem, 3vw, 2.25rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  max-width: 20ch;
}

h3 {
  margin: 0;
  font-weight: 400;
  font-size: 1.1rem;
  line-height: 1.4;
}

/* Corps de texte : 65 caractères maximum */
.films__notes p,
.card__desc { max-width: 65ch; }


/* ============================================================
   04. TRAÎNÉE DU CURSEUR
   Canvas 2D pur, dessiné par script.js. Reste vide sans JavaScript.
   Placée structurellement DERRIÈRE le contenu (z-index bas), pas
   seulement fondue dedans par un mélange de couleurs : le texte, les
   cartes et les vignettes reçoivent leur propre z-index plus haut
   (voir plus bas, chaque section) pour passer devant. Le canvas ne
   reste visible que dans les espaces vides des sections, au-dessus
   de leur fond uni — c'est ce qui donne l'impression d'un effet
   « dans » la page plutôt qu'un filtre posé dessus.
   mix-blend-mode: screen en complément, pour une lueur douce plutôt
   qu'un aplat, dans les zones où le canvas reste visible.
   ============================================================ */
#cursor-trail {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  width: 100%;
  height: 100%;
  mix-blend-mode: screen;
}
@media (prefers-reduced-motion: reduce) {
  #cursor-trail { display: none; }
}


/* ============================================================
   05. GRAIN DE FILM
   Bruit SVG inline, fixé, non interactif, 3,5 % d'opacité.
   ============================================================ */
.grain {
  position: fixed;
  inset: -100%;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  will-change: auto;
}


/* ============================================================
   06. ANIMATIONS D'APPARITION
   L'état masqué n'existe que si JavaScript est actif (.js).
   Sans JS, tout est visible immédiatement.
   ============================================================ */
.js .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 500ms var(--ease),
    transform 500ms var(--ease);
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}


/* ============================================================
   07. SECTION 1 — HERO
   Vidéo plein écran, masque dégradé sur les quatre bords,
   logo en haut à gauche, ligne de positionnement en bas à
   gauche, bouton son en bas à droite. Aucun menu.
   ============================================================ */
.hero {
  position: relative;
  height: 100vh;
  min-height: 34rem;
  overflow: hidden;
  background: var(--noir);
}

/* Unité dynamique pour les navigateurs mobiles récents */
@supports (height: 100dvh) {
  .hero { height: 100dvh; }
}

.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Plus aucun masque sur la vidéo : les quatre dégradés ont été retirés à
   la demande de Victor, l'image doit rester nette d'un bord à l'autre.
   Le textes du hero reposent donc directement sur la vidéo. */

/* Bande dégradée haute, superposée à la vidéo, portant le nom de marque.
   Purement décorative : elle ne reçoit aucun clic. */
/* Le nom repose désormais directement sur la vidéo : plus de barre noire,
   plus de dégradé. Le bloc ne sert plus qu'à le centrer en haut. */
.hero__band {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;   /* passe devant #cursor-trail (z-index: 1) */
  display: flex;
  justify-content: center;
  padding-top: clamp(1.1rem, 3vw, 2rem);
  pointer-events: none;
}

.hero__wordmark {
  font-weight: 300;
  font-size: clamp(1.25rem, 3.2vw, 2.25rem);
  line-height: 1;
  letter-spacing: 0.42em;
  /* compense l'espacement ajouté après la dernière lettre */
  text-indent: 0.42em;
  color: var(--blanc);
  white-space: nowrap;
}

.hero__ui {
  position: absolute;
  inset: 0;
  z-index: 2;   /* passe devant #cursor-trail (z-index: 1) */
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto 1fr auto;
  align-items: end;
  padding: clamp(1.5rem, 4vw, 2.75rem) var(--gutter);
}

/* Ligne de positionnement, seul h1 de la page */
.hero__baseline {
  grid-column: 1;
  grid-row: 3;
  margin: 0;
  max-width: 18ch;
  font-weight: 300;
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

/* Bouton son, discret */
.sound {
  grid-column: 2;
  grid-row: 3;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin: 0 0 0.6rem;
  padding: 0.6rem 0.9rem;
  background: rgba(8, 9, 11, 0.45);
  border: 1px solid var(--filet);
  border-radius: 999px;
  color: var(--gris);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 200ms var(--ease), border-color 200ms var(--ease);
}
.sound:hover,
.sound:focus-visible {
  color: var(--blanc);
  border-color: var(--or-fonce);
}
.sound__bar {
  width: 1px;
  height: 8px;
  background: currentColor;
}
.sound__bar:nth-child(2) { height: 13px; }
.sound__bar:nth-child(3) { height: 6px; }
.sound[aria-pressed="true"] .sound__bar:nth-child(1) { height: 12px; }
.sound[aria-pressed="true"] .sound__bar:nth-child(3) { height: 10px; }
.sound__label { margin-left: 0.7em; }


/* ============================================================
   08. SECTION 2 — POSITIONNEMENT
   Plein écran : la phrase est seule visible au moment du
   défilement, centrée verticalement et horizontalement.
   ============================================================ */
.statement {
  position: relative;
  overflow: hidden;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--noir);
  padding-inline: var(--gutter);
}
@supports (min-height: 100dvh) {
  .statement { min-height: 100dvh; }
}

/* Fond de courbes en vagues, très en retrait — un filet à peine
   perceptible derrière la phrase, jamais un motif qui se remarque.
   Les lignes elles-mêmes sont ajoutées et retirées par script.js ;
   ici, seule leur apparence et leur trajectoire sont définies. */
.statement__paths {
  position: absolute;
  inset: 0;
  z-index: 1;   /* derrière .statement__text (z-index: 2), devant le fond */
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.statement__paths path {
  fill: none;
  stroke: var(--blanc);
}
/* Révèle puis efface chaque courbe par un simple découpage en
   pourcentages, sans mesurer sa longueur réelle. Le point d'ancrage
   (0 % ou 100 %) ne bouge pas entre les deux dernières étapes : c'est
   ce qui fait ressortir la ligne par le bord opposé à son entrée
   plutôt que de la refermer sur elle-même. */
@keyframes statementLineForward {
  0%   { clip-path: inset(0 100% 0 0); }
  50%  { clip-path: inset(0 0% 0 0); }
  100% { clip-path: inset(0 0% 0 100%); }
}
@keyframes statementLineReverse {
  0%   { clip-path: inset(0 0% 0 100%); }
  50%  { clip-path: inset(0 0% 0 0); }
  100% { clip-path: inset(0 100% 0 0); }
}

.statement__text {
  position: relative;
  z-index: 2;   /* passe devant #cursor-trail (z-index: 1) */
  max-width: 22ch;
  margin: 0 auto;
  font-weight: 300;
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
  text-align: center;
}


/* ============================================================
   09. SECTION 3 — FILMS
   Fond noir, comme le reste du site. Trois vignettes YouTube en
   grille, chargées au clic (voir script.js).
   Hauteur minimale d'un écran et centrage vertical, comme chaque
   section qui suit : le site doit respirer, un point important ne
   doit jamais se retrouver collé au suivant pendant le défilement.
   ============================================================ */
.films {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(2.5rem, 6vh, 4rem);
  min-height: 100vh;
  background: var(--noir);
  padding-block: var(--section-y);
}
@supports (min-height: 100dvh) {
  .films { min-height: 100dvh; }
}

/* Plus large que les 1180px de .wrap, mais sans toucher les bords de
   l'écran : Victor a d'abord trouvé les vignettes trop petites et
   serrées, puis le plein écran trop grand. Entre les deux. */
.films__grid {
  position: relative;
  z-index: 2;   /* passe devant #cursor-trail (z-index: 1) */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  width: 100%;
  max-width: 1400px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Vignette cliquable : un lien tant que le lecteur n'est pas chargé */
.film__frame {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--noir);
  border: 1px solid var(--filet);
  border-radius: 12px;
  transition: border-color 200ms var(--ease);
}
.film__frame:hover,
.film__frame:focus-visible { border-color: var(--or-fonce); }

.film__thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* la vignette s'éclaircit au survol, sans effet appuyé */
  opacity: 0.82;
  transition: opacity 200ms var(--ease);
}
.film__frame:hover .film__thumb,
.film__frame:focus-visible .film__thumb { opacity: 1; }

/* Même langage que le bouton son du hero : pastille sombre, texte espacé */
.film__play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 0.55rem 1.1rem;
  background: rgba(8, 9, 11, 0.55);
  border: 1px solid var(--filet);
  border-radius: 999px;
  color: var(--blanc);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  transition: border-color 200ms var(--ease);
}
.film__frame:hover .film__play { border-color: var(--or-fonce); }

/* Le lecteur YouTube, injecté à la place du lien après le clic */
.film__player {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--filet);
  border-radius: 12px;
  background: var(--noir);
}

.film__titre {
  margin-top: 0.9rem;
  color: var(--gris);
  font-size: 15px;
  font-weight: 400;
}

.films__notes {
  margin-top: 3rem;
  color: var(--gris);
  text-align: center;
}
.films__notes p {
  margin-inline: auto;
  margin-bottom: 0.85em;
}


/* ============================================================
   10. SECTION 4 — OFFRES
   Trois cases côte à côte sur ordinateur, empilées sous 768 px.

   Historique, pour éviter les allers-retours : cette section a été
   brièvement refondue en liste éditoriale (lignes asymétriques, sans
   case) le 12/08/2026, puis **Victor a demandé le retour aux cases
   verticales le même jour**. La seule chose qu'il voulait garder de
   l'essai, c'est le noir : le fond des cases était `--bleu-eleve`, il
   est désormais `--noir`, comme la section qui les porte. Ce sont donc
   leurs filets d'un pixel qui les dessinent, plus un aplat de couleur.
   Ne pas repasser en liste ni réintroduire le bleu sans demande.
   ============================================================ */
.offers {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100vh;
  background: var(--noir);
  padding-block: var(--section-y);
}
@supports (min-height: 100dvh) {
  .offers { min-height: 100dvh; }
}

.offers__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
}

.card {
  display: flex;
  flex-direction: column;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--noir);
  border: 1px solid var(--filet);
  border-radius: 12px;
  transition: border-color 200ms var(--ease);
}
.card:hover { border-color: var(--or-fonce); }

.card__title { margin-bottom: 1.25rem; }

.card__desc {
  margin-bottom: 0.75em;
  color: var(--gris);
  font-size: 16px;
  line-height: 1.6;
}

/* « Devis gratuit » occupe la place que tenait le prix avant sa
   suppression, juste au-dessus du bouton — c'est là que se pose la
   question du coût. Il porte aussi le `margin: auto 0 0` qui pousse le
   bas de la case vers le bas et garde les trois boutons alignés, alors
   que « Sur mesure » a une ligne de description de plus que les autres.
   En blanc et non en or : trois mentions dorées de plus dans la même
   section, à côté des trois boutons déjà dorés, feraient beaucoup. */
.card__free {
  margin: auto 0 0;
  padding-top: 1.75rem;
  font-weight: 300;
  font-size: 1.05rem;
  color: var(--blanc);
}

.card__cta {
  display: block;
  margin-top: 1.5rem;
  padding: 0.75rem 1.25rem;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 400;
  text-align: center;
  transition:
    border-color 200ms var(--ease),
    background-color 200ms var(--ease),
    color 200ms var(--ease);
}

/* Les trois boutons : contour or, jamais de remplissage permanent — un
   aplat doré en continu dépasserait la règle des 5 % de surface et
   figure dans les interdits absolus du cahier des charges (« jamais de
   bouton plein doré »). Le remplissage n'apparaît qu'au survol, ce que
   la même règle autorise explicitement pour l'or. */
.card__cta--gold-outline {
  border-color: var(--or-fonce);
  color: var(--or);
}
.card__cta--gold-outline:hover,
.card__cta--gold-outline:focus-visible {
  border-color: var(--or);
  background: var(--or);
  color: var(--noir);
}


/* ============================================================
   11. SECTION 5 — CONTACT
   Fond noir, adresse mail en très grand, pas de formulaire.
   Pas de min-height plein écran ici, contrairement aux sections
   qui précèdent : c'est la dernière avant le pied de page, il n'y
   a pas de section suivante dont il faut se détacher, et forcer un
   écran plein ne faisait que creuser un vide avant le copyright.
   ============================================================ */
.contact {
  background: var(--noir);
  padding-block: var(--section-y);
}

.contact__title {
  max-width: none;
  margin-bottom: 3rem;
  font-weight: 300;
  font-size: clamp(1.75rem, 6vw, 4rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}

.contact__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2.5rem;
  color: var(--gris);
  font-size: 16px;
}


/* ============================================================
   12. PIED DE PAGE
   ============================================================ */
.footer {
  background: var(--noir);
  padding-bottom: 3rem;
  color: var(--gris);
  font-size: 13px;
}
.footer .wrap {
  padding-top: 2rem;
  border-top: 1px solid var(--filet);
}


/* ============================================================
   13. RESPONSIVE
   ============================================================ */
@media (max-width: 768px) {
  /* Les trois cases passent en colonne unique, une par écran de large :
     Format court, puis Campagne, puis Sur mesure — même traitement que
     les trois films juste au-dessus. Demande de Victor le 12/08/2026. */
  .offers__grid {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }

  /* Les trois films passent en colonne unique, l'un sous l'autre : PUB
     désert, puis BLOOM, puis Jeremy. Chacun prend toute la largeur du
     téléphone.
     C'est ce qui rend le lecteur YouTube réellement utilisable : à trois
     colonnes il ne faisait que 108 px de large sur un écran de 390 px,
     trop peu pour ses commandes — impossible notamment d'atteindre le
     bouton plein écran. Demande explicite de Victor le 12/08/2026, après
     l'avoir constaté sur son téléphone ; annule la consigne précédente
     qui figeait la grille à trois colonnes sur mobile. */
  .films__grid {
    grid-template-columns: 1fr;
    gap: 2.25rem;
  }

  /* La vidéo du hero reste en `object-fit: cover` sur mobile, comme sur
     bureau : elle remplit tout l'écran, quitte à rogner les côtés du
     16:9. Essayé en `contain` le 12/08/2026 pour montrer le cadre
     entier — Victor l'a refusé, les bandes noires nécessaires (625 px
     sur un écran de 844) alourdissaient trop le haut du site. Le
     recadrage est donc voulu : ne pas repasser en `contain`. */

  .hero__ui {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr auto auto;
    row-gap: 1.5rem;
  }
  .hero__baseline { grid-column: 1; grid-row: 3; }
  .sound {
    grid-column: 1;
    grid-row: 4;
    justify-self: end;
    margin-bottom: 0;
  }

  .statement { padding-block: 20vh; }
  .contact__list { flex-direction: column; gap: 0.5rem; }
}


/* ============================================================
   14. ACCESSIBILITÉ ET MOUVEMENT RÉDUIT
   Toutes les animations et transitions sont neutralisées.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .js .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}


/* ============================================================
   15. PAGE MENTIONS LÉGALES
   Page distincte, volontairement sans aucun effet décoratif — pas
   de grain, pas de traînée de curseur, pas d'animation au
   défilement. script.js n'est même pas chargé sur cette page :
   simple et lisible avant tout.
   ============================================================ */
.legal {
  background: var(--noir);
  padding-block: var(--section-y);
}

.legal__back {
  display: inline-block;
  margin-bottom: 3rem;
  color: var(--gris);
  font-size: 14px;
}

.legal h1 {
  margin: 0 0 3rem;
  font-weight: 300;
  font-size: clamp(2rem, 4vw, 3rem);
  letter-spacing: -0.01em;
}

.legal section {
  margin-bottom: 3rem;
}
.legal section:last-child { margin-bottom: 0; }

.legal__list li {
  margin-bottom: 0.6em;
  color: var(--gris);
  line-height: 1.7;
}
.legal__list strong {
  color: var(--blanc);
  font-weight: 400;
}
