/* =========================================================================
   LONGBRIDGE DRIVER HUB — ESTILOS
   -------------------------------------------------------------------------
   La referencia no es una app de oficina: es un TABLERO DE DESPACHO. Se usa
   con guantes, al sol y a las 3 de la madrugada dentro de una cabina, y lo
   que se mira son datos —horas, códigos, números de camión, puestos en la
   cola—, no párrafos.

   Decisiones del sistema, para que quien lo toque después no las deshaga:

   TIPOGRAFÍA
     Barlow           texto y botones. Es una grotesca derivada de la
                      señalética de transporte: encaja con el oficio y no es
                      la fuente por defecto de nadie.
     Barlow Condensed rótulos en versalitas. Condensada porque los rótulos de
                      un tablero van en mayúsculas y ocupan mucho en pantalla
                      de celular.
     JetBrains Mono   TODO lo que sea un dato: cronómetros, horas, códigos,
                      camiones. Cifras de ancho fijo, para que una columna de
                      números no baile y para que el despachador compare un
                      código contra WhatsApp sin equivocarse.

   COLOR
     El navy de Longbridge se queda: es la identidad. Los grises se inclinan
     hacia el navy en vez de ser grises puros — un gris puro se lee como "no
     lo eligió nadie".
     NO hay un segundo color de acento a propósito. En una herramienta de
     despacho el color YA significa algo (verde disponible, ámbar taller, rojo
     alerta); meter un acento decorativo encima le robaría fuerza a la única
     señal que importa. El carácter lo pone la tipografía, no un tercer tono.

   GEOMETRÍA
     Radios pequeños y líneas de un píxel en vez de sombras difusas. Una
     esquina muy redondeada y una sombra suave leen como app de consumo; un
     instrumento se lee mejor con cantos rectos.

   MODO OSCURO
     La empresa opera 24 h. Un conductor que abre esto a las 3 AM dentro de la
     cabina no debería recibir una pantalla blanca en la cara. Todo el color
     pasa por tokens, así que el tema oscuro solo los redefine.
   ========================================================================= */

:root {
  /* --- Tipografía --- */
  --font-ui:   "Barlow", "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
  --font-cond: "Barlow Condensed", "Barlow", "Segoe UI", system-ui, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* --- Azul navy Longbridge --- */
  --navy-900: #05121F;
  --navy-800: #0B2545;
  --navy-700: #123A6B;
  --navy-600: #1B4E8F;
  --navy-500: #2C6FB8;
  --navy-100: #DEE9F6;
  --navy-050: #F0F5FB;

  /* Texto sobre el navy */
  --on-navy: #FFFFFF;
  --on-navy-soft: #C8D9ED;

  /* --- Semáforo de estados. Es la única señal de color de la interfaz --- */
  --ok: #146B44;         --ok-bg: #E2F1E9;      --ok-line: #B2DCC5;
  --warn: #9A5B08;       --warn-bg: #FBEFDC;    --warn-line: #EBD1A2;
  --danger: #A9271F;     --danger-bg: #FAE6E4;  --danger-line: #EDBEB9;
  --info: #1B4E8F;       --info-bg: #DEE9F6;    --info-line: #B9D2EC;
  --off: #55606E;        --off-bg: #EAEDF1;     --off-line: #D2D8E0;

  /* Relleno de los botones sólidos. Va aparte del color semántico: ese se
     aclara en modo oscuro para leerse como TEXTO, y si se usara también como
     fondo dejaría el texto blanco del botón encima ilegible. */
  --ok-solid: #146B44;
  --warn-solid: #8A5107;
  --danger-solid: #A9271F;
  --navy-ink: #0B2545;

  /* La cabecera y su marca son navy en ambos temas: color fijo a propósito,
     porque un token que voltea le baja el contraste al blanco de encima. */
  --brand-mark: #1B4E8F;

  /* --- Neutros, inclinados hacia el navy --- */
  --ink: #101C2B;
  --ink-soft: #52616F;
  --ink-faint: #5F7085;
  --line: #CFD9E4;
  --line-soft: #E3EAF2;
  --bg: #EFF3F8;
  --surface: #FFFFFF;
  --surface-2: #F6F9FC;

  /* Bloque de estado del conductor. Colores planos y saturados: es lo que
     tiene que leerse de un vistazo, al sol y con el celular en la mano. */
  --hero-turno:     #10603E;
  --hero-available: #0B2545;
  --hero-maint:     #7E5210;
  --hero-incident:  #8C2E26;
  --hero-off:       #3D4855;

  /* --- Geometría: cantos cortos, líneas finas, sombra casi ausente --- */
  --radius: 8px;
  --radius-sm: 5px;
  --shadow: 0 1px 1px rgba(11, 37, 69, .05), 0 1px 3px rgba(11, 37, 69, .06);
  --shadow-lg: 0 12px 44px rgba(5, 18, 31, .34);

  --tap: 52px;              /* altura mínima táctil */
  --maxw: 1240px;
}

/* -------------------------------------------------------------------------
   MODO OSCURO — solo redefine tokens; ningún componente sabe que existe.
   ------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root {
    --navy-900: #04101C;
    --navy-800: #0A1F3A;
    --navy-700: #17406F;
    --navy-600: #3C7AC4;
    --navy-500: #5B95D6;
    --navy-100: #16304C;
    --navy-050: #112538;

    --on-navy: #F2F7FC;
    --on-navy-soft: #9DB8D8;

    --ok: #58BC8C;         --ok-bg: #10291E;      --ok-line: #1F5039;
    --warn: #DFA155;       --warn-bg: #2C2011;    --warn-line: #58411C;
    --danger: #E5837A;     --danger-bg: #2E1714;  --danger-line: #5C2F29;
    --info: #6FA5DE;       --info-bg: #14293F;    --info-line: #23486E;
    --off: #93A2B3;        --off-bg: #1B2431;     --off-line: #2E3A48;

    --ok-solid: #146B44;
    --warn-solid: #8A5107;
    --danger-solid: #9E2A22;
    --navy-ink: #C3D8EF;

    --ink: #E4ECF4;
    --ink-soft: #9DAEC0;
    --ink-faint: #97ABC0;
    --line: #24344A;
    --line-soft: #1B2939;
    --bg: #0A121C;
    --surface: #111C29;
    --surface-2: #16232F;

    /* En oscuro se bajan, no se invierten: el bloque tiene que seguir siendo
       el elemento más brillante de la pantalla sin deslumbrar de noche. */
    --hero-turno:     #0C3F2B;
    --hero-available: #10243C;
    --hero-maint:     #533718;
    --hero-incident:  #5C231D;
    --hero-off:       #28313C;

    --shadow: 0 1px 1px rgba(0,0,0,.4), 0 1px 3px rgba(0,0,0,.35);
    --shadow-lg: 0 14px 50px rgba(0,0,0,.7);
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 17px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  /* Las cifras nunca bailan: una columna de horas tiene que quedar cuadrada
     aunque cambien los dígitos cada segundo. */
  font-variant-numeric: tabular-nums;
}

h1, h2, h3 { margin: 0 0 .5rem; line-height: 1.18; letter-spacing: -.011em; text-wrap: balance; }
h1 { font-size: 1.6rem; font-weight: 700; }
h2 { font-size: 1.25rem; font-weight: 600; }
h3 { font-size: 1.05rem; font-weight: 600; }
p { margin: 0 0 .75rem; }

