/* ============================================================
   School Community · capa de aplicación
   ------------------------------------------------------------
   Se apoya en el sistema de diseño S-Community (ds/s-community.css),
   que aporta tokens, tipografía Poppins y componentes: boton, campo,
   alerta, tabla, badge, chip, cons-pill, tarjeta-stat, proposito,
   vacio, skel y los primitivos de página.

   Aquí va SOLO lo que el kit no cubre, siempre con sus tokens:
   iconos por máscara, shell (sidebar + topbar), login, selector de
   perfil, modal, menú desplegable, avisos y extras de tabla.

   Sin Bootstrap ni CDN: la tipografía y los iconos son locales.
   ============================================================ */

/* ============================================================
   ICONOS · assets del kit pintados con currentColor
   ------------------------------------------------------------
   Los SVG traen colores propios (#90939a, #2b223b, #6b4dd1), así que
   se usan como máscara para que hereden el color del contexto: es la
   técnica que recomienda el kit.

   La ruta va en una clase por icono y NO en un custom property: dentro
   de una custom property, Chrome resuelve el url() relativo contra esta
   hoja de estilos en el momento de sustituirla, de modo que un
   'url(ds/…)' escrito en el HTML terminaba buscando 'css/ds/…' (404) y
   la máscara quedaba vacía. Declarado aquí, '../ds/…' es determinista.
   ============================================================ */
.ico {
  display: inline-block; flex: none;
  width: 1.15rem; height: 1.15rem;
  background: currentColor;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.ico--sm { width: 0.9rem; height: 0.9rem; }
.ico--lg { width: 1.4rem; height: 1.4rem; }
/* flecha.svg apunta abajo y flecha-2.svg a la derecha: el resto se gira. */
.ico--arriba { transform: rotate(180deg); }
.ico--izq { transform: rotate(180deg); }

/* Los 22 iconos del kit. */
.ico--buscar { -webkit-mask-image: url(../ds/assets/iconos/buscar.svg); mask-image: url(../ds/assets/iconos/buscar.svg); }
.ico--calendario { -webkit-mask-image: url(../ds/assets/iconos/calendario.svg); mask-image: url(../ds/assets/iconos/calendario.svg); }
.ico--cerrar-sesion { -webkit-mask-image: url(../ds/assets/iconos/cerrar-sesion.svg); mask-image: url(../ds/assets/iconos/cerrar-sesion.svg); }
.ico--cerrar { -webkit-mask-image: url(../ds/assets/iconos/cerrar.svg); mask-image: url(../ds/assets/iconos/cerrar.svg); }
.ico--check { -webkit-mask-image: url(../ds/assets/iconos/check.svg); mask-image: url(../ds/assets/iconos/check.svg); }
.ico--configuracion { -webkit-mask-image: url(../ds/assets/iconos/configuracion.svg); mask-image: url(../ds/assets/iconos/configuracion.svg); }
.ico--cursos { -webkit-mask-image: url(../ds/assets/iconos/cursos.svg); mask-image: url(../ds/assets/iconos/cursos.svg); }
.ico--despliegue-menu { -webkit-mask-image: url(../ds/assets/iconos/despliegue-menu.svg); mask-image: url(../ds/assets/iconos/despliegue-menu.svg); }
.ico--editar { -webkit-mask-image: url(../ds/assets/iconos/editar.svg); mask-image: url(../ds/assets/iconos/editar.svg); }
.ico--editar_1 { -webkit-mask-image: url(../ds/assets/iconos/editar_1.svg); mask-image: url(../ds/assets/iconos/editar_1.svg); }
.ico--eliminar { -webkit-mask-image: url(../ds/assets/iconos/eliminar.svg); mask-image: url(../ds/assets/iconos/eliminar.svg); }
.ico--exportar { -webkit-mask-image: url(../ds/assets/iconos/exportar.svg); mask-image: url(../ds/assets/iconos/exportar.svg); }
.ico--filtros { -webkit-mask-image: url(../ds/assets/iconos/filtros.svg); mask-image: url(../ds/assets/iconos/filtros.svg); }
.ico--finanza { -webkit-mask-image: url(../ds/assets/iconos/finanza.svg); mask-image: url(../ds/assets/iconos/finanza.svg); }
.ico--flecha { -webkit-mask-image: url(../ds/assets/iconos/flecha.svg); mask-image: url(../ds/assets/iconos/flecha.svg); }
.ico--flecha-2 { -webkit-mask-image: url(../ds/assets/iconos/flecha-2.svg); mask-image: url(../ds/assets/iconos/flecha-2.svg); }
.ico--historial { -webkit-mask-image: url(../ds/assets/iconos/historial.svg); mask-image: url(../ds/assets/iconos/historial.svg); }
.ico--inicio { -webkit-mask-image: url(../ds/assets/iconos/inicio.svg); mask-image: url(../ds/assets/iconos/inicio.svg); }
.ico--matricula { -webkit-mask-image: url(../ds/assets/iconos/matricula.svg); mask-image: url(../ds/assets/iconos/matricula.svg); }
.ico--mi-perfil { -webkit-mask-image: url(../ds/assets/iconos/mi-perfil.svg); mask-image: url(../ds/assets/iconos/mi-perfil.svg); }
.ico--notificacion { -webkit-mask-image: url(../ds/assets/iconos/notificacion.svg); mask-image: url(../ds/assets/iconos/notificacion.svg); }
.ico--nueva-matricula { -webkit-mask-image: url(../ds/assets/iconos/nueva-matricula.svg); mask-image: url(../ds/assets/iconos/nueva-matricula.svg); }
.ico--ver { -webkit-mask-image: url(../ds/assets/iconos/ver.svg); mask-image: url(../ds/assets/iconos/ver.svg); }

/* ============================================================
   ESTRUCTURA MÍNIMA (el kit no trae grilla)
   ============================================================ */
.sc-grid { display: grid; gap: var(--esp-md); grid-template-columns: repeat(auto-fill, minmax(var(--min, 220px), 1fr)); }
.sc-split { display: grid; gap: var(--esp-lg); grid-template-columns: 1.4fr 1fr; align-items: start; }
.sc-fila { display: flex; align-items: center; gap: var(--esp-sm); flex-wrap: wrap; }
.sc-crece { flex: 1; min-width: 200px; }
.sc-card { background: var(--color-fondo); border: 1px solid var(--color-borde); border-radius: var(--radio-card); box-shadow: var(--sombra-suave); padding: var(--esp-lg); }
@media (max-width: 980px) { .sc-split { grid-template-columns: 1fr; } }

/* ============================================================
   SHELL · sidebar + topbar + contenido
   ============================================================ */
.sc-shell { display: flex; min-height: 100vh; background: var(--color-superficie); }

.sc-sidebar {
  width: 254px; flex: none; background: var(--color-fondo);
  border-right: 1px solid var(--color-borde);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
  /* transform tiene que estar en la lista: sin él, el «.abierta { transform:
     none }» del cajón móvil no anima nada y el menú aparece de golpe. */
  transition: width var(--dur-media) var(--curva-estandar),
              transform var(--dur-media) var(--curva-estandar);
}
.sc-sidebar.plegada { width: 76px; }

.sc-sidebar .marca { display: flex; align-items: center; gap: var(--esp-sm); padding: var(--esp-md) var(--esp-md) var(--esp-sm); }
.sc-sidebar .marca img { width: 34px; height: auto; flex: none; }
.sc-sidebar .marca span { font-weight: var(--peso-semi); letter-spacing: -0.01em; white-space: nowrap; }
.sc-sidebar.plegada .marca { justify-content: center; }
.sc-sidebar.plegada .marca span,
.sc-sidebar.plegada .nav-grupo,
.sc-sidebar.plegada .nav-txt { display: none; }

.sc-nav { flex: 1; overflow-y: auto; padding: var(--esp-xs) var(--esp-sm) var(--esp-md); }
.nav-grupo {
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--color-texto-suave); font-weight: var(--peso-semi);
  margin: var(--esp-md) 0.6rem var(--esp-xs);
}
/* Base de datos a la que pertenece el grupo del menú. */
.nav-grupo__bd {
  display: block; margin-top: 2px;
  font-size: 0.6rem; text-transform: none; letter-spacing: 0;
  font-weight: var(--peso-regular); color: var(--color-primario-oscuro); opacity: 0.75;
}
.sc-sidebar.plegada .nav-grupo__bd { display: none; }

/* Grupo plegable. Los catálogos de referencia y la seguridad se tocan una vez
   al año y ocupaban un tercio del menú; ahora se abren cuando hacen falta.
   Hereda de .nav-grupo para que abierto y fijo se vean igual: lo único que
   cambia es que uno responde al clic. */
.nav-grupo--plegable {
  display: flex; align-items: center; justify-content: space-between; gap: var(--esp-xs);
  width: calc(100% - 1.2rem);
  background: none; border: 0; cursor: pointer; text-align: left;
  /* Solo la FAMILIA se hereda. Un `font: inherit` borraría el tamaño y el grosor
     que define .nav-grupo, y el título del grupo dejaría de parecerse a los
     demás: fue exactamente lo que pasó la primera vez. Por lo mismo no se tocan
     aquí text-transform ni letter-spacing — manda .nav-grupo. */
  font-family: inherit;
  border-radius: var(--radio-sm);
  padding: 0.15rem 0.25rem; margin-left: 0.35rem;
  transition: color var(--dur-rapida) var(--curva-estandar),
              background-color var(--dur-rapida) var(--curva-estandar);
}
.nav-grupo--plegable:hover { color: var(--color-primario-oscuro); background: var(--color-superficie-2); }
.nav-grupo--plegable:focus-visible { outline: 2px solid var(--color-primario); outline-offset: 2px; }
/* Misma convención que el chip de usuario: flecha.svg apunta abajo y gira al
   abrir. Un «+»/«−» de texto no es del kit y además saltaba de ancho. */
