/*
Theme Name: AITSS
Theme URI: https://aitss.com.co
Author: AITSS
Description: Theme de bloques del sitio de autoridad de AITSS. Minimal, ejecutivo, bilingue ES/EN.
Version: 1.2.0
Text Domain: aitss
*/

:root {
  /* AW-137: sin esta declaracion el navegador pinta EN CLARO todo lo que dibuja el, aunque
     la pagina sea negra: la casilla de consentimiento, la barra de scroll, los selectores de
     fecha y -- el que mas dano hace en una pagina de registro -- el fondo del autocompletado.
     Ningun token puede sustituirla, porque esos pixeles no los pinta el CSS del sitio.
     Medido antes del arreglo: color-scheme resolvia a `normal` en los TRES contextos,
     incluido el oscuro. */
  color-scheme: light;

  /* ADR-003: Capa de puente (Bridge Layer) para la marca configurable */
  --accent: var(--wp--preset--color--accent);
  --accent-hover: var(--wp--preset--color--accent-hover);
  --accent-contrast: #FFFFFF;

  /* AW-137: el acento como RELLENO GRANDE es un problema distinto del acento como TEXTO, y
     un solo token no puede resolver los dos en oscuro.
     Texto en acento sobre #111111 necesita mucha luminancia para llegar a 4.5:1; un relleno
     de 376x47 px con esa misma luminancia se convierte en una fuente de luz. Medido: el
     #F04438 del boton tiene L=0.2295 sobre un fondo de L=0.0055, o sea 41 veces mas
     luminoso que la pagina que lo rodea. En claro pasa lo contrario -- el #8D1713 es 15
     veces MAS OSCURO que su fondo -- y por eso el mismo diseno se lee sobrio en claro y
     estridente en oscuro. No es opinion: es que el acento cambia de papel.
     Estos tokens separan los dos usos. En claro valen lo mismo que --accent, asi que el
     modo claro no cambia ni un pixel. */
  --accent-solid: var(--accent);
  --accent-solid-hover: var(--accent-hover);
  --accent-solid-contrast: #FFFFFF;

  /* Neutros Light Mode (Default) - design-system.md §7
   *
   * AW-113: el fondo pasa de blanco y gris frio a la familia calida del acento. El gris
   * frio #F7F8FA competia en temperatura con el rojo #8D1713 y lo dejaba aislado en la
   * pagina en vez de integrado. Estos valores son el propio acento diluido al 3% y al 7%
   * sobre blanco, asi que armonizan por construccion y no por criterio.
   *
   * Efecto colateral medido y corregido: con fondo calido el #6B7280 anterior caia a
   * 4.14:1 sobre la banda, bajo el minimo de 4.5:1 de WCAG AA. Pasa a #655F58, un gris
   * calido de la misma familia, que da 5.42:1.
   *
   * Las tarjetas se quedan en blanco puro a proposito: sobre la banda daban 1.06 de
   * separacion y casi no se despegaban del fondo; ahora dan 1.16. */
  --bg: #FBF7F6;
  /* --surface gobierna toda superficie elevada: tarjetas, cajas, el hero de paginas
   * interiores, la cabecera. Era #FFFFFF y sobre el fondo blush se leia como un
   * rectangulo blanco pegado. Basta cambiar este valor para que todo el sitio lo tome. */
  --surface: #FEFCFB;
  --surface-alt: #F4ECEB;
  /* Los campos van sobre paneles de --surface-alt (#F4ECEB), asi que para despegarse
   * tienen que ser mas CLAROS que el panel, no mas oscuros. Con #F7F1EF quedaban a 1.03
   * del panel y el PO dijo que se perdian. */
  --field: #FDFAF9;
  --text: #111111;
  --text-muted: #655F58;
  --border: #E8DDDB;
  --field-border: #8C807E;

  /* Espaciado, Radios, Sombras - design-system.md §10 */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-full: 9999px;

  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
  /* AW-96: el hero y las tarjetas de páginas hijas ya usaban --shadow-card, que no
     estaba declarada en ningún lado. La sombra sencillamente no se pintaba. */
  --shadow-card: var(--shadow-md);

  /* AW-27 fix BREAK (HIGH/MED): tokens fijos para bandas oscuras intencionales
     (hero/cta-band variant=dark), independientes del toggle claro/oscuro global.
     #181818 (no #111111) para que la banda se distinga de --bg también en dark global. */
  --band-dark-bg: #181818;
  --band-dark-text: #F4F4F5;
  --band-dark-muted: #9AA0AA;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* AW-31: el acento de marca sobre fondo oscuro daba 1.91:1, muy por debajo del
       4.5:1 que exige AA. No es preferencia estetica: el texto en acento era dificil de
       leer para cualquiera y directamente inaccesible para parte de los visitantes.
       #E0564B da 4.74:1 sobre #181818. Es el mismo tono que AW-39 reporto hardcodeado
       y desacoplado: el sistema ya lo habia contemplado, sólo nunca se conecto al token.
       AW-137: el hex de ese parrafo nunca fue el que se pinta. --accent-dark vale #F04438
       en theme.json, no #E0564B, asi que lo aplicado es #F04438. La conclusion aguanta de
       casualidad -- #F04438 da 4.73:1 sobre #181818, a una centesima del numero citado --
       pero quien lea el comentario buscando #E0564B en la paleta no lo va a encontrar. */
    /* AW-31: con el acento claro, el texto del boton primario tiene que oscurecerse.
     Blanco sobre #E0564B da 3.75:1 y falla AA; #111111 da 5.04:1. Corregir el contraste
     del acento sin corregir el del texto encima habria cambiado un fallo por otro. */
  --accent-contrast: #111111;
  --accent: var(--wp--preset--color--accent-dark);
    --accent-hover: var(--wp--preset--color--accent-dark-hover);
    /* AW-137: ver la nota de --accent-solid en :root. #C62A22 sale de resolver a la vez
       cuatro restricciones, no de elegir un rojo que guste:
         blanco encima            5.59:1  (AA pide 4.5)
         contra la pagina #111111 3.38:1  (WCAG 1.4.11 pide 3.0 para el borde del componente)
         contra la caja  #1C1C1E  3.04:1  (que es la adyacencia real: el boton va dentro)
         saturacion 71% y L=0.1378, contra el 86% y L=0.2295 del #F04438: 40% menos luz.
       El matiz se queda en 3 grados, el mismo del #8D1713 de marca (2 grados), asi que
       sigue siendo el rojo de AITSS y no otro color. */
    --accent-solid: #C62A22;
    --accent-solid-hover: #D13328;
    --accent-solid-contrast: #FFFFFF;
    color-scheme: dark;
    --bg: #111111;
    --surface: #181818;
    --surface-alt: #1C1C1E;
    /* Este token FALTABA aqui y si estaba en :root[data-theme="dark"]. Consecuencia: para quien
       tiene el sistema operativo en oscuro y NUNCA toco el conmutador -- el caso por defecto --
       --text pasaba a #F4F4F5 y --field conservaba el #FDFAF9 de :root. Texto casi blanco sobre
       campo casi blanco: el formulario de Contacto quedaba ilegible, en la pagina de conversion
       del sitio. Los dos bloques de modo oscuro tienen que declarar los MISMOS tokens; que uno
       sea la preferencia del sistema y el otro el conmutador manual no cambia lo que hay que
       pintar. */
    --field: #131314;
    --text: #F4F4F5;
    --text-muted: #9AA0AA;
    --border: #2A2A2C;
    --field-border: #6A6A6E;
    --shadow-sm: 0 1px 2px 0 rgba(255, 255, 255, 0.05);
    --shadow-md: 0 4px 6px -1px rgba(255, 255, 255, 0.05);
  }
}

