/* ╔══════════════════════════════════════════════════════════════════╗
   ║  ĐINH NHO — Design System                                       ║
   ║  Single source of truth. Replaces main.css fragments.           ║
   ╚══════════════════════════════════════════════════════════════════╝ */

/* ── 1. PRIMITIVES ──────────────────────────────────────────────── */
:root {
  /* Couleurs — primitives */
  --c-laque:        #9a2b21;
  --c-laque-deep:   #6f1e16;
  --c-laque-light:  #c4392d;
  --c-or:           #a9803a;
  --c-or-soft:      #c6a567;
  --c-or-pale:      #e8d5a3;
  --c-jade:         #2e6f5e;
  --c-jade-soft:    #4a9a85;
  --c-ivoire:       #f3ead7;
  --c-ivoire-2:     #ece0c6;
  --c-ivoire-3:     #f8f1e2;
  --c-encre:        #241f19;
  --c-encre-2:      #1b1612;
  --c-encre-3:      #2d2620;
  --c-sepia:        #5d5346;
  --c-sepia-soft:   #6d6154;
  --c-ligne:        #d8c6a2;
  --c-ligne-soft:   #e8dcc8;

  /* Typographie */
  --f-serif:  "Be Vietnam Pro", Georgia, "Times New Roman", serif;
  --f-sans:   "Be Vietnam Pro", system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-han:    "Noto Serif TC", "Songti SC", STSong, serif;

  /* Espacement — échelle 4px */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 20px;  --sp-6: 24px;  --sp-8: 32px;  --sp-10: 40px;
  --sp-12: 48px; --sp-16: 64px; --sp-20: 80px; --sp-24: 96px;

  /* Radii */
  --r-sm: 4px;  --r-md: 8px;  --r-lg: 12px;  --r-xl: 16px;

  /* Ombres */
  --shadow-sm:  0 1px 4px rgba(36,31,25,.10);
  --shadow-md:  0 4px 16px rgba(36,31,25,.14);
  --shadow-lg:  0 12px 40px -8px rgba(36,31,25,.28);
  --shadow-xl:  0 20px 60px -12px rgba(36,31,25,.40);

  /* Layout */
  --maxw: 1180px;
  --maxw-prose: 72ch;

  /* Transitions */
  --ease: cubic-bezier(.22,.7,.2,1);
  --ease-in: cubic-bezier(.4,0,1,1);
  --ease-out: cubic-bezier(0,0,.2,1);

  /* ── Tokens sémantiques ── */
  --bg:          var(--c-ivoire);
  --bg-2:        var(--c-ivoire-2);
  --bg-surface:  var(--c-ivoire-3);
  --fg:          var(--c-encre);
  --fg-soft:     var(--c-sepia);
  --fg-muted:    var(--c-sepia-soft);
  --accent:      var(--c-laque);
  --accent-deep: var(--c-laque-deep);
  --gold:        var(--c-or);
  --gold-soft:   var(--c-or-soft);
  --border:      var(--c-ligne);
  --border-soft: var(--c-ligne-soft);
}

/* ── 2. RESET & BASE ────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: auto; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--f-sans);
  font-weight: 400;
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* Paper grain */
.grain {
  position: fixed; inset: 0; pointer-events: none; z-index: 60;
  opacity: .042; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

::selection { background: var(--accent); color: #fff; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
h1, h2, h3, h4 { font-family: var(--f-sans); font-weight: 600; line-height: 1.08; margin: 0; }

/* Titres éditoriaux (sections histoire, citations) restent en serif */
.hist-book h2, .hist-book h3,
.her-h2, .her-quote, blockquote,
.lede { font-family: var(--f-serif); }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: var(--r-sm); }

/* ── 3. LAYOUT ──────────────────────────────────────────────────── */
.container {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--sp-8);
}
@media (max-width: 480px) { .container { padding: 0 var(--sp-5); } }

section.block { padding: var(--sp-24) 0; }
@media (max-width: 680px) { section.block { padding: var(--sp-16) 0; } }

/* Views (SPA) */
.view { display: none; }
.view.active { display: block; }

/* ── FIL D'ARIANE ────────────────────────────────────────────────────
   Discret par nature : il sert quand on est perdu, il ne doit pas
   disputer la vedette au titre de la page. Vide sur l'accueil, il ne
   prend alors aucune place (:empty) — sans quoi chaque page gagnerait
   un blanc pour rien. */
.fil-ariane { max-width: var(--maxw); margin: 0 auto; padding: var(--sp-5) var(--sp-8) 0; }
.fil-ariane:empty { display: none; }
@media (max-width: 480px) { .fil-ariane { padding: var(--sp-4) var(--sp-5) 0; } }

.fil-ariane ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--sp-2);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--c-sepia, #5d5346);
}
.fil-ariane li { display: flex; align-items: baseline; gap: var(--sp-2); }
/* Le chevron est décoratif : posé en CSS, il reste hors du texte lu à
   voix haute par les lecteurs d'écran. */
