/*
  LA PALETTA ES LA DE LA FAMILIA, CON SUS NOMBRES.

  Y los nombres son la mitad que importa. Antes esto declaraba tokens `--bf-*` «de Bifrost», con la
  intención correcta —un servicio no tiene paleta propia— y el vocabulario equivocado: ese prefijo no
  lo escribe ningún producto que esté corriendo. Los dos que sí corren, Hugin y Mimir, pintan con
  `--panel-color`, `--highlight-color`, `--hairline-color`; una sala embebida en Hugin con `--bf-*`
  no hereda nada y se ve de otra casa, que es justo lo contrario de para lo que existe `<bragi-room>`.

  Origen: `verdandi/docs/estilos-general.md` §1 —«adoptar verbatim»— y `hugin/src/front/styles/app.css`,
  que es la implementación de referencia. Los valores se copian; NO se retocan «para que pegue».

  Lo que Bragi decide de la §2 (estructura), y queda escrito aquí para no volver a decidirlo:

    · Tema base ....... OSCURO en :root, claro como override DESPUÉS. El orden decide: misma
                        especificidad, gana el último.
    · Superficies ..... Fondos opacos, pieles de velo. Una tarjeta es un velo del color de panel
                        sobre el degradado de la vista, y lo que la separa del fondo es su filete,
                        no un relleno.
    · Entrada ......... De escritorio hacia abajo. Una sala es una superficie de trabajo.
    · Sin empaquetador. Hugin y Mimir traen Tailwind v4 + webpack; aquí es CSS a mano servido desde
                        el ensamblado. Es una decisión del paso 1 y NO afecta a lo de arriba: lo que
                        hace familia son los tokens, no quién los compila.
*/

/* ----- Tokens: oscuro, que es la base ----------------------------------------------------- */

:root,
:root[data-theme="dark"] {
  --canvas-color: #171B1E;
  --mesa-canvas-color: #1E2327;
  --panel-color: #2C3239;
  --panel-2-color: #30373E;
  --field-color: #444D57;
  --card-surface-color: var(--panel-color);
  --view-glow-color: #262C33;

  --hairline-color: rgba(174, 182, 191, 0.16);
  --hover-color: rgba(174, 182, 191, 0.11);
  --bevel-hi-color: rgba(255, 255, 255, 0.11);
  --bevel-lo-color: rgba(255, 255, 255, 0.05);
  --selected-color: rgba(174, 182, 191, 0.11);
  --field-veil-color: rgba(174, 182, 191, 0.07);
  --disabled-ink: 0.45;

  --control-color: #2B2F33;
  --control-hover-color: #373C40;

  --text-color: #FEFEFE;
  --muted-color: #B4BDC7;
  --frame-text-color: #F6F7F8;
  --frame-muted-color: #9DA6B2;

  /* NARANJA DE MARCA, EL MISMO EN LOS DOS TEMAS. Dice «esto es nuestro / estás aquí»; lo que dice
     «esto hace algo» es el azul. Un producto que usa el naranja para todo lo interactivo pierde la
     única cosa para la que sirve un acento. */
  --highlight-color: #EE7A24;
  --highlight-edge-color: #F49A5C;
  --action-color: #2E7FC2;

  /* El botón principal NO es el naranja de marca: medido, el naranja como tinta se queda en 2.8:1.
     Como relleno y como borde va bien; como texto, no. */
  --cta-color: #D9773F;
  --cta-hover-color: #E4874E;
  --on-cta-color: #1A1A1A;

  --ok-color: #68F09D;
  --warn-color: #EED85B;
  --alarm-color: #FF5252;
  --event-color: #3373D9;
  --off-color: #808080;
  --ok-text-color: #68F09D;
  --warn-text-color: #EED85B;
  --alarm-text-color: #FF9B9B;
  --event-text-color: #96B7EB;
  --on-status-text-color: #FFFFFF;

  --shadow-size: 0 1px 2px rgba(0, 0, 0, 0.35), 0 4px 12px -2px rgba(0, 0, 0, 0.45);
  --elevated-color: #383F47;
  --elevated-edge-color: rgba(183, 190, 199, 0.3);
  --glass-drop: 0 10px 26px rgba(0, 0, 0, 0.32);
}

