/* ══════════════════════════════════════════════════════════════════════════════
   NEXXVO — hoja de estilo única
   Papel cálido + tinta espresso. Sin cajas salvo donde algo deba contenerse.
   1. Tokens · 2. Reset · 3. Tipografía · 4. Retícula · 5. La tarjeta
   6. Componentes · 7. Secciones · 8. Movimiento · 9. Legales
   ══════════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────── 1 · TOKENS ─────────────────────────────── */
/*  TIPOGRAFÍA — no hay fuentes en assets/fonts/, así que no se sirve ninguna.
    La pila usa la tipografía de sistema de cada plataforma, que en macOS e iOS
    ES SF Pro y en Windows es Segoe UI Variable: dos grotescas neutras de nivel
    editorial. Cero peticiones, cero KB, cero FOUT y ningún problema de RGPD.
    Inter, Roboto y las geométricas de startup quedan fuera a propósito.
    Si algún día compras Neue Haas o Avenir Next, se sirve desde aquí:

@font-face{
  font-family:"Nexxvo Sans"; src:url("../fonts/nexxvo-sans.woff2") format("woff2-variations");
  font-weight:300 700; font-display:swap;
}
*/

/* Dos tipografías de display, self-hosted, SOLO para el rótulo de cierre.
   Ambas con licencia SIL Open Font License: uso comercial y self-hosting
   permitidos. No hay ninguna petición a Google. Se descargan solo cuando el
   navegador va a pintar ese bloque, y font-display:swap evita texto invisible. */
@font-face{
  font-family:"Anton"; src:url("../fonts/anton-latin.woff2") format("woff2");
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"Caveat"; src:url("../fonts/caveat-700-latin.woff2") format("woff2");
  font-weight:700; font-style:normal; font-display:swap;
}
/* Playfair Display para TODOS los titulares. Una sola familia añadida y una
   sola regla: titulares con serifa, todo lo demás con la grotesca del sistema.
   La serifa de alto contraste es lo que da carácter editorial; meter cuatro o
   cinco tipografías de fantasía es lo que hace que una web parezca casera. */
@font-face{
  font-family:"Playfair Display"; src:url("../fonts/playfair-latin.woff2") format("woff2-variations");
  font-weight:400 600; font-style:normal; font-display:swap;
}
/* Yanone Kaffeesatz para subtítulos y etiquetas: condensada, hecha justo para
   ese papel, y de paso le va el nombre a una marca espresso. */
@font-face{
  font-family:"Yanone Kaffeesatz"; src:url("../fonts/yanone-latin.woff2") format("woff2-variations");
  font-weight:300 600; font-style:normal; font-display:swap;
}

:root{
  /* ── color: 70 % papel · 20 % espresso · 10 % detalle ── */
  --espresso:  #2A211D;
  --deep:      #1C1715;
  --choco:     #3A2A24;

  --paper:     #F4EFE8;   /* fondo principal — NO blanco */
  --cream:     #EAE1D7;   /* bandas secundarias */
  --white:     #FFFFFF;   /* solo producto y superficies concretas */

  --text:      #2A211D;
  --muted:     #6B635C;   /* 5,15:1 sobre papel · 4,56:1 sobre crema */
  --muted-d:   #A9A099;   /* sobre espresso — 6,9:1 */
  --muted-dd:  #7B726B;   /* microtexto sobre espresso: pie y avisos */
  --ink-soft:  #4A423C;   /* cuerpo de las páginas legales */
  --line:      rgba(42,33,29,.12);
  --line-2:    rgba(42,33,29,.20);
  --line-d:    rgba(244,239,232,.14);
  --focus:     #6B4A38;
  --gold:      #D99B2B;   /* estrellas de reseña, y solo eso */
  --star-off:  #DCD5CB;   /* estrella sin valorar, antes de que el cliente pulse */
  /* Rojo acotado AL RÓTULO DE CIERRE. No se usa en ningún otro sitio: crema y
     dorado sobre marrón es la paleta de una cadena de hamburgueserías, y el
     rojo rompe esa lectura de golpe. 4,60:1 sobre espresso. */
  --claim-red: #FF4433;
  --alert:     #C4643F;

  /* ── tipografía ── */
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue",
          "Segoe UI Variable Text", "Segoe UI", "Avenir Next", Helvetica, sans-serif;
  /* la grotesca de sistema sigue siendo la voz de interfaz: menú, botones,
     etiquetas y microtexto. Los titulares llevan la serifa. */
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue",
          "Segoe UI Variable Display", "Segoe UI", "Avenir Next", Helvetica, sans-serif;
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-label:   "Yanone Kaffeesatz", "Segoe UI", Helvetica, sans-serif;

  /* CUATRO VOCES, cada una con un papel:
     · display → titulares
     · label   → subtítulos y etiquetas
     · ui      → texto corrido, interfaz y formularios
     · Anton + Caveat → solo el rótulo de cierre               */

  /* Escala contenida: el titular baja de 5,5rem a 4,5rem y de peso 530 a 450.
     La jerarquía la hacen el tamaño, el espacio y la posición, no la negrita. */
  --fs-hero:  clamp(2.6rem, 6.2vw, 4.5rem);
  --fs-d1:    clamp(1.9rem, 4.4vw, 3.25rem);
  --fs-d2:    clamp(1.25rem, 2.2vw, 1.625rem);
  --fs-lead:  clamp(1.0625rem, .95rem + .55vw, 1.25rem);
  --fs-body:  1rem;
  --fs-sm:    .9375rem;
  --fs-cap:   .6875rem;

  /* pesos: nada por encima de 600, y 600 solo en microtexto en versales */
  --w-reg: 400;
  --w-mid: 450;
  --w-med: 500;
  --w-sem: 550;

  /* ── ritmo ── */
  --sp-1:.25rem; --sp-2:.5rem;  --sp-3:.75rem; --sp-4:1rem;
  --sp-5:1.5rem; --sp-6:2rem;   --sp-7:3rem;   --sp-8:4rem;
  --sp-9:6rem;   --sp-10:8rem;
  --sec-y: clamp(6rem, 14vw, 12rem);
  --gutter: clamp(1.5rem, 5vw, 3rem);
  --maxw: 1320px;

  /* ── forma: tres radios, no veinte ── */
  --r:       8px;    /* botones y campos */
  --r-lg:    14px;   /* los pocos contenedores reales */
  --r-sheet: 22px;   /* la lámina que cubre el hero */

  --ease:  cubic-bezier(.22,1,.36,1);
  --ease2: cubic-bezier(.4,0,.2,1);
}

/* ─────────────────────────────── 2 · RESET ─────────────────────────────── */
*,*::before,*::after{ box-sizing:border-box; }
*{ margin:0; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } }

body{
  font-family:var(--font);
  font-size:var(--fs-body);
  font-weight:var(--w-reg);
  line-height:1.65;
  letter-spacing:-.003em;
  color:var(--text);
  background:var(--deep);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
img,svg,video{ display:block; max-width:100%; }
img{ height:auto; }
button,input,textarea,select{ font:inherit; color:inherit; }
button{ background:none; border:0; cursor:pointer; }
ul,ol{ list-style:none; padding:0; }
a{ color:inherit; }

:where(a,button,summary,input,[tabindex]):focus-visible{
  outline:2px solid var(--focus); outline-offset:3px; border-radius:2px;
}
.on-dark :where(a,button,summary,input):focus-visible{ outline-color:#C89B7E; }
:target, [id]{ scroll-margin-top:5.5rem; }

.sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip{
  position:fixed; top:-100px; left:var(--gutter); z-index:200;
  background:var(--espresso); color:var(--paper);
  padding:.7rem 1.2rem; border-radius:var(--r); font-size:var(--fs-sm);
  transition:top .2s var(--ease);
}
.skip:focus{ top:1rem; }

/* ───────────────────────────── 3 · TIPOGRAFÍA ───────────────────────────── */
.display{
  font-family:var(--font-display);
  font-size:var(--fs-d1);
  font-weight:var(--w-med);
  line-height:1.1;
  letter-spacing:-.014em;
  text-wrap:balance;
}
.eyebrow{
  font-family:var(--font-label);
  font-size:calc(var(--fs-cap) + 1px);
  letter-spacing:.22em;
  text-transform:uppercase;
  color:var(--muted);
  font-weight:var(--w-sem);
}
.on-dark .eyebrow{ color:var(--muted-d); }

.lead{ font-size:var(--fs-lead); line-height:1.55; color:var(--muted); max-width:46ch; text-wrap:pretty; }
.on-dark .lead{ color:var(--muted-d); }

.todo{
  display:inline-block; font-size:.6875rem; letter-spacing:.06em;
  text-transform:uppercase; font-weight:var(--w-sem);
  background:#F3E2BC; color:#5A4300; padding:.15em .5em; border-radius:4px; margin-right:.4em;
}

/* Máscara de línea. overflow-wrap es la red de seguridad: sin ella una palabra
   más ancha que su columna se recorta en vertical en lugar de pasar de línea. */
.mask{ display:block; overflow:hidden; padding-bottom:.14em; margin-bottom:-.14em; }
.mask__i{ display:block; overflow-wrap:break-word; }

/* ────────────────────────────── 4 · RETÍCULA ────────────────────────────── */
/* Un solo contenedor en toda la página. Los anchos de lectura se limitan en
   cada elemento, no cambiando de contenedor: dos secciones seguidas con el
   borde izquierdo en sitios distintos se leen como un fallo. */
.wrap{ width:100%; max-width:var(--maxw); margin-inline:auto; padding-inline:var(--gutter); }

/* OJO: `ch` se calcula con el tamaño de letra DEL PROPIO elemento. Poner el
   max-width en .sec-head (16 px) estrangulaba el titular de 52 px a ~300 px y
   lo rompía en tres líneas. La medida va en cada elemento, no en el bloque. */
.sec-head{ margin-bottom:clamp(3rem,7vw,5.5rem); }
.sec-head .eyebrow{ margin-bottom:var(--sp-5); }
.sec-head .display{ max-width:17ch; }
.sec-head__sub{
  font-family:var(--font-label); font-weight:var(--w-med);
  margin-top:var(--sp-5); font-size:calc(var(--fs-lead) + 3px); line-height:1.4;
  letter-spacing:.004em; color:var(--muted); max-width:40ch; text-wrap:pretty;
}
.on-dark .sec-head__sub{ color:var(--muted-d); }

/* ═══════════════════════════ 5 · LA TARJETA ═══════════════════════════
   Marco físico en CSS + el arte real del producto como cara.
   Proporción y radio del formato ID-1 (85,6 × 54 mm, r = 3,18 mm).
   ══════════════════════════════════════════════════════════════════════ */
.ncard{
  position:relative; width:100%;
  perspective:1300px;
  /* Grosor real del formato ID-1: 0,76 mm sobre 85,6 mm = 0,888 % del ancho.
     A los tamaños que usa la web (450-580 px) son 4 px. Va en píxeles a
     propósito: con unidades de contenedor haría falta container-type, y eso
     aplica contain:inline-size, que dentro de un grid centrado deja la pieza
     con 0 px de ancho. */
  --th:4px; --half:2px;
  --rx:0deg; --ry:0deg; --mx:34%; --my:22%;
}
.ncard__tilt{
  transform-style:preserve-3d;
  transform:rotateX(var(--rx)) rotateY(var(--ry));
  will-change:transform;
}
.ncard__float{ position:relative; transform-style:preserve-3d; }

/* ── Sólido de verdad: cara, reverso y cuatro cantos ──
   Ya no se simula el grosor con capas de box-shadow: al girar la pieza se ve
   el canto porque el canto existe. */
.ncard__body{
  position:absolute; inset:0;
  border-radius:3.71%/5.89%;
  overflow:hidden;
  background:var(--white);
  transform:translateZ(var(--half));
  backface-visibility:hidden;
  box-shadow:0 0 0 1px var(--edge-line, rgba(42,33,29,.14));
}
/* mantiene la proporción del hueco que ocupa la pieza */
.ncard__float::before{ content:""; display:block; aspect-ratio:856/540; }
.ncard__art{ width:100%; height:100%; object-fit:cover; }

.ncard__back{
  position:absolute; inset:0;
  border-radius:3.71%/5.89%;
  background:linear-gradient(158deg,#FBF9F5,#EFEBE3 55%,#E5E0D6);
  transform:rotateY(180deg) translateZ(var(--half));
  backface-visibility:hidden;
  display:grid; place-items:center;
  box-shadow:0 0 0 1px rgba(42,33,29,.12), inset 0 1px 0 rgba(255,255,255,.8);
}
/* el reverso lleva el propio símbolo recortado, no un dibujo nuevo */
.ncard__back i{
  display:block; width:19%; aspect-ratio:1; background:var(--espresso); opacity:.14;
  -webkit-mask:url("../brand/mark-160.png") center/contain no-repeat;
          mask:url("../brand/mark-160.png") center/contain no-repeat;
}

/* Los cantos se recogen por el radio de la esquina: si llegasen de punta a
   punta, asomarían por fuera de las esquinas redondeadas al girar la pieza.
   El radio del ID-1 es 3,71 % del ancho y 5,89 % del alto. */
.ncard__edge{ position:absolute; background:linear-gradient(var(--eA,#F2EEE6), var(--eB,#C4BCAE)); }
.ncard__edge--l{ left:0; top:5.89%; width:var(--th); height:88.22%; transform:translateX(calc(var(--half) * -1)) rotateY(90deg); }
.ncard__edge--r{ right:0; top:5.89%; width:var(--th); height:88.22%; transform:translateX(var(--half)) rotateY(90deg); }
.ncard__edge--t{ left:3.71%; top:0; width:92.58%; height:var(--th); transform:translateY(calc(var(--half) * -1)) rotateX(90deg); }
.ncard__edge--b{ left:3.71%; bottom:0; width:92.58%; height:var(--th); transform:translateY(var(--half)) rotateX(90deg); }

/* reflejo: sigue al puntero, no se mueve solo */
.ncard__spec{
  position:absolute; inset:-2%; pointer-events:none;
  background:radial-gradient(44% 66% at var(--mx) var(--my),
    rgba(255,255,255,.7), rgba(255,255,255,.16) 42%, rgba(255,255,255,0) 70%);
  opacity:.42; mix-blend-mode:soft-light;
  transition:opacity .6s var(--ease);
}
.ncard__rim{
  position:absolute; inset:0; pointer-events:none; border-radius:inherit;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.85), inset 0 -1px 0 rgba(42,33,29,.10);
}
.ncard__shadow{
  position:absolute; left:8%; right:8%; bottom:-6%; height:12%;
  background:radial-gradient(50% 50% at 50% 50%, rgba(0,0,0,var(--cast,.34)), transparent 74%);
  filter:blur(18px); z-index:-1;
  transform:translateX(calc(var(--shx,0) * 1px));
  transition:transform .6s var(--ease2);
}
/* La antena va por el perímetro, que es donde va de verdad, y así no choca
   con el símbolo NFC que el diseño ya lleva impreso en el centro. */
.ncard__antenna{ position:absolute; inset:0; pointer-events:none; opacity:0; transition:opacity .6s var(--ease); }
.ncard__antenna i{ position:absolute; display:block; border:1px solid var(--choco); border-radius:3.71%/5.89%; }
.ncard__antenna i:first-child{ inset:5%; }
.ncard__antenna i:last-child{ inset:7.6%; opacity:.5; }

/* ──────────────────────────── 6 · COMPONENTES ──────────────────────────── */

/* Primario: espresso sólido, crema encima, radio discreto, sin tamaño SaaS. */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.55rem;
  min-height:46px; padding:0 1.35rem;
  border-radius:var(--r);
  font-size:var(--fs-sm); font-weight:var(--w-sem); letter-spacing:-.008em;
  text-decoration:none; white-space:nowrap;
  background:var(--espresso); color:var(--paper); border:1px solid var(--espresso);
  transition:background .4s var(--ease), border-color .4s var(--ease), transform .18s var(--ease2);
}
.btn:hover{ background:var(--choco); border-color:var(--choco); }
.btn:active{ transform:translateY(1px); }
.btn--lg{ min-height:52px; padding:0 1.7rem; }
.btn--sm{ min-height:38px; padding:0 .95rem; font-size:.8125rem; }
.btn--block{ width:100%; }
.on-dark .btn{ background:var(--paper); color:var(--espresso); border-color:var(--paper); }
.on-dark .btn:hover{ background:var(--white); border-color:var(--white); }

/* Secundario: no es un botón, es un enlace con flecha.
   El filete va bajo el TEXTO, no bajo toda la caja flexible: si va en el <a>,
   la línea se estira por debajo de la flecha y se lee como algo roto.
   min-height iguala su altura a la del botón para que compartan línea base. */
.link{
  display:inline-flex; align-items:center; gap:.55rem;
  min-height:52px;   /* la misma que .btn--lg, con la que comparte fila */
  font-size:var(--fs-sm); font-weight:var(--w-med); text-decoration:none;
  transition:gap .35s var(--ease);
}
/* Subrayado real, no un borde inferior: el span es un elemento flexible y su
   caja incluye el interlineado de 1,65, así que un border-bottom se dibuja
   muy por debajo de las letras y se lee despegado. text-underline-offset se
   mide desde la línea base y el trazo ajusta al ancho exacto del texto. */
/* Sin subrayado en reposo: la flecha ya dice que es un enlace. El trazo solo
   aparece al pasar por encima, y se dibuja desde la línea base. */
.link span{
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-decoration-color:transparent;
  text-underline-offset:.26em;
  transition:text-decoration-color .35s var(--ease);
}
.link:hover{ gap:.8rem; }
.link:hover span{ text-decoration-color:currentColor; }
.link svg{ width:14px; height:14px; flex:0 0 auto; }

/* Nav */
.nav{ position:fixed; inset:0 0 auto 0; z-index:100; color:var(--paper); transition:color .5s var(--ease); }
.nav__bar{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-6);
  max-width:var(--maxw); margin-inline:auto; padding:1.1rem var(--gutter);
  position:relative; z-index:2;
}
/* Sin backdrop-filter: recomponer una franja fija en cada scroll es de los
   costes más caros que hay y debajo siempre hay un fondo plano. */
.nav::before{
  content:""; position:absolute; inset:0; z-index:1;
  background:var(--paper); border-bottom:1px solid var(--line);
  opacity:0; transition:opacity .5s var(--ease);
}
.nav.is-solid{ color:var(--espresso); }
.nav.is-solid::before{ opacity:1; }

.nav__logo{ display:inline-flex; align-items:center; gap:.55rem; text-decoration:none; }
.nav__mark{ width:22px; height:22px; }
.nav:not(.is-solid) .nav__mark{ filter:brightness(1.95) saturate(.8); }
.nav__word{ font-size:.8125rem; font-weight:var(--w-med); letter-spacing:.16em; }
.nav__links{ display:none; gap:2.25rem; font-size:.8125rem; letter-spacing:-.002em; }
.nav__links a{ text-decoration:none; opacity:.65; transition:opacity .3s var(--ease); }
.nav__links a:hover{ opacity:1; }
.nav__end{ display:flex; align-items:center; gap:.5rem; }
.nav__cta{ display:none; background:transparent; color:inherit; border-color:currentColor; opacity:.75; }
.nav__cta:hover{ background:transparent; opacity:1; border-color:currentColor; }
.nav.is-solid .nav__cta{ background:var(--espresso); color:var(--paper); border-color:var(--espresso); opacity:1; }

.nav__burger{ width:44px; height:44px; display:grid; place-items:center; border-radius:var(--r); }
.nav__burger-lines{ display:block; width:19px; }
.nav__burger-lines i{ display:block; height:1px; background:currentColor; transition:transform .4s var(--ease); }
.nav__burger-lines i:first-child{ margin-bottom:5px; }
.nav__burger[aria-expanded="true"] i:first-child{ transform:translateY(3px) rotate(45deg); }
.nav__burger[aria-expanded="true"] i:last-child{ transform:translateY(-3px) rotate(-45deg); }

.menu{
  position:fixed; inset:0; z-index:1;
  background:var(--deep); color:var(--paper);
  padding:6rem var(--gutter) var(--sp-6);
  opacity:0; visibility:hidden;
  transition:opacity .4s var(--ease), visibility .4s;
}
.menu[data-open="true"]{ opacity:1; visibility:visible; }
.menu__inner{ display:flex; flex-direction:column; max-width:var(--maxw); margin-inline:auto; }
.menu__inner a{
  text-decoration:none; font-family:var(--font-ui);
  font-size:clamp(1.375rem,6vw,1.875rem); font-weight:var(--w-med);
  letter-spacing:-.02em; line-height:1.35;
  padding:.5rem 0; border-bottom:1px solid var(--line-d);
}
.menu__cta{ margin-top:var(--sp-6); font-size:var(--fs-sm) !important; border-bottom:0 !important; }

/* Formulario */
.form{ display:grid; gap:var(--sp-5); margin-top:var(--sp-7); text-align:left; max-width:460px; }
.field{ display:grid; gap:.4rem; }
.field label{ font-size:var(--fs-sm); font-weight:var(--w-med); }
.field__opt{ color:var(--muted-d); font-weight:var(--w-reg); }
.field input[type="email"],
.field input[type="text"]{
  min-height:48px; padding:0 .9rem;
  background:transparent;
  border:0; border-bottom:1px solid var(--line-d); border-radius:0;
  color:var(--paper);
  transition:border-color .3s var(--ease);
}
.field input::placeholder{ color:rgba(244,239,232,.3); }
.field input:hover,.field input:focus{ border-bottom-color:rgba(244,239,232,.4); }
.field input[aria-invalid="true"]{ border-bottom-color:var(--alert); }
.field__err{ font-size:.8125rem; color:var(--alert); }

.check{ display:flex; gap:.7rem; align-items:flex-start; }
.check input{
  appearance:none; -webkit-appearance:none;
  flex:0 0 auto; width:20px; height:20px; margin-top:2px;
  border:1px solid var(--line-d); border-radius:4px;
  background:transparent; cursor:pointer;
  transition:background .25s var(--ease), border-color .25s var(--ease);
}
.check input:checked{
  background:var(--paper) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 5' fill='none' stroke='%232A211D' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/14px no-repeat;
  border-color:var(--paper);
}
.check input[aria-invalid="true"]{ border-color:var(--alert); }
.check label{ font-size:.875rem; line-height:1.55; color:var(--muted-d); }
.check label a{ color:var(--paper); text-underline-offset:3px; }

.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
.form__note{ font-size:.8125rem; color:var(--muted-d); }
.form__status{ font-size:var(--fs-sm); }
.form__status[data-state="err"]{ color:var(--alert); }

/* ───────────────────────────── 7 · SECCIONES ───────────────────────────── */

/* ── HERO ── */
.hero{
  position:sticky; top:0; z-index:0;
  min-height:100svh; display:flex; flex-direction:column; justify-content:center;
  padding:7rem 0 4.5rem;
  background:var(--deep); color:var(--paper);
  overflow:hidden;
}
.hero__light{
  position:absolute; inset:0; pointer-events:none;
  background:
    radial-gradient(105% 72% at 76% 12%, rgba(234,225,215,.09), transparent 58%),
    radial-gradient(70% 50% at 12% 98%, rgba(58,42,36,.5), transparent 64%);
}
.hero__grid{ position:relative; display:grid; gap:clamp(2.5rem,6vw,4rem); align-items:center; }

/* ── El monograma, en grande y detrás ──
   Es el fondo de la portada: se coloca respecto a la retícula (no al viewport)
   para que la composición aguante en cualquier pantalla, y se aclara con un
   filtro porque el espresso sobre espresso no se vería. */
.hero__glyph{
  position:absolute; z-index:0; pointer-events:none;
  /* En móvil vive detrás del texto: más pequeño, más arriba y más apagado,
     porque a tamaño de escritorio se comería la legibilidad del párrafo. */
  right:-26%; top:26%;
  height:min(46svh, 360px); width:auto; max-width:none;
  transform:translateY(-50%) translateY(calc(var(--hero-p,0) * 5vh));
  opacity:.12; filter:brightness(3.2) saturate(.55);
}

/* ══ LA MARCA SE CONSTRUYE AL ENTRAR ══
   Una máscara 2,6 veces más ancha que el símbolo, opaca en su primer tercio
   y transparente en el último, que entra barriendo de izquierda a derecha.
   No se toca el símbolo: solo se controla cuánto de él se ha pintado ya.

   Las paradas están calculadas, no tanteadas. Con la máscara al 260 %, la
   ventana del elemento recorre el 38,5 % de la máscara: en el 100 % ve el
   tramo 61,5–100 % (todo transparente) y en el 0 % ve el 0–38,5 % (todo
   opaco). Por eso el opaco llega al 40 % y el transparente arranca en el 60 %:
   con ese margen la N acaba entera, sin un borde derecho a medio encender.

   Va en máscara y no en transform porque el transform ya lo ocupa el
   desplazamiento con el scroll (--hero-p) y se pisarían. */
.js .hero__glyph{
  -webkit-mask-image:linear-gradient(90deg,
    #000 0 40%, rgba(0,0,0,.72) 47%, rgba(0,0,0,.28) 54%, rgba(0,0,0,0) 60% 100%);
          mask-image:linear-gradient(90deg,
    #000 0 40%, rgba(0,0,0,.72) 47%, rgba(0,0,0,.28) 54%, rgba(0,0,0,0) 60% 100%);
  -webkit-mask-size:260% 100%;   mask-size:260% 100%;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:100% 0;  mask-position:100% 0;
  transition:-webkit-mask-position 2.4s var(--ease), mask-position 2.4s var(--ease);
}
.js.is-ready .hero__glyph{ -webkit-mask-position:0 0; mask-position:0 0; }

/* Sin JS la máscara no se declara siquiera, así que la marca se ve entera.
   Con movimiento reducido se anula por si acaso. */
@media (prefers-reduced-motion: reduce){
  .js .hero__glyph{
    -webkit-mask-image:none; mask-image:none; transition:none;
  }
}

/* rótulo de categoría: sin medidas, porque habrá varios tamaños */
.hero__kicker{
  font-family:var(--font-label); font-weight:var(--w-sem);
  font-size:clamp(.9375rem, 1.5vw, 1.125rem);
  letter-spacing:.3em; text-transform:uppercase;
  color:var(--muted-d);
  margin-bottom:clamp(1rem, 2.5vw, 1.75rem);
}

.hero__title{ margin-bottom:var(--sp-6); }
/* el nombre es el elemento mayor de la página */
.hero__brand{
  display:block;
  font-family:var(--font-display); font-weight:var(--w-med);
  font-size:clamp(3.25rem, 8.6vw, 8rem);
  line-height:.98; letter-spacing:.03em; text-transform:uppercase;
  margin-bottom:.18em;
}
/* la promesa, debajo y más pequeña: título y subtítulo de portada */
.hero__promise{
  display:block;
  font-family:var(--font-display); font-weight:var(--w-reg);
  font-size:clamp(1.375rem, 3.1vw, 2.375rem);
  line-height:1.15; letter-spacing:-.008em;
  color:var(--muted-d);
}
/* párrafo de tres líneas: menos cuerpo y más medida que cuando era una frase */
.hero__sub{
  font-family:var(--font-label); font-weight:var(--w-med);
  font-size:calc(var(--fs-lead) + 2px); line-height:1.4; letter-spacing:.004em;
  color:var(--muted-d); max-width:46ch;
}
.hero__actions{ display:flex; flex-wrap:wrap; align-items:center; gap:1.5rem; margin-top:var(--sp-7); }
.hero__honesty{ margin-top:var(--sp-5); font-size:.8125rem; color:#847B74; }

.hero__scroll{
  position:absolute; bottom:1.4rem; left:0; right:0; text-align:center;
  font-family:var(--font-label); font-size:calc(var(--fs-cap) + 2px);
  letter-spacing:.26em; text-transform:uppercase; color:#6A615A; font-weight:var(--w-sem);
  opacity:calc(1 - var(--hero-p,0) * 2.4);
}

/* ── LÁMINA clara ── */
.sheet{ position:relative; z-index:1; background:var(--paper); border-radius:var(--r-sheet) var(--r-sheet) 0 0; }

/* ── 02 · PROBLEMA ──
   El bloque se queda quieto mientras el texto se enciende y solo se suelta
   cuando está entero en negro. Lo hace con position:sticky, NO secuestrando
   la rueda: la barra de scroll sigue avanzando, el teclado, Fin y Re Pág
   siguen funcionando y nadie se queda atrapado. La clase la pone el JS, y
   solo si el contenido cabe de verdad en la pantalla. */
.problem{ position:relative; }
.problem__track{ position:relative; }
.problem__pin{ padding:clamp(5rem,12vw,9rem) 0 var(--sec-y); }
.problem__grid{ display:grid; gap:clamp(3rem,7vw,4.5rem); }

.problem.is-pinned .problem__track{ height:calc(100svh + var(--fill-runway,100svh)); }
.problem.is-pinned .problem__pin{
  position:sticky; top:0; height:100svh; padding:0;
  display:flex; flex-direction:column; justify-content:center;
}

/* ══ TEXTO QUE SE ENCIENDE AL BAJAR ══
   Los tres bloques son UN solo reguero, no tres efectos a la vez: cada
   palabra sabe su posición global —el desplazamiento del bloque (--o) más su
   índice dentro de él (--i)— sobre un total común (--total). Así se encienden
   en orden de lectura: columna izquierda, columna derecha y remate.
   Se anima color, no opacidad: una capa por palabra serían 51 capas.
   --fp vale 1 por defecto, no 0: si el JS no llega a escribirlo —falla, tarda,
   o hay movimiento reducido— la frase se ve entera en lugar de quedarse
   ilegible. El efecto es el añadido, nunca la condición para poder leer. */
[data-fill]{
  --fill-on:var(--espresso);
  --fill-off:color-mix(in srgb, var(--espresso) 24%, transparent);
}
[data-fill] span{
  color:color-mix(in srgb,
    var(--fill-on) calc(clamp(0, calc(var(--fp,1) * var(--total,1) - var(--o,0) - var(--i,0)), 1) * 100%),
    var(--fill-off));
}
@supports not (color: color-mix(in srgb, red 50%, blue)){
  [data-fill] span{
    color:var(--espresso);
    opacity:clamp(.26, calc(var(--fp,1) * var(--total,1) - var(--o,0) - var(--i,0)), 1);
  }
}

/* Las estelas se han quitado. Un anillo marrón muy desenfocado sobre papel no
   se leía como una cinta cálida: se desaturaba y quedaba una mancha gris.
   Se van también el recorte que las alojaba —recortar habría roto el sticky
   de este mismo bloque— y --sy, que no consumía nadie más.
   Queda el contexto de posicionamiento, que sí lo usan otros hijos. */
.how, .cta{ position:relative; }
.problem__stars{ display:flex; gap:.45rem; margin:var(--sp-6) 0 var(--sp-6); }
.problem__stars svg{ width:clamp(17px,2.6vw,21px); height:auto; fill:var(--gold); }
.problem__title{ max-width:14ch; }
/* Las medidas van en los elementos, no en un .wrap más estrecho: si la sección
   usa un contenedor distinto al resto, su borde izquierdo salta respecto a la
   siguiente y se lee como un fallo, no como composición. */
.problem__cols{ display:grid; gap:var(--sp-6); margin-top:clamp(3rem,7vw,4.5rem); max-width:820px; }
.problem__cols p{
  font-family:var(--font-label); font-weight:var(--w-med);
  font-size:calc(var(--fs-lead) + 3px); line-height:1.4; letter-spacing:.004em;
  color:var(--muted); text-wrap:pretty;
}
.problem__stamp{
  margin-top:clamp(3rem,7vw,4.5rem); padding-top:var(--sp-6); max-width:820px;
  border-top:1px solid var(--line);
  font-family:var(--font-display); font-size:var(--fs-d2);
  font-weight:var(--w-med); letter-spacing:-.012em;
}

/* ── 03 · PRODUCTO ──
   Sin padding superior: viene justo después de "problema" y comparten fondo.
   Dos --sec-y seguidos daban 384 px de vacío entre dos bloques del mismo color. */
.product{ padding:0 0 var(--sec-y); }
/* La tarjeta vive aquí, junto a su titular: una sola pieza en toda la sección
   en lugar de un render grande repetido debajo. */
.product__grid{ display:grid; gap:clamp(2.5rem,6vw,4rem); align-items:center; }
.product__stage{ margin:0; }
.product__stage .ncard{ max-width:min(84vw,460px); margin-inline:auto; --cast:.2; --drop-a:.22; --drop-y:30px; --drop-b:52px; }
.product__stage figcaption{ margin-top:var(--sp-6); text-align:center; font-size:.8125rem; letter-spacing:.02em; color:var(--muted); }

.finish{ margin-top:clamp(5rem,11vw,7.5rem); }
.finish__title{ font-family:var(--font-display); font-size:var(--fs-d2); font-weight:var(--w-med); letter-spacing:-.012em; margin-bottom:var(--sp-7); }
.finish__grid{ display:grid; gap:var(--sp-7); }
.finish__item{ margin:0; }
.finish__item img{ width:100%; height:auto; filter:drop-shadow(0 1px 1px rgba(42,33,29,.12)) drop-shadow(0 20px 38px rgba(42,33,29,.18)); }
.finish__item figcaption{
  font-family:var(--font-label); font-weight:var(--w-med);
  margin-top:var(--sp-5); font-size:calc(var(--fs-sm) + 2px); line-height:1.35;
  letter-spacing:.004em; color:var(--muted);
}
.finish__item figcaption span{ display:block; color:var(--text); font-weight:var(--w-med); font-size:1rem; letter-spacing:-.01em; margin-bottom:.1rem; }

/* ── 04 · INTERACCIÓN (banda espresso) ── */
.how{ background:var(--espresso); color:var(--paper); padding:var(--sec-y) 0; }
.how__grid{ display:grid; gap:clamp(3rem,8vw,5rem); align-items:center; }
/* sin marco, sin fondo, sin radio: el objeto flota sobre la banda */
.demo{ position:relative; }
.demo__scene{ position:relative; aspect-ratio:1/1; color:#C9A98F; }

.demo__phone{
  position:absolute; right:4%; top:50%; width:42%;
  aspect-ratio:1/2.03; transform:translateY(-50%);
  border:1px solid rgba(244,239,232,.22); border-radius:13% / 6.4%;
  background:#0F0C0B; overflow:hidden;
  box-shadow:0 30px 50px -26px rgba(0,0,0,.8);
}
.demo__island{
  position:absolute; z-index:3; top:2.6%; left:50%; transform:translateX(-50%);
  width:26%; height:1.8%; min-height:4px; border-radius:99px; background:#0F0C0B;
}
/* container-type: todo el interior se mide en cqw, así el móvil escala igual
   a cualquier tamaño sin una sola media query. */
.demo__screen{ position:absolute; inset:2% 2.8%; border-radius:11% / 5.4%; overflow:hidden; container-type:inline-size; }

.demo__home{
  position:absolute; inset:0; color:var(--paper);
  display:flex; flex-direction:column; padding:7% 8% 6%;
  background:
    radial-gradient(120% 55% at 28% 0%, rgba(234,225,215,.16), transparent 62%),
    linear-gradient(168deg,#4A3A31,#2A211D 52%,#17120F);
}
.demo__status{ display:flex; align-items:center; justify-content:space-between; font-size:4cqw; font-weight:var(--w-med); opacity:.85; }
.demo__status span{ display:flex; gap:1cqw; align-items:center; }
.demo__status i{ display:block; width:2.2cqw; height:2.2cqw; border-radius:1px; background:currentColor; opacity:.7; }
.demo__clock{ margin-top:9%; font-size:20cqw; line-height:1; font-weight:300; letter-spacing:-.045em; }
.demo__date{ font-size:4.2cqw; opacity:.6; margin-top:1%; }
.demo__apps{ margin-top:11%; display:grid; grid-template-columns:repeat(4,1fr); gap:7% 8%; }
.demo__apps i{ display:block; aspect-ratio:1; border-radius:27%; background:rgba(244,239,232,.14); }
.demo__apps i:nth-child(3){ background:rgba(244,239,232,.22); }
.demo__apps i:nth-child(6){ background:rgba(217,155,43,.4); }
.demo__dock{
  margin-top:auto; display:grid; grid-template-columns:repeat(4,1fr); gap:8%;
  padding:5%; border-radius:22%/34%; background:rgba(244,239,232,.12);
}
.demo__dock i{ display:block; aspect-ratio:1; border-radius:27%; background:rgba(244,239,232,.2); }

.demo__sheetui{
  position:absolute; inset:auto 0 0 0; height:78%;
  background:var(--white); color:var(--text);
  border-radius:5cqw 5cqw 0 0;
  padding:4% 8% 7%; display:flex; flex-direction:column; gap:3.4%;
  transform:translateY(102%);
  box-shadow:0 -10px 26px -14px rgba(0,0,0,.55);
}
.demo__handle{ width:18%; height:1cqw; min-height:2px; border-radius:99px; background:rgba(42,33,29,.16); align-self:center; margin-bottom:2%; }
.demo__biz{ display:flex; align-items:center; gap:3.5%; }
.demo__ava{ width:12cqw; height:12cqw; flex:0 0 auto; border-radius:50%; background:linear-gradient(150deg,#D6CBBC,#8D8580); }
.demo__bizinfo{ display:grid; gap:.4cqw; }
.demo__bizinfo b{ font-size:5.8cqw; font-weight:var(--w-sem); letter-spacing:-.02em; line-height:1.1; }
.demo__bizinfo i{ font-size:3.9cqw; font-style:normal; color:var(--muted); line-height:1.1; }
/* space-between + flex:0 0 auto: nunca se encogen, así la clip-path cae
   siempre sobre una caja cuadrada y las estrellas no se deforman. */
.demo__stars{ display:flex; justify-content:space-between; margin:1% 0 2%; }
.demo__stars i{
  flex:0 0 auto; width:16cqw; height:16cqw; background:var(--star-off);
  clip-path:polygon(50% 0,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%);
}
.demo__chips{ display:flex; gap:2.5%; }
.demo__chips b{
  font-size:3.4cqw; font-weight:var(--w-reg); color:var(--muted); white-space:nowrap;
  border:1px solid var(--line); border-radius:99px; padding:1.2cqw 2.6cqw;
}
/* flex:1 hace que el campo absorba el espacio sobrante, que es como se
   comporta un campo de comentario de verdad. Marcador de posición y texto
   escrito comparten celda para que uno releve al otro sin mover nada. */
.demo__input{
  flex:1; min-height:16cqw;
  border:1px solid var(--line); border-radius:2.2cqw;
  padding:3.4cqw 3.6cqw; font-size:3.9cqw;
  display:grid; align-content:start;
}
.demo__input > *{ grid-area:1/1; }
.demo__ph{ font-style:normal; color:#9C948D; }
/* El "tecleo" se hace tapando el texto y retirando la tapa con scaleX: solo
   transform, sin animar anchos ni provocar reflujo. */
.demo__typed{ position:relative; width:max-content; max-width:100%; white-space:nowrap; color:var(--text); }
.demo__typed::after{
  content:""; position:absolute; inset:-.25em -.5em -.25em 0;
  background:var(--white); transform-origin:right; transform:scaleX(1);
}

.demo__cta{
  display:grid; place-items:center; height:12cqw; border-radius:2.4cqw;
  background:var(--espresso); color:var(--paper);
  font-size:4.2cqw; font-weight:var(--w-sem);
}
.demo__cta > *{ grid-area:1/1; font-style:normal; font-weight:inherit; }
.demo__cta i{ opacity:0; }

.demo__card{
  position:absolute; left:2%; top:50%; width:44%;
  aspect-ratio:856/540; border-radius:3.71%/5.89%; overflow:hidden;
  box-shadow:0 0 0 1px rgba(255,255,255,.08), 0 1px 0 #B4AC9E, 0 2px 0 #8B8377,
             0 20px 30px -18px rgba(0,0,0,.8);
  transform:translate(0,-50%) rotate(-8deg);
}
.demo__card img{ width:100%; height:100%; object-fit:cover; }
.demo__waves{ position:absolute; left:41%; top:50%; width:20%; height:auto; transform:translateY(-50%); overflow:visible; opacity:0; }
.demo__waves .w{ opacity:0; transform-origin:20% 50%; }

.steps{ display:grid; gap:var(--sp-7); }
.steps__item{
  display:grid; gap:.35rem; padding-left:var(--sp-6); position:relative;
  border-left:1px solid var(--line-d); opacity:.4;
  transition:opacity .6s var(--ease);
}
.steps__num{
  position:absolute; left:0; top:.3rem; transform:translateX(-50%);
  background:var(--espresso); padding:.15rem 0;
  font-family:var(--font-label);
  font-size:calc(var(--fs-cap) + 2px); letter-spacing:.16em; font-weight:var(--w-sem); color:var(--muted-d);
  font-variant-numeric:tabular-nums;
}
.steps__title{ font-family:var(--font-display); font-size:var(--fs-d2); font-weight:var(--w-med); letter-spacing:-.012em; }
.steps__text{
  font-family:var(--font-label); font-weight:var(--w-med);
  color:var(--muted-d); font-size:calc(var(--fs-sm) + 2px); line-height:1.35;
  letter-spacing:.004em; max-width:36ch;
}

.tech{ margin-top:clamp(3.5rem,8vw,5rem); border-top:1px solid var(--line-d); }
.tech summary{
  list-style:none; cursor:pointer; padding:1.2rem 0;
  display:flex; align-items:center; gap:.6rem;
  font-size:var(--fs-sm); color:var(--muted-d); font-weight:var(--w-med);
}
.tech summary::-webkit-details-marker{ display:none; }
.tech summary::after{
  content:""; width:10px; height:10px;
  background:linear-gradient(currentColor,currentColor) center/100% 1px no-repeat,
             linear-gradient(currentColor,currentColor) center/1px 100% no-repeat;
  transition:transform .4s var(--ease);
}
.tech[open] summary::after{ transform:rotate(90deg); background-size:100% 1px, 0 100%; }
.tech__list{ padding-bottom:var(--sp-7); display:grid; gap:var(--sp-5); }
.tech__list dt{ font-family:var(--font-label); font-size:calc(var(--fs-cap) + 1px); letter-spacing:.18em; text-transform:uppercase; color:var(--muted-d); font-weight:var(--w-sem); margin-bottom:.3rem; }
.tech__list dd{ font-size:var(--fs-sm); color:rgba(244,239,232,.78); max-width:56ch; }

/* ── 05 · EL OBJETO ── */
.close{ padding:0; }
.close__track{ position:relative; }
.close__sticky{ padding:var(--sec-y) 0; }
.close__grid{ display:grid; gap:clamp(3rem,7vw,4.5rem); align-items:center; }
.close__head .display{ font-size:clamp(1.75rem, 3.2vw, 2.5rem); }
/* Lista por pasos: icono en cuadrado + texto. Es el ÚNICO sitio de la web con
   un contenedor por elemento; se justifica porque cada uno es un paso de una
   secuencia y el cuadrado marca cuánto llevas recorrido. Filete finísimo y
   sin sombras, para que no derive en la estética de plantilla. */
.close__list{ margin-top:clamp(2rem,5vw,3rem); display:grid; gap:.4rem; }
.close__item{
  display:grid; grid-template-columns:auto 1fr; gap:1rem; align-items:start;
  padding:1rem 1.1rem;
  border:1px solid transparent; border-radius:13px;
  opacity:.34;
  transition:opacity .7s var(--ease), border-color .7s var(--ease), background-color .7s var(--ease);
}
.close__item h3{ font-size:1rem; font-weight:var(--w-med); letter-spacing:-.012em; margin-bottom:.15rem; font-variant-numeric:tabular-nums; }
.close__item p{
  font-family:var(--font-label); font-weight:var(--w-med);
  font-size:calc(var(--fs-sm) + 2px); line-height:1.35; letter-spacing:.004em;
  color:var(--muted); max-width:34ch;
}
.close[data-stage="0"] .close__item[data-for="0"],
.close[data-stage="1"] .close__item[data-for="1"],
.close[data-stage="2"] .close__item[data-for="2"],
.close[data-stage="3"] .close__item[data-for="3"]{
  opacity:1; border-color:var(--line); background-color:rgba(255,255,255,.5);
}

/* El cuadrado se va cargando: --p es el avance del recorrido (0 a 1) y cada
   ficha consume su cuarto. pathLength="100" normaliza el contorno a
   porcentaje, así que el borde se dibuja solo con dashoffset: una variable
   para las cuatro, sin JS por elemento y sin animar nada de layout. */
.close__tile{ position:relative; width:40px; height:40px; flex:0 0 auto; }
.close__ring{ position:absolute; inset:0; width:100%; height:100%; }
.close__ring .t{ fill:none; stroke:var(--line-2); stroke-width:1; }
.close__ring .f{
  fill:none; stroke:var(--espresso); stroke-width:1.5; stroke-linecap:round;
  stroke-dasharray:100;
  stroke-dashoffset:calc(100 - 100 * clamp(0, calc(var(--p,0) * 4 - var(--i)), 1));
}
.close__ico{
  position:absolute; inset:0; margin:auto; width:19px; height:19px;
  fill:none; stroke:var(--espresso); stroke-width:1.4;
  stroke-linecap:round; stroke-linejoin:round; opacity:.8;
}

.close__stage{ position:relative; display:grid; place-items:center; }
.close .ncard{ max-width:min(78vw,450px); --cast:.2; --drop-a:.22; --drop-y:28px; --drop-b:50px; }
/* El scroll la presenta... */
.close .ncard__tilt{ transition:transform 1.2s var(--ease); }
.close[data-stage="0"] .ncard:not(.is-spun) .ncard__tilt{ transform:rotateX(6deg)  rotateY(-9deg) scale(.92); }
.close[data-stage="1"] .ncard:not(.is-spun) .ncard__tilt{ transform:rotateX(4deg)  rotateY(-3deg) scale(1); }
.close[data-stage="2"] .ncard:not(.is-spun) .ncard__tilt{ transform:rotateX(52deg) rotateY(-4deg) scale(.95); }
.close[data-stage="3"] .ncard:not(.is-spun) .ncard__tilt{ transform:rotateX(2deg)  rotateY(1deg)  scale(1.02); }
/* ...y en cuanto la tocas, manda la mano y ya no vuelve a los estados */
.close .ncard.is-spun .ncard__tilt{ transform:rotateX(var(--rx)) rotateY(var(--ry)); }
.close .ncard.is-grabbed .ncard__tilt{ transition:none; }
.ncard[data-spin]{ cursor:grab; touch-action:pan-y; }
.ncard[data-spin].is-grabbed{ cursor:grabbing; }
.ncard[data-spin]:focus-visible{ outline:2px solid var(--focus); outline-offset:14px; border-radius:4px; }
.ncard__hint{
  position:absolute; z-index:3; left:50%; bottom:-2.6rem; transform:translateX(-50%);
  font-family:var(--font-label); font-weight:var(--w-sem);
  font-size:var(--fs-cap); letter-spacing:.18em; text-transform:uppercase;
  color:var(--muted); white-space:nowrap;
  opacity:.7; transition:opacity .5s var(--ease);
}
.ncard[data-spin].is-spun .ncard__hint{ opacity:0; }
.close[data-stage="1"] .ncard__antenna{ opacity:.8; }
.close[data-stage="3"] .ncard__spec{ opacity:.8; }

/* como mucho dos cotas a la vez, nunca cinco etiquetas flotando */
.dim{
  position:absolute; display:flex; align-items:center; gap:.5rem;
  font-family:var(--font-label);
  font-size:calc(var(--fs-cap) + 2px); letter-spacing:.14em; color:var(--muted);
  font-variant-numeric:tabular-nums; white-space:nowrap;
  opacity:0; transition:opacity .6s var(--ease) .2s;
}
.dim i{ display:block; background:currentColor; opacity:.5; }
.dim--w{ left:0; right:0; bottom:-13%; flex-direction:column; }
.dim--w i{ width:100%; height:1px; }
.dim--h{ top:0; bottom:0; right:-15%; flex-direction:row-reverse; }
.dim--h i{ width:1px; height:100%; }
.dim--h b{ writing-mode:vertical-rl; }
.dim b{ font-weight:var(--w-med); }
.close[data-stage="0"] .dim{ opacity:1; }
/* En cuanto la giras a mano, las cotas dejarían de medir lo que se ve: se van
   con el gesto y vuelven si sueltas y la tarjeta recupera su presentación. */
.close .ncard.is-spun .dim{ opacity:0; }

/* Los cuatro cuadrados ya indican el avance: los puntos de antes sobraban. */
.close[data-stage="all"] .close__item{ opacity:1; border-color:var(--line); background-color:rgba(255,255,255,.5); }
.close[data-stage="all"] .ncard__tilt{ transform:rotateX(5deg) rotateY(-6deg); }
.close[data-stage="all"] .ncard__antenna,
.close[data-stage="all"] .dim{ opacity:.8; }

/* ── 06 · ECOSISTEMA (banda crema) ──
   Producto principal grande, futuros pequeños. Sin cuadrícula de cajas. */
.eco{ background:var(--cream); padding:var(--sec-y) 0; }
.eco__layout{ display:grid; gap:clamp(3rem,7vw,4.5rem); align-items:center; }
.eco__lead{ margin:0; }
.eco__lead img{ width:100%; filter:drop-shadow(0 1px 1px rgba(42,33,29,.12)) drop-shadow(0 26px 44px rgba(42,33,29,.18)); }
.eco__lead figcaption{ margin-top:var(--sp-5); display:flex; flex-wrap:wrap; align-items:baseline; gap:.6rem 1rem; }
.eco__lead b{ font-size:1.0625rem; font-weight:var(--w-med); letter-spacing:-.014em; }
.eco__lead i{ font-family:var(--font-label); font-weight:var(--w-med); font-style:normal; font-size:calc(var(--fs-sm) + 2px); letter-spacing:.004em; color:var(--muted); }

.eco__next{ border-top:1px solid var(--line); }
.eco__next li{ display:grid; gap:.15rem; padding:1.25rem 0; border-bottom:1px solid var(--line); }
.eco__next h3{ font-size:1rem; font-weight:var(--w-med); letter-spacing:-.012em; }
.eco__next p{
  font-family:var(--font-label); font-weight:var(--w-med);
  font-size:calc(var(--fs-sm) + 2px); line-height:1.35; letter-spacing:.004em;
  color:var(--muted); max-width:32ch;
}
/* "Próximamente" discreto: microtexto, no una pastilla con borde */
.eco__tag{ font-family:var(--font-label); font-size:calc(var(--fs-cap) + 1px); letter-spacing:.2em; text-transform:uppercase; color:var(--muted); opacity:.8; margin-top:.2rem; font-weight:var(--w-sem); }
.eco__foot{ margin-top:clamp(3rem,7vw,4rem); font-size:var(--fs-sm); color:var(--muted); }

/* ── 07 · PARA NEGOCIOS: lista editorial, sin iconos ni cajas ── */
.uses{ padding:var(--sec-y) 0; }
.uses__list{ border-top:1px solid var(--line); }
.uses__row{
  display:flex; align-items:baseline; justify-content:space-between; gap:1.5rem;
  padding:1.15rem 0; border-bottom:1px solid var(--line);
}
.uses__kind{ font-size:1.0625rem; font-weight:var(--w-med); letter-spacing:-.014em; }
.uses__where{ font-family:var(--font-label); font-weight:var(--w-med); font-size:calc(var(--fs-sm) + 2px); letter-spacing:.004em; color:var(--muted); text-align:right; }

/* ── FAQ ── */
.faq{ padding:0 0 var(--sec-y); }
/* medida de lectura cómoda sin cambiar de contenedor */
.faq__list{ border-top:1px solid var(--line); max-width:820px; }
.qa{ border-bottom:1px solid var(--line); }
.qa summary{
  list-style:none; cursor:pointer;
  display:flex; align-items:baseline; justify-content:space-between; gap:var(--sp-5);
  padding:1.25rem 0; font-family:var(--font-label); font-size:1.1875rem;
  font-weight:var(--w-sem); letter-spacing:.004em;
}
.qa summary::-webkit-details-marker{ display:none; }
.qa summary::after{
  content:""; align-self:center; flex:0 0 auto; width:11px; height:11px;
  background:linear-gradient(currentColor,currentColor) center/100% 1px no-repeat,
             linear-gradient(currentColor,currentColor) center/1px 100% no-repeat;
  transition:transform .4s var(--ease); opacity:.5;
}
.qa[open] summary::after{ transform:rotate(90deg); background-size:100% 1px, 0 100%; }
.qa__body{ padding-bottom:1.4rem; color:var(--muted); font-size:var(--fs-sm); max-width:58ch; }
.qa__body a{ color:var(--text); text-underline-offset:3px; }

/* ── 08 · CTA (banda espresso a sangre, sin panel flotante) ── */
.cta{ background:var(--espresso); color:var(--paper); padding:var(--sec-y) 0; }

/* Rótulo de cierre: dos líneas en versales pesadas con una línea manuscrita
   encajada entre ellas. Es el único sitio de la web con peso alto y con dos
   familias más: se permite aquí porque es un remate, no un patrón. */
.claim{
  display:grid; justify-items:start;
  font-family:"Anton", var(--font-ui);
  font-weight:400; text-transform:uppercase;
  font-size:clamp(2.4rem, 8.4vw, 6rem);
  line-height:.9; letter-spacing:-.005em;
  color:var(--paper);
  margin-bottom:clamp(3.5rem,9vw,6rem);
}
.claim__script{
  position:relative; z-index:1;
  font-family:"Caveat", "Segoe Script", cursive;
  font-weight:700; text-transform:none;
  /* la manuscrita necesita más cuerpo para pesar lo mismo que las versales */
  font-size:1.06em; line-height:.78; letter-spacing:0;
  color:var(--claim-red);
  /* se mete entre las dos líneas y las pisa un poco, como en un rótulo pintado */
  margin:-.13em 0 -.09em .32em;
  transform:rotate(-2.2deg);
}
/* la primera línea entra un pelo, la tercera vuelve al margen: el bloque deja
   de ser un rectángulo perfecto y respira como una composición dibujada */
.claim__hit:first-child{ margin-left:.05em; }

.cta__mark{ width:36px; height:36px; margin-bottom:var(--sp-6); }
.cta__title{
  font-family:var(--font-display); font-size:var(--fs-d2);
  font-weight:var(--w-med); letter-spacing:-.012em; line-height:1.2;
}
.cta__sub{
  font-family:var(--font-label); font-weight:var(--w-med);
  margin-top:var(--sp-4); color:var(--muted-d);
  font-size:calc(var(--fs-lead) + 3px); line-height:1.4; letter-spacing:.004em; max-width:34ch;
}

/* ── FOOTER ── */
.foot{ background:var(--deep); color:var(--paper); padding:var(--sp-9) 0 var(--sp-6); }
.foot__top{ display:grid; gap:.7rem; padding-bottom:var(--sp-8); border-bottom:1px solid var(--line-d); }
.foot__logo{ display:inline-flex; align-items:center; gap:.6rem; width:max-content; text-decoration:none; font-size:.8125rem; font-weight:var(--w-med); letter-spacing:.16em; }
.foot__logo img{ width:24px; height:24px; filter:brightness(1.95) saturate(.8); }
.foot__claim{ color:var(--muted-d); font-size:var(--fs-sm); max-width:40ch; }
.foot__cols{ display:grid; gap:var(--sp-6); padding:var(--sp-8) 0; }
.foot__h{ font-family:var(--font-label); font-size:calc(var(--fs-cap) + 1px); letter-spacing:.2em; text-transform:uppercase; color:var(--muted-dd); font-weight:var(--w-sem); margin-bottom:var(--sp-5); }
.foot__col li + li{ margin-top:.7rem; }
.foot__col a{ text-decoration:none; font-size:var(--fs-sm); color:var(--muted-d); transition:color .3s var(--ease); }
.foot__col a:hover{ color:var(--paper); }
.foot__bottom{ display:grid; gap:var(--sp-4); padding-top:var(--sp-6); border-top:1px solid var(--line-d); }
.foot__legal,.foot__copy{ font-size:.75rem; line-height:1.6; color:var(--muted-dd); max-width:68ch; }

/* ─────────────────────────── 8 · MOVIMIENTO ───────────────────────────
   Tres entradas y nada más. Desplazamientos pequeños, tiempos largos.
   ══════════════════════════════════════════════════════════════════════ */
.js [data-intro]{
  opacity:0; transform:translateY(12px);
  transition:opacity 1s var(--ease), transform 1s var(--ease);
  transition-delay:calc(var(--d,0) * 120ms);
}
.js.is-ready [data-intro]{ opacity:1; transform:none; }

.js .hero__title{ opacity:1; transform:none; }
.js .hero__title .mask__i{
  transform:translateY(106%);
  transition:transform 1.15s var(--ease);
  transition-delay:calc(var(--d,0) * 120ms);
}
.js .hero__promise .mask__i{ transition-delay:calc(var(--d,0) * 120ms + 200ms); }
.js.is-ready .hero__title .mask__i{ transform:none; }

.js [data-reveal="up"]{
  opacity:0; transform:translateY(10px);
  transition:opacity .85s var(--ease), transform .85s var(--ease);
  transition-delay:calc(var(--d,0) * 90ms);
}
.js [data-reveal="up"].is-in{ opacity:1; transform:none; }

.js [data-reveal="scale"]{
  opacity:0; transform:scale(.985);
  transition:opacity 1.1s var(--ease), transform 1.1s var(--ease);
  transition-delay:calc(var(--d,0) * 100ms);
}
.js [data-reveal="scale"].is-in{ opacity:1; transform:none; }

.js [data-reveal="mask"] .mask__i{
  transform:translateY(106%);
  transition:transform 1.05s var(--ease);
  transition-delay:calc(var(--d,0) * 70ms);
}
.js [data-reveal="mask"] .mask:nth-child(2) .mask__i{ transition-delay:calc(var(--d,0) * 70ms + 100ms); }
.js [data-reveal="mask"] .mask:nth-child(3) .mask__i{ transition-delay:calc(var(--d,0) * 70ms + 200ms); }
.js [data-reveal="mask"].is-in .mask__i{ transform:none; }

/* El hero es sticky: se queda en el árbol de composición toda la página.
   En cuanto la lámina lo tapa, dejamos de pintarlo. */
.hero.is-covered .hero__grid,
.hero.is-covered .hero__light,
.hero.is-covered .hero__scroll{ visibility:hidden; }

/* ── Demostración NFC: 8 s ──
   Las animaciones SOLO existen dentro de .is-playing. Con animation-play-state
   la línea de tiempo seguía avanzando por dentro y al llegar a la sección la
   secuencia ya iba por "Valorar". Así arranca siempre desde el primer paso.
   Fuera de vista, los estados base son el "antes de tocar": tarjeta en su
   sitio, hoja cerrada, ondas invisibles. */
.how.is-playing .demo__card   { animation:dCard 8s var(--ease) infinite both; }
.how.is-playing .demo__waves  { animation:dWaves 8s linear infinite both; }
.how.is-playing .demo__waves .w1{ animation:dPulse 8s var(--ease) infinite both; }
.how.is-playing .demo__waves .w2{ animation:dPulse 8s var(--ease) .12s infinite both; }
.how.is-playing .demo__waves .w3{ animation:dPulse 8s var(--ease) .24s infinite both; }
.how.is-playing .demo__sheetui{ animation:dSheet 8s var(--ease) infinite both; }
.how.is-playing .demo__screen { animation:dScreen 8s var(--ease) infinite both; }
@keyframes dCard{
  0%       { transform:translate(-46%,-50%) rotate(-15deg) scale(.94); opacity:0; }
  6%       { opacity:1; }
  17%      { transform:translate(2%,-50%) rotate(-8deg) scale(1); opacity:1; }
  20%,92%  { transform:translate(0%,-50%) rotate(-8deg) scale(1); opacity:1; }
  96%,100% { transform:translate(-46%,-50%) rotate(-15deg) scale(.94); opacity:0; }
}
@keyframes dWaves{ 0%,16%{opacity:0} 17%,40%{opacity:1} 44%,100%{opacity:0} }
@keyframes dPulse{
  0%,16%   { opacity:0; transform:scale(.55); }
  20%      { opacity:1; transform:scale(1); }
  30%      { opacity:0; transform:scale(1.18); }
  31%,100% { opacity:0; transform:scale(.55); }
}
@keyframes dScreen{ 0%,20%{filter:brightness(.95)} 26%,92%{filter:brightness(1)} 96%,100%{filter:brightness(.95)} }
@keyframes dSheet{ 0%,22%{transform:translateY(102%)} 32%,92%{transform:translateY(0)} 96%,100%{transform:translateY(102%)} }

/* ── El paso 03 se completa: valora, escribe y publica ──
   Sin esto la secuencia se quedaba con la hoja abierta y no se notaba que
   llegaba al final. Ahora hay un desenlace y la hoja se cierra después.  */
.how.is-playing .demo__stars i:nth-child(1){ animation:dS1 8s steps(1,end) infinite both; }
.how.is-playing .demo__stars i:nth-child(2){ animation:dS2 8s steps(1,end) infinite both; }
.how.is-playing .demo__stars i:nth-child(3){ animation:dS3 8s steps(1,end) infinite both; }
.how.is-playing .demo__stars i:nth-child(4){ animation:dS4 8s steps(1,end) infinite both; }
.how.is-playing .demo__stars i:nth-child(5){ animation:dS5 8s steps(1,end) infinite both; }
@keyframes dS1{ 0%{background:var(--star-off)} 37%{background:var(--gold)} 94%{background:var(--star-off)} }
@keyframes dS2{ 0%{background:var(--star-off)} 39%{background:var(--gold)} 94%{background:var(--star-off)} }
@keyframes dS3{ 0%{background:var(--star-off)} 41%{background:var(--gold)} 94%{background:var(--star-off)} }
@keyframes dS4{ 0%{background:var(--star-off)} 43%{background:var(--gold)} 94%{background:var(--star-off)} }
@keyframes dS5{ 0%{background:var(--star-off)} 45%{background:var(--gold)} 94%{background:var(--star-off)} }

.how.is-playing .demo__ph{ animation:dPh 8s linear infinite both; }
@keyframes dPh{ 0%,47%{opacity:1} 50%,94%{opacity:0} 96%,100%{opacity:1} }

/* steps(28): 28 saltos a lo largo del tramo de escritura, un carácter cada uno */
.how.is-playing .demo__typed::after{ animation:dType 8s steps(28,end) infinite both; }
@keyframes dType{ 0%,50%{transform:scaleX(1)} 64%,94%{transform:scaleX(0)} 96%,100%{transform:scaleX(1)} }

.how.is-playing .demo__cta  { animation:dPress 8s var(--ease) infinite both; }
.how.is-playing .demo__cta b{ animation:dLabelOut 8s steps(1,end) infinite both; }
.how.is-playing .demo__cta i{ animation:dLabelIn  8s steps(1,end) infinite both; }
@keyframes dPress{ 0%,69%{transform:scale(1)} 71%{transform:scale(.96)} 74%,100%{transform:scale(1)} }
@keyframes dLabelOut{ 0%{opacity:1} 72%{opacity:0} 96%{opacity:1} }
@keyframes dLabelIn { 0%{opacity:0} 72%{opacity:1} 96%{opacity:0} }

.how.is-playing .steps__item[data-step="1"]{ animation:st1 8s linear infinite both; }
.how.is-playing .steps__item[data-step="2"]{ animation:st2 8s linear infinite both; }
.how.is-playing .steps__item[data-step="3"]{ animation:st3 8s linear infinite both; }
@keyframes st1{ 0%,18%{opacity:1; border-color:rgba(244,239,232,.5)} 24%,100%{opacity:.4; border-color:var(--line-d)} }
@keyframes st2{ 0%,17%{opacity:.4; border-color:var(--line-d)} 20%,30%{opacity:1; border-color:rgba(244,239,232,.5)} 36%,100%{opacity:.4; border-color:var(--line-d)} }
@keyframes st3{ 0%,29%{opacity:.4; border-color:var(--line-d)} 34%,92%{opacity:1; border-color:rgba(244,239,232,.5)} 96%,100%{opacity:.4; border-color:var(--line-d)} }

/* ── prefers-reduced-motion ── */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
  .js [data-reveal],.js [data-intro]{ opacity:1 !important; transform:none !important; }
  .js .mask__i{ transform:none !important; }
  /* estado final legible: reseña escrita y publicada, sin nada en movimiento */
  .demo__card{ transform:translate(0,-50%) rotate(-8deg) !important; opacity:1 !important; }
  .demo__sheetui{ transform:none !important; }
  .demo__waves{ opacity:1 !important; }
  .demo__waves .w{ opacity:.5 !important; transform:none !important; }
  .demo__stars i{ background:var(--gold) !important; }
  .demo__ph{ opacity:0 !important; }
  .demo__typed::after{ transform:scaleX(0) !important; }
  .demo__cta b{ opacity:0 !important; }
  .demo__cta i{ opacity:1 !important; }
  .steps__item{ opacity:1 !important; border-color:var(--line-d) !important; }
  .close .ncard__tilt{ transform:rotateX(4deg) rotateY(-5deg) !important; }
  .close .ncard__antenna,.close .dim{ opacity:.8 !important; }
  /* sin movimiento: los cuatro cuadrados salen completos y las fichas activas */
  .close__item{ opacity:1 !important; border-color:var(--line) !important; }
  .close__ring .f{ stroke-dashoffset:0 !important; }
}

/* ── Banner de cookies (solo si CONFIG.cookieBanner = true).
   Aceptar y Rechazar comparten tamaño y jerarquía: requisito de la AEPD. ── */
.cookiebar{
  position:fixed; z-index:150; left:var(--gutter); right:var(--gutter); bottom:var(--gutter);
  max-width:620px; margin-inline:auto; display:grid; gap:var(--sp-4);
  background:var(--deep); color:var(--paper);
  border-radius:var(--r-lg); padding:var(--sp-5);
  box-shadow:0 24px 60px -20px rgba(0,0,0,.5);
}
.cookiebar__text{ font-size:var(--fs-sm); color:var(--muted-d); }
.cookiebar__text a{ color:var(--paper); text-underline-offset:3px; }
.cookiebar__actions{ display:grid; grid-template-columns:1fr 1fr; gap:.6rem; }
.cookiebar__actions button{
  min-height:46px; border-radius:var(--r); font-size:var(--fs-sm); font-weight:var(--w-sem);
  background:transparent; color:var(--paper); border:1px solid var(--paper);
  transition:background .3s var(--ease), color .3s var(--ease);
}
.cookiebar__actions button:hover{ background:var(--paper); color:var(--espresso); }

/* ───────────────────────── 9 · PÁGINAS LEGALES ───────────────────────── */
.doc{ background:var(--paper); color:var(--text); padding:9rem 0 var(--sec-y); }
.doc__inner{ max-width:680px; }
.doc h1{ font-family:var(--font-display); font-size:clamp(1.9rem,5vw,2.75rem); font-weight:var(--w-med); letter-spacing:-.014em; line-height:1.12; }
.doc__meta{ margin-top:var(--sp-4); font-size:.8125rem; color:var(--muted); }
.doc h2{ font-family:var(--font-display); font-size:clamp(1.125rem,3vw,1.375rem); font-weight:var(--w-med); letter-spacing:-.008em; margin:var(--sp-8) 0 var(--sp-3); }
.doc h3{ font-size:1rem; font-weight:var(--w-med); margin:var(--sp-5) 0 var(--sp-2); }
.doc p, .doc li{ color:var(--ink-soft); font-size:var(--fs-sm); }
.doc p + p{ margin-top:var(--sp-3); }
.doc ul{ list-style:disc; padding-left:1.25rem; margin-top:var(--sp-3); display:grid; gap:.4rem; }
.doc a{ color:var(--focus); text-underline-offset:3px; }
.doc table{ width:100%; border-collapse:collapse; margin-top:var(--sp-4); font-size:.875rem; }
.doc th,.doc td{ text-align:left; padding:.7rem .6rem; border-bottom:1px solid var(--line); vertical-align:top; }
.doc th{ font-weight:var(--w-med); }
.doc__back{ display:inline-flex; align-items:center; gap:.4rem; margin-top:var(--sp-8); font-size:var(--fs-sm); text-decoration:none; color:var(--muted); }
.doc__back:hover{ color:var(--text); }
.note{ border-left:2px solid var(--gold); background:transparent; padding:var(--sp-3) 0 var(--sp-3) var(--sp-5); margin-top:var(--sp-5); }
.note p{ font-size:.8125rem; color:var(--ink-soft); }

/* ───────────────────────────── BREAKPOINTS ───────────────────────────── */
@media (min-width:640px){
  .problem__cols{ grid-template-columns:repeat(2,1fr); gap:var(--sp-7); }
  .finish__grid{ grid-template-columns:repeat(2,1fr); }
  .foot__cols{ grid-template-columns:repeat(3,1fr); }
  .uses__list{ display:grid; grid-template-columns:repeat(2,1fr); column-gap:var(--sp-8); }
  .tech__list{ grid-template-columns:repeat(2,1fr); gap:var(--sp-5) var(--sp-7); }
}

/* Tablet: se reequilibran proporciones antes de llegar al escritorio */
@media (min-width:820px){
  .product__grid{ grid-template-columns:minmax(0,1fr) minmax(0,.92fr); }
  .how__grid{ grid-template-columns:minmax(0,1fr) minmax(0,.9fr); }
  .eco__layout{ grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr); }
}

@media (min-width:960px){
  .nav__links{ display:flex; }
  .nav__cta{ display:inline-flex; }
  .nav__burger{ display:none; }
  .menu{ display:none; }

  .hero{ padding:7.5rem 0 6.5rem; }
  /* Sin tarjeta, el hero es solo marca: una columna de texto y el monograma
     detrás. La medida se limita en el bloque, no partiendo la retícula. */
  .hero__copy{ max-width:44rem; }
  .hero__glyph{ right:-14%; top:44%; height:min(92svh, 760px); opacity:.20; }

  /* acercamiento por scroll: 4 estados en 340vh de recorrido */
  .close__track{ height:340vh; }
  .close__sticky{ position:sticky; top:0; height:100svh; display:flex; flex-direction:column; justify-content:center; padding:5rem 0 3rem; }
  .close__grid{ grid-template-columns:minmax(0,1fr) minmax(0,.9fr); gap:var(--sp-8); }
  .close__head{ order:1; }
  .close__stage{ order:2; }

  .foot__cols{ grid-template-columns:1.5fr repeat(3,1fr); }
  .foot__bottom{ grid-template-columns:1fr auto; align-items:end; }
}

@media (min-width:1240px){
  .hero__grid{ gap:var(--sp-10); }
  .close .ncard{ max-width:520px; }
}

/* Pantallas grandes: si el contenedor no crece, la página se ve pequeña y
   perdida en el centro. Crece la retícula, no el tamaño de letra. */
@media (min-width:1700px){
  :root{ --maxw:1480px; --gutter:4rem; }
  .close .ncard{ max-width:580px; }
}

/* Pantallas bajas y apaisadas: el hero no debe forzar 100svh */
@media (max-height:640px) and (min-width:960px){
  .hero{ min-height:auto; padding:8rem 0 5rem; }
  .close__sticky{ height:auto; padding:6rem 0; }
  .close__track{ height:auto; }
}
