/* ============================================================
   Tracker EC — estilos responsivos (mobile-first, sin frameworks)
   ============================================================ */
:root {
  --bg: #f4f6f9;
  --surface: #ffffff;
  --surface-2: #f0f3f7;
  --border: #dbe1ea;
  --text: #1c2430;
  --text-soft: #5b6675;
  --primary: #1f6feb;
  --primary-ink: #ffffff;
  --ok: #1a7f47;
  --ok-bg: #e4f5ec;
  --warn: #b25b00;
  --warn-bg: #fbeddb;
  --late: #c22b2b;
  --late-bg: #fbe4e4;
  --pend: #64708a;
  --pend-bg: #eceff4;
  --radius: 10px;
  --shadow: 0 1px 3px rgba(16, 24, 40, .08), 0 1px 2px rgba(16, 24, 40, .06);
  --font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f141b; --surface: #171e27; --surface-2: #1e2632; --border: #2a3441;
    --text: #e7ecf3; --text-soft: #9aa7b8; --primary: #4d90fe; --pend-bg: #232c39;
    --ok-bg: #12301f; --warn-bg: #3a2a13; --late-bg: #3a1c1c; --pend: #9aa7b8;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

/* ---------------- Header ---------------- */
.app-header {
  position: sticky; top: 0; z-index: 20;
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem;
  padding: .6rem 1rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow);
}
.brand { display: flex; align-items: center; gap: .5rem; }
.brand h1 { font-size: 1.1rem; margin: 0; letter-spacing: .2px; }
.brand h1 span { color: var(--primary); }
.brand-dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: linear-gradient(135deg, var(--primary), #7db1ff);
}
.tabs { display: flex; gap: .25rem; flex: 1 1 auto; flex-wrap: wrap; }
.tab {
  border: 1px solid transparent; background: transparent; color: var(--text-soft);
  padding: .4rem .8rem; border-radius: 8px; cursor: pointer; font-size: .92rem;
  font-family: inherit;
}
.tab:hover { background: var(--surface-2); color: var(--text); }
.tab[aria-current="page"] {
  background: var(--primary); color: var(--primary-ink); font-weight: 600;
}
.user-box { display: flex; align-items: center; gap: .5rem; margin-left: auto; }
.env-badge {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .5px;
  padding: .15rem .5rem; border-radius: 999px; background: var(--pend-bg);
  color: var(--text-soft); border: 1px solid var(--border);
}
.user-name { font-size: .85rem; color: var(--text-soft); max-width: 40vw;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------- Dev bar ---------------- */
.devbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  padding: .5rem 1rem; background: var(--surface-2);
  border-bottom: 1px solid var(--border); font-size: .85rem;
}
.devbar input {
  padding: .35rem .5rem; border: 1px solid var(--border); border-radius: 7px;
  background: var(--surface); color: var(--text); font-family: inherit;
}
.devbar-hint { color: var(--text-soft); }
.devbar code { background: var(--surface); padding: .05rem .3rem; border-radius: 4px; }

/* ---------------- Layout ---------------- */
.app-main { padding: 1rem; max-width: 1200px; margin: 0 auto; }
.toolbar {
  display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-start;
  margin-bottom: 1rem;
}
.field { display: flex; flex-direction: column; gap: .25rem; }
.field label { font-size: .78rem; color: var(--text-soft); font-weight: 600; }
.field select, .field input {
  padding: .5rem .6rem; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text); font-family: inherit; font-size: .92rem;
  min-width: 12rem;
}
.section-title { display: flex; align-items: center; gap: .5rem; margin: 0 0 .75rem; }
.section-title h2 { margin: 0; font-size: 1.05rem; }
.count-pill {
  font-size: .78rem; color: var(--text-soft); background: var(--surface-2);
  padding: .1rem .5rem; border-radius: 999px; border: 1px solid var(--border);
}

