@import url('spectrum2/colors.css');
@import url('spectrum2/theme.css');
@import url('spectrum2/dimensions.css');
@import url('spectrum2/typography.css');
@import url('spectrum2/elevation.css');
@import url('spectrum2/fonts.css');

:root {
  /* Spectrum 2 매핑 — 변수 이름은 유지, 값만 flat hex(라이트모드 고정)로 변경.
     light-dark() 원본 토큰을 직접 쓰지 않는 이유는 stock.php 차트가 런타임에
     getComputedStyle()로 이 변수들을 읽어 hex→rgba 변환하기 때문(§0 참고). */
  --ink:var(--text-primary); --body:var(--text-primary); --mute:var(--text-secondary);
  --line:var(--border-color); --bg:var(--surface-base);
  --surface:var(--surface-layer-1); --surface-hover:var(--gray-100); --surface-2:var(--surface-layer-2);
  --accent:var(--accent-fill); --accent-hover:var(--accent-fill-hover); --ink-hover:var(--neutral-fill-hover);
  /* 버튼/활성 칩처럼 "채우기" 용도로 --ink를 재사용하던 곳 전용 별칭(2026-08 다크모드
     사전정리) — --ink/--text-primary는 다크모드에서 밝은색으로 뒤집히므로, 항상
     어두운 채우기가 필요한 버튼류는 이 별칭을 참조해야 다크모드에서도 안 깨진다.
     다크 팔레트 작성 시 --ink는 재정의하되 이 두 토큰은 그대로 둘 것. */
  --fill-inverse:var(--ink); --fill-inverse-hover:var(--ink-hover);
  --up:var(--positive-fill); --down:var(--negative-fill);
  --pos-bg:var(--green-200); --pos-fg:var(--green-1100);
  --neg-bg:var(--red-200); --neg-fg:var(--red-1100);
  --gold:var(--yellow-900); --pos-dark:var(--green-1000); --sep:var(--border-color); --faint:var(--text-helper);
  --s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:24px;--s6:32px;--s7:48px;--s8:64px;
  --r-sm:var(--radius-sm);--r-md:var(--radius-default);--r-lg:var(--radius-lg);--r-pill:var(--radius-full);
  --shadow-sm:var(--elevation-emphasized); --shadow-md:var(--elevation-elevated);
  --focus:var(--focus-ring-color); --ring:0 0 0 2px var(--focus-ring-color);
  --t-fast:var(--duration-100); --t:var(--duration-200); --ease:var(--ease-default);
  --nav-h:56px; --sidebar-w:220px; --container:1200px; --content:1600px;
  --z-nav:100; --z-dropdown:200; --z-modal:1000;
  --font-sans:'Source Sans 3','Pretendard Variable','Pretendard',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  /* 2026-08 디자인 B2-2: Source Sans 3 → Inter Variable로 교체. 리서치 근거 —
     Pretendard(--font-sans의 한글 부분)의 라틴 글리프 원형 자체가 Inter라서
     한글·영문이 같은 계보를 공유하게 됨. 이미 자체호스팅 중이던 InterVariable.woff2
     (아래 @font-face)를 그동안 실사용하지 않고 있었는데 이제 실제로 쓰게 됨. */
  --font-latin:'Inter Variable',ui-sans-serif,system-ui,sans-serif;
  --lh-body:1.5; --lh-table:1.4; --lh-title:1.2;

  /* ── design_v4 오버라이드 (2026-07-16, Koyfin 실측 반영) ──
     위 Spectrum2 매핑 값을 실측 색으로 교체. --up/--down/--accent 외에
     이 변수들을 직접 참조하는 곳이 없어(다른 곳은 전부 --up 등 경유) 여기
     한 곳만 바꾸면 전체 사이트에 전파된다. */
  --accent:#0084FC; --accent-hover:#1A93FF;
  --up:#3F8657; --down:#C1503F;
  --pos-bg:#E9F3EB; --pos-fg:#2F6A42;
  --neg-bg:#FBEDEA; --neg-fg:#A83F2E;

  /* ── 다크 크롬(사이드바·톱바 전용) — 신규 ── */
  --chrome-bg:#0B0E14; --chrome-bg-hover:#171B23; --chrome-line:#262B35;
  --chrome-text:#B8BFC9; --chrome-text-active:#FFFFFF; --chrome-icon-muted:#6B7280;

  /* ── 입력 필드 전용 고정 팔레트 (2026-08) ──
     --surface-2를 그대로 쓰면 다크모드에서 입력창이 카드/위젯과 같은 색이 되어
     "입력 가능한 곳"이라는 게 안 보이고, placeholder도 거의 안 읽힘(실사용자
     피드백). 폼 필드는 라이트/다크 상관없이 항상 흰 배경 + 짙은 텍스트로 고정
     — 아래 다크모드 media query에서도 재정의하지 않는다. */
  --input-bg:#FFFFFF; --input-text:#292929; --input-border:#DADADA; --input-placeholder:#6E6E6E;
}

