/* =============================================================================
   POLICES AUTO-HÉBERGÉES
   -----------------------------------------------------------------------------
   Servies depuis le thème plutôt que depuis un service tiers : aucune
   connexion externe n'est nécessaire avant l'affichage du premier caractère.

   font-display: swap — le texte s'affiche immédiatement dans une police
   système, puis bascule dès que la police définitive est prête. Le contenu
   reste lisible en toutes circonstances.
   ========================================================================== */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/archivo-v25-latin-regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/archivo-v25-latin-500.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/dm-sans-v17-latin-regular.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/dm-sans-v17-latin-500.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/dm-sans-v17-latin-700.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: italic;
  font-weight: 100;
  font-display: swap;
  src: url('../fonts/dm-sans-v17-latin-100italic.woff2') format('woff2');
}


/* =============================================================================
   SOUNDFOLIO — Feuille de style
   -----------------------------------------------------------------------------
   Sommaire
     1. Jetons de conception (couleurs, espacements, durées…)
     2. Base et réinitialisation
     3. Utilitaires
     4. Fond génératif
     5. Gabarit (shell : en-tête fixe / contenu défilant / pied fixe)
     6. En-tête
     7. Boutons
     8. Pied de page
     9. Contenu texte des pages
   -----------------------------------------------------------------------------
   Convention : toutes les distances proviennent de l'échelle d'espacement
   (--sp-*). Aucune valeur en pixels ne doit être écrite en dur.
   ========================================================================== */


/* =============================================================================
   1. JETONS DE CONCEPTION
   ========================================================================== */

:root {
  /* Palette */
  --bordeaux-deep:  #2A0710;   /* fond général */
  --bordeaux:       #3D0E1B;   /* surfaces */
  --bordeaux-light: #551A2C;   /* surfaces en relief */
  --cream:          #F3ECDD;   /* texte principal */
  --amber:          #E8A33C;   /* accent, état actif */
  --glitch-cyan:    #4DD8E8;   /* aberration chromatique du glitch */
  --text-secondary: #CBB29C;   /* texte secondaire */

  /* Échelle d'espacement — multiples de 8, avec 4 et 12 en demi-pas */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 40px;

  /* Formes */
  --radius:       8px;    /* boutons, images, panneaux */
  --radius-lg:    10px;   /* pistes */
  --border-width: 1.5px;

  /* Mouvement */
  --dur-fast: .2s;
  --dur:      .3s;
  --ease:     ease;

  /* Typographie */
  --font-title: 'Archivo', sans-serif;
  --font-body:  'DM Sans', sans-serif;

  /* Gabarit */
  --shell-max:     680px;
  --shell-pad:     var(--sp-5);
  --scrollbar-w:   6px;
  --breakpoint-sm: 600px;   /* pour mémoire : les media queries ne lisent pas les variables */
}


/* =============================================================================
   2. BASE ET RÉINITIALISATION
   ========================================================================== */

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

html {
  height: 100%;
  margin: 0;
  background: var(--bordeaux-deep);
}

body {
  height: 100%;
  margin: 0;
  font-family: var(--font-body);
  color: var(--cream);
  overflow-x: hidden;   /* garde-fou : aucun débordement latéral possible */
  /* Pas d'arrière-plan ici : il masquerait le fond génératif placé en z-index -1 */
}

h1, h2, .page-title {
  font-family: var(--font-title);
  font-weight: 500;   /* graisse réellement disponible : pas de gras synthétique */
  letter-spacing: -0.02em;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}


/* =============================================================================
   3. UTILITAIRES
   ========================================================================== */

/* Masqué à l'écran, mais lu par les lecteurs d'écran et les moteurs.
   display:none le retirerait aussi de l'arbre d'accessibilité. */
