
/* ── 확장 1·2: 한글 + 오프라인 폰트 ─────────────────────────────────────
   토큰을 고치지 않는다. 새 이름으로 스택을 만들어 선언된 라틴 패밀리를 앞에 두고
   제네릭 **앞**에 Pretendard 를 끼운다. */
@font-face{font-family:"Pretendard";font-weight:400;font-style:normal;font-display:swap;
  src:local("Pretendard Regular"),local("Pretendard"),
      url("fonts/Pretendard-Regular.otf") format("opentype")}
@font-face{font-family:"Pretendard";font-weight:500;font-style:normal;font-display:swap;
  src:local("Pretendard Medium"),url("fonts/Pretendard-Medium.otf") format("opentype")}
@font-face{font-family:"Pretendard";font-weight:700;font-style:normal;font-display:swap;
  src:local("Pretendard Bold"),url("fonts/Pretendard-Bold.otf") format("opentype")}

:root{
  --font-body-ko:"Inter","Pretendard","Malgun Gothic",ui-sans-serif,system-ui,sans-serif;
  --font-heading-ko:"Space Grotesk","Pretendard","Malgun Gothic",ui-sans-serif,sans-serif;
}
body{font-family:var(--font-body-ko)}
h1,h2,h3,h4,.bento-title,.bento-metric{font-family:var(--font-heading-ko)}
.tnum,.mono{font-variant-numeric:tabular-nums}

/* ── `hidden` 이 실제로 숨긴다 ───────────────────────────────────────────
   `[F✔]` 2026-09-01 사용자 지적 — 실시간 카드의 종가 화살표가 종가가 없는
   날에도 **계속 떠 있었다.** 마크업과 JS 는 맞았다(`.mon-cl` 에 `hidden`,
   `paintClose` 가 `box.hidden = true`). 진 것은 CSS 다:

     `hidden` 속성은 **UA 시트**의 `[hidden]{display:none}` 으로 동작한다.
     작성자(author) 스타일은 특정도와 무관하게 UA 스타일을 **언제나 이긴다**.
     그래서 `.mon-cl{display:inline-flex}` 한 줄이 `hidden` 을 통째로 무력화했다.

   `display` 를 주는 클래스마다 개별로 방어하면 다음에 만드는 요소가 또 밟는다.
   전역 규칙 하나로 닫는다 — `!important` 는 여기서 남용이 아니라 **UA 기본을
   되돌려 놓는** 최소 수단이다(브라우저가 원래 갖는 동작이다). */
[hidden]{display:none!important}

/* ── 앱 셸 — 사이드바 + 본문. 시스템은 페이지 셸을 규정하지 않는다 ────── */
.app{display:grid;grid-template-columns:216px 1fr;min-height:100vh}
#sb{position:sticky;top:0;align-self:start;height:100vh;display:flex;
  flex-direction:column;gap:var(--space-1);padding:var(--space-5) var(--space-4);
  background:var(--color-bg);border-right:1px solid var(--color-divider);
  overflow-y:auto}
.sb-h{padding:0 var(--space-2) var(--space-4)}
/* 워드마크가 홈 링크다 (2026-09-08 사용자 지시 "페이지 제목을 누르면 홈으로").
   시스템 시트의 `a{}` 는 색만 정하고 밑줄을 지우지 않아, span 을 a 로 바꾸면
   제목에 밑줄이 붙는다. 활성 표시는 `.nv.on` 과 **같은 관용구**(면 채움)를
   쓴다 — 사이드바 안에서 두 가지 활성 표기가 생기지 않게. */
.sb-h .wm{display:block;text-decoration:none;border-radius:var(--radius-sm);
  padding:var(--space-2);margin:calc(var(--space-2)*-1);
  transition:background var(--dur) var(--ease)}
.sb-h .wm:hover{background:var(--color-surface)}
.sb-h .wm.on{background:var(--color-surface)}
.sb-h .wm b{display:block;font-family:var(--font-heading-ko);font-size:15px;
  letter-spacing:-0.01em;color:var(--color-text)}
.sb-h .wm span{display:block;margin-top:2px;font-size:11px;font-weight:600;
  letter-spacing:.11em;text-transform:uppercase;color:var(--color-muted)}
.nv{display:flex;align-items:center;gap:var(--space-2);
  padding:9px var(--space-3);border-radius:var(--radius-sm);
  font-size:13.5px;color:var(--color-muted);text-decoration:none;border:0;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease)}
.nv:hover{background:var(--color-surface);color:var(--color-text)}
.nv.on{background:var(--color-surface);color:var(--color-text);font-weight:600}
.nv.on::before{content:"";width:3px;height:16px;border-radius:2px;
  background:var(--color-accent);margin-left:-6px;margin-right:3px}
.nv i{display:none}
.nv .n{flex:1;min-width:0}
.nv .cnt{font-size:11px;font-variant-numeric:tabular-nums;color:var(--color-muted)}
.nv.on .cnt{color:var(--color-accent-300)}
.sb-sep,.sb-f{display:none}
.main{min-width:0}
.wrap{max-width:1560px;margin:0 auto}
.body{padding:var(--space-6) var(--space-6) var(--space-12);
  display:flex;flex-direction:column;gap:var(--space-6)}

/* 페이지 머리 */
.strip{display:flex;align-items:flex-end;gap:var(--space-8);flex-wrap:wrap;
  padding:var(--space-6);border-bottom:1px solid var(--color-divider)}
.strip .pg b{display:block;font-family:var(--font-heading-ko);font-size:26px;
  letter-spacing:-0.02em;color:var(--color-text)}
.strip .pg span{display:block;margin-top:var(--space-1);font-size:12.5px;
  color:var(--color-muted)}
.mx{display:flex;gap:var(--space-6);flex-wrap:wrap;margin-left:auto}
/* 본문 안에 쓰는 지표 줄 `[F]` 2026-09-04 — 머리 스트립이 모든 탭에서
   같은 실시간 값을 쓰게 되면서(사용자 지시) 덤프 기준일·지연은 본문으로
   내려왔다. 같은 `.m/.k/.v` 를 쓰되 오른쪽으로 밀지 않는다. */
.mx.basis{margin-left:0;margin:var(--space-3) 0 var(--space-4)}
.mx .m{min-width:76px}
.mx .m .k{display:block;font-size:11px;font-weight:600;letter-spacing:.11em;
  text-transform:uppercase;color:var(--color-muted);margin-bottom:2px}
.mx .m .v{font-family:var(--font-heading-ko);font-size:18px;letter-spacing:-0.02em;
  color:var(--color-text);font-variant-numeric:tabular-nums}
.mx .m .v small{font-size:11px;color:var(--color-muted);margin-left:2px}
.mx .m .v .up{color:var(--color-accent)}
.strip .act{display:flex;gap:var(--space-2)}

/* ── 트레이 밖 요소 — 시스템 규칙: 산문·표는 격자에 넣지 않는다 ───────── */
.lane,.sec,.ph{display:flex;align-items:baseline;gap:var(--space-3);flex-wrap:wrap;
  margin:var(--space-4) 0 0}
.lane b,.sec-l,.ph h2{margin:0;font-family:var(--font-heading-ko);font-size:19px;
  letter-spacing:-0.01em;color:var(--color-text);font-weight:700}
.lane b::before,.sec-l::before,.ph h2::before{content:"";display:inline-block;
  width:26px;height:3px;border-radius:2px;background:var(--color-accent);
  vertical-align:middle;margin-right:var(--space-3)}
.lane span,.sec-s,.ph .c{font-size:12.5px;color:var(--color-muted)}
.ph .r,.sec-s{margin-left:auto;font-size:12px;color:var(--color-muted)}
.sec{margin-top:var(--space-8)}
.lane i,.sec-t{display:contents}

/* 트레이 밖 블록 — 표·달력·큰 차트·해설이 들어간다. 시스템 규칙상 격자에
   넣지 않는 것들이고, 타일이 아니므로 라운드만 시스템 값을 따른다. */
.blk{display:flex;flex-direction:column;gap:var(--space-3);min-width:0}
.blk .cap{margin-bottom:0}
.blkbody{min-width:0}
/* `.blk.bento-accent` 채움 규칙은 지웠다 — 2026-08-31 사용자 요청(가독성,
   라임 카드 폐기·색상 통일). `_acc()` 가 중성 타일을 내므로 죽은 규칙이었다. */

/* 산문 블록 */
.note{font-size:13px;line-height:1.55;color:var(--color-muted);margin:0}
.note.warn{padding:var(--space-3) var(--space-4);border-radius:var(--radius-sm);
  background:var(--color-surface);border-left:3px solid var(--color-accent)}
.note strong,.note b{color:var(--color-text);font-weight:600}
.note code,.bento-spec code,code{font-family:var(--font-mono);font-size:.92em;
  color:var(--color-accent-300)}
.dim{color:var(--color-muted)}
.warn{color:var(--color-text)}
.rule{margin:0;padding:var(--space-4);border-radius:var(--radius-sm);
  background:var(--color-surface-2);font-size:13px;line-height:1.55;
  color:var(--color-text)}
/* 툴팁이 달린 낱말 — `[F]` 2026-08-31 신선도 집계 한 줄(`site._fnote`).
   접은 내용(제외 사유·결측 근거·표 이름 전량)이 있다는 **사실 자체**가
   화면에 보여야 한다: 표지가 없으면 아무도 마우스를 올리지 않고, 그러면
   접은 것이 곧 버린 것이 된다. 새 색을 만들지 않고 점선 밑줄만 쓴다. */
.tipword{border-bottom:1px dotted var(--color-neutral-500);cursor:help}

/* ── 타일 안 내용 — 시스템 내용 클래스에 얹는 것만 ────────────────────── */
.bento-tile{container-type:inline-size;container-name:tile}
.cap{display:flex;align-items:baseline;gap:var(--space-2);flex-wrap:wrap;
  font-size:11px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:var(--color-muted)}
.cap .ct{letter-spacing:.11em}
.cap .dot{display:none}
.cap .tag{margin-left:auto;letter-spacing:.06em;color:var(--color-muted)}
.cap .tag.live{color:var(--color-accent-300)}
.cap .tag.warnt{color:var(--color-accent-2-300)}
.tilebody{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-2);
  justify-content:flex-start;overflow:hidden}
.stat .v{font-family:var(--font-heading-ko);font-size:clamp(28px,3.4vw,46px);
  line-height:1;letter-spacing:-0.03em;font-variant-numeric:tabular-nums;
  color:var(--color-text)}
.stat .v .u,.stat .v small{font-size:.42em;color:var(--color-muted);margin-left:.25em}
.stat .v.lime{color:var(--color-accent)}
.stat .n,.stat .why{font-size:12.5px;color:var(--color-muted)}
.stat .why em{font-style:normal;color:var(--color-accent-300);font-weight:600}
.stat .v .dash,.dash{font-size:.5em;color:var(--color-muted)}

/* 라벨/값 행 — 타일 안에서 쓰는 유일한 표 대체물 */
.statrow,.led,.g,.rk-r,.pr-r,.tile{display:flex;justify-content:space-between;
  align-items:baseline;gap:var(--space-3);padding:var(--space-2) 0;
  border-bottom:1px solid var(--color-divider);font-size:13px}
.statrow:last-child,.led:last-child,.g:last-child,.rk-r:last-child,
.pr-r:last-child,.tile:last-child{border-bottom:0}
.statrow .k,.led span,.rk-n,.pr-n,.tl{color:var(--color-muted);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.statrow .val,.led b,.rk-v,.pr-v,.tv{font-weight:600;color:var(--color-text);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.led.warn b,.led.crit b{color:var(--color-accent)}
.gz,.rk,.pr,.tiles{display:flex;flex-direction:column;min-width:0}
.tiles.g2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:0 var(--space-4)}
.rk-r,.pr-r{align-items:center}
.rk-i{font-size:11px;color:var(--color-muted);font-variant-numeric:tabular-nums;
  width:18px;flex:0 0 auto}
.g .gk{display:flex;justify-content:space-between;gap:var(--space-2);width:100%}
.g .gt,.pr-t{display:block;height:4px;border-radius:2px;
  background:var(--color-neutral-700);flex:1;min-width:36px}
.g .gt i,.pr-f{display:block;height:4px;border-radius:2px;
  background:var(--color-accent-2)}
.g .gt i.warn,.g .gt i.crit{background:var(--color-accent)}
.tile .p{font-size:11px;color:var(--color-muted);margin-left:var(--space-1)}
.tile .chip{font-size:11px;font-weight:600;color:var(--color-muted)}
.tile .tb{display:none}
.rd{display:grid;grid-template-columns:auto 1fr;gap:0 var(--space-3);margin:0}
.rd dt{padding:var(--space-2) 0;font-size:13px;color:var(--color-muted);
  border-bottom:1px solid var(--color-divider)}
.rd dd{margin:0;padding:var(--space-2) 0;font-size:13px;font-weight:600;
  text-align:right;color:var(--color-text);font-variant-numeric:tabular-nums;
  border-bottom:1px solid var(--color-divider)}
.rd dd.warn{color:var(--color-accent)}
.rd dt:last-of-type,.rd dd:last-of-type{border-bottom:0}

/* 배지 — 두 어휘를 절대 같은 모양으로 쓰지 않는다.
   우리 판정(.b)은 채움 없는 라임/애저 윤곽, mficc 등재 상태(.ms)는 사각 채움. */
.b,.st,.ms{display:inline-flex;align-items:center;align-self:flex-start;
  font-size:11px;font-weight:600;
  letter-spacing:.06em;padding:2px var(--space-2);border-radius:var(--radius-sm);
  white-space:nowrap}
.b{border:1px solid var(--color-divider);color:var(--color-muted)}
.b.채택,.b.통과{border-color:var(--color-accent);color:var(--color-accent-300)}
.b.폐기,.b.차단{border-color:var(--color-accent-2);color:var(--color-accent-2-300)}
.ms{background:var(--color-surface-2);color:var(--color-muted);
  border:1px solid var(--color-divider);border-radius:var(--radius-sm)}
.ms.실전{background:var(--color-accent);color:var(--color-accent-ink);
  border-color:var(--color-accent)}
.ms.후보{border-color:var(--color-accent-2);color:var(--color-accent-2-300)}
.st{border:1px solid var(--color-divider);color:var(--color-muted)}
.st.live{color:var(--color-accent-300);border-color:var(--color-accent-700)}
.st.err{color:var(--color-accent-2-300);border-color:var(--color-accent-2-700)}
/* `_state()` 는 다섯 종류를 내는데 색이 붙은 것은 live·err 둘뿐이었다 —
   **5영업일 지연 경고(`partial`)가 색 없이 렌더됐다** (측정 확인, 데스크 페이지의
   신선도 배지). 본문 크기 라임 글자는 규약대로 `--color-accent-300` 만 쓰고
   강도는 **테두리와 굵기**로 가른다. 채움(`background:var(--color-accent)`)은
   쓰지 않는다 — 카드 채움은 중성으로 통일했다(2026-08-31 라임 카드 폐기). */
.st.partial{color:var(--color-accent-300);border-color:var(--color-accent-600)}
.st.stale{color:var(--color-accent-300);border-color:var(--color-accent);
  font-weight:700}
.st.none{color:var(--color-muted);border-color:var(--color-neutral-700);
  border-style:dashed}
.dl{font-weight:600;font-variant-numeric:tabular-nums;color:var(--color-accent)}
.dl.dn,.dl.is-down{color:var(--color-accent-2-300)}
.dl.fl{color:var(--color-muted);font-weight:400}
/* ── D-day 등급 (calendar.html·입찰 표) ───────────────────────────────
   `[F]` 2026-08-31 사용자 요청 — 임박한 일정이 눈에 걸려야 한다. 이전 판은
   `.dl.crit` 을 붙였는데 **어느 시트에도 그 규칙이 없어** 오늘이 나머지와
   같은 색이었다(조용히 사라지는 클래스).
   새 색은 만들지 않는다: 계열 1(라임)이 임박, 계열 2(애저)가 이번 주,
   중성색이 먼 것과 지난 것이다. 문턱의 정본은 `site.DDAY_BANDS` 이고
   이 클래스 이름이 거기서 나온다. */
.dl.dd-today{color:var(--color-bg);background:var(--color-accent);
  padding:0 var(--space-2);border-radius:var(--radius-sm);font-weight:700}
.dl.dd-soon{color:var(--color-accent);font-weight:700}
.dl.dd-week{color:var(--color-accent-2-300);font-weight:600}
.dl.dd-far{color:var(--color-muted);font-weight:500}
.dl.dd-past{color:var(--color-neutral-500);font-weight:400}
/* 범례 — 칩 실물을 그대로 쓴다(견본을 따로 만들지 않는다) */
/* ── 대회 채점 표 (contest.html) ──────────────────────────────────────
   `[F]` 2026-09-14 사용자 지시 — "적중, 미적중 대신 O,X 로 하고 색깔 다르게".

   **빨강·초록을 쓰지 않는다.** 이 시트는 계열 둘(라임·애저)로 짜여 있고 그것이
   색각이상(CVD) 검증을 통과한 조합이다(푸터가 그 사실을 적고 있다). 적중/오답을
   빨강·초록으로 칠하면 그 검증 밖으로 나간다. 그래서 **글리프(O/X)로 먼저
   가르고 색은 계열 둘로 받친다** — 색을 못 보아도 O 와 X 는 구분된다.

   가운데 정렬 클래스(`ctr`)를 여기서 만든다. 시트에는 `num`(오른쪽)뿐이라
   짧은 라벨 열의 머리와 몸이 서로 다른 쪽으로 붙어 있었다(머리는 기본 왼쪽,
   몸은 `num` 이라 오른쪽) — 그 어긋남이 2026-09-14 지적의 알맹이다. */
.tw th.ctr,.tw td.ctr,.dt th.ctr,.dt td.ctr{text-align:center}
.mk{font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:0}
.mk-o{color:var(--color-accent)}                 /* 적중 — 계열 1(라임) */
.mk-x{color:var(--color-accent-2-300)}           /* 오답 — 계열 2(애저) */
.mk-v{color:var(--color-neutral-500);font-weight:400}   /* 무효 */
.mk-n{color:var(--color-neutral-700);font-weight:400}   /* 미채점 */
/* 잠정 채점 — 당일 일별 종가+라이브 틱으로 매긴 값. 다음날 1분봉이 확정한다.
   확정과 같은 모양으로 그리면 화면이 "이미 확정" 이라고 말한다. */
/* 실제 제출과 모의 — 글자 무게로 가른다(색을 한 겹 더 쓰지 않는다) */
.sent{color:var(--color-accent);font-weight:700}
.sent.dry{color:var(--color-muted);font-weight:400}
/* ── 접는 블록(details) ────────────────────────────────────────────────
   `[F]` 2026-08-31 — 시트에 `details` 규칙이 하나도 없었다. 클래스만 붙이면
   브라우저 기본 삼각형과 기본 여백이 그대로 나와 다른 블록과 어긋난다.
   여는 손잡이는 **표 제목(`.ph h2`)과 같은 무게**로 둔다 — 접혀 있어도
   "여기 뭐가 있다" 가 읽혀야 한다. */
.fold{margin:var(--space-4) 0 0}
.fold>summary{cursor:pointer;list-style:none;padding:var(--space-2) 0;
  font-size:12px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--color-muted);font-weight:600}
.fold>summary::-webkit-details-marker{display:none}
.fold>summary::before{content:"▸";display:inline-block;width:1.2em;
  color:var(--color-neutral-500)}
.fold[open]>summary::before{content:"▾"}
.fold>summary:hover{color:var(--color-text)}
/* ── 당일 확정 종가 — 가격 오른쪽(monitor.html) ───────────────────────
   사용자 요청 2026-08-31: 아래 별도 블록이 아니라 **카드 안 가격 오른쪽**에.
   44px 가격과 baseline 을 맞추고 종가는 한 단계 작게 — 왼쪽이 실시간,
   오른쪽이 확정값이라는 위계를 크기로 말한다. 새 색은 만들지 않는다
   (`.up`/`.down` 은 시트의 델타 규약을 그대로 쓴다). */
.mon-pxrow{display:flex;align-items:baseline;gap:var(--space-3);
  flex-wrap:wrap;min-width:0}
.mon-cl{display:inline-flex;align-items:baseline;gap:6px;min-width:0}
.mon-arw{font-size:20px;color:var(--color-neutral-500)}
.mon-clv{font-size:28px;line-height:1.1;color:var(--color-text);
  font-variant-numeric:tabular-nums}
.mon-clt{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}
.mon-clt.flat{color:var(--color-muted)}
/* ── (구) 당일 확정 종가 블록 — 카드 안으로 옮겨 쓰이지 않는다 ──────────
   `[F]` 2026-08-31 사용자 지적 — 종가를 받아도 실시간 화면에 없었다.
   라이브 타일과 **출처가 다르므로**(코스콤 실시간 vs 우리 원장 확정 종가)
   시각적으로도 갈라 둔다: 점선 테두리 + 별도 머리. 새 색은 만들지 않는다. */
.mon-close{margin-top:var(--space-4);padding:var(--space-4);
  border:1px dashed var(--color-divider);border-radius:var(--radius-md)}
.mon-close .mc-h{display:flex;align-items:baseline;gap:var(--space-3);
  flex-wrap:wrap;margin-bottom:var(--space-3)}
.mon-close .mc-h b{font-family:var(--font-heading-ko);font-size:14px;
  color:var(--color-text)}
.mon-close .mc-a{font-size:12px;color:var(--color-muted);
  font-variant-numeric:tabular-nums}
.mon-close .mc-g{display:grid;gap:var(--space-3);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,140px),1fr))}
.mon-close .mc-c{display:flex;flex-direction:column;gap:2px;min-width:0}
.mon-close .mc-t{font-size:11px;letter-spacing:.04em;color:var(--color-muted)}
.mon-close .mc-v{font-size:22px;color:var(--color-text)}
.mon-close .mc-k{font-family:var(--font-mono);font-size:11px;
  color:var(--color-neutral-500);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.mon-close .mc-n{margin:var(--space-3) 0 0;font-size:11.5px;
  color:var(--color-muted);max-width:78ch}
.dd-legend{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
  margin:var(--space-2) 0 var(--space-3);font-size:11.5px;color:var(--color-muted)}
.dd-legend-l{font-weight:600;color:var(--color-text)}
.dl.dd-key{font-size:11.5px;cursor:default}
.lb{display:inline-flex;align-items:center;gap:var(--space-1);font-size:11px;
  color:var(--color-muted)}
.lb::before{content:"";width:10px;height:3px;border-radius:2px;
  background:var(--color-accent)}
.lb.k::before{background:var(--color-accent-2)}
.lb.w::before{background:var(--color-neutral-500)}
td .lb::before{background:var(--color-neutral-500)}
.sbk{display:flex;flex-wrap:wrap;gap:var(--space-1)}
.sbk .s{flex:1 1 34px;padding:var(--space-1);text-align:center;font-size:11px;
  border-radius:var(--radius-sm);background:var(--color-surface-2);
  color:var(--color-muted)}
.sbk .s.ok{color:var(--color-accent-300)}
.sbk .s .sv{display:block;font-weight:600;color:inherit}

/* 링 — 시스템의 2색 원 개념. 라임은 경고에만, 기본은 애저 */
.ring{display:flex;align-items:center;gap:var(--space-4)}
.ring svg{flex:0 0 auto;width:88px;height:88px}
.ring .rt{fill:none;stroke:var(--color-neutral-700);stroke-width:9}
.ring .rf{fill:none;stroke:var(--color-accent-2);stroke-width:9;stroke-linecap:butt}
.ring .rf.warn{stroke:var(--color-accent)}
.ring .rv{fill:var(--color-text);font-family:var(--font-heading-ko);font-size:22px;
  font-weight:700;font-variant-numeric:tabular-nums}
.ring .rl{flex:1;min-width:0;font-size:12.5px;color:var(--color-muted);line-height:1.35}

/* ── 표 — 트레이 밖. 시스템 규칙이라 클리핑 문제가 같이 사라진다 ──────── */
.dt,.tw{position:relative;overflow-x:auto;border:1px solid var(--color-divider);
  border-radius:var(--radius-md);background:var(--color-surface)}
.dt.tall{max-height:70vh;overflow-y:auto}
.dt table,.tw table{width:100%;border-collapse:collapse;font-size:13px}
.dt th,.tw th{position:sticky;top:0;z-index:2;background:var(--color-neutral-900);
  color:var(--color-muted);font-size:11px;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;text-align:left;white-space:nowrap;
  padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--color-divider)}
.dt th.n,.tw th.num{text-align:right}
/* 머리의 단위 괄호(`site._th`). 괄호만으로도 경계는 생기지만 색까지 낮춰야
   열 **이름**이 먼저 읽힌다 — 2026-09-01 지적의 알맹이가 "이름과 분리가 잘
   안 됨" 이었다. 자간을 죽인다: 머리는 `letter-spacing:.09em` 대문자라
   `(백만원)` 이 그대로 늘어나면 이름보다 넓어진다. */
.dt th .th-u,.tw th .th-u{color:var(--color-neutral-500);font-weight:400;
  letter-spacing:0;text-transform:none}
.dt td,.tw td{padding:var(--space-3) var(--space-4);color:var(--color-text);
  border-bottom:1px solid var(--color-divider);white-space:nowrap}
.dt tbody tr:last-child td,.tw tbody tr:last-child td{border-bottom:0}
.dt tbody tr:hover td,.tw tbody tr:hover td{background:var(--color-surface-2)}
.dt td.n,.tw td.num{text-align:right;font-variant-numeric:tabular-nums}
.dt td.name{font-weight:500}
.dt td.dim{color:var(--color-muted)}
.dt.sm table{font-size:12px}
.dt.sm td,.dt.sm th{padding:var(--space-2) var(--space-3)}
.dt.frz th:first-child,.dt.frz td:first-child{position:sticky;left:0;z-index:1;
  background:var(--color-surface)}
.dt.frz th:first-child{z-index:3;background:var(--color-neutral-900)}
/* 두 열 고정 — 종목판이 라벨을 독립 열로 뺀 뒤(`[F]` 2026-09-02) 가로로 밀면
   라벨 칩만 남고 **이름이 사라졌다**. 둘째 열의 left 는 첫 열 폭과 같아야
   한다(다르면 겹치거나 틈이 벌어진다) — 그 일치를 테스트가 지킨다. */
.dt.frz2 th:first-child,.dt.frz2 td:first-child{position:sticky;left:0;z-index:1;
  width:76px;min-width:76px;background:var(--color-surface)}
.dt.frz2 th:nth-child(2),.dt.frz2 td:nth-child(2){position:sticky;left:76px;
  z-index:1;background:var(--color-surface)}
.dt.frz2 th:first-child,.dt.frz2 th:nth-child(2){z-index:3;
  background:var(--color-neutral-900)}
.dt td.lbc{white-space:nowrap}

/* 실험 대장의 결과 요약 칸 — **가설 한 줄 + 결과 한 줄** (`[F]` 2026-09-07).
   두 문장이 다른 무게를 져야 한다: 가설은 배경이라 죽이고, 결과가 결론이라
   살린다. 화살표 줄이 인과를 지므로 들여쓰기로 그 관계를 눈에 보이게 한다. */
.exh{font-size:12px;line-height:1.5;color:var(--color-muted)}
.exr{margin-top:2px;font-size:12.5px;line-height:1.5;color:var(--color-text)}
/* **요약은 줄바꿈한다** (`[F]` 2026-09-22 사용자 지시 "가로스크롤이 생기지
   않도록"). 표의 칸은 기본이 `white-space:nowrap` 이라, 문단 하나가 통째로 들어온
   결과 요약이 한 줄로 뻗어 표를 뷰포트 밖으로 밀었다. 이 두 블록만 흐르게 풀고
   칸 폭에 상·하한을 준다 — 너무 좁으면 글이 세로로 서고, 상한이 없으면 표가
   다시 넓어진다. */
.exh,.exr{white-space:normal;overflow-wrap:anywhere;word-break:break-word}
.tw td[data-l="결과 요약"]{white-space:normal;min-width:26rem;max-width:44rem;width:52%}
@media (max-width:760px){.tw td[data-l="결과 요약"]{min-width:11rem;width:auto}}

/* 종가 형성 표 (`[F]` 2026-09-02 가독성). 칩 다섯이 한 칸에 흘러 들어가면
   어느 딜러가 어느 경로인지 안 읽힌다 — **한 줄에 하나씩** 세우고, 종목
   줄머리에 방향 요약(↑3 ↓2)을 먼저 둔다. */
.fmr{display:flex;align-items:baseline;gap:var(--space-2);
  padding:1px 0;font-size:11.5px;white-space:nowrap}
.fmr b{font-weight:700;min-width:2.4em}
.fmr.up b{color:var(--color-accent-300)}
.fmr.down b{color:var(--color-accent-2-300)}
.fmr .cx{font-style:normal;font-size:10px;color:var(--color-muted);
  border:1px solid var(--color-divider);border-radius:var(--radius-sm);
  padding:0 4px}
.fmr .pth{font-variant-numeric:tabular-nums;color:var(--color-muted)}
.dt td.fmrs{min-width:230px}
.dt td.dsum{white-space:nowrap;font-variant-numeric:tabular-nums}
.dsum .up{color:var(--color-accent-300)}
.dsum .down{color:var(--color-accent-2-300)}
/* 시간대 칸 — 사자(위)·팔자(아래)를 세로로 쌓아 폭을 줄인다. */
.dt td.wc{white-space:nowrap;font-variant-numeric:tabular-nums;font-size:11.5px}
.wc-b,.wc-a{display:inline-block;min-width:3.4em}
.wc-b{color:var(--color-text)}
.wc-a{color:var(--color-muted)}
.wc-d{color:var(--color-accent-300);margin-left:2px}

/* 메신저 공지 목록 (`[F]` 2026-09-02) — 시각 · 구분 · 수치 · 본문 · 올린이.
   격자로 세운다: 본문만 늘어나고 나머지는 폭이 고정이라, 긴 헤드라인이 와도
   올린이 열이 밀리지 않는다. 좁은 화면에서는 본문이 아래 줄로 접힌다. */
.nt{list-style:none;margin:0 0 var(--space-4);padding:0;
  font-size:12.5px;line-height:1.55}
.nt li{display:grid;gap:0 var(--space-3);align-items:baseline;
  grid-template-columns:78px auto 1fr auto;
  padding:var(--space-2) 0;border-bottom:1px solid var(--color-divider)}
.nt li:last-child{border-bottom:0}
.nt-t{color:var(--color-muted);font-variant-numeric:tabular-nums;
  white-space:nowrap}
.nt-k{color:var(--color-text);font-weight:600;white-space:nowrap}
.nt-n{color:var(--color-text);font-variant-numeric:tabular-nums;
  white-space:nowrap;grid-column:3}
.nt-x{color:var(--color-text);grid-column:3;min-width:0;overflow-wrap:anywhere}
.nt-w{color:var(--color-muted);white-space:nowrap;text-align:right}
@media (max-width:760px){
  .nt li{grid-template-columns:78px auto 1fr}
  .nt-w{grid-column:1/-1;text-align:left}
}
td.full,.dt td.full{white-space:normal;min-width:190px}
/* 실험 대장에서는 제목 칸을 좁게 잡고 남는 폭을 결과 요약에 준다
   (`[F]` 2026-09-22 사용자 지시). 제목은 줄바꿈으로 흐르고, 읽는 사람이
   시간을 쓰는 곳은 요약이다. */
.tw td.full{min-width:12rem;max-width:18rem}
.tsub{display:block;font-size:11px;color:var(--color-muted)}
/* 확장: 가로 스크롤 단서 — JS 가 넘칠 때만 data-scroll 을 붙인다 */
.dt[data-scroll]::after,.tw[data-scroll]::after{content:"↔ 가로 스크롤";
  position:sticky;right:0;bottom:0;float:right;
  padding:2px var(--space-2);margin:var(--space-1);border-radius:var(--radius-sm);
  background:var(--color-surface-2);color:var(--color-muted);font-size:10px;
  letter-spacing:.06em;pointer-events:none}
.cb{display:grid;grid-template-columns:1fr auto;align-items:center;
  gap:var(--space-2);overflow:hidden}
.cb i{display:block;height:6px;border-radius:2px;justify-self:end;
  background:var(--color-neutral-500)}
.cb i.up{background:var(--color-accent)}
.cb i.down,.cb i.neg{background:var(--color-accent-2)}
.cb b{font-weight:600;font-variant-numeric:tabular-nums;min-width:44px;
  text-align:right}

/* 달력 — 트레이 밖 */
.cal{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));
  border:1px solid var(--color-divider);border-radius:var(--radius-md);
  overflow:hidden;background:var(--color-surface)}
.cal .h{padding:var(--space-2);text-align:center;font-size:11px;font-weight:600;
  letter-spacing:.09em;color:var(--color-muted);background:var(--color-neutral-900)}
.cal .d{position:relative;min-height:132px;padding:var(--space-2);
  border-top:1px solid var(--color-divider);border-right:1px solid var(--color-divider)}
.cal .d:nth-child(7n+7){border-right:0}
.cal .d.out{background:var(--color-neutral-900)}
.cal .d.out .n{color:var(--color-neutral-500)}
.cal .d.today{background:var(--color-surface-2)}
.cal .d.today::before{content:"";position:absolute;left:0;top:var(--space-2);
  width:3px;height:15px;border-radius:2px;background:var(--color-accent)}
.cal .d .n{display:block;font-size:12px;color:var(--color-muted);
  font-variant-numeric:tabular-nums;margin-bottom:var(--space-1)}
.cal .d.today .n{color:var(--color-accent);font-weight:600}
.cal .ev{display:block;margin-top:var(--space-2);padding-top:var(--space-1);
  border-top:1px solid var(--color-divider);line-height:1.35}
.cal .ev:first-of-type{margin-top:0;padding-top:0;border-top:0}
.cal .ev-t{font-size:11px;font-weight:600;color:var(--color-text)}
.cal .ev-n{font-size:11px;color:var(--color-muted);margin-left:var(--space-1);
  font-variant-numeric:tabular-nums}
.cal .ev.hot .ev-t{color:var(--color-accent)}
.cal .ev-r{display:flex;justify-content:space-between;gap:var(--space-1);
  font-size:11px}
.cal .ev-b{color:var(--color-muted);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-variant-numeric:tabular-nums}
.cal .ev-a{font-weight:600;color:var(--color-text);white-space:nowrap;
  font-variant-numeric:tabular-nums}
/* 교환 덩어리의 **발행 / 매입** 줄 (`[F]` 2026-09-07 사용자 지시 — 데스크
   월간 캘린더 양식). 한 사건이 한 자리를 쓰되, 무엇을 내주고 무엇을
   사들이는지가 칸 안에서 읽혀야 한다.

       교환입찰  10Y   26-6   0.1조
        발행     26-6
        매입(물가) 18-5 20-5 22-6 24-6

   라벨은 고정폭으로 세워 두 줄의 값이 세로로 맞는다. 값은 줄바꿈을
   허용한다 — 매입 종목이 다섯이면 한 줄에 안 들어간다. */
.cal .ev-s{display:grid;grid-template-columns:auto 1fr;gap:0 var(--space-1);
  margin-top:2px;font-size:10.5px;line-height:1.4}
.cal .ev-s .ev-k{color:var(--color-neutral-500);white-space:nowrap}
.cal .ev-s .ev-v{color:var(--color-muted);word-break:keep-all;
  font-variant-numeric:tabular-nums}

/* `+n건` — **클릭하면 펼쳐진다** (`[F]` 2026-09-07 사용자 지시).
   `<details>/<summary>` 라 자바스크립트가 없다. 접힌 자리와 펼친 자리가 같은
   `.ev` 모양을 쓰므로 펼쳐도 칸의 리듬이 깨지지 않는다.
   기본 삼각형 마커는 지우고 `+`/`−` 를 직접 그린다 — 브라우저마다 마커
   모양·자리가 달라 11px 줄에서 글자와 어긋난다. */
.cal .ev-more{display:block;margin-top:var(--space-1);font-size:11px;
  color:var(--color-muted);cursor:pointer;list-style:none;
  text-decoration:underline dotted;text-underline-offset:2px}
.cal .ev-more::-webkit-details-marker{display:none}
.cal .ev-x[open] > .ev-more{color:var(--color-text)}
.cal .ev-x[open] > .ev-more::after{content:" 접기"}
.cal .ev-more:hover{color:var(--color-text)}

/* 이벤트 목록의 **묶음 자식** — 교환입찰 아래 매입대상 바이백.
   날짜·D-day 칸을 비우고 라벨에 트리 기호를 붙여, 한 사건의 부속임을
   왼쪽 여백으로 읽게 한다. */
.dt tr.kid td{border-top:0}
.dt tr.kid td.name{color:var(--color-muted)}

/* 컨트롤 바 */
.ctl{display:flex;align-items:center;gap:var(--space-5);flex-wrap:wrap;
  font-size:12px;color:var(--color-muted)}
.cp{display:flex;gap:var(--space-1);align-items:baseline}
.cp .k{font-size:11px;font-weight:600;letter-spacing:.09em;text-transform:uppercase}
.cp .v{color:var(--color-text);font-variant-numeric:tabular-nums}
.ctl .sp{margin-left:auto}
.btn{padding:4px var(--space-3);font:inherit;font-size:11px;font-weight:600;
  letter-spacing:.09em;text-transform:uppercase;color:var(--color-muted);
  background:var(--color-surface);border:1px solid var(--color-divider);
  border-radius:var(--radius-sm);cursor:pointer}
.btn:hover{color:var(--color-text);border-color:var(--color-hairline)}
.back{display:inline-block;font-size:12.5px}
.top{display:flex;align-items:flex-end;gap:var(--space-5);flex-wrap:wrap;
  padding:var(--space-6);border-bottom:1px solid var(--color-divider)}
.mark{font-size:11px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:var(--color-muted)}
.ttl h1{font-family:var(--font-heading-ko);font-size:26px;letter-spacing:-0.02em}
.ttl .s{font-size:12.5px;color:var(--color-muted)}
.top .sp{margin-left:auto}
footer{padding:var(--space-6);border-top:1px solid var(--color-divider);
  font-size:12px;color:var(--color-muted)}
iframe.pdf{display:block;width:100%;height:78vh;border:1px solid var(--color-divider);
  border-radius:var(--radius-md);background:var(--color-surface)}
.md h3{font-family:var(--font-heading-ko);font-size:17px;margin:var(--space-6) 0 var(--space-2)}
.md p,.md li{font-size:13px;line-height:1.6;color:var(--color-muted)}

/* ── 확장 3: 차트 레이어 ────────────────────────────────────────────────
   계열은 라임 + 애저 2색. 값 라벨은 라임 금지(--color-text).
   축 글자는 --color-muted (타일면 7.6:1). */
.ch{margin:0;min-width:0}
.ch svg{display:block;width:100%;height:auto;overflow:visible;
  margin-inline:auto}
/* ── 타일 안 차트는 남는 높이에 **맞춘다** `[F✔]` 2026-09-04 ────────────
   사용자 지적: "시장 탭 국고커브 x축 나오게 그려줘."

   x축 라벨은 SVG 안에 정상적으로 그려지고 있었다 — 잘린 것은 **타일**이다.
   1600×1200 헤드리스 실측(`index.html` 국고 커브 카드):

     타일 448px · `.tilebody` 354.5px(overflow:hidden) · scrollHeight 408px
     선택된 변형 v-l · SVG 375px(= 상한 925 × 300/740)
     x축 라벨 bottom 923 > body bottom 889  →  **여섯 개 전부 잘림**

   y축 라벨은 위쪽이라 멀쩡했다. 그래서 "축이 아예 없는" 것이 아니라
   "가로축만 없는" 것으로 보였다.

   고치는 방향은 둘이었다. (a) 행 높이를 키운다 — 잘리는 카드마다 다시
   재야 하고, 시트의 100px 은 34개 타일을 재서 고른 값이다(그 절 참조).
   (b) **차트가 남는 높이에 맞춰 줄어든다** — 이쪽을 골랐다. `viewBox` +
   `preserveAspectRatio="xMidYMid meet"` 라 줄어도 그림이 찌그러지지 않고
   좌우에 여백이 생길 뿐이다. 축이 잘리는 것보다 낫다.

   플렉스 사슬 전체에 `min-height:0` 을 준다 — 플렉스 항목의 기본
   `min-height:auto` 는 내용 높이 아래로 줄어들기를 막아서, 한 곳만 빠져도
   축소가 그 자리에서 멈춘다.

   **`display` 은 건드리지 않는다.** `.v-s/.v-m/.v-l` 중 어느 것을 보일지는
   컨테이너 질의가 `display:none/block` 으로 정하는데(위 절), 여기서
   `display:flex` 를 얹으면 특이도가 높아 그 토글을 이겨 셋이 한꺼번에 뜬다
   (실측: 그렇게 했더니 v-s 가 선택돼 SVG 가 59.9px 로 찌부러졌다).
   그래서 높이만 만진다 — `.v-*` 는 줄어들 수 있게(`min-height:0`), 그 안
   `figure.ch` 는 줄어든 높이를 물려받게(`height:100%`), SVG 는 남는 높이를
   차지하게(`flex`). */
.tilebody .v-s,.tilebody .v-m,.tilebody .v-l{min-height:0}
.tilebody .v-s > .ch,.tilebody .v-m > .ch,.tilebody .v-l > .ch,
.tilebody > .ch{height:100%;min-height:0;display:flex;flex-direction:column}
.tilebody .ch > svg{flex:1 1 auto;min-height:0}
.ch-t{font-size:11px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:var(--color-muted);margin-bottom:var(--space-2)}
.ch.empty .empty-b{font-size:12.5px;color:var(--color-muted);
  padding:var(--space-5) 0;line-height:1.55}
.lg{display:flex;gap:var(--space-4);flex-wrap:wrap;margin:0 0 var(--space-2);
  font-size:11px;color:var(--color-muted)}
.lg-i{display:inline-flex;align-items:center;gap:var(--space-1)}
.lg-s{width:10px;height:10px;border-radius:2px;display:inline-block;flex-shrink:0}
.ax-grid{stroke:var(--color-divider);stroke-width:1}
.ax-zero{stroke:var(--color-neutral-500);stroke-width:1}
.cutline{stroke:var(--color-neutral-500);stroke-width:1;stroke-dasharray:4 4;
  opacity:.7}
.cut-lbl{fill:var(--color-muted);font-size:9.5px;letter-spacing:.04em}
.ax-lbl{fill:var(--color-muted);font-size:11px;font-variant-numeric:tabular-nums}
.ax-lbl.sm{font-size:10.5px}
/* 계열 기본은 **애저**다. 시스템 readme: "애저는 계열과 링크에 쓴다" ·
   "라임은 그리드당 정확히 하나를 표시한다". 56점 산점도나 8행 막대를 전부 라임으로
   칠하면 라임이 아무것도 가리키지 않게 된다. 라임은 2번 계열·발산 양극·강조에만. */
.bar{fill:var(--color-accent-2)} .bar.s2{fill:var(--color-accent)}
.bar.s3{fill:var(--color-neutral-500)}
.bar.pos{fill:var(--color-accent)} .bar.neg{fill:var(--color-accent-2)}
.bar-v,.db-v{fill:var(--color-text);font-size:11px;font-weight:600;
  font-variant-numeric:tabular-nums;paint-order:stroke fill;
  stroke:var(--color-surface);stroke-width:3px}
.db-v.neg{fill:var(--color-accent-2-300)}
.ln{fill:none;stroke-width:2;stroke-linejoin:round;stroke:var(--color-accent-2)}
.ln.s2{stroke:var(--color-accent)} .ln.s3{stroke:var(--color-neutral-500)}
/* 계열이 셋을 넘으면 **파선으로** 가른다 `[F]` 2026-09-04 — 시스템 팔레트가
   3색뿐이라 넷째부터 색이 겹친다. 색을 새로 만들지 않고(브랜드 규약) 선의
   모양을 바꿔 3색 × 6무늬 = 열여덟 조합까지 구별한다.

   무늬가 여섯인 이유: 메신저 호가 추이가 **색=세대 · 무늬=테너**로 가르는데
   국고 테너가 2·3·5·10·20·30 여섯이다(`desk_data.chat_today`). 무늬는 굵기
   2px 에서 서로 안 헷갈리게 실선·긴파선·점선·아주긴파선·촘촘점선·일점쇄선
   순으로 벌렸다. */
.ln.d2{stroke-dasharray:6 3} .ln.d3{stroke-dasharray:2 3}
.ln.d4{stroke-dasharray:12 4} .ln.d5{stroke-dasharray:1 3}
.ln.d6{stroke-dasharray:10 3 2 3}
.dot{fill:var(--color-accent-2);stroke:var(--color-surface);stroke-width:2}
.dot.s2{fill:var(--color-accent)} .dot.s3{fill:var(--color-neutral-500)}
/* 강조 점 — 라벨이 붙은 극단값만 라임으로 올린다.
   `pointer-events:none` 이 필요하다: 이 원이 실제 데이터 점 위에 겹쳐 그려져서
   그냥 두면 아래 점의 호버(data-v)를 가로챈다 (측정으로 확인, 20개). */
.dot.hi{fill:var(--color-accent);pointer-events:none}
/* 적합 커브 오버레이 (2026-08-31 사용자 요청: 커브 피팅 시각화).
   점이 애저이므로 선은 라임 = "중요한 하나". 선이 점보다 굵어야 55개 점 사이에서
   경로로 읽힌다. `pointer-events:none` — 선이 점 위를 지나며 호버를 가로채면
   "이 점이 무슨 종목인가"를 못 읽는다(.dot.hi 에서 겪은 것과 같은 사고). */
.cvline{stroke-width:2.5;stroke-linecap:round;pointer-events:none}
/* 라벨이 붙은 점 — **커브가 있을 때만** 쓴다. 그때 라임은 선의 색이므로
   강조점까지 라임이면 범례("점=애저 · 선=라임")가 거짓이 된다. 색이 아니라
   테두리로 올린다. */
.dot.lb{fill:var(--color-accent-2);stroke:var(--color-text);stroke-width:2;
  pointer-events:none}
/* 두 기준일 고지 — 점(라이브 민평)과 선(우리 적합)의 날짜가 다를 수 있다.
   차트 바로 아래 붙어야 눈으로 조인하기 전에 읽힌다(§3.1). */
.cvn{margin-top:var(--space-2);font-size:11.5px}
.hit{fill:transparent;stroke:none;cursor:crosshair}
.db-c{stroke:var(--color-neutral-700);stroke-width:2}
.db-a{fill:var(--color-accent-2);stroke:var(--color-surface);stroke-width:2}
.db-b{fill:var(--color-accent);stroke:var(--color-surface);stroke-width:2}
.spark{width:100%;height:auto;aspect-ratio:420/120;display:block}
.spark.mini{width:84px;height:24px;aspect-ratio:auto}
.ar{fill:color-mix(in srgb,var(--color-accent-2) 22%,transparent);stroke:none}
.ar.s2{fill:color-mix(in srgb,var(--color-accent) 20%,transparent)}
.ar.s3{fill:color-mix(in srgb,var(--color-neutral-500) 20%,transparent)}
.spark .ln{stroke-width:2}
.arc{width:100%;max-width:170px;height:auto;display:block;margin:0 auto}
.arc .seg{stroke:var(--color-neutral-700);stroke-width:8;fill:none;stroke-linecap:butt}
.arc .seg.on{stroke:var(--color-accent-2)}
.arc .seg.on.warn,.arc .seg.on.crit{stroke:var(--color-accent)}
.arc-v{fill:var(--color-text);font-family:var(--font-heading-ko);font-size:20px;
  font-weight:700;font-variant-numeric:tabular-nums}
.arc-s{fill:var(--color-muted);font-size:10px;letter-spacing:.09em}

/* 충족도 행렬 — 클래스를 .cmx 로 개명했다. 이전 .mx 는 상단 지표 스트립과
   충돌해 캡션│범례│표가 나란히 서 버렸다 (측정 확인). */
.cmx td.mx-ok,.cmx td.mx-no,.cmx td.mx-warn{text-align:center;width:1%;
  font-size:13px;font-weight:700;white-space:nowrap}
.mx-ok{color:var(--color-accent-300)}
.mx-no{color:var(--color-accent-2-300)}
.mx-warn{color:var(--color-neutral-400)}
.mx-k{display:inline-block;margin-right:3px}
.cmx .dt table{min-width:560px}

/* 크레딧 서피스 히트맵 — 등급 × 만기. 색은 백분위, 값은 셀 안 숫자다(색 단독
   전달 금지). 발산 규약은 차트와 같다: 양끝 라임↔애저, 중앙 중립 회색. 칠은
   토큰을 color-mix 로 옅게 깐 것뿐이고 새 색값을 만들지 않는다. 글자는 값
   라벨이므로 항상 --color-text — 라임 글자 금지 규칙 그대로다. */
.hmx td.hm{text-align:right;font-size:12px;white-space:nowrap;
  font-variant-numeric:tabular-nums;color:var(--color-text)}
.hm-p2{background:color-mix(in oklab,var(--color-accent) 34%,transparent)}
.hm-p1{background:color-mix(in oklab,var(--color-accent) 17%,transparent)}
.hm-mid{background:color-mix(in oklab,var(--color-neutral-500) 22%,transparent)}
.hm-n1{background:color-mix(in oklab,var(--color-accent-2) 20%,transparent)}
.hm-n2{background:color-mix(in oklab,var(--color-accent-2) 38%,transparent)}
.hm-na{background:transparent;color:var(--color-neutral-400)}
.hmx .dt table{min-width:620px}

/* ── 확장 4: 컨테이너 쿼리로 차트 변형 선택 ─────────────────────────────
   뷰포트가 아니라 **타일 폭**으로 고른다. 기본은 좁은 변형이고, 타일이 넓어질
   때만 큰 변형으로 올린다. `max-width` 로 확대 상한을 둔다. */
/* 분기와 viewBox 폭을 맞춰 배율이 0.8~1.25 를 벗어나지 않게 한다.
   viewBox 300 / 460 / 740, 분기 375 / 600, 확대 상한 375 / 575 / 925:
     v-s  컨테이너 ~300~374 → 1.00~1.25       v-m  375~599 → 0.82~1.25
     v-l  600 이상, 925 상한 → 0.81~1.25 */
.v-s,.v-m,.v-l{display:none}
.v-s{display:block}
.v-s .ch svg{max-width:375px}
.v-m .ch svg{max-width:575px}
.v-l .ch svg{max-width:925px}
@container tile (min-width:375px){
  .v-s{display:none} .v-m{display:block}
}
@container tile (min-width:600px){
  .v-m{display:none} .v-l{display:block}
}
/* 트레이 밖(블록)은 컨테이너가 없다 — 블록에도 컨테이너를 준다 */
.blkbody{container-type:inline-size;container-name:tile}

/* ── 상호작용 공통 (확장) ──────────────────────────────────────────────
   배율 배지·조작 힌트·드래그 중 상태. 실제 상호작용은 인터랙티브 엔진이 맡는다. */
.ch{position:relative}
body[data-dragging]{user-select:none}
body[data-dragging] #tip{opacity:0}
/* 배율 표시 — 확대됐을 때만 나온다 */
.ch[data-z]:not([data-z=""])::after{content:attr(data-z);
  position:absolute;top:0;right:0;padding:2px var(--space-2);
  border-radius:var(--radius-sm);background:var(--color-surface-2);
  border:1px solid var(--color-divider);color:var(--color-accent-300);
  font-size:10px;font-weight:600;font-variant-numeric:tabular-nums;
  pointer-events:none}
/* 조작 힌트 — 커서를 올렸을 때만. 확대 중에는 배율 표시가 대신 나온다 */
.zh{position:absolute;left:0;bottom:-2px;font-size:10px;color:var(--color-muted);
  opacity:0;transition:opacity var(--dur) var(--ease);pointer-events:none}
.ch:hover .zh{opacity:1}
.ch[data-z]:not([data-z=""]) .zh{opacity:0}

/* ── 인터랙티브 차트 (확장) ────────────────────────────────────────────
   클라이언트가 실제 CSS 폭·높이와 1:1 로 그린다 — 배율이 1.0 이라 글자가 항상
   선언된 크기다. `touch-action:pan-y` 로 터치 세로 스크롤은 살려 둔다. */
figure.ix{position:relative;min-width:0}
.ix-svg{display:block;width:100%;height:auto;cursor:crosshair;touch-action:pan-y}
body[data-dragging] .ix-svg{cursor:grabbing}
/* 십자선 — 커서가 플롯 안에 있을 때만 */
.ix-cross{opacity:0;pointer-events:none}
.ix-cross[data-on]{opacity:1}
.ix-cx,.ix-cy{stroke:var(--color-neutral-400);stroke-width:1;stroke-dasharray:3 3}
/* 축 기준선 — 확대·이동과 무관하게 항상 남는다 */
.ix-axis{stroke:var(--color-neutral-500);stroke-width:1}
.ix-tag rect{fill:var(--color-neutral-900);stroke:var(--color-hairline)}
.ix-tag text{fill:var(--color-text);font-size:10.5px;font-weight:600;
  font-variant-numeric:tabular-nums}
/* y축 눈금 띠 위에서는 y 를 잡아 끌 수 있다 */
.ix-svg:hover{cursor:crosshair}
/* JS 가 죽으면 서버 SVG 폴백이 그대로 남는다 */
.ix-fb svg{display:block;width:100%;height:auto}

/* ── 툴팁 (확장) ───────────────────────────────────────────────────────── */
#tip{position:fixed;z-index:90;left:0;top:0;max-width:280px;
  padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);
  background:var(--color-neutral-900);border:1px solid var(--color-hairline);
  color:var(--color-text);font-size:11.5px;line-height:1.45;
  box-shadow:var(--shadow-md);pointer-events:none;opacity:0;
  transition:opacity var(--dur) var(--ease)}
#tip[data-on]{opacity:1}
#tip b{display:block;font-size:12px;margin-bottom:2px}
/* 키와 값이 한 조각(띄어쓰기 구분)이라 좌우로 벌리지 않는다
   `[F]` 2026-09-04 — 벌리면 "시작"과 "3.03%" 사이가 툴팁 폭만큼 떨어진다. */
#tip span{display:block;
  color:var(--color-muted);font-variant-numeric:tabular-nums}
/* `<i>` 는 더 이상 굽지 않는다(키·값이 한 조각이다). 규칙만 남겨 두면 죽은
   선언이 되므로 지운다 — 되살릴 일이 생기면 `charts._dv` 부터 바꾼다. */

/* ── 반응형 — 시스템 브레이크포인트(1000/760/520)만 쓴다 ───────────────── */
@media (max-width:1000px){
  .app{grid-template-columns:180px 1fr}
  .body{padding:var(--space-5) var(--space-5) var(--space-12)}
  .strip{padding:var(--space-5)}
}
/* 행 높이를 시스템 기본 56px → **100px**. 시스템 타일은 구절 하나를 담지만 우리
   타일은 차트와 라벨/값 목록을 담는다. 56px 이면 t-primary 가 272px 이고 내부는
   224px 뿐이라 h=240~276 차트와 9행 목록이 `overflow:hidden` 에 잘렸다
   (선물 수급의 x축 라벨이 사라지고 북 지표의 마지막 행이 끊긴 원인).

   84 / 92 / 100px 을 각각 렌더해 타일 34개의 `.tilebody` 를 실측했다:
     84px  → 잘림 7개
     100px → **잘림 0개 · 남는 여백 120px 초과 0개**  ← 채택
   더 키우면 빈 공간이 생기고 줄이면 잘린다. */
.bento-12{--bento-row:100px}
/* 재단되면 전폭이 되므로 높이를 내용에 맡긴다. 또 마지막 행 채움용 인라인
   스팬(12열 기준)은 6열에서 어긋나므로 무효화한다 — 6열에서는 t-primary 가 이미
   전폭이고, 재단된 레이아웃에서 t-secondary 가 반 폭으로 남는 건 정상이다. */
@media (max-width:1000px){
  .bento-12{--bento-row:auto}
  .bento-12 .bento-tile{min-height:300px}
  /* 12열 기준 인라인 스팬을 티어 기본값으로 되돌리고, 6열 기준으로 계산된
     `fill6` 만 전폭으로 넓힌다. 뒤에 온 규칙이 이긴다. */
  .bento-12 > .bento-tile[style*="grid-column"]{grid-column:span 3 !important}
  .bento-12 > .t-primary[style*="grid-column"]{grid-column:span 6 !important}
  .bento-12 > .bento-tile.fill6{grid-column:span 6 !important}
}
/* 시스템은 760px 에서 `.bento{--bento-cols:2}` 로 재단하는데 `.bento-12` 의 티어
   스팬은 1000px 밴드 값(t-secondary/tertiary = span 3)에 멈춰 있다. 2열 격자에
   span 3 이 들어가면 암시 열이 생겨 **타일이 42px 로 쪼그라든다** (측정 확인:
   데스크 페이지가 `.t-secondary` 를 처음 쓰면서 드러났다 — 기존 페이지는 타일이
   전부 차트라 t-primary 였고 이 밴드를 밟지 않았다). 토큰을 고치지 않고 시스템
   클래스의 스팬만 2열 격자에 맞춘다. 브레이크포인트는 시스템의 760 그대로다. */
@media (max-width:760px){
  .bento-12 .t-primary{grid-column:span 2}
  .bento-12 .t-secondary,.bento-12 .t-tertiary{grid-column:span 1}
  .bento-12 > .bento-tile[style*="grid-column"]{grid-column:span 1 !important}
  .bento-12 > .t-primary[style*="grid-column"],
  .bento-12 > .bento-tile.fill6{grid-column:span 2 !important}
}
@media (max-width:760px){
  .app{grid-template-columns:1fr}
  #sb{position:sticky;top:0;z-index:60;height:auto;flex-direction:row;
    flex-wrap:wrap;align-items:center;gap:var(--space-1);
    padding:var(--space-2) var(--space-4);border-right:0;
    border-bottom:1px solid var(--color-divider);overflow:visible}
  .sb-h{display:none}
  .nv{padding:7px var(--space-3);font-size:12.5px}
  .nv.on::before{display:none}
  .nv.on{background:var(--color-surface-2)}
  .strip{padding:var(--space-4);gap:var(--space-4)}
  .strip .pg b{font-size:21px}
  .mx{margin-left:0;gap:var(--space-4)}
  .body{padding:var(--space-4) var(--space-4) var(--space-8);gap:var(--space-5)}
  .cal .d{min-height:104px}
  .cal .ev-r{display:block}
  .ring svg{width:72px;height:72px}
}
@media (max-width:520px){
  .cal{grid-template-columns:repeat(7,minmax(44px,1fr));overflow-x:auto}
  .cal .d{min-height:88px}
  .tiles.g2{grid-template-columns:1fr}
  .strip .pg b{font-size:19px}
  /* 520px 에서는 시스템이 1열로 접고 티어 스팬을 `auto` 로 되돌린다. 위 760px
     블록이 이 시트 뒤에 와서 그 되돌림을 덮으므로(측정: 1열 격자에 span 2 가
     들어가 암시 열이 생겨 42px 타일) 여기서 다시 시스템 값으로 맞춘다. */
  .bento-12 .t-primary,.bento-12 .t-secondary,.bento-12 .t-tertiary{grid-column:auto}
  .bento-12 > .bento-tile[style*="grid-column"],
  .bento-12 > .t-primary[style*="grid-column"],
  .bento-12 > .bento-tile.fill6{grid-column:auto !important}
}
@media print{
  #sb,.act,.ctl,#tip{display:none}
  .app{grid-template-columns:1fr}
}

/* ── 확장 5: 실시간 타일(at-live) ────────────────────────────────────────
   `#live-tile` 은 이 대시보드에서 유일하게 클라이언트가 내용을 채우는
   자리다(`TIP_JS`, R8·R61). 여기서는 그 콘텐츠가 쓰는 클래스만 정의한다 —
   네 상태(R62: 휴장 / 장중·정상 / 장중·피드사망 / 수집기무응답)를 "은은한
   색조 차이" 가 아니라 채움 여부·테두리 스타일·굵기 3중으로 가른다.

   새 색을 만들지 않는다. 시스템 팔레트는 라임(--color-accent)·애저
   (--color-accent-2) 둘뿐이고 이미 이 파일 안에서 라임=정상(`.tag.live`)·
   애저=주의(`.tag.warnt`, `.st.stale`)로 관례가 서 있다 — 그 관례를 그대로
   잇는다. "장중·피드 사망"만 유일하게 애저를 **채움**으로 쓴다(다른 곳은
   전부 테두리·글자색뿐이다) — 이 상태 하나만 "지금 봐야 한다"가 목적이라
   나머지와 같은 강도로 두면 그 자체가 스펙 R62 가 금지한 "은은한 색조
   차이"가 된다. */
.live-tile{padding:var(--space-4);border-radius:var(--radius-md);
  border:1px solid var(--color-divider);background:var(--color-surface);
  font-size:13px;line-height:1.6;display:flex;flex-direction:column;
  gap:var(--space-2)}
.live-tile .live-badge{display:inline-flex;align-self:flex-start;
  font-size:11px;font-weight:700;letter-spacing:.06em;
  padding:2px var(--space-2);border-radius:var(--radius-sm);
  border:1px solid var(--color-divider);color:var(--color-muted)}
.live-tile .live-src{font-size:12px;color:var(--color-muted)}
/* 이름 옆의 코드 — 이름을 적어도 코드는 지우지 않는다(로그·파일 대조용).
   본문보다 물러나 있어야 이름이 먼저 읽힌다. */
.live-tile .live-code{margin-left:var(--space-2);font-family:var(--font-mono);
  font-size:11px;color:var(--color-neutral-500)}
.live-tile .live-inst{width:100%;border-collapse:collapse;font-size:12px;
  margin-top:var(--space-1)}
.live-tile .live-inst th{text-align:left;color:var(--color-muted);
  font-weight:600;padding:2px var(--space-2) 2px 0}
.live-tile .live-inst td{padding:2px var(--space-2) 2px 0;
  font-variant-numeric:tabular-nums;color:var(--color-text)}
/* 휴장 — 데이터 없음이 정상. `.st.none` 관례(점선 테두리·중립회색)를 잇는다. */
.live-tile.live-closed{border-style:dashed}
/* 장중 · 피드 정상 — `.tag.live` 관례(라임-300)를 잇는다. */
.live-tile.live-ok{border-color:var(--color-accent-700)}
.live-tile.live-ok .live-badge{border-color:var(--color-accent-700);
  color:var(--color-accent-300)}
/* 장중 · 주의(R70) — 피드는 살아 있는데 **로컬 결함**이 있다(수집기 오류,
   체결 경로 정지 의심, 근월물 테너 누락). `.tag.warnt`·`.st.stale` 관례대로
   애저를 **테두리·글자색으로만** 쓴다 — 채움은 "피드 사망" 하나에만 남겨
   두어야 그 상태가 유일하게 튀는 것이 유지된다(R62). */
.live-tile.live-warn{border-color:var(--color-accent-2)}
.live-tile.live-warn .live-badge{border-color:var(--color-accent-2);
  color:var(--color-accent-2)}
/* 장중 · 피드 사망 — 유일하게 채움을 쓰는 상태(위 설명 참고). */
.live-tile.live-dead{border-color:var(--color-accent-2);
  background:color-mix(in srgb,var(--color-accent-2) 16%,var(--color-surface))}
.live-tile.live-dead .live-badge{background:var(--color-accent-2);
  border-color:var(--color-accent-2);color:var(--color-surface)}
/* 수집기 자체가 응답하지 않음 — "피드 사망"과는 다른 사실(서버 부재)이므로
   채움을 쓰지 않는다(둘을 같은 모양으로 그리면 원인을 못 가른다). */
.live-tile.live-unreachable{border-style:dashed;border-color:var(--color-neutral-500)}
.live-tile.live-unreachable .live-badge{border-style:dashed;
  border-color:var(--color-neutral-500)}

/* ── 실시간 모니터(monitor.html) — 전용 화면 종일 표시 ─────────────────
   레이아웃이 흔들리지 않는 것이 요구사항이다: 값이 없어도 자리를 유지하고
   줄을 접지 않는다. 자리가 움직이는 모니터는 읽을 수 없다. */
.mon-strip{display:flex;gap:var(--space-4);align-items:center;
  padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);
  border:1px solid var(--color-neutral-500);margin-bottom:var(--space-4);
  font-size:13px;color:var(--color-muted)}
.mon-badge{font-weight:600;color:var(--color-text)}
.mon-grid{display:grid;grid-template-columns:repeat(3,1fr);
  gap:var(--space-4)}
.mon-col{padding:var(--space-4);border-radius:var(--radius-md);
  border:1px solid var(--color-neutral-500);min-width:0}
.mon-tenor{font-size:13px;color:var(--color-muted);display:flex;
  align-items:baseline;gap:var(--space-2)}
/* 지표종목 이름 — 축 옆에 붙는다 (2026-09-08 사용자 요청). 축보다
   또렷해야 한다: 축은 자리 이름이고 이쪽이 지금 그 자리에 있는 종목이다.
   새 토큰을 만들지 않고 표의 흐린 값이 이미 쓰는 색 체계를 그대로 쓴다. */
.mon-bond{font-size:12.5px;font-weight:600;color:var(--color-text);
  font-variant-numeric:tabular-nums}
/* 멀리서 읽히는 크기 — 전용 화면 요구사항 */
.mon-last{font-size:44px;line-height:1.1;font-variant-numeric:tabular-nums}
.mon-change{font-size:20px;font-variant-numeric:tabular-nums;
  min-height:1.4em}
/* 라벨 | 막대 | 숫자 세 열. 라벨·숫자 열 폭을 고정해 **세 종목의 막대
   시작점과 끝점이 세로로 맞는다** — 종목 간 비교가 이 화면의 목적이라
   어긋나면 길이 비교가 무의미해진다. 숫자를 함께 적는 이유: 막대는 비율만
   보여주고 규모는 안 보여준다(5,393 대 3,930 과 54 대 39 가 같은 모양이다). */
.mon-flow{margin:var(--space-3) 0;display:grid;
  grid-template-columns:auto 1fr auto;gap:var(--space-2);align-items:center}
.mon-tag-buy{font-size:12px;white-space:nowrap;color:var(--color-accent-700)}
.mon-tag-sell{font-size:12px;white-space:nowrap;color:var(--color-accent-2)}
.mon-flowbar{width:100%;height:10px;display:block}
.mon-qty{font-size:13px;text-align:right;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.mon-buy{fill:var(--color-accent-700)}
.mon-sell{fill:var(--color-accent-2)}
/* 방향불명 — 감추지 않는다 */
.mon-unk{fill:var(--color-neutral-500);opacity:.35}
.mon-imb{font-size:16px;font-variant-numeric:tabular-nums;min-height:1.4em}
/* 표본 부족·판정 불가는 죽인다 — 없는 신호를 읽지 않게 */
.mon-imb.mon-weak{color:var(--color-muted)}
.mon-line{font-size:13px;color:var(--color-muted);
  font-variant-numeric:tabular-nums}
.mon-chart{width:100%;height:60px;display:block;margin-top:var(--space-3)}
.mon-chart-line{fill:none;stroke:var(--color-text);stroke-width:1.5;
  vector-effect:non-scaling-stroke}
.mon-note{margin-top:var(--space-4);font-size:13px;color:var(--color-muted);
  min-height:1.4em}
/* 범례 — 참고용이라 본문보다 한 단계 물러나 있다(읽히되 먼저 읽히지 않게) */
/* 범례 — 용어/뜻 격자. `[F]` 2026-09-02 사용자 요청으로 (a) 펼친 채 뜨고
   (b) 카드 바로 밑에 붙고 (c) 산문 한 단이 아니라 두 단 격자로 선다.
   `max-width:78ch` 를 뺀 이유: 두 단으로 갈리면 각 단이 이미 그 폭 아래다. */
.mon-legend{margin:var(--space-2) 0 0;padding-top:var(--space-3);
  border-top:1px solid var(--color-divider);
  font-size:12.5px;line-height:1.6;color:var(--color-muted);
  display:grid;grid-template-columns:1fr;gap:var(--space-2) var(--space-6)}
@media (min-width:760px){
  .mon-legend{grid-template-columns:repeat(2,minmax(0,1fr))}
}
.mon-legend dt{color:var(--color-text);font-weight:600;
  margin:var(--space-2) 0 2px;display:flex;align-items:baseline;
  gap:var(--space-2);flex-wrap:wrap}
.mon-legend dd{margin:0 0 var(--space-2);max-width:52ch}
.mon-legend b{color:var(--color-text);font-weight:600}
/* 구간 꼬리표 — 당일 누적과 최근 5분이 섞이는 것이 이 화면 오독 1순위다. */
.mon-win{font-size:11px;font-weight:500;color:var(--color-muted);
  border:1px solid var(--color-divider);border-radius:var(--radius-sm);
  padding:0 6px;white-space:nowrap}
/* ── 데이터셋 인벤토리 격자(data.html) ─────────────────────────────────
   `[F]` 2026-08-28 실측: 옛 표는 172행 × 8열이고 한 화면에 25행쯤 들어갔다.
   한 표를 한 줄로 줄이고 여러 열로 접는다 — 열 수는 화면 폭이 정한다
   (`auto-fill`), 좁은 화면에서 한 열로 접히는 것까지 같은 규칙이 낸다. */
/* 주제 그룹 머리 — `[F]` 2026-08-31 사용자 요청("데이터셋 주제별로 그룹").
   `.inv-head`(표시/미표시)보다 **한 단 위**라 위계를 눈으로 읽혀야 한다:
   글자를 키우거나 색을 새로 만들지 않고 위쪽 구분선 하나와 본문색으로
   올린다(시트가 이미 쓰는 `--color-divider`·`--color-text`). 새 토큰을
   만들지 않는 것이 이 시트의 규약이다. */
/* ── 인벤토리 탭 · 카테고리 블록 (2026-09-01 사용자 요청) ───────────────
   "수집 원천 분류 탭 하나, 데이터 종류 탭 하나로 나눠. 각 탭에서 카테고리별
   블록을 만들고 그 블록 안에 데이터셋 이름이 들어가는 형태."

   **자바스크립트를 쓰지 않는다** — 숨은 라디오 + `:checked ~` 로 판을 바꾼다.
   정적 페이지라 그 편이 안전하고(파일로 열어도 돈다), 이 저장소가 접힘을
   `<details>` 로 푼 것과 같은 태도다. */
.tabs{margin:var(--space-4) 0}
.tabs>input[type=radio]{position:absolute;opacity:0;pointer-events:none}
.tabs-hd{display:flex;gap:var(--space-2);
  border-bottom:1px solid var(--color-divider);margin-bottom:var(--space-4)}
.tabs-hd label{padding:6px var(--space-4);cursor:pointer;
  font-size:12.5px;color:var(--color-muted);
  border-bottom:2px solid transparent;margin-bottom:-1px}
.tabs-hd label:hover{color:var(--color-text)}
.tabs-p{display:none}
#invtab-o:checked~.tabs-hd label[for=invtab-o],
#invtab-g:checked~.tabs-hd label[for=invtab-g]{
  color:var(--color-text);font-weight:600;
  border-bottom-color:var(--color-accent-300)}
#invtab-o:checked~.tabs-o,#invtab-g:checked~.tabs-g{display:block}
/* 키보드로도 탭이 바뀐다 — 라디오가 포커스를 받으면 테두리를 보인다. */
.tabs>input[type=radio]:focus-visible~.tabs-hd label{outline:1px dashed
  var(--color-neutral-500);outline-offset:2px}

/* 카테고리 블록 — 옛 판은 그룹 머리가 본문에 얹힌 구분선이라 **경계가
   없었다**(어디까지가 한 주제인지 눈으로 끊기지 않았다). 상자로 만든다. */
.ib{margin:0 0 var(--space-3);padding:var(--space-3);
  border:1px solid var(--color-divider);border-radius:var(--radius-md);
  background:var(--color-surface-2)}
.ib-hd{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  margin-bottom:var(--space-2)}
.ib-ic{flex:none;font-size:14px;color:var(--color-accent-300)}
.ib-t{font-weight:600;color:var(--color-text);font-size:13px}
.ib-n{font-variant-numeric:tabular-nums;font-size:12px;
  color:var(--color-text);background:var(--color-neutral-700);
  border-radius:999px;padding:0 7px}
.ib-s{margin-left:auto;min-width:0;font-size:11px;
  color:var(--color-neutral-500);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.ib-grid{display:grid;gap:1px var(--space-3);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,15rem),1fr))}

/* 데이터셋 상세 */
.ds-meta{display:grid;gap:var(--space-2);margin:var(--space-3) 0;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,13rem),1fr))}
.ds-kv{min-width:0;padding:var(--space-2) var(--space-3);
  border:1px solid var(--color-divider);border-radius:var(--radius-sm);
  background:var(--color-surface-2)}
.ds-kv span{display:block;font-size:11px;color:var(--color-muted)}
.ds-kv b{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;
  font-size:12.5px;color:var(--color-text);font-weight:600}
.ds-gap td{text-align:center;color:var(--color-neutral-500);font-size:11px}
/* 미룬 표의 수집 계획 — 슬롯 칩(`site._ds_plan`). 슬롯 이름은 스케줄러에
   실제로 등록된 작업이라 **그대로** 읽혀야 한다: 등호로 쓰지 않고 코드처럼
   칠한다. `off` 는 자동화 대상이 아닌 표다 — 색을 빼 눈이 멈추지 않게 한다. */
.ds-slot{display:inline-block;padding:1px var(--space-2);
  border-radius:var(--radius-sm);background:var(--color-surface-2);
  border:1px solid var(--color-accent-300);color:var(--color-accent);
  font-family:var(--font-mono);font-size:11px}
.ds-slot.off{border-color:var(--color-divider);color:var(--color-neutral-500)}

/* ── K-Bond 대화 타일(monitor.html · `site._chat_tile`) ─────────────────
   실시간 모니터는 종일 띄워 두는 화면이라 **줄 높이를 좁게** 간다 — 같은
   높이에 몇 줄이 들어오는지가 이 타일의 값어치다. 새 토큰을 만들지 않는다. */
/* ── 메신저 통계(`chat.html`) — 컴팩트 시각화 ──────────────────────────
   `[F]` 2026-09-02 사용자 요청("통계를 좀 더 컴팩트하게 다양한 시각화 기법을
   사용해서 한 눈에"). 라이브러리도 SVG 도 쓰지 않는다 — 인쇄·파일 열기에서
   그대로 서고, 새 토큰을 만들지 않는다. */
.kpis{display:grid;gap:var(--space-3);margin:var(--space-3) 0;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,11rem),1fr))}
.kpi{padding:var(--space-3);border:1px solid var(--color-divider);
  border-radius:var(--radius-md);background:var(--color-surface)}
.kpi .kl{font-size:11px;color:var(--color-muted);letter-spacing:.06em}
.kpi .kv{font-size:22px;font-weight:700;color:var(--color-text);
  font-variant-numeric:tabular-nums;line-height:1.25}
.kpi .ks{font-size:11px;color:var(--color-neutral-500)}

/* 시간대 막대(`.hbar`)는 걷었다 `[F]` 2026-09-04 사용자 지시 — 시간대 분포가
   `charts.bars` 세로 막대 SVG 로 바뀌면서(활성도와 같은 행·같은 형태) CSS
   막대를 쓰는 자리가 없어졌다. 죽은 규칙을 남겨 두면 다음 사람이 "이 화면에
   두 종류의 막대가 있다" 고 읽는다. */

/* 팔자/사자 비율 막대. **색 단독으로 전달하지 않는다** — 수를 옆에 적는다. */
.sbar{display:inline-block;width:3.4rem;height:6px;vertical-align:middle;
  border-radius:3px;background:var(--color-accent);overflow:hidden}
.sbar .sa{display:block;height:100%;background:var(--color-accent-2)}
.snum{margin-left:var(--space-2);font-size:11px;
  font-variant-numeric:tabular-nums}
.snum b{font-weight:600}
.snum b + b::before{content:" / ";color:var(--color-neutral-500);
  font-weight:400}
td.sc{white-space:nowrap}
/* 체결 행 — 종가를 실제로 만든 줄이다. 호가 행과 눈으로 갈려야 한다. */
.dt tbody tr.deal td{background:var(--color-surface-2)}
.dt tbody tr.deal td b{color:var(--color-accent)}

/* 표를 나란히. 좁아지면 접힌다 — 가로 스크롤을 만들지 않는다. */
.c3,.c2x{display:grid;gap:var(--space-4);align-items:start}
.c3{grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr))}
.c2x{grid-template-columns:repeat(auto-fit,minmax(min(100%,28rem),1fr))}
.c3 h3,.c2x h3,.body > h3{margin:var(--space-4) 0 var(--space-2);
  font-size:13px;color:var(--color-text)}
.c3 h3,.c2x h3{margin-top:0}
.c3 h3 span,.c2x h3 span,.body > h3 span{margin-left:var(--space-2);
  font-size:11px;font-weight:400;color:var(--color-neutral-500)}

/* ── 떠 있는 목차(`site._toc`) — 오른쪽 가장자리, 호버로 펼침 ──────────
   `[F]` 2026-09-02 사용자 요청. 접힌 상태는 얇은 손잡이 하나라 본문을 가리지
   않고, 펼침은 CSS `:hover` 만 쓴다(파일로 열어도 돈다). 키보드 접근을 위해
   `:focus-within` 도 같은 조건에 둔다. */
.toc{position:fixed;top:50%;right:0;transform:translateY(-50%);z-index:40;
  display:flex;align-items:center;flex-direction:row-reverse}
.toc-tab{padding:var(--space-3) var(--space-1);
  border:1px solid var(--color-divider);border-right:0;
  border-radius:var(--radius-sm) 0 0 var(--radius-sm);
  background:var(--color-surface);color:var(--color-muted);
  font-size:12px;cursor:default;writing-mode:vertical-rl}
.toc-p{display:none;max-width:16rem;max-height:70vh;overflow-y:auto;
  padding:var(--space-3);border:1px solid var(--color-divider);border-right:0;
  border-radius:var(--radius-md) 0 0 var(--radius-md);
  background:var(--color-surface);box-shadow:0 8px 24px rgba(0,0,0,.35)}
.toc:hover .toc-p,.toc:focus-within .toc-p{display:block}
.toc-p b{display:block;font-size:11px;color:var(--color-neutral-500);
  margin-bottom:var(--space-2);font-weight:600;letter-spacing:.06em}
.toc-p a{display:flex;gap:var(--space-2);align-items:baseline;min-width:0;
  padding:3px var(--space-2);border-radius:var(--radius-sm);
  color:var(--color-text);text-decoration:none;font-size:12.5px}
.toc-p a:hover{background:var(--color-surface-2);color:var(--color-accent)}
.toc-p a i{flex:none;font-style:normal;font-family:var(--font-mono);
  font-size:10px;color:var(--color-neutral-500);width:1.1rem;text-align:right}
.toc-p a span{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
/* 앵커로 뛰면 머리가 화면 맨 위에 붙는다 — 숨 쉴 여백을 준다. */
h2[id^="sec-"]{scroll-margin-top:var(--space-5)}

/* 접이식 범례(`<details>`) — 종일 화면이라 정의는 처음 볼 때만 필요하다. */
.mon-fold{margin:var(--space-2) 0 0}
.mon-fold summary{cursor:pointer;font-size:12px;color:var(--color-muted);
  padding:var(--space-2) var(--space-3);border:1px solid var(--color-divider);
  border-radius:var(--radius-sm);background:var(--color-surface);
  list-style:none;display:inline-block}
.mon-fold summary::before{content:"▸ ";color:var(--color-neutral-500)}
.mon-fold[open] summary::before{content:"▾ "}
.mon-fold summary::-webkit-details-marker{display:none}
.chat{margin-top:var(--space-5);border:1px solid var(--color-divider);
  border-radius:var(--radius-md);background:var(--color-surface);
  padding:var(--space-4);min-width:0}
.chat-hd{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
  margin-bottom:var(--space-3)}
.chat-badge{padding:1px var(--space-2);border-radius:var(--radius-sm);
  font-family:var(--font-mono);font-size:11px;
  border:1px solid var(--color-divider);color:var(--color-muted)}
.chat-ok{border-color:var(--color-accent-300);color:var(--color-accent)}
.chat-off{border-color:var(--color-divider);color:var(--color-neutral-500)}
.chat-sub{font-size:11.5px;color:var(--color-muted);min-width:0;
  overflow:hidden;text-overflow:ellipsis}
/* 흘려 쓰기 신호. 평소엔 눈이 멈추지 않게 흐리고, 오래 안 바뀌면 도드라진다
   — 그때가 메신저가 죽었거나 버퍼링이 길어진 때다. */
.chat-flush{font-family:var(--font-mono);font-size:11px;
  color:var(--color-neutral-500)}
.chat-flush.stale{color:var(--color-accent-2)}
/* 타일이 스스로 잰 비용. `chat-flush` 와 **같은 옷**이다 — 둘 다 "재서 화면에
   둔 값" 이고 다른 종류로 보이면 안 된다. 느릴 때만 색이 선다. */
.chat-cost{font-family:var(--font-mono);font-size:11px;
  color:var(--color-neutral-500)}
.chat-cost.stale{color:var(--color-accent-2)}
.chat-rooms{display:flex;gap:var(--space-1);margin-left:auto;flex-wrap:wrap}
.chat-rm{padding:1px var(--space-2);border-radius:var(--radius-sm);
  border:1px solid var(--color-divider);background:transparent;
  color:var(--color-muted);font-size:11px;cursor:pointer}
.chat-rm.on{border-color:var(--color-accent-300);color:var(--color-accent)}
/* 탭은 자바스크립트를 쓰지 않는다 — 인벤토리 탭과 같은 방식이다. */
/* 탭 — 라디오 하나당 패널 하나. 자바스크립트 없이 CSS 로만 가른다.
   키 목록의 정본은 `site.CHAT_TABS` 이고, 검사가 그 전량에 규칙이 있는지
   지킨다(빠지면 그 탭은 눌러도 아무것도 안 보인다). */
#chattab-q,#chattab-arb,#chattab-lend,#chattab-auc,#chattab-iss,#chattab-news,#chattab-etc,#chattab-r{position:absolute;opacity:0;pointer-events:none}
.chat-tabs{margin-bottom:var(--space-2);flex-wrap:wrap}
.chat-p{display:none}
#chattab-q:checked ~ .chat-q,#chattab-arb:checked ~ .chat-arb,#chattab-lend:checked ~ .chat-lend,#chattab-auc:checked ~ .chat-auc,#chattab-iss:checked ~ .chat-iss,#chattab-news:checked ~ .chat-news,#chattab-etc:checked ~ .chat-etc,#chattab-r:checked ~ .chat-r{display:block}
#chattab-q:checked ~ .chat-tabs label[for="chattab-q"],
#chattab-arb:checked ~ .chat-tabs label[for="chattab-arb"],
#chattab-lend:checked ~ .chat-tabs label[for="chattab-lend"],
#chattab-auc:checked ~ .chat-tabs label[for="chattab-auc"],
#chattab-iss:checked ~ .chat-tabs label[for="chattab-iss"],
#chattab-news:checked ~ .chat-tabs label[for="chattab-news"],
#chattab-etc:checked ~ .chat-tabs label[for="chattab-etc"],
#chattab-r:checked ~ .chat-tabs label[for="chattab-r"]{
  color:var(--color-accent);border-bottom-color:var(--color-accent)}
/* 분류 목록도 호가표와 같은 높이에서 스크롤한다 — 타일이 페이지를 밀지
   않게 한다. `.nt` 본체 규칙은 공지 절과 공유한다. */
.chat-nt{max-height:44vh;overflow-y:auto;margin-bottom:0}
.chat-nt li{grid-template-columns:50px auto 1fr auto}
.chat-q .dt{max-height:44vh;overflow-y:auto}
/* 방향 — 색 단독으로 전달하지 않는다(낱말이 먼저 있고 색이 거든다). */
.q-ask{color:var(--color-accent-2)}
.q-bid{color:var(--color-accent)}
.q-ask i,.q-bid i{font-style:normal;font-size:10px;color:var(--color-muted)}
.chat-raw{list-style:none;margin:0;padding:0;max-height:44vh;overflow-y:auto;
  font-size:12px;line-height:1.6}
.chat-raw li{display:flex;gap:var(--space-2);padding:2px 0;min-width:0;
  border-bottom:1px solid var(--color-divider)}
.chat-raw li:last-child{border-bottom:0}
/* 자리를 미리 굽고 `hidden` 으로 감춘다 — `display:flex` 가 UA 의
   `[hidden]{display:none}` 를 이기므로 저자 규칙으로 다시 못박는다. */
.chat-raw li[hidden]{display:none}
.chat-q tbody tr[hidden]{display:none}
.chat-rm[hidden]{display:none}
/* ── 렉의 실제 원인은 레이아웃이었다 `[B✔]` 2026-09-02 ──────────────────
   사용자 신고: "이전 300줄 버튼을 한 번 누르면 렉이 걸려. 두번째 누를때부터는
   크롬 창이 거의 멈춰." 그때 자바스크립트 쓰기는 이미 7,078회로 묶여 있었고
   서버 응답은 41ms 였다(둘 다 실측). 남은 것이 배치 비용이었다.

   1. **표를 `fixed` 로 못박는다.** `auto` 는 `width:100%` 아래에서 열 폭을
      정하려고 창 300행 × 13칸 = 3,900칸의 내용 폭을 매 페인트마다 잰다.
      폭은 `site.CHAT_COL_W` 가 `colgroup` 으로 준다.
   2. **보이지 않는 줄은 배치하지 않는다** (`content-visibility:auto`). 창이
      300줄이어도 화면에 드는 건 30줄쯤이다. `contain-intrinsic-size` 로 높이를
      근사해 스크롤바가 튀지 않게 한다(없으면 스크롤 위치가 널뛴다).
      **표 행에는 걸지 않는다** — 명세상 내부 테이블 요소는 containment 대상이
      아니라 `tr` 에 걸면 조용히 무효인 규칙이 된다. 표는 대신 `fixed` 폭과
      아래 `max-height` 스크롤로 배치·그리기 범위를 묶는다.
   3. **타일 밖으로 번지지 않게 한다.** 이 페이지는 요소가 13,643개다 —
      표 하나의 배치가 페이지 전체를 흔들면 안 된다.
   4. **큰 표에 행별 hover 를 걸지 않는다.** `.dt tbody tr:hover td` 가 걸려
      있으면 커서가 표 위에 있는 동안 마우스가 움직일 때마다 무효화가 300행에
      번진다 — "두 번째부터 멈춘다" 가 이것이었다. 대신 표 전체를 감싼 칸에
      옅은 테두리만 남긴다(줄을 짚는 기능 자체는 `title` 이 맡는다). */
.chat-q table{table-layout:fixed}
.chat-q td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chat-q tbody tr:hover td{background:none}
.chat-p{contain:layout style paint}
/* 표는 타일 안에서 스크롤한다 — 머리(`.dt th`)가 이미 sticky 라 창을 되짚는
   동안 열 이름이 붙어 있고, 그리기 범위가 화면 높이로 묶인다. */
.chat-q .dt{max-height:68vh;overflow-y:auto}
.chat-raw,.chat-nt{max-height:68vh;overflow-y:auto}
.chat-raw li,.chat-nt li{content-visibility:auto;
  contain-intrinsic-size:auto 1.6rem}
/* 창을 옮기는 자리. 방 고르개(`.chat-rm`)와 **같은 옷**을 입힌다 — 같은
   타일에서 누르는 것이라 두 가지 단추 꼴을 만들 이유가 없다. 라임 카드로
   띄우지 않는다: 값이 아니라 조작이다.
   자리 표시(`.chat-pos`)를 가운데 두고 단추를 양쪽에 둔다 — 좌우로 움직이는
   일이라 좌우로 놓는다. */
.chat-pager{display:flex;align-items:center;justify-content:center;
  gap:var(--space-3);padding-top:var(--space-2)}
.chat-pos{font-family:var(--font-mono);font-size:11px;
  color:var(--color-neutral-500)}
.chat-pg{padding:var(--space-1) var(--space-3);
  border-radius:var(--radius-sm);border:1px solid var(--color-divider);
  background:transparent;color:var(--color-muted);font-size:11px;
  font-family:var(--font-mono);cursor:pointer}
.chat-pg:hover{border-color:var(--color-accent-300);color:var(--color-accent)}
.chat-pg[hidden]{display:none}
.cr-t{flex:none;font-family:var(--font-mono);font-size:11px;
  color:var(--color-neutral-500)}
.cr-rm{flex:none;width:5.5rem;color:var(--color-muted);font-size:11px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cr-w{flex:none;width:4.5rem;color:var(--color-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 원문은 **줄바꿈을 지운다** — 여러 줄 공지가 목록을 통째로 밀어낸다.
   전문은 아침 배치가 적재한 원장(`채팅_아카이브_자체`)에 그대로 있다. */
.cr-x{min-width:0;color:var(--color-text);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

/* ── 원천 배너 (2026-09-01 사용자 요청) ─────────────────────────────────
   "각 데이터의 원천이 어디인지 표시 · 인벤토리 시각화를 아예 새로 구성해서
   눈에 잘 띄게. 아기자기하게 만들어도 된다."

   격자만으로는 표 하나하나는 보여도 **전체의 무게중심**이 안 보인다 — 185표
   중 단말 115 · 파생 31 · 코스콤 직수신 8 이라는 사실이 이 데스크의 구조
   자체인데 어디에도 없었다. 카드 한 줄로 그것을 먼저 낸다.

   **새 색을 만들지 않는다** — 채움은 `--color-surface-2`, 막대는
   `--color-accent-300`(시트의 델타 규약 색), 글자는 기존 토큰이다. 카드는
   `auto-fill minmax` 라 좁은 화면에서 스스로 접히고 `min-width:0` 이
   본문 가로 스크롤을 막는다(`.mkg` 에서 배운 것과 같은 규칙). */
.og-wrap{display:grid;gap:var(--space-2);margin:var(--space-3) 0;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,11rem),1fr))}
.og-card{min-width:0;padding:var(--space-2) var(--space-3);
  border:1px solid var(--color-divider);border-radius:var(--radius-md);
  background:var(--color-surface-2)}
.og-card:hover{border-color:var(--color-neutral-500)}
.og-hd{display:flex;align-items:center;gap:6px;min-width:0}
.og-ic{flex:none;font-size:15px;line-height:1;color:var(--color-accent-300)}
.og-nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:11.5px;color:var(--color-text)}
.og-n{display:flex;align-items:baseline;gap:4px;margin-top:2px;
  font-family:var(--font-heading-ko);font-size:20px;line-height:1.1;
  color:var(--color-text);font-variant-numeric:tabular-nums}
.og-u{font-size:11px;color:var(--color-muted);font-family:var(--font-body-ko)}
.og-p{margin-left:auto;font-size:11px;color:var(--color-neutral-500);
  font-family:var(--font-body-ko)}
/* 막대 — 숫자를 읽지 않고 크기를 잡게 하는 유일한 장치다. 높이 3px 은
   카드 높이를 늘리지 않으면서 비율이 읽히는 최소값이다 `[E]`. */
.og-bar{margin-top:5px;height:3px;border-radius:2px;
  background:var(--color-neutral-700);overflow:hidden}
.og-bar>i{display:block;height:100%;background:var(--color-accent-300)}
/* 격자 칸의 원천 글리프 — 이름 앞 한 글자. 폭을 거의 먹지 않으면서
   "이 덩어리는 전부 단말이구나" 가 훑힌다. 뜻은 배너와 툴팁이 진다. */
.inv-og{flex:none;width:1em;text-align:center;
  color:var(--color-neutral-500);font-size:11px}
.inv-cell:hover .inv-og{color:var(--color-accent-300)}
.inv-ghead{display:flex;align-items:baseline;gap:var(--space-2);
  flex-wrap:wrap;
  margin:var(--space-6) 0 0;padding-top:var(--space-3);
  border-top:1px solid var(--color-divider);
  font-size:13px;color:var(--color-muted)}
.inv-gt{font-weight:600;color:var(--color-text)}
.inv-gn{font-variant-numeric:tabular-nums;color:var(--color-text);
  font-weight:600}
/* 내역은 오른쪽 끝으로 민다 — `.inv-sub` 와 같은 자리 규칙이라 두 단이
   같은 세로선에서 읽힌다. `min-width:0` 이 없으면 좁은 화면에서 이
   조각이 줄을 넘기지 못하고 본문에 가로 스크롤을 만든다. */
.inv-gsub{margin-left:auto;min-width:0;font-size:11.5px;
  color:var(--color-neutral-500)}
.inv-head{display:flex;align-items:baseline;gap:var(--space-2);
  margin:var(--space-4) 0 var(--space-2);
  font-size:12px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--color-muted)}
.inv-n{font-variant-numeric:tabular-nums;color:var(--color-text);
  font-weight:600;letter-spacing:0}
.inv-grid{display:grid;gap:1px var(--space-4);
  grid-template-columns:repeat(auto-fill,minmax(15rem,1fr))}
.inv-cell{display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--space-2);min-width:0;
  padding:1px var(--space-2);border-radius:var(--radius-sm);
  /* 표지 자리를 **모든 칸**이 비워둔다 — 붙는 칸에만 주면 표명이 2px 씩
     어긋나 격자가 흔들린다(`site.INV_COV` 가 색만 갈아 넣는다). */
  border-left:2px solid transparent;
  font-size:12px;line-height:1.55;color:var(--color-muted)}
.inv-cell:hover{background:var(--color-surface-2)}
/* 칸이 이제 `<a>` 다(2026-09-01 — 클릭하면 데이터셋 상세가 열린다). 밑줄을
   지우고 색은 상태(밴드)가 그대로 준다. **기본 `.inv-cell` 규칙 뒤**에 둔다 —
   앞에 두면 `.inv-cell{` 를 찾는 구조 검사가 이 파생 규칙을 먼저 문다. */
.ib-grid a.inv-cell{text-decoration:none}
.ib-grid a.inv-cell:hover code{text-decoration:underline}
/* 이름이 길면 잘라 한 줄을 지킨다 — 전체 이름은 툴팁에 있다 */
.inv-cell code{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:12px}
.inv-lag{flex:none;font-variant-numeric:tabular-nums;color:var(--color-neutral-500)}
.inv-sub{margin-left:auto;font-size:11px;letter-spacing:0;text-transform:none;
  color:var(--color-neutral-500)}
/* 신선도 밴드 — 155표를 **읽지 않고** 낡은 것이 눈에 걸리게 한다.
   새 색을 만들지 않는다: 시스템 계열 2색(라임=당일, 애저=낡음 — `[F]`
   2026-08-28 실측 `--color-accent-2` = srgb(.357 .553 .937) 로 앰버가
   아니라 애저이고, 이 시트가 이미 경고에 쓰는 색이다)을 `color-mix`
   로 옅게 깐다(시트가 이미 쓰는 방식 — 시스템 시트의 `.bento-accent` 참고).
   문턱의 정본은 `site.INV_BANDS` 이고 이 클래스 이름이 거기서 나온다. */
.inv-cell.f0{background:color-mix(in srgb,var(--color-accent) 13%,transparent)}
.inv-cell.f0 code{color:var(--color-text)}
.inv-cell.f1{background:color-mix(in srgb,var(--color-neutral-500) 16%,transparent)}
.inv-cell.f2{background:color-mix(in srgb,var(--color-accent-2) 24%,transparent)}
.inv-cell.f2 code{color:var(--color-text);font-weight:600}
.inv-cell.f2 .inv-lag{color:var(--color-accent-2-300);font-weight:600}
.inv-cell.f3{background:transparent}
/* 수집 표지 — 두 번째 채널이다(배경=낡음 · 왼쪽 테두리=우리가 수집하는가).
   `[F]` 2026-08-28 사용자 요청. 배경에 겹쳐 쓰지 않는 이유: 한 색이 두
   질문을 답하면 둘 다 못 읽는다. 정본은 `site.INV_COV` 이고 이 클래스
   이름이 거기서 나온다 — 새 색은 만들지 않는다(계열 2색과 중성색).
   수집되는 표(대다수)는 **조용하다**: 표지는 없는 쪽에 붙는다. */
.inv-cell.cov-ours{border-left-color:transparent}
.inv-cell.cov-empty{border-left-color:var(--color-neutral-500);
  border-left-style:dotted}
.inv-cell.cov-gap{border-left-color:var(--color-accent-2)}
.inv-cell.cov-none{border-left-color:var(--color-neutral-500);
  border-left-style:dashed}
/* 범례 — 밴드 넷을 실물 칸으로 보여준다(색 견본을 따로 만들지 않는다) */
.inv-legend{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
  margin-top:var(--space-3);font-size:11.5px;color:var(--color-muted)}
.inv-legend-l{font-weight:600;color:var(--color-text)}
.inv-legend-r{flex-basis:100%;color:var(--color-neutral-500)}
.inv-cell.inv-key{display:inline-flex;gap:var(--space-2);cursor:default}
.inv-cell.inv-key .inv-lag{color:inherit}
/* 상태 넷 — 멀리서 보이게 테두리와 띠가 함께 바뀐다 */
.mon-ok .mon-strip{border-color:var(--color-accent-700)}
.mon-warn .mon-strip{border-color:var(--color-accent-2)}
.mon-dead .mon-strip{border-color:var(--color-accent-2);
  background:var(--color-accent-2);color:var(--color-bg)}
.mon-dead .mon-badge{color:var(--color-bg)}
.mon-closed .mon-strip{border-style:dashed}
.mon-unreachable .mon-strip{border-style:dashed;
  border-color:var(--color-neutral-500)}

/* ── 콤팩트 수치 리스트 카드(.mlist) — 시장·수급 ─────────────────────────
   2026-08-31 사용자 요청(가독성 — 수치는 오밀조밀, 라임 카드 폐기).
   수치 하나에 대형 타일 한 장을 주면 화면이 카드 열두 장으로 늘어지고 정작
   숫자는 흩어진다. 한 행 = 라벨 | 값(단위) | 전일차 | 기준일 | 추이 —
   행 구분선 + tabular-nums 로 표처럼 세로 스캔하게 한다. 출처·주석은 행
   title 툴팁(`.inv-cell` 선례 — 버리는 게 아니라 접는다).
   열 폭을 고정하는 이유: auto/max-content 로 두면 행마다 열이 어긋나 세로
   스캔이 깨진다. 새 토큰은 만들지 않는다 — 전부 시스템 var() 참조다. */
.mlist .ml{display:flex;flex-direction:column;min-width:0}
.ml-r{display:grid;grid-template-columns:minmax(0,1fr) 128px 96px 92px 92px;
  gap:var(--space-3);align-items:center;padding:var(--space-2) 0;
  border-bottom:1px solid var(--color-hairline);font-size:12px;min-width:0}
.ml-r:last-child{border-bottom:0}
.ml-r.ml-h{font-size:11px;color:var(--color-muted);
  border-bottom:1px solid var(--color-divider);padding-bottom:var(--space-1)}
.ml-r.ml-h .ml-v,.ml-r.ml-h .ml-l{color:var(--color-muted);font-weight:500;
  font-size:11px}
