/* OnSite by Gestacore, hoja 2 de 4: los componentes sueltos que usa cualquier carcasa (botones,
   campos, chips y sellos, tarjetas, avisos, línea de tiempo, tabla->tarjetas, checklist, estado
   vacío, embudo y utilidades de layout). Se carga DESPUÉS de base.css. */
/* ---------- Botones ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); min-height: 44px; padding: 0 var(--s-4); border-radius: var(--r-md); border: 1px solid transparent; font: inherit; font-weight: 600; cursor: pointer; transition: background var(--dur-rapido) var(--ease), transform var(--dur-rapido) var(--ease); text-decoration: none; white-space: nowrap; }
.btn:active { transform: translateY(1px); }
.btn-primario { background: var(--accent); color: #232222; }
.btn-primario:hover { background: color-mix(in srgb, var(--accent) 90%, #232222); }
.btn-teal { background: var(--primary); color: #FDFCFA; }
.btn-teal:hover { background: color-mix(in srgb, var(--primary) 88%, var(--fg)); }
:root[data-tema="oscuro"] .btn-teal { color: #1A1918; }
.btn-secundario { background: var(--surface); color: var(--fg); border-color: var(--border-strong); }
.btn-secundario:hover { background: var(--surface-2); }
.btn-peligro { background: var(--surface); color: var(--destructive); border-color: var(--destructive); }
.btn-peligro:hover { background: var(--bad-bg); }
/* Ida en falso (H4 Task 2, revisión ronda 1): mismo motivo que `.chip-falso`/`.kpi-falso` -- el
   rayado confinado a una barra izquierda vía `::before`, NUNCA debajo del texto (un `#232222`
   fijo sobre el rayado lleno era ilegible en oscuro, donde `--falso-bg` se voltea a un café casi
   negro). `color: var(--falso)` sobre `background: var(--falso-bg)` es la MISMA pareja que ya usan
   esos dos (ya audita cómoda arriba de 4.5:1 en los dos temas: no hace falta un override de tema
   oscuro como `.btn-teal`, porque las dos variables ya se voltean solas con `:root[data-tema]`).
   `.btn.btn-falso` (compuesta) para el padding-izquierdo: le gana en especificidad a `.btn-mini`
   (que trae su propio `padding` corto) sin importar en qué orden caigan las dos clases. */
