@font-face {
  font-family: "Inter";
  src: url("/activos/inter-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/activos/inter-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/activos/inter-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/activos/inter-700.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/activos/playfair-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/activos/playfair-400i.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/activos/playfair-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/activos/playfair-700.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/activos/playfair-600i.woff2") format("woff2");
  font-weight: 600;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/activos/jbmono-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/activos/jbmono-700.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

:root {
  --fondo: #0a0a0c;
  /* El panel de una tarjeta: un paso más claro que el fondo, no un color
     aparte, para que las tarjetas se sientan del mismo material. */
  --vitela: #18191c;
  --vitela-alta: #202226;
  --regla: #28292d;
  --tinta: #f5f5f4;
  --rubro: #f04f56;
  --azur: #7c9eff;

  --tenue: #a3a3aa;
  /*
    Para texto que debe pesar menos sin volverse ilegible. Pasa AA en los dos
    fondos oscuros: por encima de 4.5:1 sobre --fondo y sobre --vitela.
  */
  --apagado: #8b8b93;
  /* Un punto más claro que --vitela: la lengüeta del botón del asistente y
     los estados de hover tienen que despegarse del panel. */
  --lengueta: #202226;
  /*
    Dos familias, como antes de Inter: --titular para lo que es contenido
    (títulos, el nombre de una materia) y --cuerpo para lo que es interfaz
    (nav, botones, fechas, chips). Playfair Display es una display serif —
    preciosa grande, casi ilegible en un botón de 13px — así que la regla es
    mecánica: si el elemento es un título o un nombre propio, --titular; si
    es algo que se toca o un dato tabular, --cuerpo. Ver NOTAS-DISENO.md.
  */
  --titular: "Playfair Display", Georgia, serif;
  --cuerpo: "Inter", -apple-system, "Segoe UI", Roboto, sans-serif;
  /* El monospace del sistema cambia de un navegador a otro y se nota, sobre
     todo al lado de Inter y Playfair Display, que sí están cuidadas. Para
     código y el editor de la descripción. */
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* El degradado de la marca: rubro a ámbar, la fruta. Se usa en el
     wordmark del sidebar y nada más: uno solo, no dos. */
  --gradiente-marca: linear-gradient(135deg, #fb7185, #f59e0b);

  /* Escala tipográfica en cuarta justa (1.333), de Bringhurst. */
  --t--1: 0.82rem;
  --t-0: 1rem;
  --t-1: 1.333rem;
  --t-2: 1.777rem;
  --t-3: 2.369rem;
  --t-4: 3.157rem;
  --t-5: 5.61rem;

  --paso: 1.5rem;
}

/* platform.ifruit.site — panel de estudio
   Fondo casi negro, tarjetas para cada bloque, un acento rubro para lo que
   urge y uno azur para lo interactivo. Ver NOTAS-DISENO.md, «Sidebar de
   escritorio, otra vuelta»: se reemplazó el vestido serif/sin-tarjetas por
   este a pedido explícito, para calzar con la maqueta de referencia. */


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

/*
  Nada estira la página. Una URL larga, una fórmula o una palabra sin espacios
  se parten y siguen en la línea de abajo en vez de empujar el ancho del sitio.
  Pasa sobre todo en el Markdown, pero la regla es global a propósito: es más
  fiable que ir tapando cada caso cuando aparece.
*/
* { min-width: 0; }

body, p, li, td, th, h1, h2, h3, h4, a, span, div, blockquote, figcaption {
  overflow-wrap: anywhere;
  word-break: normal;
}

/*
  El recuadro azul que pinta el navegador al tocar. Se quita porque cada
  elemento ya tiene su propia respuesta al toque; el destello del sistema
  encima se ve prestado.
*/
html {
  -webkit-tap-highlight-color: transparent;
}

/*
  Mantener presionado ya no selecciona texto ni abre el menú del sistema
  («Copiar / Compartir» y la tarjeta de diccionario de Google que aparece
  debajo). En una app de consulta ese menú estorba: se toca para leer, no
  para copiar, y encima interrumpe el gesto de deslizar entre pestañas.

  `user-select: none` corta la selección; `-webkit-touch-callout: none`
  corta el menú contextual de iOS, que es independiente.

  Las excepciones son lo que sí tiene sentido copiar: lo que se escribe y
  el bloque de código de una descripción.
*/
body {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

input, textarea, code, pre {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--regla) var(--fondo);
  /* Sin esto, tirar de más arriba o abajo en el celular deja ver un
     rebote blanco del sistema antes de que vuelva a su lugar — se nota
     feo contra el fondo casi negro. */
  overscroll-behavior-y: contain;
}

/* Firefox ya se pinta bien con scrollbar-color de arriba; esto es para
   Chrome/Safari, que si no usan la barra gris cuadrada del sistema. */
::-webkit-scrollbar { width: 0.5rem; height: 0.5rem; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--regla); border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: var(--apagado); }

body {
  margin: 0;
  /*
    El degradado: un resplandor tenue arriba a la izquierda, del color de la
    marca, que se apaga contra el fondo casi negro. Fijo al viewport
    (background-attachment) para que no se note al hacer scroll de una
    página larga.
  */
  background:
    radial-gradient(ellipse 70rem 45rem at 15% -10%, color-mix(in srgb, var(--rubro) 10%, transparent), transparent 60%),
    var(--fondo);
  background-attachment: fixed;
  color: var(--tinta);
  font-family: var(--cuerpo);
  font-size: var(--t-0);
  line-height: 1.6;
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--titular);
  font-weight: 600;
  line-height: 1.1;
  margin: 0;
}

a { color: var(--azur); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--tinta); }

:focus-visible {
  outline: 2px solid var(--azur);
  outline-offset: 3px;
  border-radius: 1px;
}

button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

/* ---------- Armazón ---------- */

.marco {
  max-width: 62rem;
  margin: 0 auto;
  padding: 0 var(--paso);
}

.encabezado {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  /* Solo el eje vertical: el lateral lo pone .marco y no hay que pisarlo. */
  padding-top: 1.75rem;
  padding-bottom: 1.5rem;
}

.marca {
  font-family: var(--titular);
  font-weight: 700;
  font-size: var(--t-1);
  text-decoration: none;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* El wordmark lleva el degradado de la marca; todo lo demás, un solo color. */
  background: var(--gradiente-marca);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.encabezado nav {
  display: flex;
  gap: 1.5rem;
  align-items: baseline;
  font-family: var(--cuerpo);
  font-size: 1.05rem;
}
.encabezado nav a { color: var(--tenue); text-decoration: none; }
.encabezado nav a:hover { color: var(--tinta); }
/* La página actual se marca con la tinta llena, sin subrayado ni caja. */
.encabezado nav a[aria-current="page"] { color: var(--tinta); }

.asistente-nav { display: inline-flex; align-items: center; gap: 0.4rem; }
.asistente-nav .icono { width: 0.8em; height: 0.8em; }

.salir {
  color: var(--tenue);
  font-size: var(--t--1);
}
.salir:hover { color: var(--rubro); }

.tablero {
  display: grid;
  grid-template-columns: 1fr 19rem;
  gap: 0 3rem;
  padding: 1rem 0 5rem;
}

/* Tarjeta genérica: el panel de la marca, un paso más claro que el fondo. */
.tarjeta {
  background: var(--vitela);
  border: 1px solid var(--regla);
  border-radius: 0.85rem;
  padding: 1.25rem 1.4rem;
}

/* ---------- Sidebar (escritorio) ----------
   A partir del mismo ancho en el que la barra inferior ya dejaba de mostrarse
   entra el sidebar: no hay un tercer modo intermedio que sostener. */

.disposicion { display: block; }
.columna { min-width: 0; }
.sidebar { display: none; }

@media (min-width: 48.0625rem) {
  .disposicion { display: flex; align-items: flex-start; }
  .columna { flex: 1; min-width: 0; }
  .encabezado { display: none; }

  .sidebar {
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100svh;
    width: 15rem;
    flex: none;
    padding: 2rem 1.5rem;
    border-right: 1px solid var(--regla);
  }
  .sidebar .marca { font-size: var(--t-2); margin-bottom: 2.5rem; }

  .sidebar nav {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-family: var(--cuerpo);
    font-size: 1.05rem;
  }
  .sidebar nav a {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.5rem 0.6rem;
    margin: 0 -0.6rem;
    border-radius: 0.35rem;
    color: var(--tenue);
    text-decoration: none;
  }
  .sidebar nav a:hover { color: var(--tinta); background: var(--vitela); }
  .sidebar nav a[aria-current="page"] { color: var(--tinta); background: var(--vitela); }

  .sidebar-secundaria {
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--regla);
  }

  /* Avisa que hay algo nuevo en la bitácora sin tener que entrar a mirar. */
  .punto-nuevo {
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: var(--rubro);
    margin-left: auto;
  }

  .sidebar .asistente-nav {
    gap: 0.6rem;
    font-family: var(--cuerpo);
    font-size: 1.05rem;
    color: var(--azur);
  }
  .sidebar .asistente-nav:hover { color: var(--tinta); }
  .sidebar .asistente-nav .icono { width: 1rem; height: 1rem; }

  /* Empuja el pie al fondo del sidebar, sea cual sea el alto del contenido. */
  .sidebar-pie {
    margin-top: auto;
    padding-top: 1.5rem;
    color: var(--apagado);
    font-size: var(--t--1);
    line-height: 1.5;
  }
  .sidebar-pie .lema { color: var(--tenue); }
  .sidebar-pie .derechos { display: block; margin-top: 0.5rem; }
}

.pagina { padding: 1rem 0 5rem; max-width: 46rem; }

.titulo-pagina {
  font-size: var(--t-3);
  margin: 0.5rem 0 2rem;
}

