@mmmbuto/nexuscrew 0.9.77 → 0.9.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/docs/FLEET.md +40 -0
- package/docs/MCP.md +4 -1
- package/docs/VL_MICRO_NODES.md +10 -3
- package/frontend/dist/assets/index-Be8hcPP6.js +169 -0
- package/frontend/dist/assets/index-BwOOF72d.css +32 -0
- package/frontend/dist/index.html +2 -3
- package/frontend/dist/version.json +1 -1
- package/lib/cells/deliver.js +93 -0
- package/lib/cells/routes.js +2 -1
- package/lib/cells/scope-guard.js +46 -1
- package/lib/diagnostics/store.js +5 -0
- package/lib/fleet/builtin.js +106 -2
- package/lib/fleet/causes.js +4 -0
- package/lib/fleet/cell-exec.js +15 -2
- package/lib/fleet/definitions.js +15 -1
- package/lib/fleet/managed.js +647 -19
- package/lib/fleet/routes.js +39 -0
- package/lib/fleet/runtime.js +144 -0
- package/lib/fleet/vl-session.js +230 -0
- package/lib/mcp/tools.js +20 -4
- package/lib/proxy/federation.js +6 -3
- package/lib/proxy/resource-acl.js +17 -2
- package/lib/server.js +9 -2
- package/lib/vl-nodes/broker.js +64 -6
- package/lib/vl-nodes/outbox.js +333 -0
- package/lib/vl-nodes/routes.js +35 -2
- package/lib/vl-nodes/store.js +127 -2
- package/package.json +1 -1
- package/frontend/dist/assets/index-B9GW2LHm.css +0 -32
- package/frontend/dist/assets/index-Cgd3OQws.js +0 -169
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.nc-icon{display:block;flex:0 0 auto}.nc-live-badge{flex:0 0 auto;padding:1px 6px;border:1px solid #2e7d32;border-radius:8px;background:#0d2410;color:#7fe0a0;font:700 10px/1.4 inherit;letter-spacing:.4px}.nc-live-badge[data-mode=tmux]{border-color:#8a7a2e;background:#241f0d;color:#e0d27f}.nc-popup-velo{position:fixed;top:0;right:0;bottom:0;left:0;z-index:60;display:flex;align-items:center;justify-content:center;padding:2vmin;background:#0000009e}.nc-popup{display:flex;flex-direction:column;width:min(1100px,96vw);height:min(820px,92vh);overflow:hidden;position:relative;border:1px solid var(--nc-border, #1f3f2f);border-radius:10px;background:var(--nc-bg, #0b0f0d);box-shadow:0 10px 40px #0000008c}.nc-popup-testa{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px;border-bottom:1px solid var(--nc-border, #1f3f2f);flex:0 0 auto}.nc-popup-titolo{display:flex;align-items:baseline;gap:8px;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-weight:600}.nc-popup-sub{opacity:.65;font-weight:400;font-size:.82em}.nc-popup-chiudi{flex:0 0 auto;min-width:40px;min-height:40px;border:1px solid var(--nc-border, #1f3f2f);border-radius:8px;background:transparent;color:inherit;cursor:pointer}.nc-popup-corpo{flex:1 1 auto;min-height:0;position:relative;overflow:auto}.nc-popup-corpo>iframe,.nc-popup-corpo>.nc-cellpanel{width:100%;height:100%;border:0}.nc-popup-libera{position:fixed;z-index:2}.nc-popup-angolo{position:absolute;right:0;bottom:0;width:18px;height:18px;cursor:nwse-resize;z-index:3}.nc-popup-angolo:after{content:"";position:absolute;right:4px;bottom:4px;width:8px;height:8px;border-right:2px solid var(--nc-border, #1f3f2f);border-bottom:2px solid var(--nc-border, #1f3f2f)}.nc-popup-velo-drag{position:fixed;top:0;right:0;bottom:0;left:0;z-index:4;background:transparent;cursor:grabbing}@media(max-width:720px){.nc-popup-velo{padding:0}.nc-popup{width:100vw;height:100vh;border:0;border-radius:0}.nc-popup-angolo{display:none}}/**
|
|
2
|
+
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
|
3
|
+
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
|
4
|
+
* https://github.com/chjj/term.js
|
|
5
|
+
* @license MIT
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
|
15
|
+
* all copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
* THE SOFTWARE.
|
|
24
|
+
*
|
|
25
|
+
* Originally forked from (with the author's permission):
|
|
26
|
+
* Fabrice Bellard's javascript vt100 for jslinux:
|
|
27
|
+
* http://bellard.org/jslinux/
|
|
28
|
+
* Copyright (c) 2011 Fabrice Bellard
|
|
29
|
+
* The original design remains. The terminal itself
|
|
30
|
+
* has been extended to include xterm CSI codes, among
|
|
31
|
+
* other features.
|
|
32
|
+
*/.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{font-family:monospace;-webkit-user-select:text;user-select:text;white-space:pre}.xterm .xterm-accessibility-tree>div{transform-origin:left;width:fit-content}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;background:#0000;transition:opacity .1s linear;z-index:11}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{position:absolute;display:none}.xterm .xterm-scrollable-element>.shadow.top{display:block;top:0;left:3px;height:3px;width:100%;box-shadow:var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.left{display:block;top:3px;left:0;height:100%;width:3px;box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.top-left-corner{display:block;top:0;left:0;height:3px;width:3px}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}.nc-terminal{position:absolute;top:0;right:0;bottom:0;left:0;background:#0a0e0a}.nc-terminal-host{position:absolute;top:0;right:0;bottom:0;left:0;padding:4px}.nc-terminal .xterm{height:100%}.nc-terminal-host,.nc-terminal .xterm,.nc-terminal .xterm-viewport{touch-action:none}.nc-terminal.selecting{box-shadow:inset 0 0 0 2px #d6a600}.nc-touch-selection-caret{position:absolute;z-index:8;box-sizing:border-box;pointer-events:none;border:2px solid #baff79;background:#40822c57;box-shadow:0 0 0 1px #040c04e0,0 0 8px #baff798c}.nc-selection-tools{position:absolute;z-index:9;right:10px;top:10px;display:flex;gap:6px;align-items:center;background:#0e140ef0;border:1px solid #586b2a;border-radius:8px;padding:5px 7px;color:#edda8a;font-size:11px}.nc-selection-tools button{background:#172417;border:1px solid #486044;color:#d8ffe8;border-radius:6px;padding:5px 9px}.nc-selection-tools textarea{width:180px;height:48px;background:#071007;color:#d8ffe8}.nc-zoom-bubble{position:absolute;z-index:10;max-width:calc(100% - 8px);box-sizing:border-box;background:#0e140ef5;border:1px solid #586b2a;border-radius:10px;padding:4px 8px;overflow:hidden;box-shadow:0 4px 18px #0000008c,0 0 0 1px #040c0499}.nc-zoom-bubble.flipped{box-shadow:0 -4px 18px #0000008c,0 0 0 1px #040c0499}.nc-zoom-line{margin:0;font-family:ui-monospace,SF Mono,Menlo,Consolas,monospace;line-height:1.25;color:#d8ffe8;white-space:pre;overflow-x:auto}.nc-zoom-sel{background:#baff794d;border-radius:2px;box-shadow:inset 0 -2px #baff79}.nc-selection-held{color:#b7c98a;font-size:10px;opacity:.85;max-width:190px}.nc-sel-handle{position:absolute;z-index:9;width:2px;height:26px;background:#baff79;box-shadow:0 0 0 1px #040c04e0,0 0 8px #baff798c;touch-action:none;cursor:grab}.nc-sel-handle:after{content:"";position:absolute;top:-12px;bottom:-16px}.nc-sel-handle.start:after{left:-28px;right:-14px}.nc-sel-handle.end:after{left:-14px;right:-28px}.nc-sel-handle:before{content:"";position:absolute;top:100%;width:14px;height:14px;border-radius:50%;background:#baff79;box-shadow:0 0 0 1px #040c04e0}.nc-sel-handle.start:before{left:-15px}.nc-sel-handle.start.flip:after{left:-14px;right:-28px}.nc-sel-handle.start.flip:before{left:3px}.nc-sel-handle.end.flip:after{left:-28px;right:-14px}.nc-sel-handle.end.flip:before{left:-15px}.nc-sel-handle.end:before{left:3px}.nc-sel-handle.tight.end:before{top:calc(100% + 10px)}.nc-sel-handle.tight.end:after{bottom:-26px}.nc-sel-handle.dragging{background:#eaffb0;cursor:grabbing;z-index:12}.nc-sel-handle.dragging:before{background:#eaffb0;transform:scale(1.25)}.nc-selection-changed{color:#edda8a;font-size:10px;opacity:.9;max-width:210px}.nc-upload-state{position:absolute;z-index:10;left:50%;top:12px;transform:translate(-50%);max-width:min(520px,calc(100% - 24px));padding:6px 10px;border-radius:7px;border:1px solid #2e7d32;background:#0a140af5;color:#cfe;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}.nc-upload-state.error{border-color:#a44;color:#fbb}.nc-terminal-link-overlay{position:absolute;top:0;right:0;bottom:0;left:0;z-index:5;display:grid;place-items:start center;padding-top:14px;pointer-events:none;font-size:11px;letter-spacing:.04em;color:#b8a24e;background:linear-gradient(rgba(10,14,10,.35),rgba(10,14,10,.15) 40%,transparent 70%)}.nc-cellpanel{position:absolute;top:0;right:0;bottom:0;left:0;z-index:5;background:var(--nc-bg, #0b1014)}.nc-cellpanel-frame{width:100%;height:100%;border:0;background:#fff}.nc-cellpanel-msg{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:24px;color:var(--nc-fg, #cfe3ee);text-align:center;font-size:14px;line-height:1.5}.nc-cellpanel-actions{display:flex;gap:8px}.nc-cellpanel-actions button{padding:8px 14px;background:#122;border:1px solid #243;color:#9fd;border-radius:6px;cursor:pointer;font-size:14px}.nc-cellpanel-actions button:hover{background:#1a2a33}.nc-cellpanel-loading{position:absolute;top:10px;left:50%;transform:translate(-50%);z-index:6;padding:4px 12px;background:#0b1014d9;border:1px solid #243;border-radius:12px;color:#9fd;font-size:12px;pointer-events:none}.nc-cell-switcher-telemetry{color:#9fd8c2}.nc-peek-sorgenti{display:flex;gap:6px;margin-bottom:8px}.nc-peek-sorgente{border:1px solid rgba(216,255,232,.25);background:transparent;color:#d8ffe8;border-radius:6px;padding:4px 10px;font-size:12px;cursor:pointer}.nc-peek-sorgente.attiva{background:#d8ffe829}.nc-peek-stream{min-height:46vh;display:flex;flex-direction:column}.nc-peek-testo{margin:0;padding:12px;white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.86rem;line-height:1.45}.nc-side-peek{border:none;background:transparent;padding:4px 6px;margin-left:-6px;cursor:pointer;display:inline-flex;align-items:center}.nc-side-peek .nc-dot{pointer-events:none}.nc-sheet-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box}.nc-launch-overlay{z-index:70}.nc-sheet{width:100%;max-width:380px;background:#0e140e;color:#cfe;border:1px solid #243;border-radius:14px;padding:16px;display:flex;flex-direction:column;gap:12px;box-shadow:0 12px 40px #00000080}.nc-power-sheet{max-width:min(620px,calc(100vw - 32px));max-height:calc(100dvh - 32px);overflow-y:auto;box-sizing:border-box;min-width:0}.nc-launch-sheet{max-width:min(520px,calc(100vw - 32px));width:100%;min-width:0}.nc-launch-fields{display:flex;flex-direction:column;gap:10px;min-width:0}.nc-launch-fields .nc-field,.nc-launch-fields .nc-field input,.nc-launch-fields .nc-field select{width:100%;min-width:0;max-width:100%;box-sizing:border-box}.nc-sheet-head{display:flex;align-items:center;justify-content:space-between}.nc-sheet-head b{font-size:16px;color:#d8ffe8}.nc-sheet-state{font-size:12px;opacity:.6}.nc-sheet-label{font-size:12px;opacity:.7;text-transform:uppercase;letter-spacing:.5px}.nc-power-config{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 10px;padding:10px;border:1px solid #243;border-radius:8px;background:#0a0e0a;min-width:0;overflow-wrap:anywhere}.nc-power-config span{opacity:.7}.nc-power-config small{grid-column:1 / -1;opacity:.65}.nc-check{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer}.nc-check input{accent-color:#2e7d32}.nc-note{font-size:11px;color:#e0b020;opacity:.9}.nc-field{display:flex;flex-direction:column;gap:4px;font-size:12px;opacity:.8}.nc-field input,.nc-field select{padding:9px 10px;font:14px/1.2 inherit;background:#0a0e0a;color:#cfe;border:1px solid #243;border-radius:8px;width:100%;min-width:0;max-width:100%;box-sizing:border-box}.nc-field input:focus,.nc-field select:focus{outline:none;border-color:#2e7d32}.nc-err{color:#f88;font-size:12px}.nc-sheet-actions{display:flex;justify-content:flex-end;gap:8px;flex-wrap:wrap;min-width:0}.nc-btn{border:none;border-radius:8px;padding:8px 16px;font-size:13px;cursor:pointer}.nc-btn.ghost{background:none;border:1px solid #243;color:#9fd}.nc-btn.primary{background:#2e7d32;color:#fff}.nc-btn.primary:active{background:#255028}.nc-btn:disabled{opacity:.5;cursor:default}@media(max-width:600px){.nc-power-sheet{max-width:380px}}.nc-cellactions{display:flex;flex-direction:column;min-width:210px;padding:4px;gap:2px}.nc-cellactions-voce{display:flex;align-items:center;gap:10px;padding:10px 12px;border:none;border-radius:8px;background:none;color:#d8ffe8;font-size:13px;text-align:left;cursor:pointer;min-height:44px}.nc-cellactions-voce:hover{background:#ffffff12}.nc-cellactions-voce:disabled{opacity:.55;cursor:wait}.nc-cellactions-voce.on{color:#0c6}.nc-cellactions-testo{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-cellactions-desc{display:block;font-size:11px;opacity:.62;white-space:normal;overflow:hidden;text-overflow:ellipsis}.nc-cellactions-toggle{flex:0 0 auto;width:30px;height:17px;border-radius:9px;background:#ffffff24;position:relative;transition:background .12s ease}.nc-cellactions-toggle:after{content:"";position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:#9aa89a;transition:left .12s ease,background .12s ease}.nc-cellactions-toggle.on{background:#00cc6673}.nc-cellactions-toggle.on:after{left:15px;background:#0c6}.nc-cellactions-popover{position:fixed;z-index:55;background:#0e140e;border:1px solid #1c241c;border-radius:10px;box-shadow:0 8px 24px #0000008c}.nc-cellactions-velo{position:fixed;top:0;right:0;bottom:0;left:0;z-index:70;display:flex;align-items:flex-end;background:#00000080}.nc-cellactions-foglio{width:100%;max-height:70vh;overflow:auto;background:#0e140e;border-top:1px solid #1c241c;border-radius:14px 14px 0 0;padding:8px 8px calc(8px + env(safe-area-inset-bottom,0px))}.nc-cellactions-testa{display:flex;align-items:center;gap:8px;padding:6px 8px}.nc-cellactions-titolo{flex:1;min-width:0;font-size:13px;font-weight:700;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-cellactions-chiudi{flex:0 0 auto;width:44px;height:44px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:#ffffff0d;border:1px solid rgba(255,255,255,.22);border-radius:50%;color:#9aa89a;cursor:pointer}.nc-home{display:flex;flex-direction:column;gap:12px;padding:18px 14px 10px;color:#cfe;max-width:560px;margin:0 auto;height:100dvh;min-height:0;overflow:hidden;box-sizing:border-box}.nc-home-scroll{min-height:0;flex:1 1 auto;overflow-y:auto;overscroll-behavior-y:contain;-webkit-overflow-scrolling:touch;display:flex;flex-direction:column;gap:12px;padding:0 2px 8px 0}.nc-home-head{position:relative;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,auto);grid-template-areas:"mark actions" "sub actions";align-items:start;column-gap:12px}.nc-wordmark{grid-area:mark;font-size:26px;font-weight:700;letter-spacing:.5px;color:#d8ffe8;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-cursor{display:inline-block;width:12px;height:22px;margin-left:6px;background:#0c6;vertical-align:-2px;animation:nc-blink 1.1s steps(1) infinite}@keyframes nc-blink{50%{opacity:0}}@media(prefers-reduced-motion:reduce){.nc-cursor{animation:none}}.nc-home-sub{grid-area:sub;margin-top:4px;font-size:13px;opacity:.65}.nc-head-actions{grid-area:actions;display:inline-flex;flex-wrap:wrap;justify-content:flex-end;gap:6px;min-width:0}.nc-refresh{display:inline-flex;align-items:center;justify-content:center;background:none;border:1px solid #243;color:#9fd;border-radius:8px;min-width:40px;min-height:40px}.nc-filter{padding:10px 12px;font:16px/1.2 inherit;background:#0e140e;color:#cfe;border:1px solid #243;border-radius:8px}.nc-filter:focus{outline:none;border-color:#2e7d32}.nc-session-list{display:flex;flex-direction:column;gap:8px}.nc-session{display:flex;align-items:center;gap:12px;padding:12px 14px;border:1px solid #1c241c;background:#0e140e;color:#cfe;border-radius:10px;text-align:left;min-height:56px}.nc-session:active{background:#14200f;border-color:#2e7d32}.nc-session .dot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:#355}.nc-session .dot.on{background:#0c6;box-shadow:0 0 6px #0c68}.nc-session-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.nc-session-main b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px}.nc-session-main small{opacity:.55;font-size:12px}.nc-err{color:#f88;font-size:13px;padding:4px 2px}.nc-empty{opacity:.5;padding:18px 4px;font-size:13px}.nc-home-foot{margin-top:auto;padding:14px 4px 4px;width:100%;box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;column-gap:14px;font-size:11px}.nc-home-meta{min-width:0;display:flex;flex-wrap:wrap;align-items:center;gap:2px 8px;opacity:.48;line-height:1.35}.nc-home-version{flex:0 0 auto}.nc-home-endpoint{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-group{display:flex;flex-direction:column;gap:8px}.nc-group-title{font-size:11px;opacity:.55;text-transform:uppercase;letter-spacing:.5px;padding:6px 2px 2px}.nc-mcard{display:flex;align-items:center;gap:12px;padding:12px 14px;border:1px solid #1c241c;background:#0e140e;color:#cfe;border-radius:12px;min-height:56px}.nc-mcard-main{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:12px;background:none;border:none;color:inherit;cursor:pointer;padding:0;text-align:left}.nc-mcard-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.nc-mcard-text b{font-size:14px;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-mcard-nome{display:flex;align-items:center;gap:6px;min-width:0}.nc-mcard-nome b{min-width:0}.nc-mcard-text small{font-size:13px;opacity:.78;line-height:1.3;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}.dot.warn{background:#e0b020;box-shadow:0 0 6px #e0b02088}.nc-group-title.nc-node-title{display:flex;align-items:center;gap:6px}.nc-group-title.nc-node-title .dot{flex:0 0 auto;width:8px;height:8px;border-radius:50%;background:#355}.nc-group-title.nc-node-title .dot.on{background:#0c6;box-shadow:0 0 6px #0c68}.nc-mcard .dot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:#355}.nc-mcard .dot.on{background:#0c6;box-shadow:0 0 6px #0c68}.nc-mobile-position-head{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:8px;min-height:48px;padding:2px 0;border-bottom:1px solid #1c2b20}.nc-mobile-position-toggle{min-width:0;min-height:44px;padding:4px 2px;display:flex;align-items:center;gap:8px;border:0;background:none;color:inherit;text-align:left;cursor:pointer}.nc-mobile-position-toggle .dot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:#355}.nc-mobile-position-toggle .dot.on{background:#0c6;box-shadow:0 0 6px #0c68}.nc-mobile-chevron{flex:0 0 14px;font-size:18px;color:#8fc;text-align:center}.nc-mobile-position-copy{min-width:0;display:flex;flex-direction:column;gap:1px}.nc-mobile-position-copy b,.nc-mobile-position-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-mobile-position-copy b{font-size:13px;color:#d8ffe8}.nc-mobile-position-copy small{font-size:11px;opacity:.55}.nc-mobile-position-filter{min-height:44px;max-width:104px;padding:0 26px 0 9px;border:1px solid #294433;border-radius:8px;background:#0e140e;color:#bfe8cf;font:12px/1 inherit}.nc-mobile-position-head>.nc-act{width:44px;height:44px}.nc-node-actions{display:inline-flex;align-items:center;gap:2px}.nc-node-actions .nc-roster-handle,.nc-node-actions .nc-node-rename{width:44px;min-width:44px;height:44px;padding:0;display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:8px;background:transparent;color:#8fc;touch-action:none}.nc-node-actions .nc-node-rename{font-size:18px;cursor:pointer}.nc-node-actions .nc-node-rename:focus-visible,.nc-node-actions .nc-node-rename:active{outline:1px solid #2e7d32;background:#00cc661a}.nc-node-order-wrap.nc-roster-over{outline:2px solid rgba(0,204,102,.72);outline-offset:2px;border-radius:10px}.nc-rel{flex:0 0 auto;font-size:11px;opacity:.45}.nc-power,.nc-menu{flex:0 0 auto;background:none;border:1px solid #243;color:#9fd;border-radius:8px;min-width:44px;min-height:44px;font-size:17px;cursor:pointer}.nc-power:active,.nc-menu:active{border-color:#2e7d32}.nc-lang{display:inline-flex;align-items:center;justify-content:flex-end;gap:2px;white-space:nowrap;opacity:.7}@media(max-width:380px){.nc-home-meta{flex-direction:column;align-items:flex-start;gap:0}.nc-home-endpoint{max-width:100%}}.nc-act{width:44px;height:44px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:#ffffff0d;border:1px solid rgba(255,255,255,.22);color:#9aa89a;cursor:pointer;flex:0 0 auto;font-size:15px;line-height:1}.nc-act.power.on{color:#0c6;border-color:#00cc668c;background:#00cc661a}.nc-act.power.warn{color:#e8c547;border-color:#e8c5478c;background:#e8c5471a}.nc-fleet-stale{color:#e8c547}.nc-fleet-off{color:#b0b8ad}.nc-act.pin.on{color:#e8c547;border-color:#e8c5478c;background:#e8c54714}.nc-act.pin.designated{color:#c8a6ff;border-color:#c8a6ff99;background:#c8a6ff1f}.nc-act.pin.thread-present{color:#69b7ff;border-color:#69b7ff99;background:#69b7ff1f}.nc-act.pin.thread-active{color:#ff5a5a;border-color:#ff5a5a99;background:#ff5a5a1f}.nc-act.pin.thread-unknown{color:#e0b020;border-color:#e0b02099;background:#e0b0201f}.nc-act.technical.on{color:#d8a8ff;border-color:#b478ff8c;background:#b478ff1a}.nc-mcard{gap:8px}.nc-mcard .nc-roster-handle{flex:0 0 36px;width:36px;min-width:36px;height:44px;border:1px solid transparent;border-radius:9px;background:#ffffff06;color:#688475;touch-action:none}.nc-mcard .nc-roster-handle.active,.nc-mcard .nc-roster-handle:focus-visible{color:#bfffd8;border-color:#00cc6673;background:#00cc661f}.nc-mcard.nc-roster-dragging{opacity:.62}.nc-mcard.nc-roster-over{outline:2px solid rgba(0,204,102,.72);outline-offset:2px}@media(max-width:390px){.nc-mobile-position-head{gap:5px}.nc-mobile-position-filter{max-width:92px;padding-left:7px}.nc-mcard{padding:10px 9px;gap:5px}}.nc-m-live{flex:0 0 auto;padding:0 6px;border-radius:6px;font-size:10px;font-weight:700;letter-spacing:.5px;line-height:16px;color:#0c6;background:#00cc661f;border:1px solid rgba(0,204,102,.45)}.nc-act.cellmenu{font-size:18px;line-height:1}.nc-act.cellmenu.on{color:#bfffd8;border-color:#00cc668c;background:#00cc661f}.nc-m-live-strip{display:flex;align-items:center;gap:8px;min-height:36px;padding:6px 10px;border:1px solid #1c2b20;border-radius:10px;background:#0b120b;overflow:hidden}.nc-m-live-dot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:#355}.nc-m-live-dot.active,.nc-m-live-dot.designated,.nc-m-live-dot.present{background:#0c6;box-shadow:0 0 6px #0c68}.nc-m-live-dot.unknown{background:#e0b020;box-shadow:0 0 6px #e0b02088}.nc-m-live-testo{flex:0 1 auto;min-width:0;font-size:13px;font-weight:700;letter-spacing:.3px;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-m-live-notice{flex:1 1 auto;min-width:0;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-m-live-notice.ok{color:#0c6}.nc-m-live-notice.ko{color:#e0b020}.nc-refresh.on{color:#bfffd8;border-color:#00cc668c;background:#00cc661f}.nc-notice{color:#8c8;font-size:13px;padding:4px 2px}.nc-keybar{background:#0a0e0a;border-top:1px solid #1c241c;position:relative}.nc-keybar.termux{padding:2px 0}.nc-keygrid{display:grid;grid-template-columns:minmax(0,8fr) minmax(40px,1fr)}.nc-keygrid.no-enter{grid-template-columns:minmax(0,1fr)}.nc-keygrid.expanded{grid-template-columns:minmax(40px,1fr) minmax(0,8fr) minmax(40px,1fr)}.nc-keygrid.expanded.no-enter{grid-template-columns:minmax(40px,1fr) minmax(0,1fr)}.nc-keygrid.compact{grid-template-columns:minmax(0,8fr) minmax(40px,1fr)}.nc-keygrid.compact.no-enter{grid-template-columns:minmax(0,1fr)}.nc-keygrid.compact .row button{padding-inline:0;overflow:hidden;white-space:nowrap;font-size:clamp(10px,3vw,12px);letter-spacing:0}.nc-keygrid.compact .row button:nth-last-child(-n+2){font-size:10px}.nc-keyrows{display:flex;flex-direction:column;min-width:0}.nc-keybar .row{display:flex}.nc-keybar .row button,.nc-keybar .nc-enter-key,.nc-keybar .nc-retract-key{flex:1 1 0;min-width:0;padding:10px 2px;background:none;border:none;border-radius:0;color:#e6ffe6;font-size:14px;font-weight:600;letter-spacing:.5px;font-family:inherit}.nc-keybar .nc-enter-key{display:inline-flex;align-items:center;justify-content:center;border-left:1px solid #1c241c}.nc-keybar .nc-retract-key{display:inline-flex;align-items:center;justify-content:center;border-right:1px solid #1c241c}.nc-keybar .row button:active,.nc-keybar .nc-enter-key:active,.nc-keybar .nc-retract-key:active{background:#1d2a1d}.nc-keybar .row button.armed{color:#021;background:#0c6}.nc-keymenu{position:absolute;bottom:100%;left:8px;right:8px;z-index:30;display:flex;flex-wrap:wrap;gap:6px;padding:8px;background:#101810;border:1px solid #2a3a2a;border-radius:10px 10px 0 0}.nc-keymenu button{flex:1 0 30%;padding:10px 6px;border-radius:8px;border:1px solid #243;background:#122;color:#9fd;font-size:13px}.nc-keymenu button:active{background:#0c6;color:#021}.nc-keybar.copy{display:flex;gap:6px;overflow-x:auto;padding:8px;background:#14210f}.nc-keybar.copy button{flex:0 0 auto;padding:10px 12px;min-width:48px;border-radius:8px;border:1px solid #243;background:#122;color:#9fd;font-size:13px}.nc-keybar.copy button:active{background:#0c6;color:#021}.nc-keybar .tag{flex:0 0 auto;align-self:center;padding:0 8px;color:#8e8;font-size:12px}@media(pointer:coarse){.nc-keybar .row button,.nc-keybar .nc-enter-key,.nc-keybar .nc-retract-key{padding:12px 2px;font-size:15px}.nc-keygrid.compact .row button{padding-inline:0;font-size:clamp(10px,3vw,12px);letter-spacing:0}.nc-keygrid.compact .row button:nth-last-child(-n+2){font-size:10px}}.nc-filesheet-velo{position:fixed;top:0;right:0;bottom:0;left:0;z-index:70;display:flex;align-items:flex-end;background:#00000080}.nc-filesheet{width:100%;max-height:80vh;overflow:auto;background:#0e140e;border-top:1px solid #1c241c;border-radius:14px 14px 0 0;padding:8px 8px calc(8px + env(safe-area-inset-bottom,0px));display:flex;flex-direction:column;gap:8px}.nc-filesheet-testa{display:flex;align-items:center;gap:8px;padding:6px 8px}.nc-filesheet-titolo{flex:1;min-width:0;font-size:13px;font-weight:700;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-filesheet-chiudi{flex:0 0 auto;width:44px;height:44px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:#ffffff0d;border:1px solid rgba(255,255,255,.22);border-radius:50%;color:#9aa89a;cursor:pointer}.nc-filesheet-file{display:flex;flex-direction:column;gap:6px;padding:8px 10px;background:#ffffff08;border:1px solid #1c241c;border-radius:10px}.nc-filesheet-nome{color:#d8ffe8;font-size:15px;font-weight:600;overflow-wrap:anywhere}.nc-filesheet-originale{display:flex;flex-direction:column;gap:2px;min-width:0}.nc-filesheet-label{font-size:11px;color:#7fb89a}.nc-filesheet-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;color:#b8e6c8;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}.nc-filesheet-meta{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;color:#7fb89a;overflow-wrap:anywhere}.nc-filesheet-notice{padding:8px 10px;font-size:12px;color:#e0a030;border:1px solid #4a3a1a;border-radius:8px}.nc-filesheet-azioni{display:flex;flex-direction:column;gap:2px;padding:4px}.nc-filesheet-azioni button{display:flex;align-items:center;gap:10px;min-height:44px;padding:10px 12px;border:none;border-radius:8px;background:none;color:#d8ffe8;font-size:14px;text-align:left;cursor:pointer}.nc-filesheet-azioni button:hover{background:#ffffff12}.nc-filesheet-azioni button:disabled{opacity:.55;cursor:wait}.nc-filesheet-azioni button.danger{color:#ff8a80}.nc-filesheet-conferma{display:flex;flex-direction:column;gap:8px;padding:12px 10px;border:1px solid #4a2a2a;border-radius:10px;background:#ff8a800d}.nc-filesheet-conferma-titolo{color:#ffd6d1;font-size:14px;overflow-wrap:anywhere}.nc-filesheet-conferma-aiuto{color:#9aa89a;font-size:12px}.nc-filesheet-conferma-azioni{display:flex;gap:8px}.nc-filesheet-conferma-azioni button{flex:1;min-height:44px;padding:10px 12px;border-radius:8px;border:1px solid #243;background:none;color:#9fd;font-size:14px;cursor:pointer}.nc-filesheet-conferma-azioni button.danger{border-color:#6d3a34;background:#3a1d19;color:#ff8a80;font-weight:600}.nc-filesheet-conferma-azioni button:disabled{opacity:.55;cursor:wait}.nc-files.nc-files-d{width:min(940px,94vw)}.nc-filesd-head{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid #243}.nc-filesd-titolo{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}.nc-filesd-titolo b{color:#d8ffe8;font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-filesd-percorso{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;color:#7fb89a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-filesd-upload{flex:0 0 auto;min-height:36px;padding:0 12px;display:inline-flex;align-items:center;gap:6px;border:1px solid #2e7d32;border-radius:8px;background:#1a241a;color:#7ee787;font-size:13px;cursor:pointer}.nc-filesd-upload:hover{background:#223022}.nc-filesd-upload-input{display:none}.nc-filesd-head .nc-ntf-x{min-width:44px;min-height:44px}.nc-filesd-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:8px 14px;border-bottom:1px solid #1c231c}.nc-filesd-seg{display:inline-flex;border:1px solid #243;border-radius:8px;overflow:hidden}.nc-filesd-seg button{min-height:36px;padding:0 14px;background:none;border:none;border-right:1px solid #243;color:#9fd;font-size:13px;cursor:pointer}.nc-filesd-seg button:last-child{border-right:none}.nc-filesd-seg button.on{background:#1a241a;color:#7ee787}.nc-filesd-search{flex:1 1 220px;max-width:420px;display:flex;align-items:center;gap:8px;padding:0 10px;border:1px solid #243;border-radius:8px;color:#7fb89a}.nc-filesd-search input{flex:1;min-width:0;min-height:36px;background:none;border:none;outline:none;color:#d8ffe8;font-size:13px}.nc-filesd-search input::placeholder{color:#7fb89a}.nc-filesd-search input::-webkit-search-cancel-button{filter:invert(.8)}.nc-filesd-kbd{flex:0 0 auto;padding:1px 6px;border:1px solid #243;border-radius:4px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;color:#7fb89a}.nc-filesd-search:focus-within .nc-filesd-kbd{display:none}.nc-filesd-filtri{display:inline-flex;gap:6px;margin-left:auto}.nc-filesd-filtri button{min-height:36px;padding:0 12px;border:1px solid #243;border-radius:999px;background:none;color:#9fd;font-size:12px;cursor:pointer}.nc-filesd-filtri button.on{border-color:#2e7d32;background:#1a241a;color:#7ee787}.nc-filesd-main{flex:1 1 auto;min-height:0;display:flex}.nc-filesd-list{flex:1 1 auto;min-width:0;overflow-y:auto}.nc-filesd-daygroup{display:flex;flex-direction:column}.nc-files-d .nc-files-day{padding:8px 14px 6px}.nc-files-d .nc-files-empty{padding:24px 14px}.nc-filesd-row{display:grid;grid-template-columns:40px minmax(0,1fr) auto auto 44px 44px;gap:10px;align-items:center;min-height:44px;padding:6px 14px;border-bottom:1px solid #1c231c;border-left:3px solid transparent;cursor:pointer}.nc-filesd-row:hover{background:#0e140e}.nc-filesd-row.sel{background:#14231a;border-left-color:#7ee787}.nc-filesd-name{color:#d8ffe8;font-size:13px;line-height:1.3;-webkit-user-select:text;user-select:text;overflow-wrap:anywhere}.nc-filesd-quando,.nc-filesd-dim{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;color:#7fb89a;white-space:nowrap}.nc-filesd-cella{display:inline-flex;justify-content:center}.nc-filesd-row .nc-filesd-dl,.nc-filesd-row .nc-filesd-more{min-width:36px;min-height:36px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:none;border:1px solid #243;border-radius:8px;color:#9fd;cursor:pointer}.nc-filesd-row .nc-filesd-dl:hover,.nc-filesd-row .nc-filesd-more:hover{border-color:#2e7d32;color:#7ee787}.nc-filesd-detail{flex:0 0 340px;width:340px;border-left:1px solid #243;overflow-y:auto;padding:14px;display:flex;flex-direction:column;gap:10px}.nc-filesd-detail-none{margin:auto;padding:24px 10px;text-align:center;color:#7fb89a;font-size:13px}.nc-filesd-prev-text{margin:0;padding:10px;border:1px solid #1c231c;border-radius:8px;background:#0e140e;color:#d8ffe8;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.45;max-height:280px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}.nc-filesd-prev-img{display:block;max-width:100%;max-height:280px;object-fit:contain;border:1px solid #1c231c;border-radius:8px;background:#0e140e}.nc-filesd-nome{color:#d8ffe8;font-size:15px;font-weight:600;overflow-wrap:anywhere}.nc-filesd-originale{display:flex;flex-direction:column;gap:2px;min-width:0}.nc-filesd-label{font-size:11px;color:#7fb89a}.nc-filesd-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;color:#b8e6c8;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}.nc-filesd-meta{margin:0;display:flex;flex-direction:column;gap:6px}.nc-filesd-meta>div{display:grid;grid-template-columns:110px minmax(0,1fr);gap:8px}.nc-filesd-meta dt{color:#7fb89a;font-size:12px}.nc-filesd-meta dd{margin:0;color:#d8ffe8;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere}.nc-filesd-azioni{display:flex;flex-direction:column;gap:8px}.nc-filesd-azioni button{display:flex;align-items:center;gap:8px;min-height:40px;padding:0 12px;border:1px solid #243;border-radius:8px;background:none;color:#9fd;font-size:13px;text-align:left;cursor:pointer}.nc-filesd-azioni button.primario{background:#2e7d32;border-color:#2e7d32;color:#d8ffe8;font-weight:600}.nc-filesd-azioni button:hover{border-color:#2e7d32}.nc-filesd-azioni button.primario:hover{background:#35913b;color:#fff}.nc-filesd-azioni button.danger{color:#ff8a80}.nc-filesd-conferma{display:flex;flex-direction:column;gap:8px;padding:12px 10px;border:1px solid #4a2a2a;border-radius:10px;background:#ff8a800d}.nc-filesd-conferma-titolo{color:#ffd6d1;font-size:14px;overflow-wrap:anywhere}.nc-filesd-conferma-aiuto{color:#9aa89a;font-size:12px}.nc-filesd-conferma-azioni{display:flex;gap:8px}.nc-filesd-conferma-azioni button{flex:1;min-height:44px;padding:10px 12px;border:1px solid #243;border-radius:8px;background:none;color:#9fd;font-size:14px;cursor:pointer}.nc-filesd-conferma-azioni button.danger{border-color:#6d3a34;background:#3a1d19;color:#ff8a80;font-weight:600}.nc-filesd-conferma-azioni button:disabled{opacity:.55;cursor:wait}.nc-filesd-foot{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:6px 14px;border-top:1px solid #1c231c;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;color:#7fb89a}.nc-filesd-tasti kbd{margin-left:4px;padding:0 5px;border:1px solid #243;border-radius:4px;font-family:inherit;font-size:10px;color:#9fd}.nc-files-d button:focus-visible,.nc-files-d .nc-filesd-row:focus-visible{outline:1px solid #7ee787;outline-offset:1px}.nc-files{position:fixed;top:0;right:0;bottom:0;width:min(340px,90vw);background:#0a0e0a;border-left:1px solid #2e7d32;color:#d8ffe8;display:flex;flex-direction:column;z-index:30}@media(max-width:560px){.nc-files{width:100%;border-left:none}}.nc-files header{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid #243}.nc-files header b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-files nav{display:flex;gap:6px;padding:8px 10px;border-bottom:1px solid #1c231c}.nc-files nav button{flex:0 0 auto;padding:4px 10px;border-radius:6px;background:none;border:1px solid #243;color:#9fd;cursor:pointer}.nc-files nav button.on{background:#1a241a;border-color:#2e7d32;color:#7ee787}.nc-files-search{display:flex;align-items:center;gap:8px;margin:8px 10px;padding:0 10px;border:1px solid #243;border-radius:8px;color:#7fb89a}.nc-files-search input{flex:1;min-width:0;min-height:44px;background:none;border:none;outline:none;color:#d8ffe8;font-size:14px}.nc-files-search input::placeholder{color:#7fb89a}.nc-files-search input::-webkit-search-cancel-button{filter:invert(.8)}.nc-files-list{flex:1;min-height:0;overflow-y:auto}.nc-files-daygroup{display:flex;flex-direction:column}.nc-files-day{position:sticky;top:0;z-index:1;margin:0;padding:8px 10px 6px;font-size:11px;font-weight:700;letter-spacing:.04em;color:#7fb89a;text-transform:uppercase;background:#0a0e0a;border-bottom:1px solid #1c231c}.nc-files ul{list-style:none;margin:0;padding:0}.nc-files li{display:flex;align-items:center;gap:10px;padding:8px 10px;border-bottom:1px solid #1c231c}.nc-files-type{flex:0 0 40px;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;border:1px solid #243;border-radius:8px;background:#101810;color:#7ee787;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:10px;font-weight:700;letter-spacing:.02em}.nc-files-info{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}.nc-files li .nc-files-name{color:#d8ffe8;font-size:14px;line-height:1.25;-webkit-user-select:text;user-select:text;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-clamp:2;overflow:hidden;overflow-wrap:anywhere}.nc-files li .nc-files-meta{color:#7fb89a;font-size:11px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nc-files li button{flex:0 0 auto;background:none;border:1px solid #243;border-radius:8px;color:#9fd;cursor:pointer}.nc-files-empty{padding:24px 10px;text-align:center;opacity:.55}.nc-busy{padding:4px 10px;font-size:12px;color:#e0a030}.nc-files header button{min-height:44px;min-width:44px}.nc-files nav button{min-height:44px}.nc-files li button{min-height:44px;min-width:44px}.nc-files header button,.nc-files nav button,.nc-files li button{display:inline-flex;align-items:center;justify-content:center;gap:6px}.nc-files-dup{display:inline-block;margin-left:6px;padding:0 5px;border:1px solid rgba(46,160,67,.4);border-radius:8px;color:#7fb89a;font-size:10px;line-height:14px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:nowrap;vertical-align:1px;-webkit-user-select:none;user-select:none}.nc-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}.nc-composer{border-top:1px solid #2a332a;padding:6px max(8px,env(safe-area-inset-right)) max(6px,env(safe-area-inset-bottom)) max(8px,env(safe-area-inset-left));background:var(--bg, #111511)}.nc-composer-row{display:flex;gap:6px;align-items:flex-end}.nc-composer textarea{flex:1;min-width:0;min-height:42px;max-height:42vh;max-height:42dvh;resize:vertical;overflow-y:auto;background:#0a0e0a;color:#d8e0d8;border:1px solid #2a332a;border-radius:8px;padding:6px 8px;font:13px/1.4 inherit}.nc-composer textarea.expanded{height:clamp(128px,32dvh,320px)}.nc-composer .mic.on{background:#b02a2a;color:#fff}.nc-composer-err{font-size:12px;color:#e0a030;padding-bottom:4px}.nc-composer-info{font-size:12px;color:#baff79;padding-bottom:4px}@media(pointer:coarse){.nc-composer .mic,.nc-composer .go,.nc-composer .attach,.nc-composer .history{min-width:46px;min-height:46px;font-size:20px}.nc-composer textarea{resize:none;font-size:16px}.nc-attach-menu button,.nc-composer-history-menu button{min-height:48px}}.nc-composer .mic,.nc-composer .go,.nc-composer .attach,.nc-composer .history{display:inline-flex;align-items:center;justify-content:center;background:none;border:1px solid #243;color:#9fd;border-radius:8px;cursor:pointer}.nc-composer .go{color:#7ee787;border-color:#2e7d32}.nc-composer .go:disabled{opacity:.5;cursor:wait}.nc-composer .attach.busy{opacity:.5;animation:nc-attach-pulse 1s ease-in-out infinite}@keyframes nc-attach-pulse{50%{opacity:.9}}.nc-attach-menu{position:fixed;z-index:1000;min-width:180px;display:flex;flex-direction:column;padding:4px;background:#0e130e;border:1px solid #2e7d32;border-radius:10px;box-shadow:0 6px 24px #0000008c}.nc-attach-menu button{display:flex;align-items:center;gap:10px;text-align:left;min-height:40px;padding:8px 12px;border:0;border-radius:7px;background:none;color:#d8e0d8;font:14px/1 inherit;cursor:pointer}.nc-attach-menu button:hover,.nc-attach-menu button:focus-visible{background:#1a241a;color:#7ee787}.nc-composer-history-menu{position:fixed;z-index:1000;max-height:min(55dvh,420px);overflow-y:auto;display:flex;flex-direction:column;padding:4px;background:#0e130e;border:1px solid #2e7d32;border-radius:10px;box-shadow:0 6px 24px #0000008c}.nc-composer-history-menu button{border:0;border-radius:7px;background:none;color:#d8e0d8;font:13px/1.35 inherit;cursor:pointer}.nc-composer-history-menu button:hover,.nc-composer-history-menu button:focus-visible{background:#1a241a;color:#7ee787}.nc-composer-history-action{display:flex;align-items:center;gap:8px;min-height:38px;padding:7px 10px;text-align:left;border-bottom:1px solid #243!important;border-radius:7px 7px 0 0!important}.nc-composer-history-title{padding:8px 10px 5px;color:#7fb89a;font-size:11px;text-transform:uppercase;letter-spacing:.08em}.nc-composer-history-empty{padding:10px;color:#789a87;font-size:12px}.nc-composer-history-entry{display:flex;flex-direction:column;gap:2px;width:100%;padding:8px 10px;text-align:left}.nc-composer-history-entry span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-composer-history-entry small{color:#789a87;font-size:10px}.nc-composer-history-clear{min-height:36px;margin-top:3px;padding:7px 10px;color:#f99!important;text-align:left}@media(max-width:420px)and (pointer:coarse){.nc-composer-row{gap:4px}.nc-composer .mic,.nc-composer .go,.nc-composer .attach,.nc-composer .history{min-width:42px;width:42px}}.nc-peekcloud{position:fixed;z-index:56;display:flex;flex-direction:column;max-height:70vh;background:#0e140e;border:1px solid #1c241c;border-radius:12px;box-shadow:0 10px 28px #0009;padding:6px 8px 8px;gap:4px}.nc-peekcloud-testa{display:flex;align-items:baseline;gap:8px;min-width:0}.nc-peekcloud-nome{flex:0 1 auto;font-size:13px;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-peekcloud-sub{flex:1 1 auto;min-width:0;font-size:11px;opacity:.7;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-peekcloud-espandi{flex:0 0 auto;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:#ffffff0d;border:1px solid rgba(255,255,255,.22);border-radius:50%;color:#9aa89a;font-size:12px;cursor:pointer;align-self:center}.nc-peekcloud-espandi:hover{filter:brightness(1.25)}.nc-peekcloud .nc-peek-stream{height:240px}.nc-sidebar{display:flex;flex-direction:column;gap:8px;padding:12px 10px;color:#cfe;min-height:0;position:relative;overflow:hidden;box-sizing:border-box;border-right:1px solid #1c241c;background:#0a0e0a}.nc-sidebar.mini{padding:12px 4px;align-items:center;gap:6px}.nc-side-resize{position:absolute;top:0;right:0;bottom:0;width:6px;cursor:col-resize;z-index:5}.nc-side-resize:hover{background:#1c3a1c}.nc-collapse-btn{flex:0 0 auto;background:none;border:1px solid #243;color:#9fd;border-radius:8px;min-width:26px;min-height:26px;cursor:pointer;font-size:13px;line-height:1}.nc-collapse-btn:hover{border-color:#2e7d32;color:#d8ffe8}.nc-side-head{display:flex;align-items:center;gap:6px;justify-content:space-between;padding:2px 4px 6px}.nc-side-head.mini{padding:2px 0 6px;justify-content:center}.nc-side-scroll{min-height:0;flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:8px;padding-right:2px}.nc-side-scroll.mini{width:100%;align-items:center}.nc-side-group.mini{align-items:center;gap:6px}.nc-mini-dot,.nc-mini-init{display:flex;align-items:center;justify-content:center;width:34px;height:34px;box-sizing:border-box;border:1px solid #1c241c;background:#0e140e;border-radius:9px;cursor:pointer;-webkit-user-select:none;user-select:none;color:#d8ffe8;padding:0}.nc-mini-init{font-size:13px;font-weight:700}.nc-mini-dot:hover,.nc-mini-init:hover{border-color:#244}.nc-mini-dot.active,.nc-mini-init.active{border-color:#2e7d32;background:#14200f}.nc-side-title{font-size:13px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;opacity:.8}.nc-side-fleet-stale{color:#e0b020;font-size:12px;cursor:help}.nc-side-fleet-off{color:#8fa08f;font-size:12px;cursor:help}.nc-new-btn{background:#2e7d32;color:#fff;border:none;border-radius:8px;padding:4px 10px;font-size:12px;cursor:pointer}.nc-new-btn:active{background:#255028}.nc-side-group{display:flex;flex-direction:column;gap:6px}.nc-side-group-title{font-size:11px;opacity:.55;text-transform:uppercase;letter-spacing:.5px;padding:10px 4px 2px}.nc-node-title{display:flex;align-items:center;gap:6px;opacity:.8}.nc-node-title[role=button]{cursor:pointer;border-radius:6px}.nc-node-title[role=button]:focus-visible{outline:1px solid #2e7d32}.nc-node-title .nc-dot{width:7px;height:7px;flex:0 0 auto}.nc-node-title b{font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.nc-node-title small{text-transform:none;letter-spacing:0;opacity:.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-node-title .nc-node-main{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:1px}.nc-node-title .nc-node-main b{flex:0 0 auto;max-width:100%}.nc-node-title .nc-node-main small{min-width:0}.nc-node-chevron{flex:0 0 10px;font-size:13px}.nc-node-filter{flex:0 0 76px;width:76px;margin-left:auto;padding:3px 18px 3px 5px;border:1px solid #243;border-radius:6px;background:#0a0e0a;color:#9fd;font:10px/1.2 inherit;text-transform:lowercase}.nc-node-title>.nc-roster-handle{flex-basis:20px;width:20px;min-width:20px;height:24px}.nc-node-rename{flex:0 0 auto;width:26px;height:26px;padding:0;border:1px solid transparent;border-radius:6px;background:transparent;color:#7fa892;cursor:pointer;font:15px/1 inherit}.nc-node-rename:hover,.nc-node-rename:focus-visible{color:#caffe0;border-color:#00cc6659;outline:none}.nc-node-order-wrap.nc-roster-dragging{opacity:.62}.nc-node-order-wrap.nc-roster-over{outline:2px solid rgba(0,204,102,.72);outline-offset:2px;border-radius:8px}.nc-cell{display:flex;align-items:center;gap:8px;padding:9px 10px;border:1px solid #1c241c;background:#0e140e;border-radius:10px;overflow:hidden}.nc-cell-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.nc-cell-main b{font-size:13px;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.nc-cell-main small{font-size:12px;opacity:.75;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.nc-power,.nc-boot{flex:0 0 auto;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:#ffffff0d;border:1px solid rgba(255,255,255,.22);color:#9aa89a;border-radius:50%;cursor:pointer}.nc-power.on{color:#0c6;border-color:#00cc668c;background:#00cc661a}.nc-boot.on{color:#69b7ff;border-color:#69b7ff94;background:#69b7ff1a}.nc-power.warn{color:#e8c547;border-color:#e8c5478c;background:#e8c5471a}.nc-power:hover,.nc-boot:hover{filter:brightness(1.25)}.nc-boot:disabled{cursor:wait;opacity:.55}.nc-dot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:#355}.nc-dot.on{background:#0c6;box-shadow:0 0 6px #0c68}.nc-dot.warn{background:#e0b020;box-shadow:0 0 6px #e0b02088}.nc-side-card{display:flex;align-items:center;gap:8px;padding:9px 10px;border:1px solid #1c241c;background:#0e140e;border-radius:10px;cursor:grab;-webkit-user-select:none;user-select:none}.nc-side-card:hover{border-color:#244}.nc-side-card.active{border-color:#2e7d32;background:#14200f}.nc-side-card:active{cursor:grabbing}.nc-card-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.nc-card-main b{font-size:13px;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-card-main small{font-size:11px;opacity:.55;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-rel{flex:0 0 auto;font-size:11px;opacity:.7}.nc-badge{flex:0 0 auto;background:#2e7d32;color:#fff;border-radius:10px;padding:1px 8px;font-size:12px;line-height:18px}.nc-menu{flex:0 0 auto;width:26px;height:26px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:none;border:none;color:#9fd;cursor:pointer;font-size:15px;line-height:1;border-radius:50%}.nc-menu:active{color:#f88}.nc-empty{opacity:.4;padding:8px 4px;font-size:12px}.nc-side-gear{display:flex;align-items:center;gap:8px;background:none;border:1px solid #1c241c;border-radius:10px;color:#9fd;font-size:12px;padding:7px 10px;cursor:pointer;margin-top:0;flex:0 0 auto}.nc-side-gear:hover{border-color:#2e7d32;color:#d8ffe8}.nc-side-gear.mini{justify-content:center;width:34px;height:34px;box-sizing:border-box;padding:0;border-radius:9px;margin:6px auto 0}.nc-side-lang{flex:0 0 auto;padding:4px;display:flex;align-items:center;gap:2px;font-size:11px;opacity:.6}.nc-lang-btn{background:none;border:none;color:inherit;cursor:pointer;font-size:11px;padding:0 1px;opacity:.5;text-transform:uppercase}.nc-lang-btn.on{opacity:1;font-weight:700;color:#d8ffe8}.nc-cell.live{cursor:pointer}.nc-cell.live:hover{background:#ffffff0f}.nc-cell.active{outline:1px solid rgba(0,204,102,.5)}.nc-cell.preserved{opacity:.55;border-style:dashed;cursor:default}.nc-cell.preserved .nc-cell-main b{color:#8fa08f}.nc-cell.preserved .nc-cell-main small{font-style:italic}.nc-side-presets{display:flex;gap:4px;padding:2px 8px 6px}.nc-side-presets button{background:none;border:1px solid rgba(255,255,255,.15);border-radius:4px;color:inherit;cursor:pointer;padding:2px 8px}.nc-side-presets button:hover{background:#ffffff14}.nc-pin{flex:0 0 auto;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:#ffffff0d;border:1px solid rgba(255,255,255,.22);color:#9aa89a;cursor:pointer;border-radius:50%;font-size:14px;line-height:1}.nc-pin:hover{filter:brightness(1.25)}.nc-pin.on{color:#e8c547;border-color:#e8c5478c;background:#e8c54714}.nc-pin.designated{color:#c8a6ff;border-color:#c8a6ff99;background:#c8a6ff1f}.nc-pin.thread-present{color:#69b7ff;border-color:#69b7ff99;background:#69b7ff1f}.nc-pin.thread-active{color:#ff5a5a;border-color:#ff5a5a99;background:#ff5a5a1f}.nc-pin.thread-unknown{color:#e0b020;border-color:#e0b02099;background:#e0b0201f}.nc-technical{flex:0 0 auto;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:#ffffff0d;border:1px solid rgba(255,255,255,.22);color:#9aa89a;cursor:pointer;border-radius:50%;font:12px/1 monospace}.nc-technical.on{color:#d8a8ff;border-color:#b478ff8c;background:#b478ff1a}.nc-mini-tip{position:fixed;left:56px;transform:translateY(-50%);background:#161b16;color:#e6ffe6;border:1px solid rgba(0,204,102,.4);padding:3px 10px;border-radius:4px;white-space:nowrap;z-index:1000;pointer-events:none;font-size:12px}.nc-roster-handle{flex:0 0 24px;width:24px;min-width:24px;height:32px;display:inline-flex;align-items:center;justify-content:center;padding:0;border:0;border-radius:6px;background:transparent;color:#668875;cursor:grab;font:15px/1 monospace;touch-action:none}.nc-roster-handle:hover,.nc-roster-handle:focus-visible,.nc-roster-handle.active{color:#9fd;background:#00cc661a;outline:none}.nc-roster-handle:active,.nc-roster-handle.active{cursor:grabbing}.nc-side-card.nc-roster-dragging,.nc-cell.nc-roster-dragging{opacity:.62}.nc-side-card.nc-roster-over,.nc-cell.nc-roster-over{outline:2px solid rgba(0,204,102,.72);outline-offset:2px}.nc-cell>.nc-roster-handle{opacity:0;pointer-events:none}.nc-cell:hover>.nc-roster-handle,.nc-cell:focus-within>.nc-roster-handle{opacity:1;pointer-events:auto}.nc-live-bollino{display:inline-block;margin-left:6px;padding:0 5px;border-radius:6px;font-size:9px;font-weight:700;letter-spacing:.5px;line-height:14px;vertical-align:1px;color:#0c6;background:#00cc661f;border:1px solid rgba(0,204,102,.45)}.nc-cellmenu{flex:0 0 auto;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:#ffffff0d;border:1px solid rgba(255,255,255,.22);color:#9aa89a;cursor:pointer;border-radius:50%;font-size:14px;line-height:1}.nc-cellmenu:hover,.nc-cellmenu[aria-expanded=true]{filter:brightness(1.25)}.nc-live-strip{display:flex;align-items:center;gap:7px;min-height:22px;padding:2px 10px;overflow:hidden}.nc-live-strip-dot{flex:0 0 auto;width:8px;height:8px;border-radius:50%;background:#355}.nc-live-strip-dot.active,.nc-live-strip-dot.designated,.nc-live-strip-dot.present{background:#0c6;box-shadow:0 0 6px #0c68}.nc-live-strip-dot.active{animation:nc-live-strip-pulse 1.6s ease-in-out infinite}@keyframes nc-live-strip-pulse{0%,to{box-shadow:0 0 4px #0c68}50%{box-shadow:0 0 9px #0c6c}}.nc-live-strip-dot.unknown{background:#e0b020;box-shadow:0 0 6px #e0b02088}.nc-live-strip-testo{flex:0 1 auto;min-width:0;font-size:11px;font-weight:700;letter-spacing:.3px;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-live-strip-notice{flex:1 1 auto;min-width:0;font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-live-strip-notice.ok{color:#0c6}.nc-live-strip-notice.ko{color:#e0b020}.nc-chat{display:flex;flex-direction:column;min-height:0;height:100%;background:var(--bg-primary);color:var(--text-primary);font-size:12.5px;line-height:1.45}.nc-chat-top{flex:0 0 auto;display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:4px 8px;border-bottom:1px solid var(--border);background:var(--bg-secondary)}.nc-chat-state{font:11px/1.2 var(--font-mono, monospace);color:var(--text-secondary);padding:2px 7px;border:1px solid var(--border);border-radius:9px}.nc-chat-state[data-state=awaiting_approval]{color:var(--warning);border-color:var(--warning)}.nc-chat-state[data-state=unknown],.nc-chat-state[data-state=error]{color:var(--error);border-color:var(--error)}.nc-chat-state[data-state=done]{color:var(--success);border-color:var(--success)}.nc-chat-stop{color:var(--text-tertiary)}.nc-chat-demo-notice{flex:0 0 auto;margin:0;padding:3px 10px;font-size:10.5px;color:var(--warning);background:var(--bg-secondary);border-bottom:1px dashed var(--border)}.nc-chat-tools-menu{margin-left:auto;position:relative}.nc-chat-tools-toggle{min-height:32px;min-width:44px;background:none;border:1px solid var(--border);color:var(--text-primary);border-radius:10px;padding:2px 10px;font:11px/1.4 var(--font-mono, monospace);cursor:pointer}.nc-chat-tools-list{position:absolute;right:0;top:calc(100% + 4px);z-index:5;margin:0;padding:4px;list-style:none;min-width:220px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:8px}.nc-chat-tools-list li{display:grid;grid-template-columns:42px 1fr auto auto;gap:6px;padding:2px 4px}.nc-chat-tools-time,.nc-chat-tools-dur{color:var(--text-tertiary);font-family:var(--font-mono, monospace)}.nc-chat-log{flex:1 1 auto;min-height:0;overflow-y:auto;padding:10px 10px 6px;display:flex;flex-direction:column;gap:8px}.nc-chat-msg{max-width:88%;padding:6px 10px;border-radius:11px}.nc-chat-msg p{margin:0;white-space:pre-wrap;overflow-wrap:anywhere}.nc-chat-msg-assistant{align-self:flex-start;background:var(--bg-secondary);border:1px solid var(--border)}.nc-chat-msg-user{align-self:flex-end;background:var(--user-bg);border:1px solid var(--border)}.nc-chat-caret{color:var(--success)}.nc-chat-tool{align-self:stretch;display:flex;align-items:center;gap:8px;padding:5px 8px;border:1px solid var(--border);border-radius:8px;font-family:var(--font-mono, monospace);font-size:11.5px;background:var(--bg-secondary)}.nc-chat-tool[data-state=running]{border-style:dashed}.nc-chat-tool[data-state=error]{border-color:var(--error)}.nc-chat-tool-dot{width:7px;height:7px;border-radius:50%;background:var(--success)}.nc-chat-tool[data-state=running] .nc-chat-tool-dot{background:var(--accent)}.nc-chat-tool[data-state=error] .nc-chat-tool-dot{background:var(--error)}.nc-chat-tool-name{color:var(--accent)}.nc-chat-tool-result{color:var(--text-primary)}.nc-chat-tool-dur{margin-left:auto;color:var(--text-tertiary)}.nc-chat-notice{padding:4px 8px;border:1px dashed var(--border);border-radius:6px;color:var(--text-secondary);font-size:11.5px}.nc-chat-notice-warn{color:var(--warning);border-color:var(--warning)}.nc-chat-conflict ul{margin:4px 0 0;padding-left:16px}.nc-chat-conflict li{font-size:11.5px}.nc-chat-approval{border:1px solid var(--warning);background:var(--bg-secondary);border-radius:9px;padding:8px 10px;display:flex;flex-direction:column;gap:6px}.nc-chat-approval-head{display:flex;gap:8px;align-items:baseline}.nc-chat-approval-title{color:var(--warning);font-weight:600}.nc-chat-approval-status{margin-left:auto;color:var(--text-secondary);font-family:var(--font-mono, monospace);font-size:11px}.nc-chat-approval-command{margin:0;padding:6px 8px;background:var(--bg-primary);border-radius:6px;color:var(--text-primary);font-family:var(--font-mono, monospace);font-size:11.5px;white-space:pre-wrap;overflow-wrap:anywhere}.nc-chat-approval-meta{margin:0;display:flex;flex-wrap:wrap;gap:4px 14px;color:var(--text-secondary);font-size:11px}.nc-chat-approval-meta div{display:flex;gap:4px}.nc-chat-approval-meta dt{color:var(--text-tertiary)}.nc-chat-approval-meta dd,.nc-chat-approval-redacted{margin:0;color:var(--text-secondary)}.nc-chat-approval-actions{display:flex;gap:8px}.nc-chat-btn{min-height:32px;padding:0 10px;border-radius:7px;border:1px solid var(--border);background:transparent;color:var(--text-primary);cursor:pointer}.nc-chat-btn:disabled{opacity:.45;cursor:not-allowed}.nc-chat-btn-primary{background:var(--warning);border-color:var(--warning);color:#1a1408;font-weight:600}.nc-chat-demo-hint{color:var(--text-tertiary)}.nc-chat-statusline{flex:0 0 auto;display:flex;gap:6px;flex-wrap:wrap;padding:3px 10px;color:var(--text-tertiary);font-family:var(--font-mono, monospace);font-size:10.5px;border-top:1px solid var(--border)}.nc-chat-composer{flex:0 0 auto;display:flex;gap:6px;padding:6px 8px 8px;background:var(--bg-secondary)}.nc-chat-pill{flex:1 1 auto;display:flex;align-items:flex-end;gap:2px;border:1px solid var(--border);background:var(--bg-primary);border-radius:18px;padding:2px}.nc-chat-input{flex:1 1 auto;display:flex;min-width:0}.nc-chat-input textarea{flex:1 1 auto;min-width:0;resize:none;border:0;outline:none;background:transparent;color:var(--text-primary);font:inherit;line-height:18px;padding:7px 4px}.nc-chat-icon{width:32px;height:32px;flex:0 0 auto;border:0;border-radius:16px;background:transparent;color:var(--text-secondary);cursor:pointer}.nc-chat-icon:disabled{opacity:.5;cursor:default}.nc-chat-send{width:38px;height:38px;flex:0 0 auto;border:0;border-radius:19px;background:var(--accent);color:#fff;font-size:15px;cursor:pointer}.nc-chat-send:disabled{opacity:.55;cursor:default}.nc-chat-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media(max-width:480px){.nc-chat-icon,.nc-chat-send{width:44px;height:44px}.nc-chat-btn{min-height:44px}.nc-chat-tools-toggle{min-height:44px;min-width:44px;padding:0 12px}.nc-chat-msg{max-width:94%}}.nc-tile{display:flex;flex-direction:column;min-height:0;min-width:0;position:relative;background:#0a0e0a;border:1px solid #1c241c;border-radius:8px;overflow:hidden}.nc-tile.focused{border:2px solid #7ee787;box-shadow:none}.nc-tile.focused .nc-tile-head{background:#173117}.nc-tile.focused .nc-tile-name b{color:#d8ffe8;font-weight:700}.nc-tile-head{flex:0 0 auto;display:flex;align-items:center;gap:6px;padding:3px 6px;background:#0e140e;border-bottom:1px solid #1c241c;height:28px}.nc-tile-name{flex:1 1 auto;min-width:0;display:inline-flex;align-items:center;gap:6px;background:none;border:none;color:#cfe;cursor:pointer;padding:0}.nc-tile-name b{font-size:12px;font-weight:600;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-tile .nc-dot{width:7px;height:7px;flex:0 0 auto}.nc-tile-actions{flex:0 0 auto;display:inline-flex;gap:2px}.nc-tile-actions button{background:none;border:none;color:#9fd;cursor:pointer;min-width:22px;height:22px;font-size:13px;border-radius:4px;padding:0 3px}.nc-tile-actions button:hover{color:#d8ffe8}.nc-tile-actions .nc-tile-close:hover{color:#f88}.nc-tile-body{flex:1 1 auto;position:relative;min-height:0}.nc-tile-body .nc-terminal{width:100%;height:100%}.nc-tile-unavailable{position:absolute;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;padding:20px;color:#789a87;text-align:center;font-size:12px;background:repeating-linear-gradient(135deg,#0a0e0ad1,#0a0e0ad1 12px,#0d130dd1 12px,#0d130dd1 24px)}.nc-tile-stale{position:absolute;top:6px;right:8px;z-index:4;pointer-events:none;padding:1px 6px;border-radius:8px;font-size:10px;letter-spacing:.02em;color:#b8a24e;background:#1e1a0abf;border:1px solid #4a3f1c}.nc-tile-composer{flex:0 0 auto;border-top:1px solid #1c241c}.nc-tile-files{position:absolute;top:0;right:0;bottom:0;left:0;z-index:5;background:#0e140e}.nc-tile-head{cursor:grab}.nc-tile-head:active{cursor:grabbing}.nc-tile-unverified{flex:0 0 auto;padding:2px 8px;font-size:11px;line-height:1.6;color:#d8c07a;background:#30280ce6;border-bottom:1px solid #4a3f1c;text-align:center}.nc-tile-head.nc-float-head,.nc-tile-head.nc-float-head:active{cursor:move}.nc-tile-float-btn{width:26px;height:22px;display:inline-flex;align-items:center;justify-content:center;border:1px solid #2b3c2b;border-radius:5px;background:transparent;color:#9fd}.nc-tile.focused .nc-tile-float-btn{border-color:#2e7d32;color:#bfffd8}.nc-grid{flex:1 1 auto;min-width:0;min-height:0;display:flex;flex-direction:row;padding:6px;gap:0;position:relative;background:#070a07}.nc-col{display:flex;flex-direction:column;min-width:120px;min-height:0;position:relative}.nc-col.drop-newcol:before{content:"";position:absolute;left:-3px;top:0;bottom:0;width:3px;background:#0c6;border-radius:2px;z-index:6}.nc-tile-slot{display:flex;flex-direction:column;min-height:60px;min-width:0;position:relative}.nc-tile-slot>.nc-tile{flex:1 1 auto;min-height:0}.nc-drop-zones{position:absolute;top:0;right:0;bottom:0;left:0;z-index:7;pointer-events:none}.nc-drop-zone{position:absolute;display:flex;align-items:center;justify-content:center;color:#4a6a4a}.nc-drop-zone.left{left:0;top:0;bottom:0;width:22%;border-right:1px dashed #2b3c2b}.nc-drop-zone.right{right:0;top:0;bottom:0;width:22%;border-left:1px dashed #2b3c2b}.nc-drop-zone.top{left:22%;right:22%;top:0;height:30%;border-bottom:1px dashed #2b3c2b}.nc-drop-zone.bottom{left:22%;right:22%;bottom:0;height:30%;border-top:1px dashed #2b3c2b}.nc-drop-zone.center{left:22%;right:22%;top:30%;bottom:30%}.nc-drop-zone.on{background:#00cc6647;border:2px solid #00cc66;border-radius:6px;color:#d8ffe8}.nc-grid-toolbar{position:absolute;top:10px;right:12px;z-index:8;display:flex;gap:4px;background:#0a100ad1;border:1px solid #1c241c;border-radius:8px;padding:3px}.nc-grid-toolbar button{background:none;border:none;color:#9fd;cursor:pointer;font-size:15px;line-height:1;padding:4px 7px;border-radius:6px}.nc-grid-toolbar button:hover{background:#1c3a1c;color:#d8ffe8}.nc-divider-v{flex:0 0 11px;cursor:col-resize;margin:0;border-radius:3px;position:relative;background:#1c3a1c59;display:flex;align-items:center;justify-content:center}.nc-divider-v:before{content:"⋮";color:#4e6b4e;font-size:13px;line-height:1}.nc-divider-v:hover,.nc-divider-v.dragging{background:#1c3a1c}.nc-divider-v.dragging{background:#0c6}.nc-divider-v.dragging:before{color:#052}.nc-divider-h{flex:0 0 11px;cursor:row-resize;margin:0;border-radius:3px;position:relative;background:#1c3a1c59;display:flex;align-items:center;justify-content:center}.nc-divider-h:before{content:"⋯";color:#4e6b4e;font-size:13px;line-height:1}.nc-divider-h:hover,.nc-divider-h.dragging{background:#1c3a1c}.nc-divider-h.dragging{background:#0c6}.nc-divider-h.dragging:before{color:#052}.nc-grid.gesturing .nc-tile{opacity:.55}.nc-gesture-shield{position:absolute;top:0;right:0;bottom:0;left:0;z-index:40;user-select:none;-webkit-user-select:none;cursor:col-resize}.nc-gesture-shield.row{cursor:row-resize}.nc-gesture-guide{position:absolute;z-index:41;pointer-events:none;background:#0c6}.nc-gesture-guide.v{top:0;bottom:0;width:2px;transform:translate(-1px)}.nc-gesture-guide.h{left:0;right:0;height:2px;transform:translateY(-1px)}.nc-gesture-guide.snap{background:none;border:0}.nc-gesture-guide.v.snap{border-left:2px dashed #00cc66;width:0}.nc-gesture-guide.h.snap{border-top:2px dashed #00cc66;height:0}.nc-gesture-badge{position:absolute;z-index:42;pointer-events:none;transform:translate(-50%,-50%);display:flex;gap:6px}.nc-gesture-chip{background:#0a0e0a;border:1px solid #7ee787;border-radius:4px;color:#d8ffe8;font-family:SF Mono,ui-monospace,monospace;font-size:12px;padding:3px 7px;white-space:nowrap}.nc-drag-ghost{position:fixed;z-index:90;pointer-events:none;width:300px;height:190px;display:flex;flex-direction:column;transform:translate(-50%,-20%) rotate(-1.5deg);border:2px solid #7ee787;border-radius:6px;background:#0a0e0ad9;box-shadow:0 12px 30px #0009}.nc-drag-ghost-head{height:28px;box-sizing:border-box;display:flex;align-items:center;gap:8px;padding:0 10px;background:#173117;border-radius:4px 4px 0 0;color:#d8ffe8;font-size:13px}.nc-drag-ghost-body{flex-grow:1;opacity:.7}.nc-tile-slot.nc-tile-source>.nc-tile{opacity:.45;border:1px dashed #4a6a4a}.nc-drop-line-v{flex:0 0 3px;align-self:stretch;background:#0c6;border-radius:2px}.nc-drop-line-end{margin-left:3px}.nc-grid-empty{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;color:#cfe;opacity:.4;font-size:13px;text-align:center;padding:20px}.nc-tile-slot.nc-float{display:flex;flex-direction:column;border:1px solid #243;border-radius:8px;background:#0a0e0a;box-shadow:0 14px 36px #000000a6;overflow:hidden}.nc-tile-slot.nc-float>.nc-tile.focused{border:2px solid #7ee787;border-radius:8px}.nc-tile-slot.nc-float>.nc-tile{flex:1 1 auto;min-height:0}.nc-tile-slot.nc-float-mini .nc-tile-body,.nc-tile-slot.nc-float-mini .nc-float-rz{display:none}.nc-col.nc-col-emptyfloat{flex:0 0 0;min-width:0}.nc-float-rz{position:absolute;z-index:5}.nc-float-rz.n{left:8px;right:8px;top:-3px;height:7px;cursor:ns-resize}.nc-float-rz.s{left:8px;right:8px;bottom:-3px;height:7px;cursor:ns-resize}.nc-float-rz.w{top:8px;bottom:8px;left:-3px;width:7px;cursor:ew-resize}.nc-float-rz.e{top:8px;bottom:8px;right:-3px;width:7px;cursor:ew-resize}.nc-float-rz.se{right:-2px;bottom:-2px;width:16px;height:16px;cursor:nwse-resize;border-right:2px solid #7ee787;border-bottom:2px solid #7ee787;border-radius:0 0 6px}.nc-float-snap{position:fixed;z-index:60;pointer-events:none;opacity:.6}.nc-float-snap.v{top:0;bottom:0;border-left:1px dashed #7ee787}.nc-float-snap.h{left:0;right:0;border-top:1px dashed #7ee787}.nc-gesture-ghost{position:absolute;z-index:40;pointer-events:none;background:#00cc662e}.nc-gesture-ghost.v{top:0;bottom:0;width:2px}.nc-gesture-ghost.h{height:2px}.nc-deckbar{display:flex;align-items:center;gap:8px;flex:0 0 auto;min-width:0;padding:5px 8px;background:#0e140e;border-bottom:1px solid #1c2a1c;overflow-x:auto;white-space:nowrap}.nc-deckbar-label{font-size:10px;text-transform:uppercase;letter-spacing:.06em;opacity:.5;color:#9fd;flex:0 0 auto}.nc-deck-sidebar-toggle{flex:0 0 auto;min-width:28px;height:26px;border:1px solid #243;border-radius:6px;background:#0a0e0a;color:#9fd;cursor:pointer;font:inherit}.nc-deck-sidebar-toggle:hover{border-color:#7aa903}.nc-deck-chips{display:flex;align-items:center;gap:6px;flex:0 1 auto;min-width:0}.nc-deck-owner-group{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 2px;border:1px solid #182318;border-radius:8px;background:#0b100b;flex:0 0 auto}.nc-deck-owner{max-width:120px;padding:0 4px;overflow:hidden;text-overflow:ellipsis;color:#789a87;font-size:9px;text-transform:uppercase;letter-spacing:.04em}.nc-deck-chip{display:inline-flex;align-items:center;border:1px solid #243;border-radius:6px;overflow:hidden;background:#0a0e0a}.nc-deck-chip.current{border-color:#7aa903}.nc-deck-chip.offline{opacity:.58;border-style:dashed}.nc-deck-stale{padding:0 3px;font-size:9px;line-height:1;color:#b9964a;cursor:help;white-space:nowrap;align-self:center}.nc-deck-chip.nc-deck-dragging{opacity:.58}.nc-deck-chip.nc-deck-over{box-shadow:0 0 0 2px #0c6 inset}.nc-deck-handle{align-self:stretch;min-width:25px;padding:0 5px;background:#ffffff09;border:0;border-right:1px solid #1c2a1c;color:#789a87;cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none;font:11px/1 monospace}.nc-deck-handle:hover,.nc-deck-handle:focus-visible,.nc-deck-handle.active{color:#bfffd8;background:#00cc661f;outline:none}.nc-deck-handle.active{cursor:grabbing}.nc-deck-open{background:none;border:none;color:#cfe;padding:3px 8px;font:inherit;font-size:12px;cursor:pointer;max-width:180px;overflow:hidden;text-overflow:ellipsis}.nc-deck-chip.current .nc-deck-open{color:#d9f7c7}.nc-deck-open:hover{background:#132013}.nc-deck-open:disabled,.nc-deck-mini:disabled,.nc-deck-newbtn:disabled{cursor:not-allowed;opacity:.55}.nc-deck-mini{background:none;border:none;border-left:1px solid #1c2a1c;color:#7a9;padding:3px 6px;font:inherit;font-size:11px;cursor:pointer}.nc-deck-mini:hover{background:#132013;color:#9fd}.nc-deck-del:hover{color:#f99}.nc-deck-newbtn{background:none;border:1px dashed #2a3a2a;color:#9fd;border-radius:6px;padding:3px 7px;font:inherit;font-size:11px;cursor:pointer;flex:0 0 auto}.nc-deck-newbtn:hover{border-color:#7aa903}.nc-deck-add{display:inline-flex;align-items:center;gap:5px;flex:0 0 auto}.nc-deck-add input{padding:3px 8px;background:#122;border:1px solid #243;color:#cfe;border-radius:6px;font:inherit;font-size:12px;width:130px}.nc-deck-add input.invalid{border-color:#a44}.nc-deck-slug{color:#7a9;font-size:10px;max-width:130px;overflow:hidden;text-overflow:ellipsis}.nc-deck-ok,.nc-deck-cancel{background:#122;border:1px solid #243;color:#9fd;border-radius:6px;padding:3px 9px;font:inherit;font-size:12px;cursor:pointer}.nc-deck-ok:disabled{opacity:.4;cursor:default}.nc-deck-state{font-size:10px;color:#7a9;min-width:64px}.nc-deck-state.error,.nc-deck-error{color:#f88;font-size:10px}.nc-deck-fallback{color:#fd8;font-size:11px}.nc-tile-deck{background:#0a0e0a;border:1px solid #243;color:#9fd;border-radius:5px;font:inherit;font-size:11px;padding:1px 3px;max-width:92px}.nc-deck-owner-toggle{display:inline-flex;align-items:center;gap:2px;background:none;border:0;padding:0 2px;margin:0;color:inherit;font:inherit;cursor:pointer;border-radius:4px;flex:0 0 auto;max-width:140px}.nc-deck-owner-toggle:hover{background:#00cc6614}.nc-deck-owner-toggle:focus-visible{outline:2px solid #7aa903;outline-offset:1px}.nc-deck-owner-toggle .nc-deck-owner{padding:0 2px}.nc-deck-owner-caret{color:#5a7a68;font-size:9px;flex:0 0 auto}.nc-deck-owner-group.collapsed{background:#090d09}.nc-deck-owner-content{display:inline-flex;align-items:center;gap:4px}.nc-deck-owner-content[hidden]{display:none}.nc-deck-owner-group.collapsed .nc-deck-owner-content{gap:3px}.nc-deck-summary{display:inline-flex;align-items:center;gap:3px;padding:0 3px 0 1px;font-size:9px;color:#6f8c7c;max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-deck-summary-count{background:#15241a;color:#9fd;border-radius:8px;padding:0 5px;font-size:9px;flex:0 0 auto}.nc-deck-summary-current{color:#d9f7c7}.nc-deck-dot{display:inline-block;width:7px;height:7px;border-radius:50%;margin:0 3px 0 4px;flex:0 0 auto;background:#2a3a2a}.nc-deck-dot.working{background:#0c6;box-shadow:0 0 5px #0c6}.nc-deck-dot.on{background:#6a9}.nc-deck-dot.neutral{background:#526652}.nc-deck-dot.warn{background:#d93}.nc-deck-chip.offline .nc-deck-dot{opacity:.7}.nc-pair-card{border:1px solid #2f5;border-radius:8px;box-shadow:0 0 0 1px #22ff5514}.nc-pair-input{width:100%;min-width:0;box-sizing:border-box;font-size:15px;padding:10px}.nc-pair-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.nc-pair-status{min-height:1em}.nc-pair-progress{color:#9f9;animation:nc-pair-pulse 1.2s ease-in-out infinite}@keyframes nc-pair-pulse{0%,to{opacity:1}50%{opacity:.45}}.nc-pair-hint{opacity:.85;margin-top:4px;font-size:12px}.nc-pair-notice{display:block}.nc-pair-advanced-toggle{align-self:flex-start}.nc-pair-advanced{display:flex;flex-direction:column;gap:8px;min-width:0}.nc-qr-overlay{z-index:80}.nc-qr-modal{max-width:min(480px,calc(100vw - 32px));width:100%}.nc-qr-video{width:100%;max-height:60dvh;border-radius:6px;background:#000;object-fit:cover}.nc-qr-upload{display:inline-flex;align-items:center;cursor:pointer}.nc-authkeys{display:flex;flex-direction:column;gap:6px;margin-top:10px;padding:10px;border:1px solid #2f5;border-radius:8px;background:#22ff550a}.nc-authkeys-line{width:100%;min-width:0;box-sizing:border-box;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.4;white-space:pre-wrap;word-break:break-all;resize:vertical}.nc-authkeys .nc-btn{align-self:flex-start}.nc-detail-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:75;background:#0009;display:flex;align-items:flex-end;justify-content:center;overscroll-behavior:contain}.nc-detail-sheet{width:100%;max-height:88dvh;display:flex;flex-direction:column;min-height:0;background:#0e140e;color:#cfe;border:1px solid #243;border-bottom:none;border-radius:14px 14px 0 0;box-shadow:0 -12px 40px #0000008c;outline:none}.nc-detail-head{display:flex;align-items:flex-start;gap:10px;padding:14px 14px 10px;border-bottom:1px solid #1b2a1b;position:sticky;top:0;background:#0e140e;z-index:1}.nc-detail-title{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.nc-detail-title b{font-size:16px;color:#d8ffe8;overflow-wrap:anywhere}.nc-detail-title small{font-size:12px;opacity:.65;overflow-wrap:anywhere}.nc-detail-close{padding:6px 8px;flex:none}.nc-detail-body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:12px 14px;display:flex;flex-direction:column;gap:16px}.nc-detail-body.plain{padding:0;gap:0}.nc-detail-section{display:flex;flex-direction:column;gap:8px;min-width:0}.nc-detail-foot{display:flex;flex-wrap:wrap;gap:8px;padding:10px 14px;border-top:1px solid #1b2a1b;background:#0b110b;padding-bottom:max(10px,env(safe-area-inset-bottom))}.nc-detail-foot .nc-btn{white-space:nowrap;display:inline-flex;align-items:center;gap:6px}.nc-detail-facts{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 10px;padding:10px;border:1px solid #243;border-radius:8px;background:#0a0e0a;font-size:13px;min-width:0;overflow-wrap:anywhere}.nc-detail-facts dt{opacity:.65}.nc-detail-facts dd{margin:0}.nc-detail-grants{display:flex;flex-direction:column;gap:6px}.nc-detail-grant{display:flex;align-items:center;gap:8px;padding:7px 10px;border:1px solid #243;border-radius:8px;background:#0a0e0a;font-size:13px;min-width:0}.nc-detail-grant>span{flex:1;min-width:0;overflow-wrap:anywhere}.nc-detail-grant.unknown>span{opacity:.6;font-style:italic}.nc-detail-picker{display:flex;flex-direction:column;gap:6px}.nc-detail-picker input{padding:9px 10px;font:14px/1.2 inherit;box-sizing:border-box;background:#0a0e0a;color:#cfe;border:1px solid #243;border-radius:8px;width:100%;min-width:0}.nc-detail-picker input:focus{outline:none;border-color:#2e7d32}.nc-detail-picker-list{display:flex;flex-wrap:wrap;gap:6px}@media(min-width:600px){.nc-detail-overlay{align-items:stretch;justify-content:flex-end}.nc-detail-sheet{width:min(440px,100%);max-height:none;height:100%;border:none;border-left:1px solid #243;border-radius:0;box-shadow:-12px 0 40px #0000008c}}.nc-vl-prompt{display:flex;gap:8px;align-items:flex-end}.nc-vl-prompt textarea{flex:1 1 auto;min-height:64px;resize:vertical;background:#101810;color:#d8ffe8;border:1px solid #2d4634;border-radius:4px;padding:6px 8px;font:inherit}.nc-set-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:60;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box}.nc-set-panel{width:100%;max-width:560px;max-height:90vh;background:#0e140e;color:#cfe;border:1px solid #243;border-radius:14px;padding:16px;display:flex;flex-direction:column;gap:12px;box-shadow:0 12px 40px #00000080;overflow:hidden}@media(max-width:1023px){.nc-set-overlay{padding:0}.nc-set-panel{max-width:none;max-height:none;height:100%;border-radius:0;border:none}}.nc-set-head{display:flex;align-items:center;gap:8px}.nc-set-head b{font-size:16px;color:#d8ffe8;flex:1}.nc-set-close{background:none;border:none;color:#9fd;cursor:pointer;padding:4px}.nc-set-readonly{font-size:12px;color:#e0b020;border:1px solid #4a3a10;border-radius:8px;padding:8px 10px;background:#171307}.nc-set-tabs-wrap{position:relative;min-width:0}.nc-set-tabs-wrap:before,.nc-set-tabs-wrap:after{content:"";position:absolute;z-index:1;top:0;bottom:9px;width:28px;opacity:0;pointer-events:none;transition:opacity .16s ease}.nc-set-tabs-wrap:before{left:0;background:linear-gradient(90deg,#0e140e 10%,#0e140e00)}.nc-set-tabs-wrap:after{right:0;background:linear-gradient(270deg,#0e140e 10%,#0e140e00)}.nc-set-tabs-wrap.has-start-overflow:before,.nc-set-tabs-wrap.has-end-overflow:after{opacity:1}.nc-set-tabs{display:flex;gap:6px;min-width:0;overflow-x:auto;overflow-y:hidden;border-bottom:1px solid #1c241c;padding-bottom:8px;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:thin;scrollbar-color:rgba(159,255,221,.35) transparent}.nc-set-tabs .nc-set-tabbtn{flex:0 0 auto;min-height:44px;white-space:nowrap}.nc-set-tabbtn{background:none;border:1px solid #1c241c;border-radius:8px;color:#9fd;font-size:12px;padding:6px 12px;cursor:pointer;text-transform:uppercase;letter-spacing:.5px}.nc-set-tabbtn.on{border-color:#2e7d32;background:#14200f;color:#d8ffe8}.nc-system-tabs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}.nc-system-tabs .nc-set-tabbtn{min-width:0;text-transform:none}.nc-system-group{display:flex;flex-direction:column;gap:8px}.nc-system-group>h3{margin:0;color:#d8ffe8;font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.nc-system-diagnostics{gap:12px}.nc-alternate-screen-settings{border:1px solid #243;border-radius:10px;padding:10px}.nc-set-body{overflow-y:auto;flex:1;min-height:120px}.nc-set-tab{display:flex;flex-direction:column;gap:12px}.nc-set-tab .nc-check span{display:flex;flex-direction:column;gap:2px}.nc-set-tab .nc-check small{opacity:.6;font-size:11px}.nc-set-info{font-size:12px;opacity:.7;line-height:1.6}.nc-set-note{font-size:12px;color:#9fd}.nc-set-hint{font-size:11px;opacity:.7}.nc-set-form{display:flex;flex-direction:column;gap:8px}.nc-set-form .nc-field{display:flex;flex-direction:column;gap:4px;font-size:12px;opacity:.82}.nc-set-form .nc-field small{font-size:10px;opacity:.7;line-height:1.3}.nc-set-ports{display:grid;grid-template-columns:1fr 1fr;gap:8px}@media(max-width:520px){.nc-set-ports{grid-template-columns:1fr}}.nc-set-form input:not([type=checkbox]):not([type=file]){padding:9px 10px;font:14px/1.2 inherit;background:#0a0e0a;color:#cfe;border:1px solid #243;border-radius:8px;width:100%;min-width:0;max-width:100%;box-sizing:border-box}.nc-set-form input:focus{outline:none;border-color:#2e7d32}.nc-set-form input:disabled{opacity:.5}.nc-set-form textarea,.nc-set-form select{padding:9px 10px;font:13px/1.3 inherit;background:#0a0e0a;color:#cfe;border:1px solid #243;border-radius:8px;min-height:36px;width:100%;min-width:0;max-width:100%;box-sizing:border-box}.nc-set-form textarea{min-height:72px;resize:vertical}.nc-fleet-editor{gap:10px}.nc-fleet-view-tabs{display:grid;grid-template-columns:1fr 1fr;gap:6px;position:sticky;top:0;z-index:2;background:#0e140e;padding-bottom:6px}.nc-fleet-view-tabs .nc-set-tabbtn{width:100%;text-transform:none}.nc-fleet-section-head,.nc-fleet-item{display:flex;align-items:center;justify-content:space-between;gap:8px}.nc-fleet-section-head{margin-top:4px;border-bottom:1px solid #243;padding-bottom:6px}.nc-fleet-item{border:1px solid #1c241c;border-radius:8px;padding:8px}.nc-fleet-label{color:#9fb89f;font-style:italic}.nc-fleet-item>span{display:flex;gap:6px;align-items:center;min-width:0}.nc-fleet-item>span:first-child{flex-direction:column;align-items:flex-start;min-width:0}.nc-fleet-item>span:last-child{flex-wrap:wrap;justify-content:flex-end}.nc-fleet-item>span:first-child b,.nc-fleet-item>span:first-child small{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-fleet-item small{opacity:.6}.nc-fleet-tag{display:inline-block;padding:1px 6px;border-radius:6px;font-size:11px;font-weight:600;line-height:1.5;border:1px solid rgba(224,176,32,.55);color:#e0b020;background:#e0b0201f}.nc-fleet-tag.nc-fleet-tag-warn{color:#e8c547;border-color:#e8c5478c;background:#e8c5471a}.nc-cwd-rel-row{display:flex;align-items:center;gap:6px}.nc-cwd-rel-prefix{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;opacity:.85;flex:0 0 auto}.nc-cwd-rel-row input{flex:1;min-width:0}.nc-cwd-preview{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;opacity:.85;word-break:break-all}.nc-cwd-suggestion{display:flex;flex-wrap:wrap;align-items:center;gap:6px;font-size:12px;color:#e8c547;border:1px solid rgba(232,197,71,.4);background:#e8c54714;border-radius:8px;padding:6px 8px}.nc-cwd-no-source{font-size:12px;opacity:.65}.nc-fleet-form{border:1px solid #2e7d32;border-radius:10px;padding:10px}.nc-fleet-key{display:flex;flex-direction:column;gap:7px;border:1px solid #36523b;border-radius:9px;padding:10px;background:#0a100b}.nc-fleet-key-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.nc-fleet-key-head>b{letter-spacing:.08em}.nc-fleet-key-head>span{font-size:11px;opacity:.72}.nc-fleet-key-input{display:flex;gap:6px}.nc-fleet-key-input>input{flex:1;min-width:0}.nc-fleet-key-missing{align-items:flex-start;color:#ffca80}.nc-fleet-provider-notice{border-left:2px solid #6b7f3e;padding-left:8px;line-height:1.35}.nc-fleet-models{border:1px solid #36523b;border-radius:9px;padding:10px;display:flex;flex-direction:column;gap:7px;background:#0a100b}.nc-fleet-models-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.nc-fleet-model-row{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;padding:3px 2px;border-radius:6px}.nc-fleet-model-row .nc-fleet-model-pick{padding:2px 8px;font-size:12px}.nc-fleet-model-row.nc-model-not-in-api{background:#ff44441f;border:1px solid rgba(255,68,68,.35)}.nc-fleet-model-field{font-size:11px;opacity:.85;white-space:nowrap}.nc-fleet-model-src{display:inline-block;margin-left:3px;padding:0 4px;border-radius:4px;font-size:9px;letter-spacing:.04em;background:#1c2a1e;opacity:.8}.nc-fleet-models-note{font-size:10px;opacity:.65}.nc-fleet-missing{display:flex;flex-direction:column;gap:6px;padding:8px;border:1px solid rgba(255,187,68,.45);border-radius:8px;background:#ffbb4412}.nc-fleet-missing .nc-field input{max-width:160px}.nc-fleet-missing-open{font-size:11px;padding:2px 8px;align-self:flex-start}.nc-fleet-modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:75;padding:16px;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background:#000000b8;overscroll-behavior:contain}.nc-fleet-modal-dialog{width:min(680px,100%);max-height:calc(100dvh - 32px);overflow-y:auto;border-radius:12px;background:#0e140e;box-shadow:0 14px 50px #000000b3;overscroll-behavior:contain}.nc-fleet-modal-dialog .nc-fleet-form{margin:0;padding:14px}.nc-fleet-head-actions{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}.nc-fleet-pair,.nc-fleet-env{display:flex;gap:6px}.nc-fleet-pair input,.nc-fleet-pair select,.nc-fleet-env input{flex:1;min-width:0}@media(max-width:520px){.nc-fleet-modal{padding:0;align-items:stretch}.nc-fleet-modal-dialog{width:100%;max-height:100dvh;border-radius:0}.nc-fleet-item{align-items:stretch;flex-direction:column}.nc-fleet-item>span:last-child{width:100%;justify-content:flex-start}.nc-fleet-pair{flex-direction:column}}.nc-invite-endpoint{border:1px solid #243;border-radius:8px;padding:9px 10px;overflow-wrap:anywhere}.nc-local-share{border:1px solid #243;border-radius:10px;padding:10px;background:#0a0e0a}.nc-local-share .nc-node-share{padding:2px 0}.nc-invite-advanced{display:flex;flex-direction:column;gap:8px;padding:9px;border-left:2px solid #243}.nc-invite-actions{flex-wrap:wrap}.nc-update-settings,.nc-backup-dialog{border:1px solid #243;border-radius:10px;padding:10px}.nc-backup-tabs{margin:0}.nc-backup-list{display:flex;flex-direction:column;gap:6px;max-height:42vh;overflow-y:auto}.nc-backup-row,.nc-backup-import-row{border:1px solid #1c241c;border-radius:8px;padding:8px}.nc-backup-import-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(160px,.7fr);gap:8px;align-items:center}@media(max-width:520px){.nc-backup-import-row{grid-template-columns:1fr}}.nc-set-node{border:1px solid #1c241c;border-radius:10px;padding:10px;display:flex;flex-direction:column;gap:8px;background:#0a0e0a}.nc-peer-group{display:flex;flex-direction:column;gap:8px}.nc-peer-group-title{display:flex;align-items:center;justify-content:space-between;color:#9fd;font-size:12px;font-weight:600;padding:2px 1px}.nc-peer-group-title span{color:#789;font-variant-numeric:tabular-nums}.nc-set-node.routed{border-style:dashed;background:#090d0b}.nc-node-editor{border-top:1px solid #243;padding-top:10px}.nc-node-row{flex-direction:row;align-items:center;gap:8px;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;min-height:48px}.nc-node-row:hover{border-color:#2e7d32}.nc-node-row:focus-visible{outline:2px solid #2e7d32;outline-offset:2px}.nc-node-row-text{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.nc-node-row-text b{color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-node-row-text small{opacity:.6;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-node-row-more{flex:none;opacity:.5;display:flex}.nc-set-node-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.nc-set-node-head b{color:#d8ffe8}.nc-set-node-head small{opacity:.6;font-size:11px}.nc-set-tunnel{margin-left:auto;font-size:11px;color:#f88}.nc-set-tunnel.up{color:#6c6}.nc-set-node-actions{display:flex;gap:6px;flex-wrap:wrap}.nc-set-node-actions .nc-btn{padding:5px 10px;font-size:12px}.nc-set-test{font-size:11px}.nc-set-test.ok{color:#6c6}.nc-set-test.ko{color:#f88}.nc-diagnostics .nc-field{display:flex;flex-direction:column;gap:4px;font-size:12px}.nc-diag-controls{border:1px solid #243;border-radius:10px;padding:10px}.nc-diag-filters{display:grid;grid-template-columns:minmax(110px,.45fr) minmax(0,1fr);gap:8px}.nc-diag-filters select,.nc-diag-filters input,.nc-diagnostics>.nc-field select{padding:8px 9px;font:12px/1.3 inherit;background:#0a0e0a;color:#cfe;border:1px solid #243;border-radius:8px;min-width:0;width:100%;box-sizing:border-box}.nc-diag-log{min-height:220px;max-height:42vh;margin:0;padding:10px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text;background:#070a07;color:#bde8c8;border:1px solid #1c241c;border-radius:8px;font:11px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}@media(max-width:520px){.nc-set-tabs{scrollbar-width:none;-ms-overflow-style:none}.nc-set-tabs::-webkit-scrollbar{display:none}.nc-set-tabs .nc-set-tabbtn{min-width:max-content;padding-inline:12px}.nc-diag-filters{grid-template-columns:1fr}.nc-diag-log{min-height:35vh;max-height:48vh}}.nc-set-copyline{display:flex;gap:8px;align-items:center}.nc-set-copyline code{flex:1;font-size:10px;word-break:break-all;-webkit-user-select:all;user-select:all;background:#0a0e0a;border:1px solid #1c241c;border-radius:6px;padding:6px;max-height:72px;overflow-y:auto}.nc-set-akeys{display:flex;flex-direction:column;gap:6px}.nc-set-row{display:flex;gap:8px;flex-wrap:wrap}.nc-set-confirm{border:1px solid #4a3a10;border-radius:10px;padding:10px;background:#171307;font-size:12px;color:#e8d8a0;display:flex;flex-direction:column;gap:10px}.nc-set-panel .nc-check{display:flex;align-items:flex-start;gap:8px;font-size:13px;cursor:pointer}.nc-set-panel .nc-check input{accent-color:#2e7d32;margin-top:2px}.nc-set-panel .nc-btn{border:none;border-radius:8px;padding:8px 16px;font-size:13px;cursor:pointer}.nc-set-panel .nc-btn.ghost{background:none;border:1px solid #243;color:#9fd}.nc-set-panel .nc-btn.primary{background:#2e7d32;color:#fff}.nc-set-panel .nc-btn.danger{background:none;border:1px solid #532;color:#f88}.nc-set-panel .nc-btn:disabled{opacity:.5;cursor:default}.nc-set-panel .nc-sheet-actions{display:flex;justify-content:flex-end;gap:8px;flex-wrap:wrap}.nc-set-panel .nc-sheet-label{font-size:12px;opacity:.7;text-transform:uppercase;letter-spacing:.5px}.nc-set-panel .nc-err{color:#f88;font-size:12px}.nc-set-panel .nc-empty{opacity:.5;font-size:12px}.nc-set-panel .nc-dot{width:8px;height:8px;border-radius:50%;background:#333;display:inline-block;flex:0 0 8px}.nc-set-panel .nc-dot.on{background:#2e7d32}.nc-model-test{font-weight:600}.nc-model-test.ok{color:var(--success)}.nc-model-test.unknown-model{color:var(--error)}.nc-model-test.auth,.nc-model-test.unreachable{color:var(--warning)}.nc-model-test.unverified{color:var(--text-secondary);font-style:italic}.nc-wiz-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:70;background:#000000b3;display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box}.nc-wiz{width:100%;max-width:420px;max-height:90vh;overflow-y:auto;background:#0e140e;color:#cfe;border:1px solid #243;border-radius:14px;padding:18px;display:flex;flex-direction:column;gap:14px;box-shadow:0 12px 40px #00000080}.nc-wiz-head{display:flex;flex-direction:column;gap:4px}.nc-wiz-head b{font-size:17px;color:#d8ffe8}.nc-wiz-head small{font-size:12px;opacity:.65;text-transform:uppercase;letter-spacing:.5px}.nc-wiz-body{display:flex;flex-direction:column;gap:10px}.nc-wiz-body input{padding:9px 10px;font:14px/1.2 inherit;background:#0a0e0a;color:#cfe;border:1px solid #243;border-radius:8px}.nc-wiz-body input:focus{outline:none;border-color:#2e7d32}.nc-wiz-body .nc-field{display:flex;flex-direction:column;gap:5px;font-size:12px;color:#bfe8cd}.nc-wiz-body .nc-field small{font-size:10px;opacity:.58;line-height:1.3}.nc-wiz-help{margin:0;font-size:11px;line-height:1.4;opacity:.7}.nc-wiz-ports{display:grid;grid-template-columns:1fr 1fr;gap:10px}@media(max-width:420px){.nc-wiz-ports{grid-template-columns:1fr}}.nc-wiz-done{font-size:13px;opacity:.85}.nc-wiz .nc-check{display:flex;align-items:flex-start;gap:8px;font-size:13px;cursor:pointer}.nc-wiz .nc-check input{accent-color:#2e7d32;margin-top:2px}.nc-wiz .nc-check span{display:flex;flex-direction:column;gap:2px}.nc-wiz .nc-check small{opacity:.6;font-size:11px}.nc-wiz .nc-btn{border:none;border-radius:8px;padding:8px 16px;font-size:13px;cursor:pointer}.nc-wiz .nc-btn.ghost{background:none;border:1px solid #243;color:#9fd}.nc-wiz .nc-btn.primary{background:#2e7d32;color:#fff}.nc-wiz .nc-btn:disabled{opacity:.5;cursor:default}.nc-wiz .nc-sheet-actions{display:flex;justify-content:flex-end;gap:8px}.nc-wiz .nc-err{color:#f88;font-size:12px}.nc-wiz-skip{background:none;border:none;color:#9fd;opacity:.6;font-size:12px;cursor:pointer;text-decoration:underline;align-self:center;padding:4px}.nc-wiz-skip:hover{opacity:1}.nc-ntf-toasts{position:fixed;top:10px;right:10px;z-index:2100;display:flex;flex-direction:column;gap:8px;max-width:min(360px,calc(100vw - 20px))}.nc-ntf-toast{display:flex;align-items:flex-start;gap:8px;background:var(--bg-secondary);color:var(--text-primary);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:10px;padding:8px 8px 8px 12px;font-size:13px;box-shadow:0 2px 12px #0000008c}.nc-ntf-toast.high{border-left-color:var(--warning)}.nc-ntf-toast-txt{display:flex;flex-direction:column;gap:2px;min-width:0}.nc-ntf-toast-txt b{word-break:break-word}.nc-ntf-toast-txt small{color:var(--text-secondary);word-break:break-word}.nc-ntf-from{color:var(--text-tertiary);font-size:11px;font-family:var(--font-mono)}.nc-ntf-x{margin-left:auto;background:none;border:none;color:var(--text-tertiary);cursor:pointer;padding:2px;display:inline-flex;border-radius:6px}.nc-ntf-x:hover{color:var(--text-primary);background:var(--bg-hover)}.nc-ask-badge{position:fixed;bottom:64px;right:12px;z-index:2100;display:inline-flex;align-items:center;gap:6px;background:var(--accent);color:#fff;border:none;border-radius:999px;padding:8px 14px;font-size:14px;font-weight:700;cursor:pointer;box-shadow:0 2px 12px #0000008c}.nc-ask-badge:hover{background:var(--accent-hover)}.nc-ask-count{background:#00000059;border-radius:999px;padding:0 7px;font-size:12px;line-height:18px}.nc-ask-panel{position:fixed;bottom:10px;right:10px;z-index:2100;width:min(420px,calc(100vw - 20px));max-height:min(70vh,560px);display:flex;flex-direction:column;background:var(--bg-secondary);border:1px solid var(--border);border-radius:12px;box-shadow:0 4px 20px #0009}.nc-ask-panel-head{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--border);font-size:13px}.nc-ask-panel-head .nc-ask-count{background:var(--accent)}.nc-ask-panel-body{overflow-y:auto;padding:10px 12px;display:flex;flex-direction:column;gap:10px}.nc-ask-card{background:var(--bg-tertiary);border:1px solid var(--border);border-radius:10px;padding:10px;display:flex;flex-direction:column;gap:8px}.nc-ask-head{display:flex;align-items:center;gap:8px}.nc-ask-id{color:var(--text-tertiary);font-size:11px;margin-left:auto}.nc-ask-q{font-size:13px;white-space:pre-wrap;word-break:break-word}.nc-ask-opts{display:flex;flex-wrap:wrap;gap:6px}.nc-ask-reply{display:flex;gap:6px;align-items:flex-end}.nc-ask-reply textarea{flex:1;resize:vertical;min-height:34px;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border);border-radius:8px;padding:6px 8px;font:inherit;font-size:13px}.nc-ask-card .nc-err{color:var(--error);font-size:12px}.nc-remote-notices{display:flex;flex-direction:column;gap:8px}.nc-remote-notices-head{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text-tertiary)}.nc-remote-notices-clear{margin-left:auto;background:none;border:1px solid var(--border);color:var(--text-tertiary);border-radius:6px;padding:2px 8px;font-size:11px;cursor:pointer}.nc-remote-notices-clear:hover{color:var(--text-primary);background:var(--bg-hover)}.nc-remote-notice-head{display:flex;align-items:flex-start;gap:8px}.nc-remote-notice{background:var(--bg-tertiary);border:1px solid var(--border);border-radius:10px;padding:10px;display:flex;flex-direction:column;gap:6px}.nc-remote-notice b{font-size:13px;word-break:break-word}.nc-remote-notice div{font-size:13px;white-space:pre-wrap;word-break:break-word}.nc-remote-notice-meta{color:var(--text-tertiary);font-size:11px}.nc-remote-notice-high{border-color:var(--error)}.nc-cell-switcher-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:70;display:flex;align-items:flex-end;background:#0000008c}.nc-cell-switcher{width:min(88vw,360px);min-height:260px;max-height:72vh;max-height:min(72dvh,540px);box-sizing:border-box;padding:12px 12px max(12px,env(safe-area-inset-bottom)) max(12px,env(safe-area-inset-left));display:flex;flex-direction:column;gap:8px;background:#0e140e;color:#cfe;border-right:1px solid #243;border-top:1px solid #243;border-radius:0 14px 0 0;box-shadow:10px -6px 30px #00000073;outline:none}.nc-cell-switcher-list{min-height:0;flex:1 1 auto;overflow-y:auto;display:flex;flex-direction:column;gap:6px;overscroll-behavior-y:contain}.nc-cell-switcher-row{height:60px;min-height:60px;overflow:hidden;width:100%;display:flex;align-items:stretch;gap:6px;box-sizing:border-box;padding:0 6px 0 0;border:1px solid #1c241c;border-radius:9px;background:#0a0e0a;color:#cfe}.nc-cell-switcher-position{padding:2px 4px 0;font-size:11px;opacity:.55;text-transform:uppercase;letter-spacing:.5px}.nc-cell-switcher-row.current{border-color:#2e7d32;background:#14200f}.nc-cell-switcher-row.off .nc-cell-switcher-copy b,.nc-cell-switcher-row.off .nc-cell-switcher-copy small:not(.nc-cell-switcher-state),.nc-cell-switcher-row.off .nc-cell-switcher-dot,.nc-cell-switcher-row.off .nc-cell-switcher-menu{opacity:.55}.nc-cell-switcher-row-select{min-width:0;min-height:44px;flex:1 1 auto;display:flex;align-items:center;gap:10px;padding:8px 4px 8px 0;border:0;background:transparent;color:#cfe;text-align:left}.nc-cell-switcher-row-select[aria-disabled=true]{cursor:default}.nc-cell-switcher .nc-roster-handle{flex:0 0 36px;width:36px;min-width:36px;min-height:44px;margin:0;border:1px solid transparent;border-radius:8px;background:#ffffff06;color:#688475;touch-action:none}.nc-cell-switcher .nc-roster-handle.active,.nc-cell-switcher .nc-roster-handle:focus-visible{color:#bfffd8;border-color:#00cc6673;background:#00cc661f}.nc-cell-switcher-row.nc-roster-dragging .nc-cell-switcher-copy b,.nc-cell-switcher-row.nc-roster-dragging .nc-cell-switcher-copy small:not(.nc-cell-switcher-state){opacity:.7}.nc-cell-switcher-row.nc-roster-over{outline:2px solid rgba(0,204,102,.72);outline-offset:2px}.nc-cell-switcher-dot{flex:0 0 9px;width:9px;height:9px;border-radius:50%;background:#355}.nc-cell-switcher-dot.on{background:#0c6;box-shadow:0 0 6px #0c68}.nc-cell-switcher-dot.warn{background:#e0b020;box-shadow:0 0 6px #e0b02088}.nc-cell-switcher-dot.working{animation:nc-cell-switcher-pulse 1.1s ease-in-out infinite}.nc-cell-switcher-copy{min-width:0;min-height:0;overflow:hidden;display:flex;flex-direction:column;gap:2px}.nc-cell-switcher-copy b,.nc-cell-switcher-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-cell-switcher-copy b{color:#d8ffe8;font-size:14px}.nc-cell-switcher-nameline{display:flex;align-items:center;gap:6px;min-width:0}.nc-cell-switcher-nameline b{flex:0 1 auto;min-width:0}.nc-cell-switcher-copy small{opacity:.62;font-size:13px}.nc-cell-switcher-stateline{display:flex;align-items:baseline;min-width:0;overflow:hidden}.nc-cell-switcher-stateline>*{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-cell-switcher-stateline>*+*:before{content:" · "}.nc-cell-switcher-copy .nc-cell-switcher-state{opacity:.88;color:#d8ffe8;font-size:12px}.nc-cell-switcher-copy .nc-cell-switcher-telemetry{color:#9fd8c2}.nc-cell-switcher-notice{color:#ffd36b;font-size:12px}.nc-cell-switcher-controls{display:flex;align-items:center;gap:8px;min-width:0}.nc-cell-switcher-controls b{flex:0 0 auto;color:#d8ffe8;font-size:15px;white-space:nowrap}.nc-cell-switcher-node{flex:0 0 auto;margin-right:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;opacity:.55;text-transform:uppercase;letter-spacing:.5px}.nc-cell-switcher-controls>button{min-width:30px;min-height:30px;padding:0 6px;border:1px solid #2b3c2b;border-radius:8px;background:transparent;color:#cfe;font-size:14px;line-height:1}.nc-cell-switcher-controls .nc-cell-switcher-close{font-size:18px}.nc-cell-switcher-filter{display:inline-flex;flex:0 0 auto;border:1px solid #2b3c2b;border-radius:999px;overflow:hidden}.nc-cell-switcher-filter button{min-width:0;min-height:26px;padding:0 10px;border:0;border-radius:0;background:transparent;color:#9fb3a4;font-size:11px;line-height:1}.nc-cell-switcher-filter button.on{background:#00cc6629;color:#bfffd8}@keyframes nc-cell-switcher-pulse{50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.nc-cell-switcher-dot.working{animation:none}}.nc-cell-switcher-peek{flex:0 0 auto;display:flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:0;border-radius:8px}.nc-cell-switcher-menu{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:0;flex:0 0 auto;background:transparent;border:1px solid rgba(255,255,255,.14);color:#9aa89a;border-radius:10px;font-size:18px;line-height:1;cursor:pointer}.nc-cell-switcher-menu.on{color:#bfffd8;border-color:#00cc668c;background:#00cc661f}.nc-cell-switcher-side{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:0;flex:0 0 auto;background:transparent;border:1px solid rgba(255,255,255,.14);color:#9aa89a;border-radius:10px;line-height:1;cursor:pointer}.nc-cell-switcher-side svg{display:block}.nc-cell-switcher-side:disabled{opacity:.38;cursor:default}.nc-cell-switcher-side:hover:not(:disabled){color:#c9d6c9;border-color:#ffffff47}.nc-cell-switcher-side.on{color:#bfffd8;border-color:#00cc6673;background:#00cc661f}.nc-cell-switcher-row.side .nc-cell-switcher-copy b,.nc-cell-switcher-row.side .nc-cell-switcher-copy small:not(.nc-cell-switcher-state),.nc-cell-switcher-row.side .nc-cell-switcher-dot{opacity:.55}.nc-cell-switcher-here{flex:0 0 auto;padding:1px 6px;border-radius:999px;border:1px solid rgba(0,204,102,.55);background:#00cc661f;color:#bfffd8;font-size:10px;letter-spacing:.04em;text-transform:uppercase;white-space:nowrap}.nc-cell-switcher-reorder.on{color:#bfffd8;border-color:#00cc668c;background:#00cc661f}.nc-cell-switcher-row.selected{border-color:#4f9cff;background:#10233c}.nc-cell-switcher-taptwo{flex:0 0 auto;padding:1px 6px;border-radius:999px;border:1px solid rgba(79,156,255,.6);background:#4f9cff29;color:#cfe4ff;font-size:10px;letter-spacing:.04em;white-space:nowrap}.nc-cell-switcher-live-strip{display:flex;align-items:center;flex:0 0 auto;padding:5px 10px;border-radius:999px;background:#8b5cf629;border:1px solid rgba(139,92,246,.38);color:#d9c9ff;font-size:12px;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nc-cell-switcher-hint{padding:0 4px;font-size:11px;opacity:.6}.nc-cell-switcher-anteprima{position:absolute;left:0;right:0;top:0;height:50%;box-sizing:border-box;padding:8px 10px 6px;display:flex;flex-direction:column;gap:6px;background:#0a0e0a;border-bottom:1px solid #243;overflow:hidden}.nc-cell-switcher-anteprima-testa{display:flex;align-items:baseline;gap:8px;flex:0 0 auto;min-width:0;position:relative;z-index:2}.nc-cell-switcher-anteprima-testa b{color:#cfe4ff}.nc-cell-switcher-anteprima-testa small{opacity:.55;font-size:11px}.nc-cell-switcher-anteprima-zoom{margin-left:auto;display:flex;align-items:center;gap:6px;font-size:11px;flex:0 0 auto}.nc-cell-switcher-anteprima-zoom button{min-width:30px;min-height:30px;padding:0;border-radius:6px;border:1px solid rgba(216,255,232,.25);background:transparent;color:#d8ffe8;font-size:15px;cursor:pointer}.nc-cell-switcher-anteprima .nc-peek-stream{position:relative;min-height:0;flex:1 1 auto;overflow:hidden}.nc-cell-switcher-anteprima .nc-peek-testo{flex:1 1 auto;overflow-y:auto}.nc-cell-switcher.with-anteprima{max-height:50vh;max-height:min(50dvh,460px)}.nc-vl-session-view{display:flex;flex-direction:column;height:100%;min-height:0;background:#0a0e0a;color:#cfe}.nc-vl-session-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:16px 20px 32px}.nc-vl-session-body .nc-vl-events{max-width:70ch;margin:0 auto}.nc-vl-session-body .nc-vl-events-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}.nc-vl-session-body .nc-vl-ev{white-space:pre-wrap;overflow-wrap:anywhere;font-size:13px;line-height:1.45}.nc-vl-session-body .nc-vl-ev-thinking{color:#7fa88f;font-style:italic}.nc-vl-session-body .nc-vl-ev-tool_start,.nc-vl-session-body .nc-vl-ev-tool_end,.nc-vl-session-body .nc-vl-ev-usage,.nc-vl-session-body .nc-vl-ev-writer_epoch{color:#6f8f7a;font-size:12px}.nc-vl-session-body .nc-vl-ev-turn_end,.nc-vl-session-body .nc-vl-ev-done{color:#8fd0a8}.nc-vl-session-body .nc-vl-ev.error{color:#e08a8a}.nc-vl-session-body .nc-vl-ev.gap{color:#c9b46a;font-size:12px}:root{color-scheme:dark}body,#root{margin:0;height:100vh;height:100dvh;background:#0a0e0a;font-family:ui-monospace,monospace}.nc-app{display:flex;flex-direction:column;height:100vh;height:100dvh;min-height:0}.nc-keybar{flex:0 0 auto}.nc-bar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;padding:8px;color:#cfe;background:#0e140e}.nc-bar button{background:none;border:1px solid #243;color:#9fd;border-radius:6px;padding:4px 10px}.nc-termwrap{position:relative;flex:1}.nc-auth{color:#cfe;padding:20px;display:flex;flex-direction:column;gap:10px;max-width:420px}.nc-auth input[type=text],.nc-auth input:not([type]){padding:10px;background:#122;border:1px solid #243;color:#cfe;border-radius:6px}.nc-auth .nc-auth-error{color:#f88;margin:0}.nc-auth button:disabled{opacity:.5}.nc-auth button{padding:10px;background:#122;border:1px solid #243;color:#9fd;border-radius:6px}.nc-bar-right{margin-left:auto;display:flex;flex-wrap:wrap;gap:4px;flex:0 1 auto;min-width:0;justify-content:flex-end}.nc-bar button,.nc-bar-right button{min-height:40px;min-width:40px}@media(pointer:coarse){.nc-bar button,.nc-bar-right button{min-height:42px;min-width:42px;font-size:20px}}.nc-bar button,.nc-bar-right button{display:inline-flex;align-items:center;justify-content:center;gap:6px}.nc-bar>button{flex:0 0 auto}.nc-bar>b{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600}@media(max-width:480px){.nc-bar-label{display:none}}.nc-workspace{display:flex;flex-direction:row;height:100vh;height:100dvh;min-height:0;background:#0a0e0a;color:#cfe}.nc-workspace-main{flex:1 1 auto;min-width:0;min-height:0;display:flex;flex-direction:column}.nc-single-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:40;background:#0a0e0a}.nc-bar-single .nc-bar-center{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;line-height:1.15}.nc-bar-single .nc-bar-center b{font-size:13px;font-weight:600;color:#d8ffe8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.nc-bar-sub{font-size:10px;opacity:.55;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nc-bar-menu{font-size:18px;line-height:1}.nc-bar-files{position:relative}.nc-bar-dot-nuovi{position:absolute;top:5px;right:5px;width:7px;height:7px;border-radius:50%;background:#e5484d}.nc-app{animation:nc-slide-in .2s ease-out}@keyframes nc-slide-in{0%{transform:translate(12%);opacity:0}to{transform:translate(0);opacity:1}}@media(prefers-reduced-motion:reduce){.nc-app{animation:none}}@keyframes nc-cell-working-blip{0%,to{opacity:1;transform:scale(1);box-shadow:0 0 7px #0c6c}50%{opacity:.22;transform:scale(.72);box-shadow:0 0 1px #0c62}}.nc-dot.on.working,.dot.on.working{animation:nc-cell-working-blip 1.1s ease-in-out infinite;transform-origin:center}@media(prefers-reduced-motion:reduce){.nc-dot.on.working,.dot.on.working{animation:none}}.nc-stale{position:fixed;top:8px;left:50%;transform:translate(-50%);z-index:2000;cursor:pointer;background:#1a2410;color:#d9f7c7;border:1px solid #7aa903;border-radius:8px;padding:6px 14px;font-size:13px;box-shadow:0 2px 10px #00000080}.nc-pin-error{display:flex;align-items:center;gap:8px;padding:6px 10px;margin:6px;border:1px solid rgba(255,90,90,.55);background:#ff5a5a1f;color:#ff8a8a;border-radius:8px;font-size:12px}.nc-pin-error-text{flex:1}.nc-pin-error-retry{cursor:pointer;background:#ff5a5a33;border:1px solid rgba(255,90,90,.5);color:#ffb3b3;border-radius:6px;padding:2px 8px;font-size:12px}.nc-pin-error-retry:hover{filter:brightness(1.2)}.nc-pin-error-close{cursor:pointer;background:transparent;border:none;color:#ff8a8a;font-size:16px;line-height:1;padding:0 2px}.nc-renderer-toggle{opacity:.55}.nc-renderer-toggle.on{opacity:1;color:#7fe3ff}.nc-dual{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column}.nc-dual-pane{position:relative;display:flex;flex-direction:column;min-height:0;min-width:0;border:2px solid #243;border-radius:6px;overflow:hidden;background:#0a0e0a}.nc-dual-pane.foco{border-color:#7ee787}.nc-dual-pane:not(.foco) .nc-dual-strip{opacity:.6}.nc-dual-strip{flex:0 0 26px;display:flex;align-items:center;gap:6px;padding:0 8px;background:#0e140e;border-bottom:1px solid #1c241c;min-width:0}.nc-dual-strip b{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:600;color:#d8ffe8}.nc-dual-dot{width:7px;height:7px;flex:0 0 7px;border-radius:50%;background:#333}.nc-dual-dot.on{background:#2e7d32}.nc-dual-matita{flex:0 0 auto;font-size:12px;line-height:1;color:#7ee787}.nc-dual-tasti{display:flex;gap:2px;flex:0 0 auto}.nc-dual-tasti button{background:none;border:0;color:#9fd;font-size:14px;line-height:1;min-height:22px;min-width:24px;padding:0 3px;border-radius:4px}.nc-dual-body{position:relative;flex:1;min-height:0}.nc-dual-handle{flex:0 0 12px;position:relative;cursor:row-resize;touch-action:none}.nc-dual-handle:after{content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:36px;height:3px;border-radius:2px;background:#243}.nc-dual-handle:hover:after{background:#1c3a1c}.nc-deck-notice{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:2px 8px}.nc-dual.row{flex-direction:row}.nc-dual.row .nc-dual-handle{cursor:col-resize}.nc-dual.row .nc-dual-handle:after{width:3px;height:36px}.nc-dual-pane.nascosto{display:none}.nc-dual-alt{display:inline-flex;align-items:center;gap:4px;background:none;border:0;color:#9fd;cursor:pointer;min-height:22px;min-width:24px;padding:0 3px;border-radius:4px}.nc-update{position:fixed;bottom:8px;left:8px;right:8px;margin:0 auto;width:max-content;z-index:2000;display:flex;align-items:center;gap:10px;background:#0f1a0f;color:#d9f7c7;border:1px solid #2e7d32;border-radius:10px;padding:6px 8px 6px 14px;font-size:13px;box-shadow:0 2px 12px #0000008c;box-sizing:border-box;max-width:calc(100vw - 16px);flex-wrap:wrap}.nc-update-msg{flex:1 1 12em;min-width:0;overflow-wrap:anywhere}.nc-update-btn{display:inline-flex;align-items:center;justify-content:center;background:#2e7d32;border:1px solid #2e7d32;color:#06120a;border-radius:7px;padding:4px 12px;font:inherit;font-size:13px;cursor:pointer;flex:none}.nc-update-btn:hover{background:#3a9d42}@media(prefers-reduced-motion:reduce){.nc-update{transition:none}}.nc-update-close{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;background:transparent;border:1px solid #2e7d32;color:#d9f7c7;border-radius:7px;font:inherit;font-size:14px;line-height:1;cursor:pointer;flex:none}.nc-update-close:hover{background:#2e7d32;color:#06120a}.nc-ui0-demo{height:100dvh;min-height:0;display:flex;flex-direction:column;overflow:hidden;background:var(--bg-primary);color:var(--text-primary);font-family:var(--font-sans)}.nc-ui0-bar{flex:0 0 auto;display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;padding:8px 12px;border-bottom:1px solid var(--border);background:var(--bg-secondary);font-size:12px}.nc-ui0-bar span{color:var(--text-tertiary)}.nc-ui0-grid{flex:1 1 auto;min-height:0;display:grid;gap:8px;padding:8px;grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:minmax(0,1fr);overflow:hidden}.nc-ui0-tile{min-height:0;min-width:0}.nc-ui0-sub{color:var(--text-tertiary);font-size:10.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@media(max-width:560px){.nc-ui0-grid{grid-template-columns:minmax(0,1fr);grid-template-rows:repeat(2,minmax(0,1fr));overflow-y:auto}}:root{--bg-primary: #0d1117;--bg-secondary: #161b22;--bg-tertiary: #21262d;--bg-hover: #30363d;--text-primary: #e6edf3;--text-secondary: #8b949e;--text-tertiary: #6e7681;--border: #30363d;--accent: #6c5ce7;--accent-hover: #7c6cf7;--success: #3fb950;--warning: #d29922;--error: #f85149;--user-bg: #1c2333;--assistant-bg: transparent;--font-mono: "SF Mono", monospace;--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif}*{box-sizing:border-box;margin:0;padding:0}html,body,#root{height:100%;width:100%;overflow:hidden}body{font-family:var(--font-sans);background:var(--bg-primary);color:var(--text-primary);-webkit-font-smoothing:antialiased}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--bg-tertiary);border-radius:3px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.spinning{animation:spin 1s linear infinite}
|
package/frontend/dist/index.html
CHANGED
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
<meta name="apple-mobile-web-app-title" content="NexusCrew" />
|
|
12
12
|
<link rel="manifest" href="/manifest.json" />
|
|
13
13
|
<title>NexusCrew</title>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
15
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-Be8hcPP6.js"></script>
|
|
15
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BwOOF72d.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
18
|
<div id="root"></div>
|
|
19
|
-
<script>if('serviceWorker' in navigator) navigator.serviceWorker.register('/sw.js');</script>
|
|
20
19
|
</body>
|
|
21
20
|
</html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.9.
|
|
1
|
+
{"version":"0.9.78"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const BS = String.fromCharCode(0x5c); // backslash
|
|
4
|
+
const CR = String.fromCharCode(0x0d);
|
|
5
|
+
const LF = String.fromCharCode(0x0a);
|
|
6
|
+
const OPEN_BRACKET = String.fromCharCode(0x5b);
|
|
7
|
+
|
|
8
|
+
// A body line that starts with a delimiter marker can CLOSE the envelope and
|
|
9
|
+
// make the rest of the text look like a message from another sender. The
|
|
10
|
+
// marker is matched on the text that follows the leading '[': the two forms
|
|
11
|
+
// of the contract are "[NexusCrew message ..." and "[End NexusCrew message]".
|
|
12
|
+
const MARKER_RE = /^(?:End )?NexusCrew message/i;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Normalize the line endings of a message body: CRLF and a lone CR both
|
|
16
|
+
* become LF. A lone CR is a line break for a terminal (it rewrites the line
|
|
17
|
+
* it lands on), so it must not survive into the envelope: after the
|
|
18
|
+
* normalization every body line is a line of its own, and the escape below
|
|
19
|
+
* sees exactly what the reader will see.
|
|
20
|
+
*/
|
|
21
|
+
function normalizeEnvelopeText(text) {
|
|
22
|
+
if (typeof text !== 'string') return '';
|
|
23
|
+
return text.split(CR + LF).join(LF).split(CR).join(LF);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Escape one body line: a line that starts with a delimiter marker gets a
|
|
28
|
+
* backslash before the '['. The line no longer starts with the marker, so it
|
|
29
|
+
* cannot close the envelope nor fake a sender, and the escape survives a
|
|
30
|
+
* reader that trims the line before matching it.
|
|
31
|
+
*
|
|
32
|
+
* What counts as "starts with" is the whitespace of JavaScript: a reader
|
|
33
|
+
* that trims the head of the line removes the Unicode spaces and the byte
|
|
34
|
+
* order mark too, so a marker behind one of them is a marker for that
|
|
35
|
+
* reader. The rule is the one of trimStart(), not a hand-made list of
|
|
36
|
+
* characters: a marker that such a reader would recognize is escaped.
|
|
37
|
+
*
|
|
38
|
+
* The boundary of the contract: the line endings normalized here and the
|
|
39
|
+
* whitespace a reader trims. A reader that rewrites the text (a
|
|
40
|
+
* compatibility normalization, for instance) may still see a marker that is
|
|
41
|
+
* not a marker here.
|
|
42
|
+
*/
|
|
43
|
+
function escapeEnvelopeLine(line) {
|
|
44
|
+
const trimmed = line.trimStart();
|
|
45
|
+
if (trimmed.charAt(0) !== OPEN_BRACKET) return line;
|
|
46
|
+
if (!MARKER_RE.test(trimmed.slice(1))) return line;
|
|
47
|
+
// The head that trimStart() removed is the head to keep: the escape goes
|
|
48
|
+
// right before the bracket, so a reader that trims still sees it.
|
|
49
|
+
const head = line.slice(0, line.length - trimmed.length);
|
|
50
|
+
return head + BS + trimmed;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The body of a cell message, safe to be wrapped in the envelope: line
|
|
55
|
+
* endings are normalized and no body line can be read as a delimiter.
|
|
56
|
+
*/
|
|
57
|
+
function escapeEnvelopeText(text) {
|
|
58
|
+
return normalizeEnvelopeText(text).split(LF).map(escapeEnvelopeLine).join(LF);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Format the standard NexusCrew cell message envelope.
|
|
63
|
+
*
|
|
64
|
+
* [NexusCrew message <id> from <label>]
|
|
65
|
+
* <text>
|
|
66
|
+
* [End NexusCrew message]
|
|
67
|
+
*
|
|
68
|
+
* The contract is ONE for every path that delivers a cell message (the
|
|
69
|
+
* /cells/send route and the VL node outbox): the body never contains a line
|
|
70
|
+
* that starts with a delimiter marker, so a message can neither close its own
|
|
71
|
+
* envelope nor fake another sender.
|
|
72
|
+
*/
|
|
73
|
+
function formatCellEnvelope({ id, label, text }) {
|
|
74
|
+
return `[NexusCrew message ${id} from ${label}]\n${escapeEnvelopeText(text)}\n[End NexusCrew message]`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Deliver a message to a target cell's tmux session using the submit function.
|
|
79
|
+
*/
|
|
80
|
+
async function deliverCellMessage(submit, target, { id, label, text }) {
|
|
81
|
+
if (typeof submit !== 'function') {
|
|
82
|
+
throw new Error('cell submit function required');
|
|
83
|
+
}
|
|
84
|
+
const envelope = formatCellEnvelope({ id, label, text });
|
|
85
|
+
return await submit(target.tmuxSession, envelope, { engine: target.engine });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
formatCellEnvelope,
|
|
90
|
+
escapeEnvelopeText,
|
|
91
|
+
normalizeEnvelopeText,
|
|
92
|
+
deliverCellMessage,
|
|
93
|
+
};
|
package/lib/cells/routes.js
CHANGED
|
@@ -5,6 +5,7 @@ const { isValidSession } = require('../files/store.js');
|
|
|
5
5
|
const { submitTextOk } = require('../tmux/actions.js');
|
|
6
6
|
const { createIdentityBindingGuard } = require('../identity/binding-guard.js');
|
|
7
7
|
const { isReservedLiveName } = require('../live-host/reserved.js');
|
|
8
|
+
const { formatCellEnvelope } = require('./deliver.js');
|
|
8
9
|
|
|
9
10
|
const CELL_ID_RE = /^[A-Za-z0-9._-]{1,32}$/;
|
|
10
11
|
const CELL_LABEL_MAX = 64;
|
|
@@ -203,7 +204,7 @@ function cellsRoutes({
|
|
|
203
204
|
// End on printable text even when the source message ends in a newline:
|
|
204
205
|
// Pi may auto-submit a bracketed paste that ends with LF. NexusCrew owns
|
|
205
206
|
// the single explicit Enter used by the transport.
|
|
206
|
-
const envelope =
|
|
207
|
+
const envelope = formatCellEnvelope({ id: body.id, label, text: body.message });
|
|
207
208
|
const outcome = await submit(target.tmuxSession, envelope, { engine: target.engine });
|
|
208
209
|
if (!outcome || outcome.submitted !== true) {
|
|
209
210
|
return reject(409, outcome?.reason || 'consegna non riuscita');
|
package/lib/cells/scope-guard.js
CHANGED
|
@@ -52,6 +52,21 @@ function filterDecks(decks, scope) {
|
|
|
52
52
|
return out;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
// Route che si leggono SOLO per intero, mai per pezzi.
|
|
56
|
+
//
|
|
57
|
+
// L'inventario legacy vl e' una foto dello STATO DEL NODO: nomi di directory
|
|
58
|
+
// e conteggi di sessioni delle cartelle condivise pre-contratto. Quelle
|
|
59
|
+
// directory non hanno una mappatura affidabile cella->sessione, quindi
|
|
60
|
+
// proiettarle su uno scope ristretto richiederebbe INVENTARE quella mappa —
|
|
61
|
+
// e il progetto non la inventa. La scelta e' quindi intera o niente: per un
|
|
62
|
+
// peer con scope limitato la risposta e' un 403 che arriva PRIMA della
|
|
63
|
+
// scansione (nessuna directory viene ne' guardata ne' contata).
|
|
64
|
+
//
|
|
65
|
+
// Il predicato e' quello RISOLTO sulla catena intera (lib/cells/scope.js
|
|
66
|
+
// interseca chi consegna e chi origina): guardare solo l'ultimo hop
|
|
67
|
+
// lascerebbe un peer ristretto ereditare la promessa di un peer ampio.
|
|
68
|
+
const FULL_SCOPE_ROUTES = new Set(['/fleet/vl-legacy-inventory']);
|
|
69
|
+
|
|
55
70
|
// Route che AGISCONO su una cella o su una sessione, con il punto esatto in cui
|
|
56
71
|
// leggere il bersaglio. `null` = la route e' nota e non ha un bersaglio cella.
|
|
57
72
|
function declaredTarget(req) {
|
|
@@ -60,7 +75,14 @@ function declaredTarget(req) {
|
|
|
60
75
|
const q = req.query || {};
|
|
61
76
|
|
|
62
77
|
// Azioni sul ciclo di vita di una cella: il bersaglio e' `body.cell`.
|
|
63
|
-
|
|
78
|
+
// vl-new-session crea una richiesta persistente per cella: stesso bersaglio,
|
|
79
|
+
// stessa regola.
|
|
80
|
+
if (/^\/fleet\/(up|down|restart|engine|boot|vl-new-session)$/.test(p)) return { cell: b.cell };
|
|
81
|
+
// Lo stato della richiesta di sessione nuova e' una domanda su UNA cella: il
|
|
82
|
+
// bersaglio sta nella query (la route e' una GET, e il corpo non c'e').
|
|
83
|
+
// Senza questa dichiarazione la risposta passerebbe il predicato di scope
|
|
84
|
+
// e porterebbe lo stato di una cella non concessa.
|
|
85
|
+
if (p === '/fleet/vl-new-session-state') return { cell: q.cell };
|
|
64
86
|
// Definire/modificare/rimuovere celle e' una capacita' a se': chi ha uno
|
|
65
87
|
// scope ristretto non deve poter creare la cella che gli manca.
|
|
66
88
|
if (/^\/fleet\/(define-cell|edit-cell|remove-cell|restore-cells|import-cell)$/.test(p)) return { deny: 'scope-cannot-define-cells' };
|
|
@@ -78,6 +100,21 @@ function declaredTarget(req) {
|
|
|
78
100
|
// `originCell`, che e' la PROVENIENZA attestata dal server, non un bersaglio.
|
|
79
101
|
if (p === '/notify' || p.startsWith('/notify/')) return null;
|
|
80
102
|
if (p === '/audio' || p.startsWith('/audio/')) return null;
|
|
103
|
+
// Inventario legacy vl: diagnosi read-only del nodo, nessun bersaglio cella.
|
|
104
|
+
//
|
|
105
|
+
// Ma "nessun bersaglio" vale per la CHIAMATA, non per il METODO: se il corpo
|
|
106
|
+
// nomina una cella, la domanda cambia e non e' piu' una lettura del nodo ma
|
|
107
|
+
// un'azione su una cella — e va negata come qualsiasi altra azione fuori
|
|
108
|
+
// scope. Il predicato qui dichiara il bersaglio solo se il corpo ne porta
|
|
109
|
+
// uno: la domanda "c'e' un bersaglio?" e' gia' risposta dal corpo, quindi la
|
|
110
|
+
// tabella non serve a indovinarla. Una route che non nomina nessuna cella
|
|
111
|
+
// resta la diagnosi del nodo che e'.
|
|
112
|
+
if (p === '/fleet/vl-legacy-inventory') {
|
|
113
|
+
const b2 = (req.body && typeof req.body === 'object') ? req.body : {};
|
|
114
|
+
const q2 = req.query || {};
|
|
115
|
+
const target = scanTargets(b2) || scanTargets(b2.to) || scanTargets(q2);
|
|
116
|
+
return target ? { cell: target } : null;
|
|
117
|
+
}
|
|
81
118
|
return undefined; // route non dichiarata
|
|
82
119
|
}
|
|
83
120
|
|
|
@@ -210,6 +247,14 @@ function createCellScopeGuard({
|
|
|
210
247
|
};
|
|
211
248
|
|
|
212
249
|
function applyScope(req, res, next, scope) {
|
|
250
|
+
// --- letture che si chiedono per intero ------------------------------
|
|
251
|
+
// Prima di ogni altra cosa: qui la domanda non e' "quale cella?" ma
|
|
252
|
+
// "quanto largo e' il tuo scope?". Il corpo e la query non contano
|
|
253
|
+
// (un bersaglio dichiarato non ALLARGA lo scope), e la risposta e' un
|
|
254
|
+
// 403 dichiarato senza che la scansione sia mai avvenuta.
|
|
255
|
+
if (FULL_SCOPE_ROUTES.has(req.path || '') && scope.mode !== 'all') {
|
|
256
|
+
return res.status(403).json({ error: 'fuori dallo scope celle', reason: 'scope-not-full' });
|
|
257
|
+
}
|
|
213
258
|
// --- azioni ---------------------------------------------------------
|
|
214
259
|
const declared = declaredTarget(req);
|
|
215
260
|
if (declared === undefined) {
|
package/lib/diagnostics/store.js
CHANGED
|
@@ -11,6 +11,11 @@ const META_KEYS = new Set([
|
|
|
11
11
|
// Observability (2026-08-28): metadati di routing e chiusure — identita di
|
|
12
12
|
// cella e id di messaggio, MAI contenuto (DENIED_KEY resta la seconda rete).
|
|
13
13
|
'fromCell', 'toCell', 'msgId', 'sessionId', 'durationMs', 'gapMs', 'closeCode', 'exitCode', 'drops',
|
|
14
|
+
// Esito del consumo di una richiesta di sessione nuova: un enum chiuso
|
|
15
|
+
// ('consumed-unknown'), mai un testo libero. Senza questa chiave il
|
|
16
|
+
// marker emesso dal router Fleet verrebbe scartato in fase di sanitizzazione
|
|
17
|
+
// e il fatto resterebbe illeggibile proprio dove si dichiara.
|
|
18
|
+
'newSession',
|
|
14
19
|
]);
|
|
15
20
|
const DENIED_KEY = /(authorization|cookie|token|secret|credential|password|prompt|terminal|argv|command|env|content|payload|file|path|endpoint|url)/i;
|
|
16
21
|
|