/* ============================================================
   Le Bureau des Prédictions — feuille de style unique
   Avant la révélation : ivoire, bleu nuit, or. Aucune couleur
   genrée. La couleur n'entre en scène qu'au déclenchement.
   ============================================================ */

:root {
  --ivory: #f8f2e6;
  --ivory-deep: #efe5d1;
  --paper: #fffdf8;
  --navy: #141f38;
  --navy-soft: #2b3a5c;
  --gold: #a8842c;
  --gold-light: #d9bd6f;
  --wax: radial-gradient(circle at 34% 28%, #c2504a, #8d1f1f 58%, #651414);

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;

  /* Teintes de révélation, neutres par défaut */
  --c-glow: #ffffff;
  --c-mid: #8e9bb5;
  --c-deep: #3a465f;
  --c-abyss: #141f38;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}

body[data-result="fille"] {
  --c-glow: #ffe3ee;
  --c-mid: #ff86b6;
  --c-deep: #cf2068;
  --c-abyss: #4b0a28;
}

body[data-result="garcon"] {
  --c-glow: #e0eeff;
  --c-mid: #74aaff;
  --c-deep: #1c5cce;
  --c-abyss: #06203f;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  overflow-x: hidden;
  background: var(--ivory);
  color: var(--navy);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.8s var(--ease-in-out);
}

body[data-phase="reveal"] {
  color: #fff;
}

/* ------------------------------------------------------------ 1. décors */

.bloom,
.aurora,
.bokeh,
.rings,
.flash,
.grain,
.confetti {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

/* La nappe de couleur : un disque qui s'ouvre depuis le centre.
   Une transition (et non une animation) permet au masquage de
   refermer le disque en sens inverse, sans code supplémentaire. */
.bloom {
  background:
    radial-gradient(
      circle at 50% 42%,
      var(--c-glow) 0%,
      var(--c-mid) 26%,
      var(--c-deep) 58%,
      var(--c-abyss) 100%
    );
  clip-path: circle(0% at 50% 42%);
  transition: clip-path 1250ms var(--ease-out);
  z-index: 0;
}

body[data-phase="reveal"] .bloom {
  clip-path: circle(145% at 50% 42%);
}

.aurora,
.bokeh {
  opacity: 0;
  transition: opacity 1.4s var(--ease-in-out) 0.5s;
  z-index: 1;
  overflow: hidden;
}

body[data-phase="reveal"] .aurora,
body[data-phase="reveal"] .bokeh {
  opacity: 1;
}

/* Le dégradé radial est déjà flou par nature : un filter: blur() de 48 px sur
   trois calques de 60 vmax, doublé d'un mode de fusion, obligeait le
   navigateur à re-rastériser le fond à chaque image. Le rendu est le même. */
.blob {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
}

.blob-1 {
  width: 60vmax;
  height: 60vmax;
  top: -22vmax;
  left: -18vmax;
  background: radial-gradient(circle, var(--c-glow) 0%, transparent 62%);
  opacity: 0.42;
  animation: drift-1 13s var(--ease-in-out) infinite alternate;
}

.blob-2 {
  width: 52vmax;
  height: 52vmax;
  right: -20vmax;
  top: 18vmax;
  background: radial-gradient(circle, var(--c-mid) 0%, transparent 60%);
  opacity: 0.5;
  animation: drift-2 17s var(--ease-in-out) infinite alternate;
}

.blob-3 {
  width: 46vmax;
  height: 46vmax;
  left: 12vmax;
  bottom: -24vmax;
  background: radial-gradient(circle, var(--c-glow) 0%, transparent 58%);
  opacity: 0.3;
  animation: drift-3 15s var(--ease-in-out) infinite alternate;
}

@keyframes drift-1 {
  to {
    transform: translate3d(22vmax, 13vmax, 0) scale(1.3);
  }
}
@keyframes drift-2 {
  to {
    transform: translate3d(-20vmax, -16vmax, 0) scale(1.24);
  }
}
@keyframes drift-3 {
  to {
    transform: translate3d(14vmax, -19vmax, 0) scale(1.34);
  }
}

/* Poussière lumineuse, en deux nappes de profondeurs différentes.
   Chaque nappe ne porte qu'UNE trame et se déplace d'exactement une hauteur
   de trame : la boucle est alors invisible. Avec deux trames superposées de
   hauteurs différentes, une seule des deux bouclait et l'autre sautait à
   chaque cycle. Les calques débordent largement en haut et en bas, sinon la
   poussière s'arrête avant le bord de l'écran. */
.bokeh::before,
.bokeh::after {
  content: "";
  position: absolute;
  inset: -420px 0;
  background-repeat: repeat;
  will-change: transform;
}

.bokeh::before {
  background-image: radial-gradient(
    circle,
    rgba(255, 255, 255, 0.9) 0 1.2px,
    transparent 1.7px
  );
  background-size: 170px 220px;
  animation: rise-near 13s linear infinite;
}

.bokeh::after {
  background-image: radial-gradient(
    circle,
    rgba(255, 255, 255, 0.55) 0 2.1px,
    transparent 2.8px
  );
  background-size: 290px 340px;
  opacity: 0.6;
  animation: rise-far 21s linear infinite;
}

@keyframes rise-near {
  to {
    transform: translate3d(0, -220px, 0);
  }
}

@keyframes rise-far {
  to {
    transform: translate3d(0, -340px, 0);
  }
}

/* Onde de choc au moment du déclenchement */
.rings {
  display: grid;
  place-items: center;
  z-index: 2;
}

.rings i {
  position: absolute;
  width: 34vmin;
  height: 34vmin;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.75);
  opacity: 0;
  transform: scale(0.2);
}

body.shock .rings i {
  animation: shock 1500ms var(--ease-out) forwards;
}

body.shock .rings i:nth-child(2) {
  animation-delay: 160ms;
}
body.shock .rings i:nth-child(3) {
  animation-delay: 320ms;
}

@keyframes shock {
  0% {
    opacity: 0.9;
    transform: scale(0.15);
    border-width: 10px;
  }
  100% {
    opacity: 0;
    transform: scale(4.2);
    border-width: 1px;
  }
}

/* Éclair blanc très court : masque la bascule de mise en page */
.flash {
  background: #fff;
  opacity: 0;
  z-index: 6;
}

body.shock .flash {
  animation: flash 520ms ease-out forwards;
}

@keyframes flash {
  0% {
    opacity: 0;
  }
  12% {
    opacity: 0.82;
  }
  100% {
    opacity: 0;
  }
}

/* Grain papier : donne de la matière, en ivoire comme en couleur */
.grain {
  z-index: 7;
  opacity: 0.4;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.35'/%3E%3C/svg%3E");
}

/* En phase de révélation, le grain perd son mode de fusion : un calque fusionné
   plein écran doit être recomposé à chaque image par-dessus tout ce qui bouge
   en dessous. Il ne reste qu'un voile léger, en composition normale. */
body[data-phase="reveal"] .grain {
  mix-blend-mode: normal;
  opacity: 0.08;
}

.confetti {
  z-index: 5;
  width: 100%;
  height: 100%;
}

/* ------------------------------------------------------------ 2. scène */

.stage {
  position: relative;
  z-index: 4;
  min-height: 100dvh;
}

/* Flex + marge automatique plutôt que place-items: center : un contenu plus
   haut que l'écran reste alors intégralement accessible au défilement, là où
   un centrage par grille en rogne le haut. */
.screen {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  padding: calc(env(safe-area-inset-top, 0px) + 24px) 20px
    calc(env(safe-area-inset-bottom, 0px) + 28px);
  opacity: 0;
  visibility: hidden;
  transform: translateY(14px);
  transition:
    opacity 480ms var(--ease-in-out),
    transform 480ms var(--ease-in-out),
    visibility 480ms;
}

body[data-phase="vote"] .screen[data-screen="vote"],
body[data-phase="sealed"] .screen[data-screen="sealed"],
body[data-phase="reveal"] .screen[data-screen="reveal"] {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* Le bloc de révélation ne se déplace pas lui-même : chacun de ses enfants a
   sa propre entrée, et superposer les deux mouvements brouillait la lecture.
   Il est simplement posé, en fondu, avant que la cascade ne commence. */
.screen[data-screen="reveal"] {
  transform: none;
}

body[data-phase="reveal"] .screen[data-screen="reveal"] {
  transition: opacity 420ms ease 400ms;
}

/* ------------------------------------------------------- 3. le dossier */

.sheet,
.reveal-wrap {
  margin: auto;
}

.sheet {
  width: min(100%, 460px);
  background: var(--paper);
  border: 1px solid rgba(20, 31, 56, 0.1);
  border-radius: 4px;
  padding: 30px 24px 26px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.8) inset,
    0 18px 40px -24px rgba(20, 31, 56, 0.45);
  position: relative;
}

/* Filet d'or en haut de la chemise */
.sheet::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--gold), var(--gold-light), var(--gold));
  border-radius: 4px 4px 0 0;
}

