/* 여기 있던 토큰 18개를 지웠다(2026-09-04).
 *
 * 전부 뒤에 실리는 `tokens.css`가 덮고 있어서 **한 줄도 화면에 닿지 않았다**.
 * 코드를 바꾸지는 않았지만 읽는 사람을 속였다 — 옛 액센트 #42a5ff와 옛 muted
 * #929ba3가 여기 적혀 있어서, 이 파일만 본 사람은 그 값이 산다고 믿었다.
 * 토큰의 진실은 언제나 `tokens.css`다. `color-scheme`만 남긴다. */
:root {
  /* Android 인앱 WebView 중 일부는 body 배경을 루트 캔버스로 전파하지 않고
     앱의 기본 흰 면을 드러낸다. 토큰 시트가 오기 전부터 불투명한 바닥을 두고,
     지원하는 엔진에는 자동 색상 변환을 금지한다. 첫 선언은 `only`를 모르는
     옛 WebView의 폴백이다. */
  color-scheme: dark;
  color-scheme: only dark;
  background-color: #070b12;
}

/* 다크 고정(2026-08-19): 라이트 팔레트 제거. 페이지 정체성은 다크 단일이다. */

* { box-sizing: border-box; }
[hidden] { display: none !important; }
/* scroll-padding-top은 스크롤포트에 두지 않는다 — 앵커뿐 아니라 **포커스**
   이동에도 걸려서, sticky 검색칸을 누르면 화면이 위로 끌려간다(tokens.css의
   `main [id]` 규칙과 그 주석 참고). 여백은 앵커 대상이 갖는다. */
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background:
    radial-gradient(circle at 7% -5%, rgba(66,165,255,.08), transparent 24rem),
    radial-gradient(circle at 94% 4%, rgba(45,212,163,.055), transparent 26rem),
    var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  /* `tokens.css:148`이 뒤에서 `--fs-md`(15)로 덮고 있었다. 본문 크기가 두 파일에
     다른 값으로 적혀 있으면 다음 사람이 14를 믿고 em 계산을 한다. 살아 있는
     값으로 맞춘다 — 렌더는 안 바뀐다. */
  font-size: var(--fs-md);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
button, select { font: inherit; }
a { color: inherit; }
button, a, select { -webkit-tap-highlight-color: transparent; }
/* `summary`가 빠져 있었다 — 콘솔의 주요 인터랙션("이 가격은 어떻게 계산한
   값인가요?")이 접힘이라 키보드 사용자에게는 브라우저 기본 링만 떴다. */
button:focus-visible, a:focus-visible, select:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.skip-link {
  position: fixed; left: 12px; top: -80px; z-index: 1000;
  padding: 10px 14px; border-radius: var(--r-md); background: var(--ink); color: var(--bg);
}
.skip-link:focus { top: 12px; }

.masthead {
  position: sticky; top: 0; z-index: 100; display: flex; align-items: center;}
.brand { display: inline-flex; align-items: center; text-decoration: none;}
.brand-mark { display: block; color: var(--ink);}
.brand strong { display: block;}
.brand small { margin-top: 1px; color: var(--faint); font: 9px/1.25 var(--num); font-variant-numeric: tabular-nums; letter-spacing: .09em;}
.mast-nav { display: flex; gap: 5px; }
/* --- 화면 전환 탭 -----------------------------------------------------------
   두 화면 사이를 오가는 길이 잘 보이지 않았다. 어느 화면에 있는지와 다른
   화면으로 가는 길이 함께 보여야 한다. 두 페이지가 같은 모양을 쓴다. */
.view-switch {
  display: inline-flex;}
.view-tab { text-decoration: none; white-space: nowrap;
  transition: background .15s, color .15s;}
@media (max-width: 640px) {
  .view-tab { padding: var(--sp-1h) 11px; font-size: 12px; }
}

.nav-chip, .icon-button, .refresh-button {
  border: 1px solid var(--line); color: var(--muted); background: transparent;
  text-decoration: none; border-radius: var(--r-sm); transition: border-color .15s, color .15s, background .15s;
}
.nav-chip { padding: var(--sp-1h) 10px; font-size: 11px; font-weight: 700; }
.nav-chip:hover, .nav-chip.active { color: var(--ink); background: var(--panel-2); border-color: var(--line-strong); }
.nav-chip.active { box-shadow: inset 0 -2px var(--accent); }
.mast-actions { margin-left: auto; display: flex; align-items: center;}
.connection-badge {
  display: inline-flex; align-items: center; gap: 7px; margin-right: 5px;
  color: var(--muted); font: 10px/1 var(--num); font-variant-numeric: tabular-nums; text-transform: uppercase; letter-spacing: .06em;
}
.connection-badge i { width: 6px; height: 6px; border-radius: 50%; background: var(--amber); box-shadow: 0 0 0 4px color-mix(in srgb, var(--amber) 12%, transparent); }
.connection-badge.ok i { background: var(--green); box-shadow: 0 0 0 4px color-mix(in srgb, var(--green) 12%, transparent); }
.connection-badge.stale i { background: var(--amber); box-shadow: 0 0 0 4px color-mix(in srgb, var(--amber) 12%, transparent); }
.connection-badge.error i { background: var(--red); box-shadow: 0 0 0 4px color-mix(in srgb, var(--red) 12%, transparent); }
.icon-button { min-width: 38px; padding: 0 9px; cursor: pointer; font: 700 11px/1 var(--num); font-variant-numeric: tabular-nums;}
.icon-button:hover, .refresh-button:hover { color: var(--ink); border-color: var(--line-strong); background: var(--panel-2); }

/* 청산 집계 — 거래소별 합계와, 답하지 않은 거래소를 함께 보여 준다. */
.cliq-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; }
.cliq-card { padding: 15px 16px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel-2); }
.cliq-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
/* 12px 내용을 이끄는 카드 제목이다 — `.kro-card h3`(15가 12를 이끈다)와 같은 단. */
.cliq-head a { color: inherit; font: 700 var(--fs-md)/1.2 var(--sans); text-decoration: none; }
.cliq-head a:hover { color: var(--accent); }
.cliq-head .oi { color: var(--muted); font: 650 10.5px/1.2 var(--num); font-variant-numeric: tabular-nums; }
.cliq-total { margin: 11px 0 3px; font: 700 22px/1 var(--num); font-variant-numeric: tabular-nums; }
.cliq-split { display: flex; height: 7px; margin: 9px 0 7px; border-radius: var(--r-sm); overflow: hidden; background: var(--line); }
.cliq-split i { display: block; height: 100%; }
.cliq-split .long { background: var(--up); }
.cliq-split .short { background: var(--down); }
.cliq-legend { display: flex; justify-content: space-between; gap: 10px; color: var(--muted); font: 650 10.5px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.cliq-legend .long { color: var(--up); }
.cliq-legend .short { color: var(--down); }
.cliq-venues { margin: 11px 0 0; padding: 9px 0 0; border-top: 1px solid var(--line); color: var(--faint); font: 650 10px/1.6 var(--num); font-variant-numeric: tabular-nums; }
.cliq-venues b { color: var(--muted); font-weight: 650; }
.cliq-silent { color: var(--faint); }

/* 통합 검색 — 마스트헤드 한 칸에서 코인·국내·미국을 함께 찾는다.
 *
 * 2026-09-07 다시 짰다. 운영자 둘: "검색창 디자인이 너무 올드해", 그리고
 * "클릭했을때 순간적으로 늘어나는 애니메이션이 별로야 — 조금 더 살아있고
 * 동적인 애니메이션이면 좋겠어".
 *
 * 낡아 보이던 것의 정체는 **그림이 없다는 것**이었다. 테두리 하나짜리 빈
 * 상자에 문장 하나뿐이라, 이 제품에서 검색이라고 말하는 그림을 달지 않은
 * 유일한 검색 자리였다 — 하단 탭의 `검색`은 돋보기를 단다. 같은 뜻에 두
 * 생김새를 두면 둘 다 약해진다.
 *
 * 튀던 것은 전이를 안 걸어서다. 옛 주석에 이유가 적혀 있었다 — 폭을
 * 전이시키면 마스트헤드가 매 프레임 다시 풀린다. 맞는 걱정이었지만 답은
 * 전이를 포기하는 것이 아니라 **자리를 미리 잡는 것**이었다. `.site-search`
 * 가 열린 폭을 늘 차지하고 알약은 그 안에서 오른쪽에 붙어 산다. 여는 동안
 * 바뀌는 것은 알약의 폭뿐이고, 부모의 폭은 고정이라 위쪽 플렉스 줄은 다시
 * 풀리지 않는다. 쉬는 상태의 생김새는 그대로다 — 왼쪽에 생기는 빈자리는
 * 아무것도 그리지 않는다.
 *
 * 여는 방향은 **왼쪽**이다. 오른쪽 끝은 EN 단추 옆에 고정이라 움직일 수
 * 없고, 무엇보다 검색이 향하는 곳은 왼쪽의 내용이다. 돋보기가 그 열리는
 * 모서리에 앉아 함께 간다 — 상자가 늘어나는 것이 아니라 그림이 나아가는
 * 것으로 눈이 읽는다. 이 화면의 authored moment는 그 한 번이다. */
.site-search {
  position: relative; display: flex; align-items: center;
  --search-rest: 186px; --search-open: 258px;
  /* 열린 폭을 미리 잡는다. `contain`은 쓰지 않는다 — 이 상자가 절대 위치의
     기준이 되면 좁은 화면에서 자동완성 목록을 마스트헤드에 맞춰 둔 규칙이
     깨진다(tests/frontend/test_search_panel_mobile.py). 폭이 고정인 것만으로 위쪽
     줄은 다시 풀리지 않는다. */
  flex: 0 0 auto; width: var(--search-open);
}
/* 여백은 **안내 문장이 들어가고 남을 만큼**이어야 한다.
   운영자 제보 2026-09-07: "종목·코인 검색에서 색 자가 잘려서 보기 안 좋아".

   내 자로는 들어갔다(글자 73.4 · 자리 75.0). 그 1.6px이 문제였다 — 폰트를
   그리는 쪽이 기기마다 조금씩 다르고, 여유가 한 픽셀대면 그 차이가 그대로
   잘림이 된다. **'딱 들어간다'는 들어간 것이 아니다.** 아이콘 옆 간격과 좌우
   여백을 각각 2px씩 줄여 자리를 6px 벌리고, 쉬는 폭도 한 단 올린다. */
.site-search-field {
  position: relative; display: flex; align-items: center; gap: var(--sp-1h);
  box-sizing: border-box; width: var(--search-rest); margin-left: auto;
  height: 32px; padding: 0 10px;
  background: var(--panel); border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  /* 닫히는 것이 여는 것보다 빠르다 — 기본값이 닫힌 상태의 값이다. */
  transition: width .2s cubic-bezier(.16, 1, .3, 1), border-color .18s, background .18s;
}
.site-search:focus-within .site-search-field {
  /* 레인 폭을 **길이로** 적는다. `100%`는 플렉스 항목의 퍼센트 해석에 걸려
     실측에서 아예 안 먹었다(`!important`를 붙여도 124px 그대로). 값이 하나뿐인
     레인이므로 같은 변수를 그대로 부르는 편이 읽기에도 정확하다. */
  width: var(--search-open); border-color: var(--accent); background: var(--panel-2);
  transition-duration: .32s, .18s, .18s;
}
.site-search-ico {
  flex: 0 0 auto; width: 15px; height: 15px;
  color: var(--ink-3); transition: color .18s;
}
/* 초점이 간 칸은 지금 할 일이 있는 자리다 — 이 세계에서 그 뜻의 색은
   액센트다. 테두리와 그림이 같은 순간에 같은 색으로 간다. */
.site-search:focus-within .site-search-ico { color: var(--accent); }
.site-search-input {
  flex: 1 1 auto; min-width: 0; width: 100%;
  height: 100%; padding: 0; color: var(--ink);
  background: none; border: 0;
  font: 500 var(--fs-sm)/1 var(--sans);
}
.site-search-input:focus { outline: none; }
.site-search-input::placeholder { color: var(--faint); }
.site-search-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
/* 초점이 **멀리서** 넘어왔을 때 눈이 따라오게 한다.
 *
 * 홈의 "+ 종목 추가"를 누르면 초점이 여기로 오는데, 두 자리가 286px 떨어져
 * 있고 마스트헤드는 sticky라 칸은 움직이지도 않는다. 게다가 프로그램으로 준
 * 초점은 `:focus-visible`을 켜지 않아서(실측) 이 세계의 액센트 초점 링이 아예
 * 안 뜬다. 알약이 열리고 테두리가 액센트로 가는 것만으로는, 화면 한가운데를
 * 보고 있던 눈이 위를 볼 이유가 없다.
 *
 * 링이 칸에 **내려앉는** 한 박자를 준다. 그림자가 아니라 `outline`이다 —
 * The No-Shadow Rule은 그림자를 점등과 소등 테두리 두 자리에만 허용한다.
 * 색은 액센트(동작)다: 여기가 지금 할 일이 있는 자리라는 뜻이 정확히 맞는다.
 * 청록(`--seg-live`)은 "값이 도착했다"는 뜻이라 여기서는 거짓말이 된다.
 *
 * 한 번만 돈다. JS가 붙이고 `animationend`에서 뗀다. */
@keyframes search-handoff {
  from { outline-color: var(--accent); outline-offset: 7px; }
  to   { outline-color: transparent;   outline-offset: 2px; }
}
.site-search-field.is-handoff {
  outline: 2px solid transparent;
  animation: search-handoff .42s cubic-bezier(.16, 1, .3, 1) 1;
}
@media (prefers-reduced-motion: reduce) {
  /* 움직임만 지운다. 알약은 여전히 열리고 테두리도 액센트로 가되, 그 변화가
     **즉시** 일어난다 — 상태 변화를 지우는 것이 아니라 이동을 지우는 것이다.
     내려앉는 링은 이동 그 자체라 통째로 뺀다. */
  .site-search-field, .site-search:focus-within .site-search-field {
    transition-duration: .01ms, .01ms, .01ms;
  }
  .site-search-field.is-handoff { animation: none; outline: none; }
}
/* **뒤를 가린다.**
 *
 * 패널이 본문 위에 떠 있는데 아무것도 안 가려서, 결과 줄 사이로 아래 문장이
 * 그대로 비쳤다 — 실측 `/` 390px에서 패널 바로 아래 "아직 고정한 종목이
 * 없습니다…"가 같은 밝기로 읽혔다(운영자 2026-09-08 "가독성이 0에 가까워").
 * 목록을 읽는 동안 배경은 배경이어야 한다.
 *
 * 가림막은 패널의 형제가 아니라 **문서 바닥**에 깐다 — 마스트헤드가
 * `backdrop-filter`를 갖고 있어 그 안의 고정 요소는 머리 안에 갇힌다
 * (`--mast-h` 아래로 못 내려간다). `body`에 클래스를 걸어 켠다. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg) 62%, transparent);
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease;
}
body.search-open::after { opacity: 1; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) { body::after { transition: none; } }

/* **드롭다운은 자기 입력창에 맞춘다.**
 *
 * 342px 고정이었다. 마스트헤드의 검색창은 258px이라 패널이 왼쪽으로 84px
 * 튀어나왔고, 결과가 한 건일 때 그 84px이 통째로 빈 자리로 읽혔다
 * (운영자 2026-09-08 "네비우스 옆에 박스가 왜이리 많이남아").
 *
 * 열림의 주인은 입력창이므로 폭도 입력창이 정한다. 다만 하한은 **재서**
 * 정한다 — 300px으로 줄였더니 "Nebius Group N.V."가 잘렸다. 방금 주인공으로
 * 올린 이름을 자르면 줄인 보람이 없다.
 *
 * 실측(15px w650 캔버스): 이름 최장 128px("Nebius Group N.V.", 한국어는
 * "에이치엘비생명과학" 117), 등락 44, 표식 칸 84, 간격 20, 판 여백 12
 * → **288 필요**. 이름 칸이 124px이라 **4px 모자라서** 잘렸다. 하한을 312로
 * 두면 이름 칸이 152px이 되어 24px 여유가 남는다. */
.site-search-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  /* **내용이 폭을 정하고 입력창이 하한을 준다.**
     고정 폭이면 남는 자리가 이름과 등락 사이에 고인다(`1fr`이 이름 칸을
     늘려 등락을 오른쪽 끝까지 민다). `max-content`면 그 고임이 없다. */
  width: max-content;
  min-width: min(100%, calc(100vw - 24px));
  /* 상한이 없으면 이름이 긴 결과에서 506px까지 벌어진다(실측 "bit"). 열림의
     주인이 258px인데 그 두 배가 되면, 빈 자리는 없어도 딸린 것처럼 안 읽힌다.
     420 위로는 이름을 줄임표로 자른다 — 목록에서는 그게 정상이다. */
  max-width: min(420px, calc(100vw - 24px));
  max-height: 62vh; overflow-y: auto;
  padding: var(--sp-1h); background: var(--panel); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .45);
}
/* **9.5px은 우리 규칙 밖이다.** `tokens.css` 첫 줄이 "8~10px 텍스트를 없앤다,
   최소 12px, 이보다 작게 쓰지 않는다"인데 이 패널에만 남아 있었다. */
.site-search-group {
  margin: 10px 0 4px; padding: 0 8px;
  color: var(--faint); font: 650 var(--fs-xs)/1.4 var(--num);
  font-variant-numeric: tabular-nums; letter-spacing: .08em; text-transform: uppercase;
}
.site-search-hit {
  /* 첫 칸을 84px로 묶는다. 로고가 붙은 표식과 글자만 있는 표식이 섞이면
     이름 시작 x가 흔들려, 훑을 때 눈이 줄마다 왼쪽 모서리를 다시 찾는다.
     실측(412px, 2026-08-31): 핀 없을 때 93~115px, 76px 핀에서도 로고 칩이
     81px이라 112/117로 갈렸다. 배포본에서 가장 넓은 칩이 81px이다.

     이건 subgrid를 못 쓰는 브라우저의 **바닥**이다. 아래 블록이 같은 보장을
     더 좁게 해 준다 — 84는 국내 6자리 코드에서 나온 값이라 `NBIS` 같은 미국
     티커에서는 30px이 칩과 이름 사이에 그대로 벌어졌다(운영자 2026-09-08). */
  display: grid; grid-template-columns: minmax(84px, auto) minmax(0, 1fr) auto;
  /* 심벌이 테두리 있는 표식(`.ticker-mark`)이 된 뒤로 baseline 정렬은 상자를
     한 칸 들어 올려 이름과 어긋나 보인다. 가운데로 맞춘다. */
  align-items: center; gap: 10px;
  /* 손가락이 짚는 줄이다 — 44px을 확보한다(2.5.5). 7px 여백일 때 34px이었다. */
  min-height: 44px;
  padding: 8px; border-radius: var(--r-sm); color: var(--ink); text-decoration: none;
  transition: background-color .14s ease, transform .12s cubic-bezier(.2, .8, .3, 1);
}
/* **열을 패널이 갖고 줄들이 나눠 쓴다.**
 *
 * 84px 고정이 지키던 것은 "줄마다 이름 시작 x가 같다"였고, 그건 지켜야 한다.
 * 다만 그 값이 국내 6자리 코드에서 나온 상수라 미국 티커에서는 30px이 남았다.
 * subgrid면 칸 폭을 **이 패널에서 가장 넓은 표식**이 정하므로 둘 다 얻는다 —
 * 미국 결과만 있으면 좁게, 국내가 섞이면 그만큼. */
@supports (grid-template-columns: subgrid) {
  .site-search-panel {
    display: grid; align-content: start;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr) auto;
  }
  .site-search-panel > .site-search-group,
  .site-search-panel > .site-search-note { grid-column: 1 / -1; }
  .site-search-hit {
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
  }
}
.site-search-hit:hover, .site-search-hit.is-active { background: var(--accent-soft); }
.site-search-hit.is-pressed { transform: scale(.985); }
.site-search-hit .hit-symbol { font: 700 12px/1.3 var(--num); font-variant-numeric: tabular-nums; }
/* **이름이 주인공이다.** 코드가 굵고 이름이 안 굵어서 위계가 뒤집혀 있었다 —
   사람은 코드를 외워 오지 않는다. 코드는 같은 이름이 여럿일 때 가르는
   표식이고, 그 일은 12px 표식으로 충분하다. */
.site-search-hit .hit-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-md); font-weight: 650; letter-spacing: -.01em;
}
/* 10px이었다. 하필 **색으로 오르내림을 말하는 자리**가 화면에서 가장 작았다 —
   색은 크기를 못 대신한다. */
.site-search-hit .hit-meta {
  display: flex; align-items: baseline; gap: 5px; justify-content: flex-end;
  color: var(--muted); font: 700 var(--fs-sm)/1.3 var(--num);
  font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -.01em;
}
/* **날짜는 값이 아니라 값에 붙은 이름표다.** 등락색은 퍼센트에만 든다 —
   `.hit-meta` 통째로 물들이면 "9.7"까지 초록이 되어 그것도 값으로 읽힌다. */
.site-search-hit .hit-when { font-style: normal; font-weight: 600; color: var(--faint); }
.site-search-hit .hit-meta.up, .site-search-hit .hit-pct.up { color: var(--up); }
.site-search-hit .hit-meta.down, .site-search-hit .hit-pct.down { color: var(--down); }
.site-search-note { margin: 0; padding: 12px 9px; color: var(--muted); font-size: 12px; }