/* ---------- Lo que viene ---------- */

.manana { margin: 0 0 2rem; }

.manana-cabecera {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}
.manana-cabecera h2 { font-size: var(--t-1); font-weight: 600; }
/* Rubro solo cuando de verdad aprieta; si no, es ruido. */
.manana-cabecera h2.urge { color: var(--rubro); }
.manana-fecha { color: var(--tenue); font-size: var(--t--1); white-space: nowrap; }

.manana-fila {
  display: flex;
  align-items: center;
  gap: 1rem;
  text-decoration: none;
  color: inherit;
  background: var(--vitela-alta);
  border-radius: 0.6rem;
  padding: 0.9rem 1.1rem;
}
.manana-fila + .manana-fila { margin-top: 0.5rem; }
.manana-fila:hover { color: inherit; background: color-mix(in srgb, var(--vitela-alta) 85%, white 6%); }

.manana-fila .raya {
  align-self: stretch;
  width: 3px;
  border-radius: 999px;
  background: var(--azur);
  flex: none;
}
.manana-fila .raya.examen, .manana-fila .raya.entrega { background: var(--rubro); }

.manana-cuerpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.manana-materia { font-family: var(--titular); font-weight: 600; font-size: var(--t-1); }
.manana-nota, .manana-cuerpo .sin-desc { color: var(--tenue); font-size: var(--t--1); }
.manana-cuerpo .sin-desc { color: var(--apagado); }

/* ---------- Lista de fechas ---------- */

.seccion {
  font-family: var(--titular);
  font-size: var(--t-1);
  color: var(--tinta);
  margin: 0 0 0.75rem;
  font-weight: 600;
}

.agenda { list-style: none; margin: 0 0 3rem; padding: 0; }

.agenda a {
  display: grid;
  grid-template-columns: 3.5rem 1fr auto;
  gap: 0 1.25rem;
  align-items: baseline;
  padding: 0.7rem 0.6rem 0.7rem 0;
  text-decoration: none;
  color: inherit;
  border-bottom: 1px solid var(--regla);
}
.agenda a:hover { color: inherit; background: var(--vitela); }
.agenda a:hover .materia { color: var(--azur); }

.agenda .fecha {
  font-family: var(--cuerpo);
  font-size: var(--t-0);
  color: var(--tenue);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.agenda .materia {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--titular);
  font-size: var(--t-1);
}
.agenda .materia .icono { color: var(--tenue); }
.agenda .nota,
.agenda .sin-desc {
  color: var(--tenue);
  font-size: var(--t--1);
  margin-left: 0.6rem;
}
.agenda .sin-desc { color: var(--apagado); }

/*
  En escritorio la fila es una sola línea: una nota larga se trunca con
  puntos suspensivos en vez de empujar la fila a dos o tres renglones. En el
  teléfono la columna ya es angosta y la nota va debajo a propósito (ver la
  media query de ahí abajo), así que esto no la toca.
*/
@media (min-width: 48.0625rem) {
  .agenda .detalle {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}

/* El tipo de evento: una palabra en minúscula, sin caja ni mayúsculas. */
.tipo {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  font-family: var(--cuerpo);
  font-size: var(--t--1);
  color: var(--tenue);
}
.tipo.examen, .tipo.entrega { color: var(--rubro); }
.tipo.clase, .tipo.repaso { color: var(--azur); }

/* ---------- Índice de temas ---------- */

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

.indice li + li { border-top: 1px solid var(--regla); }

.indice a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 0;
  font-family: var(--titular);
  font-size: var(--t-1);
  text-decoration: none;
  color: var(--tinta);
}
.indice a:hover { color: var(--azur); }
.indice .cuando { color: var(--tenue); font-size: var(--t--1); font-family: var(--cuerpo); white-space: nowrap; flex: none; }

.materia-titulo {
  font-family: var(--titular);
  font-size: var(--t-0);
  color: var(--tenue);
  font-weight: 400;
  margin: 2.25rem 0 0.35rem;
}
/* Cada materia vive en su propia <section>, así que `.materia-titulo:first-of-type`
   era cierto para TODAS y ninguna tenía aire arriba: solo la primera sección. */
section:first-of-type > .materia-titulo { margin-top: 0; }

/* ---------- Columna lateral ---------- */

.lateral-titulo {
  font-family: var(--titular);
  font-size: var(--t-0);
  color: var(--tinta);
  font-weight: 600;
  margin: 0 0 0.6rem;
}

/* ---------- Versículo del día ----------
   Reemplaza el saludo con nombre de la maqueta original: un «Buenas tardes»
   no dice nada al segundo día, y esto sí cambia. Un icono, la cita y de
   dónde sale, nada más. */
.versiculo { margin: 0 0 1.75rem; }
.versiculo .icono { color: var(--apagado); margin-bottom: 0.6rem; }
.versiculo blockquote {
  margin: 0;
  font-family: var(--titular);
  font-weight: 600;
  font-size: var(--t--1);
  font-style: italic;
  line-height: 1.4;
  color: var(--tenue);
}
.versiculo figcaption {
  margin-top: 0.4rem;
  color: var(--apagado);
  font-size: 0.72rem;
}

/* Insignia «Nuevo» junto a un título de sección. */
.insignia-nuevo {
  font-family: var(--cuerpo);
  font-weight: 600;
  font-size: 0.68rem;
  color: var(--rubro);
  background: color-mix(in srgb, var(--rubro) 16%, transparent);
  border-radius: 999px;
  padding: 0.15rem 0.55rem;
  margin-left: auto;
  white-space: nowrap;
}

.bitacora { list-style: none; margin: 0; padding: 0; font-size: 0.82rem; }
.bitacora li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 0;
}
.bitacora li + li { border-top: 1px solid var(--regla); }

/* Un círculo de color por tipo de recurso, como en la maqueta. */
.bitacora .insignia {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  flex: none;
  background: color-mix(in srgb, var(--azur) 16%, transparent);
  color: var(--azur);
}
.bitacora .insignia.guia { background: color-mix(in srgb, var(--tenue) 18%, transparent); color: var(--tenue); }
.bitacora .insignia.evento { background: color-mix(in srgb, var(--rubro) 16%, transparent); color: var(--rubro); }
.bitacora .insignia .icono { width: 1rem; height: 1rem; }

.bitacora-cuerpo { flex: 1; min-width: 0; }
.bitacora .resumen { display: block; color: var(--tinta); font-size: var(--t--1); line-height: 1.4; }
.bitacora .instante { display: block; color: var(--apagado); font-size: 0.72rem; margin-top: 0.15rem; }

/* El punto de qué tan nuevo es, aparte del texto «Nuevo» que solo lleva el título. */
.bitacora .punto-recencia {
  flex: none;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--regla);
}
.bitacora .punto-recencia.nueva { background: var(--rubro); }

/* La versión de la página propia: más aire, mismo lenguaje visual. */
.bitacora-grande { font-size: var(--t--1); max-width: 36rem; }
.bitacora-grande li { padding: 0.9rem 0; }

