/* ==========================================================================
   WorkE · Estilos de la maqueta
   --------------------------------------------------------------------------
   Consume exclusivamente las variables de tokens.css.
   Ningún color, tamaño ni espaciado se define aquí de forma literal.

   Breakpoints (coherentes con Astra):
     ≥ 922px  escritorio
     ≤ 921px  colapso a hamburguesa
     ≤ 544px  móvil
   ========================================================================== */

/* --- 1. Base -------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* El hueco de la barra de desplazamiento se reserva SIEMPRE, la haya o no.

   Sin esto, cada página se maqueta contra un ancho distinto según llegue o no
   al alto de la ventana. Medido en esta maqueta con la ventana a 1280 × 1300:
   index y precios se desplazan y reciben 1265px útiles; `acceso.html` mide
   1164px de alto, no se desplaza y recibe los 1280 completos. El resultado es
   que **la cabecera se desplaza 7px al entrar en Acceso y vuelve al salir**, y
   que la banda queda 15px más ancha alrededor de un contenido que no cambia,
   de modo que el menú parece encogerse.

   No es un defecto de la cabecera —su caja mide 1200 × 72 en las cuatro
   páginas— sino del ancho de la ventana, así que la corrección va aquí, en la
   raíz, y no en ningún componente.

   El coste es una franja vacía de 15px en las páginas que no se desplazan.
   Es el precio conocido de esta propiedad y compensa: un salto al cambiar de
   página se percibe siempre; una franja fija, nunca.

   Los navegadores que no la soportan la ignoran y se comportan como hasta hoy:
   se degrada sin romper nada. */
html {
  scrollbar-gutter: stable;

  /* Desplazamiento suave para los anclajes internos. Alta del 2026-08-03, al
     pasar el botón secundario del hero a llevar a `#demostracion`.

     NO CONTRADICE §4.8. Aquella regla prohíbe movimiento que ocurre SOLO
     —entradas, revelados, parallax—; esto es §3.6 aplicado: solo se mueve lo
     que reacciona a una acción del usuario, y aquí la acción es pulsar un
     enlace. Sin el recorrido, un salto instantáneo desde el hero hasta el pie
     de la página deja al lector sin saber si ha cambiado de página.

     Va en la raíz porque `scroll-behavior` es propiedad del CONTENEDOR que se
     desplaza, no del enlace: no se puede aplicar a un anclaje suelto.

     La contrapartida es que afecta también al enlace de salto, que en rigor
     preferiría un salto seco. Se acepta porque **el foco no se anima**: el
     usuario de teclado ya está en el destino cuando la animación empieza, y lo
     único que se mueve es la ventana.

     El respaldo ya estaba puesto: el bloque de movimiento reducido del final
     anula `scroll-behavior` desde la corrección del 2026-07-31, escrita
     entonces como «cierra la puerta antes de que se abra». Hoy se abre, y el
     guardián lleva dos días en su sitio. */
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--worke-font-base);
  font-size: var(--worke-font-size-body);
  line-height: var(--worke-line-height-body);
  color: var(--worke-color-text);
  background-color: var(--worke-color-surface);
  -webkit-font-smoothing: antialiased;
}

h1,
h2 {
  color: var(--worke-color-heading);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  margin: 0 0 var(--worke-space-md);
}

h1 { font-size: var(--worke-font-size-h1); }
h2 { font-size: var(--worke-font-size-h2); }

p { margin: 0 0 var(--worke-space-md); }

/* Foco visible en todo elemento interactivo. Requisito de accesibilidad:
   no se elimina nunca el indicador de foco, solo se sustituye. */
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--worke-color-focus);
  outline-offset: 2px;
  border-radius: var(--worke-radius-sm);
}

/* Enlace de salto: oculto hasta recibir foco con el teclado. */
.lab-skip-link {
  position: absolute;
  left: var(--worke-space-md);
  top: calc(var(--worke-space-md) * -4);
  z-index: 100;
  padding: var(--worke-space-sm) var(--worke-space-md);
  background-color: var(--worke-color-primary);
  color: var(--worke-color-surface);
  border-radius: var(--worke-radius-md);
  text-decoration: none;
  transition: top var(--worke-transition);
}

.lab-skip-link:focus {
  top: var(--worke-space-md);
}

.lab-container {
  width: 100%;
  max-width: var(--worke-container-width);
  margin-inline: auto;
  padding-inline: var(--worke-container-padding);
}

/* Texto solo para lectores de pantalla: presente en el árbol de accesibilidad
   pero invisible. Se usa cuando un elemento visual comunica algo que el
   marcado no dice —por ejemplo, unas estrellas de valoración—.
   Los valores de 1px no son decisiones de diseño sino la técnica estándar
   para ocultar sin sacar el elemento del árbol; `display: none` lo sacaría. */
.lab-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- 1.1 Marca ------------------------------------------------------------ */
/* Componente ÚNICO de identidad: isotipo + «WorkE». Lo usan la cabecera y el
   pie, así que sus estilos viven aquí una sola vez y no se duplican en cada
   región.

   El nombre es texto HTML, no parte de la imagen. Tres motivos: se mantiene
   nítido a cualquier resolución y densidad de píxel, es seleccionable y
   legible por un lector de pantalla, y cambiarlo no exige reexportar un
   archivo.

   Tamaño, peso y color son los de producción, donde Astra los aplica a
   `.site-title`: 26px, peso 600 y el color de títulos.

   Funciona como <a> en la cabecera y como elemento sin enlace en el pie: el
   de la cabecera ya lleva a la portada y repetir el destino no aporta nada a
   quien navega con teclado. La imagen va con `alt=""` porque el nombre ya está
   en el texto; con `alt="WorkE"` se anunciaría dos veces. */

.lab-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--worke-space-sm);
  margin: 0;
  flex-shrink: 0;
  text-decoration: none;
}

.lab-brand__mark {
  display: block;
  height: var(--worke-logo-height);
  width: auto;
}

.lab-brand__name {
  font-size: var(--worke-brand-font-size);
  font-weight: var(--worke-font-weight-heading);
  line-height: 1;
  color: var(--worke-color-heading);
  white-space: nowrap;
}

/* --- 2. Cabecera ---------------------------------------------------------- */

.lab-header {
  background-color: var(--worke-color-surface);
  border-bottom: 1px solid var(--worke-color-border);
  box-shadow: var(--worke-shadow-header);
  position: relative;
  z-index: 20;
}

/* Tres zonas: logotipo · navegación · CTA.

   Se usa rejilla y no flex a propósito. Con `1fr auto 1fr` las dos columnas
   laterales reparten el espacio sobrante a partes iguales, así que la columna
   central queda centrada respecto al CONTENEDOR, no respecto al hueco libre.
   El ancho del logotipo y el del botón dejan de influir en la posición del
   menú: si mañana el logotipo pasa a ser horizontal, el menú no se mueve.

   Con flex y `space-between` el menú se desplazaría cada vez que cambiase
   el ancho de cualquiera de los extremos. */
.lab-header__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--worke-space-lg);
  min-height: var(--worke-header-height);
}

/* La marca la aporta .lab-brand (§1.1). Aquí solo se la coloca en la rejilla:
   el componente no debe saber nada del contexto que lo aloja. */
.lab-header__brand {
  justify-self: start;   /* zona izquierda */
}

/* Navegación: zona central de la rejilla. */
.lab-nav {
  justify-self: center;
}

.lab-nav__list {
  display: flex;
  align-items: center;
  gap: var(--worke-space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

.lab-nav__link {
  display: inline-block;
  padding: var(--worke-space-sm) var(--worke-space-xs);
  font-size: var(--worke-font-size-nav);
  font-weight: var(--worke-font-weight-nav);
  color: var(--worke-color-heading);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color var(--worke-transition), border-color var(--worke-transition);
}

.lab-nav__link:hover {
  color: var(--worke-color-primary);
}

/* Página actual: marcada también con aria-current en el HTML. */
.lab-nav__link[aria-current="page"] {
  color: var(--worke-color-primary);
  border-bottom-color: var(--worke-color-primary);
}

/* --- 3. Acciones: CTA y hamburguesa --------------------------------------- */

.lab-header__actions {
  display: flex;
  align-items: center;
  gap: var(--worke-space-sm);
  flex-shrink: 0;
  justify-self: end;   /* zona derecha */
}

/* El CTA es un botón, no un elemento de la lista de navegación:
   vive fuera de <nav> y tiene tratamiento visual propio. */
.lab-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.625rem var(--worke-space-lg);
  background-color: var(--worke-color-primary);
  color: var(--worke-color-surface);
  font-size: var(--worke-font-size-nav);
  font-weight: var(--worke-font-weight-heading);
  /* SIN ESTA LÍNEA, EL MISMO COMPONENTE MIDE DISTINTO SEGÚN SU ETIQUETA. Un
     `a` hereda la altura de línea del cuerpo y un `button` usa el `normal` del
     navegador, así que un CTA enlace medía 48,4px y un CTA botón 40,5px.
     Se descubrió al poner un enlace y un botón idénticos en la sección de
     demostración, pero afectaba ya a los tres `button.lab-cta` del sitio
     frente a sus dieciocho enlaces: los descuadrados eran ellos. Se declara el
     valor del cuerpo, que es el que ya tenían los enlaces, así que las alturas
     que había en pantalla no cambian y los tres botones se ponen al día. */
  line-height: var(--worke-line-height-body);
  text-decoration: none;
  border: 1px solid var(--worke-color-primary);
  border-radius: var(--worke-radius-md);
  white-space: nowrap;
  transition: background-color var(--worke-transition), border-color var(--worke-transition);
}

.lab-cta:hover {
  background-color: var(--worke-color-primary-dark);
  border-color: var(--worke-color-primary-dark);
}

.lab-cta--secondary {
  background-color: transparent;
  color: var(--worke-color-primary);
}

.lab-cta--secondary:hover {
  background-color: var(--worke-color-primary-soft);
  border-color: var(--worke-color-primary-dark);
  color: var(--worke-color-primary-dark);
}

/* Botón hamburguesa: oculto en escritorio. */
.lab-burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;   /* área táctil mínima recomendada */
  height: 44px;
  padding: 0;
  background: none;
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-md);
  cursor: pointer;
  color: var(--worke-color-heading);
}

.lab-burger:hover {
  border-color: var(--worke-color-primary);
  color: var(--worke-color-primary);
}

.lab-burger__icon,
.lab-burger__icon::before,
.lab-burger__icon::after {
  display: block;
  width: 20px;
  height: 2px;
  background-color: currentColor;
  transition: transform var(--worke-transition), background-color var(--worke-transition);
}

.lab-burger__icon {
  position: relative;
}

.lab-burger__icon::before,
.lab-burger__icon::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
}

.lab-burger__icon::before { transform: translateY(-6px); }
.lab-burger__icon::after  { transform: translateY(6px); }

/* Estado abierto: las tres barras se convierten en aspa. */
.lab-burger[aria-expanded="true"] .lab-burger__icon {
  background-color: transparent;
}

.lab-burger[aria-expanded="true"] .lab-burger__icon::before {
  transform: translateY(0) rotate(45deg);
}

.lab-burger[aria-expanded="true"] .lab-burger__icon::after {
  transform: translateY(0) rotate(-45deg);
}

/* --- 4. Responsive: colapso a 921px --------------------------------------- */

@media (max-width: 921px) {
  /* Aquí la navegación sale del flujo, así que la rejilla de tres columnas
     ya no aplica: quedan dos zonas, logotipo y acciones. Se vuelve a flex
     con `space-between` para que el CTA siga pegado al borde derecho. */
  .lab-header__inner {
    display: flex;
    justify-content: space-between;
  }

  .lab-burger {
    display: inline-flex;
    position: relative;
  }

  /* La navegación pasa a ser un panel desplegable bajo la cabecera.
     El CTA permanece visible: es la acción principal del sitio. */
  .lab-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background-color: var(--worke-color-surface);
    border-bottom: 1px solid var(--worke-color-border);
    box-shadow: var(--worke-shadow-panel);
  }

  .lab-nav.is-open {
    display: block;
  }

  .lab-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    max-width: var(--worke-container-width);
    margin-inline: auto;
    padding: var(--worke-space-sm) var(--worke-container-padding) var(--worke-space-md);
  }

  .lab-nav__link {
    padding: var(--worke-space-md) 0;
    border-bottom: 1px solid var(--worke-color-border);
  }

  .lab-nav__item:last-child .lab-nav__link {
    border-bottom: none;
  }

  .lab-nav__link[aria-current="page"] {
    border-bottom-color: var(--worke-color-border);
  }
}

/* --- 5. Responsive: móvil 544px ------------------------------------------- */

