/* Healthy Fleets — sistema visual. Marca en brand/ (color, simbolo, tipografia).
   Fondo blanco, tipografia grande, un solo acento. Cada pantalla tiene que
   entenderse sin que nadie la explique. */

:root {
  /* Tres superficies, no una: el fondo tras los paneles, el panel en si, y el
     matiz de cabeceras. Todo blanco sobre blanco es lo que hace que una
     interfaz parezca sin terminar. */
  --bg: #f2f6f7;
  --panel: #ffffff;
  --panel-2: #f4f7f9;
  --side: #f7fafb;
  --line: #e2e8ec;
  --line-strong: #cdd7dd;
  --text: #12262e;         /* tinta de la marca */
  --text-2: #44545e;
  /* 4.6:1 sobre blanco. El gris anterior (#79828f) daba 3.89:1 y se quedaba
     por debajo del minimo legible para texto pequeno, que es donde mas se usa. */
  --muted: #6b7480;
  /* Verde azulado de la marca (#0E7C8E) para rellenos. Texto y lineas van un
     punto mas oscuros: el de la marca da 4.9:1 sobre blanco, pero baja de 4.5:1
     sobre el fondo suave de etiquetas y filtros, que es donde hay texto pequeno. */
  --accent: #0c6f7f;
  --accent-vivid: #0e7c8e;
  --accent-soft: #e3f1f3;
  --accent-line: #b7d9df;
  /* Tipografia del nombre. Solo para la marca: el resto sigue con la del sistema. */
  --brand-font: Outfit, var(--sans);
  --oscar: #f26a21;        /* naranja de Oscar, solo para el enlace a Oscar */
  --oscar-hover: #d95a15;

  --ok: #0e7a3c;       --ok-bg: #e9f7ee;
  --warn: #9c5a00;     --warn-bg: #fff3e0;
  --overdue: #c02a1f;  --overdue-bg: #fdecea;
  --none: #5f6a78;     --none-bg: #f0f2f5;

  --r: 10px;
  --shadow: 0 1px 2px rgba(16,24,40,.04), 0 1px 1px rgba(16,24,40,.03);
  --shadow-lift: 0 2px 4px rgba(16,24,40,.05), 0 10px 24px rgba(16,24,40,.06);
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, Helvetica, Arial, sans-serif;
  color-scheme: light;   /* la aplicacion es siempre clara, a proposito */
}

* { box-sizing: border-box; }
/* Lo oculto se oculta siempre. Sin esto, cualquier elemento con display propio
   (flex, grid) ignora el atributo hidden y se pinta igual: asi salia una franja
   blanca vacia abajo en el movil. */
[hidden] { display: none !important; }
html, body { margin: 0; min-height: 100%; }
body {
  background: var(--bg); color: var(--text);
  font: 15px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
h1 { font-size: 22px; font-weight: 660; letter-spacing: -.028em; margin: 0; }
h2 { font-size: 15px; font-weight: 640; letter-spacing: -.011em; margin: 0; }
h3 { font-size: 13px; font-weight: 640; color: var(--text-2); margin: 0; }
.mono { font-variant-numeric: tabular-nums; }
.muted { color: var(--muted); }
.small { font-size: 13.5px; }
.tiny { font-size: 12.5px; }
b, strong { font-weight: 640; }

/* ================================================================= layout */
.app { display: grid; grid-template-columns: 232px 1fr; min-height: 100vh; }

.side {
  background: linear-gradient(180deg, #eff6f7 0%, var(--side) 220px);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column; padding: 20px 12px 16px;
  position: sticky; top: 0; align-self: start; height: 100vh;
}
.logo { display: flex; align-items: center; gap: 10px; padding: 4px 6px 22px; color: var(--text); }
/* El escudo va suelto, sin losa: ya es una forma cerrada y con peso. */
.logo img { width: 30px; height: 30px; flex: none; }
.logo .word { display: block; }
.logo b, .entrada-marca .word b {
  display: block; font-family: var(--brand-font); font-size: 17px; font-weight: 600;
  letter-spacing: -.02em; line-height: 1.05; color: var(--text);
}
/* La empresa del cliente, debajo de la marca. Tarjeta blanca con filo: asi un
   logo con fondo blanco y uno transparente quedan igual de bien. */
.empresa {
  display: grid; gap: 7px; justify-items: start;
  margin: -10px 0 18px; padding: 11px 12px;
  background: var(--panel); border-radius: 9px; box-shadow: 0 0 0 1px var(--line);
}
.empresa img { display: block; max-width: 100%; max-height: 42px; object-fit: contain; }
.empresa span { font-size: 13px; font-weight: 620; color: var(--text-2); line-height: 1.3; }
.side nav { display: flex; flex-direction: column; gap: 3px; }
.side nav a {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px; border-radius: 7px; font-size: 14.5px;
  font-weight: 530; color: var(--text-2);
  transition: background .12s, color .12s;
}
.side nav a svg { width: 17px; height: 17px; flex: none; opacity: .7; transition: opacity .12s; }
.side nav a:hover { background: rgba(15,23,32,.045); color: var(--text); }
.side nav a:hover svg { opacity: .95; }
.side nav a.active {
  background: var(--panel); color: var(--text); font-weight: 620;
  box-shadow: 0 1px 2px rgba(16,24,40,.06), 0 0 0 1px var(--line);
}
.side nav a.active svg { opacity: 1; color: var(--accent); }
/* Barra de acento al margen: marca donde estas sin tenir de color medio menu */
.side nav a.active::before {
  content: ''; position: absolute; left: -12px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 18px; border-radius: 0 3px 3px 0; background: var(--accent);
}
.side nav a .count {
  margin-left: auto; font-size: 12px; font-weight: 700; padding: 1px 7px;
  border-radius: 20px; background: var(--overdue); color: #fff;
}
.side-foot { margin-top: auto; padding: 12px; font-size: 12.5px; line-height: 1.5; color: var(--muted); }

.main { min-width: 0; }
.head {
  position: relative;
  padding: 22px 28px 18px; display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
  background: var(--panel); border-bottom: 1px solid var(--line);
}
/* Filo de color sobre la cabecera: firma discreta que se repite en toda la
   aplicacion y la hace reconocible sin tenir la interfaz de color. */
.head::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(90deg, var(--accent-vivid), #6db8c3 45%, transparent 85%);
}
.head .sub { color: var(--muted); font-size: 14px; margin-top: 4px; max-width: 68ch; line-height: 1.5; }
.head .spacer { flex: 1; }
.body { padding: 22px 28px 72px; max-width: 1320px; }

@media (max-width: 900px) {
  .app { grid-template-columns: minmax(0, 1fr); }
  /* Arriba solo una barra fina con la marca: el menu va abajo, como en
     cualquier app del movil. */
  .side {
    position: sticky; top: 0; z-index: 40; height: auto; align-self: stretch;
    flex-direction: row; align-items: center; gap: 12px;
    padding: calc(9px + env(safe-area-inset-top)) 16px 9px;
    background: rgba(255,255,255,.94); backdrop-filter: saturate(1.4) blur(12px);
    -webkit-backdrop-filter: saturate(1.4) blur(12px);
    border-right: 0; border-bottom: 1px solid var(--line);
  }
  /* .app delante para ganar a la regla general del pie, que va mas abajo */
  .app .side nav, .app .side-foot { display: none; }
  .logo { padding: 0; }
  .logo .word b { white-space: nowrap; }
  .logo img { width: 26px; height: 26px; }
  .logo b { font-size: 16px; }
  /* el cliente, a la derecha de la barra: su logo, o su nombre si no tiene */
  .empresa { margin: 0 0 0 auto; padding: 0; background: none; box-shadow: none; flex: none; }
  .empresa img { max-height: 26px; max-width: 110px; }
  .empresa img + span { display: none; }
  .empresa span { white-space: nowrap; font-size: 12.5px; }
  .head { padding: 18px 16px 16px; }
  .body { padding: 14px 16px calc(96px + env(safe-area-inset-bottom)); }
}

/* ================================================== menu de abajo en el movil */
.tabbar { display: none; }
@media (max-width: 900px) {
  /* clip y no hidden: con hidden en html y body, el body pasa a ser el que
     hace scroll y en iPhone deja de funcionar la barra fija de arriba. */
  html { overflow-x: clip; }

  .tabbar {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
    padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
    background: rgba(255,255,255,.96); backdrop-filter: saturate(1.4) blur(14px);
    -webkit-backdrop-filter: saturate(1.4) blur(14px);
    border-top: 1px solid var(--line);
  }
  .tabbar a, .tabbar button {
    position: relative; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 2px; min-height: 52px; padding: 6px 2px;
    border: 0; border-radius: 12px; background: none; box-shadow: none;
    font: inherit; font-size: 11.5px; font-weight: 580; color: var(--muted);
  }
  .tabbar a:hover, .tabbar button:hover { background: none; }
  .tabbar svg { width: 23px; height: 23px; }
  .tabbar .active { color: var(--accent); }
  .tabbar .active svg { stroke-width: 2.1; }
  .tabbar .count {
    position: absolute; top: 3px; left: calc(50% + 5px); min-width: 18px; padding: 0 5px;
    font-size: 11px; line-height: 18px; border-radius: 9px; font-weight: 700;
    background: var(--overdue); color: #fff; text-align: center;
  }

  /* lo que flota abajo, por encima del menu */
  /* .app delante: la regla general de este aviso va mas abajo en el fichero */
  .app .instalar-app {
    bottom: calc(76px + env(safe-area-inset-bottom));
    display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; gap: 10px 12px;
    align-items: center;
  }
  .app .instalar-app .btn-primary { grid-row: 1; grid-column: 3; }
  .app .instalar-app .btn-ghost { grid-row: 2; grid-column: 1 / -1; padding: 6px; }
  .toast { bottom: calc(86px + env(safe-area-inset-bottom)) !important; }

  /* la ficha de la furgoneta: nada puede empujarla mas ancha que la pantalla */
  .vehicle { grid-template-columns: minmax(0, 1fr); }
  .vehicle > * { min-width: 0; }
  .photo .vanimg { aspect-ratio: auto; height: 190px; }
}

/* ================================================================== bases */
.panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow), inset 0 1px 0 #fff;
}
.panel + .panel { margin-top: 18px; }
.panel-head { padding: 12px 16px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 10px; }
.panel-body { padding: 18px; }
.row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.between { justify-content: space-between; }
.stack { display: grid; gap: 16px; }