.btn-falso { position: relative; overflow: hidden; background: var(--falso-bg); color: var(--falso); border-color: var(--falso-border); }
.btn-falso::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 10px; background: var(--rayado); }
.btn.btn-falso { padding-left: 22px; }
.btn-falso:hover { background: color-mix(in srgb, var(--falso-bg) 75%, var(--falso) 25%); }
.btn-fantasma { background: transparent; color: var(--primary); }
.btn-fantasma:hover { background: var(--primary-bg); }
.btn-mini { min-height: 44px; padding: 0 var(--s-3); font-size: var(--t-sm); }
.btn-icono { width: 44px; padding: 0; }
.btn-grande { min-height: 56px; font-size: var(--t-md); width: 100%; border-radius: var(--r-md); white-space: normal; line-height: 1.3; padding: var(--s-3) var(--s-4); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; pointer-events: none; }
.btn[aria-busy="true"] { position: relative; color: transparent; pointer-events: none; }
.btn[aria-busy="true"]::after { content: ""; position: absolute; width: 18px; height: 18px; border-radius: 50%; border: 2px solid; border-color: #232222 transparent #232222 transparent; animation: giro .8s linear infinite; }
@keyframes giro { to { transform: rotate(360deg); } }
.btn-ayuda, .btn-mas { min-height: 44px; width: 44px; padding: 0; border-radius: 50%; border: 1px solid var(--border-strong); background: var(--surface); color: var(--fg); font-weight: 700; cursor: pointer; }
/* Prosa + chips en una línea PAREJA (fix 2026-08-31): inline, cada chip flotaba a su altura. */
.linea-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
/* Tablas de pocas columnas cortas: tope de lectura, que no se estiren a media pantalla de hueco. */
.tabla-angosta { max-width: 860px; }
/* Pila con aire (fix 2026-08-31): para listas con barra de filtros + acciones + tabla, donde el
   gap de 12px de `.pila` se sentía apretado (Joe, en Equipos). */
.pila-suelta { gap: var(--s-5); }

/* ---------- Campos ---------- */
/* R9 (H9 T7): `.campo` es casi siempre un item de un grid/flex (`.filtros-reportes`, `.pila`,
   `.fila-contacto`...); sin `min-width: 0` su ancho mínimo por defecto ("auto") toma el
   min-content del <select> de adentro (el nombre más largo de una opción), que puede ganarle al
   `minmax(160px, 1fr)` del contenedor y desbordar -- se vio en /panel/reportes a 820px. */
.campo { display: grid; gap: var(--s-1); min-width: 0; }
.campo label { font-weight: 600; font-size: var(--t-sm); }
.campo .hint { color: var(--muted-fg); font-size: var(--t-xs); }
/* R9 (H9 T7, continuación): el `min-width:0` de `.campo` no alcanza si el <select> de adentro
   sigue sin ancho explícito -- sin `width:100%` un <select> se dimensiona por su opción más
   larga (min-content), lo que desbordó /panel/auditoria a 820px (usuario/entidad con nombres
   largos). `width:100%; min-width:0` lo obliga a llenar la columna que ya le da el grid.
   Fix de revisión (T7 ronda 2): el selector original incluía checkbox/radio -- `width:100%` los
   estira a un rectángulo enorme en vez del cuadrado nativo (caso real: el interruptor de
   `panel/config/_form_cobranza.html`, anidado directo en `.campo`). `:not([type="checkbox"])
   :not([type="radio"])` los excluye; siguen viendo `.campo input:focus` de abajo sin problema
   porque ese selector no cambió. */
.campo input:not([type="checkbox"]):not([type="radio"]), .campo select, .campo textarea { font: inherit; width: 100%; min-width: 0; min-height: 44px; padding: 0 var(--s-3); border-radius: var(--r-md); border: 1px solid var(--border-strong); background: var(--surface); color: var(--fg); }
.campo textarea { padding: var(--s-3); min-height: 96px; resize: vertical; }
.campo input::placeholder { color: var(--muted-fg); }
.campo input:focus, .campo select:focus, .campo textarea:focus { outline: none; border-color: var(--ring); box-shadow: var(--ring-shadow); }
/* H28a (D270): el borde rojo repite a propósito el `:not(checkbox/radio)` de la regla de campos de
   arriba: sin él mide (0,2,1) contra sus (0,3,1) y nunca ganaba (ni el input ni la caja del combo
   se ponían rojos, solo el select y el textarea). Un radio o una casilla no llevan borde. */
.campo input[aria-invalid="true"]:not([type="checkbox"]):not([type="radio"]), .campo select[aria-invalid="true"], .campo textarea[aria-invalid="true"] { border-color: var(--bad); }
.campo .error { color: var(--bad); font-size: var(--t-xs); }
/* Ola final de H30a (W2, barrido A): el MISMO aviso de error fuera de un `.campo`: el de "Guardar unidad"
   (`#error-unidad`), el de "Cerrar visita" y los del diálogo "No se hizo", que vive en la capa superior. Salían en el
   color del texto, justo donde se lee "Falta la firma de quien te atendió.". Solo el `<p>`: el indicador de
   sincronización (`span.sync.error`, carcasas.css) pinta de rojo su punto, no su texto. */
p.error { color: var(--bad); font-size: var(--t-xs); }
/* H28a (D270): el aviso que pinta `formularios.mjs` cuando un campo no cuadra, en lugar del globo
   nativo. Dentro de un `.campo` ya lo viste la regla de arriba; fuera (un grupo de radios en su
   fieldset, la casilla del contrato) necesita esta. `--bad` mide >= 5.4:1 en claro y oscuro. */
.error-campo { margin: 0; color: var(--bad); font-size: var(--t-xs); line-height: var(--lh-xs); }
/* Si el `.campo` es un <label> dentro de una fila flex, el aviso no cabe adentro de él y queda como su hermano:
   al final de la fila y a todo lo ancho, para que no se meta entre dos campos. */
.fila > .error-campo { flex: 1 0 100%; order: 1; }
.campo input:disabled { opacity: .6; background: var(--surface-2); }

/* ---------- Chips y sellos ---------- */
.chip { display: inline-flex; align-items: center; gap: 6px; min-height: 26px; padding: 0 10px; border-radius: var(--r-sm); font-size: var(--t-xs); font-weight: 600; letter-spacing: .01em; border: 1px solid var(--border); background: var(--surface-2); color: var(--fg); white-space: nowrap; }
.chip-ok { color: var(--ok); background: var(--ok-bg); border-color: var(--ok-border); }
.chip-warn { color: var(--warn); background: var(--warn-bg); border-color: var(--warn-border); }
.chip-info { color: var(--info); background: var(--info-bg); border-color: var(--info-border); }
/* H15 T3 (R9): faltaba en la familia -- el pendiente "Incumplidas sin causa" del tablero es el
   primer badge clicable que necesita el tono `--bad` (los chips-veredicto ya lo usan, pero solo
   dentro de su propia forma de punto, no como chip suelto). */
.chip-bad { color: var(--bad); background: var(--bad-bg); border-color: var(--bad-border); }
.chip-primario { color: var(--primary); background: var(--primary-bg); border-color: color-mix(in srgb, var(--primary) 40%, transparent); }
.chip-falso { color: var(--falso); background: var(--falso-bg); border-color: var(--falso-border); padding-left: 0; overflow: hidden; }
.chip-falso::before { content: ""; width: 10px; align-self: stretch; background: var(--rayado); margin-right: 8px; }
/* Chip-veredicto (Diseño §2.1, RN2-28/29, H15 T2): el semáforo de cumplimiento contra el SLA --
   punto de 8 px (`::before`) + texto, SIN caja (ni fondo ni borde): forma distinta del chip de
   estado de v1 (arriba, texto sobre fondo tenue) para que nunca se confundan flujo y calificación.
   Nunca color solo (el texto ya lo dice, ver `web/veredictos.py`). Variantes de color (`clase`) y
   de forma del punto (`punto`) viajan por separado -- p. ej. "Fuera de plazo" y "Incumplida"
   comparten color `--bad` pero el punto es hueco en una y sólido en la otra (corriendo vs. sellada,
   R6). Se pinta con la macro `comunes/_chip_sla.html::chip_sla`, nunca a mano. */
.chip-veredicto { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-xs); font-weight: 600; color: var(--muted-fg); white-space: nowrap; }
.chip-veredicto::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
.chip-veredicto.punto-hueco::before { background: none; border: 1.5px solid currentColor; }
.chip-veredicto.punto-ninguno::before { content: none; }
.chip-veredicto.veredicto-ok { color: var(--ok); }
.chip-veredicto.veredicto-warn { color: var(--warn); }
.chip-veredicto.veredicto-bad { color: var(--bad); }
.chip-veredicto.veredicto-neutro { color: var(--muted-fg); }
.chip-veredicto.veredicto-corriendo { color: var(--muted-fg); }
.chip-veredicto.veredicto-corriendo::before { border-color: var(--border-strong); }