@media (max-width: 544px) {
  :root {
    --worke-header-height: 64px;
    --worke-logo-height: 34px;
    --worke-container-padding: 1rem;
  }

  .lab-header__inner {
    gap: var(--worke-space-sm);
  }

  /* El relleno y el tamaño de letra menores dejaban el control en 42,75px de
     alto —8 + 8 de relleno, 24,75 de línea y 2 de borde—, por debajo de los
     44 × 44 que §4.9.5 exige a todo control con caja propia. Afectaba a los
     botones y enlaces de las cinco páginas en móvil, que es justo donde el
     objetivo es un dedo y no un puntero.

     Se corrige con `min-height` y NO con una altura fija ni tocando el
     relleno: el mínimo garantiza el área táctil sin impedir que el control
     crezca si su texto pasa a dos líneas, cosa que ocurre en cuanto se estrecha
     la pantalla. Una altura fija recortaría ese caso.

     No hace falta nada más para centrar el texto: `.lab-cta` ya es
     `inline-flex` con `align-items: center`, así que el alto que sobra se
     reparte solo. Y no toca escritorio, donde el control ya mide 48,4px.

     Los 44px van a pelo, como en `.lab-burger`: no son un valor de la escala
     de espaciado, son un requisito de accesibilidad. */
  .lab-cta {
    padding: 0.5rem var(--worke-space-md);
    min-height: 44px;
    font-size: var(--worke-font-size-small);
  }

  h1 { font-size: var(--worke-font-size-h2); }
}

/* --- 6. Contenido de la maqueta ------------------------------------------- */

.lab-main {
  padding-block: var(--worke-space-2xl);
}

.lab-note {
  max-width: 640px;
  padding: var(--worke-space-lg);
  background-color: var(--worke-color-surface-alt);
  border-left: 3px solid var(--worke-color-primary);
  border-radius: var(--worke-radius-md);
  font-size: var(--worke-font-size-small);
}

.lab-note p:last-child { margin-bottom: 0; }

/* --- 6.1 Hero ------------------------------------------------------------- */
/* Banda a todo el ancho con fondo alterno; el texto se limita al ancho de
   lectura para que la línea no se alargue en pantallas grandes. */

/* El relleno vertical se declara a través de una variable local para que exista
   UNA sola fuente de la que puedan leer tanto el propio relleno como quien
   necesite compensarlo —hoy el sangrado del recurso visual—. No es un token
   nuevo: es un alias de `--worke-space-2xl`, y por eso vive aquí y no en
   tokens.css. Sin ella, el sangrado tendría que repetir el valor y quedarían
   dos números que mantener sincronizados a mano. */
.lab-hero {
  --lab-hero-padding-y: var(--worke-space-2xl);
  padding-block: var(--lab-hero-padding-y);
  background-color: var(--worke-color-surface-alt);
  border-bottom: 1px solid var(--worke-color-border);
  text-align: center;
}

/* Variante compacta. Existe por un motivo estructural, no porque una página
   concreta se haya quedado larga: el hero de la portada es el ÚNICO del
   sistema con cinco bloques de contenido —eyebrow, título, texto, línea de
   precio y acciones— frente a los cuatro de los demás. Con el mismo padding,
   la misma regla produce dos alturas muy distintas, así que esta variante no
   crea la excepción: la compensa, y acerca los dos heroes al mismo rango.

   En el tramo móvil es inocua: allí `.lab-hero` ya vale `xl`.

   NO se usa para «ganar espacio» en un hero que se ha quedado largo por
   contenido. Si un hero de cuatro bloques resulta alto, sobra contenido.
   Ver D-37. */
.lab-hero--compacto {
  --lab-hero-padding-y: var(--worke-space-xl);
}

/* El párrafo acerca su margen inferior un escalón, de `xl` a `lg`, SOLO cuando
   el hero lleva línea de precio. Con 32px el precio abría un bloque nuevo;
   con 24px se lee como lo que es: la conclusión del mensaje que acaba de
   leerse, no un dato suelto.

   Debajo del precio se mantiene `xl`, así que la asimetría —24 arriba, 32
   abajo— es deliberada y es el mecanismo: agrupa el precio con lo que lo
   justifica y lo separa de los botones, que son otra cosa. §4.4.2.

   Va acotada al modificador porque `.lab-hero__text` lo comparten los tres
   heroes, y en los que no llevan precio ese margen separa el párrafo de las
   acciones, donde `xl` sí es la distancia correcta. */
.lab-hero--compacto .lab-hero__text {
  margin-bottom: var(--worke-space-lg);
}


.lab-hero__inner {
  max-width: var(--worke-measure);
  margin-inline: auto;
}

/* La etiqueta superior es la misma pieza en el hero y en las secciones.
   Se agrupan los selectores en lugar de duplicar las declaraciones.

   SOBRE `line-height`, QUE AFECTA A LOS DOS SELECTORES: el eyebrow de sección
   se usa sobre `span` y también sobre `h2` —en «Por qué WorkE» es el título
   real de la sección, C-16—. Todo lo que la regla de elemento `h1, h2`
   declararía —tamaño, color, peso y margen— lo gana esta clase por
   especificidad, así que las dos etiquetas se ven idénticas. La excepción era
   `line-height`: sin declararlo, un `h2` heredaba el 1,3 de encabezado en vez
   del 1,65 del cuerpo y cambiaba la altura de la caja.
   Al estar agrupada, la declaración alcanza también a `.lab-hero__eyebrow`,
   y ahí NO cambia nada: ese eyebrow es un `span` que ya heredaba 1,65 del
   cuerpo, así que se le está fijando el valor que tenía. Comprobado midiendo
   el hero completo contra el commit 89cdb2e en nueve anchos: cero
   diferencias. */
.lab-hero__eyebrow,
.lab-section__eyebrow {
  display: block;
  margin-bottom: var(--worke-space-sm);
  font-size: var(--worke-font-size-small);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-body);
  letter-spacing: var(--worke-letter-spacing-eyebrow);
  text-transform: uppercase;
  color: var(--worke-color-primary);
}

/* `text-wrap: balance` reparte las palabras entre las líneas en lugar de dejar
   una última línea con una o dos. Es una mejora progresiva: los navegadores que
   no la reconocen la ignoran y el titular se ve exactamente como antes. */
.lab-hero__title {
  margin-bottom: var(--worke-space-md);
  text-wrap: balance;
}

.lab-hero__text {
  margin-bottom: var(--worke-space-xl);
}

/* Línea de precio. Da al mayor argumento comercial un momento visual propio,
   que dentro del párrafo no tenía: allí la cifra era la cuarta línea de un
   bloque de 16px y competía con la enumeración de funciones.

   NO es el panel .lab-price: aquí no hay caja —ni fondo, ni borde, ni radio,
   ni relleno—, porque el hero es exclusivamente tipográfico y una caja lo
   partiría en dos. Esta línea ENUNCIA el precio; el panel lo DESARROLLA.

   La cifra va a h2 y no a h1: a 36px empataría con el título de la página y
   con la cifra del panel de precio, y el escalón máximo dejaría de señalar
   nada (D-33). A h2 queda un escalón completo por debajo del título, que es
   la distancia que hace que se lea como el segundo elemento del hero y no
   como un segundo título. Empata con los h2 de sección, y es aceptable: no
   coinciden nunca en pantalla. Ver D-34.

   Arriba y abajo, `xl` a los dos lados. La simetría es lo que la convierte en
   el centro del bloque: con menos espacio debajo se leía como una etiqueta de
   los botones en lugar de como la afirmación que es. El de arriba lo aporta
   `.lab-hero__text`; este es el de abajo. */
.lab-hero__price {
  margin-bottom: var(--worke-space-xl);
}

.lab-hero__figure {
  display: block;
  font-size: var(--worke-font-size-h2);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-heading);
}

/* Tres frases cortas en lugar de una enumeración con separadores: cada hecho
   es una unidad de escaneo independiente. El peso y el color los hereda, así
   que no se declaran.
   `text-wrap: balance` evita que la tercera frase quede huérfana al plegarse,
   igual que en el título. Mejora progresiva: quien no la reconoce, la ignora. */
.lab-hero__scope {
  display: block;
  margin-top: var(--worke-space-sm);
  font-size: var(--worke-font-size-small);
  text-wrap: balance;
}

/* Franja de tranquilidad. Tres hechos que desactivan tres objeciones de compra
   por encima del pliegue: permanencia, tiempo de puesta en marcha y límite de
   plantilla. Va entre el párrafo y los botones porque es lo último que se lee
   antes de decidir si se pulsa.
   Indicadores pequeños y en azul, del mismo tamaño que el de la lista de
   valores: marcan pertenencia, no jerarquía. */
.lab-hero__garantias {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--worke-space-md) var(--worke-space-lg);
  margin: 0 0 var(--worke-space-xl);
  padding: 0;
  list-style: none;
  font-size: var(--worke-font-size-small);
}

.lab-hero__garantia {
  display: inline-flex;
  align-items: center;
  gap: var(--worke-space-xs);
}

.lab-hero__garantia svg {
  flex-shrink: 0;
  width: var(--worke-marker-size);
  height: var(--worke-marker-size);
  color: var(--worke-color-primary);
}

.lab-hero__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--worke-space-md);
}

/* Variante con recurso visual en columna. PROVISIONAL: el bloque 1 de la
   portada está reabierto para validarla, y no se cierra hasta la revisión.

   LA REGLA QUE GOBIERNA TODO EL BLOQUE: el Hero conserva su altura natural
   —la que le da el texto— y el recurso se adapta a ella. Nunca al revés. Es la
   referencia medida sobre worke.es: banda de 409px con la pieza vertical
   ocupándola de borde a borde.

   Cómo se impide que el recurso imponga la altura, en tres tiempos:

     1. La fila se dimensiona con lo único que aporta altura en flujo: el
        mensaje. El recurso vive en posición absoluta dentro de la ranura, y un
        elemento fuera de flujo no contribuye al tamaño intrínseco de su
        contenedor. La ranura, sin contenido en flujo, aporta CERO.
     2. Con la fila ya dimensionada, la ranura recibe un área de altura
        definida y su `height` resuelve contra ella.
     3. `aspect-ratio` con `width: auto` deriva el ancho a partir de esa altura.

   EL SANGRADO SE HACE MOVIENDO EL RELLENO, NO COMPENSÁNDOLO. El Hero cede su
   `padding-block` a la columna de texto, que conserva así exactamente su
   espaciado actual. La fila pasa a medir la banda completa —contenido más los
   dos rellenos— y la ranura la ocupa entera con un `height: 100%` limpio.

   Se probó antes la vía aparentemente obvia, `height: calc(100% + relleno*2)`,
   y **realimenta la fila**: la altura de la ranura entra en el cálculo del que
   depende, el navegador resuelve el bucle en un punto fijo arbitrario y salen
   472px de recurso en una banda de 410. Medido. Mover el relleno elimina la
   realimentación en lugar de compensarla.

   Sin el sangrado, el recurso quedaría limitado a los 345px del contenido y
   saldría un 40 % más estrecho que en la referencia.

   El valor se lee de `--lab-hero-padding-y`, así que no hay ningún número
   repetido: si el relleno cambia, esto se ajusta solo. */
.lab-hero--visual {
  padding-block: 0;
  text-align: left;
}

/* La primera columna vale exactamente la medida de lectura, no `1fr`.
   La diferencia no es cosmética: con `1fr` la columna se quedaba TODO el
   espacio sobrante y el texto flotaba a su izquierda limitado por su propio
   `max-width`, de modo que el hueco real entre el texto y el vídeo era el resto
   vacío de la columna MÁS el `gap`. Tocar el `gap` no acercaba nada: la columna
   crecía otro tanto y se lo tragaba.
   Con la pista medida, el sobrante sale fuera de la rejilla —lo reparte
   `justify-content: center`— y el `gap` sí es la distancia que se ve. */
.lab-hero--visual .lab-hero__inner {
  max-width: none;
  display: grid;
  grid-template-columns: minmax(0, var(--worke-measure)) auto;
  gap: var(--worke-space-xl);
  align-items: center;
  justify-content: center;
}

/* Recibe el relleno que cede el Hero: el texto mantiene su espaciado intacto y
   la fila crece hasta la altura de la banda.
   La medida de lectura se declara aquí de forma explícita y no se deja al azar
   del reparto de la rejilla: es §3.3 y no un efecto colateral. */
.lab-hero--visual .lab-hero__mensaje {
  padding-block: var(--lab-hero-padding-y);
  max-width: var(--worke-measure);
}

.lab-hero--visual .lab-hero__actions {
  justify-content: flex-start;
}

/* La ranura: geometría, nada más. El `100%` resuelve contra el área de rejilla
   —que ya vale la banda completa— y `width: auto` deja que la proporción
   calcule el ancho.

   Se le restan `sm` por lado para que el recurso no toque los bordes de la
   banda. Ese aire no altera nada más: la altura del Hero la sigue fijando la
   columna de texto, y el ancho se recalcula solo a partir de la nueva altura,
   sin tocarlo a mano.

   Aquí el `calc` sí es seguro, al contrario que el `calc(100% + …)` que se
   probó antes: aquel hacía la ranura MAYOR que su área y realimentaba el
   cálculo de la fila; este la hace menor, así que no puede empujar nada. */
.lab-hero--visual .lab-hero__visual {
  position: relative;
  align-self: center;
  width: auto;
  height: calc(100% - var(--worke-space-sm) * 2);
}

/* El recurso, fuera de flujo: es lo que impide que aporte altura intrínseca.
   Con `inset: 0` recibe ancho y alto definidos, así que su propia
   `aspect-ratio` queda inerte y no compite con la de la ranura. */
