/* ==========================================================================
   Go Stays Premium — Landing de campaña "Villa Castellana VIP"
   (landing-castellana.php / URL limpia: /castellana-vip)

   Hoja de estilos DEDICADA y autocontenida: la landing no carga
   public/css/style.css a propósito. El tráfico de Meta Ads llega en 4G y
   cada KB cuesta conversión, así que aquí solo vive lo que esta página
   usa. Los tokens replican el Design System (Playfair + Inter, dorado
   #c9a86a, rojo #bc1622) para que la marca se vea idéntica, pero en
   modo oscuro permanente: no hay tema claro en esta vista.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,500;0,600;0,700;1,500;1,600&family=Inter:wght@300;400;500;600;700&display=swap');

:root {
  --cast-black: #08080a;
  --cast-ink: #0b0b0c;
  --cast-charcoal: #131316;
  --cast-white: #ffffff;

  --cast-gold: #c9a86a;
  --cast-gold-bright: #e0c58c;
  --cast-red: #bc1622;

  --cast-text: rgba(255, 255, 255, 0.9);
  --cast-text-muted: rgba(255, 255, 255, 0.6);
  --cast-hairline: rgba(255, 255, 255, 0.12);

  --cast-font-display: 'Playfair Display', Georgia, serif;
  --cast-font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;

  --cast-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --cast-duration: 0.6s;

  --cast-container: 1180px;

  /* Borde izquierdo de composición: coincide con el gutter del contenedor,
     así los elementos posicionados en absoluto (firma, indicador de scroll)
     se alinean con el texto en vez de flotar sueltos. */
  --cast-edge: max(1.25rem, calc((100% - var(--cast-container)) / 2));
}

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

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

