/* ─────────────────────────────────────────────────────────
   디자인 토큰 — stock-screener(Linear 계열)의 체계를 그대로 가져왔다.
   다크가 기본이고 라이트는 :root[data-theme="light"] 로 토큰만 뒤집는다.
   모든 색을 var() 로만 쓰므로 토큰 교체만으로 전체 UI 가 따라온다.
   ───────────────────────────────────────────────────────── */
:root {
  --bg-base:        #08090a;
  --bg-raised:      #0d0e10;
  --bg-strong:      #131418;
  --bg-elevated:    #1a1b1f;
  --bg-hover:       rgba(255, 255, 255, .04);

  --text-primary:   #f7f8f8;
  --text-secondary: #b4b8c0;
  --text-muted:     #8a8f98;
  --text-faint:     #62666d;

  --border-subtle:  rgba(255, 255, 255, .06);
  --border-default: rgba(255, 255, 255, .10);
  --border-strong:  rgba(255, 255, 255, .16);
  --border-focus:   #5e6ad2;

  --accent:         #8d83d8;
  --accent-soft:    rgba(94, 106, 210, .18);

  /* 신호색 — 지연(주황)·부정(빨강)·승인(초록). 등락이 아니라 심사 상태라
     한국 증시 관례(빨강=상승)를 따르지 않는다. */
  --warn:           #f0a63a;
  --warn-soft:      rgba(240, 166, 58, .14);
  --bad:            #f43f5e;
  --bad-soft:       rgba(244, 63, 94, .14);
  --ok:             #34d399;
  --ok-soft:        rgba(52, 211, 153, .13);
  --neutral:        #8a8f98;
  --neutral-soft:   rgba(255, 255, 255, .07);

  --shadow-2: rgba(0,0,0,.40) 0 4px 16px -4px, rgba(0,0,0,.20) 0 1px 2px 0;
  --shadow-3: rgba(255,255,255,.04) 0 0 0 1px inset, rgba(0,0,0,.50) 0 8px 24px -8px;

  --radius-sm: 4px;
  --radius-md: 5px;
  --radius-lg: 6px;
  --radius-xl: 8px;

  --motion-instant: 100ms;
  --motion-fast: 160ms;
  --ease: cubic-bezier(.4, 0, .2, 1);

  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Pretendard',
               'Apple SD Gothic Neo', 'Malgun Gothic', 'Segoe UI', Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, 'JetBrains Mono', Menlo, monospace;
}

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

  --bg-base:        #f7f8fa;
  --bg-raised:      #ffffff;
  --bg-strong:      #eceef2;
  --bg-elevated:    #ffffff;
  --bg-hover:       rgba(0, 0, 0, .04);

  --text-primary:   #1a1d23;
  --text-secondary: #454a54;
  --text-muted:     #6b7280;
  --text-faint:     #9aa0aa;

  --border-subtle:  rgba(0, 0, 0, .07);
  --border-default: rgba(0, 0, 0, .12);
  --border-strong:  rgba(0, 0, 0, .18);

  /* 다크에서 '밝을수록 강조'였던 값은 흰 배경에서 '진할수록 강조'로 뒤집는다. */
  --accent:         #493caa;
  --accent-soft:    rgba(94, 106, 210, .12);

  --warn:           #b45309;
  --warn-soft:      rgba(217, 119, 6, .13);
  --bad:            #e11d48;
  --bad-soft:       rgba(225, 29, 72, .11);
  --ok:             #0f9d70;
  --ok-soft:        rgba(15, 157, 112, .12);
  --neutral:        #6b7280;
  --neutral-soft:   rgba(0, 0, 0, .06);

  --shadow-2: rgba(0,0,0,.10) 0 4px 16px -4px, rgba(0,0,0,.06) 0 1px 2px 0;
  --shadow-3: rgba(0,0,0,.05) 0 0 0 1px inset, rgba(0,0,0,.14) 0 8px 24px -8px;
}

:root.dark { color-scheme: dark; }

* { box-sizing: border-box; }

