/* Pipetflow — pensado para leerse con guantes, a un brazo de distancia.
 *
 * Reglas de la gama:
 *   1. El modo oscuro es el principal (mesón en penumbra, sala de microscopía).
 *   2. Los seis canales (--azul --verde --naranja --rojo --lejano --infrarrojo) son DATOS:
 *      aproximan la emisión real del fluoróforo y NO cambian con el tema.
 *   3. Los colores de estado (--ok --aviso --error) van menos saturados que los
 *      canales, para que un distintivo verde no se confunda con un Alexa 488.
 *   4. Todo texto sobre su fondo pasa 4.5:1 (AA); los bordes de los controles
 *      pasan 3:1 contra el relleno y contra lo que tienen al lado.
 */
:root {
  color-scheme: dark;

  --fondo: #0A0E14;          /* casi negro, azulado: no tiñe los canales */
  --fondo-2: #131A24;        /* tarjetas */
  --fondo-3: #1C2532;        /* campos, chips, rellenos hundidos */
  --borde: #2C3848;          /* separación entre superficies */
  --borde-fuerte: #64758C;   /* borde de los controles (3:1) */
  --texto: #E8EEF6;
  --texto-2: #A9B8CA;
  --texto-3: #8798AC;

  --marca: #2FD8EF;          /* cian: el único hueco libre entre los 5 canales */
  --marca-oscura: #0E7F94;
  --sobre-marca: #04141A;    /* texto encima de la marca */

  --ok: #35D68F;
  --aviso: #FFB528;
  --error: #FF7070;

  /* Canales de fluorescencia — emisión aproximada, iguales en los dos temas */
  --azul: #4D8DFF;           /* DAPI / Hoechst, 461 nm */
  --verde: #25EE72;          /* Alexa 488 / FITC / GFP, 519 nm */
  --naranja: #FF8A2E;        /* Alexa 555 / Cy3 / TRITC, 565-576 nm: el «rojo» del 561 */
  --rojo: #FF3B3B;           /* Alexa 594 / Texas Red, 610 nm */
  --lejano: #F35BD8;         /* Alexa 647 / Cy5: magenta convenido, 668 nm */
  --infrarrojo: #8FA6C4;     /* IRDye 680RD / 800CW: no se ve, lo pinta el escáner */

  /* Tintes y líneas derivados (sin color-mix, para que no dependan del motor) */
  --marca-tenue: rgba(47, 216, 239, .07);
  --marca-suave: rgba(47, 216, 239, .13);
  --marca-linea: rgba(47, 216, 239, .34);
  --ok-suave: rgba(53, 214, 143, .13);
  --ok-linea: rgba(53, 214, 143, .34);
  --aviso-suave: rgba(255, 181, 40, .12);
  --aviso-linea: rgba(255, 181, 40, .32);
  --error-suave: rgba(255, 112, 112, .12);
  --error-linea: rgba(255, 112, 112, .34);
  /* Lo preparado en el laboratorio (citrato, bloqueo): su propio tono, lila. */
  --preparado: #B79CFF;
  --preparado-suave: rgba(183, 156, 255, .10);
  --preparado-linea: rgba(183, 156, 255, .40);
  --velo-fondo: rgba(2, 5, 9, .68);
  --anillo-punto: rgba(0, 0, 0, .25);   /* el punto de canal ya destaca sobre el fondo oscuro */

  --barra: rgba(10, 14, 20, .90);
  --nav: rgba(19, 26, 36, .96);

  --radio: 14px;
  --sombra: 0 6px 22px rgba(0, 0, 0, .45);
  --seguro-abajo: env(safe-area-inset-bottom, 0px);

  --tipo: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", sans-serif;
  --tipo-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* ===================================================================== */
/*  Modo claro: el PC del laboratorio tiene luz de techo y el oscuro      */
/*  cansa. Mismos nombres, mismos papeles, distinta luminancia.           */
/* ===================================================================== */
@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;

    --fondo: #F4F7FA;
    --fondo-2: #FFFFFF;
    --fondo-3: #EAEFF5;
    --borde: #D4DDE7;
    --borde-fuerte: #717F92;
    --texto: #0E1620;
    --texto-2: #46566A;
    --texto-3: #586A80;

    --marca: #086E80;
    --marca-oscura: #05505E;
    --sobre-marca: #FFFFFF;

    --ok: #0C6E4A;
    --aviso: #7E5200;
    --error: #B52D2A;

    --marca-tenue: rgba(8, 110, 128, .06);
    --marca-suave: rgba(8, 110, 128, .11);
    --marca-linea: rgba(8, 110, 128, .38);
    --ok-suave: rgba(12, 110, 74, .10);
    --ok-linea: rgba(12, 110, 74, .36);
    --aviso-suave: rgba(126, 82, 0, .10);
    --aviso-linea: rgba(126, 82, 0, .34);
    --error-suave: rgba(181, 45, 42, .09);
    --error-linea: rgba(181, 45, 42, .34);
    --preparado: #6A4BC4;
    --preparado-suave: rgba(106, 75, 196, .07);
    --preparado-linea: rgba(106, 75, 196, .36);
    --velo-fondo: rgba(14, 22, 32, .42);
    --anillo-punto: rgba(0, 0, 0, .48);   /* sobre blanco, el verde y el naranja necesitan borde */

    --barra: rgba(244, 247, 250, .90);
    --nav: rgba(255, 255, 255, .96);

    --sombra: 0 6px 22px rgba(14, 22, 32, .14);
  }
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* 106,25 % = 17 px con la letra normal; en porcentaje para que el tamaño del
   sistema o del navegador llegue a la página (TextoSistema lo ajusta). */
html { font-size: 106.25%; }
body { font-size: 1rem; }
html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--fondo); color: var(--texto);
  font-family: var(--tipo);
  line-height: 1.5;
  font-feature-settings: "tnum";     /* cifras de ancho fijo en toda la app */
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

body { display: flex; flex-direction: column; min-height: 100dvh; }

/* Foco visible para quien navega con teclado (el mesón también tiene teclado) */
:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---------- cabecera ---------- */
header.barra {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 12px;
  padding: 13px 16px;
  padding-top: calc(13px + env(safe-area-inset-top, 0px));
  background: var(--barra); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--borde);
}
header.barra h1 { font-size: 1.12rem; margin: 0; font-weight: 600; letter-spacing: -.015em; }
header.barra .sub { font-size: .8rem; color: var(--texto-3); margin-top: -1px;
  /* Una línea en todas las pantallas: la frase del día ocupaba 7 en Inicio. */
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
header.barra .crece { flex: 1; min-width: 0; }
/* Con cuatro botones a la derecha, el título se recorta en vez de montarse
   sobre ellos, y los botones son cuadrados y más estrechos. */
header.barra h1 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
header.barra { gap: 8px; }
header.barra > button.chico { flex: none; width: 42px; min-width: 42px; padding: 0; justify-content: center; }

.logo {
  width: 32px; height: 32px; flex: 0 0 32px;
  display: grid; place-items: center;
  background: var(--marca);   /* logo C · Placa (2026-10-01): placa plana, sin degradado */
  border-radius: 10px; color: var(--sobre-marca);
  overflow: hidden;
}
.logo svg { width: 100%; height: 100%; display: block; }

/* ---------- contenido ---------- */
main {
  flex: 1; padding: 16px 16px 100px 16px;
  max-width: 900px; width: 100%; margin: 0 auto;
}
.pantalla { display: none; animation: entra .18s ease-out; }
.pantalla.activa { display: block; }
@keyframes entra { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

h2 { font-size: 1.42rem; margin: 0 0 5px; letter-spacing: -.022em; font-weight: 600; }
h3 { font-size: 1.02rem; margin: 24px 0 10px; color: var(--texto-2); font-weight: 600; }
p.guia { color: var(--texto-2); font-size: .93rem; margin: 0 0 18px; max-width: 62ch; }

/* ---------- tarjetas ---------- */
.tarjeta {
  background: var(--fondo-2); border: 1px solid var(--borde);
  border-radius: var(--radio); padding: 16px; margin-bottom: 12px;
}
.tarjeta.pulsable { cursor: pointer; transition: border-color .15s, transform .1s; }
.tarjeta.pulsable:active { transform: scale(.995); border-color: var(--marca-oscura); }

.fila { display: flex; align-items: center; gap: 12px; }
.fila.entre { justify-content: space-between; }
.fila.envuelve { flex-wrap: wrap; }
.crece { flex: 1; min-width: 0; }
.apilado { display: flex; flex-direction: column; gap: 10px; }

.rejilla-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.rejilla-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
@media (max-width: 420px) { .rejilla-3 { grid-template-columns: 1fr 1fr; } }

/* Comunidad: pestañas segmentadas, cabecera del grupo y filas de lista. */
.segmentos {
  display: flex; gap: 2px; padding: 3px; margin-bottom: 14px;
  background: var(--fondo-2); border: 1px solid var(--borde); border-radius: 12px;
}
.segmentos button {
  flex: 1; min-height: 34px; padding: 6px 4px; border: none; border-radius: 9px;
  background: none; color: var(--texto-2); font-size: .82rem; font-weight: 500;
}
.segmentos button.activa { background: var(--marca-suave); color: var(--marca); font-weight: 650; }
button .cuenta { display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 999px; background: var(--error);
  color: #fff; font-size: .72rem; line-height: 18px; text-align: center; vertical-align: middle; }
.segmentos .cuenta {
  display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--marca); color: var(--sobre-marca); font-size: .72rem; line-height: 18px; text-align: center;
}
.cabecera-lab {
  padding: 16px; margin-bottom: 8px; border-radius: var(--radio);
  background: linear-gradient(160deg, var(--marca-suave), var(--fondo-2) 70%); border: 1px solid var(--borde);
}
.cabecera-lab .nombre { font-size: 1.2rem; font-weight: 650; letter-spacing: -.015em; line-height: 1.2; }
.fila-lista {
  display: flex; align-items: center; gap: 10px; padding: 10px 2px;
  border-bottom: 1px solid var(--borde); font-size: .92rem;
}
.fila-lista.pulsable { cursor: pointer; }
.fila-lista:last-child { border-bottom: none; }
details.plegable > summary {
  cursor: pointer; font-size: .82rem; color: var(--marca); font-weight: 600; list-style: none;
  padding: 4px 0; user-select: none;
}
details.plegable > summary::-webkit-details-marker { display: none; }
details.plegable > summary::after { content: ' ›'; }
details.plegable[open] > summary::after { content: ' ˅'; }
.enlace-suave { font-size: .84rem; color: var(--texto-3); cursor: pointer; text-decoration: underline; }
.enlace-suave.peligro { color: var(--error); }

/* Inicio: las cifras en una línea, como pastillas pequeñas y pulsables. */
.mini-cifras { display: flex; flex-wrap: wrap; gap: 6px; }
.mini-cifra {
  background: var(--fondo-2); border: 1px solid var(--borde); border-radius: 999px;
  color: var(--texto-2); font-size: .82rem; font-weight: 500; padding: 6px 12px; min-height: 0;
}
.mini-cifra b { color: var(--texto); font-weight: 650; font-variant-numeric: tabular-nums; margin-right: 2px; }

/* Filtros discretos: desplegables pequeños en vez de filas de chips. */
.filtros-finos { gap: 8px; margin-bottom: 12px; }
select.fino { font-size: .86rem; padding: 8px 10px; min-height: 0; }

.numerote {
  font-size: 2.15rem; font-weight: 600; line-height: 1.05; letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
}
.etiqueta {
  font-size: .755rem; color: var(--texto-3); text-transform: uppercase;
  letter-spacing: .07em; font-weight: 600;
}

/* ---------- distintivos ---------- */
.distintivo {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  font-size: .77rem; font-weight: 600;
  background: var(--fondo-3); color: var(--texto-2); border: 1px solid var(--borde);
}
.distintivo.ok { background: var(--ok-suave); color: var(--ok); border-color: var(--ok-linea); }
.distintivo.aviso { background: var(--aviso-suave); color: var(--aviso); border-color: var(--aviso-linea); }
.distintivo.error { background: var(--error-suave); color: var(--error); border-color: var(--error-linea); }
.distintivo.marca { background: var(--marca-suave); color: var(--marca); border-color: var(--marca-linea); }

/* El punto lleva el color del canal; el anillo lo despega de los fondos claros
   (un Alexa 488 o un Cy3 sobre blanco quedan en 1.5:1 sin él). */
.punto {
  width: 11px; height: 11px; border-radius: 50%; flex: 0 0 11px;
  box-shadow: inset 0 0 0 1.5px var(--anillo-punto);
}

/* ---------- formularios ---------- */
label { display: block; font-size: .84rem; color: var(--texto-2); margin: 0 0 6px; font-weight: 500; }
input, select, textarea {
  width: 100%; padding: 12px 13px;
  background: var(--fondo-3); color: var(--texto);
  border: 1px solid var(--borde-fuerte); border-radius: 10px;
  font-size: 1rem; font-family: inherit;
}
input::placeholder, textarea::placeholder { color: var(--texto-3); opacity: 1; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--marca); box-shadow: 0 0 0 3px var(--marca-suave);
}
input[type="number"] { -moz-appearance: textfield; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--marca); }
textarea { resize: vertical; min-height: 72px; }
.campo { margin-bottom: 14px; }
.campo .pista { font-size: .8rem; color: var(--texto-3); margin-top: 5px; }
/* Las ayudas, en toda la app: fuera de un formulario salían a tamaño de texto. */
.pista { font-size: .8rem; color: var(--texto-3); line-height: 1.4; }

