/* ---- Polices auto-hébergées (aucune requête tierce) ---- */
@font-face{
  font-family:'Noto Serif'; font-style:normal; font-weight:400; font-display:swap;
  src:url('assets/fonts/noto-serif-latin-400.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Noto Serif'; font-style:normal; font-weight:400; font-display:swap;
  src:url('assets/fonts/noto-serif-latin-ext-400.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Noto Serif'; font-style:normal; font-weight:600; font-display:swap;
  src:url('assets/fonts/noto-serif-latin-600.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Noto Serif'; font-style:normal; font-weight:600; font-display:swap;
  src:url('assets/fonts/noto-serif-latin-ext-600.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Noto Sans'; font-style:normal; font-weight:400; font-display:swap;
  src:url('assets/fonts/noto-sans-latin-400.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Noto Sans'; font-style:normal; font-weight:400; font-display:swap;
  src:url('assets/fonts/noto-sans-latin-ext-400.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Noto Sans'; font-style:normal; font-weight:600; font-display:swap;
  src:url('assets/fonts/noto-sans-latin-600.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Noto Sans'; font-style:normal; font-weight:600; font-display:swap;
  src:url('assets/fonts/noto-sans-latin-ext-600.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Noto Sans'; font-style:normal; font-weight:700; font-display:swap;
  src:url('assets/fonts/noto-sans-latin-700.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Noto Sans'; font-style:normal; font-weight:700; font-display:swap;
  src:url('assets/fonts/noto-sans-latin-ext-700.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* Les jetons (:root) vivent maintenant uniquement dans styles/tokens.css, chargé
   avant ce fichier — sur la page unique (index.html) comme sur le site multi-pages.
   Les valeurs partagées sont identiques (aucun changement visuel), et tokens.css
   ajoute la palette V2 étendue (ink-950/900/800/700, sage-700/900, thème clair). */

/* ---- Reset léger ---- */
*,*::before,*::after{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  margin:0;
  background:var(--surface-page);
  color:var(--text-body);
  font-family:var(--font-body);
  font-size:var(--font-size-body);
  line-height:var(--leading-body);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img,svg{max-width:100%;}
[hidden]{display:none !important;}

/* ---- Focus : visible partout, jamais supprimé ---- */
/* Repli #BDCFA9 (sauge de marque) avant le var() oklch() : si oklch() n'est
   pas supporté, outline-color est simplement ignoré et le repli reste actif
   au lieu d'invalider tout le raccourci outline. */
:focus-visible{
  outline:2px solid #BDCFA9;
  outline-color:var(--focus-ring);
  outline-offset:2px;
  border-radius:3px;
}

/* ---- Liens de texte : soulignés (pas d'info portée par la couleur seule) ---- */
a{color:var(--link);text-underline-offset:3px;}
a:hover{color:var(--link-hover);text-decoration-thickness:2px;}

/* ---- Utilitaires ---- */
.visually-hidden{
  position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0;padding:0;margin:-1px;
}
.skip-link{
  position:absolute;left:var(--space-3);top:-60px;z-index:100;
  background:var(--accent);color:var(--accent-on);
  padding:var(--space-3) var(--space-6);font-weight:700;
  border-radius:0 0 var(--radius-md) var(--radius-md);
  text-decoration:none;transition:top .15s;
}
.skip-link:focus{top:0;}

/* ---- Mouvement réduit ---- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{
    transition-duration:0.01ms !important;
    animation-duration:0.01ms !important;
    animation-iteration-count:1 !important;
  }
}

/* ============================================================================
   Styles de la page
   ============================================================================ */

/* Conteneur : largeur lisible, marges fluides, rythme vertical généreux */
.site-header,
main#main,
.site-footer{
  max-width:64rem;
  margin-inline:auto;
  padding-inline:clamp(var(--space-6), 5vw, var(--space-16));
}

/* En-tête : logo centré, important */
.site-header{
  padding-block:clamp(var(--space-10), 8vw, var(--space-16)) clamp(var(--space-10), 6vw, var(--space-16));
  text-align:center;
}
.wordmark{
  margin:0;
  color:var(--accent);
  line-height:0;
}
.wordmark svg{
  height:clamp(64px, 12vw, 112px);
  width:auto;
}

/* Accroche */
.lead{
  max-width:42rem;
  margin-block:0 clamp(var(--space-10), 9vw, var(--space-16));
}
.lead-headline{
  font-family:var(--font-display);
  font-weight:600;
  font-size:clamp(1.6rem, 4.6vw, 2.25rem);
  line-height:var(--leading-tight);
  letter-spacing:var(--tracking-display);
  margin:0 0 var(--space-6);
}
.lead-headline em{
  font-style:italic;
}
.lead-body{
  font-size:var(--font-size-lead);
  color:var(--text-secondary);
  margin:0;
}

/* Deux colonnes */
.cols{
  display:grid;
  gap:clamp(var(--space-10), 6vw, var(--space-16));
  align-items:start;
  padding-top:clamp(var(--space-8), 5vw, var(--space-10));
  padding-bottom:clamp(var(--space-16), 12vw, 6rem);
  border-top:1px solid var(--olive-900); 
}
@media (min-width:720px){
  .cols{grid-template-columns:1fr 1fr;}
}
.col h2{
  font-family:var(--font-display);
  font-weight:600;
  font-size:var(--font-size-h2);
  line-height:var(--leading-heading);
  margin:0 0 var(--space-5);
}
.col h3{
  font-family:var(--font-display);
  font-weight:600;
  font-size:var(--font-size-h3);
  margin:var(--space-10) 0 var(--space-5);
}
.col p{
  color:var(--text-secondary);
  margin:0;
}

/* Liste des liens sociaux */
.social{
  list-style:none;
  padding:0;
  margin:0;
  display:flex;
  gap:var(--space-4);
}
.social a{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-width:var(--min-hit);
  min-height:var(--min-hit);
  color:var(--accent);            
  border-radius:var(--radius-md);
  text-decoration:none;
}
.social a:hover{color:var(--accent-hover);}
.social svg{width:24px;height:24px;}

/* Bouton « Écrivez-moi » */
.button{
  display:inline-flex;
  align-items:center;
  min-height:var(--min-hit);
  margin-top:var(--space-6);
  padding:var(--space-3) var(--space-8);
  background:var(--accent);
  color:var(--accent-on);
  /* font:inherit d'abord : un <button> n'hérite pas de la police du body par
     défaut (contrairement à <a>), il prend la police système du navigateur.
     Repéré via .entry-toggle sur "Voir mes réseaux" (2026-09-18), le seul
     <button class="button"> du site jusqu'ici — .button-ghost etc. n'étaient
     testés que sur des <a>. */
  font:inherit;
  font-weight:700;
  text-decoration:none;
  border-radius:var(--radius-md);
}
.button:hover{
  background:var(--accent-hover);
  color:var(--accent-on);
}
.button-ghost{
  background:transparent;
  border:1px solid var(--accent);
  color:var(--accent);
}
.button-ghost:hover{
  background:transparent;
  color:var(--accent-hover);
  border-color:var(--accent-hover);
}
.button-row{
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-4);
}
.button-row .button{margin-top:0;}

/* Pied de page */
.site-footer{
  padding-block:var(--space-10) clamp(var(--space-10), 8vw, var(--space-16));
  border-top:1px solid var(--border-default);
  text-align:center;
  color:var(--text-muted);
  font-size:var(--font-size-caption);
}
.site-footer p{margin:var(--space-3) 0;}

/* Une seule animations */
@keyframes lever{
  from{opacity:0;transform:translateY(8px);}
  to{opacity:1;transform:none;}
}
main#main{animation:lever .5s ease-out both;}
@media (prefers-reduced-motion:reduce){
  main#main{animation:none;}
}

/* ============================================================================
   Site multi-pages — en-tête, navigation, pied de page
   Classes préfixées `mp-` pour ne rien changer au rendu de la page unique
   actuelle (index.html), qui garde .site-header / .site-footer tels quels
   jusqu'à la bascule (voir docs/superpowers/plans/2026-09-09-site-multipage-base.md).
   ============================================================================ */

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

/* ---- En-tête ----
   .mp-header reste une barre pleine largeur (fond + trait du bas continus
   pendant le scroll) ; .mp-header-inner recentre logo + nav dans la même
   colonne de lecture que le reste du site (max-width:64rem), au lieu de les
   coller aux deux bords de l'écran. */
.mp-header{
  position:sticky;
  top:0;
  z-index:100;
  width:100%;
  background:var(--surface-page);
  border-bottom:1px solid var(--border-default);
  transition:opacity .2s ease, transform .2s ease;
}
.mp-header-inner{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--space-6);
  max-width:64rem;
  margin-inline:auto;
  padding:calc(var(--space-4) + 20px) clamp(var(--space-6), 5vw, var(--space-16));
}
.mp-header.is-hidden{
  opacity:0;
  transform:translateY(-100%);
}
@media (prefers-reduced-motion:reduce){
  .mp-header{transition:none;}
}

.site-logo{
  display:inline-flex;
  color:var(--accent);
  line-height:0;
  flex:none;
}
.mp-header .site-logo svg{height:clamp(80px, 9vw, 108px);width:auto;}
.mp-footer .site-logo svg{height:clamp(88px, 9vw, 112px);width:auto;}

.nav-burger{
  display:none;
  align-items:center;
  gap:var(--space-3);
  background:transparent;
  border:1px solid var(--border-strong);
  border-radius:var(--radius-md);
  color:var(--text-body);
  min-width:var(--min-hit);
  min-height:var(--min-hit);
  padding:0 var(--space-4);
  cursor:pointer;
}
.nav-burger svg{width:20px;height:20px;}

.nav-panel{
  display:flex;
  align-items:center;
  gap:clamp(var(--space-8), 5vw, 56px);
  flex:1;
  justify-content:flex-end;
  padding-right:var(--space-4);
}

.nav-panel > .site-nav{flex:none;}

.site-nav ul{
  list-style:none;
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-6);
  margin:0;
  padding:0;
}
.site-nav a,
.lab-submenu a{
  display:inline-flex;
  align-items:center;
  min-height:var(--min-hit);
  font-family:var(--font-display);
  font-weight:600;
  font-size:.95rem;
  letter-spacing:.01em;
  text-transform:uppercase;
  color:var(--accent);
  text-decoration:none;
  border-bottom:2px solid transparent;
}
.site-nav a:hover,
.lab-submenu a:hover{color:var(--accent-hover);}
.site-nav a[aria-current="page"]{border-bottom-color:var(--accent);}

.nav-lab{position:relative;}
.nav-lab-row{display:inline-flex;align-items:center;gap:2px;}
.lab-toggle{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:28px;
  height:var(--min-hit);
  background:transparent;
  border:0;
  color:var(--accent);
  cursor:pointer;
}
.lab-toggle svg{width:14px;height:14px;transition:transform .15s ease;}
.lab-toggle[aria-expanded="true"] svg{transform:rotate(180deg);}
@media (prefers-reduced-motion:reduce){
  .lab-toggle svg{transition:none;}
}

/* Sous-menu LAB : pas un popover — un toggle qui élargit le bloc de nav pour
   révéler les trois pages, dans le même style typo que les entrées du haut. */
.lab-submenu{
  list-style:none;
  margin:var(--space-2) 0 0;
  padding:0;
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-6);
  width:100%;
}

.header-tools{
  display:flex;
  flex-direction:row;
  align-items:center;
  gap:var(--space-4);
}
.lang-switch{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:32px;
  height:32px;
  border:1.5px solid var(--text-body);
  border-radius:50%;
  font-family:var(--font-display);
  font-weight:700;
  font-size:.72rem;
  letter-spacing:.02em;
  text-transform:uppercase;
  color:var(--text-body);
  text-decoration:none;
}
.lang-switch:hover{color:var(--accent-hover);border-color:var(--accent-hover);}
.a11y-options-link{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:32px;
  height:32px;
  color:var(--text-body);
}
.a11y-options-link:hover{color:var(--accent-hover);}
.a11y-options-link svg{width:32px;height:32px;}

/* ---- Navigation : sans JS, tout reste ouvert. Avec JS, replié par défaut,
   piloté par assets/js/site.js. `.js` est posé sur <html> par le script
   inline du <head>, avant le premier rendu. ---- */
@media (max-width:859px){
  .mp-header{
    display:grid;
    grid-template-columns:1fr auto 1fr;
    align-items:center;
    flex-wrap:wrap;
  }
  .site-logo{grid-column:2;justify-self:center;}
  .nav-burger{display:inline-flex;grid-column:3;justify-self:end;}
  .nav-panel{
    grid-column:1 / -1;
    flex-direction:column;
    align-items:stretch;
    gap:var(--space-6);
    padding-top:var(--space-4);
  }
  .site-nav ul{flex-direction:column;gap:0;}
  .lab-submenu{flex-direction:column;gap:0;padding-left:var(--space-6);}
  .header-tools{align-items:center;flex-direction:row;gap:var(--space-6);}

  .js .nav-panel{display:none;}
  .js .nav-panel.is-open{display:flex;}
}
.js .lab-submenu:not(.is-open){display:none;}

/* ---- Pied de page ----
   Trois colonnes ~30/20/50 sur fond noir uniforme ; seul le bloc des options
   d'accessibilité garde la surface-card verte (comme les cartes du site). */
.mp-footer{
  border-top:1px solid var(--border-default);
  padding:clamp(var(--space-10), 6vw, var(--space-16)) clamp(var(--space-6), 5vw, var(--space-16));
}
.footer-grid{
  display:grid;
  gap:var(--space-10);
  max-width:72rem;
  margin-inline:auto;
  width:100%;
}
@media (min-width:860px){
  .footer-grid{grid-template-columns:3fr 2fr 5fr;}
}
.footer-col{display:flex;flex-direction:column;gap:var(--space-8);min-width:0;}

.mp-footer h2{
  font-family:var(--font-display);
  font-size:var(--font-size-h3);
  font-weight:600;
  margin:0 0 var(--space-4);
}

/* Colonne 1 : marque */
.footer-col-brand{gap:var(--space-8);}
.footer-projects ul{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:var(--space-5);
}
.footer-project-title{
  margin:0;
  font-family:var(--font-display);
  font-weight:600;
  font-size:var(--font-size-body-sm);
  color:var(--text-secondary);
}
.footer-project-desc{
  margin:var(--space-1) 0 0;
  font-size:var(--font-size-caption);
  color:var(--text-muted);
}
.footer-credit{
  display:flex;
  align-items:center;
  gap:var(--space-3);
  color:var(--text-muted);
  font-size:var(--font-size-caption);
}
.footer-credit p{margin:0;}
.mp-footer .footer-credit-logo svg{height:28px;width:auto;}

/* Colonne 2 : plan du site */
.footer-sitemap ul{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:var(--space-3);
}
.footer-sitemap a{
  color:var(--text-secondary);
  font-size:var(--font-size-body-sm);
}

/* Colonne 3 : accessibilité */
.footer-a11y-statement p{
  color:var(--text-secondary);
  margin:0;
  font-size:var(--font-size-body-sm);
}
.footer-a11y-controls{
  padding:var(--space-8);
  background:var(--surface-card);
  border:1px solid var(--border-default);
  border-radius:var(--radius-lg);
  scroll-margin-top:calc(var(--min-hit) + var(--space-6));
}
.footer-a11y-controls h3{
  font-family:var(--font-display);
  font-size:var(--font-size-body);
  font-weight:600;
  margin:0 0 var(--space-5);
}
.a11y-control{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:var(--space-3);
  padding-block:var(--space-3);
  border-top:1px solid var(--border-default);
}
.a11y-control:first-of-type{border-top:0;padding-top:0;}
.a11y-control-label{font-size:var(--font-size-body-sm);color:var(--text-secondary);}
.a11y-control-group{display:inline-flex;gap:var(--space-2);}
.a11y-control-group button{
  min-height:36px;
  padding:0 var(--space-4);
  font-size:var(--font-size-caption);
  font-weight:700;
  font-family:var(--font-body);
  color:var(--text-secondary);
  background:var(--surface-input);
  border:1px solid var(--border-strong);
  border-radius:var(--radius-sm);
  cursor:pointer;
}
.a11y-control-group button[aria-pressed="true"]{
  background:var(--accent);
  border-color:var(--accent);
  color:var(--accent-on);
}
.a11y-control-group button:hover{border-color:var(--accent);}

/* ---- Taille de texte réglable (options d'accessibilité) ----
   Échelle appliquée sur <html>, hérite dans toute la page. */
html.vl-font--2{font-size:87.5%;}
html.vl-font--1{font-size:93.75%;}
html.vl-font-1{font-size:112.5%;}
html.vl-font-2{font-size:125%;}

/* ============================================================================
   Page Accueil (multi-pages) — 6 blocs, voir src/pages/accueil.html
   ============================================================================ */

main#main > section{
  padding-block:clamp(var(--space-10), 6vw, var(--space-16));
}
main#main > section:first-child{padding-top:clamp(var(--space-8), 5vw, var(--space-10));}
/* Pas de trait de séparation : les cartes (.mp-card) et la lune en fond
   suffisent à distinguer les blocs dans cette version. Marge en plus entre
   deux blocs : rapprochés, deux cartes voisines peuvent apparaître en fondu
   presque en même temps (leurs fenêtres de proximité au centre de l'écran se
   chevauchent) — l'écart supplémentaire les sépare mieux dans le scroll. */
main#main > section + section{margin-top:30px;}

main#main h2{
  font-family:var(--font-display);
  font-weight:600;
  font-size:var(--font-size-h2);
  line-height:var(--leading-heading);
  margin:0 0 var(--space-6);
}
main#main h3{
  font-family:var(--font-display);
  font-weight:600;
  font-size:var(--font-size-h3);
  line-height:var(--leading-heading);
  margin:0 0 var(--space-3);
}

/* ---- 1. Accroche ---- */
.hero{
  max-width:42rem;
  margin-block:50px;
  padding-top:calc(clamp(var(--space-8), 6vw, var(--space-12)) + 20px);
  padding-bottom:calc(clamp(var(--space-8), 6vw, var(--space-12)) + 20px); /* laisse la lune nue respirer avant la carte suivante */
}
.hero h1{
  font-family:var(--font-display);
  font-weight:600;
  font-size:clamp(1.8rem, 4.6vw, 2.5rem);
  line-height:var(--leading-tight);
  letter-spacing:var(--tracking-display);
  margin:0 0 var(--space-6);
}
.hero h1 em{font-style:italic;}
.hero .lead-body{
  font-size:var(--font-size-lead);
  color:var(--text-secondary);
  margin:0 0 var(--space-8);
}

/* ---- 2. Ce que je propose ---- */
.offer-list{
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  gap:var(--space-8);
  max-width:52rem;
}
.offer-list p{margin:0;color:var(--text-secondary);}
.offer-list p strong{color:var(--text-body);}
.offer-note{
  margin-top:var(--space-2) !important;
  color:var(--text-faint) !important;
  font-size:var(--font-size-caption);
  font-style:italic;
}

/* ---- 3. Sur le blog ---- */
.blog-grid{
  list-style:none;
  margin:0 0 var(--space-8);
  padding:0;
  display:grid;
  gap:var(--space-6);
}
@media (min-width:720px){
  .blog-grid{grid-template-columns:repeat(3, 1fr);}
}
.blog-card{
  display:block;
  height:100%;
  padding:var(--space-6);
  background:var(--surface-card);
  border:1px solid var(--border-default);
  border-radius:var(--radius-lg);
  text-decoration:none;
  color:var(--text-body);
}
.blog-card:hover{border-color:var(--accent);color:var(--text-body);}
.blog-card h3{font-size:var(--font-size-body);margin:0 0 var(--space-3);}
.blog-card p{margin:0;color:var(--text-secondary);font-size:var(--font-size-body-sm);}

/* ---- 4. Le Lab ---- */
.lab-teaser > p{max-width:42rem;color:var(--text-secondary);}
.lab-items{
  list-style:none;
  margin:var(--space-2) 0 var(--space-8);
  padding:0;
  display:grid;
  gap:var(--space-8);
}
@media (min-width:720px){
  .lab-items{grid-template-columns:repeat(3, 1fr);}
}
.lab-items p{margin:0;color:var(--text-secondary);font-size:var(--font-size-body-sm);}
.lab-note{
  margin:var(--space-4) 0 0;
  color:var(--text-faint);
  font-size:var(--font-size-caption);
  font-style:italic;
}

/* Le Lab tombe à peu près là où la lune fixe est pleine (voir "Lune fixe"
   plus bas) : contrairement aux autres .mp-card, son fond sauge est fixe —
   PAS de fondu au scroll — pour rester un repère visuel fort, et pour éviter
   la fenêtre de faible contraste que donnerait un texte sombre pendant que
   le fond sauge est encore semi-transparent. */
.mp-card--lab{
  color:var(--accent-on);
}
.mp-card--lab::before{
  background:var(--accent) !important;
  opacity:.88 !important; /* légèrement adouci (retour Pauline : trop accrocheur à pleine opacité) */
  mask-image:none !important; /* reste un panneau plein, pas un dégradé */
  -webkit-mask-image:none !important;
}
.mp-card--lab > p{color:var(--accent-on);}
.mp-card--lab h2{color:var(--accent-on);}
.mp-card--lab .lab-items h3{color:var(--accent-on);}
.mp-card--lab .lab-items p{color:var(--accent-on);opacity:.82;}
.mp-card--lab .lab-note{color:var(--accent-on);opacity:.7;}
.mp-card--lab .button{
  background:var(--ink-950);
  color:var(--cream-100);
}
.mp-card--lab .button:hover{background:var(--ink-800);color:var(--cream-100);}

/* ---- 5. Qui je suis / 6. Rester en contact ---- */
.about-teaser p,
.contact-teaser > p{max-width:42rem;color:var(--text-secondary);}
.about-teaser .button-ghost,
.contact-teaser .button-row{margin-top:var(--space-6);}
.contact-note{
  margin-top:var(--space-6);
  color:var(--text-faint);
  font-size:var(--font-size-caption);
}

/* ---- Lune fixe + éclipse liée au scroll de la page ----
   Un seul disque (assets/img/moon.jpg), position:fixed : il ne bouge pas à
   l'écran, c'est le CONTENU qui défile devant/dessus lui. Une seule ombre
   (même technique qu'avant : cercle de la couleur du fond, translaté, bord
   flouté pour un terminateur doux) dont la position suit --moon-phase,
   recalculée en continu sur toute la hauteur de la page (assets/js/moon.js).
   --moon-phase est SIGNÉE, de -1 à 1 : 0 en haut et en bas de page (éclipse
   totale, le H1 se lit sur fond nu), pleine lune (±1) vers le milieu. Le
   signe change entre les deux moitiés de page — l'ombre coulisse vers le bas
   sur la première, vers le haut sur la seconde — pour que le croissant du
   haut de page ne soit pas la copie conforme de celui du bas (même |phase|,
   même sens de coulissement : sans ce changement de signe, les deux
   croissants sont identiques au lieu d'être en miroir). Opacité fixe à 60%,
   pas de fondu par bloc : la lune est soit cachée par l'éclipse, soit
   visible, jamais animée en apparition/disparition indépendamment du scroll.

   .moon-fixed et .page-scrim sont en z-index négatif : ils se posent derrière
   le flux normal de la page sans toucher au z-index du header/footer/main. */
.moon-fixed{
  position:fixed;
  inset:0;
  z-index:-2;
  display:flex;
  align-items:center;
  justify-content:center;
  overflow:hidden;
  pointer-events:none;
}
.moon-fixed .moon{
  position:relative;
  width:min(93.5vmin, 990px); /* +10% */
  aspect-ratio:1;
  opacity:.75; /* +15% */
}
.moon-fixed .moon-photo,
.moon-fixed .moon-shadow{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  border-radius:50%;
}
.moon-fixed .moon-photo{object-fit:cover;display:block;}
.moon-fixed .moon-shadow{
  background:var(--surface-page);
  filter:blur(18px); /* terminateur doux, cf. retour utilisateur sur la v1 par bloc */
  transform:translateY(calc(var(--moon-phase, 0) * 100%));
}
.moon-fixed .moon::after{
  content:'';
  position:absolute;
  inset:0;
  border-radius:50%;
  background:radial-gradient(circle, transparent 55%, var(--surface-page) 100%);
  pointer-events:none;
}
/* Voile sombre semi-transparent sur toute la page, en permanence : baisse le
   contraste de la lune contre le texte sans dépendre du scroll (cf. .mp-card
   ci-dessous pour le renfort par bloc). */
.page-scrim{
  position:fixed;
  inset:0;
  z-index:-1;
  background:var(--surface-page);
  opacity:.35;
  pointer-events:none;
}
@media (prefers-reduced-motion:reduce){
  .moon-fixed .moon-shadow{transition:transform .6s ease;}
}

/* ---- Cartes de lisibilité par bloc (.mp-card) ----
   Fond qui se renforce en fondu (--card-fade, 0 → 1, assets/js/moon.js)
   quand le bloc est proche du centre de l'écran : assez pour rester lisible
   par-dessus la lune, sans figer un fond plein en permanence sur toute la
   page. .mp-card--lab (voir section "Le Lab") écrase ce fondu par un fond
   sauge fixe. */
.mp-card{
  position:relative;
  isolation:isolate;
  padding-inline:clamp(var(--space-6), 5vw, var(--space-10));
  border-radius:var(--radius-lg);
}
.mp-card::before{
  content:'';
  position:absolute;
  inset:0;
  z-index:-1;
  border-radius:inherit;
  background:var(--surface-card);
  opacity:calc(var(--card-fade, 0) * .92);
  pointer-events:none;
  /* La carte dépasse la lune (ronde) sur les côtés : sans ça, son bord droit/
     gauche tranche net sur le noir de la page. Masque en ellipse, plus
     large que haute, pour un fondu plus marqué sur les côtés qu'en haut/bas. */
  mask-image:radial-gradient(ellipse 65% 100% at 50% 50%, black 45%, transparent 100%);
  -webkit-mask-image:radial-gradient(ellipse 65% 100% at 50% 50%, black 45%, transparent 100%);
}

/* ---- Page À propos : texte + image en 2 colonnes ----
   65% texte / 35% image sur grand écran (70/30 avec --30), empilé en dessous
   de 720px. L'image est verticalement centrée sur le bloc de texte
   (align-items:center). Le modificateur --reverse inverse la position ET la
   piste de grille (via grid-column explicite, PAS `order`) : en grille CSS,
   `order` change aussi l'ordre d'auto-placement dans les pistes, pas
   seulement l'ordre visuel — avec seulement `order`, l'image héritait de la
   piste large (70%) au lieu de l'étroite (30%), d'où la photo "énorme"
   observée sur L'humain. grid-column fige chaque élément dans sa piste,
   indépendamment de l'ordre du DOM (qui reste texte puis image dans les deux
   sections, pour une lecture clavier/lecteur d'écran cohérente). */
.apropos-row{
  display:grid;
  gap:var(--space-8);
  align-items:center;
}
@media (min-width:720px){
  .apropos-row{grid-template-columns:65fr 35fr;}
  /* grid-row:1 explicite sur les deux : sans ça, l'auto-placement (qui ne
     revient jamais en arrière une fois le curseur avancé) pousse le 2e
     enfant du DOM sur une nouvelle ligne dès que son grid-column est AVANT
     celui du 1er (cas --reverse : le texte, 1er du DOM, prend la colonne 2 ;
     l'image, 2e du DOM, redemande la colonne 1 — trop tard, curseur déjà
     passé). C'était le vrai bug derrière l'image mal alignée sur L'humain :
     elle ne partageait pas la ligne du texte, elle tombait dessous. */
  .apropos-row .apropos-text{grid-column:1;grid-row:1;}
  .apropos-row .apropos-figure{grid-column:2;grid-row:1;}
  .apropos-row--30{grid-template-columns:70fr 30fr;}
  .apropos-row--reverse{grid-template-columns:35fr 65fr;}
  .apropos-row--reverse.apropos-row--30{grid-template-columns:30fr 70fr;}
  .apropos-row--reverse .apropos-text{grid-column:2;}
  .apropos-row--reverse .apropos-figure{grid-column:1;}
}
.apropos-figure{margin:0;}
.apropos-figure img{
  width:100%;
  display:block;
  /* Fondu des bords plutôt que coin arrondi net : le fond de l'illustration
     (noir pur) et le fond de la page (--surface-page, quasi noir mais teinté)
     ne matchent jamais exactement en dur ; l'image se dissout dans la page
     au lieu de découper un rectangle dessus. Même logique que le masque de
     .mp-card::before plus bas, appliqué ici directement sur l'image. */
  mask-image:radial-gradient(ellipse 92% 92% at 50% 50%, black 80%, transparent 100%);
  -webkit-mask-image:radial-gradient(ellipse 92% 92% at 50% 50%, black 80%, transparent 100%);
}

/* Lune de fond conservée sur la page À propos (même mécanique que partout :
   .moon-fixed/.page-scrim/assets/js/moon.js, rien à dupliquer), mais
   atténuée : cette page a déjà deux images fortes + une carte (.apropos-frame)
   comme repères, la lune n'a plus besoin d'être le seul élément d'ambiance. */
.page-apropos .moon-fixed .moon{opacity:.4;}
.page-apropos .page-scrim{opacity:.55;}

/* ---- Page À propos : 3 boutons + frame à bascule ----
   La frame (résumé des 3 sections) n'existe pas visuellement tant qu'aucun
   bouton n'est actif : hauteur 0 via la technique grid-template-rows
   0fr → 1fr (anime une hauteur "auto" sans mesurer de pixels en JS). Un seul
   panneau visible à la fois (recliquer le bouton actif referme tout) —
   logique d'accordéon à sélection unique, pas des tabs (rien n'est ouvert
   par défaut). Comportement dans assets/js/apropos.js. */
.apropos-toggle-row{
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-4);
  margin:0 0 var(--space-10);
}
.apropos-toggle{
  display:inline-flex;
  align-items:center;
  min-height:var(--min-hit);
  padding:var(--space-3) var(--space-8);
  background:transparent;
  /* --accent-quiet (pas --accent) : même épaisseur 1px que .entry-card sur
     Tools/Projets, mais un sauge plein contre le fond très sombre lit
     toujours plus "épais" qu'un simple hairline — la teinte plus sourde
     rapproche le poids visuel sans sortir de la gamme sauge (demande
     Pauline du 2026-09-16). */
  border:1px solid var(--accent-quiet);
  border-radius:var(--radius-md);
  color:var(--accent);
  font-size:var(--font-size-body);
  cursor:pointer;
  transition:background-color .15s ease, color .15s ease;
}
.apropos-toggle:hover{color:var(--accent-hover);border-color:var(--accent-hover);}
.apropos-toggle[aria-expanded="true"]{
  background:var(--accent);
  color:var(--accent-on);
}
.apropos-toggle[aria-expanded="true"]:hover{background:var(--accent-hover);color:var(--accent-on);}

.apropos-frame{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .4s ease;
  /* Respiration avant le pied de page quand un onglet est ouvert. (Cette
     règle visait avant à recopier l'espacement de .hero via
     var(--space-12) — un jeton qui n'existe pas dans tokens.css, l'échelle
     saute de --space-10 à --space-16 : le calc() entier était donc invalide
     et retombait silencieusement à 0, d'où l'absence de marge malgré la
     règle. Remplacé par une valeur simple et sûre.) */
  margin-bottom:30px;
}
.apropos-frame.is-open{grid-template-rows:1fr;}
.apropos-frame-inner{
  overflow:hidden;
  min-height:0;
  border:1px solid var(--accent-quiet);
  border-radius:var(--radius-lg);
  /* Fond noir non-opaque : la lune (atténuée) continue de se deviner derrière
     la carte plutôt que d'être coupée net. */
  background:oklch(0.11 0.006 150 / 0.82);
}
.apropos-panel{padding:20px;}
.apropos-panel p{font-size:calc(var(--font-size-body) - 1px);}
.apropos-panel h2{
  margin:var(--space-4) var(--space-3) var(--space-6) var(--space-3);
  padding-bottom:var(--space-3);
  border-bottom:1px solid var(--border-default);
}
@media (prefers-reduced-motion:reduce){
  .apropos-frame{transition:none;}
}

/* ============================================================================
   Page Le Lab — aiguillage (étape 1, voir src/pages/lelab.html)
   ============================================================================ */

/* Lune atténuée, même logique que la page À propos : la page a déjà 2 blocs
   de cartes (.mp-card), la lune n'a plus besoin d'être le seul repère. */
.page-lelab .moon-fixed .moon{opacity:.4;}
.page-lelab .page-scrim{opacity:.55;}

/* Une seule colonne à toutes les tailles (choix délibéré, pas juste le repli
   mobile) : la mise en grille 2/4 colonnes testée rendait chaque engagement
   trop court pour se lire confortablement.
   Séparation titre/contenu : un espacement seul (même police que le corps)
   ne suffisait pas à distinguer "Ce à quoi je tiens" du premier engagement.
   Remplacé par un filet (--border-default, même que .blog-card/.a11y-control
   ailleurs sur le site) sous le titre, répété sous chaque engagement, avec un
   rythme fixe en px (pas les jetons --space, valeurs choisies à l'essai avec
   Pauline le 2026-09-16) : 15px de chaque côté du filet, et la même marge
   (15px, pas de filet) sous le dernier engagement pour marquer la fin du
   bloc, symétrique avec l'espace au-dessus du titre. */
main#main > .engagements{padding-top:15px;}
.engagements h2{
  margin:0 0 15px;
  padding-bottom:15px;
  border-bottom:1px solid var(--border-default);
}
.engagements-grid{
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  gap:0;
}
.engagements-grid li{
  padding-bottom:15px;
  margin-bottom:15px;
  border-bottom:1px solid var(--border-default);
}
.engagements-grid li:last-child{
  padding-bottom:0;
  margin-bottom:15px;
  border-bottom:none;
}
.engagement-head{
  display:flex;
  align-items:center;
  gap:var(--space-3);
  margin-bottom:var(--space-3);
}
.engagement-icon{
  width:28px;
  height:28px;
  flex:none;
  color:var(--accent);
}
.engagements-grid h3{margin:0;font-size:var(--font-size-body);}
.engagements-grid p{margin:0;color:var(--text-secondary);font-size:var(--font-size-body-sm);}
.engagements-grid p em{font-style:italic;color:var(--text-body);}

.lab-ideas > .blog-grid{margin-bottom:0;}

/* ============================================================================
   Pages Vesper Tools / Projets — carte commune à déclencheur (étape 2, voir
   src/pages/lelab-outils.html, src/pages/lelab-realisations.html)
   ============================================================================
   Carte "entry-card" : partie visible (badges, titre, phrase, chiffres clés
   optionnels, action principale, mockup optionnel, bouton +) toujours
   suffisante seule. Le panneau cause détail est masqué par défaut (attribut
   hidden, jamais juste une opacité/hauteur nulle) et animé à l'ouverture avec
   la même technique que .apropos-frame (grid-template-rows 0fr → 1fr sur un
   conteneur, overflow:hidden sur son enfant direct). Contrairement à
   À propos, chaque carte est indépendante : ouvrir l'une n'affecte pas les
   autres (voir assets/js/entries.js). Pas de lune sur ces pages (voir
   ".page-lelab-outils"/".page-lelab-realisations" plus bas), donc pas besoin
   du "nudge" vers moon.js qu'apropos.js déclenche après coup. */

.entry-list{
  list-style:none;
  /* Marge additionnelle avant la 1ʳᵉ carte (demande Pauline), et même marge
     que ".apropos-frame" avant le footer (30px, filet sauge → footer) : ici
     aussi rien n'enveloppe la liste dans une <section>, donc pas de
     padding-bottom automatique à hériter. */
  margin:var(--space-10) 0 30px;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:var(--space-8);
}
.entry-card{
  border:1px solid var(--border-default);
  border-radius:var(--radius-lg);
  padding:clamp(var(--space-6), 4vw, var(--space-8));
}
.entry-badges{
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-2);
  margin-bottom:var(--space-4);
}
.entry-badge{
  display:inline-flex;
  align-items:center;
  min-height:0;
  padding:3px var(--space-4);
  border:1px solid var(--border-strong);
  border-radius:999px;
  font-size:var(--font-size-caption);
  color:var(--text-secondary);
}
.entry-badge--category{border-color:var(--accent);color:var(--accent);}

.entry-main{
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-6);
  align-items:flex-start;
}
.entry-text{flex:1 1 20rem;min-width:0;}
/* h2 sémantique (rien ne les précède sur ces pages, donc pas de saut de
   niveau), mais taille visuelle d'un h3 : un titre de carte n'a pas besoin
   du poids du h2 générique du site. Spécificité forcée par "main#main" pour
   passer devant la règle globale "main#main h2". */
main#main .entry-text h2{
  margin:0 0 var(--space-2);
  font-size:var(--font-size-h3);
}
.entry-tagline{margin:0 0 var(--space-4);color:var(--text-secondary);}
.entry-stats{
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-2) var(--space-6);
  margin:0 0 var(--space-4);
  padding:0;
  list-style:none;
}
/* Chiffres clés : même traitement typo que .site-nav (police display,
   graisse 600, majuscules, tracking), chiffre agrandi et en sauge pour
   sauter aux yeux, description qui garde sa couleur/taille d'origine. */
