/* rSchedule Automation Canvas — n8n-style workflow builder */ folk-automation-canvas { display: block; height: calc(100vh - 60px); } .ac-root { display: flex; flex-direction: column; height: 100%; font-family: system-ui, -apple-system, sans-serif; color: var(--rs-text-primary, #e2e8f0); } /* ── Toolbar ── */ .ac-toolbar { display: flex; align-items: center; gap: 12px; padding: 10px 20px; min-height: 46px; border-bottom: 1px solid var(--rs-border, #2d2d44); background: var(--rs-bg-surface, #1a1a2e); z-index: 10; } .ac-toolbar__title { font-size: 15px; font-weight: 600; flex: 1; display: flex; align-items: center; gap: 8px; } .ac-toolbar__title input { background: transparent; border: 1px solid transparent; color: var(--rs-text-primary, #e2e8f0); font-size: 15px; font-weight: 600; padding: 2px 6px; border-radius: 4px; width: 200px; } .ac-toolbar__title input:hover, .ac-toolbar__title input:focus { border-color: var(--rs-border-strong, #3d3d5c); outline: none; } .ac-toolbar__actions { display: flex; gap: 6px; align-items: center; } .ac-btn { padding: 6px 12px; border-radius: 8px; border: 1px solid var(--rs-input-border, #3d3d5c); background: var(--rs-input-bg, #16162a); color: var(--rs-text-primary, #e2e8f0); font-size: 12px; cursor: pointer; transition: border-color 0.15s, background 0.15s; white-space: nowrap; } .ac-btn:hover { border-color: var(--rs-border-strong, #4d4d6c); } .ac-btn--run { background: #3b82f622; border-color: #3b82f655; color: #60a5fa; } .ac-btn--run:hover { background: #3b82f633; border-color: #3b82f6; } .ac-btn--save { background: #10b98122; border-color: #10b98155; color: #34d399; } .ac-toggle { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--rs-text-muted, #94a3b8); } .ac-toggle input[type="checkbox"] { accent-color: #10b981; } .ac-save-indicator { font-size: 11px; color: var(--rs-text-muted, #64748b); } /* ── Canvas area ── */ .ac-canvas-area { flex: 1; display: flex; overflow: hidden; position: relative; } /* ── Left sidebar — node palette ── */ .ac-palette { width: 200px; min-width: 200px; border-right: 1px solid var(--rs-border, #2d2d44); background: var(--rs-bg-surface, #1a1a2e); overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 16px; } .ac-palette__group-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rs-text-muted, #94a3b8); margin-bottom: 4px; } .ac-palette__card { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 8px; border: 1px solid var(--rs-border, #2d2d44); background: var(--rs-input-bg, #16162a); cursor: grab; font-size: 12px; transition: border-color 0.15s, background 0.15s; margin-bottom: 4px; } .ac-palette__card:hover { border-color: #6366f1; background: #6366f111; } .ac-palette__card:active { cursor: grabbing; } .ac-palette__card-icon { font-size: 16px; width: 24px; text-align: center; flex-shrink: 0; } .ac-palette__card-label { font-weight: 500; color: var(--rs-text-primary, #e2e8f0); } /* ── SVG canvas ── */ .ac-canvas { flex: 1; position: relative; overflow: hidden; cursor: grab; background: var(--rs-canvas-bg, #0f0f23); } .ac-canvas.grabbing { cursor: grabbing; } .ac-canvas.wiring { cursor: crosshair; } .ac-canvas svg { display: block; width: 100%; height: 100%; } /* ── Right sidebar — config ── */ .ac-config { width: 0; overflow: hidden; border-left: 1px solid var(--rs-border, #2d2d44); background: var(--rs-bg-surface, #1a1a2e); display: flex; flex-direction: column; transition: width 0.2s ease; } .ac-config.open { width: 280px; min-width: 280px; } .ac-config__header { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--rs-border, #2d2d44); font-weight: 600; font-size: 13px; } .ac-config__header-close { background: none; border: none; color: var(--rs-text-muted, #94a3b8); font-size: 16px; cursor: pointer; margin-left: auto; padding: 2px; } .ac-config__body { padding: 12px 16px; display: flex; flex-direction: column; gap: 10px; overflow-y: auto; flex: 1; } .ac-config__field { display: flex; flex-direction: column; gap: 4px; } .ac-config__field label { font-size: 11px; font-weight: 500; color: var(--rs-text-muted, #94a3b8); } .ac-config__field input, .ac-config__field select, .ac-config__field textarea { width: 100%; padding: 6px 8px; border-radius: 6px; border: 1px solid var(--rs-input-border, #3d3d5c); background: var(--rs-input-bg, #16162a); color: var(--rs-text-primary, #e2e8f0); font-size: 12px; font-family: inherit; box-sizing: border-box; } .ac-config__field textarea { resize: vertical; min-height: 60px; } .ac-config__field input:focus, .ac-config__field select:focus, .ac-config__field textarea:focus { border-color: #3b82f6; outline: none; } .ac-config__delete { margin-top: 12px; padding: 6px 12px; border-radius: 6px; border: 1px solid #ef444455; background: #ef444422; color: #f87171; font-size: 12px; cursor: pointer; } .ac-config__delete:hover { background: #ef444433; } /* ── Execution log in config panel ── */ .ac-exec-log { margin-top: 12px; border-top: 1px solid var(--rs-border, #2d2d44); padding-top: 12px; } .ac-exec-log__title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rs-text-muted, #94a3b8); margin-bottom: 8px; } .ac-exec-log__entry { display: flex; align-items: center; gap: 6px; padding: 4px 0; font-size: 11px; color: var(--rs-text-muted, #94a3b8); } .ac-exec-log__dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; } .ac-exec-log__dot.success { background: #22c55e; } .ac-exec-log__dot.error { background: #ef4444; } .ac-exec-log__dot.running { background: #3b82f6; animation: ac-pulse 1s infinite; } @keyframes ac-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } /* ── Zoom controls ── */ .ac-zoom-controls { position: absolute; bottom: 12px; right: 12px; display: flex; align-items: center; gap: 4px; background: var(--rs-bg-surface, #1a1a2e); border: 1px solid var(--rs-border-strong, #3d3d5c); border-radius: 8px; padding: 4px 6px; z-index: 5; } .ac-zoom-btn { width: 28px; height: 28px; border: none; border-radius: 6px; background: transparent; color: var(--rs-text-primary, #e2e8f0); font-size: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s; } .ac-zoom-btn:hover { background: var(--rs-bg-surface-raised, #252545); } .ac-zoom-level { font-size: 11px; color: var(--rs-text-muted, #94a3b8); min-width: 36px; text-align: center; } /* ── Node styles in SVG ── */ .ac-node { cursor: pointer; } .ac-node.selected > foreignObject > div { outline: 2px solid #6366f1; outline-offset: 2px; } .ac-node foreignObject > div { border-radius: 10px; border: 1px solid var(--rs-border, #2d2d44); background: var(--rs-bg-surface, #1a1a2e); overflow: hidden; font-size: 12px; transition: border-color 0.15s; } .ac-node:hover foreignObject > div { border-color: #4f46e5 !important; } .ac-node-header { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--rs-border, #2d2d44); cursor: move; } .ac-node-icon { font-size: 14px; } .ac-node-label { font-weight: 600; font-size: 12px; color: var(--rs-text-primary, #e2e8f0); flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .ac-node-status { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; } .ac-node-status.idle { background: #4b5563; } .ac-node-status.running { background: #3b82f6; animation: ac-pulse 1s infinite; } .ac-node-status.success { background: #22c55e; } .ac-node-status.error { background: #ef4444; } .ac-node-ports { padding: 6px 10px; display: flex; justify-content: space-between; min-height: 28px; } .ac-node-inputs, .ac-node-outputs { display: flex; flex-direction: column; gap: 4px; } .ac-node-outputs { align-items: flex-end; } .ac-port-label { font-size: 10px; color: var(--rs-text-muted, #94a3b8); } /* ── Port handles in SVG ── */ .ac-port-group { cursor: crosshair; } .ac-port-dot { transition: r 0.15s, filter 0.15s; } .ac-port-group:hover .ac-port-dot { r: 7; filter: drop-shadow(0 0 4px currentColor); } .ac-port-group--wiring-source .ac-port-dot { r: 7; filter: drop-shadow(0 0 6px currentColor); } .ac-port-group--wiring-target .ac-port-dot { r: 7; animation: port-pulse 0.8s ease-in-out infinite; } .ac-port-group--wiring-dimmed .ac-port-dot { opacity: 0.2; } @keyframes port-pulse { 0%, 100% { filter: drop-shadow(0 0 3px currentColor); } 50% { filter: drop-shadow(0 0 8px currentColor); } } /* ── Edge styles ── */ .ac-edge-group { pointer-events: stroke; } .ac-edge-path { fill: none; stroke-width: 2; } .ac-edge-hit { fill: none; stroke: transparent; stroke-width: 16; cursor: pointer; } .ac-edge-path.running { animation: ac-edge-flow 1s linear infinite; stroke-dasharray: 8 4; } @keyframes ac-edge-flow { to { stroke-dashoffset: -24; } } /* ── Wiring temp line ── */ .ac-wiring-temp { fill: none; stroke: #6366f1; stroke-width: 2; stroke-dasharray: 6 4; opacity: 0.7; pointer-events: none; } /* ── Workflow selector ── */ .ac-workflow-select { padding: 4px 8px; border-radius: 6px; border: 1px solid var(--rs-input-border, #3d3d5c); background: var(--rs-input-bg, #16162a); color: var(--rs-text-primary, #e2e8f0); font-size: 12px; } /* ── Mobile ── */ @media (max-width: 768px) { .ac-palette { width: 160px; min-width: 160px; padding: 8px; } .ac-config.open { position: absolute; top: 0; right: 0; width: 100%; height: 100%; z-index: 20; min-width: unset; } .ac-toolbar { flex-wrap: wrap; padding: 8px 12px; } }