/* ==========================================================================
   NextPatch — estilos compartidos de la zona learner
   (home, mapa de niveles, lección, clasificación, perfil)
   Paleta: primario índigo #635BFF, acento coral #FF7A59, fondo oscuro #12141D.
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

:root {
  --np-bg: #12141d;
  --np-surface: #1b1e2b;
  --np-surface-2: #232738;
  --np-border: #2e3347;
  --np-text: #eceef6;
  --np-text-soft: #cbd0df;
  --np-muted: #9aa0b5;
  --np-primary: #635bff;
  --np-primary-soft: rgba(99, 91, 255, 0.16);
  --np-accent: #ff7a59;
  --np-ok: #3ecf8e;
  --np-ok-soft: rgba(62, 207, 142, 0.14);
  --np-bad: #ff5d73;
  --np-bad-soft: rgba(255, 93, 115, 0.14);
  /* Estado hover/activo: NO es una versión traslúcida del coral. El coral
     queda reservado a los momentos de energía (racha, XP, celebración); el
     hover de botones y controles se resuelve con estas tres variables. */
  --np-primary-hover: #756eff;
  --np-primary-soft-weak: rgba(99, 91, 255, 0.08);
  --np-surface-3: #2a2f45;
  --np-radius-sm: 8px;
  --np-radius-md: 12px;
  --np-radius-lg: 16px;
  --np-space-1: 4px;
  --np-space-2: 8px;
  --np-space-3: 12px;
  --np-space-4: 16px;
  --np-space-5: 24px;
  --np-space-6: 32px;
  --np-space-7: 48px;
  --np-space-8: 64px;
  --np-leading-body: 1.65;
  --np-leading-tight: 1.2;
  --np-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}

html,
body {
  margin: 0;
  min-height: 100%;
}

body {
  font-family: 'Outfit', system-ui, sans-serif;
  background: var(--np-bg);
  color: var(--np-text);
  font-size: 15px;
  line-height: var(--np-leading-body);
  /* Evita que iOS agrande la tipografía al girar el móvil y que un título o
     una URL sin espacios desborde el ancho de la pantalla. */
  -webkit-text-size-adjust: 100%;
  overflow-wrap: break-word;
  /* Columna topbar → main → footer, para que el pie quede abajo del todo
     también en las páginas con poco contenido (ver `.page { flex: 1 }`). */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

img {
  max-width: 100%;
}

code,
pre,
textarea.code,
input.blank {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}

a {
  color: inherit;
}

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--np-accent);
  outline-offset: 3px;
}

/* Barra superior ---------------------------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  gap: var(--np-space-6);
  padding: var(--np-space-3) var(--np-space-6);
  border-bottom: 1px solid var(--np-border);
  background: rgba(18, 20, 29, 0.9);
  position: sticky;
  top: 0;
  z-index: 10;
}

/* Logo: lo comparten la barra superior y el pie, así que la base vive en
   `.brand` y cada contenedor solo ajusta el tamaño. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  font-family: 'Outfit', sans-serif;
  font-weight: 600;
  font-size: 16px;
}

.topbar .brand {
  font-size: 18px;
}

.brand__mark {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  background: var(--np-primary);
  color: #fff;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
}

/* `display: contents` hace que nav/spacer/avatar/logout sigan siendo hijos
   flex del header: en escritorio el envoltorio es invisible para el layout.
   Por debajo de 860px pasa a ser el panel desplegable (ver media query). */
.topbar__menu {
  display: contents;
}

/* Hamburguesa: oculta en escritorio, la muestra la media query. */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 42px;
  height: 42px;
  padding: 0;
  background: none;
  border: 1px solid var(--np-border);
  border-radius: 10px;
  cursor: pointer;
}

.nav-toggle__bar {
  display: block;
  width: 18px;
  height: 2px;
  margin: 0 auto;
  border-radius: 2px;
  background: var(--np-text);
  transition: transform 0.2s ease, opacity 0.2s ease;
}

/* Aspa cuando el menú está abierto. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

.topbar nav {
  display: flex;
  gap: 4px;
}

.topbar nav a {
  text-decoration: none;
  color: var(--np-muted);
  padding: 8px 14px;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 600;
}

.topbar nav a:hover,
.topbar nav a.is-active {
  color: var(--np-text);
  background: var(--np-surface-2);
}

.topbar__spacer {
  flex: 1;
}

.nav-icon {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
}

/* La etiqueta del avatar solo hace falta en el menú móvil: en escritorio el
   icono va suelto en la barra y se entiende por sí solo. */
.nav-profile-label {
  display: none;
}

.logout-form {
  margin: 0;
}

.logout-form button {
  background: none;
  border: 1px solid var(--np-border);
  color: var(--np-muted);
  border-radius: 8px;
  padding: 8px 14px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

.logout-form button:hover {
  color: var(--np-text);
  border-color: var(--np-muted);
}

/* Pie de página ------------------------------------------------------------ */

.footer {
  border-top: 1px solid var(--np-border);
  background: var(--np-surface);
  padding: var(--np-space-4) var(--np-space-6) var(--np-space-3);
  font-size: 14px;
}

/* Sin `max-width`: el pie ocupa todo el ancho con el mismo acolchado lateral
   que la barra superior, en vez de ceñirse a los 1000px del contenido. */
.footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 28px;
}

/* Logo y lema en la misma línea: es lo que mantiene el pie bajo. */
.footer__brand {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 14px;
}

/* El logo del pie usa el tamaño base de `.brand`, con el cuadro algo menor. */
.footer .brand__mark {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  font-size: 12px;
}

.footer__tagline {
  color: var(--np-muted);
  margin: 0;
  line-height: 1.4;
  font-size: 13px;
}

/* Enlaces en fila: apilados eran cuatro líneas de altura. */
.footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
}

.footer__nav a {
  color: var(--np-muted);
  text-decoration: none;
  font-weight: 600;
}

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

.footer__bottom {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--np-border);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  color: var(--np-muted);
  font-size: 12px;
}

