/* ------------------------------------------------------------------ stage
   La pantalla compartida. Mismo lenguaje que el móvil: blanco, centrado, filete
   de un pixel, tipo grande pero contenida.

   Nada se posiciona en píxeles absolutos. En v1 el título estaba en top:76px y el
   contenido en top:280px, así que en un proyector 16:10 se solapaban.
--------------------------------------------------------------------------- */

/* El stage se mira desde el otro lado de la sala, no a treinta centímetros. A
   esa distancia el movimiento rápido se pierde: donde el móvil es ágil, aquí
   todo va casi al doble de lento para que dé tiempo a leerlo. */
body.stage-body {
  overflow: hidden;
  --fast: 300ms;
  --base: 560ms;
  --slow: 980ms;
}

/* Aire: una viñeta cálida casi imperceptible que late muy despacio. No es
   decoración —no se "ve"— pero quita la sensación de folio en blanco muerto y
   deja la pantalla respirando cuando nadie toca nada. Una sola capa, sin blur,
   para que un proyector modesto no sufra. */
.stage-air {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--accent) 5%, transparent), transparent 62%),
    radial-gradient(90% 70% at 50% 100%, color-mix(in srgb, var(--accent) 4%, transparent), transparent 58%);
  animation: air 16s ease-in-out infinite;
}
@keyframes air {
  0%, 100% { opacity: .55; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.04); }
}
.stage, .interlude, .stage-veil { position: fixed; z-index: 1; }

.stage {
  position: fixed;
  inset: 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  transition: filter var(--slow) var(--ease), opacity var(--slow);
}
.stage.veiled { filter: blur(22px); opacity: .35; }

/* ---------------------------------------------------------------- chrome */

.mono-label {
  font-family: var(--mono);
  font-size: clamp(9px, .72vw, 12px);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}
.mono-label i { font-style: normal; margin: 0 4px; opacity: .5; }

.stage-top .brand { --brand-size: clamp(22px, 2vw, 30px); }
.stage-top {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: clamp(20px, 2.2vw, 34px) clamp(24px, 3vw, 52px);
}
.stage-top > :last-child { text-align: right; }
.stage-top > :nth-child(2) { color: var(--accent); }

/* ------------------------------------------------------------------ main */

.stage-main {
  min-height: 0;
  /* Y min-width: por defecto un elemento de grid no encoge por debajo de su
     contenido, así que un bloque ancho de más hacía crecer al <main> por encima
     del escenario entero. El escenario recorta —es fixed y overflow:hidden— así
     que eso no da scroll: da contenido invisible. Nada puede ser más ancho que
     la pantalla que se proyecta. */
  min-width: 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: clamp(22px, 2.8vw, 46px);
  padding: clamp(8px, 1.6vw, 26px) clamp(28px, 5vw, 92px) 0;
}
/* Un momento no es una pregunta con instrumento debajo: es una sola imagen
   centrada. Por eso cambia de grid a flex y puede invertir el orden para poner
   la marca encima del titular. */
.stage-main.is-moment {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(22px, 4vh, 54px);
}
.stage-main.is-moment.mark-first { flex-direction: column-reverse; }
.stage-main.is-moment .stage-view { width: auto; padding: 0; }
.stage-main.is-moment .stage-view:empty { display: none; }

.stage-head {
  display: grid;
  align-content: start;
  gap: clamp(8px, .9vw, 14px);
  justify-items: center;
  text-align: center;
}
/* El cuerpo baja según crece el titular. A tamaño fijo, una frase de tres
   líneas se come la pantalla y empuja fuera lo que hay debajo —que suele ser
   justo lo que la sala tiene que leer—. Se lee desde el fondo de una sala igual:
   lo que hace legible a distancia es el contraste y el aire, no el tamaño. */
.stage-title {
  margin: 0;
  max-width: 22ch;
  font-size: clamp(27px, 3vw, 48px);
  line-height: 1.05;
  letter-spacing: -.032em;
  font-weight: 600;
  text-wrap: balance;
}
.stage-title[data-len='mid'] { max-width: 24ch; font-size: clamp(24px, 2.5vw, 40px); }
.stage-title[data-len='long'] { max-width: 28ch; font-size: clamp(21px, 2.1vw, 33px); line-height: 1.14; letter-spacing: -.022em; }
.stage-main.is-moment .stage-title { font-size: clamp(32px, 4.2vw, 68px); max-width: 17ch; }
.stage-main.is-moment .stage-title[data-len='mid'] { font-size: clamp(29px, 3.5vw, 56px); max-width: 19ch; }
.stage-main.is-moment .stage-title[data-len='long'] { font-size: clamp(25px, 2.8vw, 44px); max-width: 24ch; line-height: 1.1; }
.stage-lede {
  margin: 0;
  max-width: 46ch;
  font-size: clamp(14px, 1.15vw, 19px);
  line-height: 1.45;
  color: var(--ink-2);
}
.stage-lede:empty { display: none; }
.stage-head .kicker:empty { display: none; }