/* ── 다크모드 (2026-08 디자인 리포트 B1) ──
   flat hex만 사용(light-dark() 금지 — stock.php/index.php/portfolio.php의
   getComputedStyle()+hexAlpha() substring 파싱이 다른 포맷에선 깨짐, §0 참고).
   raw 팔레트(gray/blue/green/red/yellow)와 그걸 가리키는 시맨틱 별칭을 전부
   여기서 재정의해 vwg.css 하나로 전체 사이트에 전파한다(스펙트럼 원본
   파일들은 건드리지 않음 — vwg.css의 :root가 나중에 로드되어 우선 적용됨).
   surface-25(카드)와 surface-50(페이지 배경)의 밝기 서열은 라이트와 동일하게
   유지하되 반전 — 다크에서는 카드가 배경보다 밝아야(elevation) 정상이므로
   gray-25를 배경보다 밝은 톤으로, gray-50을 가장 어두운 페이지 배경으로 뒀다.

   2026-08-15 추가: 설정 화면에서 라이트/다크를 수동으로 고를 수 있게 되며
   이중 가드로 확장했다 — ①@media(prefers-color-scheme:dark)는 사용자가
   명시적으로 "라이트"를 고르지 않은 한(:not([data-theme="light"])) OS 설정을
   그대로 따르고, ②:root[data-theme="dark"]는 OS가 라이트여도 사용자가 명시적
   으로 "다크"를 고르면 무조건 적용된다. 두 규칙이 같은 값을 각자 담당하는
   조건에서만 켜지므로 내용은 그대로 두 번 써야 한다(합칠 수 없음 — 순수 CSS엔
   믹스인이 없음). 값을 고칠 땐 반드시 두 블록을 함께 수정할 것. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --gray-25:#151A22; --gray-50:#0B0E14; --gray-100:#1E242E; --gray-200:#262D38;
    --gray-300:#303844; --gray-400:#3D4652; --gray-700:#9BA5B4; --gray-800:#E8ECF2; --gray-900:#F5F7FA;

    --blue-800:#5C8AFF; --blue-900:#6E93FF; --blue-1000:#85A3FF;

    --green-100:#0F2A1A; --green-200:#163A24; --green-400:#2F9464; --green-900:#22A672;
    --green-1000:#1C8F5F; --green-1100:#6FDBA6; --green-1400:#B9F5D6;

    --red-100:#301512; --red-200:#3D1D18; --red-400:#C4685A; --red-900:#E85A48;
    --red-1100:#F19686; --red-1400:#FBCFC7;

    --yellow-900:#D4A340;

    --ink:var(--gray-800); --body:var(--gray-800); --mute:var(--gray-700);
    --line:var(--gray-300); --bg:var(--gray-50);
    --surface:var(--gray-50); --surface-hover:var(--gray-100); --surface-2:var(--gray-25);
    --ink-hover:var(--gray-900);

    --fill-inverse:#292929; --fill-inverse-hover:#131313;

    --accent:#4EA8FF; --accent-hover:#6FBCFF;
    --up:#5FBE82; --down:#E37A69;
    --pos-bg:#16301F; --pos-fg:#7FD99D;
    --neg-bg:#341814; --neg-fg:#F0917E;
    --gold:#D4A340; --pos-dark:var(--green-1000);

    --input-bg:#F3EEE2; --input-border:#DCD3BE; --input-placeholder:#8A8272;

    --shadow-ambient: rgba(0, 0, 0, 0.24);
    --shadow-transition: rgba(0, 0, 0, 0.12);
    --shadow-key-emphasized: rgba(0, 0, 0, 0.24);
    --shadow-key-elevated: rgba(0, 0, 0, 0.36);
    --shadow-key-dragged: rgba(0, 0, 0, 0.48);
  }
}
:root[data-theme="dark"] {
  --gray-25:#151A22; --gray-50:#0B0E14; --gray-100:#1E242E; --gray-200:#262D38;
  --gray-300:#303844; --gray-400:#3D4652; --gray-700:#9BA5B4; --gray-800:#E8ECF2; --gray-900:#F5F7FA;

  --blue-800:#5C8AFF; --blue-900:#6E93FF; --blue-1000:#85A3FF;

  --green-100:#0F2A1A; --green-200:#163A24; --green-400:#2F9464; --green-900:#22A672;
  --green-1000:#1C8F5F; --green-1100:#6FDBA6; --green-1400:#B9F5D6;

  --red-100:#301512; --red-200:#3D1D18; --red-400:#C4685A; --red-900:#E85A48;
  --red-1100:#F19686; --red-1400:#FBCFC7;

  --yellow-900:#D4A340;

  --ink:var(--gray-800); --body:var(--gray-800); --mute:var(--gray-700);
  --line:var(--gray-300); --bg:var(--gray-50);
  --surface:var(--gray-50); --surface-hover:var(--gray-100); --surface-2:var(--gray-25);
  --ink-hover:var(--gray-900);

  --fill-inverse:#292929; --fill-inverse-hover:#131313;

  --accent:#4EA8FF; --accent-hover:#6FBCFF;
  --up:#5FBE82; --down:#E37A69;
  --pos-bg:#16301F; --pos-fg:#7FD99D;
  --neg-bg:#341814; --neg-fg:#F0917E;
  --gold:#D4A340; --pos-dark:var(--green-1000);

  --input-bg:#F3EEE2; --input-border:#DCD3BE; --input-placeholder:#8A8272;

  --shadow-ambient: rgba(0, 0, 0, 0.24);
  --shadow-transition: rgba(0, 0, 0, 0.12);
  --shadow-key-emphasized: rgba(0, 0, 0, 0.24);
  --shadow-key-elevated: rgba(0, 0, 0, 0.36);
  --shadow-key-dragged: rgba(0, 0, 0, 0.48);
}

@font-face{font-family:'Pretendard Variable';font-weight:45 920;font-style:normal;font-display:swap;src:url('/fonts/PretendardVariable.woff2') format('woff2-variations');}
@font-face{font-family:'Inter Variable';font-weight:100 900;font-style:normal;font-display:swap;src:url('/fonts/InterVariable.woff2') format('woff2-variations');}
@font-face{font-family:'Inter Variable';font-weight:100 900;font-style:italic;font-display:swap;src:url('/fonts/InterVariable-Italic.woff2') format('woff2-variations');}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-padding-top:64px}
html,body{background:var(--surface);font-family:var(--font-sans);color:var(--body);line-height:var(--lh-body);font-size:14px;-webkit-font-smoothing:antialiased;}
table{line-height:var(--lh-table);border-collapse:collapse;width:100%}
th,td{line-height:var(--lh-table)}
a{color:inherit;text-decoration:none}
button{font-family:var(--font-sans);cursor:pointer}
input,select{font-family:var(--font-sans)}
.tabular{font-variant-numeric:tabular-nums;font-family:var(--font-latin)}
.font-latin{font-family:var(--font-latin);font-variant-numeric:tabular-nums}
.tkr{font-family:var(--font-latin);font-weight:700}

/* Nav */
.nav{height:var(--nav-h);display:flex;align-items:center;gap:var(--s5);padding:0 var(--s5);background:var(--bg);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:var(--z-nav);}
.nav-logo{font-size:16px;font-weight:700;color:var(--ink);white-space:nowrap;margin-right:var(--s4)}
.nav-menu{display:flex;gap:0;align-items:center}
.nav-menu a{font-size:14px;color:var(--mute);padding:0 var(--s3);height:var(--nav-h);display:inline-flex;align-items:center;gap:6px;border-bottom:2px solid transparent;transition:color var(--t);white-space:nowrap;flex-shrink:0}
.nav-menu a:hover{color:var(--ink)}
.nav-menu a.active{color:var(--ink);font-weight:700;border-bottom-color:var(--ink)}
.nav-menu a svg{width:15px;height:15px;stroke:currentColor;flex-shrink:0}
.nav-search{margin-left:auto;display:flex;align-items:center;border:1px solid var(--input-border);border-radius:var(--r-md);background:var(--input-bg);overflow:hidden}
.nav-search input{border:none;outline:none;padding:7px 12px;font-size:13px;color:var(--input-text);width:220px;background:transparent}
.nav-search input::placeholder{color:var(--input-placeholder)}
.nav-user{display:flex;gap:var(--s2);align-items:center;margin-left:var(--s3)}

/* ── 좌측 사이드바 셸 (Meridian) ─────────────────────────────────
   .nav/.nav-logo/.nav-menu/.nav-search/.nav-user 기본 규칙(위)은 아직
   상단 가로 내비를 쓰는 페이지를 위해 그대로 둔다. 아래는 .mds-sidebar/
   .mds-topbar 안에서만 적용되는 재정의 — 페이지가 사이드바 마크업으로
   옮겨가면 자동으로 이 규칙이 우선 적용된다(디스크립터 2개 > 1개). */