.footer__beta {
  background: var(--np-primary-soft);
  border: 1px solid var(--np-primary);
  border-radius: 99px;
  padding: 2px 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* Layout ------------------------------------------------------------------ */

.page {
  max-width: 1040px;
  margin: 0 auto;
  padding: var(--np-space-7) var(--np-space-5) var(--np-space-8);
  /* Empuja el footer al fondo cuando el contenido no llena la pantalla. */
  flex: 1;
  width: 100%;
}

/* Variante ancha (home): en vez de los 1000px del resto, ocupa el 85% de la
   pantalla. En móvil vuelve al ancho completo (ver media query). */
.page--wide {
  max-width: 85%;
}

.page h1 {
  font-family: 'Outfit', sans-serif;
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  line-height: var(--np-leading-tight);
  letter-spacing: -0.02em;
  margin: 0 0 var(--np-space-2);
}

.page .subtitle {
  color: var(--np-muted);
  max-width: 65ch;
  margin: 0 0 var(--np-space-6);
  font-size: 1rem;
  line-height: 1.55;
}

.grid {
  display: grid;
  gap: var(--np-space-4);
}

/* El `min(…, 100%)` evita que la columna mínima sea más ancha que la pantalla
   (en un móvil de 320px, un minmax(280px) fijo desborda por el padding). */
.grid--cards {
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
}

/* Rejilla fija de dos columnas: las tarjetas se acumulan de dos en dos por
   fila y cada una ocupa media anchura, sin importar cuántas haya. En móvil
   pasa a una sola columna (ver media query). */
.grid--cards-2 {
  grid-template-columns: repeat(2, 1fr);
}

/* Tarjetas y stats --------------------------------------------------------- */

.card {
  background: var(--np-surface);
  border: 1px solid var(--np-border);
  border-radius: 10px;
  padding: var(--np-space-5);
}

.card h3 {
  margin: 0 0 var(--np-space-2);
  font-size: 1.05rem;
  line-height: 1.35;
}

.card .muted {
  color: var(--np-muted);
  font-size: 0.9rem;
  line-height: 1.55;
}

/* Tarjeta grande (home): más aire y una altura mínima común para que las dos
   de cada fila queden iguales aunque el título ocupe una línea o dos.
   Va después de `.card h3` para ganarle el tamaño de fuente. */
.card--lg {
  display: flex;
  flex-direction: column;
  min-height: 190px;
  padding: 26px;
  color: var(--np-text);
  transition: transform 150ms ease, background-color 150ms ease,
    border-color 150ms ease, box-shadow 150ms ease, color 150ms ease;
}

.card--lg h3 {
  font-size: 19px;
}

/* La tarjeta de ruta es el clic más repetido de la app (volver cada día),
   así que es de los pocos sitios donde el coral gana protagonismo de verdad
   en el hover: una veladura cálida y un resplandor de borde, sin invertir el
   fondo ni bajar la opacidad (eso apagaba el texto en vez de realzarlo). */
@media (hover: hover) and (pointer: fine) {
  .card--lg:hover {
    background: linear-gradient(135deg, rgba(255, 122, 89, 0.14), var(--np-surface) 65%);
    border-color: var(--np-accent);
    transform: translateY(-2px);
    box-shadow: 0 18px 34px -14px rgba(255, 122, 89, 0.4);
  }
}

.card--lg:active {
  transform: translateY(1px) scale(0.985);
  transition-duration: 120ms;
}

@media (prefers-reduced-motion: reduce) {
  .card--lg {
    transition: background-color 150ms ease, border-color 150ms ease,
      color 150ms ease;
  }

  .card--lg:hover,
  .card--lg:active {
    transform: none;
  }
}

/* La barra de progreso se pega abajo: así queda alineada entre las dos
   tarjetas de la misma fila. */
.card--lg .progress {
  margin-top: auto;
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: var(--np-space-4);
  margin-bottom: var(--np-space-7);
}

.stat {
  background: var(--np-surface);
  border: 1px solid var(--np-border);
  border-radius: 10px;
  padding: var(--np-space-4) var(--np-space-5);
}

.stat__value {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 7px;
  font-family: 'Outfit', sans-serif;
  font-size: 26px;
  font-weight: 600;
}

/* Icono de una cifra (racha, XP, lecciones…): mismo tamaño de línea que el
   número, sin el margen de `.np-icon` genérico (pensado para texto corrido,
   no para ir pegado a una cifra grande). El color lo decide cada llamada con
   --np-icon-color; por defecto hereda el primario. */
.stat__value .np-icon {
  margin-right: 0;
  width: var(--np-icon-size, 0.8em);
  height: var(--np-icon-size, 0.8em);
}

.stat__label {
  color: var(--np-muted);
  font-size: 13px;
  margin-top: 4%;
}

/* Variante de la home: rótulo arriba, cifra grande abajo y todo centrado, sin
   iconos. El orden lo da el HTML (home.js pinta antes el rótulo); aquí solo se
   centra y se agranda. El perfil sigue usando `.stats-row` a secas. */
.stats-row--centered .stat {
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  padding: 20px;
}

.stats-row--centered .stat__label {
  margin: 0 0 8px;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.stats-row--centered .stat__value {
  display: flex;
  justify-content: center;
  font-size: 38px;
  line-height: 1.1;
}

.continue-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  background: linear-gradient(120deg, rgba(99, 91, 255, 0.25), rgba(255, 122, 89, 0.12));
  border: 1px solid var(--np-primary);
  border-radius: 14px;
  padding: 20px;
  margin-bottom: 28px;
}

/* «Mis rutas»: elegir a qué transiciones se apunta el usuario --------------- */
.enroll-group {
  margin-bottom: 18px;
}

.enroll-group__title {
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--np-muted);
  margin: 0 0 12px;
}

.enroll-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--np-border);
  cursor: pointer;
}

.enroll-item:last-child {
  border-bottom: none;
}

.enroll-item__check {
  margin-top: 4px;
  width: 18px;
  height: 18px;
  accent-color: var(--np-primary);
  flex-shrink: 0;
  cursor: pointer;
}

.enroll-item__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1;
}

.enroll-item__title {
  font-weight: 600;
}

.enroll-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 8px;
}

/* Botones ------------------------------------------------------------------ */

.btn {
  display: inline-block;
  border: none;
  border-radius: 10px;
  min-height: 44px;
  padding: 10px 18px;
  font: inherit;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.25;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
}

.btn--primary {
  background: var(--np-primary);
  color: #fff;
  box-shadow: 0 8px 20px rgba(99, 91, 255, 0.2);
}

.btn--ghost {
  background: var(--np-surface-2);
  color: var(--np-text);
  border: 1px solid var(--np-border);
}

.btn:not(:disabled),
.option,
.ob-option,
.donate-preset,
.lesson-node:not(.lesson-node--locked),
.tabs button,
.order-line button,
.nav-toggle,
.ob-back,
.ob-skip,
.topbar nav a,
.logout-form button,
.footer__nav a {
  transition: transform 150ms ease, background-color 150ms ease,
    border-color 150ms ease, color 150ms ease, opacity 150ms ease;
}

/* Cada familia de control tiene su propio hover con su propio significado:
   el coral no es un "modo hover" universal, es el color de la energía
   (racha, XP, celebración). Aquí el color enseña qué va a pasar. */
@media (hover: hover) and (pointer: fine) {
  /* Acción primaria: el índigo se aclara y el botón sube; nunca cambia de
     color, porque sigue siendo la misma acción. */
  .btn--primary:not(:disabled):hover {
    background: var(--np-primary-hover);
    box-shadow: 0 10px 26px rgba(99, 91, 255, 0.34);
    transform: translateY(-1px);
  }

  /* Controles secundarios/neutros: solo borde y superficie, sin acento. */
  .btn--ghost:not(:disabled):hover,
  .nav-toggle:hover,
  .ob-back:hover,
  .ob-skip:hover,
  .logout-form button:hover,
  .order-line button:hover,
  .tabs button:hover {
    background: var(--np-surface-3);
    border-color: var(--np-muted);
    color: var(--np-text);
    transform: translateY(-1px);
  }

  /* Opciones de reto, de onboarding y presets de donación: el hover
     anticipa en índigo suave el mismo aspecto que tendrán al elegirlos
     (".is-selected"), así el color informa en vez de decorar. */
  .option:hover,
  .ob-option:hover,
  .donate-preset:hover {
    border-color: var(--np-primary);
    background: var(--np-primary-soft-weak);
    transform: translateY(-1px);
  }

  /* Nodo de lección: es un paso en el camino, no un botón, así que avanza
     en horizontal en vez de subir, y marca el borde en índigo. */
  .lesson-node:not(.lesson-node--locked):hover {
    border-color: var(--np-primary);
    transform: translateX(3px);
  }

  /* Enlaces de navegación: ya tienen su propio color/fondo de hover junto a
     cada componente; aquí solo se añade el mismo lift sutil del resto. */
  .topbar nav a:hover,
  .footer__nav a:hover {
    transform: translateY(-1px);
  }
}

.btn:not(:disabled):active,
.option:active,
.ob-option:active,
.donate-preset:active,
.lesson-node:not(.lesson-node--locked):active,
.tabs button:active,
.order-line button:active,
.nav-toggle:active,
.ob-back:active,
.ob-skip:active,
.topbar nav a:active,
.logout-form button:active,
.footer__nav a:active {
  transform: translateY(1px) scale(0.985);
  transition-duration: 120ms;
}

