/* EuroTrip -- hoja de estilos unica.
 *
 * Esta app se usa DE PIE, EN LA CALLE, CON UNA MANO Y CON SOL. Eso, y no
 * el gusto, es lo que decide casi todo lo de aqui:
 *
 *   - Contraste alto. Un gris elegante sobre blanco no se lee al sol.
 *   - Todo lo que se toca mide 44 px o mas: es el minimo de Apple para que
 *     un dedo acierte sin mirar.
 *   - Los textos de los campos, 16 px. Menos de eso hace que Safari haga
 *     zoom solo al enfocar, y la pantalla queda torcida.
 *   - Barra de pestanas abajo, no arriba: es donde llega el pulgar.
 */

:root {
  --fondo: #f6f4f9;
  --tarjeta: #ffffff;
  --tinta: #1a1730;
  --tenue: #6b6885;
  --linea: #e5e1ee;
  --acento: #5b3fb8;
  --acento-suave: #ede9f9;
  --coral: #e0563c;
  --alerta: #c33b28;
  --bien: #1f7a4d;
  --sombra: 0 1px 2px rgba(26, 23, 48, .06), 0 8px 24px rgba(26, 23, 48, .07);
  --radio: 16px;

  /* El cielo de un vuelo nocturno. Es el mismo degradado del icono: la app
   * y el icono de la pantalla de inicio tienen que ser la misma cosa. */
  --cielo: linear-gradient(125deg, #151b54 0%, #3a2a8f 28%, #6f3bb3 52%,
                           #aa3e7a 76%, #e0563c 100%);
}

@media (prefers-color-scheme: dark) {
  :root {
    --fondo: #0f0d1a;
    --tarjeta: #191627;
    --tinta: #efecf8;
    --tenue: #9a94b5;
    --linea: #2a2540;
    --acento: #a68cff;
    --acento-suave: #221c3d;
    --coral: #ff8365;
    --alerta: #ff7a5e;
    --bien: #57c98d;
    --sombra: none;
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--fondo);
  color: var(--tinta);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  /* El rebote al final del scroll, en una app instalada, se siente como
   * si la pagina se despegara. */
  overscroll-behavior-y: none;
}

/* ---------- Estructura ----------
 *
 * LA APP ES UNA COLUMNA DE LA ALTURA DE LA PANTALLA, con tres filas:
 * cabecera, contenido y barra de pestanas. El que se desplaza es el
 * contenido, por dentro; las otras dos filas no se mueven porque no tienen
 * a donde.
 *
 * Esto sustituye a un position:fixed en la barra, que fallaba de una forma
 * concreta: en un iPhone "el fondo de la pantalla" no es un sitio fijo --
 * cambia con la barra del navegador, con el teclado y con el gesto de
 * inicio -- y WebKit no siempre recolocaba la barra cuando la pagina era
 * CORTA y no se podia desplazar. En una pantalla larga quedaba pegada
 * abajo; en una corta se despegaba y quedaba flotando a media altura.
 *
 * Siendo la ultima fila de la columna, no puede flotar: no hay nada
 * debajo.
 *
 * Solo aplica a la app (body.app). La pantalla de entrar NO lleva esta
 * clase a proposito: alli el teclado puede tapar el formulario, y esa
 * pagina tiene que poder desplazarse entera.
 */

body.app {
  height: 100vh;   /* respaldo para navegadores sin dvh */
  height: 100dvh;  /* la altura VISIBLE, que en el movil no es la misma */
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.cabecera {
  flex: 0 0 auto;
  z-index: 20;
  background: var(--fondo);
  border-bottom: 1px solid var(--linea);
  /* La muesca del iPhone. Sin esto, el titulo queda debajo del reloj. */
  padding: calc(env(safe-area-inset-top) + 12px) 16px 10px;
}

.cabecera__titulo { font-size: 22px; font-weight: 800; letter-spacing: -.02em; margin: 0; }
.cabecera__sub { font-size: 13px; color: var(--tenue); margin: 2px 0 0; }

body.app > main {
  /* La fila que crece y la unica que se desplaza. */
  flex: 1 1 auto;
  overflow-y: auto;
  /* Al llegar al final, el tiron NO arrastra la app entera: sin esto, en
   * una pagina corta el rebote de iOS se siente como si la app se
   * despegara de la pantalla. */
  overscroll-behavior-y: contain;
  -webkit-overflow-scrolling: touch;
}

main {
  padding: 14px 16px 22px;
}

/* El contenido no se estira en una pantalla ancha. El limite va aqui
 * dentro y no en <main>, porque <main> ahora es una fila de la columna y
 * tiene que ocupar todo el ancho para que su barra de desplazamiento salga
 * en el borde. */
#pantalla {
  max-width: 720px;
  margin: 0 auto;
}

.pestanas {
  flex: 0 0 auto;
  z-index: 30;
  display: flex;
  background: var(--tarjeta);
  border-top: 1px solid var(--linea);
  /* La franja del gesto de inicio. Es relleno DENTRO de la barra, no un
   * hueco debajo: el fondo de la barra tiene que llegar hasta el borde. */
  padding-bottom: env(safe-area-inset-bottom);
}

.pestana {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 8px 2px 6px;
  min-height: 52px;
  border: 0;
  background: none;
  color: var(--tenue);
  font-size: 10.5px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.pestana svg { width: 22px; height: 22px; }
.pestana--activa { color: var(--acento); }

/* ---------- Piezas ---------- */

.tarjeta {
  background: var(--tarjeta);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: 14px;
  margin-bottom: 12px;
  box-shadow: var(--sombra);
}

.tarjeta__titulo {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--tenue);
  margin-bottom: 10px;
}

.fila {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 11px 0;
  border-top: 1px solid var(--linea);
}
.fila:first-of-type { border-top: 0; padding-top: 2px; }
.fila__cuerpo { flex: 1; min-width: 0; }
.fila__titulo { font-weight: 650; }
.fila__sub { font-size: 13px; color: var(--tenue); }
.fila__derecha { text-align: right; white-space: nowrap; font-weight: 700; }

.hora {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  min-width: 46px;
  color: var(--acento);
}
.cifra { font-variant-numeric: tabular-nums; }

.tenue { color: var(--tenue); }
.error { color: var(--alerta); font-size: 14px; min-height: 1px; margin: 6px 0 0; }
.bien { color: var(--bien); }

.etiqueta {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--acento-suave);
  color: var(--acento);
  vertical-align: middle;
}
.etiqueta--aviso { background: rgba(192, 73, 43, .12); color: var(--alerta); }