.stage-view {
  min-height: 0;
  display: grid;
  place-items: center;
  padding-bottom: clamp(12px, 1.6vw, 26px);
}
.stage-view > * { width: 100%; }

/* ------------------------------------------------------------------ foot */

.stage-foot {
  display: grid;
  gap: clamp(10px, 1.1vw, 16px);
  padding: 0 clamp(24px, 3vw, 52px) clamp(18px, 2vw, 30px);
}
.people {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  min-height: 30px;
}
.person {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 12px 0 8px;
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: clamp(11px, .8vw, 13px);
  color: var(--ink-2);
  transition: box-shadow var(--base), color var(--base), background var(--base);
}
.person i {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--line-strong);
  transition: background var(--base), transform var(--base) var(--ease);
}
.person.locked {
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--accent-line);
  background: var(--accent-soft);
}
.person.locked i { background: var(--accent); transform: scale(1.15); }

.stage-progress { height: 1px; background: var(--line); }
.stage-progress i {
  display: block;
  height: 1px;
  width: 0;
  background: var(--accent);
  transition: width var(--slow) var(--ease);
}

/* --------------------------------------------------------------- momentos */

.moment-mark { display: grid; place-items: center; }
.moment-mark canvas { width: clamp(180px, 22vh, 300px); height: clamp(180px, 22vh, 300px); }

/* Unirse: el QR es el protagonista, nada más compite con él. */
.join {
  display: grid;
  justify-items: center;
  gap: clamp(14px, 1.6vw, 22px);
}
.join-qr {
  width: clamp(200px, 30vh, 330px);
  aspect-ratio: 1;
  padding: 14px;
  border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--line);
}
.join-qr img { width: 100%; height: 100%; display: block; }
.join-url {
  font-family: var(--mono);
  font-size: clamp(11px, .85vw, 14px);
  letter-spacing: .06em;
  color: var(--ink-2);
}

/* Cierre: el resumen que se lee en voz alta. */
/* Filete sobre cada dato, sin caja. Una rejilla con gap coloreado dejaría un
   bloque gris en la última celda cuando el número de decisiones no es exacto. */
/* El resumen final tiene que caber en el proyector que haya.
 *
 * `auto-fit` sólo sabe cuántas columnas caben si alguien le dice cuánto mide
 * la pantalla. Aquí no lo sabía: los momentos declaran `.stage-view { width:
 * auto }` —para que una ilustración centrada no se estire— y con eso la rejilla
 * se medía por su propio contenido. Elegía cuatro columnas siempre, el <main>
 * crecía hasta 1282px dentro de un escenario de 1024, y como el stage es
 * overflow:hidden no hay scroll que valga: se RECORTA. En la última
 * diapositiva, la que Daniel proyecta mientras cierra la reunión, la cuarta
 * columna de decisiones se quedaba fuera de cuadro. Se veía perfecta en el
 * portátil donde se escribió y rota en cualquier sala de 4:3.
 *
 * Devolverle el ancho de la pantalla basta: con un ancho definido, `auto-fit`
 * baja a tres columnas o a dos él solo.
 */
/* El cierre se lleva el alto que sobra, igual que la escena del editor: si no,
   la caja que se le da vale lo que mide su contenido y medir «si cabe» contra
   eso no dice nada —siempre cabe en sí mismo—. Con la caja fijada, encogerla
   sirve de algo y lo que sobra deja de repartirse como centrado. */
