/* ─────────────────────────────────────────────────────────────────────────────
   Fondations : police, couleurs, boutons, champs, barre du haut.
   Les autres feuilles (screens, game, fx) s'appuient sur les variables d'ici.
   ───────────────────────────────────────────────────────────────────────────── */

/* Archivo est une police « variable » : un seul fichier contient toutes les
   graisses (100 à 900) ET toutes les largeurs (62 % = étroite, 125 % = large).
   On joue sur ces deux axes pour toute la hiérarchie du jeu. Licence libre OFL. */
@font-face {
  font-family: 'Archivo';
  src: url('/fonts/archivo-variable.woff2') format('woff2');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}

:root {
  /* Encres : le fond, du plus sombre au plus clair (un violet profond, pas un noir). */
  --ink-0: #0d0622;
  --ink-1: #160a35;
  --ink-2: #22124f;
  --ink-3: #321d70;
  --ink-4: #4a31a0;

  /* Papier : le texte clair, teinté de la même famille que le fond. */
  --paper: #f7f1ff;
  --paper-dim: #c7b8f0;
  --paper-mute: #a593e0;

  /* Les huit couleurs proposées aux joueurs : un tour complet du cercle des
     teintes, toutes vives et assez lumineuses pour porter un texte sombre.
     Les numéros sont dans l'ordre d'attribution automatique (le 2ᵉ joueur
     reçoit une couleur très différente du 1ᵉʳ) ; le sélecteur, lui, les
     affiche dans l'ordre de l'arc-en-ciel (voir COLOR_ORDER dans dom.js). */
  --p0: #ffe01a; /* jaune */
  --p1: #ff5cbf; /* rose */
  --p2: #19e3ff; /* turquoise */
  --p3: #7dff3c; /* vert */
  --p4: #ff9422; /* orange */
  --p5: #b99bff; /* violet */
  --p6: #5b9dff; /* bleu */
  --p7: #ff5148; /* rouge */
  --danger: #ff6278;

  /* --c : la couleur « du moment » (un joueur). Redéfinie localement en JS. */
  --c: var(--p0);

  --font: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* part vite, se pose en douceur */
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* dépasse un peu, puis revient */
  --radius: 26px;
  --radius-s: 14px;
  --gap: clamp(10px, 1.5vw, 18px);
  --pad: clamp(12px, 2.4vw, 28px);
  --shadow: 0 14px 28px -12px rgb(5 2 16 / 0.85);

  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* L'attribut HTML `hidden` doit toujours gagner, même sur un élément en grid ou flex. */
[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--ink-4) var(--ink-0);
}

/* L'écran d'entrée et le classement final recouvrent toute la fenêtre, et
   défilent eux-mêmes quand ils sont plus hauts qu'elle. Tant que l'un d'eux
   est affiché, la page du dessous ne défile plus : sans cela, on voyait deux
   barres de défilement côte à côte (la leur, et celle de la page cachée). */
html:has(.splash:not([hidden]), .results:not([hidden])) {
  overflow: hidden;
}

body {
  margin: 0;
  /* Jeu installé sur l'écran d'accueil : on s'écarte de l'encoche, de l'heure
     et de la barre du bas (ces valeurs valent 0 dans un navigateur ordinaire). */
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  min-height: 100dvh;
  font: 500 1rem/1.45 var(--font);
  color: var(--paper);
  background-color: var(--ink-1);
  /* Un semis de points, comme les faces d'un dé. */
  background-image: radial-gradient(var(--ink-2) 2.5px, transparent 3px);
  background-size: 30px 30px;
  overflow-x: hidden;
  caret-color: var(--p0);
  -webkit-tap-highlight-color: transparent;
}

::selection {
  background: var(--p0);
  color: var(--ink-0);
}

h1,
h2,
p,
ol {
  margin: 0;
}

ol {
  padding: 0;
  list-style: none;
}

button,
input {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
}