/* ----- Tokens: claro. DESPUÉS del oscuro, y por eso gana ---------------------------------- */

:root[data-theme="light"] {
  --canvas-color: #DBDCDE;
  --mesa-canvas-color: #F5F5F5;
  --panel-color: #F6F6F6;
  --panel-2-color: #EAEAEA;
  --field-color: #FEFEFE;
  --card-surface-color: #FFFFFF;
  --view-glow-color: transparent;

  --hairline-color: rgba(41, 63, 79, 0.16);
  --hover-color: rgba(41, 63, 79, 0.08);
  --bevel-hi-color: rgba(255, 255, 255, 0.85);
  --bevel-lo-color: rgba(41, 63, 79, 0.13);
  --selected-color: rgba(255, 255, 255, 0.7);
  --field-veil-color: rgba(255, 255, 255, 0.66);
  --disabled-ink: 0.6;

  --control-color: #EDEEEF;
  --control-hover-color: #FFFFFF;

  --text-color: #1D3040;
  --muted-color: #383D51;
  --frame-text-color: #1D3040;
  --frame-muted-color: #383D51;

  --highlight-color: #EE7A24;
  --highlight-edge-color: #F49A5C;
  --action-color: #246BA0;

  --cta-color: #E68A50;
  --cta-hover-color: #EF9A63;
  --on-cta-color: #1A1A1A;

  /* El ámbar se parte por tema, y no es capricho: el amarillo pálido es ilegible sobre un panel
     claro. Un relleno ámbar lleva SIEMPRE tinta oscura, nunca blanca. */
  --ok-color: #0E9F42;
  --warn-color: #A16207;
  --alarm-color: #D64545;
  --event-color: #3373D9;
  --off-color: #7B8794;
  --ok-text-color: #096429;
  --warn-text-color: #794A05;
  --alarm-text-color: #A12323;
  --event-text-color: #1F52A5;
  --on-status-text-color: #FFFFFF;

  --shadow-size: 0 1px 2px rgba(41, 63, 79, 0.05), 0 4px 12px -2px rgba(41, 63, 79, 0.1);
  --elevated-color: #FFFFFF;
  --elevated-edge-color: rgba(41, 63, 79, 0.22);
  --glass-drop: 0 10px 26px rgba(41, 63, 79, 0.11);
}

/* ----- Geometría, tipo y movimiento. Sin tema: son los mismos en los dos ------------------- */

:root {
  /* Cada valor es EL TAMAÑO DE UN OBJETO, no un gusto. Dos esquinas que casi coinciden se leen
     peor que dos claramente distintas: nadie sabe nombrar qué falla y la pantalla parece sin
     terminar. Se añaden peldaños nombrando un objeto, nunca un número. */
  --radius-xs: 0.25rem;
  --radius-input: 0.4rem;
  --radius-btn: 0.5rem;
  --radius-modal: 0.65rem;
  --radius-lg: 1rem;
  --radius-xl: 1.35rem;

  /* El nombre dice EL OFICIO, no el tamaño. Es lo que impide que un sistema vuelva a las treinta
     y seis medidas para doscientos usos. */
  --text-micro: 0.625rem;
  --text-mini: 0.6875rem;
  --text-label: 0.75rem;
  --text-ui: 0.8125rem;
  --text-body: 0.875rem;
  --text-lead: 1rem;
  --text-head: 1.25rem;
  --text-hero: 1.5rem;

  --dur-fast: 120ms;
  --dur-base: 200ms;
  --dur-side: 320ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-side: cubic-bezier(0.4, 0, 0.2, 1);

  --glass-blur: 22px;
  --glass-saturate: 1.55;
  --glass-color: color-mix(in srgb, var(--canvas-color) 74%, transparent);
  --glass-bevel: inset 1.5px 1.5px 0 -0.5px var(--bevel-hi-color),
    inset -1.5px -1.5px 0 -0.5px var(--bevel-lo-color);

  --head-h: 3.5rem;
  --rail-w: 4.125rem;
  --page-pad: 1.5rem;

  /* La raíz fluida de la familia. OJO: el `rem` de una media query se resuelve contra 16px y nunca
     contra este valor, así que un `44rem` mide 726px en una pantalla de 1600 y no 704. Cualquier
     medida que se compruebe tiene que leer el tamaño vivo de la raíz. */
  font-size: clamp(16px, calc(16px + (100vw - 1280px) / 640), 18px);
}

