/* ==========================================================================
   Parallel stories — direction visuelle : "l'horloge de mission qui contient un journal"
   Minimaliste, moderne. Space Grotesk (UI) + Space Mono (horloge & dates).
   Accent : braise / ember — la mèche qui brûle vers la sortie.
   ========================================================================== */

/* ---- Tokens --------------------------------------------------------------- */
:root {
  --bg:      #F7F6F3;
  --surface: #FFFFFF;
  --ink:     #17181C;
  --muted:   #6C7079;
  --faint:   #9A9DA4;
  --line:    #E7E5E0;
  --accent:  #4F46E5;
  --accent-soft: rgba(79, 70, 229, 0.12);
  --danger:  #B23A34;
  --on-accent: #FFFFFF;
  /* Camp fire : la seule chose de l'app qui soit chaude. Distincte de
     l'accent, pour qu'un post ouvert ne se confonde pas avec un partage. */
  --fire:      #C2410C;
  --fire-soft: rgba(194, 65, 12, 0.12);

  --sans: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Space Mono", ui-monospace, "SFMono-Regular", "JetBrains Mono", monospace;

  --step: clamp(0.9rem, 0.85rem + 0.2vw, 1rem);
  --radius: 10px;
  --wrap: 40rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:      #0D0E11;
    --surface: #15171B;
    --ink:     #ECEDEF;
    --muted:   #9096A0;
    --faint:   #626873;
    --line:    #23262C;
    --accent:  #818CF8;
    --accent-soft: rgba(129, 140, 248, 0.18);
    --danger:  #E06A63;
    --on-accent: #10112E;
    --fire:      #FB923C;
    --fire-soft: rgba(251, 146, 60, 0.18);
  }
}
/* Le toggle explicite du visiteur gagne dans les deux sens. */
:root[data-theme="dark"] {
  --bg:      #0D0E11;
  --surface: #15171B;
  --ink:     #ECEDEF;
  --muted:   #9096A0;
  --faint:   #626873;
  --line:    #23262C;
  --accent:  #818CF8;
  --accent-soft: rgba(129, 140, 248, 0.18);
  --danger:  #E06A63;
  --on-accent: #10112E;
}

/* ---- Reset léger ---------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--step);
  line-height: 1.5;
  font-feature-settings: "ss01";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
button { font-family: inherit; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---- Boutons -------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5ch;
  font-family: var(--sans);
  font-size: .95rem;
  font-weight: 500;
  line-height: 1;
  padding: .72em 1.25em;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  transition: background .18s ease, border-color .18s ease, transform .05s ease, color .18s ease;
}
.btn:active { transform: translateY(1px); }
.btn--primary {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}
.btn--primary:hover { filter: brightness(1.06); }
.btn--ghost {
  border-color: var(--line);
  color: var(--muted);
}
.btn--ghost:hover { border-color: var(--ink); color: var(--ink); }
.btn--danger {
  background: transparent;
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  color: var(--danger);
}
.btn--danger:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }

/* ---- Personas ------------------------------------------------------------- */
/* La couleur vient de la ligne StoryAuthor : une story créée en admin ne peut
   pas livrer de CSS, elle livre un hex. */
.persona {
  display: inline-block;
  font-size: 1.05em;
  line-height: 1;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--persona, var(--accent)) 55%, transparent));
}
/* ==========================================================================
   COMPTE À REBOURS — le signal
   ========================================================================== */

/* Discret (connecté) : lecture d'instrument dans la navbar */
.navbar__countdown {
  display: inline-flex;
  align-items: center;
  gap: .55ch;
  font-family: var(--mono);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--muted);
}
.navbar__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent-soft);
  animation: pulse 3.2s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-soft); opacity: .85; }
  50%      { box-shadow: 0 0 0 5px transparent; opacity: 1; }
}

/* ==========================================================================
   ÉCRANS D'AUTHENTIFICATION
   ========================================================================== */
