/* Estilos de Ponte. Tokens y componentes según docs/guia-front.md.
   Mobile first: los estilos base son para 360 px y se amplían con media queries.
   Sin estilos en línea: la CSP los bloquea, así que todo va en clases. */

:root {
  color-scheme: light dark;

  --bg: #ffffff;
  --surface-subtle: #f6f8fa;
  --header: #f6f8fa;
  --border: #d0d7de;
  --divider: #d8dee4;
  --track: #eff2f5;
  --text: #1f2328;
  --muted: #59636e;
  --icon-off: #6e7781;
  --accent: #0969da;
  --primary: #1f2328;
  --on-primary: #ffffff;
  /* Fondo del enlace de la página actual y del hover en la barra superior. */
  --nav-current: #e7ebef;

  --danger-bg: #ffebe9;
  --danger-text: #a40e26;
  --today-bg: #fff8c5;
  --today-text: #7d4e00;
  --week-bg: #ddf4ff;
  --week-text: #0550ae;
  --done-bg: #dafbe1;
  --done-text: #116329;
  /* Burbujas propias del hilo (guía de front: «las tuyas a la derecha»). */
  --own-bg: #ddf4ff;
  --own-border: #b6e3ff;
  /* Texto sobre un fondo --accent (pastilla «N sin leer»). */
  --on-accent: #ffffff;

  /* Colores de módulo: nunca identifican un módulo solos, el nombre va siempre al lado. */
  --mod-mia: #0969da;
  --mod-saa: #8250df;
  --mod-pia: #1a7f37;
  --mod-sbd: #bc4c00;
  --mod-bda: #bf3989;
  /* Tutoría: gris pizarra algo más oscuro y azulado que el gris de «sin clave» (--icon-off). */
  --mod-tut: #3f5a6e;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
  --radius-block: 12px;
  --radius-control: 6px;
  --radius-pill: 999px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d1117;
    --surface-subtle: #151b23;
    --header: #010409;
    --border: #3d444d;
    --divider: #2f353d;
    --track: #262c36;
    --text: #f0f6fc;
    --muted: #9198a1;
    --icon-off: #7d8590;
    --accent: #4493f8;
    /* En oscuro, el botón principal se invierte: fondo claro y texto oscuro. */
    --primary: #f0f6fc;
    --on-primary: #0d1117;
    --nav-current: #262c36;

    --danger-bg: #4b1c20;
    --danger-text: #ffa198;
    --today-bg: #3b2e05;
    --today-text: #f2cc60;
    --week-bg: #12274a;
    --week-text: #8cc4ff;
    --done-bg: #12361f;
    --done-text: #6fdd8b;
    --own-bg: #12274a;
    --own-border: #1f4a8a;
    --on-accent: #0d1117;

    --mod-mia: #4493f8;
    --mod-saa: #ab7df8;
    --mod-pia: #3fb950;
    --mod-sbd: #f0883e;
    --mod-bda: #db61a2;
    --mod-tut: #94aab9;
  }
}

/* Base */

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  background: var(--bg);
  color: var(--text);
}

/* Columna de toda la altura: el contenido crece y el pie queda al final de la ventana. */
body {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh / var(--ui-zoom, 1));
  min-height: calc(100dvh / var(--ui-zoom, 1));
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

h1 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
}

code {
  font-size: 12px;
  padding: 1px 4px;
  background: var(--track);
  border-radius: 4px;
}

.muted {
  color: var(--muted);
}

/* Texto solo para lectores de pantalla. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.icon {
  flex-shrink: 0;
}

/* Barra superior */

.topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 12px;
  padding: 8px 16px;
  background: var(--header);
  border-bottom: 1px solid var(--border);
}

.topbar-start {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  /* En el móvil solo queda el icono: el ancho mínimo mantiene la zona táctil de 44 px. */
  min-width: 44px;
  color: var(--text);
  font-size: 16px;
  font-weight: 600;
}

.brand-name {
  display: none;
}

.brand:hover {
  text-decoration: none;
}

.nav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 6px;
  border-radius: var(--radius-control);
  color: var(--text);
}

.nav-link:hover {
  background: var(--nav-current);
  text-decoration: none;
}

.nav-link[aria-current="page"] {
  background: var(--nav-current);
  font-weight: 600;
}

.nav-link[aria-disabled="true"]:hover {
  background: none;
}

/* Secciones aún sin construir: apagadas y sin reacción al pasar el ratón.
   «Próximamente» se ve siempre. En el móvil va debajo del nombre, pequeño, para
   que el enlace siga midiendo 44 px y la barra no se ensanche. */
.nav-link[aria-disabled="true"] {
  color: var(--muted);
  cursor: default;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  line-height: 1.2;
}

.nav-soon {
  font-size: 11px;
  font-weight: 400;
}

/* En el móvil, «Aprendizaje» no cabe: se muestra «Aprender». */
.label-wide {
  display: none;
}

.user {
  display: flex;
  align-items: center;
  gap: 12px;
}

.user-name {
  display: none;
}

.user form {
  margin: 0;
}

/* Contenido */

.page {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 24px;
  /* Todo el ancho, con el margen de los lados; el tope solo evita líneas eternas en
     monitores enormes. */
  width: 100%;
  max-width: 1920px;
  margin: 0 auto;
  padding: 20px 16px 32px;
}

/* Bloque: la unidad básica para separar la información. */

.block {
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
  background: var(--bg);
  overflow: hidden;
}

.block-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: var(--surface-subtle);
  border-bottom: 1px solid var(--border);
}

.block-header h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.block-body {
  padding: 16px;
}

.block-body > :first-child {
  margin-top: 0;
}

