/* ═══════════════════════════════════════════════════════════════
   fib-trader — 화면 스타일

   원칙: 새벽에 졸린 눈으로 봐도 숫자를 잘못 읽지 않는 것.
   그래서 "지금 얼마나 남았는가" 가 화면에서 가장 큰 글자이고,
   상태(정상/오류)는 색만이 아니라 배경과 점으로도 구분된다.
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* ── 바탕 세 겹 ────────────────────────────────────────────────
     page  가장 뒤. 여기에만 광원이 깔린다.
     panel 헤더·사이드바·떠 있는 창. **반투명 유리**다 — 뒤의 광원이 비쳐야
           화면이 평평해 보이지 않는다. 불투명한 색으로 바꾸면 광원이 통째로
           가려져서 시안과 달라진다.
     bg    패널 위에 파인 칸(입력·카드). 유리보다 어두워야 파여 보인다. */
  --page: #0b0e14;
  --panel: rgba(32, 24, 22, 0.6);
  --bg: #131722;
  /* 유리와 같은 색이되 **불투명한** 것. 위 --panel 을 --page 위에 얹었을 때의
     결과값이라, 나란히 놓아도 색이 튀지 않는다.
     읽을 것이 많은데 뒤가 계속 움직이는 자리(차트 위의 종목 검색 목록)에 쓴다 —
     거기서는 반투명이 멋이 아니라 방해다. */
  --panel-solid: #181513;

  --line: #2a2e3e;      /* 경계선 */
  --line-2: #3a3f52;    /* 호버 경계선 · 꺼진 스위치 */
  --fg: #d1d4dc;        /* 본문 */
  --fg-dim: #9a9dab;    /* 보조 본문 (레벨 상세 등) */
  --muted: #787b86;     /* 라벨 · 설명 */
  --dim: #5b5f6e;       /* 가장 옅은 글자 (입력칸 아래 주석) */

  /* 강조는 테라코타다. 파랑에서 옮겼다 — 상승(#26a69a 청록)과 하락(#ef5350
     붉은색)이 이미 화면의 절반을 차지하는데, 파란 버튼까지 있으면 색이 셋으로
     갈려 어디를 봐야 할지 흩어진다. 테라코타는 하락색과 채도·명도가 달라서
     겹쳐 놔도 "빨간 것" 으로 안 읽힌다. */
  --accent: #8a4a3d;    /* 채움(버튼 배경) */
  --accent-2: #a35c4c;  /* 그 위에 마우스를 올렸을 때 */
  --accent-fg: #d9917a; /* 어두운 배경 위의 강조 글자·아이콘·링크 */
  --accent-soft: rgba(138, 74, 61, 0.12);  /* 고른 줄·옅은 강조 배경 */
  --accent-line: rgba(138, 74, 61, 0.3);

  --ok: #26a69a;        /* 정상 · 상승 · 감지됨 */
  --err: #ef5350;       /* 오류 · 하락 · 삭제 */

  /* 유리. panel 을 쓰는 곳은 이걸 함께 건다 — 안 걸면 그냥 반투명이라
     뒤의 글자가 비쳐서 읽기 어려워진다. */
  --glass: blur(18px) saturate(160%);

  /* 머리말 높이. ★ 알림 문구(.status)가 이 값을 기준으로 자리를 잡는다 —
     머리말 키를 고치면 알림도 같이 따라오게 하려고 변수로 뺐다. 숫자를 두 곳에
     적어 두면 하나만 고치는 날이 오고, 그때 알림이 종목 바를 덮는다. */
  --header-h: 52px;
}

* { box-sizing: border-box; }

/* ★ 바탕색을 html 에 둔다. body 에 두면 아래 광원(z-index:-1)이 그 색에
     덮여 안 보인다. */
html { background: var(--page); }

body {
  margin: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: transparent;
  color: var(--fg);
  font: 13px/1.5 -apple-system, "Segoe UI", "Malgun Gothic", sans-serif;
}

/* 뒤에 깔린 광원 두 덩이.
   ★ 장식이 아니라 **유리를 유리로 보이게 하는 것**이다. 반투명 패널 뒤가
     단색이면 투명한지 아닌지 알 수가 없어서 그냥 칙칙한 회색으로 보인다.
     뒤에 밝기 차이가 있어야 흐림(blur)이 눈에 띈다.
   fixed 로 둔다 — 스크롤을 따라 움직이면 배경이 아니라 내용처럼 읽힌다.
   pointer-events 를 끄지 않으면 화면 전체가 이 덩이에 덮여 클릭이 막힌다. */
body::before,
body::after {
  content: "";
  position: fixed;
  border-radius: 50%;
  filter: blur(10px);
  pointer-events: none;
  /* ★ -1 이다. 0 으로 두면 **위치가 잡힌 요소**라서 흐름 속의 내용보다 위에
       그려져 화면을 통째로 덮는다. 여기를 고치려고 body 의 자식에
       position:relative 를 걸면 position:fixed 인 모달·떠 있는 창이
       그 자리에 붙박여 버린다 — 실제로 한 번 그렇게 깨뜨렸다. */
  z-index: -1;
}
/* ★ 크기를 화면에 맞춰 키운다. 시안의 420px 은 **1200×860 짜리 카드 그림**
     안의 값이라 그 안에서는 가로의 35% 였는데, 전체 화면(가로 2560 같은)에
     그대로 옮기면 모서리에 박힌 점이 된다. 그러면 유리 뒤에 비칠 것이 없어서
     "유리가 안 먹는다" 로 보인다 — 실제로 그렇게 보고를 받았다.
     비율을 지키되 최소 크기를 두어 좁은 화면에서 사라지지 않게 한다. */
body::before {
  width: 38vw;
  height: 38vw;
  min-width: 420px;
  min-height: 420px;
  top: -9vh;
  right: -5vw;
  background: radial-gradient(circle, rgba(138, 74, 61, .55), transparent 70%);
}
body::after {
  width: 34vw;
  height: 34vw;
  min-width: 380px;
  min-height: 380px;
  bottom: -8vh;
  left: 9vw;
  background: radial-gradient(circle, rgba(38, 166, 154, .22), transparent 70%);
}

/* 유리를 쓰는 면.
   ★ --panel 을 배경으로 쓰는 곳은 **반드시** 여기 함께 적는다. 흐림 없이
     반투명이기만 하면 뒤의 글자가 그대로 비쳐 읽을 수가 없다. 새 패널을
     만들 때 이 목록에 넣는 것을 잊는 것이 이 디자인의 유일한 함정이다. */
header,
#sym-head, #rail, #favorites, #flyout,
.pop, .modal, .float,
#chats, #cond, .bub {
  backdrop-filter: var(--glass);
  -webkit-backdrop-filter: var(--glass);
}

/* 유리의 가장자리 빛.
   ★ backdrop-filter 를 못 쓰는 환경이 있다 — 크롬에서 하드웨어 가속을 끄면
     이 속성이 통째로 무시된다. 그러면 패널이 그냥 어두운 반투명 판이 되어
     "유리로 안 보인다". 이 한 줄은 흐림과 무관하게 그려지므로, 그런 환경에서도
     판이 떠 있는 것으로 읽힌다. 값이 안 드는 보험이다.
   box-shadow 를 이미 쓰는 곳(.modal · .float · #flyout 의 그림자)은 건드리지
   않는다 — 여기 넣으면 그 그림자를 덮어써서 떠 있는 느낌이 되레 사라진다. */
header, #chats, #cond, #rail, #favorites, #sym-head {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--line-2); }
::-webkit-scrollbar-track { background: transparent; }

/* 선으로 그린 아이콘. 색은 항상 글자색을 따라간다 — 상태가 하나만 바뀌면 된다. */
.ico {
  width: 24px;
  height: 24px;
  flex: none;
  fill: none;
  stroke: currentColor;
  /* 아이콘을 키우면 선이 상대적으로 가늘어 보인다. 굵기도 같이 올린다. */
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── 헤더 ────────────────────────────────────────────────────── */

header {
  display: flex;
  align-items: center;
  gap: 14px;
  height: var(--header-h);
  flex: none;
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
  position: relative;
  z-index: 5;
}

/* 배지 — 마크 + 글자.
   ★ 마크를 밖에서 불러오는 파일로 안 둔다. 이 앱은 차트 라이브러리까지
     직접 서빙하는 완전 로컬 구성이고, 마크는 26px 에서 선이 안 뭉개져야 한다
     — 비트맵은 그 크기에서 무너진다. 원본 그림은 brand/torena-logo.png.
   ★ 다른 두 페이지에서는 **화면 이름**이었다(AI 계획수립 · 계획 관리). 지금은
     셋 다 같은 배지다 — 지금 어느 화면인지는 아래 막대가 말하고(js/nav.js),
     왼쪽 위는 "여기가 무슨 앱인가" 를 답하는 자리다. 마크업은 js/brand.js 가
     만든다: 스무 줄짜리 SVG 를 셋에 복사하면 언젠가 한 페이지만 옛 로고가 된다. */
.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .2px;
  white-space: nowrap;
  color: var(--fg);
  text-decoration: none;
}
a.brand:hover .brand-word { color: var(--accent-fg); }

.brand-mark { width: 26px; height: 26px; flex: none; }

/* 원본 글자는 소문자에 효 넣은 기하학적 서체다. 글꼴 파일을 밖에서
   받아 쓰지는 않으므로(위와 같은 이유), 자간과 굵기로 근사한다. */
.brand-word {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: .1em;
}

.spacer { flex: 1; }

/* 상태 배지 — 무채색 한 줄이 아니라 점+배경이 있는 덩어리.
   글자만 바뀌므로 점은 가상 요소로 만든다 (setStatus 가 textContent 를 덮어쓴다). */
/* flex 로 짜면 긴 메시지에 말줄임이 걸리지 않는다(글자가 익명 플렉스 아이템이 된다).
   그래서 블록으로 두고 점만 절대 배치한다. */
/* 알림 문구.
   ★ 머리말의 **한가운데 위**에 떠서 잠깐 보였다 사라진다. 예전에는 머리말
     오른쪽 끝에 끼어 있었는데, 거기는 눈이 안 가는 자리인 데다 문구가 뜰
     때마다 옆 단추들이 밀렸다.
   ★ 흐름에서 빼낸다(position: fixed). 그래야 떴다 사라져도 머리말이 안 흔들린다.
   ★ 긴 원통(pill). 모서리를 반지름 999px 로 두면 높이가 바뀌어도 늘 원통이다. */
.status {
  position: fixed;
  /* ★ 머리말 **아래**, 종목 바(#sym-head)와 눈높이를 맞춘다. 머리말 안에 떠 있을
     때는 주기 단추들과 같은 줄이라 어느 쪽을 봐야 할지 눈이 갈렸다. 한 칸 내려오면
     '지금 무슨 일이 있었나' 를 말하는 자리가 종목 이름 옆으로 온다. */
  top: calc(var(--header-h) + 9px);
  left: 50%;
  z-index: 220;                    /* 청산 확인창(210)보다 위 — 알림은 가리면 안 된다 */
  display: inline-block;
  max-width: min(72vw, 560px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--fg-dim);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 16px 7px 31px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
  backdrop-filter: var(--glass);
  -webkit-backdrop-filter: var(--glass);
  /* 안 보일 때는 아무것도 못 누르게. 안 그러면 투명한 알약이 머리말을 덮는다. */
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -8px);
  transition: opacity .18s ease, transform .18s ease;
}
/* 뜬 상태. JS 가 한 프레임 뒤에 붙인다 — 같은 프레임에 붙이면 전환이 안 돈다. */
.status.show {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
/* ── 진행 알약 ─────────────────────────────────────────────────────
   봉을 받는 동안 뜬다. 알림 문구(.status)와 **자리가 같고 성질이 다르다** —
   알림은 잠깐 떴다 사라지고, 이것은 일이 끝날 때까지 떠 있는다.
   그래서 둘을 동시에 띄우지 않는다 (core.js showLoading 이 알림을 먼저 지운다).

   ★ 알림보다 z-index 가 하나 낮다. 겹칠 일이 없게 짰지만, 만에 하나 겹치면
     **오류 문구가 위에 와야 한다** — 진행 막대에 가려진 오류는 없는 오류다. */
.loading {
  position: fixed;
  top: calc(var(--header-h) + 9px);
  left: 50%;
  z-index: 219;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(72vw, 560px);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--fg-dim);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 16px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
  backdrop-filter: var(--glass);
  -webkit-backdrop-filter: var(--glass);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -8px);
  transition: opacity .18s ease, transform .18s ease;
}
.loading.show {
  opacity: 1;
  transform: translate(-50%, 0);
}
#loading-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 게이지. **부정형(indeterminate)** 이다 — 왼쪽에서 오른쪽으로 빛이 지나갈 뿐
   얼마나 남았는지는 말하지 않는다.
   ★★ 채워지는 막대로 만들지 않은 이유가 있다. 총 몇 봉인지는 마지막 쪽을
      받아 봐야 알기 때문에(services/sync._bump 의 ★★ 주석) 분모가 없다.
      상한 5,000 을 분모로 쓰면 TSLA 는 4,069봉에서 끝나므로 다 받은 순간에
      81% 라고 적히고, 막대가 끝까지 안 가고 사라진다. 이 프로젝트는 모르는
      값을 짓지 않는다 — 막대는 "돌고 있다" 만 말하고, **실제로 받은 봉 수는
      옆의 글자가 말한다.** */
.loading-track {
  position: relative;
  flex: none;
  width: 64px;
  height: 3px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--line);
}
.loading-track > i {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 45%;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, var(--accent-fg), transparent);
  animation: loading-slide 1.05s linear infinite;
}
@keyframes loading-slide {
  from { transform: translateX(-100%); }
  to   { transform: translateX(240%); }
}
/* ★ 움직임을 줄여 달라고 한 사람에게는 흐르지 않고 옅게 깜빡이기만 한다.
     끝없이 지나가는 빛은 어지럼을 부르는 대표적인 움직임이다. */
@media (prefers-reduced-motion: reduce) {
  .loading-track > i {
    width: 100%;
    background: var(--accent-fg);
    animation: loading-pulse 1.6s ease-in-out infinite;
  }
  @keyframes loading-pulse {
    0%, 100% { opacity: .25; }
    50%      { opacity: .9; }
  }
}

/* 글자 맨 앞의 표식.
   ★ 색 동그라미였는데 **모양으로도** 갈리게 한다. 색만으로 나누면 색을 못 가리는
     눈에는 둘이 같은 것이고, 흘끗 보는 순간에도 초록·빨강은 헷갈린다.
       알려주는 문구 → 체크(✓)   ·   경고 문구 → 느낌표(!)
   ★ 세로 가운데는 transform 으로 잡는다. 글자는 높이가 글꼴마다 달라서
     margin-top 을 손으로 맞추면 어느 글꼴에서 반드시 어긋난다. */
.status::before {
  content: "✓";
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
  color: var(--muted);
}
/* 할 말이 없으면 자리도 차지하지 않는다. 예전에는 마지막 메시지가 그대로
   남아서 상시 표시되는 상태 박스처럼 보였다. */
.status:empty,
.status[hidden] { display: none; }
/* 어느 문구든 눌러서 바로 지울 수 있다 (main.js 의 status onclick). */
.status { cursor: pointer; }

.status.ok {
  color: var(--ok);
  background: rgba(38, 166, 154, .12);
  border-color: rgba(38, 166, 154, .35);
}
.status.ok::before { content: "✓"; color: var(--ok); }

.status.err {
  color: var(--err);
  font-weight: 700;
  background: rgba(239, 83, 80, .14);
  border-color: rgba(239, 83, 80, .4);
}
/* 경고는 **빨간 느낌표**. 알약 바탕도 붉지만, 색만으로는 흘끗 보고 못 가른다.
   조금 크고 굵게 — 이 자리에 뜨는 것은 대개 주문이 막혔다는 말이다. */
.status.err::before {
  content: "!";
  color: var(--err);
  font-size: 14px;
  font-weight: 900;
}

/* ★ #monitor-toggle 이 여기 있었다. 종과 한 상자로 합쳐졌다(.deck-box). */
#settings-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  flex: none;
  margin: 0;
  padding: 8px 13px;
  font-size: 13px;
}
/* 톱니바퀴는 글자 없이 아이콘만이라 정사각으로 맞춘다.

   ★ 키는 **옆의 알림 상자(.deck-box)와 똑같이** 맞춘다. 머리말에 나란히 서는
     두 상자인데 키가 다르면 아래위 여백이 어긋나 한쪽이 떠 보인다. 예전에는
     설정이 5px 더 컸다 (38 vs 33).

         알림 상자   1(선) + 2(안쪽) + 5+17+5(단추) + 2 + 1 = 33px
         설정        1(선) + 7        +    17       + 7 + 1 = 33px

     아이콘도 17px 로 같이 줄인다 — 키만 맞추고 아이콘이 크면 둘이 다른 부품으로
     읽힌다. 두께(stroke-width)도 알림 쪽 값을 따른다. */
#settings-toggle { padding: 7px; }
#settings-toggle .ico { width: 17px; height: 17px; stroke-width: 1.8; }

/* ── 종목 검색 ───────────────────────────────────────────────── */

#sym-box { position: relative; flex: none; }
#sym-input {
  width: 142px;
  height: 34px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .3px;
}
#sym-input:focus { outline: none; border-color: var(--accent); }

/* ★ 여기는 유리로 두지 않는다. 검색 결과를 **읽는** 자리인데 바로 뒤가
     캔들차트라, 반투명이면 글자 뒤로 봉이 지나가며 계속 어른거린다.
     움직이는 것 위에서는 흐림도 소용이 없다 — 흐려진 채로 움직인다. */
#sym-list {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  /* ★★ 알림 알약(.status 220)·진행 알약(.loading 219)보다 **위**여야 한다.
     알림은 화면 한가운데 position:fixed 로 뜨고 이 목록은 왼쪽 위에 뜨는데,
     창이 좁으면 둘이 겹친다. 그때 알림이 위에 있으면 알림에는
     pointer-events:auto 가 걸려 있어(눌러서 지우기) **목록의 그 부분을 눌러도
     알림이 눌린다** — 클릭은 #sym-box 밖에서 일어난 것이 되어 목록이 닫히고,
     아무 일도 안 일어난다. 키보드 Enter 로는 되는데 마우스로만 안 되는
     증상이 이것이었다.
     알림이 잠깐 가려지는 것보다, 사람이 지금 누르려는 것이 안 눌리는 쪽이
     훨씬 나쁘다. */
  z-index: 240;
  width: 260px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--panel-solid);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, .5);
  padding: 4px;
}
#sym-list.hidden { display: none; }

