/* ==========================================================================
   Notable — landing "Blooming soon"
   Referencia: Figma hPUYC1Lul0IJOB9Otcxx1a, frame 2:2 (1728 × 2476)
   Escrito mobile-first: los valores base son los del móvil y crecen con vw.
   ========================================================================== */

:root {
  /* Color — hex literales del Figma */
  --verde-fondo:  #0F2323;
  --hueso:        #FCFDF2;
  --lima:         #DAE973;

  /* Tipografía — la real primero, la sustituta de Google detrás.
     En cuanto entre el kit de Adobe Fonts, las reales ganan solas. */
  --sans:  "early-sans-variable", "Early Sans Variable", "Archivo", system-ui, sans-serif;
  --serif: "late-serif-variable", "Late Serif Variable", "Newsreader", Georgia, serif;
  --mono:  "degular-mono", "Degular Mono", "DM Mono", ui-monospace, monospace;

  /* El wordmark sangra ~1.8% más ancho que el frame (1759.66 / 1728) */
  --wordmark-ancho: 101.83%;

  --margen: clamp(1rem, 3.2vw, 2.75rem);
}

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

body {
  margin: 0;
  background: var(--verde-fondo);
  color: var(--hueso);
  font-family: var(--sans);
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ============================ HEADER ============================ */

.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--margen);
  font-size: clamp(0.5625rem, 0.86vw, 0.75rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* Atenuado por color y no con `opacity`: la opacidad del contenedor no
     se puede deshacer desde dentro, y un enlace en hover tiene que poder
     encenderse en lima al 100%. */
  color: rgb(252 253 242 / 0.72);
}

/* En el Figma "IG        IN" es un solo texto con espacios de por medio.
   Aquí son dos enlaces, que es lo que van a ser: el hueco lo pone el gap. */
.header__social {
  display: flex;
  gap: 1.6em;
}

.header__link {
  color: inherit;
  text-decoration: none;
  padding-bottom: 0.2em;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0 1px;
  background-position: 100% 100%;
  background-repeat: no-repeat;
  /* La raya se pinta con `currentColor`, así que cambiando el color van
     los dos a una: texto y línea se encienden juntos. */
  transition: background-size 0.4s cubic-bezier(0.4, 0, 0.2, 1),
              color 0.3s ease;
}
.header__link:hover,
.header__link:focus-visible {
  color: var(--lima);
  background-size: 100% 1px;
  background-position: 0 100%;
}
.header__link:focus-visible { outline: none; }

/* ============================= HERO ============================= */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1.25rem, 2.6vw, 2.25rem);
  padding: calc(var(--margen) * 3) var(--margen) calc(var(--margen) * 2);
  text-align: center;
}

/* La flor es blanca sobre negro. Figma la funde en DIFFERENCE contra el
   verde y de ahí sale el rosa: #FFF ⊖ #0F2323 = #F0DCDC. Replicamos la
   misma operación en CSS, así el rosa sigue al fondo si el fondo cambia.
   El vídeo va aplanado sobre negro por eso mismo: negro ⊖ verde = verde,
   o sea que el fondo del clip desaparece sin necesitar canal alfa. */
.hero__flor {
  position: relative;
  width: clamp(6.5rem, 11vw, 9.5rem);
  aspect-ratio: 250 / 410;                   /* recorte del gif animado */
  mix-blend-mode: difference;
  transform: rotate(0.86deg);                /* rotación del nodo en Figma */
}

.hero__flor__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* ------------------------ título en tiras ------------------------ */
/* El título llega deshecho y se posa. No son partículas: son N copias
   del propio <h1>, cada una enmascarada por una franja de bloques
   sorteados, que vuelan enteras. Por eso el texto sigue siendo texto. */

.hero__titulo {
  position: relative;
  display: inline-block;
}

/* Mientras hay tiras, el original cede el sitio: las tiras SON él. */
.hero__titulo.en-tiras > .hero__title { opacity: 0; }

