/* ═══════════════════════════════════════════════════════════════════
   unete.css — Createdby /unete
   Lenguaje visual consolidado del ecosistema (ver design-tokens.md).

   Orden del archivo:
     1. View Transitions cross-document (afecta navegación entre páginas)
     2. :root tokens
     3. Reset + base (html, body, body::before spotlight, a, img, button)
     4. Tipografía global + container + noise
     5. Glass surface — patrón canónico (referencia: .ecosistema-card)
     6. Componentes reusables (.chip, halo prismático en headings, .cta-prism)
     7. Estados de página (.splash, .page-shell, .brand-row)
     8. Secciones de motion.php (manifiesto, ecosistema, convocatoria,
        serie, video-brief, no-ofrezco, formulario)
     9. Footer + CTA flotante mobile
    10. @media (prefers-reduced-motion: reduce) global
   ═══════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════
   1 · VIEW TRANSITIONS CROSS-DOCUMENT
   Habilita un crossfade nativo entre index.php (splash) y motion.php
   al navegar same-origin. Sin view-transition-name customizados, sin
   intro phase: el contenido aparece directo en el header tras un
   crossfade ligero.
   Soporte: Chrome 126+, Edge 126+, Safari 18.2+. En el resto degrada
   a navegación estándar sin animación.
   ═══════════════════════════════════════════════════════════════════ */

@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 380ms;
}


/* ═══════════════════════════════════════════════════════════════════
   2 · TOKENS
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* Color — fondo negro, blanco, prisma como acento (los acentos vivos
     vienen del sistema prism-glass.{css,js}; --accent solo es el blanco
     translúcido para focus rings, labels de sección, bordes sutiles). */
  --bg: #000;
  --surface: #0c0c0c;
  --surface-hover: #141414;
  --border: #1f1f1f;
  --border-focus: #fff;
  --text: #fff;
  --muted: #6f6f6f;
  --muted-strong: #aaa;
  --accent:      rgba(255, 255, 255, 0.95);
  --accent-dim:  rgba(255, 255, 255, 0.18);
  --accent-glow: rgba(255, 255, 255, 0.32);
  --accent-soft: rgba(255, 255, 255, 0.05);
  --success: #4ade80;
  --error: #f87171;
  --dim: rgba(255, 255, 255, 0.05);

  /* Posición del mouse — actualizada por unete.js para el spotlight global */
  --mx: 50%;
  --my: 50%;

  /* Glass surface (patrón canónico, ver sección 5) */
  --glass-bg: rgba(255, 255, 255, 0.06);
  --glass-blur: blur(10px) brightness(0.8);
  --glass-border-top: 1px solid rgba(255, 255, 255, 0.25);
  --glass-border-bottom: 0.3px solid rgba(255, 255, 255, 0.15);

  /* Typography */
  --font-display: 'Playfair Display', Georgia, serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-accent: 'Bebas Neue', Impact, sans-serif;

  /* Radius */
  --radius-sm: 7px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  /* Spacing */
  --space-xs: 7px;
  --space-sm: 12px;
  --space-md: 22px;
  --space-lg: 38px;
  --space-xl: 60px;
  --space-2xl: 90px;

  /* Animation */
  --ease: cubic-bezier(.4, 0, .2, 1);
  --ease-soft: cubic-bezier(.25, .1, .25, 1);
  --ease-pop: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 0.2s;
  --dur-mid: 0.3s;
  --dur-slow: 0.6s;
}

/* ─── Animaciones cromáticas globales ────────────────────────────────
   `--p-hue` es la variable maestra del espectro prismático del ecosistema.
   - El motor JS (sección 5) la setea inline en cada `.prism-glass` según
     el ángulo del cursor → efecto mouse-following en cards/CTA/footer.
   - En elementos NO registrados (body::before spotlight, halo del
     Createdby gigante), la animación CSS `prism-cycle` la rota libremente
     (la inline del JS gana sobre el animation cuando aplica).
   `@property` permite interpolación suave del hue numérico. */
@property --p-hue {
  syntax: '<number>';
  inherits: true;
  initial-value: 50;
}
@keyframes prism-cycle {
  from { --p-hue: 0; }
  to   { --p-hue: 360; }
}


/* ═══════════════════════════════════════════════════════════════════
   3 · RESET + BASE
   ═══════════════════════════════════════════════════════════════════ */

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

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

body {
  background: var(--bg);
  color: var(--text);
  font: 400 16px/1.65 var(--font-body);
  min-height: 100vh;
  overflow-x: hidden;
}

/* Spotlight global mouse-following — radial-gradient sutil que sigue al
   cursor (y al dedo en mobile). El fondo NO cambia de color: es overlay
   translúcido con mix-blend-mode: screen, solo aporta luminancia. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background: radial-gradient(
    720px circle at var(--mx) var(--my),
    hsla(var(--p-hue, 50), 80%, 60%, 0.06),
    hsla(calc(var(--p-hue, 50) + 60), 80%, 60%, 0.03) 35%,
    transparent 65%
  );
  mix-blend-mode: screen;
  animation: prism-cycle 22s linear infinite;
  transition: background 80ms linear;
}

a { color: inherit; text-decoration: none; }
a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; cursor: pointer; }
strong { color: var(--text); font-weight: 600; }

/* Noise overlay (textura de fondo, heredado del placeholder) */
.noise {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.03'/%3E%3C/svg%3E");
}


/* ═══════════════════════════════════════════════════════════════════
   4 · TIPOGRAFÍA GLOBAL + CONTAINER
   ═══════════════════════════════════════════════════════════════════ */

.wrap {
  position: relative;
  z-index: 1;
  max-width: 720px;
  margin: 0 auto;
  /* padding-top a 0: el contenido pega contra el .brand-sticky de arriba
     para que el primer texto entre dentro de la franja de blur progresivo
     de 40 px del header (el efecto del blur necesita CONTENIDO debajo
     suyo para difuminar — sin contenido cerca, la franja parece vacía). */
  padding: 0 22px 90px;
}
@media (min-width: 1024px) {
  .wrap { max-width: 980px; padding: 0 40px 120px; }
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.5px;
  line-height: 1.1;
  color: var(--text);
}
h1 { font-size: clamp(40px, 8vw, 72px); line-height: 0.95; letter-spacing: -1px; }
h2 { font-size: clamp(28px, 5vw, 44px); margin-bottom: var(--space-md); }
h3 { font-size: clamp(20px, 3vw, 26px); }

.section-label {
  display: inline-block;
  font-family: var(--font-accent);
  font-size: 12.5px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
  margin-bottom: var(--space-sm);
}

.section-intro {
  color: var(--muted-strong);
  font-size: clamp(15px, 2vw, 17px);
  line-height: 1.7;
  margin-bottom: var(--space-lg);
  max-width: 620px;
}


