/* nx.css — Fin-Lens 디자인 토큰 + 템플릿 공용 규칙.
 *
 * 왜 이 파일이 있나: tailwind.min.css 는 미리 컴파일된 번들이라 템플릿에서 새
 * 유틸리티 클래스(md:hidden 등)를 쓰면 에러 없이 무시된다. 그래서 화면마다
 * 인라인 <style>(nx-*)이 늘었다. 새 스타일은 여기에 CSS 변수(토큰) 기반으로 둔다
 * — rebuild_css.sh 없이 파일 수정 + 배포만으로 반영된다.
 *
 * 규칙
 *  - 색·크기 값은 --nx-* 토큰으로만 쓴다. 규칙 안에 16진수 색을 직접 쓰지 않는다.
 *  - 토큰 값은 현재 Tailwind slate/indigo 팔레트와 같게 맞춰 두었다(도입만으로
 *    화면이 바뀌지 않게). 색 의미 분리(등락·판정)는 F3, 라이트 테마는 C4 에서 추가.
 *  - 클래스 이름은 nx- 접두어 — Tailwind 클래스와 겹치지 않게.
 *  - 차트(Chart.js)도 finance.html 에서 getComputedStyle 로 이 토큰을 읽는다.
 *  - 캐시버스팅: main.py _compute_asset_version() 이 이 파일의 mtime 도 본다.
 */

:root {
  /* 표면 */
  --nx-bg: #0f172a;                        /* slate-900 — 페이지 바탕 */
  --nx-surface: #1e293b;                   /* slate-800 — 카드 */
  --nx-surface-2: rgba(51, 65, 85, .4);    /* slate-700/40 — 카드 안 타일 */
  --nx-field: #334155;                     /* slate-700 — 입력칸 */

  /* 선 */
  --nx-line: #334155;                      /* slate-700 */
  --nx-line-soft: rgba(51, 65, 85, .5);    /* slate-700/50 — 표 행 구분 */
  --nx-line-strong: rgba(51, 65, 85, .8);  /* 고정 열 경계 */

  /* 글자
   * F4(대비, WCAG AA ≥ 4.5:1): --nx-muted(slate-400)가 카드/타일 위에서 읽는 텍스트에
   * 쓸 수 있는 가장 흐린 색이다(카드 5.71:1, 타일 4.99:1, 입력칸 4.04:1 — 입력칸
   * placeholder 등은 별도 검토 필요). --nx-faint/--nx-ghost는 카드 위 3.07:1 /
   * 1.93:1로 AA 미달이라 더 이상 "읽는 글자"엔 쓰지 않는다 — 테두리·비활성 아이콘
   * 같은 "글자가 아닌 표식"에만 남겨 둔다(예: 레이더 차트에서 결측 축의 빈 점
   * 테두리). 단위·캡션·결측값 "—"·면책 문구는 전부 --nx-muted 이상을 쓴다.
   */
  --nx-text: #f1f5f9;                      /* slate-100 — 본문 */
  --nx-text-2: #cbd5e1;                    /* slate-300 — 제목·표 라벨 */
  --nx-muted: #94a3b8;                     /* slate-400 — 보조. 읽는 텍스트에 쓸 수 있는 최소 밝기(F4) */
  --nx-faint: #64748b;                     /* slate-500 — 비-텍스트 표식 전용(F4 이전엔 단위·캡션에도 썼으나 AA 미달로 중단) */
  --nx-ghost: #475569;                     /* slate-600 — 비-텍스트 표식 전용(F4 이전엔 결측·면책에도 썼으나 AA 미달로 중단) */

  /* 강조(브랜드) */
  --nx-accent: #6366f1;                    /* indigo-500 */
  --nx-accent-strong: #4f46e5;             /* indigo-600 — 주요 버튼 */
  --nx-accent-text: #818cf8;               /* indigo-400 — 링크·활성 메뉴 */

  /* ── 색의 3가지 역할 (F3) ────────────────────────────────────────────
   * 이 화면엔 의미가 다른 색이 세 종류 섞여 있었다 — 그런데 "판정(좋다/나쁘다)"에
   * 쓰던 초록/빨강을 그대로 "가격 등락"에도 쓰면(A1에서 도입 예정) 국내 사용자
   * 기준으로 정반대 색(빨강=상승)과 충돌한다. 그래서 역할을 셋으로 분리해 토큰
   * 이름 자체에 의미를 박아 둔다 — 화면마다 "이 색이 지금 무슨 뜻인지"를 변수명만
   * 보고 알 수 있게, 그리고 같은 색이 한 화면에서 두 의미를 동시에 갖지 않게 한다.
   *  1) 가격 등락(--nx-up/--nx-down/--nx-flat) — 오직 시세·등락률에만 쓴다.
   *  2) 판정(--nx-good/--nx-warn/--nx-bad) — 스코어카드·종합신호 등 "좋다/나쁘다"
   *     평가에만 쓴다. 가격이 오르거나 내린 "사실"과는 다른 축이다.
   *  3) 브랜드 강조(--nx-accent*) — 액션 버튼·활성 탭 등 "지금 누를 수 있는 것".
   *     판정색을 빌려 쓰지 않는다(초록 버튼 = "좋음"으로 오독될 수 있어서).
   * 공통 규칙: 색은 의미를 전달하는 유일한 수단이 되면 안 된다 — 등락은 ▲▼
   * 기호나 +/- 부호가, 판정은 라벨 텍스트(매력적/주의/중립 등)가 항상 함께 있어야
   * 한다(색맹·저채도 화면에서도 의미가 전달되도록).
   */

  /* 가격 등락 — 한국(네이버·토스 관행): 빨강=상승, 파랑=하락. 이 토큰은 F3에서는
     정의만 해 두고 실제 사용은 가격 헤더가 생기는 A1에서 붙인다. 대비값은
     카드(#1e293b) 위 5.29:1 / 타일(surface-2) 위 4.68:1(up), 카드 5.75:1 /
     타일 5.09:1(down) — 본문 텍스트로도 AA 기준을 만족한다. */
  --nx-up: #f87171;                        /* red-400 — 상승(국내 관행) */
  --nx-down: #60a5fa;                      /* blue-400 — 하락(국내 관행) */
  --nx-flat: var(--nx-muted);              /* 보합 — 별도 색 없이 보조 텍스트색 재사용 */

  /* 판정 (스코어카드 등) — 가격 등락 색과는 완전히 분리된 별개 토큰(위 설명 참고) */
  --nx-good: #34d399;                      /* emerald-400 */
  --nx-warn: #fbbf24;                      /* amber-400 */
  --nx-bad: #fb7185;                       /* rose-400 */
  /* 판정 배지용 옅은 배경 — 기존 bg-emerald-900/50 등과 동일한 값(도입만으로 화면 안 바뀜) */
  --nx-good-soft: rgba(6, 78, 59, .5);     /* emerald-900/50 */
  --nx-warn-soft: rgba(120, 53, 15, .5);   /* amber-900/50 */
  --nx-bad-soft: rgba(136, 19, 55, .5);    /* rose-900/50 */

  /* 차트 계열색 — 순서가 곧 기본 계열 순서 */
  --nx-chart-1: #6366f1;                   /* indigo */
  --nx-chart-2: #34d399;                   /* emerald */
  --nx-chart-3: #38bdf8;                   /* sky */
  --nx-chart-4: #fb7185;                   /* rose */
  --nx-chart-5: #a78bfa;                   /* violet */
  --nx-chart-6: #fbbf24;                   /* amber */
  --nx-chart-grid: rgba(148, 163, 184, .12);
  --nx-chart-text: #94a3b8;

  /* 형태 */
  --nx-radius-sm: 4px;
  --nx-radius: 8px;
  --nx-radius-lg: 12px;
  --nx-space-1: 4px;
  --nx-space-2: 8px;
  --nx-space-3: 12px;
  --nx-space-4: 16px;
  --nx-space-6: 24px;

  /* 글자 크기 — Tailwind text-xs/sm/base/lg/xl 과 같은 값(기존 이름 유지, 다른 곳에서
     이미 참조 중이라 이름을 바꾸면 그쪽이 깨진다). 화면 대부분의 크기는 여전히
     Tailwind 유틸리티 클래스(text-sm 등)가 담당하고, 아래 토큰은 F2 타입 스케일
     (12/13/14/16/20/28px)에서 Tailwind 표준 스텝에 없는 값(13px, 28px)이 필요하거나
     nx-* 전용 규칙(표·카드 등)에서 값 하나로 통일해 쓰고 싶을 때만 쓴다. */
  --nx-fs-xs: 12px;
  --nx-fs-sm: 14px;
  --nx-fs-md: 16px;
  --nx-fs-lg: 18px;
  --nx-fs-xl: 20px;
  --nx-fs-13: 13px;   /* Tailwind에 없는 중간 크기 — 표 캡션 등 12/14 사이가 필요할 때 */
  --nx-fs-2xl: 28px;  /* 스케일의 최대값 — 페이지 타이틀급 강조 */
  /* 한국어 가변 폰트(self-host, base.html 참고) — 시스템 폰트는 macOS/iOS(Apple SD
     Gothic Neo), Windows(Malgun Gothic), 그 외(Noto Sans KR)로 나눠 폴백해 폰트가
     아직 로드되기 전이나 로드 실패 시에도 한글이 각 OS 기본 글꼴로는 보이게 한다. */
  --nx-font: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", sans-serif;
}

/* 가격 등락 — 미국 관행(초록=상승, 빨강=하락) 오버라이드. 해외(US) 종목 화면에서
   국내 관행 그대로 쓰면 오히려 현지 사용자·데이터 관성과 어긋난다. 실제로 헤더에
   data-market="us" 를 붙이는 작업은 가격 헤더 자체가 생기는 A1에서 한다 — 지금은
   기본값(국내 관행)만 있고 이 규칙은 켜질 준비만 해 둔 것(A1 전까지는 아무 데도
   data-market 속성이 없어 이 규칙은 매치되지 않는다). */
[data-market="us"] {
  --nx-up: #34d399;                        /* emerald-400 — 상승(미국 관행) */
  --nx-down: #f87171;                      /* red-400 — 하락(미국 관행) */
}

/* body에서만 지정해도 충분하다 — Tailwind preflight가 html{font-family:...}를 주지만
   body는 그 값을 다시 쓰지 않고 상속만 받으므로, 더 구체적인(요소 타입 선택자)
   body 규칙이 그대로 이긴다(상속 재정의이지 우선순위 경쟁이 아님). font-variant-numeric:
   tabular-nums 는 숫자 폭을 고정폭으로 만든다 — 재무 표·타일에서 연도별 숫자가
   세로로 나란히 있을 때 자릿수가 같아도 폭이 들쭉날쭉하면 비교가 어렵다.
   Pretendard Variable은 tnum(고정폭 숫자) 피처를 지원한다. */
body {
  font-family: var(--nx-font);
  font-variant-numeric: tabular-nums;
}

/* ── 키보드 포커스 표시 (F4) ─────────────────────────────────────────
   이 화면들은 마우스 클릭 시엔 :hover 로만 반응하고 키보드로 탭(Tab) 이동할 때
   "지금 어디에 포커스가 있는지" 보여주는 규칙이 없었다 — 키보드로만 조작하는
   사용자(스크린리더 포함)는 링크·버튼을 누르기 전까지 위치를 알 수 없다.
   :focus(마우스 클릭 포함) 대신 :focus-visible(키보드 탐색 등 실제로 필요할 때만
   브라우저가 붙이는 상태)을 써서, 마우스로 클릭했을 땐 링이 안 뜨고 Tab으로
   이동했을 때만 뜨게 한다. input/select/textarea는 Tailwind의 focus:ring-* 로
   이미 자체 포커스 링이 있어 여기 선택자에서 뺐다 — 안 빼면 링이 두 겹으로 겹친다
   (참고: 지금 이 템플릿들엔 input/select/textarea에 tabindex 속성이 없어
   [tabindex] 선택자가 우연히 그것들과 겹칠 일도 없다). */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[role="tab"]:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--nx-accent-text);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ── 준비 중(비활성) 네비 항목 (F4) ─────────────────────────────────
   "수집기 관리"처럼 아직 구현 안 된 메뉴는 예전엔 거의 안 보이는 색(slate-700)으로
   "죽여서" 비활성임을 표시했는데, 그러면 저시력 사용자는 글자 자체를 못 읽는다.
   이제 글자는 읽을 수 있는 색(text-slate-400)을 쓰고, "눌러도 소용없다"는 사실은
   커서 모양 + "준비 중" 칩(.nx-chip-sm, 아래)으로 전달한다. cursor-default 유틸리티가
   prebuilt tailwind.min.css 에 없어(grep 결과 없음) 여기 직접 정의한다. */
.nx-disabled-text { cursor: default; }

/* nx-tag(F3, 중립 칩)와 함께 써서 더 작은 크기가 필요할 때 쓰는 보조 클래스 —
   text-[10px]/px-1.5/py-0.5 조합이 prebuilt tailwind.min.css 에 없어(grep 결과
   없음) 직접 크기를 정의한다. 배경·글자색은 nx-tag가 담당하고 이 클래스는 크기만. */
.nx-chip-sm { font-size: 10px; line-height: 1; padding: 2px 6px; border-radius: 9999px; }

/* ── 색 역할별 클래스 (F3) ───────────────────────────────────────────
   위 :root 의 3역할 설명 참고. 여기 클래스들은 모두 "색만" 담당한다 — 등락은
   ▲▼ 기호, 판정은 라벨 텍스트가 항상 같이 있어야 하며 그건 finance.html(마크업)
   쪽 책임이다. */
.nx-up { color: var(--nx-up); }
.nx-down { color: var(--nx-down); }
.nx-flat { color: var(--nx-flat); }

