/* Boîte à Histoires — palette nuit chaleureuse, accents dorés, mobile-first */

:root {
  --color-bg-top: #12142c;
  --color-bg-bottom: #262a5e;
  --color-gold: #f4c95d;
  --color-gold-strong: #e8ac2e;
  --color-gold-soft: #ffe9b8;
  --color-text: #f5f3ff;
  --color-text-muted: #b7b5da;
  --color-card: rgba(255, 255, 255, 0.07);
  --color-card-border: rgba(244, 201, 93, 0.32);
  --color-navy-ink: #1c1a2e;
  --radius-lg: 24px;
  --radius-md: 16px;
  --radius-pill: 999px;
  --shadow-soft: 0 8px 28px rgba(5, 5, 20, 0.4);
  --touch-min: 44px;
  --font-main: "Segoe UI Rounded", -apple-system, BlinkMacSystemFont, "Nunito",
    "Quicksand", "Segoe UI", system-ui, sans-serif;
  /* Hauteur de contenu de #bottom-nav (toujours visible, v2.6), hors zone
     sûre : sert à positionner #player-bar juste au-dessus (jamais
     superposés) et à calculer le padding-bottom réservé par <body>. */
  --bottom-nav-h: 60px;
  --player-bar-h: 68px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100vh;
  /* Filet de sécurité : la page ne défile jamais horizontalement — tout
     contenu large défile dans son propre conteneur (rails de tuiles, etc.). */
  overflow-x: hidden;
}

body {
  font-family: var(--font-main);
  color: var(--color-text);
  background: linear-gradient(160deg, var(--color-bg-top) 0%, var(--color-bg-bottom) 100%) fixed;
  background-attachment: fixed;
  /* padding-bottom réserve la place de #bottom-nav (toujours visible) +
     #player-bar quand elle apparaît : voir la règle body:has(...) plus bas,
     qui la complète. */
  padding-bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom) + 1rem);
}

/* Onglets pilotés en CSS pur via radios cachés */
.tab-radio {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.view { display: none; }

#tab-create:checked ~ main #view-create { display: block; }
#tab-library:checked ~ main #view-library { display: block; }
#tab-parent:checked ~ main #view-parent { display: block; }

.app-header {
  position: relative;
  padding: 1.25rem 1.25rem 0.75rem;
}

/* Bouton discret, coin haut-droit du header : ouvre l'espace parents (Task
   6). Cible tactile ≥44px malgré la taille visuelle modeste de l'icône. */
.parent-gear-btn {
  position: absolute;
  top: 0.4rem;
  right: 0.6rem;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 1.15rem;
  cursor: pointer;
}

.parent-gear-btn:hover,
.parent-gear-btn:focus-visible {
  color: var(--color-gold-soft);
}

.app-header h1 {
  margin: 0;
  font-size: 1.4rem;
  color: var(--color-gold-soft);
  letter-spacing: 0.01em;
  text-align: center;
}

main {
  max-width: 480px;
  margin: 0 auto;
  /* Espace réservé en bas pour la nav sticky (toujours visible) + la barre
     de lecture quand elle apparaît (cf. body padding-bottom plus bas) : le
     padding de main lui-même reste modeste. */
  padding: 0.5rem 1.25rem 1rem;
}

/* --- Vue création --- */

.parent-banner {
  display: flex;
}

/* display:flex ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.parent-banner[hidden] {
  display: none;
}

.parent-banner {
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-md);
  background: var(--color-card);
  border: 1px solid var(--color-gold);
  color: var(--color-gold-soft);
  font-size: 0.9rem;
}

.parent-banner-dismiss {
  flex-shrink: 0;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 1rem;
  cursor: pointer;
}

.sequel-choices {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 1rem;
}

/* display ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.sequel-choices[hidden] {
  display: none;
}

.sequel-loading {
  margin: 0;
  text-align: center;
  color: var(--color-text-muted);
}

.sequel-choice {
  min-height: var(--touch-min);
  padding: 0.75rem 1rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-card-border);
  background: var(--color-card);
  color: var(--color-text);
  font-family: inherit;
  font-size: 0.95rem;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.sequel-choice:hover,
.sequel-choice:focus-visible {
  border-color: var(--color-gold);
}

.sequel-surprise,
.sequel-manual {
  text-align: center;
  color: var(--color-gold-soft);
  font-weight: 600;
}

.adventure-toggle {
  display: flex;
  border: none;
  padding: 0;
  margin: 1rem 0 0;
}

/* display:flex ci-dessus écraserait l'attribut hidden (règle auteur > UA) :
   masqué par profil (aventure=0, Task 5, espace parents) via applyProfileToForm
   dans app.js. */
.adventure-toggle[hidden] {
  display: none;
}

.adventure-toggle input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.adventure-toggle .pill {
  width: fit-content;
  font-size: 0.9rem;
}

.adventure-toggle input:checked + .pill {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-navy-ink);
  font-weight: 700;
}

