/* Lynkeus · Componentes compartidos (esqueleto canónico de las vistas ABM).
 * Reemplaza los bloques que antes se duplicaban por página con distinto prefijo
 * (.usr-*, .rol-*, .plt-*, .param-*, .tenant-*, .rlp-*). Una sola definición aquí.
 * Cargar DESPUÉS de app.css. */

/* ── Encabezado de página ─────────────────────────────────────────── */
.lyk-page-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    margin-bottom: var(--lyk-space-7);
    gap: var(--lyk-space-5);
    flex-wrap: wrap;
}
.lyk-page-header__eyebrow-row { display: flex; align-items: center; gap: var(--lyk-space-3); margin-bottom: var(--lyk-space-2); }
.lyk-page-header__title { font-size: 26px; font-weight: 600; letter-spacing: -0.02em; color: var(--lyk-color-ink-1); margin: 0 0 var(--lyk-space-2); }
.lyk-page-header__subtitle { margin: 0; color: var(--lyk-color-ink-3); font-size: var(--lyk-text-base); max-width: 640px; }

.lyk-online-only {
    display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
    border-radius: var(--lyk-radius-sm); background: var(--lyk-color-danger-soft); color: var(--lyk-color-danger-strong);
    font-family: var(--lyk-font-mono); font-size: 10px; font-weight: 600; letter-spacing: 0.08em;
}

.btn-icon-label { display: inline-flex; align-items: center; gap: var(--lyk-space-2); }

/* ── Banner de error (con correlation_id + copiar) ────────────────── */
.lyk-error-banner {
    background: var(--lyk-color-danger-soft); border: 1px solid var(--lyk-color-danger-border); border-radius: var(--lyk-radius-sm);
    color: var(--lyk-color-danger); padding: var(--lyk-space-4) var(--lyk-space-5); margin-bottom: var(--lyk-space-5);
    display: flex; align-items: center; justify-content: space-between; gap: var(--lyk-space-4);
}
.lyk-error-banner__title { font-size: var(--lyk-text-base); font-weight: 500; }
.lyk-error-banner__meta { font-size: var(--lyk-text-sm); color: var(--lyk-color-ink-2); margin-top: 2px; }
.lyk-copy-id { border: 1px solid var(--lyk-color-border-strong); background: var(--lyk-color-surface); border-radius: var(--lyk-radius-sm); padding: 0 10px; height: 30px; font-size: var(--lyk-text-sm); cursor: pointer; }

/* ── Tarjeta de filtros ───────────────────────────────────────────── */
.lyk-filter-card {
    background: var(--lyk-color-surface); border: 1px solid var(--lyk-color-border);
    border-radius: var(--lyk-radius-md); padding: var(--lyk-space-5); margin-bottom: var(--lyk-space-7);
}
.lyk-filter-card--disabled { opacity: 0.55; pointer-events: none; }
.lyk-filter-card__header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--lyk-space-5); }
.lyk-filter-clear { border: none; background: transparent; color: var(--lyk-color-ink-3); font-family: var(--lyk-font-mono); font-size: var(--lyk-text-xs); letter-spacing: 0.08em; cursor: pointer; }
.lyk-filter-grid { display: grid; gap: var(--lyk-space-4); align-items: end; }
.lyk-filter-field { display: flex; flex-direction: column; gap: var(--lyk-space-2); }
.lyk-filter-label { font-size: var(--lyk-text-sm); color: var(--lyk-color-ink-2); font-weight: 500; }
.lyk-input { width: 100%; }
/* El DatePicker de Kendo no recibía el mismo font-size que TextBox/DropDownList y, como Kendo
   dimensiona en em, quedaba ~10px más bajo que sus vecinos de la misma fila (se veía desalineado
   en cualquier barra de filtros que mezcle ambos). Se normalizan tamaño de texto y alto de control. */
.lyk-input.k-datepicker { font-size: var(--lyk-text-base); }
.lyk-input.k-input,
.lyk-input.k-picker { min-height: 36px; }

/* .lyk-input se usa en DOS cosas: los componentes Telerik (que renderizan un <span> y traen su
   propio estilo) y los <input>/<textarea> nativos de los modales. A los nativos no los estilaba
   nadie: quedaban con el aspecto por defecto del navegador (21px de alto) al lado de controles
   Kendo de 36px. Se les da el mismo aspecto; el selector va por elemento para NO tocar Telerik. */