/* ---------- Botones y formularios ---------- */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 46px;
  padding: 0 18px;
  border: 0;
  border-radius: 11px;
  background: var(--acento);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
}
.boton:disabled { opacity: .5; }
.boton--bloque { display: flex; width: 100%; }
.boton--fantasma { background: transparent; color: var(--acento); border: 1px solid var(--linea); }
.boton--peligro { background: var(--alerta); }
.boton--chico { min-height: 36px; padding: 0 12px; font-size: 13px; border-radius: 9px; }

.campo { margin-bottom: 12px; }
.campo label { display: block; font-size: 13px; font-weight: 650; margin-bottom: 5px; }
.campo input, .campo select, .campo textarea {
  width: 100%;
  min-height: 46px;
  padding: 10px 12px;
  border: 1px solid var(--linea);
  border-radius: 11px;
  background: var(--tarjeta);
  color: var(--tinta);
  /* 16 px EXACTOS. Con 15 px, Safari hace zoom al enfocar el campo. */
  font-size: 16px;
  font-family: inherit;
}
.campo textarea { min-height: 120px; resize: vertical; line-height: 1.5; }
.campo input:focus, .campo select:focus, .campo textarea:focus {
  outline: 2px solid var(--acento);
  outline-offset: -1px;
}
.campo__pista { font-size: 12px; color: var(--tenue); margin: 4px 0 0; }

.dos-columnas { display: flex; gap: 10px; }
.dos-columnas > * { flex: 1; min-width: 0; }