.block-body > :last-child {
  margin-bottom: 0;
}

/* Botones */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.button:hover {
  background: var(--surface-subtle);
}

a.button:hover {
  text-decoration: none;
}

.button--primary {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--on-primary);
}

.button--primary:hover {
  background: var(--primary);
  opacity: 0.9;
}

.button--small {
  min-height: 44px;
  padding: 0 10px;
  font-weight: 400;
}

/* Formularios */

.field-label {
  font-weight: 600;
}

.field {
  width: 100%;
  min-height: 44px;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  /* 16px como mínimo: si no, Safari en iOS amplía la página al enfocar el campo. */
  font-size: 16px;
}

.field:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  border-color: var(--accent);
}

.field-hint {
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--muted);
}

/* Aviso de error: color, icono y texto, nunca solo color. */

.alert {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 12px 16px;
  border-radius: var(--radius-control);
  font-weight: 600;
}

.alert .icon {
  margin-top: 2px;
}

.alert--danger {
  background: var(--danger-bg);
  color: var(--danger-text);
}

.alert--warning {
  background: var(--today-bg);
  color: var(--today-text);
}

/* Etiqueta de urgencia o estado: pastilla con icono y texto. */

.tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  justify-self: start;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

.tag--today {
  background: var(--today-bg);
  color: var(--today-text);
}

.tag--week {
  background: var(--week-bg);
  color: var(--week-text);
}

.tag--done {
  background: var(--done-bg);
  color: var(--done-text);
}

/* Módulos: la clase fija el color y el resto de piezas lo leen de --mod. */

.mod--mia { --mod: var(--mod-mia); }
.mod--saa { --mod: var(--mod-saa); }
.mod--pia { --mod: var(--mod-pia); }
.mod--sbd { --mod: var(--mod-sbd); }
.mod--bda { --mod: var(--mod-bda); }
.mod--tut { --mod: var(--mod-tut); }

/* Sin clave de módulo, el punto queda gris. */
.mod-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--mod, var(--icon-off));
  flex-shrink: 0;
}

.mod-dot--small {
  width: 8px;
  height: 8px;
}

.section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.mod-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

.mod-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
  background: var(--bg);
  color: var(--text);
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
}

/* Glow en el color del módulo; sin clave de módulo, en el gris del borde. */
.mod-card:hover,
.mod-card:has(.mod-card-link:focus-visible) {
  border-color: var(--mod, var(--muted));
  box-shadow: 0 0 0 1px var(--mod, var(--muted)), 0 0 32px -6px var(--mod, var(--muted));
}

/* El foco del enlace se marca en toda la card, que es lo que se pulsa. */
.mod-card:has(.mod-card-link:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.mod-card-link {
  color: inherit;
}

.mod-card-link:hover,
.mod-card-link:focus-visible {
  text-decoration: none;
  outline: none;
}

/* Estira el enlace del título para que toda la card lleve al módulo. */
.mod-card-link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

/* Pie con los tres avisos: tareas, foro y material. */
.mod-updates {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--divider);
}

/* Solo los botones quedan por encima del enlace; el resto del pie lleva al módulo. */
.mod-update-form {
  position: relative;
  z-index: 1;
  margin: 0;
}

.mod-update {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  color: var(--icon-off);
}

.mod-update--on {
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-subtle);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
}

button.mod-update--on {
  cursor: pointer;
}

button.mod-update--on:hover {
  border-color: var(--mod, var(--muted));
}

.mod-card-title {
  display: flex;
  align-items: center;
  gap: 8px;
}

.mod-card-title h2 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.3;
}

/* Título y profesores van juntos, con menos hueco que el resto de la card. */
.mod-card-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Los nombres largos parten línea en vez de desbordar. */
.mod-teachers {
  margin: 0;
  overflow-wrap: anywhere;
}

/* Botón ↗ «Ver en Moodle»: queda por encima del enlace estirado de la card. En el móvil,
   44 px de zona táctil; el margen negativo evita que agrande la card. */
.mod-moodle {
  position: relative;
  z-index: 1;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -10px -10px -10px auto;
  border-radius: 6px;
  color: var(--muted);
}

.mod-moodle:hover {
  background: var(--surface-subtle);
  color: var(--text);
}

/* Filas de tareas */

.task-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.task {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 4px;
  padding: 12px 16px 0;
}

.task + .task {
  border-top: 1px solid var(--divider);
}

.task--done {
  background: var(--surface-subtle);
  color: var(--muted);
}

.task-name {
  font-weight: 600;
}

.task-module {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 12px;
}

.task-due {
  color: var(--muted);
}

/* Móvil: el enlace mide 44 px de alto con el texto arriba, pegado a la fecha; su zona táctil
   sobrepasa 14 px la fila (el margen negativo) y no tapa nada interactivo. */
.task-link {
  display: inline-flex;
  align-items: flex-start;
  justify-self: start;
  min-height: 44px;
  margin-bottom: -14px;
  padding-top: 2px;
}

.empty {
  margin: 0;
  padding: 16px;
  color: var(--muted);
}

.block-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
}

.block-meta {
  color: var(--muted);
  font-size: 12px;
}

.block-header form {
  margin: 0;
}

/* Dentro de un bloque, el aviso ocupa todo el ancho, sin esquinas propias. */
.block > .alert {
  border-radius: 0;
  border-bottom: 1px solid var(--divider);
}

/* Pantalla «Por asignatura». Las plantillas llegan con H4e; aquí solo los estilos. */

.breadcrumb {
  color: var(--muted);
  font-size: 13px;
}