.bitacora-resumen { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.nuevo {
  font-family: var(--cuerpo);
  font-weight: 600;
  font-size: 0.68rem;
  color: var(--rubro);
  border: 1px solid var(--rubro);
  border-radius: 999px;
  padding: 0.05rem 0.5rem;
}

.ver-mas {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-top: 1rem;
  font-family: var(--cuerpo);
  font-weight: 600;
  font-size: var(--t--1);
  color: var(--azur);
  text-decoration: none;
}
.ver-mas:hover { color: var(--tinta); }

/* La chispa toma el color del enlace, así no mete un naranja ajeno. */
.chispa {
  width: 0.95em;
  height: 0.95em;
  flex: none;
  background: currentColor;
  -webkit-mask: url("/activos/chispa.svg") center / contain no-repeat;
  mask: url("/activos/chispa.svg") center / contain no-repeat;
  transition: transform 0.25s ease;
}


/* ---------- Iconos (Lucide) ----------
   Mismo mecanismo que la chispa: una máscara en currentColor, así heredan el
   color de quien los usa en vez de traer uno propio. Los SVG son de Lucide
   (lucide.dev), copiados tal cual a web/iconos/. */
.icono {
  display: inline-block;
  width: 1em;
  height: 1em;
  flex: none;
  vertical-align: -0.15em;
  background: currentColor;
  -webkit-mask: var(--svg) center / contain no-repeat;
  mask: var(--svg) center / contain no-repeat;
}
.i-inicio      { --svg: url("/activos/inicio.svg"); }
.i-temas       { --svg: url("/activos/temas.svg"); }
.i-archivos    { --svg: url("/activos/archivos.svg"); }
.i-actividad   { --svg: url("/activos/actividad.svg"); }
.i-evento      { --svg: url("/activos/evento.svg"); }
.i-clip        { --svg: url("/activos/clip.svg"); }
.i-campana     { --svg: url("/activos/campana.svg"); }
.i-flecha-ne   { --svg: url("/activos/flecha-ne.svg"); }
.i-chevron-izq { --svg: url("/activos/chevron-izq.svg"); }
.i-chevron-der { --svg: url("/activos/chevron-der.svg"); }
.i-reloj       { --svg: url("/activos/reloj.svg"); }
.i-sparkles    { --svg: url("/activos/sparkles.svg"); }
.i-enviar      { --svg: url("/activos/enviar.svg"); }
.i-herramienta { --svg: url("/activos/herramienta.svg"); }
.i-alerta      { --svg: url("/activos/alerta.svg"); }
.i-sin-conexion { --svg: url("/activos/sin-conexion.svg"); }
.i-menu        { --svg: url("/activos/menu.svg"); }
.i-camara      { --svg: url("/activos/camara.svg"); }
.i-imagen      { --svg: url("/activos/imagen.svg"); }
.i-clip        { --svg: url("/activos/clip.svg"); }
.i-papelera    { --svg: url("/activos/papelera.svg"); }
.i-mas         { --svg: url("/activos/mas.svg"); }
.i-lapiz       { --svg: url("/activos/lapiz.svg"); }
.i-cerrar      { --svg: url("/activos/cerrar.svg"); }

/* Un icono por materia, en Próximas entregas y en «Mañana». */
.i-atom             { --svg: url("/activos/atom.svg"); }
.i-bug               { --svg: url("/activos/bug.svg"); }
.i-fish-symbol       { --svg: url("/activos/fish-symbol.svg"); }
.i-landmark          { --svg: url("/activos/landmark.svg"); }
.i-book-open         { --svg: url("/activos/book-open.svg"); }
.i-earth             { --svg: url("/activos/earth.svg"); }
.i-briefcase         { --svg: url("/activos/briefcase.svg"); }
.i-scroll-text       { --svg: url("/activos/scroll-text.svg"); }
.i-languages         { --svg: url("/activos/languages.svg"); }
.i-brain             { --svg: url("/activos/brain.svg"); }
.i-drafting-compass  { --svg: url("/activos/drafting-compass.svg"); }
.i-flask-conical     { --svg: url("/activos/flask-conical.svg"); }

.activar-avisos {
  display: block;
  margin-top: 1.5rem;
  font-family: var(--cuerpo);
  font-size: var(--t--1);
  color: var(--tenue);
  border-bottom: 1px solid var(--regla);
  padding-bottom: 2px;
}
.activar-avisos:hover { color: var(--azur); border-color: var(--azur); }

.avisos-nota { color: var(--apagado); font-size: 0.75rem; margin-top: 1.5rem; }

/* ---------- Lectura ---------- */

.lectura { max-width: 36rem; }
.lectura h1 { font-size: var(--t-3); margin-bottom: 0.3rem; }
.lectura .ficha { color: var(--tenue); font-size: var(--t--1); margin: 0 0 2.5rem; }
.lectura .cuerpo > :first-child { margin-top: 0; }
.lectura h2 { font-size: var(--t-2); margin: 2.25rem 0 0.6rem; }
.lectura h3 { font-size: var(--t-1); margin: 1.75rem 0 0.4rem; }
.lectura p, .lectura li { line-height: 1.75; }
.lectura ul, .lectura ol { padding-left: 1.2rem; }
.lectura li { margin: 0.3rem 0; }

.lectura blockquote {
  margin: 1.5rem 0;
  padding-left: 1.2rem;
  border-left: 2px solid var(--regla);
  color: var(--tenue);
}
.lectura code {
  font-family: var(--mono);
  font-size: 0.85em;
  background: var(--vitela);
  padding: 0.1em 0.35em;
  /* Un identificador largo se parte antes que desbordar. */
  overflow-wrap: anywhere;
}
.lectura pre {
  background: var(--vitela);
  padding: 1rem 1.2rem;
  overflow-x: auto;
  border-left: 2px solid var(--regla);
}
.lectura pre code { background: none; padding: 0; }
/*
  La tabla vive dentro de su propio marco deslizable: antes una tabla ancha
  estiraba la página entera y en el teléfono todo el sitio se salía de escala.
*/
.tabla-ancha {
  overflow-x: auto;
  margin: 1.25rem 0;
  /* El desplazamiento no arrastra la página detrás. */
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}
.tabla-ancha:focus-visible { outline: 2px solid var(--azur); outline-offset: 2px; }

.lectura .tabla-ancha table { margin: 0; min-width: 100%; width: max-content; }
.lectura table { border-collapse: collapse; width: 100%; margin: 1.25rem 0; }
.lectura th, .lectura td {
  text-align: left;
  padding: 0.45rem 0.8rem 0.45rem 0;
  border-bottom: 1px solid var(--regla);
  /* En una tabla que se desliza, partir palabras no aporta nada. */
  white-space: nowrap;
}
.lectura th { font-family: var(--cuerpo); font-weight: 600; }
.lectura img { max-width: 100%; }
.lectura hr { border: none; border-top: 1px solid var(--regla); margin: 2rem 0; }

.volver {
  display: inline-block;
  margin-bottom: 2rem;
  color: var(--tenue);
  text-decoration: none;
  font-size: var(--t--1);
}
.volver:hover { color: var(--tinta); }

/* ---------- Fórmulas ---------- */

/*
  KaTeX calcula las alturas suponiendo `line-height: normal`. El 1.75 del
  cuerpo se heredaba dentro de la fórmula y aplastaba las fracciones: la
  línea quedaba encima del numerador.
*/
.katex, .katex * {
  line-height: normal;
  /* Partir una fórmula la vuelve ilegible: se desliza en su contenedor. */
  overflow-wrap: normal;
  word-break: keep-all;
}
.lectura .katex { font-size: 1.05em; }

/* Una fórmula larga se desliza sola en vez de estirar la página. */
.lectura .katex-display {
  overflow-x: auto;
  overflow-y: hidden;
  /* Sitio para la barra de desplazamiento sin que pise la fórmula. */
  padding: 0.5rem 0 0.9rem;
  margin: 1rem 0;
  overscroll-behavior-x: contain;
}
.lectura .katex-display > .katex { text-align: center; }

/* ---------- Archivos ---------- */

.archivos { list-style: none; margin: 0; padding: 0; }
.archivos li + li { border-top: 1px solid var(--regla); }

.archivos a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.85rem 0;
  text-decoration: none;
  color: inherit;
}
.archivos a:hover { color: inherit; }
.archivos a:hover .titulo { color: var(--azur); }
.archivos .titulo { font-family: var(--titular); font-size: var(--t-1); }
.archivos .meta { color: var(--tenue); font-size: var(--t--1); white-space: nowrap; }

.ficha-archivo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 2rem;
  margin-bottom: 1.5rem;
}
.ficha-archivo h1 { font-size: var(--t-2); }
.ficha-archivo .ficha { margin: 0.3rem 0 0; color: var(--tenue); font-size: var(--t--1); }

.descargar,
.abrir {
  font-family: var(--cuerpo);
  font-size: var(--t-0);
  white-space: nowrap;
  text-decoration: none;
  border-bottom: 1px solid var(--regla);
  padding-bottom: 1px;
}
.descargar:hover,
.abrir:hover { border-color: var(--azur); }

/* En el teléfono, «Abrir» es la acción principal: pesa más. */
.abrir {
  font-size: var(--t-1);
  color: var(--tinta);
  border-bottom-color: var(--azur);
}

/*
  Visor en 9:16. El alto se calcula desde la ventana, no desde el ancho, para
  que la hoja entre entera sin scroll dentro del iframe: lo que se lee es una
  página, no una tira.
*/
.visor {
  display: block;
  /* Alto atado a la ventana: la hoja entra entera sin scroll interno. */
  height: calc(100svh - 12rem);
  /*
    9:16 es la proporción de la ventana, no la del papel. El visor necesita
    algo más de ancho que eso para que una hoja carta se vea completa y no
    quede una columna diminuta en el centro; 0.78 la deja llenando el alto.
  */
  width: min(100%, calc((100svh - 12rem) * 0.78));
  border: 1px solid var(--regla);
  background: var(--vitela);
  margin: 0 auto;
}

/* Escritorio por defecto; la media query de abajo las intercambia. */
.solo-movil { display: none; }
.solo-escritorio { display: inline-block; }

/* ---------- Horario ---------- */

.horario { margin: 0 0 2rem; }
.horario .cabecera-seccion { margin-bottom: 0.6rem; }

/* Plegado: solo las clases del día, que es lo que se consulta a diario. */
.clases-hoy { list-style: none; margin: 0; padding: 0; }
.clases-hoy li {
  display: flex;
  gap: 1rem;
  align-items: baseline;
  padding: 0.35rem 0;
}
.clases-hoy li + li { border-top: 1px solid var(--regla); }
.clases-hoy .hora {
  color: var(--tenue);
  font-size: var(--t--1);
  font-variant-numeric: tabular-nums;
  min-width: 3.2rem;
}
.clases-hoy .clase { font-family: var(--titular); font-size: var(--t-0); }

.rejilla-horario {
  border-collapse: collapse;
  font-size: var(--t--1);
  min-width: 100%;
  width: max-content;
}
.rejilla-horario th,
.rejilla-horario td {
  text-align: left;
  padding: 0.4rem 0.9rem 0.4rem 0;
  border-bottom: 1px solid var(--regla);
  white-space: nowrap;
}
/*
  La columna de la hora queda fija al desplazar: sin ella las materias son
  una lista suelta y no se sabe a qué bloque pertenece cada una.
*/
.rejilla-horario th:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--fondo);
  padding-right: 1.1rem;
}
.rejilla-horario thead th {
  font-family: var(--cuerpo);
  font-weight: 400;
  color: var(--tenue);
}
.rejilla-horario tbody th {
  font-family: var(--cuerpo);
  font-weight: 400;
  color: var(--tenue);
  font-variant-numeric: tabular-nums;
}
/* La columna del día que toca: lo demás es referencia. */
.rejilla-horario .hoy { color: var(--tinta); }
.rejilla-horario thead .hoy { color: var(--azur); }
.rejilla-horario .recreo th { color: var(--apagado); }
.rejilla-horario .etiqueta { font-style: italic; }
/* La fila del recreo es un respiro, no una clase: menos alto y sin texto. */
.rejilla-horario .recreo td { padding-block: 0.2rem; }

/* Insinuar que la tabla sigue a la derecha, en vez de cortarla en seco. */
.tabla-ancha {
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent);
}
.tabla-ancha::-webkit-scrollbar { display: none; }

