/* ============================================================
   Diagnostico Digital (/monitor/) - hoja de estilo
   ------------------------------------------------------------
   Igual que en la portada: esto eran 51 KB de CSS incrustados en
   dos <style> dentro de monitor/index.html. Al ir dentro del
   documento no se cacheaban, viajaban enteros en cada visita y
   retrasaban el parseo del HTML. Aqui se descargan una vez.

   Mudanza literal: mismo orden que tenian en el documento, asi
   que la cascada no cambia. Primero el bloque del <head> y
   despues el que estaba al principio del <body>.

   Las dos reglas @font-face se quedan inline en el HTML: van
   emparejadas con los <link rel="preload"> de las fuentes y
   apuntan con ruta relativa a la pagina.
   ============================================================ */


    /* Transiciones nativas entre páginas (index <-> /monitor) del mismo origen */
    @view-transition {
      navigation: auto;
    }

    ::view-transition-old(root),
    ::view-transition-new(root) {
      animation-duration: .38s;
      animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
    }

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    /* Los controles de formulario no heredan la tipografia: el navegador les
       pone la del sistema. Sin esta regla, en la portada salian en Arial el
       boton "Enviar mensaje", los campos del formulario de contacto y los
       botones del chat de la FAQ —once elementos— mientras el resto del sitio
       iba en Inter. No se veia porque casi todos los botones del sitio son
       enlaces <a>, y esos si heredan. Se deja el tamano fuera a proposito:
       heredarlo tambien descuadraria campos que ya tienen el suyo. */
    button,
    input,
    select,
    textarea {
      font-family: inherit;
    }


    html {
      scroll-behavior: smooth;
      scroll-padding-top: 88px;
      -webkit-text-size-adjust: 100%;
    }

    body {
      background: #ffffff;
      font-family: var(--sans);
      color: var(--ink);
      font-size: 15px;
      line-height: 1.6;
      -webkit-font-smoothing: antialiased;
      overflow-x: hidden;
    }

    ::selection {
      background: var(--violet);
      color: #fff;
    }

    img {
      max-width: 100%;
      display: block;
    }

    a {
      color: inherit;
      text-decoration: none;
    }

    .dot {
      color: var(--violet);
    }

    /* Floating Animation */
    @keyframes floaty {

      0%,
      100% {
        transform: translateY(0) rotate(0deg);
      }

      50% {
        transform: translateY(-8px) rotate(1.5deg);
      }
    }

    @keyframes floaty-reverse {

      0%,
      100% {
        transform: translateY(0) rotate(0deg);
      }

      50% {
        transform: translateY(-6px) rotate(-1.2deg);
      }
    }

    .float-robot {
      animation: floaty 6s ease-in-out infinite;
    }

    .float-robot-slow {
      animation: floaty-reverse 8s ease-in-out infinite;
    }

    /* Aqui vivia la cabecera de marketing de la primera version de la pagina
       —barra de navegacion, hero con titular y la barra de busqueda redonda—.
       El documento ya no la pinta: entra directo al hero del diagnostico. */

    /* Dashboard Shell */
    /* min-height, no height: el panel crece con su contenido y scrollea la
       página, no una caja interna. Con `height:100vh` + `.panel{overflow-y:auto}`
       el informe quedaba encerrado en un scroll propio dentro de la ventana:
       dos barras de desplazamiento y, en portátiles, hallazgos que no se veían
       porque la caja interior no daba señal de que hubiera más abajo. */
    .tool-shell {
      padding: 0;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
    }

    /* ---- UN SOLO NIVEL DE TARJETA ----------------------------------------
       `.app` declaraba el gris #f8fafc y encima iban `.app-bar`, `.side`,
       `.panel` y `.footer-banner` en #ffffff: el suelo gris no se veia NUNCA y
       quedaban tres niveles de caja blanca apilados, separados solo por filetes
       del 5-6% de alfa. Es el problema que `--canvas` existe para resolver, y
       estaba escrito en el archivo de tokens antes de aplicarse aqui.

       Ahora: el suelo de la aplicacion es `--canvas` —`.app`, `.app-bar`,
       `.side` y `.panel`, todos el mismo gris— y encima solo hay UN nivel de
       tarjeta blanca (`.pcard`, `.check-card`). El chrome se separa por filete,
       no por color, y las tarjetas se leen solas sobre el gris sin sombra,
       que es justo lo que dice tokens.css de `--canvas`. */
    .app {
      background: var(--canvas);
      width: 100%;
      flex: 1;
      display: flex;
      flex-direction: column;
    }

    .app.in {
      opacity: 1;
      transform: none;
    }

    /* Sin fondo propio: es el mismo suelo, y del panel la separa el filete.
       `--line-strong` y no `--line` porque ahora es la UNICA senal de que la
       barra y el contenido son cosas distintas; al 5% de alfa sobre gris no se
       veia. */
    .app-bar {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      /* Los 1,5rem laterales pasan a `--panel-pad` para que la barra respire
         igual que el panel de debajo. En un telefono son 16px en vez de 24, y
         esos 16px se los queda la caja de la direccion, que es lo que aqui
         iba mas apretado. */
      padding: 0.95rem var(--panel-pad);
      border-bottom: 1px solid var(--line-strong);
      background: transparent;
    }

    /* ---- Salidas del panel ------------------------------------------------
       Tres cosas que no existían dentro del panel: volver a analizar otro
       dominio, entrar a una cuenta y cerrar la sesión abierta. Van en la barra
       de la ventana, a la derecha del distintivo, que es donde se buscan los
       controles de la ventana en la que uno está.

       Discretos a propósito: quien acaba de recibir su diagnóstico viene a
       leerlo, y estos botones son salidas, no la acción principal. Texto en
       --ink-soft sobre blanco (7.1:1, holgado sobre el 4.5:1 que pide AA) y
       borde de un punto; el color se reserva para el distintivo de al lado. */
    .app-acciones {
      display: flex;
      align-items: center;
      gap: 0.4rem;
      margin-left: 0.55rem;
    }

    .app-btn {
      display: inline-flex;
      align-items: center;
      gap: 0.32rem;
      font: inherit;
      font-size: 12.5px;
      font-weight: 600;
      line-height: 1;
      color: var(--ink-soft);
      background: #fff;
      border: 1px solid rgba(15, 23, 42, 0.12);
      border-radius: 7px;
      padding: 0.42rem 0.66rem;
      cursor: pointer;
      white-space: nowrap;
      transition: color .16s ease, border-color .16s ease, background .16s ease;
    }

    /* El hover iba a #f8fafc, que ahora es EXACTAMENTE el color de la barra:
       el boton se fundia con el fondo justo al apuntarlo. Pasa a la misma
       tinta de hover que ya usa `.kv-sesion-x` en esta hoja. */
    .app-btn:hover {
      color: var(--ink);
      border-color: var(--line-control);
      background: rgba(15, 23, 42, 0.05);
    }

    /* El :focus-visible propio se va: la regla global de assets/tokens.css lo
       cubre con el mismo token, y tener las dos era mantener dos. */

    /* Con sesión abierta el botón lleva el nombre de la persona, y ahí sí se
       tiñe: deja de ser una salida y pasa a ser "esta es tu cuenta". */
    .app-btn--activa {
      color: var(--violet);
      border-color: rgba(130, 66, 245, 0.3);
      background: rgba(130, 66, 245, 0.1);
    }

    .app-btn--activa:hover {
      color: var(--violet);
      border-color: rgba(130, 66, 245, 0.5);
      background: rgba(130, 66, 245, 0.14);
    }

    /* En pantallas estrechas la barra no da para las dos etiquetas. Se queda
       el icono de volver —una flecha se entiende sola— y el de sesión, que
       lleva el nombre y no se puede resumir. */
    @media (max-width: 640px) {
      .app-bar {
        /* Se recorta el aire de la barra para pagar los 44px de los botones
           sin que la barra entera se hinche. */
        padding-top: 0.5rem;
        padding-bottom: 0.5rem;
      }

      .app-bar .addr {
        max-width: 150px;
      }

      .app-tag {
        display: none;
      }

      .app-acciones {
        margin-left: auto;
      }

      /* 44px de lado, que es lo que pide un objetivo tactil. Con el tamano de
         escritorio quedaban en 28-30px: se pulsan con el raton sin problema y
         con el pulgar a medias. */
      .app-btn {
        min-height: 44px;
        padding: 0.5rem 0.7rem;
      }

      #kvOtroSitio {
        font-size: 0;
        gap: 0;
        min-width: 44px;
        justify-content: center;
        padding: 0.5rem;
      }

      #kvOtroSitio svg {
        width: 16px;
        height: 16px;
      }
    }

    /* ---- "¿No tienes cuenta?" en el modal de sesión ----------------------
       Un enlace de texto, no un segundo botón: el registro de verdad está en
       el panel y esto solo lleva hasta allí. Que parezca un botón competiría
       con "Iniciar sesión", que es lo que la mayoría viene a hacer aquí. */
    .kv-sesion-pie {
      margin: 0.9rem 0 0;
      font-size: 13.5px;
      color: var(--ink-soft);
      text-align: center;
    }

    .kv-sesion-enlace {
      font: inherit;
      font-weight: 600;
      color: var(--violet);
      background: none;
      border: 0;
      padding: 0;
      cursor: pointer;
      text-decoration: underline;
      text-underline-offset: 2px;
    }

    .kv-sesion-enlace:hover {
      text-decoration-thickness: 2px;
    }

    .tl {
      width: 10px;
      height: 10px;
      border-radius: 50%;
    }

    .tl.r {
      background: #ff5f57;
    }

    .tl.y {
      background: #febc2e;
    }

    .tl.g {
      background: #28c840;
    }

    /* Con la barra ya en gris, un campo gris sobre gris desaparecia (#f1f5f9
       sobre #f8fafc). Pasa a blanco con borde de control: se lee como lo que
       es, la caja de la direccion.

       EL DOMINIO SE CORTABA SIN AVISAR. La caja llevaba `overflow: hidden` y
       `nowrap` pero no `text-overflow: ellipsis`, asi que un dominio largo se
       amputaba a media letra: medido en un telefono de 375px, 373px de texto
       metidos en 97px de caja, sin un solo indicio de que faltaba algo.

       Y el ellipsis no se puede poner aqui: `.addr` es un contenedor flex, y
       `text-overflow` solo actua sobre el contenido en linea de un bloque. Por
       eso el dominio se muda a su propio `.addr-dom`, que es quien trunca; lo
       que vaya al lado queda FUERA del elemento truncable y no puede empujarlo
       ni desaparecer con el. (Antes ahi vivia el sello "Verificado", que se
       iba a 450px cuando la caja terminaba en 188: en movil no se veia nunca.
       Se retiro por otra razon —no habia ninguna verificacion detras— pero la
       estructura queda preparada para lo que sea que ocupe ese hueco.) */
    .app-bar .addr {
      margin-left: 0.7rem;
      flex: 1;
      min-width: 0;
      max-width: 340px;
      display: flex;
      align-items: center;
      gap: 0.5rem;
      background: var(--surface);
      border: 1px solid var(--line-strong);
      border-radius: 8px;
      padding: 0.45rem 0.8rem;
      font-size: 12.5px;
      font-weight: 500;
      color: var(--ink-soft);
      overflow: hidden;
      white-space: nowrap;
    }

    .app-bar .addr .addr-dom {
      flex: 1 1 auto;
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .app-tag {
      margin-left: auto;
      font-size: 12.5px;
      font-weight: 700;
      color: var(--violet);
      background: var(--violet-soft);
      padding: 0.25rem 0.6rem;
      border-radius: 6px;
      text-transform: uppercase;
      letter-spacing: 0.05em;
    }

    /* ---- Aviso de panel temporal --------------------------------------
       REDISEÑADO 2026-08-05 sobre un vocabulario premium extraído midiendo
       attio.com de verdad (no adivinado): radios de 10-12px en vez de
       píldoras, sombra en tres capas teñida de tinta, texto en peso 500,
       curva de salida seca. La primera versión usaba una franja ámbar de
       aviso bancario a todo el ancho — funcionaba, pero desentonaba con el
       resto del sitio y no se sentía parte del mismo producto.
       Ahora es una tarjeta flotante con aire alrededor, como cualquier otro
       bloque de la interfaz: avisa sin sonar a advertencia. */
    /* Vivia como hijo directo de `.app`, encima de `.app-grid`, y de ahi los
       margenes laterales propios. Ahora es la penultima pieza de `.panel`, que
       ya es una rejilla con su gap y su padding: el margen sobra y descuadraba.
       Fuera tambien `--shadow-ui`: sobre el suelo gris ya no hace falta, y era
       el segundo nivel de elevacion que este cambio viene a quitar. El punto
       violeta sigue siendo lo que la distingue de una tarjeta corriente. */
    .kv-temp {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      gap: 1rem;
      margin: 0;
      padding: .9rem 1.1rem;
      background: var(--surface);
      border: 1px solid var(--line-strong);
      border-radius: var(--r-ui-lg);
      font-size: 13px;
    }

    .kv-temp[hidden] {
      display: none;
    }

    .kv-temp-txt {
      display: flex;
      align-items: flex-start;
      gap: .65rem;
    }

    /* El punto violeta ancla el ojo antes que el texto — el mismo principio
       que el kicker de una sección: algo pequeño que dice "esto es un
       estado", no un párrafo que hay que leer entero para saberlo. */
    .kv-temp-txt::before {
      content: '';
      flex: none;
      width: 8px;
      height: 8px;
      margin-top: .4em;
      border-radius: 50%;
      background: var(--violet);
    }

    .kv-temp-txt b {
      display: block;
      font-weight: 600;
      color: var(--ink);
      letter-spacing: -.01em;
    }

    .kv-temp-txt span {
      color: var(--ink-soft);
      font-weight: 500;
      line-height: 1.5;
    }

    .kv-temp-acciones {
      display: flex;
      align-items: center;
      gap: .6rem;
      flex: none;
    }

    /* 44px DE ALTO. Medido a 375px, este boton daba 35,2 y el enlace de al lado
       otros 35,2: se pulsan bien con el raton y a medias con el pulgar. El
       relleno no se toca —cambiarlo movia el ancho del texto—; se pone el
       minimo y se centra el contenido, que sube el area sensible sin tocar la
       tipografia. Es el mismo remedio que ya llevaban `.kv-sesion` (≤560px) y
       `.app-btn` (≤640px) en esta misma hoja, generalizado a los dos botones
       que se habian quedado fuera. */
    .kv-temp-btn {
      border: 0;
      cursor: pointer;
      background: var(--violet);
      color: #fff;
      font-family: inherit;
      font-size: 13px;
      font-weight: 600;
      min-height: 44px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: .6rem 1.15rem;
      border-radius: var(--r-ui);
      transition: transform .2s var(--ease-ui), background .2s var(--ease-ui), box-shadow .2s var(--ease-ui);
    }

    .kv-temp-btn:hover {
      transform: translateY(-1px);
      background: var(--violet-hover);
      box-shadow: 0 6px 16px -4px rgba(130, 66, 245, .45);
    }

    /* Sirve a un <a> ("Analizar otro sitio", que confirmarGuardado inyecta) y a
       un <button> ("Crear cuenta gratis"): de ahi los reset de fondo y borde,
       que un <a> no necesita y un <button> sin ellos sale como boton gris del
       sistema. */
    .kv-temp-link {
      font-family: inherit;
      font-size: 13px;
      font-weight: 600;
      color: var(--ink-soft);
      text-decoration: none;
      background: none;
      border: 0;
      cursor: pointer;
      min-height: 44px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: .6rem .3rem;
      transition: color .2s var(--ease-ui);
    }

    .kv-temp-link:hover {
      color: var(--ink);
    }

    .kv-lead-lbl {
      display: block;
      font-size: 12px;
      font-weight: 600;
      color: var(--ink-soft);
      margin-bottom: .35rem;
    }

    /* EL BORDE DE UN CAMPO ES UN BORDE DE CONTROL, NO UNA COSTURA.
       Iba con `--line-strong` (12% de alfa): medido sobre blanco da 1,28:1, y
       WCAG 1.4.11 pide 3:1 para el limite de cualquier cosa con la que se
       pueda interactuar. Con un placeholder gris y un borde que no se ve, la
       caja del campo solo existia para quien ya sabia donde estaba.
       `--line-control` (32% de alfa, ≈3,03:1) es el token que tokens.css
       creo exactamente para esto y que aqui todavia no se usaba. */
    .kv-lead-input {
      flex: 1 1 220px;
      min-width: 0;
      font-family: inherit;
      font-size: 14px;
      padding: .6rem .8rem;
      border: 1px solid var(--line-control);
      border-radius: var(--r-ui);
      background: var(--surface);
      color: var(--ink);
      transition: border-color .2s var(--ease-ui), box-shadow .2s var(--ease-ui);
    }

    .kv-lead-input::placeholder {
      color: var(--ink-faint);
    }

    .kv-lead-input:focus {
      outline: none;
      border-color: var(--violet);
      box-shadow: 0 0 0 3px var(--violet-soft);
    }

    .kv-lead-err {
      margin-top: .5rem;
      font-size: 12.5px;
      font-weight: 600;
      color: #dc2626;
      min-height: 1em;
    }

    /* Confirmación: la tarjeta gana un acento verde discreto, sin volverse
       una franja de éxito a todo color — sigue siendo la misma tarjeta. */
    .kv-temp.kv-temp-ok {
      border-color: rgba(16, 185, 129, .35);
      background: var(--green-soft);
    }

    .kv-temp.kv-temp-ok .kv-temp-txt::before {
      background: var(--green);
    }

    .kv-temp.kv-temp-ok .kv-temp-txt b {
      color: #065f46;
    }

    .kv-temp.kv-temp-ok .kv-temp-txt span {
      color: #047857;
    }

    @media (max-width: 620px) {
      .kv-temp {
        flex-direction: column;
        align-items: flex-start;
      }

      .kv-temp-acciones {
        width: 100%;
      }

      .kv-temp-btn {
        flex: 1;
      }
    }

    /* ---- Cabecera: una sola puerta ---------------------------------------
       Aquí convivían dos botones, el de sesión y un candado que llevaba al
       login de equipo en /admin/. Quedó uno solo: /api/sesion.php reconoce
       las dos llaves y decide a dónde va cada quien. Se retiraron también las
       ocho reglas del candado, que quedaban sin ningún elemento que las
       usara. */
    .kv-header-acciones {
      position: fixed;
      top: clamp(1.1rem, 3vw, 1.9rem);
      right: clamp(1.1rem, 4vw, 2.6rem);
      z-index: 40;
      display: flex;
      align-items: center;
      gap: .5rem;
    }

    body.kv-en-panel .kv-header-acciones {
      display: none;
    }


    /* SECUNDARIO, NO PRINCIPAL.
       Este boton era negro solido, igual que "Analizar mi sitio". Los dos con
       el mismo peso y a la misma altura: la accion por la que existe la pagina
       y una utilidad para quien ya vino antes, compitiendo de igual a igual.
       Sin jerarquia el ojo no sabe donde ir primero, y quien llega por primera
       vez —que es casi todo el mundo— se encuentra dos veces con la misma
       invitacion a pulsar.

       Pasa a contorno: se ve, se alcanza, y deja el unico relleno solido de la
       pantalla para el campo de analisis. Es ademas el mismo lenguaje de
       .app-btn, el secundario de la barra del panel, para que entrar y salir
       se vean igual en los dos sitios. */
    .kv-sesion {
      display: inline-flex;
      align-items: center;
      gap: .45rem;
      padding: .5rem .9rem;
      cursor: pointer;
      border-radius: var(--r-btn);
      background: #fff;
      border: 1px solid rgba(15, 23, 42, .14);
      color: var(--ink-soft);
      font-family: inherit;
      font-size: 12.5px;
      font-weight: 650;
      box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
      transition: color .2s var(--ease-ui), border-color .2s var(--ease-ui), background .2s var(--ease-ui);
    }

    .kv-sesion:hover {
      color: var(--ink);
      border-color: rgba(15, 23, 42, .3);
      background: #f8fafc;
    }

    .kv-sesion:focus-visible {
      outline: 2px solid var(--violet);
      outline-offset: 2px;
    }

    /* Con sesion abierta el boton lleva el nombre y se tine: ya no invita a
       entrar, dice quien eres. Mismo criterio que .app-btn--activa. */
    .kv-sesion.kv-sesion--activa {
      color: var(--violet);
      border-color: rgba(130, 66, 245, .3);
      /* No se usa --violet-soft (6 %): en una superficie de este tamano no se
         distingue del blanco, y el estado tiene que verse de un vistazo. */
      background: rgba(130, 66, 245, .1);
    }

    .kv-sesion svg {
      opacity: .85;
    }

    @media (max-width: 560px) {
      /* Sin texto queda solo el icono, y con el relleno de escritorio el
         boton medía 33x33: se pulsa bien con el raton y a medias con el
         pulgar. 44x44 es el objetivo tactil minimo. */
      .kv-sesion {
        padding: .5rem;
        font-size: 0;
        gap: 0;
        min-width: 44px;
        min-height: 44px;
        justify-content: center;
      }

      .kv-sesion svg {
        width: 16px;
        height: 16px;
      }
    }

    /* ---- Modal de sesión ---------------------------------------------- */
    .kv-sesion-modal {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 95;
      background: rgba(15, 23, 42, .5);
      backdrop-filter: blur(4px);
      padding: 1.2rem;
      overflow-y: auto;
    }

    .kv-sesion-modal.on {
      display: flex;
      align-items: center;
      justify-content: center;
      animation: view-in .2s var(--ease-ui) both;
    }

    .kv-sesion-card {
      position: relative;
      width: 100%;
      max-width: 380px;
      margin: auto;
      background: var(--surface);
      border-radius: var(--r-ui-lg);
      padding: 2rem;
      box-shadow: var(--shadow-lg);
    }

    .kv-sesion-card h2 {
      font-family: var(--display);
      font-size: 1.4rem;
      font-weight: 700;
      letter-spacing: -.02em;
      color: var(--ink);
      margin-bottom: .4rem;
    }

    .kv-sesion-card h2 .dot {
      color: var(--violet);
    }

    .kv-sesion-sub {
      font-size: 13.5px;
      font-weight: 500;
      color: var(--ink-soft);
      line-height: 1.5;
      margin-bottom: 1.3rem;
    }

    #kvSesionNombre {
      color: var(--violet);
    }

    /* La equis del modal: 44px de area tactil y borde de control.
       Median 32x32 y el borde iba a 1,28:1. Como no lleva texto, ese circulo
       ES el control —no hay otra pista de que se pueda pulsar—, asi que le
       aplica 1.4.11 igual que a un campo. Se sube a 44 en vez de agrandar el
       circulo: el aspa dibujada sigue midiendo 15px, que es lo que pide una
       equis discreta en la esquina. */
    .kv-sesion-x {
      position: absolute;
      top: 1rem;
      right: 1rem;
      width: 44px;
      height: 44px;
      display: grid;
      place-items: center;
      border-radius: 50%;
      border: 1px solid var(--line-control);
      background: transparent;
      color: var(--ink-soft);
      cursor: pointer;
      transition: background .2s var(--ease-ui), color .2s var(--ease-ui);
    }

    .kv-sesion-x:hover {
      background: rgba(15, 23, 42, .05);
      color: var(--ink);
    }

    .app-grid {
      display: grid;
      grid-template-columns: 220px 1fr;
      flex: 1;
      min-height: 0;
    }

    /* Sidebar */
    /* Pegado arriba: como ahora scrollea la página entera, sin `sticky` el
       menú se iba hacia arriba y había que volver hasta el principio para
       cambiar de vista. */
    .side {
      background: transparent;
      border-right: 1px solid var(--line-strong);
      /* Vertical con `--panel-pad`, como el panel de al lado; horizontal fijo
         en --s-4, que es lo que el menu necesita para que la fila activa no
         toque el filete. */
      padding: var(--panel-pad) var(--s-4);
      display: flex;
      flex-direction: column;
      gap: 0.2rem;
      position: sticky;
      top: 0;
      align-self: start;
      max-height: 100vh;
      overflow-y: auto;
      z-index: 5;
    }

    .side-brand {
      display: flex;
      align-items: center;
      gap: 0.55rem;
      padding: 0.4rem 0.6rem 1.4rem;
      font-weight: 800;
      font-size: 16px;
      font-family: var(--display);
      color: var(--ink);
    }

    .side-brand img {
      width: 32px;
      height: 32px;
      object-fit: contain;
    }

    /* LAS CINCO ENTRADAS SON <button>.
       Eran <div>: tres con role/tabindex y un keydown a mano, y las dos del
       candado sin nada — con teclado no habia forma de abrir el modal del
       Panel Pro, y son su unica puerta.

       Un <button> no hereda cuatro cosas que un <div> si tenia, y sin ellas
       sale en la fuente del sistema, encogido al ancho del texto, centrado y
       con el fondo gris del navegador. Las cuatro se devuelven aqui:
       `background`, `border`, `width` y `text-align`. (La familia tipografica
       ya la devuelve la regla `button, input, select, textarea` de arriba.)

       Y `transition: all` se cambia por la lista explicita: el sistema lo
       prohibe, y aqui ademas animaba el `outline` del foco al aparecer. */

    /* EL ROTULO DE GRUPO, COPIADO DEL PANEL PRO TAL CUAL.
       No es decoracion: es lo que convierte ocho entradas en cuatro ideas
       —como estas, quien te busca, como vas, tu cuenta— y es la mitad de por
       que las dos superficies se leian como productos distintos. */
    .side-grupo {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: .09em;
      text-transform: uppercase;
      color: var(--ink-faint);
      padding: 0 .8rem .45rem;
      margin-top: 1.3rem;
    }

    /* El primero no lleva aire arriba: ya lo da la marca del panel. */
    .side-grupo:first-of-type { margin-top: .4rem; }

    /* El titulo de cada vista. Existe para quien navega con lector de
       pantalla, que sin el aterriza en una pantalla sin nombre; a la vista no
       cambia nada. El Pro lo lleva en las ocho pestañas y aqui faltaba en las
       tres. */
    .kv-anuncio {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }

    .side-item {
      display: flex;
      align-items: center;
      gap: 0.7rem;
      width: 100%;
      text-align: left;
      /* 44px de alto. Media 38,8 medidos a 375px, y en esa anchura el menu
         deja de ser una columna lateral para convertirse en la tira horizontal
         por la que se cambia de vista: es el control que mas se pulsa del
         panel y el que peor se acertaba. El relleno se queda como estaba —el
         minimo hace el trabajo— para no mover el ritmo del menu en
         escritorio, donde las cinco filas pasan de 38,8 a 44 y el bloque crece
         26px en total. */
      min-height: 44px;
      padding: 0.65rem 0.8rem;
      border: 0;
      border-radius: var(--r-ui);
      background: transparent;
      font-size: 13.5px;
      font-weight: 600;
      color: var(--ink-soft);
      transition: background-color var(--d-base) var(--ease-ui), color var(--d-base) var(--ease-ui);
      cursor: pointer;
    }

    .side-item svg {
      width: 18px;
      height: 18px;
      flex-shrink: 0;
      color: var(--ink-faint);
      transition: color 0.2s;
    }

    /* Blanco sobre el gris del suelo: el hover iba a #f1f5f9, un gris
       indistinguible de la barra ahora que la barra tambien es gris. */
    .side-item:hover {
      background: var(--surface);
      color: var(--ink);
    }

    .side-item:hover svg {
      color: var(--ink-soft);
    }

    .side-item.active {
      background: var(--violet-soft);
      color: var(--violet);
    }

    .side-item.active svg {
      color: var(--violet);
    }

    /* Sin `opacity: .7`. Ese 0.7 sobre `--ink-faint` (4,76:1) dejaba el texto
       en ~2,8:1 sobre el suelo: por debajo de AA. Se toleraba mientras esto
       era un <div> decorativo; ahora es un <button> que se puede enfocar y
       pulsar, y un control tiene que leerse. El candado y el color mas suave
       ya dicen que esta bloqueado. */
    .side-item.locked {
      color: var(--ink-faint);
    }

    .side-item.locked svg {
      color: var(--ink-faint);
    }

    .side-item .lock {
      margin-left: auto;
      color: var(--ink-faint);
    }

    /* Aqui vivia `.side-help` (once reglas): la tarjeta "¿Necesitas ayuda? ·
       Agendar sesion" del pie del menu. Apuntaba a /#contacto, el MISMO
       destino que el boton de la tarjeta "Da el siguiente paso" del final del
       panel: dos llamadas comerciales a la misma cita, a la vista al mismo
       tiempo. Se quedo una, la del final, que es cuando la pregunta tiene
       sentido. */

    /* Main Panel */
    /* Gris, como el resto del suelo: era la tercera caja blanca sobre blanca.
       Lo blanco de aqui adentro son las tarjetas, y solo ellas. */
    /* EL RELLENO SE ADAPTA AL ANCHO. Era 1,5rem fijos: 48px de los 375 de un
       telefono se iban en aire antes de empezar a leer, y en escritorio se
       quedaba corto. `--panel-pad` es clamp(1rem, 4vw, 1,8rem) —16px en el
       movil, 28,8 en pantalla ancha— y existe en tokens.css desde que se
       escribio, sin que ninguna superficie lo usara; el linter lo listaba como
       token declarado y sin usar. */
    .panel {
      padding: var(--panel-pad);
      display: grid;
      gap: 1.2rem;
      background: var(--canvas);
      align-content: start;
      min-width: 0;
    }

    /* ---- Vistas del menú lateral ----
       Resumen, Pilares y Hallazgos son paneles distintos, no anclas. Cuando
       eran anclas, "ir" a Pilares no movía nada: estaba al lado de Resumen,
       a la misma altura, y el clic parecía no hacer nada. */
    .view {
      display: none;
    }

    .view.on {
      display: grid;
      gap: 1.2rem;
      animation: view-in 0.25s ease both;
    }

    @keyframes view-in {
      from {
        opacity: 0;
        transform: translateY(6px);
      }
    }

    /* En Resumen el índice manda y las oportunidades acompañan. */
    #vResumen .panel-top-row {
      grid-template-columns: 1.2fr 0.9fr;
    }

    /* ---- Qué se revisó en cada pilar --------------------------------------
       El gauge dice "61" y ya; esto dice de dónde sale. Cada fila es una
       revisión concreta con su resultado, que es lo que convierte un número
       en algo sobre lo que se puede actuar. */
    .pillars-check {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 1.2rem;
    }

    .check-card {
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: 18px;
      /* Mismo motivo que `.panel`: 1,3rem fijos pasan a `--card-pad`
         —clamp(1rem, 3,5vw, 1,4rem)—, 16px en telefono y 22,4 en escritorio.
         Aqui pesa mas que en ninguna otra tarjeta: las filas de revision
         llevan titulo, nota y etiqueta de severidad en la misma linea. */
      padding: var(--card-pad);
      min-width: 0;
    }

    .chk-head {
      display: flex;
      align-items: baseline;
      justify-content: space-between;
      gap: 0.8rem;
    }

    .chk-nombre {
      font-family: var(--display);
      font-size: 16px;
      font-weight: 800;
      letter-spacing: -0.01em;
      color: var(--ink);
    }

    .chk-score {
      font-size: 13px;
      font-weight: 800;
      color: var(--ink);
      white-space: nowrap;
    }

    .chk-sub {
      margin-top: 0.15rem;
      font-size: 11.5px;
      color: var(--ink-faint);
      line-height: 1.45;
    }

    .chk-list {
      margin-top: 1rem;
      display: grid;
      gap: 0.15rem;
    }

    .chk-row {
      display: flex;
      align-items: flex-start;
      gap: 0.65rem;
      padding: 0.5rem 0;
      border-top: 1px solid rgba(15, 23, 42, 0.045);
    }

    .chk-row:first-child {
      border-top: none;
    }

    .chk-ic {
      flex-shrink: 0;
      width: 19px;
      height: 19px;
      margin-top: 1px;
      border-radius: 50%;
      display: grid;
      place-items: center;
    }

    .chk-ok .chk-ic {
      background: rgba(16, 185, 129, 0.12);
      color: #059669;
    }

    .chk-mal .chk-ic {
      background: var(--red-soft);
      color: var(--red);
    }

    .chk-aviso .chk-ic {
      background: rgba(245, 158, 11, 0.12);
      color: var(--amber);
    }

    .chk-nose .chk-ic {
      background: rgba(15, 23, 42, 0.06);
      color: var(--ink-faint);
    }

    .chk-txt {
      flex: 1;
      min-width: 0;
    }

    .chk-txt b {
      display: block;
      font-size: 12.5px;
      font-weight: 700;
      line-height: 1.35;
      color: var(--ink);
    }

    .chk-txt span {
      display: block;
      margin-top: 0.1rem;
      font-size: 11.5px;
      line-height: 1.45;
      color: var(--ink-soft);
    }

    .chk-nose .chk-txt b,
    .chk-nose .chk-txt span {
      color: var(--ink-faint);
    }

    .chk-sev {
      flex-shrink: 0;
      font-size: 9.5px;
      font-weight: 800;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: var(--red);
      background: var(--red-soft);
      border-radius: 5px;
      padding: 0.15rem 0.4rem;
      margin-top: 1px;
    }

    @media (max-width: 900px) {
      .pillars-check {
        grid-template-columns: 1fr;
      }
    }

    .growth-cta {
      margin-top: auto;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: .5rem;
      width: 100%;
      padding: .8rem 1.1rem;
      border: 1.5px solid var(--ink);
      border-radius: var(--r-btn);
      background: transparent;
      color: var(--ink);
      font-family: inherit;
      font-size: 13.5px;
      font-weight: 700;
      cursor: pointer;
      transition: background .2s var(--ease), color .2s var(--ease);
    }

    .growth-cta:hover {
      background: var(--ink);
      color: #fff;
    }

    /* Cards general */
    /* EL UNICO NIVEL DE TARJETA. Sin sombra: `--shadow-sm` es de la familia de
       marketing, y sobre el suelo gris no hace falta ninguna — es literalmente
       lo que dice tokens.css de `--canvas`: "encima de el la tarjeta blanca se
       lee sola, sin necesidad de sombra ni de borde". El filete de 1px se
       queda solo para rematar el canto. */
    .pcard {
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: 18px;
      padding: var(--card-pad);
      display: flex;
      flex-direction: column;
      min-width: 0;
    }

    .pcard .ph {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 1.2rem;
    }

    .pcard .ph .lbl {
      font-size: 12px;
      font-weight: 700;
      color: var(--ink-soft);
      text-transform: uppercase;
      letter-spacing: 0.06em;
    }

    /* ---- Pista: la ayuda que si se ve ------------------------------------
       PORTADA DEL PANEL PRO, no reinventada (tool/public/pro/index.php).
       Aqui vivia `.info`: un circulito con `title` y `cursor: help`. El
       atributo `title` tarda cerca de un segundo en aparecer, no se puede
       dar estilo y EN MOVIL NO EXISTE — o sea que en el telefono habia dos
       circulos con una "i" que al tocarlos no hacian absolutamente nada.

       El boton mide 15px porque junto a una micro-etiqueta de 12px cualquier
       cosa mayor le roba el sitio. Pero 15px no se aciertan con el pulgar, asi
       que el area que responde se amplia con un pseudoelemento invisible:
       15 + 15 + 15 = 45px de lado, justo por encima del minimo tactil. Se ve
       pequeno y se pulsa grande, que es la unica forma de tener las dos. */
    .pista {
      position: relative;
      display: inline-block;
      margin-left: .3rem;
    }

    .pista-b {
      position: relative;
      width: 15px;
      height: 15px;
      border-radius: 50%;
      border: 1px solid var(--line-control);
      background: var(--surface);
      color: var(--ink-faint);
      font: inherit;
      font-size: 9.5px;
      font-weight: 800;
      line-height: 1;
      cursor: pointer;
      display: inline-grid;
      place-items: center;
      padding: 0;
      vertical-align: middle;
      transition: color var(--d-fast) var(--ease-ui), border-color var(--d-fast) var(--ease-ui);
    }

    .pista-b:hover,
    .pista-b[aria-expanded="true"] {
      color: var(--violet);
      border-color: var(--violet);
    }

    .pista-b::after {
      content: "";
      position: absolute;
      inset: -15px;
    }

    /* ANCLADA A LA DERECHA, NO CENTRADA. Aqui difiere del Panel Pro a
       proposito: alli la pista va a media linea dentro de un <h2>, y centrar
       la nota bajo el boton es lo correcto. En el monitor las dos pistas viven
       en una `.ph` con `justify-content: space-between`, o sea SIEMPRE pegadas
       al borde derecho de la tarjeta; centrada, la mitad de la nota se salia.
       Medido a 375px con la version centrada: nota de 220px cuyo borde derecho
       caia fuera de la ventana. Anclada a la derecha cabe entera en las dos
       pistas y en las dos anchuras. */
    .pista-nota {
      position: absolute;
      z-index: 30;
      top: calc(100% + 7px);
      right: 0;
      left: auto;
      width: max-content;
      max-width: 250px;
      background: var(--ink);
      color: #fff;
      /* La familia y el resto, explicitos: la nota vive dentro de una `.ph`
         que va en mayuscula y con letra espaciada, y sin esto heredaba las dos
         cosas — una frase de prosa en versalitas. */
      font-family: var(--sans);
      font-size: 11.5px;
      font-weight: 500;
      line-height: 1.5;
      letter-spacing: 0;
      text-transform: none;
      padding: .55rem .7rem;
      border-radius: 9px;
      box-shadow: var(--shadow-pop);
      white-space: normal;
    }

    /* En un telefono la tarjeta entera mide poco mas de 300px: la nota se
       estrecha para no tocar los dos bordes a la vez. */
    @media (max-width: 560px) {
      .pista-nota {
        max-width: 220px;
      }
    }

    /* `.link-detail` nacio para un <a>. La cabecera de "Tus cuatro pilares" lo
       usa sobre un <button> —cambiar de vista es una accion, no una direccion—
       y un button trae fondo, borde y padding propios que hay que quitar. */
    .pcard .link-detail {
      font-size: 12px;
      font-weight: 700;
      color: var(--violet);
      background: none;
      border: 0;
      padding: 0;
      cursor: pointer;
      text-align: right;
      transition: color var(--d-base) var(--ease-ui);
    }

    .pcard .link-detail:hover {
      color: var(--violet-hover);
    }

    /* ---- Los cuatro pilares en el Resumen ---------------------------------
       Una fila compacta, SIEMPRE con los cuatro. El indice vivia en Resumen y
       los pilares en otra vista, asi que nunca se veian juntos; y la lista de
       Oportunidades solo nombra los pilares CON hallazgos, de modo que un pilar
       sano no aparecia en el Resumen por ninguna parte.

       Sin caja por celda: son columnas de la misma tarjeta, separadas por gap y
       por un filete. Volver a meter cada pilar en su cajita seria repetir el
       apilado de blancos que este cambio quita. */
    .res-pilares {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: var(--s-4);
    }

    .rp {
      display: grid;
      grid-template-columns: 1fr auto;
      align-items: baseline;
      gap: 0 var(--s-2);
      padding-left: var(--s-4);
      border-left: 1px solid var(--line);
      min-width: 0;
    }

    .res-pilares .rp:first-child {
      padding-left: 0;
      border-left: 0;
    }

    .rp-nom {
      font-size: var(--t-sm);
      font-weight: var(--w-fuerte);
      color: var(--ink);
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .rp-num {
      font-family: var(--display);
      font-size: var(--t-xl);
      font-weight: var(--w-negro);
      line-height: 1;
      letter-spacing: -0.02em;
      color: var(--ink);
    }

    /* El tubo va a ancho completo debajo de las dos columnas. */
    .rp-tubo {
      grid-column: 1 / -1;
      margin-top: var(--s-2);
      height: 5px;
      border-radius: var(--r-pill);
      background: var(--canvas);
      border: 1px solid var(--line);
      overflow: hidden;
    }

    .rp-tubo i {
      display: block;
      height: 100%;
      width: 0;
      border-radius: var(--r-pill);
      background: var(--ink);
      transition: width var(--d-slow) var(--ease-ui);
    }

    .rp-sub {
      grid-column: 1 / -1;
      margin-top: var(--s-2);
      font-size: var(--t-xs);
      line-height: 1.4;
      color: var(--ink-soft);
    }

    /* NO MEDIDO NO ES CERO. La raya, el tubo vacio y el motivo escrito al lado
       dicen "no lo sabemos"; un cero diria "esta mal", que es una acusacion que
       no comprobamos. Se baja el peso visual del numero, no el del texto que
       explica por que. */
    .rp--sin .rp-num {
      color: var(--ink-faint);
    }

    @media (max-width: 1080px) {
      .res-pilares {
        grid-template-columns: repeat(2, 1fr);
        row-gap: var(--s-5);
      }

      /* En dos columnas el filete de la izquierda solo separa la 2 de la 1 y
         la 4 de la 3; las impares abren fila. */
      .res-pilares .rp:nth-child(odd) {
        padding-left: 0;
        border-left: 0;
      }
    }

    @media (max-width: 560px) {
      .res-pilares {
        grid-template-columns: 1fr;
        row-gap: var(--s-4);
      }

      .res-pilares .rp {
        padding-left: 0;
        border-left: 0;
        padding-top: var(--s-4);
        border-top: 1px solid var(--line);
      }

      .res-pilares .rp:first-child {
        padding-top: 0;
        border-top: 0;
      }
    }

    /* Row Layouts */
    .panel-top-row {
      display: grid;
      grid-template-columns: 1fr 1.3fr;
      gap: 1.2rem;
      align-items: stretch;
    }

    /* Index main card */
    .index-card-content {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1.5rem;
      flex: 1;
    }

    .index-left {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 0.6rem;
    }

    .score-row {
      display: flex;
      align-items: baseline;
      gap: 0.2rem;
    }

    .score-num {
      font-size: 56px;
      font-weight: 800;
      font-family: var(--display);
      line-height: 1;
      letter-spacing: -0.04em;
      color: var(--ink);
    }

    .score-max {
      font-size: 18px;
      font-weight: 600;
      color: var(--ink-faint);
    }

    .score-badge {
      display: inline-flex;
      font-size: 11px;
      font-weight: 700;
      color: #d97706;
      background: rgba(245, 158, 11, 0.08);
      border: 1px solid rgba(245, 158, 11, 0.16);
      padding: 0.25rem 0.6rem;
      border-radius: 6px;
      width: fit-content;
      text-transform: uppercase;
      letter-spacing: 0.03em;
    }

    .score-status {
      font-size: 14.5px;
      font-weight: 700;
      color: var(--ink);
      margin-top: 0.2rem;
    }

    /* Slider indicator style */
    .slider-track {
      width: 100%;
      height: 6px;
      background: #f1f5f9;
      border-radius: 10px;
      position: relative;
      margin-top: 0.8rem;
    }

    .slider-fill {
      position: absolute;
      left: 0;
      top: 0;
      height: 100%;
      border-radius: 10px;
      background: linear-gradient(90deg, #0f172a 0%, #475569 100%);
      transition: width 1.5s var(--ease);
    }

    .slider-node {
      position: absolute;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 14px;
      height: 14px;
      background: #ffffff;
      border: 3.5px solid var(--violet);
      border-radius: 50%;
      box-shadow: 0 2px 6px rgba(130, 66, 245, 0.3);
      transition: left 1.5s var(--ease);
    }

    .index-robot-box {
      width: 90px;
      height: 90px;
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
    }

    .index-robot-box img {
      width: 100%;
      height: 100%;
      object-fit: contain;
      filter: drop-shadow(0 12px 20px rgba(15, 23, 42, 0.12));
    }

    .index-footer {
      margin-top: 1.2rem;
      padding-top: 1rem;
      border-top: 1px solid rgba(15, 23, 42, 0.05);
      font-size: 12.5px;
      color: var(--ink-soft);
      line-height: 1.5;
    }

    .index-footer b {
      color: var(--ink);
    }

    /* Circular Gauges for Pillars */
    .pillars-grid {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 0.8rem;
      flex: 1;
    }

    /* SIN CAJA. Eran cuatro tarjetas blancas dentro de una tarjeta blanca
       dentro de un panel blanco. Ahora son cuatro columnas de la misma
       tarjeta, separadas por el gap y por un filete — el mismo recurso que
       `.chk-row` ya usaba unas lineas mas arriba.

       Se fue tambien el `:hover` que levantaba una sombra: la celda no es
       pulsable, y una caja que reacciona al puntero promete un clic que no
       existe. Y con el se fue un `transition: all`, que el sistema prohibe.

       `.lead-cell` (la celda de Visibilidad, tenida de violeta) desaparece por
       falta de motivo: ningun dato la elegia — es, de hecho, el pilar de MENOR
       peso, 20% — y realzar una de las cuatro estorba justo lo que esta rejilla
       tiene que dejar hacer, que es compararlas. */
    .g-cell {
      padding: 1.1rem 0.8rem 1.1rem 1.4rem;
      border-left: 1px solid var(--line);
      text-align: center;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-between;
      position: relative;
    }

    .pillars-grid .g-cell:first-child {
      padding-left: 0.8rem;
      border-left: 0;
    }

    .marc {
      position: relative;
      width: 100%;
      max-width: 90px;
      margin: 0 auto;
    }

    .marc svg {
      width: 100%;
      display: block;
    }

    .marc .track {
      fill: none;
      stroke: #f1f5f9;
      stroke-linecap: round;
    }

    .marc .fill {
      fill: none;
      stroke-linecap: round;
      stroke-dasharray: 100 100;
      stroke-dashoffset: 100;
      transition: stroke-dashoffset 1.5s var(--ease);
    }

    .marc .mnum {
      position: absolute;
      left: 0;
      right: 0;
      top: 50%;
      transform: translateY(-50%);
      font-weight: 800;
      font-size: 19px;
      letter-spacing: -0.02em;
      font-family: var(--display);
      line-height: 1;
      color: var(--ink);
    }

    .g-cell .pn {
      font-size: 12.5px;
      font-weight: 700;
      color: var(--ink);
      margin-top: 0.5rem;
    }

    .g-cell .pd {
      font-size: 10.5px;
      color: var(--ink-soft);
      margin-top: 0.1rem;
      line-height: 1.3;
    }

    /* ---- "No pudimos medirlo", escrito donde se ve ------------------------
       El estado que este producto promete declarar —lo no medido no es cero—
       se explicaba en un atributo `title` sobre la raya del anillo. En el
       telefono ese texto NO EXISTE: quedaba una raya sin explicacion en la
       vista donde la persona busca su numero, y el motivo real estaba en otra
       vista (la lista de revisiones de Pilares).

       Ahora es una linea visible bajo el nombre del pilar. Nace vacia y sin
       ocupar sitio; solo aparece cuando hay algo que decir, asi que las
       cuatro celdas siguen alineadas cuando todo se midio. */
    .g-cell .pd-estado {
      display: none;
      margin-top: 0.35rem;
      font-size: 10.5px;
      font-weight: 700;
      line-height: 1.3;
      color: var(--ink-soft);
    }

    .g-cell .pd-estado:not(:empty) {
      display: block;
    }

    /* Pillar robots in cells */
    .g-cell .pillar-robot-img {
      width: 42px;
      height: 42px;
      object-fit: contain;
      margin-top: 0.5rem;
      filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.06));
    }

    /* Findings List */
    .finds {
      display: flex;
      flex-direction: column;
    }

    /* ---- Un hallazgo -----------------------------------------------------
       Cabecera siempre visible (título + gravedad) y ficha completa al
       abrir. La versión anterior era una fila fija con el detalle recortado
       a dos renglones por `-webkit-line-clamp`: la explicación se cortaba a
       media frase y el resto —qué te está costando, por qué pasa, la
       evidencia— ni siquiera se pintaba, aunque el backend lo mandaba. */
    .find {
      border-bottom: 1px solid rgba(15, 23, 42, 0.05);
    }

    .find:last-child {
      border-bottom: none;
    }

    .find-head {
      display: flex;
      align-items: center;
      gap: 0.85rem;
      padding: 0.85rem 0;
      cursor: pointer;
      list-style: none;
    }

    /* El triángulo por defecto de <details> desalinea la fila y no combina
       con nada; el galón de la derecha hace el mismo trabajo. */
    .find-head::-webkit-details-marker {
      display: none;
    }

    .find-head::marker {
      content: "";
    }

    .find-head:hover .ft .a {
      color: var(--violet);
    }

    .find .fi {
      width: 32px;
      height: 32px;
      border-radius: 9px;
      display: grid;
      place-items: center;
      flex-shrink: 0;
    }

    .find .ft {
      flex: 1;
      min-width: 0;
    }

    .find .ft .a {
      display: block;
      font-size: 13.5px;
      font-weight: 700;
      line-height: 1.35;
      color: var(--ink);
      transition: color 0.2s var(--ease);
    }

    .find-chevron {
      flex-shrink: 0;
      display: grid;
      place-items: center;
      color: var(--ink-faint);
      transition: transform 0.25s var(--ease);
    }

    .find[open] .find-chevron {
      transform: rotate(180deg);
    }

    .find-body {
      display: grid;
      gap: 0.8rem;
      padding: 0.1rem 0 1.1rem 3.2rem;
    }

    /* LA SANGRIA SE VA EN EL TELEFONO.
       Los 3,2rem (51,2px) alinean el cuerpo del hallazgo bajo el titulo, con el
       icono de 32px a su izquierda. En escritorio es lo correcto; en un movil
       de 375px se comia 51 de los 283px de la tarjeta y dejaba la columna de
       lectura en 232px —medido en el navegador— con la evidencia monoespaciada
       partiendose cada tres palabras. En 360px quedaba en 217.

       No es un arreglo nuevo: el Panel Pro ya resolvio esto mismo con esta
       misma regla (tool/public/pro/index.php, @media max-width 620px). El
       monitor, que es el que usa todo el mundo, se habia quedado sin ella. */
    @media (max-width: 620px) {
      .find-body {
        padding-left: 0;
      }
    }

    .fb-lbl {
      display: block;
      font-size: 9.5px;
      font-weight: 800;
      letter-spacing: 0.07em;
      text-transform: uppercase;
      color: var(--ink-faint);
      margin-bottom: 0.25rem;
    }

    .fb-txt {
      font-size: 12.5px;
      line-height: 1.6;
      color: var(--ink-soft);
    }

    /* Lo que le está costando se lee primero que lo demás. */
    .fb-row.riesgo .fb-txt {
      color: var(--ink);
      font-weight: 550;
    }

    /* La receta va destacada: es la parte accionable, el resto describe. */
    .fb-row.accion {
      padding: 0.75rem 0.9rem;
      background: var(--violet-soft);
      border-left: 2px solid var(--violet);
      border-radius: 0 10px 10px 0;
    }

    .fb-row.accion .fb-lbl {
      color: var(--violet);
    }

    .fb-row.accion .fb-txt {
      color: var(--ink);
    }

    .fb-meta {
      display: block;
      font-size: 10.5px;
      color: var(--ink-faint);
      margin-top: 0.4rem;
    }

    /* La evidencia es texto técnico (un registro DNS, una etiqueta): se
       muestra tal cual, y se parte donde sea antes que desbordar. */
    .fb-code {
      display: block;
      font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
      font-size: 11.5px;
      line-height: 1.55;
      color: var(--ink-soft);
      background: rgba(15, 23, 42, 0.04);
      border-radius: 8px;
      padding: 0.6rem 0.75rem;
      word-break: break-word;
      overflow-wrap: anywhere;
    }

    .find-vacio {
      padding: 0.9rem 0;
      font-size: 13px;
      line-height: 1.55;
      color: var(--ink-soft);
    }

    /* Las etiquetas de severidad son el componente compartido de
       assets/tokens.css: las mismas cinco que el Panel Pro y las mismas que
       la maqueta de la portada. Aquí había un cuarto juego con el defecto de
       siempre —`color: var(--amber)` sobre ámbar al 8%, 2,02:1— y solo dos
       variantes para cinco niveles.

       `.find .sev` también se va: declaraba tamaño, peso, padding y radio, y
       le ganaba por especificidad al componente, así que dejarlo era tener el
       sistema y no aplicarlo. */
    .find .sev { flex: none; }

    /* El nivel sin color propio: "bajo" y "ok" en el icono. Iba en un
       atributo `style` dentro del JS, con #94a3b8 —el gris rechazado por
       contraste— sobre gris claro. */
    .fi-neutro {
      background: var(--canvas);
      color: var(--ink-faint);
    }

    .fi-crit {
      background: var(--red-soft);
      color: var(--red);
    }

    .fi-high {
      background: rgba(245, 158, 11, 0.08);
      color: var(--amber);
    }

    /* Oportunidades de Crecimiento Card */
    .growth-list {
      display: flex;
      flex-direction: column;
      gap: 0.65rem;
    }

    /* Sin caja, igual que `.g-cell`: eran tarjetas blancas dentro de la tarjeta
       blanca de Oportunidades. Separacion por gap y filete, como `.chk-row`.
       Fuera tambien el `:hover` con sombra —no son pulsables— y con el, otro
       `transition: all`. */
    .growth-item {
      padding: 0.75rem 0 0;
      border-top: 1px solid var(--line);
      display: flex;
      align-items: center;
      gap: 0.7rem;
    }

    .growth-list .growth-item:first-child {
      padding-top: 0;
      border-top: 0;
    }

    .growth-icon {
      width: 24px;
      height: 24px;
      border-radius: 50%;
      background: var(--violet-soft);
      color: var(--violet);
      display: grid;
      place-items: center;
      flex-shrink: 0;
    }

    .growth-text {
      font-size: 12px;
      font-weight: 600;
      color: var(--ink-soft);
      line-height: 1.35;
    }

    .growth-text b {
      color: var(--ink);
      font-size: 13.5px;
      display: block;
    }

    .growth-footer {
      margin-top: auto;
      font-size: 11.5px;
      color: var(--ink-faint);
      line-height: 1.4;
      padding-top: 0.8rem;
    }

    /* Call to Action card "Da el siguiente paso" */
    .cta-card {
      background: linear-gradient(145deg, #2e1065 0%, #0f052d 100%);
      border: none;
      color: #ffffff;
      position: relative;
      overflow: hidden;
      justify-content: space-between;
    }

    .cta-card::after {
      content: '';
      position: absolute;
      top: -20%;
      right: -20%;
      width: 140px;
      height: 140px;
      background: var(--violet);
      border-radius: 50%;
      filter: blur(50px);
      opacity: 0.45;
      pointer-events: none;
    }

    .cta-card-content {
      position: relative;
      z-index: 10;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      flex: 1;
    }

    .cta-head-title {
      font-size: 11px;
      font-weight: 700;
      color: var(--violet-2);
      text-transform: uppercase;
      letter-spacing: 0.08em;
      margin-bottom: 0.4rem;
    }

    .cta-title {
      font-family: var(--display);
      font-size: 18px;
      font-weight: 800;
      line-height: 1.2;
      letter-spacing: -0.02em;
      color: #ffffff;
      margin-bottom: 0.5rem;
      max-width: 26ch;
    }

    .cta-desc {
      font-size: 11.5px;
      color: rgba(255, 255, 255, 0.65);
      line-height: 1.45;
      margin-bottom: 1rem;
      max-width: 38ch;
    }

    .cta-btn-box {
      display: flex;
      flex-direction: column;
      gap: 0.4rem;
      margin-top: auto;
      max-width: 72%;
    }

    .cta-btn {
      background: #ffffff;
      color: #2e1065;
      padding: 0.7rem 1.3rem;
      border-radius: 99px;
      font-size: 13px;
      font-weight: 700;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 0.4rem;
      box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
      transition: all 0.2s;
    }

    .cta-btn:hover {
      background: #fafafa;
      transform: translateY(-1px);
      box-shadow: 0 12px 20px rgba(0, 0, 0, 0.22);
    }

    .cta-btn span {
      transition: transform 0.2s;
    }

    .cta-btn:hover span {
      transform: translateX(3px);
    }

    .cta-subtext {
      font-size: 10.5px;
      color: rgba(255, 255, 255, 0.45);
      text-align: center;
    }

    .cta-robot {
      position: absolute;
      right: -12px;
      bottom: -8px;
      width: 145px;
      height: 145px;
      object-fit: contain;
      z-index: 5;
      filter: drop-shadow(0 12px 28px rgba(0, 0, 0, 0.45));
      pointer-events: none;
    }

    /* Aqui vivia `.footer-banner` con `.fb-item`, `.fb-icon` y `.fb-info`: la
       cuarta caja blanca del panel, y dentro cuatro argumentos de portada
       ("Datos precisos", "Basado en +50 factores") dichos a quien ya esta
       leyendo su informe. Se fue el marcado y se va su CSS. */

    /* Responsive design adjustments */
    @media (max-width: 1080px) {
      .app-grid {
        grid-template-columns: 1fr;
      }

      /* Sin `sticky` aquí: en columna única el menú se vuelve una barra
         horizontal de unos 250 px y, pegada arriba, se comía un tercio de la
         pantalla del móvil mientras se lee el informe. */
      .side {
        position: static;
        max-height: none;
        flex-direction: row;
        flex-wrap: wrap;
        border-right: none;
        border-bottom: 1px solid var(--line-strong);
        align-items: center;
        gap: 0.5rem;
      }

      .side-brand {
        width: 100%;
        padding-bottom: 0.6rem;
      }

      /* En columna unica el menu es una tira horizontal, asi que el
         `width: 100%` que un <button> necesita en el menu vertical lo
         estiraria a toda la fila y dejaria una entrada por linea. */
      .side-item {
        width: auto;
      }

      /* Los rotulos de grupo no caben en la tira y no hacen falta: el Pro los
         esconde en este mismo punto. Sin esto, "CÓMO ESTÁS" y los otros tres
         saldrian intercalados entre las entradas como si fueran una mas. */
      .side-grupo { display: none; }

      /* El #vResumen de mas arriba lleva un ID, y un ID le gana a esta
         regla por especificidad aunque venga despues y dentro de una media
         query. Resultado: en el telefono el Resumen seguia partido en dos
         columnas y la tarjeta de oportunidades quedaba en 132px de ancho, con
         el texto en columnas de seis palabras. Se repite el selector con el
         ID para que la version movil pueda ganar. */
      .panel-top-row,
      #vResumen .panel-top-row {
        grid-template-columns: 1fr;
      }

      /* Con 4 pilares una sola fila se aprieta antes que con 3: pasa a 2x2. */
      .pillars-grid {
        grid-template-columns: repeat(2, 1fr);
        row-gap: 1.4rem;
      }

      /* En 2x2 el filete separa la 2 de la 1 y la 4 de la 3; las impares
         abren fila y no llevan ninguno. */
      .pillars-grid .g-cell:nth-child(odd) {
        padding-left: 0.8rem;
        border-left: 0;
      }
    }

    @media (max-width: 768px) {
      /* En móvil la tarjeta se estrecha pero el robot seguía midiendo 145 px,
         así que el titular y el copy le pasaban por encima. Se le reserva su
         esquina y se achica un poco. */
      .cta-card-content {
        max-width: calc(100% - 88px);
      }

      .cta-robot {
        width: 112px;
        height: 112px;
      }

      /* En una sola columna el filete pasa de vertical a horizontal. */
      .pillars-grid {
        grid-template-columns: 1fr;
        gap: 0.8rem;
      }

      .pillars-grid .g-cell,
      .pillars-grid .g-cell:nth-child(odd) {
        padding: 0.8rem 0.8rem 0;
        border-left: 0;
        border-top: 1px solid var(--line);
      }

      .pillars-grid .g-cell:first-child {
        padding-top: 0;
        border-top: 0;
      }
    }

    /* ---- Movimiento reducido: solo lo que tokens.css no cubre --------------
       Aqui vivia una copia del bloque global —`*` con `transition-duration`,
       `animation-duration` y `animation-iteration-count: 1`, los tres con
       `!important`—. Desde que ese bloque esta en assets/tokens.css, que esta
       hoja carga antes que ella, la copia no anadia nada: mismas propiedades,
       mismos valores, misma bandera. Dos sitios donde arreglar lo mismo.

       Se fue tambien `.app { opacity: 1; transform: none }`: `.app` no tiene
       ni animacion ni transicion que reducir —la opacidad la pone `.app.in`, y
       de una sola vez—, asi que esa regla no anulaba nada desde hace tiempo.

       Lo que SI se queda es esto: apagar la flotacion de los robots por
       nombre. Con la regla global sola, `floaty` no se detiene —se ejecuta una
       vez a 0,001s—, y una vuelta instantanea de una curva que sube y baja
       deja al robot exactamente donde estaba pero habiendo dado un tiron. */
    @media (prefers-reduced-motion: reduce) {

      .float-robot,
      .float-robot-slow {
        animation: none;
      }
    }