button, .btn {
  font: inherit; font-size: 14px; font-weight: 560; cursor: pointer;
  transition: background .12s, border-color .12s, box-shadow .12s;
  padding: 8px 15px; border-radius: 7px; border: 1px solid var(--line-strong);
  background: var(--panel); color: var(--text); white-space: nowrap;
}
button:hover, .btn:hover { background: var(--panel-2); border-color: var(--muted); }
.btn-primary {
  background: linear-gradient(180deg, var(--accent-vivid), var(--accent));
  border-color: #0a606e; color: #fff;
  box-shadow: 0 1px 2px rgba(10,96,110,.24), inset 0 1px 0 rgba(255,255,255,.14);
}
.btn-primary:hover { background: linear-gradient(180deg, var(--accent), #0a5a67); }
.btn-primary:active { box-shadow: inset 0 1px 2px rgba(0,0,0,.18); }
.btn-oscar { background: var(--oscar); border-color: var(--oscar); color: #fff; }
.btn-oscar:hover { background: var(--oscar-hover); border-color: var(--oscar-hover); }
.btn-sm { padding: 5px 11px; font-size: 13px; border-radius: 6px; }
.btn-ghost { border-color: transparent; background: transparent; color: var(--muted); }
.btn-ghost:hover { border-color: transparent; background: var(--panel-2); }
button:disabled { opacity: .45; cursor: not-allowed; }
button:disabled:hover { background: var(--panel); border-color: var(--line-strong); }

input, select, textarea {
  font: inherit; font-size: 14.5px; width: 100%; color: var(--text);
  background: var(--panel); border: 1px solid var(--line-strong);
  border-radius: 8px; padding: 9px 11px;
}
input, select, textarea { transition: border-color .12s, box-shadow .12s; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
input:disabled { background: var(--panel-2); color: var(--muted); }
label.field { display: grid; gap: 5px; font-size: 13px; font-weight: 600; color: var(--text-2); }
.grid-2 { display: grid; gap: 13px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* ================================================================ estados */
.st { display: inline-flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 580; white-space: nowrap; }
.st::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
.st.overdue { color: var(--overdue); }
.st.warn    { color: var(--warn); }
.st.ok      { color: var(--ok); }
/* "sin registro" es falta de informacion, no una alarma: punto hueco y menos
   peso, para que no compita con lo que si esta vencido. */
.st.unknown { color: var(--muted); font-weight: 520; }
.st.unknown::before { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }
.st.off     { color: var(--muted); }
.st.off::before { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }

.tag {
  display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 20px;
  font-size: 12.5px; font-weight: 620; background: var(--none-bg); color: var(--none);
}
.tag.overdue { background: var(--overdue-bg); color: var(--overdue); }
.tag.warn    { background: var(--warn-bg);    color: var(--warn); }
.tag.ok      { background: var(--ok-bg);      color: var(--ok); }

/* ============================================================== resumen */
/* Un panel unico dividido por lineas finas, en lugar de cuatro tarjetas
   flotando sueltas. Se lee como una pieza pensada y no como piezas apiladas. */
.kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; box-shadow: var(--shadow); margin-bottom: 20px;
}
.kpi { background: var(--panel); padding: 15px 18px; display: block; transition: background .12s; }
a.kpi:hover { background: var(--panel-2); }
.kpi .n {
  font-size: 28px; font-weight: 660; letter-spacing: -.035em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.kpi .l { font-size: 13px; color: var(--muted); margin-top: 3px; font-weight: 540; }
.kpi.overdue .n { color: var(--overdue); }
.kpi.warn .n { color: var(--warn); }
.kpi.ok .n { color: var(--ok); }

/* ======================================================= lista de flota */
.fleet { display: grid; gap: 10px; }
.vrow {
  display: grid; align-items: center; gap: 16px;
  grid-template-columns: 92px minmax(150px, 1fr) 130px minmax(200px, 1.3fr) auto;
  padding: 12px 18px 12px 14px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  border-left: 4px solid var(--line-strong); box-shadow: var(--shadow);
}
.vrow { transition: box-shadow .14s, border-color .14s; }
.vrow:hover { border-color: var(--line-strong); box-shadow: var(--shadow-lift); }
.vrow.s-overdue { border-left-color: var(--overdue); }
.vrow.s-warn    { border-left-color: var(--warn); }
.vrow.s-ok      { border-left-color: var(--ok); }
.vrow.s-unknown { border-left-color: var(--line-strong); }
/* La furgoneta se levanta un pelo al pasar por encima: da la sensacion de que
   la fila es un objeto y no una linea de tabla. */
.vrow:hover { transform: translateY(-1px); }
.vrow .vname { font-size: 17px; font-weight: 660; letter-spacing: -.01em; }
.vrow .sub { font-size: 13.5px; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.vrow .big { font-size: 16px; font-weight: 620; font-variant-numeric: tabular-nums; }
.vrow .chev { color: var(--muted); }

@media (max-width: 900px) {
  .vrow {
    grid-template-columns: 76px 1fr auto;
    grid-template-areas: 'foto id chev' 'foto km km' 'next next next';
    gap: 4px 14px; row-gap: 8px;
  }
  .vrow > :nth-child(1) { grid-area: foto; }
  .vrow > :nth-child(2) { grid-area: id; }
  .vrow > :nth-child(3) { grid-area: km; }
  .vrow > :nth-child(4) { grid-area: next; }
  .vrow > :nth-child(5) { grid-area: chev; }
}

/* ============================================================== imagenes */
.vanimg { position: relative; display: block; }
.vanimg svg, .vanimg img { width: 100%; height: 100%; display: block; object-fit: contain; }
.vanimg img { position: absolute; inset: 0; }
.thumb { width: 92px; height: 56px; flex: none; }

/* La matricula es dato de apoyo: se lee como una chapa pequena, nunca como
   titulo. El nombre del modelo es lo que identifica la furgoneta de un vistazo. */
.plate {
  display: inline-block; white-space: nowrap;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  letter-spacing: .04em;
  font-size: 12px; font-weight: 600; color: var(--text-2);
  background: linear-gradient(180deg, #ffffff, var(--panel-2));
  border: 1px solid var(--line-strong);
  border-radius: 4px; padding: 2px 7px;
  box-shadow: 0 1px 0 rgba(16,24,40,.04);
}
.vname { font-weight: 650; letter-spacing: -.01em; }

.task-vehicle { display: inline-flex; align-items: center; gap: 7px; font-weight: 620; }
.task-vehicle:hover { color: var(--accent); }

.modal-sub { margin: -6px 0 0; font-size: 13.5px; color: var(--muted);
             display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.head .sub:has(.plate) { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }

/* ================================================================ tablas */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* min-width: antes de comprimir las columnas hasta romper palabras, la tabla
   se desborda y el contenedor la deja desplazar en horizontal. */
table { width: 100%; min-width: 780px; border-collapse: separate; border-spacing: 0; font-size: 14px; }
th, td { text-align: left; padding: 9px 14px; border-bottom: 1px solid var(--line); vertical-align: middle; }
th {
  position: sticky; top: 0; z-index: 1;
  font-size: 11.5px; font-weight: 620; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); background: var(--panel-2); white-space: nowrap;
  border-bottom-color: var(--line-strong);
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: #fafbfc; }
tbody tr.link { cursor: pointer; }

/* La celda de acciones no compite con el contenido: el boton se enciende al
   pasar por encima. Trece botones identicos en columna son ruido, no interfaz. */
td.acciones { text-align: right; width: 1%; white-space: nowrap; }
td.acciones button { opacity: .5; transition: opacity .12s; }
tr:hover td.acciones button, td.acciones button:focus-visible { opacity: 1; }

/* Un hueco vacio se tiene que leer como hueco, no como dato */
.vacio { color: var(--line-strong); }

/* Tablas que viven en una columna estrecha: sin ancho minimo, se apanan solas */
table.compacta { min-width: 0; }
table.compacta th, table.compacta td { padding: 8px 12px; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.nowrap, th.nowrap { white-space: nowrap; }
/* La matricula dentro de una tabla va en un <span>, no como clase del <td>:
   la chapa lleva borde propio y al aplicarla a la celda se comia la linea
   separadora de la fila. */

/* ================================================= ficha de vehiculo */
.vehicle { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 20px; align-items: start; }
@media (max-width: 1040px) { .vehicle { grid-template-columns: 1fr; } }

.photo {
  background: var(--panel-2); border-bottom: 1px solid var(--line);
  border-radius: var(--r) var(--r) 0 0; padding: 10px; display: grid; place-items: center;
}
/* 3:2 es la proporcion de las fotos del catalogo; la silueta se centra dentro. */
.photo .vanimg { width: 100%; aspect-ratio: 3 / 2; }
.spec { display: grid; grid-template-columns: auto 1fr; gap: 0; font-size: 14px; }
.spec dt { color: var(--muted); padding: 8px 16px 8px 0; border-bottom: 1px solid var(--line); white-space: nowrap; }
.spec dd { margin: 0; padding: 8px 0; border-bottom: 1px solid var(--line); text-align: right;
           font-variant-numeric: tabular-nums; font-weight: 560; }
.spec dt:last-of-type, .spec dd:last-of-type { border-bottom: 0; }

/* =================================================== lista de tareas */
.group-title { display: flex; align-items: baseline; gap: 10px; margin: 26px 0 10px; }
.group-title:first-child { margin-top: 0; }
.group-title h2 { font-size: 16px; }
.group-title .n { font-size: 13.5px; color: var(--muted); }
/* es el primer hijo de su bloque, pero no el primero de la pagina */
.grupo-plegable > summary.group-title { list-style: none; cursor: pointer; margin-top: 26px; }
.grupo-plegable > summary::-webkit-details-marker { display: none; }
.grupo-plegable > summary::after {
  content: ''; width: 7px; height: 7px; align-self: center; margin-left: 2px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg); transition: transform .15s;
}
.grupo-plegable[open] > summary::after { transform: rotate(45deg); }
.grupo-plegable > summary:hover h2 { color: var(--accent); }

.task { padding: 14px 18px; border-bottom: 1px solid var(--line); display: grid; gap: 8px; }
.task:last-child { border-bottom: 0; }
.task-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.task-name { font-weight: 590; font-size: 15px; }
.task-line { font-size: 14px; color: var(--text-2); }
.task-line b { color: var(--text); }
/* De que depende el plazo: kilometros o fecha. En gris y pequeno, porque es
   explicacion, no dato. */
.task-porque { font-size: 12.5px; font-weight: 560; color: var(--muted); margin-left: 9px; }

.task-sub { font-size: 13px; color: var(--muted); }
.bar { height: 5px; border-radius: 3px; background: var(--none-bg); overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--ok); }
.bar.warn > i { background: var(--warn); }
.bar.overdue > i { background: var(--overdue); }
.bar.unknown > i { background: var(--line-strong); }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 18px; overflow-x: auto; }
.tabs .corto { display: none; }
.tabs button {
  border: 0; background: transparent; border-radius: 0; color: var(--muted);
  border-bottom: 2px solid transparent; padding: 10px 14px; font-size: 14.5px; margin-bottom: -1px;
}
.tabs button:hover { background: transparent; color: var(--text); border-color: transparent; border-bottom-color: var(--line-strong); }
.tabs button.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 620; }
.punto-aviso {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-left: 6px;
  vertical-align: 2px; background: var(--overdue);
}

.filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.filters button.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

.empty { padding: 46px 18px; text-align: center; color: var(--muted); font-size: 14.5px; }
.empty strong { display: block; color: var(--text); font-size: 16px; margin-bottom: 6px; }

/* ================================================================= modal */
.modal {
  border: 0; padding: 0; border-radius: 12px; background: var(--panel); color: var(--text);
  width: min(580px, calc(100vw - 24px)); box-shadow: 0 24px 64px rgba(10,14,20,.25);
}
.modal::backdrop { background: rgba(16,22,30,.42); }
.modal form { padding: 22px; display: grid; gap: 16px; }

.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  background: var(--text); color: #fff; padding: 11px 18px; border-radius: 8px;
  font-size: 14.5px; z-index: 60; max-width: 90vw; box-shadow: 0 8px 28px rgba(0,0,0,.22);
}

.note { font-size: 13.5px; color: var(--text-2); background: var(--warn-bg);
        border-radius: 8px; padding: 11px 14px; }

/* ======================================================= puesta al dia */
.callout {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: var(--r); padding: 16px 18px; margin-bottom: 16px;
}
.callout > div { flex: 1; min-width: 220px; font-size: 14px; color: var(--text-2); }
.callout strong { display: block; color: var(--text); font-size: 15.5px; margin-bottom: 2px; }

.setup-list {
  max-height: min(46vh, 420px); overflow-y: auto;
  border: 1px solid var(--line); border-radius: 8px;
}
.setup-row {
  display: grid; grid-template-columns: 1fr 148px 104px; gap: 10px; align-items: center;
  padding: 10px 12px; border-bottom: 1px solid var(--line);
}
.setup-row:last-child { border-bottom: 0; }
.setup-row.pendiente { background: #fffdf6; }
.setup-name { font-size: 14px; font-weight: 560; }
.setup-row input { padding: 7px 9px; font-size: 13.5px; }
@media (max-width: 560px) {
  .setup-row { grid-template-columns: 1fr 1fr; grid-template-areas: 'name name' 'date km'; }
  .setup-row > :nth-child(1) { grid-area: name; }
}

/* Aviso de problema, frente al informativo azul de la puesta al dia. */
.callout.aviso { background: var(--overdue-bg); border-color: #f3c7c3; }
.callout.aviso strong { color: var(--overdue); }

.pasos { margin: 0; padding-left: 20px; font-size: 14.5px; }
.pasos li { margin-bottom: 7px; }
.pasos li:last-child { margin-bottom: 0; }

/* ============================== control de intervalos (km y/o fecha) */
.controles { display: grid; gap: 10px; }
.control-bloque {
  border: 1px solid var(--line-strong); border-radius: 9px; padding: 12px 14px;
  transition: opacity .12s, background .12s;
}
.control-bloque.apagado { background: var(--panel-2); opacity: .55; }
.control-cabecera {
  display: flex; align-items: center; gap: 9px;
  font-size: 14.5px; font-weight: 600; cursor: pointer; user-select: none;
}
.control-cabecera input { width: auto; margin: 0; accent-color: var(--accent); transform: scale(1.15); }
.control-bloque.apagado .control-cabecera { cursor: pointer; }
.control-campos { margin-top: 11px; }
.control-bloque.apagado .control-campos { display: none; }

/* campo con la unidad pegada, para no repetir "km" en la etiqueta */
.con-sufijo { position: relative; display: block; }
.con-sufijo input { padding-right: 46px; }
.con-sufijo span {
  position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  font-size: 13px; color: var(--muted); pointer-events: none;
}

/* vista previa de los escalones */
.previa {
  border: 1px dashed var(--line-strong); border-radius: 9px;
  padding: 12px 14px; background: var(--panel-2);
}
.previa-titulo { font-size: 14px; font-weight: 600; margin-bottom: 9px; }
.previa-linea {
  display: flex; align-items: center; gap: 10px;
  font-size: 13.5px; color: var(--text-2); padding: 3px 0;
}
.previa-linea .st { min-width: 108px; }
.previa-aviso { font-size: 13.5px; color: var(--warn); }

/* Marca de intervalo independiente: informativa, no una alarma. Va en el color
   de la marca para que se distinga de los colores de estado (verde/ámbar/rojo),
   que significan urgencia y no deben mezclarse con esto. */
.tag.propio {
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent-line);
  letter-spacing: .005em;
  padding: 3px 10px;
}
/* Va en un <span> dentro de la celda, nunca en el <td>: poner display:flex en
   una celda la saca del algoritmo de tablas y descuadra anchos y alturas de
   toda la fila. */
.nombre-tarea { display: inline-flex; align-items: center; gap: 9px; flex-wrap: wrap; }

/* ================================= resultado de probar una conexion */
.resultado { font-size: 13.5px; padding: 9px 12px; border-radius: 7px; }
.resultado.probando { background: var(--panel-2); color: var(--muted); }
.resultado.bien { background: var(--ok-bg); color: var(--ok); }
.resultado.mal { background: var(--overdue-bg); color: var(--overdue); }

.detalle { border-top: 1px solid var(--line); padding-top: 12px; }
.detalle summary {
  cursor: pointer; font-size: 13.5px; font-weight: 570; color: var(--accent);
  list-style: none; display: inline-flex; align-items: center; gap: 6px;
}
.detalle summary::-webkit-details-marker { display: none; }
.detalle summary::before { content: '+'; font-weight: 700; }
.detalle[open] summary::before { content: '−'; }

.kpi.activo { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Aviso de que la lista esta filtrada: sin esto, media lista escondida parece
   una lista corta. */
.filtro-activo {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  font-size: 13.5px; color: var(--text-2); margin-bottom: 10px;
}
.filtro-activo a { color: var(--accent); font-weight: 570; text-decoration: underline; }

/* Barra de filtros: buscador y desplegables con la misma altura y el mismo
   filo que los botones, para que se lea como una sola pieza y no como tres
   controles del sistema pegados. */
.filtro-texto, .filtro-select {
  font: inherit; font-size: 14px; font-weight: 530; height: 36px;
  padding: 0 12px; border-radius: 8px; color: var(--text);
  border: 1px solid var(--line-strong); background: var(--panel);
  transition: border-color .12s, box-shadow .12s;
}
/* A su tamaño, no a lo ancho de la pantalla: la regla general de los campos
   les ponia 100% y cada desplegable ocupaba una fila entera en el ordenador. */
.filtro-texto, .filtro-select { width: auto; max-width: 100%; }
.filtro-texto:hover, .filtro-select:hover { border-color: var(--muted); }
.filtro-texto:focus, .filtro-select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* El desplegable del sistema (gris, con sus flechitas dobles) rompe el conjunto:
   se quita y se pone una punta de flecha propia. */
.filtro-select {
  appearance: none; -webkit-appearance: none; padding-right: 32px; cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7480' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 13px;
}
.filtro-texto {
  min-width: 220px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7480' stroke-width='2.2' stroke-linecap='round'><circle cx='11' cy='11' r='7'/><path d='m20 20-3.6-3.6'/></svg>");
  background-repeat: no-repeat; background-position: left 11px center; background-size: 14px;
  padding-left: 34px;
}
.filtro-texto::-webkit-search-cancel-button { cursor: pointer; }

/* Cabeceras que ordenan, como en una hoja de calculo. La flecha se ve siempre,
   apagada: si solo saliera en la columna ordenada, nadie sabria que las demas
   tambien se pueden pulsar. */
th.ordenable { cursor: pointer; user-select: none; white-space: nowrap; }
th.ordenable::after { content: ' ↕'; font-size: 11px; color: var(--line-strong); }
th.ordenable:hover { color: var(--text); }
th.ordenable:hover::after { color: var(--muted); }
th.ordenable.asc::after  { content: ' ↑'; color: var(--accent); }
th.ordenable.desc::after { content: ' ↓'; color: var(--accent); }

/* ============================================================ reparaciones */
.reps { display: grid; }
.rep {
  position: relative;
  display: grid; grid-template-columns: 116px minmax(0,1fr) auto;
  gap: 18px; align-items: center;
  padding: 16px 20px 16px 23px;
  border-bottom: 1px solid var(--line);
  transition: background .12s;
}
.rep:last-child { border-bottom: 0; }
.rep:hover { background: var(--panel-2); }
.rep.sin-foto { grid-template-columns: minmax(0,1fr) auto; }

/* Filo de color con la prisa que lleva: la lista entera se lee de un vistazo
   sin pararse a mirar una sola etiqueta. */
.rep::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--line-strong);
}
.rep.p-alta::before   { background: var(--overdue); }
.rep.p-normal::before { background: var(--warn); }
.rep.hecho::before    { background: var(--ok); }
.rep.hecho .rep-titulo b { color: var(--text-2); font-weight: 600; }
.rep.hecho .rep-foto { opacity: .7; }

.rep-foto {
  display: block; width: 116px; height: 86px; border-radius: 10px; overflow: hidden;
  background: var(--panel-2); box-shadow: 0 0 0 1px var(--line);
  transition: box-shadow .12s, transform .12s;
}
.rep-foto:hover { box-shadow: 0 0 0 1px var(--accent-line), var(--shadow-lift); transform: translateY(-1px); }
.rep-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }

.rep-titulo { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.rep-titulo b { font-size: 15.5px; letter-spacing: -.014em; }
.rep-detalle { font-size: 13.5px; color: var(--text-2); margin-top: 5px; }
.rep-meta {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--muted); margin-top: 7px;
}
.rep-meta a { color: var(--text-2); font-weight: 570; }
.rep-meta a:hover { color: var(--accent); }
.rep-meta .sep { color: var(--line-strong); }
.rep-acciones { display: flex; gap: 8px; align-items: center; }

/* Enlace a un fichero guardado (una factura, un papel) */
/* Cada linea del resumen de Geotab: el estado a la izquierda y su explicacion al lado */
/* Separador entre las caracteristicas de serie y las añadidas */
tr.separador td {
  background: var(--panel-2); font-size: 12px; font-weight: 640; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted); padding-top: 9px; padding-bottom: 9px;
}

/* Caracteristica obligatoria que esta sin rellenar */
.spec dd.falta { color: var(--warn); font-weight: 600; }
.falta-aviso {
  font-size: 12.5px; font-weight: 600; color: var(--warn);
  background: var(--warn-bg); border-radius: 7px; padding: 7px 10px; margin-bottom: 10px;
}

.geo-linea { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; }
.geo-linea > .st { flex: none; min-width: 190px; }
.geo-linea > .small { color: var(--text-2); flex: 1; min-width: 220px; }

/* Botones de cada fila de catalogo */
.acciones-fila { display: inline-flex; gap: 6px; align-items: center; }
.btn-icono { padding: 5px 8px; line-height: 0; color: var(--muted); }
.btn-icono:hover { color: var(--overdue); border-color: #f3c7c3; background: var(--overdue-bg); }
/* Descripcion bajo el nombre, en dos lineas como mucho: el resto al abrirla */
.descripcion {
  font-size: 12.5px; color: var(--muted); font-weight: 450; margin-top: 2px; max-width: 46ch;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.doc {
  display: inline-flex; align-items: center; gap: 5px; margin-right: 10px;
  font-size: 13px; font-weight: 560; color: var(--accent);
}
.doc:hover { text-decoration: underline; }
.doc svg { flex: none; opacity: .8; }
td.docs { white-space: nowrap; }

@media (max-width: 720px) {
  .rep { grid-template-columns: 76px minmax(0,1fr); padding: 14px 14px 14px 17px; gap: 12px; }
  .rep.sin-foto { grid-template-columns: minmax(0,1fr); }
  .rep-foto { width: 76px; height: 60px; }
  .rep-acciones { grid-column: 1 / -1; }
  .rep-acciones button { flex: 1; }
  .filtro-texto, .filtro-select { width: 100%; }
  .filters { gap: 7px; }
}

/* ================================================== pantalla de entrada */
body.sin-sesion { background: var(--bg); }
.entrada { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.entrada-caja {
  width: min(400px, 100%); padding: 28px; display: grid; gap: 14px;
  box-shadow: var(--shadow-lift);
}
.entrada-marca { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.entrada-empresa {
  display: grid; justify-items: center; gap: 9px; text-align: center;
  padding: 18px 16px; border-radius: 10px; background: var(--panel);
  box-shadow: 0 0 0 1px var(--line);
}
.entrada-empresa img { display: block; max-width: 100%; max-height: 64px; object-fit: contain; }
.entrada-empresa span { font-size: 15px; font-weight: 640; color: var(--text); }
.entrada h1 { font-size: 19px; }
.entrada-sub { margin: -6px 0 4px; font-size: 13.5px; color: var(--muted); line-height: 1.5; }

.quien { font-weight: 600; color: var(--text-2); font-size: 13px; }
.side-foot { display: grid; gap: 4px; justify-items: start; }


/* ====================================== esqueleto mientras carga */
.hueso {
  background: linear-gradient(90deg, var(--panel-2) 25%, #eef0f4 37%, var(--panel-2) 63%);
  background-size: 400% 100%;
  border-radius: 5px;
  animation: hueso 1.3s ease infinite;
}
@keyframes hueso { from { background-position: 100% 50%; } to { background-position: 0 50%; } }
@media (prefers-reduced-motion: reduce) { .hueso { animation: none; } }

/* Las vistas entran con un desvanecido corto: sin el, cambiar de pantalla da
   un tirón brusco. Se respeta a quien pide menos movimiento en el sistema. */
#view > .body { animation: entra .16s ease-out; }
@keyframes entra { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { #view > .body { animation: none; } }

/* ================================================== impresión
   La lista de pendientes acaba en el taller, en papel. Sin esto sale la barra
   lateral, los botones y los colores de fondo gastando tinta. */
@media print {
  .side, .acciones, .filters, .callout, .tabs, .toast, button, .btn { display: none !important; }
  body { background: #fff; }
  .app { display: block; }
  .head { border-bottom: 2px solid #000; padding: 0 0 12px; }
  .body { padding: 12px 0 0; max-width: none; }
  .panel { border: 1px solid #999; box-shadow: none; break-inside: avoid; }
  .kpis { border: 1px solid #999; }
  table { min-width: 0; font-size: 11pt; }
  th { background: #eee !important; color: #000; }
  .st::before { box-shadow: inset 0 0 0 1.5px #000; background: transparent; }
  .vrow { break-inside: avoid; border: 1px solid #999; box-shadow: none; }
  a[href^="http"]::after { content: ' (' attr(href) ')'; font-size: 9pt; color: #555; }
}

/* ================================================ configuración */
.config-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 18px; align-items: start; }
.config-grid > * { min-width: 0; }
/* minmax(0, 1fr) y no 1fr: con 1fr la columna crece hasta lo que mida su
   contenido mas ancho y la pantalla entera se sale por la derecha. */
@media (max-width: 900px) { .config-grid { grid-template-columns: minmax(0, 1fr); } }
/* los datos de la cuenta: el correo largo se parte en vez de empujar */
.spec dd { overflow-wrap: anywhere; }
.config-grid h3 { margin-bottom: 2px; }

/* ============================ tablas que se convierten en fichas en el móvil
   Una tabla de cinco columnas en una pantalla de 375 px no se lee: obliga a
   arrastrar en horizontal para ver un dato. En móvil cada fila pasa a ser una
   ficha con su etiqueta delante de cada valor. */
@media (max-width: 620px) {
  /* !important: alguna tabla lleva su ancho minimo escrito en el HTML, y en
     tarjetas ese ancho solo empuja la tarjeta fuera de la pantalla. */
  table.apilable { min-width: 0 !important; display: block; }
  table.apilable thead { display: none; }
  table.apilable tbody, table.apilable td { display: block; width: auto; }
  /* Dos columnas: con un dato por linea, cada ficha ocupaba media pantalla y
     una lista de veinte tareas era un scroll sin fin. El primer dato hace de
     titulo y los botones van debajo, a lo ancho. */
  table.apilable tr {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 4px;
    border: 1px solid var(--line); border-radius: 10px;
    padding: 6px 2px; margin-bottom: 10px; background: var(--panel);
  }
  table.apilable td:first-child, table.apilable td.acciones,
  table.apilable td[colspan] { grid-column: 1 / -1; }
  table.apilable td:first-child { font-size: 15px; padding-bottom: 2px; }
  /* el primer dato ya es el titulo de la tarjeta: su etiqueta ("TAREA") sobra */
  table.apilable td:first-child::before { display: none; }

  /* Historial: la tarjeta la titula el trabajo, no la fecha; y la factura y el
     boton de borrar comparten fila en vez de ocupar cada uno la suya. */
  table.historial td:nth-child(2) { order: -1; grid-column: 1 / -1; font-size: 15px; }
  table.historial td:nth-child(2)::before { display: none; }
  table.historial td:first-child { grid-column: auto; font-size: 14px; }
  table.historial td.docs { grid-column: auto; }
  table.historial td.acciones { grid-column: auto; align-self: end; text-align: right; }

  /* En los formularios, los campos cortos de dos en dos: la ficha entera en
     una sola columna era una lista de treinta campos. */
  .modal .grid-2 { grid-template-columns: repeat(auto-fit, minmax(135px, 1fr)); }
  table.apilable tr:last-child { margin-bottom: 0; }
  table.apilable td { border: 0; padding: 6px 12px; text-align: left; }
  table.apilable td.num { text-align: left; }
  table.apilable td::before {
    content: attr(data-etiqueta);
    display: block; font-size: 11px; font-weight: 620; letter-spacing: .04em;
    text-transform: uppercase; color: var(--muted); margin-bottom: 2px;
  }
  table.apilable td:empty { display: none; }
}

/* ================================================================ móvil */
.head-acciones { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.solo-movil { display: none; }

/* Aviso para instalar la app, abajo y sin tapar lo importante */
.instalar-app {
  position: fixed; left: 12px; right: 12px; z-index: 50;
  bottom: calc(12px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 12px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 12px; box-shadow: 0 10px 34px rgba(16,24,40,.18);
}
.instalar-app img { border-radius: 10px; flex: none; }
.instalar-texto { flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.35; color: var(--text-2); }
.instalar-texto b:first-child { display: block; color: var(--text); font-size: 14.5px; }

/* En pantallas tactiles no hay "pasar el raton por encima" */
@media (hover: none) {
  td.acciones button { opacity: 1; }
  .vrow:hover { transform: none; }
}

@media (max-width: 900px) {
  /* Por debajo de 16 px, el iPhone amplia la pagina al tocar un campo y hay que
     deshacer el zoom a mano cada vez. */
  input, select, textarea, .filtro-texto, .filtro-select { font-size: 16px; }

  /* Con la app instalada la pagina ocupa toda la pantalla: sin esto la barra de
     arriba se mete bajo la muesca y la de abajo bajo la raya de inicio. */

  .head { flex-direction: column; align-items: stretch; gap: 12px; }
  .head .spacer { display: none; }
  .head-acciones > * { flex: 1 1 auto; justify-content: center; text-align: center; }

  .kpi { padding: 12px 14px; }
  .kpi .n { font-size: 24px; }
  .task { padding: 12px 14px; }
  .callout { padding: 14px; }
  .callout > .btn { width: 100%; text-align: center; }
  .tabs button { padding: 10px 11px; font-size: 14px; white-space: nowrap; }

  /* Las ventanas con formularios largos, casi a pantalla completa y con scroll */
  .modal { width: calc(100vw - 16px); max-height: calc(100dvh - 16px); overflow-y: auto; }
  .modal form { padding: 18px 16px calc(18px + env(safe-area-inset-bottom)); }

  .solo-movil { display: block; }
  table.apilable td.acciones { text-align: left; padding-top: 10px; }
  tr.separador td { border-radius: 8px; }
}

/* ============================================ revisión paso a paso */
.pasos-check { display: grid; gap: 10px; }
.paso { display: flex; align-items: flex-start; gap: 11px; font-size: 14px; }
.paso-marca {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; font-size: 12px; font-weight: 700; margin-top: 1px;
}
.paso.bien .paso-marca { background: var(--ok-bg); color: var(--ok); }
.paso.mal .paso-marca { background: var(--warn-bg); color: var(--warn); }

/* ============================ instrucciones de instalación por sistema */
.instrucciones { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.instrucciones h3 { margin-bottom: 8px; color: var(--text); font-size: 13.5px; }
.instrucciones .pasos { font-size: 13.5px; }
.instrucciones .tiny { margin: 8px 0 0; line-height: 1.5; }

/* ========================================= banco de pruebas de avisos */
.escenarios { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
.escenario {
  display: grid; gap: 9px; text-align: left; padding: 12px 13px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel);
}
.escenario:hover { border-color: var(--accent); background: var(--panel-2); }
.escenario-cabecera { display: block; }

/* Imitación de la notificación del sistema, para ver el texto tal como saldrá */
.escenario-vista {
  display: flex; align-items: flex-start; gap: 10px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 9px; padding: 9px 11px;
}
.escenario-vista img { border-radius: 6px; flex: none; }
.escenario-vista b { display: block; font-size: 13px; font-weight: 620; line-height: 1.3; }
.escenario-vista i {
  display: block; font-style: normal; font-size: 12.5px;
  color: var(--text-2); margin-top: 2px; line-height: 1.35;
}

/* =========================================== zona de acciones peligrosas
   Separada del resto y con su propio color: lo que borra cosas no puede estar
   pegado a lo que las guarda. */
.zona-peligro {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 6px; padding: 14px 16px;
  border: 1px solid #f0d3d0; border-radius: 9px; background: var(--overdue-bg);
}
.zona-peligro > div { flex: 1; min-width: 200px; }
.zona-peligro b { font-size: 14px; color: var(--overdue); }
.zona-peligro p { margin: 3px 0 0; font-size: 13px; color: var(--text-2); line-height: 1.45; }

.btn-peligro {
  background: var(--panel); border-color: #e2b3ae; color: var(--overdue); font-weight: 600;
}
.btn-peligro:hover { background: var(--overdue); border-color: var(--overdue); color: #fff; }
.btn-peligro:disabled:hover { background: var(--panel); border-color: #e2b3ae; color: var(--overdue); }

/* ================================== secciones plegables
   Lo que se lee una vez (instalación, revisión, pruebas) va plegado: si no,
   hay que bajar media pantalla para llegar a lo que se consulta a diario. */
.plegable {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); margin-bottom: 12px;
}
.plegable > summary {
  cursor: pointer; padding: 13px 16px; font-size: 15px; font-weight: 620;
  list-style: none; display: flex; align-items: center; gap: 9px;
  border-radius: var(--r);
}
.plegable > summary::-webkit-details-marker { display: none; }
.plegable > summary::before {
  content: ''; width: 7px; height: 7px; flex: none;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg); transition: transform .15s; margin-right: 2px;
}
.plegable[open] > summary::before { transform: rotate(45deg); }
.plegable > summary:hover { background: var(--panel-2); }
.plegable-cuerpo { padding: 4px 16px 16px; border-top: 1px solid var(--line); padding-top: 16px; }
.plegable-cuerpo > .panel { border: 0; box-shadow: none; }
.plegable-cuerpo > .panel > .panel-head { display: none; }
.plegable-cuerpo > .panel > .panel-body { padding: 0; }

/* sugerencia de errata en el correo de la pantalla de entrada */
.pista-correo { margin-top: -6px; font-size: 13px; color: var(--warn); }
.pista-correo button {
  border: 0; background: none; padding: 0; font: inherit; font-weight: 650;
  color: var(--accent); text-decoration: underline; cursor: pointer;
}

/* ==========================================================================
   MOVIL. Va al final a proposito: tiene que ganar a las reglas generales de
   cada componente, que estan repartidas por todo el fichero.
   ========================================================================== */
/* ============================================ barra de arriba y accion en el movil */
.barra-movil, .fab { display: none; }

/* Las caracteristicas de la ficha, plegables */
.ficha-plegable > summary {
  list-style: none; cursor: pointer; display: flex; align-items: baseline;
  justify-content: space-between; gap: 10px; padding: 2px 0;
}
.ficha-plegable > summary::-webkit-details-marker { display: none; }
.ficha-plegable > summary h3::after { content: ' ▾'; color: var(--muted); font-size: 11px; }
.ficha-plegable:not([open]) > summary h3::after { content: ' ▸'; }

@media (max-width: 900px) {
  /* Arriba: donde estas. La barra lateral no se usa en el movil. */
  .app .side { display: none; }
  .barra-movil {
    display: flex; align-items: center; gap: 8px;
    position: sticky; top: 0; z-index: 40; min-height: 54px;
    padding: calc(6px + env(safe-area-inset-top)) 14px 6px;
    background: rgba(255,255,255,.95); backdrop-filter: saturate(1.4) blur(12px);
    -webkit-backdrop-filter: saturate(1.4) blur(12px);
    border-bottom: 1px solid var(--line);
  }
  #barra-volver {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; margin-left: -8px; border-radius: 10px; color: var(--accent);
  }
  #barra-volver:active { background: var(--accent-soft); }
  .barra-logo { width: 26px; height: 26px; flex: none; }
  #barra-titulo {
    flex: 1; min-width: 0; font-size: 17px; font-weight: 660; letter-spacing: -.015em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  #barra-empresa .empresa { margin: 0; padding: 0; background: none; box-shadow: none; }
  #barra-empresa .empresa img { max-height: 24px; max-width: 90px; }
  #barra-empresa .empresa img + span { display: none; }

  /* La cabecera de cada pantalla se queda en lo imprescindible: el titulo ya
     esta arriba, los parrafos explicativos sobran en una pantalla pequeña, y
     la accion principal esta en el boton flotante. */
  .head { padding: 12px 16px; gap: 10px; }
  .head h1, .head .sub { display: none; }
  .head .sub:has(.plate) { display: flex; margin: 0; }
  .head-acciones .btn-primary { display: none; }
  .head:not(:has(.sub .plate)):not(:has(.head-acciones > :not(.btn-primary))) { display: none; }
  .body { padding: 14px 16px calc(150px + env(safe-area-inset-bottom)); }

  /* La accion principal, abajo a la derecha y a mano */
  .fab {
    display: flex; align-items: center; gap: 8px;
    position: fixed; right: 16px; bottom: calc(78px + env(safe-area-inset-bottom)); z-index: 44;
    height: 52px; padding: 0 20px 0 16px; border: 0; border-radius: 26px;
    background: var(--accent-vivid); color: #fff; font: inherit; font-size: 15px; font-weight: 640;
    box-shadow: 0 8px 24px rgba(14,124,142,.35), 0 2px 6px rgba(16,24,40,.12);
  }
  .fab:hover { background: var(--accent); }
  .fab:active { transform: scale(.97); }
  .fab { transition: opacity .15s, transform .15s; }
  .fab.apartado { opacity: 0; pointer-events: none; transform: translateY(10px); }
  .fab svg { width: 20px; height: 20px; }

  /* Panel: cifras en una fila, y los recuadros en una linea que se toca */
  .kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-bottom: 14px; }
  .kpi { padding: 10px 4px; text-align: center; }
  .kpi .n { font-size: 21px; }
  .kpi .l { font-size: 11px; line-height: 1.2; }
  .callout-compacto { padding: 10px 12px; gap: 10px; flex-wrap: nowrap; margin-bottom: 10px; }
  .callout-compacto > div { font-size: 0; min-width: 0; }
  .callout-compacto strong { font-size: 14px; margin: 0; }
  .callout-compacto > .btn { width: auto; flex: none; padding: 6px 12px; font-size: 13px; }

  /* Filtros todos a la vista, repartidos en las filas que hagan falta. En una
     tira deslizable los ultimos quedaban fuera y nadie sabia que estaban. */
  .filters { flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
  .filters > button { flex: 1 1 auto; min-height: 40px; padding: 6px 10px; }
  .filters > span[style*="flex:1"] { display: none; }
  /* los desplegables y el buscador a su ancho, estirados hasta llenar la fila:
     dos cortos comparten fila y uno largo ("Ordenar: las más urgentes
     primero") se lleva la suya en vez de salir cortado */
  .app .filters .filtro-select, .app .filters .filtro-texto {
    flex: 1 1 auto; width: auto; min-width: 0; height: 40px; font-weight: 500; letter-spacing: -.02em;
  }
  .app .filters .filtro-texto { min-width: 150px; }
  /* menos relleno: a media pantalla, "Furgoneta: todas" no cabia entero */
  .app .filters .filtro-select { padding: 0 24px 0 10px; background-position: right 8px center; }

  /* Ficha de la furgoneta: sin el nombre repetido, foto mas baja y pestañas
     pegadas arriba al bajar */
  .ficha-nombre { display: none; }
  .photo .vanimg { height: 150px; }
  /* Pestañas de la ficha: todas a la vista, en dos filas de tres. En una tira
     habia que arrastrar de lado para encontrar Historial o Documentacion. */
  .tabs {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px;
    overflow: visible; border-bottom: 0; margin: 0 0 14px; padding: 0;
  }
  .tabs button {
    margin: 0; padding: 9px 2px; font-size: 12.5px; letter-spacing: -.01em; white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
    border: 1px solid var(--line); border-radius: 10px; background: var(--panel);
  }
  .tabs button:hover { border-color: var(--line); background: var(--panel); }
  .tabs button.active {
    background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent);
  }
  /* el punto de papeles caducados, en la esquina: al final del texto se cortaba */
  .tabs button { position: relative; }
  .tabs .punto-aviso { position: absolute; top: 5px; right: 5px; margin: 0; }
  .tabs .largo { display: none; }
  .tabs .corto { display: inline; }
  .task-sub {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }

  /* Los contadores de la ficha llevan su propio ancho escrito en el HTML */
  .vehicle .kpis { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }

  /* "Marcar hecho" como boton redondo con ✓ arriba a la derecha de cada tarea.
     Con su texto, en cuanto el nombre era un poco largo saltaba a otra linea y
     cada tarea quedaba descolocada de una forma distinta. */
  .task { position: relative; padding-right: 64px; }
  .task-top .btn-sm[data-done] {
    position: absolute; right: 14px; top: 12px;
    width: 40px; height: 40px; padding: 0; border-radius: 20px;
    font-size: 0; display: grid; place-items: center;
    border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent);
  }
  .task-top .btn-sm[data-done]::before { content: '✓'; font-size: 19px; font-weight: 700; }
  .task-top > span[style*="flex:1"] { display: none; }

  /* Tarjetas de reparacion: la papelera a su tamaño y sin puntos colgando al
     partirse la linea de datos */
  .rep-acciones .btn-icono { flex: 0 0 48px; }
  .rep-meta .sep { display: none; }
  .rep-meta { gap: 2px 10px; }

  /* El boton de la pestaña ya esta en el flotante */
  #tab-body > .row:has(.btn-primary) { display: none; }
}

/* ================================================================ ajustes */
.ajustes-grupo {
  font-size: 12px; font-weight: 660; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); margin: 22px 4px 8px;
}
.ajustes-grupo:first-child { margin-top: 4px; }
.ajustes-lista { overflow: hidden; max-width: 640px; }
.ajuste {
  display: flex; align-items: center; gap: 14px; padding: 14px 16px;
  border-bottom: 1px solid var(--line); transition: background .12s;
}
.ajuste:last-child { border-bottom: 0; }
.ajuste:hover, .ajuste:active { background: var(--panel-2); }
.ajuste-icono {
  width: 38px; height: 38px; border-radius: 10px; flex: none; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent);
}
.ajuste-icono svg { width: 20px; height: 20px; }
.ajuste-texto { flex: 1; min-width: 0; }
.ajuste-texto b { display: block; font-size: 15.5px; color: var(--text); }
.ajuste-texto span { display: block; font-size: 13px; color: var(--muted); line-height: 1.35; margin-top: 1px; }
.ajuste-flecha { color: var(--line-strong); flex: none; }
.ajustes-pie {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  max-width: 640px; margin-top: 24px; padding: 0 4px; font-size: 13.5px; color: var(--muted);
}

/* Plegables que solo se pliegan en el movil: en el ordenador van abiertos y su
   cabecera no se puede pulsar, asi que se ven igual que antes. */
/* 14 px: los 12 del hueco del formulario mas los 2 del margen del titulo */
.plegable-movil > summary { list-style: none; pointer-events: none; margin-bottom: 14px; }
.plegable-movil > summary::-webkit-details-marker { display: none; }
.geo-credenciales > summary { display: none; }

/* ==========================================================================
   MOVIL, segunda pasada: ventanas de formulario, Geotab, Notificaciones,
   Configuracion y las pestañas de la ficha que faltaban.
   ========================================================================== */
@media (max-width: 900px) {
  /* Guardar y Cancelar siempre a la vista, pegados abajo. En Editar ficha
     habia que bajar treinta campos para llegar a ellos. */
  .modal form > .row.between:has([data-cerrar]) {
    position: sticky; bottom: 0; z-index: 3; margin: 0 -16px;
    padding: 12px 16px !important; background: var(--panel);
  }
  /* "Volver al general" en su linea y debajo Cancelar y Guardar a los lados,
     no amontonados a la izquierda */
  .modal form > .row.between > .row { flex: 1 1 100%; flex-wrap: nowrap; justify-content: space-between; }
  .modal .btn, .modal .btn-primary, .modal .btn-ghost, .modal .btn-peligro { min-height: 44px; }
  /* altura fija: el de fecha salia un poco mas alto que el de al lado */
  .modal input:not([type=checkbox]):not([type=radio]):not([type=file]), .modal select { height: 46px; box-sizing: border-box; }
  /* De dos en dos, si una etiqueta ocupa dos lineas ("Renovación del seguro")
     su campo y el de al lado quedaban a distinta altura y uno estirado. Pegados
     abajo, los dos campos van a la par. */
  .modal .grid-2 > label.field { align-content: end; }
  /* al saltar al siguiente campo, que no quede debajo de la barra de Guardar */
  .modal { scroll-padding-bottom: 84px; }
  /* el campo de fecha del iPhone no encoge solo y se salia de su columna */
  .modal input[type=date] { min-width: 0; padding-left: 10px; padding-right: 8px; }

  /* Poner al dia: sin una caja con su propio scroll dentro de la ventana, que
     con el dedo no se sabia cual de los dos se movia. Y a 16 px, que por
     debajo el iPhone amplia la pagina al tocar el campo. */
  .setup-list { max-height: none; overflow: visible; }
  .setup-row input { font-size: 16px; padding: 0 8px; }
  /* la fecha necesita mas sitio que los km: a medias, en un movil de 360 px
     el año se metia debajo del icono del calendario */
  .setup-row {
    grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: 8px;
    grid-template-areas: 'name name' 'date km';
  }
  .setup-row > :nth-child(1) { grid-area: name; }

  /* Una columna para lo que no cabe de dos en dos: las caracteristicas con
     etiqueta y ayuda quedaban descuadradas, y el correo no se leia. */
  .modal .grid-campos, .modal .grid-2:has(input[type=email]) { grid-template-columns: minmax(0, 1fr); }

  /* Datos en dos columnas fijas: con la etiqueta a su ancho natural, el valor
     ("sin configurar", la fecha) se partia en dos lineas. */
  .spec { grid-template-columns: minmax(0, 1fr) auto; }
  .spec dt { white-space: normal; padding-right: 12px; }
  .spec dd { max-width: 60vw; }

  /* La cifra de al lado del titulo, debajo si no cabe, no apretando el titulo */
  .panel-head { flex-wrap: wrap; row-gap: 2px; }

  /* Botones de las tarjetas al tamaño del dedo */
  table.apilable .btn-sm { min-height: 40px; padding-left: 14px; padding-right: 14px; }
  table.apilable .btn-icono { min-width: 44px; }
  table.historial td.acciones { text-align: right; }
  /* Un dato vacio ("—") en una tarjeta es una fila entera para no decir nada */
  table.apilable td:has(> .vacio:only-child) { display: none; }

  /* Reparaciones: el titulo siempre en su linea. Con un aviso corto se ponia al
     lado y con uno largo debajo, y cada tarjeta quedaba de una forma. */
  .rep-titulo b { flex-basis: 100%; }
  .rep-acciones button { min-height: 40px; }

  .explica { display: none; }
  /* "Sin registro" ya lo dice la linea de debajo ("Nunca se ha registrado") */
  .task-top > .st.unknown { display: none; }

  /* Parametros de la ficha: nombre y estado arriba, intervalo y Editar debajo.
     La tabla de cuatro columnas se salia y Estado y Editar no se veian. */
  table.parametros, table.parametros tbody { display: block; }
  table.parametros thead { display: none; }
  table.parametros tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; align-items: center;
    padding: 11px 14px; border-bottom: 1px solid var(--line);
  }
  table.parametros tr:last-child { border-bottom: 0; }
  table.parametros td { display: block; padding: 0; border: 0; width: auto; white-space: normal; }
  table.parametros td:nth-child(1) { grid-area: 1 / 1; font-weight: 590; }
  table.parametros td:nth-child(2) { grid-area: 2 / 1; }
  table.parametros td:nth-child(3) { grid-area: 1 / 2; text-align: right; }
  table.parametros td:nth-child(4) { grid-area: 2 / 2; text-align: right; }
  table.parametros .btn-sm { min-height: 36px; padding: 0 14px; }

  /* Configuracion: cambiar la contraseña, plegado y que se pueda desplegar */
  .plegable-movil > summary {
    pointer-events: auto; cursor: pointer; margin: 0; padding: 12px 0 2px;
    display: flex; align-items: center; justify-content: space-between;
  }
  .plegable-movil > summary::after, .geo-credenciales > summary::after {
    content: ''; width: 8px; height: 8px; margin-right: 4px;
    border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
    transform: rotate(-45deg); transition: transform .15s;
  }
  .plegable-movil[open] > summary::after, .geo-credenciales[open] > summary::after { transform: rotate(45deg); }
  .plegable-movil[open] > summary { margin-bottom: 12px; }

  /* Geotab: los datos de acceso plegados cuando ya esta conectada */
  .geo-credenciales > summary {
    display: flex; align-items: center; justify-content: space-between;
    list-style: none; cursor: pointer; font-size: 14.5px; font-weight: 600;
    padding: 2px 0 12px; border-bottom: 1px solid var(--line);
  }
  .geo-credenciales > summary::-webkit-details-marker { display: none; }
  .geo-credenciales[open] > summary { margin-bottom: 14px; }
  .detalle summary { padding: 6px 0; }
  #form-geotab > .row > span[style*="flex:1"] { display: none; }
  #form-geotab > .row > button { flex: 1 1 40%; min-height: 44px; }
  .geo-credenciales:not([open]) ~ .note { display: none; }
  .geo-credenciales:not([open]) + .spec { margin-top: 4px !important; }
  /* lo que va bien no necesita explicacion; lo que falta, si */
  .geo-linea:has(> .st.ok) > .small { display: none; }
  .geo-linea > .st { min-width: 0; }
  .geo-linea > .small { min-width: 0; flex-basis: 100%; }
  /* Tarjeta de cada furgoneta: el codigo del aparato no le dice nada a nadie,
     y Emparejar al lado del estado en vez de en una fila suelta */
  table.geo-vehiculos td:nth-child(2) { display: none; }
  table.geo-vehiculos td:last-child { align-self: center; text-align: right; }

  /* Notificaciones */
  .instrucciones:has(> .mio) > :not(.mio) { display: none; }
  .callout:has(> #instalar[hidden]) { display: none; }
  table.escalones thead { display: none; }
  table.escalones td { padding: 8px 10px; }
  #activar { flex: 1 1 100%; }
  .row:has(> #probar) { flex: 1 1 100%; }
  .row:has(> #probar) > button { flex: 1; min-height: 40px; }
}

/* ==========================================================================
   MOVIL: el aviso de instalar la app flota abajo, justo donde va el boton
   de accion y el final de cada pantalla. Mientras esta a la vista, el boton se
   quita (vuelve al pulsar "Ahora no") y el final de la pagina deja sitio para
   poder leer lo ultimo sin que quede debajo del aviso.
   ========================================================================== */
@media (max-width: 900px) {
  .app:has(> .instalar-app:not([hidden])) .fab { display: none; }
  .app:has(> .instalar-app:not([hidden])) .body {
    padding-bottom: calc(240px + env(safe-area-inset-bottom));
  }
}

/* Con el teclado abierto (Android encoge la pagina para dejarle sitio), el
   menu de abajo y el boton de accion se comerian la mitad de lo que queda.
   Mientras se escribe en un campo de la pagina, fuera. */
@media (max-width: 900px) {
  .app:has(#view :is(input:not([type=checkbox]):not([type=radio]), textarea):focus) :is(.tabbar, .fab) {
    display: none;
  }
}