:root[data-theme="dark"] {
  /* AW-31: ver la nota del bloque de prefers-color-scheme. */
  /* AW-31: con el acento claro, el texto del boton primario tiene que oscurecerse.
     Blanco sobre #E0564B da 3.75:1 y falla AA; #111111 da 5.04:1. Corregir el contraste
     del acento sin corregir el del texto encima habria cambiado un fallo por otro. */
  --accent-contrast: #111111;
  --accent: var(--wp--preset--color--accent-dark);
  --accent-hover: var(--wp--preset--color--accent-dark-hover);
  /* AW-137: los mismos tres tokens que el bloque de prefers-color-scheme. Que uno sea la
     preferencia del sistema y el otro el conmutador manual no cambia lo que hay que pintar;
     declararlos en uno solo es como se rompio ya una vez el formulario de Contacto. */
  --accent-solid: #C62A22;
  --accent-solid-hover: #D13328;
  --accent-solid-contrast: #FFFFFF;
  color-scheme: dark;
  --bg: #111111;
  --surface: #181818;
  --surface-alt: #1C1C1E;
  --field: #131314;
  --text: #F4F4F5;
  --text-muted: #9AA0AA;
  --border: #2A2A2C;
  --field-border: #6A6A6E;
  --shadow-sm: 0 1px 2px 0 rgba(255, 255, 255, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(255, 255, 255, 0.05);
}

/* El conmutador explicito tiene que repetir los mismos valores que :root o los anula:
   este bloque gana por especificidad sobre el default. AW-113. */
:root[data-theme="light"] {
  /* AW-137: este bloque tiene que deshacer TAMBIEN el color-scheme y el acento solido, o
     quien tiene el sistema en oscuro y pide claro a mano se queda con los controles nativos
     y el autocompletado pintados en oscuro sobre una pagina blanca. */
  color-scheme: light;
  --accent-solid: var(--accent);
  --accent-solid-hover: var(--accent-hover);
  --accent-solid-contrast: #FFFFFF;
  --bg: #FBF7F6;
  --surface: #FEFCFB;
  --surface-alt: #F4ECEB;
  --field: #FDFAF9;
  --text: #111111;
  --text-muted: #655F58;
  --border: #E8DDDB;
  --field-border: #8C807E;
}

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

body {
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--wp--preset--font-family--manrope, 'Manrope', Inter, system-ui, sans-serif);
  margin: 0;
  padding: 0;
}

/* Fix sticky header broken by ancestor overflow (AW-65) */
html, body, .wp-site-blocks {
  overflow-x: clip;
}

/* Fix sticky header for WP template part wrapper */
.wp-block-template-part:has(.aitss-site-header--sticky) {
  position: sticky;
  top: 0;
  z-index: 100;
}

/* Mega-Menu mobile CTA visibility */
@media (min-width: 1024px) {
  .aitss-mobile-only {
    display: none !important;
  }
}

/* Global Focus-Visible (AW-48) */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Layout Utility (AW-44) */
.aitss-container {
  box-sizing: border-box;
  width: 100%;
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: var(--space-5);
}

/* Buttons — component-library §2.1 */
.aitss-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-5);
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.aitss-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* AW-68b: los modificadores llevan doble clase a proposito.
 *
 * Los botones del contenido salen del seed con wp-block-button__link, y la hoja del
 * nucleo de WordPress los pinta con su gris #32373c. Esa regla tiene la misma
 * especificidad que .aitss-btn--primary y carga despues, asi que ganaba: el boton de
 * /industrias/ se servia negro mientras los de los bloques propios salian rojos.
 *
 * El PO lo reporto varias veces y las correcciones anteriores no dieron con la causa
 * porque el CSS del sistema estaba bien; lo que fallaba era el orden de carga.
 *
 * .aitss-btn.aitss-btn--primary tiene especificidad 0,2,0 y gana siempre, sin depender
 * del orden ni de que theme.json declare styles.elements.button -- que habria tenido el
 * efecto secundario de pintar tambien los secundarios.
 */
/* AW-137: el CTA primario es el otro relleno de acento grande, y esta en la MISMA pantalla
   que el PO reporto -- el boton "Contacto" de la cabecera. Dejarlo en --accent mientras el
   submit pasa a --accent-solid habria puesto dos rojos distintos a la vista a la vez.
   Comprobado que #C62A22 llega a 3:1 contra las tres superficies oscuras donde se apoya un
   CTA: #111111 3.38:1, #181818 3.21:1, #1C1C1E 3.05:1. En claro no cambia nada. */
.aitss-btn.aitss-btn--primary {
  background-color: var(--accent-solid);
  color: var(--accent-solid-contrast);
  border-color: var(--accent-solid);
}

.aitss-btn.aitss-btn--primary:hover {
  background-color: var(--accent-solid-hover);
  border-color: var(--accent-solid-hover);
}

.aitss-btn.aitss-btn--primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.aitss-btn.aitss-btn--secondary {
  /* AW-112: el ancho del borde se declara aqui, no solo el color.
     .aitss-btn trae "border: 1px solid transparent", pero esa regla tiene
     especificidad 0,1,0 y la hoja del nucleo de WordPress la pisa con border:none.
     Resultado: el color del borde era el correcto y el ancho 0, asi que el boton
     secundario se servia como texto suelto. Es el mismo defecto de orden de carga de
     AW-104, que se corrigio en los modificadores y no en la regla base. */
  border-width: 1px;
  border-style: solid;
  background-color: transparent;
  color: var(--text);
  /* AW-105: el borde usaba --border (#E5E7EB), que sobre blanco da 1.24:1. WCAG exige
     3:1 para el contorno de un control, y por debajo de eso el boton sencillamente no se
     lee como boton: el PO lo reporto como "no parece un boton". --text-muted da 4.83:1
     y mantiene el registro sobrio, sin competir con el primario. */
  border-color: var(--text-muted);
}

.aitss-btn.aitss-btn--secondary:hover {
  background-color: var(--surface-alt);
}

/* AW-145: el enlace de avance dentro de una columna de texto.
   Antes esos tres enlaces eran botones: uno primario en espanol y dos secundarios, y en
   ingles al reves. El PO los marco como fuera de estandar y tenia razon por una razon
   estructural, no de gusto: en todo el sitio el boton con contorno existe solo en el par
   del hero, al lado del primario. Un boton con contorno solo, en medio de un parrafo, es
   un cuarto estilo que no aparece en ninguna otra parte.
   El sistema ya tiene el gesto correcto para "seguir leyendo mas alla": el enlace en
   versales con flecha de las tarjetas. Esto es ese mismo gesto fuera de la tarjeta. */
.aitss-link-avance {
    margin: var(--space-4) 0 0;
}

.aitss-link-avance a {
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--accent);
    text-decoration: none;
}

.aitss-link-avance a:hover {
    color: var(--accent-hover);
    text-decoration: underline;
}

/* AW-32: Logo Swap */
.aitss-logo-dark {
  display: none;
}
:root[data-theme="dark"] .aitss-logo-light {
  display: none;
}
:root[data-theme="dark"] .aitss-logo-dark {
  display: block;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .aitss-logo-light {
    display: none;
  }
  :root:not([data-theme="light"]) .aitss-logo-dark {
    display: block;
  }
}

/* ==========================================================================
   Fluent Forms Styling (AITSS Premium Match)
   ========================================================================== */
.fluentform {
    font-family: var(--wp--preset--font-family--manrope);
}