.entry-stats li{
  display:flex;
  flex-direction:column;
  align-items:center;
  text-align:center;
  font-family:var(--font-display);
  font-weight:600;
  letter-spacing:.01em;
  text-transform:uppercase;
  font-size:clamp(1.5rem, 4vw, 2rem);
  color:var(--accent);
}
.entry-stats li span{
  display:block;
  font-family:var(--font-display);
  font-weight:600;
  letter-spacing:.01em;
  text-transform:uppercase;
  font-size:var(--font-size-caption);
  color:var(--text-faint);
}

.entry-mockup{
  flex:0 0 auto;
  width:16.5rem; /* +50% (demande Pauline du 2026-09-18), était 11rem */
  aspect-ratio:4/3; /* réservé tant qu'aucune image (texte de substitution) */
  display:flex;
  align-items:center;
  justify-content:center;
  padding:var(--space-3);
  border:1px dashed var(--border-strong);
  border-radius:var(--radius-md);
  color:var(--text-faint);
  font-size:var(--font-size-caption);
  text-align:center;
  overflow:hidden;
}
/* Dès qu'une vraie image remplace le texte de substitution : plus de cadre
   ni de padding (les mockups de Pauline ont un fond transparent voulu, un
   cadre le casserait — retour du 2026-09-24) et le ratio 4/3 n'est plus
   forcé : la boîte suit la forme réelle de l'image (ex. une capture de
   téléphone, portraite), plafonnée en hauteur pour ne pas dominer la carte
   à côté du texte. */
