/* Hoja base de /app/, trozo 05 — su index enlaza los trozos en orden, y la cascada depende de él. */
/* ===== F16 P2B — VISTAS VESTIDAS (portada) ===== */
/* ==================================================================================================
   F16 P2B — LAS VISTAS NUEVAS, VESTIDAS
   --------------------------------------------------------------------------------------------------
   Este bloque va AL FINAL a propósito: P1 dejó la identidad puesta y aquí se termina de vestir lo
   que P1 dibujó a grandes rasgos —la vista de Acciones, el panel de inventario y el markdown del
   agente— sin volver a escribir la hoja. Cuando una regla de abajo pisa una de arriba se dice
   dónde y por qué; son cuatro, están todas marcadas «PISA:» y se listaron en los riesgos de la
   fase, porque una hoja que se contradice consigo misma a 400 líneas de distancia es una trampa
   para el siguiente.

   LO QUE ESTE BLOQUE AÑADE Y NO ESTABA
     1. Los ESTADOS NOMBRADOS del inventario (.est-*) dejan de ser seis palabras con dos colores y
        pasan a tener seis marcas distinguibles — SIN inventarles color semántico. Ver el cuadro.
     2. El <summary> de capacidades recupera un indicio de que se pliega: se le quitó el marcador
        nativo y no se puso nada en su sitio.
     3. El markdown: ligaduras APAGADAS en todo lo mono (razón de seguridad, no de gusto),
        subrayado en los enlaces (el color no puede ser la única señal) y scroll contenido.
     4. «Trabajando» sube al nivel de «mal»: carril propio, punteado, con el latido que ya usan los
        esqueletos. Provisional a la vista, sin fingir resultado.
     5. Densidad y objetivos táctiles de lo que P1 no llegó a tocar en el teléfono.

   CONTRASTES, CALCULADOS (sRGB, fórmula WCAG 2.x) sobre --elevada, que es el fondo de las fichas
   y las tarjetas — claro / oscuro:
     --tinta 17.98 / 13.92 · --tinta-suave 7.76 / 7.47 · --tinta-apagada 5.79 / 5.34
     --alerta 6.92 / 8.65 · --desconocido 7.60 / 7.81 · --acento 6.55 / 7.38
     --borde 4.10 / 3.56  ← el único que no es texto: es carril y borde informativo, mínimo 3:1
   Y sobre --superficie (el panel, fondo del markdown y de la vista):
     --acento 6.16 / 8.03 (enlaces) · --tinta-apagada 5.45 / 5.81 (marcadores de lista)
   Sobre --hundida (código): --tinta 14.47 / 16.67.
   Ninguna pieza de este bloque baja la opacidad de un texto que se esté leyendo.
   ================================================================================================== */

/* -- iconos nuevos, dibujados aquí y embebidos (misma técnica que P1: máscara, no imagen, para que
      el color lo ponga currentColor y no haya dos copias por tema) ------------------------------- */