.mds-shell{display:flex;min-height:100vh;background:var(--bg)}
.mds-sidebar{width:var(--sidebar-w);flex-shrink:0;background:var(--chrome-bg);border-right:1px solid var(--chrome-line);position:sticky;top:0;align-self:flex-start;height:100vh;overflow-y:auto;display:flex;flex-direction:column;padding:var(--s5) 0}
.mds-sidebar .nav-logo{padding:0 var(--s5) var(--s5);margin-right:0;color:var(--chrome-text-active)}
.mds-sidebar .nav-menu{flex-direction:column;align-items:stretch;gap:0}
.mds-sidebar .nav-menu a{height:auto;padding:10px var(--s5);border-bottom:none;border-left:3px solid transparent;gap:10px;justify-content:flex-start;color:var(--chrome-text)}
.mds-sidebar .nav-menu a svg{width:16px;height:16px;color:var(--chrome-icon-muted);stroke:var(--chrome-icon-muted)}
.mds-sidebar .nav-menu a:hover{background:var(--chrome-bg-hover);border-bottom-color:transparent;color:var(--chrome-text-active)}
.mds-sidebar .nav-menu a.active{border-bottom-color:transparent;border-left-color:var(--accent);background:var(--chrome-bg-hover);color:var(--chrome-text-active)}
.mds-sidebar .nav-menu a.active svg{color:var(--accent);stroke:var(--accent)}
.mds-main{flex:1;min-width:0;display:block}
.mds-topbar{height:var(--nav-h);flex-shrink:0;display:flex;align-items:center;justify-content:space-between;gap:var(--s5);padding:0 var(--s5);background:var(--bg);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:var(--z-nav)}
.mds-topbar .nav-search{margin-left:0;border:1px solid var(--input-border);border-radius:var(--r-pill);background:var(--input-bg)}
.mds-topbar .nav-search input{width:240px;padding:7px 14px}
.mds-topbar .nav-user{margin-left:0}

/* Page */
.page{max-width:var(--content);margin:0 auto;padding:var(--s6) var(--s5)}
.page-title{font-size:30px;font-weight:700;color:var(--ink);line-height:var(--lh-title);margin-bottom:var(--s5)}

/* Section head */
.section-head{display:flex;align-items:baseline;margin-bottom:var(--s4)}
.section-head .kicker{font-size:11.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--mute);margin-bottom:2px}
.section-head .title{font-size:19px;font-weight:700;color:var(--ink)}
.section-head .action{margin-left:auto;color:var(--accent);font-size:13px;font-weight:400;background:none;border:none;padding:0}
.section-head .action:hover{text-decoration:underline}

/* Card */
.card{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:var(--s5);box-shadow:var(--shadow-sm)}
.card-head{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--mute)}
.card-value{font-size:28px;font-weight:800;color:var(--ink);margin-top:6px;line-height:1.15;font-variant-numeric:tabular-nums}
.card-sub{font-size:12px;color:var(--mute);margin-top:8px}

/* AI card */
.ai-card{border:2px solid var(--line);background:var(--surface);border-radius:var(--r-lg);padding:var(--s4) var(--s5)}
.ai-card-header{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.ai-label{font-size:13px;font-weight:700;color:var(--accent)}
.ai-badge{font-size:10.5px;font-weight:700;color:var(--mute);border:1px solid var(--line);border-radius:var(--r-sm);padding:1px 6px}
.ai-text{font-size:14px;color:var(--body);white-space:pre-line;line-height:1.6}
.ai-text a{color:var(--accent);text-decoration:none}
.ai-text a:hover{text-decoration:underline}
.ai-text img{max-width:100%;height:auto;border-radius:var(--r-sm);margin:8px 0;display:block}
.ai-text table.diary-table{border-collapse:collapse;width:100%;margin:12px 0}
.ai-text table.diary-table td{border:1px solid var(--line);padding:8px 10px;font-size:13px}
.sm-ai-html h3{font-size:15px;font-weight:700;color:var(--ink);margin:14px 0 4px}
.sm-ai-html h3:first-child{margin-top:0}

/* 스켈레톤 로딩 — 스피너 대신 실제 레이아웃 형태를 미리 보여줌 */
@keyframes skel-pulse{0%,100%{opacity:.5}50%{opacity:1}}
.skel{background:var(--surface-2);border-radius:var(--r-sm);animation:skel-pulse 1.4s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){.skel{animation:none;opacity:.7}}
.skel-line{height:12px;border-radius:4px}
.skel-line+.skel-line{margin-top:8px}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
.fade-in{animation:fade-in .3s ease-out}
@media (prefers-reduced-motion:reduce){.fade-in{animation:none}}
.sm-ai-html p{font-size:14px;color:var(--body);line-height:var(--lh-body);margin:0}

/* ── 위젯풍 카드 헤더 (design.md §8.6, v3) ── */
.widget{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface-2);box-shadow:var(--shadow-sm)}
.widget__head{display:flex;align-items:center;gap:var(--s2);padding:var(--s3) var(--s4);border-bottom:1px solid var(--line)}
.widget__title{font:700 13px var(--font-sans);color:var(--ink)}
.widget__toolbar{margin-left:auto;display:flex;gap:2px;align-items:center}
.widget__toolbar button{width:26px;height:26px;border-radius:var(--r-sm);border:none;background:transparent;color:var(--mute);display:inline-flex;align-items:center;justify-content:center}
.widget__toolbar button:hover{background:var(--surface-hover);color:var(--ink)}
.widget__toolbar svg{width:14px;height:14px;stroke:currentColor}
.widget__body.pad{padding:var(--s4) var(--s5)}

/* ── 랭크 붙은 미니 리스트 (스마트머니 컨센서스Top3 등에서 유래, index.html
   로컬 스타일과 동일 — 종목상세 Holders 위젯 등 다른 페이지에서도 재사용하려고
   전역으로 옮김) ── */
.mini-list{display:flex;flex-direction:column}
.mini-list-row{display:flex;align-items:center;gap:8px;padding:var(--s3) 0;border-bottom:1px solid var(--line)}
.mini-list-row:last-child{border-bottom:none}
.mini-list-rank{width:16px;flex:0 0 auto;color:var(--faint);font-size:11px;font-family:var(--font-latin);font-weight:700}
.mini-list-name{flex:1;min-width:0}
.mini-list-name .co{color:var(--mute);font-size:11.5px;margin-left:4px}
.mini-list-val{font-family:var(--font-latin);font-weight:700;font-size:12.5px;color:var(--ink);white-space:nowrap}

/* ── 히트맵 셀 (design.md §9.3, v3) ──
   .heat-cell는 색상만 담당(작은 % 배지에도, briefing.html의 큰 섹터 카드에도 공용).
   "박스 고정폭"은 아래 .num-badge가 별도로 담당 — 섹터 카드(sector-cell)까지
   90px로 찌그러뜨렸던 사고(2026-07-16)가 있어 색상 클래스와 분리했다. */