html {
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body { margin: 0; background: var(--bg-base); word-break: keep-all; }

:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; border-radius: 4px; }
:focus:not(:focus-visible) { outline: none; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-default); border-radius: 8px; border: 2px solid var(--bg-base);
}
::-webkit-scrollbar-thumb:hover { background: var(--border-strong); }
::selection { background: rgba(94, 106, 210, .40); color: var(--text-primary); }

.wrap { max-width: 1320px; margin: 0 auto; padding: 0 20px; }
.tabular { font-variant-numeric: tabular-nums; }

/* ── topbar ───────────────────────────────────────────── */
.topbar {
  border-bottom: 1px solid var(--border-subtle);
  background: var(--bg-base); position: sticky; top: 0; z-index: 40;
}
.topbar-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; height: 46px;
}
.brand { display: flex; align-items: baseline; gap: 9px; min-width: 0; }
.brand .mark {
  width: 9px; height: 9px; border-radius: 2px; background: var(--border-focus);
  align-self: center; flex: none;
}
.brand h1 { margin: 0; font-size: 13px; font-weight: 600; letter-spacing: -.01em; }
.brand-sub { font-size: 11px; color: var(--text-faint); }

.topbar-right { display: flex; align-items: center; gap: 14px; }
.stamp { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.topbar-link { font-size: 11px; color: var(--text-muted); text-decoration: none; }
.topbar-link:hover { color: var(--text-primary); }

/* 라이트/다크 pill 스위치 — 다크: 노브 왼쪽+달 / 라이트: 노브 오른쪽+해 */
.theme-toggle {
  position: relative; flex: none; width: 42px; height: 22px; padding: 0;
  border: 1px solid var(--border-default); border-radius: 999px;
  background: var(--bg-strong); cursor: pointer;
  transition: border-color var(--motion-fast) var(--ease);
}
.theme-toggle:hover { border-color: var(--border-strong); }
.theme-toggle .ico {
  position: absolute; top: 4px; width: 12px; height: 12px;
  color: var(--text-secondary); transition: opacity var(--motion-fast) var(--ease);
}
.theme-toggle .sun { left: 5px; opacity: 0; }
.theme-toggle .moon { right: 5px; opacity: .9; }
.theme-toggle .knob {
  position: absolute; top: 2px; left: 3px; width: 16px; height: 16px;
  border-radius: 999px; background: var(--text-primary);
  box-shadow: 0 1px 3px rgba(0,0,0,.35);
  transition: left 200ms var(--ease);
}
:root[data-theme="light"] .theme-toggle .sun { opacity: .9; }
:root[data-theme="light"] .theme-toggle .moon { opacity: 0; }
:root[data-theme="light"] .theme-toggle .knob { left: 22px; }

/* ── KPI ──────────────────────────────────────────────── */
.kpis {
  display: grid; gap: 1px; margin: 18px 0 16px;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  background: var(--border-subtle);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);
  overflow: hidden;
}
.kpi { background: var(--bg-raised); padding: 12px 15px; }
.kpi-label { display: block; font-size: 11px; color: var(--text-muted); margin-bottom: 5px; }
.kpi-value {
  font-size: 24px; font-weight: 600; line-height: 1.15; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.kpi-value .suffix { font-size: 12px; font-weight: 400; color: var(--text-muted); margin-left: 3px; }
.kpi-note { font-size: 11px; color: var(--text-faint); margin-top: 4px; }
.kpi.is-warn .kpi-value { color: var(--warn); }

/* ── toolbar ──────────────────────────────────────────── */
.toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
.spacer { flex: 1 1 auto; }

.search { position: relative; flex: 0 1 380px; min-width: 220px; }
.search svg {
  position: absolute; left: 9px; top: 50%; translate: 0 -50%;
  width: 13px; height: 13px; fill: var(--text-faint); pointer-events: none;
}
.search input {
  width: 100%; height: 30px; padding: 0 10px 0 28px; font: inherit; font-size: 12px;
  color: var(--text-primary); background: var(--bg-raised);
  border: 1px solid var(--border-default); border-radius: var(--radius-lg);
  transition: border-color var(--motion-fast) var(--ease);
}
.search input::placeholder { color: var(--text-faint); }
.search input:hover { border-color: var(--border-strong); }
.search input:focus { outline: none; border-color: var(--border-focus); }
.search input::-webkit-search-cancel-button { filter: grayscale(1) opacity(.5); }

.toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-muted); cursor: pointer; user-select: none;
}
.toggle:hover { color: var(--text-secondary); }
.toggle input { accent-color: var(--border-focus); width: 13px; height: 13px; margin: 0; }