.hidden { display: none !important; }
.muted { color: var(--ink-soft); }
.small { font-size: .875rem; }
.tiny { font-size: .8rem; }
.bold { font-weight: 700; }
.center { text-align: center; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.mono { font-variant-numeric: tabular-nums; font-family: var(--font-mono); }

/* Rótulo de tablero: versalitas condensadas. Es el recurso que separa el
   NOMBRE de un dato de su VALOR sin gastar una línea ni un color. */
.rotulo {
  font-family: var(--font-cond);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .085em;
  text-transform: uppercase;
  color: var(--ink-faint);
  line-height: 1.2;
}
.grow { flex: 1; }
.row { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.stack { display: grid; gap: 1rem; }
.mt { margin-top: 1rem; }
.mb { margin-bottom: 1rem; }

/* ============================ ENCABEZADO ============================== */

.app-header {
  background: var(--navy-800);
  color: var(--on-navy);
  padding: .55rem 1rem;
  position: sticky;
  top: 0;
  z-index: 40;
  border-bottom: 1px solid rgba(255,255,255,.10);
}
.app-header-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: .75rem;
}
.brand { display: flex; align-items: center; gap: .6rem; min-width: 0; }
.brand-mark {
  width: 40px; height: 40px; flex: 0 0 40px;
  border-radius: 9px;
  background: var(--brand-mark);
  display: grid; place-items: center;
  font-weight: 700; font-size: 1.05rem; letter-spacing: -.5px;
  border: 1px solid rgba(255,255,255,.22);
}
.brand-text { min-width: 0; overflow: hidden; }
.brand-name {
  font-weight: 700; font-size: 1.05rem; line-height: 1.1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand-sub { font-size: .74rem; color: var(--on-navy-soft); line-height: 1.2; white-space: nowrap; }

.header-actions { margin-left: auto; display: flex; align-items: center; gap: .45rem; min-width: 0; }

.chip-user {
  display: flex; flex-direction: column; align-items: flex-end;
  line-height: 1.15; margin-right: .2rem; min-width: 0;
}
.chip-user b {
  font-size: .92rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 42vw;
}
.chip-user span { font-size: .74rem; color: var(--on-navy-soft); white-space: nowrap; }

.icon-btn {
  min-height: 42px; min-width: 42px;
  border: 1px solid rgba(255,255,255,.25);
  background: rgba(255,255,255,.08);
  color: var(--on-navy);
  border-radius: 9px;
  font-size: .88rem; font-weight: 600;
  cursor: pointer;
  padding: 0 .7rem;
  transition: background .15s;
}
.icon-btn:hover { background: rgba(255,255,255,.2); }

/* ============================== LAYOUT ================================ */

.page { max-width: var(--maxw); margin: 0 auto; padding: 1rem 1rem 4rem; }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.1rem;
}
.card + .card { margin-top: 1rem; }
/* El título va sobre una línea de un píxel en vez de flotar: en un tablero,
   una regla separa bloques mejor que un hueco, y no gasta alto de pantalla. */
.card-title {
  display: flex; align-items: center; gap: .5rem;
  font-size: 1.02rem; font-weight: 600;
  letter-spacing: -.008em;
  margin: 0 0 .85rem;
  padding-bottom: .55rem;
  border-bottom: 1px solid var(--line-soft);
}
.card-title .muted { font-weight: 400; font-size: .85rem; }

/* ============================== BOTONES =============================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: var(--tap);
  padding: .6rem 1.15rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: var(--navy-800);
  color: var(--on-navy);
  font-size: 1rem; font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  transition: filter .15s, transform .05s;
}
.btn:hover { filter: brightness(1.12); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; filter: none; }
.btn-block { width: 100%; }
.btn-ghost { background: var(--surface); color: var(--navy-ink); border-color: var(--line); }
.btn-ghost:hover { background: var(--navy-050); filter: none; }
.btn-ok { background: var(--ok-solid); }
.btn-danger { background: var(--danger-solid); }
.btn-warn { background: var(--warn-solid); }
.btn-sm { min-height: 38px; padding: .3rem .7rem; font-size: .85rem; border-radius: 8px; }
.btn-lg { min-height: 72px; font-size: 1.25rem; font-weight: 700; border-radius: var(--radius); }

/* Botones grandes de acción (check-in / check-out) */
.btn-action {
  width: 100%;
  min-height: 84px;
  font-size: 1.35rem;
  font-weight: 700;
  border-radius: var(--radius);
  flex-direction: column;
  gap: .1rem;
  letter-spacing: .2px;
}
.btn-action small { font-size: .8rem; font-weight: 500; opacity: .9; letter-spacing: 0; }

/* Rejilla de botones de estado */
.status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: .7rem;
}
.status-btn {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: .12rem;
  min-height: 76px;
  padding: .7rem .85rem;
  border-radius: var(--radius-sm);
  border: 2px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.status-btn:hover { background: var(--navy-050); border-color: var(--navy-500); }
.status-btn b { font-size: 1.02rem; }
.status-btn span { font-size: .8rem; color: var(--ink-soft); }
.status-btn.is-on { border-color: var(--navy-600); background: var(--navy-100); }
/* Bloqueado pero NO deshabilitado: sigue siendo pulsable a propósito, para
   que al tocarlo el conductor lea por qué no puede y qué hacer en su lugar.
   Un botón muerto no explica nada. */
.status-btn.is-locked { opacity: .55; border-style: dashed; }
.status-btn.is-locked:hover { background: var(--surface); border-color: var(--line); }
.status-btn .dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; margin-right: .35rem; }

/* =========================== ESTADOS / PILLS ========================== */

.pill {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .22rem .65rem;
  border-radius: 999px;
  font-size: .82rem; font-weight: 700;
  white-space: nowrap;
  border: 1px solid transparent;
}
.pill .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.pill-working    { background: var(--ok-bg);     color: var(--ok);     border-color: var(--ok-line); }
.pill-available  { background: var(--info-bg);   color: var(--info);   border-color: var(--info-line); }
.pill-off        { background: var(--off-bg);    color: var(--off);    border-color: var(--off-line); }
.pill-maintenance{ background: var(--warn-bg);   color: var(--warn);   border-color: var(--warn-line); }
.pill-incident   { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-line); }
.pill-inactive   { background: var(--off-bg);    color: var(--off);    border-color: var(--off-line); }
.pill-late       { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-line); }
.pill-on_time    { background: var(--ok-bg);     color: var(--ok);     border-color: var(--ok-line); }
.pill-early      { background: var(--warn-bg);   color: var(--warn);   border-color: var(--warn-line); }
.pill-missing    { background: var(--off-bg);    color: var(--off);    border-color: var(--off-line); }
.pill-excused    { background: var(--info-bg);   color: var(--info);   border-color: var(--info-line); }

/* ============================ ESTADO ACTUAL =========================== */

.state-hero {
  background: var(--navy-800);
  color: var(--on-navy);
  border-radius: var(--radius);
  padding: 1.15rem 1.25rem;
  box-shadow: var(--shadow);
}
.state-hero .label { font-family: var(--font-cond); font-size: .82rem; font-weight: 600; text-transform: uppercase; letter-spacing: .1em; color: var(--on-navy-soft); }
.state-hero .value { font-size: 1.7rem; font-weight: 700; line-height: 1.15; margin-top: .1rem; }
.state-hero .since { font-size: .88rem; color: var(--on-navy-soft); margin-top: .15rem; }
.state-hero .timer {
  font-size: 2.7rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
  letter-spacing: -.02em;
  line-height: 1.05;
  margin-top: .4rem;
}
.state-hero .timer-label { font-family: var(--font-cond); font-size: .8rem; font-weight: 600; color: var(--on-navy-soft); text-transform: uppercase; letter-spacing: .1em; }