.shell { margin: 0 auto;}
.hero {
  display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(220px, .5fr); align-items: end; gap: 40px;
  padding: 22px 0 42px; border-bottom: 1px solid var(--line);
}
.kicker, .eyebrow { margin: 0 0 8px; color: var(--accent); font: 700 10px/1.4 var(--num); font-variant-numeric: tabular-nums; letter-spacing: .14em; text-transform: uppercase; }
.hero h1 { margin: 0; max-width: 900px; word-break: keep-all; overflow-wrap: break-word; font-size: clamp(38px, 6.2vw, 84px); line-height: .96; letter-spacing: -.065em; font-weight: 760; }
.hero-copy { max-width: 720px; margin: 22px 0 0; color: var(--muted); font-size: 15px; }
.hero-meta { justify-self: end; min-width: 220px; padding-left: 20px; border-left: 1px solid var(--line); color: var(--muted); font-size: 11px; }
.hero-meta > span, .hero-meta > strong { display: block; }
.hero-meta strong { margin: 4px 0 12px; color: var(--ink); font: 650 13px/1.3 var(--num); font-variant-numeric: tabular-nums; }
.refresh-button { min-height: 34px; cursor: pointer; font-weight: 700;}
.refresh-button[aria-busy="true"] span:first-child { display: inline-block; animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.overview { padding: 44px 0 24px; }
.section-heading { display: flex; align-items: center; gap: 12px; margin: 0 0 15px; }
.section-heading.compact { margin-bottom: 22px; }
.section-index { width: 30px; height: 24px; flex: 0 0 30px; display: grid; place-items: center; border-radius: var(--r-sm); background: var(--panel-2); border: 1px solid var(--line); color: var(--faint); font: 650 10px/1 var(--num); font-variant-numeric: tabular-nums; }
/* 구역 제목은 어느 코드가 그렸든 같은 단이다.
 *
 * `/us` 실측: 위 열 구역은 `<header><h2>`로 22px, 15175px 아래부터는 이 규칙이
 * 그린 17px이었다. 스크롤하면 구역 제목이 이유 없이 작아진다 — 읽는 사람은
 * 어느 코드 경로가 그렸는지 모른다. 눈썹이 위에 붙는다고 표제가 내려갈
 * 이유도 없다. `tokens.css`의 `h2`(22)와 맞춘다. */
.section-heading h2 { margin: 0; font-size: var(--fs-xl); line-height: 1.2; letter-spacing: -.025em; }
.section-heading .eyebrow { margin-bottom: 3px; }
.source-pill { margin-left: auto; padding: 5px 7px; border: 1px solid var(--line); border-radius: var(--r-sm); color: var(--faint); font: 9px/1 var(--num); font-variant-numeric: tabular-nums; text-transform: uppercase; }
.overview-groups { display: grid; gap: 22px; }
/* 무리 표제 — 커질 수 없는 자리에서는 괘선이 표제임을 말한다.
 *
 * 넷 다 12px에서 12px 글을 이끌고 있었다(실측 계단 1.00 · `.ixr-sub`는 굵기
 * 650 하나가 유일한 차이였다). 12px에서 굵기 50은 표제로 안 읽힌다. 크기를
 * 올리지 않는 이유는 밀도가 이 제품의 성격이고 12px이 `tokens.css`에 적어 둔
 * 라벨 하한선이기 때문이다. `.overview-group h3`가 이미 갖고 있던 처리 —
 * 제목 뒤로 줄 끝까지 뻗는 1px 괘선 — 를 이름 붙여 나머지 셋에 준다. */
.overview-group h3,
.ixr-sub,
.kridx-group,
.cvol-card h3,
.cboard-card h3 {
  display: flex; align-items: center; gap: 8px;
  color: var(--muted);
  font: 650 var(--fs-xs)/1.2 var(--sans, system-ui);
  letter-spacing: .04em;
}
.overview-group h3::after,
.ixr-sub::after,
.kridx-group::after,
.cvol-card h3::after,
.cboard-card h3::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.overview-group h3 { margin: 0 0 9px; }
.summary-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
/* 카드 바닥의 출처 줄은 **흐름 안에서** 바닥에 붙는다.
 *
 * `position: absolute; bottom: 11px`이었다. 그러면 위쪽 내용이 길어져도
 * 자리를 비켜 주지 않는다 — 실측(2026-08-30, /monitor 412px): 변화율 줄이
 * 723~740, 출처 줄이 733~761로 **7px 겹쳤다.** 세 카드가 그랬다. 값이 조금만
 * 더 길어지면 겹침도 그만큼 커진다.
 *
 * 세로 flex로 두고 `margin-top: auto`로 밀면 같은 자리에 서면서 위쪽 내용의
 * 높이를 존중한다. 격자 안 카드 높이도 그대로 맞는다. */
.summary-card {
  position: relative; min-height: 128px; padding: 15px 16px 13px; overflow: hidden;
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: var(--r-md); background: linear-gradient(145deg, var(--panel), var(--panel-2));
}
.summary-card::before { content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 2px; background: var(--card-accent, var(--accent)); opacity: .8; }
.summary-card.stale { border-color: color-mix(in srgb, var(--amber) 35%, var(--line)); }
.summary-card.unavailable { background: repeating-linear-gradient(-45deg, var(--panel), var(--panel) 9px, var(--panel-2) 9px, var(--panel-2) 10px); }
.summary-label { color: var(--card-accent, var(--accent)); font: 680 10px/1.25 var(--num); font-variant-numeric: tabular-nums; text-transform: uppercase; letter-spacing: .05em; }
.summary-value { margin-top: 13px; font: 760 clamp(20px, 2vw, 27px)/1 var(--num); font-variant-numeric: tabular-nums; letter-spacing: -.03em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.summary-change { min-height: 17px; margin-top: 7px; color: var(--muted); font: 650 10px/1.3 var(--num); font-variant-numeric: tabular-nums; }
.summary-change.up { color: var(--up); }
.summary-change.down { color: var(--down); }
.summary-meta { margin-top: auto; padding-top: 8px; border-top: 1px solid var(--line); color: var(--faint); font-size: 9.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.jump-nav {
  position: sticky; top: 62px; z-index: 50; display: flex; gap: var(--sp-1h); margin: 16px 0 44px; padding: 9px;
  overflow-x: auto; scrollbar-width: none; border: 1px solid var(--line); border-radius: var(--r-md);
  background: color-mix(in srgb, var(--bg) 92%, transparent); backdrop-filter: blur(10px);
}
.weekend-pulse { margin: 8px 0 36px; padding: 22px 0 28px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.risk-strip { display: flex; flex-wrap: wrap;}
.weekend-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
/* 요약 카드는 한 줄을 통째로 쓴다.
 *
 * 카드가 일곱이면 3열에서 3+3+1이라 마지막 줄에 한 장만 남는다(운영자 지적
 * 2026-08-31). **순서를 바꾸는 것으로는 안 고쳐진다** — 혼자 남는 카드가
 * 바뀔 뿐이다. 요약을 한 줄로 펼치면 남는 여섯이 3+3(3열)·2+2+2(2열)로
 * 정확히 떨어지고, 요약이 개별 값보다 먼저 읽힌다.
 *
 * 개별 카드가 여섯이 아니게 되면 이 규칙만으로는 다시 남는다 — 그때는
 * 개수를 6의 배수로 맞춘다(`/crypto` 카드·김프와 같은 규칙). */
.weekend-card.summary { grid-column: 1 / -1; }
.weekend-card { min-height: 150px; padding: 15px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); }
.weekend-card.proxy { border-color: color-mix(in srgb, var(--violet) 28%, var(--line)); }
.weekend-card.unavailable { background: repeating-linear-gradient(-45deg, var(--panel), var(--panel) 9px, var(--panel-2) 9px, var(--panel-2) 10px); }
.weekend-card header { display: flex; align-items: flex-start; justify-content: space-between; gap: 7px; }
.weekend-badges { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 4px; }
.weekend-card h3 { margin: 0; font-size: 12px; }
.weekend-symbol { color: var(--faint); font: 8.5px/1 var(--num); font-variant-numeric: tabular-nums; }
.weekend-value { margin: 18px 0 7px; font: 750 22px/1 var(--num); font-variant-numeric: tabular-nums; letter-spacing: -.03em; }
.weekend-change { color: var(--muted); font: 700 10px/1.2 var(--num); font-variant-numeric: tabular-nums; }
.weekend-change.up { color: var(--up); }
.weekend-change.down { color: var(--down); }
.weekend-meta { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; margin-top: 14px; padding-top: 9px; border-top: 1px solid var(--line); color: var(--faint); font: 8.5px/1.35 var(--num); font-variant-numeric: tabular-nums; }
.weekend-meta strong { display: block; margin-top: 2px; color: var(--muted); font-size: 9px; }
.weekend-disclaimer { margin: 11px 0 0 42px;}
.jump-nav::-webkit-scrollbar { display: none; }
.jump-nav a { flex: 0 0 auto; padding: var(--sp-1h) 9px; border-radius: var(--r-sm); text-decoration: none; color: var(--muted); font: 650 10px/1 var(--num); font-variant-numeric: tabular-nums; }
.jump-nav a:hover { color: var(--ink); background: var(--panel-2); }

.dashboard-section { margin: 0 0 52px; scroll-margin-top: 118px; }
/* 상한이 **자식 결합자 아래**에 있었다. 같은 클래스가 같은 페이지에서 780px로
   서기도 하고 1288px(144ch)로 서기도 했다 — `/us`에서 열은 갇히고 여덟은 풀려
   있었다. 상한은 클래스 자신에게 주고, 들여쓰기만 옛 래퍼 아래에 남긴다. */
.section-copy { max-width: none; }
.dashboard-section > .section-copy { margin: calc(-1 * var(--sp-1h)) 0 15px 42px; color: var(--muted); font-size: 12px; }
.panel { border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); box-shadow: var(--shadow); }
.metric-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
/* 홀수로 끝나면 마지막 칸 옆에 **631.5 × 473.9px**(격자 폭의 49%) 빈자리가
   남는다(실측 1440px: `#macro-regime` 7장, `#funding` 3장, `/kr` 3장). 고아를
   한 줄 전체로 늘려 그 구멍을 없앤다 — 운영자가 두 번 지적한 그 문제다. */
.metric-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
.metric-grid.one { grid-template-columns: 1fr; }
.metric-card { min-width: 0; min-height: 360px; padding: 20px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); box-shadow: var(--shadow); }
.metric-card > header { display: flex; justify-content: space-between; gap: 16px; min-height: 42px; }
/* 이 줄은 시리즈 식별자를 담아 자주 두 줄이 된다("RIFLGFCY10_N.B - …").
   12px 바닥으로 올라간 뒤에도 행간은 1.2 그대로라 두 줄이 붙었다. */
.metric-kicker { margin: 0 0 4px; color: var(--faint); font: 9px/1.45 var(--num); font-variant-numeric: tabular-nums; letter-spacing: .08em; text-transform: uppercase; }
.metric-card h3 { margin: 0; font-size: 15px; line-height: 1.25; letter-spacing: -.02em; }
.badge-row { display: flex; flex-wrap: wrap; justify-content: flex-end; align-content: flex-start; gap: 4px; }
.status-badge { display: inline-flex; align-items: center; font-variant-numeric: tabular-nums;}
.status-badge.fresh { border-color: color-mix(in srgb, var(--green) 38%, var(--line));}
.status-badge.stale, .status-badge.warn { border-color: color-mix(in srgb, var(--amber) 38%, var(--line));}
.status-badge.error { border-color: color-mix(in srgb, var(--red) 38%, var(--line));}
.status-badge.info { border-color: color-mix(in srgb, var(--accent) 38%, var(--line));}
.metric-primary { display: flex; align-items: baseline; gap: var(--sp-1h); margin-top: 18px; }
.metric-primary strong { font: 780 clamp(28px, 3.2vw, 44px)/1 var(--num); font-variant-numeric: tabular-nums; letter-spacing: -.03em; }
.metric-unit { color: var(--faint); font: 10px/1 var(--num); font-variant-numeric: tabular-nums; }
.metric-change { min-height: 20px; margin-top: 8px; color: var(--muted); font: 650 10px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.metric-change.up { color: var(--up); }
.metric-change.down { color: var(--down); }
.chart-slot { width: 100%; height: 145px; margin: 15px 0 12px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.chart-slot svg { display: block; width: 100%; height: 100%; overflow: visible; }
.chart-slot .grid { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.chart-slot .zero { stroke: var(--faint); stroke-width: 1; stroke-dasharray: 3 4; vector-effect: non-scaling-stroke; }
.chart-slot .area { fill: var(--chart-fill); }
.chart-slot .line { fill: none; stroke: var(--chart); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.chart-slot .dot { fill: var(--chart); stroke: var(--panel); stroke-width: 2; vector-effect: non-scaling-stroke; }
.chart-slot .chart-empty { display: grid; height: 100%; place-items: center; color: var(--faint); font-size: 11px; }
.metric-description { min-height: 38px; margin: 0; color: var(--muted); font-size: var(--fs-sm); }
/* 우리가 계산한 한 줄 — 원 수치와 같은 카드에 있으므로 출처가 갈린다는 것을
   문구 자체가 말한다(EIA API 약관). 12px 아래로 내리면 typography 바닥에 걸린다. */
.metric-note { margin: var(--sp-1h) 0 0; color: var(--muted); font-size: 12px; line-height: 1.45; }
/* **칩 하나가 줄 하나다.** `flex-wrap: wrap`이던 때는 문장 길이가 줄 수를
   정했고, 같은 줄 두 카드에서 둘째 칩이 한쪽만 아래로 밀렸다(자 실측
   2026-09-08, `/us` 1440px: 칩1이 329px인 카드는 둘째가 2행, 286px인 카드는
   1행 — 36.8px). 알약 폭은 그대로다(`justify-self: start`). */
.metric-hints {
  display: grid; grid-template-columns: minmax(0, 1fr);
  row-gap: var(--sp-1h); min-height: 24px; margin-top: 10px;
}
.metric-hints > .hint-chip { justify-self: start; }
/* 좌우 7px은 이 칩의 글자(12px)에 대해 좁다 — `/us` 라이브 스캔에서 같은
   칩이 37번 걸렸다. 8px은 눈금 위의 값이고 세로 5px과도 비가 맞는다. */
.hint-chip { padding: 5px var(--sp-2); border: 1px solid transparent; border-radius: var(--r-sm); background: var(--panel-2); color: var(--muted); font: 9px/1.35 var(--num); font-variant-numeric: tabular-nums; }
.metric-card > footer { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; min-height: 27px; margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--line); color: var(--faint); font: 9px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.metric-card > footer a { color: var(--accent); text-decoration: none; }
.metric-card.unavailable { background: repeating-linear-gradient(-45deg, var(--panel), var(--panel) 9px, var(--panel-2) 9px, var(--panel-2) 10px); }
.metric-card.unavailable .metric-primary strong { color: var(--faint); }

/* ── 같은 줄의 카드는 같은 자리에서 같은 높이로 선다 ──────────────────────
 *
 * 실측 1440px `/us`: 같은 줄 카드의 머리가 44↔49, 설명이 38↔88, 힌트가 24↔68,
 * 바닥이 31↔37이었다. 머리의 5px이 아래 여섯 조각을 통째로 밀고, 설명의 50px이
 * 바닥을 81px까지 어긋나게 했다 — 큰 숫자 두 개가 서로 다른 높이에 서 있으면
 * 그것만으로 화면이 고장난 것처럼 보인다(운영자 2026-09-07: "한쪽은 올라가있고").
 *
 * 조각마다 `min-height`를 박아 두었지만(42·38·24·27) 내용이 그 바닥을 넘는
 * 순간 소용이 없다. **어느 값이 올지 모르므로 바닥으로는 못 고친다.**
 *
 * subgrid는 같은 줄의 카드가 부모의 줄 트랙을 함께 쓰게 한다. 트랙 높이는 그
 * 줄에서 가장 큰 것이 정하고 나머지가 따라간다 — 길이를 미리 알 필요가 없다.
 *
 * 자리를 **이름으로** 못 박는다. `p.metric-note`는 어떤 카드에만 있는데,
 * 자동 배치에 맡기면 그 카드만 아래가 한 칸씩 밀린다. 없는 카드는 그 트랙을
 * 비워 두는 편이 맞다.
 *
 * `row-gap: 0`이 필요한 이유: subgrid는 부모의 `gap: 9px`를 트랙마다 물려받아
 * 카드 하나가 63px 자란다. 조각 사이의 숨은 원래대로 각 조각의 `margin`이 만든다.
 *
 * subgrid를 모르는 브라우저는 이 블록을 통째로 건너뛰고 지금처럼 블록으로
 * 쌓인다 — 못 맞추는 것이지 깨지는 것이 아니다. */
@supports (grid-template-rows: subgrid) {
  .metric-card {
    display: grid;
    grid-template-rows: subgrid;
    /* 8 → 10. 힌트 상자가 한 줄이 아니라 **세 줄**을 쓴다(아래 참조). */
    grid-row: span 10;
    row-gap: 0;
  }
  .metric-card > header { grid-row: 1; }
  .metric-card > .metric-primary { grid-row: 2; }
  .metric-card > .metric-change { grid-row: 3; }
  .metric-card > .chart-slot { grid-row: 4; }
  .metric-card > .metric-description { grid-row: 5; }
  .metric-card > .metric-note { grid-row: 6; }
  .metric-card > .metric-hints { grid-row: 7 / span 3; }
  .metric-card > footer { grid-row: 10; }

  /* ── 힌트 상자도 줄을 나눠 쓴다 ────────────────────────────────────────
   *
   * 카드 밖은 이미 맞아 있었다 — 상자끼리는 같은 y에 선다. 어긋나는 것은
   * **그 안**이었다. 상자를 subgrid로 만들면 칩 i가 그 줄 트랙 i에 앉으므로,
   * 앞 칩이 몇 줄로 접히든 뒤 칩의 y가 안 흔들린다.
   *
   * 셋인 이유는 데이터가 최대 셋이기 때문이다(1개:12 · 2개:19 · 3개:3).
   * 자리는 **번호로 못 박는다** — 자동 배치에 맡기면 칩이 하나뿐인 카드에서
   * 다음 조각이 위로 올라와 다시 어긋난다(오늘 `.usm-note`가 그랬다). */
  .metric-card > .metric-hints { grid-template-rows: subgrid; }
  .metric-hints > .hint-chip:nth-child(1) { grid-row: 1; }
  .metric-hints > .hint-chip:nth-child(2) { grid-row: 2; }
  .metric-hints > .hint-chip:nth-child(3) { grid-row: 3; }
  /* 한 줄짜리 격자(`.metric-grid.one`)와 홀수 고아는 견줄 상대가 없다. 트랙을
     나눠 쓸 이유가 없고, 나눠 쓰면 빈 `metric-note` 트랙만 남는다. */
  .metric-grid.one > .metric-card,
  .metric-grid > :last-child:nth-child(odd) { grid-row: auto / span 10; }
}

.comparison-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
.comparison-card { padding: 18px; min-height: 250px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); }
.comparison-card h3 { margin: 0; font-size: var(--fs-md); }
.comparison-card p { margin: 5px 0 14px; color: var(--muted); font-size: 11px; }
.comparison-chart { height: 150px; }
.comparison-chart svg { width: 100%; height: 100%; }
.comparison-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; color: var(--muted); font: 9px/1 var(--num); font-variant-numeric: tabular-nums; }
.comparison-legend i { display: inline-block; width: 12px; height: 2px; margin-right: 5px; vertical-align: middle; background: var(--accent); }
.comparison-legend span:nth-child(2) i { background: var(--violet); }

/* 기간·정렬 토글 — 띠를 걷고 밑줄로 (2026-09-07).
 *
 * 운영자가 두 번 짚었다: 표 위의 이 바가 "성의 없어 보인다"(09-07 오전),
 * 그리고 히트맵의 1D·1W·1M·1Y가 "디자인도 너무 올드해"(09-07 저녁). 같은
 * 부품이라 한 번에 고친다.
 *
 * 낡아 보이던 것의 정체는 셋이다.
 *   ① 크롬이 두 겹이었다 — 1px 테두리 **와** 채운 면(`--panel-2`)이 같이 있고,
 *     그 안에 또 칸마다 면이 든다.
 *   ② 선택된 칸이 **꽉 찬 파란 사각형**이다. 폰에서 이 바는 전폭 52px 블록이라
 *     화면의 4분의 1이 통째로 파랗게 칠해진다(실측 390px: 86×44px). 이 세계에서
 *     파랑은 "동작"이지 "지금 보고 있는 것"이 아니고, 저 크기의 채움은 iOS 6·
 *     Material 2의 세그먼티드 컨트롤 그대로다.
 *   ③ 그래서 값보다 컨트롤이 무겁다. 이 바 아래에 오는 것은 표이고, 표가 주인공이다.
 *
 * 답은 이미 이 제품 안에 있었다 — 데스크톱 페이지 탭(`.view-tab.active`)이
 * 쓰는 **밑줄**이다. 띠도 채움도 없이 지금 자리를 말한다. 같은 문법을 쓰면
 * 화면에서 "고르는 것"의 생김새가 하나로 모인다.
 *
 * 굵기는 상태에 따라 **바꾸지 않는다.** 토스는 선택된 칸을 굵게 하지만, 그러면
 * 글자 폭이 늘어 옆 칸들이 밀리고 밑줄이 튄다 — 네 칸짜리 줄에서는 누를 때마다
 * 줄이 흔들린다. 색(`--ink-3` → `--ink`)과 2px 밑줄이면 충분하다. */
.segmented {
  margin-left: auto; display: inline-flex; align-items: stretch; gap: var(--sp-4);
  padding: 0; border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
  background: transparent;
}
.segmented button { position: relative; min-width: 0; min-height: 29px; padding: 0 2px 7px; cursor: pointer; color: var(--ink-3); border: 0; border-radius: 0; background: transparent; font: 650 var(--fs-sm)/1.2 var(--num); font-variant-numeric: tabular-nums; letter-spacing: -.01em; transition: color .15s; }
/* 밑줄은 칸의 아래끝이 아니라 **띠 위**에 앉는다(`bottom: -1px`) — 1px 선을
   덮어야 두 줄로 보이지 않는다. 늘 자리를 잡아 두고 색만 켠다: 나중에 만들면
   켜지는 순간 칸 높이가 1px 움직인다. */
.segmented button::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: transparent; }
.segmented button:hover { color: var(--ink); }
.segmented button.active { color: var(--ink); }
.segmented button.active::after { background: var(--accent); }
.sector-panel { padding: 18px; }
.sector-bars { display: grid; gap: 9px; min-height: 310px; padding: 15px 5px; }
.sector-row { display: grid; grid-template-columns: minmax(120px, .55fr) minmax(240px, 2fr) 70px; align-items: center; gap: 12px; }
.sector-name { color: var(--muted); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sector-name code { margin-left: 5px; color: var(--faint); font: 9px/1 var(--num); font-variant-numeric: tabular-nums; }
.bar-track { position: relative; height: 18px; }
.bar-track::before { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: var(--line-strong); }
.bar-fill { position: absolute; top: 2px; height: 14px; min-width: 1px; border-radius: var(--r-sm); }
.bar-fill.up { left: 50%; background: var(--up); }
.bar-fill.down { right: 50%; background: var(--down); }
.sector-value { text-align: right; font: 700 10px/1 var(--num); font-variant-numeric: tabular-nums; }
.sector-value.up { color: var(--up); }
.sector-value.down { color: var(--down); }

/* 값이 없을 때 서는 자리. 셋을 구별해서 말한다 — 아직 안 왔다 · 실패했다 ·
   꺼져 있다. 테두리를 여기서 준다: `.disabled`가 `border-color`만 바꾸는데
   테두리가 없는 블록에서는 그 줄이 아무 일도 하지 않았다(실측 2026-08-30,
   /us `#stress-state` `border-width: 0`). 그래서 같은 상태가 어떤 자리에선
   상자로, 어떤 자리에선 맨 글자로 보였다. */
.state-block {
  min-height: 132px; display: grid; place-items: center; padding: var(--sp-4);
  border: 1px solid var(--line); border-radius: var(--r-md);
  color: var(--faint); text-align: center; font-size: var(--fs-xs);
}
/* 빠른 응답에서는 "불러오는 중"을 아예 보여 주지 않는다.
 *
 * 탭을 옮길 때마다 0.1초쯤 떴다 사라지는 것이 거슬린다는 지적(운영자 2026-09-02).
 * API가 대개 0.03~0.3초에 오므로 글자가 뜨자마자 지워지고, 그 깜빡임이 느리다는
 * 인상을 준다 — 실제로는 빠른데도.
 *
 * 그래서 **0.4초 동안 투명하게** 둔다. 그 안에 값이 오면 아무것도 안 보이고,
 * 정말 오래 걸릴 때만 나타난다. 자리는 계속 차지하므로 값이 들어와도 화면이
 * 튀지 않는다. `role="status"`는 그대로라 스크린리더에는 바로 읽힌다. */
.state-block { opacity: 0; animation: state-block-in 140ms 400ms forwards; }
@keyframes state-block-in { to { opacity: 1; } }
/* 움직임을 줄이기로 한 사람에게는 지연만 남기고 페이드를 없앤다. */
@media (prefers-reduced-motion: reduce) {
  .state-block { animation-duration: 0s; }
}
/* 잠긴 lane 안내처럼 **계속 있을 글**은 기다리게 할 이유가 없다. */
.state-block.disabled { opacity: 1; animation: none; }

.state-block.disabled { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 35%, var(--line)); background: color-mix(in srgb, var(--amber) 5%, var(--panel)); }
/* 기호는 글자와 같은 줄에 선다. 색은 `currentColor`라 상태 색을 그대로 따른다. */
.state-block { gap: var(--sp-2); }
.state-block .ico { width: 18px; height: 18px; opacity: .85; }
.state-block[data-state="failed"] { color: var(--red); border-color: color-mix(in srgb, var(--red) 30%, var(--line)); }
/* 기다리는 중에는 기호가 돈다 — 값이 오는 중이라는 말을 글자보다 먼저 한다.
   움직임을 끈 사람에게는 돌지 않는다(그래도 기호는 남는다). */
.state-block[data-state="waiting"] .ico { animation: ico-spin 1.6s linear infinite; }
@keyframes ico-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .state-block[data-state="waiting"] .ico { animation: none; }
}

/* 기호의 기본 — 글자 크기를 따라가고 색을 물려받는다(DESIGN.md §3).
 * 아이콘에 색을 박으면 다크 테마의 상태 색과 어긋난다. */
.ico {
  width: 1em; height: 1em; flex: 0 0 auto;
  vertical-align: -.125em; color: inherit;
}
.state-block.loading::after { content: ""; width: 22px; height: 2px; margin-left: 8px; background: var(--accent); animation: pulse 1s ease-in-out infinite alternate; }
@keyframes pulse { to { width: 72px; opacity: .3; } }
.panel-footer { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; min-height: 38px; padding: 10px 0 0; border-top: 1px solid var(--line); color: var(--faint); font: 9px/1.45 var(--num); font-variant-numeric: tabular-nums; }
.panel-footer a { color: var(--accent); text-decoration: none; }
.interpretation-note { margin: 10px 0 0; padding: 10px 12px; border-left: 2px solid var(--accent); background: var(--panel-2); color: var(--muted); font-size: 10.5px; }
/* 넓은 표는 가로로 흐른다. 그런데 흐른다는 표시가 전혀 없어서, 폰에서는
 * 마지막 열이 "낮을수록 스트"처럼 말 중간에 잘린 채 서 있었다 — 스크롤바는
 * 손대는 동안에만 나타나므로 읽는 사람에게는 그냥 깨진 글자다
 * (실측 2026-08-30, /us 412px 스트레스·심리 표).
 *
 * 오른쪽 가장자리에 잔금과 옅은 빛으로 말한다. 두 겹이다: 표시는 컨테이너에
 * 붙어 있고(scroll), 덮개는 내용과 함께 움직인다(local). 끝까지 밀면 덮개가
 * 표시 위에 와서 스스로 꺼지고, 넘칠 것이 없는 표에서는 처음부터 덮여 있다 —
 * 켜고 끄는 자바스크립트가 필요 없다.
 *
 * 빛으로 긋는다. 처음엔 검은 그늘을 썼는데 패널이 이미 거의 검어서 화면에서
 * 아무것도 안 보였다(실측). 어두운 바탕에서 읽히는 건 그늘이 아니라 빛이다.
 *
 * 왼쪽은 이미 첫 열이 sticky로 붙어 있어 그 자체가 표시다.
 * `--scroll-ground`는 이 표가 앉은 바닥색이다. 패널 밖에 두는 표가 생기면
 * 그 자리에서 덮개 색을 다시 준다 — 안 맞추면 그늘이 안 꺼진다. */
.table-scroll {
  --scroll-ground: var(--panel);
  /* **상자가 표를 감싼다** (운영자 제보 2026-09-06, 데스크톱).
   *
   * `width: 100%`만 두면 좁은 표가 넓은 상자 안에 떠 있는다 — 실측
   * `/stock/005930` 1690px 화면에서 상자 1,288px에 표는 **463px·427px**(36%)였다.
   * 남은 800px은 빈 자리가 아니라 **오른쪽 스크롤 표시가 서는 자리**여서,
   * 표에서 한참 떨어진 곳에 선과 그늘이 떠 "표가 잘려 이어진다"로 읽혔다.
   *
   * `min(100%, max-content)`이면 좁은 표는 제 폭을 갖고 넓은 표는 그대로 흐른다.
   * 폰에서 표가 상자보다 넓은 경우(620 대 368)는 아무것도 안 바뀐다. */
  width: 100%; max-width: max-content; overflow-x: auto;
  background:
    linear-gradient(270deg, var(--scroll-ground) 55%, transparent) right center / 26px 100% no-repeat local,
    linear-gradient(270deg, var(--line-strong) 0 1px, transparent 1px) right center / 100% 100% no-repeat scroll,
    linear-gradient(270deg, rgba(255, 255, 255, .1), transparent) right center / 24px 100% no-repeat scroll;
}
/* 위 주석이 예고한 사고가 실제로 났다 — "패널 밖에 두는 표가 생기면 그 자리에서
   덮개 색을 다시 준다. 안 맞추면 그늘이 안 꺼진다."
   종목 페이지의 표 셋은 `.panel` 안이 아니라 `.stock-section`에 맨몸으로 선다.
   그런데 덮개는 `--panel`(#0d1420)을 칠하고 실제 지면은 `--bg`(#070b12)라,
   가리기는커녕 오른쪽 끝에 **지면보다 밝은 26px 블록**을 그렸다(실측 2026-09-06).
   패널 밖의 표는 지면색으로 덮는다. */
/* **`:not(.panel) >`는 쓰면 안 됐다** (2026-09-06, 내가 만든 회귀를 되돌린다).
   그 선택자는 직계 부모만 본다. 그런데 표는 대개 패널 안 한 겹 더 들어간
   자리에 선다 — `/kr`의 `#kridx-body > .table-scroll`이 그렇다. 패널 안인데도
   걸려서 덮개가 지면색(`--bg`, 더 어두움)을 패널 위에 칠했고, 운영자가 본
   "거래대금 오른쪽의 검은 그림자"가 그것이다.
   CSS로 "패널 안이 아님"은 조상 검사라 표현할 수 없다. 표현할 수 없는 것을
   선택자로 흉내 내는 대신, 실제로 패널 밖인 자리만 이름으로 적는다. */
.stock-section .table-scroll { --scroll-ground: var(--bg); }

/* 표가 판의 둥근 모서리를 **뚫고 나오던 것** (운영자 제보 2026-09-07:
   "테이블 오른쪽 왼쪽 상단이 사각형 꼭짓점이 뚫고나와서 뾰족한 느낌이야").

   머리 칸(`th`)은 세로로 붙어 다녀야 해서 `position: sticky`에 **불투명한 면**을
   깔고 있다(실측 라이브 `/kr`: `background: rgb(13,20,32)` · `z-index: 1`).
   그 면은 사각형인데 판은 `border-radius: 16px`에 `overflow: visible`이라,
   머리 칸이 판의 곡선 위를 덮어 모서리가 각지게 보인다.

   판을 `overflow: hidden`으로 막으면 안 된다 — 그 순간 판이 스크롤 컨테이너가
   되어 머리 칸이 페이지가 아니라 판에 들러붙고, 판은 표만큼만 높아서 **붙는
   기능 자체가 사라진다.**

   자르는 일은 이미 자르고 있는 쪽에 맡긴다. `.table-scroll`은 `overflow-x:
   auto`라 두 축을 모두 자르는 상자다 — 위 두 모서리만 둥글게 하면 머리 칸이
   그 곡선에 맞춰 잘린다. 아래 두 모서리는 각진 채로 둔다: 그 아래는 푸터가
   덮고 있어 둥글게 하면 마지막 줄만 깎인다.

   `- 1px`은 판의 테두리다. 표는 그 안쪽에서 시작하므로 곡선도 한 겹 안쪽이다. */
.panel > .table-scroll:first-child,
/* **숨은 상태 칸 뒤도 처음이다.** `:first-child`는 DOM 순서를 보는데, 상태 칸은
   값이 오면 `hidden`이 될 뿐 사라지지 않는다. 그래서 표 앞에 상태 칸을 둔 판만
   이 규칙에서 빠져 각진 꼭짓점이 남아 있었다(자 실측: `/crypto` `#cderiv-wrap`).
   `+`는 바로 뒤 하나만 잡으므로, 판 중간의 다른 표까지 깎지 않는다. */
.panel > .state-block[hidden] + .table-scroll {
  border-top-left-radius: calc(var(--r-md) - 1px);
  border-top-right-radius: calc(var(--r-md) - 1px);
}
/* 상태 칸이 처음 설 때도 판 모서리에 닿는다. 자기 반경(`--r-md`)을 그대로 쓰면
   판의 안쪽 곡선(`--r-md - 1px`)보다 작아서 꼭짓점이 곡선 밖으로 나온다 —
   실측 `/us` `#dcc-state`: 판 안쪽 15 · 자식 10.

   네 모서리를 다 준다. 값이 오면 이 칸은 숨으므로, 아래 모서리가 보이는 때는
   "이것만 서 있는" 순간뿐이고 그때는 아래도 판의 모서리다. */
.panel > .state-block:first-child { border-radius: calc(var(--r-md) - 1px); }

/* ===== FOMC 점도표 =========================================================
 * 점 하나가 위원 한 사람이다. 같은 금리에 여러 명이면 가로로 흩어 놓는다 —
 * 겹쳐 찍으면 8명과 1명이 같아 보이고, 그 수가 이 그림의 전부다. */
/* viewBox 폭(520)을 min-width와 같게 잡는 것이 요점이다. SVG 안의 글자는
 * user unit이라 그림이 줄면 같이 줄어드는데, 폰에서 12px 라벨이 7px로
 * 렌더되면 typography 테스트는 통과하면서 화면에서만 안 읽힌다. 좁으면
 * 줄이지 말고 `.table-scroll` 안에서 가로로 흐르게 둔다(넓은 표와 같은 방식).
 * 위로도 660에서 멈춘다 — 안 막으면 데스크톱에서 높이가 650px을 넘는다. */
.dotplot { width: 100%; min-width: 520px; max-width: 660px; height: auto; display: block; margin: 0 auto; }
.dotplot .dp-grid { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.dotplot .dp-dot { fill: var(--accent); fill-opacity: .85; }
.dotplot .dp-median { stroke: var(--ink); stroke-width: 2; vector-effect: non-scaling-stroke; }
.dotplot .dp-axis { fill: var(--faint); font: 600 var(--fs-xs)/1 var(--num); font-variant-numeric: tabular-nums; }
.dotplot .dp-year { fill: var(--muted); font: 650 var(--fs-xs)/1 var(--num); font-variant-numeric: tabular-nums; }
.dp-legend { display: flex; gap: 14px; flex-wrap: wrap; margin: 8px 0 0; color: var(--faint); font-size: var(--fs-xs); }
.dp-legend i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); margin-right: 5px; }
.dp-legend b { display: inline-block; width: 10px; height: 2px; background: var(--ink); margin-right: 5px; vertical-align: middle; }
.dots-summary, .rx-summary {
  display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 8px 14px;
  margin: 0 0 var(--sp-4); padding: 15px 18px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--panel-2);
}
.dots-summary span, .rx-summary span { color: var(--muted); font-size: var(--fs-xs); font-weight: 700; }
.dots-summary strong, .rx-summary strong { color: var(--ink); font: 750 21px/1.1 var(--num); font-variant-numeric: tabular-nums; }
.dots-summary small, .rx-summary small { color: var(--accent-text); font-size: var(--fs-xs); font-weight: 700; }