/* ---------- Modal ---------- */

.modal-fondo {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(10, 15, 22, .5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.modal {
  width: 100%;
  max-width: 560px;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--tarjeta);
  border-radius: 20px 20px 0 0;
  padding: 18px 16px calc(20px + env(safe-area-inset-bottom));
  -webkit-overflow-scrolling: touch;
}
.modal h2 { font-size: 18px; font-weight: 800; margin: 0 0 14px; }
@media (min-width: 640px) {
  .modal-fondo { align-items: center; }
  .modal { border-radius: 20px; }
}

/* ---------- La pantalla de hoy ---------- */

.hoy-cabeza {
  position: relative;
  overflow: hidden;
  background: var(--cielo);
  /* El degradado es mas ancho que la caja y se desplaza muy despacio: da
   * la sensacion de que el cielo se mueve sin que nada parpadee. Dos
   * minutos por vuelta -- si fuera rapido, marearia y distraeria de lo
   * unico que importa aqui, que es la cifra. */
  background-size: 260% 260%;
  animation: cielo 120s ease-in-out infinite alternate;
  color: #fff;
  border-radius: 20px;
  padding: 18px;
  margin-bottom: 12px;
}
.hoy-cabeza__ciudad { font-size: 28px; font-weight: 800; letter-spacing: -.03em; }
.hoy-cabeza__fecha { opacity: .82; font-size: 14px; }

@keyframes cielo {
  from { background-position: 0% 30%; }
  to   { background-position: 100% 70%; }
}

/* ---------- La cuenta atras ---------- */
/*
 * Es la pantalla que se abre durante los dos meses previos, o sea la que
 * mas veces se va a ver en toda la vida de la app. Por eso es la unica que
 * se permite ser grande y ocupar sitio: no esta informando de nada urgente,
 * esta contando cuanto falta, que es justo lo que uno quiere sentir.
 */
.cuenta {
  display: flex;
  gap: 6px;
  margin: 14px 0 4px;
}
.cuenta__caja {
  flex: 1;
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 13px;
  padding: 9px 4px 7px;
  text-align: center;
  backdrop-filter: blur(2px);
}
.cuenta__cifra {
  font-size: 30px;
  font-weight: 800;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
}
.cuenta__cifra--dias { font-size: 38px; }
.cuenta__unidad {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .1em;
  opacity: .75;
  font-weight: 700;
}
/* Los segundos laten. Es el unico elemento de la app que se mueve solo, y
 * es el que dice "esto esta pasando ahora". */
.cuenta__caja--seg .cuenta__cifra { animation: latir 1s ease-in-out infinite; }
@keyframes latir {
  0%, 60%, 100% { opacity: 1; }
  30% { opacity: .55; }
}

/* La frase que va cambiando: momentos reales del itinerario, no frases de
 * folleto. Salen de los dias que hay cargados. */
.chispa {
  min-height: 20px;
  font-size: 14px;
  font-weight: 600;
  opacity: .9;
  margin-top: 10px;
}
.chispa span { display: inline-block; animation: asomar .6s ease both; }
@keyframes asomar {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* El vuelo de hoy va arriba de todo y no se parece a nada mas de la
 * pantalla: es lo unico que, si se pasa por alto, no tiene arreglo. */
.vuelo-hoy {
  border: 2px solid var(--alerta);
  background: var(--tarjeta);
  border-radius: var(--radio);
  padding: 14px;
  margin-bottom: 12px;
}
.vuelo-ruta { display: flex; align-items: center; gap: 10px; margin: 8px 0; }
.vuelo-punta { flex: 1; }
.vuelo-punta__hora { font-size: 24px; font-weight: 800; font-variant-numeric: tabular-nums; }
.vuelo-punta__lugar { font-size: 13px; color: var(--tenue); }
.vuelo-flecha { color: var(--tenue); font-size: 20px; }

.tira-dias { display: flex; gap: 7px; overflow-x: auto; padding: 2px 0 10px; }
.tira-dia {
  flex: 0 0 auto;
  min-width: 50px;
  padding: 7px 4px;
  border: 1px solid var(--linea);
  border-radius: 11px;
  background: var(--tarjeta);
  color: var(--tinta);
  text-align: center;
  font-size: 11px;
  text-decoration: none;
  cursor: pointer;
}
.tira-dia strong { display: block; font-size: 16px; }
.tira-dia--hoy { border-color: var(--acento); background: var(--acento-suave); color: var(--acento); }

/* ---------- Mapa ---------- */

#mapa { height: 260px; border-radius: var(--radio); overflow: hidden; border: 1px solid var(--linea); }
.pin-numero {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  background: var(--acento); color: #fff;
  border: 2px solid #fff;
  border-radius: 50%;
  font-size: 12px; font-weight: 800;
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
/* Los creditos de OpenStreetMap son obligatorios por licencia: se hacen
 * discretos, nunca se ocultan. */
.leaflet-container .leaflet-control-attribution { font-size: 9px; opacity: .8; }

/* ---------- Aviso de sin conexion ---------- */

.aviso-cache {
  display: flex;
  gap: 8px;
  align-items: center;
  background: var(--acento-suave);
  color: var(--acento);
  border-radius: 11px;
  padding: 9px 12px;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 12px;
}

.cargando { color: var(--tenue); font-size: 14px; }

/* ---------- Entrar ---------- */

.entrar {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 18px calc(24px + env(safe-area-inset-bottom));
}
.entrar__caja { width: 100%; max-width: 380px; }
.entrar__marca { text-align: center; margin-bottom: 22px; }
.entrar__marca h1 { font-size: 28px; font-weight: 800; margin: 8px 0 2px; letter-spacing: -.02em; }
.entrar__marca p { color: var(--tenue); font-size: 14px; margin: 0; }

/* ============================================================
 * EL LOGO Y EL MOVIMIENTO
 * ============================================================
 *
 * REGLA QUE MANDA SOBRE TODO LO DE ABAJO: la animacion esta al servicio de
 * la ilusion del viaje, nunca por delante de la informacion. Concretamente:
 *
 *   - Nada se mueve mas de medio segundo al entrar a una pantalla. Si hay
 *     que esperar a que termine una animacion para leer a que hora sale el
 *     avion, la animacion sobra.
 *   - Solo dos cosas se mueven en bucle: el avion del logo y el latido de
 *     los segundos. Las dos estan en la pantalla de la cuenta atras, que es
 *     la de ilusionarse. Estando ya de viaje, la pantalla se queda quieta.
 *   - Quien tenga activado "reducir movimiento" en su telefono no ve nada
 *     de esto. Va al final del archivo y no es negociable: hay gente a la
 *     que el movimiento en pantalla le produce mareo de verdad.
 */

.logo { display: block; }
.logo__globo, .logo__meridiano { fill: none; stroke: currentColor; }
.logo__orbita-linea { fill: none; stroke: currentColor; opacity: .55; }
.logo__avion { fill: currentColor; }

/* El avion da la vuelta al mundo. Veinte segundos por vuelta: lo bastante
 * lento para que no distraiga y lo bastante vivo para que se note que la
 * app esta despierta. */
.logo__orbita {
  transform-origin: 50px 50px;
  animation: orbitar 20s linear infinite;
}
@keyframes orbitar {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* El logo de la cabecera, pequenito al lado del titulo. */
.marca { display: flex; align-items: center; gap: 9px; }
.marca .logo { width: 26px; height: 26px; color: var(--acento); flex: 0 0 auto; }

/* El de la pantalla de entrada, en grande y sobre el cielo. */
.logo--grande {
  width: 116px; height: 116px;
  margin: 0 auto 6px;
  color: #fff;
  filter: drop-shadow(0 6px 22px rgba(90, 45, 160, .45));
}
.logo--hero { width: 74px; height: 74px; color: #fff; opacity: .95; }

/* La caja de marca de la pantalla de entrada: el mismo cielo del icono. */
.entrar__cielo {
  background: var(--cielo);
  background-size: 220% 220%;
  animation: cielo 90s ease-in-out infinite alternate;
  border-radius: 24px;
  padding: 26px 20px 22px;
  margin-bottom: 18px;
  text-align: center;
  color: #fff;
}
.entrar__cielo h1 {
  font-size: 30px; font-weight: 800; margin: 10px 0 2px; letter-spacing: -.03em;
}
.entrar__cielo p { opacity: .85; font-size: 14px; margin: 0; }

/* ---------- La entrada de cada pantalla ----------
 *
 * Las tarjetas asoman de abajo, escalonadas. Es lo que hace que abrir la
 * app se sienta como que algo empieza, en vez de como que aparece un
 * documento. Dura 380 ms en total: para cuando el dedo llega a tocar algo,
 * ya termino.
 */
@keyframes asomar-tarjeta {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
#pantalla > * {
  animation: asomar-tarjeta .38s cubic-bezier(.2, .7, .3, 1) backwards;
}
#pantalla > *:nth-child(1) { animation-delay: 0ms; }
#pantalla > *:nth-child(2) { animation-delay: 55ms; }
#pantalla > *:nth-child(3) { animation-delay: 110ms; }
#pantalla > *:nth-child(4) { animation-delay: 160ms; }
#pantalla > *:nth-child(5) { animation-delay: 205ms; }
#pantalla > *:nth-child(n+6) { animation-delay: 240ms; }

/* Al tocar, la tarjeta se hunde un poco. En un telefono, sin puntero, es
 * la unica confirmacion de que el toque llego. */
.fila[data-lugar], .fila[data-vuelo], .fila[data-gasto], .tira-dia, .boton {
  transition: transform .12s ease, opacity .12s ease;
}
.boton:active, .tira-dia:active { transform: scale(.97); }

/* El dia de hoy en la tira, marcado con un pulso lento. */
.tira-dia--hoy {
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--acento) 45%, transparent);
  animation: pulso 2.6s ease-out infinite;
}
@keyframes pulso {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--acento) 45%, transparent); }
  70%  { box-shadow: 0 0 0 9px color-mix(in srgb, var(--acento) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--acento) 0%, transparent); }
}

