/* ---------- Mufa modular (public/mufa-modular.js) ----------
   Estático a propósito, no inyectado por JS en tiempo de ejecución: así no
   depende de que ningún script termine de correr para que se vea bien — se
   aplica igual que cualquier otro <link rel="stylesheet">, apenas carga la
   página. Lo enlazan tanto index.html (la app completa) como
   mufa-preview.html (la vista suelta, para iterar sin cargar todo lo demás)
   — un solo archivo, cero riesgo de que ambas terminen desincronizadas. */
#mufaModularOverlay{
  /* z-index:60 se quedaba corto: el topbar de la app ya usa 1000-1002, el
     panel de detalle 1000, y el resto de modales llegan hasta 4600 —
     encima de eso, los panes internos de Leaflet (tiles, marcadores,
     tooltips) rondan 200-700. Con 60 la ventana quedaba TAPADA por el mapa
     y por el resto de la interfaz en vez de superponerse. */
  display:none; position:fixed; inset:0; background:rgba(4,7,10,.55); z-index:5000;
  align-items:center; justify-content:center; padding:18px; pointer-events:none;
}
#mufaModularOverlay.show{display:flex;}
/* A diferencia de un modal normal, esto se comporta como una ventana
   flotante de verdad (igual que el diagrama clásico, pero además
   arrastrable) — por eso el fondo NO bloquea clics (pointer-events:none) y
   solo el panel en sí los recibe: se puede seguir viendo/usando el mapa de
   fondo, no es una pantalla completa que "tapa todo". */
