/* * SPDX-FileCopyrightText: 2025-2026 Lucio Lelii - ISTI-CNR * SPDX-License-Identifier: AGPL-3.0-or-later * Attribution term under AGPL-3.0 section 7(b): see LICENSE-ADDENDUM. */ :host { display: block; height: 100%; } .execution-viewer-fullscreen { position: fixed; inset: 0; z-index: var(--z-modal); background: #ffffff; padding: 0.25rem; } .execution-header-main { display: block; } .execution-header-details { min-width: 0; } .execution-header-details h2 { display: inline-flex; align-items: center; gap: 8px; } .execution-header-fullscreen-toggle { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 8px; border: 1px solid transparent; background: #e2e8f0; color: #334155; padding: 0; transition: filter 120ms ease; } .execution-header-fullscreen-toggle:hover { filter: brightness(1.05); } .execution-header-fullscreen-toggle mat-icon { font-size: 18px; width: 18px; height: 18px; } .execution-graph-body { position: relative; } .execution-graph-actions { position: absolute; top: 12px; left: 12px; z-index: 4; display: inline-flex; flex-direction: row; gap: 8px; } .execution-graph-actions-right { left: auto; right: 12px; } .execution-action-button { display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border-radius: 12px; border: 1px solid transparent; font-size: 12px; font-weight: 700; line-height: 1; padding: 0; transition: filter 120ms ease, opacity 120ms ease, transform 120ms ease; box-shadow: 0 10px 18px rgba(15, 23, 42, 0.16); } .execution-graph-action-button:hover:not(:disabled) { transform: translateY(-1px); } .execution-action-button mat-icon { font-size: 20px; width: 20px; height: 20px; line-height: 20px; } /* The button has to be a positioning context for the badge, and must not clip it. */ .execution-action-button { position: relative; overflow: visible; } /* * Who answers the flow's human steps - you, or an LLM - is the only difference between the two run * buttons, so both keep the play and the badge carries that difference. It is small on purpose: it * qualifies the play rather than competing with it, and the two sit side by side, which is what * makes either one legible. */ .execution-action-badge { position: absolute; right: -3px; bottom: -3px; display: inline-flex; align-items: center; justify-content: center; width: 17px; height: 17px; border-radius: 999px; border: 1px solid currentColor; background: #ffffff; color: inherit; } .execution-action-badge mat-icon { font-size: 11px; width: 11px; height: 11px; line-height: 11px; color: #0f172a; } .execution-action-button:disabled { opacity: 0.4; cursor: not-allowed; } .execution-action-button-play { background: #15803d; border-color: #166534; color: #ffffff; } .execution-action-button-play:hover:not(:disabled) { filter: brightness(1.1); } .execution-action-button-stop { background: #dc2626; border-color: #b91c1c; color: #ffffff; } .execution-action-button-stop:hover:not(:disabled) { filter: brightness(1.08); } .execution-action-button-resume { background: #4f46e5; border-color: #4338ca; color: #ffffff; } .execution-action-button-resume:hover:not(:disabled) { filter: brightness(1.1); } .execution-action-button-simulate { background: #0c4a6e; border-color: #075985; color: #e0f2fe; } .execution-action-button-simulate:hover:not(:disabled) { filter: brightness(1.1); } .execution-rete-readonly { pointer-events: auto; } :host ::ng-deep .execution-rete-readonly :is( .llm-socket, .hi-socket, .input-socket, .output-socket ) { pointer-events: none; } :host ::ng-deep .execution-rete-readonly .llm-input-info, :host ::ng-deep .execution-rete-readonly .hi-input-info, :host ::ng-deep .execution-rete-readonly .llm-input-info-wrap, :host ::ng-deep .execution-rete-readonly .hi-input-info-wrap { pointer-events: auto; } :host ::ng-deep .execution-rete-readonly :is( .node-delete-btn, .llm-delete-btn, .hi-delete-btn, .llm-edit-btn, .hi-edit-btn, .llm-name-edit-btn, .hi-name-edit-btn ) { display: none !important; } .context-title { font-size: 11px; color: #64748b; font-weight: 600; margin-bottom: 4px; } .context-json { margin: 0; border: 1px solid #e2e8f0; border-radius: 8px; background: #f8fafc; color: #0f172a; font-size: 11px; line-height: 1.35; padding: 8px; white-space: pre-wrap; word-break: break-word; } .execution-aside-tab { flex: 0 0 auto; border: 0; border-bottom: 2px solid transparent; background: transparent; color: #64748b; font-size: 11px; font-weight: 700; padding: 9px 6px; cursor: pointer; white-space: nowrap; } .execution-aside-tabs { flex-wrap: nowrap; } .execution-aside-tab-active { border-bottom-color: #2563eb; color: #1d4ed8; } .execution-aside-tab:disabled { cursor: not-allowed; opacity: 0.45; } .execution-output-modal { margin: 0; border: 1px solid #e2e8f0; border-radius: 10px; background: #f8fafc; color: #0f172a; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 12px; line-height: 1.45; padding: 14px; white-space: pre-wrap; word-break: break-word; } .execution-intermediate-group { border: 1px solid #d9eadf; border-radius: 8px; background: #f7fbf8; padding: 12px; } .execution-intermediate-group-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 800; color: #0f172a; } .execution-intermediate-group-list { margin-top: 10px; display: flex; flex-direction: column; gap: 10px; } .execution-intermediate-item { border: 1px solid #cfe6d5; border-radius: 8px; background: #ffffff; padding: 10px 12px; } .execution-intermediate-item-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; } .execution-intermediate-item-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; font-weight: 800; text-transform: uppercase; color: #15803d; } .execution-intermediate-item-meta { display: flex; flex-wrap: wrap; gap: 4px 8px; margin-top: 3px; color: #64748b; font-size: 10px; font-weight: 700; } .execution-intermediate-preview { margin-top: 8px; white-space: pre-wrap; word-break: break-word; user-select: text; color: #0f172a; font-size: 12px; line-height: 1.45; } .execution-output-group { border: 1px solid #e2e8f0; border-radius: 8px; background: #f8fafc; padding: 12px; } .execution-output-group-title { font-size: 14px; font-weight: 800; color: #0f172a; } .execution-output-group-list { margin-top: 10px; display: flex; flex-direction: column; gap: 10px; } .execution-output-item { border: 1px solid #dbe7f5; border-radius: 8px; background: #ffffff; padding: 10px 12px; } .execution-output-item-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; } .execution-output-item-name { min-width: 0; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #2563eb; } .execution-output-preview { margin-top: 8px; white-space: pre-wrap; word-break: break-word; color: #0f172a; font-size: 12px; line-height: 1.45; } .execution-output-view-btn { flex: 0 0 auto; width: 22px; height: 22px; border: 1px solid #bfdbfe; border-radius: 999px; background: #eff6ff; color: #1d4ed8; display: inline-flex; align-items: center; justify-content: center; padding: 0; } .execution-output-view-btn:hover { background: #dbeafe; } .execution-output-view-btn i { font-size: 11px; } .execution-log-card { border: 1px solid #e2e8f0; border-radius: 12px; background: #f8fafc; padding: 12px; } .execution-log-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; } .execution-log-title-wrap { display: flex; align-items: flex-start; gap: 10px; min-width: 0; } .execution-log-icon { flex: 0 0 auto; width: 20px; height: 20px; font-size: 18px; color: #475569; line-height: 20px; overflow: visible; margin-top: 1px; } .execution-log-title { color: #0f172a; font-size: 13px; font-weight: 700; line-height: 1.35; } .execution-log-meta { display: flex; flex-wrap: wrap; gap: 6px 10px; margin-top: 4px; color: #64748b; font-size: 11px; } .execution-log-actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; } /* Quiet until hovered: one of these sits on every row that carries details. */ .execution-log-details-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; border: none; border-radius: 6px; background: transparent; color: #64748b; cursor: pointer; } .execution-log-details-btn:hover { background: #e2e8f0; color: #0f172a; } .execution-log-details-btn mat-icon { font-size: 16px; width: 16px; height: 16px; line-height: 16px; } .execution-log-level { display: inline-flex; align-items: center; border-radius: 999px; border: 1px solid transparent; font-size: 10px; font-weight: 700; letter-spacing: 0.03em; padding: 3px 8px; text-transform: uppercase; } .execution-log-level-info { background: #e0f2fe; border-color: #bae6fd; color: #0c4a6e; } .execution-log-level-warn { background: #fef3c7; border-color: #fde68a; color: #92400e; } .execution-log-level-error { background: #fee2e2; border-color: #fecaca; color: #991b1b; } .execution-logs-panel { display: flex; flex-direction: column; height: 100%; min-height: 0; } .execution-logs-toolbar { display: flex; justify-content: flex-end; padding: 6px 12px 0; flex: 0 0 auto; } .execution-logs-follow { display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border: 1px solid #cbd5e1; border-radius: 999px; background: #fff; color: #475569; font-size: 11px; font-weight: 600; cursor: pointer; } .execution-logs-follow:hover { border-color: #94a3b8; background: #f8fafc; } /* Held position: stated plainly, since a log that stopped moving on its own looks like a log that stopped. */ .execution-logs-follow-paused { border-color: #fcd34d; background: #fffbeb; color: #92400e; } .execution-logs-follow mat-icon { font-size: 14px; width: 14px; height: 14px; line-height: 14px; } .execution-logs-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; } .execution-bias-variant-context { align-items: center; color: #5b21b6; display: flex; flex-wrap: wrap; font-size: .78rem; gap: .35rem .75rem; margin-top: .45rem; } /* Says what the other run used, while there is still a choice to make about this one. */ .execution-inherited-simulator-notice { background: #f0f9ff; border-left: 3px solid #0284c7; border-radius: .25rem; color: #075985; font-size: .78rem; line-height: 1.45; margin-top: .45rem; padding: .35rem .5rem; } .execution-subflow-context { align-items: center; color: #075985; display: flex; flex-wrap: wrap; font-size: .78rem; gap: .35rem .75rem; margin-top: .45rem; } .execution-graph-action-button-bias { background: #f3e8ff; color: #7e22ce; } .execution-graph-action-button-compare { background: #ccfbf1; color: #0f766e; } .execution-graph-action-button-compare:hover:not(:disabled) { filter: brightness(1.05); } .execution-bias-legend { position: absolute; top: 62px; left: 12px; z-index: 4; display: flex; align-items: center; flex-wrap: wrap; gap: .5rem .75rem; background: #ffffff; border: 1px solid #e2e8f0; border-radius: .5rem; box-shadow: 0 8px 18px rgba(15, 23, 42, 0.12); padding: .4rem .65rem; font-size: .76rem; color: #334155; } .execution-bias-legend-title { font-weight: 700; } .execution-bias-legend-item { display: inline-flex; align-items: center; gap: .3rem; } .execution-bias-legend-dot { display: inline-block; width: 10px; height: 10px; border-radius: 999px; } .execution-bias-legend-dot-active { background: #7c3aed; } .execution-bias-legend-dot-changed { background: #b45309; } .execution-bias-legend-reset { background: #f1f5f9; border: 1px solid #cbd5e1; border-radius: .4rem; color: #0f172a; cursor: pointer; font-size: .76rem; font-weight: 600; padding: .25rem .55rem; } .execution-bias-legend-reset:hover { background: #e2e8f0; } /* * A flow whose last block is wired into an End node puts its answer here rather than in the flow * result, so this reads as the run's conclusion, not as a footnote. */ .execution-outcomes { margin: 0.25rem 0.25rem 0; padding: 0.5rem 0.75rem 0.625rem; border: 1px solid #bbf7d0; border-radius: 6px; background: #f0fdf4; } .execution-outcomes-title { display: flex; align-items: center; gap: 0.375rem; width: 100%; padding: 0; border: none; background: transparent; color: #166534; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em; cursor: pointer; text-align: left; } /* Collapsed, the codes stand in for the payload so the conclusion is never hidden entirely. */ .execution-outcomes-summary { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #15803d; font-weight: 700; text-transform: none; } .execution-outcomes-title .mat-icon { font-size: 16px; width: 16px; height: 16px; line-height: 16px; } .execution-outcome:first-of-type { margin-top: 0.375rem; } .execution-outcome + .execution-outcome { margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px dashed #bbf7d0; } .execution-outcome-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.375rem; } .execution-outcome-code { padding: 0 0.375rem; border-radius: 999px; background: #16a34a; color: #ffffff; font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.02em; } .execution-outcome-label { color: #14532d; font-size: 0.875rem; font-weight: 600; } .execution-outcome-step { color: #4d7c5f; font-size: 0.75rem; } .execution-outcome-payload { margin-top: 0.375rem; padding: 0.375rem 0.5rem; border: 1px solid #dcfce7; border-radius: 4px; background: #ffffff; max-height: 220px; overflow: auto; } .execution-outcome-empty { margin-top: 0.25rem; color: #4d7c5f; font-size: 0.75rem; font-style: italic; } /* Generated documents keep their line breaks; the JSON tree would quote and flatten them. */ .execution-outcome-text { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 0.8125rem; line-height: 1.45; color: #1f2937; } /* * Only what changes how a result should be read stays in the header; ids, simulator descriptors * and probe internals are diagnostics and live behind Details. */ .execution-header-badges { display: flex; align-items: center; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.125rem; } .execution-badge { padding: 0 0.375rem; border-radius: 999px; font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; cursor: help; } .execution-badge-simulated { background: #e0f2fe; color: #075985; } .execution-badge-bias { background: #fee2e2; color: #b91c1c; } .execution-badge-subflow { background: #ede9fe; color: #6d28d9; } .execution-header-details-toggle { display: flex; align-items: center; gap: 0.125rem; margin-left: auto; padding: 0; border: none; background: transparent; color: #64748b; font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; cursor: pointer; } .execution-header-details-toggle:hover { color: #334155; } .execution-header-details-toggle .mat-icon { font-size: 16px; width: 16px; height: 16px; line-height: 16px; } .execution-header-detail-list { margin-top: 0.25rem; padding-top: 0.25rem; border-top: 1px dashed #e2e8f0; } .execution-loop { border: 1px solid #ddd6fe; border-radius: 10px; background: #faf5ff; padding: 10px; } .execution-loop-head { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 8px; color: #5b21b6; } .execution-loop-head .bi { font-size: 16px; line-height: 1.2; } .execution-loop-title { font-size: 13px; font-weight: 700; color: #3b0764; } .execution-loop-meta { font-size: 11px; color: #6d28d9; } .execution-round { border: 1px solid #e9d5ff; border-radius: 8px; background: #fff; margin-top: 6px; } .execution-round-summary { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 7px 10px; cursor: pointer; font-size: 12px; } .execution-round-number { font-weight: 700; color: #334155; } .execution-round-outcome { font-size: 11px; color: #64748b; text-align: right; } .execution-round-outcome[data-outcome='left'] { color: #047857; } .execution-round-outcome[data-outcome='limit-reached'], .execution-round-outcome[data-outcome='failed'] { color: #b91c1c; } .execution-round-outcome[data-outcome='in-progress'] { color: #6d28d9; } .execution-round-steps { display: flex; flex-direction: column; gap: 8px; padding: 0 10px 10px; } .execution-round-step { border-top: 1px solid #f1f5f9; padding-top: 8px; } .execution-round-step-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 4px; } .execution-round-step-title { font-size: 12px; font-weight: 600; color: #1e293b; } .execution-round-status { font-size: 10px; font-weight: 700; letter-spacing: 0.02em; border-radius: 999px; padding: 1px 7px; } .execution-round-status-done { background: #ecfdf5; color: #047857; } .execution-round-status-failed { background: #fef2f2; color: #b91c1c; } .execution-round-status-idle { background: #f1f5f9; color: #64748b; } .execution-round-status-active { background: #f5f3ff; color: #6d28d9; } .execution-round-input { margin-top: 4px; } .execution-round-input-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; } /* A JSON value in a preview: the first level, a few entries - the whole tree opens with the eye. */ .execution-json-preview { display: block; margin-top: 4px; max-height: 14rem; overflow: auto; border-radius: 6px; background: #f8fafc; padding: 6px 8px; } /* * A tree grows and shrinks as its nodes are opened and closed. Sized to its content, the modal - * centred on the page - would jump with every click; at a fixed height only its content scrolls. */ .execution-json-modal { height: 90vh; } /* Stays in the corner while a long payload scrolls under it. */ .execution-outcome-copy { position: sticky; top: 0; float: right; z-index: 1; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin-left: 6px; border: 1px solid #d1fae5; border-radius: 6px; background: #fff; color: #475569; cursor: pointer; } .execution-outcome-copy:hover { background: #f0fdf4; } .execution-outcome-copy .mat-icon { width: 16px; height: 16px; font-size: 16px; }