.nav-grupo--plegable .ico { opacity: 0.7; transition: transform var(--dur-rapida) var(--curva-estandar); }
.nav-grupo--plegable.abierto .ico--flecha { transform: rotate(180deg); }
.sc-sidebar.plegada .nav-grupo--plegable { display: none; }
.sc-nav a {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.5rem 0.65rem; margin-bottom: 2px;
  border-radius: var(--radio-input);
  color: var(--color-texto); text-decoration: none;
  font-size: var(--texto-label); white-space: nowrap;
  transition: background-color var(--dur-rapida) var(--curva-estandar),
              color var(--dur-rapida) var(--curva-estandar);
}
/* El rótulo de cada opción se ajusta al ancho del menú PARTIENDO a una segunda
   línea dentro de la misma opción (en vez de recortarse con «…»). Las palabras
   quedan ENTERAS: los rótulos con espacio parten ahí y «Sostenedor/Apoderado»
   parte en la «/» (un <wbr> que inserta renderNav). white-space:normal anula el
   nowrap del enlace; min-width:0 deja encoger la columna de texto. */
.nav-txt { flex: 1; min-width: 0; white-space: normal; line-height: 1.25; overflow-wrap: anywhere; }
.sc-nav a:hover { background: var(--color-superficie-2); text-decoration: none; }
/* Sobre lila claro va la ciruela, no blanco: el blanco no pasa WCAG AA. */
.sc-nav a.activo { background: var(--color-primario); color: var(--color-sobre-marca); font-weight: var(--peso-medio); }
.sc-sidebar.plegada .sc-nav a { justify-content: center; padding: 0.6rem; }

.sc-sidebar__pie { border-top: 1px solid var(--color-borde); padding: var(--esp-xs) var(--esp-sm); }
.sc-salir {
  display: flex; align-items: center; gap: 0.7rem; width: 100%;
  padding: 0.55rem 0.65rem; border: none; background: none;
  border-radius: var(--radio-input); cursor: pointer;
  color: var(--color-error); font-size: var(--texto-label); font-family: inherit;
}
.sc-salir:hover { background: var(--color-error-bg); }
.sc-sidebar.plegada .sc-salir { justify-content: center; }

.sc-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.sc-topbar {
  height: 62px; flex: none; background: var(--color-fondo);
  border-bottom: 1px solid var(--color-borde);
  display: flex; align-items: center; gap: var(--esp-sm);
  padding: 0 var(--esp-md); position: sticky; top: 0; z-index: 40;
}
.sc-topbar__espacio { flex: 1; }
.boton-icono {
  display: grid; place-items: center; width: 38px; height: 38px; flex: none;
  border: none; border-radius: var(--radio-input); background: var(--color-superficie);
  color: var(--color-texto); cursor: pointer; position: relative;
}
.boton-icono:hover { background: var(--color-superficie-2); }
.boton-icono__punto {
  position: absolute; top: 7px; right: 8px; width: 8px; height: 8px;
  border-radius: 999px; background: var(--color-error); border: 2px solid var(--color-fondo);
}

/* Contexto activo (perfil + centro elegidos al ingresar) */
.ctx-chip {
  display: inline-flex; align-items: center; gap: 0.4rem; max-width: 42vw;
  padding: 0.35rem 0.75rem; border-radius: 999px;
  background: var(--color-lila-suave); color: var(--color-primario-oscuro);
  font-size: var(--texto-pequeno); font-weight: var(--peso-semi);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.usuario-chip {
  display: flex; align-items: center; gap: 0.6rem; padding: 0.3rem 0.5rem 0.3rem 0.35rem;
  border: none; background: none; border-radius: var(--radio-input); cursor: pointer;
  font-family: inherit; color: var(--color-texto); text-align: left;
}
.usuario-chip:hover { background: var(--color-superficie); }
.usuario-chip__txt { display: grid; gap: 1px; }
.usuario-chip__nombre { font-size: var(--texto-label); font-weight: var(--peso-semi); line-height: 1.15; }
.usuario-chip__sub { font-size: var(--texto-pequeno); color: var(--color-texto-suave); line-height: 1.15; }
@media (max-width: 700px) { .usuario-chip__txt { display: none; } }
.avatar {
  display: grid; place-items: center; flex: none;
  width: 36px; height: 36px; border-radius: var(--radio-input);
  background: var(--color-lila); color: var(--color-sobre-marca); font-weight: var(--peso-semi);
}
.avatar--grande { width: 62px; height: 62px; border-radius: var(--radio-card); font-size: 1.5rem; }

.sc-contenido { flex: 1; padding: var(--esp-lg); }

/* ============================================================
   MENÚ DESPLEGABLE (el kit no trae dropdown)
   ============================================================ */
.menu { position: relative; }
.menu__lista {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 232px;
  background: var(--color-fondo); border: 1px solid var(--color-borde);
  border-radius: var(--radio-card); box-shadow: var(--sombra-card);
  padding: 0.35rem; z-index: 60; display: none;
}
.menu.abierto .menu__lista { display: block; animation: aparece var(--dur-rapida) var(--curva-entra); }
/* Salida: se mantiene visible mientras se va. La clase la quita app.js al
   terminar la animación (con setTimeout de respaldo). */
.menu--cerrando .menu__lista { display: block; animation: desaparece var(--dur-instante) var(--curva-sale) forwards; }
/* El disparador retiene el estado abierto: al salir el cursor del botón, algo
   tiene que seguir diciendo de dónde salió el panel. */
.menu.abierto .usuario-chip,
.menu.abierto .boton-icono { background: var(--color-superficie-2); }
.menu.abierto .usuario-chip .ico--flecha { transform: rotate(180deg); }
.menu__titulo { padding: 0.5rem 0.6rem 0.35rem; font-size: var(--texto-pequeno); color: var(--color-texto-suave); }
.menu__sep { height: 1px; background: var(--color-borde); margin: 0.3rem 0; }
.menu__item {
  display: flex; align-items: center; gap: 0.6rem; width: 100%;
  padding: 0.5rem 0.6rem; border: none; background: none; border-radius: 8px;
  font-family: inherit; font-size: var(--texto-label); color: var(--color-texto);
  text-align: left; cursor: pointer; text-decoration: none;
}
.menu__item:hover { background: var(--color-superficie); text-decoration: none; }
.menu__item--peligro { color: var(--color-error); }
.menu__item--peligro:hover { background: var(--color-error-bg); }
.menu__vacio { padding: 0.6rem; font-size: var(--texto-pequeno); color: var(--color-texto-suave); }

/* ============================================================
   MODAL (el kit no trae modal)
   ============================================================ */
.modal { position: fixed; inset: 0; z-index: 1000; display: none; }
.modal.abierto { display: block; }
.modal__fondo { position: absolute; inset: 0; background: rgba(36, 29, 51, 0.45); }
.modal__caja {
  position: relative; margin: 6vh auto; width: calc(100% - 2rem); max-width: 720px;
  max-height: 88vh; display: flex; flex-direction: column;
  background: var(--color-fondo); border-radius: var(--radio-card);
  box-shadow: var(--sombra-card); animation: aparece var(--dur-media) var(--curva-entra);
}
.modal--chico .modal__caja { max-width: 460px; }
/* Ancho a pedido (Modal.abrir(id, { ancho: true })): gana sobre --chico. */
.modal.modal--ancho .modal__caja { max-width: 900px; }
/* Visor de PDF: ancho de documento y alto casi completo; el PDF ocupa el cuerpo. */
.modal--pdf .modal__caja { max-width: 920px; height: 88vh; }
.modal__cuerpo--pdf { flex: 1; padding: 0; overflow: hidden; background: var(--color-superficie); }
.modal__cuerpo--pdf iframe { display: block; width: 100%; height: 100%; border: 0; }
.modal__pdf-aviso { padding: var(--esp-xl) var(--esp-lg); text-align: center; color: var(--color-texto-suave); }
.modal__pdf-aviso strong { color: var(--color-texto); font-size: var(--texto-grande); }
/* Escaneo del QR del pagaré (29-10): ventana ancha partida en dos, a la izquierda
   cómo leer el código y a la derecha lo que dice el pagaré. En pantallas angostas
   queda una columna, con el resultado debajo. */
.modal--qr .modal__caja { max-width: 1120px; min-height: min(620px, 88vh); }
.modal--qr .modal__cuerpo { flex: 1; }
.qr-split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--esp-lg); align-items: stretch; }
.qr-split__titulo { margin: 0 0 var(--esp-sm); font-size: var(--texto-label); font-weight: var(--peso-semi); }
.qr-split__resultado {
  background: var(--color-superficie); border: 1px solid var(--color-borde);
  border-radius: var(--radio-card); padding: var(--esp-md) var(--esp-lg);
}
.qr-split__vacio { display: grid; place-items: center; min-height: 12rem; margin: 0; text-align: center; color: var(--color-texto-suave); }
@media (max-width: 820px) { .qr-split { grid-template-columns: 1fr; } }
/* La vista de la cámara ocupa el ancho de su columna. */
.qr-video { display: block; width: 100%; max-height: 50vh; background: #000; border-radius: var(--radio-card); object-fit: cover; }
/* Sin visor, la ventana no necesita el alto de un documento. */
.modal--pdf.sin-visor .modal__caja { height: auto; }
/* «Firmar contrato» (30-10): el QR del link de firma, centrado. El código lleva
   fondo blanco propio: en modo oscuro también se escanea. */
.firma-qr { text-align: center; }
.firma-qr__codigo {
  display: block; width: 232px; max-width: 100%; height: auto; margin: 0 auto var(--esp-md);
  padding: var(--esp-xs); background: #fff; border: 1px solid var(--color-borde); border-radius: var(--radio-card);
}
.firma-qr__titulo { margin: 0 0 var(--esp-xs); font-size: var(--texto-grande); font-weight: var(--peso-semi); }
.firma-qr__texto { margin: 0 0 var(--esp-sm); color: var(--color-texto-suave); }
.firma-qr__estado { margin: 0; font-size: var(--texto-pequeno); color: var(--color-texto-suave); }
.modal--firma .modal__pie { justify-content: center; }

/* El velo fundía de golpe en el frame 0: un 45% de negro a pantalla completa es
   lo más brusco que hacía el panel. Y el cierre no estaba animado por ninguno de
   sus cinco caminos (fondo, X, Cancelar, Escape, guardado correcto). */
@keyframes velo { from { opacity: 0; } }
.modal.abierto .modal__fondo { animation: velo var(--dur-media) var(--curva-entra); }
.modal--cerrando .modal__fondo { animation: velo var(--dur-rapida) var(--curva-sale) reverse forwards; }
.modal--cerrando .modal__caja { animation: desaparece var(--dur-rapida) var(--curva-sale) forwards; }
.modal__cabecera {
  display: flex; align-items: center; justify-content: space-between; gap: var(--esp-md);
  padding: var(--esp-md) var(--esp-lg); border-bottom: 1px solid var(--color-borde);
}
.modal__titulo { margin: 0; font-size: var(--texto-grande); font-weight: var(--peso-semi); }
.modal__cerrar {
  display: grid; place-items: center; width: 32px; height: 32px; flex: none;
  border: none; background: none; border-radius: 8px; cursor: pointer;
  color: var(--color-texto-suave); font-size: 1.3rem; line-height: 1;
}
.modal__cerrar:hover { background: var(--color-superficie); color: var(--color-texto); }
.modal__cuerpo { padding: var(--esp-lg); overflow-y: auto; }
.modal__pie {
  display: flex; justify-content: flex-end; gap: var(--esp-sm);
  padding: var(--esp-md) var(--esp-lg); border-top: 1px solid var(--color-borde);
}
body.sin-scroll { overflow: hidden; }

/* Rejilla de campos dentro del formulario del modal */
.form-grid { display: grid; gap: var(--esp-md) var(--esp-md); grid-template-columns: 1fr 1fr; }
.form-grid .campo { margin-bottom: 0; }
.form-grid__ancho { grid-column: 1 / -1; }
@media (max-width: 620px) { .form-grid { grid-template-columns: 1fr; } }

/* ============================================================
   CARGA · el kit trae skeletons; para botones hace falta un spinner
   ============================================================ */
@keyframes girar { to { transform: rotate(360deg); } }
.spinner {
  display: inline-block; flex: none; width: 1.05rem; height: 1.05rem;
  border: 2px solid rgba(36, 29, 51, 0.22); border-top-color: currentColor;
  border-radius: 999px; animation: girar 0.6s linear infinite;
}
.cargando { display: flex; align-items: center; justify-content: center; gap: 0.6rem; padding: var(--esp-xl); color: var(--color-texto-suave); font-size: var(--texto-label); }
.oculto { display: none !important; }

/* Botón ocupado: el spinner va como ::after encima del rótulo, que conserva su
   sitio. Antes se ocultaba el rótulo y el botón encogía de golpe, arrastrando a
   los botones vecinos del pie del modal. */
.boton--cargando { position: relative; color: transparent; }
.boton--cargando::after,
.boton-mini--cargando::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 1.05rem; height: 1.05rem;
  border: 2px solid rgba(36, 29, 51, 0.22);
  /* --color-texto y no currentColor: el propio botón se pone transparente. */
  border-top-color: var(--color-texto);
  border-radius: 999px; animation: girar 0.6s linear infinite;
}