/* ===== 시장 금리 기대 =======================================================
 * 막대 하나가 목표범위 한 칸이고, 길이가 그 칸에 실린 확률이다. 점도표가 점의
 * 개수로 말한다면 이쪽은 길이로 말한다 — 같은 화면에 두 문법을 두는 것이
 * 의도다. 하나는 위원 전망이고 하나는 시장 쪽 답이라 섞이면 안 된다.
 *
 * 색은 가장 높은 칸에만 준다. 열 칸을 같은 채도로 칠하면 "어디가 유력한가"가
 * 사라지는데, 이 카드를 여는 이유가 그 한 칸이다. */
.rx-horizon + .rx-horizon {
  margin-top: var(--sp-4); padding-top: var(--sp-4); border-top: 1px solid var(--line);
}
.rx-head {
  display: flex; align-items: baseline; gap: var(--sp-2); margin: 0 0 var(--sp-2);
  color: var(--ink); font: 650 var(--fs-sm)/1.3 var(--sans);
}
.rx-n {
  margin-left: auto; color: var(--faint);
  font: 600 var(--fs-xs)/1 var(--num); font-variant-numeric: tabular-nums;
}
.rx-dist { display: grid; gap: var(--sp-1h); margin: 0; padding: 0; list-style: none; }
/* 라벨과 값은 글자폭만큼만 먹고 나머지를 막대가 가진다. 360px에서 라벨
 * "3.50–3.75%"(약 62px)와 값(약 26px)을 빼도 막대에 200px 넘게 남는다. */
.rx-row {
  display: grid; grid-template-columns: minmax(0, auto) 1fr minmax(0, auto);
  align-items: center; gap: var(--sp-2);
}
.rx-range, .rx-pct {
  color: var(--muted); font: 600 var(--fs-xs)/1.2 var(--num);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.rx-pct { min-width: 4ch; text-align: right; }
.rx-track { height: 10px; background: var(--line); border-radius: 2px; overflow: hidden; }
.rx-track i { display: block; height: 100%; background: var(--accent); opacity: .4; }
.rx-top .rx-track i { opacity: 1; }
.rx-top .rx-range, .rx-top .rx-pct { color: var(--ink); font-weight: 700; }
/* 각주는 flex다. 이 고지는 한 줄을 통째로 갖는다 — 앞의 두 조각(날짜·출처
 * 링크)과 같은 줄에 서면 길이가 제각각이라 줄이 삐뚤어 보인다(운영자 지적
 * 2026-09-06, 데스크톱 실측: 날짜 332.8 · 링크 118 · 이 문장 456.5가 한 줄). */
.rx-derived { flex-basis: 100%; margin: 0; color: var(--faint); font-size: var(--fs-xs); }

/* `.panel`은 테두리만 주고 여백은 안 준다 — 표를 담는 섹션은 셀 패딩이
 * 대신해 왔지만, 맨 텍스트를 담는 이 넷은 글자가 테두리에 붙는다. */
#fed-digest .panel, #fomc-statement .panel, #fomc-dots .panel,
#rate-expectations .panel { padding: var(--sp-4); }

/* 그리고 그 넷은 각주 여백을 **빼야** 한다.
 *
 * `.panel .panel-footer`는 판이 여백을 안 주는 것을 전제로 `--panel-inset`을
 * 스스로 얹는다(console.css). 위 네 섹션은 판이 이미 여백을 갖고 있어서 각주만
 * 두 번 먹었다 — 실측(2026-09-06, 1464px): 본문 104 · 각주 121로 17px 어긋나고,
 * 각주 위 구분선도 본문보다 짧게 시작했다. 네 섹션 모두 같은 증상이라 같이 편다. */
#fed-digest .panel > .panel-footer,
#fomc-statement .panel > .panel-footer,
#fomc-dots .panel > .panel-footer,
#rate-expectations .panel > .panel-footer { padding-left: 0; padding-right: 0; }

/* ===== 의장 발언 요약 ======================================================
 * 요약 한 줄 밑에 근거가 된 원문 문장이 붙는다. 인용을 접거나 숨기지 않는다 —
 * 대조할 수 없는 요약은 우리가 내놓지 않기로 한 것이라서, 근거는 요약과 같은
 * 화면에 있어야 한다. */
.digest-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.digest-list li { display: grid; grid-template-columns: 18px 1fr; gap: 10px; }
.digest-list .bullet { color: var(--accent); font: 650 13px/1.6 var(--num); font-variant-numeric: tabular-nums; text-align: center; }
.digest-ko { margin: 0; color: var(--ink); font-size: var(--fs-md); line-height: 1.65; }
.digest-quote {
  margin: var(--sp-1h) 0 0; padding: var(--sp-1h) 0 var(--sp-1h) 12px; border-left: 2px solid var(--line-strong);
  color: var(--faint); font-size: var(--fs-xs); line-height: 1.6;
}
/* 영어 모드의 위계 뒤집기. 클래스를 언어가 아니라 **역할**로 나눈다 — 앞에 오는
 * 줄이 크고, 뒤따르는 줄이 작다. 인용 표시(왼쪽 선)는 원문이 앞에 와도 유지한다.
 * 그것이 우리가 쓴 문장이 아니라 문서의 문장이라는 표시이기 때문이다. */
.digest-quote.is-lead { color: var(--ink); font-size: var(--fs-sm); line-height: 1.65; }
.digest-ko.is-aside { margin-top: var(--sp-1h); color: var(--faint); font-size: var(--fs-xs); line-height: 1.6; }

.digest-head { margin: 0 0 var(--sp-1h); color: var(--muted); font-size: var(--fs-sm); line-height: 1.6; }
/* "이게 최신이다" 한 줄. 제목 줄 바로 아래에 작게 — 값이 아니라 **날짜에 대한
   주석**이라 값과 같은 크기로 서면 안 된다. */
/* 줄의 몸 — 기호 옆 한 칸. 한국어와 원문이 이 안에서 위아래로 선다. */
.fomc-line { min-width: 0; flex: 1 1 auto; }
/* FOMC 성명의 한국어 — 원문 위에 선다. 의장 발언 요약과 같은 위계다:
   한국어가 뜻을 지고, 바로 아래 영어가 근거로 남는다. 영어 화면에는 안 선다. */
.fomc-ko {
  margin: 0 0 4px; color: var(--ink); font-size: var(--fs-sm); line-height: 1.6;
}
.digest-latest { margin: 0 0 14px; color: var(--ink-3); font-size: var(--fs-xs); line-height: 1.5; }
.digest-tag { display: inline-block; margin-right: 8px; padding: 2px 8px; border-radius: var(--r-pill);
  background: var(--accent-soft); color: var(--accent); font-size: var(--fs-xs); font-weight: 650; }
.digest-head a { color: var(--ink); text-decoration: none; font-weight: 550; }
.digest-head a:hover { color: var(--accent); text-decoration: underline; }
.digest-machine {
  margin: 0 0 14px; padding: 8px 12px; border-left: 2px solid var(--accent);
  background: var(--panel-2); color: var(--muted); font-size: var(--fs-xs); line-height: 1.6;
}

/* ===== FOMC 성명 변경점 =====================================================
 * 뺀 문장과 더한 문장을 나란히 둔다. 색만으로 구분하지 않는다(−/+ 기호를
 * 함께 쓴다) — 색을 못 보는 사람에게도 어느 쪽이 새 문장인지 보여야 한다. */
.fomc-head { display: flex; gap: 18px; flex-wrap: wrap; align-items: baseline; margin: 0 0 12px; }
.fomc-figure { display: flex; flex-direction: column; gap: 2px; }
.fomc-figure span { color: var(--faint); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em; }
.fomc-figure strong { color: var(--ink); font: 650 17px/1.2 var(--num); font-variant-numeric: tabular-nums; }
.fomc-figure em { color: var(--faint); font-style: normal; font-size: var(--fs-xs); }
.fomc-reading { margin: 16px 0; padding: 14px 0; border-block: 1px solid var(--line); }
.fomc-reading-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-1h) 12px; }
.fomc-reading-head strong { color: var(--ink); font-size: var(--fs-sm); }
.fomc-reading-head span { color: var(--accent-text); font-size: var(--fs-xs); font-weight: 750; }
.fomc-reading p { margin: 8px 0 0; color: var(--ink); font-size: var(--fs-md); line-height: 1.65; }
.fomc-reading small { display: block; margin-top: var(--sp-1h); color: var(--faint); font-size: var(--fs-xs); line-height: 1.5; }
.fomc-dissent { margin: 0 0 12px; color: var(--muted); font-size: 12px; line-height: 1.6; }
.fomc-changes-title { margin: 18px 0 10px; color: var(--ink); font-size: var(--fs-sm); }
.fomc-context { margin: var(--sp-2) 0 var(--sp-3); color: var(--faint); font-size: var(--fs-xs); line-height: 1.55; }
.fomc-changes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.fomc-changes li { display: grid; grid-template-columns: 16px 1fr; gap: 8px; font-size: var(--fs-sm); line-height: 1.65; }
.fomc-changes .mark { font: 650 13px/1.5 var(--num); font-variant-numeric: tabular-nums; text-align: center; }
.fomc-changes .removed .mark { color: var(--red); }
.fomc-changes .added .mark { color: var(--green); }
.fomc-changes .removed p { color: var(--faint); text-decoration: line-through; text-decoration-thickness: 1px; margin: 0; }
.fomc-changes .added p { color: var(--ink); margin: 0; }
/* 바뀐 낱말. 배경 블록 대신 색+굵기를 쓴다 — 낱말 뒤 공백이 조각에 딸려
 * 오는데, 배경을 깔면 그 공백까지 칠해져서 경계가 한 칸씩 밀려 보인다. */