input.lyk-input,
textarea.lyk-input,
select.lyk-input {
    box-sizing: border-box;
    width: 100%;
    min-height: 36px;
    padding: 0 10px;
    background: var(--lyk-color-surface);
    color: var(--lyk-color-ink-1);
    border: 1px solid var(--lyk-color-border);
    border-radius: var(--lyk-radius-sm);
    font-family: var(--lyk-font-sans);
    font-size: var(--lyk-text-base);
    outline: none;
}
textarea.lyk-input { padding: 8px 10px; line-height: 1.5; resize: vertical; }
input.lyk-input:focus,
textarea.lyk-input:focus,
select.lyk-input:focus { border-color: var(--lyk-color-primary); box-shadow: var(--lyk-shadow-focus); }
input.lyk-input::placeholder,
textarea.lyk-input::placeholder { color: var(--lyk-color-ink-4); }
input.lyk-input:disabled,
textarea.lyk-input:disabled { background: var(--lyk-color-surface-2); color: var(--lyk-color-ink-4); }

/* ── Contenedor de grilla ─────────────────────────────────────────── */
/* overflow-x: auto — NO hidden. En pantallas angostas la grilla es más ancha que su contenedor y
   con `hidden` las columnas de la derecha (típicamente "Acciones") quedaban recortadas y sin forma
   de alcanzarlas: no había scroll horizontal. Afecta a las 9 páginas con grilla.
   El eje vertical sigue en hidden para conservar el recorte del border-radius. */
.lyk-grid-wrapper { background: var(--lyk-color-surface); border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-md); overflow-x: auto; overflow-y: hidden; }
.lyk-grid__count { color: var(--lyk-color-ink-2); font-size: var(--lyk-text-base); }

/* ── Grillas en pantallas angostas ────────────────────────────────────────────
   Recomendación oficial de Telerik para grillas cuyas columnas NO declaran Width:
   fijar un min-width en la tabla. Así las columnas conservan un ancho legible y la
   grilla muestra scroll horizontal cuando la pantalla es más angosta, en vez de
   comprimir todas las columnas hasta volverlas ilegibles.
   https://www.telerik.com/blazor-ui/documentation/knowledge-base/grid-horizontal-scrolling-no-column-widths

   Se descartó `overflow-wrap: anywhere`: quebraba las palabras por la mitad y hacía
   filas altísimas, que es peor de leer que el scroll horizontal.

   700px está elegido a medida: es lo máximo que entra sin scroll en el área de contenido a
   768px (709px medidos), así que en tablet y desktop las grillas simples siguen entrando
   completas, y el scroll sólo aparece en teléfonos — que es donde comprimir 6 columnas en
   331px las volvía ilegibles. Las grillas anchas (tenants, bots, ejecuciones) superan este
   mínimo por su propio contenido. */
.lyk-grid .k-table { min-width: 700px; }

/* Telerik ya trae overflow:hidden + text-overflow:ellipsis en las celdas, pero la elipsis
   NUNCA se aplica porque white-space queda en `normal`. Con `nowrap` la elipsis empieza a
   funcionar: la fila queda de una línea y el texto largo termina en "…" en vez de cortarse
   en seco. El valor completo se ofrece con `title` en las celdas que lo necesitan. */
.lyk-grid .k-table td { white-space: nowrap; }

/* La elipsis sólo la dibuja el elemento que contiene el texto. Varias celdas apilan el dato en
   <div> internos (nombre + email, por ejemplo): sin esto el div desborda y lo recorta el td,
   otra vez sin "…". */
.lyk-grid .k-table td > div { overflow: hidden; text-overflow: ellipsis; }

/* Estado vacío / "aún no buscó" — lo pinta <LykEmptyFilter/>, que es el único que debe usarlo.
   La caja del icono estaba sólo en la copia de Tenants (.tenants-empty__icon-box): se sube aquí para
   que las nueve pantallas con filtros muestren el mismo bloque y no tres variantes distintas. */
.lyk-empty {
    background: var(--lyk-color-surface); border: 1px dashed var(--lyk-color-border-strong);
    border-radius: var(--lyk-radius-md); padding: 64px 32px; text-align: center;
    display: flex; flex-direction: column; align-items: center; gap: var(--lyk-space-4);
}
.lyk-empty__icon {
    width: 56px; height: 56px; border-radius: var(--lyk-radius-md);
    border: 1px solid var(--lyk-color-border); background: var(--lyk-color-surface-2);
    display: flex; align-items: center; justify-content: center; color: var(--lyk-color-ink-3);
}
.lyk-empty__title { margin: 0; font-size: var(--lyk-text-lg); font-weight: 600; }
.lyk-empty__msg { margin: 0; color: var(--lyk-color-ink-3); max-width: 460px; }

/* ── Acciones de fila (icon buttons) ──────────────────────────────── */
/* align-items: center porque la fila mezcla alturas: el icon button mide 30px y un LykButton
   Size="sm" mide 28px. Sin esto quedaban al ras arriba y desparejos abajo (Programaciones). */
.lyk-actions { display: flex; align-items: center; justify-content: center; gap: 4px; }
.lyk-icon-btn {
    width: 30px; height: 30px; border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-sm);
    background: var(--lyk-color-surface); color: var(--lyk-color-ink-3);
    display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