/* Anneau de focus au clavier : bien visible, sur tous les éléments. */
:focus-visible {
  outline: 3px solid var(--paper);
  outline-offset: 3px;
}

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

/* Les annonces pour lecteurs d'écran sont le dernier élément de la page :
   sans cela, leur pixel dépassait en bas et faisait apparaître une barre de
   défilement inutile sur les grands écrans. */
#live {
  position: fixed;
  top: 0;
  left: 0;
}

.icon {
  width: 1.25em;
  height: 1.25em;
  flex: none;
}

/* ── Étiquette « robot » ─────────────────────────────────────────────────── */
/* La même partout où un robot est nommé : salle d'attente, cartes des joueurs,
   table de jeu, classement final (voir botBadge dans js/ui/dom.js). */

.bot-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: none;
  padding: 2px 8px 2px 5px;
  border-radius: 7px;
  background: var(--ink-0);
  color: var(--paper);
  font-weight: 800;
  font-stretch: 100%;
  font-size: 0.7rem;
  line-height: 1.3;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.bot-badge .icon {
  width: 1.3em;
  height: 1.3em;
}

/* ── Boutons ─────────────────────────────────────────────────────────────── */

.btn {
  --btn-bg: var(--ink-3);
  --btn-fg: var(--paper);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  min-height: 52px;
  padding: 0.7em 1.5em;
  border: 0;
  border-radius: var(--radius-s);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 800;
  font-stretch: 112%;
  font-size: 1rem;
  line-height: 1.1;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  /* Une arête sombre en bas (comme une touche) et une ombre portée douce. */
  box-shadow:
    inset 0 -4px 0 rgb(13 6 34 / 0.28),
    var(--shadow);
  transition:
    transform 180ms var(--ease-spring),
    filter 180ms,
    box-shadow 180ms;
  user-select: none;
}

.btn:hover:not(:disabled) {
  transform: translateY(-3px) scale(1.02);
  filter: brightness(1.12);
}

.btn:active:not(:disabled) {
  transform: translateY(2px) scale(0.96);
  box-shadow: inset 0 -1px 0 rgb(13 6 34 / 0.28);
  transition-duration: 60ms;
}

.btn:disabled {
  cursor: not-allowed;
  box-shadow: none;
  --btn-bg: var(--ink-2);
  --btn-fg: var(--paper-mute);
}

.btn--primary {
  --btn-bg: var(--p0);
  --btn-fg: var(--ink-0);
}

.btn--ghost {
  --btn-bg: transparent;
  box-shadow: inset 0 0 0 2px var(--ink-4);
}

.btn--ghost:active:not(:disabled) {
  box-shadow: inset 0 0 0 2px var(--paper-dim);
}

.btn--xl {
  min-height: 64px;
  font-size: 1.2rem;
  font-stretch: 125%;
  font-weight: 900;
}

.btn--small {
  min-height: 40px;
  padding: 0.4em 1em;
  font-size: 0.85rem;
}

.btn--block {
  width: 100%;
}

.icon-btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-s);
  background: var(--ink-2);
  color: var(--paper);
  transition:
    transform 180ms var(--ease-spring),
    background-color 180ms;
}

.icon-btn:hover {
  transform: translateY(-2px) rotate(-6deg);
  background: var(--ink-3);
}

.icon-btn:active {
  transform: scale(0.9);
}

/* ── Champs de saisie ────────────────────────────────────────────────────── */

.field {
  display: grid;
  gap: 6px;
}

.field label {
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--paper-dim);
}

:is(.field, .local-names) input {
  width: 100%;
  min-height: 52px;
  padding: 0 16px;
  border: 2px solid var(--ink-4);
  border-radius: var(--radius-s);
  background: var(--ink-0);
  font-weight: 700;
  font-size: 1.1rem;
  transition:
    border-color 160ms,
    transform 220ms var(--ease-spring);
}

:is(.field, .local-names) input::placeholder {
  color: var(--paper-mute);
  font-weight: 500;
}

