* { margin: 0; padding: 0; box-sizing: border-box; }

/* Calque des pseudos flottants au-dessus des cases de dons (positionnement en
   coordonnees ecran, independant de la case elle-meme pour ne pas etre coupe
   par son overflow). */
#giftLabelLayer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 950;
}

.gift-donor-label {
  position: absolute;
  transform: translate(-50%, -100%);
  background: rgba(20, 16, 35, 0.85);
  color: #fff;
  font-weight: 800;
  font-size: clamp(10px, 1.6vw, 15px);
  padding: 0.3em 0.7em;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
  white-space: nowrap;
}

/* Alerte follow : bien visible, sous la camera, au-dessus des cases de dons */
/* Insere juste sous la camera dans le flux, mais de hauteur nulle pour ne rien
   decaler : les alertes elles-memes sont en position absolue par-dessus. */
#followAlertLayer {
  position: relative;
  width: 100%;
  height: 0;
  margin-top: -1vh;
  pointer-events: none;
  z-index: 960;
}

.follow-alert {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.6em;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.97), rgba(240, 238, 252, 0.94));
  color: #2c2247;
  font-weight: 800;
  font-size: clamp(14px, 2.4vw, 22px);
  padding: 0.5em 1.1em;
  border-radius: 999px;
  border: 2px solid var(--accent2);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4), 0 0 20px color-mix(in srgb, var(--accent2) 40%, transparent);
  white-space: nowrap;
}

.follow-alert-icon {
  font-size: 1.3em;
  animation: followIconSpin 1.4s ease-in-out infinite;
}

@keyframes followIconSpin {
  0%, 100% { transform: rotate(-12deg) scale(1); }
  50% { transform: rotate(12deg) scale(1.15); }
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: transparent !important;
  font-family: 'Baloo 2', 'Comic Sans MS', 'Segoe UI', Arial, sans-serif;
}

:root {
  --accent: #ff2d78;
  --accent2: #3fd0ff;
  --gold: #ffd23f;
  --red: #ff4d6d;
  --green: #2ee27b;
  --blue: #3fd0ff;
  --ink: #2c2247;

  --dark-card: linear-gradient(160deg, rgba(28, 22, 54, 0.88), rgba(16, 12, 34, 0.88));
  --light-card: linear-gradient(160deg, rgba(255, 255, 255, 0.97), rgba(240, 238, 252, 0.94));

  /* Zones interdites TikTok : pseudo/spectateurs en haut, chat + cadeaux en bas */
  --safe-top: 13vh;
  --safe-bottom: 27vh;
}

/* ============ Bande utile entre les deux zones interdites ============ */
#overlayRoot {
  position: fixed;
  top: var(--safe-top);
  bottom: var(--safe-bottom);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 1.2vh;
  padding: 0 2vw;
  pointer-events: none;
  overflow: hidden;
}

/* ============ Rangee du haut : dons | (camera + etage) | likes ============ */
#topRow {
  flex: none;
  display: flex;
  align-items: flex-start;
  gap: 1.4vw;
}

#centerColumn {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1vh;
}

/* ---------- Camera ---------- */
#cameraSlot {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 18px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  background: rgba(12, 9, 26, 0.45);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45), inset 0 0 0 1px rgba(0, 0, 0, 0.3);
  pointer-events: auto;
}

#cameraSlot.active { border-color: rgba(255, 255, 255, 0.22); }

#cameraVideo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: none;
}

#cameraSlot.active #cameraVideo { display: block; }

#cameraPlaceholder {
  position: absolute;
  top: 36%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: clamp(24px, 4vw, 46px);
  opacity: 0.35;
}

#cameraSlot.active #cameraPlaceholder { display: none; }

#cameraControls {
  position: absolute;
  left: 50%;
  bottom: 9%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.8vw;
}

#cameraSlot.active #cameraControls { bottom: auto; top: 6%; opacity: 0; transition: opacity 0.2s ease; }
#cameraSlot.active:hover #cameraControls { opacity: 1; }