/* La tarjeta del vuelo de hoy respira. Es lo unico de la pantalla que, si
 * se pasa por alto, no tiene arreglo. */
.vuelo-hoy { animation: respirar 3.4s ease-in-out infinite; }
@keyframes respirar {
  0%, 100% { border-color: var(--coral); }
  50%      { border-color: color-mix(in srgb, var(--coral) 45%, transparent); }
}

/* ---------- Y aqui se apaga todo ----------
 *
 * "prefers-reduced-motion" no es una preferencia estetica: hay personas a
 * las que el movimiento en pantalla les provoca mareo o migrana. Si el
 * sistema lo pide, la app se queda quieta entera -- incluido el avion del
 * logo, que sigue estando ahi, solo que parado.
 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ---------- El aviso de instalar ----------
 *
 * Se ve una vez, se cierra y no vuelve. Un consejo repetido cada vez que se
 * abre la app deja de ser un consejo y pasa a ser un estorbo.
 */
.instalar {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--acento-suave);
  border: 1px solid color-mix(in srgb, var(--acento) 28%, transparent);
  border-radius: var(--radio);
  padding: 13px 12px 13px 14px;
  margin-bottom: 12px;
}
.instalar__icono { flex: 0 0 auto; }
.instalar__icono .logo { width: 30px; height: 30px; color: var(--acento); }
.instalar__titulo { font-weight: 750; font-size: 14px; color: var(--acento); }
.instalar__texto { font-size: 13px; line-height: 1.42; margin-top: 2px; }
.instalar__cerrar {
  flex: 0 0 auto;
  /* 34 px de zona tocable: el aspa se ve pequena, pero el dedo no. */
  width: 34px; height: 34px;
  margin: -6px -4px 0 0;
  border: 0;
  background: none;
  color: var(--tenue);
  font-size: 21px;
  line-height: 1;
  cursor: pointer;
}
