:root {
    --fondo: #14171c;
    --superficie: #1c2028;
    --superficie-alta: #262b35;
    --borde: #333947;
    --texto: #eef1f6;
    --texto-suave: #9aa3b2;
    --primario: #4f8cff;
    --primario-oscuro: #2f6de0;
    --peligro: #e5484d;
    --exito: #34c481;
    --radio: 14px;
}
* { box-sizing: border-box; }
body {
    margin: 0;
    font-family: 'Segoe UI', system-ui, sans-serif;
    background: var(--fondo);
    color: var(--texto);
}
a { color: var(--primario); }

/* La pagina de chat no scrollea nunca: sin cabecera, .cv-main es el unico hijo y llena
   el alto disponible (el padding, por box-sizing:border-box, ya se lo resta a esos 100vh
   — asi el margen no hace que la pagina termine midiendo mas que la pantalla). */
body.pagina-chat { height: 100vh; overflow: hidden; padding: 8px; }
/* En mobile, 100vh incluye la barra de direccion de Safari/Chrome (se esconde al
   scrollear), asi que "el alto de la pantalla" cambia solo y el layout salta. 100dvh
   es el alto real visible en cada momento — se pisa aparte porque un navegador que no
   entiende "dvh" descarta TODA la declaracion, no solo el valor. */
@supports (height: 100dvh) {
    body.pagina-chat { height: 100dvh; }
}

