/* ============================================================
   Casa Felipe — page d'accueil (porte d'entrée de tous les jeux)
   ------------------------------------------------------------
   Repères de positionnement (tous en % du décor 1919x1077, mesurés
   sur homepage4.png — ne pas les retoucher « au jugé ») :
     porte  : ouverture centrée en (50.4 %, 55.7 %)
     ruine de droite : sommet à 51.5 % (le bloc de compte doit rester au-dessus)
     herbe  : commence vers 66 % (ligne de sol sous la porte)
   ============================================================ */

:root {
  --ink:      #10233f;
  --ink-2:    #44608a;
  --gold:     #e0a83a;
  --panel:    rgba(255, 255, 255, .82);
  --panel-br: rgba(255, 255, 255, .95);
  --shadow:   0 8px 28px rgba(9, 26, 51, .28);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%;
  background: #7fb4dd;
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
  color: var(--ink);
  overflow: hidden;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.hidden { display: none !important; }

/* ---------- Le décor, à ratio constant ----------
   Le stage occupe le plus grand rectangle au ratio de l'image qui tient dans
   le viewport, centré. C'est ce qui garantit que la porte et le visage restent
   à leur place quelle que soit la fenêtre. */
#stage {
  position: absolute; inset: 0; margin: auto;
  width: min(100vw, calc(100vh * 1919 / 1077));
  height: min(100vh, calc(100vw * 1077 / 1919));
  overflow: hidden;
}
#bg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; user-select: none; }

/* Le titre n'est plus incrusté dans le décor : il est posé par-dessus, et
   surtout AU-DESSUS du nuage d'information (z-index), que celui-ci vienne
   passer sous lui. */
#titre {
  position: absolute; left: 15.5%; top: 4%;
  width: 56.7%;                       /* taille naturelle de titre.png (1088/1919) */
  z-index: 20; pointer-events: none; user-select: none;
  filter: drop-shadow(0 6px 14px rgba(9, 26, 51, .35));
}

/* ---------- La porte ---------- */
#door-glow {
  position: absolute;
  left: 46.7%; top: 43.27%; width: 6.57%; height: 24.98%;
  pointer-events: none;
  mix-blend-mode: screen;            /* le halo s'ajoute à la lumière déjà peinte */
  opacity: .35;
  animation: doorBlink 2.4s ease-in-out infinite;
  will-change: opacity, filter;
}
@keyframes doorBlink {
  0%, 100% { opacity: .22; filter: blur(1px) saturate(1); }
  50%      { opacity: .85; filter: blur(0)   saturate(1.25); }
}
/* Zone de survol : un peu plus large que le halo, pour attraper la porte
   entière (battant compris) sans avoir à viser. */
#door-hit {
  position: absolute;
  left: 43.5%; top: 39%; width: 13.5%; height: 33%;
  padding: 0; border: 0; background: none; cursor: pointer;
  border-radius: 46% 46% 8% 8% / 30% 30% 8% 8%;
}
#door-hit:focus-visible { outline: 3px solid var(--gold); outline-offset: 4px; }

/* Porte « ouverte » : le halo s'emballe pendant que les bulles sont là. */
#stage.open #door-glow { animation-duration: .9s; opacity: .9; }

/* ---------- Les jeux, sur leurs bottes de paille ----------
   Posées en ZIG-ZAG dans l'herbe (positions calculées en JS, cf.
   positionBubbles) : la porte et la tour restent dégagées, et les bottes
   jaillissent de la porte à l'ouverture. */
#bubbles {
  position: absolute; inset: 0;
  opacity: 0; visibility: hidden;
  transition: opacity .28s ease, visibility .28s;
}
#stage.open #bubbles { opacity: 1; visibility: visible; }

/* Un « slot » par jeu : il porte la position (left/top posés par le JS) et
   l'animation de sortie. Il contient la botte et, pour une section, ses
   bulles filles — c'est le survol du SLOT entier qui les garde ouvertes. */
.slot {
  position: absolute;
  width: clamp(80px, 10.4vw, 158px);
  aspect-ratio: 1;
  /* état fermé : ramassé sur la porte (--fx/--fy = vecteur vers l'ouverture) */
  transform: translate(calc(-50% + var(--fx, 0px)), calc(-50% + var(--fy, 0px))) scale(.15);
  opacity: 0;
  transition: transform .1s, opacity .1s;
}
#stage.open .slot {
  transform: translate(-50%, -50%) scale(1);
  opacity: 1;
  transition: transform .55s cubic-bezier(.2, 1.45, .4, 1) var(--d, 0s),
              opacity  .3s ease var(--d, 0s);
}
/* Vignette VERROUILLÉE (cliquée) : agrandie et surlignée, elle reste en avant
   tant qu'un autre choix n'est pas fait. */