.page-header {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.page-heading {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.page-title {
  display: flex;
  align-items: center;
  gap: 10px;
}

.page-subtitle {
  margin: 0;
  color: var(--muted);
}

/* Subtítulo de 13 px bajo el título del hilo («4 mensajes · 2 sin leer»). */
.page-subtitle--small {
  font-size: 13px;
}

.page-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

.page-actions form {
  margin: 0;
}

/* En el móvil la hora ocupa su propia línea y los botones quedan juntos debajo. */
.page-actions > .block-meta {
  flex-basis: 100%;
}

.mod-dot--large {
  width: 12px;
  height: 12px;
}

/* Material y Ejercicios: una columna en el móvil, dos en pantallas anchas. */
.course-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.block-header .icon {
  color: var(--text);
}

/* El título del bloque con su icono a la izquierda y la pista a la derecha. */
.block-header--icon {
  justify-content: flex-start;
  gap: 10px;
}

.block-header--icon .block-meta {
  margin-left: auto;
}

/* Cada tema es un desplegable: el título hace de botón, con la flecha de las carpetas. */
.topic + .topic {
  border-top: 1px solid var(--divider);
}

.topic > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 16px;
  list-style: none;
  cursor: pointer;
}

.topic > summary::-webkit-details-marker {
  display: none;
}

.topic > summary:hover {
  background: var(--surface-subtle);
}

.topic > summary .chevron {
  color: var(--muted);
  transition: transform 0.2s ease;
}

.topic[open] > summary .chevron {
  transform: rotate(180deg);
}

.topic > .item-list {
  padding-bottom: 8px;
}

.topic-title {
  flex-grow: 1;
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

.item-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Fila de material o de ejercicio: icono, nombre, datos y acción. */
.item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  padding: 8px 16px;
}

.item:hover {
  background: var(--surface-subtle);
}

.item > .icon {
  color: var(--muted);
}

.item > .item-name {
  flex: 1 1 160px;
  min-width: 0;
}

/* Carpeta: una fila que se despliega con sus ficheros, sin JavaScript. */
.folder > summary {
  flex-wrap: nowrap;
  min-height: 44px;
  list-style: none;
  cursor: pointer;
}

.folder > summary::-webkit-details-marker {
  display: none;
}

.folder > summary .chevron {
  flex-shrink: 0;
  margin-left: auto;
  transition: transform 0.2s ease;
}

.folder[open] > summary .chevron {
  transform: rotate(180deg);
}

.folder-files {
  margin: 0 16px 8px 44px;
  padding: 0;
  list-style: none;
  border-left: 1px solid var(--divider);
}

.folder-files .item {
  padding: 0 0 0 12px;
}

.item-main {
  display: flex;
  flex-direction: column;
  flex: 1 1 160px;
  min-width: 0;
}

.item-name {
  overflow-wrap: anywhere;
}

.item-main .item-name {
  font-weight: 600;
}

.item-meta {
  color: var(--muted);
  font-size: 12px;
}

/* Etiqueta de estado y enlace de una tarea, juntos y sin desbordar. */
.item-side {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
}

.item-action {
  display: inline-flex;
  white-space: nowrap;
  align-items: center;
  min-height: 44px;
  font-size: 13px;
}

/* Estado neutro («Sin empezar») y vencida, con el mismo formato que el resto. */
.tag--neutral {
  padding: 1px 9px;
  border: 1px solid var(--border);
  background: var(--surface-subtle);
  color: var(--muted);
}

.tag--danger {
  background: var(--danger-bg);
  color: var(--danger-text);
}

/* Notas: si la tabla no cabe en el móvil, se desplaza dentro de su caja. */
.table-scroll {
  overflow-x: auto;
}

.grades {
  width: 100%;
  border-collapse: collapse;
}

.grades th,
.grades td {
  padding: 10px 16px;
  text-align: left;
  vertical-align: top;
}

.grades thead th {
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  border-bottom: 1px solid var(--border);
}

.grades tbody td {
  border-bottom: 1px solid var(--divider);
}

.grades tfoot th,
.grades tfoot td {
  padding-top: 12px;
  padding-bottom: 12px;
  background: var(--surface-subtle);
  font-weight: 600;
}

.grades-activity {
  display: block;
}

.grades-value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.grades-range {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.grades tfoot .grades-range {
  font-weight: 400;
}

.grades-ungraded {
  color: var(--muted);
}

.comment summary {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent);
  font-size: 12px;
  cursor: pointer;
}

/* El comentario es HTML de Moodle ya sanitizado: se igualan sus márgenes. */
.comment-body {
  margin-top: 6px;
  padding: 8px 12px;
  border-radius: var(--radius-control);
  background: var(--surface-subtle);
  color: var(--text);
  overflow-wrap: anywhere;
}

.comment-body > :first-child {
  margin-top: 0;
}

.comment-body > :last-child {
  margin-bottom: 0;
}

/* Login: caja estrecha centrada sobre fondo gris. */

.login-page {
  background: var(--surface-subtle);
}

.login {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  width: 100%;
  max-width: 340px;
  margin: 0 auto;
  padding: 48px 16px;
}

.login-logo {
  color: var(--text);
}

.login h1 {
  margin-bottom: 8px;
  font-size: 24px;
  font-weight: 600;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  padding: 20px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
}

.login-form .button {
  margin-top: 12px;
}

.login-note {
  width: 100%;
  margin: 0;
  padding: 16px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}

/* Escritorio */

@media (min-width: 768px) {
  .topbar {
    padding: 12px 32px;
  }

  .mod-moodle {
    width: 28px;
    height: 28px;
    margin: 0 0 0 auto;
  }

  .topbar-start {
    gap: 24px;
  }

  .brand-name {
    display: inline;
  }

  .nav-link {
    padding: 0 10px;
  }

  .label-wide {
    display: inline;
  }

  .label-narrow {
    display: none;
  }

  /* Escritorio: «Próximamente» al lado del nombre, en la misma línea. */
  .nav-link[aria-disabled="true"] {
    flex-direction: row;
    align-items: center;
  }

  .nav-soon {
    margin-left: 6px;
    font-size: 12px;
  }

  .user-name {
    display: inline;
    color: var(--muted);
  }

  .page {
    gap: 32px;
    padding: 32px 32px 48px;
  }

  h1 {
    font-size: 24px;
  }

  .login {
    padding-top: 64px;
  }

  .section {
    gap: 16px;
  }

  /* Rejilla de 6 columnas y cada card ocupa 2: con 5 módulos, las 2 de arriba
     quedan sobre los huecos entre las 3 de abajo. Con 6 cards (5 módulos y la
     tutoría) la rejilla queda en 3 + 3 sin más reglas. */
  .mod-grid {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 16px;
  }

  .mod-card {
    grid-column: span 2;
    min-height: 120px;
    padding: 20px;
  }

  .mod-card:first-child:nth-last-child(5) {
    grid-column: 2 / span 2;
  }

  .mod-card:nth-child(2):nth-last-child(4) {
    grid-column: 4 / span 2;
  }

  .task {
    grid-template-columns: 120px minmax(0, 1fr) 170px 110px 140px;
    align-items: center;
    gap: 16px;
    padding: 14px 20px;
  }

  /* Escritorio: fecha y estado vuelven a ser columnas propias y el « · » se oculta. */
  .task-when {
    display: contents;
  }

  .task-sep {
    display: none;
  }

  /* «Más adelante» no lleva etiqueta de urgencia, así que tiene una columna menos. */
  .task-list--plain .task {
    grid-template-columns: minmax(0, 1fr) 170px 110px 140px;
  }

  .task-link {
    justify-self: end;
    min-height: auto;
    margin-bottom: 0;
    padding-top: 0;
  }

  .page-actions > .block-meta {
    flex-basis: auto;
  }

  .page-header {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }

  .topic > summary {
    padding: 0 20px;
  }

  .item {
    flex-wrap: nowrap;
    padding: 8px 20px;
  }

  .folder-files {
    margin: 0 20px 8px 48px;
  }

  .folder-files .item {
    padding: 6px 0 6px 12px;
  }

  .item-action,
  .comment summary {
    min-height: auto;
  }

  .grades th,
  .grades td {
    padding-left: 20px;
    padding-right: 20px;
  }

  .grades-col {
    width: 160px;
  }
}

/* Dos columnas solo a partir de 1024 px: en una tableta las filas no caben. */
@media (min-width: 1024px) {
  .course-columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Página de error: un solo bloque estrecho con el mensaje y el enlace a Inicio. */

.page--narrow {
  max-width: 720px;
}

.error-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

.error-body p {
  margin: 0;
}

.error-body .alert {
  align-self: stretch;
}

.error-body .button {
  text-decoration: none;
}

/* Foros, foro e hilo (H5). Maquetas: Foros.dc.html y Hilo.dc.html. */

.alert--success {
  background: var(--done-bg);
  color: var(--done-text);
}

/* Aviso destacado (envío incierto): borde propio y el texto y los enlaces debajo del título. */
.alert--prominent {
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  padding: 16px;
  border: 2px solid currentColor;
  font-weight: 400;
}

.alert--prominent p {
  margin: 0;
}

.alert-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

.alert-head .icon {
  margin-top: 0;
}

.alert-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
}

/* Barra de filtros: una caja con la etiqueta «Asignatura», los chips y la casilla. */
.filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
  background: var(--surface-subtle);
}