.lyk-icon-btn:hover:not(:disabled) { background: var(--lyk-color-canvas); color: var(--lyk-color-ink-1); }
.lyk-icon-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.lyk-icon-btn--danger:hover:not(:disabled) { color: var(--lyk-color-danger); background: var(--lyk-color-danger-soft); }

/* ── Modal / diálogo ──────────────────────────────────────────────── */
.lyk-modal-backdrop { position: fixed; inset: 0; background: var(--lyk-color-scrim); z-index: 400; display: flex; align-items: center; justify-content: center; padding: 24px; }
/* El diálogo NO scrollea completo: scrollea sólo el cuerpo, para que el footer con el botón
   primario quede siempre visible (antes, en formularios largos, "Crear tenant" se iba de vista).
   dvh evita además que la barra de URL de iOS recorte el footer (mobile-first, §13). */
.lyk-modal {
    width: min(560px, 100%);
    background: var(--lyk-color-surface); border-radius: var(--lyk-radius-md); box-shadow: var(--lyk-shadow-lg);
    max-height: calc(100vh - 48px);
    max-height: calc(100dvh - 48px);
    display: flex; flex-direction: column; overflow: hidden;
}
/* EditForm renderiza un <form> entre el modal y el cuerpo/footer: hay que encadenarle el flex. */
.lyk-modal > form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
.lyk-dialog-header, .lyk-confirm-header,
.lyk-dialog-footer, .lyk-confirm-footer { flex: 0 0 auto; }
.lyk-dialog-body, .lyk-confirm-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.lyk-modal--sm { width: min(460px, 100%); }
.lyk-modal--md { width: min(560px, 100%); }
.lyk-modal--lg { width: min(620px, 100%); }
.lyk-modal--xl { width: min(760px, 100%); }
/* Modo agrandado (botón ⤢ de LykModal): casi toda la ventana, pero se deja el margen del backdrop
   para que siga leyéndose como diálogo y no como página. El tope evita que en un monitor ancho las
   líneas de JSON queden ilegiblemente largas. */
.lyk-modal--full { width: min(1400px, calc(100vw - 48px)); height: calc(100dvh - 48px); }
/* Con el modal agrandado, los bloques de código dejan de ser una ventanita de 260px: el que manda
   es el alto disponible y el scroll queda en el cuerpo del diálogo. */
.lyk-modal--full .ejec-detalle__body { max-height: none; }

.lyk-dialog-actions { display: flex; align-items: center; gap: 4px; }

.lyk-dialog-header { padding: 20px 28px; border-bottom: 1px solid var(--lyk-color-divider); display: flex; align-items: center; justify-content: space-between; }
.lyk-dialog-title { margin: 6px 0 0; font-size: var(--lyk-text-xl); font-weight: 600; }
.lyk-dialog-close { width: 32px; height: 32px; border: none; background: transparent; color: var(--lyk-color-ink-3); border-radius: var(--lyk-radius-sm); cursor: pointer; }
.lyk-dialog-close:hover { background: var(--lyk-color-surface-2); }
.lyk-dialog-body { padding: 24px 28px; display: grid; gap: var(--lyk-space-5); }
.lyk-dialog-footer { border-top: 1px solid var(--lyk-color-divider); padding: 14px 28px; display: flex; justify-content: flex-end; gap: var(--lyk-space-3); }
.lyk-dialog-footer__left { margin-right: auto; display: flex; align-items: center; color: var(--lyk-color-ink-3); font-size: var(--lyk-text-sm); }

/* Variante de confirmación (icono + título + texto) */
.lyk-confirm-header { padding: 22px 28px 16px; border-bottom: 1px solid var(--lyk-color-divider); display: flex; gap: var(--lyk-space-4); }
.lyk-confirm-header h3 { margin: 0 0 4px; font-size: var(--lyk-text-md); }
.lyk-confirm-header p, .lyk-confirm-body p { margin: 0; color: var(--lyk-color-ink-3); font-size: var(--lyk-text-sm); line-height: 1.6; }
.lyk-confirm-icon { width: 40px; height: 40px; border-radius: 999px; background: var(--lyk-color-warning-soft); color: var(--lyk-color-warning-strong); display: flex; align-items: center; justify-content: center; font-weight: 700; flex-shrink: 0; }
.lyk-confirm-body { padding: 22px 28px; }
.lyk-confirm-footer { border-top: 1px solid var(--lyk-color-divider); padding: 14px 28px; display: flex; justify-content: flex-end; gap: var(--lyk-space-3); }