.sym-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 8px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 12px;
}
.sym-item:hover { background: var(--bg); }
.sym-item.on { background: var(--bg); }
.sym-item.on b { color: var(--accent-fg); }
/* b 는 이름, em 은 티커다. 이름이 길어 줄을 채우므로 늘어나는 쪽은 b 다. */
.sym-item b {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sym-item em {
  flex: none;
  font-style: normal;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: .3px;
}
.sym-item.add { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 8px; }
.sym-item.add b { color: var(--ok); flex: none; }
.sym-empty { color: var(--muted); font-size: 11px; padding: 10px; text-align: center; }

/* ── 주기 선택 (1분 … 년봉) ──────────────────────────────────── */

.seg {
  display: flex;
  align-items: center;
  flex: none;
  gap: 2px;
  padding: 3px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.seg button {
  width: auto;
  margin: 0;
  padding: 7px 11px;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--muted);
  font-size: 13px;
}
/* 분봉과 일봉 이상을 눈으로 갈라 준다 */
.seg button.seg-gap { margin-left: 9px; position: relative; }
.seg button.seg-gap::before {
  content: "";
  position: absolute;
  left: -5px;
  top: 3px;
  bottom: 3px;
  width: 1px;
  background: var(--line);
}
/* 유리(--panel)로 칠하면 반투명이라 눌린 것이 안 보인다. 옅은 흰빛을 얹는다. */
.seg button:hover { background: rgba(255, 255, 255, .05); color: var(--fg); }
.seg button.on { background: var(--accent); color: #fff; }

/* 접어 둔 주기 — 15분·60분·월봉·년봉. 저장된 것이 하나도 없어서 밖에 안 둔다
   (index.html 의 셈).

   ★ **칸 안에 다섯째 조각으로** 선다. 옆에 따로 두면 테두리가 둘이 되고 키를
     손으로 맞춰야 하는데, 그러면 글자 크기나 여백을 고칠 때마다 다시 어긋난다.
     안에 넣으면 .seg 의 padding 이 저절로 같은 키를 만든다.
   ★ 상태 셋이 버튼과 **글자 하나까지 같다** — 평소 muted, 마우스 올리면 옅은
     흰빛, 고른 것은 accent. 접혀 있다고 지금 보는 봉이 흐리면, 무엇을 보고
     있는지가 화면에서 사라진다.
   ★ 그래서 **위 .seg button 규칙을 그대로 물려받는다.** 여백·글자·세 색이 전부
     거기 있다 — 여기 다시 적으면 버튼 쪽을 고칠 때 이것만 안 따라온다.
     여기서 더하는 것은 아이콘을 옆에 세우는 것뿐이다. */
.res-fold {
  display: flex;
  align-items: center;
  gap: 5px;
  padding-right: 8px;
}
/* 화살표는 **글자색을 따라간다**(.ico 의 stroke: currentColor). 그래서 눌렸을
   때 흰색을 따로 챙기지 않아도 된다 — 챙기면 팔레트가 두 군데로 갈린다.
   ★ pointer-events: none. 아이콘은 **그림일 뿐 과녁이 아니다** — 이게 없으면
     화살표 쪽을 눌렀을 때 e.target 이 svg 가 되고, 눌린 자리에 따라 되거나
     안 되는 버튼이 된다. 실제로 그랬다(label + select 이던 시절, 화살표를
     누르면 아무 일도 안 일어났다). 버튼은 **어디를 눌러도 같아야 한다.** */
.res-fold .ico {
  width: 13px;
  height: 13px;
  stroke-width: 2.2;
  pointer-events: none;
}

/* 펼쳐지는 목록. **우클릭 메뉴와 같은 판(.pop)** 이라 유리도 모서리도 그림자도
   한 곳에서 나온다.
   ★ 네이티브 select 를 걷어낸 이유가 이것이다. 펼침 목록은 운영체제가 그려서
     option 의 배경·글자색 말고는 손댈 데가 없다 — 어두운 머리말 밑에 각진 흰
     판이 떨어지고, 모서리도 그림자도 앱의 다른 메뉴와 따로 논다. */
/* ★ 폭은 **'기타' 조각에 맞춘다** — 목록이 그 조각에서 펼쳐진 것으로 읽혀야
     한다. 실제 폭은 열 때 재서 넣는다(main.js 의 toggleResMenu). .pop 의 기본
     폭(170px)은 항목 이름이 긴 우클릭 메뉴용이라 여기서는 두 배 넓다.
   ★ 글자도 위 주기 버튼과 같게 둔다 — 크기도 정렬도. 이 목록은 그 칸에서
     이어지는 한 덩어리지, 딴 데서 온 메뉴가 아니다. (.pop button 의 왼쪽
     정렬은 항목이 문장인 우클릭 메뉴의 것이다.) */
.res-menu { min-width: 0; padding: 6px; }
.res-menu button {
  padding: 7px 9px;
  text-align: center;
  font-size: 13px;
}
.res-menu button:first-child { margin-top: 0; }
/* 지금 보고 있는 것. 열었을 때 어느 봉인지 바로 보여야 한다 — 버튼 쪽과 같은 색. */
.res-menu button.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.res-menu button.on:hover { background: var(--accent-2); border-color: var(--accent-2); }

/* ── 본문 골격 ───────────────────────────────────────────────── */

main {
  flex: 1;
  display: grid;
  /* 왼쪽은 아이콘 막대만. 패널은 그 위에 겹쳐 뜬다 — 열고 닫을 때마다
     차트가 리사이즈되면 눈이 피로하고 KLineChart 도 매번 다시 그려야 한다.
     ★ 이 폭을 바꾸면 #flyout 의 left 도 같이 바꿔야 한다. 패널이 막대에
       딱 붙어 뜨는 구조라, 하나만 고치면 겹치거나 틈이 생긴다. */
  /* 오른쪽 즐겨찾기는 **겹치지 않고 칸을 차지한다.** 왼쪽 패널과 반대인 이유:
     차트 오른쪽 끝이 가격축이고 현재가 꼬리표가 붙는 자리라 덮으면 제일
     중요한 것을 가린다. 왼쪽은 자주 여닫지만 이쪽은 계속 열어 두는 창이라
     리사이즈도 접을 때 한 번뿐이다. */
  grid-template-columns: 68px 1fr 246px;
  min-height: 0;
  position: relative;
}
body.fav-closed main { grid-template-columns: 68px 1fr 30px; }

/* 종목 바 + 차트. 격자 칸 하나를 세로로 나눠 쓴다. */
#stage {
  display: grid;
  grid-template-rows: auto 1fr;
  min-width: 0;
  min-height: 0;
}

/* ★★ overflow 를 반드시 막는다. 차트 위에 얹는 것들(워터마크·글자칸)이
     칸 밖으로 삐져나가면 **문서에 스크롤바가 생기고 화면 전체가 밀린다** —
     "주석을 달면 UI 가 왼쪽으로 쏠린다" 로 겪었다. 원인이 도형과 상관없는
     자리에 있어서 찾기 어려운 종류다. */
#chart { min-height: 0; background: var(--bg); position: relative; overflow: hidden; }

/* 차트 배경의 종목 이름.
   ★ 화면을 캡처해 두면 **무엇을 보던 것인지가 그림 안에 남는다.** 차트만
     오려 놓으면 며칠 뒤에는 어느 종목인지 알 수가 없다.
   ★★ 캔버스 **위**에 얹는다. 뒤에 깔면 캔버스가 불투명할 때 안 보이는데,
      그건 라이브러리 사정이라 우리가 못 정한다. 대신 아주 옅게(6%) 두고
      pointer-events 를 끄므로 캔들을 가리지도, 클릭을 막지도 않는다. */
#chart-water {
  position: absolute;
  left: 16px;
  bottom: 34px;          /* 시간축 위 */
  pointer-events: none;
  z-index: 1;
  font-size: 40px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.05;
  color: var(--fg);
  opacity: 0.06;
  user-select: none;
  white-space: pre-line;
}
#chart-water .sub { font-size: 18px; font-weight: 500; }

/* 차트 위에서 바로 치는 글자칸 (js/annotate.js).
   ★★ **바탕을 안 깐다.** 상자가 있으면 치는 동안과 확정한 뒤의 모습이 달라서,
      다 치고 나서야 "생각한 자리가 아니네" 를 알게 된다. 투명하면 치는 중에
      이미 완성된 모습이다. 대신 아래 가는 밑줄로 "여기 치는 중" 만 알린다. */
#chart-text { position: absolute; z-index: 5; }

#chart-text .ct-input {
  display: block;
  min-width: 140px;
  padding: 0;
  font-family: -apple-system, "Segoe UI", "Malgun Gothic", sans-serif;
  font-weight: 700;
  line-height: 1.2;
  background: transparent;   /* ← 위 ★★ */
  border: 0;
  border-bottom: 1px dashed currentColor;
  outline: none;
}
#chart-text .ct-input::placeholder { color: var(--dim); font-weight: 400; }

/* 크기·색 고르는 줄. 치는 동안만 뜬다. */
#chart-text .ct-bar {
  display: flex;
  gap: 4px;
  align-items: center;
  margin-bottom: 4px;
  padding: 3px 5px;
  background: var(--panel-solid);
  border: 1px solid var(--line);
  border-radius: 4px;
  width: max-content;
}
#chart-text .ct-size {
  width: 46px;
  padding: 1px 4px;
  font: 12px/1.4 inherit;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 3px;
}
#chart-text .ct-color {
  width: 14px; height: 14px;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: 50%;
  cursor: pointer;
}
#chart-text .ct-color.on { outline: 2px solid var(--fg); outline-offset: 1px; }

/* ── 지금 보고 있는 종목 ─────────────────────────────────────── */

/* 차트만 있으면 "지금 얼마인가" 를 축 눈금에서 읽어야 한다.
   이름·티커를 위에, 값을 그 아래에 두어 한눈에 읽히게 한다. */
#sym-head {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "logo id    star"
    "logo quote star";
  align-items: center;
  column-gap: 12px;
  padding: 7px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}

#sh-logo { grid-area: logo; display: flex; }
.sh-id { grid-area: id; display: flex; align-items: baseline; gap: 7px; min-width: 0; }
#sh-name {
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#sh-tick { color: var(--muted); font-size: 11.5px; letter-spacing: .4px; flex: none; }

.sh-quote { grid-area: quote; display: flex; align-items: baseline; gap: 9px; }
#sh-price { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
#sh-chg { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--muted); }

/* ★ 정사각형이다. 예전에는 width:auto 에 좌우 패딩만 줘서 글자 폭에 따라
   가로로 길쭉했고, 별이 상자 가운데가 아니라 글꼴 기준선에 걸려 있었다.
   크기를 못 박고 flex 로 가운데에 놓는다 — 글리프가 바뀌어도 안 흔들린다. */
#sh-star {
  grid-area: star;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin: 0;
  padding: 0;
  font-size: 17px;
  line-height: 1;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--line-2);
}
#sh-star:hover { border-color: var(--line-2); color: var(--fg-dim); }
/* 금색이 아니라 앱의 강조색이다. 금색은 어디서도 안 쓰는 색이라 이 버튼만
   따로 놀았다 — 강조는 테라코타 하나로 모은다 (--accent 주석 참고). */
#sh-star.on { color: var(--accent-fg); border-color: var(--accent-line); }

/* ── 왼쪽 아이콘 막대 ────────────────────────────────────────── */

#rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 12px 0;
  border-right: 1px solid var(--line);
  background: var(--panel);
  overflow-y: auto;
  z-index: 4;
}

#rail button {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 58px;
  height: 60px;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 9px;
  background: none;
  color: var(--muted);
}
#rail button em {
  font-style: normal;
  font-size: 11px;
  line-height: 1;
  color: currentColor;
}
#rail button:hover { background: rgba(255, 255, 255, .05); color: var(--fg); }
#rail button.on { background: var(--accent-soft); color: var(--accent-fg); }

#rail .spacer { flex: 1; }
.rail-sep {
  width: 38px;
  height: 1px;
  background: var(--line);
  margin: 7px 0;
  flex: none;
}

/* 자석 세기 — 아이콘 밑 점 개수로 약(•) / 강(••) / 꺼짐(없음).
   JS 가 textContent 로 점을 넣으므로, 비어 있을 때는 알약이 보이지 않게 한다. */
#magnet-btn { height: 68px; }
#magnet-dots {
  font-style: normal;
  font-size: 13px;
  line-height: 9px;
  letter-spacing: 3px;
  padding: 3px 8px 3px 11px;
  border-radius: 7px;
  background: rgba(138, 74, 61, .22);
  color: var(--accent-fg);
}
#magnet-dots:empty { display: none; }

/* ── 즐겨찾기 (오른쪽 칸) ────────────────────────────────────── */

#favorites {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--panel);
  border-left: 1px solid var(--line);
  overflow: hidden;
}

#fav-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 8px 9px 10px;
  border-bottom: 1px solid var(--line);
  font-size: 11.5px;
  white-space: nowrap;
}
#fav-head .spacer { flex: 1; }
.fav-sub { color: var(--muted); font-size: 10.5px; font-variant-numeric: tabular-nums; }
/* 빈 칸은 아예 없앤다.
   ★ 머리말은 gap 이 14px 인 flex 줄이라, 글자가 없는 span 도 **양옆 여백은
     그대로 먹는다.** AI 가 켜져 있으면 #ai-model 이 비고 첫 물음 전까지
     #ai-spent 도 비는데, 그러면 백테스트 단추 왼쪽에 이유 없는 28px 이 생긴다.
     보이지도 않는 것이 만든 여백이라 원인을 찾기가 특히 나쁘다. */
.fav-sub:empty { display: none; }
.fav-sub.full { color: var(--err); font-weight: 700; }
#fav-head button {
  width: auto;
  margin: 0;
  padding: 2px 6px;
  font-size: 12px;
  line-height: 1;
  background: transparent;
  border: none;
  color: var(--fg-dim);
}
#fav-head button:hover { color: var(--fg); }
#fav-toggle { transition: transform .18s; }
body.fav-closed #fav-toggle { transform: rotate(180deg); }

/* 접으면 머리의 접기 버튼만 남는다. 완전히 감추면 다시 펴는 길이 없어진다. */
body.fav-closed #fav-head > *:not(#fav-toggle) { display: none; }
body.fav-closed #fav-head { padding: 9px 4px; }
body.fav-closed #fav-body { display: none; }

#fav-body { flex: 1; overflow-y: auto; padding: 4px; }
.fav-empty { color: var(--muted); font-size: 10.5px; line-height: 1.6; padding: 10px 6px; }

/* ★ 칸 너비(246px)에 견주어 글자가 너무 작았다. 이 창은 곁눈질로 보는 곳이라
     — 차트를 보다가 값만 흘깃 확인한다 — 들여다봐야 읽히면 쓸모가 준다.
     이름 13px · 값 12.5px 로 올리고 로고도 22px 로 키웠다.
     폭 계산: 246 − 패딩 8 − 행패딩 10 = 228,
              고정 칸(10+22+14) + 간격(4×7) = 74  →  이름·값이 154px 를 나눠 쓴다.
              '마이크로소프트'(13px, 약 91px) + '$298.20'(약 52px) = 143 < 154. */
.fav-row {
  display: grid;
  /* ★ 손잡이는 **오른쪽 끝**이다. 창의 가장자리라 잡기 쉽고, 왼쪽에 두면
       로고·이름과 붙어서 무엇이 손잡이인지 안 읽힌다. */
  grid-template-columns: 22px 1fr auto 14px 16px;
  /* ★ 이름이 **두 줄에 걸친다.** 윗줄에만 두면 아래 변동률 줄 때문에 이름이
       위로 붙어 로고와 눈높이가 어긋난다. 걸쳐 두면 align-items:center 가
       두 줄의 한가운데로 보낸다 — 왼쪽은 이름 하나, 오른쪽은 값·변동 두 줄. */
  grid-template-areas: "logo name price off grip" "logo name chg off grip";
  align-items: center;
  gap: 0 7px;
  padding: 7px 5px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12.5px;
}
/* 즐겨찾기 줄에서만 로고를 키운다. logo-sm 을 통째로 키우면 대화 말풍선·조건
   칸에 쓰는 작은 로고까지 같이 커진다. */
.fav-row > .logo.logo-sm { width: 22px; height: 22px; font-size: 11px; }
.fav-row:hover { background: var(--line-2); }
.fav-row.on { background: var(--line-2); box-shadow: inset 2px 0 0 var(--accent-fg); }
.fav-row.dragging { opacity: .45; }

.fav-row > .logo { grid-area: logo; }
/* 순서 손잡이. ★ **늘 보인다** — ✕ 처럼 hover 에서만 나타나게 하면 순서를 바꿀
   수 있다는 것 자체를 아무도 모른다. 대신 아주 흐리게 두어 값 읽기를 방해하지
   않고, 줄에 마우스를 얹으면 또렷해진다. */
.fav-grip {
  grid-area: grip;
  color: var(--line);
  /* 점을 굵게. ⋮⋮ 는 글꼴 점이라 굵기를 따로 못 준다 — 크기와 font-weight 로
     키운다. 대신 자간을 더 좁혀 두 줄이 흩어지지 않게 붙인다. */
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -3px;
  line-height: 1;
  text-align: center;
  cursor: grab;
  /* 글자만큼만 잡히면 너무 좁다. 줄 높이를 꽉 채워 손이 쉽게 닿게 한다. */
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
  touch-action: none;
}
.fav-row:hover .fav-grip { color: var(--fg-dim); }
.fav-grip:hover { color: var(--accent-fg); }
.fav-grip:active { cursor: grabbing; }
/* 끌고 있는 줄이 어디에 꽂힐지 눈으로 따라갈 수 있어야 한다. */
.fav-row.dragging .fav-grip { color: var(--accent-fg); }
.fav-name {
  grid-area: name;
  font-size: 13px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fav-price {
  grid-area: price;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.fav-chg {
  grid-area: chg;
  font-size: 11px;
  text-align: right;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.fav-off {
  grid-area: off;
  width: auto;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  color: transparent;
  font-size: 12px;
  line-height: 1;
}
.fav-row:hover .fav-off { color: var(--fg-dim); }
.fav-off:hover { color: var(--err) !important; }

/* ── 종목 표식 ───────────────────────────────────────────────── */

/* 로고 파일이 있으면 그림, 없으면 이름 첫 글자. logos.js 참고. */
.logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  border-radius: 50%;
  overflow: hidden;
  color: #fff;
  font-weight: 700;
  line-height: 1;
  user-select: none;
}
/* ★ cover 다. 로고는 대부분 자기 배경을 가진 정사각 배지라, 동그라미 안을
   가장자리까지 채워야 한다. contain 이면 원 안에 네모가 떠 있는 것처럼 보인다. */
/* ★★ 흰 바닥을 **그림에 직접** 깐다. 예전에는 바깥 동그라미(.logo)에 깔았는데,
   그러면 18px 짜리 원의 가장자리에서 흰색이 **한 겹 삐져나와** 보였다 —
   부모의 흰 배경은 border-radius 로 잘리고 그림은 그 안에 네모로 얹히는데,
   두 경계가 반픽셀씩 어긋나면서 흰 테두리가 남는다.
   그림 자신이 흰 바닥을 갖고 자기도 동그랗게 잘리면 어긋날 두 경계가 없다.

   ★ 바닥이 왜 필요한가: 배경이 투명한 로고(AZN·IONQ 같은 PNG)는 없으면 어두운
     페이지가 비쳐서 검은 로고가 안 보인다. 글자 표식은 인라인 style 로 색을
     얹으므로 이 규칙에 안 걸린다(img 가 없다). */
.logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
  background: #fff;
}

.logo-sm { width: 18px; height: 18px; font-size: 9.5px; }
.logo-md { width: 26px; height: 26px; font-size: 13px; }

/* ── 겹쳐 뜨는 패널 ──────────────────────────────────────────── */

#flyout {
  position: absolute;
  top: 0;
  /* #main 의 grid-template-columns 첫 값(레일 폭)과 반드시 같아야 한다. */
  left: 68px;
  bottom: 0;
  z-index: 120;
  width: 310px;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-right: 1px solid var(--line);
  box-shadow: 8px 0 24px rgba(0, 0, 0, .35);
}
#flyout.hidden { display: none; }

#flyout > section {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: 14px;
}
/* 열려 있는 칸만 보인다. display 를 지정했으므로 [hidden] 을 직접 눌러야 한다. */
#flyout > section[hidden] { display: none; }
/* 세로 플렉스에서는 내용이 넘칠 때 아이템이 먼저 찌그러진다. 눌리지 말고 스크롤되게. */
#flyout > section > * { flex-shrink: 0; }

.fly-head {
  display: flex;
  align-items: center;
  height: 44px;
  flex: none;
  padding: 0 8px 0 14px;
  border-bottom: 1px solid var(--line);
}
.fly-head b { font-size: 13px; font-weight: 700; }
.fly-head button {
  width: 26px;
  height: 26px;
  margin: 0;
  padding: 0;
  font-size: 15px;
  line-height: 1;
  border-color: transparent;
  background: none;
  color: var(--muted);
}
.fly-head button:hover { background: rgba(255, 255, 255, .06); color: var(--fg); }

#flyout h3 {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: .3px;
  margin: 16px 0 8px;
}
#flyout h3:first-child { margin-top: 0; }

/* ── 입력 요소 ───────────────────────────────────────────────── */

input, select, button {
  width: 100%;
  padding: 7px 9px;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 6px;
  font: inherit;
  font-size: 12px;
}
input:focus, select:focus { outline: none; border-color: var(--accent); }

/* 숫자 칸의 위·아래 화살표를 없앤다 (전부, 판정 칸만이 아니라).
   ★ 칸이 좁아서 화살표가 자리를 먹는데, 정작 쓸 일이 거의 없다. 임계값·금액·
     기간은 원하는 값을 바로 치지 한 칸씩 올리지 않는다. 게다가 마우스 휠이
     칸 위에 있으면 값이 조용히 바뀌는데, 금액 칸에서 그건 위험한 종류의 실수다.
   키보드 위·아래 키는 그대로 동작하므로 잃는 것은 없다. */
input[type="number"] {
  appearance: textfield;
  -moz-appearance: textfield;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

header select, header button, header input { width: auto; }

/* 머리말 버튼은 서로 **같은 크기**여야 한다.
   ★ .primary 는 본문 폼(계획 수립·저장)용이라 padding 이 10px 이고 글자도 크다.
     그대로 머리말에 서면 도움말 옆에서 혼자 부풀어, 같은 줄에 선 버튼 셋의
     아랫변이 안 맞는다. 크기는 맞추고 다른 점은 색으로만 둔다.
   ★ 지금 이 규칙이 닿는 것은 백테스트 하나다. 셋이었다 — '계획 관리' 는 아래
     막대로, '도움말' 은 입력칸 아래로 내려갔다. 규칙은 남긴다: 다음에 무엇이
     서든 그때 크기를 다시 정하지 않게.
   ★ .ai-page 로 묶는다. 차트 화면 머리말에도 버튼이 있는데 그쪽은 아이콘
     버튼이라, 폭을 강제하면 도리어 어그러진다.
   ★★ **오른쪽 끝의 두 상자는 뺀다** (> 로 손자를 자르고, 톱니는 이름으로).
      알림 상자(.deck-box)의 단추는 이 규칙의 손자라 min-width:76px 를 그대로
      먹고 있었다 — 이 화면에서만 종 하나가 76px 로 늘어나서, 세 화면에 같이
      선다던 상자가 여기서만 다른 물건이었다. 셋 중 하나만 어긋나는, 눈으로
      볼 때까지 모르는 종류의 고장이다. */
.ai-page header > button:not(#settings-toggle) {
  min-width: 76px;
  padding: 7px 9px;
  font-size: 12px;
  text-align: center;
}

/* ★ 백테스트 단추의 규칙이 여기 있었다. 그 단추는 **아래 막대로 내려갔고**
   (js/nav.js), 창은 페이지가 됐다. 남겨 두면 아무도 안 쓰는 규칙이 되고,
   그런 규칙은 다음 사람이 "이건 왜 있지" 로 시간을 쓴다.

   ★ 다만 위의 `.ai-page header > button:not(#settings-toggle)` 는 남긴다.
     ':not' 이 붙어 있는 이유가 거기 적혀 있고, 그건 이 단추 때문이 아니라
     **알림 상자 안의 버튼까지 잡히던 것**을 막는 규칙이었다. */

button { cursor: pointer; margin-top: 4px; }
button:hover { border-color: var(--line-2); }

button.primary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px;
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
}
button.primary:hover { background: var(--accent-2); border-color: var(--accent-2); }
button.primary .ico { width: 17px; height: 17px; stroke-width: 1.8; }

button.danger { color: var(--err); border-color: rgba(239, 83, 80, .4); background: transparent; }
button.danger:hover { background: rgba(239, 83, 80, .1); border-color: var(--err); }

/* 라벨과 입력을 가로로 짝지어 훑는 속도를 높인다.
   라벨 글자는 익명 그리드 아이템이 되어 첫 칸에 들어간다. */