.fil-ariane li + li::before { content: "›"; color: var(--c-ligne, #d8c6a2); }

.fil-ariane a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.fil-ariane a:hover,
.fil-ariane a:focus-visible { color: var(--c-laque, #9a2b21); border-bottom-color: currentColor; }

/* La page où l'on se trouve : dite, mais pas cliquable. Tronquée si le
   titre est long, pour que le fil tienne sur une ligne au téléphone. */
.fil-ariane [aria-current="page"] {
  color: var(--c-encre, #241f19);
  font-weight: 500;
  max-width: min(48ch, 100%);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* À l'impression, le fil n'apporte rien : le papier n'a pas de liens.
   La règle est posée dans le bloc @media print commun (plus bas), avec le
   bouton d'impression et la barre de chapitres — un second bloc @media print
   placé avant lui masquerait le premier aux yeux des tests. */

/* ── 4. ANIMATIONS ──────────────────────────────────────────────── */
@keyframes dn-up {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: none; }
}
@keyframes dn-fade {
  from { opacity: 0; } to { opacity: 1; }
}
@keyframes dn-scroll-han {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@keyframes dn-pulse-or {
  0%, 100% { opacity: .18; }
  50%       { opacity: .32; }
}

.view.active .reveal {
  animation: dn-up .72s var(--ease) both;
  animation-delay: var(--d, 0s);
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ── 5. TYPOGRAPHIE ─────────────────────────────────────────────── */
.eyebrow {
  display: inline-flex; align-items: center; gap: var(--sp-3);
  font-size: 11px; letter-spacing: .34em; text-transform: uppercase;
  font-weight: 600; color: var(--accent); margin-bottom: var(--sp-5);
}
.eyebrow::before {
  content: ""; width: 28px; height: 1.5px;
  background: var(--gold); display: block; flex-shrink: 0;
}

.sec-title {
  font-size: clamp(2rem, 4.2vw, 3rem);
  letter-spacing: .005em; margin-bottom: var(--sp-5); max-width: 18ch;
}
.lead {
  font-size: 18px; color: var(--fg-soft);
  max-width: var(--maxw-prose); line-height: 1.72;
}

/* Divider */
.divider {
  display: flex; align-items: center; gap: var(--sp-5);
  margin: var(--sp-16) 0; color: var(--gold);
}
.divider::before, .divider::after {
  content: ""; height: 1px; background: var(--border); flex: 1;
}
.divider i {
  width: 7px; height: 7px; border: 1.5px solid var(--gold);
  transform: rotate(45deg); display: block;
}

/* ── 6. HEADER ──────────────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(243,234,215,.88);
  backdrop-filter: blur(14px) saturate(1.5);
  -webkit-backdrop-filter: blur(14px) saturate(1.5);
  border-bottom: 1px solid var(--border);
  transition: box-shadow .3s var(--ease);
}

.hbar {
  padding: 0 var(--sp-8);
  display: flex; flex-direction: column;
}

/* Ligne 1 : brand à gauche, lang+burger à droite */
.hbar-top {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 10px 0 4px;
}
.hbar-top .brand { flex: 1; }

/* LA BARRE D'EN-TÊTE NE TIENT PAS SUR UN PETIT TÉLÉPHONE — mesuré le 08/09/2026
 * dans un navigateur, sur les 78 pages du site, à 360 px de large : le document
 * pouvait défiler de 23 px vers la droite. TOUTES les pages, dans les trois
 * langues. C'est ce qui donne, sur un téléphone, cette impression que la page
 * « glisse » quand on la fait défiler du pouce.
 *
 * L'ADDITION, POSTE PAR POSTE, telle que le navigateur l'a rendue :
 *
 *     marge intérieure   32 px
 *     brand (sceau+nom)  95 px   (déjà à son minimum de contenu)
 *     écart              16 px
 *     bouton loupe       29 px
 *     écart              16 px
 *     sélecteur de langue 127 px  (trois boutons de 40 px : min-width imposé
 *                                  par la règle de cible tactile 44×44)
 *     écart + marge      24 px
 *     bouton du menu     44 px   (même règle de cible tactile)
 *     ────────────────────────
 *     minimum            383 px
 *
 * Un écran de 360 px en manque donc 23, un écran de 375 px en manque 8, et le
 * débordement disparaît à 390 px — d'où le fait que personne ne l'ait vu : les
 * grands téléphones vont bien.
 *
 * CE QU'ON NE TOUCHE PAS, et c'est un choix : ni les 44 px des cibles tactiles
 * (règle d'accessibilité posée plus bas dans ce fichier, et un bouton de langue
 * trop petit se rate), ni le nom de la famille dans l'en-tête, qu'on ne va pas
 * tronquer. On récupère donc les pixels sur les ESPACES, qui n'appartiennent à
 * personne : marge intérieure 32 → 14, écarts 16 → 8, et la marge propre du
 * bouton du menu remise à zéro (l'écart de la rangée suffit).
 *
 * Nouveau minimum : 14 + 95 + 8 + 29 + 8 + 127 + 8 + 44 = 333 px. Les écrans de
 * 340 px et plus tiennent. IL RESTE LE CAS DES 320 px (iPhone SE de première
 * génération, très vieux Android) : 13 px de trop. Les combler demanderait de
 * rogner une cible tactile, de tronquer le nom du clan ou de déplacer le
 * sélecteur de langue dans le menu — trois arbitrages qui appartiennent à la
 * famille, pas à une correction technique. */
@media (max-width: 520px) {
  .hbar { padding: 0 14px; }
  .hbar-top { gap: 8px; }
  .hbar-top .menu-toggle { margin-left: 0; }
}

/* Ligne 2 : nav complète, alignée à gauche, scrollable sans coupure */
.hbar-nav {
  display: flex; align-items: center; overflow: visible;   /* visible : ne rogne pas les menus déroulants */
  padding-bottom: 2px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.hbar-nav::-webkit-scrollbar { display: none; }

/* Brand */
.brand {
  display: flex; align-items: center; gap: var(--sp-4);
  cursor: pointer; text-decoration: none; flex-shrink: 0;
}
.seal {
  width: 40px; height: 40px; border-radius: 7px; flex-shrink: 0;
  background: linear-gradient(150deg, var(--c-laque), var(--c-laque-deep));
  color: var(--c-ivoire-3); display: grid; place-items: center;
  font-family: var(--f-han); font-weight: 700; font-size: 22px;
  box-shadow:
    inset 0 0 0 1px rgba(248,241,226,.28),
    inset 0 0 0 3.5px rgba(248,241,226,.06),
    0 2px 8px rgba(111,30,22,.35);
}
.brand-txt { display: flex; flex-direction: column; line-height: 1.1; }
.brand-name { font-family: var(--f-serif); font-weight: 600; font-size: 20px; letter-spacing: .02em; }
.brand-sub {
  font-size: 10px; letter-spacing: .32em; text-transform: uppercase;
  color: var(--gold); font-weight: 600;
}

/* Nav — 2e ligne du header, alignée à gauche */
.site-nav { display: flex; align-items: center; gap: 0; flex-wrap: nowrap; }
.site-nav a {
  position: relative; font-size: 12.5px; font-weight: 500;
  color: var(--fg-soft); padding: 7px 10px; border-radius: var(--r-md);
  white-space: nowrap; letter-spacing: .01em;
  transition: color .18s var(--ease), background .18s var(--ease);
}
.site-nav a::after {
  content: ""; position: absolute; left: 12px; right: 12px;
  bottom: 3px; height: 1.5px;
  background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .26s var(--ease);
}
.site-nav a:hover { color: var(--fg); background: rgba(169,128,58,.07); }
.site-nav a:hover::after { transform: scaleX(1); }
.site-nav a.active { color: var(--accent); }
.site-nav a.active::after { transform: scaleX(1); }

/* Ancres des barres de chapitres générées (main.js ensureChapterBar) :
   l'arrivée du défilement ne se cache pas sous l'en-tête + la barre collante. */
.hb-anchor { scroll-margin-top: 148px; }

/* ── Barre de chapitres collante (main.js ensureChapterBar) ──
   Chrome GLOBAL : la barre est générée sur plusieurs vues (histoire, jeunes,
   héritage-spirituel et TOUS les recueils tieu/dinh-nhat-than/…). Ces styles
   doivent donc vivre dans la feuille globale ; laissés dans histoire.css (asset
   chargé pour la seule vue « histoire »), la barre s'affichait en texte brut
   non stylé partout ailleurs. Le décalage sous l'en-tête collant vient de la
   variable --hdr (posée par main.js), avec un repli raisonnable sans JS. */
.hb-sticky{
  /* Pas de débord latéral : la marge négative de -4px rendait la barre plus
     large que son conteneur et, sur un téléphone de 390 px, faisait défiler
     TOUTE la page de quatre pixels vers la droite. Le rail intérieur
     (.hbs-in) défile déjà horizontalement — le débord n'apportait qu'un effet
     de bord perdu. */
  position:sticky; top:var(--hdr,96px); z-index:40;
  margin:0 0 18px; padding:6px 4px; max-width:100%;
  background:rgba(243,234,215,.94);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  border-bottom:1px solid rgba(169,128,58,.28);
}
.hb-sticky .hbs-in{
  display:flex; gap:4px; overflow-x:auto; scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.hb-sticky .hbs-in::-webkit-scrollbar{ display:none; }
.hb-sticky a{
  flex:0 0 auto; display:inline-flex; align-items:center; gap:5px;
  padding:5px 10px; border-radius:999px; cursor:pointer;
  font-size:.78rem; line-height:1.1; white-space:nowrap;
  color:#5d5346; text-decoration:none; border:1px solid transparent;
}
.hb-sticky a .num{
  font-family:"Be Vietnam Pro",Georgia,serif; font-weight:700;
  color:#a9803a; font-size:.85rem;
}
.hb-sticky a:hover{ background:rgba(169,128,58,.12); }
.hb-sticky a.cur{
  background:rgba(154,43,33,.08); border-color:rgba(154,43,33,.3); color:#9a2b21;
}
.hb-sticky a.cur .num{ color:#9a2b21; }
@media print{ .hb-sticky{ display:none !important; } }

/* Bouton Admin (fin de menu) : pilule discrète, lien serveur hors SPA */
.site-nav a.nav-admin {
  margin-left: 10px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-weight: 600;
}
.site-nav a.nav-admin::after { display: none; }
.site-nav a.nav-admin:hover { border-color: var(--accent); color: var(--accent); }
@media (max-width: 860px) {
  /* En mobile la nav devient une liste verticale défilable : le bouton Admin
     est ÉPINGLÉ en bas du panneau (sticky) pour rester toujours visible,
     même quand la liste des rubriques dépasse la hauteur de l'écran. */
  .site-nav a.nav-admin {
    margin: 8px 0 0;
    border-radius: var(--r-md);
    position: sticky;
    bottom: 0;
    justify-content: center;
    background: rgba(243, 234, 215, .97);
    border: 1px solid var(--border);
    box-shadow: 0 -6px 12px -8px rgba(40, 25, 15, .35);
  }
}

/* ── Menus déroulants (groupes) ── */
.nav-group { position: relative; display: flex; align-items: center; }
.nav-trigger {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: inherit; font-size: 12.5px; font-weight: 500;
  color: var(--fg-soft); background: transparent; border: 0; cursor: pointer;
  padding: 7px 10px; border-radius: var(--r-md); white-space: nowrap; letter-spacing: .01em;
  transition: color .18s var(--ease), background .18s var(--ease);
}
.nav-trigger:hover, .nav-group:hover .nav-trigger { color: var(--fg); background: rgba(169,128,58,.07); }
.nav-trigger.active-parent { color: var(--accent); }
.nav-caret { font-size: .7em; line-height: 1; transition: transform .2s var(--ease); }
.nav-group:hover .nav-caret, .nav-group.open .nav-caret { transform: rotate(180deg); }
.nav-panel {
  position: absolute; top: 100%; left: 0; min-width: 210px; z-index: 60;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--c-surface, #fff); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: var(--shadow-lg); padding: 6px;
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility .18s var(--ease);
}
.nav-panel::before { content: ""; position: absolute; left: 0; right: 0; top: -8px; height: 8px; }
.nav-group:hover .nav-panel, .nav-group:focus-within .nav-panel, .nav-group.open .nav-panel {
  opacity: 1; visibility: visible; transform: none;
}
.nav-panel a {
  display: block; padding: 8px 12px; border-radius: 8px; white-space: nowrap;
  font-size: 13px; font-weight: 500; color: var(--fg-soft);
}
.nav-panel a::after { display: none; }
.nav-panel a:hover { background: rgba(169,128,58,.1); color: var(--fg); }
.nav-panel a.active { color: var(--accent); background: rgba(154,43,33,.06); }

/* Lang switch */
.lang {
  display: flex; align-items: center; flex-shrink: 0;
  border: 1px solid var(--border); border-radius: 20px; overflow: hidden;
}
.lang button {
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--f-sans); font-weight: 600; font-size: 11.5px;
  letter-spacing: .08em; color: var(--fg-soft);
  padding: 6px 11px; transition: background .18s, color .18s;
}
.lang button.on { background: var(--fg); color: var(--c-ivoire-3); }

/* Burger */
.menu-toggle {
  display: none; margin-left: var(--sp-2); flex-shrink: 0;
  width: 40px; height: 36px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: transparent; cursor: pointer;
  align-items: center; justify-content: center;
}
.menu-toggle span, .menu-toggle span::before, .menu-toggle span::after {
  content: ""; display: block; width: 17px; height: 1.6px;
  background: var(--fg); position: relative; transition: .22s var(--ease);
}
.menu-toggle span::before { position: absolute; top: -5.5px; }
.menu-toggle span::after  { position: absolute; top:  5.5px; }
.menu-toggle.open span { background: transparent; }
.menu-toggle.open span::before { top: 0; transform: rotate(45deg); }
.menu-toggle.open span::after  { top: 0; transform: rotate(-45deg); }

/* ── 7. HERO ────────────────────────────────────────────────────── */
.hero {
  position: relative;
  background: var(--c-encre-2);
  color: var(--c-ivoire-3);
  overflow: hidden;
  padding: var(--sp-24) 0 var(--sp-20);
}

/* Han scroll en filigrane */
.hero-han-scroll {
  position: absolute;
  top: 50%; left: 0;
  transform: translateY(-50%);
  white-space: nowrap;
  font-family: var(--f-han);
  font-weight: 700;
  font-size: clamp(6rem, 18vw, 14rem);
  color: transparent;
  -webkit-text-stroke: 1px rgba(169,128,58,.12);
  pointer-events: none; user-select: none;
  animation: dn-scroll-han 120s linear infinite;
  will-change: transform;
  letter-spacing: .06em;
  line-height: 1;
  /* Double content pour boucle fluide via JS */
}

/* Lueur ambiante */
.hero::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 60% 50% at 15% 50%, rgba(154,43,33,.18), transparent),
    radial-gradient(ellipse 50% 40% at 85% 20%, rgba(169,128,58,.10), transparent);
  pointer-events: none;
}

.hero .container { position: relative; z-index: 2; }

.hero-inner {
  display: block;
  max-width: 720px;
}

/* Sceau central dans la colonne droite */

/* Contenu textuel */
.hero-eyebrow { color: var(--c-or-soft); }
.hero-eyebrow::before { background: var(--c-or-soft); }

.hero h1 {
  font-size: clamp(3rem, 8vw, 6rem);
  font-weight: 600; letter-spacing: .01em;
  color: #fff; margin: var(--sp-2) 0 var(--sp-2);
  line-height: 1.0;
}
.hero .sub {
  font-family: var(--f-serif); font-style: italic; font-weight: 500;
  font-size: clamp(1.2rem, 2.6vw, 1.7rem);
  color: var(--c-or-pale); margin: 0 0 var(--sp-6);
}
.hero .intro {
  font-size: 17px; color: rgba(248,241,226,.72);
  max-width: 56ch; line-height: 1.75; margin: 0 0 var(--sp-8);
}
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--sp-4); }

/* Devise */
.hero-devise-wrap {
  border-top: 1px solid rgba(169,128,58,.18);
  padding: var(--sp-5) 0 0;
  margin-top: var(--sp-8);
}
.hero-devise {
  font-family: var(--f-serif); font-style: italic;
  font-size: clamp(.75rem, 1.5vw, 1.1rem);
  color: rgba(248,241,226,.42);
  letter-spacing: .22em; text-align: center; margin: 0;
  text-transform: uppercase;
}

/* Stats bar — maintenant sous le hero sur fond ivoire */
.stats-bar {
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
}
.stats {
  display: grid; grid-template-columns: repeat(4,1fr);
  max-width: var(--maxw); margin: 0 auto;
}
.stat {
  padding: var(--sp-6) var(--sp-6);
  border-right: 1px solid var(--border);
}
.stat:last-child { border-right: 0; }
.stat .v {
  font-family: var(--f-serif); font-weight: 600;
  font-size: 2.1rem; color: var(--fg); line-height: 1;
}
.stat .l {
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--fg-muted); margin-top: var(--sp-2); font-weight: 500;
}

/* Hommage Đinh Nho Tiêu */
.hero-hommage {
  background: var(--bg); border-top: 1px solid var(--border);
  padding: var(--sp-6) var(--sp-8);
  text-align: center;
}
.hero-hommage p {
  font-family: var(--f-serif); font-style: italic;
  font-size: 1.05rem; color: var(--fg-soft);
  max-width: 680px; margin: 0 auto; line-height: 1.78;
}

/* Esprit du site : colophon en bas de la page d'accueil. */
.home-charte {
  border-top: 1px solid var(--border);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  text-align: center;
}
.home-charte p {
  font-family: var(--f-serif);
  font-size: .96rem; color: var(--fg-soft);
  max-width: 720px; margin: 0 auto; line-height: 1.85;
}
.home-charte strong { color: var(--accent); font-weight: 600; }
.home-charte em { font-style: italic; color: var(--fg); }

/* ── 8. BOUTONS ─────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: var(--sp-3);
  font-family: var(--f-sans); font-weight: 600;
  font-size: 14px; letter-spacing: .02em;
  padding: 12px var(--sp-6); border-radius: var(--r-md);
  border: 1px solid transparent; cursor: pointer;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease),
              background .18s, color .18s;
  text-decoration: none;
}
.btn:active { transform: translateY(1px); }
.btn .arr { transition: transform .18s var(--ease); }
.btn:hover .arr { transform: translateX(3px); }

.btn-primary {
  background: var(--accent); color: var(--c-ivoire-3);
  box-shadow: inset 0 0 0 1px rgba(248,241,226,.15), var(--shadow-sm);
}
.btn-primary:hover {
  background: var(--accent-deep);
  box-shadow: inset 0 0 0 1px rgba(248,241,226,.15), var(--shadow-md);
}

.btn-ghost {
  background: transparent; color: var(--fg);
  border-color: rgba(169,128,58,.55);
}
.btn-ghost:hover { background: rgba(169,128,58,.09); }

/* btn-ghost dans le hero (fond sombre) */
.hero .btn-ghost {
  color: var(--c-ivoire-3);
  border-color: rgba(198,165,103,.60);
  background: rgba(248,241,226,.06);
}
.hero .btn-ghost:hover {
  background: rgba(198,165,103,.18);
  border-color: rgba(198,165,103,.9);
}

.btn-gold {
  background: var(--gold); color: var(--c-encre);
  box-shadow: var(--shadow-sm);
}
.btn-gold:hover { background: var(--gold-soft); box-shadow: var(--shadow-md); }

/* ── 9. SECTION HISTOIRE ────────────────────────────────────────── */
/* (hist-book conservé dans histoire.css — pas de conflit) */
/* Overrides spécifiques pour la carte */

/* ── 10. SECTION FIGURES ────────────────────────────────────────── */
.fig-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(300px,100%), 1fr));
  gap: var(--sp-6); margin-top: var(--sp-5);
}
.fig {
  position: relative; background: var(--bg-surface);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  overflow: hidden; transition: transform .24s var(--ease), box-shadow .24s var(--ease);
  display: flex; flex-direction: column;
}
/* Barre accent top */
.fig::before {
  content: ""; position: absolute; left: 0; top: 0;
  height: 3px; width: 48px;
  background: linear-gradient(90deg, var(--accent), var(--c-or));
  transition: width .32s var(--ease);
  pointer-events: none;   /* décoratif : ne doit pas capturer les clics */
}
.fig:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.fig:hover::before { width: 100%; }

/* Shimmer or au hover.
   pointer-events:none INDISPENSABLE : ce calque couvre toute la carte
   (inset:0) et, sans cela, intercepte les clics sur les liens des fiches
   (contenus liés « presse » et « voir dans l'arbre »). */
.fig::after {
  content: ""; position: absolute;
  inset: 0; border-radius: var(--r-lg);
  background: linear-gradient(135deg, transparent 40%, rgba(169,128,58,.05) 100%);
  opacity: 0; transition: opacity .32s;
  pointer-events: none;
}
.fig:hover::after { opacity: 1; }

.fig .era {
  position: absolute; top: var(--sp-5); right: var(--sp-5);
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 600; color: var(--gold);
  border: 1px solid var(--border); border-radius: 20px;
  padding: 3px 10px;
}
.fig .nm {
  font-family: var(--f-serif); font-weight: 600;
  font-size: 1.65rem; color: var(--fg); line-height: 1.1;
  margin: var(--sp-2) 0 var(--sp-1); padding-right: 56px;
}
.fig .dt { font-size: 12.5px; color: var(--fg-muted); letter-spacing: .04em; margin-bottom: var(--sp-3); }
.fig .ro {
  font-family: var(--f-serif); font-style: italic;
  font-size: 1.05rem; color: var(--accent-deep); margin-bottom: var(--sp-3);
}
.fig .bio {
  font-size: 14px; color: var(--fg-soft); line-height: 1.62; margin: 0; flex: 1;
}
/* Contenus liés : liens de presse « voir aussi » (auto-appariés par nom) */
.fig-related {
  margin-top: var(--sp-4); padding-top: var(--sp-3);
  border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 4px;
}
.fig-related-t {
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 600; color: var(--gold); margin-bottom: 2px;
}
.fig-related-row { display: flex; align-items: baseline; gap: var(--sp-3); }
.fig-related-row > a:first-child { flex: 1; min-width: 0; }
.fig-related a {
  font-size: 13px; color: var(--accent-deep); text-decoration: none; line-height: 1.4;
}
.fig-related a:hover { text-decoration: underline; }
.fig-related-tr {
  flex: none; align-self: center; font-size: 11px; font-weight: 600;
  color: var(--fg-soft) !important; white-space: nowrap;
}
.fig-related-tr:hover { color: var(--accent) !important; }

/* ── 11. GÉNÉALOGIE ─────────────────────────────────────────────── */
.gen-panel {
  display: grid; grid-template-columns: 1.1fr .9fr;
  border-radius: var(--r-xl); overflow: hidden;
  background: linear-gradient(150deg, var(--c-encre-2), var(--c-encre-3));
  box-shadow: var(--shadow-xl),
              inset 0 0 0 1px rgba(198,165,103,.18);
  margin-top: var(--sp-5);
}
.gen-left { padding: var(--sp-12) var(--sp-12); color: var(--c-ivoire-3); min-width: 0; }
.gen-left .eyebrow { color: var(--c-or-soft); }
.gen-left .eyebrow::before { background: var(--gold); }
.gen-left h3 { font-size: 1.9rem; color: var(--c-ivoire-3); margin-bottom: var(--sp-4); }
.gen-left p { color: #d9cdb8; max-width: 46ch; margin: 0 0 var(--sp-6); font-size: 15.5px; }
.gen-right {
  padding: var(--sp-12) var(--sp-10);
  background: rgba(248,241,226,.035);
  display: flex; flex-direction: column; justify-content: center;
  border-left: 1px solid rgba(198,165,103,.16);
}
.gen-right .pv-title {
  font-size: 10.5px; letter-spacing: .26em; text-transform: uppercase;
  color: var(--c-or-soft); font-weight: 600;
  margin-bottom: var(--sp-6); text-align: center;
}
.lineage { display: flex; flex-direction: column; align-items: center; gap: 0; }
.ln-node {
  background: rgba(248,241,226,.06);
  border: 1px solid rgba(198,165,103,.32); border-radius: var(--r-md);
  padding: 12px var(--sp-6); text-align: center; min-width: 190px;
}
.ln-node .n { font-family: var(--f-serif); font-weight: 600; font-size: 1.15rem; color: var(--c-ivoire-3); }
.ln-node .r { font-size: 11px; color: var(--c-or-soft); letter-spacing: .06em; margin-top: 2px; }
.ln-link { width: 2px; height: 24px; background: linear-gradient(var(--gold), rgba(198,165,103,.2)); }
.ln-split { display: flex; gap: var(--sp-5); }

/* ── 12. BIBLIOTHÈQUE ───────────────────────────────────────────── */
.doc {
  background: var(--bg-surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--sp-6);
  display: flex; gap: var(--sp-5);
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s;
}
.doc:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--c-or-soft); }
.doc .ic {
  flex: none; width: 44px; height: 52px; border-radius: var(--r-sm);
  background: var(--bg-2); border: 1px solid var(--border);
  position: relative; display: grid; place-items: center; color: var(--accent);
}
.doc .ic svg { width: 20px; height: 20px; }
.doc .ic::after {
  content: ""; position: absolute; top: 0; right: 0;
  border-width: 0 10px 10px 0; border-style: solid;
  border-color: var(--bg) var(--bg) transparent transparent;
}
.doc h3 { font-family: var(--f-serif); font-weight: 600; font-size: 1.22rem; color: var(--fg); line-height: 1.15; margin-bottom: var(--sp-2); }
.doc p  { font-size: 13px; color: var(--fg-soft); line-height: 1.55; margin: 0 0 var(--sp-3); }
.badges { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.badge {
  font-size: 10px; letter-spacing: .07em; text-transform: uppercase; font-weight: 600;
  padding: 2px 8px; border-radius: var(--r-sm);
  background: var(--bg-2); color: var(--fg-soft); border: 1px solid var(--border);
}
.badge.fr { background: rgba(154,43,33,.09); color: var(--accent); border-color: rgba(154,43,33,.22); }
.badge.vn { background: rgba(169,128,58,.12); color: var(--gold); border-color: rgba(169,128,58,.28); }
.doc .consult { font-size: 12.5px; font-weight: 600; color: var(--accent); display: inline-flex; align-items: center; gap: var(--sp-2); }
.doc .consult .arr { transition: transform .18s var(--ease); }
.doc:hover .consult .arr { transform: translateX(3px); }
.small-note { margin-top: var(--sp-8); font-size: 13px; color: var(--fg-muted); font-style: italic; }

/* ── 13. PRESSE & LIENS ─────────────────────────────────────────── */
.pg { margin-top: var(--sp-10); }
.pg-title {
  font-family: var(--f-serif); font-weight: 600; font-size: 1.4rem; color: var(--fg);
  display: flex; align-items: center; gap: var(--sp-5); margin-bottom: var(--sp-5);
}
.pg-title::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.link-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(320px,100%), 1fr));
  gap: var(--sp-4);
}
.lnk {
  display: flex; flex-direction: column; background: var(--bg-surface);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--sp-5) var(--sp-6); position: relative;
  transition: transform .2s var(--ease), box-shadow .2s, border-color .2s;
}
.lnk:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--c-or-soft); }
/* Lien principal : calque qui rend toute la carte cliquable. */
.lnk-main { display: block; color: inherit; text-decoration: none; }
.lnk-main::after { content: ""; position: absolute; inset: 0; border-radius: var(--r-lg); }
.lnk h4 { font-family: var(--f-serif); font-weight: 600; font-size: 1.14rem; color: var(--fg); line-height: 1.2; margin: 0 0 var(--sp-2); padding-right: var(--sp-6); }
.lnk p  { font-size: 13px; color: var(--fg-soft); line-height: 1.5; margin: 0 0 var(--sp-3); }
/* Pied de carte : domaine + bouton traduction, alignés et au-dessus du calque. */
.lnk-foot { position: relative; z-index: 1; margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
.lnk .dom { font-size: 11px; letter-spacing: .06em; color: var(--accent); font-weight: 600; }
.lnk-tr {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600; line-height: 1;
  color: var(--fg-soft); text-decoration: none;
  padding: 5px 9px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--bg); transition: color .18s, border-color .18s, background .18s;
}
.lnk-tr:hover { color: var(--accent); border-color: var(--c-or-soft); background: var(--bg-surface); }
.lnk .go { position: absolute; top: var(--sp-5); right: var(--sp-5); color: var(--gold); transition: transform .18s var(--ease); }
.lnk:hover .go { transform: translate(2px,-2px); }

