/* ==========================================================================
   Canta de Joia — feuille de style
   Palette et matières dérivées du logo (brosse carmin) et de l'affiche Heimat
   (craie sur papier, bleu cobalt, bloc ambre).
   ========================================================================== */

/* --------------------------------------------------------- 0. Polices */

/* Les trois familles sont servies par le site, et non par Google.
 *
 * Ce n'était pas un danger — fonts.gstatic.com ne pose aucun cookie — mais
 * c'était le dernier appel vers un tiers au chargement d'une page, après le
 * départ des lecteurs YouTube. Ce qui en partait, l'adresse du visiteur et la
 * page qu'il ouvrait, n'avait aucune raison d'aller chez Google pour une
 * chorale du Périgord.
 *
 * Le gain est aussi matériel : deux connexions de moins vers un autre domaine
 * à la première visite. L'argument du cache partagé entre sites, qui a
 * longtemps justifié Google Fonts, est mort en 2020 — les navigateurs
 * cloisonnent désormais leur cache par site, et le même fichier téléchargé
 * ailleurs ne sert plus ici.
 *
 * Fraunces et Karla sont des fontes variables : un seul fichier par style
 * couvre toute la plage de graisse, et les axes SOFT et WONK dont se servent
 * les titres continuent de répondre. DM Mono n'est pas variable, d'où ses deux
 * fichiers. Les sous-ensembles vietnamiens de Fraunces ont été laissés de
 * côté : rien sur ce site n'en a l'usage.
 *
 * Les fichiers viennent de Google le 02/10/2026, par l'API css2 : ce sont
 * exactement ceux que les visiteurs recevaient la veille, au même octet.
 */

@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/dm-mono-normal-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/dm-mono-normal-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/dm-mono-normal-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/dm-mono-normal-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 300 900;
  font-display: swap;
  src: url("../fonts/fraunces-italic-300-900-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 300 900;
  font-display: swap;
  src: url("../fonts/fraunces-italic-300-900-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url("../fonts/fraunces-normal-300-900-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url("../fonts/fraunces-normal-300-900-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Karla";
  font-style: italic;
  font-weight: 300 800;
  font-display: swap;
  src: url("../fonts/karla-italic-300-800-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Karla";
  font-style: italic;
  font-weight: 300 800;
  font-display: swap;
  src: url("../fonts/karla-italic-300-800-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Karla";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("../fonts/karla-normal-300-800-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Karla";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("../fonts/karla-normal-300-800-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------- 1. Jetons */

/* Teintes animables : la page se retint doucement d'une déclinaison à l'autre */
@property --accent { syntax: "<color>"; inherits: true; initial-value: #98042a; }
@property --accent-clair { syntax: "<color>"; inherits: true; initial-value: #c81e3c; }
@property --accent-voile { syntax: "<color>"; inherits: true; initial-value: rgba(152, 4, 42, 0.075); }

:root {
  /* Déclinaisons de l'identité — rouge, orange, vert, bleu */
  --carmin: #98042a;
  --vermillon: #c81e3c;
  --ambre: #d2842b;
  --verveine: #2f7a5b;
  --cobalt: #2e64da;

  /* Encre et papier */
  --encre: #1c1512;
  --encre-80: #453a34;
  --pierre: #6e6257;
  --pierre-clair: #9c9086;
  --papier: #fbf7f0;
  --papier-2: #f4ece0;
  --papier-3: #ece1d1;
  --trait: rgba(110, 98, 87, 0.22);
  --trait-fin: rgba(110, 98, 87, 0.13);

  /* Accent courant — piloté par [data-teinte] */
  --accent: var(--carmin);
  --accent-clair: #c81e3c;
  --accent-voile: rgba(152, 4, 42, 0.07);

  /* Typographie */
  --display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --corps: "Karla", "Helvetica Neue", Arial, sans-serif;
  --data: "DM Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* Mesures */
  --page: 1240px;
  --page-large: 1460px;
  --gouttiere: clamp(1.25rem, 5vw, 4rem);
  --rythme: clamp(4.5rem, 9vw, 8.5rem);

  --r-image: 4px;
  --r-carte: 6px;
  --r-pilule: 999px;

  --ombre-douce: 0 1px 2px rgba(28, 21, 18, 0.04), 0 12px 30px -18px rgba(28, 21, 18, 0.22);
  --ombre-portee: 0 2px 6px rgba(28, 21, 18, 0.06), 0 34px 70px -34px rgba(28, 21, 18, 0.4);
}

[data-teinte="carmin"] {
  --accent: #98042a;
  --accent-clair: #c81e3c;
  --accent-voile: rgba(152, 4, 42, 0.075);
}
[data-teinte="ambre"] {
  --accent: #b06914;
  --accent-clair: #d2842b;
  --accent-voile: rgba(210, 132, 43, 0.11);
}
[data-teinte="verveine"] {
  --accent: #2f7a5b;
  --accent-clair: #3f9a72;
  --accent-voile: rgba(47, 122, 91, 0.09);
}
[data-teinte="cobalt"] {
  --accent: #2e64da;
  --accent-clair: #4d7ee6;
  --accent-voile: rgba(46, 100, 218, 0.085);
}

/* --------------------------------------------------------- 2. Bases */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 6.5rem;
}

body {
  margin: 0;
  background: var(--papier);
  color: var(--encre);
  font-family: var(--corps);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.075rem);
  line-height: 1.68;
  font-weight: 400;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Grain de papier — reprend la matière crayonnée de l'affiche */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  mix-blend-mode: multiply;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

img { max-width: 100%; height: auto; display: block; }
svg { display: block; }

::selection { background: var(--accent); color: var(--papier); }

/* --------------------------------------------------------- 3. Typographie */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-variation-settings: "SOFT" 42, "WONK" 1;
  font-weight: 460;
  letter-spacing: -0.028em;
  line-height: 1.04;
  margin: 0;
  text-wrap: balance;
}

.t-geant {
  font-size: clamp(2.6rem, 1.1rem + 6.4vw, 5.4rem);
  line-height: 0.98;
  letter-spacing: -0.038em;
}
.t-grand { font-size: clamp(2.1rem, 1.15rem + 3.6vw, 3.7rem); }
.t-moyen { font-size: clamp(1.6rem, 1.15rem + 1.8vw, 2.4rem); }
.t-petit { font-size: clamp(1.22rem, 1.05rem + 0.75vw, 1.5rem); letter-spacing: -0.02em; }

em, .italique {
  font-style: italic;
  font-variation-settings: "SOFT" 60, "WONK" 1;
}

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

.chapeau {
  font-size: clamp(1.12rem, 1rem + 0.6vw, 1.35rem);
  line-height: 1.58;
  color: var(--encre-80);
}

.prose { max-width: 62ch; }
.prose p + p { margin-top: 0; }

.texte-doux { color: var(--pierre); }

/* Étiquette / œil-de-bœuf : mono, capitales, filet peint */
.oeil {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--data);
  font-size: 0.735rem;
  font-weight: 500;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.4rem;
}
.oeil::before {
  content: "";
  flex: none;
  width: 1.9rem;
  height: 6px;
  background: var(--accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 8' preserveAspectRatio='none'%3E%3Cpath d='M0 5.4c6-2.1 10-3.3 16-3.6 7-.4 12 1.4 24 .7v3.9C28 7.1 23 5.6 16 6 10 6.3 6 7 0 8Z'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 8' preserveAspectRatio='none'%3E%3Cpath d='M0 5.4c6-2.1 10-3.3 16-3.6 7-.4 12 1.4 24 .7v3.9C28 7.1 23 5.6 16 6 10 6.3 6 7 0 8Z'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
}
.oeil--centre { justify-content: center; }

.donnee {
  font-family: var(--data);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  font-weight: 500;
}

/* --------------------------------------------------------- 4. Trame */

.enveloppe {
  width: 100%;
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}
.enveloppe--large { max-width: var(--page-large); }
.enveloppe--etroite { max-width: 860px; }

.bloc { padding-block: var(--rythme); position: relative; }
.bloc--serre { padding-block: clamp(3rem, 6vw, 5rem); }
.bloc--haut-nul { padding-top: 0; }

/* Lavis de craie dans la teinte courante */
.bloc--lavis::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(58% 62% at 8% 0%, var(--accent-voile), transparent 70%),
    radial-gradient(48% 55% at 96% 88%, var(--accent-voile), transparent 72%);
}
.bloc--lavis > * { position: relative; z-index: 1; }

.bloc--papier { background: var(--papier-2); }
.bloc--encre {
  background: var(--encre);
  color: var(--papier-3);
}
.bloc--encre h2,
.bloc--encre h3 { color: var(--papier); }
.bloc--encre .oeil { color: var(--accent-clair); }
.bloc--encre .oeil::before { background: var(--accent-clair); }

.duo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
.duo--penche { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); }
.duo--haut { align-items: start; }
.duo--portrait { grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr); }

/* Les deux colonnes partent du même bord haut. Les caler par le bas avec un
   `align-items: end` sur la grille — ce que faisait cette règle — ne tient que
   tant que l'introduction reste de la hauteur du titre : passé deux
   paragraphes, c'est la colonne de gauche qui descend, et l'étiquette du bloc
   se retrouve au milieu du vide. Le texte vient du panneau, sa longueur n'est
   donc jamais acquise. */
.entete-bloc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: start;
  margin-bottom: clamp(2.2rem, 4vw, 3.6rem);
}

/* L'introduction, elle, s'assoit sur la même ligne de base que le bas du
   titre : deux ou trois lignes de texte suspendues en haut d'un titre de deux
   lignes laissaient un vide au milieu de l'en-tête.
   C'est l'introduction seule qui descend, pas la grille : elle occupe toute la
   hauteur de la rangée et pousse son texte vers le bas. Le titre garde donc
   son bord haut quoi qu'il arrive — et si l'introduction devient plus haute
   que lui, c'est elle qui fixe la rangée et rien ne bouge.
   Sur un en-tête empilé, le chapeau partage sa rangée avec les escales et doit
   partir du haut comme elles ; et `cote`, quand un appelant le compose
   lui-même, ne passe pas par `.chapeau` et n'est pas concerné.
   La descente se fait par une marge haute automatique, qui absorbe le vide de
   la rangée avant tout alignement. Un `display: flex` donnait le même résultat
   et coûtait une ligne : dans une flexe, chaque enfant devient un élément à
   part entière, et une italique ou un lien au milieu de la phrase — « accueille
   *Die Palatöne* du 6 au 11 octobre » — partait seul à la ligne. */
.entete-bloc:not(.entete-bloc--empile) > .chapeau {
  margin-block-start: auto;
}
/* La marge sépare l'en-tête de ce qui le suit. Quand le bloc n'a rien d'autre
   — le répertoire, qui range ses escales DANS la colonne — elle s'ajoute au
   creux de la section et le double. */
.entete-bloc:last-child { margin-bottom: 0; }

/* En-tête à deux étages : le titre tient la première rangée à lui seul, et la
   seconde porte les deux colonnes — les escales à gauche, l'introduction à
   droite, toutes deux partant de la même ligne. Le titre coiffe ainsi le bloc
   entier au lieu de n'être que la tête d'une colonne.

   Les trois places sont écrites, aucune n'est laissée au placement
   automatique : il range d'abord ce qui a une rangée déclarée, si bien que le
   chapeau passait devant le titre et prenait la colonne de gauche. */
.entete-bloc--empile > .entete-bloc__texte { grid-column: 1; grid-row: 1; }
.entete-bloc--empile > :nth-child(2)       { grid-column: 2; grid-row: 2; }
.entete-bloc--empile > .entete-bloc__bas   { grid-column: 1; grid-row: 2; }


/* Le fil — filet tremblé, motif emprunté au dossier de presse
   « chaque voix devient un fil… » */
.fil {
  display: block;
  width: 100%;
  height: 9px;
  color: var(--accent);
  opacity: 0.5;
}
.fil path { stroke: currentColor; stroke-width: 1.6; fill: none; }

/* --------------------------------------------------------- 5. Liens & boutons */

a { color: inherit; }

.lien {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1.5px;
  transition: background-size 0.4s cubic-bezier(0.22, 1, 0.36, 1);
  padding-bottom: 1px;
}
.lien:hover, .lien:focus-visible { background-size: 100% 1.5px; }

.lien-fleche {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--data);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--accent);
}
.lien-fleche span:last-child { transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1); }
.lien-fleche:hover span:last-child,
.lien-fleche:focus-visible span:last-child { transform: translateX(5px); }

