/* meet-retro: estilos compartidos por todas las páginas (docs/PLAN-REDISENO-PALETA.md).
   Un solo archivo con URL fija: lo enlazan index.html, sidepanel.html y las páginas de
   public/marketplace/ con <link rel="stylesheet" href="/meet-retro.css">.

   Estructura: primero los tokens y la base compartida (sin acotar); después una sección por
   página, con todas sus reglas acotadas con :where(html[data-page="..."]). :where() no suma
   especificidad, así que la cascada de cada página es la misma que cuando el CSS vivía en
   su <style>. Cada <html> lleva su data-page; el JS de la app no toca ese atributo. */

:root {
  /* Paleta neo-retro: Resurrect 64, de Kerrie Lake (lospec.com/palette-list/resurrect-64),
     la más descargada por la comunidad de pixel art. Capa 1: solo los colores que se usan,
     con su valor original; cada hex aparece una única vez en todo el proyecto. Los roles de
     la capa 2 los referencian con var(). Decisión: docs/DECISIONES.md (ADR-016). */
  --r64-plum: #2e222f;
  --r64-wine: #45293f;
  --r64-mauve: #694f62;
  --r64-grape: #625565;
  --r64-mint: #c7dcd0;
  --r64-steel: #9babb2;
  --r64-orange: #f57d4a;
  --r64-brick: #6e2727;
  --r64-peach: #fdcbb0;
  --r64-teal: #0eaf9b;
  --r64-salmon: #f68181;
  --r64-lime: #91db69;
  --r64-yellow: #f9c22b;
  --r64-olive: #a2a947;
  --r64-violet: #a884f3;

  /* Capa 2: roles de Material (mismos nombres que antes, para no tocar el resto del CSS).
     Un esquema fijo de pocos colores, no generado: outline comparte color con el texto
     secundario, y surface-container-high no admite texto secundario (3.1:1). */
  --m3-primary: var(--r64-orange);
  --m3-on-primary: var(--r64-plum);
  --m3-primary-container: var(--r64-brick);
  --m3-on-primary-container: var(--r64-peach);
  --m3-tertiary: var(--r64-teal);
  --m3-error: var(--r64-salmon);
  --m3-surface: var(--r64-plum);
  --m3-on-surface: var(--r64-mint);
  --m3-on-surface-variant: var(--r64-steel);
  --m3-surface-container: var(--r64-wine);
  --m3-surface-container-high: var(--r64-mauve);
  --m3-outline: var(--r64-steel);
  --m3-outline-variant: var(--r64-grape);
  /* Única derivación: el oscuro más profundo (letterbox, mockups). La paleta no tiene uno. */
  --m3-surface-lowest: color-mix(in srgb, var(--m3-surface) 55%, #000);

  /* Estados de conexión: colores propios, ya no prestan tertiary ni un verde fijo. */
  --status-good: var(--r64-lime);
  --status-warn: var(--r64-yellow);
  --status-bad: var(--m3-error);

  /* Familia de cuatro: un color por asiento. Se usan como relleno con texto surface. */
  --seat-1: var(--r64-orange);
  --seat-2: var(--r64-olive);
  --seat-3: var(--r64-teal);
  --seat-4: var(--r64-violet);

  /* Wordmark («meet» y «-retro») y eslogan («Únete.» «Listo.» «¡A jugar!»): un color por palabra. */
  --wm-meet: var(--r64-teal);
  --wm-retro: var(--r64-orange);
  --tg-1: var(--r64-teal);
  --tg-2: var(--r64-olive);
  --tg-3: var(--r64-orange);

  /* Pasos de «Cómo funciona» en la landing: el 1 y el 2 con los colores de «Únete.» y «Listo.»,
     el 3 con el del asiento 4 y el 4 con el de «¡A jugar!». */
  --step-1: var(--tg-1);
  --step-2: var(--tg-2);
  --step-3: var(--seat-4);
  --step-4: var(--tg-3);

  /* Recuadros de «Para lo que sea que se hayan juntado»: tres acentos que se alternan
     (naranja, amarillo, verde azulado). No usan oliva ni violeta, para no parecer asientos. */
  --oc-1: var(--r64-orange);
  --oc-2: var(--r64-yellow);
  --oc-3: var(--r64-teal);

  /* Hover de botones y enlaces de la landing. */
  --lp-hover: var(--r64-yellow);
}

/* Contorno de sprite NES (texto claro + borde oscuro): solo display/headline,
   técnica real de legibilidad de sprites, docs/CONCEPTO-DISENO.md. */
.font-display {
  font-family: "Press Start 2P", monospace;
}
.sprite-outline {
  text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
}

/* Wordmark y eslogan: cada palabra con su color de la familia. */
.wm-meet { color: var(--wm-meet); }
.wm-retro { color: var(--wm-retro); }
.tg-1 { color: var(--tg-1); }
.tg-2 { color: var(--tg-2); }
.tg-3 { color: var(--tg-3); }

/* Etiqueta de asiento (panel lateral y su mock en la landing): relleno con el color del asiento. */
.seat-tag[data-seat="1"] { background: var(--seat-1); color: var(--m3-surface); }
.seat-tag[data-seat="2"] { background: var(--seat-2); color: var(--m3-surface); }
.seat-tag[data-seat="3"] { background: var(--seat-3); color: var(--m3-surface); }
.seat-tag[data-seat="4"] { background: var(--seat-4); color: var(--m3-surface); }

/* Dithering como técnica de elevación (en vez de sombra o degradado de Material):
   el NES usaba dithering real para simular más colores de los que podía mostrar. */
.dither {
  position: relative;
}

/* ==========================================================================
   Página: escenario (index.html)
   Reglas acotadas con :where(html[data-page="stage"]): no suman especificidad.
   ========================================================================== */

:where(html[data-page="stage"]) body {
  margin: 0;
  font-family: "Roboto", system-ui, -apple-system, sans-serif;
  background: var(--m3-surface);
  color: var(--m3-on-surface);
}
:where(html[data-page="stage"]) .dither::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 2px);
  pointer-events: none;
  border-radius: inherit;
}
:where(html[data-page="stage"]) #stage {
  position: relative;
  width: fit-content;
  margin: 0 auto;
}
/* #screen (el <canvas> del juego) — el motivo de no reasignar su
   estilo por CSS (Etapa 3, H1, 2026-09-02) era que Nostalgist/
   Emscripten le reasignaba el id a "canvas" al arrancar, rompiendo
   cualquier selector por id. Con tetanes-core eso ya no pasa —
   TetanesEmulator nunca toca canvas.id — pero el tamaño lo sigue
   poniendo `applyCanvasSize()` en main.ts vía `style` inline igual.
   El <video id="remoteVideo"> que antes recibía el stream del host
   (Etapa 1) se retiró en Etapa 2, H2, Tarea 4 (docs/PLAN-ETAPA-2.md)
   — mesh, cada par renderiza su propio canvas local. */
/* Carrusel de selección de juego (Etapa 3, H2) — pantalla previa al
   arranque, visible para todos por igual mientras nadie eligió: elegir
   una card es lo que reclama el rol de host, no al revés (ver
   docs/PLAN-ETAPA-3.md). Vive DENTRO de #stage, no en un div aparte
   (#controls, retirado 2026-09-02) — mismo motivo que el canvas en
   H1: si no ocupa espacio real dentro de #stage, #stage colapsa a
   tamaño cero (nada más lo agranda mientras el juego no arrancó) y
   cualquier otro elemento posicionado absoluto contra #stage (como
   #touchpad, más abajo) termina anclado arriba de un cuadro de 0×0 en
   vez de esta pantalla — lo que se vio en vivo como el carrusel y el
   roster (retirado, Etapa 3 H5) superpuestos en la esquina. Con un
   tamaño propio en vw/vh (no depende del contenido, como el canvas
   necesita `applyCanvasSize()` en JS — acá alcanza con CSS porque no
   hay nada tipo Nostalgist congelando el style), #stage hereda ese
   tamaño vía fit-content y todo lo demás cae en su lugar real. */