:is(.field, .local-names) input:focus-visible {
  outline: none;
  border-color: var(--p0);
  transform: scale(1.015);
}

.field .input--code {
  font-weight: 900;
  font-stretch: 125%;
  font-size: 1.4rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  text-align: center;
  padding-left: calc(16px + 0.32em); /* compense l'espacement après la dernière lettre */
}

.field .input--code::placeholder {
  letter-spacing: 0.32em;
}

.form-error {
  padding: 10px 14px;
  border-radius: var(--radius-s);
  background: var(--danger);
  color: var(--ink-0);
  font-weight: 700;
}

/* ── Onglets (deux choix côte à côte, celui qui est actif est plein) ─────── */

.tabs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 4px;
  padding: 4px;
  border-radius: var(--radius-s);
  background: var(--ink-0);
}

.tabs__tab {
  min-height: 44px;
  padding: 0 8px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--paper-dim);
  font-weight: 800;
  font-stretch: 86%; /* resserré : « Sur cet appareil » tient sur une ligne au téléphone */
  font-size: 0.9rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
  transition:
    background-color 200ms,
    color 200ms,
    transform 180ms var(--ease-spring);
}

.tabs__tab:hover {
  color: var(--paper);
}

.tabs__tab:active {
  transform: scale(0.96);
}

.tabs__tab[aria-selected='true'] {
  background: var(--paper);
  color: var(--ink-0);
}

/* ── Phrases du chat : un onglet par thème, puis les phrases à toucher ───── */
/* Utilisé en salle d'attente (toujours visible) et en partie (derrière le
   bouton « Dire »). */

.phrases {
  display: grid;
  gap: 8px;
}

/* Quatre onglets doivent tenir sur un téléphone. */
.phrases__tabs .tabs__tab {
  min-height: 40px;
  padding: 0 4px;
  font-size: clamp(0.72rem, 3.1vw, 0.84rem);
}

.phrases__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}

.phrase {
  min-height: 46px;
  padding: 6px 12px;
  border: 0;
  border-radius: 12px;
  background: var(--ink-3);
  color: var(--paper);
  font-weight: 700;
  font-size: 0.9rem;
  line-height: 1.2;
  text-align: left;
  text-wrap: balance;
  transition:
    transform 180ms var(--ease-spring),
    background-color 180ms;
}

.phrase:hover {
  transform: translateY(-2px);
  background: var(--ink-4);
}

.phrase:active {
  transform: scale(0.95);
}

/* ── Sélecteur de couleur : huit pastilles ───────────────────────────────── */

.swatches {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: 6px;
}

.swatch {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  min-width: 0;
  max-width: 48px;
  padding: 0;
  border: 0;
  border-radius: 30%;
  background: var(--c);
  color: var(--ink-0);
  transition:
    transform 200ms var(--ease-spring),
    opacity 200ms,
    box-shadow 200ms;
}

.swatch .icon {
  width: 55%;
  height: 55%;
  stroke-width: 3;
  transform: scale(0);
  transition: transform 260ms var(--ease-spring);
}

.swatch:hover:not(:disabled) {
  transform: translateY(-3px) scale(1.08);
}

.swatch:active:not(:disabled) {
  transform: scale(0.9);
}

/* La couleur choisie : cerclée, avec une coche. */
.swatch.is-selected {
  box-shadow:
    0 0 0 3px var(--ink-2),
    0 0 0 6px var(--c);
}

.swatch.is-selected .icon {
  transform: scale(1);
}

/* Couleur déjà prise par un autre joueur : elle garde sa teinte (c'est bien
   SA couleur), porte son initiale, et n'est plus cliquable. */
.swatch.is-taken {
  cursor: not-allowed;
  border-radius: 50%;
  transform: scale(0.86);
}

.swatch__owner {
  grid-area: 1 / 1;
  display: grid;
  font-weight: 900;
  font-stretch: 112%;
  font-size: 0.95rem;
  line-height: 1;
}

