/* pages intérieures : en-tête de page, blocs communs, apparition au défilement */

/* ---------- pages intérieures ---------- */
.page-head{position:relative;overflow:hidden;background:var(--stone-soft);
  padding:164px 0 74px;border-bottom:1px solid var(--line);text-align:center}
/* Sur un grand écran, l'entête illustré s'allonge avec la page. À retrait fixe,
   une photo de groupe de 2560 px de large n'avait plus que 396 px de haut — six
   fois et demie plus large que haute — et le cadrage « couvrir » y coupait les
   visages. Le retrait grandit donc avec la largeur, dans le rapport de deux
   tiers / un tiers qu'il avait déjà. L'entête sobre des pages légales n'en a pas
   besoin : il n'a pas de photo à cadrer. */
@media (min-width:1500px){
  .page-head:not(.sobre){padding:clamp(164px,12vw,300px) 0 clamp(74px,5.4vw,136px)}
}

/* ---------- en-tête illustré ----------
   Le parlement de Bretagne en fond, en couleur mais assombri : la photo pose le
   décor sans disputer la vedette au titre. C'est le voile qui fait tout le
   travail — pas de désaturation, pas de contraste ajouté, sinon l'image
   reprendrait le dessus.

   Les pages des pôles sont marquées « sobre » et conservent l'en-tête clair :
   elles ont leurs propres photos d'équipe juste en dessous. */
.page-head:not(.sobre){border-bottom:0}
.page-head:not(.sobre)::before{content:"";position:absolute;inset:0;
  /* La photo peut être choisie page par page : build.py pose alors la
     variable sur la section. Sans choix, c'est le parlement. */
  /* Le cadrage vertical se règle page par page : sur une photo de groupe,
     la hauteur des visages change d'une promotion à l'autre, et c'est elle
     qui décide de ce qu'on voit sous le titre. */
  background:var(--photo-entete, url("../assets/img/hero-parlement.jpg"))
             var(--entete-x, center) var(--entete-y, 26%)/cover no-repeat;
  /* « cover » remplit toujours le bandeau : on ne peut pas en montrer moins.
     Le facteur d'échelle, lui, se règle. En dessous de 1 la photo se réduit et
     laisse paraître le fond sombre du bandeau sur les côtés ou en haut et en
     bas — c'est ainsi qu'on « dézoome » sur une photo de groupe dont le cadrage
     coupe les rangs. 1.02 par défaut : un fond exactement à 1 laisserait un
     liseré clair sur les bords. */
  transform:scale(var(--entete-zoom, 1.02));
  /* Le point fixe de l'agrandissement, et c'est lui qui rend le cadrage
     horizontal possible.

     « cover » remplit le bandeau par le plus petit côté : une photo moins
     large que le bandeau le remplit donc en largeur, déborde en hauteur, et il
     n'y a rien à faire glisser sur les côtés — le réglage horizontal restait
     lettre morte sur grand écran, quoi qu'on y mette.

     Dès que l'on agrandit, en revanche, la photo déborde des deux côtés. Le
     point fixe décide alors de ce qu'on garde : à 0 %, c'est le bord gauche
     qui ne bouge pas et l'on voit la gauche de la photo ; à 100 %, la droite.
     Ce sont les deux mêmes nombres que la position du fond, et ils vont dans
     le même sens — un seul couple de réglages, deux mécanismes qui ne se
     contredisent pas. */
  transform-origin:var(--entete-x, center) var(--entete-y, 26%)}
.page-head:not(.sobre)::after{content:"";position:absolute;inset:0;
  /* Le voile s'éclaircit là où on a mis une photo de groupe : à 80 %% de
     noir, on ne distinguait plus personne, et la photo ne servait plus à
     rien. Il se referme vers le bas, où passent les années du cursus. */
  background:linear-gradient(180deg,
    rgba(17,16,16,var(--voile-haut, .80)) 0,
    rgba(17,16,16,var(--voile-milieu, .72)) 52%,
    rgba(17,16,16,var(--voile-bas, .84)) 100%)}