/* Un indicador de carga tiene que seguir indicando: con movimiento reducido se
   ralentiza, no se apaga. Los !important son imprescindibles — el comodín del
   kit pone animation-iteration-count:1 y sin esto los spinners se congelan,
   que es peor que no haber tocado nada. */
@media (prefers-reduced-motion: reduce) {
  .spinner, .boton--cargando::after, .boton-mini--cargando::after {
    animation-duration: 1.8s !important;
    animation-iteration-count: infinite !important;
  }
}

/* ============================================================
   ASISTENTE POR PASOS (matrícula)
   ============================================================ */
.pasos { display: flex; gap: var(--esp-xs); flex-wrap: wrap; margin-bottom: var(--esp-lg); }
/* La ruta del trámite en la tarjeta de Mis alumnos (28-10): los mismos chips, sin navegación. */
.pasos--tramite { margin: var(--esp-sm) 0 0; }
/* Los chips son nodos ESTABLES: app.js los pinta una vez y luego solo alterna
   clases. Mientras se reconstruía el innerHTML en cada paso, ninguna transición
   podía dispararse — el reparto pintar-una-vez / alternar-clases es la condición
   del efecto, no un detalle de estilo. */
.paso {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.4rem 0.85rem; border-radius: 999px;
  border: 1px solid var(--color-borde); background: var(--color-fondo);
  color: var(--color-texto-suave); font-size: var(--texto-pequeno); font-weight: var(--peso-medio);
}
.paso__n {
  display: grid; place-items: center; width: 20px; height: 20px; flex: none;
  border-radius: 999px; background: var(--color-superficie-2);
  color: var(--color-texto-suave); font-size: 0.7rem; font-weight: var(--peso-semi);
}
.paso, .paso__n {
  transition: background-color var(--dur-rapida) var(--curva-estandar),
              border-color var(--dur-rapida) var(--curva-estandar),
              color var(--dur-rapida) var(--curva-estandar);
}
/* Los chips de los asistentes de matrícula son NAVEGACIÓN (21-08): se salta
   libremente de una sección a otra clicándolos — la puerta está en el botón
   final. Acotado por id a los DOS asistentes que sí navegan (el del panel y
   el del portal del apoderado): un cursor de mano sobre un chip muerto
   promete un clic que no hace nada. */
#mtPasos .paso, #pwPasos .paso { cursor: pointer; }
#mtPasos .paso:hover, #pwPasos .paso:hover { border-color: var(--color-primario); color: var(--color-primario-oscuro); }
#mtPasos .paso:focus-visible, #pwPasos .paso:focus-visible { outline: 2px solid var(--color-primario-oscuro); outline-offset: 2px; }

/* Enlaces dentro de la alerta ámbar (secciones pendientes del asistente):
   el <a> del kit (lila, sin subrayado) es casi idéntico en luminosidad al
   texto ámbar que lo rodea — invisible como enlace. Mismo ámbar oscurecido
   del aviso de Bloq Mayús (4.5:1+ sobre este fondo) y SIEMPRE subrayado. */
