/* ==========================================================================
   Papelito · Pantalla de apertura  (concepto 2)

   La impresora es la protagonista: vive SIEMPRE en el centro vertical exacto
   del viewport y no se mueve ni cambia de tamaño en ningún paso. Eso se logra
   con tres filas — [texto | impresora | vacío] — donde la primera y la tercera
   son 1fr, así que la del medio queda clavada al centro.

   El movimiento de la pantalla no viene de mover la impresora: viene de que los
   bloques de texto de arriba colapsan y se expanden. La impresora es el ancla
   fija contra la que se acomoda todo lo demás.
   ========================================================================== */

.intro {
  position: relative;
  /* Altura DEFINIDA, no min-height: sin una altura concreta las filas `1fr` no
     tienen espacio libre que repartir y se dimensionan al contenido — las tres
     terminaban midiendo lo mismo que el copy y la página se iba a scroll. */
  height: 100dvh;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto minmax(0, 1fr);
  justify-items: center;
  padding: var(--s7) var(--s5);
  overflow: hidden;
  transition: grid-template-rows var(--t-settle) var(--ease-settle);
}

/* En reposo el hero es alto y no entra en media pantalla, así que la fila de
   arriba se lleva más espacio y la impresora baja un poco. Del paso de escritura
   en adelante el texto es corto y la impresora queda centrada exacta.
   Se mueve, pero nunca cambia de tamaño. */
.intro[data-step='rest'] {
  grid-template-rows: minmax(0, 1.35fr) auto minmax(0, 0.65fr);
}

/* El degradé va en un pseudo con z-index negativo, no en el background del
   .intro. Si va en el background, se pinta por encima del canvas del confeti
   —que es un hermano anterior— y lo tapa por completo. */
.intro::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background: radial-gradient(125% 95% at 50% 12%,
              var(--bg-intro-hi) 0%, var(--bg-intro-lo) 100%);
}

/* Fila 1: el texto, apoyado contra la impresora. */
.intro__stage {
  align-self: end;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  width: 100%;
  max-width: 720px;
}

/* --- Bloques colapsables: la grilla 1fr→0fr anima la altura de verdad ----- */
.intro__collapse {
  display: grid;
  grid-template-rows: 1fr;
  width: 100%;
  transition: grid-template-rows var(--t-settle) var(--ease-settle),
              opacity          var(--t-base)   var(--ease-inout),
              transform        var(--t-settle) var(--ease-settle);
}
/* El overflow es lo que hace posible el colapso a 0fr, pero recorta todo lo que
   se pinta fuera de la caja: anillo de foco y sombras.

   NO se resuelve con `overflow-clip-margin`. La sombra de foco de la pill se
   extiende 54px hacia abajo (18 de offset + 48 de blur - 12 de spread), y un
   margen de recorte de ese tamaño dejaría asomar la pill entera durante el
   colapso, que es justo lo que el overflow tiene que impedir.
   Se resuelve dando espacio real adentro de la caja: cada bloque se paga su
   propio aire, y ese aire además es la separación que la composición necesita. */
.intro__collapse > * { overflow: hidden; min-height: 0; }

.intro__collapse[hidden] {
  display: grid;              /* sobrescribe el hidden nativo: colapsa, no desaparece */
  grid-template-rows: 0fr;
  opacity: 0;
  pointer-events: none;
}

/* --- Papelito en la apertura ---------------------------------------------
   UN SOLO TAMAÑO, en todos los pasos, y **el mismo que la impresora del panel**.
   No se retrae al despertarse ni crece al imprimir. El primer ticket tiene que
   salir exactamente del tamaño con el que después vive en la columna, así que
   las dos impresoras comparten el token: misma boca, mismo papel.

   El ancho vive en `.printer` y no en `.papelito` porque los porcentajes de la
   ranura resuelven contra `.printer`, y porque un ancho animado en el hijo con
   el padre en `max-content` hacía que Chrome reiniciara la transición en cada
   recálculo (quedaba en currentTime 0, con el ancho congelado). */