.fomc-changes .chg { font-weight: 700; }
.fomc-changes .removed .chg { color: var(--red); }
.fomc-changes .added .chg { color: var(--green); }
.fomc-same { margin: 12px 0 0; color: var(--faint); font-size: var(--fs-xs); }
#us-ipo .panel { overflow: hidden; border-radius: 16px; }
.usipo-summary {
  display: flex; align-items: center; gap: 10px; padding: 16px 18px;
  border-bottom: 1px solid var(--line); background: var(--panel-2);
}
.usipo-summary strong { color: var(--ink); font-size: var(--fs-sm); }
.usipo-summary span { color: var(--accent-text); font-size: var(--fs-xs); font-weight: 700; }
.usipo-table tbody tr { transition: background-color 140ms ease; }
.usipo-table tbody tr:hover { background: color-mix(in srgb, var(--accent) 4%, transparent); }
.usipo-stage {
  display: inline-flex; padding: 4px 9px; border-radius: var(--r-pill);
  background: var(--panel-2); color: var(--muted); font-size: var(--fs-xs); font-weight: 700; white-space: nowrap;
}
.usipo-stage.is-listing-near { background: var(--accent-soft); color: var(--accent-text); }

@media (max-width: 620px) {
  .dots-summary, .rx-summary { grid-template-columns: 1fr auto; }
  .dots-summary small, .rx-summary small { grid-column: 1 / -1; }
  .usipo-summary { align-items: flex-start; flex-direction: column; }
}
.accessible-table { border-collapse: collapse; color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums;}
.accessible-table caption { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.accessible-table th, .accessible-table td { padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--line); text-align: right; white-space: nowrap; }
.accessible-table th:first-child, .accessible-table td:first-child { position: sticky; left: 0; z-index: 1; text-align: left; background: var(--panel); }
/* 표 머리는 줄바꿈이 일어나는 자리다("예상 연율 HL · Binance · Bybit").
   `/1`이면 두 줄이 서로 붙어 읽히지 않는다 — 한 줄 보장 라벨에만 쓸 값이다. */
.accessible-table th { color: var(--faint); font: 650 9px/1.35 var(--num); font-variant-numeric: tabular-nums; text-transform: uppercase; }
.sector-panel .table-scroll { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

.notice-line { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; padding: 13px 16px; border-bottom: 1px solid var(--line); color: var(--muted); font-size: 11px; }
.tradingview-host { min-height: 620px; height: 620px; }
.tradingview-host .tradingview-widget-container, .tradingview-host .tradingview-widget-container__widget { width: 100%; height: 620px; }
/* 위젯 바닥과 각주 사이에 숨 쉴 자리를 준다.
 * `margin-top`이 0이라 각주의 윗선이 iframe 바닥에 **딱 붙어** 있었다
 * (실측 2026-08-31: 간격 0px, 412·1280px 모두). 히트맵은 제 바닥에 색 눈금
 * 띠를 그리므로, 붙어 있으면 `TradingView` 링크가 그 띠에 얹힌 것처럼 읽힌다. */
.tv-panel > .panel-footer, .correlation-panel > .panel-footer {
  margin: var(--sp-3) 16px 0; padding-bottom: 11px;
}
.tv-panel > .panel-footer { margin-inline: 0; }
.correlation-panel { padding: 16px; }
.corr-table th, .corr-table td { position: static !important; min-width: 74px; text-align: center !important; background: transparent !important; }
.corr-cell { color: var(--ink); font: 700 10px/1 var(--num); font-variant-numeric: tabular-nums; }
.select-label { margin-left: auto; display: flex; align-items: center; gap: 7px; color: var(--faint); font-size: 10px; }
.select-label select { min-height: 32px; padding: 4px 24px 4px 8px; color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel-2); }

.methodology { padding: 30px 0 0;}
.methodology h2 { margin: 0 0 18px;}
.method-grid { display: grid; grid-template-columns: repeat(3, 1fr); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.method-grid article { min-height: 120px; padding: 20px; background: var(--panel); }
.method-grid article + article { border-left: 1px solid var(--line); }
.method-grid strong { font-size: 12px; }
.method-grid p { margin: 8px 0 0; color: var(--muted); font-size: var(--fs-sm); }
/* 왼쪽 3px 색 띠를 걷었다 — 생성 UI의 가장 흔한 표식이고, 이 블록은
   장식이 필요한 자리가 아니다. 구획은 헤어라인 전체 테두리가 만든다.
   **내용은 한 글자도 건드리지 않는다** — FRED 서면 승인(인용문+접근일)과
   KRX 전제조건이 이 블록 안에 산다. */
.attribution { margin-top: var(--sp-4); padding: var(--sp-3) var(--panel-inset); border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: var(--panel); color: var(--muted); font: 10.5px/1.6 var(--num); font-variant-numeric: tabular-nums;}
/* 출처 한 줄과 그 약관 링크는 **한 짝**이다. 예전에는 짝 안쪽이 8px, 짝
   사이가 3px이라 근접성이 거꾸로였다 — 링크가 제 출처가 아니라 **아래**
   출처에 붙어 보였다(2026-08-30 운영자 지적, /us 1280px 실측).
   안쪽을 붙이고 짝과 짝 사이를 벌린다. */
.attribution p { margin: 0; color: var(--ink); }
/* 링크 없이 글만 잇따르는 자리(FRED의 두 번째 고지, 링크가 없는 출처)는
   따로 떼어 준다 — 안 그러면 서로 다른 출처가 0px으로 붙는다. */
.attribution p + p { margin-top: var(--sp-3); }
.attribution a { display: inline-block; margin: 0 var(--sp-2) var(--sp-3) 0; color: var(--accent);}
.attribution a:last-child { margin-right: 0; }
.attribution ul { margin: var(--sp-1h) 0 0; padding-left: 18px; }
.attribution li + li { margin-top: 5px; }

@media (max-width: 1050px) {
  .summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mast-nav { display: flex; margin-left: auto; }
  .mast-nav .nav-chip:not(.mobile-essential) { display: none; }
  .mast-actions { margin-left: 0; }
  .site-search { --search-rest: 132px; --search-open: 208px; }
  .hero h1 { font-size: clamp(42px, 8vw, 72px); }
  .weekend-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .masthead { min-height: 56px; padding: 9px 12px; }
  .brand { min-width: 0; }
  .brand small, .connection-badge span { display: none; }
  .connection-badge { margin-right: 2px; }
  .shell { padding: 30px 12px 64px; }
  .hero { grid-template-columns: 1fr; gap: 25px; padding-bottom: 30px; }
  .hero-meta { justify-self: stretch; padding-left: 0; padding-top: 14px; border-left: 0; border-top: 1px solid var(--line); }
  .hero-copy { font-size: 13px; }
  .overview { padding-top: 34px; }
  .jump-nav { top: 56px; margin-bottom: 35px; }
  .risk-strip, .weekend-disclaimer { margin-left: 0; }
  .weekend-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .metric-grid, .comparison-grid { grid-template-columns: 1fr; }
  .metric-card { min-height: 340px; padding: 16px; }
  .dashboard-section { margin-bottom: 42px; scroll-margin-top: 105px; }
  /* 번호 칩을 접는다. 안 접으면 제목만 칩 폭(30px)+간격(12px)만큼 밀리고
     부제는 위 규칙으로 0에 붙어, 제목이 제 설명글보다 42px 오른쪽에서 시작한다
     (≤430px에서는 칩이 27px이라 39px). 실측 2026-08-30 /us 8곳·/kr 1곳에서
     −39px. 폰에서 번호는 길잡이가 아니라 장식이고, 그 장식 때문에 본문이
     밀리는 편이 손해다. */
  .dashboard-section > .section-copy { margin-left: 0; }
  .section-heading > .section-index { display: none; }
  .section-heading { align-items: flex-start; flex-wrap: wrap; }
  /* **칩을 숨겼으면 칩 자리도 없어야 한다.** 바로 위에서 번호 칩을 접어
   * 놓고 여기 둘만 칩 폭(42px)만큼 들여쓰기를 그대로 갖고 있었다. 위 주석이
   * `.section-copy`에 대해 내린 판정과 같은 것을 이 둘이 못 받은 것이다.
   *
   * `width: 100%`와 겹치면 그 들여쓴 만큼이 그대로 화면 밖으로 나간다.
   * 실측(라이브 `/kr`, 2026-09-07): `#krl-board`가 폭 351px에 왼쪽 여백
   * 39px이라 오른끝 402 — 문서가 **412·390·360·320px 전부에서 12px씩
   * 가로로 밀렸다.** 운영자 제보: 로고와 제목 첫 글자가 잘려 보였다. */
  /* 아래 여백 0이라 바로 다음 표/판에 **그대로 얹혀** 있었다(운영자 지적
   * 2026-09-07: "거래대금 시가총액 있는 바가 너무 테이블에 딱붙어있고").
   * 폰에서 이 바는 전폭 52px짜리 블록이므로 제 뒤를 스스로 띄워야 한다. */
  /* 폰에서는 진짜 탭 줄이 된다 — 칸이 넷으로 갈리고 밑줄이 그 칸을 통째로
     긋는다. 사이 여백은 0이어야 칸 경계와 밑줄 경계가 같은 선에 선다.
     (글자 크기는 tokens.css가 정한다 — 그쪽이 뒤에 실려 이긴다.) */
  .segmented { order: 3; width: 100%; margin-left: 0; margin-bottom: var(--sp-3); gap: 0; }
  .segmented button { flex: 1; padding: 0 var(--sp-1) 9px; }
  .select-label { margin-left: 0; }
  .sector-row { grid-template-columns: minmax(96px, .5fr) minmax(120px, 1.4fr) 56px; gap: 7px; }
  .tradingview-host, .tradingview-host .tradingview-widget-container, .tradingview-host .tradingview-widget-container__widget { min-height: 500px; height: 500px; }
  .method-grid { grid-template-columns: 1fr; }
  .method-grid article + article { border-left: 0; border-top: 1px solid var(--line); }
}
@media (max-width: 560px) {
  /* 폰에서는 블러를 끄고 불투명면으로 간다 — 모바일 GPU에서 가장 비싼 효과이고,
     1순위 사용자의 기기가 거기다. 보이는 결과는 거의 같다. */
  .jump-nav { background: var(--bg); backdrop-filter: none; }
  /* 손가락이 닿는 크기 (2026-09-04 감사). 높이의 주인은 이제 알약 하나다 —
     `min-height`로 클램프하던 옛 규칙은 `.site-search-input`에 높이를 다시
     거는 규칙이 아래에 또 있어서 필요했던 것이고, 그 규칙과 함께 사라졌다. */
  /* 알약의 손가락 높이는 셸 절(이 파일 아래쪽)에서 정한다 — 거기 760px
     블록이 뒤에 서므로 여기서 44를 적으면 그쪽 38에 진다. */
  /* 마스트헤드: 뷰 탭 4개가 390px에서 넘친다 — 탭바만 가로 스크롤로 흡수하고
     API 칩은 내린다. 로고·언어·테마 버튼은 항상 보인다. */
  .masthead { gap: 10px; }
  .mast-nav { display: none; }
  .mast-actions { flex-shrink: 0; }
  /* 쉬는 폭은 "종목·코인 검색"이 **들어가는** 폭이다. 옛 판은 34px로 접었다가
     플렉스가 늘려 96px에서 멎었고, 좁은 기기에서는 70px이라 안내 문장이
     21.4px 잘려 있었다(실측 360·320px). 접는 것이 목적이 아니라 열리는 것이
     목적이므로, 쉬는 상태부터 문장이 온전히 서게 둔다.

     열린 폭은 화면을 넘지 않는 선에서 가장 넓게. `45vw` 상한이 좁은 기기를
     스스로 따라 내려온다 — 320px에서 열린 폭 144, 그때 줄의 합은 로고 90 +
     알약 144 + EN 44 + 여백 24 = 302… 가 아니라 쉬는 폭 124로 서 있다가
     열릴 때만 144가 되고, 그 순간 남는 자리는 296 - 274 = 22px이다. */
  /* 폭도 마찬가지로 셸 절에서 한 벌만 정한다. */
  /* 검색 중에 탭바를 접던 규칙은 걷었다(2026-09-07). 그것은 펼쳐진 검색칸이
     같은 플렉스 줄에서 자리를 빼앗아 로고가 눌리던 때의 보상이었는데, 이제
     열린 폭을 레인이 미리 잡으므로 빼앗을 자리가 없다. 게다가 그 사이
     `.view-switch`는 머리말이 아니라 **화면 바닥의 알약**이 되었다 — 접으면
     자리를 내주는 것이 아니라 검색하는 동안 이동 수단이 사라진다. */
  /* 자동완성 목록은 검색창이 아니라 **마스트헤드**에 맞춘다.
   *
   * 목록은 `.site-search`(position: relative)에 `right: 0`으로 붙어 있었고 폭은
   * `min(342px, 100vw - 24px)`였다. 좁은 화면에서 검색창은 화면 가운데쯤 있는데
   * 거기서 342px을 왼쪽으로 뻗으니 화면 밖으로 나갔다 — 375px 실측에서 패널
   * 왼쪽이 -136px, 종목명 칸이 -62px이라 "제이알글로벌리츠"가 "로벌리츠"로
   * 잘려 보였다(운영자 실기기 제보 2026-08-27).
   *
   * `.site-search`의 position을 풀면 절대 위치의 기준이 `.masthead`가 된다
   * (sticky + backdrop-filter라 이미 컨테이닝 블록이다). 그러면 좌우를 화면에
   * 맞출 수 있고, `top: 100%`도 검색창이 아니라 마스트헤드 아래가 되어 목록이
   * 헤더에 걸치지 않는다. */
  .site-search { position: static; }
  .site-search-panel { left: 12px; right: 12px; width: auto; }
  .view-switch { flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
  .view-switch::-webkit-scrollbar { display: none; }
  .view-tab { padding: var(--sp-1h) 9px; font-size: 11.5px; }
  .kro-price { font-size: 24px; }
  /* 컬럼 많은 표는 셀을 찌그러뜨리는 대신 컨테이너 안에서 가로 스크롤한다. */
  #ptr-body table, #krp-body table, #kre-body table, #kridx-body table, #ev-body table, #krev-body table { min-width: 620px; }
  /* 첫 열은 sticky라 스크롤하면 숫자 열이 그 밑으로 미끄러져 들어간다. 배경이
     같고 경계가 없으면 "6,742.74"의 왼쪽이 먹혀 "2.74"만 남은 것처럼 보인다 —
     스크롤이 아니라 데이터가 깨진 것으로 읽혔다(안드로이드 실측 2026-08-26).
     오른쪽 모서리에 선과 그림자를 줘 "고정 열 아래로 지나간다"로 읽히게 한다.
     collapse에서는 셀 box-shadow가 그려지지 않아(크롬 실측) 좁은 화면에서만
     separate로 바꾼다 — 셀은 아래 테두리뿐이라 spacing 0이면 그림이 같다.
     스크롤이 생기지 않는 넓은 화면에는 이 블록 자체가 없다. */
  .accessible-table { border-collapse: separate; border-spacing: 0; }
  .accessible-table th:first-child, .accessible-table td:first-child {
    border-right: 1px solid var(--line-strong);
    box-shadow: 10px 0 12px -4px rgba(0, 0, 0, .7);
  }
}
@media (max-width: 430px) {
  .hero h1 { font-size: clamp(30px, 9.5vw, 42px); }
  .summary-grid { grid-template-columns: 1fr 1fr; }
  .summary-card { min-height: 118px; padding: 13px 12px; }
  .summary-value { font-size: 19px; }
  .summary-meta { left: 12px; }
  /* `.section-index`는 760px 아래에서 접히므로 여기서 폭을 줄일 것이 없고,
     제목은 --fs-lg 하나로 간다(16px은 스케일 밖이었다). */
  /* ≤430px에서 칩이 27px이라 39px로 다시 잡던 줄이었다. 칩이 접힌 마당에
     들여쓸 것이 없으므로 0으로 통일한다(위 760px 블록과 같은 이유). */
  .segmented, .select-label { margin-left: 0; }
  .sector-name code { display: none; }
  .connection-badge { display: none; }
  .weekend-grid { grid-template-columns: 1fr; }
}
@media (max-width: 360px) {
  .masthead { gap: 7px; }
  .brand { flex: 0 0 auto; }
  .nav-chip { padding-inline: 7px; font-size: 10px; }
}
/* 전역 `.01ms` 킬을 걷었다(2026-09-04).
 *
 * 이 저장소에는 컴포넌트별 reduced-motion 블록이 **15개** 있고 전부 사려 깊다 —
 * 테이프는 멈추되 손으로 밀 수 있게 열어 두고, 게이지·틱·도넛을 각각 다룬다.
 * 그런데 `*` + `!important` 한 줄이 그 위를 덮어 **값이 바뀌었다는 신호까지**
 * 죽이고 있었다. 움직임을 줄여 달라는 요청은 "정보를 없애 달라"가 아니다.
 * 스크롤 점프만 남기고 나머지는 15개 블록에 맡긴다. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; }
}

/* --- 법적 고지 링크 -------------------------------------------------------- */
.site-footer { padding: 22px 0 8px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;}
.site-footer nav { display: flex; flex-wrap: wrap; gap: 16px; }
.site-footer a { color: var(--muted); font-size: var(--fs-sm); text-decoration: none; }

/* 손가락 자리 — 24px이 바닥이다.
 *
 * 390px 실측: `/us` 112곳 · `/kr` 43 · 홈 12의 링크가 19~21px로 서 있었다.
 * 전부 flex 항목이라 글자 높이가 곧 상자 높이였다. WCAG 2.2 AA(2.5.8)의
 * 24x24를 바닥으로 잡는다 — 44는 AAA이고, 이 밀도에서 44는 목록을 두 배로
 * 늘린다. 문장 속 인라인 링크는 2.5.8이 스스로 예외로 두므로 건드리지 않는다.
 *
 * `min-height`나 `display: flex`가 아니라 **대칭 안쪽 여백**을 쓴다. flex로
 * 바꾸면 긴 꼬리말 링크가 한 줄에 갇혀 줄바꿈이 사라지고, `min-height`만으로는
 * 글자가 상자 위쪽에 붙는다. 여백은 둘 다 피하고 기준선 정렬도 지킨다.
 *
 * 부모를 재 보니 대부분 공짜다 — 꼬리말 줄은 이미 31~418px이고 `.ev-who`는
 * 23px이라 1px 자란다. 값을 치르는 곳은 `.ev-meta` 한 줄뿐이다(19 → 25). */
.ev-who a,
.ev-meta a,
.site-footer a,
.panel-footer a,
.metric-card footer a,
.cliq-head a,
.attribution a,
/* 종목 페이지 표의 원문 링크. 실측(2026-09-06, 운영 /stock/…): **21×15px**로
   공시 줄마다 서 있었다 — 005930에 12개, NVDA에 21개. 이 저장소가 정한 바닥은
   24×24(WCAG 2.2 AA 2.5.8)이고, 홈은 위반이 0인데 이 페이지만 뚫려 있었다.
   `.doc-link`는 페이지 안 `<style>`에 살아서 이 목록에 없었다 — 손가락 자리
   정책이 두 곳에 있으면 한 곳은 잊힌다. 정책은 여기 하나로 둔다. */
.doc-link {
  /* 여백만 주면 상자 높이가 글자 높이에 끌려다닌다 — `.cliq-head a`는 내용이
     17px이라 3px씩 붙여도 23으로 1px 모자랐다. 바닥을 명시해 못 박는다. */
  padding-block: 3px;
  min-height: 24px;
}
/* 표 안의 짧은 링크는 세로만 늘려서는 21px 폭이 그대로 남는다. 인라인 플렉스로
   바꿔 가로도 바닥을 지킨다 — 문장 속 링크가 아니므로 2.5.8의 인라인 예외가
   적용되지 않는다. */
.doc-link {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 24px;
}
.site-footer a:hover { color: var(--ink); text-decoration: underline; }
.site-footer p { margin: 0; margin-left: auto; color: var(--faint); font-size: 11.5px; }
/* 한 줄 고지는 **링크 줄과 같은 줄 오른쪽 끝**에 선다(운영자 2026-09-06).
 *
 * DOM은 못 건드린다 — `test_shell_layout`이 읽는 순서를 고지문 → 출처 → 링크로
 * 잡고 있고, 그 순서는 2026-09-05 판정이다. 그래서 `order`로 **보이는 줄만**
 * 옮긴다. `.attribution`이 `width:100%`라 자기 줄을 다 쓰므로, 그 뒤에 선
 * nav와 p가 한 줄을 나눠 갖고 p의 `margin-left:auto`가 오른쪽 끝으로 민다.
 *
 * 읽는 순서와 보이는 순서가 갈리는 것은 이 한 줄뿐이고, 링크도 조작 대상도
 * 아니라 탭 순서에 영향이 없다. */
.site-footer .attribution { order: 1; }
.site-footer nav { order: 2; }
.site-footer p { order: 3; }
@media (max-width: 640px) {
  /* 좁으면 nav가 줄을 다 쓰므로 auto가 할 일이 없다 — 아래로 감기게 둔다. */
  .site-footer p { margin-left: 0; }
}

/* --- 유동성·스트레스 지수 ---------------------------------------------------
   점수만 크게 띄우면 어디서 나온 값인지 알 수 없다. 입력과 산식을 같은 카드
   안에서 보여주는 것이 이 지수의 요점이다. */
.stress-headline { margin-bottom: 22px; }
.stress-reading { margin: 0 0 8px; color: var(--ink); font-size: var(--fs-md); font-weight: 750; letter-spacing: -.02em; }
.stress-score { display: flex; align-items: baseline; gap: 12px; }
.stress-score strong { font-size: var(--fs-hero); font-weight: 700; letter-spacing: -0.02em; }
.stress-score span { padding: 4px 9px; border-radius: var(--r-pill); background: var(--panel-2); font-size: var(--fs-xs); color: var(--muted); }
/* 게이지 (2026-08-30, 두 번 고쳤다)
 *
 * 1차: 12px 알약 전체에 초록→노랑→빨강. 색이 값이 아니라 **눈금의 자리**를
 *      칠했다 — 50 언저리는 원래 노란 자리라는 말이 된다.
 * 2차: 2px 실선 하나로 줄였다. 색 문제는 풀렸는데 운영자 판정은
 *      "너무 얇은 선이어서 마음에 안 들어, 차라리 전에 게 나아."
 *      맞다. 44px 숫자 옆에 머리카락 한 올을 놓았으니 값이 있는 자리가
 *      화면에서 사라졌다. 절제를 존재감과 맞바꾼 것이다.
 * 3차(지금): **무게는 1차, 색 규칙은 2차.** 12px 띠와 눈에 잡히는 심지는
 *      돌려주되, 띠는 무지개가 아니라 **밴드 색 하나**로 찬다. 길이가 크기를
 *      말하고 색이 상태를 말한다 — 자리를 말하지 않는다. */
.stress-scale {
  --gauge-tone: var(--accent);
  position: relative; height: 12px; margin: 16px 0 8px; border-radius: var(--r-pill);
  background: linear-gradient(180deg, var(--bg-deep), var(--panel-2));
  box-shadow: inset 0 0 0 1px var(--line), inset 0 1px 2px rgba(0, 0, 0, .5);
}
/* 0·25·50·75 잔금. 띠 안에 옅게 넣어 눈금이 있다는 것만 알린다. */
.stress-scale::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: repeating-linear-gradient(90deg,
    transparent 0 calc(25% - 1px), var(--line-strong) calc(25% - 1px) 25%);
}
/* 0부터 값까지. 길이가 크기를 말한다.
 *
 * 단색으로 채웠더니 "색이 단조로워서 너무 무난하다"는 판정을 받았다(운영자,
 * 2026-08-30). 그렇다고 무지개로 돌아갈 수는 없다 — 그러면 색이 다시 눈금의
 * **자리**를 뜻하게 된다. 그래서 **한 색 안에서만** 깊이를 준다: 시작은
 * 어둡게, 값에 가까울수록 밝게. 그러면 띠에서 가장 밝은 지점이 값이 서 있는
 * 자리가 되어 장식이 아니라 강조가 된다. 은은한 발광도 그 끝에만 얹는다. */
.gauge-lit {
  position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--gauge-tone) 38%, var(--panel-2)) 0%,
    color-mix(in srgb, var(--gauge-tone) 82%, transparent) 62%,
    var(--gauge-tone) 100%);
  box-shadow: 0 0 14px color-mix(in srgb, var(--gauge-tone) 40%, transparent);
  clip-path: inset(0 100% 0 0 round 999px);
  transition: clip-path .75s cubic-bezier(.22, .9, .28, 1);
}
/* 값. 어느 바탕에서나 읽히도록 밝은 심지에 어두운 테를 두른다. */
.stress-scale i {
  position: absolute; top: 50%; width: 4px; height: 22px; margin-left: -2px;
  border-radius: var(--r-sm); background: var(--ink); transform: translateY(-50%);
  /* 이 세계는 그림자를 안 쓴다 — `world.css`가 `--shadow: none`으로 끈다.
     그런데 이 심지만 box-shadow를 리터럴로 박아 토큰을 우회하고 있었다:
     오프셋 0 · blur 10px의 `--gauge-tone` 60% 후광과 검은 드롭섀도. 앞의 것은
     DESIGN.md가 "장식"이라 부르는 색 후광 그 자체이고, 뒤의 것은 이 세계에
     없는 물체다. 남기는 것은 `0 0 0 2px var(--panel)` 하나 — 저건 흐림이
     없으므로 그림자가 아니라 **면**이다. 계기 위에서 심지를 눈금과 떼어 놓는
     일은 그 2px 테가 이미 혼자 한다(심지는 `--ink`, 이 화면에서 가장 밝은 중립). */
  box-shadow: 0 0 0 2px var(--panel);
  transition: left .75s cubic-bezier(.22, .9, .28, 1);
}
/* 밴드가 곧 색이다. 자리가 아니라 상태를 칠한다. */
.stress-scale[data-tone="low"] { --gauge-tone: var(--green); }
.stress-scale[data-tone="mid"] { --gauge-tone: var(--amber); }
.stress-scale[data-tone="high"] { --gauge-tone: var(--red); }
/* 심리·공포탐욕은 방향이 반대다 — 낮은 쪽이 위험회피다. */
.sentiment-scale[data-tone="low"], .fng-scale[data-tone="low"] { --gauge-tone: var(--down); }
.sentiment-scale[data-tone="high"], .fng-scale[data-tone="high"] { --gauge-tone: var(--up); }