.boutons { display: flex; flex-wrap: wrap; gap: 0.8rem; }

.bouton {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.92rem 1.6rem;
  border-radius: var(--r-pilule);
  border: 1.5px solid var(--accent);
  background: var(--accent);
  color: var(--papier);
  font-family: var(--corps);
  font-size: 0.94rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.3s, background 0.3s, color 0.3s;
}
.bouton:hover, .bouton:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px -12px color-mix(in srgb, var(--accent) 70%, transparent);
}
.bouton--creux {
  background: transparent;
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 42%, transparent);
}
.bouton--creux:hover, .bouton--creux:focus-visible {
  background: var(--accent);
  color: var(--papier);
  border-color: var(--accent);
}
.bloc--encre .bouton--creux { color: var(--papier); border-color: rgba(251, 247, 240, 0.35); }
.bloc--encre .bouton--creux:hover { background: var(--papier); color: var(--encre); border-color: var(--papier); }

:where(a, button, input, textarea, select, summary):focus-visible {
  outline: 2.5px solid var(--accent-clair);
  outline-offset: 3px;
  border-radius: 3px;
}

.saut-contenu {
  position: absolute;
  left: 1rem;
  top: -100px;
  z-index: 200;
  background: var(--encre);
  color: var(--papier);
  padding: 0.7rem 1.1rem;
  border-radius: var(--r-pilule);
  text-decoration: none;
  font-size: 0.9rem;
  transition: top 0.2s;
}
.saut-contenu:focus { top: 1rem; }

/* --------------------------------------------------------- 6. En-tête */

.entete {
  position: sticky;
  top: 0;
  z-index: 120;
  background: color-mix(in srgb, var(--papier) 86%, transparent);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.35s, background 0.35s;
}
.entete[data-glisse="oui"] { border-bottom-color: var(--trait-fin); }

.entete__interieur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  height: 5.5rem;
}

.marque { display: inline-flex; align-items: center; text-decoration: none; flex: none; }
.marque img { height: clamp(2.55rem, 3.6vw, 3.15rem); width: auto; }

.nav { display: flex; align-items: center; gap: clamp(0.55rem, 1.5vw, 1.55rem); }

.nav__lien {
  position: relative;
  text-decoration: none;
  font-size: 0.925rem;
  font-weight: 500;
  color: var(--encre-80);
  padding: 0.4rem 0;
  transition: color 0.25s;
  white-space: nowrap;
}
.nav__lien::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 5px;
  background: var(--accent);
  opacity: 0;
  transform: scaleX(0.4);
  transform-origin: left;
  transition: opacity 0.3s, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 8' preserveAspectRatio='none'%3E%3Cpath d='M0 5.4c6-2.1 10-3.3 16-3.6 7-.4 12 1.4 24 .7v3.9C28 7.1 23 5.6 16 6 10 6.3 6 7 0 8Z'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 8' preserveAspectRatio='none'%3E%3Cpath d='M0 5.4c6-2.1 10-3.3 16-3.6 7-.4 12 1.4 24 .7v3.9C28 7.1 23 5.6 16 6 10 6.3 6 7 0 8Z'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
}
.nav__lien:hover, .nav__lien:focus-visible { color: var(--encre); }
.nav__lien:hover::after { opacity: 0.55; transform: scaleX(1); }
.nav__lien[aria-current="page"] { color: var(--encre); font-weight: 600; }
.nav__lien[aria-current="page"]::after { opacity: 1; transform: scaleX(1); }

