/* ============================================================================
   REGISTROS LINK ADVANCE — capa de la aplicación
   Va DESPUÉS de shell.css y ANTES de ios.css: el chasis táctil corrige por
   cascada y tiene que quedar último.
   Ningún hex suelto: todo color sale de tokens.css.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   VISIBILIDAD DE LAS TRES PANTALLAS
   La app alterna arranque / ingreso / chasis con el atributo `hidden`.

   El `display:none` que trae el navegador para `[hidden]` es de su hoja de
   estilos, así que CUALQUIER `display` que pongamos nosotros le gana. Sin
   estas dos reglas, `#boot-view` y `#login-view` siguen ocupando una pantalla
   completa cada uno debajo de la app — se ven como pisos de más al hacer
   scroll — y `#app-view` no se pinta nunca, porque shell.css lo apaga hasta
   que aparezca la clase `.active`, que acá no se usa.
   --------------------------------------------------------------------------- */
[hidden] { display: none !important; }
#app-view:not([hidden]) { display: block; }

/* ---------------------------------------------------------------------------
   Marca — el logotipo real reemplaza al cuadrado con iniciales
   --------------------------------------------------------------------------- */
.brand-img { height: 30px; width: auto; display: block; }
.brand-img--hero { height: 38px; }
#login-hero .brand-lockup { margin-bottom: var(--space-6); }
.sidebar .brand .brand-img { height: 26px; }

/* ---------------------------------------------------------------------------
   MARCAS DEL CAJÓN — minera de la faena | empresa cliente

   Cada logo va dentro de una cápsula cuyo fondo lo pinta el JS con el color
   predominante del propio logo (ver pintarMarcas() en app.js). Sin eso, un
   logo pensado para papel blanco queda ilegible sobre el azul del cajón, y
   uno con fondo transparente se ve sucio. Es el patrón de TMS Minero.
   --------------------------------------------------------------------------- */
.side-marcas {
  display: flex; align-items: center; justify-content: center; gap: var(--space-3);
  min-height: var(--topbar-h);
  padding: var(--space-4) var(--space-4) var(--space-3);
}
.logo-caja {
  display: grid; place-items: center;
  padding: 7px 10px; border-radius: var(--r-sm);
  background: #fff;                      /* respaldo hasta que el JS lo tiña */
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.logo-caja img { max-height: 26px; max-width: 96px; width: auto; display: block; object-fit: contain; }
.logo-sep { width: 1px; height: 26px; background: rgba(255,255,255,.22); flex: 0 0 auto; }
.side-sin-marca {
  font-family: var(--font-display); font-size: 15px; font-weight: 800; color: #fff;
}

/* Logo del cliente en la barra superior (solo escritorio). */
.logo-cliente {
  max-height: 30px; max-width: 130px; width: auto;
  object-fit: contain; opacity: .9;
}
.topbar .logo-cliente { max-height: 24px; max-width: 96px; }

.side-pie {
  margin-top: auto;
  display: grid; justify-items: center; gap: 6px;
  padding: var(--space-4) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom));
  border-top: 1px solid rgba(255,255,255,.08);
}
.side-logo-la { height: 24px; width: auto; display: block; opacity: .85; }
.side-pie .version { font-family: var(--font-mono); font-size: 11px; color: var(--dark-muted); }

/* Selector de faena dentro del cajón. En escritorio la píldora de la barra
   superior ya cumple, así que este se oculta para no duplicar el control. */
.side-faena {
  display: flex; align-items: center; gap: 10px;
  width: calc(100% - var(--space-5) * 2);
  margin: 0 var(--space-5) var(--space-4);
  min-height: 52px; padding: 8px 12px;
  border: 1px solid rgba(255,255,255,.12); border-radius: var(--r-md);
  background: rgba(255,255,255,.06); color: var(--dark-text);
  text-align: left; cursor: pointer;
}
.side-faena:active { background: rgba(255,255,255,.12); }
@media (hover: hover) { .side-faena:hover { background: rgba(255,255,255,.1); } }
.side-faena[disabled] { opacity: .6; cursor: default; }
.side-faena .txt { display: grid; gap: 1px; min-width: 0; flex: 1; }
.side-faena small { font-size: 10.5px; font-weight: 600; color: var(--dark-muted); }
.side-faena b {
  font-size: .92rem; color: #fff;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (min-width: 900px) { .side-faena { display: none; } }

/* ---------------------------------------------------------------------------
   Arranque
   --------------------------------------------------------------------------- */
.boot {
  min-height: 100dvh;
  display: grid; place-content: center; justify-items: center; gap: var(--space-5);
  background: var(--surface-page); padding: var(--space-6);
}
.boot-bar { width: 180px; height: 4px; border-radius: var(--r-pill); background: var(--fill-2); overflow: hidden; }
.boot-bar span {
  display: block; height: 100%; width: 42%; border-radius: var(--r-pill);
  background: var(--gradient-brand); animation: boot-va 1.15s var(--ease) infinite;
}
@keyframes boot-va { 0% { transform: translateX(-110%); } 100% { transform: translateX(340%); } }
@media (prefers-reduced-motion: reduce) { .boot-bar span { animation: none; width: 100%; } }

/* ---------------------------------------------------------------------------
   Ingreso — el ojo para revelar la contraseña
   --------------------------------------------------------------------------- */
.input-icon { position: relative; }
.input-accion {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  color: var(--text-muted);
}
.input-icon:has(.input-accion) .input { padding-right: 48px; }
#login-err:empty { display: none; }
#login-err {
  margin: var(--space-4) 0 0;
  padding: 12px 14px; border-radius: var(--r-md);
  background: var(--danger-bg); color: var(--danger);
  font-size: .9rem; font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Selector de faena — píldora de contexto
   --------------------------------------------------------------------------- */
.faena-lista { display: grid; gap: var(--space-2); }
.faena-op {
  display: flex; align-items: center; gap: var(--space-4);
  width: 100%; min-height: 62px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface); text-align: left; cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.faena-op:active { background: var(--surface-2); }
@media (hover: hover) { .faena-op:hover { border-color: var(--primary); } }
.faena-op[aria-current="true"] { border-color: var(--primary); background: var(--primary-soft); }
.faena-op .cod {
  flex: 0 0 auto; display: grid; place-items: center;
  min-width: 46px; height: 38px; padding: 0 8px;
  border-radius: var(--r-sm); background: var(--fill-2);
  font-family: var(--font-mono); font-size: 12px; font-weight: 700; color: var(--text-secondary);
}
.faena-op[aria-current="true"] .cod { background: var(--primary); color: var(--text-invert); }
.faena-op .txt { display: grid; gap: 2px; min-width: 0; }
.faena-op .txt b { font-size: .95rem; color: var(--text-strong); }
.faena-op .txt span { font-size: .8rem; color: var(--text-muted); }

/* ---------------------------------------------------------------------------
   Catálogo de formularios — la pantalla que más se usa en terreno
   --------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   CATÁLOGO POR ÁREA
   Cada área tiene su color. No es decoración: a esta pantalla se entra con el
   equipo detenido y hay que encontrar el formulario de una pasada; el color es
   lo primero que separa un grupo de otro.

   El tono sale del CÓDIGO de la categoría, no de su posición, así un área
   conserva su color aunque después se agregue otra antes que ella.
   --------------------------------------------------------------------------- */
:root {
  --area-1: #2a5d9c;  --area-1-bg: #e8f0fa;
  --area-2: #0f766e;  --area-2-bg: #ddf1ef;
  --area-3: #96590a;  --area-3-bg: #fbeeda;
  --area-4: #6d28d9;  --area-4-bg: #eee8fd;
  --area-5: #b3123a;  --area-5-bg: #fde7ec;
  --area-6: #126e34;  --area-6-bg: #e3f4e9;
}

/* En oscuro el color tiene que aclararse para leerse sobre el fondo, y el
   relleno pasa a ser una transparencia del mismo tono. */
:root[data-theme="dark"] {
  --area-1: #7aacea;  --area-1-bg: rgba(122, 172, 234, .16);
  --area-2: #4cc0b4;  --area-2-bg: rgba(76, 192, 180, .16);
  --area-3: #e0a33f;  --area-3-bg: rgba(224, 163, 63, .16);
  --area-4: #a98af0;  --area-4-bg: rgba(169, 138, 240, .18);
  --area-5: #f0748f;  --area-5-bg: rgba(240, 116, 143, .16);
  --area-6: #5cc17f;  --area-6-bg: rgba(92, 193, 127, .16);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    --area-1: #7aacea;  --area-1-bg: rgba(122, 172, 234, .16);
    --area-2: #4cc0b4;  --area-2-bg: rgba(76, 192, 180, .16);
    --area-3: #e0a33f;  --area-3-bg: rgba(224, 163, 63, .16);
    --area-4: #a98af0;  --area-4-bg: rgba(169, 138, 240, .18);
    --area-5: #f0748f;  --area-5-bg: rgba(240, 116, 143, .16);
    --area-6: #5cc17f;  --area-6-bg: rgba(92, 193, 127, .16);
  }
}