.screen-auth main {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 2rem 1.25rem;
  position: relative;
  overflow: hidden;
}
/* la braise : halo ambiant derrière l'horloge (statique, sûr en reduced-motion) */
.screen-auth main::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 45% at 50% 42%,
              var(--accent-soft) 0%, transparent 70%);
  pointer-events: none;
}
.auth {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2.5rem;
  width: 100%;
  max-width: 30rem;
  text-align: center;
}
.auth__brand {
  margin: 0;
  font-family: var(--mono);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .4em;
  text-indent: .4em;
  text-transform: uppercase;
  color: var(--accent);
}
.auth-form {
  display: flex;
  flex-direction: column;
  gap: .9rem;
  width: 100%;
  max-width: 20rem;
}
.auth-form input[type="text"],
.auth-form input:not([type]) {
  width: 100%;
  font-family: var(--mono);
  font-size: 1rem;
  text-align: center;
  letter-spacing: .04em;
  padding: .85em 1em;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color .18s ease;
}
.auth-form input:focus { outline: none; border-color: var(--accent); }
.auth-form .btn { width: 100%; }
.auth-form__email {
  font-family: var(--sans);
  font-size: 1rem;
  padding: .72em 1em;
  width: 100%;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.auth-form__email:focus { outline: none; border-color: var(--accent); }
.auth__back {
  margin: 0;
  font-size: .85rem;
  color: var(--muted);
}
.auth__back a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.auth__back a:hover { color: var(--ink); border-bottom-color: var(--ink); }
.error {
  margin: 0;
  font-size: .85rem;
  color: var(--danger);
}

/* ==========================================================================
   NAVBAR (connecté)
   ========================================================================== */
.navbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  /* Elle passe à la ligne : un admin y a cinq liens, qui ne tiennent pas sur
     375 px. Sans wrap, c'est la PAGE entière qui s'élargissait — défilement
     horizontal partout, y compris sur la timeline. */
  flex-wrap: wrap;
  gap: .55rem clamp(.9rem, 3vw, 1.25rem);
  padding: .9rem clamp(1rem, 4vw, 2rem);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.navbar__brand {
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--ink);
}
.navbar__countdown { margin-right: auto; }
.navbar__actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: .55rem clamp(.9rem, 3vw, 1.25rem);
  font-size: .9rem;
}
.navbar__actions a {
  color: var(--muted);
  text-decoration: none;
  transition: color .18s ease;
}
.navbar__actions a:hover { color: var(--ink); }

/* ==========================================================================
   PROGRESS BAR — progression vers l'échéance (calculée au chargement, pas de JS)
   ========================================================================== */
.progress { display: inline-flex; align-items: center; gap: .7ch; }
.progress__track {
  flex: 1;
  background: var(--accent-soft);
  border-radius: 999px;
  overflow: hidden;
}
.progress__fill {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
}
/* Navbar (connecté) : compacte, sans label */
.progress--nav { width: clamp(3rem, 8vw, 5rem); }
.progress--nav .progress__track { height: 4px; }

/* ==========================================================================
   TIMELINE — rail vertical, plus récent en haut
   ========================================================================== */
main { display: block; }
/* En-tête de la timeline : le titre de la story, pas un second hero — même
   colonne que les stats et le rail qui suivent, pas de mise en scène propre. */