/* ---------- Calendario ---------- */

.calendario { margin-top: 0.5rem; }
.calendario.tarjeta { margin: 0 0 1.75rem; }

.control {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.75rem;
}
.control h2 { font-size: var(--t-1); font-weight: 600; color: var(--tinta); }
.control button { color: var(--apagado); font-size: var(--t-0); padding: 0 0.2rem; }
.control button:hover { color: var(--tinta); }
.control .hoy-btn { margin-left: auto; font-size: var(--t--1); color: var(--tenue); }

.mes { width: 100%; border-collapse: collapse; table-layout: fixed; }
.mes th {
  font-family: var(--cuerpo);
  font-weight: 400;
  font-size: var(--t--1);
  color: var(--tenue);
  padding-bottom: 0.5rem;
  text-align: left;
}
.mes td {
  vertical-align: top;
  height: 3.2rem;
  padding: 0;
  font-size: var(--t--1);
  border-top: 1px solid var(--regla);
  text-align: center;
}
.mes td.fuera { border-top-color: transparent; }

/*
  La celda ya no lleva el nombre de la materia: no cabía y se cortaba a la
  mitad. Un punto por tarea, y el detalle sale al tocar el día.
*/
.mes .dia {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  width: 100%;
  padding: 0.45rem 0.1rem;
  color: var(--tenue);
  font-variant-numeric: tabular-nums;
  font-size: var(--t--1);
  line-height: 1;
}
.mes button.dia { cursor: pointer; color: var(--tinta); }
.mes button.dia:hover { background: var(--vitela); }

.mes .numero {
  display: inline-grid;
  place-items: center;
  min-width: 1.6em;
  min-height: 1.6em;
  border-radius: 50%;
}
.mes .hoy .numero { background: var(--azur); color: var(--fondo); font-weight: 700; }
.mes .elegido .numero { box-shadow: inset 0 0 0 1px var(--tinta); }
.mes .elegido.hoy .numero { box-shadow: none; }

/*
  Los días sin clases se apagan: el sombreado dice «acá no pasa nada» sin
  necesidad de una leyenda. Los feriados además llevan su nombre debajo.
*/
.mes .sin-clases .numero { color: var(--regla); }
.mes .sin-clases { background: color-mix(in srgb, var(--vitela) 45%, transparent); }
.mes .feriado .numero { color: var(--rubro); opacity: 0.55; }
/* Hoy manda por encima del sombreado. */
.mes .hoy .numero { color: var(--fondo); opacity: 1; }

.feriados {
  list-style: none;
  margin: 0.85rem 0 0;
  padding: 0;
  font-size: var(--t--1);
  color: var(--tenue);
}
.feriados li { padding: 0.15rem 0; display: flex; gap: 0.6rem; align-items: baseline; }
.dia-feriado {
  color: var(--rubro);
  font-variant-numeric: tabular-nums;
  min-width: 1.4em;
  text-align: right;
}

.puntos { display: flex; gap: 2px; min-height: 5px; }
.punto { width: 5px; height: 5px; border-radius: 50%; display: block; }
.punto.examen, .punto.entrega { background: var(--rubro); }
.punto.clase, .punto.repaso { background: var(--azur); }

/*
  El calendario va primero y la lista debajo responde a él: por defecto
  muestra todo lo que viene, y al tocar un día solo ese. Una sola lista que
  se filtra, en vez de dos que dicen cosas distintas.
*/
.lista-dia { margin-top: 2rem; }

.lista-cabecera {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.75rem;
}
.lista-cabecera .seccion { margin: 0; }

.quitar-dia {
  margin-left: auto;
  font-family: var(--cuerpo);
  font-size: var(--t--1);
  color: var(--apagado);
  border-bottom: 1px solid var(--regla);
  padding-bottom: 1px;
}
.quitar-dia:hover { color: var(--azur); border-color: var(--azur); }

/* Al cambiar de día, la lista se renueva en vez de saltar. */
.lista-dia .agenda { animation: desplegar var(--medio) var(--cozy) both; }

.filtros {
  display: flex;
  gap: 1.1rem;
  flex-wrap: wrap;
  margin: 0 0 1.5rem;
  font-family: var(--cuerpo);
  font-size: var(--t-0);
}
.filtros button { color: var(--apagado); padding: 0.1rem 0; }
.filtros button:hover { color: var(--tinta); }
.filtros button[aria-pressed="true"] { color: var(--tinta); }

/* ---------- Subida ----------

   Una sola línea: clip, nombre, flecha. Antes eran tres bloques apilados con
   sus etiquetas para pedir dos datos; el icono ya dice qué hace cada parte.
*/

.subir { margin: 0 0 2rem; }

.subir .campos {
  display: flex;
  align-items: stretch;
  gap: 0;
  background: var(--vitela);
  border: 1px solid var(--regla);
  border-radius: 999px;
  padding: 0.2rem;
  transition: border-color var(--rapido) var(--cozy);
}
.subir .campos:focus-within { border-color: var(--azur); }
.subir.con-archivo .campos { border-color: var(--apagado); }

/* Accesible para quien no ve el icono, invisible para quien sí. */
.sr-solo {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.subir .elegir {
  display: grid;
  place-items: center;
  width: 2.5rem;
  flex: none;
  border-radius: 999px;
  color: var(--tenue);
  cursor: pointer;
  transition: color var(--rapido) var(--cozy), background-color var(--rapido) var(--cozy);
}
.subir .elegir:hover { color: var(--tinta); background: var(--fondo); }
.subir .elegir:focus-within { outline: 2px solid var(--azur); outline-offset: -2px; }
.subir.con-archivo .elegir { color: var(--azur); }

.clip {
  width: 1.15rem;
  height: 1.15rem;
  background: currentColor;
  -webkit-mask: url("/activos/clip.svg") center / contain no-repeat;
  mask: url("/activos/clip.svg") center / contain no-repeat;
  transition: transform var(--medio) var(--cozy);
}
.subir.con-archivo .clip { transform: rotate(-12deg); }

.subir input[type="file"] { display: none; }

.subir .nombre {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-family: var(--cuerpo);
  font-size: var(--t-0);
  color: var(--tinta);
  background: none;
  border: none;
  padding: 0.5rem 0.4rem;
}
.subir .nombre:focus { outline: none; }
.subir .nombre::placeholder { color: var(--apagado); }

.subir button[type="submit"] {
  display: grid;
  place-items: center;
  width: 2.5rem;
  flex: none;
  border-radius: 999px;
  color: var(--fondo);
  background: var(--azur);
  transition:
    background-color var(--rapido) var(--cozy),
    opacity var(--rapido) var(--cozy),
    transform var(--rapido) var(--cozy);
}
.subir button[type="submit"]:disabled {
  background: none;
  color: var(--regla);
  cursor: default;
}
.subir button[type="submit"]:not(:disabled):hover { background: var(--tinta); }

.flecha {
  width: 1.05rem;
  height: 1.05rem;
  background: currentColor;
  -webkit-mask: url("/activos/flecha-arriba.svg") center / contain no-repeat;
  mask: url("/activos/flecha-arriba.svg") center / contain no-repeat;
}

/* Mientras sube, la flecha se vuelve un giro. */
.girando {
  width: 0.95rem;
  height: 0.95rem;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: girar 0.7s linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }

.elegido-nombre {
  color: var(--tenue);
  font-size: var(--t--1);
  margin: 0.5rem 0 0;
  padding-left: 0.9rem;
  animation: desplegar var(--medio) var(--cozy) both;
}

/* ---------- Descripción ---------- */

.descripcion { margin-top: 3rem; }

.cabecera-seccion {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 1rem;
}
.cabecera-seccion h2 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--titular);
  font-size: var(--t-1);
  font-weight: 600;
  color: var(--tinta);
}
.cabecera-seccion .pista,
.cabecera-seccion .editar { margin-left: auto; font-size: var(--t--1); color: var(--tenue); }
.cabecera-seccion .editar:hover { color: var(--azur); }

.editor {
  width: 100%;
  font-family: var(--mono);
  font-size: 0.88rem;
  line-height: 1.65;
  color: var(--tinta);
  background: var(--vitela);
  border: 1px solid var(--regla);
  padding: 0.9rem 1rem;
  resize: vertical;
}
.editor:focus { border-color: var(--azur); outline: none; }

.acciones { display: flex; align-items: center; gap: 1.25rem; margin-top: 0.85rem; }
.acciones button { font-family: var(--cuerpo); font-size: var(--t-0); color: var(--tenue); }
.acciones button:hover:not(:disabled) { color: var(--tinta); }
.acciones .principal { color: var(--tinta); border-bottom: 1px solid var(--azur); padding-bottom: 1px; }
.acciones button:disabled { color: var(--apagado); cursor: default; }
.acciones .aviso { margin: 0; }

.enlaces-evento { display: flex; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 0; }

/* ---------- Portada ---------- */

.portada {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: var(--paso);
}
.portada form { width: 100%; max-width: 18rem; }
.portada h1 { font-size: var(--t-3); margin-bottom: 0.15rem; }
.portada .sub { color: var(--tenue); font-size: var(--t--1); margin: 0 0 2.5rem; }

.portada input {
  width: 100%;
  font: inherit;
  font-family: var(--cuerpo);
  font-size: var(--t-1);
  color: var(--tinta);
  background: none;
  border: none;
  border-bottom: 1px solid var(--regla);
  padding: 0.4rem 0;
}
.portada input:focus { border-bottom-color: var(--azur); outline: none; }

.portada button[type="submit"] {
  margin-top: 1.5rem;
  font-family: var(--cuerpo);
  font-size: var(--t-1);
  color: var(--tinta);
}
.portada button[type="submit"]:hover:not(:disabled) { color: var(--azur); }
.portada button[type="submit"]:disabled { color: var(--apagado); cursor: default; }