body.cast-page {
  margin: 0;
  background: var(--cast-ink);
  color: var(--cast-text);
  font-family: var(--cast-font-body);
  font-weight: 300;
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img {
  max-width: 100%;
  display: block;
}

h1, h2, h3 {
  font-family: var(--cast-font-display);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.01em;
  color: var(--cast-white);
  margin: 0;
}

.cast-container {
  width: min(100% - 2.5rem, var(--cast-container));
  margin-inline: auto;
}

/* Firma de marca — texto plano, sin enlace: nada saca al usuario de aquí.
   Alineada al mismo borde izquierdo que el hero y las secciones (--cast-edge):
   una sola línea vertical de composición en toda la página. */
.cast-brandmark {
  position: absolute;
  top: 1.6rem;
  left: var(--cast-edge);
  z-index: 5;
  margin: 0;
  font-family: var(--cast-font-body);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.36em;
  color: rgba(255, 255, 255, 0.82);
  text-transform: uppercase;
}

.cast-brandmark span {
  color: var(--cast-gold);
}

/* ========================= Video de fondo (pegajoso) ======================= */

/* El lienzo de toda la experiencia: un único video que se queda pegado al
   viewport durante TODO el scroll. Nunca se mueve — son las secciones de
   contenido las que pasan por encima, en flujo normal del documento. Por
   eso z-index: -1 basta: en el stacking context raíz, el fondo de <body>
   se pinta primero, este lienzo negativo justo encima, y cualquier
   sección normal (z-index: auto) siempre queda por delante, sin necesidad
   de subir el z-index del contenido. */
.cast-video-fixed {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: -1;
  overflow: hidden;
  background: var(--cast-black);
}

.cast-bg-video,
.cast-bg-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Video 1080x1920 (9:16): en móvil, pantalla vertical, `cover` ya encuadra
   la propiedad sin drama. En escritorio el mismo `cover` recorta arriba y
   abajo del plano — se compensa con .cast-video-vignette, no peleando
   contra el recorte sino abrazándolo.

   Sin animación de scale ni transiciones: el Ken Burns anterior generaba
   temblor/jittering visual al pelear con el compositor del navegador
   durante la reproducción. En su lugar, estas tres reglas fuerzan un
   layer de GPU estable para el video (composición por hardware, sin
   reflow ni repintado por frame). */
.cast-bg-video {
  object-fit: cover;
  object-position: center;
  background: transparent;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;
}

.cast-bg-media {
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* --------------------------- Viñeta de escritorio ---------------------------
   Un video vertical en una pantalla ancha dejará siempre franjas de sobra
   fuera del punto focal. En vez de un velo uniforme, un viñeteado radial
   funde los bordes con el negro del layout y centra el ojo en la propiedad
   — sin oscurecer el centro, que es justamente lo que la Sección 1 no
   puede permitirse. Solo aplica desde tablet: en móvil el 9:16 del video
   ya calza con la pantalla y no hace falta. */
.cast-video-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

@media (min-width: 900px) {
  .cast-video-vignette {
    background: radial-gradient(ellipse 60% 68% at 50% 48%, transparent 42%, rgba(6, 6, 8, 0.5) 78%, rgba(6, 6, 8, 0.92) 100%);
    box-shadow: inset 0 0 16vw 3vw rgba(6, 6, 8, 0.85);
  }
}

/* ================================== Hero ================================== */

/* Sección 1 (100vh): el "hook" inicial vive aquí, centrado sobre el video,
   para que nadie dude en el primer segundo de qué trata la página. Sin velo
   oscuro pesado: el contraste lo sostiene el text-shadow del título y un
   degradé radial sutil detrás del bloque de texto (ver .cast-hero-hook),
   dejando los bordes del video completamente limpios. La firma de marca
   (fuera de este bloque, ver .cast-brandmark) y el indicador de scroll
   completan la vista. */
.cast-hero-clean {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(6rem, 16vh, 9rem) var(--cast-edge) clamp(2rem, 6vh, 3.5rem);
  text-align: center;
}

/* Bloque de gancho inicial (badge + H1): centrado vertical y horizontalmente
   en el viewport, por delante del video. El ::before es el único "velo": un
   degradé radial transparente y contenido al tamaño del propio bloque de
   texto, no de la pantalla completa, así el video sigue limpio en los bordes. */
.cast-hero-hook {
  position: relative;
  z-index: 1;
  max-width: 740px;
  padding: clamp(1.75rem, 5vw, 3rem);
}

.cast-hero-hook::before {
  content: '';
  position: absolute;
  inset: -15% -8%;
  z-index: -1;
  background: radial-gradient(ellipse 62% 62% at 50% 50%, rgba(4, 4, 6, 0.4), transparent 72%);
  pointer-events: none;
}

.cast-scroll-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(1.5rem, 5vh, 3rem);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
}

.cast-scroll-cue-line {
  width: 1px;
  height: 46px;
  transform-origin: top;
  background: linear-gradient(180deg, var(--cast-gold), transparent);
  animation: cast-cue-grow 2.6s var(--cast-ease) infinite;
}

.cast-scroll-cue-label {
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}

@keyframes cast-cue-grow {
  0%, 100% { transform: scaleY(0.4); opacity: 0.3; }
  50%      { transform: scaleY(1);   opacity: 0.85; }
}

/* Columna de texto de la Sección 2 (Fase de Inmersión → Contenido): nunca
   cruza el ancho completo del panel de cristal. Una línea de 650px se lee
   de una sola pasada; una de 1180px obliga al ojo a volver a empezar. */
.cast-hero-copy {
  max-width: 650px;
}

/* Badge: el dato de contexto (dónde y bajo qué condición) antes de la
   promesa, como una píldora de Dark Glassmorphism en vez de una simple
   línea de texto — borde sutil dorado + superficie translúcida. */
.hero-badge {
  display: inline-block;
  margin: 0 0 1.15rem;
  padding: 0.5rem 1.05rem;
  border-radius: 999px;
  border: 1px solid rgba(201, 168, 106, 0.4);
  background: rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  font-family: var(--cast-font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--cast-gold-bright);
}

.cast-hero-title {
  font-size: clamp(2.4rem, 5.6vw, 4.1rem);
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: #ffffff;
  /* Sombra pronunciada: es lo que sostiene la legibilidad del H1 sobre el
     video sin recurrir a un fondo negro pesado que lo tape. */
  text-shadow: 0px 4px 20px rgba(0, 0, 0, 0.8);
}

.gold-accent {
  color: var(--cast-gold-bright);
  font-style: italic;
}

.cast-hero-subtitle {
  margin: 1.5rem 0 0;
  max-width: 54ch;
  font-family: var(--cast-font-body);
  font-size: clamp(1rem, 1.5vw, 1.12rem);
  font-weight: 300;
  line-height: 1.7;
  color: #ebebeb;
  text-shadow: 0 1px 18px rgba(0, 0, 0, 0.45);
}

.cast-hero-note {
  margin: 1.15rem 0 0;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.6);
}

