/* ==========================================================================
   sotowismify.com · base.css (v1.1)
   Tokens, reset, tipografía, fondo (puntos + orbes), cristal (.glass/.lg/.box/.corner-glass),
   botones, utilidades, estados de revelado, nav, menú, cursor, progreso, CTA flotante, toast y modal.
   Cada sección vive en assets/css/<id>.css con todo prefijado por .s-<id>.

   TEMA CLARO desde el 17-oct-2026 (blanco + blanco roto, tinta #14181f); lima #c2fc03 solo en pocos CTA (.btn-lime).
   Reglas: monocromo (grises neutros),
   PROHIBIDO feTurbulence/fractalNoise. Los hover que mueven usan translate/scale
   (propiedades individuales) para no pisar los transform de GSAP.
   PROHIBIDO -webkit-text-stroke con Inter variable (dibuja trazos cruzados): .outline = gris.

   REGLA DE CRISTAL (rendimiento + puntos visibles)
   - backdrop-filter SOLO en elementos flotantes: nav, menú, CTA flotante, cursor, toast y modal
     (clase .lg). En la página, como mucho 1-2 paneles protagonistas con .glass.glass-blur.
   - .glass y .box = receta de cristal SIN backdrop-filter (degradado + borde fino + brillos
     interiores + .corner-glass): los puntos del fondo se ven a través y ScrollSmoother no tiene
     que re-desenfocar cada panel en cada frame.
   - Chips/insignias que «flotan» dentro de una sección: .lg.lg--flat (mismo aspecto, sin blur). Red de
     seguridad: un .lg dentro de #smooth-content sin --flat tampoco desenfoca (ver «Cristal»).

   GSAP 3.15: en cuanto transforma un elemento le fija EN LÍNEA translate/rotate/scale: none (y hornea
   en su transform el translate/scale CSS que tuviera). Por eso: hover que mueve un elemento que GSAP
   también transforma → regla con !important (ver .btn y .card-h); y nunca uses translate/scale CSS como
   estado de reposo (oculto/visible) de algo que GSAP vaya a mover (ver .fcta-wrap).

   Contraste en claro (sobre #fff / #f4f2ee): --fg-2 ≈ 6:1 · --fg-3 ≈ 5,4:1 · --fg-4 ≈ 4,7:1 (texto pequeño AA). Para trazos y
   decoración más tenues, usa --line* o un rgba propio, nunca --fg-4 rebajado.
   ========================================================================== */

/* Fuentes: subconjunto latino (Latin-1 + puntuación general, €, ™, flechas, ≈ ≤ ≥ √ ▲ ▶ ▼), Inter sin el eje
   slnt (la web no usa cursiva). Lo que quede fuera del rango cae en la fuente del sistema. El nombre lleva la
   versión (.v2): las fuentes se sirven con caché immutable de 1 año. */
