@charset "utf-8";
/* =====================================================================
   STA XP — Hoja de estilos de la aplicación
   Liceo Bicentenario Santa Teresa de Los Andes

   Dirección visual "Cordillera": base clara, cabecera azul lapislázuli
   profunda, acentos dorados, tipografía Outfit. Los tokens, radios,
   sombras y tiempos vienen tal cual del mockup aprobado
   (mockups/tabla-curso.html); acá quedan sistematizados para toda la
   aplicación, no solo para la tabla del curso.

   Orden del archivo:
     1. Paleta y tokens
     2. Base y accesibilidad
     3. Estructura: cabecera, menú, envoltura
     4. Tarjetas y títulos
     5. Botones
     6. Formularios
     7. Tablas (se vuelven tarjetas apiladas en celular)
     8. Etiquetas, chips e insignias
     9. Estados: cargando, vacío, error
    10. Avisos flotantes
    11. Ventanas modales
    12. Pantalla de ingreso
    13. Tabla del curso (Fase 4)
    13b. Premios del curso (Fase 6)
    13c. Auditoría (Fase 8)
    14. Responsive
    15. Movimiento reducido
    16. Impresión de la aplicación (red de seguridad)
   ===================================================================== */

/* ---------- 1. Paleta y tokens ---------- */
:root{
  /* marca */
  --lapis:        #26619C;
  --lapis-osc:    #17416E;
  --lapis-noche:  #0E2740;
  --lapis-suave:  #E4EDF6;
  --dorado:       #F4C430;
  --dorado-osc:   #A87C05;

  /* tinta y superficies */
  --tinta:        #12202E;
  --tinta-2:      #4E6076;
  /* El gris más claro se usa en rótulos y encabezados de tabla, que son
     texto chico. En #6F8095 daba 4,04:1 sobre blanco: bonito en el
     monitor, bajo el 4,5:1 que pide AA y difícil de leer proyectado.
     Este tono llega a 5,4:1 sin cambiar el aire del diseño. */
  --tinta-3:      #5A6B80;
  --linea:        #DCE3EC;
  --linea-fuerte: #C3CEDB;
  --fondo:        #EFF3F8;
  --superficie:   #FFFFFF;

  /* semánticos */
  --crece:        #0C7A4D;
  --crece-suave:  #E1F4EA;
  --alerta:       #B4400C;
  --alerta-suave: #FCEDE6;
  --foco:         #0F5FA8;

  /* rangos (idénticos a la especificación; los usan las fases 4 a 7) */
  --r1:#F4C430; --r1-suave:#FDF3D4;
  --r2:#B87333; --r2-suave:#F6E8DB;
  --r3:#26619C; --r3-suave:#DFEAF5;
  --r4:#A8B2BD; --r4-suave:#ECEFF3;
  --r5:#D4AF37; --r5-suave:#F8EFD2;
  --r6:#4B3F35; --r6-suave:#E9E4DE;
  --r7:#7FB3D5; --r7-suave:#E6F1F9;
  --r8:#6C2BD9; --r8-suave:#EDE4FC;

  /* forma */
  --radio:14px;
  --radio-s:10px;
  --radio-xl:22px;
  --sombra:0 1px 2px rgba(18,32,46,.06), 0 6px 18px rgba(18,32,46,.07);
  --sombra-alta:0 12px 34px rgba(18,32,46,.20);
  --t:240ms cubic-bezier(.2,.7,.3,1);
  --toque:48px;                 /* alto mínimo de cualquier control táctil */
  --base:16px;

  /* Cabecera y menú del tema "Clásico": van en variables propias, NO en
     --lapis-noche/--lapis-osc/--lapis directamente. Esas tres las toca
     cada tema alternativo (ver 1b.) para aclarar los botones y la marca,
     pero --lapis-noche sigue existiendo tal cual la necesita el modo
     proyector (13.8, a través de --proyector-fondo) y los avisos
     flotantes (10), que son oscuros a propósito y no son parte de esta
     preferencia de color. Encadenar acá var(--lapis-noche) etc. hace que
     el tema "Clásico" no tenga que repetir ningún valor: es simplemente
     el que no sobreescribe nada.*/
  --cab-g1:              var(--lapis-noche);
  --cab-g2:              var(--lapis-osc);
  --cab-g3:               var(--lapis);
  --cab-texto:            #FFFFFF;
  --cab-sub:              #D3E4F5;
  --cab-chip-fondo:       rgba(255,255,255,.10);
  --cab-btn-fondo:        rgba(255,255,255,.12);
  --cab-btn-borde:        rgba(255,255,255,.28);
  --cab-btn-fondo-hover:  rgba(255,255,255,.22);
  --cab-enfoque:          #FFD450;
  --menu-fondo:           var(--lapis-noche);
  --menu-borde:           rgba(255,255,255,.10);
  --menu-texto:           #C7DBEE;
  --menu-texto-hover:     #FFFFFF;
  --menu-fondo-hover:     rgba(255,255,255,.07);
  --menu-texto-activo:    #FFFFFF;

  /* Fondo del modo proyector (13.8): antes tomaba --lapis-noche directo,
     así que se veía igual en los tres temas. Ahora es su propio token,
     con la versión "R,G,B" en paralelo para poder generar la franja
     semitransparente de .conceptos con el mismo color por tema. Clásico
     no cambia nada: sigue siendo el mismo lapis-noche de siempre. */
  --proyector-fondo:      var(--lapis-noche);
  --proyector-fondo-rgb:  14,39,64;
}

/* ---------- 1b. Temas alternativos (preferencia de color del navegador) ----------
   Elección personal de cada administrador (ver selector en la cabecera,
   pintado desde app.js). Se guarda en localStorage de SU navegador, no en
   la base de datos: no es una configuración del sistema ni afecta a los
   demás usuarios, así que no tiene sentido como columna de `usuarios`.

   Cada bloque solo sobreescribe los tokens que cambian; todo lo demás
   (radios, sombras, tiempos, --dorado, los colores de rango r1-r8,
   --crece/--alerta/--foco) se mantiene igual en los tres temas: son
   estados que la docente ya aprendió a reconocer por color y cambiarlos
   sería tocar contenido, no solo la piel visual. El dorado en particular
   se deja intacto a propósito: sigue siendo el color exclusivo de logro. */

/* "Cielo": el pedido de "muy oscuro" apunta sobre todo a la franja de
   cabecera + menú, que es lapis-noche sólido en TODA pantalla, todo el
   rato. Este tema la aclara a un degradado casi blanco con texto oscuro,
   y deja el azul como acento (botones, bordes, foco) en vez de fondo. */
[data-tema="cielo"]{
  --lapis:        #2E76B4;
  --lapis-osc:    #1F5A8F;
  --lapis-suave:  #EAF2FA;
  --fondo:        #F5F8FC;

  --cab-g1:       #EAF2FA;
  --cab-g2:       #DCEBF7;
  --cab-g3:       #CFE4F5;
  --cab-texto:    var(--tinta);
  --cab-sub:      var(--tinta-2);
  --cab-chip-fondo:      rgba(46,118,180,.08);
  --cab-btn-fondo:       rgba(46,118,180,.10);
  --cab-btn-borde:       var(--lapis-osc);
  --cab-btn-fondo-hover: rgba(46,118,180,.18);
  --cab-enfoque:  var(--foco);
  --menu-fondo:        #F3F8FC;
  --menu-borde:        var(--linea);
  --menu-texto:        var(--tinta-2);
  --menu-texto-hover:  var(--lapis-osc);
  --menu-fondo-hover:  var(--lapis-suave);
  --menu-texto-activo: var(--lapis-osc);

  /* Modo proyector (13.8): navy propio de esta paleta, un poco más
     saturado/celeste que el lapis-noche de Clásico para que el cambio
     de tema se note incluso con la sala oscurecida. 11,6:1 de contraste
     con texto blanco (AA pide 4,5:1). */
  --proyector-fondo:      #123B5C;
  --proyector-fondo-rgb:  18,59,92;
}

/* "Arena": la otra punta — no solo más clara, sino otra familia de color.
   Tinta cálida en vez de azulada, superficie color hueso en vez de gris
   frío, y el azul de marca corrido a un celeste apagado. El dorado y los
   semáforos (crece/alerta) quedan igual: siguen leyéndose como lo mismo
   que ya son en los otros dos temas. */
[data-tema="arena"]{
  --lapis:        #3B6E93;
  --lapis-osc:    #2C5470;
  --lapis-suave:  #E7EEF2;
  --tinta:        #2B2420;
  --tinta-2:      #6B5C4F;
  --tinta-3:      #7A6B5D;
  --linea:        #E6DFD4;
  --linea-fuerte: #D6CBBA;
  --fondo:        #F7F3EC;

  --cab-g1:       #F3E9DA;
  --cab-g2:       #EDDFC8;
  --cab-g3:       #E4CDA8;
  --cab-texto:    var(--tinta);
  /* Más oscuro que --tinta-2 (que ya es cálida) a propósito: contra el
     tono más claro del degradado de cabecera, --tinta-2 quedaba en
     4,16:1, bajo el 4,5:1 que pide AA para el subtítulo. */
  --cab-sub:      #5A4C40;
  --cab-chip-fondo:      rgba(59,110,147,.10);
  --cab-btn-fondo:       rgba(43,36,32,.06);
  --cab-btn-borde:       var(--lapis-osc);
  --cab-btn-fondo-hover: rgba(43,36,32,.10);
  --cab-enfoque:  var(--foco);
  --menu-fondo:        #F7F0E3;
  --menu-borde:        var(--linea);
  --menu-texto:        var(--tinta-2);
  --menu-texto-hover:  var(--lapis-osc);
  --menu-fondo-hover:  var(--lapis-suave);
  --menu-texto-activo: var(--lapis-osc);

  /* Modo proyector (13.8): acá sí se sale de la familia azul — marrón
     carbón cálido, coherente con el hueso y los acentos cálidos de esta
     paleta, en vez del navy de los otros dos temas. 13,8:1 de contraste
     con texto blanco (AA pide 4,5:1). */
  --proyector-fondo:      #3A2A1A;
  --proyector-fondo-rgb:  58,42,26;
}