#flyout > section > label,
.modal > label {
  display: grid;
  grid-template-columns: 62px 1fr;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  font-size: 11.5px;
  color: var(--muted);
}

/* 입력 + 단위 */
.field { display: flex; align-items: center; gap: 7px; }
.field input { flex: 1; width: auto; min-width: 0; }
.field em { font-style: normal; font-size: 11.5px; color: var(--muted); flex: none; }

.row { display: flex; gap: 8px; }
.row > * { flex: 1; }

.hint { color: var(--muted); font-size: 11px; line-height: 1.6; margin: 8px 0; }

/* 설명이 아니라 경고. 화면만 보고는 알 수 없는 위험을 딱 한 줄로 알린다. */
.warn {
  color: var(--err);
  font-size: 11px;
  line-height: 1.5;
  margin: 0 0 10px;
  padding: 7px 10px;
  border: 1px solid rgba(239, 83, 80, .35);
  border-radius: 6px;
  background: rgba(239, 83, 80, .08);
}

/* ── 드로잉 도구 · 지표 격자 ─────────────────────────────────── */

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 8px;
}
.grid button {
  margin-top: 0;
  padding: 12px 6px;
  font-size: 12px;
  color: var(--fg-dim);
}
.grid button:hover { border-color: var(--accent-fg); color: var(--fg); }
.grid button.on { background: var(--accent); border-color: var(--accent); color: #fff; }

#indicators h4 {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
  margin: 0 0 8px;
}
#indicators h4 + .grid { margin-bottom: 16px; }
#indicators h4:not(:first-child) { margin-top: 2px; }

/* 지표 한 칸 = 켜기 버튼 + 설정(⚙). ⚙ 는 켜져 있을 때만 보인다.
   테두리는 바깥 칸이 그리고, 안쪽 버튼은 투명하게 둔다 — 둘이 한 덩어리로 보이도록. */
.ind-item {
  display: flex;
  align-items: center;
  gap: 2px;
  padding-right: 4px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 7px;
}
.ind-item:hover { border-color: var(--line-2); }
.ind-item:has(button.on) {
  background: var(--accent-soft);
  border-color: var(--accent-line);
}
.ind-item > button {
  margin: 0;
  background: none;
  border: none;
  border-radius: 6px;
}
.ind-item > button[data-ind] {
  flex: 1;
  min-width: 0;
  /* 한글 이름이 칸보다 길면 잘라서 표시한다 — 줄바꿈으로 칸 높이가 들쭉날쭉하면 안 된다. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: left;
  padding: 9px 4px 9px 10px;
  color: var(--fg-dim);
}
.ind-item > button[data-ind].on { color: var(--fg); font-weight: 600; }
.ind-cfg {
  width: 20px;
  flex: none;
  padding: 0;
  font-size: 12px;
  color: var(--accent-fg);
}
.ind-cfg:hover { color: #8fb4ff; }
.ind-cfg.hidden { display: none; }
#ind-add.hidden { display: none; }
.lv-del.hidden { visibility: hidden; }

/* ── 목록 (웹훅 · 규칙 · 발화 기록) ──────────────────────────── */

.list { margin-bottom: 8px; }
.list .item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
  padding: 7px 8px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  margin-bottom: 4px;
  font-size: 11.5px;
}
.list .item em { color: var(--muted); font-style: normal; font-size: 11px; }
.list .item > span:first-child { min-width: 0; }
.list .item button {
  width: auto;
  margin: 0 0 0 3px;
  padding: 4px 7px;
  font-size: 10px;
}
.list .item button.on { background: var(--ok); border-color: var(--ok); color: #fff; }
/* 꺼 둔 항목. 지워진 것이 아니라 쉬고 있다는 뜻이라, 흐리게만 하고 남겨 둔다. */
.list .item.off { opacity: .5; }
.list .item.off:hover { opacity: .8; }
/* 웹훅 URL 은 길다. 넘치면 줄이되 버튼은 밀리지 않게 한다. */
.list .item > span:first-child { overflow: hidden; text-overflow: ellipsis; }
.list .item > span:last-child { flex: none; white-space: nowrap; }

#watcher {
  padding: 9px 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--fg-dim);
  margin: 0 0 8px;
}

/* ── 레벨 표 ─────────────────────────────────────────────────── */

table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 11.5px; }
th { color: var(--muted); font-weight: 500; text-align: left; }
th, td { padding: 5px 4px; border-bottom: 1px solid var(--line); }
td:nth-child(2), td:nth-child(3) { text-align: right; font-variant-numeric: tabular-nums; }
tr.touched { color: var(--ok); font-weight: 600; }

/* 내가 그은 선. js/core.js 의 LINE 과 **같은 값이어야 한다** — 표에서 레벨을
   가리키는 색과 차트에 그려진 선의 색이 다르면 무엇을 가리키는지 알 수 없다. */
.c-edge { color: #5b9cff; }
.c-server { color: var(--ok); }
/* 손익 색. 차트 봉과 같은 규칙이다 — 오르면 초록, 내리면 빨강.
   (js/chart.js 의 upColor/downColor 와 반드시 같아야 한다. 한 화면에서
    같은 '오름' 이 다른 색이면 읽는 사람이 매번 다시 생각해야 한다.) */
.c-up { color: var(--ok); }
.c-down { color: var(--err); }
/* .c-pick 은 지웠다. 고른 선은 이제 **색이 안 바뀌고** 굵어지므로, 그 색을
   가리킬 자리가 없다. 아무 데서도 안 쓰는 색을 남겨 두면 다음 사람이 그것을
   찾아 헤맨다. */
.c-err { color: var(--err); }

/* ── 우클릭 메뉴 ─────────────────────────────────────────────── */

.pop {
  position: fixed;
  z-index: 100;
  min-width: 170px;
  padding: 8px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, .5);
}
.pop.hidden { display: none; }
.pop-title {
  font-size: 11px;
  color: var(--muted);
  padding: 0 2px 7px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 6px;
}
.pop button {
  margin-top: 2px;
  text-align: left;
  border-color: transparent;
  background: none;
}
.pop button:hover { background: var(--bg); border-color: var(--line); }
.pop label { margin-bottom: 6px; }

/* ── 모달 (채널 설정 · 지표 설정) ────────────────────────────── */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, .55);
}
.backdrop.hidden { display: none; }
/* 청산 확인은 설정창 위에서 열린다. DOM 순서에 기대지 않고 명시해 둔다 —
   나중에 마크업 순서가 바뀌면 조용히 설정창 뒤로 숨어 버린다. */
#exit-pop { z-index: 210; }

.modal {
  width: 300px;
  max-height: 82vh;
  overflow-y: auto;
  padding: 16px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .6);
}
.modal-title {
  display: flex;
  align-items: center;
  font-size: 13px;
  font-weight: 700;
  padding-bottom: 11px;
  margin-bottom: 13px;
  border-bottom: 1px solid var(--line);
}
.modal-title button {
  width: auto;
  margin: 0;
  padding: 2px 8px;
  font-size: 14px;
  line-height: 1;
}

/* ── 모호한 곳 짚기 ───────────────────────────────────────────
   AI 의 되물음을 글이 아니라 선택지로 낸다.

   ★ 창 하나에 물음이 넷까지 들어온다. 그래서 물음마다 세로로 쌓고, 고른 것은
     테두리 색이 아니라 **채움**으로 표시한다 — 새벽에 졸린 눈으로도 무엇을
     골랐는지 한눈에 보여야 한다(이 파일 머리말의 원칙). */
.modal.ask { width: min(520px, 92vw); }

.ask-q { margin-bottom: 15px; }
.ask-q:last-child { margin-bottom: 4px; }
.ask-q > b {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--fg);
  margin-bottom: 7px;
}
.ask-opts { display: flex; flex-direction: column; gap: 5px; }
.ask-opts button {
  width: 100%;
  margin: 0;
  padding: 8px 10px;
  text-align: left;
  font-size: 12px;
  line-height: 1.45;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--fg);
}
.ask-opts button:hover { border-color: var(--line-2); background: rgba(255, 255, 255, .04); }
.ask-opts button.on {
  background: var(--accent);
  border-color: var(--accent-2);
  color: #fff;
}
/* 고르면 어떻게 되는지. 고른 뒤에도 읽혀야 해서 채움 위에서도 대비를 준다. */
.ask-opts em {
  display: block;
  font-style: normal;
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
}
.ask-opts button.on em { color: rgba(255, 255, 255, .75); }

/* ── 설정 창 ─────────────────────────────────────────────────── */

/* 표가 들어가므로 넓게. 화면이 좁으면 화면을 따라 줄어든다. */
.modal.wide {
  width: min(880px, 92vw);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;      /* 스크롤은 안쪽 본문이 맡는다 */
}

/* ★ 설정 창은 **탭을 바꿔도 크기가 안 변한다.**
     .modal.wide 는 내용만큼만 커지므로, 계좌 상태(짧다)에서 알림(길다)으로
     옮기면 창이 그 자리에서 늘었다 줄었다 했다. 왼쪽 탭 줄까지 함께 움직여서
     방금 누른 버튼이 손 밑에서 달아났다.
   ★ 높이를 박지 않고 min() 으로 잡는다. 화면이 낮으면 화면을 따라 줄어야 한다.
     안쪽(#set-main)이 이미 스크롤을 맡고 있어서 내용이 길어도 넘치지 않는다. */
#set-pop .modal.wide { height: min(660px, 86vh); }

.set-body {
  display: grid;
  grid-template-columns: 132px 1fr;
  gap: 16px;
  min-height: 0;         /* 이게 없으면 grid 자식이 안 줄어들어 스크롤이 안 생긴다 */
  flex: 1;
}

#set-nav {
  display: flex;
  flex-direction: column;
  gap: 3px;
  border-right: 1px solid var(--line);
  padding-right: 12px;
  overflow-y: auto;
}
#set-nav button {
  width: 100%;
  margin: 0;
  padding: 8px 10px;
  text-align: left;
  font-size: 11.5px;
  background: transparent;
  border-color: transparent;
}
#set-nav button:hover { background: var(--bg); border-color: var(--line); }
#set-nav button.on {
  background: var(--bg);
  border-color: var(--line-2);
  color: var(--accent-fg);
  font-weight: 600;
}

#set-main { overflow-y: auto; padding-right: 4px; }
#set-main h3:first-child { margin-top: 0; }

/* 잔고가 언제 값인지. 단추 줄 **바로 아래**에 작게 — 안 밝히면 몇 분 전
   잔고를 지금 값으로 읽는다.
   ★ 예전에는 줄 안에 있었는데, 그러면 단추 셋과 한 칸을 나눠 가져서 줄이
     어긋나 보였다. 글은 단추가 아니므로 단추와 같은 칸을 다투면 안 된다. */
.bal-age { color: var(--dim); font-size: 10.5px; margin: 6px 0 0; }

/* 전면 정지 단추가 앉는 칸. 새로고침·로그아웃과 **한 줄에** 선다.
   ★ .row > * { flex: 1 } 이라 이 span 이 한 칸을 받는다. 단추가 그 칸을
     다 쓰게 해야 옆 단추들과 폭이 같아진다 — 안 그러면 혼자 글자 크기만큼
     쪼그라들어 셋이 어긋나 보인다. */
#acct-halt { display: flex; }
#acct-halt > button { flex: 1; }

/* 전체 청산 — **표 아래 오른쪽에 작게.** 되돌릴 수 없는 버튼이 목록 위에서
   넓게 기다리고 있으면, 보유 종목을 보러 들어올 때마다 그것부터 눈에 닿는다.
   무엇을 팔지 보고 나서 누르는 순서가 맞다. */
.pos-foot { display: flex; justify-content: flex-end; margin-top: 10px; }
button.sm { width: auto; margin: 0; padding: 5px 10px; font-size: 11px; }

/* 잔고 카드. 계좌 상태 탭에서 가장 먼저 눈에 들어와야 할 두 숫자다. */
.bal-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 16px;
}
.bal-card {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
}
.bal-card em {
  display: block;
  font-style: normal;
  font-size: 10.5px;
  color: var(--muted);
  margin-bottom: 5px;
}
/* 달러 옆의 원화. **작고 옅다** — 이 계좌의 진짜 숫자는 달러 하나이고,
   원화는 그것을 읽기 쉽게 옮겨 적은 것일 뿐이다. 같은 크기로 두면 둘 다
   장부의 숫자처럼 보인다. (환율이 섞여 사고가 났던 프로젝트에서 갈라져
   나온 만큼, 이 위계는 눈에 보여야 한다.) */
.bal-card b .krw {
  font-style: normal;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: 0;
}
/* 환율 한 줄. 원화 숫자를 읽는 근거라 원화 바로 밑에 붙는다. */
.bal-card .fx {
  display: block;
  margin-top: 5px;
  font-size: 10.5px;
  line-height: 1.4;
}
.bal-card .fx a { color: var(--accent-fg); text-decoration: none; }
.bal-card .fx a:hover { text-decoration: underline; }

.bal-card b {
  display: block;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -.3px;
  /* 숫자 폭이 고르지 않으면 새로고침할 때마다 자릿수가 들썩인다. */
  font-variant-numeric: tabular-nums;
}
/* '평가금액 / 매입금액' 의 뒷숫자. 기준값이라 앞 숫자보다 뒤로 물러나야 한다. */
.bal-card b i {
  font-style: normal;
  font-size: 13px;
  font-weight: 400;
  color: var(--muted);
}
.bal-card span {
  display: block;
  margin-top: 4px;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}
.bal-card span.muted { color: var(--muted); }

@media (max-width: 720px) {
  .bal-cards { grid-template-columns: 1fr; }
}

/* 이름-값 표. 레벨 표와 달리 왼쪽 칸이 이름이라 오른쪽 정렬을 풀어야 한다. */
table.kv { margin-top: 6px; }
table.kv td { padding: 6px 4px; }
table.kv td:first-child { color: var(--muted); width: 40%; }
table.kv td:nth-child(2) { text-align: left; }
/* 숫자 뒤에 붙는 단서("달러 쪽"). 기울이면 숫자보다 눈에 띈다. */
table.kv i { font-style: normal; font-size: 11px; }

/* 확정 손익 성적표. 주문 내역 맨 위에 선다.
   ★ 큰 숫자 **하나**. 잔고 카드와 모양을
     일부러 다르게 했다 — 저쪽은 증권사가 말하는 '지금' 이고 이쪽은 우리 주문이
     쌓은 '과거' 라, 같은 모양이면 같은 종류로 읽힌다. */
.score {
  margin-bottom: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
}
.score-sum {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
}
.score-sum em {
  font-style: normal;
  font-size: 11px;
  color: var(--muted);
}
.score-sum b { font-size: 21px; }
/* ★ 전적(.score-tally)과 종목별 알약(.score-by) 규칙은 지웠다. 그 줄들을
     화면에서 걷어냈으니 여기 남을 이유도 없다 — 안 쓰는 CSS 는 다음에 이
     파일을 여는 사람에게 "아직 쓰는 것" 으로 보인다. */

.set-table { overflow-x: auto; }   /* 열이 많으면 표만 가로로 민다 */
.set-table table { margin-top: 6px; white-space: nowrap; }
.set-table td, .set-table th { padding: 6px 8px 6px 0; }
/* 레벨 표용 오른쪽 정렬이 여기까지 오면 안 된다 — 여긴 글자 칸이 많다. */
.set-table td:nth-child(2), .set-table td:nth-child(3) { text-align: left; }
.set-table td.wrap { white-space: normal; min-width: 160px; color: var(--muted); }
.set-table input {
  width: 84px;
  margin: 0;
  padding: 4px 6px;
  font-size: 11px;
}
.set-table button { width: auto; margin: 0 0 0 4px; padding: 4px 8px; font-size: 10px; }
.set-table button.on { background: var(--ok); border-color: var(--ok); color: #fff; }

/* DRY_RUN 주문 표시 */
.tag {
  font-style: normal;
  font-size: 9.5px;
  padding: 1px 4px;
  border-radius: 3px;
  background: var(--line-2);
  color: var(--fg-dim);
}

/* 저장은 됐지만 주문은 못 나가는 계획(한국 종목 등). .warn 은 블록형 경고 상자라
   여기 붙이면 칩이 아니라 상자가 된다 — 칩 전용 변형을 따로 둔다. */
.tag.bad { color: var(--err); background: rgba(239, 83, 80, .12); }

.lv-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
  color: var(--muted);
  margin: 14px 0 7px;
}
.lv-head button { width: auto; margin: 0; padding: 4px 9px; font-size: 11px; }

/* ★ 레벨은 **두 칸으로 세운다.** 기본이 아홉 개인데 한 줄로 세우면 창이 길어져
   이름 칸과 [적용] 이 멀어지고, 몇 개만 더 넣어도 스크롤이 생긴다(.modal 은
   max-height: 82vh). 두 칸이면 아홉 개가 다섯 줄에 들어온다.
   ★ 채우는 방향은 **가로 먼저**다(grid 기본). 세로 먼저로 두면 레벨을 하나
     지웠을 때 남은 것들이 두 칸 사이를 건너뛰며 재배치돼 눈이 자리를 잃는다. */
.lv-rows {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px 8px;
}
.lv-row { display: flex; gap: 5px; }
.lv-row .lv-input { flex: 1; font-variant-numeric: tabular-nums; }
.lv-row .lv-del {
  width: 30px;
  margin: 0;
  padding: 0;
  color: var(--muted);
  flex: none;
}
.lv-row .lv-del:hover { color: var(--err); border-color: var(--err); }

/* 채널 설정만 넓다 — 레벨이 두 칸으로 서기 때문이다. .modal 을 통째로 넓히면
   청산 확인(#exit-pop) 처럼 문구 몇 줄뿐인 창까지 허전해진다.
       380 − 32(안쪽 여백) − 2(선) = 346 → 한 칸 169 → 입력칸 134px */
#edit-pop .modal { width: 380px; }

/* 계획 수정 창. 조건 한 줄이 길어서 좁으면 대여섯 줄로 접힌다 —
   "EMA(50)이 EMA(200)을 상향 돌파했고 그때 RSI(14)가 70 미만이면" 같은 문장이다.
   ★ 이 창은 backdrop 안에 동적으로 만들어져서 #id 로 못 잡는다. 클래스로 잡는다
     (js/plan.js 의 MARKUP). */
/* ★ 440px 이었다. '다시 알리기까지' 줄을 설정으로 내보내면서 남은 자리를
   매수·매도 칸에 준다 — 거기가 이 창에서 제일 좁았다. 단위 칸(전량·금액·주수·
   비율·시드%) 다섯과 숫자 칸이 한 줄에 서야 하는데 440 에서는 아슬아슬하게
   접혔고, 접히면 "금액 $100" 이 두 줄로 갈려서 무엇의 100 인지 안 읽힌다. */
.modal.plan-edit { width: 500px; }
/* 칸 글자도 같이 키운다 — 창만 넓히면 넓은 창에 작은 글씨가 된다. */
.modal.plan-edit label { font-size: 12px; }
.modal.plan-edit input { font-size: 13px; }

/* ═══════════════════════════════════════════════════════════════
   감시 현황 창 — 이 화면에서 가장 자주 읽는 곳.

   읽는 순서가 곧 크기 순서다.
     ① 남은 거리(%)  ② 종목  ③ 현재가  ④ 레벨 상세
   ═══════════════════════════════════════════════════════════════ */

.float {
  position: fixed;
  z-index: 150;
  /* 사이드바가 왼쪽이므로 기본 위치는 오른쪽 끝. 끌어 옮기면 그 자리가 저장된다. */
  top: 68px;
  right: 16px;
  width: 380px;
  max-width: calc(100vw - 24px);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, .5);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.float.hidden { display: none; }

.float-head {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: none;
  padding: 12px 12px 12px 14px;
  border-bottom: 1px solid var(--line);
  cursor: grab;
  user-select: none;
}
.float-head:active { cursor: grabbing; }
.float-head b { font-size: 13px; font-weight: 700; white-space: nowrap; }
.float-head .grip {
  width: 14px;
  height: 14px;
  flex: none;
  fill: var(--muted);
  stroke: none;
}
.float-head button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex: none;
  margin: 0;
  padding: 0;
  background: none;
  border-color: transparent;
  color: var(--muted);
}
.float-head button:hover { background: rgba(255, 255, 255, .06); color: var(--fg); }
.float-head button.danger:hover { background: rgba(239, 83, 80, .12); color: var(--err); }
.float-head .ico { width: 14px; height: 14px; stroke-width: 1.8; }

.float-body {
  overflow-y: auto;
  max-height: 62vh;
  padding: 8px 10px 12px;
}

.mon-sym { padding: 2px 0; }
.mon-sym + .mon-sym { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 6px; }
.mon-sym.off { opacity: .5; }

.mon-sym-head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 4px;
}
.mon-name { font-size: 14px; font-weight: 700; }