/* ── Campos de formulario ─────────────────────────────────────────── */
.lyk-field { display: flex; flex-direction: column; gap: var(--lyk-space-2); }
.lyk-field__label { font-size: var(--lyk-text-sm); color: var(--lyk-color-ink-2); font-weight: 500; }
.lyk-field__req { color: var(--lyk-color-danger); }
.lyk-field__error { color: var(--lyk-color-danger); font-size: var(--lyk-text-xs); margin: 0; }
.lyk-form-banner { background: var(--lyk-color-danger-soft); border: 1px solid var(--lyk-color-danger-border); border-radius: var(--lyk-radius-sm); color: var(--lyk-color-danger); padding: 10px 12px; font-size: var(--lyk-text-sm); }
/* Variante INFORMATIVA: el banner base es rojo (advertencia). Un texto que sólo explica cómo
   funciona la pantalla no debe leerse como un error. */
.lyk-form-banner--info { background: var(--lyk-color-info-soft); border-color: var(--lyk-color-info-border); color: var(--lyk-color-info-strong); }

/* Estado de error a nivel de CONTROL (además del texto del <ValidationMessage>): el usuario ve
   qué casillero está mal, no sólo el mensaje. Telerik pone el Class del componente en su <span>
   raíz (.k-input / .k-picker), que es quien lleva el borde. components.css carga DESPUÉS del tema
   Telerik (index.html), por eso alcanza sin !important; si algún día se invierte el orden, hará falta. */
.lyk-input--error,
.lyk-input--error.k-input,
.lyk-input--error.k-picker { border-color: var(--lyk-color-danger); }
.lyk-input--error.k-input:focus-within,
.lyk-input--error.k-picker:focus-within { box-shadow: 0 0 0 3px var(--lyk-color-danger-soft); }
.lyk-form-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--lyk-space-5); }
.lyk-check { display: flex; align-items: center; gap: var(--lyk-space-3); color: var(--lyk-color-ink-2); font-size: var(--lyk-text-base); cursor: pointer; }

@media (max-width: 900px) {
    .lyk-form-grid-2 { grid-template-columns: 1fr; }
}

/* --- Integraciones · API Keys --- */
.lyk-field__hint { color: var(--lyk-color-ink-2); font-size: var(--lyk-text-xs); margin: 6px 0 0; }
.apikey-secret-box { display: flex; align-items: center; gap: var(--lyk-space-3); background: var(--lyk-color-surface-2, rgba(0,0,0,.04)); border: 1px solid var(--lyk-color-border, rgba(0,0,0,.12)); border-radius: var(--lyk-radius-sm); padding: 10px 12px; }
.apikey-secret { flex: 1; font-family: var(--lyk-font-mono, ui-monospace, monospace); font-size: var(--lyk-text-sm); word-break: break-all; color: var(--lyk-color-ink-1, inherit); }

/* --- Plataforma · Bots por tenant --- */
.tb-sub { font-size: var(--lyk-text-xs); opacity: .7; }
.tb-filter-grid { display: grid; grid-template-columns: 1fr 180px auto; gap: var(--lyk-space-4); align-items: end; }
.tb-selected { display: flex; align-items: center; justify-content: space-between; gap: var(--lyk-space-4); background: var(--lyk-color-surface-2, rgba(0,0,0,.03)); border: 1px solid var(--lyk-color-border, rgba(0,0,0,.12)); border-radius: var(--lyk-radius-sm); padding: 12px 14px; margin-bottom: var(--lyk-space-4); }
.tb-selected__name { margin-top: 2px; }
@media (max-width: 900px) { .tb-filter-grid { grid-template-columns: 1fr; } }
.tenantbots-impact { margin-top: var(--lyk-space-3); background: var(--lyk-color-danger-soft); border: 1px solid var(--lyk-color-danger-border, rgba(0,0,0,.12)); border-radius: var(--lyk-radius-sm); padding: 10px 12px; font-size: var(--lyk-text-sm); color: var(--lyk-color-danger); }
.tenantbots-impact--ok { background: var(--lyk-color-success-soft); border-color: var(--lyk-color-success-border, rgba(0,0,0,.12)); color: var(--lyk-color-success); }
.botlog { display: flex; flex-direction: column; gap: var(--lyk-space-3); max-height: 440px; overflow-y: auto; }
.botlog__item { border: 1px solid var(--lyk-color-border, rgba(0,0,0,.12)); border-radius: var(--lyk-radius-sm); padding: 10px 12px; }
.botlog__row { display: flex; align-items: center; justify-content: space-between; gap: var(--lyk-space-3); }
.botlog__fecha { font-size: var(--lyk-text-xs); opacity: .8; }
.botlog__meta { margin-top: 4px; font-size: var(--lyk-text-sm); color: var(--lyk-color-ink-2); display: flex; gap: 6px; flex-wrap: wrap; }
.botlog__detalle { margin-top: 4px; font-size: var(--lyk-text-xs); color: var(--lyk-color-ink-2); }