/* Couleur prise par un robot : son icône, à la place d'une initiale. */
.swatch__owner .icon {
  width: 1.45em;
  height: 1.45em;
  stroke-width: 2;
  transform: none;
}

.swatch .icon {
  grid-area: 1 / 1;
}

/* ── Anecdotes « Le savais-tu ? » ────────────────────────────────────────── */
/* Le bloc a toujours la même taille : celle qu'il faut à la plus longue des
   anecdotes (voir .facts__texts). Rien ne bouge donc quand le texte change. */

.facts-slot {
  width: 100%;
  max-width: 56ch;
}

.facts {
  display: grid;
  gap: 6px;
  padding: 10px 10px 14px 14px;
  border-radius: var(--radius-s);
  background: var(--ink-2);
  text-align: left;
  cursor: pointer; /* un clic sur la boîte passe à l'anecdote suivante */
  user-select: none;
  transition: background-color 200ms;
}

.facts:hover {
  background: var(--ink-3);
}

.facts:hover .facts__arrow {
  background: var(--ink-4);
}

.facts__head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.facts .row__icon {
  flex: none;
  width: 20px;
  height: 20px;
  color: var(--p0);
}

.facts__label {
  flex: 1;
  color: var(--p0);
  font-weight: 800;
  font-stretch: 112%;
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.facts__nav {
  display: flex;
  align-items: center;
  gap: 6px;
}

.facts__arrow {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: var(--ink-3);
  color: var(--paper);
  transition:
    transform 180ms var(--ease-spring),
    background-color 180ms;
}

.facts__arrow:hover {
  transform: scale(1.1);
  background: var(--ink-4);
}

.facts__arrow:active {
  transform: scale(0.88);
}

/* Toutes les anecdotes sont superposées dans la même case : une seule est
   visible, mais la case a la hauteur de la plus longue. */
.facts__texts {
  display: grid;
}

.facts__text {
  grid-area: 1 / 1;
  padding-right: 4px;
  color: var(--paper);
  font-weight: 600;
  font-size: 0.98rem;
  line-height: 1.4;
  text-wrap: pretty;
}

.facts__text.is-off {
  visibility: hidden;
}

/* La nouvelle anecdote glisse du côté d'où l'on vient (--from est fixé en JS). */
.facts__text.is-entering {
  animation: fact-in 320ms var(--ease-out) both;
}

@keyframes fact-in {
  from {
    opacity: 0;
    transform: translateX(var(--from, 18px));
  }
}

/* ── Barre du haut ───────────────────────────────────────────────────────── */

.topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 64px;
  padding: 10px var(--pad);
}

.topbar__logo {
  font-weight: 900;
  font-stretch: 125%;
  font-size: 1rem;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper);
  margin-right: auto;
}

/* Sur l'accueil, le grand logo suffit. */
#app[data-screen='home'] .topbar__logo {
  visibility: hidden;
}

.topbar__tools {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--radius-s);
  background: var(--ink-2);
  transition:
    transform 180ms var(--ease-spring),
    background-color 180ms;
}

.chip:hover {
  transform: translateY(-2px);
  background: var(--ink-3);
}

.chip:active {
  transform: scale(0.95);
}

.chip__label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--paper-dim);
}

.chip__code {
  font-weight: 900;
  font-stretch: 125%;
  letter-spacing: 0.14em;
}

/* ── Réglage du son ──────────────────────────────────────────────────────── */
/* Une pastille, trois réglages : la musique, le haut-parleur et le volume.
   Le volume est un dé qui roule sur une rampe de voyants (voir js/ui/sound.js). */

.sound {
  display: flex;
  align-items: center;
  padding-right: 12px;
  border-radius: var(--radius-s);
  background: var(--ink-2);
}

.sound .icon-btn {
  width: 40px;
  background: transparent;
}

/* Musique coupée : la note s'efface. Plus aucun son : le haut-parleur vire au rouge. */
.sound__music[aria-pressed='false'] {
  color: var(--paper-mute);
}

