/* ═══════════════════════════════════════════════════════════════════
   KOREAN STORIES — Design System v3
   Source unique de vérité pour tout le site.
   Chargé en premier par toutes les pages.
═══════════════════════════════════════════════════════════════════ */

/* ── TOKENS ──────────────────────────────────────────────────────── */
:root {
  --bg:#EEF2FB; --surf:#FFF; --s2:#F5F8FF; --s3:#E9EEFA;
  --t:#0D1823; --t2:#475E78; --t3:#8FA5BE;
  --bd:#DAE3F2; --bd2:#BFCEE6;
  --sh:0 2px 12px rgba(15,30,80,.07);
  --sh2:0 6px 28px rgba(15,30,80,.11);
  --sh3:0 16px 48px rgba(15,30,80,.14);
  --bar:rgba(255,255,255,.95);
  --side:rgba(255,255,255,.99);
  --gold:#B8924E; --goldl:#CAA96E; --gold-light:#CAA96E; --gl:#CAA96E; --goldbg:#FBF2E3; --goldbd:#E0CBA0;
  /* WCAG AA — variante accessible pour texte sur fond clair (ratio 4.92:1 sur #FFFFFF). */
  --gold-text:#8B6B3D;
  --navy:#0F1B2D;
  --r:14px; --rl:20px; --rxl:26px;
  --tr:.18s cubic-bezier(.4,0,.2,1);
  /* Compat */
  --navy2:#1a2f4a; --pure:#FFF; --white:#EEF2FB;
  --border:#DAE3F2; --border2:#BFCEE6;
  --gray:#8FA5BE; --shadow:0 6px 28px rgba(15,30,80,.11);
  --green:#22c55e; --red:#ef4444; --amber:#f59e0b; --purple:#a78bfa;
  --pink:#FF8EA8;
  --goldp:rgba(184,146,78,.10); --gold2:#E0CBA0;
  /* Text aliases */
  --tx:#0D1823; --tx-muted:#475E78;
  --text:#0D1823; --text2:#475E78; --text3:#8FA5BE;
  /* Opacity text variants */
  --t35:rgba(13,24,35,.35); --t40:rgba(13,24,35,.40); --t45:rgba(13,24,35,.45);
  --t50:rgba(13,24,35,.50); --t60:rgba(13,24,35,.60); --t70:rgba(13,24,35,.70); --t80:rgba(13,24,35,.80);
  /* Background aliases */
  --bg2:#F5F8FF; --bg3:#E9EEFA;
  --navy3:#0F1B2D; --navy2:#1a2f4a;
  /* UI component vars */
  --ms-ring:rgba(184,146,78,.30);
  --overlay-bg:rgba(0,0,0,.45);
  --toast-bg:#FFF;
  --subtle:#E9EEFA;
  --cw-num-color:#8FA5BE;
  --ws-cell-text:#0D1823;
}
[data-theme=dark] {
  --bg:#0B1522; --surf:#152030; --s2:#192840; --s3:#1C3050;
  --t:#EDF2FA; --t2:#8293A8; --t3:#445A70;
  --bd:rgba(255,255,255,.07); --bd2:rgba(255,255,255,.13);
  --sh:0 2px 12px rgba(0,0,0,.4); --sh2:0 6px 28px rgba(0,0,0,.5); --sh3:0 16px 48px rgba(0,0,0,.6);
  --bar:rgba(11,21,34,.96); --side:rgba(13,24,38,.99);
  --gold:#C9A86C; --goldl:#D5BA8A; --gold-light:#D5BA8A; --gl:#D5BA8A; --goldbg:rgba(201,168,108,.1); --goldbd:rgba(201,168,108,.25);
  /* WCAG AA — sur fonds sombres on peut éclaircir l'or pour le texte (ratio >7:1 sur #0F1B2D). */
  --gold-text:#D5BA8A;
  --white:#0B1522; --pure:#152030; --border:rgba(255,255,255,.07); --border2:rgba(255,255,255,.13);
  --gray:#445A70; --shadow:0 6px 28px rgba(0,0,0,.5); --goldp:rgba(201,168,108,.12);
  --pink:#FF8EA8;
  /* Text aliases */
  --tx:#EDF2FA; --tx-muted:#8293A8;
  --text:#EDF2FA; --text2:#8293A8; --text3:#445A70;
  /* Opacity text variants */
  --t35:rgba(237,242,250,.35); --t40:rgba(237,242,250,.40); --t45:rgba(237,242,250,.45);
  --t50:rgba(237,242,250,.50); --t60:rgba(237,242,250,.60); --t70:rgba(237,242,250,.70); --t80:rgba(237,242,250,.80);
  /* Background aliases */
  --bg2:#192840; --bg3:#1C3050;
  --navy3:#0B1522; --navy2:#152030;
  /* UI component vars */
  --ms-ring:rgba(201,168,108,.30);
  --overlay-bg:rgba(0,0,0,.65);
  --toast-bg:#152030;
  --subtle:#1C3050;
  --cw-num-color:#445A70;
  --ws-cell-text:#EDF2FA;
}