/* 종목 줄의 "2/3" 은 알약, 규칙 줄의 같은 클래스는 그냥 흐린 글씨 */
.mon-sym-head .mon-lv {
  font-size: 10.5px;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 1px 7px;
}
.mon-price {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.mon-src {
  font-size: 10px;
  color: var(--muted);
  background: var(--bg);
  border-radius: 4px;
  padding: 2px 6px;
  font-weight: 400;
}

/* 규칙은 종목 밑에 한 단 들여 쓴다 — 무엇에 딸린 것인지 선으로 보인다. */
.mon-rule {
  margin: 2px 0 4px 30px;
  padding: 6px 8px;
  border-left: 2px solid var(--line);
  border-radius: 0 6px 6px 0;
  cursor: pointer;
  font-size: 11px;
}
.mon-rule:hover { border-left-color: var(--line-2); background: rgba(255, 255, 255, .03); }
.mon-rule.hit {
  border-left: 3px solid var(--ok);
  background: rgba(38, 166, 154, .1);
}
/* ★ 계획 줄에는 이제 안 붙는다. 알림이 꺼진 계획도 주문은 내므로 흐리면
   화면이 "안 돈다" 고 말하는 셈이 된다 — 대신 '주문만' 딱지를 단다(.mon-quiet).
   선·채널 규칙 쪽에서는 그대로 쓴다. */
.mon-rule.idle { opacity: .45; }
/* 알림은 꺼졌지만 주문은 나가는 계획. 흐림이 아니라 **말**로 알린다. */
.mon-quiet {
  flex: none;
  padding: 1px 5px;
  border: 1px dashed var(--line-2);
  border-radius: 4px;
  font-size: 10px;
  color: var(--dim);
  white-space: nowrap;
}

.mon-rule-head { display: flex; align-items: center; gap: 8px; }
.mon-rule-head .mon-target,
.mon-rule-head .mon-lv[data-rule] { cursor: pointer; }

.mon-target { font-size: 12.5px; font-weight: 600; color: var(--fg); }
.mon-rule-head .mon-lv { font-size: 11px; color: var(--muted); }

/* ★ 남은 거리 — 화면에서 가장 큰 숫자. 여기만 보고 판단할 수 있어야 한다. */
.mon-left {
  margin-left: auto;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -.3px;
  color: var(--accent-fg);
  font-variant-numeric: tabular-nums;
}
/* 이미 범위 안이면 숫자가 아니라 "감지됨" — 크기 대신 배지로 바꿔 눈에 띄게 한다. */
.mon-left.hit {
  font-size: 13px;
  color: var(--ok);
  background: rgba(38, 166, 154, .16);
  border-radius: 5px;
  padding: 3px 9px;
}

.mon-detail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 3px 8px;
  color: var(--fg-dim);
  font-size: 11px;
  margin-top: 3px;
  padding-left: 2px;
  font-variant-numeric: tabular-nums;
}
.mon-levels { margin: 5px 0 2px; display: flex; flex-direction: column; gap: 3px; }
.mon-levels .mon-detail { margin-top: 0; }

.mon-lv-tag {
  font-size: 9px;
  color: #c8cad6;
  background: var(--line);
  border-radius: 3px;
  padding: 1px 5px;
  flex: none;
}

.mon-empty {
  color: var(--muted);
  font-size: 11.5px;
  padding: 14px 12px;
  margin: 4px 0;
  border: 1px dashed var(--line);
  border-radius: 6px;
  text-align: center;
  line-height: 1.7;
}

/* ── 매매 계획 (조건 알림) ───────────────────────────────────────
   그은 선을 보는 규칙과 나란히 선다. 다른 것은 **거리가 없다**는 점이다 —
   조건은 참이거나 거짓이라 "골든크로스까지 몇 %" 는 뜻이 없다. */
.mon-plan { cursor: default; }
.mon-plan .mon-left {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
}
/* 매수·매도를 색으로 가른다. 계획이 여럿이면 이름만으로는 안 갈린다. */
.mon-rule-head .mon-lv.buy { color: var(--ok); }
.mon-rule-head .mon-lv.sell { color: var(--err); }

/* 매매 스위치. 알림 스위치 **바로 아래**에 둔다 — 위는 "알릴지", 아래는
   "주문까지 낼지" 다. 하나로 묶으면 알림만 받으려던 사람에게 주문이 나간다. */
.mon-trade { gap: 6px; padding-left: 0; }
.mon-trade-on { color: var(--accent-fg); font-weight: 600; }

/* 창 맨 위에 붙는 한 줄. 지금은 **전면 정지** 하나만 이것을 쓴다 —
   '주문이 실제로 나갑니다' 는 잠금을 푸는 날부터 늘 켜져 있어서 경고가
   아니라 배경이 됐고, 그래서 걷어냈다 (monitor.js 의 orderBadge). */
.mon-orders {
  margin: 2px 0 8px;
  padding: 7px 10px;
  border-radius: 6px;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--muted);
  font-size: 11px;
  line-height: 1.6;
}
.mon-orders em { display: block; font-style: normal; color: var(--dim); font-size: 10.5px; }

/* 감시 목록에서 지우는 X. 평소에는 숨기고 줄에 마우스를 올렸을 때만 —
   늘 보이면 지우는 버튼이 켜고 끄는 스위치보다 눈에 띈다. */
.mon-x {
  width: auto;
  margin: 0;
  padding: 2px 6px;
  font-size: 12px;
  line-height: 1;
  opacity: 0;
  transition: opacity .12s ease;
}
.mon-rule:hover .mon-x, .mon-rule:focus-within .mon-x { opacity: 1; }

/* ── 켜고 끄는 스위치 ────────────────────────────────────────── */

.sw { position: relative; width: 32px; height: 18px; flex: none; }
.sw input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.sw span {
  position: absolute;
  inset: 0;
  background: var(--line-2);
  border-radius: 999px;
  transition: background .15s;
  pointer-events: none;
}
.sw span::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  background: var(--fg-dim);
  border-radius: 50%;
  transition: transform .15s, background .15s;
}
.sw input:checked + span {
  background: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .08);
}
.sw input:checked + span::after { transform: translateX(14px); background: #fff; }

/* 규칙 하나짜리 스위치 — 종목 스위치보다 작게 해서 위계를 드러낸다 */
.sw-sm { width: 24px; height: 14px; }
.sw-sm span::after { width: 10px; height: 10px; }
.sw-sm input:checked + span::after { transform: translateX(10px); }

/* 이미 감지된 규칙은 스위치도 같은 초록으로 — 줄 전체가 한 가지 상태로 읽힌다. */
.mon-rule.hit .sw input:checked + span { background: var(--ok); }

@media (max-width: 720px) {
  /* 좁은 화면에서는 패널이 남은 폭을 다 쓴다. 빼는 값은 레일 폭이다. */
  #flyout { width: calc(100vw - 68px); }
  .status { max-width: 160px; }
}

/* ═══════════════════════════════════════════════════════════════
   AI 계획수립 페이지 (ai.html)

   차트 화면과 다른 페이지다. 왼쪽이 대화, 오른쪽이 '조건' 칸.
   조건 칸을 고정폭으로 두는 이유: 여기 뜨는 문장이 **실제로 판정할 것**이라
   대화가 길어져도 자리가 밀리거나 좁아지면 안 된다.
   ═══════════════════════════════════════════════════════════════ */

/* ★ '← 차트' 되돌아가기 규칙이 여기 있었다. 그 문은 아래 막대로 내려갔다
     (.pagebar). 차트만 왼쪽 끝, 나머지 문은 오른쪽 끝이라 같은 성격의 것이
     양 끝에 갈라져 있었다. */

.head-field {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 11px;
  white-space: nowrap;
}
.head-field select { min-width: 120px; }

.ai-main {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 220px 1fr 380px;
  /* 행을 명시한다. 암묵 행(auto)이 늘어나 주는 것에 기대면, 대화가 짧을 때
     조건 칸이 내용 높이만큼만 서고 아래가 비어 보인다. */
  grid-template-rows: 1fr;
}

/* ── 대화 목록 ───────────────────────────────────────────────── */

#chats {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel);
  border-right: 1px solid var(--line);
  padding: 12px 10px;
}
.chats-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 8px;
}
.chats-head b { font-size: 13px; }
.chats-head button { width: auto; margin: 0; padding: 4px 8px; font-size: 11px; }

#chat-list { flex: 1; min-height: 0; overflow-y: auto; margin: 0; }
#chat-list .item {
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  cursor: pointer;
  /* 목록에서는 칸마다 테두리를 두르지 않는다. 스무 개가 쌓이면 선이 스무 줄이라
     정작 **고른 것**이 안 보인다. */
  padding: 10px 10px 10px 13px;
  border-radius: 9px;
  background: transparent;
  border-color: transparent;
}
#chat-list .item:hover { background: rgba(255, 255, 255, .04); }

/* 지금 보고 있는 방.
   ★ 테두리를 두르는 대신 **왼쪽에 빛나는 막대**를 세운다. 목록이 좁아서
     (220px) 테두리를 두르면 안 그래도 짧은 제목이 더 짧아지고, 색만 옅게
     깔면 마우스를 올린 칸과 구분이 안 된다. 막대는 자리를 거의 안 먹으면서
     훑을 때 바로 눈에 걸린다. 왼쪽 padding 13px 이 그 자리다. */
#chat-list .item.on {
  background: rgba(255, 255, 255, .05);
  border-color: transparent;
}
#chat-list .item.on::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  bottom: 8px;
  width: 2.5px;
  border-radius: 2px;
  background: var(--accent-fg);
  box-shadow: 0 0 8px rgba(217, 145, 122, .6);
}
#chat-list .item b { color: var(--fg-dim); }
#chat-list .item.on b { color: #f2ede9; font-weight: 600; }
#chat-list .item.on em { color: var(--fg-dim); }
#chat-list .item b {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}
#chat-list .item em { color: var(--muted); font-size: 10.5px; font-style: normal; }
#chat-list .item .row-x {
  position: absolute;
  right: 6px;
  top: 6px;
  width: auto;
  margin: 0;
  padding: 1px 5px;
  opacity: 0;
}
#chat-list .item { position: relative; }
#chat-list .item:hover .row-x { opacity: 1; }

/* ── 대화 ────────────────────────────────────────────────────── */

#chat {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  padding: 16px 20px 10px;
}

#chat-log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding-right: 6px;
}

.ai-intro { max-width: 620px; margin: 6vh auto 0; text-align: center; }
.ai-intro h2 { font-size: 20px; font-weight: 600; margin: 0 0 10px; }
.ai-intro p { color: var(--muted); line-height: 1.7; margin: 0 0 22px; }

/* 예시 알약. 시안대로 **세로로 하나씩** 쌓는다.
   가로로 흘려 놓으면(전에 flex-wrap 이었다) 창 너비에 따라 두 줄이 됐다 세 줄이
   됐다 하면서 줄바꿈 자리가 매번 달라진다. 이건 읽는 목록이 아니라 **고르는
   목록**이라, 눈이 위에서 아래로 한 번만 훑고 끝나야 한다.
   너비는 글자에 맞춘다 — 다 같은 너비로 늘리면 버튼 다섯 개짜리 서식처럼 보인다. */
.samples {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
}
.samples button {
  width: auto;           /* ← 전역 width:100% 를 되돌린다 */
  margin: 0;
  /* 알약. 16px 은 '모서리 둥근 네모' 로 읽히는데, 시안은 완전한 알약이다. */
  border-radius: 999px;
  padding: 9px 18px;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--fg-dim);
  font-size: 12px;
}
.samples button:hover {
  color: var(--fg);
  border-color: var(--accent-fg);
  background: var(--accent-soft);
}

.msg { display: flex; gap: 10px; max-width: 640px; margin-bottom: 14px; }
/* 내 말은 오른쪽에 붙는다. margin-left:auto 로 미는 이유는 max-width 가 걸려
   있어서다 — justify-content 만으로는 640px 짜리 상자 안에서만 오른쪽이 된다. */
.msg.user { margin-left: auto; justify-content: flex-end; }

/* AI 말풍선 앞의 동그란 표식. 누가 한 말인지 색만으로 가르면, 거절 문구처럼
   색이 따로 붙는 줄에서 구분이 흐려진다. */
.msg .who {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(138, 74, 61, .16);
  color: var(--accent-fg);
}
.msg .who .ico { width: 14px; height: 14px; }

.bub {
  padding: 10px 14px;
  /* 꼬리 쪽 모서리만 각지게. 어느 쪽에서 나온 말인지 모양으로도 드러난다. */
  border-radius: 12px 12px 12px 2px;
  background: var(--panel);
  border: 1px solid var(--line);
  /* 사용자가 줄바꿈을 넣었으면 그대로 보여야 한다. 긴 티커·URL 은 강제로 접는다. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  line-height: 1.5;
}
.msg.user .bub {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  border-radius: 12px 12px 2px 12px;
}
/* 답을 기다리는 동안의 점 셋.
   ★ 글자만 서 있으면 기다리는 중인지 멈췄는지 같아 보인다. 답이 반드시
     몇 초 걸리는 화면이라, 살아 있다는 표가 있어야 한 번 더 보내지 않는다.
   ★ 움직임은 **CSS 가 맡는다.** setInterval 로 그리면 대화를 다시 그릴 때마다
     끊기고, 끝내는 사라진 점을 위해 타이머가 영영 돌게 된다. */
.bub.dots { color: var(--muted); font-style: italic; }
.bub.dots i {
  display: inline-block;
  width: 3.5px;
  height: 3.5px;
  margin-left: 3px;
  border-radius: 50%;
  background: currentColor;
  vertical-align: 2px;
  animation: dot-bob 1.15s ease-in-out infinite;
}
.bub.dots i:nth-of-type(2) { animation-delay: .16s; }
.bub.dots i:nth-of-type(3) { animation-delay: .32s; }
/* 기다린 초. ★ 3초 넘게 걸릴 때만 붙는다 — 늘 있으면 짧은 답에서 '0초 1초'가
   깜빡여 오히려 어수선하고, 정작 길어질 때의 신호값이 죽는다.
   기울임을 되돌린다: 숫자는 문장이 아니라 눈금이라 곧게 서는 편이 읽힌다. */
.bub.dots .waited { margin-left: .35em; font-style: normal; font-variant-numeric: tabular-nums; }

@keyframes dot-bob {
  0%, 70%, 100% { transform: translateY(0); opacity: .3; }
  35% { transform: translateY(-3px); opacity: 1; }
}

/* 움직임을 꾸진 사람은 안 움직이게. 다만 **사라지지는 않게** 한다 —
   점이 아예 안 보이면 기다리는 중인지를 알 길이 없어진다. */
@media (prefers-reduced-motion: reduce) {
  .bub.dots i { animation: none; opacity: .55; }
}

/* ★ 여기서 쓰는 것이 글 쓰는 칸이다. 버튼이 아니라 칸이 커야 한다.
   전역 규칙에 button { width: 100% } 이 있어서, 되돌리지 않으면 보내기 버튼이
   줄 전체를 먹고 글 쓰는 칸이 남은 자리로 밀린다. */
/* 쓰는 칸과 보내기 버튼이 **한 상자 안에** 든다. 테두리가 상자에만 있고
   글 쓰는 칸에는 없어서, 상자 전체가 하나의 입력처럼 보인다. */
#chat-box {
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  margin-top: 10px;
  padding: 10px 10px 10px 14px;
  border-radius: 10px;
  background: var(--panel);
  backdrop-filter: var(--glass);
  -webkit-backdrop-filter: var(--glass);
  border: 1px solid var(--line);
}
#chat-box:focus-within { border-color: var(--accent-fg); }

#chat-input {
  flex: 1;
  min-width: 0;
  /* 두 줄쯤에서 시작하고, 쓰는 만큼 grow() 가 200px 까지 늘린다. 조건 문장은
     한 줄로 안 끝나는 경우가 많아서 쓰는 동안 자기가 쓴 글이 보여야 한다. */
  min-height: 44px;
  resize: none;
  overflow-y: auto;
  line-height: 1.5;
  font: inherit;
  font-size: 13px;
  padding: 4px 0;
  background: transparent;
  border: none;
  color: var(--fg);
}
#chat-input:focus { outline: none; }
#chat-input:disabled { opacity: .5; }
#chat-input::placeholder { color: var(--muted); }

#chat-send {
  flex: none;
  width: 34px;          /* ← 전역 width:100% 를 되돌린다 */
  height: 34px;
  margin: 0;
  padding: 0;
  border-radius: 8px;
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
#chat-send:hover { background: var(--accent-2); border-color: var(--accent-2); }
#chat-send .ico { width: 15px; height: 15px; fill: currentColor; stroke: none; }

.chat-note { flex: none; margin: 8px 2px 0; color: var(--dim); }
/* 도움말로 가는 길. 머리말에 '도움말' 버튼이 있었는데, 그 자리는 세 화면이
   같아야 하는 자리(알림 상자 · 설정 상자)라 여기로 내렸다 — 무엇을 부탁할 수
   있는지가 실제로 궁금해지는 곳은 입력칸 바로 아래다. 거절 표시의 링크와
   같은 색을 쓴다(.refuse-note a): 둘 다 같은 창을 연다. */
.chat-note a { color: var(--accent-fg); text-decoration: none; }
.chat-note a:hover { text-decoration: underline; }

/* 조건 칸 안의 주기 선택. 머리말 크기에 묻히지 않게 작고 또렷하게. */
/* 조건 칸의 주기 고르개. 유리 위에 얹히는 물건이라 --bg 로 칠하면 그 자리만
   불투명하게 파여 보인다. 어둡게 비치는 유리로 두고 테두리만 흰빛으로 준다. */
.res-pick {
  width: auto;
  padding: 5px 8px;
  font-size: 11.5px;
  color: var(--fg);
  background: rgba(20, 15, 14, .55);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 7px;
  appearance: none;
  -webkit-appearance: none;
}
.res-pick:hover { border-color: rgba(255, 255, 255, .16); }

/* ── 조건 칸 ─────────────────────────────────────────────────── */

#cond {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel);
  border-left: 1px solid var(--line);
  padding: 12px 14px;
}

.cond-head {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 10px;
}
.cond-head b { font-size: 13px; }

#cond-body {
  flex: 1;
  min-height: 90px;
  overflow-y: auto;
}
.cond-empty { color: var(--muted); font-size: 12px; line-height: 1.8; margin: 10px 2px; }

/* 조건 트리. 들여쓰기는 인라인 style 로 붙는다 (깊이가 가변이라). */
.c-node {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 4px 0;
  line-height: 1.6;
  overflow-wrap: anywhere;
}
.c-node .c-dot, .c-node .c-branch {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  transform: translateY(-1px);
}
.c-node .c-dot { background: var(--accent-fg); }
/* 묶음(모두/하나라도)은 속이 빈 표식 — 그 자체는 판정이 아니라 묶음이다. */
.c-node .c-branch { border: 1.5px solid var(--muted); }
.c-node:has(.c-branch) > span { color: var(--muted); font-size: 11.5px; }
.c-card .c-node { font-size: 11.5px; color: var(--fg-dim); }

/* 계획 개수 배지 (계획 전체 창의 머리).
   ★ 몇 개인지보다 **몇 개가 켜져 있는지**가 알아야 할 값이라 그쪽을 적는다.
   ★ 오른쪽 '저장된 계획' 칸에서는 뺐다. 켜진 개수는 줄마다 스위치를 보면
     아는 값이고, 그 칸은 목록 한 줄이 아까운 자리다. */

/* ── 대상 종목 ───────────────────────────────────────────────────
   고르는 곳이 아니라 **보여주는 곳**이다. 대상은 대화가 정한다. 여기에 다시
   고르는 물건을 두면 종목을 정하는 곳이 둘이 되고, 그 둘이 어긋나는 것이
   예전에 "테슬라도 해줘" 가 애플로 저장되던 사고였다. */

.c-target {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--line);
}
.c-target > b { font-size: 11px; color: var(--muted); font-weight: 500; }
.c-target.none { display: block; }
.c-target.none b { display: block; font-size: 12px; color: var(--err); font-weight: 600; }
.c-target.none em { display: block; font-style: normal; font-size: 11px; color: var(--muted); margin-top: 3px; }

.t-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px 3px 4px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--line);
  font-size: 12px;
  color: var(--fg);
}

/* 조건 카드. 유리 위에 파인 한 장으로 담는다 — 대상 종목·백테스트·저장된 계획과
   구분되는 덩이여야 눈이 셋을 따로 읽는다. */
.c-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px;
}
.c-card-head {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}
/* 쓰인 지표 이름표. 문장을 다 읽기 전에 무엇으로 만든 조건인지 보인다. */
.c-tag {
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--panel);
  backdrop-filter: var(--glass);
  -webkit-backdrop-filter: var(--glass);
  color: var(--muted);
  font-size: 10px;
}

/* ── 백테스트 ──────────────────────────────────────────────────
   ★ .hidden 은 이 프로젝트에 **전역 규칙이 없다.** 선택자마다 따로 적는다
     (#flyout.hidden · .pop.hidden · .float.hidden …). 여기를 빠뜨려서
     '새 대화' 를 눌러도 지난 발화 목록이 그대로 남아 있었다. 새 칸을 만들 때
     잊기 쉬운 자리다. */
#cond-back.hidden { display: none; }

/* ★ 그리고 또 빠뜨렸다. 이번에는 계획 수립 창의 **매도 칸**이었다 —
     매수 조건만 만들었는데도 "얼마나 팔지" 가 나란히 떴다. classList.toggle
     ('hidden') 은 조용히 아무 일도 안 한다. 규칙이 없으면 아무 일도 없다.

   ★ 그래서 한 자리에 모아 둔다. 화면 코드가 숨기는 칸은 여기 다 있어야 하고,
     빠지면 시험(test_js_loads)이 잡는다. display 를 따로 지정한 칸일수록
     위험하다 — 그런 칸은 '안 보이게' 를 아무도 안 걸어 두면 늘 보인다. */
.so-col.hidden,
.so-limits.hidden,
.field.hidden,
.snap-chart.hidden,
.snap-note.hidden,
.run-sum.hidden,
.run-when.hidden,
.save-over.hidden { display: none; }

/* ★ 이 칸은 **자라지 않는다.** 예전에는 높이 규칙이 없어서 발화가 많으면
   (대상이 두세 종목이면 금방 스무 줄이다) 아래 있는 계획 수립 버튼을 화면
   밖으로 밀어냈다 — 조건을 다 만들어 놓고 저장을 못 하는 꼴이었다.
   넘치는 것은 여기서 스크롤로 받는다. 안쪽(.bt-rest)에 또 스크롤을 두지
   않는 이유: 스크롤 상자가 겹치면 어느 것이 움직이는지 알 수가 없다. */