/* =========================== CUMPLIMIENTO ============================= */

.compliance {
  display: flex; align-items: center; gap: 1rem;
}
.gauge { position: relative; width: 108px; height: 108px; flex: 0 0 108px; }
.gauge svg { transform: rotate(-90deg); width: 108px; height: 108px; }
.gauge-track { fill: none; stroke: var(--line); stroke-width: 11; }
.gauge-fill { fill: none; stroke: var(--ok); stroke-width: 11; stroke-linecap: round; transition: stroke-dashoffset .6s ease; }
.gauge-fill.mid { stroke: var(--warn); }
.gauge-fill.low { stroke: var(--danger); }
.gauge-text {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 1.5rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.bar { height: 10px; border-radius: 999px; background: var(--line); overflow: hidden; min-width: 70px; }
.bar > i { display: block; height: 100%; background: var(--ok); border-radius: 999px; }
.bar > i.mid { background: var(--warn); }
.bar > i.low { background: var(--danger); }

/* ============================== KPIs ================================== */

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: .7rem;
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 5px solid var(--navy-600);
  border-radius: var(--radius-sm);
  padding: .7rem .85rem;
  box-shadow: var(--shadow);
}
.kpi .n {
  font-family: var(--font-mono);
  font-size: 1.85rem; font-weight: 700; line-height: 1.05;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.kpi .l {
  font-family: var(--font-cond);
  font-size: .86rem; color: var(--ink-faint); font-weight: 600;
  text-transform: uppercase; letter-spacing: .085em;
  margin-top: .1rem;
}
.kpi.ok { border-left-color: var(--ok); }
.kpi.warn { border-left-color: var(--warn); }
.kpi.danger { border-left-color: var(--danger); }
.kpi.off { border-left-color: var(--off); }

/* ============================== TABLAS ================================ */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.tbl { width: 100%; border-collapse: collapse; font-size: .93rem; }
table.tbl th, table.tbl td { padding: .6rem .65rem; text-align: left; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.tbl th {
  background: var(--surface-2);
  color: var(--ink-faint);
  font-family: var(--font-cond);
  font-size: .82rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em;
  white-space: nowrap;
  border-bottom-color: var(--line);
  position: sticky; top: 0; z-index: 1;
}
table.tbl tbody tr:hover { background: var(--navy-050); }
table.tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl-empty { padding: 2rem 1rem; text-align: center; color: var(--ink-soft); }

.driver-cell { display: flex; align-items: center; gap: .55rem; }
.avatar {
  width: 36px; height: 36px; flex: 0 0 36px;
  border-radius: 50%;
  background: var(--navy-100); color: var(--navy-ink);
  display: grid; place-items: center;
  font-weight: 700; font-size: .82rem;
}
.driver-cell .nm { font-weight: 600; line-height: 1.15; }
.driver-cell .sb { font-size: .78rem; color: var(--ink-soft); }

/* Tabla → tarjetas en celular */
@media (max-width: 760px) {
  table.tbl.responsive thead { display: none; }
  table.tbl.responsive, table.tbl.responsive tbody, table.tbl.responsive tr, table.tbl.responsive td { display: block; width: 100%; }
  table.tbl.responsive tr {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    margin-bottom: .6rem;
    padding: .35rem .2rem;
    background: var(--surface);
  }
  table.tbl.responsive td { border: none; padding: .32rem .7rem; display: flex; justify-content: space-between; gap: 1rem; align-items: center; }
  table.tbl.responsive td::before {
    content: attr(data-label);
    font-size: .76rem; font-weight: 700; color: var(--ink-soft);
    text-transform: uppercase; letter-spacing: .04em;
    flex: 0 0 auto;
  }
  table.tbl.responsive td.num { text-align: right; }
  table.tbl.responsive td[data-label=""]::before { content: none; }
}

/* ============================== PESTAÑAS ============================== */

.tabs {
  display: flex; gap: .3rem;
  border-bottom: 2px solid var(--line);
  margin-bottom: 1rem;
  overflow-x: auto;
}
.tab {
  min-height: 48px;
  padding: .5rem 1.05rem;
  border: none; background: none;
  font-family: var(--font-cond); font-size: 1.05rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-soft);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
  white-space: nowrap;
}
.tab:hover { color: var(--ink); }
.tab.active { color: var(--ink); border-bottom-color: var(--navy-600); }

/* =============================== FORMS ================================ */

.field { display: block; margin-bottom: .9rem; }
.field > label {
  display: block;
  font-size: .85rem; font-weight: 700;
  color: var(--ink);
  margin-bottom: .3rem;
}
.field .hint { font-size: .78rem; color: var(--ink-soft); font-weight: 500; margin-top: .25rem; }

input[type="text"], input[type="password"], input[type="date"], input[type="tel"],
input[type="number"], select, textarea {
  width: 100%;
  min-height: var(--tap);
  padding: .55rem .75rem;
  font-size: 1rem;
  font-family: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 2px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color .15s, box-shadow .15s;
}
textarea { min-height: 92px; resize: vertical; line-height: 1.45; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--navy-600);
  box-shadow: 0 0 0 3px rgba(27, 78, 143, .16);
}
input[readonly] { background: var(--navy-050); }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%), linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%); background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 2.2rem; }

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 1rem; }
.err { color: var(--danger); font-size: .88rem; font-weight: 600; margin-top: .4rem; }