.lab-hero--visual .lab-hero__visual > .lab-visual {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Por debajo del breakpoint oficial el recurso se retira y el hero vuelve a ser
   exactamente el centrado de siempre.

   El motivo está medido: con dos columnas, por debajo de ~700px el texto deja
   de caber en la altura que la fila reserva y desborda hasta 305px. Entre 700 y
   921 la composición sí funciona, pero conservarla ahí exigiría un umbral en
   700px que no es ninguno de los tres tramos del sistema (§4.9.1). Se prefiere
   perder ese rango antes que introducir un breakpoint propio sin aprobación.

   Se retira con `display: none` y no ocultándolo visualmente: el recurso no
   aporta información que el texto no dé, así que no hay nada que anunciar a un
   lector de pantalla. */
@media (max-width: 921px) {
  /* El relleno vuelve al Hero, que es donde vive en todas las demás páginas. */
  .lab-hero--visual {
    padding-block: var(--lab-hero-padding-y);
    text-align: center;
  }

  .lab-hero--visual .lab-hero__inner {
    display: block;
    max-width: var(--worke-measure);
    margin-inline: auto;
  }

  .lab-hero--visual .lab-hero__mensaje {
    padding-block: 0;
    max-width: none;
  }

  .lab-hero--visual .lab-hero__actions {
    justify-content: center;
  }

  .lab-hero--visual .lab-hero__visual {
    display: none;
  }
}

@media (max-width: 544px) {
  /* Se reasigna la variable, no la propiedad: así el sangrado del recurso
     visual sigue leyendo el mismo valor que el relleno. Ver §4.9.3. */
  .lab-hero {
    --lab-hero-padding-y: var(--worke-space-xl);
  }

  /* Un titular de doce palabras a tamaño de h2 ocupa demasiadas líneas en una
     pantalla estrecha. Se baja un escalón de la escala —a tamaño de h3— y el
     bloque se lee de un vistazo sin tocar el texto. Sigue por encima de h4,
     así que la jerarquía con el resto de la página se mantiene. */
  .lab-hero__title {
    font-size: var(--worke-font-size-h3);
  }

  /* En este tramo el título baja dos escalones, de h1 a h3, así que la cifra
     baja otros dos, de h2 a h4: la distancia entre ambos se conserva. Dejarla
     en h2 la pondría por encima del título de la página. Ver B-07. */
  .lab-hero__figure {
    font-size: var(--worke-font-size-h4);
  }

  /* En móvil los botones se apilan a todo el ancho: son el objetivo
     principal del hero y en una sola columna resultan más alcanzables.
     El hueco sube un escalón: apilados y a todo el ancho, con 16px se leían
     como un único bloque en lugar de como dos acciones distintas. */
  .lab-hero__actions {
    flex-direction: column;
    gap: var(--worke-space-lg);
  }

  .lab-hero__actions .lab-cta {
    width: 100%;
  }
}

/* --- 6.2 Secciones de contenido ------------------------------------------- */

.lab-section {
  padding-block: var(--worke-space-2xl);
}

/* Encabezado de sección: etiqueta, título e introducción, centrados y
   limitados al ancho de lectura. */
.lab-section__header {
  max-width: var(--worke-measure);
  margin-inline: auto;
  margin-bottom: var(--worke-space-2xl);
  text-align: center;
}

.lab-section__title {
  margin-bottom: var(--worke-space-md);
}

.lab-section__intro {
  margin-bottom: 0;
}

/* Enlace de cierre de sección. Envía a la página que desarrolla lo que la
   sección acaba de resumir; es lo que permite a la portada dirigir en lugar
   de agotar. Es navegación y no acción, así que va como enlace y no como
   botón: no consume cupo de llamadas a la acción del bloque. */
.lab-section__more {
  margin: var(--worke-space-xl) 0 0;
  text-align: center;
}

/* El enlace toma caja propia. Un enlace `inline` dibuja su anillo de foco sobre
   una caja dimensionada con SU tipografía —15px, 20px de alto—, y no con la de
   sus hijos: en opiniones, donde el enlace envuelve la valoración a 24px, la
   cifra desbordaba el anillo 8px por arriba y las descendentes lo rozaban por
   abajo. Medido en Chrome: caja del enlace 20px, contenido 32px.
   `inline-block` le da una caja que envuelve todo su contenido, y de paso el
   anillo deja de partirse en dos rectángulos sueltos cuando el enlace ocupa dos
   líneas, por debajo de 414px.
   Va en el enlace de cierre y no en `.lab-link`, que es global: el resto de
   enlaces del sistema no contienen nada mayor que ellos mismos. Los otros tres
   cierres de sección no cambian —una sola línea, sin hijos grandes—, pero
   heredan el anillo continuo si algún día parten. */
.lab-section__more .lab-link {
  display: inline-block;
}

/* --- 6.3 Cuadrícula de tarjetas ------------------------------------------- */
/* 3 columnas en escritorio, 2 en tablet, 1 en móvil. */

.lab-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--worke-space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (max-width: 921px) {
  .lab-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 544px) {
  .lab-grid {
    grid-template-columns: 1fr;
  }
}

/* Tarjeta informativa. No es clicable y no tiene estado de interacción:
   sin hover, sin foco, sin transiciones. */
.lab-card {
  padding: var(--worke-space-lg);
  background-color: var(--worke-color-surface);
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-lg);
}

.lab-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--worke-icon-box);
  height: var(--worke-icon-box);
  margin-bottom: var(--worke-space-md);
  color: var(--worke-color-primary);
  background-color: var(--worke-color-primary-soft);
  border-radius: var(--worke-radius-md);
}

.lab-card__icon svg {
  width: var(--worke-icon-size);
  height: var(--worke-icon-size);
}

.lab-card__title {
  margin: 0 0 var(--worke-space-sm);
  font-size: var(--worke-font-size-h4);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-heading);
}

.lab-card__text {
  margin-bottom: 0;
}

/* --- 6.4 Sección partida en dos columnas ---------------------------------- */
/* Se diferencia de la cuadrícula anterior por tres vías: fondo alterno,
   encabezado alineado a la izquierda en lugar de centrado, y valores sin
   caja —ni borde ni fondo—, apoyados solo en un indicador y el espaciado. */

.lab-section--alt {
  background-color: var(--worke-color-surface-alt);
  border-block: 1px solid var(--worke-color-border);
}

/* --- 6.2.1 Banda de oferta ------------------------------------------------ */
/* Franja bajo el hero con su propia superficie: `--worke-color-surface-accent`,
   el gemelo claro de `primary-deep`. Es el ÚNICO consumidor de ese token.

   EL FONDO PROPIO ES LO QUE HACE QUE NO HAGA FALTA NINGUNA EXCEPCIÓN. Con un
   tercer color, el ritmo queda hero(alt) → oferta(accent) → por qué(blanco) →
   qué incluye(alt) → …, y no hay dos fondos iguales seguidos: §4.2.4 se cumple
   sin más. La versión anterior compartía el fondo del hero y necesitaba una
   excepción expresa; D-69 recoge por qué dejó de hacer falta.

   Sigue apoyada en `.lab-section--alt` para heredar sus bordes, y solo
   reasigna el fondo: así la separación con el hero y con la sección siguiente
   la siguen dando las mismas líneas de 1px de todo el sistema. */

/* El hero ya trae `border-bottom`, así que el borde superior de `--alt`
   dibujaría una segunda línea pegada a la primera.

   EL RELLENO DE LA BANDA ES MENOR QUE EL DE LA TARJETA, Y ESA ES LA REGLA:
   son dos anillos de espacio, uno dentro del otro, y si miden lo mismo el ojo
   no tiene forma de decidir cuál manda. Un empate se lee como espacio
   sobrante aunque ninguno de los dos valores sea grande.
   `md` frente a los `xl` de la tarjeta: ratio 0,50. La banda es una FRANJA de
   transición entre el hero y el primer bloque, no una sección de contenido
   —esas usan `2xl`—, y por eso puede ir muy por debajo de ellas.
   ⚠ NO BAJAR A `sm`: el margen exterior quedaría en la mitad de la separación
   interna menor de la tarjeta y esta empezaría a desbordar su banda. */
.lab-oferta {
  background-color: var(--worke-color-surface-accent);
  border-top: 0;
  padding-block: var(--worke-space-md);
}

/* El encabezado de sección separa de su contenido con `2xl`. Aquí no hay
   contenido debajo: el encabezado ES la banda. */
.lab-oferta .lab-section__header {
  margin-bottom: 0;
}

/* La tarjeta. Relleno blanco, SIN borde y SIN sombra sobre el fondo de acento.

   ES LA INVERSIÓN EXACTA DE `.lab-review`, documentada como «panel de relleno
   gris SIN borde, sobre sección blanca»: misma lógica, signo contrario. El
   panel se define por contraste de relleno y no por un borde, y contraste hay
   de sobra —blanco sobre el acento da ΔE 16,3, cuando las secciones de la
   página se separan entre sí a 4,8—.

   NO LLEVA BORDE A PROPÓSITO, y no es cosmética: blanco + borde de 1px + radio
   `lg` + centrado a la medida de lectura es EXACTAMENTE `.lab-price--invertido`,
   que vive en la sección 5 de esta misma página. Con borde serían la misma
   composición dos veces, que es lo que impide §3.4.1. Se probó y se descartó.

   SIN SOMBRA: §4.6.2 la prohíbe en paneles en flujo, y el motivo que da
   —«una tarjeta con sombra sugiere que se puede pulsar»— alcanza de lleno a
   esta, que no lleva a ninguna parte.

   EL ANCHO ESTÁ DERIVADO, NO ELEGIDO: medida de lectura más los dos rellenos
   HORIZONTALES. Así la caja de contenido mide exactamente `--worke-measure` y
   el texto conserva su medida íntegra mientras la tarjeta gana presencia. El
   `calc` y el relleno horizontal son el mismo valor a propósito: si se cambia
   uno hay que cambiar el otro, y por eso no son dos números sueltos.
   ⚠ El `calc` va con el segundo valor del `padding`, no con el primero.

   EL RELLENO ES ASIMÉTRICO, Y ESA ES LA DECISIÓN: `2xl` en horizontal porque
   lo impone la medida de lectura, `xl` en vertical porque es lo que la caja
   necesita para abrazar el contenido. El criterio es la separación interna
   mayor de la tarjeta —el margen inferior del titular, `md`—: un relleno de
   contenedor tiene que leerse como marco y no como un hueco más, así que se
   fija en el DOBLE de esa separación. A `lg` bajaría a 1,5 veces y empezaría a
   competir con el ritmo interno; a `md` lo igualaría y la tarjeta dejaría de
   enmarcar. Medido: con `2xl` el relleno era el 27 % de la altura del
   contenido a cada lado, con `xl` es el 18 %.
   Este valor tiene que quedar POR ENCIMA del `padding-block` de la banda: son
   dos anillos concéntricos y el interior manda. Ver el comentario de
   `.lab-oferta`. */
.lab-oferta__panel {
  max-width: calc(var(--worke-measure) + var(--worke-space-2xl) * 2);
  margin-inline: auto;
  padding: var(--worke-space-xl) var(--worke-space-2xl);
  background-color: var(--worke-color-surface);
  border-radius: var(--worke-radius-lg);
}

/* Sobre este fondo el azul primario da 3,84:1 y no llega al 4,5:1 que exige un
   texto de 15px en negrita. `primary-dark` da 4,85:1. No es una preferencia de
   tono: es el mínimo de contraste. */
.lab-oferta .lab-section__eyebrow {
  color: var(--worke-color-primary-dark);
}

/* Pesa más que un título de sección sin subir de tamaño: el escalón de 36px es
   el del `h1` del hero, a media pantalla de aquí, y empatar con él invertiría
   la jerarquía en lugar de reforzarla (D-33, y el criterio de la 1.2.2 —«un
   escalón completo por debajo del título, nunca empatada con él»—). */
.lab-oferta .lab-section__title {
  font-weight: var(--worke-font-weight-strong);
}

/* Un escalón por encima del cuerpo. Es la mitad del refuerzo de jerarquía que
   el titular no puede dar por tamaño. */
.lab-oferta .lab-section__intro {
  font-size: var(--worke-font-size-h5);
}

/* El asterisco es un enlace y hereda de `.lab-link` el tamaño `small`, que
   junto a un `h2` lo dejaría minúsculo. Vuelve al tamaño de su título y sube
   como llamada, que es como se compone una llamada a nota.
   Mismo motivo de contraste que el eyebrow: `primary` no llega sobre este
   fondo. El hover lo sigue anunciando el subrayado (D-43), así que no hace
   falta un segundo color.
   VA ANIDADA BAJO `.lab-oferta` A PROPÓSITO: `.lab-link` declara su color más
   abajo en este archivo y, a igual especificidad, ganaba por orden. Medido:
   con la regla suelta el asterisco se quedaba en `primary`, 3,84:1. */
.lab-oferta .lab-oferta__nota {
  font-size: 0.6em;
  vertical-align: super;
  margin-left: 0.1em;
  color: var(--worke-color-primary-dark);
}

/* En móvil el titular del hero baja a `h3` (24px), pero un `h2` no lo reduce
   ninguna regla global: la banda se quedaba con un titular de 30px sobre un
   hero de 24px, es decir, el mensaje promocional por encima del titular de la
   página. Baja a `h4` para quedar un escalón por debajo, y el párrafo vuelve
   al cuerpo. Con esto la banda ENCOGE en móvil en lugar de crecer. */