#cameraControls button {
  pointer-events: auto;
  font-family: inherit;
  font-weight: 700;
  font-size: clamp(10px, 1.3vw, 14px);
  padding: 0.7vh 1.4vw;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 999px;
  background: rgba(8, 6, 18, 0.72);
  color: #fff;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.12s ease, border-color 0.12s ease;
}

#cameraControls button:hover { transform: translateY(-2px); border-color: var(--accent2); }

/* ---------- Classements ---------- */
.board {
  flex: 0 0 24vw;
  min-width: 0;
  background: var(--dark-card);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 18px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  padding: 1.1vh 1vw 1.2vh;
  color: #fff;
  overflow: hidden;
}

.board-title {
  display: flex;
  align-items: center;
  gap: 0.5vw;
  font-size: clamp(12px, 1.9vw, 19px);
  font-weight: 800;
  margin-bottom: 0.8vh;
  padding-bottom: 0.7vh;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  white-space: nowrap;
  overflow: hidden;
}

.board-icon { font-size: 1.1em; }
.board-title #likeTotal { color: var(--accent2); }

/* padding-top : laisse la place a la couronne du 1er, qui depasse au-dessus
   de sa photo (sinon elle est coupee par l'overflow du panneau). */
.board-list { display: flex; flex-direction: column; gap: 0.5vh; padding-top: 1em; }

.board-row {
  display: flex;
  align-items: center;
  gap: 0.6vw;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  font-size: clamp(9px, 1.35vw, 14px);
  line-height: 1.25;
  opacity: 0.92;
}

.board-row .avatar {
  flex: none;
  width: 1.8em;
  height: 1.8em;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid rgba(255, 255, 255, 0.25);
}

/* Petite couronne au-dessus de la photo du tout premier donateur */
.avatar-wrap {
  position: relative;
  display: inline-flex;
  flex: none;
}

.top-crown {
  position: absolute;
  /* posee sur le haut de la photo (et non au-dessus) pour ne jamais etre coupee */
  top: -0.38em;
  left: 50%;
  transform: translateX(-50%) rotate(-8deg);
  width: 1.3em;
  height: auto;
  z-index: 2;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
  pointer-events: none;
}

.board-row .avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, var(--accent2), #7a5cff);
  color: #fff;
  font-size: 0.85em;
}

/* Ligne "libre" : STRICTEMENT la meme taille qu'une vraie ligne (meme classe
   top1/top2/top3), on ne touche donc ni a la police ni aux marges - seulement
   une legere transparence. Pas de photo, juste un rond vide pour l'alignement. */
.board-row.board-empty { opacity: 0.75; }
.board-row .avatar-vide {
  /* MEMES metriques que .avatar-fallback (display + font-size, dont depend le
     1.8em de .avatar) : sans ca la ligne "libre" etait plus haute que la vraie
     et le cadrage de l'overlay bougeait a l'arrivee d'une personne. */
  display: inline-flex;
  font-size: 0.85em;
  background: none;
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.25);
}

.board-row .rank { flex: none; opacity: 0.5; min-width: 1.2em; text-align: right; }
.board-row .name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.board-row .value { flex: none; color: var(--accent2); }

.board-row.top1, .board-row.top2, .board-row.top3 {
  border-radius: 12px;
  padding: 0.4vh 0.6vw;
}
.board-row.top1 .rank, .board-row.top2 .rank, .board-row.top3 .rank { opacity: 1; }

