/* Landing publica — sistema visual propio "hiperlujo editorial", aislado
   del resto de la app. No se tocan los tokens compartidos (tokens.css)
   ni el dashboard/motor de eventos: todo vive bajo .landing-page. */
.landing-page {
  --landing-bg: #F1ECE2;
  --landing-card-bg: #FAF7F2;
  --landing-hairline: #C9BFAE;
  --landing-ink: #2A2620;
  --landing-ink-soft: #5C5C54;
  --landing-accent: #63694E;
  --landing-cream: #F6F1E9;
  --landing-blush: #D7C4B7;
  --font-display: 'Bodoni Moda', serif;

  margin: 0;
  color: var(--landing-ink);
  font-family: var(--font-sans);
  line-height: 1.65;

  /* Microtextura de lino: trama cruzada casi imperceptible + un veladura
     radial suave, 100% CSS (sin imagenes), para que el fondo no se sienta
     plano detras de la tipografia. */
  background-color: var(--landing-bg);
  background-image:
    radial-gradient(ellipse at center, rgba(255, 255, 255, 0.32) 0%, rgba(42, 38, 32, 0.05) 100%),
    repeating-linear-gradient(45deg, rgba(42, 38, 32, 0.028) 0px, rgba(42, 38, 32, 0.028) 1px, transparent 1px, transparent 4px),
    repeating-linear-gradient(-45deg, rgba(42, 38, 32, 0.028) 0px, rgba(42, 38, 32, 0.028) 1px, transparent 1px, transparent 4px);
}

.landing-page a:focus-visible,
.landing-page button:focus-visible {
  outline: 2px solid var(--landing-accent);
  outline-offset: 3px;
}

.landing-page h1,
.landing-page h2,
.landing-page h3 {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 400;
  color: inherit;
  margin: 0;
}

.landing-page .accent-italic {
  font-style: italic;
}

/* Etiquetas pequenas en mayusculas, tracking amplio — el vocabulario Inter */
.landing-page .eyebrow,
.landing-page .section-title,
.landing-page .btn-login-envolvente,
.landing-page .footer-links a,
.landing-page .btn-whatsapp,
.landing-page .btn-preview,
.landing-page .currency {
  font-family: var(--font-sans);
  text-transform: uppercase;
  letter-spacing: 0.16em;
}

/* ---------- Encabezado ---------- */
/* Absoluto y transparente: flota sobre el hero sin depender de calcular
   su altura a mano (mas robusto que un margen negativo). */
.landing-header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: 1120px;
  margin: 0 auto;
  padding: 1.85rem 1.5rem;
}

/* Marca (2026-07-24): solo el monograma LA, sin el nombre al lado — decision
   del Product Owner despues de verlo en vivo. Va en su version blanca porque
   el encabezado flota sobre la foto oscura del hero.
   Sin el texto que lo acompanaba, el monograma necesita mas altura para
   sostener la misma presencia en la barra. */
.landing-header .logo {
  display: flex;
  align-items: center;
}

.landing-header .logo-monograma {
  height: 2.1rem;
  width: auto;
  display: block;
}

/* Botón envolvente de login (2026-07-08): antes era un link suelto sin
   contorno, poco intuitivo sobre la foto del Hero. Mismo lenguaje visual
   "cristal" que el botón de música/los marcos de iPhone (borde + fondo
   translúcido claro), para que se sienta como un control, no como texto. */
.landing-header .btn-login-envolvente {
  display: inline-block;
  color: var(--landing-cream);
  text-decoration: none;
  font-size: 0.7rem;
  padding: 0.65rem 1.3rem;
  border: 1px solid rgba(246, 241, 233, 0.4);
  border-radius: 999px;
  background: rgba(246, 241, 233, 0.08);
  transition: all 0.4s ease;
}

.landing-header .btn-login-envolvente:hover {
  background: rgba(246, 241, 233, 0.2);
  border-color: rgba(246, 241, 233, 0.75);
  color: var(--landing-blush);
}

