/* ============================================================
   Kenzen Page System — molde de páginas
   ============================================================

   Construido sobre las MISMAS variables de marca que Kenzen Landing System y
   Kenzen Blog System (`--kls-ruby`, `--kls-bg-dark`, `--kls-text`…), para que
   los tres vayan a juego y sigan el mismo color de acento.

   Nunca escribir un color literal aquí: rompería la multi-marca en silencio
   —se vería bien en Kenzen y mal en las demás—. Es el fallo que hubo que
   sanear en julio de 2026 en los otros dos plugins.

   El `:root` define los valores por defecto, así que este fichero funciona
   solo aunque los otros plugins no estén.
   ============================================================ */

:root {
  --kls-ruby:            #c41230;
  --kls-ruby-rgb:        196,18,48;
  --kls-ruby-light:      #e8193a;
  --kls-ruby-dark:       #8b0010;
  --kls-dark-rgb:        11,18,32;
  --kls-bg-dark:         #0B1220;
  --kls-bg-page:         #ffffff;
  --kls-bg-alt:          #F7F7F7;
  --kls-text:            #0B1220;
  --kls-text-muted:      #3D4A60;
  --kls-text-subtle:     #8A8578;
  --kls-font-sans:       'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  --kls-font-display:    'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;

  /* Los usan los campos de formulario del hueco (más abajo, con `!important`).
     Faltaban aquí: los define `kenzen-landing.css`, que en una página KPS no
     se encola, así que `var(--kls-radius)` quedaba sin valor y el navegador
     **descartaba la declaración entera** — los campos salían con las esquinas
     rectas. Mismos valores que en KLS, que es de donde vienen. */
  --kls-radius:          8px;
  --kls-radius-lg:       12px;

  --kps-container:       1200px;
  --kps-radius:          12px;
  --kps-section-py:      clamp(3rem, 7vw, 5.5rem);
}

/* ── Shell ──────────────────────────────────────────────────── */
.kps-shell {
  font-family: var(--kls-font-sans);
  color: var(--kls-text);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

.kps-container {
  max-width: var(--kps-container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 5vw, 3rem);
}

.kps-highlight {
  color: var(--kls-ruby);
}

/* ── Hero ───────────────────────────────────────────────────── */
/* ── El relleno del hero, y lo que le descuenta la barra ──────
   Los dos rellenos viven en variables para que la resta de abajo se escriba
   **una sola vez**: la variante con foto solo cambia los valores.

   `--kps-banner-compensa` es la mitad de la altura de la barra superior, y la
   publica un script en línea justo después de pintarla (ver `banner.php`).
   Con la barra puesta, el hero se recorta esa mitad por arriba y otra tanto por
   abajo, así que el conjunto sigue ocupando lo mismo en pantalla que antes de
   añadirla. Sin barra vale `0px` y no cambia nada.

   El `max()` es el suelo: con una barra muy alta —dos líneas de texto en móvil—
   la resta se comería el relleno entero y el título quedaría pegado al borde. */
.kps-hero {
  --kps-hero-pt: clamp(3.5rem, 9vw, 6.5rem);
  --kps-hero-pb: clamp(2rem, 5vw, 3.5rem);
  padding-block:
    max(1.5rem, calc(var(--kps-hero-pt) - var(--kps-banner-compensa, 0px)))
    max(1.5rem, calc(var(--kps-hero-pb) - var(--kps-banner-compensa, 0px)));
  background: linear-gradient(
    to bottom,
    rgba(var(--kls-ruby-rgb), 0.10) 0%,
    rgba(var(--kls-ruby-rgb), 0.04) 45%,
    var(--kls-bg-page) 100%
  );
}

/* ── Hero sobre color de marca ───────────────────────────────
   Variante 'marca': fondo sólido y todo el contenido en blanco. Hay que
   invertir también etiqueta y botones — si no, la etiqueta queda blanca sobre
   blanco y el botón primario, rubí sobre rubí: invisibles los dos.
   El resaltado del título se queda en blanco puro y el resto baja a 88 %, que
   es lo que mantiene el contraste entre ambos cuando ya no puede haber color. */
.kps-hero--marca {
  background: var(--kls-ruby);
}

/* ── Hero sobre un color cualquiera ──────────────────────────
   Igual que la de marca, con el color que se elija en el editor. El valor
   llega en `--kps-hero-bg` por atributo `style`, no como un `background`
   escrito en línea: así el fondo lo sigue decidiendo esta hoja y no el HTML.
   La reserva a `--kls-ruby` no debería llegar a usarse —la plantilla convierte
   en 'marca' un hero de color sin color—, pero deja la regla completa por sí
   sola. */
.kps-hero--color {
  background: var(--kps-hero-bg, var(--kls-ruby));
}

/* ── Hero con imagen a sangre completa ───────────────────────
   La foto va en un <img> y no en `background-image` a propósito: así se
   lleva el `srcset` de WordPress —un móvil no se descarga la de 2560 px— y
   admite `fetchpriority`, que es lo que la adelanta en la cola de descarga.
   Hereda todas las inversiones de la variante de marca (ver el selector
   agrupado de abajo): sobre foto oscura el problema de contraste es el
   mismo. */
.kps-hero--imagen {
  position: relative;
  isolation: isolate;
  background: var(--kls-bg-dark);
}

/* El reparto del hero claro es asimétrico a propósito —mucho arriba, poco
   abajo— porque su degradado se funde con la página y el corte no se ve. Con
   foto sí se ve: hay un canto duro arriba y otro abajo, y ese mismo reparto
   deja el contenido pegado al de arriba. Aquí va espacio generoso y casi
   simétrico, con algo más abajo, que es donde el ojo pide aire cuando el
   bloque de texto se lee alineado al centro.
   Solo toca la variante con foto: los heros claro y de marca no se mueven. */
.kps-hero--imagen {
  --kps-hero-pt: clamp(5rem, 11vw, 8.5rem);
  --kps-hero-pb: clamp(5.5rem, 12vw, 9rem);
}

.kps-hero--imagen .kps-hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center var(--kps-foco, 50%);
  z-index: -2;
}