.adventure-toggle input:focus-visible + .pill {
  outline: 2px solid var(--color-gold-soft);
  outline-offset: 2px;
}

/* Aventure en cours (fix) : le toggle reste décoché et désactivé tant
   qu'une aventure attend un choix ou est en train d'être générée — évite
   de mélanger une nouvelle aventure (act 1) avec une chaîne déjà démarrée. */
.adventure-toggle.is-disabled .pill,
.adventure-toggle input:disabled + .pill {
  opacity: 0.5;
  cursor: not-allowed;
}

.builder {
  margin-top: 1rem;
}

.builder-category {
  border: none;
  padding: 0;
  /* Espacement vertical généreux entre catégories : laisse une zone de
     "prise" au pouce entre deux rails horizontaux consécutifs, pour que le
     geste de scroll vertical de la page démarre franchement hors d'un rail. */
  margin: 0 0 1.4rem;
  /* Quirk fieldset : min-inline-size vaut min-content par défaut, ce qui
     empêche le rail interne de rétrécir sous la largeur de ses tuiles et
     pousse toute la page en largeur sur mobile au lieu de laisser le rail
     défiler. */
  min-inline-size: 0;
  max-width: 100%;
}

.builder-category legend {
  padding: 0;
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.builder-rail {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.6rem;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  /* Empêche le défilement horizontal du rail de "chaîner" vers un défilement
     de la page entière une fois en bout de liste (mobile). Pas de
     touch-action: pan-x ici : ça bloquait aussi le pan VERTICAL de la page
     dès que le geste démarrait sur un rail (cause probable du souci de
     scroll signalé) — overscroll-behavior-x suffit à isoler le rail. */
  overscroll-behavior-x: contain;
  padding-bottom: 0.35rem;
  scroll-snap-type: x proximity;
  /* Barres de défilement des rails totalement masquées (esthétique mobile) :
     le défilement horizontal reste utilisable au doigt, juste sans trace
     visuelle en permanence. */
  scrollbar-width: none;
}

.builder-rail::-webkit-scrollbar {
  display: none;
}

.builder-tile {
  flex-shrink: 0;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  width: 76px;
  min-height: 76px;
  padding: 0.5rem 0.4rem;
  border-radius: var(--radius-md);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
  color: var(--color-text);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.builder-tile-emoji {
  font-size: 1.7rem;
  line-height: 1;
}

.builder-tile-label {
  font-size: 0.7rem;
  line-height: 1.15;
  text-align: center;
  color: var(--color-text-muted);
}

.builder-tile.selected {
  background: var(--color-gold);
  border-color: var(--color-gold);
}

.builder-tile.selected .builder-tile-label {
  color: var(--color-navy-ink);
  font-weight: 700;
}

.builder-tile-random {
  border-style: dashed;
}

.mic-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  margin: 1.5rem 0 1.25rem;
}

/* display:flex ci-dessus écraserait l'attribut hidden (règle auteur > UA) :
   masqué si la dictée n'est pas supportée ET/OU micro=0 côté profil (Task 5,
   cf. applyProfileToForm dans app.js). */
.mic-wrap[hidden] {
  display: none;
}

.btn-mic {
  width: 104px;
  height: 104px;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border-radius: 50%;
  border: none;
  background: radial-gradient(circle at 35% 30%, var(--color-gold-soft), var(--color-gold-strong));
  box-shadow: var(--shadow-soft);
  font-size: 2.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.15s ease;
}

.btn-mic:active { transform: scale(0.96); }

.btn-mic.recording {
  animation: pulse 1.2s infinite;
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(244, 201, 93, 0.55); }
  70% { box-shadow: 0 0 0 22px rgba(244, 201, 93, 0); }
  100% { box-shadow: 0 0 0 0 rgba(244, 201, 93, 0); }
}

.mic-hint {
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  text-align: center;
}

.field-label {
  display: block;
  margin: 0.75rem 0 0.4rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.consigne {
  width: 100%;
  min-height: 8rem;
  padding: 0.9rem 1rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-card-border);
  background: var(--color-card);
  color: var(--color-text);
  font-family: inherit;
  font-size: 1rem;
  resize: vertical;
}

.consigne::placeholder { color: var(--color-text-muted); }

/* edition_consigne=0 côté profil (Task 5, espace parents) : le constructeur
   continue d'écrire dans le champ (assignation .value, jamais bloquée par
   readonly), seule la saisie manuelle/clavier de l'enfant est empêchée —
   fond légèrement estompé pour signaler visuellement l'état. */