/* 어제 자리와 그 사이의 실. 이력이 없는 지수에는 그리지 않는다.
   자국은 켜진 구간 위에도 꺼진 구간 위에도 보여야 한다 — 흐린 회색이면 값이
   오른 날에만 밝은 띠 아래 깔려 사라진다. 마커와 같은 수법으로 밝은 심지에
   어두운 테를 둘러 어느 바탕에서나 읽히게 한다. */
.gauge-ghost {
  position: absolute; top: 50%; width: 2px; height: 15px; margin-left: -1px;
  border-radius: var(--r-sm); background: var(--ink); opacity: .5;
  box-shadow: 0 0 0 1.5px rgba(0, 0, 0, .5);
  transform: translateY(-50%);
}
/* 자리와 길이를 `left`/`width`가 아니라 `transform`으로 옮긴다 — 레이아웃
   속성을 전이하면 0.75초 동안 매 프레임 레이아웃이 다시 계산된다.
   `left: 0; width: 100%`로 눕혀 두고 `translateX(%)`가 **제 폭(=트랙 폭)**을
   기준으로 움직이게 만든 것이 요령이다. 퍼센트 이동은 변형 전 상자 기준이라
   `scaleX`와 함께 써도 어긋나지 않는다.

   같은 트랙의 2px 마커(`i`)는 그대로 `left`를 쓴다 — 폭이 2px이라
   `translateX(%)`가 트랙이 아니라 그 2px을 기준으로 움직여서 이 수법이
   통하지 않는다. 자식 없는 절대위치 요소 하나라 비용은 작다. */
.gauge-trail {
  position: absolute; top: 50%; left: 0; width: 100%; height: 3px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--ink) 55%, transparent);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .4);
  transform-origin: left center;
  transform: translateY(-50%) scaleX(0);
  transition: transform .75s cubic-bezier(.22, .9, .28, 1);
}
/* 값이 실제로 바뀌었을 때만 한 번 번쩍인다. 하루 한 번 갱신되는 지수에
   쉬지 않는 애니메이션을 붙이면 실시간으로 움직이는 값처럼 읽힌다. */
