/* ==========================================================================
   CertiProf OS · Móvil
   Se carga LA ÚLTIMA, después de views.css. Todo lo de aquí es una corrección
   deliberada sobre la hoja de escritorio: la plataforma se diseñó en un
   monitor y estas reglas la hacen usable con un pulgar, y instalable en la
   pantalla de inicio de un iPhone.

   CÓMO ESTÁ ORGANIZADO

   Primero lo que vale en CUALQUIER tamaño y solo depende del dispositivo
   —áreas seguras, alto real de la ventana, tamaño de los blancos táctiles—.
   Después, en un único bloque por corte, lo que cambia de forma:

     · 900 px  · tablet en vertical. Solo el tamaño de los campos.
     · 640 px  · teléfono. Barra inferior, hojas, tablas apiladas.
     · 400 px  · teléfono estrecho. Se dejan de repartir columnas.

   DOS CORTES Y NO NUEVE. La hoja de escritorio acumuló catorce anchos
   distintos (560, 640, 700, 720, 760, 780, 820, 860, 900, 1000, 1024…) porque
   cada vista resolvió lo suyo cuando le tocó. No se tocan —funcionan— pero lo
   nuevo se ata a estos tres y así se puede razonar sobre el conjunto.

   POR QUÉ 640 Y NO 768. El cajón lateral aparece a 1024, que es la frontera
   «hay o no hay raíl». La frontera de 640 es otra cosa: «esto se sujeta con
   una mano». Entre las dos queda la tableta, que tiene cajón pero no necesita
   barra inferior ni hojas.
   ========================================================================== */

/* ==================================================== ÁREAS SEGURAS ====== */
/* `viewport-fit=cover` (index.html) hace que la página ocupe la pantalla
   ENTERA del iPhone, muescas incluidas. Sin esto, la barra superior se mete
   debajo del reloj y el pie debajo de la raya del gesto de inicio.

   Fuera del iPhone —y en Safari con la barra del navegador a la vista—
   `env()` vale 0, así que estas variables no cambian nada. */
:root {
  --sa-t: env(safe-area-inset-top, 0px);
  --sa-r: env(safe-area-inset-right, 0px);
  --sa-b: env(safe-area-inset-bottom, 0px);
  --sa-l: env(safe-area-inset-left, 0px);

  /* Alto de la barra inferior SIN contar el área segura. El alto real se
     compone abajo; separarlos evita restar dos veces. */
  --tabbar-h: 58px;
}

/* ============================================ ALTO REAL DE LA VENTANA ==== */
/* `100vh` en Safari de iOS es el alto CON la barra de direcciones retraída,
   que es más de lo que se ve: el último trozo de la interfaz queda debajo del
   navegador y hay que hacer scroll para alcanzarlo. `dvh` mide lo que hay de
   verdad y se ajusta cuando la barra entra y sale.

   Se deja `100vh` escrito antes: en un navegador sin `dvh` la regla de abajo
   no se aplica y sigue valiendo la de arriba. */
@supports (height: 100dvh) {
  body { min-height: 100dvh; }
  #app { min-height: 100dvh; }
  .sidebar { height: 100dvh; }
}

/* ============================================== BLANCOS TÁCTILES ========= */
/* El criterio es el de Apple: 44 pt. Se aplica solo con puntero grueso —dedo—
   para no engordar la interfaz de quien trabaja con ratón, que es donde se
   diseñó y donde 30 px está bien.

   Regla de oro: NUNCA se agranda la caja de un control que forma parte de una
   fila apretada; se agranda su ZONA DE TOQUE con un pseudoelemento invisible.
   Cambiar la caja movería lo que tiene al lado y rompería cabeceras de
   tarjeta que ya están medidas. */