/* ===== Bloque que estaba al principio del <body> ===== */
    /* ===== Flujo: bienvenida → carga → 404 ===== */
    .kv-stage {
      min-height: 100vh;
      display: none;
      align-items: center;
      justify-content: center;
      padding: clamp(7rem, 11vw, 9rem) var(--pad) clamp(2.5rem, 6vw, 5rem);
    }

    .kv-stage.on {
      display: flex;
    }

    .kv-box {
      width: 100%;
      max-width: 720px;
      text-align: center;
      animation: kvUp .5s var(--ease) both;
    }

    @keyframes kvUp {
      from {
        opacity: 0;
        transform: translateY(16px);
      }

      to {
        opacity: 1;
        transform: none;
      }
    }

    /* Aqui vivian el logotipo flotante de la esquina (.kv-brand-fixed) y la
       puerta al Panel Pro. Al quitar la puerta quedo un selector con la coma
       colgando, y esa coma se comia el @media que venia detras: ni la regla ni
       el @media llegaban a aplicarse. Ninguna de las dos clases tiene marcado
       en /monitor/, asi que se va la familia entera y con ella el destrozo. */

    .kv-box h2 {
      font-family: var(--display);
      font-weight: 800;
      font-size: clamp(1.9rem, 5vw, 3rem);
      line-height: 1.08;
      letter-spacing: -.02em;
      color: var(--ink);
      margin: 0 0 1rem;
    }

    .kv-box h2 em {
      font-style: normal;
      color: var(--violet);
    }

    .kv-box p.kv-lead {
      font-size: clamp(1rem, 2vw, 1.12rem);
      line-height: 1.65;
      color: var(--ink-soft);
      max-width: 56ch;
      margin: 0 auto 2rem;
    }

    .kv-note {
      font-size: .82rem;
      color: var(--ink-faint);
      margin-top: 1rem;
    }

    .kv-err {
      font-size: .85rem;
      font-weight: 600;
      color: var(--red);
      margin-top: .9rem;
      min-height: 1.2em;
    }

    /* Carga */
    .kv-loader-robot {
      width: clamp(110px, 22vw, 160px);
      margin: 0 auto 1.4rem;
      display: block;
      animation: kvFloat 3s ease-in-out infinite;
    }

    @keyframes kvFloat {

      0%,
      100% {
        transform: translateY(0);
      }

      50% {
        transform: translateY(-12px);
      }
    }

    .kv-bar {
      height: 6px;
      width: min(420px, 80vw);
      margin: 1.6rem auto .9rem;
      border-radius: var(--r-pill);
      background: var(--line-strong);
      overflow: hidden;
    }

    .kv-bar i {
      display: block;
      height: 100%;
      width: 0;
      border-radius: var(--r-pill);
      background: linear-gradient(90deg, #0f172a, #475569);
      transition: width .35s var(--ease);
    }

    /* ---- La barra INDETERMINADA -------------------------------------------
       Aqui solo hay una peticion en vuelo y no informa de su avance: cualquier
       porcentaje seria inventado. La version anterior ponia 15% y se quedaba
       ahi para siempre, que es lo peor de las dos cosas —parece una medida y
       ademas no se mueve—.

       Un bloque que recorre el carril dice lo unico cierto: seguimos
       esperando. Es `infinite` a proposito y no contradice la regla del
       sistema, que prohibe lo infinito DENTRO DE UNA VISTA DE DATOS: esto es
       la pantalla de carga, donde no hay ningun dato que leer. */
    .kv-bar--indet i {
      width: 38%;
      animation: kvBarrido 1.15s var(--ease-ui) infinite;
    }

    @keyframes kvBarrido {
      from {
        transform: translateX(-110%);
      }

      to {
        transform: translateX(300%);
      }
    }

    /* VA AQUI, DESPUES DE LA REGLA QUE ANULA, y no en el bloque de
       reduced-motion de mas arriba: `.kv-bar--indet i` contra
       `.kv-bar--indet i` es la misma especificidad y gana la ultima. Escrito
       arriba, el barrido seguia ganando y —con el `animation-duration: .001s`
       y `animation-iteration-count: 1` que tokens.css impone a todo— la barra
       daba un salto instantaneo hasta translateX(300%) y desaparecia por el
       borde derecho, dejando el carril vacio. Es el mismo mecanismo del que
       avisa la nota de `animation-iteration-count`, una vuelta mas.

       Con movimiento reducido el carril se llena y se queda quieto: sigue
       diciendo "esto esta en marcha" sin moverse. */
    @media (prefers-reduced-motion: reduce) {
      .kv-bar--indet i {
        animation: none;
        width: 100%;
        opacity: .45;
      }
    }

    .kv-status {
      font-size: .9rem;
      font-weight: 600;
      color: var(--ink-soft);
      min-height: 1.4em;
    }

    /* ---- Salida de la espera ---------------------------------------------
       No existia. Si la red se colgaba, la unica salida era el boton de atras
       del navegador o recargar. Es un boton de contorno y no un enlace de
       texto: cancelar es una accion, y tiene que alcanzarse con el pulgar. */
    .kv-cancelar {
      margin-top: 1.4rem;
      min-height: 44px;
      padding: .6rem 1.2rem;
      border: 1px solid var(--line-control);
      border-radius: var(--r-pill);
      background: transparent;
      color: var(--ink-soft);
      font-family: inherit;
      font-size: var(--t-sm);
      font-weight: var(--w-semi);
      cursor: pointer;
      transition: color var(--d-fast) var(--ease-ui), border-color var(--d-fast) var(--ease-ui);
    }

    .kv-cancelar:hover {
      color: var(--ink);
      border-color: var(--ink);
    }

    /* ---- Lista de espera de la herramienta ---- */
    .kv-wait {
      max-width: 440px;
      margin: 2rem auto 0;
      text-align: left;
    }

    .kv-wait-label {
      display: block;
      font-size: 13px;
      font-weight: 700;
      color: var(--ink);
      margin-bottom: .5rem;
    }

    .kv-wait-row {
      display: flex;
      gap: .6rem;
    }

    /* Mismo caso que `.kv-lead-input`: 1,28:1 contra el 3:1 de WCAG 1.4.11. */
    .kv-wait-input {
      flex: 1;
      min-width: 0;
      padding: .85rem 1.1rem;
      border-radius: var(--r-btn);
      border: 1.5px solid var(--line-control);
      background: var(--surface);
      color: var(--ink);
      font-family: inherit;
      font-size: 15px;
      transition: border-color .2s var(--ease);
    }

    .kv-wait-input:focus {
      outline: none;
      border-color: var(--violet);
    }

    .kv-wait-btn {
      flex-shrink: 0;
      padding: .85rem 1.5rem;
      border-radius: var(--r-btn);
      border: 1.5px solid transparent;
      background: var(--ink);
      color: #fff;
      font-family: inherit;
      font-weight: 700;
      font-size: 15px;
      cursor: pointer;
      transition: background .2s var(--ease), transform .2s var(--ease);
    }

    .kv-wait-btn:hover {
      background: var(--ink);
      transform: translateY(-2px);
    }

    .kv-wait-btn[disabled] {
      opacity: .6;
      cursor: progress;
      transform: none;
    }

    .kv-wait-note {
      margin-top: .7rem;
      font-size: 12.5px;
      color: var(--ink-faint);
      line-height: 1.5;
    }

    .kv-wait-err {
      margin-top: .6rem;
      font-size: 13px;
      font-weight: 600;
      color: #b91c1c;
      min-height: 1em;
    }

    .kv-wait-ok {
      display: none;
      align-items: center;
      justify-content: center;
      gap: .6rem;
      max-width: 440px;
      margin: 2rem auto 0;
      padding: 1rem 1.2rem;
      border-radius: 12px;
      background: rgba(16, 185, 129, .08);
      border: 1px solid rgba(16, 185, 129, .22);
      color: #065f46;
      font-size: 14px;
      font-weight: 650;
    }

    @media (max-width:520px) {
      .kv-wait-row {
        flex-direction: column;
      }
    }

    /* ---- Modal del Panel Pro ---- */
    .kvpro {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 90;
      background: rgba(15, 23, 42, .55);
      backdrop-filter: blur(3px);
      padding: 1.2rem;
      overflow-y: auto;
    }

    .kvpro.on {
      display: flex;
      align-items: center;
      justify-content: center;
      animation: view-in .22s ease both;
    }

    .kvpro-card {
      position: relative;
      width: 100%;
      max-width: 560px;
      margin: auto;
      background: var(--surface);
      border-radius: 22px;
      padding: 2.2rem;
      box-shadow: 0 30px 70px rgba(15, 23, 42, .28);
    }

    /* Mismo criterio que `.kv-sesion-x`: 34x34 y 1,28:1 pasan a 44x44 y
       ≈3,03:1. Los dos modales tienen que cerrarse igual de facil. */
    .kvpro-x {
      position: absolute;
      top: 1rem;
      right: 1rem;
      width: 44px;
      height: 44px;
      display: grid;
      place-items: center;
      border-radius: 50%;
      border: 1px solid var(--line-control);
      background: transparent;
      color: var(--ink-soft);
      cursor: pointer;
      transition: background .2s var(--ease), color .2s var(--ease);
    }

    .kvpro-x:hover {
      background: rgba(15, 23, 42, .05);
      color: var(--ink);
    }

    .kvpro-tag {
      display: inline-block;
      padding: .35rem .8rem;
      border-radius: 99px;
      background: rgba(130, 66, 245, .1);
      color: var(--violet);
      font-size: 12px;
      font-weight: 700;
      margin-bottom: 1rem;
    }

    .kvpro-card h2 {
      font-family: var(--display);
      font-size: clamp(1.4rem, 3.4vw, 1.9rem);
      font-weight: 800;
      letter-spacing: -.02em;
      line-height: 1.15;
      color: var(--ink);
      text-wrap: balance;
      margin-bottom: .8rem;
    }

    .kvpro-lead {
      font-size: 15px;
      line-height: 1.65;
      color: var(--ink-soft);
    }

    .kvpro-list {
      list-style: none;
      margin: 1.3rem 0 1.2rem;
      display: grid;
      gap: .6rem;
    }

    .kvpro-list li {
      position: relative;
      padding-left: 1.6rem;
      font-size: 14.5px;
      line-height: 1.55;
      color: var(--ink);
    }

    .kvpro-list li::before {
      content: "";
      position: absolute;
      left: .35rem;
      top: .55em;
      width: 6px;
      height: 6px;
      border-radius: 50%;
      background: var(--violet);
    }

    .kvpro-estado {
      padding: .9rem 1.1rem;
      border-radius: 12px;
      background: rgba(15, 23, 42, .04);
      font-size: 13.5px;
      line-height: 1.6;
      color: var(--ink-soft);
    }

    .kvpro .kv-wait,
    .kvpro .kv-wait-ok {
      margin-top: 1.3rem;
      max-width: none;
    }

    @media (max-width:560px) {
      .kvpro-card {
        padding: 1.8rem 1.3rem;
      }
    }

    @media (prefers-reduced-motion: reduce) {

      .kv-wait-btn,
      .kv-wait-input {
        transition: none;
      }

      .kv-wait-btn:hover {
        transform: none;
      }
    }

    /* ===== Hero de bienvenida (2 columnas) ===== */
    #kvWelcome {
      align-items: flex-start;
    }

    .kv-hero {
      width: 100%;
      max-width: 1240px;
      margin: 0 auto;
      text-align: left;
      animation: kvUp .5s var(--ease) both;
    }

    /* Una sola columna: el hero es centrado y el panel de ejemplo bajó
       debajo, así que ya no hay dos columnas que repartir. */
    .kv-hero-top {
      display: block;
    }

    /* ---- Hero centrado ---------------------------------------------------
       Sustituye el reparto a dos columnas. Lo unico que se puede hacer en esta
       pantalla es escribir un dominio: centrado, esa accion queda en el eje de
       lectura en vez de competir con una ilustracion al lado. */
    .kv-hero-centro {
      grid-column: 1 / -1;
      max-width: 760px;
      margin: 0 auto;
      text-align: center;
    }

    .kv-kicker {
      display: inline-flex;
      align-items: center;
      gap: .45rem;
      font-size: 11.5px;
      font-weight: 800;
      text-transform: uppercase;
      letter-spacing: .1em;
      color: var(--violet);
      background: var(--violet-soft);
      padding: .45rem .9rem;
      border-radius: 99px;
      margin-bottom: 1.3rem;
    }

    .kv-hero-centro h1 {
      margin-bottom: .8rem;
      /* Una sola linea: partirlo en dos gastaba 57px de la primera pantalla
         para no decir nada mas. */
      text-wrap: balance;
    }

    .kv-hero-centro .kv-hero-lead {
      max-width: 46ch;
      margin: 0 auto 1.7rem;
    }

    /* El campo es el protagonista: mas ancho, mas alto y con sombra propia
       para que se despegue del fondo. */
    .kv-hero-centro .kv-field {
      max-width: 640px;
      margin: 0 auto;
      box-shadow: var(--shadow-ui), 0 18px 44px -22px rgba(15, 23, 42, .3);
    }

    .kv-hero-centro .kv-field button svg {
      margin-left: .1rem;
    }

    .kv-hero-centro .kv-err:not(:empty) {
      margin-top: .8rem;
    }

    .kv-hero-centro .kv-note {
      margin-top: 1.1rem;
      display: inline-flex;
      align-items: flex-start;
      gap: .45rem;
      max-width: 56ch;
      text-align: left;
    }

    .kv-hero-centro .kv-note svg {
      flex: none;
      margin-top: .2em;
      color: var(--violet);
    }

    /* ---- Los cuatro pilares, antes de ver el panel ----------------------
       Contestan "que me van a revisar" antes de que la persona escriba nada.
       Las preguntas son las que devuelve el backend, no otras. */
    .kv-pilares-intro {
      margin-top: clamp(2rem, 4vw, 2.8rem);
      text-align: center;
    }

    .kv-pilares-tit {
      font-size: .95rem;
      color: var(--ink-soft);
      margin-bottom: 1.6rem;
    }

    .kv-pilares-tit strong {
      color: var(--violet);
      font-weight: 700;
    }

    .kv-pilares-fila {
      display: grid;
      grid-template-columns: repeat(4, minmax(0, 1fr));
      gap: clamp(.8rem, 2vw, 1.6rem);
    }

    .kv-pilar {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: .1rem;
    }

    .kv-pilar-ic {
      width: 42px;
      height: 42px;
      border-radius: 50%;
      background: var(--violet-soft);
      color: var(--violet);
      display: grid;
      place-items: center;
      margin-bottom: .6rem;
    }

    .kv-pilar b {
      font-size: 13.5px;
      font-weight: 700;
      color: var(--ink);
    }

    .kv-pilar>span:last-child {
      font-size: 11.5px;
      color: var(--ink-soft);
    }

    @media (max-width: 620px) {
      .kv-pilares-fila {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1.4rem;
      }
    }

    .kv-hero h1 {
      font-family: var(--display);
      font-weight: 800;
      font-size: clamp(2rem, 4.4vw, 3.35rem);
      line-height: 1.06;
      letter-spacing: -.025em;
      color: var(--ink);
      margin: 0 0 1.1rem;
    }

    .kv-hero h1 em {
      font-style: normal;
      color: var(--violet);
    }

    .kv-hero-lead {
      font-size: clamp(.95rem, 1.5vw, 1.03rem);
      line-height: 1.65;
      color: var(--ink-soft);
      max-width: 52ch;
      margin: 0 0 1.8rem;
    }

    /* Campo de dominio */
    /* El unico campo que rellena quien viene a probar la herramienta, y su
       borde daba 1,28:1. Con `--line-control` pasa a ≈3,03:1 y cumple 1.4.11.
       Es ademas el que mas lo necesita: el hero es todo blanco y sin borde
       visible la caja se disolvia en el fondo. */
    .kv-field {
      display: flex;
      align-items: center;
      gap: .8rem;
      background: var(--surface);
      border: 1px solid var(--line-control);
      border-radius: 18px;
      padding: .5rem .5rem .5rem 1.2rem;
      box-shadow: var(--shadow-md);
      max-width: 600px;
      transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
    }

    .kv-field:focus-within {
      border-color: var(--violet);
      box-shadow: 0 0 0 4px var(--violet-soft), var(--shadow-md);
    }

    .kv-field-ic {
      flex: none;
      color: var(--ink-faint);
      display: grid;
      place-items: center;
    }

    /* Sin la etiqueta encima, el campo es una sola fila: globo, texto y
       boton. Ya no hay dos lineas que alinear entre si, que era el origen del
       descuadre. El texto se queda a la izquierda porque un dominio se
       escribe de izquierda a derecha y verlo saltar mientras se teclea (que
       es lo que hace un input centrado) marea. */
    .kv-field-in {
      flex: 1;
      min-width: 0;
      text-align: left;
    }

    /* Visible solo para lectores de pantalla. El campo necesita nombre
       aunque no se dibuje. */
    .kv-solo-lectores {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
      border: 0;
    }

    .kv-field-in label {
      display: block;
      font-size: .8rem;
      font-weight: 700;
      color: var(--ink);
      line-height: 1.2;
    }

    .kv-field-in input {
      width: 100%;
      border: 0;
      outline: 0;
      background: transparent;
      font-family: var(--sans);
      /* 1rem = 16px, y el 16 no es estetico: por debajo de esa medida Safari
         en iPhone hace zoom al enfocar el campo y no lo deshace al salir.
         Estaba en .95rem (15,2px), justo por debajo del umbral, en el unico
         campo que tiene que rellenar quien viene a probar la herramienta. */
      font-size: 1rem;
      color: var(--ink);
      /* El input media 18px de alto: solo la linea de texto. Lo que se ve
         grande es .kv-field, que es el contenedor — su relleno no forma parte
         del campo, asi que tocar ahi no enfocaba nada. 44px iguala el area
         sensible a lo que se ve y al alto del boton de al lado. .kv-field ya
         es al menos asi de alto por el boton, de modo que no crece. */
      min-height: 44px;
      padding: 0;
      margin-top: 1px;
    }

    .kv-field-in input::placeholder {
      color: var(--ink-faint);
    }

    .kv-field button {
      flex: none;
      border: 0;
      cursor: pointer;
      background: var(--ink);
      color: #fff;
      font-family: var(--sans);
      font-weight: 700;
      font-size: .9rem;
      padding: .85rem 1.5rem;
      border-radius: 14px;
      transition: background .2s var(--ease), transform .2s var(--ease);
    }

    /* El hover no hacia nada: ponia el mismo var(--ink) que ya tenia. Solo
       subia un pixel, y en el unico boton principal de la pagina eso es poca
       respuesta. Ahora se oscurece de verdad y la sombra acompana. */
    .kv-field button:hover {
      background: #000;
      transform: translateY(-1px);
      box-shadow: 0 6px 16px rgba(15, 23, 42, .22);
    }

    .kv-field button:active {
      transform: translateY(0);
      box-shadow: 0 1px 3px rgba(15, 23, 42, .2);
    }

    .kv-field button:focus-visible {
      outline: 2px solid var(--violet);
      outline-offset: 3px;
    }

    /* La maqueta estatica del panel —.kv-preview, su anillo, sus cuatro
       pildoras y su lista de hallazgos— se reemplazo por la demo animada que
       esta mas abajo (.kv-demo). */

    /* Enlace a la landing del diagnóstico. Reemplaza las dos tarjetas que
       comparaban «Gratis, ahora» con el Panel Pro. */
    .kv-saber {
      margin-top: 1.4rem;
      text-align: center;
    }

    .kv-saber a {
      font-size: .85rem;
      font-weight: 700;
      color: var(--violet);
      text-decoration: none;
      border-bottom: 1.5px solid transparent;
      transition: border-color .2s;
    }

    .kv-saber a:hover {
      border-bottom-color: var(--violet);
    }

    @media (max-width: 980px) {
      .kv-hero-top {
        grid-template-columns: 1fr;
        gap: 2.4rem;
      }
    }

    @media (max-width: 620px) {
      .kv-field {
        flex-wrap: wrap;
      }

      .kv-field button {
        width: 100%;
      }
    }

    /* ============================================================
       DEMO EN MARCHA SOLA — fotogramas clave de CSS
       ============================================================
       Simula a alguien usando el panel. No es un video: es DOM real animado
       con @keyframes. Pesa 0 KB de descarga, es texto que Google lee, y
       actualizarlo es editar HTML en vez de volver a grabar.

       UNA SOLA LINEA DE TIEMPO de 18s, compartida por todo. Los porcentajes
       de cada @keyframes son la misma escala:
         0-14%   Resumen
         14-19%  el cursor viaja a Pilares y pulsa
         19-42%  Pilares
         42-47%  viaja a Hallazgos y pulsa
         47-58%  Hallazgos con la lista cerrada
         58-63%  pulsa el primer hallazgo
         63-88%  hallazgo abierto
         88-100% vuelve a Resumen
       Si se toca un tramo hay que mover los demas a mano: van sincronizados
       sin libreria, que es el precio de no cargar una. */

    .kv-demo {
      /* 940px dejaba 300px de margen muerto a cada lado dentro del hero de
         1240. Las referencias (attio, peec) llevan la ventana casi al ancho
         del contenido: es el producto, tiene que dominar la pantalla. */
      max-width: 1200px;
      margin: clamp(2.5rem, 6vw, 4.5rem) auto 0;
    }

    .kv-demo-marco {
      position: relative;
      border: 1px solid var(--line-strong);
      border-radius: 14px;
      overflow: hidden;
      background: var(--surface);
      box-shadow: var(--shadow-ui), 0 34px 80px -34px rgba(15, 23, 42, .4);
      text-align: left;
    }

    /* ---- El boton de pausa (WCAG 2.2.2) -----------------------------------
       Esta demo son seis animaciones de 26s en bucle infinito y no habia
       ninguna forma de pararlas. El criterio 2.2.2 lo pide literalmente: todo
       movimiento automatico que dure mas de cinco segundos y corra en paralelo
       con otro contenido tiene que poder pausarse. No es solo norma: la
       animacion esta justo debajo del titular y encima de los cuatro pilares,
       y para quien lee despacio —o le cuesta con el movimiento periferico— es
       un panel cambiando de pantalla sola mientras intenta leer.

       Va debajo del marco y no encima: flotando sobre la ventana taparia
       precisamente lo que la demo esta ensenando, y en el tramo del cursor se
       le cruzaria por delante. */
    .kv-demo-control {
      display: flex;
      justify-content: flex-end;
      margin-top: .6rem;
    }

    .kv-demo-pausa {
      display: inline-flex;
      align-items: center;
      gap: .4rem;
      /* 44px: es un control como cualquier otro y se pulsa con el pulgar. */
      min-height: 44px;
      padding: .5rem .9rem;
      border: 1px solid var(--line-control);
      border-radius: var(--r-pill);
      background: var(--surface);
      color: var(--ink-soft);
      font-family: inherit;
      font-size: var(--t-xs);
      font-weight: var(--w-semi);
      cursor: pointer;
      transition: color var(--d-fast) var(--ease-ui), border-color var(--d-fast) var(--ease-ui);
    }

    .kv-demo-pausa:hover {
      color: var(--ink);
      border-color: var(--ink);
    }

    .kv-demo-pausa svg {
      flex: none;
    }

    /* Pausa de verdad, no reinicio: `animation-play-state` congela el
       fotograma en el que va y lo reanuda donde se quedo.

       LA ESPECIFICIDAD IMPORTA. Las animaciones se declaran sobre selectores
       con atributo (`.kv-vista[data-vista="..."]` = 0,2,0) y el `animation`
       corto reinicia `animation-play-state` a `running`. El selector de abajo
       suma dos clases en el ancestro mas la de `:is()` —que pesa lo que su
       argumento mas fuerte, una clase— y da 0,3,0. Sin eso haria falta un
       `!important`, que es como se pierde el control de una hoja. */
    .kv-demo-marco.kv-demo--quieta :is(.kv-app-item,
      .kv-vista,
      .kv-a-fill,
      .kv-hall-cuerpo,
      .kv-cursor,
      .kv-cursor-eco) {
      animation-play-state: paused;
    }

    /* ---- Ventana ---- */
    .kv-app-bar {
      display: flex;
      align-items: center;
      gap: .4rem;
      padding: .6rem .85rem;
      background: #fafafa;
      border-bottom: 1px solid var(--line);
    }

    .kv-app-bar i {
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background: rgba(15, 23, 42, .13);
    }

    .kv-app-dom {
      margin-left: .6rem;
      font-size: 11.5px;
      font-weight: 600;
      color: var(--ink-soft);
    }

    .kv-app-tag {
      margin-left: auto;
      font-size: 9.5px;
      font-weight: 800;
      letter-spacing: .07em;
      text-transform: uppercase;
      color: var(--violet);
      background: var(--violet-soft);
      padding: .2rem .5rem;
      border-radius: 99px;
    }

    .kv-app-cuerpo {
      display: grid;
      grid-template-columns: 172px minmax(0, 1fr);
      min-height: 430px;
    }

    .kv-app-side {
      border-right: 1px solid var(--line);
      padding: .7rem .5rem;
      display: flex;
      flex-direction: column;
      gap: .15rem;
      background: #fcfcfd;
    }

    .kv-app-item {
      display: flex;
      align-items: center;
      gap: .5rem;
      padding: .6rem .7rem;
      border-radius: 8px;
      font-size: 13px;
      font-weight: 600;
      color: var(--ink-faint);
    }

    /* Cada pestana se enciende en su tramo. Se anima background y color en
       vez de alternar una clase por JS: sin script que mantener y el
       navegador lo resuelve en el hilo de composicion. */
    .kv-app-item[data-item="resumen"] {
      animation: kvItemResumen 26s var(--ease) infinite;
    }

    .kv-app-item[data-item="pilares"] {
      animation: kvItemPilares 26s var(--ease) infinite;
    }

    .kv-app-item[data-item="hallazgos"] {
      animation: kvItemHallazgos 26s var(--ease) infinite;
    }