.tira {
  position: absolute;
  inset: 0;
  will-change: transform, opacity, filter;
  pointer-events: none;
}
.tira > .hero__title {
  position: absolute;
  inset: 0;
  opacity: 1;
  margin: 0;
}

/* ---------------------------- polvo ------------------------------ */

.polvo-caja { position: relative; }

/* El lienzo es más grande que lo que dibuja (240% = 1 + 2×0.7, el
   MARGEN_POLVO de main.js). Si midiera lo mismo, las motas que llegan
   desde fuera se cortarían contra su borde y se vería un cuadrado. */
.polvo {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  width: 240%;
  height: 240%;
  opacity: 0;
  pointer-events: none;
}

/* Mientras el polvo manda, el original se aparta. El relevo se cruza en
   vez de cambiar de golpe: aunque el texto del lienzo y el <h1> caigan
   en el mismo sitio, un corte seco se ve como un salto. */
.polvo,
.polvo-original {
  transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.polvo-caja[data-polvo] .polvo { opacity: 1; }
.polvo-caja[data-polvo] .polvo-original { opacity: 0; }

.hero__title {
  font-family: var(--serif);
  font-weight: 400;                          /* Late Serif Regular */
  font-size: clamp(1.5rem, 3vw, 2.625rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0;
}

.hero__cue {
  /* Anclado abajo sin robarle espacio al bloque central, que se queda
     centrado de verdad en la pantalla. */
  position: absolute;
  bottom: var(--margen);
  left: 50%;
  translate: -50% 0;
  font-size: clamp(0.5rem, 0.75vw, 0.625rem);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  opacity: 0.35;
}

/* -------------------------- captura email ------------------------ */
/* Sin caja blanca: una regla fina y el texto encima. */

/* Tras el alta no hay estado de reposo: el formulario desaparece y no
   lo sustituye nada (el popup ya dio las gracias). La rejilla se queda
   por la altura: el formulario oculto con visibility sigue ocupando su
   celda, así que la flor y el título no se mueven. */
.capture-zona {
  display: grid;
  width: min(22rem, 78vw);
}
.capture-zona > * { grid-area: 1 / 1; }

.capture {
  position: relative;
  width: 100%;
  transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}

/* `visibility` además de `opacity`: sin ella el formulario invisible
   sigue siendo enfocable con el tabulador y se podría volver a enviar,
   que es justo lo que no queremos. */
.capture-zona[data-hecho] .capture {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition-delay: 0s;
}

/* Al volver con el dato ya guardado no hay nada que fundir: estaba así
   desde el principio. */
.capture-zona[data-inmediato] .capture { transition: none; }

/* La clase la pone el script inline del <head> ANTES del primer
   pintado, leyendo la misma marca de localStorage que main.js. Sin
   esto, recargar con el alta hecha enseñaba el formulario un instante
   antes de esconderlo (main.js carga al final del body). */
.ya-apuntado .capture {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: none;
}

.capture__label {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.capture__input {
  width: 100%;
  padding: 0.7em 0;
  border: 0;
  border-bottom: 1px solid rgb(252 253 242 / 0.28);
  border-radius: 0;
  background: none;
  color: var(--hueso);
  font-family: var(--sans);
  font-size: clamp(0.8125rem, 1.1vw, 0.9375rem);
  letter-spacing: 0.04em;
  transition: border-color 0.3s ease;
}
.capture__input::placeholder {
  color: rgb(252 253 242 / 0.4);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 0.85em;
}
.capture__input:focus-visible {
  outline: none;
  border-bottom-color: var(--lima);
}

/* Ya no es una flecha dentro del campo: en el Figma es "AVÍSAME" en lima,
   fuera de la caja y alineado a su borde derecho. */
.capture__submit {
  display: block;
  margin: 0.85em 0 0 auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--lima);
  font-family: var(--mono);
  font-weight: 600;                          /* Degular Mono Semibold */
  font-size: clamp(0.625rem, 0.9vw, 0.75rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: 0.85;
  transition: opacity 0.3s ease;
}
.capture__submit:hover,
.capture__submit:focus-visible { opacity: 1; }

.capture__msg {
  position: absolute;
  top: calc(100% + 0.6em);
  left: 0;
  width: 100%;
  margin: 0;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-align: center;
  color: var(--lima);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.capture__msg[data-visible] { opacity: 1; }
.capture__msg[data-error] { color: #E9A073; }

.capture__submit[disabled] { opacity: 0.4; cursor: default; }

/* Fuera de la vista pero dentro del formulario: si se ocultara con
   `display:none` muchos bots ni lo intentarían, y el cebo dejaría de
   pescar. */
.capture__cebo {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.capture__aviso {
  margin: 1.4em 0 0;
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-align: center;
  line-height: 1.5;
  color: rgb(252 253 242 / 0.38);
}
.capture__aviso a { color: inherit; text-decoration: underline; }
.capture__aviso a:hover { color: var(--lima); }

/* ============================ POPUPS ============================== */
/* Figma 2026-08-05: dos cajas sueltas en el canvas, sin radio ni
   sombra. 624 de ancho las dos; la de contacto además 528 de alto.
   Se montan sobre <dialog>, que trae gratis el foco atrapado, el Esc
   y el fondo. */

.popup {
  width: min(39rem, calc(100vw - 2 * var(--margen)));   /* 624px de techo */
  border: 0;
  padding: 0;
  background: none;
  color: var(--verde-fondo);
}
/* El fondo se atenúa Y se desenfoca: nítido, el hero se lee detrás del
   popup y compite con él. Con blur queda como textura, que es el mismo
   truco de la NIEBLA de las tiras. */
.popup::backdrop {
  background: rgb(15 35 35 / 0.55);
  -webkit-backdrop-filter: blur(9px);
  backdrop-filter: blur(9px);
}
.popup[open] {
  animation: popup-entra 0.35s cubic-bezier(0.4, 0, 0.2, 1) both;
}
@keyframes popup-entra {
  from { opacity: 0; transform: translateY(0.75rem); }
}

.popup__cerrar {
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  padding: 0.65rem;
  border: 0;
  background: none;
  color: inherit;
  font-size: 0.8125rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.3s ease;
}
.popup__cerrar:hover,
.popup__cerrar:focus-visible { opacity: 1; }

/* En el popup del alta el ✕ es lo único enfocable, así que showModal()
   le pone el foco nada más abrir: sin esto, lo primero que se ve es el
   anillo azul del navegador encima del lima. */
.popup__cerrar:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 2px;
}

/* ------------------- confirmación del alta ----------------------- */
/* Lima sobre texto verde, Late Serif Medium. Los márgenes del Figma:
   38 arriba, 54/55 a los lados, 45 abajo. */

.popup--alta {
  background: var(--lima);
  /* Más estrecho que los 624 del Figma: con los cuerpos reducidos del
     05-08, la caja original dejaba media panza de aire a la derecha. */
  width: min(30rem, calc(100vw - 2 * var(--margen)));
  padding: clamp(1.5rem, 4vw, 2.25rem)
           clamp(1.5rem, 4vw, 2.5rem)
           clamp(1.75rem, 4vw, 2.5rem);
}

/* El primer párrafo recibe el foco al abrir (tabindex -1 + autofocus)
   para que el anillo no caiga en el ✕ y el lector arranque por el
   mensaje. No es interactivo: no se tabula hasta él, así que quitarle
   el anillo no le esconde nada a nadie. */
.popup--alta__texto:focus { outline: none; }

/* Dos voces (nodo 255:59, estilos mezclados): titular en serif como el
   "Blooming soon", detalle más pequeño en Early Sans. */
/* Cuerpos por debajo del Figma (40/24) a petición de Alexia el 05-08:
   "más pequeños los textos de los popups". La jerarquía se queda. */
.popup--alta__texto {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;                          /* Late Serif Medium */
  font-size: clamp(1.0625rem, 1.6vw, 1.375rem);
  line-height: 1.34;
}

.popup--alta__detalle {
  margin: 1.2em 0 0;
  font-family: var(--sans);
  font-weight: 400;                          /* Early Sans Regular */
  font-size: clamp(0.875rem, 1.3vw, 1.0625rem);
  line-height: 1.45;
}

/* --------------------------- contacto ---------------------------- */
/* Caja hueso con campos blancos a hueso vivo, sin borde. El Enviar es
   texto suelto abajo a la derecha, como el AVÍSAME pero en oscuro. */

.popup--contacto {
  background: var(--hueso);
  padding: clamp(1.25rem, 3.5vw, 2rem);
  /* Un pelo más que el Figma (32px): el ✕ es nuestro, no del diseño, y
     sin este aire pisa la esquina del campo Nombre en móvil. */
  padding-top: 2.25rem;
}

/* Los dos estados en la misma celda, como la captura del hero: la
   rejilla mide por el formulario y el cruce no cambia el tamaño. */
.contacto-zona { display: grid; }
.contacto-zona > * { grid-area: 1 / 1; }

.contacto {
  display: grid;
  gap: 1.1rem;                 /* aire entre reglas, no entre cajas */
  transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}
.contacto-zona[data-hecho] .contacto {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition-delay: 0s;
}

.contacto__label {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

/* Variante A (elegida el 05-08 sobre demos/popup-contacto.html): fuera
   las cajas blancas del Figma; regla fina y texto encima, el idioma del
   AVÍSAME del hero traído al fondo hueso. 16px de suelo a propósito:
   menos y el iOS hace zoom al enfocar. */
.contacto__campo {
  width: 100%;
  padding: 0.7em 0;
  border: 0;
  border-bottom: 1px solid rgb(15 35 35 / 0.28);
  border-radius: 0;
  background: none;
  color: var(--verde-fondo);
  font-family: var(--sans);
  font-size: clamp(1rem, 1.4vw, 1.125rem);
  letter-spacing: 0.04em;
  transition: border-color 0.3s ease;
}
.contacto__campo::placeholder {
  color: #A8A29E;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 0.85em;
}
.contacto__campo:focus-visible {
  outline: none;
  border-bottom-color: var(--verde-fondo);
}

.contacto__mensaje {
  min-height: clamp(5rem, 10vw, 6.5rem);
  resize: none;
}

.contacto__aviso {
  margin: 0.5em 0 0;
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  line-height: 1.5;
  color: rgb(15 35 35 / 0.55);
}
.contacto__aviso a { color: inherit; text-decoration: underline; }
.contacto__aviso a:hover { color: var(--verde-fondo); }

/* El mismo cuerpo y las mismas mayúsculas que el AVÍSAME del hero:
   los placeholders van en mayúscula pequeña y el botón desentonaba en
   caja alta/baja ("están diferente"). Ahora hablan igual. */
.contacto__enviar {
  justify-self: end;
  margin: 0.5rem 0 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--verde-fondo);
  font-family: var(--mono);
  font-weight: 600;                          /* Degular Mono Semibold */
  font-size: clamp(0.625rem, 0.9vw, 0.75rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: 0.85;
  transition: opacity 0.3s ease;
}
.contacto__enviar:hover,
.contacto__enviar:focus-visible { opacity: 1; }
.contacto__enviar[disabled] { opacity: 0.4; cursor: default; }

.contacto__msg {
  margin: 0;
  min-height: 1.2em;                         /* reserva el sitio: el popup no salta */
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--verde-fondo);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.contacto__msg[data-visible] { opacity: 1; }
.contacto__msg[data-error] { color: #B4552D; }

.contacto__gracias {
  align-self: center;
  margin: 0;
  max-width: 34.5rem;                        /* 553px del Figma */
  font-family: var(--sans);
  font-size: clamp(0.875rem, 1.3vw, 1.0625rem); /* a juego con el detalle del alta */
  line-height: 1.45;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s ease 0.35s, visibility 0s linear 0.35s;
}
.contacto-zona[data-hecho] .contacto__gracias {
  opacity: 1;
  visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
  .popup[open] { animation: none; }
}

/* ================= SECUENCIA CON SCROLL (pin + scrub) ============= */

.reveal { position: relative; }

.reveal__stage {
  position: relative;
  height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* --------------------- rodillo 3D (cilindro) --------------------- */

/* Las líneas van repartidas sobre un cilindro invisible. La cinta gira
   con el scroll y solo se ve la que queda de frente: las demás pierden
   opacidad al girar hacia atrás, así que nunca hay dos legibles. */

.rodillo {
  position: relative;
  /* Sin márgenes: el stage es un flex centrado y el rodillo es su único
     hijo en flujo, así que la línea que se lee cae en el centro de la
     pantalla. El wordmark va absoluto y no le roba sitio. */
  margin: 0;
  /* 86% del ancho hasta topar en 46.75rem, que son los 748px del Figma
     a 1440 (897/1728). Mobile-first: la proporción de escritorio es el
     techo, no el punto de partida. */
  width: clamp(20rem, 86vw, 46.75rem);
  height: 5em;
  /* En em, no en px: así la profundidad del cilindro acompaña al cuerpo
     y el efecto se ve igual de hondo en móvil que en escritorio. */
  perspective: 22em;
  font-family: var(--mono);
  font-weight: 600;                          /* Degular Mono Semibold */
  line-height: 1.326;                        /* 84.864/64 */
  text-align: center;
  text-transform: uppercase;                 /* textCase UPPER del Figma */

  /* El Figma lo subió de 40 a 64 px y lo pasó a mayúsculas. Las
     mayúsculas se quedan; el tamaño no: a 46 px se comía la pantalla.
     Decisión suya, y contradice el diseño a sabiendas. El techo baja a
     la mitad (23 px) y el suelo de móvil vuelve donde estaba, porque
     ahí nunca sobró. main.js baja más el cuerpo si la fuente cargada
     partiría alguna línea: los cortes son de diseño. */
  font-size: clamp(1.125rem, 2.8vw, 1.4375rem);
}

.rodillo__cinta {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  will-change: transform;
}

.rodillo__linea {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1.326em;
  margin-top: -0.663em;
  white-space: nowrap;
  backface-visibility: hidden;
  opacity: 0;
}

.solo-lectores {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
}

/* --------------------------- wordmark ---------------------------- */

.wordmark {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: var(--wordmark-ancho);       /* estado final; JS anima el ancho */

  /* Se centra con la propiedad `translate`, que es independiente de
     `transform`: así GSAP puede usar la transform entera para el
     desplazamiento vertical sin pisar el centrado. */
  translate: -50% 0;

  pointer-events: none;
  opacity: 0;
}
.wordmark__svg {
  display: block;
  width: 100%;
  height: auto;
  color: var(--lima);
}

/* ============================ ESTADOS ============================= */

/* Sin JS o con motion reducido no hay rodillo que valga: se muestra el
   texto entero de una vez y la marca en su tamaño final. */
.no-js .rodillo,
.reveal.is-listo .rodillo { display: none; }

.no-js .wordmark,
.reveal.is-listo .wordmark { opacity: 1; }

.no-js .solo-lectores,
.reveal.is-listo .solo-lectores {
  position: static;
  /* 86% del ancho hasta topar en 46.75rem, que son los 748px del Figma
     a 1440 (897/1728). Mobile-first: la proporción de escritorio es el
     techo, no el punto de partida. */
  width: clamp(20rem, 86vw, 46.75rem);
  height: auto;
  margin: 0;
  overflow: visible;
  clip-path: none;
  font-family: var(--mono);
  font-weight: 600;
  font-size: clamp(1.125rem, 5.2vw, 1.625rem);
  line-height: 1.326;
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .wordmark { transform: none !important; opacity: 1 !important; }
  .capture__submit svg, .header__link { transition: none; }
}
