/* ============================================================
   SCHOOLARYX — Pages CSS
   Estilos específicos por página
   ============================================================ */

.lms-task-item { background-color: #ffffff !important; }

/* ======================================================
   DASHBOARD
   ====================================================== */
.sx-mini-calendar {
  font-size: 0.8rem;
}
.sx-mini-calendar table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 2px;
}
.sx-mini-calendar th {
  text-align: center;
  font-weight: 800;
  font-size: 0.68rem;
  color: var(--sx-text-muted);
  text-transform: uppercase;
  padding: 0.25rem;
}
.sx-mini-calendar td {
  text-align: center;
  padding: 0.3rem 0.2rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--sx-text-body);
  font-weight: 600;
  transition: var(--transition-fast);
  border: none !important;
}
.sx-mini-calendar td:hover { background: var(--sx-primary-light); color: var(--sx-primary); }
.sx-mini-calendar td.today { background: var(--sx-primary); color: #fff; border-radius: var(--radius-sm); }
.sx-mini-calendar td.other-month { color: var(--sx-text-muted); opacity: 0.4; }
.sx-cal-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.75rem;
}
.sx-cal-nav button {
  background: none;
  border: none;
  color: var(--sx-text-muted);
  cursor: pointer;
  padding: 0.25rem;
  border-radius: var(--radius-sm);
  transition: var(--transition-fast);
}
.sx-cal-nav button:hover { background: var(--sx-primary-light); color: var(--sx-primary); }
.sx-cal-nav-title { font-weight: 800; font-size: 0.875rem; color: var(--sx-text-heading); }

/* Semester progress */
.sx-semester-progress { }
.sx-semester-item { margin-bottom: 1rem; }
.sx-semester-item:last-child { margin-bottom: 0; }
.sx-semester-label {
  display: flex;
  justify-content: space-between;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--sx-text-body);
  margin-bottom: 0.35rem;
}
.sx-semester-label span:last-child { color: var(--sx-text-muted); }

/* ======================================================
   FORMS — WIZARD
   ====================================================== */
.sx-wizard-steps {
  display: flex;
  align-items: center;
  margin-bottom: 2rem;
  position: relative;
}
.sx-wizard-steps::before {
  content: '';
  position: absolute;
  top: 18px;
  left: 10%;
  right: 10%;
  height: 2px;
  background: var(--sx-border-color);
  z-index: 0;
}
.sx-wizard-step {
  flex: 1;
  text-align: center;
  position: relative;
  z-index: 1;
}
.sx-wizard-step-dot {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--sx-border-color);
  color: var(--sx-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 0.875rem;
  margin: 0 auto 0.5rem;
  transition: var(--transition);
  border: 2px solid var(--sx-border-color);
}
.sx-wizard-step.active .sx-wizard-step-dot {
  background: var(--sx-primary);
  color: #fff;
  border-color: var(--sx-primary);
  box-shadow: 0 0 0 4px var(--sx-primary-light);
}
.sx-wizard-step.done .sx-wizard-step-dot {
  background: var(--sx-success);
  color: #fff;
  border-color: var(--sx-success);
}
.sx-wizard-step-label {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--sx-text-muted);
}
.sx-wizard-step.active .sx-wizard-step-label { color: var(--sx-primary); }
.sx-wizard-step.done .sx-wizard-step-label  { color: var(--sx-success-dark); }

.sx-wizard-panel { display: none; }
.sx-wizard-panel.active { display: block; }

/* ======================================================
   FORMS — FILE UPLOAD
   ====================================================== */
.sx-file-preview-list { list-style: none; padding: 0; margin-top: 1rem; }
.sx-file-preview-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.875rem;
  background: var(--sx-body-bg);
  border: 1px solid var(--sx-border-color);
  border-radius: var(--radius);
  margin-bottom: 0.5rem;
}
.sx-file-preview-icon { font-size: 1.25rem; color: var(--sx-primary); flex-shrink: 0; }
.sx-file-preview-name { font-size: 0.8rem; font-weight: 700; color: var(--sx-text-body); flex: 1; }
.sx-file-preview-size { font-size: 0.72rem; color: var(--sx-text-muted); }
.sx-file-preview-remove {
  background: none;
  border: none;
  color: var(--sx-danger);
  cursor: pointer;
  padding: 0.2rem;
  border-radius: var(--radius-sm);
  opacity: 0.7;
  transition: var(--transition-fast);
}
.sx-file-preview-remove:hover { opacity: 1; background: var(--sx-danger-light); }

/* ======================================================
   FORMS — INPUT MASKS
   ====================================================== */
.sx-mask-group { margin-bottom: 1.25rem; }
.sx-mask-complete { border-color: var(--sx-success) !important; }
.sx-mask-complete:focus { box-shadow: 0 0 0 3px rgba(var(--sx-success-rgb), 0.15) !important; }

/* Card detector de tarjeta */
.sx-card-type-icon {
  font-size: 1.25rem;
  color: var(--sx-text-muted);
  transition: var(--transition-fast);
}
.sx-card-type-visa    { color: #1434cb; }
.sx-card-type-mc      { color: #eb001b; }
.sx-card-type-amex    { color: #007bc1; }

/* ======================================================
   FORMS — SELECT2 CUSTOM THEME
   ====================================================== */
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
  border: 1.5px solid var(--sx-border-color) !important;
  border-radius: var(--radius) !important;
  min-height: 40px !important;
  background: var(--sx-card-bg) !important;
  font-family: var(--font-body) !important;
  font-size: 0.875rem !important;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
  color: var(--sx-text-body) !important;
  line-height: 38px !important;
  padding-left: 0.875rem !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
  height: 38px !important;
}
/* En Select2 4.1.0 el <ul> de chips y el campo de búsqueda son hermanos
   APILADOS dentro de un contenedor block → el cuadro vacío queda ~58px de alto.
   Lo convertimos en una fila flex y disolvemos el <ul> (display:contents) para
   que chips + buscador fluyan en la MISMA línea, igual que un select2 single. */
.select2-container--default .select2-selection--multiple {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  padding: 0.15rem 0.5rem !important;
  gap: 0.25rem !important;
}
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
  display: contents !important;
  padding: 0 !important;
  margin: 0 !important;
}
/* Campo de búsqueda interno: ya es un item flex del contenedor; lo alineamos
   a la altura del single (40px de caja). */
.select2-container--default .select2-selection--multiple .select2-search--inline {
  display: flex !important;
  align-items: center !important;
  margin: 0 !important;
}
.select2-container--default .select2-selection--multiple .select2-search--inline .select2-search__field {
  margin: 0 !important;
  padding-left: 0.3rem !important;
  height: 28px !important;
  line-height: 28px !important;
  /* El texto que se escribe debe usar la MISMA fuente/color que el resto del
     select2 (Nunito), no el sans-serif negro por defecto del navegador. */
  font-family: var(--font-body) !important;
  font-size: 0.875rem !important;
  font-weight: 400 !important;
  color: var(--sx-text-body) !important;
}
.select2-container--default .select2-selection--multiple .select2-search--inline .select2-search__field::placeholder {
  color: var(--sx-text-muted) !important;
  font-family: var(--font-body) !important;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
  background: var(--sx-primary-light) !important;
  border: 1px solid var(--sx-primary) !important;
  border-radius: var(--radius-pill) !important;
  color: var(--sx-primary) !important;
  font-size: 0.78rem !important;
  font-weight: 700 !important;
  /* inline-flex + gap: la "x" (botón) y el nombre se alinean sin encimarse.
     En Select2 4.1.0 el chip es <button.remove> + <span.display>; al pasar
     ambos a flex con position:static, el layout absoluto por defecto se anula. */
  display: inline-flex !important;
  align-items: center !important;
  gap: 0.4rem !important;
  padding: 0.1rem 0.65rem 0.1rem 0.35rem !important;
  margin: 0.1rem !important;
  line-height: 1.4 !important;
  position: relative !important;
}
/* El texto del chip: anula el padding-left por defecto (28px) que dejaba
   hueco para la "x" absoluta — ahora la "x" es un item flex normal. */
.select2-container--default .select2-selection--multiple .select2-selection__choice__display {
  padding: 0 !important;
  line-height: 1.4 !important;
}
/* "x" como botón circular claro y clickeable (más legible para marcar) */
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
  color: var(--sx-primary) !important;
  /* Quita el posicionamiento absoluto y el separador por defecto de Select2 */
  position: static !important;
  border: 0 !important;
  border-right: 0 !important;
  background: transparent !important;
  padding: 0 !important;
  margin: 0 !important;
  top: auto !important;
  left: auto !important;
  font-weight: 700 !important;
  font-size: 0.85rem !important;
  line-height: 1 !important;
  order: -1 !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 1.1rem !important;
  height: 1.1rem !important;
  border-radius: 50% !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  transition: background-color .15s ease, color .15s ease !important;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
  color: #fff !important;
  background: var(--sx-danger) !important;
}
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single {
  border-color: #bdbdbd !important;
  box-shadow: none !important;
}
.select2-dropdown {
  border: 1px solid var(--sx-border-color) !important;
  border-radius: var(--radius-lg) !important;
  box-shadow: var(--shadow-lg) !important;
  background: var(--sx-card-bg) !important;
  font-family: var(--font-body) !important;
  font-size: 0.875rem !important;
  overflow: hidden;
}
.select2-search--dropdown .select2-search__field {
  border: 1.5px solid var(--sx-border-color) !important;
  border-radius: var(--radius-sm) !important;
  padding: 0.4rem 0.75rem !important;
  font-family: var(--font-body) !important;
  font-size: 0.875rem !important;
  color: var(--sx-text-body) !important;
  background: var(--sx-body-bg) !important;
  box-shadow: none !important;
  outline: none !important;
}
.select2-search--dropdown .select2-search__field:focus {
  box-shadow: none !important;
  outline: none !important;
  border-color: #bdbdbd !important;
}
.select2-results__option {
  padding: 0.5rem 0.875rem !important;
  border-radius: var(--radius-sm) !important;
  font-family: var(--font-body) !important;
  font-size: 0.875rem !important;
  color: var(--sx-text-body) !important;
  transition: var(--transition-fast) !important;
}
.select2-results__option--highlighted {
  background: var(--sx-primary-light) !important;
  color: var(--sx-primary) !important;
}
.select2-results__option--selected {
  background: var(--sx-primary) !important;
  color: #fff !important;
}
.select2-results__group {
  font-size: 0.7rem !important;
  font-weight: 800 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
  color: var(--sx-text-muted) !important;
  padding: 0.6rem 0.875rem 0.25rem !important;
}

