:root{--bg:#0b1020;--nav:#0d1425;--panel:#131d30;--raised:#1a2942;--line:#2b3954;--text:#eaf0fa;--muted:#a5b2c8;--blue:#77a9ff;--violet:#b4a0ff;--teal:#42c5b9;--amber:#f3bd64;--red:#ff929f;--shadow:0 20px 70px #0006;--grid:rgba(119,169,255,.045)}
[data-theme=light]{--bg:#f5f7fb;--nav:#eef2f8;--panel:#fff;--raised:#f0f4fa;--line:#d8e0ec;--text:#17243b;--muted:#53657d;--blue:#365ed8;--violet:#7159c8;--teal:#087b72;--amber:#936000;--red:#b32942;--shadow:0 20px 70px #17243b22;--grid:rgba(54,94,216,.045)}
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}button,input,select,textarea{font:inherit}button,a,select{touch-action:manipulation}button{cursor:pointer}a{color:inherit;text-decoration:none}button,input,select,textarea{color:var(--text);border:1px solid var(--line);border-radius:4px;background:var(--panel)}button{min-height:36px;padding:7px 12px;display:inline-flex;align-items:center;justify-content:center;gap:8px;font-weight:550}button:hover,a:hover{background:var(--raised)}button:active{filter:brightness(1.15)}:focus-visible{outline:2px solid var(--blue);outline-offset:3px}input,select,textarea{padding:9px 11px;max-width:100%;min-width:0}textarea{width:100%;min-height:90px;resize:vertical}label{display:grid;gap:7px;color:var(--muted);font-size:12px;font-weight:600}label input,label select,label textarea{font-size:14px;color:var(--text);font-weight:400}.primary{background:var(--blue);border-color:var(--blue);color:var(--bg)}[data-theme=light] .primary{color:white}.primary:hover{background:var(--blue);filter:brightness(1.1)}.danger{color:var(--red)}.quiet{background:transparent}.icon{width:18px;height:18px;flex-shrink:0;stroke:currentColor;stroke-width:1.6;fill:none;stroke-linecap:round;stroke-linejoin:round}.app{display:grid;grid-template-columns:224px minmax(0,1fr);min-height:100vh}.sidebar{background:var(--nav);border-right:1px solid var(--line);position:fixed;inset:0 auto 0 0;width:224px;display:flex;flex-direction:column;z-index:30}.brand{display:flex;align-items:center;gap:10px;height:79px;padding:0 22px;letter-spacing:2px;font-size:18px;font-weight:750}.brandmark{width:29px;height:29px;color:var(--blue)}.brand small{font-size:10px;letter-spacing:1px;color:var(--muted)}.workspace{margin:0 14px 13px;padding:10px 12px;border:1px solid var(--line);display:flex;align-items:center;gap:10px;border-radius:4px}.avatar{display:grid;place-items:center;background:var(--raised);border:1px solid var(--line);width:30px;height:30px;font-size:11px;font-weight:650}.workspace small{display:block;color:var(--muted);font-size:11px}.navscroll{overflow:auto;padding:0 10px;flex:1}.navgroup{font-size:10px;color:var(--muted);letter-spacing:1.7px;padding:16px 13px 6px}.navitem{display:flex;align-items:center;gap:11px;min-height:37px;padding:7px 12px;margin:2px 0;color:var(--muted);border:1px solid transparent;border-radius:4px;font-size:13px}.navitem .num{margin-left:auto;font:10px ui-monospace,monospace;color:var(--muted)}.navitem.active{background:var(--raised);color:var(--blue);border-color:var(--line);box-shadow:inset 2px 0 var(--blue)}.sidefoot{margin-top:12px;border-top:1px solid var(--line);padding:14px;display:grid;gap:10px}.sidefoot .mono{font-size:10px;color:var(--muted)}.shell{grid-column:2;min-width:0}.topbar{height:66px;border-bottom:1px solid var(--line);background:var(--bg);display:flex;align-items:center;gap:12px;padding:0 28px;position:sticky;top:0;z-index:20}.crumb{font-size:12px;color:var(--muted);white-space:nowrap}.topbar .jobselect{max-width:255px;font-size:12px}.spacer{flex:1}.searchbtn{color:var(--muted);font-size:12px;min-width:155px;justify-content:space-between;background:transparent}.key{font:10px ui-monospace,monospace;border:1px solid var(--line);padding:2px 4px;border-radius:3px}.themebtn{min-width:40px;padding:8px}.mobilemenu{display:none}.status{display:inline-flex;align-items:center;gap:6px;font:10px ui-monospace,monospace;letter-spacing:.3px;color:var(--amber);white-space:nowrap}.status:before{content:'';width:5px;height:5px;background:currentColor;border-radius:50%}main{padding:26px 28px 20px;max-width:1800px;margin:auto;min-width:0}.eyebrow{font:10px ui-monospace,monospace;color:var(--muted);letter-spacing:1.6px;margin-bottom:8px}.pagehead{display:flex;align-items:center;gap:16px;margin-bottom:25px}.pagehead h1{font-size:27px;font-weight:620;letter-spacing:-.8px;margin:0 0 4px}.pagehead p{margin:0;color:var(--muted);font-size:13px}.pagehead .actions{margin-left:auto}.actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.badge{display:inline-flex;padding:3px 7px;border:1px solid var(--line);border-radius:3px;font:10px/1.5 ui-monospace,monospace;color:var(--muted);white-space:normal;overflow-wrap:anywhere;vertical-align:middle}.badge.blue{color:var(--blue);background:color-mix(in srgb,var(--blue) 8%,transparent)}.badge.teal{color:var(--teal);background:color-mix(in srgb,var(--teal) 7%,transparent)}.badge.amber{color:var(--amber);background:color-mix(in srgb,var(--amber) 6%,transparent)}.badge.red{color:var(--red);background:color-mix(in srgb,var(--red) 6%,transparent)}.badge.violet{color:var(--violet)}.kpis{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:5px;overflow:hidden;margin-bottom:23px}.kpis.summary{grid-template-columns:repeat(4,minmax(0,1fr))}.kpi{background:var(--panel);padding:15px 12px;min-width:0}.kpi label{font-size:10px;letter-spacing:.2px;min-height:30px;font-weight:500}.kpi strong{display:block;font-size:26px;font-weight:600;letter-spacing:-1px;margin:7px 0}.kpi small{font:9px ui-monospace,monospace;color:var(--muted)}.grid{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:18px;align-items:start}.three{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px}.two{display:grid;grid-template-columns:1fr 1fr;gap:18px}.stack{display:grid;gap:18px;min-width:0}.panel{background:var(--panel);border:1px solid var(--line);border-radius:5px;min-width:0;overflow:hidden}.panelhead{padding:16px 18px;border-bottom:1px solid var(--line);display:flex;gap:10px;align-items:center;min-height:56px}.panelhead h2{margin:0;font-size:13px;font-weight:600}.panelhead .sub{margin-left:auto;font-size:10px;color:var(--muted);font-family:ui-monospace,monospace}.body{padding:18px}.muted{color:var(--muted)}.mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.small{font-size:12px}.tiny{font-size:10px}.row{display:flex;gap:12px;align-items:center}.between{justify-content:space-between}.listrow{padding:16px 18px;border-bottom:1px solid var(--line)}.listrow:last-child{border-bottom:0}.listrow h3{font-size:13px;font-weight:600;margin:0 0 5px}.listrow p{font-size:12px;color:var(--muted);margin:5px 0}.progress{height:4px;background:var(--raised);margin:13px 0 6px;border-radius:2px;overflow:hidden}.progress i{display:block;background:var(--blue);height:100%}.jobrow{display:grid;grid-template-columns:minmax(0,1fr) 130px 120px 32px;align-items:center;gap:16px}.jobrow h3{margin:3px 0}.jobrow small{font-size:10px;color:var(--muted)}.sectionlabel{font-size:10px;text-transform:uppercase;letter-spacing:1.2px;color:var(--muted)}.signal{width:8px;height:8px;background:var(--teal);border-radius:2px}.warning{border-left:2px solid var(--amber)}.timeline{padding:0 18px}.event{padding:14px 0 14px 17px;border-left:1px solid var(--line);position:relative;font-size:12px}.event:before{content:'';position:absolute;left:-3px;top:20px;width:5px;height:5px;background:var(--blue);border-radius:50%}.event small{display:block;font:10px ui-monospace,monospace;color:var(--muted);margin-top:4px}.notice{padding:12px 15px;background:var(--raised);border:1px solid var(--line);border-radius:4px;font-size:12px;color:var(--muted);margin-bottom:18px;overflow-wrap:anywhere}.notice strong{color:var(--amber)}.formgrid{display:grid;grid-template-columns:1fr 1fr;gap:13px}.formgrid .full{grid-column:1/-1}.success{color:var(--teal);font-size:12px}.tabs{display:flex;gap:3px;flex-wrap:wrap;border-bottom:1px solid var(--line);padding:0 15px;background:var(--panel)}.tabs button{background:transparent;border:0;border-radius:0;font-size:12px;color:var(--muted);min-height:46px;border-bottom:2px solid transparent}.tabs button.selected{color:var(--blue);border-bottom-color:var(--blue)}.tablewrap{overflow:auto;max-width:100%}table{width:100%;border-collapse:collapse;text-align:left;font-size:12px}th{color:var(--muted);font-size:10px;text-transform:uppercase;letter-spacing:.8px;font-weight:500;background:var(--raised);white-space:nowrap}td,th{padding:13px 16px;border-bottom:1px solid var(--line)}td .mono{font-size:11px}tr:last-child td{border-bottom:0}tr:hover td{background:color-mix(in srgb,var(--raised) 50%,transparent)}.chart{display:block;width:100%;height:auto;color:var(--blue)}.chart text{fill:var(--muted);font:11px ui-monospace,monospace}.chart .gridline{stroke:var(--line);stroke-width:1}.legend{display:flex;gap:20px;font-size:10px;color:var(--muted);padding:8px 0}.legend span:before{content:'';display:inline-block;width:7px;height:7px;background:var(--blue);margin-right:6px}.legend span:nth-child(2):before{background:var(--teal)}.dock{margin:20px 28px 0;padding:10px 16px;border:1px solid var(--line);display:flex;gap:12px;align-items:center;color:var(--muted);font:11px ui-monospace,monospace;border-radius:4px;background:var(--nav)}.dock a{color:var(--blue)}.footer{padding:13px 28px;display:flex;justify-content:space-between;color:var(--muted);font:9px ui-monospace,monospace;letter-spacing:.5px}.terminal{background:var(--nav);min-height:360px;padding:22px}.termline{margin:0 0 22px;white-space:pre-wrap;overflow-wrap:anywhere;font:12px/1.8 ui-monospace,monospace}.termline .prompt{color:var(--teal)}.composer{display:flex;gap:10px;padding:15px;border-top:1px solid var(--line)}.composer input{flex:1}.modebar{display:flex;flex-wrap:wrap;gap:5px;padding:12px}.modebar .selected{border-color:var(--blue);color:var(--blue)}.nodecanvas{overflow:auto;background-color:var(--nav);background-image:radial-gradient(var(--line) 1px,transparent 1px);background-size:18px 18px;min-height:390px;padding:16px}.graph{width:100%;min-width:560px;height:340px;display:block}.graph rect{fill:var(--panel);stroke:var(--line);stroke-width:1.5}.graph text{fill:var(--text);font:12px -apple-system,sans-serif}.graph .id{font:10px ui-monospace,monospace;fill:var(--blue)}.graph path{stroke:var(--blue);stroke-width:1.5;fill:none}.graph g{cursor:pointer}.graph g:hover rect,.graph .picked rect{stroke:var(--blue)}.graph .minimap{fill:var(--raised)}.preview{background:var(--nav);padding:26px;overflow:auto;min-height:380px}.mockpage{background:var(--panel);border:1px solid var(--line);margin:auto;padding:24px;max-width:100%;min-height:310px}.mockcomponent{padding:20px;border:1px solid var(--line);background:var(--raised);margin:12px 0;cursor:pointer}.mockcomponent.picked{outline:2px solid var(--blue)}.kanban{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;padding:16px}.kanbancard{padding:15px;background:var(--raised);border:1px solid var(--line);margin:10px 0;border-radius:4px}.kanbancard h3{font-size:13px;margin:0 0 8px}.option{padding:20px;border:1px solid var(--line);border-radius:4px;cursor:pointer}.option.picked{border-color:var(--blue);background:var(--raised)}.option h3{font-size:16px;margin:8px 0}.metric{font-size:32px;letter-spacing:-1px;line-height:1.4}.rule{border:0;border-top:1px solid var(--line);margin:18px 0}.modal{background:var(--panel);color:var(--text);border:1px solid var(--line);border-radius:7px;padding:0;width:min(560px,calc(100% - 28px));max-height:85vh;box-shadow:var(--shadow)}.modal::backdrop{background:#030814b8}.modal.wide{width:min(820px,calc(100% - 28px))}.modal form{display:grid;gap:15px;padding:20px}.modal .panelhead{position:sticky;top:0;background:var(--panel);z-index:1}.modalcontent{padding:20px;overflow:auto}.modal h2{font-size:16px;margin:0}.modal .close{margin-left:auto;min-width:36px}.modalfoot{display:flex;justify-content:flex-end;gap:8px;padding-top:8px}.toast{position:fixed;bottom:22px;right:24px;max-width:min(440px,calc(100% - 32px));padding:15px 20px;border:1px solid var(--blue);background:var(--raised);color:var(--text);box-shadow:var(--shadow);border-radius:4px;z-index:100;font-size:13px}.toast.error{border-color:var(--red)}.ticket{border-left:2px solid var(--violet)}.hostmap{display:flex;align-items:center;justify-content:space-around;gap:16px;padding:30px 12px;flex-wrap:wrap}.hostbox{border:1px solid var(--line);padding:18px;background:var(--raised);text-align:center;min-width:150px}.hostbox .icon{width:30px;height:30px;color:var(--blue)}.coverage{max-height:460px;overflow:auto}.hidden{display:none!important}button:disabled{cursor:not-allowed;opacity:.5}@media(min-width:1550px){main{padding:32px 40px}.topbar{padding:0 40px}.grid{grid-template-columns:minmax(0,1fr) 330px}.kpi{padding:18px}}
@media(max-width:1250px){.kpis{grid-template-columns:repeat(4,1fr)}.topbar{gap:8px;padding:0 20px}.crumb{display:none}.searchbtn{min-width:120px}.grid{grid-template-columns:minmax(0,1fr) 260px}.jobrow{grid-template-columns:minmax(0,1fr) 90px 90px}.jobrow>button{display:none}.app{grid-template-columns:204px minmax(0,1fr)}.sidebar{width:204px}main{padding:24px 20px}.three{gap:10px}}
@media(max-width:1000px){.grid{grid-template-columns:1fr}.grid>.stack{grid-template-columns:1fr 1fr}.three{grid-template-columns:1fr}.topbar{height:auto;min-height:66px;flex-wrap:wrap;padding-top:10px;padding-bottom:10px}.two{grid-template-columns:1fr}.pagehead{flex-wrap:wrap}.pagehead .actions{margin-left:0}.sidebar{width:190px}.app{grid-template-columns:190px minmax(0,1fr)}.brand{padding:0 16px}.kanban{grid-template-columns:1fr}.jobrow{grid-template-columns:minmax(0,1fr) 110px}.jobrow>div:nth-child(3){display:none}.searchbtn{min-width:44px;font-size:0}.searchbtn .key{font-size:10px}.topbar .jobselect{max-width:220px}}
@media(max-width:700px){.app{display:block}.sidebar{transform:translateX(-100%);width:240px;box-shadow:var(--shadow)}.sidebar.open{transform:translateX(0)}.mobilemenu{display:inline-flex}.topbar{padding:10px 12px;height:auto;min-height:64px;flex-wrap:wrap;gap:8px}.topbar .jobselect{max-width:calc(100% - 62px);flex:1}.topbar .spacer{display:none}.topbar .searchbtn{margin-left:auto}.rolebtn{font-size:12px}.shell{width:100%}main{padding:20px 14px}.pagehead h1{font-size:25px}.pagehead p{font-size:12px}.pagehead{gap:12px;margin-bottom:20px}.kpis,.kpis.summary{grid-template-columns:repeat(2,minmax(0,1fr))}.kpi{padding:12px}.kpi label{min-height:0}.kpi strong{font-size:27px;margin:5px 0}.grid>.stack{grid-template-columns:1fr}.formgrid{grid-template-columns:1fr}.formgrid .full{grid-column:auto}.jobrow{grid-template-columns:minmax(0,1fr) 90px;gap:8px}.body{padding:15px}.panelhead{padding:13px 15px}.listrow{padding:15px}.actions button{min-height:44px}.topbar button{min-height:40px}.dock{margin:10px 14px 0;flex-wrap:wrap;font-size:10px}.footer{padding:12px 14px;gap:8px;flex-wrap:wrap}.composer{flex-wrap:wrap}.composer input{width:100%;flex:auto}.modal .panelhead{align-items:start}.tablewrap table{min-width:560px}.tabs{padding:0 8px}.tabs button{padding:8px}.metric{font-size:28px}.hostmap{display:grid;grid-template-columns:1fr}.hostbox{width:100%}}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media print{.sidebar,.topbar,.dock,.footer,button,.toast{display:none!important}.app{display:block}.shell{display:block}body{background:white;color:black}.panel{break-inside:avoid}main{padding:0}.modal{position:static;width:100%;max-height:none}}

/* HYBRID A+G1R/P0: logo and scrollbar surface ONLY. Preserve A layout and behavior. */
:root {
  color-scheme: dark;
  --scroll-thumb: #4d6282;
  --scroll-thumb-hover: #7094c5;
}
[data-theme="light"] {
  color-scheme: light;
  --scroll-thumb: #b7c5d8;
  --scroll-thumb-hover: #829bbb;
}
/* Keep controls visible but remove the bulky, platform-default scrollbar treatment. */
html, body, .navscroll, .nodecanvas, .tablewrap, .coverage,
.preview, .terminal, .modalcontent, .modal {
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) transparent;
}
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  min-height: 32px;
  border: 2px solid transparent;
  border-radius: 999px;
  background: var(--scroll-thumb);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background-color: var(--scroll-thumb-hover);
  background-clip: padding-box;
}
::-webkit-scrollbar-button { display: none; }
::-webkit-scrollbar-corner { background: transparent; }
/* G1R typography / branded square treatment, sized to fit the existing A shell. */
.brand { gap: 10px; letter-spacing: -.04em; text-transform: none; }
.brandmark {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  border-radius: 7px;
  background: linear-gradient(145deg, #8fb7ff 0%, #5d89ee 100%);
  box-shadow: inset 0 1px 0 #ffffff50, 0 3px 10px #0002;
  color: #101a35;
  font: 800 21px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  letter-spacing: -.065em;
}
.brand-wordmark { display: inline-flex; align-items: baseline; color: var(--text); font: 750 19px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; letter-spacing: -.06em; }
.brand-point { color: var(--blue); }
.brand-wordmark sup { position: relative; top: -.4em; padding-left: 5px; color: var(--muted); font: 650 9px/1 ui-monospace, SFMono-Regular, Consolas, monospace; letter-spacing: .09em; }
[data-theme="light"] .brandmark { background: linear-gradient(145deg,#6fa2ff 0%,#365ed8 100%); color: white; }
@media (max-width: 1000px) { .brand { padding-inline: 14px; } }
</style></head>
<body><div class="app"><aside class="sidebar" id="sidebar"></aside><div class="shell"><header class="topbar" id="topbar"></header><main id="main"></main><div class="dock"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true" style="color:var(--teal)"><path d="M4 7l5 5-5 5 M12 17h8"/></svg><a href="#/terminal">Open terminal</a><span>local://neisse-demo</span><span class="spacer"></span><span>NO EXTERNAL EFFECTS</span><span class="badge">SANDBOX</span></div><footer class="footer"><span>NEISSE OS / CONTROL MATRIX · A</span><span>PROTOTYPE_CANDIDATE · SYNTHETIC DATA ONLY</span></footer></div></div><dialog id="modal" class="modal"></dialog><div id="toast" role="status" aria-live="polite" hidden></div>
<script>
'use strict';
const $=s=>document.querySelector(s), esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
const routes=['command','terminal','studio','factory','fleet','production','finops','inbox','crm','analysis','proposal','decisions','economics','support','capabilities','settings'];
const titles=['Command Center','AI Terminal','Studio & Canvas','Factory Live','Cluster & Hosts','Work Program','Factory FinOps','Company Inbox','Leads & CRM','Cases / Analysis','Architecture / Proposal','Decision Inbox','Economics','Support','Capabilities','Settings & Access'];
const descriptions=['Your operating picture. Decisions, delivery, and the evidence behind them.','Case-linked investigation. Explicit sources. Bounded local effects.','Design the system. Inspect the dependencies. Make intent executable.','Technical execution belongs to Factory. Every effect needs a checkpoint.','Configured is not connected. Freshness is part of the evidence.','A frozen scope, an executable plan, and two distinct acceptance gates.','Follow the cost to its source. Estimates are never provider receipts.','One intake queue. Every conversation has a next permitted action.','From first signal to a qualified, traceable Company Job.','Separate what we know from what we still need to prove.','Choose deliberately. Bound the scope before committing to delivery.','Authority, evidence, revision. No approval by implication.','Business value is an assumption until accepted and reconciled.','Delivery is a beginning. Keep the original job and evidence connected.','Reuse qualified capability. Respect provenance and effective permissions.','One workspace. Explicit authority. No hidden provider connection.'];
const paths={command:'M3 3h7v7H3z M14 3h7v7h-7z M3 14h7v7H3z M14 14h7v7h-7z',terminal:'M4 7l5 5-5 5 M12 17h8',studio:'M4 4h6v6H4z M14 14h6v6h-6z M10 7h7v7 M7 10v7h7',factory:'M3 21V9l6 4V8l6 5V3h4v18z M7 17h1 M12 17h1 M17 17h1',fleet:'M4 3h16v6H4z M4 15h16v6H4z M8 6h.1 M8 18h.1 M12 9v6',production:'M9 4h11 M9 12h11 M9 20h11 M3 4h1 M3 12h1 M3 20h1',finops:'M4 20V10 M10 20V4 M16 20v-7 M22 20H2',inbox:'M4 4h16v16H4z M4 13h5l2 3h2l2-3h5',crm:'M16 21v-3a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v3 M9 10a4 4 0 1 0 0-8 4 4 0 0 0 0 8 M17 3a4 4 0 0 1 0 8 M22 21v-3a4 4 0 0 0-3-4',analysis:'M10 3h7l3 3v15H4V3h6 M8 10h8 M8 14h8 M8 18h4',proposal:'M12 3v5 M4 21v-5h16v5 M12 8v8 M8 8h8',decisions:'M9 12l2 2 4-5 M12 3l9 4v6c0 4-9 8-9 8s-9-4-9-8V7z',economics:'M12 2v20 M17 5H9a4 4 0 0 0 0 8h6a4 4 0 0 1 0 8H6',support:'M4 14v-3a8 8 0 0 1 16 0v3 M4 12H2v6h4v-6z M20 12h2v6h-4v-6z M20 18v3h-8',capabilities:'M12 3l9 5-9 5-9-5z M3 12l9 5 9-5 M3 16l9 5 9-5',settings:'M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8 M12 2v3 M12 19v3 M2 12h3 M19 12h3 M5 5l2 2 M17 17l2 2 M5 19l2-2 M17 7l2-2',arrow:'M5 12h14 M13 6l6 6-6 6',plus:'M12 5v14 M5 12h14',sun:'M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8 M12 2v2 M12 20v2 M2 12h2 M20 12h2 M5 5l2 2 M17 17l2 2 M5 19l2-2 M17 7l2-2',search:'M10 3a7 7 0 1 0 0 14 7 7 0 0 0 0-14 M15 15l6 6',menu:'M3 6h18 M3 12h18 M3 18h18',close:'M6 6l12 12 M18 6L6 18',bell:'M5 17V9a7 7 0 0 1 14 0v8l2 2H3z M10 22h4',check:'M5 12l4 4L19 6'};
const icon=n=>`<svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="${paths[n]||paths.analysis}"/></svg>`;
const badge=(t,c='')=>`<span class="badge ${c||(/DENIED|REJECTED|FAIL|STOP/.test(t)?'red':/STALE|BLOCK|UNKNOWN|DRAFT|NOT_CONNECTED|ACK/.test(t)?'amber':/APPROVED|ACCEPTED|VERIFIED|APPLIED|QUALIFIED/.test(t)?'teal':'blue')}">${esc(t)}</span>`;
const btn=(text,action,cls='',data='')=>`<button type="button" class="${cls}" data-action="${action}" ${data}>${text}</button>`;
const link=(r,t)=>`<a href="#/${r}" class="badge blue">${esc(t)} ↗</a>`;
const panel=(title,body,sub='')=>`<section class="panel"><div class="panelhead"><h2>${title}</h2><span class="sub">${sub}</span></div>${body}</section>`;
const table=(heads,rows)=>`<div class="tablewrap"><table><thead><tr>${heads.map(h=>`<th>${h}</th>`).join('')}</tr></thead><tbody>${rows.map(r=>`<tr>${r.map(c=>`<td>${c}</td>`).join('')}</tr>`).join('')}</tbody></table></div>`;
const tabs=(group,items,selected)=>`<div class="tabs" role="tablist" aria-label="${group}">${items.map(t=>`<button type="button" role="tab" aria-selected="${selected===t}" class="${selected===t?'selected':''}" data-action="tab" data-group="${group}" data-value="${t}">${t}</button>`).join('')}</div>`;
const now=()=>new Date().toISOString();
const seed=()=>({version:1,theme:'dark',role:'Owner',selected:'CASE-001',company:[{id:'CO-1',name:'Vela Works'},{id:'CO-2',name:'Lumen Freight'},{id:'CO-3',name:'Morrow Studio'},{id:'CO-4',name:'Northline Labs'}],contacts:[{id:'CT-1',company:'CO-1',name:'Mira Vale',email:'mira@vela.example'},{id:'CT-2',company:'CO-2',name:'Eli Rowan',email:'eli@lumen.example'}],leads:[{id:'L-101',company:'CO-1',contact:'CT-1',name:'Vela Works',need:'Intake qualification',stage:'Qualified',value:6400},{id:'L-102',company:'CO-2',contact:'CT-2',name:'Lumen Freight',need:'Document reconciliation',stage:'Discovery',value:9800,job:'CASE-002'},{id:'L-103',company:'CO-3',name:'Morrow Studio',need:'Studio handoff automation',stage:'New',value:4200,job:'CASE-003'},{id:'L-104',company:'CO-4',name:'Northline Labs',need:'Knowledge retrieval',stage:'New',value:7200}],jobs:[{id:'CASE-001',company:'CO-1',name:'Customer intake system',client:'Vela Works',analysis:false,an:false,scope:false,frozen:false,tech:false,accepted:false,request:'NOT_REQUESTED',attempts:0,option:'Reuse',budget:900,progress:18},{id:'CASE-002',company:'CO-2',name:'Freight document reconciliation',client:'Lumen Freight',analysis:true,an:true,scope:true,frozen:true,tech:false,accepted:false,request:'SIMULATED_APPLIED',attempts:1,option:'Reuse',budget:1400,progress:62},{id:'CASE-003',company:'CO-3',name:'Studio delivery handoff',client:'Morrow Studio',analysis:true,an:true,scope:false,frozen:false,tech:false,accepted:false,request:'NOT_REQUESTED',attempts:0,option:'Keep',budget:600,progress:32}],decisions:[{id:'D-201',job:'CASE-002',gate:'G-AN',status:'APPROVED',rev:1,expires:'2026-12-31',note:'Fixture: analytical evidence accepted',time:'2026-11-07T10:12:00Z'},{id:'D-202',job:'CASE-002',gate:'G-SCOPE',status:'APPROVED',rev:1,expires:'2026-12-31',note:'Fixture: bounded scope approved',time:'2026-11-07T10:35:00Z'},{id:'D-203',job:'CASE-003',gate:'G-SCOPE',status:'PENDING',rev:1,expires:'2026-12-31',note:'Compare keep vs reuse. Owner required.',time:'2026-11-07T11:03:00Z'}],runs:[{id:'RUN-071',job:'CASE-002',status:'SIMULATED_RUNNING',worker:'worker-01',checkpoint:'3 / 7',source:'fixture / trace-071'},{id:'RUN-070',job:'CASE-002',status:'FAILED_DEMO',worker:'worker-02',checkpoint:'schema validation',source:'fixture / trace-070'}],hosts:[{id:'host-01',name:'Atlas / local',state:'FRESH_DEMO',probe:'2026-11-07 12:03Z',cpu:'24% fixture',ram:'3.1 / 8 GB fixture',lease:'worker-01 · DEMO lease'},{id:'host-02',name:'Boreal / remote',state:'STALE',probe:'2026-11-05 08:40Z',cpu:'UNKNOWN',ram:'UNKNOWN',lease:'Expired · no capacity claim'},{id:'host-03',name:'Cirrus / provider',state:'NOT_CONNECTED',probe:'No provider receipt',cpu:'UNKNOWN',ram:'UNKNOWN',lease:'No lease'}],evidence:[{id:'EV-001',job:'CASE-001',name:'Inbound intake transcript',kind:'SYNTHETIC',source:'fixture / message-001',time:'2026-11-07 09:42Z'},{id:'EV-002',job:'CASE-002',name:'Schema mismatch / row 18',kind:'FAILED_DEMO',source:'fixture / trace-070',time:'2026-11-07 11:30Z'},{id:'EV-003',job:'CASE-002',name:'Scope approval r1',kind:'STORED_INTERNAL',source:'fixture / D-202',time:'2026-11-07 10:35Z'}],invoices:[{id:'INV-D001',job:'CASE-002',amount:9800,status:'DRAFT',note:'No accounting receipt; not receivable cash'}],tickets:[{id:'SUP-021',job:'CASE-002',run:'RUN-070',title:'Document schema mismatch',priority:'P1',status:'OPEN',assignee:'Operator',notes:['Synthetic failure on row 18. Reproduce before repair.']},{id:'SUP-022',job:'CASE-003',run:'None',title:'Handoff field mapping review',priority:'P2',status:'OPEN',assignee:'Owner',notes:['Confirm required delivery fields.']}],capabilities:[{id:'CAP-01',name:'Intake schema validator',type:'Skill',repo:'demo/intake-kit',version:'1.3.0',license:'MIT (fixture)',state:'QUALIFIED_DEMO',enabled:false,tests:0},{id:'CAP-02',name:'Document extraction adapter',type:'Plugin',repo:'demo/document-kit',version:'0.8.2',license:'Internal (fixture)',state:'EXISTS_BUT_UNAVAILABLE',enabled:false,tests:0},{id:'CAP-03',name:'Accounting MCP',type:'MCP',repo:'No source',version:'—',license:'UNKNOWN',state:'ABSENT',enabled:false,tests:0}],nodes:['Intake','Analysis','Owner gate','Scoped plan','Factory','Technical QA','Business acceptance'].map((n,i)=>({id:'n'+(i+1),name:n,type:['Input','Analysis','Gate','Plan','Worker','QA','Gate'][i]})),edges:[['n1','n2'],['n2','n3'],['n3','n4'],['n4','n5'],['n5','n6'],['n6','n7']],ui:[{id:'u1',name:'Intake workspace',type:'Section'},{id:'u2',name:'Qualification queue',type:'Table'},{id:'u3',name:'Evidence inspector',type:'Panel'}],terminal:[{mode:'Investigate',job:'CASE-001',prompt:'Inspect intake readiness',response:'DEMO analysis: two intake channels; human triage remains mandatory. Source EV-001 is synthetic. Contradiction: requested full automation, but exception rules are not defined.',time:'12:04:17',receipt:'LOCAL-001'}],drafts:[{id:'DR-01',text:'Thank you for the intake brief. We will prepare a bounded analysis.',state:'DRAFT'}],events:[{time:'2026-11-07T12:04:00Z',job:'CASE-002',text:'RUN-071 checkpoint persisted · SIMULATED_RUNNING'},{time:'2026-11-07T11:30:00Z',job:'CASE-002',text:'RUN-070 schema test failed · repair requires bounded request'},{time:'2026-11-07T11:03:00Z',job:'CASE-003',text:'G-SCOPE r1 awaiting Owner'}],notes:[],preferences:{model:'Local predefined demo',ceiling:900},messageLead:null});
let S;try{S=JSON.parse(localStorage.getItem('neisse-control-matrix-v1'))}catch{}if(!S||S.version!==1)S=seed();
function ensurePlanSnapshots(){for(const j of S.jobs){if(j.frozen&&!j.plan)j.plan={revision:1,created:'2026-11-07T10:35:00Z',nodes:JSON.parse(JSON.stringify(S.nodes)),edges:JSON.parse(JSON.stringify(S.edges))};}}
let V={studio:'Flow',production:'Graph',analysis:'Facts',crm:'List',inbox:'All',terminalMode:'Investigate',node:'n1',cap:'CAP-01',device:'Desktop',ui:'u1',recordTab:'Activity',period:'7 days',zoom:1,factoryJob:null};
function persist(){try{localStorage.setItem('neisse-control-matrix-v1',JSON.stringify(S))}catch{toast('Storage unavailable: state lasts for this session only.',true)}}
const job=()=>S.jobs.find(x=>x.id===S.selected)||S.jobs[0];
function event(text,j=S.selected){S.events.unshift({time:now(),job:j,text});persist()}
function toast(t,error=false){let el=$('#toast');el.className='toast'+(error?' error':'');el.textContent=t;el.hidden=false;clearTimeout(V.toast);V.toast=setTimeout(()=>el.hidden=true,7000)}
function deny(t){event('DENIED · '+t);toast('DENIED · '+t,true);render();return false}
function owner(){return S.role==='Owner'||deny('Owner authority required. Current role: '+S.role)}
function route(){let [p,q='']=(location.hash.replace(/^#\/?/,'')||'command').split('?');let c=new URLSearchParams(q).get('case');if(c&&S.jobs.some(j=>j.id===c)){S.selected=c;persist()}return routes.includes(p)?p:'command'}
function go(r){location.hash='/'+r}
function selectJob(id){let r=route();S.selected=id;persist();history.replaceState(null,'','#/'+r+'?case='+encodeURIComponent(id));render()}
function eventsHTML(j=null,limit=5){return `<div class="timeline">${S.events.filter(e=>!j||e.job===j).slice(0,limit).map(e=>`<div class="event">${esc(e.text)}<small>${esc(e.job)} · ${esc(e.time.replace('T',' ').slice(0,19))} · LOCAL</small></div>`).join('')||'<p class="muted small">No local events for this job yet.</p>'}</div>`}
function head(r,action=''){return `<div class="eyebrow">WORKSPACE / ${r==='command'?'OPERATING OVERVIEW':esc(job().id)} <span style="color:var(--blue)">/ ${String(routes.indexOf(r)+1).padStart(2,'0')}</span></div><div class="pagehead"><div><h1>${titles[routes.indexOf(r)]}</h1><p>${descriptions[routes.indexOf(r)]}</p></div><div class="actions">${action}</div></div>`}
function render(){ensurePlanSnapshots();const r=route();document.documentElement.dataset.theme=S.theme;$('#sidebar').innerHTML=`<a href="#/command" class="brand" aria-label="Neisse OS — Command Center"><span class="brandmark" aria-hidden="true">N</span><span class="brand-wordmark">neisse<span class="brand-point">.</span><sup>OS</sup></span></a><div class="workspace"><span class="avatar">N/</span><div><strong class="small">Founder workspace</strong><small>Sandbox · Control Matrix</small></div></div><nav class="navscroll" aria-label="Main navigation">${[['OVERVIEW',['command']],['BUSINESS',['inbox','crm','analysis','proposal','economics','support']],['PRODUCTION',['factory','fleet','production','finops','capabilities']],['WORKBENCH & GOVERNANCE',['terminal','studio','decisions','settings']]].map(([g,rs])=>`<div class="navgroup">${g}</div>${rs.map(n=>`<a class="navitem ${r===n?'active':''}" href="#/${n}" ${r===n?'aria-current="page"':''}>${icon(n)}<span>${titles[routes.indexOf(n)]}</span><span class="num">${String(routes.indexOf(n)+1).padStart(2,'0')}</span></a>`).join('')}`).join('')}</nav><div class="sidefoot"><div class="row between">${badge('DEMO / SYNTHETIC','violet')}<span class="tiny muted">v1.0</span></div><span class="mono">LOCAL STORE · NO PROVIDER EFFECTS</span></div>`;
$('#topbar').innerHTML=`${btn(icon('menu'),'menu','mobilemenu','aria-label="Toggle navigation"')}<span class="crumb">Workspace <span style="margin:0 8px;color:var(--line)">/</span> ${titles[routes.indexOf(r)]}</span><select class="jobselect" aria-label="Selected Company Job" id="jobselect">${S.jobs.map(j=>`<option value="${j.id}" ${j.id===S.selected?'selected':''}>${j.id} · ${esc(j.client)}</option>`).join('')}</select><span class="spacer"></span>${btn(icon('search')+'Search <span class="key">⌘ K</span>','palette','searchbtn')}<span class="status">DEMO · NOT_CONNECTED</span>${btn(icon('bell'),'notifications','themebtn','aria-label="Notifications"')}${btn(icon('sun'),'theme','themebtn','aria-label="Toggle dark or light theme"')}${btn(esc(S.role)+' ⌄','role','rolebtn')}`;
$('#main').innerHTML=pages[r]();}
const costchart=()=>`<svg class="chart" viewBox="0 0 600 180" role="img" aria-label="Synthetic cost estimate over seven checkpoints, model costs 18, 30, 25, 47, 41, 64, 58 euros; compute 8 to 21 euros"><path class="gridline" d="M40 20H580 M40 65H580 M40 110H580 M40 155H580"/><text x="2" y="25">€80</text><text x="2" y="70">€50</text><text x="2" y="115">€25</text><path d="M50 125L135 105L220 112L305 75L390 85L475 43L560 52L560 155H50Z" fill="var(--blue)" opacity=".09"/><path d="M50 125L135 105L220 112L305 75L390 85L475 43L560 52" stroke="var(--blue)" stroke-width="2" fill="none"/><path d="M50 144L135 138L220 140L305 132L390 130L475 124L560 119" stroke="var(--teal)" stroke-width="2" fill="none"/>${[1,2,3,4,5,6,7].map((n,i)=>`<text x="${46+i*85}" y="176">C${n}</text>`).join('')}</svg>`;
const pages={};
pages.command=()=>{const pending=S.decisions.filter(d=>d.status==='PENDING');const ks=[['Active leads',S.leads.length,'LOCAL CRM','All synthetic deals; current local state'],['Company Jobs',S.jobs.length,'LOCAL STORE','All Company Jobs; includes pending jobs'],['Pending G-AN',pending.filter(d=>d.gate==='G-AN').length,'DECISIONS','Pending analytical gates; local state'],['Owner blocked',pending.length,'GATE QUEUE','All pending decisions requiring Owner'],['Configured hosts',S.hosts.length,'FLEET CONFIG','Configured fixture entries, not availability'],['Verified online','—','NOT_CONNECTED','UNKNOWN: no live probe receipts'],['Productive runs','—','NOT_CONNECTED','UNKNOWN: no live productive-outcome receipts'],['Reconciled cost','—','NOT_CONNECTED','UNKNOWN: no accounting provider connection']];return head('command',btn('Review decisions '+icon('arrow'),'nav','primary','data-route="decisions"'))+`<div class="kpis">${ks.map(([n,v,s,t])=>`<div class="kpi" title="${t} · freshness: local session · window: all demo records"><label>${n}</label><strong ${v==='—'?'style="color:var(--muted)"':''}>${v}</strong><small>${s}</small></div>`).join('')}</div><div class="grid"><div class="stack">${panel('Company Jobs',S.jobs.map(j=>`<div class="listrow jobrow"><div><small class="mono">${j.id} / ${esc(j.client)}</small><h3>${esc(j.name)}</h3><p>${j.accepted?'Business accepted · demo':j.frozen?'Frozen r1 · Factory execution':j.an?'Analysis accepted · scope required':'Discovery · analysis required'}</p></div><div><div class="progress"><i style="width:${j.progress}%"></i></div><small>${j.progress}% · local plan</small></div><div>${badge(j.accepted?'ACCEPTED_DEMO':j.frozen?'IN_EXECUTION':'OWNER GATE')}</div>${btn(icon('arrow'),'openjob','','data-id="'+j.id+'" aria-label="Open '+j.id+'"')}</div>`).join(''),'3 TRACKED / DEMO')}${panel('Execution pressure',`<div class="body"><div class="row between"><div><span class="metric">€ 343<span class="muted small"> / € ${job().budget}</span></span><div class="muted small">Synthetic spend estimate · selected job ceiling</div></div>${badge('ESTIMATED','violet')}</div>${costchart()}<div class="legend"><span>Model request estimates</span><span>Compute allocation</span></div><div class="row between small"><span class="muted">Source: fixture / cost-ledger · not billed</span>${link('finops','Inspect ledger')}</div></div>`,'7 CHECKPOINTS')}${panel('Capture an operating note',`<form id="commandform" class="body formgrid"><label>Note title <input name="title" required placeholder="e.g. Confirm intake exception policy"></label><label>Owner email <input name="email" type="email" required placeholder="owner@example.test"></label><label class="full">Decision context <textarea name="context" required placeholder="Describe the evidence or decision needed."></textarea></label><div class="actions full">${'<button class="primary" type="submit">'+icon('plus')+' Save local note</button>'}<span id="formsuccess" class="success" role="status">${S.notes.length?S.notes.length+' notes stored locally':''}</span></div></form>`,'NATIVE FORM / LOCAL ONLY')}</div><div class="stack">${panel('Needs your authority',pending.length?pending.slice(0,3).map(d=>`<div class="listrow warning"><div class="row between">${badge(d.gate,'amber')}<span class="mono tiny muted">${d.id}</span></div><h3 style="margin-top:12px">${esc(S.jobs.find(j=>j.id===d.job)?.client)}</h3><p>${esc(d.note)}</p><div class="row between"><span class="tiny muted">${d.job} · r${d.rev}</span>${btn('Review →','decision','','data-id="'+d.id+'"')}</div></div>`).join(''):'<div class="body muted small">No pending owner decisions in the local store.</div>','OWNER ONLY')}${panel('Intervention rail',`<div class="listrow"><div class="row">${icon('fleet')}<h3>Boreal probe expired</h3></div><p>Last evidence 05 Nov. Capacity UNKNOWN.</p>${link('fleet','Inspect stale host')}</div><div class="listrow"><div class="row">${icon('factory')}<h3>Schema mismatch · RUN-070</h3></div><p>Same-failure repair limit: 3 attempts.</p>${link('factory','Inspect attempt')}</div><div class="listrow"><div class="row">${icon('inbox')}<h3>Intake waiting for triage</h3></div><p>Orion Assembly · synthetic inbound.</p>${link('inbox','Open conversation')}</div>`,'2 RISKS / 1 INTAKE')}${panel('Audit / recent activity',eventsHTML(null,4),'STORED_INTERNAL')}</div></div>`};
pages.inbox=()=>head('inbox',btn(icon('plus')+' Email draft','modal','','data-purpose="new-draft"'))+`<div class="notice"><strong>DEMO / SYNTHETIC</strong> · All messages are fictional. Email provider NOT_CONNECTED. Delivery confirmation is UNKNOWN.</div><div class="grid"><section class="panel">${tabs('inbox',['All','Unread','Drafts','Channel health'],V.inbox)}${V.inbox==='Channel health'?table(['Channel','State','Last readback'],[['Email',badge('NOT_CONNECTED'),'No receipt'],['Web intake',badge('SYNTHETIC'),'Fixture 07 Nov'],['Attachments',badge('STORED_INTERNAL'),'Demo text only']]):V.inbox==='Drafts'?S.drafts.map(d=>`<div class="listrow"><h3>${d.id} ${badge(d.state)}</h3><p>${esc(d.text)}</p><div class="actions">${btn('Edit draft','modal','','data-purpose="new-draft" data-id="'+d.id+'"')}${btn('Simulate send','sim-send','','data-id="'+d.id+'"')}</div><p>Provider delivery: UNKNOWN / NOT_CONNECTED</p></div>`).join(''):`<div class="listrow row between"><div><span class="sectionlabel">INBOUND / MESSAGE-001</span><h3>Customer intake takes us three days</h3><p>Mira Sol · Orion Assembly · Fictional contact</p></div>${badge('UNREAD','blue')}</div><div class="body"><p class="mono tiny muted">07 NOV 2026 · 09:42 UTC · FIXTURE / MESSAGE-001</p><h2 style="font-size:21px;margin:20px 0">Can we automate the first response?</h2><p>We receive around 60 enquiries a week across two inboxes. The team copies details into a spreadsheet and manually routes exceptions.</p><p>We need a structured intake queue, a reliable qualification check, and a human review before anything reaches a customer.</p><div class="notice">Attachment: intake-requirements.txt · SYNTHETIC<br>Constraints: local PII masking, human approval, no automatic outreach.</div><div class="actions">${btn(S.messageLead?'View created lead':'Create lead from message','inbox-lead','primary')}${btn('Create Company Job','inbox-case')}${btn('Draft reply','modal','','data-purpose="new-draft"')}${btn('Assign / priority','modal','','data-purpose="inbox-save"')}</div></div>`}</section><div class="stack">${panel('Thread context',`<div class="body"><div class="sectionlabel">Source authority</div><p>Fixture / message-001</p>${badge('SYNTHETIC','violet')}<hr class="rule"><p class="small muted">Assigned: ${esc(S.inboxAssignee||'Operator')}<br>Priority: ${esc(S.inboxPriority||'Normal')}<br>Lead: ${esc(S.messageLead||'Not created')}<br>Provider effect: NONE</p></div>`)}${panel('Channel integrity',`<div class="body">${badge('NOT_CONNECTED')}<p class="small muted">A simulated send records a local event. It cannot confirm delivery or send an email.</p></div>`)}</div></div>`;
function crmDrawer(id){V.lead=id;V.recordTab='Activity';showLead()}
function showLead(){let l=S.leads.find(l=>l.id===V.lead);if(!l)return;showDialog(esc(l.name)+' / '+l.id,`${tabs('record',['Activity','Emails','Tasks','Files'],V.recordTab)}<div class="modalcontent">${V.recordTab==='Activity'?`<p>${esc(l.need)}</p><p class="small muted">Company ${l.company} · Contact ${l.contact||'Not assigned'} · Deal ${l.id} · ${l.job||'No Company Job'}</p><form id="leadform"><label>Company name<input name="name" value="${esc(l.name)}" required></label><label>Opportunity / need<input name="need" value="${esc(l.need)}" required></label><label>Stage<select name="stage">${['New','Discovery','Qualified'].map(s=>`<option ${l.stage===s?'selected':''}>${s}</option>`).join('')}</select></label><div class="actions"><button type="submit" class="primary">Save record</button>${btn(l.job?'Open Company Job':'Convert to Company Job','convert','','data-id="'+l.id+'"')}</div></form>`:V.recordTab==='Emails'?`<p class="muted small">Provider NOT_CONNECTED. ${S.drafts.length} synthetic drafts in Company Inbox.</p>${btn('Create email draft','modal','','data-purpose="new-draft"')}`:V.recordTab==='Tasks'?`<p>Next task: validate exception rules with Owner.</p>${btn('Record follow-up','modal','','data-purpose="revision-request"')}`:`<p>intake-requirements.txt</p>${badge('SYNTHETIC')}<p class="small muted">No uploaded customer files. Evidence EV-001 is a fixture.</p>`}</div>`,true)}
pages.crm=()=>{let leads=S.leads.filter(l=>!V.crmFilter||l.stage===V.crmFilter);return head('crm',btn(icon('plus')+' New lead','modal','primary','data-purpose="new-lead"'))+`<div class="panel"><div class="row between body"><div class="actions">${btn('List','crm-mode',V.crm==='List'?'primary':'','data-value="List"')}${btn('Kanban','crm-mode',V.crm==='Kanban'?'primary':'','data-value="Kanban"')}</div><select aria-label="Saved CRM filter" id="crmfilter"><option value="">All opportunities</option>${['New','Discovery','Qualified'].map(s=>`<option ${V.crmFilter===s?'selected':''}>${s}</option>`).join('')}</select><span class="small muted">${leads.length} fictional opportunities</span></div>${V.crm==='List'?table(['Company / contact','Opportunity','Stage','Value · estimate','Next action'],leads.map(l=>[`<strong>${esc(l.name)}</strong><div class="tiny muted mono">${l.id} / ${l.company} / ${l.contact||'UNASSIGNED'}</div>`,esc(l.need),badge(l.stage),`€ ${l.value.toLocaleString()}`,`<div class="actions">${btn('Open record','lead','','data-id="'+l.id+'"')}${btn('Advance','advance-lead','','data-id="'+l.id+'"')}</div>`])):`<div class="kanban">${['New','Discovery','Qualified'].map(s=>`<div><span class="sectionlabel">${s} / ${leads.filter(l=>l.stage===s).length}</span>${leads.filter(l=>l.stage===s).map(l=>`<div class="kanbancard"><h3>${esc(l.name)}</h3><p class="small muted">${esc(l.need)}</p><div class="row between"><span class="mono small">€ ${l.value}</span>${btn('Open →','lead','','data-id="'+l.id+'"')}</div></div>`).join('')}</div>`).join('')}</div>`}</div><div style="margin-top:18px">${panel('Relationship integrity',`<div class="body row between"><p class="small muted">Company → Contact → Deal → Company Job. Conversion preserves the original lead ID and intake activity