.heat-cell{padding:4px 8px;border-radius:var(--r-sm);font-variant-numeric:tabular-nums;font-family:var(--font-latin)}
/* 작은 % 배지 전용 고정폭(자릿수 5~6자리 기준) — heat-cell과 함께 붙여 쓴다. */
.num-badge{display:inline-block;width:90px;text-align:center;white-space:nowrap}
.heat-cell.pos-1{background:var(--green-100);color:var(--green-1100)} .heat-cell.pos-2{background:var(--green-200);color:var(--green-1100)}
.heat-cell.pos-3{background:var(--green-400);color:var(--green-1400)} .heat-cell.pos-4{background:var(--green-900);color:#fff}
.heat-cell.neg-1{background:var(--red-100);color:var(--red-1100)} .heat-cell.neg-2{background:var(--red-200);color:var(--red-1100)}
.heat-cell.neg-3{background:var(--red-400);color:var(--red-1400)} .heat-cell.neg-4{background:var(--red-900);color:#fff}

/* ── 섹터/팩터 히트맵 그리드 (design.md §10.0c, v3) ── */
.heat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:var(--s3)}
.heat-card{border-radius:var(--r-md);padding:var(--s4);border:1px solid var(--line)}
.heat-card__label{font-size:12px;font-weight:700;opacity:.85}
.heat-card__value{font-size:22px;font-weight:800;margin-top:4px;font-family:var(--font-latin);font-variant-numeric:tabular-nums}
.heat-card__sub{font-size:11.5px;margin-top:2px;opacity:.75;font-family:var(--font-latin)}

/* ── 팩터 카드 (design.md §10.0b, v3 — 부호별 좌측 강조바) ── */
.factor-card{border:1px solid var(--line);border-radius:var(--r-md);padding:var(--s4);border-left:3px solid var(--line)}
.factor-card.pos{border-left-color:var(--up)}
.factor-card.neg{border-left-color:var(--down)}
.factor-card__label{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--mute)}
.factor-card__value{font-size:22px;font-weight:800;color:var(--ink);margin-top:6px;font-family:var(--font-latin);font-variant-numeric:tabular-nums}
.factor-card__sub{font-size:12px;color:var(--mute);margin-top:4px}

/* ── PER 밴드 (종목상세 밸류에이션) — 4년 저·평균·고 범위 안에서 현재·선행
   PER의 위치를 가로 막대 하나로 보여주는 요약. 점 라벨은 트랙 위에 직접 띄우지
   않고(값이 서로 가까우면 겹침) 아래 범례 줄로 분리해 항상 안정적으로 읽힌다. */
.per-band{padding:var(--s2) var(--s2) 0}
.per-band__labels{position:relative;height:16px;margin-bottom:var(--s3);font-size:12px;color:var(--mute);font-family:var(--font-latin)}
.per-band__labels span{position:absolute;top:0;white-space:nowrap}
.per-band__track{position:relative;height:6px;border-radius:var(--r-pill);background:var(--surface-hover)}
.per-band__range{position:absolute;top:0;bottom:0;border-radius:var(--r-pill);background:var(--accent);opacity:.14}
.per-band__avg{position:absolute;top:-4px;bottom:-4px;width:2px;background:var(--mute);opacity:.6;transform:translateX(-1px)}
.per-band__connector{position:absolute;top:50%;height:0;border-top:1.5px dashed var(--accent);opacity:.55}
.per-band__dot{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;transform:translate(-50%,-50%);box-sizing:border-box;box-shadow:0 1px 3px rgba(0,0,0,.15)}
.per-band__dot--pre{background:var(--surface-2);border:2.5px solid var(--accent);z-index:2}
.per-band__dot--post{background:var(--accent);border:2px solid var(--surface-2);z-index:3}
.per-band__dot--current{background:var(--fill-inverse);border:2px solid var(--surface-2);z-index:4}
.per-band__legend{display:flex;flex-wrap:wrap;gap:var(--s5);margin-top:var(--s4);font-size:12.5px;color:var(--mute)}
.per-band__legend-item{display:inline-flex;align-items:center;gap:6px}
.per-band__legend-item b{color:var(--ink);font-weight:700}
.per-band__dot-icon{width:10px;height:10px;border-radius:50%;display:inline-block;box-sizing:border-box}
.per-band__dot-icon--pre{background:var(--surface-2);border:2px solid var(--accent)}
.per-band__dot-icon--post{background:var(--accent)}
.per-band__dot-icon--current{background:var(--ink)}

/* ── 티커/시큐리티 칩 (design.md §9.4, v3) ── */
.ticker-chip{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface-2)}
.ticker-chip__swatch{width:7px;height:7px;border-radius:0;background:var(--accent);flex-shrink:0}
.ticker-chip__code{font:700 12px var(--font-latin);color:var(--ink)}
.ticker-chip__name{font-size:12px;color:var(--mute)}
.ticker-chip__close{color:var(--mute);cursor:pointer}
.ticker-chip__close:hover{color:var(--ink)}

/* ── 태그 칩 (v3 — 리스크/키워드 표시) ── */
.tag{display:inline-block;padding:2px 8px;border-radius:var(--r-pill);font-size:11px;font-weight:700;background:var(--surface-2);color:var(--body)}

/* Badge */
.badge{padding:1px 6px;border-radius:var(--r-sm);font-size:10px;font-weight:700;display:inline-block}
.badge-pos{background:var(--pos-bg);color:var(--pos-fg)}
.badge-neg{background:var(--neg-bg);color:var(--neg-fg)}
/* 2026-08-22: VG 투자일기 고정글 표시 — 기존 이모지(📌)+단색 배지가 사이트 전반의
   선(line) 아이콘 톤과 안 맞아서 다른 배지들과 같은 "옅은 배경 + 진한 글자색"
   톤(badge-pos/neg와 동일 톤)으로 맞췄다. accent 옅은 배경은 별도 토큰이 없어
   color-mix로 즉석 계산(다크모드 --accent가 바뀌어도 자동으로 맞물림). */
.badge-pin{background:color-mix(in srgb, var(--accent) 15%, transparent);color:var(--accent);padding:1px 6px;border-radius:var(--r-sm);font-size:10px;font-weight:700;display:inline-block;letter-spacing:.01em;flex-shrink:0}
.up{color:var(--up)} .down{color:var(--down)}

/* 강조형 등락 배지 — 지수 카드 등 단독으로 강조되는 통계 박스용(chgPill) */
.chg-pill{display:inline-flex;align-items:center;gap:3px;padding:2px 8px 2px 6px;border-radius:var(--r-pill);font-size:12px;font-weight:700}
.chg-pill svg{width:10px;height:10px;flex-shrink:0}
.chg-pill.up{background:var(--pos-bg);color:var(--pos-fg)}
.chg-pill.down{background:var(--neg-bg);color:var(--neg-fg)}