/* Sello de tiempo: la hora grande en mono, la fecha chica */
.sello { display: grid; line-height: 1; }
.sello .hora { font-family: var(--font-mono); font-weight: 500; font-size: var(--t-2xl); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.sello .fecha { font-size: var(--t-xs); color: var(--muted-fg); margin-top: 4px; }
.sello-grande .hora { font-size: var(--t-hora); }

/* ---------- Tarjetas ---------- */
.tarjeta { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-4); box-shadow: var(--sh-card); }
.tarjeta-h:hover { box-shadow: var(--sh-card-h); }
.kpi .etiqueta { font-size: var(--t-sm); color: var(--muted-fg); font-weight: 500; }
.kpi .cifra { font-family: var(--font-mono); font-size: var(--t-2xl); font-weight: 500; line-height: var(--lh-2xl); margin-top: var(--s-2); font-variant-numeric: tabular-nums; }
.kpi .detalle { font-size: var(--t-sm); color: var(--muted-fg); margin-top: var(--s-2); }
.kpi-falso { position: relative; overflow: hidden; border-color: var(--falso-border); }
.kpi-falso::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 8px; background: var(--rayado); }
.kpi-falso .cifra { color: var(--falso); }

/* ---------- Avisos ---------- */
.aviso { display: flex; gap: var(--s-3); align-items: flex-start; padding: var(--s-3) var(--s-4); border-radius: var(--r-md); border: 1px solid; font-size: var(--t-sm); }
.aviso.ok { color: var(--ok); background: var(--ok-bg); border-color: var(--ok-border); }
.aviso.warn { color: var(--warn); background: var(--warn-bg); border-color: var(--warn-border); }
.aviso.bad { color: var(--bad); background: var(--bad-bg); border-color: var(--bad-border); }
.aviso.info { color: var(--info); background: var(--info-bg); border-color: var(--info-border); }
.aviso.falso { color: var(--falso); background: var(--falso-bg); border-color: var(--falso-border); }