.stage-main.is-moment .stage-view:has(.recap-grid) {
  flex: 1;
  min-height: 0;
  width: 100%;
  align-self: stretch;
  align-items: start;
  padding-bottom: 0;
}
.recap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: calc(clamp(14px, 1.8vw, 30px) * var(--recap-scale));
  /* El tope era 1180px a secas y en una pantalla más estrecha eso no es un
     tope, es una anchura mínima impuesta: `auto-fit` seguía dando cuatro
     columnas de 230 y la última se salía. Con `min(...)` el límite es el
     menor de los dos y las columnas bajan a tres, o a dos, solas. */
  max-width: min(1180px, 100%);
  margin-inline: auto;
}
/* `--recap-scale` lo pone stage.js cuando el cierre no cabe de alto: encoge
   texto y aire a la vez, que es lo que hace que entre una fila más sin que la
   diapositiva parezca apretada por un lado y suelta por el otro. Vale 1
   mientras no haga falta. */
.recap-grid { --recap-scale: 1; }
.recap-cell {
  display: grid;
  align-content: start;
  gap: calc(8px * var(--recap-scale));
  padding-top: calc(clamp(10px, 1vw, 15px) * var(--recap-scale));
  border-top: 1px solid var(--line-strong);
}
.recap-cell small {
  font-family: var(--mono);
  /* La etiqueta encoge con la respuesta. Escalando sólo el texto grande, el
     cierre acababa con rótulos enormes sobre respuestas diminutas. */
  font-size: calc(10px * var(--recap-scale));
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.recap-cell b {
  font-size: calc(clamp(16px, 1.35vw, 22px) * var(--recap-scale));
  font-weight: 500;
  letter-spacing: -.018em;
  line-height: 1.25;
}

/* ------------------------------------------------------------------ pick */

.bars {
  max-width: 960px;
  margin-inline: auto;
  border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden;
}
.bar {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 18px;
  padding: clamp(12px, 1.2vw, 18px) clamp(16px, 1.6vw, 26px);
  overflow: hidden;
}
.bar + .bar { border-top: 1px solid var(--line); }
.bar::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--p, 0%);
  background: var(--accent-soft);
  transition: width var(--slow) var(--ease);
}
.bar b {
  position: relative;
  font-size: clamp(16px, 1.5vw, 24px);
  font-weight: 400;
  letter-spacing: -.02em;
  transition: font-weight var(--base);
}
.bar.lead b { font-weight: 600; }
.bar.zero { color: var(--ink-3); }
.bar span {
  position: relative;
  font-family: var(--mono);
  font-size: clamp(11px, .9vw, 14px);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.bar.zero span { color: var(--ink-3); }

/* ---------------------------------------------------------------- escala */

.scale-stage {
  max-width: 980px;
  margin-inline: auto;
  display: grid;
  gap: clamp(14px, 1.4vw, 22px);
}
.scale-poles {
  display: flex;
  justify-content: space-between;
  font-size: clamp(13px, 1.1vw, 18px);
  font-weight: 500;
}
.scale-poles span:last-child { text-align: right; }

.scale-rail {
  position: relative;
  height: 118px;
}
.scale-rail .line {
  position: absolute;
  left: 0; right: 0; top: 34px;
  height: 1px;
  background: var(--line-strong);
}
.scale-rail .pins { position: absolute; inset: 0; }
.scale-rail .avg {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  display: grid;
  justify-items: center;
  gap: 6px;
  transition: left var(--slow) var(--ease);
}
.scale-rail .avg b {
  font-family: var(--mono);
  font-size: clamp(15px, 1.3vw, 20px);
  font-variant-numeric: tabular-nums;
}
.scale-rail .avg i {
  width: 1px;
  height: 22px;
  background: var(--accent);
}
.scale-rail .pin {
  position: absolute;
  top: 46px;
  transform: translateX(-50%);
  display: grid;
  justify-items: center;
  gap: 6px;
  transition: left var(--base) var(--ease);
}
.scale-rail .pin u {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--ink);
  text-decoration: none;
}
.scale-rail .pin span {
  font-size: 11px;
  color: var(--ink-2);
  white-space: nowrap;
}
.scale-spread {
  text-align: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Previsualización de densidad sobre la pantalla compartida. */
.density-stage {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap, 20px);
  height: clamp(70px, 10vh, 120px);
  max-width: 760px;
  margin-inline: auto;
  transition: gap var(--slow) var(--ease);
}
/* El filete es lo que las hace visibles en un proyector: un relleno al 2% de
   contraste desaparece en la sala. */
.density-stage i {
  background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--line);
  border-radius: 5px;
}

/* ------------------------------------------------------------------ plano */

