/*
 * Room Teachers — una sola hoja, sin framework.
 *
 * Sustituye a la hoja terracota manteniendo todos los nombres de tokens y de
 * componentes: las plantillas Jinja no cambian una línea.
 *
 * Dirección: noche tranquila. Fondo azul-gris profundo, un solo acento
 * blurple usado como línea y como halo, nunca como relleno grande. Los
 * botones primarios son un contorno del acento, no un bloque de color: nada
 * en la pantalla grita antes de que el alumno hable.
 *
 * Tema claro incluido: `prefers-color-scheme` y, si algún día hay un
 * conmutador, `[data-theme="light"]` / `[data-theme="dark"]` en <html>.
 */

/* --- tokens: noche -------------------------------------------------------- */
:root {
  --ink: #e9e9ed;
  --ink-soft: #b2b6ca;
  --ink-faint: #75798c;
  --paper: #161826;
  --card: #232532;
  --line: #3f424d;
  --line-soft: #2b2d38;

  /* Blurple. Suficiente cromatismo para ser un acento sobre rampas
     desaturadas, sin la urgencia del rojo o del naranja. */
  --accent: #9184d9;
  --accent-dark: #b5abfc;   /* el paso más claro: hover y texto sobre el wash */
  --accent-wash: #2b2741;
  --good: #7ec8a2;
  --good-wash: #1d2e2a;
  --warn: #d8b46a;
  --warn-wash: #302b1f;
  --bad: #e08a86;
  --bad-wash: #332229;

  --radius: 8px;
  --radius-sm: 4px;
  --shadow: 0 0 0 1px var(--line), 0 6px 18px rgba(0, 0, 0, .45);
  --font: "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Inter", ui-sans-serif, system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --shell: 1080px;
  color-scheme: dark;
}

/* --- tokens: día ---------------------------------------------------------- */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --ink: #23252e;
    --ink-soft: #595d6c;
    --ink-faint: #75798c;
    --paper: #f3f5fe;
    --card: #fdfdff;
    --line: #cfd3e5;
    --line-soft: #e4e7f5;

    --accent: #5d5294;
    --accent-dark: #423a6a;
    --accent-wash: #f5f4ff;
    --good: #2f6b50;
    --good-wash: #e9f3ee;
    --warn: #7d5e12;
    --warn-wash: #f7f0dd;
    --bad: #97403c;
    --bad-wash: #f9ebea;

    --shadow: 0 1px 2px rgba(35, 37, 46, .05), 0 8px 24px -14px rgba(35, 37, 46, .22);
    color-scheme: light;
  }
}

:root[data-theme="light"] {
  --ink: #23252e;
  --ink-soft: #595d6c;
  --ink-faint: #75798c;
  --paper: #f3f5fe;
  --card: #fdfdff;
  --line: #cfd3e5;
  --line-soft: #e4e7f5;
  --accent: #5d5294;
  --accent-dark: #423a6a;
  --accent-wash: #f5f4ff;
  --good: #2f6b50;
  --good-wash: #e9f3ee;
  --warn: #7d5e12;
  --warn-wash: #f7f0dd;
  --bad: #97403c;
  --bad-wash: #f9ebea;
  --shadow: 0 1px 2px rgba(35, 37, 46, .05), 0 8px 24px -14px rgba(35, 37, 46, .22);
  color-scheme: light;
}

