/* ============================================================================
   Design system — Pastel Daydream
   Contrato: docs/spec-diseno-clases.md §2. El color del nivel es el FONDO;
   la tipografía va en gris neutro encima. Todo plano: cero glassmorphism,
   cero degradados. Las superficies se dibujan con FILETE, no con relleno
   (una tarjeta blanca sobre un pastel da 1,25:1 — es invisible).
   ============================================================================ */
:root {
  /* Fondos de nivel — hex muestreados de la lámina de referencia */
  --n1: #F9E69E;  /* Butter Yellow  · La máquina     */
  --n2: #F9C7DC;  /* Powder Pink    · La conversación */
  --n3: #C8D9C4;  /* Soft Sage      · El trabajo      */
  --n4: #D0E7FF;  /* Baby Sky       · El sistema      */
  --n5: #D9D0EF;  /* Lilac Mist     · El criterio     */

  /* Fondo activo. Lo fija [data-nivel]; por defecto, papel neutro */
  --fondo: var(--papel);

  /* Neutros — cero temperatura: el color ya lo pone el fondo */
  --tinta: #111111;          /* titulares y texto principal · 12,75–15,14 sobre los 5 */
  --gris: #5A5A5A;           /* secundario · el más claro que aún pasa AA en los 5    */
  --gris-inactivo: #8A8A8A;  /* solo «en preparación», apagado a propósito            */
  --superficie: #FFFFFF;     /* tarjetas y opciones — se definen con filete           */
  --papel: #F4F4F4;          /* fondo neutro donde no hay nivel                       */

  /* Estado — derivados de la propia paleta, no traídos de fuera */
  --error: #932F50;    /* berry, Powder Pink al fondo · 5,13–6,09 sobre los 5 */
  --acierto: #31724F;  /* pino, Soft Sage al fondo · sello y borde, NO texto pequeño */

  /* Filete: la puntuación del sistema */
  --filete: rgba(17, 17, 17, 0.16);
  --filete-suave: rgba(17, 17, 17, 0.10);

  --radio: 16px;
  --radio-pastilla: 999px;

  --serif: "Instrument Serif", Georgia, serif;   /* narra */
  --grotesk: "Space Grotesk", system-ui, sans-serif;  /* opera */
  --mono: "JetBrains Mono", ui-monospace, monospace;  /* cuenta */
}

/* El nivel pinta el fondo. Es lo único que cambia el ground de una pantalla */
[data-nivel="n1"] { --fondo: var(--n1); }
[data-nivel="n2"] { --fondo: var(--n2); }
[data-nivel="n3"] { --fondo: var(--n3); }
[data-nivel="n4"] { --fondo: var(--n4); }
[data-nivel="n5"] { --fondo: var(--n5); }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--grotesk);
  color: var(--tinta);
  background: var(--fondo);
  font-size: 17px;
  line-height: 1.53;
  -webkit-font-smoothing: antialiased;
  transition: background 0.25s ease;
}

#app {
  max-width: 680px;
  margin: 0 auto;
  padding: 20px 18px 120px;
  padding-left: max(18px, env(safe-area-inset-left));
  padding-right: max(18px, env(safe-area-inset-right));
}

/* ============ Escala tipográfica (375px base) ============ */
h1, h2, h3 { font-family: var(--serif); font-weight: 400; color: var(--tinta); }
h1 { font-size: 34px; line-height: 38px; margin: 0.18em 0; text-wrap: balance; }
h2 { font-size: 26px; line-height: 30px; margin: 0.5em 0 0.3em; text-wrap: balance; }
h3 { font-size: 21px; line-height: 26px; margin: 1.1em 0 0.35em; }
em, i { font-style: italic; }
p { margin: 0.62em 0; color: var(--gris); }
b, strong { font-weight: 500; color: var(--tinta); }
code, pre, .mono { font-family: var(--mono); font-size: 13px; line-height: 20px; }

.cargando { text-align: center; color: var(--gris); padding: 4rem 0; }

/* Etiqueta: 12/16, 500, +0.08em, mayúsculas */
.eyebrow {
  font-family: var(--grotesk);
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--gris);
  margin: 0 0 0.35em;
}

/* Número: nunca en serif, siempre tabular */
.num {
  font-family: var(--grotesk);
  font-size: 13px;
  line-height: 13px;
  font-weight: 500;
  letter-spacing: 0.05em;
  font-variant-numeric: tabular-nums;
  color: var(--gris);
}

/* ============ Primitivas ============ */
/* El filete es estructura, no adorno: puntúa el ritmo entre bloques */
.filete { height: 1px; background: var(--filete); border: 0; margin: 0; }

.superficie, .carta {
  background: var(--superficie);
  border: 1px solid var(--filete);
  border-radius: var(--radio);
  padding: 16px;
  margin: 12px 0;
}

.pastilla {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--filete);
  border-radius: var(--radio-pastilla);
  padding: 6px 12px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--tinta);
}
.pastilla.solida { background: var(--superficie); }
.pastilla.inactiva { color: var(--gris-inactivo); border-color: var(--filete-suave); }

/* ============ Botones ============ */
button {
  font-family: var(--grotesk);
  font-size: 16px;
  line-height: 16px;
  font-weight: 500;
  border: none;
  border-radius: var(--radio-pastilla);
  min-height: 48px;
  padding: 15px 22px;
  cursor: pointer;
  transition: transform 0.06s ease, background 0.15s ease, opacity 0.15s ease;
  touch-action: manipulation;
}
button:active { transform: scale(0.985); }
button:focus-visible { outline: 2px solid var(--tinta); outline-offset: 3px; }