@media (max-width: 544px) {
  /* Baja a `md` y no se queda en `lg` por la misma razón que en escritorio: en
     móvil la tarjeta lleva `lg`, así que dejar la banda en `lg` empataría los
     dos anillos y reproduciría el problema. Con `md` el ratio queda en 0,67,
     equivalente al 0,75 de escritorio. */
  .lab-oferta {
    padding-block: var(--worke-space-md);
  }

  /* El relleno horizontal de escritorio dejaría el texto en una columna
     demasiado estrecha en un móvil de 320px: 48px por lado se comen un tercio
     del ancho útil. Baja a `lg` y el ancho deja de estar limitado por el
     `max-width`, que a estos anchos ya no llega a aplicarse.
     AQUÍ SÍ ES SIMÉTRICO, y no es un olvido: `lg` ya son 1,5 veces la
     separación interna mayor, que es el suelo por debajo del cual la tarjeta
     deja de enmarcar. En una caja de 382px de ancho, 24px pesan mucho más de
     lo que pesaban 48px en una de 768px. */
  .lab-oferta__panel {
    padding: var(--worke-space-lg);
  }

  .lab-oferta .lab-section__title {
    font-size: var(--worke-font-size-h4);
  }

  .lab-oferta .lab-section__intro {
    font-size: var(--worke-font-size-body);
  }
}

.lab-split {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: var(--worke-space-2xl);
  align-items: start;
}

.lab-split__intro p:last-child {
  margin-bottom: 0;
}

/* Columna en flexible vertical para poder ceder a la imagen —y solo a ella— el
   espacio que sobre al final. El texto no se ve afectado: todos los hijos
   nacen con `margin-top: 0`, así que aquí no había colapso de márgenes que
   perder al cambiar de flujo. */
.lab-split__intro {
  display: flex;
  flex-direction: column;
  align-self: stretch;
}

/* Imagen de la columna izquierda, en el lugar del párrafo descriptivo.

   La imagen se adapta al bloque, nunca al revés. `flex: 1 1 0` la deja sin
   altura propia: no pide sitio, ocupa el que sobra bajo el título. Su
   aportación a la altura mínima de la columna es CERO —de ahí el
   `min-height: 0`—, así que la altura de la sección la sigue fijando la lista
   de la derecha y el bloque no crece ni un píxel por alojarla.

   `aspect-ratio: auto` anula la proporción que los atributos `width`/`height`
   del HTML le imponen; `object-fit: cover` recorta el original cuadrado a la
   franja que le toque, sea cual sea.

   Sin marco y sin sombra, a diferencia de las capturas de interfaz: el marco
   existe para fundir un fondo blanco con el de la sección, y una fotografía no
   lo necesita (§5.25). La sombra está reservada a activos de producto (§4.6.2)
   y esto no lo es. */
.lab-split__imagen {
  display: block;
  width: 100%;
  flex: 1 1 0;
  min-height: 0;
  margin-top: var(--worke-space-xl);
  aspect-ratio: auto;
  object-fit: cover;
  /* El encuadre se sube: centrado, la banda empezaba a la altura de los ojos y
     cortaba la coronilla. Al 20% arranca justo por encima del pelo y llega por
     debajo del móvil — con la caja alineada a la lista hay alto suficiente para
     los dos, cosa que no ocurría cuando la imagen solo recibía el sobrante. */
  object-position: center 20%;
  border-radius: var(--worke-radius-lg);
}

/* Variante alineada: el eyebrow se sube a una fila propia y la imagen y la lista
   comparten la segunda, así que las dos empiezan a la misma altura.

   Se hace con filas de rejilla y no con un margen superior sobre la lista: un
   valor en píxeles habría que recalcularlo cada vez que el eyebrow cambiara de
   tamaño o de número de líneas. Con la fila, la alineación es exacta siempre.

   Y tiene un efecto que no es secundario: al compartir fila, la imagen mide lo
   que mide la lista, no lo que le sobra bajo el eyebrow. Deja de ser un residuo
   y pasa a tener la misma altura que su columna vecina, que es lo que permite
   que quepan la cabeza y el móvil enteros.

   Es un modificador y no un cambio de `.lab-split` porque la portada usa el
   componente dos veces: aquí y en la sección de demostración. */
.lab-split--desfasado {
  grid-template-rows: auto auto;
  row-gap: var(--worke-space-xl);
}

.lab-split--desfasado > .lab-section__eyebrow {
  grid-column: 1;
  grid-row: 1;
  /* La separación la da ahora el hueco entre filas, que afecta por igual a las
     dos columnas. Mantener además el margen propio del eyebrow desalinearía la
     izquierda respecto a la derecha justo en los 8px que este margen vale. */
  margin-bottom: 0;
}

.lab-split--desfasado > .lab-split__intro {
  grid-column: 1;
  grid-row: 2;
}

.lab-split--desfasado > .lab-values {
  grid-column: 2;
  grid-row: 2;
}

/* La imagen ya no necesita separarse del eyebrow: de eso se encarga el hueco
   entre filas. Con el margen puesto, arrancaría 32px por debajo de la lista. */
.lab-split--desfasado .lab-split__imagen {
  margin-top: 0;
}

.lab-values {
  display: grid;
  gap: var(--worke-space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

.lab-value {
  display: flex;
  align-items: flex-start;
  gap: var(--worke-space-md);
}

/* Indicador circular, más pequeño que el icono de las tarjetas para que
   la jerarquía entre ambas secciones quede clara.
   Lo comparte el bloque de precio (§6.8): en ambos casos marca pertenencia a
   una lista y es idéntico en todos los elementos, así que se agrupan los
   selectores en lugar de duplicar las declaraciones. */
.lab-value__marker,
.lab-price__marker {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--worke-marker-box);
  height: var(--worke-marker-box);
  color: var(--worke-color-primary);
  background-color: var(--worke-color-primary-soft);
  border-radius: 50%;
}

.lab-value__marker svg,
.lab-price__marker svg {
  width: var(--worke-marker-size);
  height: var(--worke-marker-size);
}

.lab-value__title {
  margin: 0 0 var(--worke-space-xs);
  font-size: var(--worke-font-size-h5);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-heading);
}

.lab-value__text {
  margin-bottom: 0;
}

@media (max-width: 921px) {
  .lab-split {
    grid-template-columns: 1fr;
    gap: var(--worke-space-xl);
  }

  /* En una sola columna la imagen quedaría entre el eyebrow y los valores,
     separándolos. Y el hueco que venía a rellenar ya no existe, porque los dos
     bloques van apilados: sin partición no sobra altura. */
  .lab-split__imagen {
    display: none;
  }

  /* Sin dos columnas no hay nada que alinear: los bloques se apilan en el orden
     del DOM. Hay que anular la colocación explícita o la lista seguiría
     buscando una columna 2 que aquí ya no existe. */
  .lab-split--desfasado {
    grid-template-rows: none;
  }

  .lab-split--desfasado > .lab-section__eyebrow,
  .lab-split--desfasado > .lab-split__intro,
  .lab-split--desfasado > .lab-values {
    grid-column: 1;
    grid-row: auto;
  }
}

/* --- 6.5 Proceso por pasos ------------------------------------------------ */
/* Tercera variante de composición: secuencia horizontal con numerales
   sólidos y línea de conexión. Ni tarjeta con borde ni lista con indicador. */

.lab-steps {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--worke-space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

.lab-step {
  position: relative;
  text-align: center;
}

/* Bloque, no elemento en línea: así su borde superior coincide con el del
   elemento de lista y la línea de conexión se puede centrar con exactitud. */
.lab-step__number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--worke-step-box);
  height: var(--worke-step-box);
  margin-inline: auto;
  margin-bottom: var(--worke-space-md);
  font-size: var(--worke-font-size-h4);
  font-weight: var(--worke-font-weight-heading);
  line-height: 1;
  color: var(--worke-color-surface);
  background-color: var(--worke-color-primary);
  border-radius: 50%;
}

.lab-step__title {
  margin: 0 0 var(--worke-space-sm);
  font-size: var(--worke-font-size-h5);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-heading);
}

.lab-step__text {
  margin-bottom: 0;
  font-size: var(--worke-font-size-small);
}

/* Línea de conexión, solo en escritorio.
   Va de borde a borde entre dos numerales consecutivos: arranca tras el
   círculo propio y termina antes del siguiente. La distancia entre centros
   es el ancho de la columna más el hueco de la rejilla.
   Es un pseudoelemento con contenido vacío, así que no llega al lector
   de pantalla y no necesita aria-hidden. */
@media (min-width: 922px) {
  .lab-step:not(:last-child)::after {
    content: "";
    position: absolute;
    top: calc(var(--worke-step-box) / 2);
    left: calc(50% + var(--worke-step-box) / 2 + var(--worke-space-sm));
    width: calc(100% + var(--worke-space-lg) - var(--worke-step-box) - var(--worke-space-sm) * 2);
    height: 1px;
    background-color: var(--worke-color-border);
  }
}

/* En tablet y móvil, una sola columna y sin línea: en vertical estorbaría
   más de lo que aporta. */
@media (max-width: 921px) {
  .lab-steps {
    grid-template-columns: 1fr;
    gap: var(--worke-space-xl);
  }
}

/* --- 6.6 Preguntas frecuentes --------------------------------------------- */
/* Cuarta variante: un único panel continuo con separadores, en lugar de
   piezas sueltas. Ni tarjetas, ni lista suelta, ni secuencia numerada. */

.lab-faq {
  max-width: var(--worke-measure);
  margin: 0 auto;
  padding: 0;
  list-style: none;
  background-color: var(--worke-color-surface);
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-lg);
}

.lab-faq__item + .lab-faq__item {
  border-top: 1px solid var(--worke-color-border);
}

/* El encabezado solo aporta jerarquía; los estilos van en el botón. */
.lab-faq__heading {
  margin: 0;
  font-size: inherit;
}

.lab-faq__button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--worke-space-md);
  width: 100%;
  padding: var(--worke-space-md) var(--worke-space-lg);
  background: none;
  border: none;
  font-family: inherit;
  font-size: var(--worke-font-size-h5);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-heading);
  text-align: left;
  cursor: pointer;
}

.lab-faq__button:hover {
  color: var(--worke-color-primary);
}

/* El contorno de foco se dibuja hacia dentro: el botón ocupa todo el ancho
   del panel y por fuera quedaría cortado por el borde redondeado. */
.lab-faq__button:focus-visible {
  outline-offset: -2px;
}

/* Indicador de apertura. Único movimiento de la sección: un giro breve,
   que la regla de movimiento reducido del final del archivo neutraliza. */
.lab-faq__icon {
  flex-shrink: 0;
  width: var(--worke-marker-size);
  height: var(--worke-marker-size);
  color: var(--worke-color-primary);
  transition: transform var(--worke-transition);
}

.lab-faq__button[aria-expanded="true"] .lab-faq__icon {
  transform: rotate(180deg);
}

.lab-faq__panel {
  padding: 0 var(--worke-space-lg) var(--worke-space-md);
}

.lab-faq__panel[hidden] {
  display: none;
}

.lab-faq__panel p {
  margin-bottom: 0;
}

/* --- 6.7 Cierre de página -------------------------------------------------- */
/* Banda sólida en la variante profunda del azul de marca. Es la única
   sección con el color invertido, de modo que funciona como cierre y no
   como una repetición del hero.
   Se usa el azul profundo y no el primario porque una superficie completa
   al 96 % de saturación fatiga la vista; apagado y oscurecido mantiene la
   identidad y gana contraste.
   Blanco sobre este fondo: 10,2:1 — supera AAA para texto normal. */

.lab-cta-final {
  background-color: var(--worke-color-primary-deep);
  text-align: center;
}

.lab-cta-final__inner {
  max-width: var(--worke-measure);
  margin-inline: auto;
}

.lab-cta-final__title {
  margin-bottom: var(--worke-space-md);
  font-size: var(--worke-font-size-h2);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-surface);
}

.lab-cta-final__text {
  margin-bottom: var(--worke-space-xl);
  color: var(--worke-color-surface);
}

.lab-cta-final__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--worke-space-md);
}

/* El contorno de foco global es azul y aquí quedaría invisible sobre el
   fondo. Se invierte a blanco para que siga siendo perceptible. */
.lab-cta-final a:focus-visible {
  outline-color: var(--worke-color-surface);
}

/* Acción principal invertida: relleno blanco y texto azul. Mismo par de
   colores, mismo contraste de 5,2:1, jerarquía intacta. */
.lab-cta--invert {
  background-color: var(--worke-color-surface);
  border-color: var(--worke-color-surface);
  color: var(--worke-color-primary);
}

.lab-cta--invert:hover {
  background-color: var(--worke-color-surface-alt);
  border-color: var(--worke-color-surface-alt);
  color: var(--worke-color-primary-dark);
}

/* Salida secundaria de la banda oscura. Enlace de texto, sin botón y sin caja:
   a una fracción del peso de la acción principal, para que no se evalúe como
   alternativa equivalente. Es el mismo criterio que separa la contratación de
   la demostración en la portada. */
.lab-cta-final__alt {
  margin: var(--worke-space-lg) 0 0;
  font-size: var(--worke-font-size-small);
  color: var(--worke-color-surface);
}