#cond-back {
  flex: none;
  max-height: 34vh;
  overflow-y: auto;
}

.bt-label { color: var(--muted); font-size: 11px; margin-bottom: 8px; }

/* 대상이 여럿이면 어느 종목의 숫자인지 이름표를 붙인다. 하나면 붙이지 않는다 —
   당연한 것을 적으면 정작 다를 때 눈에 안 들어온다. */
.bt-who {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  font-size: 12px;
}
.bt-who + .bt { margin-top: 4px; }

/* 정상 백테스트는 상자를 두르지 않는다. 발화 줄 하나하나가 이미 상자라,
   바깥에 또 두르면 상자 안의 상자가 된다. 상자는 '안 됨' 을 알릴 때만 쓴다. */
.bt {
  flex: none;
  margin-top: 14px;
}
.bt.bad {
  padding: 10px 11px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--line);
}
.bt b { display: block; font-size: 13px; color: var(--ok); }
.bt.bad b { color: var(--err); }
.bt em { display: block; color: var(--muted); font-style: normal; font-size: 11px; margin-top: 3px; }

/* 발화한 날과 **그때 가격**을 나란히. 날짜만 있으면 "그래서 얼마였는데" 를
   차트로 건너가 확인해야 한다. 가격은 판정에 쓴 그 봉의 종가다. */
.bt-rows { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.bt-rows:empty { display: none; }
.bt-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 10px;
  border-radius: 6px;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--fg);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}
.bt-row s { color: var(--ok); font-weight: 600; text-decoration: none; }
/* 누를 수 있는 줄이라는 것이 보여야 한다 — 안 그러면 아무도 안 누른다. */
.bt-row[data-fire] { cursor: pointer; }
.bt-row[data-fire]:hover { background: var(--panel); outline: 1px solid var(--line); }

/* 발화 시점 차트. 높이를 고정한다 — 라이브러리가 부모 높이를 재서 그리는데
   부모가 내용에 맞춰 늘어나면 0 이 되어 아무것도 안 그려진다.
   ★ flex:none 이 꼭 있어야 한다. .modal.wide 는 flex 세로 상자라 기본
     flex-shrink:1 이 걸리고, 그러면 height 를 적어 둬도 눌려서 0 이 된다. */
.snap-chart { flex: none; height: 380px; width: 100%; }
.snap-note {
  flex: none;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.7;
  margin: 10px 2px 0;
}
/* 접어 둔 나머지 발화. 펼치면 위 줄들과 이어 붙어 한 목록으로 보인다. */
.bt-rest { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.bt-rest.hidden { display: none; }

.bt-toggle {
  width: 100%;
  margin: 8px 0 0;
  padding: 5px;
  background: none;
  border: 1px dashed var(--line);
  border-radius: 6px;
  color: var(--muted);
  font-size: 11px;
  cursor: pointer;
}
.bt-toggle:hover { color: var(--fg); border-color: var(--muted); }

.bt-more { text-align: center; padding-top: 8px; color: var(--muted); font-size: 11px; line-height: 1.5; }

/* 백테스트가 어림값이라는 각주. ★ 숫자 **바로 아래**에 둔다 — 접어 두거나
   도움말로 밀면 읽지 않고, 그러면 이 성적표는 조용히 후한 숫자가 된다. */
.bt-approx {
  margin-top: 8px;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent-fg);
  border-radius: 6px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.6;
}

.cond-foot { flex: none; margin-top: 10px; }
.cond-foot button { width: 100%; margin: 0; justify-content: center; }
.cond-foot button:disabled { opacity: .4; cursor: not-allowed; }

/* 저장된 계획. 조건 칸 아래 절반을 차지한다 — 방금 만든 것과 이미 있는 것을
   같은 화면에서 봐야 "이거 아까 저장한 거랑 같은 거 아닌가" 를 알 수 있다.
   ★ 이름표도 개수도 버튼도 없이 **목록만** 있다. 화면에서 제일 좁은 자리라,
     머리에 한 줄을 두면 계획 한 줄이 그만큼 밀려 내려간다. 위의 '계획 수립'
     버튼과 가로줄이 여기가 무슨 칸인지 이미 말하고 있다. */
.cond-saved {
  flex: 1;
  min-height: 100px;
  display: flex;
  flex-direction: column;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
#saved-list { flex: 1; min-height: 0; overflow-y: auto; }
/* ★ 좁은 칸의 줄을 얇게. 요약 줄을 툴팁으로 내렸으니(ai.js presetHtml) 남는 것은
     이름 줄과 종목 줄 둘뿐인데, 여백이 세 줄짜리 그대로면 얇아진 값을 못 쓴다.
     검사·삭제 버튼은 **마우스를 올렸을 때만** 보인다 — 늘 보이면 그 두 버튼이
     이름보다 눈에 띄고, 좁은 칸에서는 폭까지 빼앗는다.
     ★ 넓은 창(계획 전체)에는 걸지 않는다. 거기서는 자리가 넉넉하고, 무엇보다
       손이 어디 있든 버튼이 보이는 편이 훑기 좋다. */
#saved-list .item {
  padding: 7px 9px;
  gap: 8px;
  position: relative;
}
#saved-list .item > span:last-child {
  opacity: 0;
  transition: opacity .12s ease;
}
#saved-list .item:hover > span:last-child,
#saved-list .item:focus-within > span:last-child { opacity: 1; }
/* 스위치가 맨 앞으로 오면서 :first-child 가 버튼이 됐다. 글 칸은 이제
   가운데라, .list 의 기본 규칙 대신 여기서 자리를 잡아 준다.

   ★★ 이 두 줄은 **반드시 중괄호로 닫는다.** 한때 여기 #all-list 짝이 함께
     적혀 있었는데(`…first-of-type, #all-list …first-of-type { … }`), '계획 전체'
     창을 걷어내며 짝만 지웠더니 **선택자 두 줄과 쉼표만 남았다.** CSS 파서는
     주석과 빈 줄을 건너뛰고 쉼표를 계속 읽으므로, 스무 줄 아래의
     .sw-money 규칙이 이 두 줄에 그대로 붙어 버렸다 — 계획 줄의 글 칸과
     버튼 칸이 통째로 초록(--ok)으로 칠해지고 초록 링까지 둘렸다.
     ★ 규칙을 지울 때는 **중괄호까지 한 덩어리로** 지운다. 선택자만 남으면
       CSS 는 오류를 내지 않고 다음 규칙을 삼킨다 — 조용히 틀린다. */
#saved-list .item > span:first-of-type { flex: 1; min-width: 0; overflow: hidden; }
#saved-list .item > span:last-child { flex: none; }
/* 이름 줄과 종목 줄은 **따로 선다.** 한 줄로 흐르면 "무엇을" 과 "어디서" 가
   붙어 읽힌다 (.list 기본은 인라인이다). 이것도 위와 같이 사라졌던 규칙이다. */
#saved-list .item b { display: block; }
#saved-list .item em { display: block; margin-top: 2px; line-height: 1.45; }
#saved-list .item em.bad { color: var(--err); }
/* 꺼 둔 것은 시안대로 조금 더 진하게 남긴다 (.list 기본은 .5). 목록에서 무엇을
   껐는지도 읽혀야 한다 — 지워진 것이 아니라 쉬고 있는 것이다. */
#saved-list .item.off { opacity: .55; }

/* ── 계획 줄의 스위치 둘 ────────────────────────────────────────
   왼쪽이 알림, 오른쪽이 매매다. 두 화면(AI 목록·감시 창)이 같은 부품을 쓴다
   (js/plan.js 의 planSwitches).

   ★ 매매 스위치에 **다른 색**을 준다. 알림만 나가는 것과 돈이 움직이는 것이
     똑같이 생겼으면, 켜는 손이 둘을 구분하지 못한다 — 스위치가 바로 옆에 있다.
     테두리 링까지 주는 이유: 색만으로 가르면 색을 못 가리는 눈에는 같은
     스위치 둘이 된다. */
.sw-money input:checked + span {
  background: var(--ok);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12), 0 0 0 2px rgba(38, 166, 154, .28);
}

/* 계획 줄에서는 스위치 둘이 붙어 선다. 사이를 조금 벌려 두 손잡이임을 드러낸다. */
.mon-rule-head .sw + .sw,
.list .item .sw + .sw { margin-left: 3px; }

/* 목록(.list .item) 안의 스위치. 전역 button/label 규칙에 눌리지 않게 못 박는다. */
.list .item > .sw { margin: 0; flex: none; }

.save-preview {
  margin: 10px 0 4px;
  padding: 10px 11px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--line);
  max-height: 210px;
  overflow-y: auto;
}
.sp-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px;
  padding-bottom: 7px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--line);
}

/* 갈아끼우기 경고. 되돌릴 수 없는 일이라 저장 버튼 바로 위에 둔다 —
   미리보기 위에 두면 조건을 읽는 동안 지나쳐 버린다. */
.save-over {
  margin: 8px 0 2px;
  padding: 9px 11px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--err) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--err) 35%, transparent);
}
.save-over b { display: block; font-size: 12px; color: var(--err); }
.save-over em { display: block; font-style: normal; font-size: 11px; color: var(--fg-dim); margin-top: 4px; }
.save-over i { font-style: normal; font-size: 10px; }
.save-over i.on {
  margin-left: 5px;
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--err);
  color: #fff;
}
.save-over > i { display: block; margin-top: 6px; font-size: 11px; color: var(--err); }

@media (max-width: 900px) {
  /* 좁으면 조건 칸을 아래로 내린다. 지워 버리면 무엇을 저장하는지 안 보인다.
     ★ 이 규칙은 칸이 둘이던 시절에 썼다. 대화 목록이 생겨 셋이 됐는데 행을
       둘만 정의해 두면 세 번째가 암묵 행으로 밀려나 배치가 무너진다.
       좁을 때는 목록을 숨긴다 — 목록은 길잡이지 본문이 아니다. */
  .ai-main { grid-template-columns: 1fr; grid-template-rows: 1fr auto; }
  #chats { display: none; }
  #cond { border-left: none; border-top: 1px solid var(--line); max-height: 46vh; }
}

/* 링크지만 버튼처럼 생긴 것. 헤더의 다른 버튼과 나란히 서야 한다. */
.btn-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 11px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
  color: var(--fg);
  text-decoration: none;
  white-space: nowrap;
}
.btn-link:hover { border-color: var(--accent-fg); color: #fff; }
.btn-link .ico { width: 17px; height: 17px; }

/* 검증 결과 안의 어긋남 표시. .warn 은 상자라 한 줄 안에서 쓸 수 없다. */
.hint b.bad, em.bad { color: var(--err); }
#ind-verify div { margin-top: 4px; font-variant-numeric: tabular-nums; }

/* 거절 표시. 말풍선 안에 섞으면 "안 된다" 는 말이 대화에 묻히고,
   사용자는 같은 말을 다르게 바꿔 가며 계속 시도하게 된다. */
.refuse-note {
  margin-top: 6px;
  padding: 6px 10px;
  border-left: 2px solid var(--err);
  background: rgba(239, 83, 80, .08);
  border-radius: 0 6px 6px 0;
  color: var(--fg-dim);
  font-size: 11.5px;
}
.refuse-note a { color: var(--accent-fg); }
/* 말풍선과 그 아래 붙는 것(거절 표시)을 한 덩이로 묶는다. 표식은 옆에
   그대로 두고 이 덩이만 세로로 쌓이게 하려는 것 — 묶지 않으면 표식이
   말풍선 위로 올라가 버린다. */
.bub-wrap { min-width: 0; }

/* 행동요령 */
/* ★ 도움말은 **세로 한 줄로 읽는 글**이다. .modal.wide 의 880px 를 그대로 쓰면
   한 줄이 너무 길어져 다음 줄 첫 글자를 찾느라 눈이 되돌아온다 — 그 폭은 설정
   창처럼 왼쪽 탭 + 오른쪽 본문으로 **가로를 쓰는** 창을 위한 값이다.
   여기 내용은 능력 목록·사전 모두 위에서 아래로 훑는 것이라 좁을수록 읽힌다.
   ★ 도움말**만** 좁힌다. .modal.wide 는 설정·백테스트·계획 전체가 같이 쓴다. */
#manual-pop .modal.wide { width: min(600px, 92vw); }

.manual-body { max-height: 62vh; overflow-y: auto; padding-right: 6px; }
.manual-body h3 { margin: 14px 0 8px; font-size: 12px; color: var(--muted); }
.manual-body h3:first-child { margin-top: 0; }

.m-row {
  padding: 9px 11px;
  margin-bottom: 6px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-left: 2px solid var(--ok);
}
.m-row.bad { border-left-color: var(--err); }
.m-row b { display: block; font-size: 12.5px; }
.m-row em, .m-row i {
  display: block;
  margin-top: 3px;
  font-style: normal;
  font-size: 11px;
  color: var(--muted);
}
.m-row i { color: var(--fg-dim); }

/* 캔들 말 사전. 능력 목록(.m-row)과 달리 **읽는 물건이 아니라 찾는 물건**이라
   한 줄에 이름·뜻·별칭을 나란히 두고 줄 높이를 낮춘다. 열한 줄이 한눈에
   들어와야 "아, 이렇게 말하면 되는구나" 가 된다. */
/* 계획 수립 창. 기본 300px 로는 "코스피 → 삼성전자" 한 줄이 접혀서 화살표가
   다음 줄로 내려가고, 그러면 어느 쪽이 보는 것이고 어느 쪽이 사는 것인지가
   안 보인다. 스크롤은 .modal 의 overflow-y 가 그대로 맡는다. */
.save-modal { width: min(520px, 94vw); }

/* 어디를 보고 · 무엇을 살지. 지수는 살 수 없으므로 둘을 한 칸에 둘 수 없다. */
.save-buy {
  padding: 11px;
  border-radius: 9px;
  background: var(--bg);
  border: 1px solid var(--line);
}
.sb-head b { display: block; font-size: 12.5px; font-weight: 600; }
.sb-head em {
  display: block;
  margin-top: 3px;
  font-style: normal;
  font-size: 11px;
  line-height: 1.5;
  color: var(--muted);
}
.sb-rows { display: flex; flex-direction: column; gap: 7px; margin-top: 9px; }

/* ── 주문 칸 ────────────────────────────────────────────────────────
   .save-buy 와 같은 상자 꼴을 쓴다. 저장 창 안에서 "따로 접히는 묶음" 은
   이 둘뿐이라, 생김새가 다르면 하나는 설정이고 하나는 딴 것처럼 보인다. */
.save-order {
  padding: 11px;
  border-radius: 9px;
  background: var(--bg);
  border: 1px solid var(--line);
}
/* 켜면 그때부터 주문이 붙는 스위치라, 켠 것이 한눈에 보여야 한다. */
.so-toggle { display: grid; grid-template-columns: auto 1fr; gap: 4px 8px; align-items: center; margin: 0; }
.so-toggle input { margin: 0; grid-row: span 2; }
.so-toggle b { font-size: 12.5px; font-weight: 600; }
.so-toggle em {
  grid-column: 2;
  font-style: normal;
  font-size: 11px;
  line-height: 1.5;
  color: var(--muted);
}
.so-body { display: flex; flex-direction: column; gap: 9px; margin-top: 11px; }
.so-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.so-label { font-size: 12px; color: var(--muted); min-width: 44px; }
.so-row .field { margin: 0; }
.so-row .field input { width: 88px; }
/* 비율의 분모가 매수와 매도에서 다르다("예수금 대비" vs "보유수량 대비").
   고른 순간 여기에 적어 둔다 — 나중에 목록만 보면 구분이 안 된다. */
.so-why { margin: 0; font-size: 11px; line-height: 1.55; color: var(--muted); }
.so-why b { color: var(--accent-fg); font-weight: 600; }
.so-limits { gap: 14px; }
.so-limits label { display: flex; align-items: center; gap: 6px; margin: 0; font-size: 12px; }
/* 지금 자물쇠가 어떤지. 켜 놓고 아무 일도 안 일어나는 이유가 여기 있다. */
.so-lock {
  margin: 0;
  padding: 8px 9px;
  border-radius: 7px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  font-size: 11px;
  line-height: 1.6;
  color: var(--muted);
}
.so-lock b { color: var(--fg); }
.so-lock b.on { color: var(--err); }
.so-lock code { font-size: 10.5px; color: var(--accent-fg); }
.so-lock:empty { display: none; }
/* 대상은 읽기 전용 알약, 매수는 고르개. 가운데 화살표가 방향을 말한다 —
   "이걸 보고 저걸 산다" 가 글자 없이 읽혀야 한다. */
.sb-row { display: grid; grid-template-columns: 1fr auto 1fr; gap: 8px; align-items: center; }
.sb-row .t-chip { justify-content: flex-start; overflow: hidden; }
.sb-arrow { width: 15px; height: 15px; flex: none; color: var(--dim); }
.sb-row select { width: 100%; margin: 0; padding: 6px 8px; font-size: 12px; }
/* 대상이 지수라 **반드시 골라야 하는** 줄. 안 고르면 저장이 막히므로 미리
   눈에 띄어야 한다 — 누르고 나서 막히는 것보다 낫다. */
.sb-row.must select { border-color: var(--accent-fg); }
/* 조건 카드 안의 '마감 전' 표시. **고르는 물건이 아니다** — 대화가 정한 것을
   보여 주기만 한다. 그래서 체크박스가 아니라 조건 문장 아래 딸린 한 줄이다. */
.c-live {
  margin-top: 8px;
  padding: 7px 9px;
  border-radius: 7px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
}
.c-live b { display: block; font-size: 11.5px; font-weight: 600; color: var(--accent-fg); }
.c-live em {
  display: block;
  margin-top: 2px;
  font-style: normal;
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--muted);
}
/* 목록에서 매수 종목이 대상과 다를 때만 뜬다. 눈에 걸려야 하는 줄이다. */
.buy-at { color: var(--accent-fg); font-weight: 600; }

/* 저장된 계획 목록의 '마감 전' 표. 이름 옆에 붙어야 켜고 끌 때 눈에 든다. */
.live-tag {
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 4px;
  font-style: normal;
  font-size: 10px;
  font-weight: 600;
  vertical-align: 1px;
  color: var(--accent-fg);
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
}

/* ── 수익률 백테스트 ────────────────────────────────────────────── */
.run-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.run-pick label { display: flex; align-items: center; gap: 7px; margin: 0; font-size: 12px; }
.run-pick select { flex: 1; min-width: 0; margin: 0; }
.run-when { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.run-when input[type="date"] { margin: 0; padding: 5px 7px; font-size: 12px; }
.run-when em { font-style: normal; color: var(--dim); }
/* 총 수익률은 이 창에서 제일 먼저 읽히는 숫자다. 나머지는 그것을 설명한다. */
.run-sum { padding: 12px; border-radius: 9px; background: var(--bg); border: 1px solid var(--line); }
/* ★ 네모 안에 갇히므로 넘치는 것은 **여기서** 받는다. 상자를 늘리면 옆 곡선까지
   같이 늘어나서(격자 한 줄이다) 정사각형이 깨진다. */
.bt-pair .run-sum { overflow-y: auto; }
.rs-big { font-size: 30px; font-weight: 700; letter-spacing: -0.5px; }
.rs-big.up, .rt .up, .rs-grid b.up { color: var(--ok); }
.rs-big.down, .rt .down, .rs-grid b.down { color: var(--err); }
.rs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 6px 14px;
  margin-top: 9px;
  font-size: 12px;
  color: var(--muted);
}
.rs-grid b { color: var(--fg); font-weight: 600; }
.rs-grid em { font-style: normal; font-size: 11px; color: var(--dim); }
.rs-open, .rs-none { margin: 9px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--muted); }
.rs-open b { color: var(--accent-fg); }

/* 무엇을 걸고 돌린 성적표인가. 숫자 아래에 붙어서 늘 함께 읽히게 한다 —
   위쪽 여백과 옅은 선으로 성적표와 갈라 놓되, 접거나 숨기지는 않는다.
   ★ 가정을 감춘 성적표는 성적표가 아니다. 한 번 접으면 다시는 안 편다. */