/* La pestana bloqueada de la demo. Apagada y con candado: no se anima,
       porque no se pulsa. */
    .kv-app-item-bloq {
      opacity: .45;
      animation: none !important;
    }

    .kv-app-lock {
      margin-left: auto;
      flex: none;
      opacity: .8;
    }

    @keyframes kvItemResumen {

      0%,
      16% {
        background: var(--violet-soft);
        color: var(--violet);
      }

      18%,
      89% {
        background: transparent;
        color: var(--ink-faint);
      }

      91%,
      100% {
        background: var(--violet-soft);
        color: var(--violet);
      }
    }

    @keyframes kvItemPilares {

      0%,
      16% {
        background: transparent;
        color: var(--ink-faint);
      }

      18%,
      42% {
        background: var(--violet-soft);
        color: var(--violet);
      }

      45%,
      100% {
        background: transparent;
        color: var(--ink-faint);
      }
    }

    @keyframes kvItemHallazgos {

      0%,
      43% {
        background: transparent;
        color: var(--ink-faint);
      }

      46%,
      89% {
        background: var(--violet-soft);
        color: var(--violet);
      }

      91%,
      100% {
        background: transparent;
        color: var(--ink-faint);
      }
    }

    /* ---- Las vistas ----
       Se apilan en la misma celda para que la ventana no cambie de alto al
       pasar de una a otra: si creciera, la pagina daria un salto. */
    .kv-app-vista {
      position: relative;
      padding: 1.4rem 1.6rem;
    }

    .kv-vista {
      opacity: 0;
    }

    .kv-vista:not(:first-child) {
      position: absolute;
      inset: 1.4rem 1.6rem auto;
    }

    .kv-vista[data-vista="resumen"] {
      animation: kvVistaResumen 26s var(--ease) infinite;
    }

    .kv-vista[data-vista="pilares"] {
      animation: kvVistaPilares 26s var(--ease) infinite;
    }

    .kv-vista[data-vista="hallazgos"] {
      animation: kvVistaHallazgos 26s var(--ease) infinite;
    }

    @keyframes kvVistaResumen {

      0%,
      15% {
        opacity: 1;
        transform: none;
      }

      18%,
      89% {
        opacity: 0;
        transform: translateY(-6px);
      }

      92%,
      100% {
        opacity: 1;
        transform: none;
      }
    }

    @keyframes kvVistaPilares {

      0%,
      16% {
        opacity: 0;
        transform: translateY(6px);
      }

      19%,
      41% {
        opacity: 1;
        transform: none;
      }

      44%,
      100% {
        opacity: 0;
        transform: translateY(-6px);
      }
    }

    @keyframes kvVistaHallazgos {

      0%,
      44% {
        opacity: 0;
        transform: translateY(6px);
      }

      47%,
      88% {
        opacity: 1;
        transform: none;
      }

      91%,
      100% {
        opacity: 0;
        transform: translateY(-6px);
      }
    }

    /* Los anillos se dibujan cuando su vista entra, no al cargar la pagina:
       si se animaran al cargar, para cuando el visitante llegue a mirar ya
       estarian quietos y no habria visto nada. */
    .kv-a-fill {
      fill: none;
      stroke: var(--violet);
      stroke-width: 3.4;
      stroke-linecap: round;
      stroke-dasharray: 100 100;
      stroke-dashoffset: 100;
      animation: kvAnillo 26s var(--ease) infinite;
    }

    @keyframes kvAnillo {

      0%,
      17% {
        stroke-dashoffset: 100;
      }

      26%,
      43% {
        stroke-dashoffset: var(--o, 30);
      }

      46%,
      100% {
        stroke-dashoffset: 100;
      }
    }

    /* El hallazgo se despliega en su tramo. max-height y no height: el
       contenido no tiene una altura fija que conocer de antemano. */
    .kv-hall-demo .kv-hall-cuerpo {
      max-height: 0;
      opacity: 0;
      overflow: hidden;
      padding-top: 0;
      animation: kvAbrirHallazgo 26s var(--ease) infinite;
    }

    @keyframes kvAbrirHallazgo {

      0%,
      60% {
        max-height: 0;
        opacity: 0;
        padding-top: 0;
      }

      66%,
      87% {
        max-height: 220px;
        opacity: 1;
        padding-top: .6rem;
      }

      90%,
      100% {
        max-height: 0;
        opacity: 0;
        padding-top: 0;
      }
    }

    /* ---- El cursor ----
       Viaja entre la pestana que toca y el hallazgo. Las coordenadas son de
       la esquina superior izquierda del marco, asi que si cambia el ancho de
       la barra lateral (172px) hay que reajustar la X. Se sacan midiendo en el navegador, no a ojo. */
    .kv-cursor {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 5;
      pointer-events: none;
      animation: kvCursor 26s var(--ease) infinite;
    }

    .kv-cursor svg {
      display: block;
      filter: drop-shadow(0 2px 4px rgba(15, 23, 42, .35));
    }

    /* El circulo que sale al pulsar: sin el, el cursor llega y la vista
       cambia sin que se entienda que hubo un clic. */
    .kv-cursor-eco {
      position: absolute;
      top: -6px;
      left: -6px;
      width: 26px;
      height: 26px;
      border-radius: 50%;
      background: var(--violet);
      opacity: 0;
      transform: scale(.3);
      animation: kvClic 26s var(--ease) infinite;
    }

    @keyframes kvCursor {

      0%,
      10% {
        transform: translate(430px, 250px);
      }

      /* a Pilares */
      16% {
        transform: translate(63px, 116px);
      }

      19%,
      38% {
        transform: translate(63px, 116px);
      }

      /* a Hallazgos */
      45% {
        transform: translate(63px, 159px);
      }

      48%,
      57% {
        transform: translate(63px, 159px);
      }

      /* al primer hallazgo */
      63% {
        transform: translate(459px, 111px);
      }

      66%,
      86% {
        transform: translate(459px, 111px);
      }

      /* de vuelta a Resumen */
      92%,
      100% {
        transform: translate(63px, 74px);
      }
    }

    @keyframes kvClic {

      0%,
      16.5% {
        opacity: 0;
        transform: scale(.3);
      }

      18% {
        opacity: .35;
        transform: scale(1);
      }

      20%,
      45.5% {
        opacity: 0;
        transform: scale(.3);
      }

      47% {
        opacity: .35;
        transform: scale(1);
      }

      49%,
      63.5% {
        opacity: 0;
        transform: scale(.3);
      }

      65% {
        opacity: .35;
        transform: scale(1);
      }

      67%,
      92.5% {
        opacity: 0;
        transform: scale(.3);
      }

      94% {
        opacity: .35;
        transform: scale(1);
      }

      96%,
      100% {
        opacity: 0;
        transform: scale(.3);
      }
    }

    /* ---- Contenido de las vistas ---- */
    .kv-vista-tit {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: .08em;
      text-transform: uppercase;
      color: var(--ink-faint);
      margin-bottom: .7rem;
    }

    .kv-vista-sub {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: .08em;
      text-transform: uppercase;
      color: var(--ink-faint);
      margin: 1.1rem 0 .55rem;
    }

    .kv-vista-pie {
      font-size: 11px;
      color: var(--ink-faint);
      line-height: 1.5;
      margin-top: .9rem;
      padding-top: .7rem;
      border-top: 1px solid var(--line);
    }

    .kv-score-fila {
      display: flex;
      align-items: baseline;
      gap: .35rem;
    }

    .kv-score-num {
      font-family: var(--display);
      font-size: 3.2rem;
      font-weight: 800;
      letter-spacing: -.03em;
      line-height: 1;
      color: var(--ink);
    }

    .kv-score-de {
      font-size: .9rem;
      color: var(--ink-faint);
    }

    .kv-score-chip {
      margin-left: .4rem;
      font-size: 10px;
      font-weight: 800;
      color: #047857;
      background: var(--green-soft);
      padding: .2rem .5rem;
      border-radius: 99px;
    }

    .kv-score-barra {
      height: 6px;
      border-radius: 99px;
      background: #f1f5f9;
      margin-top: .7rem;
      overflow: hidden;
    }

    .kv-score-barra i {
      display: block;
      height: 100%;
      width: 71%;
      border-radius: inherit;
      background: linear-gradient(90deg, var(--violet), var(--violet-2));
    }

    .kv-op {
      display: flex;
      align-items: flex-start;
      gap: .5rem;
      padding: .45rem 0;
      border-bottom: 1px solid var(--line);
    }

    .kv-op:last-child {
      border-bottom: none;
    }

    .kv-op-pt {
      width: 7px;
      height: 7px;
      border-radius: 50%;
      margin-top: .38em;
      flex: none;
    }

    .kv-op-alto {
      background: var(--red);
    }

    .kv-op-medio {
      background: var(--amber);
    }

    .kv-op-bajo {
      background: var(--green);
    }

    .kv-op b {
      display: block;
      font-size: 13px;
      font-weight: 700;
      color: var(--ink);
    }

    .kv-op s {
      display: block;
      text-decoration: none;
      font-size: 12px;
      color: var(--ink-soft);
    }

    .kv-anillos {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: .5rem;
    }

    .kv-anillo {
      text-align: center;
    }

    .kv-anillo svg {
      width: 100%;
      max-width: 82px;
      display: block;
      margin: 0 auto;
      transform: rotate(-90deg);
    }

    .kv-a-track {
      fill: none;
      stroke: #f1f5f9;
      stroke-width: 3.4;
    }

    .kv-anillo b {
      display: block;
      margin-top: -3rem;
      margin-bottom: 1.8rem;
      font-family: var(--display);
      font-size: 1.25rem;
      font-weight: 800;
      color: var(--ink);
    }

    .kv-anillo span {
      display: block;
      font-size: 12px;
      font-weight: 700;
      color: var(--ink);
    }

    .kv-anillo s {
      display: block;
      text-decoration: none;
      font-size: 10px;
      color: var(--violet);
      font-weight: 700;
    }

    .kv-hall {
      border-bottom: 1px solid var(--line);
      padding: .55rem 0;
    }

    .kv-hall:last-child {
      border-bottom: none;
    }

    .kv-hall-cab {
      display: flex;
      align-items: center;
      gap: .5rem;
    }

    .kv-hall-ic {
      width: 20px;
      height: 20px;
      border-radius: 6px;
      display: grid;
      place-items: center;
      font-size: 11px;
      font-weight: 800;
      flex: none;
    }

    .kv-hall-alto {
      background: var(--red-soft);
      color: var(--red);
    }

    .kv-hall-medio {
      background: rgba(245, 158, 11, .1);
      color: var(--amber);
    }

    .kv-hall-cab b {
      flex: 1;
      min-width: 0;
      font-size: 13px;
      font-weight: 700;
      color: var(--ink);
      line-height: 1.35;
    }

    .kv-hall-sev {
      flex: none;
      font-size: 9.5px;
      font-weight: 800;
      text-transform: uppercase;
      color: var(--red);
      background: var(--red-soft);
      padding: .15rem .4rem;
      border-radius: 5px;
    }

    .kv-sev-medio {
      color: #b45309;
      background: rgba(245, 158, 11, .1);
    }

    .kv-hall-cuerpo {
      padding-left: 1.7rem;
      display: grid;
      gap: .5rem;
    }

    .kv-hall-lbl {
      display: block;
      font-size: 9px;
      font-weight: 800;
      letter-spacing: .07em;
      text-transform: uppercase;
      color: var(--ink-faint);
      margin-bottom: .15rem;
    }

    .kv-hall-txt {
      display: block;
      font-size: 12.5px;
      line-height: 1.5;
      color: var(--ink-soft);
    }

    .kv-hall-accion {
      background: var(--violet-soft);
      border-left: 2px solid var(--violet);
      border-radius: 0 8px 8px 0;
      padding: .5rem .65rem;
    }

    .kv-hall-accion .kv-hall-lbl {
      color: var(--violet);
    }

    .kv-hall-accion .kv-hall-txt {
      color: var(--ink);
    }

    .kv-hall-meta {
      display: block;
      font-size: 10px;
      color: var(--ink-faint);
      margin-top: .3rem;
    }

    .kv-hall-ev {
      display: block;
      font-size: 10px;
      color: var(--ink-faint);
      font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    }

    /* En movil el cursor sobra: nadie usa un puntero ahi, y a ese ancho el
       recorrido de coordenadas ya no cuadra con donde estan las cosas. */
    @media (max-width: 720px) {
      .kv-cursor {
        display: none;
      }

      .kv-app-cuerpo {
        grid-template-columns: minmax(0, 1fr);
      }

      .kv-app-side {
        flex-direction: row;
        border-right: none;
        border-bottom: 1px solid var(--line);
        overflow-x: auto;
      }
    }

    /* Quien pide menos movimiento ve el panel quieto en la primera vista, no
       una animacion mas lenta: lo que molesta es el movimiento, no su ritmo. */
    /* OJO CON LA ESPECIFICIDAD AQUI. Este bloque estaba escrito con selectores
       de una sola clase (.kv-vista, .kv-app-item) pero las animaciones se
       declaran arriba sobre .kv-vista[data-vista="..."] y
       .kv-app-item[data-item="..."], que pesan mas. Resultado: a quien pide
       menos movimiento la demo le quedaba a medias —el cursor desaparecia
       (ese si se apagaba, va por clase) y los anillos se quedaban quietos,
       mientras las vistas y las pestanas seguian pasando solas. O sea, un
       panel que cambia de pantalla con un puntero invisible pulsando botones.
       Los selectores de abajo repiten el atributo para empatar el peso. Si se
       anade una vista nueva arriba, hay que anadirla aqui tambien. */
    @media (prefers-reduced-motion: reduce) {

      .kv-cursor,
      .kv-cursor-eco,
      .kv-app-item[data-item="resumen"],
      .kv-app-item[data-item="pilares"],
      .kv-app-item[data-item="hallazgos"],
      .kv-vista[data-vista="resumen"],
      .kv-vista[data-vista="pilares"],
      .kv-vista[data-vista="hallazgos"],
      .kv-a-fill,
      .kv-hall-demo .kv-hall-cuerpo {
        animation: none;
      }

      /* La demo se queda en el fotograma del resumen: es la primera pantalla
         del recorrido y la unica que se explica sola sin las demas. */
      .kv-vista[data-vista="resumen"] {
        opacity: 1;
      }

      /* Las otras dos son absolutas y se apilan encima del resumen. Sin esto
         se veian las tres a la vez, una sobre otra. */
      .kv-vista[data-vista="pilares"],
      .kv-vista[data-vista="hallazgos"] {
        opacity: 0;
      }

      .kv-app-item[data-item="resumen"] {
        background: var(--violet-soft);
        color: var(--violet);
      }

      .kv-a-fill {
        stroke-dashoffset: var(--o, 30);
      }

      .kv-cursor {
        display: none;
      }

      /* Sin nada que pausar, el boton seria un control que no hace nada. La
         demo ya esta quieta en el fotograma del resumen. */
      .kv-demo-control {
        display: none;
      }
    }

    /* La frase que separa el diagnostico de la accion. No es un titulo ni una
       nota al pie: es la bisagra del informe, y por eso pesa mas que el texto
       de alrededor sin llegar a competir con el puntaje. */
    .kv-decision {
      margin: 0 0 1.1rem;
      font-family: var(--display);
      font-size: clamp(1rem, 2.2vw, 1.18rem);
      font-weight: 700;
      letter-spacing: -.02em;
      line-height: 1.35;
      color: var(--ink);
      padding-bottom: .95rem;
      border-bottom: 1px solid var(--line);
    }