/* ── 14. MÉDIAS ─────────────────────────────────────────────────── */
.video-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px,1fr));
  gap: var(--sp-8); margin-top: var(--sp-8);
}
.video-embed {
  position: relative; width: 100%; padding-bottom: 56.25%; height: 0;
  border-radius: var(--r-lg); overflow: hidden;
  border: 1px solid var(--border);
  background: #000; box-shadow: var(--shadow-md);
  transition: transform .22s var(--ease), box-shadow .22s;
}
.video-embed:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video-card { display: flex; flex-direction: column; margin: 0; }
.video-cap { margin-top: var(--sp-3); font-family: var(--f-serif); font-size: 1.02rem; line-height: 1.34; }
.video-cap a { color: var(--fg); transition: color .18s; }
.video-cap a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.video-group-title {
  grid-column: 1 / -1; font-family: var(--f-sans); font-size: 11px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--gold);
  padding: var(--sp-5) 0 var(--sp-2); border-top: 1px solid var(--border); margin-top: var(--sp-4);
}

/* YouTube / DailyMotion façades */
.yt-facade, .dm-facade {
  position: absolute; inset: 0; cursor: pointer; display: block; outline: none;
}
.yt-facade  { background: #000; }
.dm-facade  { background: #0a0a1a; }
.yt-thumb, .dm-thumb {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block; opacity: .9;
  transition: opacity .2s, transform .3s var(--ease);
}
.yt-facade:hover .yt-thumb, .yt-facade:focus-visible .yt-thumb,
.dm-facade:hover .dm-thumb, .dm-facade:focus-visible .dm-thumb {
  opacity: 1; transform: scale(1.03);
}
.yt-play-btn, .dm-play-btn {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%,-50%);
  width: 64px; height: 44px; border-radius: var(--r-md);
  transition: .2s; pointer-events: none;
}
.yt-play-btn { background: rgba(154,43,33,.88); }
.dm-play-btn { background: rgba(0,80,180,.82); }
.yt-play-btn::after, .dm-play-btn::after {
  content: ""; position: absolute; top: 50%; left: 53%;
  transform: translate(-50%,-50%);
  border-style: solid; border-width: 10px 0 10px 18px;
  border-color: transparent transparent transparent #fff;
}
.yt-facade:hover .yt-play-btn, .yt-facade:focus-visible .yt-play-btn {
  background: var(--accent); transform: translate(-50%,-50%) scale(1.08);
}
.dm-facade:hover .dm-play-btn, .dm-facade:focus-visible .dm-play-btn {
  background: #0050b4; transform: translate(-50%,-50%) scale(1.08);
}
.yt-badge, .dm-badge {
  position: absolute; bottom: 9px; right: 11px; z-index: 2;
  color: #fff; padding: 3px 9px; border-radius: var(--r-sm);
  font-family: var(--f-sans); font-size: 10.5px; font-weight: 600;
  letter-spacing: .04em; backdrop-filter: blur(2px); transition: .15s;
}
.yt-badge  { background: rgba(0,0,0,.58); }
.dm-badge  { background: rgba(0,40,100,.68); }
.yt-facade:hover .yt-badge  { background: rgba(154,43,33,.92); }
.dm-facade:hover .dm-badge  { background: rgba(0,80,180,.92); }

/* ── 15. CONTRIBUER ─────────────────────────────────────────────── */
.contrib { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-16); align-items: center; margin-top: var(--sp-5); }
.quote {
  font-family: var(--f-serif); font-style: italic;
  font-size: 1.55rem; line-height: 1.52; color: var(--fg);
  border-left: 3px solid var(--accent); padding-left: var(--sp-6); margin: 0 0 var(--sp-6);
}
.quote cite {
  display: block; font-style: normal; font-size: 11px;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold); font-family: var(--f-sans); font-weight: 600; margin-top: var(--sp-4);
}
.contrib-card {
  background: var(--bg-surface); border: 1px solid var(--border);
  border-radius: var(--r-xl); padding: var(--sp-12);
  text-align: center; box-shadow: var(--shadow-lg);
}
.contrib-card .seal { width: 56px; height: 56px; font-size: 30px; margin: 0 auto var(--sp-5); border-radius: var(--r-md); }
.contrib-card h3 { font-size: 1.65rem; margin-bottom: var(--sp-3); }
.contrib-card p { color: var(--fg-soft); margin: 0 0 var(--sp-6); font-size: 14.5px; }

/* ── 16. TIMELINE HERO ──────────────────────────────────────────── */
.timeline { position: relative; margin: var(--sp-2) 0 0; padding-left: var(--sp-10); }
.timeline::before {
  content: ""; position: absolute; left: 6px; top: 6px; bottom: 6px;
  width: 2px; background: linear-gradient(var(--gold), var(--border));
}
.tl { position: relative; padding: 0 0 var(--sp-8); }
.tl::before {
  content: ""; position: absolute; left: calc(-1 * var(--sp-10)); top: 5px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--accent);
  box-shadow: 0 0 0 3px var(--bg);
}
.tl .yr { font-family: var(--f-serif); font-weight: 600; font-size: 1.3rem; color: var(--accent); }
.tl p { margin: 2px 0 0; color: var(--fg-soft); max-width: 60ch; }

/* ── 17. NOTES / CARDS ──────────────────────────────────────────── */

/* History prose helpers */
.hist-prose h2 { font-family: var(--f-serif); font-size: 1.45rem; color: var(--accent); margin: var(--sp-10) 0 var(--sp-3); }
.hist-prose h2:first-child { margin-top: 0; }
.hist-prose p { color: var(--fg-soft); max-width: 64ch; line-height: 1.78; margin: 0 0 var(--sp-4); font-size: 16px; }

/* ── 18. FOOTER ─────────────────────────────────────────────────── */
.site-footer {
  background: linear-gradient(180deg, var(--c-encre-2), #15110d);
  color: #d9cdb8; padding: var(--sp-16) 0 var(--sp-10); margin-top: var(--sp-8);
}
.foot-grid {
  display: flex; gap: var(--sp-12); flex-wrap: wrap;
  align-items: flex-start; justify-content: space-between;
}
.foot-brand { display: flex; align-items: center; gap: var(--sp-4); margin-bottom: var(--sp-5); }
.foot-brand .brand-name { color: var(--c-ivoire-3); }
.foot-brand .brand-sub  { color: var(--c-or-soft); }
.foot-col { max-width: 44ch; }
.foot-col h5 {
  font-family: var(--f-sans); font-size: 10.5px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--gold); margin: 0 0 var(--sp-3); font-weight: 600;
}
.foot-col p { font-size: 13px; line-height: 1.62; margin: 0; color: #cabf9f; }
.foot-bottom {
  border-top: 1px solid rgba(198,165,103,.16); margin-top: var(--sp-10); padding-top: var(--sp-6);
  font-size: 11.5px; letter-spacing: .04em; color: #9c937e;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--sp-3);
}

/* ── 19. MONOLINGUE ─────────────────────────────────────────────── */
html[lang="fr"] .lang-vn { display: none !important; }
html[lang="fr"] .lang-en { display: none !important; }
html[lang="vi"] .lang-fr { display: none !important; }
html[lang="vi"] .lang-en { display: none !important; }
html[lang="en"] .lang-fr { display: none !important; }
html[lang="en"] .lang-vn { display: none !important; }
html[lang="fr"] .l-vn { display: none !important; }
html[lang="fr"] .l-en { display: none !important; }
html[lang="vi"] .l-fr { display: none !important; }
html[lang="vi"] .l-en { display: none !important; }
html[lang="en"] .l-fr { display: none !important; }
html[lang="en"] .l-vn { display: none !important; }

/* Modal accès */
#accessOverlay.open {
  display: flex; align-items: center; justify-content: center; flex-direction: column;
}

