/* ============================================================
   Control de usuario del encabezado
   ------------------------------------------------------------
   Capa: componente

   Avatar con iniciales + menu desplegable con el estado de la
   membresia. Hermano de navbar.css: se carga justo despues, para
   que el control pueda ganarle a las reglas genericas de .nav-right
   sin subir especificidad a mano.

   SOLO TOKENS DEL CONTRATO. Ni un color literal: el semaforo sale
   de --estado-ok / --estado-aviso / --estado-critico, el halo de
   rgba(var(--accent-rgb), α). Asi el control llega gratis a Neo,
   Atlas y Aurora cuando se reconstruyan.
   ============================================================ */

/* ── Contador de la prueba gratuita (Release 2) ──────────────
   Es un <span>, no un <a>: no lleva las reglas de los botones del
   navbar, que son acciones. Esto informa, no invita a hacer clic.

   VIVE ACA Y NO EN navbar.css. Lo emite _usuario-control.php, el
   mismo marcado que usan los apuntes Y la Biblioteca. La Biblioteca
   enlaza usuario.css y admin-modal.css, no navbar.css, asi que
   mientras estas reglas estuvieron alla el chip aparecia sin ningun
   estilo apenas el alumno de prueba abria un apunte y volvia a la
   Biblioteca (guardian_cupo ya en sesion).

   Dos correcciones de la misma auditoria van adentro:
     · el fondo era el literal rgba(255,255,255,.06) — blanco sobre
       blanco, invisible en Premium/Atlas/Aurora en modo claro;
     · el color pedia var(--text2), que no existe en ningun layout
       (el token del contrato es --text-2, con guion), asi que la
       declaracion era invalida y el chip heredaba el color del body. */
.nav-cupo {
  padding: 4px 10px; border-radius: 20px;
  font-size: .62rem; letter-spacing: .02em;
  background: var(--bg2);
  border: 1px solid var(--border);
  color: var(--text-2); cursor: default; white-space: nowrap;
}
.nav-cupo-lleno {
  background: var(--accent-dim);
  border-color: rgba(var(--accent-rgb),.45);
  color: var(--accent);
}
/* En pantallas chicas el navbar ya viene justo: se cae el nombre
   antes que el contador, que es el dato que cambia. */
@media (max-width: 560px) { .nav-cupo { padding: 3px 8px; font-size: .58rem; } }
/* En papel no aporta nada. */
@media print { .nav-cupo { display: none !important; } }

.usuario { position: relative; flex-shrink: 0; }

/* ── El semaforo, hecho legible ──────────────────────────────
   --estado-ok / --estado-aviso / --estado-critico son del
   contrato y NO se tocan: el que manda es el layout. Pero sus
   valores estan calculados para fondo claro —el propio contrato
   lo anota como pendiente conocido— y medidos sobre esta pieza
   no alcanzan:

     modo oscuro   "Membresia vencida"  1,55:1   ← ilegible
                   "Vence hoy"          3,72:1
     modo claro    "Vence hoy"          4,04:1   ← justo abajo de AA

   Asi que el componente se los acerca al color de texto del modo
   en curso, lo justo para pasar 4,5:1 sin perder el hue: el rojo
   sigue leyendose como rojo y el verde como verde. Los tres pares
   quedan entre 4,7:1 y 7,4:1.

   Se resuelve ACA y no en el layout a proposito: cambiar los
   tokens cambiaria tambien el modal de bienvenida, que es una
   decision aparte y no parte de esta tarea (ver CONTRATO-TOKENS
   §1.5). El dia que los layouts tengan variante oscura del
   semaforo, estas seis lineas se borran y no cambia nada mas.

   La declaracion sin mezclar va primero: un navegador sin
   color-mix() se queda con el token pelado, que es exactamente
   como se ve hoy el modal. */
.usuario {
  --u-ok: var(--estado-ok);
  --u-aviso: var(--estado-aviso);
  --u-critico: var(--estado-critico);
  --u-ok: color-mix(in srgb, var(--estado-ok) 88%, var(--text));
  --u-aviso: color-mix(in srgb, var(--estado-aviso) 88%, var(--text));
  --u-critico: color-mix(in srgb, var(--estado-critico) 88%, var(--text));
}
body.dark-mode .usuario {
  --u-ok: color-mix(in srgb, var(--estado-ok) 45%, var(--text));
  --u-aviso: color-mix(in srgb, var(--estado-aviso) 45%, var(--text));
  --u-critico: color-mix(in srgb, var(--estado-critico) 45%, var(--text));
}

/* ── El boton ────────────────────────────────────────────────
   Es un boton y no un chip decorativo: abre un menu, asi que
   tiene que verse pulsable y responder al foco de teclado. */
.usuario-btn {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 10px 4px 4px;
  border: 1px solid var(--border);
  border-radius: 22px;
  background: var(--bg2);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: .68rem;
  color: var(--text-2);
  transition: background var(--t), border-color var(--t), box-shadow var(--t);
}
.usuario-btn:hover {
  background: var(--card);
  border-color: rgba(var(--accent-rgb), .45);
}
/* El halo de acento es lindo pero NO es un indicador de foco: medido
   sobre la navbar clara da 1,15:1, y WCAG pide 3:1. El contorno solido
   es el que cumple; el halo se queda porque acompana. En oscuro el
   navy desaparece contra el fondo, asi que ahi manda el acento. */