/* El velo garantiza el contraste con cualquier foto, no solo con una oscura.
   Va más cargado abajo, que es donde caen los botones.

   Tres intensidades desde la v0.2.20, elegibles por página: el texto del hero
   va siempre en blanco, así que una foto clara necesita bastante más velo que
   una oscura para que se lea. Antes era fijo y obligaba a retocar la foto
   fuera de WordPress. 'medio' es el valor con el que nació la variante, así
   que las páginas que ya existen no cambian.

   Y desde la v0.2.22 también se puede elegir el TINTE, que es otra cosa: la
   intensidad decide cuánto tapa y el tinte de qué color tapa. Va en
   `--kps-velo-rgb` y en RGB sueltos porque los tres degradados son `rgba()`
   con distinta opacidad — un hex no encajaría ahí. Sin elegir nada manda el
   color oscuro de la marca, que es lo que se hacía siempre. */
.kps-hero--imagen .kps-hero__velo {
  position: absolute;
  inset: 0;
  z-index: -1;
}

.kps-hero__velo--suave {
  background: linear-gradient(
    to bottom,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.28) 0%,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.36) 55%,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.52) 100%
  );
}

.kps-hero__velo--medio {
  background: linear-gradient(
    to bottom,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.55) 0%,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.62) 55%,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.78) 100%
  );
}

.kps-hero__velo--fuerte {
  background: linear-gradient(
    to bottom,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.74) 0%,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.80) 55%,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.90) 100%
  );
}

.kps-hero--imagen .kps-hero__inner {
  position: relative;
  text-shadow: 0 1px 24px rgba(0, 0, 0, 0.35);
}