@media (prefers-reduced-motion: reduce) {
  .btn:not(:disabled),
  .option,
  .ob-option,
  .donate-preset,
  .lesson-node:not(.lesson-node--locked),
  .tabs button,
  .order-line button,
  .nav-toggle,
  .ob-back,
  .ob-skip,
  .topbar nav a,
  .logout-form button,
  .footer__nav a {
    transition: background-color 150ms ease, border-color 150ms ease,
      color 150ms ease, opacity 150ms ease;
  }

  .btn:not(:disabled):hover,
  .option:hover,
  .ob-option:hover,
  .donate-preset:hover,
  .lesson-node:not(.lesson-node--locked):hover,
  .tabs button:hover,
  .order-line button:hover,
  .nav-toggle:hover,
  .ob-back:hover,
  .ob-skip:hover,
  .topbar nav a:hover,
  .logout-form button:hover,
  .footer__nav a:hover,
  .btn:not(:disabled):active,
  .option:active,
  .ob-option:active,
  .donate-preset:active,
  .lesson-node:not(.lesson-node--locked):active,
  .tabs button:active,
  .order-line button:active,
  .nav-toggle:active,
  .ob-back:active,
  .ob-skip:active,
  .topbar nav a:active,
  .logout-form button:active,
  .footer__nav a:active {
    transform: none;
  }
}

/* Deshabilitado: gris plano, no el color de acción atenuado. Bloquea el avance
   de un formulario hasta que esté completo (ver onboarding.js). */
.btn:disabled {
  background: var(--np-surface-2);
  color: var(--np-muted);
  border: 1px solid var(--np-border);
  cursor: not-allowed;
}

/* Barras de progreso -------------------------------------------------------- */

.progress {
  height: 8px;
  border-radius: 99px;
  background: var(--np-surface-2);
  overflow: hidden;
  margin-top: 12px;
}

.progress__fill {
  height: 100%;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--np-primary), var(--np-accent));
  transition: width 0.4s ease;
}

/* Mapa de niveles ------------------------------------------------------------ */

.unit {
  margin-bottom: 26px;
}

.unit__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}

.unit__head h2 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'Outfit', sans-serif;
  font-size: 19px;
  margin: 0;
}

.unit__bonus {
  color: var(--np-accent);
  font-size: 13px;
  font-weight: 600;
}

/* Estado de la unidad: el mismo lenguaje visual del nodo de lección, en
   miniatura, en vez del prefijo de emoji (🔒/🔓/✅) — un emoji cambia de
   trazo y hasta de color entre sistemas operativos; este aro no. */
.unit__status {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1.5px solid var(--np-border);
  background: var(--np-surface-2);
  flex: none;
}

.unit__status--unlocked {
  border-color: var(--np-primary);
  background: var(--np-surface);
}

.unit__status--completed {
  border-color: var(--np-ok);
  background: var(--np-ok-soft);
}

.unit__status--completed::before {
  content: '';
  width: 8px;
  height: 5px;
  border-left: 1.5px solid var(--np-ok);
  border-bottom: 1.5px solid var(--np-ok);
  transform: rotate(-45deg) translate(1px, -1px);
}

.unit__status--locked::before {
  content: '';
  width: 9px;
  height: 9px;
  background-color: var(--np-muted);
  -webkit-mask: url('/icons/np/llave.svg') center / contain no-repeat;
  mask: url('/icons/np/llave.svg') center / contain no-repeat;
}

.lesson-node {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--np-surface);
  border: 1px solid var(--np-border);
  border-radius: 12px;
  padding: 14px 18px;
  margin-bottom: 10px;
  text-decoration: none;
}

.lesson-node--unlocked {
  border-color: var(--np-primary);
}

.lesson-node--locked {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Icono de estado del nodo: aro vacío (disponible), aro relleno con pulso
   (en curso), llave apagada (bloqueada) o check dibujado en CSS (completada).
   Reemplaza los emoji 🔒/🔓/✏️/✅, que no forman parte del set de iconos de
   la marca y varían de aspecto entre sistemas. */
.lesson-node__icon {
  position: relative;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--np-surface-2);
  border: 1.5px solid var(--np-border);
  flex: none;
}

.lesson-node__icon--locked::before {
  content: '';
  width: 14px;
  height: 14px;
  background-color: var(--np-muted);
  -webkit-mask: url('/icons/np/llave.svg') center / contain no-repeat;
  mask: url('/icons/np/llave.svg') center / contain no-repeat;
}

.lesson-node__icon--unlocked {
  background: var(--np-surface);
  border-color: var(--np-primary);
}

.lesson-node__icon--in-progress {
  background: var(--np-primary);
  border-color: var(--np-primary);
  animation: lesson-node-pulse 2.2s ease-out infinite;
}

.lesson-node__icon--in-progress::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #fff;
}

@keyframes lesson-node-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(99, 91, 255, 0.45);
  }
  70% {
    box-shadow: 0 0 0 9px rgba(99, 91, 255, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(99, 91, 255, 0);
  }
}

.lesson-node__icon--completed {
  background: var(--np-ok-soft);
  border-color: var(--np-ok);
}

.lesson-node__icon--completed::before {
  content: '';
  width: 12px;
  height: 7px;
  border-left: 2px solid var(--np-ok);
  border-bottom: 2px solid var(--np-ok);
  transform: rotate(-45deg) translate(1px, -1px);
}

@media (prefers-reduced-motion: reduce) {
  .lesson-node__icon--in-progress {
    animation: none;
  }
}

/* El título es el segundo span: sin `min-width: 0` un flex item no baja de su
   contenido y un título largo desborda la tarjeta. */
.lesson-node > span:nth-child(2) {
  min-width: 0;
}