.consigne:read-only {
  background: var(--color-bg-top);
  cursor: default;
}

.pill {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-min);
  padding: 0.5rem 1.1rem;
  border-radius: var(--radius-pill);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
  color: var(--color-text);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.advanced-panel {
  margin-top: 1.1rem;
  padding: 0.25rem 0;
  border-top: 1px solid var(--color-card-border);
}

.advanced-panel summary {
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
  padding: 0.5rem 0;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  cursor: pointer;
  list-style: none;
}

.advanced-panel summary::-webkit-details-marker { display: none; }

.advanced-panel[open] summary { color: var(--color-gold-soft); }

.advanced-panel fieldset {
  border: none;
  padding: 0;
  margin: 0.9rem 0 0;
}

.advanced-panel legend {
  padding: 0;
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.length-pills {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.length-pills input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.length-pills input:checked + .pill {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-navy-ink);
  font-weight: 700;
}

.length-pills input:focus-visible + .pill {
  outline: 2px solid var(--color-gold-soft);
  outline-offset: 2px;
}

.sounds-toggle {
  display: flex;
}

.sounds-toggle input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.sounds-toggle .pill {
  width: fit-content;
}

.sounds-toggle input:checked + .pill {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-navy-ink);
  font-weight: 700;
}

.sounds-toggle input:focus-visible + .pill {
  outline: 2px solid var(--color-gold-soft);
  outline-offset: 2px;
}

.btn-go {
  width: 100%;
  min-height: 56px;
  margin-top: 1.4rem;
  border: none;
  border-radius: var(--radius-pill);
  background: linear-gradient(135deg, var(--color-gold-soft), var(--color-gold-strong));
  color: var(--color-navy-ink);
  font-family: inherit;
  font-size: 1.1rem;
  font-weight: 700;
  box-shadow: var(--shadow-soft);
  cursor: pointer;
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.btn-go:active { transform: scale(0.98); }

.btn-go:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.status {
  min-height: 1.4rem;
  margin: 1rem 0 0;
  text-align: center;
  color: var(--color-gold-soft);
  font-weight: 600;
}

.ingredients-card {
  margin-top: 1rem;
  padding: 1.25rem;
  border-radius: var(--radius-lg);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
  box-shadow: var(--shadow-soft);
  text-align: center;
}

.ingredients-card h2 {
  margin: 0 0 0.5rem;
  color: var(--color-gold);
  font-size: 1.2rem;
}

.ingredients-card p {
  margin: 0;
  color: var(--color-text-muted);
}

.story-text {
  display: block;
  margin-top: 1rem;
  padding: 1.1rem 1.25rem;
  border-radius: var(--radius-lg);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
  box-shadow: var(--shadow-soft);
  color: var(--color-text);
  line-height: 1.6;
  text-align: left;
}

/* display ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.story-text[hidden] {
  display: none;
}

.story-text p {
  margin: 0 0 0.75rem;
}

.story-text p:last-child {
  margin-bottom: 0;
}

.choice-tiles {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

/* display ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.choice-tiles[hidden] {
  display: none;
}

.choice-banner {
  margin: 0;
  text-align: center;
  font-weight: 700;
  color: var(--color-gold-soft);
}

.choice-tile {
  display: flex;
  align-items: center;
  gap: 1rem;
  width: 100%;
  min-height: 64px;
  padding: 0.9rem 1.1rem;
  border-radius: var(--radius-lg);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
  color: var(--color-text);
  font-family: inherit;
  font-size: 1rem;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.choice-tile:hover,
.choice-tile:focus-visible {
  border-color: var(--color-gold);
}

.choice-tile-emoji {
  font-size: 3rem;
  line-height: 1;
  flex-shrink: 0;
}

.choice-tile-label {
  flex: 1;
}

.story-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.btn-followup {
  min-height: var(--touch-min);
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-card-border);
  background: var(--color-card);
  color: var(--color-text);
  font-family: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.btn-followup:hover,
.btn-followup:focus-visible {
  border-color: var(--color-gold);
}

/* Seule action encore directement visible sur la carte allégée (feature 2,
   hors du menu ⋮) : garde un peu d'air sous le lecteur audio. */
.btn-resume-adventure {
  display: block;
  margin-top: 0.6rem;
}

.story-full-text {
  display: block;
  margin-top: 0.75rem;
  padding: 0.9rem 1rem;
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.15);
  border: 1px solid var(--color-card-border);
  color: var(--color-text-muted);
  line-height: 1.6;
  white-space: pre-line;
}