/*
 * AW-137: EL defecto de fondo del modo oscuro en la pagina de registro.
 *
 * Fluent Forms pinta su propio <form> con background-color: #FFFFFF y el theme nunca lo
 * desmintio. En claro coincidia con el diseno por casualidad y nadie lo miro. En oscuro
 * quedaba un panel blanco de 442x412 px dentro de una caja #1C1C1E, con los campos casi
 * negros metidos dentro: el "cajas casi negras" que reporto el PO no eran los campos, era
 * el panel blanco que no debia estar ahi.
 *
 * Se pone transparente, no en otro color, porque asi lo dice el propio theme: la nota de
 * AW-126 en .ff-el-form-control dice "Los campos van sobre paneles de --surface-alt
 * (#F4ECEB)". Ese es el diseno documentado -- el formulario directamente sobre la caja --
 * y el panel del plugin lo estaba tapando en los dos modos.
 *
 * Consecuencia medida en claro: el formulario pasa de #FFFFFF a #F4ECEB. Los campos
 * (#FDFAF9) siguen siendo mas claros que su panel, que es justo lo que AW-126 pedia.
 */
.fluentform form.frm-fluent-form {
    background-color: transparent !important;
    /* El plugin dibuja tambien un borde de 1px en #E2E8F0. Mientras el panel era blanco no
       se veia (1.06:1 contra el). En cuanto el fondo se vuelve transparente, ese gris claro
       queda a 13.80:1 sobre la caja #1C1C1E: un marco luminoso alrededor del formulario,
       exactamente el tipo de cosa que aparece al arreglar otra. Se neutraliza el color y no
       el borde entero para no mover el layout un pixel por lado. */
    border-color: transparent !important;
}

/*
 * AW-137: el theme creia que controlaba el color de las etiquetas y no lo controlaba.
 *
 * La regla de abajo apunta a .ff-el-input--label, que es el DIV contenedor. El texto lo
 * pinta un <label> hijo al que Fluent Forms le escribe color: #1A202C. Medido en oscuro:
 * el div resuelve a #F4F4F5 y el label a #1A202C. O sea que --text nunca llego al pixel.
 *
 * Mientras el panel era blanco el fallo era invisible (#1A202C sobre blanco da 16.32:1).
 * En cuanto el panel se oscurece, esos mismos #1A202C sobre #1C1C1E dan 1.11:1 y el
 * formulario se queda sin etiquetas. Arreglar el panel sin arreglar esto habria cambiado
 * un defecto por otro peor.
 */
.fluentform .ff-el-input--label label,
.fluentform label.ff-el-form-label {
    color: var(--text) !important;
}

/* Mismo caso: el plugin escribe #4A5568 en la etiqueta del consentimiento. Se pasa al
   token atenuado, que es lo que el resto del sitio usa para texto secundario y lo que
   mantiene el aspecto del modo claro (#655F58, 5.42:1 sobre la caja). */
.fluentform .ff-el-form-check-label,
.fluentform .ff-el-form-check-label span {
    color: var(--text-muted) !important;
}

/* La etiqueta va en el color del texto, no en el atenuado: es la que dice qué se está
   llenando, y con --text-muted competía en peso con el marcador de posición. */
.fluentform .ff-el-input--label {
    font-size: 0.875rem !important;
    font-weight: 600 !important;
    color: var(--text) !important;
    margin-bottom: var(--space-2) !important;
}

/* El asterisco de obligatorio, en el acento y separado, para que se lea como marca y no
   como parte del nombre del campo. */
.fluentform .ff-el-is-required.asterisk-right label:after,
.fluentform .ff-el-input--label.asterisk-right:after {
    color: var(--accent) !important;
    margin-left: 2px !important;
}

/*
 * AW-126: el borde de los campos usaba --border, que no distingue el campo de su caja en
 * NINGUNO de los dos temas. Medido: en claro #E8DDDB sobre #F4ECEB da 1.14:1 y en oscuro
 * #2A2A2C sobre #1C1C1E da 1.19:1, contra el 3:1 que WCAG 1.4.11 pide para el borde de un
 * control. Y el relleno no ayudaba: en oscuro el input y la caja eran el MISMO color.
 *
 * El PO lo reporto viendo el tema oscuro, pero el defecto siempre estuvo en los dos. En
 * claro pasa desapercibido porque el resto de la pagina da referencias; en oscuro el campo
 * se queda solo y desaparece.
 *
 * --field-border es un token aparte y no se toco --border, porque subir el borde general a
 * 3:1 pondria esa linea en cada divisor decorativo del sitio, que es otro problema.
 */
.fluentform .ff-el-form-control {
    background-color: var(--field, var(--surface)) !important;
    border: 1px solid var(--field-border) !important;
    border-radius: var(--radius-md) !important;
    padding: var(--space-3) var(--space-4) !important;
    color: var(--text) !important;
    font-size: 1rem !important;
    min-height: 44px !important;
    transition: border-color 0.2s ease, box-shadow 0.2s ease !important;
}

/*
 * AW-137: autocompletado del navegador. No habia NI UNA regla en todo el theme.
 *
 * Chrome no respeta background-color en un campo autocompletado: lo pinta el mismo con un
 * amarillo palido o un azul muy claro, y el texto en su propio color. En una pagina de
 * registro en oscuro eso deja tres cajas claras chillonas en medio del formulario en cuanto
 * el visitante acepta el autocompletado -- justo el visitante que MAS avanza en el embudo.
 *
 * Dos capas, porque ninguna basta sola:
 *   1) color-scheme: dark en los bloques de tokens hace que Chrome elija su propia version
 *      oscura del autocompletado. Es la que arregla tambien la casilla y la barra de scroll.
 *   2) esta regla fija el resultado en los tokens del theme y no en lo que decida Chrome.
 *      El relleno va por box-shadow interior porque background-color lo ignora, y el texto
 *      por -webkit-text-fill-color porque color tampoco le llega.
 * La transicion larga evita el parpadeo del color original de Chrome antes de repintar.
 */
.fluentform .ff-el-form-control:-webkit-autofill,
.fluentform .ff-el-form-control:-webkit-autofill:hover,
.fluentform .ff-el-form-control:-webkit-autofill:focus,
.fluentform .ff-el-form-control:-webkit-autofill:active {
    -webkit-text-fill-color: var(--text) !important;
    -webkit-box-shadow: inset 0 0 0 1000px var(--field) !important;
    box-shadow: inset 0 0 0 1000px var(--field) !important;
    caret-color: var(--text) !important;
    transition: background-color 100000s ease-in-out 0s !important;
}

/* El foco tiene que seguir viendose sobre un campo autocompletado: sin esto el anillo lo
   tapa la sombra interior de arriba, que usa la misma propiedad. */
.fluentform .ff-el-form-control:-webkit-autofill:focus {
    -webkit-box-shadow: inset 0 0 0 1000px var(--field),
                        0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent) !important;
    box-shadow: inset 0 0 0 1000px var(--field),
                0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent) !important;
}

/* El marcador de posición nunca sustituye a la etiqueta: se atenúa a propósito para que
   no se confunda con texto ya escrito. */
.fluentform .ff-el-form-control::placeholder {
    color: var(--text-muted) !important;
    opacity: 1 !important;
}

.fluentform .ff-el-form-control:hover {
    border-color: var(--text-muted) !important;
}

.fluentform .ff-el-form-control:focus,
.fluentform .ff-el-form-control:focus-visible {
    border-color: var(--accent) !important;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent) !important;
    outline: none !important;
}

/* Error: color, borde y texto. Nunca sólo color — quien no distingue rojo y verde se
   queda sin la señal, y es requisito de accesibilidad, no una preferencia. */
.fluentform .ff-el-is-error .ff-el-form-control,
.fluentform .ff-el-form-control.ff-el-is-error {
    border-color: var(--accent) !important;
    border-width: 2px !important;
}

.fluentform .error.text-danger,
.fluentform .ff-el-is-error .error {
    color: var(--accent) !important;
    font-size: 0.8125rem !important;
    font-weight: 600 !important;
    margin-top: var(--space-2) !important;
}

/* Consentimiento: el enlace a la política tiene que distinguirse del texto corrido, o
   nadie lo ve. Y la casilla necesita área táctil real en móvil. */
.fluentform .ff-el-form-check-label a {
    color: var(--accent) !important;
    text-decoration: underline !important;
}