.landing {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.landing-caja {
    max-width: 460px;
    width: 100%;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    padding: 32px;
}
.landing-caja h1 {
    margin: 0 0 6px;
    font-size: 1.6rem;
}
.landing-caja p.subtitulo {
    color: var(--texto-suave);
    margin: 0 0 24px;
}
.modo-grupo {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}
.modo-boton {
    flex: 1;
    padding: 12px;
    border-radius: 10px;
    border: 1px solid var(--borde);
    background: var(--superficie-alta);
    color: var(--texto);
    text-align: center;
    font-size: 0.9rem;
    cursor: default;
}
.aviso-caja {
    background: rgba(79,140,255,0.08);
    border: 1px solid rgba(79,140,255,0.25);
    border-radius: 10px;
    padding: 12px 14px;
    font-size: 0.82rem;
    color: var(--texto-suave);
    margin-bottom: 18px;
    line-height: 1.5;
}
.check-fila {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 20px;
    font-size: 0.88rem;
    color: var(--texto-suave);
}
.check-fila input { margin-top: 3px; }
.btn {
    display: inline-block;
    border: none;
    border-radius: 10px;
    padding: 12px 20px;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    text-align: center;
}
.btn-primario { background: var(--primario); color: white; width: 100%; }
.btn-primario:hover { background: var(--primario-oscuro); }
.btn-primario:disabled { background: #3a4150; color: var(--texto-suave); cursor: not-allowed; }

.legal { padding: 40px 24px; max-width: 720px; margin: 0 auto; line-height: 1.7; color: var(--texto-suave); }
.legal h1 { color: var(--texto); }
.legal a.volver { display: inline-block; margin-bottom: 20px; }

/* ---- Chat / video / pizarra ---- */
.cv-main { display: flex; height: 100%; }

/* Dos videos que entre los dos ocupan el 100% del alto disponible. El ANCHO de la
 * columna se calcula una sola vez (nunca dos veces por separado — eso era lo que dejaba
 * una caja un poco mas chica que la otra por redondeo), con un margen de +36px sobre lo
 * que le tocaria por altura: pedido explicito de sumarle ancho aunque los videos dejen
 * de ser un cuadrado perfecto. El tope de 60vw evita que se dispare en ventanas angostas.
 * El ALTO de cada caja sale de flex:1 repartiendo el alto real disponible en dos mitades
 * exactas, y cada caja se estira al ancho de la columna (comportamiento por defecto de
 * flex en columna). Se probo aspect-ratio + flex:1 primero y no se resolvia bien en este
 * navegador — el ancho terminaba regido por otra cosa en vez de la altura real. */
.cv-col-video { flex-shrink: 0; display: flex; flex-direction: column; width: calc(min(calc(50vh - 8px), 60vw) + 36px); }
.cv-col-video.oculto { display: none; }
.cv-video-box {
    position: relative; flex: 1; min-height: 0;
    overflow: hidden; background: #0c0e12;
}
.cv-video-box video { width: 100%; height: 100%; object-fit: cover; display: block; }
.cv-video-box.local video { transform: scaleX(-1); }
.cv-video-label {
    position: absolute; left: 10px; top: 9px; z-index: 2;
    background: rgba(10,12,16,0.65); padding: 3px 9px; border-radius: 20px;
    font-size: 0.7rem; color: #e4e7ee; letter-spacing: 0.01em;
}
.cv-stage-vacio {
    position: absolute; inset: 0; z-index: 1; display: flex; align-items: center; justify-content: center;
    text-align: center; padding: 16px; font-size: 0.8rem; color: var(--texto-suave); background: #0c0e12;
}

/* Sala GRUPAL (3-4, via SFU) — hermana de .cv-col-video, mismo ancho de columna que
 * ella (asi el resto del layout — rail, panel — no se mueve un pixel al pasar de una a
 * otra), pero con una GRILLA de verdad en vez de flex:1 fijo a 2: a diferencia del
 * camino de 2 (siempre exactamente 2 cajas fijas en el HTML), aca los tiles se arman y
 * desarman por JS segun quien esta conectado, asi que hace falta que se puedan
 * acomodar solos. */
.cv-grid-video {
    flex-shrink: 0; width: calc(min(calc(50vh - 8px), 60vw) + 36px); height: 100%;
    display: grid; grid-template-columns: repeat(2, 1fr); align-content: center; gap: 4px;
}
.cv-grid-video.oculto { display: none; }
.cv-tile { position: relative; background: #0c0e12; border-radius: 8px; overflow: hidden; aspect-ratio: 1 / 1; }
.cv-tile video { width: 100%; height: 100%; object-fit: cover; display: block; }
.cv-tile.local video { transform: scaleX(-1); }
.cv-tile-nombre {
    position: absolute; left: 8px; top: 7px; z-index: 2;
    background: rgba(10,12,16,0.65); padding: 3px 9px; border-radius: 20px;
    font-size: 0.7rem; color: #e4e7ee; letter-spacing: 0.01em;
}
.cv-tile-reportar {
    position: absolute; right: 8px; top: 7px; z-index: 2; padding: 0;
    width: 24px; height: 24px; border-radius: 50%; border: none; cursor: pointer;
    background: rgba(10,12,16,0.65); color: #e4e7ee; display: flex; align-items: center; justify-content: center;
}
.cv-tile-reportar svg { width: 12px; height: 12px; }
.cv-tile-reportar:hover { background: rgba(229,72,77,0.6); }
#tamanoGrupoTexto { font-size: 0.8rem; font-weight: 700; }
.cv-boton-mini.oculto { display: none; }

/* Con una sala GRUPAL activa, todo lo pensado para "exactamente un companero" (chat
 * privado, pizarra privada, Snake, el "Reportar" generico del rail) no tiene sentido con
 * 3-4 personas — el reporte pasa a ser por tile (.cv-tile-reportar arriba). Un solo
 * interruptor (la clase en <body>, ver mostrarGrupoVideo() en chat.js) en vez de esconder
 * cada boton por separado desde JS. !important por el mismo motivo que ya se documento en
 * .cv-snake-envoltorio.oculto mas abajo: estos son selectores por ID, y sin esto una regla
 * mas especifica (ej. #vistaPrivado.chat-abierto en el media query de celular) le gana. */
body.sala-grupal-activa .cv-panel-tab[data-vista="privado"],
body.sala-grupal-activa #vistaPrivado,
body.sala-grupal-activa #btnReportar,
body.sala-grupal-activa #btnPaleta,
body.sala-grupal-activa #btnSnake,
body.sala-grupal-activa #btnChatPrivadoToggle {
    display: none !important;
}

/* Barra angosta entre los videos y el chat: microfono/camara arriba, reportar/siguiente
   despues, salir al final — todo junto, chico y sin robarle alto a los cuadrados. */
.cv-rail {
    width: 60px; flex-shrink: 0; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 10px; background: var(--superficie);
    border-left: 1px solid var(--borde); border-right: 1px solid var(--borde);
}
.cv-rail-sep { width: 26px; height: 1px; background: var(--borde); }
.cv-boton-mini {
    position: relative; width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--borde); cursor: pointer;
    background: var(--superficie-alta); color: var(--texto);
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.cv-boton-mini svg { width: 16px; height: 16px; }
.cv-boton-mini:hover { background: #323848; border-color: #454c5c; }
.cv-boton-mini:active { transform: scale(0.92); }
.cv-boton-mini.apagado { background: var(--texto); color: var(--fondo); border-color: var(--texto); }
.cv-boton-mini.siguiente { background: var(--exito); color: #06251a; border-color: var(--exito); }
.cv-boton-mini.siguiente:hover { background: #2bb073; }
.cv-boton-mini.reportar:hover { background: rgba(234,179,8,0.25); border-color: #a16207; }
.cv-boton-mini.colgar { background: var(--peligro); color: white; border-color: var(--peligro); }
.cv-boton-mini.colgar:hover { background: #c33d41; }
.cv-boton-mini.activo { background: var(--primario); color: #fff; border-color: var(--primario); }

/* ---- Panel: chat y pizarra son LA MISMA superficie (mismo fondo, se funden) — se
   alterna que se ve, nunca cambia de color entre una y otra. ---- */
.cv-panel {
    flex: 1; min-width: 160px; border-left: 1px solid var(--borde);
    display: flex; flex-direction: column; min-height: 0; position: relative;
}

/* Tres pestañas: privado (con quien te toco) y el grupal (chat + pizarra), que corre en
   paralelo — cambiar de pestaña no lo pausa, solo cambia que ves. */
.cv-panel-tabs { display: flex; border-bottom: 1px solid var(--borde); flex-shrink: 0; }
.cv-panel-tab { position: relative; flex: 1; padding: 10px 6px; text-align: center; background: none; border: none; color: var(--texto-suave); cursor: pointer; font-size: 0.8rem; font-family: inherit; }
.cv-panel-tab.activa { color: var(--texto); border-bottom: 2px solid var(--primario); }
.cv-panel-vista { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.cv-panel-vista.oculto { display: none; }

.cv-superficie { flex: 1; position: relative; min-height: 0; background: var(--fondo); }

.cv-chat-lista { position: absolute; inset: 0; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; z-index: 1; }
.cv-msg { max-width: 85%; padding: 8px 12px; border-radius: 12px; font-size: 0.88rem; line-height: 1.4; }
.cv-msg.propio { align-self: flex-end; background: var(--primario); color: white; border-bottom-right-radius: 3px; }
.cv-msg.otro { align-self: flex-start; background: var(--superficie-alta); border-bottom-left-radius: 3px; }
.cv-msg.sistema { align-self: center; color: var(--texto-suave); font-size: 0.78rem; background: none; }

/* La pizarra es una capa transparente ENCIMA del chat, siempre presente — no una vista
 * aparte que lo reemplaza. Lo que cambia con el boton de paleta es solo si el canvas
 * captura el puntero (para poder seguir scrolleando/leyendo el chat cuando no estas
 * dibujando); lo ya dibujado se sigue viendo siempre, con el chat detras. */
#pizarraCanvas {
    position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2;
    background: transparent; touch-action: none; pointer-events: none;
}
#pizarraCanvas.activa { pointer-events: auto; cursor: crosshair; }

/* La pizarra GRUPAL no esta superpuesta a nada (tiene su propia pestaña) — el canvas
   capta el puntero siempre, no hace falta boton de paleta para activarlo. */
#pizarraCanvasGrupal {
    position: absolute; inset: 0; width: 100%; height: 100%;
    background: transparent; touch-action: none; pointer-events: auto; cursor: crosshair;
}

/* Herramientas de la pizarra PRIVADA: flotan arriba del todo, solo mientras se esta
 * dibujando — no empujan ni esconden el chat, se superponen igual que el propio dibujo. */
.cv-pizarra-toolbar {
    position: absolute; top: 0; left: 0; right: 0; z-index: 3;
    display: flex; align-items: center; padding: 8px 10px;
    background: var(--superficie-alta); border-bottom: 1px solid var(--borde);
}
.cv-pizarra-toolbar.oculto { display: none; }
/* La de la pizarra GRUPAL no flota: es la unica cosa en su pestaña, va en flujo normal
   arriba del canvas, siempre visible (no hay nada debajo que tape). */
#vistaGrupalPizarra .cv-pizarra-toolbar { position: static; flex-shrink: 0; }

/* Dos filas fijas (herramienta+grosor / color+vaciar) en vez de dejar que el
   navegador corte donde quiera segun el ancho — mas prolijo y predecible. */
.pizarra-tools { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.pizarra-fila { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; width: 100%; }
.pizarra-grupo { display: flex; align-items: center; gap: 4px; }
.pizarra-colores { display: flex; gap: 4px; flex-wrap: wrap; }
.pizarra-tinta { width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--superficie-alta); box-shadow: 0 0 0 1px var(--borde); cursor: pointer; padding: 0; }
.pizarra-tinta.activa { box-shadow: 0 0 0 2px var(--primario); }
.pizarra-herr { width: 28px; height: 26px; border: 1px solid var(--borde); background: var(--superficie); border-radius: 6px; cursor: pointer; color: var(--texto-suave); font-size: 0.75rem; }
.pizarra-herr.activo { background: var(--primario); color: white; border-color: var(--primario); }
.pizarra-flecha { border: 1px solid var(--borde); background: var(--superficie); color: var(--texto-suave); width: 20px; height: 24px; border-radius: 6px; cursor: pointer; font-size: 0.65rem; }
/* Vaciar es una accion aparte (destructiva): queda al extremo derecho, con texto para
   que nadie la confunda con una herramienta mas. */
.pizarra-vaciar {
    width: auto; margin-left: auto; display: flex; align-items: center; gap: 5px; padding: 0 10px;
    color: var(--peligro); border-color: rgba(229,72,77,0.35);
}
.pizarra-vaciar svg { width: 13px; height: 13px; }
.pizarra-vaciar:hover { background: rgba(229,72,77,0.15); border-color: var(--peligro); }

/* ---- Snake: a diferencia de la pizarra, esto TAPA el chat (fondo opaco) — no tendria
   sentido jugar con mensajes asomando debajo. Es excluyente con la pizarra (JS se
   encarga de apagar una al prender la otra). ---- */
.cv-snake-envoltorio { position: absolute; inset: 0; z-index: 4; background: var(--fondo); }
/* !important a proposito: la version celular le pone "display:flex" a #envoltorioSnake
   con un selector de ID (para partirlo en mapa arriba / controles abajo, ver media
   query mas abajo) — un ID le gana SIEMPRE a una clase en especificidad, asi que sin
   este !important esa regla le ganaba a este .oculto y Snake quedaba visible SIEMPRE
   en celular, sin importar el estado real (eso fue lo que reporto el usuario: "entro
   a la pagina y ya esta en Snake, no puedo salir"). */
.cv-snake-envoltorio.oculto { display: none !important; }
#snakeCanvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.cv-snake-aviso {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 5;
    background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--radio);
    padding: 22px 28px; text-align: center; box-shadow: 0 10px 28px rgba(0,0,0,0.45);
    min-width: 220px;
}
.cv-snake-aviso.oculto { display: none; }
#snakeAvisoTexto { font-size: 1.1rem; font-weight: 700; }
#snakeAvisoTexto.cv-snake-cuenta { font-size: 2.4rem; }
.cv-snake-aviso-botones { display: flex; gap: 10px; margin-top: 14px; }
.cv-snake-aviso-botones:empty { margin-top: 0; }
.cv-snake-aviso-botones button {
    flex: 1; border: none; border-radius: 10px; padding: 9px 16px; cursor: pointer;
    font-family: inherit; font-size: 0.88rem; background: var(--superficie-alta); color: var(--texto);
}
.cv-snake-aviso-botones button.primario { background: var(--primario); color: white; }
.cv-snake-aviso-botones button.cancelar:hover { background: rgba(229,72,77,0.2); color: var(--peligro); }

.cv-chat-form { display: flex; align-items: center; gap: 8px; padding: 12px; border-top: 1px solid var(--borde); flex-shrink: 0; }
/* Envoltorio transparente para el layout: agrupa paleta/snake/grupal para poder
   esconderlos juntos en celular (ver media query) sin que en escritorio cambie nada —
   ahi es como si no estuviera, mismo gap que el resto de la fila. */
.cv-chat-iconos-extra { display: flex; align-items: center; gap: 8px; }
.cv-chat-form input {
    flex: 1; min-width: 0; background: var(--superficie-alta); border: 1px solid var(--borde); border-radius: 20px;
    padding: 9px 14px; color: var(--texto); font-size: 0.88rem;
}
.cv-chat-form button[type="submit"] { background: var(--primario); color: white; border: none; border-radius: 20px; padding: 0 16px; height: 36px; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 6px; }
/* En celular el boton de enviar es solo el icono (ver media query) — en escritorio se
   ve el texto de siempre y el icono ni se dibuja. */
.cv-enviar-icono { display: none; }
.cv-boton-icono {
    position: relative; width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--borde); cursor: pointer; flex-shrink: 0;
    background: var(--superficie-alta); color: var(--texto); display: flex; align-items: center; justify-content: center;
    transition: background 0.15s ease;
}
.cv-boton-icono svg { width: 17px; height: 17px; }
.cv-boton-icono:hover { background: #323848; }
.cv-boton-icono.activo { background: var(--primario); color: #fff; border-color: var(--primario); }

/* Notificacion: circulo rojo con numero, para chat privado / chat grupal / pizarra
   grupal — se posiciona sobre el boton o pestaña que lo declara (todos son
   position:relative). Vive en un mismo lugar para escritorio y celular; el JS solo
   la muestra/oculta y le cambia el numero, ver pintarBadge() en chat.js. */
.cv-badge {
    display: none; position: absolute; top: -3px; right: -3px; z-index: 3;
    min-width: 16px; height: 16px; padding: 0 3px; border-radius: 8px;
    background: var(--peligro); color: #fff; font-size: 0.62rem; font-weight: 700;
    line-height: 16px; text-align: center; font-family: inherit; pointer-events: none;
}
.cv-badge.visible { display: block; }
/* En las pestañas de escritorio (texto + badge, no un circulo aparte) el numero va
   pegado despues del texto, no flotando arriba a la derecha del boton entero. */
/* OJO ACA: esta regla de reposicionamiento NO debe tocar "display" — un selector de
   dos clases (".cv-panel-tab .cv-badge") le gana en especificidad a ".cv-badge"
   (una sola), asi que un "display" puesto aca le ganaria SIEMPRE a "display:none"
   de la regla base, mostrando el circulo con "0" todo el tiempo (bug real que hubo).
   El display lo sigue controlando unicamente ".visible", mas abajo. */
.cv-panel-tab .cv-badge, .cv-grupal-tab-movil .cv-badge {
    position: static; margin-left: 5px; vertical-align: middle; top: auto; right: auto;
}
.cv-panel-tab .cv-badge.visible, .cv-grupal-tab-movil .cv-badge.visible { display: inline-block; }

.cv-reporte-overlay {
    position: fixed; inset: 0; background: rgba(0,0,0,0.6); z-index: 50;
    display: flex; align-items: center; justify-content: center;
}
.cv-reporte-caja {
    background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--radio);
    padding: 24px; width: 320px;
}
.cv-reporte-caja select, .cv-reporte-caja textarea {
    width: 100%; background: var(--superficie-alta); border: 1px solid var(--borde); color: var(--texto);
    border-radius: 8px; padding: 8px; margin: 8px 0; font-family: inherit;
}
.cv-reporte-acciones { display: flex; gap: 10px; margin-top: 10px; }
.cv-reporte-acciones button { flex: 1; padding: 9px; border-radius: 8px; border: none; cursor: pointer; }
.btn-cancelar { background: var(--superficie-alta); color: var(--texto); }
.btn-reportar { background: var(--peligro); color: white; }

/* Carteles del D-pad tactil de Snake: solo existen visualmente en la media query de
   celular (mas abajo). En escritorio quedan en display:none siempre, no hace falta
   tocarlos ahi porque las flechas del teclado ya funcionan. El JS los muestra/oculta
   con la clase "oculto" igual que el resto del cartel de Snake — por eso esa clase
   vive fuera de la media query, para poder ganarle a "display:flex" este donde este. */
.cv-snake-controles-tactiles { display: none; }
.cv-snake-controles-tactiles.oculto { display: none !important; }

/* Elementos que SOLO existen en la version celular (botones nuevos, cabecera de
   "Grupal", cruces para cerrar) — en escritorio ni se dibujan. La cabecera de Grupal
   ademas se prende/apaga con JS aparte (empieza oculta), por eso su propio .oculto
   vive afuera de la media query — para poder ganarle a "display:flex" este donde este,
   mismo patron que ya se usaba con el D-pad de Snake. */
.cv-solo-movil { display: none; }
.cv-grupal-cabecera-movil.oculto { display: none !important; }

/* ---- Celular: cada seccion pasa a ocupar TODA la pantalla al abrirse (Snake, pizarra
   privada, pizarra grupal, chat grupal) — asi sus propios controles (D-pad, paleta de
   colores, etc.) tienen todo el mapa/lienzo para si y no se pisan con nada. La UNICA
   excepcion es el chat privado: como siempre queres poder ver a la otra persona, ese
   NO tapa toda la pantalla — es un panel que se despliega hacia arriba tapando solo tu
   propio video (el de abajo). La vista base (nada abierto) son los dos videos, uno
   arriba y otro abajo, con los botones/accesos a todo lo demas pegados abajo del todo.
   El ancho de corte (760px) cubre celulares en vertical y la mayoria en horizontal. ---- */
@media (max-width: 760px) {
    body.pagina-chat { padding: 0; }
    .cv-main { flex-direction: column; gap: 0; position: relative; }

    /* Los dos videos, apilados, llenando todo lo que sobra despues de la barra de
       controles y el renglon de chat de abajo (flex:1 en la columna se encarga solo). */
    .cv-col-video { width: 100%; flex: 1 1 auto; min-height: 0; }
    .cv-video-box { min-width: 0; }
    .cv-video-label { font-size: 0.7rem; padding: 3px 9px; }
    .cv-grid-video { width: 100%; height: auto; flex: 1 1 auto; min-height: 0; grid-auto-rows: 1fr; }

    /* Controles de la llamada: se acuestan, quedan pegados abajo (arriba del renglon
       del chat) — objetivo tactil comodo. */
    /* Alto FIJO (no "auto"): el panel de chat privado, mas abajo, necesita saber
       exactamente cuanto miden esta barra y el renglon de escribir para calcular su
       propia altura y tapar SOLO el video propio — ni un pixel de la barra de arriba. */
    .cv-rail {
        width: 100%; height: 57px; flex-direction: row;
        border-left: none; border-right: none;
        border-top: 1px solid var(--borde);
        padding: 6px 4px; gap: 6px;
    }
    .cv-rail-sep { width: 1px; height: 22px; }
    .cv-boton-mini { width: 44px; height: 44px; }
    .cv-boton-mini svg { width: 19px; height: 19px; }

    /* El panel deja de ser "una vista a la vez estirada" — en celular su unico rol
       fijo es alojar el renglon de chat privado (siempre visible, pegado abajo del
       todo); las pestañas de arriba no se usan mas, hay botones nuevos para eso. */
    .cv-panel { min-width: 0; border-left: none; flex: 0 0 auto; position: static; }
    .cv-panel-tabs { display: none; }

    /* ---- Renglon de abajo (chat/paleta/snake/grupal): arranca COLAPSADO (alto 0)
       para darle mas pantalla a las camaras — el boton "menu" en la barra de arriba
       (#btnMenuMovil) lo despliega. #vistaPrivado pasa a flex:auto (en vez de un alto
       fijo) para que, al colapsar su unico hijo en flujo normal (.cv-chat-form), la
       columna de video recupere ese espacio solita via reflow de flexbox — no hace
       falta animar nada mas a mano. ---- */
    #vistaPrivado { flex: 0 0 auto; }
    #vistaPrivado .cv-chat-form {
        max-height: 0; padding: 0 8px; border-top-width: 0; opacity: 0; overflow: hidden;
        transition: max-height 0.22s ease, padding 0.22s ease, opacity 0.15s ease, border-width 0.22s ease;
    }
    #vistaPrivado.menu-abierto .cv-chat-form {
        max-height: 80px; padding: 8px; border-top-width: 1px; opacity: 1;
    }

    /* ---- Chat privado: el unico que NO es pantalla completa. Su .cv-superficie
       (mensajes) se despega y flota justo encima del video propio — no de
       #vistaPrivado! Entre uno y otro esta la barra de controles (57px) y, SI el
       renglon de abajo esta desplegado, tambien ese (59px) — por eso el offset tiene
       dos valores segun .menu-abierto, no uno fijo. (Bug real que hubo: con un solo
       "bottom:116px" fijo, al estar el menu colapsado esos 116px no correspondian a
       nada real — el borde de arriba de este panel quedaba flotando 59px mas arriba
       de lo que debia, cruzando el video de la otra persona con una linea suelta,
       aunque el panel siguiera con alto:0 y sin abrirse.) Se ancla contra .cv-main
       (que por eso es position:relative, mas arriba), no con "bottom:100%" — ese solo
       conoce el borde de su propio contenedor inmediato. Colapsado (alto 0) por
       defecto; el boton de globo lo abre. ---- */
    #vistaPrivado .cv-superficie {
        position: absolute; left: 0; right: 0; bottom: 57px; /* sin el renglon desplegado: solo .cv-rail */
        height: 0; overflow: hidden; z-index: 15; background: var(--fondo);
        border-top: 1px solid var(--borde);
        transition: height 0.22s ease, bottom 0.22s ease;
    }
    #vistaPrivado.menu-abierto .cv-superficie { bottom: 116px; /* con el renglon desplegado: rail + renglon */ }
    /* Alto exacto = mitad de lo que le queda a la columna de video — la MISMA cuenta
       que ya hace el flex:1 de los dos videos, asi el panel cubre el video propio
       pixel a pixel, ni un poco de mas (tapando la barra) ni de menos (dejando un
       resto de video visible). */
    #vistaPrivado.chat-abierto .cv-superficie { height: calc((100vh - 116px) / 2); }
    @supports (height: 100dvh) {
        #vistaPrivado.chat-abierto .cv-superficie { height: calc((100dvh - 116px) / 2); }
    }
    /* Bordes conditional a "chat-abierto": asi, pase lo que pase con el alto o el
       offset en cualquier estado intermedio, cerrado nunca dibuja una linea suelta
       (grosor 0 = nada, por mas que el navegador calcule una posicion para ella). */
    #vistaPrivado .cv-superficie { border-top-width: 0; }
    #vistaPrivado.chat-abierto .cv-superficie { border-top-width: 1px; }

    /* La pizarra privada, a pedido, pasa a pantalla completa (probamos que compartiera
       el cajon del chat y quedaba muy chica para dibujar) — igual que Snake: fondo
       solido (separada del chat, nunca fundidos como en escritorio, donde el canvas
       sigue transparente a proposito) y cubre todo. */
    #pizarraCanvas.activa { position: fixed !important; inset: 0 !important; z-index: 45; background: var(--fondo); }
    #pizarraToolbar {
        position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important;
        z-index: 46; padding: 8px; padding-right: 54px; /* hueco a la derecha para la cruz, ver abajo */
        padding-top: max(8px, env(safe-area-inset-top));
    }
    #pizarraToolbar .pizarra-tools { gap: 6px; }
    #pizarraToolbar .pizarra-fila { gap: 6px; }
    #pizarraToolbar .pizarra-grupo { gap: 3px; }
    #pizarraToolbar .pizarra-colores { gap: 3px; }
    /* La cruz NO va adentro del renglon de herramientas (ahi quedaba mal — una fila
     * de botones que se corta a la mitad, con la cruz larga al lado, sin relacion
     * visual clara). Flota arriba a la derecha, como en Snake, para que el renglon de
     * herramientas quede compacto y prolijo, ocupando todo su ancho el solo. */
    .cv-pizarra-cerrar-movil {
        position: absolute; top: max(8px, env(safe-area-inset-top)); right: 8px; z-index: 47;
    }

    #envoltorioSnake { position: fixed !important; inset: 0 !important; z-index: 45; display: flex; flex-direction: column; }
    /* El mapa arriba del todo, ocupando lo que sobra; los controles van DEBAJO, en su
     * propio espacio (no flotando encima) — antes el D-pad se superponia al mapa y
     * tapaba celdas de juego. */
    #snakeCanvas { position: static; flex: 1 1 0; min-height: 0; }
    .cv-snake-cerrar-movil {
        position: absolute; top: max(10px, env(safe-area-inset-top)); right: 10px; z-index: 7;
        width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--borde);
        background: rgba(38,43,53,0.85); color: var(--texto); align-items: center; justify-content: center;
    }
    .cv-snake-cerrar-movil svg { width: 16px; height: 16px; }

    /* ---- "Grupal" (chat + pizarra, un boton, pantalla completa con subpestañas
       adentro). La cabecera queda fija arriba de todo; el contenido de cada vista
       empieza mas abajo (padding-top) para no quedar tapado por ella. ---- */
    #vistaGrupalChat, #vistaGrupalPizarra { position: fixed; inset: 0; z-index: 40; padding-top: 48px; }
    .cv-grupal-cabecera-movil {
        position: fixed; top: 0; left: 0; right: 0; z-index: 42; height: 48px;
        align-items: center; background: var(--superficie); border-bottom: 1px solid var(--borde);
        padding-top: env(safe-area-inset-top);
    }
    .cv-grupal-tab-movil {
        position: relative; flex: 1; height: 100%; background: none; border: none; color: var(--texto-suave);
        font-family: inherit; font-size: 0.85rem; cursor: pointer;
    }
    .cv-grupal-tab-movil.activa { color: var(--texto); box-shadow: inset 0 -2px 0 var(--primario); }
    .cv-grupal-cerrar-movil {
        flex-shrink: 0; width: 44px; height: 100%; background: none; border: none;
        color: var(--texto-suave); display: flex; align-items: center; justify-content: center; cursor: pointer;
    }
    .cv-grupal-cerrar-movil svg { width: 18px; height: 18px; }

    /* Renglon de chat privado (siempre visible, abajo del todo). */
    .cv-chat-form { padding: 8px; gap: 6px; }
    .cv-chat-form input { padding: 10px 14px; font-size: 16px; } /* 16px: evita el zoom automatico de iOS al enfocar */
    .cv-boton-icono, .cv-chat-form button[type="submit"] { width: 42px; height: 42px; flex-shrink: 0; }
    .cv-chat-form button[type="submit"] { padding: 0; border-radius: 50%; }
    .cv-enviar-texto { display: none; }
    .cv-enviar-icono { display: block; width: 18px; height: 18px; }
    .cv-solo-movil { display: flex; }
    .cv-chat-iconos-extra { gap: 6px; }

    /* Con el chat activo (cajon abierto, boton de globo apretado), paleta/snake/
     * grupal se esconden como grupo y el input (que ya es flex:1) crece solo para
     * ocupar ese lugar — no hace falta animar el input, el reflow de flexbox alcanza
     * y da el efecto de "entra desde la derecha" a medida que el grupo se achica. */
    .cv-chat-iconos-extra {
        max-width: 200px; opacity: 1; overflow: hidden;
        transition: max-width 0.22s ease, opacity 0.15s ease;
    }
    #vistaPrivado.chat-abierto .cv-chat-iconos-extra {
        max-width: 0; opacity: 0; pointer-events: none;
    }

    /* Pizarra: herramientas un poco mas grandes para dedos (hay pantalla entera ahora),
       pero no tanto como para que colores+vaciar no entren juntos en su fila. */
    .pizarra-herr, .pizarra-flecha { width: 32px; height: 30px; }
    .pizarra-tinta { width: 22px; height: 22px; }
    .pizarra-vaciar { padding: 0 8px; }

    /* D-pad + boton de impulso para Snake: van DEBAJO del mapa (que es el flex:1 de
     * arriba, ver #snakeCanvas), en su propia franja de alto fijo, centrados como un
     * solo grupo — ya no flotan encima tapando celdas de juego. */
    .cv-snake-controles-tactiles {
        display: flex; position: static; flex: 0 0 auto; z-index: 6;
        justify-content: center; align-items: center; gap: 32px;
        padding: 14px 16px calc(14px + env(safe-area-inset-bottom));
    }
    .cv-snake-dpad { display: flex; flex-direction: column; align-items: center; gap: 4px; }
    .cv-snake-dpad-fila { display: flex; gap: 4px; }
    .cv-snake-dpad-boton, .cv-snake-dpad-hueco { width: 48px; height: 48px; }
    .cv-snake-dpad-hueco { visibility: hidden; }
    .cv-snake-dpad-boton {
        border: 1px solid var(--borde); border-radius: 10px; background: rgba(38,43,53,0.85);
        color: var(--texto); display: flex; align-items: center; justify-content: center;
        touch-action: none; -webkit-tap-highlight-color: transparent;
    }
    .cv-snake-dpad-boton svg { width: 20px; height: 20px; }
    .cv-snake-dpad-boton:active { background: var(--primario); border-color: var(--primario); }
    .cv-snake-boost-boton {
        width: 60px; height: 60px; border-radius: 50%; border: 1px solid var(--borde);
        background: rgba(38,43,53,0.85); color: #EAB308; display: flex; align-items: center; justify-content: center;
        touch-action: none; -webkit-tap-highlight-color: transparent;
    }
    .cv-snake-boost-boton svg { width: 26px; height: 26px; }
    .cv-snake-boost-boton:active { background: #EAB308; color: #241c00; border-color: #EAB308; }

    /* Landing / elegir-nombre: menos aire en pantallas chicas. */
    .landing { padding: 16px; }
    .landing-caja { padding: 22px 18px; }
    .landing-caja h1 { font-size: 1.35rem; }
}

/* ---- Admin ---- */
.admin-wrap { max-width: 960px; margin: 0 auto; padding: 30px 20px; }
.admin-wrap h1 { margin-bottom: 4px; }
.admin-stats { display: flex; gap: 14px; margin: 18px 0 28px; }
.admin-stat { background: var(--superficie); border: 1px solid var(--borde); border-radius: 10px; padding: 14px 18px; }
.admin-stat b { display: block; font-size: 1.4rem; }
table.admin-tabla { width: 100%; border-collapse: collapse; background: var(--superficie); border-radius: 10px; overflow: hidden; margin-bottom: 30px; }
table.admin-tabla th, table.admin-tabla td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--borde); font-size: 0.85rem; }
table.admin-tabla th { color: var(--texto-suave); font-weight: 600; }
table.admin-tabla code { font-size: 0.72rem; color: var(--texto-suave); }
.admin-form-login { max-width: 320px; margin: 80px auto; background: var(--superficie); padding: 26px; border-radius: var(--radio); border: 1px solid var(--borde); }
.admin-form-login input { width: 100%; padding: 9px; margin: 6px 0 14px; border-radius: 8px; border: 1px solid var(--borde); background: var(--superficie-alta); color: var(--texto); }