/* Table */
/* 2026-07-18: 헤더(th)는 그 아래 값의 정렬(좌/우/중)과 무관하게 항상 중앙
   정렬로 통일한다 — 헤더는 값이 아니라 값의 "속성 라벨"이라, 값의 정렬을
   그대로 따라가면(예: 숫자 컬럼 헤더가 우측으로 쏠림) 컬럼마다 헤더 위치가
   들쭉날쭉해 보여 완성도가 떨어진다는 지적. th의 text-align은 아래서 어떤
   컬럼(.num 등)이든 절대 재정의하지 않는다 — 값(td) 쪽만 컬럼 성격에 맞게
   좌/우/중을 나눠 준다.*/
.data-table th{text-align:center;padding:var(--s2) 10px;font-size:11.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink);border-bottom:1px solid var(--line);white-space:nowrap}
.data-table th.num{font-variant-numeric:tabular-nums;font-family:var(--font-latin)}
.data-table td.num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--font-latin)}
/* 2026-07-18: 값(td)이 텍스트인 경우, 문장(설명·이유 등 서술형 문구)은 좌측
   정렬을 유지하되(자연스러운 읽기 흐름), 문장이 아닌 짧은 단어·라벨(신호명·
   상태값·날짜 등)은 중앙 정렬한다(.word) — 종목명·섹터명처럼 그 행을 식별하는
   이름 컬럼은 예외로 계속 좌측을 쓴다(스캔하기 쉬운 목록을 위해 별도 클래스
   없이 기본값 좌측 유지). */
.data-table td.word{text-align:center}
.data-table td{padding:var(--s2) 10px;border-bottom:1px solid var(--line);font-size:14px;color:var(--body);white-space:nowrap}
.data-table tr:hover td{background:var(--surface-hover)}
.data-table a:hover{color:var(--accent)}
/* 섹터×주차 매트릭스(12개 숫자 컬럼) — 일반 셀 패딩으로는 13컬럼이 안 들어가서
   폰트·패딩을 줄이고 숫자 컬럼은 우측 정렬(첫 컬럼=섹터명만 좌측). 헤더는
   위 규칙대로 항상 중앙 — th에는 text-align을 다시 지정하지 않는다. */
.data-table.matrix th,.data-table.matrix td{padding:7px 6px;font-size:11.5px;font-variant-numeric:tabular-nums}
.data-table.matrix td{text-align:right}
.data-table.matrix td:first-child{text-align:left;font-size:12.5px}
.data-table.matrix th:first-child{font-size:12.5px}
/* 2026-07-17 1차 수정: 매트릭스 첫/끝 컬럼 패딩을 var(--s5)(24px)로 올려 박스
   테두리 정렬은 맞았으나, 우측정렬 숫자 컬럼이라 마지막 컬럼(끝)의 padding-right를
   24px로 올리면 auto 테이블 레이아웃이 그 컬럼 폭을 넓게 재분배해 07/11~07/15
   사이 간격만 다른 주차 간격보다 넓어 보이는 문제가 생겼음(실측 확인됨).
   2차 수정: 매트릭스 table-scroll은 아예 bleed(음수마진) 대상에서 빼서 위젯
   자체의 24px 패딩 안에 그대로 머물게 하고, 첫/끝 컬럼의 자체 패딩은 0으로 비워
   중간 12개 주차 컬럼과 같은 6px 셀 패딩을 전혀 건드리지 않는다 — 엣지 여백은
   순전히 위젯 컨테이너의 24px 패딩에서 나오므로 컬럼 폭 재분배가 발생하지 않는다. */
.widget__body.pad > .table-scroll.matrix-scroll{margin:0}
/* 아래 두 규칙은 일반 표의 엣지 패딩 규칙(.widget__body.pad > .table-scroll
   th/td:first/last-child, 특이도 0,4,1)과 특이도가 같아 소스 순서상 밀리므로,
   .table-scroll.matrix-scroll을 앞에 붙여 특이도를 확실히 더 높게 만든다. */
.widget__body.pad > .table-scroll.matrix-scroll .data-table.matrix th:first-child,
.widget__body.pad > .table-scroll.matrix-scroll .data-table.matrix td:first-child{padding-left:0}
.widget__body.pad > .table-scroll.matrix-scroll .data-table.matrix th:last-child,
.widget__body.pad > .table-scroll.matrix-scroll .data-table.matrix td:last-child{padding-right:0}

/* 요약형 표(종목 + 소수의 수치/배지 컬럼) — 2026-07-16: 종목 열만 넓게 두고
   나머지 컬럼은 폭을 균등 분배. table-layout:fixed 특성상 폭을 지정한 첫
   컬럼 외 나머지는 남는 공간을 자동으로 똑같이 나눠 갖는다. 헤더는 위 기본
   규칙대로 항상 중앙(th에 별도 text-align 없음) — 첫 컬럼 값(종목명)만 좌측. */
.data-table.even-cols{table-layout:fixed}
.data-table.even-cols th:first-child,.data-table.even-cols td:first-child{width:30%;white-space:normal}
.data-table.even-cols td:first-child{text-align:left}
.data-table.even-cols td:not(:first-child){text-align:center;white-space:nowrap}

/* 조밀한 다열 그리드(스크리너·분기실적표) — 2026-07-16: 열 폭이 "비슷한 수준"일 땐
   내용 길이가 조금씩 달라도 균등폭으로 맞춘다. 종목명/섹터명처럼 실제로 폭 차이가
   크게 나는 열만 colgroup으로 예외를 두고, 그 외 숫자·배지 열은 전부 동일폭.
   table-layout:fixed라 좁은 화면에서 글자가 찌그러지지 않도록 min-width로
   하한을 잡고 .table-scroll의 가로 스크롤에 맡긴다(내용 넘침 방지로 ellipsis 처리). */
.data-table.grid-fixed{table-layout:fixed}
.data-table.grid-fixed th,.data-table.grid-fixed td{overflow:hidden;text-overflow:ellipsis}
/* 2026-07-18: heat-cell 배지(등락%·YoY·서프라이즈 등)는 항상 짧고 고정된
   포맷이라 줄임표가 필요 없는데, 배지 자체의 min-width(82px)가 브라우저의
   "이 셀이 필요로 하는 폭" 계산에 그대로 반영되면서 실제 글자 폭과 무관하게
   더러 좁은 컬럼에서 "…" 잔상이 덧그려지는 문제가 실측 확인됨(숫자는 안 잘리고
   옆에 점만 남음). 배지가 든 셀은 폭을 넉넉히 잡는 것과 별개로 아예 줄임표
   계산 대상에서 제외한다. */