.lab-cta-final__alt a {
  color: var(--worke-color-surface);
  text-decoration: underline;
}

/* Mismo criterio que en el hero: apilados y a todo el ancho, el hueco sube un
   escalón para que se lean como dos acciones y no como un bloque. */
@media (max-width: 544px) {
  .lab-cta-final__actions {
    flex-direction: column;
    gap: var(--worke-space-lg);
  }

  .lab-cta-final__actions .lab-cta {
    width: 100%;
  }
}

/* --- 6.8 Bloque de precio ------------------------------------------------- */
/* Quinta variante de composición: un panel único, destacado por relleno y no
   por sombra ni por color de marca.
   LA BASE VUELVE A SER GRIS SOBRE SECCIÓN BLANCA, que es lo que §5.21
   especifica desde su alta. El blanco sobre alterna fue la desviación que
   introdujo la portada al insertarse las opiniones, y quedó registrada como
   parte de C-08 —«.lab-price rellena hoy en blanco, la inversión de lo que
   dice §5.21»—.

   El motivo de devolverla: en /precios/ la sección pasó a fondo blanco al
   insertarse la sección visual, y con el panel también en blanco el punto de
   decisión de la página se quedaba sin contraste, delatado solo por su borde
   de 1px. La regla que manda es la del componente: el panel se destaca por su
   relleno, y el relleno tiene que diferir del fondo que lo aloja.

   Quien lo necesite al revés lo pide con `--invertido`. Ver D-53. */

.lab-price {
  max-width: var(--worke-measure);
  margin-inline: auto;
  padding: var(--worke-space-xl);
  background-color: var(--worke-color-surface-alt);
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-lg);
  text-align: center;
}

/* Variante invertida: relleno blanco, para cuando el panel vive sobre una
   sección de fondo alterno. Es el caso de la portada, donde el ritmo de fondos
   obliga a que su sección de precio sea alterna.
   La relación de contraste entre panel y fondo se conserva en las dos
   variantes; solo cambia de signo. */
.lab-price--invertido {
  background-color: var(--worke-color-surface);
}

/* Variante ancha, para cuando el panel aloja la enumeración completa de lo
   que cubre la tarifa en lugar de un resumen de cuatro puntos.
   La medida de lectura no aplica aquí: no es prosa, es una lista de doce
   elementos cortos a dos columnas, y a 42rem quedaría en una columna de doce
   filas que se lee como un formulario. */
.lab-price--ancho {
  max-width: var(--worke-container-width);
}

/* Dos columnas. La extensión de la lista es el argumento —«¿todo esto por
   50 €?»— y a dos columnas se abarca de un vistazo en lugar de recorrerse. */
.lab-price__list--dos {
  grid-template-columns: 1fr 1fr;
  column-gap: var(--worke-space-2xl);
}

@media (max-width: 921px) {
  .lab-price__list--dos {
    grid-template-columns: 1fr;
  }
}

/* La cifra reutiliza el tamaño de h1 en lugar de introducir uno nuevo: la
   escala tipográfica es cerrada y 36px sobre un panel ya domina la sección.
   En el HTML va completa en un único nodo de texto —«50 € al año + IVA»—:
   partirla en varios elementos haría que el lector de pantalla anunciase el
   importe, el periodo y el impuesto desconectados entre sí. */
.lab-price__figure {
  margin: 0 0 var(--worke-space-xs);
  font-size: var(--worke-font-size-h1);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-heading);
}

/* El precio nunca aparece sin su alcance: por empresa y hasta 249
   trabajadores. Un importe sin alcance es un dato incompleto. */
.lab-price__scope {
  margin-bottom: var(--worke-space-xl);
  font-size: var(--worke-font-size-small);
}

/* La lista se alinea a la izquierda aunque el panel esté centrado: una
   enumeración centrada obliga a buscar el inicio de cada línea. */
.lab-price__list {
  display: grid;
  gap: var(--worke-space-md);
  margin: 0 0 var(--worke-space-xl);
  padding: 0;
  list-style: none;
  text-align: left;
}

.lab-price__item {
  display: flex;
  align-items: flex-start;
  gap: var(--worke-space-md);
}

/* El indicador se define junto al de la lista de valores, en §6.4. */

.lab-price__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--worke-space-md);
}

/* En tablet el panel ya se estrecha, pero conservaba el relleno de escritorio
   y el hueco bajo la acción resultaba excesivo. Se baja un escalón el relleno
   del panel y la separación entre la lista y el botón. */
@media (max-width: 921px) {
  .lab-price {
    padding: var(--worke-space-lg);
  }

  .lab-price__list {
    margin-bottom: var(--worke-space-lg);
  }
}

@media (max-width: 544px) {
  .lab-price__actions {
    flex-direction: column;
  }

  .lab-price__actions .lab-cta {
    width: 100%;
  }
}

/* --- 6.9 Opiniones de clientes -------------------------------------------- */
/* Sexta variante de composición: panel de relleno gris SIN borde, sobre
   sección blanca. Es la inversión exacta de la tarjeta de funcionalidades
   —blanca, con borde, sobre sección alterna—, de modo que las dos secciones
   no se confunden aunque compartan la geometría de rejilla.
   Ni icono, ni titular: una reseña se sostiene sobre la cita y su firma. */

.lab-reviews {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--worke-space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (max-width: 921px) {
  .lab-reviews {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 544px) {
  .lab-reviews {
    grid-template-columns: 1fr;
  }
}

/* Columna flexible para que la firma quede alineada al pie en las tres
   tarjetas: las reseñas tienen longitudes muy distintas. */
.lab-review {
  display: flex;
  flex-direction: column;
  padding: var(--worke-space-lg);
  background-color: var(--worke-color-surface-alt);
  border-radius: var(--worke-radius-lg);
}

/* Las estrellas son decorativas: la valoración la comunica el texto oculto
   que las acompaña en el HTML. Altura tomada del token de indicador. */
/* El 1,3 no es un valor suelto: es el refuerzo del 30 % pedido, expresado
   sobre el token de indicador para que siga atado a la escala. */
.lab-review__stars {
  display: block;
  height: calc(var(--worke-marker-size) * 1.3);
  width: auto;
  margin-bottom: var(--worke-space-md);
  color: var(--worke-color-star);
}

/* `blockquote` trae márgenes propios del navegador; se anulan. */
.lab-review__quote {
  flex-grow: 1;
  margin: 0 0 var(--worke-space-md);
  font-size: var(--worke-font-size-small);
}

.lab-review__quote p {
  margin: 0;
}

/* `cite` viene en cursiva por defecto. */
.lab-review__author {
  font-style: normal;
  font-size: var(--worke-font-size-small);
}

.lab-review__name {
  display: block;
  font-weight: var(--worke-font-weight-heading);
  color: var(--worke-color-heading);
}

.lab-review__source {
  display: block;
}

/* Jerarquía del pie de sección: la valoración es el dato, «Ver todas nuestras
   reseñas» es la acción. Ambos siguen dentro del mismo enlace —el bloque
   entero es pulsable— pero la valoración sube a tamaño de h4, toma el peso de
   título y el color de texto oscuro, mientras la acción se queda en el tamaño
   y el azul de enlace que ya trae `.lab-link`.
   La diferencia la hacen tres cosas a la vez —tamaño, peso y color—, no el
   tamaño solo: así el contraste entre dato y acción se lee de inmediato. */
.lab-reviews__score {
  font-size: var(--worke-font-size-h3);
  font-weight: var(--worke-font-weight-heading);
  color: var(--worke-color-heading);
}

/* --- 6.10 Sección de demostración ----------------------------------------- */
/* NO es el cierre de contratación: ese termina en el bloque de precio.
   Su única misión es ayudar a conocer el producto a quien todavía no quiere
   contratar, así que no menciona precio, garantías, pago ni contratación.
   Dos columnas: a la izquierda el valor en pocas palabras, a la derecha la
   acción. Reutiliza la composición partida de «Por qué WorkE» (.lab-split),
   así que no introduce una rejilla nueva.
   Mucho aire y poco texto: la sección debe facilitar el siguiente paso, no
   volver a vender. */

.lab-demo {
  text-align: left;   /* la banda centra; esta sección tiene dos columnas */
}

/* Sube un paso en la escala, de cuerpo (16px) a h5 (18px). Entre esos dos
   valores no hay nada, así que no se inventa uno intermedio.
   El salto respecto a la frase de cierre —15px con opacidad reducida— se
   ensancha, de modo que la jerarquía entre texto principal y mensaje de
   tranquilidad queda más marcada, no menos. */
.lab-demo__text {
  margin: 0 0 var(--worke-space-md);
  font-size: var(--worke-font-size-h5);
  color: var(--worke-color-surface);
}

.lab-demo__aside {
  margin: 0;
  font-size: var(--worke-font-size-small);
  color: var(--worke-color-surface);
  opacity: 0.8;
}

/* Superficie clara para el formulario: un campo sobre azul profundo no se lee
   como editable. Relleno generoso a propósito —el aire es lo que separa una
   tarjeta limpia de un formulario comercial. */
.lab-demo__form {
  padding: var(--worke-space-xl);
  background-color: var(--worke-color-surface);
  border-radius: var(--worke-radius-lg);
  color: var(--worke-color-text);
}

/* El contorno de foco de la banda es blanco y sobre la tarjeta clara sería
   invisible: dentro vuelve al azul del sistema. */
.lab-demo__form a:focus-visible,
.lab-demo__form button:focus-visible,
.lab-demo__form input:focus,
.lab-demo__form select:focus {
  outline-color: var(--worke-color-focus);
}

/* El titular de esta sección NO lleva tamaño propio: se queda en el h2 de
   `.lab-cta-final__title`, que es lo que semánticamente es. Tuvo el tamaño de
   h1 para equilibrarlo con la densidad del formulario, y eso dejaba tres
   elementos compartiendo el escalón máximo de la página —h1, cifra del precio
   y este—, con el agravante de que el más destacado era el de la salida
   secundaria. Si al verlo la columna izquierda queda floja, la solución es más
   aire o menos campos, nunca devolverle el tamaño del h1. Ver D-33. */

/* Dos campos por fila: reduce la altura de la tarjeta a la mitad en los
   cuatro campos de contacto. */
.lab-demo__row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--worke-space-md);
}

@media (max-width: 544px) {
  .lab-demo__row {
    grid-template-columns: 1fr;
  }
}

/* Grupo de opciones. `fieldset` trae borde, relleno y márgenes propios del
   navegador; se anulan porque el agrupamiento aquí lo comunica la pregunta del
   `legend`, no una caja. */
.lab-demo__opciones {
  margin: 0;
  padding: 0;
  border: 0;
  display: grid;
  gap: var(--worke-space-sm);
}

.lab-demo__opciones .lab-field__label {
  margin-bottom: var(--worke-space-xs);
}

/* LOS CAMPOS SE PLIEGAN CON `grid-template-rows`, de `0fr` a `1fr`.
   Es la única forma de animar una altura desconocida sin inventarse un
   `max-height` que habría que recalcular cada vez que cambie el contenido.
   El hijo necesita `min-height: 0` o la fila no puede encogerse por debajo de
   su tamaño intrínseco y el plegado no ocurre.

   `visibility` NO ES DECORATIVA: `overflow: hidden` esconde los campos del ojo
   pero los dejaría en el árbol de accesibilidad y en el orden de tabulación,
   de modo que un usuario de teclado tabularía a campos invisibles. Con
   `visibility: hidden` desaparecen de los dos. Se transiciona con retardo
   —`0s` de duración, la duración del sistema de retardo— para que el cambio
   ocurra AL TERMINAR el plegado y no al empezarlo; al desplegar el retardo es
   cero y aparecen de inmediato.

   El movimiento es una transición de estado disparada por el usuario, que es
   lo único que §4.8 admite, y `prefers-reduced-motion` la neutraliza con el
   resto (§4.8.2). */
.lab-demo__campos {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  visibility: hidden;
  transition: grid-template-rows var(--worke-transition),
    opacity var(--worke-transition),
    visibility 0s var(--worke-transition);
}

.lab-demo__campos-inner {
  display: grid;
  gap: var(--worke-space-md);
  min-height: 0;
  overflow: hidden;
}

.lab-demo[data-lab-demo-modo="llamada"] .lab-demo__campos {
  grid-template-rows: 1fr;
  opacity: 1;
  visibility: visible;
  transition: grid-template-rows var(--worke-transition),
    opacity var(--worke-transition),
    visibility 0s;
}

/* El botón se separa de lo que tenga encima, sea el grupo de opciones cuando
   los campos están plegados o el último campo cuando están desplegados. */
.lab-demo__campos + .lab-cta {
  margin-top: var(--worke-space-md);
}

/* Campo de selección. Mismo tratamiento que .lab-field__input para que no
   parezca un control ajeno al sistema. */
.lab-field__select {
  width: 100%;
  padding: var(--worke-control-padding-y) var(--worke-control-padding-x);
  font-family: inherit;
  font-size: var(--worke-font-size-body);
  line-height: 1.4;
  color: var(--worke-color-text);
  background-color: var(--worke-color-surface);
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-md);
}