.cat[data-area="1"] { --area: var(--area-1); --area-bg: var(--area-1-bg); }
.cat[data-area="2"] { --area: var(--area-2); --area-bg: var(--area-2-bg); }
.cat[data-area="3"] { --area: var(--area-3); --area-bg: var(--area-3-bg); }
.cat[data-area="4"] { --area: var(--area-4); --area-bg: var(--area-4-bg); }
.cat[data-area="5"] { --area: var(--area-5); --area-bg: var(--area-5-bg); }
.cat[data-area="6"] { --area: var(--area-6); --area-bg: var(--area-6-bg); }

/* Cápsula de tipo de formulario: mismo set de tonos que .cat[data-area],
   aplicado a un badge de una sola línea para diferenciar formularios de
   un vistazo en tablas como el Historial. */
.badge-area {
  display: inline-flex; align-items: center; max-width: 100%;
  padding: 3px 9px; border-radius: var(--r-pill);
  font-size: .78rem; font-weight: 600; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.badge-area[data-area="1"] { background: var(--area-1-bg); color: var(--area-1); }
.badge-area[data-area="2"] { background: var(--area-2-bg); color: var(--area-2); }
.badge-area[data-area="3"] { background: var(--area-3-bg); color: var(--area-3); }
.badge-area[data-area="4"] { background: var(--area-4-bg); color: var(--area-4); }
.badge-area[data-area="5"] { background: var(--area-5-bg); color: var(--area-5); }
.badge-area[data-area="6"] { background: var(--area-6-bg); color: var(--area-6); }

.cat { margin-bottom: var(--space-6); }
.cat + .cat { margin-top: var(--space-6); }
.cat:last-child { margin-bottom: 0; }

.cat-cab {
  display: flex; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-4); padding-bottom: 10px;
  border-bottom: 2px solid var(--area-bg);
}
.cat-cab h2 {
  margin: 0; min-width: 0;
  font-family: var(--font-display);
  font-size: .82rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--area);
}
.cat-ico {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: var(--r-sm);
  background: var(--area-bg); color: var(--area);
}
.cat-ico .ico { width: 16px; height: 16px; }

/* El número iba suelto contra el borde derecho de la pantalla, a medio metro
   del título: no se entendía de qué era. Va pegado al nombre y dice qué cuenta. */
.cat-n {
  flex: none; padding: 3px 10px; border-radius: var(--r-pill);
  background: var(--area-bg); color: var(--area);
  font-size: .72rem; font-weight: 700; white-space: nowrap;
}

