/* Format d'ecran dedie a ce puzzle : vrai ratio mobile 9/16 (demande
   explicite de Simon, pas le ratio natif de l'illustration qui est plus
   large ~941/1610 avec fond-v2.png). L'illustration garde son aspect-ratio propre (jamais
   d'etirement anisotrope qui rendrait le pivot/les bras visuellement
   obliques) et reste calee en BAS de l'ecran (.game-area align-items:
   flex-end) ; l'espace restant en haut (~99px, noir via le fond de
   .game-area) accueille l'overlay titre+description — assume, pas un bug.
   Redefinit --phone-w/h localement (surcharge shared/harness.css, ne
   touche aucun autre puzzle). 390 * 16/9 = 693.3, arrondi a 693. */
:root {
  --phone-h: 693px;
}

.game-area {
  position: relative;
  padding: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: #0e0b08;
}

/* Titre + instruction en overlay directement sur l'illustration (plus une
   barre d'en-tete separee) — demande explicite de Simon pour l'immersion. */
.phone-header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  padding: 40px 16px 34px;
  background: linear-gradient(180deg, rgba(0, 0, 0, .62), rgba(0, 0, 0, 0));
  border-bottom: none;
  text-align: center;
  pointer-events: none;
}
.phone-header h1 {
  color: #fff;
  font-size: 22px;
  margin: 0 0 6px;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .65);
}
.phone-header .instruction {
  color: #fff;
  font-size: 15px;
  margin: 0;
  text-shadow: 0 2px 5px rgba(0, 0, 0, .6);
}

.balance-scene {
  position: relative;
  width: 100%;
  aspect-ratio: 941 / 1610;
  overflow: visible;
  user-select: none;
}

.scene-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

/* Chaque cote de la balance est une pile de calques plein-cadre (inset:0) :
   la rotation du calque exterieur (le bras) et la contre-rotation du calque
   interieur (le plateau) se composent naturellement en CSS tant que les deux
   calques ont EXACTEMENT la taille de la scene (inset:0) — un transform-origin
   en % desigfne alors le meme point physique quel que soit l'imbrication.
   Voir feedback_bottle_quest_balance_visual_rework pour le detail. */
.pivot-rot {
  position: absolute;
  inset: 0;
  transform: rotate(var(--beam-angle, 0deg));
  transition: transform 0.35s cubic-bezier(.4, 1.4, .6, 1);
  pointer-events: none;
}

.pan-counter-rot {
  position: absolute;
  inset: 0;
  transform: rotate(var(--beam-angle-neg, 0deg));
  transition: transform 0.35s cubic-bezier(.4, 1.4, .6, 1);
  pointer-events: none;
}

.sprite {
  position: absolute;
  transform: translate(var(--tx, -50%), var(--ty, -50%));
  pointer-events: none;
  filter: drop-shadow(3px 6px 5px rgba(0, 0, 0, .45));
}

.pan-dropzone {
  position: absolute;
  min-height: 8%;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-end;
  align-items: flex-end;
  justify-content: center;
  gap: 2%;
  pointer-events: auto;
}

.storage-row {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 27%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 7%;
  pointer-events: auto;
  transition: opacity 0.3s ease;
}

.encarts-row {
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: 10%;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2%;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.encarts-row.visible { opacity: 1; pointer-events: auto; }

/* Consigne affichee sous les encarts une fois la balance equilibree (meme
   fondu que .encarts-row, apparait/disparait en meme temps qu'elle). */
.ranking-instruction {
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: 3%;
  margin: 0;
  text-align: center;
  color: #fff;
  font-size: 13px;
  text-shadow: 0 2px 5px rgba(0, 0, 0, .6);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.ranking-instruction.visible { opacity: 1; }

/* Le clip-path trapezoidal vit sur ::before (pas sur .encart lui-meme) :
   un objet depose est un enfant DIRECT de .encart, donc un clip-path pose
   sur .encart aurait aussi rogne l'objet a la forme du bac. Les objets
   doivent au contraire donner l'impression d'etre POSES DESSUS, quitte a
   deborder legerement du bac sur les cotes/en haut/en bas (retour explicite
   de Simon) — seul le fond trapezoidal reste decoupe. */
.encart {
  flex: 1 1 0;
  height: calc(var(--scene-h, 1610px) * 0.13);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.encart::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, .30), rgba(0, 0, 0, .14));
  box-shadow: inset 0 3px 6px rgba(0, 0, 0, .4), inset 0 -1px 0 rgba(255, 255, 255, .05);
  z-index: 0;
}
.encart.locked::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 2px rgba(120, 200, 140, .55);
  z-index: 0;
}

/* Trapeze discret et ASYMETRIQUE par encart plutot qu'un meme trapeze
   accentue partout : chaque bac "penche" tres legerement vers le CENTRE
   de la rangee (perspective de table), d'autant plus que le bac est loin
   du centre — les 2 bacs exterieurs penchent un peu, les 2 bacs interieurs
   presque pas (retour explicite de Simon : "pas tous cette forme de
   trapeze aussi accentuee"). Applique separement sur ::before et
   .locked::after pour que les 2 restent alignes. */