.plot-wrap { display: grid; justify-items: center; gap: 10px; }
.plot-axis {
  font-family: var(--mono);
  font-size: clamp(9px, .75vw, 12px);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.plot-row { display: grid; grid-template-columns: auto auto auto; align-items: center; gap: clamp(10px, 1.4vw, 20px); }
.plot {
  position: relative;
  width: clamp(240px, 46vh, 460px);
  aspect-ratio: 1;
  border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--line);
}
.plot .cross { position: absolute; background: var(--line); }
.plot .cross.x { left: 0; right: 0; top: 50%; height: 1px; }
.plot .cross.y { top: 0; bottom: 0; left: 50%; width: 1px; }
.plot .pts { position: absolute; inset: 0; }
.plot .pt {
  position: absolute;
  display: grid;
  justify-items: center;
  gap: 4px;
  transform: translate(-50%, -50%);
  transition: left var(--slow) var(--ease), top var(--slow) var(--ease);
}
.plot .pt u { width: 9px; height: 9px; border-radius: 50%; background: var(--ink); text-decoration: none; }
.plot .pt span { position: absolute; top: 12px; font-size: 10px; color: var(--ink-2); white-space: nowrap; }
.plot .centroid {
  position: absolute;
  width: 34px; height: 34px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  box-shadow: inset 0 0 0 1px var(--accent);
  transition: left var(--slow) var(--ease), top var(--slow) var(--ease), width var(--slow), height var(--slow);
}

/* ------------------------------------------------------------ presupuesto */

