:root {
  color-scheme: light;
  --task-bg: #f4f2fb;
  --task-surface: #ffffff;
  --task-surface-soft: #edeafa;
  --task-text: #203040;
  --task-muted: #637386;
  --task-border: #ddd8ef;
  --task-primary: #6c5dd3;
  --task-primary-strong: #4b3fae;
  --task-ink: #161b33;
  --task-ink-strong: #0e1226;
  --task-ink-text: #ffffff;
  --task-shadow: 0 10px 30px rgba(34, 55, 77, 0.08);
}

html[data-theme="dark"] {
  color-scheme: dark;
  --task-bg: #101820;
  --task-surface: #182531;
  --task-surface-soft: #223443;
  --task-text: #e7eef5;
  --task-muted: #aab8c5;
  --task-border: #344757;
  --task-primary: #a594ff;
  --task-primary-strong: #c7bbff;
  --task-ink: #0b0f1f;
  --task-ink-strong: #05070f;
  --task-ink-text: #ffffff;
  --task-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
}

/* Tamano de letra (boton "Aa" junto al de tema, ver layout.html): escala
   el tamano base en rem, asi que se propaga solo a todo lo que ya esta
   medido en rem en el resto de la hoja de estilos, sin tener que tocar
   cada regla--sep-26 */
html.task-fuente-grande { font-size: 112.5%; }
html.task-fuente-muy-grande { font-size: 125%; }

html,
body {
  min-height: 100%;
}

body {
  /* Mismo fondo de siempre (--task-bg/--task-surface-soft), solo que
     ahora se mueve muy lento entre esos dos tonos -no cambia la paleta,
     solo le da un poco de vida a una pantalla que se queda abierta
     todo el turno--ago-26 */
  background: linear-gradient(-45deg, var(--task-bg), var(--task-surface-soft), var(--task-bg)) !important;
  background-size: 400% 400% !important;
  animation: task-bg-flow 60s ease infinite;
  color: var(--task-text);
  font-family: "Inter", "Segoe UI", "Trebuchet MS", sans-serif;
  overflow-x: hidden;
  transition: background-color 160ms ease, color 160ms ease;
}

@keyframes task-bg-flow {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  body { animation: none; background-position: 0% 50% !important; }
}

a {
  color: var(--task-primary);
}

a:hover {
  color: var(--task-primary-strong);
}

.task-navbar {
  width: 100%;
  background: var(--task-surface) !important;
  border-bottom: 1px solid var(--task-border);
  box-shadow: 0 3px 16px rgba(22, 41, 58, 0.08);
  padding: 0.55rem 1rem;
}

.task-navbar .nav-link,
.task-navbar .navbar-brand {
  color: var(--task-text) !important;
}

.task-navbar .nav-link:hover,
.task-navbar .nav-link:focus {
  color: var(--task-primary) !important;
}

.task-sidebar {
  position: fixed;
  z-index: 1035;
  top: 0;
  bottom: 0;
  left: 0;
  display: flex;
  width: 270px;
  flex-direction: column;
  border-right: 1px solid var(--task-border);
  background: var(--task-surface);
  box-shadow: 8px 0 28px rgba(20, 36, 50, 0.08);
  transition: width 180ms ease;
}

.task-sidebar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 76px;
  padding: 1rem 1.1rem;
  border-bottom: 1px solid var(--task-border);
}

.task-clima-widget {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 1.1rem;
  border-bottom: 1px solid var(--task-border);
  background: var(--task-surface-soft);
  font-size: 0.85rem;
  color: var(--task-muted);
  white-space: nowrap;
}

.task-clima-hora {
  font-weight: 600;
  color: var(--task-text);
}

.task-clima-dato {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.task-clima-dato i {
  color: var(--task-primary);
}

.task-sidebar-close,
.task-sidebar-collapse,
.task-menu-toggle {
  display: none;
  min-width: 44px;
  min-height: 44px;
  border: 1px solid var(--task-border);
  border-radius: 8px;
  background: var(--task-surface-soft);
  color: var(--task-text);
}

.task-sidebar-collapse {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  margin-right: 0.35rem;
}

.task-sidebar-collapse:hover,
.task-sidebar-collapse:focus,
.task-sidebar-close:hover,
.task-sidebar-close:focus {
  background: var(--task-primary);
  color: #ffffff;
}

.task-logo-preview {
  margin-bottom: 1rem;
}

.task-logo-preview img {
  max-width: 220px;
  max-height: 120px;
  padding: 0.5rem;
  border: 1px solid var(--task-border);
  border-radius: 8px;
  background: var(--task-surface-soft);
}

.task-context-switch {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.65rem 0.85rem 0;
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  background: var(--task-surface-soft);
}

.task-context-switch label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  color: var(--task-primary);
  font-size: 0.85rem;
  font-weight: 700;
}

.task-context-switch select {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--task-text);
  font-size: 0.85rem;
  font-weight: 600;
}

.task-context-switch select:focus {
  outline: 2px solid var(--task-primary);
  outline-offset: 2px;
  border-radius: 6px;
}

html.task-sidebar-collapsed .task-context-switch {
  display: none;
}

/* Buscador global del sidebar (folio o palabra clave, ver
   busqueda_global()); mismo tratamiento visual que el selector de
   área--ago-26 */
.task-search-box {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.5rem 0.85rem 0;
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  background: var(--task-surface-soft);
}

.task-search-box i {
  color: var(--task-muted);
  font-size: 0.85rem;
}

.task-search-box input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--task-text);
  font-size: 0.85rem;
}

.task-search-box input:focus {
  outline: none;
}

html.task-sidebar-collapsed .task-search-box {
  display: none;
}

/* Aviso de solicitudes guardadas sin conexion, pendientes de enviarse
   (ver static/js/offline_alta.js) -mismo tratamiento visual que el
   buscador de arriba, en color de alerta--ago-26 */
.task-offline-badge {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.5rem 0.85rem 0;
  padding: 0.4rem 0.7rem;
  border-radius: 10px;
  background: rgba(230, 162, 60, 0.16);
  color: #c9822a;
  font-size: 0.8rem;
  line-height: 1.3;
}

html.task-sidebar-collapsed .task-offline-badge {
  display: none;
}

/* El scroll vertical vivia en .task-sidebar completo; por como funciona
   overflow en CSS, un overflow-y:auto sin un overflow-x explicito hace
   que el navegador tambien vuelva "auto" al eje horizontal (no se puede
   mezclar visible+auto en los dos ejes de un mismo elemento), y eso
   recortaba/mostraba con scroll horizontal cualquier menu flotante que
   se abriera dentro del sidebar (el de la cuenta -"Mi perfil/Cambiar
   contraseña/Fin de sesión"- y el de notificaciones), sobre todo con el
   sidebar colapsado a 78px. Se mueve el scroll solo a la lista de
   navegacion (que sigue creciendo con el numero de items) y se deja
   .task-sidebar con overflow visible, para que esos menus floten
   completos fuera del riel angosto en vez de recortarse--ago-26 */
.task-sidebar-nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0.85rem 0.7rem;
}

/* Selector de area dentro del formulario "Nueva solicitud", equivalente
   al del sidebar pero visible junto al formulario mismo--ago-26 */
.task-area-inline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.25rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--task-border);
}

.task-area-inline label {
  margin: 0;
  font-weight: 700;
  color: var(--task-text);
}

.task-area-inline select {
  min-width: 200px;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--task-border);
  border-radius: 8px;
  background: var(--task-surface);
  color: var(--task-text);
}

.task-sidebar-nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.task-sidebar-nav .nav-item {
  margin-bottom: 0.2rem;
}

.task-sidebar-nav .nav-link {
  display: block;
  min-height: 44px;
  padding: 0.7rem 0.85rem;
  border-radius: 8px;
  color: var(--task-text) !important;
  white-space: normal;
  transition: background-color 140ms ease, color 140ms ease;
}

.task-nav-icon {
  width: 1.25rem;
  margin-right: 0.55rem;
  text-align: center;
  color: var(--task-muted);
}

.nav-item.active > .nav-link .task-nav-icon,
.nav-link:hover .task-nav-icon,
.nav-link:focus .task-nav-icon {
  color: inherit;
}

.task-sidebar-nav .nav-link:hover,
.task-sidebar-nav .nav-link:focus,
.task-sidebar-nav .nav-item.active > .nav-link {
  background: var(--task-surface-soft);
  color: var(--task-primary) !important;
}

.task-sidebar-nav .dropdown-menu {
  position: static !important;
  float: none;
  display: none;
  margin: 0.2rem 0 0.45rem 0.6rem;
  padding: 0.35rem;
  border: 0;
  box-shadow: none;
  background: var(--task-surface-soft);
}

.task-sidebar-nav .dropdown-menu.show {
  display: block;
  animation: task-submenu-in 140ms ease-out both;
}

.task-sidebar-nav .dropdown-item {
  min-height: 44px;
  padding: 0.55rem 0.7rem;
  border-radius: 6px;
  white-space: normal;
}

@keyframes task-submenu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

.task-sidebar-tools {
  padding: 0.75rem;
  border-top: 1px solid var(--task-border);
}

.task-tools-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  margin-bottom: 0.6rem;
}

.task-tool-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  color: var(--task-text) !important;
  background: var(--task-surface-soft);
  border: 1px solid var(--task-border);
  text-decoration: none;
  flex-shrink: 0;
}

.task-tool-btn:hover,
.task-tool-btn:focus {
  background: var(--task-primary);
  color: #ffffff !important;
  border-color: var(--task-primary);
}

.task-account-row {
  margin-bottom: 0.5rem;
}

.task-account-toggle {
  display: flex !important;
  align-items: center;
  gap: 0.55rem;
  text-align: left;
  min-height: 44px;
  padding: 0.4rem 0.6rem;
  border-radius: 10px;
  border: 1px solid var(--task-border);
  background: var(--task-surface-soft);
  color: var(--task-text) !important;
}

.task-account-toggle:hover,
.task-account-toggle:focus {
  border-color: var(--task-primary);
}

.task-account-caret {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--task-muted);
  font-size: 0.8rem;
}

.task-account-avatar {
  width: 32px;
  height: 32px;
  min-width: 32px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.task-account-avatar-initials {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--task-primary);
  color: #ffffff;
  font-weight: 700;
  font-size: 0.85rem;
}