.nx-judge-good { color: var(--nx-good); }
.nx-judge-warn { color: var(--nx-warn); }
.nx-judge-bad { color: var(--nx-bad); }

/* 스코어카드 종합신호 배지 등 "옅은 배경 + 진한 글자" 조합 — 기존
   bg-emerald-900/50 text-emerald-400 등과 동일한 시각 결과를 낸다. */
.nx-badge-good { background: var(--nx-good-soft); color: var(--nx-good); }
.nx-badge-warn { background: var(--nx-warn-soft); color: var(--nx-warn); }
.nx-badge-bad { background: var(--nx-bad-soft); color: var(--nx-bad); }

/* 중립 카테고리 칩(국내/해외 등) — 판정도 등락도 아닌 "분류표"라 판정색을
   빌리지 않는다. 텍스트(국내/해외)가 의미를 전달하고 색은 그저 칩임을 표시. */
.nx-tag { background: var(--nx-surface-2); color: var(--nx-text-2); }

/* ── 모바일 최근 목록 접기 (finance 최근 조회 · rag 최근 질의) ─────────────
   768px 미만은 가장 최근 1건만 보이고 나머지는 '이전 N건' 버튼으로 펼친다.
   데스크톱(사이드바)은 항상 펼침이고 버튼은 숨긴다. */
.nx-collapse { display: none; }
.nx-collapse.nx-open { display: block; }
@media (min-width: 768px) {
  .nx-collapse { display: block; }
  .nx-more-btn { display: none; }
}

/* ── 매출·현금흐름 표 (finance) ─────────────────────────────────────────
   줄바꿈 금지, 좁은 화면은 글자·여백 축소 + 첫 열 고정. 가로로 넘치면
   .nx-table-scroll 안에서만 스크롤된다. */
.nx-fin-table th,
.nx-fin-table td { white-space: nowrap; }
.nx-fin-table .nx-sticky {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--nx-surface);                  /* 스크롤되는 숫자를 가린다 */
  box-shadow: 1px 0 0 var(--nx-line-strong);      /* 경계선 */
}
/* 스크롤 컨테이너는 카드(p-4 = 패딩 16px)가 아니라 표만 감싸는 이 래퍼여야 한다.
   카드 자체에 overflow-x-auto를 주면 sticky(left:0)는 "카드의 콘텐츠 박스 경계"
   (패딩 안쪽)에 붙는데, 패딩 16px는 스크롤되는 콘텐츠 밖이라 sticky 셀이 덮지
   못한다 — 표를 가로로 드래그하면 스크롤된 다른 열의 숫자가 그 패딩 틈으로
   라벨 열 바로 옆에 비쳐 보인다. 패딩 없는 래퍼를 스크롤 컨테이너로 쓰면
   sticky 경계 = 래퍼(카드 콘텐츠) 경계가 되어 이 틈이 사라진다. */
.nx-table-scroll { overflow-x: auto; }

@media (max-width: 639px) {
  .nx-fin-table { font-size: var(--nx-fs-xs); }
  .nx-fin-table th,
  .nx-fin-table td { padding-left: 6px; padding-right: 6px; }
  .nx-fin-table .nx-sticky { padding-left: 0; }
}

/* ── 시세 경과일 경고 (finance 현재가 타일) ─────────────────────────────
   quote_age_days > 7일 때만 노출되는 작은 경고 문구. 색은 판정 토큰(--nx-warn)
   재사용 — 가격 등락색과는 별개(F3)이므로 새 색을 추가하지 않는다. */
.nx-warn-text { color: var(--nx-warn); font-size: 12px; }

/* ── 주주환원 표 YTD(당해 누적) 열 (finance) ────────────────────────────
   shareholder_ytd는 완결된 회계연도가 아니라 "연초부터 최근 분기보고서까지"의
   부분기간 누적치라, 옆의 FY 칸들과 나란히 두면 1:1 비교 가능한 값처럼
   오인하기 쉽다. 옅은 배경 + 왼쪽 경계선으로 "이 칸만 성격이 다르다"는 걸
   표만 봐도(툴팁·각주를 읽지 않아도) 알 수 있게 한다. */
.nx-ytd-col {
  background: var(--nx-surface-2);
  border-left: 1px solid var(--nx-line);
}

/* ── 자산 관리 트리맵 (portfolio 자산 현황 탭) ─────────────────────────────
   서버(portfolio_calc.treemap_layout)가 계산한 % 좌표로 그룹·종목 칸을 절대 배치한다.
   --nx-pf-c 는 템플릿이 그룹마다 넣는 분류 색(--nx-chart-N). 칸이 작으면 컨테이너 쿼리로
   비중 → 이름 순서로 글자를 숨긴다(칸 title 속성과 분류별 비중 표가 대체 텍스트).
   높이(360px)를 바꾸면 portfolio_calc._TREEMAP_H(가로:세로 = 100:36)도 함께 바꾼다. */
.nx-pf-tm { position: relative; height: 360px; border-radius: 8px; overflow: hidden; background: var(--nx-bg); }
@media (max-width: 640px) { .nx-pf-tm { height: 480px; } }
.nx-pf-g { position: absolute; box-sizing: border-box; border: 1px solid var(--nx-bg); display: flex; flex-direction: column; container-type: size; }
.nx-pf-gh { flex: none; height: 22px; line-height: 20px; padding: 0 6px; font-size: 12px; font-weight: 600; color: var(--nx-text);
         white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-top: 3px solid var(--nx-pf-c);
         background: var(--nx-surface); background: color-mix(in srgb, var(--nx-pf-c) 24%, var(--nx-bg)); }
