mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 09:35:39 +00:00
45e5fda9d0
Adds a full Phase-52 RBAC implementation and multiple server/frontend fixes. Key changes: new auth/permissions.go with 28 granular permissions and DefaultRolePermissions, expanded 7-role hierarchy and helpers in auth/roles.go, JWT org context and GenerateOrgToken, requirePermission/requireOrgMembership middlewares (Go + Node.js), DB schema & adapter changes for role_permissions and is_server_admin, org role boundary checks and peer org scoping, and guards for last-admin demotion and self-demotion. Also: TCP EOF/connection-reset log filtering in signal/relay servers, improved startup banner port display, KEYS_PATH auto-detect warning, CSS hover/transition layout fixes, admin password race mitigation, ID-change ghost peer cleanup, added Tauri ACL schema files, and a new RBAC_PHASE52.md doc. Misc: numerous web-nodejs i18n, CSS, JS and route updates and an updated .github/copilot-instructions.md timestamp/summary.
942 lines
23 KiB
CSS
942 lines
23 KiB
CSS
/* ═══════════════════════════════════════════════════════════════════
|
|
CDAP SDK Studio — Visual Node Editor Styles
|
|
Phase 14 of BetterDesk 3.0 Roadmap
|
|
═══════════════════════════════════════════════════════════════════ */
|
|
|
|
/* ── CSS Variables ─────────────────────────────────────────────── */
|
|
:root {
|
|
--studio-bg: var(--bg-primary, #0d1117);
|
|
--studio-panel-bg: var(--bg-secondary, #161b22);
|
|
--studio-panel-border: var(--border-primary, #30363d);
|
|
--studio-canvas-bg: #0a0e14;
|
|
--studio-grid-color: rgba(110, 118, 129, 0.12);
|
|
--studio-toolbar-bg: var(--bg-tertiary, #1c2128);
|
|
--studio-text: var(--text-primary, #e6edf3);
|
|
--studio-text-muted: var(--text-secondary, #8b949e);
|
|
--studio-accent: var(--accent-blue, #58a6ff);
|
|
--studio-green: #3fb950;
|
|
--studio-yellow: #d29922;
|
|
--studio-red: #f85149;
|
|
--studio-orange: #db6d28;
|
|
--studio-purple: #bc8cff;
|
|
|
|
/* Node colors */
|
|
--studio-node-source: #1f6feb;
|
|
--studio-node-process: #9e6a03;
|
|
--studio-node-output: #238636;
|
|
--studio-node-selected: var(--studio-accent);
|
|
--studio-node-bg: #21262d;
|
|
--studio-node-border: #30363d;
|
|
|
|
/* Wire colors */
|
|
--studio-wire-data: var(--studio-accent);
|
|
--studio-wire-control: var(--studio-orange);
|
|
--studio-wire-error: var(--studio-red);
|
|
|
|
/* Sizes */
|
|
--studio-palette-width: 220px;
|
|
--studio-right-width: 280px;
|
|
--studio-toolbar-h: 42px;
|
|
--studio-statusbar-h: 28px;
|
|
--studio-node-w: 180px;
|
|
--studio-node-h: 52px;
|
|
--studio-port-r: 6px;
|
|
}
|
|
|
|
/* ── Light theme overrides ──────────────────────────────────────── */
|
|
[data-theme="light"] {
|
|
--studio-bg: #ffffff;
|
|
--studio-panel-bg: #f6f8fa;
|
|
--studio-panel-border: #d0d7de;
|
|
--studio-canvas-bg: #f0f3f6;
|
|
--studio-grid-color: rgba(0, 0, 0, 0.06);
|
|
--studio-toolbar-bg: #f6f8fa;
|
|
--studio-text: #1f2328;
|
|
--studio-text-muted: #656d76;
|
|
--studio-node-bg: #ffffff;
|
|
--studio-node-border: #d0d7de;
|
|
}
|
|
|
|
/* ── Container ──────────────────────────────────────────────────── */
|
|
.studio-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
min-height: 0;
|
|
background: var(--studio-bg);
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
/* ── Back button ────────────────────────────────────────────────── */
|
|
.studio-back-btn {
|
|
text-decoration: none;
|
|
color: var(--studio-text-muted);
|
|
}
|
|
.studio-back-btn:hover {
|
|
color: var(--studio-text);
|
|
background: rgba(110, 118, 129, 0.15);
|
|
}
|
|
|
|
/* ── Toolbar ────────────────────────────────────────────────────── */
|
|
.studio-toolbar {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
height: var(--studio-toolbar-h);
|
|
padding: 0 8px;
|
|
background: var(--studio-toolbar-bg);
|
|
border-bottom: 1px solid var(--studio-panel-border);
|
|
flex-shrink: 0;
|
|
gap: 4px;
|
|
}
|
|
|
|
.studio-toolbar-left,
|
|
.studio-toolbar-right {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
}
|
|
|
|
.studio-tool-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 4px 8px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: var(--studio-text-muted);
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
transition: background 0.15s, color 0.15s;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.studio-tool-btn:hover {
|
|
background: rgba(110, 118, 129, 0.15);
|
|
color: var(--studio-text);
|
|
}
|
|
|
|
.studio-tool-btn .material-icons {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.studio-tool-btn.studio-tool-sm {
|
|
padding: 3px 4px;
|
|
}
|
|
|
|
.studio-tool-btn.studio-tool-sm .material-icons {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.studio-tool-btn.studio-tool-accent {
|
|
color: var(--studio-green);
|
|
}
|
|
.studio-tool-btn.studio-tool-accent:hover {
|
|
background: rgba(63, 185, 80, 0.15);
|
|
color: var(--studio-green);
|
|
}
|
|
|
|
.studio-tool-label {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.studio-toolbar-sep {
|
|
width: 1px;
|
|
height: 20px;
|
|
background: var(--studio-panel-border);
|
|
margin: 0 4px;
|
|
}
|
|
|
|
.studio-flow-name {
|
|
font-size: 12px;
|
|
color: var(--studio-text-muted);
|
|
font-style: italic;
|
|
max-width: 200px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.studio-zoom-group {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
background: rgba(110, 118, 129, 0.08);
|
|
border-radius: 4px;
|
|
padding: 0 2px;
|
|
}
|
|
|
|
.studio-zoom-label {
|
|
font-size: 11px;
|
|
color: var(--studio-text-muted);
|
|
min-width: 36px;
|
|
text-align: center;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
/* ── Workspace (3-column) ───────────────────────────────────────── */
|
|
.studio-workspace {
|
|
display: flex;
|
|
flex: 1;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ── Palette Panel (left) ───────────────────────────────────────── */
|
|
.studio-palette {
|
|
width: var(--studio-palette-width);
|
|
min-width: 180px;
|
|
background: var(--studio-panel-bg);
|
|
border-right: 1px solid var(--studio-panel-border);
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow-y: auto;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.studio-panel-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 8px 12px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: var(--studio-text-muted);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
border-bottom: 1px solid var(--studio-panel-border);
|
|
}
|
|
|
|
.studio-panel-header .material-icons {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.studio-palette-search {
|
|
margin: 8px;
|
|
padding: 6px 10px;
|
|
background: var(--studio-canvas-bg);
|
|
border: 1px solid var(--studio-panel-border);
|
|
border-radius: 4px;
|
|
color: var(--studio-text);
|
|
font-size: 12px;
|
|
outline: none;
|
|
}
|
|
|
|
.studio-palette-search:focus {
|
|
border-color: var(--studio-accent);
|
|
}
|
|
|
|
.studio-palette-search::placeholder {
|
|
color: var(--studio-text-muted);
|
|
}
|
|
|
|
.studio-palette-category {
|
|
border-bottom: 1px solid var(--studio-panel-border);
|
|
}
|
|
|
|
.studio-palette-cat-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
width: 100%;
|
|
padding: 8px 12px;
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--studio-text);
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: background 0.15s;
|
|
}
|
|
|
|
.studio-palette-cat-btn:hover {
|
|
background: rgba(110, 118, 129, 0.1);
|
|
}
|
|
|
|
.studio-palette-cat-btn .material-icons {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.studio-palette-cat-btn[data-cat="sources"] .material-icons:first-child { color: var(--studio-node-source); }
|
|
.studio-palette-cat-btn[data-cat="processing"] .material-icons:first-child { color: var(--studio-yellow); }
|
|
.studio-palette-cat-btn[data-cat="outputs"] .material-icons:first-child { color: var(--studio-node-output); }
|
|
|
|
.studio-cat-chevron {
|
|
margin-left: auto;
|
|
font-size: 18px !important;
|
|
transition: transform 0.2s;
|
|
}
|
|
|
|
.studio-palette-category.collapsed .studio-cat-chevron {
|
|
transform: rotate(-90deg);
|
|
}
|
|
|
|
.studio-palette-category.collapsed .studio-palette-items {
|
|
display: none;
|
|
}
|
|
|
|
.studio-palette-items {
|
|
padding: 4px 8px 8px;
|
|
}
|
|
|
|
.studio-palette-node {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 6px 8px;
|
|
border-radius: 4px;
|
|
cursor: grab;
|
|
font-size: 12px;
|
|
color: var(--studio-text);
|
|
transition: background 0.15s;
|
|
user-select: none;
|
|
}
|
|
|
|
.studio-palette-node:hover {
|
|
background: rgba(110, 118, 129, 0.15);
|
|
}
|
|
|
|
.studio-palette-node:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
.studio-palette-node .studio-node-dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.studio-palette-node[data-cat="sources"] .studio-node-dot { background: var(--studio-node-source); }
|
|
.studio-palette-node[data-cat="processing"] .studio-node-dot { background: var(--studio-yellow); }
|
|
.studio-palette-node[data-cat="outputs"] .studio-node-dot { background: var(--studio-node-output); }
|
|
|
|
.studio-palette-node .studio-node-icon {
|
|
font-size: 16px;
|
|
color: var(--studio-text-muted);
|
|
}
|
|
|
|
/* ── Canvas ─────────────────────────────────────────────────────── */
|
|
.studio-canvas-wrap {
|
|
flex: 1;
|
|
position: relative;
|
|
overflow: hidden;
|
|
background: var(--studio-canvas-bg);
|
|
}
|
|
|
|
.studio-canvas-svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
}
|
|
|
|
.studio-grid-rect {
|
|
pointer-events: all;
|
|
}
|
|
|
|
.studio-canvas-svg.no-grid .studio-grid-rect {
|
|
fill: transparent;
|
|
}
|
|
|
|
/* ── Nodes on canvas ────────────────────────────────────────────── */
|
|
.studio-node {
|
|
cursor: move;
|
|
}
|
|
|
|
.studio-node-body {
|
|
fill: var(--studio-node-bg);
|
|
stroke: var(--studio-node-border);
|
|
stroke-width: 1.5;
|
|
rx: 6;
|
|
ry: 6;
|
|
transition: stroke 0.15s;
|
|
}
|
|
|
|
.studio-node.selected .studio-node-body {
|
|
stroke: var(--studio-node-selected);
|
|
stroke-width: 2;
|
|
}
|
|
|
|
.studio-node.running .studio-node-body {
|
|
stroke: var(--studio-green);
|
|
stroke-dasharray: 4 2;
|
|
animation: studio-node-pulse 1s infinite;
|
|
}
|
|
|
|
.studio-node.error .studio-node-body {
|
|
stroke: var(--studio-red);
|
|
}
|
|
|
|
@keyframes studio-node-pulse {
|
|
0%, 100% { stroke-opacity: 1; }
|
|
50% { stroke-opacity: 0.5; }
|
|
}
|
|
|
|
.studio-node-accent {
|
|
width: 4px;
|
|
rx: 6;
|
|
ry: 6;
|
|
}
|
|
|
|
.studio-node[data-category="sources"] .studio-node-accent { fill: var(--studio-node-source); }
|
|
.studio-node[data-category="processing"] .studio-node-accent { fill: var(--studio-yellow); }
|
|
.studio-node[data-category="outputs"] .studio-node-accent { fill: var(--studio-node-output); }
|
|
|
|
.studio-node-label {
|
|
fill: var(--studio-text);
|
|
font-size: 12px;
|
|
font-family: inherit;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.studio-node-type {
|
|
fill: var(--studio-text-muted);
|
|
font-size: 10px;
|
|
font-family: inherit;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.studio-node-icon {
|
|
fill: var(--studio-text-muted);
|
|
font-family: 'Material Icons';
|
|
font-size: 16px;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Ports */
|
|
.studio-port {
|
|
fill: var(--studio-node-border);
|
|
stroke: var(--studio-canvas-bg);
|
|
stroke-width: 2;
|
|
cursor: crosshair;
|
|
transition: fill 0.15s, r 0.15s;
|
|
}
|
|
|
|
.studio-port:hover {
|
|
fill: var(--studio-accent);
|
|
r: 8;
|
|
}
|
|
|
|
.studio-port-in { /* left side */ }
|
|
.studio-port-out { /* right side */ }
|
|
|
|
/* ── Wires ──────────────────────────────────────────────────────── */
|
|
.studio-wire {
|
|
fill: none;
|
|
stroke: var(--studio-wire-data);
|
|
stroke-width: 2;
|
|
stroke-linecap: round;
|
|
pointer-events: stroke;
|
|
cursor: pointer;
|
|
transition: stroke-width 0.15s;
|
|
}
|
|
|
|
.studio-wire:hover {
|
|
stroke-width: 3;
|
|
}
|
|
|
|
.studio-wire.wire-error {
|
|
stroke: var(--studio-wire-error);
|
|
}
|
|
|
|
.studio-wire.wire-control {
|
|
stroke: var(--studio-wire-control);
|
|
stroke-dasharray: 6 3;
|
|
}
|
|
|
|
.studio-wire.selected {
|
|
stroke-width: 3;
|
|
stroke: var(--studio-accent);
|
|
}
|
|
|
|
.studio-wire.running {
|
|
stroke-dasharray: 8 4;
|
|
animation: studio-wire-flow 0.8s linear infinite;
|
|
}
|
|
|
|
@keyframes studio-wire-flow {
|
|
from { stroke-dashoffset: 0; }
|
|
to { stroke-dashoffset: -12; }
|
|
}
|
|
|
|
.studio-temp-wire {
|
|
stroke: var(--studio-accent);
|
|
stroke-width: 2;
|
|
stroke-dasharray: 6 3;
|
|
opacity: 0.6;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* ── Selection Box ──────────────────────────────────────────────── */
|
|
.studio-select-box {
|
|
position: absolute;
|
|
border: 1px solid var(--studio-accent);
|
|
background: rgba(88, 166, 255, 0.08);
|
|
pointer-events: none;
|
|
z-index: 10;
|
|
}
|
|
|
|
/* ── Minimap ────────────────────────────────────────────────────── */
|
|
.studio-minimap {
|
|
position: absolute;
|
|
bottom: 12px;
|
|
right: 12px;
|
|
width: 160px;
|
|
height: 100px;
|
|
background: var(--studio-panel-bg);
|
|
border: 1px solid var(--studio-panel-border);
|
|
border-radius: 6px;
|
|
overflow: hidden;
|
|
opacity: 0.85;
|
|
transition: opacity 0.2s;
|
|
z-index: 5;
|
|
}
|
|
|
|
.studio-minimap:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
.studio-minimap canvas {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.studio-minimap-viewport {
|
|
position: absolute;
|
|
border: 1.5px solid var(--studio-accent);
|
|
background: rgba(88, 166, 255, 0.08);
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* ── Empty State ────────────────────────────────────────────────── */
|
|
.studio-empty-state {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
text-align: center;
|
|
color: var(--studio-text-muted);
|
|
pointer-events: none;
|
|
z-index: 2;
|
|
}
|
|
|
|
.studio-empty-state .material-icons {
|
|
font-size: 56px;
|
|
opacity: 0.3;
|
|
}
|
|
|
|
.studio-empty-state h3 {
|
|
margin: 12px 0 6px;
|
|
font-size: 16px;
|
|
color: var(--studio-text);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.studio-empty-state p {
|
|
font-size: 13px;
|
|
margin: 0 0 16px;
|
|
}
|
|
|
|
.studio-empty-state .studio-empty-actions {
|
|
pointer-events: auto;
|
|
}
|
|
|
|
/* ── Right Panel ────────────────────────────────────────────────── */
|
|
.studio-right-panel {
|
|
width: var(--studio-right-width);
|
|
min-width: 220px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-left: 1px solid var(--studio-panel-border);
|
|
background: var(--studio-panel-bg);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* ── Inspector ──────────────────────────────────────────────────── */
|
|
.studio-inspector {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
border-bottom: 1px solid var(--studio-panel-border);
|
|
}
|
|
|
|
.studio-inspector-body {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 12px;
|
|
}
|
|
|
|
.studio-inspector-empty {
|
|
text-align: center;
|
|
padding: 32px 16px;
|
|
color: var(--studio-text-muted);
|
|
}
|
|
|
|
.studio-inspector-empty .material-icons {
|
|
font-size: 36px;
|
|
opacity: 0.3;
|
|
}
|
|
|
|
.studio-inspector-empty p {
|
|
font-size: 12px;
|
|
margin-top: 8px;
|
|
}
|
|
|
|
/* Inspector form fields */
|
|
.studio-field {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.studio-field label {
|
|
display: block;
|
|
font-size: 11px;
|
|
color: var(--studio-text-muted);
|
|
margin-bottom: 4px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.3px;
|
|
}
|
|
|
|
.studio-field input,
|
|
.studio-field select,
|
|
.studio-field textarea {
|
|
width: 100%;
|
|
padding: 6px 8px;
|
|
background: var(--studio-canvas-bg);
|
|
border: 1px solid var(--studio-panel-border);
|
|
border-radius: 4px;
|
|
color: var(--studio-text);
|
|
font-size: 12px;
|
|
font-family: inherit;
|
|
outline: none;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.studio-field input:focus,
|
|
.studio-field select:focus,
|
|
.studio-field textarea:focus {
|
|
border-color: var(--studio-accent);
|
|
}
|
|
|
|
.studio-field textarea {
|
|
resize: vertical;
|
|
min-height: 60px;
|
|
}
|
|
|
|
.studio-field-row {
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
|
|
.studio-field-row .studio-field {
|
|
flex: 1;
|
|
}
|
|
|
|
.studio-inspector-section {
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
color: var(--studio-text-muted);
|
|
margin: 16px 0 8px;
|
|
padding-bottom: 4px;
|
|
border-bottom: 1px solid var(--studio-panel-border);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.3px;
|
|
}
|
|
|
|
.studio-inspector-connections {
|
|
font-size: 12px;
|
|
color: var(--studio-text-muted);
|
|
}
|
|
|
|
.studio-inspector-connections span {
|
|
display: block;
|
|
padding: 2px 0;
|
|
}
|
|
|
|
.studio-delete-node-btn {
|
|
width: 100%;
|
|
padding: 6px;
|
|
margin-top: 16px;
|
|
background: transparent;
|
|
border: 1px solid var(--studio-red);
|
|
border-radius: 4px;
|
|
color: var(--studio-red);
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
transition: background 0.15s;
|
|
}
|
|
|
|
.studio-delete-node-btn:hover {
|
|
background: rgba(248, 81, 73, 0.12);
|
|
}
|
|
|
|
/* ── Console ────────────────────────────────────────────────────── */
|
|
.studio-console {
|
|
height: 180px;
|
|
min-height: 100px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.studio-console-header {
|
|
position: relative;
|
|
}
|
|
|
|
.studio-console-clear {
|
|
position: absolute;
|
|
right: 8px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
background: none;
|
|
border: none;
|
|
color: var(--studio-text-muted);
|
|
cursor: pointer;
|
|
padding: 2px;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.studio-console-clear:hover {
|
|
background: rgba(110, 118, 129, 0.15);
|
|
color: var(--studio-text);
|
|
}
|
|
|
|
.studio-console-clear .material-icons {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.studio-console-body {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 6px 10px;
|
|
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
|
font-size: 11px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.studio-console-line {
|
|
display: flex;
|
|
gap: 6px;
|
|
padding: 1px 0;
|
|
}
|
|
|
|
.studio-console-time {
|
|
color: var(--studio-text-muted);
|
|
flex-shrink: 0;
|
|
min-width: 50px;
|
|
}
|
|
|
|
.studio-console-msg {
|
|
word-break: break-word;
|
|
}
|
|
|
|
.studio-console-info .studio-console-msg { color: var(--studio-text-muted); }
|
|
.studio-console-success .studio-console-msg { color: var(--studio-green); }
|
|
.studio-console-warn .studio-console-msg { color: var(--studio-yellow); }
|
|
.studio-console-error .studio-console-msg { color: var(--studio-red); }
|
|
.studio-console-data .studio-console-msg { color: var(--studio-purple); }
|
|
|
|
/* ── Status Bar ─────────────────────────────────────────────────── */
|
|
.studio-statusbar {
|
|
display: flex;
|
|
align-items: center;
|
|
height: var(--studio-statusbar-h);
|
|
padding: 0 12px;
|
|
background: var(--studio-toolbar-bg);
|
|
border-top: 1px solid var(--studio-panel-border);
|
|
font-size: 11px;
|
|
color: var(--studio-text-muted);
|
|
flex-shrink: 0;
|
|
gap: 16px;
|
|
}
|
|
|
|
.studio-status-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.studio-status-item .material-icons {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.studio-status-item b {
|
|
color: var(--studio-text);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.studio-status-sep {
|
|
flex: 1;
|
|
}
|
|
|
|
.studio-status-right {
|
|
margin-left: auto;
|
|
}
|
|
|
|
.studio-status-dot {
|
|
width: 7px;
|
|
height: 7px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.studio-status-ready { background: var(--studio-green); }
|
|
.studio-status-running { background: var(--studio-accent); animation: studio-dot-pulse 1s infinite; }
|
|
.studio-status-error { background: var(--studio-red); }
|
|
.studio-status-draft { background: var(--studio-text-muted); }
|
|
|
|
@keyframes studio-dot-pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.4; }
|
|
}
|
|
|
|
/* ── Modals ──────────────────────────────────────────────────────── */
|
|
.modal-lg {
|
|
max-width: 700px;
|
|
width: 95%;
|
|
}
|
|
|
|
.studio-flow-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
max-height: 400px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.studio-flow-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 12px;
|
|
background: var(--studio-canvas-bg);
|
|
border: 1px solid var(--studio-panel-border);
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: border-color 0.15s, background 0.15s;
|
|
}
|
|
|
|
.studio-flow-item:hover {
|
|
border-color: var(--studio-accent);
|
|
background: rgba(88, 166, 255, 0.05);
|
|
}
|
|
|
|
.studio-flow-item-info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.studio-flow-item-name {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--studio-text);
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.studio-flow-item-desc {
|
|
font-size: 12px;
|
|
color: var(--studio-text-muted);
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.studio-flow-item-meta {
|
|
font-size: 11px;
|
|
color: var(--studio-text-muted);
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.studio-flow-item-actions {
|
|
display: flex;
|
|
gap: 4px;
|
|
}
|
|
|
|
.studio-flow-item-actions button {
|
|
background: none;
|
|
border: none;
|
|
color: var(--studio-text-muted);
|
|
cursor: pointer;
|
|
padding: 4px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.studio-flow-item-actions button:hover {
|
|
background: rgba(110, 118, 129, 0.15);
|
|
color: var(--studio-text);
|
|
}
|
|
|
|
.studio-flow-item-actions button.danger:hover {
|
|
color: var(--studio-red);
|
|
}
|
|
|
|
.studio-flow-item-actions .material-icons {
|
|
font-size: 18px;
|
|
}
|
|
|
|
/* Template grid */
|
|
.studio-template-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
|
gap: 12px;
|
|
max-height: 400px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.studio-template-card {
|
|
padding: 16px;
|
|
background: var(--studio-canvas-bg);
|
|
border: 1px solid var(--studio-panel-border);
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transform: translateY(0);
|
|
transition: border-color 0.15s, transform 0.15s;
|
|
}
|
|
|
|
.studio-template-card:hover {
|
|
border-color: var(--studio-accent);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.studio-template-card .material-icons {
|
|
font-size: 28px;
|
|
color: var(--studio-accent);
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.studio-template-card h4 {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--studio-text);
|
|
margin: 0 0 4px;
|
|
}
|
|
|
|
.studio-template-card p {
|
|
font-size: 12px;
|
|
color: var(--studio-text-muted);
|
|
margin: 0;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
/* ── Responsive ─────────────────────────────────────────────────── */
|
|
@media (max-width: 1200px) {
|
|
:root {
|
|
--studio-palette-width: 180px;
|
|
--studio-right-width: 240px;
|
|
}
|
|
.studio-tool-label { display: none; }
|
|
}
|
|
|
|
@media (max-width: 900px) {
|
|
.studio-palette { display: none; }
|
|
.studio-right-panel { display: none; }
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.studio-toolbar { padding: 0 4px; }
|
|
.studio-zoom-group { display: none; }
|
|
.studio-minimap { display: none; }
|
|
}
|