.columns {
  max-width: 1000px;
  margin-inline: auto;
  display: grid;
  grid-auto-flow: column;
  /* minmax(0,1fr): sin el 0 una etiqueta larga fuerza la columna y el conjunto
     se desborda por la izquierda. */
  grid-auto-columns: minmax(0, 1fr);
  gap: clamp(8px, 1vw, 16px);
  height: clamp(180px, 34vh, 340px);
}
.column { display: flex; flex-direction: column; gap: 10px; height: 100%; }
.column .tube {
  position: relative;
  flex: 1;
  min-height: 0;
  border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden;
}
.column .tube i {
  position: absolute;
  inset: auto 0 0;
  height: var(--h, 0%);
  background: var(--accent-soft);
  transition: height var(--slow) var(--ease);
}
.column .tube b {
  position: absolute;
  inset: auto 0 10px;
  text-align: center;
  font-family: var(--mono);
  font-size: clamp(16px, 1.6vw, 26px);
  font-variant-numeric: tabular-nums;
}
.column p {
  margin: 0;
  text-align: center;
  font-size: clamp(11px, .95vw, 15px);
  line-height: 1.2;
  color: var(--ink-2);
}
.column.lead p { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------------- moodboard */

.ref-stage { display: grid; place-items: center; width: 100%; }
.ref-live {
  display: grid;
  justify-items: center;
  gap: clamp(10px, 1.2vw, 18px);
  width: 100%;
}
.ref-big {
  width: min(58vh, 100%);
  aspect-ratio: 4 / 3;
  border-radius: var(--r-lg);
  background: var(--surface-2) center top / cover no-repeat;
  box-shadow: inset 0 0 0 1px var(--line);
}
.ref-big.empty { display: grid; place-items: center; }
.ref-info { display: grid; justify-items: center; gap: 3px; text-align: center; }
.ref-info b { font-size: clamp(19px, 1.8vw, 28px); font-weight: 600; letter-spacing: -.025em; }
.ref-info span { font-size: clamp(13px, 1vw, 16px); color: var(--ink-2); }
/* Atribución: el material es de otros y se dice. */
.ref-info em {
  font-family: var(--mono);
  font-size: 10px;
  font-style: normal;
  letter-spacing: .1em;
  color: var(--ink-3);
}

.ref-tally { display: flex; gap: clamp(26px, 4vw, 60px); align-items: baseline; }
.ref-tally .side { display: grid; justify-items: center; gap: 2px; }
.ref-tally u {
  text-decoration: none;
  font-size: clamp(28px, 3vw, 48px);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  transition: color var(--base);
}
.ref-tally .side.lead u { color: var(--ink); }
.ref-tally .side.yes.lead u { color: var(--accent); }
.ref-tally p {
  margin: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.ref-counter {
  margin: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Veredicto final: de lo más querido a lo más rechazado. */
.ref-board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: clamp(10px, 1.2vw, 18px);
  width: 100%;
  max-width: 1150px;
}
.ref-chip { display: grid; gap: 6px; opacity: .45; transition: opacity var(--base); }
.ref-chip.loved { opacity: 1; }
.ref-chip.rejected { opacity: .3; }
.ref-chip-shot {
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  background: var(--surface-2) center top / cover no-repeat;
  box-shadow: inset 0 0 0 1px var(--line);
}
.ref-chip.rejected .ref-chip-shot { filter: grayscale(1); }
.ref-chip b { font-size: 13px; font-weight: 500; letter-spacing: -.012em; }
.ref-chip span {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  color: var(--ink-3);
}
.ref-chip.loved span { color: var(--accent); }

/* ------------------------------------------------------------ interludio */

/* Ocupa la pantalla entera: durante un segundo y medio la sala solo mira esto,
   que es justo el efecto que se busca entre una decisión y la siguiente. */
.interlude {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: clamp(10px, 1.2vw, 18px);
  padding: 6vw;
  text-align: center;
  background: var(--paper);
}
.interlude-said {
  margin: 0;
  max-width: 18ch;
  font-size: clamp(34px, 4.6vw, 76px);
  line-height: 1.02;
  letter-spacing: -.036em;
  font-weight: 600;
  text-wrap: balance;
}
.interlude-cue {
  margin: 0;
  max-width: 34ch;
  font-size: clamp(15px, 1.3vw, 22px);
  line-height: 1.4;
  color: var(--ink-2);
}
.interlude-bar {
  position: relative;
  margin-top: clamp(10px, 1.4vw, 22px);
  width: clamp(54px, 5vw, 78px);
  height: 2px;
  border-radius: 2px;
  background: var(--line);
  overflow: hidden;
}
.interlude-bar::after {
  content: '';
  position: absolute;
  inset: 0 100% 0 0;
  background: var(--accent);
  animation: interludeBar var(--dur, 1900ms) linear both;
}
@keyframes interludeBar { to { right: 0; } }

/* El desenfoque se reserva al texto. Animarlo sobre la vista entera —con
   imágenes del moodboard dentro— hace sufrir a un proyector modesto; en una
   línea de titular es barato y es lo que da la sensación de que algo "llega"
   en vez de aparecer. */
.fade-line { animation: fadeLine 1100ms var(--ease) both; }
@keyframes fadeLine {
  from { opacity: 0; transform: translateY(10px); filter: blur(5px); }
  to { opacity: 1; transform: none; filter: none; }
}

/* El velo del interludio ya no aparece de golpe: se posa. */
.interlude { animation: veilIn 620ms var(--ease) both; }
@keyframes veilIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ------------------------------------------------------- sonda de la IA */

/* Toda la pantalla, con lo de debajo desenfocado. Una pregunta que interrumpe
   tiene que interrumpir de verdad: a medias no consigue que la sala levante la
   vista del móvil. */
.probe-veil {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  place-items: center;
  padding: 5vw;
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  backdrop-filter: blur(30px) saturate(1.1);
  animation: probeIn 700ms var(--ease) both;
}
.probe-veil[hidden] { display: none; }
@keyframes probeIn {
  from { opacity: 0; backdrop-filter: blur(0px); }
  to { opacity: 1; backdrop-filter: blur(30px) saturate(1.1); }
}
.probe-body {
  display: grid;
  justify-items: center;
  gap: clamp(12px, 1.6vw, 24px);
  width: 100%;
  max-width: 1000px;
  text-align: center;
}
.aura { width: clamp(120px, 17vh, 200px); height: clamp(120px, 17vh, 200px); display: block; }
/* El cuerpo baja según crece la pregunta. Una pregunta corta puede permitirse
   ser un titular; una de tres líneas a ese tamaño es un muro. */
.probe-q {
  margin: 0;
  max-width: 24ch;
  font-size: clamp(30px, 3.5vw, 54px);
  line-height: 1.07;
  letter-spacing: -.032em;
  font-weight: 600;
  text-wrap: balance;
}
.probe-q[data-len='mid'] { max-width: 28ch; font-size: clamp(25px, 2.7vw, 41px); line-height: 1.12; }
.probe-q[data-len='long'] {
  max-width: 34ch;
  font-size: clamp(21px, 2.1vw, 33px);
  line-height: 1.2;
  letter-spacing: -.02em;
}

/* Texto generándose: cada palabra emerge de un desenfoque, en orden. El retardo
   por palabra lo pone el JS en --d; aquí sólo se describe cómo entra una. */
.generating > span {
  display: inline-block;
  animation: generateWord 620ms var(--ease) both;
  animation-delay: var(--d, 0ms);
  will-change: opacity, filter, transform;
}
@keyframes generateWord {
  from { opacity: 0; filter: blur(8px); transform: translateY(.16em); }
  to { opacity: 1; filter: blur(0); transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion='full']) .generating > span { animation: none; }
}
.probe-bars {
  display: grid;
  gap: 8px;
  width: min(760px, 100%);
  margin-top: clamp(6px, 1vw, 14px);
}
.probe-bar {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 16px;
  padding: clamp(11px, 1.1vw, 16px) clamp(16px, 1.6vw, 24px);
  border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden;
  text-align: left;
}
.probe-bar::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--p, 0%);
  background: var(--accent-soft);
  transition: width var(--slow) var(--ease);
}
.probe-bar b { position: relative; font-size: clamp(15px, 1.4vw, 21px); font-weight: 400; letter-spacing: -.018em; }
.probe-bar.lead b { font-weight: 600; }
.probe-bar span {
  position: relative;
  font-family: var(--mono);
  font-size: clamp(11px, .9vw, 14px);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.probe-foot {
  margin: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ------------------------------------------------------------------ velo */

.stage-veil {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 6vw;
  background: color-mix(in srgb, var(--paper) 84%, transparent);
  backdrop-filter: blur(26px);
  animation: screenIn var(--slow) var(--ease) both;
}
.stage-veil[hidden] { display: none; }
.stage-veil-body { display: grid; justify-items: center; gap: clamp(14px, 1.6vh, 24px); text-align: center; max-width: min(64ch, 88vw); }
/* Ancho, no cuadrado: ahora son ondas y necesitan recorrido. */
/* Cuadrado: el orbe necesita las dos dimensiones, no una franja. */
.stage-veil canvas { width: clamp(150px, 21vh, 250px); height: clamp(150px, 21vh, 250px); }
/* El cuerpo baja segun crece el texto. A tamano de titular, una frase larga se
   salia de la pantalla por abajo y no habia forma de leer el final. */
.stage-veil h2 {
  margin: 0;
  max-width: 22ch;
  font-size: clamp(30px, 3.6vw, 58px);
  line-height: 1.06;
  letter-spacing: -.034em;
  font-weight: 600;
  text-wrap: balance;
}
.stage-veil h2[data-len='mid'] { max-width: 28ch; font-size: clamp(25px, 2.7vw, 42px); line-height: 1.12; }
.stage-veil h2[data-len='long'] {
  max-width: 34ch;
  font-size: clamp(21px, 2.1vw, 33px);
  line-height: 1.2;
  letter-spacing: -.02em;
}
.stage-veil p { margin: 0; font-size: clamp(15px, 1.2vw, 20px); line-height: 1.45; color: var(--ink-2); max-width: 42ch; }
.topics { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.topics span {
  padding: 7px 13px;
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-2);
}


/* ---------------------------------------------- formas de respuesta (stage)

   El movil ya ofrece ruleta, fichas, mosaico y ranking segun la pregunta; aqui
   se pintaba todo con la misma barra. Cuarenta pasos con el mismo grafico
   convierten la sesion en una hoja de calculo y la sala deja de mirar.

   Cada forma dice algo distinto: el ranking necesita ordinales porque el orden
   ES la respuesta; un inventario necesita superficie; una eleccion unica
   necesita una sola cosa grande, no siete barras de las que seis estan vacias. */

/* Las opciones son botones porque quien dirige puede pulsarlas desde la
   pantalla compartida. Sin permiso no son pulsables ni lo aparentan. */
.stage [data-opt] {
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: default;
}
.stage.can-host [data-opt] { cursor: pointer; }
.stage.can-host [data-opt]:hover { background-color: var(--accent-soft); }
.stage.can-host [data-opt]:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Lo que ha marcado quien dirige se distingue de lo que ha marcado la sala: en
   el acta no es lo mismo lo que alguien eligio que lo que Daniel recogio. */
.stage [data-opt].is-mine { box-shadow: inset 0 0 0 1.5px var(--accent); }

/* ---- rank: el orden es la respuesta ---- */
.podium { display: grid; gap: clamp(6px, .7vh, 12px); width: min(900px, 100%); margin-inline: auto; }
.podium-row {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: clamp(12px, 1.4vw, 22px);
  padding: clamp(8px, .9vh, 14px) clamp(14px, 1.4vw, 22px);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: opacity var(--base) var(--ease);
}
.podium-row u {
  font-family: var(--mono);
  font-size: clamp(13px, 1.5vw, 22px);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  color: var(--ink-3);
}
.podium-row b { font-size: clamp(15px, 1.5vw, 24px); font-weight: 400; letter-spacing: -.018em; }
.podium-row i {
  position: absolute;
  left: 0; bottom: 0;
  height: 2px;
  background: var(--accent-line);
  transition: width var(--slow) var(--ease);
}
.podium-row.lead u { color: var(--accent); }
.podium-row.lead b { font-weight: 600; }
.podium-row.zero { opacity: .35; }

/* ---- tokens: lo que la sala repite, crece ---- */
.token-cloud {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  gap: clamp(8px, 1vw, 16px);
  width: min(1000px, 100%);
  margin-inline: auto;
}
.token {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: clamp(7px, .8vh, 12px) clamp(13px, 1.3vw, 20px);
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: calc(clamp(15px, 1.5vw, 25px) * var(--w, 1));
  letter-spacing: -.02em;
  transition: font-size var(--slow) var(--ease), opacity var(--base) var(--ease);
}
.token b { font-weight: 400; }
.token span { font-family: var(--mono); font-size: .58em; color: var(--ink-3); }
.token.lead { box-shadow: inset 0 0 0 1.5px var(--accent-line); background: var(--accent-soft); }
.token.lead b { font-weight: 600; }
.token.zero { opacity: .4; }

/* ---- tiles: superficie, no longitud ---- */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: clamp(8px, 1vw, 14px);
  width: min(1000px, 100%);
  margin-inline: auto;
}
.tile {
  position: relative;
  display: grid;
  align-content: end;
  gap: 4px;
  min-height: clamp(84px, 13vh, 150px);
  padding: clamp(12px, 1.3vw, 18px);
  border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden;
  transition: opacity var(--base) var(--ease);
}
/* El relleno sube desde abajo: se ve llenarse, no saltar. */
.tile i {
  position: absolute;
  inset: auto 0 0 0;
  background: var(--accent-soft);
  transition: height var(--slow) var(--ease);
}
.tile b, .tile span { position: relative; }
.tile b { font-size: clamp(13px, 1.2vw, 18px); font-weight: 400; line-height: 1.25; letter-spacing: -.015em; }
.tile span { font-family: var(--mono); font-size: clamp(10px, .8vw, 13px); color: var(--ink-3); }
.tile.lead { box-shadow: inset 0 0 0 1.5px var(--accent-line); }
.tile.lead b { font-weight: 600; }
.tile.zero { opacity: .5; }

/* ---- reel: una sola eleccion ---- */
.reel-lead {
  display: grid;
  justify-items: center;
  gap: clamp(6px, .8vh, 12px);
  text-align: center;
  transition: opacity var(--base) var(--ease);
}
.reel-lead small {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.reel-lead b { font-size: clamp(30px, 4vw, 62px); font-weight: 600; letter-spacing: -.035em; line-height: 1.04; }
.reel-lead p { margin: 0; max-width: 40ch; font-size: clamp(13px, 1.1vw, 17px); color: var(--ink-2); }
.reel-lead.empty b { color: var(--ink-3); }
.reel-rest { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: clamp(14px, 2vh, 28px); }
.reel-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 15px;
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: clamp(12px, 1vw, 15px);
  color: var(--ink-2);
}
.reel-chip span { font-family: var(--mono); font-size: 10px; color: var(--ink-3); }

/* ---- dial: la posicion dice el orden ---- */
.dial-arc {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  width: min(980px, 100%);
  height: clamp(130px, 22vh, 210px);
  margin-inline: auto;
}
.dial-seg {
  position: absolute;
  top: 0;
  display: grid;
  justify-items: center;
  gap: 5px;
  width: clamp(88px, 11vw, 150px);
  text-align: center;
  /* Girado alrededor de un punto muy por debajo: los segmentos caen sobre un
     arco sin necesidad de calcular una posicion por cada uno. */
  transform-origin: 50% clamp(150px, 25vh, 240px);
  transform: rotate(var(--turn, 0deg));
  transition: opacity var(--base) var(--ease);
}
/* Solo la POSICION sigue el arco. Sin contrarrotar el contenido, las etiquetas
   salen tumbadas cada una en un angulo distinto y no hay quien las lea. */
.dial-seg > * { transform: rotate(calc(var(--turn, 0deg) * -1)); }
.dial-seg b { font-size: clamp(12px, 1.1vw, 17px); font-weight: 400; line-height: 1.2; letter-spacing: -.015em; }
.dial-seg span { font-family: var(--mono); font-size: clamp(10px, .8vw, 13px); color: var(--ink-3); }
.dial-seg::before {
  content: '';
  transform: rotate(calc(var(--turn, 0deg) * -1));
  width: clamp(8px, .9vw, 13px);
  height: clamp(8px, .9vw, 13px);
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--line-strong);
  margin-bottom: 4px;
}
.dial-seg.lead::before { background: var(--accent); box-shadow: none; }
.dial-seg.lead b { font-weight: 600; }
.dial-seg.zero { opacity: .45; }
.dial-label {
  margin: 0;
  text-align: center;
  font-size: clamp(22px, 2.6vw, 40px);
  font-weight: 600;
  letter-spacing: -.03em;
}