/* ── El texto en el tercio inferior (v0.2.39) ────────────────
   Para qué: con una persona en el centro del encuadre no se puede poner el
   texto centrado encima — le cae en la cara. Lo que se hacía era empujar el
   texto a un lado, que descuadra la página entera y además hay que calcularlo
   para esa foto concreta. Bajándolo, el texto se queda centrado en el eje de
   la página y la cara se ve entera encima.

   La altura mínima es lo que crea el hueco: sin ella el hero mide lo que mide
   su contenido y «abajo» no significaría nada. `min()` para que en una
   pantalla baja no se coma la página y en una alta no se estire sin fin.

   El `flex-end` convive con el `padding-block` del hero: el relleno de abajo
   sigue separando el texto del canto, y el de arriba sigue compensando la
   barra si la hay. */
.kps-hero--contenido-abajo {
  min-height: min(80vh, 46rem);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

/* Refuerzo del velo por abajo, solo en esta variante.

   ⚠ Es obligatorio, y no es adorno: el texto va en blanco y el sitio donde
   ahora cae —el tercio inferior— es justo donde suele estar lo más claro de
   una foto. Se hace con una capa aparte y no retocando los tres degradados
   para que **la intensidad siga significando lo mismo**: quien eligió
   «suave» no ve de pronto un velo medio en toda la foto, solo algo más de
   peso donde hay letras. */
.kps-hero--contenido-abajo .kps-hero__velo::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 55%;
  background: linear-gradient(
    to top,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0.45) 0%,
    rgba(var(--kps-velo-rgb, var(--kls-dark-rgb)), 0) 100%
  );
}

/* ── Contenido sobre fondo lleno ─────────────────────────────
   Lo que comparten las variantes 'marca', 'color' e 'imagen': el texto va en
   blanco, y con él hay que invertir etiqueta y botones o desaparecen.

   La clase `--invertido` la pone la plantilla junto a la variante concreta.
   Antes cada una de estas reglas iba con los selectores repetidos uno por
   variante, y añadir la tercera habría significado tocar las doce.

   ⚠ El HTML de respaldo de las páginas guardadas antes de la v0.2.22 no lleva
   esta clase, pero tampoco esta hoja: `render_static()` incrusta una copia del
   CSS del momento junto al marcado, así que cada respaldo es coherente consigo
   mismo. */
.kps-hero--invertido .kps-hero__title { color: rgba(255, 255, 255, 0.88); }
.kps-hero--invertido .kps-highlight { color: #fff; }
.kps-hero--invertido .kps-hero__lead { color: rgba(255, 255, 255, 0.82); }

.kps-hero--invertido .kps-badge {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.28);
  box-shadow: none;
  color: #fff;
}
.kps-hero--invertido .kps-badge__dot { background: #fff; }

/* El botón primario toma el color del fondo sobre el que se recorta: en la
   variante de color a medida, el rubí de la marca cantaría. */
.kps-hero--invertido .kps-btn--primario {
  background: #fff;
  color: var(--kps-hero-bg, var(--kls-ruby));
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
}
.kps-hero--invertido .kps-btn--primario:hover {
  background: rgba(255, 255, 255, 0.9);
  color: var(--kps-hero-bg, var(--kls-ruby-dark));
}

.kps-hero--invertido .kps-btn--secundario {
  background: transparent;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.55);
}
.kps-hero--invertido .kps-btn--secundario:hover {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.1);
}

.kps-hero__inner {
  text-align: center;
  max-width: 900px;
}

.kps-hero__title {
  font-family: var(--kls-font-display);
  font-size: clamp(2rem, 5.5vw, 3.4rem);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.035em;
  color: var(--kls-text);
  margin: 0 0 1rem;
}

.kps-hero__lead {
  font-size: clamp(1rem, 2.3vw, 1.2rem);
  color: var(--kls-text-muted);
  line-height: 1.7;
  margin: 0 auto 2rem;
  max-width: 68ch;
}

/* ── Etiqueta ───────────────────────────────────────────────── */
.kps-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.45em 1em;
  margin-bottom: 1.5rem;
  border-radius: 999px;
  background: var(--kls-bg-page);
  border: 1px solid rgba(var(--kls-dark-rgb), 0.08);
  box-shadow: 0 2px 10px rgba(var(--kls-dark-rgb), 0.05);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--kls-text-muted);
}