.entry-mockup:has(img){
  aspect-ratio:auto;
  padding:0;
  border:none;
}
.entry-mockup img{
  display:block;
  width:100%;
  height:auto;
  max-height:24rem;
  object-fit:contain;
  border-radius:inherit;
}

/* Rangée [icône lien] [bouton +] : même gabarit de bouton carré pour les
   deux, l'icône lien n'est un <a> que s'il y a vraiment un lien (sinon
   <span aria-hidden>, non interactif — voir le commentaire dans les pages
   de contenu). */
.entry-controls{
  display:flex;
  gap:var(--space-3);
  margin-top:var(--space-4);
}
.entry-icon-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:var(--min-hit);
  height:var(--min-hit);
  background:transparent;
  border:1px solid var(--border-strong);
  border-radius:var(--radius-md);
  color:var(--text-body);
}
.entry-icon-btn-svg{width:16px;height:16px;flex:none;}
a.entry-icon-btn{cursor:pointer;}
a.entry-icon-btn:hover{border-color:var(--accent);}
button.entry-icon-btn{cursor:pointer;}
button.entry-icon-btn:hover{border-color:var(--accent);color:var(--accent);}

.entry-link-icon{color:var(--accent);}
/* Gris (pas blanc) volontairement : sur fond très sombre, un blanc plein
   lirait presque aussi fort que le sage, et brouillerait la distinction
   "il y a un lien" / "il n'y en a pas". */
