:root {
  --ink: #2B2621;
  --paper: #FBF9F6;
  --card: #FFFFFF;
  --line: #E5E0D8;
  --accent: #2C7A7B;
  --accent-dark: #205C5D;
  --muted: #8A8478;
  --danger: #B4463C;
  --danger-bg: #B4463C1A;
  --warn-bg: #C9A22726;
  --radius: 10px;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--paper);
  color: var(--ink);
}
h1, h2 { margin: 0 0 4px; font-weight: 600; }
/* Icono de marca dentro de un <h2> (ej. el de GitHub en "Repositorios") —
   alineado con el texto, mismo tamaño aproximado que el texto del título. */
.card-icon { width: 18px; height: 18px; vertical-align: -3px; margin-right: 2px; }
.hidden { display: none !important; }
.hint-text { color: var(--muted); font-size: 0.88rem; line-height: 1.5; }

.app-view { min-height: 100vh; }
.tab-view { display: block; }

/* ---- Login ---- */
.login-view {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.login-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 32px;
  width: 320px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.login-card label { font-size: 0.85rem; margin-top: 6px; }
.login-card input { padding: 9px 10px; border: 1px solid var(--line); border-radius: 6px; font-size: 0.95rem; }
.login-card button { margin-top: 12px; }

/* ---- App shell ---- */
.app-header {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 14px 24px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.app-header h1 { font-size: 1.15rem; flex-shrink: 0; }
.app-brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* .app-brand ahora es un <button> (hace de "Inicio") — se resetea el
   estilo por defecto de botón nativo para que siga viéndose como el
   logo/título de siempre, con un feedback sutil de que es pulsable. */
.app-brand-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  font: inherit;
  color: inherit;
  text-align: left;
  border-radius: 8px;
  transition: opacity 0.15s;
}
.app-brand-btn:hover { opacity: 0.8; }
.app-brand-btn:focus-visible { outline: 2px solid var(--accent, #4a90d9); outline-offset: 2px; }
.app-brand-icon { width: 30px; height: 30px; border-radius: 7px; }
/* flex-basis:auto (en vez del "flex:1" de antes, que es flex-basis:0%) a
   propósito: con flex-basis:0 el nav se dejaba ENCOGER por debajo del
   ancho de "Clientes"+"Avisos" para caber junto al selector de producto y
   el botón de salir en la misma línea — el resultado era que Clientes y
   Avisos se apilaban uno encima del otro en vez de quedar en una fila.
   Con flex-basis:auto, si no cabe entero se pasa el nav ENTERO a la fila
   siguiente (como una unidad), que es el resultado que se quiere.
   order:1 (por debajo, todo lo demás en la cabecera se queda en el
   order:0 por defecto) para que, cuando no quepa todo en una fila
   (pantallas estrechas), sea SIEMPRE nav quien baje a su propia fila —
   nunca el botón de salir, que así se queda agrupado con los demás
   iconos (selector de producto/Instalaciones/Ajustes) en vez de acabar
   descolgado en medio o en una fila suelta él solo. */
.app-header nav { display: flex; gap: 6px; flex: 0 1 auto; flex-wrap: wrap; order: 1; }
.tab-btn {
  background: none; border: none; padding: 8px 14px; border-radius: 6px;
  color: var(--muted); font-size: 0.92rem; cursor: pointer; white-space: nowrap;
}
.tab-btn.active { background: var(--accent); color: white; }
.app-header nav { align-items: center; }
.tab-btn-group { display: flex; gap: 6px; flex-wrap: wrap; }

/* Selector de producto — separa con claridad los clientes de Canyon Base
   de los asientos de Kinés.io, para que no se mezclen en una sola lista.
   Visualmente distinto de las pestañas normales (más grande, con icono)
   porque es una decisión de nivel superior, no una pestaña más. */
.producto-switcher {
  display: flex;
  gap: 4px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 3px;
  flex-shrink: 0;
  flex-wrap: wrap;
}
.producto-btn {
  background: none; border: none; padding: 6px 14px; border-radius: 6px;
  color: var(--muted); font-size: 0.9rem; font-weight: 600; cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 7px;
}
.producto-icon { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.producto-btn.active { background: var(--ink); color: white; }
/* Separa visualmente "Licencias" (Canyon Base/MEDIBASE, a la izquierda)
   de "Instalaciones" y Ajustes (a la derecha) dentro de la misma barra —
   sin esto, "Instalaciones" parecía un tercer botón de producto más,
   cuando en realidad es una sección totalmente distinta (máquinas
   físicas y paquetes, no clientes/licencias). */
.switcher-divider { width: 1px; align-self: stretch; background: var(--line); margin: 2px 2px; }
.icon-only-tab-btn {
  font-size: 1.05rem;
  padding: 6px 10px;
  border-radius: 6px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--muted);
  line-height: 1;
}
.icon-only-tab-btn.active { background: var(--ink); color: white; }
.icon-only-tab-btn:hover { background: var(--bg); }
.icon-only-tab-btn.active:hover { background: var(--ink); }

.badge-count {
  display: inline-block;
  background: var(--danger, #C0392B);
  color: white;
  font-size: 0.72rem;
  font-weight: 700;
  border-radius: 999px;
  padding: 1px 6px;
  margin-left: 4px;
}

main { padding: 20px 24px; max-width: 900px; margin: 0 auto; }

@media (max-width: 640px) {
  .app-header { padding: 12px 16px; gap: 12px; }
  main { padding: 16px; }
  /* El selector "🏠 Inicio / Canyon Base / Kinés.io / ⚙️" no cabe con
     texto completo en una pantalla de móvil — se deja solo el icono
     (con el nombre como tooltip vía "title", ver index.html) en vez de
     dejar que desborde la fila y descuadre toda la cabecera. */
  .btn-label { display: none; }
  .producto-btn { padding: 6px 10px; }
  .producto-btn .producto-icon { margin: 0; }
}

@media (max-width: 480px) {
  /* Pantallas muy estrechas: las tarjetas del Inicio (resumen) pasan a
     una sola columna y los números grandes de las "stat tiles" (activas,
     caducadas, importes...) se reducen un poco para que quepan siempre,
     aunque el importe sea largo (ej. "1.234,56 €"). */
  .dashboard-grid { grid-template-columns: 1fr; }
  .stat-tile { flex-basis: 46%; padding: 10px 6px; }
  .stat-number { font-size: 1.2rem; }
}

/* ---- Buttons ---- */
button { font-family: inherit; cursor: pointer; }
.btn-primary {
  background: var(--accent); color: white; border: none;
  padding: 9px 16px; border-radius: 6px; font-size: 0.92rem; font-weight: 500;
}
.btn-primary:hover { background: var(--accent-dark); }
.btn-outline {
  background: none; border: 1px solid var(--line); color: var(--ink);
  padding: 8px 14px; border-radius: 6px; font-size: 0.9rem;
}
.btn-ghost { background: none; border: none; color: var(--muted); padding: 8px 12px; font-size: 0.9rem; }
.btn-danger {
  background: var(--danger); color: white; border: none;
  padding: 9px 16px; border-radius: 6px; font-size: 0.92rem;
}
.icon-btn { background: none; border: none; font-size: 1.3rem; color: var(--muted); cursor: pointer; line-height: 1; }

/* #logout-btn: antes era un botón de texto ("Salir") que, en móvil,
   se quedaba solo en su propia fila de la cabecera (esta es de flex-wrap,
   así que cada fila la deciden los anchos reales) — con un icono en vez
   de texto ocupa mucho menos y suele caber en la misma fila que Clientes/
   Avisos. margin-left:auto lo ancla siempre al borde derecho de la fila
   en la que termine cayendo, en vez de quedar pegado justo después del
   último botón de pestaña. */
#logout-btn {
  padding: 8px 10px;
  border-radius: 6px;
  margin-left: auto;
  flex-shrink: 0;
}
#logout-btn:hover { background: var(--bg); color: var(--ink); }

/* .token-value — el token de enrolamiento (32 bytes en hex = 64
   caracteres) es más ancho que cualquier tarjeta en móvil. Antes era un
   <code> puramente inline, sin ancho máximo ni forma de partir la línea,
   así que ese texto largo desbordaba su contenedor y arrastraba a TODA
   la página a scroll horizontal (visto de verdad en una captura del
   cliente en Android) — con display:block + max-width:100% +
   overflow-wrap:anywhere queda enmarcado en su propia caja, partiendo el
   texto si hace falta, sin que nada de alrededor se vea afectado. */
.token-value {
  display: block;
  max-width: 100%;
  box-sizing: border-box;
  margin-top: 6px;
  padding: 8px 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  font-family: monospace;
  font-size: 0.82rem;
  overflow-wrap: anywhere;
  word-break: break-all;
}

/* ---- Toolbar / lists ---- */
.module-toolbar { display: flex; gap: 10px; margin-bottom: 16px; align-items: center; flex-wrap: wrap; }
.module-toolbar input { flex: 1; min-width: 160px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 6px; }

.cliente-row {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; margin-bottom: 10px;
  display: flex; align-items: center; gap: 14px; cursor: pointer; flex-wrap: wrap;
}
.cliente-row:hover { border-color: var(--accent); }
.cliente-main { flex: 1; min-width: 0; }
.cliente-main strong { display: block; font-size: 1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cliente-meta { color: var(--muted); font-size: 0.83rem; margin-top: 2px; }
.cliente-codigo { font-family: monospace; font-size: 0.8rem; color: var(--muted); }

.badge {
  display: inline-block; padding: 3px 10px; border-radius: 100px; font-size: 0.78rem; font-weight: 600;
}
.badge-activa { background: #2C7A7B1A; color: var(--accent-dark); }
.badge-revocada { background: var(--danger-bg); color: var(--danger); }
.badge-caducada { background: var(--warn-bg); color: #8A6B10; }
.badge-sin_licencia { background: #8A84781A; color: var(--muted); }

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

/* ---- Modals ---- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(43,38,33,0.4);
  display: flex; align-items: center; justify-content: center; z-index: 100; padding: 16px;
}
/* Modales de "segundo nivel" — se abren COMO ACCIÓN desde dentro de otro
   modal ya abierto (emitir/renovar, confirmar una acción). Con el mismo
   z-index que el resto, quién queda encima dependía del orden en el HTML
   — y "duracion-modal" está declarado ANTES que "asiento-detail-modal",
   así que al abrirlo desde ahí quedaba TAPADO por él (parecía que no
   pasaba nada al pulsar "Emitir", hasta cerrar el modal de detalle, que
   lo dejaba al descubierto). Con un z-index explícito más alto, quedan
   siempre encima sin importar el orden en el documento. */
#duracion-modal, #confirm-modal { z-index: 200; }
.modal-card {
  background: var(--card); border-radius: var(--radius); width: 480px; max-width: 100%;
  max-height: 88vh; display: flex; flex-direction: column; overflow: hidden;
}
.modal-narrow { width: 380px; }
.modal-header {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 16px 20px; border-bottom: 1px solid var(--line);
}
.modal-header h2 { font-size: 0.95rem; letter-spacing: 0.03em; color: var(--muted); }
.modal-body { padding: 18px 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; }
.modal-body label { font-size: 0.85rem; font-weight: 500; margin-top: 4px; }
.modal-body input, .modal-body select, .modal-body textarea {
  padding: 9px 10px; border: 1px solid var(--line); border-radius: 6px; font-size: 0.95rem; font-family: inherit; width: 100%;
}
.modal-footer {
  display: flex; justify-content: flex-end; gap: 10px; padding: 14px 20px; border-top: 1px solid var(--line); flex-wrap: wrap;
}

.error-box { background: var(--danger-bg); color: var(--danger); padding: 8px 12px; border-radius: 6px; font-size: 0.87rem; }
.saved-msg { color: var(--accent-dark); font-size: 0.85rem; }

/* ---- Settings ---- */
/* Subpestañas dentro de Ajustes (Empresa / Configuración / Caducidad /
   Claves / Versión) y dentro de Clientes de Kinés.io (Clientes / Asientos
   / Solicitudes) — mismo patrón visual "compact" que ya usa Kinés.io para
   Sistema -> Licencia/Backup/Versión, adaptado a los colores del panel.
   Con 5 subpestañas (desde que se añadió "Caducidad"), en una pantalla
   estrecha ya no cabían todas — confirmado renderizando de verdad: se
   cortaba "Claves" y "Versión" quedaba fuera de la pantalla, invisible e
   inaccesible. overflow-x:auto deja deslizar horizontalmente en vez de
   forzarlas a encogerse (perdería legibilidad) o partir la fila en dos
   líneas (empujaría el contenido de abajo de forma inconsistente según
   cuántas subpestañas tenga cada sitio). */
.subtabs { display: flex; gap: 4px; margin-bottom: 16px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.subtab {
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 14px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
}
.subtab:hover { color: var(--ink); }
.subtab.active { background: var(--accent); color: white; border-color: var(--accent); }

.checkbox-row {
  display: flex; align-items: center; gap: 8px;
  font-weight: 600; cursor: pointer; margin-top: 4px;
}
.checkbox-row input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; }
.mini-label { display: block; font-size: 0.8rem; color: var(--muted); margin: 6px 0 2px; }
/* Icono pequeño de la app a la izquierda del encabezado de cada grupo
   (dentro de la tarjeta de máquina) — ".mini-label" en general sigue
   siendo "display:block" (se reutiliza para etiquetas de texto sueltas
   en muchos otros sitios); esta variante con clase extra ".app-group-label"
   es la única que pasa a fila flex para alinear el icono con el texto. */
.mini-label.app-group-label { display: flex; align-items: center; gap: 6px; }
.app-group-icon { width: 16px; height: 16px; border-radius: 4px; object-fit: cover; flex-shrink: 0; }
.app-group-icon-emoji { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; font-size: 0.85rem; line-height: 1; flex-shrink: 0; }

/* Grupos colapsables de Configuración (CLAVES / NOTIFICACIONES / SISTEMA) —
   demasiadas settings-card sueltas en una lista plana, sin ninguna
   jerarquía visual. Nativo <details>/<summary> en vez de JS a medida: se
   abre/cierra solo, con teclado y sin listener extra. */
.settings-group {
  border: 1px solid var(--line); border-radius: var(--radius);
  margin-bottom: 16px; overflow: hidden;
}
.settings-group summary {
  list-style: none; cursor: pointer; user-select: none;
  padding: 14px 18px; font-weight: 600; font-size: 1rem;
  display: flex; align-items: center; gap: 8px;
  background: var(--card);
}
.settings-group summary::-webkit-details-marker { display: none; }
.settings-group summary::after {
  content: "▸"; margin-left: auto; color: var(--muted); font-size: 0.8rem;
  transition: transform 0.15s ease;
}
.settings-group[open] summary::after { transform: rotate(90deg); }
.settings-group summary:hover { color: var(--accent-dark); }
.settings-group-body { padding: 4px 16px 16px; }
.settings-group .settings-card:last-child { margin-bottom: 0; }
.settings-subgroup-label {
  display: flex; align-items: center; gap: 6px;
  margin: 18px 0 10px; font-size: 0.78rem; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted);
}
.settings-subgroup-label:first-child { margin-top: 6px; }

.settings-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px 20px; margin-bottom: 16px;
}
.settings-card label { display: block; font-size: 0.85rem; font-weight: 500; margin-top: 12px; margin-bottom: 4px; }
.settings-card > input, .settings-card > select, .settings-card > textarea {
  padding: 9px 10px; border: 1px solid var(--line); border-radius: 6px; font-size: 0.95rem; font-family: inherit; width: 100%;
}
.danger-card { border-color: var(--danger-bg); }

.solo-lectura-banner {
  background: var(--warn-bg); color: #8A6B10; text-align: center;
  padding: 8px 16px; font-size: 0.85rem; font-weight: 500;
}

/* Toast "nueva versión disponible" — ver checkForNewVersion() en app.js.
   Flotante, esquina inferior derecha, para no desplazar el resto del
   contenido de la página como sí hace .solo-lectura-banner (que empuja
   la cabecera hacia abajo, apropiado para un aviso permanente pero no
   para uno puntual como este). */
.nueva-version-toast {
  position: fixed; right: 16px; bottom: 16px; z-index: 50;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  padding: 12px 14px; max-width: 320px;
  display: flex; flex-direction: column; gap: 10px;
  font-size: 0.88rem;
}
.nueva-version-toast-actions { display: flex; align-items: center; justify-content: flex-end; gap: 4px; }
.nueva-version-toast-actions .btn-primary { padding: 6px 14px; font-size: 0.85rem; }

/* Gestión de usuarios y credenciales de backup no son cosa de una cuenta
   de solo lectura — el backend ya las rechaza (requireAdmin, ver auth.js),
   esto solo evita mostrar la subpestaña a quien no puede usarla de todos
   modos. Misma clase "role-lectura" en <body> que ya pone applyRoleUI(). */
.role-lectura .admin-only { display: none; }

/* ---------------- Dashboard (Inicio) ---------------- */
.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0;
  align-items: start;
}
.dashboard-grid .settings-card { margin-bottom: 0; }
.stat-tile-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.stat-tile {
  flex: 1 1 100px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 10px; text-align: center;
}
.stat-tile.stat-ok { border-color: var(--accent); }
.stat-tile.stat-warn { border-color: #C9A227; }
.stat-tile.stat-danger { border-color: var(--danger); }
.stat-number { font-size: 1.5rem; font-weight: 700; line-height: 1.1; }
.stat-tile.stat-ok .stat-number { color: var(--accent-dark); }
.stat-tile.stat-warn .stat-number { color: #8A6B10; }
.stat-tile.stat-danger .stat-number { color: var(--danger); }
.stat-label { font-size: 0.78rem; color: var(--muted); margin-top: 2px; }
.version-detail-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 0.9rem; }
.version-detail-row:last-child { border-bottom: none; }
.version-detail-row span { color: var(--muted, #888); }
.adventurebase-logo { max-width: 220px; width: 100%; height: auto; display: block; margin: 16px 0 6px; }
.field-row { display: flex; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.field-row input {
  flex: 1;
  /* Sin esto, un <input> en flex:1 no se encoge por debajo de su ancho
     nativo (~199px) — es el mismo bug ya documentado más abajo para
     ".field-row.plain > div input", pero esa regla solo cubre inputs
     envueltos en un <div> por columna. La fila de "Zonas" (Nombre + País
     + botón Añadir) tiene los <input> como hijos directos de
     .field-row.plain, así que necesitaba su propio min-width:0 — sin él,
     la fila entera (y con ella toda la página) se desbordaba
     horizontalmente en móvil. flex-wrap arriba es el resguardo final: si
     aun así no cupiera todo en una fila (pantallas muy estrechas), el
     botón pasa a su propia línea en vez de forzar scroll horizontal. */
  min-width: 0;
  padding: 9px 10px; border: 1px solid var(--line); border-radius: 6px; font-family: monospace;
}
.field-row.plain input, .field-row.plain select { font-family: inherit; }
.field-row.plain > div input, .field-row.plain > div select {
  /* Sin esto, un <input> usa su ancho nativo del navegador (~199px) en
     vez del que le da su columna flexible — medido de verdad: en una
     fila de dos columnas en móvil, esto hacía que la fila entera
     midiera 445px en una pantalla de 390px, cortando la segunda columna
     (Ciudad, Provincia, etc.) fuera de la pantalla. */
  width: 100%;
  box-sizing: border-box;
}

.section-divider { margin: 18px 0 4px; padding-top: 14px; border-top: 1px solid var(--line); }
.section-divider span { font-size: 0.78rem; letter-spacing: 0.05em; color: var(--muted); font-weight: 600; }

.logo-row { display: flex; align-items: center; gap: 14px; margin: 10px 0 16px; flex-wrap: wrap; }
.logo-preview {
  width: 90px; height: 90px; min-width: 90px; flex-shrink: 0; border: 1px dashed var(--line); border-radius: 8px;
  /* Sin flex-shrink:0, en una pantalla estrecha esta caja se aplastaba
     para dejarle sitio al selector de archivo (llegó a medir 49px de
     ancho en vez de 90 — confirmado midiéndolo de verdad), y con la
     imagen del logo rota dentro (si el archivo daba 404) parecía solo
     una raya vertical punteada, no un recuadro. flex-wrap en .logo-row
     además deja que el selector de archivo baje a su propia línea en
     vez de seguir empujando la caja. */
  display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--paper);
  font-size: 0.75rem; color: var(--muted); text-align: center;
}
.logo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }

.factura-row {
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 10px 12px; margin-bottom: 8px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.factura-main { flex: 1; min-width: 0; }
.factura-numero { font-family: monospace; font-weight: 600; }
.factura-estado { font-size: 0.75rem; padding: 0.1rem 0.5rem; border-radius: 4px; font-weight: 600; }
.factura-estado-emitida { background: #2C7A7B1A; color: #205C5D; }
.factura-estado-rectificada { background: #8A84781A; color: #8A8478; }
.factura-estado-rectificativa { background: #C9A22726; color: #92650B; }
#clave-publica-box {
  width: 100%; font-family: monospace; font-size: 0.8rem; padding: 10px;
  border: 1px solid var(--line); border-radius: 6px; margin-top: 10px; resize: vertical; background: var(--paper);
}
.token-box-wrap { margin-top: 10px; }
.token-box {
  width: 100%; font-family: monospace; font-size: 0.78rem; padding: 10px;
  border: 1px solid var(--line); border-radius: 6px; resize: vertical; background: var(--paper);
  box-sizing: border-box; margin-bottom: 6px;
  max-height: 260px; overflow-y: auto; /* por si aun con 8 filas el token es más largo (vitalicia, etc.) */
}
.danger-card button { margin-top: 10px; }

/* ---- Client detail ---- */
.detail-section { margin-bottom: 16px; }
.detail-section h3 { font-size: 0.85rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 8px; }
.detail-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; align-items: center; }

/* Botones de acción con icono SVG (renovar/emitir, revocar, liberar
   instalación, enviar email, editar, eliminar) en las fichas de cliente
   y de asiento/licencia, y ".accion-cluster" para agrupar bien apretadas
   las acciones que pertenecen a UNA misma licencia/asiento — antes eran
   botones de texto sueltos, repartidos por toda la ficha. Ver
   `iconActionBtn()` en app.js. */
.accion-cluster { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.icon-action-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; flex-shrink: 0;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--card); color: var(--ink); cursor: pointer;
}
.icon-action-btn:hover { border-color: var(--accent); color: var(--accent-dark); }
.icon-action-btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.icon-action-btn.primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); }
/* Acciones destructivas (revocar, eliminar) llevan su propio color rojo
   a propósito — un botón sin texto visible es más fácil de pulsar por
   error si no se distingue claramente de una acción inocua. */
.icon-action-btn.danger { border-color: var(--danger); color: var(--danger); background: var(--danger-bg); }
.icon-action-btn.danger:hover { background: var(--danger); color: #fff; }
.icon-action-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.icon-action-btn:disabled:hover { border-color: var(--line); color: var(--ink); background: var(--card); }
/* Sin esto, un clic dispara el evento con e.target apuntando al <svg>/
   <path> interno en vez de al propio <button> — rompería cualquier
   handler que lea e.target en vez de e.currentTarget. */
.icon-action-btn svg { pointer-events: none; }
.evento-row { padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 0.88rem; }
.evento-row:last-child { border-bottom: none; }
.evento-tipo { font-weight: 600; text-transform: capitalize; }
.evento-fecha { color: var(--muted); font-size: 0.8rem; }