.lesson-node__xp {
  margin-left: auto;
  color: var(--np-muted);
  font-size: 13px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Contenido de lección -------------------------------------------------------- */

.lesson-content h2 {
  font-family: 'Outfit', sans-serif;
  font-size: 20px;
}

.lesson-content p,
.lesson-content li {
  max-width: 72ch;
  line-height: var(--np-leading-body);
  color: var(--np-text-soft);
}

.lesson-content p + p,
.lesson-content ul + p,
.lesson-content p + ul {
  margin-top: var(--np-space-4);
}

.lesson-content code {
  background: var(--np-surface-2);
  border-radius: 5px;
  padding: 1px 6px;
  font-size: 0.9em;
  overflow-wrap: anywhere;
}

pre.code,
.lesson-content pre {
  background: #0d0f16;
  border: 1px solid var(--np-border);
  border-radius: 10px;
  padding: 14px 16px;
  overflow-x: auto;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.lesson-content pre code {
  background: none;
  padding: 0;
}

.compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin: 20px 0;
}

@media (max-width: 760px) {
  .compare {
    grid-template-columns: 1fr;
  }
}

.compare__col h4 {
  margin: 0 0 8px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.compare__col--before h4 {
  color: var(--np-bad);
}

.compare__col--after h4 {
  color: var(--np-ok);
}

/* Player de retos -------------------------------------------------------------- */

.challenge-box {
  background: var(--np-surface);
  border: 1px solid var(--np-border);
  border-radius: 10px;
  padding: var(--np-space-6);
  margin-top: var(--np-space-6);
  max-width: 100%;
  overflow: hidden;
}

.challenge-box .prompt {
  font-weight: 600;
  margin-bottom: 16px;
}

.challenge-body {
  width: 100%;
  min-width: 0;
}

.challenge-body__renderer {
  width: 100%;
  min-width: 0;
}

.challenge-progress {
  color: var(--np-muted);
  font-size: 13px;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* Botón de ayuda que recuerda la teoría al pasar el ratón / enfocar. */
.theory-help {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  cursor: help;
}

.theory-help__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--np-primary-soft);
  border: 1px solid var(--np-primary);
  color: var(--np-primary);
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-weight: 600;
  font-size: 14px;
  line-height: 1;
  user-select: none;
}

.theory-help__tip {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 20;
  width: min(360px, 78vw);
  padding: 14px 16px;
  background: var(--np-surface-2);
  border: 1px solid var(--np-border);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  color: var(--np-text);
  font-size: 13px;
  text-align: left;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
}

.theory-help__tip::before {
  content: "";
  position: absolute;
  top: -6px;
  right: 6px;
  width: 12px;
  height: 12px;
  background: var(--np-surface-2);
  border-left: 1px solid var(--np-border);
  border-top: 1px solid var(--np-border);
  transform: rotate(45deg);
}

.theory-help__tip strong {
  color: var(--np-primary);
}

.theory-help:hover .theory-help__tip,
.theory-help:focus-within .theory-help__tip {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* Dentro del tooltip la teoría va compacta (sin márgenes grandes). */
.theory-help__tip .lesson-content p:first-child {
  margin-top: 4px;
}
.theory-help__tip .lesson-content p:last-child {
  margin-bottom: 0;
}

.options {
  display: grid;
  /* minmax(0, 1fr) y no 1fr: una opcion con un token largo
     (CompletableFuture<HttpResponse<T>>) ensancharia la columna y el texto
     acabaria recortado por el overflow:hidden de .challenge-box. */
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
}

.option {
  text-align: left;
  background: var(--np-surface-2);
  border: 1px solid var(--np-border);
  color: var(--np-text);
  border-radius: 10px;
  padding: 12px 16px;
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  /* El texto de una opcion fluye en varias lineas; los identificadores de
     Java, que no llevan espacios, se parten antes que desbordar. */
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.5;
  min-width: 0;
}

.challenge-body__renderer--options .option pre {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.option:hover {
  border-color: var(--np-primary);
}

.option.is-selected {
  border-color: var(--np-primary);
  background: var(--np-primary-soft);
}

.challenge-body__renderer--fill {
  display: block;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
}

input.blank {
  background: #0d0f16;
  border: 1px solid var(--np-primary);
  border-radius: 6px;
  color: var(--np-text);
  padding: 2px 8px;
  font-size: 13px;
  width: 110px;
  max-width: 100%;
  min-width: 72px;
}

input.blank:focus {
  outline: 2px solid var(--np-primary-soft);
}

textarea.code {
  width: 100%;
  min-height: 180px;
  background: #0d0f16;
  border: 1px solid var(--np-border);
  border-radius: 10px;
  color: var(--np-text);
  padding: 14px 16px;
  font-size: 13px;
  line-height: 1.6;
  resize: vertical;
}

.challenge-body__renderer--order {
  display: grid;
  gap: 8px;
}

.order-line {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--np-surface-2);
  border: 1px solid var(--np-border);
  border-radius: 8px;
  padding: 8px 12px;
  margin-bottom: 0;
  min-width: 0;
}

.order-line pre {
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  font-size: 13px;
}

.order-line button {
  background: none;
  border: 1px solid var(--np-border);
  color: var(--np-muted);
  border-radius: 6px;
  width: 28px;
  height: 28px;
  cursor: pointer;
}

.order-line button:hover {
  color: var(--np-text);
}

.feedback {
  margin-top: 18px;
  border-radius: 10px;
  padding: 14px 16px;
  font-size: 14px;
}

.feedback--ok {
  background: var(--np-ok-soft);
  border: 1px solid var(--np-ok);
}

.feedback--bad {
  background: var(--np-bad-soft);
  border: 1px solid var(--np-bad);
}

.challenge-body__renderer--fix {
  display: block;
}

.challenge-body__renderer--fix textarea.code {
  display: block;
  width: 100%;
  min-height: 220px;
}

.player-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--np-space-3);
  margin-top: var(--np-space-5);
}