.entry-link-icon--none{color:var(--text-faint);}

.entry-toggle-icon{transition:transform .2s ease;}
.entry-toggle[aria-expanded="true"] .entry-toggle-icon{transform:rotate(45deg);}

.entry-panel-wrap{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .3s ease;
}
.entry-panel-wrap.is-open{grid-template-rows:1fr;}
.entry-panel-inner{overflow:hidden;min-height:0;}
.entry-panel{
  margin-top:var(--space-6);
  padding-top:var(--space-6);
  border-top:1px solid var(--border-default);
}
.entry-detail{
  margin:0;
  display:grid;
  gap:var(--space-4);
}
.entry-detail dt{
  font-weight:700;
  color:var(--text-body);
  margin:0 0 var(--space-1);
}
.entry-detail dd{margin:0;color:var(--text-secondary);}
.entry-freeform{
  margin:var(--space-4) 0 0;
  padding-top:var(--space-4);
  border-top:1px solid var(--border-default);
  color:var(--text-secondary);
  font-style:italic;
}
@media (prefers-reduced-motion:reduce){
  .entry-panel-wrap{transition:none;}
  .entry-toggle-icon{transition:none;}
}

/* Pas de lune sur les sous-onglets du Lab pour l'instant (note Pauline,
   session du 2026-09-16) : la carte .entry-card porte déjà tout le contraste
   nécessaire, la lune n'ajoute qu'un fond concurrent sur des pages qui seront
   surtout des listes. */