/* Inter, alojada en el propio servidor. SIL Open Font License. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/fonts/inter-var.woff2") format("woff2");
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

a { color: var(--accent-dark); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
::selection { background: var(--accent-wash); color: var(--ink); }

h1, h2, h3 { font-family: var(--font-display); font-weight: 500; line-height: 1.18; margin: 0; }
h1 { font-size: 2rem; letter-spacing: -.02em; }
h2 { font-size: 1.3rem; letter-spacing: -.01em; }
h3 { font-size: 1rem; font-weight: 600; }

p { margin: 0 0 .8em; }
p:last-child { margin-bottom: 0; }

/* --- shell ---------------------------------------------------------------- */
.topbar {
  background: color-mix(in srgb, var(--paper) 85%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line-soft);
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar__inner {
  max-width: var(--shell);
  margin: 0 auto;
  padding: .7rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
}
.brand {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: -.01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.brand span { color: var(--accent); }
.nav { display: flex; gap: 1.1rem; flex: 1; flex-wrap: wrap; }
.nav a {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: .92rem;
  font-weight: 500;
  padding: .2rem 0;
  border-bottom: 1px solid transparent;
}
.nav a:hover { color: var(--ink); }
.nav a.is-active { color: var(--ink); border-bottom-color: var(--accent); }

.wallet {
  display: inline-flex;
  align-items: baseline;
  gap: .35rem;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent-dark);
  background: transparent;
  border-radius: 999px;
  padding: .28rem .8rem;
  font-size: .87rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  white-space: nowrap;
}
.wallet:hover { background: var(--accent-wash); color: var(--accent-dark); }

/* El nav va vacío en la cabecera pública; sin esto se queda ocupando el hueco
   flexible y empuja los enlaces de acceso contra el borde. */
.nav:empty { display: none; }
.topbar__link {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: .92rem;
  font-weight: 500;
  white-space: nowrap;
}
.topbar__link:hover { color: var(--ink); }
.wallet small { font-weight: 400; color: var(--ink-faint); }

main { max-width: var(--shell); margin: 0 auto; padding: 2.2rem 1.25rem 5rem; }
.page-head { margin-bottom: 1.5rem; }
.page-head p { color: var(--ink-soft); max-width: 62ch; }
/* Entregado como `.page-head .kicker`; generalizado porque el hero de la
   clase en vivo lleva el mismo sobretítulo y no está dentro de `.page-head`.
   El descendiente era un subconjunto de esto, así que nada pierde estilo. */
.kicker {
  font-size: .76rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .35rem;
}

/* --- cards ---------------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.25rem;
  box-shadow: var(--shadow);
}
/* Separación entre tarjetas apiladas una tras otra… */
.card + .card { margin-top: 1rem; }
/* …pero no dentro de una rejilla, que ya separa con `gap`. Ahí el margen
   empujaba hacia abajo a toda tarjeta que no fuera la primera y, como la
   fila se estira a la misma altura, la dejaba además 16 px más baja: dos
   cajas contiguas con distinto alto y desalineadas. */
.grid > .card + .card { margin-top: 0; }
.card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: .9rem;
  flex-wrap: wrap;
}
.card--flat { box-shadow: none; background: transparent; }
.card--accent {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent),
              0 10px 30px -18px var(--accent);
}

.grid { display: grid; gap: 1rem; }
/* `min(Xpx, 100%)` y no `Xpx` a secas: un `minmax` con mínimo fijo no baja
   de él, así que en una pantalla más estrecha que el mínimo la rejilla se
   sale del viewport en lugar de pasar a una columna. */
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
.stack > * + * { margin-top: 1rem; }

.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); font-size: .86rem; }
.tiny { font-size: .8rem; }

/* --- buttons -------------------------------------------------------------- */
/* El primario es un contorno del acento. Un bloque de color saturado en la
   pantalla previa a hablar añade presión donde no hace falta. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  min-height: 44px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: .5rem 1.05rem;
  font: inherit;
  font-weight: 500;
  font-size: .93rem;
  cursor: pointer;
  text-decoration: none;
  background: transparent;
  color: var(--accent-dark);
  transition: background .14s ease, border-color .14s ease, color .14s ease;
}
.btn:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent-dark);
  border-color: var(--accent-dark);
}
.btn:active { background: color-mix(in srgb, var(--accent) 26%, transparent); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
  background: transparent;
  border-color: var(--line);
  color: var(--ink-faint);
}
.btn--ghost { border-color: var(--line); color: var(--ink); }
.btn--ghost:hover { background: var(--line-soft); border-color: var(--ink-faint); color: var(--ink); }
.btn--danger { border-color: color-mix(in srgb, var(--bad) 60%, transparent); color: var(--bad); }
.btn--danger:hover { background: var(--bad-wash); border-color: var(--bad); color: var(--bad); }
.btn--big { min-height: 56px; padding: .9rem 1.7rem; font-size: 1.05rem; }
.btn--block { width: 100%; }

.actions { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }

/* --- forms ---------------------------------------------------------------- */
label { display: block; font-weight: 500; font-size: .89rem; margin-bottom: .32rem; color: var(--ink); }
.field { margin-bottom: 1.05rem; }
.field .hint { font-size: .84rem; color: var(--ink-faint); margin-top: .35rem; }
.field--error label { color: var(--bad); }
.field--error input, .field--error select, .field--error textarea { border-color: var(--bad); }
.field--error .hint { color: var(--bad); }

