:root {
  /* Multiplicador de toda la letra de la aplicacion. Cada font-size de esta
     hoja se escribe como calc(Npx * var(--fs)), asi que mover esta sola
     variable agranda o achica el texto entero sin tocar el resto del diseno.
     Lo mueve el control de la barra superior; app.js lo guarda en el navegador. */
  --fs: 1;
  /* Ancho de la barra de desplazamiento. Lo fija esta misma hoja mas abajo
     (::-webkit-scrollbar), y las cabeceras de tabla lo necesitan para dejar el
     mismo hueco que la lista que va debajo. */
  --sb: 10px;
  --bg: #08111e;
  --sidebar: #0d1a2d;
  --panel: #101b2d;
  --panel-2: #0b1424;
  --panel-3: #13223a;
  --text: #e4ecf8;
  --muted: #8da1bf;
  --soft: #526882;
  --line: rgba(141, 161, 191, 0.18);
  --accent: #3b82f6;
  --green: #11c98f;
  --red: #ef476f;
  --amber: #f59e0b;
  --purple: #8b5cf6;
  --radius: 8px;
  --grid-dot: rgba(141, 161, 191, 0.14);
  --shadow: rgba(0, 0, 0, 0.35);
  font-family: "Segoe UI", "Aptos", sans-serif;
}


* {
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  margin: 0;
  color: var(--text);
  background: var(--bg);
}

button,
input,
select {
  font: inherit;
}

button {
  white-space: nowrap;
}

h1,
h2,
p {
  margin: 0;
}

h1 {
  margin-top: 10px;
  font-size: calc(28px * var(--fs));
}

h2 {
  font-size: calc(18px * var(--fs));
}

p,
.muted {
  color: var(--muted);
}

.shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 230px minmax(0, 1fr);
}

.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  padding: 22px 16px;
  border-right: 1px solid var(--line);
  background: var(--sidebar);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 26px;
}

.login-brand {
  margin-bottom: 28px;
}

.brand-mark {
  width: 38px;
  height: 38px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: #fff;
  font-weight: 800;
  font-size: calc(13px * var(--fs));
}

.brand-title {
  font-size: calc(17px * var(--fs));
  font-weight: 800;
}

.brand-subtitle {
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.nav {
  display: grid;
  gap: 5px;
}

.nav-item {
  width: 100%;
  border: 1px solid transparent;
  border-radius: 7px;
  padding: 10px 12px;
  color: var(--muted);
  background: transparent;
  text-align: left;
  cursor: pointer;
}

.nav-item.active,
.nav-item:hover {
  color: var(--text);
  border-color: rgba(59, 130, 246, 0.18);
  background: rgba(59, 130, 246, 0.12);
}

.content {
  min-width: 0;
  padding: 24px 28px 38px;
}

.topbar {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  align-items: center;
  margin-bottom: 22px;
}

.badge,
.status-pill {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 9px;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.035);
  font-size: calc(12px * var(--fs));
}

.login-wrap {
  height: 100dvh;
  min-height: 100%;
  display: grid;
  overflow: auto;
  background: var(--bg);
}

.login-wrap:has(.login-stage) {
  grid-template-columns: minmax(0, 1.15fr) minmax(300px, 460px);
}

.login-wrap:not(:has(.login-stage)) {
  place-items: center;
  padding: 22px;
}

.login-stage {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 28px;
  min-height: 100%;
  padding: 36px 48px 40px;
  overflow: hidden;
  color: #f4f8fb;
  background:
    radial-gradient(820px 480px at 12% 0%, rgba(26, 124, 255, 0.38), transparent 62%),
    radial-gradient(640px 420px at 100% 100%, rgba(20, 211, 106, 0.22), transparent 58%),
    #071018;
}

.login-beam {
  position: absolute;
  z-index: 0;
  left: -12%;
  right: -8%;
  top: 46%;
  height: 16px;
  background: linear-gradient(90deg, transparent, #0a6cff 18%, #12c45a 82%, transparent);
  transform: rotate(-18deg);
  opacity: 0.72;
  pointer-events: none;
}

.login-stage-brand,
.login-stage-copy,
.login-tower-wrap {
  position: relative;
  z-index: 1;
}

.login-stage-brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.login-stage-brand strong {
  display: block;
  font-size: calc(16px * var(--fs));
  letter-spacing: 0.2px;
}

.login-stage-brand small {
  display: block;
  margin-top: 2px;
  color: rgba(244, 248, 251, 0.62);
  font-size: calc(12px * var(--fs));
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.login-mark {
  width: 56px;
  height: 35px;
  display: block;
  flex-shrink: 0;
}

.login-tower-wrap {
  flex: 1;
  display: grid;
  place-items: center;
  min-height: 180px;
}

.login-tower {
  width: min(420px, 92%);
  height: auto;
  filter: drop-shadow(0 18px 30px rgba(0, 0, 0, 0.35));
}

.login-tower .wave {
  animation: login-wave 3.8s ease-in-out infinite;
}

.login-tower .wave-b {
  animation-delay: 0.7s;
  opacity: 0.45;
}

@keyframes login-wave {
  0%, 100% { opacity: 0.28; }
  50% { opacity: 1; }
}

.login-stage-copy {
  max-width: 560px;
}

.login-stage-copy h1 {
  margin: 0;
  max-width: 11ch;
  font-size: clamp(calc(36px * var(--fs)), 4.4vw, calc(62px * var(--fs)));
  line-height: 0.96;
  letter-spacing: -0.04em;
}

.login-stage-copy p {
  max-width: 38ch;
  margin: 14px 0 0;
  color: rgba(244, 248, 251, 0.74);
  font-size: calc(16px * var(--fs));
  line-height: 1.45;
}

.login-points {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 22px;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
}

.login-points li {
  display: flex;
  align-items: center;
  gap: 10px;
  color: rgba(244, 248, 251, 0.9);
  font-size: calc(14px * var(--fs));
  font-weight: 600;
}

.login-points svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: #3ecf8e;
}

.login-points li:nth-child(odd) svg {
  color: #4da3ff;
}

.login-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 100%;
  padding: 40px;
  border: 0;
  border-radius: 0;
  background: #0c141c;
  color: #f4f8fb;
}

.login-wrap:not(:has(.login-stage)) .login-panel {
  width: min(460px, 100%);
  min-height: 0;
  padding: 28px;
  border: 1px solid var(--border, var(--line));
  border-radius: 16px;
}

.login-form-wrap {
  width: min(360px, 100%);
  margin: auto;
}

.login-eyebrow {
  margin: 0 0 8px;
  color: #6eb6ff;
  font-size: calc(12px * var(--fs));
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}

.login-panel h2 {
  margin: 0;
  font-size: calc(32px * var(--fs));
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.login-lede {
  margin: 10px 0 26px;
  color: rgba(244, 248, 251, 0.66);
  font-size: calc(14.5px * var(--fs));
  line-height: 1.45;
}

.login-form {
  gap: 16px;
}

.login-form .label {
  color: rgba(244, 248, 251, 0.62);
}

.login-form .input {
  min-height: 48px;
  border-radius: 10px;
  padding: 12px 14px;
  background: #121a22;
  border-color: rgba(244, 248, 251, 0.14);
  color: #f4f8fb;
}

.login-form .input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim, rgba(59, 130, 246, 0.16));
}

html .login-form .btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 48px;
  margin-top: 4px;
  border-radius: 10px;
  color: #fff;
  font-weight: 700;
  background: linear-gradient(115deg, #0a6cff 0%, #0a6cff 76%, #12c45a 100%);
  box-shadow: none;
}

.login-form .btn-primary.is-busy::before {
  content: "";
  width: 15px;
  height: 15px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: login-spin 0.7s linear infinite;
}

@keyframes login-spin {
  to { transform: rotate(360deg); }
}

.login-wrap.is-leaving .login-stage {
  animation: login-stage-out 560ms var(--ease) forwards;
}

.login-wrap.is-leaving .login-panel {
  animation: login-panel-out 560ms var(--ease) forwards;
}

@keyframes login-stage-out {
  to {
    opacity: 0;
    transform: translateX(-36px);
  }
}

@keyframes login-panel-out {
  to {
    opacity: 0;
    transform: translateY(18px);
  }
}

#app.is-arriving > .sidebar {
  animation: login-arrive-fade 520ms var(--ease) both;
}

#app.is-arriving > .main-wrap,
#app.is-arriving > .administration {
  animation: login-arrive-main 680ms var(--ease) both;
}

@keyframes login-arrive-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes login-arrive-main {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 900px) {
  .login-wrap:has(.login-stage) {
    display: flex;
    flex-direction: column;
    background: #071018;
  }

  .login-stage {
    flex: 1 1 auto;
    justify-content: space-between;
    min-height: 0;
    gap: 10px;
    padding: calc(16px + env(safe-area-inset-top)) 20px 0;
    background: transparent;
  }

  .login-tower-wrap {
    flex: none;
    min-height: 0;
    height: 118px;
  }

  .login-tower {
    width: 168px;
  }

  .login-beam,
  .login-points {
    display: none;
  }

  .login-stage-copy h1 {
    max-width: 12ch;
    font-size: calc(30px * var(--fs));
  }

  .login-stage-copy p {
    margin-top: 8px;
    font-size: calc(14px * var(--fs));
  }

  .login-panel {
    flex: 0 0 auto;
    min-height: 0;
    padding: 16px 20px calc(18px + env(safe-area-inset-bottom));
    background: transparent;
  }

  .login-form-wrap {
    width: 100%;
    margin: 0;
  }

  .login-panel h2 {
    font-size: calc(26px * var(--fs));
  }

  .login-lede {
    margin-bottom: 18px;
  }
}

@media (max-width: 900px) and (max-height: 700px) {
  .login-tower-wrap,
  .login-stage-copy p {
    display: none;
  }

  .login-stage {
    padding-bottom: 4px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .login-tower .wave,
  .login-form .btn-primary.is-busy::before,
  .login-wrap.is-leaving .login-stage,
  .login-wrap.is-leaving .login-panel,
  #app.is-arriving > .sidebar,
  #app.is-arriving > .main-wrap,
  #app.is-arriving > .administration {
    animation: none;
    opacity: 1;
  }

  .login-tower .wave {
    opacity: 0.75;
  }
}

.panel,
.metric-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
}

.panel {
  position: relative;
  padding: 18px;
}

.panel-head {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  align-items: flex-start;
  margin-bottom: 18px;
}

.panel-head p {
  margin-top: 5px;
  font-size: calc(13px * var(--fs));
}

.kpi-grid,
.router-metrics {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}

/* auto-fit y no tres fijas: con cuatro tarjetas la ultima quedaba sola en
   una fila nueva. */
.router-metrics {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.metric-card {
  padding: 14px;
}

.metric-card span,
.metric-card small {
  display: block;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.metric-card strong {
  display: block;
  margin: 8px 0 4px;
  font-size: calc(24px * var(--fs));
  line-height: 1.1;
}

.dashboard-grid,
.mikrotik-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  align-items: start;
}

/* Dos columnas: a la izquierda el formulario y RouterOS uno bajo el otro, a la
   derecha el panel de red, que es el mas alto. Antes los tres paneles iban
   sueltos en la cuadricula y el tercero caia a una fila nueva, dejando media
   pantalla vacia a su lado. */
.mikrotik-layout.has-form {
  grid-template-columns: minmax(340px, 0.85fr) minmax(0, 1.15fr);
}

.mikrotik-col {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.chart-surface {
  min-height: 240px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    linear-gradient(rgba(141, 161, 191, 0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(141, 161, 191, 0.06) 1px, transparent 1px),
    var(--panel-2);
  background-size: 42px 42px;
  position: relative;
  overflow: hidden;
}

.chart-surface.report {
  min-height: 310px;
}

.chart-line {
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: 34%;
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--green));
  transform: rotate(-8deg);
}

.chart-line.short {
  right: 36%;
  bottom: 55%;
  background: var(--amber);
}

.chart-line.mid {
  left: 26%;
  bottom: 22%;
  background: var(--red);
}

.split-list {
  display: grid;
  gap: 10px;
}

.split-list div {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-2);
  padding: 13px;
}

.split-list strong,
.split-list span {
  display: block;
}

.split-list span {
  color: var(--muted);
  font-size: calc(13px * var(--fs));
  margin-top: 4px;
}

.form {
  display: grid;
  gap: 14px;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.profile-toolbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 8px;
  align-items: end;
}

.profile-list {
  display: grid;
  gap: 8px;
}

.profile-item {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 10px 12px;
  color: var(--text);
  background: var(--panel-2);
  text-align: left;
  cursor: pointer;
}

.profile-item.selected {
  border-color: rgba(59, 130, 246, 0.72);
  background: rgba(59, 130, 246, 0.12);
}

.profile-item strong,
.profile-item span {
  display: block;
}

.profile-item span {
  margin-top: 3px;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.field {
  display: grid;
  gap: 6px;
}

.password-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
}

.mode-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}

.mode-pill {
  min-height: 36px;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 12px;
  color: var(--muted);
  background: var(--panel-2);
  cursor: pointer;
}

.mode-pill.active {
  color: var(--text);
  border-color: rgba(59, 130, 246, 0.72);
  background: rgba(59, 130, 246, 0.12);
}

.hint-box {
  border: 1px solid rgba(245, 158, 11, 0.38);
  border-radius: 9px;
  padding: 12px;
  margin-bottom: 12px;
  color: #fbbf24;
  background: rgba(245, 158, 11, 0.1);
  font-size: calc(13px * var(--fs));
  line-height: 1.45;
}

/* Variante verde del aviso: sirve para confirmar que la PC si llega al router. */
.hint-box.is-ok {
  border-color: rgba(34, 197, 94, 0.38);
  color: #4ade80;
  background: rgba(34, 197, 94, 0.1);
}

/* Tarjeta de red sin cable: se atenua para que salte a la vista. */
/* Las consultas del cliente reusan la tarjeta de los modales grandes, pero mas
   angostas: son listas, no formularios. */
.consulta-card {
  width: min(760px, 100%);
}

/* Menu "..." de cada fila del directorio. Seis botones por fila no se leen en
   una lista de cientos: quedan a la vista los dos de todos los dias y el resto
   se despliega. */
.client-mas {
  position: relative;
  display: inline-flex;
}

.client-mas-boton {
  letter-spacing: 1px;
  min-width: 34px;
}

.client-mas-menu {
  /* Fijo a la ventana: dentro de la tabla, el contenedor con scroll lo
     recortaba. La posicion la calcula el guion al abrirlo. */
  position: fixed;
  z-index: 60;
  min-width: 168px;
  display: flex;
  flex-direction: column;
  padding: 5px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: 0 14px 34px var(--shadow);
}

.client-mas-menu[hidden] { display: none; }

.client-mas-menu button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: calc(13px * var(--fs));
  text-align: left;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
}

.client-mas-menu button:hover {
  background: var(--panel-2);
}

/* Dar de baja no se pone junto a las demas sin avisar de que va. */
.client-mas-menu button.peligro { color: var(--red); }

/* La fila de conflicto ahora lleva accion: el texto a la izquierda y el boton
   de liberar a la derecha. */
.client-conflict-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.client-conflict-row > div { min-width: 0; }
.client-conflict-row .btn { flex: none; }

/* Recomendacion de conexion: es lo primero que se lee al abrir la pestana, asi
   que lleva el peso visual del panel. Verde cuando ya se puede conectar, ambar
   cuando falta algo que resolver en el router. */
.advice {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  border: 1px solid var(--line);
  border-left: 3px solid var(--amber);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 16px;
  background: var(--panel-2);
}

.advice.is-ready {
  border-left-color: var(--green);
}

.advice-copy {
  flex: 1 1 320px;
  min-width: 0;
}

.advice-copy strong {
  display: block;
  font-size: calc(15px * var(--fs));
  margin-bottom: 4px;
}

.advice-copy p {
  margin: 0;
  font-size: calc(13.5px * var(--fs));
  color: var(--muted);
  line-height: 1.5;
}

.advice-action {
  margin-top: 6px !important;
  color: var(--text) !important;
}

.advice .btn {
  flex: none;
}

/* Lista de vecinos MNDP: el equivalente a la pestana Neighbors de WinBox. */
.neighbors-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 26px 0 12px;
  font-size: calc(15px * var(--fs));
  font-weight: 600;
}

.neighbors-title span {
  font-size: calc(12px * var(--fs));
  font-weight: 500;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 1px 8px;
}

[data-mikrotik-neighbors] .neighbors-title:first-child {
  margin-top: 4px;
}

/* Un vecino sin IP se ve, pero no se puede administrar: la API necesita IP. */
.neighbor-noip {
  color: var(--amber);
  font-size: calc(12px * var(--fs));
}

.neighbor-mac {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(12px * var(--fs));
  white-space: nowrap;
}

[data-pc-network] .metric-card strong {
  font-size: calc(18px * var(--fs));
  overflow-wrap: anywhere;
}

[data-pc-network] tr.is-down {
  opacity: 0.62;
}

[data-pc-network] tr.is-down[data-role="lan"] td:first-child strong::after {
  content: ' · sin cable';
  color: #fbbf24;
  font-weight: 600;
}

.diag-list {
  display: grid;
  gap: 8px;
  margin-bottom: 12px;
}

.diag-step {
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 10px 12px;
  background: var(--panel-2);
}

.diag-step strong,
.diag-step span {
  display: block;
}

.diag-step span {
  margin-top: 4px;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
  line-height: 1.4;
}

.diag-step.ok {
  border-color: rgba(17, 201, 143, 0.42);
}

.diag-step.fail {
  border-color: rgba(239, 71, 111, 0.42);
}

.client-row {
  cursor: pointer;
}

.client-row.selected {
  background: rgba(59, 130, 246, 0.12);
}

.clients-page {
  display: grid;
  min-width: 0;
  gap: 14px;
}

.clients-kpi .metric-card {
  width: 100%;
  text-align: left;
  cursor: pointer;
  white-space: normal;
}

.kpi-filter.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

.kpi-activo::before {
  background: var(--green);
}

.kpi-suspendido::before {
  background: var(--red);
}

.kpi-moroso::before {
  background: var(--amber);
}

.clients-workspace {
  display: grid;
  grid-template-columns: minmax(280px, 380px) minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}

.clients-list-panel,
.clients-ficha-panel {
  min-height: calc(100vh - 250px);
}

.clients-toolbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 150px;
  gap: 10px;
  align-items: end;
  margin-bottom: 12px;
}

.clients-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.client-list {
  display: grid;
  gap: 8px;
  max-height: calc(100vh - 390px);
  overflow: auto;
  padding-right: 2px;
}

.client-card {
  width: 100%;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  border: 1px solid var(--border, var(--line));
  border-radius: 10px;
  padding: 10px 12px;
  color: inherit;
  background: var(--surface-2, var(--panel-2));
  text-align: left;
  cursor: pointer;
  white-space: normal;
}

.client-card:hover,
.client-card.selected {
  border-color: var(--accent);
  background: var(--accent-dim, rgba(59, 130, 246, 0.12));
}

.client-avatar {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  background: var(--accent-dim, rgba(59, 130, 246, 0.14));
  color: var(--accent);
  font-size: calc(12px * var(--fs));
  font-weight: 700;
  flex: none;
}

.client-avatar.lg {
  width: 48px;
  height: 48px;
  font-size: calc(14px * var(--fs));
}

.client-card-body {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.client-card-body strong,
.client-card-body span,
.client-card-body code {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-card-body span,
.client-card-side small {
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.client-card-body code {
  font-size: calc(11px * var(--fs));
  color: var(--text);
}

.client-card-side {
  display: grid;
  justify-items: end;
  gap: 6px;
}

.ficha-hero {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border, var(--line));
}

.ficha-hero h2 {
  font-size: calc(20px * var(--fs));
}

.ficha-hero p {
  margin-top: 4px;
  font-size: calc(13px * var(--fs));
}

.ficha-section {
  display: grid;
  gap: 12px;
  margin-bottom: 6px;
}

.ficha-section h3 {
  margin: 0;
  font-size: calc(12px * var(--fs));
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.ficha-note {
  margin: 0;
  font-size: calc(12px * var(--fs));
  line-height: 1.45;
  color: var(--muted);
}

.ficha-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ficha-empty {
  min-height: 280px;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 8px;
  text-align: center;
  padding: 28px 18px;
}

.ficha-empty.compact {
  min-height: 0;
  padding: 18px 12px;
  border: 1px dashed var(--border, var(--line));
  border-radius: 10px;
}

.ficha-empty h2 {
  margin-top: 6px;
}

textarea.input {
  min-height: 78px;
  resize: vertical;
}

.client-status-activo {
  color: #b8f6df;
  border-color: rgba(17, 201, 143, 0.35);
  background: rgba(17, 201, 143, 0.12);
}

.client-status-suspendido {
  color: #ffd7df;
  border-color: rgba(239, 71, 111, 0.35);
  background: rgba(239, 71, 111, 0.12);
}

.client-status-moroso {
  color: #fde68a;
  border-color: rgba(245, 158, 11, 0.4);
  background: rgba(245, 158, 11, 0.12);
}

[data-scheme="light"] .client-status-activo {
  color: #1f7a52;
  background: rgba(42, 157, 106, 0.12);
}

[data-scheme="light"] .client-status-suspendido {
  color: #b42318;
  background: rgba(220, 53, 69, 0.1);
}

[data-scheme="light"] .client-status-moroso {
  color: #9a6700;
  background: rgba(194, 123, 33, 0.12);
}

.equip-block {
  margin-top: 22px;
  display: grid;
  gap: 12px;
}

.equip-item {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 10px 12px;
  background: var(--panel-2);
}

.equip-item span {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.billing-toolbar {
  grid-template-columns: 150px minmax(0, 1fr) 150px;
}

.invoice-status-pagada {
  color: #b8f6df;
  border-color: rgba(17, 201, 143, 0.35);
  background: rgba(17, 201, 143, 0.12);
}

.invoice-status-pendiente {
  color: #fde68a;
  border-color: rgba(245, 158, 11, 0.4);
  background: rgba(245, 158, 11, 0.12);
}

.invoice-status-vencida,
.invoice-status-anulada {
  color: #ffd7df;
  border-color: rgba(239, 71, 111, 0.35);
  background: rgba(239, 71, 111, 0.12);
}

/* Concepto de la factura: la mensualidad queda neutra para que los cobros
   aparte (instalacion, equipo, reconexion, recargo) resalten en la tabla. */
.invoice-concept-mensualidad {
  color: var(--text-3);
  border-color: var(--border);
  background: transparent;
}

.invoice-concept-instalacion {
  color: #c7dbff;
  border-color: rgba(59, 130, 246, 0.38);
  background: rgba(59, 130, 246, 0.14);
}

.invoice-concept-equipo {
  color: #e0d4ff;
  border-color: rgba(139, 92, 246, 0.38);
  background: rgba(139, 92, 246, 0.14);
}

.invoice-concept-reconexion {
  color: #b8f6df;
  border-color: rgba(17, 201, 143, 0.35);
  background: rgba(17, 201, 143, 0.12);
}

.invoice-concept-recargo {
  color: #fde68a;
  border-color: rgba(245, 158, 11, 0.4);
  background: rgba(245, 158, 11, 0.12);
}

.invoice-concept-otro {
  color: var(--text-2);
  border-color: var(--border-2);
  background: var(--surface-2);
}

/* Los tonos de arriba estan pensados sobre fondo oscuro; en claro hay que
   invertir la relacion y usar el color saturado en el texto. */
[data-scheme="light"] .invoice-concept-instalacion {
  color: #1d4f91;
  background: rgba(59, 130, 246, 0.12);
}

[data-scheme="light"] .invoice-concept-equipo {
  color: #5b3fa8;
  background: rgba(124, 92, 191, 0.12);
}

[data-scheme="light"] .invoice-concept-reconexion {
  color: #1f7a52;
  background: rgba(42, 157, 106, 0.12);
}

[data-scheme="light"] .invoice-concept-recargo {
  color: #9a6700;
  background: rgba(194, 123, 33, 0.12);
}

.billing-table {
  width: 100%;
}

.billing-row {
  cursor: pointer;
}

.billing-row.selected {
  background: var(--accent-dim, rgba(59, 130, 246, 0.12));
}

.pay-toggle {
  display: inline-flex;
  gap: 4px;
}

.pay-toggle.big {
  display: flex;
  margin-bottom: 16px;
}

.pay-chip {
  border: 1px solid var(--border, var(--line));
  border-radius: 999px;
  padding: 5px 10px;
  color: var(--muted);
  background: transparent;
  cursor: pointer;
  font-size: calc(12px * var(--fs));
}

.pay-chip.on.paid {
  color: #b8f6df;
  border-color: rgba(17, 201, 143, 0.45);
  background: rgba(17, 201, 143, 0.14);
}

.pay-chip.on.unpaid {
  color: #fde68a;
  border-color: rgba(245, 158, 11, 0.45);
  background: rgba(245, 158, 11, 0.14);
}

[data-scheme="light"] .pay-chip.on.paid {
  color: #1f7a52;
}

[data-scheme="light"] .pay-chip.on.unpaid {
  color: #9a6700;
}

.invoice-client-results {
  display: grid;
  gap: 6px;
  margin-top: 8px;
}

.client-history-list {
  display: grid;
  gap: 8px;
}

.history-invoice {
  width: 100%;
  text-align: left;
  cursor: pointer;
}

.history-invoice:disabled {
  cursor: default;
  opacity: 1;
}

[data-scheme="light"] .invoice-status-pagada {
  color: #1f7a52;
  background: rgba(42, 157, 106, 0.12);
}

[data-scheme="light"] .invoice-status-pendiente {
  color: #9a6700;
  background: rgba(194, 123, 33, 0.12);
}

[data-scheme="light"] .invoice-status-vencida,
[data-scheme="light"] .invoice-status-anulada {
  color: #b42318;
  background: rgba(220, 53, 69, 0.1);
}

@media (max-width: 1100px) {
  .clients-workspace {
    grid-template-columns: 1fr;
  }

  .clients-list-panel,
  .clients-ficha-panel,
  .client-list {
    min-height: 0;
    max-height: none;
  }
}

@media (max-width: 760px) {
  .clients-toolbar,
  .billing-toolbar {
    grid-template-columns: 1fr;
  }
}

.status-pill[data-state="ok"] {
  color: #b8f6df;
  border-color: rgba(17, 201, 143, 0.42);
  background: rgba(17, 201, 143, 0.12);
}

.status-pill[data-state="error"] {
  color: #ff9db4;
  border-color: rgba(239, 71, 111, 0.42);
  background: rgba(239, 71, 111, 0.12);
}

[data-scheme="light"] .status-pill[data-state="ok"] {
  color: #1f7a52;
  background: rgba(42, 157, 106, 0.12);
}

[data-scheme="light"] .status-pill[data-state="error"] {
  color: #b42318;
  background: rgba(220, 53, 69, 0.1);
}

/* Vista previa de la importacion desde Excel. Es una pantalla de revision, no
   un aviso: ocupa casi toda la ventana porque hay que leer fila por fila. */
.imp-modal {
  position: fixed;
  inset: 0;
  z-index: 310;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(4, 9, 17, 0.72);
  backdrop-filter: blur(6px);
}

.imp-card {
  width: min(1080px, 100%);
  max-height: calc(100vh - 40px);
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  box-shadow: 0 24px 60px var(--shadow);
  overflow: hidden;
}

.imp-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 22px 14px;
  border-bottom: 1px solid var(--line);
}

.imp-head h2 { margin: 4px 0 4px; font-size: calc(19px * var(--fs)); }
.imp-head p { margin: 0; font-size: calc(13px * var(--fs)); color: var(--muted); }

/* El alcance se lee antes que cualquier otra cosa: es la duda que siempre
   aparece al importar datos que rozan al router. */
.imp-alcance {
  margin: 14px 22px 0;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--green);
  border-radius: var(--radius);
  background: var(--panel-2);
  font-size: calc(13px * var(--fs));
  line-height: 1.55;
  color: var(--muted);
}

.imp-alcance strong { color: var(--text); }

.imp-lista {
  overflow-y: auto;
  padding: 10px 22px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.imp-fila {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-2);
  padding: 14px 16px;
}

.imp-cabeza {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 14px;
  align-items: start;
}

@media (max-width: 720px) {
  .imp-cabeza { grid-template-columns: auto 1fr; }
  .imp-destino { grid-column: 1 / -1; }
}

.imp-check {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.imp-titulo strong { display: block; font-size: calc(15px * var(--fs)); }
.imp-titulo span { font-size: calc(12.5px * var(--fs)); color: var(--muted); }

.imp-destino {
  text-align: right;
  font-size: calc(12.5px * var(--fs));
  max-width: 340px;
}

@media (max-width: 720px) {
  .imp-destino { text-align: left; max-width: none; }
}

/* El nombre de la cola es texto del router: monoespaciado para que se note que
   viene tal cual de ahi y no lo escribio nadie del panel. */
.imp-cola {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(11.5px * var(--fs));
  overflow-wrap: anywhere;
}

.imp-aviso {
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid rgba(245, 158, 11, 0.35);
  background: rgba(245, 158, 11, 0.1);
  color: var(--amber);
  font-size: calc(12.5px * var(--fs));
  line-height: 1.5;
}

.imp-dup {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  font-size: calc(12.5px * var(--fs));
}

.imp-dup > strong { display: block; margin-bottom: 8px; }
.imp-dup > small { display: block; margin-top: 8px; color: var(--soft); }

.imp-dup-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}

.imp-dup-fila label { display: flex; align-items: center; gap: 6px; cursor: pointer; }

/* Borrar en el router es la unica accion de aqui que sale del sistema. */
.imp-dup-router { color: var(--red); }
.imp-dup-router input:disabled + * ,
.imp-dup-router:has(input:disabled) { color: var(--soft); cursor: default; }

/* El icono del calendario de los <input type="date"> lo pinta el navegador en
   negro. Sobre el tema oscuro desaparece, asi que se invierte; en el claro se
   deja como viene, que ahi si contrasta. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator {
  filter: invert(1) opacity(0.55);
  cursor: pointer;
  transition: opacity var(--dur);
}

input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="time"]::-webkit-calendar-picker-indicator:hover,
input[type="month"]::-webkit-calendar-picker-indicator:hover {
  filter: invert(1) opacity(0.95);
}

[data-scheme="light"] input[type="date"]::-webkit-calendar-picker-indicator,
[data-scheme="light"] input[type="time"]::-webkit-calendar-picker-indicator,
[data-scheme="light"] input[type="month"]::-webkit-calendar-picker-indicator {
  filter: opacity(0.5);
}

[data-scheme="light"] input[type="date"]::-webkit-calendar-picker-indicator:hover,
[data-scheme="light"] input[type="time"]::-webkit-calendar-picker-indicator:hover,
[data-scheme="light"] input[type="month"]::-webkit-calendar-picker-indicator:hover {
  filter: opacity(0.9);
}

/* Un dia con clientes por cobrar se marca aparte de los que solo tienen
   facturas ya emitidas: es lo que se mira antes de salir a cobrar. */
/* Grafico de consumo por dia. Barras sencillas dibujadas con CSS: son doce o
   noventa valores, no hace falta traer una libreria para esto. */
.consumo-grafico {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 160px;
  margin: 18px 0 20px;
  padding: 0 2px;
  overflow-x: auto;
}

.consumo-barra {
  flex: 1 0 26px;
  min-width: 26px;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 6px;
}

.consumo-barra-valor {
  width: 100%;
  border-radius: 3px 3px 0 0;
  background: linear-gradient(180deg, var(--accent), var(--accent-dim, rgba(59, 130, 246, 0.35)));
  transition: filter var(--dur);
}

.consumo-barra:hover .consumo-barra-valor { filter: brightness(1.25); }

.consumo-barra span {
  font-size: calc(10px * var(--fs));
  color: var(--muted);
  white-space: nowrap;
}

[data-consumo-cliente] { cursor: pointer; }
[data-consumo-cliente]:hover { background: var(--panel-2); }

td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* El detalle de un cliente reusa la tarjeta del dialogo, pero mas ancha. */
.consumo-detalle { width: min(720px, 100%); }
.consumo-detalle h2 { margin: 0 0 4px; }
.consumo-detalle .router-metrics { margin-top: 16px; }

/* Barra de filtros. Las pastillas del resumen son botones: con 41 filas, ir a
   buscar las 7 que piden decision a ojo era el peor momento de la pantalla. */
.imp-barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 22px 10px;
}

.imp-chips { display: flex; flex-wrap: wrap; gap: 8px; }

.imp-chip {
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--muted);
  border-radius: 999px;
  padding: 5px 13px;
  font-size: calc(12.5px * var(--fs));
  font-family: inherit;
  cursor: pointer;
  transition: border-color var(--dur), color var(--dur), background var(--dur);
}

.imp-chip b { color: var(--text); font-weight: 600; }
.imp-chip:hover { border-color: var(--accent); }

.imp-chip.activo {
  border-color: var(--accent);
  background: var(--accent-dim, rgba(59, 130, 246, 0.12));
  color: var(--text);
}

.imp-herramientas {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.imp-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: calc(12.5px * var(--fs));
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}

.imp-buscar { min-width: 220px; padding: 7px 11px; font-size: calc(13px * var(--fs)); }

/* Tabla de comparacion de una ficha. */
.imp-tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: calc(13px * var(--fs));
  margin-top: 12px;
}

.imp-tabla th {
  text-align: left;
  font-size: calc(11px * var(--fs));
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 7px 12px;
  background: var(--panel-3);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

.imp-tabla td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

.imp-tabla tr[hidden] { display: none; }
.imp-tabla tr:last-child td { border-bottom: 0; }

.imp-tabla .imp-etq { color: var(--muted); width: 130px; }
.imp-tabla .imp-sis { color: var(--text); overflow-wrap: anywhere; }
.imp-tabla .imp-exc { overflow-wrap: anywhere; }
.imp-marca-celda { width: 1%; text-align: right; white-space: nowrap; }

/* El fondo de la celda del Excel dice de un vistazo que va a pasar con ella. */
.imp-exc-cambio { background: rgba(245, 158, 11, 0.08); }
.imp-exc-revisar { background: rgba(239, 71, 111, 0.07); }

.imp-igual-txt { color: var(--muted); }
.imp-vacio { color: var(--soft); font-style: italic; }

.imp-fuente {
  display: block;
  margin-top: 2px;
  font-size: calc(10.5px * var(--fs));
  color: var(--soft);
  font-style: normal;
}

.imp-exc .input { width: 100%; padding: 6px 9px; font-size: calc(13px * var(--fs)); }

.imp-nada { color: var(--soft); text-align: center; padding: 14px; }

.scroll-x { overflow-x: auto; }

[data-imp-fila][hidden] { display: none; }

.imp-pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 22px;
  border-top: 1px solid var(--line);
  background: var(--panel);
  font-size: calc(13px * var(--fs));
  color: var(--muted);
}