:root {
  /* Galón de despliegue. Apunta a la derecha cerrado y gira 90° abierto: una sola forma para los
     dos estados, que es como se lee «esto se abre» sin dos iconos que puedan desincronizarse. */
  --mask-galon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M9.5 5 16.5 12 9.5 19'/></svg>");

  /* Tablilla EN BLANCO, con las líneas punteadas: el vacío de la vista de Acciones dice «nada
     espera tu frase», y una tablilla sin nada escrito es exactamente eso. La burbuja de --mask-vacio
     («aquí se escribe») es del hilo y allí se queda; aquí significaría otra cosa. */
  --mask-vacio-acciones: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='4.6' width='16' height='16.4' rx='3'/><rect x='8.2' y='2.6' width='7.6' height='4' rx='1.6'/><path d='M8.4 12.4h7.2' stroke-dasharray='1.7 3.4'/><path d='M8.4 16.4h4.6' stroke-dasharray='1.7 3.4'/></svg>");

  /* La equis de los campos de búsqueda. AQUÍ una equis sí es «borrar»: es un control que borra lo
     tecleado. (En .aviso.mal no lo era, y por eso allí hay una exclamación.) */
  --mask-borrar: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'><path d='M6.5 6.5 17.5 17.5'/><path d='M17.5 6.5 6.5 17.5'/></svg>");

  /* EL CARRIL PUNTEADO — trazo de --e1, hueco de --e1 — significa una cosa y solo una en toda la
     app: SIN RESOLVER. Se usa en «trabajando», en «detectado» y en «apartado», que son los tres
     sitios donde el registro todavía no ha cerrado nada.

     Y SE ESCRIBE ENTERO EN CADA SITIO, aunque duela repetirlo tres veces. La versión bonita
     —guardar la trama en un token `--trama-punteada: repeating-linear-gradient(… var(--marca) …)`
     y que cada ficha pusiera su --marca— NO FUNCIONA, y no falla de forma ruidosa sino pintando
     un color equivocado sin avisar: el valor computado de una propiedad personalizada sustituye
     sus `var()` DONDE SE DECLARA, no donde se usa. Declarada en :root, `var(--marca)` se congela
     ahí con el gris por defecto y baja ya resuelto a todos los descendientes; la ficha puede
     poner el --marca que quiera, que llega tarde.
     Cazado ejecutando: la ficha «apartado» pedía --tinta-apagada (#5e6673) y se pintaba con
     --borde (#767e8b), que era el valor que :root había horneado dentro del token. Si alguien
     vuelve a factorizar esto en una variable compartida, vuelve el mismo fallo mudo. */
}

/* ==================================================================================================
   1 · «TRABAJANDO» — al nivel de «mal», sin prometer resultado
   P1 le dio caja de trazo discontinuo y nada más, mientras «mal» llevaba carril e icono. Un aviso
   sin carril, rodeado de piezas que sí lo tienen, se lee como una pieza sin estado — y esperar SÍ
   es un estado. Lleva el carril punteado (sin resolver) y el latido que ya existe para los
   esqueletos: es el único bucle admitido de la hoja, porque solo vive mientras se espera y
   desaparece con el dato. Ni un spinner: un spinner gira igual cuando la red ya murió.
   ================================================================================================== */

/* El canal ya existe: `.aviso` trae `padding: var(--e3) var(--e4)`, así que el carril de 3px cae
   en los 16px de la izquierda sin tocar la primera letra. */
.aviso.trabajando::after {
  content: '';
  position: absolute; left: 0; top: var(--e2); bottom: var(--e2);
  width: var(--carril);
  border-radius: 0 var(--r-chip) var(--r-chip) 0;
  /* --borde: 4.10:1 claro / 3.56:1 oscuro sobre --elevada. Es marca de estado, mínimo 3:1. */
  background: repeating-linear-gradient(to bottom,
    var(--borde) 0 var(--e1), transparent var(--e1) calc(var(--e1) * 2));
  animation: esqueleto-latido 1.8s ease-in-out infinite;
}

/* ==================================================================================================
   2 · LA VISTA DE ACCIONES (vistaAcciones.js)
   ================================================================================================== */

/* La firma de la casa arriba del título. Es el mismo gesto de `.marca::before` y de `.entrada::before`
   —una raya de acento de --e5 × --carril— y es lo que ata las pantallas entre sí: se entra por la
   misma marca por la que se abre la app. Único uso de acento aquí; el resto de la cabecera es gris. */
.vista-titulos { display: block; }
.vista-titulos::before {
  content: '';
  display: block;
  width: var(--e5); height: var(--carril);
  border-radius: var(--r-chip);
  background: var(--acento);
  margin-bottom: var(--e3);
}

/* PISA: `.vista-cuerpo { gap: var(--e3) }` (sección VISTA DE ACCIONES).
   12px entre tarjetas de 16px de padding las apelmaza: se leen como filas de una tabla y no como
   piezas separadas. --e4 es además el gap del hilo, así que la app respira a un solo ritmo en las
   dos pantallas que enseñan tarjetas. */