.task-account-info {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  min-width: 0;
}

.task-account-name {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.task-account-sub {
  font-size: 0.75rem;
  color: var(--task-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.task-page {
  min-height: 100vh;
  margin-left: 270px;
  transition: margin-left 180ms ease;
}

/* Sin sesión iniciada no se renderiza el sidebar/aside (ver layout.html),
   asi que la pagina no debe reservarle espacio en ningun breakpoint. */
.task-page.task-no-sidebar {
  margin-left: 0 !important;
}

html.task-sidebar-collapsed .task-sidebar {
  width: 78px;
}

html.task-sidebar-collapsed .task-page {
  margin-left: 78px;
}

html.task-sidebar-collapsed .task-sidebar-head {
  justify-content: center;
  padding-right: 0.55rem;
  padding-left: 0.55rem;
}

html.task-sidebar-collapsed .task-sidebar .task-brand {
  width: 0;
  opacity: 0;
  overflow: hidden;
}

html.task-sidebar-collapsed .task-sidebar-collapse {
  margin: 0;
}

html.task-sidebar-collapsed .task-clima-widget {
  display: none;
}

html.task-sidebar-collapsed .task-sidebar-nav .nav-link {
  overflow: hidden;
  padding-right: 0;
  padding-left: 0;
  text-align: center;
  white-space: nowrap;
}

/* Los renglones del menu principal ya traen icono (ver menu.py): en vez de
   sacar el texto de la pantalla con text-indent -que tambien se llevaba el
   icono, dejando el menu colapsado sin nada que mostrar-, solo se oculta la
   etiqueta de texto y el icono se queda centrado--ago-26 */
html.task-sidebar-collapsed .task-sidebar-nav .task-nav-label {
  display: none;
}

html.task-sidebar-collapsed .task-sidebar-nav .task-nav-icon {
  margin: 0;
  font-size: 1.05rem;
}

/* La barra inferior (campana/sonido/tema, cuenta, "Instalar app") ya es
   icono-solo por si misma -a diferencia del menu principal, no necesita
   el truco de text-indent-: en colapsado nomas se apila vertical en vez
   de en fila (no cabe una fila de 3 botones en 78px de ancho) y se
   oculta el nombre/subtitulo de la cuenta--ago-26 */
html.task-sidebar-collapsed .task-tools-row {
  flex-direction: column;
}

html.task-sidebar-collapsed .task-account-toggle {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}

html.task-sidebar-collapsed .task-account-info,
html.task-sidebar-collapsed .task-account-caret {
  display: none;
}

html.task-sidebar-collapsed .task-sidebar-nav .dropdown-toggle::after {
  display: none;
}

html.task-sidebar-collapsed .task-sidebar-nav .dropdown-menu {
  display: none !important;
}

html.task-sidebar-collapsed .task-install-btn {
  display: none !important;
}

/* El fondo oscuro del footer (.footer, ver mas abajo) debe cubrir
   siempre el ancho completo de .task-page (ya sea con sidebar fijo de
   270px o sin sesion iniciada) para no dejar ver el fondo/degradado del
   body a los lados. Antes decia width:auto -que en la practica lo
   angostaba al contenido centrado del footer en vez de estirarlo- y
   solo se corregia en el breakpoint movil; se quita el override para
   que el ancho completo (heredado de la regla base .footer) aplique
   siempre, sin importar el tamaño de pantalla--ago-26 */
.task-page .footer {
  width: 100%;
}

.task-sidebar-overlay {
  display: none;
}

.task-navbar .navbar-collapse {
  align-items: center;
}

.task-navbar .navbar-toggler {
  border-color: var(--task-border);
  background: var(--task-surface-soft);
}

.task-navbar .navbar-toggler-icon {
  filter: var(--task-toggler-filter, none);
}

.task-brand {
  width: clamp(84px, 12vw, 132px);
  height: auto;
  object-fit: contain;
}

.task-install-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
  margin-top: 0.5rem;
  padding: 0 0.85rem;
  width: 100%;
  border: 1px solid var(--task-primary);
  border-radius: 8px;
  background: var(--task-surface-soft);
  color: var(--task-primary);
  font-weight: 600;
  justify-content: center;
}

.task-install-btn:hover,
.task-install-btn:focus {
  background: var(--task-primary);
  color: #ffffff;
}

.task-install-btn[hidden] {
  display: none;
}

.dropdown-menu {
  background: var(--task-surface);
  border-color: var(--task-border);
  box-shadow: var(--task-shadow);
}

.dropdown-item {
  color: var(--task-text);
}

.dropdown-item:hover,
.dropdown-item:focus {
  background: var(--task-surface-soft);
  color: var(--task-primary-strong);
}

/* 1600px se sentia generoso cuando se escribio, pero en un monitor
   normal de 1920px (o mas ancho) con el sidebar ya descontado (ver
   margin-left en .task-page/.task-page-collapsed) sigue dejando franjas
   vacias a los lados en vez de darle ese espacio a las tablas/grids -que
   es justo lo que mas se beneficia de ancho extra. Se sube el techo
   bastante mas alto (las paginas de texto/formularios angostos ya traen
   su propio max-width, ver .task-welcome h1 etc., asi que no se ven
   afectadas) para que el contenido realmente aproveche pantallas
   grandes, y con el sidebar colapsado (78px en vez de 270px) haya aun
   mas espacio disponible antes de topar con este limite--ago-26 */
.main-container {
  width: 100%;
  max-width: 2200px;
  box-sizing: border-box;
  margin: 0 auto;
  padding: 1.25rem clamp(0.75rem, 2vw, 2rem) 3rem;
}

.task-welcome {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(250px, 0.85fr);
  align-items: center;
  gap: clamp(1.5rem, 5vw, 5rem);
  min-height: min(560px, calc(100vh - 190px));
  padding: clamp(1.5rem, 5vw, 5rem);
  border: 1px solid var(--task-border);
  border-radius: 18px;
  background: var(--task-surface);
  box-shadow: var(--task-shadow);
}

.task-eyebrow {
  margin: 0 0 0.8rem;
  color: var(--task-primary);
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.task-welcome h1 {
  max-width: 680px;
  margin: 0;
  color: var(--task-text);
  font-size: clamp(2.2rem, 5vw, 4.8rem);
  line-height: 1.04;
}

.task-welcome-lead {
  max-width: 560px;
  margin: 1.25rem 0 1.8rem;
  color: var(--task-muted);
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  line-height: 1.6;
}

.task-welcome-action {
  padding: 0.7rem 1.1rem;
}

.task-welcome-action .fa {
  margin-right: 0.45rem;
}

.task-welcome-panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.8rem;
  min-height: 260px;
  padding: clamp(1.25rem, 4vw, 2.5rem);
  border-left: 5px solid var(--task-primary);
  border-radius: 12px;
  background: var(--task-surface-soft);
}

.task-welcome-panel-line {
  display: block;
  width: 86%;
  height: 14px;
  border-radius: 99px;
  background: var(--task-primary);
  opacity: 0.72;
}

.task-welcome-panel-line:nth-child(2) {
  width: 68%;
  opacity: 0.4;
}

.task-welcome-panel-line.short {
  width: 48%;
  opacity: 0.22;
}

.task-welcome-panel-status {
  margin-top: 1.5rem;
  color: var(--task-text);
  font-weight: 700;
}

.task-welcome-panel-status .fa {
  margin-right: 0.45rem;
  color: var(--task-primary);
}

.catalog-page-header {
  margin-bottom: 1.25rem;
}

.catalog-page-header h1 {
  margin: 0;
  color: var(--task-text);
  font-size: clamp(1.8rem, 4vw, 3rem);
}

.task-page-title-icon {
  color: var(--task-primary);
  font-size: 0.85em;
  margin-right: 0.15em;
}

.catalog-page-header p:last-child {
  color: var(--task-muted);
}

.catalog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
}

.catalog-card {
  min-width: 0;
  padding: 1rem;
  border: 1px solid var(--task-border);
  border-radius: 12px;
  background: var(--task-surface);
  box-shadow: var(--task-shadow);
  transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease;
}

.catalog-card:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--task-primary) 35%, var(--task-border));
  box-shadow: 0 14px 34px rgba(34, 55, 77, 0.14);
}

/* Rejilla propia de "Gráficas de tareas por estatus": 2 tarjetas por
   fila en vez de las 4 que le tocarian con la rejilla generica
   (.catalog-grid, compartida con catalogos/formularios) -cada grafica
   necesita mas ancho para que las barras/rebanadas y su leyenda se
   lean bien, no menos--ago-26 */
.chart-grid {
  display: grid;
  /* min(480px,100%) en vez de 480px a secas: en una pantalla angosta
     (celular) 480px es mas ancho que el propio contenedor, y una pista
     de grid no se encoge por debajo de su minimo -eso empujaba la
     pagina entera a un scroll horizontal en vez de apilar en una sola
     columna--ago-26 */
  grid-template-columns: repeat(auto-fit, minmax(min(480px, 100%), 1fr));
  gap: 1rem;
}

.chart-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  border-left: 4px solid var(--task-primary);
  padding-left: 0.65rem;
}

.chart-card-head h2 {
  margin: 0;
}

.chart-card-total {
  flex-shrink: 0;
  color: var(--task-muted);
  font-size: 0.9rem;
  font-weight: 600;
}