/* --- 6.11 Espacio visual --------------------------------------------------- */
/* Reserva el espacio EXACTO que ocupará un recurso visual definitivo —imagen o
   vídeo— y muestra mientras tanto un marcador inequívocamente provisional.

   Metodología de activos provisionales (§5.25): mientras no existan los
   recursos definitivos, todo espacio visual previsto se maqueta así. No sirve
   para representar la interfaz —eso sigue prohibido— sino para validar
   composición, jerarquía, ritmo y responsive sin esperar al material.

   COMPONENTE GENERAL, SIN PÁGINA ASIGNADA. Hoy no tiene ningún consumidor en
   las maquetas: existe documentado y listo para el primer espacio visual que se
   apruebe. Ver §5.25 y D-40.

   LA CAJA Y EL CONTENIDO ESTÁN SEPARADOS A PROPÓSITO. `.lab-visual` guarda solo
   la geometría —ancho y proporción—; el aspecto lo aporta el hijo. Así el
   marcador puede llevar borde discontinuo y el activo borde continuo sin que la
   caja se entere, y sustituir uno por otro no toca ninguna regla de layout. Es
   la condición de sustituibilidad, hecha estructura.

   Y es lo que permite que la misma caja aloje una imagen o un vídeo: los tres
   hijos posibles —marcador, `<img>` y `<video>`— rellenan el 100 % de la caja,
   así que el layout no distingue entre ellos ni necesita saber cuál hay dentro.

   Las proporciones son literales deliberados, igual que el `5fr 7fr` de
   `.lab-split`: describen el activo que se reserva, no un valor de la escala.
   Registradas en §9.3.

   SOLO LABORATORIO. Ningún marcador puede llegar a producción: §13.3, punto 14,
   bloqueante. */

.lab-visual {
  width: 100%;
  aspect-ratio: 16 / 9;
}

/* 16:9 es la proporción por defecto porque es la de la mayoría de capturas de
   interfaz. Un espacio sin proporción declarada colapsaría a cero, así que la
   base siempre lleva una: los modificadores cambian el valor, no lo introducen.
   Se da de alta un modificador cuando aparece un activo que lo necesita, no
   antes: §0.11 —lo que no está, no existe todavía—. */

/* Proporción vertical, la del vídeo de producto de la portada: 1054 × 1874 px,
   es decir 1 : 1,778. Se escribe con las dos cifras del archivo y no con una
   aproximación redonda para que la caja reserve el hueco EXACTO y el activo no
   sufra recorte al insertarse.

   Nació valiendo 1054 / 2130 y cambió al publicarse el activo real: la grabación
   traía la barra del navegador móvil dentro de la imagen y se recortaron 256px
   del pie. La proporción se lee DEL ARCHIVO y se revisa cuando el archivo
   cambia (§5.25).

   La ranura del hero comparte la declaración en lugar de repetir el valor: es
   quien deriva el ancho a partir de la altura de la banda, así que necesita la
   misma proporción. Un solo sitio que mantener (G-05). */
.lab-visual--vertical,
.lab-hero__visual {
  aspect-ratio: 1054 / 1874;
}

/* Proporción apaisada, la del panel de empresa de /precios/: 1545 × 549 px.
   Se escribe con las dos cifras del archivo y no con una aproximación redonda
   para que la caja reserve el hueco EXACTO.
   A ancho de contenedor da unos 395px de alto: baja y ancha, que es lo que
   hace que se lea como un fragmento de interfaz y no como una captura de
   pantalla completa. */
.lab-visual--apaisado {
  aspect-ratio: 1545 / 549;
}

/* El borde discontinuo es la señal de «esto no es definitivo». Es el único
   borde discontinuo del sistema, y esa exclusividad es lo que lo hace legible
   de un vistazo. */
.lab-visual__aviso {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--worke-space-sm);
  width: 100%;
  height: 100%;
  margin: 0;
  padding: var(--worke-space-lg);
  background-color: var(--worke-color-surface);
  border: 1px dashed var(--worke-color-border);
  border-radius: var(--worke-radius-lg);
  text-align: center;
}

.lab-visual__icono {
  width: var(--worke-icon-size);
  height: var(--worke-icon-size);
  color: var(--worke-color-primary);
}

.lab-visual__rotulo {
  font-size: var(--worke-font-size-small);
  font-weight: var(--worke-font-weight-heading);
  color: var(--worke-color-heading);
}

.lab-visual__detalle {
  font-size: var(--worke-font-size-small);
}

/* Estilos del activo definitivo, imagen o vídeo. Todavía sin consumidor: se
   dejan escritos para que sustituir el marcador sea cambiar el hijo y nada más.
   Se agrupan los selectores en lugar de duplicar las declaraciones, igual que
   en `.lab-hero__eyebrow, .lab-section__eyebrow`: los dos activos ocupan la
   caja de la misma forma y compartirlas garantiza que se vean idénticos.
   `object-fit: cover` recorta por el contenedor si la proporción entregada no
   coincide con la prevista, de modo que un activo ligeramente distinto no
   descuadra la composición. Sin sombra: no flota sobre el contenido (§4.6.2). */
.lab-visual__img,
.lab-visual__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-lg);
}

/* Modificador de activo de producto. La sombra se PIDE, no se hereda: va aquí
   y no en `.lab-visual__img` a secas porque `.lab-visual` es un espacio visual
   general y podría alojar algún día una imagen que no sea de producto.

   Se aplica solo a los hijos definitivos, así que EL MARCADOR PROVISIONAL NO
   LA LLEVA. La diferencia es deliberada: refuerza de un vistazo que lo
   provisional no es lo final.

   El borde de 1px se mantiene. La sombra separa del fondo; el borde delimita,
   y sigue haciéndolo en modo de contraste forzado, donde la sombra desaparece.

   NO EXTENDER a tarjetas, botones, formularios, paneles de contenido ni al
   bloque de precio. La restricción está escrita en §4.6.2, en la ficha §5.25 y
   en D-52; si aparece la petición de «un poco de sombra» en otro sitio, la
   respuesta ya está dada y es que no. */
.lab-visual--producto .lab-visual__img,
.lab-visual--producto .lab-visual__video {
  box-shadow: var(--worke-shadow-visual);
}

/* MARCO. Resuelve dos problemas a la vez y por eso es el tratamiento por
   defecto de cualquier captura de interfaz:

   1. Una captura de la aplicación tiene FONDO BLANCO, y la sección donde vive
      es `surface-alt`. Pegada a hueso, el borde entre los dos blancos es un
      corte seco que delata que ahí hay una imagen pegada. Con el marco, el
      blanco del activo y el blanco del marco se funden en una sola pieza y lo
      que separa del fondo es el conjunto, no la imagen.

   2. `object-fit: cover` recorta si la proporción entregada no coincide con la
      prevista, y en una captura de interfaz eso significa perder pestañas o
      columnas por los bordes. Dentro del marco se pasa a `contain`: la imagen
      NUNCA se recorta, y si sobra un poco de alto queda como aire interior del
      marco, que se lee como intencionado.

   La sombra se traslada al marco: es el conjunto lo que flota, no la captura.
   El borde de la imagen desaparece —lo aporta ya el marco— y el radio interior
   baja un escalón, que es la progresión de §4.6.1: a menor pieza, menor radio. */
.lab-visual--marco {
  padding: var(--worke-space-lg);
  background-color: var(--worke-color-surface);
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-lg);
}

.lab-visual--marco .lab-visual__img,
.lab-visual--marco .lab-visual__video {
  object-fit: contain;
  border: none;
  border-radius: var(--worke-radius-md);
  box-shadow: none;
}

.lab-visual--producto.lab-visual--marco {
  box-shadow: var(--worke-shadow-visual);
}

/* El marcador provisional dentro del marco pierde su fondo y su borde
   redondeado: el marco ya los aporta y dos cajas concéntricas se ven como un
   error. Conserva el trazo discontinuo, que es lo que lo declara provisional. */
.lab-visual--marco .lab-visual__aviso {
  background-color: transparent;
  border-radius: var(--worke-radius-md);
}

@media (max-width: 544px) {
  /* El relleno del marco baja un escalón: en pantalla estrecha, 24px a cada
     lado se comen el ancho útil de la captura. */
  .lab-visual--marco {
    padding: var(--worke-space-sm);
  }
}

/* --- 6.12 Situaciones ------------------------------------------------------ */
/* Séptima variante de composición: parejas emparejadas en dos columnas, sin
   caja y separadas solo por filetes. Se distingue de la cuadrícula porque no
   hay borde ni icono ni fondo; de la lista de valores porque no hay indicador
   y la unidad es una PAREJA, no un elemento; de los pasos porque no hay
   numeral ni línea; de la FAQ porque nada se despliega.

   PRINCIPIO DEL COMPONENTE: la columna izquierda nombra una tarea de gestión
   en infinitivo y dice lo que no debería costar. Ni un caso con personajes, ni
   un procedimiento interno, ni un requisito funcional. Ver §5.26 y D-50.

   La jerarquía entre las dos mitades se hace con PESO Y COLOR, nunca con
   opacidad: rebajarla bajaría el contraste de un texto que hay que leer.
   Las dos van al mismo tamaño de cuerpo, y ahora también al mismo peso de
   contenido: entre 8 y 11 palabras por lado. El bloque ya no dice «problema
   complejo / solución simple», dice «esto te suena / esto hace WorkE». */

/* El bloque no ocupa los 1200px del contenedor: se limita a una vez y media la
   medida de lectura y se centra. Con parejas de 8 a 11 palabras, cada mitad
   entra en una o dos líneas y el conjunto queda compacto.

   El valor va como cálculo sobre `--worke-measure` y no como literal, con el
   mismo criterio que `.lab-review__stars`: atado a la escala. Sigue sin ser un
   token, y está anotado como tal en §9.3. */
.lab-situaciones {
  max-width: calc(var(--worke-measure) * 1.5);
  margin-inline: auto;
}

/* Rótulos de columna. Toman del eyebrow la caja alta y el espaciado entre
   letras —es lo que los hace leerse como etiqueta y no como contenido— pero
   NO su color ni su peso: en azul y a 600 competían con el eyebrow de la
   sección, que está tres líneas más arriba, y el bloque abría con dos rótulos
   destacados en lugar de con uno.
   El azul marca lo accionable y lo destacado (§4.2.2), y una etiqueta de
   columna no es ninguna de las dos cosas: solo orienta.
   Se ocultan al lector de pantalla: cada pareja lleva su propio rótulo, y sin
   `aria-hidden` se anunciarían dos veces. */
.lab-situaciones__rotulos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--worke-space-xl);
  margin: 0 0 var(--worke-space-sm);
}

/* CAJA COMPARTIDA · la regla que hace que las dos columnas se comporten igual.
   Rótulo y texto tienen el mismo ancho y el mismo centrado, así que sus bordes
   izquierdos caen sobre la misma vertical. Una sola declaración para los tres
   selectores: si estuviera repetida, los valores acabarían divergiendo.

   `width: 100%` NO es redundante con `max-width`, y quitarlo reintroduce el
   defecto: en una rejilla, un elemento con `margin-inline: auto` deja de
   estirarse y pasa a dimensionarse a su CONTENIDO, porque los márgenes
   automáticos absorben el espacio libre y anulan el estirado por defecto. Sin
   `width: 100%`, una respuesta corta produce una caja estrecha y su borde
   izquierdo se desplaza hacia el centro; con él, las cinco parejas miden lo
   mismo y arrancan en la misma vertical, diga lo que diga cada frase.

   Se probó centrar los rótulos dentro de la columna y se descartó: el rótulo
   quedaba en el centro y el texto empezaba a la izquierda, sin nada que los
   relacionara, y en la columna derecha —donde el texto ocupa menos— el desfase
   saltaba a la vista. La simetría tiene que venir de la estructura, no de que
   los dos lados midan lo mismo por casualidad. */
.lab-situaciones__rotulos span,
.lab-situacion__hoy,
.lab-situacion__worke {
  width: 100%;
  max-width: calc(var(--worke-measure) * 0.6);
  margin-inline: auto;
}

.lab-situaciones__rotulos span {
  display: block;
  font-size: var(--worke-font-size-small);
  font-weight: var(--worke-font-weight-nav);
  letter-spacing: var(--worke-letter-spacing-eyebrow);
  text-transform: uppercase;
  color: var(--worke-color-text);
}

.lab-situaciones__lista {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--worke-color-border);
}

/* Cada pareja es la unidad. El filete va abajo y el borde superior lo aporta
   la lista, de modo que la primera y la última quedan cerradas sin reglas
   especiales para los extremos. */
.lab-situacion {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--worke-space-xl);
  align-items: start;
  padding-block: var(--worke-space-lg);
  border-bottom: 1px solid var(--worke-color-border);
}

/* El ancho y el centrado los aporta la regla de caja compartida de arriba.
   Aquí solo se anula el margen vertical del párrafo: se mueve la caja, nunca
   el renglón, que sigue alineado a la izquierda. */
.lab-situacion__hoy,
.lab-situacion__worke {
  margin-block: 0;
}

.lab-situacion__worke {
  font-weight: var(--worke-font-weight-heading);
  color: var(--worke-color-heading);
}