.kps-badge__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--kls-ruby);
}

/* ── Botones ────────────────────────────────────────────────── */
.kps-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}

.kps-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.8em 1.5em;
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.18s, box-shadow 0.18s, background 0.18s;
}

.kps-btn--primario {
  background: var(--kls-ruby);
  color: #fff;
  box-shadow: 0 6px 20px rgba(var(--kls-ruby-rgb), 0.28);
}

.kps-btn--primario:hover {
  background: var(--kls-ruby-dark);
  transform: translateY(-1px);
  color: #fff;
}

.kps-btn--secundario {
  background: var(--kls-bg-page);
  color: var(--kls-text);
  border: 1px solid rgba(var(--kls-dark-rgb), 0.12);
}

.kps-btn--secundario:hover {
  border-color: rgba(var(--kls-dark-rgb), 0.24);
  transform: translateY(-1px);
}

/* ── Bloque ─────────────────────────────────────────────────── */
.kps-block {
  padding-block: var(--kps-section-py);
  background: transparent;
}

.kps-block--gris {
  background: var(--kls-bg-alt);
}

/* Primer bloque sin cabecera, justo debajo del hero.

   Los dos rellenos se suman —hasta 3,5rem del hero abajo más 5,5rem del bloque
   arriba— y, sin cabecera que los ocupe, eso es un vacío de 9rem entre el texto
   del hero y el contenido. Se ve en cualquier página cuyo primer bloque sea un
   listado: la de blog, sin ir más lejos.

   El selector es adyacente a propósito. Entre dos bloques ese relleno sí separa
   dos secciones y no se toca; y si el hero está apagado, tampoco: entonces el
   bloque es lo primero de la página y necesita su aire.

   Solo se recorta ARRIBA. El de abajo separa del bloque siguiente o del CTA. */
.kps-hero + .kps-block--sin-cabecera {
  padding-block-start: clamp(0.5rem, 2vw, 1.25rem);
}

.kps-block__head {
  text-align: center;
  max-width: 780px;
  margin: 0 auto clamp(2rem, 5vw, 3.5rem);
}

.kps-kicker {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--kls-ruby);
  margin-bottom: 0.9rem;
}

.kps-kicker--inv {
  color: var(--kls-ruby-light);
}

.kps-block__title {
  font-family: var(--kls-font-display);
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  font-weight: 800;
  line-height: 1.16;
  letter-spacing: -0.03em;
  color: var(--kls-text);
  margin: 0 0 0.9rem;
}

/* `div`, no `p`, desde la v0.2.19. El texto admite `<p>`, `<ul>` y `<li>` por
   `allowed_html()`, y ninguno de los tres puede ir dentro de un párrafo: el
   navegador cerraba el envoltorio por su cuenta y dejaba un párrafo vacío
   ocupando su margen. Los márgenes se gobiernan ahora desde los hijos. */
.kps-block__text {
  font-size: 1.02rem;
  color: var(--kls-text-muted);
  line-height: 1.75;
  margin: 0;
}

.kps-block__text > :first-child { margin-top: 0; }
.kps-block__text > :last-child  { margin-bottom: 0; }
.kps-block__text p              { margin: 0 0 1em; }
.kps-block__text ul,
.kps-block__text ol             { margin: 0 0 1em; padding-left: 1.25em; }
.kps-block__text li             { margin-bottom: 0.4em; }

.kps-block__slot {
  margin-top: 0.5rem;
}

/* ── Vídeo del bloque (v0.2.38) ──────────────────────────────
   Va entre la cabecera y el hueco, centrado y con un ancho máximo: a todo el
   ancho de un contenedor de 1.100 px un 16:9 mide casi 620 px de alto y se come
   la pantalla entera de un portátil.

   `aspect-ratio` en vez del truco del padding: la caja tiene que tener alto
   ANTES de que se sustituya la portada por el iframe, o al pulsar el play la
   página pega un salto. */