/* --------------------------- Ancla de precio ------------------------------
   Tarjeta entre el subtítulo y el CTA: el valor de referencia tachado ancla
   la percepción antes de mostrar la tarifa real, así $17.000.000 se lee como
   oferta y no como el número más alto que el visitante vio en la página.

   Es la misma familia visual del Dark Glassmorphism que .cast-pillar y
   .cast-close-card (borde en degradé oro→rojo sobre superficie translúcida),
   pero con MÁS opacidad de fondo (0.5 vs. 0.045): esas tarjetas viven sobre
   secciones de fondo sólido oscuro; esta vive sobre una fotografía, así que
   necesita sostener su propio contraste sin depender solo de lo que haya
   detrás. El monto se destaca en dorado (no en rojo): un precio en rojo
   sobre fondo oscuro lee como oferta de supermercado, no como lujo.
   -------------------------------------------------------------------------- */
.cast-price-card {
  position: relative;
  display: inline-block;
  margin: 1.6rem 0 1.9rem;
  padding: 1.15rem 1.5rem;
  max-width: 100%;
  border-radius: 16px;
  background: rgba(10, 10, 12, 0.5);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid transparent;
  background-clip: padding-box;
}

.cast-price-card::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, var(--cast-gold) 0%, rgba(201, 168, 106, 0.2) 45%, rgba(188, 22, 34, 0.4) 80%, var(--cast-red) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

.price-commercial {
  display: block;
  margin: 0;
  font-size: 0.82rem;
  font-weight: 400;
  /* Medido, no estimado: a 0.58 de opacidad este texto quedaba en 3.49:1
     sobre la tarjeta (AA exige 4.5 para texto normal). Es información real
     (el precio de referencia), no un adorno, así que no hay excepción de
     WCAG por ser "letra pequeña deliberadamente discreta". */
  color: rgba(255, 255, 255, 0.78);
  text-decoration-color: rgba(188, 22, 34, 0.85);
  text-decoration-thickness: 1.5px;
}

.price-vip {
  margin: 0.5rem 0 0;
  font-family: var(--cast-font-display);
  font-size: clamp(1.35rem, 2.8vw, 1.75rem);
  font-weight: 700;
  color: var(--cast-gold-bright);
  text-shadow: 0 2px 20px rgba(201, 168, 106, 0.3);
}

.price-note {
  display: block;
  margin: 0.7rem 0 0;
  max-width: 44ch;
  font-size: 0.78rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.52);
}

@media (max-width: 480px) {
  .cast-price-card {
    display: block;
  }
}

/* -------------------------- Compactación de mobile -------------------------
   El H1 largo + la tarjeta de precio dejaban demasiado aire vertical entre
   bloques en los móviles de referencia (iPhone 13/14). Este bloque aprieta
   el ritmo SIN quitar ni acortar ningún texto — mismo contenido, más denso. */
