/* =====================================================================
   ÍNDICE DEL PROGRAMA — /info
   Hoja completa y aparte: reemplaza a styles.css, no se apila encima.

   Esta página tiene un problema que no tiene ninguna otra del sitio: habla
   de SIETE cosas que ya tienen cara propia, y las siete caras son
   incompatibles entre sí a propósito.

     Expo Multimedia   — editorial, serif, papel.
     Virtual Champions — negro, condensada, esquinas cortadas.
     Jam de Altura     — píxel, verde consola sobre violeta.
     INKreible         — papel claro, rotulador y rojo de sello.
     Music Fest        — cartel, Anton y degradado.
     Salidas           — papel claro, formulario institucional.
     Semillero SAMI    — papel cuadriculado y tinta azul de cuaderno.

   La salida fácil era inventar una octava cara y meterlo todo en tarjetas
   iguales. Se descartó: siete tarjetas grises con el nombre de cada evento
   no dicen qué es ninguno, y quien conoce el festival no lo reconocería.

   Lo que se hace en cambio: la página es una PILA DE BANDAS a ancho
   completo, y cada banda se viste como el sitio del que habla. El índice
   pone lo mínimo alrededor —una cabecera sobria, una portada y un pie— y
   entre banda y banda no hay decoración que las una, porque el corte seco
   de una a otra ES el efecto: se pasa de la revista al esports como se
   pasa de una página a otra del sitio.

   CÓMO ESTÁ ARMADO. Todo lo compartido (el titular, el lema, las dos
   columnas, el rótulo del historial, el enlace del final) está escrito UNA
   vez en términos de variables, y cada banda solo redefine las variables:

     --fondo   el fondo de la banda
     --tinta   el texto
     --dim     el texto secundario
     --linea   los bordes
     --acento  el color que manda
     --tipo    la letra de los titulares
     --letra   la letra del cuerpo

   Como las variables se heredan, .banda.b-jam { --acento: verde } repinta
   la banda entera sin repetir una sola regla. Lo específico de cada una
   —el corte diagonal del torneo, el marco de píxel de la jam, la escalera
   del cartel, la muesca del tiquete— va después, en su propio bloque.

   LA REGLA DE LA CASA, que aquí importa más que en ninguna otra hoja: si
   no cabe, se encoge o se recorta; NUNCA aparece scroll horizontal. Con
   nombres de grupos y de equipos que los escribe cualquiera y titulares de
   80 píxeles, un solo descuido saca la página de la pantalla. De ahí los
   clamp() en todo lo grande, los minmax(0, 1fr) en todas las rejillas y el
   overflow-wrap en todo lo que venga de la base.
   ===================================================================== */

:root {
  /* El armazón: neutro y oscuro. No es de ningún evento a propósito, para
     que las bandas no compitan con él. */
  --marco-bg: #0b0b10;
  --marco-elev: #131319;
  --marco-linea: #24242e;
  --marco-ink: #eceaf5;
  --marco-dim: #9d9bb4;
  --marco-mute: #6f6d85;
  --marco-acento: #8f7bff;

  --f-serif: "Fraunces", "Times New Roman", serif;
  --f-sans: "Plus Jakarta Sans", -apple-system, system-ui, sans-serif;
  --f-cond: "Archivo", "Arial Narrow", sans-serif;
  --f-pixel: "Press Start 2P", "Courier New", monospace;
  --f-mono: "Space Mono", "Courier New", monospace;
  --f-anton: "Anton", "Arial Narrow", Impact, sans-serif;
  --f-marker: "Permanent Marker", "Comic Sans MS", cursive;
  --f-mano: "Caveat", "Segoe Script", cursive;

  /* El ancho de lectura de todas las bandas. Uno solo para que la página
     tenga un eje aunque cambie de color seis veces. */
  --ancho: 1020px;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Los atajos bajan a una banda: sin esto el título queda pegado al borde
     de arriba, debajo de la cabecera. */
  scroll-padding-top: 70px;
}

body {
  margin: 0;
  background: var(--marco-bg);
  color: var(--marco-ink);
  font-family: var(--f-sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* El body es el único que puede fijar esto: una banda con un nombre
     larguísimo desborda su caja, no la página. */
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }

:focus { outline: none; }
:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

img { max-width: 100%; }

/* ---------------------------------------------------------------------
   La cabecera
   Sobria y pegada arriba. Dos cosas y ninguna más: de quién es el sitio y,
   si hay evento en curso, por dónde se vuelve a él.
   --------------------------------------------------------------------- */
.in-top {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(11, 11, 16, .88);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--marco-linea);
}

.in-top-in {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: 13px 22px;
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.in-marca {
  font-family: var(--f-serif);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -.01em;
  /* El nombre del programa no envuelve ni empuja: si la pantalla es muy
     angosta, se recorta con puntos suspensivos y ya. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.in-marca em { font-style: italic; color: var(--marco-acento); }

.in-ahora {
  margin-left: auto;
  flex: 0 1 auto;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 13px;
  border: 1px solid var(--marco-linea);
  border-radius: 999px;
  background: var(--marco-elev);
  overflow: hidden;
}
.in-ahora span {
  font-size: 10.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--marco-mute);
  white-space: nowrap;
}
.in-ahora strong {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.in-ahora:hover { border-color: var(--marco-acento); }

/* ---------------------------------------------------------------------
   La portada
   --------------------------------------------------------------------- */
.in { min-width: 0; }

.in-portada {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: clamp(48px, 9vw, 96px) 22px clamp(40px, 6vw, 70px);
}

.in-eyebrow {
  margin: 0 0 18px;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--marco-mute);
}

.in-portada h1 {
  margin: 0;
  font-family: var(--f-serif);
  font-weight: 500;
  /* clamp y no un tamaño fijo: es el texto más grande de la página y el que
     primero se saldría en un teléfono. */
  font-size: clamp(34px, 7vw, 68px);
  line-height: 1.05;
  letter-spacing: -.02em;
}
.in-portada h1 em { font-style: italic; color: var(--marco-acento); }

.in-lead {
  margin: 22px 0 0;
  max-width: 60ch;
  font-size: clamp(15px, 1.6vw, 17.5px);
  color: var(--marco-dim);
}

/* El estado del semestre. Las dos versiones comparten maqueta y solo
   cambian de color: la que anuncia algo se enciende, la que dice que no hay
   nada se queda apagada, que es exactamente lo que significa. */
.in-estado {
  margin: 34px 0 0;
  padding: 22px 24px;
  border: 1px solid var(--marco-linea);
  border-left-width: 3px;
  border-radius: 3px;
  background: var(--marco-elev);
  max-width: 66ch;
}
.in-estado .k {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--marco-mute);
}
.in-estado .v {
  margin: 0;
  font-family: var(--f-serif);
  font-size: clamp(21px, 3vw, 28px);
  line-height: 1.2;
  overflow-wrap: anywhere;
}
.in-estado .q { margin: 10px 0 0; color: var(--marco-dim); font-size: 15px; }

.in-estado.viva { border-left-color: var(--marco-acento); }
.in-estado.viva .v a { border-bottom: 1px solid rgba(143, 123, 255, .45); }
.in-estado.viva .v a:hover { color: var(--marco-acento); border-bottom-color: currentColor; }
.in-estado.quieta { border-left-color: var(--marco-mute); }
.in-estado.quieta .v { color: var(--marco-dim); }