.linkish {
  background: none; border: 0; padding: 0; font: inherit; font-size: 11px;
  color: var(--accent); cursor: pointer;
}
.linkish:hover { text-decoration: underline; }
.result-count { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* ── table ────────────────────────────────────────────── */
.table-scroll {
  position: relative; overflow: auto; max-height: calc(100vh - 210px);
  background: var(--bg-raised);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);
  overscroll-behavior: contain;
}
/* `collapse` 가 아니라 `separate` 다. `position: sticky` 를 붙인 표 셀은
   `border-collapse: collapse` 와 함께 쓰면 사파리에서 고정 위치가 어긋나 —
   가로로 밀 때 고정 열 자리에 빈 칸이 남는다. 실제로 그 상태가 보고됐다.
   대신 행 구분선을 `tr` 이 아니라 `td` 에 그려야 한다(아래) — `separate` 에서는
   `tr` 의 테두리가 렌더링되지 않는다. */
table { width: 100%; border-collapse: separate; border-spacing: 0; }

thead th {
  position: sticky; top: 0; z-index: 10;
  background: var(--bg-strong); text-align: left; white-space: nowrap;
  font-size: 10.5px; font-weight: 500; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-muted); padding: 0 12px; height: 30px;
  border-bottom: 1px solid var(--border-subtle);
}
thead th.num { text-align: right; }
thead th button {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  cursor: pointer; display: inline-flex; align-items: center; gap: 4px;
  transition: color var(--motion-instant) var(--ease);
}
thead th button:hover { color: var(--text-primary); }
thead th .caret { font-size: 7px; opacity: .75; }
thead th .active-n { color: var(--accent); }
thead th[data-dir="asc"] button,
thead th[data-dir="desc"] button { color: var(--text-primary); }
thead th[data-dir] .arrow { color: var(--accent); }

/* 가로 고정 열 — 폭에 무관하게 건다.
   가로 스크롤은 모바일만의 일이 아니다. 창을 900px 쯤으로 줄이면 데스크탑
   레이아웃에서도 표가 넘쳐 회사명이 왼쪽으로 사라진다. 스크롤이 없는 폭에서는
   `sticky` 가 아무 일도 하지 않으므로 조건을 나눌 이유가 없다.
   헤더 칸은 본문 셀에 덮이지 않도록 z-index 를 한 단 올린다. */
thead th:first-child,
tbody td:first-child { position: sticky; left: 0; }
thead th:first-child { z-index: 20; background: var(--bg-strong); }
tbody td:first-child {
  z-index: 5; background: var(--bg-raised);
  box-shadow: 1px 0 0 var(--border-subtle);
}
tbody tr.row:hover td:first-child,
tbody tr.row.open td:first-child { background: var(--bg-strong); }

tbody tr.row { cursor: pointer; }
tbody tr.row > td { border-bottom: 1px solid var(--border-subtle); }
tbody tr.row:hover { background: var(--bg-hover); }
tbody tr.row.open { background: var(--bg-hover); }
tbody td { padding: 8px 12px; vertical-align: top; font-size: 12px; color: var(--text-secondary); }
tbody td.num {
  text-align: right; font-family: var(--font-mono); font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  /* 좁은 화면에서 `2026-01-19` 가 두 줄로 쪼개지면 행 높이가 들쭉날쭉해진다.
     숫자·날짜는 접지 않고 가로 스크롤에 맡긴다. */
  white-space: nowrap;
}
tbody td.neg { color: var(--bad); }