/* ── 20. RESPONSIVE ─────────────────────────────────────────────── */
@media (max-width: 1020px) {
  .gen-panel { grid-template-columns: 1fr; }
  .gen-right { border-left: 0; border-top: 1px solid rgba(198,165,103,.16); }
  .contrib { grid-template-columns: 1fr; gap: var(--sp-10); }
}

@media (max-width: 860px) {
  .menu-toggle { display: flex; }
  .hbar-nav { display: none; }
  /* Menu déplié : SUPERPOSÉ à la page (position absolue sous la première
     ligne de l'en-tête sticky) — il ne pousse plus le contenu vers le bas.
     Borné à la hauteur restante et défilable verticalement — sinon les
     entrées du bas sont inatteignables. */
  .hbar-nav.open {
    display: flex;
    position: absolute;
    top: 100%; left: 0; right: 0;
    z-index: 99;
    max-height: calc(100vh - 72px);
    max-height: calc(100dvh - 72px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    /* OPAQUE : le panneau couvre désormais le contenu — un fond translucide
       laisserait transparaître la page en dessous (illisible). */
    background: var(--bg, #f3ead7);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
  }
  /* Le panneau occupe toute la largeur de l'écran (lisibilité + zone de tap) ;
     le fond opaque est porté par le conteneur ci-dessus. */
  .hbar-nav.open .site-nav {
    width: 100%;
    background: transparent;
    box-shadow: none;
    border-bottom: 0;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .site-nav {
    position: static; flex-direction: column; align-items: stretch; gap: 0;
    background: rgba(243,234,215,.97);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border);
    padding: var(--sp-2) var(--sp-5) var(--sp-5);
    box-shadow: var(--shadow-lg);
  }
  .site-nav a { padding: var(--sp-4) var(--sp-2); border-bottom: 1px solid var(--border); border-radius: 0; }
  .site-nav a::after { display: none; }
  .hbar { position: relative; }
  /* Groupes déroulants en mobile : sous-rubriques repliées par défaut,
     dépliées au tap sur l'en-tête (accordéon). Le chevron indique l'état. */
  .nav-group { display: block; }
  .nav-trigger { width: 100%; justify-content: space-between; padding: var(--sp-4) var(--sp-2);
    border-bottom: 1px solid var(--border); border-radius: 0; font-size: 12.5px; color: var(--fg); }
  .nav-caret { display: inline; }
  .nav-panel { position: static; transform: none;
    opacity: 1; visibility: visible;
    background: transparent; border: 0; border-radius: 0; box-shadow: none; padding: 0; min-width: 0; gap: 0;
    max-height: 0; overflow: hidden;
    transition: max-height .28s var(--ease); }
  .nav-group.open .nav-panel { max-height: 70vh; }
  .nav-panel::before { display: none; }
  .nav-panel a { padding-left: calc(var(--sp-2) + 18px); border-bottom: 1px solid var(--border);
    border-radius: 0; font-size: 12.5px; }
}

@media (max-width: 680px) {
  body { font-size: 16px; }
  section.block { padding: var(--sp-12) 0; }
  .stats { grid-template-columns: 1fr 1fr; }
  .stat:nth-child(2) { border-right: 0; }
  .stat { border-bottom: 1px solid var(--border); }
  .stat:nth-child(3), .stat:nth-child(4) { border-bottom: 0; }
  /* Aucun blanc au-dessus de l'exergue : sur un téléphone, ces 64 px
     repoussaient « Lignée de lettrés · Hương Sơn, Hà Tĩnh » d'autant, pour
     rien — l'en-tête fournit déjà la séparation. Le bas garde son souffle,
     avant le bandeau de statistiques. */
  .hero { padding: 0 0 var(--sp-12); }
  .gen-left, .gen-right { padding: var(--sp-8); }
  .contrib-card { padding: var(--sp-8); }
}

@media (max-width: 440px) {
  .brand-sub { display: none; }
  .brand-name { font-size: 1.12rem; }
  .hero h1 { font-size: clamp(2.4rem, 13vw, 3.2rem); }
  .hero-cta .btn { width: 100%; justify-content: center; }
  .ln-split { gap: var(--sp-3); }
  .lineage .ln-node { min-width: 0; }
  section.block { padding: var(--sp-8) 0; }
}

/* ── BIBLIOTHÈQUE ─────────────────────────────── */
.bibl-locked {
  margin: var(--sp-10) 0 var(--sp-6);
  max-width: 600px;
  background: linear-gradient(150deg, var(--c-encre-2), var(--c-encre-3));
  color: var(--c-ivoire-3);
  border: 1px solid rgba(198,165,103,.22);
  border-radius: var(--r-xl);
  padding: var(--sp-10) var(--sp-10);
  text-align: center;
  box-shadow: var(--shadow-lg);
}
.bibl-locked svg { color: var(--gold-soft); margin-bottom: var(--sp-4); }
.bibl-locked p {
  color: #e8ddc8; margin: 0 auto var(--sp-6);
  max-width: 44ch; font-size: 15px; line-height: 1.6;
}
/* Catalogue public : la liste des documents est visible de tous, seules les
   actions (voir / télécharger) sont verrouillées. Voir hdn_render_bibliotheque()
   dans render.php et renderBibliotheque() dans main.js. */
.doc-count {
  font-size: 12px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--fg-muted); margin: var(--sp-6) 0 var(--sp-4);
}
.doc-grid {
  display: grid; gap: var(--sp-5); margin-bottom: var(--sp-8);
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
}
@media (max-width: 380px) { .doc-grid { grid-template-columns: 1fr; } }
/* UN FONDS À UNE SEULE PIÈCE ne doit pas garder une colonne de grille.
   « Trung Việt dược tính hợp biên » est seul dans son fonds et porte la plus
   longue notice du catalogue : dans une colonne de 330 px, sa carte faisait
   1 000 px de haut à côté de deux tiers de page vides. Le fonds sait combien
   il contient de pièces, la classe le dit, et la carte prend une largeur de
   lecture. */
.doc-grid.solo { grid-template-columns: minmax(0, 680px); }
.doc-body { min-width: 0; }
/* La carte est une cible d'ancre depuis la loupe du site : l'en-tête ne doit
   pas la recouvrir à l'arrivée. */
.doc[id] { scroll-margin-top: 18px; }
/* Sélecteur en deux classes à dessein : « .doc p » (plus haut dans ce fichier)
   l'emporterait sur « .doc-lock » seul et lui rendrait la taille du corps. */
.doc .doc-lock {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  margin: 0; font-size: 12px; color: var(--fg-muted);
}
.doc .doc-lock svg { flex: none; color: var(--gold); }
.doc-porte { margin: 0 0 var(--sp-4); }

/* ── Fonds : l'étage entre le catalogue et la pièce ──────────────────────
   SIGNALÉ LE 08/09/2026 : « la partie bibliothèque n'est plus adaptée pour
   héberger un corpus hiérarchisé par dossiers ». Sur seize documents, HUIT
   sont le même ouvrage en huit états — le gia phả en original vietnamien, en
   rédaction trilingue, en mises à jour de 2010 et 2020, en traduction
   française, en arbre, en planches, en export. Une grille plate demandait au
   lecteur de comparer seize intitulés presque identiques.
   Le titre de fonds et sa présentation portent donc le poids visuel ; les
   cartes, elles, ne changent pas — ce sont les mêmes documents, mieux rangés. */
.doc-som {
  display: flex; flex-wrap: wrap; gap: var(--sp-2);
  margin: 0 0 var(--sp-6);
}
.doc-som a {
  display: inline-flex; align-items: baseline; gap: 7px;
  text-decoration: none; font-size: 12.5px; color: var(--fg-soft);
  padding: 5px 11px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg-surface);
  transition: border-color .18s var(--ease), color .18s var(--ease);
}
.doc-som a:hover { border-color: var(--gold); color: var(--fg); }
.doc-som .n { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--accent); }

.doc-fonds-t {
  font-family: var(--f-serif); font-weight: 600; font-size: 1.32rem;
  color: var(--fg); line-height: 1.25;
  margin: var(--sp-8) 0 var(--sp-2); padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--line); scroll-margin-top: 18px;
}
.doc-fonds-p {
  max-width: 74ch; font-size: 13.5px; line-height: 1.7;
  color: var(--fg-soft); margin: 0 0 var(--sp-5);
}
/* UN SOUS-FONDS EST DÉCALÉ — la hiérarchie doit se lire d'un coup d'œil et non
   se déduire d'une comparaison d'intitulés. Le décalage tombe à zéro sous
   700 px, remplacé par un filet : trois niveaux d'indentation ne laisseraient
   plus de place au texte sur un téléphone. */
.doc-fonds-t.sous { margin-left: calc(var(--prof, 1) * 26px); font-size: 1.1rem;
  border-bottom-style: dashed; }
.doc-fonds-p.sous, .doc-grid.sous { margin-left: calc(var(--prof, 1) * 26px); }
@media (max-width: 700px) {
  .doc-fonds-t.sous, .doc-fonds-p.sous, .doc-grid.sous {
    margin-left: 0; border-left: 2px solid var(--gold); padding-left: 12px;
  }
}
.doc-som a.sous { font-size: 11.5px; }
.doc-som a.sous .br { color: var(--gold); }

/* Ligne de faits — « informer sur le contenu du document hébergé ».
   Deux classes, pour la même raison que .doc .doc-lock : « .doc p » plus haut
   dans ce fichier l'emporterait sur une classe seule et lui rendrait la taille
   et la couleur du corps de texte, effaçant la distinction. */
.doc .doc-faits {
  display: flex; flex-wrap: wrap; gap: 3px 9px;
  margin: 0 0 var(--sp-3);
  font-size: 11.5px; letter-spacing: .02em; color: var(--fg-muted);
}
.doc .doc-faits span + span::before {
  content: "·"; color: var(--gold); margin-right: 9px;
}
.doc .doc-faits .an { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--fg-soft); }

.doc .badge.prive {
  background: rgba(154,43,33,.09); color: var(--accent);
  border-color: rgba(154,43,33,.22);
}
.doc .badge.pdf   { background: rgba(46,111,94,.09); color: var(--c-jade); border-color: rgba(46,111,94,.22); }
.doc .badge.ged   { background: rgba(58,74,138,.09); color: #3A4A8A; border-color: rgba(58,74,138,.22); }

/* ════════════════════════════════════════════════════════════════
   iOS & ANDROID COMPATIBILITY
   ════════════════════════════════════════════════════════════════ */

/* Prevent iOS text inflation */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* Remove iOS tap highlight on interactive elements */
a, button, [role="button"], .btn, .filter-btn, .lang button,
.menu-toggle, .site-nav a, .conn-item, .fig, .doc, .lnk {
  -webkit-tap-highlight-color: transparent;
}

/* Smooth scrolling on iOS */
main, .fiche-scroll, .sidebar {
  -webkit-overflow-scrolling: touch;
}

/* iOS safe area insets (notch / home indicator) */
.site-header {
  padding-left: max(0px, env(safe-area-inset-left));
  padding-right: max(0px, env(safe-area-inset-right));
}
.site-footer {
  padding-bottom: max(var(--sp-10), env(safe-area-inset-bottom));
}

/* Fix backdrop-filter on iOS — needs -webkit- prefix */
.site-header,
.site-nav {
  -webkit-backdrop-filter: blur(14px) saturate(1.5);
          backdrop-filter:  blur(14px) saturate(1.5);
}

/* Prevent rubber-band scroll on body (iOS overscroll) */
body { overscroll-behavior: none; }
main { overscroll-behavior: auto; }

/* Touch target minimum 44×44px (Apple HIG) */
.lang button       { min-height: 44px; min-width: 40px; }
.menu-toggle       { min-width: 44px;  min-height: 44px; }
.site-nav a        { min-height: 44px; display: flex; align-items: center; }
.btn               { min-height: 44px; }
.filter-btn        { min-height: 36px; }

/* Fix position:fixed stacking on Android Chrome */
.site-header { will-change: auto; }

/* Prevent double-tap zoom on buttons (Android) */
button, a, [role="button"] { touch-action: manipulation; }

/* Fix flexbox gap on older Android WebView */
@supports not (gap: 1px) {
  .hbar > * + *          { margin-left: var(--sp-6); }
  .fig-grid              { gap: 0; }
  .fig-grid .fig         { margin: var(--sp-3); }
  .hero-cta > * + *      { margin-left: var(--sp-4); }
}

/* Mobile nav — ensure it stacks correctly */
@media (max-width: 860px) {
  .site-nav {
    /* Ensure nav is above everything on mobile */
    z-index: 200;
    /* Fix potential clip on Android */
    overflow-y: auto;
    max-height: calc(100vh - 64px);
    /* Prevent momentum scrolling causing issues */
    overscroll-behavior: contain;
  }
  /* Ensure burger is always tappable */
  .menu-toggle {
    position: relative;
    z-index: 201;
    cursor: pointer;
  }
}

/* Fix input zoom on iOS (font-size < 16px triggers zoom) */
input, select, textarea {
  font-size: 16px !important;
}

/* Prevent hover styles sticking on touch devices */
@media (hover: none) {
  .fig:hover            { transform: none; box-shadow: none; }
  .fig:hover::before    { width: 48px; }
  .fig:hover::after     { opacity: 0; }
  .doc:hover            { transform: none; box-shadow: none; }
  .lnk:hover            { transform: none; box-shadow: none; }
  .btn:hover            { box-shadow: var(--shadow-sm); }
  .site-nav a:hover     { background: none; }
  .site-nav a:hover::after { transform: scaleX(0); }
  /* Active states instead of hover for touch */
  .fig:active  { transform: translateY(-2px); box-shadow: var(--shadow-md); }
  .doc:active  { transform: translateY(-2px); }
  .btn:active  { transform: translateY(1px); opacity: .9; }
}

/* Fix hero Han scroll on mobile — reduce font size to prevent jank */
@media (max-width: 680px) {
  .hero-han-scroll {
    font-size: clamp(4rem, 22vw, 8rem);
    animation-duration: 80s;
  }
}

/* ── Lien email obfusqué (anti-robots) ───────────────────────────── */

/* ── Carte Văn Miếu ─────────────────────────────────────────── */
.vanmieu-wrap { margin: 2rem 0 2.4rem; }
.vanmieu-label {
  display: flex; align-items: center; gap: .6rem;
  font-family: var(--f-sans); font-size: .72rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--lacquer); margin-bottom: .5rem;
}
.vanmieu-label .han { font-size: 1.2rem; line-height: 1; }
.vanmieu-intro {
  font-size: .88rem; color: var(--ink-soft);
  line-height: 1.6; margin-bottom: .9rem;
}
.vanmieu-frame {
  width: 100%; border-radius: 10px; overflow: hidden;
  box-shadow: 0 6px 28px rgba(44,24,16,.18);
  border: 1.5px solid rgba(176,137,64,.4);
  background: #f7f0e4;
}
.vanmieu-frame img {
  width: 100%; height: auto; display: block;
}
.vanmieu-note {
  margin-top: .6rem; font-size: .78rem; color: var(--ink-soft);
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
}
.vanmieu-mk {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  color: #fff; font-size: .72rem; font-weight: 700;
  font-family: var(--f-sans); flex-shrink: 0;
}

