diff --git a/agents/stock/workspace/scripts/behive_web.py b/agents/stock/workspace/scripts/behive_web.py
index d623915..ef81292 100644
--- a/agents/stock/workspace/scripts/behive_web.py
+++ b/agents/stock/workspace/scripts/behive_web.py
@@ -2745,6 +2745,7 @@ def _render_holding_row(r: dict, total_value: int, show_day_change: bool = False
{candle_summary}
+
{stock}{f'{code}' if code else ''}
{f'
{tag_chip}
' if tag_chip else ''}
{dl_inner}
{pl_dl_inner}
@@ -4212,6 +4213,8 @@ details.row + .section-label { margin-top: 14px; padding-top: 24px; border-top-c
.tag-chip { display: inline-block; padding: 0 4px; border-radius: 3px; font-size: 8.5px; font-weight: 500; line-height: 1.4; color: #d6b34a; background: rgba(214,179,74,0.10); border: 1px solid rgba(214,179,74,0.30); white-space: nowrap; flex: none; letter-spacing: 0.01em; font-family: inherit; pointer-events: none; user-select: none; }
.tag-chip.tag-leader { color: #ff6b78; background: rgba(255,77,94,0.12); border-color: rgba(255,77,94,0.42); font-weight: 600; }
/* 펼친 detail의 태그는 크게 (미리보기·관심행 칩은 작게 유지). */
+.detail-name { font-size: 15px; font-weight: 700; color: #f0f0f0; margin: 0 0 8px; display: flex; align-items: baseline; gap: 8px; }
+.detail-name .detail-code { font-size: 11px; font-weight: 500; color: #8b8f9a; font-variant-numeric: tabular-nums; }
.detail-tag { margin: 0 0 8px; }
.detail-tag .tag-chip { font-size: 11px; padding: 2px 8px; border-radius: 4px; }
.btn-add-tag { display: inline-block; padding: 1px 6px; border-radius: 4px; font-size: 10px; font-weight: 500; line-height: 1.5; color: #5a5f6c; background: transparent; border: 1px dashed rgba(120,124,135,0.30); white-space: nowrap; flex: none; cursor: pointer; font-family: inherit; }
@@ -4993,6 +4996,10 @@ table.market-adr td.adr-breakdown { font-size: 11px; color: #8b8f9a; }
min-width: 96px;
}
.chart-controls .nw-select:focus { outline: 1px solid #4a4f5a; outline-offset: 0; }
+/* 2번째 줄(유형/연도/월) — 연도/월은 내용 크기로(월 줄바뀜 방지), 유형은 기간과 동일 폭. 글씨는 1번째 줄과 동일. */
+.chart-controls .cc-line-ym { gap: 8px; }
+.chart-controls .cc-line-ym .nw-select { min-width: 0; }
+.chart-controls .cc-line-ym .nw-select[data-nw-ymtype] { min-width: 96px; } /* 유형 = 기간 select 와 동일 폭 */
@media (max-width: 600px) {
nav.tabs .tab-label { padding: 10px 12px; font-size: 12px; }
@@ -10028,7 +10035,27 @@ class Handler(BaseHTTPRequestHandler):
'sma20': sa.sma(closes, 20),
'sma60': sa.sma(closes, 60),
}
- svg = sa.render_svg_chart(snap, range_key='1Y')
+ # 전일종가 — 일봉 캐시에서 오늘 이전 마지막 종가 → 기준선+전일대비 등락률 표시
+ prev_close = None
+ try:
+ import daily_candles_cache as dcc
+ _today = datetime.now(KST).strftime('%Y%m%d')
+ for b in dcc._select_latest(code, 3):
+ if b.get('date') and str(b['date']) < _today and b.get('close'):
+ prev_close = b['close']
+ break
+ except Exception:
+ prev_close = None
+ if not prev_close:
+ # 일봉 캐시 미스 → ka10095(현재가−전일대비)로 전일종가 보강. 모든 종목에 전일대비 % 표시.
+ try:
+ _q = kc.get_watchlist_quotes([code]).get(code) or {}
+ _pc = (_q.get('price') or 0) - (_q.get('change') or 0)
+ if _pc > 0:
+ prev_close = _pc
+ except Exception:
+ pass
+ svg = sa.render_svg_chart(snap, range_key='1Y', ref_price=prev_close)
body = svg.encode('utf-8')
body, enc = _maybe_gzip(body, self.headers.get('Accept-Encoding'))
self.send_response(200)