/* Marcas de estado de cada fila. */
.marca.gris { color: var(--soft); background: rgba(141, 161, 191, 0.12); }
.marca.ojo  { color: var(--amber); background: rgba(245, 158, 11, 0.12); }
.marca.si   { color: var(--green); background: rgba(17, 201, 143, 0.12); }
.marca.no   { color: var(--red); background: rgba(239, 71, 111, 0.12); }

.marca {
  display: inline-block;
  font-size: calc(11px * var(--fs));
  font-weight: 500;
  letter-spacing: 0.03em;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}

/* Confirmacion propia, en lugar de la del navegador. Comparte el lenguaje del
   modal de conexion: velo a pantalla completa y tarjeta centrada. */
.dialogo {
  position: fixed;
  inset: 0;
  /* Por encima de todo, incluido el modal de conexion (300). */
  z-index: 320;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(4, 9, 17, 0.72);
  backdrop-filter: blur(6px);
  animation: connect-modal-in var(--dur) ease-out;
}

.dialogo-card {
  width: min(460px, 100%);
  padding: 24px 24px 20px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  box-shadow: 0 24px 60px var(--shadow);
}

.dialogo-card h2 {
  margin: 0 0 10px;
  font-size: calc(17px * var(--fs));
  line-height: 1.3;
}

.dialogo-texto p {
  margin: 0 0 8px;
  font-size: calc(13.5px * var(--fs));
  line-height: 1.55;
  color: var(--muted);
}

.dialogo-campos {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 14px;
}

.dialogo-error {
  margin-top: 10px;
  font-size: calc(12.5px * var(--fs));
  color: var(--red);
}

.dialogo-error[hidden] { display: none; }

/* Desglose de la rebaja: se lee de arriba abajo como un recibo. */
.rebaja-cuadro {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0 4px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-2);
  font-size: calc(13.5px * var(--fs));
}

.rebaja-cuadro div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
}

.rebaja-menos b { color: var(--amber); }

.rebaja-neto {
  border-top: 1px solid var(--line);
  padding-top: 6px;
  margin-top: 2px;
  font-size: calc(15px * var(--fs));
}

.rebaja-neto b { color: var(--green); }

.dialogo-acciones {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}

@media (max-width: 460px) {
  .dialogo-acciones {
    flex-direction: column-reverse;
  }
}

/* Modal de conexion. Antes era una capa dentro del panel: tapaba media tarjeta
   y se perdia si la pagina estaba desplazada. Ahora es un modal centrado sobre
   toda la pantalla, que es lo que corresponde a una operacion que bloquea. */
.connect-modal {
  position: fixed;
  inset: 0;
  /* Por encima de la barra lateral (100) y de los modales del sistema (200):
     mientras conecta no se puede tocar nada, y eso se tiene que ver. */
  z-index: 300;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(4, 9, 17, 0.72);
  backdrop-filter: blur(6px);
  animation: connect-modal-in var(--dur) ease-out;
}

.connect-card {
  width: min(420px, 100%);
  display: grid;
  gap: 14px;
  justify-items: center;
  text-align: center;
  padding: 30px 26px 24px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  box-shadow: 0 24px 60px var(--shadow);
}

.connect-card b {
  font-size: calc(17px * var(--fs));
  line-height: 1.25;
}

.connect-card p {
  margin: -6px 0 0;
  font-size: calc(13.5px * var(--fs));
  color: var(--muted);
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.connect-card small {
  font-size: calc(12px * var(--fs));
  color: var(--soft);
  line-height: 1.5;
  border-top: 1px solid var(--line);
  padding-top: 12px;
}

@keyframes connect-modal-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.radar {
  width: 84px;
  height: 84px;
  position: relative;
}

.radar span,
.radar strong {
  position: absolute;
  inset: 0;
  border-radius: 50%;
}

.radar span {
  border: 1px solid var(--accent-glow, rgba(59, 130, 246, 0.28));
  animation: radar-pulse 1.8s ease-out infinite;
}

.radar span:nth-child(2) { animation-delay: 0.45s; }
.radar span:nth-child(3) { animation-delay: 0.9s; }

.radar strong {
  inset: 29px;
  background: var(--accent);
  box-shadow: 0 0 18px var(--accent-glow, rgba(59, 130, 246, 0.55));
}

/* Con movimiento reducido el radar se queda quieto en vez de latir. */
@media (prefers-reduced-motion: reduce) {
  .radar span { animation: none; opacity: 0.35; }
  .connect-modal { animation: none; }
}

.form.is-connecting,
.actions.is-connecting {
  pointer-events: none;
  opacity: 0.62;
}

@keyframes radar-pulse {
  0% { transform: scale(0.35); opacity: 0.8; }
  100% { transform: scale(1); opacity: 0; }
}

.label {
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.input,
.select {
  width: 100%;
  min-height: 42px;
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 9px 11px;
  color: var(--text);
  background: var(--panel-2);
  outline: none;
}

.input:focus,
.select:focus {
  border-color: rgba(59, 130, 246, 0.75);
}

.check {
  color: var(--muted);
  font-size: calc(13px * var(--fs));
}

.btn {
  min-height: 38px;
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 8px 12px;
  color: var(--text);
  background: var(--panel-3);
  cursor: pointer;
}

.btn-primary {
  border-color: transparent;
  background: var(--accent);
}

.btn-danger {
  border-color: rgba(239, 71, 111, 0.34);
  background: rgba(239, 71, 111, 0.12);
  color: #ff9db4;
}

.btn-small {
  min-height: 32px;
  padding: 6px 9px;
  font-size: calc(12px * var(--fs));
}

.password-toggle {
  min-width: 74px;
}

.btn:disabled {
  cursor: not-allowed;
  opacity: 0.62;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.message {
  display: none;
  border-radius: 7px;
  padding: 10px 12px;
  color: #ffd7df;
  background: rgba(239, 71, 111, 0.13);
  font-size: calc(13px * var(--fs));
}

.message.visible {
  display: block;
}

.message[data-type="success"] {
  color: #b8f6df;
  background: rgba(17, 201, 143, 0.13);
}

/* Los avisos de error y exito son el unico feedback de muchos formularios;
   en claro los tonos pastel quedaban casi invisibles. */
[data-scheme="light"] .message {
  color: #b42318;
  background: rgba(220, 53, 69, 0.1);
}

[data-scheme="light"] .message[data-type="success"] {
  color: #1f7a52;
  background: rgba(42, 157, 106, 0.12);
}

.table-wrap {
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  border-bottom: 1px solid var(--line);
  padding: 11px 9px;
  text-align: left;
  font-size: calc(13px * var(--fs));
}

th {
  color: var(--soft);
  font-size: calc(11px * var(--fs));
  text-transform: uppercase;
}

.empty {
  color: var(--muted);
  padding: 26px;
  text-align: center;
}

.empty.compact {
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
}

.network-map {
  position: relative;
  min-height: 420px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    radial-gradient(circle at center, rgba(59, 130, 246, 0.14), transparent 28%),
    var(--panel-2);
}

.network-map::before,
.network-map::after {
  content: "";
  position: absolute;
  left: 20%;
  right: 20%;
  top: 50%;
  height: 1px;
  background: rgba(59, 130, 246, 0.35);
}

.network-map::after {
  transform: rotate(90deg);
}

.node {
  position: absolute;
  width: 118px;
  min-height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(59, 130, 246, 0.48);
  border-radius: 7px;
  background: #0a1628;
  color: var(--text);
  font-size: calc(12px * var(--fs));
}

.node.core {
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-color: var(--accent);
}

.node.north {
  left: 18%;
  top: 18%;
}

.node.south {
  left: 18%;
  bottom: 18%;
}

.node.east {
  right: 18%;
  top: 18%;
}

.node.west {
  right: 18%;
  bottom: 18%;
}

.router-summary {
  display: grid;
  gap: 14px;
}

@media (max-width: 1100px) {
  .kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .dashboard-grid,
  .mikrotik-layout.has-form {
    grid-template-columns: 1fr;
  }

  .mikrotik-col {
    display: contents;
  }

  .mikrotik-layout [data-pc-panel] {
    order: 1;
  }

  .mikrotik-layout [data-mk-panel="routeros"] {
    order: 2;
  }
}

@media (max-width: 760px) {
  .shell {
    grid-template-columns: 1fr;
  }

  .sidebar {
    position: static;
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .content {
    padding: 18px;
  }

  .topbar,
  .panel-head {
    align-items: flex-start;
    flex-direction: column;
  }

  .kpi-grid,
  .router-metrics,
  .profile-toolbar,
  .form-grid {
    grid-template-columns: 1fr;
  }
}

/* Prototype shell compatibility */
:root {
  --surface: #0d1a2d;
  --surface-2: #122236;
  --surface-3: #1a3050;
  --border: rgba(59, 130, 246, 0.12);
  --border-2: rgba(59, 130, 246, 0.24);
  --accent-dim: rgba(59, 130, 246, 0.14);
  --accent-glow: rgba(59, 130, 246, 0.28);
  --green-dim: rgba(16, 217, 160, 0.12);
  --amber-dim: rgba(245, 158, 11, 0.12);
  --red-dim: rgba(244, 63, 94, 0.12);
  --purple-dim: rgba(167, 139, 250, 0.12);
  --text-1: #e2eaf8;
  --text-2: #7a92b8;
  --text-3: #3d5580;
  --font: "Space Grotesk", sans-serif;
  --mono: "JetBrains Mono", monospace;
  --sidebar-w: 256px;
  --sidebar-w-collapsed: 64px;
  --topbar-h: 60px;
  /* Movimiento del sistema. Una curva para casi todo, otra para lo que se
     desliza y frena. Nada usa linear: se nota y se siente barato. */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.34, 1.14, 0.44, 1);
  --dur-fast: 160ms;
  --dur: 240ms;
  --dur-slow: 360ms;
  color-scheme: dark;
}

[data-theme="claude"] {
  --bg: #faf9f5;
  --surface: #ffffff;
  --surface-2: #f5f2eb;
  --surface-3: #ede8dc;
  --border: rgba(0, 0, 0, 0.08);
  --border-2: rgba(217, 119, 87, 0.35);
  --accent: #d97757;
  --accent-dim: rgba(217, 119, 87, 0.1);
  --accent-glow: rgba(217, 119, 87, 0.22);
  --green: #2a9d6a;
  --amber: #c27b21;
  --red: #dc3545;
  --purple: #7c5cbf;
  --text-1: #1a1612;
  --text-2: #6b6154;
  --text-3: #a09384;
  --text: var(--text-1);
  --muted: var(--text-2);
  /* Variables de la primera version de la hoja. Seguian apuntando a los
     azules oscuros del tema noche, por eso en claro quedaban cajas negras
     con texto negro (tarjetas de moneda, inputs, mapa de red). */
  --sidebar: var(--surface);
  --panel: var(--surface);
  --panel-2: var(--surface-2);
  --panel-3: var(--surface-3);
  --line: var(--border);
  --soft: var(--text-3);
  --grid-dot: rgba(26, 22, 18, 0.09);
  --shadow: rgba(26, 22, 18, 0.1);
}

/* Luxuz: el azul y el verde del anillo del logo. La raya verde a la izquierda
   de los botones y la franja del icono son el corte diagonal de la marca. */
[data-theme="luxuz"] {
  --bg: #f4f7f6;
  --surface: #ffffff;
  --surface-2: #eef3f1;
  --surface-3: #e3eeea;
  --border: rgba(10, 28, 22, 0.08);
  --border-2: rgba(10, 108, 255, 0.32);
  --accent: #0a6cff;
  --accent-dim: rgba(10, 108, 255, 0.1);
  --accent-glow: rgba(10, 108, 255, 0.22);
  --green: #0b8f45;
  --green-dim: rgba(11, 143, 69, 0.12);
  --amber: #b86e12;
  --amber-dim: rgba(184, 110, 18, 0.12);
  --red: #d3263f;
  --red-dim: rgba(211, 38, 63, 0.1);
  --purple: #5b4fcf;
  --purple-dim: rgba(91, 79, 207, 0.12);
  --brand-from: #0a6cff;
  --brand-to: #12c45a;
  --text-1: #101614;
  --text-2: #4c6158;
  --text-3: #7d948a;
  --text: var(--text-1);
  --muted: var(--text-2);
  --sidebar: var(--surface);
  --panel: var(--surface);
  --panel-2: var(--surface-2);
  --panel-3: var(--surface-3);
  --line: var(--border);
  --soft: var(--text-3);
  --grid-dot: rgba(16, 22, 20, 0.08);
  --shadow: rgba(8, 24, 18, 0.12);
}

[data-theme="luxuz-dark"] {
  --bg: #07090c;
  --sidebar: #0d1116;
  --panel: #11171e;
  --panel-2: #0c1117;
  --panel-3: #1a2430;
  --surface: #11171e;
  --surface-2: #18212b;
  --surface-3: #223040;
  --border: rgba(140, 176, 204, 0.14);
  --border-2: rgba(20, 211, 106, 0.34);
  --accent: #4da3ff;
  --accent-dim: rgba(77, 163, 255, 0.16);
  --accent-glow: rgba(77, 163, 255, 0.34);
  --green: #1ed67a;
  --green-dim: rgba(30, 214, 122, 0.14);
  --amber: #f5b942;
  --amber-dim: rgba(245, 185, 66, 0.14);
  --red: #ff5d7c;
  --red-dim: rgba(255, 93, 124, 0.14);
  --purple: #a594ff;
  --purple-dim: rgba(165, 148, 255, 0.14);
  --brand-from: #1578f0;
  --brand-to: #14d36a;
  --text: #e7f0f6;
  --text-1: #e7f0f6;
  --text-2: #93a8ba;
  --text-3: #62788a;
  --muted: var(--text-2);
  --soft: var(--text-3);
  --line: rgba(147, 168, 186, 0.16);
  --grid-dot: rgba(147, 168, 186, 0.12);
  --shadow: rgba(0, 0, 0, 0.5);
}

[data-scheme="light"] {
  color-scheme: light;
}

[data-theme^="luxuz"] .brand-mark,
[data-theme^="luxuz"] .logo-icon {
  background: linear-gradient(128deg, var(--brand-from) 0 56%, var(--brand-to) 100%);
  color: #fff;
}

[data-theme^="luxuz"] .nav-indicator::before,
[data-theme^="luxuz"] .metric-card::before {
  background: linear-gradient(90deg, var(--brand-from), var(--brand-to));
}

[data-theme^="luxuz"] .btn-primary {
  color: #fff;
  background: var(--brand-from);
  box-shadow: inset 3px 0 0 var(--brand-to);
}

html,
body {
  height: 100%;
}

body {
  overflow: hidden;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text-1);
}

.sidebar {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 100;
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 0;
  border-right: 1px solid var(--border);
  background: var(--surface);
}

.sidebar-logo {
  padding: 18px 18px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--border);
}

/* --- Barra lateral colapsada ---------------------------------------------
   Deja solo los iconos y libera ~190px de ancho para el contenido. El nombre
   de cada seccion vuelve como tooltip propio al pasar el mouse.
   Solo aplica en escritorio: bajo 900px la barra ya es un cajon deslizable
   y colapsarla lo dejaria inservible. */
@media (min-width: 901px) {
.sidebar,
.main-wrap {
  transition: width 160ms ease, min-width 160ms ease, margin-left 160ms ease;
}

.sidebar.collapsed {
  width: var(--sidebar-w-collapsed);
  min-width: var(--sidebar-w-collapsed);
}

.sidebar.collapsed ~ .main-wrap {
  margin-left: var(--sidebar-w-collapsed);
}

.sidebar.collapsed .logo-text,
.sidebar.collapsed .logo-sub,
.sidebar.collapsed .profile-switcher,
.sidebar.collapsed .nav-section-label,
.sidebar.collapsed .nav-item > span,
.sidebar.collapsed .user-name,
.sidebar.collapsed .user-role {
  display: none;
}

.sidebar.collapsed .sidebar-logo,
.sidebar.collapsed .user-card {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
  gap: 0;
}

.sidebar.collapsed .sidebar-collapse {
  justify-content: center;
  width: calc(100% - 12px);
  margin: 8px 6px 0;
  padding: 8px 0;
}

.sidebar.collapsed .sidebar-collapse span {
  display: none;
}

.sidebar.collapsed .sidebar-collapse svg {
  transform: rotate(180deg);
}

/* El scroll vertical del nav recorta el tooltip, que se dibuja fuera de la
   barra. Colapsado caben los 8 iconos sin scroll, asi que se libera el
   overflow; en ventanas muy bajas se devuelve el scroll y queda el title
   nativo como respaldo. */
.sidebar.collapsed .sidebar-nav {
  padding: 10px 6px;
  overflow: visible;
}

@media (max-height: 560px) {
  .sidebar.collapsed .sidebar-nav {
    overflow-y: auto;
  }
}

.sidebar.collapsed .nav-item {
  justify-content: center;
  padding: 10px 0;
}

.sidebar.collapsed .ico {
  width: 19px;
  height: 19px;
  opacity: 0.9;
}

/* Tooltip: el title nativo tarda ~1s y aqui la etiqueta es lo unico que
   identifica al icono, asi que se dibuja a mano. */
.sidebar.collapsed .nav-item::after {
  content: attr(data-nav-label);
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  padding: 6px 10px;
  border: 1px solid var(--border-2);
  border-radius: 6px;
  background: var(--surface-2, var(--surface));
  color: var(--text-1);
  font-size: calc(12.5px * var(--fs));
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  z-index: 120;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
  transition: opacity 120ms ease;
}

.sidebar.collapsed .nav-item:hover::after,
.sidebar.collapsed .nav-item:focus-visible::after {
  opacity: 1;
}

.sidebar.collapsed .nav-item.active::before {
  left: -6px;
}
}

.logo-icon {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--accent);
  box-shadow: 0 0 16px var(--accent-glow);
  flex-shrink: 0;
}

.logo-icon svg {
  width: 20px;
  height: 20px;
}

.logo-text {
  font-weight: 700;
  font-size: calc(15px * var(--fs));
  letter-spacing: 0.3px;
}

.logo-sub {
  font-size: calc(10px * var(--fs));
  color: var(--text-3);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  font-weight: 500;
}

/* Control de contraer/expandir, dentro de la barra. En movil sobra: alli el
   cajon se abre con el hamburguesa y se cierra tocando el fondo. */
.sidebar-collapse {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 7px;
  width: calc(100% - 16px);
  margin: 8px 8px 0;
  padding: 6px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  font-weight: 600;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  cursor: pointer;
}

.sidebar-collapse:hover {
  background: var(--accent-dim);
  color: var(--text-1);
}

.sidebar-collapse svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  transition: transform 160ms ease;
}

@media (max-width: 900px) {
  .sidebar-collapse {
    display: none;
  }
}

.profile-switcher {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}

.profile-switcher-label {
  margin-bottom: 6px;
  font-size: calc(10px * var(--fs));
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 1.2px;
  font-weight: 600;
}

.profile-tabs {
  display: flex;
  gap: 4px;
}

.profile-tab {
  flex: 1;
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: 5px;
  text-align: center;
  font-size: calc(11px * var(--fs));
  font-weight: 600;
  color: var(--text-3);
}

.profile-tab.active {
  background: var(--accent-dim);
  color: var(--accent);
  border-color: var(--border-2);
}

.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 10px 8px;
}

.nav-section-label {
  padding: 8px 10px 3px;
  color: var(--text-3);
  font-size: calc(10px * var(--fs));
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1.3px;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin-bottom: 1px;
  padding: 9px 12px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-2);
  font-size: calc(13.5px * var(--fs));
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  position: relative;
}

.nav-item:hover {
  background: var(--accent-dim);
  color: var(--text-1);
}

.nav-item.active {
  background: var(--accent-dim);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--border-2);
}

.nav-item.active::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 50%;
  width: 3px;
  height: 60%;
  transform: translateY(-50%);
  border-radius: 0 3px 3px 0;
  background: var(--accent);
}

.ico {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  opacity: 0.75;
}

.sidebar-footer {
  padding: 10px 8px;
  border-top: 1px solid var(--border);
}

.user-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 6px;
}

.user-card:hover {
  background: var(--surface-2);
}

.user-avatar {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--purple));
  color: #fff;
  font-weight: 700;
  font-size: calc(12px * var(--fs));
  flex-shrink: 0;
}

.user-name {
  font-size: calc(13px * var(--fs));
  font-weight: 600;
}

.user-role {
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
}

.main-wrap {
  margin-left: var(--sidebar-w);
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.topbar {
  position: relative;
  z-index: 20;
  height: var(--topbar-h);
  margin: 0;
  padding: 0 22px;
  display: flex;
  align-items: center;
  gap: 14px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  flex-shrink: 0;
}

.topbar-title-wrap {
  flex: 1;
  min-width: 0;
}

.topbar-title {
  font-size: calc(16px * var(--fs));
  font-weight: 700;
}

.topbar-subtitle {
  margin-top: 1px;
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
}

/* Control del tamano de la letra. Vive en la barra superior porque manda sobre
   toda la aplicacion, no sobre la pestana que se este viendo. Sus propias
   medidas no llevan var(--fs): si el control creciera con lo que controla,
   agrandar la letra lo empujaria fuera de la barra. */
.ui-scale {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  flex-shrink: 0;
}

.ui-scale button {
  height: 27px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  cursor: pointer;
}

.ui-scale button:hover:not(:disabled) {
  background: var(--accent-dim);
  color: var(--accent);
}

.ui-scale button:disabled {
  cursor: default;
  opacity: 0.35;
}

.ui-scale-btn {
  width: 31px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
}

/* El signo va mas chico que la A: junto a ella se lee como "menos letra" o
   "mas letra" sin necesidad de una leyenda. */
.ui-scale-btn span {
  font-size: 10px;
}

.ui-scale-value {
  min-width: 44px;
  padding: 0 4px;
  color: var(--text-3);
  font-family: var(--mono);
  font-size: 11px;
}

.ui-scale-value.is-changed {
  color: var(--accent);
}

.search-box {
  width: 210px;
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 12px;
  background: var(--surface-2);
  color: var(--text-3);
}

.search-box input {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-1);
  font-family: var(--font);
  font-size: calc(13px * var(--fs));
}

.icon-btn {
  width: 35px;
  height: 35px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--text-2);
  cursor: pointer;
}

.icon-btn:hover {
  border-color: var(--border-2);
  background: var(--accent-dim);
  color: var(--accent);
}

/* Selector de tema. El boton cabe donde antes estaba el interruptor
   claro/oscuro; el menu se abre hacia abajo con las variantes. */
.theme-switch {
  position: relative;
  flex-shrink: 0;
}

.theme-switch-btn {
  height: 35px;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 8px 0 7px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--text-1);
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.theme-switch-btn:hover,
.theme-switch-btn[aria-expanded="true"] {
  border-color: var(--border-2);
  background: var(--accent-dim);
}

.theme-switch-name {
  max-width: 108px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.theme-chevron {
  color: var(--text-3);
  flex-shrink: 0;
}

.theme-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30;
  min-width: 196px;
  display: grid;
  gap: 2px;
  padding: 6px;
  border: 1px solid var(--border-2);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: 0 16px 40px var(--shadow);
}

.theme-menu[hidden] {
  display: none;
}

.theme-option {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--text-1);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}

.theme-option:hover {
  background: var(--surface-2);
}

.theme-option[aria-selected="true"] {
  background: var(--accent-dim);
  color: var(--accent);
}

.theme-option[aria-selected="true"]::after {
  content: "";
  width: 6px;
  height: 10px;
  margin-left: auto;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.theme-swatch {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.16);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}