.vacio { color: var(--tenue); font-style: italic; padding: 1rem 0; }

/* ---------- Asistente ----------
   El chat es una vista de app, no una página: ocupa la pantalla entera, la
   transcripción es lo único que se desplaza y el campo de texto queda fijo
   abajo. En el teléfono desaparecen el encabezado y la barra inferior (la
   navegación pasa al drawer, como en la app de Claude que sirvió de
   referencia); en escritorio queda el sidebar del sitio, el historial y la
   charla, cada uno con su propio alto.

   Lo que el asistente responde es texto para leer, así que se compone igual
   que un tema (Markdown + KaTeX, Playfair en los títulos). Lo que el usuario
   escribe va en una burbuja discreta a la derecha, para distinguir de un
   vistazo quién dijo qué. El único gesto con personalidad es la chispa de la
   marca, con el degradado, mientras el asistente trabaja. */

.en-asistente .marco { max-width: none; padding: 0; }
body:has(.en-asistente) { padding-bottom: 0; }

.asistente {
  display: flex;
  height: 100dvh;
  overflow: hidden;
}

.conversacion {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.conversacion-cabecera {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  max-width: 46rem;
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 0.5rem) var(--paso) 0.5rem;
  min-height: 3.5rem;
}
.conversacion-titulo {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-family: var(--cuerpo);
  font-weight: 500;
  font-size: 0.95rem;
  color: var(--tenue);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.conexion { margin: 0; font-size: var(--t--1); color: var(--apagado); white-space: nowrap; }
.conexion.conectando { animation: latir 1.6s ease-in-out infinite; }
.conexion.cortada { color: var(--rubro); }

.boton-icono {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  color: var(--tenue);
  border-radius: 999px;
  transition: background-color var(--rapido) var(--cozy), color var(--rapido) var(--cozy);
}
.boton-icono:hover { color: var(--tinta); background: var(--lengueta); }
.boton-icono .icono { width: 1.15rem; height: 1.15rem; }
.asistente-menu { margin-left: -0.6rem; }

/* La transcripción se desvanece contra los bordes en vez de cortarse seco
   debajo del campo de texto. */
.transcripcion {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 1rem, #000 calc(100% - 1.5rem), transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 1rem, #000 calc(100% - 1.5rem), transparent);
}

.intercambios {
  list-style: none;
  margin: 0 auto;
  padding: 1.25rem var(--paso) 2rem;
  max-width: 46rem;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

/* ---- Vacío ---- */

.asistente-vacio {
  min-height: 100%;
  max-width: 46rem;
  margin: 0 auto;
  padding: 2rem var(--paso);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.asistente-vacio h2 {
  margin: 0 0 1.75rem;
  font-family: var(--titular);
  font-weight: 600;
  font-size: var(--t-3);
  line-height: 1.1;
  color: var(--tinta);
}
.tareas { list-style: none; margin: 0; padding: 0; }
.tareas li + li { border-top: 1px solid var(--regla); }
.tareas button {
  display: block;
  width: 100%;
  padding: 0.85rem 0;
  text-align: left;
  font-family: var(--cuerpo);
  font-size: var(--t-0);
  color: var(--tenue);
  transition: color var(--rapido) var(--cozy), padding var(--rapido) var(--cozy);
}
.tareas button:hover:not(:disabled) { color: var(--tinta); padding-left: 0.35rem; }
.tareas button:disabled { color: var(--apagado); cursor: default; }

/* ---- Mensajes ---- */

.mensaje-usuario {
  align-self: flex-end;
  max-width: min(85%, 34rem);
  padding: 0.65rem 1rem;
  background: var(--vitela-alta);
  border-radius: 1.15rem 1.15rem 0.35rem 1.15rem;
  color: var(--tinta);
  -webkit-user-select: text;
  user-select: text;
}
.mensaje-usuario p { margin: 0; line-height: 1.55; white-space: pre-wrap; }
.mensaje-adjuntos {
  list-style: none;
  margin: 0 0 0.35rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: var(--t--1);
  color: var(--tenue);
}
.mensaje-adjuntos li { display: flex; align-items: center; gap: 0.4rem; }
.mensaje-adjuntos .icono { width: 0.85rem; height: 0.85rem; flex: none; }

.respuesta { display: flex; flex-direction: column; gap: 0.6rem; }

.actividad {
  margin: 0;
  font-size: var(--t--1);
  color: var(--apagado);
}
.actividad.en-curso { display: flex; align-items: center; gap: 0.55rem; color: var(--tenue); }
.actividad.en-curso .chispa {
  width: 1.05rem;
  height: 1.05rem;
  background: var(--gradiente-marca);
  animation: chispear 1.8s ease-in-out infinite;
}
@keyframes chispear {
  0% { transform: rotate(0deg) scale(0.85); opacity: 0.7; }
  50% { transform: rotate(90deg) scale(1.05); opacity: 1; }
  100% { transform: rotate(180deg) scale(0.85); opacity: 0.7; }
}
@media (prefers-reduced-motion: reduce) {
  .actividad.en-curso .chispa { animation: none; }
}
.actividad summary {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  list-style: none;
}
.actividad summary::-webkit-details-marker { display: none; }
.actividad summary:hover { color: var(--tenue); }
.actividad summary .icono { width: 0.8rem; height: 0.8rem; }
.actividad ul {
  list-style: none;
  margin: 0.5rem 0 0.25rem;
  padding: 0 0 0 1.2rem;
  border-left: 1px solid var(--regla);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.actividad .pensamiento { font-style: italic; line-height: 1.5; white-space: pre-wrap; }

.respuesta-error {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: var(--t--1);
  color: var(--rubro);
}
.respuesta-error .icono { flex: none; }

/* La respuesta se compone como un tema, en una escala más chica. */
.prosa {
  color: var(--tinta);
  line-height: 1.7;
  -webkit-user-select: text;
  user-select: text;
}
.prosa > :first-child { margin-top: 0; }
.prosa > :last-child { margin-bottom: 0; }
.prosa p { margin: 0.7rem 0; }
.prosa h1, .prosa h2, .prosa h3, .prosa h4 {
  font-family: var(--titular);
  font-weight: 600;
  line-height: 1.25;
  margin: 1.4rem 0 0.5rem;
}
.prosa h1 { font-size: var(--t-2); }
.prosa h2 { font-size: var(--t-1); }
.prosa h3, .prosa h4 { font-size: 1.1rem; }
.prosa strong { font-weight: 600; color: var(--tinta); }
.prosa ul, .prosa ol { margin: 0.6rem 0; padding-left: 1.3rem; }
.prosa li { margin: 0.3rem 0; }
.prosa li::marker { color: var(--apagado); }
.prosa blockquote {
  margin: 1rem 0;
  padding-left: 1rem;
  border-left: 2px solid var(--regla);
  color: var(--tenue);
}
.prosa code {
  font-family: var(--mono);
  font-size: 0.85em;
  background: var(--vitela);
  padding: 0.1em 0.35em;
  border-radius: 0.3em;
  overflow-wrap: anywhere;
}
.prosa pre {
  margin: 1rem 0;
  padding: 0.9rem 1rem;
  background: var(--vitela);
  border-radius: 0.6rem;
  overflow-x: auto;
}
.prosa pre code { background: none; padding: 0; }
.prosa hr { border: none; border-top: 1px solid var(--regla); margin: 1.5rem 0; }
.prosa table { border-collapse: collapse; margin: 0; min-width: 100%; width: max-content; }
.prosa th, .prosa td {
  text-align: left;
  padding: 0.45rem 0.9rem 0.45rem 0;
  border-bottom: 1px solid var(--regla);
  white-space: nowrap;
}
.prosa th { font-weight: 600; }
.prosa .katex-display { margin: 1rem 0; overflow-x: auto; overflow-y: hidden; }

.asistente-reconectar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: min(46rem - 2 * var(--paso), calc(100% - 2 * var(--paso)));
  margin: 0 auto 0.5rem;
  padding: 0.6rem 0.9rem;
  background: var(--vitela);
  border-radius: 0.7rem;
  color: var(--tenue);
  font-size: var(--t--1);
}
.asistente-reconectar .icono { color: var(--rubro); flex: none; }
.asistente-reconectar button { margin-left: auto; color: var(--azur); font-weight: 600; }
.asistente-reconectar button:hover { color: var(--tinta); }

/* ---- Campo de texto ---- */

.compositor {
  width: min(46rem - 2 * var(--paso), calc(100% - 2 * var(--paso)));
  margin: 0 auto;
  padding-bottom: max(0.9rem, env(safe-area-inset-bottom));
}

.compositor-fila {
  display: flex;
  align-items: flex-end;
  gap: 0.25rem;
  padding: 0.3rem;
  background: var(--vitela);
  border: 1px solid var(--regla);
  border-radius: 1.5rem;
  transition: border-color var(--rapido) var(--cozy);
}
.compositor-fila:focus-within { border-color: color-mix(in srgb, var(--azur) 55%, var(--regla)); }

.compositor textarea {
  flex: 1;
  min-width: 0;
  max-height: 11rem;
  margin: 0;
  padding: 0.6rem 0.3rem;
  resize: none;
  font: inherit;
  font-family: var(--cuerpo);
  font-size: var(--t-0);
  line-height: 1.5;
  color: var(--tinta);
  background: none;
  border: none;
  overflow-y: auto;
}
.compositor textarea:focus { outline: none; }
.compositor textarea::placeholder { color: var(--apagado); }

.boton-enviar {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  border-radius: 999px;
  color: var(--fondo);
  background: var(--azur);
  transition: background-color var(--rapido) var(--cozy), color var(--rapido) var(--cozy);
}
.boton-enviar .icono { width: 1.05rem; height: 1.05rem; }
.boton-enviar:not(:disabled):hover { background: var(--tinta); }
.boton-enviar:disabled { background: var(--vitela-alta); color: var(--apagado); cursor: default; }
.boton-enviar:not(:disabled):active { transform: scale(0.9); }
.boton-enviar { transition: background-color var(--rapido) var(--cozy), color var(--rapido) var(--cozy), transform 0.12s ease; }

.compositor-aviso { margin: 0 0.75rem 0.45rem; font-size: var(--t--1); color: var(--rubro); }

.adjuntos-pendientes {
  list-style: none;
  margin: 0 0 0.5rem;
  padding: 0;
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
}
.adjuntos-pendientes li {
  position: relative;
  flex: none;
  width: 3.75rem;
  height: 3.75rem;
  border-radius: 0.75rem;
  overflow: hidden;
  background: var(--vitela);
  border: 1px solid var(--regla);
}
.adjuntos-pendientes img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }
.adjuntos-pendientes li.subiendo { display: grid; place-items: center; color: var(--tenue); }
.adjuntos-pendientes button {
  position: absolute;
  top: 0.2rem;
  right: 0.2rem;
  width: 1.3rem;
  height: 1.3rem;
  display: grid;
  place-items: center;
  color: var(--tinta);
  background: rgb(0 0 0 / 70%);
  border-radius: 50%;
}
.adjuntos-pendientes button .icono { width: 0.75rem; height: 0.75rem; }
.adjuntos-pendientes button:hover { background: var(--rubro); }

/* Un PDF no tiene miniatura que valga la pena: va su nombre y sus páginas. */
.adjuntos-pendientes li.documento {
  width: auto;
  max-width: 15rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 2.1rem 0 0.8rem;
  font-size: var(--t--1);
  color: var(--tinta);
}
.adjuntos-pendientes li.documento > .icono { width: 1.1rem; height: 1.1rem; color: var(--azur); flex: none; }
.adjunto-nombre { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adjunto-paginas { flex: none; color: var(--apagado); font-size: 0.72rem; }
.adjuntos-pendientes li.documento button { top: 50%; transform: translateY(-50%); right: 0.45rem; }

.compositor-modo {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0.75rem 0.5rem;
  font-size: var(--t--1);
  color: var(--tenue);
}
.compositor-modo .icono { width: 0.9rem; height: 0.9rem; color: var(--azur); flex: none; }
.compositor-modo button { margin-left: auto; color: var(--azur); font-size: var(--t--1); }
.compositor-modo button:hover { color: var(--tinta); }

/* ---- Menú «+» ---- */

.menu-mas { position: relative; flex: none; }
.boton-mas[aria-expanded="true"] { color: var(--tinta); background: var(--lengueta); }
.boton-mas[aria-expanded="true"] .icono { transform: rotate(45deg); }
.boton-mas .icono { transition: transform var(--rapido) var(--cozy); }

.menu-mas-fondo { position: fixed; inset: 0; background: none; z-index: 30; cursor: default; }

.menu-mas-panel {
  position: absolute;
  bottom: calc(100% + 0.7rem);
  left: -0.3rem;
  width: min(22rem, calc(100vw - 2rem));
  max-height: min(34rem, calc(100dvh - 7rem));
  overflow-y: auto;
  padding: 0.5rem;
  background: var(--vitela-alta);
  border: 1px solid var(--regla);
  border-radius: 1.1rem;
  box-shadow: 0 1rem 2.5rem rgb(0 0 0 / 45%);
  z-index: 31;
  transform-origin: 1.2rem 100%;
  animation: menu-abrir 0.24s cubic-bezier(0.32, 0.72, 0, 1) both;
}

.menu-mas-fuentes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.4rem; }
.menu-mas-fuentes label {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.85rem 0.3rem 0.7rem;
  border-radius: 0.8rem;
  background: var(--vitela);
  font-size: var(--t--1);
  color: var(--tinta);
  cursor: pointer;
  overflow: hidden;
}
.menu-mas-fuentes label:hover { background: var(--lengueta); }
.menu-mas-fuentes label:focus-within { outline: 2px solid var(--azur); outline-offset: 1px; }
.menu-mas-fuentes .icono { width: 1.25rem; height: 1.25rem; color: var(--azur); }
.menu-mas-fuentes input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }

.menu-mas-titulo {
  margin: 0.75rem 0.5rem 0.3rem;
  font-size: 0.72rem;
  color: var(--apagado);
}

.menu-mas-habilidades {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.15rem;
}
.menu-mas-habilidades button {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.55rem 0.5rem;
  border-radius: 0.55rem;
  text-align: left;
  font-size: var(--t--1);
  line-height: 1.3;
  color: var(--tinta);
}
.menu-mas-habilidades button:hover { background: var(--lengueta); }
.menu-mas-habilidades .icono { width: 1rem; height: 1rem; color: var(--azur); flex: none; }

.menu-mas-tareas {
  list-style: none;
  margin: 0;
  padding: 0;
}
.menu-mas-tareas button {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  width: 100%;
  padding: 0.55rem 0.5rem;
  border-radius: 0.55rem;
  text-align: left;
  font-size: var(--t--1);
  line-height: 1.4;
  color: var(--tinta);
}
.menu-mas-tareas button:hover:not(:disabled) { background: var(--lengueta); }
.menu-mas-tareas button:disabled { color: var(--apagado); cursor: default; }
.menu-mas-tareas .icono { width: 0.95rem; height: 0.95rem; margin-top: 0.1rem; color: var(--azur); flex: none; }

/* ---- Movimiento dentro del chat ----
   Todo responde a algo que se hizo: el mensaje propio sale desde donde se
   escribió (abajo a la derecha), la respuesta asoma, el menú se abre desde
   su botón. La pantalla vacía entra escalonada una sola vez, al llegar. */

.mensaje-usuario.recien {
  transform-origin: 100% 100%;
  animation: burbuja 0.34s cubic-bezier(0.34, 1.3, 0.5, 1) both;
}
.respuesta.recien { animation: asomar 0.42s cubic-bezier(0.32, 0.72, 0, 1) both; }
.adjuntos-pendientes li { transform-origin: 50% 100%; animation: burbuja 0.28s cubic-bezier(0.34, 1.3, 0.5, 1) both; }

.asistente-vacio h2 { animation: asomar 0.5s 0.1s cubic-bezier(0.32, 0.72, 0, 1) both; }
.tareas li { animation: asomar 0.45s cubic-bezier(0.32, 0.72, 0, 1) both; }
.tareas li:nth-child(1) { animation-delay: 0.16s; }
.tareas li:nth-child(2) { animation-delay: 0.21s; }
.tareas li:nth-child(3) { animation-delay: 0.26s; }
.tareas li:nth-child(4) { animation-delay: 0.31s; }

@keyframes burbuja {
  from { opacity: 0; transform: translateY(0.6rem) scale(0.94); }
  to { opacity: 1; transform: none; }
}
@keyframes asomar {
  from { opacity: 0; transform: translateY(0.5rem); }
  to { opacity: 1; transform: none; }
}
@keyframes menu-abrir {
  from { opacity: 0; transform: translateY(0.4rem) scale(0.95); }
  to { opacity: 1; transform: none; }
}

/* ---------- Historial del asistente ---------- */

.historial-fondo {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / 55%);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--rapido) var(--cozy);
  z-index: 40;
}
.historial-fondo.abierto { opacity: 1; pointer-events: auto; -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }

.historial {
  position: fixed;
  inset: 0 auto 0 0;
  width: min(84vw, 20rem);
  display: flex;
  flex-direction: column;
  padding-top: env(safe-area-inset-top);
  background: var(--vitela);
  transform: translateX(-100%);
  transition: transform 0.36s cubic-bezier(0.32, 0.72, 0, 1);
  z-index: 41;
}
.historial.abierto { transform: translateX(0); box-shadow: 1rem 0 3rem rgb(0 0 0 / 45%); }

.historial-cabecera { display: flex; align-items: center; gap: 0.4rem; padding: 0.75rem 0.6rem 0.5rem 0.75rem; }

.historial-nueva {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.65rem 0.8rem;
  border-radius: 0.75rem;
  font-weight: 500;
  font-size: 0.92rem;
  color: var(--tinta);
  transition: background-color var(--rapido) var(--cozy);
}
.historial-nueva:hover { background: var(--lengueta); }
.historial-nueva .icono { width: 1.05rem; height: 1.05rem; color: var(--azur); }

.historial-lista { flex: 1; min-height: 0; overflow-y: auto; padding: 0.25rem 0.5rem 1rem; }
.historial-lista ul { list-style: none; margin: 0; padding: 0; }
.historial-lista li { display: flex; align-items: center; border-radius: 0.6rem; }
.historial-lista li:hover { background: var(--lengueta); }
.historial-lista li:has([aria-current="page"]) { background: var(--vitela-alta); }

.historial-item {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.6rem 0.4rem 0.6rem 0.75rem;
  color: var(--tenue);
  text-decoration: none;
}
.historial-item:hover, .historial-item[aria-current="page"] { color: var(--tinta); }
.historial-titulo { flex: 1; min-width: 0; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.historial-fecha { flex: none; font-size: 0.72rem; color: var(--apagado); font-variant-numeric: tabular-nums; }

.historial-borrar { width: 2rem; height: 2rem; margin-right: 0.2rem; color: var(--apagado); }
.historial-borrar .icono { width: 0.9rem; height: 0.9rem; }
.historial-borrar:hover { color: var(--rubro); background: none; }
/* Con mouse aparece al pasar por encima; en una pantalla táctil no hay
   «encima», así que queda siempre a la vista. */
@media (hover: hover) {
  .historial-borrar { opacity: 0; }
  .historial-lista li:hover .historial-borrar,
  .historial-borrar:focus-visible { opacity: 1; }
}

.historial-vacio { margin: 0; padding: 1rem 0.75rem; font-size: var(--t--1); color: var(--apagado); }

.historial-sitio {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: 0.4rem 0.5rem calc(0.4rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--regla);
}
.historial-sitio a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  padding: 0.55rem 0;
  border-radius: 0.6rem;
  font-size: 0.72rem;
  color: var(--tenue);
  text-decoration: none;
}
.historial-sitio a:hover { color: var(--tinta); background: var(--lengueta); }
.historial-sitio .icono { width: 1.15rem; height: 1.15rem; }