.board-row.top3 {
  font-size: clamp(10px, 1.6vw, 16px);
  color: #ffb08a;
  background: linear-gradient(90deg, rgba(205, 127, 50, 0.14), rgba(205, 127, 50, 0.02));
}
.board-row.top3 .avatar { border-color: #cd7f32; }
.board-row.top3 .value { color: #ffb08a; }

.board-row.top2 {
  font-size: clamp(11px, 1.8vw, 18px);
  color: #e8ecf5;
  background: linear-gradient(90deg, rgba(200, 210, 230, 0.14), rgba(200, 210, 230, 0.02));
}
.board-row.top2 .avatar { border-color: #c0c8d8; }
.board-row.top2 .value { color: #e8ecf5; }

.board-row.top1 {
  font-size: clamp(14px, 2.2vw, 22px);
  color: var(--gold);
  background: linear-gradient(90deg, rgba(255, 210, 63, 0.18), rgba(255, 210, 63, 0.03));
  border: 1px solid rgba(255, 210, 63, 0.4);
  box-shadow: 0 0 14px rgba(255, 210, 63, 0.2);
  margin-bottom: 0.3vh;
}
.board-row.top1 .avatar { border-color: var(--gold); }
.board-row.top1 .value { color: var(--gold); }

/* ---------- Barre de progression des likes (explosion tous les 500) ---------- */
#likeProgress {
  margin-top: 0.9vh;
  padding-top: 0.8vh;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

#likeProgressLabel {
  font-size: clamp(10px, 1.4vw, 15px);
  font-weight: 800;
  color: var(--accent2);
  text-align: center;
  margin-bottom: 0.5vh;
  white-space: nowrap;
}

#likeProgressRow {
  display: flex;
  align-items: center;
  gap: 0.5vw;
}

#likeProgressBar {
  flex: 1;
  min-width: 0;
  height: clamp(8px, 1.1vh, 14px);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  overflow: hidden;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
}

#likeProgressFill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent2), var(--accent));
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 60%, transparent);
  transition: width 0.3s ease-out;
}

#likeProgressBoom {
  flex: none;
  font-size: clamp(14px, 2vw, 20px);
  line-height: 1;
  animation: boomPulse 1.6s ease-in-out infinite;
}

@keyframes boomPulse {
  0%, 100% { transform: scale(1) rotate(-6deg); }
  50% { transform: scale(1.22) rotate(6deg); }
}

/* ---------- Don special (bleu), tout en bas de la colonne de droite,
   nettement separe des autres cases pour bien le distinguer ---------- */
.gift-cell-special {
  /* Aucune marge : elle prendrait de la hauteur a SA colonne uniquement, et
     les cases de droite deviendraient plus courtes que celles de gauche
     (decalage cumulatif ligne apres ligne). La bordure bleue + le pulse
     suffisent a la distinguer, et une case invisible lui fait face a gauche. */
  background: var(--light-card);
  border: 2px solid var(--blue);
  padding: 0.7vh 1.6vw;
  animation:
    cellIn 0.5s cubic-bezier(.34,1.4,.64,1) forwards,
    cellBreathe var(--breathe-dur, 4s) ease-in-out infinite,
    specialPulse 2.4s ease-in-out infinite;
  animation-delay: 0.1s, calc(0.5s + var(--breathe-delay, 0s)), 0.6s;
}

.gift-cell-special .gift-name { font-size: clamp(12px, 1.7vw, 18px); }
.gift-cell-special .gift-caption { -webkit-line-clamp: 1; }

@keyframes specialPulse {
  0%, 100% { box-shadow: 0 0 16px rgba(63, 208, 255, 0.4), 0 8px 22px rgba(0, 0, 0, 0.35); }
  50% { box-shadow: 0 0 30px rgba(63, 208, 255, 0.75), 0 8px 22px rgba(0, 0, 0, 0.35); }
}