.page-lelab-outils .moon-fixed,
.page-lelab-realisations .moon-fixed{display:none;}

/* ============================================================================
   Page Blog (étape 3, voir scripts/build-blog.mjs, src/pages/blog.html)
   ============================================================================
   Galerie "destructurée" (demande Pauline) : pas de champ taille dans le
   front matter des articles, les variantes de gabarit (carte large / carte
   haute) sont purement du nth-child CSS ci-dessous, sur un grid-auto-flow
   dense pour combler les trous laissés par les cartes qui débordent de leur
   piste. Chaque carte réutilise .mp-card (même fondu au scroll que
   l'accueil, voir assets/js/moon.js — aucune inscription JS supplémentaire
   nécessaire, la classe suffit) mais son masque ::before est réécrit :
   celui de .mp-card est calibré pour un bloc pleine largeur, sur une carte
   étroite il rognerait trop les coins. */

/* ---- Recherche (bouton loupe + barre en toggle, voir assets/js/blog-search.js) ----
   Vit dans .hero, juste après .lead-body : même emplacement que
   .button-row sur l'accueil (demande Pauline du 2026-09-16), pas un bloc à
   part avec sa propre marge. Le toggle s'ouvre à droite du bouton (grid-
   template-columns 0fr → 1fr, même principe que .apropos-frame/
   .entry-panel-wrap mais sur l'axe horizontal — l'attribut hidden porte
   toujours l'accessibilité, pas juste la largeur 0). Contour sauge fin sur
   le bouton loupe ; le champ reste sur le contour neutre par défaut, sinon
   les deux contours sauge côte à côte se confondent. */