/* `input:not([type])` incluido a propósito: un input sin atributo `type` es
   de texto para el navegador pero no lo casa `input[type="text"]`, así que se
   quedaba sin ancho ni borde. Pasaba en cuatro sitios, uno de ellos el nombre
   en el formulario de registro. */
input:not([type]),
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="search"], select, textarea {
  width: 100%;
  min-height: 44px;
  padding: .6rem .75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--paper) 60%, var(--card));
  font: inherit;
  color: var(--ink);
}
::placeholder { color: var(--ink-faint); }
textarea { min-height: 84px; resize: vertical; }
input:hover, select:hover, textarea:hover { border-color: var(--ink-faint); }
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
input[disabled], select[disabled], textarea[disabled] { opacity: .45; cursor: not-allowed; }

/* Radios como tarjetas: una fila de radios de verdad se lee como un
   formulario que rellenar, no como una elección que tomar. */
.choices { display: flex; gap: .5rem; flex-wrap: wrap; }
.choice { position: relative; }
.choice input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.choice span {
  display: flex;
  align-items: center;
  gap: .4rem;
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .5rem .9rem;
  font-size: .92rem;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color .14s ease, background .14s ease, color .14s ease;
}
.choice input:hover + span { border-color: var(--ink-faint); color: var(--ink); }
.choice input:checked + span {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent-dark);
}
.choice input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.choice input[disabled] + span { opacity: .45; cursor: not-allowed; }

/* --- messages ------------------------------------------------------------- */
.alert {
  border-radius: var(--radius-sm);
  padding: .75rem 1rem;
  font-size: .92rem;
  margin-bottom: 1.1rem;
  border: 1px solid transparent;
  border-left-width: 2px;
}
.alert--bad { background: var(--bad-wash); border-color: color-mix(in srgb, var(--bad) 35%, transparent); border-left-color: var(--bad); color: var(--ink); }
.alert--good { background: var(--good-wash); border-color: color-mix(in srgb, var(--good) 32%, transparent); border-left-color: var(--good); color: var(--ink); }
.alert--warn { background: var(--warn-wash); border-color: color-mix(in srgb, var(--warn) 32%, transparent); border-left-color: var(--warn); color: var(--ink); }
.alert--info { background: var(--accent-wash); border-color: color-mix(in srgb, var(--accent) 32%, transparent); border-left-color: var(--accent); color: var(--ink); }

/* --- pills and stats ------------------------------------------------------ */
.pill {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  border-radius: 999px;
  padding: .16rem .62rem;
  font-size: .76rem;
  font-weight: 500;
  letter-spacing: .01em;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-soft);
  white-space: nowrap;
}
.pill--live { border-color: color-mix(in srgb, var(--good) 50%, transparent); color: var(--good); }
.pill--pending { border-color: color-mix(in srgb, var(--warn) 45%, transparent); color: var(--warn); }
.pill--bad { border-color: color-mix(in srgb, var(--bad) 45%, transparent); color: var(--bad); }
.pill--level { border-color: color-mix(in srgb, var(--accent) 50%, transparent); color: var(--accent-dark); }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: .7rem; }
.stat {
  background: transparent;
  border: 0;
  border-left: 1px solid var(--line-soft);
  border-radius: 0;
  padding: .1rem .85rem;
}
.stat__label { font-size: .74rem; color: var(--ink-faint); font-weight: 500; text-transform: uppercase; letter-spacing: .07em; }
.stat__value { font-size: 1.9rem; font-weight: 400; font-variant-numeric: tabular-nums; letter-spacing: -.02em; line-height: 1.1; }
.stat__delta { font-size: .8rem; font-weight: 500; font-variant-numeric: tabular-nums; }
.up { color: var(--good); }
.down { color: var(--bad); }
.flat { color: var(--ink-faint); }

/* Medidores. El número solo no dice nada; la barra es lo que hace que 62 y 84
   se sientan distintos de un vistazo. */
.meter { margin-bottom: .8rem; }
.meter__top { display: flex; justify-content: space-between; font-size: .88rem; margin-bottom: .3rem; }
.meter__top strong { font-weight: 500; font-variant-numeric: tabular-nums; }
.meter__track { height: 4px; border-radius: 999px; background: var(--line-soft); overflow: hidden; }
.meter__fill {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 60%, transparent);
  transition: width .4s ease;
}