.nx-pf-gh span { color: var(--nx-text-2); font-weight: 400; margin-left: 4px; }
.nx-pf-gb { position: relative; flex: 1 1 auto; min-height: 0; }
.nx-pf-c { position: absolute; box-sizing: border-box; border: 1px solid var(--nx-bg); overflow: hidden; container-type: size; background: var(--nx-bg); }
.nx-pf-bg { position: absolute; inset: 0; background: var(--nx-pf-c); }
.nx-pf-t { position: relative; padding: 5px 6px; color: var(--nx-text); font-size: 12px; line-height: 1.3; text-shadow: 0 1px 2px rgba(0, 0, 0, .55); }
.nx-pf-n { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nx-pf-w { font-variant-numeric: tabular-nums; }
@container (min-height: 72px) { .nx-pf-n { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } }
@container (max-width: 55px) { .nx-pf-gh span { display: none; } }
@container (max-width: 51px), (max-height: 25px) { .nx-pf-t { display: none; } }
@container (max-width: 75px), (max-height: 45px) { .nx-pf-w { display: none; } }

/* ── 입력 창(모달 대화상자) — 자산 관리 '거래 추가' ───────────────────────────
   평소엔 버튼만 두고, 누르면 <dialog>.showModal() 로 화면 가운데 큰 입력 창을 띄운다.
   배경(::backdrop)은 페이지를 어둡게 가려 입력에 집중하게 한다. 폭은 화면에 맞춰 줄어든다. */
.nx-dialog {
  width: min(760px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 1px solid var(--nx-line);
  border-radius: var(--nx-radius-lg);
  background: var(--nx-surface);
  color: var(--nx-text);
}
.nx-dialog::backdrop { background: rgba(2, 6, 23, .72); }

/* ── AI 뉴스 카드 (ai_news.html) ─────────────────────────────────────
   prebuilt tailwind.min.css 에 없는 유틸리티(line-clamp-1, pt-3, mt-4, py-12,
   shrink-0 — grep 결과 없음)만 여기서 직접 정의한다. 색은 전부 --nx-* 토큰. */

/* 원문 제목(영문)은 한 줄로 자른다. tailwind에 line-clamp-2/3은 있지만 1은 없다. */
.nx-clamp-1 {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 카드 바닥 줄(출처·시각·원문 링크). 위 요약과 시각적으로 분리하되 카드 높이가 달라도
   항상 맨 아래에 붙도록(.mt-auto) 위쪽 여백 + 얇은 구분선만 준다. */
.nx-ainews-foot {
  margin-top: auto;
  padding-top: var(--nx-space-3);
  border-top: 1px solid var(--nx-line-soft);
}

/* "원문 보기 ↗" — 카드 전체가 아니라 이 링크만 클릭 대상이다(키보드 탭 순서가 카드당
   1개로 깔끔하다). 터치 기기에서 누르기 쉽도록 세로 패딩을 넉넉히 준다. */
.nx-ainews-link {
  color: var(--nx-accent-text);
  white-space: nowrap;
  padding: 4px 0;
}
.nx-ainews-link:hover { text-decoration: underline; }

/* 순위 번호 — 칩 옆에 붙는 보조 정보라 작고 muted. 숫자 폭 고정은 body의 tabular-nums. */
.nx-ainews-rank { font-size: var(--nx-fs-xs); color: var(--nx-muted); }

/* 빈 상태 안내 박스 */
.nx-ainews-empty {
  padding: var(--nx-space-6) var(--nx-space-4);
  text-align: center;
  background: var(--nx-surface);
  border-radius: var(--nx-radius-lg);
  color: var(--nx-muted);
}

/* 긴 영문 제목·URL성 문자열이 카드 폭을 밀어 가로 스크롤이 생기는 것을 막는다
   (break-words 유틸리티가 prebuilt 에 없음). */
.nx-ainews-card { overflow-wrap: anywhere; min-width: 0; }

/* ── 종목 헤더 · 히어로 (A1, finance 상단 카드) ──────────────────────────────
   한 장의 카드: 종목명+배지 / 현재가+전일대비 칩 / 52주 범위 / 시가총액·데이터 기준 메타.
   카드 폭(컨테이너)을 기준으로 배치한다 — 같은 PC 화면이라도 왼쪽 '최근 조회' 사이드바 때문에
   본문 폭이 440px(태블릿)~950px(PC)로 달라 뷰포트 미디어쿼리로는 맞지 않는다.
   · 좁은 폭(모바일 375px 포함): 한 열로 쌓는다(이름 → 가격 → 52주 → 메타).
   · 넓은 폭(≥600px): 왼쪽에 이름·가격, 오른쪽에 52주 범위, 아래 한 줄 메타.
   등락색은 --nx-up/--nx-down(국내 관행, 국내·해외 동일). 색만으로 전달하지 않도록 마크업에
   ▲▼ 와 +/− 부호가 항상 같이 있다. 값이 없는 요소는 마크업 단계에서 통째로 빠진다. */

/* 스크린리더 전용 텍스트(prebuilt tailwind 에 sr-only 가 없다). */
.nx-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
         clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

.nx-hero-wrap { container-type: inline-size; }
.nx-hero { background: var(--nx-surface); border-radius: var(--nx-radius-lg); padding: var(--nx-space-4);
           display: grid; grid-template-columns: minmax(0, 1fr); row-gap: var(--nx-space-3); }

/* ① 종목명 + 배지 */
.nx-hero-id { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-width: 0; }
.nx-hero-name { margin: 0; min-width: 0; font-size: 22px; line-height: 1.25; font-weight: 700; color: var(--nx-text);
                word-break: keep-all; overflow-wrap: anywhere; }
.nx-hero-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.nx-hero-badge { font-size: 12px; line-height: 1; font-weight: 500; padding: 4px 8px; border-radius: 9999px; white-space: nowrap; }
.nx-hero-code { letter-spacing: .03em; font-variant-numeric: tabular-nums; }

/* ② 현재가 + 전일대비 */
.nx-hero-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; }
.nx-hero-px { margin: 0; white-space: nowrap; }
.nx-hero-num { font-size: 30px; line-height: 1.1; font-weight: 700; letter-spacing: -.01em; color: var(--nx-text);
               font-variant-numeric: tabular-nums; }
.nx-hero-unit { margin-left: 4px; font-size: 14px; font-weight: 500; color: var(--nx-muted); }
.nx-hero-prev { font-size: 13px; color: var(--nx-muted); white-space: nowrap; }
.nx-hero-prev-v { color: var(--nx-text-2); font-weight: 500; font-variant-numeric: tabular-nums; }

/* 전일 대비 칩 — 히어로·고정 바 공용. 글자색이 곧 등락색(배경은 같은 색을 8%만 깔아 AA 4.5:1 이상 유지 — 카드 위 up 4.75/down 5.02). */
.nx-chg { position: relative; display: inline-flex; align-items: baseline; gap: 4px; padding: 3px 8px;
          border-radius: var(--nx-radius); font-size: 14px; line-height: 1.3; font-weight: 600; white-space: nowrap;
          font-variant-numeric: tabular-nums; }
.nx-chg-ico { font-size: .8em; }
.nx-chg-up { color: var(--nx-up); background: color-mix(in srgb, var(--nx-up) 8%, transparent); }
.nx-chg-down { color: var(--nx-down); background: color-mix(in srgb, var(--nx-down) 8%, transparent); }
.nx-chg-flat { color: var(--nx-flat); background: color-mix(in srgb, var(--nx-muted) 8%, transparent); }

/* ③ 52주 범위 */
.nx-range { min-width: 0; }
.nx-range-title { margin: 0; font-size: 12px; font-weight: 600; color: var(--nx-muted); }
.nx-range-track { position: relative; height: 6px; margin: 12px 7px 10px; border-radius: 9999px; background: var(--nx-line); }
.nx-range-fill { position: absolute; left: 0; top: 0; bottom: 0; width: var(--nx-pos, 0%); border-radius: inherit; background: var(--nx-faint); }
.nx-range-dot { position: absolute; top: 50%; left: var(--nx-pos, 0%); width: 14px; height: 14px; margin: -7px 0 0 -7px;
                box-sizing: border-box; border-radius: 50%; background: var(--nx-text); border: 3px solid var(--nx-surface);
                box-shadow: 0 0 0 1px var(--nx-faint); }
.nx-range-ends { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; line-height: 1.3;
                 color: var(--nx-text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.nx-range-k { font-size: 12px; color: var(--nx-muted); }

/* ④ 시가총액 · 데이터 기준 — 조각마다 nowrap 이라 조각 사이에서만 줄바꿈된다. */
.nx-hero-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 16px; padding-top: var(--nx-space-3);
                border-top: 1px solid var(--nx-line-soft); font-size: 13px; line-height: 1.5; }
.nx-m { white-space: nowrap; }
.nx-m-grp { min-width: 0; color: var(--nx-muted); }
.nx-m-k { color: var(--nx-muted); }
.nx-m-v { color: var(--nx-text-2); font-weight: 600; font-variant-numeric: tabular-nums; }
.nx-m-sub { color: var(--nx-muted); }
.nx-hero-meta .nx-warn-text { font-size: 13px; }

/* 카드 폭 600px 이상 — 2열 배치 + 큰 글자. 52주 범위가 없으면 1열 유지(.nx-hero-norange). */
@container (min-width: 600px) {
  .nx-hero { padding: 20px 24px; column-gap: 32px; row-gap: 14px; grid-template-columns: minmax(0, 1fr) minmax(260px, 340px); }
  .nx-hero-norange { grid-template-columns: minmax(0, 1fr); }
  .nx-hero-id { grid-column: 1; grid-row: 1; }
  .nx-hero-price { grid-column: 1; grid-row: 2; }
  .nx-range { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
  .nx-hero-meta { grid-column: 1 / -1; grid-row: 3; }
  .nx-hero-name { font-size: 26px; }
  .nx-hero-num { font-size: 36px; }
  .nx-hero-unit { font-size: 16px; }
  .nx-hero .nx-chg { font-size: 15px; }
  .nx-hero-meta { font-size: 14px; }
  .nx-hero-meta .nx-warn-text { font-size: 14px; }
}

/* 압축 고정 바 — 히어로가 화면 위로 지나가면 나타난다. fixed 라 레이아웃을 밀지 않는다.
   z-index 40: 본문(자동완성 드롭다운 z-10)보다 위. 상단 메뉴는 고정이 아니라 스크롤되어
   사라진 뒤에만 이 바가 보이므로 메뉴를 덮지 않는다. */
.nx-herobar { position: fixed; top: 0; left: 0; right: 0; z-index: 40; padding-top: env(safe-area-inset-top, 0px);
              margin: 0 !important;   /* 부모 space-y-6 의 형제 간격(margin-top)이 fixed 요소에도 붙어 바가 24px 내려오는 것을 막는다 */
              background: var(--nx-bg); background: color-mix(in srgb, var(--nx-bg) 94%, transparent);
              -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
              border-bottom: 1px solid var(--nx-line);
              transform: translateY(-100%); opacity: 0; visibility: hidden;
              transition: transform .2s ease, opacity .2s ease, visibility 0s linear .2s; }
.nx-herobar.nx-on { transform: none; opacity: 1; visibility: visible; transition-delay: 0s; }
.nx-herobar-in { display: flex; align-items: center; gap: 10px; box-sizing: border-box; min-height: 48px;
                 max-width: calc(80rem + 48px); margin: 0 auto; padding: 6px 16px;
                 padding-left: calc(16px + env(safe-area-inset-left, 0px)); padding-right: calc(16px + env(safe-area-inset-right, 0px)); }
.nx-herobar-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
                   font-size: 15px; font-weight: 600; color: var(--nx-text); }
.nx-herobar-px { flex: none; font-size: 16px; font-weight: 700; color: var(--nx-text); white-space: nowrap;
                 font-variant-numeric: tabular-nums; }
.nx-herobar-unit { margin-left: 3px; font-size: 12px; font-weight: 500; color: var(--nx-muted); }
.nx-herobar .nx-chg { flex: none; padding: 2px 6px; font-size: 13px; }
@media (max-width: 479px) { .nx-herobar .nx-chg-abs { display: none; } }   /* 좁은 폭: 금액 생략, ▲▼+등락률만 */
@media (min-width: 640px) {
  .nx-herobar-in { padding-left: calc(24px + env(safe-area-inset-left, 0px)); padding-right: calc(24px + env(safe-area-inset-right, 0px)); }
  .nx-herobar-name { flex: 0 1 auto; max-width: 40%; }
}
/* 본문 왼쪽에 '최근 조회' 사이드바(256px + 간격 24px)가 있는 폭에서는 바의 내용을 본문 열에 맞춘다. */
@media (min-width: 768px) {
  .nx-herobar-in { padding-left: calc(304px + env(safe-area-inset-left, 0px)); }
}
@media (prefers-reduced-motion: reduce) { .nx-herobar { transition: none; } }

/* ══ 모바일 첫 화면 압축 (A1 후속) ═══════════════════════════════════════════
   목표: 375×812 에서 히어로 전체 + 핵심 요약 시작이 첫 화면에 보이게 한다.
   모든 규칙은 <768px 전용 — 데스크톱(≥768px) 렌더는 기존과 동일해야 한다.
   ─────────────────────────────────────────────────────────────────────── */

/* 모바일에서만 시각적으로 숨기고 스크린리더에는 남기는 텍스트(데스크톱에선 평소처럼 보인다). */
@media (max-width: 767px) {
  .nx-sr-mobile { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
                  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
}

/* ── 전역 상단 메뉴 (base.html) ───────────────────────────────────────────
   1행: 브랜드(왼쪽) + 사용자 영역(오른쪽, 이름은 말줄임), 2행: 메뉴 한 줄 가로 스크롤 띠.
   nx-nav-left 를 display:contents 로 풀어 브랜드·메뉴를 header 그리드에 직접 놓는다. */
@media (max-width: 767px) {
  header.nx-nav {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "brand user" "menu menu";
    align-items: center; gap: 0 var(--nx-space-3);
    padding: 0 var(--nx-space-4);
  }
  header.nx-nav .nx-nav-left { display: contents; }

  .nx-nav-brand { grid-area: brand; font-size: var(--nx-fs-lg); line-height: 1.2; white-space: nowrap;
                  min-height: 44px; display: flex; align-items: center; }

  .nx-nav-user { grid-area: user; gap: 2px; min-width: 0; justify-content: flex-end; }
  .nx-nav-user a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 6px; white-space: nowrap; }
  .nx-nav-who { display: inline-block; min-width: 0; max-width: 6.5em; white-space: nowrap; padding: 0 4px; }
  .nx-nav-name { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* (admin) 등 역할 표기는 화면에선 접고 스크린리더에는 그대로 읽힌다. */
  .nx-nav-role { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
                 clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

  .nx-nav-menu {
    grid-area: menu; position: relative; min-width: 0;
    gap: 0; margin: 0 calc(-1 * var(--nx-space-4));          /* 화면 끝까지 스크롤 영역을 늘린다 */
    padding: 0 var(--nx-space-4);
    border-top: 1px solid var(--nx-line-soft);
    overflow-x: auto; overflow-y: hidden; white-space: nowrap;
    -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
    scrollbar-width: none; -ms-overflow-style: none;
    scroll-padding: 0 var(--nx-space-4);
    /* 오른쪽 가장자리 페이드 = "더 있다" 힌트. 끝까지 스크롤되면(data-end) 끈다. */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
            mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  }
  .nx-nav-menu::-webkit-scrollbar { display: none; }
  .nx-nav-menu[data-end] { -webkit-mask-image: none; mask-image: none; }
  .nx-nav-menu > a,
  .nx-nav-menu > .nx-nav-soon { flex: none; display: inline-flex; align-items: center; min-height: 44px;
                                padding: 0 12px; white-space: nowrap; }
  .nx-nav-menu > a:first-child { padding-left: 0; }
  /* 활성 항목 밑줄 — 색(indigo)만으로 전달하지 않도록 보조 표식. */
  .nx-nav-menu > a[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--nx-accent-text); border-radius: 0; }
  .nx-nav-menu > a[aria-current="page"]:first-child { padding-left: 0; }

  .nx-main { padding: var(--nx-space-4); }
}

/* ── 재무분석 모바일 순서·검색 카드 (finance.html) ──────────────────────────
   · 사이드바(최근 조회)는 본문 뒤로 — 같은 flex 컨테이너의 order 만 바꾼다(마크업·ID 중복 없음).
   · 검색 카드: 1행 입력창 + 분석 버튼, 2행 시장 select + 심층 분석 체크. */
@media (max-width: 767px) {
  .nx-fin-aside { order: 2; }

  .nx-fin-form {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center; gap: var(--nx-space-2) var(--nx-space-2);
    padding: var(--nx-space-3);
  }
  .nx-fin-q { grid-column: 1 / 3; grid-row: 1; min-width: 0; }
  .nx-fin-go { grid-column: 3; grid-row: 1; align-self: end; min-height: 44px; padding: 0 var(--nx-space-4); }
  .nx-fin-mkt { grid-column: 1; grid-row: 2; min-width: 0; }
  .nx-fin-deep { grid-column: 2 / 4; grid-row: 2; min-height: 36px; white-space: nowrap; justify-self: start; }
  .nx-fin-q input { min-height: 44px; }
  .nx-fin-mkt select { min-height: 36px; padding-top: 4px; padding-bottom: 4px; max-width: 100%; }
}

/* ══ 모바일 압축 2차 (finance 읽기성 — 줄바꿈·잘림 최소화) ═══════════════════════════════
   PC(≥768px)는 그대로다. 문구 변형은 템플릿에 짝으로 둔다:
     · .nx-d-only  — PC 원문. PC에선 display:contents(박스 없음 → 레이아웃 불변), 모바일에선 숨김.
     · .nx-m-only  — 모바일 축약형. PC에선 숨김, 모바일에선 인라인.
     · .nx-hide-m  — 원래 요소에 붙여 모바일에서만 숨김(PC 규칙 없음).
   숫자 축약(조원·만주·$B)은 표시값의 정확한 환산이며 원래 값은 title 에 남는다.
   모바일 판정은 JS 쪽도 같은 기준: matchMedia('(max-width: 767.98px)'). */
.nx-d-only { display: contents; }
.nx-m-only { display: none; }
@media (max-width: 767.98px) {
  .nx-d-only,
  .nx-hide-m { display: none !important; }
  .nx-m-only { display: inline; }

  /* 탭: 한 줄 4등분(핵심·실적(연간)·실적(분기)·주주환원), 높이 ≥44px */
  .nx-tabs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
  .nx-tabs .tab-btn { min-height: 44px; padding: 0 2px; font-size: 13px; text-align: center; white-space: nowrap; }

  /* 검색 카드: 1행 = 입력창(늘어남) + 시장 select(콤팩트) + 분석, 2행 = 심층 분석 체크 */
  .nx-fin-form { grid-template-columns: minmax(0, 1fr) auto auto; align-items: end; }
  .nx-fin-q { grid-column: 1; grid-row: 1; }
  .nx-fin-mkt { grid-column: 2; grid-row: 1; }
  .nx-fin-go { grid-column: 3; grid-row: 1; padding: 0 var(--nx-space-3); }
  .nx-fin-deep { grid-column: 1 / -1; grid-row: 2; justify-self: start; }
  .nx-fin-mkt select { min-height: 44px; padding: 0 18px 0 8px; }

  /* 히어로 메타: '기준 09-25 종가 · FY2025 · 25Q4' 는 한 덩어리로 유지 */
  .nx-m-grp-m { white-space: nowrap; }

  /* 요약·밸류에이션 타일: 4열. 라벨·값은 한 줄(넘치면 말줄임 — 전체 값은 title). 값이 가장 큰 글자. */
  .nx-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
  .nx-tile { padding: 6px; min-width: 0; }
  .nx-tile > p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .nx-tile > p:first-child { font-size: 11px; line-height: 1.4; }
  .nx-tile .nx-tile-v { font-size: 15px; line-height: 1.4; }
  .nx-tile .nx-tile-v .text-xs { font-size: 11px; }
  /* 압축 규칙이 없는 금액 단위(예: '백만달러')는 잘리지 않게 단위를 다음 줄로 내린다 */
  .nx-tile .nx-tile-v.nx-tile-long { white-space: normal; overflow: visible; }
  .nx-tile-long .text-xs { display: block; }

  /* 스코어카드 배지 줄바꿈 금지 */
  .nx-score-badge { white-space: nowrap; flex: none; }

  /* 재무 표: 640~767px 도 ≤639px 와 같은 밀도로, 라벨 열 오른쪽 여백 축소 */
  .nx-fin-table { font-size: var(--nx-fs-xs); }
  .nx-fin-table th,
  .nx-fin-table td { padding-left: 6px; padding-right: 6px; }
  .nx-fin-table .nx-sticky { padding-left: 0; padding-right: 8px; }
}

/* ── 인증 화면(L4) — 로그인·가입·비밀번호/아이디 찾기·재설정, 검증계 배너, 약관·방침 목록 ──
   이 화면들(base_auth.html)은 예전에 base.html 을 상속하지 않아 Pretendard·nx.css 도 안
   불러왔고, 사용한 Tailwind 클래스 상당수가 prebuilt tailwind.min.css 에 없어(bg-slate-100,
   text-slate-800, h-px, my-4, space-x-2, mt-6, fixed/top-0/inset-x-0, bg-amber-500/90 …)
   Google 버튼은 배경 없는 글자, "또는" 구분선은 사라진 상태였다. 아래는 그 자리를 채우는
   nx-* 규칙이다. 색은 전부 토큰(--nx-*). 대비는 F4 기준(읽는 글자 ≥ 4.5:1, 입력칸 테두리
   ≥ 3:1)으로 골랐다 — 안내·약관 글자는 slate-500/600 대신 --nx-muted 이상, 입력칸 테두리는
   --nx-faint(카드 위 3.07:1). 카드 위 링크 --nx-accent-text 4.90:1, 주 버튼 흰 글자
   --nx-accent-strong 6.29:1. */
:root {
  /* 밝은 표면 버튼(Google 로그인) — 어두운 카드 위에서 "버튼"으로 읽히게 흰 표면 + 진한 글자.
     글자 #1e293b(slate-800) / 흰색 = 14.6:1. 테두리는 slate-300. */
  --nx-light-surface: #ffffff;
  --nx-light-surface-hover: #f1f5f9;       /* slate-100 */
  --nx-light-text: #1e293b;                /* slate-800 */
  --nx-light-line: #cbd5e1;                /* slate-300 */
  --nx-on-accent: #ffffff;                 /* 주 버튼 글자(흰색) */
  /* 검증계 배너 — 기존 bg-amber-500/90 + border-amber-600 + text-slate-900(이 클래스들도
     prebuilt 에 없어 배너가 안 보이던 상태). 글자는 페이지 바탕색 = 배너 위 6.9:1. */
  --nx-staging: #f59e0b;                   /* amber-500 */
  --nx-staging-line: #d97706;              /* amber-600 */
  --nx-staging-text: #0f172a;              /* 배너 글자 — 배너(amber)가 두 테마 모두 밝아서 항상 어두운 글자(C4: 예전엔 --nx-bg) */
}

.nx-staging-banner {
  width: 100%; box-sizing: border-box; padding: 8px 16px; text-align: center;
  font-size: var(--nx-fs-sm); line-height: 1.5; font-weight: 600; word-break: keep-all;
  color: var(--nx-staging-text); background: color-mix(in srgb, var(--nx-staging) 90%, transparent);
  border-bottom: 1px solid var(--nx-staging-line);
}

.nx-auth-page { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.nx-auth-main { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; padding: 24px 16px; }
.nx-auth-card {
  width: 100%; max-width: 400px; box-sizing: border-box; padding: 32px;
  background: var(--nx-surface); border-radius: var(--nx-radius-lg);
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, .35), 0 4px 6px -4px rgba(0, 0, 0, .35);
  /* 한글은 어절 단위로만 줄바꿈(글자 단위로 끊기지 않게), 긴 토큰(이메일·URL)은 넘치지 않게 */
  word-break: keep-all; overflow-wrap: break-word;
}
.nx-auth-head { margin-bottom: 24px; text-align: center; }
.nx-auth-brand { margin: 0; font-size: 24px; line-height: 1.25; font-weight: 700; color: var(--nx-text); }
.nx-auth-tag { margin: 8px 0 0; font-size: var(--nx-fs-sm); line-height: 1.5; color: var(--nx-muted); text-wrap: balance; }
.nx-auth-title { margin: 20px 0 0; font-size: var(--nx-fs-md); line-height: 1.4; font-weight: 600; color: var(--nx-text-2); }

.nx-auth-form { display: grid; gap: 16px; margin: 0; }
.nx-auth-label { display: block; margin-bottom: 6px; font-size: var(--nx-fs-sm); line-height: 1.4; font-weight: 500; color: var(--nx-text-2); }
.nx-auth-input {
  display: block; width: 100%; box-sizing: border-box; min-height: 44px; padding: 10px 12px;
  font-size: var(--nx-fs-md); /* 16px — iOS 가 포커스 시 화면을 확대하지 않는 최소 크기 */
  line-height: 1.4; color: var(--nx-text); background: var(--nx-field);
  border: 1px solid var(--nx-faint); border-radius: var(--nx-radius);  /* color-scheme 은 :root 에서 상속(C4: 다크/라이트) */
}
.nx-auth-input:focus { outline: 2px solid var(--nx-accent-text); outline-offset: 1px; border-color: var(--nx-accent-text); }
/* 브라우저 자동완성(autocomplete 속성이 맞게 붙으면 자주 뜬다)이 입력칸을 흰/노란 배경 + 검은 글자로
   덮어 어두운 카드 위에서 튀는 것을 막는다. */
.nx-auth-input:-webkit-autofill {
  -webkit-text-fill-color: var(--nx-text); caret-color: var(--nx-text);
  box-shadow: 0 0 0 1000px var(--nx-field) inset;
}
.nx-auth-hint { margin: 6px 0 0; font-size: var(--nx-fs-13); line-height: 1.5; color: var(--nx-muted); }

.nx-auth-check { position: relative; display: flex; align-items: flex-start; gap: 10px; min-height: 44px; }
.nx-auth-check input { flex: none; width: 22px; height: 22px; margin: 11px 0 0; accent-color: var(--nx-accent-strong); }
.nx-auth-check label { padding: 10px 0; font-size: var(--nx-fs-13); line-height: 1.5; color: var(--nx-text-2); }
/* 체크박스 자체는 22px — 라벨의 투명 ::before 로 44x44 터치 영역을 덮는다(탭하면 라벨 → 체크박스 토글) */
.nx-auth-check label::before { content: ""; position: absolute; left: -11px; top: 0; width: 44px; height: 44px; }

.nx-auth-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; box-sizing: border-box; min-height: 44px; padding: 10px 16px; margin: 0;
  font-size: var(--nx-fs-md); line-height: 1.4; font-weight: 600; text-decoration: none; cursor: pointer;
  border: 1px solid transparent; border-radius: var(--nx-radius);
}
.nx-auth-btn-primary { color: var(--nx-on-accent); background: var(--nx-accent-strong); }
/* 호버는 더 어둡게 — 더 밝은 indigo-500 은 흰 글자 대비가 4.47:1 로 AA 미달 */
.nx-auth-btn-primary:hover { background: color-mix(in srgb, var(--nx-accent-strong) 85%, black); }
.nx-auth-btn-google { color: var(--nx-light-text); background: var(--nx-light-surface); border-color: var(--nx-light-line); font-weight: 500; }
.nx-auth-btn-google:hover { background: var(--nx-light-surface-hover); }
.nx-auth-btn-google svg { flex: none; width: 20px; height: 20px; }

/* "또는" 구분선 */
.nx-auth-or { display: flex; align-items: center; gap: 12px; margin: 20px 0; font-size: var(--nx-fs-13); color: var(--nx-muted); }
.nx-auth-or::before, .nx-auth-or::after { content: ""; flex: 1 1 0; height: 1px; background: var(--nx-line); }

/* 오류·안내 상자 — 글자는 --nx-text(카드 위 11.9:1), 종류는 왼쪽 띠 + role 로 구분 */
.nx-auth-alert { margin: 0 0 16px; padding: 10px 12px; font-size: var(--nx-fs-sm); line-height: 1.5; color: var(--nx-text); border-radius: var(--nx-radius); border-left: 4px solid; }
.nx-auth-alert-error { background: var(--nx-bad-soft); border-color: var(--nx-bad); }
.nx-auth-alert-info { background: var(--nx-surface-2); border-color: var(--nx-muted); }

/* 하단 링크·안내 */
.nx-auth-foot { margin: 20px 0 0; font-size: var(--nx-fs-13); line-height: 1.6; color: var(--nx-muted); text-align: center; }
.nx-auth-foot + .nx-auth-foot { margin-top: 4px; }
.nx-auth-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 20px; margin: 12px 0 0; }
/* 단독 링크 — 터치 영역 44px */
.nx-auth-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; font-size: var(--nx-fs-sm); color: var(--nx-accent-text); text-decoration: underline; text-underline-offset: 3px; }
.nx-auth-link:hover { color: var(--nx-text); }
/* 문장 안 링크 — 색에만 의존하지 않게 밑줄 */
.nx-auth-a { color: var(--nx-accent-text); text-decoration: underline; text-underline-offset: 2px; }
.nx-auth-a:hover { color: var(--nx-text); }
.nx-auth-center { text-align: center; }

@media (max-width: 479px) {
  .nx-auth-main { align-items: flex-start; padding: 16px; }
  .nx-auth-card { padding: 24px 20px; }
}

/* 약관·방침 본문 — list-disc/list-inside 가 prebuilt 에 없어 글머리표가 안 보였다 */
.nx-legal { word-break: keep-all; overflow-wrap: break-word; }
.nx-legal-list { list-style: disc; padding-left: 1.25rem; }
.nx-legal-date { color: var(--nx-muted); }
.nx-legal-rev { color: var(--nx-muted); font-size: var(--nx-fs-13); }

/* ══ 1순위 묶음(A5·A3·B3·C1) — finance ═══════════════════════════════════════════════
   A5 밸류에이션 시각화(PER 게이지·목표가 막대) · B3 차트 높이 · C1 빈 상태. 색은 브랜드/중립 토큰만
   (등락·판정색 아님 — '비교'이지 '판단'이 아니다). 모바일(<768px)·PC 모두 같은 마크업. */

/* B3: 차트 컨테이너. PC(≥768px)는 높이를 컨테이너가 정하고(Chart.js maintainAspectRatio:false),
   모바일은 컨테이너 높이 없이 기존 aspectRatio 튜닝을 그대로 쓴다. */
.nx-chart { position: relative; }
@media (min-width: 768px) {
  .nx-chart { height: 300px; }
  .nx-chart.nx-chart-sm { height: 200px; }
}

/* A5: 밸류에이션 시각화 카드 */
.nx-vis-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--nx-space-3); margin-top: var(--nx-space-3); }
@media (min-width: 768px) { .nx-vis-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.nx-vis { background: var(--nx-surface-2); border-radius: var(--nx-radius); padding: 12px 14px; min-width: 0; }
.nx-vis-h { color: var(--nx-muted); font-size: var(--nx-fs-xs); }
.nx-vis-sub { margin-left: 6px; }
.nx-vis-cap { margin-top: 2px; color: var(--nx-text); font-size: var(--nx-fs-sm); line-height: 1.5; }
.nx-vis-cap b { font-weight: 700; }
.nx-nw { white-space: nowrap; }

/* 게이지: 트랙(0 부터) + 채움 + 위/아래 마커. 위 마커=이 종목/현재가(브랜드색), 아래 마커=업종 평균/목표가(중립 밝은색).
   라벨은 좌우 끝에서 잘리지 않게 clamp 로 안쪽으로 밀어 넣는다(틱은 정확한 위치 유지). */
.nx-gauge { position: relative; height: 64px; margin-top: 2px; }
.nx-g-track, .nx-g-fill { position: absolute; top: 28px; height: 8px; border-radius: 4px; }
.nx-g-track { left: 0; right: 0; background: var(--nx-line); }
.nx-g-fill { left: var(--l, 0%); width: var(--w); background: var(--nx-accent); }
.nx-g-fill.nx-g-base { background: var(--nx-faint); }
.nx-g-mk { position: absolute; top: 0; bottom: 0; left: 0; right: 0; pointer-events: none; }
.nx-g-tick { position: absolute; top: 21px; left: var(--p); width: 2px; height: 22px; margin-left: -1px; border-radius: 1px; }
.nx-g-top .nx-g-tick { background: var(--nx-accent-text); }
.nx-g-bot .nx-g-tick { background: var(--nx-text-2); }
.nx-g-lab { position: absolute; left: clamp(46px, var(--p), calc(100% - 46px)); transform: translateX(-50%);
            white-space: nowrap; font-size: var(--nx-fs-xs); line-height: 16px; font-weight: 600; }
.nx-g-top .nx-g-lab { top: 0; color: var(--nx-accent-text); }
.nx-g-bot .nx-g-lab { top: 46px; color: var(--nx-text-2); }

/* C1: 빈 상태 — 예시 칩(≥44px 터치 영역) · 최근 조회 · 3줄 안내 */
.nx-ex-group { margin-top: var(--nx-space-4); }
.nx-ex-k { color: var(--nx-muted); font-size: var(--nx-fs-xs); margin-bottom: 6px; }
.nx-ex-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--nx-space-2); }
.nx-ex-row.nx-ex-recent { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
.nx-ex-f { margin: 0; display: block; }
.nx-chip { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%;
           min-height: 48px; padding: 6px 8px; border-radius: var(--nx-radius); text-align: center; cursor: pointer;
           background: var(--nx-surface-2); border: 1px solid var(--nx-line); color: var(--nx-text);
           transition: background .15s, border-color .15s; }
.nx-chip:hover { border-color: var(--nx-accent); background: rgba(99, 102, 241, .15); }
.nx-chip-n, .nx-chip-c { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nx-chip-n { font-size: var(--nx-fs-sm); font-weight: 600; line-height: 1.3; }
.nx-chip-c { font-size: 11px; line-height: 1.3; color: var(--nx-muted); }
.nx-guide { list-style: none; margin: var(--nx-space-4) 0 0; padding: var(--nx-space-3) 0 0; border-top: 1px solid var(--nx-line);
            display: grid; gap: 6px; font-size: var(--nx-fs-13); color: var(--nx-muted); }
.nx-guide li { display: grid; grid-template-columns: 4.6em minmax(0, 1fr); gap: var(--nx-space-2); }
.nx-guide b { color: var(--nx-text-2); font-weight: 600; }
.nx-empty { word-break: keep-all; overflow-wrap: break-word; }

/* ══ 2순위 묶음(B2·A4·B5·L9) — finance ═══════════════════════════════════════════════════
   B2 표 가독성(YoY 보조 행·최신 열 강조·호버·음수·'—' 사유) · A4 요약 타일 전년比 칩+스파크라인 ·
   B5 스코어카드 쉬운 설명 · L9 공식 출처 링크. 색은 전부 토큰. 등락 색(--nx-up/--nx-down)은 증감·부호에만,
   판정색(--nx-good/--nx-bad)은 스코어카드의 강점/주의에만 쓴다 — 어느 쪽이든 ▲▼·+/−·텍스트가 함께 나간다. */

/* B2: 전년 대비(YoY) 표기 — 표(.nx-yoy 보조 행)와 요약 타일 칩(.nx-tile-chip)이 공유한다 */
.nx-yoy { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.nx-yoy-ico { font-size: .78em; margin-right: 1px; }
.nx-yoy-up { color: var(--nx-up); }
.nx-yoy-down { color: var(--nx-down); }
.nx-yoy-flat { color: var(--nx-muted); }
.nx-na { cursor: help; }

/* B2: 음수는 부호('-')를 유지한 채 하락색을 더한다 */
.nx-neg { color: var(--nx-down); }

/* B2: YoY 보조 행 — 본 행 바로 아래에 붙는 작고 흐린 한 줄. 본 행의 아래 여백을 흡수해 전체 높이 증가를 최소화한다 */
.nx-fin-table .nx-subrow td { padding-top: 0; padding-bottom: 5px; font-size: 11px; line-height: 1.25; }
.nx-fin-table .nx-subrow td.nx-sticky { font-size: 11px; }

/* B2: 최신 열(가장 최근 연도/분기) 은은한 강조 — 머리글은 글자도 한 단계 밝게 */
.nx-fin-table .nx-latest { background: color-mix(in srgb, var(--nx-accent) 9%, transparent); }
.nx-fin-table th.nx-latest { color: var(--nx-text-2); }

/* B2: 행 호버 — 묶음(tbody) 단위. 고정 첫 열은 불투명 배경이므로 호버색을 카드 표면 위에 미리 섞어 쓴다 */
.nx-fin-table tbody.nx-rg:hover > tr > td,
.nx-fin-table tbody:not(.nx-rg) > tr:hover > td { background-color: color-mix(in srgb, var(--nx-text) 5%, transparent); }
.nx-fin-table tbody.nx-rg:hover > tr > td.nx-sticky,
.nx-fin-table tbody:not(.nx-rg) > tr:hover > td.nx-sticky { background-color: color-mix(in srgb, var(--nx-text) 5%, var(--nx-surface)); }
.nx-fin-table tbody.nx-rg:hover > tr > td.nx-latest { background-color: color-mix(in srgb, var(--nx-accent) 13%, transparent); }

/* A4: 요약 타일 — 전년比 칩 + 5개년 스파크라인 */
.nx-tile-trend { margin-top: 2px; }
.nx-tile-chip { margin: 0; font-size: 12px; line-height: 1.4; color: var(--nx-muted); white-space: nowrap; }
.nx-tile-chip .nx-yoy { font-size: 12px; }
.nx-yoy-k { font-size: 11px; }
.nx-tile-spark { margin-top: 3px; line-height: 0; }
.nx-spark { display: block; width: 60px; height: 18px; max-width: 100%; overflow: visible; }
.nx-spark polyline { fill: none; stroke: var(--nx-muted); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.nx-spark circle { fill: var(--nx-text); stroke: var(--nx-surface); stroke-width: 1; }
@media (min-width: 768px) {
  .nx-tile-trend { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; }
  .nx-tile-spark { margin-top: 0; }
}
@media (max-width: 767.98px) {
  .nx-tile-chip { font-size: 11px; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; }
  .nx-tile-chip .nx-yoy { font-size: 11px; }
  /* 375px 4열 타일(안쪽 ≈61px)에는 'YoY ▲13.3%' 가 들어가지 않는다 — 접두어는 빼고(전체 문구는 칩 title·스크린리더 텍스트),
     스파크라인은 첫 화면 높이를 아끼려고 PC 전용으로 둔다(보이게 하려면 아래 한 줄만 지우면 된다). */
  .nx-yoy-k { display: none; }
  .nx-tile-spark { display: none; }
}

/* B5: 스코어카드 — 레이더 + 강점/주의 체크리스트, 축별 한 줄 설명 */
.nx-sc-top { display: block; }
.nx-sc-check { margin: 0 0 12px; display: grid; gap: 10px; }
.nx-sc-grp ul { margin-top: 4px; display: grid; gap: 2px; }
.nx-sc-h { margin: 0; font-size: var(--nx-fs-13); font-weight: 700; }
.nx-sc-n { font-weight: 500; opacity: .85; }
.nx-sc-grp li { font-size: var(--nx-fs-sm); line-height: 1.5; color: var(--nx-text-2); }
.nx-sc-mk { display: inline-block; width: 1.3em; font-weight: 700; }
.nx-sc-tail { color: var(--nx-muted); font-size: var(--nx-fs-xs); }
.nx-sc-none { margin: 0; font-size: var(--nx-fs-xs); color: var(--nx-muted); }
.nx-sc-ex td { padding: 0 0 8px; font-size: var(--nx-fs-xs); line-height: 1.5; color: var(--nx-muted); }
.nx-sc-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin: 0 6px 1px 1px; vertical-align: middle; }
.nx-sc-dot-good { background: var(--nx-good); }
.nx-sc-dot-warn { background: var(--nx-warn); }
.nx-sc-dot-bad { background: var(--nx-bad); }
.nx-sc-dot-na { background: var(--nx-faint); }
@media (min-width: 768px) {
  .nx-sc-top { display: grid; grid-template-columns: 330px minmax(0, 1fr); column-gap: 28px; align-items: center; }
  .nx-sc-check { margin: 0 0 12px; }
}

/* L9: 출처 — 공식 원문 링크('자세한 출처' 접기는 2026-10-17 삭제) */
.nx-src-links { display: grid; gap: 6px; font-size: var(--nx-fs-sm); line-height: 1.5; }
.nx-src-k { color: var(--nx-muted); }
.nx-src-link { color: var(--nx-accent-text); text-decoration: underline; text-underline-offset: 2px; word-break: keep-all; overflow-wrap: anywhere; }
.nx-src-link:hover { color: var(--nx-text); }
.nx-src-ico { font-size: .85em; }

/* B2: 표 안의 .nx-sr(스크린리더 전용, position:absolute) 가 가로 스크롤 영역 밖으로 새어 페이지 가로 스크롤을
   만들지 않도록, 스크롤 래퍼를 기준 위치로 삼아 안에서 잘리게 한다. */
.nx-table-scroll { position: relative; }
/* 모바일(<768px) 표의 YoY 칸은 '%' 기호를 줄여 5개년 연간 표가 375px 에 그대로 들어가게 한다(라벨이 'YoY%', ▲▼ 부호는 유지).
   칩(.nx-tile-chip)에는 적용하지 않는다. */
@media (max-width: 767.98px) {
  .nx-fin-table .nx-pct { display: none; }
}

/* ══ L8 못 찾은 종목 · L10 HTML 오류 화면 ═══════════════════════════════════════════════
   [승격 방법] 이 블록 전체를 webapp/static/nx.css 맨 끝에 붙인다(이 파일은 draft 전용이라 승격 뒤 삭제).
   색·크기는 전부 --nx-* 토큰. 터치 대상 ≥44px, 한글은 어절 단위로만 줄바꿈(keep-all). */

/* L8: 못 찾은 종목 (templates/finance_unresolved.html) */
.nx-unres { word-break: keep-all; overflow-wrap: break-word; }
.nx-unres-h { overflow-wrap: anywhere; }            /* 긴 검색어가 카드를 밀어내지 않게 */

.nx-cand-lead { margin: 0 0 var(--nx-space-3); font-size: var(--nx-fs-13); line-height: 1.5; color: var(--nx-muted); }
.nx-cand-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--nx-space-2); }
@media (min-width: 768px) { .nx-cand-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.nx-cand-f { margin: 0; display: block; }
.nx-cand { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: var(--nx-space-3);
           width: 100%; min-height: 56px; box-sizing: border-box; padding: 8px var(--nx-space-3); margin: 0;
           font: inherit; text-align: left; cursor: pointer; color: var(--nx-text);
           background: var(--nx-surface-2); border: 1px solid var(--nx-line); border-radius: var(--nx-radius);
           transition: background .15s, border-color .15s; }
.nx-cand:hover { border-color: var(--nx-accent); background: rgba(99, 102, 241, .15); }
.nx-cand-main { display: block; min-width: 0; }
.nx-cand-n, .nx-cand-c { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nx-cand-n { font-size: var(--nx-fs-sm); font-weight: 600; line-height: 1.4; color: var(--nx-text); }
.nx-cand-c { font-size: var(--nx-fs-xs); line-height: 1.4; color: var(--nx-muted); }
.nx-cand-mk { flex: none; padding: 2px 8px; font-size: var(--nx-fs-xs); line-height: 1.5; white-space: nowrap;
              color: var(--nx-text-2); background: var(--nx-surface); border: 1px solid var(--nx-line); border-radius: 9999px; }
.nx-cand-go { flex: none; font-size: var(--nx-fs-sm); font-weight: 600; white-space: nowrap; color: var(--nx-accent-text); }
.nx-cand-go::after { content: " ›"; }

.nx-unres-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--nx-space-3); margin: 0; }
.nx-unres-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; box-sizing: border-box;
                padding: 0 var(--nx-space-4); margin: 0; font: inherit; font-size: var(--nx-fs-sm); font-weight: 600;
                text-decoration: none; cursor: pointer; border: 1px solid transparent; border-radius: var(--nx-radius); }