/* ═══════════════════════════════════════════════════════════════════
   5 · GLASS SURFACE — PATRÓN CANÓNICO
   Referencia: .ecosistema-card. Todos los componentes con superficie
   "glassmorphism + bordes asimétricos" comparten el mismo bloque base.
   Los específicos solo añaden padding, layout y tipografía propios.
   ═══════════════════════════════════════════════════════════════════ */

/* Capa 1 — superficie glass (7 componentes — V19 añade .btn-submit y .cta-float) */
.ecosistema-card,
.cta-prism,
.form-card,
.form-thanks,
.site-footer,
.btn-submit,
.cta-float {
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
          backdrop-filter: var(--glass-blur);
  border-top: var(--glass-border-top);
  border-bottom: var(--glass-border-bottom);
  border-radius: var(--radius-md);
}

/* Capa 2 — receptores del motor mouse-following (necesitan recortar el
   ::after con el border-radius y aislar el stacking context).
   Estos selectores están en GLASS_SELECTORS del motor JS (sección 11).
   V19 añade .btn-submit y .cta-float — ahora 5 elementos. */
.ecosistema-card,
.cta-prism,
.site-footer,
.btn-submit,
.cta-float {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* Capa 3 — motor mouse-following.
   El JS de la sección 11 añade la clase `.prism-glass` a los elementos en
   GLASS_SELECTORS y setea inline 5 custom properties:
     --p-hue:   0-360°  ángulo cursor→centro del elemento
     --p-alpha: 0-1     opacidad superficie (decae con distancia²)
     --p-edge:  0-1     opacidad borde (decae con √distancia)
     --p-gx:    0-1     posición horizontal del gradiente hacia el cursor
     --p-gy:    0-1     posición vertical del gradiente hacia el cursor
   Cuando el cursor se aleja (3 s idle), `--p-alpha` y `--p-edge` van a 0
   y el efecto desaparece smooth. */
.prism-glass { will-change: box-shadow; }

/* Superficie: espectro cónico enmascarado hacia el cursor */
.prism-glass::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 1;
  background: conic-gradient(
    from calc(var(--p-hue, 0) * 1deg),
    hsla(0,   100%, 70%, 0.35),
    hsla(60,  100%, 65%, 0.35),
    hsla(120, 100%, 60%, 0.35),
    hsla(180, 100%, 65%, 0.35),
    hsla(240, 100%, 70%, 0.35),
    hsla(300, 100%, 65%, 0.35),
    hsla(360, 100%, 70%, 0.35)
  );
  -webkit-mask-image: radial-gradient(
    ellipse at calc(var(--p-gx, 0.5) * 100%) calc(var(--p-gy, 0.5) * 100%),
    rgba(0, 0, 0, var(--p-alpha, 0)) 0%,
    rgba(0, 0, 0, calc(var(--p-alpha, 0) * 0.25)) 45%,
    transparent 75%
  );
          mask-image: radial-gradient(
    ellipse at calc(var(--p-gx, 0.5) * 100%) calc(var(--p-gy, 0.5) * 100%),
    rgba(0, 0, 0, var(--p-alpha, 0)) 0%,
    rgba(0, 0, 0, calc(var(--p-alpha, 0) * 0.25)) 45%,
    transparent 75%
  );
  mix-blend-mode: screen;
}

/* Brillo direccional en bordes (apunta hacia el cursor) */
.prism-glass {
  box-shadow:
    inset calc((0.5 - var(--p-gx, 0.5)) * 5px) calc((0.5 - var(--p-gy, 0.5)) * 5px)
      6px 0
      hsla(var(--p-hue, 0), 100%, 75%, calc(var(--p-edge, 0) * 0.35)),
    inset calc((0.5 - var(--p-gx, 0.5)) * 12px) calc((0.5 - var(--p-gy, 0.5)) * 12px)
      20px 0
      hsla(calc(var(--p-hue, 0) + 40), 100%, 65%, calc(var(--p-edge, 0) * 0.12));
}

/* Toggle global con Ctrl+Shift+P → body.prism-off (debug útil) */
.prism-off .prism-glass::after { display: none; }
.prism-off .prism-glass { box-shadow: none !important; }

.ecosistema-card1,
.cta-prism,
.form-card,
.form-thanks,
.site-footer {
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
          backdrop-filter: var(--glass-blur);
  border-top: var(--glass-border-top);
  border-bottom: var(--glass-border-bottom);
  border-radius: var(--radius-md);
}

/* ═══════════════════════════════════════════════════════════════════
   6 · COMPONENTES REUSABLES
   ═══════════════════════════════════════════════════════════════════ */

/* ─── .chip (radio/checkbox píldora con prisma cuando está checked) ─── */
.radio-row,
.checkbox-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px;
}
.chip {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  font-size: 13.5px;
  font-weight: 400;
  color: var(--muted-strong);
  cursor: pointer;
  transition: background var(--dur-fast), border-color var(--dur-fast),
              color var(--dur-fast), box-shadow var(--dur-mid) var(--ease);
}
.chip:hover {
  background: var(--surface);
  border-color: #444;
  color: var(--text);
}
.chip input[type="radio"],
.chip input[type="checkbox"] {
  position: relative;
  z-index: 2;
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
  flex-shrink: 0;
  margin: 0;
}
.chip > span { position: relative; z-index: 2; }

/* Burbuja prisma cuando el chip está seleccionado.
   Usa --chip-hue (scope local) para no chocar con --p-hue del prism-glass.js.
   Browsers sin soporte de @property degradan a hue=50 (color estático). */
@property --chip-hue {
  syntax: '<number>';
  inherits: false;
  initial-value: 50;
}
@keyframes chip-prism-cycle {
  from { --chip-hue: 0; }
  to   { --chip-hue: 360; }
}
.chip:has(input:checked) {
  color: var(--text);
  background: var(--surface);
  border-color: transparent;
  animation: chip-prism-cycle 14s linear infinite;
  box-shadow:
    0 0 0 1px hsla(var(--chip-hue, 50), 80%, 65%, 0.55),
    0 0 14px hsla(var(--chip-hue, 50), 90%, 70%, 0.28),
    inset 0 0 0 1px hsla(var(--chip-hue, 50), 100%, 75%, 0.18);
}
.chip:has(input:checked)::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 1;
  background: conic-gradient(
    from calc(var(--chip-hue, 50) * 1deg),
    hsla(0,   100%, 70%, 0.40),
    hsla(60,  100%, 65%, 0.40),
    hsla(120, 100%, 60%, 0.40),
    hsla(180, 100%, 65%, 0.40),
    hsla(240, 100%, 70%, 0.40),
    hsla(300, 100%, 65%, 0.40),
    hsla(360, 100%, 70%, 0.40)
  );
  -webkit-mask-image: radial-gradient(ellipse at center,
    rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0.18) 50%, transparent 80%);
          mask-image: radial-gradient(ellipse at center,
    rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0.18) 50%, transparent 80%);
  mix-blend-mode: screen;
}
/* Stagger por posición para que no roten todos sincronizados (max 9 chips/grid) */
.chip:nth-of-type(2):has(input:checked) { animation-delay: -2s; }
.chip:nth-of-type(3):has(input:checked) { animation-delay: -4s; }
.chip:nth-of-type(4):has(input:checked) { animation-delay: -6s; }
.chip:nth-of-type(5):has(input:checked) { animation-delay: -8s; }
.chip:nth-of-type(6):has(input:checked) { animation-delay: -10s; }
.chip:nth-of-type(7):has(input:checked) { animation-delay: -12s; }
.chip:nth-of-type(8):has(input:checked) { animation-delay: -1s; }
.chip:nth-of-type(9):has(input:checked) { animation-delay: -5s; }