:where(html[data-page="stage"]) #gameSelect {
  display: none;
  position: relative;
  width: 94vw;
  height: 90vh;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(24px, 4vh, 40px);
  box-sizing: border-box;
}
:where(html[data-page="stage"]) #gameSelectLabel {
  position: absolute;
  top: 4px;
  left: 4px;
  font-size: 11px;
  letter-spacing: 0.05em;
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="stage"]) #gameCards {
  display: flex;
  gap: clamp(16px, 3vw, 56px);
  flex-wrap: nowrap;
  justify-content: center;
  width: 100%;
}
:where(html[data-page="stage"]) .game-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  flex: 1 1 0;
  min-width: 0;
  max-width: 320px;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
:where(html[data-page="stage"]) .game-card-art {
  width: 100%;
  aspect-ratio: 256 / 240;
  background: var(--m3-surface-container);
  border: 1.5px solid var(--m3-outline-variant);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(13px, 1.6vw, 18px);
  color: var(--m3-on-surface-variant);
  text-align: center;
  padding: 0 8px;
  box-sizing: border-box;
  overflow: hidden;
}
:where(html[data-page="stage"]) .game-card-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  image-rendering: pixelated;
}
:where(html[data-page="stage"]) .game-card:hover .game-card-art,
:where(html[data-page="stage"]) .game-card:focus-visible .game-card-art {
  border-color: var(--m3-primary);
  box-shadow: 0 0 20px 2px color-mix(in srgb, var(--m3-primary) 30%, transparent);
}
:where(html[data-page="stage"]) .game-card-name {
  font-size: clamp(10px, 1vw, 13px);
  line-height: 1.5;
}
:where(html[data-page="stage"]) .game-card-description {
  font-size: clamp(9px, 0.85vw, 11px);
  line-height: 1.4;
  color: var(--m3-on-surface-variant);
  text-align: center;
  margin-top: -6px;
}
:where(html[data-page="stage"]) #gameSelectNote {
  font-size: 12px;
  color: var(--m3-on-surface-variant);
  text-align: center;
  max-width: 480px;
  line-height: 1.5;
}
/* Overlay de controles táctiles (H7, ver docs/DECISIONES.md — diseño
   2026-08-29). Ancla por esquinas de #stage, no por coordenadas
   absolutas de pantalla — se adapta solo sin importar el tamaño real
   del canvas. Pensado para horizontal en celular: el juego (casi
   cuadrado, 256x240) queda "pillarboxed" con franjas vacías a los
   costados al ajustarse por altura — los controles viven ahí, no
   encima de la imagen. */
:where(html[data-page="stage"]) #touchpad {
  display: none;
  position: absolute;
  inset: 0;
  pointer-events: none;
  touch-action: none;
  user-select: none;
}
:where(html[data-page="stage"]) .touch-btn {
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--m3-surface-container);
  border: 1.5px solid var(--m3-outline-variant);
  color: var(--m3-on-surface);
  font: inherit;
  font-weight: 700;
}
/* .pressed replica el mismo estado que :active nativo, pero disparado
   desde JS por keydown/keyup (main.ts) -- :active por sí solo solo
   reacciona al puntero, nunca al teclado. */
:where(html[data-page="stage"]) .touch-btn:active,
:where(html[data-page="stage"]) .touch-btn.pressed {
  background: var(--m3-primary-container);
  border-color: var(--m3-primary);
  box-shadow: 0 0 10px 1px color-mix(in srgb, var(--m3-primary) 40%, transparent);
}
/* Keycap chico con la tecla real (Etapa 3, H3, 2026-09-02) — mismo
   diseño ya aprobado en el mockup (Main.dc.html). */
:where(html[data-page="stage"]) .keycap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 4px;
  border-radius: 4px;
  border: 1px solid var(--m3-outline-variant);
  background: var(--m3-surface);
  color: var(--m3-on-surface-variant);
  font-size: 10px;
  font-weight: 700;
  pointer-events: none;
}
/* D-pad y A/B: position: fixed, no absolute (Etapa 3, H3) — con
   #stage ajustado a fit-content del canvas (H1), ya no sobra nada
   DENTRO de #stage para anclarlos; las franjas negras libres existen
   recién afuera, contra el viewport real. Select/Start sí se quedan
   absolute contra #stage/#touchpad — no hay margen arriba/abajo del
   canvas para moverlos, se quedan superpuestos a la imagen como
   siempre. */
:where(html[data-page="stage"]) #dpad {
  position: fixed;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  grid-template-columns: repeat(3, 44px);
  grid-template-rows: repeat(3, 44px);
}
:where(html[data-page="stage"]) #dpad .touch-btn[data-button="up"] { grid-column: 2; grid-row: 1; border-radius: 6px 6px 0 0; }
:where(html[data-page="stage"]) #dpad .touch-btn[data-button="left"] { grid-column: 1; grid-row: 2; border-radius: 6px 0 0 6px; }
:where(html[data-page="stage"]) #dpad .hub { grid-column: 2; grid-row: 2; background: var(--m3-surface-container-high); border: 1.5px solid var(--m3-outline); }
:where(html[data-page="stage"]) #dpad .touch-btn[data-button="right"] { grid-column: 3; grid-row: 2; border-radius: 0 6px 6px 0; }
:where(html[data-page="stage"]) #dpad .touch-btn[data-button="down"] { grid-column: 2; grid-row: 3; border-radius: 0 0 6px 6px; }
:where(html[data-page="stage"]) #dpadCaption {
  position: fixed;
  left: 16px;
  top: calc(50% + 78px);
  width: 132px;
  text-align: center;
  font-size: 10px;
  color: var(--m3-on-surface-variant);
  pointer-events: none;
}
:where(html[data-page="stage"]) #ab {
  position: fixed;
  right: 20px;
  top: 50%;
  transform: translateY(-50%);
  width: 116px;
  height: 118px;
}
:where(html[data-page="stage"]) .ab-slot {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}
:where(html[data-page="stage"]) .ab-slot.ab-a { right: 0; top: 0; }
:where(html[data-page="stage"]) .ab-slot.ab-b { left: 0; bottom: 0; }
:where(html[data-page="stage"]) #ab .touch-btn[data-button="a"] {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  font-size: 19px;
  background: var(--m3-primary-container);
  border-color: var(--m3-primary);
}
/* El botón A ya lleva el color primary en reposo (a propósito, lo
   marca como "el" botón) -- el brillo compartido de .pressed/:active
   no se nota encima de un fondo que ya es casi ese mismo color
   (reportado en vivo, 2026-09-05). Acá se invierte la dirección:
   en vez de "más color", pasa a oscuro/negro -- mismo criterio que
   pidió el usuario ("los demás pasan de negro a color, A debería
   pasar de color a negro"). Necesita más especificidad que la regla
   de arriba para ganarle (mismo motivo por el que el brillo
   compartido nunca se veía). */