.page-head:not(.sobre) .wrap{position:relative;z-index:1}
.page-head:not(.sobre) h1{color:#fff;text-shadow:0 2px 28px rgba(0,0,0,.42)}
.page-head:not(.sobre) .page-rubrique{color:#fff;text-shadow:0 1px 14px rgba(0,0,0,.5)}
.page-head:not(.sobre) .page-rubrique a{color:inherit}
.page-head:not(.sobre) .page-chapeau{color:rgba(255,255,255,.82);
  text-shadow:0 1px 18px rgba(0,0,0,.45)}
.page-rubrique{display:flex;align-items:center;justify-content:center;gap:16px;margin:0 0 22px;
  font-family:Spectral,serif;font-style:italic;font-size:13.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--crimson)}
.page-rubrique::before,.page-rubrique::after{content:"";width:42px;height:2px;background:var(--crimson);flex:none}
.page-head h1{font-size:clamp(33px,4.4vw,54px);font-weight:300;line-height:1.1;margin:0 auto 22px;
  max-width:24ch;text-wrap:balance}
.page-chapeau{margin:0 auto;max-width:64ch;font-family:Spectral,serif;font-size:19px;line-height:1.68;
  color:var(--muted);text-wrap:pretty}

/* ---------- arrivée de l'en-tête ----------
   La rubrique se pose, le titre et le chapeau la suivent d'un souffle, les deux
   filets cramoisis se tracent depuis le centre, et la photo de fond termine une
   très lente approche. Rien de spectaculaire : l'en-tête est la première chose
   qu'on voit de chaque page, il doit s'installer, pas faire un numéro.

   Les animations sont posées par la feuille de style, sans classe à ajouter :
   elles partent donc dès la première image, et un navigateur sans JavaScript
   les joue comme les autres. Le routeur se contente de les relancer quand on
   revient sur la page (voir js/routeur.js).

   Les filets grandissent des deux côtés à la fois : la rubrique étant centrée,
   le texte ne bouge pas d'un pixel pendant qu'ils s'écartent. */
@keyframes entete-monte{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes entete-filet{from{width:0;opacity:0}to{width:42px;opacity:1}}
/* L'échelle d'arrivée se termine à 1.02, valeur que porte déjà ::before : un
   fond exactement à 1 laisserait paraître un liseré clair sur les bords. */
@keyframes entete-fond{from{transform:scale(calc(var(--entete-zoom, 1.02) * 1.08))}
  to{transform:scale(var(--entete-zoom, 1.02))}}

.page-head .page-rubrique{animation:entete-monte .75s cubic-bezier(.22,.68,.3,1) both}
.page-head h1{animation:entete-monte .85s cubic-bezier(.22,.68,.3,1) .1s both}
.page-head .page-chapeau{animation:entete-monte .85s cubic-bezier(.22,.68,.3,1) .22s both}
.page-head .page-rubrique::before,
.page-head .page-rubrique::after{animation:entete-filet .7s cubic-bezier(.22,.68,.3,1) .34s both}
.page-head:not(.sobre)::before{animation:entete-fond 2.6s cubic-bezier(.16,.72,.24,1) both}

@media (prefers-reduced-motion:reduce){
  .page-head .page-rubrique,.page-head h1,.page-head .page-chapeau,
  .page-head .page-rubrique::before,.page-head .page-rubrique::after,
  .page-head:not(.sobre)::before{animation:none}
}
.sec.alt{background:var(--stone-soft)}
.mod-list.light .mod{color:var(--ink);border-bottom:1px solid var(--line);cursor:default}
.mod-list.light .mod i{color:var(--muted)}
.mod-list.light .mod:hover{color:var(--ink);border-bottom-color:var(--line);padding-left:0}

.word-inline{display:grid;grid-template-columns:340px 1fr;gap:60px;align-items:start}
.texte-large{margin:0;max-width:70ch;font-size:16.5px;line-height:1.72;color:var(--muted);
  text-align:justify;hyphens:auto}
.apercu{margin:0;padding:22px 26px;background:var(--stone-soft);border-left:2px solid var(--crimson);
  font-size:15px;color:var(--muted);max-width:70ch}
.sec.alt .apercu{background:#fff}
.partner-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
.partner-grid div{background:#fff;padding:26px 20px;font-size:14.5px;color:var(--ink);text-align:center}
.sec.alt .partner-grid div{background:var(--stone-soft)}
.figure-large{margin:0}
.figure-large img{width:100%;display:block}
.figure-large figcaption{margin-top:14px;font-size:14px;color:var(--muted)}
.etapes{list-style:none;counter-reset:e;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line)}
.etapes li{counter-increment:e;background:#fff;padding:34px 32px 36px}
.etapes li::before{content:counter(e,decimal-leading-zero);display:block;margin-bottom:16px;
  font-family:Spectral,serif;font-size:30px;font-weight:300;color:var(--crimson);line-height:1}
.etapes b{display:block;font-family:Spectral,serif;font-size:20px;font-weight:600;margin-bottom:10px}
.etapes span{display:block;font-size:15.2px;line-height:1.68;color:var(--muted);text-align:justify;hyphens:auto}
.card p a{color:var(--crimson);border-bottom:1px solid currentColor}

/* ---------- la page d'erreur ----------
   Le bouton d'une carte se pose en enfant direct, jamais dans un paragraphe :
   la règle ci-dessus teindrait son libellé de cramoisi sur fond cramoisi, et
   le bouton paraîtrait vide. Il ne reste qu'à l'écarter du texte.

   Le renvoi final est une remarque, pas une invitation : il se lit plus petit
   et plus gris que le reste, et se tient à distance des trois cartes. */
.card > .btn{margin-top:18px}
.erreur-renvoi{margin:40px 0 0;font-size:14.5px;line-height:1.75;color:var(--muted);max-width:62ch}
@media (max-width:1040px){
  .word-inline{grid-template-columns:1fr;gap:34px}
  .word-inline .word-photo{max-width:400px}
  .partner-grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:680px){
  .etapes,.partner-grid{grid-template-columns:1fr}
  .page-head{padding:122px 0 46px}
}

/* ---------- grille à deux colonnes ---------- */
.grid2{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
.grid2 .card{background:#fff;padding:40px 36px 42px}
.grid2 .card-vue{width:calc(100% + 72px);margin-left:-36px;margin-right:-36px}
@media (max-width:1040px){.grid2{grid-template-columns:1fr}}

/* grands chiffres en filigrane dans les cartes */
.grid2 .card{position:relative;counter-increment:fil;overflow:hidden}
.grid2{counter-reset:fil}
.grid2 .card::after{content:counter(fil,decimal-leading-zero);position:absolute;right:18px;bottom:-14px;
  font-family:Spectral,serif;font-size:104px;font-weight:300;line-height:1;color:var(--crimson);
  opacity:.07;pointer-events:none}

/* apparition au défilement, comme les jalons de la frise */
/* Une demi-seconde, pas plus : au-delà, un défilement rapide dépasse le bloc
   avant qu'il ait fini de paraître, et l'on croit à une lenteur du site alors
   que c'est l'animation qui traîne. */
.apparait{opacity:0;transform:translateY(18px);
  transition:opacity .5s cubic-bezier(.22,.7,.3,1),transform .5s cubic-bezier(.22,.7,.3,1)}
.apparait.vu{opacity:1;transform:none}
.apparait:nth-of-type(2){transition-delay:.08s}
.apparait:nth-of-type(3){transition-delay:.16s}
.apparait:nth-of-type(4){transition-delay:.24s}
@media (prefers-reduced-motion:reduce){.apparait{opacity:1;transform:none;transition:none}}

/* ---------- rejouer une apparition ----------
   Rejouer suppose d'abord défaire — et défaire sans qu'on le voie. Sans cette
   parenthèse, retirer « vu » lance la transition en sens inverse ; elle est
   encore en cours quand l'observateur remet la classe, la reprise repart du
   milieu, et les retards en cascade ne s'appliquent plus.

   Mesuré le 2026-10-08 : au retour sur la page de l'école, les segments de la
   frise repartaient de 0,4 au lieu de 0 et finissaient presque ensemble. Le
   trait paraissait déjà tracé — l'animation « ne se refaisait pas ».

   Le routeur pose cette classe le temps d'un recalcul de mise en page, puis la
   retire : l'état remis à zéro est acquis, et la transition suivante repart
   bien de zéro. */
.sans-transition,
.sans-transition *,
.sans-transition::before,
.sans-transition::after,
.sans-transition *::before,
.sans-transition *::after{transition:none !important;animation:none !important}

/* ---------- pages libres ----------
   Le gabarit passe-partout des pages créées depuis l'interface : du texte, des
   intertitres, des images, un bouton. Rien de plus, pour que ces pages restent
   dans le ton du site quel qu'en soit l'auteur. */
.texte-libre{max-width:74ch}
.texte-libre p{margin:0 0 20px;font-size:16.4px;line-height:1.78;color:var(--muted);
  text-align:justify;hyphens:auto}
.libre-intertitre{margin:44px 0 18px;font-family:Spectral,serif;font-size:clamp(22px,2.4vw,29px);
  font-weight:300;line-height:1.2;color:var(--ink)}
.libre-intertitre:first-child{margin-top:0}
.libre-image{margin:34px 0;max-width:none}
.libre-image img{display:block;width:100%;height:auto}
.libre-image figcaption{margin-top:10px;font-size:13.5px;color:var(--muted)}
.libre-action{margin:34px 0 0}

/* ---------- pages juridiques ----------
   Mentions légales et politique de confidentialité : deux longs documents qu'on
   vient consulter sur un point précis, pas lire d'un bout à l'autre. D'où le
   sommaire en tête, et une mesure courte — soixante-dix caractères — pour que
   l'œil retrouve le début de la ligne suivante dans un texte dense. */
#vue-mentions-legales .sec,#vue-confidentialite .sec{padding:68px 0 116px}
.legal-article{margin:0 0 48px;scroll-margin-top:110px}
.legal-article h2{margin:0 0 18px;padding-top:26px;border-top:1px solid var(--line);
  font-family:Spectral,serif;font-weight:300;font-size:clamp(22px,2.4vw,28px);line-height:1.2;color:var(--ink)}
.legal-corps{max-width:72ch}
.legal-corps h3{margin:26px 0 10px;font-family:Montserrat,sans-serif;font-size:11px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink)}
.legal-corps p{margin:0 0 14px;font-size:15.8px;line-height:1.78;color:var(--muted)}
.legal-corps ul{margin:0 0 16px;padding-left:1.1em}
.legal-corps li{margin:0 0 8px;font-size:15.8px;line-height:1.74;color:var(--muted)}
.legal-corps a{color:var(--crimson);border-bottom:1px solid currentColor;word-break:break-word}
@media (max-width:680px){
  #vue-mentions-legales .sec,#vue-confidentialite .sec{padding:48px 0 88px}
}