.sheet-centered {
  text-align: center;
}

.eyebrow {
  margin: 0 0 14px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--gold);
}

.eyebrow-light {
  color: rgba(255, 255, 255, 0.72);
}

.masthead {
  margin: 0 0 14px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 8.5vw, 2.5rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
}

.masthead em {
  display: block;
  font-style: normal;
  font-size: 0.72em;
  letter-spacing: 0.04em;
  color: var(--navy-soft);
}

.lede {
  margin: 0 0 24px;
  font-size: 0.94rem;
  color: var(--navy-soft);
}

.field {
  display: block;
  margin-bottom: 22px;
}

.field span {
  display: block;
  margin-bottom: 7px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy-soft);
}

.field input {
  width: 100%;
  min-height: 52px;
  padding: 0 14px;
  font: inherit;
  font-size: 1.05rem;
  color: var(--navy);
  background: #fffefa;
  border: 1px solid rgba(20, 31, 56, 0.22);
  border-radius: 3px;
  transition: border-color 160ms, box-shadow 160ms;
}

.field input:focus-visible {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(168, 132, 44, 0.18);
}

.question {
  margin: 0 0 12px;
  font-family: var(--serif);
  font-size: 1.22rem;
}

/* Les deux choix sont strictement symétriques : même forme, même
   couleur, même poids. Rien ne favorise une réponse. */