.form-grid-app {
  display: grid; gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.form-card {
  display: flex; align-items: flex-start; gap: var(--space-4);
  width: 100%; padding: var(--space-5); text-align: left;
  background: var(--surface-card); border: 1px solid var(--border);
  border-radius: var(--r-2xl); box-shadow: var(--shadow-xs);
  cursor: pointer;
  transition: transform var(--t-fast), box-shadow var(--t-fast), border-color var(--t-fast);
}
.form-card:active { transform: scale(.985); background: var(--surface-2); }
@media (hover: hover) {
  .form-card:hover { border-color: var(--area); box-shadow: var(--shadow-md); }
}
.form-card .ficha {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: var(--r-md);
  background: var(--area-bg); color: var(--area);
}
.form-card .ficha .ico { width: 21px; height: 21px; }
.form-card .cuerpo { display: grid; gap: 4px; min-width: 0; }
.form-card b { font-size: 1rem; color: var(--text-strong); line-height: 1.3; }
.form-card p { font-size: .85rem; color: var(--text-muted); line-height: 1.45; }
/* El código es una etiqueta, no texto corrido: se lee mejor en su cápsula y
   deja de competir con el nombre del formulario. */
.form-card .codigo {
  justify-self: start; margin-top: 3px; padding: 2px 7px; max-width: 100%;
  border-radius: var(--r-sm); background: var(--fill-2); color: var(--text-muted);
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
  overflow-wrap: anywhere; box-sizing: border-box;
}
.form-card .flecha { margin-left: auto; align-self: center; color: var(--text-muted); }

@media (max-width: 767px) {
  .form-grid-app { gap: var(--space-3); grid-template-columns: 1fr; }
  .form-card { padding: var(--space-4); gap: var(--space-3); }
  .form-card .ficha { width: 38px; height: 38px; }
  .form-card .ficha .ico { width: 18px; height: 18px; }
}

/* ---------------------------------------------------------------------------
   FICHA DEL FORMULARIO — el escalón entre el catálogo y la máscara
   --------------------------------------------------------------------------- */
.volver {
  display: inline-flex; align-items: center; gap: 4px;
  min-height: 44px; margin-bottom: var(--space-2);
  font-size: .9rem; font-weight: 600; color: var(--text-muted);
}
.volver .ico { width: 18px; height: 18px; }
@media (hover: hover) { .volver:hover { color: var(--primary); } }

.ficha-cab {
  display: flex; align-items: flex-start; gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.ficha-cab .muted { margin-top: 4px; font-size: .9rem; }
.ficha-ico {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 48px; height: 48px; margin-top: 4px;
  border-radius: var(--r-md); background: var(--primary-soft); color: var(--primary);
}
.ficha-ico .ico { width: 24px; height: 24px; }

/* El botón principal de la pantalla: más alto que un botón normal porque es
   lo que se aprieta con guantes y es la única acción que importa acá. */
.btn-alto { min-height: 62px; font-size: 1.02rem; box-shadow: var(--shadow-brand); }

.sec-hist { margin-top: var(--space-8); }
.sec-hist-cab {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  padding-bottom: var(--space-3); margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}
.sec-hist-cab h2 {
  flex: 1; min-width: 0;
  font-family: var(--font-display); font-size: .82rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted);
}
.filtro-mios {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 4px;
  font-size: .87rem; font-weight: 600; color: var(--text-secondary); cursor: pointer;
}
.filtro-mios input { width: 19px; height: 19px; accent-color: var(--primary); }
.hist-n { font-size: .82rem; color: var(--text-muted); margin-bottom: var(--space-3); }
.td-acciones { display: flex; gap: 6px; flex-wrap: wrap; }

/* ---------------------------------------------------------------------------
   Barra de tabla — buscar, filtrar y exportar
   El filtrado ocurre en el navegador sobre lo ya cargado: se ve el resultado
   mientras se escribe, sin esperar al servidor por cada tecla.
   --------------------------------------------------------------------------- */
.barra-tabla {
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.buscador { position: relative; flex: 1 1 220px; min-width: 0; }
.buscador .ico {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 17px; height: 17px; color: var(--text-muted); pointer-events: none;
}
.buscador .input { padding-left: 36px; }
/* La cruz nativa del type=search se ve distinta en cada navegador. */
.buscador .input::-webkit-search-cancel-button { cursor: pointer; }

#h-filtros .cuenta {
  display: inline-grid; place-items: center;
  min-width: 19px; height: 19px; padding: 0 5px; margin-left: 4px;
  border-radius: var(--r-pill); background: var(--primary); color: var(--text-invert);
  font-size: 11px; font-weight: 700;
}
.ico-filtro { width: 13px; height: 13px; color: var(--primary); vertical-align: -1px; }

.filtro-col { margin-bottom: var(--space-5); }
.filtro-opciones {
  display: grid; gap: 2px;
  max-height: 260px; overflow-y: auto;
  padding-right: 4px;
}

@media (max-width: 639px) {
  .buscador { flex: 1 1 100%; }
  .barra-tabla .spacer { display: none; }
  .barra-tabla .btn { flex: 1 1 auto; justify-content: center; }
}

/* ---------------------------------------------------------------------------
   Máscara nativa del formulario
   --------------------------------------------------------------------------- */
.mascara { max-width: 46rem; }
.mascara .seccion {
  margin: var(--space-8) 0 var(--space-4); padding-top: var(--space-5);
  border-top: 1px solid var(--border-subtle);
}
.mascara .seccion:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.mascara .seccion h3 { font-family: var(--font-display); font-size: 1.05rem; font-weight: 800; color: var(--text-strong); }
.mascara .nota { font-size: .88rem; color: var(--text-muted); margin: var(--space-3) 0; }
.mascara .field[hidden] { display: none; }
.mascara .req { color: var(--danger); font-weight: 700; margin-left: 3px; }
.mascara .ayuda { font-size: .8rem; color: var(--text-muted); margin-top: 6px; }
.mascara .campo-error .input,
.mascara .campo-error .textarea,
.mascara .campo-error .select { border-color: var(--danger); }
.mascara .msg-error { font-size: .8rem; color: var(--danger); font-weight: 600; margin-top: 6px; }

/* Opciones y casillas: blanco de toque completo, nunca solo el círculo. */
.opciones { display: grid; gap: var(--space-2); }
.opciones.en-linea { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.opcion {
  display: flex; align-items: center; gap: 12px;
  min-height: 48px; padding: 10px 14px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); cursor: pointer;
  font-size: .95rem; color: var(--text-body);
  transition: border-color var(--t-fast), background var(--t-fast);
}
.opcion:active { background: var(--surface-2); }
@media (hover: hover) { .opcion:hover { border-color: var(--border-strong); } }
.opcion input { width: 20px; height: 20px; accent-color: var(--primary); flex: 0 0 auto; }
.opcion:has(input:checked) { border-color: var(--primary); background: var(--primary-soft); color: var(--text-strong); font-weight: 600; }
/* La caja de "Otro" acompaña a su marca y sólo se activa al marcarla. */
.opciones .otro-texto { margin-top: calc(var(--space-2) * -1 + 2px); }
.opciones .otro-texto:disabled { opacity: .5; }

/* Escala y estrellas */
.escala { display: flex; flex-wrap: wrap; gap: 8px; }
.escala button {
  min-width: 48px; height: 48px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); font-family: var(--font-mono); font-weight: 700;
  color: var(--text-body); cursor: pointer;
}
.escala button[aria-pressed="true"] { background: var(--primary); border-color: var(--primary); color: var(--text-invert); }
.estrellas { display: flex; gap: 4px; }
.estrellas button { width: 48px; height: 48px; border: 0; background: none; color: var(--border-strong); cursor: pointer; }
.estrellas button.on { color: var(--warning); }