:where(html[data-page="stage"]) #ab .touch-btn[data-button="a"]:active,
:where(html[data-page="stage"]) #ab .touch-btn[data-button="a"].pressed {
  background: var(--m3-surface-lowest);
  border-color: var(--m3-outline);
  box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.5);
}
:where(html[data-page="stage"]) #ab .touch-btn[data-button="b"] {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  font-size: 18px;
}
:where(html[data-page="stage"]) #selectStart {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  display: flex;
  gap: 14px;
}
:where(html[data-page="stage"]) .ss-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}
:where(html[data-page="stage"]) #selectStart .touch-btn {
  width: 64px;
  height: 32px;
  border-radius: 16px;
  background: color-mix(in srgb, var(--m3-surface-container) 85%, transparent);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.06em;
}
/* Etapa 3, H4 (docs/PLAN-ETAPA-3.md) — respaldo de identidad acá en
   el main stage. Encontrado en vivo, 2026-09-06: quien se une a una
   actividad ya en curso nunca llega a ver la pantalla de identidad
   del side panel — Meet enfoca el main stage y cierra/cambia el side
   panel casi de inmediato, antes de que haya chance de elegir nada
   ahí. Este overlay es el respaldo: se muestra acá mismo si el
   roster vuelve con el propio nombre en null, mismo criterio que la
   pantalla del side panel (Google o invitado). A diferencia del side
   panel, acá SÍ hay conexión directa al worker (el WebSocket que ya
   tiene main.ts) — no hace falta el handshake de frameToFrameMessage. */
:where(html[data-page="stage"]) #nameGate {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  z-index: 10000;
  align-items: center;
  justify-content: center;
}
:where(html[data-page="stage"]) #nameGateCard {
  width: 300px;
  background: var(--m3-surface-container);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 12px;
  padding: 24px 20px;
  box-sizing: border-box;
}
:where(html[data-page="stage"]) #nameGateLabel {
  font-size: 12px;
  line-height: 1.7;
  margin-bottom: 6px;
}
:where(html[data-page="stage"]) #nameGateSub {
  font-size: 12px;
  color: var(--m3-on-surface-variant);
  margin: 0 0 20px 0;
  line-height: 1.4;
}
:where(html[data-page="stage"]) #nameGateGsi {
  margin-bottom: 16px;
}
:where(html[data-page="stage"]) #nameGateDivider {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  color: var(--m3-on-surface-variant);
  margin-bottom: 16px;
}
:where(html[data-page="stage"]) #nameGateDivider::before,
:where(html[data-page="stage"]) #nameGateDivider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--m3-outline-variant);
}
:where(html[data-page="stage"]) #nameGateInput {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--m3-outline);
  font-size: 14px;
  font-family: inherit;
  background: var(--m3-surface);
  color: var(--m3-on-surface);
  margin-bottom: 10px;
}
:where(html[data-page="stage"]) #nameGateContinue {
  width: 100%;
  padding: 12px 0;
  border-radius: 8px;
  border: 1px solid var(--m3-outline);
  font-size: 14px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  background: transparent;
  color: var(--m3-on-surface);
}
/* Etapa 3, H5, Tarea 4 (docs/PLAN-ETAPA-3.md) — "pausar" difundido a
   todos (game-pause/game-resume, ver main.ts). Sin esto, un pause()
   real no tiene ninguna señal visible más que la pantalla congelada
   — indistinguible de que algo se colgó. */
:where(html[data-page="stage"]) #pauseOverlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 9000;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--m3-on-surface);
  pointer-events: none;
}

/* ==========================================================================
   Página: panel lateral (sidepanel.html)
   Reglas acotadas con :where(html[data-page="sidepanel"]): no suman especificidad.
   ========================================================================== */

:where(html[data-page="sidepanel"]) body {
  margin: 0;
  padding: 24px 20px;
  box-sizing: border-box;
  font-family: "Roboto", system-ui, -apple-system, sans-serif;
  background: var(--m3-surface);
  color: var(--m3-on-surface);
}
:where(html[data-page="sidepanel"]) .dither::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.035) 0 1px, transparent 1px 2px);
  pointer-events: none;
  border-radius: inherit;
}
:where(html[data-page="sidepanel"]) #wordmark {
  font-size: 13px;
  line-height: 1.6;
  margin-bottom: 4px;
}
:where(html[data-page="sidepanel"]) #tagline {
  font-size: 8px;
  color: var(--m3-tertiary);
  letter-spacing: 0.03em;
  margin-bottom: 32px;
}
/* Etapa 3, H4 (docs/PLAN-ETAPA-3.md) — pantalla de identidad: primer
   paso del side panel, para host y guest por igual, antes de
   cualquier otra acción. Reemplaza el bloque de prueba temporal
   (#gsiTest, 2026-09-02) — el mecanismo de Google Sign-In ya se
   había probado en vivo ahí; acá queda integrado de verdad. */
:where(html[data-page="sidepanel"]) #identityLabel {
  font-size: 12px;
  line-height: 1.7;
  margin-bottom: 6px;
}
:where(html[data-page="sidepanel"]) #identitySub {
  font-size: 12px;
  color: var(--m3-on-surface-variant);
  margin-bottom: 20px;
  line-height: 1.4;
}
:where(html[data-page="sidepanel"]) #gsiButton {
  margin-bottom: 16px;
}
:where(html[data-page="sidepanel"]) #identityDivider {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  color: var(--m3-on-surface-variant);
  margin-bottom: 16px;
}
:where(html[data-page="sidepanel"]) #identityDivider::before,
:where(html[data-page="sidepanel"]) #identityDivider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--m3-outline-variant);
}
:where(html[data-page="sidepanel"]) #guestName {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--m3-outline);
  font-size: 14px;
  font-family: inherit;
  background: var(--m3-surface-container);
  color: var(--m3-on-surface);
  margin-bottom: 10px;
}
:where(html[data-page="sidepanel"]) #guestName::placeholder {
  color: var(--m3-on-surface-variant);
}
/* Outlined — es una vía alternativa a Google, no LA acción
   principal de la pantalla. */
:where(html[data-page="sidepanel"]) #guestContinue {
  width: 100%;
  padding: 12px 0;
  border-radius: 8px;
  border: 1px solid var(--m3-outline);
  font-size: 14px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  background: transparent;
  color: var(--m3-on-surface);
}
:where(html[data-page="sidepanel"]) #statusCard {
  background: var(--m3-surface-container);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 12px;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
  position: relative;
  overflow: hidden;
}
:where(html[data-page="sidepanel"]) #statusDot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: color-mix(in srgb, var(--m3-on-surface) 35%, transparent);
}
:where(html[data-page="sidepanel"]) #statusDot[data-state="ready"] {
  background: var(--status-good);
  box-shadow: 0 0 6px 1px color-mix(in srgb, var(--status-good) 60%, transparent);
}
:where(html[data-page="sidepanel"]) #statusDot[data-state="error"] {
  background: var(--m3-error);
  box-shadow: 0 0 6px 1px color-mix(in srgb, var(--m3-error) 50%, transparent);
}
:where(html[data-page="sidepanel"]) #status {
  font-size: 13px;
  line-height: 1.4;
  margin: 0;
}
/* "Iniciar actividad" — botón filled de Material: acción principal
   de la pantalla, único con relleno primary. */
:where(html[data-page="sidepanel"]) #start {
  width: 100%;
  padding: 12px 0;
  border-radius: 8px;
  border: none;
  font-size: 14px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  background: var(--m3-primary);
  color: var(--m3-on-primary);
}
:where(html[data-page="sidepanel"]) #start:disabled {
  cursor: not-allowed;
  background: var(--m3-surface-container);
  color: var(--m3-on-surface-variant);
  opacity: 0.6;
}
/* Etapa 3, H5, Tarea 2 (docs/PLAN-ETAPA-3.md) — roster/conexión en
   vivo, reemplaza al overlay del main stage retirado en la Tarea 1.
   Mismo estilo de card que ya se probó en el canvas de Claude Design
   (SidePanel.dc.html). */
:where(html[data-page="sidepanel"]) #liveView {
  display: none;
  flex-direction: column;
  gap: 16px;
}
:where(html[data-page="sidepanel"]) .card {
  background: var(--m3-surface-container);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 12px;
  padding: 12px 14px;
  position: relative;
  overflow: hidden;
}
:where(html[data-page="sidepanel"]) .card-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--m3-on-surface-variant);
  text-transform: uppercase;
  margin: 0 0 10px 0;
}
:where(html[data-page="sidepanel"]) .roster-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
  padding: 5px 0;
  gap: 8px;
}
:where(html[data-page="sidepanel"]) .roster-row-label {
  display: flex;
  align-items: center;
  min-width: 0;
}
:where(html[data-page="sidepanel"]) .roster-row-label span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:where(html[data-page="sidepanel"]) .seat-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 4px;
  background: var(--m3-surface);
  font-size: 10px;
  font-weight: 700;
  color: var(--m3-on-surface-variant);
  margin-right: 8px;
  flex-shrink: 0;
}
/* "reclamar"/"soltar" — outlined, acción secundaria dentro de la card. */
:where(html[data-page="sidepanel"]) .roster-row button {
  font: inherit;
  font-size: 11px;
  padding: 3px 10px;
  border-radius: 8px;
  border: 1px solid var(--m3-primary);
  background: transparent;
  color: var(--m3-primary);
  cursor: pointer;
  flex-shrink: 0;
}
:where(html[data-page="sidepanel"]) #spectatorsRow {
  font-size: 12px;
  color: var(--m3-on-surface-variant);
  border-top: 1px solid var(--m3-outline-variant);
  margin-top: 8px;
  padding-top: 8px;
}
:where(html[data-page="sidepanel"]) #connectionRow {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}
:where(html[data-page="sidepanel"]) #connectionDot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}
:where(html[data-page="sidepanel"]) #connectionPing {
  font-size: 12px;
  color: var(--m3-on-surface-variant);
  margin-left: auto;
}
/* Etapa 3, H5, Tarea 4 (docs/PLAN-ETAPA-3.md) — "cambiar de juego"
   y "pausar", solo para quien es host ahora mismo (el rol dura lo
   que dura el juego que esa persona abrió, no es fijo — ver
   Análisis en PLAN-ETAPA-3.md). Oculta por completo para quien no
   lo es, gate en JS (renderRoster()), no CSS. */
:where(html[data-page="sidepanel"]) #hostButtons {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
:where(html[data-page="sidepanel"]) .host-btn {
  width: 100%;
  padding: 10px 0;
  border-radius: 8px;
  border: 1px solid var(--m3-outline);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  background: transparent;
  color: var(--m3-on-surface);
  box-sizing: border-box;
}
:where(html[data-page="sidepanel"]) #changeGame {
  border-color: var(--m3-error);
  color: var(--m3-error);
}

/* ==========================================================================
   Página: prueba del emulador (tetanes-emulator-test.html)
   Reglas acotadas con :where(html[data-page="emutest"]): no suman especificidad.
   ========================================================================== */

:where(html[data-page="emutest"]) body {
  margin: 0;
  font-family: system-ui, sans-serif;
  background: #111;
  color: #eee;
}
:where(html[data-page="emutest"]) canvas {
  display: block;
  margin: 8px auto;
  width: 512px;
  height: 480px;
  background: #000;
}
:where(html[data-page="emutest"]) p {
  text-align: center;
}

/* ==========================================================================
   Página: asistencia (public/marketplace/support.html)
   Reglas acotadas con :where(html[data-page="info-support"]): no suman especificidad.
   ========================================================================== */

:where(html[data-page="info-support"]) body { font-family: Roboto, system-ui, sans-serif; max-width: 640px; margin: 3rem auto; padding: 0 1rem 3rem; line-height: 1.6; background: var(--m3-surface); color: var(--m3-on-surface); }
:where(html[data-page="info-support"]) a { color: var(--m3-primary); }
:where(html[data-page="info-support"]) header { display: flex; align-items: center; gap: 12px; margin-bottom: 2rem; padding-bottom: 1.5rem; border-bottom: 1px solid var(--m3-outline-variant); }
:where(html[data-page="info-support"]) header img.icon { width: 40px; height: 40px; image-rendering: pixelated; }
:where(html[data-page="info-support"]) .wordmark { font-family: "Press Start 2P", monospace; font-size: 14px; color: var(--wm-meet); }
:where(html[data-page="info-support"]) .wordmark span { color: var(--wm-retro); }
:where(html[data-page="info-support"]) h1 { font-size: 1.3rem; margin: 0.15rem 0 0; font-weight: 500; color: var(--m3-on-surface); }
:where(html[data-page="info-support"]) p { color: var(--m3-on-surface-variant); }
:where(html[data-page="info-support"]) .banner { display: block; max-width: 220px; height: auto; border-radius: 10px; border: 1.5px solid var(--m3-outline-variant); margin: 0 0 1.5rem; }
:where(html[data-page="info-support"]) footer { margin-top: 3rem; width: 100vw; position: relative; left: 50%; margin-left: -50vw; border-top: 1px solid var(--m3-outline-variant); box-sizing: border-box; }
:where(html[data-page="info-support"]) .footer-top { max-width: 1440px; margin: 0 auto; padding: 32px 24px; box-sizing: border-box; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px; }
:where(html[data-page="info-support"]) .footer-link { font-size: 14px; color: var(--m3-on-surface-variant); text-decoration: none; }
:where(html[data-page="info-support"]) .footer-link:hover { color: var(--m3-primary); }

/* ==========================================================================
   Página: privacidad (public/marketplace/privacy.html)
   Reglas acotadas con :where(html[data-page="info-privacy"]): no suman especificidad.
   ========================================================================== */

:where(html[data-page="info-privacy"]) body { font-family: Roboto, system-ui, sans-serif; max-width: 640px; margin: 3rem auto; padding: 0 1rem 3rem; line-height: 1.6; background: var(--m3-surface); color: var(--m3-on-surface); }
:where(html[data-page="info-privacy"]) a { color: var(--m3-primary); }
:where(html[data-page="info-privacy"]) header { display: flex; align-items: center; gap: 12px; margin-bottom: 2rem; padding-bottom: 1.5rem; border-bottom: 1px solid var(--m3-outline-variant); }
:where(html[data-page="info-privacy"]) header img.icon { width: 40px; height: 40px; image-rendering: pixelated; }
:where(html[data-page="info-privacy"]) .wordmark { font-family: "Press Start 2P", monospace; font-size: 14px; color: var(--wm-meet); }
:where(html[data-page="info-privacy"]) .wordmark span { color: var(--wm-retro); }
:where(html[data-page="info-privacy"]) h1 { font-size: 1.3rem; margin: 0.15rem 0 0; font-weight: 500; color: var(--m3-on-surface); }
:where(html[data-page="info-privacy"]) h2 { font-size: 1.05rem; margin-top: 2rem; color: var(--m3-on-surface); }
:where(html[data-page="info-privacy"]) p,
:where(html[data-page="info-privacy"]) li { color: var(--m3-on-surface-variant); }
:where(html[data-page="info-privacy"]) small { color: var(--m3-on-surface-variant); opacity: 0.7; }
:where(html[data-page="info-privacy"]) footer { margin-top: 3rem; width: 100vw; position: relative; left: 50%; margin-left: -50vw; border-top: 1px solid var(--m3-outline-variant); box-sizing: border-box; }
:where(html[data-page="info-privacy"]) .footer-top { max-width: 1440px; margin: 0 auto; padding: 32px 24px; box-sizing: border-box; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px; }
:where(html[data-page="info-privacy"]) .footer-link { font-size: 14px; color: var(--m3-on-surface-variant); text-decoration: none; }
:where(html[data-page="info-privacy"]) .footer-link:hover { color: var(--m3-primary); }

/* ==========================================================================
   Página: términos (public/marketplace/terms.html)
   Reglas acotadas con :where(html[data-page="info-terms"]): no suman especificidad.
   ========================================================================== */