/* ============ Barre de dons, tout en bas : 2x3 rouges | special | 2x3 verts ==== */
#giftColumns {
  /* --case : cote d'une case carree. Limite a la fois par la largeur (4 cases
     + le special au centre doivent tenir) et par la hauteur (3 lignes). */
  --case: min(15vw, 26vh);
  flex: none;
  margin-top: auto;           /* la barre reste collee en bas de la zone utile */
  display: flex;
  align-items: center;        /* le special tombe pile sur la rangee du milieu */
  justify-content: space-between;
  gap: 2vw;
  padding: 2.2vw;
  border-radius: 32px;
  position: relative;
  overflow: hidden;

  /* ---- Verre liquide : une seule vitre blanche translucide derriere TOUTES
     les cases, pour que le bloc de dons se detache du jeu.
     ATTENTION : dans OBS, le jeu est une source SEPAREE et cette page est
     transparente -> backdrop-filter n'a rien a flouter. C'est donc la densite
     du blanc (ci-dessous) qui fait tout le rendu "depoli", pas le flou.
     Pour un vrai flou du jeu, voir la note OBS dans le README. ---- */
  background:
    linear-gradient(135deg,
      rgba(255, 255, 255, 0.58) 0%,
      rgba(255, 255, 255, 0.42) 38%,
      rgba(255, 255, 255, 0.38) 62%,
      rgba(255, 255, 255, 0.52) 100%);
  /* conserve pour les navigateurs ou l'overlay est affiche par-dessus du contenu */
  backdrop-filter: blur(46px) saturate(180%);
  -webkit-backdrop-filter: blur(46px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.5);
  box-shadow:
    0 20px 55px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.8),
    inset 0 -1px 0 rgba(255, 255, 255, 0.2);
}

/* Reflet doux qui glisse sur la vitre : effet "liquide". */
#giftColumns::before {
  content: '';
  position: absolute;
  inset: -40% -10%;
  pointer-events: none;
  background:
    radial-gradient(60% 40% at 25% 0%, rgba(255, 255, 255, 0.38), transparent 70%),
    radial-gradient(50% 40% at 80% 100%, rgba(255, 255, 255, 0.22), transparent 70%);
  animation: verreLiquide 11s ease-in-out infinite alternate;
}

/* Grain tres fin : imite le depoli du verre, meme sans flou reel (OBS). */
#giftColumns::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 0 2px, transparent 2px 4px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,0.04) 0 3px, transparent 3px 6px);
}

@keyframes verreLiquide {
  0% { transform: translate3d(-3%, -2%, 0) scale(1); }
  100% { transform: translate3d(4%, 2%, 0) scale(1.06); }
}

/* Deux colonnes de trois cases carrees. Aucun fond propre : la vitre unique
   de #giftColumns regroupe deja tout. */
.gift-grid {
  flex: none;
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, var(--case, 15vw));
  grid-auto-rows: var(--case, 15vw);
  gap: 1.1vw;
}

/* Le don special, seul au centre, sans cadre autour de lui. */
#giftSpecial {
  flex: none;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

#giftSpecial .gift-cell {
  width: calc(var(--case, 15vw) * 1.2);
  height: calc(var(--case, 15vw) * 1.2);
}

/* Grande case claire : icone dans un ecrin colore + nom + effet bien lisibles.
   Entree en fondu decalee (--i) puis leger flottement continu. */