/* Fotografías */
.fotos { display: grid; gap: var(--space-3); grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
.foto-slot {
  position: relative; aspect-ratio: 1; border-radius: var(--r-md); overflow: hidden;
  background: var(--surface-2); border: 1px solid var(--border);
}
.foto-slot img { width: 100%; height: 100%; object-fit: cover; }
.foto-slot .quitar {
  position: absolute; top: 5px; right: 5px;
  width: 30px; height: 30px; border: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(0,0,0,.55); color: #fff;
}
.foto-add {
  display: grid; place-items: center; gap: 6px;
  aspect-ratio: 1; border: 1.5px dashed var(--border-strong); border-radius: var(--r-md);
  background: var(--surface); color: var(--text-muted);
  font-size: .78rem; font-weight: 600; cursor: pointer;
}
.foto-add:active { background: var(--surface-2); }
.foto-slot.subiendo { display: grid; place-items: center; color: var(--text-muted); font-size: .75rem; }

/* Firma */
.firma-caja { border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); overflow: hidden; }
.firma-caja canvas { display: block; width: 100%; height: 190px; touch-action: none; cursor: crosshair; }
.firma-pie {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: 8px 12px; border-top: 1px solid var(--border-subtle); background: var(--surface-2);
  font-size: .78rem; color: var(--text-muted);
}

/* Tabla de entrada (matrix) */
.tabla-entrada { border: 1px solid var(--border); border-radius: var(--r-md); overflow: auto; }
.tabla-entrada table { width: 100%; border-collapse: collapse; min-width: 460px; }
.tabla-entrada th, .tabla-entrada td { padding: 8px 10px; border-bottom: 1px solid var(--border-subtle); text-align: left; }
.tabla-entrada th { background: var(--surface-2); font-size: .78rem; font-weight: 700; color: var(--text-secondary); white-space: nowrap; }
.tabla-entrada td:first-child { font-weight: 600; color: var(--text-strong); font-size: .85rem; white-space: nowrap; }
.tabla-entrada .input, .tabla-entrada .select { min-height: 40px; font-size: 16px; }

/* Celdas de marcar (botón de selección o casilla). El blanco de toque cubre
   la celda entera: en terreno se marca con guante y a pulso. */
.tabla-marcas table { min-width: 340px; }
.tabla-marcas th:not(:first-child) { text-align: center; }
.tabla-marcas td:not(:first-child) { padding: 0; text-align: center; }
.celda-marca {
  display: flex; align-items: center; justify-content: center;
  min-height: 46px; padding: 4px; cursor: pointer;
}
.celda-marca input { width: 22px; height: 22px; accent-color: var(--primary); margin: 0; }
.celda-marca:active { background: var(--surface-2); }
.tabla-marcas tr:has(input:checked) td:first-child { color: var(--primary); }

/* Lista configurable: filas que pone el operador. */
.tabla-dinamica table { min-width: 320px; }
.tabla-dinamica td:first-child { font-weight: 400; color: inherit; white-space: normal; }
.tabla-dinamica th.col-quitar, .tabla-dinamica td.col-quitar { width: 40px; padding: 4px; text-align: center; }
.fila-quitar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--text-muted); cursor: pointer;
}
.fila-quitar:hover:not(:disabled) { background: var(--surface-2); color: var(--danger, #c0392b); }
.fila-quitar:disabled { opacity: .25; cursor: default; }
.fila-add { margin: 8px; }

/* Barra de envío: fija abajo, sobre la barra de pestañas. */
.barra-envio {
  position: sticky; bottom: 0; z-index: 4;
  display: flex; align-items: center; gap: var(--space-4);
  margin: var(--space-6) calc(var(--space-5) * -1) 0;
  padding: var(--space-4) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom));
  background: var(--surface-chrome); backdrop-filter: var(--blur-chrome);
  border-top: 1px solid var(--border);
}
.barra-envio .btn { flex: 1; }
.barra-envio .aviso { font-size: .78rem; color: var(--text-muted); }
/* Sin barra de pestañas, la barra de envio se apoya directo en el borde. */

/* ---------------------------------------------------------------------------
   Historial y detalle
   --------------------------------------------------------------------------- */
.folio { font-family: var(--font-mono); font-size: .82rem; font-weight: 700; color: var(--text-strong); letter-spacing: .02em; }
.filtros { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-5); }
.filtros .field { margin: 0; min-width: 148px; flex: 1 1 148px; }
.filtros .field label { font-size: .74rem; }

.detalle-dato { display: grid; gap: 3px; padding: var(--space-4) 0; border-bottom: 1px solid var(--border-subtle); }
.detalle-dato:last-child { border-bottom: 0; }
.detalle-dato .k { font-size: .76rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }
.detalle-dato .v { font-size: .95rem; color: var(--text-body); white-space: pre-wrap; overflow-wrap: anywhere; }
.detalle-fotos { display: grid; gap: var(--space-3); grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); margin-top: 8px; }
.detalle-fotos button {
  padding: 0; border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2); cursor: zoom-in; overflow: hidden; display: block;
}
.detalle-fotos img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
@media (hover: hover) { .detalle-fotos button:hover { border-color: var(--primary); } }

/* Adjuntos que no son foto (PDF de respaldo, diploma, etc). */
.detalle-adjuntos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.chip-pdf {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: var(--r-pill);
  border: 1px solid var(--border); background: var(--surface-2);
  font-size: .85rem; font-weight: 600; color: var(--text-body); cursor: pointer;
}
.chip-pdf .ico { width: 16px; height: 16px; color: var(--primary); }
@media (hover: hover) { .chip-pdf:hover { border-color: var(--primary); } }

/* ---------------------------------------------------------------------------
   VISOR DE PDF
   Igual que el de fotos, pero sin panorámica ni zoom: el iframe trae el
   visor nativo del navegador con lo suyo.
   --------------------------------------------------------------------------- */