/* ── RESET ────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  font-family:'Inter',system-ui,-apple-system,sans-serif;
  background:var(--bg);color:var(--t);
  -webkit-font-smoothing:antialiased;overflow-x:hidden;min-height:100svh;
  transition:background .25s,color .25s;
  padding-bottom:calc(24px + env(safe-area-inset-bottom));
}
a{text-decoration:none;color:inherit;-webkit-tap-highlight-color:transparent}
button{font-family:inherit;border:none;cursor:pointer;-webkit-tap-highlight-color:transparent}
input,textarea,select{
  font-family:inherit;background:var(--surf);color:var(--t);
  border:1.5px solid var(--bd);border-radius:var(--r);
  transition:background var(--tr),border-color var(--tr),color var(--tr);
}
input:focus,textarea:focus,select:focus{outline:none;border-color:var(--gold)}

/* ── Micro-animations globales ────────────────────────────────────
   Transitions universelles sur les propriétés thématiques : quand
   l'utilisateur bascule en sombre, toutes les couleurs glissent
   en douceur au lieu de flasher. */
html, body, body *, body *::before, body *::after {
  transition-property: background-color, border-color, color, fill, stroke, box-shadow;
  transition-duration: .22s;
  transition-timing-function: cubic-bezier(.4, 0, .2, 1);
}
/* Désactivation ciblée pour les éléments où la transition de couleur
   nuit (overlays animés, spinners, éléments en transform constant) */
.ksf-confetti *, .ksf-conf-p, .ks-conf, #ks-onb-root *,
.ks-swu-banner *, .ks-inst-banner *, #streakWarn .sw-flame {
  transition: none !important;
}

/* ── Feedback tactile / press ─────────────────────────────────────
   Léger scale-down au clic pour signaler que l'action est prise.
   Préserve l'a11y (pas de flicker, durée <100ms). */
.scard:active,
.bni:active,
button:not(:disabled):active,
.btn-primary:active,
.btn-ghost:active,
a.scard:active {
  transform: scale(.97);
  transition: transform .08s ease-out;
}

/* ── Stagger sur grilles ─────────────────────────────────────────
   Apparition échelonnée des cards (animation-delay calculée
   sur l'ordre dans le parent). Joue UNE SEULE FOIS au load
   grâce à animation-fill-mode:both. */
@keyframes ksFadeUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.sec-grid .scard {
  animation: ksFadeUp .42s cubic-bezier(.4, 0, .2, 1) both;
}
.sec-grid .scard:nth-child(1){animation-delay:.05s}
.sec-grid .scard:nth-child(2){animation-delay:.10s}
.sec-grid .scard:nth-child(3){animation-delay:.15s}
.sec-grid .scard:nth-child(4){animation-delay:.20s}
.sec-grid .scard:nth-child(5){animation-delay:.25s}
.sec-grid .scard:nth-child(6){animation-delay:.30s}
.sec-grid .scard:nth-child(7){animation-delay:.35s}
.sec-grid .scard:nth-child(8){animation-delay:.40s}

/* ── Reduce motion : on respecte le système ──────────────────────
   Tout utilisateur qui demande à réduire les animations dans
   ses préférences voit ces animations désactivées. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ── Smooth scroll ──────────────────────────────────────────────── */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ── Hover lift sur les cards de l'accueil ───────────────────────
   Léger soulèvement + ombre + accentuation de bordure or au survol.
   Désactivé sur les périphériques tactiles (pas de hover physique). */
@media (hover: hover) {
  .scard {
    transition: transform .22s cubic-bezier(.4, 0, .2, 1),
                box-shadow .22s cubic-bezier(.4, 0, .2, 1),
                border-color .22s cubic-bezier(.4, 0, .2, 1);
  }
  .scard:hover:not(.locked) {
    transform: translateY(-3px);
    box-shadow: 0 10px 28px rgba(15, 30, 80, .10);
    border-color: rgba(201, 169, 110, .35);
  }
  [data-theme="dark"] .scard:hover:not(.locked) {
    box-shadow: 0 10px 28px rgba(0, 0, 0, .35);
    border-color: rgba(213, 186, 138, .35);
  }
}

/* ── Pulse sur le streak quand il est élevé ──────────────────────
   Le bouton « 7+ jours » mérite un petit signal visuel. La classe
   .streak-hot est ajoutée via JS quand streak ≥ 7. */
@keyframes ksStreakPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.08); }
}
.streak-val.streak-hot,
.side-xp.streak-hot {
  display: inline-block;
  animation: ksStreakPulse 2.6s ease-in-out infinite;
  transform-origin: center;
}

/* ── Fade-in sur le contenu des <details> à l'ouverture ──────────
   Touch de fluidité sur les FAQ de aide.html, et tout autre
   widget repliable du site. */