.nx-unres-btn-primary { color: var(--nx-on-accent); background: var(--nx-accent-strong); }
.nx-unres-btn-primary:hover { background: color-mix(in srgb, var(--nx-accent-strong) 85%, black); }
/* 비용이 드는 동작 = 판정 토큰(warn) — 일반 주 버튼(accent)과 한눈에 구분 */
.nx-unres-btn-warn { color: var(--nx-warn); background: var(--nx-warn-soft); border-color: var(--nx-warn); }
.nx-unres-btn-warn:hover { background: color-mix(in srgb, var(--nx-warn-soft) 70%, var(--nx-warn)); color: var(--nx-text); }
.nx-unres-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--nx-space-2);
                 font-size: var(--nx-fs-sm); color: var(--nx-muted); text-decoration: underline; text-underline-offset: 3px; }
.nx-unres-link:hover { color: var(--nx-text); }
@media (max-width: 479px) {
  .nx-unres-actions > .nx-unres-btn-primary { width: 100%; }
}

/* L10: 오류 화면 (templates/error.html) */
.nx-err { max-width: 28rem; margin: 48px auto 0; text-align: center; word-break: keep-all; overflow-wrap: break-word; }
.nx-err-code { margin: 0; font-size: var(--nx-fs-2xl); line-height: 1.2; font-weight: 700; letter-spacing: .04em; color: var(--nx-muted); }
.nx-err-title { margin: 8px 0 0; font-size: var(--nx-fs-xl); line-height: 1.35; font-weight: 600; color: var(--nx-text); text-wrap: balance; }
.nx-err-msg { margin: 12px 0 0; font-size: var(--nx-fs-sm); line-height: 1.6; color: var(--nx-text-2); }
.nx-err-hint { margin: 16px 0 0; padding: 12px 14px; text-align: left; font-size: var(--nx-fs-13); line-height: 1.6;
               color: var(--nx-muted); background: var(--nx-surface); border-radius: var(--nx-radius); }