/* ----- Base ------------------------------------------------------------------------------- */

* { box-sizing: border-box; }

/* `hidden` LO PONE EL NAVEGADOR con la especificidad más baja que hay, así que CUALQUIER regla de
   autor que declare `display` lo desactiva en silencio. Pasó aquí en cuanto los botones pasaron a
   `inline-flex`: el botón de «volver a la escena de la sala» se quedó visible estando ya en ella, y
   con él todos los `hidden` de las dos pantallas —los mandos de anfitrión, los formularios—, que es
   enseñarle a cada cual cosas que no puede hacer. No es un caso raro: es cualquier componente que
   no sea `display: block`. */
[hidden] { display: none !important; }

body {
  margin: 0;
  min-height: 100dvh;
  padding-top: var(--head-h);
  color: var(--text-color);
  background-color: var(--mesa-canvas-color);
  background-image: radial-gradient(115% 85% at 0% 0%, var(--view-glow-color) 0%, transparent 65%);
  background-attachment: fixed;

  /* Selawik es el sustituto OFL de Segoe UI con las mismas métricas; aquí no viajan los ficheros
     porque Bragi no imprime, y el orden ya está puesto para el día que haga falta. */
  font-family: "Segoe UI", Selawik, Rubik, system-ui, sans-serif;
  font-size: var(--text-body);
  line-height: 1.5;
}

/* Donde las cifras cambian en sitio. Sin esto, una columna tiembla en cada actualización y el
   temblor se lee como inestabilidad del dato. */
.tabular, .cap, #zoom, #channel { font-variant-numeric: tabular-nums; }

a { color: var(--action-color); }

svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* UN ICONO NO TRAE TAMAÑO PROPIO: un <svg><use> sin medidas cae al tamaño por defecto de un
   elemento reemplazado sin dimensiones —300 × 150 px—, revienta la fila y la causa no se ve. Cada
   componente que lleva icono pone aquí su medida, para que quien lo use no pueda equivocarse.

   Y el selector es el ELEMENTO, no una clase. Esto se escribió primero como `.btn > svg` y la
   pantalla salió con un sol de trescientos píxeles encima de la cabecera: los botones son `button`
   a secas, la regla no casaba con ninguno, y la que falla es siempre la que parecía puesta. Una
   regla que protege a sus llamantes tiene que casar con lo que los llamantes escriben de verdad. */
button > svg,
.btn > svg,
.file > svg,
.nav-link > svg { width: 1.05rem; height: 1.05rem; flex-shrink: 0; }

/* ----- El marco --------------------------------------------------------------------------- */

.app-head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 1rem;
  height: var(--head-h);
  padding: 0 var(--page-pad);
  color: var(--frame-text-color);
  background-color: var(--glass-color);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  border-bottom: 1px solid color-mix(in srgb, var(--hairline-color) 50%, transparent);
}

/* Sin `backdrop-filter` el cristal es transparente y el texto queda sobre lo que pase por debajo. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .app-head { background-color: var(--canvas-color); }
}

.app-head .spacer { margin-left: auto; }

#whoami, #me { font-weight: 600; color: var(--frame-text-color); }
.who-change { font-weight: 400; }

/*
  EL RAÍL DE ESPACIOS. La familia lo usa para una lista fija de destinos y lo pliega a una pastilla
  abajo en el teléfono; aquí la lista la hace crecer quien usa el producto, así que en pantalla
  estrecha se vuelve una tira horizontal que se desplaza en vez de una pastilla que no cabría.
*/
.app-side {
  position: fixed;
  top: var(--head-h);
  bottom: 0;
  left: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  width: var(--rail-w);
  padding: 0.75rem 0;
  overflow-y: auto;
  overflow-x: hidden;
  background-color: var(--glass-color);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  border-right: 1px solid color-mix(in srgb, var(--hairline-color) 50%, transparent);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .app-side { background-color: var(--canvas-color); }
}