@media (max-width: 767px) {
  .cast-intro-section {
    padding-block: 4.25rem 3.5rem;
  }

  .hero-badge {
    /* Mismo motivo que el kicker anterior: por debajo de ~400px de ancho el
       texto envolvía a 2 líneas y rompía la píldora. Se acorta el tracking y
       baja el tamaño para que quepa en una sola línea. */
    margin-bottom: 0.8rem;
    padding: 0.42rem 0.85rem;
    font-size: 0.62rem;
    letter-spacing: 1px;
  }

  .cast-hero-title {
    font-size: clamp(2rem, 8.6vw, 2.6rem);
  }

  /* El párrafo es el bloque más largo del hero (39 palabras, aprobadas tal
     cual por el negocio: no se acortan). A 375-390px de ancho corre en 6-7
     líneas, así que un ajuste fino de tamaño/interlineado aquí vale más para
     recuperar el pliegue que apretar cualquier otro elemento. Sigue siendo
     texto de cuerpo perfectamente legible (15px/1.5). */
  .cast-hero-subtitle {
    margin-top: 1rem;
    font-size: 0.94rem;
    line-height: 1.5;
  }

  .cast-price-card {
    margin: 1rem 0 1.1rem;
    padding: 0.8rem 1.1rem 0.9rem;
  }

  .price-vip {
    margin-top: 0.35rem;
    font-size: 1.2rem;
  }

  .price-note {
    margin-top: 0.5rem;
  }

  .cast-hero-note {
    margin-top: 0.75rem;
  }
}

/* =============================== CTA WhatsApp ============================== */

.cast-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  padding: 1.1rem 2rem;
  border-radius: 999px;
  border: 1px solid var(--cast-gold);
  /* El degradé es más ancho que el botón: al hacer hover se desplaza y el
     brillo del oro barre la superficie. Es el "hover sutil" — luz que se
     mueve, no un cambio de color. */
  background: linear-gradient(115deg, #b18f4f 0%, var(--cast-gold) 26%, var(--cast-gold-bright) 50%, var(--cast-gold) 74%, #b18f4f 100%);
  background-size: 230% 100%;
  background-position: 76% 50%;
  color: #14100a;
  font-family: var(--cast-font-body);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.25;
  text-decoration: none;
  text-align: left;
  box-shadow: 0 18px 44px -18px rgba(201, 168, 106, 0.75);
  transition:
    transform var(--cast-duration) var(--cast-ease),
    box-shadow var(--cast-duration) var(--cast-ease),
    background-position 0.9s var(--cast-ease);
}

.cast-cta svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  fill: currentColor;
}

.cast-cta:hover,
.cast-cta:focus-visible {
  transform: translateY(-2px);
  background-position: 20% 50%;
  box-shadow: 0 24px 56px -18px rgba(201, 168, 106, 0.9);
}

.cast-cta:focus-visible {
  outline: 2px solid var(--cast-white);
  outline-offset: 3px;
}

.cast-cta--hero {
  /* Antes de la tarjeta de precio este margen separaba el CTA de un simple
     párrafo y necesitaba más aire. Ahora lo precede una tarjeta con borde
     propio — ya es una separación visual fuerte — así que el margen baja
     para no acumular espacio muerto encima del botón más importante de la
     página. */
  margin-top: 1.5rem;
}

@media (max-width: 767px) {
  .cast-cta--hero {
    margin-top: 1.1rem;
  }

  /* Botones finales de contacto (hero + cierre): a todo el ancho con padding
     amplio y más aire entre ícono y texto, para que no se vean apretados
     junto al resto del copy en móvil. */
  .cast-cta--hero,
  .cast-cta--close {
    width: 100%;
    padding: 1.15rem 1.5rem;
    gap: 15px;
  }
}

/* --------------------------- CTA flotante (sticky) ------------------------- */

.cast-sticky-cta {
  position: fixed;
  z-index: 40;
  bottom: max(1.1rem, env(safe-area-inset-bottom));
  left: 50%;
  width: min(100% - 1.6rem, 560px);
  transform: translate(-50%, 130%);
  transition: transform 0.55s var(--cast-ease), opacity 0.35s linear;
  opacity: 0;
  pointer-events: none;
}