.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- Affichage conditionnel ---------------------------------------------
   À appliquer à un bloc depuis l'éditeur : panneau latéral → Avancé →
   « Classe(s) CSS additionnelle(s) ».

   Seuils retenus :
     mobile   : jusqu'à 600 px
     tablette : de 601 à 1024 px
     desktop  : à partir de 1025 px

   Les trois classes se cumulent : « hidden-on-mobile hidden-on-tablette »
   réserve un bloc au seul affichage sur ordinateur.
   --------------------------------------------------------------------- */

@media (max-width: 600px) {
  .hidden-on-mobile { display: none !important; }
}
@media (min-width: 601px) and (max-width: 1024px) {
  .hidden-on-tablette { display: none !important; }
}
@media (min-width: 1025px) {
  .hidden-on-desktop { display: none !important; }
}

/* --- Affichage selon les capacités de l'appareil -----------------------
   À distinguer des classes ci-dessus : celles-ci ne regardent pas la
   largeur mais ce que l'appareil sait faire. C'est le bon critère pour
   tout contenu qui parle de la souris ou des effets qu'elle déclenche —
   une fenêtre réduite sur ordinateur garde sa souris, une tablette large
   n'en a pas.

   Conditions identiques à celles qui gouvernent le fond génératif et la
   sculpture sonore : les trois restent ainsi cohérents.
   --------------------------------------------------------------------- */

/* Réservé aux appareils dotés d'un pointeur précis et sans restriction
   d'animation — donc là où les effets de souris sont réellement actifs. */
@media (hover: none), (prefers-reduced-motion: reduce) {
  .mouse-only { display: none !important; }
}

/* L'inverse : réservé aux appareils tactiles. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .touch-only { display: none !important; }
}

/* Lien d'évitement : invisible jusqu'à ce que le clavier l'atteigne.
   Il doit alors sortir de son masquage pour être lisible. */
.skip-link:focus {
  position: fixed;
  top: var(--sp-2);
  left: var(--sp-2);
  z-index: 100;
  width: auto;
  height: auto;
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  clip-path: none;
  background: var(--bordeaux-light);
  border: var(--border-width) solid var(--amber);
  border-radius: var(--radius);
  color: var(--cream);
  font-size: 13px;
  text-decoration: none;
}
/* La cible du lien ne doit pas afficher de contour à la prise de focus */
main:focus { outline: none; }

/* Barre de défilement, appliquée à toute zone défilante du gabarit */
.u-scroll {
  scrollbar-width: thin;
  scrollbar-color: var(--cream) transparent;
}
.u-scroll::-webkit-scrollbar { width: var(--scrollbar-w); }
.u-scroll::-webkit-scrollbar-thumb { background: var(--cream); border-radius: 3px; }
.u-scroll::-webkit-scrollbar-track { background: transparent; }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}


/* =============================================================================
   FOND GÉNÉRATIF
   -----------------------------------------------------------------------------
   Deux halos suivent le curseur avec inertie. Pendant la lecture, ils
   respirent au tempo de l'ambiance, en alternance l'un avec l'autre.

   Chaque halo est un calque distinct : sa position est portée par une
   translation, sa respiration par une mise à l'échelle. Ces deux
   transformations sont traitées par le compositeur graphique, sans redessiner
   le dégradé à chaque image — là où animer directement le rayon du dégradé
   imposerait un repeint plein écran soixante fois par seconde.
   ========================================================================== */