.filters-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.filters-label {
  margin-right: 4px;
  font-weight: 600;
}

/* Chips de filtro: enlaces con forma de pastilla. La activa se rellena de --primary. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
}

.chip:hover {
  background: var(--surface-subtle);
  text-decoration: none;
}

.chip[aria-current="true"] {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--on-primary);
}

/* «Solo no leídos»: una casilla de verdad en un formulario GET. Con JavaScript se envía al
   marcarla (auto-submit.js); sin él, sale el botón «Aplicar» (dentro de <noscript>). */
.filter-unread {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  cursor: pointer;
}

.check input {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--primary);
}

/* Fila de hilo o de foro. Móvil: título y chincheta arriba y los datos debajo. El título
   enlaza y cubre toda la fila; la chincheta queda por encima. */
.thread {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 12px;
  padding: 12px 16px;
}

.thread + .thread {
  border-top: 1px solid var(--divider);
}

.thread:hover {
  background: var(--surface-subtle);
}

.thread-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.thread-title {
  color: var(--text);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.thread-title::after {
  content: "";
  position: absolute;
  inset: 0;
}

.thread-title:hover {
  text-decoration: none;
}

.thread-title:focus-visible {
  outline: none;
}

.thread:has(.thread-title:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* Módulo (con su punto) y, si hace falta, foro y autor. */
.thread-sub,
.thread-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 12px;
  color: var(--muted);
  font-size: 12px;
}

.thread-module {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Último mensaje, cuántos hilos o respuestas y sin leer. */
.thread-meta {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 12px;
  color: var(--muted);
  font-size: 13px;
}

.thread-side {
  position: relative;
  z-index: 1;
  grid-column: 2;
  grid-row: 1;
  display: flex;
  align-items: center;
}

.thread-side form {
  margin: 0;
}

/* Pastilla «N sin leer», rellena de --accent; sin mensajes sin leer, «Al día» en gris. */
.pill-unread {
  display: inline-block;
  padding: 1px 10px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  font-size: 12px;
  font-weight: 600;
}

/* Botón de chincheta: borde discontinuo; relleno si el hilo está fijado. 44 px en el móvil. */
.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px dashed var(--icon-off);
  border-radius: var(--radius-control);
  background: var(--bg);
  color: var(--muted);
  cursor: pointer;
}

.icon-button:hover {
  background: var(--surface-subtle);
  color: var(--text);
}

.icon-button[aria-pressed="true"] {
  border-color: var(--muted);
  color: var(--text);
}

/* Hilo como conversación: caja gris con las burbujas dentro. */
.thread-heading {
  font-size: 20px;
}

.chat {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 0;
  padding: 16px;
  list-style: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
  background: var(--surface-subtle);
}

/* Separador de día: pastilla centrada. */
.chat-day {
  align-self: center;
  padding: 2px 12px;
  border-radius: var(--radius-pill);
  background: var(--nav-current);
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}

/* Línea «N sin leer» antes del primer mensaje sin leer. */
.chat-unread {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--week-text);
  font-size: 12px;
  font-weight: 600;
}