.nx-err-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--nx-space-3); margin-top: var(--nx-space-6); }
.nx-err-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; box-sizing: border-box;
              padding: 0 var(--nx-space-6); font-size: var(--nx-fs-md); font-weight: 600; text-decoration: none;
              border: 1px solid transparent; border-radius: var(--nx-radius); }
.nx-err-btn-primary { color: var(--nx-on-accent); background: var(--nx-accent-strong); }
.nx-err-btn-primary:hover { background: color-mix(in srgb, var(--nx-accent-strong) 85%, black); }
@media (max-width: 479px) {
  .nx-err { margin-top: var(--nx-space-6); }
  .nx-err-btn { width: 100%; }
}

/* ══ L3 랜딩·타일 잘림 ═══════════════════════════════════════════════════════════════════
   타일 잘림: 모바일 4열 타일(안쪽 ≈61px)에서 긴 값('-5,849억'·'1,157 배')이 말줄임으로 잘리지 않게, 템플릿이
   표시 문자열 길이로 붙이는 클래스(finance.html tsz)로 글자 크기를 한 단계씩 줄인다. PC 는 영향 없음. */
@media (max-width: 767.98px) {
  .nx-tile .nx-tile-v.nx-tile-sm { font-size: 13px; }
  .nx-tile .nx-tile-v.nx-tile-xs { font-size: 11.5px; }
  .nx-tile .nx-tile-v.nx-tile-xxs { font-size: 10px; }
  .nx-tile .nx-tile-v.nx-tile-sm .text-xs,
  .nx-tile .nx-tile-v.nx-tile-xs .text-xs,
  .nx-tile .nx-tile-v.nx-tile-xxs .text-xs { font-size: 10px; }
}

/* 랜딩(비로그인 첫 화면, templates/landing.html) — 한글은 어절 단위로만 줄바꿈, 긴 토큰은 넘치지 않게.
   모바일 먼저: 1열 · 버튼 전폭(≥48px) · 스크린샷 세로 배치. ≥640 카드 2열, ≥960 카드 4열·스크린샷 가로 배치. */
.nx-land { max-width: 1080px; margin: 0 auto; word-break: keep-all; overflow-wrap: break-word; }
.nx-land :where(h1, h2, h3, p) { margin: 0; }