.blog-search{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:var(--space-3);
}
.blog-search-toggle{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:var(--min-hit);
  height:var(--min-hit);
  flex:none;
  padding:0;
  background:transparent;
  border:1px solid var(--accent);
  border-radius:var(--radius-md);
  color:var(--accent);
  cursor:pointer;
}
.blog-search-toggle:hover{background:var(--surface-card);}
.blog-search-toggle-svg{width:18px;height:18px;}
.blog-search-panel-wrap{
  display:grid;
  grid-template-columns:0fr;
  transition:grid-template-columns .3s ease;
}
.blog-search-panel-wrap.is-open{grid-template-columns:1fr;}
.blog-search-panel-inner{overflow:hidden;min-width:0;}
.blog-search-panel{
  display:flex;
  align-items:center;
  gap:var(--space-3);
  width:18rem;
  max-width:70vw;
}
.blog-search-panel input[type="search"]{
  flex:1;
  min-width:0;
  min-height:var(--min-hit);
  padding:var(--space-3) var(--space-5);
  background:var(--surface-input);
  border:1px solid var(--border-default);
  border-radius:var(--radius-md);
  color:var(--text-body);
  font:inherit;
  font-size:var(--font-size-body-sm);
}
.blog-search-panel input[type="search"]:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
.blog-search-submit{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:var(--min-hit);
  height:var(--min-hit);
  flex:none;
  padding:0;
  background:transparent;
  border:1px solid var(--border-strong);
  border-radius:var(--radius-md);
  color:var(--accent);
  cursor:pointer;
}
.blog-search-submit:hover{border-color:var(--accent);}
.blog-search-submit-svg{width:18px;height:18px;}
@media (prefers-reduced-motion:reduce){
  .blog-search-panel-wrap{transition:none;}
}