@font-face {
  font-family: 'Inter';
  src: url('/assets/fonts/inter-latin.v2.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2190-2193, U+2197, U+2212, U+2215, U+221A, U+2248, U+2264-2265, U+25B2, U+25B6, U+25BC, U+FE0E, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('/assets/fonts/jetbrains-mono-latin.v2.woff2') format('woff2');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2190-2193, U+2197, U+2212, U+2215, U+221A, U+2248, U+2264-2265, U+25B2, U+25B6, U+25BC, U+FE0E, U+FEFF, U+FFFD;
}

:root {
  /* TEMA CLARO (Iván, 17-oct-2026): blanco + «blanco roto» como Wismify v5 claro; tinta #14181f;
     lima #c2fc03 SOLO en unos pocos CTA de resalte (nav «Hablemos», botón del email del hero…) */
  --bg: #ffffff;
  --bg-1: #faf9f6;
  --bg-2: #f4f2ee;
  --fg: #14181f;
  --fg-1: rgba(20, 24, 31, 0.88);
  --fg-2: rgba(20, 24, 31, 0.68);
  --fg-3: rgba(20, 24, 31, 0.66);
  --fg-4: rgba(20, 24, 31, 0.62);
  --line: rgba(15, 20, 30, 0.10);
  --line-2: rgba(15, 20, 30, 0.14);
  --line-3: rgba(15, 20, 30, 0.22);
  --fill-1: rgba(15, 20, 30, 0.025);
  --fill-2: rgba(15, 20, 30, 0.045);
  --accent: #c2fc03;
  --accent-ink: #14181f;
  --inv-bg: #14181f;
  --inv-fg: #f7f6f3;
  --shadow-warm: rgba(60, 50, 35, 0.10);

  --font: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --hand: 'Permanent Marker', 'Marker Felt', 'Comic Sans MS', cursive;

  --ease: cubic-bezier(0.22, 0.8, 0.28, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);

  --r-xs: 10px;
  --r-sm: 13px;
  --r: 16px;
  --r-lg: 18px;
  --pill: 999px;

  --maxw: 1240px;
  /* margen lateral: nunca bajo el notch de un iPhone en horizontal (viewport-fit=cover) */
  --gutter: max(clamp(16px, 4vw, 44px), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  --sec: clamp(100px, 12vw, 160px);

  /* Paneles claros: blanco con un poso cálido abajo (v5), borde fino y sombra cálida suave */
  --glass-bg: linear-gradient(165deg, #ffffff 0%, #ffffff 42%, #faf8f4 100%);
  --glass-shadow: 0 14px 40px rgba(60, 50, 35, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.9);
  --glass-shadow-hover: 0 22px 54px rgba(60, 50, 35, 0.13), inset 0 1px 0 rgba(255, 255, 255, 0.95);
  --glass-blur: blur(14px) saturate(140%);
  /* cristal flotante claro (nav, CTA flotante, menú, cursor): blanco translúcido + blur */
  --lg-bg:
    radial-gradient(120% 70% at 50% -30%, rgba(255, 255, 255, 0.9), transparent 60%),
    linear-gradient(165deg, rgba(255, 255, 255, 0.82) 0%, rgba(255, 255, 255, 0.72) 50%, rgba(250, 248, 244, 0.78) 100%);
  --lg-blur: blur(20px) saturate(160%);
  --lg-flat-bg: linear-gradient(165deg, #ffffff 0%, #fbfaf7 55%, #f6f4ef 100%);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  background: var(--bg);
  color-scheme: light;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Con overflow solo en body, el valor se propaga al viewport y en móvil el viewport de layout crece hasta
     el contenido que se sale (p. ej. 405 px en un iPhone de 390). Con html también en clip, body recorta
     su propio contenido y la página nunca es más ancha que la pantalla. */
  overflow-x: clip;
  /* el foco con teclado (scroll nativo: táctil / reduced-motion) nunca queda bajo la nav ni el CTA flotante */
  scroll-padding-top: 88px;
  scroll-padding-bottom: 96px;
}
html, body { margin: 0; }
body {
  background: var(--bg);
  color: var(--fg-1);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
  min-height: 100vh;
}
img, svg, video, canvas, iframe { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4, p, ul, ol, figure, blockquote, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
::selection { background: #c2fc03; color: #14181f; }
:focus-visible { outline: 2px solid rgba(20, 24, 31, 0.8); outline-offset: 3px; border-radius: 6px; }
[hidden] { display: none !important; }
.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;
}
.skip {
  position: fixed; left: 16px; top: -80px; z-index: 1000;
  padding: 10px 16px; border-radius: var(--pill);
  background: var(--inv-bg); color: var(--inv-fg); font-weight: 600; font-size: 13px;
  transition: top 0.25s var(--ease);
}
.skip:focus { top: 16px; }
main:focus { outline: none; }

/* Enlaces pendientes de URL (data-todo y SIN href: redes de Iván, canal SOTO.IA): no se muestran hasta tener la
   URL verificada (al ponerle href vuelven solos). También se oculta el <li> que solo los contiene y la lista
   que se queda sin ningún enlace real. */
a[data-todo]:not([href]) { display: none !important; }
li:has(> a[data-todo]:not([href]):only-child) { display: none !important; }
ul:has(> li > a[data-todo]:not([href])):not(:has(> li > a[href], > li > :not(a))) { display: none !important; }

/* ---------- Fondo: puntos + puntos reactivos + orbes ---------- */
.bg { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
/* Puntos base: rejilla CSS (coste cero). La capa interior se desplaza con transform (core.js, parallax
   suave con el scroll) dentro de la máscara fija → sin repintar el fondo en cada frame. */
.bg-dots {
  position: absolute; inset: -40px 0; overflow: hidden;
  -webkit-mask-image: radial-gradient(120% 85% at 50% 35%, #000 25%, rgba(0, 0, 0, 0.35) 70%, transparent 100%);
  mask-image: radial-gradient(120% 85% at 50% 35%, #000 25%, rgba(0, 0, 0, 0.35) 70%, transparent 100%);
}
.bg-dots > i {
  position: absolute; left: 0; right: 0; top: 0; bottom: -12px; display: block;
  background-image: radial-gradient(rgba(40, 34, 24, 0.17) 0.9px, transparent 1.25px);
  background-size: 12px 12px;
  will-change: transform;
}
/* Puntos reactivos: canvas que solo pinta los puntos cercanos al cursor (core.js, solo puntero fino) */
.bg-fx {
  position: absolute; inset: 0; width: 100%; height: 100%; display: none;
  -webkit-mask-image: radial-gradient(130% 100% at 50% 35%, #000 40%, rgba(0, 0, 0, 0.55) 80%, rgba(0, 0, 0, 0.3) 100%);
  mask-image: radial-gradient(130% 100% at 50% 35%, #000 40%, rgba(0, 0, 0, 0.55) 80%, rgba(0, 0, 0, 0.3) 100%);
}
.has-dotfx .bg-fx { display: block; }
/* Orbes: degradados radiales ya difusos (sin filter: blur). Solo se mueven con el hero a la vista
   (core.js pone html.sw-amb-on); el resto del tiempo, en pausa: en reposo no se recompone nada. */
.amb { position: absolute; inset: 0; overflow: hidden; }
.amb i {
  position: absolute; display: block;
  width: 60vmax; height: 60vmax; border-radius: 50%;
  opacity: 0.55; animation-play-state: paused !important;
}
html.sw-amb-on .amb i { animation-play-state: running !important; }
.amb .o1 { top: -25vmax; left: -18vmax; background: radial-gradient(circle, rgba(120, 105, 70, 0.07), transparent 62%); animation: amb-a 26s ease-in-out infinite alternate; }
.amb .o2 { top: 22%; right: -28vmax; background: radial-gradient(circle, rgba(120, 105, 70, 0.06), transparent 60%); animation: amb-b 32s ease-in-out infinite alternate; }
.amb .o3 { bottom: -30vmax; left: 12%; background: radial-gradient(circle, rgba(120, 105, 70, 0.05), transparent 65%); animation: amb-c 38s ease-in-out infinite alternate; }
@keyframes amb-a { to { transform: translate(9vmax, 7vmax) scale(1.12); } }
@keyframes amb-b { to { transform: translate(-8vmax, -6vmax) scale(0.92); } }
@keyframes amb-c { to { transform: translate(6vmax, -9vmax) scale(1.08); } }
.bg-vignette { display: none; }

#smooth-wrapper { position: relative; z-index: 1; }
#smooth-content { position: relative; }

/* ---------- Tipografía ---------- */
.kicker {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--fg-3);
}
.kicker::before { content: ''; width: 18px; height: 1px; background: currentColor; opacity: 0.7; }
.display {
  font-weight: 900; letter-spacing: -0.055em; line-height: 0.9;
  font-size: clamp(48px, 9.2vw, 148px); color: var(--fg);
}
.h2 {
  font-weight: 800; letter-spacing: -0.045em; line-height: 0.98;
  font-size: clamp(34px, 5.4vw, 76px); color: var(--fg);
}
.h3 { font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; font-size: clamp(18px, 1.7vw, 22px); color: var(--fg); }
.lead { font-size: clamp(14px, 1.12vw, 16px); line-height: 1.65; color: var(--fg-2); max-width: 58ch; }
.body { font-size: 13.5px; line-height: 1.65; color: var(--fg-2); }
.small { font-size: 12.5px; color: var(--fg-3); }
.mono { font-family: var(--mono); }
.label { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-3); }
/* «Contorno» sin -webkit-text-stroke (Inter variable dibuja los solapes): relleno gris tenue.
   Compatible con SplitText; combínalo con .fade-y si quieres que se apague hacia abajo. */
.outline { color: rgba(20, 24, 31, 0.32); -webkit-text-stroke: 0; }
.dim { color: var(--fg-3); }
/* Degradado vertical aplicado como máscara (compatible con SplitText, no se pierde al partir) */
.fade-y { -webkit-mask-image: linear-gradient(180deg, #000 35%, rgba(0, 0, 0, 0.55) 100%); mask-image: linear-gradient(180deg, #000 35%, rgba(0, 0, 0, 0.55) 100%); }
/* Degradado con background-clip:text (texto NO partido). Si se parte con SplitText, el fix: */
.grad { background: linear-gradient(180deg, #14181f 0%, rgba(20, 24, 31, 0.62) 100%); -webkit-background-clip: text; background-clip: text; color: transparent; }
.grad div { background: inherit; -webkit-background-clip: text; background-clip: text; color: transparent; }
/* Máscaras de línea de SplitText: margen para acentos y descendentes */
.sl-mask { padding: 0.12em 0 0.14em; margin: -0.12em 0 -0.14em; }

/* ---------- Layout ---------- */
.wrap { width: min(100% - 2 * var(--gutter), var(--maxw)); margin-inline: auto; }
.s { position: relative; padding: calc(var(--sec) * 0.5) 0; }
.s-head { display: grid; gap: 18px; margin-bottom: clamp(40px, 5vw, 72px); }
.s-head .lead { margin-top: 4px; }
.s-head--center { justify-items: center; text-align: center; }
.s-head--center .lead { margin-inline: auto; }

/* ---------- Cristal ---------- */
/* Panel de página: SIN backdrop-filter (ver la regla de cristal arriba) */
.glass {
  position: relative;
  background: var(--glass-bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow);
}
/* Opt-in para 1-2 paneles protagonistas de toda la página */
.glass-blur { -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
/* Liquid glass para elementos FLOTANTES (nav, menú, CTA flotante, cursor, toast, modal): blur + reflejo superior + borde fino */
.lg {
  position: relative;
  background: var(--lg-bg);
  -webkit-backdrop-filter: var(--lg-blur);
  backdrop-filter: var(--lg-blur);
  border: 1px solid rgba(15, 20, 30, 0.10);
  box-shadow: 0 14px 40px rgba(60, 50, 35, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
/* Mismo aspecto de flotante pero SIN blur, para chips/insignias que flotan DENTRO de la página
   (van en #smooth-content y se re-desenfocarían en cada frame de scroll): fondo más denso para leerse igual. */
.lg.lg--flat, .lg--flat {
  -webkit-backdrop-filter: none; backdrop-filter: none;
  background: var(--lg-flat-bg);
}
/* Red de seguridad: un .lg dentro de la página sin --flat tampoco desenfoca (ScrollSmoother lo movería en cada
   frame). El fondo denso va con especificidad baja (:where) para que el fondo propio de una sección siga mandando. */
#smooth-content .lg:not(.lg--flat) { -webkit-backdrop-filter: none; backdrop-filter: none; }
:where(#smooth-content) .lg:not(.lg--flat) { background: var(--lg-flat-bg); }
/* FIRMA: degradado en esquinas diagonales opuestas en TODO panel de cristal */
.corner-glass { position: relative; }
.corner-glass::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
  background:
    radial-gradient(160px 100px at 0% 0%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4) 45%, transparent 75%),
    radial-gradient(160px 100px at 100% 100%, rgba(244, 240, 232, 0.7), rgba(244, 240, 232, 0.25) 45%, transparent 75%);
}
.corner-glass > * { position: relative; z-index: 1; }
/* Caja interior (cajas dentro de cajas): radio interior = radio exterior − padding */
.box {
  position: relative;
  background: linear-gradient(165deg, #faf9f6, #f6f4ef 60%, #f2efe9);
  border: 1px solid rgba(15, 20, 30, 0.08);
  border-radius: var(--r-sm);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
}

/* Spotlight que sigue al ratón (SW.spotlight añade .spot y fija --mx/--my) */
.spot { --mx: 50%; --my: 50%; }
.spot::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
  background: radial-gradient(220px circle at var(--mx) var(--my), rgba(120, 105, 70, 0.07), transparent 65%);
  opacity: 0; transition: opacity 0.35s ease;
}
/* Hover de tarjetas: lift + borde + sombra profunda.
   !important en translate: GSAP 3.15 fija `translate/rotate/scale: none` EN LÍNEA en todo elemento al que
   aplica un transform (reveal, tilt, magnético…), y eso anularía el lift. */
.card-h { transition: border-color 0.35s ease, box-shadow 0.35s ease, translate 0.5s var(--ease), background 0.35s ease; }
@media (hover: hover) {
  .spot:hover::after { opacity: 1; }
  .card-h:hover { translate: 0 -4px !important; border-color: var(--line-3); box-shadow: var(--glass-shadow-hover); }
}

/* ---------- Botones ----------
   HTML horneado: <a class="btn btn-primary"><span class="btn-label">Texto</span><span class="arrow" aria-hidden="true"></span></a>
   core.js (SW.button) lo envuelve en runtime (sin tocar .btn-label, que sigue siendo el texto accesible):
     .btn-txt > .btn-label + .btn-copy[aria-hidden]   → texto que rueda (la copia sube)
     .btn-arr[aria-hidden] > .arrow + .arrow (clon)  → flecha que se intercambia
   Hover: relleno circular desde el punto de entrada (::before, --fx/--fy), barrido de brillo (::after),
   lift 2 px y magnético (GSAP x/y). Mismo efecto con :focus-visible. */
.btn {
  --h: 46px;
  --btn-fill: rgba(15, 20, 30, 0.06);
  position: relative; isolation: isolate; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  height: var(--h); padding: 0 22px; border-radius: var(--pill);
  font-size: 13px; font-weight: 600; letter-spacing: -0.005em; white-space: nowrap;
  border: 1px solid transparent;
  transition: background 0.3s ease, border-color 0.35s ease, color 0.4s var(--ease-io), translate 0.4s var(--ease), box-shadow 0.4s ease;
}
.btn::before {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  left: var(--fx, 50%); top: var(--fy, 50%);
  width: 260%; aspect-ratio: 1; border-radius: 50%;
  background: var(--btn-fill);
  translate: -50% -50%; scale: 0;
  transition: scale 0.65s var(--ease-io);
}
.btn::after {
  content: ''; position: absolute; top: -10%; bottom: -10%; left: -70%; width: 45%; z-index: -1;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: skewX(-18deg); transition: left 0.8s var(--ease); pointer-events: none;
}
.btn-label { position: relative; display: inline-block; }
.btn-primary { --btn-fill: #2a2f38; background: var(--inv-bg); color: var(--inv-fg); box-shadow: 0 10px 26px rgba(20, 24, 31, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.08); }
/* resalte lima (pocos elementos: nav «Hablemos», botón del email del hero…) */
.btn-lime { --btn-fill: #b2ea00; background: var(--accent); color: var(--accent-ink); box-shadow: 0 8px 22px rgba(130, 170, 0, 0.22), inset 0 -1px 0 rgba(0, 0, 0, 0.06); }
.btn-lime::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent); }
.btn-primary::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.28), transparent); }
.btn-ghost {
  --btn-fill: var(--inv-bg);
  background: var(--glass-bg); color: var(--fg); border-color: var(--line-2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
.btn-sm { --h: 34px; padding: 0 14px; font-size: 12px; gap: 8px; }
.btn-lg { --h: 54px; padding: 0 28px; font-size: 14px; }
.btn[disabled], .btn[aria-disabled='true'] { opacity: 0.45; pointer-events: none; }
.btn:focus-visible::before { scale: 1; }
.btn-ghost:focus-visible { color: var(--inv-fg); }
@media (hover: hover) {
  .btn:hover { translate: 0 -2px !important; }  /* !important: el magnético (GSAP) fija translate:none en línea */
  .btn:hover::before { scale: 1; }
  .btn:hover::after { left: 130%; }
  .btn-primary:hover { box-shadow: 0 16px 36px rgba(20, 24, 31, 0.26); }
  .btn-lime:hover { box-shadow: 0 14px 30px rgba(130, 170, 0, 0.32); }
  /* el relleno de tinta crece desde el ratón: el texto y la flecha pasan a claro (invertido) */
  .btn-ghost:hover { color: var(--inv-fg); border-color: var(--inv-bg); }
}
/* Texto que rueda: máscara con margen para acentos/descendentes */
.btn-txt { position: relative; display: inline-grid; overflow: hidden; padding: 0.22em 0.04em; margin: -0.22em -0.04em; }
.btn-txt > .btn-label, .btn-txt > .btn-copy { grid-area: 1 / 1; transition: translate 0.55s var(--ease-io); }
.btn-copy { display: inline-block; translate: 0 125%; }
.sw-roll:focus-visible .btn-txt > .btn-label { translate: 0 -125%; }
.sw-roll:focus-visible .btn-txt > .btn-copy { translate: 0 0; }
/* Flecha que se intercambia (la que hay sale, entra una copia) */
.btn-arr { position: relative; display: inline-grid; place-items: center; overflow: hidden; padding: 6px; margin: -6px; flex: none; }
.btn-arr > .arrow { grid-area: 1 / 1; transition: translate 0.55s var(--ease-io); }
.btn-arr > .arrow + .arrow { translate: -24px 0; }
.btn-arr > .arrow--ext + .arrow--ext { translate: -24px 24px; }
.sw-roll:focus-visible .btn-arr > .arrow:first-child { translate: 24px 0; }
.sw-roll:focus-visible .btn-arr > .arrow--ext:first-child { translate: 24px -24px; }
.sw-roll:focus-visible .btn-arr > .arrow + .arrow { translate: 0 0; }
@media (hover: hover) {
  .sw-roll:hover .btn-txt > .btn-label { translate: 0 -125%; }
  .sw-roll:hover .btn-txt > .btn-copy { translate: 0 0; transition-delay: 0.03s; }
  .sw-roll:hover .btn-arr > .arrow:first-child { translate: 24px 0; }
  .sw-roll:hover .btn-arr > .arrow--ext:first-child { translate: 24px -24px; }
  .sw-roll:hover .btn-arr > .arrow + .arrow { translate: 0 0; transition-delay: 0.05s; }
}
/* Flecha dibujada con pseudo-elementos (nunca caracteres dentro: el i18n podría borrarlos) */
.arrow { position: relative; display: inline-block; width: 14px; height: 10px; flex: none; transition: translate 0.4s var(--ease); }
.arrow::before { content: ''; position: absolute; left: 0; right: 1px; top: 50%; height: 1.5px; margin-top: -0.75px; background: currentColor; border-radius: 2px; }
.arrow::after { content: ''; position: absolute; right: 1px; top: 50%; width: 6px; height: 6px; margin-top: -3px; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; transform: rotate(45deg); }
@media (hover: hover) { .btn:hover > .arrow, a:hover > .arrow { translate: 3px 0; } }
.arrow--ext { transform: rotate(-45deg); }

/* Enlace mono con subrayado animado */
.link {
  position: relative; display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-1);
  padding-bottom: 4px;
}
.link::before { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: currentColor; opacity: 0.35; transform-origin: 0 50%; transition: transform 0.5s var(--ease), opacity 0.3s; }
@media (hover: hover) { .link:hover::before { opacity: 0.9; } }

/* Chips y pills */
.chip {
  display: inline-flex; align-items: center; gap: 8px; height: 28px; padding: 0 12px; border-radius: var(--pill);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-2);
  border: 1px solid var(--line); background: #ffffff;
}
.chip-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.chip--accent { color: var(--accent); border-color: rgba(74, 222, 128, 0.35); background: rgba(74, 222, 128, 0.06); }

/* Checks con pseudo-elementos */
.checks { display: grid; gap: 9px; }
.checks li { position: relative; padding-left: 22px; font-size: 13px; line-height: 1.5; color: var(--fg-2); }
.checks li::before {
  content: ''; position: absolute; left: 2px; top: 0.5em; width: 9px; height: 5px;
  border-left: 1.5px solid var(--fg-1); border-bottom: 1.5px solid var(--fg-1); transform: rotate(-45deg);
}

/* ---------- Estados iniciales de los efectos ----------
   Solo con JS activo (html.sw-js) y siempre con red de seguridad (.sw-nofx lo muestra todo).
   [data-reveal] y [data-stagger] > * solo se ocultan HASTA que core arranca (html.sw-booted) y SOLO con opacity
   (nunca visibility: lo que aún no ha entrado sigue en el orden de Tab y en el árbol de accesibilidad); a partir
   de ahí el estado oculto lo pone GSAP en línea, así que nada añadido después queda invisible. Con
   prefers-reduced-motion no se ocultan nunca. */
.sw-js .rv { opacity: 0; }
.sw-js [data-split], .sw-js [data-fx] { visibility: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .sw-js:not(.sw-booted) [data-reveal], .sw-js:not(.sw-booted) [data-stagger] > * { opacity: 0; }
}
.sw-nofx .rv, .sw-nofx [data-split], .sw-nofx [data-fx], .sw-nofx [data-reveal] { opacity: 1 !important; visibility: visible !important; transform: none !important; clip-path: none !important; }
.sw-nofx [data-stagger] > * { opacity: 1 !important; visibility: visible !important; }

/* ---------- Nav fija y flotante (17-oct: más ancha, menos redondeada, logo de Wismify, siempre visible) ---------- */
.nav {
  position: fixed; top: max(14px, env(safe-area-inset-top, 0px)); left: 0; right: 0; z-index: 100;
  display: flex; justify-content: center; padding: 0 var(--gutter); pointer-events: none;
}
.nav-bar {
  pointer-events: auto; position: relative;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px;
  width: min(1240px, 100%); height: 62px; padding: 0 10px 0 22px; border-radius: 14px;
  transition: background-color 0.4s ease, box-shadow 0.4s ease;
}
/* al bajar, un poco más densa: el contenido que pasa por debajo no compite con los enlaces */
.nav-bar.lg {
  background: linear-gradient(165deg, rgba(255, 255, 255, 0.58) 0%, rgba(255, 255, 255, 0.40) 55%, rgba(250, 248, 244, 0.46) 100%);
  -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
  border-color: rgba(15, 20, 30, 0.09);
}
.nav.is-scrolled .nav-bar { box-shadow: 0 12px 34px rgba(60, 50, 35, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.7); }
.brand { justify-self: start; display: inline-flex; align-items: center; padding: 8px 6px 8px 0; border-radius: 8px; color: var(--fg); }
.brand-logo { display: block; height: 22px; width: auto; opacity: 0.94; transition: opacity 0.3s ease; }
@media (hover: hover) { .brand:hover .brand-logo { opacity: 1; } }
.nav-links {
  --il: 0px; --ir: 0px; --io: 0;
  position: relative; isolation: isolate;
  display: flex; align-items: center; gap: 2px;
}
.nav-links a {
  display: block; padding: 9px 13px; border-radius: 8px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-2);
  transition: color 0.25s ease, background 0.25s ease;
}
.nav-links a:hover, .nav-links a.is-active { color: var(--fg); background: rgba(15, 20, 30, 0.05); }
/* Indicador deslizante (core.js mueve --il/--ir con clip-path; sin animar width) */
.nav-links::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none; border-radius: 8px;
  background: rgba(15, 20, 30, 0.055); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
  clip-path: inset(0 var(--ir) 0 var(--il) round 8px);
  opacity: var(--io);
}
.nav-links.has-ind a:hover, .nav-links.has-ind a.is-active { background: transparent; }
.nav-end { justify-self: end; display: flex; align-items: center; gap: 8px; }
.nav-cta.btn { --h: 42px; border-radius: 10px; padding: 0 18px; }
/* el logo de Wismify es negro: en el tema claro va tal cual (sin invertir) */
.nav-burger { display: none; position: relative; width: 42px; height: 42px; border-radius: 10px; border: 1px solid var(--line-2); transition: border-color 0.3s ease, background 0.3s ease; }
.nav-burger span { position: absolute; left: 12px; right: 12px; height: 1.5px; background: var(--fg); border-radius: 2px; transition: transform 0.4s var(--ease), top 0.4s var(--ease); }
.nav-burger span:nth-child(1) { top: 17px; }
.nav-burger span:nth-child(2) { top: 23px; }
.nav-burger[aria-expanded='true'] span:nth-child(1) { top: 20px; transform: rotate(45deg); }
.nav-burger[aria-expanded='true'] span:nth-child(2) { top: 20px; transform: rotate(-45deg); }
@media (hover: hover) { .nav-burger:hover { border-color: var(--line-3); background: rgba(15, 20, 30, 0.04); } }
@media (max-width: 980px) {
  .nav-links { display: none; }
  .nav-burger { display: inline-block; }
  .nav-bar { grid-template-columns: 1fr auto; height: 56px; padding: 0 7px 0 16px; border-radius: 12px; }
  .brand-logo { height: 19px; }
  .nav-cta.btn { --h: 40px; }
}
/* Sin JS el botón del menú no haría nada: fuera (la navegación completa está en el pie) */
.no-js .nav-burger { display: none; }
@media (max-width: 380px) {
  .brand-logo { height: 17px; }
  .nav-cta.btn { padding: 0 12px; }
  .nav-cta .btn-arr, .nav-cta > .arrow { display: none; }
}

/* Pie mínimo de /hablemos */
.mini-foot { position: relative; z-index: 1; padding: 28px 0 40px; border-top: 1px solid var(--line); font-size: 12px; color: var(--fg-3); }
.mini-foot-in { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.mini-foot-links { display: flex; gap: 18px; }
.mini-foot a { color: var(--fg-2); transition: color 0.2s ease; }
@media (hover: hover) { .mini-foot a:hover { color: var(--fg); } }

/* Menú móvil. Si su contenido no cabe (móvil en horizontal, iPhone SE con las barras de Safari) se desplaza
   dentro; el centrado es «seguro» (márgenes automáticos): con hueco se centra, sin hueco empieza bajo la nav. */
.menu {
  position: fixed; z-index: 99; border-radius: 16px;
  inset: max(10px, env(safe-area-inset-top, 0px)) max(10px, env(safe-area-inset-right, 0px)) max(10px, env(safe-area-inset-bottom, 0px)) max(10px, env(safe-area-inset-left, 0px));
  /* tinte más denso que .lg: a pantalla completa, el titular de detrás no debe competir con los enlaces */
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(255, 255, 255, 0.95), transparent 60%),
    linear-gradient(165deg, rgba(255, 255, 255, 0.94) 0%, rgba(247, 245, 240, 0.97) 100%);
  display: flex; flex-direction: column; justify-content: flex-start; gap: 26px; padding: 96px 26px 26px;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  opacity: 0; visibility: hidden; scale: 0.985; transition: opacity 0.45s ease, visibility 0.45s, scale 0.6s var(--ease);
}
.menu > :first-child { margin-top: auto; }
.menu > :last-child { margin-bottom: auto; }
/* al abrir, visible al instante (para poder mover el foco dentro); al cerrar, la transición de .menu lo retrasa */
.menu.is-open { opacity: 1; visibility: visible; scale: 1; transition: opacity 0.45s ease, visibility 0s, scale 0.6s var(--ease); }
.menu-links { display: grid; gap: 2px; }
/* cada enlace dentro de su máscara (sube con stagger al abrir); margen para el anillo de foco */
.menu-links li { overflow: hidden; padding: 6px 8px; margin: -6px -8px; }
.menu-links a { display: flex; align-items: baseline; gap: 14px; padding: 6px 0; font-size: clamp(30px, 9vw, 44px); font-weight: 800; letter-spacing: -0.04em; line-height: 1.1; color: var(--fg); }
.menu-idx { font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.14em; color: var(--fg-3); translate: 0 -0.9em; }
.menu-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 10px; }
.menu-cta { display: grid; gap: 10px; justify-items: start; }
.menu-note { font-size: 12px; line-height: 1.5; color: var(--fg-3); }
html.menu-open, html.menu-open body { overflow: hidden; }
@media (max-height: 560px) {
  .menu { padding-top: 76px; gap: 14px; }
  .menu-links a { font-size: clamp(22px, 7vh, 34px); }
  .menu-foot { margin-top: 2px; }
}
@media (max-height: 560px) and (orientation: landscape) {
  .menu-links { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 28px; }
}

/* ---------- Cursor (solo con html.has-cursor: puntero fino, sin reduced-motion) ---------- */
.cursor-dot, .cursor-pill { position: fixed; left: 0; top: 0; z-index: 500; pointer-events: none; display: none; }
/* GSAP mueve .cursor-dot (x/y y el «squash» al pulsar); los estados CSS van en el <i> de dentro
   (GSAP fija scale:none en línea en lo que transforma). mix-blend-mode en el elemento fijo. */
.cursor-dot { width: 0; height: 0; mix-blend-mode: difference; }
.cursor-dot > i {
  position: absolute; left: -3px; top: -3px; width: 6px; height: 6px; border-radius: 50%; background: #fff; /* blanco + mix-blend difference = se ve oscuro sobre claro */
  opacity: 0; transition: opacity 0.3s ease, scale 0.45s var(--ease-out);
}
.has-cursor .cursor-dot { display: block; }
.cursor-dot.is-on > i { opacity: 1; }
/* sobre enlaces/botones el punto se recoge (manda el hover del propio elemento); sobre campos y zonas con píldora, fuera */
.cursor-dot.is-link > i, .cursor-dot.is-text > i, .cursor-dot.is-pill > i { opacity: 0; scale: 0.3; }
/* Píldora de cristal líquido con la etiqueta de [data-cursor] (GSAP la mueve, la escala y la funde).
   Base ahumada densa: el texto se lee aunque pase por encima de algo claro; sobre una superficie clara
   (core.js la detecta) pasa a la variante oscura opaca .is-light. */
.cursor-pill {
  align-items: center; height: 38px; padding: 0 16px 0 13px; border-radius: var(--pill);
  font-family: var(--mono); font-size: 10.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--fg); white-space: nowrap; visibility: hidden; opacity: 0;
  background:
    radial-gradient(120% 70% at 50% -30%, rgba(255, 255, 255, 0.95), transparent 60%),
    linear-gradient(165deg, rgba(255, 255, 255, 0.86) 0%, rgba(250, 248, 244, 0.9) 100%);
  transition: background-color 0.3s ease, border-color 0.3s ease;
}
.cursor-pill.is-light {
  background: rgba(20, 24, 31, 0.94);
  color: #f7f6f3;
  border-color: rgba(20, 24, 31, 0.6);
  box-shadow: 0 12px 34px rgba(20, 24, 31, 0.25);
}
.has-cursor .cursor-pill { display: inline-flex; }
.cursor-pill.corner-glass::before {
  background:
    radial-gradient(70px 40px at 0% 0%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.3) 45%, transparent 75%),
    radial-gradient(70px 40px at 100% 100%, rgba(244, 240, 232, 0.6), rgba(244, 240, 232, 0.2) 45%, transparent 75%);
}
.cursor-label { display: inline-flex; align-items: center; gap: 9px; }
.cursor-label::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: none; }
/* El cursor del sistema SOLO se oculta en la zona etiquetada activa (core.js pone .is-cursor-zone) */
.has-cursor .is-cursor-zone, .has-cursor .is-cursor-zone * { cursor: none; }
.has-cursor .is-cursor-zone :is(input, textarea, select) { cursor: auto; }

/* ---------- Progreso ---------- */
.progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 200; pointer-events: none; }
.progress span { display: block; height: 100%; background: linear-gradient(90deg, rgba(20, 24, 31, 0.15), rgba(20, 24, 31, 0.85)); transform-origin: 0 50%; transform: scaleX(0); }

/* ---------- CTA flotante ----------
   .fcta-wrap (fijo) entra/sale con translate + visibility; .fcta (el enlace de cristal) se funde y es el
   que mueve el magnético de GSAP. Nunca pongas translate/scale CSS de reposo en algo que GSAP transforma.
   core.js lo aparta (quita .is-on) con el formulario o el pie a la vista, el menú abierto, tras enviar la
   solicitud y mientras haya bajo su franja un control de la página o una zona [data-fcta-hide]. */
.fcta-wrap {
  position: fixed; right: max(22px, env(safe-area-inset-right, 0px)); bottom: max(22px, env(safe-area-inset-bottom, 0px)); z-index: 90; pointer-events: none;
  visibility: hidden; translate: 0 24px;
  transition: visibility 0.45s, translate 0.6s var(--ease);
}
.fcta-wrap.is-on { visibility: visible; translate: 0 0; }
.fcta {
  pointer-events: auto;
  display: inline-flex; align-items: center; gap: 14px; height: 54px; padding: 0 8px 0 20px; border-radius: var(--pill);
  font-size: 13px; font-weight: 600; color: var(--fg); white-space: nowrap;
  opacity: 0; transition: opacity 0.45s ease, border-color 0.3s;
  /* siempre legible aunque pase por encima de un botón blanco: cristal más denso que el .lg general */
  background:
    radial-gradient(120% 70% at 50% -30%, rgba(255, 255, 255, 0.95), transparent 60%),
    linear-gradient(165deg, rgba(255, 255, 255, 0.9) 0%, rgba(250, 248, 244, 0.92) 100%);
}
.fcta-wrap.is-on .fcta { opacity: 1; }
.fcta-arrow {
  position: relative; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; flex: none;
  background: var(--inv-bg); color: var(--inv-fg); transition: scale 0.5s var(--ease-out), background 0.3s ease;
}
@media (hover: hover) {
  .fcta:hover { border-color: var(--line-3); }
  .fcta:hover .fcta-arrow { scale: 1.08; background: #c2fc03; color: #14181f; }
}
@media (max-width: 640px) {
  .fcta-wrap { left: var(--gutter); right: var(--gutter); bottom: max(14px, env(safe-area-inset-bottom, 0px)); }
  .fcta { display: flex; justify-content: space-between; }
}

/* ---------- Toast de idioma ----------
   Arriba, bajo la nav (nunca tapa la primera pantalla: en escritorio va al hueco libre de la derecha; en
   móvil core.js lo saca tras el primer scroll). Si la nav se esconde, sube a su sitio. Solo vive en el hero
   y se cierra solo (core.js). */
.toast {
  position: fixed; top: 78px; right: max(22px, env(safe-area-inset-right, 0px)); z-index: 95;
  display: flex; align-items: center; gap: 12px; max-width: calc(100vw - 2 * var(--gutter));
  padding: 10px 10px 10px 18px; border-radius: var(--pill); font-size: 12.5px; color: var(--fg-1);
  animation: toast-in 0.7s var(--ease) backwards;
  transition: top 0.55s var(--ease), opacity 0.4s ease, translate 0.5s var(--ease);
}
.nav.is-hidden ~ .toast { top: max(14px, env(safe-area-inset-top, 0px)); }
.toast.is-out { opacity: 0; translate: 0 -10px; pointer-events: none; }
.toast-x { position: relative; width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--line); flex: none; transition: border-color 0.3s ease; }
.toast-x::before, .toast-x::after { content: ''; position: absolute; left: 9px; right: 9px; top: 50%; height: 1.2px; background: var(--fg-2); }
.toast-x::before { transform: rotate(45deg); }
.toast-x::after { transform: rotate(-45deg); }
@media (hover: hover) { .toast-x:hover { border-color: var(--line-3); } }
@keyframes toast-in { from { opacity: 0; translate: 0 -12px; } }
@media (max-width: 980px) { .toast { top: 72px; } }
@media (max-width: 640px) { .toast { left: var(--gutter); right: var(--gutter); justify-content: space-between; } }

/* ---------- Modal (refracción de borde) ---------- */
.modal { position: fixed; inset: 0; z-index: 400; display: grid; place-items: center; padding: 20px; visibility: hidden; pointer-events: none; }
.modal.is-open { visibility: visible; pointer-events: auto; }
.modal-backdrop {
  position: absolute; inset: 0; background: rgba(40, 34, 24, 0.22);
  -webkit-backdrop-filter: blur(6px) saturate(120%); backdrop-filter: blur(6px) saturate(120%);
  opacity: 0; transition: opacity 0.45s ease;
}
.modal.is-open .modal-backdrop { opacity: 1; }
.modal-panel {
  width: min(600px, 100%); max-height: calc(100svh - 40px); overflow: auto; overscroll-behavior: contain;
  border-radius: 20px; padding: clamp(22px, 4vw, 34px);
  /* tema claro: panel casi opaco (que no se transparente lo de detrás) */
  background: linear-gradient(165deg, #ffffff 0%, #ffffff 50%, #faf8f4 100%);
  box-shadow: 0 40px 100px rgba(60, 50, 35, 0.22), inset 0 1px 0 #fff;
  opacity: 0; translate: 0 18px; scale: 0.98;
  transition: opacity 0.45s ease, translate 0.6s var(--ease), scale 0.6s var(--ease);
}
/* La refracción de borde (#sw-liquid) era para el tema oscuro: en claro dibujaba un borde oscuro. Fuera. */
.modal-panel--liquid { -webkit-backdrop-filter: none; backdrop-filter: none; }
.modal-panel.corner-glass::before {
  background:
    radial-gradient(230px 150px at 0% 0%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.4) 45%, transparent 75%),
    radial-gradient(230px 150px at 100% 100%, rgba(244, 240, 232, 0.7), rgba(244, 240, 232, 0.25) 45%, transparent 75%);
}
.modal.is-open .modal-panel { opacity: 1; translate: 0 0; scale: 1; }
.modal-close { position: absolute; top: 14px; right: 14px; width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--line-2); z-index: 3; }
.modal-close::before, .modal-close::after { content: ''; position: absolute; left: 11px; right: 11px; top: 50%; height: 1.4px; background: var(--fg-1); }
.modal-close::before { transform: rotate(45deg); }
.modal-close::after { transform: rotate(-45deg); }
html.modal-open, html.modal-open body { overflow: hidden; }

/* ---------- Movimiento reducido: todo visible y estático ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .amb i { animation: none !important; opacity: 0.4; }
  .sw-js .rv { opacity: 1; }
  .sw-js [data-split], .sw-js [data-fx], .sw-js [data-reveal], .sw-js [data-stagger] > * { visibility: visible; }
  .btn, .btn::before, .btn::after, .btn-txt > *, .btn-arr > *, .card-h, .nav, .fcta, .menu, .modal-panel, .toast { transition-duration: 0.01ms !important; }
}
@media (hover: none) { .amb i { opacity: 0.4; } }