.stress-scale i.changed { animation: gauge-bump .7s ease-out 1; }
@keyframes gauge-bump {
  0% { box-shadow: 0 0 0 2px var(--panel), 0 0 0 0 rgba(255, 255, 255, .55); }
  100% { box-shadow: 0 0 0 2px var(--panel), 0 0 0 11px rgba(255, 255, 255, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .gauge-lit, .stress-scale i, .gauge-trail { transition: none; }
  .stress-scale i.changed { animation: none; }
}
.stress-scale-note { margin: 0; font-size: 11.5px; color: var(--faint); }
/* 이력 차트를 훑는 동안. 마커만 옮기면 옆의 큰 숫자는 그대로 오늘 값이라,
   둘이 서로 다른 날을 가리키면서 같은 것처럼 보인다. 큰 숫자를 흐려서
   "이건 지금 값이 아니다"를 먼저 말한다. */
.stress-score.scrubbing strong, .stress-score.scrubbing span { opacity: .38; }
.stress-score strong, .stress-score span { transition: opacity .15s; }
.stress-scale.scrubbing .gauge-lit, .stress-scale.scrubbing i { transition: none; }
.stress-scale.scrubbing .gauge-ghost, .stress-scale.scrubbing .gauge-trail { opacity: .12; }
.gauge-readout {
  margin: var(--sp-1h) 0 0; min-height: 1.4em; color: var(--accent);
  font: 700 var(--fs-xs)/1.4 var(--num); font-variant-numeric: tabular-nums;
}
/* 훑는 층은 눈에 보이지 않는다 — 선과 점만 따라다닌다. */
.scrub-layer { fill: transparent; cursor: crosshair; }
.scrub-guide { stroke: var(--accent); stroke-width: 1; opacity: .55; }
.scrub-dot { fill: var(--accent); stroke: var(--panel); stroke-width: 1.5; }
.sentiment-chart { height: 120px; margin: var(--sp-1h) 0 14px; }
.stress-method, .stress-disclaimer {
  font-size: 11.5px; line-height: 1.6; color: var(--muted); margin: 12px 0 0;
}
.stress-disclaimer { color: var(--faint); }
#stress-table td.num { text-align: right; font-variant-numeric: tabular-nums; }

@media (max-width: 620px) {
  .stress-reading { font-size: var(--fs-sm); }
}

/* 코스피 지수군 표 */
/* 12px으로 13px 표를 이끈다 — 크기로는 못 이기는 자리라 괘선에 맡긴다. */
.kridx-group { margin: 14px 0 8px; }
.kridx-group:first-child { margin-top: 2px; }
/* 영어 모드의 지수 원명. 우리 영문 표기가 KRX 공식과 다를 수 있어 원명을 함께
 * 둔다 — 이름을 바꿔치기하지 않고 읽기를 돕는다. */
.kridx-native { display: block; margin-top: 2px; color: var(--faint); font-size: var(--fs-xs); }
.kridx-table td.num, .kridx-table th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.kridx-table td.up { color: var(--up); }
.kridx-table td.down { color: var(--down); }
.kridx-table td.range { color: var(--muted); font-size: 11.5px; }

/* 8-K 한 줄 요약.
 * 요약이 주고 Item 제목이 부다 — 표준 제목은 모든 8-K가 비슷해서, 읽는 사람이
 * 찾던 것은 구체적인 사건 쪽이다. 인용을 접지 않는 이유는 우리가 보장하는 것이
 * "지어낸 문장과 숫자가 없다"까지고 "이 인용이 이 한국어의 근거"까지는 아니라서,
 * 마지막 판단이 읽는 사람에게 남아야 하기 때문이다. */
/* 8-K 피드. 표를 버린 이유는 `monitor.js`의 `renderUsEvents` 주석에 있다.
 * 여기서는 그 위계를 눈으로 세운다 — 티커와 한 문장이 먼저, 나머지는 아래. */
.ev-feed { display: flex; flex-direction: column; }
.ev-card {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.ev-card:last-child { border-bottom: 0; }
/* 요약이 붙은 항목은 읽을 것이 있다는 뜻이다. 왼쪽 실 하나로만 말한다 —
   바탕색까지 바꾸면 33%가 배경 무늬가 되어 오히려 훑기가 어렵다.
   유형별로 색을 나누지 **않는다**: 이 화면의 색 규칙은 상태를 뜻하지 분류를
   뜻하지 않는다(DESIGN.md §2.4). 초록 `실적 발표` 칩은 "실적이 좋다"로
   읽힌다 — 우리는 그런 말을 한 적이 없다. */
/* **실은 카드 높이를 통째로 쓴다** — 끊지 않는다.

   한때 항목마다 끊어 봤다(2026-09-08). 이유는 있었다: `box-shadow: inset`은
   카드의 테두리 상자 전체를 칠하므로, 요약이 붙은 카드가 연달아 서면 2px 막대가
   이어 붙는다(실측 `/us` PC 1440: 카드 사이 간격 0). 그게 "종목 둘이 한 묶음으로
   읽힌다"는 제보의 원인이었고, 그래서 가짜 요소로 옮겨 위아래를 12px씩 비웠다.

   **운영자가 화면을 보고 되돌렸다**("전이 더 나아, 너무 짧아졌어"). 이어지는
   것보다 실이 짧고 뭉툭해지는 쪽이 더 나빴다. 재는 것으로는 안 갈리는 교환이라
   실물을 본 사람이 정한다 — **다시 짧게 만들기 전에 물어볼 것.** */
.ev-card.has-digest { box-shadow: inset 2px 0 0 var(--accent); }
/* 요약이 없는 항목은 읽을 문장이 없다. 자리도 그만큼만 쓴다. */
.ev-card:not(.has-digest) { padding-top: var(--sp-2); padding-bottom: var(--sp-2); }

/* 1행 — 회사명 · 티커 · 유형 · 제출일 · 원문. 출처와 시각은 어느 항목에서도
   빠지지 않는다.

   **회사명이 카드의 제목이다.** 한때 각주로 내려 두었는데 위계가 거꾸로였다
   (2026-08-31 실측, 412px):

     회사명    12px  400  대비 3.31:1   ← WCAG AA 4.5:1 미달, 카드 맨 아래
     종목코드  11.5px 750 대비 16.61:1
     요약      15px  600  대비 17.32:1

   읽는 사람의 첫 질문은 "어느 회사냐"인데 그 답이 카드에서 가장 작고 가장
   어두웠고, 아무도 안 읽는 여섯 자리 숫자가 이름보다 잘 보였다. */
.ev-head {
  display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap;
  margin-bottom: var(--sp-1h);
}
/* 코드 칩과 이름은 한 덩어리다 — 줄이 접힐 때 둘 사이가 갈라지면 이름만 홀로
   남은 줄이 생긴다. `min-width: 0`이 있어야 안쪽 이름이 말줄임을 할 수 있다
   (flex 항목의 기본 `min-width: auto`는 내용보다 못 줄어든다). */
.ev-who {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-width: 0; max-width: 100%;
}
.ev-name {
  min-width: 0; color: var(--ink);
  font-size: var(--fs-md); font-weight: 700; line-height: 1.3;
  letter-spacing: -.01em; text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ev-name:hover { text-decoration: underline; }
.ev-ticker {
  min-width: 4.5em; color: var(--ink);
  font: 750 var(--fs-sm)/1.2 var(--num); font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
}
.ev-kind {
  padding: 2px var(--sp-2); border-radius: var(--r-pill);
  border: 1px solid transparent; background: var(--panel-2);
  color: var(--ink-2); font-size: var(--fs-xs); font-weight: 650; white-space: nowrap;
}
/* 날짜와 원문은 한 덩어리다 — 따로 접히면 "보기↗" 하나가 줄 하나를 쓴다. */
.ev-meta {
  display: inline-flex; align-items: baseline; gap: var(--sp-2);
  margin-left: auto; white-space: nowrap;
}
.ev-when { color: var(--faint); font-size: var(--fs-xs); white-space: nowrap; }
.ev-src {
  color: var(--accent); font-size: var(--fs-xs); font-weight: 650;
  text-decoration: none; white-space: nowrap;
}
.ev-src:hover { text-decoration: underline; }
/* 외부로 나가는 링크는 나간다고 말한다. 45도 돌린 꺾쇠를 쓰다가 모서리(ㄱ)로
   읽혀서(운영자 제보 2026-08-31) 전용 기호로 바꿨다 — 돌린 꺾쇠는 화살표가
   아니다. */
.ev-src::after {
  content: ""; display: inline-block; width: .9em; height: .9em;
  margin-left: 4px; vertical-align: -.08em;
  background-color: currentColor;
  -webkit-mask: var(--ico-external) center / contain no-repeat;
  mask: var(--ico-external) center / contain no-repeat;
}

/* 2행 — 한 문장. 요약이 없는 카드에는 이 줄이 **없다**(예전에는 회사명을 여기
   세웠지만 이름은 1행으로 갔다). 제목보다 굵지 않게 두어 이름이 먼저 읽히게
   한다 — 크기는 같고 무게만 한 단 낮다. */
.ev-line {
  margin: 0; color: var(--ink); font-size: var(--fs-md); font-weight: 600; line-height: 1.55;
}
.ev-line a { color: inherit; }

/* 3행 — 각주. Item 번호는 값이 아니라 출처다. */
.ev-foot {
  display: flex; gap: var(--sp-2); flex-wrap: wrap;
  margin: var(--sp-1h) 0 0; color: var(--faint); font-size: var(--fs-xs);
}
.ev-foot a { color: var(--ink-3); }

/* 누가 옮겼는지 — 모델 이름을 **글자로** 밝힌다. 타사 로고 마크는 임의로
 * 그려 넣지 않는다(상표). 배지는 문장 **앞에** 붙어서 자기가 가리키는 줄만
 * 말한다 — 항목마다 "…가 옮겼어요" 한 줄을 더 쓰면 목록이 두 배가 되고
 * 같은 말을 서른 번 반복하게 된다. */
.ev-model {
  display: flex; align-items: center; gap: var(--sp-1h); flex-wrap: wrap;
  margin: 0 0 var(--sp-3); color: var(--muted); font-size: var(--fs-xs); line-height: 1.6;
}
.ev-by-mark {
  display: inline-flex; align-items: center; gap: 5px;
  margin-right: var(--sp-2); padding: 1px var(--sp-2); border-radius: var(--r-sm);
  border: 1px solid transparent;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent); font: 700 var(--fs-xs)/1.5 var(--sans);
  white-space: nowrap; vertical-align: 2px;
}
/* /kr 공시 표의 요약 행 — 앞 행에 딸린 전체 폭 줄이다. 위 테두리를 지워
 * 제 공시와 한 덩어리로 읽히게 하고, 글 상자는 화면 폭 안에서 접는다
 * (표 폭이 아니라 **뷰포트**가 기준이라 폰에서 가로로 밀 필요가 없다). */
.ev-by-mark::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; opacity: .85;
  box-shadow: 0 0 8px currentColor;
}
/* 후광을 걷었다. 점등은 **점**이 하는 일이다(위 `::before`의 8px) — 글자를 담은
   칩 전체에 색 후광을 두르면 그건 뜻이 아니라 장식이고, 이 세계가 스스로 못 박은
   "계기판은 평평하다"와 어긋난다. 배지는 이미 세 가지로 말한다: 점등된 점 ·
   액센트 16% 바탕 · 액센트 글자. 네 번째는 필요 없었다. */

/* 근거 문장은 **접어 둔다.** 한국어 요약 81자 아래에 영어 231자가 펼쳐져
 * 있으면 읽을 분량이 세 배다(중앙값 실측). 지우지는 않는다 — 지어내지
 * 않았다는 증거가 그 문장이다. */
.ev-source { margin-top: var(--sp-1h); }
.ev-source > summary {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 24px; color: var(--ink-3); font-size: var(--fs-xs); font-weight: 650;
  cursor: pointer; list-style: none;
}
.ev-source > summary::-webkit-details-marker { display: none; }
.ev-source > summary::before {
  content: ""; width: 1em; height: 1em; opacity: .8;
  background-color: currentColor;
  -webkit-mask: var(--ico-caret) center / contain no-repeat;
  mask: var(--ico-caret) center / contain no-repeat;
  transition: transform .15s ease;
}
.ev-source[open] > summary::before { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .ev-source > summary::before { transition: none; }
}
.ev-source > summary:hover { color: var(--ink); }
.ev-source blockquote {
  margin: var(--sp-1h) 0 0; padding: 0 0 0 var(--sp-3);
  border-left: 1px solid var(--line-strong);
  color: var(--ink-3); font-size: var(--fs-xs); line-height: 1.65;
  overflow-wrap: break-word;
}

@media (max-width: 560px) {
  .ev-card { padding: var(--sp-3); }
  /* 좁으면 오른쪽 끝으로 밀지 않는다 — 접힌 줄에서 홀로 오른쪽에 붙으면
     제 카드가 아니라 다음 카드의 것처럼 읽힌다. */
  .ev-meta { margin-left: 0; }
  .ev-head { gap: var(--sp-1h) var(--sp-2); }
}

/* 참고선 대 실제 종가 이력.
 * 통계가 아니라 기록이라 표 모양을 쓴다 — 한 줄이 하루고, 그날 우리가 뭐라고
 * 말했는지와 실제가 나란히 있어야 읽는 사람이 스스로 판단한다. 접어 두는 이유는
 * 이게 값을 읽으러 온 사람의 첫 줄이 아니기 때문이다. */
.kro-gap { margin-top: var(--sp-3); }
.kro-gap-basis { margin: 0 0 var(--sp-3); color: var(--muted); font-size: var(--fs-sm); line-height: 1.6; }
/* 화면 끝까지 늘리지 않는다. 다섯 열뿐이라 넓히면 날짜와 차이가 화면 양끝으로
 * 갈라져 한 줄을 눈으로 따라가야 한다. */
.kro-gap-table { width: 100%; max-width: 46em; border-collapse: collapse; font-size: var(--fs-sm); }
.kro-gap-table th, .kro-gap-table td { padding: 7px 10px; border-bottom: 1px solid var(--line); text-align: left; white-space: nowrap; }
.kro-gap-table th { color: var(--muted); font-weight: 700; font-size: var(--fs-xs); letter-spacing: .02em; }
.kro-gap-table td.num, .kro-gap-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.kro-gap-table td.up { color: var(--up); }
.kro-gap-table td.down { color: var(--down); }
.kro-gap-table tr:last-child td { border-bottom: 0; }
@media (max-width: 560px) {
  .kro-gap-table th, .kro-gap-table td { padding: 7px var(--sp-1h); }
}

/* 카드 전체를 누를 수 있게 한다. 링크는 하나뿐이고(이름) 그 `::after`가 카드를
 * 덮는 방식이라, 스크린리더에는 여전히 링크 하나로 읽히고 마크업도 그대로다.
 * 이름 글자만 눌리던 것이 폰에서 표적이 너무 작았다(운영자 2026-09-02). */
.kro-card.kro-clickable { position: relative; }
.kro-card .kro-hub-link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.kro-card.kro-clickable:hover { border-color: var(--line-strong, var(--muted)); }
/* 카드 안의 다른 조작 요소는 덮개 위로 올린다. 지금은 없지만 나중에 생기면
 * 이 규칙이 없을 때 조용히 안 눌리게 된다. */
.kro-card.kro-clickable a:not(.kro-hub-link), .kro-card.kro-clickable button { position: relative; z-index: 2; }
/* **코인 카드도 카드 전체가 눌린다.**
 *
 * 미국·국내 카드는 위 규칙으로 이미 그렇게 한다. 코인 카드만 이름 링크가
 * `.kro-hub-link`가 아니라 `.kro-detail`이라 짝이 없었고, 그래서 같은 생김새의
 * 카드가 어떤 것은 아무 데나 눌리고 어떤 것은 글자(44×15)만 눌렸다 —
 * 폰에서 그 차이는 "왜 안 눌리지"로 나타난다.
 *
 * 이 카드의 링크는 둘이다: 이름(상세로)과 심벌(거래소 원문으로). 심벌은
 * 위 `a:not(.kro-hub-link)` 규칙이 덮개 위로 올려 준다. */
.kro-card.crypto-card { position: relative; }
.kro-card.crypto-card .kro-detail::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.kro-card.crypto-card:hover { border-color: var(--line-strong, var(--muted)); }
.kro-card.crypto-card a:not(.kro-detail), .kro-card.crypto-card button { position: relative; z-index: 2; }

/* 지수 연도별 수익률.
 * 쉰다섯 해를 표로 세우면 아무도 안 읽는다. 해마다 작은 칸 하나씩 두고 색이
 * 부호를 말하게 하면 2008년의 붉은 덩어리 같은 것이 한눈에 보인다. */
/* `.panel`은 안쪽 여백을 갖지 않는다 — 자식이 넣는다. 세로만 주고 가로를
 * 빠뜨려 글자가 상자 왼쪽 선에 붙어 있었다(운영자 2026-09-02). 연준 요약에서
 * 겪은 것과 같은 자리다. */
.ixr-index { padding: var(--sp-4); border-top: 1px solid var(--line); }
.ixr-index:first-child { border-top: 0; }
.ixr-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.ixr-head h3 { margin: 0; font-size: var(--fs-sm); font-weight: 700; color: var(--ink); }
.ixr-since { color: var(--faint); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.ixr-stats { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 0 0 10px; }
.ixr-stats dt { color: var(--faint); font-size: var(--fs-xs); }
.ixr-stats dd { margin: 0 0 0 5px; color: var(--ink); font-size: var(--fs-xs); font-weight: 700; font-variant-numeric: tabular-nums; }
.ixr-stats dt, .ixr-stats dd { display: inline-block; }
.ixr-stats dd.up { color: var(--up); }
.ixr-stats dd.down { color: var(--down); }
.ixr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); gap: 3px; }
.ixr-cell {
  display: grid; gap: 1px; padding: 5px 4px; border-radius: var(--r-sm);
  background: var(--panel-2); text-align: center; font-variant-numeric: tabular-nums;
  /* **두 줄은 위에서부터 쌓인다.** 한 칸이 다른 칸보다 높으면 나머지가 격자에
     맞춰 늘어나는데, 그때 남는 높이를 줄 사이로 나누면 값만 아래로 내려앉는다
     (실측 폰 360·412: 같은 줄에서 7.8px 어긋남). 남는 자리는 아래에 모은다. */
  align-content: start;
}
/* 연도 라벨의 잉크를 한 단 올렸다(2026-09-04, 실측 124건 AA 미달).
   `--faint`(#8b96a1)가 초록 12% 틴트면(#1a3332) 위에서 **4.48:1**이라
   본문 기준 4.5에 못 미쳤다. 하락 셀(#33252d)은 4.83:1로 통과였으니
   초록 셀만의 문제였다. 틴트를 낮추는 대신 잉크를 올린다 — 틴트는
   상승/하락을 가르는 신호라 약화시키면 뜻이 준다. --ink-2로 7.05:1. */
.ixr-cell b { color: var(--ink-2); font: 600 var(--fs-xs)/1.2 var(--num); font-variant-numeric: tabular-nums; }
.ixr-cell span { font: 700 var(--fs-xs)/1.3 var(--num); font-variant-numeric: tabular-nums; }
.ixr-cell.up { background: color-mix(in srgb, var(--up) 12%, var(--panel-2)); }
.ixr-cell.up span { color: var(--up); }
.ixr-cell.down { background: color-mix(in srgb, var(--down) 12%, var(--panel-2)); }
.ixr-cell.down span { color: var(--down); }
/* 온전한 해가 아닌 칸은 빗금으로 구분한다 — 색만으로는 같은 해로 읽힌다. */
.ixr-cell.partial { outline: 1px dashed var(--line-strong, var(--muted)); outline-offset: -1px; }

/* 달별 띠. 열두 칸이 한 줄에 서야 계절이 한눈에 보인다. */
.ixr-sub { margin: 14px 0 var(--sp-1h); }
.ixr-months {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(52px, 1fr);
  gap: 3px; padding-bottom: 2px;
}
/* 좁은 화면에서는 **가로로 밀지 않고 반으로 접는다.**
   처음엔 `overflow-x: auto`로 뒀는데 390px에서 여섯 달만 보이고 나머지는
   스크롤 뒤에 숨었다(실측 2026-09-02). 이 띠는 "어느 달이 좋았나"를 **견주는**
   그림이라, 절반이 화면 밖이면 견줄 수가 없다. 상반기·하반기 두 줄이면
   열두 칸이 다 보이고 6월과 7월이 갈리는 자리도 자연스럽다. */
@media (max-width: 620px) {
  /* `1fr`은 `minmax(auto, 1fr)`이라 칸이 제 최소 내용보다 좁아지지 못한다.
     390px에서 여섯 칸이 각자 최소 폭을 고집해 띠가 10~11px 밖으로 새고 있었다
     (실측: `/us`만 문서 폭이 넘쳤다). `minmax(0, 1fr)`이 그 바닥을 푼다. */
  .ixr-months { grid-auto-flow: row; grid-template-columns: repeat(6, minmax(0, 1fr)); }
  /* `minmax(0, 1fr)`이 문서 넘침을 없앴지만 **칸 안**은 다시 안 쟀다. 글자는
     46.52px인데 칸 안쪽 상자가 360px에서 34.0px이라, "10월−0.77%"가 칸 테두리를
     뚫고 3px 홈을 건너 옆 칸 위에 그려지고 있었다(360에서 48칸 전부, 390에서
     43칸). `overflow-x: visible`이라 잘리지도 않는다.

     자르지 않는다 — 월과 값은 이미 두 자식(`b`와 `span`)이라 줄만 내리면 된다.
     값을 지우는 대신 한 줄을 더 쓴다. */
  .ixr-cell { min-width: 0; overflow: hidden; }
  .ixr-cell b, .ixr-cell span { display: block; min-width: 0; }
}
/* 스물넉 달 띠(`/semi`)는 열두 칸을 전제로 만든 이 격자에 한 줄로 못 선다.
   24 × 52 + 23 × 3 = **1317px**인데 가장 넓을 때도 판 안쪽은 1254px이라
   (1320 − 32 − 2 − 32) 마지막 칸이 판 밖에 서 있었다. 그리고 창이 1352px보다
   좁아지면 그 넘침이 그대로 **문서 가로 스크롤**이 됐다 — 실측 2026-09-06:
   1280에서 70px · 1024에서 326 · 768에서 582 · 621에서 729. 620px 아래는 이미
   여섯 칸씩 접혀 멀쩡했으니 넓은 화면만의 병이고, 그래서 폭이 넓어질수록
   나빠지지 않고 **좁아질수록** 나빠졌다.

   52px 바닥을 푸는 것만으로는 안 된다 — 칸이 49px가 되면 이번엔 칸 **안**에서
   `24-08`이 넘친다(바로 위 폰 규칙에서 겪은 그 자리다). 열두 칸씩 접어 줄을
   나눈다. 위아래로 같은 달이 겹쳐 한 해가 갈리는 자리도 눈에 보인다.
   폰 규칙과 다투지 않도록 621px 위에서만 건다 — 이름이 하나 더 붙어 특이도가
   높으므로, 조건 없이 두면 폰의 여섯 칸 접기를 이겨 버린다. */
@media (min-width: 621px) {
  .ixr-months.ixr-long { grid-auto-flow: row; grid-template-columns: repeat(12, minmax(0, 1fr)); }
  /* `minmax(0, …)`은 칸이 제 내용보다 좁아지는 것을 허락한다 — 폰 규칙이 하는
     것과 같은 보호를 여기도 건다. */
  .ixr-months.ixr-long .ixr-cell { min-width: 0; overflow: hidden; }
}
.ixr-month { cursor: help; }
/* 달 사이 차이를 흔들림과 나란히 놓는 줄. 평균 옆에 반드시 서야 하므로
   조용한 각주가 아니라 본문 크기로 둔다. */
.ixr-spread { margin: 8px 0 0; color: var(--muted); font: 400 var(--fs-sm)/1.6 var(--sans, system-ui); }

/* Korea zone: around-the-clock reference cards ------------------------------ */
.zone-divider { display: flex; align-items: baseline; gap: 10px; margin: 58px 0 24px; padding-top: 18px; border-top: 1px solid var(--line-strong); }
.zone-divider span { color: var(--ink); font: 800 15px/1 var(--sans); letter-spacing: -.01em; }
.zone-divider small { color: var(--faint); font: 700 9px/1 var(--num); font-variant-numeric: tabular-nums; letter-spacing: .18em; }
.kro-grid { display: grid;}
/* 위쪽 색 띠(초록/빨강)는 뺐다 — 등락은 숫자가 이미 말하고 있고, 카드마다
   띠가 서면 색이 다시 장식이 된다(DESIGN.md §2.4). `console.css`에서 되돌리는
   대신 **여기서 지운다**: 두 규칙이 특이도가 같아 나중에 읽히는 쪽이 이기는데,
   그 되돌리기가 `border-top`을 통째로 못 박아 **호버의 파란 테두리까지 위쪽만
   막고 있었다**(2026-08-31 실측: 호버 시 top `rgb(34,42,50)` 대 나머지 세 면
   `rgb(79,168,255)`). 상쇄하는 두 규칙을 다 지우면 기본 테두리 하나만 남고
   네 면이 같이 움직인다. */
.kro-card { min-width: 0; border: 1px solid var(--line); background: var(--panel);}
/* 머리는 **한 줄이다** — 로고·이름 … 심벌 (운영자 판정 2026-09-08:
   "이건 그냥 전처럼 원상복구 하는 게 나을 거 같아").

   어제 이 한 줄을 두 번 고쳤고 두 번 다 교환이 나빴다. 기록으로 남긴다.

   ① `flex-wrap: wrap` — 모자랄 때만 심벌을 아랫줄로. 그러면 **긴 이름 카드만**
      머리가 두 줄이 되어 같은 줄 옆 카드와 값 높이가 어긋났다("한쪽은
      올라가있고").
   ② 전부 두 줄(이름 줄 / 심벌 줄) — 높이는 같아졌지만 **여섯 장 중 한 장 때문에
      나머지 다섯 장까지** 줄을 하나 더 썼다. 운영자 판정: 이름이 넘치는 건
      일부인데 그것 때문에 다른 카드 디자인을 해쳤다.

   그래서 한 줄로 돌아온다. 다만 **처음 그 자리로는 아니다** — 옛 판의 진짜
   결함(로고만 첫 줄에 남는 것)은 남겨 두지 않는다. 그건 이름 링크가
   `inline-flex`(원자적)라 줄 안에서 쪼개지지 못하고 통째로 다음 줄로 내려가서
   생긴 것이었고, 지금 그 링크는 `inline`이다(console.css) — 이름은 로고 옆에서
   시작해 아래로 흐른다.

   ③ 말줄임도 걸어 봤다가 걷었다(운영자 판정 2026-09-08 아침: "긴 종목명 자르는
      건 아닌 것 같아"). 자르면 줄맞춤은 얻지만 이름을 잃는다 — 나쁜 교환이다.
      **줄맞춤은 아래 subgrid가 따로 맡는다.** 이름은 온전히 흐른다.

   `min-width: 0`은 남긴다. 없으면 이름이 줄지 않고 티커를 오른쪽으로 밀어 카드
   안쪽 여백이 12px에서 **2.98px**까지 무너진다(390 EN에서 여섯 중 넷, 최악
   +9.02px). 티커는 그 종목의 신원이라 줄이지 않는다. */
.kro-card header { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.kro-card header > :first-child { min-width: 0; }
.kro-card header > :last-child { flex: 0 0 auto; }

/* 같은 줄의 카드를 같은 높이에 세우는 subgrid 블록은 **console.css에 있다.**
   `.tile-spark`가 그쪽에도 있어서 여기 쓰면 같은 클래스가 두 파일에 걸치고,
   그러면 로드 순서상 뒤인 쪽이 이겨 이 파일의 선언이 조용히 죽는다(실제로
   105건 그랬다). 새 규칙은 console.css 한 곳에 쓴다 — test_stylesheet_split. */
.kro-card h3 { margin: 0;}
/* `font-variant-numeric`은 console.css의 `.kro-sym`으로 옮겼다 — 거기 `font:`
   단축이 이걸 지우고 있어서, 여기 두면 나중에 로드되는 쪽에 조용히 진다. */
.kro-sym { color: var(--faint); text-decoration: none;}
.kro-sym:hover { color: var(--accent); }
.kro-vs { color: var(--muted);}
.kro-vs.up { color: var(--up); }
.kro-vs.down { color: var(--down); }
.kro-vs-ref { color: var(--faint); opacity: .92;}
.kro-vs-ref.up { color: var(--up); }
.kro-vs-ref.down { color: var(--down); }
.kro-meta { display: grid; margin: 13px 0 0; border-top: 1px solid var(--line);}
.kro-meta div { display: flex; justify-content: space-between; gap: 8px; }
.kro-meta dt { font-variant-numeric: tabular-nums;}
.kro-meta dd { margin: 0; text-align: right;}
/* 종가가 마지막 거래일보다 늦을 때, 그게 의견 차이가 아니라 공개 일정임을 밝힌다. */
.kro-lag { margin: 7px 0 0; color: var(--faint); font: 650 9px/1.45 var(--num); font-variant-numeric: tabular-nums; }
.kro-badges { display: flex; flex-wrap: wrap; gap: 4px;}
.kro-footer { margin: 12px 0 0;}
.kro-footer .kro-method { margin: 0 0 4px; color: var(--muted); font-size: 10.5px; }
.kro-footer .kro-disclaimer { margin: 0; color: var(--faint); font-size: 10px; }
@media (max-width: 1020px) { .kro-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .kro-grid { grid-template-columns: 1fr; } .zone-divider { margin: 42px 0 18px; } }

/* 홀수 장일 때 마지막 한 장이 반쪽으로 남지 않게 한다.
 *
 * 반도체·메모리는 열둘이라 3열에서 3×4, 2열에서 2×6으로 떨어지지만,
 * 파운드리·장비는 셋이라 2열에서 마지막 한 장이 옆자리를 비우고 혼자 선다
 * (실측 2026-09-06, 390px: 2-1). 종목은 상장·폐지로 늘고 주니 어느 쪽도
 * 오래 짝수로 남지 않는다 — 열이 둘인 폭에서 끝 장이 홀수 자리면 한 줄로 편다.
 *
 * **폭은 실측으로 정했다.** 두 격자 다 `.board`이고(원자재 타일과 같은 조판),
 * 그 2열 구간은 console.css가 `max-width: 1080px`로 정한다. 여기 경계도 1080인
 * 이유다 — 1020으로 적으면 1020~1080 구간에서만 어긋난다. 아이디 선택자라 어느
 * 파일에 있든 열 규칙보다 세다. */
@media (max-width: 1080px) {
  #smm-grid > :last-child:nth-child(odd),
  #smf-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* 국민연금 5% 공시 표 */
.krp-company a { color: var(--ink); text-decoration: none; }
.krp-company a:hover { color: var(--accent); text-decoration: underline; }
.krp-market { margin-left: var(--sp-1h); color: var(--faint); font: 700 8.5px/1 var(--num); font-variant-numeric: tabular-nums; letter-spacing: .04em; }

/* 랜딩: 존 링크 카드 */
/* **늘어나게 둔다** — `align-items: start`를 되돌린다(2026-09-06).
 *
 * 바이오 카드가 제 내용보다 84px 큰 상자로 서는 것을 고치겠다고 늘어남을 껐는데,
 * 그러자 행마다 카드 높이가 갈렸다(운영자: "카드마다 크기 다른 것도 불편해").
 * 한 구멍을 없애려다 격자를 잃은 셈이다.
 *
 * 그리고 그 구멍은 애초에 구멍이 아니었다. `.zone-mini`가 이미
 * `margin-top: auto`를 갖고 있어, 카드가 늘어나면 **값 줄이 바닥에 붙어 행 전체가
 * 한 선에 선다.** 빈 자리는 설명과 값 사이에 생기고 그건 얼룩이 아니라 구조다.
 * 원래 그렇게 설계돼 있었고, 내가 끈 것이 그 설계였다.
 *
 * 아래 34px은 눈금(4·6·8·12·16·24·32·48·64) 밖이라 32로 되돌린 것은 유지한다. */
.zone-links { margin: var(--sp-1h) 0 var(--sp-6); }
.zone-link-card { box-shadow: var(--shadow);}
.zone-link-card strong { display: block; color: var(--ink); letter-spacing: -.01em;}
.zone-link-card strong::after { content: " →"; color: var(--accent); }
.zone-link-card span { display: block; margin-top: 8px;}
@media (max-width: 700px) { .zone-links { grid-template-columns: 1fr; } }

/* P2: 헤더 세션 배지 · H.10 환율 티커 */
.session-badge { display: inline-flex; align-items: center; gap: var(--sp-1h); padding: 5px 9px; border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--muted); font: 650 9.5px/1 var(--num); font-variant-numeric: tabular-nums; white-space: nowrap; }
.krp-company a:first-child { color: inherit; }

.feed-upcoming { display: flex; flex-wrap: wrap; gap: 7px; padding: 12px 14px; border-bottom: 1px solid var(--line); }
.feed-filter { display: flex; gap: var(--sp-1h); margin-bottom: 10px; }
.feed-region { padding: 5px 12px; border: 1px solid var(--line); border-radius: var(--r-pill); background: none; color: var(--muted); font: 650 10px/1.3 var(--num); font-variant-numeric: tabular-nums; cursor: pointer; }
.feed-region:hover { color: var(--ink); border-color: var(--line-strong); }
.feed-region.active { color: var(--ink); border-color: var(--line-strong); background: var(--panel-soft, rgba(255,255,255,0.04)); }
.feed-empty { color: var(--muted); }
.feed-soon { padding: 5px 10px; border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--muted); font: 650 10px/1.3 var(--num); font-variant-numeric: tabular-nums; text-decoration: none; }
.feed-soon:hover { color: var(--ink); border-color: var(--line-strong); }
/* **칸의 주인은 목록이다** (2026-09-04, 이슈 줄과 같은 처방).
 * 줄마다 따로 격자를 세우면 `auto` 칸은 그 줄 안에서만 넓이를 잰다 — 갈래
 * 이름이 2자(뉴스)든 5자(연준 발언)든 제목이 그만큼 밀렸다. 목록이 칸을 잡고
 * 줄은 `subgrid`로 빌려 쓰면, 넓이는 가장 넓은 갈래 하나가 정한다. */
#feed-body { display: grid; grid-template-columns: auto auto minmax(0, 1fr); }
.feed-row { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid;
  align-items: baseline; border-bottom: 1px solid var(--line);}
.feed-row:last-child { border-bottom: 0; }
/* 꼬리(출처·등락 칩·허브)는 셋째 칸 안에서 흐른다 — 좁아지면 여기서 접힌다. */
.feed-main { display: flex; align-items: baseline; flex-wrap: wrap; min-width: 0;
  gap: var(--sp-1h) 11px; }
.feed-date { font: 650 10px/1.4 var(--num); font-variant-numeric: tabular-nums;}
/* 갈래 칩은 **판에서 파인 자리**로 둔다 — 테두리를 두르면 곁가지가 본문보다
   눈에 띈다.

   처음엔 `지금 이슈`의 `.issue-tag`처럼 `--ink` 8%를 깔았다가 되돌렸다. 자가
   바로 잡았다: `.feed-tag.us` 4.12:1 < 4.5. `--accent`(#3182f6)는 판(#0d1420)
   위에서 5.01인데 밝은 면을 섞으면 바닥이 밝아져 내려간다(4%로 낮춰도 4.48).
   `.issue-tag`가 그 면으로 괜찮은 이유는 글자가 `--ink-3`이라서다 — 여기 글자는
   **색으로 뜻을 나르므로** 그 색을 손해 보면 안 된다.

   `--bg`는 판보다 어두운 페이지 바닥이다. 칩이 파인 자리로 읽히고 대비는
   5.27로 원래보다 오히려 오른다. 다크 테마에서 "면을 깐다"가 곧 "밝힌다"는
   뜻은 아니다. */
.feed-tag { justify-self: stretch; text-align: center; border-radius: var(--r-sm); border: 1px solid transparent; background: var(--bg); color: var(--muted); font: 700 9px/1.2 var(--num); font-variant-numeric: tabular-nums;}
.feed-tag.kr { color: var(--green); }
.feed-tag.us { color: var(--accent); }
.feed-tag.news { color: var(--amber); }
/* **목록의 주인공은 사건이다.** 여기 문장이 `--muted`(#b3bdc7)로 깔려 있어서
   섹션 전체가 회색 한 단이었다 — 눈이 붙잡을 데가 없고, 그 없음이 "밋밋하다"로
   읽힌다(운영자 2026-09-08, 이 섹션을 콕 집었다). 바로 위 `지금 이슈`의 제목은
   `--ink`다. 같은 화면에서 같은 무게의 것이 두 밝기로 설 이유가 없다. */
.feed-text { min-width: 0; color: var(--ink); font-size: 12px; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 쉬는 상태가 `--ink`가 되면 `--ink`로 가는 hover는 아무 말도 안 한다. */
a.feed-text:hover { color: var(--accent); }
.feed-domain { font: 650 9.5px/1.3 var(--num); font-variant-numeric: tabular-nums;}
.feed-move { flex: 0 0 auto; border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--muted); font: 700 9.5px/1.3 var(--num); font-variant-numeric: tabular-nums; text-decoration: none;}
.feed-move.up { color: var(--up); } .feed-move.down { color: var(--down); }
.feed-move:hover { border-color: var(--line-strong); }
.feed-hub { margin-left: auto; flex: 0 0 auto; font: 700 10px/1.3 var(--num); font-variant-numeric: tabular-nums; text-decoration: none;}
.feed-hub:hover { color: var(--ink); }
@media (max-width: 560px) { .feed-text { white-space: normal; } }

.kro-official-strip { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 18px; margin: 14px 2px 0; color: var(--muted); font: 650 11px/1.4 var(--num); font-variant-numeric: tabular-nums;}
.kro-official-strip .kro-strip-label { color: var(--faint); letter-spacing: .08em; text-transform: uppercase;}
.kro-strip-lag { color: var(--faint); font: 650 9.5px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.kro-strip-item { display: inline-flex; align-items: baseline; gap: var(--sp-1h); }
.kro-strip-item small { color: var(--faint); font-size: 10px; }
.kro-strip-item strong { color: var(--ink);}
.kro-strip-item em { font-style: normal; font-size: 10px; }
.kro-strip-item em.up { color: var(--up); }
.kro-strip-item em.down { color: var(--down); }
.presence-badge { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--green); font-variant-numeric: tabular-nums; white-space: nowrap;}
@media (max-width: 430px) { .presence-badge { display: none; } }
.session-badge i { width: 6px; height: 6px; border-radius: 50%; background: var(--faint); }
.session-badge.open { color: var(--green); }
.session-badge.open i { background: var(--green); box-shadow: 0 0 0 4px color-mix(in srgb, var(--green) 12%, transparent); }
.mast-ticker { display: inline-flex; align-items: baseline; gap: 5px; color: var(--ink); font: 750 11px/1 var(--num); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mast-ticker small { color: var(--faint); font: 650 8.5px/1 var(--num); font-variant-numeric: tabular-nums; }
@media (max-width: 960px) { .mast-ticker { display: none; } }
@media (max-width: 760px) { .session-badge { display: none; } }

/* P2: 랜딩 컴팩트 히어로 · 존 카드 미니 프리뷰 */
.hero.hero-compact { padding-bottom: 22px; }
.hero.hero-compact h1 { font-size: clamp(30px, 4.8vw, 58px); }
.zone-mini { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); color: var(--ink); font: 750 12px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.zone-mini small { color: var(--faint); font: 650 9px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.zone-mini em { font-style: normal; }
.zone-mini em.up { color: var(--up); }
.zone-mini em.down { color: var(--down); }

/* 24시간 카드 틱 플래시 — 값이 움직인 방향으로 한 번 번쩍인다 */
@keyframes kro-tick-up { 0% { color: var(--up); } 100% { color: inherit; } }
@keyframes kro-tick-down { 0% { color: var(--down); } 100% { color: inherit; } }
/* 굴림과 같은 길이로 — 0.7초면 숫자가 아직 도는 중에 색이 꺼진다. */
.kro-price.tick-up { animation: kro-tick-up 1.2s ease-out; }
.kro-price.tick-down { animation: kro-tick-down 1.2s ease-out; }

/* 크립토 섹션 (Phase 1) */
.crypto-card .kro-price { font-size: 24px; }
/* 아래 여백이 0이라 요약 줄이 카드 격자에 그대로 붙어 있었다(실측 간격 0px).
   위 14px · 아래 0은 이 줄을 카드의 머리글처럼 보이게 하는데, 실제로는 섹션
   전체의 요약이라 어느 카드에도 속하지 않는다. 양쪽을 떼어 놓는다. */
.crypto-strip { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 18px; margin: 14px 2px 12px; color: var(--muted); font: 650 11px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.crypto-strip .kro-strip-item em.up { color: var(--up); }
.crypto-strip .kro-strip-item em.down { color: var(--down); }
.fng-attribution { margin: 8px 0 12px; color: var(--muted); font: 650 10.5px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.fng-attribution a { color: var(--accent); text-decoration: none; }
.fng-attribution a:hover { text-decoration: underline; }
.fng-deltas { display: flex; flex-wrap: wrap; gap: var(--sp-1h); margin: 12px 0 0; }
.fng-deltas span { padding: 4px 8px; border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--muted); font: 650 10px/1.3 var(--num); font-variant-numeric: tabular-nums; }
.fng-deltas span.up { color: var(--up); }
.fng-deltas span.down { color: var(--down); }
.crypto-table td.num, .crypto-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.crypto-table td.up { color: var(--up); }
.crypto-table td.down { color: var(--down); }
.cvol-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 9px; margin: 0 0 12px; }
.cvol-card { padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel-2); }
.cvol-card h3 { margin: 0 0 8px; }
/* 22px 숫자 바로 아래에 12px 세부 줄이 간격 0으로 붙어 있었다(h3에는 8px가
   있는데 여기만 없었다). line-height 1이라 글자 아래 여유마저 없다. */
.cvol-card strong { display: block; font: 800 22px/1 var(--num); letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
/* 뒤따르는 줄이 있을 때만 띄운다 — strong에 아래 여백을 주면 세부 줄이 없는
   카드(값 하나짜리)까지 바닥이 늘어난다. */
.cvol-card strong + small { margin-top: 7px; }
.cvol-card small + small { margin-top: 2px; }
.cvol-card small { color: var(--faint); font: 650 9.5px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.zone-links.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 900px) { .zone-links.three { grid-template-columns: 1fr; } }
.crypto-dominance-bar { display: flex; height: 22px; margin: 0 0 12px; border-radius: var(--r-sm); overflow: hidden; border: 1px solid var(--line); }
.crypto-dominance-bar .seg { display: flex; align-items: center; justify-content: center; color: var(--accent-ink); font: 700 9.5px/1 var(--num); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; }
.crypto-dominance-bar .seg.btc { background: var(--amber); }
.crypto-dominance-bar .seg.eth { background: var(--accent); }
.crypto-dominance-bar .seg.others { background: var(--muted); }
.cstr-stable { margin: 4px 0 12px; }
.cstr-stable .cstr-sub { margin: 0 0 8px; font: 600 11px/1.4 var(--num); font-variant-numeric: tabular-nums; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.cstr-stable .kro-method { margin-top: 8px; }
.zone-links.four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .zone-links.four { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px) { .zone-links.four { grid-template-columns: 1fr; } }
.bio-sponsors { display: flex; flex-wrap: wrap; gap: var(--sp-1h); margin: 0 0 12px; }
.bio-chip { display: inline-flex; flex-direction: column; gap: 2px; padding: var(--sp-1h) 10px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); font-size: 11px; }
.bio-chip strong { font-size: 12px; }
.bio-chip small { color: var(--muted); }
/* opacity .55는 잉크를 3.71:1까지 깎는다. 한 단 내려서 말한다. */
.bio-chip.muted { color: var(--ink-3); border-color: var(--line); }
.bio-table { table-layout: fixed; width: 100%; min-width: 980px; }
.bio-table th, .bio-table td { white-space: normal; word-break: keep-all; vertical-align: top; text-align: left; }
#biot-table th:nth-child(1), #biot-table td:nth-child(1) { width: 8%; }
#biot-table th:nth-child(2), #biot-table td:nth-child(2) { width: 13%; }
#biot-table th:nth-child(3), #biot-table td:nth-child(3) { width: 32%; }
#biot-table th:nth-child(4), #biot-table td:nth-child(4) { width: 6%; }
#biot-table th:nth-child(5), #biot-table td:nth-child(5) { width: 13%; }
#biot-table th:nth-child(6), #biot-table td:nth-child(6) { width: 8%; }
#biof-table th:nth-child(1), #biof-table td:nth-child(1) { width: 10%; }
#biof-table th:nth-child(2), #biof-table td:nth-child(2) { width: 12%; }
#biof-table th:nth-child(3), #biof-table td:nth-child(3) { width: 30%; }
#biof-table th:nth-child(6), #biof-table td:nth-child(6) { width: 8%; }
.bio-table .bio-title { display: block; white-space: normal; }
.bio-table .bio-why { display: block; color: var(--muted); font-size: 10.5px; }
.bio-table .bio-flags { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: 4px; }
.bio-filter { display: flex; gap: var(--sp-1h); margin: 0 0 10px; }
.bio-filter button { font: inherit; font-size: 11px; padding: 4px 11px; border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--panel); color: var(--muted); cursor: pointer; }
.bio-filter button.active { color: inherit; border-color: var(--accent); }
.bio-table .bio-pub { display: block; color: var(--muted); font-size: 10.5px; margin-top: 2px; }
#bioa-table th:nth-child(1), #bioa-table td:nth-child(1) { width: 12%; }
#bioa-table th:nth-child(2), #bioa-table td:nth-child(2) { width: 24%; }
#bioa-table th:nth-child(3), #bioa-table td:nth-child(3) { width: 40%; }
#bioa-table th:nth-child(4), #bioa-table td:nth-child(4) { width: 12%; }
#biom-table th:nth-child(1), #biom-table td:nth-child(1) { width: 9%; }
#biom-table th:nth-child(2), #biom-table td:nth-child(2) { width: 30%; }
#biom-table th:nth-child(3), #biom-table td:nth-child(3) { width: 16%; }
#biom-table th:nth-child(4), #biom-table td:nth-child(4) { width: 9%; }
#biom-table th:nth-child(5), #biom-table td:nth-child(5) { width: 8%; }
.cvol-card small.up { color: var(--up); }
.cvol-card small.down { color: var(--down); }
.cboard-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
.cboard-card { min-width: 0; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); }
.cboard-card h3 { margin: 0 0 8px; }
.cboard-table th, .cboard-table td { padding: 5px var(--sp-1h); font-size: 11px; }
.cboard-sym { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--line); }
.cboard-sym:hover { color: var(--accent); border-bottom-color: var(--accent); }
.crypto-card { cursor: pointer; }
.sig-top { display: grid; grid-template-columns: repeat(2, minmax(140px, 210px)) 1fr; gap: 10px; align-items: stretch; margin: 4px 0 12px; }
.sig-gauge { padding: 12px 13px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); min-width: 0; }
.sig-gauge small { display: block; color: var(--faint); font: 650 9.5px/1.4 var(--num); font-variant-numeric: tabular-nums; text-transform: uppercase; letter-spacing: .06em; }
.sig-gauge strong { display: block; margin-top: 5px; font: 750 20px/1.1 var(--num); font-variant-numeric: tabular-nums; }
/* `>`가 요점이다 — 후손 선택자면 (0,1,1)로 안쪽 `.lang-en`의
   `display: none`(0,1,0)을 이겨 두 언어가 같이 선다(실측 2026-08-31). */