/* Barra de filtros (grilla de ejecuciones) */
.lyk-filter-bar { display: flex; flex-wrap: wrap; gap: var(--lyk-space-4); align-items: flex-end; margin-bottom: var(--lyk-space-4); }
.lyk-filter-bar__field { display: flex; flex-direction: column; gap: 4px; }

/* Detalle de una ejecución (modal de trazabilidad) */
.ejec-detalle__meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--lyk-space-3) var(--lyk-space-4); margin-bottom: var(--lyk-space-4); }
.ejec-detalle__meta > div { display: flex; flex-direction: column; gap: 2px; }
.ejec-detalle__meta-wide { grid-column: 1 / -1; }
.ejec-detalle__label { font-size: var(--lyk-text-xs); text-transform: uppercase; letter-spacing: .04em; color: var(--lyk-color-ink-2); }
.ejec-detalle__seccion { margin-top: var(--lyk-space-4); }
.ejec-detalle__seccion-head { display: flex; align-items: center; gap: var(--lyk-space-3); margin-bottom: 6px; }
/* El botón de copiar se va al extremo derecho del encabezado, alineado con el borde del bloque. */
.ejec-detalle__copiar { margin-left: auto; height: 26px; font-size: var(--lyk-text-xs); }
.ejec-detalle__body { margin: 0; padding: 10px 12px; border: 1px solid var(--lyk-color-border, rgba(0,0,0,.12)); border-radius: var(--lyk-radius-sm); background: var(--lyk-color-surface-2, rgba(0,0,0,.03)); font-size: var(--lyk-text-xs); max-height: 260px; overflow: auto; white-space: pre-wrap; word-break: break-word; }
@media (max-width: 720px) { .ejec-detalle__meta { grid-template-columns: 1fr; } }

/* Ejecutar bot (consola) */
.run-bot__key { display: flex; gap: var(--lyk-space-2); align-items: center; }
.run-bot__key .lyk-input { flex: 1; }
.run-bot__editor { width: 100%; resize: vertical; min-height: 180px; font-size: var(--lyk-text-xs); line-height: 1.5; white-space: pre; overflow: auto; }
.run-bot__editor-actions { display: flex; gap: var(--lyk-space-2); margin-top: 6px; }
.run-bot__result { margin-top: var(--lyk-space-4); border-top: 1px solid var(--lyk-color-border, rgba(0,0,0,.12)); padding-top: var(--lyk-space-3); }
.run-bot__result-head { display: flex; align-items: center; gap: var(--lyk-space-3); flex-wrap: wrap; margin-bottom: 6px; }
.run-bot__result-body { margin: 0; padding: 10px 12px; border: 1px solid var(--lyk-color-border, rgba(0,0,0,.12)); border-radius: var(--lyk-radius-sm); background: var(--lyk-color-surface-2, rgba(0,0,0,.03)); font-size: var(--lyk-text-xs); max-height: 300px; overflow: auto; white-space: pre-wrap; word-break: break-word; }

/* ═══════════════════════════════════════════════════════════════════════════
   Drawer (panel lateral) · hermano de LykModal para vistas de CONSULTA.
   Mantiene la tabla visible detrás: el usuario revisa muchos registros seguidos
   sin perder scroll ni filtros.
   ═════════════════════════════════════════════════════════════════════════ */