.in-estado .chips { margin: 16px 0 0; display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  font-size: 11.5px;
  letter-spacing: .04em;
  padding: 5px 11px;
  border: 1px solid var(--marco-linea);
  border-radius: 999px;
  color: var(--marco-dim);
}
.chip.ok { color: #7ddc9a; border-color: rgba(125, 220, 154, .35); }

/* Los atajos. Fila que envuelve, nunca una tira con scroll: una barra que se
   arrastra a los lados esconde justo lo que se está buscando. */
.in-atajos {
  margin: 38px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.in-atajos a {
  font-size: 12.5px;
  padding: 7px 14px;
  border: 1px solid var(--marco-linea);
  border-radius: 999px;
  color: var(--marco-dim);
}
.in-atajos a:hover { color: var(--marco-ink); border-color: var(--marco-mute); }

/* =====================================================================
   EL ARMAZÓN DE UNA BANDA
   Escrito una sola vez y en variables. Lo que cambia por evento son las
   variables, no estas reglas.
   ===================================================================== */
.banda {
  /* Los valores por defecto son los del armazón: una banda que se olvide de
     definir los suyos se ve sobria, no rota. */
  --fondo: var(--marco-elev);
  --tinta: var(--marco-ink);
  --dim: var(--marco-dim);
  --mute: var(--marco-mute);
  --linea: var(--marco-linea);
  --acento: var(--marco-acento);
  --tipo: var(--f-serif);
  --letra: var(--f-sans);

  background: var(--fondo);
  color: var(--tinta);
  font-family: var(--letra);
  /* El corte entre bandas: una línea y nada más. Sin degradados de
     transición, que es lo que las volvería un continuo. */
  border-top: 1px solid var(--linea);
}

.banda-in {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: clamp(46px, 7vw, 84px) 22px clamp(40px, 6vw, 72px);
  min-width: 0;
}

.b-cab { max-width: 62ch; }

.b-tipo {
  margin: 0 0 14px;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--acento);
}

.b-cab h2 {
  margin: 0;
  font-family: var(--tipo);
  font-weight: 500;
  font-size: clamp(30px, 5.4vw, 54px);
  line-height: 1.06;
  letter-spacing: -.02em;
  /* Nombres largos de eventos: parten donde haga falta antes que desbordar. */
  overflow-wrap: anywhere;
}
.b-cab h2 em { font-style: italic; color: var(--acento); }

.b-lema {
  margin: 16px 0 0;
  font-size: clamp(15px, 1.7vw, 18px);
  color: var(--dim);
}

/* Las dos columnas: el texto a la izquierda, los datos a la derecha. En
   pantalla angosta se apilan, que es lo único sensato. */
.b-cols {
  margin: 36px 0 0;
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(22px, 4vw, 48px);
  align-items: start;
}
.b-texto { min-width: 0; }
.b-texto p { margin: 0 0 14px; color: var(--dim); max-width: 58ch; }
.b-texto p:last-child { margin-bottom: 0; }

/* La ficha de datos: hilos finos, como el pie de una foto de revista. */
.b-datos { margin: 0; min-width: 0; }
.b-datos > div {
  display: grid;
  grid-template-columns: minmax(0, 90px) minmax(0, 1fr);
  gap: 12px;
  padding: 11px 0;
  border-top: 1px solid var(--linea);
}
.b-datos > div:last-child { border-bottom: 1px solid var(--linea); }
.b-datos dt {
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mute);
  padding-top: 3px;
}
.b-datos dd { margin: 0; font-size: 14.5px; overflow-wrap: anywhere; }

/* Tres cifras grandes en fila (el torneo). auto-fit con minmax para que
   nunca haya una cuarta columna apretada ni una fila que se salga. */
.b-marcas {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(120px, 100%), 1fr));
  gap: 14px;
}
.b-marcas li {
  padding: 14px 16px;
  border: 1px solid var(--linea);
  min-width: 0;
}
.b-marcas .n {
  display: block;
  font-family: var(--tipo);
  font-size: 26px;
  line-height: 1.1;
  overflow-wrap: anywhere;
}
.b-marcas .q {
  display: block;
  margin-top: 4px;
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--mute);
}

/* El historial */
.b-historial { margin: clamp(34px, 5vw, 56px) 0 0; }

.b-rotulo {
  margin: 0 0 18px;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--mute);
  padding-bottom: 10px;
  border-bottom: 1px solid var(--linea);
}

/* LAS EDICIONES VIEJAS, en un renglón cada una.
   Una banda enseña completas las últimas ediciones —tres carteles, tres
   tarjetas— y de ahí para atrás cada semestre se queda con esto: cuándo, las
   cifras y la cosa que lo distingue. Un solo marcado para las cuatro bandas;
   el color y la letra los pone cada una por las variables, como todo aquí.

   Es una rejilla y no un flex con separadores: así el semestre, las cifras y
   el nombre quedan en tres columnas alineadas de renglón a renglón, que es lo
   que hace legible una lista de ocho años. */
.b-viejas {
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}
.b-viejas li {
  display: grid;
  /* La columna del medio da para "6 equipos · 5 juegos entregados" de un solo
     renglón: partida en dos, la lista dobla de alto sin decir nada más. */
  grid-template-columns: minmax(0, 190px) minmax(0, 260px) minmax(0, 1fr);
  gap: 4px 20px;
  align-items: baseline;
  padding: 11px 0;
  border-bottom: 1px solid var(--linea);
  font-size: 13.5px;
}
.b-viejas .cuando {
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--mute);
}
.b-viejas .que { color: var(--dim); }
.b-viejas .marca { color: var(--acento); min-width: 0; overflow-wrap: anywhere; }

/* "Y cuatro semestres más". El archivo completo no vive aquí —esta página es
   el índice del programa, no su historia—, pero decir cuántos hubo es lo que
   evita que parezca que el programa empezó hace tres semestres. */
.b-mas {
  margin: 18px 0 0;
  font-size: 13px;
  color: var(--mute);
}
.b-mas a { color: var(--acento); border-bottom: 1px solid currentColor; }

/* El pie de la banda: el enlace a su sitio. */
.b-pie {
  margin: clamp(30px, 4vw, 46px) 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
}

.b-ir {
  display: inline-block;
  padding: 11px 22px;
  border: 1px solid var(--acento);
  color: var(--acento);
  font-size: 14px;
  font-weight: 600;
  border-radius: 3px;
}
.b-ir::after { content: " →"; }
.b-ir:hover { background: var(--acento); color: var(--fondo); }

.b-cerrada { margin: 0; font-size: 13.5px; color: var(--mute); }

/* =====================================================================
   BANDA 1 · EXPO MULTIMEDIA — editorial
   Serif, hilos y una tabla de anuario. Nada de cajas con relleno: en una
   revista lo que separa es una línea, no un recuadro.
   ===================================================================== */
.b-expo {
  /* Un punto más claro que el armazón, no más oscuro: es la primera banda y
     tiene que despegarse de la portada, o las dos se leen como una sola
     página larga y el corte no se ve. */
  --fondo: #15151c;
  --tinta: #e6e6f2;
  --dim: #9a99b0;
  --mute: #6e6d83;
  --linea: #262631;
  --acento: #5b9cf6;
  --tipo: var(--f-serif);
}

/* El recorrido: las salas temáticas, con el mismo color que tienen en la
   página de la Expo. El color entra por --sala y las cuatro clases son las
   mismas categorías del JSON; una sala sin categoría se queda con el azul de
   la banda, que es la forma correcta de no inventarse un color. */