/* display ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.story-full-text[hidden] {
  display: none;
}

.story-list li.story-child {
  margin-left: 1.25rem;
  border-color: rgba(244, 201, 93, 0.18);
}

/* --- Vue bibliothèque --- */

#view-library h2 {
  color: var(--color-gold-soft);
  font-size: 1.2rem;
  margin: 0 0 0.75rem;
}

.library-filter-checkbox {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.library-filter-pill {
  display: inline-flex;
  margin: 0 0 1rem;
  font-size: 0.85rem;
}

.library-filter-checkbox:checked + .library-filter-pill {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-navy-ink);
  font-weight: 700;
}

.library-filter-checkbox:focus-visible + .library-filter-pill {
  outline: 2px solid var(--color-gold-soft);
  outline-offset: 2px;
}

.story-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Un groupe (parent + descendants, cf. library.js/refreshLibrary) reste une
   unité verticale : même en grille desktop (cf. media query plus bas),
   chaque groupe occupe UNE seule cellule et ses cartes s'y empilent dans
   l'ordre (parent puis descendants), jamais dispersées dans des cellules
   différentes. */
.story-group {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
}

.story-list li {
  /* Ancre du menu ⋮ (feature 2) : .card-menu-panel s'y positionne en
     absolute, jamais relativement à un ancêtre plus lointain. */
  position: relative;
  min-height: var(--touch-min);
  padding: 0.9rem 1rem;
  border-radius: var(--radius-md);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
}

/* Carte grisée pendant un changement de voix en cours (feature 1) : le
   spinner (.card-spinner) reste seul indicateur de progression, l'opacité
   réduite évite juste de laisser croire que la carte est interactive. */
.story-card.is-busy {
  opacity: 0.7;
}

/* --- Carte bibliothèque allégée + menu ⋮ (feature 2) ----------------------
   Le bloc visible ne garde que badges/titre/date/lecteur/reprise ; tout le
   reste (lire le texte, suite/variante, voix, favori, infos, suppression)
   vit dans le panneau ancré au bouton ⋮, un seul ouvert à la fois sur toute
   la bibliothèque (cf. library.js, openMenu). */

.story-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.story-header .story-info {
  min-width: 0; /* autorise le titre à tronquer/wrap sans pousser le menu hors carte */
  /* Fix visuel : <strong> (titre + badges 🗺️/⭐/✅⚠️) et <small> (date) sont
     ajoutés via appendChild (library.js), donc sans nœud texte entre les
     deux — en display inline par défaut, la date se retrouvait collée aux
     badges (« ✅01/09/2026 »). display:flex en colonne les sépare
     proprement sur deux lignes, quel que soit le nombre de badges. */
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.card-menu {
  position: relative;
  flex-shrink: 0;
}

.card-menu-toggle {
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

.card-menu-toggle:hover,
.card-menu-toggle:focus-visible,
.card-menu-toggle[aria-expanded="true"] {
  background: rgba(244, 201, 93, 0.15);
  color: var(--color-gold-soft);
}

.card-menu-toggle:disabled {
  opacity: 0.5;
  cursor: default;
}

.card-menu-panel {
  position: absolute;
  top: calc(100% + 0.25rem);
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 220px;
  max-width: calc(100vw - 3rem);
  padding: 0.4rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-card-border);
  background: var(--color-bg-bottom);
  box-shadow: var(--shadow-soft);
}

/* display:flex ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.card-menu-panel[hidden] {
  display: none;
}

/* .btn-followup (✨ La suite ! / 🔄 Modifier, cf. library.js) porte aussi
   .card-menu-item une fois déplacé dans le panneau : la règle ci-dessous,
   placée après .btn-followup dans la cascade, l'emporte à spécificité égale
   et fait passer ces deux boutons de la pilule autonome au style de ligne de
   menu ci-dessous — jamais deux styles concurrents dans le panneau. */
.card-menu-item {
  display: block;
  width: 100%;
  min-height: var(--touch-min);
  padding: 0.5rem 0.75rem;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text);
  font-family: inherit;
  font-size: 0.9rem;
  text-align: left;
  cursor: pointer;
}

.card-menu-item:hover,
.card-menu-item:focus-visible {
  background: rgba(244, 201, 93, 0.15);
  border-color: transparent;
}

.card-menu-danger {
  color: #ff9b9b;
}

.card-menu-submenu {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin: 0.15rem 0 0.15rem 0.6rem;
  padding-left: 0.6rem;
  border-left: 1px solid var(--color-card-border);
}

.card-menu-submenu[hidden] {
  display: none;
}

.card-menu-voice {
  font-size: 0.85rem;
}