.timeline__head {
  max-width: var(--wrap);
  margin: clamp(2rem, 6vw, 3.5rem) auto 0;
  padding: 0 clamp(1.25rem, 4vw, 2rem);
}
.timeline__title {
  margin: 0;
  font-family: var(--sans);
  font-size: clamp(1.4rem, 4vw, 1.8rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.timeline__desc {
  margin: .4rem 0 0;
  font-size: .95rem;
  color: var(--muted);
}
.timeline__stats {
  max-width: var(--wrap);
  margin: clamp(1.5rem, 5vw, 3rem) auto -1rem;
  padding: 0 clamp(1.25rem, 4vw, 2rem);
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--faint);
  text-align: right;
}
/* ---- Sélecteur de vue : tout / camp fire --------------------------------- */
/* Deux liens dans une piste, pas un interrupteur : un filtre de liste doit
   nommer ses deux états. L'état courant vient d'`aria-current`, donc le style
   et le lecteur d'écran lisent la même source. */
.viewswitch {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  margin: clamp(1.5rem, 5vw, 3rem) auto 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
}
/* Le conteneur du sélecteur reprend la gouttière de la timeline pour que la
   piste s'aligne sur la première entrée, et non sur le bord de la page. */
.viewswitch-row {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 4vw, 2rem);
}
.viewswitch__opt {
  display: inline-flex;
  align-items: center;
  gap: .45em;
  padding: .5em 1.05em;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--faint);
  transition: color .18s ease, background .18s ease;
}
.viewswitch__opt:hover { color: var(--ink); }
.viewswitch__opt[aria-current="page"] { color: var(--ink); background: var(--bg); }
.viewswitch__opt--fire[aria-current="page"] {
  color: var(--fire);
  background: var(--fire-soft);
}
.viewswitch__emoji { font-size: 1.3em; letter-spacing: 0; line-height: 1; }
/* Onglet au repos : flamme éteinte. Le même code que sur l'interrupteur du
   formulaire — la couleur ne porte jamais l'état toute seule. */
.viewswitch__opt:not([aria-current]) .viewswitch__emoji {
  filter: grayscale(1) opacity(.5);
}

.timeline__empty {
  max-width: var(--wrap);
  margin: clamp(2rem, 6vw, 4rem) auto;
  padding: 0 clamp(1.25rem, 4vw, 2rem);
  color: var(--muted);
  line-height: 1.7;
}

.timeline {
  max-width: var(--wrap);
  margin: clamp(2rem, 6vw, 4rem) auto;
  padding: 0 clamp(1.25rem, 4vw, 2rem);
  position: relative;
}
/* le rail */
.timeline::before {
  content: "";
  position: absolute;
  top: .5rem;
  bottom: 2.5rem;
  left: calc(clamp(1.25rem, 4vw, 2rem) + 3.5px);
  width: 1px;
  background: var(--line);
}

.entry {
  position: relative;
  padding: 1.1rem 0 1.1rem 2rem;
}
.entry + .entry { border-top: 1px solid var(--line); }

.entry__node {
  position: absolute;
  left: -1.5px;
  top: 1.5rem;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--bg);
  border: 1.5px solid var(--faint);
}
.entry--mine .entry__node {
  background: var(--accent);
  border-color: var(--accent);
}

/* Ligne de méta : la date et l'auteur partagent la même ligne, donc étiqueter
   l'auteur ne coûte aucune hauteur dans la colonne. */
.entry__meta { margin: 0 0 .3rem; }
.entry__date {
  display: inline;
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .02em;
  color: var(--faint);
}
.entry__author {
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .02em;
  color: var(--muted);
}
.entry__author::before { content: "· "; color: var(--faint); }
.entry__title {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .6ch;
  font-size: 1.15rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.3;
}
a.entry__title {
  color: var(--ink);
  text-decoration: none;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  transition: color .16s ease;
}
a.entry__title:hover {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 55%, transparent);
}
.entry__title--locked {
  color: var(--muted);
  cursor: default;
  font-weight: 400;
}

/* badge brouillon */
.badge {
  font-family: var(--mono);
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  padding: .28em .6em;
  border-radius: 999px;
  transform: translateY(-1px);
}
/* ---- Interrupteur camp fire ---------------------------------------------- */
/* La case est masquée mais reste focusable : tout l'état passe par :checked. */
.firetoggle {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  cursor: pointer;
  user-select: none;
}
.firetoggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}
.firetoggle__track {
  position: relative;
  flex: 0 0 auto;
  width: 3.1rem;
  height: 1.7rem;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--line);
  transition: background .22s ease, border-color .22s ease, box-shadow .22s ease;
}
.firetoggle__knob {
  position: absolute;
  top: 50%;
  left: 3px;
  width: 1.3rem;
  height: 1.3rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: .82rem;
  line-height: 1;
  background: var(--bg);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
  /* Éteint, la flamme est grise : l'emoji dit l'état autant que la position. */
  filter: grayscale(1) opacity(.5);
  transform: translateY(-50%);
  transition: transform .22s ease, filter .22s ease;
}
.firetoggle__label { color: var(--muted); transition: color .22s ease; }