/* Selector segmentado (turno AM / PM) */
.segmented { display: flex; border: 2px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.segmented button {
  flex: 1; min-height: 48px;
  border: none; background: var(--surface);
  font-family: inherit; font-size: .95rem; font-weight: 600;
  color: var(--ink-soft); cursor: pointer;
}
.segmented button + button { border-left: 2px solid var(--line); }
.segmented button.on { background: var(--navy-800); color: var(--on-navy); }

/* ============================== LOGIN ================================= */

.auth-wrap {
  min-height: 100vh;
  display: grid; place-items: center;
  padding: 1.25rem;
  background: var(--navy-900);
}
.auth-card {
  width: 100%; max-width: 430px;
  background: var(--surface);
  border-radius: var(--radius);
  padding: 1.6rem 1.5rem;
  box-shadow: var(--shadow-lg);
}
.auth-logo { text-align: center; margin-bottom: 1.2rem; }
.auth-logo .mark {
  width: 62px; height: 62px; margin: 0 auto .55rem;
  border-radius: var(--radius);
  background: var(--brand-mark);
  display: grid; place-items: center;
  color: var(--on-navy); font-weight: 700; font-size: 1.5rem;
  border: 1px solid rgba(255,255,255,.18);
}
.auth-logo h1 { font-size: 1.4rem; margin: 0; }
.auth-logo p { font-size: .87rem; color: var(--ink-soft); margin: .1rem 0 0; }
.auth-switch { text-align: center; margin-top: 1rem; }
.link-btn {
  background: none; border: none; padding: .5rem;
  color: var(--navy-ink); font-family: inherit; font-size: .93rem; font-weight: 600;
  cursor: pointer; text-decoration: underline;
}
.auth-lang { display: flex; justify-content: center; gap: .35rem; margin-top: 1.1rem; }
.auth-lang button {
  min-height: 38px; padding: .25rem .8rem;
  border: 1px solid var(--line); background: var(--surface);
  border-radius: 999px; font-family: inherit; font-size: .84rem; font-weight: 600;
  color: var(--ink-soft); cursor: pointer;
}
.auth-lang button.on { background: var(--navy-800); color: var(--on-navy); border-color: var(--navy-800); }

/* ============================== MODAL ================================= */

.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(6, 23, 41, .55);
  display: grid; place-items: center;
  padding: 1rem;
  overflow-y: auto;
}
.modal {
  width: 100%; max-width: 520px;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  max-height: 92vh;
  display: flex; flex-direction: column;
}
.modal-head {
  padding: 1rem 1.15rem .6rem;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: .5rem;
}
.modal-head h2 { margin: 0; font-size: 1.15rem; }
.modal-body { padding: 1.05rem 1.15rem; overflow-y: auto; }
.modal-foot {
  padding: .85rem 1.15rem;
  border-top: 1px solid var(--line);
  display: flex; gap: .6rem; justify-content: flex-end;
  flex-wrap: wrap;
}
.modal-foot .btn { flex: 1 1 auto; min-width: 130px; }
.modal-x {
  margin-left: auto;
  border: none; background: none; cursor: pointer;
  font-size: 1.5rem; line-height: 1; color: var(--ink-soft);
  min-width: 40px; min-height: 40px;
}

/* Caja de código de invitación */
.code-box {
  background: var(--navy-050);
  border: 2px dashed var(--navy-500);
  border-radius: var(--radius-sm);
  padding: 1rem;
  text-align: center;
  margin: .8rem 0;
}
.code-box .code {
  font-family: var(--font-mono);
  font-size: 2rem; font-weight: 700;
  letter-spacing: 3px;
  color: var(--navy-ink);
  word-break: break-all;
}

/* =============================== TOAST ================================ */

#toasts {
  position: fixed; left: 50%; bottom: 1.2rem; transform: translateX(-50%);
  z-index: 200;
  display: flex; flex-direction: column; gap: .5rem;
  width: min(94vw, 460px);
  pointer-events: none;
}
.toast {
  background: var(--navy-900);
  color: var(--on-navy);
  padding: .8rem 1rem;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  font-size: .95rem; font-weight: 600;
  display: flex; align-items: center; gap: .55rem;
  animation: toast-in .22s ease;
}
.toast.ok { background: var(--ok); }
.toast.err { background: var(--danger); }
@keyframes toast-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* =========================== BANDA DE MODO ============================ */

.mode-banner {
  background: var(--warn-bg);
  color: var(--warn);
  border-bottom: 1px solid #EFD5A6;
  font-size: .82rem; font-weight: 600;
  text-align: center;
  padding: .35rem .8rem;
}

/* ============================ RESPONSIVE ============================== */

@media (max-width: 620px) {
  html, body { font-size: 16px; }
  .page { padding: .8rem .7rem 3.5rem; }
  .card { padding: .9rem; border-radius: 12px; }
  /* En celular el logo LB identifica la app; el espacio se lo damos al
     nombre del conductor, que es lo que confirma "esta es MI cuenta". */
  .brand-text { display: none; }
  .app-header { padding: .5rem .7rem; }
  .app-header-inner { gap: .5rem; }
  .icon-btn { padding: 0 .55rem; font-size: .82rem; }
  h1 { font-size: 1.35rem; }
  .state-hero .value { font-size: 1.45rem; }
  .state-hero .timer { font-size: 2.1rem; }
  .kpi .n { font-size: 1.6rem; }
  .gauge, .gauge svg { width: 92px; height: 92px; flex-basis: 92px; }
}

@media (min-width: 900px) {
  .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; }
  .two-col > .card { margin-top: 0; }
}

/* =========================================================================
   TABLERO DE FLOTA — tarjetas del despachador
   Una tarjeta por conductor, con su contador corriendo. Pensado para
   mirarse de lejos en el cambio de turno: el color del borde dice el estado
   sin tener que leer.
   ========================================================================= */

.fleet-toolbar {
  display: flex; flex-wrap: wrap; gap: .6rem 1rem;
  align-items: center; margin-bottom: .9rem;
}
.fleet-toolbar .grow { flex: 1 1 180px; }
.fleet-search {
  width: 100%; padding: .55rem .8rem; font-size: 1rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
}
.fleet-count { font-size: .85rem; color: var(--ink-soft); white-space: nowrap; }

.fleet-grid {
  display: grid; gap: .8rem;
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
}

.fleet-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 5px solid var(--tono, var(--off));
  border-radius: var(--radius);
  padding: .85rem .9rem;
  box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: .5rem;
}
.fleet-card.is-inactive { opacity: .55; }

.fleet-card .top { display: flex; align-items: flex-start; gap: .6rem; }
.fleet-card .top .grow { min-width: 0; }
.fleet-card .nombre {
  font-weight: 600; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fleet-card .sub { font-size: .8rem; color: var(--ink-soft); margin-top: .1rem; }

.fleet-timer {
  font-family: var(--font-mono);
  font-size: 1.55rem; font-weight: 600; letter-spacing: .01em;
  color: var(--tono, var(--ink)); font-variant-numeric: tabular-nums;
  line-height: 1;
}
.fleet-timer.parado { color: var(--ink-soft); }
.fleet-sub-timer { font-size: .78rem; color: var(--ink-soft); margin-top: .15rem; }

.fleet-card .acciones { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .1rem; }
.fleet-card .acciones .btn { flex: 1 1 auto; }

/* Tonos por estado: el borde y el contador comparten color. */
.t-turno       { --tono: var(--ok); }
.t-available   { --tono: var(--info); }
.t-maintenance { --tono: var(--warn); }
.t-incident    { --tono: var(--danger); }
.t-off         { --tono: var(--off); }
.t-inactive    { --tono: var(--off); }

/* Punto que late, solo mientras el contador corre. */
.latido {
  display: inline-block; width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--ok); margin-right: .35rem; vertical-align: middle;
  animation: latir 2s ease-in-out infinite;
}
@keyframes latir {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .45; transform: scale(.82); }
}
@media (prefers-reduced-motion: reduce) {
  .latido { animation: none; }
}

/* =========================================================================
   PANTALLA DEL CONDUCTOR
   El color del bloque de estado cambia con lo que está haciendo, para que
   sepa de un vistazo —y con guantes, al sol— si está fichado o no.
   ========================================================================= */

.state-hero {
  position: relative; overflow: hidden;
  transition: background-color .35s ease;
}
.state-hero.e-turno       { background: var(--hero-turno); }
.state-hero.e-available   { background: var(--hero-available); }
.state-hero.e-maintenance { background: var(--hero-maint); }
.state-hero.e-incident    { background: var(--hero-incident); }
.state-hero.e-off         { background: var(--hero-off); }
.state-hero.e-inactive    { background: var(--hero-off); }

/* Resplandor suave detrás del cronómetro, solo cuando el contador corre.
   Es CSS puro: no hay imágenes que descargar ni bucle de JavaScript. */
