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

html, body {
  height: 100%;
  overscroll-behavior: contain;
  /* Blocks double-tap zoom (viewport meta alone is ignored on some mobile browsers). */
  touch-action: manipulation;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: #111;
  color: #fff;
}

#app {
  height: 100dvh;
  width: 100%;
  overflow: hidden;
  position: relative;
  touch-action: manipulation;
}

.screen {
  display: none;
  height: 100%;
  width: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  position: relative;
}
.screen.active { display: flex; }

.logo { width: 120px; border-radius: 12px; margin-bottom: 16px; }

#screen-menu h1 { font-size: 1.8rem; margin-bottom: 8px; }
.subtitle { opacity: 0.8; margin-bottom: 24px; }

button {
  font-size: 1.1rem;
  padding: 14px 28px;
  border: none;
  border-radius: 999px;
  background: #e0334f;
  color: #fff;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  -ms-touch-action: manipulation;
}

.intro-stage {
  position: relative;
  height: 260px;
  width: 100%;
  max-width: 360px;
}

.avatar {
  position: absolute;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  border: 4px solid #fff;
  top: 40px;
}
.avatar-luis { left: 10%; }
.avatar-vitor { left: 55%; }
.avatar-andre {
  left: 32%;
  top: 130px;
  width: 110px;
  height: 110px;
}

.intro-caption { margin-top: 16px; font-size: 1.1rem; }

#screen-game { padding: 0; justify-content: flex-start; }

#hud {
  width: 100%;
  padding: 12px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  z-index: 2;
}
#distance { font-weight: 700; font-size: 1.1rem; }
/* Playtesters found the fill-up percentage bar confusing ("não percebi
   se a tinha de preencher para ganhar"). 3 hearts is an unambiguous,
   universally understood convention: they only ever go away. */
#lives {
  display: flex;
  gap: 4px;
  font-size: 1.3rem;
  margin-left: auto;
}
.heart { transition: opacity 150ms ease, transform 150ms ease; }
.heart.heart-lost { opacity: 0.25; transform: scale(0.85); filter: grayscale(1); }
#lives.heart-hit { animation: heart-hit 350ms ease-out; }
@keyframes heart-hit {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}

#lane-track {
  position: relative;
  flex: 1;
  width: 100%;
  overflow: hidden;
  background: linear-gradient(#5c4a37, #3a2c1f);
}

/* House-hallway perspective: two angled wall panels flanking a floor
   trapezoid that narrows toward a vanishing point at the top and widens
   toward the player at the bottom -- the "things approach from the
   front, like Subway Surfers" read the player asked for, adapted to an
   indoor hallway instead of a train track. */
.wall-left, .wall-right {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, #6b5640, #493a29);
  z-index: 0;
  pointer-events: none;
}
.wall-left { clip-path: polygon(0 0, 44% 0, 20% 100%, 0 100%); }
.wall-right { clip-path: polygon(56% 0, 100% 0, 100% 100%, 80% 100%); }

.floor {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  clip-path: polygon(44% 0%, 56% 0%, 100% 100%, 0% 100%);
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,0.04) 0 2px, transparent 2px 58px),
    repeating-linear-gradient(180deg, rgba(255,255,255,0.07) 0 3px, transparent 3px 90px),
    linear-gradient(#4a3327, #2c1f18);
  background-position: 0 0, 0 0, 0 0;
}
/* The floor lines scroll continuously toward the player while running,
   giving a constant sense of forward motion even though the camera
   itself doesn't move -- the "running feel" requested to match games
   like Subway Surfers. */
.floor.running-floor {
  animation: floor-scroll 550ms linear infinite;
}
@keyframes floor-scroll {
  from { background-position: 0 0, 0 0, 0 0; }
  to { background-position: 0 0, 0 90px, 0 0; }
}

/* House dressing: a door at the vanishing point reads as "there's more
   house ahead", wall art and a baseboard ground the hallway as indoors,
   and a rug under the player's starting spot reads as "at home" rather
   than an empty corridor. */