/* ---------- 2. Base y accesibilidad ---------- */
*,*::before,*::after{box-sizing:border-box}
html{font-size:var(--base)}
body{
  margin:0;
  min-height:100vh;
  background:var(--fondo);
  color:var(--tinta);
  font-family:'Outfit','Segoe UI Variable Text','Segoe UI',system-ui,-apple-system,'Helvetica Neue',Arial,sans-serif;
  font-size:1rem;
  line-height:1.45;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{margin:0;font-weight:700;letter-spacing:-.01em}
p{margin:0}
button{font:inherit;color:inherit}
a{color:var(--lapis-osc)}

/* El foco por teclado tiene que verse siempre: la docente navega con Tab
   entre clases y no puede quedarse sin saber dónde está parada. */
/* Sin border-radius acá: fijarlo le cambiaba la forma al elemento
   enfocado y los botones redondos se cuadraban al llegarles el Tab. El
   contorno ya sigue solo el radio que tenga cada control. */
:focus-visible{outline:3px solid var(--foco);outline-offset:2px}
.cabecera :focus-visible,.menu :focus-visible{outline-color:var(--cab-enfoque)}

.oculto-visual{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
[hidden]{display:none !important}
svg.ic{width:1em;height:1em;display:block;flex:none;fill:none}

/* Salto al contenido: primer tabulable de la página */
.saltar{
  position:absolute;left:8px;top:-60px;z-index:300;
  background:var(--superficie);color:var(--lapis-osc);font-weight:700;
  border:1px solid var(--linea);cursor:pointer;
  padding:.7rem 1rem;border-radius:var(--radio-s);box-shadow:var(--sombra-alta);
  transition:top var(--t);
}
.saltar:focus{top:8px}

/* ---------- 3. Estructura ---------- */
.cabecera{
  background:linear-gradient(135deg,var(--cab-g1) 0%,var(--cab-g2) 55%,var(--cab-g3) 100%);
  color:var(--cab-texto);
  padding:.9rem clamp(.9rem,3vw,2rem);
  display:flex;align-items:center;gap:.85rem;flex-wrap:wrap;
}
.marca{display:flex;align-items:center;gap:.65rem;margin-right:auto;min-width:0}
.marca .cumbre{
  width:42px;height:42px;border-radius:12px;flex:none;
  background:linear-gradient(160deg,var(--dorado),#E39B12);
  display:grid;place-items:center;color:var(--lapis-noche);font-size:1.35rem;
  box-shadow:0 2px 0 rgba(0,0,0,.18) inset;
}
.marca .textos{min-width:0}
.marca b{display:block;font-size:1.18rem;line-height:1.05;letter-spacing:.02em}
/* Los dos colores claros de la cabecera están calculados contra el
   extremo MÁS claro del degradado (--lapis), que es el peor caso. Los
   tonos anteriores (#BFD6EC y #D7E6F4) quedaban en 4,3:1 y 4,0:1, bajo
   el mínimo AA, y el chip de la docente empeoraba por su fondo blanco
   al 10%. */
.marca span.sub{
  display:block;font-size:.76rem;color:var(--cab-sub);letter-spacing:.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.docente{
  display:flex;align-items:center;gap:.5rem;font-size:.86rem;color:var(--cab-texto);
  background:var(--cab-chip-fondo);padding:.35rem .7rem .35rem .35rem;border-radius:999px;
  max-width:100%;min-width:0;
}
.docente .av{
  width:28px;height:28px;border-radius:50%;background:var(--dorado);color:var(--lapis-noche);
  display:grid;place-items:center;font-weight:700;font-size:.8rem;flex:none;
}
.docente .quien{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.btn-cabecera{
  height:40px;min-height:40px;background:var(--cab-btn-fondo);border-color:var(--cab-btn-borde);
  color:var(--cab-texto);
}
.btn-cabecera:hover{background:var(--cab-btn-fondo-hover)}

/* Menú principal. Se arma según el rol, pero eso es solo cosmético:
   el permiso de verdad lo aplica el backend en cada acción. */
.menu{
  background:var(--menu-fondo);
  border-bottom:1px solid var(--menu-borde);
  padding:0 clamp(.5rem,3vw,2rem);
}
.menu ul{
  list-style:none;margin:0 auto;padding:0;max-width:1360px;
  display:flex;gap:.25rem;overflow-x:auto;scrollbar-width:thin;
}
.menu a{
  display:inline-flex;align-items:center;gap:.5rem;white-space:nowrap;
  height:var(--toque);padding:0 .95rem;color:var(--menu-texto);text-decoration:none;
  font-weight:600;font-size:.95rem;border-bottom:3px solid transparent;
  transition:color var(--t),border-color var(--t),background var(--t);
}
.menu a:hover{color:var(--menu-texto-hover);background:var(--menu-fondo-hover)}
.menu a[aria-current=page]{color:var(--menu-texto-activo);border-bottom-color:var(--dorado)}

/* Selector de color de interfaz (1b.): lo pinta app.js para cualquier
   sesión iniciada (admin o docente), dentro de la modal que abre el botón
   de paleta de la cabecera. Las tres muestras van con degradado fijo
   (no con los tokens del tema
   activo): son la vitrina de cómo se ve CADA opción, así que tienen que
   mostrar sus propios colores pase lo que pase con el tema puesto ahora. */
.selector-tema-lista{list-style:none;margin:0;padding:0;display:grid;gap:.5rem}
.selector-tema-op{
  width:100%;display:flex;align-items:center;gap:.7rem;text-align:left;
  padding:.6rem .7rem;border:1px solid var(--linea-fuerte);border-radius:var(--radio-s);
  background:var(--superficie);cursor:pointer;font:inherit;color:inherit;
}
.selector-tema-op:hover{background:#F4F8FC}
.selector-tema-op[aria-pressed=true]{border-color:var(--lapis);box-shadow:0 0 0 2px var(--lapis-suave)}
.selector-tema-muestra{width:38px;height:38px;border-radius:10px;flex:none;border:1px solid rgba(0,0,0,.08)}
.selector-tema-muestra--clasico{background:linear-gradient(135deg,#0E2740 0%,#17416E 55%,#26619C 100%)}
.selector-tema-muestra--cielo{background:linear-gradient(135deg,#EAF2FA 0%,#DCEBF7 55%,#CFE4F5 100%)}
.selector-tema-muestra--arena{background:linear-gradient(135deg,#F3E9DA 0%,#EDDFC8 55%,#E4CDA8 100%)}
.selector-tema-info{flex:1;min-width:0}
.selector-tema-info b{display:block;font-size:.95rem}
.selector-tema-info .secundario{font-size:.8rem;color:var(--tinta-2)}
.selector-tema-marca{flex:none;color:var(--crece);font-weight:800;visibility:hidden}
.selector-tema-op[aria-pressed=true] .selector-tema-marca{visibility:visible}

.envoltura{max-width:1360px;margin:0 auto;padding:clamp(.9rem,2.4vw,1.6rem)}

/* Encabezado de cada pantalla: título a la izquierda, acciones a la derecha */
.encabezado-pantalla{
  display:flex;align-items:flex-end;gap:.8rem;flex-wrap:wrap;margin-bottom:1rem;
}
.encabezado-pantalla .titulos{margin-right:auto;min-width:0}
.encabezado-pantalla h1{font-size:clamp(1.25rem,3.6vw,1.6rem)}
.encabezado-pantalla .bajada{font-size:.9rem;color:var(--tinta-2);margin-top:.2rem}

/* ---------- 4. Tarjetas y títulos ---------- */
.tarjeta{
  background:var(--superficie);border:1px solid var(--linea);
  border-radius:var(--radio);box-shadow:var(--sombra);
}
.tarjeta-cuerpo{padding:clamp(.9rem,2.2vw,1.25rem)}
.tarjeta + .tarjeta{margin-top:1rem}
.tarjeta h2{font-size:1.05rem;display:flex;align-items:center;gap:.5rem}
.tarjeta .nota{font-size:.85rem;color:var(--tinta-2);margin-top:.3rem}
.rotulo{
  font-size:.82rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--tinta-3);
}
.separador{height:1px;background:var(--linea);border:0;margin:1rem 0}
/* Selector de hoja del libro: la hoja correcta ya viene elegida, así que
   cambiarla es la excepción y va plegada para no competir con las cifras. */
.hojas{margin-top:.6rem}
.hojas > summary{
  cursor:pointer;font-weight:600;font-size:.92rem;color:var(--lapis-osc);
  padding:.35rem 0;width:fit-content;
}
.hojas[open] > summary{margin-bottom:.5rem}
.hojas .campo{margin-bottom:0}
.hojas select{max-width:min(420px,100%)}
/* Cada aparición de un alumno repetido en su propia línea: en una sola
   fila corrida no se distinguía cuál curso era cuál. */
.aparicion{display:flex;gap:.4rem;align-items:center;flex-wrap:wrap;padding:.15rem 0}

/* Barra de herramientas de una pantalla (búsqueda, filtros, contador) */
.herramientas{display:flex;gap:.6rem;align-items:center;flex-wrap:wrap;margin-bottom:.9rem}
.herramientas .cuenta{font-size:.85rem;color:var(--tinta-2);margin-left:auto}
.campo-busqueda{position:relative;display:flex;align-items:center}
.campo-busqueda > svg{position:absolute;left:.75rem;color:var(--tinta-3);font-size:1.05rem;pointer-events:none}
/* [type=search] repetido a propósito: sin él, esta regla y la de
   `input[type=search]{padding:0 .9rem}` de más abajo quedan con la
   MISMA especificidad (una clase + un elemento, contra un elemento +
   un atributo), y gana la que aparece después en el archivo — que
   vuelve a poner el padding-left en .9rem y esconde el texto del campo
   debajo de la lupa. Pasa en las cuatro pantallas que usan
   .campo-busqueda (Cursos, Alumnos, la tabla del curso y Usuarios),
   no solo en la que lo hizo notorio. */
.campo-busqueda input[type=search]{padding-left:2.5rem;width:min(320px,60vw)}

/* ---------- 5. Botones ---------- */
.btn{
  height:var(--toque);min-height:var(--toque);display:inline-flex;align-items:center;gap:.5rem;
  padding:0 1rem;border-radius:var(--radio-s);border:1px solid var(--linea-fuerte);
  background:var(--superficie);font-weight:600;cursor:pointer;text-decoration:none;color:var(--tinta);
  transition:background var(--t),transform var(--t),border-color var(--t),color var(--t);
}
.btn:hover{background:#F4F8FC}
.btn:active{transform:translateY(1px)}
.btn[disabled],.btn[aria-disabled=true]{opacity:.55;cursor:not-allowed;transform:none}
.btn-primario{background:var(--lapis);border-color:var(--lapis);color:#fff}
.btn-primario:hover{background:var(--lapis-osc)}
.btn-peligro{color:var(--alerta);border-color:#E4B7A4}
.btn-peligro:hover{background:var(--alerta-suave)}
.btn-fantasma{background:transparent;border-color:transparent}
.btn-fantasma:hover{background:#EAF0F7}
.btn-bloque{width:100%;justify-content:center}
/* Botón de solo ícono: siempre lleva aria-label */
.btn-icono{width:var(--toque);padding:0;justify-content:center;font-size:1.1rem}
.btn-chico{height:40px;min-height:40px;padding:0 .75rem;font-size:.9rem}
.btn-chico.btn-icono{width:40px;padding:0}

/* ---------- 6. Formularios ---------- */
.campo{display:flex;flex-direction:column;gap:.3rem;margin-bottom:.9rem}
.campo > label{font-weight:600;font-size:.92rem}
.campo .ayuda{font-size:.8rem;color:var(--tinta-2)}
.campo .error-campo{font-size:.82rem;color:var(--alerta);font-weight:600}
input[type=text],input[type=email],input[type=password],input[type=search],
input[type=number],select,textarea{
  height:var(--toque);border:1px solid var(--linea-fuerte);border-radius:var(--radio-s);
  background:var(--superficie);color:var(--tinta);padding:0 .9rem;font-size:1rem;
  font-family:inherit;font-weight:500;min-width:0;width:100%;
  transition:border-color var(--t),box-shadow var(--t);
}
textarea{height:auto;padding:.6rem .9rem;line-height:1.4}
select{padding-right:2rem;cursor:pointer}
input:hover,select:hover{border-color:var(--lapis)}
input[aria-invalid=true],select[aria-invalid=true]{border-color:var(--alerta);background:#FFFBFA}
input::placeholder{color:var(--tinta-3)}
.campo-casilla{flex-direction:row;align-items:center;gap:.6rem}
.campo-casilla input[type=checkbox]{width:22px;height:22px;accent-color:var(--lapis);flex:none}
.campo-casilla label{font-weight:600}
.rejilla-campos{display:grid;gap:0 1rem;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
/* Un campo que decide más que los otros de su pantalla. Lo usa el año
   escolar del libro de matrícula: de ese <select> dependen los cursos
   que se crean y el año de las mil doscientas matrículas, y suelto
   entre las demás tarjetas se veía igual que un filtro cualquiera. */
.campo-destacado{
  background:var(--r1-suave);border:1px solid #E8C765;
  border-radius:var(--radio-s);padding:.75rem .85rem;
}
.campo-destacado > select{max-width:220px}
fieldset{border:0;margin:0;padding:0}
.acciones-form{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:.4rem}
.acciones-form .btn{flex:1 1 auto;justify-content:center}

/* El selector de archivo: el botón nativo cambia en cada navegador, así
   que se le da altura de toque y se deja que el nombre del archivo se
   lea completo. */
input[type=file]{
  border:1px dashed var(--linea-fuerte);border-radius:var(--radio-s);
  background:var(--superficie);padding:.7rem .9rem;width:100%;font-family:inherit;
  font-size:.95rem;cursor:pointer;
}
input[type=file]:hover{border-color:var(--lapis);background:#F4F8FC}
input[type=file]::file-selector-button{
  height:38px;margin-right:.8rem;padding:0 .9rem;border-radius:var(--radio-s);
  border:1px solid var(--linea-fuerte);background:#F4F8FC;color:var(--tinta);
  font-family:inherit;font-weight:600;cursor:pointer;
}

/* Cifras de un resumen (importación). No usan .cuenta porque esa lleva
   margin-left:auto y varias seguidas quedaban desparramadas. */
.cifras{display:flex;flex-wrap:wrap;gap:.5rem;margin:.2rem 0 .2rem}
.cifra{
  display:inline-flex;align-items:baseline;gap:.35rem;padding:.35rem .7rem;
  border:1px solid var(--linea);border-radius:999px;background:var(--superficie);
  font-size:.85rem;color:var(--tinta-2);
}
.cifra b{font-size:1.05rem;color:var(--tinta);font-weight:800}

/* ---------- 7. Tablas ---------- */
.envase-tabla{overflow:visible}
.tabla{width:100%;border-collapse:separate;border-spacing:0 .5rem}
.tabla thead th{
  text-align:left;padding:.35rem .9rem;font-size:.82rem;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--tinta-3);
}
.tabla tbody tr{
  background:var(--superficie);
  box-shadow:0 1px 1px rgba(18,32,46,.04);
  transition:box-shadow var(--t),border-color var(--t);
}
.tabla tbody tr:hover{box-shadow:var(--sombra)}
.tabla tbody td{
  padding:.7rem .9rem;border-top:1px solid var(--linea);border-bottom:1px solid var(--linea);
  vertical-align:middle;
}
.tabla tbody td:first-child{border-left:1px solid var(--linea);border-radius:var(--radio) 0 0 var(--radio)}
.tabla tbody td:last-child{border-right:1px solid var(--linea);border-radius:0 var(--radio) var(--radio) 0}
.tabla tbody tr:hover td{border-color:var(--linea-fuerte)}
.tabla .principal{font-weight:600;font-size:1.02rem}
.tabla .secundario{font-size:.84rem;color:var(--tinta-2)}
.tabla .numero{font-variant-numeric:tabular-nums;text-align:right}
.celda-acciones{white-space:nowrap}
.celda-acciones .grupo{display:flex;gap:.4rem;justify-content:flex-end;flex-wrap:wrap}
.fila-inactiva td{background:#FAFBFD;color:var(--tinta-2)}

/* ---------- 8. Etiquetas, chips e insignias ---------- */
.etiqueta{
  display:inline-flex;align-items:center;gap:.35rem;
  font-size:.8rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  padding:.22rem .55rem;border-radius:999px;border:1px solid transparent;white-space:nowrap;
}
.etiqueta-lapis{background:var(--lapis-suave);color:var(--lapis-osc);border-color:#C3D9EE}
.etiqueta-dorado{background:var(--r1-suave);color:#7A5B00;border-color:#E8C765}
.etiqueta-crece{background:var(--crece-suave);color:#075A39;border-color:#BEE3D0}
.etiqueta-apagada{background:#ECEFF3;color:var(--tinta-2);border-color:var(--linea-fuerte)}
.etiqueta-alerta{background:var(--alerta-suave);color:var(--alerta);border-color:#E4B7A4}
.chip{
  display:inline-flex;align-items:center;gap:.45rem;
  background:var(--superficie);border:1px solid var(--linea-fuerte);border-radius:999px;
  padding:.3rem .35rem .3rem .75rem;font-weight:600;font-size:.92rem;
}
.lista-chips{display:flex;flex-wrap:wrap;gap:.5rem}

/* ---------- 9. Estados ---------- */
.cargando{display:flex;align-items:center;gap:.7rem;color:var(--tinta-2);padding:2rem 1rem;justify-content:center}
.girador{
  width:26px;height:26px;border-radius:50%;flex:none;
  border:3px solid var(--linea-fuerte);border-top-color:var(--lapis);
  animation:girar 800ms linear infinite;
}
@keyframes girar{to{transform:rotate(360deg)}}

.vacio{
  padding:2.4rem 1.2rem;text-align:center;color:var(--tinta-2);
  background:var(--superficie);border:1px dashed var(--linea-fuerte);border-radius:var(--radio);
}
.vacio .icono-grande{font-size:2.2rem;display:block;margin-bottom:.5rem}
.vacio h2{font-size:1.05rem;color:var(--tinta);margin-bottom:.3rem}

.panel-error{
  background:var(--superficie);border:1px solid #E4B7A4;border-left:6px solid var(--alerta);
  border-radius:var(--radio);box-shadow:var(--sombra);padding:1.1rem 1.2rem;
}
.panel-error h2{color:var(--alerta);font-size:1.05rem;margin-bottom:.35rem}
.panel-error p{color:var(--tinta-2);margin-bottom:.8rem}

/* Aviso en línea dentro de un formulario (rol alert) */
.aviso-linea{
  border-radius:var(--radio-s);padding:.65rem .8rem;font-size:.92rem;font-weight:600;
  display:flex;gap:.5rem;align-items:flex-start;margin-bottom:.9rem;
}
.aviso-linea svg{margin-top:.2rem}
.aviso-error{background:var(--alerta-suave);color:#7E2C08;border:1px solid #E4B7A4}
.aviso-ok{background:var(--crece-suave);color:#075A39;border:1px solid #BEE3D0}
.aviso-info{background:var(--lapis-suave);color:var(--lapis-osc);border:1px solid #C3D9EE}
/* El escalón que faltaba entre "esto está mal" y "esto es un dato".
   Crear doce cursos no es un error, pero tampoco es un comentario al
   pasar: en rojo se confunde con las filas que se caen, y en azul se lee
   como información y nadie lo mira. */
.aviso-atencion{background:var(--r1-suave);color:#7A5B00;border:1px solid #E8C765}
.aviso-linea .btn{margin-left:auto;flex:none}

/* ---------- 10. Avisos flotantes ---------- */
.avisos{
  position:fixed;left:50%;bottom:16px;transform:translateX(-50%);
  z-index:150;width:min(560px,calc(100vw - 24px));
  display:flex;flex-direction:column;gap:.5rem;pointer-events:none;
}
.aviso{
  background:var(--lapis-noche);color:#fff;border-radius:var(--radio);box-shadow:var(--sombra-alta);
  padding:.75rem .9rem;display:flex;align-items:center;gap:.6rem;font-size:.94rem;
  pointer-events:auto;animation:entra-aviso 300ms cubic-bezier(.2,.7,.3,1);
}
.aviso.saliendo{animation:sale-aviso 240ms ease-in forwards}
.aviso .cerrar{
  margin-left:auto;background:transparent;border:0;color:#BFD6EC;cursor:pointer;
  width:32px;height:32px;border-radius:8px;display:grid;place-items:center;flex:none;
}
.aviso .cerrar:hover{background:rgba(255,255,255,.14);color:#fff}
.aviso-exito{background:#0B5B3B}
.aviso-fallo{background:#7E2C08}
@keyframes entra-aviso{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes sale-aviso{to{opacity:0;transform:translateY(10px)}}

/* ---------- 11. Ventanas modales ---------- */
.velo{
  position:fixed;inset:0;z-index:200;background:rgba(14,39,64,.62);
  display:grid;place-items:center;padding:1rem;overflow-y:auto;
}
.modal{
  background:var(--superficie);border-radius:var(--radio-xl);width:min(560px,100%);
  box-shadow:var(--sombra-alta);animation:aparece 320ms cubic-bezier(.2,.7,.3,1);
  max-height:calc(100vh - 2rem);display:flex;flex-direction:column;
}
@keyframes aparece{from{opacity:0;transform:scale(.94) translateY(12px)}to{opacity:1;transform:none}}
.modal-cabeza{
  display:flex;align-items:center;gap:.6rem;padding:1.1rem 1.2rem .6rem;
}
.modal-cabeza h2{font-size:1.15rem;margin-right:auto}
.modal-cuerpo{padding:.4rem 1.2rem 1rem;overflow-y:auto}
.modal-pie{
  display:flex;gap:.6rem;padding:.8rem 1.2rem 1.2rem;flex-wrap:wrap;
  border-top:1px solid var(--linea);margin-top:auto;
}
.modal-pie .btn{flex:1 1 auto;justify-content:center}
body.sin-scroll{overflow:hidden}

/* ---------- 12. Pantalla de ingreso ---------- */
body.pantalla-ingreso{
  background:
    radial-gradient(1100px 620px at 15% -10%,rgba(38,97,156,.20),transparent 60%),
    radial-gradient(900px 520px at 105% 110%,rgba(244,196,48,.20),transparent 62%),
    var(--fondo);
}
.ingreso{
  min-height:100vh;display:grid;place-items:center;padding:1.1rem;
}
.ingreso-caja{width:min(430px,100%)}
.ingreso-marca{text-align:center;margin-bottom:1.1rem}
.ingreso-marca .cumbre{
  width:64px;height:64px;border-radius:20px;margin:0 auto .7rem;
  background:linear-gradient(160deg,var(--dorado),#E39B12);
  display:grid;place-items:center;color:var(--lapis-noche);font-size:2rem;
  box-shadow:0 2px 0 rgba(0,0,0,.18) inset,var(--sombra);
}
.ingreso-marca h1{font-size:1.75rem;letter-spacing:.02em}
.ingreso-marca p{font-size:.9rem;color:var(--tinta-2);margin-top:.15rem}
.ingreso-tarjeta{
  background:var(--superficie);border:1px solid var(--linea);border-left:6px solid var(--lapis);
  border-radius:var(--radio-xl);box-shadow:var(--sombra);padding:clamp(1.1rem,3.5vw,1.5rem);
}
.ingreso-tarjeta h2{font-size:1.08rem;margin-bottom:.15rem}
.ingreso-tarjeta .nota{font-size:.86rem;color:var(--tinta-2);margin-bottom:1rem}
.ingreso-pie{
  text-align:center;font-size:.8rem;color:var(--tinta-3);margin-top:1rem;line-height:1.5;
}

/* ---------- 13. Tabla del curso (Fase 4) ----------

   Todo lo de esta sección va colgado de .tabla-curso a propósito. Los
   nombres del mockup (.fila, .acciones, .campo, .vacio, .lista, .panel)
   son palabras cortas que ya significan otra cosa en las pantallas de
   arriba; sin el prefijo, la primera .fila de esta sección le habría
   cambiado la caja a las tablas de cursos y alumnos.

   Lo que sí vive suelto en el <body> es lo que no puede vivir dentro de
   la pantalla: la barra de deshacer, el +XP que flota, el confeti y el
   botón de salida del proyector, todos position:fixed.
   ------------------------------------------------------------------- */

/* --- 13.1 Meta colectiva: lo primero, antes que cualquier dato individual --- */
.tabla-curso .meta{
  background:linear-gradient(140deg,#FFFFFF 0%,#FFFFFF 55%,#F6FAFE 100%);
  border:1px solid var(--linea);border-left:6px solid var(--lapis);
  border-radius:var(--radio-xl);box-shadow:var(--sombra);
  padding:clamp(1rem,2.2vw,1.4rem);
  display:grid;gap:1.2rem;grid-template-columns:1.6fr 1fr;align-items:center;
}
.tabla-curso .meta h2{font-size:1.02rem;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.tabla-curso .chip-mes{
  font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  background:var(--lapis-suave);color:var(--lapis-osc);padding:.2rem .5rem;border-radius:999px;
}
.tabla-curso .meta-cifra{font-size:clamp(1.6rem,4.6vw,2.35rem);font-weight:800;letter-spacing:-.02em;line-height:1.05}
.tabla-curso .meta-cifra small{font-size:.9rem;font-weight:600;color:var(--tinta-2)}
.tabla-curso .barra-meta{
  position:relative;height:20px;border-radius:999px;background:#E6ECF4;overflow:hidden;
  margin:.55rem 0 .4rem;border:1px solid var(--linea);
}
.tabla-curso .barra-meta i{
  display:block;height:100%;border-radius:999px;
  background:linear-gradient(90deg,var(--lapis) 0%,#3E8FD1 60%,var(--dorado) 100%);
  transition:width 500ms cubic-bezier(.2,.7,.3,1);
}
.tabla-curso .meta-pie{font-size:.85rem;color:var(--tinta-2)}
.tabla-curso .meta-pie b{color:var(--tinta)}
.tabla-curso .semana{border-left:1px solid var(--linea);padding-left:1.2rem}
.tabla-curso .semana .grande{font-size:clamp(1.5rem,4vw,2.1rem);font-weight:800;color:var(--crece);line-height:1}
/* Un cuadradito por alumno. Es la única vista del curso completo que no
   ordena a nadie: dice cuántos sumaron, no quién va adelante. */
.tabla-curso .puntitos{display:flex;flex-wrap:wrap;gap:5px;margin-top:.6rem;max-width:260px}
.tabla-curso .puntitos i{width:13px;height:13px;border-radius:4px;background:#DCE3EC;display:block}
.tabla-curso .puntitos i.on{background:var(--crece)}

/* --- 13.2 Conceptos: se elige uno y después cada alumno es UN toque --- */
.tabla-curso .conceptos{
  position:sticky;top:0;z-index:30;
  background:rgba(239,243,248,.92);backdrop-filter:blur(8px);
  border-bottom:1px solid var(--linea);
  margin:0 0 .9rem;padding:.6rem 0 .7rem;
}
.tabla-curso .titulillo{display:flex;align-items:baseline;gap:.5rem;margin-bottom:.45rem;flex-wrap:wrap}
.tabla-curso .titulillo em{font-style:normal;font-size:.82rem;color:var(--tinta-2)}
.tabla-curso .pistas{display:flex;gap:.45rem;overflow-x:auto;padding-bottom:.35rem;scrollbar-width:thin}
.tabla-curso .pista{
  flex:none;display:inline-flex;align-items:center;gap:.45rem;height:44px;padding:0 .85rem;
  border-radius:999px;border:1.5px solid var(--linea-fuerte);background:var(--superficie);
  cursor:pointer;white-space:nowrap;font-weight:600;font-size:.92rem;color:var(--tinta);
  transition:background var(--t),border-color var(--t),color var(--t),box-shadow var(--t);
}
.tabla-curso .pista .xp{
  font-weight:800;font-size:.82rem;background:var(--lapis-suave);color:var(--lapis-osc);
  padding:.1rem .4rem;border-radius:6px;
}
.tabla-curso .pista[aria-pressed=true]{
  background:var(--lapis);border-color:var(--lapis-osc);color:#fff;box-shadow:0 4px 14px rgba(38,97,156,.35);
}
.tabla-curso .pista[aria-pressed=true] .xp{background:rgba(255,255,255,.22);color:#fff}
/* Borde punteado = la segunda categoría (Misiones). Es la distinción que
   hace el mockup y la única que cabe en una píldora sin texto extra. */
.tabla-curso .pista.mision{border-style:dashed}

/* --- 13.3 Disposición: lista + panel lateral --- */
.tabla-curso .columnas{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:1.1rem;align-items:start}

/* --- 13.4 La lista de alumnos --- */
.tabla-curso .lista{list-style:none;margin:0;padding:0}
/* La columna del rango va en `rem` y no en los 132px del mockup: ese
   ancho se dibujó con "Lapislázuli" de nombre más largo, y el catálogo
   real llega hasta "Leyenda del Liceo", que ahí se cortaba en "Leyenda
   d…". Es la copa que el curso persigue todo el año y se lee proyectada
   en la pared; en rem, además, crece con la letra del modo proyector. */
.tabla-curso .encabezado-lista{
  display:grid;grid-template-columns:2.75rem minmax(0,1fr) 11.5rem 6rem auto;gap:.8rem;align-items:center;
  padding:.5rem .9rem;font-size:.78rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--tinta-3);
}
.tabla-curso .fila{
  display:grid;grid-template-columns:2.75rem minmax(0,1fr) 11.5rem 6rem auto;gap:.8rem;align-items:center;
  background:var(--superficie);border:1px solid var(--linea);border-radius:var(--radio);
  padding:.6rem .9rem;margin-bottom:.5rem;box-shadow:0 1px 1px rgba(18,32,46,.04);
  transition:box-shadow var(--t),border-color var(--t);
}
.tabla-curso .fila:hover{border-color:var(--linea-fuerte);box-shadow:var(--sombra)}
.tabla-curso .fila.destello{animation:destello 700ms ease-out}
@keyframes destello{
  0%{box-shadow:0 0 0 0 rgba(12,122,77,.55);background:#F2FBF6}
  100%{box-shadow:0 0 0 14px rgba(12,122,77,0);background:#fff}
}
/* El punto que el servidor no aceptó vuelve atrás y se dice. El rojo dura
   lo mismo que el verde del acierto: si el fallo fuera más discreto que el
   éxito, la docente seguiría la clase creyendo que sumó. */
.tabla-curso .fila.revertida{animation:revertida 900ms ease-out}
@keyframes revertida{
  0%{box-shadow:0 0 0 0 rgba(180,64,12,.55);background:var(--alerta-suave)}
  100%{box-shadow:0 0 0 14px rgba(180,64,12,0);background:#fff}
}
.tabla-curso .num{font-variant-numeric:tabular-nums;font-weight:700;color:var(--tinta-3);text-align:center;font-size:.95rem}
.tabla-curso .ident{min-width:0}
.tabla-curso .nombre{font-weight:600;font-size:1.02rem;display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}
.tabla-curso .cerca{
  font-size:.7rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  background:var(--r1-suave);color:#7A5B00;border:1px solid #E8C765;padding:.1rem .4rem;border-radius:999px;
}
.tabla-curso .progreso{margin-top:.32rem;display:flex;align-items:center;gap:.55rem}
.tabla-curso .barra{height:9px;border-radius:999px;background:#E9EEF4;flex:1;overflow:hidden;min-width:60px}
.tabla-curso .barra i{
  display:block;height:100%;border-radius:999px;background:var(--c-rango,var(--lapis));
  transition:width 420ms cubic-bezier(.2,.7,.3,1);
}
.tabla-curso .faltan{font-size:.78rem;color:var(--tinta-2);white-space:nowrap}
.tabla-curso .insignia{
  display:inline-flex;align-items:center;gap:.4rem;padding:.32rem .6rem;border-radius:999px;
  background:var(--c-suave,#ECEFF3);border:1px solid rgba(0,0,0,.08);font-weight:700;font-size:.85rem;
  max-width:100%;
}
.tabla-curso .insignia .emoji{font-size:1.05rem;line-height:1}
.tabla-curso .insignia span.txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tabla-curso .xp-total{font-variant-numeric:tabular-nums;font-weight:800;font-size:1.18rem;text-align:right}
.tabla-curso .xp-total small{display:block;font-size:.68rem;font-weight:700;color:var(--tinta-3);letter-spacing:.08em}
.tabla-curso .acciones{display:flex;gap:.4rem;align-items:center;justify-content:flex-end}
/* 52 px de alto: se toca de pie, con el dedo, decenas de veces por clase. */
.tabla-curso .btn-sumar{
  height:52px;min-width:76px;padding:0 1rem;border-radius:12px;border:none;cursor:pointer;
  background:var(--lapis);color:#fff;font-weight:800;font-size:1.15rem;font-variant-numeric:tabular-nums;
  display:inline-flex;align-items:center;justify-content:center;
  box-shadow:0 2px 0 var(--lapis-osc);
  transition:transform var(--t),background var(--t),box-shadow var(--t);
}
.tabla-curso .btn-sumar:hover{background:#2C6FB0}
.tabla-curso .btn-sumar:active{transform:translateY(2px);box-shadow:0 0 0 var(--lapis-osc)}
.tabla-curso .btn-mini{
  height:52px;min-width:46px;border-radius:12px;border:1px solid var(--linea-fuerte);background:#F7FAFD;
  font-weight:700;font-size:.9rem;cursor:pointer;color:var(--tinta-2);
  transition:background var(--t),color var(--t),border-color var(--t);
}
.tabla-curso .btn-mini:hover{background:var(--lapis-suave);color:var(--lapis-osc);border-color:var(--lapis)}

/* El +XP que sube desde el botón. Vive en el <body> y no dentro de la
   fila: la fila tiene overflow y lo cortaba a media subida. */
.flota{
  position:fixed;z-index:120;pointer-events:none;font-weight:800;font-size:1.6rem;
  color:var(--crece);text-shadow:0 2px 10px rgba(255,255,255,.9);
  animation:sube 900ms cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes sube{
  0%{opacity:0;transform:translate(-50%,0) scale(.8)}
  18%{opacity:1;transform:translate(-50%,-12px) scale(1.12)}
  100%{opacity:0;transform:translate(-50%,-64px) scale(1)}
}

/* --- 13.5 Panel lateral --- */
.tabla-curso .lateral{display:grid;gap:1rem;position:sticky;top:110px}
.tabla-curso .panel{padding:1rem}
.tabla-curso .panel h2{font-size:1rem;display:flex;align-items:center;gap:.5rem}
.tabla-curso .panel .nota{font-size:.8rem;color:var(--tinta-2);margin:.35rem 0 .8rem}
.tabla-curso .panel-crecimiento{
  border:2px solid var(--crece);border-radius:var(--radio);
  background:linear-gradient(180deg,var(--crece-suave),#fff 62%);
  box-shadow:var(--sombra);
}
.tabla-curso .panel-crecimiento h2{color:#075A39}
.tabla-curso .etiqueta-destacado{
  margin-left:auto;font-size:.66rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  background:var(--crece);color:#fff;padding:.18rem .45rem;border-radius:999px;
}
.tabla-curso .podio-lista{list-style:none;margin:0;padding:0;display:grid;gap:.4rem}
.tabla-curso .podio-item{display:grid;grid-template-columns:26px minmax(0,1fr) auto;gap:.55rem;align-items:center;font-size:.9rem}
.tabla-curso .podio-item .med{
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:.78rem;
  background:var(--r4-suave);color:var(--tinta);
}
.tabla-curso .podio-item:nth-child(1) .med{background:var(--r5-suave);color:#6A5307;border:1px solid var(--r5)}
.tabla-curso .podio-item:nth-child(2) .med{background:var(--r4-suave);border:1px solid var(--r4)}
.tabla-curso .podio-item:nth-child(3) .med{background:var(--r2-suave);color:#6B3F17;border:1px solid var(--r2)}
.tabla-curso .podio-item .nom{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tabla-curso .podio-item .pxp{font-variant-numeric:tabular-nums;font-weight:700;color:var(--tinta-2);font-size:.85rem}
.tabla-curso .candado{
  margin-top:.7rem;font-size:.78rem;color:var(--tinta-2);background:#F5F8FB;border:1px dashed var(--linea-fuerte);
  border-radius:var(--radio-s);padding:.5rem .6rem;display:flex;gap:.45rem;align-items:flex-start;
}
.tabla-curso .candado svg{margin-top:.15rem}

/* --- 13.6 Barra de deshacer (ventana de 60 s) --- */
.deshacer{
  position:fixed;left:50%;bottom:16px;transform:translateX(-50%) translateY(140%);
  z-index:150;width:min(560px,calc(100vw - 24px));
  background:var(--lapis-noche);color:#fff;border-radius:var(--radio);box-shadow:var(--sombra-alta);
  padding:.7rem .8rem;display:flex;align-items:center;gap:.75rem;
  transition:transform 300ms cubic-bezier(.2,.7,.3,1),opacity var(--t);opacity:0;
}
.deshacer.visible{transform:translateX(-50%) translateY(0);opacity:1}
.deshacer .txt{flex:1;min-width:0;font-size:.92rem}
.deshacer .txt b{font-weight:700;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.deshacer .txt small{display:block;color:#BFD6EC;font-size:.78rem}
.reloj{position:relative;width:38px;height:38px;flex:none;display:grid;place-items:center}
.reloj svg{position:absolute;inset:0;transform:rotate(-90deg);width:38px;height:38px}
.reloj circle{fill:none;stroke-width:4}
.reloj .pista-c{stroke:rgba(255,255,255,.22)}
.reloj .avance{stroke:var(--dorado);stroke-linecap:round;transition:stroke-dashoffset 1s linear}
.reloj b{font-size:.74rem;font-variant-numeric:tabular-nums}
.btn-deshacer{
  height:44px;padding:0 1rem;border-radius:10px;border:none;background:var(--dorado);color:#3A2A00;
  font-weight:800;cursor:pointer;display:inline-flex;align-items:center;gap:.4rem;flex:none;
}
.btn-deshacer:hover{background:#FFD450}
.btn-deshacer[disabled]{opacity:.6;cursor:not-allowed}

/* --- 13.7 Celebración de subida de rango --- */
/* Reusa la modal de la sección 11 (foco atrapado, Esc, devolución del
   foco). Esta clase solo le cambia la cara: título centrado bajo la copa
   en vez de la cabecera con la X. */
#confeti{position:fixed;inset:0;z-index:190;pointer-events:none;display:none}
.velo.velo-festejo .modal{max-width:420px;text-align:center}
.velo-festejo .modal-cabeza{padding-bottom:0;flex-direction:column;text-align:center}
.velo-festejo .modal-cabeza h2{margin-right:0;font-size:1.5rem;order:2}
.velo-festejo .modal-cabeza [data-cerrar]{position:absolute;right:.6rem;top:.6rem}
.velo-festejo .modal-pie{border-top:0}
.velo-festejo .modal{position:relative}
.copa-grande{
  width:104px;height:104px;margin:0 auto .2rem;border-radius:50%;display:grid;place-items:center;
  background:var(--c-suave,var(--r1-suave));border:3px solid var(--c-rango,var(--dorado));font-size:3.2rem;
  animation:latido 1.4s ease-in-out infinite;
}
@keyframes latido{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
.velo-festejo .quien{font-size:1.05rem;color:var(--tinta-2);margin:.2rem 0 .9rem}

/* --- 13.8 Modo proyector --- */
/* La misma tabla, proyectada al curso: letra más grande, fondo oscuro y
   todo lo que no le corresponde a la pared, fuera. Qué se va y por qué
   está escrito en app.js, donde se enciende. */
/* La letra grande se pide en el ELEMENTO RAÍZ y no en el body. `rem` mide
   contra el font-size de <html>, y <html> lee `--base` de sí mismo: una
   redefinición en el body no la ve nunca. Con --base solo en el body el
   modo proyector cambiaba de color y NADA de tamaño, que es justo lo
   único que se necesita desde el fondo de la sala. La clase la pone
   app.js en los dos elementos. */
html.proyector{--base:22px}
body.proyector{background:var(--proyector-fondo);color:#fff}
body.proyector .cabecera{background:none;border-bottom:1px solid rgba(255,255,255,.14)}
/* El resto de la cabecera —quién inició sesión, la etiqueta de rol, "Mi
   cuenta", "Salir"— es papelería de la profesora: no tiene nada que
   hacer en la pared. Sin el degradado de fondo quedaba flotando ahí
   mismo, justo debajo del botón fijo "Salir del modo proyector" y
   tapándose con él (y con el botón de sonido). Se va, con el mismo
   criterio que ya se usa para el buscador y el selector de curso. */
body.proyector .cabecera .docente,
body.proyector .cabecera a[href="#/cuenta"],
body.proyector .cabecera #btn-salir{display:none}
/* El selector de color SÍ se queda: el proyector ya respeta el tema
   elegido (13.8b, más abajo) y la profesora puede querer cambiarlo sin
   salir del modo. Al perder el resto de sus vecinos de la cabecera ya
   no tiene sentido dejarlo en ese flujo (competía por el mismo rincón
   que los controles fijos del proyector); se saca y se apila con
   ellos, mismo right:14px y el mismo patrón de 2px de separación que
   ya separa "salir" (top:14, alto 48) del bloque de sonido (top:64). */
body.proyector .cabecera #btn-tema{
  position:fixed;top:114px;right:14px;z-index:160;
  background:var(--superficie);border-color:var(--linea-fuerte);color:var(--tinta);
}
body.proyector .cabecera #btn-tema:hover{background:#F4F8FC}
body.proyector .menu{display:none}
body.proyector .tabla-curso .lateral,
body.proyector .tabla-curso .volver,
body.proyector .tabla-curso .encabezado-lista .col-acciones{display:none}

/* La barra de herramientas se va del proyector, salvo el botón de sonido.
   Proyectar suele significar el cable a los parlantes de la sala, y el
   sonido se guarda en localStorage: se queda encendido de una clase para
   la otra. Con la barra entera escondida, la única forma de callarlo era
   salir del modo proyector delante del curso, apagarlo y volver a entrar.
   El botón se queda —debajo del de salir, que ya vive fijo arriba a la
   derecha—; el selector de curso y el buscador no, que esos sí son
   controles de la docente y no tienen nada que hacer en la pared. */
body.proyector .tabla-curso .herramientas{
  position:fixed;top:64px;right:14px;z-index:160;
  display:block;padding:0;margin:0;border:none;background:none;box-shadow:none;
}
body.proyector .tabla-curso .herramientas > *{display:none}
body.proyector .tabla-curso .herramientas > #tc-sonido{display:inline-flex}
body.proyector .tabla-curso .conceptos{background:rgba(var(--proyector-fondo-rgb),.94);border-bottom-color:rgba(255,255,255,.14)}
body.proyector .tabla-curso .titulillo em,
body.proyector .tabla-curso .rotulo,
body.proyector .tabla-curso .encabezado-lista{color:#BFD6EC}
body.proyector .tabla-curso .pista{background:rgba(255,255,255,.10);border-color:rgba(255,255,255,.25);color:#fff}
body.proyector .tabla-curso .pista .xp{background:rgba(255,255,255,.20);color:#fff}
/* La píldora activa se pierde entre las demás sobre el fondo oscuro del
   proyector (rgba blanco tenue en las 3): se resuelve con --dorado sólido,
   el mismo acento dorado que ya marca "elegido/destacado" en el resto de
   la UI (temporizador, insignias) y que no cambia entre los 3 temas, así
   que el contraste queda garantizado sin importar Clásico/Cielo/Arena. */
body.proyector .tabla-curso .pista[aria-pressed=true]{
  background:var(--dorado);border-color:var(--dorado-osc);color:#3A2A00;
  box-shadow:0 4px 14px rgba(244,196,48,.45);
}
body.proyector .tabla-curso .pista[aria-pressed=true] .xp{background:rgba(58,42,0,.18);color:#3A2A00}
body.proyector .tabla-curso .columnas{grid-template-columns:minmax(0,1fr)}
body.proyector .tabla-curso .meta{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.16);color:#fff}
body.proyector .tabla-curso .meta-pie,
body.proyector .tabla-curso .meta-cifra small{color:#BFD6EC}
body.proyector .tabla-curso .meta-pie b,
body.proyector .tabla-curso .xp-total small{color:#FFFFFF}
body.proyector .tabla-curso .chip-mes{background:rgba(255,255,255,.16);color:#EAF3FB}
body.proyector .tabla-curso .barra-meta{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.2)}
body.proyector .tabla-curso .puntitos i{background:rgba(255,255,255,.22)}
body.proyector .tabla-curso .puntitos i.on{background:#3FD08A}
body.proyector .tabla-curso .semana .grande{color:#3FD08A}
body.proyector .tabla-curso .semana{border-left-color:rgba(255,255,255,.18)}
body.proyector .tabla-curso .fila{
  background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.16);color:#fff;padding:.75rem 1rem;
}
body.proyector .tabla-curso .fila:hover{background:rgba(255,255,255,.12)}
body.proyector .tabla-curso .fila.destello{animation:destello-oscuro 700ms ease-out}
@keyframes destello-oscuro{
  0%{box-shadow:0 0 0 0 rgba(63,208,138,.55);background:rgba(63,208,138,.22)}
  100%{box-shadow:0 0 0 14px rgba(63,208,138,0);background:rgba(255,255,255,.07)}
}
body.proyector .tabla-curso .faltan,
body.proyector .tabla-curso .num{color:#BFD6EC}
body.proyector .tabla-curso .barra{background:rgba(255,255,255,.18)}
body.proyector .tabla-curso .insignia{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.28);color:#fff}
body.proyector .tabla-curso .btn-mini{background:rgba(255,255,255,.10);border-color:rgba(255,255,255,.26);color:#fff}
body.proyector .tabla-curso .lista{max-width:1100px;margin:0 auto}
body.proyector .salir-proyector{display:inline-flex}
.salir-proyector{display:none;position:fixed;right:14px;top:14px;z-index:160}

/* ---------- 13b. Premios del curso (Fase 6) ----------

   La pantalla que decide cuánto papel sale de la impresora. Todo lo que
   hay acá está al servicio de dos preguntas: qué se va a imprimir y
   cuántas hojas van a salir. */

/* Un premio y su gente. El borde de la izquierda es lo que hace que un
   lote de cinco premios distintos se lea como cinco bloques y no como
   una lista de sesenta líneas. */
.grupo-premio{
  border-left:3px solid var(--lapis-suave);
  padding-left:.9rem;
  margin-bottom:1.2rem;
}
.grupo-premio__cab{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;margin-bottom:.2rem}
.grupo-premio__titulo{margin-right:auto;min-width:0}
.grupo-premio__titulo b{display:block;font-size:1rem}
.grupo-premio__titulo .secundario{font-size:.82rem;color:var(--tinta-2)}
.grupo-premio__marca{display:flex;align-items:center}
.grupo-premio__marca input,
.celda-marca input{width:22px;height:22px;accent-color:var(--lapis);flex:none;cursor:pointer}
.tabla-premios .celda-marca{width:44px}
.tabla-premios .secundario{display:block}

/* La barra del gasto. Pegada abajo mientras se recorre la lista: la
   decisión de imprimir se toma mirando los pendientes, no habiendo
   llegado al final de la página. */
.barra-seleccion{
  position:sticky;
  bottom:0;
  z-index:20;
  display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;
  padding:.7rem .9rem;
  margin:.4rem -.2rem 0;
  background:var(--superficie);
  border:1px solid var(--linea);
  border-radius:var(--radio);
  box-shadow:var(--sombra);
}
.barra-seleccion__cuenta{font-weight:600;margin-right:auto;font-size:.95rem}

/* --- La ventana de impresión --- */

/* Más ancha que una modal normal: adentro va una hoja carta de verdad y
   no un formulario de cuatro campos. */
.modal-ancho{width:min(1080px,96vw);max-width:min(1080px,96vw)}

.impresion{display:grid;grid-template-columns:minmax(210px,270px) minmax(0,1fr);gap:1rem;align-items:start}
.impresion-lista{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.impresion-item{
  width:100%;text-align:left;font:inherit;cursor:pointer;
  display:flex;flex-direction:column;gap:.3rem;
  padding:.7rem .8rem;
  background:var(--superficie);
  border:1px solid var(--linea);
  border-radius:var(--radio-s);
  color:inherit;
}
.impresion-item:hover{background:#F4F8FC}
.impresion-item.activo{border-color:var(--lapis);box-shadow:0 0 0 2px var(--lapis-suave)}
.impresion-item b{font-size:.95rem;line-height:1.2}
.impresion-item .secundario{font-size:.8rem;color:var(--tinta-2)}
.impresion-item__estado{font-size:.8rem;font-weight:700;color:var(--crece)}
.impresion-cabeza{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap;margin-bottom:.5rem}
.impresion-cabeza .secundario{font-size:.82rem;color:var(--tinta-2)}

/* La caja de la vista previa. La hoja de adentro está medida en
   milímetros contra una carta, así que no se encoge: se escala con
   transform desde la esquina y la caja se recorta a lo que quepa. */
.marco-caja{
  overflow:auto;
  border:1px solid var(--linea);
  border-radius:var(--radio-s);
  background:#E8EBEF;
}
.marco-caja iframe{display:block;border:0;transform-origin:0 0;background:#E8EBEF}

/* ---------- 13c. Auditoría (Fase 8) ----------

   Pantalla de soporte técnico: la única licencia visual es el código de
   la acción en monoespaciado (para que "usuario_actualizar" no se
   confunda con prosa) y el bloque de detalle, que solo aparece si
   alguien lo pide — ver el comentario de filaAuditoria() en app.js
   sobre por qué datos_antes/datos_despues no van sueltos en la fila. */
.tabla code{
  font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:.82em;
  background:var(--fondo);
  padding:.15rem .45rem;
  border-radius:6px;
}
.detalle-auditoria{
  white-space:pre-wrap;
  word-break:break-word;
  font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:.85em;
  margin:0;
}

/* ---------- 14. Responsive ---------- */
@media (max-width:900px){
  .encabezado-pantalla{align-items:stretch}
  .encabezado-pantalla .acciones{width:100%;display:flex;gap:.6rem;flex-wrap:wrap}
  .encabezado-pantalla .acciones .btn{flex:1 1 auto;justify-content:center}
}

/* Bajo 760 px la tabla se convierte en tarjetas apiladas.
   Nada de scroll horizontal: la docente está en el celular. */
@media (max-width:760px){
  .herramientas .cuenta{margin-left:0;width:100%}
  .campo-busqueda{flex:1 1 100%}
  .campo-busqueda input{width:100%}
  .herramientas > select{flex:1 1 100%}

  .tabla{border-spacing:0}
  .tabla thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .tabla,.tabla tbody,.tabla tr,.tabla td{display:block;width:100%}
  .tabla tbody tr{
    background:var(--superficie);border:1px solid var(--linea);border-radius:var(--radio);
    padding:.75rem .85rem;margin-bottom:.6rem;
  }
  .tabla tbody td{
    padding:.3rem 0;border:0 !important;border-radius:0 !important;
    display:grid;grid-template-columns:38% minmax(0,1fr);gap:.5rem;align-items:baseline;
  }
  .tabla tbody td::before{
    content:attr(data-rotulo);
    font-size:.8rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
    color:var(--tinta-3);
  }
  .tabla tbody td.celda-principal{
    grid-template-columns:1fr;gap:.15rem;padding-bottom:.5rem;
  }
  .tabla tbody td.celda-principal::before{content:none}
  .tabla tbody td.numero{text-align:left}
  .tabla tbody td.celda-acciones{
    grid-template-columns:1fr;margin-top:.55rem;padding-top:.6rem;
    border-top:1px solid var(--linea) !important;
  }
  .tabla tbody td.celda-acciones::before{content:none}
  .celda-acciones .grupo{justify-content:stretch}
  .celda-acciones .grupo .btn{flex:1 1 auto;justify-content:center}

  /* En el celular se toca con el dedo, no con el mouse: los botones
     chicos suben al alto mínimo de toque que declara la hoja. */
  .btn-chico{height:var(--toque);min-height:var(--toque)}
  .btn-chico.btn-icono{width:var(--toque)}

  .modal{width:100%;border-radius:var(--radio);max-height:calc(100vh - 1rem)}
  .modal-pie .btn{flex:1 1 100%}
  .avisos{bottom:10px}

  /* La tabla del curso también se apila. La docente anda con el celular en
     la mano: nada de scroll horizontal para llegar al botón de sumar. */
  .tabla-curso .meta{grid-template-columns:1fr;border-radius:var(--radio)}
  .tabla-curso .semana{border-left:none;border-top:1px solid var(--linea);padding-left:0;padding-top:.9rem}
  .tabla-curso .encabezado-lista{display:none}
  .tabla-curso .fila{
    grid-template-columns:auto minmax(0,1fr) auto;
    grid-template-areas:
      "num nombre xp"
      "num rango rango"
      "prog prog prog"
      "acc acc acc";
    gap:.35rem .7rem;padding:.75rem .85rem;
  }
  .tabla-curso .num{
    grid-area:num;align-self:start;background:var(--lapis-suave);color:var(--lapis-osc);
    width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  }
  /* display:contents deja que el nombre y la barra se acomoden cada uno en
     su área de la rejilla en vez de arrastrar el contenedor entero. */
  .tabla-curso .ident{grid-area:nombre;display:contents}
  .tabla-curso .nombre{grid-area:nombre;font-size:1.05rem}
  .tabla-curso .progreso{grid-area:prog;margin-top:.3rem}
  .tabla-curso .insignia{grid-area:rango;justify-self:start}
  .tabla-curso .xp-total{grid-area:xp;text-align:right;font-size:1.25rem}
  .tabla-curso .xp-total small{display:inline;font-size:.7rem;margin-left:.15rem}
  .tabla-curso .acciones{grid-area:acc;margin-top:.5rem}
  .tabla-curso .btn-sumar{flex:1;height:56px;font-size:1.2rem}
  .tabla-curso .btn-mini{height:56px;min-width:56px}
  .tabla-curso .lateral{gap:.8rem}
  .deshacer{bottom:10px}
}

@media (max-width:1080px){
  .tabla-curso .columnas{grid-template-columns:minmax(0,1fr)}
  .tabla-curso .lateral{position:static}
}

@media (max-width:420px){
  .marca .sub{display:none}
  .docente .quien{max-width:9.5rem}
  .btn{padding:0 .85rem}
  .envoltura{padding:.8rem .7rem 1.6rem}
  .rejilla-campos{grid-template-columns:1fr}

  .tabla-curso .fila{padding:.7rem .7rem}
  .tabla-curso .btn-mini{min-width:50px;padding:0 .35rem}
}

/* ---------- 15. Movimiento reducido ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important;
  }
  /* El girador queda quieto: quien pidió menos movimiento lo pidió en
     serio. El estado se sigue entendiendo porque al lado siempre va la
     palabra "Cargando…". Se le deja el borde de color para que no
     parezca un círculo suelto sin sentido. */
  .girador{border-top-color:var(--lapis)}

  /* La barra de deshacer se posiciona con transform, así que sin
     transición se quedaba pegada abajo de la pantalla, empujada por su
     propio translateY(140%). Acá aparece y desaparece sin deslizarse. */
  .deshacer{transform:translateX(-50%) translateY(0)}
  .deshacer:not(.visible){display:none}
}

/* ---------- 16. Impresión de la aplicación (red de seguridad) ----------

   LA IMPRESIÓN DE VERDAD NO PASA POR ACÁ. Los premios se imprimen dentro
   del iframe de su plantilla, que es otro documento con su propio @page
   y su propio premios.css: nada de esta hoja lo toca, y por eso la
   aplicación no declara @page (declararlo obligaría a que el diploma
   apaisado y los catorce verticales cupieran en una sola regla).

   Esto es para el otro caso: el Ctrl+P suelto sobre la aplicación. Sin
   estas reglas, esa hoja sale con la cabecera azul a sangre, el menú, la
   barra del gasto y los avisos flotantes encima del contenido. No es un
   flujo previsto, pero es un accidente de un dedo. */
@media print{
  .cabecera,.menu,.saltar,.avisos,#modales,.barra-seleccion,
  .celda-acciones,.herramientas,.salir-proyector,.deshacer{display:none !important}
  body{background:#fff;color:#000}
  .envoltura{max-width:none;padding:0}
  .tarjeta{border:0;box-shadow:none;break-inside:avoid}
  .tabla tbody tr{box-shadow:none}
}

/* ---------- 17. Ranking y reportes (Fase 7) ----------

   Todo lo del podio y el crecimiento cuelga de .tabla-curso a propósito:
   la pantalla envuelve su raíz en class="ranking tabla-curso" para reusar
   TAL CUAL .meta/.chip-mes/.barra-meta/.semana/.puntitos (13.1), .panel/
   .panel-crecimiento/.podio-lista/.podio-item/.candado/.etiqueta-destacado
   (13.5) y .insignia/.progreso/.barra (13.4) de la tabla del curso — son
   el mismo lenguaje visual (la meta colectiva, el podio de 5, la copa de
   un alumno) y duplicar esas reglas acá las habría dejado desincronizadas
   la primera vez que alguien ajustara una sola de las dos pantallas. Acá
   solo va lo que la tabla del curso no tiene: la rejilla de dos widgets,
   la tarjeta de un alumno suelto y el acta imprimible. */

.ranking-widgets{
  display:grid;grid-template-columns:1.15fr 1fr;gap:1rem;align-items:start;
  margin:1rem 0;
}
.ranking .tarjeta-alumno{
  background:var(--superficie);border:1px solid var(--linea);border-left:6px solid var(--c-rango,var(--lapis));
  border-radius:var(--radio);padding:1rem;margin-top:.7rem;max-width:420px;
}
.ranking .tarjeta-alumno__cifra{font-size:1.05rem;font-weight:600;margin:.5rem 0 .6rem}
.ranking .tarjeta-alumno__cifra b{font-variant-numeric:tabular-nums}
.ranking .insignia{margin-bottom:0}

/* El gráfico necesita una altura fija: Chart.js con maintainAspectRatio
   en falso llena el contenedor que le den, y sin alto el <canvas> queda
   en 0px y no se ve nada. */
.rk-grafico-caja{position:relative;height:260px;margin-top:.7rem}
.rk-grafico-caja canvas{width:100% !important;height:100% !important}

@media (max-width:900px){
  .ranking-widgets{grid-template-columns:1fr}
}
@media (max-width:420px){
  .rk-grafico-caja{height:210px}
}

/* --- El acta imprimible: vive FUERA de la pantalla (ver verActaImprimir()
   en app.js), append-eada directo al <body>, para que @media print pueda
   esconder TODO lo demás con un solo selector y dejar solo la tabla. --- */
#rk-acta-imprimir{display:none}
#rk-acta-imprimir table{width:100%;border-collapse:collapse;margin-top:.8rem;font-size:.82rem}
#rk-acta-imprimir th,#rk-acta-imprimir td{border:1px solid #99A3AF;padding:.32rem .5rem;text-align:left}
#rk-acta-imprimir th{background:#EEF2F6}

@media print{
  body.imprimiendo-acta > *:not(#rk-acta-imprimir){display:none !important}
  body.imprimiendo-acta #rk-acta-imprimir{display:block !important;color:#000}
}

/* ---------- 18. Movimiento reducido (Fase 7) ----------
   La barra de la meta y la del progreso de la tarjeta individual ya
   quedan cubiertas por la regla general de la sección 15 (transition-duration
   en .001ms). Lo único propio de esta pantalla es la animación de Chart.js,
   que se apaga desde JS (dibujarGraficoSemanal(), animation:false) porque
   Chart.js no lee prefers-reduced-motion por su cuenta. */

/* ---------- 19. Logros (Fase 5, pantalla) ----------
   No arma una ruta propia: vive dentro de .tarjeta-alumno (la tarjeta
   individual de ranking, sección 17) y dentro de la modal del catálogo
   (abrirCatalogoLogros() en app.js), mismo criterio que rangos. Los
   `.logro-chip` de acá NO cuelgan de `.tabla-curso .insignia` —esa regla
   vive coloreada por `--c-rango`/`--c-suave` del RANGO del alumno, y un
   logro no tiene color propio en la tabla, solo ícono— así que se define
   su propia pinta, en dorado fijo, para que un logro nunca se vea
   pintado con el color del rango de al lado. */
.logros-alumno{margin-top:1rem;padding-top:.85rem;border-top:1px solid var(--linea)}
.logros-alumno h3{font-size:.95rem;margin:0 0 .5rem}
.logros-alumno h4{
  font-size:.78rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  color:var(--tinta-2);margin:.9rem 0 .45rem;
}
.logros-catalogo{list-style:none;margin:0;padding:0;display:grid;gap:.5rem;max-width:480px}
.logro-chip{
  display:flex;align-items:center;gap:.6rem;background:var(--r1-suave);
  border:1px solid #E8C765;border-radius:10px;padding:.5rem .7rem;
}
.logro-chip .emoji{font-size:1.3rem;line-height:1;flex:none}
.logro-chip__texto{display:flex;flex-direction:column;gap:.1rem;min-width:0}
.logro-chip__texto .txt{font-weight:700;font-size:.92rem}
.logro-chip .condicion{font-size:.78rem;color:var(--tinta-2)}
.logro-chip .etiqueta{margin-left:auto;flex:none}

.logros-progreso{list-style:none;margin:0;padding:0;display:grid;gap:.65rem}
.logro-progreso-item{display:flex;gap:.6rem;align-items:flex-start}
.logro-progreso-item .emoji{font-size:1.15rem;line-height:1.3;flex:none}
.logro-progreso-item__cuerpo{display:flex;flex-direction:column;gap:.15rem;flex:1;min-width:0}
.logro-progreso-item__cuerpo .txt{font-weight:600;font-size:.9rem}
.logro-progreso-item__cuerpo .condicion{font-size:.78rem;color:var(--tinta-2)}
.logro-progreso-item__cuerpo .progreso{margin-top:.15rem;display:flex;align-items:center;gap:.5rem}
.logro-progreso-item__cuerpo .barra{
  height:7px;border-radius:999px;background:#E9EEF4;flex:1;overflow:hidden;min-width:60px;
}
.logro-progreso-item__cuerpo .barra i{
  display:block;height:100%;border-radius:999px;background:var(--lapis);
  transition:width 420ms cubic-bezier(.2,.7,.3,1);
}
.logro-progreso-item__cuerpo .faltan{font-size:.76rem;color:var(--tinta-2);white-space:nowrap}

@media (max-width:480px){
  .logros-catalogo{max-width:none}
}

/* ---------- 20. Mis conceptos y tope de puntaje (catálogo por docente) ----------
   Una fila por concepto, en tarjeta y no en tabla: en el celular la docente
   edita sus botones parada, y una tabla de cinco columnas obliga a arrastrar
   de costado. Las acciones bajan a su propia línea bajo el nombre y el
   puntaje, con altura de toque. */
.mc-guia h2{font-size:1.05rem}
.mc-guia ul{margin:.5rem 0 0 1.1rem;display:grid;gap:.35rem;font-size:.92rem;color:var(--tinta-2)}
.mc-categoria{margin-top:1.3rem}
.mc-categoria > h2{font-size:1.05rem;margin-bottom:.55rem}
.mc-lista{list-style:none;margin:0;padding:0;display:grid;gap:.55rem}
.mc-fila{
  display:grid;grid-template-columns:14px minmax(0,1fr) auto;
  grid-template-areas:"color info puntaje" "acc acc acc";
  gap:.45rem .8rem;align-items:start;
  background:var(--superficie);border:1px solid var(--linea);border-radius:var(--radio);
  padding:.8rem .9rem;box-shadow:var(--sombra);
}
.mc-color{grid-area:color;width:14px;height:14px;border-radius:50%;margin-top:.32rem;border:1px solid rgba(0,0,0,.18)}
.mc-info{grid-area:info;min-width:0}
.mc-nombre{font-weight:700;overflow-wrap:anywhere}
.mc-etiquetas{display:flex;flex-wrap:wrap;gap:.3rem;margin:.3rem 0}
.mc-info .secundario,.mc-puntaje .secundario{font-size:.84rem;color:var(--tinta-2)}
.mc-cuenta{margin-top:.15rem}
.mc-puntaje{grid-area:puntaje;text-align:right}
.mc-xp{display:block;font-size:1.45rem;font-weight:800;font-variant-numeric:tabular-nums;line-height:1.1}
.mc-xp small{font-size:.7rem;font-weight:700;color:var(--tinta-3);letter-spacing:.06em}
.mc-puntaje .secundario{display:block;max-width:15rem;margin-left:auto}
.mc-acciones{grid-area:acc;display:flex;flex-wrap:wrap;gap:.4rem;justify-content:flex-end;padding-top:.5rem;border-top:1px solid var(--linea)}
.mc-oculto{background:#FAFBFD}
.mc-oculto .mc-nombre,.mc-oculto .mc-xp{color:var(--tinta-2)}
.ic-abajo{transform:rotate(180deg)}
.mc-pie{margin-top:1rem;font-size:.88rem;color:var(--tinta-2)}
.mc-tope{display:flex;gap:.8rem;align-items:flex-end;flex-wrap:wrap;margin-top:.8rem}
.mc-tope .campo{margin-bottom:0;flex:0 1 280px}
input[type=color]{
  width:72px;height:var(--toque);padding:.25rem;border:1px solid var(--linea-fuerte);
  border-radius:var(--radio-s);background:var(--superficie);cursor:pointer;
}
/* Los botones de +XP de la tabla, cuando la vista no deja asignar (admin
   sin haber elegido profesora): se ven apagados en vez de fallar al toque. */
.tabla-curso .btn-sumar:disabled,.tabla-curso .btn-mini:disabled{opacity:.45;cursor:not-allowed;box-shadow:none;transform:none}

@media (max-width:560px){
  .mc-fila{grid-template-columns:14px minmax(0,1fr);grid-template-areas:"color info" "puntaje puntaje" "acc acc"}
  .mc-puntaje{text-align:left;display:flex;align-items:baseline;gap:.7rem;flex-wrap:wrap}
  .mc-puntaje .secundario{margin-left:0;max-width:none}
  .mc-acciones{justify-content:flex-start}
  .mc-tope .campo{flex:1 1 100%}
  .mc-tope .btn{width:100%;justify-content:center}
}

/* ---------- 21. Mis premios (catálogo de premios por docente) ----------
   Reusa las filas de "Mis conceptos" (.mc-*). Lo propio es el editor: el
   formulario a la izquierda y, al lado, la vista previa de la hoja real
   —la misma plantilla que se imprime, en un iframe—. En el celular la
   vista previa baja debajo del formulario. */
.campo[hidden]{display:none}
.mp-mensaje{font-style:italic;overflow-wrap:anywhere}
.mp-editor{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:1.2rem;align-items:start}
.mp-form fieldset{border:1px solid var(--linea);border-radius:var(--radio-s);padding:.7rem .8rem .5rem;margin:0 0 .9rem;min-width:0}
.mp-form legend{font-weight:700;font-size:.92rem;padding:0 .3rem}
.mp-plantillas{display:grid;gap:.5rem}
.mp-plantilla{display:flex;gap:.6rem;align-items:flex-start;padding:.6rem .7rem;border:1px solid var(--linea);border-radius:var(--radio-s);cursor:pointer}
.mp-plantilla:has(input:checked){border-color:var(--lapis);box-shadow:0 0 0 2px var(--lapis-suave)}
.mp-plantilla input{margin-top:.2rem;accent-color:var(--lapis);width:20px;height:20px;flex:none}
.mp-plantilla__cuerpo{display:flex;flex-direction:column;gap:.15rem;min-width:0}
.mp-plantilla__cuerpo .secundario{font-size:.8rem;color:var(--tinta-2)}
.mp-muestras{display:flex;flex-wrap:wrap;gap:.55rem;padding-bottom:.4rem}
.mp-muestra{position:relative;display:inline-flex;cursor:pointer}
.mp-muestra input{position:absolute;opacity:0;inset:0;width:100%;height:100%;margin:0;cursor:pointer}
.mp-muestra__bola{width:36px;height:36px;border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.28)}
.mp-muestra input:checked + .mp-muestra__bola{box-shadow:0 0 0 3px var(--lapis)}
.mp-muestra input:focus-visible + .mp-muestra__bola{outline:3px solid var(--lapis);outline-offset:2px}
.mp-fija{margin:0 0 .9rem}
.mp-previa{min-width:0;position:sticky;top:0}
.mp-previa__titulo{margin:0 0 .4rem}
.mp-previa__titulo .secundario{font-size:.82rem;color:var(--tinta-2)}
.mp-mano{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;gap:.8rem;align-items:end;margin-top:.8rem}
.mp-mano .campo{margin-bottom:0}

@media (max-width:820px){
  .mp-editor{grid-template-columns:minmax(0,1fr)}
  .mp-previa{position:static}
  .mp-mano{grid-template-columns:minmax(0,1fr)}
  .mp-mano .btn{width:100%;justify-content:center}
}