.chart-card-habitacion .chart-card-head { border-left-color: #38bdf8; }
.chart-card-proyecto .chart-card-head { border-left-color: #dd9654; }

/* Chart.js necesita un contenedor con alto fijo -con
   maintainAspectRatio:false y responsive:true el canvas llena este
   div y se reajusta solo si la ventana cambia de tamaño--ago-26 */
.chart-canvas-wrap {
  position: relative;
  height: 280px;
  margin-top: 0.5rem;
}

/* Bootstrap trae .modal-content en blanco fijo (#fff) sin importar el
   tema -primer modal de la app (ver graf02.html), asi que no habia
   ningun override previo para modo oscuro--ago-26 */
.modal-content {
  background: var(--task-surface);
  color: var(--task-text);
  border-color: var(--task-border);
}

.modal-header {
  border-bottom-color: var(--task-border);
}

.modal-header .close {
  color: var(--task-text);
  text-shadow: none;
  opacity: .6;
}

.modal-header .close:hover {
  opacity: 1;
}

/* El fragmento que trae el modal por AJAX es el mismo grid de
   SQLFORM.grid (buscador+tabla+paginacion) que ya se ve en las
   pantallas completas -aca solo se recorta el margen exterior para que
   no se vea con doble espaciado dentro del modal--ago-26 */
#chartDrillModalCuerpo .web2py_grid {
  margin: 0;
}

.catalog-card h2 {
  margin-top: 0;
  color: var(--task-text);
  font-size: 1.15rem;
}

.catalog-card-hint {
  margin-top: -0.5rem;
  margin-bottom: 1rem;
  color: var(--task-muted);
  font-size: 0.85rem;
  line-height: 1.4;
}

.catalog-card table {
  width: 100%;
  background: transparent;
  box-shadow: none;
}

.catalog-card .form-control,
.catalog-card select,
.catalog-card input:not([type="checkbox"]):not([type="radio"]) {
  width: 100%;
  max-width: 100%;
}

/* El formstyle bootstrap4_inline de web2py todavía genera la clase
   "col-sm-offset-3" (Bootstrap 3) para centrar el botón de enviar, pero
   Bootstrap 4 la renombró a "offset-sm-3" y nunca la aplica; el botón
   queda pegado a la izquierda en vez de alineado bajo los campos. */
#submit_record__row {
  justify-content: center;
}
#submit_record__row > div {
  display: flex;
  justify-content: center;
}
#submit_record__row input[type="submit"] {
  min-width: 220px;
}
@media (min-width: 576px) {
  #submit_record__row > div {
    margin-left: 25%;
  }
}

/* ------------------------------------------------------------------
   SQLFORM.grid: barra de filtro/búsqueda redondeada + encabezado de
   tabla en tinta oscura, mismo esquema visual en toda la app. Solo
   toca apariencia; el grid de web2py sigue funcionando igual.
   ------------------------------------------------------------------ */
.web2py_grid {
  padding: 0;
  border: none;
  background: transparent;
}

.web2py_console {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1rem;
}

.web2py_console form {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0;
  flex: 1 1 260px;
  max-width: 480px;
}

.web2py_console form input[name="keywords"] {
  flex: 1 1 auto;
  width: auto !important;
  min-width: 0;
  min-height: 44px;
  margin: 0;
  border: 1px solid var(--task-border);
  border-radius: 999px 0 0 999px;
  border-right: none;
  background: var(--task-surface);
  color: var(--task-text);
  padding: 0 1rem;
}

.web2py_console form input[name="keywords"]:focus {
  outline: none;
  border-color: var(--task-primary);
}

.web2py_console form input[type="submit"] {
  flex: 0 0 auto;
  width: auto !important;
  min-height: 44px;
  margin: 0;
  border: 1px solid var(--task-ink);
  border-radius: 0;
  background: var(--task-ink) !important;
  color: var(--task-ink-text) !important;
  font-weight: 600;
  padding: 0 1rem;
}

.web2py_console form input[type="submit"] ~ input[type="submit"] {
  border-radius: 0 999px 999px 0;
}

.web2py_console form input[type="submit"]:hover,
.web2py_console form input[type="submit"]:focus {
  background: var(--task-ink-strong) !important;
  border-color: var(--task-ink-strong) !important;
}

.web2py_grid .button.btn-secondary,
.web2py_console a.button.btn-secondary {
  min-height: 40px;
  padding: 0.35rem 0.9rem;
  border: none;
  border-radius: 999px;
  background: var(--task-ink) !important;
  color: var(--task-ink-text) !important;
  font-weight: 600;
  text-decoration: none;
}

.web2py_grid .button.btn-secondary:hover,
.web2py_console a.button.btn-secondary:hover {
  background: var(--task-ink-strong) !important;
  color: #ffffff !important;
}

[id$="_query_panel"] {
  width: 100%;
  margin-top: 0.5rem;
  padding: 1rem;
  border: 1px solid var(--task-border);
  border-radius: 12px;
  background: var(--task-surface);
  box-shadow: var(--task-shadow);
}

[id$="_query_panel"] .w2p_query_row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.web2py_htmltable {
  border: 1px solid var(--task-border);
  border-radius: 12px;
  background: var(--task-surface);
  box-shadow: var(--task-shadow);
}

.web2py_htmltable table {
  /* min-width, no width: la tabla debe poder crecer mas alla del 100%
     cuando el contenido lo pide (muchas columnas, textos largos) para
     que el overflow-x:auto que web2py ya pone en el div contenedor
     pueda mostrar una barra de scroll horizontal -con width:100% la
     tabla nunca podia ser mas ancha que su contenedor, y en vez de
     scroll el navegador simplemente aplastaba las columnas--ago-26 */
  min-width: 100%;
  margin: 0;
  border-collapse: collapse;
  background: transparent;
}

.web2py_htmltable thead tr {
  background: var(--task-ink);
}

/* web2py-bootstrap4.css tambien fija #EAEAEA en .web2py_grid thead th con
   la misma especificidad; se refuerza aqui con el color del tema. */
.web2py_htmltable thead th {
  padding: 0.75rem 0.9rem;
  background-color: var(--task-ink) !important;
  color: var(--task-ink-text);
  font-weight: 700;
  text-align: left;
  border: none;
  white-space: nowrap;
}

.web2py_htmltable thead th a {
  color: var(--task-ink-text);
}

.web2py_htmltable tbody td {
  padding: 0.65rem 0.9rem;
  border-top: 1px solid var(--task-border);
  color: var(--task-text);
  vertical-align: middle;
  transition: background-color 120ms ease;
}

/* Modo compacto (boton junto al de tema, ver layout.html): reduce el
   padding de las tablas para ver mas filas de un vistazo, sin cambiar
   nada mas del diseño--sep-26 */
html.task-densidad-compacta .web2py_htmltable thead th,
html.task-densidad-compacta .web2py_htmltable tbody td{
  padding: 0.35rem 0.6rem;
}

/* web2py-bootstrap4.css fija fondos claros (#F9F9F9/#F5F5F5) para las filas
   "odd"/hover que quedan casi invisibles con texto claro en tema oscuro;
   se reemplazan por los tokens de tema para que respeten claro/oscuro. */
.web2py_grid tr.odd,
.web2py_grid tr.even {
  background-color: transparent !important;
}

.web2py_grid tr:hover {
  background-color: var(--task-surface-soft) !important;
}

.web2py_paginator {
  margin-top: 0.75rem;
  background-color: transparent !important;
  padding: 0 !important;
  text-align: left !important;
}

.web2py_paginator ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.web2py_paginator li a,
.web2py_paginator li span {
  display: inline-flex;
  align-items: center;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
  justify-content: center;
  min-width: 36px;
  min-height: 36px;
  padding: 0 0.6rem;
  border: 1px solid var(--task-border);
  border-radius: 999px;
  color: var(--task-text);
  text-decoration: none;
}

.web2py_paginator li a:hover {
  border-color: var(--task-primary);
  color: var(--task-primary);
}

.web2py_paginator li.disabled span {
  color: var(--task-muted);
}

.web2py_paginator li.current a {
  border-color: var(--task-primary);
  background: var(--task-primary);
  color: #ffffff;
}

.w2p_export_menu {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  color: var(--task-muted);
}

.main-container > .row,
.main-container .table,
.main-container .form-control,
.main-container .custom-select,
.main-container .select2-container {
  color: var(--task-text);
}

.main-container .table-responsive,
.main-container table {
  background: var(--task-surface);
  border-color: var(--task-border);
}

.main-container .table {
  box-shadow: var(--task-shadow);
}

.main-container th {
  background: var(--task-surface-soft);
  color: var(--task-text);
  border-color: var(--task-border);
}

.main-container td {
  border-color: var(--task-border);
}

.auth-panel {
  position: relative;
  max-width: 680px;
  margin: 1rem auto 2rem;
  padding: clamp(1.25rem, 3vw, 2rem);
  border: 1px solid var(--task-border);
  border-radius: 14px;
  background: var(--task-surface);
  box-shadow: var(--task-shadow);
  animation: task-login-in 420ms cubic-bezier(0.2, 0.75, 0.25, 1) both;
}

/* Fondo interactivo de la pantalla de login: unas manchas de color
   difuminadas que flotan solas y ademas reaccionan al mouse (ver el
   script en user.html). El panel se vuelve semitransparente con blur
   para que el fondo se note detras sin restar legibilidad al formulario. */