.sound.is-silent .sound__mute {
  color: var(--danger);
}

.volume {
  --die: 24px; /* côté du dé */
  --level: 0.7; /* le volume, de 0 à 1 : fixé en JS */
  position: relative;
  flex: none;
  width: clamp(70px, 12vw, 118px);
  height: 44px; /* zone tactile confortable */
  margin-left: 4px;
  /* Permet au dé de se placer d'après la largeur de cette zone (unités cqi). */
  container-type: inline-size;
}

/* Le vrai curseur : invisible, mais c'est lui qu'on touche. Son poussoir a la
   largeur du dé, pour que le doigt et le dé restent l'un sur l'autre. */
.volume__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  opacity: 0;
  cursor: grab;
}

.volume__input:active {
  cursor: grabbing;
}

.volume__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--die);
  height: 44px;
}

.volume__input::-moz-range-thumb {
  width: var(--die);
  height: 44px;
  border: 0;
}

/* Le décor ne reçoit aucun clic : tout passe au curseur, dessous. */
.volume__rail,
.volume__mover {
  position: absolute;
  pointer-events: none;
}

/* La rampe : une rangée de petits voyants, découpée dans un fond uni par un
   masque. Le motif (un voyant, puis un intervalle) fait environ 6 px ; « round »
   l'ajuste pour qu'il tienne un nombre entier de fois dans la largeur. */
.volume__rail {
  inset: auto 0 7px;
  height: 6px;
  background: var(--ink-4);
  -webkit-mask: linear-gradient(to right, #000 68%, transparent 68%) 0 0 / 6px 100% round;
  mask: linear-gradient(to right, #000 68%, transparent 68%) 0 0 / 6px 100% round;
}

/* Les voyants allumés, jusqu'au dé : du turquoise (tout doux) au rose (à fond),
   comme sur un vumètre. On dévoile plus ou moins de ce dégradé. */
.volume__rail::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, var(--p2), var(--p3) 30%, var(--p0) 56%, var(--p4) 80%, var(--p1));
  clip-path: inset(0 calc(100% - var(--level) * 100%) 0 0);
  transition:
    clip-path 240ms var(--ease-out),
    opacity 240ms;
}

.sound.is-silent .volume__rail::before {
  background: var(--paper-mute);
  opacity: 0.6;
}

/* Le chariot : il porte le dé de gauche à droite, posé sur la rampe. */
.volume__mover {
  left: 0;
  bottom: 14px;
  width: var(--die);
  height: var(--die);
  translate: calc(var(--level) * (100cqi - var(--die))) 0;
  transition: translate 240ms var(--ease-out);
}

/* Le dé. --turn (en degrés) et --lift (en pixels) sont fixés en JS : en
   basculant sur un coin, un dé qui roule se soulève un peu. */
.volume__die {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  padding: 3px;
  border-radius: 6px;
  background: var(--p0);
  color: var(--ink-0);
  transform: translateY(calc(var(--lift, 0) * -1px)) rotate(calc(var(--turn, 0) * 1deg));
  transition:
    transform 320ms var(--ease-spring),
    scale 180ms var(--ease-spring),
    rotate 320ms var(--ease-spring),
    background-color 240ms;
}

.volume__pip {
  place-self: center;
  width: 76%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: currentColor;
}

/* Le « 1 » : un seul gros point, comme sur les dés du jeu. */
.volume[data-face='1'] .volume__pip {
  width: 130%;
}

/* Tenu, le dé colle au doigt : plus aucun délai, et il grossit un peu. */
.volume.is-dragging .volume__mover,
.volume.is-dragging .volume__rail::before {
  transition: none;
}

.volume.is-dragging .volume__die {
  scale: 1.16;
  transition:
    scale 180ms var(--ease-spring),
    background-color 240ms;
}