.lyk-drawer-backdrop { position: fixed; inset: 0; background: var(--lyk-color-scrim); z-index: 400; display: flex; justify-content: flex-end; }
.lyk-drawer {
    width: min(600px, 92%); height: 100%;
    background: var(--lyk-color-surface); border-left: 1px solid var(--lyk-color-border);
    box-shadow: var(--lyk-shadow-lg);
    display: flex; flex-direction: column; overflow: hidden;
    animation: lyk-drawer-in 180ms ease-out;
}
@keyframes lyk-drawer-in { from { transform: translateX(24px); opacity: .6; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .lyk-drawer { animation: none; } }

.lyk-drawer__header { flex: 0 0 auto; display: flex; align-items: flex-start; gap: var(--lyk-space-4); padding: 16px 22px; border-bottom: 1px solid var(--lyk-color-border); }
.lyk-drawer__header-content { min-width: 0; flex: 1 1 auto; }
.lyk-drawer__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 22px; display: grid; gap: var(--lyk-space-7); }
.lyk-drawer__footer { flex: 0 0 auto; border-top: 1px solid var(--lyk-color-border); background: var(--lyk-color-canvas); padding: 12px 22px; display: flex; justify-content: space-between; align-items: center; gap: var(--lyk-space-3); }
.lyk-drawer__title { display: flex; align-items: baseline; gap: 10px; margin-top: 6px; }
.lyk-drawer__title-id { font-family: var(--lyk-font-mono); font-size: 19px; font-weight: 600; color: var(--lyk-color-ink-1); }
.lyk-drawer__title-name { font-size: 13.5px; color: var(--lyk-color-ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lyk-drawer__ids { margin-top: 3px; font-family: var(--lyk-font-mono); font-size: 11.5px; color: var(--lyk-color-ink-3); }
.lyk-drawer__badges { display: flex; align-items: center; gap: var(--lyk-space-2); flex-wrap: wrap; }

/* Secciones del detalle */
.lyk-detail-section__title { display: flex; justify-content: space-between; align-items: center; margin-bottom: 9px; font-size: 13.5px; font-weight: 600; color: var(--lyk-color-ink-1); }
.lyk-detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 14px; background: var(--lyk-color-canvas); border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-md); }
.lyk-detail-field--wide { grid-column: span 2; }
.lyk-detail-field__value { margin-top: 3px; font-size: 12.5px; color: var(--lyk-color-ink-1); line-height: 1.4; text-wrap: pretty; }
.lyk-detail-field__value--mono { font-family: var(--lyk-font-mono); font-size: 12px; }
.lyk-detail-toggle { cursor: pointer; font-size: 12.5px; color: var(--lyk-color-ink-3); list-style: none; }
.lyk-detail-toggle::-webkit-details-marker { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   Exámenes · el código es LO FACTURABLE: nunca se trunca. Los nombres son
   largos (~75 chars) y se muestran completos con wrap, jamás con puntos suspensivos.
   ═════════════════════════════════════════════════════════════════════════ */
.lyk-exam-list { border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-md); overflow: hidden; }
.lyk-exam-row { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-bottom: 1px solid var(--lyk-color-divider); }
.lyk-exam-row:last-child { border-bottom: none; }
.lyk-exam-row:nth-child(even) { background: var(--lyk-color-canvas); }
.lyk-exam-code { font-family: var(--lyk-font-mono); font-size: 11.5px; font-weight: 600; color: var(--lyk-color-primary); background: var(--lyk-color-primary-soft); padding: 2px 7px; border-radius: var(--lyk-radius-xs); white-space: nowrap; flex-shrink: 0; margin-top: 1px; }
.lyk-exam-body { min-width: 0; }
.lyk-exam-name { font-size: 12.5px; color: var(--lyk-color-ink-1); line-height: 1.4; text-wrap: pretty; }
.lyk-exam-desc { font-size: 11.5px; color: var(--lyk-color-ink-3); margin-top: 3px; line-height: 1.4; text-wrap: pretty; }

/* Celda "Exámenes" de la grilla: conteo + primeros códigos + resto */
.lyk-exam-cell { display: flex; align-items: center; gap: 8px; min-width: 0; }
.lyk-exam-count { width: 22px; height: 22px; flex-shrink: 0; border-radius: var(--lyk-radius-xs); background: var(--lyk-color-surface-2); color: var(--lyk-color-ink-2); font-family: var(--lyk-font-mono); font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
.lyk-exam-chips { display: flex; gap: 4px; min-width: 0; overflow: hidden; }
.lyk-exam-chip { font-family: var(--lyk-font-mono); font-size: 10.5px; color: var(--lyk-color-ink-2); background: var(--lyk-color-surface-2); padding: 2px 6px; border-radius: 3px; white-space: nowrap; }
.lyk-exam-more { font-family: var(--lyk-font-mono); font-size: 10.5px; color: var(--lyk-color-ink-3); padding: 2px 4px; white-space: nowrap; }

/* Celda de dos líneas (identificador arriba, dato secundario abajo) */
.lyk-cell-main { font-size: 12.5px; color: var(--lyk-color-ink-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lyk-cell-main--id { font-family: var(--lyk-font-mono); font-weight: 600; color: var(--lyk-color-primary); }
.lyk-cell-sub { font-size: 10.5px; color: var(--lyk-color-ink-3); margin-top: 1px; }
.lyk-cell-sub--mono { font-family: var(--lyk-font-mono); font-size: 11px; }

/* ═══════════════════════════════════════════════════════════════════════════
   Estados: cargando (skeleton), vacío y error.
   Los dos vacíos son DISTINTOS a propósito: no-hay-datos y busqueda-sin-resultados
   llevan a acciones diferentes.
   ═════════════════════════════════════════════════════════════════════════ */
.lyk-skeleton { background: linear-gradient(90deg, var(--lyk-color-surface-2) 0%, var(--lyk-color-border) 50%, var(--lyk-color-surface-2) 100%); background-size: 200% 100%; animation: lyk-shimmer 1.4s ease-in-out infinite; border-radius: 3px; height: 11px; }
@keyframes lyk-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .lyk-skeleton { animation: none; } }
.lyk-skeleton-table { background: var(--lyk-color-surface); border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-md); overflow: hidden; }
.lyk-skeleton-table__row { display: grid; grid-template-columns: 108px 1.6fr 132px 1fr 96px 36px; gap: 10px; padding: 13px 14px; border-bottom: 1px solid var(--lyk-color-divider); align-items: center; }
.lyk-skeleton-table__row:last-child { border-bottom: none; }
.lyk-skeleton-table__row--head { background: var(--lyk-color-canvas); border-bottom: 1px solid var(--lyk-color-border); padding: 9px 14px; }

.lyk-state { background: var(--lyk-color-surface); border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-md); padding: 64px 32px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--lyk-space-3); }
.lyk-state__icon { width: 52px; height: 52px; display: flex; align-items: center; justify-content: center; background: var(--lyk-color-surface-2); border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-lg); color: var(--lyk-color-ink-3); }
.lyk-state__title { font-size: 15px; font-weight: 600; color: var(--lyk-color-ink-1); }
.lyk-state__message { font-size: 12.5px; color: var(--lyk-color-ink-3); max-width: 380px; line-height: 1.55; }