button, .boton {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 44px; padding: 11px 18px;
  border-radius: 10px; border: 1px solid transparent;
  background: var(--marca); color: var(--sobre-marca);
  font-size: .95rem; font-weight: 600; font-family: inherit;
  cursor: pointer; transition: filter .15s, transform .1s, border-color .15s;
}
button:active { transform: scale(.98); }
button:disabled { opacity: .45; cursor: not-allowed; }
button.fantasma { background: transparent; color: var(--texto); border-color: var(--borde-fuerte); }
button.fantasma:hover { border-color: var(--marca); }
button.peligro { background: transparent; color: var(--error); border-color: var(--error-linea); }
button.ancho { width: 100%; }
button.chico { min-height: 38px; padding: 8px 13px; font-size: .84rem; }
button.grandote { min-height: 56px; padding: 16px; font-size: 1.08rem; }

/* ---------- navegación inferior ---------- */
nav.abajo {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 40;
  display: flex; background: var(--nav); backdrop-filter: blur(14px);
  border-top: 1px solid var(--borde);
  padding-bottom: var(--seguro-abajo);
}
nav.abajo button {
  flex: 1; flex-direction: column; gap: 3px;
  background: none; border: none; border-radius: 0;
  color: var(--texto-3); padding: 10px 2px 9px; font-size: .72rem; font-weight: 500;
  min-height: 56px;
}
nav.abajo button { position: relative; }
nav.abajo button.activa { color: var(--marca); font-weight: 650; }
/* La pestaña activa se ve sin mirar: pastilla de color detrás del icono y trazo más grueso. */
nav.abajo button.activa svg { stroke-width: 2.4; background: var(--marca-suave); border-radius: 12px; padding: 4px 12px; box-sizing: content-box; }
nav.abajo svg { width: 22px; height: 22px; stroke-width: 1.9; padding: 4px 12px; box-sizing: content-box; border-radius: 12px; transition: background .15s; }

/* ---------- cronómetro ---------- */
/* Se mira de reojo y de lejos: cifras de ancho fijo y trazo con cuerpo.
   Una 3.6rem en peso 250 se deshace en penumbra. */
.cronometro {
  font-variant-numeric: tabular-nums; font-size: 4rem; font-weight: 600;
  letter-spacing: -.045em; text-align: center; margin: 8px 0 2px;
  font-feature-settings: "tnum"; line-height: 1.02;
}
.cronometro.urgente { color: var(--aviso); }
.cronometro.vencido { color: var(--ok); }
.aro { position: relative; width: 190px; height: 190px; margin: 0 auto 14px; }
.aro svg { transform: rotate(-90deg); }
.aro .centro {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
}

/* ---------- pasos ---------- */
.paso {
  display: flex; gap: 12px; padding: 13px 14px;
  background: var(--fondo-2); border: 1px solid var(--borde);
  border-radius: 12px; margin-bottom: 8px;
}
.paso.actual {
  border-color: var(--marca); background: var(--marca-tenue);
  box-shadow: inset 3px 0 0 var(--marca);
}
.paso.hecho { opacity: .52; }
.paso .orden {
  width: 27px; height: 27px; flex: 0 0 27px; border-radius: 8px;
  background: var(--fondo-3); display: grid; place-items: center;
  font-size: .82rem; font-weight: 700; color: var(--texto-2);
}
.paso.actual .orden { background: var(--marca); color: var(--sobre-marca); }
.paso.hecho .orden { background: var(--ok-suave); color: var(--ok); }
.paso .tiempo { font-size: .84rem; color: var(--texto-3); font-variant-numeric: tabular-nums; }

/* Etapa del protocolo: los artículos escriben el procedimiento por etapas
   («criosección», «tinción», «adquisición») y verlas separadas es lo que
   permite seguirlo en el mesón sin perder el hilo. */
.etapa {
  margin: 16px 0 8px; padding-left: 2px;
  font-size: .78rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--texto-3);
}
.etapa:first-child { margin-top: 4px; }

/* La calculadora: se usa en mitad de cualquier otra cosa, así que vive en el
   borde y no gasta un sitio en la barra de abajo. Va por encima del contenido
   pero sin tapar la navegación. */
.flotante {
  position: fixed;
  right: 16px;
  bottom: calc(56px + var(--seguro-abajo) + 16px);   /* justo encima de la barra */
  width: 52px; height: 52px; padding: 0;
  border-radius: 50%;
  background: var(--marca); color: var(--sobre-marca);
  border: none; box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
  display: grid; place-items: center; cursor: pointer;
  z-index: 40;
}
.flotante svg { width: 24px; height: 24px; stroke-width: 1.8; }
.flotante:active { transform: scale(.94); }
/* El de escanear va encima del de la calculadora: 52 de alto más 12 de aire.
   En tono secundario, para que dos botones redondos en la misma esquina no
   compitan por la mirada. */
#btn-qr {
  /* Ocupa el sitio que dejó la calculadora (ahora en la cabecera). */
  bottom: calc(56px + var(--seguro-abajo) + 16px);
  background: var(--fondo-3); color: var(--texto);
  border: 1px solid var(--borde);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .28);
}

/* Volver al protocolo en marcha: encima del QR, en el color de la marca
   porque es lo único urgente de la esquina. Late despacio para que se vea que
   hay algo corriendo sin distraer. */