.rail { list-style: none; margin: 0; padding: 0; display: contents; }

.rail-pill, .rail-add {
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  padding: 0;
  border-radius: var(--radius-lg);
  background-color: var(--control-color);
  color: var(--muted-color);
  font-size: var(--text-label);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.rail-pill:hover:not(:disabled), .rail-add:hover:not(:disabled) {
  background-color: var(--control-hover-color);
  color: var(--text-color);
}

/* «Estás aquí» se dice con superficie y borde de marca, nunca con el naranja como tinta. */
.rail-pill[aria-current="true"] {
  background-color: color-mix(in srgb, var(--highlight-color) 18%, transparent);
  box-shadow: inset 0 0 0 1px var(--highlight-color);
  color: var(--text-color);
}

.rail-add {
  margin-top: auto;
  border: 1px dashed var(--hairline-color);
  background-color: transparent;
}

.app-head { left: var(--rail-w); }
.app-main { margin-left: var(--rail-w); min-height: calc(100dvh - var(--head-h)); }

.browse {
  display: grid;
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  gap: 1rem;
  padding: var(--page-pad);
  align-items: start;
}

@media (max-width: 60rem) {
  .browse { grid-template-columns: 1fr; }
}

.rooms h3 {
  margin: 1rem 0 0.35rem;
  font-size: var(--text-micro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--muted-color);
}

.rooms h3:first-child { margin-top: 0; }
.rooms .list { margin-bottom: 0.5rem; }

.room-name { display: inline-flex; align-items: center; gap: 0.45rem; min-width: 0; }
.room-name > svg { width: 0.95rem; height: 0.95rem; flex-shrink: 0; color: var(--muted-color); }

.enter {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 1.85rem;
  padding: 0 0.75rem;
  border-radius: var(--radius-btn);
  background-color: var(--cta-color);
  color: var(--on-cta-color);
  font-size: var(--text-body);
  font-weight: 600;
  text-decoration: none;
}

.enter:hover { background-color: var(--cta-hover-color); }
.enter > svg { width: 1.05rem; height: 1.05rem; }

@media (max-width: 48rem) {
  .app-side {
    top: var(--head-h);
    bottom: auto;
    right: 0;
    flex-direction: row;
    width: auto;
    height: 3.6rem;
    padding: 0.5rem 0.6rem;
    overflow-x: auto;
    overflow-y: hidden;
    border-right: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--hairline-color) 50%, transparent);
  }

  .rail-add { margin-top: 0; margin-left: 0; flex-shrink: 0; }
  .rail-pill { flex-shrink: 0; }

  .app-head { left: 0; }
  .app-main { margin-left: 0; padding-top: 3.6rem; }
}

/* La marca: símbolo, nombre en minúscula y EL PUNTO NARANJA. El punto es la pieza que hace
   reconocible a la familia de un producto a otro, y la más barata de adoptar: un carácter. */
.brand-mark {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--frame-text-color);
  text-decoration: none;
}

.brand-mark > svg { width: 1.5rem; height: 1.5rem; }

.brand-name {
  font-size: var(--text-lead);
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1;
}

.brand-dot { color: var(--highlight-color); }

.app-head .claim,
.app-head .me {
  margin: 0;
  font-size: var(--text-label);
  color: var(--frame-muted-color);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 48rem) {
  .app-head .claim { display: none; }
}

/* ----- Tarjetas: velo y filete, nunca un relleno sólido ------------------------------------ */

.card {
  position: relative;
  min-width: 0;
  padding: 1rem;
  border: 1px solid var(--hairline-color);
  border-radius: var(--radius-modal);
  background-color: color-mix(in srgb, var(--card-surface-color) 54%, transparent);
  transition: border-color var(--dur-base) var(--ease-out),
    background-color var(--dur-base) var(--ease-out);
}

/* La sombra es solo para lo que FLOTA. Una tarjeta está EN la hoja; una hoja donde todo proyecta
   sombra deja de decir qué está encima de qué. */
.card h2 {
  margin: 0 0 0.75rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--hairline-color);
  font-size: var(--text-head);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.card h2 .hint { font-size: var(--text-label); font-weight: 400; }