.bg-field {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

/* Le calque porte la position ; il est deux fois plus large que le halo pour
   que celui-ci reste centré sur le point voulu. */
.halo {
  position: absolute;
  top: 0;
  left: 0;
  width: 84vmax;
  height: 84vmax;
  margin: -42vmax;
  will-change: transform;
}
.halo-a { transform: translate(calc(var(--mx, 50) * 1vw), calc(var(--my, 50) * 1vh)); }
.halo-b { transform: translate(calc((100 - var(--mx, 50)) * 1vw), calc((100 - var(--my, 50)) * 1vh)); }

/* L'enfant porte le dégradé et la respiration. */
.halo > span {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  will-change: transform;
}
.halo-a > span { background: radial-gradient(closest-side, rgba(232, 163, 60, .133), transparent 62%); }
.halo-b > span { background: radial-gradient(closest-side, rgba(85, 26, 44, .72), transparent 41%); }

/* Respiration continue.

   --halo-beat, posé par le script, vaut la durée de deux temps : chaque halo
   ne se contracte donc qu'une fois tous les deux temps, et les deux alternent.

   La courbe suit un cosinus échantillonné plutôt que deux positions reliées
   par une fonction de transition. La vitesse varie ainsi progressivement d'un
   bout à l'autre du cycle, sans la reprise sèche que produit un aller-retour
   entre deux valeurs. */
.bg-field.is-pulsing .halo-a > span {
  animation: halo-respire-a var(--halo-beat, 1.4s) linear infinite;
}
.bg-field.is-pulsing .halo-b > span {
  animation: halo-respire-b var(--halo-beat, 1.4s) linear infinite;
}

@keyframes halo-respire-a {
    0% { transform: scale(0.8500); }
    8% { transform: scale(0.8600); }
   17% { transform: scale(0.8875); }
   25% { transform: scale(0.9250); }
   33% { transform: scale(0.9625); }
   42% { transform: scale(0.9900); }
   50% { transform: scale(1.0000); }
   58% { transform: scale(0.9900); }
   67% { transform: scale(0.9625); }
   75% { transform: scale(0.9250); }
   83% { transform: scale(0.8875); }
   92% { transform: scale(0.8600); }
  100% { transform: scale(0.8500); }
}

@keyframes halo-respire-b {
    0% { transform: scale(1.0000); }
    8% { transform: scale(0.9900); }
   17% { transform: scale(0.9625); }
   25% { transform: scale(0.9250); }
   33% { transform: scale(0.8875); }
   42% { transform: scale(0.8600); }
   50% { transform: scale(0.8500); }
   58% { transform: scale(0.8600); }
   67% { transform: scale(0.8875); }
   75% { transform: scale(0.9250); }
   83% { transform: scale(0.9625); }
   92% { transform: scale(0.9900); }
  100% { transform: scale(1.0000); }
}

/* Sans souris, le fond resterait figé ; avec animations réduites, il n'a pas
   lieu de respirer. Mêmes conditions que la sculpture sonore. */
@media (hover: none), (prefers-reduced-motion: reduce) {
  .bg-field { display: none; }
}


/* =============================================================================
   5. GABARIT
   Toutes les pages partagent le même squelette : en-tête et pied de page
   fixes, contenu défilant entre les deux. Une seule définition de largeur.
   ========================================================================== */

.shell {
  width: 100%;
  max-width: var(--shell-max);
  margin: 0 auto;
  padding-left: var(--shell-pad);
  padding-right: var(--shell-pad);
}

/* Seul .shell porte les marges latérales : aucun enfant ne peut en rajouter. */
.shell > header,
.shell > main,
.shell > footer {
  width: 100%;
  max-width: 100%;
  margin-inline: 0;
  padding-inline: 0;
}

@media (min-width: 601px) {
  html, body { overflow: hidden; }   /* le défilement n'existe que dans <main> */

  .shell {
    display: grid;
    grid-template-rows: auto 1fr auto;
    height: 100dvh;
  }
  .shell > main {
    min-height: 0;        /* indispensable pour qu'une zone de grille défile */
    overflow-y: scroll;   /* 'scroll' et non 'auto' : largeur utile constante */
  }
}

/* Indice de débordement : le bas de la zone défilante s'estompe tant qu'il
   reste du contenu plus bas, et redevient net une fois la fin atteinte.
   La classe est posée par le script sur la zone elle-même — et non sur le
   conteneur, dont le bas se situe sous le pied de page.
   Le fondu s'applique au contenu par un masque, il suit donc exactement le
   bord de la zone visible. */
.shell > main.has-overflow {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 56px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 56px), transparent);
}

/* Mobile : la hauteur figée ne laisserait qu'une piste visible.
   La page défile donc naturellement de bout en bout. */