.card-spinner {
  margin-top: 0.75rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

/* --- Popin d'informations --- */

.story-info-dialog {
  position: relative;
  width: calc(100% - 2.5rem);
  max-width: 340px;
  padding: 1.5rem 1.25rem 1.25rem;
  border: 1px solid var(--color-card-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-bottom);
  color: var(--color-text);
  box-shadow: var(--shadow-soft);
}

.story-info-dialog::backdrop {
  background: rgba(5, 5, 20, 0.6);
}

.story-info-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 1rem;
  cursor: pointer;
}

.story-info-content {
  margin: 0.5rem 0 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.5rem 0.9rem;
  align-items: baseline;
}

.story-info-content dt {
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.story-info-content dd {
  margin: 0;
  font-weight: 600;
  word-break: break-word;
}

/* --- Overlay « Qui écoute ? » ---
   Tient dans le viewport le plus possible sans scroll : max-height 100dvh,
   tailles fluides via clamp() pour s'adapter aux petits écrans, padding
   respectant les zones sûres (encoche/barre de gestes). Le nombre de
   profils vient désormais de GET /api/config (Task 5, espace parents) : la
   grille de tuiles (.profile-tiles) s'adapte (auto-fit) et peut passer sur
   plusieurs lignes défilables au lieu des 3 colonnes fixes d'origine. */

.profile-overlay {
  display: flex;
}

/* display:flex ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.profile-overlay[hidden] {
  display: none;
}

.profile-overlay {
  position: fixed;
  inset: 0;
  z-index: 30;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 4dvh, 1.5rem);
  max-height: 100dvh;
  overflow: hidden;
  padding: max(1.5rem, env(safe-area-inset-top)) max(1.25rem, env(safe-area-inset-right) + 1rem)
    max(1.5rem, env(safe-area-inset-bottom)) max(1.25rem, env(safe-area-inset-left) + 1rem);
  background: linear-gradient(160deg, var(--color-bg-top) 0%, var(--color-bg-bottom) 100%);
}

.profile-overlay-title {
  margin: 0;
  color: var(--color-gold-soft);
  font-size: clamp(1.1rem, 5dvh, 1.4rem);
  text-align: center;
}

.profile-tiles {
  display: grid;
  /* auto-fit plutôt que repeat(3, …) fixe (Task 5) : le nombre de profils
     n'est plus figé à 3 (espace parents) — 3 tuiles gardent 3 colonnes
     (minmax(0,1fr) empêchant tout débordement), au-delà les tuiles
     wrappent sur plusieurs lignes plutôt que de rétrécir à l'infini. */
  grid-template-columns: repeat(auto-fit, minmax(min(96px, 100%), 1fr));
  gap: clamp(0.6rem, 3vw, 1.25rem);
  width: 100%;
  max-width: min(92vw, 480px);
  max-height: 100%;
  overflow-y: auto;
}

.profile-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  width: 100%;
  min-width: 0;
  min-height: clamp(84px, 22dvh, 112px);
  padding: 0.5rem 0.35rem;
  border-radius: var(--radius-lg);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
  color: var(--color-text);
  cursor: pointer;
  box-shadow: var(--shadow-soft);
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.profile-tile:active { transform: scale(0.97); }

.profile-tile:hover,
.profile-tile:focus-visible {
  border-color: var(--color-gold);
}

.profile-tile-emoji {
  font-size: clamp(1.7rem, 7dvh, 2.4rem);
  line-height: 1;
}

.profile-tile-label {
  font-size: clamp(0.75rem, 3dvh, 0.95rem);
  font-weight: 600;
  color: var(--color-gold-soft);
  text-align: center;
}

/* --- Nav sticky basse (v2.6) --- */

.bottom-nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 25;
  height: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom));
  padding: 0 0.75rem env(safe-area-inset-bottom);
  background: var(--color-navy-ink);
  border-top: 1px solid var(--color-card-border);
  box-shadow: 0 -8px 28px rgba(5, 5, 20, 0.4);
}

/* .bottom-nav-inner porte la mise en page (flex) : #bottom-nav ne garde que
   le positionnement fixe + le fond, pour pouvoir centrer le contenu sur
   max-width sans rétrécir le fond (cf. media query desktop plus bas). */
.bottom-nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  height: 100%;
}

.bottom-nav-item {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-height: var(--touch-min);
  padding: 0.4rem 0.6rem;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
  color: var(--color-text);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
}

.profile-chip {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--color-gold-soft);
}

/* Boutons picto seul (surprise, bascule bibliothèque/créer) : plus de
   libellé visible, mais une zone tactile généreuse (≥48px, au-delà du
   --touch-min général de 44px) — l'accessibilité passe par leur
   aria-label. */