.theme-swatch[data-swatch="dark"] {
  background: linear-gradient(145deg, #3b82f6 0 38%, #08111e 39%);
}

.theme-swatch[data-swatch="claude"] {
  background: linear-gradient(145deg, #d97757 0 38%, #faf9f5 39%);
}

.theme-swatch[data-swatch="luxuz"] {
  background: linear-gradient(135deg, #0a6cff 0 48%, #12c45a 52%);
  border-color: transparent;
}

.theme-swatch[data-swatch="luxuz-dark"] {
  background:
    radial-gradient(circle at 50% 50%, #0c1218 0 42%, transparent 43%),
    linear-gradient(135deg, #1a7cff, #14d36a);
  border-color: transparent;
}

/* Solo movil: en escritorio la barra se contrae con su boton interno. */
.hamburger {
  display: none;
}

.content {
  /* En una variable porque las barras pegajosas la necesitan para taparse el
     hueco del padding al hacer scroll. */
  --content-pad: 22px;
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  padding: var(--content-pad);
}

/* Cambio de pestana. El panel viejo se va de golpe y el nuevo entra en 240 ms:
   encadenar salida y entrada duplica la espera y se siente lento, y el ojo no
   echa de menos la salida. El marco (barra lateral, barra superior, area de
   contenido) no se redibuja nunca. */
/* backwards y no both: con both el elemento se queda con el transform del
   ultimo fotograma aplicado, y un transform (aunque sea la matriz identidad)
   convierte al elemento en el marco de referencia de sus hijos position:fixed.
   Los modales de Cobro y Tickets viven aqui dentro y se anclaban a la pantalla
   en vez de a la ventana: aparecian corridos y cortados por la derecha. */
.screen.is-entering {
  animation: paneIn var(--dur) var(--ease) backwards;
}

@keyframes paneIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Bloques escalonados. Cuatro como maximo: del quinto en adelante ya no se lee
   como ritmo, se lee como lentitud. */
@keyframes riseIn {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.screen.is-entering [data-stagger] > *:nth-child(1) {
  animation: riseIn 380ms var(--ease) backwards 30ms;
}

.screen.is-entering [data-stagger] > *:nth-child(2) {
  animation: riseIn 380ms var(--ease) backwards 75ms;
}

.screen.is-entering [data-stagger] > *:nth-child(3) {
  animation: riseIn 380ms var(--ease) backwards 120ms;
}

.screen.is-entering [data-stagger] > *:nth-child(4) {
  animation: riseIn 380ms var(--ease) backwards 165ms;
}

/* El titulo de la barra superior entra un pelo despues que el contenido, para
   que se lea como consecuencia del cambio y no como un tercer elemento suelto. */
.topbar-title.is-entering,
.topbar-subtitle.is-entering {
  animation: paneIn 260ms var(--ease) both 60ms;
}

.panel,
.metric-card {
  background: var(--surface);
  border-color: var(--border);
  border-radius: 10px;
}

.metric-card {
  position: relative;
  overflow: hidden;
}

.metric-card::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: var(--accent);
}

.metric-card strong {
  color: var(--accent);
  font-family: var(--mono);
  font-size: calc(26px * var(--fs));
}

.kpi-grid {
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}

.panel-head {
  border-bottom: 1px solid var(--border);
  padding-bottom: 12px;
}

.table-wrap table {
  border-collapse: collapse;
}

th {
  background: var(--surface-2);
  color: var(--text-3);
  font-family: var(--mono);
  letter-spacing: 0;
}

td {
  color: var(--text-2);
}

.btn,
.input,
.select {
  border-radius: 6px;
}

.btn-primary {
  background: var(--accent);
}

.sidebar-overlay {
  display: none;
}

@media (max-width: 900px) {
  .sidebar {
    transform: translateX(-100%);
  }

  .sidebar.open {
    transform: translateX(0);
  }

  .sidebar-overlay.show {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgba(0, 0, 0, 0.45);
  }

  .main-wrap {
    margin-left: 0;
  }

  .hamburger {
    display: flex;
  }

  .search-box {
    display: none;
  }
}

/* --- Editor de esquema de red ------------------------------------------- */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.net-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.net-panel:fullscreen {
  box-sizing: border-box;
  width: 100vw;
  height: 100vh;
  max-width: none;
  margin: 0;
  padding: 10px;
  border-radius: 0;
  overflow: hidden;
  background: var(--panel);
}

.net-panel:fullscreen .panel-head {
  display: none;
}

.net-panel:fullscreen .net-stage {
  flex: 1;
  min-height: 0;
}

.net-panel:fullscreen .net-canvas {
  height: 100%;
  min-height: 0;
}

.net-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.net-toolbar-group {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}

.net-toolbar-view {
  margin-left: auto;
}

.net-relation-select {
  width: auto;
  min-width: 150px;
}

.net-density-select {
  width: auto;
  min-width: 116px;
}

.net-font-select {
  width: auto;
  min-width: 124px;
}

.net-zoom-label {
  min-width: 44px;
  text-align: center;
  font-size: calc(12px * var(--fs));
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.net-toolbar-hint {
  width: 100%;
  font-size: calc(12px * var(--fs));
  color: var(--soft);
  text-align: right;
}

.net-panel:fullscreen .net-toolbar {
  flex: 0 0 auto;
  flex-wrap: nowrap;
  overflow-x: auto;
  padding-bottom: 2px;
}

.net-panel:fullscreen .net-toolbar-hint {
  display: none;
}

.net-panel:fullscreen .net-toolbar-group {
  flex: 0 0 auto;
}

.net-stage {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background:
    radial-gradient(var(--grid-dot) 1px, transparent 1px) 0 0 / 26px 26px,
    var(--panel-2);
}

.net-navigator {
  position: absolute;
  z-index: 4;
  top: 12px;
  bottom: 12px;
  left: 12px;
  display: flex;
  flex-direction: column;
  width: min(330px, calc(100% - 24px));
  overflow: hidden;
  border: 1px solid var(--border-2, var(--line));
  border-radius: var(--radius);
  background: var(--panel);
  background: color-mix(in srgb, var(--panel) 96%, transparent);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(10px);
}

.net-navigator[hidden] {
  display: none;
}

.net-navigator-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 13px 14px 10px;
}

.net-navigator-head > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.net-navigator-head strong {
  color: var(--text);
  font-size: calc(14px * var(--fs));
}

.net-navigator-head span {
  color: var(--muted);
  font-size: calc(11px * var(--fs));
}

.net-navigator-search {
  padding: 0 12px 9px;
}

.net-navigator-search .input {
  height: 36px;
  font-size: calc(12px * var(--fs));
}

.net-navigator-filters {
  display: flex;
  gap: 5px;
  padding: 0 12px 10px;
  overflow-x: auto;
}

.net-navigator-filters button {
  flex: 0 0 auto;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: calc(10px * var(--fs));
  cursor: pointer;
}

.net-navigator-filters button:hover,
.net-navigator-filters button.active {
  border-color: var(--accent);
  background: var(--accent-dim, rgba(59, 130, 246, 0.12));
  color: var(--text);
}

.net-navigator-current {
  margin: 0 12px 9px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel-2);
}

.net-navigator-current[hidden] {
  display: none;
}

.net-navigator-selected {
  display: grid;
  grid-template-columns: 7px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
}

.net-navigator-selected > i {
  width: 7px;
  height: 34px;
  border-radius: 4px;
}

.net-navigator-selected > span {
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.net-navigator-selected strong,
.net-navigator-selected small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.net-navigator-selected strong {
  color: var(--text);
  font-size: calc(12px * var(--fs));
}

.net-navigator-selected small,
.net-navigator-no-links {
  color: var(--muted);
  font-size: calc(10px * var(--fs));
}

.net-navigator-section-title {
  display: block;
  margin: 10px 0 5px;
  color: var(--soft);
  font-size: calc(9px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.net-navigator-neighbors {
  display: flex;
  max-height: 112px;
  flex-direction: column;
  gap: 3px;
  overflow-y: auto;
}

.net-navigator-neighbors button {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr);
  gap: 0 5px;
  padding: 4px 5px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  text-align: left;
  cursor: pointer;
}

.net-navigator-neighbors button:hover {
  background: var(--panel-3);
}

.net-navigator-neighbors b {
  overflow: hidden;
  color: var(--text);
  font-size: calc(10px * var(--fs));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.net-navigator-neighbors small {
  grid-column: 2;
  color: var(--muted);
  font-size: calc(9px * var(--fs));
}

.net-navigator-list {
  min-height: 0;
  padding: 0 8px 10px;
  overflow-y: auto;
}

.net-navigator-item {
  display: grid;
  width: 100%;
  grid-template-columns: 5px minmax(0, 1fr) auto;
  align-items: center;
  gap: 9px;
  padding: 7px 8px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.net-navigator-item:hover {
  background: var(--panel-2);
}

.net-navigator-item.selected {
  border-color: var(--accent);
  background: var(--accent-dim, rgba(59, 130, 246, 0.12));
}

.net-navigator-item > i {
  width: 5px;
  height: 31px;
  border-radius: 3px;
  background: var(--nav-color);
}

.net-navigator-item > span {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 1px;
}

.net-navigator-item strong,
.net-navigator-item small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.net-navigator-item strong {
  color: var(--text);
  font-size: calc(11px * var(--fs));
}

.net-navigator-item small {
  color: var(--muted);
  font-size: calc(9px * var(--fs));
}

.net-navigator-item > b {
  min-width: 20px;
  padding: 2px 5px;
  border-radius: 999px;
  background: var(--panel-3);
  color: var(--muted);
  font-size: calc(9px * var(--fs));
  text-align: center;
}

.net-navigator-empty {
  margin: 20px 10px;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
  text-align: center;
}

.net-canvas {
  display: block;
  width: 100%;
  height: clamp(520px, calc(100vh - 220px), 900px);
  cursor: grab;
  touch-action: none;
  user-select: none;
  /* Tamano de letra del mapa. Los tres niveles los fija el selector de la
     barra; el recorte de texto va en JS con la misma tabla. */
  --net-name: 13px;
  --net-meta: 11px;
  --net-link: 11px;
}

.net-canvas.net-font-grande {
  --net-name: 16.5px;
  --net-meta: 12.5px;
  --net-link: 13px;
}

.net-canvas.net-font-enorme {
  --net-name: 20px;
  --net-meta: 14px;
  --net-link: 15px;
}

/* Tres escalones mas. La caja crece con la letra, asi que el nombre se sigue
   leyendo entero en vez de recortarse. */
.net-canvas.net-font-gigante {
  --net-name: 23px;
  --net-meta: 16px;
  --net-link: 17px;
}

.net-canvas.net-font-colosal {
  --net-name: 26px;
  --net-meta: 18px;
  --net-link: 19px;
}

.net-canvas.net-font-maxima {
  --net-name: 29px;
  --net-meta: 20px;
  --net-link: 21px;
}

.net-canvas:active {
  cursor: grabbing;
}

.net-canvas.connect-mode {
  cursor: crosshair;
}

.net-node {
  cursor: pointer;
}

.net-node-box {
  fill: var(--panel-3);
  stroke: var(--line);
  stroke-width: 1;
}

.net-node-tint {
  pointer-events: none;
  opacity: 0.12;
}

.net-node:hover .net-node-box {
  stroke: var(--muted);
}

.net-node.selected .net-node-box {
  stroke: var(--accent);
  stroke-width: 1.6;
}

.net-node.connecting .net-node-box {
  stroke: var(--green);
  stroke-width: 1.8;
  stroke-dasharray: 5 3;
}

.net-node-name {
  fill: var(--text);
  font-size: var(--net-name, 13px);
  font-weight: 600;
}

.net-node-meta {
  fill: var(--muted);
  font-size: var(--net-meta, 11px);
}

.net-link-line {
  fill: none;
  stroke: var(--muted);
  stroke-width: 1.4;
  stroke-linejoin: round;
  stroke-linecap: round;
  opacity: 0.85;
}

.net-link.long .net-link-line {
  stroke-dasharray: 7 6;
  opacity: 0.4;
}

.net-link:hover .net-link-line,
.net-link.selected .net-link-line {
  stroke: var(--accent);
  stroke-width: 2;
  opacity: 1;
  stroke-dasharray: none;
}

.net-link-hit {
  fill: none;
  stroke: transparent;
  stroke-width: 14;
  cursor: pointer;
}

.net-link-label {
  fill: var(--muted);
  font-size: var(--net-link, 11px);
  text-anchor: middle;
  paint-order: stroke;
  stroke: var(--panel-2);
  stroke-width: 4;
  stroke-linejoin: round;
  pointer-events: none;
}

.net-link:hover .net-link-label,
.net-link.selected .net-link-label {
  fill: var(--text);
}

.net-empty {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  color: var(--muted);
  font-size: calc(13px * var(--fs));
  pointer-events: none;
}

.net-empty[hidden] {
  display: none;
}

.net-empty strong {
  color: var(--text);
  font-size: calc(15px * var(--fs));
}

.net-navigator:not([hidden]) ~ .net-legend {
  left: 354px;
}

.net-form {
  position: absolute;
  z-index: 5;
  top: 12px;
  right: 12px;
  bottom: 12px;
  width: min(320px, calc(100% - 24px));
  padding: 14px;
  overflow-y: auto;
  border: 1px solid var(--border-2, var(--line));
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
}

.net-form-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.net-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.net-form-route {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 12px;
  font-size: calc(12px * var(--fs));
  color: var(--muted);
}

.net-form-route b {
  color: var(--text);
}

.net-textarea {
  resize: vertical;
  min-height: 64px;
  font-family: inherit;
}

.net-template-summary {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
  line-height: 1.45;
}

.net-template-summary strong {
  color: var(--text);
  font-size: calc(13px * var(--fs));
}

.net-template-summary small {
  color: var(--accent);
  font-weight: 600;
}

.net-template-warning {
  margin: 0;
  padding: 9px 10px;
  border: 1px solid rgba(245, 158, 11, 0.35);
  border-radius: 8px;
  background: rgba(245, 158, 11, 0.08);
  color: var(--amber);
  font-size: calc(12px * var(--fs));
  line-height: 1.4;
}

.net-zoomed-out .net-link-label {
  display: none;
}

.net-legend {
  position: absolute;
  z-index: 3;
  left: 12px;
  bottom: 12px;
  display: grid;
  gap: 10px;
  max-width: min(430px, calc(100% - 24px));
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: color-mix(in srgb, var(--panel) 92%, transparent);
  box-shadow: 0 10px 28px var(--shadow);
  backdrop-filter: blur(10px);
  pointer-events: none;
}

.net-legend-body {
  display: grid;
  grid-template-columns: minmax(180px, 230px) minmax(130px, 170px);
  gap: 14px;
}

/* Plegada queda solo el boton, que ocupa una esquina en vez de un tercio
   del lienzo. */
.net-legend.collapsed {
  padding: 0;
  border-radius: 999px;
}

.net-legend.collapsed .net-legend-body {
  display: none;
}

.net-legend-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: calc(12px * var(--fs));
  font-weight: 600;
  cursor: pointer;
  pointer-events: auto;
}

.net-legend-toggle:hover {
  color: var(--text-1);
}

.net-legend-toggle > svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

.net-legend-caret {
  display: grid;
  place-items: center;
  margin-left: auto;
}

.net-legend-caret svg {
  width: 14px;
  height: 14px;
  transition: transform 150ms ease;
}

.net-legend.collapsed .net-legend-caret svg {
  transform: rotate(180deg);
}

.net-legend-block {
  display: grid;
  gap: 7px;
  min-width: 0;
}

.net-legend-block strong {
  color: var(--text-1);
  font-size: calc(11px * var(--fs));
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.net-legend-item {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.net-legend-item i {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--swatch) 18%, transparent);
}

.net-legend-item span {
  min-width: 0;
  display: grid;
}

.net-legend-item b {
  color: var(--text-1);
  font-size: calc(12px * var(--fs));
  font-weight: 600;
}

.net-legend-item small {
  overflow: hidden;
  color: var(--muted);
  font-size: calc(10px * var(--fs));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.net-legend-item em {
  color: var(--text-2);
  font-style: normal;
  font-size: calc(11px * var(--fs));
  font-variant-numeric: tabular-nums;
}

.net-legend-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
}

.net-legend-status i {
  width: 9px;
  height: 9px;
  border-radius: 99px;
}

.net-legend-note {
  margin-top: 4px;
  color: var(--muted);
  font-size: calc(11px * var(--fs));
  line-height: 1.35;
}

@media (max-width: 900px) {
  .net-legend-body {
    grid-template-columns: 1fr;
    max-height: 42vh;
    overflow: auto;
  }

  .net-legend {
    pointer-events: auto;
  }
}

/* --- Navegacion por secciones -------------------------------------------
   Con 300+ nodos el mapa completo no se puede leer. Al elegir una seccion se
   encuadra su torre y se apaga el resto, que sigue visible como contexto. */
.net-node.dimmed,
.net-link.dimmed {
  opacity: 0.13;
  pointer-events: none;
  transition: opacity 180ms ease;
}

/* Sobre fondo blanco un 13% desaparece del todo y se pierde la referencia de
   donde esta la seccion dentro del mapa. */
[data-scheme="light"] .net-node.dimmed,
[data-scheme="light"] .net-link.dimmed {
  opacity: 0.28;
}

.net-link.dimmed .net-link-label {
  display: none;
}

.net-navigator-modes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 3px;
  border-radius: 8px;
  background: var(--panel-2);
}

.net-navigator-modes button {
  padding: 6px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: calc(12px * var(--fs));
  font-weight: 600;
  cursor: pointer;
}

.net-navigator-modes button.active {
  background: var(--accent);
  color: #fff;
}

.net-navigator-filters[hidden] {
  display: none;
}

.net-section-item i {
  border-radius: 5px;
}

.net-section-bar {
  position: absolute;
  z-index: 4;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - 24px);
  padding: 7px 8px 7px 14px;
  border: 1px solid var(--border-2, var(--line));
  border-radius: 999px;
  background: color-mix(in srgb, var(--panel) 94%, transparent);
  box-shadow: 0 8px 24px var(--shadow);
  backdrop-filter: blur(10px);
  font-size: calc(12.5px * var(--fs));
}

.net-section-bar[hidden] {
  display: none;
}

.net-section-bar i {
  width: 9px;
  height: 9px;
  border-radius: 99px;
  flex-shrink: 0;
}

.net-section-bar span {
  overflow: hidden;
  color: var(--text-1);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.net-section-bar em {
  color: var(--text-2);
  font-style: normal;
  white-space: nowrap;
}

.net-section-bar button {
  padding: 5px 12px;
  border: 0;
  border-radius: 999px;
  background: var(--accent-dim);
  color: var(--accent);
  font: inherit;
  font-size: calc(12px * var(--fs));
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.net-section-bar button:hover {
  background: var(--accent);
  color: #fff;
}

.net-section-bar button.ghost {
  background: transparent;
  color: var(--text-2);
}

.net-section-bar button.ghost:hover {
  background: var(--panel-2);
  color: var(--text-1);
}

.status-pill.busy {
  color: var(--amber);
}

/* --- Rediseño de Clientes ----------------------------------------------- */

.eyebrow,
.section-kicker {
  display: block;
  color: var(--accent);
  font-family: var(--mono);
  font-size: calc(10px * var(--fs));
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 4px var(--green-dim);
}

.clients-kpi .metric-card {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 88px;
  padding: 15px 16px;
}

.clients-kpi .metric-card::before {
  height: 0;
}

.kpi-icon {
  width: 38px;
  height: 38px;
  position: relative;
  flex: 0 0 auto;
  border-radius: 12px;
  background: var(--accent-dim);
  color: var(--accent);
}

.kpi-icon::before,
.kpi-icon::after {
  content: "";
  position: absolute;
  border: 2px solid currentColor;
}

.kpi-icon::before {
  width: 11px;
  height: 11px;
  left: 12px;
  top: 8px;
  border-radius: 50%;
}

.kpi-icon::after {
  width: 16px;
  height: 8px;
  left: 9px;
  bottom: 7px;
  border-bottom: 0;
  border-radius: 10px 10px 0 0;
}

.kpi-icon-suspendido {
  color: var(--amber);
  background: var(--amber-dim);
}

.kpi-icon-suspendido::after {
  width: 12px;
  height: 12px;
  left: 11px;
  bottom: 11px;
  border-width: 0 2px;
  border-radius: 0;
}

.kpi-icon-moroso {
  color: var(--red);
  background: var(--red-dim);
}

.kpi-icon-moroso::before {
  width: 16px;
  height: 16px;
  left: 9px;
  top: 9px;
  border-radius: 50%;
}

.kpi-icon-moroso::after {
  width: 2px;
  height: 7px;
  left: 17px;
  top: 14px;
  border-width: 0 2px 0 0;
}

.clients-kpi .kpi-copy {
  display: block;
  min-width: 0;
}

.clients-kpi .kpi-copy > span,
.clients-kpi .kpi-copy > small {
  display: block;
}

.clients-kpi .kpi-copy > span {
  font-size: calc(12px * var(--fs));
}

.clients-kpi .kpi-copy > strong {
  margin: 4px 0 2px;
  font-size: calc(24px * var(--fs));
}

.kpi-money {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.kpi-money b {
  font-size: calc(18px * var(--fs));
  font-weight: 700;
}

.clients-kpi .kpi-copy > small {
  font-size: calc(11px * var(--fs));
}

.clients-kpi .kpi-filter.active {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent), 0 8px 22px rgba(59, 130, 246, 0.08);
}

.clients-workspace {
  min-width: 0;
  grid-template-columns: minmax(360px, 0.82fr) minmax(540px, 1.25fr);
  align-items: stretch;
}

.clients-list-panel,
.clients-ficha-panel {
  width: 100%;
  min-width: 0;
  min-height: calc(100vh - 254px);
}

.clients-list-panel {
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.clients-list-head {
  align-items: center;
}

.clients-list-head h2 {
  margin-top: 3px;
  font-size: calc(19px * var(--fs));
}

.list-sort {
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(10px * var(--fs));
  white-space: nowrap;
}

.clients-toolbar {
  grid-template-columns: minmax(0, 1fr) 128px;
  margin-bottom: 10px;
}

.client-search-control {
  display: block;
  position: relative;
}

.client-search-control svg {
  width: 15px;
  height: 15px;
  position: absolute;
  left: 12px;
  top: 50%;
  z-index: 1;
  transform: translateY(-50%);
  fill: none;
  stroke: var(--text-3);
  stroke-linecap: round;
  stroke-width: 1.8;
  pointer-events: none;
}

.client-search-control .input {
  padding-left: 35px;
}

.clients-filter-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.client-segmented {
  display: inline-flex;
  width: min(100%, 270px);
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-2);
}

.client-segmented button {
  min-width: 0;
  flex: 1 1 0;
  min-height: 31px;
  border: 0;
  border-right: 1px solid var(--border);
  overflow: hidden;
  padding: 5px 6px;
  color: var(--text-2);
  background: transparent;
  font-size: calc(11px * var(--fs));
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.client-segmented button:last-child {
  border-right: 0;
}

.client-segmented button:hover,
.client-segmented button.active {
  color: var(--text-1);
  background: var(--accent-dim);
}

.clients-actions {
  margin: 0;
  flex: 0 1 auto;
  justify-content: flex-end;
}

.btn-secondary {
  border-color: var(--border-2);
  background: var(--surface-2);
}

.clients-actions .btn {
  min-height: 34px;
  padding: 7px 10px;
  font-size: calc(11px * var(--fs));
}

.clients-actions .btn-primary span {
  font-size: calc(16px * var(--fs));
  line-height: 0;
  vertical-align: -1px;
}

.client-table-shell {
  display: flex;
  min-width: 0;
  min-height: 0;
  flex: 1;
  flex-direction: column;
}

.client-table-header,
.client-table-row {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 0.9fr) minmax(0, 0.75fr) minmax(0, 0.95fr) minmax(0, 76px);
  gap: 10px;
  align-items: center;
}

.client-table-header {
  padding: 8px 9px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(9px * var(--fs));
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.client-list {
  display: block;
  min-height: 0;
  max-height: calc(100vh - 410px);
  overflow-x: hidden;
  overflow-y: auto;
  padding-right: 0;
  scrollbar-gutter: stable;
}

.content {
  overflow-x: hidden;
}

/* Scrollbars de todo el panel. Global a proposito: enumerar contenedores
   deja siempre alguno afuera con la barra gruesa del sistema. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--text-3) transparent;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track,
::-webkit-scrollbar-corner {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  border-radius: 999px;
  background: var(--text-3);
  background-clip: padding-box;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
  background-clip: padding-box;
}

.client-table-row {
  width: 100%;
  min-width: 0;
  min-height: 61px;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding: 9px;
  color: inherit;
  background: transparent;
  text-align: left;
  white-space: normal;
  cursor: pointer;
}

.client-table-row:hover,
.client-table-row.selected {
  border-color: var(--border);
  background: var(--accent-dim);
  box-shadow: inset 2px 0 0 var(--accent);
}

.client-person {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 9px;
}

.client-person-copy,
.client-table-cell {
  display: block;
  min-width: 0;
  overflow: hidden;
}

.client-person-copy strong,
.client-person-copy small,
.client-table-cell strong,
.client-table-cell small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-person-copy strong {
  color: var(--text-1);
  font-size: calc(12px * var(--fs));
}

.client-person-copy small,
.client-table-cell small {
  margin-top: 4px;
  color: var(--text-2);
  font-size: calc(10px * var(--fs));
}

.client-table-cell {
  color: var(--text-2);
  font-size: calc(11px * var(--fs));
}

.client-table-header > span,
.client-table-cell,
.client-person-copy {
  min-width: 0;
}

.client-table-cell strong {
  color: var(--text-1);
  font-size: calc(11px * var(--fs));
}

.client-ip-cell code {
  display: block;
  overflow: hidden;
  color: var(--text-1);
  font-family: var(--mono);
  font-size: calc(10px * var(--fs));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-status-cell {
  overflow: visible;
  text-align: left;
}

.client-status-cell .badge {
  justify-content: center;
  min-width: 60px;
  padding: 4px 7px;
  font-size: calc(10px * var(--fs));
}

.client-list-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 9px 0;
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(10px * var(--fs));
}

.client-list-footer strong {
  color: var(--text-2);
}

.ficha-hero {
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  min-width: 0;
  margin-bottom: 14px;
  padding-bottom: 14px;
}

.ficha-identity {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  align-items: center;
  gap: 11px;
}

.ficha-identity > div {
  min-width: 0;
}

.ficha-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  max-width: 100%;
}

.ficha-title-row h2 {
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  font-size: calc(20px * var(--fs));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ficha-hero p {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-detail-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 14px;
}

.client-detail-stats > div {
  min-width: 0;
  padding: 10px 11px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface-2);
}

.client-detail-stats span,
.client-detail-stats strong {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-detail-stats span {
  color: var(--text-3);
  font-size: calc(10px * var(--fs));
}

.client-detail-stats strong {
  margin-top: 5px;
  color: var(--text-1);
  font-size: calc(12px * var(--fs));
}

.client-tabs {
  display: flex;
  gap: 18px;
  margin: 0 -2px 16px;
  border-bottom: 1px solid var(--border);
}

.client-tab {
  position: relative;
  border: 0;
  padding: 0 2px 10px;
  color: var(--text-2);
  background: transparent;
  font-size: calc(12px * var(--fs));
  cursor: pointer;
}

.client-tab::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: transparent;
}

.client-tab:hover,
.client-tab.active {
  color: var(--text-1);
}

.client-tab.active::after {
  background: var(--accent);
}

.client-tab-panel[hidden] {
  display: none;
}

.client-summary-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.client-summary-block,
.client-notes-block {
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface-2);
}

.client-summary-block {
  padding: 13px;
}

.client-summary-block-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 5px;
}

.client-summary-block-head h3 {
  color: var(--text-1);
  font-size: calc(12px * var(--fs));
}

.summary-icon,
.section-index {
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(10px * var(--fs));
}

.client-summary-row {
  display: grid;
  grid-template-columns: minmax(88px, 0.9fr) minmax(0, 1.2fr);
  gap: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--border);
}

.client-summary-row span {
  color: var(--text-2);
  font-size: calc(11px * var(--fs));
}

.client-summary-row strong {
  min-width: 0;
  overflow: hidden;
  color: var(--text-1);
  font-size: calc(11px * var(--fs));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-summary-edit-form {
  display: grid;
  gap: 10px;
}

.client-summary-edit-row {
  align-items: center;
}

.client-summary-edit-control {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  border: 1px solid var(--border-2);
  border-radius: 5px;
  padding: 6px 8px;
  color: var(--text-1);
  background: var(--surface);
  font: inherit;
  font-size: calc(11px * var(--fs));
  outline: 0;
}

.client-summary-edit-control:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(79, 130, 240, 0.16);
}

.client-summary-edit-select {
  appearance: auto;
}

.client-summary-edit-textarea {
  min-height: 54px;
  resize: vertical;
  line-height: 1.4;
}

.client-summary-edit-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.mono {
  font-family: var(--mono);
}

.client-notes-block {
  margin-top: 10px;
  padding: 13px;
}

.client-notes-block p {
  color: var(--text-2);
  font-size: calc(11px * var(--fs));
  line-height: 1.5;
}

.text-action {
  border: 0;
  padding: 0;
  color: var(--accent);
  background: transparent;
  font-size: calc(11px * var(--fs));
  cursor: pointer;
}

.ficha-section-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 2px;
}

.ficha-section-heading h3 {
  margin-top: 4px;
}

.equip-block {
  margin-top: 0;
}

.client-history-empty {
  display: grid;
  justify-items: start;
  gap: 8px;
  padding: 22px 2px;
}

.history-mark {
  display: grid;
  width: 38px;
  height: 38px;
  place-items: center;
  border-radius: 10px;
  color: var(--accent);
  background: var(--accent-dim);
  font-family: var(--mono);
  font-size: calc(12px * var(--fs));
}

.client-history-empty strong {
  color: var(--text-1);
  font-size: calc(14px * var(--fs));
}

.client-history-empty p {
  max-width: 480px;
  font-size: calc(12px * var(--fs));
  line-height: 1.5;
}

@media (max-width: 1350px) and (min-width: 1101px) {
  .client-table-header,
  .client-table-row {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 0.65fr) minmax(0, 0.85fr) minmax(0, 58px);
    gap: 3px;
  }

  .client-table-header,
  .client-table-row {
    padding-left: 6px;
    padding-right: 6px;
  }

  .client-table-header span:nth-child(2),
  .client-table-row > :nth-child(2) {
    display: none;
  }

  .client-status-cell .badge {
    min-width: 0;
    padding-left: 5px;
    padding-right: 5px;
    font-size: calc(9px * var(--fs));
  }
}

@media (max-width: 1100px) {
  .clients-filter-row {
    align-items: stretch;
    flex-direction: column;
  }

  .client-segmented,
  .clients-actions {
    width: 100%;
    max-width: none;
  }

  .clients-actions {
    justify-content: flex-start;
  }
}

@media (max-width: 1100px) {
  .clients-workspace {
    grid-template-columns: 1fr;
  }

  .clients-list-panel,
  .clients-ficha-panel,
  .client-list {
    min-height: 0;
    max-height: none;
  }

  .client-list {
    max-height: 520px;
  }
}

@media (max-width: 760px) {
  .clients-filter-row,
  .ficha-hero {
    align-items: flex-start;
    flex-direction: column;
  }

  .ficha-identity {
    width: 100%;
    max-width: 100%;
    flex: 0 1 auto;
  }

  .ficha-identity > div {
    max-width: 100%;
  }

  .clients-filter-row,
  .clients-actions,
  .client-segmented {
    max-width: 100%;
    overflow: hidden;
  }

  .client-table-header,
  .client-table-row {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.7fr) minmax(0, 58px);
  }

  .client-table-header span:nth-child(3),
  .client-table-header span:nth-child(4),
  .client-table-row > :nth-child(3),
  .client-table-row > :nth-child(4) {
    display: none;
  }

  .client-summary-grid,
  .client-detail-stats {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .net-toolbar-hint {
    display: none;
  }

  .net-form {
    width: calc(100% - 24px);
  }

  .net-navigator {
    width: calc(100% - 24px);
  }

  .net-toolbar-view {
    margin-left: 0;
  }
}

/* --- Clientes: directorio de tabla unica -------------------------------- */

.clients-page:not(.billing-page) .clients-workspace {
  grid-template-columns: minmax(0, 1fr);
}

.clients-page:not(.billing-page) .clients-list-panel {
  min-height: calc(100vh - 250px);
}

.clients-directory-head {
  align-items: center;
}

.clients-directory-head .clients-actions {
  align-items: center;
  margin: 0;
}

.client-directory-toolbar {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  margin-bottom: 12px;
}

.clients-filter-toggle {
  min-width: 92px;
}

.clients-filters-panel {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  margin: 0 0 12px;
  padding: 0 0 12px;
  border-bottom: 1px solid var(--border);
}

.clients-filters-panel[hidden] {
  display: none;
}

.clients-filter-select {
  width: 150px;
  flex: 0 0 150px;
}

.clients-filters-panel .client-segmented {
  /* Cinco pestanas (Todos, Activos, Suspendidos, Morosos, Recientes) necesitan mas ancho. */
  width: min(100%, 420px);
}

.clients-page:not(.billing-page) .client-table-shell {
  overflow-x: auto;
}

/* Estado y Acciones son columnas de ancho fijo, no fracciones del sobrante: la
   insignia y la fila de botones miden lo que miden, y si la columna fuera mas
   ancha que ellos el titulo quedaria flotando lejos de lo que describe. Al ser
   fijas, todo el ancho que sobra se lo reparten Cliente, Zona, Plan, IP y
   Cuota, que si saben que hacer con el.

   No se pueden medir con max-content porque la cabecera y las filas son
   rejillas distintas: cada una calcularia su propio ancho ("Estado" mide menos
   que la insignia) y las columnas dejarian de coincidir. Por eso el ancho se
   escribe como una parte fija (bordes y relleno, que no crecen) mas una parte
   que sigue a var(--fs), que es lo unico que crece cuando se agranda la letra.
   Los numeros salen de medir los botones a 90% y a 145%. */
.clients-page:not(.billing-page) {
  --col-estado: calc(19px + 57px * var(--fs));
  /* Editar + Llegar + los tres puntos. */
  --col-acciones: calc(82px + 59px * var(--fs));
}

.clients-page:not(.billing-page) .client-table-header,
.clients-page:not(.billing-page) .client-table-row {
  grid-template-columns: minmax(145px, 1.8fr) minmax(84px, 1.05fr) minmax(70px, 0.8fr) minmax(98px, 1.05fr) minmax(70px, 0.75fr) var(--col-estado) var(--col-acciones);
  gap: 6px;
}

.clients-page:not(.billing-page) .client-table-header span:nth-child(2),
.clients-page:not(.billing-page) .client-table-row > :nth-child(2) {
  display: block;
}

/* min-content = las columnas flexibles en su suelo y las de contenido en su
   ancho real. Antes era un numero fijo en px, que se quedaba corto o largo en
   cuanto cambiaba el tamano de la letra. */
.clients-page:not(.billing-page) .client-table-header {
  min-width: min-content;
  /* La lista de abajo reserva siempre el hueco de su barra de desplazamiento
     (scrollbar-gutter: stable, y la barra mide --sb). La cabecera no lo
     reserva, asi que se le suma aqui: sin esto las dos rejillas arrancan del
     mismo sitio pero terminan corridas, y las columnas de la derecha, que son
     de ancho fijo, quedan diez pixeles fuera de su titulo. */
  padding: 10px calc(12px + var(--sb)) 10px 12px;
  background: var(--surface-2);
}

.clients-page:not(.billing-page) .client-table-row {
  min-width: min-content;
  min-height: 58px;
  padding: 9px 12px;
}

.clients-page:not(.billing-page) .client-table-row:hover,
.clients-page:not(.billing-page) .client-table-row.selected {
  box-shadow: inset 3px 0 0 var(--accent);
}

.client-fee-cell strong {
  color: var(--text-1);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
}

.client-actions-cell {
  display: flex;
  min-width: 0;
  align-items: center;
  justify-content: flex-start;
  gap: 5px;
}

.client-pagination {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.client-page-button {
  min-width: 28px;
  height: 28px;
  border: 1px solid var(--border-2);
  border-radius: 5px;
  padding: 4px 7px;
  color: var(--text-2);
  background: var(--surface-2);
  font-family: var(--mono);
  font-size: calc(10px * var(--fs));
  cursor: pointer;
}

.client-page-button:hover:not(:disabled),
.client-page-button.active {
  border-color: var(--accent);
  color: var(--text-1);
  background: var(--accent-dim);
}

.client-page-button:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

.client-row-action {
  min-height: 29px;
  border: 1px solid var(--border-2);
  border-radius: 5px;
  padding: 5px 8px;
  color: var(--text-2);
  background: var(--surface-2);
  font-size: calc(10px * var(--fs));
  cursor: pointer;
}

.client-row-action:hover,
.client-row-action:focus-visible {
  border-color: var(--accent);
  color: var(--text-1);
  background: var(--accent-dim);
}

.client-row-action-primary {
  border-color: rgba(79, 130, 240, 0.45);
  color: var(--accent);
}

/* Botones que solo salen cuando la fila tiene ancho de sobra. Por debajo del
   corte vuelven al menu de los tres puntos (ver ANCHO_ACCIONES_AMPLIAS en
   app.js: los dos anchos tienen que coincidir). */
.client-row-action-extra {
  display: none;
}

@media (min-width: 1400px) {
  /* Con los seis botones a la vista la columna necesita mas de el doble. */
  .clients-page:not(.billing-page) {
    --col-acciones: calc(150px + 190px * var(--fs));
  }

  .client-row-action-extra {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
  }

  /* Sin permiso de gestion no queda nada que meter en el menu. */
  .client-mas-solo-compacto {
    display: none;
  }
}

.client-modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 22px;
}

.client-modal[hidden] {
  display: none;
}

.client-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(2, 7, 18, 0.78);
  backdrop-filter: blur(3px);
}

.client-modal-dialog {
  position: relative;
  z-index: 1;
  width: min(840px, calc(100vw - 44px));
  max-height: calc(100vh - 44px);
  min-height: 0;
  overflow: auto;
  padding: 22px;
}

.client-modal-dialog > [data-client-ficha] {
  padding-top: 8px;
}

.client-modal-close {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  width: 30px;
  height: 30px;
  color: var(--text-2);
}

.client-modal-open {
  overflow: hidden;
}

@media (max-width: 1100px) {
  .clients-page:not(.billing-page) .client-table-header,
  .clients-page:not(.billing-page) .client-table-row {
    min-width: 857px;
  }
}

@media (max-width: 760px) {
  .clients-directory-head {
    align-items: flex-start;
    flex-direction: column;
  }

  .clients-directory-head .clients-actions {
    justify-content: flex-start;
    width: 100%;
  }

  .client-directory-toolbar {
    grid-template-columns: 1fr;
  }

  .clients-filter-toggle {
    width: 100%;
  }

  .clients-filters-panel {
    align-items: stretch;
    flex-direction: column;
  }

  .clients-filter-select {
    width: 100%;
    flex-basis: auto;
  }

  .clients-filters-panel .client-segmented {
    width: 100%;
  }

  .client-modal {
    padding: 8px;
  }

  .client-modal-dialog {
    width: calc(100vw - 16px);
    max-height: calc(100vh - 16px);
    padding: 18px 14px;
  }
}

/* --- Cobro: tabla unica y detalle bajo demanda ---------------------------- */

#modal-root {
  position: relative;
  z-index: 100;
}

.billing-page .clients-list-panel {
  min-height: calc(100vh - 240px);
}

.billing-fx-summary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 12px;
}

.billing-fx-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: inherit;
  text-align: left;
  background: var(--panel);
  cursor: pointer;
  min-width: 0;
}

.billing-fx-card:hover,
.billing-fx-card.active {
  border-color: var(--accent);
}

.billing-fx-code {
  flex: 0 0 auto;
  font-size: calc(13px * var(--fs));
  font-weight: 600;
  color: var(--accent);
  font-family: var(--mono, "Segoe UI");
}

.billing-fx-items {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  min-width: 0;
}

.billing-fx-items > span {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-family: var(--mono, "Segoe UI");
  font-size: calc(13px * var(--fs));
  line-height: 1.25;
}

.billing-fx-items i {
  font-style: normal;
  font-family: var(--font);
  font-size: calc(10px * var(--fs));
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.billing-fx-items .is-overdue {
  color: var(--red);
}

@media (max-width: 760px) {
  .billing-fx-summary {
    grid-template-columns: 1fr;
  }
}

.billing-directory-toolbar {
  grid-template-columns: minmax(220px, 1fr) repeat(4, auto);
}

/* Cada filtro toma el ancho de su opcion mas larga para que el texto
   ("Todos los conceptos", "Colones y dolares") no quede cortado. */
.billing-directory-toolbar .clients-filter-select {
  width: auto;
  flex: none;
}

.billing-directory-toolbar .clients-filter-select .select {
  width: 100%;
  min-width: 140px;
}

/* Con cuatro filtros la fila se aprieta antes de llegar al breakpoint movil.
   El corte esta en 1080 y no antes: por encima de eso el buscador todavia
   conserva unos 400px, y partir la fila en dos le costaba altura a la tabla. */
@media (max-width: 1080px) {
  .billing-directory-toolbar {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

.billing-filters-panel {
  justify-content: flex-start;
}

.billing-filter-period {
  width: min(240px, 100%);
  flex-basis: 240px;
}

.billing-filter-status {
  width: 160px;
  flex-basis: 160px;
}

.billing-table-wrap {
  min-width: 0;
  overflow-x: auto;
}

.billing-table {
  min-width: 900px;
}

.billing-table th,
.billing-table td {
  padding: 12px 10px;
  vertical-align: middle;
}

/* La tabla tiene diez columnas y los nombres de clientes pueden ser largos.
   En vez de anchos fijos (que cortaban el nombre o empujaban las acciones
   fuera de la vista), el nombre y los botones bajan de renglon cuando no
   caben, y los montos y fechas se quedan en una sola linea. */
.billing-table td:nth-child(1) {
  min-width: 180px;
}

.billing-table td:nth-child(5),
.billing-table td:nth-child(6),
.billing-table td:nth-child(7),
.billing-table td:nth-child(8) {
  white-space: nowrap;
}

.billing-row:hover,
.billing-row.selected {
  background: var(--accent-dim);
}

.billing-row td:first-child strong {
  display: block;
  color: var(--text-1);
  overflow-wrap: anywhere;
}

.billing-date-cell,
.billing-balance-cell {
  color: var(--text-1);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
}

.billing-actions-cell {
  min-width: 150px;
}

.billing-actions-cell .client-row-action,
.billing-actions-cell .wa-split {
  margin: 2px 4px 2px 0;
}

.client-modal,
.billing-modal {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.client-modal-dialog,
.billing-modal-dialog {
  box-sizing: border-box;
  width: min(980px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  padding: 38px 22px 22px;
}

.client-modal-dialog > [data-client-ficha],
.billing-modal-dialog > [data-billing-ficha] {
  min-width: 0;
}

.client-modal-dialog > [data-client-ficha] .ficha-hero,
.billing-modal-dialog > [data-billing-ficha] .ficha-hero {
  padding-right: 48px;
}

.client-modal-close,
.billing-modal-close {
  top: 12px;
  right: 12px;
}

.billing-modal[hidden],
.client-modal[hidden] {
  display: none;
}

.billing-modal-backdrop,
.client-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(2, 7, 18, 0.78);
  backdrop-filter: blur(3px);
}

.billing-modal-dialog {
  position: relative;
  z-index: 1;
  overflow: auto;
}

.billing-modal-close,
.client-modal-close {
  position: absolute;
  z-index: 2;
  width: 32px;
  height: 32px;
}

.billing-modal-open,
.client-modal-open {
  overflow: hidden;
}

@media (max-width: 760px) {
  .billing-directory-toolbar {
    grid-template-columns: 1fr;
  }

  .billing-filter-period,
  .billing-filter-status {
    width: 100%;
    flex-basis: auto;
  }

  .billing-table {
    min-width: 820px;
  }

  .client-modal,
  .billing-modal {
    padding: 8px;
  }

  .client-modal-dialog,
  .billing-modal-dialog {
    width: calc(100vw - 16px);
    max-height: calc(100vh - 16px);
    padding: 38px 14px 18px;
  }

  .client-modal-dialog > [data-client-ficha] .ficha-hero,
  .billing-modal-dialog > [data-billing-ficha] .ficha-hero {
    padding-right: 0;
  }
}

input[type="date"],
input[type="time"],
input[type="month"] {
  color-scheme: dark;
}

[data-scheme="light"] input[type="date"],
[data-scheme="light"] input[type="time"],
[data-scheme="light"] input[type="month"] {
  color-scheme: light;
}

.billing-workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
  align-items: start;
  position: relative;
}

/* Los botones de alcance viven dentro de la cabecera del panel: como fila
   aparte le quitaban 50px de alto a la tabla de facturas. */
.billing-scope-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0;
}

.billing-scope-row .btn.active,
.clients-actions .btn.active {
  border-color: var(--accent);
  background: rgba(59, 130, 246, 0.16);
}

.billing-page .clients-table-panel {
  position: relative;
}

.billing-cal-popover {
  position: absolute;
  top: 64px;
  right: 16px;
  left: auto;
  z-index: 30;
  width: min(320px, calc(100% - 32px));
}

.billing-cal-popover[hidden] {
  display: none;
}

.billing-calendar-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.billing-calendar-panel {
  padding: 16px;
}

.billing-calendar-head h2 {
  margin-top: 4px;
  font-size: calc(18px * var(--fs));
}

.billing-cal-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 12px 0 10px;
}

.billing-cal-nav strong {
  text-transform: capitalize;
}

.billing-cal-week,
.billing-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}

.billing-cal-week span,
.billing-cal-empty {
  color: var(--muted);
  font-size: calc(11px * var(--fs));
  text-align: center;
}

.billing-cal-day {
  position: relative;
  display: flex;
  min-height: 46px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 4px 0 6px;
  border: 1px solid transparent;
  border-radius: 8px;
  color: inherit;
  background: var(--panel-2);
  cursor: pointer;
}

.billing-cal-day:hover {
  border-color: rgba(59, 130, 246, 0.45);
}

.billing-cal-day.today {
  border-color: var(--accent);
}

.billing-cal-day.selected {
  background: rgba(59, 130, 246, 0.22);
}

.billing-cal-day i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 19px;
  height: 17px;
  margin-top: 3px;
  padding: 0 5px;
  border-radius: 999px;
  font-size: calc(10.5px * var(--fs));
  font-style: normal;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  background: var(--panel-3);
  color: var(--muted);
}

.billing-cal-day.has-pending i {
  color: var(--amber);
}

.billing-cal-day.has-overdue i {
  color: var(--red);
}

.billing-cal-day.has-paid i {
  color: var(--green);
}

/* El dia con clientes por cobrar manda sobre el color por estado de
   factura: es el numero que se mira antes de salir a cobrar. */
.billing-cal-day.has-cobros {
  border-color: var(--accent);
  font-weight: 600;
}

.billing-cal-day.has-cobros i {
  background: var(--accent);
  color: #fff;
}

.billing-cal-day i.solo-facturas {
  background: var(--panel-3);
  color: var(--muted);
}

.billing-cal-legend i.cobros {
  background: var(--accent);
}


.billing-cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-top: 10px;
  color: var(--muted);
  font-size: calc(11px * var(--fs));
}

.billing-cal-legend i {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 4px;
  border-radius: 99px;
}

.billing-cal-legend i.pending { background: var(--amber); }
.billing-cal-legend i.overdue { background: var(--red); }
.billing-cal-legend i.paid { background: var(--green); }

.billing-cal-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin: 12px 0 8px;
}

.billing-cal-actions .btn.active {
  border-color: var(--accent);
  background: rgba(59, 130, 246, 0.16);
}

@media (max-width: 1100px) {
  .billing-workspace {
    grid-template-columns: 1fr;
  }
}

.metric-card[data-open-view] {
  cursor: pointer;
}

.ticket-filter-row .input {
  flex: 1 1 240px;
  min-width: 180px;
}

.ticket-filter-row .select {
  /* 180px cortaba "Todas las categorias" contra la flecha. */
  flex: 0 0 210px;
}

.ticket-work-list {
  display: grid;
  gap: 10px;
  padding: 0 16px 16px;
}

.ticket-work-card {
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
}

.ticket-work-card.selected {
  border-color: var(--accent);
  background: var(--accent-dim, rgba(59, 130, 246, 0.12));
}

.ticket-work-top {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
  justify-content: space-between;
  align-items: flex-start;
}

.ticket-work-copy {
  min-width: 0;
  flex: 1 1 240px;
}

.ticket-work-copy strong {
  display: block;
  color: var(--text-1);
}

.ticket-work-copy p {
  margin: 4px 0 8px;
  color: var(--text-1);
  font-size: calc(14px * var(--fs));
}

.ticket-work-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  align-items: center;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.ticket-status-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.ticket-status-chips.big {
  margin: 4px 0 16px;
}

.ticket-status-chip {
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 10px;
  color: var(--muted);
  background: transparent;
  cursor: pointer;
  font-size: calc(12px * var(--fs));
}

.ticket-status-chip:disabled {
  cursor: default;
  opacity: 0.7;
}

.ticket-status-chip.on {
  font-weight: 600;
}

.ticket-status-chip.next:not(.on) {
  border-color: var(--accent);
  color: var(--text-1);
  background: rgba(59, 130, 246, 0.14);
}

.ticket-status-chip.ticket-status-abierto.on {
  color: #fde68a;
  border-color: rgba(245, 158, 11, 0.45);
  background: rgba(245, 158, 11, 0.16);
}

.ticket-status-chip.ticket-status-proceso.on {
  color: #bfdbfe;
  border-color: rgba(59, 130, 246, 0.45);
  background: rgba(59, 130, 246, 0.16);
}

.ticket-status-chip.ticket-status-resuelto.on {
  color: #b8f6df;
  border-color: rgba(17, 201, 143, 0.45);
  background: rgba(17, 201, 143, 0.16);
}

.ticket-status-chip.ticket-status-cerrado.on {
  color: #cbd5e1;
  border-color: rgba(100, 116, 139, 0.45);
  background: rgba(100, 116, 139, 0.16);
}

.ticket-work-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.ticket-action-primary {
  border-color: rgba(59, 130, 246, 0.45);
  color: #fff;
  background: rgba(59, 130, 246, 0.88);
}

.ticket-action-primary:hover,
.ticket-action-primary:focus-visible {
  background: rgb(37, 99, 235);
}

.ticket-work-actions .btn.active {
  border-color: var(--accent);
  background: rgba(59, 130, 246, 0.16);
}

.ticket-inline-note {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.ticket-inline-note[hidden] {
  display: none;
}

.ticket-inline-note .input {
  flex: 1 1 220px;
}

.ticket-inline-visit {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 10px;
}

.ticket-inline-visit[hidden] {
  display: none;
}

.ticket-inline-visit .input {
  flex: 1 1 220px;
}

.ticket-visit-when {
  color: var(--text-1);
  font-weight: 600;
}

.ticket-visit-panel {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 10px;
  align-items: end;
  margin-bottom: 16px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(59, 130, 246, 0.06);
}

.ticket-visit-panel-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

@media (max-width: 820px) {
  .ticket-visit-panel {
    grid-template-columns: 1fr;
  }
}

.ticket-modal-dialog {
  width: min(1080px, calc(100vw - 24px));
  max-height: calc(100vh - 24px);
  overflow: auto;
}

.ticket-detail-hero {
  align-items: center;
  gap: 12px;
}

.ticket-detail-hero > div {
  flex: 1;
  min-width: 0;
}

.ticket-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 14px;
}

.ticket-work-panel {
  min-width: 0;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
}

.ticket-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.ticket-panel-head h3 {
  margin: 0;
  font-size: calc(15px * var(--fs));
}

.ticket-panel-head span {
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.ticket-dropzone {
  margin-bottom: 12px;
  padding: 14px;
  border: 1px dashed var(--line);
  border-radius: 10px;
  text-align: center;
  background: rgba(59, 130, 246, 0.06);
}

.ticket-dropzone.over {
  border-color: var(--accent);
  background: rgba(59, 130, 246, 0.14);
}

.ticket-dropzone strong,
.ticket-dropzone p {
  display: block;
  margin: 0;
}

.ticket-dropzone p {
  margin: 4px 0 10px;
  color: var(--muted);
  font-size: calc(13px * var(--fs));
}

.ticket-dropzone-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}

.ticket-note-composer {
  display: grid;
  gap: 8px;
  margin-bottom: 12px;
}

.ticket-case-details {
  padding-top: 4px;
}

.ticket-case-details summary {
  cursor: pointer;
  color: var(--muted);
  font-size: calc(13px * var(--fs));
}

.ticket-case-details .form-grid,
.ticket-case-details .field {
  margin-top: 12px;
}

@media (max-width: 820px) {
  .ticket-detail-grid {
    grid-template-columns: 1fr;
  }

  .ticket-status-chips.compact {
    width: 100%;
  }
}

.ticket-status-abierto {
  color: #fde68a;
  border-color: rgba(245, 158, 11, 0.4);
  background: rgba(245, 158, 11, 0.12);
}

.ticket-status-proceso {
  color: #bfdbfe;
  border-color: rgba(59, 130, 246, 0.4);
  background: rgba(59, 130, 246, 0.12);
}

.ticket-status-resuelto {
  color: #b8f6df;
  border-color: rgba(17, 201, 143, 0.35);
  background: rgba(17, 201, 143, 0.12);
}

.ticket-status-cerrado {
  color: #cbd5e1;
  border-color: rgba(100, 116, 139, 0.4);
  background: rgba(100, 116, 139, 0.12);
}

.ticket-priority-alta {
  color: #ffd7df;
  border-color: rgba(239, 71, 111, 0.35);
  background: rgba(239, 71, 111, 0.12);
}

.ticket-priority-media {
  color: #fde68a;
  border-color: rgba(245, 158, 11, 0.4);
  background: rgba(245, 158, 11, 0.12);
}

.ticket-priority-baja {
  color: #cbd5e1;
  border-color: rgba(100, 116, 139, 0.4);
  background: rgba(100, 116, 139, 0.12);
}

/* Estados y prioridades en tema claro: los tonos pastel de arriba se pierden
   sobre fondo blanco, asi que el color fuerte pasa al texto. */
[data-scheme="light"] .ticket-status-abierto,
[data-scheme="light"] .ticket-priority-media,
[data-scheme="light"] .ticket-status-chip.ticket-status-abierto.on {
  color: #9a6700;
  background: rgba(194, 123, 33, 0.12);
}

[data-scheme="light"] .ticket-status-proceso,
[data-scheme="light"] .ticket-status-chip.ticket-status-proceso.on {
  color: #1d4f91;
  background: rgba(59, 130, 246, 0.12);
}

[data-scheme="light"] .ticket-status-resuelto,
[data-scheme="light"] .ticket-status-chip.ticket-status-resuelto.on {
  color: #1f7a52;
  background: rgba(42, 157, 106, 0.12);
}

[data-scheme="light"] .ticket-status-cerrado,
[data-scheme="light"] .ticket-priority-baja,
[data-scheme="light"] .ticket-status-chip.ticket-status-cerrado.on {
  color: #4a5568;
  background: rgba(100, 116, 139, 0.12);
}

[data-scheme="light"] .ticket-priority-alta {
  color: #b42318;
  background: rgba(220, 53, 69, 0.1);
}

.ticket-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}