.visor-pdf {
  position: fixed; inset: 0; z-index: 90;
  display: grid; grid-template-rows: auto 1fr;
  background: rgba(9, 14, 24, .94);
  opacity: 0; transition: opacity var(--t);
}
.visor-pdf.open { opacity: 1; }
.visor-pdf-cab {
  display: flex; align-items: center; gap: var(--space-4);
  padding: calc(var(--space-4) + env(safe-area-inset-top)) var(--space-5) var(--space-4);
  color: #fff;
}
.visor-pdf-cab b { font-size: .95rem; font-weight: 600; overflow-wrap: anywhere; }
.visor-pdf-cab .btn-icon { color: #fff; }
.visor-pdf iframe { width: 100%; height: 100%; border: 0; background: #fff; }

/* ---------------------------------------------------------------------------
   VISOR DE FOTOS
   Una foto de terreno en miniatura no sirve para nada: el detalle que importa
   —una grieta, un número de serie— solo se ve en grande.
   --------------------------------------------------------------------------- */
.visor {
  position: fixed; inset: 0; z-index: 90;
  display: grid; grid-template-rows: auto 1fr auto;
  background: rgba(9, 14, 24, .94);
  opacity: 0; transition: opacity var(--t);
}
.visor.open { opacity: 1; }
.visor-cab {
  display: flex; align-items: center; gap: var(--space-4);
  padding: calc(var(--space-4) + env(safe-area-inset-top)) var(--space-5) var(--space-4);
  color: #fff;
}
.visor-cab b { font-size: .95rem; font-weight: 600; }
.visor-cab .n { font-family: var(--font-mono); font-size: 12px; color: rgba(255,255,255,.66); }
.visor-cab .btn-icon { color: #fff; }
/* El lienzo recorta y la foto se mueve por transform: es lo que permite
   acercarla y arrastrarla, y lo que garantiza que entre completa — con
   max-height:100% el porcentaje no se podía resolver y en pantalla ancha
   la foto salía a tamaño natural, cortada por abajo. */
.visor-cuerpo {
  position: relative; overflow: hidden; min-height: 0;
  touch-action: none; cursor: grab;
}
.visor-cuerpo.con-zoom { cursor: move; }
.visor-cuerpo img {
  position: absolute; top: 0; left: 0; transform-origin: 0 0;
  max-width: none; max-height: none;
  user-select: none; -webkit-user-drag: none;
}
.visor-nota {
  position: absolute; inset: 50% 0 auto; margin: 0; transform: translateY(-50%);
  text-align: center; color: rgba(255,255,255,.7); font-size: .9rem;
}
.visor-pie {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) var(--space-5) calc(var(--space-5) + env(safe-area-inset-bottom));
}
.visor-zoom { display: flex; align-items: center; gap: var(--space-3); margin-inline: auto; }
.visor-pie .btn, .visor-pie .btn-icon {
  background: rgba(255,255,255,.14); color: #fff; border-color: transparent;
}
.visor-pie .btn-icon { border-radius: var(--r-pill); }
.visor-pie .btn:hover, .visor-pie .btn-icon:hover { background: rgba(255,255,255,.24); }
.visor-pie .btn[disabled], .visor-pie .btn-icon[disabled] { opacity: .35; }
.visor-pie [hidden] { display: none; }

/* ---------------------------------------------------------------------------
   Cabeceras de tabla ordenables y filtrables
   --------------------------------------------------------------------------- */
.table th.col { padding: 0; }
.col-btn {
  display: flex; align-items: center; gap: 5px;
  width: 100%; min-height: 42px; padding: 8px 10px;
  background: none; border: 0; cursor: pointer;
  font: inherit; font-size: inherit; font-weight: inherit; color: inherit;
  letter-spacing: inherit; text-transform: inherit; text-align: left;
}
@media (hover: hover) { .col-btn:hover { color: var(--primary); } }
.col-btn .flechas { display: grid; line-height: .6; color: var(--border-strong); font-size: 9px; }
.col-btn .flechas .on { color: var(--primary); }
.col-btn .embudo { width: 13px; height: 13px; color: var(--primary); }

/* ---------------------------------------------------------------------------
   Administración
   --------------------------------------------------------------------------- */
.admin-tabs { margin-bottom: var(--space-5); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: var(--r-pill);
  background: var(--fill-2); color: var(--text-secondary);
  font-size: .76rem; font-weight: 600; white-space: nowrap;
}
.chip.chip-todo { background: var(--primary-soft); color: var(--primary); }
.chip.chip-global { background: var(--success-bg); color: var(--success); }

/* Asignador de alcance: el corazón del multicliente. Una fila por empresa,
   con su interruptor de "todas las faenas" y sus faenas debajo. */
.alcance-cliente {
  border: 1px solid var(--border); border-radius: var(--r-lg);
  margin-bottom: var(--space-3); overflow: hidden;
}
.alcance-cliente > header {
  display: flex; align-items: center; gap: var(--space-4);
  padding: 12px 14px; background: var(--surface-2);
}
.alcance-cliente > header b { font-size: .95rem; color: var(--text-strong); }
.alcance-cliente > header .cod { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.alcance-faenas { display: grid; gap: 2px; padding: 10px 14px 14px; }
.alcance-faenas.apagado { opacity: .45; pointer-events: none; }
.alcance-faena {
  display: flex; align-items: center; gap: 10px; min-height: 44px;
  font-size: .9rem; color: var(--text-body); cursor: pointer;
}
.alcance-faena input { width: 19px; height: 19px; accent-color: var(--primary); }
.alcance-resumen {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; margin-top: var(--space-4);
  border-radius: var(--r-md); background: var(--info-bg); color: var(--info);
  font-size: .85rem; font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Menú de acciones — una columna, cada opción encapsulada
   --------------------------------------------------------------------------- */
.menu-acciones { display: grid; gap: var(--space-2); }
.menu-accion {
  display: flex; align-items: center; gap: var(--space-4);
  width: 100%; min-height: 62px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface); text-align: left; cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.menu-accion:active { background: var(--surface-2); }
@media (hover: hover) { .menu-accion:hover { border-color: var(--primary); background: var(--primary-soft); } }
.menu-accion .ficha {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: var(--r-sm);
  background: var(--primary-soft); color: var(--primary);
}
.menu-accion .txt { display: grid; gap: 1px; min-width: 0; flex: 1; }
.menu-accion .txt b { font-size: .95rem; color: var(--text-strong); }
.menu-accion .txt small { font-size: .78rem; color: var(--text-muted); line-height: 1.35; }
.menu-accion .flecha { flex: 0 0 auto; color: var(--text-muted); }

.menu-accion.es-peligro .ficha { background: var(--danger-bg); color: var(--danger); }
.menu-accion.es-peligro .txt b { color: var(--danger); }
@media (hover: hover) {
  .menu-accion.es-peligro:hover { border-color: var(--danger); background: var(--danger-bg); }
}

/* ---------------------------------------------------------------------------
   Edición de logos
   --------------------------------------------------------------------------- */
.marcas-edit { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.marca-edit {
  display: grid; gap: 8px; justify-items: start;
  padding: var(--space-4); border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface-2);
}
.marca-edit .k { font-size: .78rem; font-weight: 700; color: var(--text-secondary); }
.marca-vista {
  display: grid; place-items: center;
  width: 100%; min-height: 76px; padding: 10px;
  border-radius: var(--r-sm); background: #fff; color: var(--ink-300);
  border: 1px solid var(--border-subtle);
}
.marca-vista img { max-height: 56px; max-width: 100%; object-fit: contain; }
.marca-acciones { display: flex; flex-wrap: wrap; gap: 6px; }
.marca-edit .ayuda { font-size: .74rem; color: var(--text-muted); margin: 0; }

/* Importación del historial */
.importe-log {
  max-height: 190px; overflow: auto; margin-top: var(--space-4);
  padding: 12px 14px; border-radius: var(--r-md);
  background: var(--surface-sunken); border: 1px solid var(--border-subtle);
  font-family: var(--font-mono); font-size: 12px; line-height: 1.7; color: var(--text-secondary);
  white-space: pre-wrap;
}

/* ---------------------------------------------------------------------------
   INICIO — KPIs y últimos registros
   --------------------------------------------------------------------------- */
.grid-kpi { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }

/* Fila de "Últimos registros": el nombre del formulario arriba, folio y fecha
   abajo. Todo en un renglón se partía en cualquier parte con pantalla angosta
   y la lista se leía como un párrafo. */
.reg-row .reg-txt { display: grid; gap: 1px; flex: 1; min-width: 0; }
.reg-row .reg-txt b {
  font-size: .92rem; font-weight: 600; color: var(--text-strong);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.reg-row .reg-txt small { font-size: .78rem; color: var(--text-muted); }
.reg-row .folio { font-size: .78rem; color: var(--text-muted); }
.reg-row > .ico { flex: none; width: 16px; height: 16px; color: var(--text-muted); }

/* En teléfono los cuatro KPI van de a dos por fila: uno por fila dejaba el
   inicio en cuatro pantallazos de tarjeta antes de llegar a algo accionable. */
@media (max-width: 639px) {
  .grid-kpi { grid-template-columns: 1fr 1fr; gap: var(--space-3); }
  .grid-kpi .stat { padding: var(--space-3) var(--space-4); border-left-width: 3px; }
  .grid-kpi .stat .value { font-size: 22px; }
  .grid-kpi .stat .label { font-size: 11px; }
}

/* ---------------------------------------------------------------------------
   LISTA AGRUPADA EN ESCRITORIO

   ios.css solo la estiliza dentro de @media (hover:none) and (pointer:coarse),
   así que con un mouse las filas quedaban sin formato: etiqueta y valor
   apilados, sin separadores y sin alto de fila. Acá se le da el mismo aspecto
   para puntero fino. Va en la capa de la app y no en ios.css, que tiene que
   seguir siendo el chasis táctil y quedar último.
   --------------------------------------------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  .list-group {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    overflow: hidden;
    margin-bottom: var(--space-5);
  }
  .list-group > .list-row + .list-row { border-top: 1px solid var(--border-subtle); }

  .list-row {
    display: flex; align-items: center; gap: var(--space-4);
    width: 100%; min-height: 52px; padding: 10px var(--space-5);
    text-align: left; background: none; border: 0;
    font: inherit; color: var(--text-body);
  }
  .list-row > .label { flex: none; font-size: .95rem; font-weight: 500; color: var(--text-strong); }
  .list-row > .value { flex: 1; text-align: right; font-size: .92rem; color: var(--text-muted); }
  /* Filas de "importar/elegir" meten un título + subtítulo dentro de .label
     en vez de una etiqueta corta: sin esto no se achica y empuja el ícono
     final (el "+") fuera de la fila cuando el nombre es largo. */
  .list-row > .label:has(b) { flex: 1 1 auto; min-width: 0; }
  .list-row > .label:has(b) b {
    display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .list-row > .label:has(b) small {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

  button.list-row, a.list-row { cursor: pointer; transition: background var(--t-fast); }
  button.list-row:hover, a.list-row:hover { background: var(--surface-2); }
  button.list-row[disabled] { opacity: .55; cursor: default; }
  button.list-row[disabled]:hover { background: none; }

  /* El título de grupo es un rótulo, no un encabezado de página. */
  .list-title {
    font-size: .78rem; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--text-muted);
    margin: var(--space-6) 0 var(--space-3);
  }

  /* El título grande es un patrón táctil: arranca grande y se recoge en la
     barra al hacer scroll. Con mouse la barra ya lo muestra siempre, así que
     acá solo repetiría el nombre de la vista en texto sin formato. */
  .title-lg { display: none; }
  /* Salvo cuando es el nombre propio de algo, no el de la sección. */
  .ficha-cab .title-lg {
    display: block;
    font-family: var(--font-display); font-size: 1.7rem; font-weight: 800;
    color: var(--text-strong); line-height: 1.15;
  }
}

/* ---------------------------------------------------------------------------
   Estados
   --------------------------------------------------------------------------- */
.cargando { display: grid; gap: var(--space-3); }
.cargando .skeleton { height: 78px; border-radius: var(--r-xl); }

.sin-conexion {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; margin-bottom: var(--space-5);
  border-radius: var(--r-md); background: var(--warning-bg); color: var(--warning);
  font-size: .87rem; font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Teléfono — una sola columna bajo 639px, sin excepciones
   --------------------------------------------------------------------------- */
@media (max-width: 639px) {
  .form-grid-app { grid-template-columns: 1fr; }
  .filtros .field { flex: 1 1 100%; }
  .opciones.en-linea { grid-template-columns: 1fr; }
  .barra-envio { margin-inline: calc(var(--space-4) * -1); padding-inline: var(--space-4); }
  .marcas-edit { grid-template-columns: 1fr; }

  /* Encabezado de tarjeta con varias acciones (la de cada empresa): en el
     teléfono no cabe en una línea y empujaba el documento hacia la derecha.
     Se envuelve y las acciones bajan a su propia fila, ocupando el ancho. */
  .card-head { flex-wrap: wrap; }
  .card-head > .spacer { flex-basis: 100%; height: 0; }
  .card-head > .btn { flex: 1 1 auto; justify-content: center; }
}

/* En el teléfono la topbar se queda con lo imprescindible: el estado de sync
   y el logo del cliente se van al cajón. Dejarlos ahí es la causa número uno
   de scroll horizontal del documento. */
@media (max-width: 860px) {
  #tb-sync { display: none; }
  .topbar .logo-cliente { display: none; }
  .context-pill { max-width: 46vw; }
  .context-pill span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* ---------------------------------------------------------------------------
   Avisos por correo
   La lista de destinatarios de un formulario en una faena, y el bloque de
   "¿falta alguien?" de la confirmación del envío. No se reusa .list-row: esa
   solo existe en escritorio y esto se usa sobre todo en el teléfono.
   --------------------------------------------------------------------------- */
.av-lista { margin-block: var(--space-5); }

.av-linea {
  display: flex; align-items: center; gap: var(--space-4);
  padding: 10px 0; min-height: 52px;
}
.av-linea + .av-linea { border-top: 1px solid var(--border-subtle); }
.av-linea > .txt { flex: 1; min-width: 0; }
.av-linea > .txt b { display: block; font-size: .95rem; color: var(--text-strong); }
.av-linea > .txt small { display: block; font-size: .8rem; color: var(--text-muted); word-break: break-all; }
/* En pausa se ve apagado, pero sigue legible: hay que poder leer a quién se le
   cortó el aviso sin tener que volver a prenderlo. */
.av-linea.es-pausa > .txt { opacity: .55; }
.av-quitar { color: var(--danger); flex: none; }

.av-vacio {
  margin: 0; padding: var(--space-5);
  border: 1px dashed var(--border); border-radius: var(--r-lg);
  color: var(--text-muted); font-size: .9rem; text-align: center;
}

.av-sumar { margin-top: var(--space-5); }
.av-sumar > label {
  display: block; margin-bottom: var(--space-2);
  font-size: .9rem; font-weight: 600; color: var(--text-strong);
}
.av-sumar-fila { display: flex; gap: var(--space-3); align-items: stretch; }
.av-sumar-fila .input { flex: 1; min-width: 0; }
.av-sumar-fila .btn { flex: none; }

button.chip.av-sug { cursor: pointer; border: 0; font-family: inherit; }
button.chip.av-sug .ico { width: 13px; height: 13px; }

.av-check {
  display: flex; align-items: flex-start; gap: var(--space-3);
  margin-top: var(--space-4); cursor: pointer;
  font-size: .88rem; line-height: 1.45; color: var(--text-body);
}
.av-check input {
  flex: none; width: 19px; height: 19px; margin: 1px 0 0;
  accent-color: var(--primary);
}

.av-prueba {
  display: flex; align-items: center; gap: var(--space-4);
  margin-top: var(--space-6); padding-top: var(--space-5);
  border-top: 1px solid var(--border-subtle);
}
.av-prueba > div { flex: 1; min-width: 0; }
.av-prueba b { font-size: .92rem; color: var(--text-strong); }
.av-prueba .ayuda { margin: 2px 0 0; }
.av-prueba .btn { flex: none; }

.av-aviso { margin-bottom: var(--space-5); }
.av-aviso .alert { align-items: flex-start; text-align: left; }

/* ---------------------------------------------------------------------------
   TABLERO DEL FORMULARIO
   Va entre el botón de registrar y el historial, así que tiene que resumir sin
   empujar la lista fuera de la pantalla: tres números, un gráfico de ritmo
   bajo y tres distribuciones de seis barras.
   --------------------------------------------------------------------------- */
.tablero { margin-block: var(--space-6); }
.tablero:empty { display: none; }

.tb-cab { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.tb-cab h2 {
  display: flex; align-items: center; gap: 8px; margin: 0;
  font-size: .78rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted);
}
.tb-cab h2 .ico { width: 15px; height: 15px; }

.tb-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.tb-tile {
  padding: var(--space-4); border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--border);
}
.tb-tile .k {
  display: block; font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-muted);
}
.tb-tile b {
  display: block; margin-top: 2px; font-size: 1.5rem; line-height: 1.15;
  font-weight: 700; color: var(--text-strong); font-variant-numeric: tabular-nums;
}
.tb-tile small { display: block; font-size: .76rem; color: var(--text-muted); }

.tb-graficos { display: grid; gap: var(--space-3); margin-top: var(--space-5); }

.tb-panel {
  padding: var(--space-4) var(--space-5) var(--space-5);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
}
.tb-panel-cab {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.tb-panel-cab h3 {
  margin: 0; flex: 1; min-width: 0;
  font-size: .92rem; font-weight: 600; color: var(--text-strong);
}

/* Selector de agrupación: un segmentado chico, no tres botones sueltos. */
.tb-grano { display: flex; gap: 2px; padding: 2px; background: var(--fill-2); border-radius: var(--r-pill); }
.tb-grano button {
  padding: 5px 12px; border: 0; border-radius: var(--r-pill);
  background: none; color: var(--text-muted);
  font: inherit; font-size: .8rem; font-weight: 600; cursor: pointer;
}
.tb-grano button.on { background: var(--surface); color: var(--primary); box-shadow: var(--shadow-sm); }

/* El SVG se dibuja al ancho real en píxeles (ver pintarRitmo), así que acá no
   se le fuerza ningún tamaño: estirarlo deformaría también la tipografía. */
.tb-lienzo { position: relative; }
.tb-svg { display: block; touch-action: pan-y; }
.tb-svg .tb-b { fill: var(--primary); cursor: pointer; transition: fill var(--t-fast); }
.tb-svg .tb-b.on { fill: var(--primary-press); }
.tb-svg .tb-b.sel { fill: var(--primary-press); stroke: var(--primary-press); stroke-width: 2.5; }
.tb-svg .tb-eje  { stroke: var(--border-strong); stroke-width: 1; }
.tb-svg .tb-guia { stroke: var(--border-subtle); stroke-width: 1; stroke-dasharray: 3 4; }
.tb-svg text { fill: var(--text-muted); font-size: 11px; font-family: inherit; }
.tb-svg .tb-x { text-anchor: middle; }
.tb-svg .tb-y { text-anchor: end; font-variant-numeric: tabular-nums; }

/* Detalle de la barra bajo el puntero. */
.tb-tip {
  position: absolute; top: 0; transform: translateX(-50%);
  padding: 6px 10px; border-radius: var(--r-md);
  background: var(--ink-900); color: #fff;
  font-size: .78rem; line-height: 1.35; text-align: center;
  white-space: nowrap; pointer-events: none; z-index: 2;
  box-shadow: var(--shadow-md);
}
.tb-tip b { display: block; font-weight: 600; }
.tb-tip span { color: rgba(255,255,255,.72); }
.tb-tip[hidden] { display: none; }

/* Ranking de equipos: en dos columnas cuando el panel quedó ancho, para que
   diez equipos no obliguen a hacer scroll. En un tercio de fila no caben. */
.tb-equipos .tb-cols { columns: 1; column-gap: var(--space-6); }
.tb-equipos[data-ancho="3"] .tb-cols,
.tb-equipos[data-ancho="6"] .tb-cols { columns: 2; }
.tb-equipos .tb-fila { break-inside: avoid; }
.tb-sub { font-size: .76rem; color: var(--text-muted); }

/* Seis columnas y no tres: así un panel puede pedir un tercio (2), una mitad
   (3) o la fila entera (6) y las filas siempre cierran parejas. Quién pide qué
   lo decide repartoPaneles() en form.js, según cuántos gráficos haya. */
.tb-grid { display: grid; gap: var(--space-3); grid-template-columns: repeat(6, 1fr); }
.tb-grid > .tb-panel { grid-column: span 2; }
.tb-grid > .tb-panel[data-ancho="3"] { grid-column: span 3; }
.tb-grid > .tb-panel[data-ancho="6"] { grid-column: span 6; }

.tb-fila { display: flex; align-items: center; gap: var(--space-3); padding: 5px 0; }
.tb-fila .k {
  flex: 0 0 34%; min-width: 0; font-size: .82rem; color: var(--text-body);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tb-fila .pista { flex: 1; height: 9px; border-radius: var(--r-pill); background: var(--fill-2); overflow: hidden; }
.tb-fila .relleno { display: block; height: 100%; border-radius: var(--r-pill); background: var(--primary); }
.tb-fila .n { flex: none; font-size: .82rem; font-variant-numeric: tabular-nums; color: var(--text-strong); }
.tb-fila .pct { flex: none; width: 34px; text-align: right; font-size: .74rem; color: var(--text-muted); }

.tb-nota {
  display: flex; align-items: flex-start; gap: 8px;
  margin: var(--space-3) 0 0; font-size: .8rem; color: var(--text-muted);
}
.tb-nota .ico { width: 14px; height: 14px; flex: none; margin-top: 2px; }

@media (max-width: 767px) {
  /* En el teléfono el tablero es lo que hay ANTES del historial: si ocupa dos
     pantallas, nadie llega a la lista. Se achica, no se reordena. */
  .tb-tiles { gap: 6px; }
  .tb-tile { padding: var(--space-3); }
  .tb-tile b { font-size: 1.2rem; }
  .tb-tile .k { font-size: .64rem; letter-spacing: .02em; }
  .tb-tile small { font-size: .68rem; }
  .tb-grid { grid-template-columns: 1fr; }
  .tb-grid > .tb-panel,
  .tb-grid > .tb-panel[data-ancho] { grid-column: auto; }
  .tb-fila .k { flex-basis: 38%; }
  .tb-equipos[data-ancho] .tb-cols { columns: 1; }
}

.tb-graficos[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   Hoja "Gráficos del resumen"
   Una lista larga de campos que hay que poder recorrer y marcar con el pulgar.
   --------------------------------------------------------------------------- */
.gr-modo { margin: var(--space-5) 0 var(--space-4); }
.gr-lista { display: grid; gap: 6px; max-height: 46vh; overflow-y: auto; }

.gr-fila {
  display: flex; align-items: flex-start; gap: var(--space-3);
  width: 100%; padding: 10px var(--space-4); text-align: left;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); font: inherit; color: var(--text-body); cursor: pointer;
}
.gr-fila:hover:not([disabled]) { border-color: var(--primary); }
.gr-fila.on { border-color: var(--primary); background: var(--primary-soft); }
/* En automático la lista solo informa: se ve qué quedaría elegido, sin tocar. */
.gr-lista.es-auto .gr-fila { cursor: default; opacity: .72; }

.gr-fila .marca {
  flex: none; display: grid; place-items: center;
  width: 24px; height: 24px; margin-top: 1px; border-radius: 50%;
  background: var(--fill-2); color: var(--text-muted);
  font-size: .78rem; font-weight: 700;
}
.gr-fila.on .marca { background: var(--primary); color: #fff; }
.gr-fila.on .marca .ico, .gr-fila.on .marca svg { width: 14px; height: 14px; }

.gr-fila .txt { min-width: 0; }
.gr-fila .txt b { display: block; font-size: .92rem; color: var(--text-strong); }
.gr-fila .txt small { display: block; font-size: .76rem; color: var(--text-muted); }
.gr-fila .txt .ej {
  margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--font-mono); font-size: .72rem; opacity: .8;
}

/* Barra del resumen usada como filtro: es un botón, así que hay que devolverle
   el aspecto de fila y marcar la que está aplicada. */
button.tb-fila {
  width: 100%; border: 0; background: none; font: inherit;
  color: inherit; text-align: left; cursor: pointer;
  border-radius: var(--r-sm); padding-inline: 4px; margin-inline: -4px;
}
@media (hover: hover) {
  button.tb-fila:hover { background: var(--surface-2); }
  button.tb-fila:hover .relleno { background: var(--primary-hover); }
}
button.tb-fila.on .k { font-weight: 600; color: var(--primary); }
button.tb-fila.on .relleno { background: var(--primary-press); }

/* Chip del filtro aplicado, arriba del historial. */
.hist-filtro {
  display: flex; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-3); padding: 8px var(--space-4);
  background: var(--primary-soft); color: var(--primary-soft-fg);
  border-radius: var(--r-lg); font-size: .88rem;
}
.hist-filtro > span { flex: 1; min-width: 0; }
.hist-filtro .ico { width: 15px; height: 15px; flex: none; }
.hist-filtro .muted { color: inherit; opacity: .7; }
.hist-filtro .btn-icon { flex: none; color: inherit; }


/* ============================================================================
   INSTALAR LA APP
   Botón flotante, abajo a la derecha, solo cuando se está usando desde el
   navegador. Va sobre el contenido pero bajo las hojas (z-index 90), para que
   nunca tape un modal abierto.
   ============================================================================ */
.fab-instalar {
  position: fixed; z-index: 60;
  right: max(var(--space-4), env(safe-area-inset-right));
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 2px;
  padding: 4px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-lg);
  animation: fab-entra .28s ease both;
}
.fab-instalar .btn { border-radius: var(--r-pill); }
.fab-instalar .fab-cerrar { width: 30px; height: 30px; color: var(--text-muted); }
@keyframes fab-entra { from { opacity: 0; transform: translateY(14px); } }

/* Pasos de "Agregar a inicio" en iPhone, donde no hay diálogo del sistema. */
.pasos-instalar { display: grid; gap: var(--space-3); margin: 0; padding: 0; list-style: none; counter-reset: paso; }
.pasos-instalar li {
  display: flex; align-items: flex-start; gap: var(--space-3);
  font-size: .9rem; line-height: 1.45;
}
.pasos-instalar li::before {
  counter-increment: paso; content: counter(paso);
  flex: none; width: 22px; height: 22px; border-radius: var(--r-pill);
  display: grid; place-items: center;
  background: var(--primary-soft); color: var(--primary);
  font-size: .74rem; font-weight: 700;
}

@media print { .fab-instalar { display: none; } }