details[open] > *:not(summary) {
  animation: ksDetailsSlide .28s cubic-bezier(.4, 0, .2, 1) both;
}
@keyframes ksDetailsSlide {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* ── Page entry fade-in (root crossfade fallback) ────────────────
   Pour les navigateurs qui ne supportent pas View Transitions :
   léger fade-in au load pour adoucir l'arrivée sur la page. */
@keyframes ksBodyEnter {
  from { opacity: .6; }
  to   { opacity: 1; }
}
body { animation: ksBodyEnter .22s ease-out both; }
/* On retire l'anim si VT est actif (Chrome 126+ gère lui-même la transition) */
@supports (view-transition-name: root) {
  body { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  body { animation: none; }
}

/* ── View Transitions API — fluide entre pages ────────────────────
   Chrome 126+ / Edge 126+ : crossfade automatique au clic sur lien
   interne (cross-document). Safari/Firefox : fail gracefully (saut
   instantané comme avant). Pas de polyfill nécessaire.
   La balise <meta name="view-transition" content="same-origin"> est
   injectée par ks.js sur toutes les pages. */
@view-transition {
  navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: .35s;
  animation-timing-function: cubic-bezier(.4, 0, .2, 1);
}
/* Crossfade par défaut (Chrome fait déjà ça mais on s'assure du timing) */
::view-transition-old(root) { animation-name: ksFadeOut; }
::view-transition-new(root) { animation-name: ksFadeIn; }
@keyframes ksFadeOut { to { opacity: 0; } }
@keyframes ksFadeIn  { from { opacity: 0; } }

/* Si l'utilisateur a demandé la réduction du mouvement, on coupe */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none !important;
  }
}

/* ── Skeleton loading (shimmer) ──────────────────────────────────
   Placeholder gris animé qui glisse de gauche à droite pendant
   que les données réelles se chargent (XP depuis Firestore, cards
   piloted par KSCurriculum, etc.). Évite le flash 0 → vraie valeur
   et donne une perception de fluidité. */
@keyframes ksShimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.ks-skel {
  display: inline-block;
  background: linear-gradient(
    90deg,
    rgba(143,165,190,0.08) 0%,
    rgba(143,165,190,0.18) 50%,
    rgba(143,165,190,0.08) 100%
  );
  background-size: 200% 100%;
  animation: ksShimmer 1.4s ease-in-out infinite;
  border-radius: 6px;
  color: transparent !important;
  user-select: none;
  pointer-events: none;
  min-height: 1em;
}
[data-theme="dark"] .ks-skel {
  background: linear-gradient(
    90deg,
    rgba(255,255,255,0.04) 0%,
    rgba(255,255,255,0.10) 50%,
    rgba(255,255,255,0.04) 100%
  );
  background-size: 200% 100%;
}
/* Variantes : bloc, ligne, badge */
.ks-skel-line  { width: 70%; height: .9em; }
.ks-skel-block { width: 100%; height: 1.6em; border-radius: 8px; }
.ks-skel-pill  { width: 4em; height: 1.1em; border-radius: 100px; }
.ks-skel-bar   { width: 100%; height: 100%; border-radius: 5px 5px 2px 2px; }

@media (prefers-reduced-motion: reduce) {
  .ks-skel { animation: none; background: rgba(143,165,190,0.12); }
  [data-theme="dark"] .ks-skel { background: rgba(255,255,255,0.06); }
}

/* ── A11Y : focus visible clavier ─────────────────────────────────
   :focus-visible cible uniquement la navigation clavier — pas les
   clics souris — ce qui évite l'anneau permanent agaçant tout en
   gardant un repère clair pour les utilisateurs clavier/lecteur. */
a:focus,button:focus,[role="button"]:focus,[tabindex]:focus{outline:none}
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible{
  outline:2.5px solid var(--gold);
  outline-offset:2px;
  border-radius:6px;
}
/* Sur fonds très foncés (navy, bnav) on bascule sur un anneau or clair */
.bar a:focus-visible,.bar button:focus-visible,
.bnav a:focus-visible,
.sidenav a:focus-visible{
  outline-color:#D4B582;
  outline-offset:3px;
}
/* Skip-link générique — invisible jusqu'au focus clavier */
.ks-skip-link{
  position:absolute;left:8px;top:-40px;background:var(--navy);color:#fff;
  padding:8px 14px;border-radius:8px;font-size:13px;font-weight:700;
  z-index:99999;text-decoration:none;transition:top .2s;
}
.ks-skip-link:focus{top:8px}

/* ── LAYOUT SHELL ─────────────────────────────────────────────────── */
.shell{display:flex;min-height:100svh}
.main{flex:1;min-width:0;display:flex;flex-direction:column}