.alerta--aviso a {
  color: #8f5d07; text-decoration: underline; font-weight: var(--peso-semi);
}
.paso--activo { border-color: var(--color-primario); background: var(--color-lila-suave); color: var(--color-primario-oscuro); }
.paso--activo .paso__n { background: var(--color-primario); color: var(--color-sobre-marca); }
.paso--hecho { border-color: var(--color-exito-bg); color: var(--color-exito); }
.paso--hecho .paso__n { background: var(--color-exito); color: #fff; }

/* El número se convierte en ✓ y lo confirma con el rebote corto. Es uno de los
   dos únicos sitios donde se usa --curva-firme. */
.paso__ok { display: none; }
.paso--hecho .paso__num { display: none; }
.paso--hecho .paso__ok { display: inline; }
@keyframes confirma { from { transform: scale(0.6); } }
.paso--hecho .paso__n { animation: confirma var(--dur-media) var(--curva-firme); }

.asistente__panel { display: none; }
.asistente__panel.activo { display: block; animation: aparece var(--dur-media) var(--curva-entra); }
/* Retroceder no puede sentirse igual que avanzar: el panel entra desde arriba. */
@keyframes aparece-atras { from { opacity: 0; transform: translateY(calc(var(--desp-entrada) * -1)); } }
.asistente--atras .asistente__panel.activo { animation-name: aparece-atras; }
.asistente__pie {
  display: flex; justify-content: space-between; gap: var(--esp-sm);
  margin-top: var(--esp-lg); padding-top: var(--esp-md); border-top: 1px solid var(--color-borde);
}
.asistente__pie .sc-fila { gap: var(--esp-xs); }

/* Cabecera INMUTABLE del asistente del apoderado: lo que fija el colegio
   (establecimiento, curso, año, identidad del alumno) se presenta como
   información — un recuadro sereno — y no como campos deshabilitados, que
   parecerían un formulario roto. */
.inmutable {
  background: var(--color-superficie-2);
  border: 1px solid var(--color-borde);
  border-radius: var(--radio-input);
  padding: var(--esp-md);
  margin-bottom: var(--esp-md);
}
.inmutable__cab {
  display: flex; align-items: center; gap: var(--esp-sm);
  margin-bottom: var(--esp-sm);
}
.inmutable__logo {
  width: 40px; height: 40px; flex: none; object-fit: contain;
  border-radius: var(--radio-sm); background: var(--color-fondo);
  border: 1px solid var(--color-borde-suave); padding: 3px;
}
.inmutable__colegio { font-weight: var(--peso-semi); font-size: var(--texto-grande); }
.inmutable__nota { color: var(--color-texto-suave); font-size: var(--texto-pequeno); }

/* ============================================================
   AVISOS FLOTANTES
   ============================================================ */
/* gap: 0 + margin-top en el hijo, a propósito. El gap del flex no es animable
   por hijo, así que al expirar un aviso del medio los de abajo daban un tirón;
   el margin sí interpola y el hueco se cierra en continuo. */
.avisos { position: fixed; right: var(--esp-md); bottom: var(--esp-md); z-index: 1100; display: flex; flex-direction: column; gap: 0; }
.aviso {
  display: flex; align-items: flex-start; gap: 0.6rem;
  min-width: 260px; max-width: 380px; padding: 0.8rem 1rem;
  margin-top: var(--esp-xs); overflow: hidden;
  background: var(--color-fondo); border: 1px solid var(--color-borde);
  border-left: 4px solid var(--color-primario);
  border-radius: var(--radio-input); box-shadow: var(--sombra-card);
  font-size: var(--texto-label); animation: aparece var(--dur-media) var(--curva-entra);
}
@keyframes aviso-sale {
  to { opacity: 0; transform: translateX(12px); max-height: 0; margin-top: 0; padding-top: 0; padding-bottom: 0; }
}
.aviso--saliendo { animation: aviso-sale var(--dur-rapida) var(--curva-sale) forwards; }
.aviso__ico { flex: none; font-weight: var(--peso-bold); line-height: 1.4; }
.aviso--ok { border-left-color: var(--color-exito); }
.aviso--ok .aviso__ico { color: var(--color-exito); }
.aviso--error { border-left-color: var(--color-error); }
.aviso--error .aviso__ico { color: var(--color-error); }

/* Select compacto para barras de herramientas (el .campo__select del kit es 100%) */
.select-inline { width: auto; padding: 0.55rem 0.8rem; font-size: var(--texto-label); }

/* ============================================================
   EXTRAS DE TABLA (sobre .tabla del kit)
   ============================================================ */
.tabla th.ordenable { cursor: pointer; user-select: none; white-space: nowrap; }
.tabla th.ordenable:hover { color: var(--color-primario-oscuro); }
.tabla th .ico { opacity: 0.4; margin-left: 0.3rem; vertical-align: middle; }
.tabla th.ordenada { color: var(--color-primario-oscuro); }
.tabla th.ordenada .ico { opacity: 1; }
.tabla td.ancho { white-space: normal; min-width: 220px; }
.tabla td .mono { font-size: var(--texto-pequeno); color: var(--color-texto-suave); }

/* Recarga EN EL SITIO. Ordenar, paginar, buscar o recargar ya no colapsan la
   tabla a un skeleton: se atenúa y se queda donde estaba, así la fila que
   mirabas no se mueve y el botón que ibas a pulsar no huye del cursor.
   pointer-events:none impide el doble clic sobre datos que se están renovando. */
.tabla-wrap { transition: opacity var(--dur-rapida) var(--curva-estandar); }
.tabla-wrap--ocupada { opacity: 0.55; pointer-events: none; }

/* La fila que el usuario mandó eliminar se va; no desaparece sin más. */
.tabla tbody tr.fila--sale {
  opacity: 0; transform: translateX(10px);
  transition: opacity var(--dur-rapida) var(--curva-sale),
              transform var(--dur-rapida) var(--curva-sale);
}

.acciones-fila { display: flex; gap: 0.3rem; justify-content: flex-end; }
/* Los iconos del kit son de línea fina: a 0.9rem casi desaparecían, así que en las
   acciones de fila van a tamaño completo y con el color de texto principal. */
.boton-mini {
  position: relative;
  display: grid; place-items: center; width: 32px; height: 32px; flex: none;
  border: 1px solid var(--color-borde); border-radius: 8px;
  background: var(--color-fondo); color: var(--color-texto); cursor: pointer;
}
.boton-mini:hover:not(:disabled) { background: var(--color-superficie-2); }
.boton-mini:disabled { opacity: 0.4; cursor: not-allowed; }
.boton-mini .ico { width: 1.05rem; height: 1.05rem; }
.boton-mini--peligro { color: var(--color-error); }
.boton-mini--peligro:hover:not(:disabled) { background: var(--color-error-bg); border-color: var(--color-error); }
/* Ocupado: el icono deja sitio al spinner del mismo tamaño, así que la celda no
   cambia de ancho y la fila no se mueve. El opacity:1 gana al 0.4 de :disabled,
   que si no apagaría el propio indicador. */
.boton-mini--cargando .ico { opacity: 0; }
.boton-mini--cargando:disabled { opacity: 1; cursor: progress; }

/* Acción de fila CON RÓTULO («Editar datos» en el listado de alumnos): a
   diferencia de las acciones de icono, abre la ficha de la PERSONA y no un
   CRUD del listado, así que se nombra. Hereda todo lo demás de .boton-mini
   (borde, foco, spinner de ocupado). */
.boton-mini--rotulado {
  width: auto; padding: 0 0.55rem;
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: var(--texto-pequeno); font-weight: 600; white-space: nowrap;
}

/* Pastilla de filtro apagada («Solo sin apoderado» cuando el perfil no puede
   leer los vínculos): el kit no trae :disabled para .cons-pill y sin esto el
   botón muerto parecía vivo. Mismos valores que .boton-mini:disabled. */
.cons-pill:disabled { opacity: 0.4; cursor: not-allowed; }
.cons-pill:disabled:hover { background: var(--color-fondo); }

/* ============================================================
   RESPUESTA AL PULSAR
   ------------------------------------------------------------
   Hasta aquí el único elemento del panel que acusaba un clic era .boton. Los
   ~77 botones de fila de una tabla de 25 filas cambiaban de fondo en seco y no
   decían nada hasta que contestaba la API.
   Esta hoja se carga después del kit, así que gana a .cons-pill sin !important.
   ============================================================ */
.boton-mini, .boton-icono, .usuario-chip, .menu__item, .modal__cerrar, .sc-salir,
.campo--clave .ojo, .tabla th.ordenable, .cons-pill {
  transition: background-color var(--dur-rapida) var(--curva-estandar),
              border-color var(--dur-rapida) var(--curva-estandar),
              color var(--dur-rapida) var(--curva-estandar),
              transform var(--dur-instante) var(--curva-estandar);
}
/* Sin el scale(0.99) que usa .boton: en cajas de 32px son 0.3px, no se ve y
   solo emborrona el texto. */
.boton-mini:active:not(:disabled), .boton-icono:active, .usuario-chip:active,
.menu__item:active, .modal__cerrar:active, .sc-salir:active,
.campo--clave .ojo:active, .cons-pill:active, .tarjeta-opcion:active {
  transform: translateY(1px);
}

/* Habilita el giro de la flecha de orden y del caret del desplegable. */
.ico { transition: transform var(--dur-rapida) var(--curva-estandar), opacity var(--dur-rapida) var(--curva-estandar); }
/* La lupa se pinta con background:currentColor, no con color: por eso la
   transición es de background-color. Se enciende al enfocar el campo, y el
   buscador aparece en los 39 listados. */
.buscador .ico { transition: background-color var(--dur-rapida) var(--curva-estandar); }
.buscador:focus-within .ico { color: var(--color-primario-oscuro); }

/* Tabulando por las acciones de una tabla larga hay que saber sobre qué
   registro se va a pulsar Eliminar. */
.tabla tbody tr:focus-within { background: var(--color-superficie); }
/* El gap entre acciones es de 0.3rem: sin esto los anillos de foco se tocan. */
.acciones-fila .boton-mini:focus-visible { outline-offset: 1px; }

.paginador {
  display: flex; align-items: center; justify-content: space-between; gap: var(--esp-sm);
  padding: var(--esp-sm) var(--esp-md); border-top: 1px solid var(--color-borde); flex-wrap: wrap;
  font-size: var(--texto-pequeno); color: var(--color-texto-suave);
}

/* Campo de búsqueda con el icono del kit dentro */
.buscador { position: relative; }
.buscador .ico {
  position: absolute; left: 0.85rem; top: 50%; transform: translateY(-50%);
  color: var(--color-texto-suave); pointer-events: none;
}
.buscador .campo__input { padding-left: 2.4rem; }

/* ============================================================
   LISTA DE DETALLE (pares etiqueta / valor)
   ============================================================ */
.detalle { margin: 0; }
.detalle > div {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--esp-md);
  padding: 0.6rem 0; border-bottom: 1px solid var(--color-borde-suave);
}
.detalle > div:last-child { border-bottom: none; }
.detalle dt { color: var(--color-texto-suave); font-size: var(--texto-label); }
.detalle dd { margin: 0; font-weight: var(--peso-semi); text-align: right; word-break: break-word; }
.detalle dd.mono { font-size: var(--texto-pequeno); font-weight: var(--peso-medio); color: var(--color-texto-suave); }