.slot.selected { z-index: 8; }
/* 1.18 et pas davantage : au-delà, la 1re botte (à 7,5 % de la largeur)
   sort du décor une fois agrandie et son libellé se fait rogner. */
#stage.open .slot.selected { transform: translate(-50%, -50%) scale(1.18); }
.slot.selected > .bubble { filter: drop-shadow(0 14px 22px rgba(9, 26, 51, .55)); }
.slot.selected > .bubble .pic {
  border-color: var(--gold);
  box-shadow: 0 0 0 4px rgba(224, 168, 58, .85),
              0 0 22px 8px rgba(255, 226, 150, .55),
              0 6px 16px rgba(0, 0, 0, .5);
}
.slot.selected > .bubble .name { background: rgba(180, 120, 20, .92); }

/* Chaque jeu est présenté sur une BOTTE DE PAILLE (paja.png, fond
   transparent) posée dans l'herbe : la vignette du jeu vient s'y appuyer
   comme une affiche. */
.bubble {
  position: absolute; inset: 0;
  background: url("paja.png") center/contain no-repeat;
  filter: drop-shadow(0 10px 16px rgba(9, 26, 51, .45));
  text-decoration: none;
}

/* Simple conteneur : les bottes ne bougent pas une fois posées. */
.bubble .inner { position: absolute; inset: 0; }

.bubble:hover, .bubble:focus-visible {
  outline: none;
  filter: drop-shadow(0 14px 20px rgba(9, 26, 51, .55)) brightness(1.06);
}
.bubble:hover .pic, .bubble:focus-visible .pic {
  filter: saturate(1.15) brightness(1.08);
  box-shadow: 0 0 0 3px rgba(224, 168, 58, .75),
              0 0 14px 5px rgba(255, 255, 255, .35),
              0 5px 14px rgba(0, 0, 0, .5);
}

/* La vignette du jeu, RONDE et cernée d'un contour blanc, occupe l'essentiel
   de la botte (un peu au-dessus du centre : le bas de la paille reste visible
   et sert de socle). Le halo blanc diffus autour du liseré adoucit la
   jonction avec les brins de paille.
   ⚠️ Pas de `mask-image` ici : un masque rogne TOUT le rendu de l'élément,
   bordure et ombres comprises — le contour blanc disparaîtrait avec. */
.bubble .pic {
  position: absolute; left: 50%; top: 43%;
  transform: translate(-50%, -50%);
  width: 70%; aspect-ratio: 1; object-fit: cover;
  border-radius: 50%;
  border: 3px solid #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, .38),
              0 0 12px 4px rgba(255, 255, 255, .28),
              0 4px 12px rgba(0, 0, 0, .45);
  transition: filter .15s ease, box-shadow .15s ease;
}
/* Les libellés vont du mot unique (« Buzzer ») à la phrase (« Historias que
   resolver ») : la pastille s'élargit jusqu'à 150 % de la botte puis passe à
   la ligne, plutôt que de déborder sur les voisines. */
.bubble .name {
  position: absolute; left: 50%; bottom: 0;
  transform: translateX(-50%);
  /* ⚠️ `width: max-content` est indispensable : un élément absolument
     positionné avec `left: 50%` est en largeur « shrink-to-fit », bornée par
     l'espace restant (ici la moitié de la botte, ~86 px) — le `max-width`
     seul ne sert alors à rien et le texte se casse sur 3 lignes. */
  width: max-content; max-width: 178%; padding: 2px 8px;
  font-size: clamp(10px, .95vw, 14px); font-weight: 700; letter-spacing: .02em;
  line-height: 1.2;
  color: #fff; text-align: center;
  background: rgba(10, 26, 48, .78);
  border-radius: 12px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .9);
}

/* ---------- Panneau compte (colonne de droite) ---------- */
/* Coin HAUT DROITE. Contrainte : le bloc ENTIER doit rester au-dessus de la
   ruine de droite, dont le sommet est à y ≈ 555 px sur 1077, soit 51,5 % —
   d'où un ancrage tout en haut, le bloc faisant ~26 % de hauteur. */
