/* ============================================================
   SAMNA · sistema visual
   Lenguaje Apple sobre la paleta de marca (crema #FBF0E4, tipografía grande y muy
   apretada, píldoras, tarjetas sin borde, nav translúcida, mucho
   aire) con un único acento: verde esmeralda profundo.
   Sin serifas. Fuentes autoalojadas, cero peticiones a terceros.

   Contraste comprobado sobre blanco: verde 5.19, gris secundario
   7.91, gris terciario 5.07. Todos pasan AA para texto normal.
   ============================================================ */

/* Sin @import de fonts.css: cada página lo enlaza en su <head>, antes que
   este fichero. Con el @import, la fuente no se descubría hasta terminar de
   bajar ESTE CSS y luego el otro: dos idas y vueltas enteras antes de pedir
   la letra, y en 4G el primer pintado esperaba por ello. */

:root{
  /* ═══════════ PALETA DE MARCA (la que manda Irene) ═══════════
     VERDE #32442F · ÁMBAR #E09132 · TAUPE #A58E74 · ARENA #F4DAB8
     CREMA #FBF0E4 · OLIVA #7E7B4D · BRUMA #D9DACB

     Se midió el contraste de los siete antes de repartirlos, y el
     resultado manda sobre el gusto:

       VERDE sobre CREMA .... 9.33  → el único que vale para texto
       OLIVA sobre CREMA .... 3.87  → sólo texto grande (>=24px)
       TAUPE sobre CREMA .... 2.78  → NO vale para texto
       ÁMBAR sobre CREMA .... 2.26  → NO vale para texto

     Así que ÁMBAR y TAUPE no llevan una sola letra encima de fondo
     claro: son formas, filetes, rellenos e iconos grandes. Poner un
     enlace en ámbar sobre crema es ilegible, y este público tiene
     niebla mental y migraña: aquí un texto flojo no es un detalle
     estético, es alguien que abandona la página.
     ═══════════════════════════════════════════════════════════ */

  --crema:#FBF0E4;
  --arena:#F4DAB8;
  --bruma:#D9DACB;
  --verde:#32442F;
  --ambar:#E09132;
  --taupe:#A58E74;
  --oliva:#7E7B4D;

  /* Los nombres de siempre siguen existiendo y ahora apuntan a la
     paleta nueva: así el cambio de marca no obliga a repasar 3.000
     líneas de CSS buscando cada uso. */
  --white:var(--crema);
  --gray:#F7EEE4;
  --gray-2:var(--bruma);

  /* Tinta. Todo el texto es VERDE sobre fondos claros: es el único
     que pasa. Los tres niveles se separan con opacidad del mismo
     verde y no con grises, para que no aparezca un gris frío en una
     paleta cálida. */
  --ink:#32442F;
  --ink-2:#4A5A46;
  --ink-3:#5E6E59;
  --line:#DCCFBC;

  /* Secciones oscuras: verde profundo, no negro. */
  --black:#32442F;
  --on-black:#FBF0E4;
  --on-black-2:#CFC5B2;

  /* El acento sigue llamándose green por compatibilidad, pero es el
     VERDE de marca. Sobre verde oscuro sube a ÁMBAR, que ahí sí
     rinde (4.13) y es el color que da carácter a la marca. */
  --green:#32442F;
  --green-2:#3E5439;
  --green-soft:#F0E6D6;
  --green-ring:rgba(50,68,47,.18);
  /* El ámbar de marca sobre el verde da 4.13: vale para un titular y no
     para un enlace de 14px. Se sube la luminosidad sin tocar el tono.
     #E39B46 daba 4,51 contra el verde PLANO, pero la sección lleva degradado,
     halo ámbar y grano, y medido sobre los píxeles de verdad detrás del
     antetítulo se quedaba en 3,5-4,0. #EBB779 da 4,5 en el peor píxel.
     Sigue siendo el mismo ámbar, un punto más claro. */
  --green-on-black:#EBB779;

  /* Ámbar y taupe, sólo para lo que NO es texto. */
  --acento:#E09132;
  --acento-suave:rgba(224,145,50,.16);
  --taupe-linea:rgba(165,142,116,.45);

  --sans:'Inter Tight', -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', sans-serif;

  --wrap:1024px;
  --wrap-wide:1180px;

  --pill:980px;
  --radius:18px;
  --radius-lg:28px;

  --shadow:0 4px 24px rgba(0,0,0,.06);
  --shadow-md:0 8px 30px rgba(0,0,0,.09);
  --shadow-lg:0 12px 44px rgba(0,0,0,.12);

  --nav-h:48px;
  --ease:cubic-bezier(.4,0,.2,1);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* Sin scroll-behavior global a propósito: un salto de 8.000 px suave es
   el peor estímulo posible para este público. Lo decide samna.js según
   la distancia (cerca = suave, lejos = salto seco). */
html{
  -webkit-text-size-adjust:100%;
  scroll-padding-top:calc(var(--nav-h) + 20px);
  /* 'clip' y no 'hidden': hidden en el html rompe position:sticky
     y la nav dejaría de quedarse arriba. */
  overflow-x:clip;
}

body{
  background:var(--white); color:var(--ink);
  font-family:var(--sans);
  font-size:17px; line-height:1.47;
  letter-spacing:-.012em;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  /* Aquí NO va overflow-x:hidden. Con el html en 'clip', el overflow del body
     ya no pasa al viewport: el body se convertía en su propia caja de scroll
     (overflow-y calculaba 'auto'), una caja que nunca se desplaza, y la nav
     sticky se anclaba a ella y se iba con la página. Lo único que se salía
     por los lados era el halo del hero, y ése se recorta en su sección. */
}

img,svg{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
::selection{background:var(--green);color:var(--crema)}

:focus-visible{outline:3px solid var(--green);outline-offset:3px;border-radius:6px}
/* En las secciones oscuras el fondo ES el verde del anillo (1,0-1,14:1): el
   foco no se veía. Crema sobre verde da 8,2:1. */
.sec-ink :focus-visible{outline-color:var(--on-black)}
.skip{position:absolute;left:-9999px;top:0;background:var(--ink);color:var(--crema);padding:12px 20px;z-index:300;border-radius:0 0 8px 0}
.skip:focus{left:0;top:0}

.wrap{width:100%;max-width:var(--wrap);margin:0 auto;padding:0 22px}
.wrap-wide{max-width:var(--wrap-wide)}
.narrow{max-width:700px;margin-left:auto;margin-right:auto}

/* ---------- Tipografía ---------- */

h1,h2,h3,h4{font-weight:600;letter-spacing:-.022em;line-height:1.08}
h1{font-size:clamp(40px,6.4vw,80px);letter-spacing:-.032em;line-height:1.05;text-wrap:balance}
h2{font-size:clamp(32px,4.6vw,56px);letter-spacing:-.028em;line-height:1.07;text-wrap:balance}
h3{font-size:clamp(20px,2vw,24px);letter-spacing:-.018em;line-height:1.2}

p{color:var(--ink)}

.lead{
  font-size:clamp(19px,1.9vw,24px);
  line-height:1.38; letter-spacing:-.016em;
  color:var(--ink-2); font-weight:400;
  text-wrap:pretty;
}

.tiny{font-size:13px;line-height:1.45;color:var(--ink-3);letter-spacing:-.004em}
.muted{color:var(--ink-3);font-weight:400}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

/* El antetítulo lleva un filete ámbar delante.
   El ámbar es el color que da carácter a esta marca, pero no puede llevar
   texto: sobre crema da 2.26 y es ilegible. Así que se le da el trabajo de
   marcar dónde empieza cada sección — un gráfico, no una letra— y con eso
   pasa de estar en el 0,01% de la página a verse en cada bloque. */
.kicker{
  display:block;
  font-size:15px; font-weight:600;
  color:var(--green);
  letter-spacing:-.01em;
  margin-bottom:10px;
}
.sec-head .kicker::before{
  content:'';display:block;
  width:34px; height:3px; border-radius:2px;
  background:var(--acento);
  margin:0 auto 14px;
}
/* Cuando la sección no va centrada, el filete tampoco. */
.sec-head.izq .kicker::before{margin-left:0}

.link{color:var(--green);font-size:17px;letter-spacing:-.012em;display:inline-flex;align-items:center;gap:3px}
.link:hover{text-decoration:underline}
.link::after{content:'›';font-size:1.25em;line-height:0;transform:translateY(.02em)}

/* ---------- Secciones ---------- */

section{padding:clamp(76px,10vw,132px) 0}
.sec-gray{background:var(--gray)}
.sec-ink{background:var(--black);color:var(--on-black)}
.sec-ink h1,.sec-ink h2,.sec-ink h3{color:var(--white)}
.sec-ink p,.sec-ink .lead,.sec-ink .tiny{color:var(--on-black-2)}
.sec-ink .kicker{color:var(--green-on-black)}
.tight{padding:clamp(60px,7vw,92px) 0}

.sec-head{max-width:760px;margin:0 auto clamp(44px,5vw,68px);text-align:center}
.sec-head .lead{margin-top:18px}
.sec-head.left{margin-left:0;text-align:left}

/* ---------- Nav ---------- */

.demo-bar{
  background:var(--black); color:var(--on-black-2);
  font-size:12px; letter-spacing:-.004em;
  text-align:center; padding:9px 16px;
}

.nav{
  position:sticky; top:0; z-index:100;
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid rgba(0,0,0,.07);
  transition:background .3s var(--ease), border-color .3s var(--ease);
}
/* Al bajar se opaca y marca el borde: el gesto de apple.com. */
.nav.scrolled{background:rgba(255,255,255,.9);border-bottom-color:rgba(0,0,0,.12)}

.nav .row{display:flex;align-items:center;justify-content:space-between;height:var(--nav-h);gap:20px}
.nav .brand{font-size:18px;font-weight:600;letter-spacing:-.022em;white-space:nowrap}
.nav .brand span{color:var(--ink-3);font-weight:400;font-size:14px;letter-spacing:-.01em}
.nav nav ul{display:flex;gap:clamp(18px,3vw,34px);list-style:none}
/* 14 px y no 12: es la navegación principal y el público lee con presbicia.
   Medido de 821 a 1280 px: cabe sin tocar la marca ni el botón. */
.nav nav a{font-size:14px;color:var(--ink);opacity:.85;letter-spacing:-.004em;transition:color .2s var(--ease),opacity .2s var(--ease)}
.nav nav a:hover{opacity:1;color:var(--green)}

/* ---------- Botones ---------- */

.btn{
  display:inline-flex; align-items:center; justify-content:center;
  font-family:inherit; font-size:17px; font-weight:400;
  letter-spacing:-.012em;
  padding:12px 23px;
  border:1px solid transparent; border-radius:var(--pill);
  cursor:pointer;
  transition:background .22s var(--ease), color .22s var(--ease),
             transform .12s var(--ease), box-shadow .22s var(--ease), opacity .2s;
  white-space:nowrap; text-align:center;
}
.btn:active{transform:scale(.975)}
.btn[disabled]{opacity:.55;cursor:default;transform:none}

.btn-primary{background:var(--green);color:var(--crema);box-shadow:0 1px 2px rgba(50,68,47,.2)}
.btn-primary:hover{background:var(--green-2);box-shadow:0 4px 14px rgba(50,68,47,.28)}

.btn-ghost{background:transparent;color:var(--green);border-color:var(--green)}
.btn-ghost:hover{background:var(--green);color:var(--crema)}

.btn-ink{background:var(--white);color:var(--ink)}
.btn-ink:hover{background:var(--gray)}

.btn-sm{font-size:14px;padding:7px 16px}
.btn-block{width:100%}

/* ---------- Hero ---------- */

.hero{
  padding:clamp(68px,9vw,124px) 0 clamp(56px,7vw,96px);
  text-align:center;
  position:relative;
  isolation:isolate;
  /* El halo mide un 140 % del ancho y se sale por los lados: en el móvil
     ensanchaba la página a 469 px. 'clip' sólo en horizontal, para que siga
     asomando por arriba, y sin crear caja de scroll (hidden sí la crea). */
  overflow-x:clip;
}
/* Halo verde muy tenue: da profundidad sin usar ni una foto. */
.hero::before{
  content:'';position:absolute;z-index:-1;
  top:-160px;left:50%;transform:translateX(-50%);
  width:min(1100px,140%);height:620px;
  background:radial-gradient(ellipse at 50% 40%,
              rgba(50,68,47,.09) 0%,
              rgba(50,68,47,.035) 38%,
              rgba(50,68,47,0) 70%);
  pointer-events:none;
}
.hero .lead{max-width:620px;margin:22px auto 0}
.hero-cta{display:flex;flex-wrap:wrap;gap:14px;justify-content:center;margin-top:34px}

/* Dos filas para que TODAS las etiquetas queden alineadas aunque
   un valor ocupe dos líneas ("4 semanas" junto a "10"). */
.hero-facts{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:20px;margin:clamp(56px,7vw,88px) auto 0;
  max-width:800px;
}
.hero-facts .fact{text-align:center;display:grid;grid-template-rows:1fr auto;gap:8px}
.hero-facts .v{
  align-self:end;
  font-size:clamp(26px,2.9vw,38px);font-weight:600;
  letter-spacing:-.028em;line-height:1.08;
  font-variant-numeric:tabular-nums;text-wrap:balance;
}
.hero-facts .l{font-size:14px;color:var(--ink-3);letter-spacing:-.004em}

/* ---------- Rejillas y tarjetas ---------- */

.grid{display:grid;gap:clamp(18px,2.4vw,26px)}
.g2{grid-template-columns:repeat(2,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}

.card{
  background:var(--gray);
  border-radius:var(--radius-lg);
  padding:clamp(26px,3.2vw,38px);
  transition:transform .3s var(--ease), box-shadow .3s var(--ease);
}
.card h3{margin-bottom:10px}
.card p{color:var(--ink-2);font-size:16px}

.sec-ink .card{background:#2A3A27}
.sec-ink .card p{color:var(--on-black-2)}
.sec-gray .card{background:var(--white);box-shadow:var(--shadow)}


/* ---------- Listas con marca ---------- */

.ticks{list-style:none;display:grid;gap:14px}
.ticks li{
  position:relative;padding-left:31px;
  font-size:17px;color:var(--ink-2);letter-spacing:-.012em;
}
.ticks li::before{
  content:'';position:absolute;left:0;top:.4em;
  width:17px;height:9px;
  /* En ámbar: son la lista de "si te reconoces en esto", el momento en que
     ella se está viendo reflejada. Que el ojo las recorra es exactamente lo
     que interesa aquí. */
  border-left:2px solid var(--acento);border-bottom:2px solid var(--acento);
  transform:rotate(-45deg);border-radius:1px;
}
.ticks li strong{color:var(--ink);font-weight:600}
.sec-ink .ticks li{color:var(--on-black-2)}
.sec-ink .ticks li::before{border-color:var(--green-on-black)}
.sec-ink .ticks li strong{color:var(--white)}

/* ---------- Pilares ---------- */

.pilar{
  display:flex;gap:22px;align-items:flex-start;
  padding:26px 0;
  border-top:1px solid rgba(255,255,255,.12);
}
.pilar:first-child{border-top:0}
.pilar .letra{
  font-size:clamp(30px,3.4vw,42px);font-weight:600;
  letter-spacing:-.03em;line-height:1;
  min-width:52px;color:var(--green-on-black);
}
.pilar h3{margin-bottom:6px}

/* ---------- Semanas ---------- */

.semana{
  display:flex;gap:clamp(20px,3vw,40px);align-items:flex-start;
  padding:clamp(24px,3vw,34px) 0;
  border-top:1px solid var(--line);
}
.semana:first-of-type{border-top:0}
.semana .n{
  flex:0 0 auto;min-width:104px;
  font-size:14px;font-weight:600;color:var(--green);
  letter-spacing:-.008em;padding-top:5px;
}
.semana h3{margin-bottom:7px}
.semana p{color:var(--ink-2);font-size:16px}

/* ---------- Caja de precio ---------- */

.precio-box{
  background:var(--white);
  border-radius:var(--radius-lg);
  padding:clamp(28px,3.4vw,40px);
  box-shadow:var(--shadow-lg);
  position:relative;overflow:hidden;
}
/* Filo arriba: convierte la caja en el ancla visual de la página. Va de verde
   a ámbar porque es el único sitio donde los dos colores de marca aparecen
   juntos, y es justo donde se decide la compra. */
.precio-box::before{
  content:'';position:absolute;top:0;left:0;right:0;height:4px;
  background:linear-gradient(90deg,var(--green) 0%,var(--acento) 100%);
}
.sec-ink .precio-box{background:#2A3A27;box-shadow:none}

.precio-cifra{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.precio-cifra .v{
  font-size:clamp(44px,5.6vw,64px);font-weight:600;
  letter-spacing:-.032em;line-height:1;font-variant-numeric:tabular-nums;
}
.precio-cifra .antes{
  font-size:20px;color:var(--ink-3);
  text-decoration:line-through;font-variant-numeric:tabular-nums;
}

.precio-meta{
  display:grid;gap:1px;background:var(--line);
  border-radius:14px;overflow:hidden;margin:26px 0 4px;
}
.precio-meta div{
  display:flex;justify-content:space-between;align-items:center;
  background:var(--white);padding:13px 16px;
}
.precio-meta .k{font-size:15px;color:var(--ink-2)}
.precio-meta .v{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums}

/* ---------- Formularios ---------- */

.form{display:grid;gap:16px;margin-top:26px}
.field{display:grid;gap:7px}
/* Etiquetas, consentimiento y avisos: el público ronda los 45-60, con
   presbicia y el móvil en la mano. Lo que hay que leer para decidir no baja
   de 15 px; lo accesorio, de 13. */
.field label{font-size:15px;font-weight:500;color:var(--ink-2);letter-spacing:-.004em}

/* El contorno del campo es lo ÚNICO que dice "aquí se escribe": el fondo del
   campo y el de la caja eran el mismo crema, y el borde --line daba 1,36:1.
   Al sol, con presbicia, eran dos rectángulos fantasma. #8C7F6A es el mismo
   taupe cálido, oscurecido hasta 3,5:1 (WCAG 1.4.11 pide 3), y el campo va
   un punto más claro que la caja para despegarse de ella. */
.field input,.field select,.field textarea{
  font-family:inherit;font-size:17px;color:var(--ink);letter-spacing:-.012em;
  background:#FFFDF9;
  border:1.5px solid #8C7F6A;border-radius:12px;
  padding:13px 15px;width:100%;
  transition:border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.field textarea{resize:vertical;min-height:96px;line-height:1.45}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--green);box-shadow:0 0 0 4px var(--green-ring);
}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-3)}

.sec-ink .field input,.sec-ink .field select,.sec-ink .field textarea{
  background:var(--verde);border-color:#4E6048;color:var(--white);
}
.sec-ink .field label{color:var(--on-black-2)}
.sec-ink .field input:focus,.sec-ink .field textarea:focus{
  border-color:var(--green-on-black);box-shadow:0 0 0 4px rgba(224,145,50,.22);
}

.consent{display:flex;gap:11px;align-items:flex-start;font-size:15px;color:var(--ink-2);line-height:1.45}
.consent input{margin-top:2px;accent-color:var(--green);width:16px;height:16px;flex:0 0 auto}
.sec-ink .consent{color:var(--on-black-2)}

.honey{position:absolute!important;left:-9999px!important;width:1px;height:1px;opacity:0}

/* El enlace a la privacidad va FUERA del <label>: dentro, tocarlo marcaba la
   casilla. Sangrado con el texto de la casilla para que se lea como su pie. */
.consent-info{font-size:15px;line-height:1.4;margin-top:-10px;padding-left:33px}
.consent-info a{display:inline-block;padding:10px 0;color:var(--green);text-decoration:underline;text-underline-offset:2px}

/* El mensaje va ENCIMA del botón: debajo, con el botón pegado al borde de la
   pantalla (lo normal con el pulgar), el error quedaba fuera de la vista y
   parecía que el botón no hacía nada. Vacío no ocupa sitio: el margen
   negativo se come el hueco de la rejilla. */
.form-msg{font-size:15px;letter-spacing:-.008em;line-height:1.4}
.form-msg:empty{margin-top:-16px}
.form-msg.ok{color:var(--green);font-weight:500}
.form-msg.err{color:#C7291B;font-weight:500}
/* Tras un alta el foco pasa al mensaje (samna.js) para cerrar el teclado.
   No es un control: no lleva anillo. */
.form-msg[tabindex]:focus{outline:none}
/* La vuelta del envío sin JS, arriba de la caja y con fondo propio: es lo
   único que dice si ha funcionado. */
.alta-aviso{margin:0 0 20px;padding:12px 16px;border-radius:14px;background:var(--green-soft)}
.alta-aviso.err{background:#FDECEA;color:#B3121F}

/* Qué campo hay que arreglar, marcado en el propio campo y no sólo con un
   texto rojo en otra parte. La casilla, además, con un anillo: el foco que
   le llega por código no pinta :focus-visible. */
.field input[aria-invalid=true]{border-color:#C7291B;box-shadow:0 0 0 3px rgba(199,41,27,.14)}
.consent:has(input[aria-invalid=true]) span{color:#C7291B}
.consent input[aria-invalid=true]{outline:2px solid #C7291B;outline-offset:2px}
.sec-ink .form-msg.ok{color:var(--green-on-black)}
/* 4.53 sobre el verde de marca; el #FF6B6B de antes se quedaba en 3.78. */
.sec-ink .form-msg.err{color:#FF8787}

/* ---------- Preguntas ---------- */

.faq{border-bottom:1px solid var(--line)}
.faq summary{
  cursor:pointer;list-style:none;
  padding:22px 44px 22px 0;position:relative;
  font-size:19px;font-weight:500;letter-spacing:-.018em;
  transition:color .2s var(--ease);
}
.faq summary:hover{color:var(--green)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:'';position:absolute;right:8px;top:50%;
  width:9px;height:9px;
  border-right:2px solid var(--ink-3);border-bottom:2px solid var(--ink-3);
  transform:translateY(-60%) rotate(45deg);
  transition:transform .3s var(--ease), border-color .2s var(--ease);
}
.faq summary:hover::after{border-color:var(--green)}
.faq[open] summary{color:var(--green)}
.faq[open] summary::after{transform:translateY(-30%) rotate(-135deg);border-color:var(--green)}
.faq p{padding:0 44px 24px 0;color:var(--ink-2);font-size:17px;line-height:1.55}

/* ---------- Pie ---------- */

.foot{background:var(--gray);color:var(--ink-2);padding:clamp(52px,6vw,76px) 0 40px;font-size:14px}
.foot .row{display:flex;flex-wrap:wrap;gap:40px;justify-content:space-between}
.foot .brand{font-size:20px;font-weight:600;color:var(--ink);letter-spacing:-.022em}
.foot a{transition:color .2s var(--ease)}
.foot a:hover{color:var(--green);text-decoration:underline}
.foot .legal{
  display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;
  margin-top:36px;padding-top:22px;border-top:1px solid var(--line);
  /* ink-2 y no ink-3: a 13-14 px y sobre el grano del gris, ink-3 bajaba de
     4,5:1 en los píxeles más oscuros del fondo (4,39 medido). */
  font-size:13px;color:var(--ink-2);
}

/* ---------- Asistente ----------
   OJO: las clases de burbuja las escribe samna.js y son
   me / bot / sys. No renombrarlas sin tocar el JS.            */

.chat-fab{
  position:fixed;right:22px;bottom:22px;z-index:120;
  width:56px;height:56px;border-radius:50%;
  background:var(--green);color:var(--crema);border:0;cursor:pointer;
  display:grid;place-items:center;
  box-shadow:0 6px 22px rgba(50,68,47,.38);
  transition:transform .25s var(--ease), background .2s var(--ease), box-shadow .25s var(--ease);
}
.chat-fab:hover{transform:scale(1.07);background:var(--green-2);box-shadow:0 8px 28px rgba(50,68,47,.45)}
.chat-fab:active{transform:scale(.97)}
.chat-fab svg{width:25px;height:25px;transition:transform .25s var(--ease)}

.chat-panel{
  position:fixed;right:22px;bottom:90px;z-index:120;
  width:min(384px,calc(100vw - 44px));
  max-height:min(620px,calc(100vh - 130px));
  /* dvh donde exista: en el móvil 100vh es la pantalla SIN la barra del
     navegador, y el panel se salía por arriba mientras la barra se ve. */
  max-height:min(620px,calc(100dvh - 130px));
  background:rgba(255,255,255,.9);
  -webkit-backdrop-filter:saturate(180%) blur(24px);
  backdrop-filter:saturate(180%) blur(24px);
  border:1px solid rgba(0,0,0,.08);
  border-radius:22px;
  box-shadow:0 16px 52px rgba(0,0,0,.20);
  display:none;flex-direction:column;overflow:hidden;
  transform-origin:bottom right;
}
.chat-panel.open{display:flex;animation:chat-in .28s var(--ease)}
@keyframes chat-in{from{opacity:0;transform:translateY(10px) scale(.97)}to{opacity:1;transform:none}}

/* Cabecera, avisos y caja de escribir no encogen nunca: si falta alto, el
   que cede es la conversación, que tiene su propio scroll. En un móvil bajo
   el panel se recortaba por arriba y se llevaba la X y el aviso médico. */
.chat-head,.chat-disclaimer,.chat-foot{flex-shrink:0}
.chat-head{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:16px 18px;border-bottom:1px solid rgba(0,0,0,.07);
}
.chat-head .t{font-size:15px;font-weight:600;letter-spacing:-.014em}
.chat-head .s{font-size:13px;color:var(--ink-3);margin-top:1px}
.chat-close{
  background:var(--gray-2);border:0;cursor:pointer;color:var(--ink-2);
  font-size:21px;line-height:1;width:32px;height:32px;border-radius:50%;
  display:grid;place-items:center;transition:background .2s var(--ease),color .2s var(--ease);
  position:relative;flex:0 0 auto;
}
/* El círculo se queda en 32 px para no inflar la cabecera; la zona que
   responde al dedo llega a los 44 con un borde invisible alrededor. */
.chat-close::before{content:'';position:absolute;inset:-6px;border-radius:50%}
.chat-close:hover{background:var(--line);color:var(--ink)}

.chat-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:18px;display:flex;flex-direction:column;gap:11px}

.msg{
  max-width:86%;padding:11px 15px;
  font-size:15px;line-height:1.45;letter-spacing:-.01em;
  border-radius:20px;white-space:pre-wrap;word-wrap:break-word;
  animation:msg-in .25s var(--ease);
}
@keyframes msg-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
/* Burbujas de iMessage: gris a la izquierda (ella), verde a la derecha (visitante). */
.msg.bot{background:var(--gray-2);color:var(--ink);align-self:flex-start;border-bottom-left-radius:6px}
.msg.me{background:var(--green);color:var(--crema);align-self:flex-end;border-bottom-right-radius:6px}
.msg.sys{background:#FDECEA;color:#B3121F;align-self:flex-start;font-size:14px}

.chat-typing{display:flex;gap:4px;padding:13px 16px;align-self:flex-start}
.chat-typing i{width:7px;height:7px;border-radius:50%;background:var(--ink-3);animation:blink 1.3s infinite}
.chat-typing i:nth-child(2){animation-delay:.18s}
.chat-typing i:nth-child(3){animation-delay:.36s}
@keyframes blink{0%,60%,100%{opacity:.25}30%{opacity:1}}

/* Hairline arriba: separa el aviso del último mensaje, que si no
   se leían pegados y parecía parte de la conversación. */
.chat-disclaimer{
  font-size:13px;color:var(--ink-3);line-height:1.4;
  padding:10px 18px;
  border-top:1px solid rgba(0,0,0,.06);
}
.chat-foot{display:flex;gap:9px;align-items:flex-end;padding:12px 14px;border-top:1px solid rgba(0,0,0,.07)}
/* 16 px y no 15: por debajo de 16, Safari en iPhone amplía la página al
   enfocar el campo y no la devuelve a su tamaño al salir, y el panel fijo
   queda medio fuera de la pantalla. */
.chat-foot textarea{
  flex:1;font-family:inherit;font-size:16px;letter-spacing:-.01em;
  border:1px solid var(--line);border-radius:var(--pill);
  padding:10px 15px;resize:none;max-height:110px;
  background:var(--white);color:var(--ink);
  transition:border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.chat-foot textarea:focus{outline:none;border-color:var(--green);box-shadow:0 0 0 3px var(--green-ring)}
.chat-send{
  flex:0 0 auto;width:44px;height:44px;border-radius:50%;
  background:var(--green);color:var(--crema);border:0;cursor:pointer;
  display:grid;place-items:center;transition:background .2s var(--ease),transform .12s var(--ease);
}
.chat-send:hover{background:var(--green-2)}
.chat-send:active{transform:scale(.94)}
.chat-send:disabled{opacity:.4;cursor:default}

/* El sistema de movimiento vive al final del fichero. */

/* ---------- Utilidades de espaciado ---------- */

.mt-xs{margin-top:8px}
.mt-s{margin-top:14px}
.mt-m{margin-top:22px}
.mt-l{margin-top:32px}
.mt-xl{margin-top:44px}
.mb-m{margin-bottom:22px}
.g2-split{gap:clamp(32px,5vw,64px);align-items:start}
.stack-340{max-width:340px}
.stack-820{max-width:820px;margin-left:auto;margin-right:auto}
.stack-900{max-width:900px;margin-left:auto;margin-right:auto}
.list-2{gap:14px clamp(28px,4vw,48px)}
.foot-note{margin-top:18px;max-width:720px}

/* ---------- Pantallas medianas ---------- */

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

/* ---------- Móvil ----------
   La nav pasa a dos filas: marca + botón arriba, y los enlaces
   debajo en una tira que se desliza. Antes se ocultaban del todo
   y en el móvil no había forma de navegar la página.            */

@media (max-width:820px){
  .nav{--nav-h:auto}
  /* OJO: .row y .wrap son el MISMO elemento (<div class="wrap row">).
     Poner aquí `padding:9px 0 0` mataba los 22px laterales del wrap y
     la marca y el botón se pegaban a los bordes de la pantalla. */
  .nav .row{flex-wrap:wrap;height:auto;padding:9px 22px 0;gap:10px}
  /* La marca lleva white-space:nowrap, así que no encogía: entre
     "SAMNA · Dra. Irene Escudero" (245px) y el botón (140px) no caben
     en los 346px útiles de un móvil de 390, y se cortaban los dos.
     El nombre se quita aquí porque ya está en el hero, en la sección
     de credibilidad y en el pie. */
  .nav .brand{flex:0 1 auto;min-width:0}
  .nav .brand span{display:none}
  .nav .btn{order:2}
  .nav nav{
    order:3;flex:1 0 100%;
    overflow-x:auto;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    margin:0 -22px;padding:2px 22px 9px;
  }
  .nav nav::-webkit-scrollbar{display:none}
  .nav nav ul{gap:8px;width:max-content}
  /* 11px de padding para llegar a ~40px de alto: por debajo de eso
     el dedo falla, y esta es la navegación principal en móvil. */
  .nav nav a{
    font-size:13px;opacity:1;
    background:var(--gray);border-radius:var(--pill);
    padding:11px 16px;display:block;white-space:nowrap;
  }
  .nav nav a:active{background:var(--gray-2)}
  /* La cabecera en dos filas mide 117 px y ahora se queda fija: con 112 el
     destino de cada ancla se metía 5 px debajo de ella. */
  html{scroll-padding-top:120px}
}

@media (max-width:760px){
  body{font-size:16px}
  .g2,.g4{grid-template-columns:1fr}
  .hero-facts{grid-template-columns:repeat(2,1fr);gap:28px 18px}
  .semana{flex-direction:column;gap:8px}
  .semana .n{padding-top:0}
  .pilar{gap:16px}
  .pilar .letra{min-width:38px}
  .foot .row{flex-direction:column;gap:28px}
  .chat-panel{right:12px;left:12px;width:auto;bottom:84px}
  .chat-fab{right:16px;bottom:16px}
  /* En el móvil el dedo tapa la tarjeta: menos sombra, más plano. */
  .precio-box{box-shadow:var(--shadow)}
  /* En Reservar, la caja con el precio y el formulario sube por delante del
     texto. En una columna iba detrás: quien tocaba "Reservar mi plaza"
     aterrizaba en el titular y el primer campo quedaba una pantalla más
     abajo. El texto de la sección sigue ahí, debajo, para quien lo busque. */
  #reservar .precio-box{order:-1}
  /* Y más recogida: a 390x844, al llegar desde un "Reservar", el botón de
     enviar se quedaba a 8 px de entrar en la pantalla. Se recorta aire de
     la ficha de datos, no de los campos ni de la letra. */
  .precio-meta{margin:18px 0 0}
  .precio-meta div{padding:10px 14px}
  .precio-box .form{margin-top:20px}
}

/* ---------- Portada en móviles bajos ----------
   Con la lámina de cookies puesta (≈147 px abajo), el "Reservar mi plaza" de
   la portada sólo quedaba libre a partir de ~740 px de alto. En un iPhone
   12-14 con las barras de Safari (390x664), un SE (375x667) o un Android de
   360x640 caía debajo de la lámina. Se recoge el aire del hero (no la letra
   ni el botón) y, en los más bajos, se afina un poco el titular y la
   entradilla. Sin la lámina se queda igual: la portada no pega un salto al
   decidir sobre cookies. */
@media (max-width:760px) and (max-height:760px){
  .hero{padding-top:20px}
  .hero .kicker{margin-bottom:6px}
  .hero .lead{margin-top:12px}
  .hero-cta{margin-top:18px}
}
@media (max-width:760px) and (max-height:660px){
  .hero{padding-top:16px}
  .hero h1{font-size:36px}
  .hero .lead{font-size:18px;line-height:1.34}
}

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

  /*
   * Se mantiene .01ms en vez de 'none' a propósito: así los eventos
   * transitionend/animationend SIGUEN disparándose y la lógica de
   * limpieza del JS no se queda a medias con clases pegadas.
   * Se anulan también retardos, repeticiones y líneas de tiempo de
   * scroll, que el parche anterior no tocaba.
   *
   * Con los pseudoelementos: '*' no los alcanza, y ahí viven el tick del
   * campo validado, los filos de los enlaces y el de las preguntas. Seguían
   * animándose a duración completa con la quietud pedida.
   */
  *,*::before,*::after{
    animation-duration:.01ms!important;
    transition-duration:.01ms!important;
    animation-delay:0s!important;
    transition-delay:0s!important;
    animation-iteration-count:1!important;
    animation-timeline:none!important;
  }

  /* Los tres puntos del chat se congelaban en el fotograma 0 (todos
     al 25%) y el indicador de espera desaparecía de hecho. Con
     opacidades fijas distintas se sigue leyendo "esperando". */
  .chat-typing i{animation:none!important}
  .chat-typing i:nth-child(1){opacity:.30}
  .chat-typing i:nth-child(2){opacity:.55}
  .chat-typing i:nth-child(3){opacity:.85}

  /* La línea de lectura se elimina, no se acelera. */
  .progreso{display:none}
}

/* ============================================================
   SISTEMA DE MOVIMIENTO
   Un principio: TODO lo que se mueve es una ENTRADA. Ocurre una
   vez, en la dirección de la lectura, y termina quieto. Nada late
   en bucle, nada se mueve si el usuario no ha hecho nada.

   Regla de quietud, y es verificable: a 1,2 s de cargar y a 700 ms
   de soltar el scroll, la página está inmóvil. Si algo se mueve en
   ese momento, sobra.

   El público tiene migraña y niebla mental: amplitudes ≤16 px,
   nunca se escala texto, y cero movimiento periférico continuo.
   ============================================================ */

:root{
  --e-out:cubic-bezier(.28,.11,.32,1);   /* desaceleración de entrada */
  --t-micro:180ms;                       /* hover, color, foco        */
  --t-press:80ms;                        /* pulsación                 */
  --t-block:420ms;                       /* entrada de bloque         */
  --paso:70ms;                           /* escalonado                */
}

/* ---------- Entrada de bloque ----------
   DOBLE CANDADO: el estado invisible sólo existe si (a) hay JS y
   (b) el usuario no ha pedido quietud. Así es imposible que una
   sección se quede invisible para siempre porque el JS falle o
   porque alguien olvide revertir un estado. */

@media (prefers-reduced-motion:no-preference){
  html.js .reveal{
    opacity:0;
    transform:translateY(16px);
    transition:opacity var(--t-block) var(--e-out),
               transform var(--t-block) var(--e-out);
    transition-delay:calc(var(--i,0) * var(--paso));
  }
  html.js .reveal.in{opacity:1;transform:none}
}

/* Escalonado por posición, sin escribir nada desde JS.
   Tope de 4 pasos: más de ~400 ms de cascada se percibe lenta. */
.reveal:nth-child(2){--i:1}
.reveal:nth-child(3){--i:2}
.reveal:nth-child(n+4){--i:3}

/* Las listas entran ítem a ítem: convierte una lista en algo que
   se lee en orden. */
@media (prefers-reduced-motion:no-preference){
}
@keyframes sube{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ---------- Entrada del hero ----------
   Sólo CSS: se dispara al cargar, no depende del JS ni del scroll.
   El h1 arranca a 60 ms porque es el elemento de mayor peso visual
   (LCP), y el conjunto termina antes de 700 ms para que nunca
   parezca que la página no ha acabado de cargar. */

@media (prefers-reduced-motion:no-preference){
  html.js .hero .kicker,
  html.js .hero h1,
  html.js .hero .lead,
  html.js .hero-cta,
  html.js .hero-facts .fact{
    animation:sube 520ms var(--e-out) backwards;
  }
  html.js .hero .kicker{animation-delay:0ms}
  html.js .hero h1{animation-delay:60ms}
  html.js .hero .lead{animation-delay:140ms}
  html.js .hero-cta{animation-delay:210ms}
  html.js .hero-facts .fact:nth-child(1){animation-delay:280ms}
  html.js .hero-facts .fact:nth-child(2){animation-delay:330ms}
  html.js .hero-facts .fact:nth-child(3){animation-delay:380ms}
  html.js .hero-facts .fact:nth-child(4){animation-delay:430ms}
}

/* ---------- Línea de lectura ----------
   2 px, sin brillo, avanza exactamente a la velocidad del dedo.
   Es la ÚNICA animación ligada al scroll de toda la página. */

.progreso{position:absolute;left:0;right:0;bottom:-1px;height:2px;pointer-events:none}
.progreso i{
  display:block;height:100%;width:100%;
  background:var(--green);
  transform:scaleX(var(--p,0));transform-origin:left;
  transition:transform .1s linear;
}

/* ---------- Raíl del programa ----------
   Se rellena un paso por semana según van entrando. Lo dispara el
   IntersectionObserver, NO el scroll: no es una animación scrubbed,
   así que no compite con la línea de lectura. */

.semanas{position:relative}
.rail{
  position:absolute;left:0;top:14px;bottom:14px;width:2px;
  background:var(--line);border-radius:2px;overflow:hidden;
}
.rail i{
  display:block;width:100%;height:100%;
  background:var(--green);
  transform:scaleY(var(--p,0));transform-origin:top;
  transition:transform .7s var(--e-out);
}
.semanas .semana{padding-left:26px;position:relative}
.semanas .semana::before{
  content:'';position:absolute;left:-4px;top:calc(clamp(24px,3vw,34px) + 7px);
  width:10px;height:10px;border-radius:50%;
  background:var(--white);border:2px solid var(--line);
  transition:border-color .4s var(--e-out), background .4s var(--e-out);
}
.semanas .semana.in::before{border-color:var(--green);background:var(--green)}

@media (max-width:760px){
  /* En columna el raíl no ayuda: estorba. */
  .rail{display:none}
  .semanas .semana{padding-left:0}
  .semanas .semana::before{display:none}
}

/* ---------- Encendido de S-A-M-N-A ----------
   Las letras entran una detrás de otra, UNA sola vez. El estado de
   reposo es el normal: no se atenúa ninguna. Atenuarlas dejaría el
   activo de marca por debajo del contraste mínimo de forma
   permanente, que es peor que no tener el efecto. */

@media (prefers-reduced-motion:no-preference){
  html.js .pilar.in .letra{animation:enciende 520ms var(--e-out) backwards}
  html.js .pilar:nth-of-type(1).in .letra{animation-delay:0ms}
  html.js .pilar:nth-of-type(2).in .letra{animation-delay:120ms}
  html.js .pilar:nth-of-type(3).in .letra{animation-delay:240ms}
  html.js .pilar:nth-of-type(4).in .letra{animation-delay:360ms}
  html.js .pilar:nth-of-type(5).in .letra{animation-delay:480ms}
}
@keyframes enciende{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ---------- Física de pulsación ----------
   Entrada rápida (80 ms), retorno más lento (200 ms): así se lee
   como hardware y no como una web. Suelo de escala .96 — por
   debajo, el texto del botón se desenfoca un fotograma. Va con
   cambio de color para que, bajo reduced-motion, la pulsación
   siga confirmándose de alguna manera. */

.btn,.chat-send,.chat-close{touch-action:manipulation;-webkit-tap-highlight-color:transparent}
.btn{transition:background var(--t-micro) var(--e-out), color var(--t-micro) var(--e-out),
                transform 200ms var(--e-out), box-shadow var(--t-micro) var(--e-out), opacity var(--t-micro)}
.btn:active{transform:scale(.96);transition-duration:var(--t-press)}
.btn-primary:active{background:#26351F}

/* ---------- Acuse de recibo en los formularios ----------
   Es lo único de la página que convierte: el hueco entre "lo he
   escrito" y "está bien" es justo donde se abandona. */

.field{position:relative}

/* Tick al soltar el foco, NUNCA mientras se teclea: marcar en rojo
   a media escritura es hostil, y más con niebla mental. */
.field.ok::after{
  content:'';position:absolute;right:14px;top:38px;
  width:15px;height:8px;
  border-left:2px solid var(--green);border-bottom:2px solid var(--green);
  transform:rotate(-45deg) scale(.4);opacity:0;border-radius:1px;
  animation:tick 340ms var(--e-out) forwards;
  pointer-events:none;
}
@keyframes tick{to{opacity:1;transform:rotate(-45deg) scale(1)}}
.field.ok input{padding-right:40px}

/* El botón bloquea su ancho antes de escribir "Enviando…" para que
   no dé el salto que hoy delata la página. */

@media (prefers-reduced-motion:no-preference){
  .form-msg.ok,.form-msg.err{animation:sube 300ms var(--e-out)}
}

/* Consentimiento más grande: es el control que bloquea las tres
   conversiones y el público ronda los 45-60. */
.consent input{width:22px;height:22px}

/* ---------- Chat ---------- */

.chat-panel.cerrando{animation:chat-out 200ms var(--e-out) forwards}
@keyframes chat-out{to{opacity:0;transform:translateY(8px) scale(.97)}}
.chat-fab.abierto svg{transform:rotate(90deg)}
/* El botón de enviar despierta cuando hay algo escrito. */
.chat-send{opacity:.45;transition:opacity var(--t-micro) var(--e-out), background var(--t-micro) var(--e-out), transform 200ms var(--e-out)}
.chat-send.vivo{opacity:1}
.chat-send:active{transform:scale(.94);transition-duration:var(--t-press)}

/* ---------- Preguntas ----------
   Sólo opacidad. Un desvanecido corto con cambio de altura
   instantáneo es más seguro que deslizar suavemente todo el
   viewport inferior: el salto discreto no dispara respuesta
   optocinética, el desplazamiento suave de área grande sí. */

.faq[open] p{animation:faq-fade 180ms var(--e-out)}
@keyframes faq-fade{from{opacity:0}to{opacity:1}}

/* ============================================================
   FONDOS CON VIDA
   Tres capas, TODAS estáticas. El fondo ocupa el 100% de la
   periferia visual: es justo el sitio donde el movimiento
   continuo está prohibido con este público. Aquí se gana
   profundidad con textura y luz, no con animación.

     1. Grano fino (SVG, 489 bytes, se repite)  -> quita el plano
     2. Lavados de luz muy tenues               -> dan volumen
     3. Bordes de sección difuminados           -> quitan el corte

   Las tres son sutiles a propósito: si se notan, están mal.
   Contraste medido después de aplicarlas — ver README §11.
   ============================================================ */

:root{
  /* Ruido fractal en escala de grises. Baked al 30% dentro del
     propio SVG: así el color de fondo asoma y no hay que jugar
     con opacidades de capa. */
  --grano:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27140%27%20height%3D%27140%27%3E%3Cfilter%20id%3D%27n%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%27.9%27%20numOctaves%3D%274%27%20stitchTiles%3D%27stitch%27%2F%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27100%25%27%20height%3D%27100%25%27%20filter%3D%27url%28%23n%29%27%20opacity%3D%27.12%27%2F%3E%3C%2Fsvg%3E");
  --grano-oscuro:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27140%27%20height%3D%27140%27%3E%3Cfilter%20id%3D%27n%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%27.9%27%20numOctaves%3D%274%27%20stitchTiles%3D%27stitch%27%2F%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27100%25%27%20height%3D%27100%25%27%20filter%3D%27url%28%23n%29%27%20opacity%3D%27.07%27%2F%3E%3C%2Fsvg%3E");
}

/* ---------- Fondo base ----------
   Blanco que no es plano: un lavado vertical de dos grados y el
   grano encima. El grano va fijo para que no "nade" al hacer
   scroll (si se desplaza con el contenido, se nota y marea). */

body{
  background-color:var(--white);
  background-image:
    var(--grano),
    linear-gradient(180deg,#FFFCF7 0%, #FCF4E9 38%, #FFFFFF 100%);
  background-attachment:fixed, fixed;
  background-size:140px 140px, cover;
}

/* ---------- Secciones grises ----------
   Deja de ser un crema liso: degradado suave, un lavado verde
   casi invisible arriba a la derecha, y el grano. */

.sec-gray{
  position:relative;
  background-color:var(--gray);
  background-image:
    var(--grano),
    radial-gradient(ellipse 70% 55% at 82% 0%, rgba(50,68,47,.045), transparent 62%),
    linear-gradient(180deg,#FDF6EC 0%, #FBF0E4 52%, #F7EADA 100%);
  background-size:140px 140px, cover, cover;
}

/* El corte entre blanco y gris era una línea dura. Se difumina
   con un degradado de 100px, que es lo que hace que la página
   se lea como un continuo y no como bloques pegados. */
.sec-gray::before{
  content:'';position:absolute;left:0;right:0;top:0;height:100px;
  background:linear-gradient(180deg,var(--white),transparent);
  pointer-events:none;z-index:0;
}
.sec-gray > .wrap{position:relative;z-index:1}

/* ---------- Secciones negras ----------
   El negro puro es una pared. Se levanta a un carbón muy oscuro,
   se le mete un halo verde arriba (donde está el titular) y otro
   apagado abajo, más el grano, que en oscuro es lo que más se
   nota y lo que evita el banding de los degradados. */

.sec-ink{
  position:relative;
  background-color:var(--black);
  background-image:
    var(--grano-oscuro),
    radial-gradient(ellipse 80% 50% at 50% -10%, rgba(224,145,50,.10), transparent 60%),
    radial-gradient(ellipse 60% 40% at 15% 105%, rgba(224,145,50,.05), transparent 65%),
    linear-gradient(180deg,#3A4C36 0%, #32442F 55%, #2C3B29 100%);
  background-size:140px 140px, cover, cover, cover;
}
.sec-ink > .wrap{position:relative;z-index:1}

/* ---------- Secciones blancas de conversión ----------
   Las dos que tienen formulario llevan un lavado verde muy tenue
   detrás de la caja, para que el ojo vaya ahí sin necesidad de
   añadir ni un adorno. */

#autoevaluacion,
#reservar{
  position:relative;
  background-image:
    var(--grano),
    radial-gradient(ellipse 55% 50% at 78% 42%, rgba(50,68,47,.055), transparent 65%);
  background-size:140px 140px, cover;
  background-attachment:fixed, scroll;
}
#autoevaluacion > .wrap,
#reservar > .wrap{position:relative;z-index:1}

/* La sección de la bio, con las cuatro tarjetas, pide el lavado
   por el otro lado para que la página no se desequilibre. */
#irene{
  position:relative;
  background-image:
    var(--grano),
    radial-gradient(ellipse 50% 45% at 12% 30%, rgba(50,68,47,.04), transparent 65%);
  background-size:140px 140px, cover;
  background-attachment:fixed, scroll;
}
#irene > .wrap{position:relative;z-index:1}

/* ---------- Hero ----------
   El halo que ya existía se queda, pero ahora convive con el
   grano y con un segundo foco más frío abajo que le da suelo. */

.hero::after{
  content:'';position:absolute;z-index:-1;inset:auto 0 -40px 0;height:280px;
  background:radial-gradient(ellipse 60% 100% at 50% 100%, rgba(50,68,47,.035), transparent 70%);
  pointer-events:none;
}

/* ---------- Pie ----------
   Comparte el tratamiento de las secciones grises para que el
   final de la página no se caiga a un gris plano. */

.foot{
  position:relative;
  background-color:var(--gray);
  background-image:
    var(--grano),
    linear-gradient(180deg,#FDF7EE 0%, #F7EADA 100%);
  background-size:140px 140px, cover;
}
.foot > .wrap{position:relative;z-index:1}

/* ---------- Tarjetas sobre gris ----------
   Con el fondo ya texturizado, las tarjetas blancas necesitan un
   punto más de separación para no fundirse con él. */

.sec-gray .card{
  background:rgba(255,255,255,.86);
  -webkit-backdrop-filter:blur(6px);
  backdrop-filter:blur(6px);
  box-shadow:0 1px 2px rgba(0,0,0,.03), 0 8px 30px rgba(0,0,0,.055);
}

/* Las tarjetas de las secciones negras también se levantan del
   fondo, que ahora tiene halo. */
.sec-ink .card{background:rgba(255,255,255,.045)}
.sec-ink .precio-box{background:rgba(255,255,255,.05)}

/* ---------- Impresión y ahorro de datos ----------
   El grano no aporta nada en papel y encarece la impresión. */
@media print{
  body,.sec-gray,.sec-ink,.foot,#autoevaluacion,#reservar,#irene{
    background-image:none!important;background-color:var(--crema)!important;color:#000!important;
  }
}

/* ---------- Retrato ----------
   Su foto de estudio en la sección oscura. El fondo claro de la propia foto
   hace de tarjeta luminosa sobre el negro: es un contraste buscado, así que
   nada de desvanecerla por abajo (eso sólo funciona si la foto ya es negra). */
.retrato{position:relative;align-self:end}
.retrato img{
  width:100%;height:auto;display:block;
  border-radius:var(--radius-lg);
}
.retrato-fila{align-items:center}
@media (max-width:760px){
  /* En móvil la foto va primero: la cara antes que la lista de méritos.
     width:100% reserva el hueco antes de que llegue la foto (lazy): sin él,
     el contenedor se ajustaba al contenido, medía 0x0 y al cargar empujaba
     el texto 400 px hacia abajo con la persona leyendo. */
  .retrato-fila{display:flex;flex-direction:column}
  .retrato{order:-1;width:100%;max-width:320px;margin:0 auto}
}

/* Su cara en el momento de reservar. Pequeña y redonda: acompaña a la frase,
   no compite con el precio. El tamaño va en el <picture>, que es el hijo de
   la fila flex: puesto sólo en el <img>, el <picture> encogía y la cara salía
   en un óvalo de 30x44. */
.firma{display:flex;align-items:center;gap:12px}
.firma picture{flex:0 0 44px;width:44px;height:44px}
.firma img{width:44px;height:44px;max-width:none;border-radius:50%;object-fit:cover}
.firma p{margin:0;font-size:14px}

/* ============================================================
   LA PÁGINA RESPONDE
   Segunda capa de movimiento. El principio no cambia: nada se
   mueve solo. Lo que se añade aquí lo provoca la persona —el
   puntero, el dedo, el tabulador, enviar el formulario— y muere
   en cuanto suelta. Por eso no toca ninguna de las reglas
   clínicas: no hay bucles, no hay scroll, no hay periferia.

   Respuestas cortas (180 ms), pequeñas (≤3 px) y sin rebote.
   La regla de quietud se sigue cumpliendo sin hacer nada más.

   OJO TÉCNICO, que costó encontrarlo: el hover de las tarjetas
   NO puede ir en `transform`. La regla de entrada
   `html.js .reveal.in{transform:none}` pesa (0,3,1) y se comería
   cualquier `.card:hover` (0,2,0) en silencio. Va en `translate`,
   que es una propiedad independiente y compone con transform sin
   pelea de especificidad.
   ============================================================ */

/* Todo el hover va detrás de esta consulta: en táctil un hover se
   queda pegado tras el toque, que es el fallo clásico. */

/* ---------- Tarjetas ----------
   Hasta ahora NINGUNA respondía: la única regla que existía era
   `.g4 .card:hover` y en esta landing no hay ni un .g4. */
.card{position:relative;isolation:isolate;transition:translate var(--t-micro) var(--e-out)}
.card::after{
  content:'';position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;
  box-shadow:0 10px 30px rgba(0,0,0,.09), 0 2px 6px rgba(0,0,0,.04);
  opacity:0;transition:opacity var(--t-micro) var(--e-out);
}
.sec-ink .card::after{box-shadow:0 10px 30px rgba(0,0,0,.5)}
@media (hover:hover) and (pointer:fine){
  .card:hover{translate:0 -3px}
  .card:hover::after{opacity:1}
}
.card:active{translate:0 -1px;transition-duration:var(--t-press)}

/* ---------- Las cuatro semanas ----------
   Es donde el ojo se queda más rato comparando, y era una lista
   muerta con un raíl que ya se había pintado solo. Ahora el raíl
   deja de ser decorado y marca lo que estás mirando. */
.semanas .semana > *{position:relative;z-index:1}
.semanas .semana::after{
  content:'';position:absolute;z-index:0;pointer-events:none;
  top:1px;bottom:0;left:12px;right:-18px;
  border-radius:14px;background:var(--gray);
  opacity:0;transition:opacity var(--t-micro) var(--e-out);
}
.semana .n{transition:transform var(--t-micro) var(--e-out)}
@media (hover:hover) and (pointer:fine){
  .semanas .semana:hover::after{opacity:1}
  .semanas .semana:hover .n{transform:translateX(3px)}
  .semanas .semana:hover::before{transform:scale(1.4)}
}
@media (max-width:760px){
  .semanas .semana::after{left:-14px;right:-14px}
}

/* ---------- Enlaces ----------
   Filo que crece desde el centro. Y lo importante: también con
   :focus-visible, porque hasta ahora el teclado sólo tenía el
   anillo genérico. */
.nav nav a,.foot a{position:relative;display:inline-block}
.nav nav a::after,.foot a::after{
  content:'';position:absolute;left:0;right:0;bottom:-5px;height:1.5px;
  background:currentColor;border-radius:2px;
  transform:scaleX(0);transform-origin:center;
  transition:transform var(--t-micro) var(--e-out);
}
.nav nav a:hover::after,.nav nav a:focus-visible::after,
.foot a:hover::after,.foot a:focus-visible::after{transform:scaleX(1)}
.foot a:hover{text-decoration:none}

@media (max-width:820px){
  /* Ahí los enlaces ya son píldoras: el filo estorba, la pulsación no. */
  .nav nav a::after{display:none}
  .nav nav a{transition:transform 200ms var(--e-out), background var(--t-micro) var(--e-out)}
  .nav nav a:active{transform:scale(.96);transition-duration:var(--t-press)}
}

/* ---------- Preguntas ----------
   La flecha se adelanta antes de que pulses: es la promesa del
   gesto. Y un filo verde marca cuál tienes abierta sin releer. */
.faq{position:relative}
.faq::before{
  content:'';position:absolute;left:-16px;top:16px;bottom:16px;width:2px;
  border-radius:2px;background:var(--green);
  transform:scaleY(0);transform-origin:top;
  transition:transform 260ms var(--e-out);
}
.faq[open]::before{transform:scaleY(1)}
@media (hover:hover) and (pointer:fine){
  .faq summary:hover::after{transform:translateY(-35%) rotate(45deg)}
  .faq[open] summary:hover::after{transform:translateY(-8%) rotate(-135deg)}
}
.faq summary:active::after{transition-duration:var(--t-press)}
/* El anillo global se metía en la fila de al lado: esto es un arreglo. */
.faq summary:focus-visible{outline-offset:-4px;border-radius:12px}

/* ---------- La caja de reserva ----------
   Mientras escribe dentro, la caja se separa del fondo. */
.precio-box{transition:translate var(--t-micro) var(--e-out)}
.precio-box::before{transition:height var(--t-micro) var(--e-out)}
.precio-box:focus-within{translate:0 -2px}
.precio-box:focus-within::before{height:5px}

/* ============================================================
   ACUSE DE RECIBO
   El formulario es lo único de la página que convierte, y el
   hueco entre "lo he escrito" y "está bien" es donde se abandona.
   ============================================================ */

/* Riel verde bajo el campo activo: "te estoy escuchando aquí".
   Duplica la señal de foco sin tocar el anillo, que se queda
   por accesibilidad. Si el navegador no soporta :has(), no pasa
   nada: el foco sigue siendo el de siempre. */
.field::before{
  content:'';position:absolute;left:12px;right:12px;bottom:0;height:2px;
  background:var(--green);border-radius:2px;pointer-events:none;
  transform:scaleX(0);transform-origin:left;
  transition:transform 240ms var(--e-out);
}
.sec-ink .field::before{background:var(--green-on-black)}
.field:has(input:focus)::before,
.field:has(select:focus)::before{transform:scaleX(1)}

.field label{
  transform-origin:left;
  transition:color var(--t-micro) var(--e-out), transform var(--t-micro) var(--e-out);
}
.field:has(input:focus) label,
.field:has(select:focus) label{color:var(--green);transform:translateY(-1px)}

/* Al validar, el riel no se apaga hacia atrás: se retrae hacia la
   derecha y justo donde muere aparece el tick. La línea le pasa
   el testigo a la marca. */
.field.ok:not(:has(input:focus))::before{
  transform-origin:right;transform:scaleX(0);transition-duration:180ms;
}
.field.ok::after{animation:tick 340ms var(--e-out) 140ms forwards}
/* Hueco del tick reservado siempre: así el texto nunca se recoloca. */
.precio-box .field input{padding-right:40px}

/* El consentimiento es el control que bloquea la conversión y no
   confirmaba nada. Un anillo sale y se desvanece, UNA vez. */
.consent{position:relative}
.consent::before{
  content:'';position:absolute;left:0;top:2px;width:22px;height:22px;
  border-radius:7px;box-shadow:0 0 0 2px var(--green);
  opacity:0;pointer-events:none;
}
@media (prefers-reduced-motion:no-preference){
  html.js .consent:has(input:checked)::before{animation:acuse 460ms var(--e-out) 1 both}
}
@keyframes acuse{from{opacity:.85;transform:scale(1)}to{opacity:0;transform:scale(1.55)}}
.consent span{transition:color var(--t-micro) var(--e-out)}
.consent:has(input:checked) span{color:var(--ink)}

/* Cuando el formulario está completo, el botón se alza: es el
   único movimiento de la página que informa de un cambio real
   ("ya puedes reservar"). No se atenúa en reposo a propósito:
   bajarle la opacidad dejaría el blanco sobre verde por debajo
   del mínimo legible, justo en el elemento que convierte. */
.form .btn[type=submit]{--lift:0px;position:relative;transform:translateY(var(--lift))}
.form .btn[type=submit]::after{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:0 8px 22px rgba(50,68,47,.34);
  opacity:0;transition:opacity 220ms var(--e-out);
}
.form:not(:has(input[required]:invalid)) .btn[type=submit]{--lift:-2px}
.form:not(:has(input[required]:invalid)) .btn[type=submit]::after{opacity:1}
.btn:active{transform:translateY(var(--lift,0px)) scale(.96);transition-duration:var(--t-press)}

/* ARREGLO: convivían .btn[disabled]{opacity:.55} y .enviando{.75}.
   Ganaba .75 y dejaba el texto blanco sobre verde en ~2.9:1,
   ilegible justo en el segundo de más ansiedad. Ahora la espera
   se cuenta con jerarquía, no bajando el contraste: la tecla se
   queda hundida y lo ya entregado se aparta. */
.btn.enviando,
.btn.enviando[disabled]{opacity:1;transform:translateY(var(--lift,0px)) scale(.985)}
.btn.enviando::after{opacity:.35}
.form:has(.btn.enviando) .field,
.form:has(.btn.enviando) .consent{opacity:.6;transition:opacity 240ms var(--e-out)}
.form:has(.btn.enviando) .field::before{transform:scaleX(0)}

/* ============================================================
   ENTRADAS CON MÁS CARÁCTER, SIN MÁS RIESGO
   El contenedor funde; las piezas sólo se mueven. Así se percibe
   más movimiento con MENOS recorrido, y se evita el doble fundido
   (padre × hijo), que es lo que ensucia un desvanecido.
   ============================================================ */

:root{--dy:16px;--dy-s:12px}
@media (max-width:760px){:root{--dy:10px;--dy-s:8px}}

/* Sólo movimiento: la opacidad la pone el contenedor. */
@keyframes alza{from{transform:translateY(var(--dy-s))}to{transform:none}}

@media (prefers-reduced-motion:no-preference){
  /* La cabecera de sección deja de viajar como una losa y llegan
     dentro el kicker, el titular y la entradilla, en ese orden.
     Es el elemento que más se repite: es donde más se nota. */
  html.js .sec-head.reveal{transform:none}
  html.js .sec-head.reveal.in > .kicker{animation:alza 460ms var(--e-out) backwards}
  html.js .sec-head.reveal.in > h2     {animation:alza 460ms var(--e-out) 60ms backwards}
  html.js .sec-head.reveal.in > p      {animation:alza 460ms var(--e-out) 120ms backwards}

  /* Las rejillas de dos se montan hacia el centro en vez de subir
     en paralelo. El vector diagonal mide 14,1 px: bajo el tope. */
  html.js .g2 > .reveal:not(.in):nth-child(odd) {transform:translate3d(-10px,10px,0)}
  html.js .g2 > .reveal:not(.in):nth-child(even){transform:translate3d( 10px,10px,0)}

  /* Las filas de semana: se enciende el punto del raíl, de él sale
     el número y detrás entra el texto. Tres gestos sueltos pasan
     a ser uno solo. */
  html.js .semana.reveal{transform:none}
  html.js .semana.reveal.in .n   {animation:desde-rail 420ms var(--e-out) backwards}
  html.js .semana.reveal.in > div{animation:alza 460ms var(--e-out) 80ms backwards}

  /* El titular pesa: recorre menos y tarda más que lo pequeño que
     tiene al lado. Y lo último que se mueve en pantalla es el
     número de plazas, que es el único dato vivo. */
  html.js .hero h1{animation:sube-h1 660ms var(--e-out) 60ms backwards}
  html.js .hero-facts .fact:nth-child(1){animation-delay:300ms}
  html.js .hero-facts .fact:nth-child(3){animation-delay:350ms}
  html.js .hero-facts .fact:nth-child(4){animation-delay:400ms}
  html.js .hero-facts .fact:nth-child(2){animation-delay:480ms}
}
@keyframes desde-rail{from{transform:translateX(-10px)}to{transform:none}}
@keyframes sube-h1{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

@media (max-width:760px){
  /* En columna única no hay lados. */
  html.js .g2 > .reveal:not(.in):nth-child(n){transform:translate3d(0,10px,0)}
}

/* ARREGLO: `.reveal:nth-child(n+4)` contaba TODOS los hermanos, así
   que en «Por qué puedes fiarte» y en «Reservar» la lista es el
   cuarto hijo pero el primer .reveal, y arrancaba con 210 ms de
   retraso que nadie pidió. Con `of .reveal` cuenta lo que debe.
   Las reglas de arriba se quedan como respaldo si el navegador
   no soporta la sintaxis. */
.reveal:nth-child(1 of .reveal){--i:0}
.reveal:nth-child(2 of .reveal){--i:1}
.reveal:nth-child(3 of .reveal){--i:2}
.reveal:nth-child(n+4 of .reveal){--i:3}

/* El escalonado de las listas, comprimido a 70 ms: la más larga
   cierra en 630 ms en vez de 740, que se salía del presupuesto. */
.ticks li{--d:210ms}
.ticks li:nth-child(1){--d:0ms}
.ticks li:nth-child(2){--d:70ms}
.ticks li:nth-child(3){--d:140ms}
@media (prefers-reduced-motion:no-preference){
  html.js .ticks.in li{animation:alza var(--t-block) var(--e-out) var(--d) backwards}
}

/* ---------- Fondo vivo ----------
   El lienzo va detrás de todo, sin interceptar el ratón y sin
   entrar nunca en el orden de lectura. La sección ya es
   position:relative, así que sólo hay que anclarlo. */
.fondo{
  position:absolute;inset:0;width:100%;height:100%;
  display:block;pointer-events:none;z-index:0;
}
.hero > .wrap,
.sec-ink > .wrap{position:relative;z-index:1}
/* El halo del hero vive en z-index:-1, así que la red se pinta
   entre el halo y el texto: encima de la luz, debajo de la letra. */
@media (prefers-reduced-motion:reduce){ .fondo{display:none} }

/* ---------- Objetivos táctiles ----------
   En móvil todo lo que se pulsa necesita alto suficiente. Medido:
   las píldoras de la nav estaban en 33px y el botón de reservar en 37. */
@media (max-width:820px){
  .nav .btn-sm{padding:11px 20px}
}
@media (max-width:760px){
  /* Los enlaces del pie eran de 16-21px de alto; con 6 px de relleno se
     quedaban en 31-33. Con 11 llegan a unos 44, lo que pide un pulgar. */
  .foot a{display:inline-block;padding:11px 0}
  .foot .legal{gap:0 16px;font-size:14px}
  .foot .row p.mt-xs{margin-top:0}
}
/* El correo del cierre (y el enlace a la consulta) eran una línea de 16 px
   de alto: se ensancha la zona que responde al dedo, no la letra. */
.sec-ink .tiny a{display:inline-block;padding:12px 0}

/* ---------- Iconos ----------
   Trazo fino, verde de marca, sin círculo de fondo: acompañan al
   título, no compiten con él. Heredan el color, así que sobre negro
   pasan solos al verde brillante. */
/* Los iconos, en ámbar. Son dibujos de 26px sin requisito de contraste, y
   reparten el color de marca por toda la sección del mecanismo, que es la
   más larga de la página y la que más fría se quedaba en verde sobre crema. */
.icono{color:var(--acento);margin-bottom:14px}
.sec-ink .icono{color:var(--green-on-black)}
.card .icono{display:block}
/* En las filas de semana va en línea con la etiqueta. */
.icono-sm{width:18px;height:18px;display:inline-block;vertical-align:-4px;margin:0 7px 0 0}
.semana .n{display:inline-flex;align-items:center}
@media (hover:hover) and (pointer:fine){
  /* Acompaña al levantamiento de la tarjeta, sin vida propia. */
  .card{transition:translate var(--t-micro) var(--e-out)}
  .card .icono{transition:transform var(--t-micro) var(--e-out)}
  .card:hover .icono{transform:scale(1.08)}
}

/* ---------- Acceso al área privada ----------
   Discreto a propósito: lo usa ella, no la visitante. Se aclara al
   pasar por encima, como cualquier otro enlace del pie. */
/* Va como `.foot a.acceso` y no como `.acceso` a secas: la regla
   `.foot a` de los enlaces del pie pesa más (0,1,1 contra 0,1,0) y le
   imponía su display, así que el candado se colocaba encima de la
   palabra en vez de al lado. */
.foot a.acceso{
  display:inline-flex;align-items:center;gap:6px;
  white-space:nowrap;flex:0 0 auto;
  color:var(--ink-2);   /* discreto por tamaño y sitio, no por contraste (ver .foot .legal) */
  transition:color var(--t-micro) var(--e-out);
}
.foot a.acceso:hover,.foot a.acceso:focus-visible{color:var(--green)}
.foot a.acceso svg{opacity:.8}
/* Sin el filo que crece: ya lleva icono, dos señales sobran. */
.foot a.acceso::after{display:none}

/* Los tres enlaces legales del pie. Iban como texto plano —decían
   "Aviso legal · Privacidad · Cookies" sin llevar a ninguna parte—,
   que en una web que va a pedir consentimiento es justo lo que no
   puede pasar: el banner tiene que poder enlazar a algo. */
.legal-enlaces{display:inline-flex;flex-wrap:wrap;gap:14px}
.legal-enlaces a{color:inherit;text-decoration:none;border-bottom:1px solid transparent}
.legal-enlaces a:hover,
.legal-enlaces a:focus-visible{border-bottom-color:currentColor}

/* El aviso de que el texto sale a un proveedor externo. Va con el mismo
   peso que el aviso clínico —no más pequeño ni más gris—: es la única
   información que tiene la persona antes de escribir sus síntomas. */
.chat-aviso-envio{margin-top:6px}
.chat-aviso-envio a{color:inherit;text-decoration:underline}

/* Texto sólo para el lector de pantalla (el "Escribiendo…" del asistente). */
.sr-only{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* ---------- La burbuja no tapa lo que se pulsa ----------
   Es fija abajo a la derecha, y justo ahí caen el botón de enviar del
   formulario (cuando se baja con el pulgar) y el 'Acceso' del pie.

   Formulario: samna.js la aparta mientras el formulario está en pantalla y
   le cae debajo (en el móvil, siempre; en escritorio ancho la caja queda
   lejos y no se toca), y la devuelve en cuanto sale. Se desvanece, no se
   desplaza: nada recorre la pantalla. Si el panel está abierto no se toca,
   porque la burbuja es la que lo cierra.

   Pie: se le da aire por debajo para que, al llegar al final, 'Acceso' quede
   por encima de la burbuja. En escritorio ancho no hace falta: el pie está
   centrado y la burbuja vive fuera de él. */
.chat-fab{transition:transform .25s var(--ease), background .2s var(--ease), box-shadow .25s var(--ease),
                     opacity var(--t-micro) var(--e-out), visibility 0s linear 0s}
body.chat-apartado .chat-fab:not(.abierto){
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity var(--t-micro) var(--e-out), visibility 0s linear var(--t-micro);
}
@media (max-width:1100px){
  body:has(#chat-fab) .foot{padding-bottom:104px}
}

/* ---------- A dónde llevan los "Reservar" ----------
   Al formulario, no al titular de la sección. El margen deja que asome el
   filo de la caja bajo la cabecera fija. */
#formulario{scroll-margin-top:8px}

/* ---------- Pantallas bajas ----------
   Un portátil al 200 % de zoom (640x400) o un móvil apaisado: la cabecera
   fija en dos filas se comía casi un tercio de la pantalla. Ahí deja de
   seguirte y se queda arriba del todo, como una cabecera normal. */
@media (max-height:500px){
  .nav{position:relative}
  html{scroll-padding-top:12px}
}