.usuario-btn:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .3);
}
body.dark-mode .usuario-btn:focus-visible { outline-color: var(--accent); }
.usuario.abierto .usuario-btn {
  background: var(--card);
  border-color: rgba(var(--accent-rgb), .5);
}
body.dark-mode .usuario-btn { background: var(--card2); }

/* ── El circulo ──────────────────────────────────────────────
   Solido y con --on-accent encima: el acento a media opacidad
   deja las iniciales al borde del contraste en modo claro. */
.usuario-avatar {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 50%;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  color: var(--on-accent);
  font-family: var(--font-mono);
  font-size: .66rem; font-weight: 700; letter-spacing: .02em;
  line-height: 1;
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .12);
  transition: box-shadow var(--t);
  position: relative;
}
.usuario-btn:hover .usuario-avatar,
.usuario.abierto .usuario-avatar {
  box-shadow: 0 0 0 4px rgba(var(--accent-rgb), .22);
}

.usuario-nombre {
  max-width: 130px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.usuario-flecha {
  flex-shrink: 0; opacity: .55;
  transition: transform var(--t), opacity var(--t);
}
.usuario.abierto .usuario-flecha { transform: rotate(180deg); opacity: .9; }

/* Nombre accesible completo, para lectores de pantalla. En mobile
   el boton es solo el circulo y el aviso de vencimiento es color:
   sin esto, ninguna de las dos cosas llega a quien no las ve. */
.usuario-sr {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
}

/* ── El aviso de vencimiento ─────────────────────────────────
   Un punto chico en el borde del circulo. Elegante, no invasivo:
   no hay banda roja ni cartel: el que quiere saber, abre el menu.
   El color lo pone el semaforo del sistema, nunca el layout. */
.usuario-avatar::after {
  content: '';
  position: absolute; right: -1px; bottom: -1px;
  width: 9px; height: 9px; border-radius: 50%;
  border: 2px solid var(--bg2);
  background: transparent;
  transform: scale(0);
  transition: transform .25s cubic-bezier(.34,1.56,.64,1);
}
.usuario[data-estado="aviso"]   .usuario-avatar::after { background: var(--u-aviso);   transform: scale(1); }
.usuario[data-estado="critico"] .usuario-avatar::after { background: var(--u-critico); transform: scale(1); }
body.dark-mode .usuario-avatar::after { border-color: var(--card2); }

/* Vencida: ademas del punto, un latido lento del halo. Ocho
   segundos de ciclo y opacidad baja — se percibe de reojo y no
   compite con la lectura, que es de lo que trata la pagina. */
.usuario[data-estado="critico"] .usuario-avatar {
  animation: usuario-latido 8s ease-in-out infinite;
}
@keyframes usuario-latido {
  0%, 100% { box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .12); }
  50%      { box-shadow: 0 0 0 6px rgba(var(--accent-rgb), .05); }
}
@media (prefers-reduced-motion: reduce) {
  .usuario[data-estado="critico"] .usuario-avatar { animation: none; }
  .usuario-avatar::after { transition: none; }
}

/* ── El desplegable ──────────────────────────────────────────
   display:none y no [hidden]/opacity: cerrado tiene que salir del
   arbol de accesibilidad, no solo dejar de verse. Es el mismo
   criterio que usa #modal-bienvenida. */
.usuario-menu {
  display: none;
  position: absolute; top: calc(100% + 12px); right: 0;
  z-index: 1001;
  width: 260px; max-width: calc(100vw - 32px);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), 0 0 0 1px rgba(var(--accent-rgb), .10);
  overflow: hidden;
  text-align: left;
}
.usuario.abierto .usuario-menu {
  display: block;
  animation: usuario-menu-in .18s cubic-bezier(.34,1.4,.64,1);
}
@keyframes usuario-menu-in {
  from { opacity: 0; transform: translateY(-6px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* Hilo de acento arriba, igual que el modal de bienvenida: las dos
   piezas hablan de lo mismo y conviene que se reconozcan. */
.usuario-menu::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--accent-strong), var(--accent), transparent);
}