.board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1rem;
  padding: var(--page-pad);
  align-items: start;
}

.hint { color: var(--muted-color); font-size: var(--text-label); }
.empty { color: var(--muted-color); font-size: var(--text-label); margin: 0.4rem 0; }
.error { color: var(--alarm-text-color); font-size: var(--text-label); }

.row { display: flex; gap: 0.4rem; margin-bottom: 0.8rem; flex-wrap: wrap; align-items: center; }
.row .input { flex: 1 1 8rem; min-width: 0; }

/* ----- Mandos ----------------------------------------------------------------------------- */

/* El borde transparente existe SIEMPRE, para que una variante con borde no cambie de tamaño. */
.btn, button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;

  /* 24 × 24 es el mínimo de WCAG 2.2 para un blanco de pulsación, y se comprueba midiendo cajas. */
  min-height: 1.85rem;
  padding: 0 0.75rem;
  border: 1px solid transparent;
  border-radius: var(--radius-btn);
  background-color: var(--control-color);
  color: var(--text-color);
  font: inherit;
  font-size: var(--text-body);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

/* Cada :hover lleva su :not(:disabled). Es la regla que más se rompe sola, y su modo de fallo es
   una persona pulsando un mando que parece vivo y concluyendo que la aplicación está rota. */
button:hover:not(:disabled) { background-color: var(--control-hover-color); }
button:disabled { opacity: var(--disabled-ink); cursor: not-allowed; }

button[type="submit"] {
  background-color: var(--cta-color);
  color: var(--on-cta-color);
}

button[type="submit"]:hover:not(:disabled) { background-color: var(--cta-hover-color); }

.input, .select, input, select {
  min-height: 1.85rem;
  padding: 0 0.625rem;
  border: 1px solid var(--hairline-color);
  border-radius: var(--radius-input);
  background-color: var(--field-veil-color);
  color: var(--text-color);
  font: inherit;
  font-size: var(--text-body);
}

/* UN CAMPO DE TEXTO NO LLEVA ANILLO DE FOCO: lo que dice que está activo es el cursor parpadeando
   dentro, que es su propio indicador, y un anillo de 3px alrededor es lo más pesado de la fila por
   haber pulsado donde ibas a escribir. El borde se reserva para el ERROR. Todo lo demás —botones,
   filas pulsables— sí lleva anillo, sin excepciones. */
:focus-visible {
  outline: 2px solid var(--highlight-edge-color);
  outline-offset: 2px;
}

input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; }
input[aria-invalid="true"] { border-color: var(--alarm-color); }

/* ----- Listas ----------------------------------------------------------------------------- */

.list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; }

.list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  min-height: 1.9rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid transparent;
  border-radius: var(--radius-input);
  cursor: pointer;
  transition: background-color var(--dur-base) var(--ease-out);
}

.list li:hover { background-color: var(--hover-color); }

/* «Estás aquí» es lo que dice el naranja, y se dice con superficie y borde, no con tinta. */
.list li[aria-selected="true"] {
  background-color: var(--selected-color);
  box-shadow: inset 2px 0 0 var(--highlight-color);
}

.list .sub { color: var(--muted-color); font-size: var(--text-label); white-space: nowrap; }
.list .sub button { min-height: 1.5rem; padding: 0 0.5rem; font-size: var(--text-label); }

.detail h3 {
  margin: 0.9rem 0 0.3rem;
  font-size: var(--text-micro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--muted-color);
}

.detail h3:first-child { margin-top: 0; }
.detail ul { list-style: none; margin: 0; padding: 0; }
.detail li { padding: 0.15rem 0; font-size: var(--text-ui); }