/* ---------- Banda "sin verificar" (H16 T5, R10): 4 px --bad -- pieza APARTE del chip-veredicto,
   pueden convivir. `.sin-verificar-linea` es el texto "Sin verificar hace N días" con su propia
   marca de 4 px (fila de la lista Y cabecera del detalle); `tr.sin-verificar` es la banda de la
   fila completa (inset, sobrevive el border-collapse de .tabla en escritorio y se convierte en el
   borde de la tarjeta a 640 px, ver el media query de .tabla). */
.sin-verificar-linea { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--bad); font-size: var(--t-sm); font-weight: 500; }
.sin-verificar-linea::before { content: ""; width: 4px; height: 1em; background: var(--bad); border-radius: 1px; flex: none; }
/* M3 (ronda de fixes 1): acotada a escritorio -- a <= 640 px `.tabla tr` YA es la tarjeta (ver el
   media query de `.tabla` arriba) y trae su PROPIA regla; sin el `min-width` de aquí, las dos
   pintaban a la vez ahí abajo (borde de la tarjeta + una segunda barra dentro del padding). */
@media (min-width: 641px) { .tabla tr.sin-verificar td:first-child { box-shadow: inset 4px 0 0 var(--bad); } }
@media (max-width: 640px) { .tabla tr.sin-verificar { box-shadow: inset 4px 0 0 var(--bad); } }