.expo-salas {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 2px 26px;
}
.expo-salas li {
  --sala: var(--acento);
  min-width: 0;
  padding: 12px 0 12px 15px;
  border-left: 2px solid var(--sala);
}
.expo-salas strong {
  display: block;
  font-family: var(--f-serif);
  font-weight: 500;
  font-size: 18px;
  color: var(--sala);
  overflow-wrap: anywhere;
}
.expo-salas span { font-size: 13.5px; color: var(--dim); }
.cat-code     { --sala: #9a8bff; }
.cat-story    { --sala: #ff8a66; }
.cat-realtime { --sala: #4cdfb6; }
.cat-design   { --sala: #ffc861; }

.b-tabla {
  width: 100%;
  border-collapse: collapse;
  /* fixed y no auto: con auto, un título de proyecto largo estira la columna
     y la tabla empuja la página. Aquí cada columna tiene lo suyo y el texto
     se acomoda dentro. */
  table-layout: fixed;
  font-size: 14px;
}
.b-tabla tr { border-bottom: 1px solid var(--linea); }
.b-tabla th, .b-tabla td {
  text-align: left;
  vertical-align: top;
  padding: 14px 12px 14px 0;
  overflow-wrap: anywhere;
}
.b-tabla th {
  width: 30%;
  font-family: var(--f-serif);
  font-weight: 500;
  font-size: 16px;
  color: var(--tinta);
}
.b-tabla .cifras { width: 32%; color: var(--dim); }
.b-tabla .cifras span { display: block; }
.b-tabla .cifras strong { color: var(--tinta); font-weight: 600; }
.b-tabla .podio span { display: block; color: var(--dim); }
.b-tabla .podio em {
  font-style: normal;
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mute);
  margin-right: 8px;
}
.b-tabla .podio .oro { color: #e8c877; }

/* =====================================================================
   BANDA 2 · VIRTUAL CHAMPIONS — esports
   Condensada en mayúsculas, negro casi puro y el corte diagonal. El color
   de cada juego entra por --juego desde config.
   ===================================================================== */
.b-vc {
  --fondo: #08090c;
  --tinta: #eef0f6;
  --dim: #99a0b3;
  --mute: #656c7e;
  --linea: #1e212a;
  --acento: #ff4655;
  --tipo: var(--f-cond);
}

.b-vc .b-cab h2 {
  font-variation-settings: "wdth" 75, "wght" 700;
  text-transform: uppercase;
  letter-spacing: .01em;
  font-weight: 700;
}
.b-vc .b-cab h2 em { font-style: normal; }
.b-vc .b-tipo, .b-vc .b-rotulo { font-family: var(--f-cond); }
.b-vc .b-ir { border-radius: 0; text-transform: uppercase; letter-spacing: .06em; }

.vc-juegos {
  margin: clamp(30px, 4vw, 44px) 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: 14px;
}

.vc-juego {
  --juego: var(--acento);
  position: relative;
  min-width: 0;
  padding: 20px 20px 22px;
  background: #10131a;
  border-left: 3px solid var(--juego);
  /* La firma del torneo: la esquina de abajo a la derecha cortada en
     diagonal. Va con clip-path y no con un borde girado para que el corte
     sea del elemento entero, fondo incluido. */
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%);
}

.vc-nombre {
  margin: 0;
  font-family: var(--f-cond);
  font-variation-settings: "wdth" 75, "wght" 700;
  font-size: clamp(20px, 2.6vw, 26px);
  text-transform: uppercase;
  line-height: 1.1;
  color: var(--juego);
  overflow-wrap: anywhere;
}
.vc-formato {
  margin: 6px 0 14px;
  font-size: 11.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mute);
}
.vc-cifra { margin: 0; font-size: 13.5px; color: var(--dim); }

.vc-campeon {
  margin: 12px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--linea);
  font-size: 15px;
  overflow-wrap: anywhere;
}
.vc-campeon span {
  display: block;
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--juego);
  margin-bottom: 3px;
}

/* El torneo escribe hasta las fechas en condensada. */
.b-vc .b-viejas .cuando {
  font-family: var(--f-cond);
  font-variation-settings: "wdth" 75, "wght" 600;
  letter-spacing: .06em;
  color: var(--dim);
}

/* La jam y el festival: sus renglones viejos siguen hablando su idioma —mono
   la una, mayúsculas la otra— para que la lista no se sienta pegada de otra
   página. */
.b-jam .b-viejas li { border-bottom-color: rgba(124, 247, 74, .12); }
.b-jam .b-viejas .cuando { font-family: var(--f-pixel); font-size: 9px; }
.b-mf .b-viejas .marca {
  font-family: var(--f-anton);
  font-weight: 400;
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: .01em;
  color: var(--tinta);
}

/* =====================================================================
   BANDA 3 · JAM DE ALTURA — píxel
   Marcos de cuatro sombras planas (las esquinas quedan mordidas solas),
   verde de consola sobre violeta y monoespaciada en todo el cuerpo.
   ===================================================================== */
.b-jam {
  --fondo: #10091f;
  --tinta: #f4f0ff;
  --dim: #b6a7e4;
  --mute: #7d6db4;
  --linea: #3b2580;
  --acento: #7cf74a;
  --tipo: var(--f-pixel);
  --letra: var(--f-mono);
  --px: 4px;
}

/* Press Start 2P es enorme por letra: al tamaño de los otros titulares, el
   nombre de la jam ocuparía tres renglones y se saldría en un teléfono. Va
   pequeño y en su sitio; el peso lo pone el marco, no el cuerpo. */
.b-jam .b-cab h2 {
  font-size: clamp(15px, 2.6vw, 26px);
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--acento);
}
.b-jam .b-tipo { font-family: var(--f-pixel); font-size: 9px; letter-spacing: .1em; }
.b-jam .b-rotulo { font-family: var(--f-pixel); font-size: 9px; letter-spacing: .1em; }
.b-jam .b-ir {
  border-radius: 0;
  font-family: var(--f-pixel);
  font-size: 10px;
  padding: 14px 18px;
  letter-spacing: .05em;
}

/* El marco: cuatro sombras planas, una por lado. Un border normal dobla las
   esquinas, y eso es justo lo que no queremos. */
.px {
  --marco: var(--linea);
  background: #1b1038;
  box-shadow:
    0 calc(var(--px) * -1) 0 0 var(--marco),
    0 var(--px) 0 0 var(--marco),
    calc(var(--px) * -1) 0 0 0 var(--marco),
    var(--px) 0 0 0 var(--marco);
  /* El marco se pinta por fuera, así que necesita aire o se le mete debajo
     al vecino. */
  margin: var(--px);
}

.jam-reglas { padding: 20px; min-width: 0; }
.jam-reloj {
  margin: 0 0 14px;
  font-family: var(--f-pixel);
  font-size: clamp(20px, 3.4vw, 30px);
  color: var(--acento);
  line-height: 1.3;
}
.jam-reglas ul { margin: 0; padding: 0; list-style: none; font-size: 13px; }
.jam-reglas li {
  padding: 8px 0;
  border-top: var(--px) solid rgba(124, 247, 74, .12);
  color: var(--dim);
  overflow-wrap: anywhere;
}
.jam-reglas li span {
  display: inline-block;
  min-width: 76px;
  color: var(--mute);
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: .1em;
}

.jam-ediciones {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 18px;
}
.jam-edicion { padding: 20px; min-width: 0; }

.jam-cuando {
  margin: 0 0 12px;
  font-family: var(--f-pixel);
  font-size: 10px;
  color: var(--acento);
  letter-spacing: .06em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
.jam-tema {
  margin: 0 0 12px;
  font-size: 15px;
  color: #ff5fd2;
  overflow-wrap: anywhere;
}
.jam-tema span {
  display: block;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--mute);
}
.jam-cifras { margin: 0; font-size: 12.5px; color: var(--dim); }

.jam-juegos {
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  font-size: 13px;
}
.jam-juegos li {
  padding: 5px 0 5px 16px;
  position: relative;
  overflow-wrap: anywhere;
}
/* La viñeta es un cuadrado de la retícula, no un punto. */
.jam-juegos li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  width: var(--px);
  height: var(--px);
  background: var(--acento);
}

