/*
 * identity.css
 * ------------
 * Cargado por:
 *   - panel/tircloud_panel/templates/users.html (gestión de operadores/usuarios
 *     del panel, junto con identity.js)
 *   - panel/tircloud_panel/templates/identity_activate.html (activación de
 *     cuenta de un operador nuevo, invitado por email)
 *   - panel/tircloud_panel/templates/identity_recover.html (flujo de
 *     recuperación de cuenta / restablecimiento con TOTP)
 * Un solo archivo cubre tres pantallas relacionadas con la identidad de los
 * operadores del panel: la tabla/grid de administración de usuarios
 * (bloque principal de este archivo), las pantallas públicas de
 * activación/recuperación de cuenta (clases .identity-public*,
 * .wizard-steps, .totp-enroll, .recovery-codes, .button-link) y, en las
 * líneas siguientes del archivo, el layout de dos columnas específico de
 * la pantalla de recuperación (.recovery-*) más ajustes de marca y del
 * componente TOTP.
 */

/* Cabecera de "Usuarios/Identidad": título grande alineado abajo. */
.identity-head{align-items:end;margin-bottom:18px}.identity-head h1{font-size:clamp(26px,3vw,34px);letter-spacing:-.035em;margin:4px 0}/* Botón primario "Invitar operador" / botón "Guardar" del formulario de
   edición: mismo estilo (fondo y borde en color primario) para ambas
   acciones principales de la página. */
.identity-primary-action,.identity-save{background:var(--primary);border:1px solid var(--primary);border-radius:8px;color:#fff;font-weight:750;min-height:40px;padding:9px 14px}/* Banner "solo una vez" que muestra una credencial/enlace generado (p.ej.
   el enlace de activación de un operador recién invitado): tarjeta con
   borde izquierdo grueso en color primario para llamar la atención, en
   grid de 3 columnas (icono, campo de solo-lectura, botón copiar). */
.identity-once{align-items:center;background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--primary);border-radius:10px;display:grid;gap:8px;grid-template-columns:auto 1fr auto;margin-bottom:14px;padding:12px}.identity-once input{min-width:0;width:100%}/* Barra de filtros de la lista de operadores: campo de búsqueda (más
   ancho) + dos selectores (p.ej. rol, estado) + acciones, en una fila con
   sombra y fondo de tarjeta. */
.identity-filters{align-items:end;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-sm);display:grid;gap:12px;grid-template-columns:minmax(260px,1.5fr) repeat(2,minmax(150px,.5fr)) auto;padding:14px}.identity-filters label,.identity-edit label,.identity-dialog label{display:grid;font-size:10px;gap:6px}.identity-filters label>span:first-child{color:var(--muted);font-weight:750;text-transform:uppercase}.identity-filters input,.identity-filters select{min-height:40px}/* Campo de búsqueda con icono dentro de la barra de filtros: resalta el
   borde con el color primario cuando el input interno tiene foco
   (:focus-within), simulando que todo el campo (icono + input) está
   enfocado. */
.identity-search-field{align-items:center;border:1px solid var(--line);border-radius:8px;display:flex;padding-inline:11px}.identity-search-field:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--primary) 14%,transparent)}.identity-search-field>span{color:var(--muted);font-size:19px;line-height:1}.identity-search-field input{background:transparent;border:0;box-shadow:none;min-width:0;width:100%}/* Grupo de acciones al final de la barra de filtros: botón "Filtrar" en
   color primario y enlace "Limpiar" en texto atenuado, uno junto al otro. */