.choices {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.choice {
  position: relative;
  min-height: 118px;
  display: grid;
  place-content: center;
  gap: 10px;
  padding: 16px 10px;
  font: inherit;
  color: var(--navy);
  background: linear-gradient(180deg, #fffdf7, var(--ivory-deep));
  border: 1.5px solid rgba(20, 31, 56, 0.26);
  border-radius: 3px;
  cursor: pointer;
  transition: transform 160ms var(--ease-out), box-shadow 220ms, border-color 220ms;
}

.choice-ornament {
  width: 34px;
  height: 34px;
  margin: 0 auto;
  border: 1.5px solid var(--gold);
  border-radius: 50%;
  position: relative;
}

.choice-ornament::after {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid var(--gold);
  border-radius: 50%;
  opacity: 0.55;
}

.choice-label {
  font-family: var(--serif);
  font-size: 1.3rem;
  letter-spacing: 0.03em;
}

.choice:active {
  transform: scale(0.975);
}

.choice:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.choice[aria-pressed="true"] {
  border-color: var(--navy);
  box-shadow: 0 0 0 1.5px var(--navy) inset;
}

/* Tampon « enregistré » apposé sur le choix retenu */
.choice[aria-pressed="true"]::after {
  content: "Retenu";
  position: absolute;
  top: 8px;
  right: -6px;
  padding: 3px 8px;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #8d1f1f;
  border: 1.5px solid #8d1f1f;
  border-radius: 2px;
  transform: rotate(6deg);
  opacity: 0.85;
}

.notice {
  min-height: 1.2em;
  margin: 14px 0 0;
  font-size: 0.86rem;
  color: #8d1f1f;
}

.fineprint {
  margin: 18px 0 0;
  font-size: 0.74rem;
  line-height: 1.45;
  color: rgba(20, 31, 56, 0.55);
}

/* ------------------------------------------------- 4. dossier scellé */

.seal {
  width: 104px;
  height: 104px;
  margin: 4px auto 20px;
  position: relative;
  display: grid;
  place-items: center;
  filter: drop-shadow(0 6px 10px rgba(101, 20, 20, 0.3));
}

.seal::before,
.seal::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--wax);
  transition: transform 900ms var(--ease-out), opacity 900ms ease-out;
}

