/* ==========================================================================
   Reset + estructura base
   ========================================================================== */

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

/* El atributo [hidden] debe ganarle a cualquier `display` de autor.
   Sin esto, las capas de modal/sheet (display:grid) siguen ocupando toda
   la pantalla en z-index 9200 y se tragan todos los clics de la app. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--font);
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--ink);
  background: var(--bg-2);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
  overscroll-behavior: none;
  transition: background .35s var(--ease-out);
}

h1, h2, h3, h4, p, ul, ol, figure { margin: 0; padding: 0; }
ul, ol { list-style: none; }
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }

::selection { background: var(--brand); color: #fff; }

:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 2px;
  border-radius: 6px;
}

/* ------------------------- Escenario ------------------------- */

.stage {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(1200px 600px at 15% -10%, rgba(255,107,26,.16), transparent 60%),
    radial-gradient(900px 700px at 110% 110%, rgba(28,176,246,.14), transparent 60%),
    var(--bg-2);
  overflow: hidden;
  /* overflow:hidden no impide que el navegador desplace este contenedor al
     enfocar un campo; sin esto la posición sobrevive al cambio de pantalla. */
  overflow-anchor: none;
}

.stage__glow {
  position: absolute;
  width: 46vmax; height: 46vmax;
  max-width: 900px; max-height: 900px;
  border-radius: 50%;
  /* Un desenfoque enorme sobre una capa propia y animada (will-change) es la
     receta habitual de las bandas de color en pantallas grandes. Se reduce el
     radio y se deja que el compositor decida si necesita capa. */
  filter: blur(70px);
  opacity: .45;
  pointer-events: none;
}
.stage__glow--a {
  background: radial-gradient(circle, rgba(255,107,26,.55), transparent 70%);
  top: -18vmax; left: -14vmax;
  animation: floatGlow 22s var(--ease-in-out) infinite;
}
.stage__glow--b {
  background: radial-gradient(circle, rgba(168,85,247,.45), transparent 70%);
  bottom: -20vmax; right: -16vmax;
  animation: floatGlow 28s var(--ease-in-out) infinite reverse;
}
html[data-theme="dark"] .stage__glow { opacity: .3; }

/* ------------------------- Teléfono ------------------------- */

.phone {
  position: relative;
  width: min(var(--phone-w), 100vw);
  height: min(940px, 100vh);
  background: var(--bg);
  display: grid;
  grid-template-rows: auto 1fr auto;
  overflow: hidden;
  overflow-anchor: none;
  box-shadow: var(--sh-pop);
  border-radius: 34px;
  isolation: isolate;
}

/* Sin esto, un carrusel horizontal (ligas, retos, chips del mentor) impone
   su ancho de contenido como mínimo al grid y desborda toda la app. */
.phone > * { min-width: 0; }

@media (max-width: 520px), (max-height: 700px) {
  .phone { border-radius: 0; width: 100vw; height: 100dvh; box-shadow: none; }
  .stage { background: var(--bg); }
  .stage__glow { display: none; }
}

/* Quien pide menos movimiento no debería tener dos manchas gigantes animadas. */
@media (prefers-reduced-motion: reduce) {
  .stage__glow { animation: none; }
}

/* ------------------------- Viewport ------------------------- */

.viewport {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  /* El anclaje de desplazamiento reajusta scrollTop cuando cambia el contenido:
     es justo lo que hacía que una pantalla nueva apareciera a media altura. */
  overflow-anchor: none;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.viewport::-webkit-scrollbar { width: 6px; }
.viewport::-webkit-scrollbar-thumb { background: var(--line); border-radius: 99px; }
.viewport::-webkit-scrollbar-track { background: transparent; }

.screen {
  min-height: 100%;
  min-width: 0;
  padding: var(--s5) var(--s5) calc(var(--s8) + 20px);
  display: flex;
  flex-direction: column;
  gap: var(--s4);
}
.screen > * { min-width: 0; }
.screen--flush { padding-left: 0; padding-right: 0; }
.screen--center { justify-content: center; align-items: center; text-align: center; }

/* ------------------------- Capas globales ------------------------- */

.fx-canvas {
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 9000;
  /* Fuera de las celebraciones no debe existir como capa: una capa a pantalla
     completa siempre compuesta puede ensuciar o desteñir lo que hay debajo. */
  display: none;
}
.fx-canvas.is-on { display: block; }

.toast-layer {
  position: fixed;
  left: 50%; top: 18px;
  transform: translateX(-50%);
  z-index: 9500;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
  width: min(420px, calc(100vw - 24px));
}

.modal-layer, .sheet-layer {
  position: fixed; inset: 0;
  z-index: 9200;
  display: grid;
}
/* El modal gana a la hoja. Con el mismo z-index mandaba el orden del
   documento y la hoja quedaba encima, así que un aviso que no se puede
   posponer —quedarse sin vidas, por ejemplo— aparecía debajo de un panel
   informativo y no había forma de llegar a sus botones. */
.modal-layer { place-items: center; padding: var(--s5); z-index: 9300; }
.sheet-layer { align-items: end; }

.scrim {
  position: absolute; inset: 0;
  background: rgba(8,14,26,.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: fadeIn .22s var(--ease-out);
}

/* ------------------------- Utilidades ------------------------- */

.row  { display: flex; align-items: center; gap: var(--s3); }
.col  { display: flex; flex-direction: column; gap: var(--s3); }
.between { justify-content: space-between; }
.center { justify-content: center; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1; }
.t-center { text-align: center; }
.hidden { display: none !important; }
.mt-auto { margin-top: auto; }
.nowrap { white-space: nowrap; }

.h1 { font-size: var(--fs-3xl); font-weight: 900; line-height: 1.1; letter-spacing: -.5px; }
.h2 { font-size: var(--fs-2xl); font-weight: 900; line-height: 1.15; letter-spacing: -.3px; }
.h3 { font-size: var(--fs-xl); font-weight: 800; line-height: 1.25; }
.h4 { font-size: var(--fs-lg); font-weight: 800; line-height: 1.3; }
.p  { font-size: var(--fs-md); font-weight: 600; line-height: 1.55; color: var(--ink-2); }
.small { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-3); line-height: 1.45; }
.tiny { font-size: var(--fs-xs); font-weight: 800; color: var(--ink-3); letter-spacing: .4px; text-transform: uppercase; }

.muted { color: var(--ink-3); }
.c-brand { color: var(--brand); }
.c-green { color: var(--green); }
.c-red   { color: var(--red); }
.c-blue  { color: var(--blue); }
.c-gold  { color: var(--gold-dark); }
.c-purple{ color: var(--purple); }

.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;
}