@media (max-width: 48rem) {
  .en-asistente .encabezado { display: none; }
  .disposicion.en-asistente ~ .barra { display: none; }
}

@media (min-width: 48.0625rem) {
  .asistente-menu, .historial-cerrar, .historial-fondo, .historial-sitio { display: none; }
  /* A la derecha: así la charla queda centrada entre el sidebar del sitio
     y el historial, en vez de corrida hacia el borde. */
  .historial {
    position: static;
    inset: auto;
    order: 2;
    width: 16.5rem;
    flex: none;
    transform: none;
    transition: none;
    background: none;
    border-left: 1px solid var(--regla);
    padding-top: 1rem;
  }
  .historial.abierto { box-shadow: none; }
  .conversacion-cabecera { padding-top: 1rem; }
}

/* ---------- Splash ----------
   Lo primero que se pinta, antes de que cargue el bundle: el mismo marcado
   vive a mano en scripts/build.ts para que no haya un parpadeo entre uno y
   otro al arrancar la app. */
.splash {
  min-height: 100svh;
  display: grid;
  place-items: center;
}
.splash .chispa {
  width: 2.4rem;
  height: 2.4rem;
  color: var(--apagado);
  animation: latir 1.6s ease-in-out infinite;
}
@keyframes latir {
  0%, 100% { opacity: 0.35; transform: scale(0.92); }
  50% { opacity: 0.9; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .splash .chispa { animation: none; opacity: 0.6; }
}

/* Lo mismo, pero adentro del tablero mientras carga /inicio: el sidebar y el
   encabezado ya están, así que no hace falta un splash de página entera. */
.tablero-cargando {
  min-height: 60svh;
  display: grid;
  place-items: center;
}
.tablero-cargando .chispa {
  width: 2rem;
  height: 2rem;
  color: var(--apagado);
  animation: latir 1.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .tablero-cargando .chispa { animation: none; opacity: 0.6; }
}

/* ---------- Barra inferior, solo móvil ---------- */

.barra { display: none; }

@media (max-width: 48rem) {
  :root { --t-5: 4.2rem; --t-4: 2.6rem; --t-3: 2rem; --t-2: 1.6rem; }

  .tablero { grid-template-columns: 1fr; gap: 0; }
  .tablero > aside {
    padding-top: 2.5rem;
    margin-top: 2.5rem;
    border-top: 1px solid var(--regla);
  }
  .encabezado nav { display: none; }
  body { padding-bottom: 4.5rem; }

  /*
    Los cinco filtros no entran en una columna de teléfono: envolvían y
    «repasos» quedaba solo en su propia línea, huérfano. Una fila que se
    desliza, con el mismo desvanecido de la tabla del horario, es más
    prolijo que una segunda línea despareja.
  */
  .filtros {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    mask-image: linear-gradient(to right, #000 calc(100% - 1.5rem), transparent);
    padding-bottom: 0.2rem;
  }
  .filtros::-webkit-scrollbar { display: none; }
  .filtros button { flex: none; }

  /*
    Más plana que antes para que estorbe menos, y con el botón del asistente
    asomando por encima del borde: es la acción que abre una conversación
    nueva, así que se distingue de los tres destinos en vez de hacer fila
    con ellos.
  */
  .barra {
    display: flex;
    position: fixed;
    inset: auto 0 0 0;
    padding-bottom: env(safe-area-inset-bottom);
    z-index: 10;
  }

  /*
    El fondo va en una capa aparte, no en la barra: así puede taparse el pie
    del botón sin tapar también sus enlaces.
  */
  .barra::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--fondo);
    border-top: 1px solid var(--regla);
    z-index: 2;
  }

  /*
    El botón asoma POR DETRÁS de la barra, no encima: una lengüeta ancha y
    baja que sale del borde superior. Apoyado delante parecía una pastilla
    pegada; detrás se lee como parte de la misma pieza.
  */
  .boton-asistente {
    position: absolute;
    left: 50%;
    bottom: calc(100% - 1px);
    /* Se ajusta al contenido: un ancho fijo dejaba el texto descentrado. */
    padding-inline: 1.1rem;
    /* Un poco más alta: la lengüeta crece hacia arriba, no hacia la barra. */
    height: 2.35rem;
    transform: translateX(-50%);
    display: grid;
    place-items: center;
    /* Curva amplia arriba; abajo entra recto bajo la barra. */
    border-radius: 1.5rem 1.5rem 0 0;
    /*
      Un punto más claro que la barra: --vitela sobre --fondo casi no se
      distingue y el texto de la página se leía a través de la lengüeta.
    */
    background: var(--lengueta);
    border: 1px solid var(--regla);
    border-bottom: none;
    color: var(--azur);
    text-decoration: none;
    /*
      La caja está centrada, pero ópticamente el icono se ve alto: la lengüeta
      es redondeada arriba y recta abajo, así que la curva «come» aire visual
      en la parte superior. Un par de píxeles lo compensan.
    */
    padding-top: 4px;
    transition:
      color var(--rapido) var(--cozy),
      background-color var(--rapido) var(--cozy),
      height var(--medio) var(--cozy);
  }
  .boton-asistente:active {
    height: 2.6rem;
    background: var(--regla);
  }
  .boton-asistente {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
  }
  .boton-asistente .icono {
    width: 1.3rem;
    height: 1.3rem;
    /*
      Un píxel arriba: «Asistente» tampoco tiene descendentes, así que la
      masa de las letras queda por encima del centro de la caja de línea.
      Mismo ajuste que ya tenía este botón con «Claude», por la misma razón.
    */
    transform: translateY(-1px);
  }
  .boton-asistente .texto {
    font-family: var(--cuerpo);
    font-size: 0.95rem;
    color: var(--tinta);
    line-height: 1;
  }
  .boton-asistente:active .texto { color: var(--azur); }

  /*
    El botón no usa z-index negativo: eso lo mandaría detrás del contenido de
    la página, que se vería a través de la lengüeta. En su lugar la barra se
    pinta por encima con un z-index mayor, así el botón queda EN MEDIO: detrás
    de la barra y delante de la página.
  */
  .boton-asistente { z-index: 1; }
  .barra > a:not(.boton-asistente),
  .barra > .subrayado { position: relative; z-index: 3; }

  /*
    El destino del medio se corre a la derecha para dejar pasar al botón.
    Sin esto, «Temas» queda debajo de la chispa y no se puede leer ni tocar.
  */
  /* El botón ya no tapa el texto: va detrás. Sin hueco extra. */



  /*
    Un solo subrayado que se desliza a la pestaña activa, en vez de un borde
    por pestaña que aparezca y desaparezca: así el movimiento cuenta de dónde
    viene la atención y hacia dónde va.

    El ancho es un tercio porque son tres destinos; se mueve en múltiplos de
    su propio ancho, así que no hace falta medir nada en JavaScript.
  */
  .barra .subrayado {
    position: absolute;
    top: -1px;
    left: 0;
    width: calc(100% / 3);
    height: 2px;
    background: var(--azur);
    transition:
      transform var(--medio) var(--cozy),
      opacity var(--rapido) var(--cozy);
    pointer-events: none;
  }
  .barra a:not(.boton-asistente) {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    text-align: center;
    /* Aplanada: antes 0.9rem arriba y abajo. */
    padding: 0.5rem 0 0.55rem;
    font-family: var(--cuerpo);
    font-size: 0.85rem;
    color: var(--tenue);
    text-decoration: none;
  }
  .barra a:not(.boton-asistente) .icono { width: 1.15rem; height: 1.15rem; }
  .barra a[aria-current="page"] { color: var(--tinta); }

  /* En pantalla angosta la marca larga empujaba el encabezado fuera del marco. */
  .marca { font-size: var(--t-0); }
  .encabezado { padding-top: 1.25rem; padding-bottom: 1rem; }

  .manana { margin: 1rem 0 2rem; }

  /* Sin visor, la ficha del archivo no tiene que ocupar la pantalla entera. */
  .pagina { padding-bottom: 2rem; }

  /* En una columna angosta la nota y el aviso van debajo, no arrastrados. */
  .agenda a { grid-template-columns: 3.2rem 1fr; padding-right: 0; }
  .agenda .tipo { grid-column: 2; }

  .agenda .nota,
  .agenda .sin-desc { display: block; margin-left: 0; }

  /* El calendario es perpetuo: se aprieta, no se esconde. */
  .mes td { height: 3.4rem; font-size: 0.7rem; padding-right: 0.2rem; }
  .mes th { font-size: 0.7rem; }
  .mes .marca { font-size: 0.7rem; }

  /* El visor embebido en pantalla angosta estorba más de lo que ayuda. */
  .visor { display: none; }
  .solo-movil { display: inline-block; }
  .solo-escritorio { display: none; }

  .ficha-archivo { flex-direction: column; gap: 0.75rem; }
  /* El formulario ya es una sola línea; apilarlo era para la versión vieja. */
  .archivos a { flex-direction: column; gap: 0.15rem; }
  .archivos .meta { white-space: normal; }
}

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

   El movimiento responde a lo que hace la persona: abrir un día, guardar,
   tocar un enlace. No hay entradas escalonadas ni apariciones al bajar: eso
   se ve una vez y estorba las cien siguientes.

   Curva propia, un poco elástica al final, para que asentarse se sienta
   deliberado y no mecánico.