/* ---------- Hero: atmosfera fotografica ---------- */
.hero {
  position: relative;
  min-height: 82vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2rem 1.5rem 4rem;
  /* Tres capas, de arriba hacia abajo: vineteado, velo y foto.
     El vineteado oscurece las orillas y deja el centro mas limpio — enmarca
     la escena y de paso asienta el texto sin tener que subir el velo. */
  background-image:
    radial-gradient(ellipse at 50% 44%, rgba(18, 16, 13, 0) 38%, rgba(18, 16, 13, 0.55) 100%),
    linear-gradient(180deg, rgba(30, 27, 22, 0.4) 0%, rgba(30, 27, 22, 0.52) 55%, rgba(30, 27, 22, 0.62) 100%),
    url('/img/hero-landing.webp');
  background-size: cover, cover, cover;
  /* 20%: encuadra la franja oscura y calmada de arriba (pared y novia
     desenfocada) justo detras del texto, y deja el ramo llenando la mitad
     de abajo. Es la zona de la foto donde el texto se lee sin pelear. */
  background-position: center, center, center 20%;
  background-repeat: no-repeat;
  color: var(--landing-cream);
}

/* Parallax: la foto queda anclada a la ventana y el contenido pasa por encima.
   Solo en escritorio con puntero — 'fixed' esta roto o va a tirones en Safari
   de iOS y en varios navegadores moviles, y ahi esta la mayoria del trafico.
   Las dos capas de degradado siguen en 'scroll' para que se peguen al hero
   y no a la ventana. */
@media (min-width: 901px) and (hover: hover) {
  .hero {
    background-attachment: scroll, scroll, fixed;
  }
}

.hero .eyebrow {
  color: var(--landing-blush);
  font-size: 0.74rem;
  font-weight: 500;
  margin-bottom: 1.6rem;
  opacity: 0;
  animation: fadeInUp 0.9s ease 0.1s forwards;
}

.hero h1 {
  font-size: clamp(2.3rem, 6vw, 3.9rem);
  line-height: 1.2;
  max-width: 16ch;
  text-wrap: balance;
  margin-bottom: 1.85rem;
  opacity: 0;
  animation: fadeInUp 1s ease 0.25s forwards;
}

.hero .subtitle {
  font-size: 1rem;
  line-height: 1.85;
  color: var(--landing-cream);
  opacity: 0;
  max-width: 42ch;
  margin: 0 auto;
  animation: fadeInUp 1.1s ease 0.4s forwards;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero .eyebrow,
  .hero h1,
  .hero .subtitle {
    animation: none;
    opacity: 1;
  }
}

/* ---------- Tarifas (antes ".catalog" — el catalogo real ahora son los
   6 estilos de abajo; ".section-title"/"h2" quedan compartidos entre
   ambas secciones para no duplicar el mismo look de eyebrow+titulo) ---------- */
.pricing,
.style-gallery {
  max-width: 1120px;
  margin: 0 auto;
  padding: 6rem 1.5rem 8rem;
  text-align: center;
}

.pricing .section-title,
.style-gallery .section-title {
  display: block;
  color: var(--landing-accent);
  font-size: 0.74rem;
  font-weight: 500;
  margin-bottom: 1.1rem;
}

.pricing h2,
.style-gallery h2 {
  font-size: clamp(1.7rem, 3vw, 2.2rem);
  margin-bottom: 0.85rem;
}

.pricing-note {
  font-size: 0.92rem;
  color: var(--landing-ink-soft);
  margin: 0 0 4.5rem;
}

/* ---------- Escaparate de 6 estilos (V1.7) ---------- */
.gallery-note {
  font-size: 0.92rem;
  color: var(--landing-ink-soft);
  margin: 0 0 3.5rem;
}

.phones-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1.75rem 1.25rem;
}

@media (max-width: 900px) {
  .phones-grid {
    grid-template-columns: repeat(3, 1fr);
    row-gap: 3rem;
  }
}

@media (max-width: 480px) {
  .phones-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.phone-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
}