/* ─── .cta-prism (botón reusable derivado del patrón .ecosistema-card) ─── */
.cta-prism {
  /* La superficie glass + posicionamiento ya viene de la sección 5. */
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 38px;
  color: var(--text);
  text-decoration: none;
  font-family: var(--font-body);
  font-size: clamp(15px, 1.6vw, 17px);
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: transform var(--dur-mid) var(--ease),
              box-shadow var(--dur-mid) var(--ease);
}
.cta-prism:hover { transform: translateY(-2px); }
.cta-prism:active { transform: scale(0.98); }
.cta-prism:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

/* Halo prismático del TEXTO del botón — mismo motor que el "Createdby"
   gigante (attr(data-text) + background-clip: text + blur). La luz viene
   detrás de las letras, no de la superficie. Requiere `data-text="..."`
   en el HTML (ej. <a class="cta-prism" data-text="Postular">Postular</a>).
   Animación CSS pura — independiente del motor mouse-following del JS.
   V19 extiende a .btn-submit y .cta-float (selector compartido). */
.cta-prism::before,
.btn-submit::before,
.cta-float::before,
.chip:has(input:checked)::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  user-select: none;
  background: conic-gradient(
    from calc(var(--p-hue, 0) * 1deg),
    hsl(0,   100%, 65%),
    hsl(60,  100%, 60%),
    hsl(120, 100%, 55%),
    hsl(180, 100%, 60%),
    hsl(240, 100%, 65%),
    hsl(300, 100%, 60%),
    hsl(360, 100%, 65%)
  );
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  letter-spacing: inherit;
  font-family: inherit;
  font-weight: inherit;
  font-size: inherit;
  line-height: inherit;
  text-transform: inherit;
  filter: blur(8px);
  opacity: 0.7;
  z-index: -1;
  animation: prism-cycle 10s linear infinite;
}

/* Cuando .btn-submit entra en estado loading, oculta el halo del texto:
   el contenido visible es el spinner, no el texto, y el halo del texto
   detrás se vería desconectado. */
.btn-submit.loading::before { opacity: 0; }

/* Override per-chip — V20. El chip tiene texto a 13.5px (vs 14-17px en
   los botones). El blur(8px) heredado se ve desproporcionado. Reducir.
   También z-index: 0 para coexistir con ::after del chip (z=1) y el
   span (z=2) en su stacking context con `isolation: isolate`. */
.chip:has(input:checked)::before {
  filter: blur(4px);
  opacity: 0.55;
  z-index: 0;
}

/* ─── .text-prism — efecto prismático reusable para textos grandes ────
   Aplica halo difuso + contorno luminoso al texto via attr(data-text).
   Funciona con cualquier fuente/peso/tamaño (todo se hereda).

   Uso:
     <h1 class="text-prism" data-text="Createdby">Createdby</h1>

   3 capas:
   1. ::before  → halo difuso detrás del texto (siempre activo, drift orgánico).
   2. ::after   → contorno luminoso de las letras (siempre activo + se
                  intensifica cuando el cursor está cerca).
   3. JS handler (IIFE 1, sección "Text-prism cursor") — actualiza las
      variables --tp-x, --tp-y, --tp-active según la cercanía del cursor.

   Independiente del motor mouse-following del IIFE 2 (que sigue manejando
   .ecosistema-card, .cta-prism, .site-footer con su sistema de burbujas). */

.text-prism {
  position: relative;
  isolation: isolate;
  display: inline-block;
  /* El texto literal del elemento es transparente (sirve como spacer en
     flujo normal para que el .text-prism mantenga su altura natural,
     incluyendo descenders). Las dos capas visibles son los pseudos. */
  color: transparent;
  /* V22: padding adaptive en em — da espacio para que el halo blur del
     ::before (filter: blur(--tp-blur)) y el text-stroke del ::after no
     se extiendan MÁS ALLÁ del frame del elemento. Escala automáticamente
     con font-size: ~1px @16px (CREAR body), ~3.4px @56px (Createdby
     header), ~10px @168px (Createdby splash). El frame ahora abraza el
     halo en lugar de cortar las letras al límite del texto. */
  padding: 0.06em 0.12em;

  /* Configurables: radios de las zonas alrededor del cursor (en px).
     Ajusta estos valores aquí (global) o per-elemento via inline style /
     selector específico para cambiar el "alcance" del foco. */
  --tp-near: 60px;   /* radio del núcleo blanco */
  --tp-mid:  300px;  /* radio del anillo cromático */

  /* Posición del cursor relativa al rect del texto — el JS las actualiza */
  --tp-x: 0.5;
  --tp-y: 0.5;

  /* Blur reactivo de la capa principal del texto: 0 cuando el cursor
     está lejos, hasta MAX cuando está sobre el rect. El JS lo setea. */
  --tp-blur: 0px;

  /* Fade global del efecto: 0 = idle (texto en estado normal), 1 = activo
     (cursor moviéndose). El JS lo decae gradualmente cuando el cursor
     lleva 3s sin movimiento, y lo sube de vuelta al primer movimiento. */
  --tp-fade: 0;
}

/* ::before — capa principal del texto (blanca, con blur reactivo).
   Absolutada al top-left, EXACTAMENTE el mismo origen que ::after.
   Ambos pseudos heredan las mismas font properties → renderizan en
   posiciones idénticas → alineación pixel-perfect garantizada. */
.text-prism::before {
  content: attr(data-text);
  position: absolute;
  /* V22: top/left coinciden con el padding del .text-prism (0.06em / 0.12em)
     para que el pseudo renderice el texto en la misma posición que el texto
     literal del elemento (que está en el content-box, no en el padding-box). */
  top: 0.06em;
  left: 0.12em;
  pointer-events: none;
  user-select: none;
  letter-spacing: inherit;
  font-family: inherit;
  font-weight: inherit;
  font-size: inherit;
  line-height: inherit;
  text-transform: inherit;
  color: #fff;
  filter: blur(var(--tp-blur, 0px));
  transition: filter 0.15s ease-out;
}