*/

:root {
  --cozy: cubic-bezier(0.22, 0.8, 0.3, 1);
  --rapido: 0.16s;
  --medio: 0.28s;
  --calmo: 0.45s;
}

/* Lo que se toca responde. Sin sombras ni escalas: cambia el color. */
a, button, .dia, summary {
  transition:
    color var(--rapido) var(--cozy),
    background-color var(--rapido) var(--cozy),
    border-color var(--rapido) var(--cozy),
    opacity var(--rapido) var(--cozy);
}

/* Un toque hunde levemente el elemento: confirma que el dedo llegó. */
button:active, .agenda a:active, .manana-fila:active {
  transform: scale(0.985);
  transition-duration: 0.06s;
}

.manana-fila, .agenda a, .archivos a, .indice a {
  transition:
    color var(--rapido) var(--cozy),
    background-color var(--rapido) var(--cozy),
    transform var(--rapido) var(--cozy);
}

/*
  La fila de «Mañana» entra una vez, al abrir: es lo primero que se mira y
  merece un momento.
*/
.manana-fila {
  animation: asentarse var(--calmo) var(--cozy) both;
}

@keyframes asentarse {
  from { opacity: 0; transform: translateY(0.35em); }
  to { opacity: 1; transform: none; }
}

/* La usa la lista del día, el aviso de la subida y el nombre del archivo. */
@keyframes desplegar {
  from { opacity: 0; transform: translateY(-0.4rem); }
  to { opacity: 1; transform: none; }
}

/* El punto del día elegido late una vez al marcarlo. */
.mes .elegido .numero { animation: marcar var(--medio) var(--cozy); }

@keyframes marcar {
  0% { transform: scale(1); }
  45% { transform: scale(1.12); }
  100% { transform: scale(1); }
}

.mes .numero { transition: background-color var(--rapido) var(--cozy), box-shadow var(--rapido) var(--cozy); }

/* Guardar una descripción: el texto aparece en su sitio, sin sobresaltos. */
.descripcion .cuerpo { animation: aparecer var(--medio) var(--cozy) both; }

@keyframes aparecer {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* El aviso de la subida entra deslizándose, así se nota que es nuevo. */
.aviso:not(:empty) { animation: desplegar var(--medio) var(--cozy) both; }

/* Las fórmulas aparecen cuando KaTeX termina, en vez de saltar de golpe. */
.katex-display { animation: aparecer var(--rapido) var(--cozy) both; }

/* ---------- Entre páginas ----------

   La página entra por el lado que corresponde: avanzar en la barra
   (Calendario → Temas → Archivos) o abrir un detalle entra desde la derecha;
   volver, desde la izquierda. La dirección la decide navegacion.ts antes de
   que cambie la ruta y la anuncia en `data-nav`.
*/

@view-transition { navigation: auto; }

/* Las dos páginas se superponen mientras dura el cruce. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--medio);
  animation-timing-function: var(--cozy);
  animation-fill-mode: both;
  mix-blend-mode: normal;
}

/* Sin dirección conocida: un cruce sencillo. */
::view-transition-old(root) { animation-name: desvanecer; }
::view-transition-new(root) { animation-name: revelar; }

/* Adelante: la vieja se va a la izquierda, la nueva entra por la derecha. */
html[data-nav="adelante"]::view-transition-old(root) {
  animation-name: salir-izquierda;
}
html[data-nav="adelante"]::view-transition-new(root) {
  animation-name: entrar-derecha;
}

/* Atrás: al revés. */
html[data-nav="atras"]::view-transition-old(root) {
  animation-name: salir-derecha;
}
html[data-nav="atras"]::view-transition-new(root) {
  animation-name: entrar-izquierda;
}

/*
  El asistente se abre desde su botón. La pastilla de la barra inferior
  crece hasta ser la pantalla entera: el recorte empieza con su forma y su
  lugar (abajo, al centro, redondeada) y se abre hasta los bordes, mientras
  la página de atrás se hunde un poco y la barra baja. Al salir, lo mismo
  al revés: el chat se recoge hacia donde estaba el botón. Es el único
  gesto grande del chat; adentro, el movimiento es chico y responde a lo
  que se toca.
*/
html[data-nav="abrir-asistente"]::view-transition-new(root) {
  animation: asistente-abrir 0.46s cubic-bezier(0.32, 0.72, 0, 1) both;
}
html[data-nav="abrir-asistente"]::view-transition-old(root) {
  animation: hundirse 0.46s cubic-bezier(0.32, 0.72, 0, 1) both;
}
html[data-nav="cerrar-asistente"]::view-transition-old(root) {
  z-index: 2;
  animation: asistente-cerrar 0.36s cubic-bezier(0.4, 0, 0.2, 1) both;
}
html[data-nav="cerrar-asistente"]::view-transition-new(root) {
  animation: emerger 0.36s cubic-bezier(0.4, 0, 0.2, 1) both;
}
html[data-nav="abrir-asistente"]::view-transition-old(pie) { animation: esconder-marco 0.24s ease-in both; }
/* La barra y la cabecera se dibujan por encima de las páginas: si aparecen
   antes de que el chat se recoja, lo tapan. Esperan a que casi termine. */
html[data-nav="cerrar-asistente"]::view-transition-new(pie) { animation: mostrar-marco 0.26s 0.26s ease-out both; }
html[data-nav="abrir-asistente"]::view-transition-old(cabecera) { animation: desvanecer 0.18s ease-in both; }
html[data-nav="cerrar-asistente"]::view-transition-new(cabecera) { animation: revelar 0.26s 0.26s ease-out both; }

/* Se sale del chat desde el drawer: navegacion.ts marca `data-nav` antes de
   que el navegador fotografíe la página vieja, así que el drawer se cierra
   de golpe y lo que se recoge hacia el botón es la charla, no el drawer. */
html[data-nav="cerrar-asistente"] .historial { transform: translateX(-100%); box-shadow: none; transition: none; }
html[data-nav="cerrar-asistente"] .historial-fondo { opacity: 0; transition: none; }

@keyframes asistente-abrir {
  from {
    clip-path: inset(calc(100% - 4.6rem - env(safe-area-inset-bottom)) 33% calc(1rem + env(safe-area-inset-bottom)) 33% round 1.5rem);
    opacity: 0.6;
  }
  30% { opacity: 1; }
  to { clip-path: inset(0 0 0 0 round 0); opacity: 1; }
}
@keyframes asistente-cerrar {
  from { clip-path: inset(0 0 0 0 round 0); opacity: 1; }
  80% { opacity: 1; }
  to {
    clip-path: inset(calc(100% - 4.6rem - env(safe-area-inset-bottom)) 33% calc(1rem + env(safe-area-inset-bottom)) 33% round 1.5rem);
    opacity: 0;
  }
}
@keyframes hundirse { to { transform: scale(0.94); opacity: 0.35; } }
@keyframes emerger {
  from { transform: scale(0.94); opacity: 0.35; }
  to { transform: none; opacity: 1; }
}
@keyframes esconder-marco { to { transform: translateY(100%); opacity: 0; } }
@keyframes mostrar-marco {
  from { transform: translateY(100%); opacity: 0; }
  to { transform: none; opacity: 1; }
}

/*
  El deslizamiento cuenta «avancé» o «volví» en el orden de la barra
  inferior. En escritorio no hay barra: el sidebar es una lista vertical sin
  un orden de izquierda a derecha, así que esa dirección no significa nada
  ahí. Se cae al cruce simple, el mismo que ya se usaba sin dirección
  conocida.
*/
@media (min-width: 48.0625rem) {
  html[data-nav]::view-transition-old(root) {
    animation: desvanecer var(--medio) var(--cozy) both;
    z-index: auto;
  }
  html[data-nav]::view-transition-new(root) {
    animation: revelar var(--medio) var(--cozy) both;
  }
}

@keyframes desvanecer { to { opacity: 0; } }
@keyframes revelar {
  from { opacity: 0; transform: translateY(0.5rem); }
  to { opacity: 1; transform: none; }
}

/*
  La que se va recorre menos distancia que la que llega: así la atención
  queda en la que entra, en vez de repartirse entre las dos.
*/
@keyframes salir-izquierda {
  to { opacity: 0; transform: translateX(-12%); }
}
@keyframes entrar-derecha {
  from { opacity: 0; transform: translateX(28%); }
  to { opacity: 1; transform: none; }
}
@keyframes salir-derecha {
  to { opacity: 0; transform: translateX(12%); }
}
@keyframes entrar-izquierda {
  from { opacity: 0; transform: translateX(-28%); }
  to { opacity: 1; transform: none; }
}

/*
  La barra inferior y el encabezado no se deslizan con el resto: son el marco
  fijo de la app, y verlos viajar rompería la ilusión de que la página se
  mueve dentro de ellos.
*/
.encabezado { view-transition-name: cabecera; }
.barra { view-transition-name: pie; }
.sidebar { view-transition-name: sidebar; }

::view-transition-group(cabecera),
::view-transition-group(pie),
::view-transition-group(sidebar) { animation-duration: 0s; }
::view-transition-old(cabecera),
::view-transition-new(cabecera),
::view-transition-old(pie),
::view-transition-new(pie),
::view-transition-old(sidebar),
::view-transition-new(sidebar) { animation: none; opacity: 1; }

/*
  Quien pidió menos movimiento no recibe ninguno. No es un detalle de
  cortesía: para algunas personas el movimiento marea de verdad.
*/
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