.nav__bouton { margin-left: 0.35rem; padding: 0.62rem 1.15rem; font-size: 0.88rem; }

.burger {
  display: none;
  width: 2.9rem;
  height: 2.9rem;
  border: 1px solid var(--trait);
  border-radius: var(--r-pilule);
  background: transparent;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex: none;
}
.burger span {
  display: block;
  width: 17px;
  height: 1.5px;
  background: var(--encre);
  position: relative;
  transition: background 0.2s;
}
.burger span::before,
.burger span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 17px;
  height: 1.5px;
  background: var(--encre);
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.burger span::before { top: -5.5px; }
.burger span::after { top: 5.5px; }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { transform: translateY(5.5px) rotate(45deg); }
.burger[aria-expanded="true"] span::after { transform: translateY(-5.5px) rotate(-45deg); }

/* --------------------------------------------------------- 7. Ouverture */

.ouverture {
  position: relative;
  padding-block: clamp(2rem, 4vw, 3.4rem) clamp(3.5rem, 7vw, 5.5rem);
  overflow: hidden;
  transition: --accent 1.1s ease, --accent-clair 1.1s ease, --accent-voile 1.1s ease;
}
.ouverture::before {
  content: "";
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 130%;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(46% 52% at 12% 8%, var(--accent-voile), transparent 68%),
    radial-gradient(40% 46% at 88% 72%, var(--accent-voile), transparent 70%);
  transition: background 1.2s ease;
}
.ouverture > * { position: relative; z-index: 1; }

/* La photo mène : elle prend la plus large des deux colonnes, et son bord
   haut se pose sur celui du logo plutôt qu'au milieu de la rangée. Centrée,
   elle commençait plus bas que le mot « Canta de Joia » et finissait plus bas
   que les boutons — deux décalages qu'aucun œil ne lit comme un alignement. */
.ouverture__trame {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

/* Les quatre versions du mot sont empilées et se fondent l'une dans l'autre.
   Un seul <img> dont on échangerait la source clignoterait : le fondu
   passerait par le vide plutôt que par l'autre couleur. Celle qui arrive
   monte au-dessus et devient opaque avant que la précédente ne s'efface —
   le dessin étant le même, il n'y a aucun moment où l'encre pâlit. */
.ouverture__logo {
  position: relative;
  width: min(100%, 29.5rem);
  aspect-ratio: 1200 / 1176;
  margin: 0 0 clamp(1.1rem, 2.2vw, 1.7rem) -0.5%;
}
.ouverture__logo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity 1.05s ease;
}
.ouverture__logo img[data-actif="oui"] { opacity: 1; }

.ouverture__phrase {
  font-family: var(--display);
  font-variation-settings: "SOFT" 62, "WONK" 1;
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.5rem, 0.95rem + 1.95vw, 2.35rem);
  line-height: 1.24;
  letter-spacing: -0.024em;
  margin: 0 0 1.3rem;
  max-width: 20ch;
}
.ouverture__phrase b { font-weight: 600; font-style: normal; color: var(--accent); }

.ouverture__texte { max-width: 46ch; color: var(--encre-80); margin-bottom: 1.9rem; }

/* Panneau photo — la déclinaison de couleurs.

   En paysage, et c'est ce que les photos sont : trois des quatre déclinaisons
   sont prises en largeur. Debout, le cadre les découpait deux fois — une
   première pour fabriquer la vignette en 4/5, une seconde par le cadre
   lui-même, presque carré sur un écran large. Il restait un peu moins de la
   moitié de la photo, prise au milieu, c'est-à-dire sans les choristes des
   deux bords. Couché, le cadre épouse la photo et les deux découpes tombent. */
.panneau {
  position: relative;
  aspect-ratio: 3 / 2;
  border-radius: var(--r-image);
  overflow: hidden;
  background: var(--papier-3);
  box-shadow: var(--ombre-portee);
}
.panneau img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.045);
  transition: opacity 1.3s ease, transform 8s linear;
}
.panneau img[data-actif="oui"] { opacity: 1; transform: scale(1); }

.nuancier {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: 1.15rem;
}
.nuancier__legende {
  font-family: var(--data);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--pierre-clair);
  margin-left: 0.35rem;
  white-space: nowrap;
}
.pastille {
  width: 1.35rem;
  height: 1.35rem;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  border-radius: 50%;
  position: relative;
  flex: none;
}
.pastille::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--pastille);
  transform: scale(0.58);
  opacity: 0.4;
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s;
}
.pastille:hover::after { transform: scale(0.78); opacity: 0.7; }
.pastille[aria-pressed="true"]::after { transform: scale(1); opacity: 1; }

/* --------------------------------------------------------- 8. Cartes & listes */

.carte {
  display: flex;
  flex-direction: column;
  background: var(--papier);
  border: 1px solid var(--trait-fin);
  border-radius: var(--r-carte);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.45s, border-color 0.45s;
}
a.carte:hover, a.carte:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--ombre-douce);
  border-color: color-mix(in srgb, var(--accent) 32%, transparent);
}
.carte__image { position: relative; aspect-ratio: 3 / 2; overflow: hidden; background: var(--papier-3); }
.carte__image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1); }
a.carte:hover .carte__image img { transform: scale(1.045); }
.carte__corps { padding: 1.4rem 1.5rem 1.6rem; display: flex; flex-direction: column; gap: 0.6rem; flex: 1; }
.carte__meta { font-family: var(--data); font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }
.carte__pied { margin-top: auto; padding-top: 0.9rem; }

/* Musiciens et équipes — une personne par ligne.

   C'étaient des cartes en colonnes. La dernière rangée n'était presque jamais
   pleine : à cinq musiciens sur quatre colonnes, le cinquième restait seul à
   gauche d'un vide de trois cases, et les deux équipes de trois laissaient
   chacune une case vide. Le nombre de personnes n'est pas un multiple du
   nombre de colonnes, et rien ne le fera l'être.

   La ligne n'a pas de rangée à remplir. Elle reprend la grammaire de l'agenda
   — une colonne étroite, puis le texte, séparés par un filet — et rend au
   passage les textes lisibles en largeur : de 154 à 593 signes, ils
   s'étiraient en colonne étroite. */

.portraits-lignes { display: grid; }

.portrait-ligne {
  display: grid;
  /* Douze rem pour le portrait, et non huit. Le texte n'y perd rien : il
     s'arrête de toute façon à sa mesure de lecture, si bien que la colonne
     gagnée est prise sur le vide de droite et non sur le paragraphe. À huit
     rem, un visage faisait cent vingt-huit pixels — une vignette. */
  grid-template-columns: minmax(0, 12rem) minmax(0, 12rem) minmax(0, 1fr);
  gap: clamp(1.1rem, 2.6vw, 2.2rem);
  align-items: start;
  padding-block: clamp(1.4rem, 2.8vw, 2rem);
  border-bottom: 1px solid var(--trait-fin);
}
.portrait-ligne:first-child { padding-top: 0; }
.portrait-ligne:last-child { border-bottom: none; padding-bottom: 0; }

/* Tant qu'aucune photo n'est arrivée, la colonne du portrait disparaît au lieu
   de tenir sa largeur pour rien — sans quoi chaque ligne s'ouvrirait sur un
   vide de huit rem. */
.portraits-lignes--sans-photo .portrait-ligne {
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
}

.portrait-ligne__image {
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--r-image);
  background: var(--papier-3);
  box-shadow: var(--ombre-douce);
}
.portrait-ligne__image img { width: 100%; height: 100%; object-fit: cover; display: block; }

.portrait-ligne__qui .carte__meta { margin-bottom: 0.35rem; }

/* Le texte s'arrête à la mesure de lecture, et non au bord de la page : sur un
   écran large, la ligne fait plus de mille pixels et l'œil ne retrouve plus le
   début de la ligne suivante. */
.portrait-ligne__mot { max-width: 62ch; }