.chat-unread::before,
.chat-unread::after {
  content: "";
  flex: 1 1 0;
  height: 1px;
  background: var(--accent);
}

.chat-msg {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  align-self: flex-start;
  max-width: 88%;
}

.chat-msg--own {
  align-self: flex-end;
}

.chat-avatar {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--bg);
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}

.chat-bubble {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 12px 12px 12px 4px;
  background: var(--bg);
}

.chat-msg--own .chat-bubble {
  border-color: var(--own-border);
  border-radius: 12px 12px 4px 12px;
  background: var(--own-bg);
}

.chat-author {
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}

.chat-msg--own .chat-author {
  color: var(--week-text);
}

.chat-time {
  align-self: flex-end;
  color: var(--muted);
  font-size: 11px;
}

/* Mensaje de Moodle ya sanitizado: se igualan sus márgenes y se evita que ensanche la página. */
.chat-body {
  overflow-wrap: anywhere;
}

.chat-body > :first-child {
  margin-top: 0;
}

.chat-body > :last-child {
  margin-bottom: 0;
}

.chat-body pre {
  overflow-x: auto;
}

.chat-body table {
  display: block;
  overflow-x: auto;
}

.chat-attachments {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chat-attachments a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  overflow-wrap: anywhere;
}

/* Caja de respuesta: una caja con borde, etiqueta, campo y, debajo, la pista y el botón. */
.reply-box {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
}

.reply-box > .alert,
.reply-box > p {
  margin: 0;
}

.reply-label {
  font-size: 13px;
  font-weight: 600;
}

.field--area {
  min-height: 96px;
  resize: vertical;
}

.field[aria-invalid="true"] {
  border-color: var(--danger-text);
}

.reply-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
}

.reply-hint {
  color: var(--muted);
  font-size: 12px;
}

.reply-preview {
  margin: 0;
  padding: 12px;
  border: 1px solid var(--own-border);
  border-radius: var(--radius-block);
  background: var(--own-bg);
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.form-actions form {
  margin: 0;
}

.button:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

@media (min-width: 768px) {
  .chip {
    min-height: 36px;
  }

  .check {
    min-height: 36px;
  }

  .icon-button {
    width: 32px;
    height: 32px;
  }

  .thread-heading {
    font-size: 22px;
  }

  .chat {
    padding: 20px;
  }

  .chat-msg {
    max-width: 72%;
  }

  .chat-attachments a {
    min-height: auto;
  }
}

/* Exámenes de práctica (#20). Maquetas: ExamenInicio, ExamenPregunta y ExamenResultado. */

.exam-card {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
}

.exam-fieldset {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.exam-fieldset > legend {
  margin-bottom: 10px;
  padding: 0;
  font-weight: 600;
}

.exam-modules {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
}

/* Opción de radio con forma de caja: módulo o respuesta. La elegida, con borde marcado. */
.exam-option {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}

.exam-option:hover {
  border-color: var(--icon-off);
}

.exam-option input {
  flex-shrink: 0;
  margin: 0;
  accent-color: var(--primary);
}

.exam-option:has(input:checked) {
  border-color: var(--primary);
  background: var(--surface-subtle);
  box-shadow: inset 0 0 0 1px var(--primary);
}

.exam-counts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Botones segmentados de 5, 10 y 20 y de la dificultad: el radio queda oculto y la caja hace de botón. */
.exam-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 64px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
}

.exam-count:has(input:checked) {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--on-primary);
}

.exam-count:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.exam-footer {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  padding-top: 16px;
  border-top: 1px solid var(--divider);
}

.exam-footer .field-hint {
  margin: 0;
}