/* Tarjeta de estadística con icono (extiende .tarjeta-stat del kit) */
.tarjeta-stat { display: flex; align-items: center; gap: var(--esp-md); min-width: 0; }
/* Un rótulo largo SIN espacios («Sostenedor/Apoderado») se salía del recuadro: la
   columna de texto (hijo flex) no podía encogerse (min-width:auto). min-width:0 la
   deja encoger; el salto de línea cae en la «/» (un <wbr> que inserta el render),
   dejando las palabras ENTERAS, nunca cortando «Apoderado» a la mitad. */
.tarjeta-stat > :not(.tarjeta-stat__ico) { min-width: 0; }
.tarjeta-stat__ico {
  display: grid; place-items: center; flex: none; width: 48px; height: 48px;
  border-radius: var(--radio-input); background: var(--color-lila-suave); color: var(--color-primario-oscuro);
}
/* Marca de contador que no se puede acotar por centro. */
.tarjeta-stat__global {
  display: inline-block; margin-left: 0.3rem; padding: 0 0.3rem;
  border-radius: 999px; background: var(--color-superficie-2);
  color: var(--color-primario-oscuro); font-weight: var(--peso-bold); cursor: help;
}

/* Tonos del icono, todos dentro de la paleta del kit. */
.tarjeta-stat__ico--turquesa { background: rgba(72, 209, 211, 0.18); color: #1c7274; }
.tarjeta-stat__ico--verde { background: var(--color-exito-bg); color: var(--color-exito); }
.tarjeta-stat__ico--ambar { background: var(--color-aviso-bg); color: var(--color-aviso); }

/* ============================================================
   LOGIN · pantalla partida
   ============================================================ */
/* La fila se declara 1fr de forma explícita: el panel de marca solo tiene hijos
   absolutos (alto de contenido 0) y así no depende del estiramiento implícito
   del grid para llegar al borde inferior. */
.login-wrap {
  min-height: 100vh; display: grid;
  grid-template-columns: 1fr 1fr; grid-template-rows: 1fr;
  background: var(--color-fondo);
}
.login-marca { position: relative; overflow: hidden; }
.login-marca__fondo {
  position: absolute; inset: 0;
  background: linear-gradient(155deg, var(--color-primario) 0%, var(--color-lila) 55%, var(--color-lila-suave) 100%);
}
.login-marca__forma { position: absolute; border-radius: 22%; background: rgba(255, 255, 255, 0.16); }
.login-marca__forma--a { width: 220px; height: 220px; top: -60px; left: -60px; transform: rotate(18deg); }
.login-marca__forma--b { width: 140px; height: 140px; bottom: 14%; left: 8%; border-radius: 30%; background: rgba(255, 255, 255, 0.12); }
.login-marca__forma--c { width: 260px; height: 260px; border-radius: 50%; right: -80px; top: 12%; background: rgba(255, 255, 255, 0.14); }
.login-marca__logo {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 190px; height: auto; opacity: 0.4; filter: brightness(0) invert(1);
}
.login-marca__foto { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }

.login-lado { display: flex; align-items: center; justify-content: center; padding: var(--esp-xl) var(--esp-lg); background: var(--color-fondo); }
.login-card { width: 100%; max-width: 380px; }
.login-card__logo { width: 86px; height: auto; margin: 0 auto var(--esp-lg); }
.login-card h1 { font-size: var(--texto-titulo); font-weight: var(--peso-semi); letter-spacing: -0.015em; margin: 0 0 var(--esp-lg); text-align: center; }
.login-card__sub { color: var(--color-texto-suave); font-size: var(--texto-label); text-align: center; margin: -0.75rem 0 var(--esp-lg); line-height: 1.45; }
.login-card__fila { display: flex; align-items: center; justify-content: space-between; gap: var(--esp-sm); font-size: var(--texto-label); margin: 0 0 var(--esp-lg); }
.login-card__nota { color: var(--color-texto-suave); font-size: var(--texto-pequeno); text-align: center; margin: var(--esp-lg) 0 0; line-height: 1.5; }

.check { display: inline-flex; align-items: center; gap: 0.45rem; cursor: pointer; }
.check input { width: 1rem; height: 1rem; accent-color: var(--color-primario); }

/* Campo con prefijo fijo (p. ej. teléfono «+56»): el prefijo va pegado al input. */
.campo__prefijado { display: flex; align-items: stretch; }
.campo__prefijado .campo__input { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.campo__prefijo {
  display: flex; align-items: center; padding: 0 var(--esp-sm);
  border: 1px solid var(--color-borde); border-right: none;
  border-radius: var(--radio-input) 0 0 var(--radio-input);
  background: var(--color-superficie-2); color: var(--color-texto-suave); white-space: nowrap;
}

/* Ojo para mostrar/ocultar contraseña */
.campo--clave { position: relative; }
.campo--clave .campo__input { padding-right: 2.6rem; }
.campo--clave .ojo {
  position: absolute; right: 0.5rem; top: 2.45rem;
  display: grid; place-items: center; width: 34px; height: 34px;
  border: none; background: transparent; border-radius: 8px; cursor: pointer; color: var(--color-texto-suave);
  /* Sin esto, algunos navegadores (Chrome/Edge en Windows) igual pintan el
     borde y la sombra nativos de <button> encima de border:none/background:
     none, y el ícono queda metido dentro de una caja gris por defecto. */
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  box-shadow: none; outline: none;
}
.campo--clave .ojo .ico { width: 1.5rem; height: 1.5rem; }
.campo--clave .ojo:hover { background: var(--color-superficie); color: var(--color-primario-oscuro); }
/* Contraseña visible: el kit no tiene "ojo tachado", así que se marca por color. */
.campo--clave .ojo--activo { color: var(--color-primario-oscuro); background: var(--color-lila-suave); }

@media (max-width: 900px) {
  .login-wrap { grid-template-columns: 1fr; grid-template-rows: auto; background: var(--color-superficie); align-items: center; padding: var(--esp-lg); }
  .login-marca { display: none; }
  .login-lado { padding: 0; background: transparent; }
  .login-card { background: var(--color-fondo); border-radius: var(--radio-card); padding: var(--esp-xl) var(--esp-lg); box-shadow: var(--sombra-card); }
}

/* ============================================================
   SELECTOR DE PERFIL / ALUMNO
   ============================================================ */
.selector-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--color-superficie); padding: var(--esp-xl) var(--esp-lg); }
.selector { width: 100%; max-width: 900px; text-align: center; }
.selector__logo { width: 52px; height: auto; margin: 0 auto var(--esp-md); display: block; }
/* Título accesible: lo lee un lector de pantalla, pero no ocupa espacio
   visual — la maqueta no lleva encabezado, solo la identidad y las tarjetas. */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.selector__seccion { margin-bottom: var(--esp-xl); }
.selector__seccion-titulo { font-size: var(--texto-label); font-weight: var(--peso-medio); text-align: left; margin: 0 0 var(--esp-md); }
.selector__opcional { font-weight: var(--peso-regular); color: var(--color-texto-suave); }
.selector__vacio { text-align: left; color: var(--color-texto-suave); font-size: var(--texto-label); margin: 0; }

.tarjetas { display: flex; gap: var(--esp-md); justify-content: center; flex-wrap: wrap; margin-bottom: var(--esp-xl); }
.tarjeta-opcion {
  position: relative; width: 210px; padding: var(--esp-lg) var(--esp-md) var(--esp-md);
  display: flex; flex-direction: column; align-items: center; gap: 0.2rem;
  background: var(--color-fondo); border: 2px solid var(--color-borde); border-radius: var(--radio-card);
  cursor: pointer; font-family: inherit; text-align: center;
  transition: border-color var(--dur-rapida) var(--curva-estandar),
              box-shadow var(--dur-rapida) var(--curva-estandar),
              transform var(--dur-rapida) var(--curva-estandar);
}
/* :not(.elegida) — apuntar la tarjeta ya elegida le degradaba el borde de
   --color-primario a --color-lila. Y solo con puntero real: en táctil la
   elevación se quedaba pegada tras el toque. */
@media (hover: hover) {
  .tarjeta-opcion:hover:not(.elegida) { border-color: var(--color-lila); transform: translateY(-2px); }
}
.tarjeta-opcion.elegida { border-color: var(--color-primario); box-shadow: var(--sombra-card); }
.tarjeta-opcion__check {
  position: absolute; top: -10px; right: -10px;
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 999px;
  background: var(--color-primario); color: var(--color-sobre-marca);
  opacity: 0; transform: scale(0.6);
  /* Era el único «transition: all» del proyecto e interpolaba top, right y
     width, que son fijos. Con la curva firme el escalado pasa de «aparece» a
     «confirmado»: el segundo de los dos sitios donde se usa el rebote. */
  transition: opacity var(--dur-rapida) var(--curva-estandar),
              transform var(--dur-media) var(--curva-firme);
}
.tarjeta-opcion.elegida .tarjeta-opcion__check { opacity: 1; transform: scale(1); }
/* Espejo del check: mismo tamaño y offset, en la esquina opuesta. Nace con
   el gorro SVG (color: currentColor) y, si el colegio tiene logo,
   seleccion-perfil lo reemplaza por un <img> (Api.blob). El fondo neutro
   respalda los PNG transparentes; overflow recorta el logo al círculo. */