:where(html[data-page="info-terms"]) body { font-family: Roboto, system-ui, sans-serif; max-width: 640px; margin: 3rem auto; padding: 0 1rem 3rem; line-height: 1.6; background: var(--m3-surface); color: var(--m3-on-surface); }
:where(html[data-page="info-terms"]) a { color: var(--m3-primary); }
:where(html[data-page="info-terms"]) header { display: flex; align-items: center; gap: 12px; margin-bottom: 2rem; padding-bottom: 1.5rem; border-bottom: 1px solid var(--m3-outline-variant); }
:where(html[data-page="info-terms"]) header img.icon { width: 40px; height: 40px; image-rendering: pixelated; }
:where(html[data-page="info-terms"]) .wordmark { font-family: "Press Start 2P", monospace; font-size: 14px; color: var(--wm-meet); }
:where(html[data-page="info-terms"]) .wordmark span { color: var(--wm-retro); }
:where(html[data-page="info-terms"]) h1 { font-size: 1.3rem; margin: 0.15rem 0 0; font-weight: 500; color: var(--m3-on-surface); }
:where(html[data-page="info-terms"]) p,
:where(html[data-page="info-terms"]) li { color: var(--m3-on-surface-variant); }
:where(html[data-page="info-terms"]) small { color: var(--m3-on-surface-variant); opacity: 0.7; }
:where(html[data-page="info-terms"]) footer { margin-top: 3rem; width: 100vw; position: relative; left: 50%; margin-left: -50vw; border-top: 1px solid var(--m3-outline-variant); box-sizing: border-box; }
:where(html[data-page="info-terms"]) .footer-top { max-width: 1440px; margin: 0 auto; padding: 32px 24px; box-sizing: border-box; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px; }
:where(html[data-page="info-terms"]) .footer-link { font-size: 14px; color: var(--m3-on-surface-variant); text-decoration: none; }
:where(html[data-page="info-terms"]) .footer-link:hover { color: var(--m3-primary); }

/* ==========================================================================
   Landing (la que se ve en meet-retro.com fuera de Meet: app/src/landing.ts)
   Reglas acotadas con :where(html[data-page="stage"]), como las del escenario, porque
   la landing se monta dentro de index.html. Solo var(--…): ningún hex.
   Plan: docs/PLAN-REDISENO-LANDING.md
   ========================================================================== */

:where(html[data-page="stage"]) .lp {
  width: 100%;
  min-height: 100vh;
  font-size: 17px;
  line-height: 1.55;
  overflow-x: clip; /* clip, no hidden: hidden rompería el position: sticky de la cabecera */
}
:where(html[data-page="stage"]) .lp-anchor {
  scroll-margin-top: 84px;
}
:where(html[data-page="stage"]) .lp-muted {
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="stage"]) .lp-h2 {
  font-weight: 400;
  font-size: clamp(20px, 2.6vw, 30px);
  line-height: 1.4;
  margin: 0;
  text-wrap: balance;
}
:where(html[data-page="stage"]) .lp-p {
  margin: 0;
  font-size: 18px;
  text-wrap: pretty;
}
:where(html[data-page="stage"]) .lp-col {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
:where(html[data-page="stage"]) .lp-section {
  max-width: 1200px;
  margin: 0 auto;
  padding: 72px 24px;
  box-sizing: border-box;
}
:where(html[data-page="stage"]) .lp-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr));
  gap: 56px;
  align-items: center;
}

/* Botones y enlaces */
:where(html[data-page="stage"]) .lp-btn {
  display: inline-block;
  text-decoration: none;
  font-weight: 700;
  border-radius: 999px;
  padding: 10px 22px;
  background: var(--m3-primary);
  color: var(--m3-on-primary);
}
:where(html[data-page="stage"]) .lp-btn:hover {
  background: var(--lp-hover);
}
:where(html[data-page="stage"]) .lp-btn-secondary {
  background: var(--m3-surface-container);
  color: var(--m3-on-surface);
}
:where(html[data-page="stage"]) .lp-btn-secondary:hover {
  background: var(--m3-surface-container-high);
  color: var(--m3-on-surface);
}
:where(html[data-page="stage"]) .lp-btn-lg {
  padding: 16px 30px;
  font-size: 18px;
}
:where(html[data-page="stage"]) .lp-link {
  color: var(--m3-primary);
  text-underline-offset: 3px;
}
:where(html[data-page="stage"]) .lp-link:hover {
  color: var(--lp-hover);
}

/* Tramado (dithering) como transición entre superficies y como elevación */
:where(html[data-page="stage"]) .lp-strip {
  height: 4px;
  background: repeating-conic-gradient(var(--a) 0 25%, var(--b) 0 50%) 0 0 / 4px 4px;
}
:where(html[data-page="stage"]) .lp-strip-down {
  --a: var(--m3-surface-container);
  --b: var(--m3-surface);
}
:where(html[data-page="stage"]) .lp-strip-up {
  --a: var(--m3-surface);
  --b: var(--m3-surface-container);
}
:where(html[data-page="stage"]) .lp-dframe {
  background: repeating-conic-gradient(var(--m3-surface-container-high) 0 25%, transparent 0 50%) 0 0 / 4px 4px;
  padding: 0 8px 8px 0;
  text-align: left;
}

/* Cabecera fija */
:where(html[data-page="stage"]) .lp-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--m3-surface-container);
}
:where(html[data-page="stage"]) .lp-header-in {
  max-width: 1200px;
  margin: 0 auto;
  padding: 12px 24px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
:where(html[data-page="stage"]) .lp-brand {
  display: flex;
  align-items: center;
  gap: 12px;
}
:where(html[data-page="stage"]) .lp-brand img {
  width: 36px;
  height: 36px;
  image-rendering: pixelated;
}
:where(html[data-page="stage"]) .lp-brand-name {
  font-size: 14px;
}
:where(html[data-page="stage"]) .lp-nav {
  display: flex;
  gap: 4px;
  align-items: center;
  flex-wrap: wrap;
}
:where(html[data-page="stage"]) .lp-navlink {
  color: var(--m3-on-surface);
  text-decoration: none;
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 500;
}
:where(html[data-page="stage"]) .lp-navlink:hover {
  background: var(--m3-surface-container-high);
}
:where(html[data-page="stage"]) .lp-nav .lp-btn {
  margin-left: 8px;
}

/* Hero */
:where(html[data-page="stage"]) .lp-hero {
  max-width: 1200px;
  margin: 0 auto;
  padding: 88px 24px 72px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 28px;
}
:where(html[data-page="stage"]) .lp-badge {
  font-size: 14px;
  font-weight: 500;
  color: var(--m3-on-surface-variant);
  background: var(--m3-surface-container);
  padding: 6px 14px;
  border-radius: 8px;
}
:where(html[data-page="stage"]) .lp-h1 {
  font-weight: 400;
  font-size: clamp(28px, 5.6vw, 68px);
  line-height: 1.25;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 0.5em;
}
:where(html[data-page="stage"]) .lp-lead {
  margin: 0;
  font-size: 19px;
  max-width: 34em;
  text-wrap: pretty;
}
:where(html[data-page="stage"]) .lp-cta-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}
:where(html[data-page="stage"]) .lp-note {
  margin: 0;
  font-size: 13px;
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="stage"]) .lp-frame-wrap {
  width: 100%;
  max-width: 800px;
  margin-top: 40px;
  box-sizing: border-box;
  border-radius: 24px;
}
:where(html[data-page="stage"]) .lp-frame {
  background: var(--m3-surface-container);
  border-radius: 20px;
  padding: 16px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 210px;
  gap: 14px;
}
:where(html[data-page="stage"]) .lp-stage-mock {
  min-width: 0;
  aspect-ratio: 5 / 3;
  border-radius: 10px;
  background: var(--m3-surface-lowest);
  border: 1.5px solid var(--m3-outline-variant);
  display: flex;
  align-items: center;
  justify-content: center;
}
:where(html[data-page="stage"]) .lp-frame-caption {
  margin: 12px 0 0;
  font-size: 12px;
  color: var(--m3-on-surface-variant);
}

/* Asientos y conexión (lista del hero y tarjetas) */
:where(html[data-page="stage"]) .lp-seats {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
:where(html[data-page="stage"]) .lp-seats-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--m3-on-surface);
  padding: 6px 2px;
}
:where(html[data-page="stage"]) .lp-seatrow {
  background: var(--m3-surface);
  border-radius: 12px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
}
:where(html[data-page="stage"]) .lp-seatrow-name {
  flex: 1;
  min-width: 0;
}
:where(html[data-page="stage"]) .lp-seatchip {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--m3-surface);
}
:where(html[data-page="stage"]) .lp-seatchip-lg {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  font-size: 18px;
}
:where(html[data-page="stage"]) .lp-net {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 12px;
}
:where(html[data-page="stage"]) .lp-net i {
  display: block;
  width: 3px;
  background: var(--m3-surface-container-high);
}
:where(html[data-page="stage"]) .lp-net i:nth-child(1) { height: 4px; }
:where(html[data-page="stage"]) .lp-net i:nth-child(2) { height: 8px; }
:where(html[data-page="stage"]) .lp-net i:nth-child(3) { height: 12px; }
:where(html[data-page="stage"]) .lp-net-lg {
  gap: 3px;
  height: 16px;
}
:where(html[data-page="stage"]) .lp-net-lg i {
  width: 4px;
}
:where(html[data-page="stage"]) .lp-net-lg i:nth-child(1) { height: 6px; }
:where(html[data-page="stage"]) .lp-net-lg i:nth-child(2) { height: 11px; }
:where(html[data-page="stage"]) .lp-net-lg i:nth-child(3) { height: 16px; }
:where(html[data-page="stage"]) .lp-net[data-q="buena"] i {
  background: var(--status-good);
}
:where(html[data-page="stage"]) .lp-net[data-q="regular"] i:nth-child(-n + 2) {
  background: var(--status-warn);
}
:where(html[data-page="stage"]) .lp-net[data-q="mala"] i:nth-child(1) {
  background: var(--status-bad);
}

/* Ocasiones */
:where(html[data-page="stage"]) .lp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
:where(html[data-page="stage"]) .lp-chip {
  border: 1px solid var(--m3-outline-variant);
  border-radius: 8px;
  padding: 8px 16px;
  font-size: 15px;
  font-weight: 500;
  display: flex;
  gap: 10px;
  align-items: center;
}
:where(html[data-page="stage"]) .lp-chip i {
  display: block;
  width: 6px;
  height: 6px;
  background: var(--oc);
}
:where(html[data-page="stage"]) .lp-chip {
  border-color: var(--oc);
}
:where(html[data-page="stage"]) .lp-chip:nth-child(3n + 1) { --oc: var(--oc-1); }
:where(html[data-page="stage"]) .lp-chip:nth-child(3n + 2) { --oc: var(--oc-2); }
:where(html[data-page="stage"]) .lp-chip:nth-child(3n + 3) { --oc: var(--oc-3); }

/* Banda de asientos */
:where(html[data-page="stage"]) .lp-band {
  background: var(--m3-surface-container);
}
:where(html[data-page="stage"]) .lp-band-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 88px 24px;
  box-sizing: border-box;
}
:where(html[data-page="stage"]) .lp-seatgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
:where(html[data-page="stage"]) .lp-seatcard {
  background: var(--m3-surface);
  border-radius: 20px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
:where(html[data-page="stage"]) .lp-seatcard-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
:where(html[data-page="stage"]) .lp-seatcard strong {
  display: block;
  font-size: 18px;
}
:where(html[data-page="stage"]) .lp-seatcard span.lp-muted {
  font-size: 14px;
}

/* Cómo funciona: pasos con el color de la paleta (el resto de la sección es el de siempre) */
:where(html[data-page="stage"]) [data-step="1"] { --step: var(--step-1); }
:where(html[data-page="stage"]) [data-step="2"] { --step: var(--step-2); }
:where(html[data-page="stage"]) [data-step="3"] { --step: var(--step-3); }
:where(html[data-page="stage"]) [data-step="4"] { --step: var(--step-4); }
:where(html[data-page="stage"]) .step-node {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Press Start 2P", monospace;
  font-size: 16px;
  z-index: 1;
  background: var(--step);
  color: var(--m3-surface);
}
:where(html[data-page="stage"]) .step-title {
  color: var(--step);
}

/* Juegos: las mismas tarjetas del escenario (.game-card*), en una grilla */
:where(html[data-page="stage"]) .lp-head {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 28px;
}
:where(html[data-page="stage"]) .lp-games {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: 24px;
}
:where(html[data-page="stage"]) .lp-games .game-card {
  max-width: none;
  width: 100%;
  pointer-events: none;
}
/* El escenario dimensiona el texto por ancho de ventana (9 a 11 px, pensado
   para la pantalla de selección); en una página de lectura se fija un piso. */
:where(html[data-page="stage"]) .lp-games .game-card-name {
  font-size: 12px;
  text-align: center;
}
:where(html[data-page="stage"]) .lp-games .game-card-description {
  font-size: 13px;
}
@media (max-width: 640px) {
  :where(html[data-page="stage"]) .lp-games {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 12px;
  }
}

/* Netcode */
:where(html[data-page="stage"]) .lp-netcode-wrap {
  border-radius: 32px;
}
:where(html[data-page="stage"]) .lp-netcode {
  background: var(--m3-surface-container);
  border-radius: 28px;
  padding: clamp(28px, 5vw, 56px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: 40px;
  align-items: center;
}
:where(html[data-page="stage"]) .lp-netcode p {
  margin: 0;
  font-size: 17px;
  text-wrap: pretty;
}
:where(html[data-page="stage"]) .lp-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
:where(html[data-page="stage"]) .lp-stat {
  background: var(--m3-surface);
  border-radius: 16px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: 15px;
}
:where(html[data-page="stage"]) .lp-stat-n {
  font-size: 24px;
  line-height: 1.35;
}
:where(html[data-page="stage"]) .lp-stat-t {
  font-size: 18px;
  line-height: 1.35;
}

/* Preguntas */
:where(html[data-page="stage"]) .lp-faq {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: 48px;
  padding-bottom: 96px;
}
:where(html[data-page="stage"]) .lp-faq-list {
  display: flex;
  flex-direction: column;
}
:where(html[data-page="stage"]) .lp-faq-item {
  padding: 18px 4px;
  border-bottom: 1px solid var(--m3-outline-variant);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
:where(html[data-page="stage"]) .lp-faq-item strong {
  font-size: 17px;
}
:where(html[data-page="stage"]) .lp-faq-item span {
  font-size: 15px;
  color: var(--m3-on-surface-variant);
  text-wrap: pretty;
}

/* Pie */
:where(html[data-page="stage"]) .lp-footer {
  background: var(--m3-surface-container);
}
:where(html[data-page="stage"]) .lp-footer-cta {
  max-width: 1200px;
  margin: 0 auto;
  padding: 80px 24px 48px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 28px;
}
:where(html[data-page="stage"]) .lp-footer-cta h2 {
  font-weight: 400;
  font-size: clamp(18px, 2.8vw, 32px);
  line-height: 1.5;
  margin: 0;
  max-width: 22em;
  text-wrap: balance;
}
:where(html[data-page="stage"]) .lp-footer-meta {
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  gap: 12px 24px;
  flex-wrap: wrap;
  font-size: 14px;
  border-top: 1px solid var(--m3-outline-variant);
}
:where(html[data-page="stage"]) .lp-footer-meta nav {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
}
:where(html[data-page="stage"]) .lp-footlink {
  color: var(--m3-on-surface);
  text-decoration: none;
}
:where(html[data-page="stage"]) .lp-footlink:hover {
  color: var(--lp-hover);
}
:where(html[data-page="stage"]) .lp-footer-meta p {
  margin: 0;
}
:where(html[data-page="stage"]) .lp-legal {
  width: 100%;
  font-size: 13px;
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="stage"]) .lp-footer-wm {
  padding: 24px 12px 28px;
  text-align: center;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  font-size: clamp(26px, 8.6vw, 112px);
}
:where(html[data-page="stage"]) .lp-colorbar {
  height: 12px;
  background: linear-gradient(90deg, var(--seat-1) 0 25%, var(--seat-2) 25% 50%, var(--seat-3) 50% 75%, var(--seat-4) 75% 100%);
}

@media (max-width: 640px) {
  :where(html[data-page="stage"]) .lp-frame {
    grid-template-columns: 1fr;
  }
  :where(html[data-page="stage"]) .lp-hero {
    padding-top: 56px;
  }
}

/* ==========================================================================
   Admin (la página de monitoreo que sirve el Worker en /admin, detrás de Cloudflare Access)
   docs/PLAN-ADMIN-MONITOREO.md, H4. Mismas reglas que la landing: solo var(--…), contorno de
   1 px en los títulos pixel, Roboto para todo dato y etiqueta, tramado como elevación.
   ========================================================================== */
:where(html[data-page="admin"]) body {
  margin: 0;
  font-family: "Roboto", system-ui, -apple-system, sans-serif;
  background: var(--m3-surface);
  color: var(--m3-on-surface);
  line-height: 1.45;
}
:where(html[data-page="admin"]) .mon-muted {
  color: var(--m3-on-surface-variant);
  font-size: 13px;
  margin: 0;
}

/* Cabecera */
:where(html[data-page="admin"]) .mon-header {
  background: var(--m3-surface-container);
}
:where(html[data-page="admin"]) .mon-header-in {
  max-width: 1280px;
  margin: 0 auto;
  padding: 12px 24px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
:where(html[data-page="admin"]) .mon-brand {
  display: flex;
  align-items: center;
  gap: 12px;
}
:where(html[data-page="admin"]) .mon-brand img {
  width: 36px;
  height: 36px;
  image-rendering: pixelated;
}
:where(html[data-page="admin"]) .mon-brand-name {
  font-size: 14px;
}
:where(html[data-page="admin"]) .mon-brand-sub {
  color: var(--m3-on-surface-variant);
  font-size: 15px;
  font-weight: 500;
}
:where(html[data-page="admin"]) .mon-live {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="admin"]) .mon-strip {
  height: 4px;
  background: repeating-conic-gradient(var(--m3-surface-container) 0 25%, var(--m3-surface) 0 50%) 0 0 / 4px 4px;
}

/* Puntos de estado (conexión, estado de sala) */
:where(html[data-page="admin"]) .mon-dot {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--m3-outline);
}
:where(html[data-page="admin"]) .mon-dot[data-state="good"] { background: var(--status-good); }
:where(html[data-page="admin"]) .mon-dot[data-state="warn"] { background: var(--status-warn); }
:where(html[data-page="admin"]) .mon-dot[data-state="bad"] { background: var(--status-bad); }

/* Disposición: en pantalla ancha el uso a la izquierda y las salas a la derecha; en angosta, las salas primero */
:where(html[data-page="admin"]) .mon-main {
  max-width: 1280px;
  margin: 0 auto;
  padding: 24px;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(300px, 380px) minmax(0, 1fr);
  gap: 32px;
  align-items: start;
}
:where(html[data-page="admin"]) .mon-usage-col {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
}
:where(html[data-page="admin"]) .mon-rooms-col {
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
}
@media (max-width: 900px) {
  :where(html[data-page="admin"]) .mon-main {
    grid-template-columns: minmax(0, 1fr);
    padding: 16px;
    gap: 24px;
  }
  :where(html[data-page="admin"]) .mon-usage-col,
  :where(html[data-page="admin"]) .mon-rooms-col {
    grid-column: 1;
    grid-row: auto;
  }
  :where(html[data-page="admin"]) .mon-header-in {
    padding: 12px 16px;
  }
}

/* Títulos pixel (solo títulos y marca) */
:where(html[data-page="admin"]) .mon-h1 {
  font-size: 16px;
  line-height: 1.5;
  font-weight: 400;
  margin: 0 0 16px;
}
:where(html[data-page="admin"]) .mon-h2 {
  font-size: 14px;
  line-height: 1.5;
  font-weight: 400;
  margin: 0 0 16px;
}
:where(html[data-page="admin"]) .mon-h3 {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--m3-on-surface-variant);
  margin: 18px 0 8px;
}

/* Resumen de salas */
:where(html[data-page="admin"]) .mon-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 8px;
}
:where(html[data-page="admin"]) .mon-stat {
  background: var(--m3-surface-container);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 10px;
  padding: 8px 16px;
  min-width: 96px;
}
:where(html[data-page="admin"]) .mon-stat dt {
  font-size: 12px;
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="admin"]) .mon-stat dd {
  margin: 0;
  font-size: 24px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
:where(html[data-page="admin"]) .mon-stat[data-tone="warn"] {
  border-color: var(--status-warn);
}
:where(html[data-page="admin"]) .mon-stat[data-tone="warn"] dd {
  color: var(--status-warn);
}
:where(html[data-page="admin"]) .mon-rooms {
  align-items: start;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr));
  gap: 20px;
  margin-top: 16px;
}
:where(html[data-page="admin"]) .mon-poll {
  margin-top: 16px;
}

/* Mensajes (vacío, error, no configurado) */
:where(html[data-page="admin"]) .mon-empty {
  grid-column: 1 / -1;
  margin: 0;
  padding: 24px;
  text-align: center;
  color: var(--m3-on-surface-variant);
  background: var(--m3-surface-container);
  border: 1px dashed var(--m3-outline);
  border-radius: 12px;
}
:where(html[data-page="admin"]) .mon-msg {
  margin: 8px 0;
  padding: 10px 14px;
  font-size: 14px;
  background: var(--m3-surface-container);
  border: 1px solid var(--m3-outline-variant);
  border-left-width: 4px;
  border-radius: 8px;
}
:where(html[data-page="admin"]) .mon-msg[hidden] {
  display: none;
}
:where(html[data-page="admin"]) .mon-msg[data-kind="error"] {
  border-color: var(--status-bad);
}
:where(html[data-page="admin"]) .mon-msg[data-kind="warn"] {
  border-color: var(--status-warn);
}
:where(html[data-page="admin"]) .mon-msg[data-kind="info"] {
  border-color: var(--m3-outline);
}