.state-hero.e-turno::after {
  content: ''; position: absolute; inset: -40% -20% auto -20%; height: 190%;
  background: radial-gradient(ellipse at 50% 0%, rgba(255,255,255,.16), transparent 62%);
  animation: respirar 5s ease-in-out infinite; pointer-events: none;
}
@keyframes respirar {
  0%, 100% { opacity: .5; }
  50%      { opacity: 1; }
}
.state-hero > * { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  .state-hero::after { animation: none; }
  .state-hero { transition: none; }
}

/* Tarjetas de resumen de horas del conductor. */
.hours-grid {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(3, 1fr);
}
.hours-box {
  background: var(--navy-050); border: 1px solid var(--navy-100);
  border-radius: var(--radius-sm); padding: .7rem .6rem; text-align: center;
}
.hours-box .n {
  font-family: var(--font-mono);
  font-size: 1.3rem; font-weight: 600; color: var(--navy-ink);
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
.hours-box .l {
  font-family: var(--font-cond);
  font-size: .82rem; font-weight: 600; color: var(--ink-faint); margin-top: .2rem;
  text-transform: uppercase; letter-spacing: .085em;
}

@media print {
  .app-header, .tabs, .btn, .no-print { display: none !important; }
  body { background: #fff; }
  .card { box-shadow: none; border: 1px solid #999; }
  .fleet-toolbar { display: none !important; }
  .fleet-grid { grid-template-columns: repeat(3, 1fr); }
  .fleet-card { box-shadow: none; }
  .state-hero::after { display: none; }
}

/* =========================================================================
   AVISO DE CRONÓMETROS LARGOS
   Ámbar, no rojo, y a propósito: no es un error ni una falta. Un conductor
   esperando en el pozo lleva muchas horas con razón. Es información para que
   el despachador decida, no una alarma.
   ========================================================================= */

.card.aviso-largos {
  border-left: 5px solid var(--warn);
  background: var(--warn-bg);
}

/* Marca en la tarjeta del conductor cuando su cronómetro lleva mucho. */
.fleet-card.largo { border-left-color: var(--warn); }
.fleet-card.largo .fleet-timer { color: var(--warn); }
.fleet-card.largo .latido { background: var(--warn); }

/* Aviso de meta del día en la pantalla del conductor. Verde cuando ya la
   cumplió, neutro mientras va en camino: nunca en rojo, porque el horario es
   flexible y no alcanzarla a media jornada no es una falta. */
.meta-hint {
  margin-top: .7rem; padding: .5rem .7rem; border-radius: var(--radius-sm);
  font-size: .9rem; font-weight: 600; text-align: center;
  background: var(--navy-050); color: var(--ink-soft); border: 1px solid var(--navy-100);
}
.meta-hint.ok { background: var(--ok-bg); color: var(--ok); border-color: var(--ok-line); }

/* =========================================================================
   CALENDARIO DE DÍAS OFF
   Rejilla de mes. Pensado para el pulgar en un celular: cada día es un
   objetivo táctil de 44 px como mínimo.
   ========================================================================= */

.cal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-bottom: .7rem;
}
.cal-head .mes { font-weight: 700; font-size: 1.05rem; text-transform: capitalize; }

.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow {
  text-align: center; font-size: .7rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-soft); padding-bottom: .2rem;
}
.cal-day {
  min-height: 44px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1px;
  font-size: .9rem; font-variant-numeric: tabular-nums; padding: .2rem;
}
.cal-day.vacio { border: none; background: transparent; }
.cal-day.hoy { border-color: var(--navy-600); border-width: 2px; font-weight: 700; }
.cal-day.pasado { opacity: .45; }

/* Aprobado y pendiente se distinguen por relleno, no solo por color: un
   despachador daltónico tiene que poder separarlos igual. */
.cal-day.off {
  background: var(--off-bg); border-color: var(--off); color: var(--off); font-weight: 700;
}
.cal-day.pend {
  background: repeating-linear-gradient(45deg,
    var(--warn-bg), var(--warn-bg) 5px, transparent 5px, transparent 10px);
  border-color: var(--warn); color: var(--warn); font-weight: 700;
}
.cal-day .marca { font-size: .62rem; line-height: 1; letter-spacing: .02em; }

.cal-leyenda {
  display: flex; flex-wrap: wrap; gap: .8rem; margin-top: .8rem;
  font-size: .78rem; color: var(--ink-soft);
}
.cal-leyenda i {
  display: inline-block; width: 13px; height: 13px; border-radius: 3px;
  border: 1px solid var(--line); margin-right: .3rem; vertical-align: -2px;
}
.cal-leyenda .l-off  i { background: var(--off-bg); border-color: var(--off); }
.cal-leyenda .l-pend i { background: repeating-linear-gradient(45deg,
  var(--warn-bg), var(--warn-bg) 4px, transparent 4px, transparent 8px); border-color: var(--warn); }

/* --- Línea de tiempo de 24 h (tarjeta del conductor) --- */

.tl24-caja { margin-top: .7rem; }
.tl24-titulo {
  font-size: .7rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-soft); margin-bottom: .25rem;
}
.tl24 {
  position: relative; height: 12px; border-radius: 6px; overflow: hidden;
  background: var(--navy-050); border: 1px solid var(--line);
}
.tl24-caja.grande .tl24 { height: 22px; border-radius: 8px; }
.tl24 i { position: absolute; top: 0; bottom: 0; display: block; }
.tl24-vacio { position: absolute; inset: 0; }

/* Cada estado con su color, el mismo de las píldoras para que no haya que
   aprender dos códigos distintos. */
.tl-available   { background: var(--ok); }
.tl-maintenance { background: var(--warn); }
.tl-off         { background: var(--off); }
.tl-incident    { background: var(--danger); }

.tl24-horas {
  display: flex; justify-content: space-between;
  font-size: .62rem; color: var(--ink-soft); margin-top: .15rem;
  font-variant-numeric: tabular-nums;
}

.ult-marcas {
  margin-top: .5rem; font-size: .78rem; display: flex;
  flex-direction: column; gap: .15rem;
}
.punto {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: .35rem; vertical-align: 1px;
}

/* Código de check-in verificable + nota de "cuándo vuelvo", en la tarjeta
   del conductor. Van entre el nombre y el cronómetro: identidad, no estado. */
.fleet-meta {
  display: flex; flex-wrap: wrap; gap: .1rem 1rem;
  margin: .35rem 0;
}

.tl-totales {
  display: flex; flex-wrap: wrap; gap: 1rem;
  margin: .8rem 0; font-size: .85rem;
}

/* Contador de solicitudes pendientes en el botón de la pestaña. */
.tab-badge {
  display: inline-block; min-width: 17px; padding: 0 4px;
  border-radius: 9px; background: var(--warn); color: var(--on-navy);
  font-size: .68rem; font-weight: 700; line-height: 17px;
  text-align: center; vertical-align: 1px;
}

/* --- Calendario de la flota (panel del despachador) --- */

/* Los días del calendario del despachador sí se pulsan, al contrario que los
   del conductor, que son solo de lectura. */
.cal-day.cal-click { cursor: pointer; }
.cal-day.cal-click:hover { border-color: var(--navy-600); }
.cal-day.cal-click:focus-visible {
  outline: 2px solid var(--navy-600); outline-offset: 2px;
}
.cal-day.sel {
  border-color: var(--navy-600); border-width: 2px;
  box-shadow: 0 0 0 3px var(--navy-100, rgba(11, 37, 69, .12));
}

