/* Voyage - landing y soporte.
   Un solo archivo, sin framework, sin JS. Los tokens son los de la app
   (frontend/src/styles.scss) copiados a mano: la landing no importa el SCSS. */

/* Fuentes autoalojadas.
   Playfair solo para títulos, Space Mono solo para los códigos de tres letras.
   El cuerpo usa la pila del sistema y no descarga nada. Subconjunto latino, que
   ya cubre los acentos y la eñe. */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/playfair-display-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/space-mono-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Color: valores reales de la app. --canvas y --sage existen allí pero aquí no
     pintan nada. */
  --cream: #FFFFFF;
  --paper: #F2F5F3;
  --ink: #1C3B34;
  --terracotta: #C67B5C;
  --stamp: var(--terracotta);
  /* La terracota de la app solo llega a 2.97:1 sobre --page y a 3.29:1 con texto
     blanco encima: falla AA en cuanto deja de ser decoración. --stamp queda para
     los trazos (aria-hidden) y todo lo que sea texto o foco usa esta versión
     oscurecida, que pasa 4.5:1 sobre --page (5.16) y sobre --cream (5.70). */
  --stamp-strong: #9B5335;
  --hairline: rgba(28, 59, 52, 0.16);

  /* El fondo cálido de las capturas es un literal suelto en las barras superiores
     de la app, no un token. Se copia a sabiendas. */
  --page: #F7F3ED;
  /* --ink-soft de la app es rgba(28,59,52,0.55): al límite de AA en texto pequeño.
     Aquí va sólido y más oscuro. 6.19:1 sobre --page. */
  --ink-soft: #4A5F58;
  /* Línea secundaria sobre --ink, en el panel de privacidad. 7.36:1. */
  --page-soft: rgba(247, 243, 237, 0.78);

  /* Tipografía: dos voces y un motivo. */
  --font-display: 'Playfair Display', Georgia, serif;
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'Space Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  /* Movimiento: tokens de la app, más dos duraciones propias de la landing, que
     cuenta cosas a escala de sección y no de control. --ease-spring es la firma
     del sello y solo lo usan las banderas del pasaporte. */
  --ease-smooth: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out:    cubic-bezier(0.17, 1, 0.32, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --duration-fast:   150ms;
  --duration-slow:   300ms;
  --duration-reveal: 600ms;
  --duration-draw:   1200ms;

  /* La única sombra. Aquí la llevan solo los objetos del collage que se solapan
     sobre la página (hero y tarjeta final): flotan de verdad. Nada en el flujo
     la usa. */
  --shadow-elevated:
    0 1px 2px rgba(20, 40, 30, 0.05),
    0 4px 12px rgba(20, 40, 30, 0.06),
    0 0 0 0.5px var(--hairline);

  /* Radios, con su regla:
     999 botones, 20 celdas y paneles, 16 billete, 14 marcos de foto y filas. */
  --r-card: 20px;
  --r-ticket: 16px;
  --r-row: 14px;

  --space-section: clamp(4rem, 9vw, 7rem);
}

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

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

body {
  background: var(--page);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.55;
  overflow-wrap: break-word;
}

/* Los objetos girados y el pasaporte que sangra por el borde no pueden empujar la
   página a scroll horizontal. clip, no hidden: no crea contenedor de scroll. */
main { overflow-x: clip; }

img { max-width: 100%; display: block; }
a { color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--stamp-strong);
  outline-offset: 3px;
  border-radius: 4px;
}

.wrap {
  width: 100%;
  max-width: 72rem;
  margin-inline: auto;
  /* En horizontal las muescas del notch se van a los lados. */
  padding-inline: calc(1.25rem + env(safe-area-inset-left, 0px))
                  calc(1.25rem + env(safe-area-inset-right, 0px));
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 1rem;
  top: 1rem;
  z-index: 10;
  background: var(--cream);
  padding: 0.75rem 1rem;
  border-radius: var(--r-row);
  box-shadow: var(--shadow-elevated);
}

/* Cabecera */
.site-head {
  border-bottom: 1px solid var(--hairline);
  padding-block: 1rem;
}
.site-head .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