/* Tarjetas con tramado como elevación (igual que el marco de la landing) */
:where(html[data-page="admin"]) .mon-frame {
  background: repeating-conic-gradient(var(--m3-surface-container-high) 0 25%, transparent 0 50%) 0 0 / 4px 4px;
  padding: 0 6px 6px 0;
  border-radius: 14px;
  min-width: 0;
}
:where(html[data-page="admin"]) .mon-card {
  background: var(--m3-surface-container);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 12px;
  padding: 16px;
  min-width: 0;
}
:where(html[data-page="admin"]) .mon-room[data-status="sin-senal"] {
  border-color: var(--status-bad);
}
:where(html[data-page="admin"]) .mon-room-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
:where(html[data-page="admin"]) .mon-roomid,
:where(html[data-page="admin"]) .mon-id {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 13px;
}
:where(html[data-page="admin"]) .mon-roomid {
  overflow-wrap: anywhere;
  user-select: all;
}
:where(html[data-page="admin"]) .mon-badge {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid var(--m3-outline);
  border-radius: 999px;
}
:where(html[data-page="admin"]) .mon-badge[data-status="activa"] { border-color: var(--status-good); }
:where(html[data-page="admin"]) .mon-badge[data-status="activa"] .mon-dot { background: var(--status-good); }
:where(html[data-page="admin"]) .mon-badge[data-status="vacia"] { border-color: var(--status-warn); }
:where(html[data-page="admin"]) .mon-badge[data-status="vacia"] .mon-dot { background: var(--status-warn); }
:where(html[data-page="admin"]) .mon-badge[data-status="sin-senal"] { border-color: var(--status-bad); }
:where(html[data-page="admin"]) .mon-badge[data-status="sin-senal"] .mon-dot { background: var(--status-bad); }
:where(html[data-page="admin"]) .mon-meta {
  margin: 0 0 6px;
  font-size: 14px;
}
:where(html[data-page="admin"]) .mon-alerts {
  margin: 8px 0;
  padding: 8px 12px 8px 28px;
  font-size: 13px;
  background: var(--m3-surface);
  border-left: 4px solid var(--status-warn);
  border-radius: 6px;
}

/* Asientos (mismos colores que el panel lateral) */
:where(html[data-page="admin"]) .mon-seats {
  list-style: none;
  margin: 12px 0 6px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 6px 12px;
}
:where(html[data-page="admin"]) .mon-seat {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  min-width: 0;
  font-size: 13px;
}
:where(html[data-page="admin"]) .mon-seat[data-free="1"] .mon-id {
  font-family: "Roboto", system-ui, sans-serif;
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="admin"]) .mon-seatchip {
  flex: none;
  width: 24px;
  height: 24px;
  box-sizing: border-box;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  color: var(--m3-surface);
}
:where(html[data-page="admin"]) .mon-seatchip[data-seat="1"] { background: var(--seat-1); border-color: var(--seat-1); }
:where(html[data-page="admin"]) .mon-seatchip[data-seat="2"] { background: var(--seat-2); border-color: var(--seat-2); }
:where(html[data-page="admin"]) .mon-seatchip[data-seat="3"] { background: var(--seat-3); border-color: var(--seat-3); }
:where(html[data-page="admin"]) .mon-seatchip[data-seat="4"] { background: var(--seat-4); border-color: var(--seat-4); }
/* Asiento reservado (desconectado): contorno discontinuo, sin relleno */
:where(html[data-page="admin"]) .mon-seatchip[data-connected="0"] {
  background: transparent;
  border: 2px dashed var(--m3-outline);
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="admin"]) .mon-tag {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border: 1px solid var(--m3-outline);
  border-radius: 4px;
}
:where(html[data-page="admin"]) .mon-spectators {
  margin-top: 4px;
  overflow-wrap: anywhere;
}

/* Conexiones entre pares */
:where(html[data-page="admin"]) .mon-peers {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}
:where(html[data-page="admin"]) .mon-peer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 12px;
  align-items: center;
  padding: 6px 10px;
  font-size: 13px;
  background: var(--m3-surface);
  border-radius: 8px;
}
:where(html[data-page="admin"]) .mon-pair,
:where(html[data-page="admin"]) .mon-who,
:where(html[data-page="admin"]) .mon-qual {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
:where(html[data-page="admin"]) .mon-ms {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  justify-self: end;
}
:where(html[data-page="admin"]) .mon-qual {
  justify-self: end;
}
:where(html[data-page="admin"]) .mon-net {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  height: 12px;
}
:where(html[data-page="admin"]) .mon-net i {
  display: block;
  width: 3px;
  background: var(--m3-surface-container-high);
}
:where(html[data-page="admin"]) .mon-net i:nth-child(1) { height: 4px; }
:where(html[data-page="admin"]) .mon-net i:nth-child(2) { height: 8px; }
:where(html[data-page="admin"]) .mon-net i:nth-child(3) { height: 12px; }
:where(html[data-page="admin"]) .mon-net[data-q="good"] i { background: var(--status-good); }
:where(html[data-page="admin"]) .mon-net[data-q="warn"] i:nth-child(-n + 2) { background: var(--status-warn); }
:where(html[data-page="admin"]) .mon-net[data-q="bad"] i:nth-child(1) { background: var(--status-bad); }

/* Contadores */
:where(html[data-page="admin"]) .mon-counters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 8px;
  margin: 0;
}
:where(html[data-page="admin"]) .mon-counter {
  min-width: 0;
  background: var(--m3-surface);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 8px;
  padding: 6px 10px;
}
:where(html[data-page="admin"]) .mon-counter dt {
  font-size: 12px;
  color: var(--m3-on-surface-variant);
}
:where(html[data-page="admin"]) .mon-counter dd {
  overflow-wrap: anywhere;
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
:where(html[data-page="admin"]) .mon-counter[data-tone="warn"] { border-color: var(--status-warn); }
:where(html[data-page="admin"]) .mon-counter[data-tone="warn"] dd { color: var(--status-warn); }
:where(html[data-page="admin"]) .mon-counter[data-tone="bad"] { border-color: var(--status-bad); }
:where(html[data-page="admin"]) .mon-counter[data-tone="bad"] dd { color: var(--status-bad); }
:where(html[data-page="admin"]) .mon-foot {
  margin-top: 12px;
}

/* Uso y costos */
:where(html[data-page="admin"]) .mon-metrics {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}
:where(html[data-page="admin"]) .mon-metric {
  background: var(--m3-surface-container);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 10px;
  padding: 10px 12px;
}
:where(html[data-page="admin"]) .mon-metric-top {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: baseline;
  flex-wrap: wrap;
}
:where(html[data-page="admin"]) .mon-metric-label {
  font-size: 13px;
  color: var(--m3-on-surface-variant);
  min-width: 0;
}
:where(html[data-page="admin"]) .mon-metric-val {
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
:where(html[data-page="admin"]) .mon-bar {
  height: 8px;
  margin: 8px 0 4px;
  background: var(--m3-surface);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 999px;
  overflow: hidden;
}
:where(html[data-page="admin"]) .mon-bar-fill {
  display: block;
  height: 100%;
  width: var(--pct, 0%);
  min-width: 2px;
  background: var(--m3-outline);
}
:where(html[data-page="admin"]) .mon-bar[data-state="good"] .mon-bar-fill { background: var(--status-good); }
:where(html[data-page="admin"]) .mon-bar[data-state="warn"] .mon-bar-fill { background: var(--status-warn); }
:where(html[data-page="admin"]) .mon-bar[data-state="bad"] .mon-bar-fill { background: var(--status-bad); }
:where(html[data-page="admin"]) .mon-pct {
  font-size: 12px;
  color: var(--m3-on-surface-variant);
  font-variant-numeric: tabular-nums;
}
:where(html[data-page="admin"]) .mon-metric[data-state="warn"] .mon-pct { color: var(--status-warn); }
:where(html[data-page="admin"]) .mon-metric[data-state="bad"] .mon-pct { color: var(--status-bad); }
:where(html[data-page="admin"]) .mon-note {
  margin-top: 4px;
}
:where(html[data-page="admin"]) .mon-cost {
  background: var(--m3-surface-container);
  border: 1px solid var(--m3-outline-variant);
  border-radius: 10px;
  padding: 12px 14px;
}
:where(html[data-page="admin"]) .mon-cost-val {
  margin: 0 0 6px;
  font-size: 24px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
:where(html[data-page="admin"]) .mon-link {
  display: inline-block;
  margin-top: 8px;
  font-size: 14px;
  color: var(--m3-primary);
  text-underline-offset: 3px;
}
:where(html[data-page="admin"]) .mon-link:hover {
  color: var(--lp-hover);
}