.name { color: var(--text-primary); font-weight: 500; display: flex; align-items: center; gap: 6px; }
.spac-tag {
  flex: none;
  font-size: 9.5px; font-weight: 500; padding: 1px 4px; border-radius: var(--radius-sm);
  background: var(--neutral-soft); color: var(--text-muted); letter-spacing: .02em;
}
/* 스팩 껍데기는 걸러낼 잡음이라 무채색으로 가라앉히고, 스팩과 합병해 들어오는
   실제 사업회사는 눈에 걸리도록 강조색을 준다 — 후자가 읽을 값이 있는 쪽이다. */
.spac-tag.merge { background: var(--accent-soft); color: var(--accent); }
.product { color: var(--text-faint); font-size: 11px; margin-top: 2px; }

/* ── 넘치는 텍스트 슬라이드 ───────────────────────────
   칸보다 긴 글자는 평소 말줄임으로 두고, hover(데스크탑)/터치(모바일) 시 넘치는
   만큼 좌우로 흘려 전문을 보여준다. stock-screener 의 `NameCell` 과 같은
   동작이며, 이 사이트는 빌드 단계가 없으므로 anime.js 대신 Web Animations API
   로 낸다(`app.js` 의 `bindMarquee`).

   말줄임과 슬라이드는 공존할 수 없다 — `text-overflow` 는 자기 요소가 내용을
   자를 때만 나오므로, 흘리는 동안에는 `.sliding` 이 그 제약을 걷어낸다.
   행 높이를 고정하려면 한 줄 유지가 전제라, `white-space: nowrap` 은 양쪽 상태에
   모두 남는다.
   ───────────────────────────────────────────────────── */