/* ── SIDEBAR ─────────────────────────────────────────────────────── */
.side{
  display:none;width:252px;flex-shrink:0;
  background:var(--side);border-right:1.5px solid var(--bd);
  position:sticky;top:0;height:100svh;
  overflow-y:auto;overflow-x:hidden;
  flex-direction:column;z-index:60;
  scrollbar-width:thin;scrollbar-color:var(--bd) transparent;
  transition:background var(--tr),border-color var(--tr);
}
.side::-webkit-scrollbar{width:3px}
.side::-webkit-scrollbar-thumb{background:var(--bd2);border-radius:2px}

.side-head{
  padding:20px 18px 16px;
  border-bottom:1.5px solid var(--bd);
  display:flex;align-items:center;gap:10px;
  transition:border-color var(--tr);
}
.side-logo{
  flex:1;font-family:'Playfair Display',serif;font-size:16px;font-weight:700;color:var(--t);
}
.side-logo em{color:var(--gold);font-style:italic}
.side-xp{
  display:flex;align-items:center;gap:4px;padding:4px 10px;
  background:var(--goldbg);border:1.5px solid var(--goldbd);border-radius:100px;
  font-size:11px;font-weight:800;color:var(--gold);white-space:nowrap;
  transition:background var(--tr),border-color var(--tr);
}
.side-xp svg{width:9px;height:9px;fill:var(--gold)}

.side-nav{padding:10px 10px 6px;display:flex;flex-direction:column;gap:1px}
.sn{
  display:flex;align-items:center;gap:10px;padding:9px 12px;
  border-radius:10px;font-size:13px;font-weight:600;color:var(--t2);
  transition:all var(--tr);text-decoration:none;
}
.sn:hover{background:var(--s2);color:var(--t)}
.sn.on{background:var(--goldbg);color:var(--gold);font-weight:700}
.sn svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}

.side-block{padding:14px 10px 6px;border-top:1.5px solid var(--bd);transition:border-color var(--tr)}
.side-lbl{font-size:9px;font-weight:900;letter-spacing:.12em;text-transform:uppercase;color:var(--t3);margin-bottom:8px;padding:0 8px}

.side-theme{
  margin:auto 18px 18px;
  display:flex;align-items:center;justify-content:space-between;
  padding:10px 14px;background:var(--s2);border-radius:10px;
  border:1.5px solid var(--bd);
  transition:background var(--tr),border-color var(--tr);
}
.side-theme-lbl{font-size:12px;font-weight:600;color:var(--t2)}
.theme-pill{
  width:44px;height:24px;border-radius:100px;
  background:var(--bd2);position:relative;cursor:pointer;
  transition:background var(--tr);border:none;flex-shrink:0;
}
[data-theme=dark] .theme-pill{background:var(--gold)}
.theme-pill::after{
  content:'';position:absolute;top:3px;left:3px;
  width:18px;height:18px;border-radius:50%;background:#fff;
  transition:transform var(--tr);box-shadow:0 1px 4px rgba(0,0,0,.2);
}
[data-theme=dark] .theme-pill::after{transform:translateX(20px)}

/* ── GLASS TOPBAR (.bar) ─────────────────────────────────────────── */
.bar{
  position:sticky;top:0;z-index:100;height:56px;
  padding:0 16px;display:flex;align-items:center;gap:12px;
  background:var(--bar);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  border-bottom:1.5px solid var(--bd);
  transition:background var(--tr),border-color var(--tr);
  flex-shrink:0;
}
.bar-back{
  display:flex;align-items:center;gap:5px;padding:7px 13px;
  border-radius:100px;border:1.5px solid var(--bd2);
  font-size:12px;font-weight:700;color:var(--t2);
  text-decoration:none;
  transition:all var(--tr);flex-shrink:0;
}
.bar-back:hover{color:var(--gold);border-color:var(--goldbd)}
.bar-back svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round}
.bar-logo{
  position:absolute;left:50%;transform:translateX(-50%);
  font-family:'Playfair Display',serif;font-size:15px;font-weight:700;
  color:var(--t);pointer-events:none;white-space:nowrap;
}
.bar-logo em{color:var(--gold);font-style:italic}
.bar-r{display:flex;align-items:center;gap:8px;flex-shrink:0;margin-left:auto}
.bar-theme{
  width:34px;height:34px;border-radius:50%;
  background:var(--s2);border:1.5px solid var(--bd);
  display:flex;align-items:center;justify-content:center;
  transition:border-color var(--tr),background var(--tr);cursor:pointer;
}
.bar-theme:hover{border-color:var(--goldbd)}
.bar-theme svg{width:15px;height:15px;stroke:var(--t2);fill:none;stroke-width:2;stroke-linecap:round}
.ico-d{display:none}.ico-l{display:block}
[data-theme=dark] .ico-d{display:block}[data-theme=dark] .ico-l{display:none}
.bar-xp{
  display:flex;align-items:center;gap:4px;padding:5px 12px;
  background:var(--goldbg);border:1.5px solid var(--goldbd);
  border-radius:100px;font-size:12px;font-weight:800;color:var(--gold);
  text-decoration:none;white-space:nowrap;
  transition:background var(--tr),border-color var(--tr);
}
.bar-xp svg{width:10px;height:10px;fill:var(--gold)}