/* Pas de cadre : le bloc se pose directement sur le ciel. Les libellés sont
   donc en encre foncée avec un léger halo clair, seul moyen de rester lisibles
   sans panneau derrière eux. */
#account {
  position: absolute; right: 2.4%; top: 3.2%;
  width: clamp(196px, 18%, 300px);
}
#acc-actions { display: flex; flex-direction: column; gap: 7px; }

.form-title {
  margin: 0 0 8px; font-size: clamp(13px, 1.15vw, 17px); font-weight: 700;
  color: var(--ink); text-shadow: 0 1px 0 rgba(255, 255, 255, .85);
}
.fld { display: block; margin-bottom: 8px; }
.fld span {
  display: block; font-size: clamp(10px, .82vw, 12px); font-weight: 700;
  color: var(--ink); margin-bottom: 3px;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .9);
}
.fld input {
  width: 100%; padding: 7px 9px;
  font: inherit; font-size: clamp(12px, .95vw, 14px);
  color: var(--ink);
  background: #fff;
  border: 1px solid #b9c9de; border-radius: 8px;
  box-shadow: 0 2px 8px rgba(9, 26, 51, .22);
}
.fld input:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 3px rgba(224, 168, 58, .3); }

/* Empilés plutôt que côte à côte : « Créer un compte » / « Crear una cuenta »
   ne tient pas sur une ligne dans un bloc de 18 % de large. */