@media (pointer: coarse) {
  /* El doble toque para hacer zoom obliga al navegador a esperar ~300 ms
     antes de dar por bueno un toque. `manipulation` le dice que en estos
     controles no hay doble toque que esperar: el botón responde al instante.
     No desactiva el zoom de la página —eso sería inaccesible— solo el gesto
     sobre el control. */
  a, button, [role="button"], summary,
  .nav-link, .tab, .chip, .icon-btn, .btn,
  input[type="checkbox"], input[type="radio"], select,
  tr.is-clickable {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }

  /* Quitar el resalte gris del sistema sin poner nada a cambio deja la
     interfaz muda al tacto: se toca y no pasa nada hasta que la vista
     termina de pintar. Esta es la respuesta inmediata. */
  .btn:active, .icon-btn:active, .chip:active, .tab:active,
  .nav-link:active, .card.is-clickable:active {
    transform: scale(.975);
    transition-duration: 60ms;
  }
  tr.is-clickable:active { background: var(--surface-3); }

  /* Controles con etiqueta: la caja entera crece, que es lo correcto. */
  .btn { min-height: 44px; }
  .btn-sm { min-height: 38px; }        /* con los 8 px de separación, cumple */
  .icon-btn { min-width: 44px; min-height: 44px; }
  .nav-link { min-height: 44px; }
  .tab { min-height: 44px; }
  select, .select, .input, input:not([type="checkbox"]):not([type="radio"]) { min-height: 44px; }

  /* Controles pequeños dentro de filas medidas: zona de toque invisible.
     `inset` negativo crece hacia fuera sin ocupar espacio. */
  .icon-btn-sm,
  .chip .x,
  .table .icon-btn,
  .card-head .icon-btn { position: relative; }
  .icon-btn-sm::after,
  .chip .x::after,
  .table .icon-btn::after,
  .card-head .icon-btn::after {
    content: ""; position: absolute; inset: -8px; border-radius: inherit;
  }
  /* La casilla y el radio son 16 px por diseño; se toca su etiqueta entera. */
  .check, .radio { min-height: 44px; display: flex; align-items: center; }
}

/* Sin `hover` real, `:hover` se queda PEGADO después de tocar: la fila que se
   abrió queda resaltada para siempre hasta que se toca otra cosa. */
@media (hover: none) {
  .table tbody tr:hover { background: transparent; }
  .stack-bar > span:hover { filter: none; }
}

/* ============================================== BARRA SUPERIOR =========== */
/* Se mete debajo del reloj y la muesca cuando la plataforma corre instalada.
   Como `env()` es 0 en el navegador normal, la misma regla vale para los dos
   casos y no hace falta detectar el modo. */
.topbar {
  padding-top: var(--sa-t);
  height: calc(var(--topbar-h) + var(--sa-t));
  padding-left: max(var(--s6), var(--sa-l));
  padding-right: max(var(--s6), var(--sa-r));
}
/* La marca de la barra solo existe en teléfono: en escritorio el logotipo
   entero está en el raíl, a la vista, y repetirlo sería decirlo dos veces. */
.topbar .tb-mark { display: none; }

/* ================================================== CAJÓN LATERAL ======== */
.sidebar {
  padding-top: var(--sa-t);
  padding-left: var(--sa-l);
}
.sidebar-foot { padding-bottom: max(var(--s4), var(--sa-b)); }
/* El menú es largo: sin esto, al llegar al final el gesto arrastra la página
   de detrás y el cajón «rebota» sobre el contenido. */
.sidebar-nav { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }

/* =============================================== HOJAS Y MODALES ========= */
.drawer {
  padding-top: var(--sa-t);
  padding-bottom: var(--sa-b);
}
.modal-body, .drawer-body { overscroll-behavior: contain; }

/* ==========================================================================
   900 px · TABLETA EN VERTICAL
   ========================================================================== */

/* EL ZOOM DE IOS AL ESCRIBIR.
   Safari hace zoom sobre cualquier campo con letra de menos de 16 px en
   cuanto recibe el foco, y al salir NO lo deshace: la interfaz se queda
   ampliada y descuadrada, y hay que pellizcar para volver. La plataforma usa
   13 y 14 px en sus campos, así que le pasaba en TODOS los formularios.

   16 px exactos, no `--fs-base` (15 px): el umbral es 16 y no admite
   aproximaciones. */
@media (max-width: 900px) {
  input, select, textarea,
  .input, .select, .textarea,
  .filters .input, .filters .select,
  .search-input {
    font-size: 16px;
  }
  /* La barra de filtros fija 34 px de alto; con letra de 16 no cabe. */
  .filters .input, .filters .select { height: 44px; }
  .filters { gap: var(--s2); padding: var(--s3); }
}