/* Rótulo por pareja. Es el nombre accesible de cada mitad y en escritorio está
   oculto —los rótulos de columna ya orientan—, con la misma técnica que
   `.lab-sr-only`: fuera de la vista pero dentro del árbol de accesibilidad.
   Por debajo de 545px se hace visible, porque al apilarse las columnas
   desaparecen y con ellas la única referencia de qué es cada mitad. */
.lab-situacion__rotulo {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 544px) {
  /* Los rótulos de columna dejan de tener sentido sin columnas. */
  .lab-situaciones__rotulos {
    display: none;
  }

  .lab-situacion {
    grid-template-columns: 1fr;
    gap: var(--worke-space-sm);
  }

  /* El mismo elemento que arriba era solo para lector de pantalla pasa a ser
     visible: se restituyen todas las propiedades que lo ocultaban. */
  .lab-situacion__rotulo {
    position: static;
    display: block;
    width: auto;
    height: auto;
    margin: 0 0 var(--worke-space-xs);
    overflow: visible;
    clip-path: none;
    white-space: normal;
    font-size: var(--worke-font-size-small);
    font-weight: var(--worke-font-weight-nav);
    letter-spacing: var(--worke-letter-spacing-eyebrow);
    text-transform: uppercase;
    color: var(--worke-color-text);
  }
}

/* --- 6.13 Invariables del precio ------------------------------------------ */
/* Octava composición: tres ejes que podrían mover el precio y no lo mueven,
   con la MISMA cifra debajo de cada uno.

   La repetición es el argumento. No hay que explicar que el precio no escala:
   se ve. Por eso las tres cifras son idénticas y por eso no hay párrafo que
   las comente.

   ⚠ EL RIESGO DE ESTA COMPOSICIÓN, y hay que tenerlo presente al tocarla:
   tres columnas con precios es VISUALMENTE la rejilla de planes que D-14 y
   D-27 prohíben. Lo único que la separa de ella es que no hay nada que elegir.
   De ahí las cuatro prohibiciones: ni caja por columna, ni borde por columna,
   ni botón por columna, ni columna destacada. En cuanto aparezca cualquiera de
   las cuatro, esto deja de ser una demostración y pasa a ser un selector de
   planes. Ver D-54.

   Sin caja también por otro motivo: la sección vecina es el panel de precio,
   que sí la tiene. Dos bloques con caja seguidos se confundirían (§3.4). */

.lab-invariables {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--worke-space-2xl);
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: center;
}

/* La imagen de producto que sigue a los tres ejes, desde que «El producto» dejó
   de ser sección propia (2026-08-02). Se separa con el mismo hueco que el
   encabezado deja sobre su composición —`2xl`— y no con el de un bloque
   accesorio —`xl`, el de `.lab-section__more` o `.lab-valoracion`—, porque no
   es un apéndice de los ejes: es el segundo argumento de la sección.

   Selector de hermano adyacente y no clase nueva: la regla describe una
   RELACIÓN entre dos bloques, no una propiedad del componente visual, que se
   usa igual en otras páginas sin este margen. */
.lab-invariables + .lab-visual {
  margin-top: var(--worke-space-2xl);
}

/* El eje toma el aspecto del eyebrow: es la misma clase de etiqueta. */
.lab-invariable__eje {
  display: block;
  margin-bottom: var(--worke-space-sm);
  font-size: var(--worke-font-size-small);
  font-weight: var(--worke-font-weight-heading);
  letter-spacing: var(--worke-letter-spacing-eyebrow);
  text-transform: uppercase;
  color: var(--worke-color-primary);
}

/* El rango ocupa el escalón que tenía la cifra —h3— porque al retirarse esta
   se quedó como único contenido de la columna. Por debajo del h1 de la página:
   aquí no se compite, se ilustra. */
.lab-invariable__rango {
  margin: 0;
  font-size: var(--worke-font-size-h3);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-heading);
}

/* En tablet siguen cabiendo tres columnas: el texto más largo es la cifra y
   entra de sobra. En móvil se apilan, y apiladas la repetición se lee incluso
   mejor: tres veces el mismo importe, una debajo de otra. */
@media (max-width: 544px) {
  .lab-invariables {
    grid-template-columns: 1fr;
    gap: var(--worke-space-xl);
  }
}

/* Valoración con estrellas. Las estrellas van encima y centradas, a la altura
   que ya usa el bloque de reseñas de la portada: son la misma pieza y deben
   verse igual en las dos páginas.
   Decorativas: la valoración la comunica el texto alternativo que las
   acompaña, para que el lector de pantalla no intente leer cinco formas sin
   significado. */
.lab-valoracion {
  margin: var(--worke-space-xl) 0 0;
  text-align: center;
}

.lab-valoracion .lab-review__stars {
  margin-inline: auto;
  margin-bottom: var(--worke-space-sm);
}

/* --- 6.14 Bloque de compromiso --------------------------------------------- */
/* Novena composición: un bloque centrado a medida de lectura, sin caja, sin
   indicadores y sin columnas. Su forma es deliberadamente la más simple de la
   página, porque lo que dice no necesita apoyo visual: es una declaración.

   Se distingue de las demás por ausencia. La sección anterior es un panel con
   caja y doce elementos; esta es texto centrado y nada más. Ese contraste es
   lo que la hace leerse como una toma de posición y no como más argumentario.

   La primera frase sube un escalón —de cuerpo a h5— para que el compromiso se
   lea antes que su desarrollo. Entre 16px y 18px no hay nada en la escala, así
   que no se inventa un valor intermedio. */

.lab-compromiso {
  max-width: var(--worke-measure);
  margin-inline: auto;
  text-align: center;
}

.lab-compromiso__clave {
  margin: 0 0 var(--worke-space-md);
  font-size: var(--worke-font-size-h5);
  color: var(--worke-color-heading);
}

.lab-compromiso__texto {
  margin: 0 0 var(--worke-space-md);
}

.lab-compromiso__texto:last-child {
  margin-bottom: 0;
}

/* --- 6.15 Centro de actualidad -------------------------------------------- */
/* Composición del blog. Es la primera del sistema pensada para contenido que
   el diseño NO controla: crece, se ordena por fecha y su cantidad es
   desconocida. Todo lo demás en esta web tiene un número fijo de elementos
   elegidos uno a uno.
   De ahí que ninguna regla dependa de cuántos artículos haya: con tres o con
   treinta, la composición no cambia ni deja huecos. */

/* Cabecera editorial. Variante del hero sin botones: aquí nadie ha leído nada
   todavía y no hay nada que contratar. Es el único hero del sistema sin acción,
   y esa ausencia es la decisión. */
.lab-hero--editorial .lab-hero__inner {
  text-align: left;
  margin-inline: 0;
}

/* Texto a la izquierda y una única imagen de apoyo a la derecha, para que la
   página no arranque como un muro de texto.

   La medida de lectura va en la PISTA, no solo en el hijo. Es D-59: con
   `1fr` la columna se queda todo el sobrante, el texto no la llena porque tiene
   su propio `max-width`, y entonces el hueco visible es el resto vacío de la
   pista MÁS el `gap` — tocar el `gap` no acerca nada. Con la pista medida, el
   hueco entre texto e imagen es el que se declara. */
.lab-hero__editorial {
  display: grid;
  grid-template-columns: minmax(0, var(--worke-measure)) minmax(0, 1fr);
  gap: var(--worke-space-2xl);
  align-items: center;
}

/* Apoyo, no hero comercial: sin marco, sin sombra y sin botones al lado.
   Proporción 4:3 y no una banda estrecha, porque aquí la imagen acompaña a un
   texto de tres líneas y una franja apaisada se leería como un adorno.

   `height: auto` NO es redundante: los atributos `width`/`height` del HTML son
   sugerencias de presentación que el navegador convierte en CSS, así que la
   imagen llega con `height: 1024px` puesto, y un alto definido gana a
   `aspect-ratio`. Sin esta línea la proporción se ignora.

   El encuadre se sube al 30%: centrado cortaría la cabeza por arriba. A esta
   proporción caben la cara y el móvil enteros, cosa que no ocurría en las cajas
   estrechas de la portada. */
.lab-hero__apoyo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center 30%;
  border-radius: var(--worke-radius-lg);
}

@media (max-width: 921px) {
  /* En una columna la imagen pasa DEBAJO del texto y se abre a banda: apilada
     a 4:3 ocuparía casi una pantalla entera y retrasaría la llegada al primer
     titular, que es a lo que se viene. */
  .lab-hero__editorial {
    grid-template-columns: 1fr;
    gap: var(--worke-space-xl);
  }

  .lab-hero__apoyo {
    aspect-ratio: 16 / 9;
  }
}

/* Franja de áreas: dice de qué se escribe aquí antes de que el lector lo
   deduzca de los titulares. Es lo que separa un centro de actualidad de un
   listado de entradas.
   Va en línea y no en tres columnas a propósito: una rejilla de tres con
   rótulo y texto sería `.lab-invariables` de /precios/ con otro contenido.
   Aquí son etiquetas, no bloques.
   Queda preparada para convertirse en el filtro de categorías cuando cada área
   tenga cuatro artículos o más; hoy no filtra porque filtrar «Consejos»
   devolvería dos, y un filtro que vacía la página se lee como una avería. */
.lab-secciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--worke-space-lg);
  margin: var(--worke-space-xl) 0 0;
  padding: var(--worke-space-md) 0 0;
  border-top: 1px solid var(--worke-color-border);
  list-style: none;
}

.lab-seccion {
  font-size: var(--worke-font-size-small);
  font-weight: var(--worke-font-weight-heading);
  letter-spacing: var(--worke-letter-spacing-eyebrow);
  text-transform: uppercase;
  color: var(--worke-color-primary);
}

/* Artículo destacado. Selección editorial manual, no el más reciente
   automáticamente: la Dirección decide cuál representa mejor el mensaje en
   cada momento (2026-08-02).
   Se distingue por tipografía y aire, NO por caja ni por imagen. Una tarjeta
   grande sería la cuarta aparición del patrón de tarjetas del sistema; el peso
   tipográfico es lo que lo hace editorial. */
.lab-destacado {
  max-width: var(--worke-measure);
}

.lab-destacado__titulo {
  margin: var(--worke-space-sm) 0 var(--worke-space-md);
  font-size: var(--worke-font-size-h2);
}

/* Un escalón por encima del cuerpo, dentro de la escala cerrada: es la
   entradilla del artículo elegido y debe pesar más que las del índice, que van
   a tamaño de cuerpo. El sistema no tiene un tamaño «lead» propio y no se
   inventa uno. */
.lab-destacado__entradilla {
  margin: 0;
  font-size: var(--worke-font-size-h5);
  color: var(--worke-color-text);
}

/* Índice cronológico. Dos columnas por entrada: el dato a la izquierda, el
   contenido a la derecha.
   La proporción es fija y no `fr`: la columna de la izquierda debe medir lo
   mismo en todas las filas para que fecha y categoría se escaneen en vertical.
   Con `fr` variaría según el largo del título de al lado. */
/* Rótulo del índice. A tamaño `h4` para que no compita con el destacado, que
   es `h2`, y alineado a la izquierda: los encabezados centrados del sistema
   abren un argumento, y esto abre un archivo. */
.lab-articulos__rotulo {
  margin: 0 0 var(--worke-space-md);
  font-size: var(--worke-font-size-h4);
}

.lab-articulos {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lab-articulo {
  display: grid;
  /* 14rem y no 12: es lo que mide «CONSEJOS PARA EMPRESAS» en una sola línea,
     que es la etiqueta más larga de las tres. A 12rem partía en dos y esas
     filas quedaban más altas que el resto, rompiendo el ritmo del índice.
     La medida sale de la etiqueta real, no de un número redondo. */
  grid-template-columns: 14rem minmax(0, 1fr);
  gap: var(--worke-space-lg);
  padding-block: var(--worke-space-xl);
  border-top: 1px solid var(--worke-color-border);
}

/* El filete separa entradas, no las enmarca: la última no lleva borde inferior
   porque el borde de la sección ya cierra el bloque. */
.lab-articulo:last-child {
  padding-bottom: 0;
}

.lab-articulo__meta {
  display: flex;
  flex-direction: column;
  gap: var(--worke-space-xs);
  margin: 0;
}

/* La categoría NO es decoración. Es lo que permite al lector saltarse de un
   vistazo lo que no le sirve, y hace falta porque aquí conviven dos cosas
   distintas: contenido útil para cualquier pyme y novedades de la empresa. */
.lab-articulo__categoria {
  font-size: var(--worke-font-size-small);
  font-weight: var(--worke-font-weight-heading);
  letter-spacing: var(--worke-letter-spacing-eyebrow);
  text-transform: uppercase;
  color: var(--worke-color-primary);
}

.lab-articulo__fecha {
  font-size: var(--worke-font-size-small);
  color: var(--worke-color-text);
}

.lab-articulo__titulo {
  margin: 0 0 var(--worke-space-xs);
  font-size: var(--worke-font-size-h4);
}

.lab-articulo__entradilla {
  max-width: var(--worke-measure);
  margin: 0;
  color: var(--worke-color-text);
}

/* El enlace es el TÍTULO y solo el título. Envolver la fila entera haría que un
   lector de pantalla anunciase categoría, fecha, título y entradilla como el
   nombre de un único enlace: ilegible.
   El subrayado se transiciona por color, nunca alternando `text-decoration`
   (§4.8.1): declarado siempre y transparente en reposo, para que no haya salto
   de maquetación al pasar el ratón. */
.lab-articulo__enlace {
  color: var(--worke-color-heading);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
  transition: color var(--worke-transition),
    text-decoration-color var(--worke-transition);
}

.lab-articulo__enlace:hover {
  color: var(--worke-color-primary);
  text-decoration-color: currentColor;
}

@media (max-width: 921px) {
  /* En una columna el dato se coloca ENCIMA del título, que es la forma
     natural de leerlo cuando no hay una columna lateral. La meta pasa a línea
     horizontal para no gastar dos renglones en dos palabras. */
  .lab-articulo {
    grid-template-columns: 1fr;
    gap: var(--worke-space-sm);
  }

  .lab-articulo__meta {
    flex-direction: row;
    align-items: baseline;
    gap: var(--worke-space-md);
  }
}

/* --- 7. Pantalla de acceso ------------------------------------------------ */

.lab-access {
  max-width: var(--worke-form-width);
  margin-inline: auto;
  padding-block: var(--worke-space-xl);
}

.lab-access__title {
  text-align: center;
}

/* Aviso de que esto es una maqueta. Se retira al llevarlo a producción. */
.lab-access__disclaimer {
  margin-top: var(--worke-space-md);
  margin-bottom: 0;
  text-align: center;
  font-size: var(--worke-font-size-small);
  color: var(--worke-color-text);
  opacity: 0.75;
}

.lab-access__card {
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-lg);
  background-color: var(--worke-color-surface);
  overflow: hidden;
}