.vista-cuerpo { gap: var(--e4); }

/* El vacío de esta vista cambia de icono (ver --mask-vacio-acciones). Redefinir la variable EN EL
   ELEMENTO basta: el ::before de P1 la lee de ahí, así que no hay que repetir ni una línea de la
   maquinaria de máscaras. */
.vista-cuerpo > .vacio { --mask-vacio: var(--mask-vacio-acciones); }

/* -- los filtros: control segmentado de verdad --------------------------------------------------
   P1 dejó el contenedor hundido y la píldora activa elevada, que es la forma correcta. Falta lo
   que hace que no baile: la cuenta con ancho reservado y alineada a la derecha, para que pasar de
   9 a 10 no ensanche la píldora y mueva a las otras tres. El :empty de P1 sigue mandando — sin
   lista fiable no se reserva sitio para un número que nadie ha comprobado. */
.filtro-cuenta {
  min-width: 2ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* La píldora activa se levanta también con un filete, no solo con la sombra: en el tema oscuro
   --sombra-1 es `none` a propósito (allí la elevación la dan luminancia y borde), así que sin esta
   línea el filtro activo se distinguía únicamente por el peso de la letra — la misma razón por la
   que P1 obliga a declarar SIEMPRE borde y sombra juntos en todo lo que flota.
   El filete lo llevan los CUATRO, transparente en los inactivos: si solo lo tuviera el activo,
   cambiar de filtro ensancharía una píldora 2px y desplazaría a las otras tres. */
/* PISA: `.filtro { border: 0 }` de más arriba. El borde transparente reserva el sitio para
   que la marca del activo no desplace a los demás. */
.filtro { border: var(--filete) solid transparent; }
.filtro.activo { border-color: var(--linea); }

/* ==================================================================================================
   3 · EL PANEL DE INVENTARIO (inventario.js)
   --------------------------------------------------------------------------------------------------
   LOS SEIS ESTADOS NOMBRADOS, Y POR QUÉ SE DISTINGUEN ASÍ
   El encargo pide que cada .est-* tenga marca clara y distinta. La tentación es darle un color a
   cada uno; es exactamente lo que no se puede hacer: «Gestionado» en verde diría «esto está bien»
   y gestionado NO significa comprobado — lo dice el propio inventario.js. Seis colores en un
   carril de 3px tampoco sobreviven a un ojo real.
   Así que la distinción se reparte en tres señales que sí se leen, y ninguna promete nada:

     estado         carril de la ficha            marca de la insignia      color
     -------------- ----------------------------- ------------------------- -----------------
     detectado      3px PUNTEADO  --borde         corta (.6em)              --tinta-suave
     revisión       3px sólido    --alerta        entera                    --alerta
     incorporado    3px sólido    --borde         entera                    --tinta-suave
     gestionado     3px sólido    --tinta-suave   entera                    --tinta  (plena)
     apartado       2px PUNTEADO  --tinta-apagada punteada                  --tinta-apagada
     desconocido    3px sólido    --desconocido   entera                    --desconocido

   Se lee: punteado = SIN RESOLVER · sólido = resuelto · más tinta = más decisión tuya · 2px =
   fuera del recorrido. El violeta de «desconocido» ni promete ni acusa, y es el único color que
   no comparte familia con nada más de la hoja. Y encima de todo esto sigue estando la PALABRA,
   que es la que de verdad informa: el color nunca va solo.
   ================================================================================================== */

/* PISA (amplía): `.cand[data-estado=…]` de la sección INVENTARIO, que solo conocía dos estados.
   Los otros cuatro caían al gris por defecto de :root y salían idénticos entre sí. */
.cand[data-estado="est-detectado"]   { --marca: var(--borde); }
.cand[data-estado="est-incorporado"] { --marca: var(--borde); }
.cand[data-estado="est-gestionado"]  { --marca: var(--tinta-suave); }
.cand[data-estado="est-apartado"]    { --marca: var(--tinta-apagada); }

/* Punteado = sin resolver. No se toca el `background: var(--marca)` de P1 para los sólidos: solo
   se sustituye en los dos estados que lo necesitan, y con el color ESCRITO (ver el aviso del
   bloque de tokens: una trama compartida en :root se lleva el gris de :root a todas partes). */
.cand[data-estado="est-detectado"]::after {
  background: repeating-linear-gradient(to bottom,
    var(--borde) 0 var(--e1), transparent var(--e1) calc(var(--e1) * 2));
}
/* Apartado además adelgaza: menos presencia para lo que está fuera del recorrido. No se apaga con
   opacidad —eso rebajaría su contraste medido—, se estrecha. --tinta-apagada: 5.79:1 / 5.34:1. */
.cand[data-estado="est-apartado"]::after {
  width: var(--carril-fino);
  background: repeating-linear-gradient(to bottom,
    var(--tinta-apagada) 0 var(--e1), transparent var(--e1) calc(var(--e1) * 2));
}

/* PISA: `.insignia.est-gestionado { color: var(--tinta-suave) }`.
   Gestionado es el único de los seis que exige una decisión explícita de la persona («marcado como
   gestionado por ti»), y por eso va en tinta plena. Sigue sin ser verde: más peso, no aprobación. */
.insignia.est-gestionado { color: var(--tinta); }

/* Marca corta = va por el primer peldaño. Es la misma idea de `.peldano` de las tarjetas: cuánto
   se ha recorrido se dice con la forma, no con el color. */
.insignia.est-detectado::after { height: .6em; }
/* Marca punteada = apartado, fuera del recorrido. La trama va en currentColor y no en --marca
   porque la insignia se pinta siempre con su propio color. */
.insignia.est-apartado::after {
  background: repeating-linear-gradient(to bottom,
    currentColor 0 var(--carril-fino), transparent var(--carril-fino) calc(var(--carril-fino) * 2));
}

/* -- la caja de la regla ------------------------------------------------------------------------
   Los tres pasos son la espina del panel entero: detectar ≠ autorizar ≠ poder hacer. Sus números
   llevan peso y tinta plena porque son la estructura del argumento, no una viñeta decorativa. */
.regla-pasos > li::marker {
  color: var(--tinta);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* -- controles del inventario -------------------------------------------------------------------
   La equis nativa de <input type="search"> es un blob gris que ignora el tema: en oscuro es la
   pieza más clara de la barra. Se reemplaza por la nuestra, con el color ya medido del texto
   apagado. Se estilan los DOS buscadores de la app, porque dejar uno con la equis del navegador y
   el otro con la nuestra sería peor que no tocar ninguno. */
.inv-buscar::-webkit-search-cancel-button,
.buscar-conv::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none;
  width: var(--e3); height: var(--e3);
  cursor: pointer;
  background-color: var(--tinta-apagada);
  -webkit-mask-image: var(--mask-borrar);  mask-image: var(--mask-borrar);
  -webkit-mask-repeat: no-repeat;          mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;            mask-size: 100% 100%;
}

/* -- el desplegable de capacidades ---------------------------------------------------------------
   P1 quitó el marcador nativo del <summary> y no puso nada en su sitio: «Qué le dejas hacer a
   Hermes» era un texto azul que no anunciaba que se abriera. El galón lo dice, y gira al abrirse
   para que el estado del pliegue se vea sin leer. */
.cand-caps-titulo {
  display: flex; align-items: center; gap: var(--e2);
}
.cand-caps-titulo::before {
  content: '';
  flex: 0 0 auto;
  width: .8em; height: .8em;
  background-color: currentColor;          /* = --acento, 6.55:1 claro / 7.38:1 oscuro sobre --elevada */
  -webkit-mask-image: var(--mask-galon);   mask-image: var(--mask-galon);
  -webkit-mask-repeat: no-repeat;          mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;            mask-size: 100% 100%;
  transition: transform var(--dur-pop) var(--curva-salida);
}
.cand-caps[open] > .cand-caps-titulo::before { transform: rotate(90deg); }

/* -- las casillas de capacidad ------------------------------------------------------------------
   Una casilla nativa mide 13px. Es el control que CONCEDE PERMISOS y se marca con el dedo tanto
   como con el ratón; fallar una concede lo que no era. Se sube a --e5 y se alinea con la primera
   línea del texto en vez de con la caja, que es donde el ojo la busca. */
.cap > input[type="checkbox"] {
  flex: 0 0 auto;
  width: var(--e5); height: var(--e5);
  margin: 0;
  /* Centrada respecto a la línea de --t-sm del código, no respecto al bloque entero: una casilla
     que flota a media altura de un texto de tres líneas parece de otro sitio. */
  align-self: flex-start;
  margin-top: calc((var(--t-sm) * var(--lh-sm) - var(--e5)) / 2);
}
/* El grupo «Preparar» y el grupo «Leer» no se tiñen: leer y preparar son ambos inocuos hasta que
   alguien teclea una frase. Lo que sí se marca es el título del grupo contra su explicación. */
.cap-grupo-titulo { letter-spacing: -.01em; }

/* ==================================================================================================
   4 · MARKDOWN (markdown.js) — lo que más se mira
   ================================================================================================== */

/* LIGADURAS APAGADAS EN TODO LO MONO. No es gusto tipográfico: es la misma regla del proyecto.
   Las fuentes de código modernas (SF Mono, JetBrains Mono, Cascadia) componen `!=` como `≠`,
   `->` como `→` y `==` como `⩵`. Aquí se COPIAN comandos y se TECLEA la frase de confirmación
   carácter a carácter: un glifo que no es el carácter que hay debajo es una mentira tipográfica,
   y en esta app eso significa un comando mal copiado o una frase que no valida. Alcanza a TODO lo
   mono, no solo al markdown. */
.mono, code, pre, kbd,
.md-codigo, .md-bloque pre, .md-bloque code,
.cap-codigo, .sug-nombre, .tarjeta .crudo,
.confirmar input, .frase-esperada code {
  font-variant-ligatures: none;
  font-feature-settings: 'liga' 0, 'clig' 0, 'calt' 0;
}

/* La tabulación de un bloque pegado desde un YAML o un Dockerfile: 8 columnas por defecto parten
   la línea y obligan a scroll lateral desde el primer nivel de sangría. */
.md-bloque pre { tab-size: 2; -moz-tab-size: 2; }

/* El scroll del bloque se queda EN el bloque. Sin esto, llegar al final de un comando largo
   arrastra la línea de tiempo entera hacia el lado en trackpad y en táctil. */
.md-bloque pre, .tarjeta .crudo { overscroll-behavior-x: contain; }

/* Los enlaces del agente llevaban SOLO color. El color no puede ser la única señal —vale para
   quien no distingue el azul del gris, y vale para cualquiera sobre --superficie, donde --acento
   está a 6.16:1 pero un ojo distraído no separa «enlace» de «negrita»—. Subrayado fino, separado
   de las descendentes, y más grueso al pasar por encima. */
.md-enlace {
  text-decoration: underline;
  text-decoration-thickness: from-font;
  text-underline-offset: 2px;
}
.md-enlace:hover { text-decoration-thickness: 2px; }

/* Los marcadores de lista son andamiaje, no contenido: van apagados (5.45:1 claro / 5.81:1 oscuro
   sobre --superficie, AA de sobra) y con cifras tabulares, porque markdown.js respeta la
   numeración de origen y una lista puede empezar en 8 y llegar a 12. */
.md-lista > li::marker {
  color: var(--tinta-apagada);
  font-variant-numeric: tabular-nums;
}

/* Una cita que contiene un párrafo heredaba el margen del párrafo DENTRO de su propio padding y
   se descolgaba de la raya del margen. */
.md-cita > :first-child { margin-top: 0; }
.md-cita > :last-child  { margin-bottom: 0; }

/* La cabecera del bloque no se desploma cuando el mensaje no declaró lenguaje (.md-lang:empty se
   oculta y solo queda el botón): altura fija de control pequeño, y el botón centrado en ella. */
.md-bloque-cabecera { min-height: var(--alto-control); }

/* Dos bloques seguidos (salida de un comando y su explicación en otro bloque) no se pegan. */
.md-bloque + .md-bloque { margin-top: var(--e4); }

/* ==================================================================================================
   5 · FOCO — lo que quedó fuera de la ronda de P1
   ================================================================================================== */

/* El galón y el texto del <summary> comparten anillo: el anillo abraza la fila entera, que es la
   zona pulsable de verdad. */
.cand-caps-titulo:focus-visible { outline-offset: 2px; }

/* Enlaces del agente y salida de emergencia: el anillo global los alcanza, pero un enlace que
   parte en dos líneas necesita que el anillo siga la forma real de cada trozo. */
.md-enlace:focus-visible, .escape a:focus-visible, .entrada a:focus-visible {
  border-radius: var(--r-menudo);
  outline-offset: 1px;
}

/* La casilla de capacidad ya ilumina su fila (P1, `.cap:has(...)`). Aquí solo se garantiza que el
   anillo nativo no se recorte contra el borde del grupo. */
.cap > input[type="checkbox"]:focus-visible { outline-offset: 1px; }

/* ==================================================================================================
   6 · MÓVIL — densidad y dedo
   P1 cubrió la barra, el hilo y los botones. Falta lo que solo existe en estas dos vistas.
   ================================================================================================== */

@media (max-width: 760px) {
  /* El control segmentado a dos columnas: cuatro píldoras del mismo tamaño se pulsan sin mirar,
     que es justo lo que no pasaba con cuatro anchos distintos envolviendo a media línea. */
  .filtros {
    display: grid; grid-template-columns: 1fr 1fr;
    width: 100%; align-self: stretch;
  }
  .filtro { justify-content: center; text-align: center; }

  /* Filtro y buscador del inventario a línea completa: a 375px compartir fila deja el buscador en
     100px, que no admite ni «postgres». */
  .inv-filtro, .inv-buscar { flex: 1 1 100%; min-width: 0; }

  /* Densidad: --e4 de padding por los cuatro lados en una pantalla de 375px se come el 9 % del
     ancho por lado. El aire vertical se conserva; el horizontal cede, que es el que escasea. */
  .cand, .regla, .tarjeta { padding: var(--e4) var(--e3); }

  /* La confianza deja de colgarse a la derecha (margin-left:auto) y baja a su propia línea: en una
     cabecera que ya envuelve, un dato empujado al margen acaba solo en una línea huérfana. */
  .cand-conf { margin-left: 0; flex-basis: 100%; }

  /* La equis de borrar, a tamaño de dedo. */
  .inv-buscar::-webkit-search-cancel-button,
  .buscar-conv::-webkit-search-cancel-button { width: var(--e5); height: var(--e5); }

  /* El bloque de código gana columnas por DENTRO, no saliéndose del margen: sacarlo a sangre lo
     metía en el canal de la espina (y dentro de la burbuja de la persona, casi contra su borde),
     y la espina es la estructura de la pantalla, no un margen negociable. Bajar el padding de
     --e3 a --e2 devuelve 8px de código sin tocar la retícula. */
  .md-bloque pre { padding: var(--e2); }
}

/* ==================================================================================================
   7 · MOVIMIENTO REDUCIDO — lo que añade este bloque
   El @media de P1 está más arriba y no puede conocer estos selectores. Se apaga aquí lo único que
   se mueve de los añadidos: el giro del galón y el latido del carril de «trabajando». En los dos
   casos la información NO estaba en el movimiento —el galón conserva su rotación final y el
   carril su trama punteada—, así que no se pierde nada al detenerlos.
   ================================================================================================== */

@media (prefers-reduced-motion: reduce) {
  .cand-caps-titulo::before { transition: none; }
  /* opacity: 1 explícito: sin él, el latido puede dejar el carril congelado a media atenuación. */
  .aviso.trabajando::after { animation: none; opacity: 1; }
}