.lyk-error-card { background: var(--lyk-color-surface); border: 1px solid var(--lyk-color-border); border-top: 3px solid var(--lyk-color-danger); border-radius: var(--lyk-radius-md); padding: 24px; }
.lyk-error-card__head { display: flex; align-items: center; gap: 10px; font-size: 14.5px; font-weight: 600; color: var(--lyk-color-ink-1); }
.lyk-error-card__icon { width: 30px; height: 30px; flex-shrink: 0; background: var(--lyk-color-danger-soft); color: var(--lyk-color-danger); border-radius: 50%; display: flex; align-items: center; justify-content: center; }
.lyk-error-card__message { margin-top: 10px; font-size: 12.5px; color: var(--lyk-color-ink-2); line-height: 1.55; max-width: 560px; }
.lyk-error-card__meta { margin-top: 12px; padding: 10px; background: var(--lyk-color-canvas); border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-sm); font-family: var(--lyk-font-mono); font-size: 11px; color: var(--lyk-color-ink-3); line-height: 1.7; overflow-x: auto; }
.lyk-error-card__meta strong { color: var(--lyk-color-ink-1); font-weight: 500; }
.lyk-error-card__actions { margin-top: 14px; display: flex; gap: var(--lyk-space-3); }

/* Encabezado de página con acciones a la derecha + meta de la toolbar de grilla */
.lyk-page-header__actions { display: flex; gap: var(--lyk-space-3); align-items: center; }
.lyk-grid__meta { font-family: var(--lyk-font-mono); font-size: 11.5px; color: var(--lyk-color-ink-3); margin-left: auto; }

/* Fila clickeable de la grilla (abre el drawer) */
.lyk-grid tbody tr { cursor: pointer; }
.lyk-grid tbody tr:hover { background: var(--lyk-color-row-hover); }

/* Skeletons con proporciones nombradas (evita medidas sueltas repartidas por el markup). */
.lyk-skeleton--head   { height: 9px; }
.lyk-skeleton--chip   { height: 18px; border-radius: var(--lyk-radius-xs); }
.lyk-skeleton--bloque { height: 120px; }
.lyk-skeleton--w80 { width: 80%; } .lyk-skeleton--w75 { width: 75%; }
.lyk-skeleton--w70 { width: 70%; } .lyk-skeleton--w60 { width: 60%; }
.lyk-skeleton--w85 { width: 85%; } .lyk-skeleton--w40 { width: 40%; }
.lyk-skeleton--w10 { width: 10px; }

/* Acciones bajo una sección del drawer (copiar códigos / exportar). */
.lyk-detail-actions { margin-top: var(--lyk-space-3); display: flex; gap: var(--lyk-space-3); }
/* Grilla de metadatos dentro de un <details>. */
.lyk-detail-grid--anidada { margin-top: var(--lyk-space-3); }
/* Pie del drawer: sello de origen del dato. */
.lyk-drawer__origen { font-family: var(--lyk-font-mono); font-size: 11px; color: var(--lyk-color-ink-3); }
/* Chevron de "abrir detalle" en la grilla. */
.lyk-cell-chevron { color: var(--lyk-color-ink-3); }

/* ═══════════════════════════════════════════════════════════════════════════
   Cuenta · modales "Mi perfil" y "Cambiar contraseña".
   ═════════════════════════════════════════════════════════════════════════ */

/* Campo de sólo lectura: se ve como campo, pero se lee como dato (el correo es
   la identidad de la cuenta y no se edita desde el perfil). */
input.lyk-input--readonly,
input.lyk-input--readonly:focus {
    background: var(--lyk-color-surface-2);
    color: var(--lyk-color-ink-3);
    border-color: var(--lyk-color-border);
    box-shadow: none;
    cursor: default;
}

/* Contraseña + botón de mostrar/ocultar en la misma línea. */
.lyk-pwd-input { display: flex; align-items: center; gap: var(--lyk-space-2); }
.lyk-pwd-input .lyk-input { flex: 1; }
/* Mismo grupo campo+ojo en las paginas de AuthLayout, que usan su propia clase de input. */
.lyk-pwd-input .lyk-authform-input { flex: 1; }