.encart:nth-child(1)::before, .encart:nth-child(1).locked::after { clip-path: polygon(12% 0%, 98% 0%, 100% 100%, 0% 100%); }
.encart:nth-child(2)::before, .encart:nth-child(2).locked::after { clip-path: polygon(6% 0%, 99% 0%, 100% 100%, 0% 100%); }
.encart:nth-child(3)::before, .encart:nth-child(3).locked::after { clip-path: polygon(1% 0%, 94% 0%, 100% 100%, 0% 100%); }
.encart:nth-child(4)::before, .encart:nth-child(4).locked::after { clip-path: polygon(2% 0%, 88% 0%, 100% 100%, 0% 100%); }

/* Poids et objets : vrais sprites detoures, plus de formes CSS abstraites. */
.weight-chip, .object-chip {
  cursor: grab;
  touch-action: none;
  user-select: none;
  position: relative;
  z-index: 2;
  display: block;
  filter: drop-shadow(2px 5px 4px rgba(0, 0, 0, .275));
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.weight-chip.dragging, .object-chip.dragging {
  position: fixed;
  z-index: 50;
  cursor: grabbing;
  filter: drop-shadow(3px 8px 10px rgba(0, 0, 0, .25));
}
/* Purement symbolique une fois "spent" (retour explicite de Simon) : sorti
   du flux flex pour ne plus jamais partager/decaler la place d'un objet
   pese ensuite sur le meme plateau — juste une trace en transparence,
   plus un occupant reel de l'espace. */
.weight-chip.spent {
  opacity: 0.4;
  pointer-events: none;
  filter: grayscale(0.4) drop-shadow(2px 4px 3px rgba(0, 0, 0, .2));
  position: absolute;
  /* left ET bottom sont MESURES sur la position flex reelle de chaque poids
     juste avant le verrouillage (cf. lockCalibration() dans main.js), pas
     une valeur arbitraire — sinon le passage relative->absolute (mode de
     mise en page qui ne s'anime jamais) fait sauter/eloigner les poids vers
     un point qui ne correspond pas a leur arrangement flex reel (bug reel
     signale par Simon, corrige en mesurant plutot qu'en approximant). */
  left: var(--spent-x, 50%);
  bottom: var(--spent-bottom, 8%);
  transform: translateX(-50%);
  /* left/bottom changent instantanement (une custom property CSS ne s'anime
     jamais sans @property) : le transform doit sauter en meme temps, sinon
     lui seul glisse sur 0.4s pendant que left a deja saute. Seule l'opacite
     doit rester animee ici. */
  transition: opacity 0.4s ease;
}
.weight-chip.leftover-exit { opacity: 0; transform: translateX(-60%); }

.object-chip.enter-hidden { opacity: 0; transform: translateY(22%); }
.object-chip.enter-hidden.dragging { transition: none; }

/* Largeur calculee contre --scene-w (variable CSS posee sur .balance-scene,
   heritee par tous les descendants) plutot qu'un % local : un poids/objet
   peut se retrouver enfant d'un conteneur etroit (le plateau) ou large (la
   rangee de stockage), un % simple se recalculerait alors contre le
   mauvais parent. */
.weight-A { width: calc(var(--scene-w, 941px) * 0.140); }
.weight-B { width: calc(var(--scene-w, 941px) * 0.120); }
.weight-C { width: calc(var(--scene-w, 941px) * 0.094); }
.weight-D { width: calc(var(--scene-w, 941px) * 0.073); }

/* Une fois sur un plateau, les poids doivent tenir cote a cote dans la
   coupelle : taille reduite specifiquement dans ce contexte (demande
   explicite de Simon, "pas grave si plus petits dans les plateaux"). */
.pan-dropzone .weight-A { width: calc(var(--scene-w, 941px) * 0.088); }
.pan-dropzone .weight-B { width: calc(var(--scene-w, 941px) * 0.076); }
.pan-dropzone .weight-C { width: calc(var(--scene-w, 941px) * 0.060); }
.pan-dropzone .weight-D { width: calc(var(--scene-w, 941px) * 0.047); }

/* Meme logique pour les objets : plus petits une fois sur un plateau (pour
   comparer leur masse deux par deux) qu'en rangee de stockage. */
.pan-dropzone .obj-key { width: calc(var(--scene-w, 941px) * 0.072); }
.pan-dropzone .obj-box { width: calc(var(--scene-w, 941px) * 0.130); }
.pan-dropzone .obj-medallion { width: calc(var(--scene-w, 941px) * 0.098); }
.pan-dropzone .obj-statue { width: calc(var(--scene-w, 941px) * 0.084); }

/* +20% (demande explicite de Simon) : uniquement la taille "presentee" en
   rangee de stockage, jamais .pan-dropzone .obj-X ci-dessus qui reste
   inchangee (les objets doivent rester plus petits une fois sur un
   plateau, pour comparer leur masse deux par deux). */
.obj-key { width: calc(var(--scene-w, 941px) * 0.110); }
.obj-box { width: calc(var(--scene-w, 941px) * 0.218); }
.obj-medallion { width: calc(var(--scene-w, 941px) * 0.154); }
.obj-statue { width: calc(var(--scene-w, 941px) * 0.132); }

.mass-label {
  display: none;
  position: absolute;
  top: -18px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  color: #222;
  background: #fff;
  padding: 0 3px;
  border-radius: 3px;
  white-space: nowrap;
}
.weight-chip.show-mass .mass-label, .object-chip.show-mass .mass-label { display: block; }

.digit-badge {
  position: absolute;
  bottom: -4%;
  right: -6%;
  width: 22%;
  aspect-ratio: 1;
  min-width: 16px;
  border-radius: 50%;
  background: #1b1e24;
  color: #f2d9a0;
  font-size: 11px;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid #f2d9a0;
}