/* Select2: alinear altura/padding con .form-control y dar más aire interno */
.select2-container--default .select2-selection--single {
  height: calc(1.5em + 1rem + 3px) !important;
  padding: 0 0.25rem !important;
  display: flex !important;
  align-items: center !important;
  position: relative !important;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
  line-height: 1.5 !important;
  padding-left: 0.6rem !important;
  padding-right: 3.6rem !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
  height: 100% !important;
  width: 2.2rem !important;
  right: 2px !important;
}
.select2-container--default .select2-selection__placeholder {
  color: var(--sx-text-muted) !important;
}
/* allowClear: mover la "x" a la derecha, justo al lado del arrow (no a la izquierda). */
.select2-container--default .select2-selection--single .select2-selection__clear {
  position: absolute !important;
  right: 2.5rem !important;
  top: 50% !important;
  transform: translateY(-50%) !important;
  margin: 0 !important;
  padding: 0 !important;
  line-height: 1 !important;
  z-index: 2 !important;
  color: var(--sx-text-muted) !important;
}
.select2-container--default .select2-selection--single .select2-selection__clear:hover {
  color: var(--sx-danger) !important;
}
.select2-results__options { padding: 0.3rem !important; }
.select2-results__option { margin-bottom: 0.1rem !important; }
.select2-dropdown { padding: 0 !important; }

/* ======================================================
   MODAL FORMS — FIELDSET + INPUT CON ÍCONO (patrón super-admin)
   Convención de markup:
     <fieldset class="app-form-fieldset">
       <legend class="app-form-legend">Grupo</legend>
       <div class="form-icon">
         <input class="form-control form-control-icon"> <i class="bi bi-..."></i>
       </div>
     </fieldset>
   Textarea: usar .form-icon.form-icon-textarea (ícono arriba).
   ====================================================== */
.app-form-fieldset {
  border: 1.5px solid var(--sx-border-color);
  border-radius: var(--radius);
  padding: 1rem 1rem 0.85rem;
  margin: 0 0 1rem;
  background: var(--sx-card-bg);
}
.app-form-fieldset:last-child { margin-bottom: 0; }
.app-form-legend {
  float: none;
  width: auto;
  margin: 0 0 0.25rem;
  padding: 0 0.5rem;
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sx-primary);
}
/* Fieldset de traducción (es/en) con leve tinte para distinguir idioma */
.app-form-fieldset-lang { background: var(--sx-body-bg); }
.app-form-label-flag {
  margin-left: 0.35rem;
  vertical-align: baseline;
  line-height: 1;
  font-size: 0.95rem;
}

/* Input con ícono interno (izquierda) */
.form-icon { position: relative; }
.form-icon > i {
  position: absolute;
  top: 50%;
  left: 0.9rem;
  transform: translateY(-50%);
  color: var(--sx-text-muted);
  font-size: 1rem;
  line-height: 1;
  z-index: 5;
  pointer-events: none;
}
.form-control-icon { padding-left: 2.5rem !important; }
.form-icon .form-control:focus ~ i,
.form-icon:focus-within > i { color: var(--sx-primary); }
/* Ícono de YouTube (enlaces de video): siempre en color de marca de error/rojo,
   incluso con foco (no cambia a primary). */
.form-icon > i.bi-youtube,
.form-icon:focus-within > i.bi-youtube { color: var(--sx-danger); }

/* Select2 dentro de .form-icon: empujar el texto para el ícono */
.form-icon .select2-container--default .select2-selection--single .select2-selection__rendered {
  padding-left: 1.9rem !important;
}
/* Select2 MÚLTIPLE dentro de .form-icon: empujar los tags/placeholder para el ícono */
.form-icon .select2-container--default .select2-selection--multiple {
  padding-left: 1.9rem !important;
}
.form-icon .select2-container { z-index: 1; }

/* Filtros de estudiantes: el mensaje de validacion aumenta la altura del
   wrapper y con top:50% el icono se desplaza. Aqui lo fijamos al alto del
   control para que Select2 conserve la alineacion. */
/* Textarea con ícono: ícono anclado arriba, no centrado */
.form-icon-textarea > i { top: 0.85rem; transform: none; }
textarea.form-control-icon { padding-left: 2.5rem !important; }

[data-theme="dark"] .app-form-fieldset { background: var(--sx-dark-2); }
[data-theme="dark"] .app-form-fieldset-lang { background: var(--sx-dark-3); }

/* DataTables: ver components.css (sección "DATATABLES — toolbar, tabla y paginación") */

/* ======================================================
   CHARTS PAGES
   ====================================================== */
.sx-chart-card .card-body { padding: 1.25rem; }
.sx-chart-title {
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--sx-text-heading);
  margin-bottom: 0.25rem;
}
.sx-chart-subtitle { font-size: 0.78rem; color: var(--sx-text-muted); margin-bottom: 1rem; }

/* ======================================================
   WIDGETS PAGE
   ====================================================== */
/* Leaderboard */
.sx-leaderboard { list-style: none; padding: 0; }
.sx-leaderboard-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--sx-border-color);
}
.sx-leaderboard-item:last-child { border-bottom: none; }
.sx-leaderboard-rank {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--sx-body-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--sx-text-muted);
  flex-shrink: 0;
}
.sx-leaderboard-item:nth-child(1) .sx-leaderboard-rank { background: var(--sx-yellow-light); color: var(--sx-yellow-dark); }
.sx-leaderboard-item:nth-child(2) .sx-leaderboard-rank { background: var(--sx-sky-light); color: var(--sx-sky-dark); }
.sx-leaderboard-item:nth-child(3) .sx-leaderboard-rank { background: var(--sx-primary-light); color: var(--sx-primary); }

/* Timeline horario */
.sx-schedule-timeline { position: relative; padding-left: 1.5rem; }
.sx-schedule-timeline::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--sx-border-color);
}
.sx-schedule-item {
  position: relative;
  padding-bottom: 1.25rem;
}
.sx-schedule-item::before {
  content: '';
  position: absolute;
  left: -1.5rem;
  top: 0.25rem;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--sx-primary);
  border: 2px solid var(--sx-card-bg);
  box-shadow: 0 0 0 2px var(--sx-primary);
  transform: translateX(-4px);
}
.sx-schedule-time { font-size: 0.72rem; font-weight: 700; color: var(--sx-text-muted); margin-bottom: 0.2rem; }
.sx-schedule-class { font-size: 0.875rem; font-weight: 700; color: var(--sx-text-heading); }
.sx-schedule-room { font-size: 0.78rem; color: var(--sx-text-muted); }

/* Achievements grid */
.sx-achievements-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.75rem;
}
.sx-achievement-item {
  text-align: center;
  padding: 0.75rem 0.5rem;
  border-radius: var(--radius);
  background: var(--sx-body-bg);
}
.sx-achievement-icon {
  font-size: 1.75rem;
  margin-bottom: 0.35rem;
  display: block;
}
.sx-achievement-label { font-size: 0.68rem; font-weight: 700; color: var(--sx-text-muted); }
.sx-achievement-item.earned { background: var(--sx-primary-light); }
.sx-achievement-item.earned .sx-achievement-icon { color: var(--sx-primary); }
.sx-achievement-item.earned .sx-achievement-label { color: var(--sx-primary); }
.sx-achievement-item.locked { opacity: 0.4; filter: grayscale(1); }

/* ======================================================
   APPS - CALENDAR
   ====================================================== */