.grille { display: grid; gap: clamp(1.1rem, 2.2vw, 1.8rem); }
.grille--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grille--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grille--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }



/* À la une — l'affiche tient dans une colonne étroite, le texte mène */
.une {
  display: grid;
  grid-template-columns: minmax(0, 1.34fr) minmax(0, 0.66fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.une__affiche { margin: 0; display: flex; flex-direction: column; align-items: center; }
.une__affiche img {
  height: min(41vw, 640px);
  width: auto;
  max-width: 100%;
  border-radius: var(--r-image);
  box-shadow: var(--ombre-portee);
}
@media (max-width: 940px) {
  .une__affiche img { height: auto; width: min(100%, 22rem); }
  .une__affiche { align-items: flex-start; }
}

/* Répertoire — le carnet de route, en grands caractères */
.escales {
  font-family: var(--display);
  font-variation-settings: "SOFT" 48, "WONK" 1;
  font-size: clamp(1.7rem, 1rem + 2.6vw, 3rem);
  line-height: 1.22;
  letter-spacing: -0.03em;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.55em;
  row-gap: 0.12em;
  max-width: 25ch;
}
.escales li { display: inline-flex; align-items: baseline; gap: 0.55em; }
.escales li::after {
  content: "";
  width: 0.19em;
  height: 0.19em;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.45;
  transform: translateY(-0.28em);
}
.escales li:last-child::after { display: none; }
.escales span { transition: color 0.3s; cursor: default; }
.escales span:hover { color: var(--accent); }

/* Agenda — une ligne, un lien.

   La ligne entière est le lien plutôt qu'un bouton posé au bout : la cible
   est grande, le lecteur d'écran annonce le titre du concert au lieu d'un
   « En savoir plus » qui ne dit rien, et le clavier ne s'arrête qu'une fois
   par événement. La flèche reste comme signe, pas comme cible. */
.agenda { border-top: 1px solid var(--trait); }

.ligne {
  display: grid;
  grid-template-columns: minmax(0, 9.5rem) minmax(0, 1fr) auto auto;
  gap: clamp(1rem, 3vw, 2.5rem);
  align-items: start;
  padding: clamp(1.5rem, 3vw, 2.2rem) clamp(0.6rem, 1.4vw, 1.1rem);
  margin-inline: clamp(-1.1rem, -1.4vw, -0.6rem);
  border-bottom: 1px solid var(--trait-fin);
  text-decoration: none;
  color: inherit;
  border-radius: var(--r-carte);
  transition: background 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.ligne:hover, .ligne:focus-visible { background: var(--accent-voile); }

.ligne__folio {
  font-family: var(--data);
  font-size: 0.78rem;
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--accent);
  text-transform: uppercase;
  padding-top: 0.35rem;
  display: block;
}
.ligne__folio b {
  display: block;
  font-size: 2.1rem;
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
  margin-bottom: 0.3rem;
}

.ligne__texte { display: block; }
.ligne__titre { margin-bottom: 0.35rem; transition: color 0.3s; }
.ligne:hover .ligne__titre { color: var(--accent); }
.ligne__sous { display: block; color: var(--pierre); font-size: 0.985rem; margin-bottom: 0.5rem; }
.ligne__meta {
  display: block;
  font-family: var(--data);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  color: var(--pierre-clair);
  text-transform: uppercase;
  margin-bottom: 0.7rem;
}
.ligne__chapeau { display: block; color: var(--pierre); font-size: 0.96rem; max-width: 56ch; }

/* Le cadre reste même sans photo, sinon la grille se déplacerait d'une
   ligne à l'autre. */
.ligne__vignette {
  display: block;
  width: 11rem;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-image);
  overflow: hidden;
  background: var(--papier-3);
}
.ligne__vignette img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1); }
.ligne:hover .ligne__vignette img { transform: scale(1.05); }
.ligne__vignette--vide {
  border: 1.5px dashed var(--trait);
  background: transparent;
}

.ligne__fleche {
  align-self: center;
  font-size: 1.05rem;
  color: var(--accent);
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.35s, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.ligne:hover .ligne__fleche, .ligne:focus-visible .ligne__fleche { opacity: 1; transform: none; }

.ligne--passee { opacity: 0.84; }
.ligne--passee .ligne__folio { color: var(--pierre-clair); }
.ligne--passee:hover { opacity: 1; }

/* Sur l'accueil, à côté de l'affiche : la même ligne, resserrée. */
.agenda--serre .ligne { padding-block: 1.25rem; grid-template-columns: minmax(0, 8rem) minmax(0, 1fr) auto auto; }
.agenda--serre .ligne__chapeau { display: none; }
.agenda--serre .ligne__vignette { width: 7.5rem; }
.agenda--serre .ligne__folio b { font-size: 1.75rem; }

/* Citation */
.citation { max-width: 38ch; }
.citation__texte {
  font-family: var(--display);
  font-variation-settings: "SOFT" 58, "WONK" 1;
  font-style: italic;
  font-size: clamp(1.35rem, 1rem + 1.4vw, 2rem);
  line-height: 1.34;
  letter-spacing: -0.022em;
  margin: 0 0 1.1rem;
}
.citation__source {
  font-family: var(--data);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pierre);
  font-style: normal;
}
.bloc--encre .citation__source { color: var(--pierre-clair); }
.citation--large { max-width: 46ch; }
.citation--large .citation__texte { font-size: clamp(1.28rem, 1rem + 1.05vw, 1.72rem); line-height: 1.4; }

.guillemet {
  font-family: var(--display);
  font-size: 5rem;
  line-height: 0.6;
  color: var(--accent);
  opacity: 0.32;
  display: block;
  margin-bottom: 0.4rem;
}

/* Les équipes — une grille de cartes par équipe, empilées. L'intertitre
   s'écarte de sa grille davantage que les cartes ne s'écartent entre elles,
   sans quoi il paraîtrait coiffer la seule première d'entre elles. */
.equipe { margin-top: clamp(2.2rem, 4vw, 3.2rem); }
.equipe + .equipe { margin-top: clamp(3rem, 5.5vw, 4.4rem); }
.equipe__nom { margin-bottom: clamp(1.6rem, 3.2vw, 2.6rem); }

/* Vidéos */
.video { margin: 0; }

/* L'image d'attente d'une vidéo extérieure.
   Le lecteur n'arrive qu'au clic : ce cadre tient sa place, dans la même forme
   et le même rayon, pour que rien ne saute au moment de la bascule. Sans image
   fournie, l'aplat d'encre suffit — c'est déjà le fond du lecteur. */
.video__attente {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-image);
  overflow: hidden;
  background: var(--encre);
}
.video__attente::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--video-image, none);
  background-size: cover;
  background-position: center;
  /* L'image est assourdie pour que le disque de lecture s'en détache, et
     reprend ses couleurs au survol : la vignette dit alors « clique ». */
  filter: saturate(0.85) brightness(0.82);
  transition: filter 0.4s ease, transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.video__lire {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  text-decoration: none;
}
.video__triangle {
  width: clamp(3.4rem, 7vw, 4.6rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--papier);
  box-shadow: 0 0.6rem 2rem rgba(28, 21, 18, 0.45);
  display: grid;
  place-items: center;
  transition:
    transform 0.35s cubic-bezier(0.22, 1, 0.36, 1),
    background 0.35s ease;
}
/* Le triangle est dessiné en bordures : pas de fichier, pas de police, et il
   suit la couleur d'accent du bloc où la vidéo se trouve. */
.video__triangle::after {
  content: "";
  width: 0;
  height: 0;
  margin-left: 0.22em;
  border-left: 1.05rem solid var(--accent);
  border-top: 0.66rem solid transparent;
  border-bottom: 0.66rem solid transparent;
}
.video__lire:hover .video__triangle,
.video__lire:focus-visible .video__triangle {
  transform: scale(1.08);
  background: #fff;
}
.video__attente:hover::before {
  filter: saturate(1) brightness(0.92);
  transform: scale(1.02);
}
@media (prefers-reduced-motion: reduce) {
  .video__attente::before, .video__triangle { transition: none; }
  .video__attente:hover::before { transform: none; }
}