/* ==========================================================================
   640 px · TELÉFONO
   ========================================================================== */
@media (max-width: 640px) {

  /* ------------------------------------------------------ Contenido ---- */
  .view {
    /* En horizontal la muesca se come el margen izquierdo: `max()` mantiene
       el aire de siempre y añade solo lo que haga falta. */
    padding-left: max(var(--s4), var(--sa-l));
    padding-right: max(var(--s4), var(--sa-r));
    /* Sitio para la barra inferior. Sin esto, la última fila de cada lista
       queda tapada y parece que la tabla se corta. */
    padding-bottom: calc(var(--tabbar-h) + var(--sa-b) + var(--s5));
  }

  /* --------------------------------- Rejillas escritas en el JS -------- */
  /* Catorce pantallas montan su «principal + lateral» con un `style=` en línea:
     `<div class="grid" style="grid-template-columns:minmax(0,1fr) 340px">`.
     En línea gana siempre sobre una hoja de estilos, así que en un teléfono se
     quedaban en dos columnas de 150 px —ilegibles— y la del Calendario, que
     pide 340 px FIJOS para su lateral, sacaba la barra horizontal de la página
     entera en cualquier pantalla de menos de 360.

     Este es el caso en que `!important` es la herramienta correcta y no un
     parche: es la única forma de que una hoja gane a un atributo `style`, y lo
     que se impone —una columna— es lo que las catorce quieren en un teléfono.
     La alternativa era tocar catorce sitios y confiar en que el siguiente que
     escriba una se acuerde. */
  .view .grid[style*="grid-template-columns"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  /* El encabezado deja de repartirse en dos columnas: el título arriba, los
     botones debajo y a lo ancho, que es donde llega el pulgar. */
  .page-head { flex-direction: column; align-items: stretch; gap: var(--s3); margin-bottom: var(--s5); }
  .page-head h1 { font-size: var(--fs-xl); }
  .page-head .actions { width: 100%; }
  .page-head .actions > .btn { flex: 1 1 auto; justify-content: center; }

  /* ------------------------------------------------- Barra superior ---- */
  /* Se va el plegador del raíl: en teléfono el raíl es un cajón y «plegarlo»
     no significa nada — el botón estaba ahí sin efecto visible. */
  .topbar [data-collapse],
  .sidebar-head .collapse-btn { display: none; }
  .topbar { gap: var(--s1); padding-left: max(var(--s3), var(--sa-l)); padding-right: max(var(--s3), var(--sa-r)); }
  /* La marca ocupa el hueco del plegador: sin ella la barra no dice de qué
     aplicación es, que en pantalla de inicio es justo lo que hay que decir. */
  .topbar .tb-mark { display: block; width: 26px; height: 26px; flex: none; margin-left: 2px; }
  .topbar > .theme-switch { margin: 0; }
  .user-btn .who { display: none; }

  /* ------------------------------------------------------- Tarjetas ---- */
  .card-head { padding: var(--s4); }
  .card-body { padding: var(--s4); }
  /* Cabecera con título Y control —«Headcount por equipo» + «Ver por:»— en una
     fila que no se parte: el título se comprime hasta partirse en tres líneas
     para dejarle sitio al desplegable. Que baje a la línea siguiente. */
  .card-head { flex-wrap: wrap; row-gap: var(--s3); }

  /* ------------------------------------- Fichas de indicador ----------- */
  /* En teléfono van a DOS columnas (base.css), y ahí el icono deja de caber
     al lado del rótulo: medido a 375 px, «Productividad», «Completado» y
     «Sin responsable» se cortaban; a 320 px se cortaban seis de seis en el
     panel de RRHH. No es cuestión de apretar —«Ausentismo» es UNA palabra y
     no se puede partir—, así que el icono sube a su propia línea y al rótulo
     le queda la ficha entera.

     SIEMPRE, no solo cuando no cabe. Con `flex-wrap` a secas cada ficha
     decide por su cuenta y en la misma fila salía «Abiertas» en línea y
     «Productividad» debajo: dos maneras de componer lo mismo, una al lado de
     la otra. Las fichas de una fila se leen en paralelo, y para eso tienen
     que estar cortadas por el mismo patrón.

     Dos estructuras porque hay dos: `.hr-kpi` pone el icono a la izquierda y
     el componente `UI.stat()` a la derecha — de ahí el `order` en el
     segundo, para que los dos acaben con el icono ARRIBA. */
  .grid-3 > .card .card-body > .row:first-child,
  .grid-4 > .card .card-body > .row:first-child,
  .grid-3 > .card .stat-top,
  .grid-4 > .card .stat-top {
    flex-wrap: wrap;
    row-gap: 8px;
  }
  .grid-3 > .card .stat-top > .stat-ico,
  .grid-4 > .card .stat-top > .stat-ico { order: -1; }

  .grid-3 > .card .card-body > .row:first-child > .grow,
  .grid-4 > .card .card-body > .row:first-child > .grow,
  .grid-3 > .card .stat-top > .grow,
  .grid-4 > .card .stat-top > .grow { flex-basis: 100%; }

  /* --------------------------------------------- Modales como hojas ---- */
  /* Un modal centrado en un teléfono queda lejos del pulgar y, con el teclado
     abierto, se parte por la mitad. Anclado abajo se comporta como una hoja
     del sistema: sube desde el borde, se agarra donde está la mano y el
     teclado lo empuja entero. */
  .overlay { padding: 0; place-items: end stretch; }
  .modal, .modal-sm, .modal-lg, .modal-xl {
    max-width: none; width: 100%;
    max-height: 92dvh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    border-bottom: 0;
    animation: sheet-up var(--t) var(--ease-out) both;
  }
  /* El asa: dice «esto se cierra hacia abajo» sin escribirlo. */
  .modal-head { position: relative; padding-top: var(--s6); }
  .modal-head::before {
    content: ""; position: absolute; top: 8px; left: 50%; transform: translateX(-50%);
    width: 36px; height: 4px; border-radius: var(--r-full);
    background: var(--border-strong);
  }
  .modal-foot {
    flex-direction: column-reverse; align-items: stretch;
    padding-bottom: max(var(--s4), var(--sa-b));
  }
  .modal-foot .btn { width: 100%; justify-content: center; }
  .modal-foot .grow { width: 100%; }

  .drawer { width: 100%; }

  /* La paginación enseña cinco páginas seguidas desde el 22-sep-2026: con la
     primera, la última y las flechas no cabe en 375 px, así que se parte en
     dos líneas centradas en vez de salirse de la tarjeta. */
  .pager-nav { flex-wrap: wrap; justify-content: center; }

  /* ------------------------------------------------------- Buscador ---- */
  .search-results { width: auto; left: var(--s3); right: var(--s3); }
  /* El de Clientes (0126) ocupa su fila entera; los desplegables se reparten
     debajo, como cualquier `.fsel`. */
  .cu-search { flex: 1 1 100%; max-width: none; min-width: 0; }
  .cu-bar-end { flex: 1 1 100%; }
  .cu-bar-end .cu-export { flex: 1 1 auto; }
  /* Partners (0135): registrar un seguimiento va en columna, con el botón a
     lo ancho, y la fecha de cada evento baja a su propia línea. */
  .pt-composer { padding: var(--s3); }
  .pt-composer-row { flex-direction: column; align-items: stretch; }
  .pt-mini { min-width: 0; }
  .pt-log-btn { justify-content: center; }
  .pt-ev-at { margin-left: 0; flex-basis: 100%; }
  .pt-views { padding: 0 var(--s2); }

  /* -------------------------------------------- Tiras que se deslizan -- */
  /* Pestañas, chips y filtros no se parten en varias líneas: se deslizan en
     una sola, como en cualquier app. Partirse dejaba el contenido empujado
     tres dedos hacia abajo antes de empezar. */
  .tabs, .chips, .filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    /* El desbordamiento horizontal recorta la sombra de foco de los hijos;
       este relleno le devuelve el sitio. */
    padding-bottom: 2px;
  }
  .tabs::-webkit-scrollbar, .chips::-webkit-scrollbar, .filters::-webkit-scrollbar { display: none; }
  .tabs > *, .chips > *, .filters > * { flex: none; scroll-snap-align: start; }
  .filters .search, .filters .input { width: min(240px, 72vw); }

  /* ------------------------------------------------------ Gráficas ----- */
  /* El globo de una gráfica es de ratón. En teléfono ocupa media pantalla y
     se queda pegado donde se tocó. */
  .chart-tip { max-width: 78vw; white-space: normal; }
}