.cast-sticky-cta.is-visible {
  transform: translate(-50%, 0);
  opacity: 1;
  pointer-events: auto;
}

.cast-cta--sticky {
  width: 100%;
  padding: 1rem 1.4rem;
  font-size: 0.98rem;
  text-align: center;
}

/* El copy completo del CTA se mantiene en todos los tamaños (es el mensaje
   que el cliente aprobó para la campaña); en el píldora flotante se permite
   que ocupe dos líneas. Solo por debajo de 360px —donde dos líneas se
   vuelven cuatro— se cae a la versión corta. */
.cast-cta-short { display: none; }

@media (max-width: 359px) {
  .cast-cta-long { display: none; }
  .cast-cta-short { display: inline; }
}

/* ============================== Secciones base ============================= */

.cast-section {
  padding-block: clamp(4.5rem, 11vw, 8rem);
}

/* --------------------------- Fase de Contenido ------------------------------
   A partir de aquí el video pegajoso deja de verse limpio: cada sección de
   contenido es un panel de cristal oscuro que, al subir por scroll, tapa y
   desenfoca instantáneamente el lienzo fijo detrás — sin necesidad de tocar
   el video, solo de estar en el flujo normal del documento por encima de él
   (ver .cast-video-fixed). Esto le da 100% de contraste al texto mientras el
   video sigue "respirando" como fondo tras el cristal. */
.cast-intro-section,
.cast-pillars-section,
.cast-gallery-section,
.cast-close-section {
  position: relative;
  background: rgba(10, 10, 10, 0.6);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
}

.cast-section-eyebrow {
  margin: 0 0 0.9rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--cast-gold);
}

.cast-section-title {
  font-size: clamp(1.9rem, 4.4vw, 3rem);
  max-width: 18ch;
}

.cast-section-lede {
  margin: 1.1rem 0 0;
  max-width: 52ch;
  color: var(--cast-text-muted);
  font-size: 1.02rem;
}

/* Hilo dorado que separa bloques sin romper el fondo oscuro. */
.cast-pillars-section,
.cast-gallery-section {
  position: relative;
}

.cast-pillars-section::before,
.cast-gallery-section::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(100% - 2.5rem, var(--cast-container));
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--cast-hairline) 20%, rgba(201, 168, 106, 0.5) 50%, var(--cast-hairline) 80%, transparent);
}

/* ============================== 3 Pilares ================================= */

.cast-pillars {
  list-style: none;
  margin: clamp(2.5rem, 6vw, 4rem) 0 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
  grid-template-columns: 1fr;
}

@media (min-width: 860px) {
  .cast-pillars {
    grid-template-columns: repeat(3, 1fr);
    gap: 1.5rem;
  }
}

/* Dark Glassmorphism: superficie translúcida + borde degradé oro→rojo,
   el mismo lenguaje de la tarjeta "Conecta con Nosotros" de about.html. */
.cast-pillar {
  position: relative;
  padding: clamp(1.8rem, 3.4vw, 2.4rem);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.045);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border: 1px solid transparent;
  background-clip: padding-box;
  transition: transform var(--cast-duration) var(--cast-ease), background var(--cast-duration) var(--cast-ease);
}

.cast-pillar::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, var(--cast-gold) 0%, rgba(201, 168, 106, 0.15) 35%, rgba(188, 22, 34, 0.35) 70%, var(--cast-red) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

.cast-pillar:hover {
  transform: translateY(-4px);
  background: rgba(255, 255, 255, 0.065);
}

.cast-pillar-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid rgba(201, 168, 106, 0.4);
  background: rgba(201, 168, 106, 0.09);
  color: var(--cast-gold);
}

.cast-pillar-icon svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cast-pillar-title {
  margin: 1.3rem 0 0.6rem;
  font-size: 1.4rem;
}