/* ---------------- Buttons ---------------- */
.btn {
  padding: .5rem .9rem; border-radius: 8px; border: 1px solid var(--primary);
  background: var(--primary); color: var(--primary-ink); cursor: pointer;
  font-family: inherit; font-size: .9rem; font-weight: 600;
}
.btn:hover { filter: brightness(1.05); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-ghost { background: transparent; color: var(--primary); }
.btn-sm { padding: .3rem .55rem; font-size: .8rem; font-weight: 500; }
/* Los botones de hito son los que mas se pulsan en toda la jornada, asi que
   se les da objetivo tactil propio en vez de heredar los 26px de `.btn-sm`
   (muy por debajo de los 44px de referencia). */
.btn-hito {
  border-color: var(--border); background: var(--surface); color: var(--text);
  min-height: 2.4rem; font-size: .85rem;
}
.btn-hito.done { border-color: var(--ok); background: var(--ok-bg); color: var(--ok); }

/* ---------------- Cards / tables ---------------- */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow); padding: 1rem;
  margin-bottom: 1rem;
}
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.grid { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.grid th, table.grid td {
  text-align: left; padding: .55rem .6rem; border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

/* --- Seguimientos: una TARJETA por servicio, no una fila de tabla ---------
   Historia de este bloque, porque explica por que ya no hay anchos fijos:

   La tabla tenia seis columnas y cinco con ancho declarado (5+11+11+5.5+10 =
   42.5rem ≈ 680px). Con `max-width:1200px` a los hitos les quedaban ~500px
   para CUATRO fases, o sea ~118px cada una. En ese ancho no cabe "Llegada a
   agencia" ni el par boton+✎ (69+24px), asi que todo lo demas fue una cadena
   de compensaciones sobre esa unica restriccion: titulos y botones recortados
   con "...", la tipografia bajada a 10.5px, `gap` de fila en 0, margenes de
   1.5px entre el veredicto y su causal, y la tipologia abreviada a "C15".

   El presupuesto de ancho era el problema, no el padding. Una tarjeta le da a
   cada servicio el ancho completo, asi que las fases caben sin recortes y la
   letra vuelve a un tamaño legible. */
.svc-lista { display: flex; flex-direction: column; gap: .6rem; }

.svc {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: .75rem .9rem;
  display: flex; flex-direction: column; gap: .5rem;
}
/* Servicio con un incumplimiento sin justificar: se marca en el borde para
   que se localice sin leer, que es lo que hace el chip "N sin causal". */
.svc-deuda { border-left: 3px solid var(--warn); }

/* --- Modo compacto -------------------------------------------------------
   La tarjeta arregla el apiñado pero cuesta alto: ~210-255px cada una, o sea
   unas 4 por pantalla y ~5 pantallas de scroll en un dia de 20 servicios. Para
   un tracker que BARRE el dia buscando lo que le falta, eso es un problema
   distinto del que se arreglo.

   El compacto no vuelve a apretar la letra —esa fue la causa del problema
   original—: quita lo que solo se necesita cuando ya estas trabajando UN
   servicio (los descriptivos y el pie), y aprieta los espacios en blanco.
   Los botones de hito y el select de causal se quedan en su tamaño. */
.svc-lista.compacto { gap: .35rem; }
.compacto .svc { padding: .5rem .7rem; gap: .3rem; }
/* Los descriptivos (tipologia, tipo de carga, ubicacion) no deciden nada del
   cumplimiento: son de contexto y se consultan al abrir Detalles. */
.compacto .veh-datos { display: none; }
.compacto .svc-meta { padding-bottom: .3rem; }
/* El pie se revela al pasar por encima: "Ver paradas" y "Detalles" son de
   cuando ya elegiste un servicio, no del barrido. */
.compacto .svc-pie {
  max-height: 0; overflow: hidden; opacity: 0;
  transition: max-height .12s ease, opacity .12s ease;
}
.compacto .svc:hover .svc-pie,
.compacto .svc:focus-within .svc-pie,
.compacto .svc-abierto .svc-pie {
  max-height: 4rem; opacity: 1;
}
.compacto .fase-cabecera { margin-bottom: .2rem; }
.compacto .fases { gap: .3rem .75rem; }
.compacto .fase-control { margin-top: .2rem; }
.compacto .fase-causal-caja { margin-top: .2rem; }
.svc-abierto { border-color: var(--primary); }

/* Cabecera: identidad a la izquierda, estado a la derecha. */
.svc-cab {
  display: flex; align-items: baseline; gap: .5rem 1rem; flex-wrap: wrap;
}
.svc-ident {
  display: flex; align-items: baseline; gap: .5rem .75rem; flex-wrap: wrap;
  flex: 1 1 auto; min-width: 0;
}
/* El ID del servicio es el ancla de lectura: es lo unico que sube de tamaño. */
.svc-id { font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.svc-placa { font-size: .95rem; font-weight: 600; }
.svc-conductor { font-size: .88rem; color: var(--text-soft); }
.svc-orden { font-size: .8rem; color: var(--text-soft); }
.svc-estado { flex: none; }

/* Segunda linea: ruta editable + descriptivos del vehiculo. */
.svc-meta {
  display: flex; align-items: flex-start; gap: .5rem 1rem; flex-wrap: wrap;
  padding-bottom: .5rem; border-bottom: 1px solid var(--border);
}
.veh-datos { display: flex; flex-wrap: wrap; gap: .25rem .5rem; align-items: baseline; }
.veh-dato {
  font-size: .8rem; color: var(--text-soft);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; padding: .1rem .5rem;
}

.svc-pie {
  display: flex; gap: .5rem; flex-wrap: wrap; align-items: center;
  padding-top: .15rem;
}

/* Paradas: van DENTRO de la tarjeta, hundidas sobre el fondo para leerse como
   "detalle de lo de arriba" y no como otro servicio. */
.svc-paradas {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; padding: .6rem .7rem; margin-top: .15rem;
}
.paradas-tit {
  font-size: .8rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; color: var(--text-soft); margin-bottom: .5rem;
  display: flex; gap: .5rem; flex-wrap: wrap; align-items: baseline;
}

/* Barra de filtros del panel de seguimientos. Los selects de orden y sentido
   y el campo de día no necesitan las 12rem del mínimo general: con ese ancho
   la barra se estiraba a lo largo de toda la pantalla. El buscador de cliente
   sí lo conserva, porque ahí se escriben nombres largos. */
.toolbar { gap: .5rem .6rem; margin-bottom: .6rem; }
.toolbar .field select,
.toolbar .field input[type="date"] { min-width: 0; width: auto; }
.toolbar .field-cliente input { min-width: 14rem; }
table.grid th {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .4px;
  color: var(--text-soft); background: var(--surface-2); position: sticky; top: 0;
}
table.grid tr:hover td { background: var(--surface-2); }

/* Estado badges */
.badge {
  display: inline-block; font-size: .74rem; font-weight: 600; padding: .12rem .5rem;
  border-radius: 999px; white-space: nowrap;
}
.badge.pendiente { background: var(--pend-bg); color: var(--pend); }
.badge.en_curso { background: var(--warn-bg); color: var(--warn); }
.badge.completado { background: var(--ok-bg); color: var(--ok); }
.badge.late { background: var(--late-bg); color: var(--late); }

.hito-pair { display: inline-flex; align-items: stretch; }
.hito-pair .btn-hito:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
/* El ✎ estaba en 24px de ancho y pegado sin separacion al boton que escribe la
   hora actual de forma irreversible: en tactil se confundian dos acciones con
   consecuencias muy distintas. Ancho minimo real y un borde que las separa. */
.hito-pair .hito-edit {
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  border-left: 1px solid var(--border);
  min-width: 2.2rem; padding-left: .45rem; padding-right: .45rem;
  color: var(--text-soft);
}
.hito-pair .hito-edit:hover { color: var(--primary); }

/* Buscador */
.search-bar { margin-bottom: .75rem; }
.search-input {
  width: 100%; max-width: 420px; padding: .5rem .7rem;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text); font-family: inherit; font-size: .92rem;
}
.search-input:focus { outline: 2px solid var(--primary); outline-offset: 1px; }
/* Buscador y filtro de hub en la misma fila: los dos recortan lo ya descargado.
   `wrap` para que en pantallas angostas el combo baje en vez de desbordar. */
.filtros-locales { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
/* El combo se ajusta a su contenido en vez de robarle ancho al buscador. */
.filtros-locales select.search-input { width: auto; max-width: 260px; }

/* Chip de incumplimientos sin justificar. Ámbar y no rojo: es una tarea
   pendiente del tracker, no un error del sistema — el mismo código de color
   que el "sin causal" de cada fase, para que se lean como lo mismo. */
.chip-alerta {
  border-color: #e0b341; background: #fff7e6; color: #9a6700;
  white-space: nowrap; font-weight: 600;
}
.chip-alerta:hover { filter: brightness(.97); }
/* Filtro puesto: se invierte para que se vea que la tabla está recortada y
   que ese botón es la forma de volver atrás. */
.chip-alerta.activo {
  background: #9a6700; border-color: #9a6700; color: #fff;
}
@media (prefers-color-scheme: dark) {
  .chip-alerta { background: #3a2a13; border-color: #6b5220; color: #e0b341; }
  .chip-alerta.activo { background: #e0b341; border-color: #e0b341; color: #241a06; }
}
.muted { color: var(--text-soft); }
.nowrap { white-space: nowrap; }

/* Forms (admin) */
.form-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: .75rem; margin-bottom: 1rem;
}
textarea {
  width: 100%; padding: .5rem .6rem; border: 1px solid var(--border);
  border-radius: 8px; background: var(--surface); color: var(--text);
  font-family: inherit; font-size: .9rem; resize: vertical; min-height: 3rem;
}

/* States */
.empty, .loading, .error {
  padding: 2rem 1rem; text-align: center; color: var(--text-soft);
}
.error { color: var(--late); }

/* Toast */
.toast {
  position: fixed; left: 50%; bottom: 1.2rem; transform: translateX(-50%);
  background: var(--text); color: var(--surface); padding: .6rem 1rem;
  border-radius: 8px; box-shadow: var(--shadow); z-index: 50; font-size: .88rem;
  max-width: 90vw;
}
.toast.error { background: var(--late); color: #fff; }
.toast.ok { background: var(--ok); color: #fff; }

/* Modal */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(10, 15, 22, .55);
  display: flex; align-items: center; justify-content: center; z-index: 40; padding: 1rem;
}
.modal {
  background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow);
  width: 100%; max-width: 460px; padding: 1.2rem; border: 1px solid var(--border);
}
.modal h3 { margin: 0 0 .8rem; }
.modal .field { margin-bottom: .7rem; }
.modal-actions { display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1rem; }

/* ============================================================
   Responsive: tabla -> tarjetas en pantallas angostas
   ============================================================ */
/* ============================================================
   Paradas de un servicio (fila desplegable)
   ============================================================ */

.btn-paradas { white-space: nowrap; }
/* Abierto = estado "activo" en versión clara: hay que reponer el fondo, porque
   `.btn` viene con `background: var(--primary)` y dejar solo `color: primary`
   pintaba azul sobre azul y el texto desaparecía. */
.btn-paradas.abierto {
  background: var(--surface); border-color: var(--primary); color: var(--primary);
}

.paradas { display: flex; flex-direction: column; gap: .5rem; }
.paradas-ayuda {
  margin: 0 0 .2rem; font-size: .85rem; color: var(--text-soft);
}

/* Cada parada es una tarjeta ancha: nombre y lugar a la izquierda, los dos
   botones de hora en el centro y el motivo al final. Una sola línea de lectura
   por parada, sin tabla anidada. */
.parada {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: .6rem .75rem;
}
.parada-info { flex: 1 1 14rem; min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.parada-titulo { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.parada-lugar { color: var(--text-soft); font-size: .9rem; word-break: break-word; }
.parada-horas { display: flex; gap: .4rem; flex-wrap: wrap; }
/* Los botones de hora son el elemento que más se pulsa: objetivo táctil amplio. */
.parada-horas .btn-hito { min-height: 2.1rem; }

@media (max-width: 760px) {
  .app-main { padding: .75rem; }

  /* En móvil cada parada se apila: título arriba, botones abajo a lo ancho,
     que es como se usa con una mano en la calle. */
  .parada { flex-direction: column; align-items: stretch; gap: .5rem; }
  .parada-horas { display: grid; grid-template-columns: 1fr 1fr; gap: .4rem; }
  .parada-horas .hito-pair { width: 100%; }
  .parada-horas .btn-hito:first-child { flex: 1 1 auto; }
}

@media (max-width: 760px) {
  .field select, .field input { min-width: 0; width: 100%; }
  .toolbar .field { flex: 1 1 100%; }
  /* Apilados no hay nada que desalinear: el hint vuelve al flujo para que no
     se solape con el campo siguiente. */
  .field-hint { position: static; }
  .field-cliente { padding-bottom: 0; }

  table.grid, table.grid thead, table.grid tbody,
  table.grid th, table.grid td, table.grid tr { display: block; }
  table.grid thead { display: none; }
  table.grid tr {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); margin-bottom: .75rem; padding: .35rem .6rem;
    box-shadow: var(--shadow);
  }
  table.grid td {
    border: none; padding: .35rem 0; display: flex; justify-content: space-between;
    gap: 1rem; align-items: center;
  }
  table.grid td::before {
    content: attr(data-label); font-size: .72rem; text-transform: uppercase;
    letter-spacing: .4px; color: var(--text-soft); font-weight: 600; flex: 0 0 auto;
  }
  /* Las cuatro fases en columnas no caben en un teléfono: ahí se dejan
     envolver a dos, y el separador vertical pasa a horizontal. */
  .fases { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: .6rem .7rem; }
  .fase { padding-left: 0; border-left: none; padding-top: .5rem; border-top: 1px solid var(--border); }
  .fase:first-child { padding-top: 0; border-top: none; }
  /* Envueltas, la última fase ya no es un caso especial. */
  .fase:last-child .fase-botones { flex-direction: row; }
  /* La tarjeta ya es el contenedor: en móvil solo se aprieta el padding. */
  .svc { padding: .6rem .7rem; }
}

/* ============================================================
   Pantalla de login (login.html)
   ============================================================ */
.login-body {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 1.25rem;
  background:
    radial-gradient(1000px 500px at 50% -10%, rgba(31, 111, 235, .13), transparent 70%),
    var(--bg);
}
.login-card {
  width: 100%; max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 2rem 1.6rem;
  text-align: center;
}
.login-brand { justify-content: center; margin-bottom: .25rem; }
.login-brand h1 { font-size: 1.5rem; }
.login-sub {
  margin: 0 0 1.6rem; color: var(--text-soft); font-size: .88rem;
}

.login-alert {
  text-align: left; font-size: .84rem; line-height: 1.4;
  padding: .6rem .75rem; border-radius: 8px; margin-bottom: 1rem;
  background: var(--late-bg); color: var(--late);
  border: 1px solid color-mix(in srgb, var(--late) 30%, transparent);
}
.login-alert.ok {
  background: var(--ok-bg); color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 30%, transparent);
}
.login-alert.warn {
  background: var(--warn-bg); color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
}

/* Botón Google — sigue las guías de marca (fondo blanco, logo a color) */
.btn-google {
  display: flex; align-items: center; justify-content: center; gap: .65rem;
  width: 100%; padding: .7rem 1rem;
  background: #ffffff; color: #1f1f1f;
  border: 1px solid #dadce0; border-radius: 8px;
  font-family: inherit; font-size: .95rem; font-weight: 500;
  text-decoration: none; cursor: pointer;
  transition: background .15s ease, box-shadow .15s ease;
}
.btn-google:hover { background: #f7f8f8; box-shadow: var(--shadow); }
.btn-google:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.btn-google.is-disabled { opacity: .5; cursor: not-allowed; }
.g-logo { width: 18px; height: 18px; flex: 0 0 auto; }

.login-hint {
  margin: .9rem 0 0; font-size: .78rem; color: var(--text-soft);
}

/* Bloque de bypass dev (oculto cuando el SSO es obligatorio) */
.login-dev { margin-top: 1.4rem; text-align: left; }
.login-sep {
  display: flex; align-items: center; gap: .6rem;
  margin-bottom: .9rem; color: var(--text-soft); font-size: .74rem;
  text-transform: uppercase; letter-spacing: .5px;
}
.login-sep::before, .login-sep::after {
  content: ""; flex: 1; height: 1px; background: var(--border);
}
.login-dev label {
  display: block; font-size: .78rem; color: var(--text-soft); margin-bottom: .3rem;
}
.login-dev input {
  width: 100%; padding: .5rem .6rem; font-family: inherit; font-size: .9rem;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text);
}
.login-dev-btn { width: 100%; margin-top: .6rem; }

.btn-logout { margin-left: .25rem; }

/* Combo de cliente con búsqueda (input + datalist) */
.field-cliente { flex: 1 1 260px; min-width: 220px; }
.field-cliente input { width: 100%; }

/* El datalist no debe participar del layout: si ocupa una celda del flex
   column, el desplegable del navegador se ancla desplazado respecto al input. */
.field datalist { display: none; }

/* El hint se saca del flujo para que no empuje el input hacia arriba y
   desalinee este campo respecto a los demás del toolbar. */
.field-hint {
  position: absolute; top: 100%; left: 0; right: 0;
  margin-top: .25rem;
  font-size: .72rem; color: var(--text-soft); line-height: 1.3;
}
.field-cliente { position: relative; padding-bottom: .2rem; }

/* --- Ruta: se muestra y se edita en la misma celda --- */
/* El borde ya no es transparente: era un boton que solo se revelaba al pasar
   el raton, o sea invisible en tactil y para quien no lo descubriera por azar.
   Y la ruta decide si el servicio se evalua, asi que es de lo mas importante
   que hay que poder corregir. */
.ruta-btn {
  display: inline-flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  text-align: left; max-width: 100%;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: .35rem .55rem; cursor: pointer; font: inherit; color: inherit;
  min-height: 2.2rem;
}
.ruta-btn:hover { border-color: var(--primary); background: var(--surface-2); }
.ruta-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
/* El lapiz avisa de que esto se edita, sin gastar una etiqueta. */
.ruta-btn::after { content: "✎"; color: var(--text-soft); font-size: .85rem; }
.ruta-linea { line-height: 1.35; word-break: break-word; display: inline; }
.ruta-linea + .ruta-linea::before { content: ""; }

/* Marca de que este servicio NO se va a evaluar. Sin esto el fallo es
   silencioso: se registran los hitos y los KPIs quedan vacios sin aviso. */
.ruta-flag {
  display: inline-block; margin-top: .25rem;
  font-size: .68rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .02em; padding: .1rem .35rem; border-radius: 4px;
}
.ruta-falta     { background: var(--late-bg); color: var(--late); }
.ruta-sin-tramo { background: var(--warn-bg); color: var(--warn); }

/* Lo que falta de la caracterizacion aparte de la ruta (tipologia, tipo de
   carga). Va en tono apagado y no como .ruta-flag: no impide que el servicio
   se evalue, solo que quede completo, y compite con la marca de "sin tramo"
   que si es bloqueante. */
.ruta-pendiente {
  display: block; width: 100%;
  font-size: .7rem; font-style: italic;
}

/* El destino queda deshabilitado hasta elegir el origen: la lista de destinos
   depende de el, y ofrecer combinaciones inexistentes solo genera errores. */
.modal select:disabled {
  background: var(--surface-2);
  color: var(--text-soft); cursor: not-allowed;
}
/* Las opciones son nombres largos (BEC_CLIE_FAVORITA-SUPERMAXI_...): que el
   select pueda crecer en vez de recortarlos. */
.modal .field select { width: 100%; }

/* --- Fases del viaje, agrupadas como en la planilla de la operacion ---
   Cada fase lleva su hora tope arriba y su veredicto abajo. Se usa grid con
   columnas de ancho FIJO a proposito: con flex-wrap, registrar un hito hacia
   crecer el boton (de "Salida" a "¹3 12:25") y eso reacomodaba toda la
   fila, que era lo que se veia desordenado. */
/* Valor de catálogo dado de baja. Se sigue mostrando (para poder reactivarlo)
   pero atenuado, para que no se confunda con los que el tracker sí puede
   elegir hoy. */
.fila-inactiva { opacity: .55; }

/* Ubicación actual: es la única que cambia durante el viaje, así que se
   distingue del resto en vez de mezclarse con los datos fijos. */
.veh-ubicacion {
  color: var(--primary);
  border-color: var(--primary);
  overflow-wrap: anywhere;
}

.fases {
  display: grid;
  /* Cuatro columnas, una por fase, como la planilla que la operacion ya usa.
     Dentro de la tarjeta hay ancho completo (~1100px en vez de los ~500px que
     dejaba la tabla), asi que cada fase recibe ~260px: sitio de sobra para
     "Llegada a agencia" y para el par boton+✎ sin recortar nada.

     `minmax(0, 1fr)` y no `1fr` a secas: sin el mínimo en 0, una columna de
     grid no baja del ancho de su contenido. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: .5rem .75rem;
  align-items: start;
}
/* Separador entre fases: la franja se lee como cuatro bloques y no como una
   masa de botones. Es un borde de 1px, no una caja: no compite con la tarjeta. */
.fase {
  min-width: 0;
  padding-left: .7rem;
  border-left: 1px solid var(--border);
}
.fase:first-child { padding-left: 0; border-left: none; }
/* El título y el tope viven en la misma línea ("SALIDA · 08:00") en vez de
   apilarse: son dos datos cortos y ocupaban dos renglones por fase, o sea
   ocho renglones por servicio solo de encabezados. */
/* Ya no se recorta con ellipsis: en la tarjeta cabe el nombre entero, y un
   rotulo cortado ("Llegada a age…") obligaba a pasar el raton para leerlo. */
.fase-titulo {
  font-size: .78rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; color: var(--text-soft);
  display: inline;
}
.fase-tope {
  font-size: .8rem; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
  display: inline;
}
/* Separador entre el nombre de la fase y su hora tope. */
.fase-tope::before { content: " · "; color: var(--border); }
/* La línea que contiene a ambos. */
.fase-cabecera { line-height: 1.3; margin-bottom: .35rem; }
.fase-botones { display: flex; flex-wrap: wrap; gap: .35rem; }
/* Ancho minimo estable: el boton no salta al pasar de "Salida" a "✓ 12:25".
   Sin recorte por ellipsis: en la tarjeta cabe "Llegada planta" entero. */
.fase-botones .hito-pair .btn-hito:first-child {
  min-width: 5.2rem; text-align: center;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* La fase Retorno lleva DOS hitos (inicio y llegada a planta). En una columna
   estrecha no caben lado a lado, así que se apilan a propósito en vez de
   dejar que el wrap los acomode de forma impredecible. Es la última fase, así
   que crecer hacia abajo ahí no descuadra las otras tres. */
.fase:last-child .fase-botones { flex-direction: column; align-items: stretch; }
/* El veredicto es el dato que decide si hay trabajo pendiente: sube de tamaño
   respecto al resto de la fase en vez de quedar por debajo del badge de estado. */
.fase-control {
  margin-top: .35rem; font-size: .82rem; font-weight: 700;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}
.fase-control.a-tiempo { color: var(--ok); }
.fase-control.tarde    { color: var(--late); }

/* El motivo, bajo el veredicto que lo produjo, y AHORA EDITABLE ahi mismo.
   Antes era texto: la pantalla decia "sin causal" pero para ponerla habia que
   ir a "Detalles", un formulario de siete campos. Cuatro clics para un dato ya
   señalado en pantalla. */
.fase-causal-caja { margin-top: .3rem; }
.fase-causal-sel {
  width: 100%; max-width: 100%;
  font-family: inherit; font-size: .8rem;
  padding: .3rem .4rem;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text-soft);
}
.fase-causal-sel:focus { outline: 2px solid var(--primary); outline-offset: 1px; }
/* Falta la causal: es una tarea pendiente del tracker, no un dato neutro.
   Mismo ambar que el chip "N sin causal", para que se lean como lo mismo. */
.fase-causal-sel.falta {
  border-color: var(--warn); background: var(--warn-bg);
  color: var(--warn); font-weight: 600;
}
.fase-na { opacity: .55; }

/* Hito que no aplica porque el viaje no tiene retorno. Se deja visible (no se
   oculta) para que se entienda que es "no aplica", no "falta registrarlo". */
.hito-na {
  opacity: .45; cursor: default; border-style: dashed;
  background: none; pointer-events: none;
}

/* Casilla con explicacion debajo (ej. "este viaje no tiene retorno"). */
.check-linea {
  display: flex; align-items: flex-start; gap: .5rem;
  margin: .2rem 0 1rem; cursor: pointer; line-height: 1.4;
}
.check-linea input { margin-top: .18rem; flex: none; }
.check-linea strong { display: block; font-size: .88rem; font-weight: 600; }
.check-linea small { display: block; color: var(--text-soft); font-size: .78rem; }

/* Aviso de tramo dentro del modal de Ruta. */
.modal-ayuda {
  margin: -.3rem 0 1rem; font-size: .82rem; color: var(--text-soft);
  line-height: 1.45;
}
.tramo-aviso {
  margin: .2rem 0 1rem; padding: .6rem .7rem; border-radius: 6px;
  font-size: .82rem; line-height: 1.5; border: 1px solid transparent;
}
.tramo-aviso strong { display: block; margin-bottom: .15rem; }
.tramo-ok    { background: var(--ok-bg); border-color: var(--ok); color: var(--ok); }
.tramo-warn  { background: var(--warn-bg); border-color: var(--warn); color: var(--warn); }
.tramo-muted { background: var(--surface-2); border-color: var(--border); color: var(--text-soft); }

/* Administración de clientes habilitados */
.hint-block {
  margin: -.4rem 0 1rem; font-size: .82rem; color: var(--text-soft);
  max-width: 70ch; line-height: 1.45;
}
.code-soft {
  font-size: .8rem; color: var(--text-soft);
  background: var(--surface-2); padding: .1rem .35rem; border-radius: 4px;
}
.inp-orden { width: 5rem; min-width: 0 !important; }
.row-inactiva { opacity: .55; }

/* Panel de seguimientos: pistas de ordenamiento */
.orden-aviso {
  font-size: .8rem; color: var(--warn); background: var(--warn-bg);
  border: 1px solid color-mix(in srgb, var(--warn) 28%, transparent);
  border-radius: 8px; padding: .5rem .7rem; margin-bottom: .75rem; line-height: 1.4;
}

/* ============================================================
   Dashboard de reportes
   ============================================================ */
:root { --muted-fill: #cbd3de; }
@media (prefers-color-scheme: dark) { :root { --muted-fill: #3a4553; } }

/* --- KPIs: número grande, sin gráfico (es un dato único) --- */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: .75rem;
  margin-bottom: .75rem;
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .75rem .9rem;
  box-shadow: var(--shadow);
}
.kpi-label { color: var(--text-soft); font-size: .8rem; }
.kpi-value { font-size: 1.9rem; font-weight: 600; line-height: 1.1; }
.kpi-pct { color: var(--text-soft); font-size: .85rem; }

.chart-title { margin: 0 0 .15rem; font-size: 1rem; font-weight: 600; }
.small { font-size: .8rem; }

/* --- Pie charts (fieles al reporte original del cliente) --- */
.pie-wrap {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: .6rem;
}
.pie-svg { flex: 0 0 auto; overflow: visible; }
/* Separador de 2px entre porciones: el color de la tarjeta hace de espaciador. */
.pie-slice { stroke: var(--surface); stroke-width: 2px; }
/* La etiqueta va sobre el color, no junto a él: blanco con sombra funciona
   sobre cualquier tono de la paleta, claro u oscuro. */
.pie-label {
  fill: #fff;
  font-size: 15px;
  font-weight: 600;
  paint-order: stroke;
  stroke: rgba(0, 0, 0, .35);
  stroke-width: 3px;
}

.legend { display: flex; flex-wrap: wrap; gap: .9rem; font-size: .82rem; color: var(--text-soft); }
.legend-col {
  flex-direction: column;
  gap: .3rem;
  flex: 1 1 150px;
  min-width: 0;
}
.legend-item { display: inline-flex; align-items: center; gap: .4rem; min-width: 0; }
.legend-dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.legend-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.legend-val {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  font-weight: 600;
  flex: 0 0 auto;
}

/* Fila de dos gráficos (cumplimiento + responsables), como el original. */
.chart-grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: .75rem;
}

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

@media (max-width: 560px) {
  /* En pantalla estrecha la leyenda pasa debajo del pie, no al lado. */
  .pie-wrap { justify-content: center; }
  .legend-col { flex-basis: 100%; }
}

/* ============================================================
   Portal de clientes: login local, cambio de contraseña, cuentas
   ============================================================ */
.login-local { display: grid; gap: .35rem; text-align: left; }
.login-local label { font-size: .82rem; color: var(--text-soft); }
.login-local input {
  width: 100%;
  padding: .55rem .7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-size: .95rem;
}
.login-local .login-dev-btn { margin-top: .5rem; }

/* Contraseña temporal: se muestra una sola vez, así que destaca. */
.pw-aviso { border-left: 3px solid var(--warn); }
.pw-box {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  margin-top: .5rem;
}
.pw-code {
  font-family: ui-monospace, "Cascadia Code", "Courier New", monospace;
  font-size: 1.15rem;
  letter-spacing: .06em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .45rem .7rem;
  user-select: all;
}