.fluentform .ff-el-form-check input[type="checkbox"],
.fluentform .ff-el-form-check input[type="radio"] {
    width: 20px !important;
    height: 20px !important;
    accent-color: var(--accent) !important;
    cursor: pointer !important;
}

.fluentform .ff-el-form-check-label {
    cursor: pointer !important;
    line-height: 1.5 !important;
}

@media (prefers-reduced-motion: reduce) {
    .fluentform .ff-el-form-control {
        transition: none !important;
    }
}

/* AW-96: el botón de envío se servía transparente y sólo aparecía al pasar el ratón.
 *
 * La causa eran tres tokens que no existen. La paleta de theme.json declara únicamente
 * `accent` y `accent-hover`, así que `--wp--preset--color--brand-red`,
 * `--wp--preset--color--white` y `--wp--preset--radius--full` resolvían a nada. Una
 * declaración con una variable indefinida es inválida y el navegador la descarta: el
 * botón se quedaba sin fondo. El hover sí se veía porque tenía el rojo escrito a mano.
 *
 * Que esto sobreviviera tanto tiempo señala un punto ciego: `lint-tokens` excluye
 * style.css de la comprobación de hex literales, y no verifica que las variables
 * referenciadas existan. Anotado en AW-96.
 *
 * El botón de una página de conversión invisible hasta que el visitante lo roza es un
 * defecto de negocio, no de estilo.
 */
.fluentform .ff-btn-submit {
    /* AW-137: pasa de --accent a --accent-solid. Es el unico relleno de acento grande de la
       pagina de registro y era lo que el PO veia "encendido" en oscuro. En claro los dos
       tokens valen lo mismo, asi que aqui no cambia nada. */
    background-color: var(--accent-solid) !important;
    color: var(--accent-solid-contrast) !important;
    /* AW-112: el submit era pildora de 48px con tipografia de 16px mientras los
       142 CTA del sitio miden 41px con radio 10px y 15px. Se alinea al estandar. */
    border-radius: var(--radius-md) !important;
    padding: var(--space-3) var(--space-5) !important;
    /* AW-129: faltaba, y por eso el CTA de la pagina de conversion se pintaba en Arial.
       Un <button> NO hereda font-family del documento: el navegador le impone la suya de
       interfaz salvo que se le diga lo contrario. .aitss-btn ya lo hacia; esta regla alineo
       radio, relleno, peso y tamano con ese estandar y se dejo la familia fuera. Ninguna
       herramienta podia verlo: el CSS es valido y el HTML servido, identico. */
    font-family: inherit !important;
    font-weight: 600 !important;
    font-size: 0.9375rem !important;
    border: none !important;
    transition: background-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease !important;
    width: 100% !important;
    min-height: 44px !important; /* área táctil mínima en móvil */
    cursor: pointer !important;
}

.fluentform .ff-btn-submit:hover {
    background-color: var(--accent-solid-hover) !important;
    transform: translateY(-1px) !important;
    box-shadow: var(--shadow-md) !important;
}

/* El anillo de foco es requisito de accesibilidad, no decoración: sin él, quien navega
   con teclado no sabe dónde está parado. */
.fluentform .ff-btn-submit:focus-visible {
    outline: 2px solid var(--accent) !important;
    outline-offset: 2px !important;
}

/* Mientras se envía: evita el doble clic y da señal de que algo está pasando. */
.fluentform .ff-btn-submit[disabled],
.fluentform .ff-btn-submit.ff_working {
    opacity: 0.65 !important;
    cursor: wait !important;
    transform: none !important;
}

@media (prefers-reduced-motion: reduce) {
    .fluentform .ff-btn-submit {
        transition: none !important;
    }
    .fluentform .ff-btn-submit:hover {
        transform: none !important;
    }
}

/*
 * AW-137: aqui vivia una regla [data-theme="dark"] .fluentform .ff-el-form-control que
 * repetia background-color: var(--field) y border-color: var(--field-border). Se retira.
 *
 * Era redundante: la regla base .fluentform .ff-el-form-control ya usa esos dos tokens, y
 * los dos estan declarados en los cuatro bloques, asi que el modo oscuro ya funcionaba sin
 * ella. Pero no era inocua. Tenia la misma especificidad que
 * .fluentform .ff-el-form-control:focus y que .ff-el-is-error .ff-el-form-control, y estaba
 * DESPUES en el archivo, asi que ganaba el desempate y les pisaba el border-color.
 *
 * Efecto medido, provocando foco y enviando el formulario vacio:
 *                        borde al foco     borde en error
 *   claro                #8D1713           #8D1713
 *   oscuro por sistema   #F04438           #F04438
 *   oscuro por boton     #6A6A6E           #6A6A6E   <- sin cambio, la senal desaparecia
 *
 * O sea: quien pulsaba el conmutador de tema se quedaba sin indicador de foco (WCAG 2.4.7)
 * y sin marca de campo con error (3.3.1), y quien tenia el sistema en oscuro no. El mismo
 * modo oscuro, dos comportamientos distintos, ninguna herramienta mirando el segundo.
 */

/*
 * Tablas. AW-130: el theme no tenia NI UNA regla para tablas, y una entrada heredada trae
 * una con border-color: black y anchos en pixeles con tres decimales. Al retirar esos
 * estilos en linea la tabla se quedaba con los del navegador, que es peor que como estaba.
 *
 * Se disena para lo que hay: tablas de comparacion dentro de un articulo a 68ch. El scroll
 * horizontal propio es lo que evita que en movil la tabla desborde y empuje la pagina
 * entera, que es el modo tipico en que una tabla rompe un layout responsive.
 */
.wp-block-post-content table,
.entry-content table {
    width: 100%;
    border-collapse: collapse;
    margin: var(--space-6) 0;
    font-size: 0.9375rem;
    display: block;
    overflow-x: auto;
}

.wp-block-post-content th,
.wp-block-post-content td,
.entry-content th,
.entry-content td {
    border: 1px solid var(--border);
    padding: var(--space-3) var(--space-4);
    text-align: left;
    vertical-align: top;
}

.wp-block-post-content th,
.entry-content th {
    background-color: var(--surface-alt);
    font-weight: 600;
    color: var(--text);
}

/* Box component - AW-68 */
.aitss-box {
    background-color: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
}

.aitss-box-surface {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
}


/* ---------------------------------------------------------------------------
 * Clases de contenido usadas por el seed — AW-93
 *
 * Las cuatro se usaban sin que ningún CSS las definiera. El efecto no era un error
 * visible sino algo peor: la sección se servía sin diseño, la página cargaba igual y el
 * deploy salía verde. El PO lo encontró revisando dev a mano, comparando español contra
 * inglés; ahora lo detecta `scripts/lint-tokens.js` (AW-94).
 * ------------------------------------------------------------------------ */

/* Encabezillo de sección. El árbol español pintaba esta píldora con estilos en línea y el
   inglés esperaba esta clase, así que la misma sección se veía distinta en cada idioma.
   La regla toma la versión española, que es la del mockup, y ambos árboles convergen. */
.aitss-eyebrow {
    /* AW-113: era una pildora con fondo y 12px de padding lateral. El fondo
       redondeado sobresalia del titulo que va debajo y no corresponde a ninguna
       de las referencias de diseno del proyecto. Rotulo de texto plano. */
    display: block;
    margin: 0 0 var(--space-4);
    color: var(--accent);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}


/* Línea de certificaciones y estándares aplicados. */
/* AW-117: va sobre una banda, no suelto sobre el fondo. El PO lo reporto en la version
   inglesa: sin superficie propia, la linea de certificaciones se lee como texto perdido
   y no como el sello de respaldo que pretende ser. */