.blog-gallery{
  list-style:none;
  margin:var(--space-10) 0 30px;
  padding:0;
  display:grid;
  gap:var(--space-6);
  grid-auto-flow:dense;
  /* Sans ça, les cartes d'une même rangée s'étirent (align-items:stretch
     par défaut) pour matcher la plus haute du lot — invisible en mobile
     (une carte par rangée) mais très visible dès qu'on a plusieurs colonnes.
     "start" laisse chaque carte à sa propre hauteur : les trous que ça
     laisse sont voulus (effet mur de liège/moodboard, pas un mur plein). */
  align-items:start;
}
@media (min-width:720px){
  .blog-gallery{grid-template-columns:repeat(6, 1fr);grid-auto-rows:min-content;}
  /* Rythme irrégulier sur un cycle de 7 cartes : 1 large (2 colonnes), le
     reste au gabarit standard (1x1, largeur variable via auto-fit implicite
     du 6-colonnes). Recommence tous les 7 éléments pour ne pas dépendre du
     nombre total d'articles. Pas de grid-row:span : la hauteur de chaque
     carte suit son propre contenu (voir .blog-entry-body plus bas) — un
     span forcé laissait un vide entre les tags et le bas du cadre quand le
     texte ne remplissait pas la hauteur imposée. */
  .blog-gallery > .blog-entry{grid-column:span 2;}
  .blog-gallery > .blog-entry:nth-child(7n+1){grid-column:span 4;}

  /* Les lignes de la grille restent lisibles tant que tout démarre au même
     niveau : on désynchronise le calage vertical (cycle de 3, indépendant
     du cycle de largeur ci-dessus) pour un rendu "épinglé au mur", pas
     aligné au cordeau — sans inclinaison (essayée puis retirée sur retour
     Pauline du 2026-09-16 : le bazar d'alignement lui plaisait, pas la
     rotation). La grande carte (span 4) reste l'ancre visuelle du lot : pas
     décalée, sinon l'effet lit comme un bug plutôt qu'un choix — d'où la
     règle après, qui l'emporte car déclarée plus tard. */
  .blog-gallery > .blog-entry:nth-child(3n+2){align-self:center;}
  .blog-gallery > .blog-entry:nth-child(3n){align-self:end;}
  .blog-gallery > .blog-entry:nth-child(7n+1){align-self:start;}
}
.blog-entry{
  position:relative;
  isolation:isolate;
  display:flex;
  flex-direction:column;
  padding-inline:0; /* écrase .padding-inline de .mp-card : le padding vit
    sur .blog-entry-body pour laisser l'image affleurer les bords */
  border-radius:var(--radius-lg);
  overflow:hidden;
}
.blog-entry::before{
  mask-image:radial-gradient(ellipse 90% 94% at 50% 50%, black 65%, transparent 100%);
  -webkit-mask-image:radial-gradient(ellipse 90% 94% at 50% 50%, black 65%, transparent 100%);
}
.blog-entry-image{margin:0;line-height:0;}
.blog-entry-image img{width:100%;max-height:220px;object-fit:cover;display:block;}
.blog-entry-body{
  padding:clamp(var(--space-6), 4vw, var(--space-8));
  display:flex;
  flex-direction:column;
}
/* Étiré à toute la largeur par défaut (align-items:stretch, hérité du
   parent en colonne) alors que le contour doit épouser le texte de la
   catégorie, pas la carte. */
.blog-entry-body > .entry-badge{align-self:flex-start;}
main#main .blog-entry-body h2{
  margin:var(--space-4) 0 var(--space-2);
  font-size:var(--font-size-h3);
}
.blog-entry-body h2 a{color:inherit;text-decoration:none;}
.blog-entry-body h2 a:hover{text-decoration:underline;}
.blog-entry-body .post-meta{
  margin:0 0 var(--space-3);
  color:var(--text-faint);
  font-size:var(--font-size-caption);
}
.blog-entry-desc{
  margin:0;
  color:var(--text-secondary);
  font-size:var(--font-size-body-sm);
}
.blog-tags{
  list-style:none;
  margin:var(--space-4) 0 0;
  padding:0;
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-2);
}
.blog-tag{
  padding:2px var(--space-3);
  border:1px solid var(--border-default);
  border-radius:999px;
  color:var(--text-faint);
  font-size:var(--font-size-caption);
}

/* Lune atténuée comme À propos (demande Pauline) : la galerie porte déjà
   son propre contraste par carte, la lune reste une ambiance, pas le seul
   repère. */
.page-blog .moon-fixed .moon{opacity:.4;}
.page-blog .page-scrim{opacity:.55;}

/* ============================================================================
   Article de blog (.post) — voir
   docs/superpowers/specs/2026-09-17-blog-article-template-design.md
   ============================================================================ */
.post{
  max-width:50rem;
  margin-inline:auto;
  padding-block:clamp(var(--space-10), 6vw, var(--space-16));
}
.post-back{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:57px;
  height:57px;
  color:var(--accent);
  border-radius:50%;
  margin-bottom:var(--space-6);
}
.post-back:hover{color:var(--accent-hover);}
.post-back svg{width:36px;height:36px;}

.post h1{
  font-family:var(--font-display);
  font-weight:600;
  font-size:clamp(1.8rem, 4.6vw, 2.5rem);
  line-height:var(--leading-tight);
  letter-spacing:var(--tracking-display);
  margin:0 0 var(--space-3);
}

.post .post-meta{
  margin:0 0 var(--space-6);
  color:var(--text-secondary);
}

.post-toc{
  border:1px solid var(--border-default);
  border-radius:var(--radius-lg);
  padding:var(--space-6);
  margin-block:var(--space-8);
}
/* Spécificité forcée par "main#main" pour passer devant la règle globale
   "main#main h2" (même principe que main#main .entry-text h2 plus haut). */
main#main .post-toc h2{margin-bottom:var(--space-3);}
.post-toc ul{margin:0;padding-left:var(--space-6);}
.post-toc li{margin-bottom:var(--space-2);}
.post-toc a{color:var(--link);}
.post-toc a:hover{color:var(--link-hover);}

.post blockquote{
  border-left:3px solid var(--border-default);
  padding:var(--space-2) 0 var(--space-2) var(--space-6);
  margin:var(--space-8) 0;
  color:var(--text-secondary);
}
.post blockquote p:last-child{margin-bottom:0;}