.cal-detalle {
  margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line);
}
.cal-persona {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; padding: .45rem 0; border-bottom: 1px solid var(--line);
  font-size: .9rem;
}
.cal-persona:last-child { border-bottom: none; }
.cal-persona .acciones { display: flex; gap: .4rem; flex-shrink: 0; }

/* En pantalla estrecha el nombre y los botones no caben en una línea. */
@media (max-width: 420px) {
  .cal-persona { flex-direction: column; align-items: stretch; }
  .cal-persona .acciones { justify-content: flex-end; }
}

/* Solicitudes pendientes en el panel del despachador. */
.solicitud {
  border: 1px solid var(--line); border-left: 4px solid var(--warn);
  border-radius: var(--radius-sm); padding: .8rem .9rem; margin-bottom: .6rem;
  background: var(--surface);
}
.solicitud .row { justify-content: space-between; align-items: flex-start; }
.solicitud .fechas { font-weight: 700; font-variant-numeric: tabular-nums; }
.solicitud .acciones { display: flex; gap: .4rem; margin-top: .6rem; }
.solicitud .acciones .btn { flex: 1; }

/* =========================== COLA DE CARGAS =========================== */

/* Pantalla del conductor: su puesto, grande, y el código al lado. */
.cola-caja {
  display: flex; align-items: center; gap: .9rem;
  background: var(--navy-050);
  border: 1px solid var(--navy-100);
  border-radius: var(--radius-sm);
  padding: .8rem .9rem;
}
.cola-puesto {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 62px; padding: .35rem .5rem;
  background: var(--surface);
  border: 2px solid var(--navy-600);
  border-radius: var(--radius-sm);
}
.cola-puesto b { font-size: 1.7rem; line-height: 1; color: var(--navy-ink); }
.cola-puesto span { font-size: .62rem; color: var(--ink-soft); text-align: center; margin-top: .15rem; }
.cola-cod { font-size: 1.35rem; font-weight: 700; letter-spacing: .09em; }

/* Panel del despachador: una columna por pozo. */
.cola-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
}
.cola-col-tit {
  font-weight: 700; font-size: .82rem; letter-spacing: .05em; text-transform: uppercase;
  padding-bottom: .4rem; margin-bottom: .5rem;
  border-bottom: 2px solid var(--line);
}
.cola-fila {
  display: flex; gap: .6rem; align-items: flex-start;
  padding: .55rem 0;
  border-bottom: 1px solid var(--line);
}
.cola-fila:last-child { border-bottom: 0; }
.cola-n {
  flex: 0 0 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  background: var(--navy-100); color: var(--navy-ink);
  border-radius: 50%; font-weight: 700; font-size: .82rem;
}

/* Contador de cargas de la jornada. Es lo único de la pantalla del conductor
   que habla de la unidad con la que le pagan, así que va grande y en mono,
   como el cronómetro: los dos son instrumentos, no texto. */
.cargas-caja {
  display: flex; align-items: center; gap: .9rem;
  padding: .7rem .9rem;
  margin-bottom: .9rem;
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-left: 4px solid var(--navy-600);
  border-radius: var(--radius-sm);
}
.cargas-n {
  font-size: 2.3rem; font-weight: 700; line-height: 1;
  letter-spacing: -.04em;
  color: var(--navy-ink);
  min-width: 1.6em; text-align: center;
}
.cargas-rot {
  font-family: var(--font-cond);
  font-size: .92rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .085em;
  color: var(--ink);
}

/* ==================== TICKETS / BOL ==================== */

/* Aviso de "queda pendiente de subir". No es un error —el ticket está a
   salvo en el teléfono— pero tampoco está hecho, así que ni verde ni rojo. */
.toast.warn { background: var(--warn-solid); }

/* Vista previa del escaneo. Fondo blanco fijo y no var(--surface): el
   escaneo es blanco y negro puro, y sobre un fondo oscuro el papel
   parecería un recorte flotando. Alto limitado para que en un móvil se vea
   el ticket entero y los botones a la vez, sin tener que rodar la pantalla. */
.ticket-vista {
  background: #FFFFFF;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .35rem;
  max-height: 46vh;
  overflow: auto;
  text-align: center;
}
.ticket-vista img { max-width: 100%; height: auto; display: block; margin: 0 auto; }

/* Lista de tickets pendientes en la pantalla del conductor */
.ticket-fila {
  display: flex; align-items: center; gap: .7rem;
  padding: .6rem .75rem;
  margin-top: .5rem;
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-left: 4px solid var(--warn);
  border-radius: var(--radius-sm);
}
.ticket-fila.rechazado { border-left-color: var(--danger); }
.ticket-fila .grow { min-width: 0; }
.ticket-fila .ticket-cuando {
  font-family: var(--font-cond);
  font-size: .95rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink);
}

/* Recordatorio del número de carga escrito en el papel. Va en caja aparte
   porque es la instrucción que más se olvida y la que hace inservible el
   ticket: sin ese número, la foto no se puede casar con la carga. */
.ticket-aviso {
  display: flex; gap: .55rem; align-items: flex-start;
  padding: .55rem .7rem;
  margin-top: .6rem;
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-radius: var(--radius-sm);
  font-size: .88rem;
  color: var(--ink);
}
.ticket-aviso b { color: var(--warn); }

/* Estado del ticket en el panel del despachador */
.ticket-estado {
  display: inline-block;
  padding: .12rem .5rem;
  border-radius: 999px;
  font-size: .78rem; font-weight: 600;
  white-space: nowrap;
}
.ticket-estado.subida    { background: var(--ok-bg);     color: var(--ok);     border: 1px solid var(--ok-line); }
.ticket-estado.pendiente { background: var(--warn-bg);   color: var(--warn);   border: 1px solid var(--warn-line); }
.ticket-estado.rechazada { background: var(--danger-bg); color: var(--danger); border: 1px solid var(--danger-line); }
.ticket-estado.sin_ticket{ background: var(--off-bg);    color: var(--off);    border: 1px solid var(--off-line); }

/* =========================================================================
   DESPACHADOR EN TURNO — franja superior del panel del conductor
   -------------------------------------------------------------------------
   Resuelve un problema de teléfono, no de pantalla: los conductores llamaban
   al despachador que estaba descansando. Por eso va lo PRIMERO, antes del
   cronómetro, y el teléfono es un enlace `tel:` — con guantes, dentro de la
   cabina, la diferencia entre leer un número y poder tocarlo es real.
   ========================================================================= */
.desp-barra {
  background: var(--surface);
  border: 1px solid var(--ok-line);
  border-left: 4px solid var(--ok);
  border-radius: var(--radius-sm);
  padding: .6rem .8rem .55rem;
  margin-bottom: .9rem;
}
.desp-barra.vacia { border-color: var(--line); border-left-color: var(--ink-faint); }

.desp-tit {
  font-family: var(--font-cond);
  font-size: .8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-faint);
  margin-bottom: .35rem;
}
.desp-fila {
  display: flex; align-items: center; gap: .5rem;
  padding: .18rem 0;
  flex-wrap: wrap;
}
/* El punto no parpadea a propósito: una app que late en la mano de alguien
   que conduce es una distracción, no una señal. */