.exam-module {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.exam-history {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.exam-history h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.exam-history .empty {
  padding: 0;
}

.exam-results {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
  overflow: hidden;
}

.exam-result-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  padding: 10px 16px;
}

.exam-result-row + .exam-result-row {
  border-top: 1px solid var(--divider);
}

.exam-result-row .exam-module {
  flex-grow: 1;
}

.exam-result-row .muted {
  font-size: 13px;
}

.exam-tally {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Pregunta: progreso, enunciado y respuestas. */

.exam-progress {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.exam-progress-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.exam-progress-label {
  font-weight: 600;
}

.exam-leave {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--muted);
  font-size: 13px;
}

/* La CSP no deja dar el ancho en línea: <progress> lleva su valor y se pinta aquí. */
.exam-progress-bar {
  display: block;
  width: 100%;
  height: 6px;
  border: 0;
  border-radius: 4px;
  background: var(--track);
  color: var(--primary);
  appearance: none;
  overflow: hidden;
}

.exam-progress-bar::-webkit-progress-bar {
  background: var(--track);
}

.exam-progress-bar::-webkit-progress-value {
  border-radius: 4px;
  background: var(--primary);
}

.exam-progress-bar::-moz-progress-bar {
  border-radius: 4px;
  background: var(--primary);
}

.exam-question {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.exam-question .exam-module {
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
}

.exam-question-text {
  font-size: 18px;
  line-height: 1.4;
}

.exam-answer {
  gap: 12px;
  padding: 12px 16px;
}

.exam-letter {
  width: 16px;
  color: var(--muted);
  font-weight: 600;
}

/* «Siguiente» va antes en el HTML (Intro envía el primer botón); aquí se pinta a la derecha. */
.exam-nav {
  flex-direction: row-reverse;
  justify-content: space-between;
}

.exam-note {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  text-align: center;
}

/* Resultado: nota y repaso de las respuestas. */

.exam-score {
  gap: 16px;
}

.exam-score-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.exam-score-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.exam-score-title {
  color: var(--muted);
  font-size: 14px;
}

.exam-score-value {
  font-size: 48px;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.exam-score-max {
  color: var(--muted);
  font-size: 24px;
}

.exam-review {
  margin: 0;
  padding: 0;
  list-style: none;
}

.exam-review-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 14px 16px;
}

.exam-review-item + .exam-review-item {
  border-top: 1px solid var(--divider);
}

.exam-review-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 13px;
}

.exam-review-question {
  font-size: 14px;
  font-weight: 600;
}

@media (min-width: 768px) {
  .exam-card {
    padding: 24px;
  }

  .exam-modules {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .exam-option {
    min-height: auto;
  }

  .exam-answer {
    min-height: 44px;
  }

  .exam-count {
    min-height: 40px;
  }

  .exam-footer {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }

  .exam-nav {
    flex-direction: row-reverse;
  }

  .exam-leave {
    min-height: auto;
  }

  .exam-score {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
  }

  .exam-review-item {
    flex-direction: row;
    gap: 12px;
    padding: 14px 20px;
  }

  .exam-review-item .tag {
    flex-shrink: 0;
  }
}

/* Filas de hilo en columnas (nombre, último mensaje, cuántos, sin leer y chincheta) cuando su
   lista mide 640 px o más. Va por el ancho de la lista y no de la ventana, para que en la
   columna estrecha de «Fijados» sigan como en el móvil. */
.item-list {
  container-type: inline-size;
}

@container (min-width: 640px) {
  .thread {
    grid-template-columns: minmax(0, 1fr) 200px 110px 120px 44px;
    gap: 16px;
    padding: 12px 20px;
  }

  .thread-meta {
    display: contents;
  }

  .thread-side {
    grid-column: auto;
    grid-row: auto;
    justify-self: end;
  }
}

/* Enlace «Volver» encima del título. */
.back-link {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 6px;
  min-height: 44px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
}

.back-link:hover {
  color: var(--text);
  text-decoration: none;
}

/* Pie */
.footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 16px;
  border-top: 1px solid var(--border);
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 12px;
}

.footer a {
  /* Zona táctil de 44 px en el móvil sin mover el texto: padding y margen negativo. */
  display: inline-block;
  padding: 13px 0;
  margin: -13px 0;
  color: var(--muted);
}

.footer a:hover {
  color: var(--text);
}

.forums-columns,
.thread-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

@media (min-width: 768px) {
  /* Escritorio: «Volver» se ve como un control (letra de 15 px, icono de 20 px, 40 px de alto). */
  .back-link {
    min-height: 40px;
    font-size: 15px;
  }

  .back-link .icon {
    width: 20px;
    height: 20px;
  }

  .footer a {
    padding: 0;
    margin: 0;
  }

  .button--small {
    min-height: 36px;
  }

  .footer {
    padding: 16px 32px;
  }
}

/* Pantalla ancha: dos columnas en Foros y en el hilo. */
@media (min-width: 1200px) {
  .forums-columns {
    grid-template-columns: minmax(0, 1fr) minmax(340px, 30%);
    grid-template-areas: "all pinned";
  }

  .forums-pinned {
    grid-area: pinned;
  }

  .forums-all {
    grid-area: all;
  }

  /* La respuesta a la derecha, pegada arriba mientras se baja por la conversación. */
  .thread-layout {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 28%);
  }

  .thread-layout > .reply-box {
    position: sticky;
    top: 24px;
  }

  .thread-layout > .reply-box:only-child {
    grid-column: 1 / -1;
  }

  .chat-bubble {
    max-width: 720px;
  }
}

/* Fila de botones de la cabecera del hilo: los tres en una línea y del mismo alto. */
.action-row {
  display: flex;
  gap: 8px;
}

.action-row form {
  margin: 0;
}

/* Fila de hilo estrecha (lista de menos de 640 px): la chincheta a la derecha de las dos
   líneas y los datos solo a la izquierda, para que «N sin leer» no quede pegado a ella. */
@container (max-width: 639.98px) {
  .thread {
    column-gap: 16px;
  }

  .thread-meta {
    grid-column: 1;
  }

  .thread-side {
    grid-row: 1 / span 2;
  }
}

/* Móvil: card de módulo en una sola fila (punto, nombre, avisos y ↗) en vez de apilada. */
@media (max-width: 767.98px) {
  .mod-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 4px 10px;
    padding: 10px 12px 10px 16px;
  }

  /* Los contenedores desaparecen para que sus hijos sean celdas del grid de la card. */
  .mod-card-head,
  .mod-card-title {
    display: contents;
  }

  .mod-card-title h2 {
    font-size: 15px;
  }

  /* Bajo el nombre, en su propia fila y alineado con él (no con el punto). */
  .mod-teachers {
    order: 3;
    grid-column: 2 / -1;
  }

  .mod-updates {
    order: 1;
    flex-wrap: nowrap;
    gap: 2px;
    margin: 0;
    padding: 0;
    border: 0;
  }

  .mod-update {
    padding: 4px 6px;
  }

  .mod-update--on {
    position: relative;
    padding: 3px 8px;
  }

  /* Zona táctil invisible de 44 px; el dibujo de la pastilla no cambia. */
  .mod-update--on::before {
    content: "";
    position: absolute;
    inset: -11px -2px;
  }

  .mod-moodle {
    order: 2;
    margin: -6px -4px -6px 0;
  }

  /* Los tres botones del hilo reparten el ancho. */
  .action-row {
    width: 100%;
  }

  .action-row > * {
    flex: 1 1 auto;
  }

  .action-row .button {
    width: 100%;
    padding: 0 8px;
    white-space: nowrap;
  }
}