.data-table.grid-fixed td:has(.heat-cell){overflow:visible;text-overflow:clip}
.data-table.grid-fixed .num-badge{width:auto;min-width:82px}
/* 2026-08 디자인 B3-4: 종목상세 분기 실적 추이 표 전용 — 기존 .sticky-first는
   @media(max-width:768px) 안에만 있어 데스크톱에서 무효인데, 이 표는 모바일과
   무관하게 항상 가로로 길어(min-width:1190px) 데스크톱에서도 첫 컬럼(항목명)이
   스크롤에 딸려가면 어떤 분기 값인지 위쪽 헤더까지 다시 스크롤해야 하는 불편이
   있었다. 다른 페이지의 .sticky-first(스크리너·EPS 등)에 영향 주지 않도록
   별도 클래스로 분리 — 미디어쿼리 없이 항상 적용. overflow-x:auto wrapper의
   조상에 overflow:hidden/transform이 없음을 확인해 sticky가 정상 동작한다. */
.data-table.sticky-first-desktop th:first-child,.data-table.sticky-first-desktop td:first-child{
  position:sticky;left:0;background:var(--surface-2);z-index:1;box-shadow:1px 0 0 var(--line);
}

/* Table scroll wrapper — table{width:100%}(위) + table-layout:auto 기본값 조합이
   콘텐츠와 무관하게 표를 부모 폭까지 늘리고 표마다 컬럼 폭을 제각각 재분배해
   셀 간격이 표마다 흔들리는 문제가 있었음(위젯 폭 꽉 채운 5~8컬럼 표에서
   숫자 셀에 실제 필요폭의 1.5~2배 여백이 생김). 좁은 표(5~7컬럼)는 max-width로
   캡하고, widget__body.pad 안에서는 표가 위젯 테두리까지 자연스럽게 bleed 되는
   표준 패턴으로 통일해 표마다 패딩 유무가 달라지는 문제도 없앤다. */
.table-scroll{overflow-x:auto}
.table-scroll.compact{max-width:820px}
/* 직계 자식(>)에만 적용 — grid-2 등으로 한 겹 더 감싸인 table-scroll(예: WoW
   상향/하향 좌우 배치)까지 걸리면 매 컬럼마다 -24px 마진+48px 폭 bleed가
   중첩되어 뷰포트 밖으로 넘치는 가로 스크롤이 생겼었음. */
.widget__body.pad > .table-scroll{margin:0 calc(var(--s5) * -1)}
/* table-scroll이 이미 음수마진으로 위젯 테두리까지 bleed된 상태라 표 자체는
   그 100%만 채우면 됨 — 예전엔 여기에 +48px를 더 더해 표가 table-scroll의
   가시영역(특히 .compact 상한 820px)보다 넓어져, 스크롤바 표시 없이 마지막
   컬럼이 잘려 보이는 버그가 있었음(브레드스 표에서 "평균 변화율" 컬럼 확인). */
.widget__body.pad > .table-scroll table{width:100%}
.widget__body.pad > .table-scroll th:first-child,.widget__body.pad > .table-scroll td:first-child{padding-left:var(--s5)}
.widget__body.pad > .table-scroll th:last-child,.widget__body.pad > .table-scroll td:last-child{padding-right:var(--s5)}
/* grid-2 등으로 한 겹 더 감싸인 table-scroll(위 두 규칙의 >가 일부러 걸러내는
   대상)은 bleed를 안 받아 widget__body.pad의 24px 패딩이 그대로 살아있는데,
   거기에 표 자체의 기본 셀 패딩(8~10px)까지 더해져 텍스트가 다른 표보다
   8px 더 안쪽에서 시작하는 문제가 실측으로 확인됨(예: 종목별 이익 전망 변화
   표의 티커가 다른 표의 첫 컬럼보다 오른쪽으로 밀려 보임). 이런 표는 이미
   부모 쪽에서 24px 여백을 받고 있으니 표 자체의 첫/끝 컬럼 패딩은 0으로
   비워, 다른 표들과 같은 위치(위젯 안쪽 25px 지점)에서 텍스트가 시작하게
   맞춘다. */
.grid-2 .table-scroll th:first-child,.grid-2 .table-scroll td:first-child{padding-left:0}
.grid-2 .table-scroll th:last-child,.grid-2 .table-scroll td:last-child{padding-right:0}
@media (max-width:768px){
  .data-table.sticky-first th:first-child,.data-table.sticky-first td:first-child{
    position:sticky;left:0;background:var(--surface-2);z-index:1;box-shadow:1px 0 0 var(--line);
  }
}

/* Tabs */
.tabs{display:flex;gap:var(--s5);border-bottom:1px solid var(--line);margin-bottom:var(--s5)}
.tabs button{padding:10px 2px;font-size:14px;color:var(--mute);background:none;border:none;border-bottom:2px solid transparent}
.tabs button.active{color:var(--ink);font-weight:700;border-bottom-color:var(--ink)}

/* Segment — Spectrum 세그먼트 토글: 소프트 트랙 + 개별 pill 활성 상태 */
.seg{display:inline-flex;align-self:flex-start;background:var(--surface-hover);padding:2px;gap:2px;border-radius:var(--r-md)}
.seg button{padding:6px 12px;font-size:12px;background:transparent;border:none;border-radius:var(--r-sm);color:var(--mute);transition:background var(--t) var(--ease),color var(--t) var(--ease)}
.seg button.active{background:var(--surface-2);color:var(--ink);font-weight:700;box-shadow:var(--shadow-sm)}

/* Buttons — Spectrum: 항상 pill, 눌림 스케일, 아웃라인 포커스 */
/* 2026-08-02: white-space:nowrap·flex-shrink:0이 없으면, 버튼이 긴 형제
   요소(예: 종목상세 헤더의 긴 회사명)와 같은 flex 행에 있을 때 버튼 자체가
   찌그러지며 라벨 텍스트가 여러 줄로 쪼개지는 문제가 실측 확인됨(좁은 화면). */