.nx-land-hero { padding: 24px 0 8px; text-align: center; }
.nx-land-eyebrow {
  display: inline-block; max-width: 100%; box-sizing: border-box; padding: 6px 14px;
  font-size: var(--nx-fs-13); line-height: 1.4; font-weight: 600; color: var(--nx-accent-text);
  border: 1px solid var(--nx-line); border-radius: 9999px;
}
.nx-land-h1 {
  margin: 20px auto 0; max-width: 16em; font-size: 28px; line-height: 1.3; font-weight: 800;
  color: var(--nx-text); text-wrap: balance;
}
.nx-land-sub {
  margin: 16px auto 0; max-width: 34em; font-size: var(--nx-fs-md); line-height: 1.7;
  color: var(--nx-text-2); text-wrap: balance;
}
.nx-land-cta { display: flex; flex-direction: column; align-items: stretch; gap: 12px; max-width: 360px; margin: 28px auto 0; }
.nx-land-btn {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  min-height: 48px; padding: 0 28px; font-size: var(--nx-fs-md); line-height: 1.4; font-weight: 600;
  text-decoration: none; border: 1px solid transparent; border-radius: var(--nx-radius);
}
.nx-land-btn-primary { color: var(--nx-on-accent); background: var(--nx-accent-strong); }
.nx-land-btn-primary:hover { background: color-mix(in srgb, var(--nx-accent-strong) 85%, black); }
.nx-land-btn-ghost { color: var(--nx-text); border-color: var(--nx-faint); background: transparent; }
.nx-land-btn-ghost:hover { background: var(--nx-surface); }

.nx-land-sec { margin-top: 56px; }
.nx-land-h2 { font-size: var(--nx-fs-xl); line-height: 1.4; font-weight: 700; color: var(--nx-text); text-align: center; text-wrap: balance; }
.nx-land-lead { max-width: 40em; margin: 12px auto 0; font-size: var(--nx-fs-sm); line-height: 1.7; color: var(--nx-muted); text-align: center; text-wrap: balance; }

/* 스크린샷: 모바일은 휴대폰 화면 → PC 화면 순서로 세로, ≥960 은 PC 화면(넓게) + 휴대폰 화면(260px) 가로 */
.nx-land-shots { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; margin-top: 24px; }
.nx-land-shot { margin: 0; min-width: 0; }
.nx-land-shot img {
  display: block; width: 100%; height: auto; box-sizing: border-box;
  border: 1px solid var(--nx-line); border-radius: var(--nx-radius-lg); background: var(--nx-surface);
}
.nx-land-shot figcaption { margin-top: 8px; font-size: var(--nx-fs-13); line-height: 1.4; color: var(--nx-muted); text-align: center; }
.nx-land-shot-m { width: 100%; max-width: 280px; margin-left: auto; margin-right: auto; }
.nx-land-cap { margin-top: 16px; font-size: var(--nx-fs-13); line-height: 1.5; color: var(--nx-muted); text-align: center; }

.nx-land-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; margin: 24px 0 0; padding: 0; list-style: none; }
.nx-land-src { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; margin-top: 24px; }
.nx-land-card { box-sizing: border-box; min-width: 0; padding: 16px 18px; background: var(--nx-surface); border-radius: var(--nx-radius-lg); }
.nx-land-card h3 { font-size: var(--nx-fs-md); line-height: 1.4; font-weight: 700; color: var(--nx-text); }
.nx-land-card p { margin-top: 6px; font-size: var(--nx-fs-sm); line-height: 1.65; color: var(--nx-text-2); }

.nx-land-final { padding: 32px 16px 36px; background: var(--nx-surface); border-radius: var(--nx-radius-lg); }
.nx-land-final .nx-land-cta { margin-top: 24px; }

.nx-land-foot { margin-top: 48px; padding-top: 20px; border-top: 1px solid var(--nx-line); text-align: center; }
.nx-land-disc { max-width: 44em; margin: 0 auto; font-size: var(--nx-fs-13); line-height: 1.7; color: var(--nx-muted); }
.nx-land-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 12px; margin-top: 8px; }
.nx-land-links a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 8px;
  font-size: var(--nx-fs-sm); color: var(--nx-accent-text); text-decoration: underline; text-underline-offset: 3px;
}
.nx-land-links a:hover { color: var(--nx-text); }

@media (min-width: 640px) {
  .nx-land-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
  .nx-land-src { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
  .nx-land-cta { flex-direction: row; justify-content: center; max-width: none; }
  .nx-land-btn { min-width: 180px; }
  .nx-land-final { padding: 40px 24px 44px; }
}
@media (min-width: 960px) {
  .nx-land-hero { padding: 64px 0 8px; }
  .nx-land-h1 { margin-top: 24px; font-size: 44px; line-height: 1.25; }
  .nx-land-sub { margin-top: 20px; font-size: var(--nx-fs-lg); }
  .nx-land-cta { margin-top: 36px; }
  .nx-land-sec { margin-top: 88px; }
  .nx-land-h2 { font-size: 26px; }
  .nx-land-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .nx-land-shots { grid-template-columns: minmax(0, 1fr) 260px; align-items: end; gap: 32px; margin-top: 32px; }
  .nx-land-shot-d { order: 1; }
  .nx-land-shot-m { order: 2; max-width: none; margin: 0; }
}

/* ── 맨 위로 버튼(랜딩) — 2026-10-17 사용자 요청: 오른쪽 아래 플로팅. 첫 화면(가입 버튼)이 화면 밖으로
   나가면 나타난다(landing.html 스크립트가 hidden 토글). 홈 표시줄·노치를 피하도록 safe-area 를 더한다. */
.nx-totop {
  position: fixed;
  right: calc(16px + env(safe-area-inset-right, 0px));
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  border: 1px solid var(--nx-line);
  background: var(--nx-accent-strong);
  color: var(--nx-on-accent, #ffffff);
  box-shadow: 0 6px 18px rgba(2, 6, 23, .45);
  cursor: pointer;
}
.nx-totop:hover { background: var(--nx-accent); }
.nx-totop:focus-visible { outline: 2px solid var(--nx-accent-text); outline-offset: 3px; }
.nx-totop[hidden] { display: none; }
@media (min-width: 768px) {
  .nx-totop { right: calc(24px + env(safe-area-inset-right, 0px)); bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }
}

/* ══ C3·B4·C2 — 검색 자동완성 · 탭 접근성 · 분석 진행 단계 (finance.html) ═══════════════════════════════
   이 블록의 색은 전부 아래 --nx-* 토큰(라이트 테마 C4 에서 값만 바꾸면 된다)을 통한다. 규칙 안에 16진수 색은 없다.
   모바일 판정은 다른 규칙과 같은 767.98px. */
:root {
  /* C3 자동완성 목록(바탕은 입력칸과 같은 --nx-field) — 호버·활성 행 */
  --nx-sg-hover: #475569;                  /* slate-600 */
  --nx-sg-on: #475569;
  --nx-sg-badge-line: var(--nx-ghost);
  /* C2 진행 배너(예전 bg-indigo-900/40 · border-indigo-700 · text-indigo-100 과 같은 값) */
  --nx-job-bg: rgba(49, 46, 129, .4);
  --nx-job-line: #4338ca;                  /* indigo-700 */
  --nx-job-text: #e0e7ff;                  /* indigo-100 */
  --nx-job-muted: #a5b4fc;                 /* indigo-300 — 대기 단계 글자 */
  --nx-job-track: #6366f1;                 /* 대기 단계 선(점선) */
  --nx-job-done: #818cf8;                  /* 완료·진행 단계 선 */
  /* C2 스켈레톤 */
  --nx-skel: rgba(71, 85, 105, .45);       /* slate-600/45 */
  --nx-skel-shine: rgba(148, 163, 184, .16);
}

/* ── C3: 자동완성 ─────────────────────────────────────────────────────────── */
.nx-sg-row { display: flex; align-items: center; justify-content: space-between; gap: var(--nx-space-3);
             min-height: 44px; padding: var(--nx-space-2) var(--nx-space-3); cursor: pointer; }
.nx-sg-row:hover { background: var(--nx-sg-hover); }
/* 활성(키보드) 행: 배경 + 왼쪽 막대 — 색만으로 구분하지 않는다. */
.nx-sg-row.nx-sg-on { background: var(--nx-sg-on); box-shadow: inset 3px 0 0 var(--nx-accent-text); }
.nx-sg-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.nx-sg-name, .nx-sg-meta { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nx-sg-name { font-size: var(--nx-fs-sm); line-height: 1.35; color: var(--nx-text-2); }
.nx-sg-meta { font-size: var(--nx-fs-xs); line-height: 1.35; color: var(--nx-text-2); }
.nx-sg-hit { font-weight: 700; color: var(--nx-text); }
.nx-sg-badge { flex: none; font-size: 11px; line-height: 1.4; padding: 2px 8px; border-radius: var(--nx-radius-sm);
               box-shadow: inset 0 0 0 1px var(--nx-sg-badge-line); white-space: nowrap; }
.nx-sg-empty { cursor: default; justify-content: flex-start; color: var(--nx-text-2); font-size: 13px;
               line-height: 1.5; word-break: keep-all; overflow-wrap: break-word; }
.nx-sg-empty:hover { background: transparent; }
/* '/' 단축키 힌트: PC 에서 입력칸이 비어 있고 포커스가 없을 때만. 터치 기기·모바일에선 숨긴다. */
.nx-fin-q .nx-kbd { position: absolute; right: 10px; bottom: 9px; min-width: 20px; height: 22px; padding: 0 5px;
                    display: inline-flex; align-items: center; justify-content: center; font: inherit; font-size: 12px;
                    color: var(--nx-muted); border: 1px solid var(--nx-ghost); border-radius: var(--nx-radius-sm);
                    pointer-events: none; }
.nx-fin-q input:focus ~ .nx-kbd,
.nx-fin-q input:not(:placeholder-shown) ~ .nx-kbd { display: none; }
@media (max-width: 767.98px), (hover: none) { .nx-fin-q .nx-kbd { display: none; } }
@media (min-width: 768px) { .nx-fin-q input { padding-right: 40px; } .nx-sg-row { min-height: 40px; } }
/* 모바일: 입력칸 칸(1열)이 좁아 목록이 말줄임투성이가 되므로, 목록은 검색 카드 전체 폭으로 편다. */
@media (max-width: 767.98px) {
  .nx-fin-form { position: relative; }
  .nx-fin-q { position: static; }
  .nx-sg { left: var(--nx-space-3); right: var(--nx-space-3); width: auto; }
}

/* ── B4: 탭 ─────────────────────────────────────────────────────────────────
   활성 탭은 채움(색) 외에 아래쪽 굵은 막대로도 구분한다(색맹·흑백에서도 보인다). 키보드 포커스 링 분리. */
.nx-tabs .tab-btn[aria-selected="true"] { box-shadow: inset 0 -3px 0 var(--nx-on-accent); }
.nx-tabs .tab-btn:focus-visible { outline: 2px solid var(--nx-accent-text); outline-offset: 2px; }

/* ── C2: 분석 진행 배너 · 단계 · 결과 자리 스켈레톤 ─────────────────────────── */
.nx-job { background: var(--nx-job-bg); border: 1px solid var(--nx-job-line); color: var(--nx-job-text);
          border-radius: var(--nx-radius-lg); padding: var(--nx-space-3) var(--nx-space-4); font-size: var(--nx-fs-sm); }
.nx-job-head { display: flex; align-items: center; gap: var(--nx-space-3); }
.nx-job-dot { flex: none; width: 12px; height: 12px; border-radius: 9999px; background: var(--nx-job-done); }
.nx-job-msg { margin: 0; min-width: 0; word-break: keep-all; overflow-wrap: break-word; }
.nx-job-steps { list-style: none; margin: var(--nx-space-3) 0 0; padding: 0; display: grid;
                grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--nx-space-2); }
.nx-job-steps[hidden] { display: none; }
.nx-job-step { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "ico lab" ". st";
               column-gap: 6px; row-gap: 0; align-items: baseline; padding-top: var(--nx-space-2);
               border-top: 3px solid var(--nx-job-done); color: var(--nx-job-text); }
.nx-job-ico { grid-area: ico; font-size: var(--nx-fs-xs); line-height: 1.5; }
.nx-job-lab { grid-area: lab; font-size: var(--nx-fs-13); line-height: 1.5; word-break: keep-all; }
.nx-job-st { grid-area: st; font-size: 11px; line-height: 1.4; color: var(--nx-job-muted); }
/* 대기=점선 · 완료=실선 · 진행 중=굵은 글씨+깜빡이는 선 — 선 모양·아이콘(✓ ● ○)·글자 굵기·'완료/진행 중/대기' 글자가 같이 간다. */
.nx-job-step[data-state="todo"] { border-top-style: dashed; border-top-color: var(--nx-job-track); color: var(--nx-job-muted); }
.nx-job-step[data-state="current"] .nx-job-lab { font-weight: 700; }
.nx-job-step[data-state="current"] { animation: nx-job-pulse 1.6s ease-in-out infinite; }
@keyframes nx-job-pulse { 50% { border-top-color: var(--nx-job-track); } }
@media (max-width: 767.98px) {
  /* 4열(칸 ≈75px): 위 줄 아이콘+상태, 아래 줄 단계 이름 */
  .nx-job-step { grid-template-areas: "ico st" "lab lab"; column-gap: 4px; }
  .nx-job-lab { font-size: var(--nx-fs-xs); }
}

.nx-skel-wrap { display: grid; gap: var(--nx-space-6); }
.nx-skel { display: block; position: relative; overflow: hidden; background: var(--nx-skel); border-radius: var(--nx-radius); }
.nx-skel::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
                  background: linear-gradient(90deg, transparent, var(--nx-skel-shine), transparent);
                  animation: nx-skel-shine 1.5s ease-in-out infinite; }
@keyframes nx-skel-shine { to { transform: translateX(100%); } }
.nx-skel-hero { display: grid; gap: var(--nx-space-3); background: var(--nx-surface);
                border-radius: var(--nx-radius-lg); padding: var(--nx-space-4); }
.nx-skel-name { height: 26px; width: 45%; }
.nx-skel-price { height: 36px; width: 35%; }
.nx-skel-range { height: 10px; width: 100%; }
.nx-skel-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--nx-space-3);
                 background: var(--nx-surface); border-radius: var(--nx-radius-lg); padding: var(--nx-space-4); }