.usuario-cab {
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--border);
}
.usuario-cab-nombre {
  font-family: var(--font-body);
  font-size: .92rem; font-weight: 600; color: var(--text);
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.usuario-cab-mail {
  font-family: var(--font-mono);
  font-size: .64rem; color: var(--gray);
  margin-top: 3px;
  overflow-wrap: anywhere;
}

.usuario-datos { padding: 12px 18px 14px; background: var(--bg2); }
.usuario-dato {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
  font-size: .74rem; line-height: 1.6;
}
.usuario-dato-k {
  font-family: var(--font-mono);
  font-size: .62rem; letter-spacing: .06em; text-transform: uppercase;
  /* --gray y no --gray-light: el contrato mide --gray-light en 3,07:1
     sobre fondo claro y estas etiquetas son texto, no epigrafes. */
  color: var(--gray); flex-shrink: 0;
}
.usuario-dato-v { color: var(--text-2); text-align: right; }

/* El dato que el alumno vino a buscar. Por eso va solo, mas grande
   y con el color del semaforo. */
.usuario-dias {
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: .82rem; font-weight: 700;
  color: var(--u-ok);
}
.usuario[data-estado="aviso"]   .usuario-dias { color: var(--u-aviso); }
.usuario[data-estado="critico"] .usuario-dias { color: var(--u-critico); }

.usuario-acciones { padding: 6px; }
/* Sirve para <a> y para <button> — "Panel de administración" es un
   boton porque abre un modal, no navega a ningun lado.

   Las cuatro primeras declaraciones existen SOLO por el <button>:
   base/02-reset.css no resetea `button`, asi que sin esto el UA le
   pone su fondo gris, su borde y su tipografia de sistema, y el item
   desentona con los <a> de al lado. En un <a> no cambian nada: ya es
   display:block a ancho completo, sin fondo ni borde, y heredando la
   fuente. Por eso van aca y no en una regla aparte. */
.usuario-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  font-family: inherit;
  line-height: inherit;
  cursor: pointer;

  padding: 9px 12px;
  border-radius: var(--radius-sm);
  font-size: .78rem; color: var(--text-2);
  text-decoration: none;
  transition: background .15s, color .15s;
}
.usuario-item:hover,
.usuario-item:focus-visible {
  background: var(--accent-dim);
  color: var(--accent-2);
}
/* Mismo motivo que arriba: --accent-dim es un fondo al 8 %, no un
   anillo de foco. Va por dentro para no empujar el ancho del menu. */
.usuario-item:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: -2px;
}
body.dark-mode .usuario-item:focus-visible { outline-color: var(--accent); }
html.dark-mode .usuario-item:hover,
body.dark-mode .usuario-item:hover,
html.dark-mode .usuario-item:focus-visible,
body.dark-mode .usuario-item:focus-visible { color: var(--accent); }
.usuario-salir { color: var(--gray); }

/* ── Mobile ──────────────────────────────────────────────────
   Solo el circulo. El navbar en 375 px ya lleva logo, chip de cupo
   y toggle de tema; el nombre es lo primero que sobra, y adentro
   del menu esta completo. */
@media (max-width: 600px) {
  .usuario-nombre, .usuario-flecha { display: none; }
  .usuario-btn { padding: 3px; border-radius: 50%; }

  /* ⚠️ EL MENU CUELGA DEL NAVBAR, NO DEL BOTON.
     ------------------------------------------------------------
     BUG QUE ARREGLA (2026-09, reportado desde un iPhone)
     El menu es `position: absolute; right: 0`, y su ancla era
     `.usuario` (el unico `position: relative` cercano). O sea que
     su borde derecho quedaba pegado al borde derecho del AVATAR.
     Eso funciona mientras el avatar sea lo ultimo del navbar —el
     caso de los apuntes, donde solo lo sigue el toggle de tema—
     pero en la Biblioteca despues del avatar vienen todavia el
     bloque "Profe Seba / Nivel ..." y el boton de compartir. En
     375 px el avatar termina cerca de los 185 px, y un menu de
     250 px colgado de ahi se iba 65 px afuera de la pantalla por
     la IZQUIERDA: el mail y las dos acciones quedaban cortados.

     `max-width: calc(100vw - 32px)` no lo salvaba porque el
     problema no era el ancho sino el punto de anclaje.

     LA SOLUCION es quitarle el `position: relative` a `.usuario`:
     el ancla pasa a ser el ancestro posicionado siguiente, que en
     las dos paginas es el navbar (`position: fixed`, de borde a
     borde). Con eso:
       · `right`/`left` se miden contra el viewport → nunca se
         desborda, sea cual sea el lugar del avatar en la barra.
       · el `top: calc(100% + 12px)` del bloque base ya no es
         "debajo del avatar" sino "debajo de la barra", que es
         justo donde se lo espera en mobile. No hay que tocarlo,
         ni hardcodear --navbar-h, ni sumar el safe-area: sale del
         alto real de la barra.

     NO se usa `position: fixed` a proposito: los dos navbars
     llevan `backdrop-filter`, y un ancestro con backdrop-filter se
     vuelve el containing block de sus descendientes fixed. Es
     exactamente la trampa que ya documenta nucleo/usuario.js para
     el modal de admin, que por eso tiene que mudarse al <body>. */
  .usuario { position: static; }
  .usuario-menu {
    left: 12px; right: 12px;
    width: auto;
    max-width: 340px;      /* anula el calc(100vw - 32px) del base */
    margin-left: auto;     /* con left+right, esto lo pega a la derecha */
  }
}

/* En papel el navbar entero ya se oculta (base/06-impresion.css).
   Esto es por si un layout futuro decide mostrarlo. */
@media print { .usuario { display: none !important; } }