.btn{font:700 13px/1 var(--font-sans);border-radius:var(--r-pill);padding:10px 16px;border:1px solid transparent;transition:background var(--t) var(--ease),border-color var(--t),scale var(--t-fast) var(--ease);display:inline-flex;align-items:center;gap:6px;white-space:nowrap;flex-shrink:0}
.btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.btn:active{scale:var(--press-scale)}
.btn:disabled{opacity:.5;cursor:default}
.btn-primary{background:var(--fill-inverse);color:#fff}.btn-primary:hover{background:var(--fill-inverse-hover)}
.btn-accent{background:var(--accent);color:#fff}.btn-accent:hover{background:var(--accent-hover)}
.btn-secondary{background:var(--surface-hover);border-color:var(--line);color:var(--ink)}.btn-secondary:hover{background:var(--gray-200)}
.btn-ghost{background:transparent;border-color:transparent;color:var(--accent)}.btn-ghost:hover{background:var(--surface-hover)}

/* Input — Spectrum TextField: 2px 테두리, 포커스 시 링 대신 테두리를 어둡게 */
.input{width:100%;height:40px;box-sizing:border-box;font-size:14px;line-height:1.4;color:var(--input-text);background:var(--input-bg);border:2px solid var(--input-border);border-radius:var(--r-md);padding:8px 11px}
.input::placeholder{color:var(--input-placeholder)}
.input:focus{outline:none;border-color:var(--accent)}
.label{font-size:12px;font-weight:700;color:var(--ink);margin-bottom:6px;display:block}
.form-group{margin-bottom:var(--s4)}

/* Picker — Spectrum 드롭다운: 네이티브 <select> 대신 트리거 버튼+커스텀 팝업(js/picker.js) */
.picker{position:relative}
.picker__trigger{width:100%;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:14px;color:var(--body);background:var(--surface-2);border:2px solid var(--line);border-radius:var(--r-md);padding:8px 11px;cursor:pointer;text-align:left}
.picker__trigger:hover{border-color:var(--gray-400)}
.picker__trigger:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.picker.is-open .picker__trigger{border-color:var(--ink)}
.picker__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.picker__chevron{width:16px;height:16px;stroke:var(--mute);flex-shrink:0;transition:transform var(--t) var(--ease)}
.picker.is-open .picker__chevron{transform:rotate(180deg)}
.picker__menu{position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-md);z-index:var(--z-dropdown);max-height:280px;overflow-y:auto;padding:4px;list-style:none;margin:0}
.picker__menu[hidden]{display:none}
.picker__item{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px;font-size:14px;color:var(--body);border-radius:var(--r-sm);cursor:pointer}
.picker__item:hover{background:var(--surface-hover)}
.picker__item:focus{outline:2px solid var(--accent);outline-offset:-2px;background:var(--surface-hover)}
.picker__item.is-selected{font-weight:700;color:var(--ink)}
.picker__item .picker__check{width:14px;height:14px;stroke:var(--accent);flex-shrink:0;visibility:hidden}
.picker__item.is-selected .picker__check{visibility:visible}

/* Grid */
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:var(--s4)}
.grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:var(--s4)}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s4)}
.grid-5{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--s4)}
/* grid item의 min-width 기본값은 auto(=내용물의 자연폭) — 폭이 넓은 표 같은
   콘텐츠가 들어가면 1fr 트랙이 그 폭 아래로 못 줄어들어 그리드 전체가
   뷰포트 밖으로 넘치는 문제가 있었음(WoW 상향/하향 좌우 배치에서 발견). */
.grid-2>*,.grid-3>*,.grid-4>*,.grid-5>*{min-width:0}

/* Util */
/* mb-1/2/3·mt-1/2/3·ml-1/2/3은 --s1~--s3 스케일과 이름이 맞아떨어져 이미
   쓰이고 있었지만(mb-2 25곳·mb-3 34곳 등, gap-2/gap-3처럼) 정작 정의 자체가
   없어 전부 margin 0으로 조용히 무시되고 있었다(2026-08 실측 발견 — 스크리너
   프리셋 저장 UI 간격 버그를 추적하다 드러남). 사이트 전역에 걸친 문제라
   개별 마크업이 아니라 여기서 한 번에 고친다. */
.mb-1{margin-bottom:var(--s1)}.mb-2{margin-bottom:var(--s2)}.mb-3{margin-bottom:var(--s3)}
.mb-4{margin-bottom:var(--s4)}.mb-5{margin-bottom:var(--s5)}.mb-6{margin-bottom:var(--s6)}
.mt-1{margin-top:var(--s1)}.mt-2{margin-top:var(--s2)}.mt-3{margin-top:var(--s3)}
.mt-4{margin-top:var(--s4)}.mt-5{margin-top:var(--s5)}.mt-6{margin-top:var(--s6)}
.ml-1{margin-left:var(--s1)}.ml-2{margin-left:var(--s2)}.ml-3{margin-left:var(--s3)}
.ta-center{text-align:center}
.btn-xs{height:26px;padding:0 8px;font-size:12px;font-weight:400}
.flex{display:flex}.flex-center{display:flex;align-items:center}
/* 스크리너 필터+결과 2단 레이아웃 — 데스크톱에서는 상단 정렬(원래 인라인
   style="align-items:flex-start"였던 값을 이관). 인라인 style은 항상 외부
   시트보다 우선하므로, 모바일에서 flex-direction:column으로 바뀔 때 함께 넣을
   align-items:stretch 오버라이드(아래 768px 미디어쿼리)가 먹지 않는 문제가
   있었다 — 클래스 기반으로 옮겨 우선순위를 정상화한다. */
.flex:has(#filterPanel){align-items:flex-start}
.gap-2{gap:var(--s2)}.gap-3{gap:var(--s3)}.gap-4{gap:var(--s4)}
.ml-auto{margin-left:auto}
.text-mute{color:var(--mute)}.text-ink{color:var(--ink)}.text-faint{color:var(--faint)}
.fw-700{font-weight:700}.fs-12{font-size:12px}.fs-13{font-size:13px}

/* News */
.news-item{padding:12px 4px;border-bottom:1px solid var(--line)}
.news-title{font-size:14px;font-weight:700;color:var(--ink)}
.news-line{font-size:13px;color:var(--body);margin-top:4px}
.news-src{font-size:12px;color:var(--mute);margin-top:6px}
.news-src a{color:var(--accent)}.news-src a:hover{text-decoration:underline}

/* Pagination — 뉴스 등 10개 단위 목록의 페이지 이동(이전/숫자.../다음) */
.pagination{display:flex;align-items:center;justify-content:center;gap:4px;margin-top:16px;flex-wrap:wrap}
.pagination button{min-width:32px;height:32px;padding:0 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface-2);color:var(--mute);font:600 12px var(--font-sans);cursor:pointer;transition:background var(--t) var(--ease),border-color var(--t),color var(--t)}
.pagination button:hover:not(:disabled):not(.active){border-color:var(--ink);color:var(--ink)}
.pagination button.active{background:var(--fill-inverse);border-color:var(--fill-inverse);color:#fff}
.pagination button:disabled{opacity:.4;cursor:default}

/* Modal */
.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:var(--z-modal);display:flex;align-items:center;justify-content:center}
.modal{background:var(--surface-2);border-radius:16px;box-shadow:var(--shadow-md);padding:var(--s6);max-width:480px;width:90%}
.modal-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--s5)}
.modal-title{font-size:18px;font-weight:700;color:var(--ink)}
.modal-close{background:none;border:none;font-size:20px;color:var(--mute);line-height:1}
.modal-footer{display:flex;justify-content:flex-end;gap:var(--s3);margin-top:var(--s5)}

/* Search dropdown */
.search-wrap{position:relative}
.search-dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-md);z-index:var(--z-dropdown);max-height:260px;overflow-y:auto}
.search-item{padding:10px 12px;cursor:pointer;font-size:14px;display:flex;align-items:center;gap:var(--s3)}
.search-item:hover{background:var(--surface-hover)}
.search-item .ticker{font-weight:700;color:var(--ink);min-width:56px;font-family:var(--font-latin)}
.search-item .name{color:var(--mute);font-size:13px}