.nx-skel-tile { height: 68px; }
@media (min-width: 640px) { .nx-skel-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 767.98px) { .nx-skel-tile { height: 52px; } }
@media (prefers-reduced-motion: reduce) {
  .nx-skel::after { animation: none; }
  .nx-job-step[data-state="current"] { animation: none; }
}
/* ══ /C3·B4·C2 ═════════════════════════════════════════════════════════════════════════════════ */

/* ══ C5 헤더 — 로고 · 사용자 메뉴(드롭다운) · 비로그인 링크/테마 버튼 (base.html, base_auth.html) ═══════════════
   색은 전부 --nx-* 토큰 → 라이트 테마(C4)에서 값만 바뀐다. 터치 대상은 모바일 44px, 데스크톱 40px.
   모바일(<768px)의 2행 헤더 구조(nx-nav-*)와 높이(≈90px)는 그대로 — 1행 안에서만 폭을 쓴다. */
:root {
  color-scheme: dark;                      /* 스크롤바·기본 폼 컨트롤·자동완성이 테마를 따르게(C4) */
  --nx-hover: rgba(148, 163, 184, .14);    /* 메뉴 항목·아이콘 버튼 호버 */
  --nx-shadow-pop: 0 10px 24px rgba(2, 6, 23, .45), 0 2px 6px rgba(2, 6, 23, .35);   /* 떠 있는 패널 */
}

/* 로고 + 서비스 이름 = 홈 링크. 파비콘과 같은 모양(인디고 사각형 + 상승 막대 3개). */
.nx-brand-link { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: inherit; text-decoration: none;
                 border-radius: var(--nx-radius); }
.nx-brand-link:hover .nx-brand-name { color: var(--nx-accent-text); }
.nx-brand-link:focus-visible { outline: 2px solid var(--nx-accent-text); outline-offset: 2px; }
.nx-logo { display: block; flex: none; width: 28px; height: 28px; }
.nx-logo-bg { fill: var(--nx-accent-strong); }
.nx-logo-bar { fill: var(--nx-on-accent); }
.nx-brand-name { white-space: nowrap; }

/* 사용자 영역 */
.nx-nav-user { position: relative; }
.nx-umenu { position: relative; }
.nx-umenu > summary { list-style: none; }
.nx-umenu > summary::-webkit-details-marker { display: none; }
.nx-umenu-btn { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; max-width: 100%; box-sizing: border-box;
                padding: 4px 10px 4px 6px; border: 1px solid var(--nx-line); border-radius: 999px; background: var(--nx-surface);
                color: var(--nx-text-2); font-size: var(--nx-fs-sm); line-height: 1.2; cursor: pointer; user-select: none;
                -webkit-tap-highlight-color: transparent; }
.nx-umenu-btn:hover { border-color: var(--nx-faint); }
.nx-umenu[open] > .nx-umenu-btn { border-color: var(--nx-accent-text); }
.nx-umenu-btn:focus-visible { outline: 2px solid var(--nx-accent-text); outline-offset: 2px; }
/* 내 정보 화면에 있을 때 버튼도 활성 표시(색 + 테두리 — 색만으로 전달하지 않는다) */
.nx-umenu-cur { border-color: var(--nx-accent-text); color: var(--nx-accent-text); }
.nx-avatar { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
             border-radius: 50%; background: var(--nx-accent-strong); color: var(--nx-on-accent);
             font-size: var(--nx-fs-13); font-weight: 700; line-height: 1; }
.nx-umenu-name { min-width: 0; max-width: 10em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nx-umenu-chev { flex: none; transition: transform .15s ease; }
.nx-umenu[open] .nx-umenu-chev { transform: rotate(180deg); }

.nx-umenu-panel { position: absolute; right: 0; top: calc(100% + 6px); z-index: 50; box-sizing: border-box;
                  min-width: 240px; max-width: calc(100vw - 32px); padding: 6px;
                  background: var(--nx-surface); border: 1px solid var(--nx-line); border-radius: var(--nx-radius-lg);
                  box-shadow: var(--nx-shadow-pop); }
.nx-umenu-who { display: grid; gap: 2px; padding: 8px 10px 10px; margin-bottom: 4px; border-bottom: 1px solid var(--nx-line-soft); }
.nx-umenu-who-name { font-size: var(--nx-fs-sm); font-weight: 600; color: var(--nx-text); overflow-wrap: anywhere; }
.nx-umenu-who-sub { font-size: var(--nx-fs-xs); color: var(--nx-muted); }
.nx-umenu-panel .nx-umenu-item { display: flex; align-items: center; min-height: 44px; box-sizing: border-box; padding: 0 10px;
                                  border-radius: var(--nx-radius); color: var(--nx-text-2); font-size: var(--nx-fs-sm);
                                  text-decoration: none; white-space: nowrap; }
.nx-umenu-panel .nx-umenu-item:hover { background: var(--nx-hover); color: var(--nx-text); }
.nx-umenu-panel .nx-umenu-item:focus-visible,
.nx-theme-opt:focus-visible { outline: 2px solid var(--nx-accent-text); outline-offset: -2px; }
.nx-umenu-panel .nx-umenu-item[aria-current="page"] { color: var(--nx-accent-text); font-weight: 600; }
.nx-umenu-theme { margin: 4px 0; padding: 8px 10px; border-top: 1px solid var(--nx-line-soft); border-bottom: 1px solid var(--nx-line-soft); }
.nx-umenu-theme-lab { display: block; margin-bottom: 6px; font-size: var(--nx-fs-xs); color: var(--nx-muted); }
.nx-theme-seg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; padding: 2px;
                background: var(--nx-field); border-radius: var(--nx-radius); }
.nx-theme-opt { min-height: 44px; padding: 0 4px; border: 0; border-radius: 6px; background: transparent; color: var(--nx-text-2);
                font: inherit; font-size: var(--nx-fs-13); line-height: 1.2; cursor: pointer; white-space: nowrap; }
.nx-theme-opt:hover { background: var(--nx-hover); color: var(--nx-text); }
.nx-theme-opt[aria-checked="true"] { background: var(--nx-accent-strong); color: var(--nx-on-accent); font-weight: 600; }

/* 비로그인: 로그인/가입 링크 + 테마 순환 아이콘 버튼 */
.nx-nav-user .nx-nav-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 6px; white-space: nowrap; }
.nx-nav-link:focus-visible { outline: 2px solid var(--nx-accent-text); outline-offset: 2px; border-radius: var(--nx-radius-sm); }
.nx-theme-btn { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 44px; height: 44px; padding: 0;
                border: 0; border-radius: 50%; background: transparent; color: var(--nx-muted); cursor: pointer;
                -webkit-tap-highlight-color: transparent; }
.nx-theme-btn:hover { background: var(--nx-hover); color: var(--nx-text); }
.nx-theme-btn:focus-visible { outline: 2px solid var(--nx-accent-text); outline-offset: 0; }
.nx-ti { display: none; }
:root:not([data-theme-pref]) .nx-ti-system,
:root[data-theme-pref="system"] .nx-ti-system,
:root[data-theme-pref="light"] .nx-ti-light,
:root[data-theme-pref="dark"] .nx-ti-dark { display: block; }
:root:not([data-theme]) .nx-theme-btn { display: none; }      /* 스크립트가 꺼져 있으면 동작하지 않으니 숨긴다 */
.nx-auth-card { position: relative; }
.nx-auth-theme { position: absolute; top: 6px; right: 6px; }

@media (min-width: 768px) {
  .nx-umenu-btn { min-height: 40px; }
  .nx-nav-user .nx-nav-link { min-height: 40px; padding: 0 4px; }
  .nx-theme-btn { width: 40px; height: 40px; }
  .nx-umenu-panel .nx-umenu-item, .nx-theme-opt { min-height: 40px; }
}
@media (max-width: 767px) {
  /* 1행 폭 아끼기: 이름은 말줄임(최대 6em), 가입 링크는 아주 좁은 화면에서만 접는다 */
  .nx-umenu-name { max-width: 6em; }
  .nx-nav-user { gap: 0; }
}
@media (max-width: 359px) { .nx-nav-signup { display: none; } }
@media (prefers-reduced-motion: reduce) { .nx-umenu-chev { transition: none; } }
/* ══ /C5 ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ══ C4 라이트 테마 ═════════════════════════════════════════════════════════════════════════════════
   기본(:root)은 다크 그대로. <html data-theme="light"> 일 때만 아래가 켜진다 — data-theme 은 _theme_head.html 의
   인라인 스크립트가 첫 페인트 전에 정한다(저장값 light|dark|system, system 이면 prefers-color-scheme).
   구성: ① 토큰 재정의(다크가 정의한 --nx-* 를 전부 다시 정의) ② 템플릿에서 쓰는 Tailwind 다크 유틸리티의 라이트 대응표
   (prebuilt tailwind.min.css 는 고정이라 클래스를 새로 못 만든다 — 같은 클래스를 [data-theme="light"] 아래에서 덮어쓴다)
   ③ 몇몇 개별 규칙 보정.
   대비(WCAG AA): 읽는 글자 ≥ 4.5:1 — 본문 text/카드 17.9, text-2 10.4, muted 카드 7.6·타일 6.9, accent-text 카드 7.9,
   등락 빨강 up(#c62828) 카드 5.6·타일 5.1 / 파랑 down(#2563eb) 카드 5.2·타일 4.7, 판정 good 5.5·warn 5.0·bad 6.3(카드).
   --nx-faint/--nx-ghost 는 다크와 같은 규칙대로 "글자가 아닌 표식" 전용(입력칸 테두리 faint 카드 위 4.8:1).
   차트 계열색은 다크의 겹침 관계를 유지한다: chart-2=good, chart-4=bad, chart-6=warn (finance.html 이 테마 전환 시
   색 문자열을 값→값으로 치환하므로, 다크에서 같은 값이던 토큰은 라이트에서도 같은 값이어야 한다). */
:root[data-theme="light"] {
  color-scheme: light;

  --nx-bg: #f8fafc;                        /* slate-50 */
  --nx-surface: #ffffff;
  --nx-surface-2: #f1f5f9;                 /* slate-100 — 카드 안 타일 */
  --nx-field: #f1f5f9;                     /* 입력칸·칩·토글 바탕 */

  --nx-line: #cbd5e1;                      /* slate-300 */
  --nx-line-soft: #e2e8f0;                 /* slate-200 */
  --nx-line-strong: #cbd5e1;

  --nx-text: #0f172a;                      /* slate-900 */
  --nx-text-2: #334155;                    /* slate-700 */
  --nx-muted: #475569;                     /* slate-600 — 보조 글자(바탕 7.2:1 · 카드 7.6:1 · 타일 6.9:1) */
  --nx-faint: #64748b;                     /* slate-500 — 비-글자 표식 */
  --nx-ghost: #94a3b8;                     /* slate-400 — 비-글자 표식 */

  --nx-accent: #4f46e5;                    /* indigo-600 */
  --nx-accent-strong: #4f46e5;             /* 주요 버튼(흰 글자 6.3:1) */
  --nx-accent-text: #4338ca;               /* indigo-700 — 링크·활성 메뉴(카드 7.9:1) */

  --nx-up: #c62828;                        /* 상승(국내 관행: 빨강) */
  --nx-down: #2563eb;                      /* 하락(국내 관행: 파랑) */
  --nx-flat: var(--nx-muted);

  --nx-good: #047857;                      /* emerald-700 */
  --nx-warn: #b45309;                      /* amber-700 */
  --nx-bad: #be123c;                       /* rose-700 */
  --nx-good-soft: #d1fae5;                 /* emerald-100 */
  --nx-warn-soft: #fef3c7;                 /* amber-100 */
  --nx-bad-soft: #ffe4e6;                  /* rose-100 */

  --nx-chart-1: #4f46e5;                   /* indigo-600 */
  --nx-chart-2: #047857;                   /* = good */
  --nx-chart-3: #0284c7;                   /* sky-600 */
  --nx-chart-4: #be123c;                   /* = bad */
  --nx-chart-5: #7c3aed;                   /* violet-600 */
  --nx-chart-6: #b45309;                   /* = warn */
  --nx-chart-grid: rgba(71, 85, 105, .16);
  --nx-chart-text: #475569;

  --nx-hover: rgba(71, 85, 105, .09);
  --nx-shadow-pop: 0 10px 24px rgba(15, 23, 42, .16), 0 2px 6px rgba(15, 23, 42, .10);

  --nx-light-surface: #ffffff;
  --nx-light-surface-hover: #f1f5f9;
  --nx-light-text: #1e293b;
  --nx-light-line: #94a3b8;                /* 흰 카드 위 흰 버튼이라 테두리를 한 단계 진하게 */
  --nx-on-accent: #ffffff;
  --nx-staging: #f59e0b;
  --nx-staging-line: #d97706;
  --nx-staging-text: #0f172a;

  --nx-sg-hover: #e2e8f0;
  --nx-sg-on: #e2e8f0;
  --nx-sg-badge-line: var(--nx-faint);
  --nx-job-bg: #e0e7ff;                    /* indigo-100 */
  --nx-job-line: #a5b4fc;                  /* indigo-300 */
  --nx-job-text: #312e81;                  /* indigo-900 */
  --nx-job-muted: #4338ca;                 /* indigo-700 */
  --nx-job-track: #818cf8;                 /* indigo-400 */
  --nx-job-done: #4f46e5;                  /* indigo-600 */
  --nx-skel: rgba(100, 116, 139, .18);
  --nx-skel-shine: rgba(255, 255, 255, .7);
}
/* 미국 관행(초록=상승, 빨강=하락) — 다크의 [data-market="us"] 는 :root[data-theme] 보다 약해서 라이트용을 따로 둔다 */
:root[data-theme="light"][data-market="us"],
:root[data-theme="light"] [data-market="us"] {
  --nx-up: #047857;
  --nx-down: #c62828;
}