.mm-modal{
  background:var(--panel); border:1px solid var(--line); border-radius:14px;
  width:min(1100px, 88vw); height:min(720px, 82vh); display:flex; flex-direction:column; overflow:hidden;
  box-shadow:0 30px 80px rgba(0,0,0,.55); pointer-events:auto;
}
.mm-header{display:flex; align-items:center; gap:10px; padding:14px 18px; border-bottom:1px solid var(--line);}
.mm-header-actions{cursor:default;}
.mm-header h3{font-size:15px; font-weight:650; margin:0;}
.mm-header-actions{display:flex; gap:8px; margin-left:auto;}
.mm-btn{
  font-family:inherit; font-size:12px; font-weight:600; padding:7px 12px; border-radius:7px;
  cursor:pointer; border:1px solid var(--line); background:#17305a; color:var(--text);
}
.mm-btn:hover{border-color:#395c94;}
.mm-view-toggle{display:flex; gap:2px; background:#0c1a30; border:1px solid var(--line); border-radius:7px; padding:2px;}
.mm-view-toggle .mm-btn{border:none; background:transparent; padding:4px 10px;}
.mm-view-toggle .mm-btn.active{background:#34d399; color:#04160d;}
.mm-body{flex:1; display:grid; grid-template-columns:230px 1fr 340px; overflow:hidden; min-height:0;}
.mm-col{overflow-y:auto; min-height:0;}
.mm-cables{border-right:1px solid var(--line); padding:12px;}
.mm-traydetail{border-left:1px solid var(--line); padding:12px;}
.mm-center{display:flex; flex-direction:column; overflow:hidden; min-height:0;}
.mm-section-title{font-size:10.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--text-dim); margin:4px 0 8px;}

.mm-cable-card{background:#0c1a30; border:1px solid var(--line); border-radius:8px; margin-bottom:10px; overflow:hidden;}
.mm-cable-head{
  padding:7px 9px; font-size:12px; font-weight:650; display:flex; align-items:center; gap:6px;
  background:#122542;
}
.mm-cable-head.assigned{border-left:3px solid #34d399;}
.mm-cable-head.unassigned{border-left:3px solid #fbbf24;}
.mm-cable-head small{font-weight:500; color:var(--text-dim); margin-left:auto;}
.mm-buffer-hint{font-size:10.5px; color:var(--text-dim); padding:4px 7px 2px;}

/* Base de la mufa vista desde abajo, girable en X/Y/Z */
.mm-plate-bar{display:flex; align-items:center; gap:10px; padding:10px 16px 4px; flex-wrap:wrap;}
.mm-plate-spacer{flex:1;}
button.mm-btn.mini{padding:4px 9px; font-size:11px;}
/* Entradas/bandejas directo en la barra — reemplaza el modal "⚙ Configurar
   mufa" que había antes. Buffers por bandeja ya no es configurable (ver
   MM_BUFFERS_POR_BANDEJA en mufa-modular.js), por eso quedan solo 2 campos. */
.mm-layout-inline{display:flex; align-items:center; gap:8px;}
.mm-layout-inline label{
  display:flex; align-items:center; gap:5px; font-size:10.5px; color:var(--text-dim);
  text-transform:uppercase; letter-spacing:.05em;
}
.mm-layout-inline input{
  width:46px; background:#0c1a30; border:1px solid var(--line); border-radius:6px; padding:4px 6px;
  color:var(--text); font-size:12px; font-family:inherit;
}
.mm-layout-err{color:var(--danger); font-size:10.5px;}
/* Candadito: esa parte de la mufa ya tiene fusiones y no se puede achicar */
.mm-lock{font-size:10px; line-height:1; cursor:help;}
.mm-subtitulo{
  font-size:10.5px; color:var(--text-dim); text-transform:uppercase;
  letter-spacing:.07em; margin-top:2px;
}

/* Clic para tomar / clic para soltar. Lo que se lleva sigue al cursor, y los
   destinos posibles quedan marcados para no tener que adivinar dónde soltar. */
.mm-fantasma{
  position:fixed; z-index:6000; pointer-events:none;
  display:flex; align-items:center; gap:6px;
  background:#17305a; border:1px solid var(--drop); border-radius:7px;
  padding:5px 9px; font-size:11px; font-weight:650; color:var(--text);
  box-shadow:0 8px 22px rgba(0,0,0,.5);
}
.mm-fantasma-punto{width:11px; height:11px; border-radius:50%; flex-shrink:0;}
body.mm-llevando{cursor:crosshair;}
body.mm-llevando .mm-destino{cursor:copy;}
.mm-destino.esperando{
  outline:2px dashed var(--drop); outline-offset:2px;
  background:rgba(255,122,41,.08); animation:mmLatido 1.4s ease-in-out infinite;
}
@keyframes mmLatido{ 50%{ background:rgba(255,122,41,.16); } }
/* Lo que ya está tomado se ve levantado del resto */
.mm-cx-buffer-hit.tomado, .mm-cx-wrap.tomado{
  outline:2px solid var(--drop); outline-offset:2px;
}
.mm-plate-scene{
  perspective:1100px; height:262px; display:flex; align-items:center; justify-content:center;
  flex-shrink:0; touch-action:none; cursor:grab; user-select:none;
}
.mm-plate-rotor{transform-style:preserve-3d; will-change:transform;}
.mm-plate-svg{display:block; overflow:visible;}
/* Vista 3D (Three.js — ver mufa-3d.js). Mismo alto que la escena 2D para
   que el resto del panel no salte al alternar entre las dos vistas. */
.mm-3d-scene{height:262px; flex-shrink:0; cursor:grab; touch-action:none;}
.mm-3d-scene canvas{display:block; width:100%; height:100%;}
.mm-port .ring{transition:stroke .12s, stroke-width .12s;}
.mm-port.has-cable{cursor:pointer;}
.mm-port.dragover .ring{stroke:var(--drop); stroke-width:5;}
.mm-lead{stroke-dasharray:420; stroke-dashoffset:420; animation:mmLeadIn .5s ease forwards;}
@keyframes mmLeadIn{to{stroke-dashoffset:0;}}
.mm-rotate-hint{text-align:center; font-size:10.5px; color:var(--text-dim); margin:0 0 8px;}

.mm-cable-art{padding:6px 8px 2px;}
/* Corte transversal del cable — ver buildCableCrossSection. El SVG de
   adentro es solo dibujo (pointer-events:none); el arrastre real lo hacen
   estos dos divs de encima: mm-cx-wrap (toda la chaqueta) y un
   mm-cx-buffer-hit circular por buffer, puesto exactamente sobre su
   círculo — así el arrastre es 100% confiable (draggable de HTMLElement),
   sin depender de que el navegador soporte bien draggable en SVG. */
.mm-cx-wrap{position:relative; width:100%; aspect-ratio:1/1; cursor:grab;}
.mm-cx-svg{position:absolute; inset:0; width:100%; height:100%; pointer-events:none;}
.mm-cx-buffer-hit{position:absolute; border-radius:50%; transform:translate(-50%,-50%); transition:box-shadow .12s, background .12s;}
.mm-cx-buffer-hit.drag{cursor:grab;}
.mm-cx-buffer-hit.drag:not(.placed):hover{background:rgba(255,255,255,.14); box-shadow:0 0 0 3px rgba(255,255,255,.3);}
/* Ya colocado en una bandeja: no se arrastra, y se nota con un tilde */
.mm-cx-buffer-hit.placed{
  cursor:not-allowed; background:rgba(0,0,0,.45); box-shadow:0 0 0 2px rgba(52,211,153,.75) inset;
}
.mm-cx-buffer-hit.placed::after{
  content:'✓'; position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  color:#34d399; font-size:11px; font-weight:700;
}
.mm-cx-wrap:hover:not(:has(.mm-cx-buffer-hit:hover)){filter:brightness(1.12);}

/* Bandejas dibujadas como bandejas reales vistas de frente (cápsula
   ovalada, entradas "Ti"/"Td" abajo — ver foto de referencia), no barras */
.mm-trays{
  flex:1; overflow-y:auto; padding:0 16px 16px; display:grid;
  grid-template-columns:repeat(auto-fill,minmax(112px,1fr)); gap:10px; align-content:start;
}
.mm-tray-card{border:2px solid transparent; border-radius:11px; cursor:pointer; padding:2px;}
.mm-tray-card:hover{border-color:#395c94;}
.mm-tray-card.selected{border-color:#34d399; background:rgba(52,211,153,.07);}
.mm-tray-figure{position:relative;}
.mm-tray-svg{display:block; width:100%; height:auto;}
/* Zonas de drop ancladas sobre los puertos "Ti"/"Td" del SVG (círculos en
   x=34/86, y=128 dentro del viewBox 120x150 — ver renderTrayCard) */
.mm-tray-drop{
  position:absolute; bottom:6%; width:32%; height:20%; border-radius:50%;
}
.mm-tray-drop.izq{left:12%;}
.mm-tray-drop.der{right:12%;}
.mm-tray-drop.dragover{background:rgba(255,122,41,.3); outline:2px dashed var(--drop);}
.mm-tray-cap{display:flex; align-items:baseline; gap:6px; padding:3px 4px 0;}
.mm-tray-cap b{font-size:11.5px; font-weight:650;}
.mm-tray-cap span{margin-left:auto; font-size:9.5px; color:var(--text-dim); font-family:'IBM Plex Mono',monospace;}

.mm-tray-detail-title{font-size:13px; font-weight:650; margin-bottom:2px;}
.mm-tray-detail-sub{font-size:11px; color:var(--text-dim); margin-bottom:12px;}
/* Bandeja frontal ampliada — zonas de suelte ancladas sobre los puertos
   "Ti"/"Td" del SVG (círculos en x=85/215, y=345 dentro del viewBox
   300x380 — ver renderTrayFrontSvg) */
.mm-trayfront-scene{position:relative; margin-bottom:14px;}
.mm-trayfront-svg{display:block; width:100%; height:auto;}
.mm-trayfront-port{position:absolute; width:26%; height:16%; border-radius:50%; transform:translate(-50%,-50%);}
.mm-trayfront-port.izq{left:28.3%; top:90.8%;}
.mm-trayfront-port.der{left:71.7%; top:90.8%;}
.mm-trayfront-port.dragover{background:rgba(255,122,41,.35); outline:2px dashed var(--drop);}
/* Zona clicable sobre el portafusión ámbar del SVG (rect en x=66,y=144,
   w=168,h=66 dentro del viewBox 300x380) — abre openMmSpliceCreator */
/* Fusiones del dibujo. El trazo ancho invisible (.mm-fusion-hit) es el que
   recibe el cursor: apuntarle a una línea de 3 px es incómodo. Al pasar por
   encima se resalta toda la fusión, y el clic abre su cuadro de cliente. */
.mm-fusion{cursor:pointer;}
.mm-fusion-hit{stroke:transparent; stroke-width:16; pointer-events:stroke;}
.mm-fusion path{transition:stroke-width .12s, filter .12s;}
.mm-fusion:hover path:not(.mm-fusion-hit){stroke-width:5; filter:drop-shadow(0 0 5px rgba(255,255,255,.55));}
.mm-fusion:hover rect{stroke:#fff; stroke-width:1.5;}
.mm-sides{display:grid; grid-template-columns:1fr 1fr; gap:10px;}
.mm-side-zone{
  min-height:70px; border:1px dashed var(--line); border-radius:8px; padding:8px; font-size:10.5px;
}
.mm-side-zone.dragover{border-color:var(--drop); background:#2a1c10;}
.mm-side-label{font-size:10px; text-transform:uppercase; letter-spacing:.06em; color:var(--text-dim); margin-bottom:6px;}
.mm-tray-buffer{
  background:#17305a; border:1px solid var(--line); border-radius:6px; padding:5px 7px; margin-bottom:6px; cursor:grab;
  transition:background .12s, border-color .12s;
}
.mm-tray-buffer:hover{background:#202c3c; border-color:#395c94;}
.mm-tray-buffer .hd{display:flex; align-items:center; gap:5px; font-size:10.5px; font-weight:650; cursor:pointer;}
.mm-tray-buffer.expanded .hd{margin-bottom:5px;}
.mm-tray-buffer-dot{width:10px; height:10px; border-radius:50%; flex-shrink:0;}
.mm-tray-buffer-toggle{margin-left:auto; font-weight:500; color:var(--text-dim); font-size:9.5px;}
.mm-tray-buffer-remove{
  flex-shrink:0; width:16px; height:16px; display:inline-flex; align-items:center; justify-content:center;
  background:none; border:none; border-radius:4px; color:var(--text-dim); font-size:10px; line-height:1; cursor:pointer; padding:0;
}
.mm-tray-buffer-remove:hover{background:rgba(248,113,113,.16); color:var(--danger);}
/* Grilla fija de 6 columnas en vez de flex-wrap: un buffer de 12 hilos cae
   siempre en 2 filas parejas de 6, y uno de 4 u 8 queda alineado con los
   demás — con wrap libre las filas quedaban desparejas según el ancho. */
.mm-tray-buffer-dots{display:grid; grid-template-columns:repeat(6, 1fr); gap:3px; justify-items:center;}
.mm-context-menu{
  position:fixed; z-index:5030; background:#122542; border:1px solid var(--line); border-radius:8px;
  padding:4px; box-shadow:0 12px 30px rgba(0,0,0,.45); min-width:180px;
}
.mm-context-item{
  display:block; width:100%; text-align:left; background:none; border:none; color:var(--text);
  font-family:inherit; font-size:12px; padding:8px 10px; border-radius:6px; cursor:pointer;
}
.mm-context-item:hover{background:rgba(248,113,113,.14); color:var(--danger);}
.mm-fiber-dot{
  width:16px; height:16px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center;
  font-size:8px; font-weight:700; cursor:pointer; border:2px solid transparent;
}
.mm-fiber-dot.selected{border-color:#fff; transform:scale(1.15);}
.mm-fiber-dot.spliced{outline:2px solid #34d399; outline-offset:1px;}
.mm-empty-note{color:var(--text-dim); font-size:11.5px; padding:8px 2px;}

.mm-splice-tip{
  position:fixed; z-index:5010; background:#0c1a30; border:1px solid var(--line); border-radius:8px;
  padding:10px 12px; font-size:11.5px; width:220px; box-shadow:0 12px 30px rgba(0,0,0,.4);
}
.mm-splice-tip .row{display:flex; justify-content:space-between; gap:8px; margin-bottom:5px;}
.mm-splice-tip label{color:var(--text-dim); font-size:10px; text-transform:uppercase; letter-spacing:.05em;}
.mm-splice-tip input, .mm-splice-tip select{
  width:100%; background:#17305a; border:1px solid var(--line); border-radius:5px; padding:4px 6px;
  color:var(--text); font-size:11px; margin-top:2px;
}
.mm-config-modal{
  position:fixed; inset:0; z-index:5020; display:flex; align-items:center; justify-content:center;
  background:rgba(4,7,10,.7);
}
.mm-config-box{background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:20px; width:min(360px,92vw);}
.mm-config-box h4{margin:0 0 4px; font-size:14px;}
.mm-config-box p{margin:0 0 14px; font-size:11.5px; color:var(--text-dim);}
.mm-config-field{margin-bottom:12px;}
.mm-config-field label{display:block; font-size:11px; color:var(--text-dim); margin-bottom:4px;}
.mm-config-field input{
  width:100%; background:#0c1a30; border:1px solid var(--line); border-radius:7px; padding:8px 10px;
  color:var(--text); font-size:13px;
}
.mm-config-actions{display:flex; justify-content:flex-end; gap:8px; margin-top:6px;}
.mm-config-err{color:var(--danger); font-size:11.5px; margin-top:4px; display:none;}
.mm-config-err.show{display:block;}

/* Cuadro de empalmes existentes, debajo de la bandeja seleccionada */
.mm-splice-table-wrap{overflow-x:auto;}
.mm-splice-table{width:100%; border-collapse:collapse; font-size:11px;}
.mm-splice-table th{
  text-align:left; font-size:9.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--text-dim);
  padding:0 8px 6px; font-weight:600; border-bottom:1px solid var(--line);
}
.mm-splice-table td{padding:7px 8px; border-bottom:1px solid var(--line); white-space:nowrap;}
.mm-splice-table tbody tr{cursor:pointer;}
.mm-splice-table tbody tr:hover{background:#122542;}
.mm-splice-table td:last-child{width:1%;}