/* ----- Pastillas de estado: una forma, cinco tintas --------------------------------------- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  height: 1.5rem;
  padding: 0 0.625rem;
  border-radius: 999px;
  font-size: var(--text-label);
  font-weight: 600;
  white-space: nowrap;
}

.chip-ok { background-color: color-mix(in srgb, var(--ok-color) 15%, transparent); color: var(--ok-text-color); }
.chip-warn { background-color: color-mix(in srgb, var(--warn-color) 15%, transparent); color: var(--warn-text-color); }
.chip-alarm { background-color: color-mix(in srgb, var(--alarm-color) 15%, transparent); color: var(--alarm-text-color); }
.chip-event { background-color: color-mix(in srgb, var(--event-color) 15%, transparent); color: var(--event-text-color); }
.chip-off { background-color: color-mix(in srgb, var(--muted-color) 16%, transparent); color: var(--muted-color); }

.tag {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  border: 1px solid var(--hairline-color);
  border-radius: var(--radius-xs);
  font-size: var(--text-label);
  color: var(--muted-color);
}

.cap { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: var(--text-label); }
.cap.media { color: var(--ok-text-color); }
.cap.app { color: var(--text-color); }

/* Un input de fichero disfrazado de mando: el control nativo no se estila, y su rótulo lo pone el
   navegador en el idioma del sistema, no en el de la pantalla. */
.file {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 1.85rem;
  padding: 0 0.75rem;
  border: 1px dashed var(--hairline-color);
  border-radius: var(--radius-btn);
  font-size: var(--text-label);
  color: var(--muted-color);
  cursor: pointer;
}

.file:hover { border-color: var(--highlight-color); color: var(--text-color); }
.file input { display: none; }

/* ----- La sala: un escenario y un panel ------------------------------------------------------ */

/*
  MODO LLAMADA. Lo que manda es lo que se está mirando —el plano, la pantalla de alguien, una cara—
  y todo lo demás flota encima: los mandos en una barra, el mosaico en una tira, y lo que se lee en
  un panel al lado. Es la forma de Teams, Discord y Roll20, y es la misma por el mismo motivo: en una
  llamada la pantalla se mira, no se administra.

  Y EN LA SALA NO HAY RAÍL. Quien está dentro está en una cosa; una columna de sitios a los que ir al
  lado del lienzo invita a irse. Se vuelve por la marca, como en toda la familia.
*/
body.in-room .app-head { left: 0; }

.room {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(18rem, 22rem);
  gap: 0.75rem;
  height: calc(100dvh - var(--head-h));
  padding: 0.75rem;
}

.stage {
  position: relative;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--hairline-color);
  border-radius: var(--radius-lg);

  /* El escenario es SIEMPRE oscuro, en los dos temas. Un vídeo o un plano se miran contra un fondo
     neutro; un escenario claro alrededor de una imagen oscura deslumbra, y con un plano claro
     tampoco ayuda — lo que hace falta es que nada compita con lo que se está mirando. */
  background-color: #12161a;
  background-image:
    linear-gradient(color-mix(in srgb, #ffffff 3%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, #ffffff 3%, transparent) 1px, transparent 1px);
  background-size: 28px 28px;
}

/* El fondo y el lienzo, EXACTAMENTE en el mismo sitio: si no encajaran, el trazo caería desplazado
   de lo que señala y no habría forma de verlo mirando. */
.backdrop, .stage canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.backdrop { display: grid; place-items: center; }

.backdrop video {
  width: 100%;
  height: 100%;

  /* `contain` y no `cover`: recortar el vídeo movería lo que se ve respecto de las coordenadas en
     las que se apunta, y el cursor de cada cual caería en un sitio distinto de la misma imagen. */
  object-fit: contain;
  background-color: #000;
}

.stage canvas { touch-action: none; cursor: crosshair; }

.stage-head {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.75rem;
  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.55), transparent);
  color: #f6f7f8;
  pointer-events: none;
}

.stage-head > * { pointer-events: auto; }
.stage-head .spacer { margin-left: auto; pointer-events: none; }

.source { display: inline-flex; align-items: center; gap: 0.4rem; }

.source-label {
  font-size: var(--text-micro);
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  opacity: 0.75;
}

.source .select {
  max-width: 16rem;
  background-color: rgba(0, 0, 0, 0.45);
  border-color: rgba(255, 255, 255, 0.2);
  color: #f6f7f8;
}

.stage-note {
  font-size: var(--text-label);
  color: rgba(255, 255, 255, 0.8);
  font-variant-numeric: tabular-nums;
}

/* Con una fuente viva detrás, lo que se dibuja NO se guarda, y el borde lo dice todo el rato. Un
   aviso que solo aparece al empezar no está cuando hace falta, que es mientras se dibuja. */