/* ---------- Efectos del escaparate (2026-07-24) ----------
   Tres transformaciones, cada una en su propio elemento (transform es una
   sola propiedad — si compartieran elemento se pisarian entre si):
     .phone-item   -> entrada al entrar en pantalla (una sola vez)
     .phones-grid  -> deriva de parallax al hacer scroll (la rejilla ENTERA,
                      no cada telefono: la primera version movia pares e
                      impares en sentidos opuestos y los telefonos quedaban
                      desalineados entre si — decision del PO 2026-07-24)
     .phone-mockup -> levantamiento y zoom al pasar el cursor */

/* 1. Entrada: aparecen subiendo, escalonadas de izquierda a derecha.
   Todo el estado oculto vive dentro de (scripting: enabled) a proposito.
   Es quien devuelve la clase .is-visible; si el JS no corre, estas reglas
   ni se aplican y los telefonos se ven de siempre, sin animacion. Un
   navegador que no conozca la consulta tambien las ignora, que es
   exactamente el fallo que queremos. Se resuelve aqui y no con un script
   en linea porque la CSP de Helmet bloquea los scripts en linea. */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  .phone-item {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.85s ease, transform 0.85s cubic-bezier(0.22, 0.61, 0.36, 1);
  }

  .phone-item.is-visible {
    opacity: 1;
    transform: translateY(0);
  }

  .phone-item:nth-child(2) { transition-delay: 0.09s; }
  .phone-item:nth-child(3) { transition-delay: 0.18s; }
  .phone-item:nth-child(4) { transition-delay: 0.27s; }
  .phone-item:nth-child(5) { transition-delay: 0.36s; }
  .phone-item:nth-child(6) { transition-delay: 0.45s; }
}

/* 2. Parallax: la rejilla completa deriva unos pixeles mas lento que el
   resto de la pagina mientras pasa el scroll — profundidad sin desalinear
   los telefonos entre si. Se apoya en animation-timeline, que corre en el
   compositor sin escuchar el evento de scroll — con 6 iframes vivos, un
   listener de scroll seria justo lo que hace que una pagina se sienta
   pesada. Donde no exista la propiedad simplemente no pasa nada. */
@supports (animation-timeline: view()) {
  @media (min-width: 901px) and (prefers-reduced-motion: no-preference) {
    .phones-grid {
      animation: derivaEscaparate linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
  }
}

@keyframes derivaEscaparate {
  from { transform: translateY(36px); }
  to { transform: translateY(-36px); }
}

/* 3. Zoom al pasar el cursor. Solo con puntero real: en tactil el :hover se
   queda pegado despues del tap y el telefono se quedaria agrandado. */
@media (hover: hover) {
  .phone-mockup {
    transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1), box-shadow 0.5s ease;
  }

  .phone-item:hover .phone-mockup {
    transform: scale(1.05);
    box-shadow:
      0 2px 4px rgba(42, 38, 32, 0.1),
      0 18px 34px rgba(42, 38, 32, 0.16),
      0 40px 74px rgba(42, 38, 32, 0.2);
  }
}

/* Marco de iPhone 100% CSS: bisel oscuro + notch, sin imagenes. El
   overflow:hidden + border-radius del bisel recorta el iframe (elemento
   reemplazado) en las esquinas igual que recortaria una imagen. */
.phone-mockup {
  display: block;
  position: relative;
  box-sizing: border-box;
  width: 100%;
  max-width: 165px;
  aspect-ratio: 9 / 19.5;
  background: #14120F;
  border-radius: 1.6rem;
  padding: 8px;
  box-shadow:
    0 1px 2px rgba(42, 38, 32, 0.08),
    0 12px 24px rgba(42, 38, 32, 0.12),
    0 28px 56px rgba(42, 38, 32, 0.14);
  overflow: hidden;
  cursor: pointer;
}

.phone-notch {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 38%;
  height: 16px;
  background: #14120F;
  border-radius: 0 0 10px 10px;
  z-index: 2;
}

.phone-mockup iframe {
  position: relative;
  width: 100%;
  height: 100%;
  border: none;
  border-radius: 1.05rem;
  display: block;
  /* Sin scrollbars nativas dentro del mockup: el fix real vive en el
     documento interior (.is-escaparate en event.css); esto es refuerzo
     a nivel del propio elemento iframe. */
  overflow: hidden;
  /* Decorativa: el clic real vive en .phone-mockup (ahora es el <a> que
     envuelve este iframe). Sin esto, un scroll o tap accidental dejaria
     ver contenido debajo del Hero (100vh). */
  pointer-events: none;
}