.kps-block__video {
  position: relative;
  max-width: 46rem;
  margin: 0 auto 2rem;
  aspect-ratio: 16 / 9;
  border-radius: 14px;
  overflow: hidden;
  background: #000;
  box-shadow: 0 12px 32px rgba(var(--kls-dark-rgb), 0.14);
}

.kps-block__video iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* La portada: la miniatura de YouTube y el botón de play. El reproductor de
   verdad no se carga hasta que se pulsa — son varios cientos de KB y cookies
   de terceros que, si nadie le da al play, no hacen ninguna falta. */
.kps-video-facade {
  width: 100%;
  height: 100%;
  border: 0;
  margin: 0;
  padding: 0;
  cursor: pointer;
  background-color: #000;
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
}

.kps-video-facade__play {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 68px;
  height: 48px;
  border-radius: 14px;
  background: rgba(0, 0, 0, 0.75);
  transition: background 0.15s, transform 0.15s;
}

.kps-video-facade:hover .kps-video-facade__play,
.kps-video-facade:focus-visible .kps-video-facade__play {
  background: #c41230;
  transform: scale(1.06);
}

.kps-block__action {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
}

/* ── Disposición con imagen al lado (v0.2.8) ─────────────────────────────
   Un eje del MISMO bloque, no una sección nueva: cambia cómo se reparte el
   espacio, no qué contiene. La cabecera deja de ir centrada porque a dos
   columnas el texto centrado se lee mal. */
.kps-block--media .kps-block__split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.kps-block--media .kps-block__head {
  text-align: left;
  max-width: none;
  margin: 0;
}

/* El orden lo decide el CSS, no el marcado: así el HTML sale siempre en el
   mismo orden de lectura —texto y luego imagen— y en móvil, donde las
   columnas se apilan, el texto va primero en las dos variantes. */
.kps-block--media-izquierda .kps-block__media {
  order: -1;
}

.kps-block__media {
  margin: 0;
}

.kps-block__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--kps-radius);
  box-shadow: 0 14px 40px rgba(var(--kls-dark-rgb), 0.12);
}

/* Los botones de la columna de texto se alinean con él, no al centro. */
.kps-btn-row--inline {
  justify-content: flex-start;
  margin-top: 1.75rem;
}

@media (max-width: 860px) {
  .kps-block--media .kps-block__split {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  /* Apilado, la imagen vuelve debajo del texto también en media_izquierda. */
  .kps-block--media-izquierda .kps-block__media {
    order: 0;
  }
}

/* ── Tarjetas ───────────────────────────────────────────────── */
.kps-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.5rem;
}

.kps-card {
  display: block;
  padding: 1.75rem;
  border-radius: var(--kps-radius);
  background: var(--kls-bg-page);
  border: 1px solid rgba(var(--kls-dark-rgb), 0.07);
  box-shadow: 0 4px 16px rgba(var(--kls-dark-rgb), 0.05);
  text-decoration: none;
  color: inherit;
  transition: transform 0.2s, box-shadow 0.2s;
}

.kps-card--link:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 32px rgba(var(--kls-dark-rgb), 0.10);
}

.kps-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 10px;
  background: rgba(var(--kls-ruby-rgb), 0.08);
  color: var(--kls-ruby);
  font-size: 1.15rem;
  margin-bottom: 1.1rem;
}

/* El icono es un SVG incrustado desde la v0.2.6, no un glifo: `font-size` no
   lo dimensiona. Sin ancho ni alto el navegador lo pinta a 300x150 y revienta
   la tarjeta. Con `1em` sigue al tamaño de letra de arriba, como hacía el glifo. */
.kps-card__icon svg {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
}

/* La foto de la tarjeta (v0.2.38). Ocupa el sitio del icono y es bastante más
   grande que él: es una cara, y a 46 px no se reconoce a nadie.

   `aspect-ratio` + `object-fit: cover` para que un retrato que no venga
   cuadrado no salga deformado — llegan de donde llegan, y el recorte centrado
   acierta casi siempre con una cara. El borde claro la despega de la tarjeta
   cuando la foto tiene el fondo blanco, que si no parece flotar. */