.video iframe, .video video {
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--r-image);
  background: var(--encre);
  display: block;
}
.video__legende { margin-top: 0.85rem; display: grid; gap: 0.15rem; }
.video__legende b { font-weight: 600; font-size: 1.02rem; }
.video__legende span { color: var(--pierre); font-size: 0.95rem; }
.video__legende i {
  font-family: var(--data);
  font-style: normal;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: var(--pierre-clair);
}

/* Le mur des paroles — filmées et écrites, dans la même maçonnerie.

   Les vidéos sont verticales, filmées au téléphone : leur donner une colonne
   entière est ce qui leur rend justice, et ce qui rend les sous-titres
   lisibles.

   La phrase à retenir est posée sur l'image d'attente, pas en dessous. Sous
   la vidéo, dans une maçonnerie, elle se lisait comme l'introduction de la
   vignette suivante — rien ne disait à quoi elle se rattachait. Dessus, la
   carte se réduit à une seule chose à regarder. */
.mur {
  columns: 3;
  column-gap: clamp(1rem, 2vw, 1.6rem);
}
/* La bande du public s'ouvre avec deux ou trois paroles, rarement plus. À
   trois colonnes, deux citations laissent un tiers de la largeur vide et une
   seule se réduit à une colonne étroite au bord gauche. */
.mur--deux { columns: 2; }
.mur--une { columns: 1; max-width: 62ch; }

.parole {
  break-inside: avoid;
  margin: 0 0 clamp(1.6rem, 3vw, 2.6rem);
  display: block;
}

.parole__cadre {
  position: relative;
  border-radius: var(--r-image);
  overflow: hidden;
  background: var(--encre);
  box-shadow: var(--ombre-douce);
}

.parole__video {
  width: 100%;
  aspect-ratio: 9 / 16;
  object-fit: cover;
  display: block;
}

/* Les sous-titres.
 *
 * ::cue n'accepte qu'une poignée de propriétés : la police, la couleur, le
 * fond, l'ombre. Ni padding ni margin — la spécification ne les prévoit pas,
 * et le navigateur les ignore en silence. D'où trois détours :
 *
 *   border-radius: 0  celui-là, en revanche, est bien appliqué : il carre les
 *                     bouts de ligne, que le navigateur arrondissait.
 *   line-height       la boîte de fond épouse la line box : l'augmenter donne
 *                     la marge verticale qu'on ne peut pas demander.
 *   une espace insécable de part et d'autre de chaque réplique, dans le
 *                     fichier VTT, pour la marge horizontale — c'est le seul
 *                     moyen d'écarter le fond du texte sur les côtés.
 *
 * Le placement dans l'image (line, size) se règle lui aussi dans le VTT.
 */
.parole__video::cue {
  font-family: var(--corps);
  font-size: 1.15em;
  line-height: 1.85;
  border-radius: 0;
  background: rgba(20, 15, 12, 0.85);
  color: #fbf7f0;
}

/* Le voile — ce qu'on lit avant d'écouter. */
.parole__voile {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.55rem;
  padding: 1.4rem 1.3rem 1.5rem;
  cursor: pointer;
  color: var(--papier);
  /* Un dégradé plutôt qu'un aplat : le visage reste visible en haut, le texte
     lisible en bas, sans que la photographie disparaisse sous un voile. */
  background: linear-gradient(
    to bottom,
    rgba(20, 15, 12, 0) 0%,
    rgba(20, 15, 12, 0.15) 38%,
    rgba(20, 15, 12, 0.62) 68%,
    rgba(20, 15, 12, 0.88) 100%
  );
  transition: opacity 0.45s ease, visibility 0.45s ease;
}
.parole__cadre[data-lecture="oui"] .parole__voile {
  opacity: 0;
  visibility: hidden;
}

.parole__voile .parole__citation {
  margin: 0;
  font-family: var(--display);
  font-variation-settings: "SOFT" 54, "WONK" 1;
  font-size: 1.16rem;
  line-height: 1.38;
  letter-spacing: -0.016em;
  text-shadow: 0 1px 12px rgba(20, 15, 12, 0.5);
}
.parole__voile .parole__citation p { margin: 0; }

.parole__voile .parole__qui {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem;
  margin: 0;
  font-style: normal;
}
.parole__voile .parole__qui b { font-weight: 600; font-size: 0.94rem; }
.parole__voile .parole__qui span {
  font-family: var(--data);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(251, 247, 240, 0.78);
}
.parole__voile .parole__qui em {
  font-family: var(--data);
  font-style: normal;
  font-size: 0.63rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--papier);
  border: 1px solid rgba(251, 247, 240, 0.45);
  border-radius: var(--r-pilule);
  padding: 0.1rem 0.45rem;
}

.parole__lire {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  align-self: flex-start;
  margin-top: 0.35rem;
  padding: 0.5rem 0.95rem 0.5rem 0.8rem;
  border: 1px solid rgba(251, 247, 240, 0.4);
  border-radius: var(--r-pilule);
  background: rgba(251, 247, 240, 0.12);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--papier);
  font-family: var(--data);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.3s, border-color 0.3s, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.parole__voile:hover .parole__lire {
  background: rgba(251, 247, 240, 0.22);
  border-color: rgba(251, 247, 240, 0.7);
  transform: translateY(-1px);
}
.parole__triangle {
  width: 0;
  height: 0;
  border-left: 0.55rem solid currentColor;
  border-top: 0.35rem solid transparent;
  border-bottom: 0.35rem solid transparent;
}

/* La parole écrite : même famille, moins de matière. */
.parole--ecrite {
  background: var(--papier-2);
  border: 1px solid var(--trait-fin);
  border-radius: var(--r-carte);
  padding: 1.6rem 1.5rem 1.7rem;
}
.parole--ecrite .guillemet { font-size: 3.4rem; margin-bottom: 0.15rem; }
.parole--ecrite .parole__citation {
  margin: 0;
  font-family: var(--display);
  font-variation-settings: "SOFT" 54, "WONK" 1;
  font-size: 1.1rem;
  line-height: 1.44;
  letter-spacing: -0.014em;
  font-style: italic;
}
.parole--ecrite .parole__qui {
  display: block;
  margin: 0.8rem 0 0;
  font-style: normal;
}
.parole--ecrite .parole__qui span {
  font-family: var(--data);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pierre);
}

/* Chiffres-clés */
.reperes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1.2rem, 3vw, 2.5rem); }
.repere { border-top: 2px solid var(--accent); padding-top: 0.95rem; }
.repere__valeur {
  font-family: var(--display);
  font-variation-settings: "SOFT" 46, "WONK" 1;
  font-size: clamp(1.7rem, 1.2rem + 1.7vw, 2.5rem);
  letter-spacing: -0.035em;
  line-height: 1;
  margin-bottom: 0.35rem;
}
.repere__note { font-size: 0.92rem; color: var(--pierre); line-height: 1.45; }

/* Cadre photo — cadrage homogène dans toutes les pages */
.figure-cadre { margin: 0; }
.figure-cadre img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-image);
  box-shadow: var(--ombre-douce);
}
.figure-cadre--portrait img { aspect-ratio: 4 / 5; }
.figure-cadre--carre img { aspect-ratio: 1 / 1; }
.figure-cadre--large img { aspect-ratio: 16 / 9; }
.figure-cadre--libre img { aspect-ratio: auto; }
.figure-cadre figcaption { margin-top: 0.85rem; }

/* Portrait */
.portrait { position: relative; }
.portrait img { width: 100%; border-radius: var(--r-image); box-shadow: var(--ombre-douce); }
.portrait__legende {
  font-family: var(--data);
  font-size: 0.73rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pierre-clair);
  margin-top: 0.85rem;
}