@media (hover: hover) {
  .volume:hover:not(.is-dragging) .volume__die {
    scale: 1.1;
  }
}

/* Au clavier : l'anneau de focus se dessine autour du dé (le curseur est invisible). */
.volume__input:focus-visible ~ .volume__mover .volume__die {
  outline: 3px solid var(--paper);
  outline-offset: 3px;
}

/* Le dé endormi (volume à zéro ou son coupé) : il penche, ferme les yeux, et ronfle. */
.volume[data-face='0'] .volume__die {
  background: var(--ink-4);
  color: var(--paper-dim);
  transform: none; /* quel que soit le chemin parcouru, son visage reste à l'endroit */
  rotate: -9deg;
}

.volume__die .icon {
  grid-area: 1 / 1 / -1 / -1;
  width: 100%;
  height: 100%;
}

.volume__zzz {
  position: absolute;
  left: 78%;
  bottom: 74%;
  display: none;
  font-weight: 900;
  font-size: 0.6rem;
  line-height: 1;
  color: var(--paper-dim);
}

.volume[data-face='0'] .volume__zzz {
  display: block;
}

.volume__zzz span {
  position: absolute;
  left: 0;
  bottom: 0;
  animation: volume-snore 2.8s ease-in-out infinite;
}

.volume__zzz span + span {
  animation-delay: -1.4s;
}

@keyframes volume-snore {
  from {
    opacity: 0;
    transform: translate(0, 2px) scale(0.6);
  }
  25% {
    opacity: 1;
  }
  to {
    opacity: 0;
    transform: translate(7px, -11px) scale(1.25);
  }
}

/* L'onde qui part du dé quand on pousse le volume à fond (animée en JS). */
.volume__ring {
  position: absolute;
  inset: 0;
  border: 2px solid var(--p1);
  border-radius: 6px;
  opacity: 0;
}

/* ── Bandeau « connexion perdue » ────────────────────────────────────────── */

.netbar {
  position: sticky;
  top: 0;
  z-index: 30;
  padding: 8px var(--pad);
  background: var(--danger);
  color: var(--ink-0);
  font-weight: 700;
  text-align: center;
}

/* ── Notifications ───────────────────────────────────────────────────────── */

.toasts {
  position: fixed;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 70;
  display: grid;
  gap: 8px;
  width: min(calc(100vw - 24px), 440px);
  transform: translateX(-50%);
  pointer-events: none;
}

.toast {
  padding: 12px 16px;
  border-radius: var(--radius-s);
  background: var(--paper);
  color: var(--ink-0);
  font-weight: 700;
  box-shadow: var(--shadow);
  animation: toast-in 380ms var(--ease-spring) both;
  transition:
    opacity 280ms,
    transform 280ms;
}

.toast--error {
  background: var(--danger);
}

.toast.is-leaving {
  opacity: 0;
  transform: translateY(12px);
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(24px) scale(0.9);
  }
}

/* ── Mise en page générale ───────────────────────────────────────────────── */

main {
  padding: 0 var(--pad) var(--pad);
}

.screen {
  width: min(100%, 1480px);
  margin-inline: auto;
}

.panel {
  padding: clamp(18px, 3vw, 30px);
  border-radius: var(--radius);
  background: var(--ink-2);
  box-shadow: var(--shadow);
}

@media (max-width: 520px) {
  /* En salle, la barre du haut doit loger le code, le son et « quitter ». */
  #app:not([data-screen='home']) .topbar__logo {
    display: none;
  }

  #app:not([data-screen='home']) .topbar__tools {
    margin-left: auto;
  }
}

@media (max-width: 400px) {
  /* Petit téléphone : le mot « Salle » s'efface pour laisser sa place au
     réglage du son. Il reste lu par les lecteurs d'écran (comme .sr-only). */
  .chip__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

@media (max-width: 340px) {
  /* Très petit téléphone : le curseur du volume se serre, pour que « quitter » reste à l'écran. */
  .volume {
    width: 46px;
  }
}