.kps-card__foto {
  display: block;
  width: 88px;
  height: 88px;
  margin-bottom: 1.1rem;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(var(--kls-dark-rgb), 0.06);
  box-shadow: 0 0 0 3px rgba(var(--kls-dark-rgb), 0.06);
}

.kps-card__foto img {
  width: 100%;
  height: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
}

.kps-card__title {
  font-family: var(--kls-font-display);
  font-size: 1.12rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--kls-text);
  margin: 0 0 0.6rem;
}

.kps-card__text {
  font-size: 0.95rem;
  color: var(--kls-text-muted);
  line-height: 1.7;
  margin: 0;
}

/* ── CTA final ──────────────────────────────────────────────── */
.kps-cta {
  padding-block: var(--kps-section-py);
  background: var(--kls-bg-dark);
}

.kps-cta__inner {
  text-align: center;
  max-width: 760px;
}

.kps-cta__title {
  font-family: var(--kls-font-display);
  font-size: clamp(1.5rem, 3.6vw, 2.2rem);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: #fff;
  margin: 0 0 0.9rem;
}

/* Mismo cambio de `p` a `div` que en el bloque, y por el mismo motivo. Aquí
   el síntoma era más visible: un hueco muerto entre el titular y el botón. */
.kps-cta__text {
  font-size: 1.02rem;
  color: rgba(255, 255, 255, 0.74);
  line-height: 1.7;
  margin: 0 0 1.75rem;
}

.kps-cta__text > :first-child { margin-top: 0; }
.kps-cta__text > :last-child  { margin-bottom: 0; }
.kps-cta__text p              { margin: 0 0 0.75em; }