/*
 * Bandas de superficie alterna a borde completo. El fondo lo pinta el envoltorio, no el
 * bloque interno, asi que sangrar .aitss-stats no servia de nada: la banda gris seguia
 * cortada 64px antes de cada margen mientras la cinta de certificaciones atravesaba la
 * pagina. El contenido sigue dentro de .aitss-container, que es lo que mantiene el texto
 * en el ancho de lectura. Mismo conflicto de orden de carga que la cinta: WordPress emite
 * margen cero para .alignfull a igual especificidad, de ahi el selector de tres clases.
 */
.has-global-padding > .aitss-band.alignfull {
    width: 100vw;
    max-width: 100vw;
    margin-inline: calc((100% - 100vw) / 2);
}

/* Con la banda a 100vw, su contenedor interno tiene que devolver el contenido al ancho
   de lectura o las cifras se reparten de borde a borde y la ultima se corta. */
.aitss-band > .aitss-container {
    max-width: var(--wp--style--global--content-size, 1152px);
    margin-inline: auto;
}

/*
 * Cinta de confianza. Se implementa segun ai-specs/design/mockups/home.html (.trust,
 * .trust-in, .trust-label, .cert): banda a todo el ancho con filetes arriba y abajo
 * sobre superficie alterna, fila centrada con separacion de 16/30, rotulo de 14/600 en
 * texto atenuado precedido de un punto de acento, y valores de 16/700 en color de texto.
 *
 * En AW-117 la converti en una pildora con borde y radio completo sin consultar el
 * mockup, y en AW-113 quite la banda dejando solo la pildora: dos marcos anidados
 * primero y un ovalo flotante despues. Ninguna de las dos formas estaba especificada.
 */
.wp-block-group.aitss-trust,
.aitss-trust {
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    background-color: var(--surface-alt);
    /* La cinta del mockup atraviesa la pagina de borde a borde. alignfull dentro de
       este arbol solo llegaba a 64..1216 porque el contenedor de contenido tiene su
       propio relleno, y una banda que se corta antes del borde es justo lo que se lee
       como un rectangulo pegado en medio de la pagina. 100cqw/100vw sin barra de
       desplazamiento para no provocar desbordamiento horizontal. */
    width: 100vw;
    max-width: 100vw;
    /* El margen negativo tiene que salir en la misma regla que gana a alignfull de
       WordPress: con especificidad 0,1,0 el ancho si aplicaba pero el margen no, y la
       banda salia corrida 64px a la derecha (64..1344 en un viewport de 1280). */
    margin-inline: calc((100% - 100vw) / 2);
}

/* Medido en dev: margin-left computaba 0px. WordPress emite
   .has-global-padding > .alignfull { margin-left: 0; margin-right: 0 } con la misma
   especificidad 0,2,0 y carga despues de la hoja del theme, asi que ganaba por orden.
   El mismo patron que ya obligo a duplicar clase en los botones (AW-68b, AW-112). Se
   sube a 0,3,0 en vez de recurrir a !important. */
.has-global-padding > .aitss-trust.alignfull {
    margin-inline: calc((100% - 100vw) / 2);
}

.aitss-certs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-4) 30px;
    margin: 0;
    padding: 28px var(--space-5);
    max-width: none;
}

.aitss-certs__label {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--text-muted);
    font-size: 0.875rem;
    font-weight: 600;
}

.aitss-certs__label::before {
    content: '';
    flex: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: var(--accent);
}

.aitss-certs strong {
    color: var(--text);
    font-size: 1rem;
    font-weight: 700;
}


/* Banda de superficie alterna. Va con esquinas redondeadas y padding propio a propósito:
   un fondo a ancho completo dentro de un contenedor restringido es justo lo que produce el
   rectángulo con bordes duros que el PO reportó (AW-98). Así se lee como un panel
   deliberado, y de paso la sección deja de pegarse al borde en móvil. */
.aitss-surface-alt {
    background-color: var(--surface-alt);
    border-radius: var(--radius-lg);
    padding-left: var(--space-6);
    padding-right: var(--space-6);
}

/* Ficha de autor, fecha y tiempo de lectura de un artículo. */
.aitss-insight-meta {
    color: var(--text-muted);
    font-size: 0.875rem;
}

@media (max-width: 600px) {
    .aitss-insight-meta {
        gap: var(--space-4);
    }
}

/* ---------------------------------------------------------------------------
 * Columna de contenido de /recurso/ — AW-96
 *
 * El PO señaló que, junto a la tarjeta del formulario ya estilada, el texto de la
 * izquierda se veía pobre. El desequilibrio era real: la derecha tenía tarjeta, borde y
 * ritmo, y la izquierda era una lista con viñetas por defecto.
 * ------------------------------------------------------------------------ */

.aitss-recurso__titulo {
    margin-top: var(--space-7);
    padding-top: var(--space-6);
    border-top: 1px solid var(--border);
}

/* Lista de beneficios: marcador propio en el acento en vez de la viñeta del navegador,
   y aire suficiente para que cada punto se lea como una afirmación y no como un ítem. */
.aitss-feature-list {
    list-style: none;
    margin: var(--space-5) 0 0;
    padding: 0;
    max-width: 60ch;
}

.aitss-feature-list li {
    position: relative;
    padding-left: var(--space-5);
    margin-bottom: var(--space-4);
    line-height: 1.7;
}

.aitss-feature-list li:before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background-color: var(--accent);
}

/* Nota de privacidad: presente pero subordinada. Quien la busca la encuentra y quien no,
   no tropieza con ella antes del formulario. */
.aitss-recurso__nota {
    margin-top: var(--space-6);
    color: var(--text-muted);
    font-size: 0.8125rem;
    line-height: 1.6;
    max-width: 52ch;
}

/* ---------------------------------------------------------------------------
 * Prosa con ancho propio dentro de un grupo restringido — AW-106
 *
 * WordPress le aplica `margin-left:auto; margin-right:auto` a los hijos directos de un
 * layout constrained. Un parrafo con su propio `max-width` -- 68ch, mas angosto que el
 * contenedor -- queda entonces **centrado**, mientras el encabezado de al lado, que ocupa
 * todo el ancho, arranca a la izquierda. El resultado es el texto desalineado respecto de
 * su titulo que el PO vio en /en/contact/ y en /en/about-us/.
 *
 * Se corrige aca y no pagina por pagina: el patron esta en todo el arbol ingles, que usa
 * columna unica donde el espanol usa columnas, y volveria a aparecer en la proxima pagina
 * que se escriba asi.
 * ------------------------------------------------------------------------ */
/* AW-112: la regla original solo cubria hijos DIRECTOS de un grupo. En
   /experiencia/sector-portuario/ los parrafos van anidados y quedaban centrados: el
   encabezado arrancaba en 64px y su texto en 308px. Se amplia a cualquier descendiente
   dentro de una maquetacion constrained, que es donde WordPress aplica el margin auto. */
/* AW-117: se excluyen los centrados a proposito. La version anterior forzaba
   margin-inline:0 en todo parrafo con ancho propio, y eso descuadraba los que van
   centrados bajo un titular centrado -- el de "Seis pilares" en las dos portadas.
   Arregle un centrado indebido y rompi los debidos. */
.is-layout-constrained p[style*="max-width"]:not(.has-text-align-center),
.is-layout-constrained ul[style*="max-width"]:not(.has-text-align-center),
.is-layout-constrained ol[style*="max-width"]:not(.has-text-align-center),
.wp-block-group.is-layout-constrained > p[style*="max-width"],
.wp-block-group.is-layout-constrained > ul[style*="max-width"],
.wp-block-group.is-layout-constrained > ol[style*="max-width"] {
    /* AW-112b: con !important a proposito, y es la cuarta vez que el mismo mecanismo
       muerde. WordPress emite CSS por bloque -- .wp-container-core-group-is-layout-xxx --
       con la misma especificidad que esta regla y cargando despues, asi que ganaba y el
       margin auto seguia centrando. Medido en dev: margin-left calculado de 244px, que es
       exactamente (1152 - 664) / 2.
       Subir especificidad con selectores no sirve aca porque la clase generada es
       impredecible. */
    margin-inline: 0 !important;
}