#btn-ejecucion {
  bottom: calc(56px + var(--seguro-abajo) + 16px + 52px + 12px);
  animation: late-ejecucion 2.4s ease-in-out infinite;
}
#btn-ejecucion svg { width: 22px; height: 22px; margin-left: 3px; }
@keyframes late-ejecucion {
  0%, 100% { box-shadow: 0 6px 20px rgba(0, 0, 0, .35), 0 0 0 0 color-mix(in srgb, var(--marca) 55%, transparent); }
  50% { box-shadow: 0 6px 20px rgba(0, 0, 0, .35), 0 0 0 8px color-mix(in srgb, var(--marca) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) { #btn-ejecucion { animation: none; } }
.cuenta-flotante {
  position: absolute; top: -4px; right: -4px; min-width: 20px; height: 20px;
  padding: 0 5px; border-radius: 10px; font-size: .72rem; font-weight: 700;
  background: var(--texto); color: var(--fondo); display: none;
  place-items: center; line-height: 20px;
}

/* Editar una receta: tres campos y el botón de quitar, que tiene que caber en
   un celular sin apretar los dedos. */
.comp-fila {
  display: grid; grid-template-columns: 1fr 88px 88px 34px;
  gap: 6px; margin-bottom: 6px; align-items: center;
}
.comp-fila input { min-width: 0; }
.comp-fila .quitar {
  width: 34px; height: 38px; padding: 0; border-radius: 9px;
  background: var(--fondo-3); color: var(--texto-3);
  border: 1px solid var(--borde); font-size: 1.1rem; line-height: 1;
}
.comp-fila .quitar:hover { color: var(--error); border-color: var(--error); }
@media (max-width: 420px) {
  .comp-fila { grid-template-columns: 1fr 1fr 34px; }
  .comp-fila input:first-child { grid-column: 1 / -1; }
}

/* La rejilla de horas de un equipo: se mira de un vistazo para ver dónde hay
   hueco, así que las cogidas tienen que distinguirse sin leer. */
.huecos {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 6px; margin-top: 4px;
}
.hueco {
  padding: 10px 4px; border-radius: 9px; font-size: .82rem; font-weight: 600;
  background: var(--marca-tenue); color: var(--marca);
  border: 1px solid transparent; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.hueco:active { transform: scale(.96); }
.hueco.tomado {
  background: var(--fondo-3); color: var(--texto-3);
  text-decoration: line-through; cursor: default;
}
/* Elegir horas con dos toques: inicio y término (Horas, app.js). */
.hueco.elegido { background: var(--marca); color: #fff; }
.hueco.tramo { background: color-mix(in srgb, var(--marca) 45%, transparent); color: #fff; }
.horas-resumen { font-size: .88rem; margin: 6px 0 2px; min-height: 1.3em; }

/* Permisos de cada persona dentro del grupo. */
.permisos {
  display: grid; gap: 4px; margin-top: 8px; padding: 9px 11px;
  background: var(--fondo); border: 1px solid var(--borde); border-radius: 10px;
}

/* Lo que hay que preparar antes de empezar: va arriba y se puede pinchar. */
.antelacion {
  border: 1px solid var(--borde); border-radius: 12px;
  padding: 11px 12px; margin: 14px 0;
  background: var(--fondo-2);
}
.antelacion .etiqueta { margin-bottom: 8px; }
.preparar-fila {
  display: flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 9px 10px; margin-bottom: 6px;
  background: var(--fondo); border: 1px solid var(--borde); border-radius: 10px;
  font: inherit; font-size: .88rem; color: inherit; text-align: left;
  cursor: pointer;
}
.preparar-fila:last-child { margin-bottom: 0; }
.preparar-fila:hover:not(:disabled) { border-color: var(--marca); }
.preparar-fila:disabled { cursor: default; opacity: .75; }

/* Reactivos y recetas que vinieron con el artículo. */
.lista-reactivos { border: 1px solid var(--borde); border-radius: 12px; overflow: hidden; }
.reactivo-fila {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding: 8px 12px; font-size: .86rem;
  border-bottom: 1px solid var(--borde);
}
.reactivo-fila:last-child { border-bottom: 0; }

/* Dónde está el frasco. Es lo único del inventario que nunca sale del grupo:
   fuera se sabe que lo tienen, jamás en qué estante. */
.donde {
  background: var(--fondo-2); border: 1px solid var(--borde);
  border-radius: 12px; padding: 12px; margin: 6px 0 10px;
}
.donde .pista { font-size: .8rem; color: var(--texto-3); margin-top: 6px; }
.sitio::before { content: "📍\00A0"; }
.receta {
  border: 1px solid var(--borde); border-radius: 12px;
  margin-bottom: 8px; padding: 4px 0;
}
.receta > summary {
  cursor: pointer; padding: 8px 12px; font-weight: 600; font-size: .9rem;
}

/* Problemas frecuentes, tal como los publica el autor. */
.apuro {
  padding: 11px 13px; margin-bottom: 8px; border-radius: 11px;
  background: var(--fondo-2); border: 1px solid var(--borde);
  border-left: 3px solid var(--aviso, var(--marca));
}

/* ---------- avisos del panel ---------- */
.nota-panel {
  display: flex; gap: 11px; padding: 13px 14px; border-radius: 12px;
  margin-bottom: 9px; border: 1px solid; font-size: .9rem; line-height: 1.45;
}
.nota-panel.bloqueante { background: var(--error-suave); border-color: var(--error-linea); }
.nota-panel.aviso { background: var(--aviso-suave); border-color: var(--aviso-linea); }
.nota-panel.nota { background: var(--marca-tenue); border-color: var(--marca-linea); }
.nota-panel .icono { font-size: 1.1rem; line-height: 1.3; }
.nota-panel b { display: block; margin-bottom: 3px; font-size: .94rem; }

/* ---------- listas ---------- */
.lista-vacia {
  text-align: center; padding: 44px 20px; color: var(--texto-3);
  border: 1px dashed var(--borde); border-radius: var(--radio);
}
.lista-vacia .emoji { font-size: 2rem; display: block; margin-bottom: 10px; opacity: .7; }

/* ---------- hoja inferior ---------- */
.velo {
  position: fixed; inset: 0; z-index: 50; background: var(--velo-fondo);
  display: none; align-items: flex-end; backdrop-filter: blur(3px);
}
.velo.abierta { display: flex; }
.hoja {
  width: 100%; max-height: 92dvh; overflow-y: auto;
  background: var(--fondo-2); border-radius: 20px 20px 0 0;
  border-top: 1px solid var(--borde);
  padding: 8px 16px calc(24px + var(--seguro-abajo));
  animation: sube .22s cubic-bezier(.2, .8, .2, 1);
}
@keyframes sube { from { transform: translateY(100%); } to { transform: none; } }
.hoja .asa {
  width: 38px; height: 4px; background: var(--borde-fuerte);
  border-radius: 2px; margin: 8px auto 16px; opacity: .6;
}
@media (min-width: 640px) {
  .velo { align-items: center; justify-content: center; }
  .hoja { max-width: 560px; border-radius: 18px; border: 1px solid var(--borde); box-shadow: var(--sombra); }
}

/* ---------- avisos flotantes ---------- */
#avisos {
  position: fixed; left: 12px; right: 12px; bottom: calc(80px + var(--seguro-abajo));
  z-index: 60; display: flex; flex-direction: column; gap: 8px; pointer-events: none;
}
.globo {
  background: var(--fondo-3); border: 1px solid var(--borde);
  border-left: 3px solid var(--marca);
  border-radius: 10px; padding: 12px 14px; font-size: .93rem;
  box-shadow: var(--sombra); animation: entra .2s;
}
.globo.error { border-left-color: var(--error); }
.globo.ok { border-left-color: var(--ok); }

/* ---------- varios ---------- */
.separador { height: 1px; background: var(--borde); margin: 18px 0; }
.mono { font-variant-numeric: tabular-nums; font-family: var(--tipo-mono); }
.recorta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tenue { color: var(--texto-3); }
.suave { color: var(--texto-2); }
.centrado { text-align: center; }

/* El chip lleva el color del canal como fondo; el texto va oscuro siempre,
   porque los cinco canales son colores emitidos (claros) en los dos temas. */
.chip-canal-texto {
  padding: 2px 8px; border-radius: 6px; font-size: .74rem; font-weight: 700;
  color: #04141A; letter-spacing: .01em; flex-shrink: 0; white-space: nowrap;
}

.cargando { display: inline-block; width: 15px; height: 15px; border: 2px solid var(--borde);
  border-top-color: var(--marca); border-radius: 50%; animation: gira .7s linear infinite; }
@keyframes gira { to { transform: rotate(360deg); } }

/* ---------- entrada ---------- */
.portada {
  min-height: 100dvh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; padding: 24px; gap: 6px;
}
.portada .marca-grande {
  width: 68px; height: 68px; border-radius: 20px; margin-bottom: 16px;
  background: var(--marca);
  display: grid; place-items: center; color: var(--sobre-marca);
  overflow: hidden; box-shadow: var(--sombra);
}
.portada .marca-grande svg { width: 100%; height: 100%; display: block; }
.portada h2 { font-size: 1.6rem; letter-spacing: -.028em; }
.portada h2 .flow { font-weight: inherit; color: inherit; }   /* el nombre en un solo peso */
.portada form { width: 100%; max-width: 340px; margin-top: 20px; }
/* En escritorio el cuerpo se pone en fila (navegación al lado) y la portada
   se encogía al ancho de su contenido, pegada a la izquierda (app del Mac,
   2026-10-13): que ocupe todo el ancho para quedar centrada. */
body > .portada { flex: 1 1 auto; width: 100%; align-self: stretch; }
/* La pantalla de carga: encima de todo mientras llega app.js, y se va con un
   fundido (Arranque.quitar). La frase entra un instante después del logo
   para que no parpadee si la carga es rápida. */
.arranque {
  position: fixed; inset: 0; z-index: 9999; background: var(--fondo);
  transition: opacity .3s ease;
}
.arranque.se-va { opacity: 0; pointer-events: none; }
.arranque-frase {
  margin: 22px 0 0; max-width: 320px; text-align: center;
  opacity: 0; animation: arranque-aparece .5s ease .25s forwards;
}
.arranque-frase blockquote { margin: 0; font-size: .95rem; line-height: 1.5; color: var(--texto-2); }
.arranque-frase figcaption { margin-top: 8px; font-size: .78rem; color: var(--texto-3); }
@keyframes arranque-aparece { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .arranque, .arranque-frase { transition: none; animation: none; opacity: 1; }
}
.portada .cambiar { margin-top: 16px; font-size: .88rem; color: var(--texto-2); }
.portada .cambiar a { color: var(--marca); text-decoration: none; cursor: pointer; font-weight: 500; }

/* ===================================================================== */
/*  Pantallas grandes: el mesón tiene celular, pero el escritorio tiene   */
/*  monitor. A partir de tablet la navegación pasa al lado y el           */
/*  contenido respira en dos columnas.                                    */
/* ===================================================================== */
@media (min-width: 760px) {
  main { padding: 24px 24px 48px; max-width: 1040px; }
  header.barra { padding-left: 24px; padding-right: 24px; }
  .rejilla-3 { grid-template-columns: repeat(3, 1fr); }
  .cronometro { font-size: 4.8rem; }
  #avisos { left: auto; right: 24px; bottom: 24px; max-width: 380px; }
}

@media (min-width: 900px) {
  body { flex-direction: row; }

  nav.abajo {
    position: fixed; top: 0; bottom: 0; left: 0; right: auto;
    width: 96px; flex-direction: column; justify-content: flex-start;
    gap: 4px; padding: 88px 8px 16px;
    border-top: none; border-right: 1px solid var(--borde);
  }
  nav.abajo button { flex: 0 0 auto; padding: 14px 4px; border-radius: 10px; font-size: .74rem; }
  nav.abajo button.activa { background: var(--marca-suave); }
  nav.abajo svg { width: 23px; height: 23px; }

  header.barra { left: 0; padding-left: 24px; }
  #app { padding-left: 96px; }
  main { padding-bottom: 48px; }
  #avisos { bottom: 24px; }

  /* Dos columnas en las pantallas que son listas largas */
  #lista-anticuerpos, #lista-protocolos, #ultimas-corridas {
    display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start;
  }
  #lista-anticuerpos .tarjeta, #lista-protocolos .tarjeta, #ultimas-corridas .tarjeta {
    margin-bottom: 0;
  }
  .lista-vacia { grid-column: 1 / -1; }
}

@media (min-width: 1240px) {
  main { max-width: 1180px; }
  #p-correr .paso { max-width: 780px; }
}

/* El ratón sí tiene estado de reposo; el dedo no. */
@media (hover: hover) {
  .tarjeta.pulsable:hover { border-color: var(--marca-oscura); }
  button:hover:not(:disabled) { filter: brightness(1.08); }
  nav.abajo button:hover { color: var(--texto-2); }
}

/* Quien pide menos movimiento, menos movimiento. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* Pantallas muy angostas: que nada se salga. */
@media (max-width: 360px) {
  main { padding-left: 12px; padding-right: 12px; }
  .numerote { font-size: 1.75rem; }
  .cronometro { font-size: 3.2rem; }
  nav.abajo button { font-size: .6875rem; }
}

/* Apaisado en el celular: la barra de navegación roba demasiada altura. */
@media (max-height: 460px) and (orientation: landscape) {
  header.barra { padding-top: 8px; padding-bottom: 8px; }
  .cronometro { font-size: 2.6rem; margin: 2px 0; }
  main { padding-bottom: 76px; }
  nav.abajo button { min-height: 44px; padding: 6px 2px; }
}

/* ---------- galería de resultados ---------- */
.galeria {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px; margin-bottom: 12px;
}
.galeria figure {
  margin: 0; background: var(--fondo-2); border: 1px solid var(--borde);
  border-radius: 12px; overflow: hidden; cursor: pointer;
}
.galeria img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.galeria figcaption {
  padding: 7px 9px; font-size: .8rem; line-height: 1.35; color: var(--texto-2);
}
img.mini {
  width: 76px; height: 76px; object-fit: cover; border-radius: 9px;
  margin: 8px 6px 0 0; cursor: pointer; border: 1px solid var(--borde);
}
input[type="file"] {
  padding: 9px; font-size: .88rem; background: var(--fondo-3);
}
input[type="range"] { padding: 0; accent-color: var(--marca); border: none; background: none; }

/* ---------- impresión: que salga el protocolo, no la aplicación ---------- */
@media print {
  nav.abajo, header.barra, #avisos, .velo, button { display: none !important; }
  body, main { background: #fff !important; color: #000 !important; padding: 0 !important; }
  .tarjeta, .paso { border-color: #ccc !important; background: #fff !important; break-inside: avoid; }
  .tenue, .suave { color: #555 !important; }
  a { color: #000 !important; text-decoration: none; }
}


/* Cajitas de filtro: la elegida se ve elegida. */
button.chico.activa, .filtro-ab.activa, .esp.activa, .tab-calc.activa, .tab-prot.activa {
  background: var(--marca-suave);
  border-color: var(--marca);
  color: var(--marca);
}

/* ===================================================================== */

/*                                                                        */
/*  El color de cada canal lo manda el servidor (fluorophores.py,         */
/*  CANAL_COLOR) y app.js lo escribe como estilo en línea, así que las    */
/*  variables --azul/--verde/--naranja/--rojo/--lejano de arriba no       */
/*  llegan solas al punto ni al chip. Mientras esa tabla siga con la      */
/*  gama antigua, reasignamos aquí sus cinco hexadecimales.               */
/*  BORRAR este bloque en cuanto CANAL_COLOR use los valores nuevos.      */
/* ===================================================================== */

/* El girito pequeño que dice «esto es lo guardado, sigo buscando». */
.cargando.chica { width: 11px; height: 11px; border-width: 2px; vertical-align: -1px; }

/* Por qué salió este resultado: dónde coincidió la búsqueda, con la palabra marcada. */
.coincide { font-size: .78rem; color: var(--texto-3); margin-top: 4px; line-height: 1.35; }
.coincide .donde { color: var(--marca); font-weight: 600; }
.coincide .donde::after { content: ":"; }
.coincide mark { background: var(--marca-tenue); color: var(--texto); padding: 0 2px; border-radius: 3px; }

/* Las vueltas de un paso repetido (3 × 5 min): cuál va y cuáles quedan. */
.vueltas { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 8px; }
.vueltas .vuelta {
  width: 26px; height: 26px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; font-size: .8rem; font-weight: 650;
  border: 1.5px solid var(--borde-fuerte); color: var(--texto-2);
}
.vueltas .vuelta.actual { border-color: var(--marca); color: var(--marca); }
.vueltas .vuelta.hecha { background: var(--marca); border-color: var(--marca); color: var(--sobre-marca); }

/* Dentro de la cuenta de otra persona: se ve todo el rato, y volver está a un toque. */
#suplantacion {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 16px; font-size: .86rem;
  background: var(--aviso); color: #1a1200;
}
#suplantacion button { background: #1a1200; color: var(--aviso); border-color: #1a1200; }

/* Los tres sitios donde puede estar un reactivo: lo mío, lo que puedo pedir, lo de fuera. */
.ambitos { display: flex; gap: 4px; margin: 2px 0 12px; background: var(--fondo-3); border-radius: 12px; padding: 4px; }
.ambitos .ambito {
  flex: 1; padding: 8px 6px; border-radius: 9px; border: 0; background: transparent;
  color: var(--texto-2); font-size: .84rem; font-weight: 600;
}
.ambitos .ambito.activa { background: var(--fondo); color: var(--texto); box-shadow: 0 1px 2px rgba(0,0,0,.3); }
.ambitos .cuenta { display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px;
  border-radius: 9px; font-size: .72rem; background: var(--marca-tenue); color: var(--marca); }
.ambitos .cuenta:empty { display: none; }

/* Deslizar una tarjeta: a la izquierda la quita, a la derecha la edita. */
.deslizable { position: relative; overflow: hidden; border-radius: 14px; margin-bottom: 10px; }
.deslizable > .tarjeta { position: relative; z-index: 1; margin-bottom: 0; transition: transform .18s ease; touch-action: pan-y; }
.deslizable .fondo {
  position: absolute; inset: 0; display: flex; align-items: center; padding: 0 18px;
  font-weight: 650; font-size: .9rem; opacity: .55; transition: opacity .12s;
}
.deslizable .fondo.editar { justify-content: flex-start; background: var(--marca-oscura); color: #fff; }
.deslizable .fondo.quitar { justify-content: flex-end; background: var(--error); color: #1a0505; }
.deslizable.va-editar .fondo.editar, .deslizable.va-quitar .fondo.quitar { opacity: 1; }

/* Anticuerpos de un paso: la casilla lleva el color del fluoróforo y el veredicto. */
.ab-paso { margin-top: 8px; }
.ab-fila { border: 1px solid var(--borde); border-left: 4px solid var(--borde-fuerte); border-radius: 10px; padding: 8px 10px; margin-bottom: 6px; background: var(--fondo-3); }
.ab-fila.incompatible { border-color: var(--error); border-left-color: var(--error); }
.ab-fila .dilucion { width: 78px; flex: 0 0 78px; padding: 6px 8px; font-size: .86rem; text-align: center; }
.ab-fila .quitar { width: 30px; height: 30px; padding: 0; border-radius: 8px; flex: 0 0 30px; }
.veredicto { font-size: .78rem; margin-top: 5px; }
.veredicto.bien { color: var(--ok); }
.veredicto.mal { color: var(--error); }
.veredicto.duda { color: var(--aviso); }
.reactivo-paso { font-size: .82rem; color: var(--texto-2); border-left: 3px solid transparent; padding-left: 8px; margin-top: 3px; }
.reactivo-paso.incompatible { border-left-color: var(--error); }

/* La foto de dónde está el reactivo. */
/* El tramo del plan que no se puede reservar: en rojo, pero se sigue igual. */
.tarjeta.tramo-rojo { background: color-mix(in srgb, var(--error) 7%, var(--fondo-2, transparent)); }
.nota-panel.error { border-color: var(--error); }
.nota-panel.error .icono { color: var(--error); }

/* Muestras: la rejilla de espacios de una caja del tanque */
.rejilla-espacios { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; margin-top: 4px; }
.rejilla-espacios .espacio { text-align: center; font-size: .72rem; padding: 8px 0; border-radius: 6px;
  border: 1px solid var(--ok-linea); background: var(--ok-suave); color: var(--ok); }
.rejilla-espacios .espacio.ocupado { border-color: var(--error-linea); background: var(--error-suave); color: var(--error); cursor: pointer; }
#mu-rejilla .espacio { cursor: pointer; padding: 11px 0; font-size: .82rem; user-select: none; }
.rejilla-espacios .espacio.ocupado.ajeno { border-color: var(--borde); background: var(--fondo-2, transparent); color: var(--texto-3); }
#mu-rejilla .espacio.elegido { background: var(--marca); border-color: var(--marca); color: #fff; font-weight: 700; }

/* Aviso plegado: una línea de color; se abre al pinchar */
details.aviso-plegado { border: 1px solid var(--aviso-linea); background: var(--aviso-suave); border-radius: 12px; margin-bottom: 10px; }
details.aviso-plegado.error { border-color: var(--error-linea); background: var(--error-suave); }
details.aviso-plegado summary { display: flex; align-items: center; gap: 8px; padding: 9px 12px; cursor: pointer; list-style: none; font-size: .9rem; }
details.aviso-plegado summary::-webkit-details-marker { display: none; }
details.aviso-plegado summary .icono { font-weight: 700; }
details.aviso-plegado summary .flecha { color: var(--texto-3); transition: transform .15s; }
details.aviso-plegado[open] summary .flecha { transform: rotate(90deg); }
details.aviso-plegado .cuerpo { padding: 0 12px 10px 34px; font-size: .88rem; }

/* La barra de cuánto queda del frasco abierto.
   Se toca donde corresponde: 44 px de alto es lo que pide un dedo con guante,
   y el relleno lleva su propio color —que va del verde al rojo por el tono,
   sin escalones— porque la diferencia entre el 60 % y el 30 % importa antes de
   que salte ninguna alarma. */
.barra-queda {
  position: relative; height: 44px; border-radius: 12px; width: 100%;
  background: var(--fondo-3); border: 1px solid var(--borde-fuerte);
  overflow: hidden; cursor: pointer; padding: 0; display: block;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.barra-queda .relleno {
  position: absolute; inset: 0 auto 0 0; width: 0;
  transition: width .18s ease, background-color .18s ease;
}
.barra-queda .cifra {
  position: relative; display: flex; align-items: center; justify-content: center;
  height: 100%; font-weight: 650; font-size: .95rem; color: var(--texto);
  font-variant-numeric: tabular-nums; text-shadow: 0 1px 2px var(--fondo);
  pointer-events: none;
}
/* Las marcas del cuarto, la mitad y tres cuartos: dan dónde apuntar sin
   obligar a acertar un píxel. */
.barra-queda .marca {
  position: absolute; top: 0; bottom: 0; width: 1px;
  background: var(--borde-fuerte); opacity: .55; pointer-events: none;
}
.barra-queda:focus-visible { outline: 2px solid var(--marca); outline-offset: 2px; }

/* La cajita de stock de un reactivo: verde, amarillo, rojo */
button.stock { min-height: 32px; padding: 5px 11px; border-radius: 999px; font-size: .72rem; font-weight: 650; border: 1px solid; white-space: nowrap; }
button.stock.stock-ok { background: var(--ok-suave); color: var(--ok); border-color: var(--ok-linea); }
button.stock.stock-poco { background: var(--aviso-suave); color: var(--aviso); border-color: var(--aviso-linea); }
button.stock.stock-agotado { background: var(--error-suave); color: var(--error); border-color: var(--error-linea); }

/* Un componente que es un reactivo del estante: se pincha y lleva a dónde está */
.enlace-reactivo { color: var(--marca); cursor: pointer; text-decoration: underline dotted; padding: 4px 0; display: inline-block; }
.enlace-reactivo.sin-estante { color: inherit; text-decoration-color: var(--tenue, #8a97a8); }

/* Estadísticas de uso: barras por grupo */
.barra-uso { margin-bottom: 8px; }
.pista-barra { height: 8px; border-radius: 999px; background: var(--fondo); border: 1px solid var(--borde); overflow: hidden; margin-top: 3px; }
.pista-barra .relleno { height: 100%; background: var(--marca); border-radius: 999px; }

/* Recetas favoritas: estrella en la tarjeta y caja arriba */
.caja-favoritas { padding: 10px 10px 2px; margin-bottom: 6px; border-radius: 12px;
  border: 1px solid var(--aviso-linea); background: color-mix(in srgb, var(--aviso) 8%, var(--fondo-2)); }
button.estrella { float: right; background: none; border: none; min-height: 32px; min-width: 32px; padding: 0 0 0 8px; margin: -6px 0 0 0;
  font-size: 1.15rem; line-height: 1; color: var(--texto-3); }
button.estrella.puesta { color: var(--aviso); }

/* La caja de anticuerpos de un paso de primario o secundario, en el editor */
.caja-anticuerpos { margin: 8px 0 4px; padding: 10px 11px; border: 1px dashed var(--marca-oscura, var(--marca)); border-radius: 12px; background: var(--fondo); }
.ab-fila.pendiente { border-left-color: var(--borde); background: transparent; }

/* Los anticuerpos de un paso durante la corrida */
.abs-paso { font-size: .84rem; margin-top: 4px; display: grid; gap: 2px; }
.abs-paso.grande { font-size: .92rem; margin: 8px 0 2px; }

/* Tarjeta de equipo: el marco lleva el color del estado. */
.tarjeta.equipo { padding: 8px 10px; margin-bottom: 8px; border-left-width: 4px; }
.tarjeta.equipo > .fila { gap: 8px; }
.tarjeta.equipo .icono-equipo { width: 42px; height: 42px; flex-basis: 42px; margin-right: 4px; border-radius: 10px; }
.tarjeta.equipo .icono-equipo.vacio { font-size: 1.15rem; }
.tarjeta.equipo button.chico { padding: 6px 10px; min-height: 0; font-size: .8rem; align-self: center; }
.tarjeta.equipo details.plegable { margin-top: 2px; }
.tarjeta.equipo details.plegable summary { font-size: .76rem; padding: 2px 0; }
.tarjeta.equipo .distintivo { padding: 2px 7px; font-size: .7rem; }
.tarjeta.equipo.estado-operativo { border-left-color: var(--ok); }
.tarjeta.equipo.estado-mantencion { border-left-color: var(--aviso); border-color: var(--aviso-linea); }
.tarjeta.equipo.estado-malo { border-left-color: var(--error); border-color: var(--error-linea); }
.nombre-equipo { font-weight: 650; font-size: .92rem; line-height: 1.2; }
.tarjeta.equipo .tenue { font-size: .76rem !important; line-height: 1.25; }
.estado-equipo { display: inline-flex; align-items: center; gap: 5px; font-size: .74rem; font-weight: 600; margin-top: 2px; }
.estado-equipo .punto { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.estado-operativo .estado-equipo { color: var(--ok); }
.estado-mantencion .estado-equipo { color: var(--aviso); }
.estado-malo .estado-equipo { color: var(--error); }

/* La foto del equipo como icono de su tarjeta */
.icono-equipo { width: 52px; height: 52px; flex: 0 0 52px; object-fit: cover; border-radius: 12px;
  border: 1px solid var(--borde); margin-right: 10px; cursor: zoom-in; background: var(--fondo-2); }
.icono-equipo.vacio { display: flex; align-items: center; justify-content: center; font-size: 1.4rem;
  color: var(--texto-3); cursor: pointer; }

/* Invitaciones con QR */
.qr-caja { background: #fff; border-radius: 14px; padding: 12px; max-width: 260px; margin: 10px auto; }
.qr-caja svg { width: 100%; height: auto; display: block; }
.invitacion-banner { margin: 14px 0 4px; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--marca);
  background: var(--marca-suave); font-size: .92rem; text-align: left; width: 100%; }
.invitacion-banner img { height: 34px; width: auto; margin-bottom: 6px; display: block; }

/* Logos de la unidad: instituto › centro › grupo, en fila y a la misma altura. */
.logos-unidad { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-bottom: 8px; }
.logos-unidad img { height: var(--alto, 40px); width: auto; max-width: 42%; object-fit: contain; cursor: zoom-in; }
img.logo-unidad { height: 44px; width: auto; max-width: 140px; object-fit: contain; border-radius: 6px; }
img.logo-unidad.chico { height: 32px; max-width: 90px; margin-right: 8px; }
.foto-sitio { margin-top: 8px; }
.foto-sitio img.mini { display: block; max-width: 100%; max-height: 180px; width: auto; border-radius: 10px; border: 1px solid var(--borde); cursor: zoom-in; }

/* La campana de la cabecera con su número. */
#btn-avisos { position: relative; }
#btn-avisos .cuenta { position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 9px; background: var(--marca); color: var(--sobre-marca);
  font-size: .7rem; font-weight: 700; line-height: 18px; text-align: center; }
#btn-avisos .cuenta:empty { display: none; }

/* Resultado de una corrida: estrellas que se tocan y galería de fotos. */
.estrellas-editables { display: flex; align-items: center; gap: 2px; }
.estrellas-editables .estrella { background: none; border: 0; padding: 2px 4px; font-size: 1.6rem; line-height: 1;
  color: var(--texto-3); cursor: pointer; }
.estrellas-editables .estrella.llena { color: var(--aviso); }
.galeria { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; margin-bottom: 8px; }
.foto-corrida { position: relative; margin: 0; }
.foto-corrida img.mini { width: 100%; height: 110px; object-fit: cover; border-radius: 10px; border: 1px solid var(--borde); cursor: zoom-in; }
.foto-corrida .quitar { position: absolute; top: 4px; right: 4px; width: 26px; height: 26px; padding: 0; border-radius: 50%;
  background: rgba(0,0,0,.6); color: #fff; border: 0; }

/* Tubos iguales plegados en una entrada: el resumen es la fila, dentro va cada sitio. */
details.lote-tubos { margin-bottom: 8px; }
details.lote-tubos > summary { list-style: none; cursor: pointer; }
details.lote-tubos > summary::-webkit-details-marker { display: none; }
details.lote-tubos[open] > summary { border-bottom: 1px solid var(--borde); padding-bottom: 8px; margin-bottom: 4px; }

/* Jerarquía en Buscar: el centro es el resumen, sus laboratorios cuelgan dentro. */
details.jerarquia > summary { list-style: none; cursor: pointer; }
details.jerarquia > summary::-webkit-details-marker { display: none; }
details.jerarquia[open] > summary { border-bottom: 1px solid var(--borde); padding-bottom: 6px; margin-bottom: 4px; }

/* Dilución: el «1:» va impreso y solo se escribe el número. Así nadie pelea
   con los dos puntos en el teclado del celular ni se guarda «500» a secas. */
.dil-campo { display: inline-flex; align-items: stretch; flex: 1; min-width: 0; }
.dil-campo .dil-uno {
  display: flex; align-items: center; padding: 0 8px; font-weight: 650;
  color: var(--texto-3); background: var(--fondo-2, transparent);
  border: 1px solid var(--borde); border-right: none; border-radius: 10px 0 0 10px;
  font-variant-numeric: tabular-nums;
}
.dil-campo input.dilucion { border-radius: 0 10px 10px 0; min-width: 0; flex: 1; }

/* Visor de la cámara para leer el código de invitación. */
.visor-qr { position: relative; border-radius: 14px; overflow: hidden; background: #000; aspect-ratio: 1; }
.visor-qr video { width: 100%; height: 100%; object-fit: cover; display: block; }
.visor-qr::after {
  content: ""; position: absolute; inset: 18%; border: 3px solid var(--marca);
  border-radius: 12px; pointer-events: none;
}

/* Equipos antes de empezar: lo que no está disponible se ve sin leer. */
.equipo-plan.no-disponible b { color: var(--error); }
.equipo-plan.no-disponible { background: var(--error-suave); border-radius: 8px; padding-left: 8px; padding-right: 8px; }

/* La dilución dentro de una fila del resumen: el «1:» impreso y un hueco corto. */
.reactivo-fila .dil-uno { display: inline-flex; align-items: center; gap: 2px; font-weight: 650; color: var(--texto-3); }
.reactivo-fila .dil-uno input { width: 5.5rem; text-align: right; padding: 5px 8px; font-variant-numeric: tabular-nums; }

/* ---------- pestañas de arriba ---------- */
/* Mismo lenguaje que la barra de abajo —icono encima, nombre debajo, pastilla
   en la elegida— para que se lean igual sin tener que aprender dos cosas.
   Se quedan pegadas al bajar, que es cuando hacen falta para cambiar. */
nav.arriba {
  display: flex; gap: 2px; margin: 0 0 14px;
  /* Debajo de la cabecera, no encima: las dos eran pegajosas a la misma
     altura y al bajar las pestañas tapaban el título. */
  position: sticky; top: var(--alto-barra, 0px); z-index: 29;
  background: var(--fondo); padding-top: 2px;
  border-bottom: 1px solid var(--borde);
}
nav.arriba button {
  flex: 1; flex-direction: column; gap: 3px;
  background: none; border: none; border-radius: 0;
  color: var(--texto-3); padding: 8px 2px 8px; font-size: .72rem; font-weight: 500;
  min-height: 52px; min-width: 0;
}
nav.arriba button svg {
  width: 21px; height: 21px; stroke-width: 1.9;
  padding: 3px 11px; box-sizing: content-box; border-radius: 11px;
  transition: background .15s;
}
nav.arriba button.activa { color: var(--marca); font-weight: 650; }
nav.arriba button.activa svg { stroke-width: 2.4; background: var(--marca-suave); }

/* Dos líneas y a otra cosa: en la lista del cuaderno se lee de qué va cada
   entrada, no la entrada entera. */
.recorta-2 {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---------- cuaderno ---------- */
/* El texto de una entrada se lee como texto, no como una ficha: respeta los
   saltos de línea que escribió quien lo puso y va más ancho de lo normal. */
.cuerpo-cuaderno {
  white-space: pre-wrap; font-size: .92rem; line-height: 1.55;
  margin: 10px 0; color: var(--texto-2);
}
.galeria-cuaderno { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; }
.galeria-cuaderno figure { margin: 0; position: relative; }
.galeria-cuaderno img {
  width: 100%; border-radius: 10px; display: block;
  border: 1px solid var(--borde); background: var(--fondo-3);
}
.galeria-cuaderno figcaption { font-size: .76rem; color: var(--texto-3); margin-top: 3px; }
.galeria-cuaderno figure > button { position: absolute; top: 5px; right: 5px; padding: 2px 7px; }

/* ---------- recortar una hoja de cuaderno ---------- */
/* La foto con sus cuatro esquinas arrastrables encima. El recuadro se dibuja
   en un SVG que se estira con la imagen, así no hay que recalcular nada al
   girar el teléfono. */
.recorte { position: relative; display: inline-block; max-width: 100%; touch-action: none; }
.recorte img { max-width: 100%; display: block; border-radius: 10px; }
.recorte svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.recorte svg polygon { fill: rgba(47, 216, 239, .16); stroke: var(--marca); stroke-width: .6; }
.recorte .esquina {
  position: absolute; width: 30px; height: 30px; padding: 0; margin: -15px 0 0 -15px;
  border-radius: 50%; background: var(--marca); border: 3px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.4); cursor: grab; touch-action: none;
}
.recorte .esquina:active { cursor: grabbing; transform: scale(1.15); }

/* El calendario del mes. Los días se tocan con el dedo y con guantes: 40 px
   de lado como mínimo, que es lo que mide una yema. El color dice si queda
   sitio, pero nunca lo dice *solo* el color: el día completo va tachado. */
.cal-cabecera {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin: 2px 0 8px;
}
.cal-cabecera b { font-size: .95rem; text-transform: capitalize; }
.cal-flecha {
  width: 38px; height: 38px; border-radius: 10px; font-size: 1.3rem; line-height: 1;
  background: var(--fondo-3); color: var(--texto); border: 1px solid var(--borde);
  cursor: pointer;
}
.cal-flecha:active { transform: scale(.94); }
.cal-flecha:disabled { opacity: .35; cursor: default; }
/* El título es un botón: abre la rejilla de meses. Ocupa el hueco que queda
   entre las cuatro flechas, y no encoge las flechas al hacerlo. */
.cal-titulo {
  flex: 1 1 auto; min-width: 0; padding: 8px 6px; border-radius: 10px;
  font-size: .95rem; font-weight: 600; text-transform: capitalize;
  background: transparent; color: var(--texto); border: 1px solid transparent;
  cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-titulo:hover { background: var(--fondo-3); border-color: var(--borde); }
.cal-titulo:active { transform: scale(.98); }
.cal-meses { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.cal-mes {
  padding: 12px 4px; border-radius: 10px; font-size: .86rem; text-transform: capitalize;
  background: var(--fondo-3); color: var(--texto); border: 1px solid var(--borde);
  cursor: pointer;
}
.cal-mes.elegido { background: var(--marca); color: #fff; border-color: var(--marca); }
.cal-mes:disabled { opacity: .3; cursor: default; }
.cal-rejilla { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-nombre {
  text-align: center; font-size: .72rem; color: var(--texto-3);
  padding-bottom: 2px; font-weight: 600;
}
.cal-dia {
  min-height: 40px; border-radius: 10px; border: 1px solid transparent;
  background: var(--fondo-3); color: var(--texto); font-size: .88rem;
  font-variant-numeric: tabular-nums; cursor: pointer; padding: 0;
}
.cal-dia:active { transform: scale(.93); }
.cal-dia:disabled { opacity: .35; cursor: default; }
.cal-dia.hoy { border-color: var(--borde-fuerte); font-weight: 700; }
.cal-dia.libre { background: var(--marca-tenue); color: var(--marca); border-color: var(--marca-oscura); }
.cal-dia.algo { background: var(--fondo-3); color: var(--texto); border-color: var(--aviso); }
.cal-dia.completo { color: var(--texto-3); text-decoration: line-through; }
.cal-dia.elegido {
  background: var(--marca); color: var(--sobre-marca); font-weight: 700;
  border-color: var(--marca);
}

/* La fecha como campo: el botón enseña el día escrito con todas sus letras,
   que es como se dice en voz alta, y despliega el calendario debajo. */
.cal-campo {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; padding: 11px 12px; border-radius: 10px; text-align: left;
  background: var(--fondo-3); color: var(--texto);
  border: 1px solid var(--borde-fuerte); font-size: .95rem; cursor: pointer;
}
.cal-cuerpo {
  margin-top: 6px; padding: 10px; border-radius: 12px;
  background: var(--fondo-2); border: 1px solid var(--borde);
}
.cal-leyenda {
  display: flex; gap: 12px; flex-wrap: wrap;
  font-size: .76rem; color: var(--texto-3);
}
.cal-leyenda span { display: inline-flex; align-items: center; gap: 5px; }
.cal-leyenda i {
  width: 11px; height: 11px; border-radius: 3px; display: inline-block;
  background: var(--fondo-3); border: 1px solid var(--borde);
}
.cal-leyenda i.libre { background: var(--marca-tenue); border-color: var(--marca-oscura); }
.cal-leyenda i.algo { border-color: var(--aviso); }
.cal-leyenda i.completo { background: var(--fondo); border-color: var(--texto-3); }

/* El cuaderno leído en pantalla: son las hojas del PDF de verdad, así que lo
   que se ve aquí es exactamente lo que se imprime. Fondo oscuro alrededor para
   que el papel se lea como papel. */
.visor-hojas {
  background: var(--fondo); border: 1px solid var(--borde); border-radius: 10px;
  overflow: auto; max-height: 68vh; text-align: center; padding: 8px;
  -webkit-overflow-scrolling: touch;
}
.visor-hojas img {
  width: 100%; height: auto; border-radius: 4px; background: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .35); user-select: none;
}
.visor-barra {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin-top: 8px;
}
.visor-barra .tenue { font-variant-numeric: tabular-nums; min-width: 110px; text-align: center; }

/* Para lectores de pantalla y nada más. El cronómetro cambia cada segundo:
   leerlo en voz alta sería insoportable, así que se marca aria-hidden y al
   lado va esto, que dice lo mismo una vez. */
.oculto-visual {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Mi estante: cada reactivo es una tarjeta plegada. Punto de estado a la
   izquierda, nombre y dónde al centro, cuántos frascos a la derecha. Lo que se
   acabó queda desvaído: ya avisó y ya está en la lista de compra. */
details.grupo-reactivo {
  background: var(--fondo-2); border: 1px solid var(--borde);
  border-radius: var(--radio); margin-bottom: 8px; overflow: hidden;
}
details.grupo-reactivo > summary {
  display: flex; align-items: center; gap: 11px; padding: 11px 13px;
  cursor: pointer; list-style: none; user-select: none;
}
details.grupo-reactivo > summary::-webkit-details-marker { display: none; }
details.grupo-reactivo > summary .linea-2 { display: block; font-size: .8rem; margin-top: 1px; }
details.grupo-reactivo > summary .cuantos {
  display: flex; flex-direction: column; align-items: center; min-width: 46px; line-height: 1.05;
}
details.grupo-reactivo > summary .cuantos b { font-size: 1.15rem; }
details.grupo-reactivo > summary .cuantos small { font-size: .6875rem; color: var(--texto-3); }
details.grupo-reactivo > summary .punto { width: 13px; height: 13px; flex: 0 0 13px; }
details.grupo-reactivo[open] > summary { border-bottom: 1px solid var(--borde); }
details.grupo-reactivo .grupo-detalle { padding: 6px 13px 2px; }
/* Desvaído solo lo que dice «no queda» (punto y nombre): la segunda línea y el
   «📦 pedido» siguen legibles, que es justo lo útil. */
details.grupo-reactivo.agotado > summary > .punto,
details.grupo-reactivo.agotado > summary > .crece > b { opacity: .55; }


/* ---------- estados y flotantes (revisión estética 2026-10-01) ---------- */
/* Tres colores de estado, siempre los mismos: hay, queda poco, no queda. */
:root {
  --estado-ok: var(--ok);
  --estado-poco: var(--aviso);
  --estado-sin: var(--error);
}
/* Con el botón de volver a la ejecución hay tres flotantes en la esquina: el
   contenido deja aire debajo para que no tapen la última fila. */
body.con-ejecucion main { padding-bottom: 200px; }
/* Al bajar se apartan (dejan ver la columna derecha: «Reservar», la cifra de
   frascos); al subir vuelven. */
.flotante { transition: transform .2s ease, opacity .2s ease; }
body.flotantes-fuera .flotante { transform: translateX(84px); opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .flotante { transition: none; } }
/* Sin resultados en una búsqueda: el mismo bloque que una lista vacía, más
   bajo. Antes era un párrafo gris suelto que parecía un error. */
.lista-vacia.vacio-chico { padding: 16px 14px; font-size: .86rem; margin: 6px 0; }
.lista-vacia.vacio-chico .emoji { font-size: 1.3rem; margin-bottom: 2px; }
/* La ejecución en marcha: una sola fila de acciones bajo el botón principal. */
.acciones-paso { display: flex; gap: 6px; }
.acciones-paso button {
  flex: 1; flex-direction: column; gap: 1px; min-height: 52px; padding: 6px 4px;
  font-size: 1.05rem; line-height: 1;
}
.acciones-paso button small { font-size: .6875rem; color: var(--texto-3); font-weight: 500; }
/* El ▶ de cada paso de «Lo que sigue», centrado y de su tamaño. */
.paso > button { align-self: center; }
/* La misma tarjeta que Mi estante, para listas cuya ficha es una hoja
   (anticuerpos): sin desplegar, con la misma cabecera. */
.grupo-reactivo.tarjeta-fila {
  background: var(--fondo-2); border: 1px solid var(--borde);
  border-radius: var(--radio); margin-bottom: 8px; overflow: hidden;
}
.grupo-reactivo.tarjeta-fila > .cabeza {
  display: flex; align-items: center; gap: 11px; padding: 11px 13px; cursor: pointer;
}
.grupo-reactivo.tarjeta-fila .linea-2 { display: block; font-size: .8rem; margin-top: 1px; }
.grupo-reactivo.tarjeta-fila .cuantos {
  display: flex; flex-direction: column; align-items: center; min-width: 46px; line-height: 1.05;
}
.grupo-reactivo.tarjeta-fila .cuantos b { font-size: 1.15rem; }
.grupo-reactivo.tarjeta-fila .cuantos small { font-size: .6875rem; color: var(--texto-3); }
.grupo-reactivo.tarjeta-fila .punto { width: 13px; height: 13px; flex: 0 0 13px; }
/* Un preparado: la misma tarjeta, teñida de lila y con su sello, para
   distinguirlo de un frasco comprado (Germán, 2026-10-23). */
.grupo-reactivo.tarjeta-fila.preparado { background: var(--preparado-suave); border-color: var(--preparado-linea); }
.sello-preparado { display: inline-block; font-size: .6875rem; font-weight: 650; letter-spacing: .02em;
  color: var(--preparado); border: 1px solid var(--preparado-linea); border-radius: 999px; padding: 0 6px;
  margin-left: 4px; vertical-align: 1px; }
.grupo-reactivo.tarjeta-fila.preparado .cuantos { cursor: pointer; border-radius: 8px; padding: 2px 4px; }
.grupo-reactivo.tarjeta-fila.preparado .cuantos:active { background: var(--preparado-suave); }
/* El color del canal (fluoróforo), ya no en el punto: el punto es el estado. */
.chip-canal { display: inline-block; width: 10px; height: 10px; border-radius: 3px; vertical-align: middle;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.25); }

/* Diagnóstico plegado en una línea (alarmas en Ajustes). */
details.plegable.diag > summary { display: flex; align-items: center; gap: 8px; color: var(--texto); font-size: .9rem; }
details.plegable.diag > summary .punto { width: 10px; height: 10px; border-radius: 50%; flex: none; }
details.plegable.diag[open] > summary { margin-bottom: 6px; }

/* Pestañas que no se parten en dos líneas: «Dónde está», «Mi laboratorio»
   y «Peticiones 3» caben en una sola; si no caben, se recortan antes que saltar. */
.ambitos .ambito, .segmentos button { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }

/* Las calculadoras, en una sola fila que se desliza con el dedo. */
.fila-chips {
  display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none;
  margin-left: -16px; margin-right: -16px; padding: 2px 16px;
  scroll-snap-type: x proximity;
}
.fila-chips::-webkit-scrollbar { display: none; }
.fila-chips > button { flex: none; white-space: nowrap; scroll-snap-align: start; }
/* Comunidad: cada pestaña ocupa lo que mide su nombre. */
#comunidad-pestanas button { flex: auto; padding: 6px 8px; }
/* La tarjeta de anticuerpos también se desliza: tiene que tapar el fondo rojo
   y el de editar, que solo se ven al arrastrarla. */
.deslizable > .tarjeta-fila {
  position: relative; z-index: 1; margin-bottom: 0; background: var(--fondo-2);
  transition: transform .18s ease; touch-action: pan-y;
}
.deslizable:has(> .tarjeta-fila) { border-radius: var(--radio); margin-bottom: 8px; }
/* Cada frasco dentro de su grupo también se desliza (editar / quitar). */
.deslizable:has(> .frasco) { border-radius: 0; margin: 0 -6px; }
.deslizable:has(> .frasco) .fondo { opacity: 0; }
.deslizable.va-editar:has(> .frasco) .fondo.editar, .deslizable.va-quitar:has(> .frasco) .fondo.quitar { opacity: 1; }
.deslizable > .frasco {
  position: relative; z-index: 1; background: var(--fondo-2); padding: 0 6px;
  transition: transform .18s ease; touch-action: pan-y;
}

/* ======================= Inicio: tu día ======================= */
/* Del boceto aprobado el 2026-10-01. Una sola cosa grande y en color (la
   ejecución que va o, si no hay, «Ejecutar protocolo»); todo lo demás,
   tranquilo y en las superficies de siempre. */
:root {
  --hero-a: #0E5F6E; --hero-b: #0B3C48; --hero-texto: #E8F8FB;
  --hero-punto: #2FD8EF; --hero-aro: rgba(255, 255, 255, .16); --hero-caja: rgba(0, 0, 0, .22);
  --hero-boton: #2FD8EF; --hero-boton-texto: #04141A; --hero-sombra: 0 10px 30px rgba(0, 0, 0, .45);
}
@media (prefers-color-scheme: light) {
  :root {
    --hero-a: #086E80; --hero-b: #05505E; --hero-texto: #FFFFFF;
    --hero-punto: #7FE9F7; --hero-aro: rgba(255, 255, 255, .22); --hero-caja: rgba(0, 0, 0, .16);
    --hero-boton: #FFFFFF; --hero-boton-texto: #05505E; --hero-sombra: 0 10px 28px rgba(5, 80, 94, .28);
  }
}
#p-inicio { display: none; }
#p-inicio.activa { display: flex; flex-direction: column; gap: 18px; }
#p-inicio > div:empty, #p-inicio > figure:empty { display: none; }
.hoy-titulo { margin: 0 0 8px; }
.hoy-saludo { display: flex; flex-direction: column; gap: 2px; }
.hoy-saludo .tenue { font-size: .84rem; }
.hoy-saludo .tenue::first-letter { text-transform: uppercase; }
.hoy-saludo h2 { margin: 0; font-size: 1.4rem; font-weight: 650; letter-spacing: -.01em; text-wrap: balance; }
.hoy-saludo p { margin: 4px 0 0; color: var(--texto-2); font-size: .92rem; line-height: 1.45; }

.hoy-hero {
  border-radius: 20px; padding: 18px; display: flex; flex-direction: column; gap: 14px;
  background: linear-gradient(150deg, var(--hero-a) 0%, var(--hero-b) 100%);
  color: var(--hero-texto); box-shadow: var(--hero-sombra);
}
.hoy-eyebrow { display: flex; align-items: center; gap: 8px; font-size: .74rem; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; opacity: .88; }
.punto-vivo { width: 8px; height: 8px; border-radius: 50%; background: var(--hero-punto);
  animation: latido 2s ease-in-out infinite; }
@keyframes latido { 50% { opacity: .35; } }
.hoy-hero-fila { display: flex; gap: 16px; align-items: center; }
.hoy-hero-titulo { font-size: 1.2rem; font-weight: 650; line-height: 1.25; text-wrap: balance; }
.hoy-hero-paso { font-size: .9rem; opacity: .86; margin-top: 3px; line-height: 1.35; }
.anillo { position: relative; width: 72px; height: 72px; flex: none; }
.anillo svg { width: 72px; height: 72px; transform: rotate(-90deg); }
.anillo circle { fill: none; stroke-width: 6; }
.anillo .fondo-anillo { stroke: var(--hero-aro); }
.anillo .lleno-anillo { stroke: var(--hero-punto); stroke-linecap: round; transition: stroke-dasharray .6s ease; }
.anillo b { position: absolute; inset: 0; display: grid; place-items: center; font-size: .95rem; }
.hoy-alarma { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 14px;
  background: var(--hero-caja); font-size: .82rem; line-height: 1.3; }
.hoy-alarma svg { width: 22px; height: 22px; flex: none; }
.hoy-alarma-que { opacity: .85; color: inherit; }
.hoy-reloj { font-family: var(--tipo-mono); font-size: 1.6rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.hoy-hero-boton {
  display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; width: 100%;
  border: 0; border-radius: 14px; background: var(--hero-boton); color: var(--hero-boton-texto);
  font-weight: 650; font-size: 1rem;
}
.hoy-hero-boton svg { width: 16px; height: 16px; }

.hoy-otra {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; min-height: 56px;
  margin-bottom: 8px; border-radius: 14px; border: 1px solid var(--borde); background: var(--fondo-2);
  color: var(--texto); text-align: left; font-weight: 400;
}
.hoy-otra .tenue { font-size: .8rem; white-space: nowrap; }
.hoy-barra { height: 5px; margin-top: 7px; border-radius: 3px; background: var(--fondo-3); overflow: hidden; }
.hoy-barra > div { height: 100%; border-radius: 3px; background: var(--marca); }

.hoy-accesos { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.hoy-acceso { display: flex; flex-direction: column; align-items: center; gap: 7px; padding: 2px 0;
  border: 0; background: none; color: var(--texto); font-size: .76rem; font-weight: 500; line-height: 1.2; }
.hoy-acceso .circulo { width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center;
  background: var(--marca-suave); color: var(--marca); }
.hoy-acceso svg { width: 24px; height: 24px; }

.hoy-bento { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.hoy-bloque {
  display: flex; flex-direction: column; align-items: stretch; gap: 6px; padding: 14px; min-height: 104px;
  border-radius: 16px; border: 1px solid var(--borde); background: var(--fondo-2); color: var(--texto);
  text-align: left; font-weight: 400; min-width: 0;
}
.hoy-bloque.ancho2 { grid-column: span 2; min-height: 0; }
.hoy-bloque.tono-aviso { background: var(--aviso-suave); border-color: var(--aviso-linea); }
.hoy-bloque.tono-error { background: var(--error-suave); border-color: var(--error-linea); }
.hoy-bloque[aria-expanded="true"] { outline: 2px solid var(--marca); outline-offset: -1px; }
.hoy-bloque-titulo { display: flex; align-items: center; gap: 7px; font-size: .8rem; color: var(--texto-2); }
.hoy-bloque-titulo svg { width: 18px; height: 18px; }
.hoy-bloque-titulo .punto { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.hoy-bloque-n { font-size: 1.75rem; font-weight: 700; line-height: 1; }
.hoy-bloque-detalle { font-size: .8rem; color: var(--texto-2); line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hoy-reservas { display: flex; gap: 8px; }
.hoy-reserva { flex: 1; min-width: 0; padding: 10px; border-radius: 12px; background: var(--fondo-3);
  display: flex; flex-direction: column; gap: 2px; font-size: .8rem; color: var(--texto-2); }
.hoy-reserva b { font-size: 1.1rem; color: var(--texto); }
.hoy-detalle { margin-top: 10px; padding: 4px 14px 8px; border-radius: 16px; border: 1px solid var(--borde); background: var(--fondo-2); }
.hoy-detalle-fila { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 0; border: 0;
  border-bottom: 1px solid var(--borde); background: none; color: var(--texto); text-align: left;
  font-size: .9rem; font-weight: 400; }
.hoy-detalle-fila .tenue { font-size: .8rem; white-space: nowrap; }
.hoy-detalle .enlace-suave { display: inline-block; margin-top: 8px; border: 0; background: none; }

.hoy-linea { list-style: none; margin: 0; padding: 0; }
.hoy-linea li button { display: flex; gap: 12px; width: 100%; min-height: 58px; padding: 0; border: 0;
  background: none; color: var(--texto); text-align: left; font-weight: 400; align-items: stretch; }
.hoy-linea .hora { width: 46px; flex: none; font-size: .8rem; color: var(--texto-2); padding-top: 2px; }
.hoy-linea .marca-linea { width: 14px; flex: none; display: flex; flex-direction: column; align-items: center; }
.hoy-linea .marca-linea::before { content: ""; width: 12px; height: 12px; margin-top: 3px; border-radius: 50%;
  box-sizing: border-box; border: 2px solid var(--texto-3); background: var(--fondo-2); flex: none; }
.hoy-linea .marca-linea > span { width: 2px; flex-grow: 1; background: var(--borde); }
.hoy-linea li:last-child .marca-linea > span { visibility: hidden; }
.hoy-linea .hoy-que { display: block; font-size: .94rem; font-weight: 500; }
.hoy-linea .hoy-donde { display: block; font-size: .8rem; color: var(--texto-3); padding-bottom: 14px; }
.hoy-linea li.hecho .hoy-que, .hoy-linea li.hecho .hora { color: var(--texto-3); font-weight: 400; }
.hoy-linea li.hecho .marca-linea::before { background: var(--texto-3); }
.hoy-linea li.ahora .hoy-que { font-weight: 650; }
.hoy-linea li.ahora .hora { color: var(--marca); font-weight: 600; }
.hoy-linea li.ahora .marca-linea::before { border-color: var(--marca); background: var(--marca); }

#ultimas-corridas { margin-top: -10px; }
.hoy-frase { margin: 0; padding: 14px 16px; border-radius: 16px; background: var(--fondo-3); }
.hoy-frase blockquote { margin: 0; font-size: .9rem; line-height: 1.5; color: var(--texto-2); }
.hoy-frase figcaption { margin-top: 6px; font-size: .76rem; color: var(--texto-3); }


.hoy-entra { animation: hoyEntra .45s cubic-bezier(.34, 1.4, .64, 1) both; }
@keyframes hoyEntra { from { transform: translateY(10px); opacity: .4; } to { transform: none; opacity: 1; } }
.hoy-hero-boton, .hoy-otra, .hoy-acceso .circulo, .hoy-bloque { transition: transform .18s cubic-bezier(.34, 1.56, .64, 1); }
.hoy-hero-boton:active, .hoy-otra:active, .hoy-acceso:active .circulo, .hoy-bloque:active { transform: scale(.97); }
@media (prefers-reduced-motion: reduce) {
  .hoy-entra, .punto-vivo { animation: none; }
  .hoy-hero-boton, .hoy-otra, .hoy-acceso .circulo, .hoy-bloque, .anillo .lleno-anillo { transition: none; }
}

/* ======================= Only Good Antibodies ======================= */
/* La validación por knockout de YCharOS. Sus palabras y sus cuatro niveles;
   el respaldo limitado no se pinta como fracaso (lo piden ellos). */
.oga-bloque { margin: 12px 0; padding: 14px; border-radius: var(--radio);
  border: 1px solid var(--ok-linea); background: var(--ok-suave); }
.oga-cabeza { display: flex; gap: 10px; align-items: center; }
.oga-sello { width: 36px; height: 36px; flex: none; border-radius: 50%; display: grid; place-items: center;
  font-size: .72rem; font-weight: 700; letter-spacing: .04em; background: var(--ok); color: var(--fondo-2); }
.oga-chip { display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: .74rem; font-weight: 600;
  border: 1px solid var(--borde); background: var(--fondo-2); color: var(--texto-2); }
.oga-chip.oga-supportive { border-color: var(--ok-linea); color: var(--ok); }
.oga-chip.oga-limited_support { border-color: var(--marca-linea); color: var(--marca); }
.oga-chip.oga-not_supportive { color: var(--texto-3); }
.oga-mini { display: inline-block; padding: 2px 7px; border-radius: 999px; font-size: .7rem; font-weight: 700;
  border: 1px solid var(--ok-linea); background: var(--ok-suave); color: var(--ok); white-space: nowrap; }
.oga-atribucion { margin-top: 10px; font-size: .72rem; color: var(--texto-3); }
.oga-bloque a { color: var(--marca); }


/* ── Calculadoras: menú en rejilla con íconos y controles segmentados ──── */
.calc-menu .tab-calc, .calc-menu .tab-todas {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  border-radius: 14px; background: var(--fondo-2); color: var(--texto-2); border: 1px solid var(--borde);
  font-weight: 600; line-height: 1.15; text-align: center; cursor: pointer;
}
.calc-menu .tab-calc svg, .calc-menu .tab-todas svg { flex: none; }
.calc-menu span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.calc-menu .tab-calc.activa {
  background: color-mix(in srgb, var(--marca) 14%, var(--fondo-2)); color: var(--marca);
  border-color: var(--marca);
}
.calc-menu button:active { transform: scale(.97); }

/* Al entrar: la cuadrícula ocupa toda la pantalla y no se ve ninguna calculadora. */
.calc-inicio .calc-menu {
  display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 1fr; gap: 10px; margin: 4px 0 8px;
  min-height: calc(100dvh - var(--alto-barra, 76px) - 56px - var(--seguro-abajo, 0px) - 44px);
}
.calc-inicio .calc-menu .tab-calc { padding: 12px 4px; font-size: .86rem; min-height: 92px; }
.calc-inicio .calc-menu .tab-calc svg { width: 34px; height: 34px; }
.calc-inicio .calc-menu .tab-calc.activa { background: var(--fondo-2); color: var(--texto-2); border-color: var(--borde); }
.calc-inicio .calc-menu .tab-todas { display: none; }
.calc-inicio #calc-contenido, .calc-inicio #calc-panel { display: none !important; }
@media (min-width: 560px) { .calc-inicio .calc-menu { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 900px) { .calc-inicio .calc-menu { min-height: 0; grid-auto-rows: 120px; } }

/* Con una abierta: la cuadrícula se recoge en una fila que se desliza de lado. */
.calc-abierta .calc-menu {
  display: flex; gap: 6px; overflow-x: auto; margin: 2px -16px 14px; padding: 2px 16px 6px;
  scroll-snap-type: x proximity; scrollbar-width: none;
}
.calc-abierta .calc-menu::-webkit-scrollbar { display: none; }
.calc-abierta .calc-menu .tab-calc, .calc-abierta .calc-menu .tab-todas {
  flex: 0 0 auto; min-width: 68px; padding: 7px 8px 5px; font-size: .7rem; scroll-snap-align: center;
}
.calc-abierta .calc-menu svg { width: 20px; height: 20px; }
.calc-abierta .calc-menu .tab-todas { background: var(--fondo-3); }

/* Pestañas dentro de una calculadora (Cultivo): un control segmentado. */
.segmentos {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 2px; padding: 3px;
  margin: 0 0 14px; border-radius: 12px; background: var(--fondo-3, var(--fondo-2));
  border: 1px solid var(--borde);
}
.segmentos > button {
  padding: 8px 2px; border-radius: 9px; border: none; background: transparent;
  color: var(--texto-2); font-size: .78rem; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.segmentos > button.activa { background: var(--marca); color: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.15); }

/* Elegir entre dos maneras (Manual / Con foto). */
.eleccion { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.eleccion > button {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 6px;
  padding: 18px 12px; border-radius: 14px; border: 1px solid var(--borde);
  background: var(--fondo-2); color: var(--texto); text-align: center; cursor: pointer;
}
.eleccion > button svg { width: 34px; height: 34px; color: var(--marca); }
.eleccion > button b { font-size: 1rem; }
.eleccion > button .tenue { font-size: .8rem; line-height: 1.3; }
.eleccion > button:active { transform: scale(.98); border-color: var(--marca); }

/* Copiar y guardar: solo cuando hay un resultado que copiar. */
.calc-acciones { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
#calc-contenido:not(:has(.numerote)) .calc-acciones { display: none; }
/* En pantalla grande (escritorio, la app del Mac) la calculadora usa el
   espacio: la cuadrícula se reparte en más columnas, con baldosas más altas,
   y los formularios se abren a tres columnas (pedido de Germán, 2026-10-13:
   «queda pequeño todo centrado»). */
@media (min-width: 900px) {
  .calc-inicio .calc-menu { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); grid-auto-rows: 150px; gap: 14px; }
  .calc-inicio .calc-menu .tab-calc { font-size: .95rem; }
  .calc-inicio .calc-menu .tab-calc svg { width: 40px; height: 40px; }
  .calc-abierta .calc-menu { flex-wrap: wrap; overflow-x: visible; margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }
  #calc-contenido .rejilla-2 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
}

/* Comparar grupos: barras con su error y cada muestra como punto. */
.grafico-grupos { display: block; width: 100%; max-width: 440px; height: auto; margin: 8px auto 0; }
.tabla-grupos { width: 100%; border-collapse: collapse; font-size: .84rem; margin-top: 6px; }
.tabla-grupos th, .tabla-grupos td { padding: 5px 4px; border-bottom: 1px solid var(--borde); text-align: right; white-space: nowrap; }
.tabla-grupos th:first-child, .tabla-grupos td:first-child { text-align: left; }
.boton-denunciar { padding: 2px 8px; min-height: 0; font-size: .8rem; line-height: 1.4; margin-left: 4px; vertical-align: middle; }
/* NanoDrop por lecturas: qué columnas se anotan, y los valores de cada muestra. */
.chip-opcion { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--borde);
  border-radius: 999px; font-size: .86rem; cursor: pointer; background: var(--fondo-2); }
.chip-opcion input { width: auto; margin: 0; }
.chip-opcion:has(input:checked) { border-color: var(--marca); color: var(--marca); }
.ndm-valores { display: grid; grid-template-columns: repeat(auto-fit, minmax(72px, 1fr)); gap: 6px; margin-top: 8px; }
.ndm-valores input { padding: 6px 8px; }
/* El secundario del panel: en su propia línea y tocable. */
.fila-secundario { display: flex; align-items: center; gap: 8px; width: 100%; margin-top: 8px; padding: 8px 10px;
  background: var(--fondo-2); border: 1px solid var(--borde); border-radius: 10px; color: var(--texto);
  text-align: left; font-weight: 400; }
.fila-secundario .codigo { display: block; font-weight: 600; font-size: .86rem; overflow-wrap: anywhere; }
.fila-secundario .chico-accion { flex-shrink: 0; font-size: .8rem; color: var(--marca); font-weight: 600; }
/* Volver a la calculadora: píldora abajo a la izquierda, encima de la barra. */
.flotante-volver { position: fixed; left: 16px; bottom: calc(56px + var(--seguro-abajo) + 16px); z-index: 40;
  display: flex; align-items: stretch; border-radius: 999px; overflow: hidden;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .35); background: var(--marca); }
.flotante-volver button { background: transparent; color: var(--sobre-marca); border: none; border-radius: 0;
  padding: 0 12px; height: 46px; font-weight: 600; font-size: .9rem; }
.flotante-volver .volver-x { padding: 0 12px 0 6px; font-size: 1.1rem; opacity: .85; }
body.flotantes-fuera .flotante-volver { opacity: 0; pointer-events: none; }
/* «Todas» siempre a mano: fijo a la izquierda mientras la fila se desliza. */
.calc-abierta .calc-menu .tab-todas { position: sticky; left: 0; z-index: 2;
  box-shadow: 6px 0 10px -6px rgba(0, 0, 0, .35); }

/* Carga por lote: lo leído con dudas, en amarillo, como en la etiqueta suelta. */
.campo.dudoso input { background: var(--aviso-suave); border-color: var(--aviso-linea); }
.campo.dudoso label::after { content: " ?"; color: var(--aviso); font-weight: 700; }
.lr-miniatura { width: 64px; height: 64px; object-fit: cover; border-radius: 8px; cursor: zoom-in;
  border: 1px solid var(--borde); flex: none; }

/* La biblioteca, agrupada por tipo de ensayo (2026-10-13). */
.grupo-biblio { margin: 0 0 14px; }
.grupo-biblio > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: .95rem; padding: 8px 2px; border-bottom: 1px solid var(--borde); margin-bottom: 10px;
}
.grupo-biblio > summary::-webkit-details-marker { display: none; }
.grupo-biblio > summary::before { content: "▾"; color: var(--texto-2); transition: transform .15s; }
.grupo-biblio:not([open]) > summary::before { transform: rotate(-90deg); }
@media (min-width: 900px) {
  .grupo-biblio-lista { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
  .grupo-biblio-lista .tarjeta { min-width: 0; }
  .grupo-biblio-lista .tarjeta { margin-bottom: 0; }
}

/* Panel Ac (2026-10-13): verde lo que tengo, ámbar lo que se pide prestado,
   azul lo que hay que comprar. */
.pac-ab, .pac-op {
  display: block; width: 100%; text-align: left; margin-top: 8px; padding: 9px 11px; border-radius: 10px;
  border: 1px dashed var(--borde); background: var(--fondo-2); color: var(--texto); cursor: pointer; font-size: .9rem;
}
.pac-op { border-style: solid; margin-top: 6px; }
.pac-tengo { border-color: var(--estado-ok, #2f9e44); background: color-mix(in srgb, var(--estado-ok, #2f9e44) 10%, transparent); }
.pac-centro { border-color: var(--aviso, #f08c00); background: color-mix(in srgb, var(--aviso, #f08c00) 12%, transparent); }
.pac-comprar { border-color: #3b5bdb; background: color-mix(in srgb, #3b5bdb 10%, transparent); }
.pac-chip { font-size: .74rem; padding: 2px 8px; border-radius: 999px; border: 1px solid; white-space: nowrap; }
.pac-tabla-caja { overflow-x: auto; }
.pac-tabla td, .pac-tabla th { padding: 6px 8px; vertical-align: top; }
@media (min-width: 900px) { #pac-filas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } #pac-filas .tarjeta { margin-bottom: 0; } }

/* La gradilla de una caja: rótulos de fila y columna y un hueco por celda. */
.gradilla { display: grid; gap: 3px; margin-top: 6px; align-items: center; }
.gradilla .rotulo { font-size: .6875rem; color: var(--texto-3); text-align: center; font-weight: 600; padding: 0 2px; }
.gradilla .hueco { aspect-ratio: 1; min-width: 0; border-radius: 5px; border: 1px solid var(--ok-linea);
  background: var(--ok-suave); color: var(--ok); font-size: .6875rem; display: flex; align-items: center;
  justify-content: center; overflow: hidden; cursor: pointer; user-select: none; line-height: 1; }
.gradilla .hueco.ocupado { border-color: var(--marca); background: var(--marca); color: #fff; font-weight: 700; }

/* Material en dos filas (2026-10-20): arriba las cuatro de siempre, abajo
   partidores, preparaciones, almacenamiento y compras, un poco más bajas. */
/* Rejilla y no flex con 25 %: el hueco de 2 px entre botones sumaba más del
   100 % y salían de tres en tres (3×3 en el teléfono de Germán). */
#tabs-material { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) auto; gap: 0; }
#tabs-material button { min-width: 0; overflow: hidden; }
#tabs-material button { white-space: nowrap; text-overflow: ellipsis; }
#tabs-material button.fila2 { min-height: 44px; padding: 5px 2px 6px; font-size: .6875rem; }
#tabs-material button.fila2 svg { width: 18px; height: 18px; padding: 2px 9px; }
#tabs-material button svg { max-width: calc(100% - 4px); }
#tabs-material button.fila2 { border-top: 1px solid var(--borde); }

/* Seis iconos abajo desde que Salas tiene el suyo: algo más apretados. */
@media (max-width: 899px) {
  nav.abajo button { font-size: .6875rem; padding-left: 0; padding-right: 0; }
  nav.abajo svg, nav.abajo button.activa svg { padding: 4px 8px; }
}

/* Equipos agrupados (2026-10-20): cada familia es una tarjeta con icono,
   contador y flecha que gira; los equipos van dentro como filas de una lista,
   sin una caja dentro de otra. */
details.grupo-equipos {
  background: var(--fondo-2); border: 1px solid var(--borde);
  border-radius: 16px; margin-bottom: 10px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}
details.grupo-equipos > summary {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px;
  cursor: pointer; list-style: none; user-select: none;
}
details.grupo-equipos > summary::-webkit-details-marker { display: none; }
details.grupo-equipos .ge-icono {
  width: 34px; height: 34px; flex: 0 0 34px; border-radius: 10px;
  display: grid; place-items: center; font-size: 1.05rem; background: var(--marca-suave);
}
details.grupo-equipos .ge-nombre { font-weight: 650; font-size: .96rem; color: var(--texto); }
details.grupo-equipos .ge-pill {
  font-size: .74rem; font-weight: 600; padding: 2px 9px; border-radius: 999px;
  background: var(--fondo-3, var(--fondo)); color: var(--texto-2); font-variant-numeric: tabular-nums;
}
details.grupo-equipos .ge-pill.marca { background: var(--marca-suave); color: var(--marca); }
details.grupo-equipos .ge-pill.aviso { background: color-mix(in srgb, var(--aviso) 18%, transparent); color: var(--aviso); }
details.grupo-equipos .ge-flecha {
  width: 8px; height: 8px; flex: 0 0 8px; margin: 0 2px 3px 4px;
  border-right: 2px solid var(--texto-3); border-bottom: 2px solid var(--texto-3);
  transform: rotate(-45deg); transition: transform .2s;
}
details.grupo-equipos[open] .ge-flecha { transform: rotate(45deg); margin-bottom: 6px; }
details.grupo-equipos[open] > summary { border-bottom: 1px solid var(--borde); }
/* Dentro, los equipos sin caja propia: una lista con separadores. */
details.grupo-equipos > details.caja-equipo {
  border: 0; border-radius: 0; margin: 0; background: transparent;
  border-bottom: 1px solid var(--borde);
}
details.grupo-equipos > details.caja-equipo:last-child { border-bottom: 0; }
details.grupo-equipos > details.caja-equipo > summary { padding: 10px 14px 10px 18px; }
details.grupo-equipos > details.caja-equipo[open] { background: var(--fondo); }

/* Un botón esperando al servidor: la rueda en vez del texto, sin cambiar de
   tamaño (Eventos.ocupar). */
button.esperando { position: relative; color: transparent !important; pointer-events: none; }
button.esperando::after { content: ''; position: absolute; inset: 0; margin: auto; width: 16px; height: 16px;
  border: 2px solid currentColor; border-color: var(--borde); border-top-color: var(--marca);
  border-radius: 50%; animation: gira .7s linear infinite; }

/* Un sitio del estante agrupado por ubicación: plegado, una línea por sitio. */
details.sitio-estante { border-bottom: 1px solid var(--borde); }
details.sitio-estante > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 6px;
  margin: 0; padding: 12px 2px; }
details.sitio-estante > summary::-webkit-details-marker { display: none; }
details.sitio-estante > summary::after { content: '›'; margin-left: auto; font-size: 1.1rem; transition: transform .15s; }
details.sitio-estante[open] > summary::after { transform: rotate(90deg); }
details.sitio-estante[open] { padding-bottom: 8px; }

/* ✎ en el encabezado de un sitio agrupado: editarlo sin salir de la lista. */
.mini-editar { margin-left: 6px; padding: 2px 8px; min-height: 0; font-size: .85rem; line-height: 1.4;
  background: transparent; color: var(--marca); border: 1px solid var(--borde); border-radius: 999px;
  text-transform: none; letter-spacing: 0; }

/* Los filtros de Reactivos (Todo · Químicos · Anticuerpos · Partidores ·
   Preparados): pastillas que se deslizan de lado si no caben. */
.chips-filtro { display: flex; gap: 6px; overflow-x: auto; padding: 2px 0 10px; scrollbar-width: none; }
.chips-filtro::-webkit-scrollbar { display: none; }
.chips-filtro button { flex: 0 0 auto; min-height: 32px; padding: 5px 13px; border-radius: 999px;
  border: 1px solid var(--borde); background: var(--fondo-2); color: var(--texto-2); font-size: .84rem; font-weight: 500; }
.chips-filtro button.activa { background: var(--marca-suave); border-color: var(--marca); color: var(--marca); font-weight: 650; }

/* La capacidad del sitio en su encabezado: «45/60». */
.capacidad-sitio { margin-left: auto; font-weight: 650; font-size: .8rem; text-transform: none; letter-spacing: 0; }
.capacidad-sitio + .mini-editar { margin-left: 8px; }
details.sitio-estante > summary:has(.capacidad-sitio)::after { margin-left: 8px; }

/* Cajitas por tipo (Biblioteca, Recetas): ícono, tipo y cuántos. */
.cajitas-tipo { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; margin: 6px 0 12px; }
.cajita-tipo { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-height: 92px;
  padding: 12px; border: 1px solid var(--borde); border-radius: 14px; background: var(--fondo-2);
  color: var(--texto); text-align: left; position: relative; }
.cajita-tipo .icono { font-size: 1.6rem; line-height: 1; }
.cajita-tipo .nombre { font-weight: 650; font-size: .88rem; line-height: 1.2; }
.cajita-tipo .n { position: absolute; top: 10px; right: 12px; font-weight: 700; color: var(--marca); font-size: .9rem; }
.cajita-tipo:active { background: var(--marca-suave); }

/* El campo desde el que se vino (el espacio tocado en la lista). */
input.resaltado { border-color: var(--marca); box-shadow: 0 0 0 3px var(--marca-suave); }


/* ---------- Propuesta 1 de diseño (2026-10-22, guías de Apple) ----------
   · Ningún texto bajo 11 pt (typography.md): .6875rem = 11 px.
   · El ✎ se toca en 44 × 44 aunque se vea pequeño (accessibility.md:
     «44x44 pt» por defecto, 28 de mínimo): la zona de toque crece por fuera.
   · Quien pide menos transparencia o más contraste en el teléfono recibe
     barras opacas y bordes y textos secundarios más firmes. */
.mini-editar { position: relative; }
.mini-editar::before { content: ''; position: absolute; inset: -12px -10px; }

@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  header.barra, nav.abajo { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--fondo-2); }
  .velo { backdrop-filter: none; -webkit-backdrop-filter: none; }
}
@media (prefers-contrast: more) {
  :root { --texto-3: var(--texto-2); --borde: var(--borde-fuerte); }
}

/* ---------- Propuesta 2 (2026-10-22): el texto sigue al del teléfono ----------
   TextoSistema (app.js) pone el tamaño raíz según el ajuste del sistema, con
   tope de 150 %. Los títulos de las pestañas no crecen: Apple lo dice tal
   cual (typography.md › «people… don't expect the tab titles to increase»),
   y con cinco iconos abajo no caben más grandes. */
nav.abajo button { font-size: 11px; }
nav.arriba button { font-size: 11.5px; }
#tabs-material button.fila2 { font-size: 11px; }
@media (max-width: 899px) { nav.abajo button { font-size: 11px; } }
@media (max-width: 360px) { nav.abajo button { font-size: 11px; } }
@media (min-width: 900px) { nav.abajo button { font-size: 12px; } }


/* ---------- Propuesta 3: arreglos de la auditoría (2026-10-23) ----------
   · Encabezado de sitio con letra grande: el nombre se parte en líneas y la
     cuenta va pegada a él; la capacidad y el ✎ siempre a la derecha.
   · Las categorías empiezan con mayúscula, como el resto de los títulos. */
details.sitio-estante > summary .nombre-sitio { min-width: 0; flex: 0 1 auto; overflow-wrap: anywhere; }
details.sitio-estante > summary .nombre-sitio .tenue { white-space: nowrap; }
details.sitio-estante > summary .mini-editar { margin-left: auto; flex: 0 0 auto; }
details.sitio-estante > summary .capacidad-sitio { flex: 0 0 auto; }
details.sitio-estante > summary .capacidad-sitio + .mini-editar { margin-left: 8px; }
details.sitio-estante > summary:has(.mini-editar)::after { margin-left: 8px; }
.cajita-tipo .nombre::first-letter { text-transform: uppercase; }
.filtros-plegados { margin: 0 0 10px; }
.filtros-plegados > summary { font-size: .86rem; color: var(--texto-2); padding: 6px 0; cursor: pointer; }
.filtros-plegados[open] > summary { margin-bottom: 6px; }

/* Una caja dentro de su espacio, un escalón más adentro. */
details.caja-anidada { margin-left: 14px; border-bottom: 1px dashed var(--borde); }
details.caja-anidada > summary { padding: 9px 2px; }

/* ---------- Gestos de la vista por ubicación (2026-10-23) ---------- */
.asa-orden { display: inline-flex; align-items: center; justify-content: center; width: 28px; min-height: 36px;
  margin: -6px 2px -6px -6px; font-size: 1.1rem; color: var(--texto-3); cursor: grab; touch-action: none;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
details.sitio-estante { position: relative; transition: transform .18s ease-out; }
details.sitio-estante.reordenando { background: var(--fondo-2); box-shadow: 0 6px 18px rgba(0,0,0,.18); z-index: 2; }
details.sitio-estante.va-editar > summary { background: var(--marca-suave); }
details.sitio-estante.va-quitar > summary { background: var(--error-suave); }
details.sitio-estante > summary, details.caja-de-arriba > summary { transition: transform .18s cubic-bezier(.2,.9,.3,1.2), background-color .12s; }
details.sitio-estante.destino-arrastre > summary, details.caja-de-arriba.destino-arrastre > summary {
  background: var(--marca-suave); outline: 2px solid var(--marca); outline-offset: -2px; border-radius: 8px; transform: scale(1.025); }
.fantasma-arrastre .hacia { display: block; font-size: .74rem; font-weight: 550; opacity: .9; }
.fantasma-arrastre .hacia:empty { display: none; }
.fantasma-arrastre.sobre-destino { border-radius: 14px; }
summary.recibe { animation: recibe .6s ease-out; }
@keyframes recibe { 0% { background: var(--marca); color: var(--sobre-marca, #fff); transform: scale(1.04); }
  100% { background: transparent; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { details.sitio-estante > summary, details.caja-de-arriba > summary { transition: none; transform: none !important; }
  summary.recibe { animation: none; background: var(--marca-suave); } }
[data-mover], [data-mover-lotes] { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.levantado { opacity: .45; }
.fantasma-arrastre { position: fixed; z-index: 90; pointer-events: none; transform: translate(-50%, -130%);
  padding: 8px 14px; border-radius: 999px; background: var(--marca); color: var(--sobre-marca, #fff);
  font-weight: 650; font-size: .9rem; box-shadow: 0 8px 24px rgba(0,0,0,.25); max-width: 70vw;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.arrastrando { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { details.sitio-estante { transition: none; } }

/* ---------- Barra limpia de Reactivos (2026-10-23) ---------- */
.barra-material { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; }
.barra-material .chips-filtro { flex: 1 1 auto; min-width: 0; }
.boton-icono { flex: 0 0 auto; width: 44px; height: 44px; min-height: 44px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--fondo-2); color: var(--texto-2); border: 1px solid var(--borde); }
.boton-icono svg { width: 21px; height: 21px; }
.boton-icono.activa { color: var(--marca); border-color: var(--marca); background: var(--marca-suave); }
.boton-icono.principal { background: var(--marca); color: var(--sobre-marca, #fff); border-color: var(--marca); }
.campo-busqueda { display: none; }
.campo-busqueda.abierto { display: block; animation: entra .18s ease-out; }
/* Lo que el «+» reúne ya no se repite en cada vista. */
#rc-anadir, #btn-anadir-ab, .sustituido-por-mas { display: none !important; }

/* Íconos de laboratorio (2026-10-23): del color del texto secundario en los
   encabezados, alineados con el nombre. */
.ico-lab { flex: 0 0 auto; vertical-align: -4px; color: var(--texto-2); }
summary .ico-lab { color: var(--marca); }
.ico-opcion { display: inline-flex; color: var(--marca); }
h2 .ico-lab { vertical-align: -3px; color: var(--marca); }

/* ---------- La hoja que se cierra arrastrando (apple-motion 1, 2026-10-23) ---------- */
.velo.saliendo { display: flex; pointer-events: none; }
.hoja { will-change: transform; overscroll-behavior: contain; }
/* La barrita: su propia franja a lo ancho (fácil de agarrar) y la raya
   dibujada en el centro; sin invadir los botones de la cabecera. */
.hoja .asa { cursor: grab; touch-action: none; width: auto; height: 24px; margin: -4px -16px 8px;
  background: none; opacity: 1; border-radius: 0; }
.hoja .asa::after { content: ''; display: block; width: 38px; height: 4px; margin: 10px auto 0;
  border-radius: 2px; background: var(--borde-fuerte); opacity: .6; }

/* ---------- Lupa y «+» en un recuadro junto a las pestañas (2026-10-23) ---------- */
nav.arriba .acciones-material {
  flex: 0 0 auto; align-self: center; display: flex; align-items: center;
  margin: 0 0 4px 6px; padding: 2px; gap: 2px;
  background: var(--fondo-2); border: 1px solid var(--borde); border-radius: 14px;
}
nav.arriba .acciones-material button {
  flex: 0 0 auto; width: 44px; height: 44px; min-height: 44px; padding: 0; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--texto-2); background: none; border: none;
  transition: transform .15s ease-out, background .15s;
}
nav.arriba .acciones-material button svg { width: 22px; height: 22px; padding: 0; background: none; }
nav.arriba .acciones-material button.activa { color: var(--marca); background: var(--marca-suave); }
nav.arriba .acciones-material button.principal { background: var(--marca); color: var(--sobre-marca, #fff); }
nav.arriba .acciones-material button:active { transform: scale(.94); transition-duration: .08s; }
.ver-clase { display: block; width: 100%; margin: 2px 0 6px; padding: 10px 4px; min-height: 44px;
  text-align: left; background: none; border: none; color: var(--marca); font-size: .875rem; font-weight: 600; }

/* Muestras por ubicación (2026-10-23): mueble → espacio → contenido. Sin ✎
   ni flecha; el nombre a la izquierda y lo ocupado pegado a la derecha. */
.vista-ubic details > summary::after { content: none !important; }
.vista-ubic details > summary { display: flex; align-items: center; gap: 8px; list-style: none; cursor: pointer; }
.vista-ubic details > summary::-webkit-details-marker { display: none; }
.vista-ubic .nombre-sitio { flex: 1 1 auto; min-width: 0; text-align: left; display: flex; flex-direction: column;
  text-transform: none; letter-spacing: 0; }
.vista-ubic .ocupa { margin-left: auto; flex: 0 0 auto; text-align: right; font-weight: 650; font-size: .82rem;
  font-variant-numeric: tabular-nums; text-transform: none; letter-spacing: 0; }
.vista-ubic .ocupa small { font-weight: 500; font-size: .74rem; }
.vista-ubic .donde-caja { font-size: .76rem; font-weight: 500; color: var(--texto-2); }
.vista-ubic .nivel-espacio, .vista-ubic .nivel-caja { margin-left: 14px; border-bottom: 1px solid var(--borde); }
.vista-ubic .nivel-espacio > summary, .vista-ubic .nivel-caja > summary { padding: 10px 2px; }
.vista-ubic .nivel-caja { margin-left: 12px; }
.vista-ubic .nivel-espacio > .fila-lista, .vista-ubic .nivel-caja > .fila-lista { margin-left: 12px; }
.vista-ubic .nivel-vacio { display: flex; align-items: center; gap: 8px; margin-left: 14px; padding: 9px 2px;
  border-bottom: 1px solid var(--borde); color: var(--texto-2); opacity: .7; font-size: .9rem; }
.vista-ubic .vacio-sitio { font-size: .84rem; margin: 6px 0 4px 14px; }
.vista-ubic .posicion-caja { flex: 0 0 auto; min-width: 26px; height: 26px; border-radius: 7px; display: inline-flex;
  align-items: center; justify-content: center; font-size: .78rem; font-weight: 650; background: var(--fondo-2);
  border: 1px solid var(--borde); margin-right: 8px; font-variant-numeric: tabular-nums; }
/* Las cajas juntas, siempre arriba y de otro color. */
.bloque-cajas { background: var(--marca-suave); border: 1px solid var(--marca); border-radius: 14px;
  padding: 0 12px; margin: 6px 0 12px; }
.bloque-cajas > summary { padding: 12px 0; color: var(--marca); }
.bloque-cajas[open] { padding-bottom: 6px; }
.caja-de-arriba { border-top: 1px solid color-mix(in srgb, var(--marca) 25%, transparent); }
.caja-de-arriba > summary { padding: 10px 0; }
.caja-de-arriba[open] { padding-bottom: 6px; }
.vista-ubic > details.sitio-estante > summary .nombre-sitio { font-size: .95rem; font-weight: 700; color: var(--texto); }
.vista-ubic .nivel-espacio > summary .nombre-sitio, .vista-ubic .nivel-caja > summary .nombre-sitio { font-size: .88rem; font-weight: 600; }

/* El mismo estilo en toda vista por ubicación (Reactivos, Anticuerpos,
   Preparados; Germán, 2026-10-23): sin flecha, nombre a la izquierda y lo
   ocupado pegado a la derecha; los espacios dentro de su mueble. */
details.sitio-estante > summary::after, .bloque-cajas > summary::after, .caja-de-arriba > summary::after { content: none !important; }
details.sitio-estante > summary .nombre-sitio, .bloque-cajas .nombre-sitio, .caja-de-arriba .nombre-sitio {
  flex: 1 1 auto; min-width: 0; text-align: left; display: flex; flex-direction: column; text-transform: none; letter-spacing: 0; }
.bloque-cajas > summary, .caja-de-arriba > summary { display: flex; align-items: center; gap: 8px; list-style: none; cursor: pointer; }
.bloque-cajas > summary::-webkit-details-marker, .caja-de-arriba > summary::-webkit-details-marker { display: none; }
.ocupa { margin-left: auto; flex: 0 0 auto; text-align: right; font-weight: 650; font-size: .82rem;
  font-variant-numeric: tabular-nums; text-transform: none; letter-spacing: 0; }
.donde-caja { font-size: .76rem; font-weight: 500; color: var(--texto-2); }

details.sitio-estante:not(.nivel-espacio):not(.caja-anidada) > summary .nombre-sitio {
  font-size: .95rem; font-weight: 700; color: var(--texto); }
details.sitio-estante.nivel-espacio { margin-left: 14px; }
details.sitio-estante.nivel-espacio > summary { padding: 10px 2px; }
details.sitio-estante.nivel-espacio > summary .nombre-sitio { font-size: .88rem; font-weight: 600; }
details.sitio-estante.nivel-espacio:last-of-type { border-bottom: 0; }
.nivel-vacio { display: flex; align-items: center; gap: 8px; margin-left: 14px; padding: 9px 2px;
  border-bottom: 1px solid var(--borde); color: var(--texto-2); opacity: .7; font-size: .9rem; }
.vacio-sitio { font-size: .84rem; margin: 6px 0 4px 14px; }
.caja-de-arriba .abrir-caja { margin: 0 0 6px; }

/* Equipos y Salas con la barra de Material (2026-10-23): «‹ Reservas» a la
   izquierda y el recuadro de lupa y «+» a la derecha; Reservar es un ícono. */
.barra-seccion { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 10px; }
.barra-seccion .acciones-material { display: flex; align-items: center; padding: 2px; gap: 2px;
  background: var(--fondo-2); border: 1px solid var(--borde); border-radius: 14px; }
.barra-seccion .acciones-material button { flex: 0 0 auto; width: 44px; height: 44px; min-height: 44px; padding: 0;
  border-radius: 11px; display: inline-flex; align-items: center; justify-content: center;
  color: var(--texto-2); background: none; border: none; transition: transform .15s ease-out, background .15s; }
.barra-seccion .acciones-material button[hidden] { display: none; }
.barra-seccion .acciones-material button svg { width: 22px; height: 22px; }
.barra-seccion .acciones-material button.activa { color: var(--marca); background: var(--marca-suave); }
.barra-seccion .acciones-material button.principal { background: var(--marca); color: var(--sobre-marca, #fff); }
.barra-seccion .acciones-material button:active { transform: scale(.94); transition-duration: .08s; }
.campo-seccion { display: none; margin-bottom: 10px; }
.campo-seccion.abierto { display: block; animation: entra .18s ease-out; }
.boton-reservar { flex: 0 0 auto; width: 40px; height: 40px; min-height: 40px; padding: 0; margin-left: 6px;
  border-radius: 12px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--marca-suave); color: var(--marca); border: 1px solid color-mix(in srgb, var(--marca) 35%, transparent); }
.boton-reservar svg { width: 21px; height: 21px; }
.boton-reservar:active { transform: scale(.94); }
details.caja-equipo[hidden], details.grupo-equipos[hidden] { display: none; }