@media (max-width: 760px) {
  .page {
    padding: var(--np-space-6) var(--np-space-4) var(--np-space-8);
  }

  .challenge-box {
    padding: var(--np-space-5) var(--np-space-4);
  }

  .challenge-progress {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .challenge-body__renderer--options {
    grid-template-columns: minmax(0, 1fr);
  }

  .challenge-body__renderer--fill {
    font-size: 12px;
  }

  .challenge-body__renderer--fill input.blank {
    width: min(120px, 40vw);
  }

  .challenge-body__renderer--order .order-line {
    flex-wrap: wrap;
    padding: 10px 10px 8px;
  }

  .challenge-body__renderer--order .order-line pre {
    width: 100%;
    min-width: 0;
    flex-basis: 100%;
  }

  .challenge-body__renderer--order .order-line button {
    flex: 1;
    min-width: 40px;
  }

  .option {
    padding: 12px 14px;
  }

  .feedback {
    padding: 12px 14px;
  }
}

/* Resultado de lección ----------------------------------------------------------- */

.result {
  text-align: center;
  padding: 48px 24px;
}

@keyframes lesson-complete-in {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.result--completed {
  animation: lesson-complete-in 240ms cubic-bezier(0.23, 1, 0.32, 1) both;
  color: var(--np-ok);
}

.result__celebration {
  position: relative;
  width: 92px;
  height: 92px;
  margin: 0 auto 18px;
  display: grid;
  place-items: center;
  border: 2px solid var(--np-ok);
  border-radius: 50%;
  background: var(--np-ok-soft);
  animation: celebration-pop 280ms cubic-bezier(0.23, 1, 0.32, 1) 50ms both;
}

.result__check {
  font-size: 52px;
  font-weight: 700;
  line-height: 1;
  color: var(--np-ok);
}

.result__congrats {
  margin: 0 0 6px;
  color: var(--np-ok);
  font-size: 18px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.result--completed .result__xp {
  animation: lesson-complete-in 240ms cubic-bezier(0.23, 1, 0.32, 1) 100ms both;
  color: var(--np-ok);
}

.result--completed h1,
.result--completed p:not(.muted) {
  color: var(--np-ok);
}

.result--completed .btn--primary {
  border: 1px solid var(--np-primary-soft);
  background: var(--np-primary);
}

.result__spark {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--np-ok);
  animation: spark-burst 420ms cubic-bezier(0.23, 1, 0.32, 1) 90ms both;
}

.result__spark--1 { --spark-x: -42px; --spark-y: -22px; }
.result__spark--2 { --spark-x: 38px; --spark-y: -28px; }
.result__spark--3 { --spark-x: 48px; --spark-y: 12px; }
.result__spark--4 { --spark-x: -46px; --spark-y: 18px; }
.result__spark--5 { --spark-x: -20px; --spark-y: 42px; }
.result__spark--6 { --spark-x: 18px; --spark-y: 42px; }

@keyframes celebration-pop {
  from {
    opacity: 0;
    transform: scale(0.94);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes spark-burst {
  from {
    opacity: 0;
    transform: translate(0, 0) scale(0.6);
  }
  to {
    opacity: 1;
    transform: translate(var(--spark-x), var(--spark-y)) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .result--completed,
  .result--completed .result__xp,
  .result__celebration,
  .result__spark {
    animation: lesson-complete-fade 160ms ease-out both;
  }
}

@keyframes lesson-complete-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.result .big-xp {
  font-family: 'Outfit', sans-serif;
  font-size: 44px;
  font-weight: 600;
  color: var(--np-accent);
}

.result--completed .big-xp {
  color: var(--np-ok);
}

.result--completed .badge-pill {
  background: var(--np-ok-soft);
  border-color: var(--np-ok);
  color: var(--np-ok);
}

.badge-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--np-primary-soft);
  border: 1px solid var(--np-primary);
  border-radius: 99px;
  padding: 6px 14px;
  margin: 4px;
  font-size: 13px;
  font-weight: 200;
  color: var(--np-accent);
}

/* El icono toma el color del texto de la píldora (currentColor): así hereda
   automáticamente el índigo normal o el verde de `.result--completed`, sin
   necesidad de una variante por color. */
.badge-pill .np-icon {
  margin-right: 0;
  width: 14px;
  height: 14px;
  background-color: currentColor;
}

.status-select {
  display: inline-block;
  background: var(--np-primary-soft);
  border: 1px solid var(--np-primary);
  border-radius: 99px;
  padding: 6px 12px;
  margin: 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--np-text);
  cursor: pointer;
}

/* Tablas (leaderboard) ------------------------------------------------------------ */

table.board {
  width: 100%;
  border-collapse: collapse;
  background: var(--np-surface);
  border: 1px solid var(--np-border);
  border-radius: 14px;
  overflow: hidden;
}

.board th,
.board td {
  text-align: left;
  padding: 12px 18px;
  border-bottom: 1px solid var(--np-border);
  font-size: 14px;
}

.board th {
  color: var(--np-muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.board tr.is-me td {
  background: var(--np-primary-soft);
  font-weight: 600;
}

/* XP con estrella: si el icono y la cifra se alinean a la derecha como un
   solo bloque, la estrella se desplaza fila a fila segun los digitos de XP
   (85 frente a 1240). Con el numero a ancho minimo fijo, la estrella queda
   siempre en la misma columna. */
.xp-cell {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
}

.xp-cell .np-icon {
  margin-right: 0;
}

.xp-cell__value {
  min-width: 3.5ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Puesto del ranking: un aro numerado, la misma familia visual que
   `.unit__status` y `.lesson-node__icon` (nunca un emoji de medalla, que
   cambia de trazo y color entre sistemas). El top 3 gana un aro de color;
   del 4º en adelante el aro queda neutro y solo cuenta el número. */
.rank-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1.5px solid var(--np-border);
  background: var(--np-surface-2);
  color: var(--np-muted);
  font-family: 'Outfit', sans-serif;
  font-size: 13px;
  font-weight: 700;
}

.rank-badge--gold {
  border-color: #e0b64c;
  background: rgba(224, 182, 76, 0.14);
  color: #e0b64c;
}

.rank-badge--silver {
  border-color: #b9c1d1;
  background: rgba(185, 193, 209, 0.14);
  color: #d7dbe6;
}

.rank-badge--bronze {
  border-color: #c98455;
  background: rgba(201, 132, 85, 0.14);
  color: #d99a6c;
}

.tabs {
  display: inline-flex;
  flex-wrap: wrap;
  max-width: 100%;
  background: var(--np-surface);
  border: 1px solid var(--np-border);
  border-radius: 10px;
  padding: 4px;
  margin-bottom: 20px;
}

.tabs button {
  border: none;
  background: none;
  color: var(--np-muted);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 7px;
  cursor: pointer;
}

.tabs button.is-active {
  background: var(--np-primary);
  color: #fff;
}

/* Utilidades ------------------------------------------------------------------ */

/* Icono SVG de /icons en línea con un texto (cifras de stats, etiquetas…).
   Va con `mask` y no con <img> a propósito: los ficheros de /icons usan
   fill="currentColor", que un <img> no resuelve y saldría negro sobre el fondo
   oscuro. Aquí el color lo pone el `background-color`, así que el icono sale
   siempre en el primario de la marca.

   Uso:  <span class="np-icon" style="--np-icon: url('/icons/np/fill/maletin.svg')"></span>
   Tamaño: 20px por defecto; se ajusta con --np-icon-size en el mismo style.
   El color se puede cambiar en un caso puntual con --np-icon-color. */
.np-icon {
  display: inline-block;
  flex: none;
  width: var(--np-icon-size, 40px);
  height: var(--np-icon-size, 40px);
  margin-right: 8%;
  vertical-align: -0.18em;
  background-color: var(--np-icon-color, var(--np-primary));
  -webkit-mask: var(--np-icon) center / contain no-repeat;
  mask: var(--np-icon) center / contain no-repeat;
}

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

.loading {
  color: var(--np-muted);
  padding: 40px 0;
  text-align: center;
}

.error-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 20px;
  background: var(--np-bad-soft);
  border: 1px solid var(--np-bad);
  border-radius: 10px;
  padding: 14px 16px;
  margin: 20px 0;
}

.error-box__message {
  flex: 1 1 240px;
  margin: 0;
}

.error-box__retry {
  flex: none;
}

/* Aviso informativo (no es un error): banda suave con icono a la izquierda.
   La usa la home para avisar de que puede haber lecciones que todavia no
   estan traducidas al idioma del usuario. */
.notice {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--np-primary-soft);
  border: 1px solid var(--np-border);
  border-left: 3px solid var(--np-primary);
  border-radius: 10px;
  padding: 14px 16px;
  margin: 20px 0;
}

/* El margen del .np-icon generico (8%) descuadra el flex: aqui manda el gap. */
.notice .np-icon {
  margin-right: 0;
  margin-top: 1px;
}

.notice__title {
  margin: 0 0 2px;
  font-size: 15px;
  font-weight: 600;
}

.notice__text {
  margin: 0;
  color: var(--np-muted);
  font-size: 14px;
}

/* Perfil: cabecera y formularios de edición ------------------------------- */

.profile-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 24px;
}

.profile-head__avatar {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--np-border);
  background: var(--np-surface-2);
  flex: none;
}

.settings-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
}

.avatar-edit {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
}

/* Input de fichero del avatar (#avatarFile): fondo oscuro y letra blanca,
   incluido el botón nativo "Seleccionar archivo" del navegador. */
.field input[type="file"] {
  background: var(--np-surface-2);
  color: var(--np-text);
  cursor: pointer;
}

.field input[type="file"]::file-selector-button {
  background: #0d0f16;
  color: var(--np-text);
  border: 1px solid var(--np-border);
  border-radius: 8px;
  padding: 6px 12px;
  margin-right: 10px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

.field input[type="file"]::file-selector-button:hover {
  border-color: var(--np-muted);
}

.avatar-edit__img {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--np-border);
  background: var(--np-surface-2);
  flex: none;
}

.chip {
  display: inline-block;
  border-radius: 99px;
  padding: 2px 10px;
  margin-left: 6px;
  font-size: 12px;
  font-weight: 600;
}

.chip--ok {
  background: var(--np-ok-soft);
  border: 1px solid var(--np-ok);
  color: var(--np-ok);
}

.chip--warn {
  background: var(--np-bad-soft);
  border: 1px solid var(--np-bad);
  color: var(--np-bad);
}

.form-msg {
  margin-top: 10px;
  font-size: 13px;
  min-height: 18px;
}

.form-msg--ok {
  color: var(--np-ok);
}

.form-msg--bad {
  color: var(--np-bad);
}

/* ---------- Consola de administración de retos ---------- */

.admin-grid {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: 20px;
  align-items: start;
  margin-top: 20px;
}

@media (max-width: 900px) {
  .admin-grid {
    grid-template-columns: 1fr;
  }
}

.field {
  margin-bottom: 14px;
}

.field label {
  display: block;
  font-size: 13px;
  color: var(--np-muted);
  margin-bottom: 6px;
}

.field input[type="text"],
.field input[type="number"],
.field input[type="password"],
.field input[type="email"],
.field input[type="file"],
.field select,
.field textarea {
  width: 100%;
  background: var(--np-surface-2);
  border: 1px solid var(--np-border);
  border-radius: 10px;
  color: var(--np-text);
  padding: 9px 12px;
  font: inherit;
  font-size: 14px;
}

.field textarea.mono {
  font-family: "JetBrains Mono", monospace;
  font-size: 13px;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--np-primary);
  box-shadow: 0 0 0 3px var(--np-primary-soft);
}

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

.field--inline label {
  margin: 0;
}

.field-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.btn--small {
  padding: 5px 10px;
  font-size: 13px;
}

.option-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.option-row .option-text {
  flex: 1;
  background: var(--np-surface-2);
  border: 1px solid var(--np-border);
  border-radius: 10px;
  color: var(--np-text);
  padding: 8px 12px;
  font: inherit;
  font-size: 14px;
}

.blank-def input {
  margin-bottom: 6px;
}

.challenge-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--np-border);
}

.challenge-row:last-child {
  border-bottom: none;
}

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

.challenge-row__prompt {
  font-size: 14px;
}