.btn-primario { background: var(--tinta); color: #fff; }
.btn-primario:hover { opacity: 0.88; }
.btn-primario[disabled] { background: var(--gris-inactivo); cursor: not-allowed; }

.btn-secundario,
.btn-linea {
  background: transparent;
  color: var(--tinta);
  border: 1px solid var(--filete);
}
.btn-fantasma { background: transparent; color: var(--gris); }
.btn-bloque { width: 100%; }

/* ============ Barra de acción fija (mobile-first) ============ */
.barra {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  display: flex;
  gap: 10px;
  justify-content: center;
  padding: 14px 18px calc(14px + env(safe-area-inset-bottom));
  background: var(--fondo);
  border-top: 1px solid var(--filete-suave);
  z-index: 10;
}
.barra > * { flex: 1; max-width: 400px; }
.barra.oculta { display: none; }

/* ============ Cabecera de vista ============ */
.cabecera { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.volver {
  min-height: 48px; min-width: 48px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--filete); border-radius: var(--radio-pastilla);
  color: var(--tinta); font-size: 1.15rem; text-decoration: none;
}

/* ============ La marca ============
   Contrato: el brand board «1M3» del 2026-08-06. La plataforma se llama **1 millón 3** y su
   forma corta es `1M3`, escrita en la misma grotesca con la que opera la app.

   No hay símbolo dibujado a propósito: competiría con los 27 iconos de §2.4, que usan
   exactamente ese lenguaje. La marca es tipográfica para que los iconos sigan siendo lo
   único que se dibuja.

   Y NO añade ni un token: `--grotesk` y `--tinta` ya son los de la marca. Los tres valores
   propios (peso 500, tracking −0,02em, caja 1) van aquí literales porque solo los usa
   la marca — un token con un único consumidor es indirección, no sistema. */
.marca {
  font-family: var(--grotesk);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--tinta);
}

/* La «caja de tinta» del brand board —blanco sobre negro, radio 22 %— NO tiene clase aquí, y
   es a propósito (decidido el 2026-08-11): en la app se sirve como asset, `favicon.svg` y
   `icono-180.png`, así que una regla CSS para ella no tendría ni un consumidor. Vuelve del
   brand board el día que haya una superficie de verdad —un avatar, una cabecera de compartir—
   y ese día se declara también el `container-type` que sus unidades `cq*` necesitan. */

/* El lockup completo — `1M3 | 1 millón 3` — se usa la PRIMERA vez que alguien ve la marca,
   y en ningún sitio más: aquí, la portada. Dentro de un nivel o de una clase ya no aparece,
   porque ahí manda el color del nivel y la marca solo haría ruido. */
.marca-lockup {
  display: flex; align-items: center; gap: 9px;
  text-decoration: none; color: inherit;
}
.marca-lockup .marca { font-size: 19px; }
/* El separador es un filete de 1px a la altura de la M */
.marca-sep { width: 1px; height: 14px; background: var(--filete); flex: none; }
.marca-nombre { font-family: var(--mono); font-size: 10px; color: var(--gris); }

/* ============ La ruta: portada de cinco tarjetas de nivel ============
   El detalle de cada nivel vive en su propia vista. Aquí solo el mapa, para que quepa en
   una pantalla. Las tarjetas están más abajo, con los iconos, que es lo que las sostiene. */
.ruta-cab { margin-bottom: 20px; }
/* El título del curso va centrado, y la barra de marca de arriba NO: la barra es chrome
   —lockup a un lado, en qué curso estás al otro— y esto es la portada del curso. Centrarlo
   bajo una barra repartida es lo que los separa como dos cosas distintas. */
.ruta-cab .eyebrow, .ruta-cab h1 { text-align: center; }
.ruta-cab h1 { margin: 0; }

/* La barra de marca de la portada: lockup a la izquierda, en qué curso estás a la derecha */
.ruta-marca {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding-bottom: 14px; margin-bottom: 18px; border-bottom: 1px solid var(--filete);
}
.ruta-curso { font-family: var(--mono); font-size: 10px; color: var(--gris); }

/* El pie: la forma corta sola, centrada. El lockup ya se gastó arriba. */
.ruta-pie {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  margin-top: 28px;
}
.ruta-pie .marca { font-size: 12px; }
.ruta-pie span { font-family: var(--mono); font-size: 10px; color: var(--gris); }

/* La firma: los cinco pasteles en orden de nivel. Es el ÚNICO adorno que la marca permite,
   y el brand board lo dice con dos formas — tira de 5px bajo la marca, o banda a todo el
   ancho en pies y banners. Un pie es de las segundas.

   «Nunca reordenados, nunca con un color de más»: por eso los cinco salen de `curso.json` en
   su orden y no de una lista escrita a mano aquí. Una sexta franja querría decir que hay un
   sexto nivel, y eso lo decide el temario, no el CSS. */
.firma-niveles { display: flex; height: 5px; margin-top: 14px; }
.firma-niveles > * { flex: 1; background: var(--fondo); }

/* «Empieza por aquí»: la única tarjeta con el color de SU nivel, para que el siguiente
   peldaño se distinga del mapa sin necesidad de gritar. */
.continuar {
  display: block; text-decoration: none; color: inherit;
  background: var(--fondo); border: 1px solid var(--filete); border-radius: var(--radio);
  padding: 18px; margin-bottom: 14px;
}
.continuar-nombre { font-size: 24px; line-height: 28px; margin: 0 0 4px; }
.continuar-promesa { margin: 0; font-size: 14.5px; line-height: 21px; }

.fila-mazo {
  display: flex; align-items: center; gap: 12px;
  text-decoration: none; color: inherit; margin-bottom: 26px;
  border: 1px solid var(--filete); border-radius: var(--radio); padding: 13px 16px;
}
.fila-mazo-n {
  font-family: var(--grotesk); font-size: 20px; font-weight: 500;
  font-variant-numeric: tabular-nums; min-width: 26px;
}
.fila-mazo b { display: block; font-size: 15px; }
.fila-mazo-nota { font-size: 12.5px; color: var(--gris); }