.firetoggle input:checked + .firetoggle__track {
  background: var(--fire-soft);
  border-color: transparent;
  box-shadow: 0 0 14px color-mix(in srgb, var(--fire) 22%, transparent);
}
.firetoggle input:checked + .firetoggle__track .firetoggle__knob {
  /* La piste fait 3.1rem, la pastille 1.3rem. Le retrait de 8px et non 6
     compte les deux bordures : sinon la pastille s'arrête 2px du bord droit
     contre 4px à gauche, et la course paraît de travers. */
  transform: translate(calc(3.1rem - 1.3rem - 8px), -50%);
  filter: none;
}
.firetoggle input:checked ~ .firetoggle__label { color: var(--fire); }
/* `:focus-visible` et non `:focus` : la bague ne doit apparaître qu'au clavier,
   pas sous le curseur — sans quoi elle reste allumée après chaque clic. */
.firetoggle input:focus-visible + .firetoggle__track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .firetoggle__track,
  .firetoggle__knob,
  .firetoggle__label { transition: none; }
}

/* badge camp fire : le post est ouvert, et le reste */
.badge--campfire {
  color: var(--fire);
  background: var(--fire-soft);
  display: inline-flex;
  align-items: center;
  gap: .45em;
}
/* L'emoji sort de la typo du badge : à .58rem et avec l'interlettrage des
   capitales, la flamme serait un point illisible poussé loin du mot. */
.badge__emoji {
  font-size: 1.35em;
  letter-spacing: 0;
  line-height: 1;
}
/* Vignette : taille fixe et recadrage centré (`cover`), pour que toutes les
   entrées s'alignent quel que soit le format de l'image d'origine. Le padding
   n'est réservé que sur les entrées qui en portent une, sinon le titre garderait
   une gouttière vide. */
.entry--has-thumb { padding-right: 4.5rem; }
.entry__thumb {
  position: absolute;
  top: 1.1rem;
  right: 0;
  width: 3.5rem;
  height: 3.5rem;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--line);
}
/* Une entrée camp fire est verrouillée au sens du CSS (on ne l'édite pas) mais
   son titre s'ouvre : il doit se lire comme un lien, pas comme un titre éteint. */
.entry--locked .entry__title--campfire { color: var(--ink); font-weight: 500; }

/* charger plus */
.loadmore {
  display: block;
  margin: 1.75rem auto 0;
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .6em 1.4em;
  cursor: pointer;
  transition: border-color .18s ease, color .18s ease;
}
.loadmore:hover { border-color: var(--ink); color: var(--ink); }

/* ==========================================================================
   FORMULAIRE D'ARTICLE
   ========================================================================== */
.post-form {
  max-width: var(--wrap);
  margin: clamp(2rem, 6vw, 3.5rem) auto;
  padding: 0 clamp(1.25rem, 4vw, 2rem);
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.post-form__title {
  font-family: var(--sans);
  font-size: clamp(1.5rem, 4vw, 2.1rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line);
  padding: .35em 0;
  width: 100%;
}
.post-form__title::placeholder { color: var(--faint); }
.post-form__title:focus { outline: none; border-bottom-color: var(--accent); }

.post-form__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem;
  font-size: .88rem;
  color: var(--muted);
}
.post-form__date {
  font-family: var(--mono);
  font-size: .85rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .5em .7em;
}
.post-form__date:focus { outline: none; border-color: var(--accent); }
.inline {
  display: inline-flex;
  align-items: center;
  gap: .55ch;
  cursor: pointer;
}
.inline input[type="checkbox"] { accent-color: var(--accent); }
.post-form__image-preview { margin: 0 0 1rem; }
.post-form__image-preview img {
  display: block;
  max-width: 220px;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.post-form__image-preview figcaption {
  margin-top: .4rem;
  font-size: .78rem;
  color: var(--faint);
}
.post-form__file { font-size: .85rem; color: var(--muted); }
.post-form__file::file-selector-button {
  font-family: var(--sans);
  font-size: .82rem;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .5em .9em;
  margin-right: .8rem;
  cursor: pointer;
}

.post-form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  padding-top: .5rem;
}
.danger-link {
  margin-left: auto;
  font-size: .85rem;
  color: var(--faint);
  text-decoration: none;
}
.danger-link:hover { color: var(--danger); }