.ticket-photo {
  position: relative;
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
}

.ticket-photo img {
  display: block;
  width: 100%;
  height: 110px;
  object-fit: cover;
  cursor: zoom-in;
  background: rgba(0, 0, 0, 0.2);
}

.ticket-photo figcaption {
  padding: 6px 8px;
  color: var(--muted);
  font-size: calc(11px * var(--fs));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ticket-photo-del {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 24px;
  height: 24px;
  border: 0;
  border-radius: 99px;
  color: #fff;
  background: rgba(15, 23, 42, 0.72);
  cursor: pointer;
}

.ticket-notes {
  display: grid;
  gap: 10px;
  margin-bottom: 14px;
}

.ticket-note {
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
}

.ticket-note div {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.ticket-note p {
  margin: 0;
  white-space: pre-wrap;
}

.ticket-pending-files {
  color: var(--muted);
  font-size: calc(13px * var(--fs));
}

.ticket-modal[hidden] {
  display: none;
}

body.ticket-modal-open {
  overflow: hidden;
}

/* ---- Cobros automaticos ---- */

.billing-auto-panel {
  margin-bottom: 16px;
  padding: 12px 16px;
}

.billing-auto-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.billing-auto-head-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.auto-switch {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
  user-select: none;
}

.auto-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.auto-switch-track {
  flex: 0 0 auto;
  width: 42px;
  height: 24px;
  margin-top: 2px;
  border-radius: 999px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  transition: background 0.18s ease, border-color 0.18s ease;
}

.auto-switch-thumb {
  display: block;
  width: 18px;
  height: 18px;
  margin: 2px;
  border-radius: 50%;
  background: var(--text-3);
  transition: transform 0.18s ease, background 0.18s ease;
}

.auto-switch input:checked + .auto-switch-track {
  background: var(--accent);
  border-color: var(--accent);
}

.auto-switch input:checked + .auto-switch-track .auto-switch-thumb {
  background: #fff;
  transform: translateX(18px);
}

.auto-switch input:focus-visible + .auto-switch-track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.auto-switch-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.auto-switch-text strong {
  color: var(--text-1);
  font-size: calc(14px * var(--fs));
}

.auto-switch-text small {
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
  line-height: 1.45;
}

/* En la barra principal el titulo y el estado van en una sola linea para que
   el panel no le robe alto a la tabla de facturas. */
.auto-switch-main .auto-switch-text {
  flex-direction: row;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
}

.auto-switch-main .auto-switch-text strong {
  font-size: calc(16px * var(--fs));
}

.billing-auto-body {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}

.billing-auto-body[hidden] {
  display: none;
}

.billing-auto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 18px;
}

.billing-auto-block {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}

.billing-auto-block h3 {
  margin: 0;
  font-size: calc(12px * var(--fs));
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  font-family: var(--mono);
}

.billing-auto-cut {
  border-color: var(--border-2);
}

.field-hint {
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  line-height: 1.4;
}

.billing-auto-preview {
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
  line-height: 1.5;
}

.billing-auto-preview.warn {
  background: var(--amber-dim, rgba(245, 158, 11, 0.12));
  color: var(--text-1);
}

.billing-auto-preview strong {
  color: var(--amber);
}

.billing-auto-log {
  margin-top: 18px;
}

.billing-auto-log h3 {
  margin: 0 0 10px;
  font-size: calc(12px * var(--fs));
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  font-family: var(--mono);
}

.billing-auto-log ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.billing-auto-log li {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--surface-2);
  font-size: calc(12px * var(--fs));
  color: var(--text-2);
}

.billing-auto-log li.has-error {
  border-left: 2px solid var(--red);
}

.billing-auto-log-when {
  color: var(--text-1);
  font-family: var(--mono);
}

.billing-auto-log-tag {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
}

.billing-auto-log-nums {
  font-family: var(--mono);
}

.billing-auto-log-error {
  flex-basis: 100%;
  color: var(--red);
}

.billing-auto-last {
  margin: 10px 0 0;
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

@media (max-width: 720px) {
  .billing-auto-head {
    align-items: flex-start;
  }

  .billing-auto-head-actions {
    width: 100%;
  }

  .billing-auto-head-actions .btn {
    flex: 1;
  }
}

/* ---- Estado del MikroTik en la barra superior ---- */

.mk-status {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 12px 5px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-1);
  font-family: var(--font);
  cursor: pointer;
  flex-shrink: 0;
  max-width: 220px;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.mk-status:hover {
  border-color: var(--accent);
}

.mk-dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-3);
}

.mk-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.15;
  min-width: 0;
}

.mk-text {
  font-size: calc(12px * var(--fs));
  font-weight: 600;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mk-sub {
  font-size: calc(10px * var(--fs));
  color: var(--text-3);
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mk-status.is-online .mk-dot {
  background: var(--green);
  box-shadow: 0 0 0 3px rgba(17, 201, 143, 0.18);
}

.mk-status.is-offline .mk-dot {
  background: var(--red);
  box-shadow: 0 0 0 3px rgba(239, 71, 111, 0.18);
}

.mk-status.is-offline {
  border-color: rgba(239, 71, 111, 0.4);
}

.mk-status.is-off .mk-dot,
.mk-status.is-unknown .mk-dot {
  background: var(--text-3);
}

/* En pantallas angostas el chip se queda solo con el punto de color: el
   nombre del router y el usuario siguen disponibles en el tooltip. */
@media (max-width: 720px) {
  .mk-status {
    padding: 6px;
    max-width: none;
  }

  .mk-copy {
    display: none;
  }
}

/* ---- Respaldos ---- */

.historial-page > .panel {
  margin-bottom: 16px;
}

/* La pestana de respaldos ocupa el alto disponible y deja que scrolleen las
   listas de adentro: asi todo entra en una pantalla sin bajar la pagina. */
.backups-page {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: calc(100vh - var(--topbar-h) - 44px);
  min-height: 420px;
}

.backup-tabs {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.backup-tab {
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text-2);
  font-family: var(--font);
  font-size: calc(13px * var(--fs));
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.backup-tab:hover {
  border-color: var(--border-2);
  color: var(--text-1);
}

.backup-tab.active {
  border-color: var(--accent);
  background: var(--accent-dim);
  color: var(--text-1);
  font-weight: 600;
}

.backup-message {
  flex: 1;
  margin: 0;
  min-width: 0;
}

.backup-message:not(.visible) {
  display: none;
}

.backup-pane {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.backup-pane[hidden] {
  display: none;
}

.backup-pane-head {
  flex-shrink: 0;
  margin-bottom: 14px;
}

.backup-pane-head h2 {
  font-size: calc(16px * var(--fs));
}

.backup-pane-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.backup-inventory {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
}

.backup-inv-block {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.backup-inv-block h3 {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
  font-size: calc(13px * var(--fs));
  color: var(--text-1);
}

.backup-inv-total {
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--text-2);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
  font-weight: 400;
}

.backup-inv-total.ok {
  background: var(--green-dim, rgba(17, 201, 143, 0.14));
  color: var(--green);
}

.backup-inv-total.warn {
  background: var(--amber-dim, rgba(245, 158, 11, 0.14));
  color: var(--amber);
}

.backup-inv-warn {
  margin-bottom: 10px;
  padding: 8px 11px;
  border-radius: 8px;
  background: var(--amber-dim, rgba(245, 158, 11, 0.12));
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
  line-height: 1.45;
}

.backup-inv-list {
  list-style: none;
  margin: 0;
  padding: 0 6px 0 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.backup-inv-list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 10px;
  border-radius: 6px;
  background: var(--surface-2);
  font-size: calc(12px * var(--fs));
  color: var(--text-2);
}

.backup-inv-list b {
  color: var(--text-1);
  font-family: var(--mono);
  font-size: calc(12px * var(--fs));
}

.backup-inv-list b.mono {
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
}

.backup-inv-list i {
  font-style: normal;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
}

.backup-excluded {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px 14px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 9px 12px;
  border: 1px dashed var(--border);
  border-radius: 8px;
  font-size: calc(11.5px * var(--fs));
  color: var(--text-3);
}

.backup-excluded strong {
  color: var(--text-2);
}

.backup-excluded span::before {
  content: "·";
  margin-right: 8px;
  color: var(--text-3);
}

.backup-excluded span:first-of-type::before {
  content: none;
}

.backup-create {
  flex-shrink: 0;
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}

.backup-list-head {
  flex-shrink: 0;
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 14px 0 10px;
}

.backup-list-head h3 {
  margin: 0;
  font-size: calc(13px * var(--fs));
  color: var(--text-1);
}

.backup-list-head span {
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

/* La cabecera de la tabla queda fija mientras la lista scrollea. */
.backups-page [data-backup-list] thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}

.backup-note-field {
  flex: 1;
  min-width: 240px;
}

.backup-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.backup-actions .btn {
  padding: 5px 10px;
  font-size: calc(12px * var(--fs));
}

.backup-warn-inline {
  margin-top: 3px;
  color: var(--amber);
  font-size: calc(11px * var(--fs));
}

.backup-detail-row > td {
  padding: 0;
}

.restore-panel {
  padding: 16px;
  background: var(--surface-2);
}

.restore-warn {
  padding: 12px 14px;
  border-left: 3px solid var(--red);
  border-radius: 6px;
  background: var(--red-dim, rgba(239, 71, 111, 0.1));
  color: var(--text-2);
  font-size: calc(12.5px * var(--fs));
  line-height: 1.55;
}

.restore-warn strong {
  color: var(--text-1);
}

.restore-table {
  width: 100%;
  margin: 14px 0;
  font-size: calc(12px * var(--fs));
}

.restore-table th {
  text-align: left;
}

.restore-loss {
  color: var(--red);
}

.restore-hidden {
  margin: -6px 0 12px;
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
}

.restore-confirm {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

.restore-confirm .field {
  min-width: 240px;
}

/* ---- Historial de versiones ---- */

.hist-kind {
  display: flex;
  gap: 6px;
}

.hist-toolbar {
  grid-template-columns: minmax(0, 1fr) 190px 190px 130px;
}

@media (max-width: 1080px) {
  .hist-toolbar {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

.hist-errors .btn {
  width: 100%;
}

.hist-note {
  margin: 4px 0 12px;
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
}

.hist-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.hist-item {
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--surface-2);
  border-left: 2px solid transparent;
}

.hist-item.has-error {
  border-left-color: var(--red);
}

.hist-line {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.hist-when {
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
  flex: 0 0 auto;
}

.hist-who {
  color: var(--text-1);
  font-size: calc(12.5px * var(--fs));
  font-weight: 600;
}

.hist-summary {
  color: var(--text-2);
  font-size: calc(12.5px * var(--fs));
  flex: 1 1 240px;
  min-width: 0;
}

.hist-cat,
.hist-kind-badge {
  font-size: calc(10.5px * var(--fs));
  padding: 1px 8px;
}

.hist-kind-badge {
  color: var(--text-3);
}

.hist-fail {
  color: var(--red);
  border-color: rgba(239, 71, 111, 0.4);
}

.hist-more {
  padding: 3px 9px;
  font-size: calc(11px * var(--fs));
}

.hist-detail {
  margin: 8px 0 0;
  padding: 10px 12px;
  border-radius: 6px;
  background: var(--surface-3);
  color: var(--text-2);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
  line-height: 1.5;
  max-height: 320px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

.hist-meta {
  margin-top: 5px;
  color: var(--text-3);
  font-size: calc(10.5px * var(--fs));
}

.hist-error {
  margin-top: 5px;
  color: var(--red);
  font-size: calc(11.5px * var(--fs));
}

.hist-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 14px;
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

/* En movil no tiene sentido forzar el alto: con dos bloques apilados cada
   lista quedaria en una franja de pocos centimetros. Mejor scroll normal. */
@media (max-width: 760px) {
  .backups-page {
    height: auto;
    min-height: 0;
  }

  .backup-pane {
    overflow: visible;
  }

  .backup-pane-body,
  .backup-inv-list {
    overflow-y: visible;
    max-height: none;
  }

  .backup-tabs {
    flex-wrap: wrap;
  }

  .backup-message {
    flex-basis: 100%;
  }
}

/* ---- Dashboard con datos reales ---- */

.dash {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.dash-loading {
  padding: 60px 0;
}

.dash-kpis {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin-bottom: 0;
}

.dash-kpis .metric-card {
  cursor: pointer;
}

.dash-alerts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 10px;
}

.dash-alert {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: 10px;
  background: var(--surface);
  cursor: pointer;
}

.dash-alert p {
  margin: 3px 0 0;
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
  line-height: 1.45;
}

.dash-alert strong {
  color: var(--text-1);
  font-size: calc(13.5px * var(--fs));
}

.dash-alert-go {
  flex-shrink: 0;
  color: var(--accent);
  font-size: calc(12px * var(--fs));
  white-space: nowrap;
}

.dash-alert.level-alta {
  border-left-color: var(--red);
}

.dash-alert.level-media {
  border-left-color: var(--amber);
}

.dash-alert.level-baja {
  border-left-color: var(--text-3);
}

.dash-alert.level-ok {
  border-left-color: var(--green);
  cursor: default;
}

.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  gap: 14px;
  align-items: start;
}

.dash-panel .panel-head {
  margin-bottom: 14px;
}

.dash-panel .panel-head h2 {
  font-size: calc(15px * var(--fs));
}

.dash-panel .status-pill {
  cursor: pointer;
  white-space: nowrap;
}

.dash-chart svg {
  display: block;
  width: 100%;
  height: var(--dash-chart-h, 150px);
  overflow: visible;
}

.dash-grid line.dash-grid,
.dash-chart .dash-grid {
  stroke: var(--border);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.dash-bar {
  fill: var(--accent);
  opacity: 0.55;
}

.dash-bar.is-now {
  opacity: 1;
}

.dash-chart-labels {
  display: flex;
  margin-top: 8px;
}

.dash-chart-labels > span {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 0;
}

.dash-chart-labels b {
  color: var(--text-2);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
}

.dash-chart-labels i {
  color: var(--text-3);
  font-style: normal;
  font-size: calc(10.5px * var(--fs));
  text-transform: capitalize;
}

.dash-chart-labels .is-now b {
  color: var(--text-1);
}

.dash-chart-labels .is-now i {
  color: var(--accent);
}

.dash-split {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.dash-split li {
  display: grid;
  grid-template-columns: minmax(70px, 30%) 1fr auto auto;
  align-items: center;
  gap: 10px;
  font-size: calc(12px * var(--fs));
}

.dash-split-name {
  color: var(--text-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dash-split-track {
  height: 6px;
  border-radius: 999px;
  background: var(--surface-3);
  overflow: hidden;
}

.dash-split-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

.dash-split b {
  color: var(--text-1);
  font-family: var(--mono);
  font-size: calc(12px * var(--fs));
}

.dash-split i {
  color: var(--text-3);
  font-style: normal;
  font-family: var(--mono);
  font-size: calc(10.5px * var(--fs));
  min-width: 32px;
  text-align: right;
}

.dash-money {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.dash-money li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 11px;
  border-radius: 8px;
  background: var(--surface-2);
}

.dash-money span {
  color: var(--text-3);
  font-size: calc(10.5px * var(--fs));
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.dash-money b {
  color: var(--text-1);
  font-family: var(--mono);
  font-size: calc(14px * var(--fs));
}

.dash-money b.ok {
  color: var(--green);
}

.dash-money b.bad {
  color: var(--red);
}

.dash-due {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.dash-due h3 {
  margin: 0 0 8px;
  font-size: calc(11px * var(--fs));
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-3);
  font-family: var(--mono);
}

.dash-due ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.dash-due li {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  gap: 10px;
  font-size: calc(12px * var(--fs));
  color: var(--text-2);
}

.dash-due li span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dash-due li i {
  color: var(--text-3);
  font-style: normal;
  font-size: calc(11px * var(--fs));
}

.dash-due li b {
  color: var(--text-1);
  font-family: var(--mono);
}

.dash-foot {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
  line-height: 1.5;
}

/* ---- Analisis previo al respaldo ---- */

.backup-analysis {
  flex-shrink: 0;
  margin-top: 14px;
  padding: 14px;
  border: 1px solid var(--border-2);
  border-radius: 10px;
  background: var(--surface-2);
}

.backup-analysis[hidden] {
  display: none;
}

.backup-analysis-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.backup-analysis-head h3 {
  margin: 0;
  font-size: calc(13px * var(--fs));
  color: var(--text-1);
}

.backup-analysis-size {
  color: var(--accent);
  font-family: var(--mono);
  font-size: calc(12px * var(--fs));
}

.backup-analysis-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
}

.backup-analysis-block h4 {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 8px;
  font-size: calc(11px * var(--fs));
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
  font-family: var(--mono);
}

.backup-analysis-block h4 b {
  font-family: var(--font);
  font-size: calc(11px * var(--fs));
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-2);
}

.backup-analysis-block h4 b.ok {
  color: var(--green);
}

.backup-analysis-block h4 b.bad {
  color: var(--red);
}

.backup-analysis-block ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 190px;
  overflow-y: auto;
}

.backup-analysis-block li {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  gap: 10px;
  padding: 4px 8px;
  border-radius: 5px;
  background: var(--surface);
  font-size: calc(11.5px * var(--fs));
  color: var(--text-2);
}

.backup-analysis-block li b {
  color: var(--text-1);
  font-family: var(--mono);
}

.backup-analysis-block li i {
  color: var(--text-3);
  font-style: normal;
  font-size: calc(10.5px * var(--fs));
  min-width: 54px;
  text-align: right;
}

.backup-analysis-note {
  margin: 6px 0 0;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  line-height: 1.5;
}

.backup-analysis-note.bad {
  color: var(--red);
}

.backup-analysis-warns {
  margin: 12px 0 0;
  padding: 9px 12px 9px 26px;
  border-radius: 8px;
  background: var(--amber-dim, rgba(245, 158, 11, 0.12));
  color: var(--text-2);
  font-size: calc(11.5px * var(--fs));
  line-height: 1.6;
}

.backup-analysis-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.backup-analysis-actions .backup-analysis-note {
  margin: 0;
  flex: 1;
  min-width: 200px;
}

/* Aviso de version nueva: sale solo cuando el panel abierto quedo atrasado
   y recargar podria perder algo que el usuario estaba llenando. */
.app-update-bar {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 999;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  color: var(--text-1);
  background: var(--surface);
  box-shadow: 0 8px 24px var(--shadow);
  font-size: calc(13px * var(--fs));
}

@media (max-width: 760px) {
  .app-update-bar {
    right: 12px;
    left: 12px;
    bottom: 12px;
    justify-content: space-between;
  }
}

/* Aviso de datos repetidos al llenar una ficha. La IP va en rojo porque es la
   unica que rompe la red; el resto solo confunde al operador. */
.client-conflicts {
  display: grid;
  gap: 8px;
  margin-top: 12px;
  padding: 10px 12px;
  border: 1px solid var(--amber);
  border-radius: var(--radius);
  background: var(--amber-dim);
}

.client-conflicts[hidden] {
  display: none;
}

.client-conflict-row {
  display: grid;
  gap: 2px;
  font-size: calc(12px * var(--fs));
}

.client-conflict-row strong {
  color: var(--text-1);
}

.client-conflict-row span {
  color: var(--text-2);
}

.client-conflict-ip strong {
  color: var(--red);
}

/* Revision de sincronizacion con el MikroTik */
.sync-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0 4px;
}

.sync-summary span {
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-2);
  background: var(--surface-2);
  font-size: calc(12px * var(--fs));
}

.sync-summary span strong {
  margin-right: 4px;
  color: var(--text-1);
  font-family: var(--mono);
}

.sync-summary span.warn {
  border-color: var(--amber);
  background: var(--amber-dim);
}

.sync-group {
  margin-top: 18px;
}

.sync-group-head h3 {
  margin: 0;
  font-size: calc(14px * var(--fs));
}

.sync-group-head p {
  margin: 2px 0 10px;
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
}

.sync-item {
  margin-bottom: 8px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}

.sync-item-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

.sync-item-head strong {
  min-width: 0;
  overflow: hidden;
  color: var(--text-1);
  font-size: calc(13px * var(--fs));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sync-actions {
  display: flex;
  flex: 0 0 auto;
  gap: 6px;
}

.sync-field {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 3px 0;
  font-size: calc(12px * var(--fs));
}

.sync-field-name {
  flex: 0 0 120px;
  color: var(--text-2);
}

.sync-field-values {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
  color: var(--text-2);
}

.sync-side {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}

.sync-side small {
  color: var(--text-3);
  font-size: calc(10px * var(--fs));
  text-transform: uppercase;
}

.sync-side strong {
  color: var(--text-1);
  font-family: var(--mono);
}

.sync-vs {
  color: var(--text-3);
}

@media (max-width: 760px) {
  .sync-item-head {
    align-items: stretch;
    flex-direction: column;
  }

  .sync-field {
    flex-direction: column;
    gap: 2px;
  }

  .sync-field-name {
    flex-basis: auto;
  }
}

/* Barra de progreso del riel de la ficha. */
.ficha-guide-bar {
  position: relative;
  display: block;
  overflow: hidden;
  height: 6px;
  border-radius: 999px;
  background: var(--surface-3);
}

.ficha-guide-bar > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.2s ease;
}

/* Ficha con riel: cabecera y pie quietos, solo el contenido hace scroll.
   Se limita al modal de la ficha para no tocar el de sincronizacion, que
   comparte las clases del dialogo. */
[data-client-ficha-modal] .client-modal-dialog {
  display: flex;
  overflow: hidden;
  height: calc(100vh - 32px);
  flex-direction: column;
}

[data-client-ficha-modal] .client-modal-dialog > [data-client-ficha] {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
}

.ficha-shell {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
}

.ficha-layout {
  display: grid;
  flex: 1 1 auto;
  gap: 18px;
  min-height: 0;
  margin-top: 14px;
  grid-template-columns: 236px minmax(0, 1fr);
}

.ficha-rail {
  overflow-y: auto;
  min-height: 0;
  padding: 2px 10px 8px 0;
  border-right: 1px solid var(--border);
  scrollbar-gutter: stable;
}

.ficha-content {
  position: relative;
  overflow-y: auto;
  min-height: 0;
  padding-right: 2px;
  scrollbar-gutter: stable;
}

.ficha-rail-progress {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.ficha-rail-progress strong {
  display: block;
  margin: 2px 0 8px;
  color: var(--text-1);
  font-size: calc(13px * var(--fs));
}

.ficha-rail-group {
  margin-top: 14px;
}

.ficha-rail-group-title {
  display: block;
  margin-bottom: 6px;
  color: var(--text-3);
  font-size: calc(10px * var(--fs));
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.ficha-rail-step {
  margin-bottom: 2px;
}

.ficha-rail-step.open {
  margin-bottom: 10px;
}

.ficha-rail-link {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 5px 8px;
  border: 0;
  border-radius: 6px;
  color: var(--text-1);
  background: none;
  font-size: calc(12px * var(--fs));
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.ficha-rail-link.plain {
  font-weight: 400;
  color: var(--text-2);
}

.ficha-rail-link small {
  color: var(--text-3);
  font-family: var(--mono);
  font-weight: 400;
}

.ficha-rail-link:hover:not(:disabled) {
  background: var(--surface-2);
}

/* La seccion que se esta viendo: barra de color a la izquierda. */
.ficha-rail-link.active {
  color: var(--accent);
  background: var(--accent-dim);
  box-shadow: inset 2px 0 0 var(--accent);
}

.ficha-rail-link:disabled {
  cursor: not-allowed;
  color: var(--text-3);
}

.ficha-rail-step.done .ficha-rail-link small {
  color: var(--green);
}

.ficha-rail-step ul {
  display: none;
  margin: 2px 0 0;
  padding: 0 0 0 8px;
  list-style: none;
}

.ficha-rail-step.open ul {
  display: block;
}

.ficha-rail-step li {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 1px 0;
}

/* Punto de estado: relleno cuando el dato ya esta, hueco cuando falta. */
.ficha-rail-step li::before {
  content: "";
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border: 1px solid var(--text-3);
  border-radius: 50%;
}

.ficha-rail-step li.done::before {
  border-color: var(--green);
  background: var(--green);
}

.ficha-rail-step li.pending::before {
  border-color: var(--amber);
}

.ficha-rail-step li button {
  padding: 0;
  border: 0;
  color: var(--text-2);
  background: none;
  font-size: calc(11.5px * var(--fs));
  text-align: left;
  cursor: pointer;
}

.ficha-rail-step li button:hover:not(:disabled) {
  color: var(--accent);
  text-decoration: underline;
}

.ficha-rail-step li button:disabled {
  cursor: default;
  opacity: 0.55;
}

.ficha-rail-step li.done button {
  color: var(--text-1);
}

.ficha-rail-step li em {
  color: var(--text-3);
  font-style: normal;
}

/* Pie siempre a la vista: guardar y cancelar no deberian exigir scroll. */
.ficha-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex: 0 0 auto;
  flex-wrap: wrap;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.ficha-footer-hint {
  color: var(--amber);
  font-size: calc(12px * var(--fs));
}

.ficha-footer-actions {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

@media (max-width: 900px) {
  [data-client-ficha-modal] .client-modal-dialog {
    height: calc(100vh - 16px);
  }

  .ficha-layout {
    gap: 12px;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  .ficha-rail {
    max-height: 190px;
    padding: 0 0 10px;
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }

  .ficha-footer-actions {
    width: 100%;
    margin-left: 0;
  }

  .ficha-footer-actions .btn {
    flex: 1 1 auto;
  }
}

/* Overlay de guardado. Tapa toda la pantalla a proposito: mientras el servidor
   habla con el MikroTik no debe entrar ningun clic mas. */
.saving-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  background: rgba(2, 7, 18, 0.6);
  backdrop-filter: blur(2px);
}

.saving-overlay[hidden] {
  display: none;
}

.saving-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 22px;
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  color: var(--text-1);
  background: var(--surface);
  box-shadow: 0 12px 32px var(--shadow);
  font-size: calc(14px * var(--fs));
}

.saving-spinner {
  width: 18px;
  height: 18px;
  border: 2px solid var(--border-2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: saving-spin 0.7s linear infinite;
}

@keyframes saving-spin {
  to { transform: rotate(360deg); }
}

/* Quien pide no animarse, no se anima. */
@media (prefers-reduced-motion: reduce) {
  .saving-spinner {
    animation-duration: 2.4s;
  }
}

/* Seleccion multiple en la lista de clientes */
.client-head-select {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Las casillas solo existen visualmente dentro del modo Seleccionar.
   display:none tambien las saca del recorrido con Tab. */
.client-select {
  display: none;
}

.clients-page.select-mode .client-select {
  display: inline-block;
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  accent-color: var(--accent);
  cursor: pointer;
}

.client-bulk-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  padding: 9px 12px;
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  background: var(--accent-dim);
}

.client-bulk-bar[hidden] {
  display: none;
}

.client-bulk-bar strong {
  color: var(--text-1);
  font-size: calc(13px * var(--fs));
}

.client-bulk-actions {
  display: flex;
  gap: 8px;
}

/* Equipos cargados antes de guardar la ficha: todavia no existen en la base. */
.equip-item.pending {
  border-style: dashed;
}

.equip-pending-note {
  margin: 8px 0 0;
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
}

/* Editar / Quitar de cada equipo, y el pie del formulario cuando se esta
   editando uno ya cargado. */
.equip-actions {
  display: flex;
  flex: 0 0 auto;
  gap: 6px;
}

.equip-form-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.equip-form-actions [hidden] {
  display: none;
}

/* =========================================================================
   Movimiento y estados de carga
   Tres duraciones, dos curvas, y la regla de que solo se animan opacity y
   transform: son las dos unicas propiedades que el navegador mueve sin
   recalcular la pagina entera.
   ========================================================================= */

/* ---- Marcador deslizante del menu lateral -------------------------------
   Un solo elemento que viaja entre secciones. Antes eran diez fondos que se
   encendian y apagaban de golpe, y el salto se notaba. */
.sidebar-nav {
  position: relative;
}

.nav-indicator {
  position: absolute;
  left: 8px;
  right: 8px;
  top: 0;
  height: 0;
  border-radius: 6px;
  background: var(--accent-dim);
  box-shadow: inset 0 0 0 1px var(--border-2);
  opacity: 0;
  pointer-events: none;
  transition: transform var(--dur-slow) var(--ease-soft),
              opacity var(--dur-fast) var(--ease);
}

.nav-indicator.ready {
  opacity: 1;
}

.nav-indicator::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 50%;
  width: 3px;
  height: 60%;
  transform: translateY(-50%);
  border-radius: 0 3px 3px 0;
  background: var(--accent);
}

/* El item activo solo aporta el color: el fondo y el borde los pone el
   marcador, que es lo que se mueve. */
.nav-item {
  z-index: 1;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.nav-item svg {
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-slow) var(--ease-soft);
}

.nav-item.active {
  background: transparent;
  box-shadow: none;
}

.nav-item.active::before {
  display: none;
}

.nav-item.active svg {
  opacity: 1;
  transform: scale(1.08);
}

/* ---- Roce y pulsacion ---------------------------------------------------
   120-180 ms: lo que el dedo toca tiene que sentirse instantaneo. */
.btn,
.icon-btn,
.client-row-action,
.metric-card,
.client-table-row {
  transition: transform var(--dur-fast) var(--ease-soft),
              background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              box-shadow var(--dur) var(--ease);
}

.btn:hover:not(:disabled),
.icon-btn:hover:not(:disabled) {
  transform: translateY(-1px);
}

.btn:active:not(:disabled),
.icon-btn:active:not(:disabled) {
  transform: translateY(0);
}

.metric-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 22px -14px var(--shadow);
}

/* ---- Esqueleto de carga -------------------------------------------------
   Antes cada pestana escribia "Cargando..." y despues metia la tabla: el alto
   cambiaba dos veces y todo brincaba. Ahora el hueco se reserva con la forma
   final antes de pedir los datos. */
@keyframes shimmer {
  from { background-position: -240px 0; }
  to { background-position: 360px 0; }
}

.skel {
  display: grid;
  gap: 10px;
}

.skel-line,
.skel-row,
.skel-card,
.skel-block {
  border-radius: var(--radius);
  background-image: linear-gradient(90deg, var(--surface-2) 0%, var(--surface-3) 45%, var(--surface-2) 90%);
  background-size: 360px 100%;
  animation: shimmer 1.1s linear infinite;
}

.skel-line {
  height: 12px;
}

.skel-row {
  height: 54px;
}

.skel-card {
  height: 84px;
}

.skel-block {
  height: 220px;
}

.skel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px;
}

.skel-split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 14px;
}

/* Desfase minimo entre filas para que no parezca una imagen fija. */
.skel > *:nth-child(2) { animation-delay: 90ms; }
.skel > *:nth-child(3) { animation-delay: 180ms; }
.skel > *:nth-child(4) { animation-delay: 270ms; }
.skel > *:nth-child(5) { animation-delay: 360ms; }
.skel > *:nth-child(6) { animation-delay: 450ms; }

/* ---- Buscador de pestanas (Ctrl K) -------------------------------------- */
.cmdk-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  width: calc(100% - 16px);
  margin: 10px 8px 2px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--text-3);
  font-family: var(--font);
  font-size: calc(12px * var(--fs));
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}

.cmdk-hint:hover {
  border-color: var(--border-2);
  background: var(--accent-dim);
  color: var(--accent);
}

.cmdk-hint svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.cmdk-hint span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar.collapsed .cmdk-hint {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}

.sidebar.collapsed .cmdk-hint span,
.sidebar.collapsed .cmdk-hint kbd {
  display: none;
}

kbd {
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--surface);
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(10.5px * var(--fs));
}

.cmdk-backdrop {
  position: fixed;
  inset: 0;
  z-index: 400;
  background: rgba(0, 0, 0, 0.34);
  animation: paneIn var(--dur-fast) var(--ease) both;
}

.cmdk-backdrop[hidden] {
  display: none;
}

.cmdk-dialog {
  position: fixed;
  left: 50%;
  top: 13vh;
  z-index: 401;
  width: min(520px, calc(100vw - 32px));
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.6);
  animation: cmdkIn var(--dur) var(--ease) both;
}

@keyframes cmdkIn {
  from {
    opacity: 0;
    transform: translate(-50%, -8px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0) scale(1);
  }
}

.cmdk-field {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}

.cmdk-field svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--text-3);
}

.cmdk-field input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-1);
  font-family: var(--font);
  font-size: calc(15px * var(--fs));
}