.jam-podio {
  margin: 14px 0 0;
  padding: 12px 0 0;
  list-style: none;
  border-top: var(--px) solid rgba(124, 247, 74, .12);
  font-size: 13px;
}
.jam-podio li { padding: 4px 0; overflow-wrap: anywhere; }
.jam-podio span {
  display: block;
  font-size: 9.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--mute);
}
.jam-podio .oro { color: #ffd83d; }
.jam-podio .plata { color: #d8d3e8; }
.jam-podio .bronce { color: #e0a06a; }

/* =====================================================================
   BANDA 4 · INKREIBLE — papel y tinta
   Clara, como la de las salidas, pero de otra mano: rojo de sello en vez
   de verde, rotulador en los titulares y los bordes a pulso —el mismo
   border-radius desigual de su hoja— en vez de la pauta de formato.
   ===================================================================== */
.b-ink {
  --fondo: #f3ede1;
  --tinta: #16120c;
  --dim: #4f4636;
  --mute: #8b8069;
  --linea: #d6c9ae;
  --acento: #c33f28;
  --tipo: var(--f-marker);

  border-top-color: #c6b590;
}

/* Permanent Marker no tiene más que una grosura y ya viene inclinada: el
   titular no necesita ni negrita ni cursiva encima, solo tamaño. */
.b-ink .b-cab h2 {
  font-weight: 400;
  letter-spacing: 0;
  color: var(--acento);
}
.b-ink .b-cab h2 em { font-style: normal; color: var(--tinta); }
.b-ink .b-tipo, .b-ink .b-rotulo { font-family: var(--f-mano); font-size: 17px; letter-spacing: .02em; }
.b-ink .b-ir { border-radius: 200px 14px 220px 12px / 12px 210px 14px 200px; }

/* El trazo a pulso: el mismo recurso de public/ink.css. Un radio desigual
   en las cuatro esquinas hace que un rectángulo parezca dibujado encima
   del papel y no impreso con él. */
.ink-reglas,
.ink-edicion {
  background: #fffdf6;
  border: 2px solid var(--tinta);
  border-radius: 220px 18px 255px 16px / 16px 225px 18px 250px;
  padding: 22px;
  min-width: 0;
}

.ink-numero {
  margin: 0 0 12px;
  font-family: var(--f-marker);
  font-size: clamp(38px, 7vw, 58px);
  line-height: 1;
  color: var(--acento);
}
.ink-reglas ul { margin: 0; padding: 0; list-style: none; font-size: 13px; }
.ink-reglas li {
  padding: 7px 0;
  border-top: 1px dashed var(--linea);
  color: var(--dim);
  overflow-wrap: anywhere;
}
.ink-reglas li span {
  display: block;
  font-family: var(--f-mano);
  font-size: 15px;
  color: var(--tinta);
}

.ink-ediciones {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  gap: 16px;
  margin-top: 18px;
}
/* A partir de tres tarjetas la rejilla se parte sola; por debajo de 620px
   van una sobre otra, que es lo único que cabe con este relleno. */
@media (max-width: 620px) {
  .ink-ediciones { grid-template-columns: minmax(0, 1fr); }
}

.ink-cuando {
  margin: 0 0 4px;
  font-family: var(--f-mano);
  font-size: 19px;
  color: var(--acento);
}
.ink-cifras { margin: 0; font-size: 12.5px; color: var(--dim); }

.ink-obras {
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  font-size: 13.5px;
}
.ink-obras li {
  padding: 5px 0 5px 18px;
  position: relative;
  overflow-wrap: anywhere;
}
/* La viñeta es un trazo de tinta, no un punto: dos píxeles inclinados. */
.ink-obras li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 12px;
  width: 9px;
  height: 2px;
  background: var(--acento);
  transform: rotate(-18deg);
}

.ink-podio {
  margin: 16px 0 0;
  padding: 14px 0 0;
  border-top: 1px dashed var(--linea);
  list-style: none;
  font-size: 13.5px;
}
.ink-podio li { padding: 4px 0; overflow-wrap: anywhere; }
.ink-podio span {
  display: block;
  font-family: var(--f-mano);
  font-size: 15px;
  color: var(--mute);
}
/* Oro, plata y bronce oscurecidos: sobre papel, los de las bandas oscuras
   se pierden del todo. */
.ink-podio .oro { color: #a8791a; }
.ink-podio .plata { color: #6f6a5c; }
.ink-podio .bronce { color: #96551f; }

.b-ink .b-viejas li { border-bottom-color: rgba(120, 105, 75, .22); }
.b-ink .b-viejas .cuando { font-family: var(--f-mano); font-size: 16px; }

/* =====================================================================
   BANDA 5 · MULTIMEDIA MUSIC FEST — cartel
   Anton en mayúsculas, el degradado corriendo por el título y la escalera
   de nombres. El degradado nunca va plano: siempre de una esquina a otra.
   ===================================================================== */
.b-mf {
  --fondo: #0a0710;
  --tinta: #f7f3ff;
  --dim: #b6abd0;
  --mute: #7b7190;
  --linea: #2c2540;
  --acento: #ff2d78;
  --tipo: var(--f-anton);
  --fuego: linear-gradient(100deg, #ff2d78, #ff8a3d);
}

.b-mf .b-cab h2 {
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -.005em;
  line-height: .95;
  font-size: clamp(38px, 8vw, 78px);
}
/* El título recortado sobre el degradado. background-clip necesita el color
   transparente, y si la fuente no cargó todavía el texto se ve igual porque
   el color de reserva va antes. */
.b-mf .fuego {
  color: var(--acento);
  background: var(--fuego);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.b-mf .b-ir { border-radius: 2px; text-transform: uppercase; letter-spacing: .06em; }

.mf-areas {
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}
.mf-areas li {
  padding: 12px 0 12px 14px;
  border-left: 2px solid var(--linea);
  margin-bottom: 10px;
  min-width: 0;
}
.mf-areas li:nth-child(1) { border-left-color: #ff2d78; }
.mf-areas li:nth-child(2) { border-left-color: #ff8a3d; }
.mf-areas li:nth-child(3) { border-left-color: #35e5e0; }
.mf-areas strong {
  display: block;
  font-family: var(--f-anton);
  font-weight: 400;
  font-size: 18px;
  text-transform: uppercase;
  letter-spacing: .01em;
}
.mf-areas span { font-size: 13.5px; color: var(--dim); }

.mf-edicion {
  padding: clamp(22px, 3vw, 34px) 0;
  border-bottom: 1px solid var(--linea);
}
.mf-edicion:last-child { border-bottom: 0; padding-bottom: 0; }

.mf-cuando {
  margin: 0 0 18px;
  font-size: 11.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--mute);
  text-align: center;
}
.mf-cuando span { color: var(--dim); }

/* La escalera del cartel. Cada renglón mide menos que el anterior y todos
   los nombres de un renglón miden lo mismo: así es como está armado
   cualquier afiche de festival. */
.mf-cartel { text-align: center; }
.mf-fila {
  display: flex;
  justify-content: center;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 22px;
  font-family: var(--f-anton);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 1.05;
  letter-spacing: -.01em;
  overflow-wrap: anywhere;
}
.mf-fila.n1 { font-size: clamp(24px, 5.6vw, 52px); }
.mf-fila.n2 { font-size: clamp(19px, 3.8vw, 34px); color: var(--dim); }
.mf-fila.n3 { font-size: clamp(14px, 2.2vw, 20px); color: var(--mute); }

.mf-cifras {
  margin: 18px 0 0;
  text-align: center;
  font-size: 12.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--mute);
}

.mf-podio {
  margin: 16px auto 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 26px;
  font-size: 14px;
}
.mf-podio li { text-align: center; min-width: 0; overflow-wrap: anywhere; }
.mf-podio span {
  display: block;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--mute);
}
.mf-podio .oro { color: #ffc861; }
.mf-podio .plata { color: #35e5e0; }
.mf-podio .bronce { color: #ff8a3d; }

/* =====================================================================
   BANDA 6 · SALIDAS PEDAGÓGICAS — papel
   La única clara. Crema con pauta de formato, tinta oscura, reglas
   punteadas y la muesca del tiquete. Nada de sombras difusas: una plana y
   corta, la de un papel encima de otro.
   ===================================================================== */
.b-sal {
  --fondo: #f6f2e9;
  --tinta: #201d16;
  --dim: #56503f;
  --mute: #8a8271;
  --linea: #ddd4c2;
  --acento: #1f6b4a;
  --tipo: var(--f-cond);

  /* La pauta: una línea cada 34px, tan tenue que solo se nota como textura. */
  background-image: linear-gradient(rgba(195, 183, 158, .22) 1px, transparent 1px);
  background-size: 100% 34px;
  border-top-color: #c3b79e;
}

.b-sal .b-cab h2 {
  font-variation-settings: "wdth" 100, "wght" 700;
  font-weight: 700;
  letter-spacing: -.015em;
}
.b-sal .b-cab h2 em { font-style: italic; color: var(--acento); }
.b-sal .b-ir { border-radius: 4px; }
.b-sal .b-ir:hover { color: #f6f2e9; }

.sal-nota {
  margin: 26px 0 0;
  max-width: 62ch;
  font-size: 14.5px;
  color: var(--dim);
  padding-left: 14px;
  border-left: 3px solid var(--linea);
}

.sal-grupo { margin: clamp(32px, 5vw, 52px) 0 0; }
.b-sal .b-rotulo { border-bottom: 1px dashed var(--linea); color: var(--mute); }

.sal-lista {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 18px;
}

/* La boleta: la muesca a los lados es lo único que se permite parecer un
   tiquete, y por eso se usa solo aquí. Se dibuja con dos gradientes
   radiales del color del fondo de la banda. */
.sal-boleta {
  position: relative;
  min-width: 0;
  padding: 22px 24px 24px;
  background: #fffdf8;
  border: 1px solid var(--linea);
  border-radius: 5px;
  box-shadow: 0 2px 0 rgba(32, 29, 22, .06);

  /* Columna flexible para poder mandar el botón al fondo. Las boletas ya
     miden lo mismo —son celdas de una rejilla y se estiran a la fila—, pero
     sin esto el "Registrarme" quedaba a media altura en la que tuviera menos
     asignaturas, y dos botones a distinta altura se leen como dos tarjetas
     de distinto tamaño aunque midan igual. */
  display: flex;
  flex-direction: column;

  /* Dónde muerde el tiquete. Es la altura de la cabecera —nombre de dos
     renglones más el lugar—, que ahora es fija, así que la muesca cae en el
     mismo sitio en todas. */
  --muesca: 100px;
}
.sal-boleta::before,
.sal-boleta::after {
  content: "";
  position: absolute;
  top: var(--muesca);
  width: 13px;
  height: 26px;
  background: #f6f2e9;
  border: 1px solid var(--linea);
}
.sal-boleta::before { left: -1px; border-left: 0; border-radius: 0 13px 13px 0; }
.sal-boleta::after { right: -1px; border-right: 0; border-radius: 13px 0 0 13px; }
.sal-boleta.apagada { background: #f3eee4; }

/* LA CABECERA DE LA BOLETA — el nombre y el estado.
   Era un flex que envolvía, y ahí estaba el error: un nombre de dos renglones
   mandaba el "Abierta" a una línea propia debajo, empujaba el lugar y dejaba
   la boleta descuadrada contra la de al lado. Con una rejilla de dos columnas
   el estado tiene la suya —no la puede perder por largo que sea el nombre— y
   el nombre envuelve dentro de la suya sin mover nada. */
.sal-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: start;
}
.sal-top h3 {
  margin: 0;
  font-family: var(--f-cond);
  font-variation-settings: "wdth" 100, "wght" 700;
  font-size: 21px;
  line-height: var(--alto-nombre, 1.15);
  min-width: 0;
  overflow-wrap: anywhere;
  /* Dos renglones SIEMPRE: reservados aunque el nombre ocupe uno solo, para
     que todas las boletas arranquen el cuerpo a la misma altura y la muesca
     del tiquete quede a la misma altura en las dos. Uno más largo se corta
     con puntos suspensivos —el nombre completo está en su página—. */
  min-height: calc(21px * 1.15 * 2);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.sal-chip {
  /* Pegado arriba y no a la línea base: la referencia es el borde de la
     boleta, no el primer renglón del nombre, que puede no existir mañana. */
  align-self: start;
  margin-top: 2px;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 3px;
  white-space: nowrap;
}
.sal-chip.ok { background: #e4f0e8; color: var(--acento); }
.sal-chip.no { background: #efe9dc; color: var(--mute); }

/* El lugar va en un renglón y solo uno: es un rótulo, no una frase. Si no
   cabe, puntos suspensivos —nunca un segundo renglón que desplace todo lo de
   abajo—. */
.sal-lugar {
  margin: 4px 0 0;
  font-size: 13px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* EL OBJETIVO, a cuatro renglones fijos.
   Los objetivos los escribe cada docente en el config y miden lo que miden:
   uno de dos líneas y otro de seis dejaban las dos boletas con los datos a
   distinta altura, que es lo que se veía torcido. Aquí se reservan cuatro
   renglones y se recorta lo que sobre; el texto entero está en la página de
   la salida, que es a donde lleva el botón. */
.sal-objetivo {
  margin: 14px 0 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--dim);
  min-height: calc(14px * 1.55 * 4);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  overflow: hidden;
}

.sal-datos { margin: 16px 0 0; }
.sal-datos > div {
  display: flex;
  gap: 12px;
  padding: 7px 0;
  border-bottom: 1px dashed var(--linea);
  font-size: 14px;
}
.sal-datos dt {
  min-width: 66px;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mute);
  padding-top: 3px;
}
.sal-datos dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }

.sal-materias {
  margin: 14px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.sal-materias span {
  font-size: 11.5px;
  padding: 3px 9px;
  border: 1px solid var(--linea);
  border-radius: 3px;
  color: var(--dim);
}

/* El botón, siempre al fondo de la boleta. El margen automático se come el
   aire que sobre; el padding es el mínimo que se respeta cuando no sobra
   nada. Y align-self, porque un hijo de columna flexible se estira a lo ancho
   por defecto y el subrayado se iría de lado a lado de la tarjeta. */
.sal-ir {
  align-self: flex-start;
  margin-top: auto;
  padding-top: 18px;
  font-size: 14px;
  font-weight: 600;
  color: var(--acento);
  border-bottom: 1px solid currentColor;
}

.sal-vacio {
  margin: 30px 0 0;
  padding: 22px;
  border: 1px dashed var(--linea);
  border-radius: 5px;
  color: var(--mute);
  font-size: 14.5px;
}

/* Las que ya se hicieron: una línea cada una. Son archivo, no oferta. */
.sal-pasadas { margin: 0; padding: 0; list-style: none; }
.sal-pasadas li { border-bottom: 1px dashed var(--linea); }
.sal-pasadas a {
  display: grid;
  /* La primera columna carga la fecha con año ("viernes 12 de septiembre de
     2025"): más angosta, se parte en dos renglones y la lista se despeina. */
  grid-template-columns: minmax(0, 240px) minmax(0, 1.1fr) minmax(0, 1fr) auto;
  gap: 8px 18px;
  align-items: baseline;
  padding: 13px 0;
  font-size: 14px;
}
.sal-pasadas a:hover { color: var(--acento); }
.sal-pasadas .cuando {
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--mute);
}
.sal-pasadas .que {
  font-family: var(--f-cond);
  font-variation-settings: "wdth" 100, "wght" 700;
  font-size: 16px;
  min-width: 0;
  overflow-wrap: anywhere;
}
.sal-pasadas .donde { color: var(--dim); min-width: 0; overflow-wrap: anywhere; }
.sal-pasadas .cuantos {
  font-size: 12px;
  color: var(--acento);
  white-space: nowrap;
}

.sal-codigo { margin: 0; font-size: 13.5px; color: var(--mute); }
.sal-codigo a { color: var(--acento); border-bottom: 1px solid currentColor; }

/* =====================================================================
   BANDA 7 · SEMILLERO SAMI — cuaderno de laboratorio

   La segunda banda clara, y tenía que distinguirse de la de las salidas sin
   volverse otra cosa: las dos son papel. La diferencia es la TRAMA. Salidas
   lleva pauta de renglones —el formato que se llena a mano y se firma una
   vez—; esta lleva cuadrícula y tinta azul de bolígrafo, que es el cuaderno
   en el que se apuntan avances semana a semana durante tres semestres. Es la
   misma trama de /semillero, así que quien llegue allá desde aquí reconoce
   el papel antes de leer el título.
   ===================================================================== */
.b-sami {
  --fondo: #f2f5fa;
  --tinta: #151b28;
  --dim: #46536a;
  --mute: #7c879a;
  --linea: #ccd5e4;
  --acento: #2b47b4;
  --tipo: var(--f-cond);

  /* La cuadrícula: 26 px, dos gradientes cruzados y ninguna imagen. Tan tenue
     que solo se nota como textura, igual que en la hoja del semillero. */
  background-image:
    linear-gradient(rgba(150, 166, 194, .20) 1px, transparent 1px),
    linear-gradient(90deg, rgba(150, 166, 194, .20) 1px, transparent 1px);
  background-size: 100% 26px, 26px 100%;
  border-top-color: #b3bfd2;
}

.b-sami .b-cab h2 {
  font-variation-settings: "wdth" 100, "wght" 700;
  font-weight: 700;
  letter-spacing: -.02em;
}
.b-sami .b-cab h2 em { font-style: normal; color: var(--acento); }
.b-sami .b-tipo, .b-sami .b-rotulo { font-family: var(--f-mono); }
.b-sami .b-rotulo { border-bottom: 1px solid var(--linea); }
.b-sami .b-ir { border-radius: 4px; }
.b-sami .b-ir:hover { color: #f2f5fa; }

/* Las cifras, sobre papel: la caja tiene fondo propio porque una casilla sin
   relleno sobre cuadrícula se pierde en la trama. */
.b-sami .b-marcas li { background: #fff; border-color: var(--linea); }
.b-sami .b-marcas .n { font-variation-settings: "wdth" 100, "wght" 700; }
.b-sami .b-marcas .q { font-family: var(--f-mono); letter-spacing: .1em; }

/* LOS PERFILES — cuatro renglones, no cuatro tarjetas.
   No son opciones que se eligen (eso está escrito en la página del
   semillero): son por dónde se mueve. Cuatro tarjetas los harían parecer un
   menú del que hay que escoger uno. */
.sam-perfiles {
  margin: clamp(28px, 4vw, 42px) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  /* 200 y no 230: con 230 los cuatro perfiles no alcanzan a caber en una fila
     y quedan tres arriba y uno solo abajo, que se lee como si el cuarto fuera
     de otra categoría. */
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: 0 26px;
}
.sam-perfiles li {
  min-width: 0;
  padding: 13px 0;
  border-top: 1px solid var(--linea);
}
.sam-perfiles strong {
  display: block;
  font-family: var(--f-cond);
  font-variation-settings: "wdth" 100, "wght" 700;
  font-weight: 700;
  font-size: 15.5px;
}
.sam-perfiles span {
  display: block;
  margin-top: 3px;
  font-size: 13.5px;
  color: var(--dim);
  overflow-wrap: anywhere;
}

/* LOS PROYECTOS — título y director, en dos columnas alineadas.
   Ni el semestre ni el estado: eso es del panel. Y el título manda el ancho
   porque es lo único que dice de qué es el proyecto. */
.sam-lista { margin: 0; padding: 0; list-style: none; }
.sam-lista li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 210px);
  gap: 4px 20px;
  align-items: baseline;
  padding: 12px 0;
  border-bottom: 1px solid var(--linea);
}
.sam-lista .que {
  min-width: 0;
  font-size: 14.5px;
  line-height: 1.45;
  overflow-wrap: anywhere;
}
.sam-lista .quien {
  min-width: 0;
  font-family: var(--f-mono);
  font-size: 12px;
  color: var(--mute);
  overflow-wrap: anywhere;
}
/* Los sustentados son archivo: se leen en gris, para que en un vistazo se
   vea cuáles están andando y cuáles ya terminaron. El director se queda del
   mismo color que arriba —pintarlo de acento aquí resaltaría los guiones de
   los proyectos viejos, que es lo último que hay que mirar—. */
.sam-lista.cerrados .que { color: var(--dim); }

.sam-estado { margin: 0; font-size: 13.5px; color: var(--mute); max-width: 52ch; }

/* =====================================================================
   BANDA GENÉRICA — la de un evento sin cara propia todavía
   ===================================================================== */
.b-gen {
  --fondo: #0e0e13;
  --tinta: var(--marco-ink);
  --dim: var(--marco-dim);
  --mute: var(--marco-mute);
  --linea: var(--marco-linea);
  --acento: var(--marco-acento);
  --tipo: var(--f-serif);
}

/* ---------------------------------------------------------------------
   El pie
   --------------------------------------------------------------------- */
.in-foot {
  background: var(--marco-bg);
  border-top: 1px solid var(--marco-linea);
}
.in-foot-in {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: 26px 22px 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px;
}
.in-foot strong {
  display: block;
  font-family: var(--f-serif);
  font-weight: 500;
  font-size: 15px;
}
.in-foot span { font-size: 12px; color: var(--marco-mute); }
.in-foot .der { margin-left: auto; }
.in-acceso {
  font-size: 12px;
  color: var(--marco-mute);
  border: 1px solid var(--marco-linea);
  border-radius: 999px;
  padding: 7px 14px;
}
.in-acceso:hover { color: var(--marco-dim); border-color: var(--marco-mute); }

/* ---------------------------------------------------------------------
   Pantallas angostas
   Las dos columnas se apilan y las tablas dejan de serlo. Una tabla de tres
   columnas en un teléfono o se sale o se vuelve ilegible, y salirse aquí
   está prohibido: se convierte en bloques apilados.
   --------------------------------------------------------------------- */
@media (max-width: 780px) {
  .b-cols { grid-template-columns: minmax(0, 1fr); }

  .b-tabla, .b-tabla tbody, .b-tabla tr, .b-tabla th, .b-tabla td { display: block; width: auto; }
  .b-tabla tr { padding: 14px 0; }
  .b-tabla th { padding: 0 0 8px; }
  .b-tabla td { padding: 0 0 6px; }
  .b-tabla .cifras span { display: inline; margin-right: 14px; }

  .sal-pasadas a { grid-template-columns: minmax(0, 1fr); gap: 2px; padding: 14px 0; }
  .b-viejas li { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .sam-lista li { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

@media (max-width: 560px) {
  .in-top-in { padding: 11px 16px; }
  .in-portada { padding-left: 16px; padding-right: 16px; }
  .banda-in { padding-left: 16px; padding-right: 16px; }
  .in-foot-in { padding-left: 16px; padding-right: 16px; }
  .in-estado { padding: 18px 18px; }
  .sal-boleta { padding: 20px 18px; }
  /* La muesca del tiquete estorba cuando la boleta es casi tan ancha como la
     pantalla: se quita y queda una tarjeta limpia. */
  .sal-boleta::before, .sal-boleta::after { display: none; }
  .in-ahora span { display: none; }
}

/* =====================================================================
   EL MOVIMIENTO

   Va al final y a propósito: es la única sección de esta hoja que se puede
   borrar entera sin que la página cambie de forma. Todo lo de aquí abajo
   cuelga de `html.js`, y esa clase no la pone el servidor: la pone
   public/info.js en su primera línea. Si esa petición falla, la clase no
   llega, nada de esto se aplica y queda la página de siempre —quieta y
   completa—, que es exactamente la degradación que se quiere.

   DOS PALANCAS Y NINGUNA MÁS.

     --mx / --my   dónde está el puntero, de -1 a 1, con el centro de la
                   pantalla en 0. Las escribe info.js en el <html>, con
                   retardo (persigue al ratón, no lo copia) y solo en
                   escritorio con ratón de verdad.
     .ve           esto ya entró en pantalla. Va sobre CONTENEDORES, y sus
                   hijos entran escalonados según --rv, que es su turno.

   LA REGLA DE LA CASA AQUÍ, que es la misma de toda la hoja escrita para
   otra cosa: el índice no decora las bandas, y el movimiento tampoco. Lo
   que se mueve lo hace con el material de SU banda —su color de acento, su
   trama, su marco— y no con un efecto igual para las siete. De ahí la
   decisión que manda en toda esta sección:

     las bandas oscuras reciben halo y luz; las de papel, no.

   Un halo de color sobre papel no es papel, es una lámpara. Las tres
   claras —el reto, las salidas y el semillero— reciben en cambio lo suyo:
   se les mueve la trama y se les levanta la hoja con una sombra, que es lo
   que hace el papel de verdad.

   Y NADA DE ESTO PASA si el sistema pide que no se mueva nada. El bloque
   del final apaga todo y deja cada pieza en su sitio, visible: quien pidió
   quietud pidió eso, no una página a medias.
   ===================================================================== */

/* ---------------------------------------------------------------------
   LAS ENTRADAS
   Con animation y no con transition, y esa es la decisión que hace que
   todo lo demás quepa: la animación se queda con `translate` y `opacity`,
   y deja `transform` y `transition` LIBRES para el hover de cada ficha.
   Si la entrada usara transform, cada tarjeta que se levanta al pasar el
   ratón tendría que pelearse por especificidad con su propia entrada —y
   heredaría además su retardo, así que levantarse tardaría medio segundo.
   --------------------------------------------------------------------- */
html.js [data-rv] { opacity: 0; }

html.js .ve > [data-rv] {
  animation: rv-entra .62s cubic-bezier(.22, .61, .36, 1) both;
  /* El turno de la pieza dentro de su caja. 62 ms es lo justo para que se
     lea como una fila y no como siete cosas sueltas apareciendo. */
  animation-delay: calc(var(--rv, 0) * 62ms);
}

@keyframes rv-entra {
  from { opacity: 0; translate: 0 var(--rv-y, 15px); }
  to   { opacity: 1; translate: 0 0; }
}

/* Los titulares suben más que el resto. Son lo primero que se lee de cada
   banda y el recorrido más largo es lo que hace que se lean como entrada y
   no como un fundido. */
html.js .in-portada h1,
html.js .b-cab h2 { --rv-y: 26px; }

/* Los renglones de archivo suben poco: son ocho seguidos, y ocho renglones
   recorriendo 15 px cada uno se ve como una persiana. */
html.js .b-viejas li,
html.js .sal-pasadas li,
html.js .sam-lista li,
html.js .sam-perfiles li,
html.js .expo-salas li { --rv-y: 9px; }

/* ---------------------------------------------------------------------
   LA PORTADA — las tres capas
   Es el único sitio de la página donde el índice puede decorar, porque es
   lo único que es suyo: aquí no habla ningún evento. Tres planos y el
   paralaje sale de que se mueven a distinta velocidad y en distinto
   sentido, no de que se muevan mucho.

     el halo    persigue al puntero, de frente y lejos (es la luz);
     la trama   se va al lado contrario, poco (es el fondo);
     el texto   se aparta del puntero, cada renglón un poco más que el de
                arriba (es lo que está cerca).
   --------------------------------------------------------------------- */
html.js .in-portada {
  position: relative;
  /* Las dos capas van con z-index negativo para quedar bajo el texto sin
     tener que numerar el texto. El aislamiento las encierra aquí: sin él,
     un -1 se iría a buscar el fondo del <body> y desaparecería. */
  isolation: isolate;
}

/* El halo. Es el mismo violeta del armazón —el único color que esta página
   puede llamar suyo— y está tan bajo que no se ve: se nota. */
html.js .in-portada::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -14%;
  left: 50%;
  width: min(780px, 96vw);
  aspect-ratio: 1;
  margin-left: calc(min(780px, 96vw) / -2);
  background: radial-gradient(circle closest-side,
              rgba(143, 123, 255, .22), rgba(143, 123, 255, 0) 100%);
  pointer-events: none;
  transform: translate3d(calc(var(--mx, 0) * 86px), calc(var(--my, 0) * 58px), 0);
}

/* La trama. El armazón nunca tuvo una y las bandas de papel sí —la pauta de
   las salidas, la cuadrícula del semillero—, así que aquí se le da la suya:
   puntos, que no son de nadie. Difuminada por los bordes con una máscara,
   porque una retícula que termina en línea recta se lee como una tabla. */
html.js .in-portada::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -30px -8vw 0;
  background-image: radial-gradient(circle at center, rgba(236, 234, 245, .17) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(ellipse 68% 68% at 50% 38%, #000, transparent 74%);
          mask-image: radial-gradient(ellipse 68% 68% at 50% 38%, #000, transparent 74%);
  opacity: .55;
  pointer-events: none;
  transform: translate3d(calc(var(--mx, 0) * -20px), calc(var(--my, 0) * -13px), 0);
}

/* El texto. Recorridos pequeños y crecientes: el ojo no ve los píxeles, ve
   que el bloque de abajo va por delante del de arriba. Pasados los 20 px la
   portada deja de tener profundidad y empieza a tener un temblor. */
html.js.con-paralaje .in-eyebrow { transform: translate3d(calc(var(--mx, 0) * -4px),  calc(var(--my, 0) * -3px),  0); }
html.js.con-paralaje .in-portada h1 { transform: translate3d(calc(var(--mx, 0) * -8px),  calc(var(--my, 0) * -5px),  0); }
html.js.con-paralaje .in-lead   { transform: translate3d(calc(var(--mx, 0) * -11px), calc(var(--my, 0) * -7px),  0); }
html.js.con-paralaje .in-estado { transform: translate3d(calc(var(--mx, 0) * -15px), calc(var(--my, 0) * -9px),  0); }
html.js.con-paralaje .in-atajos { transform: translate3d(calc(var(--mx, 0) * -19px), calc(var(--my, 0) * -11px), 0); }

/* ---------------------------------------------------------------------
   LAS BANDAS
   Dos cosas por banda y las dos con SU color, que es lo único que esta
   sección se permite añadirles.
   --------------------------------------------------------------------- */
html.js .banda { position: relative; }

/* El contenido, por encima del halo. Sin esto el halo —que está
   posicionado— se pintaría sobre un contenido que no lo está. */
html.js .banda-in { position: relative; z-index: 1; }

/* EL HALO. Un foco enorme y bajísimo del acento de la banda, que se
   enciende al llegar y se mueve con el puntero. No se mueve con transform
   sino cambiando de dónde sale el degradado: así no hay una capa que
   desplazar y no hay nada que se pueda salir de la banda. */
html.js .banda::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(62% 52% at calc(50% + var(--mx, 0) * 15%) calc(34% + var(--my, 0) * 13%),
              color-mix(in srgb, var(--acento) 13%, transparent),
              transparent 72%);
  opacity: 0;
  transition: opacity 1.1s ease;
}
html.js .banda.ve::before { opacity: 1; }

/* Las tres de papel no llevan halo, por lo que dice la cabecera de esta
   sección. La del reto se queda solo con su línea; a las otras dos se les
   mueve la trama, que es su equivalente. */
html.js .b-ink::before,
html.js .b-sal::before,
html.js .b-sami::before { display: none; }

html.js.con-paralaje .b-sal,
html.js.con-paralaje .b-sami {
  /* Seis píxeles. La pauta de las salidas mide 34 y la cuadrícula del
     semillero 26: más que esto y la trama se ve caminar, que es un defecto
     de impresión, no un efecto. */
  background-position: calc(var(--mx, 0) * 6px) calc(var(--my, 0) * 6px);
}

/* LA LÍNEA. El corte entre bandas ya era una línea de --linea; encima se
   dibuja la de su acento cuando se llega. Es la única cosa de esta hoja que
   se anima sola y no responde a nada, y se permite porque es exactamente lo
   que la página quiere decir en ese punto: aquí empieza otra cosa, y esta
   es de qué color es. */
html.js .banda::after {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 2;
  /* Se apaga hacia la derecha en vez de cruzar la banda entera. A ancho
     completo y en color plano dejaba de ser un corte y empezaba a ser una
     barra de carga: lo mismo que dibuja un navegador cuando está ocupado.
     Así el color se dice donde empieza la lectura y se disuelve. */
  background: linear-gradient(90deg,
              var(--acento) 0,
              color-mix(in srgb, var(--acento) 50%, transparent) 34%,
              transparent 76%);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 1.2s cubic-bezier(.22, .61, .36, 1);
  pointer-events: none;
}
html.js .banda.ve::after { transform: scaleX(1); }

/* ---------------------------------------------------------------------
   LA CABECERA
   Se asienta al bajarse de la portada y lleva el avance en un hilo. Las dos
   son información: con siete bandas largas, "voy por la mitad" es un dato.
   --------------------------------------------------------------------- */
html.js .in-top {
  transition: background-color .3s ease, border-color .3s ease, box-shadow .3s ease;
}
html.js .in-top.pegada {
  background: rgba(11, 11, 16, .94);
  border-bottom-color: #2e2e3c;
  box-shadow: 0 14px 34px -22px #000;
}

html.js .in-top::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--marco-acento);
  transform: scaleX(var(--avance, 0));
  transform-origin: 0 50%;
  opacity: .8;
  pointer-events: none;
}

html.js .in-ahora { transition: border-color .25s ease, background-color .25s ease; }
html.js .in-ahora:hover { background: #1a1a24; }

/* ---------------------------------------------------------------------
   LOS ATAJOS
   El de la banda que se está mirando se enciende. No es adorno: es la única
   forma que tiene esta página de decir dónde va uno, porque no hay barra de
   navegación y las bandas miden tres pantallas.
   --------------------------------------------------------------------- */
html.js .in-atajos a {
  transition: color .25s ease, border-color .25s ease, background-color .25s ease;
}
html.js .in-atajos a.aqui {
  color: var(--marco-ink);
  border-color: var(--marco-acento);
  background: rgba(143, 123, 255, .13);
}

/* ---------------------------------------------------------------------
   EL ENLACE DEL FINAL DE CADA BANDA
   La flecha ya estaba; ahora sale. El contenido se reescribe sin el espacio
   de delante porque un inline-block se come el espacio inicial, y el aire
   lo pone el margen.
   --------------------------------------------------------------------- */
html.js .b-ir { transition: background-color .25s ease, color .25s ease; }
html.js .b-ir::after {
  content: "→";
  display: inline-block;
  margin-left: 7px;
  transition: transform .25s cubic-bezier(.22, .61, .36, 1);
}
html.js .b-ir:hover::after { transform: translateX(5px); }

/* ---------------------------------------------------------------------
   LAS FICHAS, UNA POR UNA
   Aquí no hay una regla común y no debería haberla: cada banda reacciona
   con su propio material. Es la misma idea de toda la hoja —lo compartido
   arriba, lo propio abajo—, y es lo que impide que el movimiento aplane las
   siete caras que la página se tomó el trabajo de mantener separadas.
   --------------------------------------------------------------------- */

/* LA EXPO — editorial. En una revista no se levanta nada: se subraya. El
   renglón del anuario se tiñe y ya. */
html.js .b-expo .b-tabla tr { transition: background-color .25s ease; }
html.js .b-expo .b-tabla tr:hover { background: rgba(91, 156, 246, .06); }
html.js .expo-salas li { transition: transform .25s cubic-bezier(.22, .61, .36, 1); }
html.js .expo-salas li:hover { transform: translateX(4px); }

/* EL TORNEO — la luz. La ficha de cada juego se enciende con SU color,
   donde está el puntero. Va en un ::after con z-index negativo para quedar
   entre el fondo de la ficha y su texto: una luz por encima de las letras
   sería un velo. El clip-path de la ficha ya la encierra, así que la luz
   respeta la esquina cortada sin una sola regla más. */
html.js .vc-juego { transition: transform .3s cubic-bezier(.22, .61, .36, 1); }
html.js .vc-juego::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0;
  transition: opacity .35s ease;
  background: radial-gradient(210px circle at var(--sx, 50%) var(--sy, 50%),
              color-mix(in srgb, var(--juego) 24%, transparent), transparent 70%);
  pointer-events: none;
}
html.js .vc-juego:hover { transform: translateY(-3px); }
html.js .vc-juego:hover::after { opacity: 1; }

/* La misma luz para el estado del semestre, que es la única ficha de la
   portada. Ahí el color no es de ningún juego: es el del armazón. */
html.js .in-estado { position: relative; isolation: isolate; }
html.js .in-estado::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  opacity: 0;
  transition: opacity .35s ease;
  background: radial-gradient(240px circle at var(--sx, 50%) var(--sy, 50%),
              rgba(143, 123, 255, .16), transparent 72%);
  pointer-events: none;
}
html.js .in-estado:hover::before { opacity: 1; }

/* LA JAM — el píxel. Y aquí NO hay transición, que es todo el asunto: en
   una consola de 8 bits nada se desliza. La ficha salta los mismos 4 px de
   la retícula y el marco se pone verde de golpe. Suavizarlo la sacaría de
   su propia estética, que es justo lo que esta página no hace. */
html.js .jam-edicion:hover,
html.js .jam-reglas:hover {
  --marco: var(--acento);
  transform: translate(0, calc(var(--px) * -1));
}

/* EL FESTIVAL — el cartel. Pasar por encima de un nombre apaga los demás,
   que es lo que hace la vista cuando busca a alguien en un cartel de
   festival. El resplandor es del magenta del degradado. */
html.js .mf-fila span { transition: color .3s ease, text-shadow .3s ease; }
html.js .mf-cartel:hover span { color: var(--mute); }
html.js .mf-fila span:hover {
  color: var(--tinta);
  text-shadow: 0 0 30px rgba(255, 45, 120, .55);
}

/* EL RETO Y LAS SALIDAS — el papel. Se levanta y hace sombra; no se
   enciende. El del reto además se tuerce un pelo, porque el suyo es papel
   suelto dibujado a mano y el de las salidas es un formato en una carpeta. */
html.js .ink-edicion,
html.js .ink-reglas {
  transition: transform .3s cubic-bezier(.22, .61, .36, 1), box-shadow .3s ease;
}
html.js .ink-edicion:hover,
html.js .ink-reglas:hover {
  transform: translateY(-4px) rotate(-.4deg);
  box-shadow: 0 12px 24px -16px rgba(22, 18, 12, .55);
}

html.js .sal-boleta {
  transition: transform .3s cubic-bezier(.22, .61, .36, 1), box-shadow .3s ease;
}
html.js .sal-boleta:hover {
  transform: translateY(-3px);
  /* La sombra plana y corta de la hoja sigue ahí debajo: la boleta se
     despega del papel, no flota sobre él. */
  box-shadow: 0 2px 0 rgba(32, 29, 22, .06), 0 16px 28px -20px rgba(32, 29, 22, .5);
}

/* EL SEMILLERO — el cuaderno. Un renglón de cuaderno no se levanta: se
   marca al margen, que es lo que hace quien lee con un lápiz en la mano. */
html.js .sam-lista li,
html.js .sam-perfiles li {
  transition: background-color .25s ease, box-shadow .25s ease;
}
html.js .sam-lista li:hover,
html.js .sam-perfiles li:hover {
  background: rgba(43, 71, 180, .05);
  box-shadow: inset 3px 0 0 var(--acento);
}

/* Los renglones de archivo de las bandas oscuras. La jam se queda fuera a
   propósito: ahí nada se desliza. */
html.js .b-expo .b-viejas li,
html.js .b-vc .b-viejas li,
html.js .b-mf .b-viejas li,
html.js .sal-pasadas a {
  transition: transform .25s cubic-bezier(.22, .61, .36, 1), color .25s ease;
}
html.js .b-expo .b-viejas li:hover,
html.js .b-vc .b-viejas li:hover,
html.js .b-mf .b-viejas li:hover,
html.js .sal-pasadas a:hover { transform: translateX(4px); }

/* ---------------------------------------------------------------------
   Pantallas angostas
   El paralaje ya no existe aquí (info.js pide 900 px y ratón), pero las dos
   capas de la portada sí, y en un teléfono el halo es la mitad de la
   pantalla. Se encogen.
   --------------------------------------------------------------------- */
@media (max-width: 700px) {
  html.js .in-portada::before { top: -6%; width: min(420px, 88vw); margin-left: calc(min(420px, 88vw) / -2); }
  html.js .in-portada::after { background-size: 22px 22px; opacity: .4; }
}

/* ---------------------------------------------------------------------
   QUIEN PIDIÓ QUE NADA SE MUEVA
   Se apaga todo lo de arriba y —esto es lo que importa— se dejan las piezas
   PUESTAS: visibles, con su línea de color dibujada y su halo encendido.
   Una página sin movimiento no es una página a medio cargar.

   Las dos primeras reglas repiten el selector completo de la entrada porque
   tiene que ganarle en especificidad, no por costumbre.
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  /* El desplazamiento suave de los atajos es justamente movimiento que
     nadie pidió. */
  html { scroll-behavior: auto; }

  html.js [data-rv],
  html.js .ve > [data-rv] { opacity: 1; translate: 0 0; animation: none; }

  html.js .banda::before { opacity: 1; transition: none; }
  html.js .banda::after { transform: scaleX(1); transition: none; }

  html.js .in-top,
  html.js .in-atajos a,
  html.js .b-ir,
  html.js .b-ir::after,
  html.js .vc-juego,
  html.js .vc-juego::after,
  html.js .in-estado::before,
  html.js .mf-fila span,
  html.js .ink-edicion,
  html.js .ink-reglas,
  html.js .sal-boleta,
  html.js .expo-salas li,
  html.js .sam-lista li,
  html.js .sam-perfiles li,
  html.js .b-viejas li,
  html.js .sal-pasadas a { transition: none; }

  html.js .b-ir:hover::after,
  html.js .vc-juego:hover,
  html.js .expo-salas li:hover,
  html.js .ink-edicion:hover,
  html.js .ink-reglas:hover,
  html.js .sal-boleta:hover,
  html.js .jam-edicion:hover,
  html.js .jam-reglas:hover,
  html.js .b-viejas li:hover,
  html.js .sal-pasadas a:hover { transform: none; }
}