.bottom-nav-icon {
  flex: 0 0 auto;
  min-width: 48px;
  min-height: 48px;
  padding: 0;
  font-size: 1.35rem;
}

.bottom-nav-link {
  color: var(--color-gold-soft);
}

/* Un seul des deux labels [for=tab-library]/[for=tab-create] est visible à
   la fois : celui qui bascule VERS l'autre vue (les radios #tab-create /
   #tab-library sont déclarées en tête de <body>, donc antérieures dans le
   DOM — le sélecteur ~ fonctionne jusque dans la nav). */
#tab-create:checked ~ #bottom-nav .bottom-nav-link-create,
#tab-library:checked ~ #bottom-nav .bottom-nav-link-library {
  display: none;
}

/* CTA « ✨ Raconte ! » : seul élément doré proéminent de la nav (le bouton
   surprise devient un picto discret, cf. .bottom-nav-icon ci-dessus) ;
   déclenche la même soumission que #btn-go (app.js factorise le handler) et
   partage son état disabled pendant la génération. */
.bottom-nav-cta {
  flex: 1 1 auto;
  min-width: 48px;
  min-height: 48px;
  padding: 0.5rem 1rem;
  background: linear-gradient(135deg, var(--color-gold-soft), var(--color-gold-strong));
  border-color: var(--color-gold);
  color: var(--color-navy-ink);
  font-size: 0.95rem;
  font-weight: 700;
  box-shadow: var(--shadow-soft);
}

.bottom-nav-cta:active { transform: scale(0.97); }

.bottom-nav-cta:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.bottom-nav-item:focus-visible {
  outline: 2px solid var(--color-gold-soft);
  outline-offset: 2px;
}

/* --- Barre de lecture fixe ---
   Se place toujours AU-DESSUS de #bottom-nav (jamais superposée) : son
   offset bas correspond exactement à la hauteur de la nav. */

.player-bar {
  display: flex;
}

/* display:flex ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.player-bar[hidden] {
  display: none;
}

.player-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom));
  z-index: 20;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: var(--player-bar-h);
  padding: 0.75rem 1.1rem;
  background: var(--color-navy-ink);
  border-top: 1px solid var(--color-card-border);
  box-shadow: 0 -8px 28px rgba(5, 5, 20, 0.4);
}

.player-bar-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-gold-soft);
  font-weight: 600;
  font-size: 0.95rem;
}

.player-bar-controls {
  display: flex;
  flex-shrink: 0;
  gap: 0.5rem;
}

.player-bar-btn {
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border: none;
  border-radius: 50%;
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
  color: var(--color-text);
  font-size: 1.2rem;
  cursor: pointer;
}

/* Quand la barre de lecture est affichée, <body> réserve en plus sa hauteur
   (le padding-bottom de base, réservant déjà la nav sticky, est défini plus
   haut avec la règle body {} principale). */
body:has(#player-bar:not([hidden])) {
  padding-bottom: calc(var(--bottom-nav-h) + var(--player-bar-h) + env(safe-area-inset-bottom) + 1rem);
}

/* --- Espace parents (Task 6) ---
   Tout le contenu de #view-parent est construit par parent.js
   (createElement/textContent, données parent non fiables). Les classes
   ci-dessous ne font que styler ce que parent.js produit. La vue hérite du
   max-width 480px/1080px de <main> (mobile-first) comme les autres vues ;
   .parent-panel/.parent-pin plafonnent en plus à 640px pour rester
   lisibles sur grand écran, sans effet sur mobile (déjà plus étroit). */

.parent-view-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.parent-view-header h2 {
  margin: 0;
  font-size: 1.15rem;
  color: var(--color-gold-soft);
}

.parent-back-btn {
  flex-shrink: 0;
  min-height: var(--touch-min);
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-card-border);
  background: var(--color-card);
  color: var(--color-text);
  font-size: 0.85rem;
  cursor: pointer;
}

.parent-back-btn:hover,
.parent-back-btn:focus-visible {
  border-color: var(--color-gold);
}

/* --- Pavé PIN --- */

.parent-pin {
  display: flex;
}

/* display:flex ci-dessus écraserait l'attribut hidden (règle auteur > UA) */
.parent-pin[hidden] {
  display: none;
}

.parent-pin {
  justify-content: center;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

.parent-pin-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  width: 100%;
  max-width: 300px;
  padding: 1.5rem 1rem;
}

.parent-pin-title {
  margin: 0;
  text-align: center;
  color: var(--color-gold-soft);
  font-size: 1.02rem;
}

.parent-pin-dots {
  display: flex;
  gap: 0.85rem;
}