.peldanos { margin-top: 14px; display: flex; flex-direction: column; }
.peldano {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 13px 0; text-decoration: none; color: inherit;
  border-top: 1px solid var(--filete-suave);
}
.peldano-num {
  font-family: var(--mono); font-size: 11.5px; color: var(--gris);
  font-variant-numeric: tabular-nums; flex: none; min-width: 24px; margin-top: 4px;
}
.peldano-cuerpo { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.peldano-nombre { font-family: var(--serif); font-size: 19px; line-height: 23px; }
.peldano-heredado { font-family: var(--mono); font-size: 10.5px; color: var(--gris); }
.peldano-marca {
  font-family: var(--mono); font-size: 10.5px; color: var(--gris);
  white-space: nowrap; margin-top: 5px; text-align: right;
}

/* Estados. Solo el gris cambia de peso: el color del nivel no se toca. El punto de estado
   se retiró con el icono (§2.4): el contorno fino ya dice lo que decía el punto. */
.peldano[data-clave="completado"] .peldano-marca { color: var(--acierto); }
.peldano[data-clave="borrador"] { cursor: default; }
.peldano[data-clave="borrador"] .peldano-nombre,
.peldano[data-clave="borrador"] .peldano-num,
.peldano[data-clave="borrador"] .peldano-marca { color: var(--gris-inactivo); }

/* El escalón del examen, al pie de la vista de su nivel. Es lo único de esa vista que NO es
   un tema, y por eso se dibuja macizo (filete de 1,5px en tinta) en vez de con la fila fina
   del peldaño: no es un tema más, es la puerta de salida del nivel. */
.escalon-examen {
  display: flex; align-items: center; gap: 12px; width: 100%;
  min-height: 56px; padding: 14px 16px; margin-top: 14px;
  border: 1.5px solid var(--tinta); border-radius: 13px;
  background: transparent; text-align: left; color: var(--tinta); text-decoration: none;
  font-family: var(--grotesk); font-size: 16px; font-weight: 500;
}
.escalon-examen .escalon-marca { font-family: var(--mono); font-size: 12px; }
.escalon-examen .escalon-nombre { flex: 1; }
.escalon-examen .cola {
  font-family: var(--mono); font-size: 11.5px; font-weight: 400; color: var(--gris);
  text-align: right;
}
.escalon-examen.es-cerrado { border-color: var(--filete); color: var(--gris-inactivo); }
.escalon-examen.es-cerrado .cola { color: var(--gris-inactivo); }
.escalon-examen.es-aprobado { border-color: var(--acierto); }

/* El final no pertenece a ningún nivel: va suelto al pie de la portada, sobre papel */
.escalon-examen.es-final { margin-top: 22px; }

/* ============ Ficha de tema ============ */
.ficha-promesa { font-size: 17px; line-height: 25px; margin: 4px 0 14px; max-width: 34ch; }
.ficha-meta { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 16px; }
.ficha-bloque { margin-top: 18px; }
.ficha-bloque h3 { margin-top: 0; }
.ficha-nota { font-size: 13px; color: var(--gris); font-style: italic; }
.requisitos { display: flex; flex-direction: column; margin: 12px 0; }
.requisito {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 0; text-decoration: none; color: inherit;
  border-top: 1px solid var(--filete-suave);
}
.requisito-nombre { flex: 1; font-family: var(--serif); font-size: 18px; }


/* ============ Quiz: mazo y exámenes ============
   Comparte lenguaje con los ejercicios de clase (misma opción, mismo filete, mismos
   estados) porque es la misma pregunta vista en otro sitio: si se vistieran distinto,
   parecerían dos cosas. Va sobre --papel: el mazo cruza niveles y no es de ninguno. */
.quiz-progreso {
  font-family: var(--mono); font-size: 11.5px; color: var(--gris);
  letter-spacing: 0.02em; margin-bottom: 8px; display: block;
}
.quiz-barra { height: 4px; border-radius: var(--radio-pastilla); background: rgba(17, 17, 17, 0.15); overflow: hidden; margin-bottom: 20px; }
.quiz-barra > * { display: block; height: 100%; background: var(--tinta); border-radius: var(--radio-pastilla); transition: width 0.25s ease; }
.quiz-pregunta { font-family: var(--serif); font-weight: 400; font-size: 26px; line-height: 30px; margin: 0 0 16px; }

.opciones { display: flex; flex-direction: column; gap: 9px; }
.opcion {
  display: block; width: 100%; min-height: 48px; padding: 13px 15px; text-align: left;
  background: var(--superficie); border: 1px solid var(--filete); border-radius: 13px;
  font-family: var(--grotesk); font-size: 15.5px; font-weight: 400; color: var(--tinta);
}
.opcion.correcta { border-color: var(--acierto); border-width: 1.5px; }
.opcion.fallada { border-color: var(--error); border-width: 1.5px; }
.opcion.elegida-examen { border-color: var(--tinta); border-width: 1.5px; }
.opcion[disabled] { cursor: default; }

.zona-explicacion:empty { display: none; }
.explicacion {
  background: var(--superficie); border: 1px solid var(--filete); border-radius: 13px;
  padding: 14px 15px; margin-top: 12px;
  font-size: 14.5px; line-height: 22px; color: var(--gris);
}
.explicacion b { color: var(--tinta); font-weight: 500; }

/* Resultado */
.resultado { text-align: center; padding: 30px 20px; }
.num-resultado {
  font-family: var(--grotesk); font-size: 46px; font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--tinta); line-height: 1.1; margin: 6px 0;
}
.nota { font-size: 14px; color: var(--gris); }
.sello {
  display: inline-block; margin-top: 12px; padding: 8px 18px;
  border: 1.5px solid var(--acierto); border-radius: var(--radio-pastilla);
  font-family: var(--grotesk); font-size: 13px; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--acierto);
}
.sello.no-apto { border-color: var(--error); color: var(--error); }

.fecha-sello { font-family: var(--mono); font-size: 11.5px; color: var(--gris); margin-top: 10px; }

/* Repaso de falladas */
.zona-repaso { margin-top: 26px; text-align: left; }
.repaso-item { border-top: 1px solid var(--filete-suave); padding: 14px 0 4px; }
.repaso-pregunta { font-family: var(--serif); font-size: 19px; line-height: 24px; margin: 0 0 6px; }
.mini {
  border-top: 1px solid var(--filete-suave); padding: 12px 0;
  font-size: 14px; line-height: 21px; color: var(--gris);
}
.repaso-item .mini { border-top: 0; padding: 2px 0; }
.mini b { color: var(--tinta); font-weight: 500; }
.mini.mal b { color: var(--error); }
.nota-mazo { margin-top: 18px; }

/* ============ Examen ============
   Hereda entero el lenguaje del quiz (misma opción, mismo filete, mismo sello): un examen
   es la misma pregunta vista en otro sitio, y vestirla distinta la convertiría en otra cosa.
   Lo único propio son las tres piezas de abajo — la convocatoria, el contador de fallos y
   la salida. Va sobre el fondo del NIVEL; el final, sobre papel, como el mazo. */