/* ------------------------------------------------------ compartir el acta

   Vive dentro del resumen, en la esquina: mientras nadie lo pulsa no compite
   con lo que la sala esta leyendo, que es el resumen. */
.share { position: absolute; right: 0; top: calc(-1 * clamp(34px, 4vh, 52px)); display: grid; justify-items: end; gap: 12px; }
.share-open {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 8px 15px;
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  font-size: clamp(12px, .95vw, 15px);
  color: var(--ink-2);
  transition: box-shadow var(--base), color var(--base), background var(--base);
}
.share-open:hover { color: var(--ink); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-line); }
.share-open i { font-style: normal; }
.share-open:disabled { opacity: .5; }
.share-body {
  display: grid;
  justify-items: center;
  gap: 12px;
  padding: clamp(16px, 2vw, 26px);
  border-radius: var(--r-lg);
  background: var(--paper);
  box-shadow: 0 0 0 1px var(--line), 0 20px 50px #00000014;
  animation: shareIn 420ms var(--ease) both;
}
@keyframes shareIn { from { opacity: 0; transform: translateY(-8px) scale(.98); } to { opacity: 1; transform: none; } }
.share-qr { width: clamp(150px, 20vh, 220px); aspect-ratio: 1; display: grid; place-items: center; }
.share-qr img { width: 100%; height: 100%; display: block; }
.share-link { margin: 0; font-family: var(--mono); font-size: 11px; letter-spacing: .04em; color: var(--ink-2); word-break: break-all; max-width: 26ch; text-align: center; }
.share-mails { display: flex; gap: 7px; }
.share-mails input {
  min-width: 0;
  width: clamp(150px, 16vw, 210px);
  padding: 9px 13px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-strong);
  background: var(--paper);
  font-size: 13px;
}
.share-note { margin: 0; max-width: 28ch; text-align: center; font-size: 11px; line-height: 1.45; color: var(--ink-3); }
.share-note:empty { display: none; }
/* El resumen necesita ser el ancla del panel, que va posicionado. */
.stage-main.is-moment .stage-view:has(.share) { position: relative; }


/* ------------------------------------------------- la escena del editor cabe

   Traia `height: calc(100dvh - 220px)`: un numero adivinado para descontar el
   cromo de arriba y abajo. Ese 220 solo es correcto en la pantalla donde se
   escribio; en cualquier otra proporcion la escena se sale por abajo y, como el
   stage es overflow:hidden, no genera scroll — se RECORTA, y desaparece justo la
   barra inferior del navegador de ejemplo, que es donde estan «En vivo»,
   «Guardado» y «Terminar».

   Asi que no se adivina: la celda del stage ya tiene la altura correcta y la
   escena ocupa lo que le den. */
.stage-main.is-moment .stage-view:has(.editor-scene) {
  flex: 1;
  min-height: 0;
  width: 100%;
  align-self: stretch;
  padding-bottom: 0;
}
/* Y el titular deja de empujar: en estos pasos la escena es el contenido. */
.stage-main.is-moment:has(.editor-scene) { gap: clamp(12px, 1.8vh, 26px); }
.stage-main.is-moment:has(.editor-scene) .stage-title { font-size: clamp(24px, 2.6vw, 40px); }
