/* 매매 시그널 알림 목록 — 갤러리 행 (요약 카드 + 가로 스크롤 차트) */ /* 실시간 WS/STOMP 수신 — 목록 행(.tnl-row) 외곽 아웃라인만 형광 연두 (내부 inset 없음) */ .tnl-row.tnl-row--receiving { border-color: var(--gc-receive-border) !important; box-shadow: var(--gc-receive-shadow); transition: box-shadow 0.15s ease-out, border-color 0.15s ease-out; } /* 수신 시 알림 상태 카드(좌측 요약)에는 연두 효과 미적용 */ .tnl-row.tnl-row--receiving .tnl-row-gallery-detail .tnl-hscroll-pane, .tnl-row.tnl-row--receiving .tnl-summary-card { box-shadow: none !important; background: var(--se-panel-card-bg, var(--bg2)); transition: border-color 0.15s ease-out; } .tnl-row.tnl-row--receiving .tnl-row-gallery-detail .tnl-hscroll-pane { border-color: var(--se-border, var(--border)); background: color-mix(in srgb, var(--bg) 40%, var(--bg2)); } .tnl-row.tnl-row--receiving .tnl-summary-card--buy { border-color: color-mix(in srgb, var(--gc-trade-buy) 35%, var(--se-border, var(--border))); } .tnl-row.tnl-row--receiving .tnl-summary-card--sell { border-color: color-mix(in srgb, var(--gc-trade-sell) 35%, var(--se-border, var(--border))); } .tnl-row.tnl-row--receiving.tnl-row--selected .tnl-summary-card--selected { border-color: var(--accent, #7aa2f7); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #7aa2f7) 35%, transparent); } /* 수신 시 신호 상세(vtd-card) — 연두 테두리·inset 제거 (목록 행 외곽만 유지) */ .tnl-row.tnl-row--receiving .tnl-signal-slot .vtd-card--receiving, .tnl-row.tnl-row--receiving .tnl-signal-slot .vtd-card.vtd-card--live { border-color: color-mix(in srgb, var(--accent, #3f7ef5) 40%, var(--se-border, var(--border))) !important; box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #3f7ef5) 12%, transparent) !important; background: var(--se-panel-card-bg, var(--bg2)) !important; } .tnl-row.tnl-row--receiving .tnl-signal-slot .vtd-card--receiving .vtd-sig-panel, .tnl-row.tnl-row--receiving .tnl-signal-slot .vtd-card--receiving .vtd-card-chart-panel, .tnl-row.tnl-row--receiving .tnl-signal-slot .vtd-sig-panel-wrap--receiving .vtd-sig-panel { box-shadow: none !important; } .tnl-row--gallery { display: block; width: 100%; overflow: visible; box-sizing: border-box; } /* 목록 한 줄 = 알림상세 · 신호일치율 · 통합차트(캔들+보조지표) — 가로 100% 꽉 참 */ .tnl-row-gallery { --tnl-summary-card-width: 260px; --tnl-signal-slot-width: 280px; --tnl-chart-card-width: 312px; --tnl-row-inner-h: 340px; display: flex; flex-direction: row; align-items: stretch; gap: 10px; width: 100%; height: calc(var(--tnl-row-inner-h) + 20px); max-height: calc(var(--tnl-row-inner-h) + 20px); padding: 10px; box-sizing: border-box; } .tnl-row-gallery-detail { flex: 0.88 1 0; min-width: 0; } .tnl-row-gallery-signal { flex: 0.92 1 0; min-width: 0; } .tnl-row-gallery-candle { flex: 1.12 1 0; min-width: 0; height: var(--tnl-row-inner-h, 420px); max-height: var(--tnl-row-inner-h, 420px); display: flex; flex-direction: column; align-items: stretch; border-radius: 12px; border: 1px solid var(--se-border, var(--border)); background: color-mix(in srgb, var(--bg) 40%, var(--bg2)); overflow: hidden; box-sizing: border-box; } .tnl-row-gallery-candle > .tnl-chart-card { flex: 1 1 auto; width: 100%; min-width: 0; max-width: none; height: 100%; max-height: 100%; border: none; border-radius: 0; } .tnl-row-gallery-indicators { flex: 1.12 1 0; min-width: 0; } .tnl-row-gallery > .tnl-hscroll-pane, .tnl-row-gallery > .tnl-row-gallery-candle { height: var(--tnl-row-inner-h, 420px); max-height: var(--tnl-row-inner-h, 420px); } /* ── 통합 차트 영역 (캔들 위, 보조지표 아래) ───────────────────── */ .tnl-row-gallery-combined-chart { flex: 2.24 1 0; /* 구 캔들(1.12) + 구 보조지표(1.12) 합산 */ min-width: 0; height: var(--tnl-row-inner-h, 420px); max-height: var(--tnl-row-inner-h, 420px); display: flex; flex-direction: column; align-items: stretch; border-radius: 12px; border: 1px solid var(--se-border, var(--border)); background: color-mix(in srgb, var(--bg) 40%, var(--bg2)); overflow: hidden; box-sizing: border-box; position: relative; } .tnl-row-gallery-combined-chart > .tnl-chart-card { flex: 1 1 auto; width: 100%; min-width: 0; max-width: none; height: 100%; max-height: 100%; border: none; border-radius: 0; } /* 전체보기 상태에서 통합 차트가 나머지 공간을 모두 차지 */ .tnl-row-gallery--chart-expanded .tnl-row-gallery-combined-chart { flex: 1 1 0; min-width: 0; height: var(--tnl-row-inner-h, 420px); max-height: var(--tnl-row-inner-h, 420px); } .tnl-row-gallery-combined-chart--expanded { flex: 1 1 0 !important; } /* 지표 로딩 중 오버레이 */ .tnl-combined-chart-placeholder { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 0.75rem; color: var(--text3, var(--se-text-muted)); background: color-mix(in srgb, var(--bg2) 65%, transparent); pointer-events: none; z-index: 2; } .tnl-row-gallery .tnl-chart-card { height: 100%; max-height: 100%; } .tnl-row-gallery--chart-expanded .tnl-row-gallery-detail { flex: 0 0 min(24%, var(--tnl-summary-card-width)); width: min(24%, var(--tnl-summary-card-width)); min-width: min(200px, var(--tnl-summary-card-width)); max-width: var(--tnl-summary-card-width); } .tnl-row-gallery--chart-expanded .tnl-row-gallery-indicators { flex: 1 1 0; min-width: 0; } /* 가로 스크롤 + 우측 세로 레일 버튼 */ .tnl-hscroll-pane { display: flex; flex-direction: row; align-items: stretch; min-width: 0; min-height: 0; height: var(--tnl-row-inner-h, 420px); max-height: var(--tnl-row-inner-h, 420px); border-radius: 12px; border: 1px solid var(--se-border, var(--border)); background: color-mix(in srgb, var(--bg) 40%, var(--bg2)); overflow: hidden; box-sizing: border-box; isolation: isolate; } .tnl-hscroll-pane__viewport { flex: 1 1 0; min-width: 0; height: 100%; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--text3) 35%, transparent) transparent; } .tnl-hscroll-pane__viewport::-webkit-scrollbar { height: 6px; } .tnl-hscroll-pane__viewport::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--text3) 35%, transparent); border-radius: 4px; } .tnl-hscroll-pane__content { display: flex; flex-direction: row; align-items: stretch; height: 100%; min-height: 0; box-sizing: border-box; } .tnl-row-gallery-signal .tnl-hscroll-pane__viewport { overflow-x: hidden; } .tnl-row-gallery-signal .tnl-hscroll-pane__content { width: 100%; min-width: 100%; } .tnl-row-gallery-indicators--scroll .tnl-hscroll-pane__viewport { overflow-x: auto; } .tnl-row-gallery-indicators--scroll .tnl-hscroll-pane__content { width: max-content; min-width: max-content; } .tnl-row-gallery-indicators:not(.tnl-row-gallery-indicators--scroll) .tnl-hscroll-pane__viewport { overflow-x: hidden; } .tnl-row-gallery-indicators:not(.tnl-row-gallery-indicators--scroll) .tnl-hscroll-pane__content { width: 100%; min-width: 100%; } .tnl-row-gallery-indicators--expanded .tnl-hscroll-pane__content { min-width: 100%; width: 100%; } .tnl-row-gallery-indicators--expanded .tnl-hscroll-pane__viewport { overflow-x: hidden; } .tnl-hscroll-pane__rail { position: relative; z-index: 4; flex: 0 0 32px; width: 32px; display: flex; flex-direction: column; align-items: stretch; justify-content: center; gap: 8px; padding: 8px 4px; border-left: 1px solid var(--se-border, var(--border)); background: color-mix(in srgb, var(--bg3, var(--bg2)) 85%, transparent); box-sizing: border-box; } .tnl-hscroll-pane__rail-btn { flex: 1 1 0; min-height: 44px; max-height: 96px; margin: 0; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: 1px solid color-mix(in srgb, var(--accent, #3f7ef5) 28%, var(--se-border, var(--border))); border-radius: 8px; background: color-mix(in srgb, var(--bg2) 90%, transparent); color: var(--accent, #3f7ef5); cursor: pointer; transition: background 0.15s, border-color 0.15s, opacity 0.15s, transform 0.1s; } .tnl-hscroll-pane__rail-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--accent, #3f7ef5) 16%, var(--bg2)); border-color: var(--accent, #3f7ef5); } .tnl-hscroll-pane__rail-btn:active:not(:disabled) { transform: scale(0.96); } .tnl-hscroll-pane__rail-btn:disabled { opacity: 0.35; cursor: default; color: var(--text3); border-color: var(--se-border, var(--border)); } /* 좌측 알림 상세(매매 시그널 요약 카드) */ .tnl-row-gallery-detail .tnl-hscroll-pane__viewport { overflow-x: hidden; } .tnl-row-gallery-detail .tnl-hscroll-pane__content { min-width: 100%; width: 100%; } .tnl-row-gallery-detail .tnl-hscroll-pane { width: 100%; } .tnl-row-gallery-detail .tnl-summary-card { flex: 1 1 auto; width: 100%; min-width: 0; max-width: none; height: 100%; } /* 신호상세 — 갤러리 행에서는 슬롯 너비 100% */ .tnl-signal-slot { flex: 0 0 var(--tnl-signal-slot-width); width: var(--tnl-signal-slot-width); min-width: var(--tnl-signal-slot-width); max-width: var(--tnl-signal-slot-width); height: 280px; max-height: 280px; display: flex; flex-direction: column; min-height: 0; box-sizing: border-box; } .tnl-row-gallery-signal .tnl-signal-slot { flex: 1 1 auto; width: 100%; min-width: 0; max-width: none; height: 100%; max-height: 100%; } .tnl-signal-slot .tnl-signal-summary--embedded-wrap { flex: 1; min-height: 0; height: 100%; display: flex; flex-direction: column; overflow: visible; } .tnl-signal-slot .tnl-signal-summary--embedded-wrap > .vtd-card { flex: 1; width: 100%; height: 100%; min-height: 0; max-height: 100%; align-self: stretch; overflow: visible; box-sizing: border-box; } .tnl-signal-slot .tnl-signal-summary--embedded-wrap > .vtd-card > .vtd-sig-panel-wrap--summary { flex: 0 0 auto; min-height: 0; overflow: visible; } .tnl-signal-slot .tnl-signal-summary--embedded-wrap .vtd-sig-panel--summary { flex: 0 0 auto; overflow: visible; } .tnl-signal-slot .tnl-signal-summary--embedded-wrap .vtd-sig-visual { flex: 0 0 auto; min-height: 0; overflow: visible; } /* 가상매매와 동일 vtd-sig-* (strategyEditorTheme + virtualTradingDashboard) */ .tnl-signal-slot .tnl-signal-summary--embedded-wrap > .vtd-card > .vtd-card-chart-panel { flex: 1; min-height: 0; } .tnl-signal-slot .tnl-signal-summary--embedded-wrap .vtd-card-foot-select:disabled { opacity: 1; cursor: default; color: var(--se-text); max-width: 200px; } /* 신호 상세 헤더 — 우측 현재가·등락·실시간 (아이콘/토글 버튼 없음) */ .tnl-signal-slot .vtd-card--head-inline-quote .vtd-card-head { flex-shrink: 0; padding-bottom: 2px; } .tnl-signal-slot .vtd-card-head-quote { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-left: auto; } .tnl-signal-slot .vtd-card-head-quote .vtd-target-quote--compact { display: inline-flex; align-items: baseline; gap: 6px; margin: 0; padding: 0; flex: 0 1 auto; min-width: 0; } .tnl-signal-slot .vtd-card-head-quote .vtd-target-price { font-size: 13px; font-weight: 700; line-height: 1.2; white-space: nowrap; } .tnl-signal-slot .vtd-card-head-quote .vtd-target-change { font-size: 11px; font-weight: 600; white-space: nowrap; } .tnl-signal-slot .vtd-card-head-quote .vtd-live-badge { flex-shrink: 0; } /* 가상매매 투자대상 카드(vtd)와 동일한 3단 구성 */ .tnl-summary-card { flex: 1 1 auto; width: 100%; min-width: 0; height: 100%; max-height: 100%; align-self: stretch; display: flex; flex-direction: column; border: 1px solid color-mix(in srgb, var(--accent, #7aa2f7) 28%, var(--se-border, var(--border))); border-radius: 12px; background: var(--se-panel-card-bg, var(--bg2)); overflow: hidden; box-sizing: border-box; } .tnl-row-gallery-detail .tnl-summary-card { min-width: 0; } .tnl-summary-card--buy { border-color: color-mix(in srgb, var(--gc-trade-buy) 35%, var(--se-border, var(--border))); } .tnl-summary-card--sell { border-color: color-mix(in srgb, var(--gc-trade-sell) 35%, var(--se-border, var(--border))); } .tnl-summary-panel { flex: 1; min-height: 0; width: 100%; padding: 10px 14px 10px; border: none; background: transparent; color: inherit; text-align: left; cursor: pointer; display: flex; flex-direction: column; gap: 0; justify-content: space-between; overflow: hidden; box-sizing: border-box; } .tnl-summary-panel:hover { background: color-mix(in srgb, var(--accent, #7aa2f7) 6%, transparent); } /* 1행: 종목명 */ .tnl-summary-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-shrink: 0; } .tnl-summary-title { display: flex; flex-direction: row; align-items: baseline; flex-wrap: nowrap; gap: 8px; min-width: 0; flex: 1; } .tnl-summary-ko { font-size: 15px; font-weight: 700; line-height: 1.2; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .tnl-summary-sym { font-size: 12px; font-weight: 600; color: var(--text3, var(--se-text-muted)); white-space: nowrap; flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tnl-summary-head-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; } .tnl-summary-dot { flex-shrink: 0; } /* 2행: 페어 · 시그널 가격 */ .tnl-summary-quote { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-shrink: 0; padding: 1px 2px; } .tnl-summary-quote-left { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1; } .tnl-summary-arrow { font-size: 11px; line-height: 1; flex-shrink: 0; } .tnl-summary-arrow--buy { color: var(--gc-trade-buy); } .tnl-summary-arrow--sell { color: var(--gc-trade-sell); } .tnl-summary-pair { font-size: 12px; font-weight: 600; color: var(--text3, var(--se-text-muted)); white-space: nowrap; } .tnl-summary-type { font-size: 12px; font-weight: 700; white-space: nowrap; } .tnl-summary-type--buy { color: var(--gc-trade-buy); } .tnl-summary-type--sell { color: var(--gc-trade-sell); } .tnl-summary-quote-right { display: flex; align-items: baseline; flex-shrink: 0; margin-left: auto; } .tnl-summary-price { font-size: 17px; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; line-height: 1.1; } .tnl-summary-price--buy { color: var(--gc-trade-buy); } .tnl-summary-price--sell { color: var(--gc-trade-sell); } /* 3행+: 상세 정보 */ .tnl-summary-meta { flex: 0 0 auto; display: flex; flex-direction: column; gap: 5px; overflow-y: visible; overflow-x: hidden; padding-right: 2px; } .tnl-summary-info-row { display: grid; grid-template-columns: 80px minmax(0, 1fr); align-items: start; gap: 5px 10px; } /* 캔들 시각 — 10분봉·15분봉 등 분봉 라벨이 다음 줄로 밀리지 않도록 */ .tnl-summary-info-row--candle { grid-template-columns: 80px minmax(100px, 1fr); } .tnl-summary-info-val--candle { word-break: keep-all; overflow-wrap: normal; } .tnl-summary-info-val--candle .tnl-candle-interval { white-space: nowrap; } .tnl-summary-info-lbl { font-size: 11px; font-weight: 600; color: var(--text3, var(--se-text-muted)); line-height: 1.4; flex-shrink: 0; } .tnl-summary-info-val { font-size: 12px; font-weight: 500; color: var(--text2); line-height: 1.4; word-break: break-word; text-align: right; } .tnl-summary-info-val--hi { font-weight: 700; color: var(--text); } /* 하단: 투자전략 (vtd-target-strategy-field) */ /* ── 전략명 태그 (헤더 바로 아래) ──────────────────────────────── */ .tnl-summary-strategy-tag { display: flex; align-items: center; gap: 5px; padding: 4px 9px; border-radius: 5px; background: var(--bg2, rgba(255,255,255,0.06)); border: 1px solid var(--border, rgba(255,255,255,0.1)); width: fit-content; max-width: 100%; overflow: hidden; flex-shrink: 0; } .tnl-summary-strategy-tag-ic { font-size: 0.65rem; flex-shrink: 0; opacity: 0.75; } .tnl-summary-strategy-tag-name { font-size: 0.72rem; font-weight: 600; color: var(--text2, var(--se-text-muted)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* 그리드 레이아웃에서 전략 태그 약간 작게 */ .tnl-summary-card--grid .tnl-summary-strategy-tag { padding: 3px 7px; } .tnl-summary-card--grid .tnl-summary-strategy-tag-name { font-size: 0.68rem; } .tnl-summary-strategy-field { display: flex; align-items: center; gap: 8px; flex-shrink: 0; width: 100%; padding-top: 8px; border-top: 1px solid var(--border); } .tnl-summary-strategy-lbl { font-size: 11px; font-weight: 600; color: var(--text3, var(--se-text-muted)); white-space: nowrap; flex-shrink: 0; } .tnl-summary-strategy-box { flex: 1; min-width: 0; padding: 5px 10px; border-radius: 6px; border: 1px solid var(--se-border, var(--border)); background: var(--bg, var(--bg3)); color: var(--text); font-size: 12px; font-weight: 600; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; } .tnl-summary-card-actions { display: flex; align-items: center; gap: 4px; padding: 6px 10px; border-top: 1px solid var(--border); background: var(--bg3, var(--se-center-bg)); flex-shrink: 0; } /* 상세 · 차트 · 매매 — 동일 세그먼트 버튼 */ .tnl-summary-card-actions .tnl-row-action, .tnl-summary-card-actions .tnl-row-chart, .tnl-summary-card-actions .tnl-row-trade { display: inline-flex; align-items: center; justify-content: center; height: 32px; padding: 0 14px; margin: 0; border: 1px solid var(--border); border-radius: 0; background: transparent; color: var(--text2); font-size: 12px; font-weight: 500; cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s; } .tnl-summary-card-actions .tnl-row-action { border-radius: 6px 0 0 6px; } .tnl-summary-card-actions .tnl-row-chart, .tnl-summary-card-actions .tnl-row-trade { margin-left: -1px; border-left: none; } .tnl-summary-card-actions .tnl-row-trade { border-radius: 0 6px 6px 0; } .tnl-summary-card-actions:not(:has(.tnl-row-trade)) .tnl-row-chart { border-radius: 0 6px 6px 0; } .tnl-summary-card-actions .tnl-row-action:hover, .tnl-summary-card-actions .tnl-row-chart:hover, .tnl-summary-card-actions .tnl-row-trade:hover { background: var(--bg4); color: var(--text); z-index: 1; } .tnl-row-report { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; margin-left: 2px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text3); cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s; flex-shrink: 0; } .tnl-row-report:hover:not(:disabled) { background: color-mix(in srgb, var(--se-gold, #e6c200) 14%, transparent); color: var(--se-gold, #e6c200); border-color: color-mix(in srgb, var(--se-gold, #e6c200) 40%, transparent); } .tnl-row-report:disabled { opacity: 0.45; cursor: wait; } .tnl-row-report--loading svg { animation: spin 0.8s linear infinite; } .tnl-charts-expanded-inner { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 100%; width: 100%; height: 100%; padding: 0 4px 4px; box-sizing: border-box; } .tnl-charts-expanded-inner .tnl-chart-card--expanded { flex: 1; width: 100%; height: 100%; max-height: none; border: none; border-radius: 0; gap: 8px; box-sizing: border-box; } .tnl-charts-track { display: flex; flex-direction: row; align-items: stretch; gap: 10px; padding: 10px; height: 100%; box-sizing: border-box; width: max-content; min-width: max-content; flex-shrink: 0; } .tnl-charts-track > .tnl-chart-card { flex: 0 0 var(--tnl-chart-card-width); width: var(--tnl-chart-card-width); min-width: var(--tnl-chart-card-width); max-width: var(--tnl-chart-card-width); } /* 보조지표 1개 — 슬롯 너비 100% 채움 */ .tnl-row-gallery-indicators:not(.tnl-row-gallery-indicators--scroll) .tnl-charts-track--indicators-only { width: 100%; min-width: 100%; max-width: 100%; } .tnl-row-gallery-indicators:not(.tnl-row-gallery-indicators--scroll) .tnl-charts-track--indicators-only > .tnl-chart-card, .tnl-row-gallery-indicators:not(.tnl-row-gallery-indicators--scroll) .tnl-charts-track--indicators-only > .tnl-chart-card--placeholder { flex: 1 1 auto; width: 100%; min-width: 0; max-width: none; } /* 보조지표 2개↑ — 우측 슬롯 안에서만 스크롤, 페이지당 1장 = 슬롯 너비 */ .tnl-row-gallery-indicators--scroll .tnl-charts-track--indicators-only { width: max-content; min-width: max-content; } .tnl-row-gallery-indicators--scroll .tnl-charts-track--indicators-only > .tnl-chart-card { flex: 0 0 var(--tnl-hscroll-page-width, 240px); width: var(--tnl-hscroll-page-width, 240px); min-width: var(--tnl-hscroll-page-width, 240px); max-width: var(--tnl-hscroll-page-width, 240px); flex-shrink: 0; } .tnl-charts-track--indicators-only:not(:has(.tnl-chart-card)) { min-width: 100%; } .tnl-chart-card { position: relative; flex: 0 0 var(--tnl-chart-card-width); width: var(--tnl-chart-card-width); min-width: var(--tnl-chart-card-width); height: 280px; max-height: 280px; display: flex; flex-direction: column; gap: 6px; border: 1px solid var(--se-border, var(--border)); border-radius: 10px; background: var(--se-panel-card-bg, var(--bg2)); overflow: hidden; box-sizing: border-box; } .tnl-chart-card-body { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; } .tnl-chart-card--expanded .tnl-chart-card-body { flex: 1; min-height: 0; } .tnl-chart-card--placeholder { align-items: center; justify-content: center; } .tnl-chart-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px 0; flex-shrink: 0; } .tnl-chart-card-label { font-size: 12px; font-weight: 700; } /* 보조지표 스크롤 — 뷰포트에 완전히 들어오지 않은 카드는 라벨 숨김 */ .tnl-chart-card--peek .tnl-chart-card-head { visibility: hidden; pointer-events: none; } .tnl-chart-card-meta { font-size: 10px; color: var(--text3); font-weight: 600; } .tnl-mini-chart-canvas { position: relative; flex: 1 1 auto; width: 100%; min-width: 0; min-height: 0; height: 100%; max-height: 100%; display: flex; flex-direction: column; overflow: hidden; box-sizing: border-box; } .tnl-mini-chart-canvas--fill { flex: 1 1 auto; height: 100%; max-height: none; } .tnl-mini-chart-canvas > .tv-chart-wrap { flex: 1 1 0; min-height: 0; max-height: 100%; width: 100%; overflow: hidden !important; } /* 보조지표 pane 좌측 상단 지표명 — 우측 가격축만 비우고 전체 이름 표시 */ .tnl-mini-chart-canvas .pane-legend-item { right: 46px; width: auto; max-width: none; } .tnl-mini-chart-canvas .pane-legend-name { font-size: 10px; flex: 0 0 auto; max-width: none; overflow: visible; text-overflow: clip; white-space: nowrap; } /* 캔들 pane 우측 상단 오버레이 on/off (미니 차트) */ .tnl-mini-chart-canvas .chart-right-toolbar--overlay-only .chart-right-toolbar-btn { width: 24px; height: 24px; min-width: 24px; min-height: 24px; } .tnl-mini-chart-loading { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; font-size: 11px; color: var(--text3); background: color-mix(in srgb, var(--bg2) 80%, transparent); } .tnl-mini-chart-placeholder { flex: 1 1 auto; width: 100%; min-height: 120px; height: 100%; max-height: 100%; display: flex; align-items: center; justify-content: center; font-size: 11px; color: var(--text3); box-sizing: border-box; } .tnl-mini-chart-placeholder--fill { flex: 1; height: 100%; max-height: none; } /* 차트 하단 우측 — 펼쳐보기 / 원래보기 */ .tnl-chart-view-btn { position: absolute; right: 8px; bottom: 8px; z-index: 4; display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; padding: 0; border: 1px solid color-mix(in srgb, var(--accent, #3f7ef5) 35%, var(--se-border, var(--border))); border-radius: 8px; background: color-mix(in srgb, var(--bg2) 88%, transparent); color: var(--accent, #3f7ef5); cursor: pointer; box-shadow: 0 2px 8px color-mix(in srgb, var(--bg) 50%, transparent); transition: background 0.15s, border-color 0.15s, transform 0.1s; } .tnl-chart-view-btn:hover { background: color-mix(in srgb, var(--accent, #3f7ef5) 18%, var(--bg2)); border-color: var(--accent, #3f7ef5); } .tnl-chart-view-btn:active { transform: scale(0.96); } .tnl-chart-view-btn--restore { color: var(--text2); border-color: var(--se-border, var(--border)); background: color-mix(in srgb, var(--bg3) 92%, transparent); } .tnl-chart-view-btn--restore:hover { color: var(--text); border-color: var(--accent, #7aa2f7); background: color-mix(in srgb, var(--accent, #7aa2f7) 12%, var(--bg3)); } .tnl-muted { font-size: 12px; color: var(--text3); margin: 0; } .tnl-list--gallery { gap: 12px; } .tnl-list.vl-scroll { list-style: none; margin: 0; padding: 4px 4px 16px; } .tnl-list.vl-scroll.tnl-list--gallery .vl-scroll-row { padding-bottom: 12px; } .tnl-list.vl-scroll.tnl-list--grid { padding: 4px 4px 16px; } /* 우측 매매·호가 패널 접기/펼치기 */ .tnl-side-wrap--right { display: flex; flex-direction: row; align-items: stretch; flex-shrink: 0; min-height: 0; height: 100%; position: relative; z-index: 8; } .tnl-page--right-collapsed .tnl-main { flex: 1; min-width: 0; } /* 우측 패널 너비: styles/tradeRightPanel.css (--gc-trade-right-panel-*) */ .tnl-side-wrap--right:not(.tnl-side-wrap--open) .tnl-right-tabs, .tnl-side-wrap--right:not(.tnl-side-wrap--open) .tnl-right-body { visibility: hidden; pointer-events: none; } /* ── 검색 박스 ─────────────────────────────────────────────── */ .tnl-search-box { display: flex; align-items: center; gap: 6px; padding: 0 10px; height: 32px; border: 1px solid var(--se-border, var(--border)); border-radius: 8px; background: var(--bg2, var(--se-panel-card-bg)); flex-shrink: 0; min-width: 180px; max-width: 240px; transition: border-color 0.15s; } .tnl-search-box:focus-within, .tnl-search-box--active { border-color: var(--accent, #3f7ef5); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #3f7ef5) 25%, transparent); } .tnl-search-icon { flex-shrink: 0; color: var(--text3, var(--se-text-muted)); opacity: 0.7; } .tnl-search-input { flex: 1; border: none; background: transparent; color: var(--text); font-size: 12px; outline: none; min-width: 0; line-height: 1.4; } .tnl-search-input::placeholder { color: var(--text3, var(--se-text-muted)); opacity: 0.7; } .tnl-search-clear { display: flex; align-items: center; justify-content: center; width: 16px; height: 16px; flex-shrink: 0; border: none; background: transparent; color: var(--text3, var(--se-text-muted)); cursor: pointer; padding: 0; font-size: 10px; border-radius: 50%; transition: color 0.15s, background 0.15s; } .tnl-search-clear:hover { color: var(--text); background: color-mix(in srgb, var(--text3) 15%, transparent); } /* 툴바 — 좌: 필터·액션 · 우: 목록/그리드·배치·삭제 */ .tnl-page--with-right .tnl-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; } .tnl-toolbar-selects { display: flex; align-items: center; gap: 8px; flex-shrink: 0; } .tnl-toolbar-select, .tnl-candle-filter-select { height: 32px; min-width: 108px; padding: 0 10px; border: 1px solid var(--se-border, var(--border)); border-radius: 8px; background: var(--bg2, var(--se-panel-card-bg)); color: var(--text); font-size: 12px; flex-shrink: 0; cursor: pointer; } .tnl-toolbar-select:focus-visible, .tnl-candle-filter-select:focus-visible { outline: 2px solid color-mix(in srgb, var(--accent, #3f7ef5) 55%, transparent); outline-offset: 1px; } .tnl-toolbar-end { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; } .tnl-layout-toggle { flex-shrink: 0; } /* 그리드 n×n 배치 선택 */ .tnl-grid-layout-picker { position: relative; flex-shrink: 0; } .tnl-grid-layout-trigger { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; padding: 0; border: 1px solid var(--se-border, var(--border)); border-radius: 8px; background: var(--bg2, var(--se-panel-card-bg)); color: var(--text2); cursor: pointer; transition: border-color 0.15s, background 0.15s, color 0.15s; } .tnl-grid-layout-trigger:hover:not(:disabled) { border-color: var(--accent, #3f7ef5); color: var(--accent, #3f7ef5); background: color-mix(in srgb, var(--accent, #3f7ef5) 10%, var(--bg2)); } .tnl-grid-layout-trigger--open { border-color: var(--accent, #3f7ef5); color: var(--accent, #3f7ef5); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #3f7ef5) 35%, transparent); } .tnl-grid-layout-trigger--disabled { opacity: 0.4; cursor: not-allowed; } .tnl-grid-layout-popover { position: absolute; top: calc(100% + 8px); right: 0; z-index: 120; width: min(320px, calc(100vw - 48px)); max-height: min(420px, 70vh); overflow-y: auto; padding: 10px 12px 12px; border-radius: 10px; border: 1px solid var(--se-border, var(--border)); background: var(--bg2, #1a1f2e); box-shadow: 0 12px 32px color-mix(in srgb, var(--bg) 55%, transparent), 0 0 0 1px color-mix(in srgb, var(--text3) 12%, transparent); } .tnl-grid-layout-popover-title { margin: 0 0 10px; font-size: 11px; font-weight: 700; color: var(--text3); letter-spacing: 0.04em; } .tnl-grid-layout-group { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-top: 1px solid color-mix(in srgb, var(--border) 80%, transparent); } .tnl-grid-layout-group:first-of-type { border-top: none; padding-top: 0; } .tnl-grid-layout-group-lbl { flex: 0 0 14px; font-size: 11px; font-weight: 600; color: var(--text3); text-align: center; } .tnl-grid-layout-group-row { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; min-width: 0; } .tnl-grid-preset-btn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 32px; padding: 0; border: 1px solid transparent; border-radius: 6px; background: transparent; color: var(--text2); cursor: pointer; transition: border-color 0.12s, background 0.12s, color 0.12s; } .tnl-grid-preset-btn:hover { background: color-mix(in srgb, var(--accent, #3f7ef5) 10%, transparent); color: var(--text); } .tnl-grid-preset-btn--on { border-color: var(--accent, #3f7ef5); background: color-mix(in srgb, var(--accent, #3f7ef5) 14%, transparent); color: var(--accent, #3f7ef5); } .tnl-grid-preset-icon-svg { display: block; } /* 그리드형 — 목록형과 동일한 알림 상세 카드 · n×n */ .tnl-list-wrap.tnl-list-wrap--grid { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; padding: 12px 24px 24px; box-sizing: border-box; container-type: inline-size; container-name: tnl-grid-wrap; } .tnl-list.tnl-list--grid { flex: 1; min-height: 0; width: 100%; display: block; list-style: none; margin: 0; padding: 4px 4px 16px; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; } /* VirtualGridScroll 행 단위 n열 배치 */ .tnl-grid-row { display: grid; grid-template-columns: repeat(var(--tnl-grid-cols, 2), minmax(0, 1fr)); gap: 14px; align-items: start; width: 100%; } @container tnl-grid-wrap (max-width: 640px) { .tnl-list-wrap--grid .tnl-grid-row { grid-template-columns: minmax(0, 1fr) !important; } } @container tnl-grid-wrap (max-width: 960px) { .tnl-list-wrap--grid .tnl-list--grid.tnl-grid--cols-3 .tnl-grid-row, .tnl-list-wrap--grid .tnl-list--grid.tnl-grid--cols-4 .tnl-grid-row, .tnl-list-wrap--grid .tnl-list--grid.tnl-grid--cols-5 .tnl-grid-row { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; } } @container tnl-grid-wrap (max-width: 1200px) { .tnl-list-wrap--grid .tnl-list--grid.tnl-grid--cols-4 .tnl-grid-row, .tnl-list-wrap--grid .tnl-list--grid.tnl-grid--cols-5 .tnl-grid-row { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; } } .tnl-row.tnl-row--grid { display: block; min-width: 0; width: 100%; border: none; background: transparent; border-radius: 0; overflow: visible; } /* 목록형과 동일 카드 박스(544×300) — 그리드 셀 너비에 맞춤 */ .tnl-row--grid .tnl-summary-card, .tnl-summary-card--grid { flex: none; width: 100%; max-width: none; height: 300px; max-height: 300px; min-height: 300px; } /* 그리드형 — 메타 하단 빈 공간 제거, 구분선·투자전략 간격 분리 */ .tnl-summary-card--grid .tnl-summary-meta { flex: 0 1 auto; margin-bottom: -4px; } .tnl-summary-card--grid .tnl-summary-strategy-field { margin-top: 0; padding-top: 8px; } .tnl-row--grid.tnl-row--unread .tnl-summary-card { border-color: rgba(122, 162, 247, 0.45); } .tnl-row--grid .tnl-summary-card--selected, .tnl-row--grid.tnl-row--selected .tnl-summary-card { border-color: var(--accent, #7aa2f7); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #7aa2f7) 35%, transparent); } .tnl-row--gallery.tnl-row--selected, .tnl-row--grid.tnl-row--selected { border-color: var(--accent, #7aa2f7) !important; box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #7aa2f7) 45%, transparent), 0 0 12px 2px color-mix(in srgb, var(--accent, #7aa2f7) 18%, transparent); } /* 그리드형 — 실시간 수신 시 카드 외곽 형광 연두 (목록형 행 아웃라인과 동일) */ .tnl-summary-card--grid.tnl-summary-card--receiving { border-color: var(--gc-receive-border) !important; box-shadow: var(--gc-receive-shadow); transition: box-shadow 0.15s ease-out, border-color 0.15s ease-out; } .tnl-summary-card--grid.tnl-summary-card--receiving.tnl-summary-card--selected { border-color: var(--gc-receive-border) !important; box-shadow: var(--gc-receive-shadow); } .tnl-summary-card--grid .tnl-summary-head-actions .vtd-live-badge { margin-right: 2px; flex-shrink: 0; } .tnl-summary-card--grid .tnl-summary-head-actions { flex-wrap: wrap; justify-content: flex-end; row-gap: 4px; max-width: 55%; } .tnl-row--gallery.tnl-row--selected .tnl-hscroll-pane, .tnl-row--gallery.tnl-row--selected .tnl-summary-card--selected { border-color: var(--accent, #7aa2f7); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #7aa2f7) 35%, transparent); } .tnl-row--gallery, .tnl-row--grid { cursor: pointer; } .tnl-list--gallery .tnl-row--gallery { width: 100%; } @container tnl-main (max-width: 900px) { .tnl-row-gallery { flex-direction: column; height: auto; max-height: none; align-items: stretch; } .tnl-row-gallery { --tnl-summary-card-width: min(100%, 260px); } .tnl-row-gallery-detail, .tnl-row-gallery--chart-expanded .tnl-row-gallery-detail { flex: 0 0 var(--tnl-summary-card-width); width: var(--tnl-summary-card-width); min-width: var(--tnl-summary-card-width); max-width: var(--tnl-summary-card-width); } .tnl-row-gallery-detail, .tnl-row-gallery-signal, .tnl-row-gallery-candle, .tnl-row-gallery-indicators { flex: 1 1 auto; width: 100%; min-width: 0; max-width: 100%; } .tnl-hscroll-pane { height: 300px; max-height: 300px; } .tnl-summary-card { min-width: 0; width: 100%; height: 100%; max-height: none; } .tnl-row-gallery-signal .tnl-signal-slot, .tnl-charts-track > .tnl-chart-card { flex: 0 0 min(var(--tnl-chart-card-width), 88vw); width: min(var(--tnl-chart-card-width), 88vw); min-width: min(var(--tnl-chart-card-width), 88vw); } .tnl-row-gallery-signal .tnl-signal-slot { flex: 0 0 min(var(--tnl-signal-slot-width), 88vw); width: min(var(--tnl-signal-slot-width), 88vw); min-width: min(var(--tnl-signal-slot-width), 88vw); } } /* ══════════════════════════════════════════════════════════════ 차트 전체화면 모달 (tnl-chart-fs-*) ══════════════════════════════════════════════════════════════ */ .tnl-chart-fs-overlay { position: fixed; inset: 0; z-index: 9500; background: rgba(0, 0, 0, 0.88); display: flex; align-items: center; justify-content: center; padding: 16px; box-sizing: border-box; } .tnl-chart-fs-inner { width: 100%; height: 100%; max-width: calc(100vw - 32px); max-height: calc(100vh - 32px); display: flex; flex-direction: column; background: var(--bg, #131722); border-radius: 14px; border: 1px solid var(--se-border, var(--border)); overflow: hidden; box-shadow: 0 24px 80px rgba(0, 0, 0, 0.7); } /* ── 헤더 ─────────────────────────────────────────────────── */ .tnl-chart-fs-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--se-border, var(--border)); flex-shrink: 0; background: color-mix(in srgb, var(--bg2) 60%, var(--bg)); } .tnl-chart-fs-title { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1; } .tnl-chart-fs-signal-badge { flex-shrink: 0; font-size: 0.68rem; font-weight: 700; color: #fff; padding: 2px 8px; border-radius: 5px; letter-spacing: 0.04em; } .tnl-chart-fs-market { font-size: 1rem; font-weight: 700; color: var(--text); } .tnl-chart-fs-tf { font-size: 0.75rem; color: var(--text3, var(--se-text-muted)); background: var(--bg2); border: 1px solid var(--se-border, var(--border)); border-radius: 5px; padding: 1px 7px; } .tnl-chart-fs-price { font-size: 0.9rem; font-weight: 700; } .tnl-chart-fs-time { font-size: 0.72rem; color: var(--text3, var(--se-text-muted)); } .tnl-chart-fs-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; } .tnl-chart-fs-strategy { font-size: 0.72rem; color: var(--text2); background: var(--bg2); border: 1px solid var(--se-border, var(--border)); border-radius: 5px; padding: 2px 9px; max-width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .tnl-chart-fs-close { flex-shrink: 0; width: 32px; height: 32px; border: 1px solid var(--se-border, var(--border)); border-radius: 7px; background: transparent; color: var(--text2); cursor: pointer; font-size: 0.85rem; display: flex; align-items: center; justify-content: center; transition: background 0.15s, color 0.15s; } .tnl-chart-fs-close:hover { background: color-mix(in srgb, var(--text3) 20%, transparent); color: var(--text); } /* ── 차트 바디 ────────────────────────────────────────────── */ .tnl-chart-fs-body { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; position: relative; } .tnl-chart-fs-body .tnl-mini-chart-canvas { height: 100% !important; flex: 1 1 0; } .tnl-chart-fs-body .tnl-mini-chart-canvas--fill { height: 100% !important; }