.ww-player .ww-opt {
  border: 2px solid var(--ww-card-border, #dee2e6);
  background: var(--ww-card-bg, #fff);
  color: var(--ww-card-fg, var(--ww-fg, #1f2937));
  font-weight: 500;
  padding: 1rem;
  text-align: left;
  white-space: normal;
  transition: transform .1s, box-shadow .1s;
}
.ww-player .ww-opt:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0,0,0,.1);
}
.ww-player .ww-opt:disabled { opacity: .9; }

/* === Wordwall-style activity page === */

.ww-play-page {
  /* Techo de la PÁGINA, no del marco: quien decide cuánto crece el ejercicio es
     la regla de abajo (alto libre × proporción). Con 1100 aquí, ese cálculo se
     quedaba corto en cualquier monitor de escritorio — el marco tenía sitio
     para 1400 y la página no le dejaba pasar de 1100. */
  max-width: 1400px;
  margin: 0 auto;
  padding: 5px .5rem 0;   /* un respiro entre la barra superior y el marco */
}

/* LA IMAGEN NUNCA DESBORDA, HAYA MARCO O NO — la regla de suelo (§3).
   Todo el estándar de maquetación vive bajo `.ww-play-page .ww-player-frame`,
   que SOLO monta la página del profe (`views/playerView.js`). La TAREA y el EN
   VIVO montan la plantilla directa en `#app`: allí ninguna de esas reglas
   aplica, así que una imagen de 1280 px empujaba la página a 1280 px en un
   iPhone de 390 — el alumno veía «una esquinita» de su tarea. Se notó porque la
   pregunta SIGUIENTE, sin imagen, entraba bien, y la misma actividad en VS (que
   sí va enmarcada) escalaba. Ronda del compañero 2026-08-11, prueba 12.
   Va sin `.ww-play-page` a propósito: es el mínimo que debe cumplirse en las
   TRES pantallas. Dentro del marco, la regla de abajo (más específica) sigue
   mandando con su `max-height` + `object-fit`. */
.ww-player img,
.ww-q-media img,
#s-round img { max-width: 100%; height: auto; }

/* …Y EN EL MÓVIL LA FOTO LLEGA AL BORDE (§3 · ronda del compañero 2026-08-12,
   prueba 4: «sale un pequeño margen a los lados de la foto, no hace fill»).
   La tarea y el en vivo montan la plantilla dentro de `#app.container`, que
   reserva 12px a cada lado: la foto ya entraba entera (arriba), pero con dos
   franjas de fondo pegadas al marco del teléfono. En pantalla ancha ese margen
   es lo correcto — la foto no debe pegarse al borde —; solo estorba cuando el
   ancho ES la medida del ejercicio. El sangrado se hace SIN conocer el padding
   del contenedor (centrando en el viewport), así no hay un 12px copiado que se
   desincronice si Bootstrap cambia. No alcanza al marco del profe: ese monta en
   un `#app` sin `.container` y sus reglas de `object-fit` siguen mandando. */
@media (max-width: 640px) {
  #app.container .ww-q-media img,
  #app.container #s-round img {
    width: 100vw;
    max-width: 100vw;
    margin-inline: calc(50% - 50vw);
    border-radius: 0;
  }
}

/* ── Diagramación de la página de jugar (dueño, 2026-08-18, dos capturas) ────
   CUATRO áreas — cabecera · marco · modo de juego · apariencia — repartidas
   por `grid-template-areas`. El ORDEN VISUAL lo decide el CSS por breakpoint,
   no el DOM (que es siempre header→stage→modes→appearance):

     · PC (≥992px, la captura ancha mide 1064): cabecera arriba a todo el
       ancho; marco + «Modo de juego» a la izquierda; Apariencia a la derecha.
     · tablet-o-menos (la captura estrecha mide 807): se JUEGA primero — el
       marco arriba, la cabecera debajo, luego modos y Apariencia.

   «Modo de juego» es área PROPIA (no vive dentro del escenario) porque en
   tablet la foto lo pone DESPUÉS de la cabecera, y solo un área independiente
   puede reordenarse. Duplicar el marcado por breakpoint hubiera sido el
   camino fácil pero rompe "una sola fuente de verdad".

   El primer intento puso el corte de las dos columnas en 1450px «para que el
   VS expandido conservara sus 1100» — y la ventana del dueño mide 1443: nunca
   vio el modo PC. El fallo que motivó aquel 1450 era en realidad VERTICAL
   (los smokes tocaban sin hacer scroll; ya corregidos), así que el corte
   vuelve a donde manda la foto. El VS en columna estrecha se adapta solo:
   toda su maquetación es de contenedor (cq*), no de viewport. */
.pp-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "stage" "header" "modes" "appearance";
  gap: 1rem;
  align-items: start;
}
.pp-header      { grid-area: header; }
.pp-stage       { grid-area: stage; min-width: 0; }
.pp-modes       { grid-area: modes; min-width: 0; }
.pp-appearance  { grid-area: appearance; min-width: 0; }