.cmdk-list {
  max-height: 320px;
  overflow-y: auto;
  padding: 6px;
}

.cmdk-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  font-size: calc(13.5px * var(--fs));
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.cmdk-item .ico {
  width: 16px;
  height: 16px;
}

.cmdk-item small {
  margin-left: auto;
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
}

.cmdk-item.active,
.cmdk-item:hover {
  background: var(--accent-dim);
  color: var(--accent);
}

.cmdk-empty {
  padding: 22px 16px;
  color: var(--text-3);
  font-size: calc(13px * var(--fs));
  text-align: center;
}

/* ---- Alta de cliente en cuatro pasos ------------------------------------
   La ficha de un cliente ya guardado sigue igual. Esto solo aplica al alta,
   donde el formulario largo asustaba y no dejaba ver que faltaba. */
.ficha-shell.is-wizard .ficha-layout {
  grid-template-columns: 232px minmax(0, 1fr) 264px;
}

.ficha-shell.is-wizard .ficha-content {
  overflow: hidden;
}

.wizard-progress {
  height: 3px;
  margin-top: 12px;
  border-radius: 3px;
  background: var(--surface-3);
  overflow: hidden;
}

.wizard-progress span {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--accent);
  transition: width 420ms var(--ease);
}

.wizard-steps {
  position: relative;
  margin-top: 12px;
}

.wizard-steps::before {
  content: "";
  position: absolute;
  left: 18px;
  top: 20px;
  bottom: 22px;
  width: 2px;
  background: var(--surface-3);
}

.wizard-step {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 11px;
  width: 100%;
  margin-bottom: 4px;
  padding: 8px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}

.wizard-step:hover {
  background: var(--surface-2);
}

.wizard-step-dot {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: inset 0 0 0 2px var(--surface-3);
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(10.5px * var(--fs));
  font-weight: 600;
  transition: background var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              color var(--dur) var(--ease);
}

.wizard-step.current .wizard-step-dot {
  background: var(--accent);
  box-shadow: inset 0 0 0 2px var(--accent), 0 0 0 4px var(--accent-dim);
  color: #fff;
}

.wizard-step.done .wizard-step-dot {
  background: var(--green-dim);
  box-shadow: inset 0 0 0 2px var(--green);
  color: var(--green);
}

.wizard-step b {
  display: block;
  color: var(--text-2);
  font-size: calc(12.5px * var(--fs));
  font-weight: 600;
  transition: color var(--dur-fast) var(--ease);
}

.wizard-step.current b {
  color: var(--text-1);
}

.wizard-step small {
  display: block;
  margin-top: 1px;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
}

/* Solo se ve el paso actual, y entra deslizando desde la derecha. */
.ficha-shell.is-wizard [data-ficha-section] {
  display: none;
}

.ficha-shell.is-wizard [data-ficha-section].is-step {
  display: block;
  animation: stepIn 300ms var(--ease) both;
}