/* Enlace de administración del topbar (solo se renderiza para admins). */
.topbar nav a.nav-admin {
  color: var(--np-accent);
}

.admin-form {
  max-width: 720px;
}

/* La pantalla de traduccion pone el original y la traduccion lado a lado, asi
   que necesita todo el ancho: los 720px del formulario de alta dejarian dos
   columnas demasiado estrechas para leer un bloque de codigo. */
.admin-form--wide {
  max-width: none;
}

.field-row--2 {
  grid-template-columns: repeat(2, 1fr);
}

/* Árbol del explorador de contenido. */
.tree-transition {
  margin-bottom: 16px;
}

.tree-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--np-border);
}

.tree-row:last-child {
  border-bottom: none;
}

.tree-row__info {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  min-width: 0;
}

.tree-row--transition {
  padding-top: 0;
}

.tree-row--unit {
  margin-left: 18px;
}

.tree-row--lesson {
  margin-left: 44px;
  font-size: 14px;
}

/* ==========================================================================
   Responsive
   Los grids que ya se adaptan solos (.grid--cards, .stats-row,
   .settings-grid, .compare, .admin-grid) llevan su propia regla arriba.
   Aquí van los tres saltos que sí necesitan decisión de layout.
   ========================================================================== */

/* ---------- Tablet: la barra pasa a hamburguesa ---------- */
@media (max-width: 860px) {
  .topbar {
    flex-wrap: wrap;
    gap: 12px;
    padding: 12px 16px;
  }

  /* Empuja la hamburguesa contra el borde derecho, junto al logo. */
  .nav-toggle {
    display: flex;
    margin-left: auto;
  }

  /* Deja de ser `display: contents` para poder ocultarse y colocarse como
     panel a lo ancho de la barra. */
  .topbar__menu {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding-top: 8px;
    border-top: 1px solid var(--np-border);
  }

  .topbar__menu.is-open {
    display: flex;
  }

  .topbar nav {
    flex-direction: column;
  }

  /* Objetivos táctiles cómodos: los enlaces ocupan toda la fila. */
  .topbar nav a {
    padding: 12px 14px;
    font-size: 15px;
  }

  .topbar__spacer {
    display: none;
  }

  /* El avatar pasa a ser una fila más del menú, con su etiqueta. */
  .topbar__menu > #imgUser {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    color: var(--np-muted);
    text-decoration: none;
    font-size: 15px;
    font-weight: 600;
  }

  .nav-profile-label {
    display: inline;
  }

  .logout-form button {
    width: 100%;
    padding: 12px;
    font-size: 14px;
  }
}

/* ---------- Móvil ---------- */
@media (max-width: 640px) {
  .page {
    padding: 24px 16px 64px;
  }

  /* El 85% dejaría el contenido demasiado estrecho en un móvil. */
  .page--wide {
    max-width: 100%;
  }

  .stats-row--centered .stat__value {
    font-size: 30px;
  }

  .page h1 {
    font-size: 22px;
  }

  .page .subtitle {
    font-size: 14px;
    margin-bottom: 20px;
  }

  .card,
  .card--lg,
  .challenge-box {
    padding: 16px;
  }

  /* Dos tarjetas grandes por fila no caben en un móvil: se apilan. */
  .grid--cards-2 {
    grid-template-columns: 1fr;
  }

  .card--lg {
    min-height: 0;
  }

  /* Los formularios del studio/admin pasan a una sola columna: dos o tres
     campos numéricos en 320px quedan ilegibles. */
  .field-row,
  .field-row--2 {
    grid-template-columns: 1fr;
  }

  /* Botones a ancho completo, apilados. */
  .player-actions .btn {
    flex: 1 1 100%;
  }

  /* El leaderboard cabe en 3 columnas si se recorta el acolchado. */
  .board th,
  .board td {
    padding: 10px 10px;
    font-size: 13px;
  }

  .result {
    padding: 32px 12px;
  }

  .result .big-xp {
    font-size: 34px;
  }

  .profile-head__avatar {
    width: 64px;
    height: 64px;
  }

  /* La sangría del árbol se come el ancho útil en pantallas pequeñas. */
  .tree-row--unit {
    margin-left: 10px;
  }

  .tree-row--lesson {
    margin-left: 22px;
  }

  .lesson-node {
    padding: 12px 14px;
    gap: 10px;
  }

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

  /* Los enlaces ya van en fila y hacen wrap solos; aquí solo se aprieta algo
     el espaciado para que quepan en dos líneas como mucho. */
  .footer__inner {
    gap: 8px 16px;
  }

  .footer__nav {
    gap: 6px 16px;
  }
}

/* Donaciones (/donate) --------------------------------------------------- */

.donate-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
  gap: 48px;
  align-items: start;
}

.donate-kicker {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--np-primary);
  margin-bottom: 12px;
}

.donate-lede h1 {
  font-family: 'Outfit', sans-serif;
  font-size: 32px;
  line-height: 1.12;
  margin: 0 0 14px;
}

.donate-lede > p {
  color: var(--np-muted);
  font-size: 15px;
  max-width: 46ch;
  margin: 0 0 26px;
}

.donate-points {
  display: grid;
  gap: 16px;
  max-width: 46ch;
}

.donate-point {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

.donate-point::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--np-primary);
  margin-top: 8px;
  flex: none;
}

.donate-point strong {
  display: block;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 2px;
}

.donate-point span {
  font-size: 13px;
  color: var(--np-muted);
  line-height: 1.5;
}

.donate-goal {
  margin-top: 30px;
  padding-top: 24px;
  border-top: 1px solid var(--np-border);
  max-width: 46ch;
}

.donate-goal__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  color: var(--np-muted);
  margin-bottom: 4px;
}

.donate-goal__row b {
  color: var(--np-text);
  font-weight: 600;
}

/* La barra de progreso reutiliza .progress / .progress__fill. */

.donate-card {
  background: var(--np-surface);
  border: 1px solid var(--np-border);
  border-radius: 14px;
  padding: 24px;
  display: grid;
  gap: 20px;
  align-content: start;
}

.donate-card h2 {
  font-size: 19px;
  margin: 0 0 4px;
}

.donate-form__label {
  font-size: 12px;
  color: var(--np-muted);
  margin-bottom: 10px;
}

.donate-presets {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.donate-preset {
  padding: 14px 6px;
  border-radius: 10px;
  background: var(--np-bg);
  border: 1px solid var(--np-border);
  color: var(--np-text);
  font: inherit;
  cursor: pointer;
  text-align: center;
}

.donate-preset:hover {
  border-color: var(--np-muted);
}

.donate-preset.is-active {
  border-color: var(--np-primary);
  background: var(--np-primary-soft);
}

.donate-preset__amt {
  display: block;
  font-size: 17px;
  font-weight: 600;
}

.donate-preset__note {
  display: block;
  font-size: 11px;
  color: var(--np-muted);
  margin-top: 2px;
}

.donate-custom {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--np-bg);
  border: 1px solid var(--np-border);
  border-radius: 10px;
  padding: 10px 14px;
}

.donate-custom span {
  color: var(--np-muted);
}

.donate-custom input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: none;
  color: var(--np-text);
  font: inherit;
}

.donate-custom input:focus-visible {
  outline: 2px solid var(--np-accent);
  outline-offset: 2px;
}

.btn--block {
  width: 100%;
}

.donate-fineprint {
  margin: 0;
  text-align: center;
  font-size: 11px;
  color: var(--np-muted);
}

@media (max-width: 860px) {
  .donate-grid {
    grid-template-columns: 1fr;
    gap: 28px;
  }

  .donate-lede h1 {
    font-size: 26px;
  }
}

/* Logros e insignias ------------------------------------------------------------ */

/* Rareza de una insignia (BadgeCatalog.Tier): color del aro, del icono y de la
   píldora. Mismos tonos que los aros del top 3 de la clasificación
   (.rank-badge--gold/silver/bronze); el platino es el único con degradado. */
