/* panel.css -- the one stylesheet of the panel (spec 2026-10-10-panel-pulido-visual).
 *
 * Served at /panel.css as text/css: under nosniff a stylesheet served with any other
 * type is dropped, and the panel turns into bare HTML with no error anywhere
 * (tests/test_panel_seguridad.py checks the type). Templates carry no style attribute
 * and no style element: the CSP blocks both. What varies with the data -- bar heights,
 * the fork between branches -- goes in SVG attributes, which are not styles.
 *
 * Light only, on purpose (spec §2). `only light` and not `light`: with `light` alone,
 * Chrome on Android and Samsung Internet darken the page anyway.
 *
 * Type is IBM Plex, served from /fuentes/. Plex Mono ships only 400 and 500: any
 * heavier weight on the mono would be a faux bold the browser synthesises, so headings
 * and labels are sans and the mono only carries values.
 *
 * tests/test_panel_estilo.py ties this file to what paints it, both ways it breaks
 * silently: every class of a template, of a drawing or of Python has a rule here (a pill
 * with no rule is bare text), and no two states paint alike.
 */

/* IBM Plex, served from /fuentes/ (spec 2026-10-10-panel-pulido-visual §4). Every url()
   here must be EXACTLY a name of pintar.FUENTES: a wrong one gets the 307 to /status,
   which the browser follows with the cookie, painting Inicio underneath every page.
   swap: while a font loads, the system one shows. */
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("/fuentes/plex-sans-400-b5ad7bd39f.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 500;
  font-display: swap; src: url("/fuentes/plex-sans-500-b5610af04d.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 600;
  font-display: swap; src: url("/fuentes/plex-sans-600-fff0ab3a88.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("/fuentes/plex-mono-400-e8993d9466.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500;
  font-display: swap; src: url("/fuentes/plex-mono-500-41201b658a.woff2") format("woff2"); }

:root {
  color-scheme: only light;
  /* Neutrals */
  --tinta: #14171C; --tinta-2: #59606B; --tinta-3: #8D96A5;
  --linea: #DDE1E6; --linea-suave: #EDEFF2; --linea-campo: #CDD2D9;
  --fondo: #F4F5F7; --superficie: #FFFFFF; --pasar: #F8F9FB;
  /* Menu */
  --menu: #15181E; --menu-linea: #232831; --menu-activo: #2C323D; --menu-salir: #343A45;
  --menu-texto: #C9CED6;
  /* Accent: links, focus, the primary button and the open box */
  --acento: #2B4ACB; --acento-pasar: #1C318F; --acento-tinte: #EEF1F8;
  /* Brand: the favicon's green. Only the logo carries it, and the logo IS the favicon
     file; it is written here so nobody picks it as a second accent. */
  --logo: #0f6b5f;
  /* State palettes (spec §3); the e-* rules below pick from them */
  --bien-texto: #16653F; --bien-fondo: #E3F3EA; --bien-borde: #8FCAA9; --bien-marca: #2E8A5C;
  --fallo-texto: #A2231B; --fallo-fondo: #FBE7E5; --fallo-borde: #C8402F; --fallo-caja: #FDF4F3;
  --reintento-texto: #7A4700; --reintento-fondo: #FCEFD6; --reintento-borde: #D98E04;
  --reintento-caja: #FFF8EA;
  --gris-texto: #4E5560; --gris-fondo: #ECEEF2; --gris-borde: #AEB4BE;
  /* Inicio's bars: red on a day with a failed or a retrying run */
  --barra: #B4BFDC; --barra-mal: #C8402F;
  --r-boton: 8px; --r-buscador: 10px; --r-tarjeta: 12px; --r-caja: 14px; --r-pill: 999px;
  --sombra: 0 1px 3px rgba(20, 23, 28, 0.08);
  --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  /* Everything that is tapped measures at least 44 px (spec n8n §6, still in force). */
  --tactil: 44px;
  /* The canvas box. CAJA_ALTO and CAJA_HUECO in src/panel/lienzo.py are the same two
     numbers, and the forks are drawn with them; tests/test_panel_lienzo.py ties both. */
  --caja-ancho: 184px; --caja-alto: 118px; --caja-hueco: 16px;
  /* How much of the page stays above #detalle when a box's link takes the page down to it.
     On a wide screen it has to leave the drawing in sight: a row of boxes (118), the
     frame's padding (2 × 24) and the legend under it. 240 was measured at 1280 px and it
     leaves the drawing in sight. The phone sets its own, below. */
  --detalle-arriba: 240px;
}

/* --- Base --- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; font-family: var(--sans); font-size: 14px; line-height: 1.5;
       color: var(--tinta); background: var(--fondo); }
a { color: var(--acento); text-decoration: none; }
a:hover { color: var(--acento-pasar); text-decoration: underline; }
:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
h1 { font-size: 26px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.2;
     margin: 0 0 4px; overflow-wrap: anywhere; }
h2 { font-size: 16px; font-weight: 600; margin: 28px 0 10px; }
h3 { font-size: 15px; font-weight: 600; margin: 0 0 4px; }
p { margin: 6px 0; }
code, pre, .mono { font-family: var(--mono); }
.mono { white-space: nowrap; }
pre { background: var(--superficie); border: 1px solid var(--linea); border-radius: var(--r-boton);
      padding: 10px 12px; font-size: 12px; margin: 6px 0; white-space: pre-wrap;
      overflow-wrap: anywhere; }
details summary { cursor: pointer; color: var(--acento); min-height: var(--tactil);
                  display: flex; align-items: center; }
.sub { display: block; color: var(--tinta-2); font-size: 12px; overflow-wrap: anywhere; }
.leyenda, .metricas, .latidos { color: var(--tinta-2); font-size: 12px; }
.ambar, .ambar a { color: var(--reintento-texto); font-weight: 600; }
.solo-lector { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
               overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* Shown only on a phone, where the table header it stands for is hidden (Flujos). */
.solo-movil { display: none; }

/* --- Armazón: side menu on a wide screen, a dark bar on top on a phone (spec §5.1) --- */
.armazon { display: grid; grid-template-columns: 232px minmax(0, 1fr); min-height: 100vh; }
.menu { background: var(--menu); color: var(--menu-texto); padding: 16px 12px;
        display: flex; flex-direction: column; gap: 4px; }
.menu .logo { display: flex; align-items: center; gap: 10px; min-height: var(--tactil);
              padding: 0 8px; margin-bottom: 12px; color: #FFFFFF; font-weight: 600; font-size: 15px; }
.menu .logo:hover { color: #FFFFFF; text-decoration: none; }
.menu .logo img { display: block; }
.menu ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.menu li a { display: flex; align-items: center; gap: 10px; min-height: var(--tactil);
             padding: 0 12px; border-radius: var(--r-boton); color: var(--menu-texto); }
.menu li a:hover { background: var(--menu-linea); color: #FFFFFF; text-decoration: none; }
.menu li a[aria-current="page"] { background: var(--menu-activo); color: #FFFFFF; }
.menu .salir { margin-top: auto; }
.menu .salir button { width: 100%; background: transparent; color: var(--menu-texto);
                      border-color: var(--menu-salir); }
.contenido { min-width: 0; max-width: 1120px; padding: 28px 32px 48px; }

/* --- Controls --- */
button { font: inherit; font-weight: 500; min-height: var(--tactil); padding: 0 16px;
         border: 1px solid var(--linea-campo); border-radius: var(--r-boton);
         background: var(--superficie); color: var(--tinta); cursor: pointer; }
button.primario { background: var(--acento); border-color: var(--acento); color: #FFFFFF; }
button.primario:hover { background: var(--acento-pasar); border-color: var(--acento-pasar); }
input, select { font: inherit; min-height: var(--tactil); padding: 0 12px;
                border: 1px solid var(--linea-campo); border-radius: var(--r-boton);
                background: var(--superficie); color: var(--tinta); min-width: 0; max-width: 100%; }

/* --- Pieces (spec §5.2) --- */
.tarjeta { background: var(--superficie); border: 1px solid var(--linea);
           border-radius: var(--r-tarjeta); box-shadow: var(--sombra); padding: 16px; min-width: 0; }
.filas { padding: 0; overflow: hidden; }
.fila { display: grid; gap: 4px 12px; align-items: center; min-height: var(--tactil);
        padding: 10px 16px; color: var(--tinta); border-top: 1px solid var(--linea-suave); }
.fila:first-child { border-top: 0; }
.fila:hover { background: var(--pasar); color: var(--tinta); text-decoration: none; }
.pill { display: inline-flex; align-items: center; gap: 4px; padding: 1px 10px;
        border: 1px solid transparent; border-radius: var(--r-pill); font-size: 12px;
        font-weight: 500; line-height: 18px; white-space: nowrap;
        color: var(--e-texto, var(--tinta-2)); background: var(--e-fondo, var(--fondo)); }
.pill.e-no_llego { border: 1px dashed var(--gris-borde); }
.pill.e-sin_dato { border-color: var(--gris-borde); }
.punto { display: inline-block; width: 10px; height: 10px; border-radius: 50%;
         background: var(--e-marca); }
.punto.e-no_llego { background: var(--superficie); border: 1px dashed var(--gris-borde); }
.chip { display: inline-flex; align-items: center; min-height: var(--tactil); padding: 0 14px;
        border: 1px solid var(--linea); border-radius: var(--r-pill); background: var(--superficie);
        color: var(--tinta); font-size: 13px; }
a.chip:hover { border-color: var(--acento); color: var(--acento); text-decoration: none; }
.chip.activo { background: var(--acento); border-color: var(--acento); color: #FFFFFF; }
/* The number of a state chip (spec 4a §4): part of its name, «Fallidas 1», not a badge. */
.chip-n { margin-left: 6px; font-family: var(--mono); font-size: 12px; }
.boton { display: inline-flex; align-items: center; min-height: var(--tactil); padding: 0 16px;
         border: 1px solid var(--linea-campo); border-radius: var(--r-boton);
         background: var(--superficie); color: var(--tinta); font-weight: 500; }
.boton:hover { border-color: var(--acento); color: var(--acento); text-decoration: none; }
/* A run's links out of the panel (spec 4a §7): buttons, so each one is a 44 px target. */
.enlaces { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
/* Always the colours of «Falló»: the two disk warnings are the runbook's «dos recuadros
   rojos». .aviso warns and reports no failure: the colours of «Reintentando». */
.alerta { display: block; border: 1px solid var(--fallo-borde); border-radius: var(--r-tarjeta);
          background: var(--fallo-fondo); color: var(--fallo-texto); padding: 10px 14px;
          margin: 10px 0; font-size: 13px; }
.alerta.aviso { border-color: var(--reintento-borde); background: var(--reintento-fondo);
                color: var(--reintento-texto); }
.orden { background: var(--fondo); border-color: var(--linea); font-size: 13px; }
.icono { flex: none; display: block; }
.marca { flex: none; display: block; }
.marca .fondo { fill: var(--e-marca); stroke: none; }
.marca .glifo { stroke: var(--e-glifo, #FFFFFF); }
.marca .glifo-lleno { fill: var(--e-glifo, #FFFFFF); stroke: none; }
.marca.e-no_llego .fondo { fill: none; stroke: var(--gris-borde); stroke-width: 1.5;
                           stroke-dasharray: 3 2.5; }

/* --- Search (spec §5.2): one macro, _buscador.html --- */
form.buscar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0; }
form.buscar label { flex: 1 0 100%; font-size: 12px; color: var(--tinta-2); }
.campo-buscar { position: relative; flex: 1 1 260px; min-width: 0; }
.campo-buscar .icono { position: absolute; left: 13px; top: 13px; color: var(--tinta-3);
                       pointer-events: none; }
.campo-buscar input { width: 100%; padding-left: 40px; border-radius: var(--r-buscador); }

/* --- The six states of Estado (src/panel/recorrido.py) plus `neutra` (spec §3). Each
   one sets its own tokens; pills, boxes, dots and marks read them. One rule per state
   and never grouped: tests/test_panel_estilo.py reads each block and checks no two
   are equal, because the runbook tells «No aplica» from «Sin dato». --- */
.e-bien { --e-texto: var(--bien-texto); --e-fondo: var(--bien-fondo);
          --e-borde: var(--bien-borde); --e-caja: var(--superficie); --e-marca: var(--bien-marca); }
.e-fallo { --e-texto: var(--fallo-texto); --e-fondo: var(--fallo-fondo);
           --e-borde: var(--fallo-borde); --e-caja: var(--fallo-caja); --e-marca: var(--fallo-borde); }
.e-reintentando { --e-texto: var(--reintento-texto); --e-fondo: var(--reintento-fondo);
                  --e-borde: var(--reintento-borde); --e-caja: var(--reintento-caja);
                  --e-marca: var(--reintento-borde); }
.e-no_aplica { --e-texto: var(--gris-texto); --e-fondo: var(--gris-fondo); --e-borde: var(--linea);
               --e-caja: var(--superficie); --e-marca: var(--linea); --e-glifo: var(--tinta-2); }
.e-no_llego { --e-texto: var(--gris-texto); --e-fondo: var(--superficie);
              --e-borde: var(--gris-borde); --e-caja: var(--superficie); --e-marca: var(--gris-borde); }
.e-sin_dato { --e-texto: var(--gris-texto); --e-fondo: var(--gris-fondo);
              --e-borde: var(--gris-borde); --e-caja: var(--superficie); --e-marca: var(--tinta-3); }
.e-neutra { --e-borde: var(--linea); --e-caja: var(--superficie); }

/* --- Credentials of Inicio (spec §6.1): five states, three colours, five marks --- */
.cred-ok { --e-texto: var(--bien-texto); --e-marca: var(--bien-marca); }
.cred-rechazada { --e-texto: var(--fallo-texto); --e-marca: var(--fallo-borde); }
.cred-no_comprobable { --e-texto: var(--reintento-texto); --e-marca: var(--reintento-borde); }
.cred-sin_chequeo, .cred-por_evento { --e-texto: var(--tinta-2); --e-marca: var(--tinta-3); }

/* --- Inicio's bars. Heights are SVG attributes; only their colour is here. --- */
.barras .b-ok { fill: var(--barra); }
.barras .b-mal { fill: var(--barra-mal); }
.barras .b-vacio { fill: var(--linea-suave); }

/* --- Tables: a wide one scrolls inside its box, never the page --- */
.tabla { background: var(--superficie); border: 1px solid var(--linea);
         border-radius: var(--r-tarjeta); box-shadow: var(--sombra); overflow-x: auto; }
table { border-collapse: collapse; width: 100%; }
th { font-size: 12px; font-weight: 500; color: var(--tinta-2); text-align: left;
     padding: 10px 12px; border-bottom: 1px solid var(--linea); white-space: nowrap; }
td { padding: 10px 12px; border-bottom: 1px solid var(--linea-suave); text-align: left;
     vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }

/* === Inicio (spec §6.1) === */
.cabecera { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
            gap: 12px 24px; margin-bottom: 8px; }
.cabecera form.buscar { flex: 0 1 440px; margin: 0; }
.fecha { color: var(--tinta-2); margin: 0; }
/* The disk footprint, Total, Hoy and the heartbeats: one or two grey lines, right under
   the disk warnings (spec n8n §5.1; runbook «justo debajo»). */
.franja { display: flex; flex-wrap: wrap; gap: 0 16px; margin: 4px 0 8px; }
.franja p { margin: 0; }
.fila { grid-template-columns: 170px minmax(0, 1fr) auto; }
.fila-estado { display: flex; }
.fila-quien { display: block; font-weight: 500; overflow-wrap: anywhere; }
.fila-error { display: block; font-family: var(--mono); font-size: 12px; color: var(--fallo-texto);
              overflow-wrap: anywhere; }
/* «sin aviso» (spec 4b §4.2): the error pill, smaller, on its own line under the error.
   Inline-flex after a block span starts a new line by itself. */
.pill.sin-aviso { margin-top: 4px; padding: 0 8px; font-size: 11px; line-height: 16px; }
.fila-cuando { font-family: var(--mono); font-size: 12px; color: var(--tinta-2); white-space: nowrap; }
.mas { margin: 0; }
/* A link on its own line is a tap target as tall as any button (spec §2 and §5). */
.mas a { display: inline-flex; align-items: center; min-height: var(--tactil); }
.tarjetas { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
/* The title is the card's link: 44 px tall, with the margin giving back the space so the
   card does not grow. */
.tarjeta h3 a { display: flex; align-items: center; min-height: var(--tactil); margin: -10px 0;
                color: var(--tinta); }
.pildoras { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.barras { display: block; width: 100%; height: 40px; margin: 10px 0 4px; }
.dos-columnas { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 0 24px; }
.creds { list-style: none; margin: 0; padding: 0; overflow: hidden; }
.cred { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 2px 10px;
        align-items: center; min-height: var(--tactil); padding: 10px 16px;
        border-top: 1px solid var(--linea-suave); }
.cred:first-child { border-top: 0; }
.cred-nombre { font-weight: 500; }
.cred-estado { font-size: 12px; font-weight: 500; color: var(--e-texto); text-align: right; }
.cred .sub { grid-column: 2 / -1; }
.pie { margin-top: 32px; border-top: 1px solid var(--linea); padding-top: 4px; }
.pie p { margin: 0; }
.pie a { display: inline-flex; align-items: center; min-height: var(--tactil); }
@media (max-width: 759.98px) {
  .cabecera form.buscar { flex: 1 1 100%; }
  .fila { grid-template-columns: minmax(0, 1fr) auto; }
  .fila-cuerpo { grid-column: 1 / -1; grid-row: 2; }
  .dos-columnas, .tarjetas { grid-template-columns: minmax(0, 1fr); }
}

/* === Ejecuciones (spec §6.2) === */
.filtros { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 12px 0 8px; }
.filtros-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 12px; margin: 0 0 12px; }
.filtros-form label { display: flex; flex-direction: column; gap: 2px; font-size: 12px;
                      color: var(--tinta-2); }
tr.dia th { background: var(--fondo); font-family: var(--mono); font-size: 12px; font-weight: 500;
            color: var(--tinta); }
td.hora a { display: inline-flex; align-items: center; min-height: var(--tactil);
            font-family: var(--mono); }
td.quien, td.que { overflow-wrap: anywhere; }
/* The dots of a run, joined by a thin line drawn behind them. */
.puntos { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
          background: linear-gradient(var(--linea), var(--linea)) center / 100% 1px no-repeat; }
td.tardo { font-family: var(--mono); white-space: nowrap; color: var(--tinta-2); }
td.abrir a { display: inline-flex; align-items: center; justify-content: center;
             min-width: var(--tactil); min-height: var(--tactil); color: var(--tinta-3); }
td.abrir a:hover { color: var(--acento); }
.mas-antiguas { margin: 12px 0; }
@media (max-width: 759.98px) {
  /* The same table, a card per row: the header hides and the cells stack, each by its
     class. Everything of the desktop row stays except «Abrir»: the hour is the link, and
     its ::after stretches over the whole card so a tap anywhere on it opens the run. The
     other cells hold no link or control; if one ever does, it needs position: relative
     and z-index: 1 or this overlay swallows its taps. */
  .lista { background: transparent; border: 0; box-shadow: none; overflow: visible; }
  .lista table, .lista tbody, .lista tr, .lista td, .lista th { display: block; }
  .lista thead { display: none; }
  .lista tr.dia th { padding: 16px 0 6px; background: transparent; border: 0; }
  .lista tbody tr:not(.dia) { display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
                              gap: 4px 10px; align-items: center; background: var(--superficie);
                              border: 1px solid var(--linea); border-radius: var(--r-tarjeta);
                              box-shadow: var(--sombra); padding: 4px 12px 10px; margin-bottom: 8px; }
  .lista td { padding: 0; border: 0; }
  .lista td.hora { grid-column: 1; grid-row: 1; }
  .lista td.estado { grid-column: 2 / 4; grid-row: 1; justify-self: end; }
  .lista td.quien, .lista td.que { grid-column: 1 / -1; }
  .lista td.pasos { grid-column: 1 / 3; }
  .lista td.tardo { grid-column: 3; justify-self: end; }
  .lista td.abrir { display: none; }
  .lista tbody tr:not(.dia) { position: relative; }
  .lista td.hora a::after { content: ""; position: absolute; inset: 0; }
  .filtros-form label { flex: 1 1 140px; }
  .filtros-form select { width: 100%; }
}

/* === Una ejecución y el lienzo (spec §6.3) === */
.miga { font-size: 12px; color: var(--tinta-2); }
/* 44 px to tap, but the negative margin keeps the breadcrumb line as tall as its text. */
.miga a { display: inline-flex; align-items: center; vertical-align: middle;
          min-height: var(--tactil); margin: -14px 0; }
/* The name in a run's header opens the person page (spec ficha §4). A 26 px title is not
   44 px tall: the margin keeps the line as it was while the target grows. */
h1 a { display: inline-flex; align-items: center; min-height: var(--tactil); margin: -9px 0;
       overflow-wrap: anywhere; }
.id { font-family: var(--mono); overflow-wrap: anywhere; }
.resumen { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
pre.error { background: var(--fallo-fondo); border-color: var(--fallo-borde); color: var(--fallo-texto); }
/* With no «Copy» button, one tap selects the whole order (spec §2 and §5.2). */
.orden code { -webkit-user-select: all; user-select: all; }
/* A white frame with a dot grid. On a wide screen it scrolls sideways inside its frame
   (Docencia is ~1,700 px wide): the page never does. */
.lienzo { overflow-x: auto; background-color: var(--superficie);
          background-image: radial-gradient(circle, var(--linea) 1px, transparent 1.5px);
          background-size: 16px 16px; border: 1px solid var(--linea);
          border-radius: var(--r-tarjeta); padding: 24px; }
.lienzo-fila { display: flex; align-items: center; width: max-content; }
.columna { display: flex; flex-direction: column; gap: var(--caja-hueco); }
.flecha, .horquilla { flex: none; }
.flecha-abajo { display: none; }
.flecha path, .horquilla path, .flecha-abajo path { stroke: var(--gris-borde); stroke-width: 1.5;
                                                     fill: none; }
.caja { display: flex; flex-direction: column; gap: 2px; width: var(--caja-ancho);
        height: var(--caja-alto); padding: 8px 12px; overflow: hidden; background: var(--e-caja);
        border: 1.5px solid var(--e-borde); border-radius: var(--r-caja); box-shadow: var(--sombra);
        color: var(--tinta); }
a.caja:hover { border-color: var(--acento); color: var(--tinta); text-decoration: none; }
.caja.abierta { outline: 3px solid var(--acento); outline-offset: 2px; }
.caja.e-no_llego { border-style: dashed; }
.caja.e-no_llego > * { opacity: .5; }
.caja .cabeza { display: flex; align-items: center; justify-content: space-between;
                min-height: 22px; color: var(--tinta-2); }
.caja .etiqueta { font-weight: 600; font-size: 13px; line-height: 1.3; white-space: nowrap;
                  overflow: hidden; text-overflow: ellipsis; }
.caja .clave { font-family: var(--mono); font-size: 11px; line-height: 1.25;
                color: var(--tinta-3); }
.caja .estado { font-size: 11px; line-height: 1.25; font-weight: 600; color: var(--e-texto); }
.caja .texto { font-size: 12px; line-height: 1.25; color: var(--tinta-2); white-space: nowrap;
               overflow: hidden; text-overflow: ellipsis; }
/* «No aplica»: nothing to do there, so all its text goes grey (spec §3). After the rules
   above, which give the rótulo and the text their own colours. */
.caja.e-no_aplica, .caja.e-no_aplica .estado, .caja.e-no_aplica .texto { color: var(--tinta-3); }
.caja .cuentas { display: flex; gap: 6px; margin-top: auto; }
.cuenta-bien, .cuenta-mal { font-family: var(--mono); }
/* The mark is smaller than its 22 px attributes: it sits inside a 12 px pill. */
.cuenta-bien .marca, .cuenta-mal .marca { width: 14px; height: 14px; }
.leyenda-estados { list-style: none; display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 0;
                   margin: 10px 0; font-size: 12px; color: var(--tinta-2); }
.leyenda-estados li { display: flex; align-items: center; gap: 6px; }
.leyenda-estados .marca { width: 16px; height: 16px; }
.detalle { margin-top: 16px; }
.detalle h2 { margin-top: 0; }
#detalle { scroll-margin-top: var(--detalle-arriba); }
dl.valores { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 4px 16px;
             font-size: 13px; margin: 8px 0; }
dl.valores dt { color: var(--tinta-2); }
dl.valores dd { margin: 0; font-family: var(--mono); overflow-wrap: anywhere; }
@media (max-width: 480px) {
  dl.valores { grid-template-columns: minmax(0, 1fr); }
  dl.valores dd { margin-bottom: 6px; }
}
@media (max-width: 759.98px) {
  /* Top to bottom: at 360 px a row holds a box and a half, and the red one would sit off
     the screen. Branches of one column share the width; a box grows as tall as it needs. */
  :root { --detalle-arriba: 16px; }
  .lienzo { padding: 16px; }
  .lienzo-fila { flex-direction: column; align-items: stretch; width: auto; }
  .flecha, .horquilla { display: none; }
  .flecha-abajo { display: block; flex: none; margin: 6px auto; }
  .columna { flex-direction: row; gap: 8px; }
  .columna > .caja { flex: 1 1 0; }
  .caja { width: auto; min-width: 0; height: auto; min-height: var(--caja-alto); }
  .caja .etiqueta, .caja .texto { white-space: normal; }
}

/* === La ficha por persona (spec 2026-10-11-panel-ficha-persona §3) === */
/* One column. A long e-mail breaks anywhere instead of pushing the page sideways. */
.ficha h1 { overflow-wrap: anywhere; }
.ficha-fuera { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 12px 0; }
.ficha-fuera p { flex: 1 1 260px; margin: 0; color: var(--tinta-2); }
.ficha-fuera form { margin: 0; }
.ficha-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.ficha-fila { display: grid; gap: 4px; }
.ficha-fila p { margin: 0; }
.ficha-arriba { display: flex; flex-wrap: wrap; align-items: center;
                justify-content: space-between; gap: 4px 8px; }
/* The date is the row's link: 44 px tall, with the margin giving the space back. */
.ficha-cuando { display: inline-flex; align-items: center; min-height: var(--tactil);
                margin: -10px 0; font-family: var(--mono); font-size: 12px; }
.ficha-quien { font-weight: 500; overflow-wrap: anywhere; }
.ficha-que { color: var(--tinta-2); overflow-wrap: anywhere; }
/* A box's text can be a whole error line (rule 1): here a pill wraps, or one row would
   scroll the page sideways at 360 px. */
.ficha-cajas { margin: 4px 0 0; }
.ficha-cajas .pill { white-space: normal; overflow-wrap: anywhere; }
@media (max-width: 759.98px) {
  /* The same stretched link as the cards of Ejecuciones (fbb5d0a): the date's ::after
     covers the whole card, so a tap anywhere on it opens the run. No other link or
     control lives inside a row; one that does needs position: relative and z-index: 1
     or this overlay swallows its taps. */
  .ficha-fila { position: relative; }
  .ficha-cuando::after { content: ""; position: absolute; inset: 0; }
}

/* === Flujos, Accesos y Entrar (spec §6.4, §6.5) === */
.flujo { margin-bottom: 36px; }
.flujo h2 { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.modo { font-weight: 500; }
/* The note under a drawing (spec 4a §6): what the drawing alone would get wrong. */
.nota-flujo { color: var(--tinta-2); font-size: 13px; margin: 8px 0 0; }
.formularios { margin-top: 12px; }
.formularios td.nombre { font-weight: 500; }
.formularios td.source { font-size: 12px; color: var(--tinta-2); }
.formularios td.cuenta, .formularios td.ultima { font-size: 12px; }
.formularios td.lleva-aviso { color: var(--tinta-2); }
.suelta { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center;
          padding: 24px 16px; }
main.entrar { width: 100%; max-width: 360px; padding: 28px 24px; }
.logo-entrar { display: flex; align-items: center; gap: 12px; font-size: 22px; margin: 0 0 20px; }
.logo-entrar img { display: block; }
form.entrar { display: flex; flex-direction: column; gap: 14px; }
form.entrar label { display: flex; flex-direction: column; gap: 4px; font-size: 13px;
                    color: var(--tinta-2); }
form.entrar input { width: 100%; }

/* --- Phone (< 760 px): the menu is a dark bar on top; nothing scrolls the page sideways. --- */
@media (max-width: 759.98px) {
  .armazon { grid-template-columns: minmax(0, 1fr); }
  /* Two rows at most: the logo and «Salir» on top, the four links under them on one
     line. If they do not fit, that line scrolls inside the bar, never the page. The
     markup order stays; the areas place each piece. */
  .menu { display: grid; grid-template-columns: minmax(0, 1fr) auto;
          grid-template-areas: "logo salir" "lista lista"; align-items: center; gap: 0 8px;
          padding: 6px 8px; border-bottom: 1px solid var(--menu-linea); }
  .menu .logo { grid-area: logo; margin: 0; padding: 0 4px; justify-self: start; }
  .menu .logo span { display: none; }
  .menu ul { grid-area: lista; flex-direction: row; flex-wrap: nowrap; overflow-x: auto;
             min-width: 0; }
  .menu li { flex: none; }
  /* Sized so the four links fit on a 390 px phone without scrolling the bar. */
  .menu li a { padding: 0 7px; gap: 5px; white-space: nowrap; font-size: 13px; }
  .menu .salir { grid-area: salir; margin: 0; }
  .menu .salir button { width: auto; }
  .contenido { padding: 16px 16px 32px; }
}
/* Below 380 px even the tight links do not fit with their icons: the words stay, the
   icons go, so «Accesos» is never hidden behind a scroll nobody notices. */
@media (max-width: 379.98px) {
  .menu li a svg { display: none; }
}
@media (max-width: 759.98px) {
  /* The same table, a card per form, in two lines: the name and its source, then the three
     numbers. The header hides, so the numbers say what they are. A zero-height pseudo
     element forces the break between the two lines. */
  .formularios { background: transparent; border: 0; box-shadow: none; overflow: visible; }
  .formularios table, .formularios tbody, .formularios td { display: block; }
  .formularios thead { display: none; }
  .formularios tr.formulario { display: flex; flex-wrap: wrap; align-items: baseline;
                               gap: 2px 10px; background: var(--superficie);
                               border: 1px solid var(--linea); border-radius: var(--r-tarjeta);
                               box-shadow: var(--sombra); padding: 10px 12px; margin-bottom: 8px; }
  .formularios tr.formulario::before { content: ""; order: 3; flex-basis: 100%; height: 0; }
  .formularios td { padding: 0; border: 0; }
  .formularios td.nombre { order: 1; flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
  .formularios td.source { order: 2; min-width: 0; white-space: normal; text-align: right;
                           overflow-wrap: anywhere; }
  .formularios td.cuenta { order: 4; }
  .formularios td.ultima { order: 5; }
  .formularios td.lleva-aviso { order: 6; }
  /* The label is a span in the HTML, never a content: here. Written in the sheet, the
     label kept the default period over the count of 90 (spec 4a §5). */
  .formularios td.cuenta .solo-movil { display: inline; font-family: var(--sans);
                                       color: var(--tinta-2); }
  .formularios td.ultima::before { content: "· la última: "; font-family: var(--sans);
                                   color: var(--tinta-2); }
  .formularios td.lleva-aviso::before { content: "· aviso: "; }
  /* Under 16 px, Safari on iOS zooms in on focus and the page scrolls sideways. */
  input, select { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }
