
body { font-family: -apple-system, 'Malgun Gothic', sans-serif; background:#f5f5f7; margin:0; padding:16px; color:#222; }
h1 { font-size:20px; margin:0 0 10px; }
/* [2026-10-17 사용자: 로그인 아이디는 메뉴 말고 위 칸 오른쪽] 제목 줄 = 제목 | 아이디·모드 바꾸기·로그아웃 */
.topbar { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:10px; }
.topbar h1 { margin:0; flex:0 1 auto; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.top-user { position:relative; font-size:13px; min-width:0; flex:0 1 auto; }
.top-user summary { list-style:none; cursor:pointer; display:flex; align-items:center; gap:6px; padding:6px 10px; border-radius:8px;
  border:1px solid rgba(127,127,127,.35); white-space:nowrap; }
.top-user summary::-webkit-details-marker { display:none; }
.top-user .uid { display:inline-block; max-width:220px; overflow:hidden; text-overflow:ellipsis; vertical-align:bottom; font-weight:600; }
.top-user .menu { position:absolute; right:0; top:calc(100% + 4px); z-index:50; min-width:170px; display:flex; flex-direction:column;
  background:var(--card, #fff); border:1px solid rgba(127,127,127,.35); border-radius:10px; box-shadow:0 6px 18px rgba(0,0,0,.25); overflow:hidden; }
.top-user .menu a { padding:11px 14px; color:inherit; text-decoration:none; white-space:nowrap; }
.top-user .menu a + a { border-top:1px solid rgba(127,127,127,.2); }
.top-user .menu a:hover { background:rgba(127,127,127,.12); }
.top-user .menu .logout-f { margin:0; border-top:1px solid rgba(127,127,127,.2); }
.top-user .menu .logout-f .linkbtn { display:block; width:100%; box-sizing:border-box; padding:11px 14px; text-align:left; color:inherit; text-decoration:none; white-space:nowrap; }
.top-user .menu .logout-f .linkbtn:hover { background:rgba(127,127,127,.12); }
.logout-f { display:inline; margin:0; }
.linkbtn { background:none; border:0; padding:0; margin:0; font:inherit; color:var(--link); text-decoration:underline; cursor:pointer; min-height:0; }
@media (prefers-color-scheme: dark) {:where(:root:not([data-theme=light])) .top-user .menu{ background:#1f2224; }}
:where(:root[data-theme=dark]) .top-user .menu{ background:#1f2224; }
@media (max-width:600px) { .topbar h1 { font-size:17px; } .top-user { font-size:12px; } .top-user .uid { max-width:34vw; } }
nav a { display:inline-block; margin-right:6px; padding:6px 12px; border-radius:8px; background:#fff; color:#333;
        text-decoration:none; font-size:14px; box-shadow:0 1px 2px rgba(0,0,0,.08); }
nav a.on { background:#263238; color:#fff; }
nav a.nav-user { background:var(--surface2); color:var(--text2); }   /* [11-07 점검 4절] 테마가 덮지 않는 규칙 = 토큰 */
.tabs a { display:inline-block; padding:6px 14px; margin:10px 6px 10px 0; border-radius:8px 8px 0 0; text-decoration:none;
          font-weight:bold; border-bottom:3px solid transparent; color:#555; }
.tabs a.on-demo { color:#1565c0; border-color:#1565c0; } .tabs a.on-real { color:#c62828; border-color:#c62828; }
.card { background:#fff; border-radius:12px; padding:16px; margin-bottom:16px; overflow-x:auto;
        box-shadow:0 1px 3px rgba(0,0,0,0.08); }
.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(320px,1fr)); gap:16px; }
.muted { color:#666; font-size:13px; }
table { width:auto; min-width:100%; border-collapse:collapse; font-size:13px; margin-top:8px; }
th, td { text-align:right; padding:6px 4px; border-bottom:1px solid #eee; vertical-align:middle; white-space:nowrap;
         font-variant-numeric:tabular-nums; }
td:first-child { white-space:normal; min-width:9em; }
th:first-child, td:first-child { text-align:left; }
/* [2026-10-12 사용자: 국내 관례] 손익·등락 = 수익·상승 빨강 / 손실·하락 파랑. 상태(켜짐·정상 / 꺼짐·실패)는 ok·bad 로 따로 */
.pos { color:#d32f2f; } .neg { color:#1565c0; }
.up { color:#d32f2f; } .dn { color:#1565c0; }
.ok { color:#0a7d34; } .bad { color:#c62828; }
details summary { cursor:pointer; margin-top:8px; font-size:13px; }
.tag { display:inline-block; background:#eef2ff; color:#3949ab; border-radius:6px; padding:1px 6px; font-size:11px; margin-left:4px; }
h2 { font-size:16px; margin:0 0 8px; }
h3 { font-size:14px; margin:14px 0 4px; }
.badge { display:inline-block; border-radius:6px; padding:2px 8px; font-size:12px; font-weight:bold; vertical-align:middle; }
.badge-mock { background:#e3f2fd; color:#1565c0; } .badge-real { background:#c62828; color:#fff; }
.badge-err { background:#fff3e0; color:#e65100; }
/* [2026-10-31 사용자: "오늘 시황에서 약세·강세 모두 빨간색"] 강세 = 빨강(상승) / 약세 = 회색(방향 약한 보합 구간) / 하락 = 파랑 / 자료 없음 = 테두리만 (예전 약세 #bf360c 가 강세 빨강과 구분 안 됨) */
.rg-up { background:var(--pos); color:var(--on-bad); } .rg-weak { background:var(--muted); color:var(--surface); } .rg-down { background:var(--neg); color:var(--on-bad); } .rg-none { background:transparent; color:var(--muted); border:1px solid var(--muted); }
.msg-item { text-align:left; margin:8px 0; padding:8px 10px; border-left:4px solid var(--line2); } .msg-admin { border-left-color:var(--ok); }
.tag-warn { background:#fff3e0; color:#bf360c; font-weight:bold; }   /* [2026-10-16 디자인 검수] 경고 = 주황 - 수익 빨강(.pos)과 구분 */
ul { padding-left:18px; font-size:13px; margin:6px 0; }
code { background:#f0f0f3; padding:1px 4px; border-radius:4px; }
form.inline { display:inline; margin-left:4px; }
form.filter { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:6px 0; }   /* [2026-10-17] 조회 조건 - 항목 단위로 줄바꿈 */
form.filter .fg { display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
form.filter .fg-btns { flex-wrap:wrap; white-space:normal; }   /* [2026-10-17] 빠른 선택 버튼 묶음 */
form.filter .fg { min-width:0; max-width:100%; } select { max-width:100%; text-overflow:ellipsis; }   /* 긴 선택지가 카드 밖으로 넘치지 않게 */
form.filter.inline, form.filter { display:flex; } form.filter .fg-wrap { display:contents; } form.filter .fg-wrap[hidden] { display:none; } form.filter .fg > .muted { white-space:normal; min-width:0; }   /* 전략별로 바뀌는 입력 묶음 - 안의 덩어리가 폼 줄에 바로 놓인다 */
.btn { display:inline-block; border:0; border-radius:6px; padding:4px 10px; font-size:12px; cursor:pointer; text-decoration:none; }
.btn-blue { background:#1565c0; color:#fff; } .btn-red { background:#c62828; color:#fff; } .btn-gray { background:#e0e0e0; color:#222; border:1px solid #b0b0b0; }
input, select, textarea { font-size:13px; padding:4px 6px; border:1px solid #8c8c8c; border-radius:6px; font-family:inherit; }   /* [2026-10-16] 테두리 3:1 */
.row-total { font-weight:bold; background:#fafafa; } .row-new { background:#fffdf3; }
tr.row-cur, table.stack tr.row-cur { background:#f1f8e9; } tr.row-cur > :first-child { background:inherit; }   /* [2026-10-16 다크 모드] 지금 적용 중인 줄(관리자 수수료·세금 표) - 예전 인라인 style 은 다크가 못 덮었다 */
.bl-bad { border-left:6px solid var(--bad); } .bl-ok { border-left:6px solid var(--ok); }   /* 관리자 '오늘 할 일' 카드 왼쪽 띠 */
.flash { padding:10px 14px; border-radius:8px; margin-bottom:12px; font-size:14px; }
.flash-ok { background:#e8f5e9; color:#1b5e20; } .flash-err { background:#ffebee; color:#b71c1c; }
.sum td, .sum th { font-size:14px; }
.stat { display:inline-block; min-width:110px; margin:4px 10px 4px 0; }
.stat b { display:block; font-size:18px; }
.disclaimer { margin:20px 0 8px; padding:10px 14px; border-radius:8px; background:#fff8e1; color:#6d4c00; font-size:12px; line-height:1.5; }
@media (max-width:600px) { body { padding:12px 16px; }   /* [10-30 재검수 3차] 옆 여백 10 -> 16px(가이드 '화면 옆 여백 16px', 고객 앱 틀과 같게) */ .grid { grid-template-columns:1fr; }
  .fld { flex:1 1 100%; } .fld .fi input { flex:1; min-width:0; } .fld .fi select { flex:0 0 auto; } }
/* [2026-10-12 디자인 점검] 모바일: 표는 글자 단위로 깨지지 않게(nowrap) 카드 안 가로 스크롤 + 첫 열 고정, 메뉴는 한 줄 가로 스크롤,
   손가락 터치 영역 44px, 입력 글꼴 16px(iOS 확대 방지), 키보드 포커스 표시, 위험 조작 구역, 실전·모의 띠 */
.card { -webkit-overflow-scrolling:touch; }
:focus-visible { outline:3px solid #1565c0; outline-offset:2px; }
.opts { margin:10px 0; } .opt { display:block; margin:6px 0 6px 4px; padding:8px 10px; border:1px solid #eee; border-radius:8px; }
.opt .muted { display:block; margin-top:2px; } .opt label { margin-right:14px; }
/* [2026-10-17] 입력 항목 묶음 - 이름 위·칸+단위 아래, 항목 단위로 줄바꿈(스프릿 만들기) */
.step { margin:14px 0; } .step > .st { display:block; margin-bottom:6px; }
.fields { display:flex; flex-wrap:wrap; gap:10px 18px; align-items:flex-start; }
.fld { display:inline-flex; flex-direction:column; gap:4px; } .fld .fl { font-size:12px; color:#666; }
.fld .fi { display:inline-flex; align-items:center; gap:6px; white-space:nowrap; } .fld .fh { font-size:12px; }
.fld-wide { flex:1 1 100%; } .fld-wide input { width:100%; box-sizing:border-box; }   /* 키처럼 긴 값 - 한 줄 전체 */
.step .hint { display:block; margin-top:6px; font-size:12px; line-height:1.5; }
.step .hint + .fields { margin-top:14px; }
.danger-zone { border:1px solid #c62828; background:#fff5f5; border-radius:10px; padding:10px 12px; margin:10px 0; }
.mode-band { position:sticky; top:0; z-index:10; margin:-16px -16px 12px; padding:8px 16px; font-weight:bold; font-size:14px; }
.mode-real { background:#c62828; color:#fff; } .mode-demo { background:#e3f2fd; color:#0d47a1; }
.mode-admin { background:#37474f; color:#fff; } .badge-admin { background:#37474f; color:#fff; }
body.real { border-top:6px solid #c62828; }
@media (max-width:600px) {
  .mode-band { margin:-12px -16px 10px; padding:8px 16px; }
  nav { display:flex; flex-wrap:nowrap; overflow-x:auto; gap:6px; padding:4px 0; -webkit-overflow-scrolling:touch;
        position:sticky; top:36px; z-index:9; background:var(--bg, #f5f5f7); scrollbar-width:none; }   /* [10-30] 가로 막대 숨김(관리자 메뉴와 같게) */
  nav::-webkit-scrollbar, .flt .chips::-webkit-scrollbar, .tabs::-webkit-scrollbar { display:none; }
  .flt .chips, .tabs { scrollbar-width:none; }   /* [2026-10-16] 내려도 메뉴가 남게 */
  nav a { flex:0 0 auto; margin-right:0; }
  /* [2026-10-18] 선택한 메뉴·탭이 가로 줄 안에 보이게 - 스크립트 대신 CSS(처음 그릴 때 그 칸으로 스크롤된 채 나온다) */
  nav a.on, .tabs a.on, .tabs a.on-demo, .tabs a.on-real { scroll-initial-target:nearest; scroll-snap-align:center; }
  nav > * { flex:0 0 auto; white-space:nowrap; align-self:center; }   /* [2026-10-17] '모의 모드' 배지가 줄어들며 두 줄로 꺾여 메뉴 칸 전체가 높아졌다 */
  .card { padding:12px; }
  table td:first-child, table th:first-child { position:sticky; left:0; background:#fff; z-index:1; }
  input, select, textarea { max-width:100%; }
  .tabs { display:flex; flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .tabs a { flex:0 0 auto; white-space:nowrap; }
  /* [2026-10-12 모바일 실측] 카드보다 넓은 표 = 줄마다 카드 한 장(첫 칸 = 제목, 나머지 = '머리글: 값'). [10-18] 서버 web_layout 이 고른다(예전 STACK_JS) */
  table.stack { min-width:0; width:100%; display:block; }
  table.stack thead, table.stack tr.hdr { display:none; }
  table.stack tbody { display:block; }
  table.stack tr { display:block; border:1px solid #e6e6ea; border-radius:10px; padding:4px 10px; margin:8px 0; background:#fff; }
  /* [2026-10-16 디자인 검수] 예전 display:flex 는 칸 안의 span·br·글자를 각각 따로 늘어놓아 '규/칙/조/작', '+0.03 ... %' 로 쪼갰다 -> 블록 + 라벨 왼쪽 띄움 */
  table.stack td, table.stack th { display:block; overflow:hidden; white-space:normal;
                                   text-align:right; border-bottom:1px dashed #eee; padding:6px 0; position:static; min-width:0; }
  table.stack tr > :last-child { border-bottom:0; }
  table.stack td::before, table.stack th::before { content:attr(data-label); color:#666; font-size:12px; font-weight:normal;
                                                   text-align:left; float:left; max-width:45%; margin-right:12px; }
  table.stack tr > :first-child { display:block; text-align:left; font-weight:bold; font-size:14px; }
  table.stack tr > :first-child::before, table.stack [data-label=""]::before { display:none; }
  table.stack td.span-msg { text-align:left; }   /* [2026-11-05] 여러 칸 합친 안내 문장 = 이름표 없이 왼쪽(web_layout span-msg) */
  table.stack form.inline { margin:2px 0 2px 4px; }
  /* [2026-10-19] 조작 없는 긴 기록 표(web_layout class rec) = 첫 칸 한 줄 + 나머지 '머리글 값' 이어 쓰기 */
  table.stack.rec tr { padding:6px 10px; margin:4px 0; }
  table.stack.rec td, table.stack.rec th { display:inline-block; border:0; padding:1px 12px 1px 0; text-align:left; font-size:13px; max-width:100%; }
  table.stack.rec td::before, table.stack.rec th::before { float:none; content:attr(data-label) " "; margin-right:2px; max-width:none; }
  table.stack.rec tr > :first-child { display:block; font-size:13px; }
  /* [2026-10-17 사용자 화면: 바이낸스 실거래 '전략 설정' 확인 문구 칸이 카드 밖으로 잘림] 칸(td)은 overflow:hidden 이라 넘치면 잘린다 ->
     칸 안의 폼은 줄바꿈되는 묶음, 입력칸은 칸 너비를 넘지 않게(전 화면 공통) */
  table.stack td form.inline, table.stack td form { display:flex; flex-wrap:wrap; gap:10px 6px; justify-content:flex-end; align-items:center; max-width:100%; }
  table.stack td .fg, table.stack td .fg-wrap { display:inline-flex; flex-wrap:wrap; gap:10px 6px; align-items:center; max-width:100%; min-width:0; }
  table.stack td input:not([type=checkbox]):not([type=radio]), table.stack td select, table.stack td textarea { max-width:100%; min-width:0; box-sizing:border-box; }
  /* [10-17 전수 점검] 백테스트 폼 - 긴 선택지(전략 이름)·size 지정 입력칸이 카드 밖으로. 카드 안 입력은 카드 너비를 넘지 않는다(전 화면 공통) */
  .card input:not([type=checkbox]):not([type=radio]):not([type=hidden]), .card select, .card textarea { max-width:100%; box-sizing:border-box; }
  .card input.confirm-in { flex:1 1 100%; }   /* [10-17] 실전 켜기 확인 문구 칸 = 한 줄 전체(안내 글자 안 잘리게) */
  .card .fg, .card .fg-wrap { max-width:100%; min-width:0; } .card .fg select, .card .fg input { min-width:0; max-width:100%; }
}
@media (pointer:coarse) {
  .btn, nav a, .tabs a { min-height:44px; padding:10px 14px; font-size:15px; box-sizing:border-box; display:inline-flex; align-items:center; }
  input, select, textarea { font-size:16px; min-height:44px; box-sizing:border-box; }
  input[type=checkbox], input[type=radio] { min-height:0; width:22px; height:22px; margin:0 6px 0 0; vertical-align:middle; }
  label { line-height:1.6; }
  details summary { display:list-item; padding:14px 0; }      /* [2026-10-16 디자인 검수] 17px 이던 접기 제목 - flex 는 ▶ 표시·글자 흐름을 깼다 */
  ol > li > a:only-child:not(.btn) { display:inline-block; padding:12px 0; }   /* [10-30 디자인 검수] 차례 같은 링크 목록만 - 문단·고지 안 링크까지 위아래 14px 로 키워 줄간격이 깨졌다 */
  form.inline { display:inline-block; margin:4px 4px 4px 0; }
  form.filter .fg { flex:1 1 100%; } form.filter .fg select { flex:1; min-width:0; }
  form.filter .fg input:not([type=checkbox]):not([type=radio]) { flex:1; min-width:0; }
  form.filter > .btn, form.filter > .fg-act { flex:1 1 100%; } form.filter > .btn, form.filter > .fg-act > .btn { justify-content:center; flex:1; }
  .tag { font-size:12px; }
}
/* [2026-10-16 디자인 검수] 차트 라이브러리(Lightweight Charts)는 안쪽에 <table> 을 만든다 - 위 공통 표 규칙(td:first-child min-width 9em·
   휴대폰 sticky 첫 칸·padding·테두리)이 닿아 왼쪽 117px 이 빈 칸, 최근 봉이 가격축 밑으로 가려졌다. 차트 안쪽은 원래대로. */
.tv-lightweight-charts table { min-width:0 !important; width:auto !important; margin:0 !important; font-size:inherit; }
.tv-lightweight-charts td, .tv-lightweight-charts th { min-width:0 !important; padding:0 !important; border:0 !important;
  position:static !important; background:transparent !important; white-space:normal; text-align:left; }
/* [2026-10-16 사용자: 모바일 다크 모드 확인 요청 -> 디자인 검수 '다크 모드 없음'] 기기 설정이 다크면 어두운 색. 손익 색은 어두운 바탕에서도
   대비 4.5:1 이상이 되게 밝힌다(수익·상승 빨강 #ff6b6b / 손실·하락 파랑 #64b5f6 / 정상 #66bb6a). <meta name=color-scheme> 로 브라우저 자동 반전을 막는다. */
:root { color-scheme: light dark; --bg:#f5f5f7; }
@media (prefers-color-scheme: dark) {:root:where(:not([data-theme=light])){ --bg:#121212; }:where(:root:not([data-theme=light])) body{ background:#121212; color:#e6e6e6; }:where(:root:not([data-theme=light])) a{ color:#90caf9; }:where(:root:not([data-theme=light])) nav a{ background:#262626; color:#dddddd; box-shadow:none; }:where(:root:not([data-theme=light])) nav a.on{ background:#e0e0e0; color:#111111; }:where(:root:not([data-theme=light])) .tabs a{ color:#bbbbbb; }:where(:root:not([data-theme=light])) .tabs a.on-demo{ color:#64b5f6; border-color:#64b5f6; }:where(:root:not([data-theme=light])) .tabs a.on-real{ color:#ff6b6b; border-color:#ff6b6b; }:where(:root:not([data-theme=light])) .card{ background:#1e1e1e; box-shadow:0 1px 3px rgba(0,0,0,.6); }:where(:root:not([data-theme=light])) .muted{ color:#a8a8a8; }:where(:root:not([data-theme=light])) .fld .fl{ color:#a8a8a8; }:where(:root:not([data-theme=light])) th,:where(:root:not([data-theme=light])) td{ border-bottom-color:#2e2e2e; }:where(:root:not([data-theme=light])) .pos,:where(:root:not([data-theme=light])) .up{ color:#ff6b6b; }:where(:root:not([data-theme=light])) .neg,:where(:root:not([data-theme=light])) .dn{ color:#64b5f6; }:where(:root:not([data-theme=light])) .ok{ color:#66bb6a; }:where(:root:not([data-theme=light])) .bad{ color:#ff6b6b; }:where(:root:not([data-theme=light])) .tag{ background:#283050; color:#c5cae9; }:where(:root:not([data-theme=light])) .badge-mock{ background:#0d2a4a; color:#90caf9; }:where(:root:not([data-theme=light])) .badge-err{ background:#3e2723; color:#ffb74d; }:where(:root:not([data-theme=light])) .tag-warn{ background:#3e2a00; color:#ffb74d; }:where(:root:not([data-theme=light])) code{ background:#2a2a2a; color:#e6e6e6; }:where(:root:not([data-theme=light])) .btn-gray{ background:#3a3a3a; color:#eeeeee; border:1px solid #777777; }:where(:root:not([data-theme=light])) .btn:not(.btn-blue):not(.btn-red):not(.btn-gray){ background:#333333; color:#eeeeee; border:1px solid #777777; }:where(:root:not([data-theme=light])) input,:where(:root:not([data-theme=light])) select,:where(:root:not([data-theme=light])) textarea{ background:#1a1a1a; color:#eeeeee; border-color:#7a7a7a; }:where(:root:not([data-theme=light])) .row-total{ background:#2a2a2a; }:where(:root:not([data-theme=light])) .row-new{ background:#2b2410; }:where(:root:not([data-theme=light])) tr.row-cur,:where(:root:not([data-theme=light])) table.stack tr.row-cur{ background:#1b2e1c; }:where(:root:not([data-theme=light])) .flash-ok{ background:#1b3a1f; color:#a5d6a7; }:where(:root:not([data-theme=light])) .flash-err{ background:#3b1517; color:#ef9a9a; }:where(:root:not([data-theme=light])) .disclaimer{ background:#2b2410; color:#e6d3a3; }:where(:root:not([data-theme=light])) .disclaimer a{ color:#ffe082; }:where(:root:not([data-theme=light])) .danger-zone{ background:#2a1414; border-color:#ef5350; }:where(:root:not([data-theme=light])) .opt{ border-color:#333333; }:where(:root:not([data-theme=light])) .mode-demo{ background:#0d2a4a; color:#bbdefb; }:where(:root:not([data-theme=light])) .mode-real{ background:#b71c1c; }:where(:root:not([data-theme=light])) body.real{ border-top-color:#e53935; }:where(:root:not([data-theme=light])) :focus-visible{ outline-color:#90caf9; }:where(:root:not([data-theme=light])) table td:first-child,:where(:root:not([data-theme=light])) table th:first-child{ background:inherit; }:where(:root:not([data-theme=light])) table.stack tr{ background:#1e1e1e; border-color:#333333; }:where(:root:not([data-theme=light])) table.stack td,:where(:root:not([data-theme=light])) table.stack th{ border-bottom-color:#2e2e2e; }:where(:root:not([data-theme=light])) table.stack td::before,:where(:root:not([data-theme=light])) table.stack th::before{ color:#a8a8a8; }}
:root:where([data-theme=dark]){ --bg:#121212; }:where(:root[data-theme=dark]) body{ background:#121212; color:#e6e6e6; }:where(:root[data-theme=dark]) a{ color:#90caf9; }:where(:root[data-theme=dark]) nav a{ background:#262626; color:#dddddd; box-shadow:none; }:where(:root[data-theme=dark]) nav a.on{ background:#e0e0e0; color:#111111; }:where(:root[data-theme=dark]) .tabs a{ color:#bbbbbb; }:where(:root[data-theme=dark]) .tabs a.on-demo{ color:#64b5f6; border-color:#64b5f6; }:where(:root[data-theme=dark]) .tabs a.on-real{ color:#ff6b6b; border-color:#ff6b6b; }:where(:root[data-theme=dark]) .card{ background:#1e1e1e; box-shadow:0 1px 3px rgba(0,0,0,.6); }:where(:root[data-theme=dark]) .muted{ color:#a8a8a8; }:where(:root[data-theme=dark]) .fld .fl{ color:#a8a8a8; }:where(:root[data-theme=dark]) th,:where(:root[data-theme=dark]) td{ border-bottom-color:#2e2e2e; }:where(:root[data-theme=dark]) .pos,:where(:root[data-theme=dark]) .up{ color:#ff6b6b; }:where(:root[data-theme=dark]) .neg,:where(:root[data-theme=dark]) .dn{ color:#64b5f6; }:where(:root[data-theme=dark]) .ok{ color:#66bb6a; }:where(:root[data-theme=dark]) .bad{ color:#ff6b6b; }:where(:root[data-theme=dark]) .tag{ background:#283050; color:#c5cae9; }:where(:root[data-theme=dark]) .badge-mock{ background:#0d2a4a; color:#90caf9; }:where(:root[data-theme=dark]) .badge-err{ background:#3e2723; color:#ffb74d; }:where(:root[data-theme=dark]) .tag-warn{ background:#3e2a00; color:#ffb74d; }:where(:root[data-theme=dark]) code{ background:#2a2a2a; color:#e6e6e6; }:where(:root[data-theme=dark]) .btn-gray{ background:#3a3a3a; color:#eeeeee; border:1px solid #777777; }:where(:root[data-theme=dark]) .btn:not(.btn-blue):not(.btn-red):not(.btn-gray){ background:#333333; color:#eeeeee; border:1px solid #777777; }:where(:root[data-theme=dark]) input,:where(:root[data-theme=dark]) select,:where(:root[data-theme=dark]) textarea{ background:#1a1a1a; color:#eeeeee; border-color:#7a7a7a; }:where(:root[data-theme=dark]) .row-total{ background:#2a2a2a; }:where(:root[data-theme=dark]) .row-new{ background:#2b2410; }:where(:root[data-theme=dark]) tr.row-cur,:where(:root[data-theme=dark]) table.stack tr.row-cur{ background:#1b2e1c; }:where(:root[data-theme=dark]) .flash-ok{ background:#1b3a1f; color:#a5d6a7; }:where(:root[data-theme=dark]) .flash-err{ background:#3b1517; color:#ef9a9a; }:where(:root[data-theme=dark]) .disclaimer{ background:#2b2410; color:#e6d3a3; }:where(:root[data-theme=dark]) .disclaimer a{ color:#ffe082; }:where(:root[data-theme=dark]) .danger-zone{ background:#2a1414; border-color:#ef5350; }:where(:root[data-theme=dark]) .opt{ border-color:#333333; }:where(:root[data-theme=dark]) .mode-demo{ background:#0d2a4a; color:#bbdefb; }:where(:root[data-theme=dark]) .mode-real{ background:#b71c1c; }:where(:root[data-theme=dark]) body.real{ border-top-color:#e53935; }:where(:root[data-theme=dark]) :focus-visible{ outline-color:#90caf9; }:where(:root[data-theme=dark]) table td:first-child,:where(:root[data-theme=dark]) table th:first-child{ background:inherit; }:where(:root[data-theme=dark]) table.stack tr{ background:#1e1e1e; border-color:#333333; }:where(:root[data-theme=dark]) table.stack td,:where(:root[data-theme=dark]) table.stack th{ border-bottom-color:#2e2e2e; }:where(:root[data-theme=dark]) table.stack td::before,:where(:root[data-theme=dark]) table.stack th::before{ color:#a8a8a8; }
@media (prefers-color-scheme: dark) and (max-width:600px) {:where(:root:not([data-theme=light])) table td:first-child,:where(:root:not([data-theme=light])) table th:first-child{ background:#1e1e1e; }}
@media (max-width:600px) {:where(:root[data-theme=dark]) table td:first-child,:where(:root[data-theme=dark]) table th:first-child{ background:#1e1e1e; }}
.busy-bar{display:none;position:fixed;top:0;left:0;right:0;z-index:9999;padding:12px 16px;background:var(--accent);color:var(--accent-ink);font-weight:600;text-align:center;box-shadow:0 2px 8px rgba(0,0,0,.3)}html.is-busy button[disabled],html.is-busy input[disabled]{opacity:.55;cursor:progress}html.is-busy body{cursor:progress}
[hidden] { display:none !important; }
.u-ta-l { text-align:left !important; }
.u-lh-1_7 { line-height:1.7 !important; }
.u-fs-11 { font-size:11px !important; } .u-fs-12 { font-size:12px !important; } .u-fs-13 { font-size:13px !important; }
.u-fs-15 { font-size:15px !important; } .u-fs-18 { font-size:18px !important; } .u-fs-20 { font-size:20px !important; }
.u-fs-22 { font-size:22px !important; } .u-fs-26 { font-size:26px !important; }
.u-ls-1 { letter-spacing:1px !important; }
.u-fw-b { font-weight:bold !important; }
.u-ff-inherit { font-family:inherit !important; }
.u-ws-nowrap { white-space:nowrap !important; } .u-ws-pre { white-space:pre-wrap !important; }
.u-break { overflow-wrap:anywhere !important; word-break:break-all !important; }
.u-ib { display:inline-block !important; }
.u-w-100 { width:100% !important; } .u-w-4em { width:4em !important; }
.u-h-200 { height:200px !important; } .u-h-240 { height:240px !important; } .u-h-300 { height:300px !important; }
.u-h-320 { height:320px !important; } .u-h-460 { height:460px !important; }
.u-m-0 { margin:0 !important; } .u-m-tpl { margin:4px 6px 4px 0 !important; } .u-m-b10 { margin:0 0 10px !important; }
.u-mt-8 { margin-top:8px !important; } .u-mt-14 { margin-top:14px !important; } .u-mt-20 { margin-top:20px !important; }
.u-mt-n6 { margin-top:-6px !important; }
.u-mr-14 { margin-right:14px !important; } .u-mr-18 { margin-right:18px !important; }
.u-p-stat { padding:6px 10px !important; }
.u-bl-warn { border-left:6px solid #ef6c00 !important; } .u-bl-off { border-left:6px solid #9e9e9e !important; }
.u-bl-good { border-left:6px solid #2e7d32 !important; } .u-bl-bad { border-left:6px solid #c62828 !important; }
.u-bd-bad { border:2px solid #c62828 !important; }
.u-qr { background:#fff !important; display:inline-block !important; padding:6px !important; }
.u-offscreen { position:absolute !important; left:-5000px !important; }
.u-grid-cards { display:grid !important; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)) !important; gap:8px !important; }
.login{max-width:420px;margin:40px auto}.login label{display:block;margin:10px 0 4px}.login input[type=email],.login input[type=password],.login input[type=text]{width:100%;box-sizing:border-box;padding:10px;font-size:16px}.login button{width:100%;margin-top:14px;padding:12px;font-size:16px}.login button:not(.btn-gray):not(.btn-red){background:var(--accent)!important;color:var(--accent-ink)!important;border:0;border-radius:8px;cursor:pointer}body.viewer form[method=post]:not([action^='/account']),body.viewer form[method=POST]:not([action^='/account']){display:none!important}.pwrap{max-width:980px;margin:0 auto;padding:0 16px}.pwrap .login{max-width:420px;margin:40px auto}.pwrap .login label{display:block;margin:10px 0 4px}.pwrap .login input{width:100%;box-sizing:border-box;padding:10px;font-size:16px}.pwrap .login button{width:100%;margin-top:14px;padding:12px;font-size:16px}.pwrap .btn:not(.btn-blue):not(.btn-red):not(.btn-gray){background:var(--accent);color:var(--accent-ink)}.pf{display:inline-block;margin:4px 10px 4px 0}@media (max-width:600px){.pf{display:block}.pf input{display:block;width:100%;box-sizing:border-box;margin-top:4px}}
/* ===== 토큰 ===== */
:root {
  --bg:#F3F5F8; --surface:#FFFFFF; --surface2:#F0F2F5; --line:#D5DCE4; --line2:#C5CDD6;   /* [10-30 디자인 검수] 카드 경계 1.16 -> 약 1.4:1(테두리), 바탕 한 단계 진하게 */
  --text:#141A21; --text2:#3D4A58; --muted:#5E6B7A;
  --accent:#F2B544; --accent-ink:#15110A; --accent-soft:#FFF4DC; --accent-line:#E2B865; --accent-text:#7A4E00; --link:#8A5A00;
  --pos:#C92A2A; --neg:#1565C0; --ok:#0A7D34; --ok-soft:#E7F6EE; --ok-line:#9FD9B9;
  --bad:#C62828; --bad-soft:#FDECEC; --bad-line:#E8A3A3; --band:#E8ECF2; --band-text:#2B3744;
  --tabbar:#FFFFFF; --shadow:0 1px 3px rgba(20,26,33,.08);
  --on-bad:#FFFFFF; --ctl-line:#7E8A97;
  --font:-apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', sans-serif;
}
@media (prefers-color-scheme: dark) {:root:where(:not([data-theme=light])){
    --bg:#0E1116; --surface:#181E27; --surface2:#212A35; --line:#2F3946; --line2:#3E4959;   /* [10-30 디자인 검수] 카드 바탕 1.09 -> 약 1.15:1·테두리 1.31 -> 약 1.6:1 - '구분이 안 된다' */
    --text:#E8ECF1; --text2:#B4BFCC; --muted:#9AA6B5;
    --accent:#F2B544; --accent-ink:#15110A; --accent-soft:#2A2213; --accent-line:#6B5524; --accent-text:#F7DFA5; --link:#F2B544;
    --pos:#FF6B6B; --neg:#5B9BFF; --ok:#3FCF8E; --ok-soft:#12241C; --ok-line:#2B5D46;
    --bad:#FF8A8A; --bad-soft:#2A1416; --bad-line:#6B2E33; --band:#1E2633; --band-text:#C9D2DD;
    --tabbar:#11161D; --shadow:none;
    --on-bad:#15110A; --ctl-line:#6E7A8C;   /* 바탕(surface2)을 밝힌 만큼 조작 테두리 3:1 유지 */
  }}
:root:where([data-theme=dark]){
    --bg:#0E1116; --surface:#181E27; --surface2:#212A35; --line:#2F3946; --line2:#3E4959;   /* [10-30 디자인 검수] 카드 바탕 1.09 -> 약 1.15:1·테두리 1.31 -> 약 1.6:1 - '구분이 안 된다' */
    --text:#E8ECF1; --text2:#B4BFCC; --muted:#9AA6B5;
    --accent:#F2B544; --accent-ink:#15110A; --accent-soft:#2A2213; --accent-line:#6B5524; --accent-text:#F7DFA5; --link:#F2B544;
    --pos:#FF6B6B; --neg:#5B9BFF; --ok:#3FCF8E; --ok-soft:#12241C; --ok-line:#2B5D46;
    --bad:#FF8A8A; --bad-soft:#2A1416; --bad-line:#6B2E33; --band:#1E2633; --band-text:#C9D2DD;
    --tabbar:#11161D; --shadow:none;
    --on-bad:#15110A; --ctl-line:#6E7A8C;   /* 바탕(surface2)을 밝힌 만큼 조작 테두리 3:1 유지 */
  }

/* ===== 바탕·글자 ===== */
html { background:var(--bg); }
body { background:var(--bg); color:var(--text); font-family:var(--font); -webkit-font-smoothing:antialiased; letter-spacing:-0.1px; }
a { color:var(--link); }
h1 { font-size:20px; font-weight:700; letter-spacing:-0.4px; }
h2 { font-size:17px; font-weight:700; letter-spacing:-0.2px; margin:0 0 10px; }
h3 { font-size:15px; font-weight:700; color:var(--text2); margin:18px 0 8px; }   /* [10-30 디자인 검수] 제목 위계: 카드·섹션 제목 17px > 카드 안 소제목 15px(본문 14px) - 예전 h2 16px·h3 14px 로 항목보다 작았다 */
.card > h3:first-child, .card > h2 + h3 { margin-top:0; }
.muted, .fld .fl { color:var(--muted); }
code { background:var(--surface2); color:var(--text); }
.num, td, th, .stat b { font-variant-numeric:tabular-nums; }
:focus-visible { outline:3px solid var(--link); outline-offset:2px; }

/* ===== 카드 ===== */
.card { background:var(--surface); border:1px solid var(--line); border-radius:14px; box-shadow:var(--shadow); padding:18px; }
@media (max-width:600px) { .card { padding:14px; border-radius:12px; } }
.danger-zone { background:var(--bad-soft); border:1px solid var(--bad-line); border-radius:12px; }
.opt { border-color:var(--line); border-radius:10px; }
details summary { color:var(--text2); }

/* ===== 표 ===== */
th { color:var(--muted); font-weight:600; font-size:12px; }
th, td { border-bottom:1px solid var(--line); padding:9px 6px; }
.row-total { background:var(--surface2); } .row-new { background:var(--accent-soft); }
tr.row-cur, table.stack tr.row-cur { background:var(--ok-soft); }
@media (max-width:600px) {
  table td:first-child, table th:first-child { background:var(--surface); }
  table.stack tr { background:var(--surface2); border:1px solid var(--line); border-radius:12px; }
  table.stack td, table.stack th { border-bottom:1px dashed var(--line); }
  table.stack td::before, table.stack th::before { color:var(--muted); }
  /* [2026-10-18 사용자 휴대폰 화면: "카드 안 맨 밑 버튼이 너무 많은 영역을 차지"] 조작 칸 = 버튼마다 한 줄씩 쌓이고(form 이 block) 44px 버튼이라
     카드 높이의 1/3 을 먹었다 -> 버튼을 한 줄에 나란히(넘치면 줄바꿈), 머리글은 왼쪽, 버튼 높이 40px. 표 카드 전부(공용). */
  table.stack td:has(form), table.stack td:has(> .btn) { display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end; gap:10px 6px; }
  table.stack td:has(form)::before, table.stack td:has(> .btn)::before { float:none; margin-right:auto; max-width:none; }
  table.stack td form, table.stack td form.inline { display:inline-flex !important; flex-wrap:wrap; gap:6px; margin:0 !important; width:auto; }
  table.stack td .btn { min-height:40px; padding:6px 14px; font-size:14px; }
}
/* [2026-10-19 검토 21·22] 긴 글 칸(web_layout 이 class lc) = 줄바꿈 허용. 자리가 있으면 한 줄 그대로, 모자랄 때만 접힌다 -
   휴대폰의 머리글 없는 기록 표(카드 안 455px -> 줄바꿈), PC 의 넓은 표(1,811px -> 카드 폭). 너무 좁게 접히지 않게 최소 10em. */
th.lc, td.lc { white-space:normal; overflow-wrap:anywhere; min-width:10em; }
td.lc form, td.lc .fg { white-space:normal; }
/* [2026-10-19 검토 22] 고객 앱 틀(body.app)은 PC 에서도 가운데 640px 한 줄 - 카드 안쪽 약 600px. 휴대폰 기준(368px)으로 고른 stack 표(9~12칸)가
   PC 에서는 보통 표로 돌아가 카드 안에서 700~1,170px(스프릿 상세·실적·안전 설정, 넘침 25곳) -> 고객 앱에서는 PC 에서도 휴대폰과 같은 줄 카드.
   모양 = dashboard.CSS 휴대폰 규칙(max-width:600px 의 table.stack) + 위 휴대폰 묶음과 같은 값. 운영·관리자 화면(넓은 틀)은 PC 에서 그대로 표. */

/* [2026-11-07 SaaS 점검 4절] 실적 작은 선 그래프(dashboard_perf.spark) = 토큰 색(예전 #e53935·#1e88e5·#999 고정 - 다크 값 없음) */
svg .spk-base { stroke:var(--line2); } svg .spk-pos { stroke:var(--pos); } svg .spk-neg { stroke:var(--neg); }
@media (min-width:601px) {
  body.app table.stack { min-width:0; width:100%; display:block; }
  body.app table.stack thead, body.app table.stack tr.hdr { display:none; }
  body.app table.stack tbody { display:block; }
  body.app table.stack tr { display:block; padding:4px 12px; margin:8px 0; background:var(--surface2); border:1px solid var(--line); border-radius:12px; }
  body.app table.stack td, body.app table.stack th { display:block; overflow:hidden; white-space:normal; text-align:right; border-bottom:1px dashed var(--line); padding:6px 0; position:static; min-width:0; }
  body.app table.stack tr > :last-child { border-bottom:0; }
  body.app table.stack td::before, body.app table.stack th::before { content:attr(data-label); color:var(--muted); font-size:12px; font-weight:normal; text-align:left; float:left; max-width:45%; margin-right:12px; }
  body.app table.stack tr > :first-child { display:block; text-align:left; font-weight:bold; font-size:14px; }
  body.app table.stack tr > :first-child::before, body.app table.stack [data-label=""]::before { display:none; }
  body.app table.stack td.span-msg { text-align:left; }
  body.app table.stack td:has(form), body.app table.stack td:has(> .btn) { display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end; gap:10px 6px; }
  body.app table.stack td:has(form)::before, body.app table.stack td:has(> .btn)::before { float:none; margin-right:auto; max-width:none; }
  body.app table.stack td form, body.app table.stack td form.inline { display:inline-flex !important; flex-wrap:wrap; gap:6px; margin:0 !important; width:auto; align-items:center; }
  body.app table.stack td input:not([type=checkbox]):not([type=radio]), body.app table.stack td select { max-width:100%; min-width:0; box-sizing:border-box; }
  body.app table.stack.rec tr { padding:6px 10px; margin:4px 0; }
  body.app table.stack.rec td, body.app table.stack.rec th { display:inline-block; border:0; padding:1px 12px 1px 0; text-align:left; font-size:13px; max-width:100%; }
  body.app table.stack.rec td::before, body.app table.stack.rec th::before { float:none; content:attr(data-label) " "; margin-right:2px; max-width:none; }
  body.app table.stack.rec tr > :first-child { display:block; font-size:13px; }
}

/* [2026-10-20 디자인 시스템 반응형 '휴대폰 · 태블릿 · PC'] 태블릿(601~1023px) 운영·관리자 화면도 넓은 표(web_layout 이 stack 으로 고른 표) = 줄 카드.
   768px 실측: 26화면·표 64개가 카드 안 가로 넘김(카드 안쪽 351·719px 에 386~1,312px 표). 1024px 부터는 예전처럼 보통 표. 모양 = 위 고객 앱 묶음과 같은 함수. */
@media (min-width:601px) and (max-width:1023px) {
  body:not(.app) table.stack { min-width:0; width:100%; display:block; }
  body:not(.app) table.stack thead, body:not(.app) table.stack tr.hdr { display:none; }
  body:not(.app) table.stack tbody { display:block; }
  body:not(.app) table.stack tr { display:block; padding:4px 12px; margin:8px 0; background:var(--surface2); border:1px solid var(--line); border-radius:12px; }
  body:not(.app) table.stack td, body:not(.app) table.stack th { display:block; overflow:hidden; white-space:normal; text-align:right; border-bottom:1px dashed var(--line); padding:6px 0; position:static; min-width:0; }
  body:not(.app) table.stack tr > :last-child { border-bottom:0; }
  body:not(.app) table.stack td::before, body:not(.app) table.stack th::before { content:attr(data-label); color:var(--muted); font-size:12px; font-weight:normal; text-align:left; float:left; max-width:45%; margin-right:12px; }
  body:not(.app) table.stack tr > :first-child { display:block; text-align:left; font-weight:bold; font-size:14px; }
  body:not(.app) table.stack tr > :first-child::before, body:not(.app) table.stack [data-label=""]::before { display:none; }
  body:not(.app) table.stack td.span-msg { text-align:left; }
  body:not(.app) table.stack td:has(form), body:not(.app) table.stack td:has(> .btn) { display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end; gap:10px 6px; }
  body:not(.app) table.stack td:has(form)::before, body:not(.app) table.stack td:has(> .btn)::before { float:none; margin-right:auto; max-width:none; }
  body:not(.app) table.stack td form, body:not(.app) table.stack td form.inline { display:inline-flex !important; flex-wrap:wrap; gap:6px; margin:0 !important; width:auto; align-items:center; }
  body:not(.app) table.stack td input:not([type=checkbox]):not([type=radio]), body:not(.app) table.stack td select { max-width:100%; min-width:0; box-sizing:border-box; }
  body:not(.app) table.stack.rec tr { padding:6px 10px; margin:4px 0; }
  body:not(.app) table.stack.rec td, body:not(.app) table.stack.rec th { display:inline-block; border:0; padding:1px 12px 1px 0; text-align:left; font-size:13px; max-width:100%; }
  body:not(.app) table.stack.rec td::before, body:not(.app) table.stack.rec th::before { float:none; content:attr(data-label) " "; margin-right:2px; max-width:none; }
  body:not(.app) table.stack.rec tr > :first-child { display:block; font-size:13px; }
}

/* [2026-10-20] PC 앞쪽(1024~1279px): 어림 폭 1,000px 넘는 표(web_layout class xw)만 줄 카드 - 1024px 실측 실적 기록 표 1,059px·관리자 고객 표 1,004px 가 카드 975px 를 넘었다 */
@media (min-width:1024px) and (max-width:1279px) {
  body:not(.app) table.stack.xw { min-width:0; width:100%; display:block; }
  body:not(.app) table.stack.xw thead, body:not(.app) table.stack.xw tr.hdr { display:none; }
  body:not(.app) table.stack.xw tbody { display:block; }
  body:not(.app) table.stack.xw tr { display:block; padding:4px 12px; margin:8px 0; background:var(--surface2); border:1px solid var(--line); border-radius:12px; }
  body:not(.app) table.stack.xw td, body:not(.app) table.stack.xw th { display:block; overflow:hidden; white-space:normal; text-align:right; border-bottom:1px dashed var(--line); padding:6px 0; position:static; min-width:0; }
  body:not(.app) table.stack.xw tr > :last-child { border-bottom:0; }
  body:not(.app) table.stack.xw td::before, body:not(.app) table.stack.xw th::before { content:attr(data-label); color:var(--muted); font-size:12px; font-weight:normal; text-align:left; float:left; max-width:45%; margin-right:12px; }
  body:not(.app) table.stack.xw tr > :first-child { display:block; text-align:left; font-weight:bold; font-size:14px; }
  body:not(.app) table.stack.xw tr > :first-child::before, body:not(.app) table.stack.xw [data-label=""]::before { display:none; }
  body:not(.app) table.stack.xw td.span-msg { text-align:left; }
  body:not(.app) table.stack.xw td:has(form), body:not(.app) table.stack.xw td:has(> .btn) { display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end; gap:10px 6px; }
  body:not(.app) table.stack.xw td:has(form)::before, body:not(.app) table.stack.xw td:has(> .btn)::before { float:none; margin-right:auto; max-width:none; }
  body:not(.app) table.stack.xw td form, body:not(.app) table.stack.xw td form.inline { display:inline-flex !important; flex-wrap:wrap; gap:6px; margin:0 !important; width:auto; align-items:center; }
  body:not(.app) table.stack.xw td input:not([type=checkbox]):not([type=radio]), body:not(.app) table.stack.xw td select { max-width:100%; min-width:0; box-sizing:border-box; }
  body:not(.app) table.stack.xw.rec tr { padding:6px 10px; margin:4px 0; }
  body:not(.app) table.stack.xw.rec td, body:not(.app) table.stack.xw.rec th { display:inline-block; border:0; padding:1px 12px 1px 0; text-align:left; font-size:13px; max-width:100%; }
  body:not(.app) table.stack.xw.rec td::before, body:not(.app) table.stack.xw.rec th::before { float:none; content:attr(data-label) " "; margin-right:2px; max-width:none; }
  body:not(.app) table.stack.xw.rec tr > :first-child { display:block; font-size:13px; }
}

/* [2026-10-19 검토 24] 끊을 곳 없는 긴 글(키 해시·주소)이 카드 밖으로(관리자 '같은 키 공유 중' 422/362px) - 넘칠 때만 끊는다 */
.card p, .card li { overflow-wrap:break-word; }
/* [2026-10-20 디자인 시스템 '글 - 문단 나누기'] 긴 설명을 문단·목록으로 나눈 뒤의 간격 한 벌: 문단 사이 8px, 목록 줄 사이 4px,
   설명 상자(.note·.warnbox·.disclaimer) 안 첫·끝 여백 0. 번호 목록(ol)도 ul 과 같은 들여쓰기·글자 크기. */
ol { padding-left:20px; font-size:13px; margin:6px 0; }
li { line-height:1.55; } li + li { margin-top:4px; }
.card p { margin:0 0 8px; } .card p:last-child { margin-bottom:0; }
.note p, .warnbox p, .disclaimer p { margin:0 0 6px; } .note p:last-child, .warnbox p:last-child, .disclaimer p:last-child { margin-bottom:0; }
.note ul, .note ol, .warnbox ul, .warnbox ol { margin:4px 0 0; font-size:inherit; }
/* [2026-10-19 검토 24] 한 줄 숫자 타일 표(web_layout 이 class tiles - 관리자 '오늘 할 일'·'고객 현황', 파트너) = 줄바꿈되는 상자 */
table.tiles, table.tiles > tbody { display:block; min-width:0; width:100%; }
table.tiles tr { display:flex; flex-wrap:wrap; gap:6px; }
table.tiles td, table.tiles td:first-child { flex:1 1 8.5em; min-width:0; white-space:normal; position:static; text-align:left;
  background:var(--surface2); border:0; border-radius:10px; }
/* [2026-11-05 사용자: "상단 메뉴 한칸 스와이프로"] 관리자 메뉴도 휴대폰에서 한 줄 가로 스와이프(고객·운영 화면과 같은 nav 규칙) -
   예전(10-19 검토 24) 관리자만 줄바꿈해 메뉴 7개가 두 줄(알약 2줄 = 약 240px)로 본문을 밀어냈다.
   고정 위치 = 위 모드 띠 높이(12px 글자 + 위아래 6px = 28px, 한 줄 고정) - 예전 띠(36px) 기준 top:36px 이라 내리면 띠와 메뉴 사이 8px 로 본문 글자가 비쳤다. 띠 없는 화면 = 0 */
@media (max-width:600px) { .mode-band { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } nav { top:28px; } body:not(:has(.mode-band)) nav { top:0; } }
/* [2026-10-19 검토 23] 로그인 없는 틀(.login 420px)에 넓은 표가 있으면(공개 실적·공유 실적) PC 에서 틀을 넓힌다 - 420px 카드 안 540px 표 */
.login:has(table.stack) { max-width:min(760px, 100%); }
/* [2026-10-19 검토 29] 손가락 높이 44px - 링크만 있는 줄(web_layout p.lnk-row)·서비스 칩·제목 줄 링크·구간 선택·접기 카드 제목·고지 줄 링크·타일 링크 */
@media (pointer:coarse) {
  p.lnk-row > a { display:inline-flex; align-items:center; min-height:44px; box-sizing:border-box; }
  .chip { display:inline-flex; align-items:center; min-height:44px; box-sizing:border-box; }
  .sec a, .seg a { display:inline-flex; align-items:center; justify-content:center; min-height:44px; box-sizing:border-box; padding-top:0; padding-bottom:0; }
  body details.card > summary { padding:11px 0; }   /* 아래 details.card > summary(2px)보다 뒤에 와도 이기게 body 를 붙였다 */
  .top-user summary { min-height:44px; box-sizing:border-box; }
  .top-user .menu a { min-height:44px; box-sizing:border-box; display:flex; align-items:center; }
  td.u-p-stat a { display:inline-flex; align-items:center; min-height:44px; }
}

/* ===== 손익·상태 색 ===== */
.pos, .up { color:var(--pos); } .neg, .dn { color:var(--neg); }
.ok { color:var(--ok); } .bad { color:var(--bad); }

/* ===== 배지·꼬리표 ===== */
.tag { background:var(--surface2); color:var(--text2); border:1px solid var(--line); border-radius:99px; padding:1px 8px; }
.tag-warn { background:var(--accent-soft); color:var(--accent-text); border-color:var(--accent-line); }
.badge { border-radius:99px; padding:2px 9px; font-weight:600; }
.badge-mock { background:var(--band); color:var(--band-text); }
.badge-real { background:var(--bad); color:var(--on-bad); }
.badge-err { background:var(--accent-soft); color:var(--accent-text); }
.badge-admin { background:#37474f; color:#fff; }

/* ===== 버튼 ===== */
.btn { border-radius:10px; padding:8px 14px; font-size:13px; font-weight:600; border:1px solid transparent; font-family:inherit; text-align:center; justify-content:center; }   /* [2026-10-20 사용자: 로그인 버튼 글자가 왼쪽] 버튼 글자 = 늘 가운데(넓은 버튼·flex 버튼 포함) */
.btn-blue { background:var(--accent); color:var(--accent-ink); border-color:var(--accent); }
.btn-blue:hover { filter:brightness(1.05); }
.btn-gray, .btn:not(.btn-blue):not(.btn-red):not(.btn-gray) { background:transparent; color:var(--text); border:1px solid var(--ctl-line); }
.btn-red { background:transparent; color:var(--bad); border:1px solid var(--bad-line); }
.login button:not(.btn-gray):not(.btn-red) { background:var(--accent) !important; color:var(--accent-ink) !important; border-radius:10px; font-weight:700; }

/* ===== 입력 ===== */
input, select, textarea { background:var(--surface2); color:var(--text); border:1px solid var(--ctl-line); border-radius:10px; padding:8px 10px; }
input:focus, select:focus, textarea:focus { border-color:var(--link); outline:none; }
/* [2026-11-12] 날짜 칸 = 크롬 기본 안쪽 여백(위아래 1px)으로 옆 글자 칸보다 2px 높았다(PC 35 vs 37, 새 스프릿 7단계 예약 가격·만료일) */
input[type=date]::-webkit-datetime-edit-fields-wrapper { padding-top:0; padding-bottom:0; }
/* [2026-10-20 디자인 시스템 반응형 'PC 에서 늘어짐'] 1280px 실측: 키 입력 칸 1,195px·안전 설정 칸 659px, 스프릿 버튼 줄 1,233px·위험 구역 1,195px,
   주문 확인 버튼 줄 1,210px - 넓은 틀(운영·관리자)에서 한 줄 칸이 화면 끝까지 늘어났다. 입력 = 최대 28em, 주 조작 묶음 = 최대 app-width(640px).
   휴대폰·고객 앱(640px 틀)에서는 이미 그보다 좁아 바뀌는 것이 없다. 체크·라디오·숨은 칸은 대상 아님. */
input:not([type=checkbox]):not([type=radio]), select, textarea { max-width:28em; }
.btn-row, .btn-wide, .danger-zone, .card.review { max-width:640px; box-sizing:border-box; }
/* [2026-10-20 디자인 시스템 반응형 - PC 1024px 이상 '넓은 표가 카드 안에 다 들어감'] 1280px 실측 남은 넘김 2가지:
   ① 코인·바이낸스 화면의 두 칸 격자(.grid, 최소 320px) 카드 607px 안에 571~635px 표 -> 격자 칸 최소 640px(1,280px 에서 한 줄, 1,300px 넘으면 두 칸)
   ② 실적 화면의 조작 없는 긴 기록 표(rec) 1,312px -> PC 에서는 기록 표 칸 줄바꿈 허용(숫자는 붙어 있어 갈라지지 않는다) */
.grid { grid-template-columns:repeat(auto-fit, minmax(min(100%, 640px), 1fr)); }
@media (min-width:1024px) { body:not(.app) table.stack.rec td, body:not(.app) table.stack.rec th { white-space:normal; } }
/* [2026-10-20] 비상 손절 한 칸: 방식에 따라 단위(% / 원·USD) - 서버 HTML 에 둘 다 두고 CSS 로 하나만 */
.stopf { display:inline-flex; flex-wrap:wrap; align-items:center; gap:6px; }
.stopf .u-px { display:none; }
.stopf:has(option[value=price]:checked) .u-px { display:inline; }
.stopf:has(option[value=price]:checked) .u-pct { display:none; }
/* [2026-10-20 휴대폰 지적 "셀렉트 디자인은 못 바꾸나" / "이쁘게"] 선택 창 = CSS 만(appearance:base-select, 크롬 135+). 지원 안 하는 브라우저는
   예전 시스템 창 그대로(@supports) - 그린 뒤 고치는 스크립트 없음. 여러 줄 목록(multiple·size)은 대상 아님. */
@supports (appearance: base-select) {
  select:not([multiple]):not([size]), ::picker(select) { appearance:base-select; }
  select:not([multiple]):not([size]) { display:inline-flex; align-items:center; gap:8px; min-height:40px; cursor:pointer; }
  select:not([multiple]):not([size])::picker-icon { color:var(--muted); transition:rotate .15s; }
  select:not([multiple]):not([size]):open { border-color:var(--link); }
  select:not([multiple]):not([size]):open::picker-icon { rotate:180deg; }
  ::picker(select) { background:var(--surface); color:var(--text); border:1px solid var(--line2); border-radius:14px; padding:6px; margin-block:6px;
    box-shadow:0 14px 36px rgba(0,0,0,.38); max-height:min(60vh, 440px); max-width:calc(100vw - 24px); overflow-y:auto; }
  select:not([multiple]):not([size]) option { padding:11px 12px; border-radius:10px; line-height:1.35; gap:10px; }
  select:not([multiple]):not([size]) option + option { margin-top:2px; }
  select:not([multiple]):not([size]) option:hover, select:not([multiple]):not([size]) option:focus-visible { background:var(--surface2); outline:none; }
  select:not([multiple]):not([size]) option:checked { background:var(--accent-soft); color:var(--accent-text); font-weight:600; }
  select:not([multiple]):not([size]) option::checkmark { color:var(--accent); }
  select:not([multiple]):not([size]) option[value=''] { color:var(--muted); }
  select:not([multiple]):not([size]) optgroup { color:var(--muted); font-size:12px; font-weight:600; padding:8px 12px 2px; }
}
input[type=checkbox], input[type=radio] { accent-color:var(--accent); }

/* ===== 알림 띠 ===== */
.flash { border-radius:12px; border:1px solid transparent; }
.flash-ok { background:var(--ok-soft); color:var(--ok); border-color:var(--ok-line); }
.flash-err { background:var(--bad-soft); color:var(--bad); border-color:var(--bad-line); }
/* [2026-10-18 사용자: "맨 하단의 글자는 색상을 줘야 하지 않을까"] 투자 위험 고지 = 경고색(호박색 띠) - 회색이면 그냥 지나친다 */
.disclaimer { background:var(--accent-soft); color:var(--accent-text); border:1px solid var(--accent-line); border-radius:12px;
  font-size:12px; line-height:1.6; padding:12px 14px; margin:24px 0 0; }
.disclaimer a { color:var(--accent-text); font-weight:600; }
/* 공통 링크 터치 여백(14px 위아래)이 고지 줄 간격을 벌렸다 -> [2026-10-19 검토 29] 여백 대신 링크 상자만 44px(고지 끝의 '사용자 매뉴얼' 한 줄만 높아진다) */
@media (pointer:coarse) { .disclaimer a { display:inline-flex !important; align-items:center; min-height:44px; padding:0 !important; vertical-align:middle; } }

/* ===== 모드 띠·제목 줄·메뉴 ===== */
.mode-band { font-weight:500; font-size:12px; text-align:center; padding:6px 16px; }
.mode-demo { background:var(--band); color:var(--band-text); }
.mode-real { background:var(--bad); color:var(--on-bad); font-weight:700; }
.mode-admin { background:#263238; color:#ECEFF1; }
body.real { border-top:0; }
.topbar h1 { font-size:17px; }
.top-user summary { border-color:var(--ctl-line); color:var(--text2); }
/* [2026-11-01 412px 관리자 화면] 계정 칩의 긴 이메일이 로고 글자('Auto Trading Syst…')를 밀어 잘랐다 -> 로고는 줄지 않고, 이메일이 말줄임 */
.topbar > h1 { flex:0 0 auto; } .topbar > .top-user { min-width:0; }
.top-user .uid { display:inline-block; max-width:10em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; vertical-align:bottom; }
@media (max-width:480px) { .top-user .uid { max-width:6.5em; } }
.top-user .menu { background:var(--surface); border-color:var(--line); }
.top-user .menu a + a { border-top-color:var(--line); }
nav a { background:var(--surface); color:var(--text2); border:1px solid var(--line); box-shadow:none; border-radius:99px; }
nav a.on { background:var(--accent); color:var(--accent-ink); border-color:var(--accent); font-weight:600; }
@media (max-width:600px) { nav { background:var(--bg); } }
.tabs a { color:var(--muted); }
.tabs a.on-demo { color:var(--text); border-color:var(--link); }
.tabs a.on-real { color:var(--bad); border-color:var(--bad); }
/* [10-30 사용자 캡처] 탭 개수 = 동그라미 안 숫자, 제목 옆 보조 글 = 제목과 간격 */
.tabs a .cnt, .cnt { display:inline-flex; align-items:center; justify-content:center; min-width:22px; height:22px; padding:0 6px; margin-left:6px; border-radius:11px; background:var(--surface2); color:var(--text); font-size:12px; font-weight:700; line-height:1; vertical-align:middle; box-sizing:border-box; }
.tabs a.on-demo .cnt { background:var(--accent); color:#111; }
@media (min-width:1024px) { .tabs:not(.svc-tabs) { display:flex; flex-wrap:wrap; column-gap:2px; } .tabs:not(.svc-tabs) a { margin:10px 0; padding:6px 10px; font-size:15px; white-space:nowrap; } }   /* [10-30 재검수 3차] PC 1120px 안에서 탭 9개(스프릿 서비스)가 두 줄로 넘쳤다 */
h2.h-cnt { display:flex; align-items:center; flex-wrap:wrap; gap:6px 10px; } h2.h-cnt > .muted { font-size:13px; font-weight:400; } h2.h-cnt > form { margin-left:auto; }
/* [10-31 사용자 캡처 '제목 옆에 바로 할 일 0·답변 대기 0이 붙어 있음'] 모든 제목 뒤 흐린 보조 글(건수·기간·안내) = 간격 8px·작은 보통 굵기 - 알림함(h-cnt)만 고쳐져 있었다 */
h2 > span.muted, h3 > span.muted, .sec h2 > span.muted { margin-left:8px; font-size:13px; font-weight:400; letter-spacing:0; } h2.h-cnt > span.muted { margin-left:0; }

/* ===== 고객 앱 틀 (body.app) - 가운데 한 줄 + 아래 탭 ===== */
body.app { padding:0 0 calc(76px + env(safe-area-inset-bottom)); }
body.app .app-main { max-width:640px; margin:0 auto; padding:0 16px; }
.app-main { max-width:1120px; margin:0 auto; }
@media (min-width:1152px) { body:not(.app) > .topbar, body:not(.app) > nav { max-width:1120px; margin-left:auto; margin-right:auto; } }   /* [10-30 재검수 3차] 헤더·메뉴 줄도 본문과 같은 왼쪽 선 */   /* [10-30 디자인 검수] PC 1280px 에서 카드가 1,233px 로 늘어 이름표와 숫자가 1,100px 떨어졌다 */
.warn-t { color:var(--accent-text); font-weight:600; }
/* [10-30 사용자 '선택은 두 번 눌러야 함'] 선택지가 적은 칸 = 버튼 모양 라디오(web_list.pick) - 한 번 누르면 끝 */
.pick { display:flex; flex-wrap:wrap; gap:6px; width:100%; }
.pick .pk { flex:1 1 0; min-width:0; margin:0; position:relative; cursor:pointer; }
.pick .pk input { position:absolute !important; opacity:0; width:1px !important; height:1px !important; min-height:0 !important; margin:0 !important; pointer-events:none; }
.pick .pk span { display:flex; align-items:center; justify-content:center; text-align:center; min-height:44px; padding:4px 10px; box-sizing:border-box; border:1px solid var(--ctl-line); border-radius:10px; color:var(--text2); font-size:14px; line-height:1.3; }
.pick .pk input:checked + span { border-color:var(--link); color:var(--link); background:var(--accent-soft); font-weight:600; }
.pick .pk input:focus-visible + span { outline:2px solid var(--link); outline-offset:2px; }
.pick.g2 { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); }
.pick.sm { display:inline-flex; width:auto; flex-wrap:nowrap; vertical-align:middle; } .pick.sm .pk { flex:none; } .pick.sm .pk span { min-height:40px; padding:4px 12px; }
.stopf:has(input[value=price]:checked) .u-px { display:inline; } .stopf:has(input[value=price]:checked) .u-pct { display:none; }
/* [10-30 사용자 '선택 버튼이 한 칸인데 꽉 채워지지 않는 부분'] 비상 손절 = 방식 버튼 둘이 한 줄 전체, 아래 줄 값 칸이 남는 폭 + 단위 */
.stopf { display:flex !important; flex-wrap:wrap; width:100%; } .stopf > .pick.sm { display:flex; flex:1 1 100%; width:100%; } .stopf > .pick.sm .pk { flex:1 1 0; }
.stopf > input { flex:1 1 auto; min-width:0; max-width:none; }
#sf > button.btn, #sf > p > button.btn { display:flex; width:100%; max-width:640px; justify-content:center; min-height:48px; }   /* 스프릿 만들기 '확인' = 세로 폼 끝 주 버튼(form-col 과 같게) */
/* [10-30 사용자 판단 요청] 세로로 쌓인 글쓰기 폼(form-col: 문의·전략 요청) = 칸과 마지막 주 버튼 모두 한 줄 전체, 폼 폭 640px - 작은 버튼이 왼쪽에 떨어져 보였다 */
form.form-col { max-width:640px; } form.form-col > p > select, form.form-col > p > input, form.form-col > p > textarea, form.form-col > textarea { width:100%; box-sizing:border-box; max-width:none; }
form.form-col > .btn { display:flex; width:100%; justify-content:center; min-height:48px; margin-top:4px; }
/* [2026-11-06 사용자: "어떤 버튼은 한줄(100%) 이고 어떤 버튼은 글자에 맞게"] 세로 입력 폼(vform: 비밀번호 변경·키 저장·지문 등록·전부 멈춤·백테스트·고객 등록) =
   입력칸과 마지막 주 버튼이 같은 폭(최대 640px). 입력 없는 단독 보조 버튼(모두 로그아웃·삭제·다시 확인)은 글자 폭 그대로. 글이 여러 줄인 한 줄 폼(textarea) 주 버튼도 같게 */
.vform { max-width:640px; }
.vform > p > input:not([type=hidden]):not([type=checkbox]):not([type=radio]), .vform > p > select { width:100%; max-width:none; box-sizing:border-box; }
.vform > .btn, .vform > p > .btn:only-child, .vform > p.btn-line > .btn:only-child, .vform .pk-box > .btn, form.inline:has(> textarea) > .btn
  { display:flex; width:100%; justify-content:center; min-height:48px; }
.vform > .btn + p { margin-top:8px; } .vform + p { margin-top:12px; } .pk-msg:empty { display:none; }
/* [10-31 관리자 검수] 세로 폼은 칸이 문단(p) 없이 바로 와도 같은 모양 - 관리자 추가 폼 칸이 반 폭·칸 사이 간격 0이었다(공용 form.filter 가 겹쳐 붙어도 세로 유지) */
form.form-col { display:flex !important; flex-direction:column; align-items:stretch; gap:10px; flex-wrap:nowrap !important; }
form.form-col > input:not([type=hidden]), form.form-col > select, form.form-col > .fg, form.form-col > .fg > input, form.form-col > .fg > select { width:100%; max-width:none; box-sizing:border-box; flex:0 0 auto !important; }
form.form-col > .fg-act, form.form-col > .fg-act > .btn { width:100%; justify-content:center; } form.form-col > p { margin:0; } form.form-col > label.chk { display:flex; align-items:center; gap:8px; }
/* [2026-10-31 사용자 캡처 "디자인 확인" - 스프릿 위험 관리: 한 줄 인라인 폼이 접혀 '위험 설정 저장'이 '지정 가격' 위에 겹침, '매도 후' 이름표만 떨어짐]
   세로 폼 줄(frow) = 이름표(fl) 위 + 칸 묶음(fc) 아래. 칸 묶음 안 버튼 모양 선택은 한 줄 전체, 입력은 남는 폭(단위 글자는 옆) */
form.form-col > .frow { display:flex; flex-direction:column; gap:6px; } form.form-col > .frow > .fl { font-size:13px; color:var(--muted); font-weight:600; }
form.form-col > .frow > .fc, form.form-col > .frow .stopf { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
form.form-col > .frow .pick { flex:1 1 100%; display:flex; } form.form-col > .frow .pick .pk { flex:1 1 0; justify-content:center; }
form.form-col > .frow input:not([type=hidden]):not([type=radio]) { flex:1 1 140px; min-width:0; max-width:none; width:auto; }
form.form-col + p, form.form-col + .btn-line { margin-top:12px; }   /* 세로 폼 뒤 안내 글·단추 줄 = 주 버튼에 붙지 않게 */
/* '선택(버튼 모양) + 버튼' 폼 = 한 줄(연장 개월 + 연장) - 360px 에서 버튼이 다음 줄로 떨어졌다 */
form:has(> .pick.sm):not(.form-col):not(:has(input:not([type=hidden]):not([type=radio]))):not(:has(select)) { display:flex !important; flex-wrap:nowrap; align-items:center; gap:8px; } form:has(> .pick.sm):not(.form-col):not(:has(input:not([type=hidden]):not([type=radio]))):not(:has(select)) > .pick.sm { flex:1 1 auto; display:flex; } form:has(> .pick.sm):not(.form-col):not(:has(input:not([type=hidden]):not([type=radio]))):not(:has(select)) > .pick.sm .pk { flex:1 1 0; }
form:has(> .pick.sm):not(.form-col):not(:has(input:not([type=hidden]):not([type=radio]))):not(:has(select)) > .btn, form:has(> .pick.sm):not(.form-col):not(:has(input:not([type=hidden]):not([type=radio]))):not(:has(select)) > .fg-act { flex:0 0 auto; margin:0; }
/* [2026-11-08 사용자 캡처 '디자인 확인' - 관리자 고객 상세] 단추·선택 칩·접는 줄 제목 = 낱말 단위 줄바꿈('지문·얼굴 로그인 초기 / 화', '소유 / 자' 금지),
   이메일처럼 띄어쓰기 없는 긴 글은 넘칠 때만 아무 데서나 */
.btn, button, .pick .pk span, summary, .xs { word-break:keep-all; overflow-wrap:anywhere; }
form.btn-line + .card { margin-top:12px; }   /* [11-08] 카드 밖 단추 줄(보유 수량 정정 '잔고 조회') 다음 카드 = 붙지 않게(정렬 규칙 '버튼 위아래 붙음 금지') */
.pick .pk .pk-t { font-style:normal; } .pick .pk .pk-p { white-space:nowrap; font-style:normal; }   /* 칩 글의 붙은 괄호 묶음 = 한 덩어리(web_list._chip) */
/* 휴대폰: '선택 칩 셋 이상 + 단추' 폼 = 칩이 한 줄 전체, 단추는 다음 줄 전체(칩이 단추 옆에 끼어 '고객 / 관리자 / (조작 / 가능)' 4줄로 접혔다). 칩 둘 + 단추(연장 개월 + 연장)는 한 줄 그대로 */
@media (max-width:600px) {
  form:has(> .pick.sm > .pk:nth-child(3)):not(.form-col):not(:has(input:not([type=hidden]):not([type=radio]))):not(:has(select)) { flex-wrap:wrap; }
  form:has(> .pick.sm > .pk:nth-child(3)):not(.form-col):not(:has(input:not([type=hidden]):not([type=radio]))):not(:has(select)) > .pick.sm { flex:1 1 100%; }
  form:has(> .pick.sm > .pk:nth-child(3)):not(.form-col):not(:has(input:not([type=hidden]):not([type=radio]))):not(:has(select)) > .btn { flex:1 1 100%; }
}
/* 좁은 폰(400px 이하) 표 칸 스위치 = 모양만(켬/끔 글자는 머리 '모의·실전'과 색으로) - 전략 공개 표가 360px 에서 51px 넘쳤다 */
@media (max-width:400px) { table td .sw .sw-on, table td .sw .sw-off, table td .btn-sw .sw-t { display:none; } table.nostack th, table.nostack td { padding-left:6px; padding-right:6px; } table.nostack td { overflow-wrap:anywhere; white-space:normal; min-width:0 !important; }   /* 첫 칸 최소 117px·나머지 칸 nowrap 이 360px 에서 표를 카드 여백까지 밀었다 */ table.nostack td .muted { font-size:12px; } }
ol.steps-ol { margin:8px 0 12px; padding-left:20px; font-size:13px; color:var(--text2); } ol.steps-ol li { margin:4px 0; } ol.steps-ol b { color:var(--text); }   /* [10-30] 진행 순서 = 짧은 번호 목록(전략 요청) */
/* [10-30 재검수] 펼침 표시 한 가지 = 갈매기(브라우저 기본 ▸ 와 목록 줄 ⌄ 가 섞였다) - 접힌 칸 제목 앞 */
details:not(.xrow) > summary { list-style:none; cursor:pointer; }
details:not(.xrow) > summary::-webkit-details-marker { display:none; }
details:not(.xrow) > summary::before { content:''; display:inline-block; width:6px; height:6px; border-right:2px solid var(--text2); border-bottom:2px solid var(--text2); transform:rotate(-45deg); margin:0 10px 2px 2px; transition:transform .15s; vertical-align:middle; }
details:not(.xrow)[open] > summary::before { transform:rotate(45deg); margin-bottom:4px; }
.topbar details > summary::before { content:none !important; display:none !important; }   /* 헤더(topbar) 계정 메뉴는 제 표시(▾)가 있다 */
/* 숫자·단위·짧은 단추 글자는 줄이 갈리지 않게('4,899,998 / 원', '체결가 / 286.07', '연 / 장') */
.kpi-mid, .kpi-big, .nw { white-space:nowrap; } .todo > b, .todo > span:last-child { flex:none; white-space:nowrap; }
.badge-count { background:var(--text); color:var(--bg); border-color:transparent; } nav a .badge-count, .tabs a .badge-count { margin-left:6px; }   /* 메뉴가 flex 일 때 글자 뒤 띄어쓰기가 사라져 '알림1393'으로 붙었다 */   /* [10-30 디자인 검수] 메뉴 알림 개수 = 중립(호박 알약 안 빨강 = 오류처럼 보였다) */
/* [10-30] 주식 서비스 탭 4개 = 같은 폭 칸, 이름 두 줄(증권사 / (국내·해외)) */
.app-main:has(> .tabs:first-child) { padding-top:4px; } @media (pointer:coarse) { .app-main:has(> .tabs:first-child) { padding-top:0; } } .app-main > .tabs:first-child a { margin-top:0 !important; }   /* [11-13 사용자 "상단 메뉴와 탭 메뉴 사이 공간이 넓어 조정"] 메뉴 줄 바로 아래 탭 = 위 여백 24~28px -> 10px(본문 위 4 + 탭 안 6) */
.tabs.svc-tabs { display:grid; grid-template-columns:repeat(auto-fit, minmax(0, 1fr)); max-width:640px; }
.tabs.svc-tabs a { margin:6px 0 0 !important; padding:6px 2px 8px !important; text-align:center; line-height:1.25; white-space:nowrap; display:flex; flex-direction:column; align-items:center; justify-content:center; }
.tabs.svc-tabs a small { display:block; font-size:11px; color:inherit; opacity:.85; }   /* 할 일 상태 글자(키 필요 등) - 오류(bad)와 구분 */
body.app .mode-band { margin:0; position:sticky; top:0; z-index:20; }
:target { scroll-margin-top:96px; }   /* [2026-10-20] '#auto-hold' 같은 이동 = 위에 붙은 띠·메뉴에 제목이 가리지 않게 */
body.app .topbar { max-width:640px; margin:0 auto; padding:14px 16px 6px; box-sizing:border-box; }
body.app .topbar h1 { font-size:20px; }
body.app nav.app-sub { display:flex; gap:6px; overflow-x:auto; padding:2px 0 10px; }
body.app .disclaimer { max-width:608px; margin:24px auto 0; box-sizing:border-box; }
@media (max-width:640px) { body.app .disclaimer { margin:24px 16px 0; } }
.tabbar { position:fixed; left:0; right:0; bottom:0; top:auto; z-index:30; display:flex; justify-content:center;
  background:var(--tabbar); border-top:1px solid var(--line); padding:4px 4px calc(8px + env(safe-area-inset-bottom)); }
.tabbar .tb { flex:1; max-width:128px; display:flex; flex-direction:column; align-items:center; gap:3px; padding:8px 0 4px;
  font-size:11px; color:var(--muted); text-decoration:none; min-height:44px; box-sizing:border-box; position:relative; }
.tabbar .tb svg { width:22px; height:22px; }
.tabbar .tb.on { color:var(--link); font-weight:600; }   /* 밝은 화면에서 호박색 글자는 대비 1.8:1 - 링크색(어두운 화면 = 호박색) */
.tabbar .tb .dot { position:absolute; top:4px; left:calc(50% + 6px); min-width:16px; height:16px; border-radius:99px; background:var(--bad);
  color:var(--on-bad); font-size:10px; line-height:16px; text-align:center; padding:0 4px; box-sizing:border-box; }

/* ===== 고객 앱 컴포넌트 ===== */
.app-title { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; margin:6px 0 12px; }
.app-title h2 { margin:0; font-size:18px; }
.status { display:flex; align-items:center; gap:8px; border-radius:12px; padding:11px 14px; font-size:13px; margin:0 0 12px;
  background:var(--ok-soft); border:1px solid var(--ok-line); color:var(--text2); }
.status b { color:var(--ok); flex:none; white-space:nowrap; }   /* [10-21] 긴 중단 글 옆에서 '중단'이 '중/단' 세로로 꺾였다 */
.status .sd { width:8px; height:8px; border-radius:99px; background:var(--ok); flex:none; }
/* [2026-11-01 사용자 '홈·주식 탭 정상 문구와 보조 문구 위치가 다름'] 보조 글이 길어(주식 '… 최근 7일 주문 오류 0건') 큰 글씨 휴대폰에서 두 줄로 접히면
   가운데 정렬 때문에 '정상'·점이 두 줄 가운데로 내려가 한 줄짜리 서비스와 자리가 달랐다 -> 첫 줄 기준 위 정렬(점은 첫 줄 가운데) */
.status { align-items:flex-start; line-height:1.5; } .status > .sd { margin-top:calc(0.75em - 4px); } .status > span:not(.sd) { min-width:0; }
.status.st-bad { background:var(--bad-soft); border-color:var(--bad-line); } .status.st-bad b { color:var(--bad); } .status.st-bad .sd { background:var(--bad); }
.status.st-warn { background:var(--accent-soft); border-color:var(--accent-line); } .status.st-warn b { color:var(--accent-text); } .status.st-warn .sd { background:var(--accent); }
.kpi-big { font-size:30px; font-weight:700; letter-spacing:-0.6px; font-variant-numeric:tabular-nums; line-height:1.15; }
.kpi-mid { font-size:16px; font-weight:600; font-variant-numeric:tabular-nums; }
.kpi-lab { font-size:12px; color:var(--muted); }
.kpi-row { display:flex; justify-content:space-between; align-items:flex-end; gap:12px; }
.kpi-head { margin-bottom:2px; display:flex; justify-content:space-between; align-items:baseline; gap:8px; flex-wrap:wrap; }   /* [11-13] 서비스 요약 이름 | 기준 시각 한 줄 */
.kpi-grid { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:8px; margin-top:12px; }
.kpi-grid3 { grid-template-columns:repeat(3, minmax(0,1fr)); }
/* [2026-11-01 사용자 캡처 "보유 원가·평가손익·합산손익 제목과 값이 왼쪽 정렬 - 중앙 정렬과 비교"] 같은 폭 세 칸(짧은 제목 + 숫자 하나) = 가운데 정렬. 두 칸 요약(긴 값·설명)은 왼쪽 그대로 */
.kpi-grid > .kpi-cell:not(.wide) { text-align:center; }   /* [11-13 사용자 "서비스 요약 중앙 두칸 영역도 중앙 정렬"] 2칸·3칸 요약 칸 모두 가운데(예전 3칸만), 긴 글 칸(.wide)은 왼쪽 */
.kpi-grid + p, .kpi-grid + .muted { margin-top:10px; }   /* [11-01 1440px 확인] 요약 칸 바로 밑 설명 글이 칸에 붙어 있었다(간격 0) */
.kpi-grid > .kpi-cell:only-child { grid-column:1 / -1; }   /* [10-30 디자인 검수] 칸 하나면 줄 전체(반쪽 상자 + 빈 오른쪽이었다) */
.kpi-cell { background:var(--surface2); border-radius:10px; padding:10px 12px; }
.kpi-cell .kpi-mid { font-size:14px; margin-top:3px; }
.kpi-cell .kpi-txt { margin-top:3px; overflow-wrap:anywhere; }   /* [10-31 서비스 요약] 숫자가 아닌 칸(계좌 확인·코인 지갑) = 줄 전체·줄바꿈 */
.kpi-cell.wide { grid-column:1 / -1; }
.kpi-row > div:first-child { min-width:0; }
.cmp { border-top:1px solid var(--line); margin-top:14px; padding-top:12px; display:flex; flex-direction:column; gap:8px; font-size:13px; }
.cmp-row { display:flex; align-items:center; gap:10px; }
.cmp-row .cl { width:92px; color:var(--text2); }
.cmp-row .cb { flex:1; height:8px; background:var(--surface2); border-radius:99px; overflow:hidden; }
.cmp-row .cb i { display:block; height:8px; }
.cmp-row .cb i.pos { background:var(--pos); } .cmp-row .cb i.neg { background:var(--neg); }
.cmp-row .cv { width:64px; text-align:right; font-variant-numeric:tabular-nums; }
.todo { display:flex; justify-content:space-between; align-items:center; gap:10px; border-radius:12px; padding:13px 14px; margin:0 0 12px;
  background:var(--accent-soft); border:1px solid var(--accent-line); color:var(--accent-text); text-decoration:none; font-size:14px; }
.todo:hover { filter:brightness(1.04); }
.sec { display:flex; justify-content:space-between; align-items:center; margin:22px 0 4px; }
.sec h2 { margin:0; font-size:17px; }
.card > .sec:first-child, .card > div:empty:first-child + .sec { margin-top:0; }   /* [2026-10-21] 카드 첫 머리(앞에 빈 이동 표시 div 가 있어도) 위 빈칸 없음 */
.sec a { font-size:14px; text-decoration:none; padding:8px 0; }
.lrow { display:flex; justify-content:space-between; align-items:center; gap:12px; padding:13px 2px; border-top:1px solid var(--line);
  color:var(--text); text-decoration:none; }
.lrow:first-child { border-top:0; }
.lrow .lt { font-size:15px; font-weight:600; }
/* [2026-11-01 사용자 "한 종목을 여러 전략·스프릿이 보유하면 어떻게 표현되지"] 같은 종목 묶음 = 종목 한 줄(합계) + 들여 쓴 전략·스프릿 줄 */
.lgrp { border-top:1px solid var(--line); } .list > .lgrp:first-child { border-top:0; } .lgrp > .lrow.lgh { border-top:0; padding-bottom:6px; }
.lgrp > .lrow.lsub { border-top:0; padding:7px 2px 7px 14px; margin-left:4px; border-left:2px solid var(--line); } .lgrp > .lrow.lsub .lt { font-size:14px; font-weight:500; }
.lrow .ls { font-size:12px; color:var(--muted); margin-top:2px; }
.lrow .ls.pos { color:var(--pos); } .lrow .ls.neg { color:var(--neg); }   /* [2026-10-21] 목록 작은 줄의 손익 색 - 회색(.ls)이 빨강·파랑을 덮던 것 */
.lrow .lv { font-size:14px; font-variant-numeric:tabular-nums; text-align:right; white-space:nowrap; }
.lrow.more { justify-content:center; color:var(--muted); font-size:13px; }
.list { background:var(--surface); border:1px solid var(--line); border-radius:14px; padding:2px 14px; }
/* [10-30 디자인 검수 2단계] 카드 안 목록 상자 = 한 겹(카드 > 상자 > 줄 3겹이 섹션 시작점을 흐렸다), 카드 안 소제목(.sec h2) = 카드 제목보다 한 단계 아래 */
.card .list { background:none; border:0; border-radius:0; padding:0; }
.card .sec { margin:18px 0 2px; } .card > .sec:first-child { margin-top:0; } .card .sec h2 { font-size:15px; color:var(--text2); }
.card > .sec:first-child h2, .card > :empty:first-child + .sec h2 { font-size:17px; color:var(--text); }   /* 앞에 빈 자리표(id 앵커 div)가 있어도 카드 첫 제목 */   /* [10-30 재검수] 카드 첫 줄 제목(.sec 로 감싼 '자동 전략 보유' 등)은 카드 제목 그대로 - 소제목 규칙이 카드 제목까지 줄였다 */
.lrow.row-new { background:none; }   /* [10-30 사용자 '새가 뭐냐'] 안 읽음 = 제목 앞 N 동그라미 + 굵은 제목(국내 관례) - 왼쪽 띠·'새' 꼬리표 두 겹 표시 없앰 */
.nmark { display:inline-flex; align-items:center; justify-content:center; width:16px; height:16px; border-radius:50%; background:#E5484D; color:#fff; font-size:10px; font-weight:800; line-height:1; vertical-align:2px; flex:0 0 auto; }   /* 안 읽음 = 띠 하나(바탕까지 칠하면 안 읽은 줄이 많을 때 목록 전체가 호박색) */   /* 안 읽은 줄 = 왼쪽 호박 띠(바탕이 상자 끝까지 안 차던 것) */
blockquote { margin:8px 0; padding:2px 0 2px 12px; border-left:3px solid var(--line2); color:var(--text2); }   /* 기본 왼쪽 40px 들여쓰기 없앰 */
main.app-main { padding-top:12px; }   /* 고정 메뉴 줄 아래 첫 카드가 4px 로 붙었다 */
.menu-list { background:var(--surface); border:1px solid var(--line); border-radius:14px; overflow:hidden; margin:0 0 12px; }
.menu-list a { display:flex; justify-content:space-between; align-items:center; gap:12px; padding:15px 14px; border-top:1px solid var(--line);
  color:var(--text); text-decoration:none; font-size:15px; min-height:44px; box-sizing:border-box; }
.menu-list a:first-child { border-top:0; }
.menu-list .ms { display:block; font-size:12px; color:var(--muted); margin-top:2px; }
.menu-list .mr { font-size:13px; color:var(--muted); white-space:nowrap; }
.menu-list .mr.warn { color:var(--accent-text); }
.menu-list a > svg { flex:0 0 16px; width:16px; height:16px; }
/* [10-30 관리자 디자인] 표 칸 안 스위치 = 작은 모양(전략 공개 표가 휴대폰 폭을 넘었다), 접힌 카드 첫 줄 = 카드 제목 크기·뒤 설명은 작게 */
@media (max-width:600px) { table td .btn-sw { gap:4px; } table td .btn-sw .sw-ui { width:34px; height:20px; border-radius:10px; } table td .btn-sw .sw-ui::after { top:2px; left:2px; width:14px; height:14px; }
  table td .btn-sw[aria-checked=true] .sw-ui::after { transform:translateX(14px); } table td .btn-sw .sw-t { font-size:13px; }
  table td .sw { gap:4px; } table td .sw .sw-ui { width:34px; height:20px; border-radius:10px; } table td .sw .sw-ui::after { top:2px; left:2px; width:14px; height:14px; }
  table td .sw > input:checked + .sw-ui::after { transform:translateX(14px); } table td .sw .sw-on, table td .sw .sw-off { font-size:13px; } }
.card > details:first-child > summary { font-size:13px; color:var(--muted); }
/* [10-30 관리자 디자인] 접힌 카드(details.card)가 이어지면 한 덩어리 목록으로(서비스 운영 접힌 카드 10장이 따로 떠 있었다) - 사이 간격 없이 가는 선만 */
details.card:has(+ details.card) { margin-bottom:0; border-bottom-left-radius:0; border-bottom-right-radius:0; border-bottom-color:transparent; }
details.card + details.card { margin-top:0; border-top-left-radius:0; border-top-right-radius:0; border-top:1px solid var(--line); }
details.card > summary { padding:2px 0; } details.card:not([open]) { padding-top:12px; padding-bottom:12px; }
/* 같은 '접힌 카드'가 div.card > details 모양이어도 같게(공지·요금·중앙 설정 89px vs 서비스 운영 66px) */
.card:has(> details:only-child:not([open])) { padding-top:12px; padding-bottom:12px; } .card > details:only-child > summary { margin:0; padding:2px 0; }   /* 접힌 카드 한 줄 = 위아래 여백 카드 몫만(요약 줄 자체 여백 14px·8px 이 겹쳐 85px) */
.card:has(> details:only-child):has(+ .card > details:only-child) { margin-bottom:0; border-bottom-left-radius:0; border-bottom-right-radius:0; border-bottom-color:transparent; }
.card:has(> details:only-child) + .card:has(> details:only-child) { margin-top:0; border-top-left-radius:0; border-top-right-radius:0; border-top:1px solid var(--line); } .card > details:first-child > summary > b:first-child { font-size:17px; color:var(--text); margin-right:4px; } .menu-list .mr { margin-left:auto; }   /* [10-30 재검수 3차] 긴 설명 줄에서 갈매기가 12px 로 줄었다 */
.pill { display:inline-block; font-size:11px; border-radius:99px; padding:3px 9px; white-space:nowrap; border:1px solid var(--line2); color:var(--muted); }
/* [10-30 디자인 검수] 상태 알약에 손익 색(--pos 빨강·--neg 파랑) 금지 - 보유 = 중립 강조, 주문 중 = 진행(호박) */
.pill-hold { background:var(--band); border-color:var(--line2); color:var(--text); }
.pill-buy { background:var(--accent-soft); border-color:var(--accent-line); color:var(--accent-text); }
.pill-ok { background:var(--ok-soft); border-color:var(--ok-line); color:var(--ok); }
.note { border:1px solid var(--line2); border-radius:12px; padding:12px 14px; font-size:12px; line-height:1.6; color:var(--text2); margin:12px 0; }
.note b { color:var(--text); }
.warnbox { background:var(--accent-soft); border:1px solid var(--accent-line); color:var(--accent-text); border-radius:12px; padding:12px 14px;
  font-size:13px; line-height:1.55; margin:10px 0; }
.seg { display:flex; gap:4px; background:var(--surface2); border-radius:10px; padding:4px; margin:0 0 12px; }
.seg a { flex:1; text-align:center; font-size:13px; padding:9px 0; border-radius:8px; color:var(--muted); text-decoration:none; }
.seg a.on { background:var(--surface); color:var(--link); font-weight:600; box-shadow:inset 0 0 0 1px var(--link); }   /* [10-30 디자인 검수] 선택 = 칩과 같은 호박 테두리·글자(흰 칸 대비 1.1:1 로 무엇을 골랐는지 안 보였다) */
@media (prefers-color-scheme: dark) {:where(:root:not([data-theme=light])) .seg a.on{ background:var(--surface); }}
:where(:root[data-theme=dark]) .seg a.on{ background:var(--surface); }
/* [11-02] 앱 설치 안내(pwa.INSTALL_BAR) - 브라우저로 열었을 때 화면 위 한 줄, 휴대폰은 글 아래로 단추 */
.install-bar { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:8px 12px; margin:0 0 12px; padding:10px 12px;
  border:1px solid var(--link); border-radius:10px; background:var(--surface); font-size:13px; line-height:1.45; }
.install-bar[hidden], .install-bar [hidden] { display:none; }
.install-bar .ib-txt { flex:1 1 220px; min-width:0; } .install-bar .ib-how { display:block; margin-top:2px; color:var(--text2); }
.install-bar .ib-how:empty { display:none; } .install-bar .ib-act { display:flex; gap:6px; flex:1 1 100%; justify-content:flex-end; } .install-bar #ib-close { margin-right:auto; }   /* [11-13 사용자 "닫기 왼쪽·앱 설치 오른쪽 - 같이 있게 하지 말고"] 글 아래 한 줄: 닫기 = 왼쪽 끝, 설치 단추 = 오른쪽 끝 */
.install-bar .ib-go { cursor:pointer; }   /* [11-02] 설치 창이 되는 브라우저 = 글을 눌러도 설치 창 */
.install-bar .ib-steps { flex:1 1 100%; margin:2px 0 0; padding-left:20px; color:var(--text2); }   /* 설치 방법 1·2·3(아이폰·설치 창 없는 브라우저) */
.install-bar .ib-steps li { margin:2px 0; }
/* [11-02] 팝업(슬라이드, dashboard_popup.overlay) - 가운데 상자 + 가로 넘김(scroll-snap, 손가락으로 밀기) + 아래 '오늘 하루 보지 않기 | 닫기' */
.pop { position:fixed; inset:0; z-index:100; display:flex; align-items:center; justify-content:center; padding:16px; background:rgba(0,0,0,.6); box-sizing:border-box; }
.pop[hidden] { display:none; } html.pop-on, html.pop-on body { overflow:hidden; }
.pop-box { width:100%; max-width:420px; max-height:calc(100vh - 32px); display:flex; flex-direction:column; background:var(--surface); border:1px solid var(--line);
  border-radius:16px; overflow:hidden; box-shadow:0 12px 40px rgba(0,0,0,.45); }
.pop-track { display:flex; overflow-x:auto; overflow-y:hidden; scroll-snap-type:x mandatory; scrollbar-width:none; flex:1 1 auto; min-height:0; outline:none; }
.pop-track::-webkit-scrollbar { display:none; }
.pop-slide { flex:0 0 100%; scroll-snap-align:start; overflow-y:auto; min-width:0; }
.pop-img { display:block; width:100%; height:auto; max-height:56vh; object-fit:contain; background:var(--surface2); }
.pop-text { padding:16px 18px 14px; } .pop-text h2 { margin:0 0 8px; font-size:17px; } .pop-body { margin:0 0 12px; font-size:14px; line-height:1.55; color:var(--text2); overflow-wrap:anywhere; }
.pop-link { display:flex; justify-content:center; width:100%; box-sizing:border-box; }
.pop-nav { display:flex; align-items:center; justify-content:center; gap:14px; padding:4px 0 6px; }
.pop-nav button { min-width:44px; min-height:40px; border:0; background:none; color:var(--text2); font-size:22px; cursor:pointer; }
.pop-cnt { font-size:13px; color:var(--muted); min-width:44px; text-align:center; }
.pop-foot { display:flex; border-top:1px solid var(--line); }
.pop-foot button { flex:1 1 0; min-height:48px; border:0; background:none; color:var(--text2); font-size:14px; cursor:pointer; }
.pop-foot button + button { border-left:1px solid var(--line); color:var(--text); font-weight:600; }
.pop-thumb { display:block; max-width:240px; max-height:120px; margin-bottom:6px; border-radius:8px; }
.fld .fi > .seg { margin:0; width:100%; }   /* [11-02] 백테스트 '빠른 선택' = 구간 선택(폼 칸 안 - 아래 여백 없음) */.sp-name { color:var(--text2); }
/* [2026-10-19] 관리자 고객 서비스 줄 - 이름·상태·기간 왼쪽, 연장 폼 오른쪽(좁으면 아래로) / 관리자 메뉴 = 가로 넘김 한 줄 */
.svc-line { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:6px 10px; padding:8px 0; border-bottom:1px solid var(--line); }
.svc-line form.inline { margin:0; display:flex; gap:6px; align-items:center; }
.svc-line select { width:auto; min-width:84px; }
.svc-line > span:first-child { flex:1 1 14em; min-width:0; overflow-wrap:anywhere; }
.svc-line .btns { display:flex; flex-wrap:wrap; gap:6px; justify-content:flex-end; }
.svc-line .btns form { margin:0; }
.lrow > div:first-child, .lrow .lt, .lrow .ls { min-width:0; overflow-wrap:anywhere; }   /* [10-31] 띄어쓰기 없는 긴 글(실적 해시)이 알림 줄을 360px 밖으로 밀었다 */ .svc-line > span > b .muted { font-weight:400; font-size:12px; }   /* 제어 줄 이름 칸 안 작업 이름(ctl_lines) */
.svc-line .btns.wide { flex:1 1 100%; } .svc-line .btns.wide form { flex:1 1 auto; display:flex; gap:6px; } .svc-line .btns.wide input { flex:1 1 auto; min-width:0; }
.adm-nav { display:flex; flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; }
.adm-nav a { white-space:nowrap; flex:none; }
.btn-wide { display:block; width:100%; box-sizing:border-box; text-align:center; padding:14px; font-size:15px; border-radius:10px; }
.btn-row { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:8px; margin:12px 0; }
/* [2026-10-30 사용자 캡처] 뒤에 오는 form.inline(마진 4px·inline-block)이 이겨 폼 단추만 4px 내려가고 높이가 달랐다 -> 줄 안 폼은 칸을 채우는 flex */
.btn-row > form, .btn-row > form.inline { display:flex !important; margin:0 !important; align-self:stretch; } .btn-row > form > .btn { flex:1 1 auto; height:100%; margin:0 !important; }   /* form.inline > button 위아래 6px 도 같은 원인 */
.btn-row form { display:block; margin:0; } .btn-row .btn { width:100%; min-height:46px; justify-content:center; text-align:center; box-sizing:border-box; display:flex; align-items:center; }
.chips { display:flex; flex-wrap:wrap; gap:8px; }
.chip { font-size:13px; border:1px solid var(--ctl-line); border-radius:99px; padding:6px 12px; color:var(--text2); text-decoration:none; background:transparent; }
.chip.on { border-color:var(--link); color:var(--link); }   /* [10-20 디자인 시스템] 밝은 화면 호박색 테두리 1.83:1 -> link(5.9:1), 어두운 화면은 같은 호박색 */
.chip.dash { border-style:dashed; color:var(--muted); }

/* 스프릿 칸 격자 */
.lvgrid { background:var(--surface); border:1px solid var(--line); border-radius:12px; overflow:hidden; }
.lvgrid .lv { display:grid; grid-template-columns:32px minmax(0,1fr) minmax(0,1fr) max-content; gap:6px; align-items:center; padding:10px 12px;
  font-size:13px; border-top:1px solid var(--line); font-variant-numeric:tabular-nums; }
.lvgrid .lv:first-child { border-top:0; color:var(--muted); font-size:11px; }
.lvgrid .lv.idle { color:var(--muted); }
.lvgrid .lv .pill { text-align:center; }
.lvgrid .now { display:flex; align-items:center; gap:8px; padding:4px 12px; font-size:11px; color:var(--accent-text); }
.lvgrid .now::before, .lvgrid .now::after { content:''; flex:1; height:1px; background:var(--accent-line); }

/* 소개 화면 */
.hero { padding:28px 4px 20px; display:flex; flex-direction:column; gap:12px; }
.hero .eyebrow { font-size:13px; color:var(--link); font-weight:600; }
.hero h1 { font-size:28px; line-height:1.3; margin:0; letter-spacing:-0.6px; word-break:keep-all; }
.hero p { margin:0; font-size:15px; line-height:1.6; color:var(--text2); word-break:keep-all; }
.steps { display:flex; flex-direction:column; gap:10px; }
.steps .stp { display:flex; gap:14px; background:var(--surface); border:1px solid var(--line); border-radius:12px; padding:14px; }
.steps .sn { color:var(--link); font-weight:700; width:18px; font-variant-numeric:tabular-nums; }
.steps .st { font-size:15px; font-weight:600; } .steps .sd2 { font-size:13px; color:var(--muted); margin-top:3px; line-height:1.5; }
.checks { display:flex; flex-direction:column; gap:12px; font-size:14px; line-height:1.5; color:var(--text2); padding:0 4px; }
.checks div { display:flex; gap:10px; } .checks svg { flex:none; margin-top:2px; color:var(--ok); }
.price { display:flex; flex-direction:column; gap:10px; }
.price .pr { display:flex; justify-content:space-between; gap:14px; font-size:14px; } .price .pr > span:first-child { color:var(--text2); }   /* [10-21] > = 값 안의 손익 색(span.pos·neg)을 덮지 않게 */
.price .pr > span:last-child { text-align:right; font-variant-numeric:tabular-nums; }
.price .pr > span:first-child { flex-shrink:0; max-width:62%; }   /* [10-21] 값이 길면 이름표가 한 글자씩 접혔다('비상 손 / 절') - 이름표는 줄지 않고 길면 62% 안에서만 줄바꿈 */

/* 비교 막대 폭(5% 단위 - 인라인 style 금지) */
.cb i.w-0 { width:0%; } .cb i.w-5 { width:5%; } .cb i.w-10 { width:10%; } .cb i.w-15 { width:15%; } .cb i.w-20 { width:20%; } .cb i.w-25 { width:25%; } .cb i.w-30 { width:30%; } .cb i.w-35 { width:35%; } .cb i.w-40 { width:40%; } .cb i.w-45 { width:45%; } .cb i.w-50 { width:50%; } .cb i.w-55 { width:55%; } .cb i.w-60 { width:60%; } .cb i.w-65 { width:65%; } .cb i.w-70 { width:70%; } .cb i.w-75 { width:75%; } .cb i.w-80 { width:80%; } .cb i.w-85 { width:85%; } .cb i.w-90 { width:90%; } .cb i.w-95 { width:95%; } .cb i.w-100 { width:100%; }
.kpi-right { text-align:right; }
.note.blk { display:block; text-decoration:none; color:var(--text2); }
.u-m-b0 { margin-bottom:0 !important; }
details.more { margin:16px 0 0; } details.more > summary { font-size:14px; padding:8px 0; margin-top:0; color:var(--text2); }   /* [11-13 자체 디자인 점검] 12 -> 8px: 앞 줄과 20px 떨어져 보였다(높이 36px) */
details > summary { min-height:32px; box-sizing:border-box; }   /* [11-13 자체 디자인 점검] 접기 제목 17~30px(이메일 변경·데이터 출처·조건 줄) -> 최소 32px */
.tplbox { margin:0 0 14px; } .tplbox > details.more, details.more + details.more { margin-top:0; } .tplbox > details.more > summary, details.more + details.more > summary { padding-top:6px; } details.more:has(+ .tplbox) > summary, details.more:has(+ details.more) > summary { padding-bottom:6px; } details.more:has(+ .tplbox) { margin-bottom:0; } details.more + .tplbox { margin-top:0; } h2 + details.more { margin-top:0; } h2 + details.more > summary { padding-top:6px; }   /* [11-13 사용자 "스프릿 설명 하고 공간이 커 좁게"] 카드 제목 바로 아래 접힘 = 위 여백 없음 */   /* [11-13 사용자 "스프릿 설명과 템플릿 사이 공간이 좁게"] 접힘 줄이 이어지면 뒤 줄 위 여백·summary 위 여백 0 */
.tplgrid { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:8px; margin-top:6px; }
.tpl { font:inherit; text-align:left; background:var(--surface2); border:1px solid var(--ctl-line); border-radius:10px; padding:10px; color:var(--text); cursor:pointer; min-height:44px; }
.tpl b { display:block; font-size:14px; } .tpl span { display:block; font-size:11px; color:var(--muted); margin-top:3px; }
.tpl:hover, .tpl:focus-visible { border-color:var(--link); }
body.landing { padding-bottom:24px; }
body.landing .topbar { display:flex; justify-content:space-between; align-items:center; }
body.landing .topbar h1 { font-size:16px; }
.hero .btn-wide + .btn-wide { margin-top:10px; }   /* [10-20 정렬] 위아래 버튼 사이 = 10px(예전 2px) */
a.brand { color:var(--text); text-decoration:none; }   /* [10-18] 로고 = 처음 화면 링크 - 글자 모양은 제목 그대로 */
a.brand:hover { color:var(--link); }
.kpi-unit { font-size:15px; font-weight:600; margin-left:2px; color:var(--text2); }
details.card > summary { margin:0; padding:2px 0; font-size:14px; color:var(--text); }
/* [2026-10-21] 서비스별 접는 카드(키 설정) - 제목 왼쪽 · 상태 오른쪽, 펼침 표시 ▸/▾ */
details.key-card > summary { display:flex; align-items:center; justify-content:space-between; gap:8px; list-style:none; cursor:pointer; }
details.key-card > summary::-webkit-details-marker { display:none; }
details.key-card > summary { justify-content:flex-start; } details.key-card > summary > span:first-child { flex:1 1 auto; }   /* [10-30 재검수 3차] 펼침 표시 = 다른 접힘과 같은 갈매기(예전 글자 ▸▾) */
details.key-card[open] > summary { margin-bottom:8px; }
details.status { display:block; } details.status summary { display:flex; align-items:center; gap:8px; margin:0; color:var(--text2); } details.status ul { margin:8px 0 0; }
/* [2026-10-28] 매수 중지 한 줄(buy_stop_view.item_html) = 사유 / 지금 숫자 / 매수 재개 단추를 위아래로(버튼 옆 작은 글씨 금지 - 정렬 규칙) */
/* [2026-11-03 사용자 캡처 "디자인 변경"] 한 건 = 이름 + 꼬리표 / 언제부터 / 이름 값 목록(.kv) / 판단 한 줄 / 단추 줄(한도 설정·매수 재개 나란히) - 숫자를 한 문단에 잇지 않는다.
   '확인 필요' 목록(ul) 안에서는 글머리 점 없이 건마다 구분선 */
.stop-item { display:grid; gap:6px; justify-items:stretch; padding:10px 0; }
details.status li:has(> .stop-item) { list-style:none; margin-left:-18px; border-top:1px solid var(--line); }
details.status li:has(> .stop-item):first-child { border-top:0; }
.stop-item .stop-h { display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; color:var(--text); }
.stop-item .stop-s, .stop-item .stop-tip { font-size:13px; color:var(--muted); }
.stop-item .stop-tip { color:var(--text2); }
.stop-item .kv { gap:4px 14px; font-size:14px; } .stop-item .kv dd { color:var(--text); }
.stop-item .kv dd .btn-sm { margin-left:6px; vertical-align:middle; }
.stop-item .stop-acts { display:flex; flex-wrap:wrap; align-items:stretch; gap:8px; margin-top:2px; }
.stop-item .stop-acts > form.inline { margin:0 !important; display:flex; }
/* [2026-11-03 사용자: "pc는 두칸으로 하는게 공간 활용이 좋지 않을까"] PC(1024px~) = 매수 중지 건을 두 칸(스프릿 목록 .sp-list 와 같은 기준), 건마다 테두리 칸.
   다른 '확인 필요' 줄(중단·주문 오류 등 글 한 줄)은 두 칸 전체 폭 */
@media (min-width:1024px) {
  details.status ul:has(> li > .stop-item) { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:10px 14px; padding-left:0; align-items:start; }
  details.status ul:has(> li > .stop-item) > li:not(:has(> .stop-item)) { grid-column:1 / -1; margin-left:18px; }
  details.status li:has(> .stop-item), details.status li:has(> .stop-item):first-child { margin:0; border:1px solid var(--line); border-radius:12px; padding:0 14px; }
}
.stop-item .stop-acts .btn { min-width:112px; min-height:44px; margin:0 !important; padding:8px 16px; box-sizing:border-box; display:inline-flex; align-items:center; justify-content:center; }
/* [2026-10-30] 자동 전략 조작(customer_strategies._ctl) = 두 줄: ① 서비스 이름 + 스위치(오른쪽) ② 금액 칸(작은 이름표 위) 나란히 + 저장(켜 둔 채 금액만 바꿈).
   사용자 캡처 "쓸데없이 공간을 많이 차지" - 예전 412px 서비스 하나 = 이름·스위치·칸마다 한 줄·저장 전체 폭 */
.strat-ctl { display:grid; gap:8px; max-width:640px; }
.strat-head { display:flex; align-items:center; justify-content:space-between; gap:8px; min-height:40px; }
.strat-head form.inline { margin:0 0 0 auto; }
.strat-head:not(:has(> b)) { justify-content:flex-start; } .strat-head:not(:has(> b)) form.inline { margin:0; }   /* 이름 없는 곳(내 자동 전략 = 서비스 제목 아래) = 스위치 왼쪽 */
.strat-vals { display:flex; flex-wrap:wrap; align-items:flex-end; gap:8px; margin:0 !important; }
.strat-vals .sv-f { display:grid; gap:4px; flex:1 1 7em; min-width:0; margin:0; font-size:12px; color:var(--muted); }
.strat-vals .sv-f input { width:100%; min-width:0; max-width:none; box-sizing:border-box; margin:0; }
.strat-vals > .btn { flex:0 0 auto; margin:0; }
.strat-svcs > .strat-ctl + .strat-ctl { border-top:1px dashed var(--line); padding-top:10px; margin-top:10px; }
.strat-svcs, .strat-ctl { margin-bottom:14px; } .strat-svcs > .strat-ctl { margin-bottom:0; }   /* 아래 상태·규칙 글과 띄움 */
/* [2026-10-30 사용자 "꼭 필요한 것과 사용하기 편리하게"] 스프릿 목록 카드(dashboard_split.plan_card) = 이름·종목·상태 / 차수 상태 배지 / 평가·실현·합산 / 자주 쓰는 스위치 */
/* [2026-10-30 사용자 캡처 "상단에 글자 바로 뒤에 버튼 넣지 말고"] 알림 상자(.flash·.warnbox) 안 단추 = 글 다음 줄 왼쪽(글 끝에 붙어 줄 가운데 걸리지 않게) */
.flash > a.btn, .flash > form.inline, .warnbox > a.btn, .warnbox > form.inline { display:flex; width:max-content; max-width:100%; margin:10px 0 0; }
/* 칸 하나 + 단추 한 줄(in-row) = 칸이 남는 폭을 채우고 단추는 줄 끝(폼 밖 조작 - 예: 해외 종목 직접 입력 + '이 종목 사용') */
.in-row { display:flex; align-items:center; gap:8px; margin:8px 0; max-width:640px; }   /* [11-01] 위 종목 선택칸과 같은 폭(PC 13-3 = 선택칸 최대 640px) */
.in-row > input:not([type=checkbox]):not([type=radio]) { flex:1 1 auto; min-width:0; max-width:none; margin:0; }   /* [11-06] 공용 입력 최대 28em(구체성 0,2,1)이 이겨 1280px 에서 칸이 364px 에 멈췄다 */ .in-row > .btn { flex:0 0 auto; margin:0; }
.sp-tot { margin:0 0 12px; }
/* 만들기 미리보기(SPLIT_JS pv) = 요약 네 칸(2x2) + 단추 줄 + 차수 카드(차수 | 매수가·매도가 | 수량·금액) */
.pv-kpi { grid-template-columns:repeat(2, minmax(0,1fr)); margin-bottom:8px; }
.pv-list { display:grid; gap:8px; margin:12px 0; }
.pv-lv { display:grid; grid-template-columns:auto minmax(0,1fr) minmax(0,1fr); gap:10px; align-items:center; background:var(--surface); border:1px solid var(--line); border-radius:12px; padding:10px 12px; }
.pv-c { display:grid; grid-template-columns:auto 1fr; gap:2px 8px; font-size:13px; } .pv-c b { text-align:right; font-variant-numeric:tabular-nums; font-weight:600; min-width:0; overflow-wrap:anywhere; }
/* 스프릿 상세 차수 카드(dashboard_split.level_row = web_list.xrow) - 현재가 선은 차수 사이에(예전 격자 .lvgrid .now 와 같은 모양) */
.lv-now { display:flex; align-items:center; gap:8px; padding:6px 4px; font-size:11px; color:var(--accent-text); }
.lv-now::before, .lv-now::after { content:''; flex:1; height:1px; background:var(--accent-line); }
.lv-row .xt b { margin-right:4px; } .lv-row .xm .pill { margin-top:2px; } .lv-row .xv { display:flex; gap:4px; align-items:baseline; }
.lv-row .xd .price { margin:0 0 10px; } .lv-row > .xd { max-width:640px; }
/* [10-30 사용자 '꽉 채워지지 않는 부분'] 펼친 차수 조작 = 줄 전체 - 중지 둘 반반, 지금 매도 = 주문 방식 | 가격(남는 폭) | 단추 */
.lv-row .ctl-rows { justify-items:stretch; } .lv-row .ctl-row { width:100%; }
.lv-row .ctl-row > form { display:flex !important; flex:1 1 0; align-items:center; gap:6px; margin:0 !important; }
.lv-row .ctl-row > form > .btn { flex:1 1 auto; justify-content:center; margin:0; } .lv-row .ctl-row > form:only-child > .btn { flex:0 0 auto; }
.lv-row .ctl-row > form > input:not([type=hidden]) { flex:1 1 auto; min-width:0; max-width:none; }   /* PC 에서 이름표와 숫자가 1,200px 떨어지지 않게 */
.sp-list { display:grid; gap:12px; }
@media (min-width:1024px) { .sp-list { grid-template-columns:repeat(2, minmax(0,1fr)); align-items:start; } }   /* PC = 두 장씩(한 장이 1,200px 로 늘어 이름표와 숫자가 멀었다) */
.sp-item { background:var(--surface2); border:1px solid var(--line); border-radius:12px; padding:10px 12px; display:grid; gap:6px; } .sp-item > * { min-width:0; }   /* 긴 이름이 줄을 늘려 오른쪽 합산손익이 잘렸다 */
.sp-top { display:flex; align-items:baseline; justify-content:space-between; gap:10px; }
.sp-top a, .sp-top .sp-nm { color:var(--text); text-decoration:none; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1 1 auto; } .sp-top a b, .sp-top .sp-nm b { font-size:16px; } .sp-top .sp-tot-v { font-size:14px; font-weight:600; flex:0 0 auto; }
/* [2026-11-01 사용자 "어디를 클릭해야 상세로 가는지 알 수 없음"] 목록 카드 윗부분(이름·요약·평가) = 상세 링크 한 덩어리 + 오른쪽 '›', 아래 스위치는 링크 밖 */
.sp-link { display:grid; gap:6px; color:inherit; text-decoration:none; border-radius:8px; } .sp-link:hover .sp-nm b, .sp-link:focus-visible .sp-nm b { text-decoration:underline; }
.sp-link .chev { color:var(--text2); font-size:24px; font-weight:600; line-height:1; flex:0 0 auto; margin-left:2px; } .sp-link .sp-meta, .sp-link .sp-sub { color:var(--text2); }   /* [10-30 재검수 3차] 제목(종목) 16 > 손익 14 - 무게가 같았다 */
.sp-tot-v { flex:none; font-weight:700; font-size:14px; font-variant-numeric:tabular-nums; }   /* [10-30 "수십개"] 합산손익 = 이름 줄 오른쪽 */
.sp-meta { font-size:12px; line-height:1.5; } .sp-sub { font-size:13px; font-variant-numeric:tabular-nums; }
.sp-item .price { margin:0; }
.sp-act { border-top:1px dashed var(--line); padding-top:6px; } .sp-act .act-t { font-size:12px; } .sp-act form.inline { margin:0; flex:none; }   /* [11-13] 목록 카드 숨김·숨김 해제 = 안내 왼쪽·작은 단추 오른쪽 한 줄 */
.sp-sw { display:grid; grid-template-columns:repeat(5, minmax(0,1fr)); gap:4px; border-top:1px dashed var(--line); padding-top:6px; }   /* 작은 스위치 다섯 한 줄 */
.sp-sw .sp-sw-i { display:flex; flex-direction:column; align-items:center; justify-content:flex-start; gap:2px; min-height:0; margin:0; }
.sp-sw-i form.inline { margin:0; } .sp-sw-i > .al-lbl, .sp-sw-i > span:first-child { flex:none; min-width:0; max-width:100%; font-size:11px; color:var(--text2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-align:center; }
.sp-sw .sw-t { display:none; } .sp-sw .btn-sw { min-height:32px; padding:2px 0; }
/* [10-30 재검수 3차] 목록 카드 스위치 = 작은 모양(카드마다 큰 호박 스위치 다섯 개가 무거웠다) - 켬 = 호박 테두리·점, 끔 = 회색 */
.sp-sw .sw-ui { width:34px; height:20px; border-radius:10px; } .sp-sw .sw-ui::after { top:2px; left:2px; width:14px; height:14px; }
.sp-sw .btn-sw[aria-checked=true] .sw-ui { background:transparent; border-color:var(--accent); } .sp-sw .btn-sw[aria-checked=true] .sw-ui::after { transform:translateX(14px); background:var(--accent); }   /* 켬·끔 글자 대신 스위치 모양만(이름은 위) */

/* ===== [2026-10-20 디자인 시스템 '정렬'] 사용자: "좌우·가로·세로 정렬이 깔끔하게 / 작은 글씨 옆에 바로 큰 버튼 / 입력값 바로 뒤에 버튼, 뒤로 공간이 많음 /
   로그인·관리자 OTP 화면 버튼 위아래 간격 없음". 412·1280px 실측(운영자 54화면 + 로그인 6화면): 글씨-버튼 한 줄 24·26곳, 입력+버튼 뒤 빈칸 27·87곳,
   버튼 위아래 간격 8px 미만 94·20곳. 규칙 한 벌:
   ① 세로 리듬 - 카드 안 폼 위아래 12px, 줄바꿈된 버튼 사이 10px(같은 줄 사이 8px)
   ② 입력 + 버튼 한 줄 = 버튼 바로 앞 칸이 남는 폭을 채우고 버튼은 줄 끝(한 줄 최대 640px) - 뒤에 빈칸을 남기지 않는다
   ③ 버튼 옆 설명 글씨는 버튼 줄 아래 한 줄(fh-line, web_layout 이 붙인다) - 큰 버튼과 작은 글씨를 같은 줄에 두지 않는다
   ④ 로그인 틀의 보조 버튼(회원가입 등)도 주 버튼과 같은 폭·높이, 사이 10px */
.card > form:not(.inline) { margin:12px 0; }
.card > form:not(.inline):first-child, .card > h2 + form:not(.inline), .card > h3 + form:not(.inline) { margin-top:0; }
.card > form:not(.inline):last-child { margin-bottom:0; }
/* ⑥ 휴대폰 줄 카드의 조작 칸: 폼이 둘 이상이거나 입력이 있는 칸 = 폼마다 한 줄 전체, 버튼은 그 줄을 채움(오른쪽에 들쭉날쭉 쌓이지 않게), 폼 사이 10px.
      버튼 하나뿐인 칸('조작 [끄기]')은 그대로 오른쪽 */
@media (max-width:600px) {
  table.stack td:has(form + form) form, table.stack td:has(form input:not([type=hidden]):not([type=checkbox]):not([type=radio])) form,
  table.stack td:has(form select) form { display:flex !important; width:100%; margin:0; justify-content:stretch; }
  table.stack td:has(form + form) form > .btn, table.stack td:has(form + form) form .fg-act,
  table.stack td:has(form input:not([type=hidden]):not([type=checkbox]):not([type=radio])) form > .btn,
  table.stack td:has(form input:not([type=hidden]):not([type=checkbox]):not([type=radio])) form .fg-act,
  table.stack td:has(form select) form .fg-act, table.stack td:has(form select) form > .btn { flex:1 1 0; justify-content:center; }
  table.stack td:has(form + form) form .fg-act > .btn, table.stack td:has(form input:not([type=hidden])) form .fg-act > .btn,
  table.stack td:has(form select) form .fg-act > .btn { width:100%; justify-content:center; }
  table.stack td:has(form select) form .fg { flex:1 1 100%; } table.stack td:has(form select) form .fg > select { flex:1 1 auto; max-width:none; }
  table.stack td:has(form + form) form .fg, table.stack td:has(form input:not([type=hidden])) form .fg { flex:1 1 100%; }
  table.stack td:has(form + form) form .fg > input, table.stack td:has(form + form) form .fg > select,
  table.stack td:has(form input:not([type=hidden])) form .fg > input:not([type=checkbox]), table.stack td:has(form input:not([type=hidden])) form .fg > select { flex:1 1 auto; max-width:none; }
}
/* ⑦ 묶음 줄(ctl-rows > ctl-row, 2026-10-30 사용자 캡처 '매수 중지·매도 중지 한 칸'): 한 줄 = 한 묶음. 줄 안 폼은 나란히 같은 폭(단추 둘),
      입력 폼 하나면 주문 방식·가격·단추가 한 줄. ⑥(폼마다 한 줄)보다 앞선다 */
.ctl-rows { display:grid; gap:10px; justify-items:end; }
.ctl-row { display:flex; flex-wrap:nowrap; align-items:center; gap:8px; }
.ctl-rows .ctl-row > form, table.stack td .ctl-row > form { display:flex !important; flex-wrap:nowrap; align-items:center; gap:6px; margin:0 !important; width:auto !important; min-width:0; }
.ctl-row > form > select, .ctl-row > form > input:not([type=hidden]), .ctl-row > form > .fg:not(.fg-act) { flex:1 1 0; min-width:0; max-width:8em; }
.ctl-row > form > .fg { display:flex; margin:0; } .ctl-row > form > .fg:not(.fg-act) > select, .ctl-row > form > .fg:not(.fg-act) > input { width:100%; min-width:0; max-width:none; }
.ctl-row > form > .fg-act { flex:0 0 auto !important; } .ctl-row > form .btn { white-space:nowrap; }
/* [2026-11-01 사용자 캡처 '지금 매도 칸에 겹침 있음'] 주문 방식 선택(시장가·지정가)이 줄어들 수 있어 한글이 글자 단위로 접히며 상자 밖으로 넘쳤고
   옆 가격 칸이 '지정가' 위에 겹쳤다 -> 선택은 줄지 않고(글자 한 줄), 줄어드는 몫은 가격 칸이 맡는다 */
.ctl-row > form > .pick.sm { flex:0 0 auto; } .ctl-row > form > .pick.sm .pk span { white-space:nowrap; }
/* 360px 폭: 가격 칸의 기본 폭(size=7)이 최소 폭으로 잡혀 줄이 카드 밖(화면 끝)까지 나갔다 -> 칸 기본 폭 0 + 남는 폭만 차지 */
.ctl-rows > .ctl-row { min-width:0; } .ctl-row > form > input:not([type=hidden]) { width:0; }
@media (max-width:600px) {
  table.stack td:has(.ctl-rows) { display:block; text-align:left; }
  table.stack td:has(.ctl-rows)::before { display:block; float:none; text-align:left; }
  table.stack td .ctl-row .btn, table.stack td .ctl-row select, table.stack td .ctl-row input:not([type=hidden]) { box-sizing:border-box; height:44px; min-height:44px; }
  table.stack td .ctl-rows { justify-items:stretch; width:100%; margin-top:8px; }
  table.stack td .ctl-row > form { flex:1 1 0; }
  table.stack td .ctl-row > form > .btn { flex:1 1 auto; justify-content:center; }
  table.stack td .ctl-row > form > select, table.stack td .ctl-row > form > input:not([type=hidden]), table.stack td .ctl-row > form > .fg:not(.fg-act) { flex:1 1 0 !important; max-width:none; }
  table.stack td .ctl-row > form > .fg-act > .btn { width:auto; }
}
form.inline { display:inline-block; vertical-align:middle; margin:4px 6px 4px 0; }
form.filter, form.filter .fg, form.filter .fg-btns, table.stack td form, table.stack td .fg, table.stack td .fg-wrap,
.svc-line .btns, .svc-line form.inline, .svc-line .btns.wide form, .chips { row-gap:10px; }
form.filter { column-gap:8px; max-width:640px; }
/* [10-30 관리자 디자인] '칸 하나 + 버튼 하나'(설정 값 + 저장) = 어느 폭에서도 한 줄 - 휴대폰 규칙이 칸·버튼을 각각 한 줄씩 쌓아 관리자 설정 하나가 100px(로그인 설정 카드 5,097px)였다 */
form.filter:has(> .fg:not(.fg-act)):not(:has(> .fg:not(.fg-act) ~ .fg:not(.fg-act))):has(> .fg-act) { flex-wrap:nowrap; }
form.filter:has(> .fg:not(.fg-act)):not(:has(> .fg:not(.fg-act) ~ .fg:not(.fg-act))):has(> .fg-act) { min-width:0; max-width:100%; }
form.filter:has(> .fg:not(.fg-act)):not(:has(> .fg:not(.fg-act) ~ .fg:not(.fg-act))):has(> .fg-act) > .fg:not(.fg-act) { flex:1 1 auto !important; min-width:0; }
form.filter:has(> .fg:not(.fg-act)):not(:has(> .fg:not(.fg-act) ~ .fg:not(.fg-act))):has(> .fg-act) > .fg:not(.fg-act) > input:not([type=hidden]) { width:100%; min-width:0; }   /* size='22' 칸이 줄을 넘겼다(중앙 설정 360px) */
form.filter:has(> .fg:not(.fg-act)):not(:has(> .fg:not(.fg-act) ~ .fg:not(.fg-act))):has(> .fg-act) > .fg-act { flex:0 0 auto !important; }
form.filter:has(> .fg:not(.fg-act)):not(:has(> .fg:not(.fg-act) ~ .fg:not(.fg-act))):has(> .fg-act) > .fg-act > .btn { flex:0 0 auto; }
@media (max-width:600px) { .svc-line .btns:has(form.filter .fg:not(.fg-act) input:not([type=hidden])) { flex:1 1 100%; justify-content:stretch; } .svc-line .btns:has(form.filter .fg:not(.fg-act) input:not([type=hidden])) > form { flex:1 1 auto; } }
/* 칸 하나 + 버튼(금액·코드·메모 한 칸) = 칸이 버튼까지 채우고 줄 전체 최대 480px. 칸이 여럿인 폼은 각 칸 제 폭(입력 최대 28em) */
form.filter:not(:has(> .fg ~ .fg ~ .fg-act)):not(:has(> .fg ~ .fg ~ .btn)) { max-width:480px; }   /* [11-06] 칸 둘 이상 + 버튼(.btn 바로) = 여러 칸 조회 줄(640px) - 실적 기간 조회 조회가 다음 줄로 밀렸다 */
form.filter:not(:has(> .fg ~ .fg ~ .fg-act)) > .fg:has(+ .fg-act) { flex:1 1 12em; }
form.filter:not(:has(> .fg ~ .fg ~ .fg-act)) > .fg:has(+ .fg-act) > input:not([type=checkbox]):not([type=radio]),
form.filter:not(:has(> .fg ~ .fg ~ .fg-act)) > .fg:has(+ .fg-act) > select { flex:1 1 auto; min-width:0; max-width:none; }
form.filter > .fg-act { margin-left:auto; }
/* [2026-11-05 사용자 캡처(관리자 실적 순위): "기간 레이블 없애고 구분 레이블은 셀렉트에 구분 전체로 ... 보기 버튼까지 해서 한칸으로"]
   선택 상자만 있는 조회 폼 = 어느 폭에서도 한 줄 [선택 채움][선택 채움][버튼] - 이름표는 첫 항목('구분 전체'·'거래소 전체')과 aria-label 로 */
form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)) { flex-wrap:nowrap; max-width:640px; }
form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)) > .fg:not(.fg-act) { flex:1 1 0 !important; min-width:0; }
form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)) > .fg:not(.fg-act) > select { width:100%; min-width:0; max-width:none; }
form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)) > .fg-act, form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)) > .btn { flex:0 0 auto !important; margin-left:0; align-self:stretch; }
/* [2026-11-06 사용자 캡처(내역 내려받기 412px): 선택 3개 + 'CSV 내려받기' 한 줄 = 선택 글자가 '체결 내ᄋ'·'서비스 전'처럼 잘림]
   휴대폰 폭에서 선택이 셋 이상이면 두 칸씩 줄바꿈([종류][서비스] / [기간][버튼]) - 412px 한 줄 셋 = 칸 111px < '서비스 전체'+화살표 127px.
   선택 둘 + 버튼은 11-05 결정대로 한 줄 */
@media (max-width:600px) {
  form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)):has(> .fg:not(.fg-act) ~ .fg:not(.fg-act) ~ .fg:not(.fg-act)) { flex-wrap:wrap; row-gap:8px; }
  form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)):has(> .fg:not(.fg-act) ~ .fg:not(.fg-act) ~ .fg:not(.fg-act)) > .fg:not(.fg-act),
  form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)):has(> .fg:not(.fg-act) ~ .fg:not(.fg-act) ~ .fg:not(.fg-act)) > .btn,
  form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)):has(> .fg:not(.fg-act) ~ .fg:not(.fg-act) ~ .fg:not(.fg-act)) > .fg-act { flex:1 1 calc(50% - 4px) !important; }
  form.filter:has(> .fg > select):has(> .fg-act, > .btn):not(:has(> .fg:not(.fg-act) > :not(select), > input:not([type=hidden]), > span:not(.fg-act), > textarea)):has(> .fg:not(.fg-act) ~ .fg:not(.fg-act) ~ .fg:not(.fg-act)) > .fg-act > .btn { width:100%; }
}
/* 줄 목록(svc-line)·표 칸 안의 폼 = 채우지 않고 제 폭 한 줄(이름표 오른쪽에 '칸 [저장] [기본값으로]') */
@media (min-width:601px) {
  .svc-line form.filter { flex-wrap:nowrap; max-width:none; } td form.filter { max-width:none; }
  .svc-line form.filter > .fg, td form.filter > .fg { flex:0 1 auto !important; }
  .svc-line form.filter > .fg > input:not([type=checkbox]):not([type=radio]), td form.filter > .fg > input:not([type=checkbox]):not([type=radio]) { flex:0 1 auto !important; width:auto; max-width:12em !important; }
  .svc-line form.filter > .fg-act, td form.filter > .fg-act { margin-left:0; }
  /* 긴 값 줄(btns.wide - 켤 서비스 목록 등) = 왼쪽부터 [칸 채움 … 저장] [기본값으로], 칸 묶음 최대 480px */
  .svc-line .btns.wide { justify-content:flex-start; }
  .svc-line .btns.wide form.filter { flex:0 1 480px; }
  .svc-line .btns.wide form.filter > .fg:has(+ .fg-act) { flex:1 1 auto !important; }
  .svc-line .btns.wide form.filter > .fg:has(+ .fg-act) > input:not([type=checkbox]):not([type=radio]) { flex:1 1 auto !important; max-width:none !important; }
}
form.filter > .fg-act + .fg:has(> .muted:only-child), form.filter > .fg-btns + .fg:has(> .muted:only-child) { flex:1 1 100%; white-space:normal; font-size:12px; }
.fh-line { display:block; margin-top:6px; font-size:12px; line-height:1.5; }
/* ⑤ 이름표 + 버튼 한 줄(act-line, web_layout) = 이름표 왼쪽·버튼 오른쪽, 세로 가운데. 아래 설명(fh-line)은 줄 전체 */
.act-line { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px 12px; }
.act-line > .al-lbl { flex:1 1 10em; min-width:0; }
.act-line > form.inline { margin:0; flex:none; }
.act-line > a.btn { flex:none; margin:0; }
.fld-wide { display:flex; } .fld-wide .fi { display:flex; flex-wrap:wrap; white-space:normal; max-width:640px; } .fld-wide .fi select, .fld-wide .fi input:not([type=date]) { flex:1 1 auto; width:100%; min-width:0; max-width:100%; }   /* [2026-10-20] 넓은 칸 = 칸이 줄을 채움(긴 선택지가 넘치지 않게) */
.fields + .btn-line { margin-top:16px; }   /* [2026-10-20] 마지막 칸과 실행 버튼이 붙지 않게 */
/* [2026-10-20 사용자: "입력 인풋값과 밑에 버튼이 탁 붙은 화면이 여러 개(키 설정·내 계정)"] 전 화면 실측 135곳(0~6px) - 줄을 넘겨 아래로 내려간 버튼과 입력칸 사이 = 세로 12px(가로 간격은 그대로).
   폼 묶음·표 카드 칸 안 폼·서비스 줄·손절 칸 = row-gap, 폼 안 버튼 줄(p·div.btn-line)·이름표 칸 다음 버튼 = margin-top. 점검 = scratchpad align_d.mjs 검사 D. */
form.filter, table.stack td form, table.stack td form.inline, .svc-line form.inline, .svc-line .btns.wide form, .stopf, .form-stack > form { row-gap:12px !important; }
form > .btn-line, form > p.btn-line, form .fld + .btn-line, form label + .btn-line, form .fld + p, form label.fld + button { margin-top:12px; }
.fields + p, .fields + .btn-line { margin-top:12px; }
/* [10-30 사용자 캡처 '선택이 한 칸인데 전체를 차지하지 않음 / 전략명은 칸을 넘어감'] 이름표 없이 바로 놓인 칸(종목 선택·전략명) = 한 줄 전체, 카드 밖으로 넘지 않음 */
.fields > select, .fields > input:not([type=hidden]):not([type=radio]):not([type=checkbox]) { display:block; width:100%; max-width:100%; min-width:0; box-sizing:border-box; }
form.inline:not(.filter) > input:not([type=hidden]), form.inline:not(.filter) > select, form.inline:not(.filter) > button, form.inline:not(.filter) > label { margin-top:6px; margin-bottom:6px; }   /* 묶이지 않은 한 줄 폼이 줄을 넘길 때 위아래 12px */
/* [2026-10-20 정렬 검사 B 남은 곳] 이름표 안 선택칸 + 버튼 폼(실적 순위)·폼 없는 '입력칸 + 버튼' 문단(해외 스프릿 직접 입력)·날짜 칸 거르기(실적 기간) = 칸이 줄을 채우고 버튼은 오른쪽 */
form.inline:not(.filter):has(> label > select) { display:flex; flex-wrap:wrap; align-items:center; gap:12px; max-width:640px; }
form.inline:not(.filter):has(> label > select) > button:last-child { margin:0 0 0 auto; }
p:has(> input:not([type=hidden]) + button) { display:flex; flex-wrap:wrap; align-items:center; gap:12px 8px; max-width:640px; }
p:has(> input:not([type=hidden]) + button) > input { flex:1 1 8em; min-width:0; margin:0; }
form.filter > .fg:has(> input[type=date]) { flex:1 1 auto; } form.filter > .fg > input[type=date] { flex:1 1 auto; min-width:0; }
.chk-line { display:flex; flex-wrap:wrap; align-items:center; gap:8px 18px; } .chk-line > .fl { flex:1 1 100%; color:var(--muted); font-size:13px; }
.chk-line label { display:inline-flex; align-items:center; gap:6px; margin:0; } .chk-line input[type=checkbox] { margin:0; }
/* [2026-11-05] 가격 차트 컴포넌트(web_chart price-chart.js, 백테스트·스프릿 공용) - RSI·MACD 아래 칸(각 120px + 구분선)을 켠 만큼 칸을 키운다 */
.pc-chart { height:420px; } .pc-chart.pc-p1 { height:550px; } .pc-chart.pc-p2 { height:680px; }
@media (max-width:600px) { .pc-chart { height:340px; } .pc-chart.pc-p1 { height:470px; } .pc-chart.pc-p2 { height:600px; } }
/* [2026-11-05 사용자 "휴대폰에서 차트 가로 모드로 변경 가능한가 최대 사이즈로"] 전체 화면 = 컴포넌트 자리(.pc-full)가 화면 전체(브라우저 전체 화면 또는 고정 덮개),
   표시 줄은 위 한 덩어리로 가로 스크롤, 차트가 남은 높이 전부. 세로로 든 아이폰(가로 고정 불가)만 '가로로 돌리세요' 안내 */
.pc-bar { display:flex; align-items:center; justify-content:flex-end; gap:8px; margin-bottom:6px; } .pc-bar .pc-lbl { margin-right:auto; } .pc-hint { display:none; }
/* [2026-11-11 사용자: "표시 글자를 없애고 보조지표 버튼"] 보조지표 선택 칸 = 단추를 누를 때만(차트 위), 묶음 이름(보조지표·차트 표시) + 체크 + 설명 + 초기화·닫기 */
.pc-bar .pc-ib.on { border-color:var(--accent); color:var(--accent); }
/* [2026-11-11 사용자 휴대폰 캡처 "보조지표, 전체 화면 버튼 영역을 높이를 줄이는 방안"] 맨 위 줄 단추 = 카드 제목 줄 작은 단추(32px, 가이드 13-1) - 예전 48px 한 줄을 따로 차지했다,
   왼쪽 짧은 글(.pc-sub '일봉 · 기준 봉')과 같은 줄 */
.pc-bar .btn { min-height:32px; padding:0 12px; font-size:13px; box-sizing:border-box; display:inline-flex; align-items:center; flex:0 0 auto; white-space:nowrap; }   /* 360px = 왼쪽 글만 두 줄, 단추 글자는 한 줄 */
.pc-bar .pc-sub { min-width:0; word-break:keep-all; overflow-wrap:normal; }   /* 날짜(2026-11-10) 가운데서 줄바꿈 금지 */ .pc-panel .pc-note > .pc-xn { margin:4px 0 0; }
.pc-panel { border:1px solid var(--line); border-radius:10px; padding:10px 12px; margin-bottom:8px; background:var(--surface); }
.pc-panel:not(.open) { display:none; } .pc-ph { font-weight:600; font-size:14px; margin:2px 0 8px; } .pc-ph ~ .pc-ph { margin-top:12px; }
.pc-panel .pc-note { margin:8px 0 0; } .pc-panel .pc-note > summary { color:var(--muted); min-height:0; padding:2px 0; } .pc-panel .pc-note > p { margin:4px 0 0; }
.pc-msg { margin:6px 0 0; } .pc-msg:empty { display:none; }   /* [11-11 사용자 "초기화, 닫기 버튼 제거 자꾸 화면을 높게 차지하지 않게"] 닫기 = 보조지표 단추 다시 누름, 설명 = 접힘 한 줄 */
/* [2026-11-11 사용자: "보유종목 영역에서 ... 차트 버튼" -> "이름 오른쪽이 아니고 화면 오른쪽" -> "종목명 과 같은 라인에 표현이 어려우면 텍스트로"]
   보유 종목 머리 줄 = 종목명과 같은 줄 화면 오른쪽 끝에 글자 링크 '차트'(트레이딩뷰 새 창), 손익 값은 그 아래 줄(이름 아래 작은 줄과 같은 높이).
   두 칸 모두 위 맞춤 - 가운데 맞춤이면 링크가 이름 줄보다 내려간다. 링크 = 호박색 밑줄(누를 자리 위아래 4px 더) */
.lrow.lgh:has(.tv-link) { align-items:flex-start; }
.lrow.lgh > .lv > .tv-link { display:block; font-size:14px; line-height:20px; color:var(--accent); text-decoration:underline; text-underline-offset:3px; padding:2px 0; margin:-2px 0 0; }
.lrow.lgh > .lv > .tv-link + * { display:block; font-size:13px; margin-top:2px; }
.lrow.lgh > .lv > .tv-link { order:2; }   /* PC(값 칸이 한 줄 flex) = 손익 값 다음 맨 오른쪽 - 줄마다 '차트' 자리가 같게(값 있는 줄만 112px 안쪽에 섰다) */
.pc-bar h2.pc-title { margin:0 auto 0 0; font-size:17px; }   /* [11-06] 카드 제목을 맨 위 줄에(보유 상세 차트) - 카드 첫 제목 크기 */
.pc-full { position:fixed; inset:0; z-index:1000; background:var(--bg); display:flex; flex-direction:column; padding:8px 10px env(safe-area-inset-bottom); box-sizing:border-box; }
.pc-full .pc-tg { display:flex; flex-wrap:nowrap; overflow-x:auto; padding-bottom:4px; } .pc-full .pc-tg label { white-space:nowrap; }
/* [2026-11-06 사용자: "휴대폰 화면에서 한칸에 3개는 표현되게"] 표시 체크 = 휴대폰 3열 격자(줄마다 3개, 칸 폭 같음). 전체 화면은 위 한 줄 가로 스크롤 그대로 */
@media (max-width:600px) { .pc-tg { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px 6px; } .pc-tg label { white-space:nowrap; min-width:0; } }
.pc-full .pc-bar { margin-bottom:4px; } .pc-full .pc-chart { flex:1 1 auto; height:auto !important; min-height:0; margin-top:4px; } .pc-full > p { display:none; }
@media (orientation:portrait) { .pc-full.pc-nolock .pc-hint { display:inline; } }
/* [2026-11-11 사용자: "전체 화면은 기존 표현방식이 좋은데"] 전체 화면 = 예전처럼 지표 체크가 위 한 줄(가로 스크롤)에 바로 보임 -
   '보조지표' 단추·묶음 이름·설명·선택 칸 틀은 숨김(체크를 바꾸면 일반 화면과 같이 계정에 저장). 일반 화면은 '보조지표' 단추 그대로 */
.pc-full .pc-ib, .pc-full .pc-bar .pc-sub { display:none; }
.pc-full .pc-panel { display:flex; flex-wrap:nowrap; align-items:center; gap:18px; overflow-x:auto; border:0; border-radius:0; padding:0 0 4px; margin:0; background:none; }
.pc-full .pc-panel > .pc-ph, .pc-full .pc-panel > .pc-note, .pc-full .pc-panel > .pc-msg { display:none; }
.pc-full .pc-panel > .pc-tg { flex:0 0 auto; overflow:visible; padding:0; }
/* [2026-11-12 사용자 "pc 모드에서는 보조지표 버튼 없애고 전체화면 모드처럼 기본으로 표현 … 두번 클릭을 해야 하잖아 모바일은 칸을 많이 차지해서"]
   PC(1024px~) = '보조지표' 단추 없음, 지표 체크가 차트 위에 늘 보이는 줄(전체 화면처럼 묶음 이름·틀 없음, 넘치면 다음 줄),
   '기준·지표 설명'은 줄 끝 접힘. 그 아래 폭은 단추로 열고 닫는 칸 그대로(.open) */
@media (min-width:1024px) {
  .pc-bar .pc-ib { display:none; }
  :not(.pc-full) > .pc-panel, :not(.pc-full) > .pc-panel:not(.open) { display:flex; flex-wrap:wrap; align-items:center; gap:6px 18px; border:0; border-radius:0; padding:0; margin:0 0 4px; background:none; }
  :not(.pc-full) > .pc-panel > .pc-ph { display:none; }   /* 전체 화면(.pc-full)은 위 한 줄 가로 스크롤 규칙 그대로 */
  :not(.pc-full) > .pc-panel > .pc-tg { display:contents; } .pc-panel > .pc-tg label { white-space:nowrap; }   /* 체크·설명 접힘이 한 흐름(설명이 따로 한 줄을 차지하지 않게) */
  :not(.pc-full) > .pc-panel > .pc-note { margin:0; } :not(.pc-full) > .pc-panel > .pc-msg { flex-basis:100%; margin:0; }
}
@media (orientation:landscape) { .pc-full .pc-bar { position:absolute; top:4px; right:10px; margin:0; } .pc-full .pc-bar .pc-lbl { display:none; } .pc-full .pc-panel { margin-right:76px; } .pc-full .pc-fs { min-height:32px; padding:2px 14px; } }   /* 가로 = 닫기를 체크 줄 오른쪽에(차트 높이 확보) - 예전 그대로 */
html.pc-lock, html.pc-lock body { overflow:hidden; }
/* [2026-11-06 사용자: "차트 링크 또는 버튼을 두고 클릭 시에만"] 보유 상세 차트 칸 = 단추를 누를 때만 연다(hidden), 전략 안내 = 점 목록 */
.hc[hidden] { display:none; }
/* [2026-11-06 사용자: "수익률 설명칸의 오른쪽 설명 9 : 차트 1 비율"] 설명 문단과 '차트' 단추 = 한 줄(단추는 위 맞춤, 글자 길이만큼) */
.hc-row { display:flex; align-items:flex-start; gap:10px; } .hc-row > p { flex:9 1 0; min-width:0; } .hc-act { flex:1 0 auto; display:flex; justify-content:flex-end; }
.pc-lv { margin:6px 0 2px; } .pc-lv:empty { display:none; } .pc-lv-up { color:var(--pos); } .pc-lv-dn { color:var(--neg); } .pc-lv-take { color:#ef6c00; } .pc-lv-avg { color:var(--muted); }
.hc-msg:empty { display:none; } .hc-note { margin:8px 0 0; padding-left:18px; } .hc-note:empty { display:none; } .hc-note li { margin:2px 0; }
h2.act-line { margin-top:0; }
.act-line > .fh-line { flex:1 1 100%; margin-top:0; }
h3.act-line { margin:18px 0 10px; }
div.act-line { margin:0 0 8px; }
/* [2026-10-20 휴대폰 지적 "켜고 끄는 건 셀렉트보다 스위치"] 켬/끔 스위치(web_layout.switch: 체크박스 + CSS, 스크립트 없음). 켜짐 = accent, 글자 켬/끔이 같이 바뀐다 */
.sw { display:inline-flex; align-items:center; gap:8px; position:relative; cursor:pointer; min-height:36px; white-space:nowrap; }
.sw > input { position:absolute; opacity:0; width:1px; height:1px; margin:0; pointer-events:none; }
.sw-ui { position:relative; flex:none; width:46px; height:28px; border-radius:14px; background:var(--surface2); border:1px solid var(--ctl-line); transition:background .15s, border-color .15s; }
.sw-ui::after { content:''; position:absolute; top:3px; left:3px; width:20px; height:20px; border-radius:50%; background:var(--muted); transition:transform .15s, background .15s; }
.sw > input:checked + .sw-ui { background:var(--accent); border-color:var(--accent); }
.sw > input:checked + .sw-ui::after { transform:translateX(18px); background:var(--accent-ink); }
.sw > input:focus-visible + .sw-ui { outline:2px solid var(--link); outline-offset:2px; }
.sw-on, .sw-off { font-weight:600; min-width:1.6em; }
.sw-on { color:var(--ok); } .sw-off { color:var(--muted); }
.sw > input:checked ~ .sw-off, .sw > input:not(:checked) ~ .sw-on { display:none; }
@media (pointer:coarse) { .sw { min-height:44px; } }
/* 누르면 바로 바뀌는 켜기·끄기 = 스위치 모양 제출 버튼(web_layout._onoff_sw, button.btn-sw[aria-checked]) - 위 .sw 와 같은 모양 */
.btn-sw { appearance:none; -webkit-appearance:none; background:none; border:0; padding:4px 0; margin:0; min-height:36px; display:inline-flex; align-items:center;
  gap:8px; cursor:pointer; color:inherit; font:inherit; white-space:nowrap; vertical-align:middle; }
.btn-sw[aria-checked=true] .sw-ui { background:var(--accent); border-color:var(--accent); }
.btn-sw[aria-checked=true] .sw-ui::after { transform:translateX(18px); background:var(--accent-ink); }
.btn-sw .sw-t { font-weight:600; min-width:1.6em; text-align:left; color:var(--muted); }
.btn-sw[aria-checked=true] .sw-t { color:var(--ok); }
.btn-sw:focus-visible { outline:none; } .btn-sw:focus-visible .sw-ui { outline:2px solid var(--link); outline-offset:2px; }
.btn-sw:disabled, form.busy .btn-sw { opacity:.6; cursor:progress; }
@media (pointer:coarse) { .btn-sw { min-height:44px; } }
/* [2026-10-20 사용자 "모달만 뜨고 스위치만 변경"] 스위치 확인 모달(dashboard.SWITCH_JS, <dialog>) · 결과 알림(잠깐 떴다 사라짐) */
dialog.sw-dlg { box-sizing:border-box; width:min(360px, calc(100vw - 32px)); padding:20px; border:1px solid var(--line2); border-radius:14px; background:var(--surface); color:var(--text); }
dialog.sw-dlg::backdrop { background:rgba(0,0,0,.55); }
dialog.sw-dlg h3 { margin:0 0 8px; font-size:17px; }
dialog.sw-dlg p { margin:0 0 12px; color:var(--text2); }
dialog.sw-dlg .btn-line { display:flex; gap:10px; justify-content:flex-end; margin:16px 0 0; }
dialog.sw-dlg .btn-line .btn { min-width:88px; justify-content:center; text-align:center; }
.sw-toast { position:fixed; left:50%; transform:translateX(-50%); bottom:calc(80px + env(safe-area-inset-bottom)); z-index:9998;
  width:max-content; max-width:calc(100vw - 32px); margin:0; box-shadow:0 4px 16px rgba(0,0,0,.35); }
/* [2026-10-20 사용자: "데이터가 많아질 건데 리스트(페이지)·상세 또는 리스트·펼침"] 목록 컴포넌트(web_list.py) - 거르기 칩 줄·기록 줄 펼침·페이지 번호 */
.flt { display:flex; flex-wrap:wrap; align-items:center; gap:8px 10px; margin:0 0 12px; }
.flt-l { font-size:12px; color:var(--muted); min-width:3em; }
.xlist { border-top:1px solid var(--line); margin:0 0 4px; }
.xrow { border-bottom:1px solid var(--line); }
.xrow > .xs { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:12px 2px; list-style:none; cursor:pointer; min-height:44px; box-sizing:border-box; }
.xrow.plain > .xs { cursor:default; }
.xrow > summary.xs::-webkit-details-marker { display:none; }
/* [10-30 디자인 검수] 펼침 표시 = 같은 갈매기 모양(작고 흐린 ▾ 는 누를 수 있는지 안 보였다) */
.xrow > summary.xs::after { content:''; flex:none; width:7px; height:7px; border-right:2px solid var(--text2); border-bottom:2px solid var(--text2); transform:rotate(45deg); margin:0 4px 4px 8px; transition:transform .15s; }
.xrow[open] > summary.xs::after { transform:rotate(-135deg); margin-bottom:-2px; }
.xrow > summary.xs:focus-visible { outline:2px solid var(--link); outline-offset:-2px; border-radius:6px; }
.xs .xt { flex:1 1 auto; min-width:0; }
.xs .xt > b, .xs .xt > .lt { font-size:15px; font-weight:600; } .xs .xm b { font-size:inherit; }   /* [10-30 재검수] 보조 줄 안 <b>(시장 이김 등)가 제목 크기로 커졌다 - 제목 b 만 */
.xs .xm { display:block; font-size:12px; color:var(--muted); margin-top:2px; overflow-wrap:anywhere; }
.xs .xv { flex:none; text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap; font-size:14px; }
.xs .xv small { display:block; font-size:12px; color:var(--muted); }
/* [10-30 재검수 3차] 체결 줄 = 홈 최근 매매(lrow)와 같은 모양 - 제목 줄 전체(방향 굵게 + 종목·차수 보통) 15px 본문색, 손익 작은 줄도 손익 색 */
.xs .xt { font-size:15px; color:var(--text); } .xs .xv small.pos { color:var(--pos); } .xs .xv small.neg { color:var(--neg); }
.xs .xt { min-width:0; flex:1 1 auto; } .xs .xv .warn-t, .xs .xv .muted { white-space:normal; display:inline-block; max-width:45vw; }   /* [10-30 재검수 3차] 제목 nowrap 은 긴 전략 이름이 숫자·갈매기를 덮었다 - 제목은 접히고 오른쪽 긴 글만 폭 제한 */   /* [10-30] 오른쪽 글이 길면 이름 대신 오른쪽이 줄을 바꾼다('빗썸(코 / 인)') */
.xrow .xd { padding:2px 2px 14px; font-size:13px; }
.xs .xds { display:block; font-size:12px; color:var(--muted); margin-top:2px; overflow-wrap:anywhere; }   /* [11-01] 전략 설명 = 이름 아래 작은 줄(제목에 이어 굵게 쓰면 좁은 칸에 7줄) */
.xs .xv .fxk { display:block; font-size:12px; }   /* [11-01] 전략·목록 펼침 줄 외화 손익 원화 환산 = 휴대폰은 다음 줄(체결 줄 .lv 는 그대로 한 줄)(한 줄로 두면 숫자 칸이 넓어 제목 칸이 좁아졌다) */
.xrow.new > .xs .xt b { color:var(--text); }
.kv { display:grid; grid-template-columns:max-content minmax(0,1fr); gap:6px 14px; margin:0; }
.kv dt { color:var(--muted); font-size:12px; } .kv dd { margin:0; overflow-wrap:anywhere; }
/* [2026-11-03 사용자 "중앙정렬로 하고"] 페이지 줄 = 모든 폭 가운데(건수 위 줄 · 번호 아래 줄) - 예전 PC = 건수 왼쪽·번호 오른쪽 끝 */
.pager { display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:8px 10px; margin:14px 0 4px; }
.pg-info { flex:1 1 100%; text-align:center; font-size:12px; color:var(--muted); }
.pg-row { display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:6px; }
.pg { display:inline-flex; align-items:center; justify-content:center; min-width:36px; min-height:36px; padding:0 10px; box-sizing:border-box;
  border:1px solid var(--ctl-line); border-radius:8px; color:var(--text2); text-decoration:none; font-size:13px; font-variant-numeric:tabular-nums; }
.pg.on { border-color:var(--accent); background:var(--accent); color:var(--accent-ink); font-weight:600; }
.pg.off { opacity:.45; }
.pg-gap { color:var(--muted); padding:0 2px; }
@media (pointer:coarse) { .pg { min-width:44px; min-height:44px; } }
/* 목록 줄 오른쪽 작은 글씨는 다음 줄로('마지막 로그인' + 날짜가 붙어 보였다) · 줄 목록 안 '선택 + 버튼'(연장 개월 등)은 휴대폰도 한 줄 */
.lrow .lv small { display:block; font-size:12px; color:var(--muted); }
.svc-line form.filter:not(:has(input:not([type=hidden]))) { flex-wrap:nowrap; }
.svc-line form.filter:not(:has(input:not([type=hidden]))) > .fg { flex:0 1 auto !important; }
/* [2026-10-20] 검색 줄(type=search 칸 하나 + '검색') = 휴대폰도 한 줄(칸이 채우고 버튼은 끝) - OTP·금액처럼 버튼을 아래 꽉 채우지 않는다 */
form.filter:has(> .fg > input[type=search]) { flex-wrap:nowrap; }
form.filter:has(> .fg > input[type=search]) > .fg-act { flex:0 0 auto !important; }
form.filter:has(> .fg > input[type=search]) > .fg:has(> input[type=search]) { flex:1 1 auto !important; min-width:0; }
/* 휴대폰: 거르기 칩 한 줄을 옆으로 밀기(서비스 10개가 4줄을 차지했다) - 탭과 같은 방식 */
@media (max-width:600px) { .flt { flex-wrap:nowrap; } .flt-l { flex:none; } .flt .chips { flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; padding-bottom:2px; }
  .flt .chip { flex:0 0 auto; white-space:nowrap; } }
/* [2026-10-31 사용자 캡처: "페이징 네비게이션 수정해야 하지 않나 - 앞뒤로만 이동 가능하잖아"] 휴대폰도 쪽 번호(첫·현재 앞뒤·마지막 + …) 보임 - 예전엔 현재 쪽 말고 모두 숨겨
   37건(2쪽)에서 '1'만 남았다. 자리를 위해 이전·다음은 화살표만(글자 .pg-tx 숨김), 넘치면 가운데 정렬로 줄바꿈 */
@media (max-width:600px) { .pager { justify-content:center; } .pg-info { flex:1 1 100%; text-align:center; } .pg-row { justify-content:center; gap:4px; } .pg-nav .pg-tx { display:none; } .pg { padding:0 8px; } }
/* [2026-11-03 사용자 캡처 "패이징은 왜 이렇게 나오지"] 휴대폰(600px 이하) = 화살표 + 번호 5개 묶음 한 줄(묶음 밖 첫·마지막 '1 …'·'… 30' = .far 숨김).
   예전 400px 이하 .near(현재 앞뒤 번호) 숨김 -> 5쪽 중 1쪽에서 '‹ 1 … 5 ›'만 보였다.
   360px 카드 안쪽 약 288px: 너비 36px x 7 + 간격 3px x 6 = 270px(높이는 터치 44px 그대로) - 44px 폭이면 '›'가 다음 줄로 넘어갔다 */
@media (max-width:600px) { .pg-row .far { display:none; } }
@media (max-width:400px) { .pg-row { gap:3px; } .pg-row .pg { min-width:36px; padding:0 4px; } }
/* 휴대폰 줄 카드: 스위치가 든 조작 칸 = 칸 이름(변경·설정) 왼쪽·스위치 오른쪽 한 줄, 나머지 칸·저장은 아래 줄마다 */
@media (max-width:600px) {
  table.stack td:has(form .sw) form:has(.sw):not(#_) { display:contents !important; }   /* :not(#_) = 줄 카드 조작 칸 규칙(td:has(form input:not(...)))보다 앞서게 */
  table.stack td:has(form .sw) form > .fg:has(> .sw) { flex:0 0 auto !important; margin-left:auto; }
  table.stack td:has(form .sw) form > .fg:not(:has(> .sw)):not(.fg-act) { flex:1 1 100% !important; }
  table.stack td:has(form .sw) form > .fg-act { flex:1 1 100% !important; }
}
/* ⑦ 조작만 든 문단(web_layout): 폼 여럿 = 한 줄에 하나(최대 640px), 버튼 여럿 = 줄바꿈 사이 10px */
.form-stack { margin:12px 0; max-width:480px; }
.form-stack > form { display:flex !important; flex-wrap:wrap; align-items:center; gap:10px 8px; margin:0 !important; width:100%; }
.form-stack > form + form { margin-top:10px !important; }
.form-stack > form > input:not([type=hidden]):not([type=checkbox]):not([type=radio]), .form-stack > form > select { flex:1 1 8em; min-width:0; max-width:none; }
.btn-line { display:flex; flex-wrap:wrap; align-items:center; gap:10px 8px; }
td .fh-line { text-align:left; }
.login .card > form:not(.inline) { margin-bottom:0; }
.login a.btn, .login .card > p > a.btn:only-child { display:flex; width:100%; box-sizing:border-box; justify-content:center; align-items:center;
  padding:12px; font-size:16px; min-height:46px; margin-top:10px; }
.login .card > p:has(> a.btn:only-child) { margin:0; }
.login .card > form + p, .login .card > form + ul, .login .card > p:has(> a.btn:only-child) + p { margin-top:14px; }
/* [2026-11-01 사용자: "스프릿 전체의 새 스프릿 버튼하고 각 서비스의 키 설정 버튼 높이가 너무 크고, 키가 없을 때 설명 후 아래에 버튼 구조라 화면을 많이 차지"]
   ① 카드 제목 줄(.sec)·전략 머리 줄(.strat-head)의 단추 = 작은 단추(높이 32px, 좌우 12px) - 제목 글자 줄보다 크지 않게
   ② 안내 + 단추 = 한 줄(.act-row: 왼쪽 글 .act-t 가 남는 폭, 오른쪽 단추). 10-30 '글 바로 뒤에 단추 붙이지 말 것'은 지킨다(단추는 줄 오른쪽 끝) */
.sec > .btn, .sec > a.btn, .sec-acts > .btn, h2 > a.btn, h3 > a.btn, .strat-head .btn, .act-row > .btn, .btn-sm { min-height:32px; padding:5px 12px; font-size:13px; line-height:1.3;
  display:inline-flex; align-items:center; justify-content:center; white-space:nowrap; flex:0 0 auto; margin:0; width:auto; box-sizing:border-box; }
.act-row { display:flex; align-items:center; justify-content:space-between; gap:12px; }
/* [2026-11-01 사용자 "G로 변경하자"] 로고 앞 브랜드 마크(앱 아이콘 축소 - 둥근 칸) */
.brand { display:inline-flex; align-items:center; gap:8px; } .brand-mark { width:24px; height:24px; border-radius:6px; flex:0 0 auto; }
.act-row > .act-t { flex:1 1 auto; min-width:0; }
.act-row > .act-t > .sub { display:block; font-size:12px; color:var(--muted); margin-top:2px; }
.warnbox.act-row, .flash.act-row { padding:10px 12px; }
.warnbox.act-row > a.btn, .flash.act-row > a.btn { margin:0; width:auto; display:inline-flex; }
/* ===== [2026-11-01 사용자 "pc 화면 디자인은 다시 한번 검증 - 한 줄에 표현해도 될 것 같고 두 줄에 나오고 정렬이 잘 안되어 있어"] PC 폭 정리(13-3) =====
   휴대폰(412px)용 두 줄·세로 쌓임이 1120px 본문에 그대로 남아 줄마다 높이가 들쭉날쭉하고 이름표와 숫자가 1,000px 떨어졌다. 휴대폰 모양은 그대로(아래는 모두 min-width) */
.sec > .sec-acts { display:inline-flex; align-items:center; gap:14px; flex:0 0 auto; } .sec-acts > a:not(.btn) { padding:4px 0; }   /* 제목 줄 오른쪽 '+ 만들기'·'전체 보기' 한 묶음 */
/* ① 맨 아래 고지 = 본문과 같은 왼쪽 선(예전 화면 끝 16px 까지 넓어 본문 1120px 보다 튀어나왔다) */
@media (min-width:1152px) { body:not(.app) > .disclaimer { max-width:1120px; margin-left:auto; margin-right:auto; box-sizing:border-box; } }
@media (min-width:601px) {
  /* ② 서비스 탭 '키움 / (국내)' 두 줄 = 휴대폰 넷이 한 줄에 들어가게 한 것 - 태블릿·PC 는 '키움(국내)' 한 줄 */
  .tabs.svc-tabs a { flex-direction:row; align-items:baseline; gap:2px; }
  .tabs.svc-tabs a small { display:inline; font-size:inherit; opacity:1; }
  /* ③ 거르기 줄 '서비스' 이름표가 칩 위 줄로 떨어졌다(칩이 한 줄을 넘으면) - 이름표 왼쪽 고정, 칩만 줄바꿈 */
  .flt { flex-wrap:nowrap; align-items:flex-start; } .flt-l { flex:none; display:flex; align-items:center; min-height:31px; } .flt .chips { flex:1 1 auto; min-width:0; }   /* 이름표 = 첫 칩 줄과 같은 높이 가운데 */
  /* ⑦ 기간 '시작일 ~ 끝일'(백테스트) = 한 줄 - 날짜 칸 하나가 28em 이라 끝일이 다음 줄로 떨어졌다 */
  .fld-wide .fi input[type=date] { flex:1 1 0; width:auto; min-width:0; }
  /* ⑧ 버튼 모양 선택 4개(문의 분류·역할, g2 = 휴대폰 2x2) = 한 줄 넷 */
  .pick.g2:has(> .pk:nth-child(4):last-child) { grid-template-columns:repeat(4, minmax(0,1fr)); }
  /* ⑫ 숫자 타일 표(관리자 '오늘 할 일' 8칸) = 같은 폭 칸 격자 - 줄바꿈 상자(flex)는 7칸 뒤 남은 1칸이 1,080px 로 늘었다 */
  table.tiles tr { display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); }   /* [11-01] 8칸 한 줄(130px)이라 이름이 2~3줄로 접혔다 -> 한 줄 4칸(8칸 = 4+4) */
}
/* ⑨ 세로 글쓰기 폼(form-col) 제목 칸 = 폼 폭 전체(640px) - 공용 입력 최대 28em 규칙이 더 구체적이라 제목만 364px 로 짧았다(내용 칸·보내기 단추와 오른쪽 끝이 달랐다) */
form.form-col > p > input:not([type=hidden]):not([type=checkbox]):not([type=radio]) { max-width:none; }
@media (pointer:coarse) and (min-width:601px) { .flt-l { min-height:44px; } }   /* 터치 기기 칩 = 44px */
@media (min-width:1024px) {
  /* ④ 숫자가 있는 목록 줄(lrow·xrow) = 한 줄: 제목 | 보조 글(같은 줄, 제목 칸 최소 10em 으로 보조 글 시작선 맞춤) … 숫자들(같은 줄). 길면 보조 글만 다음 줄 */
  .lrow:has(> .lv) > div:first-child { display:flex; flex-wrap:wrap; align-items:baseline; column-gap:14px; }
  .lrow:has(> .lv) > div:first-child > :first-child { flex:0 0 auto; min-width:10em; }
  .lrow:has(> .lv) > div:first-child > .ls { margin-top:0; }
  .lrow > .lv { display:flex; align-items:baseline; justify-content:flex-end; column-gap:12px; }
  .lrow > .lv > .ls, .lrow > .lv > small { display:inline; margin-top:0; }
  .lrow > .lv:not(:has(> .muted.u-fs-12:first-child)) > :last-child:not(:only-child) { min-width:7.5em; }   /* 끝 칸 폭을 맞춰 앞 칸(수익률 등) 오른쪽 선이 줄마다 같게(시각이 끝으로 가는 체결 줄 제외) */
  .lrow > .lv > .muted.u-fs-12:first-child:not(:only-child) { order:9; }   /* 체결 시각 = 줄 끝(매수 줄·매도 줄 시각 자리가 같게) */
  .xs > .xt > .xm { display:inline-block; margin:0 0 0 12px; }
  .xs > .xt > .xds { display:inline; margin:0 0 0 8px; }
  .xs .xv .fxk { display:inline; font-size:inherit; }
  .xs > .xv { display:flex; align-items:baseline; justify-content:flex-end; gap:12px; }
  .xs > .xv small, .xs > .xv .ls { display:inline; margin:0; }
  .xs > .xv > small:first-child:not(:only-child) { order:9; }
  /* ⑤ 카드 안 이름표·값 줄(.price) = 칸 격자(280px 이상) - 1120px 한 줄에 이름표 왼쪽 끝·값 오른쪽 끝으로 떨어지지 않게. 차수 펼침(640px 안)은 그대로 */
  .card > .price, .card > div > .price, .card > details > .price { display:grid; grid-template-columns:repeat(auto-fill, minmax(280px, 1fr)); column-gap:40px; }
  /* ⑥ 세로 폼(스프릿 만들기 등)의 '한 줄 전체' 칸(종목 선택·전략명)·선택 상자·틀 고르기 = 최대 640px - 1,080px 로 늘어 아래 칸(제 폭)·주 버튼(640px)과 오른쪽 끝이 제각각이었다 */
  .fields > select, .fields > input:not([type=hidden]):not([type=radio]):not([type=checkbox]), .step > .opts, .tplgrid { max-width:640px; }
  /* ⑩ 기간 고르기(.seg 오늘·이번 주·이번 달·전체) = 최대 640px(주 버튼 줄과 같게) - 1,120px 에 넷이 280px 씩 늘었다 */
  .seg { max-width:640px; box-sizing:border-box; }
  /* ⑪ 오늘 시황 세 시장(국내·미국·코인 .stat) = 한 줄 세 칸 - 글 길이대로 놓여 코인만 다음 줄 왼쪽에 떨어졌다 */
  .card > .stat { width:calc((100% - 20px) / 3); margin-right:10px; box-sizing:border-box; vertical-align:top; }
  .card > .stat:nth-of-type(3n) { margin-right:0; }
}

:root[data-theme=light] { color-scheme:light; } :root[data-theme=dark] { color-scheme:dark; }