@media (min-width: 992px) {
  .pp-layout {
    grid-template-columns: minmax(0, 1fr) clamp(300px, 32%, 430px);
    /* La última fila (1fr) absorbe el alto sobrante de la columna de
       Apariencia (que abarca dos filas): sin esto, ese alto infla la fila del
       marco y «Modo de juego» queda descolgado un pantallazo más abajo. */
    grid-template-rows: auto auto 1fr;
    grid-template-areas:
      "header header"
      "stage  appearance"
      "modes  appearance";
  }
}

/* La TARJETA de sección (como en las fotos): blanca, redondeada, con su
   etiqueta gris en versalitas dentro. Es CHROME del panel (paleta de la home),
   no juego: por eso los colores van directos y no por tokens --ww-*. */
.pp-card {
  background: #fff;
  border: 1px solid rgba(15, 23, 42, .08);
  border-radius: 16px;
  padding: 1rem 1.25rem;
  box-shadow: 0 2px 10px rgba(15, 23, 42, .05);
}

.pp-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: .5rem .75rem;
}
.pp-header-info {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .25rem .6rem;
  min-width: 0;
}
.pp-title { font-size: 1.6rem; font-weight: 800; margin: 0; line-height: 1.2; }
.pp-meta a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.pp-header-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.pp-appearance-title { font-weight: 800; font-size: 1.15rem; margin-bottom: .75rem; }

/* Tema y Fondo dentro de la tarjeta de Apariencia: en la columna lateral de PC
   van uno debajo del otro; a todo el ancho (tablet) caben lado a lado, que es
   exactamente cómo los pinta la captura estrecha. */
.pp-appearance-sections {
  display: grid;
  gap: 1rem 2rem;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}
@media (min-width: 992px) {
  .pp-appearance-sections { grid-template-columns: minmax(0, 1fr); }
}

/* ── Los cuadritos de Tema y Fondo (dueño, 2026-08-18: «se ven muy mal, que
   entren 3 o 4 bien puestos, pequeños, y su relación de aspecto creo que es
   16:10») ────────────────────────────────────────────────────────────────────
   Estaban en `flex-wrap` con un ancho FIJO por cuadro (96px), así que el
   reparto del hueco lo decidía el cuadro y no la columna: sobraba un canal a
   la derecha y las filas quedaban desiguales. Ahora manda la REJILLA
   (auto-fill + 1fr): los cuadros se estiran para llenar el ancho exacto que
   haya, y su alto sale de la proporción, no de un px escrito. 16/10 porque es
   la forma de una pantalla — que es lo que el cuadro está enseñando.
   El `minmax` es el único número: «no bajes de 78px», y de ahí sale que entren
   3 en la columna lateral y 4-6 a todo el ancho. */
.pp-pick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(78px, 1fr));
  gap: .5rem;
}
.pp-appearance .ww-pick-tile { width: auto; padding: .25rem; }
/* Los dos previews comparten forma; cada uno conserva su contenido (el del
   tema enseña su tipografía sobre su fondo, el del fondo es solo textura). */
.pp-appearance .ww-skin-preview,
.pp-appearance .ww-bg-preview {
  height: auto;
  aspect-ratio: 16 / 10;
}
.pp-appearance .ww-skin-preview { padding: .35rem; border-radius: 5px; }
.pp-appearance .ww-skin-preview .d-flex { gap: 2px; }
.pp-appearance .ww-skin-preview span { width: 100%; height: 8px; border-radius: 2px; }
.pp-appearance .ww-skin-preview small { font-size: .62rem; line-height: 1.1; }
.pp-appearance .ww-bg-preview + small { font-size: .62rem; line-height: 1.15; }
/* La puerta de «Mi imagen»: el botón entero no cabe a 78px de ancho. */
.pp-appearance .bg-pick .btn { font-size: .62rem; padding: .15rem .25rem; }