/* Compat : alias hérités pour les CSS de page. Source UNIQUE = primitives --c-*
   (les couleurs de marque — laque/or/ivoire/encre — ne sont plus redéfinies en
   dur ici, ce qui garantit un rendu identique sur toutes les pages). */
:root{
  --c-border: var(--border);
  --c-cream-dark: var(--c-ivoire-2);
  --c-ink: var(--fg);
  --c-ink-soft: var(--fg-soft);
  --c-lacquer: var(--c-laque);
  --c-lacquer-deep: var(--c-laque-deep);
  --c-line: var(--border);
  --c-text-soft: var(--fg-soft);
  --c-text: var(--c-encre);
  --s-1: 4px;
  --s-3: 12px;
  --s-5: 20px;
  --encre: var(--c-encre);
  --font-serif: var(--f-serif);
  --gold-bright: var(--c-or-soft);
  --gold-deep: #7a5e2a;
  --gold-pale: var(--c-or-pale);
  --hb-maxw: 42rem;
  --ink: var(--c-encre);
  --ink-faint: var(--c-sepia-soft);
  --ink-soft: var(--c-sepia);
  --ivoire: var(--c-ivoire);
  --ivoire-2: var(--c-ivoire-2);
  --jade: var(--c-jade);
  --jade-clair: #E7F0EC;
  --jade-soft: var(--c-jade-soft);
  --lac: var(--c-laque);
  --lac-deep: var(--c-laque-deep);
  --lacquer: var(--c-laque);
  --lacquer-bright: var(--c-laque-light);
  --lacquer-deep: var(--c-laque-deep);
  --laque: var(--c-laque);
  --laque-clair: var(--c-laque-light);
  --ligne: var(--c-ligne);
  --line: var(--c-ligne);
  --line-soft: rgba(36,30,23,.09);
  --or: var(--c-or);
  --or-clair: var(--c-or-soft);
  --paper: var(--c-ivoire);
  --paper-2: var(--c-ivoire-2);
  --paper-panel: var(--c-ivoire-2);
  --radius-sm: var(--r-sm);
  --rust: #8d4a2f;
  --s-12: var(--sp-12);
  --s-16: var(--sp-16);
  --s-2: var(--sp-2);
  --s-24: var(--sp-24);
  --s-4: var(--sp-4);
  --s-6: var(--sp-6);
  --s-8: var(--sp-8);
  --sepia: var(--c-sepia);
  --serif: "Be Vietnam Pro",Georgia,serif;
  --shadow: 0 18px 50px -28px rgba(40,25,15,.55);
}

/* ==================================================================== *
 *  Accessibilité & impression (ajouts audit front-end)
 * ==================================================================== */

/* Contrôles de formulaire cohérents (évite l'assombrissement auto incohérent). */
:root { color-scheme: light; }