@keyframes stepIn {
  from {
    opacity: 0;
    transform: translateX(22px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.wizard-summary {
  overflow-y: auto;
  min-height: 0;
  padding-left: 16px;
  border-left: 1px solid var(--border);
}

.wizard-summary-title {
  display: block;
  margin-bottom: 8px;
  color: var(--text-3);
  font-size: calc(10px * var(--fs));
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.wizard-summary-card {
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}

.wizard-summary-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.wizard-summary-head strong {
  display: block;
  color: var(--text-1);
  font-size: calc(13px * var(--fs));
}

.wizard-summary-head small {
  display: block;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
}

.wizard-summary-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  border-top: 1px solid var(--border);
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

.wizard-summary-row b {
  color: var(--text-1);
  font-family: var(--mono);
  font-size: calc(12px * var(--fs));
  font-weight: 600;
  text-align: right;
}

.wizard-summary-row.pending b {
  color: var(--text-3);
  font-weight: 400;
}

.wizard-summary-note {
  margin-top: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: calc(11.5px * var(--fs));
  line-height: 1.55;
}

.wizard-summary-note strong {
  display: block;
  margin-bottom: 3px;
  color: var(--text-1);
  font-size: calc(11.5px * var(--fs));
}

.wizard-summary-note code {
  color: var(--text-2);
  font-family: var(--mono);
  font-size: calc(10.5px * var(--fs));
  word-break: break-all;
}

.ficha-footer-step {
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

/* Los campos de una fila arrancan arriba. Sin esto, el que lleva pista debajo
   reparte el alto sobrante entre sus filas y su caja queda mas alta que la del
   campo de al lado: la IP y el nombre de la cola no se alineaban. */
.form-grid > .field {
  align-content: start;
}

/* Pista calculada bajo un campo: la fecha que se va a guardar sola, el nombre
   de cola que se va a usar si se deja vacio. */
.field-auto {
  display: block;
  margin-top: 5px;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  line-height: 1.45;
}

.field-auto.is-warn {
  color: var(--amber);
}

@media (max-width: 1100px) {
  .ficha-shell.is-wizard .ficha-layout {
    grid-template-columns: 232px minmax(0, 1fr);
  }

  .ficha-shell.is-wizard .wizard-summary {
    display: none;
  }
}

/* ---- Quien pidio menos movimiento ---------------------------------------
   Sin esto el sistema marea a quien tiene esa preferencia activada. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- Pestana Reportes --------------------------------------------------- */
.reports-page {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.report-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.report-toolbar-copy {
  flex: 1;
  min-width: 180px;
}

.report-toolbar-copy h2 {
  margin: 2px 0 0;
}

.report-kpis {
  margin-bottom: 0;
}

.report-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

@media (max-width: 1000px) {
  .report-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.report-grid .panel {
  display: flex;
  flex-direction: column;
}

.report-grid .panel-head p {
  margin-top: 3px;
  font-size: calc(12px * var(--fs));
}

/* Cartera de cada zona, debajo de sus barras: la barra dice cuantos son y
   esto dice cuanto factura cada una. */
.report-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.report-legend span {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 9px;
  border-radius: 20px;
  background: var(--surface-2);
  color: var(--text-1);
  font-family: var(--mono);
  font-size: calc(11.5px * var(--fs));
}

.report-legend i {
  color: var(--text-3);
  font-family: var(--font);
  font-style: normal;
  font-size: calc(11px * var(--fs));
}

.report-row {
  cursor: pointer;
}

.report-row:hover {
  background: var(--accent-dim);
}

.report-row:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* ---- Cobros automaticos en la barra superior ----------------------------
   El bloque vivia dentro de Cobro, empujando la tabla de facturas hacia abajo
   aunque casi nunca se toca. Ahora es un indicador junto al del MikroTik: se
   lee el estado de un vistazo y las reglas se abren solo para cambiarlas. */
.auto-chip.is-ok .mk-dot {
  background: var(--green);
  box-shadow: 0 0 0 3px var(--green-dim);
}

.auto-chip.is-manual .mk-dot {
  background: var(--amber);
  box-shadow: 0 0 0 3px var(--amber-dim);
}

.auto-chip.is-manual {
  border-color: color-mix(in srgb, var(--amber) 40%, transparent);
}

.auto-modal-dialog {
  width: min(920px, calc(100vw - 32px));
  max-height: min(760px, calc(100vh - 48px));
  overflow-y: auto;
}

/* Dentro de su propia ventana el bloque ya no necesita marco ni margen: el
   marco es el dialogo. */
.auto-modal-dialog [data-billing-auto] {
  padding: 0;
}

.auto-modal-dialog .billing-auto-head {
  padding-right: 44px;
}

/* ---- Contabilidad ------------------------------------------------------- */
.finance-page {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* La barra queda pegada arriba: el registro de gastos se hace largo y tener
   que subir hasta el techo para anotar el siguiente es el gesto que mas se
   repite en esta pestana. Los margenes negativos compensan el padding de
   .content para que el contenido pase por debajo sin asomar por los lados. */
.finance-page .report-toolbar {
  --pad: var(--content-pad, 22px);
  position: sticky;
  top: 0;
  z-index: 5;
  /* Los margenes negativos sacan la barra hasta los bordes del area de scroll,
     para que el contenido no asome por los lados al pasar por debajo. */
  margin: 0 calc(var(--pad) * -1);
  padding: 4px var(--pad) 12px;
  background: var(--bg);
}

/* La barra se pega justo debajo del padding del contenedor, no en su borde:
   ese hueco deja ver el contenido pasando por arriba. Este bloque lo tapa. */
.finance-page .report-toolbar::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: calc(var(--pad) + 2px);
  background: var(--bg);
}

/* Utilidad negativa: el numero no puede leerse igual que uno bueno. */
.metric-card.is-loss::before {
  background: var(--red);
}

.metric-card.is-loss strong {
  color: var(--red);
}

/* Flujo de caja: dos barras por mes. La clara entra, la oscura sale. */
.flow-chart .flow-in {
  fill: var(--green);
  opacity: 0.85;
}

.flow-chart .flow-out {
  fill: var(--red);
  opacity: 0.75;
}

.flow-legend {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.flow-legend span {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-2);
  font-size: calc(11.5px * var(--fs));
  white-space: nowrap;
}

.flow-legend span::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 2px;
}

.flow-legend-in::before {
  background: var(--green);
}

.flow-legend-out::before {
  background: var(--red);
}

.expense-form-panel[hidden] {
  display: none;
}

.expense-form-panel .form {
  margin-top: 14px;
}

/* Las categorias de gasto se distinguen de un vistazo, pero sin convertir la
   tabla en un semaforo: mismo tono para todas, el color lo llevan los montos. */
.badge[class*="expense-cat-"] {
  background: var(--surface-2);
  color: var(--text-2);
  font-weight: 500;
}

.badge.expense-cat-enlace,
.badge.expense-cat-equipos {
  background: var(--accent-dim);
  color: var(--accent);
}

.badge.expense-cat-salarios {
  background: var(--purple-dim);
  color: var(--purple);
}

[data-expense-table] td small {
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
}

/* Editar y Eliminar en una sola linea: la columna es angosta y se partian. */
[data-expense-table] td:last-child {
  display: flex;
  gap: 6px;
  white-space: nowrap;
}

/* ---- Bajas de clientes -------------------------------------------------- */
.client-status-cancelado {
  background: color-mix(in srgb, var(--text-3) 18%, transparent);
  color: var(--text-2);
}

.cancel-modal-dialog {
  width: min(620px, calc(100vw - 32px));
  max-height: min(760px, calc(100vh - 48px));
  overflow-y: auto;
}

.cancel-warning {
  margin: 14px 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--amber);
  border-radius: var(--radius);
  background: var(--surface-2);
}

.cancel-warning strong {
  display: block;
  color: var(--text-1);
  font-size: calc(13px * var(--fs));
}

.cancel-warning p {
  margin: 4px 0 0;
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
  line-height: 1.5;
}

.cancel-invoices {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.cancel-invoices .ficha-note {
  margin: 4px 0 10px;
}

.cancel-choice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 8px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.cancel-choice:hover {
  border-color: var(--border-2);
}

.cancel-choice:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.cancel-choice input {
  margin-top: 2px;
  accent-color: var(--accent);
  flex-shrink: 0;
}

.cancel-choice strong {
  display: block;
  color: var(--text-1);
  font-size: calc(12.5px * var(--fs));
}

.cancel-choice small {
  display: block;
  margin-top: 3px;
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
  line-height: 1.45;
}

/* ---- Firma del cliente --------------------------------------------------
   El lienzo es blanco a proposito, en tema claro y oscuro: es un papel, y la
   firma tiene que verse igual en pantalla que impresa. */
.sign-dialog {
  width: min(680px, calc(100vw - 24px));
}

.sign-head h2 {
  margin: 2px 0 0;
}

.sign-head p {
  margin: 4px 0 0;
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

.sign-pad {
  position: relative;
  height: min(260px, 42vh);
  margin: 16px 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #fff;
  overflow: hidden;
}

.sign-pad canvas {
  display: block;
  width: 100%;
  height: 100%;
  /* Sin esto el navegador interpreta el trazo como gesto de scroll y la firma
     se corta en cuanto el dedo se mueve. */
  touch-action: none;
  cursor: crosshair;
}

.sign-baseline {
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: 28%;
  border-bottom: 1px dashed rgba(18, 35, 61, 0.28);
  pointer-events: none;
}

.sign-hint {
  position: absolute;
  left: 50%;
  bottom: 30%;
  transform: translateX(-50%);
  color: rgba(18, 35, 61, 0.32);
  font-size: calc(13px * var(--fs));
  letter-spacing: 0.04em;
  pointer-events: none;
}

.sign-hint[hidden] {
  display: none;
}

.sign-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.sign-meta {
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
}

.sign-actions {
  display: flex;
  gap: 8px;
}

/* ---- Boleta de instalacion ---------------------------------------------- */
.boleta-dialog {
  width: min(860px, calc(100vw - 24px));
  max-height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  padding: 0;
}

.boleta-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}

.boleta-toolbar-actions {
  display: flex;
  gap: 8px;
}

.boleta-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 18px;
  background: var(--surface-2);
}

/* El documento es siempre claro: es una hoja, no una pantalla. Asi lo que se
   ve es exactamente lo que sale de la impresora. */
.boleta {
  max-width: 760px;
  margin: 0 auto;
  padding: 34px 38px;
  background: #fff;
  color: #1a1a1a;
  font-size: calc(13px * var(--fs));
  line-height: 1.5;
  box-shadow: 0 10px 30px -18px rgba(0, 0, 0, 0.5);
}

.boleta-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding-bottom: 16px;
  border-bottom: 2px solid #1a1a1a;
}

.boleta-head h1 {
  margin: 0;
  font-size: calc(20px * var(--fs));
  letter-spacing: -0.3px;
}

.boleta-head p {
  margin: 4px 0 0;
  color: #555;
  font-size: calc(11.5px * var(--fs));
}

.boleta-numero {
  text-align: right;
  flex-shrink: 0;
}

.boleta-numero span {
  display: block;
  color: #555;
  font-size: calc(11px * var(--fs));
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.boleta-numero strong {
  display: block;
  margin: 2px 0;
  font-family: var(--mono);
  font-size: calc(17px * var(--fs));
}

.boleta-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 26px;
  margin-top: 20px;
}

.boleta h2 {
  margin: 0 0 8px;
  padding-bottom: 5px;
  border-bottom: 1px solid #ddd;
  color: #1a1a1a;
  font-size: calc(12px * var(--fs));
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.boleta-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
  border-bottom: 1px dotted #e2e2e2;
}

.boleta-row span {
  color: #666;
  font-size: calc(11.5px * var(--fs));
  flex-shrink: 0;
}

.boleta-row strong {
  color: #1a1a1a;
  font-size: calc(12.5px * var(--fs));
  font-weight: 600;
  text-align: right;
}

.boleta-block {
  margin-top: 22px;
}

.boleta-table {
  width: 100%;
  border-collapse: collapse;
  font-size: calc(12px * var(--fs));
}

.boleta-table th {
  padding: 6px 8px;
  border-bottom: 1px solid #1a1a1a;
  color: #555;
  font-size: calc(10.5px * var(--fs));
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.boleta-table td {
  padding: 7px 8px;
  border-bottom: 1px solid #eee;
  color: #1a1a1a;
}

.boleta-vacio,
.boleta-detalle {
  margin: 0;
  color: #333;
  font-size: calc(12.5px * var(--fs));
  white-space: pre-line;
}

.boleta-vacio {
  color: #777;
  font-style: italic;
}

.boleta-conformidad p {
  margin: 0 0 18px;
  color: #333;
  font-size: calc(12px * var(--fs));
}

.boleta-firmas {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 34px;
  margin-top: 26px;
}

.boleta-firma {
  text-align: center;
}

.boleta-firma-hueco {
  position: relative;
  height: 74px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.boleta-firma-linea {
  display: block;
  width: 100%;
  border-bottom: 1px solid #1a1a1a;
}

.boleta-firma-img {
  max-width: 100%;
  max-height: 74px;
  object-fit: contain;
  /* La firma se guarda sobre blanco: multiply la funde con el papel en vez de
     dejarle un recuadro alrededor. */
  mix-blend-mode: multiply;
  border-bottom: 1px solid #1a1a1a;
}

.boleta-firma-pie {
  display: block;
  margin-top: 6px;
  font-size: calc(12.5px * var(--fs));
  font-weight: 600;
}

.boleta-firma-rol {
  display: block;
  color: #666;
  font-size: calc(11px * var(--fs));
}

.boleta-firma-nota {
  margin: 16px 0 0;
  color: #777;
  font-size: calc(11px * var(--fs));
  font-style: italic;
}

/* ---- Impresion ----------------------------------------------------------
   Se imprime solo la boleta: nada del panel, ni barras, ni botones. */
@media print {
  body {
    overflow: visible !important;
    background: #fff !important;
  }

  /* La factura usa el mismo armazon que la boleta, asi que comparte las reglas
     de impresion; solo hay que dejarla pasar tambien a ella. */
  body > *:not([data-boleta-modal]):not([data-factura-modal]),
  .sidebar,
  .topbar,
  .boleta-toolbar,
  .client-modal-backdrop {
    display: none !important;
  }

  [data-boleta-modal],
  [data-factura-modal] {
    position: static !important;
    display: block !important;
    background: none !important;
  }

  .boleta-dialog {
    position: static !important;
    width: auto !important;
    max-height: none !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    background: #fff !important;
    transform: none !important;
  }

  .boleta-scroll {
    overflow: visible !important;
    padding: 0 !important;
    background: #fff !important;
  }

  .boleta {
    max-width: none;
    padding: 0;
    box-shadow: none;
  }

  .boleta-block,
  .boleta-conformidad {
    break-inside: avoid;
  }

  @page {
    size: letter;
    margin: 14mm;
  }
}

/* =========================================================================
   Movil
   ========================================================================= */

/* ---- Barra superior ------------------------------------------------------
   Una regla vieja de la maqueta la ponia en columna bajo 760px. Como la barra
   tiene alto fijo de 60px, su contenido crecia a 227px y se pintaba encima de
   la pagina. Se veia en todas las pestanas, no solo en Tickets. */
@media (max-width: 760px) {
  .topbar {
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
  }

  /* El subtitulo no cabe en una barra de 60px con cuatro controles al lado.
     El titulo solo alcanza para saber donde esta uno. */
  .topbar-subtitle {
    display: none;
  }

  .topbar-title {
    font-size: calc(15px * var(--fs));
  }

  /* Los chips se quedan en su punto de color: el texto vuelve en el tooltip. */
  .mk-status {
    padding: 0;
    width: 38px;
    height: 38px;
    justify-content: center;
    border-radius: 10px;
  }

  .mk-copy {
    display: none;
  }

  .icon-btn {
    width: 38px;
    height: 38px;
    flex-shrink: 0;
  }

  .panel-head {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* =========================================================================
   Tickets
   ========================================================================= */

/* Carril de color por prioridad: dice de un vistazo cual urge, sin leer. */
.ticket-work-card {
  position: relative;
  overflow: hidden;
  padding-left: 16px;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.ticket-rail {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
}

.ticket-rail-alta { background: var(--red); }
.ticket-rail-media { background: var(--amber); }
.ticket-rail-baja { background: var(--text-3); }

.ticket-work-top {
  gap: 10px;
  flex-wrap: nowrap;
}

.ticket-work-copy strong {
  font-size: calc(15.5px * var(--fs));
  font-weight: 600;
  letter-spacing: -0.1px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ticket-work-copy p {
  margin: 2px 0 0;
  color: var(--text-2);
  font-size: calc(13.5px * var(--fs));
  line-height: 1.4;
}

/* Los datos del caso como fichas: cada una con su icono, en vez de una fila de
   textos separados por espacios donde no se sabe donde termina uno. */
.ticket-work-meta {
  gap: 6px;
  margin-top: 10px;
}

.ticket-work-meta > span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 24px;
  padding: 0 9px;
  border-radius: 7px;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: calc(11.5px * var(--fs));
  white-space: nowrap;
}

.ticket-work-meta svg {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  opacity: 0.8;
}

.ticket-work-meta .ticket-visit-when {
  color: var(--accent);
  background: var(--accent-dim);
}

.ticket-status-chips {
  margin-top: 12px;
}

.ticket-status-chip {
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

@media (max-width: 760px) {
  .content {
    padding: 12px;
  }

  .tickets-page {
    gap: 10px;
  }

  /* Las tarjetas de indicadores y los filtros de estado hacian el mismo
     trabajo: filtrar por estado. Eran cuatro tarjetas de 412px de alto entre
     el techo de la pantalla y el primer ticket. Ahora son una tira de fichas
     que se desliza de lado. */
  .ticket-kpi {
    display: flex;
    gap: 8px;
    margin-bottom: 0;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .ticket-kpi::-webkit-scrollbar {
    display: none;
  }

  .ticket-kpi .metric-card {
    display: flex;
    align-items: center;
    gap: 7px;
    flex: 0 0 auto;
    height: 40px;
    min-height: 0;
    padding: 0 14px;
    border-radius: 20px;
  }

  .ticket-kpi .metric-card::before {
    display: none;
  }

  .ticket-kpi .kpi-copy {
    display: flex;
    align-items: center;
    gap: 7px;
  }

  .ticket-kpi .metric-card span {
    font-size: calc(13px * var(--fs));
    font-weight: 500;
  }

  .ticket-kpi .metric-card strong {
    font-family: var(--mono);
    font-size: calc(12px * var(--fs));
    opacity: 0.8;
  }

  /* La pista ("Pendientes", "En visita") no cabe en una ficha de 40px y no
     dice nada que el numero no diga ya. */
  .ticket-kpi .metric-card small {
    display: none;
  }

  .ticket-kpi .metric-card.active {
    border-color: var(--border-2);
    background: var(--accent-dim);
    color: var(--accent);
  }

  /* Filtros: la busqueda ocupa toda la fila y el resto se desliza debajo. */
  .ticket-filter-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px;
  }

  .ticket-filter-row .input {
    flex: 1 1 100%;
    min-width: 0;
    height: 44px;
  }

  .ticket-filter-row .select {
    flex: 1 1 100%;
    height: 44px;
  }

  .ticket-filter-row .btn {
    flex: 1 1 auto;
    height: 40px;
  }

  .ticket-work-list {
    padding: 0 12px 12px;
  }

  /* Cuatro estados en una fila de 44px: el pulgar no falla y no hay que
     abrir el detalle para mover el caso. */
  .ticket-status-chips {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
  }

  .ticket-status-chip {
    height: 40px;
    padding: 0 4px;
    border-radius: 10px;
    font-size: calc(12px * var(--fs));
    text-align: center;
  }

  /* Seis acciones no caben en una fila de telefono y apiladas ocupan media
     pantalla. Una sola fila que se desliza: nada se esconde y nada crece. */
  .ticket-work-actions {
    flex-wrap: nowrap;
    gap: 7px;
    margin: 12px -14px 0 -16px;
    padding: 0 14px 0 16px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .ticket-work-actions::-webkit-scrollbar {
    display: none;
  }

  .ticket-work-actions .btn {
    flex: 0 0 auto;
    height: 44px;
    padding: 0 15px;
    border-radius: 11px;
    font-size: calc(13px * var(--fs));
  }

  .ticket-inline-note,
  .ticket-inline-visit {
    flex-wrap: wrap;
  }

  .ticket-inline-note .input,
  .ticket-inline-visit .input {
    flex: 1 1 100%;
    height: 44px;
  }

  .ticket-inline-note .btn,
  .ticket-inline-visit .btn {
    height: 44px;
  }

  /* El detalle ocupa la pantalla entera: en un telefono, un dialogo flotante
     con margenes desperdicia el poco espacio que hay. */
  .ticket-modal-dialog {
    width: 100vw;
    max-width: none;
    height: 100vh;
    max-height: none;
    margin: 0;
    border: 0;
    border-radius: 0;
  }

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

/* ---- Ajustes finos de Tickets en movil ---------------------------------- */
@media (max-width: 760px) {
  /* Las fichas se estiraban al ancho de la pantalla y solo se veia una. */
  .ticket-kpi .metric-card {
    width: max-content;
  }

  .ticket-kpi .kpi-copy {
    width: auto;
  }

  /* "Tickets" ya esta en la barra superior: repetirlo aqui costaba 123px. Se
     queda el contador, que si dice algo, y el boton al lado. */
  .tickets-page .clients-directory-head {
    flex-direction: row;
    align-items: center;
    gap: 10px;
    padding: 12px;
  }

  .tickets-page .clients-directory-head .section-kicker,
  .tickets-page .clients-directory-head h2 {
    display: none;
  }

  .tickets-page .clients-directory-head p {
    margin: 0;
    font-size: calc(12.5px * var(--fs));
  }

  .tickets-page .clients-actions {
    flex-shrink: 0;
  }

  .tickets-page .clients-actions .btn {
    height: 40px;
  }

  /* Busqueda y categoria ocupan su propia linea; los filtros de fecha caben en
     una sola fila de fichas, no cuatro botones estirados en dos filas. */
  .ticket-filter-row .input,
  .ticket-filter-row .select {
    flex: 1 1 100%;
  }

  .ticket-filter-row .btn {
    flex: 0 0 auto;
    height: 40px;
    border-radius: 20px;
  }

  /* "En proceso" no cabia en su ficha y se salia del borde. */
  .ticket-status-chip {
    padding: 0 2px;
    font-size: calc(11px * var(--fs));
    letter-spacing: -0.2px;
  }
}

@media (max-width: 760px) {
  /* "2 tickets." se partia en dos lineas al lado del boton. */
  .tickets-page .clients-directory-head p {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* Los cuatro filtros de fecha caben en una fila si no arrastran el tamano de
     texto de un boton normal. Antes ocupaban dos filas de 216px en total. */
  .ticket-filter-row .btn {
    padding: 0 12px;
    font-size: calc(12.5px * var(--fs));
  }

  /* "En proceso" no entraba en su ficha de 60px y se salia del borde. */
  .ticket-status-chips {
    gap: 4px;
  }

  .ticket-status-chip {
    overflow: hidden;
    font-size: calc(10.5px * var(--fs));
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

@media (max-width: 760px) {
  /* Los cuatro filtros de fecha en una sola fila: con el padding de un boton
     normal, "Todos" caia solo a una cuarta linea. */
  .ticket-filter-row {
    gap: 6px;
  }

  .ticket-filter-row .btn {
    padding: 0 10px;
  }
}

@media (max-width: 760px) {
  /* El dialogo heredaba el margen del contenedor y dejaba 16px muertos a los
     lados. En un telefono ese espacio hace falta. */
  .ticket-modal {
    padding: 0;
  }
}

/* =========================================================================
   Tickets: los dos dialogos
   ========================================================================= */

/* El detalle tiene dos paneles y se aprovecha el ancho; el alta es una sola
   columna de campos y a 1080px los inputs quedaban de 730px de largo. */
.ticket-modal-dialog.is-new-ticket {
  width: min(660px, calc(100vw - 24px));
}

/* El bloque de texto del encabezado se iba a la derecha porque no ocupaba el
   ancho sobrante. Ahora avatar y texto a la izquierda, accion a la derecha. */
.ticket-modal-dialog .ficha-hero {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-right: 48px;
  text-align: left;
}

.ticket-modal-dialog .ficha-hero > div {
  flex: 1;
  min-width: 0;
}

.ticket-modal-dialog .ficha-hero h2 {
  margin: 0;
  font-size: calc(18px * var(--fs));
  letter-spacing: -0.3px;
}

.ticket-modal-dialog .ficha-hero p {
  margin: 3px 0 0;
  color: var(--text-2);
  font-size: calc(12.5px * var(--fs));
  line-height: 1.5;
}

.ticket-modal-dialog .ficha-hero .btn {
  flex-shrink: 0;
}

/* Panel de la visita: etiquetas arriba, campos parejos y los botones al final
   de la fila, sin apretarse contra el select. */
.ticket-visit-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  align-items: end;
  gap: 12px;
  margin: 14px 0;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
}

.ticket-visit-panel .field {
  margin: 0;
}

.ticket-visit-panel-actions {
  display: flex;
  gap: 8px;
}

.ticket-work-panel {
  display: flex;
  flex-direction: column;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
}

.ticket-panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.ticket-panel-head h3 {
  margin: 0;
  font-size: calc(13px * var(--fs));
  font-weight: 600;
  letter-spacing: -0.1px;
}

.ticket-panel-head span {
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(11.5px * var(--fs));
}

/* Las dos cajas de "todavia no hay nada" median distinto: una tomaba el ancho
   de una celda de fotos y la otra el del panel. */
.ticket-work-panel .empty,
.ticket-photos .empty,
.ticket-notes .empty {
  grid-column: 1 / -1;
  width: 100%;
  margin: 0;
  text-align: center;
}

.ticket-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-bottom: 12px;
  padding: 16px 14px;
  border: 1px dashed var(--border-2);
  border-radius: 11px;
  text-align: center;
}

.ticket-dropzone strong {
  color: var(--text-1);
  font-size: calc(13px * var(--fs));
}

.ticket-dropzone p {
  margin: 0;
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
}

.ticket-dropzone-actions {
  display: flex;
  gap: 8px;
  margin-top: 6px;
}

.ticket-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
}

.ticket-note-composer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}

.ticket-notes {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* El triangulo nativo del <details> desentona con todo lo demas. */
.ticket-case-details {
  margin-top: 4px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
  overflow: hidden;
}

.ticket-case-details > summary {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 13px 14px;
  color: var(--text-2);
  font-size: calc(13px * var(--fs));
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.ticket-case-details > summary::-webkit-details-marker {
  display: none;
}

.ticket-case-details > summary::before {
  content: "";
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--dur) var(--ease-soft);
}

.ticket-case-details[open] > summary::before {
  transform: rotate(45deg);
}

.ticket-case-details > summary:hover {
  color: var(--text-1);
  background: var(--surface-3);
}

.ticket-case-details .form-grid {
  padding: 0 14px 14px;
}

/* Las acciones del alta, en una barra al pie en vez de un boton suelto
   pegado al borde. */
.ticket-modal-dialog .ficha-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

@media (max-width: 900px) {
  .ticket-visit-panel {
    grid-template-columns: minmax(0, 1fr);
  }

  .ticket-visit-panel-actions {
    flex-wrap: wrap;
  }

  .ticket-visit-panel-actions .btn {
    flex: 1 1 auto;
  }
}

@media (max-width: 760px) {
  .ticket-modal-dialog.is-new-ticket {
    width: 100vw;
  }

  /* Una regla general apila .ficha-hero en columna bajo 760px. Con el
     align-items: center del dialogo eso dejaba avatar, titulo y boton
     centrados y apilados: 300px de alto para tres lineas de texto. */
  .ticket-modal-dialog .ficha-hero {
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    padding-right: 44px;
  }

  .ticket-modal-dialog .ficha-hero .btn {
    width: 100%;
  }

  .ticket-modal-dialog .ficha-hero h2 {
    font-size: calc(16.5px * var(--fs));
  }

  /* En el telefono todo el dialogo es de una columna. */
  .ticket-detail-grid {
    gap: 12px;
  }

  .ticket-modal-dialog .input,
  .ticket-modal-dialog .select {
    height: 44px;
  }

  .ticket-modal-dialog textarea.input {
    height: auto;
    min-height: 88px;
  }

  .ticket-modal-dialog .btn {
    height: 44px;
  }

  .ticket-modal-dialog .btn-small {
    height: 40px;
  }

  .ticket-status-chips.big {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
  }

  .ticket-status-chips.big .ticket-status-chip {
    height: 44px;
    font-size: calc(11px * var(--fs));
  }

  .ticket-photos {
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  }

  .ticket-modal-dialog .ficha-actions {
    position: sticky;
    bottom: 0;
    margin: 16px -14px -14px;
    padding: 12px 14px;
    background: var(--surface);
  }

  .ticket-modal-dialog .ficha-actions .btn {
    flex: 1;
  }
}

/* =========================================================================
   Configuracion
   ========================================================================= */
.config-page {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.config-grid {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.config-logo-panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

/* Fondo claro a proposito: el logo se va a imprimir sobre papel blanco, asi
   que hay que verlo como se vera, no sobre el panel oscuro. */
.config-logo {
  display: grid;
  place-items: center;
  width: 100%;
  max-width: 320px;
  min-height: 108px;
  padding: 14px;
  border: 1px dashed var(--border-2);
  border-radius: 12px;
  background: #fff;
}

.config-logo img {
  max-width: 100%;
  max-height: 88px;
  object-fit: contain;
}

.config-logo-empty {
  color: #8a8a8a;
  font-size: calc(12.5px * var(--fs));
}

.config-logo-actions {
  display: flex;
  gap: 8px;
}

.config-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  padding-top: 4px;
}

.config-saved {
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

/* ---- La marca en la boleta impresa ---- */
.boleta-marca {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  min-width: 0;
}

.boleta-logo {
  max-width: 132px;
  max-height: 62px;
  flex-shrink: 0;
  object-fit: contain;
}

.boleta-razon {
  margin: 2px 0 0;
  color: #444;
  font-size: calc(12px * var(--fs));
}

.boleta-sin-datos {
  color: #b3261e;
  font-style: italic;
}

h1.boleta-sin-datos {
  font-size: calc(15px * var(--fs));
  font-weight: 600;
}

@media (max-width: 760px) {
  .config-actions {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .config-actions .btn {
    height: 44px;
  }

  .config-saved {
    text-align: center;
  }
}

/* Los avisos de exito se desvanecen a los 4 segundos en vez de quedarse
   colgados hasta la proxima accion. */
.message.visible {
  animation: mensajeEntra 200ms var(--ease) backwards;
}

.message.is-leaving {
  opacity: 0;
  transition: opacity 200ms var(--ease);
}

@keyframes mensajeEntra {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}

/* La fila de filtros quedaba pegada a la primera tarjeta, sin un pixel de aire,
   y ademas desalineada: el panel ya pone 18px de padding y la lista sumaba
   otros 16px propios, asi que las tarjetas iban 16px mas adentro que el
   buscador. Ahora la lista hereda el padding del panel y comparten borde. */
.tickets-page .ticket-filter-row {
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

.tickets-page .ticket-work-list {
  padding: 0;
}

.tickets-page .clients-table-wrap {
  padding: 0;
}

/* =========================================================================
   Tickets: el estado como control principal, y las fotos a la vista
   ========================================================================= */

.ticket-work-card:hover {
  border-color: var(--border-2);
  transform: translateY(-2px);
  box-shadow: 0 14px 30px -20px rgba(0, 0, 0, 0.9);
}

@keyframes ticketIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

.ticket-work-list > .ticket-work-card {
  animation: ticketIn 380ms var(--ease) backwards;
}

.ticket-work-list > .ticket-work-card:nth-child(2) { animation-delay: 60ms; }
.ticket-work-list > .ticket-work-card:nth-child(3) { animation-delay: 120ms; }
.ticket-work-list > .ticket-work-card:nth-child(4) { animation-delay: 180ms; }

/* El cuerpo de la tarjeta: el estado a la izquierda, las fotos a la derecha. */
.ticket-card-body {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 12px;
}

/* ---- Estado ----
   Un solo indicador que se desliza al estado elegido y se tine de su color,
   en vez de cuatro fichas encendiendose y apagandose. */
.ticket-seg {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  width: 344px;
  max-width: 100%;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--panel-2, #0a1728);
}

.ticket-seg-ind {
  position: absolute;
  left: 3px;
  top: 3px;
  bottom: 3px;
  width: calc(25% - 1.5px);
  border-radius: 8px;
  background: rgba(100, 116, 139, 0.75);
  pointer-events: none;
  transition: transform 320ms var(--ease-soft),
              background 240ms var(--ease),
              box-shadow 240ms var(--ease);
}

.ticket-seg-ind.ticket-status-abierto {
  background: rgba(245, 158, 11, 0.92);
  box-shadow: 0 4px 12px -4px rgba(245, 158, 11, 0.65);
}

.ticket-seg-ind.ticket-status-proceso {
  background: rgba(59, 130, 246, 0.9);
  box-shadow: 0 4px 12px -4px rgba(59, 130, 246, 0.7);
}

.ticket-seg-ind.ticket-status-resuelto {
  background: rgba(17, 201, 143, 0.9);
  box-shadow: 0 4px 12px -4px rgba(17, 201, 143, 0.6);
}

.ticket-seg-ind.ticket-status-cerrado {
  background: rgba(100, 116, 139, 0.75);
  box-shadow: 0 4px 12px -4px rgba(100, 116, 139, 0.5);
}

.ticket-seg-btn {
  position: relative;
  z-index: 1;
  height: 36px;
  padding: 0 4px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  font-size: calc(12.5px * var(--fs));
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: color 200ms var(--ease);
}

.ticket-seg-btn:hover:not(:disabled):not(.on) {
  color: var(--text-1);
}

.ticket-seg-btn.on {
  color: #fff;
  font-weight: 600;
}

.ticket-seg-btn:disabled {
  cursor: default;
}

.ticket-seg.big {
  width: 100%;
  margin: 4px 0 16px;
}

.ticket-seg.big .ticket-seg-btn {
  height: 42px;
  font-size: calc(13px * var(--fs));
}

/* ---- Miniaturas ----
   Antes las fotos solo existian como el texto "1 foto". */
.ticket-thumbs {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
}

.ticket-thumb {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  padding: 0;
  border: 0;
  border-radius: 9px;
  background-color: var(--surface-2);
  background-position: center;
  background-size: cover;
  box-shadow: inset 0 0 0 1px var(--border);
  cursor: pointer;
  transition: transform 240ms var(--ease-soft), box-shadow 240ms var(--ease);
}

.ticket-thumb.is-loaded {
  box-shadow: inset 0 0 0 1px var(--border-2);
}

/* Mientras baja la imagen la ficha late suave, para que no parezca un hueco. */
@keyframes thumbLatido {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 0.85; }
}

.ticket-thumb[data-thumb-url]:not(.is-loaded) {
  animation: thumbLatido 1.4s var(--ease) infinite;
}

.ticket-thumb:hover {
  transform: translateY(-2px) scale(1.04);
  box-shadow: 0 8px 18px -10px rgba(0, 0, 0, 0.9), inset 0 0 0 1px var(--border-2);
}

.ticket-thumb-more {
  display: grid;
  place-items: center;
  color: var(--text-2);
  font-family: var(--mono);
  font-size: calc(12px * var(--fs));
  cursor: default;
}

.ticket-thumb-add {
  display: grid;
  place-items: center;
  border: 1px dashed var(--border-2);
  background: transparent;
  color: var(--accent);
  box-shadow: none;
}

.ticket-thumb-add svg {
  width: 17px;
  height: 17px;
}

.ticket-thumb-add:hover {
  background: var(--accent-dim);
}

.ticket-thumbs-empty {
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
}

/* La visita se tine cuando hay una agendada: es el dato que el tecnico busca. */
.ticket-work-meta .ticket-visit-when {
  color: var(--accent);
  background: var(--accent-dim);
}

.ticket-card-count {
  margin-left: auto;
  color: var(--text-3);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
}

@media (max-width: 760px) {
  .ticket-card-body {
    flex-direction: column;
    gap: 12px;
  }

  .ticket-seg {
    width: 100%;
  }

  .ticket-seg-btn {
    height: 42px;
    font-size: calc(11px * var(--fs));
  }

  /* Las miniaturas se deslizan de lado si no caben, como las acciones. */
  .ticket-thumbs {
    flex-wrap: nowrap;
    margin: 0 -14px 0 -16px;
    padding: 0 14px 0 16px;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .ticket-thumbs::-webkit-scrollbar {
    display: none;
  }

  .ticket-thumb {
    width: 54px;
    height: 54px;
  }

  .ticket-card-count {
    display: none;
  }
}

/* =========================================================================
   Clientes en pantallas angostas
   Una tabla de ocho columnas no cabe en un telefono por mas columnas que se
   escondan: la fila media 857px dentro de una ventana de 375 y el usuario solo
   veia el final. Bajo 900px cada fila pasa a ser una tarjeta.
   ========================================================================= */
@media (max-width: 900px) {
  /* Los indicadores ocupaban 1.100px antes del directorio: una tira que se
     desliza, igual que en Tickets. */
  .clients-page > .clients-kpi {
    display: flex;
    gap: 8px;
    margin-bottom: 0;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .clients-page > .clients-kpi::-webkit-scrollbar {
    display: none;
  }

  .clients-page > .clients-kpi .metric-card {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    width: max-content;
    min-height: 0;
    padding: 0 14px;
    height: 40px;
    border-radius: 20px;
  }

  .clients-page > .clients-kpi .metric-card::before {
    display: none;
  }

  .clients-page > .clients-kpi .kpi-icon {
    display: none;
  }

  .clients-page > .clients-kpi .kpi-copy {
    display: flex;
    align-items: center;
    gap: 7px;
    width: auto;
  }

  .clients-page > .clients-kpi .metric-card span {
    font-size: calc(13px * var(--fs));
    font-weight: 500;
  }

  .clients-page > .clients-kpi .metric-card strong {
    font-family: var(--mono);
    font-size: calc(12px * var(--fs));
    opacity: 0.8;
  }

  .clients-page > .clients-kpi .metric-card small {
    display: none;
  }

  /* La cabecera de la tabla no tiene sentido cuando ya no hay tabla. */
  .clients-page:not(.billing-page) .client-table-header {
    display: none;
  }

  .client-table-shell,
  .client-list {
    overflow: visible;
  }

  .client-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px 0;
  }

  /* Nombre arriba a la izquierda, estado arriba a la derecha, los datos en dos
     columnas debajo y las acciones al pie. */
  .clients-page:not(.billing-page) .client-table-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 10px 12px;
    align-items: start;
    width: auto;
    min-width: 0;
    min-height: 0;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
  }

  .clients-page:not(.billing-page) .client-table-header {
    min-width: 0;
  }

  .clients-page:not(.billing-page) .client-table-row .client-person {
    grid-area: 1 / 1 / 2 / 2;
    min-width: 0;
  }

  .clients-page:not(.billing-page) .client-table-row .client-status-cell {
    grid-area: 1 / 2 / 2 / 3;
    justify-self: end;
  }

  .clients-page:not(.billing-page) .client-table-row .client-actions-cell {
    grid-column: 1 / -1;
    display: flex;
    gap: 8px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
  }

  .clients-page:not(.billing-page) .client-table-row .client-row-action {
    flex: 1;
    height: 40px;
  }

  /* Cada dato dice que es: la cabecera ya no esta para explicarlo. */
  .clients-page:not(.billing-page) .client-table-cell:not(.client-status-cell) {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
  }

  .clients-page:not(.billing-page) .client-table-cell[data-label]::before {
    content: attr(data-label);
    color: var(--text-3);
    font-size: calc(10px * var(--fs));
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

  .client-table-cell strong,
  .client-table-cell code {
    font-size: calc(12.5px * var(--fs));
  }

  .client-plan-cell small {
    color: var(--text-3);
    font-size: calc(11px * var(--fs));
  }

  .client-person-copy strong {
    font-size: calc(14.5px * var(--fs));
  }

  .client-list-footer {
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
    text-align: center;
  }

  .client-pagination {
    justify-content: center;
  }

  .client-page-button {
    min-width: 40px;
    height: 40px;
  }

  /* Buscador y filtros a lo ancho, con altura de dedo. */
  .client-directory-toolbar {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  .clients-search .input,
  .clients-filter-toggle {
    height: 44px;
  }

  .clients-directory-head {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }

  .clients-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  .clients-actions .btn {
    flex: 1 1 auto;
    height: 40px;
  }
}

/* Entre 900 y 1100 la tabla sigue siendo tabla, pero sin la IP ni la zona:
   son los dos datos que menos se miran de un vistazo. */
@media (max-width: 1100px) and (min-width: 901px) {
  /* La tabla cabe sin scroll lateral si suelta la zona y la IP: son los dos
     datos que menos se miran de un vistazo, y siguen en la ficha. */
  .clients-page:not(.billing-page) .client-table-header,
  .clients-page:not(.billing-page) .client-table-row {
    /* Cinco pistas para las cinco celdas que quedan visibles: si sobran o
       faltan, la de acciones cae a una segunda linea. */
    grid-template-columns:
      minmax(0, 1.7fr) minmax(0, 0.9fr) minmax(0, 0.7fr)
      var(--col-estado) var(--col-acciones);
    gap: 8px;
    min-width: 0;
  }

  .clients-page:not(.billing-page) .client-table-header > span:nth-child(2),
  .clients-page:not(.billing-page) .client-table-row > :nth-child(2),
  .clients-page:not(.billing-page) .client-table-header > span:nth-child(4),
  .clients-page:not(.billing-page) .client-table-row > :nth-child(4) {
    display: none;
  }
}

@media (max-width: 900px) {
  /* La lista tenia alto fijo con scroll propio: pensada para una tabla, en
     tarjetas comprimia cada fila a 30px y se montaban unas sobre otras. En el
     telefono la lista crece y quien hace scroll es la pagina. */
  .clients-page:not(.billing-page) .client-list {
    height: auto;
    max-height: none;
    flex: none;
    overflow: visible;
  }

  .clients-page:not(.billing-page) .client-table-shell {
    height: auto;
    max-height: none;
    overflow: visible;
  }

  .clients-page:not(.billing-page) .client-table-row {
    flex-shrink: 0;
  }

  /* Reglas viejas escondian columnas sueltas cuando esto era una tabla. En
     tarjetas cada dato tiene que verse. */
  .clients-page:not(.billing-page) .client-table-row > :nth-child(2),
  .clients-page:not(.billing-page) .client-table-row > :nth-child(3),
  .clients-page:not(.billing-page) .client-table-row > :nth-child(4) {
    display: flex;
  }
}

/* ---- Tickets en vivo ---------------------------------------------------- */
.ticket-live-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 8px;
  padding: 4px 10px 4px 8px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: var(--surface-2);
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.ticket-live-chip.is-on {
  border-color: color-mix(in srgb, var(--green) 40%, transparent);
  color: var(--green);
}

.ticket-live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-3);
}

/* Late solo cuando esta conectado: un punto fijo no dice si hay linea. */
@keyframes livePulso {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--green) 55%, transparent); }
  70% { box-shadow: 0 0 0 5px transparent; }
}

.ticket-live-chip.is-on .ticket-live-dot {
  background: var(--green);
  animation: livePulso 2s var(--ease) infinite;
}

/* Destello cuando el cambio llego de otra sesion: sin esto la tarjeta cambia
   sola y uno no sabe si lo hizo una persona o el sistema. */
@keyframes liveDestello {
  0% { box-shadow: 0 0 0 0 var(--accent-glow); border-color: var(--accent); }
  100% { box-shadow: 0 0 0 14px transparent; border-color: var(--border); }
}

.ticket-work-card.is-live-change {
  animation: liveDestello 1.6s var(--ease) both;
}

.ticket-live-tag {
  position: absolute;
  right: 12px;
  bottom: 10px;
  padding: 3px 9px;
  border-radius: 20px;
  background: var(--accent-dim);
  color: var(--accent);
  font-size: calc(10.5px * var(--fs));
  font-weight: 600;
  animation: paneIn 260ms var(--ease) backwards;
}

@media (max-width: 760px) {
  .ticket-live-tag {
    position: static;
    display: inline-block;
    margin-top: 10px;
  }
}

/* =========================================================================
   Agenda de trabajo
   Antes el modulo tenia tres filtros compitiendo (fichas de estado, fila de
   fechas y selector Lista/Agenda). Ahora manda una sola seleccion en el carril:
   un dia del calendario, o una bandeja. El calendario nunca se va de pantalla.
   ========================================================================= */
.agenda-shell {
  display: grid;
  grid-template-columns: 268px minmax(0, 1fr);
  align-items: start;
  gap: 16px;
}

.agenda-rail {
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: sticky;
  top: 76px;
}

/* ---- Calendario ---- */
.agenda-cal {
  padding: 14px;
}

.cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-bottom: 10px;
}

.cal-head strong {
  flex: 1;
  text-align: center;
  font-size: calc(13.5px * var(--fs));
  font-weight: 700;
  letter-spacing: -0.2px;
}

.cal-nav {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  font-size: calc(16px * var(--fs));
  line-height: 1;
}

.cal-week,
.cal-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.cal-week {
  margin-bottom: 4px;
}

.cal-week span {
  color: var(--text-3);
  font-size: calc(10.5px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.6px;
  text-align: center;
}

.cal-week span.is-fin {
  color: var(--text-3);
  opacity: 0.55;
}

.cal-day {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: 34px;
  padding: 4px 0 6px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--text-1);
  font-family: var(--font);
  font-size: calc(12.5px * var(--fs));
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.cal-day:hover {
  background: var(--surface-3);
}

.cal-day.is-out {
  color: var(--text-3);
  opacity: 0.5;
}

/* Hoy siempre se distingue, incluso cuando se esta mirando otro dia. */
.cal-day.is-today {
  border-color: var(--border-strong, var(--border));
  font-weight: 700;
}

.cal-day.is-sel {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 700;
}

.cal-day.is-sel.is-out {
  opacity: 1;
}

/* El punto es el dato: hay visita ese dia. Se tine cuando algo es urgente y se
   apaga a verde cuando ya no queda nada pendiente. */
.cal-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

.cal-dot.is-urgent { background: var(--red); }
.cal-dot.is-pending { background: var(--accent); }
.cal-dot.is-done { background: var(--green); }

.cal-day.is-sel .cal-dot {
  background: #fff;
}

.cal-hoy {
  width: 100%;
  margin-top: 10px;
  padding: 7px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  font-size: calc(12px * var(--fs));
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.cal-hoy:hover {
  background: var(--surface-3);
  color: var(--text-1);
}

/* ---- Bandejas ---- */
.agenda-bandejas {
  padding: 14px;
}

.agenda-bandejas .section-kicker {
  display: block;
  margin-bottom: 8px;
}

.agenda-bandejas > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.bandeja {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  font-size: calc(13px * var(--fs));
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.bandeja:hover {
  background: var(--surface-3);
  color: var(--text-1);
}

.bandeja.is-sel {
  background: var(--accent-dim);
  color: var(--accent);
}

.bandeja-count {
  min-width: 22px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: calc(11.5px * var(--fs));
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.bandeja.is-sel .bandeja-count {
  background: var(--accent);
  color: #fff;
}

/* Lo que no tiene fecha no aparece en ningun dia del calendario: es lo unico
   que se puede perder de vista, asi que se avisa. */
.bandeja.is-aviso .bandeja-count {
  background: var(--amber-dim);
  color: var(--amber);
}

.bandeja.is-aviso.is-sel .bandeja-count {
  background: var(--amber);
  color: var(--surface);
}

/* ---- Panel principal ---- */
.agenda-main {
  padding: 18px;
  min-width: 0;
}

.agenda-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

.agenda-head-copy {
  min-width: 0;
}

.agenda-head-kicker {
  display: flex;
  align-items: center;
  gap: 8px;
}

.agenda-head-copy h2 {
  margin: 3px 0 2px;
  font-size: calc(20px * var(--fs));
  letter-spacing: -0.4px;
}

.agenda-head-copy p {
  margin: 0;
  color: var(--text-3);
  font-size: calc(12.5px * var(--fs));
}

.agenda-head-tools {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.agenda-daynav {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--surface-2);
}

.agenda-daynav .icon-btn {
  width: 28px;
  height: 28px;
  font-size: calc(16px * var(--fs));
  line-height: 1;
}

/* Saltar de dia solo tiene sentido mirando un dia. */
.tickets-page:not([data-focus="dia"]) .agenda-daynav {
  display: none;
}

.agenda-search {
  width: 220px;
}

.agenda-cat {
  width: 186px;
}

/* Un foco, una vista: el dia se pinta como tablero y las bandejas como lista. */
.tickets-page[data-focus="dia"] .clients-table-wrap,
.tickets-page:not([data-focus="dia"]) .agenda-board {
  display: none;
}

.agenda-board {
  display: grid;
  grid-auto-flow: column;
  /* La agenda ahora dibuja la tarjeta completa, con estados y acciones:
     con 232px quedaba estrangulada. */
  grid-auto-columns: minmax(360px, 1fr);
  gap: 12px;
  overflow-x: auto;
  padding-bottom: 6px;
}

/* La descripcion que escribio quien abrio el caso. Antes solo se veia entrando
   al detalle, y es justo lo que hace falta antes de salir a la visita. */
.ticket-work-detalle {
  margin: 6px 0 0;
  padding: 8px 10px;
  border-left: 2px solid var(--border-2, var(--accent));
  border-radius: 0 6px 6px 0;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: calc(12.5px * var(--fs));
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.agenda-col {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.agenda-col.is-target {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.agenda-col.is-empty {
  opacity: 0.72;
}

.agenda-col-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}

.agenda-col-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-size: calc(13px * var(--fs));
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agenda-col-count {
  flex-shrink: 0;
  min-width: 22px;
  padding: 2px 7px;
  border-radius: 11px;
  background: var(--surface-3);
  color: var(--text-2);
  font-family: var(--mono);
  font-size: calc(11px * var(--fs));
  text-align: center;
}

.agenda-col-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  min-height: 90px;
}



/* El carril de prioridad, igual que en las tarjetas de la lista. */




























/* El aviso del viaje evitable: solo sale cuando de verdad cambia de zona. */
.agenda-salto {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 2px 0;
  padding: 5px 9px;
  border-radius: 7px;
  background: var(--amber-dim);
  color: var(--amber);
  font-size: calc(10.5px * var(--fs));
  line-height: 1.35;
}

.agenda-salto svg {
  width: 11px;
  height: 11px;
  flex-shrink: 0;
}

.agenda-vacia {
  margin: 0;
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
  text-align: center;
}

/* En pantallas medianas el carril se sigue leyendo, pero mas angosto. */
@media (max-width: 1180px) {
  .agenda-shell {
    grid-template-columns: 236px minmax(0, 1fr);
  }

  .agenda-search {
    width: 170px;
  }

  .agenda-cat {
    width: 172px;
  }
}

@media (max-width: 900px) {
  /* Ya no caben dos columnas: el carril pasa arriba, en una sola fila, y el
     calendario sigue visible porque es el indice del modulo. */
  .agenda-shell {
    grid-template-columns: minmax(0, 1fr);
  }

  .agenda-rail {
    position: static;
    flex-direction: row;
    align-items: stretch;
  }

  .agenda-cal {
    flex: 1 1 300px;
  }

  .agenda-bandejas {
    flex: 1 1 220px;
  }

  .agenda-bandejas > div {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px 8px;
  }
}

@media (max-width: 760px) {
  /* En el telefono todo se apila. El calendario mantiene el ancho completo:
     es lo que se toca primero. */
  .agenda-rail {
    flex-direction: column;
  }

  /* Apilados ya no reparten ancho: si siguen creciendo, el panel de bandejas
     se estira y deja un hueco muerto debajo de los contadores. */
  .agenda-cal,
  .agenda-bandejas {
    flex: 0 0 auto;
  }

  /* Compacto para que la agenda no quede debajo del pliegue. */
  .agenda-cal {
    padding: 12px;
  }

  .cal-hoy {
    margin-top: 6px;
    padding: 6px;
  }

  .agenda-main {
    padding: 14px;
  }

  .agenda-head {
    gap: 12px;
  }

  .agenda-head-tools {
    width: 100%;
  }

  /* Dos lineas en vez de cuatro: cambiar de dia y crear arriba, buscar y
     filtrar abajo. Cada fila de controles que se apila empuja las visitas
     medio telefono hacia abajo. */
  .agenda-daynav {
    flex: 0 0 auto;
  }

  .agenda-head-tools .btn-primary {
    flex: 1 1 140px;
    min-width: 0;
  }

  .agenda-search {
    flex: 1 1 58%;
    width: auto;
    min-width: 0;
  }

  .agenda-cat {
    flex: 1 1 34%;
    width: auto;
    min-width: 0;
  }

  /* Las bandejas pasan a una fila de chips que se desliza: en vertical ocupaban
     150px antes de la primera visita. */
  .agenda-bandejas {
    padding: 10px 12px;
  }

  .agenda-bandejas .section-kicker {
    display: none;
  }

  .agenda-bandejas > div {
    display: flex;
    flex-direction: row;
    gap: 6px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .agenda-bandejas > div::-webkit-scrollbar {
    display: none;
  }

  .bandeja {
    flex: 0 0 auto;
    gap: 6px;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: calc(12.5px * var(--fs));
  }

  .bandeja.is-sel {
    border-color: var(--accent);
  }

  .bandeja-count {
    min-width: 0;
    padding: 0 4px;
    background: transparent;
  }

  .cal-day {
    min-height: 36px;
    font-size: calc(13.5px * var(--fs));
  }

  /* Las columnas del tablero se apilan: una al lado de otra no se leen. */
  .agenda-board {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    overflow-x: visible;
  }
}

@media (max-width: 460px) {
  /* En pantallas muy angostas la categoria se queda sin sitio junto al buscador
     y se corta el texto: mejor una linea propia. */
  .agenda-cat {
    flex: 1 1 100%;
  }
}

/* =========================================================================
   Usuarios y permisos
   El rol solo pone los valores de fabrica. Lo que se ve aqui es una lista de
   interruptores por usuario, con marca en los que se apartaron del rol.
   ========================================================================= */
.usuarios-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.usuarios-lista {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.usuario-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
  overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease);
}

.usuario-card.is-open {
  border-color: var(--accent);
}

.usuario-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 12px 14px;
}

.usuario-copy {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  flex: 1 1 200px;
}

.usuario-copy strong {
  font-size: calc(14px * var(--fs));
  letter-spacing: -0.2px;
}

.usuario-copy span {
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

.usuario-yo {
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--accent-dim);
  color: var(--accent);
  font-size: calc(10.5px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}

.usuario-badges,
.usuario-acciones {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.badge-ok { background: var(--green-dim); color: var(--green); }
.badge-off { background: var(--surface-3); color: var(--text-3); }
.badge-custom { background: var(--amber-dim); color: var(--amber); }

/* ---- Panel de permisos ---- */
.permisos-panel {
  padding: 14px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}

.permisos-head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.permisos-rol {
  flex: 0 0 180px;
}

.permisos-nota {
  flex: 1 1 260px;
  margin: 0;
  align-self: center;
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
  line-height: 1.5;
}

.permisos-grupos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 14px;
}

.permiso-grupo h4 {
  margin: 0 0 6px;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.permiso-fila {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 7px 8px;
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.permiso-fila:hover {
  background: var(--surface-2);
}

/* Se ve de un vistazo que este usuario se aparta de su rol justo aqui. */
.permiso-fila.is-custom {
  border-color: var(--amber-dim);
  background: var(--surface-2);
}

.permiso-fila input {
  margin-top: 2px;
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.permiso-copy {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.permiso-copy strong {
  font-size: calc(12.5px * var(--fs));
  font-weight: 600;
}

.permiso-copy small {
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
  line-height: 1.4;
}

.permiso-marca {
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 999px;
  background: var(--amber-dim);
  color: var(--amber);
  font-size: calc(9.5px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}

.permisos-pie {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.permisos-resumen {
  margin-right: auto;
  color: var(--text-3);
  font-size: calc(12px * var(--fs));
}

@media (max-width: 760px) {
  .usuario-top {
    align-items: stretch;
  }

  .usuario-acciones {
    width: 100%;
  }

  .usuario-acciones .btn {
    flex: 1 1 auto;
  }

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

  .permisos-pie .btn {
    flex: 1 1 auto;
  }
}

/* =========================================================================
   Red: barra de zonas
   El esquema son dos troncales que no se tocan. Entrar por zona evita el
   lienzo entero a 199 equipos, donde el zoom baja al 7% y no se lee nada.
   ========================================================================= */
/* En vertical y pegada a la izquierda: en horizontal se comia la franja de
   arriba del lienzo, que es justo donde caen los primeros equipos. */
.net-troncales {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  width: 178px;
  max-height: calc(100% - 24px);
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: color-mix(in srgb, var(--surface-2) 92%, transparent);
  backdrop-filter: blur(6px);
}

.net-troncales-label {
  padding: 0 4px 2px;
  color: var(--text-3);
  font-size: calc(10.5px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.net-troncal {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 12px;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.net-troncal strong {
  font-size: calc(12.5px * var(--fs));
  font-weight: 600;
  letter-spacing: -0.1px;
}

.net-troncal em {
  color: var(--text-3);
  font-size: calc(10.5px * var(--fs));
  font-style: normal;
}

.net-troncal:hover {
  background: var(--surface-3);
  color: var(--text-1);
}

.net-troncal.selected {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}

.net-troncal.selected em {
  color: color-mix(in srgb, var(--accent) 75%, var(--text-2));
}

.net-troncal.ghost {
  align-self: stretch;
  justify-content: center;
}

/* De este equipo cuelgan clientes: en el Excel era la palabra "Clientes" al
   final de la rama, que antes se importaba como 73 nodos falsos. El nodo es
   SVG, asi que el distintivo es un icono, no una etiqueta HTML. */
.net-node-clientes {
  color: var(--green);
  opacity: 0.9;
}

@media (max-width: 760px) {
  /* En el telefono no sobra ancho para una columna: vuelve a ser una tira que
     se desliza, encima del lienzo. */
  .net-troncales {
    position: static;
    width: auto;
    max-width: 100%;
    max-height: none;
    margin-bottom: 8px;
    flex-direction: row;
    align-items: center;
    overflow-x: auto;
    overflow-y: visible;
    flex-wrap: nowrap;
    scrollbar-width: none;
  }


  .net-troncales::-webkit-scrollbar {
    display: none;
  }

  .net-troncal {
    flex: 0 0 auto;
  }
}

/* La barra de seccion esta centrada arriba y la de zonas ocupa esa misma
   franja: con las dos visibles se pisaban. La de seccion baja una linea. */
/* La barra flotante del centro se retira: tapaba la franja donde caen los
   primeros equipos, y lo que decia esta ahora en el panel de zonas. */
.net-section-bar {
  display: none !important;
}

@media (max-width: 760px) {
  .net-troncales:not([hidden]) ~ .net-section-bar {
    top: 12px;
  }
}

/* =========================================================================
   Mapa geografico
   Red dice quien cuelga de quien; el mapa dice donde esta. Como las
   coordenadas se llenan poco a poco, lo primero que se ve es cuanto falta.
   ========================================================================= */
.mapa-shell {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  align-items: stretch;
  gap: 16px;
  height: calc(100vh - 150px);
  min-height: 460px;
}

.mapa-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  overflow-y: auto;
}

.mapa-resumen {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.mapa-dato {
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}

.mapa-dato strong {
  display: block;
  font-size: calc(20px * var(--fs));
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

.mapa-dato strong span {
  color: var(--text-3);
  font-size: calc(13px * var(--fs));
  font-weight: 500;
}

.mapa-dato small {
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  line-height: 1.3;
}

.mapa-aviso {
  margin: 0;
  padding: 9px 11px;
  border: 1px solid var(--amber-dim);
  border-radius: 10px;
  background: color-mix(in srgb, var(--amber-dim) 45%, transparent);
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
  line-height: 1.5;
}

.mapa-lista h4 {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 6px;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.mapa-lista h4 em {
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: calc(10.5px * var(--fs));
  font-style: normal;
}

.mapa-pendiente {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.mapa-pendiente:hover {
  background: var(--surface-3);
}

.mapa-pendiente.is-activo {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.mapa-pendiente-punto {
  width: 9px;
  height: 9px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--pin, var(--accent));
}

.mapa-pendiente-copy {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.mapa-pendiente-copy strong {
  font-size: calc(12.5px * var(--fs));
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mapa-pendiente-copy small {
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mapa-mas {
  margin: 4px 0 0;
  color: var(--text-3);
  font-size: calc(11.5px * var(--fs));
}

.mapa-lienzo-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  min-width: 0;
}

.mapa-barra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.mapa-capas {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.mapa-capas label {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-2);
  font-size: calc(12.5px * var(--fs));
  cursor: pointer;
}

.mapa-capas input {
  accent-color: var(--accent);
  cursor: pointer;
}

.mapa-modo {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: var(--accent-dim);
  color: var(--accent);
  font-size: calc(12.5px * var(--fs));
}

.mapa-lienzo {
  flex: 1;
  min-height: 320px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  /* El mapa es de otra libreria y trae su propio fondo claro: sin esto el
     hueco entre teselas parpadea en blanco sobre el tema oscuro. */
  background: var(--surface-2);
}

/* Mientras se coloca un punto, el cursor dice que el clic va al mapa. */
.mapa-page.is-ubicando .mapa-lienzo {
  cursor: crosshair;
}

.mapa-pin {
  display: block;
  width: 100%;
  height: 100%;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--pin, #3b82f6);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.45);
}

.mapa-pin-sitio.is-torre {
  border-width: 3px;
}

/* Mas grande y con doble borde: sobre el verde del mapa un punto de 12 px
   sin contorno oscuro se perdia. */
.mapa-pin-cliente {
  border-width: 2.5px;
  box-shadow: 0 0 0 1.5px rgba(15, 23, 42, 0.55), 0 2px 6px rgba(0, 0, 0, 0.45);
}

/* El nombre junto al punto. Solo de cerca: la clase la pone el zoom. */
.mapa-etiqueta {
  display: none;
  padding: 2px 7px;
  border: 0;
  border-radius: 6px;
  background: rgba(15, 23, 42, 0.86);
  color: #fff;
  font-size: 11.5px;
  font-weight: 600;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}

.mapa-etiqueta::before { display: none; }
.mapa-cerca .mapa-etiqueta { display: block; }

.mapa-pop strong {
  display: block;
  font-size: calc(13.5px * var(--fs));
}

.mapa-pop p {
  margin: 3px 0 0;
  font-size: calc(12px * var(--fs));
}

.mapa-pop-estado {
  display: inline-block;
  margin-top: 3px;
  padding: 1px 7px;
  border-radius: 999px;
  background: #e2e8f0;
  color: #334155;
  font-size: calc(10.5px * var(--fs));
  font-weight: 700;
  text-transform: capitalize;
}

.mapa-pop-sug {
  margin-top: 6px !important;
  padding: 6px 8px;
  border-radius: 8px;
  background: #f1f5f9;
  color: #334155;
  line-height: 1.4;
}

.mapa-pop-sug small {
  display: block;
  color: #64748b;
  font-size: calc(10.5px * var(--fs));
}

.mapa-pop-acciones {
  display: flex;
  gap: 6px;
  margin-top: 9px;
}

@media (max-width: 900px) {
  .mapa-shell {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
  }

  .mapa-panel {
    max-height: 340px;
  }

  .mapa-lienzo {
    height: 60vh;
  }
}

/* [hidden] pone display:none, pero una clase con display:flex declarada
   despues lo gana: el aviso se quedaba en pantalla tras ubicar el punto. */
.mapa-modo[hidden] {
  display: none;
}

/* Lo que estaba en la barra flotante: que seccion se esta mirando y como
   salir de ella. Va al pie del panel de zonas. */
.net-troncal-sel {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 6px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

.net-troncal-sel-punto {
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--pin, var(--accent));
}

.net-troncal-sel-copy {
  flex: 1;
  min-width: 0;
}

.net-troncal-sel-copy strong {
  display: block;
  font-size: calc(11.5px * var(--fs));
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.net-troncal-sel-copy em {
  color: var(--text-3);
  font-size: calc(10.5px * var(--fs));
  font-style: normal;
}

.net-troncal-sel-acciones {
  display: flex;
  gap: 4px;
  width: 100%;
}

.net-troncal-sel-acciones button {
  flex: 1;
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  font-size: calc(11px * var(--fs));
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.net-troncal-sel-acciones button:hover {
  background: var(--surface-3);
  color: var(--text-1);
}

/* El modo "ubicar" acepta dos caminos: marcar en el mapa o pegar el enlace que
   comparte el telefono, que es lo que se tiene a mano en campo. */
.mapa-modo {
  flex-wrap: wrap;
}

.mapa-modo-texto {
  flex: 1 1 100%;
}

.mapa-modo-enlace {
  flex: 1 1 260px;
  min-width: 0;
  height: 32px;
  font-size: calc(12.5px * var(--fs));
}

/* Aviso bajo el campo de enlace de la ficha de Red. */
.net-ayuda {
  display: block;
  margin-top: 4px;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  line-height: 1.4;
}

.net-ayuda.is-error {
  color: var(--red);
}

/* La cabecera del panel de Red se queda solo con el aviso de guardado. */
.net-head-slim {
  justify-content: flex-end;
  margin-bottom: 8px;
  padding-bottom: 0;
  border-bottom: 0;
}

/* El campo de punto y el boton de GPS comparten linea. */
.client-punto {
  display: flex;
  align-items: center;
  gap: 8px;
}

.client-punto .input {
  flex: 1;
  min-width: 0;
}

.client-punto .btn {
  flex-shrink: 0;
}

@media (max-width: 560px) {
  .client-punto {
    flex-wrap: wrap;
  }

  .client-punto .input,
  .client-punto .btn {
    flex: 1 1 100%;
  }
}

/* "Como llegar" en la tarjeta del ticket y en la de la agenda. El punto lo
   pone el cliente en su ficha o desde el mapa; sin coordenada no aparece. */


.agenda-ir {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--accent);
  font-size: calc(11px * var(--fs));
  font-weight: 600;
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.agenda-ir:hover {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.agenda-ir svg {
  width: 12px;
  height: 12px;
}

/* =========================================================================
   Factura imprimible
   Se imprime en papel blanco, asi que va con colores propios y no con los
   del tema oscuro. Comparte el armazon del modal con la boleta.
   ========================================================================= */
.factura {
  max-width: 780px;
  margin: 0 auto;
  padding: 34px 38px;
  background: #fff;
  color: #1e293b;
  font-size: calc(13px * var(--fs));
  line-height: 1.55;
}

.factura-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding-bottom: 18px;
  border-bottom: 2px solid #1e293b;
}

.factura-marca {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.factura-logo {
  width: 64px;
  height: 64px;
  object-fit: contain;
}

.factura-marca h1 {
  margin: 0 0 2px;
  font-size: calc(19px * var(--fs));
  letter-spacing: -0.3px;
}

.factura-marca p {
  margin: 1px 0;
  color: #64748b;
  font-size: calc(11.5px * var(--fs));
}

.factura-razon {
  font-style: italic;
}

.factura-falta {
  color: #b45309 !important;
}

.factura-numero {
  flex-shrink: 0;
  text-align: right;
}

.factura-numero span {
  display: block;
  color: #64748b;
  font-size: calc(11px * var(--fs));
  text-transform: uppercase;
  letter-spacing: 0.6px;
}

.factura-numero strong {
  display: block;
  margin: 2px 0 6px;
  font-size: calc(20px * var(--fs));
  font-variant-numeric: tabular-nums;
}

.factura-estado {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: calc(10.5px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

.factura-estado.es-pagada { background: #dcfce7; color: #15803d; }
.factura-estado.es-pendiente { background: #fef3c7; color: #b45309; }
.factura-estado.es-vencida { background: #fee2e2; color: #b91c1c; }
.factura-estado.es-anulada { background: #e2e8f0; color: #475569; }

.factura-partes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px;
  margin: 22px 0;
}

.factura-partes h4 {
  margin: 0 0 6px;
  color: #64748b;
  font-size: calc(10.5px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.factura-partes strong {
  font-size: calc(14px * var(--fs));
}

.factura-partes p {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin: 2px 0;
  color: #475569;
  font-size: calc(12px * var(--fs));
}

.factura-partes p span {
  color: #94a3b8;
}

.factura-detalle {
  width: 100%;
  margin-top: 16px;
  border-collapse: collapse;
}

.factura-detalle th {
  padding: 7px 10px;
  background: #f1f5f9;
  color: #475569;
  font-size: calc(10.5px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.6px;
  text-align: left;
  text-transform: uppercase;
}

.factura-detalle td {
  padding: 10px;
  border-bottom: 1px solid #e2e8f0;
}

.factura-detalle .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.factura-pagos th {
  background: #f8fafc;
}

.factura-totales {
  margin: 18px 0 0 auto;
  width: min(300px, 100%);
}

.factura-totales p {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin: 3px 0;
  font-variant-numeric: tabular-nums;
}

.factura-totales span {
  color: #64748b;
}

.factura-saldo {
  margin-top: 8px !important;
  padding-top: 8px;
  border-top: 2px solid #1e293b;
  font-size: calc(15px * var(--fs));
  font-weight: 700;
}

.factura-notas {
  margin-top: 20px;
  padding: 10px 12px;
  border-left: 3px solid #cbd5e1;
  color: #475569;
  font-size: calc(12px * var(--fs));
  white-space: pre-line;
}

.factura-pie {
  margin-top: 26px;
  padding-top: 14px;
  border-top: 1px solid #e2e8f0;
  color: #64748b;
  font-size: calc(11px * var(--fs));
  line-height: 1.6;
  text-align: center;
  white-space: pre-line;
}

/* Sugerencia de IP libre bajo el campo. */
.ip-libre button {
  padding: 1px 7px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent-dim);
  color: var(--accent);
  font-family: var(--font-mono, var(--font));
  font-size: calc(11.5px * var(--fs));
  font-weight: 700;
  cursor: pointer;
}

.ip-libre button:hover {
  background: var(--accent);
  color: #fff;
}

.ip-libre span {
  margin-left: 6px;
  color: var(--text-3);
}

/* Botón de borrar una nota del ticket. */
.ticket-note-del {
  margin-left: auto;
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-3);
  font-size: calc(15px * var(--fs));
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.ticket-note:hover .ticket-note-del,
.ticket-note-del:focus-visible {
  opacity: 1;
}

.ticket-note-del:hover {
  background: var(--red-dim, rgba(239, 71, 111, 0.15));
  color: var(--red);
}

/* =========================================================================
   Carpeta del cliente
   Todo lo que le ha pasado a esa casa, junto y en orden: visitas con sus
   notas, y las fotos de todos sus tickets en un solo sitio.
   ========================================================================= */
/* Selector Movimientos / Fotos. No tenia ninguna regla: salian los botones
   crudos del navegador. Sigue el mismo patron segmentado del resto del panel. */
.ticket-mode {
  display: inline-flex;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
}

.ticket-mode button {
  min-height: 30px;
  padding: 5px 14px;
  border: 0;
  border-right: 1px solid var(--border);
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: calc(12px * var(--fs));
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur), color var(--dur);
}

.ticket-mode button:last-child { border-right: 0; }
.ticket-mode button:hover { color: var(--text-1); background: var(--surface-3); }

.ticket-mode button.active,
.ticket-mode button[aria-pressed="true"] {
  color: #fff;
  background: var(--accent);
}

/* ---- Linea de tiempo ---- */

/* El riel llevaba solo una raya. Un punto por hito hace que se lea como una
   cronologia y no como una tabla con el borde corrido. */
.carpeta-hito-fecha::before {
  content: '';
  position: absolute;
  top: 4px;
  right: -5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--surface);
  background: var(--accent);
  z-index: 1;
}

.carpeta-hito-fecha strong {
  letter-spacing: -0.2px;
}

.carpeta-hito-fecha span {
  margin-top: 2px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: calc(10px * var(--fs));
}

.carpeta-hito-caja {
  transition: border-color var(--dur), box-shadow var(--dur);
}

.carpeta-hito-caja:hover {
  border-color: var(--border-2, var(--accent));
  box-shadow: 0 6px 18px var(--shadow);
}

.carpeta-hito-caja header strong {
  letter-spacing: -0.2px;
}

/* Cabecera con algo de aire y el resumen separado del titulo. */
.carpeta-head {
  background: var(--surface-2);
}

.carpeta-head .section-kicker {
  letter-spacing: 0.14em;
}

.carpeta-head p {
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}

.carpeta-dialog {
  display: flex;
  flex-direction: column;
  width: min(920px, 94vw);
  max-height: 88vh;
  padding: 0;
  overflow: hidden;
}

.carpeta-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
}

.carpeta-head h2 {
  margin: 3px 0 2px;
  font-size: calc(19px * var(--fs));
  letter-spacing: -0.3px;
}

.carpeta-head p {
  margin: 0;
  color: var(--text-3);
  font-size: calc(12.5px * var(--fs));
}

.carpeta-head-acciones {
  display: flex;
  align-items: center;
  gap: 8px;
}

.carpeta-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 18px;
}

/* ---- Linea de tiempo ---- */
.carpeta-linea {
  margin: 0;
  padding: 0;
  list-style: none;
}

.carpeta-hito {
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr);
  gap: 14px;
  padding-bottom: 16px;
}

.carpeta-hito-fecha {
  position: relative;
  padding-right: 14px;
  text-align: right;
}

/* El riel que une los hitos: sin el, la lista no se lee como una linea. */
.carpeta-hito-fecha::after {
  content: '';
  position: absolute;
  top: 6px;
  right: -1px;
  bottom: -22px;
  width: 2px;
  background: var(--border);
}

.carpeta-hito:last-child .carpeta-hito-fecha::after {
  bottom: 8px;
}

.carpeta-hito-fecha strong {
  display: block;
  font-size: calc(12.5px * var(--fs));
  font-weight: 700;
}

.carpeta-hito-fecha span {
  display: block;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
}

.carpeta-hito-caja {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
}

.carpeta-hito-caja header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.carpeta-hito-caja header strong {
  font-size: calc(13.5px * var(--fs));
}

.carpeta-hito-caja p {
  margin: 5px 0 0;
  color: var(--text-2);
  font-size: calc(12.5px * var(--fs));
  line-height: 1.5;
}

.carpeta-hito-quien {
  color: var(--text-3) !important;
  font-size: calc(11.5px * var(--fs)) !important;
}

.carpeta-notas {
  margin: 9px 0 0;
  padding: 0 0 0 12px;
  border-left: 2px solid var(--border);
  list-style: none;
}

.carpeta-notas li {
  margin: 4px 0;
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
  line-height: 1.5;
}

.carpeta-notas span {
  color: var(--text-3);
  font-weight: 600;
}

.carpeta-notas span::after {
  content: ':';
}

.carpeta-hito-fotos {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.carpeta-abrir-ticket {
  margin-top: 10px;
}

/* ---- Miniaturas ---- */
.carpeta-mini {
  width: 62px;
  height: 62px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background-color: var(--surface-3);
  background-position: center;
  background-size: cover;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.carpeta-mini:hover {
  transform: scale(1.04);
  border-color: var(--accent);
}

.carpeta-mini.grande {
  width: 100%;
  height: 130px;
}

.carpeta-mini.is-rota {
  background: repeating-linear-gradient(45deg, var(--surface-3), var(--surface-3) 6px, var(--surface-2) 6px, var(--surface-2) 12px);
  cursor: default;
}

/* ---- Galeria ---- */
.carpeta-galeria {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}

.carpeta-foto {
  margin: 0;
}

.carpeta-foto figcaption {
  display: flex;
  flex-direction: column;
  margin-top: 5px;
}

.carpeta-foto figcaption strong {
  font-size: calc(11.5px * var(--fs));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.carpeta-foto figcaption span {
  color: var(--text-3);
  font-size: calc(10.5px * var(--fs));
}

/* ---- Bajas ---- */
.carpeta-bajas {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.carpeta-bajas h4 {
  margin: 0 0 8px;
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.carpeta-bajas article {
  padding: 10px 12px;
  border: 1px solid var(--amber-dim);
  border-radius: 10px;
  background: var(--surface-2);
  margin-bottom: 8px;
}

.carpeta-bajas article strong {
  font-size: calc(12.5px * var(--fs));
}

.carpeta-bajas article span {
  margin-left: 8px;
  color: var(--amber);
  font-size: calc(12px * var(--fs));
}

.carpeta-bajas article p {
  margin: 4px 0 0;
  color: var(--text-2);
  font-size: calc(12px * var(--fs));
}

.carpeta-bajas article em {
  color: var(--text-3);
  font-size: calc(11px * var(--fs));
  font-style: normal;
}

@media (max-width: 760px) {
  .carpeta-dialog {
    width: 100%;
    max-height: 92vh;
  }

  .carpeta-hito {
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
  }

  .carpeta-hito-fecha {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding-right: 0;
    text-align: left;
  }

  .carpeta-hito-fecha::after {
    display: none;
  }

  .carpeta-head-acciones {
    width: 100%;
    justify-content: space-between;
  }
}

/* Administración: scroll propio porque el panel operativo bloquea el body. */
.administration { width: 100%; height: 100vh; height: 100dvh; overflow-y: auto; overscroll-behavior-y: contain; scrollbar-gutter: stable; }
.admin-layout { width: min(100%, 1180px); margin-inline: auto; padding: 28px 32px 48px; }
.admin-header, .admin-header-actions, .admin-intro, .admin-capacity { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.admin-header { padding-block: 0 24px; border-bottom: 1px solid var(--border); }
.admin-header .brand { min-width: 0; }
.admin-header-actions { gap: 10px; }
.admin-intro { margin: 36px 0 24px; }
.admin-intro h1 { margin: 8px 0; font-size: calc(32px * var(--fs)); letter-spacing: -.04em; }
.admin-intro p, .admin-help { line-height: 1.6; }
.administration .btn, .admin-dialog .btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 42px; }
.administration .btn svg, .admin-dialog button svg { flex-shrink: 0; }
.admin-capacity { justify-content: flex-start; gap: 12px; margin-bottom: 24px; color: var(--text-2); font-size: calc(13px * var(--fs)); }
.admin-count { white-space: nowrap; border: 1px solid var(--border-2); border-radius: 24px; padding: 7px 12px; color: var(--accent); background: var(--accent-dim); }
.admin-companies { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: start; }
.admin-company { min-width: 0; background: var(--surface); padding: 26px; border: 1px solid var(--border-2); border-radius: 16px; }
.admin-company-meta { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; }
.admin-company-icon { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 12px; color: var(--accent); background: var(--accent-dim); }
.admin-status { display: inline-flex; align-items: center; gap: 7px; color: var(--text-2); font-size: calc(12px * var(--fs)); }
.admin-status i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.admin-status.is-active { color: var(--green); }
.admin-company-type { color: var(--text-2); font-size: calc(12px * var(--fs)); }
.admin-company h2 { margin-top: 8px; font-size: calc(25px * var(--fs)); letter-spacing: -.025em; overflow-wrap: anywhere; }
.admin-company-email { margin-top: 8px; overflow-wrap: anywhere; font-size: calc(14px * var(--fs)); }
.admin-router-info { display: grid; gap: 6px; margin: 24px 0; padding: 16px; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; font-size: calc(13px * var(--fs)); }
.admin-router-info span { color: var(--text-2); overflow-wrap: anywhere; line-height: 1.5; }
.admin-company-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.admin-company-actions .btn-primary { flex: 1; }
.admin-help { margin-top: 28px; color: var(--text-2); font-size: calc(13px * var(--fs)); }
.administration .message.visible { margin-bottom: 20px; }

/* El dialogo nativo mantiene el foco dentro y se cierra con Escape. */
.admin-dialog { width: min(640px, calc(100% - 32px)); max-width: none; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); padding: 0; margin: auto; border: 1px solid var(--border-2); border-radius: 16px; color: var(--text-1); background: var(--surface); box-shadow: 0 24px 80px rgba(0,0,0,.4); overflow: hidden; }
.admin-dialog::backdrop { background: rgba(2,8,18,.72); backdrop-filter: blur(4px); }
.admin-editor { display: flex; flex-direction: column; max-height: inherit; min-height: 0; margin: 0; }
.admin-editor-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; padding: 24px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.admin-editor-header > div { min-width: 0; }
.admin-editor-header h2 { margin-top: 8px; font-size: calc(23px * var(--fs)); line-height: 1.25; overflow-wrap: anywhere; }
.admin-editor-header .icon-btn { width: 36px; height: 36px; flex-shrink: 0; }
.admin-editor-body { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 24px; }
.admin-editor-body > p { font-size: calc(13px * var(--fs)); line-height: 1.6; margin-bottom: 22px; }
.admin-fields { display: grid; gap: 20px; }
.admin-fields .field { min-width: 0; margin: 0; }
.admin-fields .input { width: 100%; min-width: 0; min-height: 44px; }
.admin-fields small { color: var(--text-2); line-height: 1.5; font-size: calc(12px * var(--fs)); }
.admin-router-fields { padding: 16px; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; }
.admin-router-fields summary { cursor: pointer; font-size: calc(14px * var(--fs)); }
.admin-router-fields[open] summary { margin-bottom: 20px; }
.admin-editor-footer { border-top: 1px solid var(--border); padding: 18px 24px; background: var(--surface); flex-shrink: 0; }
.admin-editor-actions { display: flex; justify-content: flex-end; gap: 12px; }
.admin-form-error { color: var(--red); font-size: calc(13px * var(--fs)); line-height: 1.5; margin-bottom: 14px; }
.admin-dialog [hidden] { display: none; }
.admin-dialog :focus-visible, .administration :focus-visible, .company-admin-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Identidad de empresa en ambos tamaños de la barra lateral. */
.active-company { min-width: 0; display: grid; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.active-company-row { min-width: 0; display: flex; align-items: center; gap: 10px; }
.active-company-badge { display: grid; place-items: center; width: 32px; height: 32px; flex-shrink: 0; background: var(--accent-dim); color: var(--accent); border-radius: 9px; font-size: 11px; font-weight: 700; }
.active-company-caption { min-width: 0; display: grid; gap: 3px; }
.active-company-caption > span { font-size: calc(10px * var(--fs)); color: var(--text-2); }
.active-company-caption > strong { font-size: calc(13px * var(--fs)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.company-admin-link { min-width: 0; display: flex; gap: 9px; align-items: center; justify-content: center; min-height: 36px; padding: 8px; border: 1px solid var(--border-2); border-radius: 8px; background: var(--surface-2); color: var(--text-2); font-size: calc(12px * var(--fs)); cursor: pointer; }
.company-admin-link:hover { background: var(--accent-dim); color: var(--accent); }
.company-admin-link svg { flex-shrink: 0; }
.sidebar { height: 100dvh; }
.sidebar-nav { min-height: 0; }
.sidebar-logo, .sidebar-footer, .sidebar-collapse, .profile-switcher, .cmdk-hint { flex-shrink: 0; }
.main-wrap { height: 100dvh; min-width: 0; }
.main-wrap > .content { min-height: 0; }
.topbar-heading { min-width: 0; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.topbar-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-company { display: block; min-width: 0; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--accent); font-size: calc(11px * var(--fs)); background: var(--accent-dim); border-radius: 5px; padding: 3px 7px; }
@media (min-width: 901px) {
  .sidebar.collapsed .active-company { padding: 12px 6px; justify-items: center; gap: 8px; }
  .sidebar.collapsed .active-company-caption, .sidebar.collapsed .company-admin-link > span { display: none; }
  .sidebar.collapsed .company-admin-link { width: 36px; height: 36px; padding: 0; }
  .sidebar.collapsed .sidebar-nav { overflow-y: auto; overflow-x: hidden; }
}
@media (max-width: 760px) {
  .admin-layout { padding: 20px 16px 32px; }
  .admin-header { align-items: flex-start; flex-wrap: wrap; gap: 18px; }
  .admin-header-actions { flex-wrap: wrap; }
  .admin-intro { align-items: flex-start; flex-direction: column; gap: 18px; margin-top: 28px; }
  .admin-intro h1 { font-size: calc(28px * var(--fs)); }
  .admin-companies { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .admin-company { padding: 22px; }
  .admin-capacity { align-items: flex-start; flex-direction: column; gap: 8px; }
  .topbar { height: auto; min-height: var(--topbar-h); display: grid; grid-template-columns: 38px minmax(0,1fr) 52px 52px; gap: 8px; padding: 10px 12px; }
  .topbar [data-menu] { grid-column: 1; grid-row: 1; }
  .topbar-title-wrap { grid-column: 2; grid-row: 1; }
  .topbar [data-theme-switch] { grid-column: 3; grid-row: 1; justify-self: end; }
  .theme-switch-name,
  .theme-chevron { display: none; }
  .theme-switch-btn { width: 35px; padding: 0; justify-content: center; }
  .topbar [data-logout] { grid-column: 4; grid-row: 1; justify-self: end; }
  .topbar [data-auto-chip] { grid-column: 1; grid-row: 2; }
  .topbar [data-mk-status] { grid-column: 2; grid-row: 2; }
  .topbar .ui-scale { grid-column: 3 / 5; grid-row: 2; justify-self: end; }
  .topbar-heading { display: grid; gap: 3px; }
  .topbar-company { max-width: 100%; width: fit-content; padding: 0; background: transparent; }
}
@media (max-width: 480px) {
  .admin-header-actions { width: 100%; }
  .admin-header-actions .btn { flex: 1; }
  .admin-company-actions .btn { flex: 1 1 100%; }
  .admin-dialog { width: calc(100% - 16px); max-height: calc(100dvh - 16px); border-radius: 12px; }
  .admin-editor-header, .admin-editor-body { padding: 18px; }
  .admin-editor-footer { padding: 14px 18px; }
  .admin-editor-header h2 { font-size: calc(20px * var(--fs)); }
  .admin-editor-actions .btn { flex: 1; white-space: normal; }
  .admin-fields .input { font-size: max(16px, calc(14px * var(--fs))); }
}
@media (max-height: 600px) {
  .admin-editor-header { padding-block: 14px; }
  .admin-editor-header .eyebrow { display: none; }
  .admin-editor-header h2 { margin-top: 0; }
  .admin-editor-footer { padding-block: 12px; }
}

/* Anclajes constantes: solo cambia el ancho del menú, nunca la posición de sus iconos. */
@media (min-width: 901px) {
  .sidebar, .main-wrap { transition: width 220ms var(--ease), min-width 220ms var(--ease), margin-left 220ms var(--ease); }
  .sidebar .sidebar-logo, .sidebar.collapsed .sidebar-logo { height: 74px; padding: 18px 14px; gap: 12px; justify-content: flex-start; overflow: hidden; }
  .sidebar-logo > div:last-child { flex-shrink: 0; width: 180px; }
  .sidebar .logo-text, .sidebar .logo-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .sidebar .sidebar-collapse, .sidebar.collapsed .sidebar-collapse { position: relative; margin: 8px 14px 0; padding: 0; width: calc(100% - 28px); height: 32px; justify-content: flex-start; overflow: hidden; }
  .sidebar-collapse svg { position: absolute; left: 10px; }
  .sidebar-collapse > span { margin-left: 46px; }
  .sidebar .active-company, .sidebar.collapsed .active-company { position: relative; display: block; height: 64px; padding: 0; overflow: hidden; }
  .sidebar .active-company:has(.company-admin-link) { height: 104px; }
  .sidebar .active-company-row { position: absolute; top: 12px; left: 16px; height: 32px; }
  .sidebar .active-company-caption, .sidebar.collapsed .active-company-caption { display: grid; position: absolute; left: 44px; width: calc(var(--sidebar-w) - 80px); }
  .sidebar .company-admin-link, .sidebar.collapsed .company-admin-link { position: absolute; left: 14px; right: 14px; bottom: 12px; width: auto; height: 36px; min-height: 36px; padding: 8px; justify-content: flex-start; gap: 18px; overflow: hidden; }
  .sidebar .company-admin-link > span, .sidebar.collapsed .company-admin-link > span { display: block; white-space: nowrap; }
  .sidebar .cmdk-hint, .sidebar.collapsed .cmdk-hint { margin: 10px 14px; width: calc(100% - 28px); height: 36px; padding: 8px; gap: 16px; justify-content: flex-start; overflow: hidden; }
  .sidebar .cmdk-hint svg { width: 18px; min-width: 18px; }
  .sidebar .cmdk-hint > span { flex-shrink: 0; }
  .sidebar .sidebar-nav, .sidebar.collapsed .sidebar-nav { padding: 10px 6px; overflow-y: auto; overflow-x: hidden; }
  .sidebar .nav-section-label, .sidebar.collapsed .nav-section-label { display: block; height: 30px; white-space: nowrap; overflow: hidden; }
  .sidebar .nav-item, .sidebar.collapsed .nav-item { display: grid; grid-template-columns: 50px minmax(0, 1fr); align-items: center; justify-content: normal; padding: 10px 0; gap: 0; overflow: hidden; }
  .sidebar .nav-item > svg, .sidebar.collapsed .nav-item > svg { justify-self: center; width: 19px; height: 19px; }
  .sidebar .nav-item > span, .sidebar.collapsed .nav-item > span { display: block; width: 176px; white-space: nowrap; text-align: left; }
  .sidebar .sidebar-logo > div:last-child, .sidebar .active-company-caption, .sidebar .company-admin-link > span,
  .sidebar .nav-section-label, .sidebar .nav-item > span, .sidebar .cmdk-hint > span, .sidebar .cmdk-hint > kbd,
  .sidebar .sidebar-collapse > span { transition: opacity 130ms ease, visibility 130ms ease; }
  .sidebar.collapsed .sidebar-logo > div:last-child, .sidebar.collapsed .active-company-caption, .sidebar.collapsed .company-admin-link > span,
  .sidebar.collapsed .nav-section-label, .sidebar.collapsed .nav-item > span, .sidebar.collapsed .cmdk-hint > span, .sidebar.collapsed .cmdk-hint > kbd,
  .sidebar.collapsed .sidebar-collapse > span { opacity: 0; visibility: hidden; pointer-events: none; }
  .sidebar.collapsed .logo-text, .sidebar.collapsed .logo-sub, .sidebar.collapsed .cmdk-hint > span, .sidebar.collapsed .cmdk-hint > kbd, .sidebar.collapsed .sidebar-collapse > span { display: block; }
}
@media (prefers-reduced-motion: reduce) {
  .sidebar, .main-wrap, .sidebar * { transition: none !important; }
}

/* ---------------------------------------------------------------------------
   WhatsApp: bandeja de entrada
   --------------------------------------------------------------------------- */

/* Todo con variables del tema: la bandeja se ve en los cuatro temas. Los
   tonos de las burbujas salen de mezclar el color de acento con el panel, asi
   cada tema da su propia version sin repetir reglas. */
.wa-panel {
  --wa-read: #53bdeb;
  --wa-out: color-mix(in srgb, var(--green) 16%, var(--panel));
  --wa-out-line: color-mix(in srgb, var(--green) 34%, transparent);
  --wa-tpl: color-mix(in srgb, var(--accent) 13%, var(--panel));
  --wa-tpl-line: color-mix(in srgb, var(--accent) 38%, transparent);
  --wa-in: var(--panel-3);
}

[data-scheme="light"] .wa-panel {
  --wa-read: #1479b8;
  --wa-in: var(--surface);
}

.wa-panel svg {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

.wa-title-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.wa-conexion {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--muted);
  font-size: calc(12px * var(--fs));
  font-weight: 600;
}

.wa-conexion-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--soft);
}

.wa-conexion[data-state="ok"] { color: var(--green); border-color: color-mix(in srgb, var(--green) 40%, transparent); background: color-mix(in srgb, var(--green) 10%, transparent); }
.wa-conexion[data-state="ok"] .wa-conexion-dot { background: var(--green); box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 22%, transparent); }
.wa-conexion[data-state="aviso"] { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 40%, transparent); }
.wa-conexion[data-state="aviso"] .wa-conexion-dot { background: var(--amber); }
.wa-conexion[data-state="error"] { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); }
.wa-conexion[data-state="error"] .wa-conexion-dot { background: var(--red); }

.wa-tab-count {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 18px;
  margin-left: 7px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--green);
  color: #fff;
  font-size: calc(11px * var(--fs));
  font-weight: 700;
}

.wa-tab-count[hidden] { display: none; }

/* La bandeja se mide contra su propio ancho y no contra la ventana: la barra
   lateral abierta o cerrada cambia mucho el espacio que queda. */
.wa-bandeja {
  container: wa-bandeja / inline-size;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.wa-bandeja[hidden] { display: none; }

/* ---- Cifras ---- */

.wa-kpis {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
}

.wa-kpis > .skel { grid-column: 1 / -1; }

.wa-kpi {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 11px;
  row-gap: 2px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  min-width: 0;
}

.wa-kpi-icon {
  grid-row: span 2;
  width: 36px;
  height: 36px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  font-size: 18px;
  color: var(--wa-kpi, var(--accent));
  background: color-mix(in srgb, var(--wa-kpi, var(--accent)) 15%, transparent);
}

.wa-kpi[data-tono="azul"] { --wa-kpi: var(--accent); }
.wa-kpi[data-tono="ambar"] { --wa-kpi: var(--amber); }
.wa-kpi[data-tono="verde"] { --wa-kpi: var(--green); }
.wa-kpi[data-tono="morado"] { --wa-kpi: var(--purple); }
.wa-kpi[data-tono="celeste"] { --wa-kpi: var(--wa-read); }

.wa-kpi-body {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}

.wa-kpi-body span {
  color: var(--muted);
  font-size: calc(12px * var(--fs));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wa-kpi-body strong {
  font-size: calc(20px * var(--fs));
  line-height: 1.1;
}

.wa-kpi small {
  color: var(--muted);
  font-size: calc(11px * var(--fs));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wa-kpi small[data-tono="ambar"] { color: var(--amber); }
.wa-kpi small[data-tono="rojo"] { color: var(--red); }

/* ---- Las tres columnas ---- */

.wa-inbox {
  position: relative;
  display: grid;
  grid-template-columns: minmax(270px, 330px) minmax(0, 1fr) 300px;
  gap: 12px;
  height: clamp(520px, calc(100dvh - 310px), 1000px);
}

.wa-col {
  min-height: 0;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel-2);
  overflow: hidden;
}

.wa-lista-col {
  display: flex;
  flex-direction: column;
}

.wa-lista-tools {
  display: grid;
  gap: 9px;
  padding: 11px;
  border-bottom: 1px solid var(--line);
}

.wa-search {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--muted);
  font-size: 15px;
}

.wa-search:focus-within { border-color: var(--accent); }

.wa-search input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: var(--text);
  font-size: calc(13px * var(--fs));
}

.wa-filtros,
.wa-rapidas {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.wa-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 28px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
  cursor: pointer;
}

.wa-chip span { opacity: 0.8; font-variant-numeric: tabular-nums; }
.wa-chip:hover { color: var(--text); border-color: var(--border-2, var(--accent)); }

.wa-chip.is-on {
  color: var(--text);
  border-color: var(--accent);
  background: var(--accent-dim);
}

.wa-lista {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 6px;
}

.wa-conv {
  width: 100%;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 11px;
  align-items: start;
  padding: 10px;
  margin-bottom: 2px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.wa-conv:hover { background: var(--panel-3); }

.wa-conv.is-active {
  background: var(--accent-dim);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

.wa-conv-body {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.wa-conv-top,
.wa-conv-prev {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.wa-conv-top strong {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: calc(13.5px * var(--fs));
}

.wa-conv-top time {
  color: var(--muted);
  font-size: calc(11px * var(--fs));
}

.wa-conv-prev > span:not(.wa-tick) {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
  font-size: calc(12.5px * var(--fs));
}

.wa-conv.is-unread .wa-conv-prev > span:not(.wa-tick) { color: var(--text); font-weight: 600; }
.wa-conv.is-unread .wa-conv-top time { color: var(--green); font-weight: 700; }

.wa-unread {
  display: grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--green);
  color: #fff;
  font-size: calc(11px * var(--fs));
}

.wa-conv-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 2px;
}

.wa-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 20px;
  padding: 0 7px;
  border-radius: 5px;
  background: var(--panel-3);
  color: var(--muted);
  font-size: calc(11px * var(--fs));
  white-space: nowrap;
}

.wa-tag[data-tono="rojo"] { color: var(--red); background: color-mix(in srgb, var(--red) 13%, transparent); }
.wa-tag[data-tono="verde"],
.wa-tag[data-ventana="abierta"] { color: var(--green); background: color-mix(in srgb, var(--green) 13%, transparent); }
.wa-tag[data-ventana="poca"] { color: var(--amber); background: color-mix(in srgb, var(--amber) 14%, transparent); }

/* ---- Avatar ---- */

.wa-avatar {
  position: relative;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--wa-av);
  color: #fff;
  font-weight: 700;
  font-size: calc(14px * var(--fs));
  letter-spacing: 0.02em;
}

.wa-avatar-dot {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 2px solid var(--panel-2);
  background: var(--wa-estado, var(--soft));
}

/* Los mismos colores de estado que la lista de clientes. */
.wa-avatar[data-estado="activo"] { --wa-estado: var(--green); }
.wa-avatar[data-estado="moroso"] { --wa-estado: var(--amber); }
.wa-avatar[data-estado="suspendido"] { --wa-estado: var(--red); }
.wa-avatar[data-estado="cancelado"] { --wa-estado: var(--soft); }
.wa-avatar[data-estado="ninguno"] .wa-avatar-dot { display: none; }

.wa-avatar-sm { width: 36px; height: 36px; font-size: calc(12px * var(--fs)); }
.wa-avatar-sm .wa-avatar-dot { width: 11px; height: 11px; }

.wa-avatar-lg {
  width: 68px;
  height: 68px;
  font-size: calc(22px * var(--fs));
  box-shadow: 0 0 0 3px var(--panel-2), 0 0 0 5px var(--wa-estado, var(--soft));
}

.wa-avatar-lg .wa-avatar-dot { display: none; }

/* ---- Hilo ---- */

.wa-hilo {
  display: flex;
  flex-direction: column;
}

.wa-hilo-head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}

.wa-volver { display: none; }

.wa-hilo-titulo {
  display: grid;
  flex: 1;
  min-width: 0;
}

.wa-hilo-titulo strong,
.wa-hilo-titulo span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wa-hilo-titulo strong { font-size: calc(15px * var(--fs)); }
.wa-hilo-titulo span { color: var(--muted); font-size: calc(12px * var(--fs)); }

.wa-ventana {
  display: grid;
  gap: 5px;
  width: 180px;
  flex: none;
  font-size: calc(11.5px * var(--fs));
  font-weight: 600;
  color: var(--muted);
}

.wa-ventana > span:first-child { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.wa-ventana[data-nivel="abierta"] { color: var(--green); }
.wa-ventana[data-nivel="poca"] { color: var(--amber); }

.wa-ventana-barra {
  height: 4px;
  border-radius: 2px;
  background: var(--panel-3);
  overflow: hidden;
}

.wa-ventana-barra span {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: currentColor;
}

.wa-hilo-acciones {
  display: flex;
  gap: 6px;
  flex: none;
}

.wa-hilo-acciones .btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.wa-btn-resolver.is-ok {
  color: var(--green);
  border-color: color-mix(in srgb, var(--green) 40%, transparent);
}

.wa-btn-cliente { display: none; }

.wa-msgs {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 16px 20px;
  background-color: var(--panel-2);
  background-image: radial-gradient(var(--grid-dot) 1px, transparent 1px);
  background-size: 18px 18px;
}

/* Sin esto la columna encoge las burbujas para que quepan y las de plantilla,
   que llevan overflow: hidden, salian cortadas a media frase. */
.wa-msgs > * {
  flex-shrink: 0;
}

.wa-dia {
  align-self: center;
  margin: 8px 0 4px;
}

.wa-dia span {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--panel-3);
  color: var(--muted);
  font-size: calc(11.5px * var(--fs));
}

.wa-msg {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: min(72%, 560px);
  padding: 8px 12px 6px;
  border: 1px solid var(--line);
  border-radius: 12px;
}

.wa-msg p {
  margin: 0;
  color: var(--text);
  font-size: calc(13.5px * var(--fs));
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.wa-msg-in {
  align-self: flex-start;
  background: var(--wa-in);
  border-bottom-left-radius: 4px;
}

.wa-msg-out {
  align-self: flex-end;
  background: var(--wa-out);
  border-color: var(--wa-out-line);
  border-bottom-right-radius: 4px;
}

.wa-msg-tpl {
  align-self: flex-end;
  padding: 0;
  background: var(--wa-tpl);
  border-color: var(--wa-tpl-line);
  border-bottom-right-radius: 4px;
  overflow: hidden;
}

.wa-msg-tpl p { padding: 8px 12px 0; }
.wa-msg-tpl .wa-msg-meta { padding: 0 12px 7px; }
.wa-msg.is-failed { border-color: color-mix(in srgb, var(--red) 55%, transparent); }

.wa-tpl-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--wa-tpl-line);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--accent);
  font-size: calc(11.5px * var(--fs));
}

.wa-tpl-head strong { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.wa-origen {
  padding: 1px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  font-weight: 600;
}

.wa-origen[data-origen="automatico"] {
  color: var(--purple);
  background: color-mix(in srgb, var(--purple) 16%, transparent);
}

.wa-msg-meta {
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  font-size: calc(10.5px * var(--fs));
}

.wa-tick {
  display: inline-flex;
  font-size: 15px;
  color: var(--muted);
}

.wa-tick[data-entrega="leido"] { color: var(--wa-read); }
.wa-tick[data-entrega="fallido"] { color: var(--red); }

.wa-msg-error {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  margin: 2px -12px -6px;
  padding: 7px 12px;
  border-top: 1px solid color-mix(in srgb, var(--red) 35%, transparent);
  background: color-mix(in srgb, var(--red) 11%, transparent);
  color: var(--red);
  font-size: calc(12px * var(--fs));
}

.wa-msg-tpl .wa-msg-error { margin: 0; }

.wa-adjunto {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--muted);
  font-size: 22px;
}

.wa-adjunto > span { display: grid; font-size: calc(12.5px * var(--fs)); }
.wa-adjunto strong { color: var(--text); }
.wa-adjunto small { font-size: calc(11px * var(--fs)); }

/* ---- Escribir ---- */

.wa-composer {
  display: grid;
  gap: 8px;
  padding: 10px 14px 12px;
  border-top: 1px solid var(--line);
  background: var(--panel);
}

.wa-escribir {
  display: flex;
  align-items: flex-end;
  gap: 10px;
}

.wa-escribir textarea {
  flex: 1;
  min-width: 0;
  min-height: 46px;
  max-height: 160px;
  padding: 10px 12px;
  resize: vertical;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: calc(13.5px * var(--fs));
  line-height: 1.4;
  outline: none;
}

.wa-escribir textarea:focus { border-color: var(--accent); }

.wa-enviar {
  width: 46px;
  height: 46px;
  flex: none;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 12px;
  background: var(--green);
  color: #fff;
  font-size: 19px;
  cursor: pointer;
}

.wa-enviar:hover { filter: brightness(1.1); }
.wa-enviar:disabled { opacity: 0.55; cursor: progress; }

.wa-ayuda,
.wa-solo-lectura {
  color: var(--muted);
  font-size: calc(11px * var(--fs));
}

.wa-cerrada {
  display: flex;
  align-items: center;
  gap: 12px;
}

.wa-cerrada > div {
  display: grid;
  gap: 2px;
  flex: 1;
  font-size: calc(12px * var(--fs));
  color: var(--muted);
}

.wa-cerrada strong { color: var(--text); font-size: calc(13px * var(--fs)); }

.wa-cerrada-icon {
  width: 38px;
  height: 38px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--panel-3);
  color: var(--muted);
  font-size: 18px;
}

.wa-aviso {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 14px 8px;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: calc(12.5px * var(--fs));
  color: var(--red);
  border: 1px solid color-mix(in srgb, var(--red) 40%, transparent);
  background: color-mix(in srgb, var(--red) 10%, var(--panel));
}

.wa-aviso[data-tipo="success"] {
  color: var(--green);
  border-color: color-mix(in srgb, var(--green) 40%, transparent);
  background: color-mix(in srgb, var(--green) 10%, var(--panel));
}

.wa-aviso span { flex: 1; }

.wa-aviso button {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

/* ---- Plantillas dentro del hilo ---- */

.wa-tpl-panel {
  display: grid;
  gap: 10px;
  max-height: 55%;
  overflow-y: auto;
  padding: 12px 14px;
  border-top: 1px solid var(--line);
  background: var(--panel);
}

.wa-tpl-panel[hidden] { display: none; }

.wa-tpl-panel-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.wa-tpl-panel-head strong { flex: 1; }

.wa-tpl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}

.wa-tpl-card {
  display: grid;
  gap: 6px;
  align-content: start;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.wa-tpl-card:hover { border-color: var(--accent); }

.wa-tpl-card-head {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--accent);
  font-size: calc(12.5px * var(--fs));
}

.wa-tpl-card-text {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
  line-height: 1.4;
}

.wa-tpl-form {
  display: grid;
  gap: 10px;
}

.wa-tpl-vars {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 8px;
}

.wa-tpl-preview {
  max-width: 100%;
  align-self: stretch;
}

.wa-tpl-preview p { padding-bottom: 10px; }

.wa-tpl-form .btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

/* ---- Panel del cliente ---- */

.wa-cliente {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 14px;
  overflow-y: auto;
}

.wa-cliente-cerrar { display: none; }

.wa-cli-top {
  display: grid;
  justify-items: center;
  gap: 7px;
  text-align: center;
}

.wa-cli-top strong {
  margin-top: 4px;
  font-size: calc(16px * var(--fs));
}

.wa-cli-top .muted { font-size: calc(12px * var(--fs)); }

.wa-cli-acciones {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px;
}

.wa-cli-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 40px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
  font-size: calc(12.5px * var(--fs));
  cursor: pointer;
}

.wa-cli-btn:hover { border-color: var(--accent); background: var(--accent-dim); }

.wa-cli-card {
  display: grid;
  gap: 7px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
}

.wa-cli-card h3 {
  margin: 0 0 2px;
  color: var(--muted);
  font-size: calc(11px * var(--fs));
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.wa-dato {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: calc(12.5px * var(--fs));
}

.wa-dato > span:first-child { color: var(--muted); }
.wa-dato > span:last-child { text-align: right; overflow-wrap: anywhere; }
.wa-mono { font-family: var(--mono, monospace); }

.wa-dato-saldo strong { font-size: calc(14px * var(--fs)); }
.wa-dato-saldo[data-tono="verde"] strong,
.wa-dato-nota[data-tono="verde"] { color: var(--green); }
.wa-dato-saldo[data-tono="ambar"] strong,
.wa-dato-nota[data-tono="ambar"] { color: var(--amber); }
.wa-dato-saldo[data-tono="rojo"] strong,
.wa-dato-nota[data-tono="rojo"] { color: var(--red); }

.wa-dato-nota {
  margin: -4px 0 2px;
  text-align: right;
  font-size: calc(11.5px * var(--fs));
}

.wa-cli-ticket {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid color-mix(in srgb, var(--amber) 35%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--amber) 9%, transparent);
  color: var(--text);
  font-size: calc(12.5px * var(--fs));
  text-align: left;
  cursor: pointer;
}

.wa-cli-ticket svg { color: var(--amber); }
.wa-cli-ticket span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-cli-ticket small { color: var(--amber); }

.wa-aviso-fila {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  font-size: calc(12px * var(--fs));
}

.wa-aviso-fila > span:first-child { color: var(--muted); }
.wa-aviso-fila > span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.wa-estado {
  padding: 1px 8px;
  border-radius: 999px;
  font-size: calc(10.5px * var(--fs));
  font-weight: 600;
  color: var(--muted);
  background: var(--panel-3);
}

.wa-estado[data-entrega="leido"] { color: var(--wa-read); background: color-mix(in srgb, var(--wa-read) 14%, transparent); }
.wa-estado[data-entrega="fallido"] { color: var(--red); background: color-mix(in srgb, var(--red) 14%, transparent); }

.wa-cli-nota {
  margin: 0;
  font-size: calc(12.5px * var(--fs));
  line-height: 1.45;
  white-space: pre-wrap;
}

.wa-link {
  align-self: center;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: calc(12px * var(--fs));
  text-decoration: underline;
  cursor: pointer;
}

.wa-link:hover { color: var(--text); }

.wa-info {
  display: flex;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 10px;
  background: var(--accent-dim);
  font-size: calc(12.5px * var(--fs));
  line-height: 1.45;
}

.wa-info svg { font-size: 17px; color: var(--accent); }

.wa-vincular-lista {
  display: grid;
  gap: 6px;
}

.wa-vincular-fila {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
}

.wa-vincular-fila > span:not(.wa-avatar) {
  display: grid;
  flex: 1;
  min-width: 0;
  font-size: calc(12.5px * var(--fs));
}

.wa-vincular-fila small {
  color: var(--muted);
  font-size: calc(11.5px * var(--fs));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wa-cli-hint {
  margin: 0;
  color: var(--muted);
  font-size: calc(11.5px * var(--fs));
  line-height: 1.45;
}

.wa-vacio {
  display: grid;
  justify-items: center;
  gap: 6px;
  padding: 36px 18px;
  color: var(--muted);
  text-align: center;
}

.wa-vacio > svg { font-size: 34px; opacity: 0.6; }
.wa-vacio strong { color: var(--text); }
.wa-vacio p { max-width: 320px; font-size: calc(12.5px * var(--fs)); }
.wa-hilo-vacio { margin: auto; }

/* Sin espacio para tres columnas: los datos del cliente salen como un cajon
   sobre el hilo, con el boton Cliente de la cabecera. */
@container wa-bandeja (max-width: 1100px) {
  .wa-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .wa-inbox { grid-template-columns: minmax(250px, 310px) minmax(0, 1fr); }
  .wa-btn-cliente { display: inline-flex; }
  .wa-cliente-cerrar { display: grid; align-self: flex-end; margin-bottom: -38px; }

  .wa-cliente {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    width: min(330px, 92%);
    box-shadow: -18px 0 40px var(--shadow);
    transform: translateX(calc(100% + 20px));
    visibility: hidden;
    transition: transform var(--dur, 240ms) var(--ease, ease), visibility 0s linear var(--dur, 240ms);
  }

  .wa-inbox.ver-cliente .wa-cliente {
    transform: none;
    visibility: visible;
    transition: transform var(--dur, 240ms) var(--ease, ease);
  }

  .wa-ventana { width: 150px; }
}

/* Telefono: una columna. Se ve la lista o la conversacion, como en WhatsApp. */
@container wa-bandeja (max-width: 720px) {
  .wa-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wa-kpi:last-child { grid-column: 1 / -1; }
  .wa-inbox { grid-template-columns: minmax(0, 1fr); height: clamp(480px, calc(100dvh - 190px), 900px); }
  .wa-hilo { display: none; }
  .wa-inbox.ver-hilo .wa-lista-col { display: none; }
  .wa-inbox.ver-hilo .wa-hilo { display: flex; }
  .wa-volver { display: grid; }
  .wa-hilo-head { flex-wrap: wrap; padding: 8px 10px; }
  .wa-ventana { order: 5; width: 100%; }
  .wa-hilo-acciones .btn { padding-inline: 9px; }
  .wa-msgs { padding: 12px; }
  .wa-msg { max-width: 88%; }
  .wa-cliente { width: 100%; }
  .wa-cerrada { flex-wrap: wrap; }
}

@media (prefers-reduced-motion: reduce) {
  .wa-cliente { transition: none !important; }
}

.wa-origen[data-origen="cobro"] {
  color: var(--amber);
  background: color-mix(in srgb, var(--amber) 16%, transparent);
}

/* ---------------------------------------------------------------------------
   WhatsApp desde Cobro
   --------------------------------------------------------------------------- */

.wa-cobro-ico {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

/* Boton de WhatsApp de dos zonas: "Avisar" a la izquierda y la flechita
   para ver el mensaje a la derecha, con un borde comun que los une. */
.wa-split {
  --wa: #1fa855;
  display: inline-flex;
  align-items: stretch;
  min-height: 29px;
  border: 1px solid color-mix(in srgb, var(--wa) 45%, transparent);
  border-radius: 6px;
  background: color-mix(in srgb, var(--wa) 9%, transparent);
  overflow: hidden;
  vertical-align: middle;
}

[data-scheme="dark"] .wa-split { --wa: #25d366; }

.wa-split button {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 0;
  margin: 0;
  color: var(--wa);
  background: transparent;
  font: inherit;
  font-size: calc(10px * var(--fs));
  font-weight: 600;
  cursor: pointer;
}

.wa-split .wa-cobro-ico { width: 15px; height: 15px; }

.wa-split-main {
  padding: 4px 8px 4px 7px;
}

.wa-split .wa-split-menu {
  padding: 4px 5px;
  border-left: 1px solid color-mix(in srgb, var(--wa) 35%, transparent);
}

.wa-split-menu .wa-cobro-ico { width: 13px; height: 13px; stroke-width: 2.4; }

.wa-split button:hover,
.wa-split button:focus-visible {
  color: #fff;
  background: var(--wa);
  outline: none;
}

/* El rayito solo aparece con el envio directo encendido. */
.wa-split .wa-split-rayo { display: none; width: 12px; height: 12px; fill: currentColor; stroke: none; }
.wa-split.is-directo .wa-split-rayo { display: inline-block; }

.wa-split.is-off {
  --wa: var(--soft);
  opacity: 0.6;
}

.wa-split.is-off button { cursor: not-allowed; }
.wa-split.is-off button:hover { color: var(--wa); background: transparent; }

.client-row-action.wa-ver-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.client-row-action.wa-ver-btn .wa-cobro-ico { width: 14px; height: 14px; }

.wa-vista-directo {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 12px 0 4px;
  padding: 10px 12px;
  border: 1px solid var(--border-2);
  border-radius: 8px;
  cursor: pointer;
}

.wa-vista-directo:has(input:checked) {
  border-color: color-mix(in srgb, #25d366 45%, transparent);
  background: color-mix(in srgb, #25d366 8%, transparent);
}

.wa-vista-directo input { width: 16px; height: 16px; margin: 2px 0 0; accent-color: #1fa855; flex: none; }
.wa-vista-directo span { display: grid; gap: 2px; }
.wa-vista-directo strong { display: inline-flex; align-items: center; gap: 5px; color: var(--text-1); font-size: calc(12.5px * var(--fs)); }
.wa-vista-directo strong .wa-cobro-ico { width: 13px; height: 13px; fill: #1fa855; stroke: none; }
.wa-vista-directo small { color: var(--muted); font-size: calc(11.5px * var(--fs)); line-height: 1.4; }

.wa-cobro-ultimo {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 5px;
  color: var(--muted);
  font-size: calc(11px * var(--fs));
  white-space: nowrap;
}

.wa-cobro-ultimo .wa-cobro-ico { width: 13px; height: 13px; color: #25a855; }
.wa-cobro-ultimo[data-entrega="leido"] span { color: #1f9bd6; }
.wa-cobro-ultimo[data-entrega="fallido"],
.wa-cobro-ultimo[data-entrega="fallido"] .wa-cobro-ico { color: var(--red); }

.wa-cobro-check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0 2px;
  padding: 9px 11px;
  border: 1px solid color-mix(in srgb, #25d366 35%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, #25d366 8%, transparent);
  font-size: calc(12.5px * var(--fs));
  cursor: pointer;
}

.wa-cobro-check input { width: 16px; height: 16px; margin: 0; accent-color: #1fa855; }
.wa-cobro-check .wa-cobro-ico { color: #1fa855; }

.wa-vista-dialog {
  width: min(520px, calc(100vw - 32px));
}

.wa-vista-tipos {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}

.wa-vista-tipo {
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-size: calc(12.5px * var(--fs));
  cursor: pointer;
}

.wa-vista-tipo.is-on {
  color: var(--text);
  border-color: var(--accent);
  background: var(--accent-dim);
}

.wa-vista-chat {
  display: grid;
  gap: 8px;
  padding: 16px;
  border-radius: 10px;
  background-color: var(--panel-2);
  background-image: radial-gradient(var(--grid-dot) 1px, transparent 1px);
  background-size: 16px 16px;
}

.wa-vista-chat small {
  color: var(--muted);
  font-size: calc(11.5px * var(--fs));
}

.wa-vista-burbuja {
  justify-self: end;
  max-width: 92%;
  border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent);
  border-radius: 12px 12px 4px 12px;
  background: color-mix(in srgb, var(--accent) 12%, var(--panel));
  overflow: hidden;
}

.wa-vista-plantilla {
  padding: 6px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--accent);
  font-size: calc(11.5px * var(--fs));
  font-weight: 600;
}

.wa-vista-burbuja p {
  margin: 0;
  padding: 10px 12px;
  color: var(--text);
  font-size: calc(13.5px * var(--fs));
  line-height: 1.5;
  white-space: pre-wrap;
}

.wa-vista-dialog .actions .btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.wa-toasts {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 1200;
  display: grid;
  gap: 8px;
  width: min(380px, calc(100vw - 36px));
}

.wa-toast {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  color: var(--text);
  box-shadow: 0 12px 32px var(--shadow);
  font-size: calc(13px * var(--fs));
  animation: wa-toast-in var(--dur, 240ms) var(--ease, ease);
}

.wa-toast > .wa-cobro-ico { color: #1fa855; width: 18px; height: 18px; }
.wa-toast[data-tipo="ok"] { border-color: color-mix(in srgb, var(--green) 45%, transparent); }
.wa-toast[data-tipo="error"] { border-color: color-mix(in srgb, var(--red) 55%, transparent); color: var(--red); }
.wa-toast.is-leaving { opacity: 0; transform: translateY(6px); transition: opacity 200ms, transform 200ms; }

.wa-toast-texto { flex: 1; min-width: 0; }

.wa-toast-acciones button {
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--panel-2);
  color: var(--text);
  font-weight: 600;
  cursor: pointer;
}

/* ---- Por avisar (Cobro) ---- */

.wa-avisar-scope {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.wa-avisar-scope .wa-cobro-ico { color: #1fa855; }

.wa-avisar-count {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  border-radius: 999px;
  background: #1fa855;
  color: #fff;
  font-size: calc(11px * var(--fs));
  font-weight: 700;
}

.wa-avisar-count[hidden] { display: none; }

.wa-avisar {
  display: grid;
  gap: 14px;
  padding: 4px 2px;
}

.wa-avisar-barra {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
}

.wa-avisar-todos {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 600;
  cursor: pointer;
}

.wa-avisar input[type="checkbox"] { width: 17px; height: 17px; margin: 0; accent-color: #1fa855; flex: none; }

.wa-avisar-enviar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.wa-avisar-grupo {
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.wa-avisar-grupo header {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 12px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
}

.wa-avisar-grupo header small {
  flex-basis: 100%;
  color: var(--muted);
  font-size: calc(11.5px * var(--fs));
}

.wa-avisar-n {
  padding: 0 7px;
  border-radius: 999px;
  background: var(--panel-3);
  color: var(--muted);
  font-size: calc(11.5px * var(--fs));
  font-weight: 700;
}

.wa-avisar-fila {
  display: grid;
  grid-template-columns: auto 38px minmax(160px, 1.4fr) minmax(120px, 1fr) minmax(90px, auto) minmax(150px, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-top: 1px solid var(--line);
}

.wa-avisar-fila:first-of-type { border-top: 0; }
.wa-avisar-fila.is-off { opacity: 0.55; }

.wa-avisar-cliente {
  display: grid;
  min-width: 0;
}

.wa-avisar-cliente strong,
.wa-avisar-cliente small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wa-avisar-cliente small { color: var(--muted); font-size: calc(11.5px * var(--fs)); }

.wa-avisar-motivo {
  justify-self: start;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: calc(12px * var(--fs));
  font-weight: 600;
  white-space: nowrap;
  color: var(--amber);
  background: color-mix(in srgb, var(--amber) 13%, transparent);
}

.wa-avisar-motivo[data-tipo="suspension"] { color: var(--red); background: color-mix(in srgb, var(--red) 13%, transparent); }
.wa-avisar-motivo[data-tipo="pago"] { color: var(--green); background: color-mix(in srgb, var(--green) 13%, transparent); }

.wa-avisar-monto {
  font-weight: 700;
  text-align: right;
  white-space: nowrap;
}

.wa-avisar-ultimo .wa-cobro-ultimo { margin-top: 0; }
.wa-avisar-ultimo .muted { font-size: calc(11.5px * var(--fs)); }

.wa-avisar-vacio .wa-cobro-ico { width: 30px; height: 30px; color: #1fa855; }

/* En angosto la fila se apila: casilla y avatar a la izquierda, el resto debajo del nombre. */
@media (max-width: 900px) {
  .wa-avisar-fila {
    grid-template-columns: auto 38px minmax(0, 1fr) auto;
    row-gap: 6px;
  }
  .wa-avisar-motivo,
  .wa-avisar-monto,
  .wa-avisar-ultimo { grid-column: 3 / 4; justify-self: start; text-align: left; }
  .wa-avisar-fila > .wa-ver-btn { grid-column: 4; grid-row: 1; }
}

/* ---- Envio en lote ---- */

.wa-lote-dialog { width: min(560px, calc(100vw - 32px)); }

.wa-lote-previa { display: grid; gap: 8px; }

.wa-lote-nav {
  display: flex;
  align-items: center;
  gap: 8px;
}

.wa-lote-nav span {
  flex: 1;
  text-align: center;
  color: var(--muted);
  font-size: calc(12.5px * var(--fs));
}

.wa-lote-error { margin: 0; color: var(--red); }

.wa-lote-progreso {
  display: grid;
  gap: 6px;
  margin-top: 12px;
  font-size: calc(12.5px * var(--fs));
}

.wa-lote-progreso[hidden] { display: none; }

.wa-lote-barra {
  height: 6px;
  border-radius: 3px;
  background: var(--panel-3);
  overflow: hidden;
}

.wa-lote-barra span {
  display: block;
  width: 0;
  height: 100%;
  background: #1fa855;
  transition: width 200ms var(--ease, ease);
}

.wa-lote-lista {
  display: grid;
  gap: 2px;
  max-height: 180px;
  margin: 12px 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.wa-lote-lista li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  border-radius: 7px;
  background: var(--panel-2);
  font-size: calc(12.5px * var(--fs));
}

.wa-lote-lista li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-lote-lista small { color: var(--muted); }
.wa-lote-lista b { font-weight: 600; color: var(--muted); max-width: 220px; text-align: right; }
.wa-lote-lista li[data-estado="enviando"] b { color: var(--accent); }
.wa-lote-lista li[data-estado="ok"] b { color: var(--green); }
.wa-lote-lista li[data-estado="error"] b { color: var(--red); font-weight: 500; }

/* ---- Avisos de cobro (WhatsApp) ---- */

.wa-avisos-tools {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}

.wa-avisos-dias .select { min-height: 34px; }

.wa-avisos-tabla td { vertical-align: middle; }

.wa-avisos-cliente {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}

.wa-avisos-fecha { white-space: nowrap; }

/* Tres lineas como mucho: el texto completo queda en el title. */
.wa-avisos-error {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-width: 180px;
  max-width: 280px;
  margin-top: 4px;
  color: var(--red);
  font-size: calc(11px * var(--fs));
  line-height: 1.35;
}

.wa-avisos-acciones {
  white-space: nowrap;
  text-align: right;
}

.wa-avisos-acciones .btn + .btn { margin-left: 6px; }

/* ---- Envios y campanas ---- */

.wa-origen[data-origen="campana"] {
  color: var(--purple);
  background: color-mix(in srgb, var(--purple) 16%, transparent);
}

.wa-camp-cabeza {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 14px;
}

.wa-camp-cabeza > div:first-child {
  display: grid;
  gap: 4px;
}

.wa-camp-cabeza strong { font-size: calc(16px * var(--fs)); }
.wa-camp-cabeza .wa-link { justify-self: start; display: inline-flex; align-items: center; gap: 4px; padding: 0; }
.wa-camp-cabeza .muted { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

.wa-camp-cabeza .actions .btn,
.wa-camp-enviar {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.wa-camp-lista {
  display: grid;
  gap: 8px;
}

.wa-camp-item {
  display: grid;
  gap: 6px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.wa-camp-item:hover { border-color: var(--accent); }

.wa-camp-item-top {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.wa-camp-item-top strong { flex: 1; min-width: 160px; }
.wa-camp-item-sub { color: var(--muted); font-size: calc(12px * var(--fs)); }

.wa-camp-tipo,
.wa-camp-estado {
  padding: 1px 9px;
  border-radius: 999px;
  font-size: calc(11px * var(--fs));
  font-weight: 700;
  white-space: nowrap;
}

.wa-camp-tipo { color: var(--purple); background: color-mix(in srgb, var(--purple) 15%, transparent); }
.wa-camp-tipo[data-tipo="averia"] { color: var(--red); background: color-mix(in srgb, var(--red) 13%, transparent); }
.wa-camp-estado { color: var(--muted); background: var(--panel-3); }
.wa-camp-estado[data-estado="enviando"] { color: var(--accent); background: var(--accent-dim); }
.wa-camp-estado[data-estado="terminada"] { color: var(--green); background: color-mix(in srgb, var(--green) 13%, transparent); }

.wa-camp-progreso {
  display: grid;
  gap: 5px;
  margin-bottom: 12px;
}

.wa-camp-item .wa-camp-progreso { margin-bottom: 0; }

.wa-camp-barra {
  display: flex;
  height: 6px;
  border-radius: 3px;
  background: var(--panel-3);
  overflow: hidden;
}

.wa-camp-barra span {
  display: block;
  height: 100%;
  background: #1fa855;
  transition: width 300ms var(--ease, ease);
}

.wa-camp-barra span.is-mal { background: var(--red); }

.wa-camp-cifras {
  color: var(--muted);
  font-size: calc(12px * var(--fs));
}

.wa-camp-cifras b { color: var(--text); }
.wa-camp-cifras [data-tono="celeste"] { color: var(--wa-read); }
.wa-camp-cifras [data-tono="rojo"] { color: var(--red); }

.wa-camp-nueva {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(280px, 1fr);
  gap: 14px;
  align-items: start;
}

@media (max-width: 1100px) {
  .wa-camp-nueva { grid-template-columns: minmax(0, 1fr); }
}

.wa-camp-form {
  display: grid;
  gap: 12px;
}

.wa-camp-paso {
  display: grid;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel-2);
}

.wa-camp-paso h3 {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  font-size: calc(14px * var(--fs));
}

.wa-camp-paso h3 span {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: calc(12px * var(--fs));
}

.wa-camp-grupo {
  display: grid;
  gap: 6px;
}

.wa-camp-grupo small { font-size: calc(11.5px * var(--fs)); }

.wa-tpl-card.is-on {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.wa-camp-mapeo {
  display: grid;
  gap: 8px;
  margin-top: 4px;
}

.wa-camp-var {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr);
  gap: 8px;
  align-items: center;
}

.wa-camp-var .input { grid-column: 2; }

.wa-camp-var-n {
  display: grid;
  color: var(--accent);
  font-family: var(--mono, monospace);
  font-size: calc(12.5px * var(--fs));
}

.wa-camp-var-n small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
  font-family: inherit;
  font-size: calc(11px * var(--fs));
}

.wa-camp-elegidos {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.wa-camp-elegido {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 4px 3px 10px;
  border-radius: 999px;
  background: var(--accent-dim);
  font-size: calc(12px * var(--fs));
}

.wa-camp-elegido button {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

.wa-camp-lado {
  position: sticky;
  top: 12px;
  display: grid;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel-2);
}

.wa-camp-dest-head {
  display: grid;
  gap: 2px;
}

.wa-camp-dest-head strong { font-size: calc(15px * var(--fs)); }
.wa-camp-dest-head .muted { font-size: calc(12px * var(--fs)); }

.wa-camp-previa {
  display: grid;
  gap: 6px;
  padding: 12px;
  border-radius: 10px;
  background-color: var(--panel);
  background-image: radial-gradient(var(--grid-dot) 1px, transparent 1px);
  background-size: 16px 16px;
}

.wa-camp-previa:empty { display: none; }
.wa-camp-previa-titulo { color: var(--muted); font-size: calc(12px * var(--fs)); }
.wa-camp-previa .wa-vista-burbuja { justify-self: stretch; max-width: 100%; }

.wa-camp-dest {
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
}

.wa-camp-dest .wa-cli-hint { padding: 12px; }

.wa-camp-fila {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-top: 1px solid var(--line);
}

.wa-camp-fila:first-child { border-top: 0; }
.wa-camp-fila.is-off { opacity: 0.6; }
.wa-camp-fila.is-previa { background: var(--accent-dim); }
.wa-camp-fila input { width: 16px; height: 16px; margin: 0; accent-color: #1fa855; flex: none; }

.wa-camp-fila-ver {
  display: grid;
  flex: 1;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.wa-camp-fila-ver:disabled { cursor: default; }
.wa-camp-fila-ver strong,
.wa-camp-fila-ver small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-camp-fila-ver strong { font-size: calc(12.5px * var(--fs)); }
.wa-camp-fila-ver small { color: var(--muted); font-size: calc(11.5px * var(--fs)); }
.wa-camp-fila.is-off .wa-camp-fila-ver small { color: var(--amber); }

.wa-camp-enviar { justify-content: center; min-height: 44px; }

.wa-camp-detalle-lista {
  max-height: 520px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 10px;
}

.wa-camp-dfila {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) auto;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-top: 1px solid var(--line);
}

.wa-camp-dfila:first-child { border-top: 0; }
.wa-camp-dnombre { display: grid; min-width: 0; }
.wa-camp-dnombre strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-camp-dnombre small { color: var(--muted); font-size: calc(11.5px * var(--fs)); }
.wa-camp-destado { display: grid; justify-items: start; gap: 2px; }

@keyframes wa-toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .wa-toast { animation: none; }
}

/* Las pastillas de las sub-pestanas de WhatsApp necesitan aire arriba y abajo:
   van pegadas a la cabecera del panel y al contenido de la pestana. */
.wa-tabs {
  margin: 4px 0 14px;
}

/* El dialogo de la ficha del cliente es ancho porque lleva tablas. Este solo
   tiene un formulario: mas angosto se lee mejor y los campos no quedan
   estirados de lado a lado. */
.wa-config-dialog {
  width: min(640px, calc(100vw - 44px));
}