/* ── Apariencia PLEGABLE (pedido) ─────────────────────────────────────────── */
.pp-acc > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  cursor: pointer;
  list-style: none;          /* sin el triángulo del navegador: hay chevron */
  margin-bottom: .75rem;
}
.pp-acc > summary::-webkit-details-marker { display: none; }
.pp-acc > summary .pp-appearance-title { margin: 0; }
.pp-acc-chev { transition: transform .15s; color: #64748b; }
.pp-acc[open] > summary .pp-acc-chev { transform: rotate(180deg); }

/* The "embed" frame — bounded width, fixed aspect ratio, scrolls inside.
   Like a YouTube embed: small box inside the page, not the whole page. */
.ww-play-page .ww-player-frame {
  max-width: 720px;
  width: 100%;
  margin: 0 auto;
  position: relative;
  background: var(--ww-card-bg, #ffffff);
  color: var(--ww-card-fg, var(--ww-fg, #1f2937));
  border-radius: 12px;
  box-shadow: 0 6px 24px rgba(0,0,0,.12);
  overflow: hidden;
  /* ESTÁNDAR DE MAQUETACIÓN: el marco es una COLUMNA flex y RESERVA el espacio de
     cada parte ANTES de dibujar. Si el modo Individual activa la animación de
     progreso, su carril (.ww-solo-anim) ocupa su franja arriba y el widget toma
     el resto; si no, el carril es display:none y el widget llena todo. */
  display: flex;
  flex-direction: column;
  /* ESQUINA RESERVADA: el ancho que el botón de pantalla completa ocupa arriba a
     la derecha. Quien pinte una barra a todo el ancho dentro del marco la
     respeta con este valor — una sola medida, no un número copiado. */
  --ww-fs-reserve: 52px;
  /* LA PROPORCIÓN QUE DECLARA LA PLANTILLA (core/frameAspect.js la pone como
     variable, no como `aspect-ratio` en línea: en línea ganaba a todo y no se
     podía soltar donde hace falta). */
  aspect-ratio: var(--ww-ar-css, 4/3);
}

/* El marcador del duelo cede la esquina (si no, el botón taparía el puntaje del
   jugador de la derecha). Los skins solo tocan el FONDO de `.vss-right`, no su
   relleno, así que esta regla no entra en la guerra de especificidad del skin.
   LA RESERVA VA EN LAS DOS MITADES, aunque el botón solo esté a la derecha (dueño,
   2026-08-22, con captura: «el avatar de alumno 1 está pegado al borde y el otro
   no, ¿qué pasó ahí?»). Medido: 12 px de hueco a la izquierda contra 52 a la
   derecha. El duelo es un ESPEJO —dos mitades iguales enfrentadas—, y una reserva
   en un solo lado lo rompe a la vista aunque cada regla por separado sea correcta.
   Cuesta un poco de relleno a la izquierda; que las dos fichas de alumno estén a
   la misma distancia de su borde vale más. */
.ww-play-page .ww-player-frame .vss-right { padding-right: var(--ww-fs-reserve); }
.ww-play-page .ww-player-frame .vss-left  { padding-left:  var(--ww-fs-reserve); }

/* BOTÓN DE PANTALLA COMPLETA, DISCRETO (como Wordwall). Flota en la esquina del
   marco, translúcido, y se afirma al pasar el dedo/ratón. Está DENTRO del marco
   a propósito: al expandir, el botón se expande con él y sigue ahí para salir
   (en una pizarra táctil no hay tecla Esc). Colores por token: los skins
   recolorean el juego y este botón vive encima del juego. */
.ww-fs-btn--corner {
  /* z-index POR ENCIMA de lo que pinte el modo. El marcador del duelo
     (`.vss-bar`, z-index 10) tapaba el botón: existía, se veía a medias y NO se
     podía tocar en ningún VS — comprobado con hit-testing, no a ojo. La esquina
     superior derecha del marco es DEL MARCO; el modo que ponga algo ahí debe
     dejarla libre (ver `--ww-fs-reserve`). */
  position: absolute; top: 8px; right: 8px; z-index: 30;
  width: max(34px, 5cqmin); height: max(34px, 5cqmin);
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: 50%;
  /* VELO NEUTRO, no tokens de skin: es un control DE SUPERPOSICIÓN (como los de
     YouTube) y debe leerse sobre CUALQUIER fondo. Con var(--ww-card-bg)/--ww-fg
     el skin un concurso lo dejaba blanco-sobre-blanco: el icono existía y no se veía
     (reporte de prueba real, v1.51.386). Un velo oscuro + icono blanco es
     legible sobre los 6 skins sin conocer ninguno. */
  background: rgba(0, 0, 0, .45); color: #fff;
  box-shadow: 0 1px 6px rgba(0,0,0,.22);
  opacity: .38; cursor: pointer;
  transition: opacity .15s ease, transform .15s ease;
}
.ww-fs-btn--corner:hover,
.ww-fs-btn--corner:focus-visible { opacity: 1; transform: scale(1.06); }
.ww-fs-btn--corner.is-on { opacity: .62; }   /* en pantalla completa se ve más: es la salida */
.ww-fs-btn--corner i { font-size: max(14px, 2.4cqmin); line-height: 1; }
/* Táctil: no hay hover que revele el botón, así que nace visible. */
@media (hover: none) { .ww-fs-btn--corner { opacity: .55; } }

/* EL HUD DEL JUEGO (core/playerHud.js): los indicadores —página, tiempo,
   puntos, racha— FLOTAN en las esquinas superiores, encima del juego, y no
   crean franja (decisión del dueño, 2026-08-17: «como en la actividad
   Calcular»). Quien tenga un `.edu-hud` como hijo directo se convierte en su
   ámbito de posicionamiento — ninguna plantilla necesita clase extra.
   VELO NEUTRO como el botón de la esquina (y por el mismo reporte v1.51.386):
   son controles DE SUPERPOSICIÓN y deben leerse sobre cualquier fondo/skin.
   No captura toques: un globo que pase debajo se sigue explotando. */
:where(:has(> .edu-hud)) { position: relative; }
.edu-hud {
  position: absolute; top: 0; left: 0; right: 0; z-index: 20;
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 1cqmin;
  padding: max(6px, 1.2cqmin);
  /* La esquina derecha es del botón de pantalla completa. */
  padding-right: var(--ww-fs-reserve, 52px);
  pointer-events: none;
}
.edu-hud__zona { display: flex; gap: max(4px, .8cqmin); flex-wrap: wrap; }
.edu-hud__chip {
  background: rgba(0, 0, 0, .45); color: #fff;
  border-radius: 999px;
  padding: .22em .7em;
  font-size: max(12px, 2.6cqmin);
  font-weight: 600;
  line-height: 1.35;
  white-space: nowrap;
}

/* Carril de la animación de progreso (solo) DENTRO del marco: franja arriba.
   La animación es SECUNDARIA → ocupa como mucho el 25% del alto del marco (y el
   widget se queda con el 75%+). Oculto ([hidden]) no ocupa espacio. */
.ww-play-page .ww-player-frame > .ww-solo-anim {
  flex: 0 0 auto;
  height: clamp(44px, 25%, 104px);
  margin: 0;
}
/* Marco de alto indefinido (aspect:auto, p.ej. Tildes/Comas): el % no resuelve,
   usar un alto fijo discreto. */
.ww-play-page .ww-player-frame[style*="auto"] > .ww-solo-anim { height: 84px; }

/* Widget: toma la altura RESTANTE tras el carril (flex:1), con su propio scroll.
   container-type:size lo hace contenedor de consulta para que la actividad se
   dimensione al hueco real (cq*) y quepa sin desbordar. display:flex+column deja
   que las actividades cortas se centren con margin:auto. */
.ww-play-page .ww-player-frame > #ww-player-widget {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 1.25rem;
  container-type: size;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.ww-play-page .ww-player-frame > #ww-player-widget > * {
  margin-top: auto;
  margin-bottom: auto;
}

/* Quiz/solo player: a flex column that exactly fills the frame, so it never
   needs a scrollbar. The image is the flexible middle (shrinks to fit); the
   question and options keep natural size. Text/buttons scale with the frame
   via container-query units → crisp on a 1280x800 board and in fullscreen. */
.ww-play-page .ww-player-frame .ww-player {
  display: flex;
  flex-direction: column;
  height: 100%;
  gap: 1.4cqh;
}
/* EL ENUNCIADO: primera subsección del juego, CENTRADO (2026-08-17). Los
   contadores que compartían esta fila viven ahora en el HUD de las esquinas
   (`.edu-hud`), así que la fila es solo la pregunta — y respeta a AMBOS lados
   el espacio de los chips para que un enunciado largo no se meta debajo. Va
   sin `.ww-play-page` porque la tarea y el en vivo montan sin marco. */
.ww-player .ww-prow {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: .25em;
  padding-inline: var(--ww-fs-reserve, 52px);
}
/* EN VERTICAL EL ENUNCIADO BAJA DE LA FRANJA DE CHIPS. Compartir línea con los
   chips ahorra alto en apaisado, pero en un marco alto la pregunta ENVUELVE y
   sus letras acaban debajo de «⏱ 12 · ★ 40» (lo cazó la matriz en vertical al
   estrenar el chip de puntos del Quiz). En vertical sobra alto y falta ancho:
   el enunciado toma el ancho entero y empieza bajo los chips — misma reserva
   que la Sopa (fuente del chip × su caja + el relleno del HUD). */
/* Sin nombre de contenedor: el Quiz no monta el andamio (`player` es
   .ww-scaffold), así que la consulta resuelve contra el contenedor más
   cercano — el widget (#ww-player-widget, container-type: size). Y gateado a
   que HAYA chips: la ronda de VS monta .ww-player sin HUD y no debe pagar la
   franja. */
@container (aspect-ratio < 1/1) {
  .ww-player:has(> .edu-hud) .ww-prow { padding-inline: .5rem; margin-top: max(30px, 6.5cqmin); }
}
.ww-player .ww-prow .ww-q { flex: 1 1 auto; text-align: center; }
.ww-play-page .ww-player-frame .ww-player .ww-prow { flex: 0 0 auto; }
.ww-play-page .ww-player-frame .ww-player .ww-q {
  margin: 0;
  line-height: 1.15;
  font-size: clamp(1rem, 5cqmin, 2.4rem);
}
/* PLACA DE LEGIBILIDAD (§3 · reporte del dueño 2026-08-12). Sobre la foto del
   profe el enunciado y el contador quedaban en texto suelto: en la captura,
   «¿Cuántos días tiene una semana?» era ILEGIBLE. El color sale de los tokens
   de tarjeta, así que cada tema la recolorea.
   Quién la lleva NO se decide aquí: la PIDE el fondo con `plate:true` en su
   manifest y `applyBackground` pone `bg-plated` (plan de temas y fondos). Hoy
   solo la foto — las otras 9 texturas tienen su tinta declarada y medida en CI
   contra su `colorBase`—, pero una textura nueva la enciende declarándola, sin
   tocar este CSS. */
.ww-play-page .ww-player-frame.bg-plated .ww-player .ww-q,
body.bg-plated .ww-player .ww-q {
  background: var(--ww-card-bg, #fff);
  color: var(--ww-card-fg, var(--ww-fg, #1f2937));
  border-radius: 12px;
  padding: .35em .7em;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
}
/* Sobre FOTO el botón de pantalla completa se viste como las placas (círculo de
   tarjeta, mismo icono): es lo que dibujó el dueño en su mockup. El velo oscuro
   sigue siendo el default en el resto de fondos — la lección de v1.51.386
   (blanco-sobre-blanco en el skin un concurso) era sobre el marco plano, no sobre
   fotos, donde el círculo claro contrasta igual que las placas de al lado. */
.ww-play-page .ww-player-frame.bg-plated .ww-fs-btn--corner {
  background: var(--ww-card-bg, #fff);
  color: var(--ww-card-fg, var(--ww-fg, #1f2937));
  box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
  opacity: 1;
}

.ww-play-page .ww-player-frame .ww-player .ww-q-media {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ww-play-page .ww-player-frame .ww-player .ww-q-media img {
  max-height: 100%;
  max-width: 100%;
  object-fit: contain;
  border-radius: 8px;
}
.ww-play-page .ww-player-frame .ww-player .ww-options { flex: 0 0 auto; gap: 1.2cqh; }
/* SIN imagen no hay sección de media (el player ya no la pinta vacía): las
   opciones heredan su espacio y crecen a lo un concurso, en vez de dejar un hueco
   muerto del 70 % entre pregunta y respuestas (medido en piezas.mjs, D8). El
   selector es el hueco mismo: la rejilla PEGADA al enunciado. */
.ww-play-page .ww-player-frame .ww-player > .ww-prow + .ww-opt-grid {
  flex: 1 1 auto;
  min-height: 0;
  grid-auto-rows: 1fr;
}
.ww-play-page .ww-player-frame .ww-player > .ww-prow + .ww-opt-grid .btn { height: 100%; }
.ww-play-page .ww-player-frame .ww-player .ww-opt-grid .btn {
  font-size: clamp(.9rem, 3.4cqmin, 1.9rem);
  padding: clamp(.45rem, 2.2cqh, 1.6rem);
  min-height: 0;
  white-space: normal;
}
.ww-play-page .ww-player-frame[style*="auto"] > #ww-player-widget {
  position: static;
  inset: auto;
  min-height: inherit;
  container-type: normal; /* indefinite height: size containment would collapse it */
}

/* Fullscreen mode: frame fills the screen, widget loses padding so the
   activity uses every pixel (interactive board / projector). */
.ww-play-page .ww-player-frame:fullscreen,
.ww-play-page .ww-player-frame:-webkit-full-screen {
  max-width: none;
  width: 100vw;
  height: 100vh;
  border-radius: 0;
  box-shadow: none;
}
/* EN PANTALLA COMPLETA, LA ACTIVIDAD RESPIRA AL 90 % (dueño, 2026-08-21: «para
   full screen vamos a hacer más pequeñas esas actividades, pues están muy
   grandes»). Al arreglar el fill, en una pizarra grande el juego pasó a ocupar
   literalmente todo y quedaba agobiado contra los bordes. El margen es
   RELATIVO (`vmin`), no un número de píxeles: en un monitor de 27" y en una
   pizarra de 86" recorta la misma proporción. Vale para las 13, porque lo pone
   el marco y no cada plantilla. */
.ww-play-page .ww-player-frame:fullscreen > #ww-player-widget,
.ww-play-page .ww-player-frame:-webkit-full-screen > #ww-player-widget {
  padding: 1rem;
}
/* …Y EL JUEGO RESPIRA, pero NO el HUD. El margen va sobre el andamio y sobre el
   reparto del duelo —lo que contiene el juego—, nunca sobre el widget entero:
   los indicadores flotan en las ESQUINAS del marco (`.edu-hud`, absoluto contra
   el widget) y al padear el widget se despegaban de su esquina. Lo cazó la
   matriz al primer intento: «el HUD no está en la esquina: 49px, tope 48». */
.ww-play-page .ww-player-frame:fullscreen .ww-scaffold,
.ww-play-page .ww-player-frame:-webkit-full-screen .ww-scaffold,
.ww-play-page .ww-player-frame:fullscreen .vs-main,
.ww-play-page .ww-player-frame:-webkit-full-screen .vs-main {
  padding: 5vmin;
}

/* Embedded modes (VS / Equipos / Memoria) need more room than the solo
   aspect-ratio box. When one is active the frame drops its ratio for a taller,
   wider definite-height box; the inner widget keeps filling it (absolute
   inset:0, scrolls if needed). The arenas — designed for the full viewport —
   are re-scoped just below to fill THIS frame instead of 100vh, so they sit
   neatly inside the activity page (and grow with the Pantalla completa button). */
/* MEDIDO (v1.51.581): subir estos topes NO agranda el duelo en una pizarra 4K —
   el ancho lo manda la COLUMNA de la página (~960 px), no este `max-width`, así
   que crecer solo de alto vuelve el marco VERTICAL, dispara el container query de
   `max-aspect-ratio: 5/4` y el marcador se COMPRIME a 46 px: peor que antes.
   Agrandar el duelo dentro de la página exige ensanchar la columna primero (otra
   decisión). Para el aula la vía es «Pantalla completa», donde el marco es 100vh
   y todo el marcador escala con `cqh` como debe. NO tocar sin re-medir. */
.ww-play-page .ww-player-frame.is-expanded {
  aspect-ratio: auto !important;
  max-width: 1100px;
  height: min(80vh, 720px);
}
.ww-play-page .ww-player-frame.is-expanded > #ww-player-widget {
  padding: 0;                /* arenas manage their own padding */
}
/* Re-scope the full-viewport arenas to the embed frame. In real fullscreen the
   frame is 100vh, so 100% still fills the screen — one rule covers both. */
.ww-play-page .ww-player-frame .vs-arena,
.ww-play-page .ww-player-frame .teams-arena {
  height: 100%;
  min-height: 0;
}

/* Active mode button gets a subtle "you are here" cue beyond the solid fill. */
.ww-modes .ww-mode.is-active {
  box-shadow: 0 0 0 3px rgba(0,0,0,.08);
  font-weight: 600;
}

/* Shared SETUP scaffold (views/modeSetup.js) — ONE look for every mode's setup
   so they never drift. Lives inside the stage when embedded. */
.ww-mode-setup { padding: 1.5rem 1rem; }
.ww-mode-setup .ww-mode-setup-body { margin: 0 auto; }
.ww-mode-setup .form-control { max-width: 100%; }

/* Pantalla de INICIO estándar (views/startScreen.js). Vive dentro del escenario
   (#ww-player-widget, container-type:size) → escala con el marco/pantalla
   completa usando unidades de contenedor. Oculta el ejercicio hasta "Iniciar". */
.ww-start {
  width: 100%; min-height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 3cqmin 2cqmin; box-sizing: border-box;
}
.ww-start-card {
  width: min(640px, 100%); text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 2.2cqmin;
}
.ww-start-icon {
  width: clamp(54px, 12cqmin, 110px); height: clamp(54px, 12cqmin, 110px);
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: rgba(25,135,84,.12); color: #198754;
  font-size: clamp(1.6rem, 6cqmin, 3.4rem);
}
.ww-start-title { margin: 0; font-weight: 800; font-size: clamp(1.4rem, 5.2cqmin, 3rem); line-height: 1.1; }
.ww-start-instructions {
  margin: 0; color: var(--ww-muted, #6b7280);
  font-size: clamp(.95rem, 2.6cqmin, 1.4rem); max-width: 52ch;
}
/* OPCIONES DE PARTIDA (core/playOptions.js) — "cómo se gana" y similares. Van
   por encima de los ajustes de ambiente porque cambian el JUEGO. Segmentado y
   con la elección ya marcada: no es un formulario que rellenar. */
.ww-playopts { display: flex; flex-direction: column; gap: .5rem; margin: 0 auto 1rem; max-width: 520px; }
.ww-playopt-label {
  font-size: max(11px, 1.7cqmin); font-weight: 700; letter-spacing: .02em;
  text-transform: uppercase; opacity: .6; margin-bottom: .25rem;
}
.ww-playopt-values { display: flex; gap: .4rem; flex-wrap: wrap; justify-content: center; }
.ww-playopt-btn {
  flex: 1 1 auto; min-width: 40%;
  padding: .55rem .9rem; border-radius: 10px; cursor: pointer;
  border: 2px solid var(--ww-line, #e2e8f0);
  background: var(--ww-card-bg, #fff); color: var(--ww-fg, #1f2937);
  font-size: max(12px, 2cqmin); font-weight: 600;
}
.ww-playopt-btn.is-on {
  border-color: var(--ww-accent, #2563eb);
  background: var(--ww-accent-soft, #eff6ff);
  color: var(--ww-accent-fg, var(--ww-accent, #1d4ed8));
}

.ww-start-settings { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; }
.ww-set-toggle {
  border: 2px solid #e2e8f0; background: #f8fafc; color: #334155;
  border-radius: 12px; padding: .5em .9em; cursor: pointer;
  font-size: clamp(.82rem, 2.2cqmin, 1.1rem); display: inline-flex; align-items: center; gap: .45em;
}
.ww-set-toggle.is-on { border-color: #198754; background: #f0fdf4; color: #166534; }
.ww-set-state { font-weight: 700; opacity: .85; }
.ww-start-go {
  margin-top: 1cqmin; border-radius: 999px;
  font-size: clamp(1.05rem, 3.4cqmin, 1.9rem); padding: .5em 1.8em; font-weight: 700;
}

/* Pickable tiles for skin and background. */
.ww-pick-tile {
  width: 96px;
  cursor: pointer;
  padding: .35rem;
  border-radius: 8px;
  border: 2px solid transparent;
  transition: border-color .12s, transform .1s;
}
.ww-pick-tile:hover { transform: translateY(-2px); }
.ww-pick-tile.is-active {
  border-color: #6366f1;
  box-shadow: 0 0 0 3px rgba(99,102,241,.18);
}

/* Responsive tiles on small screens */
@media (max-width: 600px) {
  .ww-pick-tile { width: 76px; }
}

/* ── Player container queries (respond to the FRAME size, not the viewport) ── */

/* Narrow frame: compact quiz layout */
@container (max-width: 420px) {
  .ww-play-page .ww-player-frame .ww-player { gap: .6rem; }
  .ww-play-page .ww-player-frame .ww-player .ww-q { font-size: clamp(.85rem, 5cqmin, 1.4rem); }
  .ww-play-page .ww-player-frame .ww-player .ww-opt-grid .btn {
    font-size: clamp(.8rem, 3cqmin, 1.1rem);
    padding: clamp(.35rem, 2cqh, .9rem);
  }
}

/* LA MEDIDA DEL MARCO LA PONE EL ALTO QUE HAY, NO UN NÚMERO (dueño,
   2026-08-15, con captura: «la actividad no está a la medida del player»).
   Había un tope plano de 800px: en una pantalla de 1920×1030 el ejercicio
   ocupaba 800×500 y el resto era fondo vacío — y en la pizarra del aula, que es
   ancha y baja, pasaba lo mismo. El marco tiene una PROPORCIÓN declarada por la
   plantilla (`meta.aspectRatio`), así que su ancho máximo se DEDUCE del alto
   libre: `alto disponible × proporción`. Así crece hasta donde llega la
   pantalla y ni desborda por abajo ni deja una franja muerta.
   `--ww-ar` lo escribe `views/playerView.js` junto al `aspect-ratio` (una sola
   fuente: la proporción de la plantilla). El tope duro de 1400px es para que en
   un monitor 21:9 el texto no quede a metro y medio de ancho.
   El descuento de alto cubre la barra superior + el aire de la página; en
   pantalla completa mandan las reglas `:fullscreen` de arriba. */
/* Y VA EN TODOS LOS ANCHOS, no solo en pantalla grande. Estuvo dentro de un
   `@media (min-width: 1100px)` mientras la proporción se aplicaba SIEMPRE: en un
   móvil apaisado (844x390) el marco salía 720x540 sobre 334px de alto útil y el
   documento desbordaba 227px. El tope por ancho sigue siendo el de cada tramo
   —720 normal, 1400 en pantalla grande—; lo que ahora acompaña a los dos es el
   tope por ALTO, que es el que impide el scroll. */
.ww-play-page .ww-player-frame {
  max-width: min(720px, calc((100dvh - var(--ww-topbar-h, 56px) - 74px) * var(--ww-ar, 1.6)));
}
@media (min-width: 1100px) {
  .ww-play-page .ww-player-frame {
    max-width: min(1400px, calc((100dvh - var(--ww-topbar-h, 56px) - 74px) * var(--ww-ar, 1.6)));
  }
}

/* ── VENTANA CLARAMENTE VERTICAL: la proporción es un OBJETIVO, no una jaula ──
   El TERCER caso de «pantalla completa suelta la proporción» (§ la forma del
   marco de juego), y estaba previsto sin escribir. Medido en un móvil de
   390x844 con el marco 4/3: 358x269 — el juego se quedaba con el **29 % de la
   pantalla** y ~445 px de alto muerto debajo. La proporción está para que la
   mecánica tenga la forma que pide, no para tirar dos tercios del teléfono del
   alumno.
   Y tiene un segundo efecto que importa igual: con el marco apaisado a la
   fuerza, el reflujo por forma del andamio (`aspect-ratio < 1/1`) era
   INALCANZABLE en las 13 — el contenedor nunca era vertical. Al soltar la
   proporción aquí, los rieles del andamio, las pistas del crucigrama y el banco
   de la sopa vuelven a poder bajar, sin un solo breakpoint de píxeles.
   El corte es 3/4: más vertical que eso ya no es «una pantalla apaisada de
   lado», es un teléfono en la mano. */
@media (max-aspect-ratio: 3/4) {
  .ww-play-page .ww-player-frame {
    aspect-ratio: auto;
    max-width: 100%;
    /* El alto que queda tras la barra y el aire de la página. */
    height: calc(100dvh - var(--ww-topbar-h, 56px) - 74px);
  }
}