.parent-pin-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--color-card-border);
  background: transparent;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.parent-pin-dot.filled {
  background: var(--color-gold);
  border-color: var(--color-gold);
}

.parent-pin-message {
  min-height: 1.2em;
  margin: 0;
  text-align: center;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.parent-pin-message.is-error {
  color: #ff9d9d;
}

.parent-pin-keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.6rem;
  width: 100%;
}

.parent-pin-key {
  min-height: 56px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-card-border);
  background: var(--color-card);
  color: var(--color-text);
  font-size: 1.3rem;
  cursor: pointer;
}

.parent-pin-key:active {
  transform: scale(0.96);
}

.parent-pin-key:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.parent-pin-key-empty {
  visibility: hidden;
}

/* --- Panneau connecté --- */

.parent-panel {
  display: flex;
}

.parent-panel[hidden] {
  display: none;
}

.parent-panel {
  flex-direction: column;
  gap: 1.25rem;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

.parent-tabs {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.parent-tab {
  flex: 1;
  min-height: var(--touch-min);
  min-width: 90px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-card-border);
  background: var(--color-card);
  color: var(--color-text-muted);
  font-size: 0.82rem;
  cursor: pointer;
}

.parent-tab.is-active {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-navy-ink);
  font-weight: 700;
}

.parent-section[hidden] {
  display: none;
}

.parent-section {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* --- Profils : liste de cartes --- */

.parent-profile-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.parent-profile-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius-md);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
}

.parent-profile-emoji {
  font-size: 1.6rem;
  flex-shrink: 0;
}

.parent-profile-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.parent-profile-info strong {
  overflow-wrap: break-word;
}

.parent-profile-age {
  font-size: 0.78rem;
  color: var(--color-text-muted);
}

.parent-profile-actions {
  display: flex;
  gap: 0.25rem;
  flex-shrink: 0;
}

.parent-icon-btn {
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 1.05rem;
  cursor: pointer;
}

.parent-icon-btn:hover,
.parent-icon-btn:focus-visible {
  color: var(--color-gold-soft);
}

.parent-icon-btn-danger:hover,
.parent-icon-btn-danger:focus-visible {
  color: #ff8a8a;
}

.parent-add-btn {
  min-height: var(--touch-min);
  border-radius: var(--radius-pill);
  border: 1px dashed var(--color-card-border);
  background: transparent;
  color: var(--color-gold-soft);
  cursor: pointer;
  padding: 0.6rem;
  font-size: 0.9rem;
}

.parent-add-btn:hover,
.parent-add-btn:focus-visible {
  border-color: var(--color-gold);
}

/* --- Formulaires (profil, tuile, réglages) --- */

.parent-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem;
  border-radius: var(--radius-md);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
}

.parent-form h3 {
  margin: 0;
  font-size: 1rem;
  color: var(--color-gold-soft);
}

.parent-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  border: none;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.parent-field legend {
  padding: 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.parent-field label {
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.parent-field input[type="text"],
.parent-field select {
  min-height: var(--touch-min);
  padding: 0.5rem 0.7rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-card-border);
  background: rgba(255, 255, 255, 0.05);
  color: var(--color-text);
  font-size: 0.95rem;
  width: 100%;
}

.parent-field input[type="text"]::placeholder {
  color: var(--color-text-muted);
}

.parent-field-row {
  display: flex;
  gap: 0.75rem;
}

.parent-field-row .parent-field {
  flex: 1;
  min-width: 0;
}

.parent-pill-group {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.parent-pill-group input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.parent-pill-group input:checked + .pill {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-navy-ink);
  font-weight: 700;
}

.parent-pill-group input:focus-visible + .pill {
  outline: 2px solid var(--color-gold-soft);
  outline-offset: 2px;
}

.parent-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.parent-tag {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.35rem 0.5rem 0.35rem 0.7rem;
  border-radius: var(--radius-pill);
  background: rgba(244, 201, 93, 0.15);
  border: 1px solid var(--color-card-border);
  font-size: 0.85rem;
}

.parent-tag-remove {
  min-width: 26px;
  min-height: 26px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  font-size: 0.85rem;
  padding: 0;
}

.parent-tag-remove:hover,
.parent-tag-remove:focus-visible {
  color: #ff8a8a;
}

.parent-toggle-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.parent-toggle input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.parent-toggle .pill-switch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  min-height: var(--touch-min);
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--color-card-border);
  cursor: pointer;
  font-size: 0.9rem;
}

.parent-toggle input:checked + .pill-switch {
  border-color: var(--color-gold);
  background: rgba(244, 201, 93, 0.12);
}

.parent-toggle input:focus-visible + .pill-switch {
  outline: 2px solid var(--color-gold-soft);
  outline-offset: 2px;
}