/* La convocatoria: ficha de examen, no muro de texto */
.convocatoria h1 { margin: 2px 0 10px; }
.reglas { list-style: none; margin: 22px 0 0; padding: 0; }
.regla {
  display: flex; gap: 13px; align-items: baseline;
  border-top: 1px solid var(--filete-suave); padding: 12px 0;
}
.regla:last-child { border-bottom: 1px solid var(--filete-suave); }
.regla-cifra {
  font-family: var(--mono); font-size: 15px; font-weight: 500; color: var(--tinta);
  font-variant-numeric: tabular-nums; min-width: 42px;
}
.regla-texto { font-size: 15px; line-height: 21px; color: var(--gris); }
.regla-texto b { color: var(--tinta); font-weight: 500; }

/* El aviso de convocatoria única: el único sitio del examen donde el color profundo
   aparece ANTES de haber fallado nada. Filete y no relleno, como toda superficie. */
.aviso-unico {
  border: 1px solid var(--error); border-radius: 13px;
  padding: 13px 15px; margin-top: 20px;
  font-size: 14.5px; line-height: 21px; color: var(--gris);
}
.aviso-unico b { color: var(--error); font-weight: 500; }
.nota-previo { margin-top: 14px; }

/* Cabecera del examen en curso. El contador de fallos se pone berry al llegar al límite:
   la siguiente que falles ya es un NO APTO, y eso hay que verlo venir. */