.identity-filter-actions{align-items:center;display:flex;gap:10px}.identity-filter-actions button{background:var(--primary);border-color:var(--primary);color:#fff;min-height:40px}.identity-filter-actions a{color:var(--muted);font-size:11px}/* Fila entre los filtros y la grilla de tarjetas: a la izquierda el
   contador de resultados ("N operadores"), a la derecha texto auxiliar. */
.identity-results{align-items:center;display:flex;justify-content:space-between;margin:15px 2px 10px}.identity-results strong{font-size:12px}.identity-results span{color:var(--muted);font-size:10px}/* Grilla de tarjetas de operadores: 3 columnas iguales en escritorio,
   alineadas arriba (para que tarjetas de distinta altura -- por permisos
   expandidos -- no se estiren entre sí). */
.identity-grid{align-items:start;display:grid;gap:14px;grid-template-columns:repeat(3,minmax(0,1fr))}/* Tarjeta individual de un operador: contenedor con esquinas redondeadas
   y overflow oculto (para que la cabecera con fondo y el <dl> con fondo
   propio no se salgan del radio del borde). */
.identity-card{background:var(--surface);border:1px solid var(--line);border-radius:13px;box-shadow:var(--shadow-sm);overflow:hidden;padding:0}/* Cabecera de la tarjeta: avatar, nombre+rol y badge de estado en una
   fila de 3 columnas (auto, flexible, auto). */
.identity-card header{align-items:center;display:grid;gap:11px;grid-template-columns:auto 1fr auto;padding:15px}/* Variante en color primario del avatar genérico .operator-avatar (estilo
   base definido en otro CSS compartido) para las tarjetas de esta página. */
.identity-card .operator-avatar{background:var(--primary-soft);border-color:color-mix(in srgb,var(--primary) 32%,var(--line));color:var(--primary-text);height:36px;width:36px}/* Nombre del operador dentro de la tarjeta: permite partir palabras muy
   largas (correos) para que no desborden la tarjeta. */
.identity-card h2{font-size:14px;line-height:1.25;margin:0;overflow-wrap:anywhere}/* Texto del rol del operador, debajo del nombre, en color atenuado. */
.identity-role{color:var(--muted);display:block;font-size:10px;margin-top:2px}/* Badge base de estado del operador (píldora en mayúsculas); el color
   concreto lo aportan las clases de modificador .state-active/
   -suspended/-revoked definidas justo debajo, según el estado real de la
   cuenta. */
.identity-state{border:1px solid transparent;border-radius:999px;font-size:8px;font-weight:800;padding:4px 7px;text-transform:uppercase}.state-active{background:color-mix(in srgb,var(--green) 13%,var(--surface));color:var(--green)}.state-suspended{background:color-mix(in srgb,var(--amber) 14%,var(--surface));color:var(--amber)}.state-revoked{background:color-mix(in srgb,var(--red) 13%,var(--surface));color:var(--red)}/* Lista de definición con los metadatos del operador (email, último
   acceso, etc.): fondo ligeramente distinto al de la tarjeta, con bordes
   horizontales para separarla de la cabecera y del bloque de permisos. */
.identity-card dl{background:color-mix(in srgb,var(--surface-2) 52%,var(--surface));border-block:1px solid var(--line);display:grid;gap:9px;margin:0;padding:12px 15px}/* Cada par etiqueta/valor dentro del <dl>: etiqueta de ancho fijo (82px) y
   valor en el espacio restante. */
.identity-card dl div{align-items:start;display:grid;gap:8px;grid-template-columns:82px 1fr}.identity-card dt{color:var(--muted);font-size:9px;text-transform:uppercase}.identity-card dd{font-size:10px;margin:0;overflow-wrap:anywhere}/* Contenedor del bloque expandible de permisos del operador (el <details>
   de abajo va dentro de este contenedor). */
.identity-permissions{padding:0 15px}/* Cabecera clicable ("Ver permisos") del <details> de permisos: oculta el
   marcador nativo del navegador y añade un "+"/"−" propio mediante
   ::after (ver reglas siguientes), que cambia según el <details> esté
   abierto o cerrado. */
.identity-card summary{align-items:center;color:var(--primary-text);cursor:pointer;display:flex;font-size:11px;font-weight:750;justify-content:space-between;list-style:none;min-height:44px}.identity-card summary::-webkit-details-marker{display:none}.identity-card summary:after{content:"＋";font-size:14px}.identity-card details[open] summary:after{content:"−"}.identity-card summary small{color:var(--muted);font-size:9px;font-weight:400;margin-left:auto;margin-right:8px}/* Formulario de edición inline del operador, mostrado dentro de la
   tarjeta (separado del resto por un borde superior). */
.identity-edit{border-top:1px solid var(--line);display:grid;gap:11px;padding:14px 0 15px}.identity-edit input,.identity-edit select{min-height:38px}/* Agrupación de checkboxes de permisos (p.ej. módulos habilitados) tanto
   en el formulario de edición inline como en el diálogo modal de "nuevo
   operador": fondo distinto, en fila con ajuste de línea. */
.identity-edit fieldset,.identity-dialog fieldset{background:var(--surface-2);border:1px solid var(--line);border-radius:9px;display:flex;flex-wrap:wrap;gap:10px;padding:11px}.identity-edit fieldset label,.identity-dialog fieldset label{align-items:center;display:flex}/* El botón "Guardar" (definido junto con .identity-primary-action al
   inicio del archivo) ocupa todo el ancho cuando está dentro del
   formulario de edición. */
.identity-save{width:100%}
/* Diálogo modal (<dialog>) para crear un nuevo operador: tarjeta con
   fondo desenfocado detrás (::backdrop) y ancho acotado. */
.identity-dialog{background:var(--surface);border:1px solid var(--line);border-radius:16px;color:var(--text);max-width:720px;padding:0;width:calc(100% - 30px)}.identity-dialog::backdrop{backdrop-filter:blur(4px);background:rgb(2 12 9 / 68%)}.identity-dialog form{display:grid;gap:15px;padding:22px}/* Cabecera del diálogo modal (título + botón "cerrar"): patrón compartido
   con otros diálogos del panel (p.ej. backup-profiles.css). */
.dialog-head{align-items:start;display:flex;justify-content:space-between}.dialog-head h2{font-size:22px;margin:2px 0 0}.dialog-head [data-dialog-close]{background:var(--surface-2);border:1px solid var(--line);color:var(--muted);font-size:20px;padding:2px 9px}/* Pantalla pública de activación de cuenta (identity_activate.html):
   ocupa casi toda la altura visible y centra la tarjeta de activación
   tanto vertical como horizontalmente. */
.identity-public{display:grid;min-height:calc(100vh - 150px);padding:30px 16px;place-items:center}/* Tarjeta central de la pantalla de activación: ancho máximo acotado con
   padding que crece en pantallas grandes (clamp) y sombra pronunciada
   para destacar sobre el fondo. */
.identity-public-card{background:var(--surface);border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow);max-width:560px;padding:clamp(24px,5vw,42px);width:100%}.identity-public-card h1{margin-top:4px}
/* Indicador de pasos del asistente de activación ("1. Verifica tu correo
   2. Configura tu contraseña 3. Activa 2FA", por ejemplo): lista en fila
   con separación entre pasos, en tamaño pequeño y color atenuado.
   NOTA: el nombre de clase .wizard-steps coincide con el usado en
   staging-wizard.css para el asistente de creación de staging; son
   componentes visualmente distintos que comparten nombre por
   convención ("indicador de pasos de un asistente"), no hay conflicto
   porque nunca se cargan las dos hojas de estilo en la misma página. */