.door {
  position: absolute;
  top: 4%;
  left: 50%;
  width: 8%;
  height: 11%;
  transform: translateX(-50%);
  background: linear-gradient(180deg, #7a5a3a, #5c4128);
  border: 2px solid #3a2a18;
  border-radius: 2px 2px 0 0;
  z-index: 0;
  pointer-events: none;
}
.door::after {
  content: "";
  position: absolute;
  right: 12%;
  top: 48%;
  width: 10%;
  height: 10%;
  background: #d9a441;
  border-radius: 50%;
}
/* Easter egg: a plaque referencing the real podcast this game is based
   on. Needs a background pill and real size to actually read against
   the busy floor lines -- a 5px label at the vanishing point was
   effectively invisible. */
.door-plaque {
  position: absolute;
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: #fff2d6;
  white-space: nowrap;
  text-transform: uppercase;
  background: rgba(0,0,0,0.55);
  padding: 2px 7px;
  border-radius: 4px;
  border: 1px solid #d9a441;
}

/* Easter egg: red pennants like the ones on the real Prata da Casa
   studio wall (a sports-bar look), instead of generic picture frames. */
.wall-pennant {
  position: absolute;
  width: 42px;
  height: 56px;
  z-index: 0;
  pointer-events: none;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  background: linear-gradient(180deg, #e8324a, #8f1626);
  border-top: 4px solid #f4d78a;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.4));
}
.wall-pennant-left { top: 18%; left: 5%; }
.wall-pennant-right { top: 26%; right: 6%; transform: scaleX(-1); }

/* Easter egg: a framed sign hanging beside each pennant with a real line
   from a Prata da Casa episode. Up to 4 different ones cycle through
   during a single run, alternating side each time (JS toggles the
   .visible class; only one side shows at once via the fade). */
.wall-quote {
  position: absolute;
  width: 30%;
  z-index: 0;
  pointer-events: none;
  text-align: center;
  font-size: 0.62rem;
  font-weight: 700;
  font-style: italic;
  line-height: 1.25;
  color: #f4e6c8;
  background: rgba(20, 14, 8, 0.72);
  border: 2px solid #caa15e;
  border-radius: 6px;
  padding: 6px 7px;
  opacity: 0;
  transition: opacity 500ms ease;
}
.wall-quote.visible { opacity: 1; }
.wall-quote-left { top: 40%; left: 3%; }
.wall-quote-right { top: 48%; right: 3%; }

.baseboard {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 30%;
  height: 4px;
  background: rgba(0,0,0,0.25);
  z-index: 0;
  pointer-events: none;
}

.rug {
  position: absolute;
  bottom: 6%;
  left: 50%;
  width: 46%;
  height: 12%;
  transform: translateX(-50%);
  background: #8a3b3b;
  border: 6px solid #6e2c2c;
  border-radius: 50%;
  z-index: 0;
  pointer-events: none;
  opacity: 0.85;
}

#instructions {
  position: absolute;
  top: 38%;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.4;
  background: rgba(0,0,0,0.5);
  padding: 12px 18px;
  border-radius: 14px;
  z-index: 5;
  transition: opacity 400ms ease;
  pointer-events: none;
  white-space: nowrap;
}
#instructions.hidden { opacity: 0; }

#player {
  position: absolute;
  bottom: 10%;
  width: 70px;
  height: 165px;
  transform: translateX(-50%);
  transform-origin: bottom center;
  transition: left 200ms ease, transform 250ms ease;
  z-index: 4;
  pointer-events: none;
}
.player-inner {
  position: relative;
  width: 100%;
  height: 100%;
}
#player.walking .player-inner {
  animation: walk-bounce 480ms ease-in-out infinite;
}
@keyframes walk-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}
.player-svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
/* Per-tap feedback: each leg kicks up on its own tap (not a generic
   walk cycle), so a touch produces an immediate, visible response tied
   to exactly which side was tapped -- not just the distance/imbalance
   numbers changing. transform-box/-origin make an SVG shape pivot from
   its own hip point instead of the whole SVG's top-left corner. */
.player-svg .leg {
  transform-box: fill-box;
  transform-origin: 50% 0%;
}
.leg-left.step { animation: leg-step-left 200ms ease-out; }
.leg-right.step { animation: leg-step-right 200ms ease-out; }
@keyframes leg-step-left {
  0% { transform: translateY(0) rotate(0deg); }
  45% { transform: translateY(-7px) rotate(-14deg); }
  100% { transform: translateY(0) rotate(0deg); }
}
@keyframes leg-step-right {
  0% { transform: translateY(0) rotate(0deg); }
  45% { transform: translateY(-7px) rotate(14deg); }
  100% { transform: translateY(0) rotate(0deg); }
}
.player-svg.tap-pulse { animation: tap-pulse 180ms ease-out; }
@keyframes tap-pulse {
  0% { transform: scale(1); }
  40% { transform: scale(1.07); }
  100% { transform: scale(1); }
}
/* André's real face, cropped to a circle over the illustrated body --
   sized/positioned to land exactly where the old illustrated head was. */
.player-face {
  position: absolute;
  top: 2%;
  left: 50%;
  width: 68%;
  aspect-ratio: 1;
  transform: translateX(-50%);
  border-radius: 50%;
  object-fit: cover;
  object-position: center 18%;
  border: 3px solid #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,0.4);
  z-index: 2;
}
/* A whole watermelon (not a cut slice) between his hands: a solid green
   circle with a few curved darker rind stripes. */
.melon-stripe {
  fill: none;
  stroke: #1f4d1f;
  stroke-width: 2;
  stroke-linecap: round;
}

.obstacle {
  position: absolute;
  top: -40px;
  width: 64px;
  height: 64px;
  opacity: 0.85;
  z-index: 2;
  pointer-events: none;
  transform: translateX(-50%) scale(0.5);
  transition-property: top, left, transform, opacity;
  transition-timing-function: linear;
}
/* Obstacles are photos of André's co-hosts, framed as the ones
   sabotaging him -- a circular headshot instead of a generic icon. */
