Major changes: logic add to panel, local variables, panel histor, users management...
This commit is contained in:
+677
-249
@@ -164,6 +164,42 @@ body {
|
||||
background: #374151;
|
||||
}
|
||||
|
||||
/* ── User identity chip ──────────────────────────────────────────────────── */
|
||||
.user-chip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.75rem;
|
||||
padding: 0.2rem 0.6rem;
|
||||
border-radius: 9999px;
|
||||
background: #1e293b;
|
||||
color: #cbd5e1;
|
||||
border: 1px solid #334155;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ── Access denied screen ────────────────────────────────────────────────── */
|
||||
.access-denied {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
color: #e2e8f0;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.access-denied h1 {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #fca5a5;
|
||||
}
|
||||
|
||||
.access-denied p {
|
||||
max-width: 32rem;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
@@ -257,8 +293,17 @@ body {
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.panel-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
padding: 0.5rem 0.6rem;
|
||||
border-bottom: 1px solid #2d3748;
|
||||
@@ -834,6 +879,15 @@ body {
|
||||
background: #1e40af;
|
||||
}
|
||||
|
||||
/* Read-only: user lacks permission to write this signal (.sv-select shares
|
||||
.sv-input). */
|
||||
.sv-input:disabled,
|
||||
.sv-btn:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.sv-btn:disabled:hover { background: #2563eb; }
|
||||
|
||||
/* ── Button widget ─────────────────────────────────────────────────────── */
|
||||
|
||||
.button-widget {
|
||||
@@ -868,6 +922,19 @@ body {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
/* Read-only: user lacks permission to write this signal. */
|
||||
.button-widget .btn:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.button-widget .btn:disabled:hover {
|
||||
background: #1e3a5f;
|
||||
border-color: #2d5a9e;
|
||||
}
|
||||
.button-widget .btn:disabled:active {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* ── ImageWidget ───────────────────────────────────────────────────────── */
|
||||
|
||||
.image-widget {
|
||||
@@ -1001,6 +1068,7 @@ body {
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-family: system-ui, sans-serif;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.toolbar-btn:hover { background: #374151; }
|
||||
@@ -1042,6 +1110,384 @@ body {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* ── Center column tabs (Layout / Logic) ────────────────────────────────── */
|
||||
|
||||
.edit-center {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.center-tabs {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
background: #0f1117;
|
||||
border-bottom: 1px solid #1e2433;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.center-tab {
|
||||
padding: 0.4rem 1rem;
|
||||
font-size: 0.8rem;
|
||||
color: #94a3b8;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-right: 1px solid #1e2433;
|
||||
border-bottom: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.center-tab:hover { color: #e2e8f0; background: #161b27; }
|
||||
|
||||
.center-tab-active {
|
||||
color: #e2e8f0;
|
||||
border-bottom-color: #3b82f6;
|
||||
background: #161b27;
|
||||
}
|
||||
|
||||
/* ── Logic flow editor (Node-RED style) ─────────────────────────────────── */
|
||||
|
||||
.flow-editor {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Palette of node types to add */
|
||||
.flow-palette {
|
||||
width: 10rem;
|
||||
flex: 0 0 auto;
|
||||
border-right: 1px solid #1e2433;
|
||||
background: #0f1117;
|
||||
padding: 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.flow-palette-toolbar {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
.flow-palette-toolbar .toolbar-btn { flex: 1; }
|
||||
|
||||
.flow-palette-title {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.flow-palette-btn {
|
||||
text-align: left;
|
||||
padding: 0.4rem 0.6rem;
|
||||
font-size: 0.8rem;
|
||||
color: #e2e8f0;
|
||||
background: #161b27;
|
||||
border: 1px solid #1e2433;
|
||||
border-left-width: 3px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.flow-palette-btn:hover { background: #1c2230; }
|
||||
.flow-palette-trigger { border-left-color: #f59e0b; }
|
||||
.flow-palette-gate { border-left-color: #a855f7; }
|
||||
.flow-palette-flow { border-left-color: #10b981; }
|
||||
.flow-palette-action { border-left-color: #3b82f6; }
|
||||
.flow-palette-hint { margin-top: 0.5rem; font-size: 0.7rem; line-height: 1.4; }
|
||||
.flow-palette-hint code { background: #1e2433; padding: 0 0.2em; border-radius: 3px; }
|
||||
|
||||
/* Scrollable node canvas */
|
||||
.flow-canvas {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
background:
|
||||
repeating-linear-gradient(0deg, transparent 0 19px, #161b2733 19px 20px),
|
||||
repeating-linear-gradient(90deg, transparent 0 19px, #161b2733 19px 20px),
|
||||
#0b0e14;
|
||||
}
|
||||
|
||||
.flow-canvas-inner {
|
||||
position: relative;
|
||||
width: 125rem;
|
||||
height: 87.5rem;
|
||||
}
|
||||
|
||||
.flow-wires {
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
width: 100%; height: 100%;
|
||||
pointer-events: none;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.flow-wire {
|
||||
fill: none;
|
||||
stroke: #475569;
|
||||
stroke-width: 2;
|
||||
pointer-events: stroke;
|
||||
cursor: pointer;
|
||||
}
|
||||
.flow-wire:hover { stroke: #64748b; }
|
||||
.flow-wire-selected { stroke: #ef4444; stroke-width: 2.5; }
|
||||
.flow-wire-pending { stroke: #3b82f6; stroke-dasharray: 5 4; }
|
||||
|
||||
/* Node block */
|
||||
.flow-node {
|
||||
position: absolute;
|
||||
background: #161b27;
|
||||
border: 1px solid #1e2433;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 6px #0006;
|
||||
cursor: move;
|
||||
user-select: none;
|
||||
}
|
||||
.flow-node-trigger { border-top: 3px solid #f59e0b; }
|
||||
.flow-node-gate { border-top: 3px solid #a855f7; }
|
||||
.flow-node-flow { border-top: 3px solid #10b981; }
|
||||
.flow-node-action { border-top: 3px solid #3b82f6; }
|
||||
.flow-node-selected { border-color: #3b82f6; box-shadow: 0 0 0 2px #3b82f680; }
|
||||
|
||||
.flow-node-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.3rem 0.5rem;
|
||||
}
|
||||
.flow-node-title { font-size: 0.78rem; font-weight: 600; color: #e2e8f0; }
|
||||
.flow-node-del {
|
||||
background: none; border: none; color: #64748b;
|
||||
cursor: pointer; font-size: 0.75rem; line-height: 1; padding: 0;
|
||||
}
|
||||
.flow-node-del:hover { color: #ef4444; }
|
||||
|
||||
.flow-node-body {
|
||||
padding: 0 0.5rem 0.4rem;
|
||||
font-size: 0.7rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Ports — input/output positions are set inline (in rem-scaled px) so they
|
||||
stay aligned with the node geometry on any root font size. */
|
||||
.flow-port {
|
||||
position: absolute;
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
border-radius: 50%;
|
||||
background: #0b0e14;
|
||||
border: 2px solid #64748b;
|
||||
cursor: crosshair;
|
||||
}
|
||||
.flow-port:hover { border-color: #3b82f6; background: #3b82f6; }
|
||||
.flow-port-then { border-color: #10b981; }
|
||||
.flow-port-body { border-color: #10b981; }
|
||||
.flow-port-else { border-color: #ef4444; }
|
||||
|
||||
.flow-port-label {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
font-size: 0.6rem;
|
||||
color: #64748b;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Expression field: signal-insert helper row */
|
||||
.flow-expr-insert {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
margin-top: 0.35rem;
|
||||
}
|
||||
.flow-expr-insert > * { flex: 1; min-width: 0; }
|
||||
.prop-input-error { border-color: #ef4444; }
|
||||
|
||||
/* Inspector */
|
||||
.flow-inspector {
|
||||
width: 15rem;
|
||||
flex: 0 0 auto;
|
||||
border-left: 1px solid #1e2433;
|
||||
background: #0f1117;
|
||||
padding: 0.75rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Local-variable editor in the palette */
|
||||
.flow-localvars {
|
||||
margin-top: 0.5rem;
|
||||
border-top: 1px solid #1e2433;
|
||||
padding-top: 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
.flow-localvars-empty { padding: 0; }
|
||||
.flow-localvar-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.35rem;
|
||||
padding: 0.2rem 0.4rem;
|
||||
background: #161b27;
|
||||
border: 1px solid #1e2433;
|
||||
border-left: 3px solid #14b8a6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.flow-localvar-name {
|
||||
font-size: 0.78rem;
|
||||
color: #e2e8f0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.flow-localvar-add { text-align: center; border-left-color: #14b8a6; }
|
||||
.flow-localvar-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
.flow-localvar-actions {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.flow-localvar-actions .panel-btn { flex: 1; }
|
||||
|
||||
/* ── History pane ───────────────────────────────────────────────────────── */
|
||||
|
||||
.history-pane {
|
||||
width: 280px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #11151f;
|
||||
border-left: 1px solid #1f2733;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.history-pane-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 12px;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid #1f2733;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
.history-save-row {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
padding: 10px 12px;
|
||||
border-bottom: 1px solid #1f2733;
|
||||
}
|
||||
|
||||
.history-tag-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
background: #0a0d14;
|
||||
border: 1px solid #2a3543;
|
||||
border-radius: 4px;
|
||||
color: #e2e8f0;
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.history-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.history-empty {
|
||||
padding: 16px 12px;
|
||||
color: #64748b;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.history-item {
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #1f2733;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 6px;
|
||||
background: #0e1219;
|
||||
}
|
||||
|
||||
.history-item-current {
|
||||
border-color: #2563eb;
|
||||
background: #0f1830;
|
||||
}
|
||||
|
||||
.history-item-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.history-version {
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
color: #93c5fd;
|
||||
}
|
||||
|
||||
.history-tag {
|
||||
font-size: 11px;
|
||||
padding: 1px 6px;
|
||||
border-radius: 10px;
|
||||
background: #1e293b;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
.history-current-badge {
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
padding: 1px 6px;
|
||||
border-radius: 10px;
|
||||
background: #2563eb;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.history-item-meta {
|
||||
font-size: 11px;
|
||||
color: #64748b;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.history-item-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.history-action-btn {
|
||||
flex: 1 1 auto;
|
||||
font-size: 11px;
|
||||
padding: 3px 6px;
|
||||
background: #1e293b;
|
||||
border: 1px solid #2a3543;
|
||||
border-radius: 4px;
|
||||
color: #cbd5e1;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.history-action-btn:hover {
|
||||
background: #2a3543;
|
||||
}
|
||||
|
||||
/* ── Edit Canvas ────────────────────────────────────────────────────────── */
|
||||
|
||||
.edit-canvas-container {
|
||||
@@ -1792,6 +2238,47 @@ body {
|
||||
.iface-delete { color: #ef4444 !important; }
|
||||
.iface-delete:hover { background: rgba(239, 68, 68, 0.15) !important; }
|
||||
|
||||
/* ── Panel sharing / folders (access control) ───────────────────────────── */
|
||||
|
||||
.iface-badge {
|
||||
display: inline-block;
|
||||
margin-left: 6px;
|
||||
padding: 0 4px;
|
||||
font-size: 0.6rem;
|
||||
line-height: 1.3;
|
||||
color: #94a3b8;
|
||||
background: #1e293b;
|
||||
border: 1px solid #334155;
|
||||
border-radius: 3px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.iface-folder { list-style: none; }
|
||||
|
||||
.iface-folder-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.iface-folder-name {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
color: #cbd5e1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.iface-folder:hover .iface-item-actions { display: flex; }
|
||||
|
||||
.iface-sublist {
|
||||
margin-left: 0.75rem;
|
||||
border-left: 1px solid #2d3748;
|
||||
padding-left: 0.4rem;
|
||||
}
|
||||
|
||||
/* ── Phase 7 additions ───────────────────────────────────────────────────── */
|
||||
|
||||
/* Rubber-band selection rectangle */
|
||||
@@ -2395,39 +2882,6 @@ kbd {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.view-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
padding: 0 0.5rem;
|
||||
height: 2.25rem;
|
||||
background: #0f1117;
|
||||
border-bottom: 1px solid #1e293b;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.view-tab {
|
||||
background: none;
|
||||
border: none;
|
||||
border-bottom: 2px solid transparent;
|
||||
color: #64748b;
|
||||
font-size: 0.82rem;
|
||||
padding: 0 0.75rem;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
transition: color 0.15s, border-color 0.15s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.view-tab:hover {
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
.view-tab-active {
|
||||
color: #e2e8f0;
|
||||
border-bottom-color: #4a9eff;
|
||||
}
|
||||
|
||||
/* ── InfoPanel ─────────────────────────────────────────────────────────── */
|
||||
|
||||
.info-panel {
|
||||
@@ -2527,220 +2981,6 @@ kbd {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* ── PlotPanel ─────────────────────────────────────────────────────────── */
|
||||
|
||||
.plot-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
background: #0f1117;
|
||||
}
|
||||
|
||||
.plot-panel-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0 0.75rem;
|
||||
height: 2.5rem;
|
||||
background: #0f1117;
|
||||
border-bottom: 1px solid #1e293b;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.plot-panel-title {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
color: #94a3b8;
|
||||
margin-right: 0.5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.plot-window-btns {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.plot-panel-body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.plot-empty-hint {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #475569;
|
||||
font-size: 0.88rem;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.plot-panel-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.plot-panel-legend {
|
||||
width: 160px;
|
||||
flex-shrink: 0;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #1e293b;
|
||||
padding: 0.5rem 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.plot-legend-item {
|
||||
padding: 0.4rem 0.6rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.plot-legend-item:hover { background: #1a1f2e; }
|
||||
|
||||
.plot-legend-hdr {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.plot-legend-swatch {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.plot-legend-name {
|
||||
flex: 1;
|
||||
font-size: 0.75rem;
|
||||
color: #cbd5e1;
|
||||
font-family: ui-monospace, monospace;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.plot-legend-icon-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #475569;
|
||||
cursor: pointer;
|
||||
font-size: 0.75rem;
|
||||
padding: 0 0.15rem;
|
||||
line-height: 1;
|
||||
opacity: 0.6;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.plot-legend-icon-btn:hover { opacity: 1; color: #94a3b8; }
|
||||
.plot-legend-icon-btn.active { opacity: 1; color: #4a9eff; }
|
||||
|
||||
/* kept for back-compat — remove button is now .plot-legend-icon-btn */
|
||||
.plot-legend-rm {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #475569;
|
||||
cursor: pointer;
|
||||
font-size: 0.7rem;
|
||||
padding: 0 0.15rem;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.plot-legend-rm:hover { opacity: 1; color: #f87171; }
|
||||
|
||||
/* ── Per-signal style editor ────────────────────────────────────────────── */
|
||||
|
||||
.plot-style-editor {
|
||||
margin-top: 0.4rem;
|
||||
padding-top: 0.4rem;
|
||||
border-top: 1px solid #1e293b;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.plot-style-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.plot-style-label {
|
||||
font-size: 0.68rem;
|
||||
color: #64748b;
|
||||
width: 2.8rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.plot-style-color {
|
||||
width: 28px;
|
||||
height: 20px;
|
||||
border: 1px solid #2d3748;
|
||||
border-radius: 3px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.plot-style-btns {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.plot-style-btn {
|
||||
background: #1e293b;
|
||||
border: 1px solid #2d3748;
|
||||
color: #64748b;
|
||||
cursor: pointer;
|
||||
font-size: 0.68rem;
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
line-height: 1.4;
|
||||
min-width: 1.6rem;
|
||||
text-align: center;
|
||||
}
|
||||
.plot-style-btn:hover { color: #cbd5e1; border-color: #475569; }
|
||||
.plot-style-btn.active { background: #1e3a5f; border-color: #4a9eff; color: #e2e8f0; }
|
||||
|
||||
.plot-stats-tbl {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.72rem;
|
||||
}
|
||||
.plot-stats-tbl td {
|
||||
padding: 0.05rem 0;
|
||||
color: #475569;
|
||||
}
|
||||
.plot-stats-tbl td:first-child {
|
||||
width: 44px;
|
||||
color: #334155;
|
||||
font-size: 0.68rem;
|
||||
}
|
||||
.plot-stats-tbl td:last-child {
|
||||
color: #94a3b8;
|
||||
font-family: ui-monospace, monospace;
|
||||
}
|
||||
|
||||
.plot-panel-chart {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* uPlot inside plot-panel needs full dimensions */
|
||||
.plot-panel-chart .uplot,
|
||||
.plot-panel-chart .u-wrap {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* ── Zoom control ─────────────────────────────────────────────────────────── */
|
||||
|
||||
.zoom-control {
|
||||
@@ -2800,6 +3040,15 @@ kbd {
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
||||
/* Muted placeholder text inside the trigger. Unlike .hint it adds no padding,
|
||||
so an empty select is exactly as tall as one showing a selected value. */
|
||||
.search-select-placeholder {
|
||||
color: #475569;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.search-select-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
@@ -2893,11 +3142,190 @@ kbd {
|
||||
}
|
||||
|
||||
.panel-btn.icon-only {
|
||||
padding: 0;
|
||||
width: 1.6rem;
|
||||
padding: 0 0.35rem;
|
||||
min-width: 1.6rem;
|
||||
width: auto;
|
||||
height: 1.6rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.app-root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.view-panel-container {
|
||||
display: none;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.view-panel-container.active {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* ── Plot panels (split layout) ─────────────────────────────────────────── */
|
||||
|
||||
/* Edit surface: fills the editor body flex slot. */
|
||||
.plot-panel-edit {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
background: #0a0d14;
|
||||
}
|
||||
|
||||
/* View/fullscreen surface: fills the (relative) canvas container. */
|
||||
.plot-panel-view {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.split-root {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.split-row { display: flex; flex-direction: row; flex: 1; min-width: 0; min-height: 0; }
|
||||
.split-col { display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0; }
|
||||
|
||||
.split-child {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.split-leaf {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.split-divider {
|
||||
flex: 0 0 auto;
|
||||
background: #1e293b;
|
||||
transition: background 0.12s;
|
||||
}
|
||||
.split-divider-h { width: 6px; cursor: col-resize; }
|
||||
.split-divider-v { height: 6px; cursor: row-resize; }
|
||||
.split-divider:hover { background: #4a9eff; }
|
||||
.split-divider-static { pointer-events: none; }
|
||||
|
||||
/* Neutralize the free-form absolute positioning of plot widgets so they fill
|
||||
their split pane responsively (the chart uses a ResizeObserver). */
|
||||
.split-leaf .plot-widget {
|
||||
position: relative !important;
|
||||
left: auto !important;
|
||||
top: auto !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
.split-leaf .chart-area {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* Editable pane chrome. */
|
||||
.plot-pane {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
background: #0f1117;
|
||||
outline: 1px solid transparent;
|
||||
}
|
||||
/* Dim panes that are not the one currently being edited. */
|
||||
.plot-panel-edit .plot-pane:not(.plot-pane-selected)::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(10, 14, 22, 0.45);
|
||||
z-index: 4;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.plot-pane-selected {
|
||||
outline: 3px solid #4a9eff;
|
||||
outline-offset: -3px;
|
||||
box-shadow: inset 0 0 0 1px rgba(74, 158, 255, 0.6),
|
||||
inset 0 0 18px rgba(74, 158, 255, 0.35);
|
||||
}
|
||||
|
||||
.plot-pane-badge {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
z-index: 6;
|
||||
padding: 1px 7px;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
color: #0b1018;
|
||||
background: #4a9eff;
|
||||
border-radius: 3px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.plot-pane-empty,
|
||||
.plot-pane-hint {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: #475569;
|
||||
font-size: 0.82rem;
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
.plot-pane-hint { top: auto; bottom: 0.6rem; transform: translateX(-50%); }
|
||||
|
||||
.plot-pane-overlay {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
z-index: 5;
|
||||
opacity: 0;
|
||||
transition: opacity 0.12s;
|
||||
}
|
||||
.plot-pane:hover .plot-pane-overlay,
|
||||
.plot-pane-selected .plot-pane-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.plot-pane-btn {
|
||||
background: #1e293b;
|
||||
border: 1px solid #2d3748;
|
||||
color: #94a3b8;
|
||||
cursor: pointer;
|
||||
font-size: 0.8rem;
|
||||
line-height: 1;
|
||||
padding: 3px 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.plot-pane-btn:hover { color: #e2e8f0; border-color: #4a9eff; }
|
||||
.plot-pane-btn:disabled { opacity: 0.35; cursor: default; }
|
||||
|
||||
Reference in New Issue
Block a user