/* ::after — único pseudo. Contorno (text-stroke 2px) que recibe color
   solo en una "burbuja" centrada en la posición del cursor:
     - 0 → --tp-near       blanco (núcleo brillante)
     - --tp-near → --tp-mid color (anillo cromático con conic centrado en cursor)
     - > --tp-mid           invisible (mask radial corta a transparente)
   Sin animación — el efecto es 100 % reactivo al cursor. */
.text-prism::after {
  content: attr(data-text);
  position: absolute;
  /* V22: top/left coinciden con el padding del .text-prism para que el
     pseudo renderice el texto donde está el texto literal (content-box),
     no en la esquina del padding-box. Sin esto, el ::after queda offset
     respecto al ::before y al texto literal, creando duplicados visibles
     (efecto "y hanging right" en Createdby del splash). */
  top: 0.06em;
  left: 0.12em;
  pointer-events: none;
  user-select: none;
  white-space: pre;  /* preserva espacios de data-text por si lleva " " */

  /* Tipografía heredada — independiente de la fuente del texto principal */
  letter-spacing: inherit;
  font-family: inherit;
  font-weight: inherit;
  font-size: inherit;
  line-height: inherit;
  text-transform: inherit;

  /* Solo contorno (1 px hacia cada lado del borde de cada letra) */
  color: transparent;
  -webkit-text-stroke: 2px transparent;

  /* Sutil blur del render final — suaviza el text-stroke */
  filter: blur(0.4px);

  /* Opacidad reactiva al idle: 0 cuando el cursor lleva 3s sin movimiento,
     1 cuando está activo. JS lo controla via --tp-fade. */
  opacity: var(--tp-fade, 1);

  /* Background dual centrado en el cursor.
     Stops graduales (no bordes duros) para difuminar las transiciones:
     - núcleo blanco sólido en el centro, fade gradual hacia el anillo cromático
     - anillo cromático debajo (siempre presente, recortado por la mask) */
  background:
    /* Núcleo blanco con fade gradual (3 stops smooth) */
    radial-gradient(
      circle at calc(var(--tp-x) * 100%) calc(var(--tp-y) * 100%),
      rgba(255, 255, 255, 1)    0,
      rgba(255, 255, 255, 1)    calc(var(--tp-near) * 0.55),
      rgba(255, 255, 255, 0.45) var(--tp-near),
      rgba(255, 255, 255, 0)    calc(var(--tp-near) * 1.35)
    ),
    /* Anillo cromático con conic centrado en cursor — los colores rotan
       según el ángulo respecto al cursor, no respecto al centro del texto */
    conic-gradient(
      from 0deg at calc(var(--tp-x) * 100%) calc(var(--tp-y) * 100%),
      hsl(0,   100%, 65%),
      hsl(30,  100%, 60%),
      hsl(60,  100%, 60%),
      hsl(90,  100%, 55%),
      hsl(120, 100%, 55%),
      hsl(150, 100%, 60%),
      hsl(180, 100%, 60%),
      hsl(210, 100%, 65%),
      hsl(240, 100%, 65%),
      hsl(270, 100%, 65%),
      hsl(300, 100%, 60%),
      hsl(330, 100%, 60%),
      hsl(360, 100%, 65%)
    );
  -webkit-background-clip: text;
          background-clip: text;

  /* Mask radial con fade gradual al borde exterior (4 stops):
     - 0 → 40% del mid: opacidad 1 (visible total)
     - 40 → 70% del mid: opacidad 0.7
     - 70 → 90% del mid: opacidad 0.25
     - 90% → mid: fade a transparent */
  -webkit-mask-image: radial-gradient(
    circle at calc(var(--tp-x) * 100%) calc(var(--tp-y) * 100%),
    rgba(0, 0, 0, 1)    0,
    rgba(0, 0, 0, 1)    calc(var(--tp-mid) * 0.4),
    rgba(0, 0, 0, 0.7)  calc(var(--tp-mid) * 0.7),
    rgba(0, 0, 0, 0.25) calc(var(--tp-mid) * 0.9),
    rgba(0, 0, 0, 0)    var(--tp-mid)
  );
          mask-image: radial-gradient(
    circle at calc(var(--tp-x) * 100%) calc(var(--tp-y) * 100%),
    rgba(0, 0, 0, 1)    0,
    rgba(0, 0, 0, 1)    calc(var(--tp-mid) * 0.4),
    rgba(0, 0, 0, 0.7)  calc(var(--tp-mid) * 0.7),
    rgba(0, 0, 0, 0.25) calc(var(--tp-mid) * 0.9),
    rgba(0, 0, 0, 0)    var(--tp-mid)
  );

  z-index: -1;
}

/* ─── Variante .text-prism--red ───────────────────────────────────────
   Misma mecánica que .text-prism (cursor-following, idle fade, blur),
   pero la paleta del CONTORNO cromático queda limitada a rojos y
   naranja-rojizo. Se usa en "MOTION" del brand-row para diferenciarlo
   cromáticamente de "Createdby" manteniendo el lenguaje del prisma.

   La capa principal (::before) sigue siendo BLANCA igual que .text-prism
   default — solo cambia el ::after (contorno reactivo al cursor) para
   limitar los colores del conic-gradient a rojos. El núcleo radial
   central también queda blanco para que la "burbuja" de cursor sea
   consistente con la versión Createdby. */
.text-prism--red::after {
  background:
    /* Núcleo blanco en cursor (idéntico al .text-prism default) */
    radial-gradient(
      circle at calc(var(--tp-x) * 100%) calc(var(--tp-y) * 100%),
      rgba(255, 255, 255, 1)    0,
      rgba(255, 255, 255, 1)    calc(var(--tp-near) * 0.55),
      rgba(255, 255, 255, 0.45) var(--tp-near),
      rgba(255, 255, 255, 0)    calc(var(--tp-near) * 1.35)
    ),
    /* Conic con paleta limitada: rojo puro + naranja-rojizo + variantes
       de saturación/brillo. Sin amarillos, verdes, azules ni morados. */
    conic-gradient(
      from 0deg at calc(var(--tp-x) * 100%) calc(var(--tp-y) * 100%),
      hsl(0,   100%, 60%),  /* rojo puro          */
      hsl(12,  100%, 55%),  /* rojo-naranja       */
      hsl(22,  100%, 52%),  /* naranja rojizo     */
      hsl(15,  100%, 58%),
      hsl(5,   100%, 62%),
      hsl(355, 95%,  60%),
      hsl(0,   100%, 65%)
    );
  -webkit-background-clip: text;
          background-clip: text;
}