.tarjeta-opcion__logo {
  position: absolute; top: -14px; left: -14px;
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 999px;
  background: var(--color-fondo); border: 2px solid var(--color-borde); color: var(--color-primario-oscuro);
  overflow: hidden;
}
.tarjeta-opcion__logo svg { width: 20px; height: 17px; }
.tarjeta-opcion__logo img { width: 100%; height: 100%; object-fit: contain; }
.tarjeta-opcion__avatar {
  display: grid; place-items: center; width: 74px; height: 74px; border-radius: 999px;
  font-weight: var(--peso-semi); font-size: 1.25rem; color: var(--color-sobre-marca);
  margin-bottom: var(--esp-xs); flex: none;
}
.tarjeta-opcion__nombre { font-weight: var(--peso-medio); }
.tarjeta-opcion__meta {
  font-size: var(--texto-pequeno); color: var(--color-texto-suave); text-align: center;
}
.ico-meta { flex: none; width: 0.9rem; height: 0.9rem; margin-top: 0.15rem; }
.ico-meta--check { width: 0.8rem; height: 0.8rem; margin-top: 0; }
.tarjeta-opcion__etiqueta { font-size: var(--texto-pequeno); color: var(--color-texto-suave); }

/* Identidad de quien inició sesión, arriba de las tarjetas de selección.
   Horizontal (avatar + nombre/correo apilado a la derecha), como en NEWSC —
   no una columna centrada. */
.selector__identidad {
  display: inline-flex; align-items: center; gap: 0.625rem;
  margin: 0 auto var(--esp-lg);
}
.selector__identidad-avatar {
  display: grid; place-items: center; flex: none;
  width: 38px; height: 38px; border-radius: 999px;
  background: var(--color-primario); color: var(--color-sobre-marca);
  font-weight: var(--peso-semi); font-size: 0.95rem;
}
.selector__identidad-info { display: flex; flex-direction: column; align-items: flex-start; text-align: left; gap: 1px; }
.selector__identidad-nombre { font-weight: var(--peso-semi); font-size: var(--texto-label); line-height: 1.25; }
.selector__identidad-correo { font-size: var(--texto-pequeno); color: var(--color-texto-suave); }

@media (max-width: 720px) {
  .tarjetas { flex-direction: column; align-items: center; }
  .tarjeta-opcion { width: 100%; max-width: 280px; }
}

/* ============================================================
   AYUDA · botón flotante/inline + acordeón de preguntas frecuentes
   (help-widget.js). z-index por debajo del modal (1000).
   ============================================================ */
.ayuda-fab, .ayuda-inline, .ayuda-debajo {
  display: grid; place-items: center; border: none; border-radius: 999px;
  background: var(--color-primario); color: var(--color-sobre-marca);
  font-weight: var(--peso-semi); cursor: pointer; font-family: inherit;
  line-height: 1;
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  box-shadow: none; outline: none;
}
.ayuda-fab:hover, .ayuda-inline:hover, .ayuda-debajo:hover { background: var(--color-primario-oscuro); }
.ayuda-fab {
  position: fixed; right: var(--esp-lg); bottom: var(--esp-lg); z-index: 900;
  width: 46px; height: 46px; font-size: 1.15rem; box-shadow: var(--sombra-card);
}
.ayuda-inline {
  position: absolute; top: 0; right: 0; width: 22px; height: 22px; font-size: 0.75rem;
}
/* Centrado y en el flujo normal, debajo de otro elemento (ver opts.after en
   help-widget.js) — no flotante ni anclado a una esquina. */
.ayuda-debajo { width: 30px; height: 30px; font-size: 0.9rem; margin: var(--esp-lg) auto 0; }
.ayuda-acordeon { display: flex; flex-direction: column; gap: var(--esp-xs); }
.ayuda-item { border: 1px solid var(--color-borde); border-radius: var(--radio-input); overflow: hidden; }
.ayuda-pregunta {
  display: flex; align-items: center; justify-content: space-between; gap: var(--esp-sm);
  width: 100%; padding: 0.65rem 0.85rem; border: none; background: var(--color-fondo);
  color: var(--color-texto); font-family: inherit; font-size: var(--texto-label);
  font-weight: var(--peso-medio); text-align: left; cursor: pointer;
}
.ayuda-pregunta:hover { background: var(--color-superficie); }
.ayuda-pregunta .ico { transition: transform var(--dur-rapida) var(--curva-estandar); }
.ayuda-pregunta.abierta .ico--flecha { transform: rotate(180deg); }
.ayuda-respuesta {
  padding: 0 0.85rem 0.85rem; color: var(--color-texto-suave);
  font-size: var(--texto-label); line-height: 1.5;
}

/* ============================================================
   RESPONSIVE DEL SHELL
   ============================================================ */
@media (max-width: 860px) {
  /* visibility con retardo, no en la lista de duraciones: aparece al instante al
     abrir y solo se oculta cuando el deslizamiento ha terminado. Además saca del
     orden de tabulación los ~40 enlaces que seguían siendo alcanzables con Tab
     estando fuera de pantalla. */
  .sc-sidebar {
    position: fixed; z-index: 70; transform: translateX(-100%); visibility: hidden;
    transition: transform var(--dur-media) var(--curva-estandar),
                visibility 0s linear var(--dur-media);
  }
  .sc-sidebar.abierta {
    transform: none; visibility: visible;
    transition: transform var(--dur-media) var(--curva-estandar), visibility 0s;
  }
  /* Velo del cajón. Es un pseudo-elemento fixed, así que no participa del flex
     de .sc-shell; z-index 65 lo deja entre el contenido y el menú (70) y muy por
     debajo del modal (1000). */
  .sc-shell::after {
    content: ""; position: fixed; inset: 0; z-index: 65;
    background: rgba(36, 29, 51, 0.45); opacity: 0; pointer-events: none;
    transition: opacity var(--dur-media) var(--curva-estandar);
  }
  body.nav-abierta .sc-shell::after { opacity: 1; pointer-events: auto; }
  .ctx-chip { display: none; }
  .sc-contenido { padding: var(--esp-md); }
}

/* ============================================================
   LOGO DEL COLEGIO · topbar del panel
   La imagen llega de /accesos/centro-logo/{pii} (Api.blob); si el centro
   no tiene logo o la carga falla, se queda el isologo estático de School
   Community. object-fit: contain — nunca se recorta ni deforma.
   (En seleccion-perfil el logo vive en la insignia de cada tarjeta:
   .tarjeta-opcion__logo, más arriba.)
   ============================================================ */
.topbar-logo {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: none;
}
.topbar-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* Pantalla «sin colegio» del selector: mensaje + salidas. */
.selector__sin-colegio {
  max-width: 460px; margin: 0 auto var(--esp-xl);
  padding: var(--esp-xl) var(--esp-lg);
  background: var(--color-fondo); border: 2px solid var(--color-borde);
  border-radius: var(--radio-card); text-align: center;
}
.selector__sin-colegio-icono { font-size: 2rem; margin-bottom: var(--esp-sm); }
.selector__sin-colegio-titulo {
  font-weight: var(--peso-semi); font-size: var(--texto-grande);
  margin: 0 0 var(--esp-xs);
}
.selector__sin-colegio-desc {
  color: var(--color-texto-suave); font-size: var(--texto-label);
  line-height: 1.5; margin: 0 0 var(--esp-lg);
}
.selector__sin-colegio-acciones {
  display: flex; gap: var(--esp-sm); justify-content: center; flex-wrap: wrap;
}

/* ============================================================
   CONTRATO DINÁMICO · plantilla del contrato por cláusulas
   ------------------------------------------------------------
   Prefijo dc- a propósito: «.campo» ya es el wrapper de los
   formularios del kit, y aquí «campo» significa otra cosa — la
   PASTILLA que resalta un dato del contrato dentro del texto.
   ============================================================ */
.dc-paper { padding: var(--esp-xl) var(--esp-lg); }
.dc-paper h1 { margin: 0 0 var(--esp-xl); text-align: center; font-size: var(--texto-grande); font-weight: var(--peso-semi); }

.dc-campo {
  display: inline-block; background: var(--color-lila-suave); color: var(--color-primario-oscuro);
  border-radius: 5px; padding: 0 0.45rem; font-weight: var(--peso-medio); border-bottom: 2px solid var(--color-lila);
}
/* No corresponde a ningún dato real del sistema: nunca se completa solo. */
.dc-campo--falta { background: transparent; color: var(--color-error); border-color: var(--color-error); text-decoration: line-through; }

.dc-clausula {
  position: relative; margin-bottom: var(--esp-md); padding: 6px var(--esp-sm);
  margin-left: calc(var(--esp-sm) * -1); margin-right: calc(var(--esp-sm) * -1); border-radius: var(--radio-input);
}
.dc-clausula:hover, .dc-clausula--activa { background: var(--color-superficie); }
.dc-clausula h3 { margin: 0 0 4px; font-size: var(--texto-pequeno); font-weight: var(--peso-semi); }
.dc-clausula p { margin: 0; text-align: justify; white-space: pre-wrap; }
.dc-titulo-input { border: 0; background: transparent; font-weight: var(--peso-semi); width: 100%; padding: 0; font: inherit; color: inherit; }
.dc-tools { position: absolute; right: var(--esp-xs); top: 4px; display: none; gap: 6px; }
.dc-clausula:hover .dc-tools, .dc-clausula--activa .dc-tools { display: flex; }
.dc-editor { margin-top: 6px; }
.dc-editor textarea { min-height: 130px; }
.dc-barra { display: flex; gap: var(--esp-sm); align-items: center; margin-top: var(--esp-sm); flex-wrap: wrap; }
.dc-addcl {
  width: 100%; border: 1px dashed var(--color-borde); border-radius: var(--radio-input); background: transparent;
  padding: var(--esp-sm); color: var(--color-primario-oscuro); font-weight: var(--peso-medio); cursor: pointer;
  margin-top: 6px; font: inherit;
}
.dc-addcl:hover { background: var(--color-lila-suave); }
.dc-firmas {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--esp-xl); margin-top: var(--esp-xl);
  text-align: center; font-size: var(--texto-pequeno); color: var(--color-texto-suave);
}
.dc-firmas div { border-top: 1px solid var(--color-texto); padding-top: var(--esp-xs); }