.seal::before {
  clip-path: inset(0 50% 0 0);
}

.seal::after {
  clip-path: inset(0 0 0 50%);
}

.seal span {
  position: relative;
  z-index: 1;
  font-family: var(--serif);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  color: #f1d9a3;
  transition: opacity 260ms ease-out;
}

/* Le sceau se brise en deux au déclenchement */
body.breaking .seal::before {
  transform: translate(-64px, 26px) rotate(-26deg);
  opacity: 0;
}

body.breaking .seal::after {
  transform: translate(64px, 22px) rotate(24deg);
  opacity: 0;
}

body.breaking .seal span {
  opacity: 0;
}

.headline {
  margin: 0 0 10px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 7vw, 1.95rem);
}

.verdict-line {
  margin: 0 0 6px;
  font-size: 0.98rem;
  color: var(--navy-soft);
}

.verdict-line strong {
  color: var(--navy);
}

.refline {
  margin: 0 0 22px;
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(20, 31, 56, 0.5);
}

.waiting {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  margin: 0 0 6px;
  font-size: 0.9rem;
  color: var(--navy-soft);
}

.pulse {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gold);
  animation: pulse 2.4s var(--ease-in-out) infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 0.35;
    transform: scale(0.85);
  }
  50% {
    opacity: 1;
    transform: scale(1.15);
  }
}

.tally {
  margin: 0 0 18px;
  font-size: 0.82rem;
  color: rgba(20, 31, 56, 0.55);
}

.link-button {
  padding: 10px 4px;
  font: inherit;
  font-size: 0.84rem;
  color: var(--navy-soft);
  background: none;
  border: none;
  border-bottom: 1px solid rgba(20, 31, 56, 0.3);
  cursor: pointer;
}

/* ---------------------------------------------------- 5. la révélation */

.reveal-wrap {
  width: min(100%, 540px);
  text-align: center;
}

/* Dérive de six pixels sur neuf secondes : trop lente pour être remarquée,
   assez pour que l'écran ne paraisse jamais figé. */
body[data-phase="reveal"] .reveal-wrap {
  animation: float 9s ease-in-out 3s infinite;
}

@keyframes float {
  0%,
  100% {
    transform: translate3d(0, -3px, 0);
  }
  50% {
    transform: translate3d(0, 3px, 0);
  }
}

.verdict {
  position: relative;
  margin: 0 0 18px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.5rem, 14vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: 0.005em;
  color: #fff;
  text-shadow:
    0 2px 30px rgba(255, 255, 255, 0.35),
    0 1px 2px rgba(0, 0, 0, 0.12);
}

/* Le halo respire sur un calque derrière le titre, dont seule l'opacité varie.
   Animer text-shadow forcerait le navigateur à repeindre le texte à chaque
   image, sans fin : c'est ce qui figeait tout le reste. */
.verdict::before {
  content: "";
  position: absolute;
  inset: -34% -14%;
  z-index: -1;
  background: radial-gradient(
    62% 54% at 50% 50%,
    rgba(255, 255, 255, 0.5),
    transparent 74%
  );
  opacity: 0;
  pointer-events: none;
}

body[data-phase="reveal"] .verdict::before {
  animation: breathe 5.5s ease-in-out 2.4s infinite;
}

@keyframes breathe {
  0%,
  100% {
    opacity: 0.2;
  }
  50% {
    opacity: 1;
  }
}

.verdict .word {
  display: inline-block;
  white-space: nowrap;
}

/* Uniquement opacité et transform : ces deux propriétés sont traitées par le
   compositeur. Un filter: blur() par lettre, lui, fait retomber les dix-sept
   lettres sur le processeur et hache toute la séquence. */
.verdict .glyph {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.4em) scale(0.94);
  will-change: transform, opacity;
}

body[data-phase="reveal"] .verdict .glyph {
  animation: glyph-in 920ms var(--ease-out) forwards;
  animation-delay: calc(700ms + var(--i) * 38ms);
}

@keyframes glyph-in {
  to {
    opacity: 1;
    transform: none;
  }
}

/* Reflet satiné : un glissement large et doux, qui traverse franchement
   le titre une fois toutes ses lettres en place, puis sort du cadre. */