.post pre{
  border:1px solid var(--border-default);
  border-radius:var(--radius-md);
  padding:var(--space-6);
  margin:var(--space-8) 0;
  overflow-x:auto;
}
.post code{
  background:var(--surface-card);
  border-radius:var(--radius-sm);
  padding:0.15em 0.4em;
}
.post pre code{background:none;padding:0;}
/* Retour à la ligne dans les blocs de code : pas de défilement horizontal (WCAG 1.4.10). */
.post pre, .post pre code{white-space:pre-wrap;overflow-wrap:anywhere;}

.post hr{
  border:none;
  border-top:1px solid var(--border-default);
  margin:var(--space-10) 0;
}

.post .callout{
  border-left:3px solid var(--accent);
  background:var(--surface-card);
  border-radius:var(--radius-md);
  padding:var(--space-6);
  margin-block:var(--space-8);
}
.post .callout-label{
  font-family:var(--font-display);
  font-weight:600;
  color:var(--accent);
  margin:0 0 var(--space-2);
}
.post .callout p:last-child{margin-bottom:0;}

.post figure{
  margin:var(--space-8) 0;
  border:1px solid var(--border-default);
  border-radius:var(--radius-lg);
  padding:var(--space-6);
  background:var(--surface-card);
}
.post figure img{width:100%;border-radius:var(--radius-md);display:block;}
.post figure video{width:100%;height:auto;border-radius:var(--radius-md);display:block;background:var(--surface-card);}
.post figcaption{
  font-size:var(--font-size-caption);
  color:var(--text-muted);
  margin-top:var(--space-3);
  text-align:center;
}

.post-resources{
  border-top:1px solid var(--border-default);
  padding-top:var(--space-8);
  margin-top:var(--space-10);
}
.post-resources ul{margin:0;padding-left:var(--space-6);}
.post-resources li{margin-bottom:var(--space-2);color:var(--text-secondary);}
.post-resources a{color:var(--link);}
.post-resources a:hover{color:var(--link-hover);}
/* Ressource sans URL : même poids visuel que le titre lié, sans le
   soulignement/couleur de lien puisqu'il n'y a rien à cliquer. */
.post-resources .resource-title{color:var(--text-body);}

.post-cta{
  margin-top:var(--space-10);
  text-align:center;
}

/* ============================================================================
   Page Contact — voir src/pages/contact.html
   ============================================================================ */

/* Lune atténuée, même logique que À propos/Le Lab/Blog : la carte
   ci-dessous fait déjà office de repère fort. */
.page-contact .moon-fixed .moon{opacity:.4;}
.page-contact .page-scrim{opacity:.55;}

/* Les deux CTA (Suivre / Écrire) partagent une seule carte .mp-card standard
   (fond translucide qui se renforce au scroll, comme .blog-teaser sur
   l'accueil) : une colonne par CTA, séparées par un filet plutôt qu'un
   espace seul (même besoin de démarcation nette que .engagements-grid).
   Le fond sauge fixe de .mp-card--lab a été essayé en premier (repère fort,
   cohérent avec Le Lab) mais jugé trop clair par Pauline (2026-09-18) — la
   carte neutre convient mieux ici.
   Grille (pas flex) pour que le passage 1 → 2 colonnes se déclenche
   exactement au même seuil que le filet (même mécanique et même seuil,
   720px, que .apropos-row/.cols) plutôt que de dépendre du flex-basis, qui
   peut empiler les colonnes tout en gardant le filet vertical, à cheval
   entre les deux mises en page. */
.contact-cta{
  display:grid;
  gap:var(--space-10);
}
@media (min-width:720px){
  .contact-cta{grid-template-columns:1fr 1fr;}
}
/* --border-default (14% d'opacité) est calibré pour trancher sur un fond
   plein (--surface-page/-card à pleine opacité) : sur .mp-card, le fond n'est
   translucide qu'en proportion de --card-fade (0 → 1 selon la proximité au
   centre de l'écran, voir assets/js/moon.js), qui n'est pas forcément élevé
   ici puisque la carte est en haut de page. Résultat : filet quasi invisible
   en usage réel (retour Pauline du 2026-09-18, invisible en fenêtre privée,
   même si visible dans un aperçu où le fondu était déjà monté). --text-faint
   est opaque et assez sombre pour rester discret : contraste garanti quel
   que soit l'état du fondu. */
.contact-cta-col + .contact-cta-col{
  border-top:1px solid var(--text-faint);
  padding-top:var(--space-10);
}
@media (min-width:720px){
  .contact-cta-col + .contact-cta-col{
    border-top:none;
    padding-top:0;
    border-left:1px solid var(--text-faint);
    padding-left:var(--space-10);
  }
}
.contact-cta-col h2{
  /* Séparation nette titre/texte du CTA (demande Pauline), même filet que
     .engagements h2, recalé sur --text-faint pour la même raison que
     ci-dessus. */
  padding-bottom:var(--space-5);
  margin-bottom:var(--space-5);
  border-bottom:1px solid var(--text-faint);
}

/* Flux RSS : carte pleine largeur sous .contact-cta, même style (.mp-card
   standard), pour offrir une façon de suivre le travail sans répéter les
   icônes déjà dans le pied de page (retour Pauline du 2026-09-18). */
.contact-rss h2{margin-bottom:var(--space-3);}
.contact-rss p{max-width:42rem;color:var(--text-secondary);}
.contact-rss .button-row{margin-top:var(--space-6);}

/* ============================================================================
   Bandeau de repli FR (pages EN non traduites) — voir
   scripts/lib/template.mjs (renderTranslationBanner), branché depuis
   build-site.mjs (Tools/Réalisations) et build-blog.mjs (articles sans
   équivalent EN). Même langage visuel que .post .callout (filet à gauche +
   carte pleine, pas de fondu au scroll : ce bandeau doit rester lisible dès
   l'arrivée sur la page, pas seulement une fois centré à l'écran). -->
.translation-notice{
  border-left:3px solid var(--accent);
  background:var(--surface-card);
  border-radius:var(--radius-md);
  padding:var(--space-6);
  margin-bottom:var(--space-8);
}
.translation-notice p{
  margin:0 0 var(--space-4);
  color:var(--text-secondary);
}
.translation-notice p:last-of-type{margin-bottom:0;}
.translation-notice .button{margin-top:var(--space-4);}

/* ============================================================================
   Agrandissement d'image au clic — assets/js/lightbox.js. Scope volontaire :
   mockups d'outils/projets, photos À propos, images d'article de blog (voir
   le commentaire en tête du script pour ce qui est exclu et pourquoi). */
.lightbox-trigger{cursor:zoom-in;}
/* <dialog> natif : centré par le navigateur (position par défaut de
   l'algorithme "top layer"), ::backdrop pour l'assombrissement — pas de
   JS pour ça. */
.lightbox-dialog{
  border:none;
  border-radius:var(--radius-md);
  background:var(--surface-card);
  padding:var(--space-8);
  max-width:min(90vw, 60rem);
  max-height:90vh;
}
.lightbox-dialog::backdrop{background:rgb(3 5 4 / .85);}
.lightbox-img{
  display:block;
  max-width:100%;
  max-height:calc(90vh - var(--space-8) * 2);
  width:auto;
  height:auto;
  object-fit:contain;
  border-radius:var(--radius-sm);
}
.lightbox-close{
  position:absolute;
  top:var(--space-3);
  right:var(--space-3);
  width:44px;
  height:44px;
  border:1px solid var(--border-default);
  border-radius:50%;
  background:var(--surface-page);
  color:var(--text-body);
  font-size:1.5rem;
  line-height:1;
  cursor:pointer;
}
.lightbox-close:hover{border-color:var(--accent);color:var(--accent);}