@media (max-width: 600px) {
  html, body { overflow: visible; height: auto; }

  .shell {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
    --shell-pad: var(--sp-4);
  }
  .shell > main { overflow: visible; }
  .shell > main.has-overflow { -webkit-mask-image: none; mask-image: none; }
}


/* =============================================================================
   6. EN-TÊTE
   ========================================================================== */

.site-header {
  position: relative;   /* passe au-dessus du contenu (infobulle) */
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  /* Le bouton se centre sur la hauteur du bloc titre + accroche */
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-5) 0 var(--sp-4);
  border-bottom: 1px solid var(--amber);
}

.site-title {
  margin: 0;
  font-family: var(--font-title);
  font-size: clamp(22px, 6vw, 28px);
  /* 500 : seule graisse haute auto-hébergée. Demander 700 obligerait le
     navigateur à épaissir le dessin mécaniquement, avec un rendu grossier. */
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 0;   /* supprime l'espace fantôme sous le logo */
}

.site-name {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.site-name:hover { color: var(--amber); }

.site-logo {
  display: block;
  height: clamp(41px, 11.5vw, 60px);
  /* Rapport déclaré : certains moteurs mobiles ne le déduisent pas du
     viewBox et résolvent la largeur à zéro. */
  aspect-ratio: 1278 / 527;
  width: auto;
  max-width: 100%;
  flex-shrink: 0;
  color: inherit;
}

.tagline {
  margin: 0;
  font-family: var(--font-title);
  font-size: 14px;
  line-height: 1.5;
  max-width: 42ch;
  color: var(--text-secondary);
}

/* --- Bouton d'information et son infobulle --- */

.info-wrap { position: relative; flex-shrink: 0; }

.info-btn { width: 40px; height: 40px; color: var(--text-secondary); }
.info-btn svg { position: relative; z-index: 1; width: 22px; height: 22px; }
.info-btn:hover,
.info-btn:focus-visible { border-color: var(--amber); color: var(--amber); }

.info-tooltip {
  position: absolute;
  top: calc(100% + var(--sp-3));
  right: 0;
  z-index: 40;
  width: min(320px, 78vw);
  padding: var(--sp-4);
  background: var(--bordeaux-light);
  border: 1px solid var(--amber);
  border-radius: var(--radius-lg);
  box-shadow: 0 8px 24px rgba(42, 7, 16, .5);
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition:
    opacity var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease),
    visibility var(--dur-fast);
}
.info-tooltip :is(p, ul, ol) { margin: 0 0 var(--sp-3); }
.info-tooltip > *:last-child { margin-bottom: 0; }
.info-tooltip ul { padding-left: var(--sp-4); }
.info-tooltip :is(h2, h3, h4) {
  margin: 0 0 var(--sp-2);
  font-family: var(--font-title);
  font-size: 13px;
  color: var(--cream);
}
.info-tooltip strong { color: var(--cream); }
.info-tooltip a { color: var(--amber); text-decoration: none; }

/* Souris : survol et focus clavier. Tactile : classe posée par le script,
   car le survol n'existe pas et le focus reste collé après un appui. */
.info-wrap:hover .info-tooltip,
.info-wrap:focus-within .info-tooltip,
.info-wrap.is-open .info-tooltip {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

@media (hover: none) {
  /* Seul le pilotage par classe s'applique */
  .info-wrap:hover .info-tooltip,
  .info-wrap:focus-within .info-tooltip {
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4px);
  }
  .info-wrap.is-open .info-tooltip {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
  }
}


/* =============================================================================
   7. BOUTONS
   ========================================================================== */

/* Bouton rond, partagé par le bouton d'information et les boutons de lecture.
   Le pseudo-élément assure le remplissage progressif à l'activation. */
.icon-btn {
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
  padding: 0;
  border: var(--border-width) solid var(--text-secondary);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition:
    border-color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast) var(--ease);
}
.icon-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--amber);
  clip-path: circle(0% at 50% 50%);
  transition: clip-path var(--dur) var(--ease);
}