/* ═══════════════════════════════════════════════════════════════════
   7 · ESTADOS DE PÁGINA
   ═══════════════════════════════════════════════════════════════════ */

/* ─── Estado A: pantalla intro (index.php) ─── */
.splash {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 3vw, 28px);
  padding: 24px;
  background: var(--bg);
  text-align: center;
}
.splash[hidden] { display: none; }

.splash-tagline {
  font-family: var(--font-accent);
  font-size: clamp(13px, 1.8vw, 15.5px);
  font-weight: 50;
  letter-spacing: 0.5px;
  color: var(--muted-strong);
  max-width: 40ch;
  line-height: 1.5;
}
/* Contenedor de las dos palabras del splash brand: Createdby (Playfair)
   + MOTION (Bebas Neue). Side-by-side en pantallas anchas, se apila a
   columna cuando no caben juntos (flex-wrap: wrap).

   `width: 100%` es CRÍTICO: el padre (.splash) tiene align-items: center,
   así que sin ancho explícito el row tomaría max-content (suma de los dos
   hijos) y nunca dispararía el wrap. Con 100 % el row respeta el ancho
   del padre y los hijos wrappean cuando no caben. */
.splash-brand-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: clamp(8px, 2vw, 40px);
  width: 100%;
}

/* En pantallas estrechas Createdby + MOTION no caben juntos: forzar
   stacking vertical. Más confiable que depender solo de flex-wrap, que
   con elementos inline-block (text-prism) a veces no dispara como
   esperamos. Breakpoint a 720 px porque por encima de eso ambos caben
   cómodos en una línea con los clamp del CSS. */
@media (max-width: 720px) {
  .splash-brand-row {
    flex-direction: column;
    align-items: center;          /* override del baseline (que en column
                                     equivale a flex-start = izquierda) */
    gap: 4px;
  }
}

.splash-brand {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.025em;
  /* Min bajado para que "Createdby" entre con margen en mobile estrecho
     (≤ 375 px) cuando MOTION baja a la siguiente línea. Mantiene 168 px
     en desktop ancho. */
  font-size: clamp(38px, 11vw, 168px);
  line-height: 0.95;
}

/* MOTION del splash — espejo del brand-row-sub de motion.php pero en
   tamaño splash (más grande en desktop). Bebas Neue + prism rojo. */
.splash-brand-sub {
  font-family: var(--font-accent);
  /* +10 % vs Createdby en desktop para balance visual: Bebas Neue es
     alta-condensada y a mismo px parece más chica que Playfair 700. */
  font-size: clamp(44px, 12.5vw, 184px);
  line-height: 0.95;
  letter-spacing: 0.02em;
}
.splash-sub {
  /* JS aplica letter-spacing dinámico para que ocupe el mismo ancho
     horizontal que .splash-brand (función fitSubToBrandWidth). */
  font-family: var(--font-accent);
  font-size: clamp(10px, 1.2vw, 12px);
  letter-spacing: 0.3em; /* fallback antes de que el JS lo ajuste */
  text-transform: uppercase;
  color: var(--muted-strong);
  margin-top: 4px;
  white-space: nowrap;
  will-change: letter-spacing;
}
/* CTA "Postular" del splash — sin view-transition-name customizado:
   la transición usa el crossfade default del browser para evitar conflictos
   con la animación de intro phase de motion.php (que sube Createdby+MOTION
   juntos del centro al header como un bloque). */

/* ─── Estado Motion: page-shell (motion.php) ─── */
.page-shell { opacity: 1; }

/* Wrapper sticky del header. Queda pegado al top del viewport mientras
   el usuario hace scroll dentro de .page-shell. Contiene el header
   (opaco) y la franja de blur progresivo que va debajo.
   V21: max-width 100vw + overflow-x clip como defensa contra cualquier
   overflow horizontal del brand-row (ej. cuando combinaciones de fuentes
   y vw hacen que Createdby+MOTION o sus pseudos `.text-prism` excedan
   el viewport). El body ya tiene overflow-x hidden, pero un wrapper
   sticky puede crear contexto separado. */
.brand-sticky {
  position: sticky;
  top: 0;
  z-index: 50;
  max-width: 100vw;
  overflow-x: clip;
}

.brand-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;          /* Createdby + MOTION centrados en el header */
  gap: clamp(10px, 1.5vw, 18px);
  /* Padding-bottom mínimo (6 px). Con un padding grande, entre el texto
     "Createdby MOTION" y la franja de blur quedaba un hueco oscuro vacío.
     Ahora el blur empieza casi pegado al texto del header. */
  padding: clamp(28px, 5vw, 50px) clamp(22px, 4vw, 40px) 6px;
  max-width: 980px;
  margin: 0 auto;
  text-align: center;               /* fallback para text-align center si llegan
                                       a wrappear en mobile */
  /* Background opaco: cuando el header está sticky, el contenido que sube
     al scroll queda OCULTO bajo el header (no semi-transparente). El efecto
     de difuminado pasa en el .brand-blur-fade de abajo, no a través
     del header. */
  
}

/* Franja de 40 px debajo del header con blur progresivo en 4 slices.
   Cada slice tiene su propio backdrop-filter: el más cercano al header
   (slice 1, top: 0) tiene blur enorme; el más alejado (slice 4, top: 30)
   tiene blur leve. Resultado: el contenido que pasa por debajo del header
   al scroll se difumina fuerte cerca del borde y se aclara progresivamente
   hasta verse nítido a partir de los 40 px. */
.brand-blur-fade {
  position: absolute;
  top: 0;            /* justo debajo del .brand-row */
  left: 0;
  right: 0;
  height: 45px;
  pointer-events: none; /* nunca bloquea clicks en el contenido de abajo */
}
.brand-blur-fade .bbf-layer {
  position: absolute;
  left: 0;
  right: 0;
  height: 45px;
  /* will-change le dice al browser que componga estos elementos en su
     propio layer GPU para que el backdrop-filter no haga repaint del
     resto de la página al hacer scroll. */
  will-change: backdrop-filter;
}
.bbf-layer-1 {
  top:  0px;
  -webkit-backdrop-filter: blur(2.5px);
          backdrop-filter: blur(4px);
}
.bbf-layer-2 {
  top: 10px;
  -webkit-backdrop-filter: blur(2px);
          backdrop-filter: blur(3px);
}
.bbf-layer-3 {
  top: 20px;
  -webkit-backdrop-filter: blur(1px);
          backdrop-filter: blur(2px);
}
.bbf-layer-4 {
  top: 30px;
  -webkit-backdrop-filter: blur(0.8px);
          backdrop-filter: blur(1px);
}
.brand-row-main {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.025em;
  font-size: clamp(34px, 5.5vw, 56px);
  line-height: 1;
  z-index: 100
}
.brand-row-sub {
  /* Bebas Neue (display all-caps condensada). Da contraste tipográfico
     contra "Createdby" en Playfair y refuerza MOTION como sub-marca
     operativa. Bebas Neue solo trae peso regular — no se especifica
     font-weight para que el CSS sea honesto. */
  font-family: var(--font-accent);
  font-size: clamp(38px, 6.2vw, 64px);  /* +12 % vs Createdby: Bebas Neue
                                           es alta-condensada y a mismo px
                                           parece más chica que Playfair 700 */
  line-height: 1;
  letter-spacing: 0.03em;               /* leve tracking positivo —
                                           Bebas Neue muy pegada se lee mal */
z-index: 100
}