.tier-bronze {
  --tier: #d99a6c;
  --tier-soft: rgba(201, 132, 85, 0.14);
}

.tier-silver {
  --tier: #d7dbe6;
  --tier-soft: rgba(185, 193, 209, 0.14);
}

.tier-gold {
  --tier: #e0b64c;
  --tier-soft: rgba(224, 182, 76, 0.14);
}

.tier-platinum {
  --tier: #9ee7ff;
  --tier-soft: rgba(158, 231, 255, 0.12);
}

/* Píldora de insignia ganada (NP.badgePill). Va después de
   `.result--completed .badge-pill` para ganarle: en el resultado de la lección
   cada insignia conserva el color de su rareza en vez del verde genérico. */
.badge-pill[class*="tier-"] {
  color: var(--tier);
  border-color: var(--tier);
  background: var(--tier-soft);
  font-weight: 500;
}

.badge-pill--new {
  animation: np-badge-pop 0.5s var(--np-ease-out) both;
}

.badge-pill--new:nth-of-type(2) { animation-delay: 0.08s; }
.badge-pill--new:nth-of-type(3) { animation-delay: 0.16s; }
.badge-pill--new:nth-of-type(4) { animation-delay: 0.24s; }

@keyframes np-badge-pop {
  from {
    opacity: 0;
    transform: scale(0.7);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.result__badges {
  margin: 16px 0;
}

.result__badges-title {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--np-accent);
}

.link-more {
  color: var(--np-primary-hover);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
}

.link-more:hover,
.link-more:focus-visible {
  text-decoration: underline;
}

/* Vitrina (/badges) --------------------------------------------------------- */

/* Una insignia conseguida es una medalla "encendida" (aro y fondo del color de
   su rareza + sello verde); una por conseguir es un hueco "apagado" (aro
   discontinuo, icono gris) que rotula qué hay que hacer. El color de rareza
   solo dice rareza; el verde, "conseguida"; el índigo, avance. */
.ach-page {
  --ach-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --ach-label: #a5a0ff;
}

.ach-num {
  font-variant-numeric: tabular-nums;
}

/* Resumen: la colección (total + reparto por rareza) y, al lado, las que
   tienes más cerca. */
.ach-summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: var(--np-space-6);
  margin-bottom: var(--np-space-5);
}

.ach-summary--solo {
  grid-template-columns: minmax(0, 1fr);
}

.ach-collection__title {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  line-height: var(--np-leading-tight);
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.ach-collection__bar {
  margin-top: var(--np-space-3);
}

.ach-tier-rows {
  display: grid;
  gap: 10px;
  margin: var(--np-space-5) 0 0;
  padding: 0;
  list-style: none;
}

.ach-tier-row {
  display: grid;
  grid-template-columns: 6.5em minmax(0, 1fr) 4.5em;
  align-items: center;
  gap: var(--np-space-3);
  font-size: 13px;
  color: var(--np-text-soft);
}

.ach-tier-row__name {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.ach-tier-row__name::before {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--tier);
}

.ach-tier-row__bar {
  height: 6px;
  margin: 0;
}

.ach-tier-row__bar .progress__fill {
  background: var(--tier);
}

.ach-tier-row .ach-num {
  text-align: right;
  font-weight: 600;
  color: var(--np-text);
}

.ach-num__of {
  font-weight: 500;
  color: var(--np-muted);
}

.ach-near {
  min-width: 0;
  padding-left: var(--np-space-6);
  border-left: 1px solid var(--np-border);
}

.ach-near__title {
  margin: 0 0 var(--np-space-2);
  font-size: 14px;
  font-weight: 600;
  color: var(--np-text-soft);
}

.ach-near__list {
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ach-near__item {
  display: flex;
  align-items: center;
  gap: var(--np-space-3);
  margin: 0 -10px;
  padding: 8px 10px;
  border-radius: var(--np-radius-sm);
  color: inherit;
  text-decoration: none;
  transition: background-color 150ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .ach-near__item:hover {
    background: var(--np-surface-2);
  }
}

.ach-near__body {
  display: grid;
  flex: 1;
  min-width: 0;
}

.ach-near__name {
  font-size: 14px;
  font-weight: 600;
  line-height: var(--np-leading-tight);
}

.ach-near__meta {
  overflow: hidden;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--np-muted);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ach-near__item.is-ready .ach-near__meta {
  font-weight: 600;
  color: var(--np-ok);
  white-space: normal;
}

.ach-near__bar {
  height: 4px;
  margin-top: 6px;
}

/* Filtro: el mismo control segmentado de la clasificación, con el recuento
   de cada vista para que "todas / tengo / me faltan" se lea sin pulsar. */
.ach-filter button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.ach-filter__n {
  min-width: 2.2em;
  padding: 1px 7px;
  border-radius: 99px;
  background: var(--np-surface-2);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.5;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--np-text-soft);
}

.ach-filter button.is-active .ach-filter__n {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}

/* Familias ------------------------------------------------------------------ */

.ach-section {
  margin-top: var(--np-space-6);
}

.ach-section h2 {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 var(--np-space-3);
  font-size: 18px;
}

.ach-section__count {
  font-size: 13px;
  font-weight: 500;
  color: var(--np-muted);
}

.ach-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: var(--np-space-3);
}

.ach-empty {
  margin: 0;
  padding: var(--np-space-7) 0;
  text-align: center;
  color: var(--np-muted);
}

/* Tarjeta de insignia ------------------------------------------------------- */

.ach-card {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  min-width: 0;
  padding: var(--np-space-4);
  background: var(--np-surface);
  border: 1px solid var(--np-border);
  border-radius: var(--np-radius-md);
}

.ach-card:focus {
  outline: none;
}

.ach-card.is-earned {
  border-color: color-mix(in srgb, var(--tier) 45%, var(--np-border));
  background: linear-gradient(160deg, var(--tier-soft), var(--np-surface) 65%);
}

.ach-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-self: stretch;
  min-width: 0;
}

.ach-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 10px;
}

.ach-card h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: var(--np-leading-tight);
}

.ach-card.is-secret.is-locked h3 {
  font-style: italic;
  color: var(--np-text-soft);
}

.ach-tier {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tier);
}

.ach-card.is-locked .ach-tier {
  color: color-mix(in srgb, var(--tier) 55%, var(--np-muted));
}

.ach-req {
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--np-text-soft);
  text-wrap: pretty;
}

.ach-req__label {
  display: block;
  margin-bottom: 1px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ach-label);
}

/* El pie (fecha o avance) se pega abajo: en una fila de tarjetas las barras
   quedan a la misma altura aunque la descripción ocupe una línea o dos. */
.ach-status {
  margin: auto 0 0;
  padding-top: var(--np-space-3);
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--np-muted);
}

.ach-status--earned {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--np-text-soft);
}

.ach-check {
  flex: none;
  width: 14px;
  height: 14px;
  background: var(--np-ok);
  -webkit-mask: var(--ach-check) center / contain no-repeat;
  mask: var(--ach-check) center / contain no-repeat;
}

.ach-status__line {
  margin: 0;
  color: var(--np-text-soft);
}

.ach-status--ready .ach-status__line {
  font-weight: 600;
  color: var(--np-ok);
}

.ach-progress {
  height: 6px;
  margin-top: 6px;
}

/* En las tarjetas y en "cerca" el avance va en índigo liso: el degradado con
   coral se queda para la barra de la colección. */
.ach-progress .progress__fill,
.ach-near__bar .progress__fill {
  background: var(--np-primary);
}

.ach-status--ready .progress__fill,
.ach-near__item.is-ready .progress__fill {
  background: var(--np-ok);
}

/* Medalla ---------------------------------------------------------------------- */

.ach-medal {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 2px solid var(--tier);
  border-radius: 50%;
  background: var(--tier-soft);
}

.ach-medal .np-icon {
  --np-icon-size: 24px;
  --np-icon-color: var(--tier);
  margin: 0;
}

