@font-face { font-family: 'Bowlby One'; src: url('../fonts/bowlby-one.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Figtree'; src: url('../fonts/figtree.woff2') format('woff2'); font-weight: 300 900; font-display: swap; }

:root {
  --ink: #0B2228;
  --sea-deep: #083A40;
  --sea: #0E5158;
  --sea-light: #17717A;
  --foam: #EAF4EE;
  --plank: #E9DDC0;
  --plank-shade: #CDBE9B;
  --sky: #F6D9A8;
  --yellow: #F7B81F;
  --red: #E5412D;
  --white: #FFFDF6;
  --display: 'Bowlby One', 'Figtree', sans-serif;
  --text: 'Figtree', system-ui, sans-serif;
  --out: cubic-bezier(.16, 1, .3, 1);
  --lift: 0 10px 22px -8px rgba(3, 24, 28, .6);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scrollbar-color: var(--sea-light) var(--sea-deep); }
body {
  margin: 0; min-height: 100dvh;
  font: 500 1rem/1.5 var(--text); color: var(--foam);
  background: var(--sea) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='60'%3E%3Cpath d='M0 30Q15 18 30 30T60 30' fill='none' stroke='%2317717A' stroke-width='3' stroke-linecap='round'/%3E%3Cpath d='M60 58Q75 46 90 58T120 58' fill='none' stroke='%2317717A' stroke-width='3' stroke-linecap='round' opacity='.6'/%3E%3C/svg%3E");
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  caret-color: var(--red);
}
::selection { background: var(--yellow); color: var(--ink); }
[hidden] { display: none !important; }
h1, h2, p, ol, ul, fieldset { margin: 0; padding: 0; border: 0; }
h2 { font: inherit; }
ol, ul { list-style: none; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid var(--white); outline-offset: 3px; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.icon { width: 1.4em; height: 1.4em; display: block; }

/* ---------- Boutons : des bouées peintes ---------- */
.btn {
  font-family: var(--display); font-size: 1.15rem; line-height: 1.1;
  padding: .75em 1.5em; border-radius: 12px; border: 3px solid var(--ink); border-bottom-width: 8px;
  transition: transform .18s var(--out), box-shadow .18s var(--out), background-color .18s;
}
.btn-main { background: var(--yellow); color: var(--ink); }
.btn-main:hover { transform: translateY(-2px); background: #FFC93C; }
.btn-main:active, .btn-ghost:active { transform: translateY(4px); border-bottom-width: 4px; margin-bottom: 4px; }
.btn-ghost { background: transparent; color: inherit; border-color: currentColor; }
.btn-ghost:hover { background: color-mix(in srgb, currentColor 14%, transparent); }
.btn-big { font-size: clamp(1.3rem, 5vw, 1.6rem); width: min(100%, 26rem); }
.btn:disabled { cursor: default; opacity: .55; transform: none; }
.btn .icon { display: inline-block; vertical-align: -.28em; margin-right: .35em; }

/* Un mot en haut de l'écran : invitation copiée, coup refusé, connexion perdue. */
.notice {
  position: fixed; z-index: 60; top: max(12px, env(safe-area-inset-top)); left: 50%; translate: -50% 0; width: max-content; max-width: calc(100vw - 24px);
  padding: 10px 18px; border-radius: 26px; background: var(--plank); color: var(--ink); border: 3px solid var(--ink); box-shadow: var(--lift);
  font-weight: 700; line-height: 1.3; text-align: center; overflow-wrap: anywhere; cursor: pointer; animation: accoste .35s var(--out);
}

/* ---------- Rideau d'entrée ---------- */
.splash {
  position: fixed; inset: 0; z-index: 50; display: grid; place-content: center; justify-items: center; gap: 18px; padding: 24px;
  border: 0; background: var(--sea); color: var(--foam); text-align: center;
  clip-path: circle(150% at 50% 50%); transition: clip-path .45s cubic-bezier(.7, 0, .84, 0);
}
.splash.leaving { clip-path: circle(0 at 50% 50%); }
.splash-title { font: 400 clamp(4.5rem, 22vw, 6rem)/.82 var(--display); color: var(--white); text-shadow: .045em .06em 0 var(--ink); }
.splash-go {
  font: 400 clamp(1.1rem, 4vw, 1.5rem)/1.2 var(--display); color: var(--ink); background: var(--yellow);
  border: 3px solid var(--ink); border-bottom-width: 8px; border-radius: 12px; padding: .7em 1.2em; animation: appel 1.5s ease-in-out infinite;
}
.splash-note { font-weight: 700; }
.hint { font-size: .9rem; max-width: 62ch; }

/* ====================== Accueil ====================== */
/* L'accueil tient dans un seul écran : le Rocher prend la place qui reste, le formulaire reste compact. */
.setup { min-height: 100dvh; display: grid; grid-template-rows: minmax(210px, 1fr) auto auto; }
.hero {
  --band: 112px; /* bande de mer sous l'horizon, où se pose le titre */
  grid-area: 1 / 1; position: relative; overflow: hidden; container-type: size;
  background: linear-gradient(var(--sky) 0 calc(100% - var(--band)), transparent calc(100% - var(--band)));
}
.perce {
  position: absolute; left: 50%; translate: -56% 0; overflow: visible; aspect-ratio: 900 / 520;
  height: calc((100cqh - var(--band)) / .577); bottom: calc(var(--band) - (100cqh - var(--band)) / .577 * .423);
}
.soleil { animation: leve 1.6s var(--out) both; }
@keyframes leve { from { transform: translateY(170px); } }
/* Les oiseaux planent une demi-minute puis se laissent porter : un accueil laissé ouvert ne fait plus travailler la tablette. */
.oiseau { animation: plane 4.5s ease-in-out 6 alternate both; }
@keyframes plane { from { transform: translate(-10px, 6px) rotate(-4deg); } to { transform: translate(12px, -8px) rotate(5deg); } }

.brand, .crew, .extras { width: min(100% - 32px, 44rem); margin-inline: auto; }
.brand { grid-area: 1 / 1; align-self: end; position: relative; padding-bottom: 10px; }
.title {
  font: 400 clamp(3.4rem, 15vw, 4.2rem)/.82 var(--display); letter-spacing: -.01em;
  color: var(--white); text-shadow: .045em .06em 0 var(--ink);
  animation: accoste .9s .15s var(--out) both;
}
.tagline {
  font-weight: 800; font-size: clamp(1rem, 3.6vw, 1.2rem); color: var(--foam);
  animation: accoste .9s .3s var(--out) both;
}
@keyframes accoste { from { opacity: 0; transform: translateY(40px); } }
/* Le mot qui change de personnage (voir js/words.js) : une étiquette peinte à sa couleur (--kc, lettres --ko, fixées en JS),
   cernée d'encre et un peu de travers, comme les pancartes de l'accueil. L'ancienne plonge, la nouvelle refait surface,
   et sa largeur s'ajuste en douceur pour que la suite de la ligne ne saute pas. */
.kin {
  display: inline-block; white-space: nowrap; padding: .02em .38em .06em; margin-inline: .1em; border-radius: .4em;
  background: var(--kc, var(--red)); color: var(--ko, var(--white)); border: 2.5px solid var(--ink); text-shadow: none; rotate: -2deg;
  transition: width .4s var(--out), transform .4s var(--out), opacity .25s, background-color .3s;
}
.kin.out { opacity: 0; transform: translateY(.45em) rotate(4deg); transition-duration: .18s; }
.crew { padding-top: 20px; }
.crew, .deck { display: grid; gap: 20px; align-content: start; }
.extras { margin-block: 14px 24px; }

@media (min-width: 900px) and (min-aspect-ratio: 5/4) {
  /* Tablette couchée, ordinateur : l'horizon traverse tout l'écran ; dessous, l'enseigne à gauche, l'équipage à droite. */
  .setup {
    grid-template: minmax(200px, 1fr) auto / minmax(24px, 1fr) minmax(15rem, 29rem) clamp(30rem, 54vw, 44rem) minmax(24px, 1fr);
    column-gap: clamp(24px, 4vw, 64px);
  }
  .hero { --band: 28px; grid-area: 1 / 1 / 2 / -1; }
  .perce { left: 42%; }
  .brand, .crew, .extras { width: auto; margin-inline: 0; }
  .brand { grid-area: 2 / 2; align-self: start; padding: 30px 0 0; }
  .title { font-size: clamp(3.6rem, 7.4vw, 6rem); }
  .tagline { font-size: 1.3rem; margin-top: 8px; }
  .crew { grid-area: 2 / 3; padding: 34px 0 40px; }
  .extras { grid-area: 2 / 2; align-self: end; margin-block: 0 40px; }
}

.seg, .row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 20px; }
.seg-label { font: 400 1.25rem/1.2 var(--display); }
.seg-opts { display: flex; gap: 12px; }
.seg label { position: relative; }
.seg input { position: absolute; opacity: 0; inset: 0; }
.seg-opts label span {
  display: grid; place-items: center; width: 60px; height: 60px; border-radius: 50%;
  font: 400 1.4rem/1 var(--display); color: var(--ink); cursor: pointer;
  background: radial-gradient(circle, var(--plank) 0 54%, var(--ink) 54% 60%, transparent 60%), conic-gradient(from 22.5deg, var(--red) 0 12.5%, var(--white) 0 25%, var(--red) 0 37.5%, var(--white) 0 50%, var(--red) 0 62.5%, var(--white) 0 75%, var(--red) 0 87.5%, var(--white) 0);
  border: 3px solid var(--ink);
  transition: transform .25s var(--out), background-color .2s;
}
.seg label:hover span { transform: translateY(-2px); }
.seg input:checked + span { --plank: var(--yellow); transform: scale(1.18) rotate(-14deg); }
.seg input:focus-visible + span { outline: 3px solid var(--white); outline-offset: 3px; }

/* Même écran ou en ligne : deux pancartes côte à côte, celle qu'on a choisie est peinte en jaune. */
.mode { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.mode label { position: relative; }
.mode input { position: absolute; inset: 0; opacity: 0; margin: 0; }
.mode span {
  display: block; padding: .6em .4em; border-radius: 12px; border: 3px solid var(--ink); background: var(--plank-shade); color: var(--ink);
  font: 400 clamp(1rem, 4.2vw, 1.25rem)/1.1 var(--display); text-align: center; cursor: pointer;
  transition: background-color .2s, transform .25s var(--out);
}
.mode label:hover span { transform: translateY(-2px); }
.mode input:checked + span { background: var(--yellow); transform: translateY(-2px) rotate(-2deg); }
.mode input:focus-visible + span { outline: 3px solid var(--white); outline-offset: 3px; }

.players { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); align-items: start; }
.mate { display: grid; gap: 10px; min-width: 0; animation: accoste .5s var(--out) both; }
.mate:nth-child(2) { animation-delay: .06s; } .mate:nth-child(3) { animation-delay: .12s; } .mate:nth-child(4) { animation-delay: .18s; }
.player {
  display: flex; align-items: center; gap: 14px; min-width: 0;
  padding: 6px 18px 6px 6px; border-radius: 999px;
  background: var(--plank); color: var(--ink); border: 3px solid var(--ink); box-shadow: var(--lift);
}
.player.off { background: var(--plank-shade); }
.pick { position: relative; flex: none; width: 56px; height: 56px; padding: 0; border: 0; border-radius: 50%; background: none; transition: transform .25s var(--out); }
button.pick:hover { transform: rotate(-10deg) scale(1.05); }
button.pick:active { transform: scale(.92); }
button.pick[aria-expanded="true"] .swap { background: var(--white); rotate: 90deg; }
.pick svg { display: block; width: 100%; height: 100%; }
.swap {
  position: absolute; right: -6px; bottom: -4px; width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center; background: var(--yellow); border: 2.5px solid var(--ink);
}
.swap { transition: rotate .25s var(--out), background-color .2s; }
.swap .icon { width: 16px; height: 16px; }
.mate :focus-visible { outline-color: var(--white); }
.player :focus-visible, .tray :focus-visible { outline-color: var(--ink); }
/* Le surnom : écrit sur la planche, souligné d'un pointillé, un crayon au bout pour dire qu'il se change. */
.name { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; border-bottom: 3px dashed color-mix(in srgb, var(--ink) 35%, transparent); cursor: text; }
.name:focus-within { border-bottom-style: solid; border-bottom-color: var(--ink); }
.name input, .name-text {
  flex: 1; width: 100%; min-width: 0; padding: 4px 0; background: none; border: 0;
  font: 400 clamp(1.15rem, 4vw, 1.4rem)/1.2 var(--display); color: var(--ink); border-radius: 0;
}
.name input:focus { outline: 0; }
.name input::placeholder { color: color-mix(in srgb, var(--ink) 68%, var(--plank)); opacity: 1; }
.name-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pen { flex: none; opacity: .55; transition: opacity .2s; }
.pen .icon { width: 20px; height: 20px; }
.name:focus-within .pen { opacity: 0; }

/* Le choix du personnage : les quatre pions sur une planche, celui qu'on tient sur sa bouée jaune. */
.tray {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; padding: 10px 6px 8px; border-radius: 26px;
  background: var(--plank); color: var(--ink); border: 3px solid var(--ink); box-shadow: var(--lift); animation: accoste .35s var(--out) both;
}
.tray-opt { display: grid; justify-items: center; align-content: start; gap: 4px; min-width: 0; padding: 4px 2px; border: 0; border-radius: 12px; background: none; }
.tray-tok { width: 52px; height: 52px; border-radius: 50%; transition: transform .25s var(--out), box-shadow .2s; }
.tray-tok svg { display: block; width: 100%; height: 100%; }
.tray-name { font-weight: 800; font-size: .8rem; line-height: 1.1; text-wrap: balance; }
.tray-opt small { font-weight: 700; font-size: .8rem; line-height: 1.1; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tray-opt:hover:not(:disabled) .tray-tok { transform: translateY(-3px) rotate(-8deg); }
.tray-opt[aria-checked="true"] .tray-tok { transform: scale(1.1) rotate(-8deg); box-shadow: 0 0 0 3px var(--ink), 0 0 0 8px var(--yellow), 0 0 0 11px var(--ink); }
.tray-opt[aria-checked="true"] .tray-name { margin-top: 6px; }
.tray-opt:disabled { cursor: default; }
.tray-opt:disabled .tray-tok { filter: saturate(.3); opacity: .5; }

/* ---------- En ligne : créer, rejoindre, salle d'attente ---------- */
.join { display: flex; align-items: center; gap: 12px; }
.code-input {
  width: 6.4em; padding: .42em .2em .42em .5em; border-radius: 12px; background: var(--plank); color: var(--ink); border: 3px solid var(--ink);
  font: 400 1.25rem/1.1 var(--display); letter-spacing: .22em; text-transform: uppercase;
}
.code-input::placeholder { color: color-mix(in srgb, var(--ink) 45%, var(--plank)); opacity: 1; }
.code-input:focus-visible { outline: 3px solid var(--white); outline-offset: 3px; }
/* Le code de la salle : quatre faces de dé. */
.code { display: flex; gap: 6px; }
.code b {
  display: grid; place-items: center; width: 46px; height: 46px; border-radius: 11px; background: var(--white); color: var(--ink); border: 3px solid var(--ink);
  font: 400 1.4rem/1 var(--display); animation: apparait .4s var(--out) both;
}
.code b:nth-child(2) { animation-delay: .06s; rotate: 3deg; } .code b:nth-child(3) { animation-delay: .12s; rotate: -2deg; } .code b:nth-child(4) { animation-delay: .18s; rotate: 4deg; }
.code b:first-child { rotate: -4deg; }
.hint.bad { font-weight: 800; color: var(--white); }
.invite {
  display: flex; align-items: center; gap: 4px 2px; flex-wrap: wrap; padding: 12px 18px; border-radius: 26px;
  background: var(--plank); color: var(--ink); border: 3px solid var(--ink); box-shadow: var(--lift); font-weight: 700; line-height: 1.3; rotate: -1deg;
}
.invite b { font: 400 1.1em/1.2 var(--display); }
.invite .mini { width: 34px; height: 34px; margin-right: 6px; }
.tags { flex: none; display: flex; align-items: center; gap: 6px; font-weight: 800; font-size: .8rem; line-height: 1.1; }
.tag.ready { display: flex; align-items: center; gap: 2px; padding: .3em .6em .3em .35em; border-radius: 999px; background: var(--yellow); border: 2.5px solid var(--ink); animation: tamponne .45s var(--out) both; }
.tag.ready .icon { width: 16px; height: 16px; }
.tag.off { padding: .3em .6em; border-radius: 999px; border: 2.5px dashed var(--ink); }
.kick {
  flex: none; display: grid; place-items: center; width: 36px; height: 36px; margin-right: -8px; padding: 0; border-radius: 50%;
  background: var(--plank-shade); color: var(--ink); border: 2.5px solid var(--ink); transition: transform .2s var(--out);
}
.kick:hover { transform: rotate(90deg); }
.kick .icon { width: 18px; height: 18px; }
.kick.sure { width: auto; height: auto; padding: .5em .8em; border-radius: 12px; background: var(--white); border-width: 3px; border-bottom-width: 6px; }
.kick.sure:hover { transform: none; }
.readonly .seg label, .readonly .switch { cursor: default; }
.readonly .seg-opts label span { cursor: default; }
.readonly .seg label:hover span { transform: none; }
.readonly .seg input:checked + span { transform: scale(1.18) rotate(-14deg); }
.readonly .seg input:not(:checked) + span, .readonly .knob { opacity: .45; }

.switches { display: grid; gap: 14px 24px; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
.switch { display: flex; align-items: center; gap: 14px; cursor: pointer; position: relative; font-weight: 700; }
.switch input { position: absolute; opacity: 0; width: 60px; height: 34px; margin: 0; }
.knob {
  flex: none; width: 60px; height: 34px; border-radius: 999px; background: var(--plank-shade);
  border: 3px solid var(--ink); position: relative; transition: background-color .2s;
}
.knob::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 24px; height: 24px; border-radius: 50%;
  background: var(--white); border: 3px solid var(--ink); transition: transform .3s var(--out);
}
.switch input:checked + .knob { background: var(--yellow); }
.switch input:checked + .knob::after { transform: translateX(26px); }
.switch input:focus-visible + .knob { outline: 3px solid var(--white); outline-offset: 3px; }
.switch-text small { display: block; font-weight: 500; font-size: .875rem; color: color-mix(in srgb, var(--foam) 82%, var(--sea)); }
.go, .extras { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.extras { gap: 10px; }
.btn-small { font-size: .95rem; padding: .6em 1.1em; border-bottom-width: 6px; }
.menu-settings { display: grid; gap: 16px; }
.pills { display: grid; gap: 8px; }
.pills-label { font-weight: 700; }
.pills-opts { display: flex; flex-wrap: wrap; gap: 8px; }
.pills label { position: relative; }
.pills input { position: absolute; inset: 0; opacity: 0; margin: 0; }
.pills label span {
  display: block; padding: .5em 1em; border-radius: 10px; border: 3px solid var(--ink); background: var(--plank-shade);
  font: 400 1rem/1.1 var(--display); cursor: pointer; transition: background-color .2s, transform .2s var(--out);
}
.pills input:checked + span { background: var(--yellow); transform: translateY(-2px) rotate(-3deg); }
.pills input:focus-visible + span { outline: 3px solid var(--ink); outline-offset: 3px; }

/* Volume : un homard marche sur un cordage à six flotteurs (voir js/volume.js).
   --level (le volume, de 0 à 1) est fixé en JS ; le vrai curseur, invisible, est posé par-dessus tout. */
.vol { --crab: 60px; --level: 1; display: grid; gap: 6px; }
.vol-label { font-weight: 700; justify-self: start; }
.vol-track { position: relative; height: 76px; container-type: inline-size; }
.vol-input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; appearance: none; -webkit-appearance: none; background: transparent; opacity: 0; cursor: grab; }
.vol-input:active { cursor: grabbing; }
/* Son poussoir a la largeur du homard, pour que le doigt et lui restent l'un sur l'autre. */
.vol-input::-webkit-slider-thumb { -webkit-appearance: none; width: var(--crab); height: 76px; }
.vol-input::-moz-range-thumb { width: var(--crab); height: 76px; border: 0; }
.vol-rope, .vol-mover { position: absolute; pointer-events: none; }
/* Le cordage : un trait d'encre. Chaque flotteur est posé là où le homard se tient à ce cran, et s'allume quand il l'a atteint. */
.vol-rope { left: calc(var(--crab) / 2); right: calc(var(--crab) / 2); bottom: 12px; height: 4px; border-radius: 2px; background: var(--ink); display: grid; grid-template-columns: repeat(6, 1fr); }
.vol-rope i { justify-self: end; width: 16px; height: 16px; margin: -6px -8px 0 0; border-radius: 50%; border: 3px solid var(--ink); background: var(--plank-shade); transition: background-color .2s, transform .3s var(--out); }
.vol-rope i.on { background: var(--yellow); transform: translateY(-2px); }
/* Le chariot porte le homard de gauche à droite (100cqi : la largeur de la piste). */
.vol-mover { left: 0; bottom: 13px; width: var(--crab); height: var(--crab); translate: calc(var(--level) * (100cqi - var(--crab))) 0; transition: translate .24s var(--out); }
/* --tilt (degrés) et --hop (pixels) viennent du JS : il se dandine d'après le chemin parcouru. */
.vol-crab { position: absolute; inset: 0; transform-origin: 50% 92%; transform: translateY(calc(var(--hop, 0) * -1px)) rotate(calc(var(--tilt, 0) * 1deg)); transition: transform .3s var(--out), scale .18s var(--out), rotate .3s var(--out); }
.vol-crab svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* Les pinces montent avec le son : tombantes tout en bas, dressées à fond. */
.vol-crab .claw-l { transform-origin: 11px 18px; transform: rotate(calc((1 - var(--level)) * -78deg)); transition: transform .3s var(--out); }
.vol-crab .claw-r { transform-origin: 37px 17px; transform: rotate(calc((1 - var(--level)) * 78deg)); transition: transform .3s var(--out); }
/* Tenu, il colle au doigt : plus aucun délai, et il grossit un peu. */
.vol.dragging .vol-mover { transition: none; }
.vol.dragging .vol-crab { scale: 1.12; }
@media (hover: hover) { .vol-track:hover .vol-crab { scale: 1.08; } }
.vol-input:focus-visible ~ .vol-mover { outline: 3px solid var(--ink); outline-offset: 2px; border-radius: 50%; }
/* Endormi (volume à zéro, ou tout coupé) : il penche, laisse tomber les pinces, ferme les yeux et ronfle. */
.vol.asleep .vol-crab { transform: none; rotate: -11deg; }
.vol.asleep .claw-l { transform: rotate(-98deg); }
.vol.asleep .claw-r { transform: rotate(98deg); }
.vol.asleep .pupil { opacity: 0; }
.vol.asleep .eye { transform-box: fill-box; transform-origin: center; transform: scaleY(.2); }
.vol-zzz { position: absolute; left: 72%; bottom: 78%; display: none; font: 400 .8rem/1 var(--display); }
.vol.asleep .vol-zzz { display: block; }
/* Trois ronflements, puis il dort en silence : un écran au repos n'anime rien en boucle. */
.vol-zzz b { position: absolute; left: 0; bottom: 0; font-weight: 400; animation: ronfle 2.8s ease-in-out 3 both; }
.vol-zzz b + b { animation-delay: 1.4s; }
@keyframes ronfle { from { opacity: 0; transform: translate(0, 2px) scale(.6); } 25% { opacity: 1; } to { opacity: 0; transform: translate(9px, -14px) scale(1.25); } }

/* ====================== Table de jeu ====================== */
body.playing { overflow: hidden; position: fixed; inset: 0; }
.game { position: fixed; inset: 0; overflow: hidden; }
.table {
  position: absolute; top: 0; left: 0; transform-origin: 0 0; display: grid; overflow: hidden;
  background-color: color-mix(in srgb, var(--turn, transparent) 86%, transparent); transition: background-color .6s;
}
.ambient { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
/* Vie marine : chaque saynète est un petit dessin posé sur la mer, sous les planches. */
.amb { position: absolute; translate: -50% -50%; }
.amb svg { display: block; width: 100%; height: 100%; overflow: visible; }
.amb .v-o, .amb .buee { opacity: 0; }
.v-tangue { animation: tangue 1.7s ease-in-out infinite alternate; }
.v-flotte { animation: flotte 1.3s ease-in-out infinite alternate; }
.v-trot { animation: trotte .3s ease-in-out infinite alternate; }
.v-clac .claw-l { transform-origin: 13px 18px; animation: pince-g .9s ease-in infinite; }
.v-clac .claw-r { transform-origin: 36px 17px; animation: pince-d .9s .45s ease-in infinite; }
@keyframes tangue { from { transform: rotate(-3deg) translateY(1px); } to { transform: rotate(3deg) translateY(-1px); } }
@keyframes flotte { from { transform: translateY(1.5px) rotate(-5deg); } to { transform: translateY(-1.5px) rotate(5deg); } }
@keyframes trotte { from { transform: rotate(-7deg) translateY(-1px); } to { transform: rotate(7deg) translateY(1px); } }
@keyframes pince-g { 0%, 55%, 100% { transform: rotate(0); } 72% { transform: rotate(-24deg); } 84% { transform: rotate(6deg); } }
@keyframes pince-d { 0%, 55%, 100% { transform: rotate(0); } 72% { transform: rotate(24deg); } 84% { transform: rotate(-6deg); } }
.panel, .board, .dock, .clock-far { position: relative; z-index: 1; }
.demo-tag {
  position: absolute; z-index: 2; left: 50%; top: 50%; translate: -50% -50%; rotate: -8deg; pointer-events: none;
  font: 400 clamp(1rem, 3vmin, 1.4rem)/1 var(--display); color: var(--ink); background: var(--yellow);
  border: 3px solid var(--ink); border-radius: 10px; padding: .35em .7em; margin-top: calc(var(--board) * -.16);
}

.table.strips { grid-template-columns: 1fr 1fr auto; grid-template-rows: 1fr var(--board) 1fr; align-items: center; padding: 0 8px; column-gap: 8px; }
.strips .seat-A { grid-area: 1 / 1; }
.strips .seat-B { grid-area: 1 / 2 / 2 / 4; }
.strips .board { grid-area: 2 / 1 / 3 / 4; justify-self: center; }
.strips .seat-D { grid-area: 3 / 1; }
.strips .seat-C { grid-area: 3 / 2; }
.strips .dock { grid-area: 3 / 3; }
/* Un bandeau s'étale quand la place voisine est libre. */
.strips.no-A .seat-B, .strips.no-B .seat-A { grid-column: 1 / 4; }
.strips.no-C .seat-D { grid-column: 1 / 3; }
.strips[data-n="2"] .panel-inner { max-width: 30rem; margin-inline: auto; }
.table.visavis.strips .seat-A .panel-inner, .table.visavis.strips .seat-B .panel-inner { rotate: 180deg; }

.table.cols { grid-template-columns: 1fr var(--board) 1fr; grid-template-rows: 1fr 1fr auto; column-gap: 16px; padding: 12px 16px; }
.cols .board { grid-area: 1 / 2 / 4 / 3; align-self: center; }
.cols .seat-A { grid-area: 1 / 1; align-self: start; }
.cols .seat-D { grid-area: 2 / 1 / 4 / 2; align-self: end; }
.cols .seat-B { grid-area: 1 / 3; align-self: start; }
.cols .seat-C { grid-area: 2 / 3; align-self: end; }
.cols .dock { grid-area: 3 / 3; justify-self: end; margin-top: 12px; grid-auto-flow: column; align-items: center; gap: 10px; }
.cols .dock .clock { order: -1; }
.cols .panel-inner { grid-template-columns: auto 1fr; }
.cols .pname { flex-wrap: wrap; font-size: clamp(1rem, 2.2vmin, 1.3rem); }
.cols .pname-text { white-space: normal; overflow-wrap: anywhere; }
.cols .die { grid-column: 1 / 3; justify-self: center; margin: 10px 0 6px; }

.panel { min-width: 0; }
.panel-inner {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px;
  padding: 8px 14px 8px 8px; border-radius: 26px; border: 3px solid transparent;
  transition: background-color .3s, border-color .3s, color .3s, transform .4s var(--out), box-shadow .3s;
}
.panel.active .panel-inner { background: var(--plank); color: var(--ink); border-color: var(--ink); box-shadow: var(--lift); }
.table.visavis.strips .panel.active.seat-A .panel-inner, .table.visavis.strips .panel.active.seat-B .panel-inner { box-shadow: 0 -10px 22px -8px rgba(3, 24, 28, .6); }
.avatar { width: 54px; height: 54px; flex: none; transition: transform .4s var(--out); }
.avatar svg { display: block; width: 100%; height: 100%; }
.panel.active .avatar { transform: scale(1.1) rotate(-8deg); }
.who { min-width: 0; }
.pname { display: flex; align-items: center; gap: 8px; font: 400 clamp(1.05rem, 3.4vmin, 1.4rem)/1.15 var(--display); }
.pname-text { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* En ligne : un joueur absent, et de quoi jouer à sa place quand il fait attendre. */
.away { flex: none; padding: .25em .6em; border-radius: 999px; border: 2.5px dashed currentColor; font: 800 .8rem/1 var(--text); }
.panel.off .avatar { filter: saturate(.25); opacity: .7; }
.relay { flex: none; max-width: 9.5em; background: var(--white); color: var(--ink); line-height: 1.1; }
.cols .relay { grid-column: 1 / 3; justify-self: center; margin: 10px 0 6px; }
.status { font-weight: 700; font-size: .95rem; line-height: 1.25; min-height: 1.25em; }
.pips { display: flex; gap: 6px; margin-top: 4px; }
.marks { display: flex; gap: 4px; margin-top: 4px; }
.marks:empty { display: none; }
.mark { width: 26px; height: 26px; animation: apparait .3s var(--out) both; }
.mark svg { display: block; width: 100%; height: 100%; }
.pips i { width: 13px; height: 13px; border-radius: 50%; border: 2.5px solid currentColor; opacity: .55; transition: transform .4s var(--out); }
.pips i.on { background: var(--pc); border-color: var(--ink); opacity: 1; transform: scale(1.25); box-shadow: 0 0 0 2px var(--foam); }

/* Le dé : un vrai cube qui tourne */
.die {
  min-height: 78px; padding: 8px 20px 8px 12px; display: flex; align-items: center; gap: 12px; flex: none; perspective: 420px;
  font: 400 1.25rem/1 var(--display); color: var(--ink); background: var(--yellow);
  border: 3px solid var(--ink); border-bottom-width: 8px; border-radius: 16px;
}
.die:active:not(:disabled) { border-bottom-width: 4px; margin-top: 4px; }
.panel.active { cursor: pointer; }
.die:disabled { cursor: default; opacity: .4; background: var(--plank-shade); }
.die:disabled .die-label { display: none; }
.die:disabled { padding-right: 12px; }
.panel.active .die:disabled { opacity: .75; }
.panel :focus-visible { outline-color: var(--yellow); }
.panel.active :focus-visible { outline-color: var(--ink); }
.cube { position: relative; width: var(--s, 56px); height: var(--s, 56px); transform-style: preserve-3d; transition: transform .74s cubic-bezier(.2, .85, .25, 1); }
.face {
  position: absolute; inset: 0; display: grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); padding: 8px; gap: 2px;
  background: var(--die-bg, var(--white)); border: 3px solid var(--ink); border-radius: 11px;
}
.face i { border-radius: 50%; }
.face i.on { background: var(--ink); }
.f6 i.on, .f1 i.on { background: var(--red); }
.f1 { transform: translateZ(calc(var(--s, 56px) / 2)); }
.f6 { transform: rotateY(180deg) translateZ(calc(var(--s, 56px) / 2)); }
.f3 { transform: rotateY(90deg) translateZ(calc(var(--s, 56px) / 2)); }
.f4 { transform: rotateY(-90deg) translateZ(calc(var(--s, 56px) / 2)); }
.f5 { transform: rotateX(90deg) translateZ(calc(var(--s, 56px) / 2)); }
.f2 { transform: rotateX(-90deg) translateZ(calc(var(--s, 56px) / 2)); }
.bigdie {
  --s: calc(var(--board) * .2); position: absolute; z-index: 8; width: var(--s); height: var(--s); translate: -50% -50%;
  display: grid; perspective: 900px; pointer-events: none; filter: drop-shadow(0 18px 12px rgba(3, 24, 28, .5));
}
.bigdie .cube { transition: none; }
.bigdie .face i.on { background: var(--die-pip, var(--ink)); }
.bigdie.keep { --s: calc(var(--board) * .14); z-index: 7; }
.bigdie .face { padding: 13%; gap: 3%; border-width: 5px; border-radius: 16%; }
/* Le dé, le halo du radeau et la bouteille appellent par bouffées (trois battements au début du tour, un rappel de loin en loin).
   Entre deux, plus rien ne bouge : l'écran au repos ne coûte presque rien à la batterie. */
.calling .die:not(:disabled):not(.rolling) { animation: appel 1.5s ease-in-out var(--calls, 1); }
.die.rolling { animation: lance .74s var(--out); }
@keyframes appel { 0%, 100% { transform: translateY(0) rotate(0); } 50% { transform: translateY(-5px) rotate(-5deg); } }
@keyframes lance { 0% { transform: translateY(0) scale(1); } 35% { transform: translateY(-22px) scale(1.2); } 70% { transform: translateY(3px) scale(.96); } 100% { transform: none; } }

.menu-btn {
  width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center; padding: 0;
  background: var(--plank); color: var(--ink); border: 3px solid var(--ink);
  transition: transform .2s var(--out);
}
.menu-btn:hover { transform: rotate(90deg); }
/* Le coin du menu : le bouton, et le chrono de la partie dessous (à sa gauche quand les bandeaux sont en colonnes). */
.dock { display: grid; justify-items: center; gap: 4px; }
/* Le chrono : une petite planche cernée d'encre. Chiffres de même largeur, pour qu'il ne tremble pas à chaque seconde. */
.clock {
  padding: 1px 7px; border-radius: 999px; background: var(--plank); color: var(--ink); border: 2.5px solid var(--ink);
  font-weight: 800; font-size: .8rem; line-height: 1.3; font-variant-numeric: tabular-nums; white-space: nowrap;
  min-width: 54px; text-align: center; /* la même largeur de « 0:00 » à « 59:59 », puis « 1h02 » */
}
/* En vis-à-vis, le joueur d'en face a le sien, tourné vers lui, dans le coin opposé. Les bandeaux du haut se poussent
   de sa largeur (54px, plus 8px d'écart) : ils gardent ainsi la même taille que ceux du bas, qui laissent
   la même place au bouton de menu. */
.clock-far { display: none; }
.table.visavis.strips .clock-far { display: block; grid-area: 1 / 1; place-self: center start; rotate: 180deg; }
.table.visavis.strips .seat-A, .table.visavis.strips .seat-B { margin-left: 62px; }
.table.visavis.strips:not(.no-B) .seat-A { margin-right: -62px; }

/* ---------- Plateau et chevaux ---------- */
.board { width: var(--board); height: var(--board); }
.spot {
  position: absolute; width: 38%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; pointer-events: none;
  border: 5px solid var(--white); transition: left .5s var(--out), top .5s var(--out);
}
.calling .spot { animation: halo 1.4s ease-out var(--calls, 1); }
@keyframes halo { from { transform: scale(.86); opacity: 1; } to { transform: scale(1.14); opacity: 0; } }
.board-art { display: block; width: 100%; height: 100%; }
.board.shake { animation: secousse .3s; }
@keyframes secousse { 20% { transform: translate(-6px, 3px) rotate(-.6deg); } 50% { transform: translate(6px, -4px) rotate(.6deg); } 80% { transform: translate(-3px, 2px); } }
.board.arrive::after {
  content: ''; position: absolute; left: 50%; top: 50%; width: 22%; aspect-ratio: 1; border-radius: 50%;
  border: 5px solid var(--white); translate: -50% -50%; pointer-events: none; animation: onde .55s ease-out both;
}
@keyframes onde { from { transform: scale(.3); opacity: 1; } to { transform: scale(2.4); opacity: 0; } }

.pieces { position: absolute; inset: 0; }
.previews { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.previews svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.previews polyline {
  fill: none; stroke: var(--white); stroke-width: .15; stroke-dasharray: .3 .26; stroke-linecap: round; stroke-linejoin: round;
  animation: file .7s linear infinite; transition: opacity .2s;
}
.previews polyline.kill { stroke: var(--red); stroke-width: .18; }
.previews .sortie { fill: rgba(255, 253, 246, .35); stroke: var(--white); stroke-width: .12; animation: palpite .6s ease-in-out infinite alternate; transform-box: fill-box; transform-origin: center; transition: opacity .2s; }
.previews .sortie.kill { fill: rgba(229, 65, 45, .3); stroke: var(--red); }
@keyframes file { to { stroke-dashoffset: -.56; } }
.ghost.exit::after { display: none; }
.ghost.exit .tok { opacity: .75; scale: .82; }
.ghost {
  position: absolute; width: calc(100% / 15 * 1.06); aspect-ratio: 1; translate: -50% -50%; padding: 0; border: 0; background: none;
  border-radius: 50%; pointer-events: auto; cursor: pointer; transition: opacity .2s; animation: apparait .3s var(--out) both;
}
.ghost:disabled { cursor: default; }
.ghost .tok { display: block; width: 100%; height: 100%; opacity: .6; }
.ghost svg { display: block; width: 100%; height: 100%; }
.ghost::before { content: ''; position: absolute; inset: -30%; border-radius: 50%; }
.ghost::after { content: ''; position: absolute; inset: -8%; border-radius: 50%; border: 3px dashed var(--white); }
.ghost.on-kill .tok, .ghost.on-kill::after { display: none; }
.previews .dim { opacity: .15; }
@keyframes apparait { from { transform: scale(.3); opacity: 0; } }
.piece {
  position: absolute; width: calc(100% / 15 * 1.06); aspect-ratio: 1; padding: 0; border: 0; background: none;
  translate: -50% -50%; z-index: 1; border-radius: 50%;
  transition: left var(--step, .13s) linear, top var(--step, .13s) linear, scale .4s var(--out);
  filter: drop-shadow(0 3px 2px rgba(3, 24, 28, .45));
}
.piece:disabled { pointer-events: none; cursor: default; }
.piece .tok { display: block; width: 100%; height: 100%; }
.piece svg { display: block; width: 100%; height: 100%; }
.piece.target { z-index: 4; }
.piece.target::after {
  content: ''; position: absolute; inset: -22%; border-radius: 50%; border: 5px dashed var(--red);
  animation: vise 2.4s linear infinite, palpite .5s ease-in-out infinite alternate;
}
.piece.target .tok { animation: tremble .18s linear infinite; }
@keyframes vise { to { rotate: 360deg; } }
@keyframes palpite { from { scale: 1; } to { scale: 1.18; } }
@keyframes tremble { 25% { transform: translate(-5%, 3%); } 75% { transform: translate(5%, -3%); } }
.piece.moving { z-index: 5; }
/* Cheval garé : il s'efface sous une grande coche tamponnée en plein milieu, lisible sur toutes les couleurs et jamais cachée par le voisin. */
.coche {
  position: absolute; inset: -6%; scale: 0; rotate: -8deg; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 26l10 10L39 13' stroke='%230B2228' stroke-width='12.5'/%3E%3Cpath d='M9 26l10 10L39 13' stroke='%23FFFDF6' stroke-width='6.6'/%3E%3C/svg%3E") center / contain no-repeat;
}
.piece.parked .coche { scale: 1; animation: tamponne .45s var(--out) both; }
.table.visavis .piece.top .coche { rotate: 172deg; } /* en vis-à-vis, la coche se lit depuis le bord de son joueur */
@keyframes tamponne { from { transform: scale(2.6); opacity: 0; } }
.piece.parked .tok { filter: saturate(.55) brightness(.7); }
.piece.parked .gear { display: none; }
.piece.parked::after { content: ''; position: absolute; inset: -7%; border-radius: 50%; border: 3px solid var(--white); }
/* Bouteille à la mer, et ce qu'elle laisse sur un cheval : bouée ou casier. */
.bottle {
  position: absolute; width: calc(100% / 15 * .98); aspect-ratio: 1; translate: -50% -50%; pointer-events: none;
  transition: left 1.4s ease-in-out, top 1.4s ease-in-out; filter: drop-shadow(0 3px 2px rgba(3, 24, 28, .45)); animation: apparait .45s var(--out) both;
}
.bottle svg { display: block; width: 100%; height: 100%; }
.calling .bottle svg { animation: houle 1.6s ease-in-out var(--calls, 1); }
@keyframes houle { 25% { transform: translateY(1.5px) rotate(-7deg); } 75% { transform: translateY(-1.5px) rotate(7deg); } }
.gear { position: absolute; inset: -16.7%; pointer-events: none; }
.gear svg { animation: apparait .35s var(--out) both; }
.piece.aim { z-index: 4; cursor: pointer; }
.piece.aim::before { content: ''; position: absolute; inset: -32%; border-radius: 50%; }
.piece.aim::after {
  content: ''; position: absolute; inset: -20%; border-radius: 50%; border: 5px solid var(--yellow);
  animation: appelle 1s ease-out infinite;
}
.piece.aim .tok { animation: trepigne .5s ease-in-out infinite alternate; }
.bigdie.pickable { pointer-events: auto; cursor: pointer; z-index: 9; }
.bigdie.pickable::after { content: ''; position: absolute; inset: -16%; border-radius: 24%; border: 5px solid var(--white); animation: halo 1.4s ease-out infinite; }
.bigdie.pickable:focus-visible { outline: 3px solid var(--white); outline-offset: 8px; }
.piece.can { z-index: 3; }
.piece.can::before { content: ''; position: absolute; inset: -32%; border-radius: 50%; }
.piece.can::after {
  content: ''; position: absolute; inset: -12%; border-radius: 50%; border: 3px solid var(--white);
  animation: appelle 1s ease-out infinite;
}
.piece.can.kill::after { border-color: var(--red); border-width: 5px; inset: -18%; }
.piece.can .tok { animation: trepigne .5s ease-in-out infinite alternate; }
.piece.can:hover .tok, .piece.can:focus-visible .tok { animation-duration: .25s; }
@keyframes appelle { from { transform: scale(.8); opacity: 1; } to { transform: scale(1.5); opacity: 0; } }
@keyframes trepigne { from { transform: translateY(4%) scale(1.02, .96); } to { transform: translateY(-16%) scale(1.12); } }
.piece.hop .tok { animation: saut var(--step, .135s) ease-out; }
@keyframes saut { 50% { transform: translateY(-40%) scale(1.22); } }
.piece.leap { transition: left .4s var(--out), top .4s var(--out); }
.piece.leap .tok { animation: bond .42s ease-out; }
@keyframes bond { 40% { transform: translateY(-90%) scale(1.6) rotate(-14deg); } 85% { transform: translateY(6%) scale(1.1, .86); } }
.piece.hit .tok { animation: ecrase .2s var(--out) forwards; }
@keyframes ecrase { to { transform: scale(1.3, .5) translateY(30%); } }
.piece.fly { z-index: 6; transition: left .5s var(--out), top .5s var(--out); }
.piece.fly .tok { animation: vrille .5s ease-out; }
@keyframes vrille { 50% { transform: scale(1.7) rotate(360deg); } 100% { transform: rotate(720deg); } }

/* ====================== Saynètes ====================== */
.scene {
  position: absolute; inset: 0; z-index: 20; display: grid; place-items: center; overflow: hidden;
  background: var(--bg); color: var(--on); cursor: pointer;
  clip-path: circle(0 at var(--ox) var(--oy)); animation: ouvre .5s var(--out) forwards;
}
.scene.leaving { animation: ferme .26s ease-in forwards; }
@keyframes ouvre { to { clip-path: circle(150% at var(--ox) var(--oy)); } }
@keyframes ferme { from { clip-path: circle(150% at var(--ox) var(--oy)); } to { clip-path: circle(0 at var(--ox) var(--oy)); } }
.scene-inner { display: grid; justify-items: center; width: min(100%, 40rem); padding: 16px; text-align: center; }
.scene.flip .scene-inner { rotate: 180deg; }
.stage { width: max(150px, min(var(--tw, 100vw) * .84, 600px, var(--th, 100vh) - 250px)); aspect-ratio: 1; overflow: visible; }
.on-sea .scene-word, .on-sea .win-title { text-shadow: .045em .06em 0 var(--ink); }
.scene-word {
  font: 400 clamp(3rem, 14vmin, 6rem)/.9 var(--display); rotate: -6deg; margin-top: 14px; position: relative; animation: claque .45s 1.2s var(--out) both;
}
@keyframes claque { from { opacity: 0; transform: scale(2.8) rotate(-12deg); } }
.scene-sub { position: relative; margin-top: 14px; max-width: 30ch; font-weight: 800; font-size: clamp(1rem, 3.6vmin, 1.35rem); line-height: 1.3; text-wrap: balance; animation: accoste .45s 1.45s var(--out) both; }

.grand-homard, .grande-baleine { animation: monte .5s var(--out) both; }
@keyframes monte { from { transform: translateY(320px); } }
.pince { transform-origin: 150px 345px; animation: clac 2.5s ease-in both; }
@keyframes clac {
  0%, 22% { transform: rotate(-36deg); } 29% { transform: rotate(-17deg); } 36%, 41% { transform: rotate(-32deg); }
  47% { transform: rotate(-16deg); } 52% { transform: rotate(-19deg); } 100% { transform: rotate(-17deg); }
}
.proie-pince { animation: serre 2.5s both; }
@keyframes serre {
  0% { transform: scale(0); } 12% { transform: scale(1.1); } 16%, 26% { transform: scale(1); } 29% { transform: scale(.66, 1.14); }
  36%, 42% { transform: scale(1); } 47% { transform: scale(.6, 1.18); } 60% { transform: scale(.66, 1.12) rotate(-5deg); }
  75% { transform: scale(.66, 1.12) rotate(5deg); } 100% { transform: scale(.66, 1.12); }
}
.eclat { opacity: 0; }
.eclat-pince { animation: eclat 2.5s both; }
@keyframes eclat {
  0%, 28% { opacity: 0; transform: scale(.7); } 29% { opacity: 1; transform: scale(1); } 35% { opacity: 0; transform: scale(1.35); }
  46% { opacity: 0; transform: scale(.7); } 47% { opacity: 1; transform: scale(1); } 58%, 100% { opacity: 0; transform: scale(1.5); }
}

.pecheur-scene { animation: debarque .5s var(--out) both; }
@keyframes debarque { from { transform: translateX(-280px); } }
.ligne { animation: lancer 2.5s ease-in-out both; }
@keyframes lancer {
  0% { transform: translateY(70px); } 22% { transform: translateY(374px); } 28% { transform: translateY(360px); }
  34% { transform: translateY(378px); } 40% { transform: translateY(366px); } 68%, 100% { transform: translateY(128px); }
}
.prise { transform-origin: 306px 0; animation: pendre 2.5s ease-in-out both; }
@keyframes pendre {
  0%, 24% { opacity: 0; } 26% { opacity: 1; transform: rotate(0); } 52% { transform: rotate(13deg); } 66% { transform: rotate(-15deg); }
  78% { transform: rotate(10deg); } 90% { transform: rotate(-5deg); } 100% { opacity: 1; transform: rotate(0); }
}
.gouttes { opacity: 0; }
.scene-peche .gouttes { animation: gicle .55s .52s ease-out both; }
.scene-plongeon .gouttes { animation: gicle .6s .76s ease-out both; }
@keyframes gicle { 0% { opacity: 1; transform: scale(.2); } 70% { opacity: 1; } 100% { opacity: 0; transform: scale(1.5); } }

.plongeur { animation: plonge 2.5s both; }
@keyframes plonge {
  0% { transform: translate(-130px, -170px) rotate(48deg); animation-timing-function: ease-in; }
  31% { transform: translate(196px, 246px) rotate(48deg); animation-timing-function: linear; }
  38% { transform: translate(262px, 480px) rotate(48deg); }
  52% { transform: translate(296px, 480px) rotate(0); animation-timing-function: cubic-bezier(.16, 1, .3, 1); }
  72% { transform: translate(292px, 236px) rotate(-10deg); } 86% { transform: translate(292px, 252px) rotate(-4deg); } 100% { transform: translate(292px, 246px) rotate(-6deg); }
}
.proie-plongeon { animation: ejecte 2.5s both; }
@keyframes ejecte {
  0% { transform: translateY(-6px); } 15% { transform: translateY(6px); } 30% { transform: translateY(-4px); animation-timing-function: cubic-bezier(.2, .8, .4, 1); }
  62%, 100% { transform: translate(-250px, -600px) rotate(-560deg); }
}

.jet { transform-origin: 176px 284px; animation: jaillit 2.5s both; }
@keyframes jaillit { 0%, 32% { transform: scaleY(0); opacity: 0; } 33% { transform: scaleY(0); opacity: 1; } 40% { transform: scaleY(1.1); } 46%, 66% { transform: scaleY(1); } 84% { transform: scaleY(0); opacity: 1; } 85%, 100% { transform: scaleY(0); opacity: 0; } }
.grande-baleine .buee { display: none; }
.proie-souffle { animation: envol 2.5s both; }
@keyframes envol {
  0% { transform: translateY(-440px); } 16% { transform: translateY(0); } 20% { transform: translateY(-16px); } 24%, 33% { transform: translateY(0); }
  40% { transform: translateY(-104px) rotate(18deg); } 47% { transform: translateY(-92px) rotate(-14deg); } 54% { transform: translateY(-106px) rotate(12deg); }
  60% { transform: translateY(-96px) rotate(-8deg); animation-timing-function: ease-in; } 80%, 100% { transform: translateY(-700px) rotate(420deg); }
}

/* ---------- Message de la bouteille ---------- */
.scene.note { --bg: rgba(8, 58, 64, .86); }
.parchemin {
  display: grid; justify-items: center; gap: 10px; width: min(100%, 22rem); padding: 22px 24px 26px; rotate: -2deg;
  border-radius: 28px; background: var(--plank); color: var(--ink); border: 3px solid var(--ink); box-shadow: 0 24px 50px -12px rgba(3, 24, 28, .7);
  animation: deroule .5s .12s var(--out) both;
}
.parchemin svg { width: clamp(84px, 22vmin, 128px); height: auto; }
.parchemin-word { font: 400 clamp(1.5rem, 6vmin, 2.2rem)/1 var(--display); text-wrap: balance; }
.parchemin-line { font-weight: 700; line-height: 1.3; max-width: 26ch; text-wrap: balance; }
@keyframes deroule { from { opacity: 0; transform: translateY(46px) scale(.8) rotate(-7deg); } }

/* ---------- Victoire ---------- */
.win { cursor: default; }
.win .scene-inner { gap: 6px; position: relative; }
.stage-win { width: max(110px, min(var(--tw, 100vw) * .62, 400px, var(--th, 100vh) - 500px)); }
/* La fête dure une douzaine de secondes, puis l'écran de victoire se pose : il peut rester ouvert sans rien consommer. */
.stage-win .pince { animation: clac-boucle 1.1s ease-in 11 forwards; }
@keyframes clac-boucle { 0%, 40% { transform: rotate(-32deg); } 55%, 85% { transform: rotate(-17deg); } 100% { transform: rotate(-32deg); } }
.stage-win .proie-pince { animation: serre-boucle 1.1s 11 forwards; }
@keyframes serre-boucle { 0%, 45% { transform: scale(1); } 55%, 85% { transform: scale(.66, 1.14); } 100% { transform: scale(1); } }
.stage-win .eclat-pince { animation: none; }
.heros { animation: jubile .55s ease-in-out 22 alternate forwards; }
@keyframes jubile { from { transform: translateY(8px) rotate(-4deg); } to { transform: translateY(-20px) rotate(4deg); } }
.eclat-tourne { opacity: .55; animation: tourne 12s linear 1; }
@keyframes tourne { to { transform: rotate(360deg); } }
.guedille { animation: sert .7s .35s var(--out) both; }
@keyframes sert { from { transform: translate(260px, -120px) rotate(24deg); } }
.vapeur path { animation: fume 1.8s ease-in-out 7 forwards; }
.vapeur path:nth-child(2) { animation-delay: -.6s; } .vapeur path:nth-child(3) { animation-delay: -1.2s; }
@keyframes fume { 0% { opacity: 0; transform: translateY(14px); } 40% { opacity: .9; } 100% { opacity: 0; transform: translateY(-22px); } }
.win-title { font: 400 clamp(2.4rem, 10vmin, 4.75rem)/.95 var(--display); rotate: -5deg; text-wrap: balance; position: relative; animation: claque .5s .5s var(--out) both; }
.win-title span { display: block; overflow-wrap: anywhere; }
.win .scene-sub { animation-delay: .8s; }
.recap { position: relative; margin-top: 14px; border-collapse: collapse; font-variant-numeric: tabular-nums; font-size: clamp(.8rem, 2.2vmin, .95rem); animation: accoste .5s .9s var(--out) both; }
.recap caption { font-weight: 800; padding-bottom: 6px; }
.recap th, .recap td { padding: 4px 8px; text-align: right; border-top: 2px solid color-mix(in srgb, currentColor 30%, transparent); }
.recap thead th { font-weight: 800; font-size: .85em; border-top: 0; }
.recap th:first-child { text-align: left; }
.recap tbody th { font-weight: 800; }
.recap em { font-style: normal; font-size: .8em; padding: .1em .5em; border-radius: 6px; background: var(--on); color: var(--bg); margin-left: 4px; }
.recap b { font: 400 1.15em/1 var(--display); }
.win.wide .scene-inner { width: min(100%, 68rem); grid-template-columns: auto auto; justify-content: center; align-items: center; column-gap: 40px; }
.win.wide .stage-win { grid-area: 1 / 1; width: max(110px, min(var(--tw) * .36, 400px, var(--th) - 330px)); }
.win.wide .win-title { grid-area: 2 / 1; }
.win.wide .scene-sub { grid-area: 3 / 1; }
.win.wide .recap { grid-area: 1 / 2 / 3 / 3; align-self: end; margin: 0 0 12px; }
.win.wide .win-actions { grid-area: 3 / 2; margin-top: 0; align-self: start; }
.win-note { position: relative; margin-top: 10px; font-weight: 800; min-height: 1.5em; }
.win-note:empty { display: none; }
.win.wide .win-note { grid-area: 4 / 2; }
.win [aria-pressed="true"] { transform: translateY(4px); border-bottom-width: 4px; margin-bottom: 4px; }
.win-actions { position: relative; display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 22px; animation: accoste .5s 1s var(--out) both; }
.win :focus-visible { outline-color: var(--on); }
.win .btn-main, .win .btn-main:hover { background: var(--on); color: var(--bg); border-color: var(--ink); }
.confetti { position: absolute; top: 0; left: 0; width: 100%; height: 100%; place-self: start; pointer-events: none; }
.confetti i { position: absolute; top: -30px; width: 12px; height: 20px; border-radius: 3px; animation: tombe linear 2 both; }
@keyframes tombe { from { transform: translateY(0) rotate(var(--r)); } to { transform: translateY(1500px) rotate(calc(var(--r) + 900deg)); } }

/* ====================== Menu ====================== */
.sheet {
  width: min(100vw - 32px, 27rem); max-height: calc(100dvh - 32px); padding: 24px; border-radius: 28px;
  background: var(--plank); color: var(--ink); border: 3px solid var(--ink); box-shadow: 0 24px 50px -12px rgba(3, 24, 28, .7);
}
.sheet[open] { display: grid; gap: 16px; animation: accoste .35s var(--out); }
.sheet.rot { rotate: 90deg; max-height: calc(100vw - 32px); width: min(100vh - 32px, 27rem); }
.sheet::backdrop { background: rgba(8, 58, 64, .72); }
.sheet h2 { font: 400 1.75rem/1.1 var(--display); }
.sheet :focus-visible, .sheet .switch input:focus-visible + .knob { outline-color: var(--ink); }
.sheet { overflow-y: auto; }
.sheet h3 { font: 400 1.15rem/1.2 var(--display); margin: 0 0 8px; }
.mini { display: inline-block; width: 26px; height: 26px; flex: none; vertical-align: middle; margin-right: 8px; }
.mini svg { display: block; width: 100%; height: 100%; }
.scores-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.scores-table th, .scores-table td { padding: 6px 4px; text-align: right; border-bottom: 2px solid color-mix(in srgb, var(--ink) 18%, transparent); }
.scores-table thead th { font-size: .8rem; font-weight: 800; }
.scores-table th:first-child { text-align: left; }
.scores-table tbody th { font: 400 1.05rem/1.2 var(--display); }
.scores-table td:nth-child(2) { font: 400 1.2rem/1 var(--display); }
.scores-list { display: grid; gap: 8px; margin-top: 12px; padding: 0; list-style: none; font-size: .95rem; }
.scores-list li { display: flex; align-items: flex-start; }
.scores-list small { display: block; font-size: .85rem; }
.scores-empty { font-size: .95rem; }
.sheet summary { font-weight: 800; cursor: pointer; padding: 6px 0; }
.sheet ul { display: grid; gap: 8px; margin-top: 8px; padding-left: 1.2em; list-style: disc; font-size: .95rem; max-width: 62ch; }
.sheet-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 4px; }

@media (max-width: 520px) {
  .avatar { width: 44px; height: 44px; }
  .die { min-height: 62px; padding: 5px 12px 5px 8px; gap: 8px; font-size: 1rem; --s: 44px; }
  .panel-inner { gap: 8px; padding: 6px 8px 6px 6px; }
  .strips:not([data-n="2"]) .avatar { display: none; }
  .strips:not([data-n="2"]) .panel-inner { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 6px; padding: 8px; }
  .strips:not([data-n="2"]) .pips { justify-content: center; }
  .strips:not([data-n="2"]) .marks { justify-content: center; }
  .strips:not([data-n="2"]) .status { font-size: .85rem; }
  .player { padding-right: 16px; gap: 10px; }
  .tray-tok { width: 46px; height: 46px; }
  .code b { width: 40px; height: 40px; font-size: 1.25rem; }
  .code-input { font-size: 1.15rem; }
  .join { gap: 8px; }
  .join .btn { padding-inline: .9em; }
  .relay { max-width: 7em; font-size: .85rem; padding: .5em .7em; }
  /* Téléphone : libellé et bouées sur une seule ligne, pour que l'accueil tienne sans défiler. */
  .setup { grid-template-rows: minmax(176px, 1fr) auto auto; }
  .crew, .deck { gap: 14px; }
  .crew { padding-top: 14px; }
  .extras .btn-small { font-size: .85rem; padding: .55em .8em; }
  .seg, .row { flex-wrap: nowrap; gap: 8px; }
  .seg-label { font-size: 1.05rem; line-height: 1.1; text-wrap: balance; }
  .seg-opts { gap: 8px; }
  .seg-opts label span { width: 50px; height: 50px; font-size: 1.2rem; }
  .extras { margin-block: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  /* Le homard endormi garde ses « z », immobiles. */
  .vol-zzz b { animation: none; }
  .vol-zzz b + b { translate: 8px -10px; }
}