.cast-pillar-copy {
  margin: 0;
  color: var(--cast-text-muted);
  font-size: 0.97rem;
}

/* =============================== Galería ================================== */

.cast-gallery-section {
  background:
    radial-gradient(80% 55% at 12% 0%, rgba(201, 168, 106, 0.09), transparent 60%),
    radial-gradient(70% 50% at 92% 100%, rgba(188, 22, 34, 0.1), transparent 58%),
    rgba(10, 10, 10, 0.6);
}

/* Masonry con columnas CSS puras (sin librería), igual que The Journal. */
.cast-gallery {
  margin-top: clamp(2.5rem, 6vw, 3.5rem);
  column-count: 1;
  column-gap: 1.1rem;
}

@media (min-width: 640px) {
  .cast-gallery { column-count: 2; }
}

@media (min-width: 1024px) {
  .cast-gallery { column-count: 3; column-gap: 1.4rem; }
}

.cast-shot {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  margin: 0 0 1.1rem;
  border: 1px solid var(--cast-hairline);
  border-radius: 16px;
  overflow: hidden;
  break-inside: avoid;
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  cursor: zoom-in;
  transition:
    transform var(--cast-duration) var(--cast-ease),
    border-color var(--cast-duration) var(--cast-ease),
    box-shadow var(--cast-duration) var(--cast-ease);
}

@media (min-width: 1024px) {
  .cast-shot { margin-bottom: 1.4rem; }
}

.cast-shot img {
  width: 100%;
  height: auto;
  transition: transform 0.9s var(--cast-ease), filter var(--cast-duration) var(--cast-ease);
  filter: saturate(0.95);
}

/* Velo oscuro permanente que se disuelve al hover: da unidad cromática a
   fotos tomadas con luces distintas y evita que la grilla se vea "suelta". */
.cast-shot-glow {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 8, 10, 0.05) 0%, rgba(8, 8, 10, 0.42) 100%);
  transition: opacity var(--cast-duration) var(--cast-ease);
  pointer-events: none;
}

.cast-shot:hover,
.cast-shot:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(201, 168, 106, 0.55);
  box-shadow: 0 26px 60px -30px rgba(0, 0, 0, 0.9);
}

.cast-shot:focus-visible {
  outline: 2px solid var(--cast-gold);
  outline-offset: 3px;
}

.cast-shot:hover img,
.cast-shot:focus-visible img {
  transform: scale(1.045);
  filter: saturate(1.05);
}

.cast-shot:hover .cast-shot-glow,
.cast-shot:focus-visible .cast-shot-glow {
  opacity: 0.35;
}

/* ============================ Cierre / Contacto =========================== */

.cast-close-section {
  background:
    radial-gradient(90% 70% at 50% 0%, rgba(188, 22, 34, 0.14), transparent 62%),
    rgba(10, 10, 10, 0.6);
}

.cast-close-card {
  max-width: 820px;
  margin-inline: auto;
  padding: clamp(2.2rem, 6vw, 3.6rem);
  text-align: center;
  position: relative;
  border-radius: 24px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.045);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  background-clip: padding-box;
}

.cast-close-card::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, var(--cast-gold) 0%, rgba(201, 168, 106, 0.15) 35%, rgba(188, 22, 34, 0.35) 70%, var(--cast-red) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

.cast-close-card .cast-section-eyebrow {
  color: var(--cast-red);
  filter: brightness(1.5);
}

.cast-close-title {
  font-size: clamp(1.9rem, 4.6vw, 3rem);
  font-style: italic;
  font-weight: 500;
}

.cast-close-copy {
  margin: 1.3rem auto 0;
  max-width: 56ch;
  color: var(--cast-text-muted);
}

.cast-cta--close {
  margin-top: 2.2rem;
  padding: 1.25rem 2.4rem;
  font-size: 1.05rem;
}

.cast-close-note {
  margin: 1.1rem 0 0;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.45);
}

/* ================================= Footer ================================= */