.sig-gauge > span { display: block; margin-top: var(--sp-1h); color: var(--muted); font: 650 10.5px/1.3 var(--num); font-variant-numeric: tabular-nums; }
.sig-bar { position: relative; height: 6px; margin-top: 8px; border-radius: var(--r-pill); background: var(--line); overflow: hidden; }
.sig-bar i { position: absolute; top: 0; bottom: 0; left: 0; border-radius: var(--r-pill); background: var(--accent); }
.sig-bar.center::before { content: ""; position: absolute; left: 50%; top: -2px; bottom: -2px; width: 1px; background: var(--muted); opacity: .6; }
.sig-reading { margin: 0; padding: 12px 14px; border: 1px dashed var(--line); border-radius: var(--r-md); color: var(--ink); font-size: 12px; line-height: 1.65; }
.sig-spark { display: block; width: 100%; height: 26px; margin-top: 8px; }
.sig-spark path { fill: none; }
.creg-delta { display: block; margin-top: 4px; color: var(--muted); font: 650 10px/1.3 var(--num); font-variant-numeric: tabular-nums; }
.crypto-news { list-style: none; margin: 0; padding: 0; }
.crypto-news li { padding: 10px 2px; border-bottom: 1px solid var(--line); }
.crypto-news li:last-child { border-bottom: 0; }
.crypto-news a.headline { color: inherit; font-size: var(--fs-sm); font-weight: 650; line-height: 1.5; text-decoration: none; }
.crypto-news a.headline:hover { color: var(--accent); text-decoration: underline; }
.crypto-news .meta { display: flex; flex-wrap: wrap; gap: var(--sp-1h); align-items: center; margin-top: 5px; color: var(--faint); font: 650 10px/1.4 var(--num); font-variant-numeric: tabular-nums; }
.crypto-news .coin-tag { padding: 2px 7px; border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--muted); text-decoration: none; }
.crypto-news .coin-tag:hover { color: var(--accent); border-color: var(--accent); }
@media (max-width: 760px) { .sig-top { grid-template-columns: 1fr 1fr; } .sig-reading { grid-column: 1 / -1; } }
.crypto-card h3 .kro-detail { color: inherit; text-decoration: none; }
.crypto-card:hover { border-color: var(--accent); }
.crypto-card:hover h3 .kro-detail { color: var(--accent); }
@media (max-width: 900px) { .cboard-grid { grid-template-columns: 1fr; } }

/* 뉴스 영상 — 썸네일은 구글 CDN에서 오지만(쿠키 없음) 플레이어는 누르기 전에
 * 로드되지 않는다. 누르면 그 카드만 iframe으로 바뀐다. 플레이어는 약관상
 * 200x200 미만이면 안 되므로 min-height로 바닥을 받쳐 둔다. */
/* 4열 고정. auto-fill로 두니 넓은 화면에서 5열이 되어 썸네일이 244px까지
 * 작아졌다 — 영상 목록은 칸을 늘리는 것보다 한 칸이 커지는 쪽이 낫다. */
