:root{
  /* Le hero suit le thème du site (variables de base.css). Les papiers
     découpés, eux, sont des objets physiques : leurs couleurs sont fixes. */
  --cut-bg: #0b0c0f;
  --cut-ink: rgba(var(--surface-rgb), .92);
  --cut-muted: rgba(var(--surface-rgb), .65);
  --cut-paper1: #f3f0e7;            /* papier journal clair */
  --cut-paper2: #efe9db;
  --cut-paper-ink: rgba(0,0,0,.86);  /* encre sur papier clair */
  --cut-headline1: #111;            /* papier « manchette » sombre */
  --cut-headline2: #1b1b1b;
  --cut-headline-ink: rgba(255,255,255,.92);
  --cut-signature-inversion: var(--media-inversion, invert(0));
  --cut-signature-fusion: var(--media-fusion, screen);

  /* ✅ Nouveau — espace dynamique */
  --content-width: min(900px, calc(100vw - 400px));
  --side-space: calc((100vw - var(--content-width)) / 2);
}

/* Mode clair : la table sous les papiers devient claire (voir base.css) */
:root[data-theme="clair"]{ --cut-bg: #efece5; }
@media (prefers-color-scheme: light){
  :root:not([data-theme="sombre"]){ --cut-bg: #efece5; }
}

/* ── Photographie de fond ────────────────────────────────────────────
   Un homme de dos qui s'eloigne et ne se retourne pas : l'image dit la
   contrainte fondatrice du manifeste, « ne jamais revenir en arriere ».
   Elle est posee en fond du hero, sous un voile sombre, pour que les
   papiers decoupes gardent leur lisibilite.

   Le voile se regle avec --cut-photo-voile-haut / -bas : deux valeurs
   entre 0 et 1, la premiere pour le haut de l'ecran, la seconde pour le
   bas ou passe le pied de page. Monter les valeurs assombrit.

   Trois tailles servies selon la largeur de l'ecran : 900, 1400, 2400.
   Une seule est telechargee, le navigateur choisit.                      */
/* ATTENTION : les trois lignes --cut-photo ci-dessous sont DOUBLEES dans
   index.php, avec un numero de version tire de la date du fichier, et c'est
   cette version-la qui gagne. Sans elle, un visiteur deja venu garderait
   l'ancienne image en cache une semaine apres son remplacement, puisque les
   noms de fichier ne changent pas. Les valeurs de voile, elles, ne vivent
   qu'ici. Si tu renommes une taille, renomme-la aux deux endroits.        */
:root{
  --cut-photo: url('/images/accueil-ruelle-1400.jpg');
  /* Voile a zero : l'image est servie telle quelle, le temps de juger.
     Remonter ces deux valeurs assombrit, la premiere pour le haut de
     l'ecran, la seconde pour le bas ou passe le pied de page. */
  --cut-photo-voile-haut: 0;
  --cut-photo-voile-bas: 0;
}
@media (max-width: 700px){
  :root{ --cut-photo: url('/images/accueil-ruelle-900.jpg'); }
}
@media (min-width: 1500px){
  :root{ --cut-photo: url('/images/accueil-ruelle-2400.jpg'); }
}

/* fond coherent */
.cutouthero{
  position: relative;
  background:
    radial-gradient(1200px 800px at 70% 20%, rgba(var(--surface-rgb),.06), transparent 60%),
    radial-gradient(900px 700px at 20% 70%, rgba(var(--surface-rgb),.04), transparent 60%),
    var(--cut-bg);
}

/* La photo occupe sa propre couche, haute d'exactement UN ecran, et non la
   boite du hero. Si le poeme depasse la hauteur visible, le hero grandit ;
   une photo peinte sur lui serait alors etiree et recadree, ce qui est le
   defaut qu'on corrige ici. Elle garde donc toujours les proportions de
   l'ecran, et le fond du site prend le relais en dessous s'il y a lieu.

   Couche absolue plutot que fixe : une couche fixe deborderait sur le
   contenu qui suit le hero, et background-attachment: fixed se comporte
   mal sur iOS.                                                            */
.cutouthero::before{
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 100vh;
  height: 100dvh;   /* ecarte les barres d'outils mobiles quand c'est connu */
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(
      to bottom,
      rgba(11,12,15, var(--cut-photo-voile-haut)) 0%,
      rgba(11,12,15, var(--cut-photo-voile-haut)) 55%,
      rgba(11,12,15, var(--cut-photo-voile-bas)) 92%,
      var(--cut-bg) 100%),
    var(--cut-photo) center / cover no-repeat;
}
.cutouthero__wrap{ z-index: 1; }

/* Animation en pause : le wrap n'est pas rendu, et c'est lui qui donnait
   sa hauteur au hero. La section reprend donc la mesure a son compte,
   pour que la photo occupe exactement un ecran. Voir l'interrupteur
   $cutoutAnime dans partials/hero-cutout.php.                          */
.cutouthero--photoseule{
  min-height: 100vh;
  min-height: 100dvh;
}


/* Zone animation */
.cutouthero__wrap{
  position: relative;
  width: 100%;
  min-height: 100vh;
  padding: 10px 18px 18px; /* ✅ moins de padding en haut */
  box-sizing: border-box;
  overflow: hidden;
}

/* ===== Loader (avant animation) ===== */
.cutouthero__loader{
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  gap: 10px;
  z-index: 6;                 /* au-dessus */
  pointer-events: none;       /* ne bloque pas le scroll */
  opacity: 1;
  transition: opacity 220ms ease;
}

.cutouthero__spinner{
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 3px solid rgba(var(--surface-rgb),0.18);
  border-top-color: rgba(var(--surface-rgb),0.75);
  animation: cutSpin 0.9s linear infinite;
  filter: drop-shadow(0 6px 14px rgba(var(--ombre-rgb), calc(0.35 * var(--ombre-k))));
}

.cutouthero__loaderText{
  font-family: 'Special Elite', serif;
  font-size: 13px;
  letter-spacing: 0.06em;
  color: rgba(var(--surface-rgb),0.55);
  text-transform: uppercase;
}

.cutouthero__loader.is-hidden{
  opacity: 0;
}

@keyframes cutSpin{
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce){
  .cutouthero__spinner{ animation: none; }
}

.cutouthero__stage{
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.cutouthero__layout{
  position: relative;
  width: var(--content-width); /* ✅ cohérent avec --content-width */
  max-width: 900px;
  margin: 0 auto;
  padding-right: var(--side-space); /* ✅ dynamique */
  padding-top: max(10px, env(safe-area-inset-top));
  opacity: 0;
  pointer-events: none;
  box-sizing: border-box;
}

.cutouthero__layoutTitle{
  display: flex;
  flex-wrap: wrap;
  justify-content: center; /* ✅ centre horizontal */
  align-items: flex-start;

  gap: 0 0;
  margin: 2px 0 10px 0; /* ✅ moins de vide en haut */
}

.cutouthero__line{
  display: flex;
  flex-wrap: wrap;
  justify-content: center; /* ✅ centre chaque ligne */
  align-items: flex-start;

  gap: 0 0;
  margin: 0 0 10px 0;
}

/* pile à droite */
.cutouthero__pile{
  position: fixed;
  right: 18px;
  top: 12px;
  bottom: auto;
  transform: none;

  width: calc(var(--side-space) - 20px); /* ✅ dynamique */
  height: calc(100vh - 24px);

  pointer-events: none;
  z-index: 3;
}

/* grain */
.cutouthero__grain{
  pointer-events: none;
  position: fixed;
  inset: 0;
  opacity: .10;
  mix-blend-mode: overlay;
  background-image:
    repeating-linear-gradient(0deg, rgba(var(--surface-rgb),.08) 0, rgba(var(--surface-rgb),.08) 1px, transparent 1px, transparent 3px);
  filter: blur(.4px);
  z-index: 2;
}

/* cutouts */
.cutouthero__cutout{
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 5px 7px;
  border-radius: 2px;
  line-height: 1;
  white-space: nowrap;
  transform-origin: 50% 50%;
  will-change: left, top, transform;
  box-shadow: 0 8px 18px rgba(var(--ombre-rgb), calc(.30 * var(--ombre-k))), 0 2px 0 rgba(var(--ombre-rgb), calc(.22 * var(--ombre-k)));
}
.cutouthero__paper{
  background: linear-gradient(180deg, var(--cut-paper1), var(--cut-paper2));
  color: var(--cut-paper-ink);
}
.cutouthero__headline{
  background: linear-gradient(180deg, var(--cut-headline1), var(--cut-headline2));
  color: var(--cut-headline-ink);
}

/* ── Verre depoli ─────────────────────────────────────────────────────
   Les papiers cessent d'etre opaques. Chacun devient une plaque de verre
   translucide et floutee, posee sur la photo : la ruelle reste visible a
   travers le mot, mais le filtre force le contraste sous l'encre — ce
   qu'aucun mode de fusion ne sait faire, puisqu'un mode de fusion subit
   le fond au lieu de le corriger.

   INTERRUPTEUR : l'attribut data-papiers sur la section, dans
   partials/hero-cutout.php. « verre » pour ce traitement, n'importe
   quelle autre valeur pour revenir aux papiers opaques.

   TROIS REGLAGES, tous ici :
     --cut-verre-flou  rayon du flou derriere la plaque
     --cut-verre-a     opacite de la plaque (0 = verre pur, 1 = papier)
     --cut-verre-force ecart de luminosite impose au fond (1 = aucun)

   La plaque claire eclaircit le fond sous elle, la plaque sombre
   l'assombrit. L'encre se retrouve donc toujours du cote contraste,
   quelle que soit la photo — c'est tout l'interet : cela ne depend
   d'aucune propriete de l'image, et la prochaine tiendra aussi.

   COUT : chaque plaque oblige le navigateur a rechantillonner la photo
   derriere elle, y compris pendant que les mots volent. C'est assume :
   un papier qui arrive opaque puis devient verre une fois pose casse
   l'animation, et l'animation est le sujet de la page. Si un jour le
   vol saccade sur une machine lente, la parade n'est pas de retarder
   le verre en bloc mais de le poser mot par mot, a l'atterrissage.    */
.cutouthero[data-papiers="verre"]{
  --cut-verre-flou: 8px;
  --cut-verre-a: .34;
  --cut-verre-force: 1.7;
}
.cutouthero[data-papiers="verre"] .cutouthero__cutout{
  box-shadow: 0 6px 16px rgba(var(--ombre-rgb), calc(.20 * var(--ombre-k)));
}
/* plaque claire : encre sombre, fond eclairci */
.cutouthero[data-papiers="verre"] .cutouthero__paper{
  background: rgba(243,240,231, var(--cut-verre-a));
  color: rgba(0,0,0,.90);
  -webkit-backdrop-filter: blur(var(--cut-verre-flou)) saturate(.45) brightness(var(--cut-verre-force));
          backdrop-filter: blur(var(--cut-verre-flou)) saturate(.45) brightness(var(--cut-verre-force));
}
/* plaque sombre : encre claire, fond assombri */
.cutouthero[data-papiers="verre"] .cutouthero__headline{
  background: rgba(8,9,12, var(--cut-verre-a));
  color: rgba(255,255,255,.95);
  -webkit-backdrop-filter: blur(var(--cut-verre-flou)) saturate(.85) brightness(calc(1 / var(--cut-verre-force)));
          backdrop-filter: blur(var(--cut-verre-flou)) saturate(.85) brightness(calc(1 / var(--cut-verre-force)));
}
/* plaque teintee : la couleur du magazine, en verre. Le script pose
   --mot-fond et --mot-encre au lieu d'ecrire un style en dur, sans quoi
   le style en ligne l'emporterait sur tout ce qui precede.             */
.cutouthero__mag{ background: var(--mot-fond); color: var(--mot-encre); }
.cutouthero[data-papiers="verre"] .cutouthero__mag{
  background: rgba(243,240,231, calc(var(--cut-verre-a) * .55));
  background: color-mix(in srgb, var(--mot-fond) calc(var(--cut-verre-a) * 100%), transparent);
  color: var(--mot-encre);
  -webkit-backdrop-filter: blur(var(--cut-verre-flou)) saturate(.45) brightness(var(--cut-verre-force));
          backdrop-filter: blur(var(--cut-verre-flou)) saturate(.45) brightness(var(--cut-verre-force));
}
/* Sans backdrop-filter, ou si le visiteur demande moins de transparence,
   la plaque redevient presque opaque : on perd l'effet, jamais le texte. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){
  .cutouthero[data-papiers="verre"]{ --cut-verre-a: .92; }
}
@media (prefers-reduced-transparency: reduce){
  .cutouthero[data-papiers="verre"]{ --cut-verre-a: .92; --cut-verre-flou: 0px; }
}

/* Fonts */
/* --cut-fit : facteur d'ajustement pose par le script pour que le poeme
   entre dans la hauteur visible. Il vaut 1 tant que le poeme tient.       */
.cut-f-book{ font-family: "Libre Baskerville", Georgia, serif; font-weight: 700; font-size: calc(17px * var(--cut-fit, 1)); }
.cut-f-news{ font-family: "Newsreader", Georgia, serif; font-weight: 700; font-size: calc(19px * var(--cut-fit, 1)); }
.cut-f-art { font-family: "Playfair Display", Georgia, serif; font-weight: 700; font-size: calc(19px * var(--cut-fit, 1)); }
.cut-f-ad  { font-family: "Archivo Black", Arial, sans-serif; font-weight: 400; font-size: calc(21px * var(--cut-fit, 1)); text-transform: uppercase; }
.cut-f-mono{ font-family: "Space Mono", ui-monospace, monospace; font-weight: 400; font-size: calc(15px * var(--cut-fit, 1)); }

/* Title big */
.cut-f-title{
  font-family: "Archivo Black", Arial, sans-serif;
  font-weight: 400;
  font-size: calc(38px * var(--cut-fit, 1));
  text-transform: uppercase;
  letter-spacing: .02em;
}

/* Wrap extrait sous animation */
.cutouthero__excerptWrap{
  padding: 2.2rem 1.5rem 2.8rem;
}

/* ==== BIO EXCERPT STYLE (scopé) ==== */
.cutouthero .bio-extrait{
  position: relative;
  margin: 0 auto;
  max-width: min(50%, 640px);
  padding: 1.05rem 1.1rem 1.05rem 1.35rem;
  border: 1px solid rgba(var(--texte-rgb),0.18);
  border-radius: 10px;
  background: rgba(var(--voile-rgb),0.28);
  overflow: hidden;
  box-shadow: 0 0 18px rgba(var(--ombre-rgb), calc(0.35 * var(--ombre-k)));
}
.cutouthero .bio-extrait::before{
  content:"";
  position:absolute;
  left:0; top:0; bottom:0;
  width: 14px;
  opacity: 0.95;
}
.cutouthero .bio-extrait__quote,
.cutouthero .bio-extrait__meta{
  padding-left: calc(1.25rem + 35px);
}
.cutouthero .bio-extrait__quote{
  font-family: 'Special Elite', serif;
  font-weight: 400;
  font-size: 1.0rem;
  line-height: 1.55;
  letter-spacing: 0.035em;
  margin: 0 0 0.5rem;
  color: rgba(var(--encre-rgb), calc(0.68 * var(--encre-k)));
  -webkit-font-smoothing: antialiased;
  text-shadow: 0 1px 14px rgba(var(--ombre-rgb), calc(0.55 * var(--ombre-k)));
}
.cutouthero .bio-extrait__meta{
  font-family: 'Special Elite', serif;
  font-weight: 400;
  font-size: 0.82rem;
  letter-spacing: 0.05em;
  color: rgba(var(--encre-rgb), calc(0.50 * var(--encre-k)));
  font-style: italic;
}
.cutouthero .bio-extrait--yellow::before{ background: rgba(var(--or-rgb),0.95); }
.cutouthero .bio-extrait--rose::before{ background: rgba(var(--magenta-rgb),0.95); }
.cutouthero .bio-extrait--blue::before{ background: rgba(var(--poudre-rgb),0.95); }

@media (max-width: 900px){
  .cutouthero__layout{
    width: calc(100vw - 36px);
    margin: 0 auto;
    padding-right: 0; /*plus de pile à réserver*/
  }
  .cutouthero__pile{
    right: 12px;
    bottom: 12px;
    top: auto;
    width: 180px;
    height: 140px;
    opacity: .85;
  }
  .cut-f-title{ font-size: calc(32px * var(--cut-fit, 1)); }
  .cutouthero .bio-extrait{ max-width: 70%; }
  .cutouthero .bio-extrait__quote,
  .cutouthero .bio-extrait__meta{
    padding-left: calc(1.25rem + 26px);
  }
}
@media (max-width: 600px){
  .cutouthero .bio-extrait{ max-width: 90%; }
  .cutouthero__pile{ display:none; }
  .cutouthero__layout{ padding-right: 0; }
}

/* Signature post-animation */
.cutouthero__signature{
  /* none en mode clair : voir --media-signature dans base.css */
  display: var(--media-signature, block);
  width: calc(var(--side-space) - 40px);  /* ✅ toute la marge, moins un peu d'air */
  height: calc(var(--side-space) - 40px);
  object-fit: contain;
  max-height: 60vh; /* protection écrans courts */

  opacity: 0;
  /* vidéo blanche sur noir : inversée puis multipliée en mode clair */
  filter: var(--cut-signature-inversion) drop-shadow(0 2px 12px rgba(var(--ombre-rgb), calc(0.55 * var(--ombre-k))));

  position: fixed;
  right: 20px;
  top: 50%;
  translate: 0 calc(-50% + 12px);
  z-index: 10;

  transition: opacity 900ms ease, translate 900ms ease;
  transition-delay: 200ms;
  mix-blend-mode: var(--cut-signature-fusion);
}

.cutouthero__signature--visible{
  opacity: 1;
  translate: 0 -50%;
}

@media (max-width: 900px){
  .cutouthero__signature{
    width: min(240px, calc(var(--pile-width, 180px) - 24px));
    max-height: 40vh;
  }
}

@media (max-width: 600px){
  .cutouthero__signature{
    display: none; /* déjà caché avec la pile */
  }
}