/* ==========================================================================
   TABLAS APILADAS · 640 px
   Una tabla de doce columnas en 375 px solo se puede leer arrastrando de
   lado, columna a columna, sin ver nunca a quién pertenece el dato. Apilada
   es una tarjeta por fila: la primera celda hace de título y el resto son
   pares «rótulo · valor».

   El rótulo lo pone `UI.stackTables()` en `data-l`, copiado del `<th>` de la
   columna. Si por lo que sea no llegó, el par se ve igual: sin rótulo, pero
   con su valor.

   Escape: `<div class="table-wrap" data-stack="off">` mantiene el arrastre
   lateral. Es para las tablas que SON una rejilla —una malla de horarios, un
   calendario— donde apilar destruye el significado.
   ========================================================================== */
@media (max-width: 640px) {
  /* `.table-wrap` conserva su `overflow-x: auto`. Se probó a quitárselo —una
     tabla apilada ya no necesita arrastre— y se rompió la MALLA DE HORARIOS:
     esa rejilla de 900 px no es una tabla, pero vive dentro de un
     `.table-wrap`, y sin el arrastre desbordaba la página entera. Como la
     tabla apilada cabe, el contenedor no dibuja ninguna barra: dejarlo puesto
     no cuesta nada y evita romper lo que no es una tabla. */

  .table-wrap:not([data-stack="off"]) .table,
  .table-wrap:not([data-stack="off"]) .table tbody,
  .table-wrap:not([data-stack="off"]) .table tr,
  .table-wrap:not([data-stack="off"]) .table td { display: block; width: auto; }

  /* Varias vistas le ponen un ancho mínimo a SU tabla para que las columnas no
     se apelotonen al arrastrar de lado —`.itd-table` pide 420 px, y otras
     truncan la primera columna con el truco de `width:100%; max-width:0`—.
     Apilada no hay columnas que cuadrar: esas medidas dejaban la tarjeta más
     ancha que la pantalla y devolvían el arrastre lateral que veníamos a
     quitar. Se anulan aquí, en un solo sitio, en vez de ir vista por vista. */
  .table-wrap:not([data-stack="off"]) .table { min-width: 0; }
  .table-wrap:not([data-stack="off"]) .table td,
  .table-wrap:not([data-stack="off"]) .table td:first-child { min-width: 0; max-width: none; width: auto; }

  /* La cabecera desaparece: su texto ya viaja en cada celda. */
  .table-wrap:not([data-stack="off"]) .table thead { display: none; }

  .table-wrap:not([data-stack="off"]) .table tr {
    margin-bottom: var(--s3);
    padding: var(--s3) var(--s4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
  }
  .table-wrap:not([data-stack="off"]) .table tr:last-child { margin-bottom: 0; }

  .table-wrap:not([data-stack="off"]) .table td {
    display: flex; align-items: baseline;
    gap: var(--s2) var(--s4);
    flex-wrap: wrap;
    padding: 5px 0;
    border-bottom: 0;
    text-align: left;
  }
  /* El rótulo empuja TODO lo demás a la derecha con un solo margen. Con
     `space-between` en el contenedor, una celda de dos trozos —«2 mar 2015» y
     «11 años y 6 meses»— se repartía los tres por igual y el dato quedaba
     partido en dos mitades de la pantalla. Así el rótulo se queda a la
     izquierda y el valor entero, junto, a la derecha. */
  .table-wrap:not([data-stack="off"]) .table td::before {
    content: attr(data-l);
    flex: none; max-width: 45%; margin-right: auto;
    font-size: var(--fs-xs); font-weight: 600; color: var(--ink-3);
  }
  /* Celda decorativa (el galón de «abrir»): la marca `UI.stackTables()`. */
  .table-wrap:not([data-stack="off"]) .table td[data-stack="hide"] { display: none; }

  /* Nada dentro de una celda puede ser más ancho que la celda. Sin esto, un
     nombre largo sin espacios o un enlace de correo estiraban la tarjeta y con
     ella la página: el desbordamiento sube por los contenedores hasta el
     `main`, porque un hijo de flex mide `min-width: auto` por defecto. */
  .table-wrap:not([data-stack="off"]) .table td > * { min-width: 0; max-width: 100%; }

  /* Las barras van al 100 % del ancho, que en una celda apilada es el ancho de
     la celda ENTERA, rótulo incluido: se salían por la derecha y arrastraban
     la página con ellas. Se les da su propia línea debajo del rótulo, que es
     donde una barra se lee mejor de todas formas. */
  .table-wrap:not([data-stack="off"]) .table td > .progress,
  .table-wrap:not([data-stack="off"]) .table td > .stack-bar {
    flex: 1 1 100%; width: auto;
  }
  /* Celda sin rótulo (la primera, o una que no tenía `<th>`): ocupa la línea
     entera y no deja un hueco a la izquierda. */
  .table-wrap:not([data-stack="off"]) .table td:not([data-l])::before,
  .table-wrap:not([data-stack="off"]) .table td[data-l=""]::before { display: none; }

  /* Primera celda = título de la tarjeta. Se separa del resto con la línea
     que ya no tienen las celdas. */
  .table-wrap:not([data-stack="off"]) .table td:first-child {
    display: block;
    padding: 0 0 var(--s2);
    margin-bottom: var(--s2);
    font-weight: 600;
    border-bottom: 1px solid var(--border-soft);
  }
  .table-wrap:not([data-stack="off"]) .table td:first-child::before { display: none; }

  /* Fila de «no hay nada» (un `td` con `colspan`): es un mensaje, no una
     tarjeta con pares. */
  .table-wrap:not([data-stack="off"]) .table td[colspan] {
    display: block; text-align: center; font-weight: 400;
    border-bottom: 0; margin: 0; padding: var(--s3) 0;
  }
  .table-wrap:not([data-stack="off"]) .table td[colspan]::before { display: none; }

  /* La alineación a la derecha de las cifras la resuelve ahora el `flex`. */
  .table-wrap:not([data-stack="off"]) .table .num { text-align: left; }
  .table-wrap:not([data-stack="off"]) .table .shrink { width: auto; white-space: normal; }
}

/* ==========================================================================
   BARRA INFERIOR
   Cinco destinos como mucho, que es el límite en el que la fila sigue siendo
   legible y cada blanco conserva sus 44 px. Los cuatro primeros salen del
   menú y respetan los permisos: quien no tiene una pantalla no la ve aquí
   tampoco. El quinto abre el cajón con TODO lo demás — la barra es un atajo,
   no un menú recortado.
   ========================================================================== */
.tabbar { display: none; }

@media (max-width: 640px) {
  .tabbar {
    position: fixed; left: 0; right: 0; bottom: 0;
    z-index: calc(var(--z-drawer) - 2);
    display: flex; align-items: stretch;
    height: calc(var(--tabbar-h) + var(--sa-b));
    padding: 0 max(var(--s1), var(--sa-l)) var(--sa-b) max(var(--s1), var(--sa-r));
    background: var(--surface);
    border-top: 1px solid var(--border);
    /* Opaca, como la barra superior: el cristal deja translucir la lista al
       arrastrar y ensucia la lectura de lo que hay debajo. */
  }
  .tabbar__item {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px;
    padding: 6px 2px;
    color: var(--ink-3);
    background: none; border: 0;
    transition: color var(--t-fast) var(--ease);
  }
  .tabbar__item svg { width: 21px; height: 21px; }
  .tabbar__item .lb {
    font-size: 10px; font-weight: 600; letter-spacing: .01em;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .tabbar__item.is-active { color: var(--primary); }
  .tabbar__item:active { color: var(--primary); }

  /* El punto del destino activo. Un subrayado arriba, del ancho del icono:
     dice dónde estoy sin robar alto a la etiqueta. */
  .tabbar__item.is-active::before {
    content: ""; position: absolute; top: 0;
    width: 26px; height: 2px; border-radius: 0 0 2px 2px;
    background: var(--primary);
  }
  .tabbar__item { position: relative; }

  /* Contador: el mismo rojo de marca que en el raíl. */
  .tabbar__item .pill {
    position: absolute; top: 4px; left: 50%; margin-left: 5px;
    min-width: 16px; padding: 0 4px;
    font-size: 9px; font-weight: 700; line-height: 16px; text-align: center;
    color: #fff; background: var(--brand-red);
    border-radius: var(--r-full);
    font-variant-numeric: tabular-nums;
  }
}

/* ==========================================================================
   400 px · TELÉFONO ESTRECHO
   Por debajo de esto, dos columnas dejan menos de 160 px por tarjeta: la
   cifra cabe pero el rótulo se parte en tres líneas. Se deja de repartir.
   ========================================================================== */
@media (max-width: 400px) {
  .home-quick, .emp-band, .emp-kpis, .rt-grid, .ot-tri, .res-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .page-head h1 { font-size: var(--fs-lg); }
  .tabbar__item .lb { font-size: 9px; }

  /* Un título con su selector de periodo al lado («7 días · 30 · 90») no cabe
     en 320 px: el selector no se encoge y sacaba la página por la derecha
     (TI › Salud, 23-sep-2026). Baja a su propia línea. */
  .row-between:has(> .segmented) { flex-wrap: wrap; }
}

/* ==========================================================================
   MODO INSTALADO
   Cuando corre desde la pantalla de inicio no hay barra de direcciones ni
   botón de recargar: la plataforma es lo único en pantalla.
   ========================================================================== */
@media (display-mode: standalone) {
  /* Sin barra del navegador, el gesto de «tirar para recargar» de Safari
     dispara al arrastrar hacia abajo dentro de cualquier lista. Se corta en
     el documento; las listas internas siguen arrastrándose. */
  body { overscroll-behavior-y: none; }

  /* Seleccionar texto con el dedo es un gesto de escritorio importado: aquí
     lo único que hace es sacar la lupa al arrastrar por una tarjeta. Se
     conserva donde el texto se copia de verdad. */
  .nav-link, .tabbar__item, .topbar, .stat, .kpi { -webkit-user-select: none; user-select: none; }
}

/* ==========================================================================
   ANIMACIÓN DE LA HOJA
   ========================================================================== */
@keyframes sheet-up {
  from { transform: translateY(14px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .modal, .modal-sm, .modal-lg, .modal-xl { animation: none; }
  .btn:active, .icon-btn:active, .chip:active, .tab:active,
  .nav-link:active, .card.is-clickable:active { transform: none; }
}

/* ==========================================================================
   PANEL DE GERENCIA
   La cabecera se apila y las pestanas se arrastran de lado --ya llevan su
   propio desbordamiento en views.css, aqui solo se les quita el borde para
   que la fila no parezca cortada a mitad de gesto--.
   ========================================================================== */
@media (max-width: 900px) {
  .mgt-split { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 640px) {
  .mgt-head { flex-direction: column; gap: var(--s3); }
  .mgt-head-side { width: 100%; justify-content: flex-start; }
  .mgt-hi { font-size: var(--fs-xl); }
  /* Dos indicadores por fila y no cinco: a 375 px, `auto-fit` con minimo de
     190 px deja uno por fila y la primera pantalla se va entera en la mitad
     de las cifras. */
  .mgt-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); }
  .mgt-tabs { margin-left: calc(var(--s4) * -1); margin-right: calc(var(--s4) * -1);
              padding-left: var(--s4); padding-right: var(--s4); }
}

@media (max-width: 400px) {
  .mgt-kpis { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   HISTORIAL DE LA FICHA (0120)
   Los dos botones de registrar uno encima del otro, los tipos de acción en dos
   columnas y la leyenda fuera de la cabecera, que ya lleva «Ver más». En
   táctil, corregir y borrar se ven siempre: no hay «pasar por encima».
   ========================================================================== */
@media (max-width: 640px) {
  .hist-add { grid-template-columns: minmax(0, 1fr); }
  .ev-kinds { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hist > * { padding-left: 40px; }
  .hist > .hist-ytag { padding-left: 0; }
  .hist-more { padding-left: 40px; }
  .hist-card .card-head .hist-legend { display: none; }
}

@media (hover: none) {
  .hist-act { opacity: 1; }
}