/* ── Responsive ─────────────────────────────────────────────── */
@media (max-width: 640px) {
  .kps-btn-row {
    flex-direction: column;
    align-items: stretch;
  }

  .kps-cards {
    grid-template-columns: 1fr;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   Ninja Forms dentro de un hueco de bloque (v0.2.7)

   Portado desde la seccion de contacto de Kenzen Landing System, donde el
   aspecto de Ninja Forms ya estaba resuelto. Se reapunta el ambito de
   .kenzen-contact__form-wrap a .kps-block__slot, asi que cualquier
   formulario metido en un bloque queda con el estilo de la casa sin
   necesidad de campos nuevos.

   Se COPIA en vez de compartirse porque los tres plugins son independientes
   a proposito, igual que los deltas de color. Si se toca el de KLS, tocar
   este tambien.

   Los dos fondos que en KLS eran literales (#f2f4f7 y #fff) pasan aqui a
   var(--kls-bg-alt) y var(--kls-bg-page). El color #fff del texto del boton
   se mantiene: es texto sobre el color de acento, no un color de marca, y es
   lo que ya usa .kps-btn--primario.
   ══════════════════════════════════════════════════════════════════════ */
.kps-block__slot .nf-form-cont,
.kps-block__slot .nf-form-layout {
  font-family: var(--kls-font-sans) !important;
}

/* Eliminar padding y margin propios de NF */
.kps-block__slot .nf-form-fields-required,
.kps-block__slot .nf-field-container {
  margin-bottom: 1.25rem !important;
}

.kps-block__slot .nf-form-fields-required {
  font-size: 0.8rem;
  color: var(--kls-text-subtle);
  margin-bottom: 1.5rem !important;
}

/* Labels */
.kps-block__slot .nf-field-label label,
.kps-block__slot label {
  font-family: var(--kls-font-sans) !important;
  font-size: 0.9rem !important;
  font-weight: 700 !important;
  color: var(--kls-text) !important;
  letter-spacing: -0.01em;
  margin-bottom: 0.5rem !important;
  display: block;
}

/* Asterisco required */
.kps-block__slot .ninja-forms-req-symbol {
  color: var(--kls-ruby) !important;
}

/* Inputs y textarea */
.kps-block__slot input[type="text"],
.kps-block__slot input[type="email"],
.kps-block__slot input[type="tel"],
.kps-block__slot input[type="number"],
.kps-block__slot input[type="url"],
.kps-block__slot textarea {
  width: 100% !important;
  background: var(--kls-bg-alt) !important;
  border: 1.5px solid transparent !important;
  border-radius: var(--kls-radius-lg) !important;
  padding: 0.9rem 1.1rem !important;
  font-family: var(--kls-font-sans) !important;
  font-size: 1rem !important;
  color: var(--kls-text) !important;
  outline: none !important;
  box-shadow: none !important;
  transition: border-color 0.2s, background 0.2s !important;
  -webkit-appearance: none;
  appearance: none;
}

.kps-block__slot input[type="text"]:focus,
.kps-block__slot input[type="email"]:focus,
.kps-block__slot input[type="tel"]:focus,
.kps-block__slot input[type="number"]:focus,
.kps-block__slot input[type="url"]:focus,
.kps-block__slot textarea:focus {
  background: var(--kls-bg-page) !important;
  border-color: var(--kls-ruby) !important;
  box-shadow: 0 0 0 3px rgba(var(--kls-ruby-rgb),0.08) !important;
}

.kps-block__slot textarea {
  min-height: 130px !important;
  resize: vertical !important;
}

/* Botón enviar */
.kps-block__slot input[type="button"],
.kps-block__slot button[type="submit"],
.kps-block__slot .nf-element[type="button"],
.kps-block__slot .submit-wrap input {
  width: 100% !important;
  background: var(--kls-ruby) !important;
  color: #fff !important;
  border: none !important;
  border-radius: var(--kls-radius) !important;
  padding: 1rem 2rem !important;
  font-family: var(--kls-font-sans) !important;
  font-size: 0.9rem !important;
  font-weight: 800 !important;
  letter-spacing: 0.12em !important;
  text-transform: uppercase !important;
  cursor: pointer !important;
  transition: background 0.2s, transform 0.15s !important;
  margin-top: 0.5rem !important;
  box-shadow: 0 4px 18px rgba(var(--kls-ruby-rgb),0.25) !important;
}

.kps-block__slot input[type="button"]:hover,
.kps-block__slot button[type="submit"]:hover,
.kps-block__slot .submit-wrap input:hover {
  background: var(--kls-ruby-dark) !important;
  transform: translateY(-2px) !important;
  box-shadow: 0 6px 24px rgba(var(--kls-ruby-rgb),0.35) !important;
}

/* Mensajes de error y éxito */
.kps-block__slot .nf-error .nf-field-element input,
.kps-block__slot .nf-error .nf-field-element textarea {
  border-color: var(--kls-ruby) !important;
}

.kps-block__slot .nf-error-msg {
  font-size: 0.8rem !important;
  color: var(--kls-ruby) !important;
  margin-top: 0.3rem !important;
}

.kps-block__slot .nf-response-msg {
  padding: 1rem 1.25rem;
  background: rgba(var(--kls-ruby-rgb),0.06);
  border-left: 3px solid var(--kls-ruby);
  border-radius: 0 var(--kls-radius) var(--kls-radius) 0;
  font-weight: 600;
  color: var(--kls-text);
  margin-top: 1rem;
}

/* ─────────────────────────────────────────────────────────────────────────
   Disposiciones con cabecera ancha (v0.2.10)

   media_izquierda_hueco · media_derecha_hueco

   La cabecera ocupa todo el ancho y hace de separador entre secciones; debajo,
   la imagen y el hueco comparten fila. Se apoyan en la retícula que ya monta
   `.kps-block--media .kps-block__split`, así que aquí solo van las diferencias.
   ───────────────────────────────────────────────────────────────────────── */

/* La cabecera recupera el centrado del layout `centrado`: con media hereda
   text-align:left y max-width:none, que es justo lo contrario de un separador. */
.kps-block--hueco-lateral .kps-block__head {
  text-align: center;
  max-width: 780px;
  margin: 0 auto clamp(2rem, 5vw, 3.5rem);
}

/* Alineadas arriba, no centradas: la lista y la foto rara vez miden lo mismo,
   y centrarlas deja la primera fila de la lista flotando a media altura. */
.kps-block--hueco-lateral .kps-block__split {
  align-items: start;
}

/* El marcado sale siempre contenido → imagen. Solo esta variante lo invierte,
   y lo hace por CSS para que en móvil el contenido siga yendo primero. */
.kps-block--media-izquierda-hueco .kps-block__media {
  order: -1;
}

/* El hueco ya está separado por la cabecera; el margen de arriba sobra. */
.kps-block__slot--columna {
  margin-top: 0;
}

/* La imagen se recorta a la altura de la columna en vez de estirar la fila:
   una foto vertical al lado de una lista corta descuadraba la sección. */
.kps-block--hueco-lateral .kps-block__img {
  height: 100%;
  max-height: 32rem;
  object-fit: cover;
}

.kps-btn-row--hueco {
  justify-content: flex-start;
  margin-top: 1.5rem;
}

@media (max-width: 860px) {
  /* Apilado, la foto vuelve a mandar su propia altura: recortada a 32rem sobre
     el ancho completo del móvil se veía como una franja. */
  .kps-block--hueco-lateral .kps-block__img {
    height: auto;
    max-height: none;
  }
  .kps-btn-row--hueco {
    justify-content: center;
  }
}

/* Texto bajo la imagen (v0.2.12). Llena el hueco que queda cuando la columna
   de al lado —una lista larga de cursos— es más alta que la foto. */
.kps-block__media-text {
  margin: 1rem 0 0;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--kls-text-muted, #3D4A60);
}

/* ── Barra superior ──────────────────────────────────────────
   Franja de borde a borde por encima del hero. Va fuera del contenedor a
   propósito: el color llega hasta los bordes de la ventana y `.kps-container`
   solo centra el contenido.

   El `#fff` es texto y fondo de botón **sobre el color de acento**, no un color
   de marca — el mismo criterio que ya sigue `.kps-btn--primario`. Cualquier otro
   literal aquí rompería la multi-marca en silencio. */
.kps-banner {
  background: var(--kls-ruby);
  color: #fff;
}

.kps-banner__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.6rem 1.25rem;
  padding-block: 0.7rem;
}

.kps-banner__text {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
}

.kps-banner__cta {
  /* Sin esto, el botón se estira o se parte cuando el texto ocupa dos líneas. */
  flex: none;
  display: inline-block;
  padding: 0.4em 1.1em;
  border-radius: 8px;
  background: #fff;
  color: var(--kls-ruby);
  font-size: 0.85rem;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  transition: transform 0.2s, box-shadow 0.2s;
}

.kps-banner__cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(var(--kls-dark-rgb), 0.22);
}

/* ── Cuenta atrás de la barra ─────────────────────────────────
   Las cifras las escribe `kenzen-page.js` contra el epoch de
   `data-kps-countdown`; el reloj nace `hidden` y solo se destapa si queda
   tiempo. Sin JS —el respaldo estático de `post_content`— no aparece, en vez de
   quedarse congelado en el día en que se guardó la página.

   Sobre el fondo de marca, cajas blancas translúcidas y cifras en blanco: un
   `#fff` aquí es texto sobre el color de acento, no un color de marca. */
.kps-banner__reloj {
  display: flex;
  gap: 0.4rem;
}

/* ⚠️ El `display:flex` de arriba gana al `[hidden]{display:none}` del
   navegador. Sin esta regla el reloj se vería siempre, con ceros incluidos. */
.kps-banner__reloj[hidden] {
  display: none;
}

.kps-banner__unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 2.6rem;
  padding: 0.25rem 0.4rem;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.16);
  line-height: 1.1;
}

.kps-banner__unit b {
  font-size: 1.05rem;
  font-weight: 800;
  /* Sin esto el ancho baila en cada tic al cambiar de dígito. */
  font-variant-numeric: tabular-nums;
}

.kps-banner__unit i {
  font-size: 0.6rem;
  font-style: normal;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  opacity: 0.85;
}
