/* AlgoLab — connect-nodes page (algo_page.py + agx_editor.js).
   Loaded globally by Dash from /assets: every rule is scoped under .agx-page.
   Shared node look: panels rgba(0,0,0,0.6), chips rgba(255,255,255,0.06),
   radius 10px, text #e8e8e8, muted #9fb3c8, headings #cfefff, accent #f0a030. */

.agx-page { color: #e8e8e8; font-size: 13px; height: calc(100vh - 84px); padding: 6px 1.2vw 8px; box-sizing: border-box; }
.agx-page * { box-sizing: border-box; }
.agx-main { display: flex; gap: 10px; height: 100%; }
.agx-root { flex: 1; min-width: 0; height: 100%; }
.agx-side { width: 27vw; min-width: 340px; flex: 0 0 auto; height: 100%; overflow-y: auto; padding-right: 2px; }

.agx { display: flex; gap: 10px; height: 100%; user-select: none; }

/* ---------- palette ---------------------------------------------------------- */
.agx-pal { width: 236px; flex: 0 0 236px; background: rgba(0,0,0,0.6); border: 1px solid rgba(255,255,255,0.07);
           border-radius: 10px; display: flex; flex-direction: column; overflow: hidden; }
.agx-ptabs { display: flex; gap: 4px; padding: 8px 8px 4px; }
.agx-ptab { flex: 1; background: rgba(255,255,255,0.05); color: #9fb3c8; border: 1px solid rgba(255,255,255,0.08);
            border-radius: 8px; font-size: .78rem; padding: 4px 0; }
.agx-ptab.on { color: #cfefff; border-color: rgba(240,160,48,0.7); background: rgba(240,160,48,0.10); font-weight: 600; }
.agx-page input.agx-search, .agx-page input.agx-in { background: rgba(255,255,255,0.06); color: #e8e8e8; border: 1px solid rgba(255,255,255,0.12);
            border-radius: 8px; padding: 4px 8px; font-size: .8rem; outline: none; width: 100%; }
.agx-search { margin: 4px 8px 6px; width: calc(100% - 16px) !important; }
.agx-page input:focus { border-color: #f0a030; }
.agx-pal-list { overflow-y: auto; flex: 1; padding: 0 6px 10px; }
.agx-cat { display: flex; align-items: center; gap: 7px; padding: 6px; cursor: pointer; border-radius: 8px; font-size: .78rem; color: #cfefff; }
.agx-cat:hover { background: rgba(255,255,255,0.05); }
.agx-cl { flex: 1; }
.agx-cn, .agx-chev { color: #6f8295; font-size: .68rem; }
.agx-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: 0 0 9px; margin-right: 5px; }
.agx-items { padding: 0 0 6px 8px; }
.agx-item { display: flex; align-items: center; gap: 7px; padding: 3px 6px; margin: 2px 0; border-radius: 7px; cursor: pointer;
            font-size: .76rem; background: rgba(255,255,255,0.035); color: #e8e8e8; }
.agx-item.pal { cursor: grab; }
.agx-item:hover { background: rgba(255,255,255,0.09); }
.agx-item.on { background: rgba(240,160,48,0.12); outline: 1px solid rgba(240,160,48,0.5); }
.agx-it { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agx-iid { color: #6f8295; font-family: Consolas, monospace; font-size: .7rem; min-width: 16px; }
.agx-sdot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 8px; }
.agx-bar { width: 3px; height: 14px; border-radius: 2px; flex: 0 0 3px; }
.agx-add { color: #6f8295; font-weight: 700; padding: 0 3px; cursor: pointer; }
.agx-add:hover { color: #f0a030; }
.agx-tag { font-size: .58rem; color: #9fb3c8; border: 1px solid rgba(159,179,200,.4); border-radius: 5px; padding: 0 3px; }
.agx-datacard { background: rgba(91,141,239,0.10); border: 1px solid rgba(91,141,239,0.35); border-radius: 10px; padding: 8px 9px;
                font-size: .74rem; color: #cfdcf5; margin: 2px 2px 8px; }
.agx-datacard .agx-btn { margin-top: 6px; width: 100%; }
.agx-note { color: #9fb3c8; font-size: .74rem; line-height: 1.45; padding: 6px; }
.agx-note b { color: #cfefff; }

/* ---------- canvas ------------------------------------------------------------ */
.agx-centre { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.agx-bar2 { display: flex; justify-content: space-between; align-items: flex-end; gap: 10px; padding-bottom: 4px; }
.agx-algo { color: #cfefff; font-weight: 600; font-size: .95rem; padding-left: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.agx-tools { display: flex; gap: 4px; align-items: center; }
.agx-tb { background: rgba(255,255,255,0.06); color: #e8e8e8; border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; padding: 2px 9px; font-size: .74rem; }
.agx-tb:hover { border-color: #f0a030; }
.agx-tb:disabled { opacity: .35; }
.agx-zoom { color: #9fb3c8; font-size: .72rem; min-width: 36px; text-align: center; }
.agx-canvas { flex: 1; position: relative; overflow: hidden; border-radius: 10px; outline: none; background-color: rgba(0,0,0,0.6);
              border: 1px solid rgba(255,255,255,0.07); background-image: radial-gradient(rgba(255,255,255,0.09) 1px, transparent 1px); }
.agx-world { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.agx-svg { position: absolute; left: 0; top: 0; width: 1px; height: 1px; overflow: visible; }
.agx-edge { fill: none; stroke-width: 2.2; opacity: .8; pointer-events: none; }
.agx-edge.loose { stroke-dasharray: 6 5; opacity: .7; }
.agx-edge.pending { stroke-dasharray: 4 4; opacity: .9; }
.agx-edge.sel { stroke-width: 3.4; opacity: 1; }
.agx-edge.temp { stroke-dasharray: 5 4; opacity: 1; }
.agx-elabel { fill: #9fb3c8; font-size: 10px; text-anchor: middle; pointer-events: none; }
.agx-hit { fill: none; stroke: transparent; stroke-width: 12; pointer-events: stroke; cursor: pointer; }
.agx-nodes { position: absolute; left: 0; top: 0; }
.agx-node { position: absolute; background: #141b23; border: 1px solid rgba(255,255,255,0.12); border-left: 4px solid;
            border-radius: 10px; box-shadow: 0 3px 12px rgba(0,0,0,.5); cursor: move; }
.agx-node.sel { box-shadow: 0 0 0 2px #f0a030, 0 3px 14px rgba(0,0,0,.55); }
.agx-node.busy { animation: agx-pulse 1.2s ease-in-out infinite; }
@keyframes agx-pulse { 50% { box-shadow: 0 0 0 3px rgba(240,160,48,.55), 0 3px 12px rgba(0,0,0,.5); } }
.agx-nh { display: flex; align-items: center; gap: 7px; padding: 6px 9px 0 8px; }
.agx-idc { color: #0b1016; font-weight: 700; font-size: .66rem; border-radius: 6px; padding: 0 5px; line-height: 1.5; }
.agx-nt { flex: 1; font-weight: 600; color: #e8f4ff; font-size: .82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.agx-st { font-size: .8rem; }
.agx-ns { padding: 1px 9px 0 8px; color: #9fb3c8; font-size: .68rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.agx-nsn { color: #6f8295; }
.agx-warn { color: #f0c080; margin-left: 6px; }
.agx-row { position: absolute; left: 0; right: 0; height: 21px; display: flex; justify-content: space-between; align-items: center;
           padding: 0 12px; font-size: .7rem; border-top: 1px solid rgba(255,255,255,0.04); }
.agx-rl { color: #cfdcea; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60%; }
.agx-rl.empty { color: #f0c080; }
.agx-rr { color: #9fb3c8; white-space: nowrap; }
/* a port = the glyph of the kind that travels through it (an inline SVG drawn by agx_editor.js glyph(): shape and
   colour per contract kind). Output: filled. Input: outlined, filled once wired; a slot that takes several sources
   has a second outline behind. The 12 px box is the footprint, ::before only widens the target. */
.agx-port { position: absolute; width: 12px; height: 12px; }
.agx-port::before { content: ''; position: absolute; inset: -4px; }
.agx-port.in { left: -8px; }
.agx-port.out { right: -8px; cursor: crosshair; }
.agx-gl { display: block; overflow: visible; pointer-events: none; transition: transform .12s; }
.agx-gl path { stroke-width: 1.7; stroke-linejoin: round; stroke-linecap: round; }
.agx-gl path.agx-gl-b { fill: #0c1116; opacity: .6; }
.agx-port:hover .agx-gl { transform: scale(1.25); filter: brightness(1.35); }
/* while a wire is dragged (or a legend kind is lit): what fits glows in the colour of the kind that travels
   (currentColor, set by mark()), what does not fit steps back */
.agx-canvas.marking .agx-node { transition: opacity .15s; }
.agx-node.dim { opacity: .32; }
.agx-port.nofit, .agx-rl.nofit { opacity: .3; }
.agx-rl.fit, .agx-rl.conv { color: #fff; }
.agx-port.fit, .agx-port.conv, .agx-port.lit { z-index: 2; }
.agx-port.fit .agx-gl, .agx-port.lit .agx-gl { transform: scale(1.45); filter: drop-shadow(0 0 2px currentColor) drop-shadow(0 0 5px currentColor); }
.agx-port.conv .agx-gl { transform: scale(1.25); filter: drop-shadow(0 0 2px currentColor); }
.agx-port.fit::after, .agx-port.conv::after { content: ''; position: absolute; inset: -6px; border-radius: 50%; border: 1.6px solid currentColor;
                                              pointer-events: none; }
.agx-port.fit::after { animation: agx-ring 1.1s ease-in-out infinite; }
.agx-port.conv::after { border-style: dashed; opacity: .7; }
.agx-port.fit:hover .agx-gl, .agx-port.conv:hover .agx-gl { transform: scale(1.8); }
@keyframes agx-ring { 50% { transform: scale(1.2); opacity: .5; } }
.agx-hint { position: absolute; display: none; z-index: 6; background: rgba(12,17,22,.95); color: #e8e8e8; border: 1px solid #9fb3c8; border-left-width: 3px;
            border-radius: 7px; padding: 2px 8px; font-size: .72rem; white-space: nowrap; pointer-events: none; }
.agx-hint.show { display: block; }
.agx-hint.bad { color: #ffb4ac; }
.agx-emptyhint { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #45596d; font-size: 1rem; pointer-events: none; }
.agx-flash { position: absolute; left: 50%; bottom: 30px; transform: translateX(-50%); background: rgba(240,160,48,.16); color: #f5d6a3;
             border-radius: 10px; padding: 5px 14px; font-size: .78rem; opacity: 0; transition: opacity .3s; pointer-events: none; max-width: 80%; text-align: center; }
.agx-flash.show { opacity: 1; }
.agx-flash.bad { background: rgba(60,16,14,.92); color: #ffb4ac; border: 1px solid rgba(255,123,114,.55); }
/* legend: the node families inside the canvas (never a mouse target); "what travels" (one glyph per kind; a click
   lights its ports) is a strip under the canvas, so that a chip never covers a card nor takes a drop meant for a port */
.agx-legend { position: absolute; left: 10px; bottom: 8px; display: flex; gap: 12px; font-size: .68rem; color: #9fb3c8; pointer-events: none; }
.agx-legend > span { display: inline-flex; align-items: center; }
.agx-kinds { flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 1px 3px; padding: 4px 6px 0; font-size: .68rem; color: #9fb3c8; }
.agx-kinds > span { display: inline-flex; align-items: center; }
.agx-leg-t { color: #6f8295; font-style: italic; margin-right: 5px; }
.agx-leg-k { gap: 4px; padding: 0 5px; border: 1px solid transparent; border-radius: 7px; line-height: 1.5; cursor: pointer; }
.agx-leg-k:hover { color: #e8e8e8; background: rgba(255,255,255,0.06); }
.agx-leg-k.on { background: rgba(255,255,255,0.08); }

/* ---------- side panel -------------------------------------------------------- */
.agx-card { background: rgba(0,0,0,0.6); border: 1px solid rgba(255,255,255,0.07); border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; }
.agx-card-title { color: #cfefff; font-weight: 600; font-size: .86rem; margin-bottom: 4px; }
.agx-card-sub { color: #9fb3c8; font-size: .72rem; margin: 2px 0 6px; line-height: 1.4; }
.agx-chips { display: flex; gap: 6px; align-items: center; margin-bottom: 7px; flex-wrap: wrap; }
.agx-chip { font-size: .66rem; border: 1px solid; border-radius: 8px; padding: 0 7px; line-height: 1.6; }
.agx-chip.soft { border-color: rgba(255,255,255,0.15); color: #cfdcea; background: rgba(255,255,255,0.05); }
.agx-nid { color: #6f8295; font-size: .7rem; margin-left: auto; }
.agx-page input.agx-title-in { font-weight: 600; font-size: .95rem; color: #cfefff; }
.agx-code { font-family: Consolas, monospace; font-size: .7rem; color: #f0a030; margin: 4px 0 2px; word-break: break-word; }
.agx-btns { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 9px; }
.agx-btn { flex: 1 1 auto; background: rgba(255,255,255,0.06); color: #e8e8e8; border: 1px solid rgba(255,255,255,0.12); border-radius: 8px;
           padding: 4px 8px; font-size: .76rem; white-space: nowrap; }
.agx-btn:hover { border-color: #f0a030; }
.agx-btn.acc { border-color: rgba(240,160,48,0.6); color: #f5d6a3; }
.agx-btn.danger:hover, .agx-btn.armed { border-color: #ff7b72; color: #ffb4ac; }
.agx-btn.armed { background: rgba(255,90,80,0.14); }
.agx-slot { padding: 6px 0; border-top: 1px solid rgba(255,255,255,0.06); }
.agx-slot:first-of-type { border-top: none; }
.agx-slot-t { color: #9fb3c8; font-size: .7rem; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 3px; }
.agx-feed { display: flex; align-items: center; gap: 4px; font-size: .76rem; background: rgba(255,255,255,0.04); border-radius: 7px;
            padding: 2px 7px; margin: 2px 0; }
.agx-feed > span:nth-child(2) { flex: 1; }
.agx-x { color: #6f8295; cursor: pointer; padding: 0 3px; }
.agx-x:hover { color: #ff9b92; }
.agx-empty { color: #6f8295; font-size: .72rem; font-style: italic; }
.agx-out { margin: 3px 0 6px; }
.agx-out .agx-chip { display: inline-flex; align-items: center; gap: 5px; margin-bottom: 1px; }
.agx-slot-t .agx-gl { display: inline-block; vertical-align: -1px; margin-right: 6px; }
.agx-feed .agx-gl { flex: 0 0 auto; margin-right: 3px; }
.agx-takes { text-transform: none; letter-spacing: 0; color: #6f8295; margin-left: 8px; }
.agx-edgedesc { font-size: .78rem; line-height: 1.6; color: #cfdcea; }
.agx-edgedesc b { color: #e8f4ff; }
.agx-kpis { display: flex; gap: 6px; }
.agx-kpi { flex: 1; background: rgba(255,255,255,0.05); border-radius: 8px; padding: 5px 4px; text-align: center; }
.agx-kv { font-size: 1.05rem; font-weight: 600; color: #cfefff; }
.agx-kl { font-size: .62rem; color: #9fb3c8; }
.agx-statrow { display: flex; align-items: center; gap: 7px; font-size: .76rem; padding: 3px 5px; border-radius: 7px; cursor: pointer; }
.agx-statrow:hover { background: rgba(255,255,255,0.06); }
.agx-stl { font-size: .68rem; }
.agx-help { color: #9fb3c8; font-size: .73rem; line-height: 1.6; }
.agx-help b { color: #cfefff; font-weight: 600; }
.agx-help i { color: #cfdcea; }

/* ---------- kind glyphs outside the editor --------------------------------------- */
/* The kind chips drawn by Dash (idea_nodes._kind_chip, the item docs of the Data page) show the same glyph as the
   ports: <span class="agx-kg <shape>"> in the kind's colour (currentColor). Shapes = the GLYPH table of agx_editor.js,
   names = contracts.KINDS[kind]['shape']; unscoped on purpose (the docs are not inside .agx-page). */
.agx-kg { display: inline-block; width: 8px; height: 8px; margin-right: 4px; vertical-align: -1px; background: currentColor; }
.agx-kg.circle { border-radius: 50%; }
.agx-kg.ring { border-radius: 50%; background: none; border: 2.5px solid currentColor; box-sizing: border-box; }
.agx-kg.diamond { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
.agx-kg.square { border-radius: 1px; }
.agx-kg.pentagon { clip-path: polygon(50% 0, 100% 38%, 81% 100%, 19% 100%, 0 38%); }
.agx-kg.arrow { clip-path: polygon(6% 0, 100% 50%, 6% 100%); }
.agx-kg.triangle { clip-path: polygon(50% 2%, 100% 96%, 0 96%); }
.agx-kg.hexagon { clip-path: polygon(0 50%, 25% 4%, 75% 4%, 100% 50%, 75% 96%, 25% 96%); }
.agx-kg.pill { width: 10px; height: 5px; border-radius: 3px; vertical-align: 1px; }
.agx-kg.tag { clip-path: polygon(0 50%, 36% 10%, 100% 10%, 100% 90%, 36% 90%); }
.agx-kg.plus { clip-path: polygon(33% 0, 67% 0, 67% 33%, 100% 33%, 100% 67%, 67% 67%, 67% 100%, 33% 100%, 33% 67%, 0 67%, 0 33%, 33% 33%); }
.agx-kg.interval { clip-path: polygon(22% 0, 78% 0, 78% 12%, 57% 12%, 57% 24%, 84% 50%, 57% 76%, 57% 88%, 78% 88%, 78% 100%, 22% 100%, 22% 88%,
                                      43% 88%, 43% 76%, 16% 50%, 43% 24%, 43% 12%, 22% 12%); }

/* the node modules' own input controls, rendered inside the "Input mapping" card */
#ag_inputs_card #input_controls > div { margin-left: 0 !important; margin-top: 4px !important; }
#ag_inputs_card .div-hyperpar { border-color: rgba(255,255,255,0.08); border-radius: 10px; background-color: rgba(255,255,255,0.03) !important; }
