/* Tokens de docs/DESIGN.md. Ningún valor se inventa aquí: si hace falta uno
   nuevo, se añade primero al documento de diseño. */
:root{
  /* cromo — 6 colores */
  --lienzo:#101010; --panel:#181818; --overlay:#222222; --trazo:#333333;
  --tinta:#EDEDED; --tinta-debil:#9A9A9A;
  /* un solo acento */
  --acento:#3DDC91;
  /* semánticos — «cumple» NO tiene color */
  --aviso:#E8A33D; --alarma:#FF6B5E;

  /* 5 tamaños */
  --t-micro:11px; --t-dato:12px; --t-base:13px; --t-titulo:15px; --t-display:20px;
  --sans:"Space Grotesk",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  /* rejilla de 4 px */
  --e1:4px; --e2:8px; --e3:12px; --e4:16px; --e6:24px; --e8:32px;
  --r-control:4px; --r-panel:8px;
  --sombra:0 2px 8px rgba(0,0,0,.5);   /* la única del sistema */
  --ease:cubic-bezier(.22,1,.36,1);

  --barra-h:44px; --tiempo-h:0px; --inspector-w:320px;

  /* lienzo — los colores del dibujo que no son datos. Tokenizados para que el
     tema claro pueda cambiarlos; los de las paletas de niveles NO se tocan. */
  --reticula:#ffffff0d;
  --explanada:#161616;
  --edificio-cubierta:#4a4a4a;
  --edificio-fachada:#3d3d3d;
  --edificio-muro-a:#2c2c2c;
  --edificio-muro-b:#242424;
  --edificio-muro-mapa:#9a9a9a;
  --hueco:#1b1b1b;
  --etiqueta-fondo:#101010d9;
  /* paneles flotantes sobre el lienzo: el lienzo velado, no un color nuevo */
  --lienzo-velado:#101010e0;
  --lienzo-velado-fuerte:#101010e6;
}

/* Tema claro. Los DOCUMENTOS (informe, impresión) son claros siempre; esto es
   el taller de día. Verificado en docs/tokens/verificar_paleta.py con los
   mismos suelos que el oscuro: tinta 15,3:1 · débil 5,9 · acento 4,8 ·
   aviso 5,3 · alarma 5,0. Las paletas de datos no cambian con el tema. */
:root[data-tema=claro]{
  --lienzo:#F2F1EE; --panel:#FAFAF9; --overlay:#FFFFFF; --trazo:#D9D7D3;
  --tinta:#1B1B1B; --tinta-debil:#5E5C58;
  --acento:#0E7A4C;
  --aviso:#8A5A00; --alarma:#C0322A;
  --sombra:0 2px 8px rgba(0,0,0,.18);

  --reticula:#0000000f;
  --explanada:#E7E5E1;
  --edificio-cubierta:#B6B4AF;
  --edificio-fachada:#A9A7A2;
  --edificio-muro-a:#C1BFBA;
  --edificio-muro-b:#CBC9C4;
  --edificio-muro-mapa:#8A8880;
  --hueco:#7E7C78;
  --etiqueta-fondo:#FFFFFFd9;
  --lienzo-velado:#F2F1EEe0;
  --lienzo-velado-fuerte:#F2F1EEe6;
}

*{box-sizing:border-box}
html,body{height:100%}
body{margin:0;background:var(--lienzo);color:var(--tinta);
  font:var(--t-base)/1.55 var(--sans);overflow:hidden}

/* Dígitos tabulares: obligatorio en todo dB, Hz, m y hora. */
.mono,td,th,input[type=number],.num{
  font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
:focus-visible{outline:2px solid var(--acento);outline-offset:2px;border-radius:2px}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

button{all:unset;cursor:pointer;padding:var(--e1) var(--e3);border:1px solid var(--trazo);
  border-radius:var(--r-control);font-size:var(--t-base);transition:border-color .12s var(--ease)}
/* `all:unset` devuelve `display` a su valor inicial, que es una regla de autor
   y por tanto **gana al `[hidden]{display:none}` del navegador**: un botón con
   `hidden` seguía viéndose. Pasaba con el botón de la vista del patrón, que
   aparecía sin haber ningún patrón. Se repone aquí, después, y para todo. */
[hidden]{display:none !important}
button:hover{border-color:var(--tinta-debil)}
button.primaria{background:var(--acento);color:#08150E;border-color:var(--acento);font-weight:600}

/* ---------- barra ---------- */
.barra{display:flex;align-items:center;gap:var(--e3);height:var(--barra-h);
  padding:0 var(--e4);background:var(--panel);border-bottom:1px solid var(--trazo)}
.barra strong{font-size:var(--t-titulo);font-weight:600;letter-spacing:-.01em}
.proyecto{font-size:var(--t-base);color:var(--tinta-debil);
  background:none;border:1px solid transparent;border-radius:var(--r-control);
  padding:2px var(--e2);font-family:inherit;width:26ch;min-width:8ch}
.proyecto:hover{border-color:var(--trazo)}
.proyecto:focus{border-color:var(--acento);color:var(--tinta);outline:none}
.proyecto::placeholder{color:var(--tinta-debil);opacity:.6}
.motor{font-size:var(--t-micro);color:var(--tinta-debil);
  border:1px solid var(--trazo);border-radius:var(--r-control);padding:1px var(--e2)}
.barra .sep{flex:1}

/* Barra de progreso del cálculo.
   Dice **qué** se está calculando y cuánto lleva, no sólo que algo pasa: una
   barra sin sujeto obliga a adivinar si es el mapa, un corte o las fachadas. */
.barra{position:relative}
.progreso{position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--overlay)}
.progreso[hidden]{display:none}
.progreso i{display:block;height:100%;width:0;background:var(--acento);
  transition:width .12s linear}
/* El texto de progreso vive EN el flujo de la barra (esquina derecha), como
   hermano de #v-estado: nunca se superponen (pedido de Salva, 18-ago-2026).
   El veredicto por receptor se fue a su ficha y al esquema; la trazabilidad
   se abre en el chip del motor. */
#progreso-txt{white-space:nowrap}
.mandos-calc button{padding:0 var(--e2);font-size:var(--t-micro);line-height:1.6}
.motor{cursor:pointer;padding:var(--e1) var(--e2);border-radius:var(--r-control)}
.motor:hover{background:var(--reticula)}
.estado{font-size:var(--t-micro);color:var(--tinta-debil)}   /* cumple: sin color */
.estado.mal{color:var(--alarma)}
.estado.limite{color:var(--aviso)}

/* ---------- obra: lienzo + inspector ---------- */
.recoger{position:absolute;right:var(--inspector-w);top:calc(var(--barra-h) + var(--e4));
  width:20px;height:34px;padding:0;text-align:center;line-height:32px;
  background:var(--panel);border-radius:var(--r-control) 0 0 var(--r-control);
  border-right:none;color:var(--tinta-debil);z-index:4;transition:right .24s var(--ease)}
.recoger:hover{color:var(--tinta)}
.obra.plegado .recoger{right:0;transform:scaleX(-1)}
.obra.plegado{grid-template-columns:minmax(0,1fr) 0}
.obra.plegado .datos{display:none}
/* El tirador va antes del panel en el DOM, pero no ocupa columna: se posiciona
   sobre el borde. Así el `grid` sigue siendo de dos columnas y el plegado no
   necesita saber nada de él. */
.tirador{position:absolute;top:0;bottom:0;right:var(--inspector-w);width:7px;
  margin-right:-3px;cursor:col-resize;z-index:5}
.tirador:hover,.tirador:focus-visible{background:var(--acento);opacity:.5}
.tirador:focus-visible{outline:none}
.obra.plegado .tirador{display:none}
.obra.redimensionando{transition:none;user-select:none}
.obra.redimensionando .tirador{background:var(--acento);opacity:.7}
.obra{position:relative;transition:grid-template-columns .24s var(--ease);
  display:grid;grid-template-columns:minmax(0,1fr) var(--inspector-w);
  height:calc(100vh - var(--barra-h) - var(--tiempo-h))}
.lienzo{position:relative;min-width:0}
canvas{display:block;width:100%;height:100%;cursor:crosshair}
/* Con un elemento seleccionado en EDICIÓN, el puntero lo dice en todo
   momento (pedido de Salva, 12-ago-2026): flechas de mover, salvo que un
   estado más concreto (coger, arrastrar, calibrar, colocar) mande. */
.lienzo.seleccion canvas:not(.agarrable):not(.arrastrando):not(.calibrando):not(.colocando){cursor:move}
/* La mano dice lo que hay debajo: abierta sobre lo que se puede coger,
   cerrada mientras se arrastra. Sin esto, coger un elemento era un acto de fe. */
/* Los mandos fijos del modo interior: siempre a la vista mientras se
 * trabaja dentro (modo interior EXCLUSIVO, 22-ago), en su fila bajo la
 * barra de cálculo (.modos) para no taparla. */
.mandos-interior{position:absolute;top:calc(var(--e4) + 34px);left:50%;transform:translateX(-50%);
  display:flex;gap:var(--e2);z-index:30}
#salir-interior{background:var(--acento);color:var(--lienzo);border:0;
  border-radius:6px;padding:6px 14px;font:600 13px system-ui;
  cursor:pointer;box-shadow:0 2px 8px #0006}
#salir-interior:hover{filter:brightness(1.1)}
#plano-interior,#ver-dentro,#alinear-recinto{background:var(--panel);color:var(--tinta);border:1px solid var(--trazo);
  border-radius:6px;padding:6px 12px;font:500 12px system-ui;cursor:pointer}
#plano-interior:hover,#ver-dentro:hover,#alinear-recinto:hover{background:var(--overlay)}
canvas.agarrable{cursor:grab}
canvas.calibrando{cursor:cell}
/* El lienzo 3D va debajo; el 2D encima, transparente, sólo para el texto. */
#gl[hidden]{display:none}
#gl{position:absolute;inset:0}
#planta{position:absolute;inset:0}
.lienzo.tridi #planta{background:transparent}
canvas.arrastrando{cursor:grabbing}
.vistas{position:absolute;top:var(--e4);left:var(--e4);display:flex;gap:var(--e1)}
.vistas button[aria-pressed=true]{border-color:var(--acento);color:var(--acento)}
/* A5 · modo interior: selector de plantas junto a las migas */
#v-plantas{display:flex;gap:2px}
#v-plantas button{min-width:4ch}
#v-plantas button[aria-pressed=true]{border-color:var(--acento);color:var(--acento)}
/* A5 · paleta del interior: solo lo que se coloca DENTRO de una sala */
.herramientas.interior details.grupo-herr{display:none}
.herramientas.interior details.grupo-herr:has(#add-fuente),
.herramientas.interior details.grupo-herr:has(#add-altavoz),
.herramientas.interior details.grupo-herr:has(#add-caja),
.herramientas.interior details.grupo-herr:has(#add-punto){display:block}
.herramientas.interior #add-flineal,.herramientas.interior #add-fsuper,
.herramientas.interior #add-circulo{display:none}
/* Sección y mapa SÍ se gestionan dentro (Salva, 25-ago): el corte y el
 * campo del recinto son herramientas de interiores de pleno derecho. */
.herramientas.interior details.grupo-herr:has(#add-seccion){display:block}
/* Recinto y edificio también (Salva, 4-sep): el kernel de sala honra los
 * recintos anidados y los edificios con la huella dentro como obstáculos.
 * Barrera, panel, explanada y vegetación no los lee (sala.rs): quedan
 * fuera hasta su tanda de kernel — hueco declarado en el manual. */
.herramientas.interior details.grupo-herr:has(#add-recinto){display:block}
.herramientas.interior #add-barrera,.herramientas.interior #add-panel,
.herramientas.interior #add-explanada,.herramientas.interior #add-vegetacion{display:none}
/* Varios planos de fondo: lista con orden de pintado y elegido activo. */
.fondos-lista{display:flex;flex-direction:column;gap:2px;margin:var(--e2) 0}
.fondo-fila{display:flex;align-items:center;gap:6px}
.fondo-fila .f-elige{flex:1;text-align:left;background:none;border:1px solid transparent;
  color:var(--tinta);cursor:pointer;padding:2px 6px;border-radius:4px;font:inherit}
.fondo-fila.activa .f-elige{border-color:var(--acento);color:var(--acento)}
.fondo-fila button[disabled]{opacity:.3}

/* Filtro del esquema (proyectos grandes) y carpetas de grupo. */
.esquema-filtro{margin:var(--e2) var(--e3) 0;padding:4px 8px;width:calc(100% - 2*var(--e3));
  background:transparent;border:1px solid var(--trazo);border-radius:4px;
  color:var(--tinta);font:inherit;font-size:var(--t-micro)}
.esquema-filtro::placeholder{color:var(--tinta-debil)}
.grupo.carpeta>summary{display:flex;align-items:center;gap:6px}
.grupo.carpeta .g-act{display:inline-flex}
.grupo.carpeta .g-borrar{margin-left:auto;border:0;background:none;
  color:var(--tinta-debil);cursor:pointer;padding:0 4px}
.grupo.carpeta .g-borrar:hover{color:var(--aviso)}
.esquema-acciones{margin:var(--e1) var(--e3)}
.caras-patio{display:flex;gap:2px;flex-wrap:wrap}
.caras-patio button{min-width:34px;padding:1px 4px;font-variant-numeric:tabular-nums}
.caras-patio button[aria-pressed="true"]{border-color:var(--acento);color:var(--acento)}

/* Panel «Organización»: variantes y grupos con nombre y notas. */
.org-fila{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;
  gap:4px 6px;align-items:center;padding:4px 0;border-bottom:1px solid var(--trazo)}
.org-fila.org-base{grid-template-columns:auto auto minmax(0,1fr)}
.org-fila.activa .org-activa{color:var(--acento)}
.org-fila .org-activa{border:none;background:none;cursor:pointer;
  color:var(--tinta-debil);padding:0 2px;font-size:14px}
.org-fila .org-nombre{background:transparent;border:1px solid transparent;
  border-radius:4px;color:var(--tinta);font:inherit;padding:2px 4px;min-width:0}
.org-fila .org-nombre:hover,.org-fila .org-nombre:focus{border-color:var(--trazo)}
.org-fila small{color:var(--tinta-debil);white-space:nowrap}
.org-fila .org-borrar{border:none;background:none;color:var(--tinta-debil);
  cursor:pointer;padding:0 4px}
.org-fila .org-borrar:hover{color:var(--aviso)}
.org-fila .org-notas{grid-column:1/-1;background:transparent;
  border:1px solid var(--trazo);border-radius:4px;color:var(--tinta);
  font:inherit;font-size:var(--t-micro);padding:4px 6px;resize:vertical}

/* Desglose dentro de Organización: overrides de variante y miembros. */
.org-desglose{grid-column:1/-1;font-size:var(--t-micro)}
.org-desglose>summary{cursor:pointer;color:var(--tinta-debil);list-style:none}
.org-desglose>summary::before{content:"▸ "}
.org-desglose[open]>summary::before{content:"▾ "}
.org-ov{display:flex;justify-content:space-between;align-items:center;
  gap:6px;padding:2px 0 2px 12px;color:var(--tinta-debil)}
.org-ov button{border:none;background:none;color:var(--tinta-debil);cursor:pointer}
.org-ov button:hover{color:var(--aviso)}
.org-ov .org-ir{color:var(--tinta);text-align:left;padding:0}
.org-ov .org-ir:hover{color:var(--acento)}
.marca-variante{color:var(--acento)}

/* Selector de VARIANTE en cabecera: contexto siempre a la vista. */
.variante-caja{display:inline-flex;gap:2px;align-items:center;margin-left:var(--e2)}
.variante-caja select{background:transparent;border:1px solid var(--trazo);
  border-radius:4px;color:var(--tinta);font:inherit;font-size:var(--t-micro);
  padding:2px 4px;max-width:150px}
.variante-caja button{min-width:22px;padding:0 4px}

/* Vistas de cámara 3D en el menú Ver (Salva, 16-ago: nada de ocupar
   lienzo). Fila: ir (crece) + guardar/sobreescribir + borrar. */
.menu-seccion{padding:2px 10px;color:var(--tinta-debil);font-size:var(--t-micro);
  text-transform:uppercase;letter-spacing:.06em;white-space:nowrap}
.camara-fila{display:flex;gap:2px;align-items:stretch}
.camara-fila .c-ir{flex:1;text-align:left;white-space:nowrap}
.camara-fila .c-ir small{color:var(--tinta-debil);margin-left:6px}
.camara-fila .c-guarda,.camara-fila .c-borra{min-width:26px;padding:0 6px}
.camara-fila button[disabled]{opacity:.35;cursor:default}
.camara-fila .c-borra:not([disabled]):hover{color:var(--aviso)}

/* La leyenda lleva SIEMPRE los límites numéricos escritos (§4.2). */
/* Todos los paneles flotantes se pliegan igual: un solo gesto en toda la app. */
.panel{background:var(--lienzo-velado);border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:var(--e2)}
.panel > summary{cursor:pointer;font-size:var(--t-micro);color:var(--tinta-debil);
  list-style:none;user-select:none;text-transform:uppercase;letter-spacing:.06em}
.panel > summary::-webkit-details-marker{display:none}
.panel > summary::before{content:"▸ "}
.panel[open] > summary::before{content:"▾ "}
.panel > summary:hover{color:var(--tinta)}
.panel[open] > summary{margin-bottom:var(--e2)}

/* ---------- menús de cabecera ---------- */
.menus{display:flex;gap:2px;align-items:center;margin-left:var(--e3)}
.menu{position:relative}
.menu>summary{list-style:none;cursor:default;font-size:var(--t-micro);
  padding:5px var(--e3);border:none;border-radius:4px;
  user-select:none;color:var(--tinta)}
.menu>summary:hover{background:var(--overlay)}
.menu>summary::-webkit-details-marker{display:none}
.menu[open]>summary{background:var(--overlay);color:var(--acento)}
.menu-lista{position:absolute;top:calc(100% + 4px);left:0;min-width:210px;
  background:var(--panel);border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:var(--e2);display:flex;flex-direction:column;gap:2px;z-index:40}
.menu-lista button{text-align:left;border:none;background:none;
  padding:6px var(--e2);border-radius:4px;font-size:var(--t-micro);color:var(--tinta)}
.menu-lista button:hover{background:var(--overlay)}
.menu-lista label{display:flex;gap:var(--e2);align-items:center;
  font-size:var(--t-micro);padding:4px var(--e2);color:var(--tinta)}
.menu-lista hr{border:none;border-top:1px solid var(--trazo);margin:4px 0}
/* La línea de tiempo necesita hombros: sin este ancho el tramo «cerrado»
   quedaba cortado al abrir la ventana de fases. */
#tiempo-panel[open]{min-width:420px}
/* Los paneles de la izquierda, apilados.
   Antes cada uno se posicionaba en absoluto y el segundo se colgaba del alto
   del primero, medido en JavaScript y publicado en una variable CSS. Bastaba
   que un panel creciera para que el de abajo se montara encima. Una columna
   flexible hace lo mismo sin medir nada. */
.pila{position:absolute;left:var(--e4);top:calc(var(--e4) + 34px);width:290px;
  display:flex;flex-direction:column;gap:var(--e2);
  max-height:calc(100% - 34px - 76px);pointer-events:none}
.pila > .panel{pointer-events:auto;flex:0 0 auto;min-height:0}
/* Sólo el panel abierto se lleva el espacio sobrante y hace scroll: los
   cerrados ocupan su fila y ya está. */
.pila > .panel[open]{flex:0 1 auto;overflow-y:auto}
.panel .campo{margin-bottom:var(--e2)}
.panel .campo label{font-size:var(--t-micro)}

/* Nivel 2: un panel cerrado sigue diciendo su dato. El nombre a la izquierda y
   la cifra a la derecha, sin que se toquen. */
.panel > summary{display:flex;align-items:baseline;gap:var(--e2)}
.resumen{margin-left:auto;font:var(--t-dato)/1.4 var(--mono);
  font-variant-numeric:tabular-nums;color:var(--tinta-debil);text-transform:none;
  letter-spacing:0;white-space:nowrap}
.panel[open] > summary .resumen{display:none}
/* Plegado, el sumario no parte en varias líneas: el nombre y su dato caben en
   una porque el panel se estrecha a lo que necesita. Con ancho fijo, la
   leyenda plegada se partía en tres renglones. */
.panel:not([open]) > summary{white-space:nowrap}
.leyenda:not([open]){width:auto}
.efectos[hidden]{display:none}
.efectos{display:grid;grid-template-columns:1fr 1fr;gap:2px var(--e2);margin-top:var(--e2)}
.efectos label{display:flex;align-items:center;gap:5px;font-size:var(--t-micro);
  color:var(--tinta-debil);cursor:pointer}
.efectos input{accent-color:var(--acento);width:13px;height:13px}
.efectos label.on{color:var(--tinta)}
.campo.terreno{grid-column:1/-1;margin-top:var(--e2)}
.campo.terreno select{font-size:var(--t-micro)}
.suelo-g{display:grid;grid-template-columns:auto 1fr;gap:var(--e2);align-items:center;
  margin-top:var(--e2);font-size:var(--t-micro);color:var(--tinta-debil)}
.suelo-g input{width:100%}
/* La leyenda se queda **junto al mapa**, a la derecha del lienzo: es la clave
   de lo que se está mirando y llevársela a la columna de la izquierda la
   alejaría de lo que explica. Se pliega igual que las demás. */
.leyenda{position:absolute;right:var(--e4);top:var(--e4);width:250px;
  max-height:calc(100% - var(--e8));overflow-y:auto}
.leyenda:not([open]){overflow:visible}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
.leyenda-sel{display:block;margin-bottom:var(--e2)}
.leyenda-sel select{width:100%;background:var(--lienzo);color:var(--tinta);
  border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:3px var(--e2);font:var(--t-base)/1.4 var(--sans)}
.leyenda-sel select:focus{border-color:var(--acento);outline:none}
/* La leyenda lleva el límite de cada tramo escrito. Nunca sólo colores. */
.leyenda-clases{list-style:none;margin:var(--e2) 0 0;padding:0;
  display:grid;grid-template-columns:1fr 1fr;gap:1px 6px}
.leyenda-clases li{display:flex;align-items:center;gap:5px;
  font:var(--t-micro)/1.5 var(--mono);color:var(--tinta-debil)}
.leyenda-clases i{width:13px;height:9px;border-radius:1px;flex:none}
.leyenda-tira{display:flex;height:10px;border-radius:2px;overflow:hidden;margin-bottom:var(--e1)}
.leyenda-tira i{flex:1;position:relative}
.leyenda-pie{display:flex;justify-content:space-between;align-items:baseline;gap:var(--e3);
  font-size:var(--t-micro);color:var(--tinta-debil);white-space:nowrap}
.leyenda-nota strong.mal{color:var(--alarma)}
.leyenda-altura{display:grid;grid-template-columns:1fr auto auto;gap:var(--e2);
  align-items:center;margin-top:var(--e2);font-size:var(--t-micro);color:var(--tinta-debil)}
.leyenda-altura input{width:62px;background:var(--lienzo);color:var(--tinta);
  border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:2px var(--e1);font:var(--t-dato)/1.4 var(--mono);text-align:right}
.leyenda-altura input:focus{border-color:var(--acento);outline:none}
.leyenda-chk{display:flex;align-items:center;gap:5px;margin-top:var(--e2);
  font-size:var(--t-micro);color:var(--tinta-debil);cursor:pointer}
.leyenda-chk input{accent-color:var(--acento);width:13px;height:13px}
/* El display:flex de arriba pisaría al atributo hidden (curvas de nivel). */
.leyenda-chk[hidden]{display:none}
.ajustes{margin-top:var(--e2);border-top:1px solid var(--trazo);padding-top:var(--e2)}
.ajustes summary{cursor:pointer;font-size:var(--t-micro);color:var(--tinta-debil);
  list-style:none;user-select:none}
.ajustes summary::-webkit-details-marker{display:none}
.ajustes summary::before{content:"▸ ";display:inline-block;transition:transform .12s var(--ease)}
.ajustes[open] summary::before{content:"▾ "}
.ajustes summary:hover{color:var(--tinta)}
.alturas-norma{margin:var(--e1) 0 0;font-size:var(--t-micro);line-height:1.35;
  color:var(--tinta-debil);border-left:2px solid var(--trazo);padding-left:var(--e2)}
.leyenda-sin-mapa[hidden]{display:none}
.leyenda-sin-mapa{margin:0 0 var(--e2);font-size:var(--t-micro);line-height:1.35;
  color:var(--aviso);border-left:2px solid var(--aviso);padding-left:var(--e2)}
.leyenda-nota{margin:var(--e1) 0 0;font-size:var(--t-micro);line-height:1.35;
  color:var(--tinta-debil);border-top:1px solid var(--trazo);padding-top:var(--e1);max-width:236px}
.leyenda-marcas{display:flex;font:var(--t-micro)/1 var(--mono);color:var(--tinta-debil);
  justify-content:space-between;margin-bottom:3px}
/* Sonda: el nivel bajo el cursor, en el sitio donde estás mirando. */
.sonda{position:absolute;pointer-events:none;z-index:3;
  background:var(--lienzo-velado-fuerte);border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:2px var(--e2);font:var(--t-dato)/1.5 var(--mono);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.sonda em{font-style:normal;color:var(--tinta-debil);font-size:var(--t-micro)}
.espectro{display:flex;align-items:flex-end;gap:2px;height:56px;margin:var(--e2) 0 var(--e1)}
.espectro div{flex:1;background:var(--tinta-debil);border-radius:1px 1px 0 0;position:relative}
.espectro div.pico{background:var(--acento)}
/* Las TABLAS que reutilizan «espectro» (R por bandas de barrera, alero y
 * panel) sólo quieren su tipografía: el flex de la gráfica de barras las
 * aplastaba a 56 px con las filas solapadas. */
table.espectro{display:table;height:auto;align-items:initial}
.tabla-octavas{margin-bottom:var(--e2)}
.tabla-octavas td,.tabla-octavas th{height:20px;padding:1px var(--e2) 1px 0}
.tabla-octavas tr.pico td{color:var(--acento)}
.espectro-ejes{display:flex;gap:2px;font:var(--t-micro)/1.3 var(--mono);color:var(--tinta-debil)}
.espectro-ejes span{flex:1;text-align:center}
/* Edición y visualización. Va junto a las vistas porque las dos cosas son
   «cómo estoy mirando», no «qué estoy mirando». */
.modos{position:absolute;top:var(--e4);left:50%;transform:translateX(-50%);
  display:flex;gap:2px;background:var(--lienzo-velado);border:1px solid var(--trazo);
  border-radius:var(--r-control);padding:2px;z-index:4}
.modos button{font-size:var(--t-micro);padding:3px var(--e3);border:none;
  color:var(--tinta-debil);border-radius:2px}
/* Pulsado = visualización. El acento marca que la escena está bloqueada, que
   es lo que conviene notar de un vistazo antes de intentar mover algo. */
.modos button[aria-pressed="true"]{background:var(--overlay);color:var(--acento)}
.modos button:hover{color:var(--tinta)}
.obra.viendo canvas{cursor:default}
.obra.viendo .herramientas .rotulo,
.obra.viendo .herramientas button:not(#cargar-ejemplo){display:none}
.mapa-directo{margin-top:var(--e2)}
/* El mapa desactualizado tiene que verse desactualizado: un mapa viejo con
   pinta de recién calculado es la peor forma de equivocarse. */
.obra.mapa-viejo .lienzo::after{content:"";position:absolute;inset:0;
  border:2px dashed var(--aviso);pointer-events:none;opacity:.55}
.mapa-viejo-aviso{color:var(--aviso)}
.arranque{margin:0 0 var(--e3);padding-left:var(--e5);color:var(--tinta-debil);
  font-size:var(--t-micro);line-height:1.7}
.arranque strong{color:var(--tinta)}
.herramientas{position:absolute;left:var(--e4);bottom:var(--e4);right:var(--e4);
  display:flex;gap:var(--e2);align-items:center;flex-wrap:wrap}
/* Fichas de herramienta: icono encima, etiqueta debajo. La etiqueta va
   SIEMPRE (§11.4: nada de barras de iconos crípticos). */
.herramientas button:not(.rotulo){display:inline-flex;flex-direction:column;
  align-items:center;gap:2px;padding:var(--e2) var(--e3);font-size:var(--t-micro);
  line-height:1;color:var(--tinta-debil)}
.herramientas button:not(.rotulo):hover{color:var(--tinta)}
.herramientas button svg{width:18px;height:18px;fill:none;stroke:currentColor;
  stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.herramientas button svg .relleno{fill:currentColor;stroke:none}
.herramientas button[aria-pressed=true]{border-color:var(--acento);color:var(--acento)}
.lienzo canvas.colocando{cursor:crosshair}
.herramientas .rotulo{font-size:var(--t-micro);text-transform:uppercase;
  letter-spacing:.08em;color:var(--tinta-debil);margin-right:2px}
.herramientas .separa{width:1px;height:18px;background:var(--trazo);margin:0 var(--e2)}
.barra .fichero{display:flex;gap:var(--e2);margin-left:var(--e4)}
.barra .fichero button{font-size:var(--t-micro);padding:2px var(--e3)}
.pista{font-size:var(--t-micro);color:var(--tinta-debil)}

/* Panel de datos: esquema arriba, inspector debajo.
   Es la jerarquía explícita —qué hay en la escena y qué tengo elegido—, en vez
   de obligar a cazar el objeto en el lienzo para poder editarlo. */
.datos{background:var(--panel);border-left:1px solid var(--trazo);
  display:grid;grid-template-rows:auto minmax(0,1fr);min-height:0;overflow:hidden}
.esquema{border-bottom:1px solid var(--trazo);overflow-y:auto;max-height:42vh;
  padding:var(--e3) var(--e3) var(--e2)}
.esquema h3{font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.08em;
  color:var(--tinta-debil);font-weight:600;margin:var(--e3) 0 2px;padding:0 var(--e2)}
.esquema h3:first-child{margin-top:0}
.esquema .fila{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--e2);
  width:100%;align-items:baseline;border:none;background:none;text-align:left;
  padding:3px var(--e2);border-radius:var(--r-control);color:var(--tinta-debil)}
/* Sin esto, un nombre largo empuja la cifra fuera de la celda y los dos textos
   se montan. `minmax(0,1fr)` deja que la primera columna encoja; el recorte
   decide qué se pierde, que es el final del nombre y no el número. */
.esquema .fila > span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.esquema .fila .n{white-space:nowrap}
.esquema .fila:hover{background:var(--overlay)}
.esquema .fila .n{font:var(--t-dato)/1.4 var(--mono);font-variant-numeric:tabular-nums;
  color:var(--tinta-debil)}
.esquema .fila[aria-current]{background:var(--overlay);color:var(--tinta)}
/* B2: los acumulados con ⌘/Ctrl+clic — la multi-selección se ve fila a fila */
.esquema .fila.multi{outline:1px dashed var(--acento);outline-offset:-1px}
.esquema .fila[aria-current] .n{color:var(--tinta)}
.esquema .fila.hija{padding-left:var(--e6)}
.esquema .huecos summary{padding:2px var(--e2) 2px var(--e6);color:var(--tinta-debil);
  font-size:var(--t-micro);cursor:pointer;border-radius:var(--r-control)}
.esquema .huecos summary:hover{background:var(--overlay)}
.esquema .vacio{margin:0;padding:0 var(--e2) var(--e2)}
.inspector{padding:var(--e4) var(--e4) var(--e8);overflow-y:auto;min-height:0}
.inspector h2{font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.08em;
  color:var(--tinta-debil);font-weight:600;margin:0 0 var(--e2)}
.inspector h2:not(:first-child){margin-top:var(--e6)}
.migas{display:flex;align-items:center;gap:var(--e2);margin-bottom:var(--e3);
  font-size:var(--t-micro);color:var(--tinta-debil)}
.migas button{border:none;padding:1px 0;color:var(--tinta-debil);font-size:var(--t-micro)}
.migas button:hover{color:var(--acento)}
.migas [aria-current]{color:var(--tinta)}
.migas .sep{opacity:.5}
.migas .cerrar{margin-left:auto;font-size:var(--t-titulo);line-height:1}
.aviso-norma{margin:0 0 var(--e3);padding:var(--e2);border-left:2px solid var(--aviso);
  background:#E8A33D14;font-size:var(--t-micro);line-height:1.4;color:var(--tinta)}
.octavas{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--e1) var(--e2);margin-bottom:var(--e2)}
.octavas label{display:flex;flex-direction:column;gap:2px}
.octavas span{font:var(--t-micro)/1.2 var(--mono);color:var(--tinta-debil)}
.octavas input{width:100%;background:var(--lienzo);color:var(--tinta);
  border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:2px var(--e1);font:var(--t-dato)/1.4 var(--mono);text-align:right}
.acciones-fila button[aria-pressed=true]{border-color:var(--acento);color:var(--acento)}
.inspector .titulo{font-size:var(--t-titulo);font-weight:600;margin:0 0 var(--e3)}
.vacio{color:var(--tinta-debil);font-size:var(--t-base)}

.campo{display:grid;grid-template-columns:1fr auto;align-items:baseline;
  gap:var(--e1) var(--e2);margin-bottom:var(--e2)}
.campo label{font-size:var(--t-base)}
.campo label small{color:var(--tinta-debil);font-size:var(--t-micro);margin-left:var(--e1)}
.campo input{width:84px;background:var(--lienzo);color:var(--tinta);
  border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:3px var(--e2);font:var(--t-dato)/1.4 var(--mono);text-align:right}
.campo input:focus{border-color:var(--acento);outline:none}

.campo select{width:150px;background:var(--lienzo);color:var(--tinta);
  border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:3px var(--e2);font:var(--t-dato)/1.4 var(--sans)}
.personas{display:flex;flex-direction:column;gap:3px;margin-bottom:var(--e2)}
.persona{display:grid;grid-template-columns:26px 1fr;gap:var(--e2);align-items:center}
/* Quien habla es una fuente acústica: se distingue por valor, no por color. */
.persona .conmuta{padding:0;height:24px;text-align:center;font:var(--t-dato)/24px var(--mono);
  color:var(--tinta-debil);border-color:var(--trazo)}
.persona.habla .conmuta{color:var(--lienzo);background:var(--tinta);border-color:var(--tinta);font-weight:600}
.persona select{width:100%;background:var(--lienzo);color:var(--tinta-debil);
  border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:2px var(--e2);font:var(--t-micro)/1.5 var(--sans)}
.persona.habla select{color:var(--tinta)}
.persona select:disabled{opacity:.45}
/* Reparto de una agrupación: se edita el %, pero manda la columna de personas,
   que es el número que entra en el cálculo. */
.mezcla{width:100%;margin-bottom:var(--e2)}
.mezcla th,.mezcla td{padding:2px 0}
.mezcla td:first-child label{color:var(--tinta-debil);font:var(--t-micro)/1.5 var(--sans)}
.mezcla input{width:5ch;text-align:right;background:var(--lienzo);color:var(--tinta);
  border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:2px var(--e1);font:var(--t-dato)/1.4 var(--mono);font-variant-numeric:tabular-nums}
.mezcla td.n{font:var(--t-dato)/1.4 var(--mono);font-variant-numeric:tabular-nums;
  text-align:right;color:var(--tinta)}
.mezcla.espectro input,.mezcla.espectro td.n{font-size:10px}
/* Con 5ch el spinner del número tapaba el segundo dígito («20» se leía «2»). */
.mezcla.espectro input{width:8ch}
.mezcla.espectro th.n{font:10px/1.4 var(--mono);color:var(--tinta-debil)}
/* Matriz banda × cara de la fuente caja: seis columnas en 320 px, sin spinner. */
.mezcla.caras-caja input{width:5ch;padding:2px 3px;appearance:textfield;-moz-appearance:textfield}
.mezcla.caras-caja input::-webkit-inner-spin-button,.mezcla.caras-caja input::-webkit-outer-spin-button{display:none}
.mezcla.caras-caja th{font:10px/1.3 var(--mono);color:var(--tinta-debil);text-align:center;vertical-align:bottom}
.mezcla.caras-caja th label{display:block;cursor:pointer}
.mezcla.caras-caja td{text-align:center}
.mezcla.caras-caja td:first-child{text-align:left}
.mezcla.caras-caja tr.global td{border-top:1px solid var(--trazo);padding-top:var(--e1)}
.mezcla.espectro td:first-child{font:var(--t-dato)/1.4 var(--mono);color:var(--tinta-debil)}
.mezcla .resto td{color:var(--tinta-debil);border-top:1px solid var(--trazo);padding-top:var(--e2)}
/* Vistas guardadas: una lista, no una rejilla de miniaturas. Una miniatura de
   40 px de un mapa de ruido no distingue nada; el nombre, sí. */
.vistas-guardadas{display:flex;flex-direction:column;gap:2px;margin-bottom:var(--e3)}
.vista-guardada{display:grid;grid-template-columns:1fr auto;gap:var(--e2);align-items:center}
.vista-guardada .ir{width:100%;text-align:left;font-size:var(--t-micro);
  padding:3px var(--e2);border-color:var(--trazo);color:var(--tinta-debil)}
.vista-guardada .ir:hover{color:var(--acento);border-color:var(--acento)}
.vista-guardada .quitar{border:none;padding:0 var(--e2);color:var(--tinta-debil);
  font-size:var(--t-base);line-height:1}
.vista-guardada .quitar:hover{color:var(--aviso)}
.pista-inline{margin:0 0 var(--e3);font-size:var(--t-micro);line-height:1.5;
  color:var(--tinta-debil)}
.acciones-fila{display:flex;gap:var(--e2);margin-bottom:var(--e2);flex-wrap:wrap}
.acciones-fila button{font-size:var(--t-micro);padding:3px var(--e2)}
.dato{display:flex;justify-content:space-between;align-items:baseline;
  padding:3px 0;border-bottom:1px solid #ffffff0a;font-size:var(--t-base)}
.dato span{color:var(--tinta-debil);font-size:var(--t-micro)}
.dato b{font:600 var(--t-dato)/1.5 var(--mono)}
.dato b em{font-style:normal;font-weight:400;color:var(--tinta-debil);font-size:var(--t-micro)}

table{border-collapse:collapse;width:100%;font-size:var(--t-dato)}
th{text-align:left;font:600 var(--t-micro)/1.4 var(--sans);color:var(--tinta-debil);
  text-transform:uppercase;letter-spacing:.06em;padding:0 var(--e2) var(--e1) 0;
  border-bottom:1px solid var(--trazo)}
th.n,td.n{text-align:right}
td{padding:2px var(--e2) 2px 0;border-bottom:1px solid #ffffff0a;font-family:var(--mono);height:24px}
tr.sel td{color:var(--acento)}

/* ---------- línea de tiempo ---------- */
.tiempo{height:var(--tiempo-h);background:var(--panel);border-top:1px solid var(--trazo);
  padding:var(--e2) var(--e4)}
.tiempo-cab{display:flex;align-items:baseline;gap:var(--e3);margin-bottom:var(--e2)}
/* El pie se pliega como todo lo demás, y plegado sigue diciendo su resumen:
   qué periodo, cuántas horas de actividad. Es el mismo nivel 2 de los paneles
   flotantes, y por eso no hace falta explicarlo dos veces. */
#tiempo-plegar{border:none;padding:0 var(--e1);color:var(--tinta-debil);
  font-size:var(--t-micro);line-height:1}
#tiempo-plegar:hover{color:var(--tinta)}
body.tiempo-plegado{--tiempo-h:34px}
body.tiempo-plegado .tiempo{overflow:hidden}
body.tiempo-plegado .tiempo-cab{margin-bottom:0}
body.tiempo-plegado #tiempo-plegar{transform:rotate(-90deg)}
.tiempo-cab h2{font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.08em;
  color:var(--tinta-debil);font-weight:600;margin:0}
#tiempo-resumen{font-size:var(--t-micro);color:var(--tinta-debil);flex:1}
.regla{display:flex;font:var(--t-micro)/1 var(--mono);color:var(--tinta-debil);
  border-bottom:1px solid var(--trazo);padding-bottom:2px;margin-bottom:3px}
.regla i{flex:1;font-style:normal;text-align:left}
.fases{display:flex;height:34px;gap:1px}
.fase{position:relative;background:#ffffff12;border-radius:2px;overflow:hidden;
  display:flex;flex-direction:column;justify-content:center;padding:0 var(--e2);min-width:0}
.fase .pct{font:600 var(--t-dato)/1.2 var(--mono)}
.fase .h{font:var(--t-micro)/1.2 var(--mono);color:var(--tinta-debil)}
.fase.cerrado{background:#ffffff06}
.fase.cerrado .pct{color:var(--tinta-debil);font-weight:400}
.fase .pct,.fase .h{display:flex;align-items:baseline;gap:3px;white-space:nowrap}
.fase .pct em,.fase .h em{font-style:normal;color:var(--tinta-debil);font-size:var(--t-micro)}
.fase input{width:3.2em;background:none;border:none;color:inherit;font:inherit;padding:0}
.fase input:focus{outline:1px solid var(--acento)}
.fase button{position:absolute;top:2px;right:3px;padding:0 3px;border:none;
  color:var(--tinta-debil);font-size:var(--t-micro);line-height:1}
.fase button:hover{color:var(--alarma)}

/* ---------- trazabilidad (única superficie con sombra) ---------- */
/* El `display` de una regla de autor gana al `[hidden]{display:none}` del
   navegador. Sin esta línea el modal no se oculta nunca y tapa la aplicación
   entera. Toda regla que fije `display` sobre un elemento con `hidden` necesita
   su pareja; lo comprueba apps/web/verificar_ui.mjs. */
.traza[hidden]{display:none}
.traza{position:fixed;inset:0;background:#000000a6;display:grid;place-items:center;z-index:10}
.traza-caja{background:var(--overlay);border:1px solid #3D3D3D;border-radius:var(--r-panel);
  box-shadow:var(--sombra);width:min(560px,92vw);max-height:80vh;overflow-y:auto;padding:var(--e4)}
.traza-caja header{display:flex;align-items:baseline;gap:var(--e3);margin-bottom:var(--e3)}
.traza-caja h2{font-size:var(--t-titulo);margin:0;flex:1}
.traza-caja button{border:none;font-size:var(--t-display);line-height:1;color:var(--tinta-debil)}
.traza-caja dl{margin:0 0 var(--e4);display:grid;grid-template-columns:auto 1fr;
  gap:var(--e1) var(--e3);font-size:var(--t-base)}
.traza-caja dt{color:var(--tinta-debil);font-size:var(--t-micro);text-transform:uppercase;
  letter-spacing:.06em;padding-top:2px}
.traza-caja dd{margin:0;font-family:var(--mono);font-size:var(--t-dato)}
.hipotesis{font-size:var(--t-base);border-left:2px solid var(--trazo);
  padding:2px 0 2px var(--e3);margin-bottom:var(--e2)}
.hipotesis code{font:var(--t-micro)/1.4 var(--mono);color:var(--aviso);display:block}

/* Visor de directividad: ocupa el ancho del panel, que se puede estirar. */
.visor {
  display: block;
  width: 100%;
  margin: var(--e2) 0;
}

/* Nivel 1 y 2 del esquema: cada grupo se pliega y, plegado, dice cuántos hay. */
.esquema .grupo > summary{display:flex;align-items:baseline;gap:var(--e2);
  font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.08em;
  color:var(--tinta-debil);font-weight:600;margin:var(--e3) 0 2px;
  padding:2px var(--e2);cursor:pointer;list-style:none;border-radius:var(--r-control)}
.esquema .grupo > summary::-webkit-details-marker{display:none}
.esquema .grupo > summary::before{content:"▸";opacity:.6;font-size:9px}
.esquema .grupo[open] > summary::before{content:"▾"}
.esquema .grupo > summary:hover{background:var(--overlay);color:var(--tinta)}
.esquema .grupo:first-child > summary{margin-top:0}
.esquema .grupo .cuenta{margin-left:auto;font:var(--t-dato)/1.4 var(--mono);
  font-variant-numeric:tabular-nums;text-transform:none;letter-spacing:0}

/* Nivel 0: el panel cerrado, encogido a su icono.
   Es el escalón que faltaba por debajo de «cerrado con su dato». En una
   pantalla con mapa, cortes y una manzana cargada, tres paneles de 290 px se
   comen la escena aunque estén plegados.

   El icono **no va desnudo**: conserva su `title` y su nombre accesible, que es
   lo que la spec §11 exige de un icono. Y es un modo que se elige, no el estado
   por defecto: quien no lo active nunca ve un icono sin texto. */
.lienzo.iconos .pila{width:auto}
.lienzo.iconos .panel:not([open]){width:auto}
.lienzo.iconos .leyenda:not([open]){width:auto;left:auto}
/* `font-size:0` se lleva el texto del sumario; el `::before` recupera el suyo. */
.lienzo.iconos .panel:not([open]) > summary{gap:0;font-size:0;padding:1px 2px}
.lienzo.iconos .panel:not([open]) > summary::before{
  content:attr(data-icono);font-size:15px;line-height:1.2}
.lienzo.iconos .panel:not([open]) .resumen{display:none}
#densidad[aria-pressed=true]{border-color:var(--acento);color:var(--acento)}

/* En la vista del patrón no se está tocando la escena: sus mandos estorban y
   además tapan el dibujo. Se quedan sólo los botones de vista, que son la
   salida. */
.lienzo.patron .pila,
.lienzo.patron .leyenda,
.lienzo.patron .herramientas,
.lienzo.patron .modos{display:none}

/* La barra de herramientas también tiene su nivel plegado: un «+» y ya.
   Ocho botones cruzando el pie son ocho cosas compitiendo con la escena
   mientras no se está creando nada. */
.herramientas .rotulo{border:1px solid var(--trazo);border-radius:var(--r-control);
  padding:var(--e1) var(--e3);cursor:pointer;color:var(--tinta-debil);
  font-size:var(--t-base);line-height:1.2}
.herramientas .rotulo:hover{border-color:var(--tinta-debil);color:var(--tinta)}
.herramientas .rotulo[aria-expanded=true]{border-color:var(--acento);color:var(--acento)}
.herramientas.plegada button:not(.rotulo),
.herramientas.plegada .grupo-herr,
.herramientas.plegada .pista{display:none}

/* Familias de la paleta como DESPLEGABLES, con la misma gramática ▸/▾ que
   los paneles de datos (coherencia visual, Salva 12-ago-2026). Cerrada,
   una familia es sólo su rótulo; abierta, el rótulo y sus fichas en fila. */
.herramientas .grupo-herr{flex-basis:100%;display:flex;align-items:center;
  gap:var(--e2);flex-wrap:wrap}
.herramientas .grupo-herr>summary{list-style:none;cursor:pointer;
  font:var(--t-micro)/1.2 var(--sans);color:var(--tinta-debil);
  text-transform:uppercase;letter-spacing:.08em;margin:0 2px;min-width:9ch}
.herramientas .grupo-herr>summary::-webkit-details-marker{display:none}
.herramientas .grupo-herr>summary::before{content:"▸ "}
.herramientas .grupo-herr[open]>summary::before{content:"▾ "}
.herramientas .grupo-herr>summary:hover{color:var(--tinta)}

/* La interfaz no es un documento: arrastrar no debe ir dejando textos
   seleccionados (pedido de Salva, 11-ago-2026). Los campos de entrada sí
   siguen siendo texto de verdad. */
body{-webkit-user-select:none;user-select:none}
input,textarea,select,[contenteditable="true"]{-webkit-user-select:text;user-select:text}

/* Rótulo de colocación: al armar una herramienta la paleta se pliega, y este
   aviso —arriba, centrado— es lo único que dice qué se está colocando
   (pedido de Salva, 13-ago-2026). */
#colocando-aviso{position:absolute;top:calc(var(--e4) + 42px);left:50%;transform:translateX(-50%);
  z-index:6;padding:4px 12px;border:1px solid var(--acento);border-radius:999px;
  background:var(--papel);color:var(--acento);font:var(--t-dato)/1.4 var(--sans);
  pointer-events:none;white-space:nowrap}

/* Insertar con anidación y scroll (Salva, 20-ago: «no se puede acceder a
   todos los elementos»): secciones plegables y la lista nunca más alta que
   la ventana. */
.menu-lista{max-height:calc(100vh - 72px);overflow-y:auto}
.menu-sub{border:0;margin:0}
.menu-sub>summary{cursor:pointer;padding:4px 10px;font-size:.72rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--tinta-debil);
  list-style-position:inside}
.menu-sub>summary:hover{color:var(--tinta)}
.menu-sub>button{width:100%;text-align:left}

/* B1 · tabla de resultados por receptor */
#resultados,#manual,#exposicion-v,#dosimetria-v,#cronograma-v,#informe-v,#relato-v,.rel-progreso,#planificador{background:var(--panel);color:var(--tinta);border:1px solid var(--trazo);
  border-radius:var(--r-panel);padding:var(--e4)}
#resultados::backdrop,#manual::backdrop,#exposicion-v::backdrop,#dosimetria-v::backdrop,#cronograma-v::backdrop,#informe-v::backdrop,#relato-v::backdrop,.rel-progreso::backdrop,#planificador::backdrop{background:#000a}
.res-cabecera{display:flex;gap:var(--e3);align-items:center;margin-bottom:var(--e3);
  flex-wrap:wrap}
.res-cabecera .sep{flex:1}
.res-badge{font-size:var(--t-micro);color:var(--aviso)}
/* Maquetación firme (Salva, 22-ago): cabeceras sin partir y números a la
   derecha SIEMPRE — columnas que no bailan. */
.res-tabla th{white-space:nowrap}
/* El gestor del informe. */
.inf-bloques{list-style:none;margin:var(--e3) 0;padding:0;display:flex;
  flex-direction:column;gap:var(--e1)}
.inf-bloques li{display:flex;align-items:flex-start;gap:var(--e2);
  padding:var(--e1) var(--e2);border:1px solid var(--trazo);border-radius:4px}
.inf-bloques label{flex:1;display:flex;gap:var(--e2);align-items:center}
.inf-bloques textarea{flex:2;background:var(--overlay);color:var(--tinta);
  border:1px solid var(--trazo);border-radius:4px;font:inherit;padding:4px}
.inf-orden button{min-width:24px}
/* La cámara va DENTRO de .vistas (arriba-izquierda): flotando en la esquina
   derecha tapaba el summary del panel «Leyenda y magnitud». */
#capturar{background:var(--panel);color:var(--tinta);border:1px solid var(--trazo);
  border-radius:6px;padding:5px 9px;cursor:pointer}
#capturar:hover{background:var(--overlay)}

/* Botón secundario: acción de respaldo en letra pequeña. */
button.secundario{font-size:var(--t-micro);color:var(--tinta-debil);
  background:transparent;border:1px dashed var(--trazo)}

/* El diseñador SDE: editor a PANTALLA COMPLETA con dos columnas
   (modelos | cajas) — pedido de Salva, 26-ago. */
#sde-disenador{width:96vw;height:94vh;max-width:none;max-height:none}
#sde-grafico{width:100%;height:180px;border:1px solid var(--trazo);
  border-radius:4px;background:var(--lienzo)}
.sde-guia{margin:var(--e2) 0;border:1px dashed var(--trazo);border-radius:4px;
  padding:var(--e1) var(--e2)}
.sde-guia ol{margin:var(--e2) 0 var(--e1) var(--e4)}
.sde-guia li{margin-bottom:4px}
.sde-columnas{display:grid;grid-template-columns:minmax(340px,2fr) 3fr;
  gap:var(--e4);align-items:start}
.sde-columnas section{min-width:0;overflow-x:auto}
.sde-octavas td{padding:2px}
@media (max-width:1100px){.sde-columnas{grid-template-columns:1fr}}

/* El panel de calibración: la lista de fuentes en columnas. */
.cal-fuentes{columns:3 220px;column-gap:var(--e4);margin:var(--e2) 0}
.cal-fuentes label{display:block;break-inside:avoid;margin-bottom:2px}

/* Los días de una franja del trabajador: checkbox compacto por letra. */
.fr-dia{display:inline-flex;flex-direction:column;align-items:center;
  margin-right:2px;font-size:var(--t-micro);color:var(--tinta-debil)}
.fr-dia input{margin:0}

/* El cronograma: rejilla semanal pintable. */
.cr-tabla{border-collapse:collapse;margin:var(--e3) 0;user-select:none}
.cr-tabla th{font-size:var(--t-micro);color:var(--tinta-debil);padding:1px 2px}
.cr-tabla td{width:22px;height:20px;border:1px solid var(--trazo);cursor:crosshair}
.cr-tabla td:hover{outline:1px solid var(--acento)}
.cr-pinceles{display:flex;gap:var(--e2);align-items:center;flex-wrap:wrap;margin:var(--e2) 0}
.cr-pincel i{display:inline-block;width:10px;height:10px;border:1px solid var(--trazo);
  border-radius:2px;margin-right:4px;vertical-align:-1px}
.cr-pincel.sel{outline:2px solid var(--acento)}
/* Filas de camino del receptor de rayos: clicables, la elegida resaltada. */
.tabla-lw tr.cam-fila{cursor:pointer}
.tabla-lw tr.cam-fila:hover{background:var(--overlay)}
.tabla-lw tr.cam-fila.sel{background:var(--overlay);outline:1px solid var(--acento)}
.res-tabla th.n,.res-tabla td.n{text-align:right;font-variant-numeric:tabular-nums}
.res-cuenta{font-size:var(--t-micro);color:var(--tinta-debil)}
.res-tabla{max-height:64vh;overflow:auto}
.res-tabla th.ordenable{cursor:pointer;white-space:nowrap}
.res-tabla th.ordenable:hover{color:var(--acento)}
.res-tabla tbody tr[data-id]{cursor:pointer}
.res-tabla tbody tr[data-id]:hover td{background:var(--overlay)}
.res-supera td{color:var(--alarma)}
.res-bandas td{background:var(--overlay)}
.res-despliega{padding:0 6px;border:none}
/* El planificador de cálculos (Salva, 2-sep): LÍNEAS mapa × variante ×
   magnitud, cada una con su carpeta; la fila del caso actual, resaltada. */
.plan-tabla td,.plan-tabla th[scope=row]{vertical-align:top}
.plan-tabla td small{display:block;color:var(--tinta-debil);font-size:var(--t-micro)}
.plan-tabla tr.plan-actual td,.plan-tabla tr.plan-actual th{background:var(--overlay)}
.plan-tabla tr.plan-actual th{box-shadow:inset 2px 0 var(--acento)}
.plan-ruta{display:inline-flex;gap:2px;align-items:center}
.plan-ruta input{width:16ch;font-size:var(--t-micro)}
.plan-ruta button{padding:0 6px}
.plan-nueva label,.plan-pie label{display:flex;gap:6px;align-items:center;white-space:nowrap}
.plan-pie .campo{grid-template-columns:auto auto}
.plan-pie #plan-carpeta{width:28ch}
#plan-cada{width:6ch}
/* Las cabeceras son DATOS (nombre de variante «Pantalla 3 m», «celda 0,15 m»),
   no rótulos: sin mayúsculas — «0.15 M» convertía metros en mega. */
.plan-tabla th{text-transform:none;letter-spacing:0}
.plan-tabla th[scope=row]{font-size:var(--t-dato)}
.plan-tabla th[scope=row] small{display:block;font-weight:normal;color:var(--tinta-debil)}
.plan-tabla label{display:flex;gap:6px;align-items:center;cursor:pointer;white-space:nowrap}
.plan-corre{color:var(--acento)}
.plan-hecho{color:var(--tinta-debil)}
.plan-hecho button{padding:0 6px;font-size:var(--t-micro)}
.plan-mal{color:var(--alarma)}
.plan-barra{height:3px;background:var(--overlay);margin:0 0 var(--e2);border-radius:2px;overflow:hidden}
.plan-barra i{display:block;height:100%;background:var(--acento);transition:width .3s}

/* ---------- B7 · informe imprimible ---------- */
/* En pantalla el informe no existe; al imprimir, SOLO existe él. */
#informe{display:none}
@media print{
  body>*:not(#informe){display:none !important}
  #informe{display:block;color:#000;background:#fff;font:11pt/1.45 system-ui,sans-serif}
  #informe header{border-bottom:2px solid #000;margin-bottom:12pt;padding-bottom:6pt}
  #informe h1{font-size:18pt;margin:0 0 4pt}
  #informe h2{font-size:13pt;margin:14pt 0 6pt;border-bottom:1px solid #999;
    page-break-after:avoid}
  #informe h3{font-size:11pt;margin:10pt 0 4pt;page-break-after:avoid}
  #informe table{border-collapse:collapse;width:100%;margin:6pt 0;
    font-size:9.5pt}
  #informe thead{display:table-header-group}
  #informe tr{break-inside:avoid}
  #informe th,#informe td{border:1px solid #999;padding:2pt 5pt;text-align:right}
  #informe th:first-child,#informe td:first-child{text-align:left}
  #informe figure{margin:8pt 0;page-break-inside:avoid}
  #informe figcaption{font-size:9pt;color:#333;margin-top:2pt}
  #informe .texto-libre p{margin:5pt 0;text-align:justify}
  #informe figure img{max-width:100%;border:1px solid #999}
  #informe .leyenda{display:flex;flex-wrap:wrap;gap:4pt 10pt;font-size:8.5pt;
    margin-top:4pt;align-items:center}
  #informe .leyenda i{display:inline-block;width:10pt;height:10pt;
    margin-right:3pt;vertical-align:-1.5pt;border:0.5pt solid #666}
  #informe .nota{font-size:9pt;color:#333}
  #informe ul{font-size:9pt;padding-left:14pt}
  #informe .hipotesis li{margin-bottom:3pt;page-break-inside:avoid}
  #informe footer{margin-top:14pt;border-top:1px solid #999;padding-top:4pt;
    font-size:8.5pt;color:#333}
}

/* ---------- manual de consulta ---------- */
/* SOLO abierto: sin [open] este display pisa el display:none del dialog
 * cerrado y el manual «no se cerraba» (Salva, 22-ago). */
#manual[open]{display:flex;flex-direction:column}
#manual .res-cabecera input[type=search]{flex:0 1 34ch;background:var(--overlay);
  border:1px solid var(--trazo);border-radius:var(--r-control);color:var(--tinta);
  padding:var(--e1) var(--e2);font:inherit}
.man-cuerpo{display:grid;grid-template-columns:220px minmax(0,1fr);
  gap:var(--e4);min-height:0;flex:1}
.man-indice{overflow-y:auto;border-right:1px solid var(--trazo);
  padding-right:var(--e2);display:flex;flex-direction:column;gap:2px}
.man-cap{text-align:left;border:none;padding:var(--e1) var(--e2);
  border-radius:var(--r-control);color:var(--tinta-debil)}
.man-cap:hover{color:var(--tinta);background:var(--overlay)}
.man-cap.activo{color:var(--tinta);background:var(--overlay);font-weight:600}
.man-texto{overflow-y:auto;min-width:0;padding-right:var(--e3);
  line-height:1.6;font-size:var(--t-base)}
.man-texto h2{font-size:var(--t-display);margin:0 0 var(--e3)}
.man-texto h3{font-size:var(--t-titulo);margin:var(--e6) 0 var(--e2);
  color:var(--tinta)}
.man-texto p{margin:0 0 var(--e3);color:var(--tinta-debil)}
.man-texto strong{color:var(--tinta)}
.man-texto em{color:var(--tinta)}
.man-texto ul{margin:0 0 var(--e3);padding-left:var(--e4);color:var(--tinta-debil)}
.man-texto li{margin-bottom:var(--e2)}

/* ---------- Relato para el cliente (docs/spec-relato-cliente.md) ---------- */
/* El gestor. */
#relato-v{width:min(96vw,980px);max-height:92vh;overflow:auto}
.rel-portada{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:var(--e2) var(--e3);margin-bottom:var(--e3)}
.rel-portada label,.rel-ficha label{display:flex;gap:var(--e2);align-items:center;
  font-size:var(--t-micro);color:var(--tinta-debil)}
.rel-portada input:not([type=file]),.rel-ficha input:not([type=checkbox]),.rel-ficha select,
.rel-ficha textarea,#rel-url,.rel-url{flex:1;min-width:0;background:var(--overlay);color:var(--tinta);
  border:1px solid var(--trazo);border-radius:4px;font:inherit;padding:4px 6px}
.rel-logo-mini{height:28px;border-radius:4px}
.rel-cuerpo{display:grid;grid-template-columns:minmax(220px,1fr) 2fr;gap:var(--e4)}
.rel-caps li.sel{border-color:var(--acento)}
.rel-caps .rel-cap{flex:1;text-align:left;display:flex;flex-direction:column;
  align-items:flex-start;gap:2px;background:none;border:0;color:var(--tinta);cursor:pointer}
.rel-caps .rel-cap small{color:var(--tinta-debil)}
.rel-ficha{display:flex;flex-direction:column;gap:var(--e2)}
.rel-ficha label:has(textarea){align-items:flex-start}
.rel-ficha textarea{line-height:1.5}
.rel-fila{display:flex;flex-wrap:wrap;gap:var(--e2) var(--e3);align-items:center;
  font-size:var(--t-micro);color:var(--tinta-debil)}
.rel-fila>span{min-width:9ch}
.rel-fila label:has([type=checkbox]){gap:4px}
#rel-url{margin-left:var(--e2);width:min(46ch,100%)}
.rel-progreso{min-width:min(90vw,420px)}
.rel-progreso .mono{min-height:1.4em;color:var(--tinta-debil)}
.rel-progreso .rel-url{width:100%;margin-top:var(--e1)}
@media (max-width:760px){.rel-cuerpo{grid-template-columns:1fr}}

/* El visor: modo CLIENTE. Solo el lienzo y la tarjeta; ni barra, ni
   inspector, ni herramientas, ni paneles — nada que se pueda romper. */
body.cliente .barra,body.cliente .mandos-interior,body.cliente .vistas,
body.cliente #colocando-aviso,body.cliente .pila,body.cliente .modos,
body.cliente .herramientas,body.cliente .tirador,body.cliente .datos,
body.cliente .recoger,body.cliente .traza-caja,body.cliente #leyenda{display:none!important}
body.cliente .obra{grid-template-columns:minmax(0,1fr) 0;height:100vh}
body.cliente .obra.mapa-viejo .lienzo::after{display:none}
.relato{position:absolute;inset:0;pointer-events:none;display:flex;
  flex-direction:column;justify-content:flex-end;align-items:flex-start;
  padding:var(--e4);gap:var(--e3);font-size:var(--t-base);line-height:1.55}
.relato>*{pointer-events:auto}
.rel-tarjeta{background:color-mix(in srgb,var(--panel) 92%,transparent);
  color:var(--tinta);border:1px solid var(--trazo);border-radius:var(--r-panel);
  box-shadow:var(--sombra);padding:var(--e4) var(--e6);
  max-width:min(520px,calc(100vw - 2*var(--e4)));max-height:70vh;overflow:auto;
  backdrop-filter:blur(6px);animation:rel-entra .5s var(--ease)}
@keyframes rel-entra{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.rel-centro{align-self:center;margin:auto;text-align:center}
.rel-tarjeta h1{font-size:var(--t-display);margin:0 0 var(--e2)}
.rel-tarjeta h2{font-size:var(--t-titulo);margin:0 0 var(--e2)}
.rel-tarjeta p{margin:0 0 var(--e2);color:var(--tinta-debil)}
.rel-tarjeta .rel-num{color:var(--tinta-debil);font-size:var(--t-micro)}
.rel-portada-v{max-width:min(640px,calc(100vw - 2*var(--e4)));padding:var(--e6) var(--e8)}
.rel-portada-v .rel-logo{max-height:64px;max-width:240px;margin-bottom:var(--e3)}
.rel-portada-v .rel-para{font-size:var(--t-titulo);color:var(--tinta)}
.rel-portada-v .rel-por,.rel-portada-v .rel-n{font-size:var(--t-micro)}
.rel-empezar,.rel-nav button,.rel-oir,.rel-tarjeta form button{background:var(--acento);
  color:#fff;border:0;border-radius:var(--r-control);padding:8px 18px;font:inherit;
  font-size:var(--t-base);cursor:pointer}
.rel-empezar{font-size:var(--t-titulo);padding:10px 28px;margin-top:var(--e3)}
.rel-nav button:disabled{opacity:.35;cursor:default}
.rel-tarjeta form{display:flex;gap:var(--e2);justify-content:center}
.rel-tarjeta form input{background:var(--overlay);color:var(--tinta);border:1px solid var(--trazo);
  border-radius:var(--r-control);padding:8px 10px;font:inherit;font-size:var(--t-base)}
.rel-mal{color:var(--alarma);min-height:1.5em}
.rel-tabla{border-collapse:collapse;margin:var(--e2) 0 var(--e1);width:100%}
.rel-tabla th{text-align:left;font-weight:500;color:var(--tinta-debil);
  border-bottom:1px solid var(--trazo);padding:4px 8px;white-space:nowrap}
.rel-tabla td{padding:5px 8px;border-bottom:1px solid color-mix(in srgb,var(--trazo) 50%,transparent)}
.rel-tabla td.mono{text-align:right}
.rel-tabla strong{font-size:var(--t-titulo)}
.rel-mejora{color:var(--acento)}
.rel-nocumple{color:var(--alarma)}
.rel-unidad,.rel-audio small{color:var(--tinta-debil);font-size:var(--t-micro)}
.rel-hueco{color:var(--aviso)}
.rel-audio{display:flex;flex-wrap:wrap;gap:var(--e2);align-items:center;margin:var(--e2) 0}
.rel-oir{background:var(--overlay);color:var(--tinta);border:1px solid var(--trazo)}
.rel-oir[aria-pressed=true]{background:var(--acento);color:#fff;border-color:var(--acento)}
.rel-leyenda{margin-top:var(--e2);font-size:var(--t-micro);display:flex;flex-wrap:wrap;gap:4px 10px;align-items:center;color:var(--tinta-debil)}
.rel-leyenda span{display:inline-flex;align-items:center;gap:4px;font-family:var(--mono)}
.rel-leyenda i{width:14px;height:9px;border-radius:1px;display:inline-block}
.rel-nav{display:flex;gap:var(--e2);align-items:center;
  background:color-mix(in srgb,var(--panel) 92%,transparent);border:1px solid var(--trazo);
  border-radius:999px;padding:6px 8px;box-shadow:var(--sombra)}
.rel-nav .rel-volver{background:var(--overlay);color:var(--tinta);border:1px solid var(--trazo)}
.rel-puntos{display:flex;gap:6px;padding:0 var(--e2)}
.rel-puntos i{width:8px;height:8px;border-radius:50%;background:var(--trazo);cursor:pointer}
.rel-puntos i.on{background:var(--acento)}
@media (max-width:640px){
  .relato{padding:var(--e2);align-items:stretch}
  .rel-tarjeta{max-width:none;max-height:55vh;padding:var(--e3)}
  .rel-nav{align-self:center}
}

/* ---------- Cuenta y licencia de TECOMA ONE (sesion.js, features.js) ---------- */
/* Lo cerrado por nivel va `inert` (sin clic, foco ni teclado) y lo dice. */
[data-pro][inert]{opacity:.55;cursor:not-allowed}
[data-pro][inert]::after{content:" 🔒 PRO";font-size:var(--t-micro);color:var(--tinta-debil)}
div[data-pro][inert]::after{display:block;margin:var(--e1) 0 var(--e2)}
#cuenta{text-decoration:none;white-space:nowrap}
#cuenta:hover{color:var(--acento)}
/* La capa tapa la app entera: sin licencia no se trabaja, pero la escena sigue
   debajo (el puesto puede volver con Reintentar). */
#licencia{position:fixed;inset:0;z-index:60;display:grid;place-items:center;
  background:rgba(0,0,0,.72);backdrop-filter:blur(3px)}
#licencia .tarjeta{background:var(--panel);border:1px solid var(--trazo);border-radius:var(--r-panel);
  width:min(480px,92vw);padding:var(--e6);font-size:var(--t-base)}
#licencia h2{margin:0 0 var(--e3);font-size:var(--t-titulo)}
#licencia ul{margin:0 0 var(--e3);padding-left:var(--e4)}
#licencia a{color:var(--acento)}
#licencia .acciones-fila{margin:var(--e4) 0 0;align-items:center}