.ml-l{color:var(--color-muted);min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.ml-v{text-align:right;color:var(--color-text);font-weight:600;font-size:13px;
  font-variant-numeric:tabular-nums;white-space:nowrap;
  /* 값 열은 고정 폭인데 내용은 가변이다 — `3.811 / 4.287%`(내재수익률 두 값)
     처럼 긴 값이 들어오면 열을 밀고, 그 밀림이 격자 → 카드 → 페이지까지
     번져 **본문에 가로 스크롤이 생긴다**(`[F]` 2026-08-31 실측: 4열 격자에서
     카드가 322px 로 좁아지자 80px 열에 98px 값이 들어가 페이지가 50px
     흘렀다). 열 안에서 줄이고, 넘치면 잘라 낸다 — 전체 값은 행 툴팁에 있다. */
  min-width:0;overflow:hidden;text-overflow:ellipsis}
.ml-v .u{font-size:11px;font-weight:400;color:var(--color-muted);
  margin-left:2px}
.ml-d{text-align:right;font-size:12px;white-space:nowrap}
.ml-x{color:var(--color-muted);font-variant-numeric:tabular-nums}
.ml-a{text-align:right;font-size:11px;color:var(--color-muted);
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* 기준일·다리 불일치 경고 — 본문 크기 라임은 규약대로 -300 만 */
.ml-a.hot{color:var(--color-accent-300);font-weight:600}
.ml-s{justify-self:end;display:flex;align-items:center}
.mlist .spark.mini{width:76px;height:20px}
/* 좁은 화면은 추이·기준일 열부터 접는다 — 라벨과 값이 우선이다.
   브레이크포인트는 시스템의 760 만 쓴다. */
@media (max-width:760px){
  .ml-r{grid-template-columns:minmax(0,1fr) 110px 84px}
  .ml-a,.ml-s{display:none}
}

/* ── 수급 3테너 가로 배치(.sply) ─────────────────────────────────────────
   2026-08-31 사용자 요청: "3/10/30년 표를 한 번에 가로로 다 보여주고, 1일/
   1주/1개월/1년 전 대비는 컬럼으로". 앞선 배치는 카드 여섯 장을 세로로
   쌓았고(레벨 셋 + 흐름 셋) 네 기간이 `.ml-m` 로 한 칸에 뭉쳐 있어서
   ① 세 테너를 한 화면에서 비교할 수 없고 ② 같은 기간을 주체끼리 세로로
   훑을 수 없었다. 이제 블록 하나(축 하나) 안에 테너 카드 셋이 가로로 서고
   기간은 표의 독립 열이다. **레벨/흐름은 여전히 다른 블록이다(§3.3).**

   격자에 `auto-fit` 을 쓰는 이유: 새 브레이크포인트를 만들지 않고도 폭이
   모자라면 스스로 2열·1열로 접힌다(시트의 1000/760/520 규약을 건드리지
   않는다). **페이지 본문에 가로 스크롤을 만들지 않는다** — 카드 안 표가
   정말 넘치면 `.dt`(overflow-x:auto)가 그 표 안에서만 스크롤하고 시트의
   `[data-scroll]` 단서가 그 사실을 적는다.
   새 토큰·색은 만들지 않는다 — 전부 시스템 var() 참조이고 라임 채움은 없다. */
.sply-g{display:grid;gap:var(--space-4);align-items:start;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
.sply-c{min-width:0;display:flex;flex-direction:column;gap:var(--space-2)}
.sply-t{display:flex;align-items:baseline;gap:var(--space-2);flex-wrap:wrap;
  font-size:11.5px;color:var(--color-muted)}
.sply-t b{font-family:var(--font-heading-ko);font-size:14px;font-weight:600;
  color:var(--color-text)}
.sply-t span{font-variant-numeric:tabular-nums}
/* 한 카드에 숫자 열이 다섯(누적 레벨 + 기간 넷)이라 시스템 `.dt.sm` 여백
   (8/12px)으로는 3열 배치에서 표가 넘친다. **값을 지우거나 줄이지 않고
   여백·자간만 줄인다** — 숫자는 tabular-nums 라 폭이 흔들리지 않는다.
   `.dt th` 의 자간 .09em 은 한글 기간 라벨에서 그냥 낭비라 되돌린다. */
.sply .dt.sm table{font-size:11px}
.sply .dt.sm th,.sply .dt.sm td{padding:var(--space-1) 6px}
.sply .dt th{letter-spacing:.02em}
.sply .dt td.name{color:var(--color-muted);font-weight:500}
.sply .spark.mini{width:64px;height:18px}
.sply .dt td.sply-sp{padding-top:2px;padding-bottom:2px}
.sply .blkbody > .note{margin-top:var(--space-3)}

/* ── 시장 카드 가로 격자(.mkg) ───────────────────────────────────────────
   2026-08-31 사용자 요청: "시장 상태에는 전일비 변동 상위·대차 잔량 상위·
   순매수를 한 행에 쫙", "국고 커브쪽도 표들을 아래로 열거하지 말고 한 행에".

   앞선 배치는 ① 리스트 카드 넷(커브 레벨 16행·기울기·커브 간·시장 수치)을
   블록이라 **세로로** 쌓았고(그것만 화면 한 장이다) ② 라이브 차트 셋은 12열
   트레이 안에서 티어 승격(차트가 든 타일은 t-primary=6열)때문에 2+1 두 행으로
   갈렸다. 어느 쪽도 한 화면에서 비교가 안 된다.

   수급이 먼저 쓴 `.sply-g` 와 **같은 방식**이다 — 트레이(고정 행높이 격자)가
   아니라 블록 격자에 올리고 `auto-fit` 으로 접는다. 블록인 이유는 카드마다
   행 수가 5~16으로 달라서다(고정 높이면 절반이 빈 카드가 된다 — `.mlist` 가
   블록인 것과 같은 이유). 새 브레이크포인트는 만들지 않는다.

   **페이지 본문에 가로 스크롤을 만들지 않는다.** `.ml-r` 은 고정 폭 열 넷
   (128+96+92+92 + 간격)만으로 456px 을 요구하므로 300px 트랙에 그대로 넣으면
   카드가 넘쳐 본문이 가로로 흐른다. 그래서 열을 **뷰포트가 아니라 카드 자기
   폭**(컨테이너 질의 — 시트가 `.blkbody` 에서 이미 쓰는 장치)으로 접는다.
   뷰포트 기준(760px 미디어)으로 접으면 넓은 화면의 좁은 카드가 그대로 넘친다.
   좁은 카드에서 먼저 접는 것은 추이·기준일이고 라벨·값·전일차는 남는다 —
   시트의 760 규칙과 같은 우선순위다. 새 토큰·색은 만들지 않는다. */
.mkg{display:grid;gap:var(--space-4);align-items:start;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
/* 넓은 변형 — **차트가 든 카드**용 `[F]` 2026-09-04 사용자 지시("호가 추이
   차트들 정렬 조절해서 페이지에서 잘 보이게").

   300px 최소폭은 리스트·표 카드 기준이다. 차트는 그 폭에서 `.v-s` 변형
   (viewBox 300)이 선택되고, 12계열 범례가 세 줄로 접히면서 카드마다 높이가
   달라져 격자가 톱니처럼 어긋난다. 620px 를 최소로 두면 `@container tile
   (min-width:600px)` 를 넘어 `.v-l`(viewBox 740)이 서고, 넓은 화면에서
   정확히 **두 열**이 된다 — 여섯 장이 3행으로 가지런히 눕는다. */
.mkg.mkg-w{grid-template-columns:repeat(auto-fit,minmax(min(100%,620px),1fr))}
.mkg > .blk{min-width:0}
/* 격자 칸 안의 모든 자식이 **줄어들고 잘릴 수** 있어야 한다.
   `[F]` 2026-08-31 실측: 라벨(`.ml-l`)에만 잘림 규칙이 있었고 구간(`.ml-d`)·
   기준일(`.ml-a`) 은 `nowrap` 인데 잘리지 않아, 발행·입찰 요약 카드에서 행이
   508px(카드 435px)로 부풀어 격자 → 페이지까지 밀었다(본문 가로 스크롤 50px).
   전체 값은 행 툴팁에 있으므로 여기서 자르는 것은 정보를 버리는 것이 아니다. */
.mkg .ml-r > *{min-width:0;overflow:hidden;text-overflow:ellipsis}
.mkg .mlist .ml{container-type:inline-size;container-name:mkgc}
/* 좁은 카드 기본값 — 라벨 | 값 | 전일차. 넓어지면 기준일·추이가 돌아온다 */
.mkg .ml-r{grid-template-columns:minmax(0,1fr) 80px 64px;gap:var(--space-2)}
.mkg .ml-a,.mkg .ml-s{display:none}
@container mkgc (min-width:340px){
  .mkg .ml-r{grid-template-columns:minmax(0,1fr) 88px 68px 66px}
  .mkg .ml-a{display:block}
}
@container mkgc (min-width:440px){
  .mkg .ml-r{grid-template-columns:minmax(0,1fr) 100px 76px 76px 60px;
    gap:var(--space-3)}
  .mkg .ml-s{display:flex}
}
/* 스파크는 자기 칸에 맞춘다 — `.spark.mini` 는 viewBox 라 폭만 주면 줄어든다 */
.mkg .mlist .spark.mini{width:100%;max-width:60px;height:18px}
/* 접힘(`<details class="fold">`)도 같은 한 행 격자에 선다 — `[F]` 2026-08-31
   사용자 요청("발행입찰쪽도 한 행으로 가로로 나열해"). 발행·입찰의 참조용
   과거 표 둘(최근 완료 8열 · 테너별 5열)이 세로로 이어져 있었다.

   접힘은 `.blk` 가 아니라 `<details>` 라 위의 `.mkg > .blk{min-width:0}` 이
   걸리지 않는다. 격자 자식의 기본값은 `min-width:auto` 라 8열짜리 완료 표가
   트랙을 밀어 **본문이 가로로 흐른다** — 스크롤은 표 안(`.dt{overflow-x:auto}`)
   에서만 일어나야 한다. 그래서 `min-width:0` 만 준다. 여기에 `overflow` 를
   걸지 않는다(격자가 스크롤하면 잘린 표를 알아챌 단서가 사라진다).
   위쪽 여백은 격자 `gap` 이 이미 지므로 `.fold` 의 상단 마진은 되돌린다. */
.mkg > .fold{min-width:0;margin:0}
/* 앵커 카드(`_acc`)가 이 격자에 들어오면서 생기는 넘침 둘을 막는다 —
   `[F]` 2026-08-31(발행·입찰 한 행 가로). ① 시트의 `.bento-meta` 는
   `display:flex` 이고 그 자식은 `min-width:auto` 라 "09/02 국고03625-2809(26-7)
   경쟁" 같은 메타 한 줄이 300px 트랙을 밀어 **본문이 가로로 흐른다**(옛
   자리는 12열 트레이 타일이라 폭이 넉넉했다). ② 종목명은 한글·숫자·하이픈이
   붙은 한 덩어리라 줄바꿈 지점이 없다.
   값을 지우거나 줄이지 않고 **줄을 접게만** 한다 — 여기에도 `overflow` 는
   걸지 않는다. */
.mkg .bento-meta{flex-wrap:wrap}
.mkg .bento-meta>*,.mkg .bento-body{min-width:0;overflow-wrap:anywhere}

/* ── 다음 경쟁 입찰 앵커 카드(`site._auc_next_card`) ─────────────────────
   `[F✔]` 2026-08-31 사용자 보고: "D-day 태그가 짤려서 내려감."

   위 `flex-wrap:wrap` 처방은 **원인을 못 고쳤다**. 옛 카드는 D-day 칩이
   `.bento-body` **산문의 꼬리**였고, 좁은 트랙(300~435px)에서 그 문장이
   서너 줄로 접히면서 배경+패딩이 붙은 칩(`.dl.dd-today`)이 마지막 줄에
   홀로 떨어졌다. 줄을 접게 하는 규칙은 그 상태를 만들어 내는 쪽이다.

   그래서 칩을 산문에서 꺼내 **큰 날짜와 한 줄로 못 박는다.** `.auc-hd` 는
   `flex-wrap:nowrap` 이고 칩은 `flex:0 0 auto` 라 어떤 폭에서도 줄어들지도
   내려가지도 않는다 — 이 카드에서 먼저 보는 값이 "언제 · 며칠 남았나" 둘이고
   둘은 갈라지면 안 된다. 날짜는 `white-space:nowrap` 이라 "08/31 2026" 이
   연도만 다음 줄로 떨어지지 않는다(칩의 baseline 이 흔들린다).

   나머지(종목·만기·구분·예정액)는 `.auc-kr` 두 칸 격자다. 값 칸이
   `minmax(0,1fr)` + `overflow-wrap:anywhere` 라, 줄바꿈 지점 없는 종목명
   (`국고03625-2809(26-7)`)도 **자기 칸 안에서** 접히고 트랙을 밀지 않는다.
   `overflow:auto|scroll` 은 여기에도 걸지 않는다(격자 스크롤 금지 규약). */
.auc-hd{display:flex;align-items:baseline;flex-wrap:nowrap;gap:var(--space-3);
  margin:var(--space-1) 0 var(--space-2)}
.auc-hd .bento-metric{min-width:0;white-space:nowrap}
.auc-hd .dl{flex:0 0 auto;white-space:nowrap}
.auc-yr{font-size:.34em;color:var(--color-muted);margin-left:.25em}
.auc-kv{display:flex;flex-direction:column;gap:var(--space-1);font-size:12.5px;
  color:var(--color-muted);border-top:1px solid var(--color-divider);
  padding-top:var(--space-2)}
.auc-kr{display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:var(--space-3);align-items:baseline}
.auc-kr>b{justify-self:end;text-align:right;color:var(--color-text);
  font-weight:600;overflow-wrap:anywhere}

/* ── 카드 제목 위계 + 출처 표기(.cs) + 추이 열 정렬 ───────────────────────
   `[F]` 2026-08-31 사용자 요청 셋을 한 절에서 처리한다. 새 토큰·리터럴 색은
   만들지 않는다 — 전부 시스템 var() 참조이고 라임 채움은 없다.

   ① "각 표별 제목이 더 눈에 띄게."
      `.cap` 은 11px · 대문자 · `--color-muted` 라 **본문(13px, 같은 회색)과
      거의 같은 무게**였다. 카드가 열 장 넘게 이어지는 시장 화면에서 제목이
      본문에 묻힌다. 제목(`.ct`)만 **제목체·14px·700·본문색**으로 올리고,
      개수·규격 같은 **부연은 `.cq`** 로 떼어 작고 흐리게 둔다(호출부가
      `count=` 로 넘긴다 — `site._caphead`). 캡션 밑에 hairline 을 깔아
      "여기부터 카드 내용" 을 눈으로 가른다. `.cap` 기본 규칙은 그대로 두고
      **덮어쓰기만** 한다(시트 뒤쪽이라 같은 특정도에서 이긴다).

   ② "어떤 데이터셋에서 그렸는지 모두 뜨도록 통일."
      `.cs` = 캡션 오른쪽 끝의 표명 칩. 표명은 코드에서 오므로 `--font-mono`
      다. 좁은 카드(`.mkg` 300px 트랙)에서 **줄이고 잘린다** — 전문은 칩의
      title 툴팁에 있으므로 자르는 것이 정보를 버리는 것이 아니다
      (`.mkg .ml-r > *` 가 이미 세운 계약과 같다). `margin-left:auto` 로
      오른쪽에 붙이되, 뒤따르는 상태배지(`.st`)·태그(`.tag`)가 **또 한 번**
      auto 를 먹어 둘 사이가 벌어지는 것을 막는다(둘 다 auto 면 남는 폭이
      반씩 나뉜다).

   ③ "수급쪽 추이 그래프와 '추이' 글씨 간 정렬이 안 맞음. 그래프를 우측정렬."
      머리글은 `.dt th.n{text-align:right}` 로 우측인데 스파크는
      `.spark{display:block}` 이라 **블록 상자가 칸 왼쪽에 붙어** 있었다 —
      `text-align` 은 블록 상자를 움직이지 못한다. 블록 그대로 두고
      `margin-left:auto` 로 밀어 머리글과 오른쪽 변을 맞춘다. `.mlist` 의
      `.ml-s` 열도 같은 부류라 함께 맞춘다(플렉스라 `justify-content`). */
.cap .ct{font-family:var(--font-heading-ko);font-size:14px;font-weight:700;
  letter-spacing:-.005em;text-transform:none;color:var(--color-text);
  line-height:1.3;min-width:0;overflow-wrap:anywhere}
.cap .cq{font-size:11px;font-weight:500;letter-spacing:.02em;
  text-transform:none;color:var(--color-muted);min-width:0;
  font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.cap .cs{margin-left:auto;font-family:var(--font-mono);font-size:10.5px;
  font-weight:500;letter-spacing:0;text-transform:none;
  color:var(--color-muted);white-space:nowrap;min-width:0;overflow:hidden;
  text-overflow:ellipsis;border:1px solid var(--color-divider);
  border-radius:var(--radius-sm);padding:1px var(--space-2)}
.cap .cs~.tag,.cap .cs~.st{margin-left:var(--space-2)}
.blk>.cap,.bento-tile>.cap{padding-bottom:var(--space-2);
  border-bottom:1px solid var(--color-divider)}
/* 추이 열 우측 정렬 — 머리글(`추이`)과 스파크의 오른쪽 변을 맞춘다 */
.dt td.n .spark.mini,.sply .dt td.sply-sp .spark.mini{margin-left:auto}
.ml-s{justify-content:flex-end}
.ml-s .spark.mini{margin-left:auto}