.clip { display: block; overflow: hidden; white-space: nowrap; min-width: 0; }
.clip > .t {
  display: inline-block; max-width: 100%; vertical-align: bottom;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.clip.sliding > .t { max-width: none; overflow: visible; text-overflow: clip; }

.clip.w-name    { max-width: 26ch; }
.clip.w-product { max-width: 32ch; }
.clip.w-induty  { max-width: 24ch; }
.clip.w-uw      { max-width: 16ch; }

.pill {
  display: inline-block; font-size: 10.5px; font-weight: 500; padding: 2px 7px;
  border-radius: 999px; white-space: nowrap;
}
.pill.progress { background: var(--accent-soft); color: var(--accent); }
.pill.ok   { background: var(--ok-soft);   color: var(--ok); }
.pill.warn { background: var(--warn-soft); color: var(--warn); }
.pill.bad  { background: var(--bad-soft);  color: var(--bad); }
.pill.done { background: var(--neutral-soft); color: var(--text-muted); }

.elapsed { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.elapsed .bar { width: 40px; height: 2px; border-radius: 2px; background: var(--border-default); overflow: hidden; }
.elapsed .bar i { display: block; height: 100%; background: var(--accent); }
.elapsed.over .bar i { background: var(--warn); }
.elapsed.over .v { color: var(--warn); }

/* 펼침 행 */
tr.detail > td { background: var(--bg-strong); padding: 0 12px 13px; border-bottom: 1px solid var(--border-subtle); }
.dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 9px 20px; margin: 11px 0 0; }
.dl dt { font-size: 10px; color: var(--text-faint); margin-bottom: 2px; text-transform: uppercase; letter-spacing: .04em; }
.dl dd { margin: 0; font-size: 12px; color: var(--text-secondary); overflow-wrap: anywhere; }
.dl dd .unit { color: var(--text-faint); font-size: 10.5px; }
.dl a { color: var(--accent); }

.empty { text-align: center; color: var(--text-muted); padding: 40px 0; font-size: 12px; }

/* ── 헤더 필터 드롭다운 ───────────────────────────────── */
.filter-menu {
  position: fixed; z-index: 60; width: 210px; max-height: 60vh; overflow: auto;
  padding: 4px; border: 1px solid var(--border-default); border-radius: var(--radius-md);
  background: var(--bg-elevated); box-shadow: var(--shadow-3);
  text-transform: none; letter-spacing: normal;
}
.filter-menu .all {
  width: 100%; text-align: left; padding: 4px 8px; margin-bottom: 2px;
  background: none; border: 0; border-radius: var(--radius-sm);
  font: inherit; font-size: 11px; color: var(--text-muted); cursor: pointer;
}
.filter-menu .all:hover { background: var(--bg-hover); color: var(--text-primary); }
.filter-menu label {
  display: flex; align-items: center; gap: 8px; padding: 4px 8px;
  border-radius: var(--radius-sm); cursor: pointer;
}
.filter-menu label:hover { background: var(--bg-hover); }
.filter-menu input { width: 12px; height: 12px; flex: none; margin: 0; accent-color: var(--border-focus); }
.filter-menu .lbl { flex: 1 1 auto; min-width: 0; font-size: 11px; color: var(--text-secondary); }
.filter-menu .n { flex: none; font-size: 10px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.filter-menu .none { padding: 6px 8px; font-size: 11px; color: var(--text-faint); }

/* ── footer ───────────────────────────────────────────── */
.foot { padding: 20px 20px 40px; font-size: 11px; color: var(--text-muted); }
.foot p { margin: 0 0 4px; }
.foot a { color: var(--accent); }
.foot .faint { color: var(--text-faint); }

/* ── 모바일 ───────────────────────────────────────────
   표는 **가로로만** 움직인다. 컬럼을 감추면 헤더에 달린 필터도 함께 사라지므로
   전부 남기고 옆으로 굴린다. 회사명 열은 왼쪽에 고정해 오른쪽으로 밀어도 어느
   회사인지 잃지 않는다(고정이 어긋나던 원인은 위 `border-collapse` 참조).

   세로는 페이지가 전담한다. 표에 높이를 주면 페이지와 표가 각각 세로로 움직여
   어느 쪽을 미는지 알 수 없고, 안쪽이 러버밴딩하면 헤더 위에 빈 칸이 남는다.
   `visible` 로는 못 끈다 — 한 축이 `auto` 면 다른 축의 `visible` 도 `auto` 로
   계산되므로 `hidden` 이라야 세로 스크롤포트가 사라진다. 높이가 `auto` 라
   잘려 나가는 내용은 없다.
   ───────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .wrap { padding: 0 12px; }

  .table-scroll { max-height: none; overflow-x: auto; overflow-y: hidden; }
  /* 날짜 한 칸(결과확정일)이 늘어난 만큼 바닥값도 올린다. 지금은 아래 `clip` 폭이
     표를 그보다 넓게 잡아 이 값이 걸리지 않지만, 그 폭을 줄이는 날 이것이 날짜가
     눌리는 것을 막는 마지막 선이다. */
  table { min-width: 755px; }

  /* 가로 이동량을 줄인다. 잘린 글자는 탭하면 흐르고, 행을 펼치면 전문이 나온다. */
  .clip.w-name    { max-width: 14ch; }
  .clip.w-product { max-width: 16ch; }
  .clip.w-induty  { max-width: 14ch; }
  .clip.w-uw      { max-width: 10ch; }
  thead th, tbody td { padding-left: 8px; padding-right: 8px; }

  .kpis { grid-template-columns: repeat(2, 1fr); }
  .kpi-value { font-size: 21px; }

  .search { flex: 1 1 100%; min-width: 0; }
  .toolbar { gap: 8px 12px; }
  .result-count { order: -1; }

  /* 상단바가 두 줄로 접히지 않게 군더더기를 뺀다. 시각과 토글은 남긴다 —
     "언제 기준 데이터인가" 는 모바일에서 더 중요하다. */
  .brand-sub, .topbar-link { display: none; }
}



@media (max-width: 420px) {
  .kpis { grid-template-columns: 1fr 1fr; }
  .kpi { padding: 10px 12px; }
  .kpi-value { font-size: 19px; }
  .filter-menu { width: min(210px, calc(100vw - 24px)); }
}

/* 움직임을 줄이도록 설정한 사용자에게는 슬라이드를 걸지 않는다. `app.js` 가 같은
   질의를 확인해 애니메이션을 아예 시작하지 않으므로, 여기서는 혹시 `.sliding` 이
   붙더라도 말줄임이 유지되게만 해 두면 된다. */
@media (prefers-reduced-motion: reduce) {
  .clip.sliding > .t { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
}