/* --- sparkline ------------------------------------------------------------ */
.spark { display: block; width: 100%; height: 56px; overflow: visible; }
.spark__line { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.spark__area { fill: color-mix(in srgb, var(--accent) 14%, transparent); }
.spark__dot { fill: var(--accent-dark); }

/* --- lists and tables ----------------------------------------------------- */
.list { list-style: none; margin: 0; padding: 0; }
.list > li { padding: .7rem 0; border-bottom: 1px solid var(--line-soft); }
.list > li:last-child { border-bottom: 0; padding-bottom: 0; }
.list > li:first-child { padding-top: 0; }

.row { display: flex; gap: 1rem; align-items: center; justify-content: space-between; }
.row__main { min-width: 0; }
.row__title { font-weight: 500; }

table { width: 100%; border-collapse: collapse; font-size: .91rem; }
th, td { text-align: left; padding: .6rem .6rem; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
th { font-size: .74rem; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-faint); font-weight: 500; }
tbody tr:hover { background: color-mix(in srgb, var(--ink) 4%, transparent); }
td.num { text-align: right; font-variant-numeric: tabular-nums; }
.table-wrap { overflow-x: auto; }

/* 360 px: la tabla de correcciones deja de ser tabla y pasa a ser una lista
   de fichas, con el nombre de la columna delante de cada valor. */
@media (max-width: 560px) {
  .table--cards thead { display: none; }
  .table--cards tr {
    display: block;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    padding: .6rem .7rem;
    margin-bottom: .6rem;
  }
  .table--cards td { display: flex; gap: .6rem; border: 0; padding: .18rem 0; }
  .table--cards td::before {
    content: attr(data-label);
    flex: 0 0 6.5rem;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--ink-faint);
    padding-top: .2rem;
  }
  .table--cards td:empty { display: none; }
}

/* --- badges --------------------------------------------------------------- */
.badges { display: flex; flex-wrap: wrap; gap: .6rem; }
.badge {
  display: flex;
  gap: .55rem;
  align-items: flex-start;
  background: transparent;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  padding: .6rem .8rem;
  max-width: 260px;
}
.badge__icon { font-size: 1.25rem; line-height: 1.2; filter: saturate(.75); }
.badge__title { font-weight: 500; font-size: .9rem; }

/* --- lesson-specific ------------------------------------------------------ */
/* La pantalla más emocional del producto: mucho aire, un halo del acento
   detrás del botón, ningún borde duro, ninguna cuenta atrás. */
.live-hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 70%),
    linear-gradient(180deg, var(--card), var(--paper));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 3.2rem 2rem;
  text-align: center;
}
.live-hero h1 { font-size: 2.1rem; margin-bottom: .4rem; }
.live-hero p { color: var(--ink-soft); }
/* `:not(.btn--ghost)` porque el hero lleva dos botones grandes — «Entrar» y
   «Terminar» — y sin esto el descendiente gana en especificidad al modificador
   ghost: los dos salían con el halo del acento y con el mismo peso visual,
   que es justo lo contrario de lo que la jerarquía quiere decir. */
.live-hero .btn--big:not(.btn--ghost) {
  border-color: var(--accent);
  color: var(--accent-dark);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 10%, transparent);
}
.live-hero .btn--big:not(.btn--ghost):hover {
  box-shadow: 0 0 0 10px color-mix(in srgb, var(--accent) 14%, transparent);
}

.dot {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--good);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 55%, transparent);
  margin-right: .45rem;
  animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 50%, transparent); }
  70% { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .dot { animation: none; }
  .meter__fill { transition: none; }
}

/* La frase «¿qué acaba de decir?». Se lee como una cita, porque es lo que es. */
.repeat {
  margin: 0;
  padding: .85rem 1.1rem;
  border-left: 2px solid var(--accent);
  background: var(--accent-wash);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.repeat__who {
  display: block;
  font-size: .72rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--accent-dark);
  margin-bottom: .25rem;
}
.repeat p { font-size: 1.1rem; line-height: 1.5; }

.correction { font-family: var(--mono); font-size: .87rem; }
.correction del { color: var(--bad); text-decoration-thickness: 1px; }
.correction ins { color: var(--good); text-decoration: none; }