#fcWrap {
  background: var(--sx-card-bg);
  border: 1px solid var(--sx-border-color);
  border-radius: var(--radius-lg);
  overflow: visible;
}

/* Aquí vivía un `.fc .fc-scrollgrid { border: none !important }` que le quitaba
   el marco exterior a TODO calendario de la app. Tenía sentido cuando el
   calendario iba dentro de #fcWrap (arriba), que pone su propio borde y así se
   evitaba el doble marco — pero #fcWrap ya no existe en ningún markup (ver el
   comentario de courses.css:376, que documenta lo mismo). O sea que solo dejaba
   la rejilla abierta por fuera. Se quita para que cada calendario dibuje su
   marco completo; el de "Mis Cursos" mantiene el suyo sin borde con su propia
   regla (#crsCalMount, courses.css:389), que no depende de esta. */

.fc .fc-scrollgrid td,
.fc .fc-scrollgrid th {
  border-color: var(--sx-border-color) !important;
}

.fc .fc-scrollgrid td {
  height: 140px;
}

.fc .fc-scroller {
  overflow: visible !important;
}

#modalEvent .modal-dialog,
#modalEventDetail .modal-dialog {
  max-width: 560px;
}

#modalEventHeader,
#detailModalHeader {
  border-bottom: 0;
}

#modalEventHeader .modal-title,
#detailModalHeader .modal-title,
#detailModalHeader #detailEvTime {
  color: inherit;
}

/* ===========================================================================
   APARIENCIA (super-admin) — color pickers, file input y preview de logos.
   =========================================================================== */

/* Barra superior con el boton Guardar (sticky para que siempre se vea). */
.appearance-toolbar {
  position: sticky;
  top: 0;
  z-index: 5;
  padding: 0.5rem 0;
  background: var(--sx-body-bg, transparent);
}

/* Regla global de inputs de color (misma que Apariencia): swatch compacto
   dentro del input-group y SIN box-shadow. Aplica a TODOS los selectores de
   color del sistema, no solo a los de Apariencia (.js-color-picker). */
.input-group .form-control-color {
  width: 2.4rem;
  flex: 0 0 2.4rem;
  padding: 0.2rem;
  border-radius: 0; /* swatch en medio del grupo (icono · swatch · hex) */
}
.form-control-color,
.form-control-color:focus,
.form-control-color:focus-visible {
  box-shadow: none !important;
}

/* En focus se resalta TODO el grupo (icono + swatch + texto) con el MISMO gris
   de foco que ya usan los inputs (#bdbdbd), SIN glow/box-shadow ni naranja.
   Aplica a todos los input-group. */
.input-group:focus-within {
  border-radius: var(--radius-sm);
}
.input-group:focus-within .form-control,
.input-group:focus-within .form-control-color,
.input-group:focus-within .input-group-text {
  border-color: #bdbdbd;
}
.input-group .form-control:focus,
.input-group .form-control-color:focus,
.input-group .js-color-hex:focus,
.input-group .input-group-text:focus {
  box-shadow: none; /* el resaltado lo da el borde del grupo completo */
}

/* Input de archivo (choose file) redondeado, incluido su boton interno.
   Clase reutilizable .sx-file-input (la antigua .appearance-file se mantiene
   por compatibilidad y comparte el mismo estilo). */