/* Spinner */
.spinner{display:inline-block;width:20px;height:20px;border:2px solid var(--line);border-top-color:var(--accent);border-radius:50%;animation:spin .6s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* Footer */
.site-footer{border-top:1px solid var(--line);padding:var(--s5);font-size:12px;color:var(--mute);text-align:center;margin-top:var(--s8)}

/* Chip filter */
.filter-wrap{display:flex;flex-wrap:wrap;gap:var(--s2);margin-bottom:var(--s4)}
.chip{padding:4px 12px;border:1px solid var(--line);border-radius:var(--r-pill);font-size:12px;color:var(--mute);background:var(--surface-2);cursor:pointer}
.chip:hover{border-color:var(--ink);color:var(--ink)}
.chip.active{background:var(--fill-inverse);border-color:var(--fill-inverse);color:#fff;font-weight:700}

/* Screener range input */
.range-group{display:flex;flex-direction:column;gap:4px}
.range-group label{font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--mute)}
.range-inputs{display:flex;gap:6px;align-items:center}
.range-inputs input{flex:1;min-width:0;padding:6px 8px;font-size:13px;border:1px solid var(--input-border);border-radius:var(--r-sm);color:var(--input-text);background:var(--input-bg)}
.range-inputs input:focus{outline:none;border-color:var(--accent)}
.range-sep{color:var(--faint);font-size:12px}

/* Breadth bar */
.breadth-bar{display:flex;height:6px;border-radius:999px;overflow:hidden}
.breadth-up{background:var(--up)}
.breadth-flat{background:var(--line)}
.breadth-down{background:var(--down)}

/* ── Responsive (tablet/mobile) ──────────────────────────────── */
@media (max-width: 1024px) {
  .grid-3,.grid-4,.grid-5{grid-template-columns:1fr 1fr}
}

/* 2026-07-19: 검색창은 원래 768px 이하에서 완전히 숨기고 대체 진입점이 없어
   모바일에서 검색 자체가 불가능했던 버그가 있었음(실측 확인) — 처음엔 아이콘
   버튼 토글로 고쳤으나, PC와 동일하게 검색창을 항상 노출하는 편이 낫다는
   피드백에 따라 토글 없이 입력창 자체를 폭에 맞춰 줄여서 상시 노출한다. */
.mobile-search-btn{display:none}

@media (max-width: 768px) {
  html,body{font-size:13px}

  .nav{gap:var(--s3);padding:0 var(--s3);flex-wrap:nowrap}
  .nav-logo{font-size:14px;margin-right:var(--s2)}
  .nav-menu{gap:0;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .nav-menu::-webkit-scrollbar{display:none}
  .nav-menu a{padding:0 10px;font-size:13px;white-space:nowrap}
  .nav-user{margin-left:var(--s2)}
  .nav-user .btn{padding:6px 10px;font-size:12px}

  /* 사이드바 셸(Meridian) 모바일 접이 — 상단 가로 스크롤 탭으로 전환 */
  .mds-shell{flex-direction:column}
  .mds-sidebar{width:100%;height:auto;position:static;border-right:none;border-bottom:1px solid var(--chrome-line);padding:var(--s3) 0}
  .mds-sidebar .nav-logo{font-size:14px;padding:0 var(--s3) var(--s3)}
  .mds-sidebar .nav-menu{flex-direction:row}
  .mds-sidebar .nav-menu a{padding:8px 12px;font-size:13px;border-left:none;border-bottom:2px solid transparent}
  .mds-sidebar .nav-menu a.active{border-left-color:transparent;border-bottom-color:var(--accent)}
  .mds-topbar{gap:var(--s3);padding:0 var(--s3)}
  /* PC와 동일하게 검색창을 상시 노출 — 토글 버튼 없이 폭만 줄여서 맞춘다. */
  .search-wrap{flex:1 1 auto;min-width:0}
  .mds-topbar .nav-search{width:100%}
  .mds-topbar .nav-search input{width:100%;min-width:0}

  .page{padding:var(--s4) var(--s3)}
  .page-title{font-size:22px;margin-bottom:var(--s4)}
  .section-head .title{font-size:16px}

  /* 좁은 화면에서 위젯 헤더의 정렬 세그먼트 버튼(예: 스크리너 결과 정렬)이
     제목과 한 줄에 다 안 들어가 페이지 전체를 가로로 밀어내는 문제 —
     헤더/세그먼트 둘 다 줄바꿈을 허용해 폭을 안전하게 유지한다. */
  .widget__head{flex-wrap:wrap}
  .seg{flex-wrap:wrap}

  /* 2026-08-02: section-head(예: 종목상세 "주요 주가 지표", 홈 "시장 지수")도
     같은 문제 — 제목 옆 ml-auto 텍스트(업데이트 시각 등)가 좁은 화면에서
     줄바꿈 없이 제목과 겹쳐 보이는 게 실측 확인됨. widget__head와 동일하게
     줄바꿈을 허용한다. */
  .section-head{flex-wrap:wrap}

  .card{padding:var(--s4)}
  .card-value{font-size:20px}

  .modal{padding:var(--s5);width:92%}

  .data-table th,.data-table td{padding:7px 8px;font-size:12.5px}

  .tabs{gap:var(--s4);overflow-x:auto;-webkit-overflow-scrolling:touch}

  /* 스크리너: 필터 패널이 인라인 width:280px로 고정돼 있어 좁은 화면에서
     결과 테이블과 나란히 눌려버림 → 위아래로 쌓이게 전환. 이 컨테이너는
     데스크톱용 인라인 style="align-items:flex-start"를 갖고 있어서, 세로
     stack으로 바뀐 뒤에도 그 값이 남아 각 자식이 컨테이너 폭까지 늘어나지
     않고(stretch 대신 flex-start) 내용물(결과 표의 min-width) 크기로 줄어들며
     페이지 전체가 가로로 밀려나는 문제가 있었다 — align-items:stretch로 되돌린다. */
  #filterPanel{width:100% !important}
  .flex:has(#filterPanel){flex-direction:column;align-items:stretch}
}

/* 2026-07-19: 갤럭시 Z 폴드처럼 펼쳤을 때 폭이 600~768px대인 "넓은 모바일"
   기기에서, grid-2~5를 768px 기준으로 전부 1열로 눌러버리면 화면 폭이
   충분한데도 박스가 세로로 하나씩만 나열되어 공간이 크게 낭비되는 문제가
   실측 확인됨. 진짜 좁은 폰(600px 미만)에서만 1열로 접고, 그보다 넓은
   구간은 위 768px 블록의 나머지 모바일 스타일(사이드바 접힘 등)은 유지한 채
   grid-3/4/5는 1024px 티어의 2열을, grid-2는 기본 2열을 그대로 살린다. */
@media (max-width: 599px) {
  .grid-2,.grid-3,.grid-4,.grid-5{grid-template-columns:1fr;gap:var(--s3)}
}