.news-videos { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 1180px) { .news-videos { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 900px) { .news-videos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .news-videos { grid-template-columns: 1fr; } }
.news-videos li { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.news-videos li.playing { border: 1px solid var(--accent); border-radius: var(--r-md); overflow: hidden; }
.news-videos .nvid-shot { position: relative; display: block; width: 100%; padding: 0; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; background: var(--panel); cursor: pointer; aspect-ratio: 16 / 9; }
.news-videos .nvid-shot:hover { border-color: var(--accent); }
.news-videos .nvid-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 썸네일이 없거나 404면 빈 액자만 남으므로, 그 자리를 접는다. */
.news-videos .nvid-shot.no-shot { aspect-ratio: auto; padding: 5px 11px; text-align: left; }
.news-videos .nvid-badge { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 42px; height: 42px; display: grid; place-items: center; border-radius: var(--r-pill); background: rgba(0, 0, 0, 0.55); color: var(--ink); font-size: 15px; pointer-events: none; }
.news-videos .nvid-shot.no-shot .nvid-badge { position: static; transform: none; width: auto; height: auto; background: none; color: var(--muted); }
.news-videos .nvid-meta { display: flex; flex-wrap: wrap; gap: var(--sp-1h); align-items: center; color: var(--faint); font: 650 10px/1.4 var(--num); font-variant-numeric: tabular-nums; }
/* **알약을 걷었다** (운영자 제보 2026-09-08: "영상 주인 이름이랑 영상 제목이랑
   세로 align 안 맞지? 영상 제목이 더 왼쪽에서 시작해").

   실측 390px: 채널·시각·제목의 상자는 셋 다 x=25.0으로 맞아 있었다. 그런데
   알약은 `padding: 2px 7px` + 테두리 1px이라 **글자가 x=33에서** 시작하고,
   바로 아래 제목은 x=25에서 시작했다. 상자를 맞춰 놓고 안심한 것이었다 —
   눈은 상자가 아니라 글자 기둥을 읽는다.

   알약이 하던 일(채널을 시각과 갈라 보이게)은 굵기와 밝기가 대신한다. 애초에
   여기 알약이 맞지도 않았다: 이 줄에는 고를 것이 없는데 알약은 고를 수 있는
   것처럼 보인다. */
.news-videos .nvid-channel { color: var(--muted); font-weight: 700; }
.news-videos .nvid-channel::after { content: "·"; margin-left: var(--sp-1h); color: var(--ink-3); }
.news-videos .nvid-title { color: inherit; min-height: 3em; font-size: var(--fs-sm); font-weight: 650; line-height: 1.5; text-decoration: none; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.news-videos .nvid-title:hover { color: var(--accent); text-decoration: underline; }
.news-videos .nvid-play { align-self: flex-start; display: inline-flex; align-items: center; gap: var(--sp-1h); padding: 5px 11px; border: 1px solid var(--line); border-radius: var(--r-pill); background: none; color: var(--muted); font: 650 10.5px/1 var(--num); font-variant-numeric: tabular-nums; cursor: pointer; }
.news-videos .nvid-play:hover { color: var(--accent); border-color: var(--accent); }
.news-videos .nvid-frame { width: 100%; min-height: 200px; aspect-ratio: 16 / 9; border: 0; display: block; }

/* 눌림 — monitor.css에만 정의된 컨트롤 셋. 나머지 눌림 규칙은 console.css
 * 끝의 블록에 있다(두 파일 겹침을 늘리지 않기 위한 배치). */
.nav-chip:active, .bio-filter button:active { transform: scale(.96); }

/* 긴 목록의 꼬리를 접는 버튼 (2026-08-31).
 * 목록의 끝에 서고, 눌러야 할 것처럼 보이되 값을 이기지 않는다. */
.list-fold {
  display: block; width: 100%;
  padding: var(--sp-3) var(--sp-4);
  border: 0; border-top: 1px solid var(--line);
  background: none; color: var(--accent);
  font: 650 var(--fs-xs)/1 var(--num); font-variant-numeric: tabular-nums;
  text-align: center; cursor: pointer;
}
.list-fold:hover { background: var(--panel-2); }
.list-fold:active { background: var(--panel-3); }


/* ======================================================================
 * 공용 셸 — 마스트헤드·화면 전환 탭·검색·아이콘 버튼 (console.css에서 이동)
 *
 * 콘솔 13장과 법적 3장이 **같은 머리**를 쓰게 하려고 여기로 내렸다. 이 파일은
 * 두 계열이 모두 싣는 유일한 자리다. 위쪽의 옛 `.view-switch` 알약 규칙보다
 * 뒤에 오므로 그것을 덮는다.
 * ================================================================== */
.masthead {
  min-height: var(--mast-h);
  gap: var(--sp-4);
  padding: 0 max(var(--sp-4), calc((100vw - 1320px) / 2));
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(12px) saturate(120%);
  border-bottom: 1px solid var(--line);
}
.brand { min-width: 0; gap: var(--sp-2); }
/* 마크는 2:1이다(TIDAL FLOW, 2026-09-19). 정사각형 치수를 주면 그 안에
 * 레터박스로 들어가 절반 크기로 줄어든다 — 높이가 아니라 폭을 정한다. */
.brand-mark { width: 48px; height: 24px; }
/* 머리말의 이름은 **타이핑한 글자**다. 작도한 로고타입(#308)을 하루 띄워 보고
 * 운영자 판정으로 되돌렸다 — 둥근 기하 소문자가 이 화면의 다른 글자와 재료가
 * 달라서, 브랜드가 서기보다 혼자 떠 보였다. 그린 글자를 다시 제안하지 마라.
 *
 * 파일(`brand/mulmit-word-*.svg`)은 지운 게 아니라 큰 자리(og 이미지·소개)용으로
 * 남아 있다. 여기로 다시 끌어오는 것이 되돌린 판정이다. */
.brand strong { font-size: var(--fs-lg); font-weight: 700; letter-spacing: -.03em; }
/* 마스트헤드의 브랜드 부제를 뺀다. 두 줄짜리 로크업은 박스는 가운데여도
 * "Mulmit" 글자가 6~7px 위로 뜨고, 그러면 옆의 탭이 내려앉아 보인다. 부제는
 * 바로 아래 h1이 이미 하는 말이라 없어도 잃는 게 없다. */
.brand small { display: none; }

/* 탭은 헤더 높이를 꽉 채운다. 글자는 헤더 정중앙에 놓이고, 활성 밑줄은 공중에
 * 뜨는 대신 헤더 아래 선 위에 정확히 앉는다. */
/* `border-radius: 0`이 핵심이다. monitor.css의 이 줄은 알약 모양 탭 묶음이라
 * `border-radius: var(--r-pill)`를 갖고 있었고, 여기서 배경·테두리·여백만 지우고 반경은
 * 안 지웠다. 그 상태에서 좁은 화면 규칙이 `overflow-x: auto`를 얹으면(아래
 * 850줄) 반경이 **클리핑 경계**가 된다 — 첫 탭(홈)의 활성 밑줄 왼쪽 13px이
 * 둥근 모서리에 깎여 쐐기 모양으로 나왔다. 실측(411×915, dpr 3.5, /):
 * 밑줄이 기기 87~149px(탭의 58%)에 두께 1~6px로 들쭉날쭉 → 고친 뒤 42~149px
 * (탭의 99%)에 두께 6px 균일. 둘째 탭부터는 컨테이너 모서리에서 멀어 멀쩡했고,
 * 그래서 "홈만 잘려 보인다"로 제보됐다. */
.view-switch { align-self: stretch; align-items: stretch; min-width: 0; background: transparent; border: 0; border-radius: 0; padding: 0; gap: var(--sp-1); }
.view-tab {
  display: inline-flex; align-items: center;
  padding: 0 12px; border-radius: 0; font-size: var(--fs-sm); font-weight: 600;
  color: var(--ink-3);
}
.view-tab:hover { color: var(--ink); background: var(--panel-2); }
.view-tab.active { background: transparent; color: var(--ink); box-shadow: inset 0 -2px var(--accent); }
/* 탭은 이름을 둘 갖는다 — 넓은 화면은 온전한 이름, 폰 하단 바는 짧은 이름.
 * 아이콘은 폰에서만 선다. `display: none`인 쪽은 접근성 트리에도 없으므로
 * 낭독기는 언제나 **보이는 이름 하나**만 읽는다. */
.view-tab-ico { display: none; width: 20px; height: 20px; flex: 0 0 auto; }
.view-tab-name.is-short { display: none; }
/* `is-both`는 두 폭에서 같은 이름을 쓰는 탭이다(홈·한국). 짧게 만들 것이
   없는데 같은 글자를 두 번 적으면, 다음에 한쪽만 고쳐진다. */

.mast-actions { gap: var(--sp-2); }
/* 검색칸의 높이·모서리는 알약(`.site-search-field`)이 갖는다 — 여기서 다시
   걸면 알약 안에 다른 높이의 상자가 하나 더 선다. */
.icon-button { height: 32px; border-radius: var(--r-sm); font-size: var(--fs-xs); }

/* 좁은 화면의 셸 — console.css에서 함께 내려왔다(2026-09-01).
 *
 * 기본 규칙만 옮기고 여기를 두고 왔더니 폰에서 갈렸다. 실측(412px):
 * `/kr` 머리 58px 대 `/privacy` 100px — 법적 페이지가 첫 화면을 42px 더
 * 먹었다. 셸은 통째로 움직여야 한다. */
@media (max-width: 760px) {
  /* 두 줄로 접는다: [로고 · 검색 · 모드 · 언어] / [탭]. 세 줄이 되면 첫 화면의
   * 3분의 1을 머리말이 먹는다. */
  .masthead { flex-wrap: wrap; padding-top: var(--sp-1h); padding-bottom: 0; gap: var(--sp-2); row-gap: 0; }
  .brand { order: 1; }
  .mast-actions { order: 2; margin-left: auto; }
  .view-switch { order: 3; width: 100%; overflow-x: auto; scrollbar-width: none; }
  .view-switch::-webkit-scrollbar { display: none; }
  .view-tab { padding: 0 10px; height: 42px; }
  .site-search { --search-rest: 128px; --search-open: 172px; }
  /* 손가락 자리는 알약이 낸다 — 입력칸은 이제 그 안의 글자 줄이다. */
  .site-search-field { height: 38px; }

}

@media (max-width: 560px) {
  /* 좁은 폭에서도 **이름은 그대로 둔다** — 예전에 통째로 숨기던 규칙(356px에서
   * 320px 필요·309px 있음)은 탭이 아직 머리말에 있던 시절 것이고, 760px 아래에서
   * `.view-switch`는 화면 바닥으로 내려가 머리말에는 로고·검색·언어 셋뿐이다.
   *
   * 2026-09-16 한국어 브랜드 질의 때문에 마스트헤드가 `물밑 Mulmit`이 되었고,
   * 폰에서는 라틴 절반을 `.brand-latin`으로 접었다(브랜드 90.1 → 121.9px,
   * 360px에서 액션이 두 줄로 밀렸다). **2026-09-17 운영자 판정으로 이름은 다시
   * `Mulmit` 한 마디**라 접을 절반이 없고, 그래서 규칙도 없다. 한글 브랜드는
   * `og:site_name`·JSON-LD·`<title>`·바닥 고지가 계속 들고 있다 — 색인이
   * 읽는 세 자리는 그대로다. 되돌리려면 그 수치를 다시 재라(git log 66a21132). */
  .masthead { padding-left: 12px; padding-right: 12px; }
  /* 검색 레인 — 폰 한 벌.
   *
   * 쉬는 폭은 "종목·코인 검색"이 **들어가는** 폭이다. 옛 판은 34px로 접었다가
   * 플렉스가 늘려 96px에서 멎었고, 좁은 기기에서는 70px이라 안내 문장이
   * 21.4px 잘려 있었다(실측 360·320px). 접는 것이 목적이 아니라 여는 것이
   * 목적이므로, 쉬는 상태부터 문장이 온전히 선다.
   *
   * 열린 폭의 `45vw` 상한이 좁은 기기를 스스로 따라 내려온다 — 폭을 정하는
   * 곳이 둘이면 다음에 한쪽만 고쳐진다(옛 판은 실제로 네 군데였다).
   *
   * 실측(쉬는 124 → 열린): 412 → 185.4 · 390 → 175.5 · 360 → 162 · 320 → 144.
   * 로고는 네 폭 전부에서 90.1로 그대로 서고 가로 넘침은 0이다. */
  .site-search { --search-rest: 130px; --search-open: min(196px, 45vw); }
  .site-search-field { height: 44px; }
}

/* 320px대(구형 iPhone SE)에도 검색칸을 따로 줄이지 않는다. 열린 폭에 걸어 둔
 * `45vw` 상한이 화면을 따라 내려오므로 한 벌로 족하다 — 폭을 정하는 곳이
 * 둘이면 다음에 한쪽만 고쳐진다(옛 판은 실제로 그래서 네 군데였다). */

/* --- 폰에서는 페이지 탭을 하단으로 (3차 감사 W-6, 운영자 승인 2026-08-31)
 * console.css에서 함께 내려왔다(2026-09-01) — 법적 3장도 같은 자리에서
 * 페이지를 옮길 수 있어야 한다. 한 손 조작에서 가장 자주 쓰는 컨트롤이
 * 엄지에서 가장 멀리 있던 것을 고친 규칙이고, 그 이유는 문서 페이지에서도
 * 똑같다. **같은 요소를 CSS로만 옮긴다** — 마크업·i18n·활성 상태는 그대로다.
 * `.section-rail`은 콘솔에만 있으므로 그쪽에 남겼다. */
@media (max-width: 760px) {
  /* backdrop-filter는 fixed 후손의 기준 상자를 만든다(Chrome 실측: 탭 바가
   * 마스트헤드 안에 갇혀 top 4px에 섰다). 폰에서는 블러를 걷고 불투명으로. */
  .masthead { background: var(--bg); backdrop-filter: none; }
  /* 바는 **가장자리에서 띄운 알약**이다 (2026-09-07, 운영자: "토스같은
   * 느낌으로 가자"). 바닥에 붙은 띠는 화면을 위아래로 자르는데, 띄우면
   * 본문이 그 옆으로 계속 흐른다 — 화면이 끝나지 않은 것처럼 보인다.
   *
   * 테두리는 높이 안에 있다(`box-sizing`). 밖에 두면 `--pagebar-h`를 읽는
   * 모든 곳이 1px씩 어긋난다 — 실측으로 두 번 겪은 자리다.
   *
   * 반투명·블러는 **가져오지 않는다.** world.css가 고정 띠 셋의
   * `backdrop-filter`를 걷어낸 이유가 "모바일 GPU에서 가장 비싼 효과이고
   * 1순위 사용자의 기기가 거기"였다. 불투명한 한 단 위 면(`panel-2`)이
   * 같은 인상을 값 없이 낸다. */
  .view-switch {
    position: fixed; z-index: 510; order: 0; width: auto;
    left: var(--pagebar-inset); right: var(--pagebar-inset);
    bottom: calc(var(--pagebar-inset) + env(safe-area-inset-bottom, 0px));
    /* 칸을 균등하게 나누므로 넘칠 것이 없다. 스크롤 컨테이너로 두면 반경이
     * 클리핑 경계가 되던 옛 함정(위 주석)이 되살아날 자리만 남는다. */
    gap: 0; overflow: visible;
    box-sizing: border-box; height: var(--pagebar-h);
    padding-bottom: 0;
    background: var(--panel-2);
    border: 1px solid var(--line); border-radius: var(--r-pill);
  }
  /* 아이콘 위, 이름 아래. 이름은 **짧은 쪽**을 쓴다 — 12px가 바닥인데
   * 360px에서 한 칸이 69px이라 "미국·글로벌"(72px)이 자기 칸을 넘는다.
   * 글자를 줄이는 대신 이름을 줄이고, 뜻은 아이콘이 함께 진다. */
  /* `height: auto`는 위 블록의 `height: 42px`를 걷는 것이다 — 그것이 남으면
   * 바 안에 손가락이 닿지 않는 띠가 생긴다(실측: 바 52 · 칸 42). */
  .view-tab {
    position: relative;
    flex: 1 1 0; min-width: 0; height: auto;
    flex-direction: column; justify-content: center; align-items: center;
    gap: 3px; padding: 0 2px; white-space: nowrap;
  }
  /* 다섯이 같은 24×24 상자에 같은 잉크로 선다. 한때 국기를 컬러 파일로
   * 넣으며 24×16 상자와 `opacity` 규칙을 뒀는데, "색깔은 빼줘"(2026-09-07)로
   * 그 재료가 사라져 규칙도 함께 걷었다. */
  .view-tab-ico { display: block; width: 24px; height: 24px; }
  .view-tab-name { display: none; }
  .view-tab-name.is-short, .view-tab-name.is-both { display: block; font-weight: 600; }
  /* 활성은 **밑줄이 아니라 잉크와 점**이다. 알약에는 걸 모서리가 없고,
   * 바닥에 붙지 않으므로 밑줄이 잘릴 일도 없어졌다. 다만 잉크 대비만으로는
   * 어느 칸인지 한눈에 안 잡혀(실측 비교) 점 하나를 더한다 — 색에 맡기고
   * 싶어지면 형태로 말한다는 규칙 그대로다. */
  /* 활성은 **잉크와 굵기만**으로 말한다 (운영자 판정 2026-09-07: "점 빼").
   * 알약에는 밑줄을 걸 모서리가 없고, 점은 토스에 없다. 잉크 3단 → 잉크
   * 1단은 대비 6.66 → 15.83이라 옆 칸과 확실히 갈린다. */
  .view-tab.active { box-shadow: none; }
  .view-tab.active .view-tab-name { font-weight: 700; }
  /* 알약이 먹는 자리 = 높이 + 아래 여백. 위쪽으로도 같은 만큼 띄워 본문
   * 마지막 줄이 알약에 닿지 않게 한다. */
  body {
    padding-bottom: calc(
      var(--pagebar-h) + var(--pagebar-inset) * 2 + env(safe-area-inset-bottom, 0px)
    );
  }
}

/* 연결 배지는 어긋났을 때만 선다 (운영자 2026-09-03).
   초록 점에 "데이터 연결"은 늘 켜져 있으면서 아무것도 안 알린다 — 알림은
   상태가 바뀔 때 값어치가 생긴다. 지연·오류·연결 중일 때는 그대로 뜬다.
   (DOM에는 남는다: aria-live 영역이라 사라지면 변화를 못 알린다.) */
.connection-badge.ok { display: none; }

/* 자사주 매입 목록. **막대는 기간 경과다** — 매입 진행률이 아니고, 라벨이
   매번 그렇게 말한다. 색을 등락색(초록/빨강)으로 쓰지 않는 이유도 같다:
   시간이 지나는 것은 좋은 일도 나쁜 일도 아니다. */
.krbb-row { padding: 14px var(--panel-inset); border-bottom: 1px solid var(--line); }
.krbb-row:last-child { border-bottom: 0; }
.krbb-head { display: flex; align-items: baseline; gap: var(--sp-2); }
.krbb-head h3 { margin: 0; font-size: var(--fs-md); font-weight: 650; letter-spacing: -.015em; }
.krbb-head h3 a { text-decoration: none; }
.krbb-head h3 a:hover { color: var(--accent); text-decoration: underline; }
/* 손가락 자리를 24px로 — **보이는 크기는 그대로.**
 *
 * 실측 폰 390: 51×18. 인라인 링크의 히트 영역은 글자 상자이고 행간은 거기
 * 안 들어간다(2026-09-08 `elementFromPoint`로 확인). 이 줄에는 링크가 둘이라
 * (종목명 · 원문) 카드를 통째로 덮는 수법은 못 쓴다 — 둘째가 안 눌린다.
 * 위아래로만 늘린다. */
.krbb-head h3 a, .krbb-link { position: relative; }
.krbb-head h3 a::after, .krbb-link::after {
  content: ""; position: absolute; left: 0; right: 0;
  top: 50%; height: 24px; transform: translateY(-50%);
}
.krbb-amount { margin-left: auto; color: var(--ink); font: 750 var(--fs-md)/1 var(--num); font-variant-numeric: tabular-nums; }
.krbb-meta { margin: 5px 0 0; color: var(--muted); font: 650 var(--fs-xs)/1.5 var(--num); font-variant-numeric: tabular-nums; }
/* `/us`의 FOMC 막대(`.rx-row`)와 **같은 틀**이다 — 라벨이 글자폭, 값이 글자폭,
   나머지를 막대가 갖는다. 5px 회색 띠가 폭을 통째로 가로지르고 값이 다음 줄에
   있으면 스크롤바로 읽힌다(운영자 제보 2026-09-08: "지금은 스크롤바 같아"). */
.krbb-note { margin: 4px 0 0; color: var(--ink-2); font-size: var(--fs-xs); line-height: 1.5; }
.krbb-purpose { margin: 4px 0 0; color: var(--muted); font-size: var(--fs-xs); line-height: 1.5; }
.krbb-link { display: inline-flex; align-items: center; gap: 4px; margin-top: var(--sp-1h); color: var(--muted); font-size: var(--fs-xs); font-weight: 700; text-decoration: none; }
.krbb-link .ico { width: 12px; height: 12px; }
.krbb-link:hover { color: var(--accent); text-decoration: underline; }

/* 대장주 네 판. 표 자체는 `.accessible-table`을 그대로 쓰고, 종목 칸에 붙는
   표식 둘만 여기서 정한다.

   순위는 크기를 견주는 값이 아니라 이름표라 가운데로 둔다 — 오른쪽 정렬이면
   자릿수가 다른 1과 10이 어긋나 보인다(검색 관심도 표에서 같은 판단). */
#kr-leaders .accessible-table th.krl-rank,
#kr-leaders .accessible-table td.krl-rank { width: 1%; text-align: center; color: var(--faint); font: 700 var(--fs-xs)/1 var(--num); font-variant-numeric: tabular-nums; }
#kr-leaders .accessible-table th[scope="row"] { display: flex; align-items: center; gap: var(--sp-1h); font-weight: 650; }
#kr-leaders .accessible-table th[scope="row"] a { text-decoration: none; }
#kr-leaders .accessible-table th[scope="row"] a:hover { color: var(--accent); text-decoration: underline; }
.krl-market { color: var(--faint); font: 650 var(--fs-xs)/1 var(--num); font-variant-numeric: tabular-nums; letter-spacing: .02em; }
/* 지우지 않고 표시한다 — 얇은 것도 사실이다. 눈에 띄되 이름을 밀어내지는
   않도록 테두리만 준다. */
.krl-flag { padding: 2px var(--sp-1h); border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--faint); font: 650 var(--fs-xs)/1.2 var(--sans); white-space: nowrap; }
.krl-flag.warn { border-color: color-mix(in srgb, var(--red) 45%, var(--line)); color: var(--red); }
/* 표 셀에는 `.up`만으로 색이 안 든다 — `.accessible-table`의 셀 색 규칙이 더
   구체적이라 이긴다. 실측(2026-09-06): +29.86%가 muted(157,176,198)로 나갔다.
   다른 표들(`.mkt-table .up`·`.weekend-table td.up`)이 각자 선언하는 이유가
   같다. 색이 이 표의 값 중 하나이므로 여기서도 선언한다. */
#kr-leaders .accessible-table td.up { color: var(--up); }
/* 업종 안 상위 10% 판 — 대장주 판과 같은 표, 문자는 색 없는 상자 하나. */
#kr-top-grades .accessible-table th.krtg-rank,
#kr-top-grades .accessible-table td.krtg-rank { width: 1%; text-align: center; color: var(--faint); font: 700 var(--fs-xs)/1 var(--num); font-variant-numeric: tabular-nums; }
#kr-top-grades .accessible-table th[scope="row"] a { text-decoration: none; font-weight: 650; }
#kr-top-grades .accessible-table th[scope="row"] a:hover { color: var(--accent); text-decoration: underline; }
#kr-top-grades .accessible-table td.krtg-scope { color: var(--muted); font-size: var(--fs-xs); }
/* 등락 분포 — 오른·보합·내린 띠 하나와 칸마다 가로 막대. 색은 등락의 신호, 값은 중립 잉크. */
#krbd-panel > :not(.table-scroll) { padding-inline: var(--panel-inset); }
#krbd-panel > #krbd-basis { padding-top: var(--sp-3); }
.krbd-split-label { margin: var(--sp-2) 0 var(--sp-1); font-size: var(--fs-xs); color: var(--ink-2); }
.krbd-split { display: flex; height: 10px; border-radius: var(--r-pill); overflow: hidden; background: var(--panel-3); margin: 0 var(--panel-inset) var(--sp-3); }
.krbd-seg { display: block; height: 100%; background: var(--line-strong); }
.krbd-seg.up { background: var(--up); }
.krbd-seg.down { background: var(--down); }
.krbd-bars { display: flex; flex-direction: column; gap: var(--sp-1); padding-bottom: var(--sp-3); }
.krbd-row { display: grid; grid-template-columns: minmax(5.5em, auto) minmax(0, 1fr) minmax(4em, auto); align-items: center; gap: var(--sp-2); font-size: var(--fs-xs); min-height: 18px; }
.krbd-label { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.krbd-track { display: block; height: 12px; min-width: 0; }
.krbd-fill { display: block; height: 100%; min-width: 1px; border-radius: 2px; background: var(--line-strong); opacity: .85; }
.krbd-fill.up { background: var(--up); }
.krbd-fill.down { background: var(--down); }
.krbd-count { text-align: right; color: var(--ink); font-family: var(--num); font-variant-numeric: tabular-nums; }
/* 업종별 — 같은 크기 타일. 면적으로 시총을 말하지 않는다. */
#krin-panel > :not(.table-scroll) { padding-inline: var(--panel-inset); }
#krin-panel > #krin-basis { padding-top: var(--sp-3); }
#krrg-panel > :not(.table-scroll) { padding-inline: var(--panel-inset); }
#krrg-panel > #krrg-basis { padding-top: var(--sp-3); }
/* 타일이 판의 줄을 나눠 쓴다(subgrid) — 이름이 두 줄인 타일 옆에서 한 줄짜리 타일의
   등락·곳수·대표 종목이 통째로 19.2px(12px 한 줄) 올라가 있었다(UI 감사 ALIGN 10·11건,
   2026-09-12 /kr 84점). 이름을 한 줄로 자르는 처방은 이미 기각된 판정이라 쓰지 않는다
   (바로 아래 주석 · 운영자 2026-09-08 "긴 종목명 자르는 것"). 네 줄을 함께 세우면 줄 수가
   달라도 자리가 맞는다. subgrid를 모르는 브라우저는 예전처럼 쌓는다. */
.krin-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  grid-auto-rows: auto; gap: var(--sp-2); padding-bottom: var(--sp-3);
}
.krin-tile {
  display: grid; grid-row: span 4; grid-template-rows: subgrid; row-gap: 2px;
  align-content: start; min-width: 0; border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--sp-2) var(--sp-3);
}
/* 이름과 대표 종목은 두 줄까지 — 한 줄 말줄임은 폰 두 열에서 이름 하나만 남겼다(360px 실측). */
.krin-name { font-size: var(--fs-xs); color: var(--ink-2); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.krin-change { font: 650 var(--fs-lg)/1.15 var(--num); font-variant-numeric: tabular-nums; letter-spacing: 0; }
.krin-change.up { color: var(--up); }
.krin-change.down { color: var(--down); }
.krin-meta { font-size: var(--fs-xs); color: var(--ink-3); }
/* 대표 종목도 **자리로 선다.** 셋을 한 줄에 흘려 두면 이름 길이에 따라 둘째·셋째가
   타일마다 다른 줄에서 시작했다(UI 감사 ALIGN 안쪽 지적 6·12건 — 바깥 네 자리를 맞추자
   비로소 보였다). 종목 하나가 한 칸이면 이름이 길어도 자리가 안 밀린다. 한 줄로 자르는
   처방은 기록된 판정(바로 위 주석)이 막는다. */
.krin-top { display: grid; row-gap: 0; font-size: var(--fs-xs); color: var(--ink-2); min-width: 0; }
/* 종목 한 줄 — 이름과 등락이 한 칸에 선다. 이름이 길면 **이름만** 줄고 등락은 제자리다. */
.krin-stock { position: relative; display: flex; align-items: baseline; gap: var(--sp-1); min-width: 0; }
.krin-stock a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.krin-stock small { flex: none; font-variant-numeric: tabular-nums; }
/* 줄 높이는 19px인데 손가락은 24px가 필요하다(WCAG 2.2 AA). 줄을 키우면 타일이 세 줄만큼
   길어지므로 **짚는 면만** 넓힌다 — 가짜 요소로 줄 전체를 덮는다. 줄끼리 2.5px씩 겹치지만
   겹치는 쪽은 언제나 아래 줄이라 위 종목이 가려지지 않는다. */
.krin-stock a::after { content: ""; position: absolute; inset: -2.5px 0; }
.krin-top a { text-decoration: none; color: var(--ink); }
.krin-top a:hover { text-decoration: underline; }
.krin-top small.up { color: var(--up); }
.krin-top small.down { color: var(--down); }
@media (max-width: 560px) { .krin-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
#kr-top-grades .krtg-letter { display: inline-block; min-width: 1.6em; padding: 1px var(--sp-1h); border: 1px solid var(--line-strong); border-radius: var(--r-sm); font: 700 var(--fs-sm)/1.4 var(--num); font-variant-numeric: tabular-nums; color: var(--ink); text-align: center; }
@media (max-width: 560px) { #kr-top-grades .accessible-table td.krtg-scope { max-width: 34vw; white-space: normal; } }
#kr-leaders .accessible-table td.down { color: var(--down); }

/* 폰에서는 다섯 열이 안 들어간다. 실측(2026-09-06, iframe 100vw): 표 439px ·
   스크롤러 319px(360px 화면) — 120px이 화면 밖이고, 그 화면 밖이 하필 **탭
   이름이 된 열**이다. 종가와 시장 배지를 내려 305px로 맞춘다. 옆으로 밀어
   보게 두는 것보다 덜 보여 주고 다 보이는 쪽이 낫다. */
@media (max-width: 480px) {
  #kr-leaders .krl-close { display: none; }
  #kr-leaders .krl-market { display: none; }
  #kr-leaders .accessible-table th,
  #kr-leaders .accessible-table td { padding-left: var(--sp-2); padding-right: var(--sp-2); }
}