.intro .printer { width: var(--impresora-w); }

.intro .papelito {
  width: 100%;
  transition: transform var(--t-base) var(--ease-settle);
}

/* --- Copy ---------------------------------------------------------------- */
/* REGLA DEL BLOQUE COLAPSABLE: el hijo directo del .intro__collapse no lleva
   padding propio, nunca. Con box-sizing: border-box un elemento con padding no
   puede medir menos que ese padding, así que el bloque no llega a cero y queda
   ocupando alto aun estando cerrado. El aire va un nivel más adentro. */
.intro__copy { text-align: center; }
.intro__copy .intro__sub { padding-bottom: var(--s6); }

.intro__title {
  font-size: clamp(30px, 4.6vw, 54px);
  font-weight: var(--w-title);
  letter-spacing: var(--title-tracking);
  line-height: 1.14;
  color: var(--plum);
  text-wrap: balance;
}
.intro__title em { font-style: normal; color: var(--pink); }

.intro__sub {
  margin-top: var(--s4);
  font-size: clamp(15px, 1.3vw, 18px);
  font-weight: var(--w-body);
  color: var(--ink-mute);
}

/* --- Input (paso 2) ------------------------------------------------------ */
/* El aire no es decorativo: contiene la sombra de foco de la pill, que se sale
   54px por abajo (18 de offset + 48 de blur - 12 de spread) y 36px por los
   costados. Sin esto, el overflow del bloque colapsable la corta.
   Va en el <form> y no en el hijo directo, por la regla de arriba. */
.intro__form form { padding: var(--s5) 40px 56px; }

.pill {
  display: flex;
  align-items: center;
  gap: var(--s2);
  width: min(440px, 100%);
  margin-inline: auto;
  padding: 6px 6px 6px var(--s5);
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(8px);
  transition: box-shadow var(--t-base) var(--ease-settle);
}
.pill:focus-within { box-shadow: var(--shadow-lg), var(--focus); }

.pill__input {
  flex: 1;
  min-width: 0;
  padding: var(--s3) 0;
  font-size: 16px;
  color: var(--ink);
}
.pill__input::placeholder { color: var(--ink-mute); opacity: 0.75; }
/* El anillo de foco lo dibuja la pill entera (:focus-within). Si el input
   también lo dibuja, quedan dos anillos, uno adentro del otro. */
.pill__input:focus-visible { box-shadow: none; }

.pill__send {
  display: grid;
  place-items: center;
  flex: none;
  width: 38px;
  aspect-ratio: 1;
  border-radius: 50%;
  color: #fff;
  background: var(--pink);
  box-shadow: var(--shadow-sm);
  transition: background var(--t-fast), transform var(--t-fast) var(--ease-settle);
}
.pill__send:hover  { background: var(--pink-deep); transform: scale(1.06); }
.pill__send:active { background: var(--pink-press); transform: scale(0.94); }
.pill__send:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
.pill__send svg { width: 17px; height: 17px; }

/* --- Hint de abajo ------------------------------------------------------- */
.intro__hint {
  position: absolute;
  left: 50%;
  bottom: var(--s7);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: 14px;
  font-weight: var(--w-med);
  color: var(--pink);
  animation: hint-bob 2.6s var(--ease-inout) infinite;
  transition: opacity var(--t-base) var(--ease-inout);
}
.intro__hint[hidden] { display: flex; opacity: 0; pointer-events: none; }
.intro__hint svg { width: 22px; height: 22px; }

@keyframes hint-bob {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 5px); }
}

@media (max-width: 640px) {
  .intro { padding: var(--s6) var(--s4); }
  .intro__hint { bottom: var(--s5); }
}

/* --- Salida de la portada -------------------------------------------------
   Fundido cruzado con el panel, que entra al mismo tiempo. Quitarla de golpe
   se leía como un corte. */
.intro--sale {
  opacity: 0;
  pointer-events: none;
  transition: opacity 620ms var(--ease-inout);
}