body.live-backdrop .stage { box-shadow: inset 0 0 0 2px var(--highlight-color); }
body.live-backdrop .stage-note { color: var(--highlight-edge-color); }

.drop-hint {
  position: absolute;
  inset: 0;
  z-index: 3;
  margin: 0;
  display: grid;
  place-items: center;
  background-color: color-mix(in srgb, var(--highlight-color) 20%, rgba(0, 0, 0, 0.55));
  box-shadow: inset 0 0 0 3px var(--highlight-color);
  color: #ffffff;
  font-size: var(--text-head);
  font-weight: 600;
  pointer-events: none;
}

/* ----- El mosaico: una tira, no una rejilla ---------------------------------------------------- */

.filmstrip {
  position: absolute;
  z-index: 2;
  top: 3.25rem;
  right: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: calc(100% - 8rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.tile {
  position: relative;
  margin: 0;
  width: 11rem;
  border-radius: var(--radius-modal);
  overflow: hidden;
  background-color: #000;
  box-shadow: var(--glass-drop), inset 0 0 0 1px rgba(255, 255, 255, 0.12);
  cursor: pointer;
  transition: box-shadow var(--dur-base) var(--ease-out);
}

.tile:hover { box-shadow: var(--glass-drop), inset 0 0 0 1px rgba(255, 255, 255, 0.4); }

/* La baldosa que está de fondo se marca: sin eso, pulsar una y otra no se distingue de no pulsar. */
.tile[aria-current="true"] { box-shadow: var(--glass-drop), inset 0 0 0 2px var(--highlight-color); }

.tile video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background-color: #000;
}

.tile figcaption {
  position: absolute;
  inset: auto 0 0 0;
  padding: 0.2rem 0.5rem;
  font-size: var(--text-micro);
  color: #f6f7f8;
  background-image: linear-gradient(to top, rgba(0, 0, 0, 0.75), transparent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tile audio { display: none; }

/* ----- La barra de mandos: flotante, agrupada, siempre en el mismo sitio ------------------------ */

.bar {
  position: absolute;
  z-index: 4;
  left: 50%;
  bottom: 0.9rem;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.4rem;
  max-width: calc(100% - 1.5rem);
  padding: 0.4rem;
  border-radius: var(--radius-xl);
  background-color: rgba(20, 24, 28, 0.72);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  box-shadow: var(--glass-drop), inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  overflow-x: auto;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .bar { background-color: #14181c; }
}

.bar-group { display: flex; align-items: center; gap: 0.25rem; }

/* Los mandos se agrupan por OFICIO —lo mío, el lienzo, la llamada— y el separador lo dice. Doce
   botones en fila se leen como doce botones; en tres grupos, como tres cosas. */
.bar-split {
  width: 1px;
  height: 1.6rem;
  flex-shrink: 0;
  background-color: rgba(255, 255, 255, 0.18);
}

.bar button {
  width: 2.4rem;
  height: 2.4rem;
  padding: 0;
  background-color: transparent;
  color: rgba(255, 255, 255, 0.85);
}

.bar button:hover:not(:disabled) { background-color: rgba(255, 255, 255, 0.14); color: #fff; }
.bar button:disabled { opacity: 0.35; }

/* Encendido se dice con superficie y borde de marca, nunca con el naranja como tinta. */
.bar button[aria-pressed="true"] {
  background-color: color-mix(in srgb, var(--highlight-color) 30%, transparent);
  box-shadow: inset 0 0 0 1px var(--highlight-color);
  color: #fff;
}

.bar .bar-wide { width: auto; padding: 0 0.8rem; gap: 0.4rem; font-size: var(--text-label); }
.bar .bar-go { background-color: var(--cta-color); color: var(--on-cta-color); }
.bar .bar-go:hover:not(:disabled) { background-color: var(--cta-hover-color); }
.bar .bar-stop:not(:disabled) { background-color: var(--alarm-color); color: #fff; }

.bar input[type="color"] {
  width: 2rem;
  height: 2rem;
  min-height: 0;
  padding: 0.15rem;
  border-color: rgba(255, 255, 255, 0.2);
  background-color: transparent;
  cursor: pointer;
}

/* ----- El panel: pestañas, no tres tarjetas apiladas ------------------------------------------- */

.panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: 1px solid var(--hairline-color);
  border-radius: var(--radius-lg);
  background-color: color-mix(in srgb, var(--card-surface-color) 54%, transparent);
  overflow: hidden;
}

.tabs { display: flex; border-bottom: 1px solid var(--hairline-color); }

.tabs button {
  flex: 1 1 0;
  min-width: 0;
  gap: 0.35rem;
  min-height: 2.6rem;
  border-radius: 0;
  background-color: transparent;
  color: var(--muted-color);
  font-size: var(--text-label);
}

.tabs button:hover:not(:disabled) { background-color: var(--hover-color); color: var(--text-color); }

.tabs button[aria-selected="true"] {
  color: var(--text-color);
  box-shadow: inset 0 -2px 0 var(--highlight-color);
}

.badge {
  font-size: var(--text-micro);
  font-variant-numeric: tabular-nums;
  color: var(--muted-color);
}

.tab-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 0;
  padding: 0.75rem;
  overflow-y: auto;
}

/* Lo que la conversación necesita y las otras dos no: crecer hasta el fondo del panel. */
.tab-body[data-panel="chat"] { flex: 1 1 auto; }
.tab-body[data-panel="chat"] .messages { flex: 1 1 auto; max-height: none; }

@media (max-width: 60rem) {
  /* En estrecho, el escenario manda y el panel se va debajo: partir el ancho deja las dos cosas
     demasiado pequeñas para servir de nada. */
  .room {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(16rem, 1fr) minmax(14rem, 20rem);
    height: auto;
    min-height: calc(100dvh - var(--head-h));
  }

  .filmstrip { flex-direction: row; top: auto; bottom: 4.5rem; left: 0.75rem; max-height: none; }
  .tile { width: 7.5rem; }
}

/* ----- La conversación --------------------------------------------------------------------- */

.messages {
  list-style: none;
  margin: 0 0 0.8rem;
  padding: 0;
  display: grid;
  gap: 0.55rem;

  /* Con tope y con su propio desplazamiento: sin él, una conversación larga empuja el resto del
     lateral fuera de la pantalla y el mosaico deja de verse. */
  max-height: 22rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.said { display: grid; gap: 0.15rem; }

.said-head {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  margin: 0;
  font-size: var(--text-micro);
  color: var(--muted-color);
}

.said .who { font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.said .when { font-variant-numeric: tabular-nums; }

.said-body {
  margin: 0;
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius-modal);
  background-color: color-mix(in srgb, var(--panel-color) 62%, transparent);
  font-size: var(--text-ui);

  /* Lo que escribe una persona trae saltos de línea y palabras sin espacios —una ruta, un
     identificador— que sin esto estiran la columna y sacan el panel de la pantalla. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Lo propio se distingue por el borde de marca, no por el lado: una columna estrecha con mensajes
   alineados a derecha e izquierda deja la mitad del ancho sin usar. */
.said.mine .said-body { box-shadow: inset 2px 0 0 var(--highlight-color); }

.said-shot { margin: 0.25rem 0 0; display: grid; gap: 0.2rem; }

.said-shot img {
  display: block;
  max-width: 100%;
  border: 1px solid var(--hairline-color);
  border-radius: var(--radius-input);
}

.said-file { font-size: var(--text-label); overflow-wrap: anywhere; }

#chat-attach { padding: 0 0.5rem; }

/* ----- Movimiento: los dos interruptores, los dos obligatorios ---------------------------- */

/* El del sistema cubre a quien lo pidió en su máquina. En una planta la pantalla es un cliente
   ligero atornillado a la pared con el sistema tal como vino, así que además tiene que poder
   pedirse DESDE la aplicación, con un atributo que sirve el servidor. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

:root[data-motion="still"] *,
:root[data-motion="still"] *::before,
:root[data-motion="still"] *::after {
  animation-duration: 0.001ms !important;
  animation-delay: 0ms !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 0.5rem 0.75rem;
  background-color: var(--elevated-color);
  border-radius: var(--radius-btn);
  z-index: 50;
}

.skip-link:focus { left: var(--page-pad); top: 0.5rem; }