.auth-panel-glass {
  background: color-mix(in srgb, var(--task-surface) 86%, transparent);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.auth-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.auth-bg-blob {
  position: absolute;
  width: 46vmax;
  height: 46vmax;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.5;
  will-change: transform;
  animation: auth-bg-drift 22s ease-in-out infinite alternate;
}

.auth-bg-blob-1 {
  top: -18vmax;
  left: -14vmax;
  background: radial-gradient(circle, var(--task-primary), transparent 70%);
  animation-duration: 20s;
}

.auth-bg-blob-2 {
  bottom: -20vmax;
  right: -12vmax;
  background: radial-gradient(circle, #f5b6c9, transparent 70%);
  animation-duration: 26s;
  animation-delay: -6s;
}

.auth-bg-blob-3 {
  top: 30%;
  right: 8vmax;
  width: 30vmax;
  height: 30vmax;
  background: radial-gradient(circle, #38bdf8, transparent 70%);
  animation-duration: 18s;
  animation-delay: -10s;
}

@keyframes auth-bg-drift {
  from { transform: translate(0, 0) scale(1); }
  to { transform: translate(4vmax, 3vmax) scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  .auth-bg-blob {
    animation: none !important;
  }
}

@keyframes task-login-in {
  from { opacity: 0; transform: translateY(18px) scale(0.985); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.auth-panel h2,
.auth-panel label,
.auth-panel .w2p_fl,
.auth-panel .w2p_fc {
  color: var(--task-text);
}

.auth-panel h2 {
  margin-top: 0;
  font-size: clamp(1.65rem, 3vw, 2.25rem);
  animation: task-login-content-in 420ms 80ms ease-out both;
}

.auth-panel table {
  width: 100%;
  background: transparent;
  box-shadow: none;
}

.auth-panel .w2p_fl {
  width: 32%;
}

.auth-panel .form-control,
.auth-panel input[type="text"],
.auth-panel input[type="password"],
.auth-panel input[type="email"] {
  width: 100%;
  color: var(--task-text);
}

.auth-panel table {
  animation: task-login-content-in 420ms 150ms ease-out both;
}

.auth-panel .btn {
  animation: task-login-content-in 420ms 220ms ease-out both;
}

@keyframes task-login-content-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

.auth-panel .form-check-label,
.auth-panel .w2p_fw label {
  color: var(--task-muted);
}

/* Bootstrap4's absolutely-positioned .form-check-input assumes a
   single-line label; with a long/wrapping label (e.g. "sin_evidencia")
   the checkbox lands mid-text instead of before it. A flex row fixes
   that on wide screens, but the label text is an unwrapped anonymous
   flex item that overflows the viewport on narrow ones instead of
   wrapping. Float the checkbox instead: normal text flow wraps around
   it correctly at any width, same as a list marker. */
.form-check-label {
  display: block;
  padding-left: 0;
  overflow: hidden;
  white-space: normal;
}

.form-check-input {
  position: static;
  float: left;
  margin: 0.2rem 0.5rem 0 0;
}

.auth-panel a {
  display: inline-block;
  margin: 0.35rem 0.8rem 0.35rem 0;
}

.form-control,
.custom-select,
select,
textarea,
input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"],
input[type="date"],
input[type="datetime-local"] {
  min-height: 44px;
  background: var(--task-surface);
  border: 1px solid var(--task-border);
  border-radius: 8px;
  color: var(--task-text);
}

.form-control:focus,
.custom-select:focus,
select:focus,
textarea:focus {
  border-color: var(--task-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--task-primary) 22%, transparent);
  background: var(--task-surface);
  color: var(--task-text);
}

/* web2py-bootstrap4.css trae "label, th{white-space:nowrap}" para toda
   la app. Con las etiquetas cortas de siempre no se notaba, pero
   etiquetas mas largas ("Foto de evidencia (opcional)", "Contenido de
   la tarea") no caben en la columna col-sm-3 en anchos intermedios
   (ej. la franja de tablet 768-1024px, donde el sidebar fijo deja
   todavia menos ancho util) y el texto se desborda por encima del
   campo/boton de al lado en vez de partirse en dos lineas. Como
   .form-control-label tiene mas especificidad que el "label" suelto de
   arriba, esto solo revierte el nowrap ahi, sin tocar el de las
   cabeceras de tabla (th)--ago-26 */
.form-control-label {
  white-space: normal;
}

.btn {
  min-height: 44px;
  border-radius: 8px;
  font-weight: 600;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease, transform 140ms ease, box-shadow 140ms ease;
}

.btn:active {
  transform: translateY(1px);
}

/* Alinea los colores propios de Bootstrap (btn-primary, badges, texto/
   fondo/borde "primary") con la paleta de la marca en lugar del azul
   por defecto de Bootstrap, para que toda la interfaz sea consistente. */
.btn-primary {
  background-color: var(--task-primary) !important;
  border-color: var(--task-primary) !important;
  color: #ffffff !important;
}

.btn-primary:hover,
.btn-primary:focus {
  background-color: var(--task-primary-strong) !important;
  border-color: var(--task-primary-strong) !important;
}

.btn-primary:focus,
.btn-primary.focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--task-primary) 35%, transparent) !important;
}

.text-primary { color: var(--task-primary) !important; }
.bg-primary { background-color: var(--task-primary) !important; }
.border-primary { border-color: var(--task-primary) !important; }
.badge-primary {
  background-color: var(--task-primary) !important;
  color: #ffffff !important;
}

.border-tptask,
.cuadro-redondeado,
.form-tsk1,
.form-stl-1 {
  background: var(--task-surface) !important;
  border-color: var(--task-border) !important;
  color: var(--task-text);
  box-shadow: var(--task-shadow);
}

.footer {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  background: var(--task-bg);
  border-top: 1px solid var(--task-border) !important;
  color: var(--task-muted);
  padding: 1rem clamp(0.75rem, 2vw, 2rem);
  overflow-x: hidden;
}

.footer a {
  color: var(--task-primary);
}

/* flex-wrap solo mueve un item completo a la siguiente linea si NO cabe
   entero; si un solo item (p.ej. "Ultimo respaldo: dd/mm/aaaa hh:mm") es
   mas ancho que la pantalla, con white-space:nowrap no tenia forma de
   acomodarse y el texto se cortaba en el borde en vez de envolverse. Sin
   nowrap el texto puede partirse dentro del propio item como ultimo
   recurso, asi nunca se sale del ancho de pantalla sin importar el
   dispositivo--ago-26 */
.task-app-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.4rem 1.5rem;
  font-size: 0.85rem;
  text-align: center;
  width: 100%;
  max-width: 100%;
}

.task-app-footer-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 100%;
}

.task-app-footer-item i {
  color: var(--task-primary);
}

/* web2py-bootstrap4.css trae div.w2p_flash.alert con colores fijos
   (amarillo #f9edbe, sin relacion con el tema) y una posicion (top:70px;
   right:75px) que en pantallas angostas, combinada con el max-width de
   abajo, hace que se salga por la izquierda y se vea como una tarjeta a
   mitad de pantalla en vez de un aviso lateral. Se sobreescribe todo aca:
   colores del tema, y una posicion fija que si funciona en movil--ago-26 */
div.w2p_flash.alert {
  background-color: var(--task-surface);
  border-color: var(--task-border);
  border-left: 4px solid var(--task-primary);
  color: var(--task-text);
  box-shadow: var(--task-shadow);
  top: calc(1rem + env(safe-area-inset-top, 0px));
  right: calc(1rem + env(safe-area-inset-right, 0px));
  left: auto;
  /* web2py-bootstrap4.css tambien trae "div.w2p_flash { max-width:300px }"
     mas arriba en el mismo archivo -selector mas especifico que el
     ".w2p_flash" de abajo, asi que gana pase lo que pase con el orden de
     los <link>- se repite aca para asegurar el ancho que sí queremos--ago-26 */
  max-width: min(85vw, 340px);
}

div.w2p_flash #closeflash {
  color: var(--task-muted);
  float: right;
  margin-left: 15px;
  cursor: pointer;
}