/* Mosaïque d'images */
.mosaique { display: grid; grid-template-columns: repeat(12, 1fr); gap: clamp(0.5rem, 1.1vw, 0.85rem); }
.mosaique figure { margin: 0; overflow: hidden; border-radius: var(--r-image); background: var(--papier-3); }
.mosaique img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1); }
.mosaique figure:hover img { transform: scale(1.05); }
.m-4 { grid-column: span 4; aspect-ratio: 1 / 1; }
.m-5 { grid-column: span 5; aspect-ratio: 4 / 3; }
.m-6 { grid-column: span 6; aspect-ratio: 3 / 2; }
.m-7 { grid-column: span 7; aspect-ratio: 16 / 10; }
.m-8 { grid-column: span 8; aspect-ratio: 16 / 9; }
.m-12 { grid-column: span 12; aspect-ratio: 21 / 9; }

/* Galerie filtrable */
.filtres { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: clamp(1.8rem, 3vw, 2.6rem); }
.filtre {
  font-family: var(--corps);
  font-size: 0.88rem;
  font-weight: 500;
  padding: 0.55rem 1.05rem;
  border-radius: var(--r-pilule);
  border: 1px solid var(--trait);
  background: transparent;
  color: var(--encre-80);
  cursor: pointer;
  transition: all 0.3s;
}
.filtre:hover { border-color: color-mix(in srgb, var(--accent) 45%, transparent); color: var(--encre); }
.filtre[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--papier); }

.galerie { columns: 3; column-gap: clamp(0.6rem, 1.2vw, 0.9rem); }
.galerie figure {
  margin: 0 0 clamp(0.6rem, 1.2vw, 0.9rem);
  break-inside: avoid;
  border-radius: var(--r-image);
  overflow: hidden;
  background: var(--papier-3);
  cursor: zoom-in;
  position: relative;
}
.galerie img { width: 100%; transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1), filter 0.5s; }
.galerie figure:hover img { transform: scale(1.045); }
.galerie figure[hidden] { display: none; }

/* Visionneuse */
.visionneuse {
  position: fixed;
  inset: 0;
  z-index: 500;
  background: rgba(20, 15, 12, 0.94);
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s, visibility 0.35s;
}
.visionneuse[data-ouverte="oui"] { opacity: 1; visibility: visible; }
.visionneuse img { max-width: 100%; max-height: 84vh; border-radius: var(--r-image); box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.9); }
.visionneuse__legende {
  color: var(--papier-3);
  font-family: var(--data);
  font-size: 0.78rem;
  letter-spacing: 0.09em;
  text-align: center;
  margin-top: 1rem;
}
.visionneuse__fermer,
.visionneuse__nav {
  position: absolute;
  background: rgba(251, 247, 240, 0.1);
  border: 1px solid rgba(251, 247, 240, 0.22);
  color: var(--papier);
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 1.1rem;
  transition: background 0.25s, transform 0.25s;
}
.visionneuse__fermer:hover,
.visionneuse__nav:hover { background: rgba(251, 247, 240, 0.24); }
.visionneuse__fermer { top: clamp(1rem, 3vw, 2rem); right: clamp(1rem, 3vw, 2rem); }
.visionneuse__nav--prec { left: clamp(0.6rem, 3vw, 2rem); top: 50%; transform: translateY(-50%); }
.visionneuse__nav--suiv { right: clamp(0.6rem, 3vw, 2rem); top: 50%; transform: translateY(-50%); }

/* Encart à compléter — visible pour la relecture, à retirer avant mise en ligne */
.a-completer {
  border: 1.5px dashed color-mix(in srgb, var(--pierre) 45%, transparent);
  border-radius: var(--r-carte);
  padding: 1.15rem 1.35rem;
  background: color-mix(in srgb, var(--papier-2) 70%, transparent);
  color: var(--pierre);
  font-size: 0.93rem;
  line-height: 1.55;
}
.a-completer strong {
  display: block;
  font-family: var(--data);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.4rem;
  font-weight: 500;
}

/* Formulaire */
.formulaire { display: grid; gap: 1.05rem; }
.champ { display: grid; gap: 0.42rem; }
.champ label {
  font-family: var(--data);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pierre);
}
.champ input,
.champ textarea,
.champ select {
  font-family: var(--corps);
  font-size: 1rem;
  color: var(--encre);
  background: var(--papier);
  border: 1px solid var(--trait);
  border-radius: var(--r-carte);
  padding: 0.82rem 1rem;
  width: 100%;
  transition: border-color 0.25s, box-shadow 0.25s;
}
.champ textarea { min-height: 9.5rem; resize: vertical; }
.champ input:focus,
.champ textarea:focus,
.champ select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-voile);
}

/* Liste de contact */
.contact-liste { display: grid; gap: 1.4rem; margin: 0; }
.contact-liste div { display: grid; gap: 0.2rem; }
.contact-liste dt {
  font-family: var(--data);
  font-size: 0.71rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--pierre);
}
.contact-liste dd { margin: 0; font-size: 1.06rem; }

/* --------------------------------------------------------- 9. Pied de page */

.pied { background: var(--encre); color: var(--papier-3); padding-block: clamp(3.5rem, 6vw, 5.5rem) 2.2rem; }
.pied__haut {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) repeat(3, minmax(0, 0.85fr));
  gap: clamp(1.8rem, 4vw, 3.5rem);
  padding-bottom: clamp(2.5rem, 5vw, 3.5rem);
  border-bottom: 1px solid rgba(251, 247, 240, 0.14);
}
.pied img.pied__logo { width: 11rem; margin-bottom: 1.15rem; }
.pied h3 {
  font-family: var(--data);
  font-size: 0.71rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--pierre-clair);
  margin-bottom: 1rem;
}
.pied ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.pied a { color: var(--papier-3); text-decoration: none; transition: color 0.25s; font-size: 0.96rem; }
.pied a:hover, .pied a:focus-visible { color: var(--papier); }
.pied__note { color: var(--pierre-clair); font-size: 0.95rem; line-height: 1.6; max-width: 34ch; }
.pied__bas {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  padding-top: 1.7rem;
  font-family: var(--data);
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  color: var(--pierre-clair);
}

/* --------------------------------------------------------- 10. Bannière de page */

.banniere { position: relative; padding-block: clamp(3rem, 6vw, 5rem) clamp(2.5rem, 5vw, 4rem); overflow: hidden; }
.banniere::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(52% 78% at 6% 0%, var(--accent-voile), transparent 68%);
}
.banniere > * { position: relative; z-index: 1; }
.banniere__trame { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.78fr); gap: clamp(1.5rem, 4vw, 4rem); align-items: end; }
.banniere__titre { margin-bottom: 1.1rem; }

.sommaire { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-top: 1.6rem; }
.sommaire a {
  font-family: var(--data);
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--encre-80);
  border: 1px solid var(--trait);
  border-radius: var(--r-pilule);
  padding: 0.48rem 0.95rem;
  transition: all 0.28s;
}
.sommaire a:hover, .sommaire a:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-voile);
}

/* Programme — le déroulé jour par jour */
.programme { border-top: 1px solid var(--trait); }
.jour {
  display: grid;
  grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
  gap: clamp(0.5rem, 3vw, 3rem);
  padding: clamp(1.5rem, 3vw, 2.3rem) 0;
  border-bottom: 1px solid var(--trait-fin);
}
.jour__date {
  font-family: var(--data);
  font-size: 0.79rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0.3rem 0 0;
}
.jour__corps { max-width: 68ch; }
.jour__corps h3 { margin-bottom: 0.75rem; }

.liste-simple {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
  color: var(--pierre);
}
.liste-simple li { position: relative; padding-left: 1.15rem; }
.liste-simple li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 0.42rem;
  height: 0.42rem;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.6;
}
.jour__corps .liste-simple + p { margin-top: 1rem; }
.bloc--encre .liste-simple { color: var(--papier-3); }