/* logo.svg es un PNG de 219 KB dentro de un <svg>. La portada no lo sirve tal
   cual: usa logo.webp/logo.png, el mismo PNG recortado a su contenido y reducido a
   120 px de alto (3x su tamaño máximo en pantalla). Soporte sigue componiendo la
   marca con la fuente de display y un trazo de ruta. */
.brand {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  text-decoration: none;
}
.brand-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.brand-trail { display: block; width: 100%; height: 6px; color: var(--stamp); }
.brand-logo { height: clamp(1.875rem, 1.5rem + 1.5vw, 2.25rem); width: auto; }

.nav {
  display: flex;
  align-items: center;
  gap: clamp(0.25rem, 2vw, 1.25rem);
}
.head-link {
  font-size: 0.9375rem;
  color: var(--ink-soft);
  text-decoration: none;
  padding: 0.625rem 0.25rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.head-link:hover { color: var(--ink); }
/* Se rompe por contenido, no por dispositivo: primero sobra el ancla, que el hero
   repite, y en el ancho mínimo también Soporte, que sigue en el pie. */
@media (max-width: 47.99rem) { .head-link--wide { display: none; } }
@media (max-width: 25.99rem) { .nav .head-link { display: none; } }

/* Tipos de título (compartidos con soporte) */
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.015em;
}
h1 { font-size: clamp(2.25rem, 7vw, 3.5rem); }
h2 { font-size: clamp(1.75rem, 4.5vw, 2.25rem); }
h3 { font-size: 1.25rem; }

.lead {
  font-size: 1.125rem;
  color: var(--ink-soft);
  max-width: 38ch;
}

/* Botones */
.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 48px;
  padding: 0.75rem 1.5rem;
  border-radius: 999px;
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
}
/* Tinta sobre blanco: 12.2:1. La terracota queda como acento, no como botón. */
.btn--primary { background: var(--ink); color: var(--cream); }
.btn--primary:hover { background: color-mix(in srgb, var(--ink) 86%, var(--cream)); }
.btn--ghost { border-color: var(--hairline); color: var(--ink); }
.btn--ghost:hover { border-color: var(--ink); }
.btn--sm { min-height: 44px; padding: 0.5rem 1.125rem; font-size: 0.9375rem; }

/* El badge del App Store, que hoy está comentado en index.html. Vive aquí para que
   activarlo sea solo descomentar. */
.badge-store {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
}
.badge-store img { height: 47px; width: auto; }

.cta-note {
  margin-top: 0.875rem;
  font-size: 0.875rem;
  color: var(--ink-soft);
}

/* Piezas de la portada */
.eyebrow {
  margin-bottom: 1rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stamp-strong);
}

/* Nota al margen: el patrón de la app para lo que escribe quien viaja. Se distingue
   por color y tamaño, nunca por cursiva, subrayada con el raíl de ruta. Hay tres
   en toda la página. */
.note {
  display: inline-block;
  max-width: 17ch;
  padding-bottom: 0.375rem;
  border-bottom: 1.5px dashed var(--stamp);
  font-size: 0.9375rem;
  line-height: 1.35;
  color: var(--ink-soft);
  rotate: -2deg;
}

/* Marco de foto: papel blanco con filete, como una copia impresa. --float solo
   para lo que se solapa en un collage. */
.frame {
  background: var(--cream);
  padding: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: var(--r-row);
}
.frame img { width: 100%; height: auto; border-radius: calc(var(--r-row) - 0.5rem); }
.frame--float { box-shadow: var(--shadow-elevated); }
.frame figcaption {
  padding: 0.5rem 0.25rem 0.125rem;
  font-size: 0.8125rem;
  color: var(--ink-soft);
}

/* El billete: el elemento héroe */
.ticket {
  position: relative;
  background: var(--cream);
  border: 1px solid var(--hairline);
  border-radius: var(--r-ticket);
  padding: 1.5rem 1.25rem 1.25rem;
}