/* ═══════════════════════════════════════════════════════════════════
   8 · SECCIONES (motion.php)
   ═══════════════════════════════════════════════════════════════════ */

/* ─── 8.1 Manifiesto ─── */
.manifiesto {
  /* Padding-top reducido a 18 px (era var(--space-2xl) = 90 px). Junto con
     .wrap padding-top: 0, esto hace que el primer texto del manifiesto
     entre dentro de la franja de blur de 40 px del header sticky.
     Padding-bottom mantiene el espaciado normal entre secciones. */
  padding: 18px 0 var(--space-2xl);
  max-width: 660px;
}
.manifiesto p {
  font-size: clamp(16px, 2.2vw, 18.5px);
  line-height: 1.75;
  color: var(--text);
  margin-bottom: var(--space-md);
  /* V21: defensa contra cualquier token o combinación que pudiera generar
     una línea más ancha que el contenedor. break-word rompe palabras solo
     cuando es estrictamente necesario; hyphens auto añade guiones donde el
     idioma lo permite. */
  overflow-wrap: break-word;
  word-wrap: break-word;
  hyphens: auto;
}
.manifiesto p + p { margin-top: 0; }

/* ─── 8.2 Ecosistema (cards + tags) ─── */
.ecosistema { padding: var(--space-2xl) 0; }

.ecosistema-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
  margin-bottom: var(--space-lg);
}

/* .ecosistema-card es un <button> — la superficie glass + posicionamiento
   ya vienen de la sección 5 (patrón canónico). Aquí solo lo específico. */
.ecosistema-card {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--text);
  border: none; /* el border-top/bottom viene del patrón canónico */
  padding: 22px 22px 24px;
  cursor: pointer;
  transition: transform var(--dur-mid) var(--ease),
              box-shadow var(--dur-mid) var(--ease);
}
.ecosistema-card > * { position: relative; z-index: 2; }
.ecosistema-card:hover { transform: translateY(-2px); }
.ecosistema-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.ecosistema-card h3 {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--text);
  letter-spacing: -0.2px;
}
.ecosistema-card p {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--muted-strong);
}

/* Tags inline (sub-marcas pequeñas, sin glass) */
.ecosistema-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 18px 0 0;
}
.tags-label {
  font-family: var(--font-accent);
  font-size: 12px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 6px;
}
.tag {
  font-family: var(--font-accent);
  font-size: 11.5px;
  letter-spacing: 2px;
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  color: var(--muted-strong);
  transition: color var(--dur-fast), border-color var(--dur-fast);
}
.tag:hover { color: var(--text); border-color: var(--accent-dim); }

/* ─── 8.3 Convocatoria (oferta tabular) ─── */
.convocatoria { padding: var(--space-2xl) 0; max-width: 720px; }
.oferta {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.oferta-row {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 18px;
  background: var(--surface);
  padding: 18px 22px;
  align-items: baseline;
}
.oferta-lbl {
  font-family: var(--font-accent);
  font-size: 12.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--accent);
}
.oferta-val {
  font-size: 15px;
  line-height: 1.65;
  color: var(--text);
}
@media (max-width: 600px) {
  .oferta-row {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 16px 18px;
  }
}

/* ─── 8.4 La serie (Createdby Original) ─── */
.serie {
  padding: var(--space-2xl) 0;
  max-width: 760px;
  scroll-margin-top: 24px;
}
.serie-kicker {
  font-size: clamp(17px, 2.4vw, 20px);
  line-height: 1.55;
  color: var(--text);
  margin-bottom: var(--space-lg);
  max-width: 640px;
}

/* "Lo que NO es" — lista contundente */
.serie-no-es {
  margin: var(--space-lg) 0;
  padding: 18px 22px 16px;
  border-left: 3px solid var(--error);
  background: rgba(248, 113, 113, 0.04);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.serie-no-es-lbl {
  display: inline-block;
  font-family: var(--font-accent);
  font-size: 11.5px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--error);
  margin-bottom: 10px;
}
.serie-no-es ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.serie-no-es li {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted-strong);
  position: relative;
  padding-left: 20px;
}
.serie-no-es li::before {
  content: "✕";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--error);
  opacity: 0.55;
  font-size: 12px;
}

/* Las 4 referencias (grid 2×2 sin glass — son referencias externas) */
.serie-referencias-bloque { margin: var(--space-lg) 0; }
.serie-referencias-intro {
  font-size: clamp(15.5px, 2vw, 17px);
  color: var(--muted-strong);
  margin-bottom: var(--space-md);
}
.serie-referencias {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}
@media (max-width: 640px) {
  .serie-referencias { grid-template-columns: 1fr; }
}
.ref-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 18px 20px 20px;
  border-top: 2px solid var(--accent);
}
.ref-card-nombre {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.2px;
  color: var(--text);
  margin-bottom: 6px;
}
.ref-card-desc {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--muted-strong);
}

/* Bloques narrativos (formato/tono/personajes/casting) */
.serie-bloques {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  margin-top: var(--space-lg);
}
.serie-bloque h3 {
  font-family: var(--font-display);
  font-size: clamp(20px, 3vw, 25px);
  font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--text);
  margin-bottom: 12px;
}
.serie-bloque p {
  font-size: clamp(15.5px, 2vw, 17.5px);
  line-height: 1.75;
  color: var(--muted-strong);
}

