/* ============================================================
   ACM — Estándar UI v2 (S03-01, spec_presentacion §2.8)
   Tokens monocromos + semáforo PF-01. Referencia visual viva:
   ~/Developer/prototipos-acm/estilo-front-acm-v1.html
   Regla dura: cero colores/medidas literales fuera de este bloque
   de tokens; los templates referencian solo var(--…).
   ============================================================ */
:root[data-theme="dark"]{
  --bg:#101012; --sidebar:#0b0b0d; --panel:#18181b; --panel-2:#1e1e21;
  --border:#28282b; --border-soft:#212124;
  --text:#f2f2f4; --muted:#8f8f95; --muted-2:#5a5a60;
  --primary:#f2f2f4; --primary-fg:#101012;
  --accent:#c9c9ce; --accent-strong:#e8e8ea;
  --verde:#22c55e; --verde-bg:rgba(34,197,94,.14);
  --rojo:#ef4444; --rojo-bg:rgba(239,68,68,.14);
  --gris:#8b8b90; --gris-bg:rgba(139,139,144,.14);
  --ambar:#e0a11b; --ambar-bg:rgba(224,161,27,.15);
  --code-bg:#0d0d0f;
  --toast-bg:#26262a;
  --shadow:0 10px 28px rgba(0,0,0,.45);
  --page-glow:
    radial-gradient(1100px 620px at 10% -14%, rgba(255,255,255,.055), transparent 55%),
    radial-gradient(800px 520px at 100% 108%, rgba(255,255,255,.03), transparent 52%);
  --sheen: linear-gradient(160deg, rgba(255,255,255,.055), rgba(255,255,255,0) 48%);
  --sheen-soft: linear-gradient(160deg, rgba(255,255,255,.03), rgba(255,255,255,0) 55%);
  --hl-inset: inset 0 1px 0 rgba(255,255,255,.06);
  --hl-inset-soft: inset 0 1px 0 rgba(255,255,255,.035);
}
:root[data-theme="light"]{
  --bg:#f2f2f3; --sidebar:#ffffff; --panel:#ffffff; --panel-2:#f6f6f7;
  --border:#e2e2e4; --border-soft:#ececed;
  --text:#171719; --muted:#6b6b70; --muted-2:#9a9a9f;
  --primary:#171719; --primary-fg:#ffffff;
  --accent:#4a4a4f; --accent-strong:#171719;
  --verde:#178a4c; --verde-bg:rgba(23,138,76,.10);
  --rojo:#c8342b; --rojo-bg:rgba(200,52,43,.10);
  --gris:#6b6b70; --gris-bg:rgba(107,107,112,.10);
  --ambar:#9a6e00; --ambar-bg:rgba(154,110,0,.10);
  --code-bg:#f6f6f7;
  --toast-bg:#26262a;
  --shadow:0 10px 24px rgba(20,20,25,.08);
  --page-glow:
    radial-gradient(1100px 620px at 10% -14%, rgba(255,255,255,.9), transparent 55%),
    radial-gradient(800px 520px at 100% 108%, rgba(0,0,0,.025), transparent 52%);
  --sheen: linear-gradient(160deg, rgba(255,255,255,.7), rgba(255,255,255,0) 48%);
  --sheen-soft: linear-gradient(160deg, rgba(255,255,255,.5), rgba(255,255,255,0) 55%);
  --hl-inset: inset 0 1px 0 rgba(255,255,255,.7);
  --hl-inset-soft: inset 0 1px 0 rgba(255,255,255,.4);
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body{
  margin:0; background-color:var(--bg); background-image:var(--page-glow); color:var(--text);
  font-family:ui-sans-serif,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-size:13.5px; line-height:1.5;
}
h1,h2,h3,h4{margin:0; font-weight:650; letter-spacing:.1px}
code,pre,.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
code{background:var(--code-bg); padding:1px 5px; border-radius:5px; font-size:.9em}
pre{background:var(--code-bg); border:1px solid var(--border); border-radius:8px; padding:8px 10px; overflow-x:auto}
.muted{color:var(--muted)}
.hidden{display:none !important}
a{color:inherit; text-decoration:none}
a:hover{text-decoration:underline}
button{font:inherit}

/* ---------- Shell: app + sidebar ---------- */
/* Ancho de la sidebar vía --side-w (v3.4, ajustable por arrastre): el riel
   colapsado (48px, .app.collapsed) manda por especificidad y no arrastra. */
.app{display:grid; grid-template-columns:var(--side-w, 230px) 1fr; height:100vh; overflow:hidden}
.sidebar{
  background-color:var(--sidebar); background-image:var(--sheen-soft); border-right:1px solid var(--border);
  display:flex; flex-direction:column; padding:14px 10px;
  position:relative; /* ancla del handle de redimensionado */
}
/* Handle de ancho (S04-01 corrección, spec §2.8 v3.4): franja invisible en
   el borde derecho que se revela al acercarse; mismo lenguaje del divisor
   del workspace (.grid-divisor). */
.side-resize{
  position:absolute; top:0; right:-3px; bottom:0; width:7px; cursor:col-resize;
  z-index:6; touch-action:none;
}
.side-resize:hover, .side-resize.dragging{background:var(--accent); opacity:.4}
.app.collapsed .side-resize{display:none}
.brand{display:flex; align-items:center; gap:10px}
.brand .name{font-size:13.5px; font-weight:600}
.brand .sub{font-size:10.5px; color:var(--muted); margin-top:1px}
nav.primary{display:flex; flex-direction:column; gap:2px; margin-top:4px}
.navlink{
  display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:9px;
  color:var(--muted); cursor:pointer; font-size:13px; border:1px solid transparent;
}
.navlink svg{width:16px; height:16px; flex:none; opacity:.85}
.navlink:hover{background:var(--panel-2); color:var(--text); text-decoration:none}
.navlink.active{background:var(--panel-2); color:var(--text); border-color:var(--border-soft)}
.navlink.active svg{opacity:1}
.nav-section-label{
  font-size:10px; text-transform:uppercase; letter-spacing:.7px; color:var(--muted-2);
  padding:14px 10px 4px;
}
.sidebar-spacer{flex:1}
.sidebar-foot{border-top:1px solid var(--border); padding-top:10px; display:flex; flex-direction:column; gap:6px}

/* ---------- Shell v3: pestañas Menú/Ventana + riel colapsable (S03-03) ---------- */
/* side-top ya no reparte icono/texto en extremos opuestos (justify-content:
   space-between): sin el tile de marca, el botón de retraer va primero y
   ocupa su espacio (mismo tamaño 28px/radio 8px que tenía el tile). */
.side-top{display:flex; align-items:center; gap:10px; padding:6px 8px 16px}
.side-collapse{
  width:28px; height:28px; border-radius:8px; flex:none;
  display:flex; align-items:center; justify-content:center;
  color:var(--muted); background:transparent; border:1px solid transparent; cursor:pointer;
}
.side-collapse svg{width:15px; height:15px}
.side-collapse:hover{background:var(--panel-2); color:var(--text)}
.side-tabs{display:grid; grid-template-columns:1fr 1fr; gap:4px; padding:2px 4px 10px; border-bottom:1px solid var(--border)}
.side-tab{
  display:flex; align-items:center; justify-content:center; gap:6px; padding:7px 6px;
  border-radius:8px; font-size:12px; color:var(--muted); background:transparent;
  border:1px solid transparent; cursor:pointer;
}
.side-tab svg{width:13px; height:13px; flex:none; opacity:.85}
.side-tab:hover:enabled{background:var(--panel-2); color:var(--text)}
.side-tab.active{background:var(--panel-2); color:var(--text); border-color:var(--border-soft)}
.side-tab.active svg{opacity:1}
.side-tab:disabled{opacity:.35; cursor:default}
.side-pane{flex:1; min-height:0; display:flex; flex-direction:column; overflow-y:auto; margin-top:4px}
.rail-ventana{
  display:none; align-items:center; justify-content:center; padding:9px 0; margin-top:6px;
  border-radius:9px; color:var(--muted); background:transparent; border:1px solid transparent; cursor:pointer;
}
.rail-ventana svg{width:16px; height:16px}
.rail-ventana:hover{background:var(--panel-2); color:var(--text)}
.side-menu{display:flex; flex-direction:column; min-height:0; flex:1}
.side-menu .search{padding:10px}
.side-menu .items{overflow-y:auto; min-height:0}

/* Colapso de la sidebar a riel de iconos (~48px; memoria por sesión en app.js) */
.app.collapsed{grid-template-columns:48px 1fr}
.app.collapsed .sidebar{padding:14px 8px}
.app.collapsed .side-top{flex-direction:column; align-items:stretch; padding:0; gap:0}
/* riel sin brand: el toggle ocupa su lugar como botón prominente */
.app.collapsed .brand{display:none}
.app.collapsed .side-collapse{
  margin:2px 0 10px; transform:rotate(180deg);
  width:100%; height:36px; border-radius:9px;
  background-color:var(--panel-2); background-image:var(--sheen);
  border:1px solid var(--border); color:var(--text);
}
.app.collapsed .side-collapse svg{width:17px; height:17px}
.app.collapsed .side-collapse:hover{border-color:var(--muted)}
.app.collapsed .side-tabs{display:none}
.app.collapsed.has-side-menu .rail-ventana{display:flex}
.app.collapsed .navlink{justify-content:center; padding:9px 0; gap:0}
.app.collapsed .navlink span{display:none}
.app.collapsed .nav-section-label{height:8px; padding:0; overflow:hidden; visibility:hidden}
.app.collapsed #pane-window{display:none}
.app.collapsed .user-chip{justify-content:center; padding:6px 0}
.app.collapsed .user-chip .who{display:none}
.app.collapsed .ghost-row{flex-direction:column}
.app.collapsed .ghost-row button span{display:none}
.app.collapsed .ghost-row button svg{margin:0}
.user-chip{display:flex; align-items:center; gap:8px; padding:6px 8px}
.user-chip .av{
  width:26px; height:26px; border-radius:99px; background:var(--panel-2); border:1px solid var(--border);
  display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; color:var(--muted);
}
.user-chip .who{display:flex; flex-direction:column; line-height:1.2; min-width:0}
.user-chip .who b{font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.user-chip .who span{font-size:10.5px; color:var(--muted)}
.ghost-row{display:flex; gap:6px}
.ghost-row button{flex:1}

/* ---------- Main: topbar + content ---------- */
.main{display:flex; flex-direction:column; min-width:0; height:100vh}
.topbar{
  display:flex; align-items:center; gap:14px; padding:14px 22px; border-bottom:1px solid var(--border);
  flex-wrap:wrap; flex:none;
}
.topbar .heading{flex:1; min-width:200px}
.topbar .crumbs{font-size:11.5px; color:var(--muted); display:flex; align-items:center; gap:6px; margin-bottom:2px}
.topbar .crumbs b{color:var(--text); font-weight:600}
.topbar h1{font-size:17px}
.topbar .subtitle{font-size:12px; color:var(--muted); margin-top:2px}
.topbar .actions{display:flex; gap:8px; align-items:center; flex-wrap:wrap}
.content{flex:1; overflow:auto; padding:22px}

/* ---------- Botones (Capa 2) ---------- */
.btn{
  display:inline-flex; align-items:center; gap:6px; justify-content:center;
  padding:7px 13px; border-radius:9px; border:1px solid var(--border);
  background-color:var(--panel-2); background-image:var(--sheen); box-shadow:var(--hl-inset-soft);
  color:var(--text); cursor:pointer; font-size:12.5px; font-weight:550;
  transition:border-color .15s, filter .15s;
}
.btn svg{width:14px; height:14px}
.btn:hover{border-color:var(--muted-2); filter:brightness(1.08)}
.btn.primary{background-color:var(--primary); background-image:var(--sheen); box-shadow:var(--hl-inset);
  border-color:var(--primary); color:var(--primary-fg); font-weight:650}
.btn.primary:hover{filter:brightness(.94)}
.btn.danger{background:transparent; box-shadow:none; border-color:var(--rojo); color:var(--rojo)}
.btn.danger:hover{background:var(--rojo-bg); filter:none}
.btn.ghost{background:transparent; box-shadow:none}
.btn.sm{padding:4px 9px; font-size:11.5px; border-radius:7px}
.btn:disabled{opacity:.4; cursor:not-allowed}
.link-btn{background:transparent; border:none; color:var(--accent-strong); cursor:pointer; padding:2px 6px; font-size:12.5px; text-decoration:underline}
.icon-btn{
  width:30px; height:30px; display:inline-flex; align-items:center; justify-content:center;
  border-radius:8px; border:1px solid transparent; background:transparent; color:var(--muted); cursor:pointer; line-height:0;
}
.icon-btn svg{width:16px; height:16px}
.icon-btn:hover{background-color:var(--panel-2); background-image:var(--sheen); border-color:var(--border); color:var(--text)}
.icon-btn:focus-visible{outline:2px solid var(--accent-strong); outline-offset:1px}
.icon-btn:disabled, .icon-btn.working{opacity:.5; cursor:wait}
/* Tooltip (delay 1s en aparecer, fade — línea S02-07) */
.icon-btn[data-tip]{position:relative}
.icon-btn[data-tip]::after{
  content:attr(data-tip);
  position:absolute; bottom:calc(100% + 6px); left:50%; transform:translateX(-50%);
  background:var(--toast-bg); color:#f2f2f4; padding:3px 8px; border-radius:5px;
  font-size:12px; white-space:nowrap; pointer-events:none;
  opacity:0; transition:opacity .2s; z-index:50;
}
.icon-btn[data-tip]:hover::after{opacity:1; transition:opacity .2s 1s}

/* ---------- Badges / pills ---------- */
.badge{display:inline-flex; align-items:center; gap:5px; font-size:11px; font-weight:650; padding:3px 9px; border-radius:99px}
.badge::before{content:""; width:6px; height:6px; border-radius:99px; background:currentColor}
.badge-ok{background:var(--verde-bg); color:var(--verde)}
.badge-warn{background:var(--gris-bg); color:var(--gris)}
.badge-err{background:var(--rojo-bg); color:var(--rojo)}
.status-pill{
  display:inline-flex; align-items:center; gap:6px; font-size:11px; font-weight:650;
  padding:3px 10px; border-radius:99px; border:1px solid var(--border);
  background-color:var(--panel-2); background-image:var(--sheen); box-shadow:var(--hl-inset-soft); color:var(--muted);
}
.status-pill .dot{width:7px; height:7px; border-radius:99px; background:var(--gris)}
.status-pill.ok{color:var(--verde); border-color:var(--verde)}
.status-pill.ok .dot{background:var(--verde)}
.status-pill.warn{color:var(--gris)}
.status-pill.err{color:var(--rojo); border-color:var(--rojo)}
.status-pill.err .dot{background:var(--rojo)}

/* ---------- Cards / superficies ---------- */
.card{
  background-color:var(--panel); background-image:var(--sheen); box-shadow:var(--hl-inset-soft);
  border:1px solid var(--border); border-radius:14px; padding:16px; margin-bottom:16px;
}
.card-head{display:flex; align-items:center; justify-content:space-between; margin-bottom:12px}
.card-head h2{font-size:13px; text-transform:uppercase; letter-spacing:.5px; color:var(--muted); font-weight:650}
.grid-cols{display:grid; gap:16px}
.cols-2{grid-template-columns:1fr 1fr}
.cols-3{grid-template-columns:repeat(3,1fr)}
.stat .num{font-size:26px; font-weight:750}
.stat .label{font-size:11.5px; color:var(--muted); margin-top:2px}

/* entidad (cliente) */
.entity-card{display:flex; align-items:flex-start; gap:12px}
.entity-card .tile{
  width:42px; height:42px; border-radius:11px; background-color:var(--panel-2); background-image:var(--sheen);
  box-shadow:var(--hl-inset); border:1px solid var(--border);
  display:flex; align-items:center; justify-content:center; font-weight:750; font-size:14px; flex:none;
}
.entity-card .body{flex:1}
.entity-card .body h2{font-size:15px}
.entity-card .kv-row{display:flex; gap:18px; margin-top:10px; flex-wrap:wrap}
.entity-card .kv{display:flex; flex-direction:column}
.entity-card .kv span:first-child{font-size:10.5px; color:var(--muted); text-transform:uppercase; letter-spacing:.4px}
.entity-card .kv span:last-child{font-size:13px; margin-top:2px}

/* listas de acceso (dashboard) */
.wallet-list{display:flex; flex-direction:column; gap:2px}
.wallet-row{display:flex; align-items:center; gap:10px; padding:10px 8px; border-radius:10px}
.wallet-row:hover{background:var(--panel-2); text-decoration:none}
.wallet-row .tile{
  width:32px; height:32px; border-radius:8px; background-color:var(--panel-2); background-image:var(--sheen);
  box-shadow:var(--hl-inset-soft); border:1px solid var(--border);
  display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:700; color:var(--muted); flex:none;
}
.wallet-row .info{flex:1; min-width:0}
.wallet-row .info b{font-size:12.5px; display:block}
.wallet-row .info span{font-size:11px; color:var(--muted)}
.wallet-row .go{color:var(--muted-2); font-size:13px}

/* ---------- Tablas (Capa 2: .tbl) ---------- */
table.tbl{width:100%; border-collapse:collapse}
table.tbl th{
  text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.5px; color:var(--muted-2);
  font-weight:650; padding:0 10px 10px; border-bottom:1px solid var(--border);
}
table.tbl td{padding:11px 10px; border-bottom:1px solid var(--border-soft); font-size:12.5px; vertical-align:middle}
table.tbl tbody tr{transition:background .12s}
table.tbl tbody tr:hover{background:var(--panel-2)}
table.tbl tbody tr:last-child td{border-bottom:none}
.cell-actions{display:flex; gap:4px; justify-content:flex-end}

/* Autofiltro columnar del visor (S02-06) */
table.tbl th .filtro-col{
  width:100%; font-size:10.5px; font-weight:400; text-transform:none; letter-spacing:0;
  padding:3px 6px; margin-top:4px; border-radius:5px; box-sizing:border-box;
}
/* Columnas redimensionables del visor (S02-09) */
table.tbl.resizable{table-layout:fixed}
table.tbl.resizable th{position:relative}
table.tbl.resizable th .col-resize{position:absolute; top:0; right:0; bottom:0; width:6px; cursor:col-resize; user-select:none; z-index:3}
table.tbl.resizable th .col-resize:hover,
table.tbl.resizable th .col-resize.dragging{background:var(--accent); opacity:.4}

/* ---------- Formularios (Capa 2: field) ---------- */
label{display:block; font-size:11.5px; color:var(--muted); margin-bottom:5px; font-weight:600}
input, select, textarea{
  width:100%; padding:8px 10px; border-radius:9px; border:1px solid var(--border);
  background:var(--panel-2); color:var(--text); font:inherit; font-size:12.5px;
}
textarea{font-family:ui-monospace,Menlo,monospace; font-size:11.5px; background:var(--code-bg)}
.field{margin-bottom:12px}
.field-row{display:flex; gap:12px}
.field-row > .field{flex:1}
.hint-box{
  font-size:11.5px; color:var(--muted); border-left:3px solid var(--muted-2); background:var(--panel-2);
  padding:8px 12px; border-radius:0 9px 9px 0; margin:12px 0;
}

/* ---------- Tarjetas nodo+conexiones del editor de flujos (spec_flujos §2.2.1) ---------- */
.nodo-card{
  border:1px solid var(--border-soft); border-radius:11px; background:var(--panel);
  padding:12px 14px; margin-bottom:10px; transition:box-shadow .2s, border-color .2s;
}
.nodo-card.flash{border-color:var(--accent-strong); box-shadow:0 0 0 2px var(--accent-strong)}
.nodo-card .card-head-row{display:flex; align-items:flex-start}
.aristas-inline{margin-top:6px; padding-top:8px; border-top:1px dashed var(--border)}
.aristas-inline .label-out{
  font-size:10.5px; color:var(--muted-2); text-transform:uppercase; letter-spacing:.4px; margin-bottom:6px;
}
.arista-row-inline .field{margin-bottom:8px}

/* ---------- Login (arquetipo login) ---------- */
.login-page{display:flex; justify-content:center; align-items:center; min-height:100vh}
.login-card{
  background-color:var(--panel); background-image:var(--sheen); box-shadow:var(--hl-inset-soft), var(--shadow);
  border:1px solid var(--border); border-radius:14px; padding:30px; width:100%; max-width:360px;
}
.login-card .brand{padding:0 0 18px; justify-content:center}
.login-card h1{text-align:center; font-size:17px}
.login-card p{text-align:center; margin:0 0 20px; color:var(--muted); font-size:12px}
.login-card .error{color:var(--rojo); text-align:center; font-size:12px}

/* ---------- Workspace (arquetipo workspace-canvas-panel) ---------- */
.ribbon{
  background:var(--panel-2); border-left:3px solid var(--accent-strong);
  padding:10px 16px; margin-bottom:16px; border-radius:0 9px 9px 0; font-size:12.5px;
}
.grid-2{display:grid; grid-template-columns:30fr 6px 70fr; gap:0; align-items:stretch}
.grid-2 > .panel-izq{padding-right:10px; overflow:auto; min-width:0}
.grid-2 > .panel-der{padding-left:10px; overflow:auto; min-width:0}
.grid-divisor{cursor:col-resize; background:transparent; position:relative; z-index:2; min-width:6px}
.grid-divisor::after{
  content:""; position:absolute; top:0; bottom:0; left:50%; width:4px; transform:translateX(-50%);
  background:var(--border); border-radius:2px; transition:background .15s;
}
.grid-divisor:hover::after, .grid-divisor.dragging::after{background:var(--accent-strong)}
.visor{
  background-color:var(--panel); background-image:var(--sheen-soft); border:1px solid var(--border);
  border-radius:14px; padding:12px;
}
.tabs{display:flex; gap:4px; border-bottom:1px solid var(--border); margin-bottom:8px}
.tab{background:transparent; color:var(--muted); border:none; padding:5px 11px; border-radius:7px 7px 0 0; cursor:pointer; font-size:12px}
.tab.active{color:var(--text); font-weight:650; box-shadow:inset 0 -2px 0 var(--accent-strong)}
.paginas{display:flex; justify-content:center; align-items:center; gap:12px; margin-bottom:8px; color:var(--muted); font-size:11px}
.paginas button{background:transparent; border:1px solid var(--border); color:var(--text); width:22px; height:22px; border-radius:6px; cursor:pointer; line-height:0}
.tabla-scroll{overflow:auto; max-height:500px}

/* ---------- ABM lista-detalle (arquetipo) ---------- */
.admin-shell{display:grid; grid-template-columns:280px 1fr; gap:0; border:1px solid var(--border); border-radius:14px; overflow:hidden; min-height:0}
.admin-shell.solo{grid-template-columns:1fr}
/* llena exactamente el área de contenido (.content es flex:1 + overflow):
   sustituye al calc(100vh - 178px) mágico que desbordaba en pantallas reales.
   margin-bottom:0 neutraliza el section{margin-bottom:22px} global. */
.screen-fill{height:100%; min-height:0; margin-bottom:0}
.screen-fill > .admin-shell{height:100%}
.admin-list{border-right:1px solid var(--border); background-color:var(--panel); background-image:var(--sheen-soft); display:flex; flex-direction:column; min-height:0}
.admin-list .search{padding:10px}
.admin-list .items{overflow-y:auto}
.admin-row{display:flex; flex-direction:column; gap:2px; padding:10px 14px; cursor:pointer; border-left:2px solid transparent}
.admin-row:hover{background:var(--panel-2)}
.admin-row.active{background:var(--panel-2); border-left-color:var(--text)}
.admin-row b{font-size:12.5px}
.admin-row span{font-size:10.5px; color:var(--muted)}
.admin-editor{padding:18px; background:var(--bg); overflow-y:auto}
.ficha-ref{display:flex; gap:8px; margin-bottom:6px; align-items:center}
.ficha-ref select{flex:1}

/* ---------- Grafo de flujo (biblioteca pre-instalada para Flujo-1a) ---------- */
/* .flow-split reparte preview (arriba) y formulario (abajo) 50/50; al
   retraer el preview (spec_flujos v2.1 / spec_presentacion v3.2, operador
   2026-08-17) la fila de arriba pasa a "auto" (solo la altura del
   toolbar) y el formulario gana el espacio liberado. */
.flow-split{display:grid; grid-template-rows:minmax(0,1fr) minmax(0,1fr); gap:0; height:100%; overflow:hidden}
.flow-split.preview-collapsed{grid-template-rows:auto minmax(0,1fr)}
.flow-split.preview-collapsed .canvas-outer{display:none}
.flow-toolbar{display:flex; align-items:center; gap:14px; padding:9px 16px; border-bottom:1px solid var(--border); background:var(--panel)}
/* La franja completa es el control (no un botón aparte): cursor + hover
   señalan que es clicable; el chevron (i-collapse, doble-chevron
   horizontal reutilizado) es solo el indicador visual del estado. */
.flow-toolbar[role="button"]{cursor:pointer; user-select:none}
.flow-toolbar[role="button"]:hover{background:var(--panel-2)}
.flow-toolbar[role="button"]:focus-visible{outline:2px solid var(--accent-strong); outline-offset:-2px}
.toolbar-chevron{width:14px; height:14px; flex:none; color:var(--muted);
  transform:rotate(90deg); transition:transform .15s}
.flow-split.preview-collapsed .toolbar-chevron{transform:rotate(-90deg)}
/* .canvas-outer no scrollea — es el ancla fija de .zoomctl. .canvas-wrap
   (su único hijo, position:absolute + inset:0) es quien scrollea el grafo
   por dentro; así el zoom queda pegado a la esquina sin importar cuánto se
   desplace el contenido. */
.canvas-outer{position:relative; flex:1; min-height:0}
.canvas-wrap{position:absolute; inset:0; overflow:auto; background-color:var(--bg);
  background-image:var(--page-glow), radial-gradient(var(--border) 1px, transparent 1px);
  background-size:auto, 22px 22px;}
.zoomctl{
  position:absolute; right:14px; top:14px; display:flex; flex-direction:column;
  background-color:var(--panel); background-image:var(--sheen); border:1px solid var(--border);
  border-radius:10px; overflow:hidden; box-shadow:var(--shadow), var(--hl-inset);
  opacity:.35; transition:opacity .15s;
}
/* el control no estorba la lectura del grafo: se revela al acercarse */
.zoomctl:hover, .zoomctl:focus-within{opacity:1}
.zoomctl button{
  width:34px; height:32px; border:none; border-bottom:1px solid var(--border); background:transparent;
  color:var(--text); cursor:pointer; font-size:15px;
}
.zoomctl button:last-child{border-bottom:none}
.zoomctl button:hover{background:var(--panel-2)}
.node{cursor:pointer}
.node rect.box{fill:var(--panel); stroke:var(--border); stroke-width:1.4}
.node.gris rect.box{stroke:var(--gris)}
.node.verde rect.box{stroke:var(--verde)}
.node.ambar rect.box{stroke:var(--ambar)}
.node.rojo rect.box{stroke:var(--rojo)}
.node.sel rect.box{stroke-width:2.6; stroke:var(--text)}
.node .statusdot{fill:var(--gris)}
.node.verde .statusdot{fill:var(--verde)}
.node.ambar .statusdot{fill:var(--ambar)}
.node.rojo .statusdot{fill:var(--rojo)}
.node .kicker{fill:var(--muted-2); font-size:9.5px; letter-spacing:.6px; font-weight:700}
.node .title{fill:var(--text); font-size:12.5px; font-weight:650}
.node .chip{fill:var(--muted); font-size:9.5px; font-family:ui-monospace,Menlo,monospace}
.node .divider{stroke:var(--border-soft); stroke-width:1}
.node .portlbl{fill:var(--muted); font-size:9px}
.node .portdot{stroke-width:1.4; stroke:var(--panel)}
.node .portdot.in{fill:var(--muted-2)}
/* v3.3 (S04-01): puertos INVERTIDOS — convención positiva: la pregunta se
   formula en positivo, sí = confirmación (verde), no = refutación (rojo). */
.node .portdot.si{fill:var(--verde)}
.node .portdot.no{fill:var(--rojo)}

/* Sdot: semáforo mínimo para filas de tabla (workspace fase 2, S04-01) */
.sdot{display:inline-block; width:9px; height:9px; border-radius:99px; background:var(--gris); vertical-align:middle; margin-right:6px}
.sdot.verde{background:var(--verde)}
.sdot.ambar{background:var(--ambar)}
.sdot.rojo{background:var(--rojo)}
.sdot.gris{background:var(--gris)}
.node .portdot.out{fill:var(--muted-2)}
.node.locked{opacity:.5}
.edge{stroke:var(--muted-2); stroke-width:1.6; stroke-dasharray:5 5; fill:none; opacity:.75}
.elabel rect{fill:var(--panel-2); stroke:var(--border)}
.elabel text{font-size:9.5px; fill:var(--muted); font-weight:700}

/* ---------- Toast ---------- */
.toast{
  position:fixed; bottom:20px; right:20px; background:var(--toast-bg); color:#f2f2f4;
  padding:10px 16px; border-radius:8px; opacity:0; transition:opacity .3s;
  max-width:400px; z-index:1000; font-size:12.5px;
}
.toast.show{opacity:1}
.toast.error{background:var(--rojo)}
.toast.warn{background:var(--gris)}

/* utilidades */
.flex{display:flex; align-items:center}
.gap8{gap:8px} .gap12{gap:12px}
.mt8{margin-top:8px} .mt16{margin-top:16px}
section{margin-bottom:22px}
details summary{cursor:pointer; padding:4px 0}
details[open] summary{margin-bottom:12px}
h4{margin:12px 0 4px}

@media (max-width:900px){
  .app{grid-template-columns:1fr}
  .sidebar{display:none}
  .cols-2,.cols-3{grid-template-columns:1fr}
  .grid-2{grid-template-columns:1fr; gap:16px}
  .grid-divisor{display:none}
  .grid-2 > .panel-izq, .grid-2 > .panel-der{padding:0}
  .admin-shell{grid-template-columns:1fr}
  .admin-list{border-right:none; border-bottom:1px solid var(--border); max-height:200px}
  .screen-fill{height:auto}
  .screen-fill > .admin-shell{height:auto}
}