.cabecera-cuerpo { flex: 1; }
.examen-cabecera { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.examen-cabecera .quiz-progreso { margin-bottom: 0; }
.examen-fallos { font-family: var(--mono); font-size: 11.5px; color: var(--gris); }
.examen-fallos.al-limite { color: var(--error); }

/* Rendirse es explícito y está abajo: en un examen no hay flecha de volver, porque salir
   no es navegar — es entregar en blanco lo que quede. */
.rendirse {
  display: block; text-align: center; margin-top: 24px;
  font-size: 13px; color: var(--gris); text-decoration: underline;
  min-height: 48px; line-height: 48px;
}

/* Un enlace que hace de botón en la barra fija (el «Mazo (n)» tras un resultado) */
.btn-enlace {
  display: flex; align-items: center; justify-content: center;
  text-decoration: none; font-weight: 500;
}

/* ============ Figuras (js/figuras/) — v2, «el trazo de los iconos» ============
   Contrato: docs/spec-diseno-clases.md §3. Los componentes emiten CLASES y nunca
   colores: un fill="var(--x)" como atributo SVG no funciona.

   Lo que cambia respecto de v1:
     - Un solo grosor de tinta (1,75) con remates redondos, declarado en .fig y heredado.
       Antes cada pieza traía el suyo y el conjunto se leía como wireframe.
     - Cero relleno blanco: el fondo del nivel entra en la figura.
     - Andamio (ejes, guías, rejilla) y corchetes bajan de peso y nunca compiten.
     - Cuatro tramas de tinta sustituyen a los tres tintes pastel. Distinguen sin gastar
       paleta y aguantan sobre los cinco fondos, incluido el sage.
     - Ninguna etiqueta legible usa --gris-inactivo (2,78:1 sobre los cinco).

   No añade ni un token de color. Usa --tinta, --gris y --gris-inactivo, que ya existen. */

:root {
  --fig-trazo: 1.75;      /* el objeto */
  --fig-andamio: 1;       /* eje, rejilla, guía, línea base */
  --fig-corchete: 1.2;    /* «esto de aquí, junto, es tanto» */
}

.figura {
  margin: 18px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.figura .fig {
  display: block;
  width: 100%;
  max-width: 420px; /* el viewBox está en px de móvil: sin tope, en desktop se agiganta */
  height: auto;
  fill: none;
  stroke: var(--tinta);
  stroke-width: var(--fig-trazo);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.figura figcaption {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 16px;
  color: var(--gris);
  margin-top: 10px;
  text-align: center;
}

/* ---- Las seis marcas -------------------------------------------------------
   Cualquier figura se construye con estas y nada más. Una marca nueva casi siempre
   significa que el componente está dibujando dos cosas. */

.fig-andamio   { stroke-width: var(--fig-andamio); opacity: .35; }
.fig-corchete  { stroke-width: var(--fig-corchete); opacity: .5; }
.fig-enlace    { opacity: .55; }
.es-hipotetico { stroke-dasharray: 6 5; opacity: .5; }   /* lo que no existe */
.es-macizo     { fill: var(--tinta); stroke: none; }     /* «esta es la que te señalo» */
.fig-punto     { fill: var(--tinta); stroke: none; }     /* el punto del anillo con punto */

/* ---- Tramas ----------------------------------------------------------------
   Tinta al 40-50%: su contraste baja con el fondo en vez de depender de acertar un tono,
   así que aguantan en los cinco niveles. Se asignan POR ORDEN DE APARICIÓN, nunca por
   significado. Los <pattern> los emite el JS con estos ids. */

.tr-1 { fill: url(#fig-tr-1); }   /* diagonal, paso 8 */
.tr-2 { fill: url(#fig-tr-2); }   /* punto, paso 6    */
.tr-3 { fill: url(#fig-tr-3); }   /* malla, paso 7    */
.tr-4 { fill: url(#fig-tr-4); }   /* raya, paso 6     */
.tr-1, .tr-2, .tr-3, .tr-4 { stroke: none; }
.tr-muestra { stroke: var(--tinta); stroke-width: var(--fig-trazo); }  /* el cuadro de leyenda */

/* ---- Tipos dentro del SVG --------------------------------------------------
   Se declaran aquí y no en cada componente por la misma razón que el color.
   Regla heredada del sistema: si se lee, grotesca; si se cuenta, mono. */

.fig text { stroke: none; font-family: var(--grotesk); fill: var(--tinta); }

.fig-t-titulo  { font-size: 13.5px; font-weight: 500; }
.fig-t-cuerpo  { font-size: 13px; }
.fig-t-dato    { font-family: var(--mono); font-size: 10.5px; fill: var(--gris); }
.fig-t-etq     { font-family: var(--mono); font-size: 11px; }
.fig-t-cifra   { font-family: var(--mono); font-size: 12px; }
.fig-t-cuenta  { font-family: var(--mono); font-size: 14px; font-weight: 500; }
.fig-t-eyebrow { font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; fill: var(--gris); }
.fig-t-nota    { font-size: 11.5px; font-style: italic; fill: var(--gris); }
.fig-t-token   { font-family: var(--mono); font-size: 13px; }
.fig-t-blanco  { fill: var(--gris-inactivo); }  /* el glifo · de un espacio: decorativo */

.fig-t-pregunta { font-size: 15px; font-weight: 500; }   /* la cabecera de `capas` */
.fig-t-id       { font-family: var(--mono); font-size: 10px; fill: var(--gris); }

.fig-t-etq.es-secundario,
.fig-t-cuerpo.es-secundario,
.fig-t-titulo.es-secundario { fill: var(--gris); }

/* Lo contrario de `es-secundario`: una etiqueta que por defecto va en gris y aquí es la que
   se lee. La usan `contraste` (el panel que sí existe) y `posicion` (el centro de la U). */
.fig-t-dato.es-tinta,
.fig-t-eyebrow.es-tinta { fill: var(--tinta); }

/* `cronologia`: el hito destacado pesa más, pero no cambia de color ni de tamaño. */
.fig-t-cuerpo.es-destacado { font-weight: 500; }
/* NUNCA --gris-inactivo en una etiqueta que haya que leer: 2,78:1 sobre los cinco fondos.
   Lo que no existe ya lo dice la discontinua; atenuar el texto encima solo lo hace ilegible. */

/* ---- Estampas --------------------------------------------------------------
   Un icono de js/iconos.js dibujado a 84 dentro de una figura. El grosor lo compensa el
   JS, igual que en icono(). El <svg> que guarda los <symbol> DEBE llevar fill="none": en
   pantalla da igual, pero cualquier pipeline que reserialice el DOM (captura, PDF) los
   pinta como manchas negras si falta. */

.fig-estampa { stroke: var(--tinta); }
.fig-estampa.es-hipotetico { stroke-dasharray: 3 3; opacity: .5; }

/* ---- Solo la figura que ES ejercicio se deja tocar -------------------------- */

.fig-grupo.es-tocable { cursor: pointer; }
.fig-grupo.es-tocable:focus-visible { outline: 2px solid var(--tinta); outline-offset: 2px; }

/* ============ Movimiento ============ */
@keyframes aparecer {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
/* Solo entran los bloques grandes al cargar una vista. Los peldaños NO: veintidós
   elementos apareciendo en cascada es un festival, no una interfaz. */
.superficie, .carta, .figura, .continuar, .nivel-tarjeta { animation: aparecer 0.32s ease both; }

@keyframes estampar {
  from { transform: rotate(-3deg) scale(2.1); opacity: 0; }
  60% { transform: rotate(-3deg) scale(0.94); opacity: 1; }
  to { transform: rotate(-3deg) scale(1); opacity: 1; }
}
.sello { animation: estampar 0.5s cubic-bezier(0.2, 0.8, 0.3, 1) 0.15s both; }

@keyframes sacudir {
  20%, 60% { transform: translateX(-4px); }
  40%, 80% { transform: translateX(4px); }
}
.opcion.fallada { animation: sacudir 0.35s ease; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

@media (min-width: 700px) {
  h1 { font-size: 2rem; }
  #app { padding-top: 36px; }
}
/* ============ La clase, pantalla a pantalla ============
   El fondo lo pone [data-nivel] en <body> (§2.2): aquí no se pinta ningún color de
   pantalla. Las superficies van con filete, nunca con relleno de contraste. */
.clase { display: flex; flex-direction: column; min-height: 70vh; }

/* --- cabecera: progreso del TRAMO, no de las 30 pantallas --- */
.clase-cab { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
.clase-top { display: flex; align-items: center; gap: 12px; }
.clase-barra { flex: 1; height: 4px; border-radius: var(--radio-pastilla); background: rgba(17, 17, 17, 0.15); overflow: hidden; }
.clase-barra i { display: block; height: 100%; background: var(--tinta); border-radius: var(--radio-pastilla); transition: width 0.25s ease; }

.clase-atras, .clase-salir {
  min-height: 44px; min-width: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0;
  color: var(--gris); font-size: 1.5rem; line-height: 1; text-decoration: none;
}
.clase-salir { font-size: 1.05rem; }
.clase-atras[disabled] { opacity: 0.25; cursor: default; }

.clase-tramos { display: flex; align-items: center; gap: 7px; }
.clase-diam { width: 7px; height: 7px; transform: rotate(45deg); background: rgba(17, 17, 17, 0.2); flex: none; }
.clase-diam.es-sellado { background: var(--acierto); }
.clase-tramos b {
  font-family: var(--grotesk); font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--gris); margin-left: 4px;
}

/* --- cuerpo --- */
.clase-cuerpo { display: flex; flex-direction: column; gap: 15px; }
.clase-cuerpo > .num { align-self: flex-start; }
.clase-prosa { color: var(--gris); font-size: 17px; line-height: 26px; }
.clase-prosa > :first-child { margin-top: 0; }
.clase-prosa > :last-child { margin-bottom: 0; }

.pantalla-apertura .clase-prosa { font-size: 18px; line-height: 28px; }
.pantalla-apertura h1 { font-size: 38px; line-height: 42px; }

/* La pantalla de un desvío se marca discreta: se está fuera del hilo principal */
.clase.es-desvio .clase-cuerpo > .num { color: var(--tinta); }
.clase.es-desvio .clase-cuerpo > .num::after { content: " · desvío"; color: var(--gris); }

/* --- desvío de profundidad --- */
.clase-desvio {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; min-height: 48px; padding: 13px 15px;
  background: none; border: 1px solid var(--filete); border-radius: 14px;
  font-family: var(--grotesk); font-size: 14.5px; font-weight: 500; color: var(--tinta);
  text-align: left;
}
.clase-desvio i { font-family: var(--mono); font-style: normal; font-size: 12px; color: var(--gris); }

/* --- ejercicio --- */
.clase-pregunta { font-family: var(--serif); font-weight: 400; font-size: 26px; line-height: 30px; margin: 0; }
.clase-ejercicio { display: flex; flex-direction: column; gap: 9px; }
.clase-pie-ejercicio:empty { display: none; }
.clase-explicacion {
  background: var(--superficie); border: 1px solid var(--filete); border-radius: 13px;
  padding: 14px 15px; font-size: 14.5px; line-height: 22px; color: var(--gris);
}
.clase-explicacion b { color: var(--tinta); }
.clase-nota { font-size: 14px; color: var(--gris); font-style: italic; }

/* --- hito de tramo: el punto donde se puede parar limpio --- */
.clase-hito {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 15px; text-align: center; padding: 40px 10px;
}
.clase-hito h1 { font-size: 28px; line-height: 32px; margin: 0; }
.clase-sello {
  width: 52px; height: 52px; transform: rotate(45deg); border-radius: 9px;
  background: var(--acierto); display: flex; align-items: center; justify-content: center;
}
.clase-sello span { transform: rotate(-45deg); color: #fff; font-size: 22px; line-height: 1; }
.clase-hito.es-nuevo .clase-sello { animation: sello 0.4s cubic-bezier(0.2, 1.4, 0.4, 1); }
@keyframes sello {
  from { transform: rotate(45deg) scale(0.4); opacity: 0; }
  to { transform: rotate(45deg) scale(1); opacity: 1; }
}

/* --- misión: cierre de la clase, sin cabecera --- */
.clase-mision { padding-top: 12px; }

/* --- reanudación --- */
.clase-reanudar { display: flex; flex-direction: column; gap: 10px; padding: 40px 0 0; text-align: center; }
.clase-reanudar h1 { margin: 0; }
.clase-reanudar-pos {
  font-family: var(--grotesk); font-size: 30px; font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--tinta); margin: 6px 0 0;
}
.clase-reanudar-donde { font-size: 13px; color: var(--gris); margin: 0; text-transform: uppercase; letter-spacing: 0.06em; }
.clase-reanudar-titulo { font-family: var(--serif); font-size: 21px; line-height: 26px; color: var(--tinta); margin: 8px 0 0; }

/* --- ejercicios (js/ejercicios/) --- */
/* Todas las superficies con filete: un relleno blanco sobre pastel no se ve (1,25:1) */
.ej-opciones, .ej-orden-sueltos { display: flex; flex-direction: column; gap: 9px; }

.ej-opcion, .ej-ficha, .ej-linea {
  display: flex; align-items: center; gap: 11px; width: 100%;
  min-height: 48px; padding: 13px 15px; text-align: left;
  background: var(--superficie); border: 1px solid var(--filete); border-radius: 13px;
  font-family: var(--grotesk); font-size: 15.5px; font-weight: 400; color: var(--tinta);
}
.ej-opcion[disabled], .ej-ficha[disabled], .ej-linea[disabled] { cursor: default; }
.ej-texto { flex: 1; }

.ej-punto { width: 17px; height: 17px; border-radius: 999px; border: 1.5px solid rgba(17, 17, 17, 0.3); flex: none; }
.ej-marca { font-family: var(--mono); font-style: normal; font-size: 11px; white-space: nowrap; }

/* El error se marca con borde y tono; el acierto igual. Nunca con relleno de color:
   sobre un fondo pastel una banda saturada se come la lectura. */
.ej-opcion.es-mal { border-color: var(--error); border-width: 1.5px; }
.ej-opcion.es-mal .ej-punto { border-color: var(--error); background: var(--error); box-shadow: inset 0 0 0 3px var(--superficie); }
.ej-opcion.es-mal .ej-marca { color: var(--error); }
.ej-opcion.es-bien { border-color: var(--acierto); border-width: 1.5px; }
.ej-opcion.es-bien .ej-punto { border-color: var(--acierto); background: var(--acierto); box-shadow: inset 0 0 0 3px var(--superficie); }
.ej-opcion.es-bien .ej-marca { color: var(--acierto); }

.ej-pista {
  font-family: var(--mono); font-size: 11.5px; color: var(--gris);
  margin: 0; letter-spacing: 0.02em;
}

/* --- ordenar: se toca para colocar, no se arrastra --- */
.ej-orden { display: flex; flex-direction: column; gap: 11px; }
.ej-orden-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.ej-orden-lista:empty { display: none; }
.ej-ficha.es-colocada { border-color: var(--tinta); }
.ej-orden-num {
  font-family: var(--mono); font-size: 12px; color: var(--gris);
  font-variant-numeric: tabular-nums; flex: none; min-width: 14px;
}
.ej-orden-sueltos:empty { display: none; }

/* --- marcar fallos sobre material real --- */
.ej-fallos { display: flex; flex-direction: column; gap: 11px; }
.ej-material {
  display: flex; flex-direction: column; gap: 3px;
  border: 1px solid var(--filete); border-radius: 13px; padding: 8px;
  background: var(--superficie); overflow-x: auto;
}
.ej-linea {
  min-height: 40px; padding: 8px 11px; border: 1px solid transparent; border-radius: 8px;
  background: none; gap: 0;
}
.ej-linea code { font-family: var(--mono); font-size: 12.5px; line-height: 19px; white-space: pre; color: var(--tinta); }
.ej-linea.es-marcada { border-color: var(--tinta); background: rgba(17, 17, 17, 0.05); }
.ej-linea.es-culpable { border-color: var(--error); }
.ej-linea.es-culpable code { color: var(--error); }

.ej-comprobar {
  align-self: flex-start; min-height: 44px; padding: 12px 20px;
  background: var(--tinta); color: #fff; border: 0; border-radius: var(--radio-pastilla);
  font-family: var(--grotesk); font-size: 15px; font-weight: 500;
}
.ej-comprobar[disabled] { background: var(--gris-inactivo); cursor: not-allowed; }

/* ============================================================================
   Entornos — la tercera capa del sistema visual
   Contrato: docs/patron-figuras.md §3.17. Va a `styles.css` como bloque propio.

   Un ENTORNO no es una figura. Una figura es un dibujo SVG que explica un
   mecanismo; un entorno es el MARCO RECONOCIBLE donde pasa algo, y lo que lleva
   dentro es material de verdad: texto, un comando, un diff, un mensaje.

   Y por eso es DOM y no SVG. El material se selecciona, se lee con lector de
   pantalla, se busca con Cmd+F y se escribe en el JSON de la clase como texto.
   Meterlo en un <svg> lo convertiría en un dibujo de un comando, que es
   exactamente lo que no queremos: el alumno tiene que reconocer la terminal que
   va a tener delante.

   Precedente en la app: `.ej-material` y `.ej-linea` del ejercicio de marcar
   fallos ya hacen esto. Los entornos generalizan ese patrón, con sus mismas
   reglas: superficie con FILETE (nunca relleno de color), mono para el material,
   cero degradados, cero sombras, cero cromo de sistema operativo dibujado.
   ============================================================================ */

.ent {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--filete);
  border-radius: 13px;
  background: var(--superficie);
  overflow: hidden;
  margin: 18px 0;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 20px;
  color: var(--tinta);
}

/* La barra: dice DÓNDE estás. Es lo único que convierte una caja de texto en un
   sitio. No lleva semáforo de macOS ni botones dibujados: la ruta es suficiente,
   y un cromo dibujado envejece con la versión de la app que imita. */
.ent-barra {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 13px;
  border-bottom: 1px solid var(--filete-suave);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--gris);
}
.ent-barra b { color: var(--tinta); font-weight: 500; }
.ent-barra .ent-cola { margin-left: auto; }

/* Las pestañas de un editor: la abierta va en tinta, las demás en gris. Máximo
   tres — un editor con seis pestañas dibuja el IDE, no la lección. */
.ent-pestanas { display: flex; gap: 0; border-bottom: 1px solid var(--filete-suave); }
.ent-pestana {
  padding: 9px 13px;
  font-size: 11px;
  color: var(--gris);
  border-right: 1px solid var(--filete-suave);
}
.ent-pestana.es-activa { color: var(--tinta); box-shadow: inset 0 -2px 0 var(--tinta); }

.ent-cuerpo { display: flex; flex-direction: column; padding: 11px 13px; gap: 2px; overflow-x: auto; }
.ent-cuerpo.es-denso { gap: 0; }

/* Una línea de material. `white-space: pre` porque la sangría es contenido. */
.ent-linea { display: flex; gap: 10px; white-space: pre; }
.ent-linea > code { font-family: var(--mono); font-size: 12.5px; line-height: 20px; }

/* El número de línea: NO es andamio como en una figura — el texto de la clase lo
   cita («la línea 5 no dice nada que se pueda seguir»), así que hay que poder
   leerlo. Va en `--gris` sin opacidad: 4,66:1 sobre la superficie. Si pesa
   demasiado en el conjunto, se baja el tamaño, nunca el contraste. */
.ent-num {
  flex: none;
  min-width: 20px;
  text-align: right;
  color: var(--gris);
  font-size: 10.5px;
  user-select: none;
}

/* Los tres marcadores de estado de una línea, y ninguno más:
   prompt (lo que se escribe), salida (lo que devuelve), fallo (lo que rompe). */
.ent-prompt { flex: none; color: var(--tinta); font-weight: 500; user-select: none; }
.ent-salida { color: var(--gris); }
.ent-linea.es-mal > code, .ent-linea.es-mal .ent-salida { color: var(--error); }
.ent-linea.es-bien .ent-salida { color: var(--acierto); }

/* La línea que se señala. Es la maciza de las figuras traducida a DOM: como
   mucho una por entorno, y significa «esta es la que te señalo». */
.ent-linea.es-marcada {
  background: rgba(17, 17, 17, 0.05);
  border-radius: 5px;
  margin: 0 -5px;
  padding: 0 5px;
}

/* Lo que todavía no ha pasado: mismo significado que la discontinua de §3.2. */
.ent-linea.es-hipotetica { opacity: 0.45; }
.ent-cursor {
  display: inline-block;
  width: 7px;
  height: 15px;
  vertical-align: -2px;
  background: var(--tinta);
  margin-left: 2px;
}
@media (prefers-reduced-motion: no-preference) {
  .ent-cursor { animation: ent-latido 1.1s steps(1) infinite; }
}
@keyframes ent-latido { 50% { opacity: 0; } }

/* --- diff: dos marcadores y nada más. El color es el de estado, que aquí sí es
   estado: una línea que se va y una que entra. Sin fondo saturado. --- */
.ent-linea.es-quita .ent-prompt, .ent-linea.es-quita > code { color: var(--error); }
.ent-linea.es-pone .ent-prompt, .ent-linea.es-pone > code { color: var(--acierto); }

/* --- conversación: turnos. El del alumno con filete, el del modelo sin caja
   —para que no parezcan dos participantes iguales— y el bloque de herramienta
   con su propia sangría. --- */
.ent-turnos { display: flex; flex-direction: column; gap: 11px; padding: 13px; }
.ent-turno { display: flex; flex-direction: column; gap: 5px; max-width: 92%; }
.ent-turno-quien {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gris);
}
.ent-turno-cuerpo {
  font-family: var(--grotesk);
  font-size: 14.5px;
  line-height: 21px;
  color: var(--tinta);
}
.ent-turno.es-tu { align-self: flex-end; align-items: flex-end; text-align: right; }
.ent-turno.es-tu .ent-turno-cuerpo {
  border: 1px solid var(--filete);
  border-radius: 12px;
  padding: 9px 12px;
}
/* La llamada a herramienta: no es prosa, así que va en mono y sangrada. */
.ent-tool {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-left: 2px solid var(--filete);
  padding: 4px 0 4px 11px;
  color: var(--gris);
  font-size: 11.5px;
  line-height: 18px;
}
.ent-tool b { color: var(--tinta); font-weight: 500; }

/* --- lo que viene de fuera. El único entorno con marca propia, porque la
   lección de seguridad entera es «esto no lo has escrito tú»: filete en berry y
   una etiqueta que lo dice. No es un error, es procedencia. --- */
.ent.es-ajeno { border-color: var(--error); }
.ent.es-ajeno .ent-barra { color: var(--error); }
.ent.es-ajeno .ent-barra b { color: var(--error); }

/* --- el árbol de archivos: rutas reales, no un dibujo. La figura `arbol` explica
   una jerarquía; esto ES el explorador.

   La sangría va en padding y por nivel, NO en caracteres de dibujo: un `└─` de
   texto lo pronuncia un lector de pantalla, y esta capa existe justamente porque
   su material es texto accesible. La guía se dibuja con un filete. --- */
.ent-arbol { display: flex; flex-direction: column; padding: 11px 13px; gap: 3px; }
.ent-nodo { display: flex; align-items: baseline; gap: 9px; }
.ent-nodo[data-nivel="1"] { padding-left: 18px; }
.ent-nodo[data-nivel="2"] { padding-left: 36px; }
.ent-nodo[data-nivel="3"] { padding-left: 54px; }
.ent-nodo[data-nivel="1"], .ent-nodo[data-nivel="2"], .ent-nodo[data-nivel="3"] { position: relative; }
.ent-nodo[data-nivel="1"]::before,
.ent-nodo[data-nivel="2"]::before,
.ent-nodo[data-nivel="3"]::before {
  content: "";
  position: absolute;
  top: 0.62em;
  width: 9px;
  border-top: 1px solid var(--filete);
}
.ent-nodo[data-nivel="1"]::before { left: 5px; }
.ent-nodo[data-nivel="2"]::before { left: 23px; }
.ent-nodo[data-nivel="3"]::before { left: 41px; }
.ent-nodo .ent-nota { margin-left: auto; font-size: 10.5px; color: var(--gris); }
.ent-nodo.es-cerrado > code { color: var(--gris); }

/* --- el pie del entorno: la misma pieza que el figcaption de una figura, para
   que las dos capas se lean como el mismo sistema. --- */
.ent-pie {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 16px;
  color: var(--gris);
  margin: 10px 0 0;
  text-align: center;
}

/* ============================================================================
   Glifos en línea — una estampa dentro de una frase
   Contrato: docs/patron-figuras.md §3.18.

   Es la misma estampa del vocabulario, a la altura de una x, dentro del texto.
   Sirve para anclar un sustantivo la primera vez que aparece, no para decorar.
   Reglas: uno o dos por pantalla, siempre pegado al sustantivo que nombra, y
   nunca en un titular —un titular con dibujos deja de ser un titular—.
   ============================================================================ */

.glifo {
  display: inline-block;
  width: 1.15em;
  height: 1.15em;
  vertical-align: -0.2em;
  margin: 0 0.1em;
}
.glifo svg { display: block; width: 100%; height: 100%; }

/* --- revelar --- */
.ej-revelar { display: flex; flex-direction: column; gap: 8px; align-items: center; }
.ej-revelar .figura { margin: 0; width: 100%; }

/* --- glosario inline --- */
.termino {
  border-bottom: 1px dashed var(--filete); cursor: help; color: var(--tinta); font-weight: 500;
}
.termino-def {
  display: block; margin: 8px 0; padding: 11px 13px;
  background: var(--superficie); border: 1px solid var(--filete); border-radius: 12px;
  font-size: 14px; line-height: 21px; color: var(--gris);
}

/* ============ Iconos de nivel y de tema ============
   Misma regla que las figuras: el JS emite clases, el color vive aquí. Trazo monolínea,
   cero relleno — el icono no compite con el campo de color del nivel, lo puntúa.

   El `stroke-width` NO se pone aquí: lo calcula `icono()` compensando el tamaño, porque va
   en unidades del viewBox (48) y el mismo valor se ve el doble de fino al doble de tamaño. */
.ico {
  display: block;
  flex: none;
  fill: none;
  stroke: var(--tinta);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Contorno fino y apagado: la clase todavía no está escrita. El icono se gana al existir,
   igual que el color del peldaño (spec §6.5). */
.ico.es-fino { stroke: var(--gris-inactivo); }

/* Lo hipotético dentro del dibujo: el token que aún no se ha decidido, la rama que no se
   toma, lo que se carga bajo demanda. Es el único recurso expresivo del set. */
.ico .es-hipotetico { stroke-dasharray: 3 3; }

/* --- portada: los cinco niveles, uno por tarjeta --- */
.nivel-tarjeta {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--fondo);
  border-radius: var(--radio);
  padding: 15px 16px;
  text-decoration: none;
  color: inherit;
}
.nivel-tarjeta-cuerpo { flex: 1; display: flex; flex-direction: column; gap: 1px; }
.nivel-tarjeta-nombre { font-family: var(--serif); font-size: 26px; line-height: 29px; }
.nivel-tarjeta-lema { font-size: 13px; line-height: 18px; color: var(--gris); }
.nivel-tarjeta-cola { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.nivel-tarjeta-cuenta {
  font-family: var(--mono); font-size: 11px; color: var(--gris);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Un nivel sin clases escritas apaga su texto y su icono, pero NUNCA su color: el color
   del nivel es un hecho, no un estado (spec §6.5). */
.nivel-tarjeta.es-apagada .eyebrow,
.nivel-tarjeta.es-apagada .nivel-tarjeta-nombre,
.nivel-tarjeta.es-apagada .nivel-tarjeta-lema,
.nivel-tarjeta.es-apagada .nivel-tarjeta-cuenta { color: var(--gris-inactivo); }

.niveles { display: flex; flex-direction: column; gap: 11px; }

/* --- cabecera de la vista de nivel --- */
.nivel-cab { display: flex; align-items: flex-start; gap: 16px; margin-top: 16px; }
.nivel-cab-cuerpo { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.nivel-cab h1 { margin: 0; font-size: 32px; line-height: 35px; }
.nivel-cab-lema { font-size: 13.5px; line-height: 19px; color: var(--gris); margin: 0; }

/* Qué falta para que el nivel deje de estar cerrado. Se entra igual —la escalera es una
   recomendación, no una verja—, así que es una nota al margen y no un muro. */
.nivel-cerrado {
  margin: 14px 0 0; font-size: 13px; line-height: 19px; color: var(--gris);
  border-left: 2px solid var(--filete); padding-left: 10px;
}

/* --- el peldaño, ahora con icono y sin promesa ---
   El icono ocupa el sitio de las dos líneas que se van: la promesa se lee en la ficha,
   que es donde decides si entras. */
.peldano .ico { margin-top: 1px; }
.peldano-cuerpo.es-una-linea { justify-content: center; min-height: 30px; }

/* --- ficha y apertura de clase: el mismo icono, en grande y a contorno --- */
.ficha .ico, .clase-apertura-ico { margin: 22px 0 18px; }
.clase-apertura-ico { align-self: center; margin: 0; }