.cast-footer {
  padding: 2.2rem 1.25rem calc(6.5rem + env(safe-area-inset-bottom));
  text-align: center;
  border-top: 1px solid var(--cast-hairline);
  background: var(--cast-black);
}

.cast-footer p {
  margin: 0;
  font-size: 0.76rem;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.38);
}

/* ================================ Lightbox ================================ */

/* `display: flex` gana sobre la regla de UA `[hidden] { display: none }`, así
   que el overlay debe apagarse explícitamente: si no, el lightbox cerrado
   queda ocupando toda la pantalla y se traga los clics del CTA de WhatsApp
   (mismo patrón que .lightbox-overlay en el Design System). */
.cast-lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(6, 6, 8, 0.94);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  transition: opacity 0.35s var(--cast-ease);
}

.cast-lightbox:not([hidden]) {
  display: flex;
}

.cast-lightbox.is-visible {
  opacity: 1;
}

.cast-lightbox-stage {
  width: min(92vw, 1200px);
  height: min(82vh, 900px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.cast-lightbox-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 6px;
  opacity: 0;
  transition: opacity 0.35s var(--cast-ease);
}

.cast-lightbox-image.is-loaded {
  opacity: 1;
}

.cast-lightbox-close,
.cast-lightbox-nav {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.06);
  color: var(--cast-white);
  cursor: pointer;
  transition: border-color var(--cast-duration) var(--cast-ease), background var(--cast-duration) var(--cast-ease);
}

.cast-lightbox-close:hover,
.cast-lightbox-nav:hover {
  border-color: var(--cast-gold);
  background: rgba(201, 168, 106, 0.16);
}

.cast-lightbox-close svg,
.cast-lightbox-nav svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cast-lightbox-close {
  top: 1.2rem;
  right: 1.2rem;
}

.cast-lightbox-nav--prev { left: 1rem; }
.cast-lightbox-nav--next { right: 1rem; }

.cast-lightbox-counter {
  position: absolute;
  bottom: 1.4rem;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  color: rgba(255, 255, 255, 0.6);
}

@media (min-width: 900px) {
  .cast-lightbox-nav--prev { left: 2.4rem; }
  .cast-lightbox-nav--next { right: 2.4rem; }
}

/* Bloquea el scroll de fondo mientras el lightbox está abierto. */
body.cast-lightbox-open {
  overflow: hidden;
}

/* =============================== Revelado ================================= */

/* El estado oculto solo se aplica cuando html.cast-js existe (lo marca el
   script inline del <head>). Sin JS —o si el bundle falla— el contenido se
   renderiza visible: en una landing de pauta, jamás una pantalla en blanco. */
.cast-js .cast-reveal {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 0.85s var(--cast-ease),
    transform 0.85s var(--cast-ease);
}

.cast-js .cast-reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Entrada del copy de la Sección 2 (badge, H1, párrafo de neuromarketing,
   tarjeta de oferta dual COP/USD, CTA): mismo patrón que .cast-reveal
   (oculto solo bajo html.cast-js, escalonado por IntersectionObserver al
   final del documento) pero con su propio nombre y timing "Apple-style" —
   translateY(40px) → 0 y opacity 0 → 1 a lo largo de 1.2s en
   cubic-bezier(0.16, 1, 0.3, 1), con delays en cascada por elemento. */
.cast-js .cast-fade-up {
  opacity: 0;
  transform: translateY(40px);
  transition:
    opacity 1.2s var(--cast-ease),
    transform 1.2s var(--cast-ease);
}

.cast-js .cast-fade-up.is-inview {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .cast-js .cast-reveal,
  .cast-js .cast-reveal.is-visible,
  .cast-js .cast-fade-up,
  .cast-js .cast-fade-up.is-inview {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .cast-scroll-cue-line { animation: none; }

  .cast-cta,
  .cast-shot,
  .cast-shot img,
  .cast-pillar,
  .cast-sticky-cta {
    transition: none;
  }
}
