Files
goldenChart/frontend/src/styles/strategyEditor.css
T
2026-05-24 13:15:26 +09:00

1066 lines
30 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ── 전략편집기 (Strategy Builder) — app theme tokens (strategyEditorTheme.css) ── */
.se-page {
display: flex;
flex-direction: column;
flex: 1;
height: calc(100vh - 44px);
min-height: 0;
background: var(--se-bg);
color: var(--se-text);
overflow: hidden;
position: relative;
}
.se-save-toast {
position: absolute;
top: 56px;
left: 50%;
transform: translateX(-50%);
z-index: 200;
padding: 10px 20px;
border-radius: 8px;
background: rgba(0, 255, 136, 0.12);
border: 1px solid rgba(0, 255, 136, 0.45);
color: #00ff88;
font-size: 0.82rem;
font-weight: 600;
box-shadow: 0 0 24px rgba(0, 255, 136, 0.25);
animation: se-toast-in 0.3s ease;
}
@keyframes se-toast-in {
from { opacity: 0; transform: translateX(-50%) translateY(-8px); }
to { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.se-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 18px;
border-bottom: 1px solid var(--se-header-border);
background: var(--se-header-bg);
flex-shrink: 0;
}
.se-header-left { display: flex; align-items: baseline; gap: 10px; }
.se-title {
margin: 0;
font-size: 1.1rem;
font-weight: 800;
background: var(--se-title-gradient);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.se-subtitle { font-size: 0.72rem; color: var(--se-text-muted); }
.se-header-actions { display: flex; align-items: center; gap: 8px; }
.se-editor-mode {
display: inline-flex;
border: 1px solid var(--se-border);
border-radius: 8px;
overflow: hidden;
background: var(--se-btn-bg);
}
.se-editor-mode-btn {
border: none;
background: transparent;
color: var(--se-text-muted);
padding: 7px 12px;
font-size: 0.78rem;
cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.se-editor-mode-btn:hover {
color: var(--se-text);
background: color-mix(in srgb, var(--se-accent) 8%, transparent);
}
.se-editor-mode-btn--on {
color: var(--se-text);
background: color-mix(in srgb, var(--se-accent) 18%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--se-accent) 35%, transparent);
}
.se-list-editor {
flex: 1;
min-height: 0;
overflow: auto;
margin: 8px 12px 12px;
padding: 12px;
border: 1px dashed var(--se-border);
border-radius: 10px;
background: color-mix(in srgb, var(--se-center-bg) 92%, var(--se-accent) 8%);
}
.se-btn {
border: 1px solid var(--se-border);
background: var(--se-btn-bg);
color: var(--se-text);
border-radius: 8px;
padding: 7px 14px;
font-size: 0.82rem;
cursor: pointer;
transition: box-shadow 0.15s, border-color 0.15s;
}
.se-btn:hover { border-color: color-mix(in srgb, var(--se-accent) 50%, transparent); }
.se-btn--ghost { background: transparent; }
.se-btn--icon {
min-width: 34px;
padding: 7px 10px;
font-size: 0.9rem;
line-height: 1;
}
.se-btn--icon:disabled {
opacity: 0.35;
cursor: not-allowed;
}
.se-btn--gold {
background: var(--se-btn-gold-bg);
border-color: var(--se-btn-gold-border);
color: var(--se-btn-gold-text);
font-weight: 700;
box-shadow: 0 0 16px color-mix(in srgb, var(--se-gold) 15%, transparent);
}
.se-btn--gold:hover { box-shadow: 0 0 24px color-mix(in srgb, var(--se-gold) 30%, transparent); }
.se-btn--danger { border-color: color-mix(in srgb, var(--se-danger) 50%, transparent); color: var(--se-danger); }
.se-body {
flex: 1;
min-height: 0;
display: flex;
min-width: 0;
}
.se-splitter {
flex-shrink: 0;
background: var(--se-splitter-bg);
transition: background 0.12s, box-shadow 0.12s;
touch-action: none;
z-index: 6;
}
.se-splitter:hover,
.se-splitter.se-splitter--active {
background: var(--se-splitter-active);
box-shadow: 0 0 10px color-mix(in srgb, var(--se-accent) 20%, transparent);
}
.se-splitter--v {
width: 5px;
cursor: col-resize;
}
.se-splitter--h {
height: 5px;
margin: 0 10px;
border-radius: 3px;
cursor: row-resize;
flex-shrink: 0;
}
/* ── Left: strategy list card ── */
.se-left {
flex-shrink: 0;
border-right: none;
display: flex;
flex-direction: column;
min-height: 0;
background: var(--se-panel-shell-bg);
padding: 10px;
}
.se-strat-panel {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
padding: 14px 12px 12px;
border-radius: 14px;
background: var(--se-panel-card-bg);
border: 1px solid var(--se-panel-card-border);
box-shadow: var(--se-panel-card-shadow), inset 0 1px 0 color-mix(in srgb, var(--se-text) 4%, transparent);
}
.se-strat-panel-head {
margin-bottom: 12px;
padding-bottom: 10px;
border-bottom: 1px solid var(--se-border);
}
.se-panel-title {
margin: 0;
font-size: 0.88rem;
font-weight: 700;
letter-spacing: 0.02em;
color: var(--se-text);
}
.se-new-strat-btn {
flex-shrink: 0;
width: 100%;
margin: 0 0 12px;
padding: 11px 12px;
border-radius: 10px;
border: 1px solid var(--se-border);
background: var(--se-btn-bg);
color: var(--se-text-muted);
font-size: 0.8rem;
font-weight: 600;
cursor: pointer;
transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.se-new-strat-btn:hover {
background: var(--se-item-hover-bg);
border-color: color-mix(in srgb, var(--se-accent) 28%, transparent);
color: var(--se-accent);
}
.se-strat-list {
flex: 1;
overflow-y: auto;
min-height: 0;
display: flex;
flex-direction: column;
gap: 10px;
padding: 2px 1px 4px;
}
.se-strat-item {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 13px;
cursor: pointer;
border-radius: 12px;
border: 1px solid var(--se-strat-item-border);
background: var(--se-strat-item-bg);
box-shadow: var(--se-strat-item-shadow);
transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.12s;
outline: none;
}
.se-strat-item:hover {
background: var(--se-item-hover-bg);
border-color: color-mix(in srgb, var(--se-accent) 28%, transparent);
box-shadow: var(--se-strat-item-hover-shadow);
transform: translateY(-1px);
}
.se-strat-item--sel {
background: var(--se-item-selected-bg);
border-color: var(--se-item-selected-border);
box-shadow:
var(--se-strat-item-hover-shadow),
0 0 0 1px color-mix(in srgb, var(--se-item-selected-border) 45%, transparent),
inset 0 1px 0 color-mix(in srgb, var(--se-text) 6%, transparent);
transform: translateY(-1px);
}
.se-strat-item--sel:hover {
background: var(--se-item-selected-bg);
box-shadow:
var(--se-strat-item-hover-shadow),
0 0 0 1px color-mix(in srgb, var(--se-item-selected-border) 45%, transparent),
inset 0 1px 0 color-mix(in srgb, var(--se-text) 6%, transparent);
}
.se-strat-item:focus-visible {
outline: 2px solid color-mix(in srgb, var(--se-accent) 55%, transparent);
outline-offset: 2px;
}
.se-strat-name {
flex: 1;
min-width: 0;
font-size: 0.82rem;
font-weight: 700;
color: var(--se-text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.se-strat-item--sel .se-strat-name {
color: var(--se-item-selected-text);
}
.se-strat-item-actions {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 8px;
}
.se-strat-del {
display: flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
padding: 0;
border: none;
border-radius: 6px;
background: transparent;
color: var(--se-text-dim);
cursor: pointer;
transition: color 0.12s, background 0.12s;
}
.se-strat-item--sel .se-strat-del {
color: color-mix(in srgb, var(--se-item-selected-text) 85%, transparent);
}
.se-strat-del:hover {
color: var(--se-danger);
background: color-mix(in srgb, var(--se-danger) 15%, transparent);
}
.se-strat-status {
flex-shrink: 0;
min-width: 36px;
text-align: center;
font-size: 0.65rem;
font-weight: 700;
padding: 3px 7px;
border-radius: 999px;
color: var(--se-text-muted);
background: color-mix(in srgb, var(--se-text-muted) 10%, transparent);
border: 1px solid var(--se-border);
}
.se-strat-status--on {
color: var(--se-status-on);
background: color-mix(in srgb, var(--se-status-on) 10%, transparent);
border-color: color-mix(in srgb, var(--se-status-on) 28%, transparent);
}
.se-strat-item--sel .se-strat-status--on {
color: var(--se-item-selected-text);
background: color-mix(in srgb, var(--se-gold) 15%, transparent);
border-color: color-mix(in srgb, var(--se-gold) 35%, transparent);
}
.se-empty {
font-size: 0.78rem;
color: var(--se-text-dim);
text-align: center;
padding: 20px 8px;
}
/* ── Center ── */
.se-center {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
min-height: 0;
background: var(--se-center-bg);
}
.se-center-work {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.se-center-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px 0;
flex-shrink: 0;
}
.se-signal-tabs { display: flex; gap: 6px; }
.se-signal-tab {
border: 1px solid var(--se-border);
background: var(--se-btn-bg);
color: var(--se-text-muted);
border-radius: 8px 8px 0 0;
padding: 7px 16px;
font-size: 0.76rem;
cursor: pointer;
transition: all 0.15s;
}
.se-signal-tab--buy-on {
color: var(--se-buy);
border-color: color-mix(in srgb, var(--se-buy) 50%, transparent);
background: color-mix(in srgb, var(--se-buy) 10%, transparent);
box-shadow: 0 0 16px color-mix(in srgb, var(--se-buy) 15%, transparent);
}
.se-signal-tab--sell-on {
color: var(--se-sell);
border-color: color-mix(in srgb, var(--se-sell) 50%, transparent);
background: color-mix(in srgb, var(--se-sell) 10%, transparent);
box-shadow: 0 0 16px color-mix(in srgb, var(--se-sell) 15%, transparent);
}
.se-editing-name {
font-size: 0.72rem;
color: color-mix(in srgb, var(--se-gold) 85%, transparent);
padding: 4px 10px;
border: 1px solid color-mix(in srgb, var(--se-gold) 25%, transparent);
border-radius: 999px;
}
.se-canvas-wrap {
flex: 1;
min-height: 0;
margin: 0 10px;
border: 1px solid var(--se-canvas-border);
border-radius: 12px;
overflow: hidden;
box-shadow: var(--se-canvas-inset);
}
.se-canvas-wrap--sell {
border-color: var(--se-canvas-sell-border);
box-shadow: var(--se-canvas-sell-inset);
}
.se-canvas-wrap .react-flow { background: transparent; }
.se-canvas-wrap .react-flow__selection {
background: var(--se-selection-bg);
border: 1px dashed var(--se-selection-border);
border-radius: 4px;
}
.se-flow-bg { opacity: 0.4; }
.se-canvas-toolbar {
background: var(--se-toolbar-bg);
border: 1px solid var(--se-border);
border-radius: 8px;
padding: 5px 12px;
display: flex;
gap: 10px;
align-items: center;
}
.se-canvas-toolbar-title { font-size: 0.72rem; font-weight: 700; color: var(--se-toolbar-title); }
.se-canvas-toolbar-hint { font-size: 0.65rem; color: var(--se-text-muted); }
.se-canvas-empty {
background: var(--se-toolbar-bg);
border: 1px dashed var(--se-border);
border-radius: 10px;
padding: 8px 16px;
font-size: 0.76rem;
color: var(--se-text-muted);
}
/* ── React Flow controls & minimap (editor theme) ── */
.se-flow-controls,
.se-flow-minimap {
background: var(--se-control-bg) !important;
border: 1px solid var(--se-control-border) !important;
border-radius: 10px !important;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35), 0 0 16px color-mix(in srgb, var(--se-accent) 6%, transparent) !important;
overflow: hidden;
}
.se-canvas-wrap .se-flow-controls .react-flow__controls-button {
width: 28px !important;
height: 28px !important;
background: var(--se-control-bg) !important;
border: none !important;
border-bottom: 1px solid color-mix(in srgb, var(--se-accent) 12%, transparent) !important;
color: var(--se-control-icon) !important;
fill: var(--se-control-icon) !important;
transition: background 0.12s, color 0.12s;
}
.se-canvas-wrap .se-flow-controls .react-flow__controls-button:last-child {
border-bottom: none !important;
}
.se-canvas-wrap .se-flow-controls .react-flow__controls-button:hover {
background: var(--se-control-hover) !important;
color: var(--se-accent) !important;
fill: var(--se-accent) !important;
}
.se-canvas-wrap .se-flow-controls .react-flow__controls-button svg {
fill: currentColor !important;
max-width: 14px;
max-height: 14px;
}
.se-canvas-wrap--sell .se-flow-controls .react-flow__controls-button {
color: color-mix(in srgb, var(--se-sell) 88%, transparent) !important;
fill: color-mix(in srgb, var(--se-sell) 88%, transparent) !important;
border-bottom-color: color-mix(in srgb, var(--se-sell) 12%, transparent) !important;
}
.se-canvas-wrap--sell .se-flow-controls .react-flow__controls-button:hover {
background: color-mix(in srgb, var(--se-sell) 14%, transparent) !important;
color: var(--se-sell) !important;
fill: var(--se-sell) !important;
}
.se-canvas-wrap--sell .se-flow-minimap {
border-color: color-mix(in srgb, var(--se-sell) 22%, transparent) !important;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35), 0 0 16px color-mix(in srgb, var(--se-sell) 6%, transparent) !important;
}
.se-flow-edge {
stroke: var(--se-edge);
filter: drop-shadow(0 0 4px color-mix(in srgb, var(--se-accent) 50%, transparent));
}
.se-flow-edge--selected {
stroke: var(--se-accent);
filter: drop-shadow(0 0 8px color-mix(in srgb, var(--se-accent) 85%, transparent));
}
.se-canvas-wrap--sell .se-flow-edge {
stroke: color-mix(in srgb, var(--se-sell) 65%, transparent);
filter: drop-shadow(0 0 4px color-mix(in srgb, var(--se-sell) 40%, transparent));
}
.se-canvas-wrap--sell .se-flow-edge--selected {
stroke: var(--se-sell);
filter: drop-shadow(0 0 8px color-mix(in srgb, var(--se-sell) 75%, transparent));
}
.se-flow-edge-del {
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
padding: 0;
border: 1px solid rgba(248, 113, 113, 0.6);
border-radius: 50%;
background: rgba(15, 23, 42, 0.95);
color: #f87171;
font-size: 16px;
line-height: 1;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
transition: background 0.15s, transform 0.15s;
}
.se-flow-edge-del:hover {
background: rgba(248, 113, 113, 0.25);
scale: 1.1;
}
.se-flow-edge-hit {
pointer-events: stroke;
}
.se-flow-edge-hit--source { cursor: grab; }
.se-flow-edge-hit--middle { cursor: move; }
.se-flow-edge-hit--target { cursor: grab; }
.se-selection-delete {
z-index: 12;
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
padding: 0;
border: 1px solid rgba(248, 113, 113, 0.65);
border-radius: 50%;
background: rgba(15, 23, 42, 0.96);
color: #f87171;
font-size: 17px;
line-height: 1;
cursor: pointer;
pointer-events: all;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.55), 0 0 12px rgba(248, 113, 113, 0.35);
transition: background 0.15s, scale 0.15s;
}
.se-selection-delete:hover {
background: rgba(248, 113, 113, 0.28);
scale: 1.08;
}
/* ── Flow nodes ── */
.se-flow-node {
position: relative;
min-width: 130px;
border-radius: 10px;
font-size: 0.75rem;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.45);
backdrop-filter: blur(8px);
}
.se-flow-node--start {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 14px;
background: var(--se-node-start-bg);
border: 1px solid var(--se-node-start-border);
color: var(--se-text-muted);
}
.se-flow-start-dot {
width: 8px; height: 8px; border-radius: 50%;
background: var(--se-text-dim);
box-shadow: 0 0 6px color-mix(in srgb, var(--se-text-dim) 60%, transparent);
}
.se-flow-node--logic {
background: var(--se-node-logic-bg);
border: 1px solid var(--se-gate-color, var(--se-accent));
padding: 12px 16px;
min-width: 110px;
box-shadow: 0 0 20px color-mix(in srgb, var(--se-accent) 20%, transparent);
}
.se-flow-node--logic.se-flow-node--sell-mode {
background: linear-gradient(145deg, color-mix(in srgb, var(--se-sell) 18%, transparent), color-mix(in srgb, var(--se-bg) 92%, transparent));
box-shadow: 0 0 20px color-mix(in srgb, var(--se-sell) 15%, transparent);
}
.se-flow-gate-badge {
font-weight: 800;
font-size: 0.88rem;
color: var(--se-accent);
letter-spacing: 0.06em;
}
.se-flow-gate-hint { font-size: 0.62rem; color: var(--se-text-dim); display: block; margin-top: 4px; }
.se-flow-node--cond {
padding: 10px 14px;
border: 1px solid var(--se-node-cond-border);
background: var(--se-node-cond-bg);
min-width: 170px;
box-shadow: 0 0 16px color-mix(in srgb, var(--se-success) 12%, transparent);
}
.se-flow-node--cross {
border-color: color-mix(in srgb, var(--se-gold) 50%, transparent);
background: linear-gradient(145deg, color-mix(in srgb, var(--se-gold) 14%, transparent), color-mix(in srgb, var(--se-bg) 92%, transparent));
box-shadow: 0 0 16px color-mix(in srgb, var(--se-gold) 12%, transparent);
}
.se-flow-node--cond.se-flow-node--sell-mode {
border-color: color-mix(in srgb, var(--se-sell) 45%, transparent);
box-shadow: 0 0 16px color-mix(in srgb, var(--se-sell) 12%, transparent);
}
.se-flow-cond-badge { font-size: 0.65rem; font-weight: 800; color: var(--se-success); margin-bottom: 4px; }
.se-flow-node--cross .se-flow-cond-badge { color: var(--se-gold); }
.se-flow-node--sell-mode .se-flow-cond-badge { color: var(--se-sell); }
.se-flow-cond-text { font-size: 0.7rem; line-height: 1.35; color: var(--se-node-text); word-break: break-word; }
.se-flow-node--selected {
outline: 2px solid color-mix(in srgb, var(--se-gold) 70%, transparent);
outline-offset: 2px;
}
.se-flow-node--orphan {
border-style: dashed !important;
opacity: 0.88;
box-shadow: 0 0 12px rgba(148, 163, 184, 0.2) !important;
}
.se-flow-node--orphan .se-flow-cond-badge,
.se-flow-node--orphan .se-flow-gate-badge {
opacity: 0.75;
}
.se-flow-node--drop {
box-shadow: 0 0 0 2px rgba(255, 204, 0, 0.55), 0 0 28px rgba(0, 212, 255, 0.25);
}
.se-flow-del {
position: absolute; top: 4px; right: 6px;
border: none; background: rgba(0, 0, 0, 0.4);
color: rgba(255, 77, 109, 0.9);
width: 18px; height: 18px; border-radius: 4px;
cursor: pointer; font-size: 0.85rem; line-height: 1;
opacity: 0; transition: opacity 0.12s;
}
.se-flow-node:hover .se-flow-del { opacity: 1; }
.se-flow-handle {
width: 9px !important; height: 9px !important;
background: var(--se-handle) !important;
border: 2px solid color-mix(in srgb, var(--se-bg) 80%, var(--se-accent)) !important;
box-shadow: 0 0 8px color-mix(in srgb, var(--se-accent) 60%, transparent);
opacity: 0.35;
transition: opacity 0.12s, transform 0.12s;
}
.se-flow-node:hover .se-flow-handle,
.se-flow-node.se-flow-node--selected .se-flow-handle,
.se-flow-node.se-flow-node--drop .se-flow-handle {
opacity: 1;
}
.se-flow-handle:hover {
opacity: 1 !important;
transform: scale(1.25);
}
.se-flow-handle--active {
opacity: 1 !important;
transform: scale(1.45);
background: var(--se-gold) !important;
border-color: color-mix(in srgb, var(--se-gold) 40%, var(--se-bg)) !important;
box-shadow: 0 0 14px color-mix(in srgb, var(--se-gold) 95%, transparent);
z-index: 2;
}
.se-flow-handle--valid-hover {
opacity: 1 !important;
transform: scale(1.35);
background: #34d399 !important;
border-color: #065f46 !important;
box-shadow: 0 0 12px rgba(52, 211, 153, 0.85);
z-index: 2;
}
.se-flow-handle--invalid {
opacity: 1 !important;
width: 16px !important;
height: 16px !important;
transform: scale(1.35);
background: rgba(15, 23, 42, 0.95) !important;
border-color: #f87171 !important;
box-shadow: 0 0 14px rgba(248, 113, 113, 0.85);
z-index: 3;
}
.se-flow-handle--invalid::after {
content: '×';
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: 800;
line-height: 1;
color: #f87171;
pointer-events: none;
}
.se-flow-handle--disabled {
opacity: 0.08 !important;
pointer-events: none !important;
box-shadow: none !important;
}
.se-flow-handle--out { opacity: 0.35; }
/* ── Node config bar ── */
.se-node-config-bar {
flex-shrink: 0;
margin: 6px 10px 0;
padding: 10px 12px;
border-radius: 10px;
border: 1px solid color-mix(in srgb, var(--se-accent) 25%, transparent);
background: var(--se-toolbar-bg);
box-shadow: 0 0 24px color-mix(in srgb, var(--se-accent) 8%, transparent);
}
.se-node-config-label {
display: inline-block;
font-size: 0.68rem;
font-weight: 800;
color: var(--se-accent);
padding: 2px 8px;
border: 1px solid color-mix(in srgb, var(--se-accent) 35%, transparent);
border-radius: 999px;
margin-bottom: 8px;
}
.se-sync-tip {
display: block;
margin-top: 6px;
font-size: 0.65rem;
color: color-mix(in srgb, var(--se-success) 75%, transparent);
}
.se-node-config-bar .sp-cond-editor { margin: 0; }
.se-node-config-bar .sp-cond-sel,
.se-node-config-bar .sp-cond-num {
background: var(--se-input-bg);
border-color: var(--se-input-border);
color: var(--se-text);
font-size: 0.72rem;
}
/* ── Terminal ── */
.se-terminal {
flex-shrink: 0;
display: flex;
flex-direction: column;
margin: 0 10px 10px;
border: 1px solid var(--se-terminal-border);
border-radius: 10px;
background: var(--se-terminal-bg);
overflow: hidden;
min-height: 88px;
}
.se-terminal-label {
flex-shrink: 0;
font-size: 0.62rem;
font-weight: 800;
letter-spacing: 0.14em;
color: var(--se-terminal-label);
padding: 6px 12px;
border-bottom: 1px solid var(--se-border);
}
.se-terminal-text {
flex: 1;
min-height: 0;
margin: 0;
padding: 10px 14px;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 0.78rem;
line-height: 1.55;
color: var(--se-terminal-code);
white-space: pre-wrap;
overflow-y: auto;
}
.se-terminal-text--rich {
display: block;
}
.se-formula-line + .se-formula-line {
margin-top: 0.35em;
}
.se-formula-punc {
color: var(--se-text-dim);
}
.se-formula-detail {
color: var(--se-text-muted);
}
.se-formula-empty,
.se-formula-comment {
color: var(--se-text-dim);
font-style: italic;
}
.se-formula-signal--buy {
color: var(--se-buy);
font-weight: 700;
}
.se-formula-signal--sell {
color: var(--se-sell);
font-weight: 700;
}
.se-formula-logic {
font-weight: 800;
letter-spacing: 0.03em;
}
.se-formula-logic--and { color: var(--se-palette-logic-and-accent); }
.se-formula-logic--or { color: var(--se-palette-logic-or-accent); }
.se-formula-logic--not { color: var(--se-palette-logic-not-accent); }
.se-formula-ind {
font-weight: 800;
}
.se-formula-ind--band { color: var(--se-palette-band-accent); }
.se-formula-ind--ind { color: var(--se-palette-ind-accent); }
/* ── Right palette ── */
.se-right {
flex: 0 0 260px;
width: 260px;
border-left: 1px solid var(--se-border);
display: flex;
flex-direction: column;
min-height: 0;
background: var(--se-palette-bg);
overflow: hidden;
}
.se-right-tabs {
display: flex;
border-bottom: 1px solid var(--se-border);
}
.se-right-tab {
flex: 1;
padding: 10px 6px;
border: none;
background: transparent;
color: var(--se-text-muted);
font-size: 0.76rem;
cursor: pointer;
}
.se-right-tab--on {
color: var(--se-tab-active);
box-shadow: inset 0 -2px 0 var(--se-tab-active);
}
.se-palette-search {
margin: 10px 10px 6px;
padding: 8px 10px;
border-radius: 8px;
border: 1px solid var(--se-input-border);
background: var(--se-input-bg);
color: var(--se-text);
font-size: 0.78rem;
}
.se-palette-search:focus {
outline: none;
border-color: var(--se-input-focus);
box-shadow: 0 0 12px color-mix(in srgb, var(--se-accent) 12%, transparent);
}
.se-palette-section { padding: 0 10px 10px; }
.se-palette-section--scroll { flex: 1; overflow-y: auto; min-height: 0; }
.se-palette-section h3 {
margin: 0 0 8px;
font-size: 0.65rem;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--se-text-dim);
}
.se-palette-section--logic h3 { color: var(--se-palette-section-logic); }
.se-palette-section--band h3 { color: var(--se-palette-section-band); }
.se-palette-section--aux h3 { color: var(--se-palette-section-ind); }
.se-palette-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px;
}
.se-palette-grid--3 { grid-template-columns: repeat(3, 1fr); }
.se-palette-card {
border-radius: 8px;
padding: 8px;
cursor: grab;
border: 1px solid var(--se-border);
background: var(--se-palette-card-bg);
transition: transform 0.12s, box-shadow 0.12s, border-color 0.12s, background 0.12s;
}
.se-palette-card:hover {
transform: translateY(-2px);
}
/* ── 논리 연산: AND / OR / NOT ── */
.se-palette-card--logic-and {
border-color: color-mix(in srgb, var(--se-palette-logic-and-accent) 42%, transparent);
background: var(--se-palette-logic-and-bg);
box-shadow: inset 3px 0 0 var(--se-palette-logic-and-accent);
}
.se-palette-card--logic-and .se-palette-card-icon {
background: color-mix(in srgb, var(--se-palette-logic-and-accent) 22%, transparent);
color: var(--se-palette-logic-and-accent);
}
.se-palette-card--logic-and:hover {
border-color: color-mix(in srgb, var(--se-palette-logic-and-accent) 65%, transparent);
box-shadow: inset 3px 0 0 var(--se-palette-logic-and-accent), 0 4px 14px color-mix(in srgb, var(--se-palette-logic-and-accent) 22%, transparent);
}
.se-palette-card--logic-or {
border-color: color-mix(in srgb, var(--se-palette-logic-or-accent) 42%, transparent);
background: var(--se-palette-logic-or-bg);
box-shadow: inset 3px 0 0 var(--se-palette-logic-or-accent);
}
.se-palette-card--logic-or .se-palette-card-icon {
background: color-mix(in srgb, var(--se-palette-logic-or-accent) 22%, transparent);
color: var(--se-palette-logic-or-accent);
}
.se-palette-card--logic-or:hover {
border-color: color-mix(in srgb, var(--se-palette-logic-or-accent) 65%, transparent);
box-shadow: inset 3px 0 0 var(--se-palette-logic-or-accent), 0 4px 14px color-mix(in srgb, var(--se-palette-logic-or-accent) 22%, transparent);
}
.se-palette-card--logic-not {
border-color: color-mix(in srgb, var(--se-palette-logic-not-accent) 42%, transparent);
background: var(--se-palette-logic-not-bg);
box-shadow: inset 3px 0 0 var(--se-palette-logic-not-accent);
}
.se-palette-card--logic-not .se-palette-card-icon {
background: color-mix(in srgb, var(--se-palette-logic-not-accent) 22%, transparent);
color: var(--se-palette-logic-not-accent);
}
.se-palette-card--logic-not:hover {
border-color: color-mix(in srgb, var(--se-palette-logic-not-accent) 65%, transparent);
box-shadow: inset 3px 0 0 var(--se-palette-logic-not-accent), 0 4px 14px color-mix(in srgb, var(--se-palette-logic-not-accent) 22%, transparent);
}
/* ── 밴드 · 추세 ── */
.se-palette-card--band {
border-color: color-mix(in srgb, var(--se-palette-band-accent) 42%, transparent);
background: var(--se-palette-band-bg);
box-shadow: inset 3px 0 0 var(--se-palette-band-accent);
}
.se-palette-card--band .se-palette-card-icon {
background: color-mix(in srgb, var(--se-palette-band-accent) 22%, transparent);
color: var(--se-palette-band-accent);
}
.se-palette-card--band:hover {
border-color: color-mix(in srgb, var(--se-palette-band-accent) 65%, transparent);
box-shadow: inset 3px 0 0 var(--se-palette-band-accent), 0 4px 14px color-mix(in srgb, var(--se-palette-band-accent) 22%, transparent);
}
/* ── 보조지표 ── */
.se-palette-card--ind {
border-color: color-mix(in srgb, var(--se-palette-ind-accent) 42%, transparent);
background: var(--se-palette-ind-bg);
box-shadow: inset 3px 0 0 var(--se-palette-ind-accent);
}
.se-palette-card--ind .se-palette-card-icon {
background: color-mix(in srgb, var(--se-palette-ind-accent) 22%, transparent);
color: var(--se-palette-ind-accent);
}
.se-palette-card--ind:hover {
border-color: color-mix(in srgb, var(--se-palette-ind-accent) 65%, transparent);
box-shadow: inset 3px 0 0 var(--se-palette-ind-accent), 0 4px 14px color-mix(in srgb, var(--se-palette-ind-accent) 22%, transparent);
}
.se-palette-card-head { display: flex; align-items: flex-start; gap: 6px; }
.se-palette-card-icon {
width: 24px; height: 24px; border-radius: 6px;
display: flex; align-items: center; justify-content: center;
font-size: 0.72rem; font-weight: 800;
flex-shrink: 0;
transition: background 0.12s, color 0.12s;
}
.se-palette-card-meta { min-width: 0; }
.se-palette-card-name { font-size: 0.68rem; font-weight: 700; line-height: 1.2; display: block; }
.se-palette-card-desc { font-size: 0.58rem; color: var(--se-text-dim); display: block; }
.se-palette-card-period {
display: flex; align-items: center; gap: 4px;
margin-top: 6px; font-size: 0.58rem; color: var(--se-text-dim);
}
.se-palette-period-input {
width: 36px; text-align: center;
border: 1px solid var(--se-input-border);
border-radius: 4px;
background: var(--se-input-bg);
color: var(--se-text); font-size: 0.58rem; padding: 2px;
}
.se-palette-sync { color: var(--se-success); font-size: 0.65rem; }
.se-template-list { padding: 10px; overflow-y: auto; flex: 1; }
.se-template-item {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px 8px;
width: 100%;
padding: 10px 12px;
margin-bottom: 6px;
border-radius: 8px;
border: 1px solid var(--se-border);
background: var(--se-palette-card-bg);
color: var(--se-text);
cursor: pointer;
text-align: left;
transition: border-color 0.12s, box-shadow 0.12s;
}
.se-template-item:hover {
border-color: var(--se-palette-hover-border);
box-shadow: 0 0 12px color-mix(in srgb, var(--se-gold) 10%, transparent);
}
.se-template-label { font-size: 0.76rem; flex: 1 1 auto; }
.se-template-desc {
flex: 1 1 100%;
font-size: 0.66rem;
line-height: 1.35;
color: var(--se-text-muted);
}
.se-template-signal { font-size: 0.62rem; font-weight: 700; padding: 2px 6px; border-radius: 4px; margin-left: auto; }
.se-template-signal--buy { color: var(--se-buy); background: color-mix(in srgb, var(--se-buy) 12%, transparent); }
.se-template-signal--sell { color: var(--se-sell); background: color-mix(in srgb, var(--se-sell) 12%, transparent); }
/* ── Modal / snack ── */
.se-field-lbl { display: block; font-size: 0.72rem; color: var(--se-text-muted); margin: 8px 0 4px; }
.se-field-inp, .se-field-ta {
width: 100%; box-sizing: border-box;
border: 1px solid var(--se-input-border);
border-radius: 8px;
background: var(--se-input-bg);
color: var(--se-text); padding: 7px 10px; font-size: 0.8rem;
}
.se-modal-body { padding: 4px 0; }
.se-modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.se-snack {
position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
padding: 10px 18px; border-radius: 10px; font-size: 0.82rem; z-index: 9999;
background: color-mix(in srgb, var(--se-success) 92%, #000);
color: var(--se-success);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.se-snack--err {
background: color-mix(in srgb, var(--se-danger) 92%, #000);
color: var(--se-danger);
}
@media (max-width: 1100px) {
.se-right { flex: 0 0 220px; width: 220px; }
}