.rs-assume {
  margin: 10px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  font-size: 11px;
  line-height: 1.65;
  color: var(--muted);
}
.rs-assume em { font-style: normal; opacity: .82; }
.rs-assume .rs-skip { display: block; margin-top: 3px; color: var(--err); opacity: 1; }
/* 자리 목록. 길어질 수 있으니 스스로 스크롤한다 — 창이 늘어나면 차트가 밀린다. */
.run-list { max-height: 26vh; overflow-y: auto; }
.run-list:empty { display: none; }
.rt { width: 100%; border-collapse: collapse; font-size: 12px; }
.rt th {
  position: sticky;
  top: 0;
  padding: 5px 8px;
  text-align: left;
  font-weight: 600;
  color: var(--muted);
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
.rt td { padding: 5px 8px; border-bottom: 1px solid var(--line); }
.rt td:nth-child(2), .rt td:nth-child(4), .rt td:last-child { text-align: right; }
/* 아직 안 판 자리. 성적표에서 뺐다는 것이 목록에서도 보여야 한다. */
.rt tr.open td { color: var(--muted); font-style: italic; }

/* 주문이 붙은 계획. ★ '마감 전' 알약과 **다른 색**이어야 한다 — 저건 알림이
   되돌아갈 수 있다는 표시고 이건 돈이 움직인다는 표시다. 같은 색이면 켜는
   손이 둘을 구분하지 못한다. 매수는 오르는 색, 매도는 내리는 색을 쓴다. */
/* ★ 매매는 붙어 있는데 **알림이 꺼져 판정되지 않는** 계획. 색을 빼고 점선으로
   두른다 — 붙어 있다는 사실은 남기되 "지금 돈다" 로는 안 읽히게. */
/* 어느 계좌에 주문이 나가는가. 머리말에 늘 선다.
   ★ 실계좌일 때만 색을 쓴다 — 셋 다 눈에 띄게 하면 아무것도 안 띄는 것과 같다. */
.acct-badge {
  flex: none;
  margin-left: 8px;
  padding: 2px 7px;
  border-radius: 5px;
  font-size: 10.5px;
  font-weight: 600;
  white-space: nowrap;
}
.acct-badge.off, .acct-badge.paper {
  border: 1px solid var(--line);
  color: var(--dim);
}
.acct-badge.real {
  border: 1px solid var(--err);
  background: var(--err);
  color: #fff;
}

.order-tag.idle {
  border: 1px dashed var(--line-2);
  background: none;
  color: var(--dim);
}
/* 딱지의 숫자 중 일부만 실제로 도는 종목. 설명에 몇 개인지 적혀 있다. */
.pl-chip.money.half { border-style: dashed; }

.order-tag {
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 4px;
  font-style: normal;
  font-size: 10px;
  font-weight: 600;
  vertical-align: 1px;
  white-space: nowrap;
}
/* 주문이 안 붙은 계획. 매수/매도는 보여야 하지만 돈이 움직이지는 않으므로
   색을 빼고 테두리만 남긴다 — 눈이 색 있는 쪽으로 먼저 간다. */
.order-tag.off { color: var(--muted); border: 1px solid var(--line-2); }
.order-tag.buy { color: var(--ok); background: rgba(38, 166, 154, .12); border: 1px solid rgba(38, 166, 154, .35); }
.order-tag.sell { color: var(--err); background: rgba(239, 83, 80, .12); border: 1px solid rgba(239, 83, 80, .35); }

.m-lead { margin: -2px 0 8px; }
/* 사전 안의 갈래 머리말. h3(할 수 있는 일/못 하는 일)보다 한 단 작게 —
   같은 크기로 두면 '캔들 모양' 이 '못 하는 일' 과 같은 층으로 읽힌다. */
.manual-body .m-sub {
  margin: 10px 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--accent-fg);
}
.m-word {
  display: grid;
  grid-template-columns: 74px 1fr;
  gap: 2px 10px;
  padding: 7px 11px;
  margin-bottom: 4px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
}
.m-word b { grid-column: 1; grid-row: 1 / span 2; font-size: 12.5px; color: var(--accent-fg); }
.m-word span { grid-column: 2; font-size: 11.5px; color: var(--muted); }
.m-word em {
  grid-column: 2;
  font-style: normal;
  font-size: 11px;
  color: var(--fg-dim);
}

/* 조건 카드 안의 매수/매도 머리. 짝으로 만들었을 때만 붙는다 — 하나뿐이면
   카드도 하나라 굳이 이름표가 필요 없다. */
.c-side {
  display: inline-block;
  margin-bottom: 7px;
  padding: 2px 7px;
  border-radius: 5px;
  font-size: 11px;
  font-weight: 600;
}
.c-side.buy { color: var(--ok); background: rgba(38, 166, 154, .12); border: 1px solid rgba(38, 166, 154, .35); }
.c-side.sell { color: var(--err); background: rgba(239, 83, 80, .12); border: 1px solid rgba(239, 83, 80, .35); }
/* 고를 것이 없을 때 고르개 자리에 들어가는 글. */
.so-fixed { font-size: 12px; color: var(--muted); }

/* .modal.wide 안쪽의 스크롤 상자 (백테스트 창 · 계획 전체 창이 같이 쓴다).
   ★ .modal.wide 는 overflow:hidden 이고 "스크롤은 안쪽 본문이 맡는다" 가
   규약인데, 백테스트 창에는 그 상자가 없어서 차트 아래가 통째로 잘려 있었다.
   flex:1 과 min-height:0 이 둘 다 있어야 한다 — min-height 기본값 auto 가
   내용 높이를 바닥으로 잡아서, 그것만 빠져도 다시 삐져나온다. */
.run-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 11px;
}

/* 매수·매도 크기 칸. 짝이면 좌우로 나뉘고, 하나뿐이면 그쪽만 남는다.
   ★ 토글 뒤에 숨기지 않는다 — 얼마를 사고 팔지는 **계획을 세울 때** 정하는
     것이지 주문을 켤 때 정하는 것이 아니다. 스위치는 "실제로 낼지" 만 정한다. */
.so-sides { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; }
.so-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border-radius: 8px;
  background: var(--bg-2, var(--bg));
  border: 1px solid var(--line);
}
.so-col-head { font-size: 11.5px; font-weight: 700; }
.so-col-head.buy { color: var(--ok); }
.so-col-head.sell { color: var(--err); }
.so-col .seg button { padding: 4px 9px; font-size: 11.5px; }
/* ★ 76px 이었다. 다섯 자리(보유 상한 10000)가 들어가면 끝이 잘렸다 —
   금액 칸이 잘리는 것은 이 창에서 제일 나쁜 종류의 잘림이다. */
.so-col .field input { width: 92px; }
.so-limits { display: flex; flex-wrap: wrap; gap: 8px 12px; }
.so-limits label { display: flex; align-items: center; gap: 6px; margin: 0; font-size: 11.5px; color: var(--muted); }
.so-limits .field input { width: 76px; }

/* 고치는 창 머리 — 무엇을 고치는 중인지. */
/* 계획 수정 창의 머리 — **무엇에 대한 계획인가.**
   ★ 이 창은 목록에서 줄 하나를 눌러 여는데, 열고 나면 어느 계획이었는지가
     이름 칸의 짧은 글자뿐이었다. 계획 이름은 사람이 지은 것이라 종목이 안
     들어 있는 경우가 대부분이다 ('눌림 반등' · '채널 돌파'). */
.edit-what { margin: 0 0 12px; line-height: 1.55; }
.edit-sym {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.edit-sym .logo-sm { width: 24px; height: 24px; font-size: 11px; flex: none; }
.edit-what b {
  font-size: 16px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 티커는 이름 뒤에 작게. 이름이 '넷플릭스' 여도 주문 기록에는 NFLX 로 남는다. */
.edit-what i {
  font-style: normal;
  font-size: 11px;
  letter-spacing: .4px;
  color: var(--muted);
  flex: none;
}
/* ★★ **조건이 이 창에서 제일 읽어야 할 글이다.** 이름·크기·한도는 칸을 보면
   알지만, 조건은 여기 적힌 한 줄이 전부다 — 그런데 제일 작은 회색 글씨였다.
   키우고 색을 올리고, 여러 줄이면 줄바꿈을 살린다. */
.edit-what em {
  display: block;
  margin-top: 8px;
  padding: 9px 11px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  font-style: normal;
  font-size: 13px;
  line-height: 1.6;
  color: var(--fg-dim);
  white-space: pre-wrap;
  word-break: break-word;
}

/* 눌러서 여는 줄. 누를 수 있다는 것이 보여야 눌러 본다. */
.list .item.clickable { cursor: pointer; }
.list .item.clickable:hover { background: var(--accent-soft); }

/* 봉마다의 성적. 깃발에는 건수만 적고 숫자는 여기서 본다. */
.rd-head { margin-bottom: 5px; font-size: 11px; color: var(--muted); }

/* ── 단계 계획 ────────────────────────────────────────────────
   ★ 지금 서 있는 칸만 밝고 나머지는 흐리다. 사용자가 줄을 훑을 때 제일 먼저
     읽어야 하는 것이 "지금 어디" 라서, 색이 그 하나만 가리키게 둔다. */
.mon-stage .stage-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.stage-chain { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.stage-at { color: var(--ok); font-weight: 700; }
.stage-off { color: var(--dim); }
.stage-arrow { color: var(--line-2); }
.stage-doors { margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 2px; }
.stage-doors li { display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; }
.stage-do { color: var(--fg); font-weight: 600; white-space: nowrap; }
.stage-when { color: var(--fg-dim); min-width: 0; }
.stage-goto { color: var(--dim); white-space: nowrap; }
/* 주문이 막혀 칸을 못 옮겼을 때. 조용히 두면 "왜 아직 관망이지" 가 남는다. */
.stage-held { color: var(--accent-fg); }

/* ═══════════════════════════════════════════════════════════════
   계획 관리 (plans.html)

   ★ 감시 창과 **다른 화면**이다. 저쪽은 "지금 무슨 일이 일어나나" 라 좁고
     떠 있고 5초마다 다시 그린다. 여기는 "무엇을 갖고 있나" 라 넓고 가만히
     있는다 — 목록을 훑으며 여럿 고르는 일이 벌어지는 자리다.
   ═══════════════════════════════════════════════════════════════ */

.plans-main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 14px 18px 18px;
  gap: 12px;
}

/* 머리말의 검색칸. 계획이 백 개가 되면 제일 먼저 손이 가는 곳이라 머리에 둔다. */
.pl-search {
  display: flex;
  align-items: center;
  gap: 7px;
  flex: 0 1 320px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--bg);
}
.pl-search:focus-within { border-color: var(--accent); }
.pl-search .ico { width: 15px; height: 15px; color: var(--dim); }
.pl-search input {
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 7px 0;
  border: none;
  background: none;
  font-size: 12px;
}
.pl-search input:focus { outline: none; }

/* ── 거르개 줄 ─────────────────────────────────────────────── */
.pl-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
}
.pl-filter { display: flex; align-items: center; gap: 7px; }
.pl-lab { color: var(--muted); font-size: 11px; white-space: nowrap; }
.pl-bar .seg button { padding: 5px 10px; font-size: 11.5px; }
.pl-sel {
  /* 펼침 메뉴가 이 칸에 매달린다 (#pl-menu). */
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  color: var(--muted);
  font-size: 11px;
  white-space: nowrap;
}
/* ★ 고르개 칸의 알맹이. **정렬(select)과 전체 선택(button)이 같은 규칙**을
     쓴다 — 나란히 선 두 칸이 다른 크기면 하나가 다른 종류처럼 보인다. */
.pl-sel select,
.pl-sel button { width: auto; margin: 0; padding: 5px 7px; font-size: 11.5px; }
.pl-sel.hidden { display: none; }
/* 켜졌을 때는 **테두리로** 말한다. 채워 버리면 옆의 상태·방향 토글에서 고른
   조각과 같은 무게가 되어, 무엇이 골라져 있는지가 오히려 흐려진다. */
.pl-sel button.on {
  border-color: var(--accent-fg);
  color: var(--accent-fg);
}

/* ── 목록 ───────────────────────────────────────────────────────
   ★ 한 줄에 하나씩 **가로로 길게** 늘어놓았더니, 넓은 화면에서 줄 하나가
     1400px 를 차지하고 오른쪽 3분의 2가 비었다. 정작 알아야 할 것(이름·종목·
     숫자)은 왼쪽 400px 안에 다 들어 있는데, 눈은 그 빈 곳을 가로질러 오간다.

   ★ 그래서 **칸을 나눈다.** auto-fill + minmax 라 폭이 정한다 —
     ~1100px 이상 세 칸, ~740px 이상 두 칸, 좁으면 한 칸. 숫자를 화면 크기별로
     못 박지 않는 이유: 창을 반으로 줄여 쓰는 일이 잦고, 그때 세 칸이 억지로
     남아 있으면 글자가 서로 밟는다.

   ★ 최소 폭 340px 는 **줄 하나가 안 깨지는 폭**에서 나왔다. 이름 + 매매 딱지가
     한 줄에 서고, 요약이 한 줄로 잘려도 무슨 조건인지 읽히는 최소치다. */
.pl-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
  display: grid;
  /* ★ **세 칸을 넘지 않는다.** 그냥 minmax(340px, 1fr) 로 두면 1920 화면에서
       다섯 칸이 되고, 그러면 칸마다 이름과 숫자만 남아 무엇을 걸어 둔
       계획인지를 줄에서 못 읽는다. 사람이 한 번에 훑는 폭에도 끝이 있다.
     max(340px, …/3) 하나로 양쪽을 동시에 묶는다 — **340px 보다 좁지도, 세 칸보다
     많지도 않게.** 미디어 쿼리로 나누면 칸 수를 정하는 곳이 둘이 되고,
     둘은 언젠가 어긋난다.

       1920 → 3칸 (615px)   1440 → 3칸 (455px)   1280 → 3칸 (401px)
       1024 → 2칸 (481px)    800 → 2칸 (369px)    700 → 1칸 (652px)  */
  /* ★ 28px(= 틈 둘)이 아니라 **32px** 을 물린다. 딱 28 이면 세 칸이 정확히
     경계에 놓이게 되어, 마지막 자릿수를 반올림하는 방향에 따라 세 칸이다
     두 칸이다 한다 — 1440px 에서 실제로 두 칸으로 떨어졌다. 4px 을 남긴다. */
  grid-template-columns: repeat(auto-fill, minmax(max(340px, (100% - 32px) / 3), 1fr));
  gap: 14px;
  /* 묶음마다 계획 수가 다르다. stretch 면 짧은 칸이 긴 칸 높이만큼 늘어나
     빈 상자가 된다. */
  align-items: start;
}
/* 안내문은 **칸 하나에 끼면 안 된다.** 3분의 1 폭에 갇힌 안내문은 고장으로
   보인다 — 목록이 비었다는 말이 목록보다 어색하게 생기면 안 된다. */
.pl-list > .cond-empty { grid-column: 1 / -1; }

/* 묶음 하나가 곧 카드 하나. 칸이 나란히 서면 경계가 있어야 어디까지가 한
   종목인지 읽힌다 — 여백만으로는 두 칸이 한 덩어리로 보인다. */
.pl-group {
  padding: 10px 11px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
  min-width: 0;
}
.pl-group-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: -10px -11px 8px;
  padding: 9px 11px 7px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  color: var(--fg-dim);
}
/* ★ 머리에는 **이름 하나**만 선다(종목별이면 로고가 앞에). 개수와
     '묶음 고르기' 버튼을 걷어냈다 — 카드 폭이 340px 까지 좁아지는데
     머리 하나에 셋이 서 있으면 정작 종목 이름이 줍어든다.
   이름은 길면 자른다 — 카드 머리가 두 줄로 불어나면 칸마다 높이가 어긋난다. */
.pl-group-head b {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12.5px;
  color: var(--fg);
}
.pl-group-head > .logo { flex: none; }

/* ── 종목 머리의 손잡이 셋 — 알림 · 매수 · 매도 ────────────────────
   ★ 위 주석이 "머리에는 이름 하나만" 이라고 적어 둔 것을 도로 붙이는 것이
     아니다. 그때 걷어낸 것은 **버튼과 개수가 따로** 서서 셋이 되던 모양이고,
     이건 **딱지가 곧 숫자**다 — "알림 3/5" 하나가 상태와 손잡이를 겸한다.
   ★ 이름은 줄어들되(min-width:0 + ellipsis) 딱지는 안 줄어든다(flex:none).
     그래서 카드가 340px 이 돼도 손잡이가 먼저 잘리지 않는다. */
.pl-syms {
  display: flex;
  flex: none;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}
.pl-chip {
  flex: none;
  width: auto;
  margin: 0;
  padding: 2px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--muted);
  font-size: 10.5px;
  font-style: normal;
  line-height: 1.45;
  white-space: nowrap;
}
button.pl-chip:hover { border-color: var(--line-2); color: var(--fg); }
/* 알림이 하나라도 켜져 있으면 또렷하게. 훑을 때 "이 종목은 돌고 있다" 가
   보여야 한다. */
.pl-chip.on { border-color: var(--accent-line); color: var(--accent-fg); }
/* ★ 주문이 붙어 있는 칸은 **돈 색**이다 (.order-tag 와 같은 뜻). 이 딱지를
   누르면 떼어지므로, 눈에 걸려야 하는 쪽이 맞다. */
.pl-chip.money.buy { border-color: var(--ok); color: var(--ok); }
.pl-chip.money.sell { border-color: var(--err); color: var(--err); }
/* ★ 붙은 것이 없으면 **안 눌린다.** 누를 수 있는데 아무 일도 안 일어나는
   버튼은 고장으로 읽힌다 — 그래서 button 이 아니라 span 으로 그린다
   (plans.js 의 symbolHandles). */
.pl-chip.off { opacity: .4; }

/* ★ 묶음 손잡이는 **'한 번에 세운 것' 으로 묶을 때만** 뜬다 (plans.js).
     위 주석이 걷어낸 것을 도로 붙이는 것이 아니다 — 종목 머리는 그대로 이름
     하나이고, 이 줄은 "일곱 개짜리 전략 하나" 를 다루는 다른 머리다.
   ★ 평소에는 개수만 또렷하고 버튼은 흐리다. 한 번에 일곱을 끄는 버튼이
     늘 도드라져 있으면 훑어 내리다 누른다. */
.pl-batch {
  display: flex;
  flex: none;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
.pl-batch em { font-style: normal; white-space: nowrap; }

/* ★ **사면 나올 길이 없다**는 표시 (plan.js 의 noExitMark). 기호 하나이고
     설명은 마우스를 대면 나온다 — 이 줄이 답할 것은 조건과 거리이고 이건
     곁가지다. 크게 그리면 정작 그 둘을 밀어낸다.
   ★ 그래도 흐리게 두지는 않는다. 못 사는 것보다 **못 나오는 것**이 훨씬
     위험한데, 지금은 그 사실이 화면 어디에도 안 뜬다. */
.no-exit {
  flex: none;
  margin-left: 4px;
  font-size: 11px;
  font-style: normal;
  line-height: 1;
  /* 알림 뱃지의 '주의' 와 **같은 색**이다 (.notice-dot.lv-warn). 새 색을
     들이면 팔레트에 뜻이 하나 더 늘고, 같은 무게의 경고가 두 색으로 갈린다. */
  color: var(--accent-fg);
  cursor: help;
}
.pl-batch button {
  width: auto;
  margin: 0;
  padding: 2px 7px;
  opacity: .45;
  font-size: 11px;
  line-height: 1.2;
  white-space: nowrap;
}
.pl-group:hover .pl-batch button { opacity: 1; }
/* 묶음 머리는 목록을 밀고 올라오면 안 된다 — 훑어 내릴 때 어느 묶음인지가
   화면에 계속 남아 있어야 한다. 카드 안쪽 여백만큼 음수 margin 으로 빼서,
   붙박혔을 때 카드 폭을 꽉 채우게 한다.
   ★ --panel 이 아니라 **--panel-solid** 를 쓴다. 유리색은 반투명이라,
     붙박힌 머리 뒤로 줄들이 비치며 지나간다 — 읽을 것이 많은데 뒤가 움직이는
     자리에서는 반투명이 멋이 아니라 방해다(팔레트 주석이 적어 둔 그대로). */
.pl-group-head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--panel-solid);
  border-radius: 8px 8px 0 0;
}

/* ── 줄 하나 ─────────────────────────────────────────────────────
   ★ 칸이 좁아졌으니 **두 층으로 접는다.** 예전에는 옆으로 한 줄이었는데
     (체크·스위치·글·숫자·X), 340px 안에서 그러면 숫자가 글자를 밀어내고
     이름이 세 글자만 남는다. 숫자는 아래로 내리고 글에 폭을 준다.

       sw   text  x      ← X 는 상자 오른쪽 **위**
       sw   meta meta    ← 숫자는 글 아래

   ★ 체크상자를 걷어냈다. 일괄로 고르는 길이 없어졌으니 자리를 차지할 이유도
     없다 — 그 폭이 그대로 이름에 간다. */
/* ★★ 고른 것으로 할 일 — **겹쳐 뜨는 작은 메뉴.**
   예전에는 목록 위에 줄이 하나 더 생겼는데(.pl-bulk), 그것이 40px 을 먹어서
   고르는 동안 내내 계획이 덜 보였다. 고르는 이유가 계획을 보려는 것인데
   고르는 순간 덜 보이는 셈이었다. 겹쳐 뜨면 자리를 안 먹는다. */
.pl-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 150px;
  padding: 5px;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  background: var(--panel-solid);
  box-shadow: 0 10px 24px rgba(0, 0, 0, .45);
}
.pl-menu.hidden { display: none; }
.pl-menu button {
  width: 100%;
  margin: 0;
  padding: 7px 9px;
  border-color: transparent;
  background: none;
  text-align: left;
  font-size: 12px;
}
.pl-menu button:hover { background: var(--accent-soft); border-color: transparent; }
/* 되돌릴 수 없는 것 하나만 색으로 갈라 둔다. 그 위에 가르는 줄도 긋는다. */
.pl-menu button.danger { margin-top: 3px; border-top: 1px solid var(--line); border-radius: 0; }

.pl-pick { grid-area: pick; display: flex; align-items: center; padding: 0 2px; }
.pl-pick input { margin: 0; cursor: pointer; }

.pl-row {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  grid-template-areas:
    "pick sw text x"
    "pick sw meta meta";
  align-items: center;
  gap: 2px 10px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--bg);
  cursor: pointer;
}
/* 묶음 안에서는 줄 사이를 직접 벌린다 (격자 gap 은 카드 사이에만 걸린다).
   '안 묶기' 로 보면 줄 자체가 격자의 칸이 되므로 그때는 필요 없다. */
.pl-group .pl-row { margin-bottom: 5px; }
.pl-group .pl-row:last-child { margin-bottom: 0; }

.pl-row:hover { background: var(--accent-soft); }
/* 고른 줄. 테두리로 표시한다 — 배경으로 하면 hover 와 구분이 안 된다. */
/* ★ 고른 줄. **테두리로만** 말한다 — 배경까지 칠하면 스무 줄을 골랐을 때
     목록이 통째로 한 덩어리가 되어 줄이 안 갈린다.
   ★ 색은 강조 글자색(--accent-fg)이다. 채움색(--accent)은 어두운 바탕에서
     테두리로 쓰면 거의 안 보였다 — 골라 놓고도 골랐는지 몰랐다. */
