/* LA-AH — la feuille du site
   ================================================================

   Le parti : l'extrême minimalisme, en mise en page comme en
   animation — viser l'intemporel. Blanc tournant largement dominant,
   amplitudes discrètes, mais le temps a le droit d'être vif.

   Cette feuille s'édite directement (site/index.html, lui, est bâti
   par atelier/batir-site.py — on ne l'édite jamais à la main).
*/

  /* Figtree en attendant que la fonte soit tranchée — variable de 300
     à 900 : le passage au gras s'interpole, il ne saute pas. */
  @font-face { font-family: 'Figtree'; src: url('fontes/figtree-latin-var.woff2') format('woff2'); font-weight: 300 900; font-display: block; }

  html, body { height: 100%; }
  body {
    margin: 0;
    background: var(--fond);
    color: #1a1a1a;
    font-family: 'Figtree', sans-serif;
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow: hidden; /* rien ne défile hors du texte : la page écoute le geste */
  }

  :root {
    /* le fond : entre un ivoire très pâle et un rose très pâle —
       une chaleur à peine perceptible, jamais un blanc d'écran */
    --fond: #fbf5f1;
    --corps-noms: clamp(17px, 2.3vw, 26px);
    --pas: 34px;
    --duree: 480ms;
    --courbe: cubic-bezier(0.22, 0.61, 0.36, 1);
  }

  /* La mention d'accueil — même composition que les autres bancs. */
  main {
    height: 100%;
    display: grid;
    place-items: center;
  }
  main h1, main p { margin: 0; }
  .mention { text-align: center; }
  .noms {
    font-weight: 400;
    font-size: var(--corps-noms);
    letter-spacing: 0.08em;
    padding-left: 0.08em;
    white-space: nowrap;
  }
  .devise {
    font-size: clamp(12px, 1.7vw, 19px);
    letter-spacing: 0.42em;
    padding-left: 0.42em;
    margin-top: 0.95em;
    white-space: nowrap;
  }
  .mention {
    transition:
      transform calc(var(--duree) * 0.7) var(--courbe),
      opacity   calc(var(--duree) * 0.7) var(--courbe);
  }
  body[data-etat="accueil"] .mention { transform: none; opacity: 1; transition-delay: calc(var(--duree) * 0.3); }
  body:not([data-etat="accueil"]) .mention { transform: translateY(calc(-1 * var(--pas))); opacity: 0; }

  /* Les quatre mots — positionnés un à un : la ligne du sommaire, puis
     l'élu en haut et les autres en bas. Le script pose les transforms,
     le CSS fait le voyage (position, graisse, présence). */
  .mot {
    position: absolute;
    left: 0; top: 0;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    /* le corps de la devise : les mots du menu pèsent comme
       ARCHITECTURES (demande d'Adrien) */
    font-size: clamp(12px, 1.7vw, 19px);
    letter-spacing: 0.14em;
    opacity: 0.62;
    will-change: transform;
    transition:
      transform   calc(var(--duree) * 0.7) var(--courbe),
      opacity     calc(var(--duree) * 0.7) var(--courbe),
      font-weight calc(var(--duree) * 0.7) var(--courbe);
  }
  .mot:hover { opacity: 1; }
  .mot.actif { opacity: 1; }

  #mesure {
    position: absolute;
    visibility: hidden;
    white-space: nowrap;
    font-size: clamp(12px, 1.7vw, 19px); /* toujours le même corps que .mot */
    letter-spacing: 0.14em;
  }

  /* Le texte, entre le titre et le menu redescendu. */
  #texte {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    width: min(560px, 84vw);
    overflow-y: auto;
    font-size: 15px;
    line-height: 1.65;
    visibility: hidden;
  }
  #texte.visible { visibility: visible; }

  /* ce qui défile ne montre jamais sa barre, sur aucune plateforme ;
     c'est un voile en dégradé qui dit qu'il reste du texte au-delà :
     sur la dernière ligne visible vers le bas, la première vers le
     haut (les deux si les deux sens sont ouverts) */
  #texte, .corps {
    scrollbar-width: none;
    -ms-overflow-style: none;
    --voile-haut: 0px;
    --voile-bas: 0px;
    -webkit-mask-image: linear-gradient(to bottom,
      transparent, #000 var(--voile-haut),
      #000 calc(100% - var(--voile-bas)), transparent);
    mask-image: linear-gradient(to bottom,
      transparent, #000 var(--voile-haut),
      #000 calc(100% - var(--voile-bas)), transparent);
  }
  #texte::-webkit-scrollbar, .corps::-webkit-scrollbar { display: none; }
  /* la tête reste à demeure ; sous elle, c'est le corps qui défile
     et porte le voile */
  .colonne { min-height: 0; display: flex; flex-direction: column; }
  .corps { min-height: 0; flex: 1 1 auto; overflow-y: auto; }
  #texte p { margin: 0 0 1.5em; }
  #texte > * {
    opacity: 0;
    transform: translateY(10px);
    transition:
      opacity   calc(var(--duree) * 0.7) var(--courbe),
      transform calc(var(--duree) * 0.7) var(--courbe);
  }
  #texte.visible > * { opacity: 1; transform: none; }

  /* quatre sections, quatre colonnes : la grille de l'entre-deux */
  #texte.colonnes {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    /* deux rangées : les colonnes prennent la hauteur (et défilent
       chacune pour soi au-delà), les mentions se posent au fond de
       l'entre-deux, juste au-dessus du menu */
    grid-template-rows: minmax(0, 1fr) auto;
    overflow: hidden;
    column-gap: 3em;
    /* la largeur du carré : posée par la mesure, un seul côté pour tous */
    width: var(--cote, min(900px, 86vw));
    font-size: 13.5px;
  }
  /* la disposition encadrée : les deux textes qui parlent du duo
     prennent toute la largeur, au-dessus et au-dessous, immobiles ;
     entre eux, deux colonnes — une par protagoniste — qui défilent */
  #texte.colonnes.encadree {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto auto;
    row-gap: 2.8em;
  }
  /* la loi du centre : ce qui ne remplit pas l'entre-deux vient s'y
     centrer, en hauteur comme en largeur — l'agence le remplit, les
     autres se posent au milieu. Les marges auto (texte simple) comme
     le fit-content (grilles) redeviennent inoffensifs au débord :
     le défilement garde alors tous ses droits */
  #texte:not(.colonnes) { display: flex; flex-direction: column; }
  #texte:not(.colonnes) > :first-child { margin-top: auto; }
  #texte:not(.colonnes) > :last-child { margin-bottom: auto; }

  /* la démarche : deux colonnes jumelles, comme Lucie | Adrien */
  #texte.colonnes.deux {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: fit-content(100%);
    align-content: center;
  }
  /* le contact : les deux fiches se calent sur la ligne du sommaire —
     Lucie au fer à gauche sur le bord de PROJETS, Adrien au fer à
     droite sur celui de CONTACT (la largeur --ligne vient de mesurer,
     interlettrage final compensé) */
  #texte.colonnes.fiches {
    /* deux fiches, deux colonnes — la grille de quatre couperait les
       adresses en deux */
    grid-template-columns: repeat(2, 1fr);
    /* trois lignes chacune : elles ne remplissent pas l'entre-deux, donc
       elles s'y centrent, comme les colonnes de la démarche. La rangée
       en 1fr les collait au titre et laissait tout le vide dessous */
    grid-template-rows: fit-content(100%);
    align-content: center;
    width: var(--ligne, var(--cote));
    column-gap: 3em;
  }
  #texte.colonnes.fiches .colonne:first-of-type { justify-self: start; }
  #texte.colonnes.fiches .colonne:last-of-type {
    justify-self: end;
    text-align: right;
  }
  /* les projets : tout est élection, en cascade — les catégories,
     la catégorie élue ouvre sa liste, le projet élu ouvre d'emblée
     la planche en grand sur tout l'entre-deux (la grande, un voile
     blanc qui couvre les volets — plus d'étape intermédiaire, la
     petite galerie frustrait). Pas de croix nulle part : on
     redescend d'un cran en recliquant, par le blanc, ou par Échap. */
  #texte.colonnes.projets {
    /* (le fixed de #texte ancre déjà la grande absolue) */
    grid-template-columns: max-content max-content;
    grid-template-rows: none;
    /* les deux colonnes s'alignent par le haut et les catégories
       tiennent le fer à gauche du carré, immobiles : l'ouverture de
       la liste n'a pas à les déplacer. Le centrage ne garde que la
       hauteur (la colonne des catégories, la plus haute, ne varie
       pas — rien ne bouge). */
    align-items: start;
    align-content: center;
    justify-content: start;
    column-gap: 4em;
  }
  #texte.projets .volet { min-width: 0; }
  #texte.projets .entree {
    display: block;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    opacity: 0.62;
    font-weight: 400;
    margin: 0 0 1.15em;
    transition:
      opacity     calc(var(--duree) * 0.7) var(--courbe),
      font-weight calc(var(--duree) * 0.7) var(--courbe);
  }
  #texte.projets .entree:last-child { margin-bottom: 0; }
  #texte.projets .entree:hover { opacity: 1; }
  #texte.projets .entree.elu { opacity: 1; font-weight: 600; }
  /* l'élection grise les autres, comme les mots du sommaire */
  #texte.projets .volet.choisie .entree:not(.elu) { opacity: 0.35; }
  #texte.projets .volet.choisie .entree:not(.elu):hover { opacity: 1; }
  /* la grande : l'image nue — rectangle droit, ni ombre ni coin
     rond — la légende au-dessous ; la planche et sa légende font
     un seul groupe, centré dans la hauteur */
  #texte.projets .grande {
    position: absolute;
    inset: 0;
    background: var(--fond); /* le voile porte le fond, pas un blanc */
    margin: 0;
    /* une bande de blanc demeure en haut et en bas, quelle que soit
       la vue : la planche respire, et le blanc reste cliquable pour
       redescendre */
    padding: 2em 0;
    box-sizing: border-box;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    cursor: pointer;
    transition: opacity calc(var(--duree) * 0.7) var(--courbe);
    /* le délai étagé du dévoilement ne la concerne pas */
    transition-delay: 0ms !important;
  }
  #texte.projets.pleine .grande { opacity: 1; pointer-events: auto; }
  /* le cadre : en-tête, planche, légende d'un seul tenant — sa
     largeur, posée par taillerPlanche(), suit exactement l'image
     (le format unique 3:2 la rend calculable) */
  #texte.projets .cadre { max-width: 100%; }
  #texte.projets .planche {
    position: relative;
    aspect-ratio: 3 / 2;
    width: 100%;
  }
  #texte.projets .planche img {
    display: block;
    width: 100%;
    height: 100%;
    /* le passage d'une vue : un fondu éclair, net et vif */
    transition: opacity 140ms ease;
  }
  /* au-dessus de la planche : le nom au fer à gauche, « retour » en
     face au fer à droite — sortir et naviguer doivent se voir */
  #texte.projets .entete {
    margin: 0 0 1.1em;
    font-size: 11.5px;
    letter-spacing: 0.04em;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 2em;
  }
  #texte.projets .entete .tete { font-weight: 600; }
  #texte.projets .retour,
  #texte.projets .fleche {
    color: inherit;
    text-decoration: none;
    opacity: 0.45;
    transition: opacity calc(var(--duree) * 0.5) var(--courbe);
  }
  #texte.projets .retour:hover,
  #texte.projets .fleche:hover { opacity: 1; }
  #texte.projets .feuillets { display: inline-flex; align-items: baseline; }
  #texte.projets .fleche { padding: 0 0.55em; }
  /* deux zones muettes sur la planche : rien ne se signale au repos,
     le curseur seul dit le sens sous la main */
  #texte.projets .zone { position: absolute; top: 0; bottom: 0; }
  #texte.projets .zone.avant { left: 0;  width: 34%; cursor: w-resize; }
  #texte.projets .zone.apres { right: 0; width: 66%; cursor: e-resize; }
  #texte.projets .legende {
    margin: 1.15em 0 0;
    font-size: 11.5px;
    letter-spacing: 0.04em;
  }
  #texte.projets .legende .rang {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 2em;
  }
  #texte.projets .legende .rang > span:first-child { opacity: 0.6; }
  #texte.projets .compteur {
    opacity: 0.85;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    /* le compteur naît élu — un battement de graisse — puis se range */
    animation: battement 600ms var(--courbe);
  }
  @keyframes battement { from { font-weight: 600; } 40% { font-weight: 600; } }
  #texte.projets .credit { display: block; font-size: 10px; opacity: 0.42; margin-top: 0.3em; }
  /* la liste et la grande naissent au geste, comme le texte se dévoile */
  @keyframes venue { from { opacity: 0; transform: translateY(10px); } }
  #texte.projets .liste .entree,
  #texte.projets .grande > * {
    animation: venue calc(var(--duree) * 0.7) var(--courbe) backwards;
  }
  body.sans-transition #texte .entree,
  body.sans-transition #texte .compteur,
  body.sans-transition #texte .grande > * { animation: none; }
  body.sans-transition #texte .grande { transition: none; }
  #texte .corps .intertitre:first-child { margin-top: 0; }
  #texte .cadre { grid-column: 1 / -1; }
  /* dans l'encadrée, le row-gap suffit : les mentions gardent
     le même entre-blocs que le reste, sans marge en plus */
  #texte.colonnes.encadree .legales { margin-top: 0; }
  #texte .cadre p:last-child { margin-bottom: 0; }
  #texte .tete { font-weight: 600; }
  /* Safari repère les numéros de téléphone et en fait des liens tout
     seul. On lui laisse le geste — appeler d'un doigt, c'est utile —
     mais pas le bleu souligné : ici, un numéro reste du texte */
  #texte a[href^="tel:"], #reserve a[href^="tel:"] {
    color: inherit;
    text-decoration: none;
  }
  #texte .legales {
    grid-column: 1 / -1;
    align-self: end;
    margin: 2.4em 0 0;
    font-size: 11px;
    letter-spacing: 0.04em;
    text-align: left; /* au fer à gauche, sur la colonne de gauche */
  }
  #texte.visible .legales { opacity: 0.55; }
  #texte .intertitre {
    font-size: 12px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    opacity: 0;
    margin: 1.6em 0 1.1em;
  }
  #texte.visible .intertitre { opacity: 0.62; }
  #texte strong { font-weight: 600; }

  /* ================================================================
     Le coin — les mentions légales

     La loi veut qu'elles soient joignables depuis n'importe quelle
     page ; le parti veut qu'elles ne se voient pas. Un lien gris
     clair dans l'angle bas-droit, posé une fois pour toutes en
     dehors de la scène : il ne participe ni au voyage des mots ni
     aux changements d'état, il attend. Au doigt ou à la souris, il
     reprend sa couleur d'encre — c'est là qu'il se déclare cliquable.
     ================================================================ */
  .coin {
    position: fixed;
    right: 2.2vw;
    bottom: 1.5vh;
    z-index: 3;
    color: inherit;
    opacity: 0.28;
    font-size: 11px;
    letter-spacing: 0.06em;
    text-decoration: none;
    padding: 0.6em 0.2em; /* la cible du doigt, sans marque visible */
    transition: opacity var(--duree) var(--courbe);
  }
  .coin:hover, .coin:focus-visible { opacity: 0.72; }

  /* ================================================================
     La page ordinaire — mentions.html

     Pas de scène, pas de moteur : un document qui se lit, défile et
     s'imprime. Il reprend la fonte, le fond et l'échelle du site,
     rien de plus.
     ================================================================ */
  body.page {
    height: auto;
    overflow: visible;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 14vh 7vw 8vh;
    box-sizing: border-box;
  }
  html:has(body.page) { height: auto; }
  .feuille {
    /* c'est un <main>, et la scène en fait une grille centrée qui
       rétrécit chaque bloc sur son texte, plus un cadre de 14vh en
       haut. Ici on lui rend sa nature de colonne : une pile de blocs
       pleine largeur, au fer à gauche, sans cadre à elle. */
    display: block;
    place-items: normal;
    height: auto;
    width: min(560px, 100%);
    font-size: 14px;
    line-height: 1.65;
  }
  /* la règle sans-JavaScript donne un cadre de 14vh à tout <main> ;
     ici il ferait double emploi avec celui du corps */
  body.page main.feuille { padding: 0; }
  .feuille h1 {
    font-size: var(--corps-noms);
    font-weight: 400;
    letter-spacing: 0.08em;
    margin: 0 0 3.2em;
  }
  .feuille h2 {
    font-size: 12px;
    font-weight: 400;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    opacity: 0.62;
    margin: 3.4em 0 1.2em;
  }
  .feuille h2:first-of-type { margin-top: 0; }
  .feuille p { margin: 0 0 1.4em; }
  /* les courriels et le numéro restent du texte, comme dans le site */
  .feuille a { color: inherit; text-decoration: none; }
  /* sur la page, le coin cesse d'être un coin : il se range sous le
     texte, au fer à droite de la feuille */
  body.page .coin {
    position: static;
    width: min(560px, 100%);
    text-align: right;
    margin-top: 4em;
    padding: 0;
  }

  /* ================================================================
     L'écran étroit — le téléphone tenu droit

     La scène ne change pas : mêmes états, même voyage des mots, même
     carré pour la mesure. Ce qui change, c'est que plus rien ne se met
     côte à côte : les colonnes se rangent l'une sous l'autre, dans
     l'ordre où le texte est écrit, et c'est l'entre-deux tout entier
     qui défile — un seul geste, un seul voile.
     ================================================================ */
  @media (max-width: 620px) {
    /* la grille rend ses colonnes : on retrouve la loi du centre du
       texte simple, dont les marges auto restent inoffensives au
       débord (une grille centrée, elle, couperait par le haut) */
    #texte.colonnes:not(.projets):not(.fiches) {
      display: flex;
      flex-direction: column;
      gap: 2.2em;
      overflow-y: auto;
      width: var(--cote, 86vw);
      font-size: 14px;
    }
    #texte.colonnes:not(.projets):not(.fiches) > :first-child { margin-top: auto; }
    #texte.colonnes:not(.projets):not(.fiches) > :last-child { margin-bottom: auto; }
    #texte.colonnes:not(.projets):not(.fiches) .colonne { flex: 0 0 auto; }
    /* une seule colonne, donc un seul défilement : les corps rendent
       le leur, et le voile revient à l'entre-deux */
    #texte .corps {
      overflow: visible;
      -webkit-mask-image: none;
      mask-image: none;
    }
    /* les fiches, elles, restent face à face — deux noms, trois
       lignes chacun, ça tient dans la largeur d'un téléphone. On
       resserre seulement la gouttière pour que les courriels aient
       leur place */
    #texte.colonnes.fiches { column-gap: 1.6em; font-size: 14px; }
    /* les projets gardent leur cascade, resserrée */
    #texte.colonnes.projets { column-gap: 2em; }
    #texte.projets .grande { padding: 1em 0; }
    #texte.projets .entete { gap: 1em; }
    /* sous la planche, la légende et le feuilletage passent l'un sous
       l'autre : la ligne unique les écrasait */
    #texte.projets .legende .rang { display: block; }
    #texte.projets .feuillets { display: flex; margin-top: 0.6em; }
    #texte.projets .fleche { padding: 0 0.9em 0 0; }
    #texte.projets .fleche.apres { padding: 0 0 0 0.9em; }
  }

  @media (prefers-reduced-motion: reduce) {
    .mention, .mot, #texte > * { transition-duration: 200ms; }
  }

  body.sans-transition .mention,
  body.sans-transition .mot,
  body.sans-transition #texte > * { transition: none; }

  /* ================================================================
     La réserve — le texte en clair

     La page porte tout son texte dans #reserve : c'est de là que le
     moteur le tire pour l'installer au centre, c'est ce que lisent les
     moteurs de recherche, et c'est ce qui reste si le JavaScript ne
     vient pas. Avec lui, elle disparaît — la classe .js est posée dans
     l'en-tête, avant le moindre affichage : rien ne clignote.
  */
  .js #reserve { display: none; }

  .hors-vue {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* Sans JavaScript : plus de scène, un document. Le mouvement, les
     mots qui voyagent et la cascade des projets tombent ; restent la
     mention, le sommaire en liens ordinaires — qui mènent aux ancres —
     et les textes empilés dans une seule colonne. */
  html:not(.js), html:not(.js) body { height: auto; overflow: visible; }
  html:not(.js) main { height: auto; padding: 14vh 0 7vh; }
  html:not(.js) #texte, html:not(.js) #mesure { display: none; }
  html:not(.js) #sommaire { text-align: center; padding-bottom: 6vh; }
  html:not(.js) .mot {
    position: static;
    display: inline-block;
    opacity: 0.62;
    margin: 0 0.9em 1.2em;
  }
  html:not(.js) #reserve {
    max-width: 560px;
    margin: 0 auto;
    padding: 0 7vw 14vh;
    font-size: 15px;
    line-height: 1.65;
  }
  html:not(.js) #reserve h2 {
    font-size: 12px;
    font-weight: 400;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    opacity: 0.62;
    margin: 4.5em 0 1.4em;
  }
  html:not(.js) #reserve p { margin: 0 0 1.5em; }
  html:not(.js) #reserve .tete { font-weight: 600; margin-bottom: 0.5em; }
  html:not(.js) #reserve .legales,
  html:not(.js) #reserve .intertitre { font-size: 12px; opacity: 0.62; }