.w2p_flash {
  /* el pequeno delay evita que el deslizamiento se pierda entre el resto
     del repintado de la pagina justo despues de cargar/redirigir--ago-26 */
  animation: task-flash-in 320ms 150ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.w2p_flash.task-flash-closing {
  animation: task-flash-out 260ms cubic-bezier(0.4, 0, 1, 1) both;
}

@keyframes task-flash-in {
  from { opacity: 0; transform: translateX(32px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes task-flash-out {
  from { opacity: 1; transform: translateX(0); }
  to { opacity: 0; transform: translateX(32px); }
}

.task-action-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.task-tour-overlay{
  position: fixed;
  inset: 0;
  background: rgba(10, 14, 26, 0.6);
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.task-tour-card{
  max-width: 380px;
  width: 100%;
  background: var(--task-surface);
  border-radius: 14px;
  box-shadow: var(--task-shadow);
  padding: 1.75rem 1.5rem 1.25rem;
  text-align: center;
}
.task-tour-icono{
  font-size: 2.2rem;
  color: var(--task-primary);
  margin-bottom: 0.75rem;
  display: block;
}
.task-tour-card h3{
  margin: 0 0 0.5rem;
  color: var(--task-text);
}
.task-tour-card p{
  color: var(--task-muted);
  margin-bottom: 1rem;
}
.task-tour-puntos{
  display: flex;
  justify-content: center;
  gap: 0.35rem;
  margin-bottom: 1.1rem;
}
.task-tour-puntos span{
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--task-border);
  display: inline-block;
}
.task-tour-puntos span.task-tour-punto-activo{
  background: var(--task-primary);
}
.task-tour-botones{
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
}

.task-checklist-pasos{
  margin-top: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.task-checklist-item{
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 400;
  margin: 0;
}
.task-checklist-resumen{
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.85rem;
}

.task-qr-video {
  width: 100%;
  max-width: 420px;
  border-radius: 8px;
  border: 1px solid var(--task-border);
  background: #000;
  display: block;
}

.task-firma-lienzo {
  display: block;
  width: 100%;
  max-width: 500px;
  height: 180px;
  border: 1px dashed var(--task-border);
  border-radius: 8px;
  background: #fff;
  cursor: crosshair;
  touch-action: none;
}

/* Folio como link principal hacia el detalle completo del ticket, en las
   tablas que se simplificaron a solo columnas esenciales (Panel de
   tareas, Reportes cerrados, Proyectos, Mantenimiento)--sep-26 */
.task-folio-link {
  font-weight: 700;
  color: var(--task-primary);
  text-decoration: none;
}
.task-folio-link:hover {
  text-decoration: underline;
}

/* Aviso de filtro activo (?estatus=... llegado de un clic en una
   rebanada/barra de "Gráficas de tareas por estatus")--ago-26 */
.task-filtro-activo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--task-border);
  border-radius: 10px;
  background: var(--task-surface-soft);
  color: var(--task-text);
  font-size: 0.9rem;
}

.task-filtro-activo i {
  color: var(--task-primary);
}

.task-filtro-quitar {
  margin-left: auto;
  color: var(--task-muted);
  text-decoration: none;
}

.task-filtro-quitar:hover {
  color: var(--task-primary-strong);
}

/* Casilla de "Acciones en lote" dentro del grid (ver lnkbulk en
   form_task1()) y la barra flotante que aparece cuando hay al menos
   una marcada--ago-26 */
.task-bulk-check {
  width: 1.15rem;
  height: 1.15rem;
  cursor: pointer;
}

.task-bulk-bar {
  position: sticky;
  bottom: 1rem;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.65rem;
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--task-border);
  border-radius: 12px;
  background: var(--task-surface);
  box-shadow: var(--task-shadow);
}

.task-bulk-bar #taskBulkContador {
  font-weight: 700;
  color: var(--task-text);
}

.task-bulk-bar select {
  max-width: 220px;
}

/* Aviso tras aplicar (o deshacer) una acción en lote, con el botón
   "Deshacer" -ver form_task1.html--ago-26 */
.task-bulk-aviso {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.65rem;
  margin-top: 1rem;
  padding: 0.65rem 1rem;
  border: 1px solid var(--task-border);
  border-radius: 12px;
  background: var(--task-surface-soft);
  color: var(--task-text);
}

/* .column is a legacy two-column layout used by a few pages (e.g. actualiza_task.html);
   keep it side-by-side on desktop but stack it on narrow screens. */
.column {
  box-sizing: border-box;
}

@media (max-width: 767.98px) {
  .web2py_console form {
    max-width: 100%;
  }

  .web2py_console form input[name="keywords"] {
    flex: 1 1 100%;
    border-radius: 999px;
    border-right: 1px solid var(--task-border);
    margin-bottom: 0.4rem;
  }

  .web2py_console form input[type="submit"] {
    flex: 1 1 0;
    border-radius: 999px !important;
    margin-right: 0.4rem;
  }

  .task-sidebar {
    width: min(84vw, 320px);
    transform: translateX(-105%);
    transition: transform 180ms ease;
  }

  /* En movil el sidebar siempre es un cajon deslizante del mismo ancho,
     colapsado o no: .task-page ya recibe margin-left:0 mas abajo, sin
     necesidad de heredar el width:min(84vw,320px) del sidebar (que antes
     dejaba el contenido principal encogido si el usuario colapsaba el
     menu en escritorio y luego reducia la ventana sin recargar). */
  html.task-sidebar-collapsed .task-sidebar {
    width: min(84vw, 320px);
  }

  .task-sidebar-collapse {
    display: none;
  }

  html.task-menu-open .task-sidebar {
    transform: translateX(0);
  }

  .task-sidebar-close,
  .task-menu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .task-menu-toggle {
    position: fixed;
    z-index: 1030;
    top: calc(0.75rem + env(safe-area-inset-top, 0px));
    left: calc(0.75rem + env(safe-area-inset-left, 0px));
    box-shadow: var(--task-shadow);
  }

  .task-sidebar-overlay {
    position: fixed;
    z-index: 1034;
    inset: 0;
    background: rgba(7, 15, 23, 0.52);
  }

  .task-sidebar {
    padding-left: env(safe-area-inset-left, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  html.task-menu-open .task-sidebar-overlay {
    display: block;
  }

  .task-page {
    margin-left: 0;
  }

  .task-navbar {
    display: none;
    padding: 0.5rem 0.75rem;
  }

  .task-navbar .navbar-collapse {
    padding-top: 0.5rem;
  }

  .task-navbar .navbar-collapse.collapse:not(.show) {
    display: none !important;
  }

  .task-navbar .navbar-collapse.show {
    display: block !important;
  }

  .task-navbar .nav-item,
  .task-navbar .nav-link {
    white-space: normal;
  }

  .task-navbar .form-inline {
    display: none;
  }

  .main-container {
    min-width: 0;
    padding: 0.75rem 0.6rem 2rem;
    /* Deja espacio para que el boton fijo de hamburguesa (44px, con su
       propio offset de 0.75rem) no se sobreponga al titulo de la
       pagina--ago-26 */
    padding-top: calc(44px + 1.5rem + env(safe-area-inset-top, 0px));
  }

  .main-container .row {
    margin-right: 0;
    margin-left: 0;
  }

  .main-container .form-control,
  .main-container select,
  .main-container textarea,
  .main-container input {
    max-width: 100%;
  }

  .auth-panel {
    margin: 0.5rem 0 1.5rem;
  }

  .auth-panel .w2p_fl,
  .auth-panel .w2p_fw {
    display: block;
    width: 100%;
  }

  .task-welcome {
    display: block;
    min-height: auto;
    padding: 1.5rem 1.15rem 1.25rem;
    border-radius: 14px;
  }

  .task-welcome h1 {
    font-size: 2.35rem;
  }

  .task-welcome-lead {
    margin: 1rem 0 1.35rem;
    font-size: 1rem;
  }

  .task-welcome-action {
    width: 100%;
  }

  .task-welcome-panel {
    min-height: 150px;
    margin-top: 1.5rem;
    padding: 1.2rem;
  }

  .main-container .table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }

  .main-container .row > [class*="col-"] {
    margin-bottom: 0.75rem;
  }

  .column {
    float: none !important;
    width: 100% !important;
    margin-bottom: 1rem;
  }

  .tab button {
    float: none;
    width: 100%;
    text-align: left;
  }

  h1 { font-size: 2rem; }
  h2 { font-size: 1.65rem; }
  h3 { font-size: 1.4rem; }
  h4 { font-size: 1.25rem; }
  h5 { font-size: 1.1rem; }

  .task-app-footer {
    flex-direction: column;
    gap: 0.35rem;
  }
}

/* Banda de tablet: el sidebar fijo de 270px y la grilla de dos columnas
   de la portada dejaban muy poco espacio util entre 768 y 1024px. */
@media (min-width: 768px) and (max-width: 1024px) {
  .task-sidebar {
    width: 220px;
  }

  .task-page {
    margin-left: 220px;
  }

  html.task-sidebar-collapsed .task-sidebar {
    width: 78px;
  }

  html.task-sidebar-collapsed .task-page {
    margin-left: 78px;
  }

  .task-welcome {
    grid-template-columns: minmax(0, 1fr);
  }

  .task-welcome-panel {
    min-height: 180px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .auth-panel,
  .auth-panel h2,
  .auth-panel table,
  .auth-panel .btn,
  .task-sidebar-nav .dropdown-menu.show,
  .w2p_flash {
    animation: none !important;
  }

  .catalog-card:hover {
    transform: none !important;
  }
}

/* ------------------------------------------------------------------
   Estilos de dominio (estatus de tareas, folios, formularios) movidos
   aca desde el <style> embebido en layout.html para tener una sola
   fuente de verdad y que el navegador pueda cachear el CSS. Los colores
   de estatus se mantienen (son parte del vocabulario visual conocido
   por el equipo), solo se ajustan los que quedaban ilegibles en tema
   oscuro (.txt-frm1 usaba un azul oscuro fijo).
   ------------------------------------------------------------------ */
/* Antes cada .tsk_N traia su propio padding horizontal a mano (5px 15px,
   5px 31px, etc.) solo para que las insignias parecieran mas o menos del
   mismo ancho -sin white-space:nowrap, una etiqueta de dos palabras
   ("proc compra", "en ejecución") se partia en dos renglones en columnas
   angostas de la tabla en vez de conservarse en una sola linea. Se separa
   el color (por estatus) del tamaño/forma (comun a todas), y se fuerza
   una sola linea--ago-26 */
.tsk_1,.tsk_2,.tsk_3,.tsk_4,.tsk_5,.tsk_6,.tsk_7,.tsk_8,.tsk_9,
.tsk_12,.tsk_13,.tsk_14,.tsk_15,.tsk_16,.tsk_17 {
  display: inline-block;
  white-space: nowrap;
  border-radius: 999px;
  padding: 0.3rem 0.9rem;
  font-size: 0.85rem;
  line-height: 1.2;
}
.tsk_1{background-color:rgb(25, 199, 25);color:rgb(241, 235, 226);}
.tsk_2{background-color: rgb(162, 110, 211);color:antiquewhite;}
.tsk_3{background-color:rgb(82, 122, 197);color:antiquewhite;}
.tsk_4{background-color: rgb(221, 150, 84);color:antiquewhite;}
.tsk_5{background-color: rgb(156, 150, 154);color:antiquewhite;}
.tsk_6{background-color: rgb(107, 217, 245);color:rgb(150, 107, 50);}
.tsk_7{background-color: rgb(247, 112, 89);color:antiquewhite;}
.tsk_8{background-color: rgb(238, 68, 68);color:antiquewhite;}
.tsk_9{background-color: rgb(192, 117, 4);color:antiquewhite;}
.tsk_10{color: rgb(162,110,211);}
.tsk_11{color:rgb(238, 200, 129);}
.tsk_12{background-color: rgb(2, 6, 29);color:antiquewhite;}
.tsk_13{background-color: rgb(175, 5, 104);color:antiquewhite;}
/* Fondo rosa claro con texto antiquewhite (casi blanco) practicamente
   no se leia -dos colores claros uno sobre otro. Se cambia a un texto
   oscuro para que "Sin autorización" sea legible--ago-26 */
.tsk_14{background-color: rgb(245, 176, 242);color:rgb(107, 20, 100);}
.tsk_15{background-color: rgb(230, 103, 223);color:antiquewhite;}
.tsk_16{background-color: rgb(153, 111, 47);color:antiquewhite;}
.tsk_17{background-color: rgb(245, 62, 175);color:antiquewhite;}

/* Grilla legacy de dos columnas usada por actualiza_task.html; el
   comportamiento responsive esta en el media query de mobile mas arriba. */
.column { float: left; width: 50%; padding: 10px; box-sizing: border-box; }
.row:after { content: ""; display: table; clear: both; }
.txt-right, .txt-rigth { text-align: right; }

.tab { overflow: hidden; border: 1px solid var(--task-border); background-color: var(--task-surface-soft); border-radius: 8px; }
.tab button, .tab a.tablinks { background-color: inherit; float: left; border: none; outline: none; cursor: pointer; padding: 14px 16px; color: var(--task-text); transition: 0.2s; text-decoration: none; }
.tab button:hover, .tab button:focus, .tab a.tablinks:hover, .tab a.tablinks:focus { background-color: var(--task-border); text-decoration: none; color: var(--task-text); }
.tab button.active, .tab a.tablinks.active { background-color: var(--task-primary); color: #fff; }
.tab a.tablinks.active:hover, .tab a.tablinks.active:focus { color: #fff; }
.tabcontent { display: none; padding: 6px 12px; border: 1px solid var(--task-border); border-top: none; }
.tabcontent.tabcontent-activo { display: block; }

.folio-str{color: crimson;font-style: italic;font-size:20px;}
.folio2-str{color: rgb(31, 128, 10);font-style: italic;font-size:20px;}
.folio3-str{color: rgb(170, 28, 63);font-style: italic;font-size:20px;}
.txt-frm1{color: var(--task-primary-strong);font-weight: bold;font-style: italic;}

.folio-st1{background-color: #af9ff5;border-radius:5px;padding:5px 13px 5px 7px;font-weight: bold;color: rgb(47, 47, 124);}
.folio-st2{background-color: #f3e4a0;border-radius:5px;padding:5px 13px 5px 7px;font-weight: bold;color: rgb(47, 47, 124);}
.folio-st3{background-color: #c1f7ba;border-radius:5px;padding:5px 13px 5px 7px;font-weight: bold;color: rgb(47, 47, 124);}
.dep-sta1{border-radius: 5px;padding:5px 13px 5px 7px;font-weight: bold;color: #7c54c7;}
.dep-sta2{border-radius: 5px;padding:5px 13px 5px 7px;font-weight: bold;color: rgb(207, 186, 67);}
.borde-1{border:2px solid blueviolet;border-radius: 5px;background-color: #af9ff5;}
.titulo-1{margin: auto;width: 60px;padding: 4px;}
.titulo-2{text-align:center;padding:2px;color: rgb(47, 47, 124);font-weight: bolder;bottom: auto;}
.sta-field{background-color: rgb(238, 200, 129);color: darkslategray;font-weight: bolder;}
.sta-field-1{background-color: rgb(226, 43, 211);}
.icon1{color: rgb(115, 92, 245);}
.icon2{color:#57e445;}
.icon3{color:#501ab3;}
.sta1{color: #aa0846;font-weight: bolder;}
.sta2{color: #e66713;font-weight: bolder;}
.sta3{color: #ebac26;font-weight: bolder;}
.task-prioridad{display:inline-flex;align-items:center;gap:0.4rem;font-weight:600;}
.task-prioridad-dot{display:inline-block;width:0.65rem;height:0.65rem;border-radius:50%;flex:none;}
.task-prioridad-dot.p1{background-color:#ebac26;}
.task-prioridad-dot.p2{background-color:#e66713;}
.task-prioridad-dot.p3{background-color:#aa0846;}
.task-sla-badge{display:inline-block;padding:0.05rem 0.5rem;border-radius:999px;font-size:0.72rem;font-weight:700;text-transform:uppercase;letter-spacing:0.02em;}
.task-sla-vencido{background:#fddede;color:#a3123a;}
.task-sla-riesgo{background:#ffe8c7;color:#a35a00;}
html[data-theme="dark"] .task-sla-vencido{background:#4a1220;color:#ff9db3;}
html[data-theme="dark"] .task-sla-riesgo{background:#4a3210;color:#ffcb80;}
.task-etiqueta-pill{display:inline-block;padding:0.1rem 0.55rem;margin:0 0.25rem 0.25rem 0;border-radius:999px;font-size:0.75rem;font-weight:600;background:color-mix(in srgb, var(--task-etq-color,#6c5ce7) 18%, var(--task-surface));border:1px solid var(--task-etq-color,#6c5ce7);color:var(--task-text);}
.task-etiquetas-editor{margin-top:0.75rem;}
.task-etiquetas-titulo{font-size:0.95rem;font-weight:700;margin-bottom:0.5rem;color:var(--task-text);}
.task-etiqueta-checks{display:flex;flex-wrap:wrap;gap:0.6rem;margin-bottom:0.75rem;}
.task-etiqueta-check{display:inline-flex;align-items:center;gap:0.35rem;font-weight:500;margin:0;}
.icon-vrf1{color:green;}
.icon-vrf2{color:rgb(110, 160, 19);}
.icon-vrf3{color:rgb(218, 198, 18);}
.icon-vrf4{color:rgb(218, 74, 55);}
.sta-sin-evidencia{color:#da2f40;}
.sta-sin-evidencia-ok{color:#ebac26;}
.task-foto-botones{display:flex;flex-wrap:wrap;gap:0.5rem;margin-bottom:0.4rem;}
.task-foto-nombre{display:block;font-size:0.85rem;color:var(--task-muted);margin-bottom:0.35rem;}

.form-tsk1{background-color:rgb(198, 225, 240);}
#task1_verifica__label{background-color: #4a69f0;color: rgb(240, 222, 222);}
.border-tptask{border:1px solid rgb(47, 47, 124);border-radius: 5px;padding-left: 10px;padding-top:8px;border-left: 12px solid rgb(47, 47, 124);background-color: #af9ff5;}
.form-stl-1{background-color: #ebca37;border-radius: 5px;padding-left: 10px;padding-top:8px;border-left: 12px solid rgb(47, 47, 124);}
#tsk-descripcion{background-color: #b0d1f1;border: 1px solid #ddd;padding: 10px;margin-top:5px;margin-bottom: 20px;border-radius: 5px;border-left: 8px solid rgb(61, 61, 146);}
.cuadro-redondeado{width: auto;padding: 20px;border: 2px solid #3498db;border-radius: 15px;background-color: #f0f8ff;box-shadow: 2px 2px 8px rgba(0,0,0,0.1);}
.cuadro-separacion{margin-bottom: 20px;}

.task-alert-danger{
  margin-bottom: 15px;
  padding: 0.75rem 1rem;
  border-radius: 8px;
  background-color: color-mix(in srgb, #f44336 14%, var(--task-surface));
  border-left: 6px solid #f44336;
  color: var(--task-text);
}
.task-alert-danger h2,
.task-alert-danger h4{margin: 0;}
.task-alert-danger .task-alert-value{color: #f44336;font-weight: bold;}

/* Bitacora unificada por tarea: linea de tiempo con cambios de estatus
   y fotos de evidencia intercalados por fecha--ago-26 */
.task-timeline-summary{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.task-timeline{
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.task-timeline::before{
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 19px;
  width: 2px;
  background: var(--task-border);
}

.task-timeline-item{
  position: relative;
  display: flex;
  gap: 1rem;
  padding-bottom: 1.5rem;
}

.task-timeline-marker{
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--task-surface);
  border: 2px solid var(--task-border);
  color: var(--task-primary);
}

.task-timeline-foto .task-timeline-marker{
  color: #57e445;
}

.task-timeline-body{
  flex: 1;
  min-width: 0;
  padding: 0.85rem 1rem;
  border-radius: 10px;
  background: var(--task-surface);
  border: 1px solid var(--task-border);
}

.task-timeline-meta{
  font-size: 0.8rem;
  color: var(--task-muted);
  margin-bottom: 0.35rem;
}

.task-timeline-thumb{
  display: block;
  max-width: 220px;
  width: 100%;
  height: auto;
  border-radius: 8px;
  margin: 0.35rem 0;
}

.task-timeline-nota .task-timeline-marker{color:var(--task-primary);}
.task-timeline-nota-mia .task-timeline-body{background:var(--task-surface-soft);}
.task-chat-burbuja{white-space:pre-wrap;word-break:break-word;}
.task-nota-interna{display:inline-block;margin-left:0.5rem;padding:0.05rem 0.5rem;border-radius:999px;font-size:0.7rem;font-weight:700;text-transform:uppercase;background:var(--task-surface-soft);color:var(--task-primary-strong);}
.task-chat-form{margin-top:1rem;}
.task-chat-form textarea{margin-bottom:0.6rem;}
.task-nota-check{display:flex;margin-bottom:0.6rem;}
.task-ayuda-buscador{
  display:flex;align-items:center;gap:0.6rem;
  padding:0.6rem 0.9rem;margin-bottom:0.6rem;
  border:1px solid var(--task-border);border-radius:10px;
  background:var(--task-surface);color:var(--task-muted);
}
.task-ayuda-buscador input{
  flex:1;border:none;background:transparent;color:var(--task-text);
  font-size:0.95rem;outline:none;
}
.task-ayuda-contador{font-size:0.8rem;white-space:nowrap;}
.task-ayuda-acciones{display:flex;gap:0.5rem;margin-bottom:1rem;}
.task-ayuda-lista{display:flex;flex-direction:column;gap:0.75rem;}
.task-ayuda-grupo{font-size:1.05rem;font-weight:800;color:var(--task-text);margin:1.25rem 0 -0.25rem;}
.task-ayuda-grupo:first-child{margin-top:0;}
.task-ayuda-item summary{cursor:pointer;font-weight:700;font-size:1rem;color:var(--task-primary-strong);list-style:none;}
.task-ayuda-item summary::-webkit-details-marker{display:none;}
.task-ayuda-item summary::before{content:'▸';display:inline-block;margin-right:0.5rem;transition:transform 0.15s ease;}
.task-ayuda-item[open] summary::before{transform:rotate(90deg);}
.task-ayuda-cuerpo{margin-top:0.75rem;color:var(--task-text);}
.task-ayuda-cuerpo ul{padding-left:1.25rem;}
.task-ayuda-cuerpo li{margin-bottom:0.35rem;}
.task-impacto-badge{display:inline-block;padding:0.05rem 0.55rem;border-radius:999px;font-size:0.75rem;font-weight:700;}
.task-impacto-badge.imp-leve{background:#fff3cd;color:#856404;}
.task-impacto-badge.imp-moderado{background:#ffe0b3;color:#a35a00;}
.task-impacto-badge.imp-severo{background:#fddede;color:#a3123a;}
.task-especialidad-badge{display:inline-block;padding:0.05rem 0.55rem;border-radius:999px;font-size:0.75rem;font-weight:700;background:color-mix(in srgb, var(--task-primary) 16%, var(--task-surface));color:var(--task-primary-strong,var(--task-primary));}
.task-hoy-lista{font-size:0.9rem;}
.task-hoy-lista li{margin-bottom:0.3rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* ------------------------------------------------------------------
   Selector de fecha/hora (calendar.js, cargado por web2py_ajax.html):
   por defecto es blanco y negro puro sin relacion con el resto de la
   UI. Se sobreescribe con los mismos tokens del tema--ago-26
   ------------------------------------------------------------------ */
.calendar{
  background: var(--task-surface) !important;
  border: 1px solid var(--task-border) !important;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25);
  font-family: inherit !important;
}

.calendar table,
.calendar tbody .day,
.calendar td.time .hour,
.calendar td.time .minute,
.calendar td.time .ampm,
.calendar td.time .colon{
  color: var(--task-text) !important;
}

.calendar thead .title{
  background: var(--task-primary) !important;
  color: #fff !important;
  border-radius: 8px 8px 0 0;
}

.calendar thead .name{
  background: var(--task-surface-soft) !important;
  color: var(--task-text) !important;
  font-weight: 600;
}

.calendar thead .weekend{
  color: #f44336 !important;
}

.calendar .button{
  background: transparent !important;
  color: #fff !important;
}

.calendar tbody .day.othermonth{
  color: var(--task-muted) !important;
}

.calendar tbody td.today{
  color: var(--task-primary) !important;
  font-weight: 700;
}

.calendar tbody .hilite,
.calendar tbody td.hilite,
.calendar tbody td.active,
.calendar .combo .hilite,
.calendar .combo .active{
  background: var(--task-surface-soft) !important;
  color: var(--task-text) !important;
}

.calendar tbody td.selected{
  background: var(--task-primary) !important;
  color: #fff !important;
  border-radius: 4px;
}

.calendar tbody td.weekend{
  color: #f44336 !important;
}

.calendar .combo{
  background: var(--task-surface) !important;
  border: 1px solid var(--task-border) !important;
}

.calendar table .wn,
.calendar td.time{
  background: var(--task-surface-soft) !important;
}

.calendar td.time span.active{
  background: var(--task-primary) !important;
  border-color: var(--task-primary) !important;
  color: #fff !important;
}

.calendar tfoot .ttip{
  background: var(--task-primary) !important;
  color: #fff !important;
  border-radius: 0 0 8px 8px;
}

/* Campana de notificaciones--ago-26 */
.task-notif-badge{
  position:absolute;top:2px;right:-2px;
  background:#da2f40;color:#fff;
  border-radius:999px;
  font-size:0.65rem;font-weight:700;
  min-width:1.1rem;line-height:1.1rem;
  padding:0 0.3rem;text-align:center;
}
.task-notif-list{min-width:300px;max-height:70vh;overflow-y:auto;}
.task-notif-list .dropdown-item{white-space:normal;padding:0.5rem 1rem;border-bottom:1px solid var(--task-border);}
.task-notif-list .dropdown-item:last-child{border-bottom:0;}
.task-notif-unread{background:var(--task-surface-soft);font-weight:600;}
.task-notif-item{display:flex;align-items:flex-start;gap:0.4rem;padding-right:0.5rem;}
.task-notif-item .task-notif-link{flex:1;min-width:0;color:inherit;}
.task-notif-borra{
  flex-shrink:0;border:0;background:transparent;color:var(--task-muted);
  width:1.6rem;height:1.6rem;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;font-size:0.8rem;
}
.task-notif-borra:hover{background:var(--task-surface-soft);color:var(--task-danger,#da2f40);}
.task-notif-footer{display:flex;border-top:1px solid var(--task-border);}
.task-notif-footer .dropdown-item{flex:1;}

/* Mejoras de UI/UX -ago-26: estado de carga, banner sin conexion, FAB
   movil, modal de confirmacion, estados vacios de grid. */

/* El texto de "Guardando..." en un boton de submit ya lo pone
   web2py.js (disableElement, ver views/web2py_ajax.html); aqui solo se le
   da una animacion de pulso para que se note que algo esta pasando,
   funciona igual en <button> y en <input type=submit> (un pseudo-elemento
   ::before no se puede usar en <input>, por eso no es un spinner real). */
.btn.disabled,
input.disabled[type="submit"],
button.disabled[type="submit"] {
  animation: task-btn-pulso 1.1s ease-in-out infinite;
  cursor: progress !important;
}
@keyframes task-btn-pulso {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 0.95; }
}
@media (prefers-reduced-motion: reduce) {
  .btn.disabled,
  input.disabled[type="submit"],
  button.disabled[type="submit"] { animation: none; opacity: 0.65; }
}

.task-conn-banner{
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1050;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.6rem 1rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
  background: #c9822a;
  color: #fff;
  font-size: 0.85rem;
  text-align: center;
  box-shadow: 0 -4px 16px rgba(0,0,0,0.18);
}

.task-fab-nueva{
  display: none;
  position: fixed;
  right: calc(1.1rem + env(safe-area-inset-right, 0px));
  bottom: calc(1.1rem + env(safe-area-inset-bottom, 0px));
  z-index: 1020;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  align-items: center;
  justify-content: center;
  background: var(--task-primary);
  color: #fff;
  font-size: 1.4rem;
  box-shadow: var(--task-shadow);
  transition: bottom 160ms ease, transform 120ms ease;
}
.task-fab-nueva:hover,
.task-fab-nueva:focus{
  color: #fff;
  transform: translateY(-2px);
}
html.task-is-offline .task-fab-nueva{
  bottom: calc(4.4rem + env(safe-area-inset-bottom, 0px));
}
@media (max-width: 767.98px){
  .task-fab-nueva{ display: flex; }
}

.task-confirm-body{
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 1.25rem 1.25rem 0.5rem;
}
.task-confirm-icon{
  color: #c9822a;
  font-size: 1.5rem;
  flex-shrink: 0;
  margin-top: 0.1rem;
}
.task-confirm-msg{
  margin: 0;
  font-size: 0.95rem;
}

.task-grid-empty{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 2.5rem 1rem;
  color: var(--task-muted);
  font-size: 0.95rem;
  text-align: center;
}
.task-grid-empty i{
  font-size: 2rem;
  opacity: 0.6;
}

/* Mejoras de UI/UX -30-ago-26: lightbox de fotos, validacion visible,
   filtro instantaneo de tablas, arrastrar-y-soltar para subir evidencia. */

.task-lightbox-overlay{
  position: fixed;
  inset: 0;
  z-index: 1080;
  background: rgba(5, 8, 15, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
}
.task-lightbox-imagen{
  max-width: min(92vw, 1100px);
  max-height: 88vh;
  border-radius: 8px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}
.task-lightbox-cerrar,
.task-lightbox-prev,
.task-lightbox-next{
  position: absolute;
  background: rgba(255,255,255,0.12);
  border: none;
  color: #fff;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.task-lightbox-cerrar:hover,
.task-lightbox-prev:hover,
.task-lightbox-next:hover{
  background: rgba(255,255,255,0.24);
}
.task-lightbox-cerrar{ top: 1.25rem; right: 1.25rem; }
.task-lightbox-prev{ left: 1.25rem; top: 50%; transform: translateY(-50%); }
.task-lightbox-next{ right: 1.25rem; top: 50%; transform: translateY(-50%); }
.task-lightbox-contador{
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(255,255,255,0.8);
  font-size: 0.85rem;
}
html.task-lightbox-abierto{ overflow: hidden; }

/* Errores de SQLFORM (gluon/html.py ya los marca con estas clases):
   antes era solo texto rojo suelto, sin relacion visual con el campo. */
div.error{
  color: #fff;
  background: #da2f40;
  border-radius: 6px;
  padding: 0.3rem 0.6rem;
  font-size: 0.85rem;
  margin-top: 0.3rem;
  display: inline-block;
}
.invalidinput,
.task-campo-invalido{
  border-color: #da2f40 !important;
  box-shadow: 0 0 0 3px rgba(218,47,64,0.18);
}
.task-campo-obligatorio{
  color: #da2f40;
  font-size: 0.82rem;
  margin-top: 0.3rem;
}
@keyframes task-campo-shake{
  10%,90% { transform: translateX(-1px); }
  20%,80% { transform: translateX(2px); }
  30%,50%,70% { transform: translateX(-4px); }
  40%,60% { transform: translateX(4px); }
}
.task-campo-shake{
  animation: task-campo-shake 400ms ease;
}
@media (prefers-reduced-motion: reduce){
  .task-campo-shake{ animation: none; }
}

.task-grid-filtro{
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
  color: var(--task-muted);
}
.task-grid-filtro input{
  flex: 1;
  max-width: 320px;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--task-border);
  border-radius: 8px;
  background: var(--task-surface);
  color: var(--task-text);
}
.task-grid-filtro-contador{
  font-size: 0.8rem;
  white-space: nowrap;
}

.task-dropzone{
  border: 2px dashed var(--task-border);
  border-radius: 10px;
  padding: 0.5rem;
  transition: border-color 120ms ease, background-color 120ms ease;
}
.task-dropzone-activa{
  border-color: var(--task-primary);
  background: var(--task-surface-soft);
}
.task-dropzone-hint{
  color: var(--task-muted);
  font-size: 0.85rem;
  margin: 0.4rem 0 0;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* Tom-Select (selects buscables): se pinta con los mismos tokens de
   color del resto de la app, en vez del azul/gris por defecto de su
   tema bootstrap4 -incluido modo oscuro--ago-26 */
.ts-wrapper.single .ts-control,
.ts-wrapper.multi .ts-control{
  background: var(--task-surface);
  border-color: var(--task-border);
  color: var(--task-text);
}
.ts-wrapper.focus .ts-control{
  border-color: var(--task-primary);
  box-shadow: 0 0 0 3px rgba(108,93,211,0.18);
}
.ts-dropdown{
  background: var(--task-surface);
  border-color: var(--task-border);
  color: var(--task-text);
}
.ts-dropdown .ts-dropdown-content .option{
  color: var(--task-text);
}
.ts-dropdown .ts-dropdown-content .active{
  background: var(--task-primary);
  color: #fff;
}
.ts-control input{
  color: var(--task-text);
}
.ts-wrapper.single .ts-control:after{
  border-top-color: var(--task-muted);
}

/* Calendario de mantenimiento preventivo (vanilla, sin libreria)--30-ago-26 */
.task-calendario-cabecera{
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.75rem;
}
.task-calendario-titulo{
  margin: 0;
  flex: 1;
  text-align: center;
  font-size: 1.05rem;
}
.task-calendario-diassemana{
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  color: var(--task-muted);
  font-size: 0.78rem;
  font-weight: 600;
  margin-bottom: 0.35rem;
}
.task-calendario-grid{
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.3rem;
}
.task-calendario-dia{
  position: relative;
  aspect-ratio: 1 / 1;
  min-height: 2.4rem;
  border: 1px solid var(--task-border);
  border-radius: 8px;
  background: var(--task-surface);
  color: var(--task-text);
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  padding: 0.3rem;
  cursor: default;
}
.task-calendario-dia-vacio{
  border: none;
  background: transparent;
}
.task-calendario-dia-hoy{
  border-color: var(--task-primary);
}
.task-calendario-dia-conEventos{
  cursor: pointer;
  background: var(--task-surface-soft);
}
.task-calendario-dia-conEventos:hover{
  border-color: var(--task-primary);
}
.task-calendario-numero{
  font-size: 0.85rem;
}
.task-calendario-badge{
  position: absolute;
  bottom: 0.3rem;
  right: 0.3rem;
  background: var(--task-primary);
  color: #fff;
  border-radius: 999px;
  min-width: 1.2rem;
  height: 1.2rem;
  font-size: 0.7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.25rem;
}
.task-calendario-detalle{
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--task-border);
}
.task-calendario-detalle h4{
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
}
.task-calendario-detalle ul{
  margin: 0;
  padding-left: 1.1rem;
}
.task-calendario-detalle li{
  margin-bottom: 0.3rem;
  font-size: 0.9rem;
}
@media (max-width: 575.98px){
  .task-calendario-numero{ font-size: 0.75rem; }
  .task-calendario-badge{ min-width: 1rem; height: 1rem; font-size: 0.62rem; }
}

/* ===== Tablero Kanban (kanban_task.html)--31-ago-26 ===== */
.kanban-nav{
  display: flex;
  gap: 0.4rem;
  overflow-x: auto;
  padding-bottom: 0.5rem;
  margin-bottom: 0.5rem;
  -webkit-overflow-scrolling: touch;
}
.kanban-nav-chip{
  flex: 0 0 auto;
  border: 1px solid var(--task-border);
  background: var(--task-surface);
  color: var(--task-muted);
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  font-size: 0.78rem;
  white-space: nowrap;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.kanban-nav-chip-activo{
  border-color: var(--task-primary);
  color: var(--task-text);
  background: color-mix(in srgb, var(--task-primary) 14%, var(--task-surface));
}
.kanban-tablero{
  display: flex;
  gap: 0.85rem;
  overflow-x: auto;
  padding-bottom: 0.5rem;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.kanban-columna{
  flex: 0 0 260px;
  min-width: 260px;
  background: var(--task-surface-soft);
  border: 1px solid var(--task-border);
  border-radius: 10px;
  padding: 0.6rem;
  transition: background-color 0.15s;
  scroll-snap-align: start;
}
.kanban-columna-sobre{
  background: color-mix(in srgb, var(--task-primary) 12%, var(--task-surface-soft));
}
.kanban-columna-titulo{
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--task-muted);
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.6rem 0;
}
.kanban-columna-contador{
  background: var(--task-border);
  color: var(--task-text);
  border-radius: 999px;
  padding: 0.05rem 0.5rem;
  font-size: 0.75rem;
}
.kanban-columna-cuerpo{
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 40px;
}
.kanban-tarjeta{
  background: var(--task-surface);
  border: 1px solid var(--task-border);
  border-radius: 8px;
  padding: 0.55rem 0.65rem;
  cursor: grab;
}
.kanban-tarjeta.kanban-arrastrando{
  opacity: 0.4;
}
.kanban-tarjeta-folio{
  font-weight: 700;
  font-size: 0.85rem;
}
.kanban-tarjeta-descrip{
  font-size: 0.85rem;
  margin: 0.15rem 0;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.kanban-tarjeta-meta{
  font-size: 0.75rem;
  color: var(--task-muted);
}
.kanban-selector{
  margin-top: 0.4rem;
  font-size: 0.78rem;
  padding: 0.2rem 0.4rem;
}
.task-aviso-ok{
  border: 1px solid var(--task-border);
  border-radius: 10px;
  padding: 0.5rem 0.85rem;
  background: color-mix(in srgb, #2e9e5b 15%, var(--task-surface-soft));
}
.task-aviso-error{
  border: 1px solid var(--task-border);
  border-radius: 10px;
  padding: 0.5rem 0.85rem;
  background: color-mix(in srgb, var(--task-danger, #da2f40) 15%, var(--task-surface-soft));
}

/* ===== Nueva solicitud: borrador, plantillas, duplicados, dictado
   (alta_task.html, JS en static/js/alta_task_extra.js)--31-ago-26 ===== */
.task-borrador-banner{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.75rem;
  padding: 0.55rem 0.85rem;
  border: 1px solid var(--task-border);
  border-radius: 10px;
  background: var(--task-surface-soft);
}
.task-plantillas{
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.85rem;
}
.task-plantilla-chip{
  border: 1px solid var(--task-border);
  background: var(--task-surface);
  color: var(--task-text);
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  font-size: 0.82rem;
  cursor: pointer;
}
.task-plantilla-chip:hover{
  background: var(--task-surface-soft);
}
.task-duplicado-aviso{
  margin: 0.5rem 0 0.85rem 0;
  padding: 0.55rem 0.85rem;
  border: 1px solid var(--task-border);
  border-radius: 10px;
  background: color-mix(in srgb, #d99a2b 15%, var(--task-surface-soft));
  font-size: 0.85rem;
}
.task-duplicado-aviso ul{
  margin: 0.35rem 0 0 0;
  padding-left: 1.1rem;
}
.task-dictado-btn{
  border: 1px solid var(--task-border);
  background: var(--task-surface);
  color: var(--task-text);
  border-radius: 6px;
  padding: 0.2rem 0.5rem;
  margin-left: 0.4rem;
  cursor: pointer;
}
.task-dictado-btn.task-dictado-activo{
  background: var(--task-danger, #da2f40);
  color: #fff;
  border-color: var(--task-danger, #da2f40);
}
@media (max-width: 575.98px){
  .kanban-columna{ flex: 0 0 90vw; min-width: 90vw; }
  .kanban-tablero{ scroll-snap-type: x mandatory; }
}

.task-pull-refresh{
  position: fixed;
  top: 0;
  left: 50%;
  transform: translate(-50%, -60px);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--task-surface);
  border: 1px solid var(--task-border);
  color: var(--task-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
  box-shadow: var(--task-shadow);
  transition: background-color 120ms ease, color 120ms ease;
  pointer-events: none;
}
.task-pull-refresh.task-pull-lista{
  color: #fff;
  background: var(--task-primary);
}
.task-pull-refresh.task-pull-cargando i{
  animation: task-pull-gira 0.6s linear infinite;
}
@keyframes task-pull-gira{
  from{ transform: rotate(0deg); }
  to{ transform: rotate(360deg); }
}

/* Tarjetas responsivas para TODAS las tablas de SQLFORM.grid en pantallas
   angostas (ver el JS que arma esto en layout.html): sin esto, cada
   tabla obligaba a deslizar horizontalmente para ver las columnas que no
   cabian. Se aplica solo dentro de .web2py_grid (nunca a otras tablas
   sueltas del sistema, como los reportes PDF o el centro de ayuda), y
   solo bajo este breakpoint -en escritorio/tablet la tabla normal de
   web2py se queda intacta--sep-26 */
.task-grid-orden-envoltura{ display: none; }
.task-tarjeta-vermas{
  display: none;
  margin-top: 0.4rem;
  border: 1px solid var(--task-border);
  background: var(--task-surface);
  color: var(--task-primary);
  border-radius: 6px;
  padding: 0.25rem 0.6rem;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}
@media (max-width: 575.98px){
  .task-grid-orden-envoltura{
    display: block;
    margin-bottom: 0.6rem;
  }
  .task-grid-orden-envoltura select{
    width: 100%;
  }
  .web2py_htmltable table,
  .web2py_htmltable thead,
  .web2py_htmltable tbody,
  .web2py_htmltable th,
  .web2py_htmltable td,
  .web2py_htmltable tr{
    display: block;
    min-width: 0;
  }
  .web2py_htmltable{ overflow-x: visible; }
  .web2py_htmltable thead{ display: none; }
  .web2py_htmltable tbody tr{
    border: 1px solid var(--task-border);
    border-radius: 10px;
    /* !important a proposito: web2py-bootstrap4.css fija "background-color:
       transparent !important" en .odd/.even (ver el comentario de esa
       misma regla mas arriba en este archivo) -sin esto cada tarjeta se
       veia transparente en vez de con su propio fondo--sep-26 */
    background: var(--task-surface) !important;
    padding: 0.75rem 0.85rem;
    margin-bottom: 0.6rem;
  }
  html.task-densidad-compacta .web2py_htmltable tbody tr{
    padding: 0.4rem 0.6rem;
    margin-bottom: 0.35rem;
  }
  /* Especificidad igual o mayor que ".web2py_htmltable tbody td" (la
     regla de escritorio que ya pone padding/border-top, mas arriba en
     este archivo) a proposito: sin esto, esa regla de escritorio gana
     por especificidad aunque esta este declarada despues, y las lineas
     divisorias y el padding grande se quedaban en modo tarjeta--sep-26 */
  .web2py_htmltable tbody td{
    border: none;
    padding: 0.15rem 0;
  }
  .task-tarjeta-titulo{
    font-size: 1.05rem;
    font-weight: 700;
    margin-bottom: 0.15rem;
  }
  .task-tarjeta-resumen[data-label]::before,
  .task-tarjeta-extra[data-label]::before{
    content: attr(data-label) ": ";
    font-weight: 600;
    color: var(--task-muted);
  }
  .task-tarjeta-resumen{
    font-size: 0.88rem;
    color: var(--task-muted);
  }
  /* Misma razon de especificidad que arriba: ".web2py_htmltable td" ya
     no alcanza para ganarle a la regla de escritorio--sep-26 */
  .web2py_htmltable tbody td.task-tarjeta-extra{ display: none; }
  .web2py_htmltable tbody tr.task-tarjeta-abierta td.task-tarjeta-extra{
    display: block !important;
    font-size: 0.88rem;
    color: var(--task-text);
  }
  .web2py_htmltable tbody tr.task-tarjeta-abierta td.task-tarjeta-extra[data-label]::before{
    color: var(--task-muted);
  }
  .task-tarjeta-vermas{ display: inline-block; }
  .web2py_htmltable tbody td.task-tarjeta-accion,
  .web2py_htmltable tbody td.row_buttons{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    border: none;
    padding: 0;
    margin-top: 0.5rem;
  }
}