.pl-row.picked {
  border-color: var(--accent-fg);
  box-shadow: 0 0 0 2px var(--accent-soft);
}
/* 꺼 둔 것은 흐리게만. 지워진 것이 아니라 쉬고 있는 것이다. */
.pl-row.off { opacity: .55; }
.pl-row.off:hover { opacity: .85; }
/* 조건이 깨진 줄. 켤 수 없는 줄이라 목록에서 바로 보여야 한다. */
.pl-row.broken { border-color: rgba(239, 83, 80, .5); }

/* ── 스위치 둘 · 이름표 ──────────────────────────────────────────
   ★ 스위치 **위에** 무엇인지 적는다 (plan.js 의 planSwitches 가 labeled 로).
     감시 창은 줄마다 "조건이 맞으면 매수 주문을 냅니다" 를 글로 적어서 둘을
     가르는데, 이 화면에는 그 글줄이 없다 — 이름표가 그 일을 한다.
   ★ 매매 쪽 이름표는 계획을 따라간다. 파는 계획에 '매수' 라고 적혀 있으면
     그건 그냥 거짓말이다. */
.pl-sw {
  grid-area: sw;
  align-self: center;
  display: flex;
  gap: 8px;
}
.sw-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.sw-col em {
  font-style: normal;
  font-size: 9.5px;
  line-height: 1;
  color: var(--muted);
  white-space: nowrap;
}
/* 돈이 걸린 쪽 이름표는 조금 더 또렷하게. 이름표까지 같은 회색이면, 색을 준
   스위치가 무엇을 뜻하는지 글자 쪽에서 되받아 주지 못한다. */
.sw-col:last-child em { color: var(--fg-dim); }

.pl-text { grid-area: text; min-width: 0; }
.pl-text b { display: flex; align-items: center; gap: 6px; font-size: 12.5px; min-width: 0; }
/* ★ 길면 **이름을** 자른다. 딱지(매수 $100 · 단계)는 안 자른다 — 잘린
     금액은 읽는 사람을 속인다("$1,0…"). 이름은 잘려도 누를 수 있다. */
.pl-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-text b .order-tag, .pl-text b .pl-stage { flex: none; }
/* ★ flex 가 아니라 **block** 이다. 로고 뒤에 오는 것이 맨 텍스트라, flex 로
     두면 그 익명 칸에는 말줄임을 못 건다 — 그냥 잘려 나간다.
     .logo 는 이미 inline-flex 라 줄 안에 그대로 선다. */
.pl-text em {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  font-style: normal;
  font-size: 11px;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pl-text em > .logo { vertical-align: -3px; margin-right: 4px; }
/* 요약은 길다. 위에서 이미 한 줄로 자른다 — 줄 높이가 들쭉날쭉하면 훑기가 나빠진다. */
.pl-sum { color: var(--dim); }
.pl-text em.bad { color: var(--err); white-space: normal; }
/* 못 켜는 줄이라는 딱지. 이름 바로 옆에 선다.
   ★ '문제 있는 것만' 체크상자를 대신하는 표시다 — 걸러내는 칸이 필요했던 것은
     표시가 약했기 때문이지 계획이 많아서가 아니었다. 까닭은 줄 아래에 그대로
     있고(em.bad), 이 딱지는 **훑을 때 걸리라고** 있는 것이라 색을 채운다.
   ★ 색은 오류색 하나를 그대로 쓴다. 붉은 테두리(.pl-row.broken)와 같은 뜻이라
     새 색을 들이면 같은 무게의 경고가 두 색으로 갈린다. */
.pl-bad {
  flex: none;
  margin-left: 5px;
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
  line-height: 1.5;
  color: var(--err);
  background: rgba(239, 83, 80, .14);
}

/* 숫자들. ★ 한 번도 안 울린 계획을 가려내는 것이 이 화면의 핵심이라
   줄마다 적는다 — 지울지 고칠지가 그 숫자 하나로 정해진다.
   좁은 칸에서는 옆이 아니라 **아래**에 선다 (위 grid-template-areas). */
.pl-meta {
  grid-area: meta;
  display: flex;
  gap: 10px;
  color: var(--dim);
  font-size: 10.5px;
  white-space: nowrap;
  overflow: hidden;
}

/* 치우기 · 지우기 — 상자 **오른쪽 위**.
   ★ align-self: start 로 첫 층 꼭대기에 붙인다. center 로 두면 두 층의 한가운데,
     즉 이름과 숫자 사이에 떠서 어느 쪽에 걸린 버튼인지 흐려진다.
   ★ 평소에는 흐리게. 늘 또렷하면 치우고 지우는 버튼이 켜고 끄는 스위치보다
     눈에 띈다.
   ★ 보관이 왼쪽, 지우기가 오른쪽이다. 되돌릴 수 있는 것이 먼저 손에 닿아야 한다. */
.pl-act {
  grid-area: x;
  align-self: start;
  display: flex;
  align-items: center;
  gap: 4px;
}
.pl-x,
.pl-put {
  width: auto;
  margin: 0;
  padding: 1px 6px;
  opacity: .3;
  font-size: 13px;
  line-height: 1.2;
}
.pl-put { font-size: 11px; padding: 2px 7px; }
.pl-row:hover .pl-x,
.pl-row:hover .pl-put { opacity: 1; }

/* 단계 계획이 지금 서 있는 칸. */
.pl-stage {
  padding: 1px 7px;
  border-radius: 9px;
  border: 1px solid var(--line-2);
  color: var(--ok);
  font-style: normal;
  font-size: 10px;
  font-weight: 700;
}

/* 목록 줄에 들어가는 제일 작은 표식. */
.logo-xs { width: 14px; height: 14px; font-size: 8px; flex: none; }

/* 감시 창 맨 아래의 '꺼진 계획 n개' 줄.
   ★ 링크지만 경고처럼 생기지 않게 한다. 꺼 둔 것은 잘못이 아니다 — 그저
     여기 없을 뿐이고, 어디 있는지만 알려 주면 된다. */
.mon-off-line {
  display: block;
  margin: 6px 0 2px;
  padding: 6px 10px;
  border-radius: 6px;
  border: 1px dashed var(--line);
  color: var(--muted);
  font-size: 10.5px;
  text-align: center;
  text-decoration: none;
}
.mon-off-line:hover { color: var(--fg); border-color: var(--line-2); }

/* 좀은 화면. 칸 수는 여기서 안 정한다 — 위의 auto-fill 이 폭을 보고
   알아서 한 칸으로 내려준다. 여기서 다시 정하면 둘이 어긋나는 날이 온다.
   ★ 숫자를 더 이상 숨기지 **않는다.** 예전에는 줄 오른쪽에 붙어 있어
     좀아지면 이름을 밀어냈는데, 이젠 아랫줄에 서므로 자리를 안 다투다.
     '한 번도 안 울렸다' 는 이 화면의 핵심 정보라 지울 자리가 아니다. */
@media (max-width: 900px) {
  .plans-main { padding: 10px; }
  .pl-bar { gap: 9px; }
}

/* ── 알림 ───────────────────────────────────────────────────────
   웹훅마다 '무엇을 받을지' 묶음 셋. 낱개 이벤트로 고르게 하면 웹훅 하나에
   체크박스가 열 개가 된다 — 사람이 나누고 싶어 하는 선은 셋이다. */
.wh-evs { display: flex; gap: 10px; margin-top: 5px; flex-wrap: wrap; }
.wh-ev {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  color: var(--muted);
  font-size: 10.5px;
  white-space: nowrap;
  cursor: pointer;
}
.wh-ev input { width: auto; margin: 0; }
.wh-item > span:first-child { min-width: 0; }

/* ── 알림 종 ────────────────────────────────────────────────────
   ★ 뱃지 색이 **제일 나쁜 것을 따라간다.** 체결 3건과 전면 정지 1건은 같은
     '3' 이 아니다 — 숫자만 보면 "나중에 보지" 가 되고, 그 나중이 장중일 수 있다. */
/* ★ 종은 옆에 선 버튼들과 **키가 같아야 한다.** 아이콘 하나만 들어 있어서 글자가
     든 버튼(감시 현황 · 계획 관리)보다 낮게 서 있었다 — 한 줄에 선 것들의 아랫변이
     안 맞으면 머리말이 정돈돼 보이지 않는다. .btn-link 와 같은 여백(7px 11px)을
     쓰고, 가운데 정렬로 아이콘을 세운다. 뱃지를 얹으려고 기준점도 함께 준다. */
[data-notice-bell] {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 7px 11px;
  margin: 0;
}

/* ★ 떠 있는 창을 여는 버튼은 **열려 있는 동안 눌린 티**를 낸다.
     창을 끌어 화면 구석으로 치워 두면 버튼만 보고는 열렸는지 모른다 — 그러면
     같은 버튼을 또 눌러 엉뚱하게 닫게 된다.
     종과 감시 현황이 **같은 규칙**을 따른다 (notices.js · monitor.js). */
header button.on {
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: var(--accent-fg);
}
header button.on:hover { background: var(--accent-soft); border-color: var(--accent-fg); }
.notice-dot {
  position: absolute;
  top: 1px;
  right: 1px;
  min-width: 15px;
  height: 15px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--accent);
  color: #fff;
  font-style: normal;
  font-size: 9.5px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
  pointer-events: none;
}
.notice-dot.lv-warn { background: var(--accent-fg); color: #1a0f0c; }
.notice-dot.lv-error { background: var(--err); }
.notice-dot.hidden { display: none; }

/* ── 알림 · 감시 현황 (한 상자 · 한 창) ─────────────────────────
   ★ 예전에는 **떠 있는 창이 둘**이었다. 둘 다 오른쪽 위에 뜨고 폭도 같아서
     자리를 다퉜다 — 둘 다 열면 겹쳐서 서로를 가렸고, 하나를 끔어 치우면
     다음에 다른 하나가 그 밑에서 열렸다. 지금은 한 창의 두 칸이다
     (js/deck.js 머리말에 이유가 적혀 있다). */

/* 머리말의 상자. 종과 눈이 한 칸에 선다 — 같은 창을 여는 두 문이라는 것이
   생김새로 보여야 한다. 주기 고르는 칸과 같은 부품(.seg)을 쓴다. */
.deck-box { padding: 2px; gap: 0; }
.deck-box button {
  position: relative;      /* 뱃지를 얹을 기준점 */
  display: inline-flex;
  align-items: center;
  margin: 0;
  padding: 5px 9px;
  border: none;
  background: none;
  border-radius: 4px;
  color: var(--muted);
}
.deck-box button .ico { width: 17px; height: 17px; stroke-width: 1.8; }
/* 칸이 하나뿐인 화면(계획 관리)에서는 좌우를 조인다.
   ★ 단추가 둘일 때 9px 은 **둘 사이를 가르는** 여백이다. 하나뿐이면 가를 것이
     없어서 그냥 빈 자리로 남고, 옆의 설정(톱니)은 정사각인데 이쪽만 넓어서
     나란히 선 두 상자가 다른 부품으로 보인다. 5px 로 조이면 33×33 으로
     톱니와 **똑같은 정사각**이 된다 (키 계산은 #settings-toggle 주석 참고). */
.deck-box.solo button { padding: 5px; }
.deck-box button:hover { background: rgba(255, 255, 255, .06); color: var(--fg); }
/* 지금 보고 있는 칸. 창을 끔어 구석에 치워 두면 버튼만 보고는 무엇이 열려
   있는지 알 수 없다 — 이 표시가 그 답이다. */
.deck-box button.on {
  background: var(--accent-soft);
  color: var(--accent-fg);
}

/* 창 머리의 탭. 칸이 하나뿐인 화면에서는 아예 안 그린다 (js/deck.js).

   ★★ **width/height 를 되돌려야 한다.** 이 탭은 .float-head 안에 있는데,
      그 안의 버튼은 새로고침·닫기 같은 **아이콘 버튼**이라 26px 정사각으로
      묶여 있다(.float-head button). 그대로 두면 탭이 26px 상자가 되고 글자가
      세로로 한 자씩 접힌다 — 실제로 그렇게 나왔다. 여백만 덮어써서는 안 되고
      크기 자체를 풀어 줘야 한다. */
.deck-tabs { padding: 2px; flex: none; }
.deck-tabs button {
  width: auto;
  height: auto;
  padding: 5px 12px;
  font-size: 11.5px;
  /* 글자가 접히면 다시 세로가 된다. 탭 이름은 짧으니 접을 이유가 없다. */
  white-space: nowrap;
}

.deck { width: 380px; max-height: 66vh; top: 60px; right: 16px; }
/* 빼는 것은 머리말뿐이다. 묶음 탭이 여기 있었는데(그만큼 96px 이었다) 걷어냈다 —
   같은 묶음 셋이 설정의 웹훅에 이미 있어서, 생김새가 같고 뜻이 다른 칸이 둘이었다.
   고르는 자리는 설정 하나다 (js/notices.js 머리말에 이유가 적혀 있다).
   ★ 탭이 서면 머리가 조금 높아진다. 탭 줄은 .float-head 안에 있으므로 그
     높이는 여기 한 값으로 흡수된다 — 칸마다 따로 재지 않는다. */
.deck .float-body { max-height: calc(66vh - 62px); }

/* 알림 한 줄.
   ★ 세기를 **왼쪽 띠**로 준다. 글자색만 바꾸면 훑을 때 안 걸린다 — 이 창은
     "뭔가 잘못됐나" 를 확인하러 여는 자리라, 나쁜 것이 먼저 눈에 와야 한다. */
.notice {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  margin-bottom: 5px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-2);
  border-radius: 6px;
  background: var(--bg);
  font-size: 11.5px;
}
.notice > span:first-child { min-width: 0; }
.notice.lv-warn { border-left-color: var(--accent-fg); }
.notice.lv-error { border-left-color: var(--err); }

/* ★ 왼쪽 색 바가 **무슨 일이 일어났는지**를 말한다. 제목만으로는
   '냈습니다'·'체결됐습니다'·'막혔습니다' 가 다 비슷하게 생겨서, 목록을 훑을 때
   정작 읽어야 할 그 차이가 안 읽힌다.

       매수 체결  초록   실제로 샀다
       매도 체결  빨강   실제로 팔았다
       주문 냈다  강조색 아직 아무 일도 안 일어났다

   ★ 초록=좋음 / 빨강=나쁨이 **아니다.** 매수·매도를 가르는 것이고 차트의
     양봉·음봉과 같은 규약이다 — 그래서 손절 체결도 빨강이다. 판 것이니까.
   ★ 세기(lv-*)보다 뒤에 둬서 이긴다. 체결은 info 라 어차피 안 부딪히지만,
     순서가 곧 규칙이라는 것이 코드에 보여야 한다. */
.notice.did-buy { border-left-color: var(--ok); }
.notice.did-sell { border-left-color: var(--err); }
.notice.did-place { border-left-color: var(--accent); }
/* 체결은 굵게 — 실제로 돈이 움직인 줄이다. */
.notice.did-buy, .notice.did-sell { border-left-width: 4px; }
/* 방금 온 것. 숫자만 지우고 목록이 똑같으면 무엇을 봤는지 알 수 없다. */
.notice.fresh { background: var(--accent-soft); }
/* 제목줄 — 로고 + 종목 이름 + 무슨 일. 예전에는 '주문이 체결됐습니다' 만 있고
   종목은 아래 회색 잔글씨였다 — 제일 먼저 알고 싶은 것이 제일 작았다. */