/* AW-118: el skip link no estaba tematizado y heredaba el azul del user-agent
   (#0000EE sobre #111 = 2.01:1). Solo se ve al tabular, pero cuando aparece
   tiene que ser legible en ambos temas. */
.skip-link:focus {
    background-color: var(--surface);
    color: var(--text);
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/*
 * AW-112: el calendario de FluentBooking pinta las celdas de dia a 21x21px en
 * movil, bajo el minimo de 24px que exige WCAG 2.5.8 para un area tactil. Son 16
 * celdas por mes, y el calendario es el paso de conversion de /contacto/. El
 * plugin no expone opcion para esto, asi que se corrige desde el theme.
 *
 * AW-126: la lista llevaba un tercer selector, .fcal_days .day, que apunta a una clase
 * inexistente -- cero apariciones en los bundles del plugin. La regla nunca dejo de
 * aplicar, porque los otros dos si existen (fcal_calendar sale 220 veces y day-enabled 10),
 * pero un selector muerto en una regla viva es la clase de resto que luego hace dudar de si
 * el arreglo sigue en pie.
 */
@media (max-width: 767px) {
  .fcal_calendar .day,
  span.day.day-enabled {
    min-width: 32px;
    min-height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/*
 * FluentBooking, alineacion completa con el theme. AW-126.
 *
 * Lo anterior era una pila de parches: fondos forzados con !important sobre clases
 * concretas, una regla para celdas de dia que apuntaba a una clase que el plugin ya no
 * usa, y de AW-124 un "color: inherit !important" sobre todo el subarbol. Ese ultimo
 * funcionaba pero aplanaba la jerarquia entre texto principal y secundario.
 *
 * Lo que cambia el enfoque: extrayendo los bundles JS que la pagina carga se ve que
 * FluentBooking esta COMPLETAMENTE TOKENIZADO y trae dos juegos de valores, .fcal-light-mode
 * y .fcal-dark-mode, con quince variables cada uno. Y el HTML servido fija el wrapper en
 * "fcal_cal_wrap fcal-light-mode", asi que el widget se pinta siempre con la paleta clara,
 * sin importar el tema del sitio.
 *
 * De ahi salian las tres quejas de golpe, y ninguna era un misterio: los botones azules son
 * --fcal_primary_color:#386bb8 del juego claro; el mes desaparecia porque su encabezado usa
 * --fcal_dark:#1b2533, un color oscuro, sobre nuestro fondo oscuro; y las celdas de dia
 * contrastaban de mas por --fcal_enable_day_bg:#e5e7eb.
 *
 * Se remapean sus quince variables a nuestros tokens en vez de encender .fcal-dark-mode con
 * JavaScript. Asi el widget sigue el tema del sitio en los dos sentidos por construccion --
 * nuestros tokens ya cambian con data-theme -- sin JS que mantener y sin un solo !important.
 * El selector lleva las dos clases a proposito: con una sola empataria en especificidad con
 * la del plugin y ganaria quien se inyecte despues, que es el plugin.
 */
.fcal_cal_wrap.fcal-light-mode,
.fcal_cal_wrap.fcal-dark-mode {
    --fcal_dark: var(--text);
    --fcal_gray: var(--text-muted);
    --fcal_cal_bg: var(--surface);
    --fcal_body_bg: var(--surface);
    --fcal_input_bg: var(--field);
    --fcal_input_disable_bg: var(--surface-alt);
    --fcal_slot_border: var(--border);
    /* La celda de un dia disponible tiene que verse como celda. Aqui iba --field y era un
       error medible: 1.02:1 contra el fondo del calendario en claro y 1.05:1 en oscuro, o
       sea que la celda desaparecia y quedaba el numero suelto. El plugin usaba #e5e7eb y
       #2b2b2b, ~1.2:1 en los dos temas; --border da 1.30:1 y 1.24:1, que es esa misma
       intencion con nuestra paleta. */
    --fcal_enable_day_bg: var(--border);
    --fcal_date_disabled_bg: transparent;
    --fcal_date_disabled_color: var(--text-muted);
    --fcal_thBG: var(--surface-alt);

    /* El acento de la marca, no el azul del plugin ni el blanco de su juego oscuro. El
       boton de agendar es el CTA de la pagina y tiene que verse como los demas del sitio. */
    --fcal_primary_color: var(--accent);
    --fcal_primaryColor: var(--accent);
    --fcal_whiteColor: var(--accent-contrast);

    /* El dia elegido: acento con su color de contraste, no el gris azulado del plugin. */
    --date-picker-selected-background: var(--accent);
    --date-picker-selected-color: var(--accent-contrast);
    --date-picker-highlight-border: var(--accent);
}

/* El selector de zona horaria es un componente svelte-select y no responde a
   background-color sino a sus propias variables. Queda fuera del mapeo de arriba. */
.fcal_timezone_selector.svelte-select,
.fcal_timezone_selector .svelte-select-list,
.fcal_slot_picker_header {
    --background: var(--surface);
    --list-background: var(--surface);
    --item-hover-bg: var(--surface-alt);
    background-color: var(--surface);
}

/* AW-145: ese selector no se leia como un control. El PO: "no tiene mucho contraste y no
 * parece un cuadro de seleccion". La captura de dev le dio la razon de sobra: no es que
 * tuviera poco contraste, es que NO TENIA BORDE. El calculado era "0px none".
 *
 * La causa costo encontrarla y vale la pena dejarla escrita, porque es una trampa que se
 * puede repetir con cualquier componente de terceros que se configure por variables.
 *
 * svelte-select pinta su contorno con  border: var(--border, 1px solid #d8dbdf).  Nuestro
 * sistema de diseno define --border como un COLOR (#E8DDDB), no como un atajo de borde.
 * Ese token es global y se hereda, asi que dentro del componente la sustitucion daba
 * "border: #E8DDDB", que no es un atajo valido: la declaracion queda invalida en tiempo de
 * calculo y la propiedad cae a su valor inicial, o sea sin borde. Nuestro token no
 * competia con el borde del plugin: se lo estaba borrando.
 *
 * Dos intentos anteriores fallaron por atacar el sintoma. Darle el borde al elemento con
 * dos clases no gano, porque svelte repite su clase con hash tres veces a proposito
 * (.svelte-select.svelte-82qwg8.svelte-82qwg8.svelte-82qwg8, que es 0,4,0). Anteponer el
 * nombre de etiqueta tampoco, por lo mismo. Lo que funciona es dejar de pelear y darle a
 * su variable un valor valido, que ademas es como el componente pide ser configurado.
 *
 * El borde va en --text-muted y no en --border por la razon medida en AW-105: --border da
 * 1.24:1 sobre blanco y WCAG pide 3:1 para el contorno de un control. */
div.fcal_timezone_selector.svelte-select {
    --border: 1px solid var(--text-muted);
    --border-hover: 1px solid var(--accent);
    --border-focused: 1px solid var(--accent);
    --border-radius: 6px;
    --height: 44px;
    /* Y el color va aparte, porque el plugin lo fija con
       .svelte-select { border-color: var(--fcal_slot_border) !important }.
       Con el borde ya dibujado, ese !important lo repintaba en --border (1.24:1) y el
       control seguia sin leerse. Se redefine la variable que esa regla consume, en vez de
       pelearle al !important, y solo para este elemento: en el resto del widget
       --fcal_slot_border sigue siendo el filete suave que mapeo AW-126. */
    --fcal_slot_border: var(--text-muted);
}

/* AW-145: la pantalla de confirmacion de la reserva salia con la tipografia del plugin y
   sin jerarquia -- "fuera de estandar sin ningun formato", en palabras del PO. No hace
   falta rehacerla: sus bloques ya vienen con clases propias y solo les faltaba el registro
   del sitio. Rotulo en versales para el nombre del campo, filete gris fino como separador,
   y el mismo ancho de lectura del resto del contenido. Es el mismo lenguaje visual que la
   coleccion de guias. */
/* AW-163: el mensaje de exito se distingue de la caja que lo contiene.
 *
 * El PO tras descargar una guia: "poner algo que diferencie el color donde esta el mensaje
 * de la caja de afuera". Tenia razon y el motivo es de fondo, no de gusto: el mensaje
 * aparece exactamente donde estaba el formulario, sobre el mismo fondo y con el mismo texto
 * corrido. Quien acaba de enviar sus datos necesita una senal de que algo cambio, y sin
 * contraste no la hay.
 *
 * Se usa --surface-alt, que es el tono de caja que el resto del sitio ya emplea, mas un
 * filete de acento a la izquierda. No se inventa un verde de "exito": la paleta es blanco,
 * negro y rojo, y meter un color de semaforo aqui rompe el registro del sitio entero. La
 * senal la da el contraste y el filete, no un color nuevo. */
/* El selector NO cuelga de .fluentform. En la landing del embudo ese envoltorio no
 * existe: el formulario se pinta directo como .frm-fluent-form, asi que una regla
 * descendiente de .fluentform no aplicaba nunca. Fue el primer intento y no se veia nada.
 *
 * Se usa div.ff-message-success para ganarle por especificidad a la regla del propio
 * plugin, que es .ff-message-success a secas, sin depender del orden de carga. */
div.ff-message-success,
div.ff_submit_success {
    /* AW-173: el contraste lo da el FONDO, no un filete lateral. El PO leyo la raya de
     * acento como un tic de contenido generado, y tiene razon en el fondo del argumento: un
     * filete al costado es decoracion, y lo que hacia falta era que la caja se distinguiera
     * del marco que la contiene. Se sube el contraste del relleno y se quita el adorno. */
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: var(--space-5);
    color: var(--text);
    line-height: 1.7;
}

/* El formulario desaparece cuando llega su acuse. Sin esto la pagina muestra a la vez el
 * formulario que se acaba de enviar y el mensaje de que se envio, y el visitante no sabe si
 * tiene que volver a rellenarlo.
 *
 * Se hace con :has() y no cambiando la configuracion del formulario a proposito: esa
 * configuracion vive en la base de datos y el clon se la lleva, que es el problema que
 * acabamos de resolver con los correos. Asi viaja con el deploy. */
form.frm-fluent-form:has(+ div.ff-message-success) {
    display: none;
}

/* AW-173: el que se desborda es ESTE, no .fcal_confirmation.
 *
 * El plugin le pone `max-width: 600px` sin permitir que se encoja, y la columna donde vive
 * es mas estrecha que eso. Mi arreglo anterior fue sobre el hijo, que ya cabia: por eso no
 * cambio nada. La leccion es mirar el marcado antes que el CSS. */
/* AW-174: los DOS contextos, y esta es la tercera vez que se toca esto, asi que conviene
 * dejar escrito por que fallaron las dos anteriores.
 *
 * La confirmacion se pinta de dos formas distintas. Al abrir la URL con meeting_hash, el
 * servidor devuelve una pagina propia del plugin donde el envoltorio SI cuelga de
 * .confirmation_page. Pero justo despues de reservar, el widget la pinta por JavaScript
 * dentro de .fcal_cal_wrap, y ahi ese ancestro NO existe. Mi regla anterior solo cubria el
 * primer caso, que es el unico que se ve con curl y el que menos importa.
 *
 * Se declaran los dos selectores: el suelto cubre la version del widget, y el que repite el
 * ancestro le gana en especificidad a la regla del plugin, que fija 600px. */
.fcal_conf_wrap,
.confirmation_page .fcal_conf_wrap {
    max-width: 100%;
    box-sizing: border-box;
}

.fcal_confirmation {
    /* AW-163: `min()` y no 40rem a secas. El widget vive en la columna derecha de
     * /contacto/, que es mas estrecha que 40rem, asi que ese maximo no lo contenia: el
     * enlace de la videollamada y la nota adicional se salian por el borde derecho y
     * quedaban cortados. El PO lo vio en su reserva de prueba. */
    max-width: min(40rem, 100%);
    margin: 0 auto;
}

/* Nada dentro de la confirmacion puede ser mas ancho que ella, y todo texto rompe donde
 * haga falta. El enlace de Zoom es una sola palabra de doscientos caracteres. */
.fcal_confirmation * {
    max-width: 100%;
}

.fcal_confirmation p,
.fcal_confirmation a,
.fcal_confirmation div {
    overflow-wrap: anywhere;
}

/* AW-176: LA causa del desbordamiento, y estaba un nivel mas arriba de donde mire cuatro
 * veces seguidas.
 *
 * Las columnas de WordPress son elementos flex, y como todo elemento flex traen
 * `min-width: auto`: se niegan a encogerse por debajo del ancho intrinseco de su contenido.
 * El widget de agenda vive dentro de una columna. Cuando su contenido resulta ancho, la que
 * se ensancha es LA COLUMNA, y con ella la pagina entera. Por eso en la captura del PO
 * salian cortadas tambien la barra superior y la cabecera: no era la confirmacion saliendose
 * de su caja, era la pagina volviendose mas ancha que la ventana.
 *
 * Mis cuatro intentos anteriores fueron todos DENTRO del widget, y el widget nunca fue el
 * problema: ya traia max-width 100%.
 *
 * Es el remedio estandar para el maquetado de columnas de WordPress y no tiene efectos
 * secundarios: min-width 0 solo devuelve la capacidad de encoger, que es lo que una columna
 * flexible deberia poder hacer siempre. */
.wp-block-columns > .wp-block-column {
    min-width: 0;
}

/* AW-174: la causa de fondo del desbordamiento, y es un clasico de flexbox.
 *
 * .fcal_confirm_section es un contenedor flex, y los elementos flex traen `min-width: auto`
 * por defecto: eso les impide encogerse por debajo del ancho intrinseco de su contenido. Con
 * un titulo de reunion largo o una URL de videollamada sin espacios, el elemento se niega a
 * estrecharse, ensancha su contenedor y termina empujando la pagina entera. Por eso la barra
 * superior tambien salia cortada en la captura del PO: no era la confirmacion la que se
 * salia de su caja, era la pagina la que se habia vuelto mas ancha que la ventana.
 *
 * `min-width: 0` devuelve la capacidad de encoger, y ahi si actua el overflow-wrap de arriba.
 *
 * Se anula ademas el ancho fijo de 200px del rotulo, que en una columna estrecha reserva
 * espacio que hace falta para el contenido. */
.fcal_confirmation .fcal_confirm_section,
.fcal_confirmation .fcal_confirm_section > * {
    min-width: 0;
}

.fcal_confirmation .fcal_confirm_section_title {
    width: auto;
}

/* AW-174: la cadena completa del widget, tomada del inspector del PO.
 *
 * Este es el arbol real, que solo existe despues de que el JavaScript pinta la
 * confirmacion y que por eso no se ve en el HTML del servidor:
 *
 *   .fcal_cal_wrap > .fluent_booking_app > .fcal_wrap > .fcal_holder [flex]
 *     > .fcal_calendar_inner  <- data-width="478px", ancho que le pone el JavaScript
 *       > .fcal_booking_confirmed > .fcal_confirmation > .fcal_confirm_body
 *
 * El que fuerza el ancho es .fcal_calendar_inner: es hijo de un contenedor flex, asi que
 * trae min-width auto, y ademas recibe un ancho explicito en pixeles calculado para el
 * calendario, no para la confirmacion. Cuando la columna es mas estrecha que ese numero,
 * el elemento no cede y empuja hasta la cabecera de la pagina.
 *
 * Mis reglas anteriores actuaban dos niveles mas abajo, sobre .fcal_confirm_section. El
 * inspector confirmo que aplicaban: estaban bien escritas y sobre el elemento equivocado.
 *
 * Se recorre la cadena entera. max-width 100% doblega el ancho en pixeles del JavaScript y
 * min-width 0 devuelve la capacidad de encoger que flex quita por defecto. */
.fcal_cal_wrap,
.fcal_cal_wrap .fluent_booking_app,
.fcal_cal_wrap .fcal_wrap,
.fcal_cal_wrap .fcal_holder,
.fcal_cal_wrap .fcal_calendar_inner,
.fcal_cal_wrap .fcal_booking_confirmed,
.fcal_cal_wrap .fcal_confirmation,
.fcal_cal_wrap .fcal_confirm_body {
    max-width: 100%;
    min-width: 0;
}

/* Red de seguridad: si aun asi algo resultara mas ancho, que se desplace DENTRO del widget
 * en vez de empujar la pagina. Una barra horizontal en un recuadro es un inconveniente; una
 * en toda la pagina descoloca hasta la cabecera. */
.fcal_cal_wrap {
    overflow-x: auto;
}

.fcal_confirm_header h2 {
    font-family: var(--wp--preset--font-family--manrope, 'Manrope', system-ui, sans-serif);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text);
    margin: 0 0 4px;
}

.fcal_confirm_header p {
    color: var(--text-muted);
    margin: 0 0 8px;
}

.fcal_confirm_section {
    border-top: 1px solid var(--border);
    padding: 14px 0 2px;
}

.fcal_confirm_section_title h4 {
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 0 0 4px;
}

.fcal_confirm_section_content {
    color: var(--text);
    line-height: 1.6;
    overflow-wrap: anywhere;   /* el enlace de la videollamada es larguisimo y desbordaba */
}

/* AW-178: los rotulos de los dias se partian en dos lineas.
 *
 * El PO lo vio en celular: DOM, LUN, MAR, JUE y SAB caian a dos lineas mientras MIE y VIE
 * no. El patron parece caprichoso hasta que se mira el ancho de las letras -- los dos que
 * sobreviven son los que llevan una "I", que es la letra mas estrecha del alfabeto. O sea
 * que la columna se queda a uno o dos pixeles de poder con tres mayusculas, y solo pasan
 * las palabras mas angostas. En ingles ocurre lo mismo y sobrevive FRI, por lo mismo.
 *
 * El plugin ya tiene previsto un tamano menor para cuando va apretado, pero lo condiciona a
 * un estado que en celular no se da (fcal_on_md + fcal_day_selected + is_active), asi que en
 * la practica el rotulo se queda en 14px.
 *
 * Se engancha en fcal_on_sm y fcal_on_xs, que son las clases que el propio widget se pone
 * segun SU ancho, no el de la ventana. Eso importa aqui: el widget vive en una columna de
 * /contacto/, asi que puede ir estrecho con la ventana ancha, y un media query no lo veria.
 *
 * El min-width: 0 no es decorativo. La celda es un elemento de rejilla, y esos traen
 * min-width: auto: con nowrap y sin esto, un rotulo que no quepa ensancharia su columna, y
 * con ella el calendario y la pagina. Es el mismo mecanismo que nos costo seis intentos en
 * la confirmacion (AW-174), asi que aqui se pone desde el principio. */
.fcal_calendar_inner.fcal_on_sm .calendar .day-name,
.fcal_calendar_inner.fcal_on_xs .calendar .day-name {
    font-size: 11px;
    white-space: nowrap;
    min-width: 0;
}

/* AW-178: el pie de "necesita hacer un cambio" se partia a mitad de frase.
 *
 * Salia "...Cancelar or Cambiar la" y "fecha" caia sola a la linea siguiente. El marcado del
 * plugin explica por que no hay forma de arreglarlo con un selector directo:
 *
 *     <div class="fcal_booking_manage fcal_normal_booking_footer">
 *       Need to make a change?     <- nodo de texto suelto, sin elemento
 *       <a>Cancel</a>
 *       or                         <- tambien suelto
 *       <a>Reschedule</a>
 *     </div>
 *
 * Ni la pregunta ni el "or" estan envueltos en nada, asi que no se pueden seleccionar. Todo
 * es un unico flujo de texto y el navegador lo parte donde le cabe, que es a mitad de
 * "Cambiar la fecha".
 *
 * La salida es convertir el contenedor en flex: en un contenedor flex cada tramo de texto
 * suelto se vuelve un elemento anonimo. Sin haber tocado el marcado, las cuatro piezas pasan
 * a ser cuatro cajas independientes, y ninguna se puede partir por dentro. Con wrap y
 * centrado, las que no caben bajan enteras a la linea siguiente y quedan centradas.
 *
 * El flex resolvio que no se cortaran frases, pero dejaba la ruptura donde cupiera: en
 * escritorio quedaba "Necesita hacer un cambio? Cancelar o" arriba y "Cambiar la fecha"
 * abajo. El PO pidio que bajen los dos enlaces juntos, y eso necesita una ruptura fija, no
 * una que dependa del ancho.
 *
 * Aqui el flex estorba: para forzar el salto hay que meter un elemento de ruptura, y el
 * unico gancho seleccionable es el primer enlace, cuyo ::before vive DENTRO de su caja. En
 * un contenedor flex eso partiria el enlace en dos lineas en vez de separarlo de la
 * pregunta. En flujo normal, en cambio, un ::before con un salto de linea literal rompe la
 * linea justo antes del enlace, que es exactamente donde hace falta.
 *
 * Por eso se vuelve a display block, y lo que el flex aportaba se consigue de otra forma:
 * el nowrap de los enlaces impide que "Cambiar la fecha" se parta por dentro. Si la segunda
 * linea no cupiera, rompe entre enlaces y nunca a mitad de uno.
 *
 * :first-of-type y no :first-child porque el primer hijo es un nodo de texto, y porque
 * cuando la reserva solo admite una de las dos acciones el plugin pinta un unico enlace:
 * asi la regla sigue valiendo. */
.fcal_normal_booking_footer {
    display: block;
    text-align: center;
}

.fcal_normal_booking_footer a {
    white-space: nowrap;
}

.fcal_normal_booking_footer a:first-of-type::before {
    content: "\A";
    white-space: pre;
}

/* AW-155: la seccion de la vertical destacada en la portada.
 *
 * El texto conserva su medida de lectura, porque un parrafo de 130 caracteres por linea no
 * se lee sino que se recorre, y la ilustracion se lleva el ancho completo debajo. Antes iba
 * al lado, en media columna y centrada frente a cuatro parrafos, y parecia una miniatura. */
/* AW-176: centrada como la seccion de Capacidades, que es la referencia que dio el PO.
 * Se centra el texto y tambien el boton. Antes solo se centraba el bloque y el texto quedaba
 * alineado a la izquierda dentro de el, que es lo que no le convencia. */
.aitss-vertical__texto {
    text-align: center;
}

.aitss-vertical__texto .wp-block-buttons {
    justify-content: center;
}

.aitss-vertical__texto > div {
  max-width: 68ch;
  /* AW-165: centrada, no pegada a la izquierda. El PO lo vio en produccion. Al apilar,
   * AW-155 dejo una columna de 68 caracteres contra el borde izquierdo y, justo debajo, la
   * ilustracion ocupando el ancho completo: quedaba un hueco grande a la derecha del texto
   * y la composicion no cerraba. Se centra el BLOQUE; el texto sigue alineado a la
   * izquierda dentro de el, que es lo que se lee bien. */
  margin-inline: auto;
}

.aitss-vertical__media {
  margin-top: var(--space-7);
}

.aitss-vertical__media img {
  display: block;
}