.btn-style {
  font-size: 0.66rem;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--landing-ink-soft);
  text-decoration: none;
  border: 1px solid var(--landing-hairline);
  border-radius: 999px;
  padding: 0.45rem 1rem;
  transition: all 0.4s ease;
}

.btn-style:hover {
  color: var(--landing-accent);
  border-color: var(--landing-accent);
}

.cards-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2.5rem;
  text-align: left;
}

.tier-card {
  display: flex;
  flex-direction: column;
  background: var(--landing-card-bg);
  border: 1px solid var(--landing-hairline);
  border-radius: 2px;
  overflow: hidden;
  transition: all 0.4s ease;
}

.tier-card:hover {
  border-color: var(--landing-accent);
  box-shadow: 0 6px 22px rgba(42, 38, 32, 0.09);
  transform: translateY(-3px);
}

/* Captura horizontal real de cada plantilla (src/constants/catalog.js
   define la ruta por nivel, inyectada inline desde index.ejs). El color
   de fondo es solo un respaldo por si una imagen no carga. aspect-ratio
   en vez de altura fija: escala limpio en cualquier ancho de tarjeta,
   en movil y en desktop, sin necesitar media queries aparte. El
   micro-zoom al hover se recorta gracias al overflow:hidden de
   .tier-card (arriba). */
.card-preview-placeholder {
  display: block;
  aspect-ratio: 16 / 9;
  background-color: var(--landing-blush);
  background-size: cover;
  background-position: center;
  border-bottom: 1px solid var(--landing-hairline);
  transition: transform 0.6s ease;
  cursor: pointer;
}

.tier-card:hover .card-preview-placeholder {
  transform: scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .card-preview-placeholder {
    transition: none;
  }

  .tier-card:hover .card-preview-placeholder {
    transform: none;
  }
}

.card-content {
  padding: 2.5rem 2.25rem 2.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  flex-grow: 1;
}

.tier-card h3 {
  font-style: italic;
  font-size: 1.65rem;
  text-align: center;
}

.tier-desc {
  font-size: 0.86rem;
  line-height: 1.6;
  color: var(--landing-ink-soft);
  text-align: center;
  min-height: 2.6em;
  margin: 0 0 0.5rem;
}

.price {
  font-family: var(--font-display);
  font-size: 2.6rem;
  text-align: center;
  margin: 0.5rem 0 2.25rem;
  font-variant-numeric: tabular-nums;
}

.currency {
  font-family: var(--font-sans);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--landing-ink-soft);
}

.features-list {
  list-style: none;
  padding: 1.85rem 0 0;
  margin: 0 0 2.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  flex-grow: 1;
  border-top: 1px solid var(--landing-hairline);
}

.features-list li {
  font-size: 0.88rem;
  line-height: 1.6;
  padding-left: 1.4rem;
  position: relative;
}

.features-list li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: var(--landing-ink-soft);
}

.btn-whatsapp {
  display: block;
  width: 100%;
  border: none;
  cursor: pointer;
  background: var(--landing-accent);
  color: var(--landing-card-bg);
  padding: 0.95rem 1.5rem;
  font-size: 0.74rem;
  font-weight: 500;
  transition: all 0.4s ease;
}

.tier-card:hover .btn-whatsapp {
  background: var(--landing-ink);
  letter-spacing: 0.2em;
}

.btn-preview {
  display: block;
  text-align: center;
  font-size: 0.68rem;
  color: var(--landing-ink-soft);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  margin: 0.85rem auto 0;
  width: fit-content;
  transition: all 0.4s ease;
}

.btn-preview:hover {
  color: var(--landing-accent);
  border-bottom-color: var(--landing-accent);
}

/* ---------- Pie de pagina ---------- */
footer {
  border-top: 1px solid var(--landing-hairline);
  text-align: center;
  padding: 2.75rem 1.5rem;
  font-size: 0.78rem;
  color: var(--landing-ink-soft);
}