.appearance-file.form-control,
.sx-file-input.form-control {
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.appearance-file.form-control::file-selector-button,
.sx-file-input.form-control::file-selector-button {
  border-radius: var(--radius-xs);
  border: 0;
  margin-inline-end: 0.65rem;
  background: var(--sx-primary-light);
  color: var(--sx-primary-dark);
  font-weight: 600;
  cursor: pointer;
}

/* Caja de preview de logos. */
.appearance-logo-box {
  min-height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.75rem;
  border: 1px solid var(--sx-border-color);
  border-radius: var(--radius-sm);
}
.appearance-logo-box img {
  max-height: 64px;
  max-width: 100%;
}
/* Logo blanco -> fondo oscuro para contraste. */
.appearance-logo-box--dark {
  background: var(--sx-dark, #302f3b);
  border-color: transparent;
}
/* Logo "a color" que en realidad es blanco -> fondo tipo damero para que se vea. */
.appearance-logo-box--check {
  background-color: #e9ecf2;
  background-image:
    linear-gradient(45deg, #c9cedb 25%, transparent 25%),
    linear-gradient(-45deg, #c9cedb 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #c9cedb 75%),
    linear-gradient(-45deg, transparent 75%, #c9cedb 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
[data-theme="dark"] .appearance-logo-box--check {
  background-color: #3a3947;
  background-image:
    linear-gradient(45deg, #2d2c38 25%, transparent 25%),
    linear-gradient(-45deg, #2d2c38 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #2d2c38 75%),
    linear-gradient(-45deg, transparent 75%, #2d2c38 75%);
}

/* ============================================================
   Detalle de log (admin/log-details.php) — patrón "ticket details"
   ============================================================ */
.ld-info-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding: .55rem 0; border-bottom: 1px solid var(--sx-border-color); font-size: .83rem; }
.ld-info-row:last-child { border-bottom: 0; }
.ld-info-label { color: var(--sx-text-muted); white-space: nowrap; }
.ld-info-value { font-weight: 600; color: var(--sx-text-heading); text-align: right; word-break: break-word; }
.ld-json { background: var(--sx-bg-subtle, #f5f5f7); border: 1px solid var(--sx-border-color); border-radius: var(--radius-sm, .5rem); padding: .75rem 1rem; font-size: .8rem; white-space: pre-wrap; word-break: break-word; margin: 0; }
.ld-diff td, .ld-diff th { vertical-align: top; }
.ld-diff .ld-old { color: var(--sx-danger, #c0392b); }
.ld-diff .ld-new { color: var(--sx-success, #1e7e34); }

/* ===========================================================================
   Wizard de creación de escuela (admin/school-wizard.php)
   Stepper horizontal: badge numerado + etiqueta. Estados: activo / completado.
   =========================================================================== */
.sx-wizard-steps { margin: 0; padding: 0; }
.sx-wizard-step {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--sx-border-color);
  border-radius: var(--radius-pill, 999px);
  background: var(--sx-bg-subtle, #f5f5f7);
  color: var(--sx-text-muted);
  font-size: 0.85rem;
  cursor: default;
  transition: var(--transition-fast, all .15s ease);
}
.sx-wizard-step__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6em;
  height: 1.6em;
  border-radius: 50%;
  background: var(--sx-text-muted);
  color: #fff;
  font-size: 0.8rem;
  flex: 0 0 auto;
}
/* Texto opcional: etiqueta + pequeña descripción apiladas. */
.sx-wizard-step__text { display: inline-flex; flex-direction: column; align-items: flex-start; text-align: left; line-height: 1.15; }
.sx-wizard-step__desc { font-size: 0.7rem; font-weight: 400; opacity: 0.72; }
.sx-wizard-step.is-active {
  border-color: var(--sx-primary);
  background: var(--sx-primary-light);
  color: var(--sx-primary-dark);
  font-weight: 600;
}
.sx-wizard-step.is-active .sx-wizard-step__badge { background: var(--sx-primary); }
.sx-wizard-step.is-done {
  border-color: var(--sx-success);
  color: var(--sx-success-dark);
  cursor: pointer;
}
.sx-wizard-step.is-done .sx-wizard-step__badge { background: var(--sx-success); }

/* ===========================================================================
   Selector de iconos (sx-icon-picker.js): grilla dentro del modal compartido.
   =========================================================================== */
.sx-icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr));
  gap: 0.4rem;
}
.sx-icon-grid-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--sx-border-color);
  border-radius: var(--radius-sm, 8px);
  background: var(--sx-surface, #fff);
  color: var(--sx-text-body);
  font-size: 1.15rem;
  cursor: pointer;
  transition: var(--transition-fast, all .12s ease);
}
.sx-icon-grid-cell:hover {
  border-color: var(--sx-primary);
  background: var(--sx-primary-light);
  color: var(--sx-primary-dark);
}
.sx-icon-grid-cell.is-selected {
  border-color: var(--sx-primary);
  background: var(--sx-primary);
  color: #fff;
}
/* Botón "examinar" del campo de icono. */
.sx-icon-pick-btn { display: inline-flex; align-items: center; }

/* ===========================================================================
   Autocompletado de iconos (sx-icon-autocomplete.js): desplegable typeahead.
   =========================================================================== */
.sx-icon-field { position: relative; }
.sx-icon-ac-menu {
  position: fixed;       /* montado en <body>; coordenadas vía JS */
  z-index: 1085;         /* sobre el modal (1055) y su backdrop */
  max-height: 16rem;
  overflow-y: auto;
  padding: 0.25rem;
  background: var(--sx-surface, #fff);
  border: 1px solid var(--sx-border-color);
  border-radius: var(--radius-sm, 8px);
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.12);
}
.sx-icon-ac-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 0;
  border-radius: var(--radius-sm, 8px);
  background: transparent;
  color: var(--sx-text-body);
  font-size: 0.9rem;
  text-align: left;
  cursor: pointer;
}
.sx-icon-ac-item > i { font-size: 1.15rem; line-height: 1; width: 1.4rem; text-align: center; }
.sx-icon-ac-item:hover,
.sx-icon-ac-item.is-active {
  background: var(--sx-primary-light);
  color: var(--sx-primary-dark);
}
.sx-icon-ac-empty {
  padding: 0.5rem 0.6rem;
  color: var(--sx-text-muted);
  font-size: 0.85rem;
}
/* Botón "x" para limpiar el campo de icono (lo crea sx-icon-autocomplete.js). */
.sx-icon-ac-has-clear { padding-right: 2.2rem !important; }
.sx-icon-ac-clear {
  position: absolute;
  top: 50%;
  right: 0.55rem;
  transform: translateY(-50%);
  display: none; /* el JS lo pone en 'flex' cuando hay valor */
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--sx-text-muted);
  font-size: 0.75rem;
  line-height: 1;
  cursor: pointer;
  z-index: 6;
  transition: var(--transition-fast, all .12s ease);
}
.sx-icon-ac-clear:hover {
  background: var(--sx-primary-light);
  color: var(--sx-primary-dark);
}

/* ===========================================================================
   Estilos movidos desde public/app/students-create.php (regla: nada de <style> inline)
   =========================================================================== */
/* El stepper horizontal es el componente OFICIAL del sistema (.sx-wizard-step
   en pages.css, igual que admin/school-wizard). Aquí solo van estilos propios. */
.sx-guardian-card { border:1px solid var(--sx-border-color); border-radius:var(--radius, .6rem); padding:1rem; margin-bottom:1rem; }
.sx-guardian-card .sx-guardian-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:.75rem; }
.sx-review-grid dt { font-weight:600; color:var(--sx-text-heading, #302f3b); }
.sx-review-grid dd { margin-bottom:.4rem; }
/* Radios sin marcar: círculo gris neutro (claro que no hay selección). */
#wBapYes:not(:checked), #wBapNo:not(:checked) { background-color:#fff; border-color:var(--sx-text-muted); }

/* ===========================================================================
   Estilos movidos desde public/app/chat.php (regla: nada de <style> inline)
   =========================================================================== */
.sx-chat { overflow: hidden; }
.sx-chat__row { min-height: 70vh; }
.sx-chat__aside { display: flex; flex-direction: column; }
.sx-chat__conv-list { overflow-y: auto; flex: 1 1 auto; }
.sx-chat__conv-item { display: flex; align-items: center; width: 100%; border-bottom: 1px solid var(--sx-border-color); }
.sx-chat__conv-item:hover { background: var(--sx-row-hover); }
.sx-chat__conv-item.active { background: rgba(var(--sx-primary-rgb), .12); }
.sx-chat__conv-open { display: flex; gap: .65rem; align-items: center; flex: 1 1 auto; min-width: 0; padding: .65rem .85rem; border: 0; background: transparent; text-align: start; cursor: pointer; }
.sx-chat__conv-del { flex: 0 0 auto; border: 0; background: transparent; color: var(--sx-text-muted); padding: .35rem .55rem; margin-right: .25rem; border-radius: var(--radius-sm, .4rem); opacity: 0; cursor: pointer; transition: var(--transition); }
.sx-chat__conv-item:hover .sx-chat__conv-del { opacity: 1; }
.sx-chat__conv-del:hover { color: var(--sx-danger); background: rgba(var(--sx-danger-rgb), .12); }
.sx-chat__peer-avatar { width: 40px; height: 40px; border-radius: 50%; flex: 0 0 40px; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: .85rem; color: #fff; background: var(--sx-primary); text-transform: uppercase; }
.sx-chat__conv-body { min-width: 0; flex: 1 1 auto; }
.sx-chat__conv-name { font-weight: 600; }
.sx-chat__conv-last { font-size: .8rem; }
.sx-chat__unread-badge { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--sx-primary, #4361ee); color: #fff; font-size: .72rem; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; }
.sx-chat__main { min-height: 70vh; }
.sx-chat__messages { overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: .4rem; background: var(--bs-body-bg, #fff); }
.sx-chat__bubble-row { display: flex; flex-direction: column; align-items: flex-start; }
.sx-chat__bubble-row.mine { align-items: flex-end; }
.sx-chat__bubble { max-width: 75%; padding: .5rem .75rem; border-radius: 14px; background: var(--bs-tertiary-bg, #f1f3f5); }
.sx-chat__bubble-row.mine .sx-chat__bubble { background: var(--sx-primary-light); color: var(--sx-text-heading); border-bottom-right-radius: 4px; }
.sx-chat__bubble-row:not(.mine) .sx-chat__bubble { border-bottom-left-radius: 4px; }
.sx-chat__bubble-sender { font-size: .72rem; font-weight: 600; opacity: .8; margin-bottom: 2px; }
.sx-chat__bubble-text { white-space: pre-wrap; word-wrap: break-word; overflow-wrap: anywhere; }
.sx-chat__bubble-meta { display: flex; align-items: center; gap: .35rem; margin: 2px 4px 0; }
.sx-chat__bubble-row.mine .sx-chat__bubble-meta { flex-direction: row-reverse; }
.sx-chat__bubble-time { font-size: .66rem; color: var(--sx-text-muted); }
.sx-chat__bubble-actions { display: flex; gap: .1rem; opacity: 0; transition: var(--transition); }
.sx-chat__bubble-row.mine:hover .sx-chat__bubble-actions { opacity: 1; }
.sx-chat__bubble-action { border: 0; background: transparent; color: var(--sx-text-muted); padding: .15rem .3rem; border-radius: var(--radius-sm, .4rem); cursor: pointer; font-size: .72rem; line-height: 1; }
.sx-chat__bubble-action:hover { background: var(--sx-row-hover); color: var(--sx-text-heading); }
.sx-chat__bubble-action--danger:hover { color: var(--sx-danger); background: rgba(var(--sx-danger-rgb), .12); }
.sx-chat__bubble-edit-form { display: flex; flex-direction: column; gap: .3rem; min-width: 180px; }
.sx-chat__bubble-edit-form textarea { resize: none; border: 1px solid var(--sx-border-color); border-radius: var(--radius-sm, .4rem); padding: .35rem .5rem; font: inherit; background: var(--sx-card-bg); color: var(--sx-text-body); }
.sx-chat__bubble-edit-actions { display: flex; gap: .25rem; justify-content: flex-end; }
.sx-chat__contact-item { display: flex; gap: .65rem; align-items: center; width: 100%; padding: .55rem .65rem; border: 0; background: transparent; text-align: start; border-radius: .5rem; cursor: pointer; }
.sx-chat__contact-item:hover { background: var(--bs-tertiary-bg, #f5f6f8); }
.sx-chat__contact-list { max-height: 45vh; overflow-y: auto; }
#chatInput { resize: none; min-height: 0; max-height: 140px; overflow-y: hidden; }
/* Adjuntos del chat (imágenes inline + chip descargable). */
.sx-chat__att-img { display: block; margin-top: .35rem; max-width: 220px; }
.sx-chat__att-img img { max-width: 100%; border-radius: 10px; display: block; }
.sx-chat__att-file { display: flex; align-items: center; gap: .5rem; margin-top: .35rem; padding: .5rem .65rem; border-radius: 10px; background: var(--sx-card-bg); border: 1px solid var(--sx-border-color); color: var(--sx-text-body); text-decoration: none; max-width: 260px; }
.sx-chat__att-file:hover { background: var(--sx-row-hover); }
.sx-chat__att-file > i { font-size: 1.2rem; color: var(--sx-primary); }
.sx-chat__att-meta { display: flex; flex-direction: column; min-width: 0; }
.sx-chat__att-name { font-size: .8rem; font-weight: 600; }
.sx-chat__att-size { font-size: .7rem; color: var(--sx-text-muted); }
.sx-chat__typing { font-style: italic; }
/* Progreso de subida DENTRO de la burbuja que se envía (solo quien envía). */
.sx-chat__att-up { margin-top: .35rem; min-width: 160px; }
.sx-chat__att-up-name { font-size: .75rem; color: var(--sx-text-muted); margin-bottom: .3rem; }
.sx-chat__upload-bar { height: 6px; border-radius: 3px; background: var(--sx-border-color); overflow: hidden; }
.sx-chat__upload-fill { height: 100%; width: 0; background: var(--sx-primary); border-radius: 3px; transition: width .15s ease; }
/* Imagen adjunta clicable (abre modal). */
.sx-chat__att-img { cursor: zoom-in; }
.sx-chat__img-modal-img { max-width: 100%; max-height: 80vh; border-radius: var(--radius); display: block; margin: 0 auto; }
/* Panel de emojis. */
.sx-chat__emoji-panel { position: absolute; bottom: calc(100% + .4rem); left: 0; z-index: 20; width: 264px; max-height: 200px; overflow-y: auto; display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; padding: .5rem; background: var(--sx-card-bg); border: 1px solid var(--sx-border-color); border-radius: var(--radius); box-shadow: var(--shadow-lg); }
.sx-chat__emoji { border: 0; background: transparent; font-size: 1.25rem; line-height: 1; padding: .25rem; border-radius: var(--radius-sm, .4rem); cursor: pointer; }
.sx-chat__emoji:hover { background: var(--sx-row-hover); }
@media (max-width: 767.98px) {
  .sx-chat__aside.is-hidden { display: none; }
  .sx-chat__main.is-hidden { display: none !important; }
}

/* Transcripción: vista HTML — DISEÑO WEB EDUCATIVO (distinto al PDF). */
.sx-transcript-scroll { max-height: 78vh; overflow-y: auto; background: var(--sx-body-bg); border-radius: var(--radius); padding: 1.25rem; }
.sx-tr-doc { display: flex; flex-direction: column; gap: 1.5rem; }
.sx-tr {
  background: var(--sx-card-bg);
  border: 1px solid var(--sx-border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  max-width: 860px;
  margin: 0 auto;
  width: 100%;
  padding: 1.5rem 1.75rem;
  color: var(--sx-text-body);
}
/* Banda del estudiante (encabezado del preview) */
.sx-tr__student { display: flex; align-items: center; gap: 1rem; }
.sx-tr__avatar { width: 52px; height: 52px; font-size: 1.1rem; }
.sx-tr__name { font-size: 1.15rem; font-weight: 700; color: var(--sx-text-heading); }
.sx-tr__chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .35rem; }
.sx-tr__chip { background: var(--sx-body-bg); border: 1px solid var(--sx-border-color); color: var(--sx-text-body); font-size: .74rem; font-weight: 600; padding: .15rem .55rem; border-radius: var(--radius-pill); }
.sx-tr__pill { margin-left: auto; align-self: flex-start; background: var(--sx-primary); color: #fff; font-size: .72rem; font-weight: 700; letter-spacing: .3px; padding: .35rem .75rem; border-radius: var(--radius-pill); white-space: nowrap; }
/* Stat tiles */
.sx-tr__stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: .75rem; margin: 1.2rem 0; }
.sx-tr__stat { background: var(--sx-body-bg); border: 1px solid var(--sx-border-color); border-radius: var(--radius); padding: .8rem 1rem; text-align: center; }
.sx-tr__stat:first-child { background: rgba(var(--sx-primary-rgb), .10); border-color: rgba(var(--sx-primary-rgb), .35); }
.sx-tr__stat-val { font-family: var(--font-display); font-size: 1.5rem; font-weight: 700; color: var(--sx-text-heading); line-height: 1; }
.sx-tr__stat:first-child .sx-tr__stat-val { color: var(--sx-primary); }
.sx-tr__stat-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .4px; color: var(--sx-text-muted); margin-top: .3rem; }
/* Año */
.sx-tr__year { margin-top: 1.1rem; }
.sx-tr__year-head { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: .5rem; }
.sx-tr__year-title { font-size: .95rem; font-weight: 700; color: var(--sx-text-heading); }
.sx-tr__year-grade { font-size: .76rem; color: var(--sx-text-muted); }
.sx-tr__year-gpa { margin-left: auto; background: rgba(var(--sx-primary-rgb), .12); color: var(--sx-primary); font-size: .74rem; font-weight: 700; padding: .15rem .6rem; border-radius: var(--radius-pill); }
.sx-tr__table { width: 100%; border-collapse: collapse; }
.sx-tr__table thead th { text-align: left; font-size: .66rem; text-transform: uppercase; letter-spacing: .4px; color: var(--sx-text-muted); font-weight: 700; padding: .35rem .6rem; border-bottom: 2px solid var(--sx-border-color); }
.sx-tr__table thead th:nth-child(n+2), .sx-tr__table tbody td:nth-child(n+2) { text-align: center; }
.sx-tr__table tbody td { font-size: .84rem; color: var(--sx-text-body); padding: .4rem .6rem; border-bottom: 1px solid var(--sx-border-color); }
.sx-tr__table tbody tr:nth-child(even) td { background: rgba(var(--sx-dark-rgb), .02); }
.sx-tr__cls { font-weight: 600; color: var(--sx-text-heading); }
.sx-tr__flag { font-size: .68rem; font-weight: 600; font-style: italic; color: var(--sx-text-muted); }
.sx-tr__dash { color: var(--sx-text-muted); }
.sx-tr__year-foot { display: flex; flex-wrap: wrap; gap: .35rem 1.25rem; margin-top: .5rem; font-size: .78rem; color: var(--sx-text-body); }
.sx-tr__year-foot b { color: var(--sx-text-heading); }
.sx-tr__none { color: var(--sx-text-muted); font-style: italic; padding: 1rem 0; }

/* Tarjeta Acumulativa: rejilla de datos biográficos (reusa .sx-tr* para todo
   lo demás — bandas, stat tiles y tablas por año ya son genéricas). */
.sx-cr-section-title { font-size: .95rem; font-weight: 700; color: var(--sx-text-heading); margin: 1.3rem 0 .5rem; padding-bottom: .35rem; border-bottom: 2px solid var(--sx-border-color); }
.sx-cr-info { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: .75rem 1.25rem; margin: .75rem 0; }
.sx-cr-info__k { font-size: .68rem; text-transform: uppercase; letter-spacing: .4px; color: var(--sx-text-muted); }
.sx-cr-info__v { font-size: .88rem; font-weight: 600; color: var(--sx-text-heading); margin-top: .15rem; }
.sx-cr-conduct__cell, .sx-cr-comment__cell, .sx-cr-tests__cell { cursor: pointer; }
.sx-cr-conduct__cell:hover, .sx-cr-comment__cell:hover, .sx-cr-tests__cell:hover { background: rgba(var(--sx-primary-rgb), .06); }

/* Estado vacío de la transcripción (llamativo, de marca). */
.sx-transcript-empty { text-align: center; padding: 3.5rem 1.5rem; }
.sx-transcript-empty__icon { width: 84px; height: 84px; margin: 0 auto 1.25rem; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: rgba(var(--sx-primary-rgb), .12); color: var(--sx-primary); font-size: 2.4rem; }
.sx-transcript-empty__title { font-size: 1.05rem; font-weight: 700; color: var(--sx-text-heading); margin-bottom: .35rem; }
.sx-transcript-empty__hint { color: var(--sx-text-muted); max-width: 360px; margin: 0 auto; font-size: .9rem; }

/* ===========================================================================
   Collapsible Table — BASE COMPARTIDA
   Movido desde: public/admin/{grading,modules,standards,geo,evaluations,
   lookups,planning}.php (todas tenían este mismo bloque <style> inline).
   Se consolida UNA sola vez; abajo van solo los deltas por página.
   =========================================================================== */
.sx-lvl { width: 100%; margin-bottom: 0; vertical-align: middle; }
.sx-lvl > thead > tr > th { font-size: .8rem; text-transform: uppercase; letter-spacing: .02em; white-space: nowrap; }
.sx-lvl > tbody > tr > td { vertical-align: middle; }

/* ===========================================================================
   TABLA A RAS DEL CARD — para las tablas que NO son DataTables.
   ===========================================================================
   Regla del sistema (design-system-css #11): una tabla de datos va a ras de su
   card. Las DataTables ya lo consiguen con .sx-att-card. Las demás —las
   colapsables de nivel y las que se pintan a mano (gradebook, rúbricas,
   resultados…)— se quedaban metidas 1.25rem por el padding del card-body.

   POR QUÉ :has() Y NO UNA CLASE: el selector describe la condición real —"un
   card-body cuyo HIJO DIRECTO es el envoltorio de una tabla"— así que no hay que
   acordarse de poner una clase en la próxima página. Ya se usaba en courses.css.

   EL `> >` ES EL FILTRO, y no es casual:
     - DataTables NO matchea: su bootstrap5 crea su propio wrapper anidado
       (.dataTables_wrapper > .row > .col > .table-responsive), así que su
       .table-responsive no es hijo directo del card-body. Su tratamiento sigue
       siendo .sx-att-card, y este selector no lo pisa.
     - Las tablas ANIDADAS de los árboles tampoco: viven dentro de
       .sx-detail-inner y conservan su indentación.
     - Los widgets de dashboard con tablita dentro de una columna tampoco: ahí el
       padding del card es el correcto.
   =========================================================================== */
.card-body:has(> .table-responsive:not(.sx-table-flush) > .table) { padding: 0; }
/* Lo que convive con la tabla dentro de ese card-body necesita su propio aire,
   ahora que el card ya no lo pone. Mismo .85rem/1rem que usa .sx-att-card para las
   filas de controles de DataTables: es lo que las alinea con las celdas. */
.card-body:has(> .table-responsive:not(.sx-table-flush) > .table) > .sx-lvl-top { padding: .85rem 1rem; }
.card-body:has(> .table-responsive:not(.sx-table-flush) > .table) > .sx-pager { padding: 0 1rem .85rem; margin-top: .75rem; }
/* El estado vacío y los estados de carga/error que comparten card-body con la
   tabla: sin el padding del card se pegarían a los bordes. */
.card-body:has(> .table-responsive:not(.sx-table-flush) > .table) > .sx-transcript-empty { padding-inline: 1.5rem; }
.card-body:has(> .table-responsive:not(.sx-table-flush) > .table) > .sx-state { padding: .75rem 1rem; }

/* ---------------------------------------------------------------------------
   .sx-table-flush — tabla a ras cuando el card-body SÍ conserva su padding.
   ---------------------------------------------------------------------------
   El caso de admin/promotion-rules: el card-body tiene contenido mixto (un texto
   introductorio, un formulario Y la tabla). Quitarle el padding pegaría el texto y
   los campos a los bordes, así que la regla de arriba —que anula el padding
   entero— no sirve, y por eso su `> >` no la alcanzaba.

   Aquí solo la TABLA se estira hasta los bordes, cancelando el padding con un
   margen negativo del tamaño exacto. Ese tamaño sale de --sx-card-pad, que declara
   el propio .card-body (components.css): repetir aquí un 1.25rem literal sería
   dejar dos números que divergen en cuanto alguien toque uno.

   Va en el .table-responsive, no en la <table>: así la tabla conserva su scroll
   horizontal propio y no desborda el card cuando es ancha.

   EXCLUYENTE CON LA REGLA DE ARRIBA, y no es teórico: si un .sx-table-flush cayera
   como hijo directo del card-body, dispararían LAS DOS —el :has() dejaría el
   padding en 0 y encima el margen negativo restaría otros 20px— y la tabla se
   saldría del card. Medido: -19px por lado. De ahí el :not(.sx-table-flush) del
   selector de arriba: donde una manda, la otra se calla.
   --------------------------------------------------------------------------- */
.sx-table-flush {
  margin-inline: calc(var(--sx-card-pad, 1.25rem) * -1);
  /* El ancho lo resuelve el margen negativo sobre un bloque; width:auto evita que
     un w-100 heredado lo fije al ancho viejo. */
  width: auto;
}
/* Las celdas recuperan el aire lateral que daba el card: mismo 1rem que el resto
   de tablas a ras del sistema (ver .sx-att-card). */
.sx-table-flush > .table > thead > tr > th:first-child,
.sx-table-flush > .table > tbody > tr > td:first-child { padding-inline-start: 1rem; }
.sx-table-flush > .table > thead > tr > th:last-child,
.sx-table-flush > .table > tbody > tr > td:last-child { padding-inline-end: 1rem; }

/* Celda-toggle (chevron) y celda-acciones, compactas. */
.sx-col-toggle { width: 2.25rem; text-align: center; }
.sx-col-actions { width: 1%; white-space: nowrap; text-align: start; }
.sx-col-status  { width: 1%; white-space: nowrap; text-align: start; }
.sx-toggle { background: none; border: 0; padding: 0; width: 1.25rem; line-height: 1; color: var(--sx-text-muted); }
.sx-toggle.is-leaf { visibility: hidden; }
.sx-row-code { font-weight: 600; white-space: nowrap; }
.sx-actions { display: inline-flex; gap: .25rem; }

/* Fila-detalle: contiene la tabla anidada del nivel hijo. */
.sx-detail > td { padding: 0; border-top: 0; }
.sx-detail-inner { padding: .5rem .5rem .75rem 1.75rem; }

.sx-state { padding: .75rem 1rem; color: var(--sx-text-muted); }

/* Barra de herramientas de cada tabla anidada (título + botón "Añadir"). */
.sx-lvl-toolbar { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .25rem .25rem .5rem; }
.sx-lvl-toolbar .sx-lvl-title { font-size: .8rem; font-weight: 600; text-transform: uppercase; letter-spacing: .02em; margin: 0; }

/* Cabecera colapsable por estudiante (Materias por estudiante, modo grupo). */
.sc-stu-toggle { cursor: pointer; }
.sc-stu-toggle .sc-chevron { transition: transform .2s ease; }
.sc-stu-toggle[aria-expanded="true"] .sc-chevron { transform: rotate(90deg); }

/* Controles del nivel raíz, con la MISMA maqueta que DataTables:
 *
 *   .sx-lvl-top   [Mostrar N ▾]                    [Buscar…]
 *                 ┌──────────── tabla ────────────┐
 *   .sx-pager     [Mostrando 1 a 3 de 3]      [‹ 1 2 3 ›]
 *
 * Los dos son flex con space-between, así que el primer hijo cae a la izquierda y
 * el último a la derecha — igual que .dataTables_length/.dataTables_filter y
 * .dataTables_info/.dataTables_paginate. El padding lateral es 1rem: el mismo que
 * el de las celdas de la tabla (ver .sx-att-card), para que el selector, el
 * buscador, la info y la primera columna caigan en la misma línea vertical. */
.sx-lvl-top { display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap; }
.sx-lvl-top__search { width: 100%; max-width: 20rem; }
.sx-pager { display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap; margin-top: .75rem; }
.sx-pager .pagination { flex-wrap: wrap; }
/* Si el selector de largo se oculta (tabla vacía), el buscador no debe saltar a la
   izquierda: el hueco se mantiene. */
.sx-lvl-top > .d-none + .sx-lvl-top__search { margin-inline-start: auto; }

/* Tinte del nivel "item" (solo evaluations.php: sus niveles Item y Niveles).
   Va en success porque las dos tablas que acompaña —sx-lvl-item y sx-lvl-level—
   son success: el título salía azul sobre una tabla verde. Antes lo compartía con
   planning.php, que sí quería info, y por eso estaba mal para uno de los dos;
   planning ya tiene el suyo (sx-tint-plan-item). */
.sx-lvl-toolbar.sx-tint-item .sx-lvl-title { color: var(--sx-success-dark); }

/* ===========================================================================
   Estilos movidos desde public/admin/grading.php (regla: nada de <style> inline)
   Solo delta: niveles Escala -> primary, Banda -> info. (Base compartida arriba.)
   =========================================================================== */
.sx-lvl-scale > thead > tr > th { background: var(--sx-body-bg); color: var(--sx-text-muted); }
.sx-lvl-band > thead > tr > th { background: var(--sx-info-light); color: var(--sx-info-dark); }
.sx-lvl-toolbar.sx-tint-band .sx-lvl-title { color: var(--sx-info-dark); }

/* ===========================================================================
   Estilos movidos desde public/admin/modules.php (regla: nada de <style> inline)
   Solo delta: Módulo -> primary, Funcionalidad -> info. (Base compartida arriba.)
   =========================================================================== */
.sx-col-default { width: 1%; white-space: nowrap; text-align: start; }
.sx-lvl-module   > thead > tr > th { background: var(--sx-body-bg); color: var(--sx-text-muted); }
.sx-lvl-feature  > thead > tr > th { background: var(--sx-info-light); color: var(--sx-info-dark); }
.sx-lvl-toolbar.sx-tint-feature .sx-lvl-title { color: var(--sx-info-dark); }

/* ===========================================================================
   Estilos movidos desde public/admin/standards.php (regla: nada de <style> inline)
   Solo delta: Estándar -> primary, Expectativa -> info, Indicador -> success.
   =========================================================================== */
.sx-lvl-standard   > thead > tr > th { background: var(--sx-body-bg); color: var(--sx-text-muted); }
.sx-lvl-expectation > thead > tr > th { background: var(--sx-info-light); color: var(--sx-info-dark); }
.sx-lvl-indicator  > thead > tr > th { background: var(--sx-success-light); color: var(--sx-success-dark); }
.sx-lvl-toolbar.sx-tint-expectation .sx-lvl-title { color: var(--sx-info-dark); }
.sx-lvl-toolbar.sx-tint-indicator  .sx-lvl-title { color: var(--sx-success-dark); }

/* ===========================================================================
   Estilos movidos desde public/admin/geo.php (regla: nada de <style> inline)
   Solo delta: País -> primary, Ciudades -> info. (Base compartida arriba.)
   =========================================================================== */
.sx-col-count   { width: 1%; white-space: nowrap; text-align: start; }
.sx-row-name { font-weight: 600; }
.sx-lvl-country > thead > tr > th { background: var(--sx-body-bg); color: var(--sx-text-muted); }
.sx-lvl-city > thead > tr > th { background: var(--sx-info-light); color: var(--sx-info-dark); }
.sx-lvl-toolbar.sx-tint-city .sx-lvl-title { color: var(--sx-info-dark); }

/* ===========================================================================
   Estilos movidos desde public/admin/evaluations.php (regla: nada de <style> inline)
   Delta: Instrumento/Sección/Item + pestaña Escalas (Escala/Opciones/Niveles).
   =========================================================================== */
.sx-lvl-instrument > thead > tr > th { background: var(--sx-body-bg); color: var(--sx-text-muted); }
.sx-lvl-section > thead > tr > th { background: var(--sx-info-light); color: var(--sx-info-dark); }
.sx-lvl-item > thead > tr > th { background: var(--sx-success-light); color: var(--sx-success-dark); }
/* Pestaña Escalas: Escala -> primary; Opciones -> info; Niveles -> success.
   Reutiliza los tintes -section (info) y -item (success) porque aquí valen por su
   COLOR, no por la entidad: "Opciones" toma el tinte info y "Niveles" el success.
   sx-lvl-scale lo define el bloque de grading.php: misma clase, misma página raíz
   y mismos valores. Estaba duplicada aquí, palabra por palabra. */
.sx-lvl-option > thead > tr > th { background: var(--sx-info-light); color: var(--sx-info-dark); }
.sx-lvl-level  > thead > tr > th { background: var(--sx-success-light); color: var(--sx-success-dark); }
/* Apila las dos tablas hijas (Opciones / Niveles) con separación. */
.sx-scale-child + .sx-scale-child { margin-top: 1rem; }
.sx-lvl-toolbar.sx-tint-section .sx-lvl-title { color: var(--sx-info-dark); }

/* ===========================================================================
   Estilos movidos desde public/admin/lookups.php (regla: nada de <style> inline)
   Solo delta: Tipo -> primary, Valor -> info, + chip de color del valor.
   =========================================================================== */
.sx-lvl-type  > thead > tr > th { background: var(--sx-body-bg); color: var(--sx-text-muted); }
.sx-lvl-value > thead > tr > th { background: var(--sx-info-light); color: var(--sx-info-dark); }
.sx-lvl-toolbar.sx-tint-value .sx-lvl-title { color: var(--sx-info-dark); }
/* Chip de color del valor. */
.sx-color-chip { display: inline-flex; align-items: center; gap: .35rem; }
.sx-color-dot { display: inline-block; width: 14px; height: 14px; border-radius: 50%; border: 1px solid var(--sx-border-color); }

/* ===========================================================================
   Estilos movidos desde public/admin/planning.php (regla: nada de <style> inline)
   Delta: Sección -> primary (raíz), Ítem -> info.

   NOMBRES PROPIOS (sx-lvl-plan-*), y no es cosmético: esta página llamaba a sus
   niveles sx-lvl-section y sx-lvl-item, los MISMOS nombres que usa
   evaluations.php — pero con otro significado. Aquí "section" es la RAÍZ (gris +
   borde primary); allí es un nivel HIJO (info). Como este bloque va después,
   ganaba, y evaluations renderizaba su "Sección" en gris con un borde de más y su
   "Item" en azul en vez de verde. Misma especificidad, decide el orden del
   archivo: una colisión silenciosa que solo se ve mirando la pantalla.
   =========================================================================== */
.sx-col-icon    { width: 1%; white-space: nowrap; text-align: start; }
.sx-col-sort    { width: 1%; white-space: nowrap; text-align: center; }
.sx-lvl-plan-section > thead > tr > th { background: var(--sx-body-bg); color: var(--sx-text-muted); }
.sx-lvl-plan-item > thead > tr > th { background: var(--sx-info-light); color: var(--sx-info-dark); }
.sx-lvl-toolbar.sx-tint-plan-item .sx-lvl-title { color: var(--sx-info-dark); }

/* ===========================================================================
   Estilos movidos desde public/admin/billing-invoice.php (regla: nada de <style> inline)
   =========================================================================== */
/* Toggle minimalista $ / % del descuento (sin azul de Bootstrap). */
.sx-disc-toggle { display: inline-flex; }
.sx-disc-toggle .btn-check + .sx-disc-btn {
  border: 1px solid var(--sx-primary);
  color: var(--sx-primary);
  background: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  padding: 0;
  line-height: 1.6;
  --bs-btn-focus-shadow-rgb: var(--sx-primary-rgb);
}
.sx-disc-toggle .sx-disc-btn:first-of-type { border-top-left-radius: .375rem; border-bottom-left-radius: .375rem; }
.sx-disc-toggle .sx-disc-btn:last-of-type  { border-top-right-radius: .375rem; border-bottom-right-radius: .375rem; border-left: 0; }
.sx-disc-toggle .btn-check:checked + .sx-disc-btn {
  background: var(--sx-primary);
  border-color: var(--sx-primary);
  color: #fff;
}
.sx-disc-toggle .btn-check:focus-visible + .sx-disc-btn {
  box-shadow: 0 0 0 .2rem rgba(var(--sx-primary-rgb), .35);
}
/* Total en color primario del theme. */
#totTotal { color: var(--sx-primary) !important; font-family: var(--font-body); }
/* Boton agregar producto: icono solo, paleta (nunca azul). */
#btnAddItem { white-space: nowrap; }
/* Checkboxes de la tabla de items: todos del mismo tamaño. */
#itemsBody .form-check-input,
#itemsSelectAll {
  width: 1rem;
  height: 1rem;
  margin: 0;
  vertical-align: middle;
}
/* Alertas de la seccion de ítems (vacío + confirmación de borrado): layout flex
   SIN !important. Bootstrap `.d-flex` es `display:flex !important` y ganaría sobre
   el `display:none` inline que pone jQuery .hide(), dejando las alertas SIEMPRE
   visibles. Con esta clase propia, .show()/.hide() funcionan correctamente. */
.sx-items-alert { display: flex; align-items: center; flex-wrap: wrap; }
.sx-items-alert.sx-items-between { justify-content: space-between; }
/* Cantidad editable en linea: el input se ve como texto plano hasta que
   recibe foco/hover; ahi aparece el borde y el fondo para "activarlo". */
.sx-qty-input {
  width: 4.5rem;
  text-align: right;
  font: inherit;
  color: inherit;
  border: 1px solid transparent;
  background: transparent;
  border-radius: .375rem;
  padding: .15rem .4rem;
  cursor: pointer;
  -moz-appearance: textfield;
}
.sx-qty-input::-webkit-outer-spin-button,
.sx-qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.sx-qty-input:hover { border-color: var(--bs-border-color, #dee2e6); }
.sx-qty-input:focus {
  cursor: text;
  background: var(--bs-body-bg, #fff);
  outline: none;
}
/* Precio unitario editable: un poco mas ancho y con prefijo $ pegado al numero. */
.sx-price-input { width: 6rem; }
.sx-price-prefix { color: inherit; }

/* ============================================================
   Autosave indicator (sx-autosave.js) — borrador/publicado.
   Indicador discreto en el footer del modal; el icono de "saving"
   gira con .sx-spin. Clases scopeadas (prefijo sx-), sin elementos
   desnudos, segun UI_CONVENTIONS §15.
   ============================================================ */
.sx-autosave-indicator {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 1.25rem;
  line-height: 1.25;
}
.sx-autosave-indicator:empty { display: none; }
@keyframes sxAutosaveSpin { to { transform: rotate(360deg); } }
.sx-autosave-indicator .sx-spin {
  display: inline-block;
  animation: sxAutosaveSpin 1s linear infinite;
}

/* ============================================================
   AI Assistant (public/app/ai-assistant.php · ai-assistant.js)
   Layout de chat: sidebar de conversaciones + hilo + input.
   Clases scopeadas con prefijo .sx-ai- (UI_CONVENTIONS §15).
   ============================================================ */

/* Lista de conversaciones (sidebar) */
.sx-ai-conv-list {
  max-height: 60vh;
  overflow-y: auto;
}
.sx-ai-conv-item {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  border-radius: var(--radius-sm);
  padding: 0.25rem;
  margin-bottom: 0.25rem;
  transition: var(--transition-fast);
}
.sx-ai-conv-item:hover { background: var(--sx-row-hover); }
.sx-ai-conv-item.active { background: var(--sx-primary-light); }
.sx-ai-conv-open {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  border: 0;
  background: transparent;
  text-align: left;
  padding: 0.4rem 0.5rem;
  color: var(--sx-text-body);
  cursor: pointer;
}
.sx-ai-conv-title {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.sx-ai-conv-meta {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.sx-ai-conv-edit,
.sx-ai-conv-del { flex: 0 0 auto; padding: 0.2rem 0.3rem; line-height: 1; }
/* Iconos de acción pegados entre sí (sin separación del gap del item). */
.sx-ai-conv-edit { margin-left: 0.1rem; }
.sx-ai-conv-edit + .sx-ai-conv-del { margin-left: -0.2rem; }

/* Hilo de mensajes */
.sx-ai-thread {
  overflow-y: auto;
  max-height: 60vh;
  min-height: 280px;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.sx-ai-thread-empty { margin: auto; max-width: 28rem; }

.sx-ai-msg { display: flex; }
.sx-ai-msg--user { justify-content: flex-end; }
.sx-ai-msg--assistant { justify-content: flex-start; }

.sx-ai-bubble {
  max-width: 85%;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius);
  border: 1px solid var(--sx-border-color);
  background: var(--sx-card-bg);
}
.sx-ai-msg--user .sx-ai-bubble {
  background: var(--sx-primary-light);
  border-color: var(--sx-primary-light);
}
.sx-ai-msg-role { color: var(--sx-text-muted); }
.sx-ai-msg-body {
  white-space: pre-wrap;   /* conserva saltos de línea del texto del LLM */
  word-break: break-word;
  color: var(--sx-text-body);
}
/* Respuestas del asistente renderizadas como HTML: sin pre-wrap y con espaciado. */
.sx-ai-msg-body--html { white-space: normal; }
.sx-ai-msg-body--html > :first-child { margin-top: 0; }
.sx-ai-msg-body--html > :last-child { margin-bottom: 0; }
.sx-ai-msg-body--html p { margin: 0 0 0.5rem; }
.sx-ai-msg-body--html ul,
.sx-ai-msg-body--html ol { margin: 0 0 0.5rem; padding-left: 1.25rem; }
.sx-ai-msg-body--html li { margin-bottom: 0.15rem; }
.sx-ai-msg-body--html h1,
.sx-ai-msg-body--html h2,
.sx-ai-msg-body--html h3,
.sx-ai-msg-body--html h4,
.sx-ai-msg-body--html h5,
.sx-ai-msg-body--html h6 { margin: 0.5rem 0 0.35rem; font-weight: 700; }
.sx-ai-msg-body--html h4 { font-size: 1rem; }
.sx-ai-msg-body--html code {
  background: var(--sx-body-bg);
  padding: 0.05rem 0.3rem;
  border-radius: var(--radius-sm);
  font-size: 0.875em;
}
.sx-ai-msg-body--html pre {
  background: var(--sx-body-bg);
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-sm);
  overflow-x: auto;
  margin: 0 0 0.5rem;
}
.sx-ai-msg-body--html pre code { background: none; padding: 0; }
.sx-ai-msg-body--html table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 0.5rem;
  font-size: 0.9em;
}
.sx-ai-msg-body--html th,
.sx-ai-msg-body--html td {
  border: 1px solid var(--sx-border-color);
  padding: 0.3rem 0.5rem;
  text-align: left;
}
.sx-ai-msg-body--html a { color: var(--sx-primary); text-decoration: underline; }
.sx-ai-msg-body--html blockquote {
  border-left: 3px solid var(--sx-border-color);
  margin: 0 0 0.5rem;
  padding-left: 0.75rem;
  color: var(--sx-text-muted);
}

/* Valoración de la respuesta (👍/👎): íconos sutiles bajo cada mensaje del asistente. */
.sx-ai-feedback {
  display: flex;
  gap: 0.25rem;
  margin-top: 0.4rem;
}
.sx-ai-feedback-btn {
  border: 0;
  background: none;
  padding: 0.1rem 0.3rem;
  line-height: 1;
  border-radius: var(--radius-sm);
  color: var(--sx-text-muted);
  cursor: pointer;
  transition: var(--transition);
}
.sx-ai-feedback-btn:hover { color: var(--sx-text-body); background: var(--sx-body-bg); }
.sx-ai-feedback-btn.is-active { color: var(--sx-primary); }

/* Columna del mensaje: burbuja + pie (hora · acciones). Limita el ancho al 85%
   (antes lo hacía la burbuja) para que el pie se alinee al borde del mensaje. */
.sx-ai-msg-col { display: flex; flex-direction: column; max-width: 85%; min-width: 0; }
.sx-ai-msg--user .sx-ai-msg-col { align-items: flex-end; }
.sx-ai-msg--assistant .sx-ai-msg-col { align-items: flex-start; }
.sx-ai-msg-col .sx-ai-bubble { max-width: 100%; }

/* Pie: hora siempre visible; acciones (copiar/editar) fuera de la burbuja, solo
   al hacer hover sobre el mensaje. */
.sx-ai-msg-foot {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.2rem;
  padding: 0 0.3rem;
  font-size: 0.72rem;
  color: var(--sx-text-muted);
}
.sx-ai-msg--user .sx-ai-msg-foot { flex-direction: row-reverse; }
.sx-ai-msg-time { line-height: 1; white-space: nowrap; }
.sx-ai-msg-actions {
  display: flex;
  gap: 0.1rem;
  opacity: 0;
  transition: var(--transition);
}
.sx-ai-msg:hover .sx-ai-msg-actions { opacity: 1; }
.sx-ai-act-btn { font-size: 0.8rem; }

/* Textarea de edición: crece con el contenido, sin barra de scroll. */
.sx-ai-edit-ta { resize: none; overflow-y: hidden; }

/* Medidores de uso: barras tipo "context window" (pill + relleno suave). */
.sx-ai-usage-card .progress {
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--sx-border-color);
  overflow: hidden;
}
.sx-ai-usage-card .progress-bar {
  border-radius: var(--radius-pill);
  transition: width 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
.sx-ai-usage-card #uCtxLbl,
.sx-ai-usage-card #u5hLbl,
.sx-ai-usage-card #uGenLbl {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Indicador "pensando…" */
/* Indicador "pensando": burbuja con ícono en pulso + puntos que rebotan. */
.sx-ai-thinking-bubble {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.sx-ai-thinking-icon {
  color: var(--sx-primary);
  font-size: 1.05rem;
  animation: sxAiPulse 1.4s ease-in-out infinite;
}
.sx-ai-thinking-label {
  color: var(--sx-text-muted);
  font-style: italic;
  background: linear-gradient(90deg,
    var(--sx-text-muted) 0%, var(--sx-primary) 50%, var(--sx-text-muted) 100%);
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: sxAiShimmer 2s linear infinite;
}
.sx-ai-typing {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.sx-ai-typing span {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-circle);
  background: var(--sx-primary);
  animation: sxAiBounce 1.2s ease-in-out infinite;
}
.sx-ai-typing span:nth-child(2) { animation-delay: 0.18s; }
.sx-ai-typing span:nth-child(3) { animation-delay: 0.36s; }
@keyframes sxAiBounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.45; }
  30% { transform: translateY(-5px); opacity: 1; }
}
@keyframes sxAiPulse {
  0%, 100% { transform: scale(1); opacity: 0.7; }
  50% { transform: scale(1.18); opacity: 1; }
}
@keyframes sxAiShimmer {
  0% { background-position: 200% center; }
  100% { background-position: 0% center; }
}
@media (prefers-reduced-motion: reduce) {
  .sx-ai-thinking-icon,
  .sx-ai-thinking-label,
  .sx-ai-typing span { animation: none; }
}

/* Fila de input */
.sx-ai-input-row .form-icon { margin-bottom: 0; }
/* Sin min-height global (components.css lo pone en 100px): este textarea arranca
   en 1 renglón y crece solo (autoGrow). */
.sx-ai-input-row textarea.form-control { resize: vertical; min-height: 0; }
/* Selector "enfocar clase" en el header del chat. */
.sx-ai-focus { min-width: 220px; max-width: 340px; margin-bottom: 0; }
.sx-ai-focus .select2-container { min-width: 200px; }
/* Micrófono grabando: color de marca "peligro" + pulso suave. */
.sx-ai-mic-on { color: var(--sx-red); border-color: var(--sx-red); animation: sxMicPulse 1.2s ease-in-out infinite; }
@keyframes sxMicPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

/* =========================================================================
 * Inscripciones (admin) — enrollment-admin
 * Prefijo: .sx-enradmin-
 * ========================================================================= */

/* Modal de detalle: lista de documentos (checklist). */
.sx-enradmin-doclist .sx-enradmin-docrow:last-child,
.sx-enradmin-conlist .sx-enradmin-conrow:last-child {
  border-bottom: 0 !important;
}
.sx-enradmin-docstate {
  width: auto;
  min-width: 9rem;
}

/* Configurador: grupos de campos. */
.sx-enradmin-cfg-group {
  padding-bottom: 0.5rem;
  border-bottom: 1px dashed var(--bs-border-color, #dee2e6);
}
.sx-enradmin-cfg-group:last-child {
  border-bottom: 0;
}

/* Configurador: bloques de consentimiento. */
.sx-enradmin-cfg-con {
  background: var(--bs-tertiary-bg, #f8f9fa);
}
.sx-enradmin-cfg-con textarea {
  resize: vertical;
}

/* Espacio interno coherente entre fieldsets del configurador. */
.sx-enradmin-fieldset {
  margin-bottom: 1.25rem;
}

/* Avatar grande para el badge de identidad del estudiante. */
.sx-avatar--lg {
  width: 62px;
  height: 62px;
  min-width: 62px;
  font-size: 1.45rem;
}

/* Tamaño de fuente extra pequeño (Bootstrap solo llega a fs-6). */
.fs-7 { font-size: 0.8rem; }

/* Avatar mediano (cabeceras de colapsables por grupo). */
.sx-avatar--md {
  width: 46px;
  height: 46px;
  min-width: 46px;
  font-size: 1.1rem;
}

/* Variantes de color para el avatar de iniciales (paleta schoolaryx). */
.sx-avatar--primary { background: var(--sx-primary); }
.sx-avatar--purple  { background: var(--sx-purple); }
.sx-avatar--success { background: var(--sx-green); }
.sx-avatar--sky     { background: var(--sx-sky); }
.sx-avatar--red     { background: var(--sx-red); }