/* ── ② Tailwind 다크 유틸리티 → 라이트 대응표 ─────────────────────────────────────────────────────────
   키: 템플릿(webapp/templates, tools/draft)에서 실제로 쓰는 색 클래스 전부. tools/test_theme_header.py 가
   "템플릿이 쓰는 색 클래스 ⊆ 이 표"를 검사한다(새 색 클래스를 쓰면 여기에도 추가해야 한다).
   특이도: [data-theme="light"] .x (0,2,0) > .x (0,1,0), 호버/포커스 변형도 같은 방식으로 이긴다. */
/* 바탕 */
[data-theme="light"] .bg-slate-900 { background-color: var(--nx-bg); }
[data-theme="light"] .bg-slate-800 { background-color: var(--nx-surface); }
[data-theme="light"] .bg-slate-700 { background-color: var(--nx-field); }
[data-theme="light"] .bg-slate-700\/40 { background-color: var(--nx-surface-2); }
[data-theme="light"] .bg-slate-600 { background-color: var(--nx-sg-hover); }
[data-theme="light"] .hover\:bg-slate-600:hover,
[data-theme="light"] .hover\:bg-slate-700:hover,
[data-theme="light"] .hover\:bg-slate-750:hover { background-color: var(--nx-sg-hover); }
[data-theme="light"] .bg-indigo-400,
[data-theme="light"] .bg-indigo-500 { background-color: #6366f1; }
[data-theme="light"] .bg-indigo-600 { background-color: var(--nx-accent-strong); }
[data-theme="light"] .hover\:bg-indigo-500:hover { background-color: #4338ca; }   /* 흰 글자 유지 — 더 진하게 */
[data-theme="light"] .bg-indigo-600\/30,
[data-theme="light"] .bg-indigo-900\/40,
[data-theme="light"] .bg-indigo-900\/60 { background-color: #e0e7ff; }
[data-theme="light"] .bg-amber-900\/40,
[data-theme="light"] .bg-amber-900\/50 { background-color: #fef3c7; }
[data-theme="light"] .bg-amber-950\/40 { background-color: #fffbeb; }
[data-theme="light"] .bg-emerald-900\/50 { background-color: var(--nx-good-soft); }
[data-theme="light"] .bg-red-900\/50 { background-color: #fee2e2; }
[data-theme="light"] .bg-rose-900\/40,
[data-theme="light"] .bg-rose-900\/50 { background-color: var(--nx-bad-soft); }
[data-theme="light"] .bg-sky-900\/50 { background-color: #e0f2fe; }
[data-theme="light"] .bg-emerald-400 { background-color: #059669; }
[data-theme="light"] .bg-red-400,
[data-theme="light"] .bg-red-500 { background-color: #dc2626; }
[data-theme="light"] .bg-yellow-500 { background-color: #d97706; }
[data-theme="light"] .bg-rose-700 { background-color: #be123c; }
[data-theme="light"] .hover\:bg-rose-600:hover { background-color: #9f1239; }
/* 솔리드 색 버튼은 라이트에서도 흰 글자 — 본문 글자색(어두움)을 상속받지 않게 text-slate-* 규칙 뒤에서 되돌린다 */
[data-theme="light"] .bg-indigo-600,
[data-theme="light"] .bg-indigo-600.text-slate-100,
[data-theme="light"] .bg-rose-700,
[data-theme="light"] .bg-rose-700.text-slate-100 { color: var(--nx-on-accent); }

/* 글자 */
[data-theme="light"] .text-slate-100 { color: var(--nx-text); }
[data-theme="light"] .text-slate-200 { color: #1e293b; }
[data-theme="light"] .text-slate-300 { color: var(--nx-text-2); }
[data-theme="light"] .text-slate-400,
[data-theme="light"] .text-slate-500,
[data-theme="light"] .text-slate-600 { color: var(--nx-muted); }
[data-theme="light"] .hover\:text-slate-200:hover { color: var(--nx-text); }
[data-theme="light"] .text-indigo-100 { color: #312e81; }
[data-theme="light"] .text-indigo-300 { color: #4338ca; }
[data-theme="light"] .text-indigo-400 { color: var(--nx-accent-text); }
[data-theme="light"] .text-indigo-500 { color: var(--nx-accent); }
[data-theme="light"] .hover\:text-indigo-300:hover { color: #3730a3; }
[data-theme="light"] .text-amber-200 { color: #78350f; }
[data-theme="light"] .text-amber-300 { color: #92400e; }
[data-theme="light"] .text-amber-400 { color: var(--nx-warn); }
[data-theme="light"] .text-emerald-400 { color: var(--nx-good); }
[data-theme="light"] .text-red-200 { color: #7f1d1d; }
[data-theme="light"] .text-red-400 { color: #b91c1c; }
[data-theme="light"] .text-rose-200 { color: #881337; }
[data-theme="light"] .text-rose-300 { color: #9f1239; }
[data-theme="light"] .text-rose-400 { color: var(--nx-bad); }
[data-theme="light"] .text-sky-300 { color: #0369a1; }
/* .text-white 는 라이트에서도 흰색 그대로(색 바탕 위 글자용) */

/* 테두리·구분선·링 */
[data-theme="light"] .border-slate-800 { border-color: var(--nx-line-soft); }
[data-theme="light"] .border-slate-700 { border-color: var(--nx-line); }
[data-theme="light"] .border-slate-700\/50 { border-color: var(--nx-line-soft); }
[data-theme="light"] .border-slate-600 { border-color: var(--nx-ghost); }
[data-theme="light"] .hover\:border-slate-600:hover { border-color: var(--nx-faint); }
[data-theme="light"] .divide-slate-700 > :not([hidden]) ~ :not([hidden]) { border-color: var(--nx-line); }
[data-theme="light"] .border-indigo-500 { border-color: var(--nx-accent); }
[data-theme="light"] .border-indigo-600\/50,
[data-theme="light"] .border-indigo-700 { border-color: #a5b4fc; }
[data-theme="light"] .border-amber-700 { border-color: #f59e0b; }
[data-theme="light"] .border-amber-700\/50 { border-color: #fcd34d; }
[data-theme="light"] .border-red-700 { border-color: #f87171; }
[data-theme="light"] .border-rose-700 { border-color: #fda4af; }
[data-theme="light"] .focus\:ring-indigo-500:focus,
[data-theme="light"] .hover\:ring-indigo-500:hover { --tw-ring-color: var(--nx-accent); }

/* ── ③ 개별 보정 ───────────────────────────────────────────────────────────────────────────────── */
/* 입력칸: 카드(흰색) 위에서 칸 경계가 보이게 흰 바탕 + 진한 테두리, 플레이스홀더는 칸 위 AA */
[data-theme="light"] input.bg-slate-700, [data-theme="light"] select.bg-slate-700, [data-theme="light"] textarea.bg-slate-700 {
  background-color: #ffffff; border-color: var(--nx-faint);
}
[data-theme="light"] input::placeholder, [data-theme="light"] textarea::placeholder { color: var(--nx-muted); opacity: 1; }
[data-theme="light"] .nx-auth-card { box-shadow: 0 10px 15px -3px rgba(15, 23, 42, .12), 0 4px 6px -4px rgba(15, 23, 42, .10); border: 1px solid var(--nx-line-soft); }
[data-theme="light"] .nx-pf-t { text-shadow: none; }                 /* 파스텔 칸 위 어두운 글자라 그림자 불필요 */
[data-theme="light"] .nx-totop { box-shadow: 0 6px 18px rgba(15, 23, 42, .25); }
/* ══ /C4 ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ══ A2 결론 바 ════════════════════════════════════════════════════════════════════════════════════
   히어로 바로 아래 한 줄 결론(finance.html #nxVerdict) — 신호 배지 · 투자스코어 N/10 · 근거 보기 링크 / 강점 / 유의.
   색은 판정 토큰만(다크·라이트 :root 가 각각 재정의) — 신호 이름과 ✓/! 글자가 항상 같이 있어 색만으로 전달하지 않는다.
   왼쪽 띠가 신호색(--nx-vb). 항목은 nowrap 이라 긴 유의 목록도 항목 사이에서만 줄바꿈된다. */
.nx-vbar {
  --nx-vb: var(--nx-warn);
  display: grid; gap: 8px; padding: 12px 16px 12px 14px;
  background: var(--nx-surface); border: 1px solid var(--nx-line-soft);
  border-left: 4px solid var(--nx-vb); border-radius: var(--nx-radius-lg);
}
.nx-vb-good { --nx-vb: var(--nx-good); }
.nx-vb-warn { --nx-vb: var(--nx-warn); }
.nx-vb-bad { --nx-vb: var(--nx-bad); }
.nx-vb-top { display: flex; align-items: center; gap: 10px; min-width: 0; }
.nx-vb-sig { flex: none; padding: 2px 10px; border-radius: 9999px; font-size: var(--nx-fs-13); font-weight: 700; line-height: 1.5; white-space: nowrap; }
.nx-vb-score { font-size: var(--nx-fs-sm); color: var(--nx-text-2); white-space: nowrap; }
.nx-vb-score b { color: var(--nx-text); font-size: var(--nx-fs-md); }
.nx-vb-link { margin-left: auto; flex: none; padding: 4px 0 4px 8px; font-size: var(--nx-fs-13); font-weight: 600; color: var(--nx-accent-text); text-decoration: none; white-space: nowrap; }
.nx-vb-link:hover { text-decoration: underline; }
.nx-vb-rows { display: grid; gap: 4px; }
.nx-vb-row { margin: 0; display: flex; align-items: baseline; gap: 8px; min-width: 0; font-size: var(--nx-fs-13); line-height: 1.6; }
.nx-vb-k { flex: none; font-weight: 700; white-space: nowrap; }
.nx-vb-items { min-width: 0; color: var(--nx-text-2); }
.nx-vb-it { display: inline-block; white-space: nowrap; }
.nx-vb-more { color: var(--nx-muted); }
.nx-scorecard { scroll-margin-top: 64px; }
@media (min-width: 768px) {
  .nx-vb-rows { display: flex; flex-wrap: wrap; gap: 4px 28px; }
  .nx-vb-row { font-size: var(--nx-fs-sm); }
  .nx-vb-top { gap: 12px; }
}
/* ══ /A2 ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ══ 관리자 대시보드 — 회원 현황(2026-10-24) ═══════════════════════════════════════════════════════
 * 가입자 목록: PC 는 표, 모바일(<640px)은 회원 1명 = 2줄 행. 기본은 접힌 <details>.
 * tailwind.min.css 는 빌드 시점에 쓰인 클래스만 담으므로 새 반응형 규칙은 여기 둔다. */
.nx-mem-unit { font-size: var(--nx-fs-sm, .875rem); font-weight: 500; color: var(--nx-muted); margin-left: 2px; }
.nx-mem-sub { color: var(--nx-muted); font-size: .75rem; margin-top: 8px; font-variant-numeric: tabular-nums; }
.nx-mem-list { background: var(--nx-surface); border-radius: .75rem; margin-top: 16px; }
.nx-mem-list summary { cursor: pointer; padding: 14px 16px; font-size: .875rem; color: var(--nx-text); list-style: none;
  display: flex; justify-content: space-between; gap: 8px; }
.nx-mem-list summary::-webkit-details-marker { display: none; }
.nx-mem-list summary:focus-visible { outline: 2px solid var(--nx-accent-text); outline-offset: 2px; border-radius: .75rem; }
.nx-mem-hint { color: var(--nx-accent-text); font-size: .8125rem; }
.nx-mem-list[open] .nx-mem-hint::after { content: "접기"; }
.nx-mem-list:not([open]) .nx-mem-hint::after { content: "펼치기"; }
.nx-mem-table { overflow-x: auto; padding: 0 8px 12px; }
.nx-mem-table table { width: 100%; border-collapse: collapse; font-size: .8125rem; font-variant-numeric: tabular-nums; }
.nx-mem-table th { text-align: left; color: var(--nx-muted); font-weight: 500; padding: 8px; border-bottom: 1px solid var(--nx-line); white-space: nowrap; }
.nx-mem-table td { padding: 8px; border-bottom: 1px solid var(--nx-line-soft); white-space: nowrap; }
.nx-mem-table tr:last-child td { border-bottom: 0; }
.nx-mem-id { font-weight: 600; color: var(--nx-text); }
.nx-mem-pill { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: .6875rem; border: 1px solid var(--nx-line); color: var(--nx-muted); }
.nx-mem-pill.is-admin { color: var(--nx-accent-text); border-color: var(--nx-accent-text); }
.nx-mem-ok { color: var(--nx-good); }
.nx-mem-no { color: var(--nx-warn); }
.nx-mem-rows { display: none; padding: 0 16px 8px; }
.nx-mem-row { padding: 10px 0; border-top: 1px solid var(--nx-line-soft); }
.nx-mem-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.nx-mem-row .nx-mem-sub { margin-top: 4px; }
@media (max-width: 639px) {
  .nx-mem-table { display: none; }
  .nx-mem-rows { display: block; }
}
/* ══ /회원 현황 ═══════════════════════════════════════════════════════════════════════════════════ */