.gift-cell {
  /* Case CARREE : la grille impose deja la taille des lignes/colonnes,
     la case remplit simplement sa cellule. */
  width: 100%;
  height: 100%;
  min-height: 0;
  display: flex;
  /* contenu empile : icone en haut, nom puis effet en dessous, centres */
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 0.3vh;
  /* teintee a la couleur du don (rouge = ca casse, vert = ca construit) plutot
     que blanche : plus lisible d'un coup d'oeil et plus incitatif */
  background:
    linear-gradient(160deg,
      color-mix(in srgb, var(--gift-color, #fff) 34%, #ffffff) 0%,
      color-mix(in srgb, var(--gift-color, #fff) 18%, #fdfbff) 52%,
      color-mix(in srgb, var(--gift-color, #fff) 44%, #ffffff) 100%);
  border: 2px solid color-mix(in srgb, var(--gift-color, #fff) 62%, #ffffff);
  border-radius: 14px;
  padding: 0.6vh 0.5vw;
  color: var(--ink);
  /* Halo colore plus discret : le panneau sombre derriere assure deja le
     contraste, inutile de "baver" sur le fond du jeu. */
  box-shadow:
    0 6px 16px rgba(0, 0, 0, 0.3),
    0 0 12px color-mix(in srgb, var(--gift-color, transparent) 28%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.95);
  position: relative;
  overflow: hidden;
  opacity: 0;
  /* Entree en cascade, puis respiration continue au rythme propre de chaque case
     (--breathe-dur / --breathe-delay) autour de son inclinaison propre (--rot). */
  animation:
    cellIn 0.5s cubic-bezier(.34,1.4,.64,1) forwards,
    cellBreathe var(--breathe-dur, 4s) ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * 0.08s), calc(0.5s + var(--breathe-delay, 0s));
}

/* Reflet qui balaie la case de temps en temps : attire l'oeil sur les dons. */
.gift-cell::after {
  content: '';
  position: absolute;
  top: 0;
  left: -60%;
  width: 42%;
  height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.8), transparent);
  transform: skewX(-18deg);
  pointer-events: none;
  animation: cellShine 4.5s ease-in-out infinite;
  animation-delay: var(--shine-delay, 0s);
}

@keyframes cellShine {
  0%, 70% { left: -60%; }
  100% { left: 135%; }
}

@keyframes cellIn {
  from { opacity: 0; transform: translateY(14px) scale(0.94); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes cellBreathe {
  0%, 100% { transform: translateY(0) scale(1); }
  50% { transform: translateY(-4px) scale(var(--breathe-scale, 1.04)); }
}

/* L'icone est ancree EN HAUT de la case et descend jusqu'en bas : elle occupe
   toute la hauteur (x1.5 par rapport a sa largeur) au lieu d'etre centree et
   rognee des deux cotes. */
.gift-icon-wrap {
  /* ecrin carre en haut de la case, il occupe toute la hauteur restante */
  flex: 1 1 auto;
  aspect-ratio: 1;
  width: auto;
  max-width: 100%;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  background:
    radial-gradient(circle at 50% 30%,
      #ffffff 0%,
      color-mix(in srgb, var(--gift-color, #999) 22%, white) 100%);
  border: 2px solid color-mix(in srgb, var(--gift-color, #999) 75%, white);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.08);
}

.gift-cell[data-color="red"] { --gift-color: var(--red); }
.gift-cell[data-color="green"] { --gift-color: var(--green); }
.gift-cell[data-color="blue"] { --gift-color: var(--blue); }

/* Seule l'image se balance : rotation rapide entre -5 et +5 degres,
   chaque case ayant sa propre cadence (--swing-dur / --swing-delay). */
.gift-cell img {
  width: 100%;
  height: 100%;
  /* l'image entiere reste visible, calee en haut de son ecrin */
  object-fit: contain;
  object-position: top center;
  animation: iconSwing var(--swing-dur, 1s) ease-in-out infinite;
  animation-delay: var(--swing-delay, 0s);
}

@keyframes iconSwing {
  0%, 100% { transform: rotate(-5deg); }
  50% { transform: rotate(5deg); }
}

.gift-cell .gift-fallback {
  font-size: 8px;
  font-weight: 700;
  opacity: 0.55;
  text-align: center;
  word-break: break-all;
  padding: 2px;
}

.gift-text {
  flex: none;
  width: 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.1vh;
}

.gift-name {
  /* le nom est l'info la moins importante : un peu plus petit pour que les
     noms longs ("Coeur dans les mains") tiennent sans etre coupes */
  font-size: clamp(10px, 1.28vw, 14px);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: color-mix(in srgb, var(--gift-color, var(--ink)) 55%, var(--ink));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Hierarchie de lecture : l'effet en gros et en gras, la precision en petit. */
.gift-caption {
  display: flex;
  align-items: baseline;
  justify-content: center;
  width: 100%;
  gap: 0.3em;
  min-width: 0;
  font-size: clamp(9px, 1.2vw, 13px);
  font-weight: 700;
  line-height: 1.2;
  opacity: 0.65;
  overflow: hidden;
}

.gift-effet {
  flex: none;
  font-size: clamp(15px, 2.3vw, 26px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.01em;
  color: color-mix(in srgb, var(--gift-color, var(--ink)) 78%, var(--ink));
  opacity: 1;
}

.gift-effet-long { font-size: clamp(12px, 1.7vw, 19px); }

.gift-detail {
  min-width: 0;
  font-size: clamp(8px, 1.05vw, 12px);
  font-weight: 700;
  opacity: 0.7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