.desp-punto {
  width: 9px; height: 9px; flex: 0 0 9px;
  border-radius: 50%; background: var(--ok);
}
.desp-nombre { font-weight: 600; }
.desp-tel {
  font-family: var(--font-mono);
  font-size: .92rem;
  margin-left: auto;
  color: var(--navy-ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.desp-en {
  margin-left: auto;
  font-size: .82rem; color: var(--ok);
}
.desp-none { color: var(--ink-soft); font-size: .92rem; }
.desp-pie { font-size: .78rem; color: var(--ink-faint); margin-top: .3rem; }


/* =========================================================================
   DIRECTORIO DE CONDUCTORES — pestaña del panel de despacho
   -------------------------------------------------------------------------
   Es la hoja de Google que usaban, en vivo. Se mira de un vistazo buscando
   una fila concreta, así que lo que importa es que el filtro esté a mano y
   que las columnas de dato no bailen (de ahí la fuente monoespaciada en
   camión, teléfono y última conexión).
   ========================================================================= */
.dir-barra {
  display: flex; align-items: center; gap: .6rem;
  flex-wrap: wrap;
  margin-bottom: .7rem;
}
.dir-barra input[type="search"], .dir-barra input.dir-q {
  flex: 1 1 240px;
  min-width: 0;
}
.dir-cuenta {
  font-family: var(--font-mono);
  font-size: .84rem;
  color: var(--ink-faint);
  white-space: nowrap;
}
table.tbl td.dir-dato {
  font-family: var(--font-mono);
  font-size: .88rem;
  white-space: nowrap;
}
/* Sin ver desde hace mucho: se apaga en vez de gritar. Un conductor
   desconectado suele ser uno que terminó su turno, no una alarma. */
td.dir-dato.frio { color: var(--ink-faint); }
.dir-pad {
  display: inline-block;
  font-family: var(--font-cond);
  font-size: .8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  padding: .1rem .45rem;
  border-radius: var(--radius-sm);
  background: var(--navy-100); color: var(--navy-ink);
  white-space: nowrap;
}
.dir-pad.vacio { background: transparent; color: var(--ink-faint); }

/* Los selectores del directorio van en línea, no apilados: son filtros de
   tablero, y tres desplegables a ancho completo empujan la tabla —lo que de
   verdad se viene a mirar— fuera de la pantalla. En celular sí se apilan. */
.dir-barra select {
  width: auto;
  flex: 0 1 auto;
  min-width: 8rem;
  max-width: 14rem;
}
@media (max-width: 560px) {
  .dir-barra select { flex: 1 1 45%; max-width: none; }
  .dir-cuenta { flex-basis: 100%; }
}

/* =========================================================================
   DESPACHO EN TURNO, TIPO DE MENSAJE Y DESCARTE DE TICKETS
   ========================================================================= */

/* --- Franja del conductor: quién está de guardia ---
   'frio' = pulsó el botón de entrar a despacho pero hace rato que no toca el
   panel. No se le esconde (sigue siendo el de guardia) pero el conductor
   merece saberlo antes de llamar tres veces. */
/* El nombre y "desde tal hora" van juntos en la primera línea; el teléfono y
   el aviso de inactividad, cada uno en la suya, sangrados bajo el nombre para
   que se lean como parte de la misma persona. En 375 px las tres cosas no
   caben en una línea, y al envolverse el número quedaba pegado al borde
   derecho, huérfano, como si fuera de otro despachador. */
.desp-desde  { font-size: .78rem; font-weight: 400; color: var(--ink-faint); margin-left: .35rem; }
.desp-fila .desp-tel,
.desp-fila .desp-en { flex: 1 0 100%; margin-left: 1.05rem; }

/* En pantalla ancha sí caben en una sola línea: el teléfono vuelve a la
   derecha, que es donde se busca en una tabla. */
@media (min-width: 620px) {
  .desp-fila .desp-tel,
  .desp-fila .desp-en { flex: 0 0 auto; margin-left: auto; }
}

/* --- Rótulo del mensaje que se copia ---
   Check-in y pedido de carga van al MISMO grupo de WhatsApp y se parecen
   demasiado. Esta banda es lo que hace que el conductor sepa qué acaba de
   pegar y el despachador qué acaba de recibir. */
.msg-tipo {
  display: flex; flex-direction: column; gap: .1rem;
  padding: .55rem .75rem;
  border-radius: var(--radius-sm);
  border-left: 5px solid var(--ok);
  background: var(--ok-bg);
}
.msg-tipo.carga { border-left-color: var(--info); background: var(--info-bg); }
.msg-tipo-rot {
  font-family: var(--font-cond);
  font-size: 1.15rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--ok);
}
.msg-tipo.carga .msg-tipo-rot { color: var(--info); }
.msg-tipo-sub { font-size: .84rem; color: var(--ink-soft); }

/* --- Tarjeta de tickets del conductor ---
   Hasta el 1 de septiembre avisa; a partir de ahí bloquea, y entonces se
   pinta en naranja para que se distinga de una nota informativa. */
.tarjeta-tickets { border-left: 4px solid var(--ink-faint); }
.tarjeta-tickets.frena { border-left-color: var(--warn); }
.tickets-n {
  display: inline-block; min-width: 1.35rem; text-align: center;
  padding: 0 .3rem; border-radius: 999px;
  background: var(--off-bg); color: var(--off);
  font-size: .78rem; font-weight: 700;
}
.tarjeta-tickets.frena .tickets-n { background: var(--warn-bg); color: var(--warn); }

/* --- Barra de despacho (panel del despachador) --- */
.dsp-barra {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 4px solid var(--ink-faint);
  border-radius: var(--radius-sm);
  padding: .6rem .85rem;
  margin-bottom: .85rem;
}
.dsp-barra.activo { border-color: var(--ok-line); border-left-color: var(--ok); }
.dsp-izq { flex: 1 1 260px; min-width: 0; }
.dsp-der { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.dsp-tit {
  font-family: var(--font-cond);
  font-size: .78rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-faint);
  margin-bottom: .3rem;
}
.dsp-lista { display: flex; gap: .4rem; flex-wrap: wrap; }
.dsp-chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .18rem .55rem;
  border-radius: 999px;
  background: var(--ok-bg); color: var(--ok);
  border: 1px solid var(--ok-line);
  font-size: .88rem; font-weight: 600;
}
.dsp-chip i {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ok); flex: 0 0 7px;
}
.dsp-chip b { font-family: var(--font-mono); font-weight: 500; opacity: .75; }
.dsp-nadie { color: var(--ink-soft); font-size: .92rem; }
.dsp-mio { font-size: .84rem; color: var(--ink-soft); }
.dsp-solo-mirar { font-size: .82rem; color: var(--ink-faint); font-style: italic; }

/* --- Aviso de datos nuevos ---
   Reemplaza al repintado automático en las pestañas donde el despachador
   está escribiendo. Es un botón: él decide cuándo perder lo que tiene. */
.tab.tab-nuevo {
  background: var(--warn-bg);
  color: var(--warn);
  border-color: var(--warn-line);
  font-weight: 600;
}