.visuellement-cache {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------- 11. Les choristes */

/* La mosaïque des portraits. Une cinquantaine de vignettes : la grille se
   remplit d'elle-même selon la largeur disponible plutôt que de compter des
   colonnes, faute de quoi la dernière rangée serait à refaire à chaque palier.
   La fiche d'une personne est un enfant de la même grille, qui prend toute la
   largeur : c'est ce qui lui permet de s'ouvrir SOUS la rangée cliquée, et non
   par-dessus la page. */

.pupitre + .pupitre { margin-top: clamp(2.6rem, 5vw, 4rem); }
.pupitre__nom { margin-bottom: clamp(1.2rem, 2.4vw, 1.8rem); }

.choristes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: clamp(0.9rem, 1.8vw, 1.5rem);
  align-items: start;
}

.choriste {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  text-align: center;
}
button.choriste { cursor: pointer; }

.choriste__image {
  display: block;
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--r-image);
  background: var(--papier-3);
  box-shadow: var(--ombre-douce);
}
.choriste__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
button.choriste:hover .choriste__image img,
button.choriste:focus-visible .choriste__image img { transform: scale(1.055); }

/* Le trait de l'accent dit laquelle est ouverte : à cinquante vignettes, un
   simple agrandissement ne se retrouve plus du regard. */
.choriste__image::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid transparent;
  transition: border-color 0.3s;
}
button.choriste[aria-expanded="true"] .choriste__image::after { border-color: var(--accent); }

.choriste__nom {
  font-family: var(--data);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  color: var(--encre-80);
  line-height: 1.3;
}
button.choriste[aria-expanded="true"] .choriste__nom { color: var(--accent); }

/* La fiche. Sans script, elle suit sa propre vignette et se lit comme une
   suite de portraits légendés — la page reste complète, seulement plus
   longue. */
.choriste__fiche {
  grid-column: 1 / -1;
  position: relative;
  display: grid;
  grid-template-columns: 12rem minmax(0, 1fr);
  gap: clamp(1.2rem, 3vw, 2.2rem);
  align-items: start;
  margin: 0.5rem 0 1rem;
  padding: clamp(1.3rem, 3vw, 1.9rem);
  background: var(--papier-2);
  border: 1px solid var(--trait-fin);
  border-radius: var(--r-carte);
}
/* `display: grid` l'emporte sur le `display: none` que le navigateur attache
   à [hidden] — il vient d'une feuille de style de moindre poids. Sans cette
   ligne, le script replie les fiches et aucune ne se referme. */
.choriste__fiche[hidden] { display: none; }

.choriste__grande { margin: 0; }
.choriste__grande img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--r-image);
  display: block;
}
.choriste__mot h4 { margin: 0.25rem 0 0.7rem; }
.choriste__mot .prose { color: var(--encre-80); }

.choriste__fermer {
  position: absolute;
  top: 0.55rem;
  right: 0.75rem;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: none;
  background: none;
  color: var(--pierre);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
}
.choriste__fermer:hover { color: var(--accent); background: var(--papier-3); }

/* --------------------------------------------------------- 12. Page d'attente */

/* Ce que voit un visiteur quand le site est fermé depuis le panneau. Elle ne
   passe ni par l'en-tête ni par le pied : un menu n'y offrirait que des liens
   qui ramènent à elle-même. Reste le logo, le mot, et de quoi écrire. */

.attente-page {
  min-height: 100svh;
  display: grid;
  place-items: center;
  text-align: center;
  background: var(--papier);
  position: relative;
  overflow: hidden;
}
/* Le même voile coloré que l'ouverture, pour que la page fermée reste une
   page du site et non un écran d'erreur. */
.attente-page::before {
  content: "";
  position: absolute;
  inset: -15%;
  pointer-events: none;
  background:
    radial-gradient(46% 52% at 14% 10%, var(--accent-voile), transparent 68%),
    radial-gradient(40% 46% at 86% 74%, var(--accent-voile), transparent 70%);
}
.attente-page__centre {
  position: relative;
  padding-block: clamp(3rem, 10vh, 6rem);
  width: 100%;
}
.attente-page__logo {
  width: min(100%, 22rem);
  height: auto;
  margin: 0 auto clamp(1.6rem, 4vh, 2.6rem);
}
.attente-page__mot {
  margin-top: 1.3rem;
  color: var(--encre-80);
}
.attente-page__contact {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.6rem;
  margin-top: clamp(1.8rem, 4vh, 2.8rem);
  font-family: var(--data);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
}

/* --------------------------------------------------------- 13. Apparitions */

.apparait {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.85s cubic-bezier(0.22, 1, 0.36, 1), transform 0.85s cubic-bezier(0.22, 1, 0.36, 1);
}
.apparait[data-vu="oui"] { opacity: 1; transform: none; }
.apparait[data-retard="1"] { transition-delay: 0.09s; }
.apparait[data-retard="2"] { transition-delay: 0.18s; }
.apparait[data-retard="3"] { transition-delay: 0.27s; }
.apparait[data-retard="4"] { transition-delay: 0.36s; }