.ticket-row {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}
.end { min-width: 0; }
.end--mid { text-align: center; }
.end--to { text-align: right; margin-left: auto; }
.code {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(1.375rem, 5.5vw, 1.75rem);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--ink);
  /* A 320px los códigos siguen sin poder partirse. */
  white-space: nowrap;
}
.city {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Tramo: raíl discontinuo, glifo de transporte en el centro. */
.route {
  flex: 1;
  min-width: 2.5rem;
  display: flex;
  align-items: center;
  gap: 0.375rem;
  padding-top: 0.75rem;
}
.rail {
  flex: 1;
  border-top: 1.5px dashed var(--stamp);
  transform-origin: left center;
}
.mode {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1.5px dashed var(--stamp);
  color: var(--stamp);
}
.mode svg { width: 13px; height: 13px; }

/* La línea de rasgado, con sus dos muescas punzadas en el color de lo que haya
   debajo (--notch). Van sobre este elemento y no sobre .ticket: así la muesca cae
   siempre exactamente sobre la línea. */
.ticket-tear {
  position: relative;
  margin: 1.125rem -1.25rem 1rem;
  border-top: 1px dashed var(--hairline);
}
.ticket-tear::before,
.ticket-tear::after {
  content: '';
  position: absolute;
  top: -11px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--notch, var(--page));
  border: 1px solid var(--hairline);
}
.ticket-tear::before { left: -11px; clip-path: inset(0 0 0 50%); }
.ticket-tear::after { right: -11px; clip-path: inset(0 50% 0 0); }
.ticket-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.375rem;
  line-height: 1.15;
}
.ticket-meta {
  margin-top: 0.375rem;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.ticket-dates {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--hairline);
  font-size: 0.8125rem;
  color: var(--ink-soft);
}

/* Variante compacta, como el compact de app-ticket-header: tres paradas en el
   ancho de un collage o de una celda. */
.ticket--compact { padding: 1rem 1rem 0.875rem; }
.ticket--compact .code { font-size: 1.25rem; }
.ticket--compact .city { font-size: 0.75rem; }
.ticket--compact .route { min-width: 1.5rem; gap: 0.25rem; padding-top: 0.5rem; }
.ticket--compact .mode { width: 22px; height: 22px; }
.ticket--compact .mode svg { width: 11px; height: 11px; }
.ticket--compact .ticket-tear { margin: 0.875rem -1rem 0.75rem; }
.ticket--compact .ticket-title { font-size: 1.0625rem; }
.ticket--compact .ticket-meta { font-size: 0.6875rem; }
.ticket--compact .ticket-dates { margin-top: 0.5rem; padding-top: 0.5rem; font-size: 0.75rem; }