/* ─── 8.5 Brief del video de 60 segundos ─── */
.video-brief {
  margin-top: var(--space-xl);
  padding: clamp(24px, 4vw, 36px);
  background: var(--bg);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  position: relative;
  scroll-margin-top: 24px;
}
.video-brief::before {
  /* "ribbon" diagonal sutil estilo papel pegado */
  content: "";
  position: absolute;
  top: 0;
  right: 28px;
  width: 2px;
  height: 18px;
  background: var(--accent);
  opacity: 0.5;
}
.video-brief-head { margin-bottom: var(--space-md); }
.video-brief-tag {
  display: inline-block;
  font-family: Menlo, Consolas, 'Courier New', monospace;
  font-size: 11.5px;
  letter-spacing: 1px;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 3px 8px;
  border-radius: 3px;
  margin-bottom: 14px;
}
.video-brief-kicker {
  font-size: 13.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
  font-family: var(--font-accent);
  margin-bottom: 4px;
}
.video-brief-titulo {
  font-family: var(--font-display);
  font-size: clamp(24px, 4vw, 34px);
  font-weight: 700;
  letter-spacing: -0.5px;
  line-height: 1.05;
  color: var(--text);
}
.video-brief-lead,
.video-brief-tecnico {
  font-size: clamp(15.5px, 2vw, 17px);
  line-height: 1.7;
  color: var(--text);
  margin-bottom: var(--space-md);
}
.video-brief-tecnico { color: var(--muted-strong); }
.video-brief-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin: var(--space-md) 0;
}
@media (max-width: 640px) {
  .video-brief-cols { grid-template-columns: 1fr; gap: 14px; }
}
.video-brief-col {
  background: var(--surface);
  border-radius: var(--radius-sm);
  padding: 16px 18px 18px;
  border-top: 2px solid var(--border);
}
.video-brief-col--si { border-top-color: var(--success); }
.video-brief-col--no { border-top-color: var(--error); }
.video-brief-col h4 {
  font-family: var(--font-accent);
  font-size: 12.5px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  margin-bottom: 12px;
}
.video-brief-col--si h4 { color: var(--success); }
.video-brief-col--no h4 { color: var(--error); }
.video-brief-col ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.video-brief-col li {
  position: relative;
  padding-left: 18px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted-strong);
}
.video-brief-col--si li::before {
  content: "+";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--success);
  font-weight: 700;
  opacity: 0.7;
}
.video-brief-col--no li::before {
  content: "−";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--error);
  font-weight: 700;
  opacity: 0.7;
}
.video-brief-cierre {
  margin-top: var(--space-md);
  padding-top: var(--space-md);
  border-top: 1px solid var(--border);
  font-size: clamp(15px, 2vw, 17px);
  line-height: 1.65;
  color: var(--text);
  font-style: italic;
}

/* Hint con link interno (en el campo 13 del formulario) */
.hint-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent-dim);
  transition: border-color var(--dur-fast), color var(--dur-fast);
}
.hint-link:hover {
  color: var(--text);
  border-bottom-color: var(--accent);
}

/* ─── 8.6 Lo que NO ofrezco (cards rojas) ─── */
.no-ofrezco {
  padding: var(--space-2xl) 0;
  max-width: 760px;
}
.no-ofrezco-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
.no-ofrezco-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 2px solid var(--error);
  border-radius: var(--radius-md);
  padding: 18px 20px 22px;
  transition: transform var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.no-ofrezco-card:hover {
  transform: translateY(-2px);
  border-color: rgba(248, 113, 113, 0.25);
  border-top-color: var(--error);
}
.no-ofrezco-card h3 {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.2px;
  color: var(--text);
  margin-bottom: 8px;
}
.no-ofrezco-card p {
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted-strong);
}

/* ─── 8.7 Formulario ─── */
.form-section {
  padding: var(--space-2xl) 0 var(--space-lg);
  scroll-margin-top: 24px;
}
.form-welcome,
.form-welcome-pasiva {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 24px 26px;
  margin-bottom: var(--space-lg);
  border-left: 3px solid var(--accent);
}
.form-welcome p,
.form-welcome-pasiva {
  font-size: 15.5px;
  line-height: 1.75;
  color: var(--muted-strong);
  margin-bottom: 14px;
}
.form-welcome p:last-child,
.form-welcome-pasiva { margin-bottom: 0; }
.form-welcome p:last-child { color: var(--text); font-style: italic; }

/* .form-card hereda glass del patrón canónico (sección 5) */
.form-card {
  padding: clamp(22px, 4vw, 36px);
  position: relative;
}

.form-block {
  border: none;
  padding: 0;
  margin-bottom: var(--space-lg);
}
.form-block legend {
  font-family: var(--font-accent);
  font-size: 12.5px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-md);
  padding: 0;
}

.f { margin-bottom: var(--space-md); }
.f label,
.f > label {
  display: block;
  font-size: 14.5px;
  font-weight: 500;
  margin-bottom: 7px;
  color: var(--text);
}
.f .hint {
  display: block;
  font-size: 12.5px;
  color: var(--muted);
  margin-bottom: 9px;
  line-height: 1.55;
}
.f input[type="text"],
.f input[type="email"],
.f input[type="tel"],
.f input[type="url"],
.f input[type="number"],
.f textarea {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 15px;
  color: var(--text);
  font: 15px var(--font-body);
  outline: none;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast);
  -webkit-appearance: none;
          appearance: none;
}
.f input:focus,
.f textarea:focus {
  border-color: var(--accent);
  background: var(--surface);
}
.f input:user-valid,
.f textarea:user-valid {
  border-color: rgba(74, 222, 128, 0.3);
}
.f input.invalid,
.f textarea.invalid {
  border-color: var(--error);
  background: rgba(248, 113, 113, 0.04);
}
.f textarea {
  resize: vertical;
  min-height: 92px;
  line-height: 1.55;
}
.f input::placeholder,
.f textarea::placeholder { color: #4a4a4a; }

.f-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
}
@media (max-width: 540px) {
  .f-grid { grid-template-columns: 1fr; gap: 0; }
}

.field-error {
  display: none;
  margin-top: 6px;
  font-size: 12.5px;
  color: var(--error);
}
.f.has-error .field-error { display: block; }

.char-count {
  display: block;
  text-align: right;
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 5px;
  font-variant-numeric: tabular-nums;
}
.char-count.near { color: var(--accent); }
.char-count.over { color: var(--error); }

.f-otro {
  margin-top: 10px;
  padding-left: 12px;
  border-left: 2px solid var(--accent-dim);
}
.f-otro input[type="text"] {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  color: var(--text);
  font: 14px var(--font-body);
  width: 100%;
  outline: none;
  transition: border-color var(--dur-fast);
}
.f-otro input:focus { border-color: var(--accent); }

/* Submit button — V19: glass-style con prism halo detrás del texto.
   Antes era blanco sólido + texto negro; ahora es transparente/glass con
   texto blanco para que el halo cromatico (.btn-submit::before) se vea
   detrás de las letras. La superficie glass + posicionamiento (position
   relative + overflow hidden + isolation isolate) viene de las capas 1-2
   compartidas con .cta-prism, .ecosistema-card, .site-footer. */