/* --- Descartar tickets en bloque --- */
.tk-masivo {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  justify-content: space-between;
  margin-top: .8rem; padding: .65rem .8rem;
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.ticket-estado.descartada {
  background: var(--off-bg); color: var(--off);
  border: 1px solid var(--off-line);
  text-decoration: line-through;
}

/* --- Campana de avisos (cabecera) ---
   Sustituye a la tarjeta grande que ocupaba la parte de arriba del panel
   del conductor. Encendida se marca con el verde de "todo en orden", para
   que se distinga de un vistazo sin tener que leer nada. */
.icon-btn.campana-on {
  background: rgba(46, 160, 92, .28);
  border-color: rgba(46, 160, 92, .55);
}
.icon-btn.campana-on:hover { background: rgba(46, 160, 92, .4); }
.icon-btn[hidden] { display: none; }

/* ===================================================================
   NÚMERO DE CARGA Y REVISIÓN DE TICKETS  (migración 26)
   =================================================================== */

/* Panel del conductor: el número que tiene que copiar a mano en el papel
   antes de hacer la foto. Va más grande que la fecha de la carga a
   propósito — es el dato que hace que la foto sirva para algo. */
.ticket-num {
  font-size: 1.15rem; font-weight: 700;
  letter-spacing: .04em;
  color: var(--navy-ink);
  line-height: 1.2;
}

/* --- Pestaña Revisar --- */
.rev-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: .8rem;
}
.rev-card {
  display: flex; flex-direction: column;
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
/* Ámbar = el número lo puso la base porque el despachador dejó el campo
   vacío al asignar. Son exactamente las que faltan por casar con el TMS,
   y por eso se ven distintas sin tener que leer nada. */
.rev-card.rev-auto {
  border-color: var(--warn-line);
  box-shadow: inset 4px 0 0 var(--warn);
}
.rev-foto {
  display: flex; align-items: center; justify-content: center;
  height: 190px;
  background: var(--navy-900);
  overflow: hidden;
}
.rev-foto img {
  width: 100%; height: 100%;
  object-fit: cover;
  cursor: zoom-in;
  display: block;
}
.rev-sinfoto {
  font-family: var(--font-cond);
  font-size: .9rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--on-navy-soft);
}
.rev-datos { padding: .6rem .7rem .7rem; display: flex; flex-direction: column; gap: .3rem; }
.rev-num {
  font-size: 1.1rem; font-weight: 700;
  letter-spacing: .04em;
  color: var(--navy-ink);
  word-break: break-all;
}
.rev-aviso {
  align-self: flex-start;
  font-family: var(--font-cond);
  font-size: .76rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  padding: .08rem .4rem;
  border-radius: var(--radius-sm);
  background: var(--warn-bg); color: var(--warn);
  border: 1px solid var(--warn-line);
}
.rev-quien { font-size: .95rem; }
.rev-estado { margin-top: .1rem; }
.rev-acciones {
  display: flex; flex-wrap: wrap; gap: .4rem;
  margin-top: .45rem;
}

/* --- Directorio: numeración y antigüedad de turno --- */
table.tbl th.dir-n, table.tbl td.dir-n {
  width: 2.6rem;
  text-align: right;
  color: var(--ink-faint);
  font-size: .84rem;
}
/* Con turno abierto el tiempo es un dato vivo; sin turno es un guion. */
td.dir-dato.dir-abierto { color: var(--ink); font-weight: 600; }

/* El número de carga en la tabla de Tickets. Es un botón, no texto: se toca
   para escribir el del TMS. Se disfraza de dato para no llenar la tabla de
   botones —lo que importa ahí es leer la columna— pero se subraya al pasar
   por encima para que se note que se puede tocar. */
.btn-num {
  display: block; width: 100%;
  background: none; border: 0; padding: 0;
  font: inherit; color: inherit;
  text-align: left; cursor: pointer;
  min-height: 0;
}
.btn-num .mono {
  font-family: var(--font-mono);
  font-size: .9rem; font-weight: 600;
  color: var(--navy-ink);
  border-bottom: 1px dashed var(--line);
}
.btn-num:hover .mono { border-bottom-style: solid; border-bottom-color: var(--navy-500); }
.btn-num.es-auto .mono { color: var(--warn); }
.btn-num-aviso {
  display: block;
  font-family: var(--font-cond);
  font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--warn);
  margin-top: .1rem;
}

/* ===================== LA COLA DE CARGAS, ARRIBA DEL TODO =====================
   Es lo único de la pestaña donde hay alguien esperando a que el despachador
   haga algo. Cuando la cola tiene gente, la tarjeta se marca: en una pantalla
   llena de bloques iguales, el que exige acción tiene que verse distinto sin
   tener que leerlo. */
.card.cola-activa { border-left: 5px solid var(--warn); }

.cola-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.5rem; height: 1.5rem; padding: 0 .4rem;
  border-radius: 999px;
  background: var(--warn); color: #fff;
  font-family: var(--font-cond);
  font-size: .82rem; font-weight: 700;
}

/* La hora del dato. Empuja al botón de actualizar contra el borde derecho y
   contesta la pregunta que no se puede contestar mirando una pantalla quieta:
   ¿esto está vivo o lleva veinte minutos congelado? */
.cola-sello {
  margin-left: auto;
  font-family: var(--font-cond);
  font-size: .8rem; font-weight: 500;
  color: var(--ink-faint);
  white-space: nowrap;
}
@media (max-width: 560px) {
  .cola-sello { display: none; }
}

/* ===================== DIRECTORIO EN VIVO =====================
   La tabla que sustituyó al tablero de tarjetas. */

/* El cronómetro de turno. Late cada segundo, así que se le fija el ancho por
   caracteres: sin esto, la columna entera da un salto al pasar de 9 a 10
   horas y la tabla parece que parpadea. */
.dir-crono {
  font-family: var(--font-mono);
  font-size: .88rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.dir-fila.abierta { background: var(--navy-050); }
.dir-fila.abierta td { border-bottom-color: transparent; }

.dir-abrir { white-space: nowrap; }
.dir-abrir.abierta { background: var(--navy-800); color: var(--on-navy); }

/* La ficha del conductor, desplegada bajo su fila. Se le pone tope de ancho:
   estirada sobre once columnas de un monitor grande, la línea de 24 horas
   queda tan larga que deja de leerse como una línea de tiempo. */
tr.dir-detalle > td {
  padding: .2rem .7rem 1rem;
  background: var(--navy-050);
}
tr.dir-detalle .fleet-card { max-width: 560px; box-shadow: none; }

@media (max-width: 760px) {
  tr.dir-detalle > td { padding: .4rem 0 .8rem; }
  tr.dir-detalle > td::before { content: none; }
  tr.dir-detalle .fleet-card { max-width: none; }
}

/* ===================== BOL TICKETS =====================
   La barra que decide QUÉ se ve (Lista o Fotos) y CUÁNTO (los dos filtros).
   Va debajo del rango de fechas y del buscador porque esos dicen qué cargas
   se traen del servidor; esto solo recorta lo que ya está en pantalla. */
.bol-barra {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .6rem 1rem;
  margin: .2rem 0 .9rem;
}
.bol-barra .segmented { flex: 0 0 auto; }
.bol-barra .segmented button { min-width: 6.5rem; flex: 0 0 auto; }

.bol-check {
  display: flex; align-items: center; gap: .45rem;
  cursor: pointer;
  font-size: .92rem;
  margin: 0;
}
.bol-check input[type="checkbox"] {
  width: auto; min-height: auto; margin: 0;
}

@media (max-width: 560px) {
  .bol-barra .segmented { flex: 1 1 100%; }
  .bol-barra .segmented button { flex: 1 1 auto; }
  .bol-check { flex: 1 1 100%; }
}