.btn-row { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.btn {
  width: 100%; padding: 8px 6px;
  font: inherit; font-size: clamp(11px, .9vw, 13px); font-weight: 700;
  border-radius: 9px; cursor: pointer; border: 1px solid transparent;
  box-shadow: 0 3px 10px rgba(9, 26, 51, .3);
  transition: transform .12s ease, filter .12s ease;
}
.btn:hover { transform: translateY(-1px); filter: brightness(1.06); }
.btn:active { transform: translateY(0); }
.btn-primary { background: linear-gradient(#2f5f9e, #1d4278); color: #fff; }
.btn-ghost { background: rgba(255, 255, 255, .95); color: var(--ink-2); border-color: #b9c9de; }

.msg {
  margin: 8px 0 0; min-height: 1em; font-size: clamp(10px, .82vw, 12px);
  color: #7f1d1d; font-weight: 700; text-shadow: 0 1px 0 rgba(255, 255, 255, .9);
}
.msg.ok { color: #14532d; }
.hello {
  margin: 0 0 10px; font-size: clamp(12px, 1vw, 15px); font-weight: 700;
  color: var(--ink); text-shadow: 0 1px 0 rgba(255, 255, 255, .9);
}

/* ---------- Drapeaux (haut droite, sous le visage) ---------- */
/* Coin HAUT GAUCHE, les deux côte à côte. Le ciel est dégagé de ce côté :
   le titre « CASAFELIPE » ne commence qu'à ~21 % de la largeur. */
#langs {
  position: absolute; left: 1.9%; top: 3%;
  display: flex; flex-direction: row; align-items: flex-start;
  gap: clamp(5px, .7vw, 11px);
}
.lang {
  padding: 0; border: 0; background: none; cursor: pointer;
  line-height: 0; border-radius: 6px;
  filter: drop-shadow(0 3px 6px rgba(9, 26, 51, .4));
  transition: transform .16s ease, filter .16s ease, opacity .16s ease;
}
.lang img { width: clamp(28px, 3.1vw, 56px); height: auto; display: block; }
.lang:hover { transform: scale(1.1) rotate(-2deg); }
/* La langue active reste « levée » : image rollover (posée par le JS) + halo. */
.lang[aria-pressed="true"] { filter: drop-shadow(0 4px 9px rgba(224, 168, 58, .95)); }
.lang[aria-pressed="false"] { opacity: .58; }
.lang:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

/* ---------- Écrans étroits ----------
   En portrait le décor devient très petit : on décolle le panneau compte et
   les drapeaux du décor pour qu'ils restent lisibles. */
/* En portrait le décor se réduit à une bande horizontale : plus rien ne peut
   y être ancré lisiblement. On décroche donc les panneaux du stage (position
   fixe, repère écran) et on présente les jeux en grille plein écran plutôt
   qu'en arc autour d'une porte devenue minuscule. */
@media (max-aspect-ratio: 1/1) {
  /* Même ordre qu'en paysage (drapeaux d'abord), mais empilés : la largeur
     ne permet pas de mettre le bloc de compte à côté d'eux. */
  #langs   { position: fixed; left: 3%; top: 2%; flex-direction: row; }
  #account { position: fixed; left: 3%; top: 68px; right: auto; width: min(70%, 320px); }

  #bubbles {
    position: fixed; inset: 0;
    display: flex; flex-wrap: wrap; align-content: center; justify-content: center;
    gap: clamp(8px, 2.4vw, 18px);
    padding: 24vh 3vw 6vh;
    background: rgba(8, 22, 44, .45);
    backdrop-filter: blur(2px);
  }
  /* le JS pose left/top pour l'arc : sans effet ici, la grille reprend la main */
  #bubbles .slot {
    position: relative !important; left: auto !important; top: auto !important;
    width: min(26vw, 118px);
    transform: translate(var(--fx, 0px), var(--fy, 0px)) scale(.15);
  }
  #stage.open #bubbles .slot { transform: none; }
}

/* ============================================================
   Nuage d'information (au clic sur une vignette)
   ------------------------------------------------------------
   Centré, PAR-DESSUS la porte et EN PARTIE SOUS le titre (#titre a un
   z-index supérieur). Les dimensions suivent le rapport réel de nuage4.png
   (1059x663) pour que le contenu reste dans la partie dense du nuage : les
   bords sont vaporeux, un texte posé dessus y serait illisible.
   ============================================================ */
#info {
  position: absolute; left: 50%; top: 11%;
  width: 52%; aspect-ratio: 1059 / 663;
  transform: translateX(-50%);
  background: url("nuage4.png") center/contain no-repeat;
  z-index: 12;
  opacity: 1;
  transition: opacity .25s ease, transform .25s ease;
}
#info.hidden { display: block !important; opacity: 0; pointer-events: none; transform: translateX(-50%) scale(.94); }

/* Zone utile : le cœur opaque du nuage. */
.info-inner {
  position: absolute; left: 50%; top: 52%;
  transform: translate(-50%, -50%);
  width: 62%; max-height: 66%;
  display: flex; flex-direction: column; align-items: center;
  gap: clamp(4px, .55vw, 10px);
  text-align: center;
}
#info-close {
  position: absolute; right: 15%; top: 21%;
  width: clamp(22px, 2vw, 32px); aspect-ratio: 1;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(16, 35, 63, .85); color: #fff;
  font-size: clamp(11px, 1vw, 15px); line-height: 1;
  box-shadow: 0 3px 10px rgba(9, 26, 51, .4);
}
#info-close:hover { background: rgba(16, 35, 63, 1); }
#info h2 {
  margin: 0; font-size: clamp(13px, 1.45vw, 23px); font-weight: 800;
  color: var(--ink); text-shadow: 0 1px 0 rgba(255, 255, 255, .9);
}
#info p {
  margin: 0; font-size: clamp(10px, .95vw, 15px); line-height: 1.35;
  color: #23324a;
}
#info-play {
  width: auto; padding: 7px 22px; margin-top: 2px;
  font-size: clamp(11px, 1vw, 15px); text-decoration: none;
}
#info-play.hidden { display: none !important; }

/* Les 2 histoires, présentées DANS le nuage quand la section est choisie. */
#info-choices { display: flex; gap: clamp(6px, 1vw, 18px); justify-content: center; }
#info-choices:empty { display: none; }
#info-choices a {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  text-decoration: none; width: clamp(56px, 6.4vw, 100px);
}
#info-choices img {
  width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 50%;
  border: 3px solid #fff;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .4);
  transition: border-color .15s ease, transform .15s ease;
}
#info-choices a:hover img { border-color: var(--gold); transform: translateY(-2px); }
#info-choices span {
  font-size: clamp(8px, .72vw, 11px); font-weight: 700; color: var(--ink);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .9); line-height: 1.15;
}

/* En portrait le stage est une bande : le nuage d'information s'y afficherait
   minuscule. On le décroche du décor et on l'affiche en plein écran. */
@media (max-aspect-ratio: 1/1) {
  #info {
    position: fixed; left: 50%; top: 50%;
    width: min(94vw, 460px); aspect-ratio: 1059 / 663;
    transform: translate(-50%, -50%);
    z-index: 30;
  }
  #info.hidden { transform: translate(-50%, -50%) scale(.94); }
  #info-close { right: 12%; top: 18%; }
  .info-inner { width: 68%; }
}