.wizard-steps{color:var(--muted);display:flex;font-size:10px;gap:24px;margin:18px 0;padding-left:18px}/* Caja de enrolamiento TOTP (código/secreto de 2FA a introducir en la app
   autenticadora) durante la activación de cuenta: borde discontinuo
   (dashed) para diferenciarla visualmente de una tarjeta normal. */
.totp-enroll{background:var(--surface-2);border:1px dashed var(--line);border-radius:9px;padding:12px}.totp-enroll code{display:block;font-size:14px;letter-spacing:.08em;overflow-wrap:anywhere}/* Grilla de códigos de recuperación (2 columnas) mostrados una sola vez
   al terminar la activación/enrolamiento; cada código es seleccionable
   por completo con un solo clic (user-select:all) para copiarlo fácil. */
.recovery-codes{display:grid;gap:7px;grid-template-columns:1fr 1fr;padding-left:24px}.recovery-codes code{user-select:all}
/* Enlace con apariencia de botón (p.ej. "Ir a iniciar sesión" al final
   del flujo de activación): mismo color primario que los botones reales. */
.button-link{background:var(--primary);border-radius:8px;color:#fff;display:inline-block;font-weight:750;margin-top:15px;padding:10px 14px}/* Responsive intermedio (<=1100px): la grilla de tarjetas y los filtros
   pasan a 2 columnas, y las acciones de filtro ocupan el ancho completo
   de la fila para no quedar apretadas. */
@media(max-width:1100px){.identity-grid{grid-template-columns:1fr 1fr}.identity-filters{grid-template-columns:minmax(220px,1fr) 1fr 1fr}.identity-filter-actions{grid-column:1/-1}}
/* Responsive móvil (<=700px): tarjetas, filtros, el banner "solo una vez"
   y los códigos de recuperación colapsan todos a una sola columna; la
   cabecera y el contador de resultados se alinean a la izquierda en vez
   de repartirse en la fila; se oculta el contador "N permisos" del
   resumen de permisos para ahorrar espacio. */
@media(max-width:700px){.identity-grid,.identity-filters,.identity-once,.recovery-codes{grid-template-columns:1fr}.identity-head{align-items:start}.identity-results{align-items:start;flex-direction:column;gap:3px}.identity-filter-actions{grid-column:auto}.identity-card summary small{display:none}}

/*
 * Pantalla de recuperación de cuenta (identity_recover.html): layout de
 * dos columnas tipo "landing" -- panel de contexto/marca a la izquierda
 * (degradado y garantías de seguridad) y tarjeta con el formulario del
 * paso actual del asistente a la derecha (usuario -> verificación TOTP ->
 * nueva contraseña + códigos de recuperación).
 */
/* Contenedor de toda la pantalla: centra la tarjeta en el viewport. */
.recovery-shell{display:grid;min-height:calc(100vh - 108px);padding:clamp(18px,4vw,52px);place-items:center}/* Tarjeta principal: grid de 2 columnas (panel de contexto más angosto a
   la izquierda, panel de formulario más ancho a la derecha), con sombra
   pronunciada y ancho máximo para pantallas grandes. */
.recovery-layout{background:var(--surface);border:1px solid var(--line);border-radius:20px;box-shadow:0 24px 70px rgba(17,18,22,.14);display:grid;grid-template-columns:minmax(300px,.82fr) minmax(420px,1.18fr);max-width:1040px;overflow:hidden;width:100%}/* Columna izquierda de contexto: fondo con degradado morado (color fijo,
   luego sobrescrito más abajo por la regla de "identidad visual esmeralda
   ODOOCRC" para usar el degradado de marca real); texto en blanco. */
.recovery-context{background:linear-gradient(145deg,#5c3d55,#7d536f);color:#fff;display:flex;flex-direction:column;gap:28px;justify-content:space-between;padding:clamp(30px,4vw,52px)}/* Icono/marca cuadrada (isotipo) en la esquina superior del panel de
   contexto, con fondo semitransparente sobre el degradado. */
.recovery-mark{align-items:center;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.22);border-radius:12px;display:flex;font-size:19px;font-weight:850;height:44px;justify-content:center;width:44px}/* Texto "eyebrow" (rótulo pequeño encima del título) en un rosa claro
   fijo, pensado para el degradado morado original (también sobrescrito
   más abajo junto con el degradado de marca). */
.recovery-context .eyebrow{color:#f2dce9}/* Título principal del panel de contexto: blanco fijo (independiente del
   tema) porque siempre se dibuja sobre el degradado oscuro. */
.recovery-context h1{color:#fff;font-size:clamp(26px,3vw,38px);letter-spacing:-.035em;line-height:1.08;margin:7px 0 14px}/* Párrafo de descripción bajo el título, en blanco semitransparente para
   diferenciarlo jerárquicamente del título. */
.recovery-context>div>p:last-child{color:rgba(255,255,255,.78);font-size:13px;line-height:1.65}/* Lista de "garantías" de seguridad (p.ej. "Tus datos están cifrados"),
   sin viñetas nativas, cada ítem en una fila con su propio icono circular. */
.recovery-assurances{display:grid;gap:14px;list-style:none;margin:0;padding:0}/* Cada garantía individual: icono + texto en línea. */
.recovery-assurances li{align-items:center;display:flex;font-size:12px;gap:11px}/* Icono circular (con checkmark/emoji vía contenido HTML) de cada
   garantía. */
.recovery-assurances span{align-items:center;background:rgba(255,255,255,.15);border-radius:50%;display:flex;font-size:10px;font-weight:800;height:24px;justify-content:center;width:24px}/* Texto de ayuda al pie del panel de contexto (p.ej. enlace a soporte),
   separado por un borde superior semitransparente. */
.recovery-help{border-top:1px solid rgba(255,255,255,.18);color:rgba(255,255,255,.68);font-size:10px;line-height:1.55;margin:0;padding-top:18px}/* Columna derecha (panel de formulario): solo define su padding interno,
   ya que el fondo/borde los aporta .recovery-layout. */
.recovery-card{padding:clamp(28px,5vw,58px)}/* Enlace "Volver" en la parte superior del formulario, en color atenuado. */
.recovery-back{color:var(--muted);display:inline-block;font-size:11px;margin-bottom:28px}/* Título del paso actual del asistente (p.ej. "Verifica tu identidad"). */
.recovery-heading h2{font-size:clamp(24px,3vw,32px);letter-spacing:-.025em;margin:5px 0 8px}/* Descripción del paso actual, con ancho máximo para que las líneas no se
   vuelvan demasiado largas de leer. */
.recovery-heading>p:last-child{color:var(--muted);font-size:12px;line-height:1.55;margin:0;max-width:560px}/* Indicador de progreso de 3 pasos del asistente de recuperación (no
   confundir con .wizard-steps, usado en la pantalla de activación): 3
   columnas iguales, con position:relative para poder dibujar encima la
   línea conectora (::before) que atraviesa los círculos de paso. */
.recovery-progress{display:grid;grid-template-columns:repeat(3,1fr);list-style:none;margin:28px 0;padding:0;position:relative}/* Línea horizontal conectora detrás de los círculos de paso, recortada a
   los extremos (16.6% ~ un sexto de ancho, para alinearse con el centro
   del primer y último círculo en la grilla de 3 columnas). */
.recovery-progress:before{background:var(--line);content:"";height:1px;left:16.6%;position:absolute;right:16.6%;top:14px}/* Cada paso del indicador: círculo numerado + etiqueta apilados en
   columna, por encima de la línea conectora (z-index en el círculo). */
.recovery-progress li{align-items:center;color:var(--muted);display:flex;flex-direction:column;font-size:10px;gap:6px;position:relative}/* Círculo numerado de cada paso, en su estado por defecto (paso futuro,
   aún no alcanzado): fondo de tarjeta y borde normal. */
.recovery-progress li span{align-items:center;background:var(--surface);border:1px solid var(--line);border-radius:50%;display:flex;font-size:10px;font-weight:800;height:29px;justify-content:center;width:29px;z-index:1}/* Paso actualmente activo: etiqueta en color primario y negrita. */
.recovery-progress li.active{color:var(--primary);font-weight:800}/* Círculo del paso activo: relleno en color primario con texto blanco. */
.recovery-progress li.active span{background:var(--primary);border-color:var(--primary);color:#fff}/* Paso ya completado: círculo en verde fijo con un checkmark ("✓") vía
   ::after en vez del número; la segunda regla ".recovery-progress
   li.done span{font-size:0}" oculta el texto/número original del círculo
   (poniendo su tamaño de fuente a 0) para que solo se vea el checkmark
   generado por contenido. Son dos reglas para el mismo selector
   ".recovery-progress li.done span" que se combinan en cascada (no se
   pisan porque tocan propiedades distintas). */
.recovery-progress li.done span{background:#e1f3e8;border-color:#bce2ca;color:#147a43}.recovery-progress li.done span:after{content:"✓";font-size:12px}.recovery-progress li.done span{font-size:0}/* Formulario del paso actual: campos apilados con separación uniforme. */
.recovery-form{display:grid;gap:16px}/* Etiqueta de cada campo del formulario, con texto de ayuda opcional en
   <small> (ver regla siguiente). */
.recovery-form label{color:var(--text);display:grid;font-size:11px;font-weight:700;gap:6px}/* Texto de ayuda pequeño bajo la etiqueta de un campo (contrapeso a la
   negrita/tamaño de la etiqueta principal). */
.recovery-form label small{color:var(--muted);font-size:9px;font-weight:400}
/* Campo de texto del formulario: más alto que un input normal (44px) y
   con padding lateral, para que sea cómodo de tocar en móvil. */
.recovery-form input{border-radius:9px;min-height:44px;padding-inline:12px;width:100%}/* Botón de envío del formulario: ancho completo, centra su contenido
   (texto + posible icono/span, ver regla siguiente) horizontalmente. */
.recovery-form button{align-items:center;background:var(--primary);border:0;border-radius:9px;color:#fff;display:flex;font-weight:800;justify-content:center;min-height:45px}/* Un <span> dentro del botón (p.ej. una flecha "→") separado del texto. */
.recovery-form button span{margin-left:8px}/* Bloque de alerta (error de validación, código incorrecto, etc.) sobre
   el formulario, con su texto secundario en tamaño pequeño. */
.recovery-alert{display:grid;gap:3px;margin-bottom:16px}.recovery-alert span{font-size:11px}/* Contador de tiempo restante (p.ej. para reenviar un código o antes de
   que expire un enlace): tarjeta discreta con fondo secundario. */
.recovery-timer{align-items:center;background:var(--surface-2);border-radius:9px;display:flex;gap:8px;margin-bottom:16px;padding:11px 13px}/* El número/tiempo restante en color primario y destacado; el texto de
   acompañamiento ("segundos restantes") en color atenuado. */
.recovery-timer strong{color:var(--primary);font-size:12px}.recovery-timer span{color:var(--muted);font-size:10px}/* Bloque que muestra el secreto TOTP manual (para introducirlo a mano en
   la app autenticadora si no se puede escanear el QR): etiqueta en
   mayúsculas y texto de ayuda debajo en color atenuado. */
.recovery-secret span{display:block;font-size:10px;font-weight:750;margin-bottom:8px;text-transform:uppercase}.recovery-secret small{color:var(--muted);display:block;font-size:9px;margin-top:8px}/* Mensaje de éxito (p.ej. "Contraseña actualizada") tras completar un
   paso, con su texto secundario en tamaño reducido. */
.recovery-success{display:grid;gap:5px;margin:16px 0}.recovery-success span{font-size:11px}/* Título "Tus códigos de recuperación" y su párrafo de advertencia (p.ej.
   "guárdalos en un lugar seguro"), antes de la grilla .recovery-codes
   definida en la sección de administración de usuarios más arriba. */
.recovery-codes-heading h3{font-size:15px;margin:22px 0 4px}.recovery-codes-heading p{color:var(--muted);font-size:10px;margin:0}/* Enlace/botón final del asistente ("Ir a iniciar sesión"), centrado. */
.recovery-finish{display:block;text-align:center}
/* Responsive tablet/móvil (<=800px): se oculta por completo el panel de
   contexto/marca (columna izquierda) para dejar todo el ancho al
   formulario, que pasa a una sola columna; se reducen paddings y
   márgenes para aprovechar mejor el espacio. */
@media(max-width:800px){.recovery-shell{padding:14px}.recovery-layout{grid-template-columns:1fr;max-width:580px}.recovery-context{display:none}.recovery-card{padding:26px 22px}.recovery-back{margin-bottom:20px}.recovery-progress{margin:22px 0}.recovery-shell{min-height:calc(100vh - 90px)}}
/* Responsive móvil pequeño (<=480px): padding aún más reducido, título de
   paso más pequeño y las etiquetas del indicador de progreso se achican. */
@media(max-width:480px){.recovery-card{padding:22px 16px}.recovery-heading h2{font-size:24px}.recovery-progress small{font-size:8px}}

/* Identidad visual esmeralda ODOOCRC. */
.recovery-context{background:var(--brand-gradient)}
.recovery-context .eyebrow{color:rgb(255 255 255 / 82%)}

/* QR de enrolamiento TOTP: fondo blanco fijo (no ligado al tema) porque un
   QR de bajo contraste falla al escanear con cámaras de teléfono. */
.totp-qr{background:#fff;border-radius:9px;display:block;margin:10px auto 4px;padding:8px}
.totp-manual{margin-top:6px}
.totp-manual summary{color:var(--primary-text);cursor:pointer;font-size:11px;font-weight:700;list-style:none}
.totp-manual summary::-webkit-details-marker{display:none}
.totp-manual code{margin-top:8px}