/* Lien d'évitement : masqué jusqu'au focus clavier (1er élément tabulable). */
.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 2000;
  background: var(--c-laque, #9a2b21); color: #fff;
  padding: 10px 16px; border-radius: 0 0 8px 8px; text-decoration: none;
  font-weight: 600; transition: top .15s ease;
}
.skip-link:focus { top: 0; outline: 2px solid var(--c-or, #a9803a); outline-offset: 2px; }

/* Impression : on retire le décor d'écran (overlay grain, en-tête collant,
   pied sombre) et on force un rendu clair et lisible sur papier. */
@media print {
  .grain, .site-header, .site-footer, .menu-toggle, .lang, .skip-link { display: none !important; }
  /* Le bouton qui a lancé l'impression n'a rien à faire sur la feuille —
     le fil d'Ariane non plus : le papier n'a pas de liens à suivre. */
  .print-btn, .hb-sticky, .chapter-nav, .fil-ariane { display: none !important; }
  body { background: #fff !important; color: #1a1410 !important; }
  main, #view-root, .container { margin: 0 !important; padding: 0 !important; }
  a { color: #1a1410 !important; text-decoration: underline; }
  .reveal { opacity: 1 !important; transform: none !important; }

  /* ══════════ LES JETONS DE LA CHARTE, REPRIS À L'ENCRE ══════════════════
     RELEVÉ FAIT SUR LE SITE SERVI, pas sur le dépôt : les vingt pages
     imprimables, dans les trois langues, chargées avec leurs feuilles de
     production, mesurées sous média print, élément par élément. Treize pages
     sur vingt avaient du texte sous le seuil de contraste.

     LA CAUSE PREMIÈRE EST ICI, EN QUATRE LIGNES. L'or de la charte donne
     3,6:1 sur blanc, son ton clair 2,34:1, son ton pâle 1,45:1 — et les
     rubriques ne les redéclarent pas : histoire.css fait --or:var(--c-or),
     livret.css --gold:var(--c-or), ecrits.css de même. Un alias en chaîne,
     donc une seule correction : reprendre les jetons ICI les corrige partout
     — surtitres, numéros de chapitre, filets, libellés de tableau, séparateurs
     des six pages de poésie, intitulés de figures apparentées.

     Sur écran ces tons portent un fond crème ou laqué et sont justes. Sur le
     blanc du papier ils n'ont plus rien derrière eux.

     Les tons ivoire ne servent de couleur de TEXTE que sur fond sombre : sur
     papier ils passent à l'encre. Comme fond ils ne s'impriment pas. */
  :root {
    --c-or:        #856320 !important;   /* 3,60 → 5,52:1 */
    --c-or-soft:   #856320 !important;   /* 2,34 → 5,52:1 */
    --c-or-pale:   #6b5a2e !important;   /* 1,45 → 6,72:1 */
    --c-ivoire:    #241f19 !important;   /* 1,20 → 16,3:1 */
    --c-ivoire-3:  #241f19 !important;   /* 1,12 → 16,3:1 */
    --c-ligne:     #7d6f58 !important;   /* 1,68 → 4,90:1 (filets ET texte) */
  }

  /* SAUF LÀ OÙ LE FOND S'IMPRIME VRAIMENT. La couverture du livre d'histoire
     porte print-color-adjust:exact : sa laque sort de l'imprimante, et sur ce
     fond-là ce sont les tons CLAIRS qui se lisent. Reprendre les jetons à
     l'encre y faisait l'inverse de ce qu'on cherche — l'or foncé sur le rouge
     tombe à 1,39:1, alors que l'or clair d'origine y tient 3,8:1. On rétablit
     donc la palette d'écran sur ce sous-arbre. Les propriétés personnalisées
     se cascadant par élément, une redéclaration sur .cover l'emporte pour tout
     ce qu'elle contient, sans avoir à répéter une seule règle de couleur.

     ET IL FAUT REPRENDRE LES ALIAS, PAS SEULEMENT LES PRIMITIVES : histoire.css
     déclare --or-clair:var(--c-or-soft) sur .hist-book, donc la substitution a
     déjà eu lieu À CET ÉLÉMENT-LÀ, un cran au-dessus de la couverture. Rétablir
     --c-or-soft sur .cover ne rejoue pas cette substitution ; il faut redonner
     sa valeur à --or-clair lui-même. Une heure perdue à comprendre pourquoi la
     première correction ne changeait rien. */
  .hist-book .cover {
    --c-or:        #a9803a;
    --c-or-soft:   #c6a567;
    --c-or-pale:   #e8d5a3;
    --c-ivoire:    #f3ead7;
    --c-ivoire-3:  #f8f1e2;
    --c-ligne:     #d8c6a2;
    --or:          #a9803a;
    --or-clair:    #e8d5a3;   /* 3,28 → 5,28:1 sur la laque imprimée */
    --ivoire:      #f3ead7;
    --ligne:       #d8c6a2;
  }
  /* Le seul écart qui restait après tout cela : le sous-titre et le distique
     de la couverture, en or clair sur la laque, tenaient 3,28:1 — un défaut
     d'origine, pas une conséquence des reprises ci-dessus. L'or PÂLE de la
     charte, un ton au-dessus, y monte à 5,28:1 sans rien changer à l'écran :
     la règle ne vaut que sous @media print. */

  /* ══════════ LES SECTIONS EN NÉGATIF, PAGE PAR PAGE ═════════════════════
     Un fond sombre ne s'imprime pas : son texte clair reste seul sur du
     blanc. On rend le fond au papier et TOUT ce qu'il contient à l'encre —
     « et * », sans quoi un titre qui porte sa propre couleur resterait blanc.
     Même geste que le livret des jeunes dans sa propre feuille.

     UNE EXCEPTION, ET C'EST UNE ERREUR QUE J'AI COMMISE ICI. La couverture du
     livre d'histoire (.cover) N'EST PAS dans cette liste, et ne doit pas y
     entrer : histoire.css lui pose print-color-adjust:exact, donc sa laque
     S'IMPRIME VRAIMENT — c'est une couverture de livre, voulue en couleur.
     L'y avoir mise a fait sortir son titre en encre noire sur du rouge, à
     2,13:1 : plus illisible qu'avant la correction. La règle générale « les
     fonds ne s'impriment pas » a donc une exception, et elle se lit dans la
     feuille : print-color-adjust:exact. */
  .hb-foot, .hb-foot *, .chap-num, .chap-num *,
  .note-h, .note-h *, .vanmieu-mk, .vanmieu-mk *,
  .hv-clan-sceau, .hv-clan-sceau *, .hv-fin, .hv-fin *,
  .rp-seal, .rp-seal *,
  .seal, .seal *,
  #gen-acces, #gen-acces *, .bhead, .bhead *, .disc, .disc *,
  #gen-livret .couplet, #gen-livret .couplet *,
  #gen-livret .branch-card, #gen-livret .branch-card *,
  #gen-livret .custody, #gen-livret .custody *,
  #gen-livret .card .badge, #gen-livret .poem .excerpt,
  #gen-livret .poem .excerpt *, #gen-livret .reason .stp,
  #gen-livret .reason .stp *,
  #rit-ch2, #rit-ch2 *, #rit-film, #rit-film *,
  .rsc-altar, .rsc-altar *, .rit-foot, .rit-foot *,
  #ritPlay, #ritPlay * {
    background: none !important; color: #241f19 !important;
    text-shadow: none !important; box-shadow: none !important;
    opacity: 1 !important;
  }

  /* ══════════ LES TEINTES ÉCRITES EN DUR, RUBRIQUE PAR RUBRIQUE ══════════
     Ces pages tiennent leur palette dans leur propre <style> plutôt que dans
     la charte. On reprend leurs jetons sur le sélecteur qui les porte, sinon
     une redéclaration à la racine perdrait contre lui. */
  #histoire-vietnam {
    --hv-or:        #856320 !important;  /* 2,40 → 5,52:1 */
    --hv-or-fonce:  #8a6a22 !important;  /* 4,01 → 5,04:1 */
    --hv-estompe:   #5d5346 !important;  /* 4,18 → 7,52:1 */
    --hv-ecru:      #241f19 !important;  /* 1,20 → 16,3:1 (texte sur sombre) */
  }
  #recueil-poemes .rp-root {
    --rp-gold:  #856320 !important;      /* 3,60 → 5,52:1 */
    --rp-paper: #241f19 !important;      /* 1,16 → 16,3:1 (texte sur sombre) */
  }
  #rituels .rit-root {
    --gold: #856320 !important;          /* 3,60 → 5,52:1 */
    --rp:   #241f19 !important;          /* 1,16 → 16,3:1 (texte sur sombre) */
  }
  /* La doctrine écrit ses gris et ses ors sans jeton : on vise les classes. */
  .ng-eyebrow, .ng-cite cite, .ng-vs .qui, .ng-fiche .k {
    color: #5d5346 !important;           /* 3,38 et 4,18 → 7,52:1 */
  }
  .ng-rel .fl, .ng-canon .fl { color: #856320 !important; } /* 3,09 → 5,52:1 */
  /* L'italique et les libellés secondaires de la doctrine héritent du gris
     estompé posé en dur dans les blocs : même reprise. */
  #nho-giao em, #view-nho-giao em,
  #nho-giao .k, #view-nho-giao .k { color: #5d5346 !important; }
  /* Rituels écrit deux gris à la main, sans jeton. */
  #rituels .rit-hero-src, #rituels .rsc-natte span { color: #5d5346 !important; }

  /* LES TEINTES PÂLES POSÉES EN ATTRIBUT style=. Une couleur en ligne ne se
     laisse dépasser que par un !important, et aucun sélecteur de classe ne la
     désigne : on vise donc l'attribut lui-même, comme le fait déjà plus bas
     l'harmonisation des polices avec [style*="Cormorant"]. */
  [style*="#8a7a5f"], [style*="#8A7A5F"] { color: #5d5346 !important; }
  [style*="#d8c9a8"], [style*="#D8C9A8"] { color: #241f19 !important; }

  /* LE PIED DE SOURCES, SUR LES QUARANTE-CINQ PAGES QUI EN PORTENT UN.
     Il est écrit en dur dans le contenu, avec sa teinte en attribut style= :
     #8a7a5f, cinquante-quatre fois, jamais autre chose. Sur écran elle est
     juste — un gris sépia discret sous un fond crème. Sur papier, à 11,5 px,
     elle ne donne que 4,18:1 : sous le seuil AA pour du petit texte, et c'est
     précisément le texte qu'on relit de près, celui qui dit d'où vient une
     date. Le sépia de la charte, #5d5346, donne 7,52:1 — même famille de
     couleur, deux fois plus lisible.

     !important parce que la teinte est en attribut style= ; rien d'autre ne
     la dépasse. Le filet du haut passe d'un gris à 25 % d'opacité, qui sort
     presque blanc, à un trait franc : sans lui le pied de sources se
     confondrait avec le corps du texte.

     DEUX BALISES, et c'est un piège que la mutation d'essai a révélé : la
     plupart des pieds sont des <footer>, cinq sont des <p>. La règle porte
     sur la CLASSE — elle couvre donc les deux.

     ET SUR SES DESCENDANTS, pas seulement sur lui : la page de la doctrine
     colore ses propres paragraphes de sources dans sa feuille (.ng-sources p),
     ce qui battait l'héritage. D'où le « * ». */
  .page-sources, .page-sources * {
    color: #5d5346 !important;
  }
  .page-sources { border-top-color: rgba(93,83,70,.45) !important; }
}

/* Bouton « Imprimer / enregistrer en PDF ».
   Le livret pour les jeunes l'avait en premier, avec ses styles en ligne ; la
   règle ci-dessous donne la même apparence aux boutons que l'application pose
   sur les autres pages (voir ensurePrintButton dans assets/main.js), sans
   recopier les styles dans chaque page. */
.print-btn{ text-align:right; max-width:860px; margin:10px auto -6px; }
.print-btn button{
  cursor:pointer; border:1px solid rgba(169,128,58,.5); background:rgba(169,128,58,.08);
  color:var(--c-laque,#9a2b21); border-radius:999px; padding:8px 16px;
  font-size:14px; font-weight:600; font-family:inherit; line-height:1.3;
}
.print-btn button:hover{ background:rgba(169,128,58,.18); }
.print-btn button:focus-visible{ outline:2px solid var(--c-or,#a9803a); outline-offset:2px; }
/* Les pages larges (généalogie, figures, agenda…) cadrent leur contenu bien
   au-delà de 860 px : le bouton s'aligne alors sur la largeur du contenu. */
.print-btn.print-btn--wide{ max-width:var(--maxw,1180px); }

/* ==================================================================== *
 *  Icônes au trait (jeu moderne — voir assets/icons.js)
 *  .hicon prend la taille (1em) et la couleur (currentColor) du texte
 *  qui l'entoure : les emoji « dessin » sont remplacés à l'identique de
 *  leur emplacement, mais accordés à la palette. Des règles existantes
 *  plus spécifiques (ex. .ic svg, .doc .ic svg) gardent leur dimension.
 * ==================================================================== */
.hicon{ width:1em; height:1em; display:inline-block; vertical-align:-.14em; flex:none; }

/* Boutons pilules de la section finale « héritage » : ils reposent sur un
   fond rouge foncé, mais leur style en ligne fixait color:#9a2b21 (rouge)
   → illisibles (rouge sur rouge). On force un texte crème lisible. */
.her-links a{ color:#f4ead4 !important; background:rgba(255,255,255,.07) !important;
  border-color:rgba(216,192,137,.55) !important; }
.her-links a:hover{ background:rgba(255,255,255,.15) !important; border-color:rgba(216,192,137,.8) !important; }

/* Harmonisation Be Vietnam Pro — neutralise les polices sérif restées en dur
   dans le contenu géré en ligne (héritage, jeunes) sans resynchronisation.
   On épargne les caractères Han (.her-han / .rt-han → Noto Serif TC). */
[style*="Cormorant"], [style*="cormorant"] { font-family: var(--f-sans) !important; }
.her-hero h1, .her-hero .devise, .her-h2, .her-quote, .her-finale, .her-rite strong { font-family: var(--f-sans) !important; }

/* ==================================================================== *
 *  IMPRESSION DE « HÉRITAGE SPIRITUEL » — un négatif ne s'imprime pas
 * --------------------------------------------------------------------
 *  LE DÉFAUT, tel qu'il a été signalé : la première page imprimée de
 *  /heritage-spirituel ne portait PAS son titre. Une feuille qui ouvre sur
 *  du vide, puis du texte sans en-tête.
 *
 *  LA CAUSE : le héros est un NÉGATIF. Son fond est un dégradé très sombre
 *  et son texte est pâle — or les navigateurs n'impriment pas les fonds.
 *  Reste donc l'or clair (#e8d5a3) du titre sur le blanc du papier :
 *  invisible. Même sort pour les quatre bandes sombres (.her-band-dark) et
 *  la bande rouge finale (.her-band-red) — soit la moitié de la page.
 *
 *  C'est exactement le piège déjà documenté et corrigé dans la page de la
 *  doctrine (views/nho-giao.html, bloc @media print) ; cette page-ci ne
 *  l'avait jamais reçu : sa seule règle d'impression bornait la hauteur des
 *  figures.
 *
 *  POURQUOI ICI, ET AVEC !important. Le contenu de cette page vit dans
 *  content/blocks/heritage-spirituel.{fr,vn,en}.json, qui se modifient EN
 *  LIGNE depuis l'administration : une resynchronisation écraserait ces
 *  éditions. On neutralise donc à la source, comme le fait déjà juste
 *  au-dessus l'harmonisation des polices. Le <style> des blocs est inséré
 *  DANS le document, donc PLUS BAS que cette feuille : à spécificité égale
 *  il gagnerait. Et les couleurs pâles des bandes sombres sont posées en
 *  attribut style= (« color:#c5a96a », « color:#e8d5a3 », « color:#c9a24b »),
 *  que seul un !important d'auteur peut dépasser. D'où le !important partout.
 *
 *  La même feuille sert la vue views/heritage-spirituel.html : une seule
 *  règle couvre les deux chemins de rendu.
 * ==================================================================== */
@media print{
  /* Le héros : fond retiré, texte à l'encre, un filet pour tenir le titre. */
  .her-hero{ background:none !important; color:#241f19 !important;
    padding:0 0 14px !important; margin-bottom:20px !important;
    border-bottom:2px solid #9c7a2e !important; overflow:visible !important;
    page-break-after:avoid; break-after:avoid; }
  .her-hero::before{ display:none !important; }
  .her-hero .seal-lg{ color:#9c7a2e !important; font-size:26pt !important;
    margin-bottom:4px !important; filter:none !important; }
  .her-hero h1{ color:#9a2b21 !important; font-size:21pt !important;
    margin:0 0 8px !important; }
  .her-hero .sub{ color:#5d5346 !important; font-size:10pt !important;
    max-width:none !important; margin:0 auto 14px !important; }
  .her-hero .devise{ color:#9c7a2e !important; padding:8px 0 !important;
    border-color:rgba(156,122,46,.5) !important; }
  .her-hero .devise-sub{ color:#5d5346 !important; }

  /* Les bandes : le décor d'écran tombe, la marge d'écran avec lui. */
  .her-band{ padding:0 !important; margin-bottom:20px !important; }
  .her-band .page{ max-width:none !important; }
  .her-band-dark, .her-band-red, .her-band-cream{
    background:none !important; color:#241f19 !important; }

  /* Ce que les bandes sombres et rouge coloraient en clair — titres, chapeaux,
     surtitres, noms — repasse à l'encre. Les attributs style= en ligne des
     blocs sont visés par ces mêmes règles. */
  .her-band-dark .her-h2, .her-band-red .her-h2{ color:#9a2b21 !important; }
  .her-band-dark .her-lead, .her-band-red .her-lead,
  .her-band-dark .her-p, .her-band-red .her-p,
  .her-band-dark .her-quote, .her-band-red .her-quote,
  .her-band-dark .her-finale, .her-band-red .her-finale{
    color:#241f19 !important; opacity:1 !important; }
  .her-band-dark .her-nom, .her-band-red .her-nom{ color:#9a2b21 !important; }
  .her-band-dark .her-quote{ background:none !important; }
  .her-finale{ border-color:rgba(156,122,46,.5) !important; }

  /* L'or pâle passe partout à un or foncé : sur écran il portait un fond
     sombre, sur papier il n'a plus que du blanc derrière lui.
     DEUX TONS, ET LA RAISON EST MESURÉE. #9c7a2e donne 4,01:1 sur blanc :
     assez pour un GRAND caractère (le seuil AA tombe à 3:1 au-delà de 24 px —
     le sceau ☯ à 34 px, la devise, les idéogrammes de rite), pas assez pour du
     texte courant à 18 px. Celui-là prend #8a6a22, soit 5,04:1. */
  .her-kicker{ color:#7a6a4a !important; }
  .her-rite .rt-han{ color:#9c7a2e !important; }
  .her-quote .src, .her-rite strong{ color:#8a6a22 !important; }
  .her-quote{ border-left-color:#9c7a2e !important; }
  .her-rule{ border-top-color:rgba(156,122,46,.5) !important; }

  /* Un titre seul en bas de page, son texte à la page suivante. */
  .her-h2, .her-kicker{ page-break-after:avoid; break-after:avoid; }
  .her-quote, .her-finale, .her-rite li{
    break-inside:avoid; page-break-inside:avoid; }

  /* Le papier n'a pas de liens à suivre — et ces pilules-là sont forcées en
     crème pour l'écran (règle .her-links ci-dessus), donc blanc sur blanc. */
  .her-links{ display:none !important; }
}

/* ==================================================================== *
 *  Recherche sur tout le site (icône en-tête + overlay)
 * ==================================================================== */
.icon-btn{
  /* En-tête clair (papier) : l'icône doit contraster. L'ancienne teinte
     or pâle rendait la loupe quasi invisible (ton sur ton). */
  background:transparent; border:1px solid var(--c-or,#a9803a); color:var(--c-laque,#9a2b21);
  border-radius:999px; width:34px; height:34px; font-size:.95rem; cursor:pointer; line-height:1;
  display:inline-grid; place-items:center;
}
.icon-btn:hover{ color:var(--c-laque-deep,#6f1e16); }
.icon-btn:hover{ background:rgba(169,128,58,.15); }

.srch-ov{ position:fixed; inset:0; z-index:1500; background:rgba(20,14,9,.55);
  display:flex; align-items:flex-start; justify-content:center; padding:8vh 16px 16px; }
.srch-ov[hidden]{ display:none; }
.srch-box{ width:min(640px,100%); background:var(--c-ivoire-3,#f8f1e2); color:var(--c-encre,#241f19);
  border-radius:14px; box-shadow:0 24px 70px -20px rgba(0,0,0,.6); max-height:82vh;
  display:flex; flex-direction:column; overflow:hidden; }
.srch-top{ display:flex; align-items:center; gap:8px; padding:12px 14px; border-bottom:1px solid var(--c-ligne,#d8c6a2); }
.srch-ico{ font-size:1.05rem; opacity:.7; }
#searchInput{ flex:1; border:0; background:transparent; font-size:1.05rem; color:inherit; outline:none; padding:6px 2px; }
.srch-close{ border:0; background:transparent; font-size:1.1rem; cursor:pointer; color:var(--c-sepia,#5d5346); padding:4px 8px; }
.srch-results{ overflow:auto; padding:6px 0; }
.srch-hint{ padding:20px 16px; color:var(--c-sepia,#5d5346); }
.srch-item{ display:block; width:100%; text-align:left; border:0; background:transparent; cursor:pointer;
  padding:10px 16px; text-decoration:none; color:inherit; border-bottom:1px solid rgba(0,0,0,.05); }
.srch-item:hover{ background:rgba(169,128,58,.1); }
.srch-kind{ display:inline-block; font-size:.62rem; letter-spacing:.06em; text-transform:uppercase;
  color:var(--c-laque,#9a2b21); background:rgba(154,43,33,.08); border-radius:20px; padding:2px 8px; margin-right:6px; }
.srch-title{ font-weight:600; }
.srch-snip{ display:block; font-size:.85rem; color:var(--c-sepia,#5d5346); margin-top:2px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* Bouton « haut de page » */
.to-top{
  position:fixed; right:18px; bottom:18px; z-index:200; width:44px; height:44px;
  border-radius:999px; border:1px solid var(--c-or,#a9803a); cursor:pointer;
  background:var(--c-laque,#9a2b21); color:#f8f1e2; font-size:1.2rem; line-height:1;
  box-shadow:0 6px 20px -6px rgba(0,0,0,.5); display:grid; place-items:center;
  padding-bottom:env(safe-area-inset-bottom,0);
}
.to-top[hidden]{ display:none; }
.to-top:hover{ background:var(--c-laque-deep,#6f1e16); }
@media print { .to-top{ display:none !important; } }

/* ============================================================
   ILLUSTRATIONS DE CHAPITRE — LIGNÉE MATERNELLE
   La page /clan-lam n'a pas de feuille à elle. Ses règles vivent
   donc ici, comme .photo-slot juste dessous, et ne sont scopées
   sous AUCUN conteneur : servie par les blocs, la page n'a pas
   le #id que porte sa vue de repli — une règle scopée ne s'y
   appliquerait pas (le cas s'est produit sur /heritage-spirituel).
   ============================================================ */
.lam-fig{
  width:min(460px,100%); margin:20px auto 24px; padding:0;
  display:flex; flex-direction:column; gap:8px;
}
.lam-fig img{
  display:block; width:100%; height:auto; border-radius:10px;
  border:1px solid rgba(169,128,58,.34); background:rgba(169,128,58,.06);
}
.lam-fig figcaption{
  font-size:.79rem; line-height:1.55; font-style:italic;
  color:var(--c-sepia,#5d5346);
}
.lam-fig .lam-fig-src{
  display:block; margin-top:5px; font-style:normal; font-size:.72rem;
  color:var(--c-sepia-soft,#6d6154);
}
.lam-fig .lam-fig-src a{
  color:inherit; text-decoration:underline;
  text-decoration-color:rgba(169,128,58,.5); text-underline-offset:2px;
}
.lam-fig .lam-fig-src a:hover{ color:var(--c-or,#a9803a); }
@media (max-width:760px){ .lam-fig{ width:100%; margin:16px 0 20px; } }
@media print{
  /* Hauteur bornée : une figure haute qu'on refuse de couper se fait
     renvoyer à la page suivante en laissant une demi-page blanche. */
  .lam-fig{ width:auto; max-width:58%; margin:12px 0 16px; align-items:flex-start;
    break-inside:avoid; page-break-inside:avoid; }
  .lam-fig img{ width:auto; max-width:100%; max-height:72mm;
    border-color:rgba(156,122,46,.5); }
}

/* ============================================================
   EMPLACEMENTS PHOTO RÉSERVÉS (lieux de mémoire)
   <figure class="photo-slot" data-photo="lieu-…"> : cadre en
   pointillés tant que la photo n'existe pas dans la médiathèque ;
   dès que /uploads/media/lieu-….jpg est en ligne, main.js ajoute
   .ps-has et la photo remplace le cadre (le nom devient légende).
   ============================================================ */
.ps-grid{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  gap:14px; margin:22px 0;
}
.photo-slot{
  position:relative; margin:0; aspect-ratio:4/3; overflow:hidden;
  border:2px dashed rgba(169,128,58,.5); border-radius:var(--r-lg,12px);
  background:rgba(169,128,58,.06);
  display:flex; align-items:center; justify-content:center; text-align:center;
}
.photo-slot img{ display:none; }
.photo-slot .ps-label{
  padding:12px; display:flex; flex-direction:column; gap:6px; align-items:center;
}
.photo-slot .ps-label strong{
  font-family:var(--f-serif,Georgia,serif); font-weight:600; font-size:1.02rem;
  line-height:1.3; color:var(--c-sepia,#5d5346);
}
.photo-slot .ps-label span{
  font-size:.75rem; letter-spacing:.02em; color:var(--c-sepia-soft,#6d6154);
}
/* Invitation à contribuer une photo d'un lieu encore sans image. */
.photo-slot .ps-contrib{
  margin-top:4px; font-size:.72rem; font-weight:600; letter-spacing:.02em;
  color:var(--c-laque,#9a2b21); text-decoration:none; border-bottom:1px dotted currentColor;
}
.photo-slot .ps-contrib:hover{ color:var(--c-or,#a9803a); }
.photo-slot.ps-has .ps-contrib{ display:none; }
.photo-slot.ps-has{
  border:1px solid rgba(169,128,58,.35); background:none;
  box-shadow:0 8px 24px -12px rgba(0,0,0,.35);
}
.photo-slot.ps-has img{
  display:block; position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
}
.photo-slot.ps-has .ps-label{
  position:absolute; left:0; right:0; bottom:0; z-index:1; padding:20px 10px 8px;
  background:linear-gradient(transparent,rgba(20,14,8,.68));
}
.photo-slot.ps-has .ps-label strong{ color:#f8f1e2; text-shadow:0 1px 3px rgba(0,0,0,.5); }
.photo-slot.ps-has .ps-label span{ display:none; }
/* Variante compacte, insérée dans une carte (« lieux » de la page Jeunes) */
.photo-slot--inline{ max-width:340px; margin-top:12px; }
@media print { .photo-slot:not(.ps-has){ display:none !important; } }

/* Figures ↔ arbre généalogique public */
.fig-tree{
  display:inline-block; margin-top:12px; padding:5px 12px;
  border:1px solid rgba(46,111,94,.4); border-radius:999px;
  font-size:.8rem; text-decoration:none; color:var(--c-jade,#2e6f5e);
  background:rgba(46,111,94,.07);
}
.fig-tree:hover{ background:rgba(46,111,94,.14); }
/* Figure ↔ page de son œuvre (recueil de poèmes) — même gabarit que .fig-tree,
   teinte or pour distinguer le lien littéraire du lien vers l'arbre. */
.fig-works{
  display:inline-block; margin-top:12px; margin-left:8px; padding:5px 12px;
  border:1px solid rgba(169,128,58,.4); border-radius:999px;
  font-size:.8rem; text-decoration:none; color:var(--c-or,#a9803a);
  background:rgba(169,128,58,.07);
}
.fig-works:hover{ background:rgba(169,128,58,.14); }
/* État civil d'une figure, issu du gia phả (naissance, décès, sépulture, đời). */
.fig-facts{
  margin:16px 0 4px; padding:12px 14px; display:grid; gap:6px;
  border-left:3px solid rgba(169,128,58,.35);
  background:rgba(169,128,58,.05); border-radius:0 8px 8px 0;
}
.fig-facts .fig-fact{ display:flex; gap:10px; flex-wrap:wrap; align-items:baseline; }
.fig-facts dt{
  flex:0 0 8.5rem; font-size:.74rem; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-soft,#8a7768);
}
.fig-facts dd{ margin:0; flex:1 1 12rem; min-width:0; font-size:.92rem; }
@media(max-width:520px){ .fig-facts dt{ flex-basis:100%; } }
.fig.fig-hit{
  outline:2px solid var(--c-or,#a9803a); outline-offset:3px;
  animation:fig-hit-fade 2.4s ease 1.2s forwards;
}
@keyframes fig-hit-fade{ to{ outline-color:transparent; } }

/* Fiches figures : titre cliquable, lien « Lire la fiche », page détail */
.fig .nm a, .fig h2 a{ color:inherit; text-decoration:none; }
.fig .nm a:hover, .fig h2 a:hover{ text-decoration:underline; text-underline-offset:3px; }
.fig-more{
  display:inline-block; margin-top:10px; margin-right:10px;
  font-family:var(--f-sans); font-size:.82rem; font-weight:600;
  color:var(--c-or,#a9803a); text-decoration:none;
}
.fig-more:hover{ text-decoration:underline; text-underline-offset:3px; }
.fig-back{
  display:inline-block; margin-bottom:18px; font-family:var(--f-sans);
  font-size:.85rem; color:var(--c-or,#a9803a); text-decoration:none;
}
.fig-back:hover{ text-decoration:underline; text-underline-offset:3px; }
.fig-detail{ max-width:760px; }
.fig-detail .fig-era{ font-family:var(--f-sans); letter-spacing:.06em; text-transform:uppercase; font-size:.8rem; color:var(--c-or,#a9803a); }
.fig-detail .fig-role{ font-weight:600; margin:2px 0 14px; }
.fig-detail .fig-bio{ font-size:1.05rem; line-height:1.7; }

/* Utilitaire : empêche la coupure de ligne (remplace <nobr> non standard). */
.nowrap { white-space: nowrap; }

/* ══════════════════════════════════════════════════════════════════
   ORNEMENTS & ILLUSTRATIONS — bibliothèque assets/ornements.svg
   (monochrome currentColor : la couleur se règle ici, par contexte)
   ══════════════════════════════════════════════════════════════════ */

/* Séparateur lotus sous l'introduction d'une section */
.orn-divider { color: var(--c-or); margin: 2px 0 4px; line-height: 0; }
.orn-divider svg { width: 152px; height: 26px; }

/* Emblème thématique du bandeau de section (flotte à droite du titre) */
.sec-emblem {
  float: right; width: clamp(54px, 8vw, 80px); height: clamp(54px, 8vw, 80px);
  color: var(--c-or); opacity: .38; margin: 6px 0 10px 18px;
}
#genealogie .sec-emblem { color: var(--c-or-soft); }
@media (max-width: 560px) { .sec-emblem { width: 48px; height: 48px; } }

/* État vide illustré (agenda, galerie, actualités) */
.act-empty {
  margin-top: 32px; padding: 44px 36px; text-align: center;
  border: 1px dashed var(--c-ligne, #cdbfa6); border-radius: 14px;
  color: var(--c-sepia, #7a6a58); background: rgba(176, 141, 87, .04);
}
.act-empty strong {
  display: block; font-family: var(--f-serif, Georgia, serif);
  font-size: 1.1rem; color: var(--c-laque, #9a2b21); margin-bottom: 8px;
}
.act-empty .orn-vide {
  display: block; width: 62px; height: 62px; margin: 0 auto 12px;
  color: var(--c-or); opacity: .7;
}
.act-empty a {
  color: var(--c-laque, #9a2b21); font-weight: 600;
  text-decoration: none; border-bottom: 1px dotted currentColor;
}
.act-empty a:hover { color: var(--c-or, #a9803a); }

/* Vignette d'album sans photo : monts + sceau (au lieu du seul 丁) */
.gal-cover-ph { position: relative; background: linear-gradient(180deg, var(--c-ivoire-3), var(--c-ivoire-2)); }
.gal-cover-ph .ph-monts {
  position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 48%;
  color: var(--c-or); opacity: .3;
}
.gal-cover-ph span { position: relative; }

/* Médaillon-sceau des cartes de figures */
.fig-seal {
  position: absolute; top: -10px; right: -10px;
  width: 92px; height: 92px; color: var(--c-or); opacity: .12;
  transform: rotate(-6deg);
  transition: opacity .24s var(--ease), transform .24s var(--ease);
  pointer-events: none;
}
.fig:hover .fig-seal { opacity: .26; transform: rotate(-2deg); }
.fig-seal svg { width: 100%; height: 100%; }

/* Crête de montagnes en transition vers le pied de page */
.foot-ridge {
  display: block; width: 100%; height: clamp(36px, 6vw, 72px);
  color: var(--c-encre-2); margin-top: var(--sp-16); line-height: 0;
}
.foot-ridge svg { width: 100%; height: 100%; display: block; }
.foot-ridge + .site-footer { margin-top: 0; }

/* Bande « photos de famille » (alimentée par le flux galerie) */
.photo-strip { margin-top: var(--sp-12); }
.photo-strip[hidden] { display: none; }
.photo-strip-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 10px;
}
.photo-strip-title {
  font-size: .76rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--c-or); font-weight: 700;
}
.photo-strip-all {
  font-size: .85rem; color: var(--c-laque); text-decoration: none;
  border-bottom: 1px solid rgba(154, 43, 33, .3); white-space: nowrap;
}
.photo-strip-all:hover { border-bottom-color: var(--c-laque); }
.photo-strip-row {
  display: flex; gap: 10px; overflow-x: auto; padding-bottom: 6px;
  scrollbar-width: thin; -webkit-overflow-scrolling: touch;
}
.photo-strip-row a {
  flex: 0 0 auto; width: 138px; height: 100px; border-radius: 10px;
  overflow: hidden; background: var(--c-ivoire-2);
  box-shadow: 0 1px 6px rgba(45, 30, 20, .12);
}
.photo-strip-row img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .3s var(--ease);
}
.photo-strip-row a:hover img { transform: scale(1.06); }
/* Variante sur fond sombre (panneau généalogie) */
#genealogie .photo-strip-title { color: var(--c-or-soft); }
#genealogie .photo-strip-all { color: var(--c-or-pale); border-bottom-color: rgba(232, 213, 163, .35); }

/* ══════════════════════════════════════════════════════════════════
   FIGURES — portraits, outils de recherche/filtre, navigation de fiche
   ══════════════════════════════════════════════════════════════════ */

/* Portrait dans la carte : bandeau encadré en tête (la carte est en flex-column) */
.fig-photo {
  display: block; width: 100%; height: 190px; margin: 2px 0 14px;
  border-radius: 10px; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(169, 128, 58, .45), 0 2px 10px rgba(45, 30, 20, .18);
  background: var(--c-ivoire-2); position: relative; z-index: 1;
}
@media (max-width: 560px) { .fig-photo { height: 165px; } }
.fig-photo img {
  /* contain (et non cover) : la photo s'affiche ENTIÈRE, centrée sur fond
     ivoire — aucun visage coupé, hauteur de bandeau uniforme préservée. */
  width: 100%; height: 100%; object-fit: contain; object-position: center;
  display: block; transition: transform .3s var(--ease);
}
.fig:hover .fig-photo img { transform: scale(1.05); }

/* Portrait de la fiche individuelle */
.fig-detail { overflow: visible; }
.fig-detail .fig-portrait {
  float: right; width: min(260px, 38vw); margin: 0 0 16px 24px;
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(169, 128, 58, .5), 0 10px 30px rgba(45, 30, 20, .22);
  background: var(--c-ivoire-2);
}
.fig-detail .fig-portrait img { width: 100%; display: block; }
@media (max-width: 640px) {
  .fig-detail .fig-portrait { float: none; width: min(300px, 78vw); margin: 0 auto 18px; }
}

/* Navigation entre fiches (précédente / suivante) */
.fig-nav {
  display: flex; justify-content: space-between; gap: 16px; clear: both;
  margin-top: 34px; padding-top: 18px; border-top: 1px solid var(--c-ligne-soft);
}
.fig-nav a {
  max-width: 46%; font-family: var(--f-serif); font-size: 1rem; font-weight: 600;
  color: var(--c-laque); text-decoration: none;
}
.fig-nav a:hover { text-decoration: underline; text-underline-offset: 3px; }
.fig-nav-next { text-align: right; margin-left: auto; }

/* Outils de la rubrique : recherche + compteur + puces d'époque */
.fig-tools { margin: 6px 0 18px; }
.fig-search-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
#fig-search {
  flex: 1 1 240px; max-width: 420px; padding: 10px 14px;
  border: 1px solid var(--c-ligne); border-radius: 999px;
  background: var(--bg-surface, #fff); color: var(--c-encre);
  font-family: var(--f-sans); font-size: .95rem;
}
#fig-search:focus { outline: 2px solid rgba(169, 128, 58, .5); outline-offset: 1px; }
.fig-count-badge {
  font-size: .78rem; font-weight: 700; color: var(--c-or);
  font-variant-numeric: tabular-nums; letter-spacing: .04em; white-space: nowrap;
}
.fig-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.fig-chip {
  border: 1px solid var(--c-ligne); background: var(--bg-surface, #fff);
  color: var(--c-sepia); border-radius: 999px; padding: 5px 13px;
  font-family: var(--f-sans); font-size: .8rem; cursor: pointer;
  transition: border-color .18s var(--ease), color .18s var(--ease), background .18s var(--ease);
}
.fig-chip:hover { border-color: var(--c-or); color: var(--c-encre); }
.fig-chip.on { background: var(--c-laque); border-color: var(--c-laque); color: #fff; font-weight: 600; }
/* Pastille d'époque lisible au-dessus d'un portrait */
.fig .era { background: rgba(248, 241, 226, .92); z-index: 2; }

/* ══════════════════════════════════════════════════════════════════
   §GD — Démo animée de l'éditeur généalogique (page Généalogie).
   Le DOM vit dans views/genealogie.html ; gen-demo.js orchestre.
   ══════════════════════════════════════════════════════════════════ */
.gen-secnav{display:flex;flex-wrap:wrap;gap:10px;margin:6px 0 18px}
.gen-secnav a{font-size:.85rem;font-weight:600;color:var(--c-laque,#9a2b21);text-decoration:none;
  border:1px solid var(--c-ligne,#cdbfa6);border-radius:20px;padding:6px 14px;background:rgba(255,255,255,.55);
  transition:border-color .15s,color .15s}
.gen-secnav a:hover{border-color:var(--c-or,#a9803a);color:var(--c-or,#a9803a)}

.gd-wrap{scroll-margin-top:80px}
/* La démo vit dans la colonne gauche du panneau sombre « Éditeur GEDCOM 5.5.1 ». */
.gen-panel .gd-wrap{margin:0 0 var(--sp-8)}
/* Conteneur d'échelle : le cadre est dessiné à 1000px puis réduit à la largeur disponible
   (gen-demo.js pose le scale et la hauteur ; sans JS le cadre est simplement rogné). */
.gd-scale{position:relative;width:100%;overflow:hidden;border-radius:14px}
.gd-scale .gd-frame{width:1000px;max-width:none;transform-origin:0 0}
.gen-panel .gd-caption{flex-wrap:wrap}
.gen-panel .gd-captext{color:#d9cdb8}
.gen-panel .gd-cap b{color:#e6d3a3}
.gen-panel .gd-ctrl button{background:rgba(255,255,255,.07);border-color:rgba(198,165,103,.4);color:#e9dfc9}
.gen-panel .gd-ctrl button:hover{border-color:var(--c-or-soft,#c6a567)}
.gen-panel .gd-dots i{background:rgba(233,223,201,.28)}
.gen-panel .gd-dots i.on{background:var(--c-or-soft,#c6a567)}
.gd-frame{position:relative;width:100%;aspect-ratio:16/10;background:#f7f2e8;border:1px solid var(--c-ligne,#d9cbb2);
  border-radius:14px;overflow:hidden;box-shadow:0 3px 12px rgba(60,40,20,.14),inset 0 1px 0 #fff}
.gd-bar{position:absolute;inset:0 0 auto 0;height:44px;background:#2b211b;display:flex;align-items:center;gap:9px;padding:0 14px;z-index:5}
.gd-seal{color:#e8d5a3;font-family:var(--f-serif);font-weight:700;font-size:1.15rem}
.gd-ttl{color:#e9dfc9;font-size:.84rem;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gd-sp{flex:1}
.gd-bbtn{background:rgba(255,255,255,.09);border:1px solid rgba(255,255,255,.16);color:#e9dfc9;
  font-size:.72rem;font-weight:600;border-radius:7px;padding:5px 9px;white-space:nowrap}
.gd-bbtn.accent{background:var(--c-or,#a9803a);border-color:var(--c-or,#a9803a);color:#fff}
.gd-search{position:absolute;top:54px;left:14px;z-index:5;width:240px;height:30px;background:#fff;border:1px solid var(--c-ligne,#d9cbb2);
  border-radius:8px;display:flex;align-items:center;gap:7px;padding:0 9px;font-size:.8rem;color:var(--c-sepia,#7a6a58)}
.gd-q{color:#2b2b2b;font-weight:600;white-space:pre}
.gd-caret{width:1.5px;height:14px;background:var(--c-laque,#9a2b21);animation:gd-blink 1s steps(1) infinite}
@keyframes gd-blink{50%{opacity:0}}
.gd-sres{position:absolute;top:88px;left:14px;z-index:5;width:240px;background:#fff;border:1px solid var(--c-ligne,#d9cbb2);border-radius:8px;
  box-shadow:0 4px 12px rgba(60,40,20,.14);font-size:.78rem;overflow:hidden;opacity:0;transform:translateY(-4px);transition:.25s}
.gd-sres.on{opacity:1;transform:none}
.gd-sres div{padding:7px 10px;border-bottom:1px solid #f0e8d8}
.gd-sres div:last-child{border-bottom:0}
.gd-sres .hit{background:rgba(169,128,58,.14);font-weight:700}
.gd-sres small{color:var(--c-sepia,#7a6a58);font-weight:400}
.gd-stage{position:absolute;inset:44px 0 0 0;overflow:hidden;background:radial-gradient(1100px 480px at 60% -80px,#fffdf6,#f7f2e8)}
.gd-world{position:absolute;inset:0;transform-origin:470px 250px;transition:transform 1.6s cubic-bezier(.4,.1,.2,1)}
.gd-links{position:absolute;inset:0;width:100%;height:100%}
.gd-links line{stroke:var(--c-ligne,#d9cbb2);stroke-width:2}
.gd-links line.new{stroke:var(--c-or,#a9803a);stroke-dasharray:60;stroke-dashoffset:60;transition:stroke-dashoffset .8s .1s}
.gd-frame.s-new .gd-links line.new{stroke-dashoffset:0}
.gd-node{position:absolute;width:148px;padding:7px 10px 6px;background:#fff;border:1.5px solid var(--c-or,#a9803a);border-radius:9px;
  box-shadow:0 1px 4px rgba(60,40,20,.10);transition:box-shadow .3s,border-color .3s,opacity .5s,transform .5s;text-align:center}
.gd-node b{display:block;font-size:.76rem;color:#2b2b2b;line-height:1.25}
.gd-node span{font-size:.66rem;color:var(--c-sepia,#7a6a58)}
.gd-node .gd-gen{position:absolute;top:-9px;left:8px;background:var(--c-or,#a9803a);color:#fff;font-size:.56rem;font-weight:700;
  border-radius:8px;padding:1px 6px;letter-spacing:.03em}
.gd-node.focus{border-color:var(--c-laque,#9a2b21);box-shadow:0 0 0 4px rgba(154,43,33,.18),0 2px 8px rgba(60,40,20,.18)}
.gd-node.kin{border-color:#2f6f7d;box-shadow:0 0 0 4px rgba(47,111,125,.20)}
.gd-node.ghost{opacity:0;transform:translateY(12px)}
.gd-frame.s-new .gd-node.ghost{opacity:1;transform:none}
.gd-node.ghost i{font-style:normal;color:var(--c-or,#a9803a);font-weight:700;font-size:.7rem}
.gd-panel{position:absolute;top:54px;right:12px;bottom:12px;width:290px;background:#fff;border:1px solid var(--c-ligne,#d9cbb2);
  border-radius:12px;box-shadow:-4px 4px 18px rgba(60,40,20,.13);z-index:6;padding:12px 13px;
  transform:translateX(112%);transition:transform .5s cubic-bezier(.35,.1,.25,1);overflow:hidden;font-size:.78rem}
.gd-frame.panel-on .gd-panel{transform:none}
.gd-phead{display:flex;align-items:center;justify-content:space-between;gap:8px}
.gd-phead h4{margin:0;font-family:var(--f-serif);color:var(--c-laque,#9a2b21);font-size:1rem}
.gd-plang{display:inline-flex;gap:3px}
.gd-plang button{border:1px solid var(--c-ligne,#d9cbb2);background:#fff;border-radius:6px;font-size:.62rem;font-weight:700;
  padding:2px 6px;color:var(--c-sepia,#7a6a58)}
.gd-plang button.on{background:var(--c-laque,#9a2b21);border-color:var(--c-laque,#9a2b21);color:#fff}
.gd-pgen{color:var(--c-sepia,#7a6a58);font-size:.68rem;margin:2px 0 8px}
.gd-portrait{display:flex;align-items:center;gap:9px;margin:0 0 8px}
.gd-pph{width:44px;height:44px;border-radius:9px;border:1.5px dashed var(--c-ligne,#cdbfa6);display:flex;align-items:center;justify-content:center;
  font-family:var(--f-serif);color:var(--c-or,#a9803a);font-size:1.15rem;background:#fdfcf9;transition:border-color .3s,background .3s}
.gd-frame.s-portrait .gd-pph{border-style:solid;border-color:var(--c-or,#a9803a);background:rgba(169,128,58,.12)}
.gd-pbtn{font-size:.68rem;font-weight:700;color:var(--c-sepia,#7a6a58);border:1px solid var(--c-ligne,#d9cbb2);border-radius:6px;padding:3px 8px}
.gd-frame.s-portrait .gd-pbtn{color:#fff;background:var(--c-or,#a9803a);border-color:var(--c-or,#a9803a)}
.gd-pf{margin:6px 0}
.gd-pf label{display:block;font-size:.58rem;font-weight:700;letter-spacing:.05em;color:var(--c-or,#a9803a);text-transform:uppercase;margin-bottom:2px}
.gd-val{border:1px solid #eadfc9;border-radius:6px;padding:4px 7px;background:#fdfcf9;min-height:15px}
.gd-val.edit{border-color:var(--c-laque,#9a2b21);box-shadow:0 0 0 3px rgba(154,43,33,.12)}
.gd-typed{white-space:pre}
.gd-note{font-size:.68rem;color:var(--c-sepia,#7a6a58);line-height:1.45;border-left:3px solid #e8d5a3;padding-left:8px;margin-top:8px}
.gd-pbtns{display:flex;gap:6px;margin-top:9px}
.gd-pbtns span{flex:1;text-align:center;font-size:.7rem;font-weight:700;border-radius:7px;padding:5px 0;border:1px solid var(--c-ligne,#d9cbb2);color:var(--c-sepia,#7a6a58)}
.gd-pbtns .save{background:var(--c-laque,#9a2b21);border-color:var(--c-laque,#9a2b21);color:#fff}
.gd-kin{position:absolute;left:50%;top:56%;transform:translate(-50%,-50%) scale(.85);z-index:7;background:#243138;color:#eef4f5;
  border-radius:12px;padding:12px 17px;font-size:.82rem;box-shadow:0 8px 26px rgba(0,0,0,.28);opacity:0;transition:.4s;text-align:center;pointer-events:none}
.gd-kin.on{opacity:1;transform:translate(-50%,-50%) scale(1)}
.gd-kin b{color:#9fd1de}
.gd-toast{position:absolute;left:50%;bottom:14px;transform:translateX(-50%) translateY(8px);z-index:8;background:#2f7d3f;color:#fff;
  font-size:.78rem;font-weight:600;border-radius:20px;padding:7px 15px;opacity:0;transition:.35s;pointer-events:none;white-space:nowrap}
.gd-toast.on{opacity:1;transform:translateX(-50%)}
.gd-cur{position:absolute;z-index:9;width:22px;height:22px;left:-40px;top:-40px;pointer-events:none;
  transition:left .55s cubic-bezier(.4,.1,.25,1),top .55s cubic-bezier(.4,.1,.25,1);filter:drop-shadow(0 1px 1.5px rgba(0,0,0,.4))}
.gd-cur.click{transform:scale(.82)}
.gd-caption{display:flex;align-items:center;gap:12px;margin-top:12px}
.gd-stepnum{flex:none;width:30px;height:30px;border-radius:50%;background:var(--c-laque,#9a2b21);color:#fff;display:flex;
  align-items:center;justify-content:center;font-weight:800;font-size:.9rem}
.gd-captext{flex:1;font-size:.92rem;line-height:1.4;min-height:2.6em}
.gd-cap{display:none}
.gd-cap.on{display:inline}
.gd-cap b{color:var(--c-laque,#9a2b21)}
.gd-ctrl{flex:none;display:flex;gap:8px}
.gd-ctrl button{border:1px solid var(--c-ligne,#d9cbb2);background:#fff;border-radius:8px;font:600 .8rem/1 inherit;padding:8px 12px;cursor:pointer;color:#2b2b2b}
.gd-ctrl button:hover{border-color:var(--c-or,#a9803a)}
.gd-pause .p-off{display:none}
.gd-pause.paused .p-on{display:none}
.gd-pause.paused .p-off{display:inline}
.gd-dots{display:flex;gap:5px;margin-top:8px}
.gd-dots i{width:8px;height:8px;border-radius:50%;background:#d8ccb4;transition:.3s}
.gd-dots i.on{background:var(--c-laque,#9a2b21);transform:scale(1.25)}
@media (max-width:760px){
  .gd-frame{aspect-ratio:4/3}
  .gd-panel{width:230px}
  .gd-bbtn{font-size:.6rem;padding:4px 6px}
  .gd-caption{flex-wrap:wrap}
}
@media (prefers-reduced-motion: reduce){
  .gd-world,.gd-panel,.gd-cur,.gd-sres{transition:none}
  .gd-caret{animation:none}
}