/* Pestañas. Patrón ARIA tablist/tab/tabpanel. */
.lab-tabs {
  display: flex;
  background-color: var(--worke-color-surface-alt);
  border-bottom: 1px solid var(--worke-color-border);
}

.lab-tab {
  flex: 1;
  padding: var(--worke-space-md) var(--worke-space-sm);
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  font-family: inherit;
  font-size: var(--worke-font-size-nav);
  font-weight: var(--worke-font-weight-nav);
  color: var(--worke-color-text);
  cursor: pointer;
  transition: color var(--worke-transition), border-color var(--worke-transition),
    background-color var(--worke-transition);
}

.lab-tab:hover {
  color: var(--worke-color-primary);
}

.lab-tab[aria-selected="true"] {
  background-color: var(--worke-color-surface);
  border-bottom-color: var(--worke-color-primary);
  color: var(--worke-color-primary);
  font-weight: var(--worke-font-weight-heading);
}

.lab-tab:focus-visible {
  outline-offset: -3px;
}

.lab-panel {
  padding: var(--worke-space-xl) var(--worke-space-lg);
}

.lab-panel[hidden] {
  display: none;
}

.lab-panel__title {
  font-size: var(--worke-font-size-h3);
  margin-bottom: var(--worke-space-xs);
}

.lab-panel__text {
  margin-bottom: var(--worke-space-lg);
  font-size: var(--worke-font-size-small);
}

/* --- 7.1 Formulario ------------------------------------------------------- */
/* Representación visual. No envía datos: lab.js cancela el envío. */

.lab-form {
  display: flex;
  flex-direction: column;
  gap: var(--worke-space-md);
}

.lab-field {
  display: flex;
  flex-direction: column;
  gap: var(--worke-space-xs);
}

/* Etiqueta siempre visible. No se usa el placeholder como etiqueta: al
   escribir desaparecería y el campo quedaría sin identificar. */
.lab-field__label {
  font-size: var(--worke-font-size-small);
  font-weight: var(--worke-font-weight-nav);
  color: var(--worke-color-heading);
}

.lab-field__input {
  width: 100%;
  padding: var(--worke-control-padding-y) var(--worke-control-padding-x);
  font-family: inherit;
  font-size: var(--worke-font-size-body);
  line-height: 1.4;
  color: var(--worke-color-text);
  background-color: var(--worke-color-surface);
  border: 1px solid var(--worke-color-border);
  border-radius: var(--worke-radius-md);
  transition: border-color var(--worke-transition), box-shadow var(--worke-transition);
}

.lab-field__input:hover {
  border-color: var(--worke-color-text);
}

/* El foco se marca con dos señales a la vez, borde y halo, para que sea
   perceptible sin depender solo del color. */
.lab-field__input:focus {
  outline: none;
  border-color: var(--worke-color-primary);
  box-shadow: 0 0 0 3px var(--worke-color-primary-soft);
}

/* En modo de contraste forzado el halo no se pinta: se restituye el contorno. */
@media (forced-colors: active) {
  .lab-field__input:focus {
    outline: 2px solid;
    outline-offset: 1px;
  }
}

/* Fila de «Recordarme» y enlace de contraseña olvidada. */
.lab-form__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--worke-space-sm) var(--worke-space-md);
}

/* La casilla y el radio son la misma pieza —control nativo más etiqueta al
   lado—, así que comparten declaraciones en lugar de duplicarlas, igual que
   `.lab-hero__eyebrow, .lab-section__eyebrow`.
   El radio se alinea arriba y no al centro porque su etiqueta puede ocupar dos
   líneas al estrecharse; la casilla del RGPD nunca lo hace. */
.lab-checkbox,
.lab-radio {
  display: inline-flex;
  align-items: center;
  gap: var(--worke-space-sm);
  font-size: var(--worke-font-size-small);
  cursor: pointer;
}

.lab-radio {
  align-items: flex-start;
}

.lab-checkbox input,
.lab-radio input {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--worke-color-primary);
  cursor: pointer;
}

/* Compensa la diferencia entre la altura del control y la de su línea de
   texto, para que el círculo quede ópticamente alineado con la primera línea
   en lugar de con el borde superior de la caja. */
.lab-radio input {
  flex: none;
  margin-top: 0.2em;
}

/* El subrayado se declara SIEMPRE y lo que cambia es su color, en lugar de
   alternar `text-decoration: none` con `underline`. Son tres cosas a la vez:
   `text-decoration` no es animable, así que alternándola el color entraba con
   la transición y el subrayado aparecía de golpe en el mismo gesto; declarado
   en reposo, el subrayado ya ocupa su sitio y el hover no puede reflotar la
   línea; y `text-underline-offset` lo separa de las descendentes, que es lo
   que el navegador no hace por defecto.
   Sin duración propia: usa el token de movimiento del sistema (§4.8). */
.lab-link {
  font-size: var(--worke-font-size-small);
  color: var(--worke-color-primary);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color var(--worke-transition),
    text-decoration-color var(--worke-transition);
}

.lab-link:hover {
  color: var(--worke-color-primary-dark);
  text-decoration-color: currentColor;
}

.lab-cta--block {
  width: 100%;
}

/* SIN ESTA REGLA, `hidden` NO OCULTA UN `.lab-cta`. El navegador aplica
   `[hidden] { display: none }` desde su propia hoja, y cualquier declaración
   de una hoja de autor le gana con independencia de la especificidad: el
   `display: inline-flex` de `.lab-cta` la anularía y el control quedaría
   visible. Se resuelve con especificidad de clase más atributo, sin recurrir
   a `!important` —el sistema solo autoriza uno, en §4.8.2—.
   Lo necesitan los dos controles de la sección de demostración, que se
   alternan con `hidden`. */
.lab-cta[hidden] {
  display: none;
}

/* --- 7.2 Bloque secundario de la pestaña Empresa -------------------------- */

.lab-panel__divider {
  height: 1px;
  margin: var(--worke-space-xl) 0 var(--worke-space-lg);
  background-color: var(--worke-color-border);
  border: none;
}

.lab-panel__aside {
  text-align: center;
}

.lab-panel__aside p {
  margin-bottom: var(--worke-space-md);
  font-size: var(--worke-font-size-small);
}

/* --- 8. Pie de página ----------------------------------------------------- */
/* Fondo alterno con borde superior. NO se usa el azul profundo: ese color está
   reservado a la banda de cierre, y su exclusividad es lo único que la hace
   leerse como final de página en lugar de como una repetición del hero.
   Un pie oscuro competiría con ella y ambas perderían. */

.lab-footer {
  padding-block: var(--worke-space-2xl);
  background-color: var(--worke-color-surface-alt);
  border-top: 1px solid var(--worke-color-border);
}

/* Cuatro zonas: marca, producto, empresa y legal.
   La marca ocupa el doble porque lleva logotipo y una descripción;
   las otras tres solo enlaces. */
.lab-footer__inner {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--worke-space-xl);
  align-items: start;
}

/* La marca es el mismo componente que en la cabecera (§1.1). Aquí solo se le
   añade el espacio que la separa de la descripción. */
.lab-footer__brand .lab-brand {
  margin-bottom: var(--worke-space-md);
}

.lab-footer__claim {
  margin-bottom: 0;
  font-size: var(--worke-font-size-small);
}

/* Encabezado de columna. Es <h2> por jerarquía —el pie no es una sección,
   así que no compite con el <h2> de ninguna— y su tamaño lo decide el
   componente, no el nivel. */
.lab-footer__title {
  margin: 0 0 var(--worke-space-md);
  font-size: var(--worke-font-size-h5);
  font-weight: var(--worke-font-weight-heading);
  line-height: var(--worke-line-height-heading);
  color: var(--worke-color-heading);
}

.lab-footer__list {
  display: grid;
  gap: var(--worke-space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Mismo mecanismo de subrayado que `.lab-link`: el enlace del pie tenía el
   mismo salto —transicionaba el color y el subrayado entraba de golpe—. */
.lab-footer__link {
  font-size: var(--worke-font-size-small);
  color: var(--worke-color-text);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color var(--worke-transition),
    text-decoration-color var(--worke-transition);
}

.lab-footer__link:hover {
  color: var(--worke-color-primary);
  text-decoration-color: currentColor;
}

.lab-footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--worke-space-md);
  margin-top: var(--worke-space-2xl);
  padding-top: var(--worke-space-lg);
  border-top: 1px solid var(--worke-color-border);
}

.lab-footer__copy {
  margin-bottom: 0;
  font-size: var(--worke-font-size-small);
}

/* Nota de condiciones de la oferta de lanzamiento. Destino del asterisco de
   `.lab-oferta`, y por eso vive en el pie GLOBAL: el pie es idéntico en las
   cinco páginas (§5.20) y así el ancla funciona desde cualquiera que lleve la
   banda, sin duplicar la nota ni bifurcar el componente.
   Va DESPUÉS de `.lab-footer__bottom` y no dentro: esa fila es un flex de dos
   extremos —copyright y redes— y un tercer elemento rompería el reparto.
   Tamaño `small` y ancho completo: es letra pequeña, no un bloque de lectura,
   y limitarla a la medida dejaría un texto legal descolgado a la izquierda. */
.lab-footer__nota {
  margin: var(--worke-space-lg) 0 0;
  font-size: var(--worke-font-size-small);
}

/* Lleva `tabindex="-1"` para que al saltar desde el asterisco el foco se mueva
   de verdad hasta ella: un `p` no es enfocable, y sin esto el navegador
   desplaza la página pero deja el foco atrás, de modo que quien navega con
   teclado o lector de pantalla sigue «estando» en la banda de oferta.
   Y si el foco llega, tiene que verse: la regla global solo cubre `a` y
   `button`. Mismo trazo y mismo desplazamiento que §3.7. */
.lab-footer__nota:focus-visible {
  outline: 2px solid var(--worke-color-focus);
  outline-offset: 2px;
  border-radius: var(--worke-radius-sm);
}

/* Redes sociales. Solo las que existen de verdad: perfiles verificados en el
   HTML de producción. No se añaden iconos de redes sin perfil detrás.
   Van al pie y sin rótulo visible: el nombre accesible lo aporta aria-label,
   porque un icono suelto no dice nada a un lector de pantalla. */
.lab-footer__social {
  display: flex;
  gap: var(--worke-space-md);
}

.lab-footer__social-link {
  display: inline-flex;
  color: var(--worke-color-text);
  transition: color var(--worke-transition);
}

.lab-footer__social-link:hover {
  color: var(--worke-color-primary);
}

.lab-footer__social-link svg {
  width: var(--worke-marker-size);
  height: var(--worke-marker-size);
}

/* En tablet, dos columnas: cuatro zonas apiladas en una sola obligarían a
   recorrer todo el pie para llegar a los enlaces legales. */
@media (max-width: 921px) {
  .lab-footer__inner {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 544px) {
  .lab-footer__inner {
    grid-template-columns: 1fr;
  }
}

/* --- 9. Preferencias de movimiento reducido ------------------------------- */
/* Neutraliza TODO el movimiento, no solo las transiciones. La versión anterior
   solo anulaba `transition-duration`, de modo que cualquier `@keyframes` o
   desplazamiento suave habría seguido ejecutándose con la preferencia activa:
   el sistema declaraba en §3.7 que la respetaba y no era cierto para todo.
   Hoy el sistema no tiene ninguna animación —§4.8 no las admite—, así que la
   corrección no cambia nada visible: cierra la puerta antes de que se abra.
   `animation-iteration-count` es necesario junto a la duración, porque un bucle
   infinito de 0.01ms sigue siendo un bucle infinito.
   Es el ÚNICO `!important` autorizado del sistema (§4.8). No se añade una
   excepción nueva: se completa la que ya existía. */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