.obstacle img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 20%;
  border-radius: 50%;
  border: 3px solid #fff;
  box-shadow: 0 3px 8px rgba(0,0,0,0.45);
}
/* Obstacles start narrow and small near the vanishing point at the top
   (set via JS before the .obstacle-travel class is added), then this
   class animates both their position AND their lane offset outward at
   once -- so they visibly come from the front and spread into their
   lane as they approach, instead of falling straight down already in
   place. They stop above the player's chest height (not at his feet),
   and sit at a lower z-index than #player, so an obstacle can never
   visually cover the character even at the moment of contact. */
.obstacle.obstacle-travel { top: 62%; opacity: 1; transform: translateX(-50%) scale(1.55); }

#crash-effect {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
  z-index: 3;
}
@keyframes crash-flash {
  0% { opacity: 0; transform: scale(1.15); }
  30% { opacity: 1; transform: scale(1); }
  100% { opacity: 1; transform: scale(1); }
}
#crash-effect.crash-flash {
  animation: crash-flash 450ms ease-out forwards;
}

#touch-zones {
  position: absolute;
  inset: 0;
  display: flex;
  z-index: 1;
}
.zone { flex: 1; touch-action: none; position: relative; overflow: hidden; }
/* Fires the instant a finger touches down -- before the tap even
   resolves into a step -- so the touch itself feels acknowledged
   immediately, not just its eventual effect on distance/imbalance. */
.zone-flash {
  position: absolute;
  inset: 0;
  background: rgba(255,255,255,0.18);
  opacity: 0;
  pointer-events: none;
}
.zone-flash.active { animation: zone-flash 250ms ease-out; }
@keyframes zone-flash {
  0% { opacity: 0.7; }
  100% { opacity: 0; }
}

#gameover-bg {
  position: absolute;
  inset: 0;
  background-image: url(assets/melancia.jpg);
  background-size: cover;
  background-position: center;
}
#gameover-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.6);
}
#gameover-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  height: 100%;
  justify-content: center;
  padding: 24px;
}
#gameover-reaction {
  width: 76px;
  height: 76px;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid #fff;
  margin-bottom: 4px;
}
/* Easter egg: "Já perdi." is a real recurring catchphrase on the show. */
.catchphrase { font-size: 1.15rem; font-weight: 700; font-style: italic; opacity: 0.95; margin-top: -6px; }
#final-score { font-size: 1.6rem; font-weight: 700; }
/* Another real episode quote, picked fresh each time you lose -- a
   second reason to smile (and to play again to see a different one). */
.funny-line {
  font-size: 1.2rem;
  font-style: italic;
  opacity: 0.9;
  max-width: 340px;
  line-height: 1.35;
  margin-top: 2px;
  margin-bottom: 8px;
}

#result-form { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 320px; }
#result-form input {
  padding: 12px 14px;
  border-radius: 8px;
  border: none;
  font-size: 1rem;
}
.btn-secondary {
  background: transparent;
  color: #fff;
  border: 2px solid rgba(255,255,255,0.5);
  margin-top: 4px;
}

#ranking-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  height: 100%;
  justify-content: center;
  padding: 24px;
  width: 100%;
}
.ranking-note { font-size: 0.78rem; opacity: 0.65; margin-top: -6px; margin-bottom: 6px; }
#ranking-list {
  list-style: none;
  width: 100%;
  max-width: 340px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 46vh;
  overflow-y: auto;
  margin-bottom: 8px;
}
.rank-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: rgba(255,255,255,0.08);
  border-radius: 8px;
  font-size: 0.85rem;
}
.rank-row-you {
  background: rgba(224, 51, 79, 0.35);
  border: 2px solid #e0334f;
  font-weight: 700;
}
.rank-pos { width: 26px; opacity: 0.7; flex-shrink: 0; }
.rank-name { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-score { flex-shrink: 0; }

.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.ranking-status {
  margin: 0 0 12px;
  font-size: 0.85rem;
  opacity: 0.8;
}

.ranking-status.hidden {
  display: none;
}

.ranking-status.is-error {
  color: #ffb4b4;
}

.ranking-credit {
  margin-top: 18px;
  font-size: 0.78rem;
  opacity: 0.7;
}

.ranking-credit a {
  color: inherit;
}

@keyframes slide-in-left {
  from { transform: translateX(-140px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
@keyframes slide-in-right {
  from { transform: translateX(140px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
@keyframes pop-in {
  from { transform: scale(0.4); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

#screen-intro.active .avatar-luis { animation: slide-in-left 500ms ease-out both; }
#screen-intro.active .avatar-vitor { animation: slide-in-right 500ms ease-out both; }
#screen-intro.active .avatar-andre { animation: pop-in 400ms ease-out 500ms both; }

html, body {
  overscroll-behavior: contain;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

#screen-game,
#touch-zones,
#touch-zones .zone {
  touch-action: none;
}

input, textarea {
  -webkit-user-select: text;
  user-select: text;
}