.dc-lista { display: flex; flex-direction: column; gap: var(--esp-xs); }
.dc-item {
  background: var(--color-superficie); border: 1px solid var(--color-borde); border-radius: var(--radio-input);
  padding: var(--esp-xs) var(--esp-sm); display: grid; grid-template-columns: 1fr auto auto;
  gap: 2px var(--esp-xs); align-items: center;
}
.dc-item b { font-weight: var(--peso-medio); font-size: var(--texto-pequeno); }
.dc-item small { color: var(--color-texto-suave); font-size: 0.7rem; grid-column: 1; }
.dc-usos { font-size: 0.7rem; color: var(--color-texto-suave); grid-row: 1 / 3; text-align: right; }
.dc-usos--cero { color: var(--color-error); }
.dc-del { grid-row: 1 / 3; border: 0; background: transparent; color: var(--color-texto-suave); cursor: pointer; font-size: 1rem; }
.dc-del:hover { color: var(--color-error); }
.dc-nuevo { margin-top: var(--esp-md); background: var(--color-superficie); border: 1px solid var(--color-borde); border-radius: var(--radio-input); padding: var(--esp-sm); }

.dc-drop { border: 2px dashed var(--color-borde); border-radius: var(--radio-card); padding: var(--esp-xl) var(--esp-md); text-align: center; color: var(--color-texto-suave); cursor: pointer; }
.dc-drop:focus-visible, .dc-drop--hover { border-color: var(--color-lila); background: var(--color-lila-suave); outline: none; }
.dc-drop strong { display: block; color: var(--color-texto); font-size: var(--texto-label); margin-bottom: 4px; }
.dc-o { text-align: center; color: var(--color-texto-suave); font-size: var(--texto-pequeno); margin: var(--esp-md) 0 var(--esp-xs); }

.dc-rev { display: grid; grid-template-columns: 1fr 320px; gap: var(--esp-md); }
@media (max-width: 760px) { .dc-rev { grid-template-columns: 1fr; } }
.dc-doc { border: 1px solid var(--color-borde); border-radius: var(--radio-input); padding: var(--esp-md); max-height: 52vh; overflow: auto; background: var(--color-fondo); }
.dc-doc h4 { margin: 0 0 3px; font-size: var(--texto-pequeno); font-weight: var(--peso-semi); }
.dc-doc p { margin: 0 0 var(--esp-md); font-size: var(--texto-label); text-align: justify; white-space: pre-wrap; }