/* ── SOLID NAVY TOPBAR (.topbar) — content pages ─────────────────── */
.topbar{
  position:sticky;top:0;z-index:100;height:56px;padding:0 18px;
  display:flex;align-items:center;justify-content:space-between;
  background:var(--navy);flex-shrink:0;
}
.tb-back,.back{
  display:flex;align-items:center;gap:6px;padding:7px 14px;
  border-radius:100px;border:1.5px solid rgba(255,255,255,.14);
  background:none;font-size:12px;font-weight:600;
  color:rgba(247,248,250,.6);text-decoration:none;cursor:pointer;
  transition:border-color var(--tr),color var(--tr);
}
.tb-back:hover,.back:hover{border-color:var(--gold);color:var(--gold)}
.tb-back svg,.back svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.tb-title{
  font-family:'Playfair Display',serif;font-size:15px;font-style:italic;
  color:#fff;
}
.tb-right{display:flex;align-items:center;gap:8px}

/* Lesson progress topbar (.tbar) */
.tbar{
  position:sticky;top:0;z-index:100;
  background:var(--surf);border-bottom:1.5px solid var(--bd);
  padding:0 18px;height:56px;
  display:flex;align-items:center;gap:14px;
  flex-shrink:0;
  transition:background var(--tr),border-color var(--tr);
}
.quit{
  width:32px;height:32px;border-radius:50%;
  border:1.5px solid var(--bd);
  display:flex;align-items:center;justify-content:center;
  background:none;cursor:pointer;text-decoration:none;
  transition:border-color var(--tr),background var(--tr);flex-shrink:0;
}
.quit:hover{border-color:var(--gold);background:var(--goldbg)}
.quit svg{width:13px;height:13px;stroke:var(--t3);fill:none;stroke-width:2.5;stroke-linecap:round}
.ptrack{flex:1;height:8px;background:var(--bd);border-radius:100px;overflow:hidden}
.pbar{height:100%;border-radius:100px;background:linear-gradient(90deg,var(--gold),#FFD800);transition:width .5s cubic-bezier(.4,0,.2,1);width:0%}

/* ── PAGE CONTENT ─────────────────────────────────────────────────── */
.page{max-width:620px;margin:0 auto;padding:16px 16px 0;width:100%}
.page-enter{animation:pgIn .35s ease both}
@keyframes pgIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ── CARDS ────────────────────────────────────────────────────────── */
.card,.scard,.content-card{
  background:var(--surf);border:1.5px solid var(--bd);
  border-radius:var(--rl);box-shadow:var(--sh);
  transition:background var(--tr),border-color var(--tr),box-shadow var(--tr);
}
.card:hover,.scard:hover{box-shadow:var(--sh2);border-color:var(--bd2)}

/* ── HERO (navy dark hero for content pages) ──────────────────────── */
.hero-navy{
  background:var(--navy);padding:24px 20px 36px;position:relative;overflow:hidden;
}
.hero-navy::after{
  content:'';position:absolute;bottom:0;left:0;right:0;
  height:32px;background:var(--bg);border-radius:24px 24px 0 0;
}
.hero-navy-inner{max-width:560px;margin:0 auto;position:relative;z-index:1}

/* ── BOTTOM NAV ───────────────────────────────────────────────────── */
.bnav{
  position:fixed;bottom:0;left:0;right:0;z-index:200;
  height:calc(58px + env(safe-area-inset-bottom));
  padding-bottom:env(safe-area-inset-bottom);
  display:flex;align-items:center;justify-content:space-around;padding-top:2px;
  background:rgba(255,255,255,.97);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
  border-top:1.5px solid var(--bd);
  transition:background var(--tr),border-color var(--tr);
}
[data-theme=dark] .bnav{background:rgba(11,21,34,.97)}
.bni{
  display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:6px 12px;border-radius:12px;color:var(--t3);
  text-decoration:none;transition:color var(--tr);position:relative;min-width:44px;
  -webkit-tap-highlight-color:transparent;
}
.bni.act,.bni[aria-current="page"]{color:var(--gold)}
/* État actif signalé par PLUS que la couleur (WCAG 1.4.1) :
   barre dorée en haut de l'onglet + libellé en gras. */
.bni.act::before,.bni[aria-current="page"]::before{
  content:"";position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:24px;height:3px;border-radius:0 0 3px 3px;background:var(--gold);
}
.bni.act span,.bni[aria-current="page"] span{font-weight:800}
.bni:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.bni svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.bni span{font-size:9px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.bni-dot{width:7px;height:7px;border-radius:50%;background:#ef4444;border:1.5px solid var(--surf);position:absolute;top:5px;right:7px}

/* ── BUTTONS ──────────────────────────────────────────────────────── */
.btn-gold{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  background:var(--gold);color:#fff;
  font-family:inherit;font-size:14px;font-weight:700;
  padding:14px 24px;border-radius:100px;border:none;cursor:pointer;
  transition:background var(--tr),transform .1s,box-shadow var(--tr);
  box-shadow:0 4px 16px rgba(184,146,78,.3);
  -webkit-tap-highlight-color:transparent;
}
.btn-gold:hover{background:var(--goldl);box-shadow:0 6px 20px rgba(184,146,78,.4)}
.btn-gold:active{transform:scale(.97)}
.btn-gold svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round}

.btn-outline{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  background:transparent;color:var(--t2);
  font-family:inherit;font-size:14px;font-weight:600;
  padding:13px 24px;border-radius:100px;border:1.5px solid var(--bd);
  cursor:pointer;transition:border-color var(--tr),color var(--tr),background var(--tr);
  -webkit-tap-highlight-color:transparent;
}
.btn-outline:hover{border-color:var(--gold);color:var(--gold);background:var(--goldbg)}

/* ── XP / STAT PILLS ─────────────────────────────────────────────── */
.xp-pill{
  display:flex;align-items:center;gap:5px;
  background:var(--goldbg);border:1.5px solid var(--goldbd);
  border-radius:100px;padding:5px 12px;
  font-size:12px;font-weight:800;color:var(--gold);
  text-decoration:none;white-space:nowrap;
  transition:background var(--tr),border-color var(--tr);
}
.xp-pill svg{width:11px;height:11px;fill:currentColor}

/* ── SECTION LABEL ───────────────────────────────────────────────── */
.sec-lbl{
  display:flex;align-items:center;gap:10px;
  font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:var(--t3);margin-bottom:12px;padding:0 4px;
}
.sec-lbl::after{content:'';flex:1;height:1px;background:var(--bd)}

/* ── FILTER CHIPS ────────────────────────────────────────────────── */
.fchip,.fc{
  display:inline-flex;align-items:center;gap:5px;
  padding:6px 14px;border-radius:100px;
  border:1.5px solid var(--bd);background:var(--surf);
  font-size:12px;font-weight:600;color:var(--t2);
  cursor:pointer;white-space:nowrap;
  transition:all var(--tr);-webkit-tap-highlight-color:transparent;
  box-shadow:var(--sh);
}
.fchip:hover,.fc:hover{border-color:var(--gold);color:var(--gold)}
.fchip.act,.fc.on{background:var(--goldbg);border-color:var(--goldbd);color:var(--gold)}

/* ── BADGE ───────────────────────────────────────────────────────── */
.badge-gold{
  display:inline-flex;align-items:center;gap:5px;
  padding:4px 11px;border-radius:100px;
  background:var(--goldbg);border:1.5px solid var(--goldbd);
  font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--gold);
}

/* ── MODAL ───────────────────────────────────────────────────────── */
.modal-bg{
  position:fixed;inset:0;z-index:500;
  background:rgba(0,0,0,.65);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  display:flex;align-items:flex-end;justify-content:center;
  opacity:0;pointer-events:none;transition:opacity .28s;
}
.modal-bg.on{opacity:1;pointer-events:all}
.modal-sheet{
  background:var(--surf);border-radius:var(--rxl) var(--rxl) 0 0;
  border:1.5px solid var(--bd);
  padding:22px 22px calc(32px + env(safe-area-inset-bottom));
  width:100%;max-width:480px;
  transform:translateY(100%);transition:transform .38s cubic-bezier(.34,1.2,.64,1);
}
.modal-bg.on .modal-sheet{transform:translateY(0)}
.modal-handle{width:36px;height:4px;background:var(--bd2);border-radius:100px;margin:0 auto 22px}

/* ── SCROLLBAR ───────────────────────────────────────────────────── */
::-webkit-scrollbar{width:4px;height:4px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--bd2);border-radius:4px}
*{scrollbar-width:thin;scrollbar-color:var(--bd2) transparent}

/* ── ANIMATIONS ──────────────────────────────────────────────────── */
@keyframes pageIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes shimmer{0%{transform:translateX(-100%)}100%{transform:translateX(200%)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}

/* ── DÉFENSIVES MOBILES ──────────────────────────────────────────────
   - Empêche tout débordement horizontal (en plus de body{overflow-x:hidden})
   - Rend les tables défilables si elles sont trop larges
   - Casse les mots longs (URLs, mots collés) plutôt que d'étendre la page
   - Les images sont contraintes à la largeur du conteneur */
img, video, iframe { max-width: 100%; height: auto; }
table { max-width: 100%; }
pre, code, kbd { word-wrap: break-word; overflow-wrap: anywhere; }

@media (max-width: 480px) {
  /* Sur très petits écrans, les tables nowrap deviennent scrollables */
  .table-scroll-wrap, table.scroll-on-mobile {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Les éléments avec white-space:nowrap héritent du wrap si trop large */
  td, th { word-wrap: break-word; overflow-wrap: anywhere; }
  /* Bottom-nav : texte 10px minimum pour rester lisible (8px était trop petit) */
  .bni span { font-size: 10px !important; letter-spacing: 0 !important; }
}

/* Sur très petits écrans (iPhone SE, 320px), on cache le texte du bnav
   et on garde uniquement les icônes pour ne pas écraser la mise en page */
@media (max-width: 359px) {
  /* On masque visuellement le libellé mais on le garde pour les lecteurs
     d'écran (visually-hidden) — display:none l'aurait retiré de l'arbre
     d'accessibilité, privant les personnes aveugles du nom de l'onglet. */
  .bni span {
    position:absolute !important;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
  }
  .bni { padding: 10px 6px !important }
  .bni svg { width: 24px; height: 24px }
}

/* ── BARRE D'OUTILS DU HEADER (notes, favoris, immersif) ─────────────
   Ces boutons sont injectés par JS dans .bar-r. Sur écran étroit, ils
   s'étendent jusqu'au centre et passent SOUS le logo centré (position
   absolute) — illisible. Quand la barre porte des outils, on masque
   le logo : l'utilisateur sait où il est (il y a le bouton retour). */
@media (max-width: 599px) {
  .bar.bar-has-tools .bar-logo { display: none; }
  /* La barre porte désormais un hamburger (à gauche) ; sur les pages avec
     bouton retour, le logo centré entrerait en collision. On le masque —
     la marque « Korean Stories » reste visible en tête du tiroir du menu. */
  .bar:has(.bar-back) .bar-logo { display: none; }
}

/* ── WIDGETS FLOTTANTS — anti-collision ──────────────────────────────
   3 widgets pouvaient s'empiler en bas à droite (recherche, raccourci
   Hangeul, toggle sombre flottant) :
   - #darkFab : redondant — toutes les pages qui l'ont possèdent déjà
     un toggle thème dans le header (.bar-theme). On le retire.
   - .hg-fab (raccourci « Tableau Hangeul » des leçons) : déplacé en
     bas à GAUCHE, le coin droit est réservé à la recherche. */
#darkFab { display: none !important; }
.hg-fab {
  left: 14px !important;
  right: auto !important;
  bottom: calc(20px + env(safe-area-inset-bottom)) !important;
}

/* ── RESPONSIVE DESKTOP ──────────────────────────────────────────── */
@media(min-width:960px){
  body{padding-bottom:0}
  /* .side (ancien menu latéral) retiré partout : navigation via le menu hamburger ☰ */
  .bnav{display:none}
  .bar{padding:0 28px}
  .bar-back{display:none}
  .page{max-width:680px;padding-left:36px;padding-right:36px;padding-top:24px}
  .main{max-width:none}
}

/* ── UTILITY ─────────────────────────────────────────────────────── */
.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.visually-hidden,.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ── DARK MODE — LISIBILITÉ DES BADGES & ALERTES ─────────────────────
   Beaucoup de leçons / quiz utilisent des badges "OK/correct" avec un
   texte vert sombre (#16A34A, #15803d) sur un fond vert très clair
   (rgba(22,163,74,.1)). En mode sombre, ce fond reste sombre et le
   texte sombre devient illisible. Ces overrides ciblent les classes
   couramment utilisées dans tout le site et éclaircissent à la fois
   le fond et le texte pour rester contrastés. */

/* Réponses correctes (vert) — utilisé partout dans les quiz */
[data-theme=dark] .opt.ok,
[data-theme=dark] .mq .opt.ok,
[data-theme=dark] .ch.ok,
[data-theme=dark] .qchoice.ok,
[data-theme=dark] .q-choice.correct,
[data-theme=dark] .q-opt.ok,
[data-theme=dark] .choice-btn.ok,
[data-theme=dark] .qopt.correct{
  background:rgba(34,197,94,.18)!important;
  border-color:rgba(74,222,128,.55)!important;
  color:#4ade80!important;
}

/* Réponses incorrectes (rouge) — pour cohérence */
[data-theme=dark] .opt.ko,
[data-theme=dark] .mq .opt.ko,
[data-theme=dark] .ch.ko,
[data-theme=dark] .qchoice.ko,
[data-theme=dark] .q-choice.incorrect,
[data-theme=dark] .q-opt.ko,
[data-theme=dark] .choice-btn.ko{
  background:rgba(220,38,38,.18)!important;
  border-color:rgba(248,113,113,.55)!important;
  color:#f87171!important;
}

/* Pilules / badges colorés sur les pages cours */
[data-theme=dark] .pill,
[data-theme=dark] .xp-badge{
  background:rgba(124,58,237,.18)!important;
  color:#c4b5fd!important;
}

/* Cards / messages "ok" (vert pâle + texte vert sombre) — message
   d'export Réglages, badge "Lu/Fait", etc. */
[data-theme=dark] .rg-msg.ok{
  background:rgba(34,197,94,.18)!important;
  color:#4ade80!important;
}

/* Badge bleu (compréhension, lecture, etc.) */
[data-theme=dark] .scard-word.played,
[data-theme=dark] .cc-tag{
  color:#93c5fd!important;
  background:rgba(56,189,248,.16)!important;
}

/* Badges A1 / niveaux colorés sur lecture.html, grammaire.html */
[data-theme=dark] .story-card[data-level="A1"] .story-lvl-badge,
[data-theme=dark] .tag-a1{
  background:rgba(34,197,94,.18)!important;
  color:#86efac!important;
}

/* Avatars-emoji (histoire9, histoire10) */
[data-theme=dark] .avatar.doc,
[data-theme=dark] .avatar.emp{
  color:#4ade80!important;
}

/* Encadrés "mnémotechnique" bleu pâle (lecon.html, hangeul.html) :
   ces blocs sont à l'intérieur de cartes au fond TOUJOURS sombre
   (même en light mode). La couleur claire du texte est définie
   directement dans les pages — aucun override de thème nécessaire ici. */

/* Mode invité / révision badges sur revision.html */
[data-theme=dark] .qz-mode-badge.srs{
  background:rgba(96,165,250,.18)!important;
  border-color:rgba(96,165,250,.4)!important;
  color:#93c5fd!important;
}

/* ─────────────────────────────────────────────────────────────────────
   DARK MODE — overrides pour les classes utilisées dans plusieurs
   leçons / histoires qui ont un fond semi-transparent doré/violet/
   coloré et un texte var(--navy). En light mode le fond pâle se voit
   bien, en dark mode le fond devient sombre et le texte var(--navy)
   devient invisible. On force texte clair + un fond plus contrasté.
   ───────────────────────────────────────────────────────────────────── */

/* Boutons "Écouter" dans les leçons Hangeul */
[data-theme=dark] .speak-btn{
  background:rgba(201,169,110,.18)!important;
  border-color:rgba(201,169,110,.4)!important;
  color:#E8D6A4!important;
}
[data-theme=dark] .speak-btn:hover,
[data-theme=dark] .speak-btn.playing{
  background:var(--gold)!important;
  color:var(--navy)!important;
}

/* Indices / hints / titres de questions dans les leçons */
[data-theme=dark] .tw-hint,
[data-theme=dark] .q-prompt,
[data-theme=dark] .combo-note em,
[data-theme=dark] .modal-char,
[data-theme=dark] .qr-subtitle{
  color:var(--t)!important;
}

/* Cartes de récap de mots dans les histoires */
[data-theme=dark] .recap-kr,
[data-theme=dark] .recap-fr{
  color:var(--t)!important;
}

/* Definitions / cards de vocabulaire dans cours/grammaire */
[data-theme=dark] .gcard-title,
[data-theme=dark] .scard-name,
[data-theme=dark] .card-kr,
[data-theme=dark] .card-fr,
[data-theme=dark] .stat-n,
[data-theme=dark] .goal-title,
[data-theme=dark] .vt-title,
[data-theme=dark] .ccard-char{
  color:var(--t)!important;
}

/* Chips/filters actifs dans cours et grammaire */
[data-theme=dark] .chip.active,
[data-theme=dark] .fchip.act{
  background:var(--gold)!important;
  border-color:var(--gold)!important;
  color:var(--navy)!important;
}
[data-theme=dark] .chip:hover,
[data-theme=dark] .fchip:hover{
  color:var(--gold)!important;
  border-color:var(--gold)!important;
}

/* Boutons gold qui ont déjà du texte navy — c'est l'usage attendu :
   bouton doré + initial navy = lisible dans les 2 thèmes. On le
   laisse tel quel mais on affirme le contraste maximum. */
[data-theme=dark] .btn-gold,
[data-theme=dark] .res-prim,
[data-theme=dark] .gotit-btn,
[data-theme=dark] .start-btn,
[data-theme=dark] .quiz-next,
[data-theme=dark] .primary,
[data-theme=dark] .nav.dark .nav-cta{
  color:#0a1220!important; /* navy fixe, pas var(--navy) qui pourrait changer */
}

/* Tooltips "word-tip" dans les histoires — fond navy fixe, texte
   doit toujours être clair dans les 2 thèmes. */
.word-tip{ color:#f7f8fa!important; }

/* Encadrés "premium / pro" sur les pages auth */
[data-theme=dark] .auth-mobile-logo,
[data-theme=dark] .auth-left-logo{
  color:var(--t)!important;
}

/* Hover sur les cards de leçon — éviter que le texte devienne navy
   en dark mode quand on survole. */
[data-theme=dark] .ccard:hover .ccard-char,
[data-theme=dark] .ccard.active .ccard-char{
  color:#fff!important;
}