.parent-toggle input:disabled + .pill-switch {
  opacity: 0.5;
  cursor: not-allowed;
}

.parent-toggle-hint {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.parent-form-error {
  margin: 0;
  min-height: 1.1em;
  font-size: 0.85rem;
  color: #ff9d9d;
}

.parent-form-error.is-success {
  color: var(--color-gold-soft);
}

.parent-form-actions {
  display: flex;
  gap: 0.6rem;
}

.parent-btn-primary {
  flex: 1;
  min-height: var(--touch-min);
  border-radius: var(--radius-pill);
  border: none;
  background: var(--color-gold);
  color: var(--color-navy-ink);
  font-weight: 700;
  cursor: pointer;
}

.parent-btn-primary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.parent-btn-secondary {
  min-height: var(--touch-min);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-card-border);
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
  padding: 0 1rem;
}

/* --- Tuiles personnalisées : liste --- */

.parent-tile-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.parent-tile-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.8rem;
  border-radius: var(--radius-md);
  background: var(--color-card);
  border: 1px solid var(--color-card-border);
}

.parent-tile-emoji {
  font-size: 1.3rem;
  flex-shrink: 0;
}

.parent-tile-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.parent-tile-info strong {
  overflow-wrap: break-word;
}

.parent-tile-scope {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

/* --- Réglages : voix autorisées --- */

.parent-voice-groups {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.parent-voice-group h3 {
  margin: 0 0 0.4rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.parent-checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-height: var(--touch-min);
  cursor: pointer;
  font-size: 0.9rem;
}

.parent-checkbox-row input {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  accent-color: var(--color-gold);
}

/* ===========================================================================
   Adaptation desktop (≥900px) — mobile-first : tout ce qui précède reste la
   mise en page par défaut (<900px, inchangée à l'identique). Cette section
   ne fait qu'ÉLARGIR/RÉORGANISER pour les écrans larges, jamais de nouveau
   comportement JS ; les [hidden] posés plus haut restent valides partout
   (aucune règle ci-dessous ne redéfinit display sur un sélecteur [hidden]).
   =========================================================================== */

@media (min-width: 900px) {

  main {
    max-width: 1080px;
  }

  /* --- Constructeur : rails → grilles qui wrappent -------------------------
     Sous 900px le rail défile horizontalement (comportement mobile
     inchangé) ; à partir de 900px il n'y a plus assez de raison de cacher
     des tuiles derrière un scroll horizontal, donc les tuiles s'enroulent
     sur plusieurs lignes (flex-wrap) et grossissent légèrement. */
  .builder-rail {
    flex-wrap: wrap;
    overflow-x: visible;
    overflow-y: visible;
    scroll-snap-type: none;
  }

  .builder-tile {
    width: 96px;
    min-height: 96px;
  }

  .builder-tile-emoji {
    font-size: 2rem;
  }

  /* --- Zone création : deux colonnes ---------------------------------------
     .create-main (tuiles du constructeur) prend 2fr, .create-aside
     (micro/consigne/réglages/CTA) 1fr et reste visible en sticky pendant
     que la colonne des tuiles, plus haute, défile. Choisie plutôt qu'une
     simple colonne élargie : sur 1900px une seule colonne à 1080px de large
     aurait laissé le micro et le bouton « Raconte ! » très loin sous des
     dizaines de tuiles, alors qu'ici ils restent toujours à portée d'œil. */
  .create-columns {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 0 2rem;
    align-items: start;
  }

  .create-aside {
    position: sticky;
    top: 1rem;
  }

  /* --- Nav sticky basse : contenu centré, fond pleine largeur --------------
     #bottom-nav garde position:fixed + fond pleine largeur (inchangé) ;
     seul .bottom-nav-inner (le contenu) se centre sur la même largeur que
     #main, pour ne pas étirer le CTA sur toute la largeur de l'écran. */
  .bottom-nav-inner {
    max-width: 1080px;
    margin-inline: auto;
  }

  .bottom-nav-cta {
    max-width: 420px;
  }

  /* --- Bibliothèque : grille de cartes --------------------------------------
     Chaque cellule de grille est un .story-group entier (parent + suite /
     variante / actes d'aventure, cf. library.js) : jamais un membre isolé
     d'un groupe dans sa propre cellule. */
  .story-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
    align-items: start;
    gap: 1rem;
  }

  /* --- Tuiles de choix (aventure) : 3 côte à côte --------------------------- */
  .choice-tiles {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }

  .choice-tile {
    flex-direction: column;
    text-align: center;
    gap: 0.5rem;
  }

  .choice-tile-label {
    flex: none;
  }
}