.exercise { border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 1.1rem; background: var(--card); }
.exercise + .exercise { margin-top: .9rem; }
.exercise__prompt { font-size: 1.05rem; margin-bottom: .8rem; }
.exercise__prompt code { background: var(--line-soft); padding: .1rem .35rem; border-radius: var(--radius-sm); font-family: var(--mono); }

.chunks { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .8rem; }
.chunk {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .4rem .7rem;
  background: transparent;
  color: var(--ink);
  cursor: grab;
  font-size: .92rem;
  user-select: none;
}
.chunk.is-picked { background: var(--accent-wash); border-color: var(--accent); color: var(--accent-dark); }

/* --- misc ----------------------------------------------------------------- */
.auth-shell { max-width: 400px; margin: 4rem auto; }
.center { text-align: center; }
.empty { text-align: center; padding: 2.6rem 1rem; color: var(--ink-soft); }
.empty h3 { margin-bottom: .4rem; color: var(--ink); }

hr { border: 0; border-top: 1px solid var(--line-soft); margin: 1.2rem 0; }

/* --- HTMX ----------------------------------------------------------------- */
/* Los fragmentos que se cambian solos no deben saltar. Reservan su altura y
   entran con un fundido corto; el spinner ocupa sitio siempre. */
.spinner { display: inline-block; visibility: hidden; }
.htmx-request .spinner, .htmx-request.spinner { visibility: visible; }
[hx-get], [hx-post] { transition: opacity .12s ease; }
.htmx-request[hx-get], .htmx-request[hx-post] { opacity: .6; }
.htmx-settling { opacity: 0; }
.htmx-added { opacity: 0; }
[hx-swap] > * { animation: fade-in .18s ease both; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
#repeat { min-height: 5.2rem; }

@media (max-width: 640px) {
  h1 { font-size: 1.55rem; }
  main { padding: 1.25rem 1rem 4rem; }
  /* Dos filas: marca y saldo arriba, navegación y salida abajo.
     `flex-wrap` es lo que permite que el nav baje de línea — sin él su
     `order` no tiene a dónde ir y los enlaces se apilan cortados contra el
     borde. El nav no envuelve, se desplaza: cinco enlaces en tres filas
     convierten la cabecera en media pantalla. */
  .topbar__inner { gap: .6rem .8rem; flex-wrap: wrap; }
  /* Salto de línea forzado entre el saldo y la navegación. `order` sola no
     basta: ordena, pero no parte, y un nav que puede encogerse acaba
     apretujado al final de la primera fila en lugar de abrir la segunda. */
  .topbar__inner::after {
    content: "";
    flex-basis: 100%;
    height: 0;
    order: 2;
  }
  .nav {
    gap: .9rem;
    order: 3;
    /* `1 1 0` con `min-width: 0`: sin los dos, un elemento flex no baja de
       su ancho de contenido, el nav se queda con la línea entera y «Salir»
       cae a una tercera fila. Con ellos, el nav toma lo que sobra y hace
       scroll por dentro. */
    flex: 1 1 0;
    min-width: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { white-space: nowrap; }
  .topbar__inner form { order: 4; }
  .live-hero { padding: 2.2rem 1.1rem; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .btn--block-mobile { width: 100%; }
}

/* --- landing -------------------------------------------------------------- */
/* La única página que ve alguien sin cuenta. Construida con los componentes
   del producto: enseñar el sitio al que vas es más honesto que una foto de
   archivo, y además no puede prometer una pantalla que no existe. */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: 2.5rem;
  align-items: center;
  padding: 1rem 0 2.5rem;
}
.hero h1 { font-size: clamp(2rem, 4.4vw, 2.9rem); line-height: 1.1; margin-bottom: .9rem; }
.hero__lead { color: var(--ink-soft); font-size: 1.1rem; max-width: 46ch; margin-bottom: 1.4rem; }
.hero__demo .live-hero { padding: 2.2rem 1.5rem; }
/* La maqueta es decorativa: no debe poder recibir el foco al tabular. */
.hero__demo .btn { pointer-events: none; }

/* Dos columnas anchas. `grid--2` reparte en tres a este ancho y deja los
   cuatro pasos en 3 + 1, que se lee como si el último sobrara. */
.grid--wide { grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); }

main > section + section { margin-top: 3.5rem; }
main > section > .page-head h2 { font-size: 1.6rem; }

@media (max-width: 860px) {
  .hero { grid-template-columns: 1fr; gap: 1.8rem; padding-bottom: 1.5rem; }
  .hero__demo { order: -1; }
  main > section + section { margin-top: 2.5rem; }
}

/* --- legal pages and the account screen ---------------------------------- */

/* A card that is about to do something irreversible. Only the border and the
   heading are tinted: a whole red panel reads as an error that has already
   happened rather than a choice still being offered. */
.card--danger { border-color: color-mix(in srgb, var(--bad) 40%, var(--line)); }
.card--danger .card__head h2 { color: var(--bad); }

/* Two-column key/value, for the identity blocks on the legal pages and the
   account summary. Deliberately not `.table--cards`: these are two or three
   rows of plain facts, not a data table that needs to collapse. */
.table--plain th {
  width: 34%;
  text-align: left;
  font-weight: 600;
  color: var(--ink-soft);
  vertical-align: top;
  padding: .42rem .8rem .42rem 0;
}
.table--plain td { padding: .42rem 0; vertical-align: top; }
@media (max-width: 520px) {
  /* At this width a 34% label column leaves the value four characters wide. */
  .table--plain th, .table--plain td { display: block; width: auto; padding: .1rem 0; }
  .table--plain th { padding-top: .55rem; }
}

/* Long-form legal text. The rest of the app is dashboards and forms, so
   nothing existed for a page that is simply read top to bottom. */
.prose { max-width: 68ch; }
.prose h2 { font-size: 1.05rem; margin: 1.9rem 0 .6rem; }
.prose h2:first-child { margin-top: 0; }
.prose p, .prose ul, .prose table { margin-bottom: .9rem; }
.prose ul { padding-left: 1.15rem; }
.prose li { margin-bottom: .4rem; }
.prose li::marker { color: var(--ink-faint); }

/* The footer. Muted on purpose — it is a legal requirement and a way out, not
   part of the pitch. */
.footer {
  border-top: 1px solid var(--line);
  margin-top: 3rem;
  padding: 1.4rem 0 2rem;
}
.footer__inner {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 1.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.4rem;
  align-items: center;
  justify-content: space-between;
  font-size: .85rem;
  color: var(--ink-faint);
}
.footer__brand { font-weight: 600; }
.footer__links { display: flex; flex-wrap: wrap; gap: .5rem 1.1rem; }
.footer__links a { color: var(--ink-faint); text-decoration: none; }
.footer__links a:hover { color: var(--ink); text-decoration: underline; }

/* The beta mark, next to the brand.

   An `<em>` inside the brand link rather than a sibling, so it travels with
   the logo and cannot end up on its own line when the topbar wraps — which is
   exactly what the nav did on a 390px screen before it was pinned down. */
.brand .beta {
  font-style: normal;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  vertical-align: .35em;
  margin-left: .4rem;
  padding: .1rem .34rem;
  border-radius: 5px;
  color: var(--accent);
  background: var(--accent-wash);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
}

/* --- the live transcript -------------------------------------------------- */

/* A `.pill` used as a control rather than a label. The element has to be a
   button — it performs an action and belongs in the tab order — and buttons
   arrive with a font and a background of their own. */
button.pill { cursor: pointer; font: inherit; font-size: .8rem; background: transparent; }
button.pill:hover { border-color: var(--accent); color: var(--accent-dark); }

/* Fixed height and its own scroll: an hour of conversation cannot be allowed
   to push the "Terminar" button off the bottom of the page. */
.transcript {
  max-height: 20rem;
  overflow-y: auto;
  padding: .9rem 1rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  font-size: .92rem;
}
.transcript__line { margin: 0 0 .55rem; }
.transcript__line:last-child { margin-bottom: 0; }
.transcript__who {
  display: inline-block;
  min-width: 4.5rem;
  margin-right: .4rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--ink-faint);
}
.transcript__line--teacher .transcript__who { color: var(--accent); }
@media (max-width: 520px) {
  /* Two words of label and four of speech is not a readable line. */
  .transcript__who { display: block; min-width: 0; margin-bottom: .1rem; }
}

/* El titular de la maqueta del hero. Era un `h2` de verdad y entraba en el
   esquema de encabezados como si fuese una sección de la página. */
.demo__title { font-size: 1.5rem; font-weight: 600; margin: 0 0 .3rem; }