.ach-medal--sm {
  width: 36px;
  height: 36px;
  border-width: 1.5px;
}

.ach-medal--sm .np-icon {
  --np-icon-size: 17px;
}

/* El platino ganado lleva el aro en degradado (borde transparente + fondo en
   dos capas: la de dentro tapa el degradado salvo en el borde). */
.tier-platinum.is-earned .ach-medal {
  border-color: transparent;
  background:
    linear-gradient(var(--np-surface-2), var(--np-surface-2)) padding-box,
    linear-gradient(135deg, #9ee7ff, #b8a9ff, #ffc6ec) border-box;
}

/* Sello de conseguida: círculo verde con la marca, recortado sobre el aro. */
.ach-card.is-earned .ach-medal::after {
  content: "";
  position: absolute;
  right: -5px;
  bottom: -5px;
  width: 20px;
  height: 20px;
  border: 2px solid var(--np-surface);
  border-radius: 50%;
  background:
    var(--np-ok);
}

.ach-card.is-earned .ach-medal::before {
  content: "";
  position: absolute;
  z-index: 1;
  right: -1px;
  bottom: -1px;
  width: 12px;
  height: 12px;
  background: #0f2a1d;
  -webkit-mask: var(--ach-check) center / contain no-repeat;
  mask: var(--ach-check) center / contain no-repeat;
}

/* Hueco apagado: se intuye la rareza en el aro, pero sin brillo. */
.ach-card.is-locked .ach-medal,
.ach-near__item .ach-medal {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--tier) 40%, var(--np-border));
  background: var(--np-surface-2);
}

.ach-card.is-locked .ach-medal .np-icon,
.ach-near__item .ach-medal .np-icon {
  --np-icon-color: var(--np-muted);
  opacity: 0.75;
}

/* Movimiento ------------------------------------------------------------------ */

/* Primera pintada: las barras se rellenan una vez para que el avance se lea
   como avance. Solo al llegar (.is-intro), nunca al cambiar de filtro. */
.ach-page.is-intro .progress__fill {
  transform-origin: left center;
  transition: transform 450ms var(--np-ease-out);
}

@starting-style {
  .ach-page.is-intro .progress__fill {
    transform: scaleX(0);
  }
}

/* Al saltar desde "Lo tienes cerca", la tarjeta de destino se marca un
   momento para que el ojo sepa dónde ha aterrizado. */
.ach-card.is-flash {
  animation: ach-flash 1.4s var(--np-ease-out);
}

@keyframes ach-flash {
  0%,
  35% {
    border-color: var(--np-primary);
    box-shadow: 0 0 0 3px var(--np-primary-soft);
  }
}

@media (max-width: 720px) {
  .ach-summary {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--np-space-5);
  }

  .ach-near {
    padding: var(--np-space-4) 0 0;
    border-top: 1px solid var(--np-border);
    border-left: 0;
  }
}

@media (max-width: 560px) {
  /* Los tres filtros en una fila a lo ancho: con el recuento no caben con el
     relleno de escritorio y "Por conseguir" saltaba sola a otra línea. */
  .ach-filter {
    display: flex;
    width: 100%;
  }

  .ach-filter button {
    flex: 1 1 auto;
    justify-content: center;
    gap: 6px;
    padding: 8px;
  }

  .ach-filter__n {
    min-width: 0;
    padding: 1px 6px;
  }
}

/* En los móviles más estrechos el recuento baja bajo la etiqueta: así las
   tres opciones siguen en una fila también en catalán. */
@media (max-width: 400px) {
  .ach-filter {
    flex-wrap: nowrap;
  }

  .ach-filter button {
    flex: 1 1 0;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    padding: 6px 4px;
    line-height: 1.25;
  }
}

@media (max-width: 560px) {
  .ach-card {
    padding: 14px;
  }

  .ach-medal {
    width: 46px;
    height: 46px;
  }

  .ach-medal .np-icon {
    --np-icon-size: 21px;
  }

  .ach-medal--sm {
    width: 36px;
    height: 36px;
  }

  .ach-medal--sm .np-icon {
    --np-icon-size: 17px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .badge-pill--new {
    animation: none;
  }

  .ach-page.is-intro .progress__fill {
    transition: none;
  }

  /* Sin movimiento, pero el aterrizaje sigue marcado (estado, no efecto). */
  .ach-card.is-flash {
    animation: none;
    border-color: var(--np-primary);
  }
}

/* Lección y retos a tamaño de lectura -------------------------------------------- */

/* En la lección se lee de verdad (teoría, código, enunciados), así que todo
   el conjunto sube un escalón respecto al resto de la app: texto base 17px,
   código 15px y controles de al menos 48px de alto. Solo afecta a
   /lesson/{id} (<main class="page page--lesson">); el resto de páginas
   conserva sus tamaños. Va al final del fichero para ganar a las reglas
   base y a sus media queries con la misma especificidad. */
.page--lesson {
  font-size: 17px;
}

.page--lesson .muted {
  font-size: 15px;
}

.page--lesson .lesson-content h2 {
  font-size: 24px;
}

.page--lesson .lesson-content h3 {
  font-size: 20px;
}

.page--lesson .lesson-content p,
.page--lesson .lesson-content li {
  line-height: 1.7;
}

.page--lesson pre.code,
.page--lesson .lesson-content pre,
.page--lesson textarea.code {
  padding: 16px 18px;
  font-size: 15px;
  line-height: 1.65;
}

.page--lesson .compare {
  gap: 18px;
  margin: 28px 0;
}

.page--lesson .compare__col h4 {
  font-size: 14px;
}

.page--lesson .challenge-progress {
  margin-bottom: 12px;
  font-size: 15px;
}

.page--lesson .challenge-box .prompt {
  margin-bottom: 20px;
  font-size: 19px;
  line-height: 1.5;
}

.page--lesson .options {
  gap: 12px;
}

.page--lesson .option {
  min-height: 56px;
  padding: 16px 20px;
  font-size: 17px;
}

.page--lesson .challenge-body__renderer--fill {
  font-size: 15px;
}

.page--lesson input.blank {
  width: 140px;
  min-height: 32px;
  padding: 4px 10px;
  font-size: 15px;
}

.page--lesson .order-line {
  gap: 12px;
  padding: 12px 16px;
}

.page--lesson .order-line pre {
  font-size: 15px;
}

.page--lesson .order-line button {
  width: 36px;
  height: 36px;
  font-size: 16px;
}

.page--lesson .feedback {
  padding: 16px 20px;
  font-size: 16px;
}

.page--lesson .unit__bonus {
  font-size: 14px;
}

.page--lesson .btn {
  min-height: 48px;
  padding: 12px 22px;
  font-size: 16px;
}

.page--lesson .theory-help__icon {
  width: 26px;
  height: 26px;
  font-size: 16px;
}

.page--lesson .theory-help__tip {
  width: min(420px, 80vw);
  font-size: 15px;
}

/* En móvil, medio escalón menos: el código no puede partirse en demasiadas
   líneas ni un hueco de rellenar desbordar la pantalla. */
@media (max-width: 760px) {
  .page--lesson {
    font-size: 16px;
  }

  .page--lesson pre.code,
  .page--lesson .lesson-content pre,
  .page--lesson textarea.code {
    padding: 14px;
    font-size: 14px;
  }

  .page--lesson .challenge-body__renderer--fill {
    font-size: 14px;
  }

  .page--lesson .challenge-box .prompt {
    font-size: 17px;
  }

  .page--lesson .option {
    padding: 14px 16px;
    font-size: 16px;
  }

  .page--lesson input.blank {
    width: min(140px, 40vw);
  }

  .page--lesson .order-line {
    padding: 10px 10px 8px;
  }

  .page--lesson .order-line pre {
    font-size: 14px;
  }

  .page--lesson .order-line button {
    min-width: 40px;
    height: 40px;
  }
}