.sheen {
  position: absolute;
  inset: -20% -40%;
  background: linear-gradient(
    100deg,
    transparent 30%,
    rgba(255, 255, 255, 0.18) 44%,
    rgba(255, 248, 226, 0.42) 50%,
    rgba(255, 255, 255, 0.18) 56%,
    transparent 70%
  );
  mix-blend-mode: overlay;
  opacity: 0;
  pointer-events: none;
  will-change: transform;
}

/* Le reflet ne passe qu'une fois, pendant l'ouverture. En boucle, il devenait
   une barre blanche qui surgit toutes les neuf secondes sur un écran par
   ailleurs immobile : l'entretien de la vie à l'écran revient aux mouvements
   continus (nappes, poussière, pluie de confettis), jamais à un événement. */
body[data-phase="reveal"] .sheen {
  animation: sheen 2100ms ease-in-out 2500ms both;
}

@keyframes sheen {
  0% {
    opacity: 0;
    transform: translate3d(-110%, 0, 0);
  }
  18% {
    opacity: 1;
  }
  82% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate3d(110%, 0, 0);
  }
}

.verdict-rule {
  width: min(260px, 70%);
  height: 1px;
  margin: 0 auto 18px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.85) 20%,
    #fff5d8 50%,
    rgba(255, 255, 255, 0.85) 80%,
    transparent
  );
  transform: scaleX(0);
  transition: transform 1100ms var(--ease-out) 1500ms;
}

body[data-phase="reveal"] .verdict-rule {
  transform: scaleX(1);
}

.verdict-sub,
.outcome,
.outcome-joke,
.split {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 900ms ease-out, transform 900ms var(--ease-out);
}

/* Cascade finale : les entrées durent 900 ms et se déclenchent toutes les
   250 ms, donc trois d'entre elles sont toujours en mouvement en même temps.
   C'est ce chevauchement qui fait un flux continu plutôt que des paliers. */
body[data-phase="reveal"] .verdict-sub {
  opacity: 1;
  transform: none;
  transition-delay: 1750ms;
}

body[data-phase="reveal"] .outcome {
  opacity: 1;
  transform: none;
  transition-delay: 2000ms;
}

body[data-phase="reveal"] .outcome-joke {
  opacity: 1;
  transform: none;
  transition-delay: 2250ms;
}

body[data-phase="reveal"] .split {
  opacity: 1;
  transform: none;
  transition-delay: 2500ms;
}

.verdict-sub {
  margin: 0 0 26px;
  font-size: 1.02rem;
  color: rgba(255, 255, 255, 0.86);
}

/* Tampon du résultat personnel */
.outcome {
  display: inline-block;
  margin: 0 auto 28px;
  padding: 9px 18px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #fff;
  border: 2px solid rgba(255, 255, 255, 0.75);
  border-radius: 3px;
  transform: rotate(-2.6deg);
  /* Pas de backdrop-filter : il apparaissait à 2,2 s et provoquait à cet
     instant précis un à-coup du compositeur, au milieu de la cascade. */
  background: rgba(255, 255, 255, 0.14);
}

.outcome[hidden] {
  display: none;
}

/* La vanne du Bureau : ton pince-sans-rire, donc en italique de labeur. */
.outcome-joke {
  max-width: 34ch;
  margin: -14px auto 28px;
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.88);
  text-wrap: pretty;
}

.outcome-joke[hidden] {
  display: none;
}

.split {
  display: grid;
  gap: 12px;
  text-align: left;
}

.split[hidden] {
  display: none;
}

.split-row {
  display: grid;
  grid-template-columns: 4.6rem 1fr 2.4rem;
  align-items: center;
  gap: 12px;
  font-size: 0.86rem;
}

.split-key {
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.82);
}

.split-bar {
  height: 7px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.2);
  overflow: hidden;
}

.split-bar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.9), #fff);
  transition: width 1200ms var(--ease-out) 2750ms;
}

.split-val {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: #fff;
}

/* ------------------------------------------- 6. le Registre, côté invité */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.ledger {
  margin: 34px auto 0;
  padding: 22px 18px 18px;
  text-align: left;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 14px;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 900ms ease-out, transform 900ms var(--ease-out);
}