/* Bouton rectangulaire : contour au repos, ambre au survol. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-height: 44px;   /* cible tactile recommandée */
  padding: var(--sp-3) var(--sp-5);
  border: var(--border-width) solid var(--cream);
  border-radius: var(--radius);
  background: transparent;
  color: var(--cream);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    border-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}
.btn:hover,
.btn:focus-visible {
  border-color: var(--amber);
  color: var(--amber);
}

/* Libellés longs sur petit écran : on resserre plutôt que de déborder. */
@media (max-width: 600px) {
  .btn {
    padding: var(--sp-3) var(--sp-2);
    font-size: 11px;
    letter-spacing: .02em;
    line-height: 1.3;
  }
}
@media (max-width: 360px) {
  .btn { padding: var(--sp-3) var(--sp-1); font-size: 10px; }
}


/* =============================================================================
   8. PIED DE PAGE
   ========================================================================== */

.site-footer {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-4) 0 var(--sp-5);
  border-top: 1px solid var(--amber);
}

.footer-nav { display: flex; gap: var(--sp-3); width: 100%; }
.footer-nav .btn { flex: 1 1 0; min-width: 0; }

.footer-legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-1) var(--sp-4);
  width: 100%;
  font-size: 11px;
  color: var(--text-secondary);
}
.footer-legal a {
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.footer-legal a:hover { color: var(--cream); }


/* =============================================================================
   9. CONTENU TEXTE DES PAGES
   ========================================================================== */

.static-content { padding: var(--sp-5) 0 var(--sp-6); }

.page-title {
  margin: 0 0 var(--sp-5);
  font-size: clamp(20px, 5vw, 24px);
}

.static-body {
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-secondary);
  overflow-wrap: anywhere;   /* une URL longue n'élargit pas la page */
}

/* Rythme vertical : --sp-6 avant un titre, --sp-3 après, --sp-4 entre paragraphes */
.static-body h2 {
  margin: var(--sp-6) 0 var(--sp-3);
  font-family: var(--font-title);
  font-size: 16px;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--cream);
}
.static-body > h2:first-child { margin-top: 0; }

.static-body p { margin: 0 0 var(--sp-4); }
.static-body p:last-child { margin-bottom: 0; }
.static-body strong { color: var(--cream); font-weight: 700; }

.static-body a {
  color: var(--amber);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.static-body a:hover,
.static-body a:focus-visible { color: var(--cream); }

.static-body ul { margin: 0 0 var(--sp-4); padding-left: var(--sp-5); }
.static-body li { margin-bottom: var(--sp-2); }

.static-body blockquote {
  margin: var(--sp-5) 0;
  padding-left: var(--sp-4);
  border-left: 2px solid var(--amber);
  color: var(--cream);
}

/* Médias insérés depuis l'éditeur : rien ne doit dépasser la colonne. */
.static-body :is(img, video, iframe, figure) {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius);
}
.static-body figure { margin: var(--sp-5) 0; }
.static-body figcaption {
  margin-top: var(--sp-2);
  font-size: 12px;
  color: var(--text-secondary);
}

/* Image mise en avant : habillage, le texte s'écoule autour. */
/* Cadrage carré partout : le format ne change plus selon la largeur, seule
   la place occupée varie. Le point de mise au point reste identique, si bien
   que le visage est cadré de la même façon sur tous les écrans. */
.about-photo {
  float: right;
  width: 200px;
  margin: var(--sp-3) 0 var(--sp-3) var(--sp-3);
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: center 18%;
  border-radius: var(--radius);
}
/* Le conteneur doit englober la photo flottante. */
.static-body::after { content: ""; display: block; clear: both; }

/* Seuil calculé : en dessous, la colonne restant à côté de la photo
   passe sous 260 px et devient inconfortable à lire. */
@media (max-width: 530px) {
  .about-photo {
    float: none;
    width: 100%;
    margin: 0;
  }
  /* Empilée, la photo joue le rôle d'un titre : --sp-3 la sépare de la suite. */
  .about-photo + * { margin-top: var(--sp-3); }
}