footer p {
  margin: 0 0 0.75rem;
}

.footer-links a {
  font-size: 0.7rem;
  color: var(--landing-ink-soft);
  text-decoration: none;
  transition: all 0.4s ease;
}

.footer-links a:hover {
  color: var(--landing-accent);
}

/* ---------- Responsive: movil ---------- */
@media (max-width: 640px) {
  /* El header es position:absolute (flota sobre la foto) sin alto propio;
     en pantallas angostas el logo y el boton de login competian por el
     mismo ancho y terminaban superpuestos. Se envuelven en 2 lineas con
     espacio propio en vez de solaparse. */
  .landing-header {
    flex-wrap: wrap;
    row-gap: 0.75rem;
  }

  .landing-header .logo {
    font-size: 1.2rem;
  }

  .landing-header .btn-login-envolvente {
    font-size: 0.62rem;
    padding: 0.55rem 1rem;
  }

  .hero {
    min-height: 74vh;
    /* Con el header envuelto en 2 lineas (logo + boton), el contenido
       centrado del Hero necesita este respiro arriba para no meterse
       debajo del boton de login. */
    padding-top: 6.5rem;
    /* Recorte vertical propio: la version de escritorio es apaisada y en una
       pantalla de telefono 'cover' se comeria dos tercios del ancho. */
    background-image:
      radial-gradient(ellipse at 50% 44%, rgba(18, 16, 13, 0) 38%, rgba(18, 16, 13, 0.55) 100%),
      linear-gradient(180deg, rgba(30, 27, 22, 0.4) 0%, rgba(30, 27, 22, 0.52) 55%, rgba(30, 27, 22, 0.62) 100%),
      url('/img/hero-landing-movil.webp');
    /* El recorte 3:4 es mas alto que el hueco del hero, asi que aqui apenas
       se recorta en vertical: se ve la foto casi completa. */
    background-position: center, center, center;
  }

  .hero h1 {
    max-width: 100%;
  }

  .pricing,
  .style-gallery {
    padding: 4rem 1.25rem 5rem;
  }

  .card-content {
    padding: 2rem 1.75rem 1.85rem;
  }
}

/* ---------- Invitación finalizada (2026-07-25) ----------
   Pantalla que ve quien abre una invitación ya archivada. Es marketing:
   viene de una boda real y acaba de ver el producto funcionando.
   Reutiliza el vocabulario de la landing (.eyebrow, .accent-italic,
   .btn-whatsapp, footer) para que se sienta la misma marca. */
.finalizada-hero {
  position: relative;
  min-height: 62vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 4rem 1.5rem;
  background-image:
    linear-gradient(180deg, rgba(30, 27, 22, 0.55) 0%, rgba(30, 27, 22, 0.72) 100%),
    url('/img/hero-landing.webp');
  background-size: cover;
  background-position: center 30%;
  color: var(--landing-cream);
}

.finalizada-logo {
  height: 2.4rem;
  width: auto;
  margin-bottom: 2rem;
}

.finalizada-oferta {
  max-width: 900px;
  margin: 0 auto;
  padding: 5rem 1.5rem 4rem;
  text-align: center;
}

.finalizada-servicios {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2rem;
  margin: 3rem 0 3.25rem;
}

.finalizada-servicio {
  flex: 1 1 300px;
  max-width: 400px;
  text-align: left;
  padding: 2rem 1.75rem;
  border: 1px solid var(--landing-hairline, rgba(42, 38, 32, 0.14));
  background: rgba(255, 255, 255, 0.5);
}

.finalizada-servicio h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.35rem;
  margin: 0 0 0.75rem;
}

.finalizada-servicio p {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.8;
}

.finalizada-vermas {
  margin-top: 2rem;
  font-size: 0.85rem;
}

@media (max-width: 640px) {
  .finalizada-hero {
    min-height: 56vh;
    padding: 3rem 1.25rem;
  }

  .finalizada-oferta {
    padding: 3.5rem 1.25rem 3rem;
  }

  .finalizada-servicios {
    margin: 2.25rem 0 2.5rem;
  }
}