/* ---------- Línea de tiempo (bitácora de la visita) ---------- */
.bitacora { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.bitacora li { display: grid; grid-template-columns: 84px 20px minmax(0, 1fr); gap: 0 var(--s-3); padding-bottom: var(--s-5); position: relative; }
/* H22: un correo o un username largo es una ficha irrompible; con `1fr` a secas la columna crece a su
   ancho mínimo y el modal Historial la recorta a 390 px. `minmax(0, 1fr)` + `anywhere` la parten. */
.bitacora .que, .bitacora .quien { overflow-wrap: anywhere; }
.bitacora .cuando { font-family: var(--font-mono); font-size: var(--t-base); font-weight: 500; font-variant-numeric: tabular-nums; text-align: right; line-height: 1.2; }
.bitacora .cuando small { display: block; font-family: var(--font-ui); font-size: var(--t-xs); color: var(--muted-fg); font-weight: 400; }
.bitacora .nodo { position: relative; }
.bitacora .nodo::before { content: ""; position: absolute; left: 9px; top: 18px; bottom: -4px; width: 2px; background: var(--primary); }
.bitacora li:last-child .nodo::before { display: none; }
.bitacora .nodo::after { content: ""; position: absolute; left: 4px; top: 4px; width: 12px; height: 12px; border-radius: 50%; background: var(--primary); box-shadow: 0 0 0 3px var(--surface); }
.bitacora .pendiente .nodo::after { background: var(--surface); border: 2px solid var(--border-strong); }
.bitacora .pendiente .nodo::before { background: var(--border); }
.bitacora .falso .nodo::after { background: var(--falso); border-radius: 2px; transform: rotate(45deg); }
.bitacora .falso .nodo::before { background: var(--rayado); width: 6px; left: 7px; }
.bitacora .que { font-weight: 600; }
.bitacora .quien { font-size: var(--t-sm); color: var(--muted-fg); }

/* ---------- Tabla → tarjetas ---------- */
/* Red de seguridad de scroll horizontal propio (H7 T2): `.tabla`/`.tabla-densa` se vuelven
   tarjetas antes de que el ancho estorbe (640/900 px), pero en la banda intermedia (tablet,
   ~700-1024 px) una tabla ancha real puede seguir sin caber. El contenedor scrollea, nunca el
   body de la página (`overflow-x` global). */
.tabla-scroll { overflow-x: auto; }
.tabla { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.tabla th { text-align: left; font-size: var(--t-xs); color: var(--muted-fg); font-weight: 600; padding: var(--s-2) var(--s-3); background: var(--surface-2); border-bottom: 1px solid var(--border); }
.tabla td { padding: var(--s-3); border-bottom: 1px solid var(--border); vertical-align: middle; }
.tabla tr:hover td { background: color-mix(in srgb, var(--surface-2) 60%, transparent); }
/* Filas atenuadas (H11 T5): el apartado Eliminados de Configuración, Usuarios -- un eliminado no
   está "activo pero apagado" como un desactivado normal, está fuera hasta que alguien lo reviva. */
.fila-atenuada { opacity: .6; }
.fila-atenuada:hover { opacity: 1; }
/* H30b (B4): en una CELDA ("Nueva liquidación" atenúa las celdas de la visita bloqueada, no la fila) el hover encendía una
   sola celda y la casilla deshabilitada parecía viva: la celda se queda atenuada. Las filas de la casa no cambian. */
td.fila-atenuada:hover { opacity: .6; }
.tabla .num { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.tabla th.num { font-family: var(--font-ui); }   /* el mono es para el dato, no para el rótulo */
.barra { height: 6px; border-radius: var(--r-pill); background: var(--surface-2); overflow: hidden; }
.barra > span { display: block; height: 100%; background: var(--primary); }
.barra.falso > span { background: var(--rayado); }
@media (max-width: 640px) {
  .tabla thead { display: none; }
  .tabla, .tabla tbody { display: block; width: 100%; }
  .tabla tr { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: var(--s-1) var(--s-4); align-items: center; border: 1px solid var(--border); border-radius: var(--r-md); margin-bottom: var(--s-2); background: var(--surface); padding: var(--s-3) var(--s-4); }
  .tabla td { display: block; border: 0; padding: 0; }
  .tabla td:first-child { grid-column: 1 / -1; }
  .tabla td[data-col]:not(:first-child)::before { content: attr(data-col); display: block; font-size: var(--t-xs); color: var(--muted-fg); font-family: var(--font-ui); }
  .tabla .num { text-align: left; }
  /* Celdas que en la tarjeta de 3 pistas no caben al lado de otras (H25, lista de /hardware): el chip
     de la prueba con su fecha y la casilla del lote van a renglón propio. */
  .tabla td.renglon-propio { grid-column: 1 / -1; }
  /* R9 (H9 T7): en la tarjeta móvil, el folio/nombre de la primera columna es un <a> de una sola
     línea de texto (~17px de alto) -- el área táctil real quedaba muy por debajo de los 44px.
     `min-height` + `align-items:center` en flex la sube a 44px sin tocar ninguna plantilla. */
  .tabla td:first-child a { display: flex; align-items: center; min-height: 44px; }
  /* H22: la celda de texto libre de Auditoría ("Detalle") era una columna `auto` más de la
     tarjeta y aplastaba a las otras dos hasta encimarlas; toma su propio renglón, como `.acciones`. */
  .tabla td.detalle-celda { grid-column: 1 / -1; }
}

/* ---------- Checklist (portal) ---------- */
.check { display: grid; grid-template-columns: 28px 1fr; gap: var(--s-3); align-items: start; padding: var(--s-4); border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); min-height: 64px; cursor: pointer; }
.check:hover { border-color: var(--border-strong); }
.check input { width: 28px; height: 28px; margin: 0; accent-color: var(--primary); cursor: pointer; }
.check .titulo { font-weight: 600; }
.check .ayuda { font-size: var(--t-sm); color: var(--muted-fg); margin-top: 2px; }
.check.listo { border-color: color-mix(in srgb, var(--primary) 45%, var(--border)); background: color-mix(in srgb, var(--primary-bg) 55%, var(--surface)); }
.check .marca { font-size: var(--t-xs); color: var(--primary); margin-top: var(--s-1); font-family: var(--font-mono); }

/* ---------- Estado vacío ---------- */
.vacio { border: 1px dashed var(--border-strong); border-radius: var(--r-md); padding: var(--s-8) var(--s-4); text-align: center; display: grid; gap: var(--s-2); justify-items: center; }

/* ---------- Embudo del tablero: dónde se atoran las órdenes (Diseño §8) ---------- */
.embudo { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3); }
.etapa { padding: var(--s-4); border-radius: var(--r-md); background: var(--surface); border: 1px solid var(--border); display: grid; gap: var(--s-1); color: inherit; text-decoration: none; }
.etapa:hover { box-shadow: var(--sh-card-h); }
.etapa .cifra { font-family: var(--font-mono); font-size: var(--t-xl); font-weight: 500; }
.etapa .nombre { font-size: var(--t-sm); font-weight: 600; }
.etapa .desde { font-size: var(--t-xs); color: var(--muted-fg); }
.etapa.atorada { border-color: var(--warn-border); background: var(--warn-bg); }
.etapa.atorada .cifra { color: var(--warn); }
/* H30a: la tarjeta "En sitio con la espera vencida" del tablero, con el borde del mismo ámbar de la etapa atorada
   (Diseño de la Tanda 3, §1: ámbar = esperó de más). */
.tarjeta.espera-vencida { border-color: var(--warn-border); }
@media (max-width: 1024px) { .embudo { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Fila de tarjetas KPI sueltas (H7 T6, cobranza: los 4 buckets de aging): mismo grid responsivo
   que `.embudo`, pero genérica -- no son etapas de un flujo, son cifras (`.kpi`) sin enlace. */
.kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3); }
@media (max-width: 1024px) { .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------- Utilidades de layout ---------- */
.fila { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.entre { justify-content: space-between; }
/* R9 (H9 T7): sin `grid-template-columns` explícito, la única columna implícita se dimensiona
   "auto" (max-content de su hijo más ancho); un hijo con su propio grid interno de `auto-fit`
   (ej. `.filtros-reportes`) puede pedir más ancho del que hay y desborda -- se vio en
   /panel/reportes a 820px (873px de scroll contra 820 de viewport). `minmax(0, 1fr)` topa esa
   columna al ancho disponible sin cambiar el layout normal (sigue siendo una pila vertical). */
.pila { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-3); }
/* `<fieldset class="pila">` (H5 T2, campo/stock/pasar): quita el borde/padding/min-width que el
   navegador le pone por default a un fieldset -- si no, se ve una caja ajena al resto de la casa
   alrededor de la lista de checkboxes. La leyenda queda con el mismo peso que un `.campo label`. */
fieldset.pila { border: 0; margin: 0; padding: 0; min-width: 0; }
fieldset.pila > legend { padding: 0; font-weight: 600; font-size: var(--t-sm); margin-bottom: var(--s-1); }
/* Separador entre bloques repetidos dentro de una tarjeta (H4 T3: filas de `_relojes.html`, una
   por ida en falso): la casa no usa `<hr>` crudo, este es el equivalente con la línea de la casa. */
.separador { margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px solid var(--border); }
.contenedor { width: 100%; max-width: 1400px; margin: 0 auto; padding: var(--s-6); min-width: 0; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }


/* ---------- Escoba del barrido H18 (B1 y B3): la tarjeta de 3 pistas de `.tabla` ----------
   Reglas NUEVAS al final de la hoja, no encima de las de arriba (Ruling N del plan H18b): la
   cascada de `app.css` no se mueve, solo se le agrega. */
@media (max-width: 640px) {
  /* Una pista `auto` se dimensiona por el min-content de su celda, y el de un ICC de 19 dígitos en
     `.mono` es la cadena ENTERA (no tiene dónde partirse): la pista no baja, la pista 1
     (`minmax(0, 1fr)`) se colapsa a 0 y su texto se sale encima de la vecina -- así se encimaban
     "Marca / Modelo" e "ICC" en /panel/equipos a 390 px. `anywhere` sí achica el min-content
     (`break-word` NO: por eso no sirve aquí). */
  .tabla td.mono, .tabla td .mono { overflow-wrap: anywhere; }
  /* Mismo colapso por otra vía: `.chip` es `nowrap` por diseño, así que su min-content es la frase
     completa ("No se descansa (ajuste)" encima de "Motivo" en Festivos a 390). Dentro de la tarjeta
     el chip envuelve; sigue siendo una sola pieza, nomás que en dos renglones. */
  .tabla td .chip { white-space: normal; }
  /* Los botones de la fila ya tenían renglón propio en `.tabla-densa` (vistas.css) pero no en
     `.tabla`: con 4 celdas peleando por 3 pistas, "Quitar" de Festivos quedaba medio fuera de la
     pantalla. Misma medicina que `td.detalle-celda`. */
  .tabla td.acciones-celda { grid-column: 1 / -1; margin-top: var(--s-2); }
}

/* ---------- Campana de notificaciones (T5, Tanda 1 de campanita, Diseño §1/§2/§6) ----------
   Regla NUEVA al final de la hoja (mismo criterio que el barrido H18 de arriba): botón solo-ícono
   con el SVG de la campana en `currentColor` (monocromo, `aria-hidden` en la plantilla) + el
   contador que `panel-avisos.mjs` crea/borra encima según haya o no avisos sin leer. El popover/
   hoja de `.dialogo-avisos` vive en `vistas.css`, NO aquí -- ver el comentario de esa regla: tiene
   que cargar DESPUÉS de `.dialogo` (H18, hoja 4 de 4) para ganarle el ancho/alto en la cascada. */
.btn-campana { position: relative; display: inline-flex; align-items: center; justify-content: center; flex: none; min-height: 44px; width: 44px; padding: 0; border-radius: var(--r-md); border: 1px solid transparent; background: transparent; color: var(--fg); cursor: pointer; }
.btn-campana:hover { background: var(--surface-2); }
.icono-campana { width: 22px; height: 22px; }
/* Encima del ícono, no al lado (Diseño §1: "Contador... chip naranja"). `min-height`/`padding`
   más chicos que el `.chip` genérico -- 26px de alto se salía del botón de 44px sin dejar aire. */
.contador-avisos { position: absolute; top: 2px; right: 2px; min-height: 18px; padding: 0 5px; font-size: var(--t-xs); line-height: 1.3; border-radius: var(--r-pill); }

/* H31 (D297): la cita todavía sin fecha ("Sin fecha" en el panel, "Por acordar" para el cliente) va en el lugar de
   la hora, como texto y no como reloj: sin la mono ni el tamaño de la hora grande. */
.sello .hora.sin-fecha { font-family: inherit; font-size: var(--t-lg); font-weight: 600; letter-spacing: 0; color: var(--muted-fg); }

/* ---------- "Mis avisos" (H31, pieza 3, regla 28): la rejilla categoría por canal de campo y proveedor ----------
   En escritorio y tableta, una tabla con las tres casillas al centro; a <= 640 px cada fila ya es tarjeta (`.tabla tr`)
   y sus tres casillas van en un renglón, cada una con su rótulo (`data-col`). La casilla vive en un `label` de 44 px:
   el área de toque no es solo el cuadrito. */
.tabla-avisos .titulo-aviso { font-weight: 600; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.tabla-avisos th:not(:first-child), .tabla-avisos td.casilla-aviso { text-align: center; width: 104px; }
.casilla-toque { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; cursor: pointer; }
.casilla-toque input { width: 24px; height: 24px; margin: 0; accent-color: var(--primary); cursor: pointer; }
.casilla-toque input:disabled { cursor: not-allowed; opacity: .55; }
@media (max-width: 640px) {
  .tabla-avisos tr { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tabla-avisos td.casilla-aviso { width: auto; text-align: left; }
  .tabla-avisos .casilla-toque { justify-content: flex-start; }
}


/* ---------- Píldoras con casilla (H32, D307): los días y las horas de la autoagenda en la ficha del cliente ----------
   La píldora marcada se ve como la activa de los filtros; la casilla nativa sigue adentro (sin JS, teclado y lector de
   pantalla igual que siempre). Solo dentro de `.pildoras-casillas`: los filtros "Mostrar inactivos" no cambian. */
.pildoras-casillas .pildora:has(input:checked) { background: var(--primary-bg); border-color: var(--primary); color: var(--primary); }
.pildoras-casillas .pildora input { width: 18px; height: 18px; margin: 0; accent-color: var(--primary); cursor: pointer; }

/* H32 (barrido, hallazgo 3): "Fecha y hora deseadas" del paso 3 del portal. El formulario del wizard no es rejilla y el
   `fieldset.pila` de la casa va sin margen: a 390 px su ayuda quedaba pegada a "Notas para Gestacore". */
fieldset.agenda-deseada { margin-bottom: var(--s-4); }

/* ---------- Tamaño de la página (2026-10-20): las tres A de la barra (`comunes/_tamano.html`) ----------
   Un control segmentado sobrio (revisión de interfaz): un borde fino exterior con el radio de la casa abarca las tres
   A, con separadores finos, para que se lean como botones y no como letras sueltas. Cada segmento mide 44 x 44. El
   tamaño actual (`aria-pressed`) va con el teal de estructura, como la píldora activa de los filtros, nunca con el
   naranja de acción; hover con `--surface-2` y un tono más al presionar. La etiqueta "Tamaño" está a la vista (cero
   tooltips). Cada «A» crece con su tamaño. Solo en escritorio (más de 1024 px) en las cinco carcasas, con esta única
   regla: en la tableta y el celular el tamaño está en Perfil, y abajo de 1025 px el grupo queda `display: none` (no
   enfocable). El foco es el global de 2 px. Los tokens se voltean solos en oscuro. */
.tamano { display: none; align-items: center; gap: var(--s-2); margin: 0; }
@media (min-width: 1025px) { .tamano { display: inline-flex; } }
.tamano-etiqueta { font-size: var(--t-xs); font-weight: 600; color: var(--muted-fg); }
.tamano-opciones { display: inline-flex; border: 1px solid var(--border-strong); border-radius: var(--r-md); background: var(--surface); }
.btn-tamano { display: inline-flex; align-items: center; justify-content: center; flex: none; min-height: 44px; width: 44px; padding: 0; border: 0; border-radius: 0; background: transparent; color: var(--fg); font: inherit; font-weight: 600; line-height: 1; cursor: pointer; }
.btn-tamano + .btn-tamano { border-left: 1px solid var(--border); }
.btn-tamano:first-child { border-radius: calc(var(--r-md) - 1px) 0 0 calc(var(--r-md) - 1px); }
.btn-tamano:last-child { border-radius: 0 calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0; }
.btn-tamano:hover { background: var(--surface-2); }
.btn-tamano:active { background: color-mix(in srgb, var(--fg) 12%, var(--surface-2)); }
.btn-tamano[aria-pressed="true"] { background: var(--primary-bg); color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.btn-tamano[aria-pressed="true"]:active { background: color-mix(in srgb, var(--primary) 18%, var(--primary-bg)); }
.btn-tamano-compacto { font-size: var(--t-xs); }
.btn-tamano-normal { font-size: var(--t-base); }
.btn-tamano-grande { font-size: var(--t-lg); }
/* Sin soporte (la sonda de `base.html` marcó `data-tamano-sin-soporte`: el navegador mide a la antigua con `zoom`), ni la
   barra ni la sección de Perfil se ven: el tamaño se queda en Normal. */
:root[data-tamano-sin-soporte] .tamano,
:root[data-tamano-sin-soporte] .perfil-tamano { display: none; }
/* Medido con las capturas del tamaño (2026-10-20): en Grande la página de un celular mide 339 px CSS (390 de ancho) o
   313 (360). En la tarjeta de visita (`campo/_tarjeta_visita.html` y la del proveedor) el chip "Continuación de la visita
   N" se salía 30 px de lado a 390, y "Gestacore te paga: $750.00" 15 px a 360. Ahí se parten en dos renglones antes que
   salirse; fuera de la tarjeta siguen en uno. */
.tarjeta-visita .chip { white-space: normal; }
.tarjeta-visita .pago-etiqueta { flex-wrap: wrap; }
/* Y en Perfil (el único lugar del tamaño en el celular), "Cerrar sesión en otros dispositivos" se salía 1 px a 360: un
   botón con `.btn-envuelve` parte su texto en dos renglones si no le cabe en uno. */
.btn-envuelve { white-space: normal; text-align: center; padding-block: var(--s-1); }