/* Trix — accordé à la charte */
trix-toolbar .trix-button-group {
  border-color: var(--line) !important;
  border-radius: 8px;
}
trix-toolbar .trix-button {
  border-bottom: none;
}
trix-editor {
  min-height: 40vh;
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.7;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line) !important;
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
}
trix-editor:empty:not(:focus)::before { color: var(--faint); }
trix-editor:focus { outline: none; border-color: var(--accent) !important; }

/* ==========================================================================
   ÉCRANS DE CONFIRMATION (suppression, lecture unique)
   ========================================================================== */
.confirm {
  max-width: 30rem;
  margin: clamp(3rem, 12vh, 6rem) auto;
  padding: 2rem clamp(1.5rem, 5vw, 2.25rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
}
.confirm__q {
  margin: 0 0 1.75rem;
  font-size: 1.05rem;
  line-height: 1.5;
}
.confirm__q { margin-bottom: 1rem; }
.confirm__warning {
  margin: 0 0 1.75rem;
  padding-left: .9rem;
  border-left: 2px solid var(--accent);
  font-size: .9rem;
  line-height: 1.55;
  color: var(--muted);
}
.confirm__warning strong { color: var(--ink); }
.confirm__actions {
  display: flex;
  gap: 1rem;
  align-items: center;
}

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

/* ==========================================================================
   PICKER — les histoires parallèles
   ========================================================================== */
.screen-stories main {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 3rem 1.25rem;
}
.stories__brand {
  font-family: var(--mono);
  letter-spacing: .12em;
  text-transform: uppercase;
  font-size: .8rem;
  color: var(--muted);
  margin: 0 0 1.75rem;
}
.story-card {
  display: block;
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.35rem 1.5rem;
  margin-bottom: 1rem;
  transition: border-color .18s ease, transform .05s ease;
}
.story-card:hover { border-color: var(--ink); }
.story-card:active { transform: translateY(1px); }
.story-card__title { margin: 0; font-size: 1.35rem; font-weight: 600; }
.story-card__desc { margin: .4rem 0 0; color: var(--muted); }
.story-card__countdown {
  font-family: var(--mono);
  font-size: 1.1rem;
  margin: .9rem 0 .5rem;
  color: var(--accent);
}
.story-card__authors { margin: .8rem 0 0; display: flex; gap: .5ch; }
.stories__empty { color: var(--muted); }
.stories__out { margin-top: 2rem; font-size: .9rem; color: var(--muted); }

/* ==========================================================================
   PROFIL — la persona, par histoire
   ========================================================================== */
/* Hérite de .post-form (largeur, gouttières, colonne) : le formulaire de
   profil n'a que trois champs, il ne mérite pas sa propre mise en page. */
.profile-form__heading {
  margin: 0;
  font-size: clamp(1.4rem, 3.5vw, 1.85rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.profile-form__hint {
  margin: 0;
  font-size: .85rem;
  line-height: 1.6;
  color: var(--muted);
}
.profile-form__fields {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 1rem;
}
/* Le dimensionnement vit sur le wrapper, jamais sur l'input : le wrapper est en
   `flex-direction: column`, donc un `flex-basis` posé sur l'input y serait lu
   comme une HAUTEUR — c'est ce qui rendait le champ « nom » démesuré. */
.profile-form__field {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  min-width: 0;
}
.profile-form__field--name { flex: 1 1 12rem; }
.profile-form__field--emoji,
.profile-form__field--color { flex: 0 0 auto; }
.profile-form__label {
  display: block;
  font-size: .74rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--faint);
}
/* Une seule hauteur pour les trois contrôles : c'est elle qui les aligne. */
.profile-form__name,
.profile-form__emoji,
.profile-form__color {
  height: 2.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
}
.profile-form__name,
.profile-form__emoji {
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--ink);
  padding: 0 .7em;
}
.profile-form__name { width: 100%; }
.profile-form__emoji {
  width: 3.75rem;
  text-align: center;
  font-size: 1.25rem;
  padding: 0;
  cursor: pointer;
}
.profile-form__name:focus,
.profile-form__emoji:focus { outline: none; border-color: var(--accent); }
/* Le champ natif : on lui retire son chrome pour n'en garder que la pastille. */
.profile-form__color {
  width: 3.75rem;
  padding: 3px;
  cursor: pointer;
}
.profile-form__color::-webkit-color-swatch-wrapper { padding: 0; }
.profile-form__color::-webkit-color-swatch { border: none; border-radius: 5px; }
.profile-form__color::-moz-color-swatch { border: none; border-radius: 5px; }

.profile-form__email {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  margin: 0;
  padding: 1rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.profile-form__email-value {
  font-family: var(--mono);
  font-size: .9rem;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.profile-form__errors {
  margin: 0;
  padding-left: 1.2rem;
  font-size: .85rem;
  color: var(--danger);
}
.profile-form__error { font-size: .8rem; color: var(--danger); }

/* ---- Sélecteur d'emoji ---------------------------------------------------- */
/* Surcouche du champ texte : chargé en module depuis le CDN, comme Trix. Le
   conteneur est le repère de position de la fenêtre flottante. */
.emojifield { position: relative; }
.emojifield__pop {
  position: absolute;
  z-index: 20;
  top: calc(100% + .4rem);
  /* Ancrée à DROITE du champ : celui-ci est proche du bord droit du formulaire,
     un ancrage à gauche ferait déborder les 20rem de la fenêtre hors de la page. */
  right: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .14);
}
emoji-picker {
  display: block;
  /* 23rem et non 20 : à 20 la rangée des dix onglets de catégories est rognée
     sur son bord droit. La largeur du formulaire (--wrap : 40rem) le permet. */
  width: 23rem;
  height: 23rem;
  --background: var(--surface);
  --border-color: var(--line);
  --indicator-color: var(--accent);
  --button-active-background: var(--accent-soft);
  --button-hover-background: var(--accent-soft);
  --input-border-color: var(--line);
  --input-font-color: var(--ink);
  --input-placeholder-color: var(--faint);
  --outline-color: var(--accent);
  --category-font-color: var(--muted);
  --num-columns: 8;
}
/* Sous 26rem la fenêtre dépasserait la gouttière : on la recale sur la page. */
@media (max-width: 29rem) {
  emoji-picker { width: min(23rem, calc(100vw - 3.5rem)); }
}

/* ==========================================================================
   AUTEURS — qui écrit dans cette histoire (réservé aux admins)
   ========================================================================== */
.authors {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 2rem 1.1rem 3rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.authors__heading {
  margin: 0;
  font-size: clamp(1.4rem, 3.5vw, 1.85rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.authors__hint {
  margin: 0;
  font-size: .85rem;
  line-height: 1.6;
  color: var(--muted);
}
.authors__list { margin: 0; padding: 0; list-style: none; }
.authors__row {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .85rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.authors__row + .authors__row { margin-top: .5rem; }
/* `flex: 1 1 12rem` et non `flex: 1` : l'email porte `overflow-wrap: anywhere`,
   qui compte dans la taille min-content d'un conteneur flex. Sans base réelle,
   le bloc se laissait écraser jusqu'à UN CARACTÈRE PAR LIGNE au lieu de pousser
   les contrôles à la ligne suivante. */
.authors__who { display: flex; flex-direction: column; gap: .15rem; min-width: 0; flex: 1 1 12rem; }
.authors__name { font-weight: 500; }
.authors__email {
  font-family: var(--mono);
  font-size: .78rem;
  color: var(--muted);
  overflow-wrap: anywhere;
}
/* Les deux contrôles de la ligne. `row-gap` non nul : sur un écran étroit ils
   passent sous l'identité plutôt que de comprimer l'email. */
.authors__row { flex-wrap: wrap; row-gap: .7rem; }
.authors__field {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  min-width: 0;
}
.authors__select,
.authors__date {
  height: 2.4rem;
  font-family: var(--sans);
  font-size: .9rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0 .5em;
}
.authors__select:focus,
.authors__date:focus { outline: none; border-color: var(--accent); }
/* `display: flex` ci-dessus l'emporterait sur le `display: none` que le
   navigateur applique à [hidden] : sans ce !important, masquer la colonne
   d'accès ne masquerait rien du tout. */
.authors__field[hidden] { display: none !important; }
.authors__forever-value {
  height: 2.4rem;
  display: flex;
  align-items: center;
  font-size: .9rem;
  color: var(--muted);
}
/* Un accès déjà terminé doit se voir sans lire les dates une par une. */
.authors__row--expired { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); }
.authors__row--expired .authors__name { color: var(--muted); }
.authors__row--expired .persona { filter: grayscale(1); opacity: .55; }

/* ---- Réglages de l'histoire ----------------------------------------------- */
/* Hérite de .post-form (largeur, colonne) et emprunte les libellés et messages
   d'erreur de .profile-form : mêmes formes, une seule définition. */
.story-form__title,
.story-form__desc,
.story-form__date {
  width: 100%;
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .7em;
}
.story-form__title { font-size: 1.1rem; font-weight: 500; }
.story-form__desc { resize: vertical; line-height: 1.6; }
.story-form__title:focus,
.story-form__desc:focus,
.story-form__date:focus { outline: none; border-color: var(--accent); }
.story-form__dates { display: flex; flex-wrap: wrap; gap: 1rem; }
.story-form__dates .profile-form__field { flex: 1 1 10rem; }


/* ==========================================================================
   LA VEILLÉE — la page de lecture d'un post camp fire
   La seule page de l'app qui sorte du thème clair : elle apporte sa nuit, sa
   police et son feu. Tout est cadenassé sous .screen-campfire pour que rien
   n'en déborde sur le reste.
   ========================================================================== */
.screen-campfire {
  /* `overflow: hidden` sur le corps : c'est le panneau de lecture qui défile,
     pas la page. Sans ça, la flamme partirait vers le haut au défilement. */
  overflow: hidden;
  height: 100%;
  background: #04060c;
  font-family: "Cormorant", "Cormorant Garamond", Georgia, "Times New Roman", serif;
}
.screen-campfire main { display: contents; }

.veillee__sky {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: linear-gradient(to bottom,
    #04060c 0%, #0a0f1f 42%, #171020 62%, #1c1206 84%, #2c1608 100%);
}
.veillee__stars { position: fixed; inset: 0; z-index: 1; pointer-events: none; }
.veillee__star {
  position: absolute;
  border-radius: 50%;
  background: #eaf1ff;
  animation: veillee-twinkle linear infinite;
}
@keyframes veillee-twinkle {
  0%, 100% { opacity: var(--min-op, .2); }
  50% { opacity: var(--max-op, .9); }
}

/* Le foyer. Sa hauteur borne le panneau de lecture ci-dessous : c'est ce qui
   garantit qu'aucune ligne ne sera jamais tracée par-dessus la flamme, à
   n'importe quelle position de défilement. */
.veillee__fire {
  position: fixed;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: min(260px, 70vw);
  height: min(190px, 26vh);
  z-index: 2;
  pointer-events: none;
}
.veillee__glow {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: min(880px, 150vw);
  height: min(480px, 64vh);
  background: radial-gradient(closest-side,
    rgba(255, 150, 60, .5), rgba(255, 110, 30, .15) 45%, transparent 72%);
  filter: blur(2px);
  animation: veillee-glow 2.6s ease-in-out infinite;
}
@keyframes veillee-glow {
  0%, 100% { opacity: .85; } 30% { opacity: 1; } 55% { opacity: .72; } 80% { opacity: .96; }
}
.veillee__fire canvas { position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); }
.veillee__ember {
  position: absolute;
  bottom: 40px;
  left: 50%;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #ffb347;
  opacity: 0;
  animation: veillee-rise linear infinite;
}
@keyframes veillee-rise {
  0% { opacity: 0; transform: translate(0, 0) scale(1); }
  8% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), -210px) scale(.25); }
}

.veillee__reader {
  position: fixed;
  inset: 0 0 198px;  /* dégage toute la boîte du foyer (190px) et un peu plus */
  z-index: 3;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 180, 110, .35) transparent;
}
.veillee__reader::-webkit-scrollbar { width: 8px; }
.veillee__reader::-webkit-scrollbar-thumb { background: rgba(255, 180, 110, .3); border-radius: 4px; }
.veillee__reader::-webkit-scrollbar-track { background: transparent; }

.veillee__content {
  max-width: 620px;
  width: 88%;
  margin: 0 auto;
  padding-top: 8vh;
  padding-bottom: 6vh;
  text-align: center;
  /* Le repli : sans JavaScript, les mots n'ont aucune couleur en ligne. Cette
     valeur-là doit déjà se lire sur la nuit. */
  color: #d8c8a8;
}
.veillee__seal,
.veillee__date {
  display: block;
  font-family: var(--mono);
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255, 178, 108, .75);
}
.veillee__seal { margin: 0 0 .6rem; font-weight: 700; }
.veillee__date { margin: 0 0 2.2rem; color: rgba(214, 200, 170, .45); }
.veillee__title {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-style: italic;
  font-weight: 600;
  font-size: clamp(2.1rem, 5vw, 3.3rem);
  letter-spacing: .02em;
  margin: 0 0 3rem;
  text-wrap: balance;
}
.veillee__image {
  display: block;
  width: 100%;
  margin: 0 auto 2.6rem;
  border-radius: 4px;
  /* Comme un tirage posé près du feu : chaud au centre, mangé par la nuit. */
  box-shadow: 0 0 60px rgba(255, 140, 50, .18);
}
.veillee__text {
  font-size: clamp(1.05rem, 1.9vw, 1.32rem);
  line-height: 1.95;
  font-weight: 400;
}
/* Le contenu vient de Trix : des blocs, des listes, des liens. On les habille
   pour la nuit plutôt que de les laisser retomber sur le thème clair. */