.btn-submit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 16px;
  margin-top: var(--space-md);
  color: #fff;
  font-family: var(--font-accent);
  font-size: 17px;
  letter-spacing: 3px;
  text-transform: uppercase;
  border: none;
  cursor: pointer;
  transition: opacity var(--dur-fast), transform .1s;
  appearance: none;
  -webkit-appearance: none;
}
.btn-submit:active { transform: scale(.99); }
.btn-submit:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-submit .btn-spinner {
  display: none;
  width: 18px;
  height: 18px;
  border: 2px solid #fff;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}
.btn-submit.loading .btn-spinner { display: block; }
/* V24: texto del botón se mantiene visible durante loading (con la palabra
   "ENVIANDO…" puesta por JS), junto al spinner. Antes se ocultaba y solo
   quedaba el spinner sin contexto verbal. La opacidad ligeramente baja
   refuerza el estado "en proceso" sin esconder la información. */
.btn-submit.loading .btn-text {
  display: inline-block;
  opacity: 0.85;
  letter-spacing: 4px; /* leve aumento del tracking, refuerza el feel "en proceso" */
}
@keyframes spin { to { transform: rotate(360deg); } }

.form-msg {
  display: none;
  text-align: center;
  padding: 14px 18px;
  border-radius: var(--radius-sm);
  margin-top: 16px;
  font-size: 14px;
  line-height: 1.5;
}
.form-msg.show.error {
  display: block;
  background: rgba(248, 113, 113, 0.08);
  border: 1px solid rgba(248, 113, 113, 0.25);
  color: var(--error);
}
.form-msg.show.ok {
  display: block;
  background: rgba(74, 222, 128, 0.08);
  border: 1px solid rgba(74, 222, 128, 0.25);
  color: var(--success);
}

/* V27 — Banner de "postulación pendiente". Se inyecta vía JS al inicio
   de .form-section cuando hay un backup en localStorage del intento
   anterior. Pemite al usuario reintentar sin re-llenar el form, o
   descartar la sesión guardada. */
.cb-pending-banner {
  background: rgba(255, 200, 0, 0.08);
  border: 1px solid rgba(255, 200, 0, 0.4);
  border-left: 3px solid #fc0;
  border-radius: var(--radius-md);
  padding: 18px 22px;
  margin-bottom: var(--space-md);
  color: var(--text);
}
.cb-pending-banner p {
  font-size: 14.5px;
  line-height: 1.6;
  margin: 0 0 12px;
}
.cb-pending-banner strong { color: #fc0; }
.cb-pending-actions { display: flex; gap: 10px; }
.cb-pending-retry,
.cb-pending-discard {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: var(--text);
  padding: 8px 18px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-family: var(--font-accent);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--dur-fast);
}
.cb-pending-retry { background: #fc0; color: #000; border-color: #fc0; }
.cb-pending-retry:hover { background: #ffd633; }
.cb-pending-discard:hover { background: rgba(255, 255, 255, 0.06); }

.form-foot {
  text-align: center;
  font-size: 12.5px;
  color: var(--muted);
  margin-top: 22px;
  line-height: 1.6;
}

/* Pantalla de cierre del formulario (.form-thanks hereda glass del
   patrón canónico — sección 5).
   V24: la pantalla ocupa min-height 60vh y centra verticalmente su
   contenido para que se sienta como "pantalla nueva" tras el envío
   exitoso, no como un mensaje inline en la sección del form. */
.form-thanks {
  text-align: center;
  padding: 70px 20px;
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* fade-in suave cuando aparece (JS le quita el atributo hidden) */
  animation: thanks-fade-in 0.6s ease-out;
}
/* CRÍTICO: el HTML attribute `hidden` por default aplica `display: none`,
   pero el `display: flex` de arriba lo sobreescribe (CSS gana al UA-default).
   Sin esta regla, el .form-thanks aparece SIEMPRE visible incluso antes del
   submit. Esta regla restaura el comportamiento del attribute hidden. */
.form-thanks[hidden] { display: none; }
@keyframes thanks-fade-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.thanks-check {
  width: 72px;
  height: 72px;
  border: 2px solid var(--success);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 26px;
  font-size: 32px;
  color: var(--success);
  font-weight: 700;
  /* V24: pulso sutil del check al aparecer — celebra el éxito sin
     ser molesto. Una sola iteración. */
  animation: thanks-check-pop 0.5s 0.2s ease-out backwards;
}
@keyframes thanks-check-pop {
  from { transform: scale(0.6); opacity: 0; }
  60%  { transform: scale(1.1); }
  to   { transform: scale(1); opacity: 1; }
}
.form-thanks h2 {
  font-size: clamp(32px, 5vw, 44px);
  margin-bottom: 18px;
}
.form-thanks p {
  max-width: 520px;
  margin: 0 auto 14px;
  color: var(--muted-strong);
  font-size: 15.5px;
  line-height: 1.7;
}
.form-thanks p:last-child { color: var(--text); font-style: italic; }


/* ═══════════════════════════════════════════════════════════════════
   9 · FOOTER + CTA FLOTANTE
   ═══════════════════════════════════════════════════════════════════ */

/* .site-footer hereda glass + posicionamiento del patrón canónico */
.site-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
  padding: 32px 28px;
  margin-top: var(--space-2xl);
}
.site-footer > * { position: relative; z-index: 2; }

.footer-section h4 {
  font-family: var(--font-accent);
  font-size: 12px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 10px;
}
.footer-section p {
  font-size: 14px;
  color: var(--muted-strong);
  margin-bottom: 6px;
}
.footer-section a {
  color: var(--muted-strong);
  transition: color var(--dur-fast);
}
.footer-section a:hover { color: var(--text); }
.footer-tagline {
  font-style: italic;
  color: var(--muted) !important;
  font-size: 12.5px !important;
  margin-top: 8px;
}

@media (max-width: 700px) {
  .site-footer {
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 28px 20px;
  }
}

/* CTA flotante mobile-only — visible cuando scrollY pasa el hero.
   V19: glass-style con prism halo detrás del texto, mismo tratamiento
   que .btn-submit y .cta-prism. Posición fixed se preserva; las
   propiedades position/overflow/isolation las hereda de las capas 1-2.
   IMPORTANTE: position fixed sobreescribe el position relative de capa 2
   (es lo correcto — necesita estar fijo a viewport). El motor JS de
   mouse-following sigue funcionando con position fixed. */
.cta-float {
  position: fixed;
  bottom: 18px;
  right: 18px;
  z-index: 50;
  padding: 12px 22px;
  color: #fff;
  font-family: var(--font-accent);
  font-size: 14px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: var(--radius-pill);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transform: translateY(20px);
  pointer-events: none;
  transition: opacity var(--dur-mid) var(--ease), transform var(--dur-mid) var(--ease);
}
.cta-float.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
@media (min-width: 769px) {
  .cta-float { display: none !important; }
}


/* ═══════════════════════════════════════════════════════════════════
  10 · REDUCED MOTION (override global, al final para máxima especificidad)
   ═══════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