.notice b { display: block; font-size: 12px; }
.notice-head {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.notice-head .logo-sm { width: 18px; height: 18px; font-size: 9px; flex: none; }
.notice-sym {
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 무슨 일이 있었는지는 종목 뒤에 작게. 색 바가 이미 절반을 말했다. */
.notice-what {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
  flex: none;
}

/* ★ 값줄은 이 창에서 **제일 크게** 적는다. "얼마에 샀나" 가 이 알림을 여는
     이유이기 때문이다. 숫자는 tabular-nums 로 자리를 고정해 세로로 훑힌다. */
.notice-money {
  display: flex !important;
  align-items: baseline;
  gap: 6px;
  margin-top: 5px !important;
  color: var(--fg-dim) !important;
  font-size: 11px !important;
}
.notice-money b {
  display: inline !important;
  font-size: 15px !important;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.notice.did-buy .notice-money b { color: var(--ok); }
.notice.did-sell .notice-money b { color: var(--err); }
.notice em {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  font-style: normal;
  font-size: 11px;
  /* 이유가 여러 줄인 알림이 있다 (막힌 까닭 · 계획 이름). 줄바꿈을 살린다. */
  white-space: pre-wrap;
  word-break: break-word;
}
.notice .notice-when { color: var(--dim); font-size: 10px; }
.notice > span:last-child { flex: none; font-size: 10px; }

/* ── 페이지 바 ──────────────────────────────────────────────────
   세 화면을 오가는 문. 예전에는 페이지마다 다른 데 있었고(차트는 왼쪽 위,
   나머지는 오른쪽 위) 이름도 갈렸다 — js/nav.js 머리말에 그 표가 있다.

   ★ **떠 있지 않고 칸을 차지한다.** body 가 세로 flex 라 본문이 그만큼 줄
     뿐, 무엇도 안 덮는다. 떠 있게 하면 차트의 시간축과 계획 목록의 마지막
     줄을 가리고, 그걸 피하려면 페이지마다 여백을 따로 넣어야 하는데 그
     여백은 한 페이지만 빠뜨려도 눈으로 볼 때까지 모른다.

   ★ **얇아야 한다.** 세 화면 전부에서 세로를 영구히 한 줄 뺏는 것이고,
     제일 아쉬운 곳이 차트다. 아이콘 15px · 글자 12px 로 38px 에 맞춘다. */
.pagebar {
  display: flex;
  flex: none;
  /* ★ stretch 가 아니라 **가운데**다. 칸이 막대 높이를 꽉 채우면 표의 셀처럼
     보인다 — 안쪽에 여백을 두고 알약을 앉히면 같은 자리가 훨씬 가볍다.
     ★ 가로도 **가운데로 모은다.** 아래는 flex:1 을 걷어 낸 이유다. */
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 12px;
  border-top: 1px solid var(--line);
  background: var(--panel);
  /* 머리말(z-index:5)과 같은 층. 떠 있는 창(.float 는 150)보다는 아래라
     끌어다 놓은 감시 창이 막대를 덮는다 — 그쪽이 맞다, 창은 지금 보는 것이다. */
  position: relative;
  z-index: 5;
}

/* ★ 셋이 **똑같은 폭**을 갖는다. 글자 길이대로 두면 'AI 계획수립' 칸만 넓어지고,
     넷째 페이지가 생기는 날 폭이 통째로 다시 흔들린다.
   ★★ 다만 flex:1 은 **아니다.** 그러면 화면 전체로 늘어나서, 1900px 짜리
      모니터에서는 칸 하나가 600px 을 차지한다 — 글자 넷과 아이콘 하나를 담는 데
      그만한 자리가 필요하지 않고, 그렇게 벌어지면 막대가 '표' 로 보인다.
      기준 폭을 주고(0 1 168px) 좁아지면 줄어들게 둔다. 셋이 같은 폭인 것은
      그대로이고, 넓은 화면에서는 가운데 모여 선다. */
.pagebar-item {
  display: flex;
  flex: 0 1 168px;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 0;
  padding: 8px 12px;
  /* ★ 칸 사이의 **세로 금을 걷었다.** 금을 그으면 셋이 한 덩어리가 아니라
     칸막이 친 표로 읽힌다. 사이는 gap 이 벌리고, 무엇이 눌렸는지는 알약이
     말한다 — 금은 그 둘을 다 시킨 뒤에도 남아 있던 군더더기였다. */
  border: none;
  /* 완전한 알약. 8px 모서리는 '조금 둥근 네모' 라 여전히 칸으로 읽힌다. */
  border-radius: 999px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .01em;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* 색이 툭 바뀌는 대신 스며들게. 짧게 둔다 — 길면 누른 뒤 반응이 굼떠 보인다. */
  transition: background .16s ease, color .16s ease;
}
.pagebar-item .ico {
  width: 16px;
  height: 16px;
  stroke-width: 1.7;
  transition: transform .16s ease;
}
.pagebar-item:hover { background: rgba(255, 255, 255, .06); color: var(--fg); }
/* 아이콘이 살짝 뜬다. 색만 바뀌는 것보다 "눌러도 되는 것" 으로 읽힌다. */
.pagebar-item:hover .ico { transform: translateY(-1px); }

/* ★ 지금 보고 있는 곳. 이 표시가 이 막대의 절반이다 — 예전에는 현재 페이지
     버튼이 **아예 없어져서** 셋 중 어디인지가 버튼으로는 안 보였다.
     span 이라 눌리지 않는다(js/nav.js): 눌러 봤자 페이지만 다시 뜨고
     차트에서는 보던 종목·주기·그리던 선이 날아간다. */
.pagebar-item.on {
  background: var(--accent-soft);
  color: var(--accent-fg);
  font-weight: 600;
  cursor: default;
  /* ★ 색만으로는 훑을 때 안 걸린다 — 모양으로도 말해야 한다. 예전에는 위쪽에
     2px 금을 그었는데, 칸이 막대를 꽉 채우던 시절의 방식이라 알약과는 안 맞는다.
     알약 둘레를 얇게 두르면 같은 일을 하면서 훨씬 조용하다. */
  box-shadow: inset 0 0 0 1px var(--accent);
}
.pagebar-item.on:hover { background: var(--accent-soft); color: var(--accent-fg); }

/* 좁아지면 글자를 접고 아이콘만 남긴다. 셋을 다 보여 주는 것이 먼저다 —
   한 칸이 잘려 '계획 관…' 이 되면 그게 무슨 문인지 알 수 없다. */
@media (max-width: 560px) {
  /* 글자를 접으면 168px 기준 폭도 뜻이 없다 — 아이콘만 담을 만큼만 준다. */
  .pagebar-item { flex: 0 1 64px; font-size: 0; gap: 0; padding: 9px; }
  .pagebar-item .ico { width: 18px; height: 18px; }
}

/* ═══════════════════════════════════════════════ 백테스트 페이지
   창이었다. 옮긴 이유는 넓어서가 아니라 창이 못 하는 일이 둘 생겨서다 —
   나란히 비교, 그리고 가정 바꿔 돌리기 (backtest.html 머리말). */

.bt-main {
  flex: 1;
  min-height: 0;
  display: flex;
  gap: 14px;
  padding: 14px 18px 18px;
}

/* ★ 왼쪽은 **고정 폭**이다. 이 화면의 주인공은 차트라, 남는 자리는 전부
   오른쪽에 준다. 왼쪽이 늘어나면 고르개 두 개가 화면 절반을 차지한다. */
.bt-side {
  flex: 0 0 288px;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow-y: auto;
}

.bt-box {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 13px 13px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
}
.bt-box h3 {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 2px;
  font-size: 12px;
  font-weight: 600;
  color: var(--fg);
}
.bt-box .hint { margin: 2px 0 0; }

.bt-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11.5px;
  color: var(--muted);
}
.bt-field select { width: 100%; }
/* 숫자 칸은 이름과 **한 줄에** 둔다. 셋이 세로로 쌓이면 가정 칸이 고르개보다
   길어져서, 곁가지가 본론보다 커 보인다. */
.bt-num { flex-direction: row; align-items: center; justify-content: space-between; }
.bt-num .field { flex: 0 0 116px; }
.bt-num .field input { width: 100%; text-align: right; }

.bt-lab { font-size: 11.5px; color: var(--muted); }
.bt-dates { display: flex; align-items: center; gap: 6px; }
.bt-dates input { flex: 1; min-width: 0; }
.bt-dates em { font-style: normal; color: var(--dim); }
.bt-seg { display: flex; }
.bt-seg button { flex: 1; }
.bt-go { margin-top: 2px; }

/* ★★ 가정이 실전값과 다르면 **칸이 물든다.** 이 화면의 제일 위험한 고장은
   숫자를 만지작거리다 지금 것이 실전 가정인지 잊는 것이다. 성적표 위에도
   같은 말이 뜨지만(.rs-notlive), 원인이 있는 자리에도 표시가 있어야
   무엇을 되돌려야 할지 안다. */
.bt-box.off-live { border-color: var(--err); }
.bt-tag {
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 700;
  color: var(--err);
  background: rgba(239, 83, 80, .14);
}
.bt-tag.hidden { display: none; }
.bt-reset {
  margin-top: 2px;
  padding: 6px 8px;
  font-size: 11.5px;
}

/* ★ '담아 둔 결과' 와 '나란히 비교' 가 여기 있었다. **함께 걷어냈다.**
   결과를 고르는 길이 그 상자뿐이라, 상자만 없애면 비교 표는 닿을 수 없는
   화면으로 남는다 — 부르는 곳 없는 코드가 살아 있는 것이 제일 나쁘다.
   되살리려면 이 커밋을 보면 된다 (.bt-keep · .bt-kept* · .bt-drop · .bt-off ·
   .bt-compare · .bt-table 과 js/backtest 의 keep · paintKeep · paintCompare). */

/* 오른쪽 — 결과 */
.bt-view {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow-y: auto;
}
.bt-viewrow { display: flex; align-items: center; gap: 8px; }
.bt-viewrow.hidden { display: none; }
/* 계좌 곡선. **차트가 아니라 그림 하나다** — 밀 것이 없어서 높이도 낮다.
   ★ SVG 를 폭에 맞춰 늘린다(preserveAspectRatio="none"). 구간 전체가 한 눈에
     들어오는 것이 이 그림의 전부라, 가로 비율은 지킬 것이 아니다. */
/* ★ **테두리를 두른다.** 캔들 차트 바로 아래에 붙는데, 경계가 없으면 두
   그림이 한 덩어리로 뭉쳐 보여서 어디부터가 곡선인지 눈이 못 가른다.
   ★ 위쪽 모서리는 각지게 둔다 — 캔들에 이어 붙은 칸이라는 뜻이다. */
/* ★★ 성적표와 곡선을 **나란히, 정사각형으로.**
   곡선은 가로로 길수록 완만해 보이고 세로로 길수록 가팔라 보인다 — 같은 성적이
   칸 모양에 따라 다르게 읽힌다. 네모로 못 박으면 담아 둔 결과들끼리도 같은 눈으로
   견줄 수 있다. 그리고 둘은 함께 읽어야 뜻이 선다(왼쪽이 얼마, 오른쪽이 어떻게). */
.bt-pair {
  flex: none;
  display: grid;
  /* ★★ **위 차트와 같은 폭이다.** 한때 정사각형이었다. 걷어냈다 — 네모와
     "폭을 차트에 맞춘다" 는 **함께 설 수 없다**:

         반쪽 폭 700px  ×  정사각형  =  높이 700px  →  한 화면에 안 들어온다
         높이를 33vh 로 묶고 정사각형  →  폭이 300px  →  차트보다 훨씬 좁다

     둘 중 하나를 골라야 하고, 고른 것은 폭이다. 왼쪽 끝과 오른쪽 끝이 위
     차트와 안 맞으면 셋이 한 덩어리로 안 읽히고, 그러면 "이 낙폭이 저 매도
     때문" 을 눈으로 잇는 일이 어려워진다 — 나란히 둔 까닭이 그것이다.

     ★ 네모가 하던 일(담아 둔 결과들끼리 같은 눈으로 견주기)은 **높이를 고정**
       하는 것으로 남는다. 곡선의 기울기를 왜곡하는 것은 칸 모양이 매번 다른
       것이지 네모가 아닌 것 자체가 아니다. 폭은 화면마다 달라도 한 화면 안에서
       돌린 결과끼리는 늘 같은 칸에 그려진다. */
  /* ★ 성적표를 반으로 줄이고 그 자리에 사고판 날 목록을 넣는다. 곡선은 반쪽
     그대로다 — 그림은 좁아지면 모양이 안 읽히는데, 표는 좁아도 줄로 읽힌다. */
  grid-template-columns: 1fr 1fr 2fr;
  gap: 10px;
}
.bt-pair > * {
  /* 차트와 같은 높이. 40 + 33 + 여백이 한 화면이다. */
  height: 33vh;
  min-height: 200px;
  min-width: 0;
}
/* 목록도 같은 상자로 보이게. 머리줄이 붙박이(sticky)라 배경색이 상자와 같아야
   스크롤할 때 글자가 비쳐 보이지 않는다. */
.bt-pair .run-list {
  max-height: none;
  padding: 0 2px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
  overflow: auto;
}
.bt-pair .rt { font-size: 11px; }
.bt-pair .rt th, .bt-pair .rt td { padding: 4px 6px; }
.bt-curve {
  display: flex;
  flex-direction: column;
  padding: 10px 12px 8px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
}
.bt-curve.hidden { display: none; }
/* ★★ 눈금 글자는 **SVG 밖**에 둔다. 곡선은 preserveAspectRatio="none" 으로 폭에
   맞춰 늘리는데(구간 전체를 한 눈에 담으려고), 그 안에 <text> 를 넣으면 글자까지
   가로로 늘어나 뭉개진다. 축은 HTML 로, 곡선은 SVG 로.

   왼쪽 칸(46px)이 % 눈금 자리다. 곡선은 그만큼 좁아지지만, 눈금 없는 넓은
   그림보다 눈금 있는 조금 좁은 그림이 읽힌다 — 숫자를 못 읽으면 모양만 남는다. */
/* ★ 그림 칸이 남는 자리를 **전부** 먹는다(1fr). 네모 상자 안에서 축과 밑줄을
   빼고 남는 만큼이 곡선의 높이다 — 높이를 숫자로 박아 두면 상자가 커져도 곡선만
   납작하게 남는다. */
.eq-grid {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 46px 1fr;
  grid-template-rows: 1fr auto;
}
.eq { display: block; grid-column: 2; width: 100%; height: 100%; min-height: 0; }
/* 세로축. 눈금은 **값이 있는 자리**에 절대 위치로 선다 — 같은 격자 줄에 있어서
   곡선과 높이가 언제나 같고, 그래서 % 가 그대로 맞는다. */
.eq-y {
  position: relative;
  min-height: 0;
}
.eq-y span {
  position: absolute;
  right: 7px;
  transform: translateY(-50%);
  font-size: 9.5px;
  font-variant-numeric: tabular-nums;
  color: var(--dim);
  white-space: nowrap;
}
/* 가로축. 양 끝은 안쪽으로 붙여 잘리지 않게 한다. */
.eq-x {
  grid-column: 2;
  display: flex;
  justify-content: space-between;
  margin-top: 3px;
  font-size: 9.5px;
  font-variant-numeric: tabular-nums;
  color: var(--dim);
}
.eq-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: 4px;
  padding-top: 5px;
  border-top: 1px solid var(--line);
  font-size: 10.5px;
  color: var(--dim);
}
.eq-foot b { font-size: 12px; }
/* ★ 캔들은 **온전한 상자**다. 한때 아래쪽 선을 빼서 곡선과 이어 붙였는데,
   곡선이 성적표 옆으로 가면서 이어 붙일 짝이 없어졌다 — 선을 빼 둔 채로 두면
   아래가 터진 상자가 된다. */
.bt-view .snap-chart {
  /* ★ 340px 로 박아 뒀었다. 아래 두 상자와 합치면 어떤 화면에서도 한 페이지에
     안 들어온다 — 높이는 화면에 맞춰 정해야 한다. 33vh + 33vh + 여백이 한
     화면이다. 작은 노트북에서도 캔들이 뭉개지지 않게 바닥은 남겨 둔다. */
  /* ★★ 33 → 40 → 48vh 로 왔다. 마지막 한 뼘은 **깃발 때문**이다.
     매매 깃발은 봉의 고가에서 위로 서고, 가까운 봉끼리 겹치지 않게 네 층까지
     올라간다(js/chartmark.ladder). 글자 상자는 그 자리에서 **픽셀로** 위쪽에
     그려지므로, 칸이 낮으면 제일 위층 깃발이 차트 천장에 잘린다 — 봉이 잘리는
     것이 아니라 **글자가** 잘려서, 무엇을 산 자리인지 읽을 수가 없다.
     ★ 그래도 한 화면이다: 48 + 33 + 여백. */
  height: 48vh;
  min-height: 280px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
}

/* 무엇을 보고 있는지. 그림 바로 위 한 줄.
   ★ 이름이 run-* 인 이유. .bt-who 는 **AI 화면이 이미 쓰고 있다**(js/ai.js 의
     종목별 성적 이름표). 같은 이름을 쓰면 여기서 준 flex:none·글자 크기가
     그쪽까지 따라가서, 손댄 적 없는 화면이 조용히 바뀐다. */
.run-who {
  flex: none;
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
}
.run-who.hidden { display: none; }
.run-who b { color: var(--fg); }
.run-who em {
  font-style: normal;
  font-size: 11px;
  color: var(--dim);
}

/* ── 계좌 상태 맨 위 두 그림 ────────────────────────────────────
   ★ 나란히 둔다. 왼쪽이 시간(얼마였다가 얼마가 됐나), 오른쪽이 구성(지금
     무엇에 들어 있나) — 두 질문이 짝이라 한 줄에 서야 서로를 설명한다. */
.acct-top { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
/* 곡선이 아직 없으면 포트폴리오가 폭을 다 쓴다. 빈 상자를 세워 두는 것보다
   낫다 — 테두리만 남으면 고장처럼 보인다. */
.acct-top.solo { grid-template-columns: 1fr; }
.acct-box {
  min-width: 0;
  padding: 10px 11px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
}
.acct-box > em { display: block; margin-bottom: 6px; font-style: normal; font-size: 11px; color: var(--muted); }
.acct-box .hint { margin: 6px 0 0; }
/* 이름표 뒤에 붙는 단서("원화 포함"). 이름과 같은 굵기면 이름이 둘이 된다. */
.acct-box > em i { font-style: normal; opacity: .65; }

.spark { display: block; width: 100%; height: 64px; }
.spark-foot { display: flex; justify-content: space-between; align-items: baseline; margin-top: 4px; font-size: 10.5px; color: var(--dim); }
.spark-foot b { font-size: 11.5px; }

/* 도넛. 라이브러리 없이 SVG 로 그린다 — 조각이 대여섯이라 그럴 일이 아니다. */
.pie-wrap { display: flex; align-items: center; gap: 10px; }
.pie { flex: none; width: 78px; height: 78px; }
.pie-key { flex: 1; min-width: 0; margin: 0; padding: 0; list-style: none; font-size: 10.5px; }
.pie-key li { display: flex; align-items: center; gap: 5px; line-height: 1.7; }
.pie-key i { flex: none; width: 8px; height: 8px; border-radius: 2px; }
.pie-key span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); }
.pie-key b { flex: none; color: var(--fg); }

@media (max-width: 620px) {
  .acct-top { grid-template-columns: 1fr; }
}
/* ★ 좁아지면 위아래로 눕히고 네모를 푼다. 반쪽 너비가 200px 도 안 되는데 네모를
   고집하면 둘 다 읽을 수 없는 크기가 된다 — 견주는 것보다 읽히는 것이 먼저다. */
/* ★ 좁아지면 위아래로 눕힌다. 반쪽이 200px 도 안 되면 성적표의 숫자 칸이
   한 줄에 하나씩 떨어져서, 나란히 둔 값어치보다 읽히지 않는 손해가 커진다. */
@media (max-width: 900px) {
  .bt-pair { grid-template-columns: 1fr; }
  .bt-pair > * { height: auto; min-height: 220px; }
  .bt-pair .run-list { max-height: 26vh; }
  .bt-pair .eq-grid { min-height: 170px; }
}
/* ★ 낮은 화면에서는 vh 가 너무 작아져 캔들이 뭉개진다. 그때는 한 페이지를
   포기하고 읽히는 쪽을 고른다 — 안 보이는 그림은 자리만 차지한다. */
@media (max-height: 700px) {
  .bt-view .snap-chart { height: auto; min-height: 260px; }
  .bt-pair > * { height: auto; min-height: 240px; }
}
.bt-view #bt-empty { margin: auto; text-align: center; }
/* ★ .hidden 은 이 프로젝트에 전역 규칙이 없다 — 선택자마다 따로 적는다.
   빠뜨리면 classList.add('hidden') 이 조용히 아무 일도 안 한다. */
#bt-empty.hidden { display: none; }

/* 실전 가정이 아니라는 말은 성적표 **맨 위**에. 아래에 적으면 숫자를 다 읽은
   뒤에야 보이고, 그때는 이미 판단이 끝나 있다. */
.rs-notlive {
  display: block;
  margin-bottom: 4px;
  color: var(--err);
  font-weight: 600;
}

@media (max-width: 900px) {
  /* 왼쪽을 위로 접는다. 좁은 화면에서 288px 을 떼면 차트가 못 쓰게 된다. */
  .bt-main { flex-direction: column; padding: 10px; }
  .bt-side { flex: none; overflow: visible; }
}

/* 알림 내역 한 줄. **제목이 종목과 행동부터 말한다.**
   ★ 예전 제목은 `NAS:HOOD · 로빈후드 매수 · 그어 둔 채널…` 이었다. 거래소
     코드가 맨 앞이고 얼마어치인지는 어디에도 없었다 — 이 목록을 여는 이유가
     바로 그 물음인데. 로고·이름·금액을 한 줄로 올리고 조건은 아래로 내렸다. */
.fire-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.fire-head b { font-size: 13px; }
/* 금액이 이 줄에서 제일 급한 값이다. 사는 쪽과 파는 쪽은 차트 봉과 같은 색. */
.fire-do {
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 12px;
  background: var(--panel-2, rgba(255, 255, 255, .06));
}
/* 상승/하락과 같은 색을 쓴다 (--ok / --err) — 화면 어디서나 사는 쪽이 청록,
   파는 쪽이 붉은색이라 이 줄만 다른 규칙을 두면 한 번 더 읽어야 한다. */
.fire-do.buy { color: var(--ok); }
.fire-do.sell { color: var(--err); }
/* ★ 아직 안 붙은 주문. **나간 돈처럼 보이면 안 된다** — 색을 빼고 흐린다.
     옆에 '주문' 이라고도 적는다(js/settings.js 의 orderDeal). */
.fire-do.idle { color: var(--muted); }
.fire-head i { font-size: 11px; font-style: normal; color: var(--muted); }

/* 도구 묶음. 알림을 걸 수 있는 도형과 표시용을 **줄로 가른다** — 섞어 두면
   수직선을 긋고 "왜 알림이 안 오지" 가 된다. */
.tool-group { display: contents; }
.tool-head {
  grid-column: 1 / -1;
  margin: 6px 0 2px;
  color: var(--muted);
  font-size: 10.5px;
  border-top: 1px solid var(--line);
  padding-top: 7px;
}
.tool-head i { font-style: normal; color: var(--dim); }

/* 주문 한 줄의 오른쪽 — 실현손익. 없는 건(매수·평단 모름)은 아예 비운다.
   0 을 찍으면 '본전' 으로 읽힌다. */
#set-orders .item > span:last-child { flex: none; white-space: nowrap; }

/* 포지션 줄의 종목 칸 — 로고 · 티커 · 이름이 한 줄에 선다. */
.pos-who {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

/* ── 로그인 화면 ────────────────────────────────────────────────
   로고 하나 · 입력 둘 · 칸 둘. 설명 글이 없다 — 이 화면에서 할 일이
   하나뿐이라, 무엇을 하는 화면인지 글로 적을 필요가 없다.

   ★★ **여기서는 전역 규칙을 하나도 믿지 않는다.** 이 스타일시트는 차트
      화면을 위해 쓰여서, 요소 이름에 걸린 규칙이 많다:

          main   { display: grid; grid-template-columns: 68px 1fr 246px }
          input, select, button { width: 100%; padding: 7px 9px; font-size: 12px }
          button { margin-top: 4px }

      처음에 이 화면을 <main> 으로 짜고 몇 가지만 덮었다가, 로고가 **68px
      칸에 끼여** 글자가 잘리고 입력칸이 가운데 칸으로 밀려 화면이 통째로
      뒤죽박죽이 됐다. 덮어쓴 몇 개 말고 **안 덮은 것들이 문제였다.**

      그래서 여기서는 여백·안쪽여백·글꼴·상자계산을 전부 **직접 적는다.**
      길어 보여도, 전역 규칙이 하나 바뀔 때마다 이 화면이 무너지는 것보다 싸다. */
body.login-page {
  /* body 에는 flex-direction: column 이 이미 걸려 있다. 그대로 두고
     가운데 정렬만 얹으면 세로 가운데가 된다. */
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.login-box {
  /* ★ flex 자식이라 flex: 1 을 안 걸면 내용만큼만 차지한다. 폭은 고정. */
  flex: none;
  width: min(320px, 100%);
}

/* 로고 줄. 배지는 brand.js 가 만들고(마크 + 글자, 가로 배치) 여기서는
   **가운데로 세우기만** 한다 — 로고 마크업을 두 벌 만들면 언젠가 한쪽만 낡는다. */
.login-logo {
  display: flex;
  justify-content: center;
  margin-bottom: 28px;
}
/* ★ 여기서는 배지가 아니라 간판이다. 머리말(26px/17px)보다 크게. */
.login-page .brand {
  gap: 12px;
  cursor: default;
  pointer-events: none;
}
.login-page .brand-mark { width: 40px; height: 40px; }
.login-page .brand-word { font-size: 27px; letter-spacing: .06em; }

.login-box form { margin: 0; }

.login-box input {
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 42px;
  margin: 0 0 9px;
  padding: 0 14px;
  font-family: inherit;
  font-size: 13.5px;
  line-height: 42px;          /* ★ height 와 같게. 안 맞추면 글자가 위로 붙는다 */
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  appearance: none;
}
.login-box input::placeholder { color: var(--dim); }
.login-box input:focus { outline: none; border-color: var(--accent); }
.login-box input[hidden] { display: none; }

/* 로그인 / 회원가입. **나란히 선다.**
   ★ 채워진 쪽이 지금 하는 일이고 테두리만 있는 쪽이 넘어갈 곳이다.
     그래서 "지금 회원가입 중입니다" 같은 글이 필요 없다 — 색이 말한다. */
.login-tabs {
  display: flex;
  gap: 9px;
  margin-top: 7px;
}
.login-tabs button {
  /* ★ flex: 1 로 **반씩 나눠 갖는다.** 두 칸은 언제나 함께 서 있고
     (첫 계정일 때도), 그때는 회원가입 쪽이 못 눌리는 상태로 자리를 지킨다
     (js/login.js 의 ★★). 숨기면 남은 칸이 폭을 다 먹으면서 그런 길이
     있다는 것 자체가 화면에서 사라진다. */
  flex: 1;
  /* ★ 둘이 같은 폭이어야 한다. 글자 길이('시작하기' vs '회원가입')로
     칸이 갈리면 어느 쪽이 큰 쪽인지가 뜻 없이 정해진다. */
  flex-basis: 0;
  box-sizing: border-box;
  min-width: 0;
  height: 42px;
  margin: 0;                  /* ★ 전역 button 의 margin-top: 4px 를 지운다 */
  padding: 0 10px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  color: var(--fg-dim);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
  appearance: none;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.login-tabs button:hover:not(:disabled) { border-color: var(--line-2); color: var(--fg); }
.login-tabs button.on {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}
.login-tabs button.on:hover:not(:disabled) {
  background: var(--accent-2);
  border-color: var(--accent-2);
}
.login-tabs button:disabled { opacity: .55; cursor: default; }
.login-tabs button[hidden] { display: none; }

/* ★ 클래스 이름을 .warn 에서 바꿨다. 저쪽은 본문용이라 여백·배경이 딸려 온다. */
.login-err {
  margin: 14px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--err);
}
.login-err[hidden] { display: none; }