.dc-cand { max-height: 44vh; overflow: auto; display: flex; flex-direction: column; gap: var(--esp-xs); }
.dc-cd { border: 1px solid var(--color-borde); border-radius: var(--radio-input); padding: 9px 11px; background: var(--color-superficie); }
.dc-cd--off { opacity: 0.45; }
.dc-cd__fila { display: flex; gap: var(--esp-xs); align-items: center; }
.dc-cd__fila input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--color-primario-oscuro); }
.dc-cd__fila input[type="text"] { flex: 1; }
.dc-cd__fila2 { display: flex; gap: var(--esp-xs); align-items: center; margin-top: 6px; padding-left: 24px; }
.dc-muestra { font-size: 0.7rem; color: var(--color-texto-suave); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dc-tag { font-size: 0.65rem; border-radius: 999px; padding: 1px 8px; font-weight: var(--peso-medio); }
.dc-tag--reuso { background: var(--color-exito-bg); color: var(--color-exito); }
.dc-tag--nuevo { background: var(--color-lila-suave); color: var(--color-primario-oscuro); }

.dc-modo { display: flex; gap: var(--esp-md); font-size: var(--texto-pequeno); margin-top: var(--esp-sm); color: var(--color-texto-suave); }
.dc-modo label { display: flex; gap: 6px; align-items: center; cursor: pointer; }
.dc-modo input { accent-color: var(--color-primario-oscuro); }

/* ============================================================
   SISTEMA DE COMPONENTES DEL PANEL (revisión de UX, 21-10)
   ------------------------------------------------------------
   Cada pantalla resolvía lo mismo a su manera: acciones a la
   izquierda en una y a la derecha en otra, tres botones sólidos
   por fila, «Activo» y «ACTIVO» y «Vigente» con colores distintos,
   once variantes de aviso. Desde aquí hay cinco piezas y ninguna más:

     1. Encabezado de página  título + subtítulo; acciones SIEMPRE a la derecha
     2. Botones               un solo .boton--primario por vista; el resto con borde
     3. Estados               verde activo · amarillo pendiente · gris cerrado · rojo error
     4. Avisos                información · advertencia · error, cada uno con su ícono
     5. Tabla estándar        buscador + paginación + menú de acciones por fila

   Más los estados de respuesta: esqueleto de carga, «Reintentar» y
   el vacío que dice qué hacer. Los íconos nuevos van como data URI:
   el kit no trae ni los de aviso ni el de «más acciones».
   ============================================================ */

/* ---- 1. Encabezado de página -------------------------------- */
.pagina__cabecera { align-items: flex-start; }
.pagina__titulos { flex: 1 1 320px; min-width: 0; }
.pagina__sub {
  margin: 0.3rem 0 0; max-width: 72ch;
  color: var(--color-texto-suave); font-size: var(--texto-label); line-height: 1.5;
}
.pagina__acciones {
  display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap;
  gap: var(--esp-xs); margin-left: auto;
}
/* Mismo alto para todas las acciones del encabezado, sean o no «chico»: antes
   «Nuevo» medía 48px y «CSV» 32px, uno al lado del otro. */
.pagina__acciones .boton { width: auto; padding: 0.6rem 1.05rem; font-size: var(--texto-label); }

/* ---- 2. Botones ---------------------------------------------- */
/* El .boton del kit nace a ancho completo (es el del login). Dentro del panel
   ningún botón ocupa la fila salvo que se le pida. */
.sc-contenido .boton, .modal .boton { width: auto; }
.modal__pie .boton { min-width: 7.5rem; }
/* Acción destructiva que NO es la principal de la vista (p. ej. «Quitar» en
   cada fila): con borde, en rojo, nunca sólida. La sólida queda para la
   confirmación final. */
.boton--peligro-borde { background: var(--color-fondo); color: #b5333d; border: 1px solid rgba(214, 69, 80, 0.45); width: auto; }
.boton--peligro-borde:hover:not(:disabled) { background: var(--color-error-bg); }

/* ---- 3. Estados ---------------------------------------------- */
/* Una insignia INFORMA, no se pulsa: punto de color, sin borde, cursor normal
   y nunca en lila (el lila es del botón principal y de lo seleccionado). El
   texto va un tono más oscuro que el del kit para pasar AA a 13px. */
.estado {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.12rem 0.6rem 0.12rem 0.5rem; border-radius: 999px;
  font-size: var(--texto-pequeno); font-weight: var(--peso-medio); line-height: 1.5;
  white-space: nowrap; vertical-align: middle; cursor: default; user-select: none;
}
.estado::before {
  content: ""; flex: none; width: 0.45rem; height: 0.45rem;
  border-radius: 999px; background: currentColor;
}
.estado--activo { background: var(--color-exito-bg); color: #1d6b3e; }
.estado--pendiente { background: var(--color-aviso-bg); color: #8f5d07; }
.estado--cerrado { background: var(--color-superficie-2); color: var(--color-texto-suave); }
.estado--error { background: var(--color-error-bg); color: #b5333d; }
/* Las etiquetas que no son estado («Obligatoria», «Propio», nombres de
   columna) tampoco llevan borde: el borde es de los botones. */
.badge--gris { border: 0; background: var(--color-superficie-2); }

/* ---- 4. Avisos ----------------------------------------------- */
/* Tres tipos y un ícono por tipo. El texto va en el color de lectura; el tipo
   lo dicen el ícono, el filete izquierdo y el fondo. El ícono es un ::before,
   así que todos los avisos del panel lo tienen, también los que se escribieron
   sin él; el «!» de texto que traían algunos se oculta. */
.alerta {
  position: relative; display: block;
  padding: 0.75rem 1rem 0.75rem 2.75rem;
  border: 1px solid; border-left-width: 4px; border-radius: var(--radio-input);
  color: var(--color-texto); font-size: var(--texto-label); line-height: 1.5;
}
.alerta::before {
  content: ""; position: absolute; left: 0.9rem; top: 0.85rem;
  width: 1.15rem; height: 1.15rem;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.alerta .alerta__icono { display: none; }
.alerta--enfasis { display: block; }
.alerta strong { color: inherit; }
.alerta a { text-decoration: underline; font-weight: var(--peso-semi); }
.alerta .boton { vertical-align: middle; }

.alerta--info, .alerta--exito {
  background: #effafa; border-color: #c3ebeb; border-left-color: #2bb3b5; color: var(--color-texto);
}
.alerta--info::before, .alerta--exito::before {
  background: #1c7274;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z'/%3E%3C/svg%3E");
}
.alerta--info a, .alerta--exito a { color: #155a5c; }

.alerta--aviso {
  background: var(--color-aviso-bg); border-color: #f0dca6; border-left-color: #d99b1c; color: var(--color-texto);
}
.alerta--aviso::before {
  background: #8f5d07;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}

.alerta--error {
  background: var(--color-error-bg); border-color: #f3c3c8; border-left-color: var(--color-error); color: var(--color-texto);
}
.alerta--error::before {
  background: var(--color-error);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM13 17h-2v-2h2v2zm0-4h-2V7h2v6z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM13 17h-2v-2h2v2zm0-4h-2V7h2v6z'/%3E%3C/svg%3E");
}
.alerta--error a { color: #9e2a33; }

/* Avisos flotantes (toast): el mismo vocabulario de íconos. */
.aviso__ico {
  width: 1.15rem; height: 1.15rem; margin-top: 0.1rem; font-size: 0; background: currentColor;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.aviso--ok .aviso__ico {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.aviso--error .aviso__ico {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM13 17h-2v-2h2v2zm0-4h-2V7h2v6z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM13 17h-2v-2h2v2zm0-4h-2V7h2v6z'/%3E%3C/svg%3E");
}
.aviso--aviso { border-left-color: #d99b1c; }
.aviso--aviso .aviso__ico {
  color: #8f5d07;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.aviso--info { border-left-color: #2bb3b5; }
.aviso--info .aviso__ico {
  color: #1c7274;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z'/%3E%3C/svg%3E");
}
.aviso__txt { flex: 1; min-width: 0; }
.aviso__accion {
  flex: none; align-self: center; border: 0; background: none; cursor: pointer;
  font-family: inherit; font-size: var(--texto-pequeno); font-weight: var(--peso-semi);
  color: var(--color-primario-oscuro); padding: 0.2rem 0.3rem; border-radius: 6px;
}
.aviso__accion:hover { background: var(--color-superficie-2); }

/* ---- 5. Tabla estándar: menú de acciones por fila ------------- */
/* Un solo botón «más acciones» por fila. El menú se abre con position:fixed
   calculado desde el botón: así escapa al overflow de .tabla-wrap, que si no
   lo recortaría en las últimas filas. */
.ico--mas {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='5' cy='12' r='2.2'/%3E%3Ccircle cx='12' cy='12' r='2.2'/%3E%3Ccircle cx='19' cy='12' r='2.2'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='5' cy='12' r='2.2'/%3E%3Ccircle cx='12' cy='12' r='2.2'/%3E%3Ccircle cx='19' cy='12' r='2.2'/%3E%3C/svg%3E");
}
.acciones-fila__abrir[aria-expanded="true"] { background: var(--color-superficie-2); border-color: var(--color-primario); }
.acciones-fila__menu {
  position: fixed; z-index: 990; min-width: 210px; max-width: 300px;
  display: flex; flex-direction: column; gap: 1px; padding: 0.35rem;
  background: var(--color-fondo); border: 1px solid var(--color-borde);
  border-radius: var(--radio-card); box-shadow: var(--sombra-card);
  animation: aparece var(--dur-rapida) var(--curva-entra);
}
.acciones-fila__menu[hidden] { display: none; }
.acciones-fila__menu .boton-mini,
.acciones-fila__menu .boton {
  display: flex; align-items: center; justify-content: flex-start; gap: 0.6rem;
  width: 100%; height: auto; min-width: 0; padding: 0.5rem 0.6rem;
  border: 0; border-radius: 8px; background: none; box-shadow: none;
  color: var(--color-texto); font-family: inherit; font-size: var(--texto-label);
  font-weight: var(--peso-regular); text-align: left; white-space: nowrap; text-decoration: none;
}
.acciones-fila__menu .boton-mini:hover:not(:disabled),
.acciones-fila__menu .boton:hover:not(:disabled) { background: var(--color-superficie); filter: none; }
.acciones-fila__menu .boton-mini--peligro,
.acciones-fila__menu .boton--peligro { color: var(--color-error); }
.acciones-fila__menu .boton-mini--peligro:hover:not(:disabled) { background: var(--color-error-bg); }
.acciones-fila__menu .ico { width: 1rem; height: 1rem; }
.acciones-fila__sep { height: 1px; margin: 0.25rem 0.2rem; background: var(--color-borde); }
/* Rótulo de las acciones de ícono: solo se lee dentro del menú. */
.acc-txt { display: none; }
.acciones-fila__menu .acc-txt { display: inline; }

/* ---- Respuesta: esqueleto, carga lenta, error con reintento ---- */
.esqueleto { display: grid; gap: var(--esp-md); }
.esqueleto__titulo { height: 30px; width: min(320px, 70%); }
.esqueleto__sub { height: 14px; width: min(520px, 90%); margin-bottom: var(--esp-md); }
.esqueleto__bloque { height: 150px; border-radius: var(--radio-card); }
.esqueleto__bloque--bajo { height: 90px; }
.carga-lenta, .carga-error { margin-top: var(--esp-md); }
.carga-lenta .boton, .carga-error .boton { margin-left: var(--esp-xs); }

/* ---- Vacío que guía ------------------------------------------- */
.vacio__acciones {
  display: flex; gap: var(--esp-xs); flex-wrap: wrap; justify-content: center;
  margin-top: var(--esp-sm);
}
.vacio__acciones .boton { margin-top: 0; }

/* ---- Contexto de trabajo en la barra superior: colegio y año -- */
/* El año es el de TODO el panel: listados, tablero y formularios lo toman de
   aquí, así que tiene que verse siempre — también en el celular, donde el chip
   del colegio se oculta. */
.ctx-anio {
  display: inline-flex; align-items: center; gap: 0.15rem; flex: none;
  padding: 0.15rem 0.2rem 0.15rem 0.75rem; border-radius: 999px;
  background: var(--color-fondo); border: 1px solid var(--color-borde);
  font-size: var(--texto-pequeno); color: var(--color-texto-suave); font-weight: var(--peso-medio);
}
.ctx-anio:focus-within { border-color: var(--color-primario-oscuro); }
.ctx-anio select {
  border: 0; background: transparent; cursor: pointer;
  padding: 0.25rem 0.4rem; border-radius: 999px;
  font-family: inherit; font-size: var(--texto-label); font-weight: var(--peso-semi);
  color: var(--color-texto);
}
.ctx-anio select:focus { outline: none; }
/* Toda la barra deja de mostrar lo que pasa con el año: la vista se repinta. */
.ctx-anio--cambiando { opacity: 0.6; pointer-events: none; }

/* La campana solo marca cuando hay algo que leer. */
.boton-icono__punto { display: none; }
.boton-icono--con-avisos .boton-icono__punto { display: block; }

/* ---- Asistente: qué paso tiene errores ------------------------- */
.paso--error { border-color: var(--color-error); color: #b5333d; background: var(--color-error-bg); }
.paso--error .paso__n { background: var(--color-error); color: #fff; }
.paso__faltan {
  display: inline-grid; place-items: center; min-width: 1.15rem; height: 1.15rem; padding: 0 0.3rem;
  border-radius: 999px; background: var(--color-error); color: #fff;
  font-size: 0.68rem; font-weight: var(--peso-bold); line-height: 1;
}
.borrador { display: flex; align-items: center; gap: var(--esp-sm); flex-wrap: wrap; }
.borrador__txt { flex: 1; min-width: 220px; }

/* Fila del año con el que se trabaja (barra superior), en la tabla de períodos. */
.tabla tbody tr.fila--actual > td:first-child { box-shadow: inset 3px 0 0 var(--color-primario); }

/* ---- Tarjetas del inicio: cada una lleva a su listado ----------- */
.tarjeta-stat--enlace { color: inherit; text-decoration: none; }
.tarjeta-stat--enlace:hover { text-decoration: none; border-color: var(--color-lila); }
.tarjeta-stat__alcance { font-size: var(--texto-pequeno); color: var(--color-texto-suave); opacity: 0.85; }

/* ---- «Antes de crear aquí debe existir» ------------------------ */
/* Era una banda con borde lila en CADA listado, con claves internas
   («res:anios-academicos»). Ahora es una línea con enlaces legibles, y solo
   para quien puede crear. */
.requiere { margin: calc(var(--esp-xs) * -1) 0 var(--esp-md); font-size: var(--texto-pequeno); color: var(--color-texto-suave); }
.requiere__tabla { margin-left: var(--esp-xs); padding: 0.1rem 0.5rem; border-radius: 999px; background: var(--color-superficie-2); }

/* ---- Contexto en los formularios ------------------------------ */
/* Lo que antes eran dos campos bloqueados (Centro y Año académico) es ahora
   una línea: el dato se toma de la barra superior. */
/* Texto corrido, no flex: con flex cada <strong> era un ítem aparte y los
   espacios alrededor se perdían («en  Escuela … , año  2026 .»). */
.form-contexto {
  display: block; line-height: 1.5;
  margin: 0 0 var(--esp-md); color: var(--color-texto-suave); font-size: var(--texto-label);
}
.form-contexto label { margin-right: var(--esp-xs); }
.form-contexto strong { color: var(--color-texto); font-weight: var(--peso-semi); }