/* Barra de fuerza: 4 segmentos = los 4 requisitos reales de la política. */
.lyk-pwd-strength { display: flex; gap: 4px; margin-top: 6px; }
.lyk-pwd-strength__seg { flex: 1; height: 3px; border-radius: 2px; background: var(--lyk-color-surface-2); }
.lyk-pwd-strength__seg--danger.is-on  { background: var(--lyk-color-danger); }
.lyk-pwd-strength__seg--warning.is-on { background: var(--lyk-color-warning); }
.lyk-pwd-strength__seg--success.is-on { background: var(--lyk-color-success); }

/* Rótulo Débil/Media/Fuerte bajo la barra: el color solo no comunica la fuerza (daltonismo, alto
   contraste), y aria-live lo anuncia al lector de pantalla mientras se escribe. */
.lyk-pwd-strength__label { font-size: 11px; margin: 4px 0 0; color: var(--lyk-color-ink-3); }
.lyk-pwd-strength__label--danger  { color: var(--lyk-color-danger); }
.lyk-pwd-strength__label--warning { color: var(--lyk-color-warning); }
.lyk-pwd-strength__label--success { color: var(--lyk-color-success); }

/* Checklist de requisitos: se marca en verde en vivo mientras se escribe. */
.lyk-requisitos {
    padding: 12px; background: var(--lyk-color-canvas);
    border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-sm);
    display: grid; gap: 6px;
}
.lyk-requisitos > .lyk-eyebrow { margin: 0; }
.lyk-requisitos__item { display: flex; align-items: center; gap: var(--lyk-space-3); font-size: 11.5px; color: var(--lyk-color-ink-3); }
.lyk-requisitos__item.is-ok { color: var(--lyk-color-ink-1); }
.lyk-requisitos__mark {
    width: 15px; height: 15px; flex-shrink: 0; border-radius: 50%;
    background: var(--lyk-color-surface-2); color: var(--lyk-color-ink-4);
    display: flex; align-items: center; justify-content: center;
}
.lyk-requisitos__item.is-ok .lyk-requisitos__mark { background: var(--lyk-color-success-soft); color: var(--lyk-color-success); }

/* Identidad del perfil: avatar + nombre + correo + badge de rol. */
.lyk-perfil-identidad { display: flex; align-items: center; gap: 14px; }
.lyk-perfil-identidad__meta { min-width: 0; flex: 1; }
.lyk-perfil-identidad__nombre { font-size: 15px; font-weight: 600; color: var(--lyk-color-ink-1); }
.lyk-perfil-identidad__email { font-size: 11.5px; color: var(--lyk-color-ink-3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; }
.lyk-perfil-avatar {
    width: 52px; height: 52px; flex-shrink: 0; border-radius: 50%;
    background: var(--lyk-color-primary-soft); color: var(--lyk-color-primary);
    display: flex; align-items: center; justify-content: center; font-size: 17px; font-weight: 600;
}

/* Fila de seguridad: antigüedad de la contraseña + atajo al modal de cambio. */
.lyk-perfil-seguridad {
    display: flex; align-items: center; justify-content: space-between; gap: var(--lyk-space-4);
    padding: 12px 14px; border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-sm);
}
.lyk-perfil-seguridad__info { display: flex; align-items: center; gap: 10px; }
.lyk-perfil-seguridad__icon {
    width: 30px; height: 30px; flex-shrink: 0; border-radius: var(--lyk-radius-sm);
    background: var(--lyk-color-surface-2); color: var(--lyk-color-ink-2);
    display: flex; align-items: center; justify-content: center;
}
.lyk-perfil-seguridad__title { font-size: 12.5px; font-weight: 600; color: var(--lyk-color-ink-1); }
.lyk-perfil-seguridad__sub { font-size: 11.5px; color: var(--lyk-color-ink-3); margin-top: 1px; }

/* Cerrar sesión: aclaración + caja de contexto de la sesión. */
/* Selector con .lyk-confirm-body para ganarle a la regla base `.lyk-confirm-body p` (ink-3):
   esta aclaración es contenido, no un subtítulo. */
.lyk-confirm-body p.lyk-logout-nota { color: var(--lyk-color-ink-2); font-size: 12.5px; line-height: 1.6; }
.lyk-logout-meta {
    margin-top: 12px; padding: 10px; background: var(--lyk-color-canvas);
    border: 1px solid var(--lyk-color-border); border-radius: var(--lyk-radius-sm);
    font-size: 11px; color: var(--lyk-color-ink-3); line-height: 1.7;
}
.lyk-logout-meta strong { color: var(--lyk-color-ink-1); font-weight: 500; }