/* Hero: split asimétrico con collage */
.hero { padding-block: clamp(2.5rem, 6vw, 4.5rem) var(--space-section); }
.hero .wrap {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
  align-items: center;
}
.hero h1 {
  font-size: clamp(2.25rem, 4.4vw, 3.5rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.hero .lead { margin-top: 1.25rem; }
.hero .cta-row { margin-top: 2rem; }

/* Móvil: una foto, el billete encima y un detalle. Flujo normal, sin posiciones
   absolutas comprimidas. */
.hero-art {
  position: relative;
  display: grid;
  width: 100%;
  max-width: 34rem;
  margin-inline: auto;
}
.layer--photo { width: 70%; justify-self: end; rotate: 2deg; }
.layer--photo-2 { display: none; }
.layer--ticket { width: min(19rem, 94%); margin-top: -30%; rotate: -2deg; z-index: 2; }
.layer--juntos { width: min(15rem, 68%); justify-self: end; margin-top: -0.5rem; rotate: 1.5deg; z-index: 3; }
.layer--ticket .ticket { box-shadow: var(--shadow-elevated); }

@media (min-width: 56rem) {
  .hero .wrap { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
  .hero-art { display: block; aspect-ratio: 1 / 0.95; }
  .layer { position: absolute; margin: 0; }
  .layer--photo { left: 20%; top: 0; width: 50%; }
  .layer--photo-2 { display: block; right: 0; top: 14%; width: 33%; rotate: 5deg; }
  .layer--ticket { left: 0; top: 50%; width: min(19rem, 68%); rotate: -3deg; }
  .layer--juntos { right: 3%; bottom: 2%; width: 44%; }
}

/* Manifiesto: declaración centrada */
.manifesto {
  padding-block: 0 calc(var(--space-section) * 0.6);
  text-align: center;
}
.manifesto .wrap { position: relative; }
.manifesto h2 {
  font-size: clamp(2.5rem, 7.5vw, 5.5rem);
  line-height: 1.02;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.manifesto .lead { margin: 1.25rem auto 0; max-width: 40ch; }
.manifesto .route { max-width: 20rem; margin: 2.5rem auto 0; padding-top: 0; }
.manifesto .note { margin-top: 2rem; }
@media (min-width: 64rem) {
  .manifesto .note { position: absolute; right: 1.25rem; bottom: 0; margin: 0; rotate: 3deg; }
}

/* Mosaico: 12 columnas, seis celdas de anchos desiguales */
.mosaic { padding-block: calc(var(--space-section) * 0.4) var(--space-section); }
.mosaic h2 { font-size: clamp(1.875rem, 3.6vw, 2.75rem); max-width: 20ch; text-wrap: balance; }
.cells {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  margin-top: 2.5rem;
}
@media (min-width: 40rem) {
  .cells { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 64rem) {
  .cells { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .cell--ruta    { grid-column: span 5; }
  .cell--dias    { grid-column: span 3; }
  .cell--lugares { grid-column: span 4; }
  .cell--juntos  { grid-column: span 3; }
  .cell--mapa    { grid-column: span 5; }
  .cell--tarjeta { grid-column: span 4; }
}
.cell {
  display: flex;
  flex-direction: column;
  background: var(--cream);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  overflow: hidden;
}
.cell-text { padding: 1.25rem 1.25rem 1rem; }
.cell-text p { margin-top: 0.375rem; font-size: 0.9375rem; color: var(--ink-soft); }
.cell-visual { margin-top: auto; padding: 0 1.25rem 1.25rem; }
.cell-visual img { width: 100%; height: auto; }

.cell--ruta { background: var(--paper); --notch: var(--paper); }
.cell--ruta .ticket { max-width: 22rem; rotate: -2deg; }
.cell--dias .cell-visual img,
.cell--lugares .cell-visual img { border-radius: var(--r-row); }
.cell--juntos { background: var(--cream); }
.cell--juntos .cell-visual img { width: min(100%, 14rem); }
.cell--mapa .cell-visual { padding: 0; }
.cell--mapa .cell-visual img { aspect-ratio: 420 / 232; object-fit: cover; }
.cell--tarjeta { background: var(--paper); }
.cell--tarjeta .cell-visual { height: 15rem; overflow: hidden; padding-bottom: 0; }
.cell--tarjeta .cell-visual img {
  width: min(100%, 13rem);
  margin-inline: auto;
  border: 1px solid var(--hairline);
  border-radius: var(--r-row) var(--r-row) 0 0;
}

/* Cómo funciona: secuencia escalonada */
.how { padding-block: var(--space-section); scroll-margin-top: 1rem; }
.how h2 { font-size: clamp(1.875rem, 3.6vw, 2.75rem); }
.steps {
  list-style: none;
  display: grid;
  gap: 2.5rem;
  margin-top: 3rem;
}
/* Cada paso cuelga de su tramo de raíl: bajan como las paradas de una ruta. */
.step {
  position: relative;
  display: grid;
  gap: 1.25rem;
  padding-left: 1.5rem;
}
/* El tramo de raíl de cada paso. Pseudo-elemento y no borde: así se puede dibujar
   al hacer scroll sin mover el contenido. */
.step::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  border-left: 1.5px dashed var(--stamp);
  transform-origin: top;
}
.step p { margin-top: 0.5rem; color: var(--ink-soft); max-width: 36ch; }
.step .frame { max-width: 20rem; }
/* Una franja de interfaz apaisada necesita más ancho para que su texto se lea. */
.step .frame--wide { max-width: 26rem; }
@media (min-width: 56rem) {
  .step {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: 2.5rem;
    width: 66%;
    padding-left: 2.5rem;
  }
  .step:nth-child(2) { margin-left: 17%; }
  .step:nth-child(3) { margin-left: 34%; }
}

/* Privacidad: panel de tinta contenido, un objeto dentro del mismo tema */
.privacy { padding-block: 0 var(--space-section); scroll-margin-top: 1rem; }
.privacy-panel {
  background: var(--ink);
  color: var(--page);
  border-radius: var(--r-card);
  padding: clamp(2.5rem, 7vw, 5.5rem) clamp(1.5rem, 6vw, 5rem);
}
.privacy h2 {
  color: var(--page);
  font-size: clamp(2.25rem, 5.5vw, 4.25rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  max-width: 16ch;
}
.privacy .lead { margin-top: 1.25rem; max-width: 46ch; color: var(--page-soft); }
.principles {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: 1.5rem 2rem;
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
.principles li {
  padding-top: 1rem;
  border-top: 1.5px dashed var(--stamp);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.25rem, 2.4vw, 1.625rem);
  line-height: 1.2;
}

/* Colaboración: split con álbum */
.together { padding-block: 0 var(--space-section); }
.together .wrap { display: grid; gap: 3rem; align-items: center; }
.together h2 { font-size: clamp(1.875rem, 3.2vw, 2.5rem); text-wrap: balance; }
.together .lead { margin-top: 1rem; }
.album {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
  gap: 0.5rem;
}
.album .frame { rotate: var(--r, 0deg); }
.album .frame:nth-child(1) { --r: -4deg; --from-x: -4rem; margin-top: 2rem; }
.album .frame:nth-child(2) { --r: 1deg;  --from-x: 0rem;  z-index: 1; }
.album .frame:nth-child(3) { --r: 4deg;  --from-x: 4rem;  margin-top: 3rem; }
.together .note { justify-self: end; margin-top: 1.5rem; }
@media (min-width: 56rem) {
  .together .wrap { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
  .album { gap: 0; }
  .album .frame:nth-child(2) { scale: 1.08; }
  .album .frame + .frame { margin-left: -1.5rem; }
}
.album-wrap { display: grid; }

/* Pasaporte: banda a sangre con el libro rompiendo el margen */
.passport {
  background: var(--paper);
  border-block: 1px solid var(--hairline);
  padding-block: var(--space-section);
}
.passport h2 { font-size: clamp(1.875rem, 3.6vw, 2.75rem); }
.passport .lead { margin-top: 1rem; max-width: 46ch; }
.shelf {
  display: grid;
  gap: 2.5rem;
  align-items: center;
  margin-top: 3rem;
}
.passport-book { width: min(17rem, 72%); rotate: -3deg; }
.ensigns {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--hairline);
  border-radius: var(--r-row);
  background: var(--cream);
  justify-content: center;
  width: fit-content;
  max-width: 100%;
  justify-self: center;
}
.ensign {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  min-width: 4.5rem;
  rotate: var(--tilt, 0deg);
}
.ensign:nth-child(1) { --tilt: -4deg; }
.ensign:nth-child(2) { --tilt: 3deg; }
.ensign:nth-child(3) { --tilt: -2deg; }
.ensign-flag { font-size: 2.5rem; line-height: 1.1; }
.ensign-name { font-size: 0.8125rem; color: var(--ink-soft); }
@media (min-width: 56rem) {
  .shelf { grid-template-columns: auto minmax(0, 1fr) auto; gap: 3.5rem; }
  /* El libro sale por el borde izquierdo de la rejilla. */
  .passport-book { width: 17rem; margin-left: clamp(-6rem, -5vw, -2rem); }
}

/* Tarjeta de viaje: split con objeto vertical */
.card-section { padding-block: var(--space-section); scroll-margin-top: 1rem; }
.card-section .wrap { display: grid; gap: 3rem; align-items: center; }
.card-section h2 { font-size: clamp(1.875rem, 3.6vw, 2.75rem); max-width: 14ch; }
.card-section .lead { margin-top: 1rem; }
.card-object { justify-self: center; width: min(20rem, 82%); rotate: 3deg; }
.card-object img {
  width: 100%;
  height: auto;
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-elevated);
}
@media (min-width: 56rem) {
  .card-section .wrap { grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr); }
}

/* Cierre: centrado estrecho */
.closing {
  padding-block: var(--space-section);
  border-top: 1px solid var(--hairline);
  text-align: center;
}
.closing h2 { font-size: clamp(2.25rem, 5vw, 3.75rem); text-wrap: balance; }
.closing .lead { margin: 1rem auto 0; }
.closing .cta-row { justify-content: center; margin-top: 2rem; }

/* Movimiento.
   Todo vive dentro de no-preference: con movimiento reducido la página se pinta
   quieta y completa. Solo transform, translate, rotate, scale y opacity.
   Lo de carga funciona en todos los navegadores. Lo ligado al scroll va en
   animation-timeline: view() tras @supports; donde no existe (hoy Firefox, y
   Safari anterior a la 26) los elementos se pintan ya en su estado final. */
@keyframes draw   { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes appear { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise   { from { opacity: 0; translate: 0 var(--rise, 1rem); } to { opacity: 1; translate: 0 0; } }
@keyframes drift  { from { translate: 0 0; } to { translate: 0 var(--drift, -1rem); } }
@keyframes stamp-land {
  0%   { opacity: 0; scale: 1.15; rotate: -14deg; }
  60%  { opacity: 1; scale: 0.97; rotate: calc(var(--tilt) + 3deg); }
  100% { opacity: 1; scale: 1;    rotate: var(--tilt); }
}
@keyframes settle {
  from { opacity: 0; translate: 0 2rem; rotate: 9deg; }
  to   { opacity: 1; translate: 0 0;    rotate: 3deg; }
}
@keyframes draw-down { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes gather {
  from { opacity: 0; translate: var(--from-x, 0) 2.5rem; rotate: 0deg; }
  to   { opacity: 1; translate: 0 0; rotate: var(--r, 0deg); }
}
@keyframes arrive {
  from { opacity: 0; translate: -3rem 1rem; rotate: -12deg; }
  to   { opacity: 1; translate: 0 0;        rotate: -3deg; }
}
@keyframes open-up { from { opacity: 0.5; scale: 0.94; } to { opacity: 1; scale: 1; } }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }

  .btn { transition: background-color var(--duration-fast) var(--ease-smooth),
                     border-color var(--duration-fast) var(--ease-smooth),
                     transform var(--duration-fast) var(--ease-smooth); }
  .btn:active { transform: scale(0.98); }

  /* El billete del hero traza su ruta al cargar: existe un camino entre ciudades. */
  .hero .rail { animation: draw var(--duration-draw) var(--ease-out) 350ms both; }
  .hero .mode { animation: appear var(--duration-slow) var(--ease-out) 700ms both; }

  /* El collage se posa por capas: primero la foto, luego el billete, luego quién iba. */
  .hero-art .layer > * { animation: rise var(--duration-reveal) var(--ease-out) both; }
  .layer--photo-2 > * { animation-delay: 90ms; }
  .layer--ticket > *  { animation-delay: 180ms; }
  .layer--juntos > *  { animation-delay: 300ms; }

  @supports (animation-timeline: view()) {
    /* Parallax corto al salir del hero: cada capa a su profundidad. */
    .hero-art .layer {
      animation: drift linear both;
      animation-timeline: view();
      animation-range: exit 0% exit 100%;
    }
    .layer--photo   { --drift: -0.5rem; }
    .layer--photo-2 { --drift: -1.5rem; }
    .layer--ticket  { --drift: -1rem; }
    .layer--juntos  { --drift: -1.5rem; }

    /* Revelado al entrar: orden de lectura. */
    .reveal {
      animation: rise var(--ease-out) both;
      animation-timeline: view();
      animation-range: entry 0% entry 70%;
    }

    /* La ruta del manifiesto se dibuja al llegar a ella. */
    .manifesto .rail {
      animation: draw var(--ease-out) both;
      animation-timeline: view();
      animation-range: entry 20% cover 45%;
    }

    /* Los principios de privacidad, uno detrás de otro. */
    .principles li {
      animation: rise var(--ease-out) both;
      animation-timeline: view();
    }
    .principles li:nth-child(1) { animation-range: entry 0% entry 60%; }
    .principles li:nth-child(2) { animation-range: entry 15% entry 75%; }
    .principles li:nth-child(3) { animation-range: entry 30% entry 90%; }
    .principles li:nth-child(4) { animation-range: entry 45% cover 55%; }

    /* El sello aterriza: un país ha quedado documentado. */
    .ensign {
      animation: stamp-land var(--ease-spring) both;
      animation-timeline: view();
    }
    .ensign:nth-child(1) { animation-range: entry 30% cover 35%; }
    .ensign:nth-child(2) { animation-range: entry 50% cover 42%; }
    .ensign:nth-child(3) { animation-range: entry 70% cover 50%; }

    /* La tarjeta se posa en su sitio: el viaje se convierte en recuerdo. */
    .card-object {
      animation: settle var(--ease-out) both;
      animation-timeline: view();
      animation-range: entry 0% cover 40%;
    }

    /* Las celdas del mosaico entran columna a columna: orden de lectura. */
    @media (min-width: 64rem) {
      .cells .cell:nth-child(3n+2) { animation-range: entry 10% entry 80%; }
      .cells .cell:nth-child(3n)   { animation-range: entry 20% entry 90%; }
    }

    /* El billete de la celda Ruta traza su ruta tramo a tramo: existe un camino
       entre ciudades. Línea de tiempo con nombre de la celda, que la comparten
       raíles y glifos. */
    .cell--ruta { view-timeline-name: --ruta; }
    .cell--ruta .rail {
      animation: draw var(--ease-out) both;
      animation-timeline: --ruta;
      animation-range: entry 40% cover 40%;
    }
    .cell--ruta .route ~ .route .rail { animation-range: entry 70% cover 55%; }
    .cell--ruta .mode {
      animation: appear var(--ease-out) both;
      animation-timeline: --ruta;
      animation-range: entry 60% cover 50%;
    }

    /* Cada paso dibuja su tramo de raíl al llegar: el viaje avanza de uno a otro. */
    .step { view-timeline-name: --step; }
    .step::before {
      animation: draw-down var(--ease-out) both;
      animation-timeline: --step;
      animation-range: entry 10% cover 50%;
    }

    /* La privacidad es una pausa: el panel verde crece hasta ocupar su sitio. */
    .privacy-panel {
      animation: open-up var(--ease-out) both;
      animation-timeline: view();
      animation-range: entry 0% cover 30%;
    }

    /* Las fotos llegan separadas y se agrupan: varias personas, un mismo viaje. */
    .album .frame {
      animation: gather var(--ease-out) both;
      animation-timeline: view();
    }
    .album .frame:nth-child(1) { animation-range: entry 10% cover 40%; }
    .album .frame:nth-child(2) { animation-range: entry 0% cover 30%; }
    .album .frame:nth-child(3) { animation-range: entry 20% cover 50%; }

    /* El pasaporte llega antes que sus sellos. */
    .passport-book {
      animation: arrive var(--ease-out) both;
      animation-timeline: view();
      animation-range: entry 0% cover 30%;
    }
  }
}

/* Pie */
.site-foot {
  border-top: 1px solid var(--hairline);
  padding-block: 2rem calc(2rem + env(safe-area-inset-bottom, 0px));
  font-size: 0.875rem;
  color: var(--ink-soft);
}
.site-foot ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin-bottom: 0.75rem;
}
.site-foot a { color: var(--ink-soft); }
.site-foot a:hover { color: var(--ink); }

/* Soporte */
.support { padding-block: clamp(2rem, 6vw, 3.5rem); }
.support .wrap { max-width: 42.5rem; }
.support h2 { margin-top: 2.5rem; }
.support h2:first-of-type { margin-top: 2rem; }

.contact {
  margin-top: 1.5rem;
  padding: 1.25rem;
  background: var(--cream);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
}
.contact a {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--stamp-strong);
}
.contact p { margin-top: 0.375rem; font-size: 0.875rem; color: var(--ink-soft); }

.faq {
  margin-top: 0.5rem;
  background: var(--cream);
  border: 1px solid var(--hairline);
  border-radius: var(--r-row);
}
.faq + .faq { margin-top: 0.5rem; }
.faq summary {
  min-height: 52px;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  border-radius: var(--r-row);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+';
  margin-left: auto;
  font-size: 1.25rem;
  color: var(--stamp-strong);
}
.faq[open] summary::after { content: '–'; }
.faq p {
  padding: 0 1rem 1rem;
  color: var(--ink-soft);
}
.faq a { color: var(--stamp-strong); }

.link-list { list-style: none; margin-top: 1rem; }
.link-list li + li { margin-top: 0.25rem; }
.link-list a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--stamp-strong);
}

.status {
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.875rem;
  color: var(--ink-soft);
}