.veillee__text p,
.veillee__text div,
.veillee__text ul,
.veillee__text ol,
.veillee__text blockquote { margin: 0 0 2rem; }
.veillee__text ul,
.veillee__text ol { padding-left: 1.2em; text-align: left; display: inline-block; }
.veillee__text blockquote {
  border-left: 1px solid rgba(255, 178, 108, .3);
  padding-left: 1.1em;
  text-align: left;
  font-style: italic;
}
.veillee__text a { color: #ffc98a; text-decoration-color: rgba(255, 201, 138, .4); }
.veillee__text img { max-width: 100%; border-radius: 4px; }
.veillee__text strong { font-weight: 600; }
/* `white-space: pre` : le mot garde son espace, sinon le découpage tasserait
   le texte. */
.veillee__word { white-space: pre; }

.veillee__back {
  position: fixed;
  top: 1.1rem;
  left: 1.2rem;
  z-index: 4;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  color: rgba(226, 214, 190, .5);
  padding: .5em .9em;
  border-radius: 999px;
  /* Le texte défile dessous : il lui faut son propre fond de nuit. */
  background: rgba(4, 6, 12, .55);
  backdrop-filter: blur(6px);
  transition: color .2s ease;
}
.veillee__back:hover { color: rgba(255, 201, 138, .95); }

@media (prefers-reduced-motion: reduce) {
  .veillee__star,
  .veillee__ember,
  .veillee__glow { animation: none; }
}