/* Movimiento. Solo si el sistema no pide reducirlo; sin animación, todo está en su sitio. */
@media (prefers-reduced-motion: no-preference) {
  /* Transición suave entre páginas (los navegadores que no la tienen, cambian sin más). La
     barra superior y el pie no se mueven. */
  @view-transition {
    navigation: auto;
  }

  .topbar {
    view-transition-name: topbar;
  }

  .footer {
    view-transition-name: footer;
  }

  ::view-transition-old(root) {
    animation: fade-out 0.15s ease both;
  }

  ::view-transition-new(root) {
    animation: rise-in 0.25s ease both;
  }

  /* Entrada escalonada de lo que hay en la página. */
  .page > *,
  .mod-card,
  .course-columns > * {
    animation: rise-in 0.35s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  }

  .page > :nth-child(2) { animation-delay: 0.04s; }
  .page > :nth-child(3) { animation-delay: 0.08s; }
  .page > :nth-child(4) { animation-delay: 0.12s; }
  .page > :nth-child(n + 5) { animation-delay: 0.16s; }

  .mod-card:nth-child(1) { animation-delay: 0.02s; }
  .mod-card:nth-child(2) { animation-delay: 0.06s; }
  .mod-card:nth-child(3) { animation-delay: 0.1s; }
  .mod-card:nth-child(4) { animation-delay: 0.14s; }
  .mod-card:nth-child(5) { animation-delay: 0.18s; }

  /* Las cards se elevan un poco con el glow. */
  .mod-card {
    transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
  }

  .mod-card:hover {
    transform: translateY(-3px);
  }

  /* Burbujas: cada una entra desde su lado. */
  .chat-msg {
    animation: from-left 0.35s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  }

  .chat-msg--own {
    animation-name: from-right;
  }

  .chat-unread span {
    animation: pulse 1.6s ease 0.5s 2;
  }

  /* Botones, chips y filas reaccionan al pasar y al pulsar. */
  .button,
  .chip,
  .icon-button,
  .nav-link,
  .thread,
  .topic > summary {
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease,
      transform 0.1s ease;
  }

  .button:active:not(:disabled),
  .chip:active,
  .icon-button:active {
    transform: scale(0.96);
  }

  .icon-button:hover .icon {
    transform: rotate(-15deg);
  }

  .icon-button .icon {
    transition: transform 0.2s ease;
  }

  /* La flecha de «Volver» se adelanta hacia atrás. */
  .back-link .icon {
    transition: transform 0.2s ease;
  }

  .back-link:hover .icon {
    transform: translateX(-3px);
  }

  /* Desplegables que se abren con suavidad (donde el navegador lo permite). */
  :root {
    interpolate-size: allow-keywords;
  }

  details::details-content {
    height: 0;
    overflow: clip;
    transition: height 0.25s ease, content-visibility 0.25s allow-discrete;
  }

  details[open]::details-content {
    height: auto;
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

@keyframes fade-out {
  to {
    opacity: 0;
  }
}

@keyframes from-left {
  from {
    opacity: 0;
    transform: translateX(-12px);
  }
}

@keyframes from-right {
  from {
    opacity: 0;
    transform: translateX(12px);
  }
}

@keyframes pulse {
  50% {
    opacity: 0.4;
  }
}

/* Tarea y Confirmar entrega (H6f). Provisional: no tienen maqueta. */

/* La miga lleva enlaces con zona táctil de 44 px en el móvil. */
.breadcrumb--links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* Fecha límite con su etiqueta de urgencia, en una línea que baja si no cabe. */
.assignment-due {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  margin: 0;
  color: var(--muted);
}

/* El aviso de borrador y la lista de ficheros comparten bloque: una línea los separa. */
.block-header + .block-body + .item-list,
.item-list + .block-body {
  border-top: 1px solid var(--divider);
}

.upload-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.upload-body > p,
.upload-body > .form-actions {
  margin: 0;
}

.upload-limits {
  font-weight: 600;
}

.upload-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.upload-form .field-hint {
  margin: 0;
}

/* El selector de ficheros: el botón nativo respeta los 16 px y los 44 px del resto de campos. */
.upload-form .field[type="file"] {
  padding: 8px 12px;
}

/* «Se sustituirán: …» ocupa todo el ancho del bloque y parte los nombres largos. */
.replace-note {
  font-weight: 400;
  overflow-wrap: anywhere;
}

.replace-note strong {
  font-weight: 600;
}

/* Lo que hará Moodle al pulsar el botón, antes de los botones. */
.confirm-outcome {
  margin: 0;
}

/* Aprendizaje (H9i). Maqueta Aprendizaje.dc.html. Móvil: una columna, el detalle debajo de la
   lista y las cuatro medidas en 2×2. Las barras son <progress>: la CSP no deja dar el ancho en
   línea. */

.learning-header {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

.learning-header .page-subtitle--small {
  margin-top: 4px;
}

.learning-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.learning-modules {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.learning-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
}

.learning-section-head h2 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.learning-section-head .muted {
  font-size: 12px;
}

.learning-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Tarjeta de módulo: el enlace del nombre se estira a toda la tarjeta. */
.learning-mod {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-block);
  background: var(--bg);
  transition: border-color 0.15s ease, background 0.15s ease;
}

.learning-mod:hover {
  border-color: var(--icon-off);
}

/* El módulo elegido: borde --primary y fondo gris, como en la maqueta. */
.learning-mod:has(.learning-mod-link[aria-current="true"]) {
  border-color: var(--primary);
  background: var(--surface-subtle);
}

.learning-mod:has(.learning-mod-link:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Arriba, para que el punto quede junto a la primera línea de un nombre largo. */
.learning-mod-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

/* Centrado con la primera línea del nombre (14 px × 1,5 = 21 px de alto). */
.learning-mod-head .mod-dot {
  margin-top: 5px;
}

.learning-mod-link {
  flex-grow: 1;
  min-width: 0;
  color: var(--text);
  font-weight: 600;
}

.learning-mod-link:hover,
.learning-mod-link:focus-visible {
  text-decoration: none;
  outline: none;
}

.learning-mod-link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.learning-score {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  flex-shrink: 0;
}

.learning-score-value {
  font-size: 20px;
  font-weight: 600;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.learning-note {
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.learning-measures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 16px;
}

.learning-measure {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.learning-measure-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0 4px;
  font-size: 12px;
}

.learning-measure-value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Barras: pista --track y relleno --accent (la guía: un solo tono, no el del módulo). Las
   medidas, en el gris de la maqueta. */
.learning-bar {
  --bar-fill: var(--accent);
  display: block;
  width: 100%;
  height: 10px;
  border: 0;
  border-radius: 4px;
  background: var(--track);
  color: var(--bar-fill);
  appearance: none;
  overflow: hidden;
}

.learning-bar::-webkit-progress-bar {
  background: var(--track);
}

.learning-bar::-webkit-progress-value {
  border-radius: 4px;
  background: var(--bar-fill);
}

.learning-bar::-moz-progress-bar {
  border-radius: 4px;
  background: var(--bar-fill);
}

.learning-bar--module {
  height: 12px;
}

.learning-bar--measure {
  --bar-fill: var(--icon-off);
  height: 6px;
}

/* Detalle por tema: un bloque con la cabecera gris. */
.learning-detail-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  background: var(--surface-subtle);
  border-bottom: 1px solid var(--border);
}

.learning-detail-head h2 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.learning-detail-module {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 13px;
}

.learning-topics {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 0;
  padding: 16px;
  list-style: none;
}

.learning-topic {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.learning-topic-head {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}

.learning-topic-name {
  min-width: 0;
  overflow-wrap: anywhere;
}

.learning-topic-score {
  flex-shrink: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.learning-empty {
  padding: 16px;
}

.learning-detail-foot {
  padding: 4px 16px;
  border-top: 1px solid var(--divider);
}

/* Enlace del pie con zona táctil de 44 px. */
.learning-detail-foot a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 13px;
  font-weight: 600;
}

/* El detalle trae todos los módulos y solo se ve el elegido (learning.js cambia `hidden`).
   Hace falta decirlo: el display de nuestras clases ganaría al [hidden] del navegador. */
.learning-detail [hidden] {
  display: none;
}

/* Al cambiar de módulo, el detalle nuevo entra con un fundido corto. learning.js pone la clase
   en el primer cambio (así no se ve al cargar la página); desde ahí, la animación vuelve a
   empezar sola cada vez que un detalle deja de estar oculto. Las barras de los temas las hace
   crecer learning.js. */
@media (prefers-reduced-motion: no-preference) {
  .learning-detail--switching .learning-detail-body {
    animation: learning-fade-in 0.2s ease both;
  }
}

@keyframes learning-fade-in {
  from {
    opacity: 0;
  }
}

@media (min-width: 560px) {
  .learning-measures {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (min-width: 768px) {
  .learning-header {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
  }

  .learning-header .button {
    min-height: 40px;
    white-space: nowrap;
  }

  .learning-mod {
    padding: 16px 20px;
  }

  .learning-detail-head,
  .learning-topics {
    padding-inline: 20px;
  }

  .learning-detail-foot {
    padding: 4px 20px 8px;
  }
}

@media (min-width: 1024px) {
  .learning-layout {
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  }
}

/* Escala general
   Todos los tamaños están en px, así que en pantallas anchas se escala con `zoom` del
   documento: una sola variable (--ui-zoom) hace crecer letra, espaciados, cards y botones
   a la vez. Por debajo de 1280 px no cambia nada. Todo va dentro de @supports: si el
   navegador no tiene `zoom`, --ui-zoom no existe y el min-height del body (que divide entre
   --ui-zoom, con 1 por defecto) tampoco se divide. */
@supports (zoom: 1) {
  @media (min-width: 1280px) {
    :root {
      --ui-zoom: 1.12;
    }
  }

  @media (min-width: 1600px) {
    :root {
      --ui-zoom: 1.15;
    }
  }

  html {
    zoom: var(--ui-zoom, 1);
  }
}