/* Séquence d'ouverture */
.leve { opacity: 0; transform: translateY(26px); animation: leve 1s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
.leve--1 { animation-delay: 0.05s; }
.leve--2 { animation-delay: 0.17s; }
.leve--3 { animation-delay: 0.29s; }
.leve--4 { animation-delay: 0.41s; }
.leve--5 { animation-delay: 0.53s; }
.leve--6 { animation-delay: 0.34s; }
@keyframes leve { to { opacity: 1; transform: none; } }

/* --------------------------------------------------------- 14. Adaptations */

/* L'ouverture tenait sur une hauteur fixe d'environ 1050 px : rien n'y
   réagissait à la hauteur de la fenêtre, si bien qu'il fallait un écran de
   1080 px de haut pour voir les boutons — ce qu'aucun portable n'offre.

   On réserve donc la place du texte et des boutons, et on donne au logo ce
   qui reste. Le `min()` garde le plafond de 29.5rem : dès qu'il y a la
   place, la formule ne s'applique pas et la maquette est celle d'origine.
   La règle ne se déclenche que là où elle est nécessaire.

   Le téléphone est volontairement exclu : le pli y coupe le paragraphe
   d'intro en deux, ce qui annonce la suite mieux que n'importe quel indice,
   et le défilement y est le geste naturel. */

@media (min-width: 941px) {
  .ouverture {
    /* œil + phrase + intro + boutons + paddings */
    --reserve: 30rem;
    padding-block: clamp(1.1rem, 3vh, 3.4rem) clamp(2rem, 5vh, 5.5rem);
  }
  .ouverture .oeil { margin-bottom: clamp(0.7rem, 1.8vh, 1.4rem); }
  .ouverture__logo {
    width: min(100%, 29.5rem, calc((100svh - 5.5rem - var(--reserve)) * 1200 / 1176));
    margin-bottom: clamp(0.7rem, 1.7vh, 1.7rem);
  }
  .ouverture__phrase { margin-bottom: clamp(0.75rem, 1.7vh, 1.3rem); }
  .ouverture__texte { margin-bottom: clamp(1rem, 2.4vh, 1.9rem); }
  /* La photo ne dicte plus la hauteur de la rangée : couchée, elle est plus
     courte que la colonne de texte, quelle que soit la hauteur de l'écran. La
     hauteur imposée qui tenait ici servait le cadre debout, qui dépassait. */

  /* Le bord haut de la photo se pose sur le haut du logo. Ce qui les sépare,
     c'est la ligne « Ensemble vocal · Bars, Dordogne » : sa hauteur de ligne,
     plus la marge qu'elle porte. Les deux valeurs sont celles de la règle
     juste au-dessus — le jour où l'une change, celle-ci suit. */
  .ouverture__cote { margin-top: calc(0.735rem * 1.68 + clamp(0.7rem, 1.8vh, 1.4rem)); }
}

/* Tablette en portrait : la trame est déjà en colonne unique, la réserve est
   donc plus haute. `min-height` écarte le téléphone en paysage, où la formule
   écraserait le logo sans rien gagner. */
@media (max-width: 940px) and (min-width: 600px) and (min-height: 600px) {
  .ouverture { --reserve: 33rem; }
  .ouverture__logo {
    width: min(100%, 29.5rem, calc((100svh - 5.5rem - var(--reserve)) * 1200 / 1176));
  }
}

@media (max-width: 1080px) {
  .nav__lien { font-size: 0.87rem; }
  .nav { gap: 0.75rem; }
}

@media (max-width: 940px) {
  .nav {
    position: fixed;
    inset: 5.5rem 0 auto;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--papier);
    border-bottom: 1px solid var(--trait-fin);
    padding: 0.5rem var(--gouttiere) 1.6rem;
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), visibility 0.3s;
    max-height: calc(100dvh - 5.5rem);
    overflow-y: auto;
  }
  .nav[data-ouvert="oui"] { opacity: 1; visibility: visible; transform: none; }
  .nav__lien { font-size: 1.12rem; padding: 0.95rem 0; border-bottom: 1px solid var(--trait-fin); }
  .nav__lien::after { display: none; }
  .nav__lien[aria-current="page"] { color: var(--accent); }
  .nav__bouton { margin: 1.1rem 0 0; justify-content: center; font-size: 0.95rem; padding: 0.85rem 1.3rem; }
  .burger { display: inline-flex; }

  .ouverture__trame,
  .duo,
  .duo--penche,
  .duo--portrait,
  .une,
  .entete-bloc,
  .banniere__trame { grid-template-columns: minmax(0, 1fr); }
  .entete-bloc { gap: 1.2rem; }
  /* Une seule colonne : les places écrites plus haut n'ont plus de sens, et
     l'ordre du document — titre, introduction, escales — redevient l'ordre de
     lecture. Les trois sélecteurs sont repris tels quels : un `> *` pèse moins
     que `> :nth-child(2)`, et le chapeau gardait sa colonne 2, qui rouvrait
     une deuxième piste dans une grille qui n'en déclare plus qu'une. */
  .entete-bloc--empile > .entete-bloc__texte,
  .entete-bloc--empile > :nth-child(2),
  .entete-bloc--empile > .entete-bloc__bas { grid-column: auto; grid-row: auto; }
  .ouverture__trame { gap: 2.5rem; }
  /* Toujours couché : la vignette est fabriquée en paysage, et la remettre
     debout ici recommencerait le découpage qu'on vient de supprimer. Plus de
     largeur maximale non plus — sur une colonne unique, la photo occupe la
     colonne, et un plafond de 30rem la laissait petite au milieu du vide. */
  .panneau { aspect-ratio: 3 / 2; }
  .ouverture__cote { margin-top: 0; }
  .grille--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* La ligne se replie : le portrait à gauche, sur deux rangs, et le nom
     au-dessus du texte plutôt qu'à côté — à cette largeur, une colonne de nom
     de douze rem ne laisse plus assez de place au paragraphe.

     C'est la COLONNE DU NOM qui était de trop, pas la photo. Celle-ci tombait
     pourtant à cinq rem et demie dans la même foulée, si bien qu'une tablette
     affichait des portraits de quatre-vingt-huit pixels — plus petits que ceux
     d'un téléphone, qui en fait cent quarante-huit. La photo garde donc ses
     douze rem tant que le paragraphe à côté d'elle reste lisible, et ne cède
     qu'au plus étroit de la bande : à 701 pixels, douze rem laissent quarante-
     deux signes par ligne, dix rem et demie en laissent quarante-cinq. Au-delà
     de 800 le plafond s'applique et la photo ne bouge plus.

     La marche vers le téléphone en devient presque invisible : 168 pixels à
     701, 152 à 700. */
  .portrait-ligne { grid-template-columns: minmax(0, clamp(10.5rem, 24vw, 12rem)) minmax(0, 1fr); }
  .portrait-ligne__image { grid-row: 1 / span 2; }
  .portraits-lignes--sans-photo .portrait-ligne { grid-template-columns: minmax(0, 1fr); }
  .mur { columns: 2; }
  .galerie { columns: 2; }
  /* La fiche d'un choriste : la photo au-dessus du texte, et plus petite —
     à 12rem de large sur une colonne étroite, elle mangeait la moitié du
     cadre pour une photo déjà visible juste au-dessus. */
  .choriste__fiche { grid-template-columns: minmax(0, 1fr); }
  .choriste__grande { max-width: 9rem; }
  .pied__haut { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
  :root { --rythme: clamp(3.25rem, 11vw, 4.5rem); }
  .grille--3, .grille--2 { grid-template-columns: minmax(0, 1fr); }
  /* Sur un téléphone, le portrait ne garde à côté de lui que le nom : le
     paragraphe passe dessous, sur toute la largeur. À côté d'une photo de
     cinq rem, il se lisait sur vingt-deux signes de large, soit trois mots
     par ligne.

     C'est ce repli qui permet au portrait d'être large. La photo ne dispute
     plus sa place au paragraphe, seulement au nom et au rôle — et le rôle le
     plus long de la page, « Chef de choeur remplaçante », tient sur deux
     lignes sans gêner, le texte se calant en haut d'une photo plus haute que
     lui. À cinq rem le visage faisait quatre-vingts pixels : une vignette,
     pas un portrait.

     Fluide plutôt que fixe : la fourchette va de 320 à 700 pixels, et une
     valeur fixe serait soit étriquée en bas, soit étouffante en haut. Le
     plafond de 9,5 rem est ce qui laisse encore respirer le nom à 700. */
  .portrait-ligne {
    grid-template-columns: minmax(0, clamp(7rem, 38vw, 9.5rem)) minmax(0, 1fr);
    row-gap: 0.9rem;
  }
  .portrait-ligne__image { grid-row: auto; }
  .portrait-ligne__mot { grid-column: 1 / -1; }
  .escales { max-width: none; }
  .ligne, .agenda--serre .ligne { grid-template-columns: minmax(0, 1fr); gap: 0.85rem; }
  .ligne__folio { padding-top: 0; display: flex; align-items: baseline; gap: 0.6rem; }
  .ligne__folio b { font-size: 1.65rem; margin-bottom: 0; }
  .ligne__vignette, .agenda--serre .ligne__vignette { width: 100%; order: -1; }
  .ligne__fleche { display: none; }
  .jour { grid-template-columns: minmax(0, 1fr); gap: 0.5rem; }
  .reperes { grid-template-columns: minmax(0, 1fr); gap: 1.4rem; }
  .nuancier { flex-wrap: wrap; }
  .nuancier__legende { white-space: normal; margin-left: 0; flex-basis: 100%; margin-top: 0.15rem; }
  .m-4, .m-5, .m-6, .m-7, .m-8 { grid-column: span 6; aspect-ratio: 1 / 1; }
  .m-12 { grid-column: span 12; aspect-ratio: 16 / 9; }
  .galerie { columns: 1; }
  .mur { columns: 1; }
  .pied__haut { grid-template-columns: minmax(0, 1fr); }
  .ouverture__logo { width: min(100%, 20rem); }
  html { scroll-padding-top: 5.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .leve, .apparait { opacity: 1; transform: none; }
}

/**
 * Dans la colonne d'aperçu du panneau, la page s'affiche posée.
 *
 * Cette colonne recharge la page à chaque pause de frappe. Les deux mises en
 * scène d'entrée — .leve au chargement, .apparait au défilement — y
 * rejoueraient sans cesse : au lieu de voir le mot qu'on vient de taper, on
 * verrait la page se remonter. Le repère `data-apercu` est posé par
 * site/snippets/tete.php quand l'adresse porte le paramètre du greffon
 * d'aperçu.
 *
 * Volontairement plus étroit que le bloc « mouvement réduit » ci-dessus :
 * seules les animations d'ENTRÉE sont éteintes, pas les transitions. Couper
 * ces dernières ferait claquer le fondu entre les quatre couleurs du logo au
 * lieu de le fondre — on remplacerait une gêne par une autre.
 */
html[data-apercu] .leve,
html[data-apercu] .apparait {
  opacity: 1;
  transform: none;
  animation: none;
}

@media print {
  .entete, .pied, .nuancier, .visionneuse, body::after { display: none !important; }
  body { background: #fff; }
}