body[data-phase="reveal"] .ledger {
  opacity: 1;
  transform: none;
  transition-delay: 2750ms;
}

.ledger-kicker {
  margin: 0 0 6px;
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}

.ledger-title {
  margin: 0 0 6px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.42rem;
  color: #fff;
}

.ledger-lede {
  margin: 0 0 16px;
  font-size: 0.9rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.84);
}

.ledger-field {
  display: block;
  margin-bottom: 12px;
}

.ledger-field[hidden] {
  display: none;
}

.ledger-label {
  display: block;
  margin-bottom: 6px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.76);
}

.ledger-field input {
  width: 100%;
  min-height: 48px;
  padding: 0 13px;
  font: inherit;
  font-size: 1rem;
  color: #fff;
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 9px;
}

.ledger-field input::placeholder {
  color: rgba(255, 255, 255, 0.5);
}

.ledger-field input:focus-visible {
  outline: none;
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.22);
}

/* Les pièces déjà versées par cet invité, avec retrait possible */
.ledger-mine {
  margin: 14px 0 12px;
  padding: 0;
  list-style: none;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
}

.ledger-mine[hidden] {
  display: none;
}

.ledger-mine li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.ledger-mine li:last-child {
  border-bottom: none;
}

.ledger-mine p {
  flex: 1;
  margin: 0;
  font-family: var(--serif);
  font-size: 0.95rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.92);
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

.ledger-mine .masked {
  font-style: italic;
  color: rgba(255, 255, 255, 0.6);
}

.ledger-mine button {
  flex: 0 0 auto;
  min-height: 34px;
  padding: 0 11px;
  font: inherit;
  font-size: 0.76rem;
  color: #fff;
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 7px;
  cursor: pointer;
}

.ledger-mine button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.ledger-field textarea {
  display: block;
  width: 100%;
  min-height: 108px;
  padding: 12px 13px;
  font: inherit;
  font-size: 1rem;
  line-height: 1.5;
  color: #fff;
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 9px;
  resize: vertical;
}

.ledger-field textarea::placeholder {
  color: rgba(255, 255, 255, 0.5);
}

.ledger-field textarea:focus-visible {
  outline: none;
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.22);
}

.ledger-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
}

.ledger-count {
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.64);
}

.ledger-count.over {
  color: #ffe08a;
}

.ledger-save {
  margin-left: auto;
  min-height: 46px;
  padding: 0 20px;
  font: inherit;
  font-size: 0.94rem;
  font-weight: 600;
  color: var(--navy);
  background: #fff;
  border: none;
  border-radius: 9px;
  cursor: pointer;
  transition: transform 140ms var(--ease-out), opacity 180ms;
}

.ledger-save:active:not(:disabled) {
  transform: scale(0.97);
}

.ledger-save:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.ledger-status {
  min-height: 1.2em;
  margin: 10px 0 0;
  font-size: 0.84rem;
  color: rgba(255, 255, 255, 0.82);
}

.ledger-link {
  display: inline-block;
  margin-top: 6px;
  font-size: 0.9rem;
  color: #fff;
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.45);
}

/* ------------------------------------------- 7. mouvement réduit */

@media (prefers-reduced-motion: reduce) {
  .bloom {
    transition-duration: 420ms;
  }

  .blob,
  .bokeh::before,
  .bokeh::after,
  .pulse,
  body[data-phase="reveal"] .reveal-wrap {
    animation: none !important;
  }

  .rings,
  .flash,
  .sheen {
    display: none;
  }

  .verdict .glyph {
    opacity: 1;
    transform: none;
    filter: none;
    animation: none !important;
  }

  body[data-phase="reveal"] .verdict::before {
    animation: none !important;
    opacity: 0.5;
  }

  .seal::before,
  .seal::after {
    transition-duration: 200ms;
  }

  .verdict-rule {
    transition-delay: 200ms;
  }

  body[data-phase="reveal"] .verdict-sub,
  body[data-phase="reveal"] .outcome,
  body[data-phase="reveal"] .outcome-joke,
  body[data-phase="reveal"] .split,
  body[data-phase="reveal"] .ledger {
    transition-delay: 240ms;
  }

  .split-bar i {
    transition-delay: 300ms;
  }
}
