/* ── Toss TDS Light 토큰 (디자인 컨셉 matches.html에서 이식) ── */
@font-face {
  font-family: "Pretendard Variable";
  src: url("fonts/PretendardVariable.woff2") format("woff2-variations");
  font-weight: 45 920;
  font-display: swap;
}
:root {
  --font: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --bg: #f2f4f6;
  --surface: #ffffff;
  --text: #191f28;
  --text-primary: #333d4b;
  --text-secondary: #4e5968;
  --text-tertiary: #6b7684;
  --text-quaternary: #b0b8c1;
  --text-brand: #3182f6;
  --brand: #3182f6;
  --brand-strong: #1b64da;
  --brand-weak: rgba(49, 130, 246, 0.12);
  --success: #029359;
  --success-weak: rgba(2, 162, 98, 0.16);
  --danger: #e42939;
  --danger-weak: rgba(240, 68, 82, 0.12);
  --neutral-weak: rgba(7, 25, 76, 0.05);
  --border: rgba(2, 32, 71, 0.05);
  --border-strong: #d1d6db;
  --hero-bg: #191f28;
  --r-xs: 8px; --r-s: 12px; --r-m: 16px; --r-full: 999px;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--font);
       font-size: 15px; line-height: 1.6; -webkit-font-smoothing: antialiased;
       letter-spacing: 0; word-break: keep-all; }
a { color: var(--text-brand); text-decoration: none; }
.b-score, .stat-card__value { font-feature-settings: "tnum"; font-variant-numeric: tabular-nums; }
/* 표가 본문 폭을 결정한다 — 8열 NRFI 표(최소 1254px, 내역은 .b-table-head--nrfi
   주석의 폭 예산)가 들어가야 셀 안에서 문장이 끊기지 않는다. 콘텐츠 박스는
   1320-64=1256px이라 여유가 2px뿐이다. 표만 컨테이너 밖으로 빼면 헤더·요약 카드와
   폭이 어긋나 어색하므로 페이지 전체를 같이 넓힌다. */
.container { max-width: 1320px; margin: 0 auto; padding: 24px 32px 64px; }
h1 { font-size: 22px; font-weight: 700; color: var(--text); }
h2 { font-size: 17px; font-weight: 700; margin-top: 28px; }

/* 헤더/네비 */
.site-header { display: flex; align-items: center; justify-content: space-between;
               padding: 8px 0 16px; border-bottom: 1px solid var(--border); margin-bottom: 24px; }
.site-header__title { font-size: 18px; font-weight: 700; }
.nav a { margin-left: 4px; color: var(--text-tertiary); font-size: 14px; font-weight: 600;
         padding: 8px 12px; border-radius: var(--r-xs); }
.nav a:hover { background: var(--neutral-weak); color: var(--text-primary); }
/* 현재 섹션 — 하단 탭바의 .is-current와 같은 판정(nav_current)을 쓴다. 색만으로
   구분하면 색각 이상에서 안 보이므로 배경까지 함께 준다. */
.nav > a.is-current { background: var(--brand-weak); color: var(--brand-strong); }
.nav-lang { margin-left: 12px; }
.nav-lang a { padding: 8px 6px; }
.nav-lang .is-current { color: var(--text); font-weight: 700; }

/* 하단 탭바 — 모바일 전용(데스크톱은 상단 .nav를 그대로 쓴다) */
.tabbar { display: none; }

/* 기존 카드류 (date/history/accuracy가 계속 사용) — 라이트 재정의 */
.card, .game-card, .stat-card { background: var(--surface); border: 1px solid var(--border);
       border-radius: var(--r-m); padding: 18px 20px; }
.game-card { display: block; margin-bottom: 12px; color: inherit; transition: background 0.15s; }
.game-card:hover { background: rgba(0, 23, 51, 0.02); }
.matchup { font-size: 16px; font-weight: 600; margin-bottom: 12px; color: var(--text); }
.winbar { display: flex; height: 8px; border-radius: var(--r-full); overflow: hidden;
          background: var(--neutral-weak); margin: 8px 0; }
.winbar__home { background: var(--brand); }
.winbar__away { background: var(--border-strong); }
.winbar__label { display: flex; justify-content: space-between; font-size: 13px; color: var(--text-secondary); }
.chip { display: inline-block; background: var(--brand-weak); color: var(--text-brand);
        border-radius: 6px; padding: 3px 8px; font-size: 12px; font-weight: 600; }
.commentary { color: var(--text-secondary); margin-top: 10px; }
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin: 16px 0; }
.stat-card__value { font-size: 28px; font-weight: 700; }
.stat-card__label { color: var(--text-tertiary); font-size: 13px; }
.compare-table, .recent-table { width: 100%; border-collapse: collapse; margin: 16px 0;
       background: var(--surface); border-radius: var(--r-s); overflow: hidden; }
.compare-table th, .compare-table td, .recent-table th, .recent-table td {
       text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.recent-table th, .compare-table th { color: var(--text-tertiary); font-size: 12px; font-weight: 600;
       background: var(--bg); }
.badge { display: inline-block; border-radius: 6px; padding: 2px 8px; font-size: 12px; font-weight: 600; }
.badge--o { background: var(--success-weak); color: var(--success); }
.badge--x { background: var(--danger-weak); color: var(--danger); }
.callout { background: var(--surface); border-left: 3px solid var(--brand); border-radius: var(--r-xs);
           padding: 12px 16px; color: var(--text-secondary); margin: 16px 0; font-size: 14px; }
.footer { color: var(--text-secondary); font-size: 12px; margin-top: 32px; padding-top: 16px;
          border-top: 1px solid var(--border); }
.served-model { color: var(--text-secondary); font-size: 14px; }
.team-logo { width: 22px; height: 22px; vertical-align: middle; margin-right: 6px; }
.team-logo--lg { width: 34px; height: 34px; }

/* 컨셉 B — 리스트 (index) */
.b-date-title { font-size: 22px; font-weight: 700; color: var(--text); }
.b-date-sub { font-size: 13px; color: var(--text-tertiary); margin: 2px 0 16px; }
.b-summary { display: flex; gap: 12px; margin-bottom: 16px; }
.b-summary-item { flex: 1; background: var(--surface); border-radius: 10px; padding: 12px 14px;
                  border: 1px solid var(--border); }
.b-summary-label { font-size: 12px; color: var(--text-tertiary); }
.b-summary-value { font-size: 20px; font-weight: 700; color: var(--text); margin-top: 2px;
                   font-feature-settings: "tnum"; }
.b-summary-value.upcoming { color: var(--brand); }
/* 상태 · 원정 · 홈 · 스코어 · 모델 · 배당 · 구장 (7열).
   배당 열은 모델 뒤·구장 앞이다 — 모델(우리 예측)과 시장 가격을 나란히 두되 칸을
   갈라 눈이 두 층을 섞지 않게 한다.

   폭 예산: 최소폭 합 90+170+170+110+150+140+120 = 950 + gap 12×6=72 + 패딩 32 +
   보더 2 = 1056px ≤ .container 콘텐츠 박스(1320-64=1256). 여유 200px.
   (NRFI 표는 여유가 2px뿐이라 별도 규칙 .b-table-head--nrfi로 갈라져 있다 —
   이 규칙을 만질 때 그쪽 트랙은 건드리지 않는다.)

   배당 열 상한 170px의 근거(Pretendard 13px 글리프 폭 실측):
     ko "홈 1.54 / 원정 2.56"      103px
     en "Home 1.54 / Away 2.56"    136px
     ja "ホーム 1.54 / アウェイ 2.56"  154px  ← 3언어 중 최대
   총득점 줄은 더 짧다(ko 126 / en 122 / ja 119). 여유 200px 중 배당·모델 트랙이
   상한까지 자라도(각 +30/+50) 120px이 두 1fr 열로 남으므로 데스크톱에서 이 열은
   실제로 170px을 받는다 → ja도 한 줄에 들어간다(여백 16px).

   상한을 170px → 190px로 올린 이유: 총득점 줄에 오버/언더 이모지(🔼 🔽)가 붙었다
   (messages.py odds_total). 이모지는 Pretendard에 없어 Apple Color Emoji로
   폴백되는데 그 advance는 정확히 1em이라 13px에서 13px씩, 앞의 공백까지 더해
   줄이 +32.5px 길어진다. 13px 기준 실측(Pretendard hmtx + Apple Color Emoji hmtx,
   ja의 한자 '合計'는 Pretendard에 없어 Hiragino 폴백 13px/자):
     라인 8.5 기준 총득점 줄  ko 163.97px / en 159.80px / ja 156.27px
     최장 라인 10.5 기준       ko 171.96px / en 167.78px / ja 164.25px  ← 최악
     승패 줄(변화 없음)        ko 105.61px / en 138.82px / ja 157.22px
   두 줄 중 긴 쪽이 열 폭을 정하므로 최악은 ko 171.96px → 190px 상한 대비 여유 18px.
   최소폭은 140px 그대로라 위 예산(1056px)은 안 변한다. 모델 트랙(150→200, 여지 50)과
   배당 트랙(140→190, 여지 50)의 합이 100px이라 free space 200px 안에서 둘 다 상한에
   닿는다 — 데스크톱에서 이 열은 실제로 190px을 받는다.
   (NRFI 표는 여유 2px이라 이모지를 못 받는다. 그쪽 odds 문자열은 별개다.) */
.b-table-head, .b-row { display: grid;
  grid-template-columns: 90px minmax(170px, 1fr) minmax(170px, 1fr) 110px minmax(150px, 200px) minmax(140px, 190px) 120px;
  gap: 12px; align-items: center; }
.b-table-head { padding: 8px 16px; font-size: 12px; font-weight: 600; color: var(--text-secondary);
                background: #e8ebed; border-radius: 8px 8px 0 0; min-width: min-content;
                border: 1px solid transparent; border-bottom: none; }
.b-table-body { background: var(--surface); border-radius: 0 0 var(--r-s) var(--r-s); overflow: hidden;
                border: 1px solid var(--border); border-top: none; min-width: min-content; }
.b-row { padding: 14px 16px; border-bottom: 1px solid var(--border); color: inherit;
         transition: background 0.15s; }
.b-row:last-child { border-bottom: none; }
.b-row:hover { background: rgba(0, 23, 51, 0.02); }
.b-status { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; border-radius: 6px;
            font-size: 12px; font-weight: 600; }
.b-status.done { background: var(--neutral-weak); color: var(--text-secondary); }
.b-status.upcoming { background: var(--brand-weak); color: var(--brand-strong); }
/* 팀 칸 — 팀 행(로고+이름) 위, 선발 이름 아래(세로 2줄). index/game과 NRFI가 공유한다. */
.b-team-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: 15px; }
.b-team { display: flex; align-items: center; gap: 6px; min-width: 0; }
.b-team-name { font-weight: 600; color: var(--text-primary); }
.b-team-cell.winner .b-team-name { color: var(--text); font-weight: 700; }
.b-team-sp { font-size: 12px; color: var(--text-tertiary); }
/* 선발 투수 줄 — [얼굴][이름 / 스탯] 2단.
   스탯(ERA·1회 무실점)을 이름과 같은 줄에 두면 시작 위치가 이름 길이를 따라 행마다
   달라져 세로로 읽히지 않는다. 아래 줄로 내리면 모든 행에서 왼쪽 끝이 같아진다.
   얼굴은 이름 줄에 맞춘다(flex-start) — 두 줄 블록 가운데에 두면 이름과 어긋나 보인다. */
.b-sp { display: inline-flex; align-items: flex-start; gap: 6px; }
.b-sp-face { width: 24px; height: 24px; border-radius: var(--r-full); flex: none;
             background: var(--neutral-weak); }
/* 선발 미정 자리표시. img가 아니라 빈 원이므로 display를 따로 준다. */
.b-sp-face--none { display: inline-block; }
/* min-width:0 — 이 칸이 좁아질 때 flex 항목이 내용 최소폭 아래로 줄지 못해
   표를 밀어내는 것을 막는다(긴 투수 이름에서 실제로 난다). */
.b-sp-body { display: flex; flex-direction: column; min-width: 0; }
/* 색 위계: 이름(secondary) > 스탯(tertiary). quaternary(#b0b8c1)는 흰 배경에서
   대비 2.01:1로 WCAG AA(4.5:1)에 한참 못 미쳐 12px 본문에는 쓸 수 없다 — 실제로
   폰에서 ERA가 "안 보인다"는 보고가 나왔다. tertiary는 4.62:1로 통과한다.
   부모 .b-team-sp가 이미 tertiary이므로 스탯은 그와 같고, 이름만 한 단계 진하게 둔다. */
.b-sp-name { color: var(--text-secondary); }
.b-sp-stats { font-feature-settings: "tnum"; color: var(--text-tertiary); }
/* I-5/Pre-existing(final-review): NRFI 모바일 전용 행 라벨. 데스크톱에는 열 헤더가
   있어 불필요하므로 기본은 숨김 — 아래 모바일 폭 미디어쿼리 안 .b-row--nrfi
   스코프에서만 보인다. 텍스트는 항상 템플릿의 t()가 넣는다 — CSS content:에 문자열을
   박으면 en/ja 페이지에도 그 문자열이 그대로 나온다(이 버그가 이미 한 번 있었다). */
.b-team-cell-label, .b-row-label { display: none; }
.b-score { text-align: center; font-size: 19px; font-weight: 700; color: var(--text); }
.b-score.upcoming { color: var(--text-secondary); font-size: 14px; font-weight: 600; }
.b-score .sep { color: var(--text-quaternary); margin: 0 4px; font-weight: 400; }
.b-pitcher { font-size: 13px; color: var(--text-secondary); line-height: 1.5; }
.b-pitcher .label { color: var(--text-tertiary); margin-right: 4px; }
.b-pitcher .name { color: var(--text-primary); font-weight: 500; }
.b-model { font-size: 13px; color: var(--text-secondary); line-height: 1.5; }
.b-model .pct { color: var(--text); font-weight: 700; }
/* 배당 열. 크기·줄간격은 .b-model과 맞춘다 — 예전엔 배당 줄이 .b-model 안에 있어
   13px/1.5를 상속받았는데, 자기 열로 나오면서 상속 사슬이 끊겼다(그대로 두면 이
   칸만 본문 크기로 커진다). */
.b-odds-col { font-size: 13px; line-height: 1.5; }
/* 배당은 모델 수치(우리 예측)와 성격이 다른 시장 가격이다. 옆칸이지만 한 단계
   옅게 두어 눈이 두 층을 구분하게 한다. tabular-nums는 행마다 자릿수가
   달라도 소수점이 세로로 맞게 한다 — 가격 20개가 깔리는 칸이라 정렬이 읽기를 좌우한다. */
.b-odds { color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
.b-meta { font-size: 13px; color: var(--text-tertiary); }
.b-commentary { grid-column: 1 / -1; font-size: 13px; color: var(--text-secondary); margin: 4px 0 0; }
/* 컨테이너 자체가 표 폭에 맞춰 넓어졌으므로(위 .container 주석) 표를 밖으로
   빼낼 필요가 없다 — 헤더·요약 카드와 좌우가 정렬된다. 그보다 좁은 화면에서는
   overflow-x가 가로 스크롤로 폴백한다. */
.b-table-wrap { overflow-x: auto; }

/* 컨셉 A — 상세 히어로 (game) */
.a-detail-hero { background: var(--hero-bg); color: #fff; padding: 32px 24px;
                 border-radius: var(--r-m); margin-bottom: 24px; }
/* 데스크톱은 3열 2행, 모바일은 얼굴 행 + 정보 행으로 바뀐다. 배지("경기 전")는 가운데
   남고 시각·모델%만 아래로 내려가기 때문에, flex로는 마크업이 두 벌 필요해진다.
   grid-template-areas면 DOM 한 벌로 두 배치를 다 만든다. 모바일 재정의는 @media 참조. */
.a-detail-hero-inner { display: grid; gap: 12px 24px;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: "away status home"
                       "away meta   home";
  align-items: center; justify-items: center; }
.a-detail-col--away { grid-area: away; }
.a-detail-col--home { grid-area: home; }
.a-detail-status-col { grid-area: status; align-self: end; }
.a-detail-meta-col { grid-area: meta; align-self: start; min-width: 200px;
  display: flex; flex-direction: column; align-items: center; gap: 10px; }
.a-detail-team-col { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.a-detail-team-meta { font-size: 12px; color: rgba(255, 255, 255, 0.55); text-align: center; }

/* 선발 얼굴 + 우하단 팀 로고 배지 */
.a-detail-face { position: relative; width: 88px; height: 88px; }
.a-detail-face-img { width: 100%; height: 100%; display: block; border-radius: var(--r-full);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.18); }
.a-detail-face-badge { position: absolute; right: -3px; bottom: -3px; width: 30px; height: 30px;
  padding: 2px; background: var(--hero-bg); border-radius: var(--r-full); }
/* 선발 미정 자리표시. 머리(::before)와 어깨(::after)로 만든 실루엣이라 요청이 나가지 않는다 */
.a-detail-face--empty { background: rgba(255, 255, 255, 0.08); overflow: hidden; }
.a-detail-face--empty::before, .a-detail-face--empty::after {
  content: ""; position: absolute; left: 50%; transform: translateX(-50%);
  background: rgba(255, 255, 255, 0.25); }
.a-detail-face--empty::before { top: 20%; width: 30%; height: 30%; border-radius: var(--r-full); }
.a-detail-face--empty::after { bottom: -12%; width: 62%; height: 44%;
  border-radius: var(--r-full) var(--r-full) 0 0; }

.a-detail-sp-name { font-size: 16px; font-weight: 700; color: #fff; text-align: center; }
.a-detail-sp-stat { font-size: 11px; color: rgba(255, 255, 255, 0.75); }
/* ERA 줄은 1회 무실점 % 아래 보조 정보 — 한 단계 흐리게 두고 숫자는 고정폭으로 맞춘다. */
.a-detail-sp-stat--era { color: rgba(255, 255, 255, 0.55); font-feature-settings: "tnum"; }
.a-detail-status-badge { display: inline-flex; align-items: center; padding: 6px 12px;
  background: rgba(255, 255, 255, 0.12); color: rgba(255, 255, 255, 0.85);
  border-radius: var(--r-full); font-size: 13px; font-weight: 600; }
.a-detail-score-row { display: flex; align-items: baseline; gap: 4px; }
.a-detail-score-value { font-size: 48px; font-weight: 700; color: #fff;
                        font-feature-settings: "tnum"; line-height: 1; }
.a-detail-score-divider { color: rgba(255, 255, 255, 0.4); font-size: 28px; padding: 0 8px; }
.a-detail-time { font-size: 32px; font-weight: 700; color: #fff; }
.a-detail-model { font-size: 13px; color: rgba(255, 255, 255, 0.7); text-align: center; }
.a-detail-model .pct { color: #fff; font-weight: 700; }

/* 컨셉 A — 카드/섹션 */
.a-section-title { font-size: 17px; font-weight: 700; color: var(--text); margin: 0 0 16px; }
.a-card { background: var(--surface); border-radius: var(--r-s); padding: 20px; margin-bottom: 24px; }
.a-scoreboard-table { width: 100%; border-collapse: collapse; font-feature-settings: "tnum"; }
.a-scoreboard-table th { padding: 8px 4px; font-size: 13px; font-weight: 600; color: var(--text-tertiary);
       text-align: center; background: var(--bg); border-bottom: 1px solid var(--border); }
.a-scoreboard-table td { padding: 12px 4px; font-size: 15px; color: var(--text-primary);
       text-align: center; border-bottom: 1px solid var(--border); }
.a-scoreboard-table th:first-child, .a-scoreboard-table td:first-child {
       text-align: left; padding-left: 12px; font-weight: 600; color: var(--text); }
.a-game-info { background: var(--surface); border-radius: var(--r-s); padding: 20px;
       display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.a-game-info-item .label { font-size: 13px; color: var(--text-tertiary); margin-bottom: 4px; }
.a-game-info-item .value { font-size: 15px; color: var(--text); font-weight: 600; }

/* 스카우팅 시트 — 기존 클래스, 라이트 재정의 */
.scout { margin-top: 32px; }
.scout__sort-value { color: var(--text-tertiary); font-size: 13px; margin-top: -4px; }
.scout__pitchers { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 12px 0 24px; }
.scout__pitcher { background: var(--surface); border-radius: var(--r-s);
       padding: 14px 16px; display: flex; flex-direction: column; gap: 2px; font-size: 14px; }
.scout__lineup { background: var(--surface); border-radius: var(--r-s); padding: 16px 20px; margin-bottom: 16px; }
.scout__lineup h3 { margin: 0 0 8px; font-size: 15px; }
.scout__lineup-tag { color: var(--text-tertiary); font-size: 12px; font-weight: 400; }
/* 텍스트만 있을 땐 baseline이 옳았지만, 얼굴이 섞이면 baseline이 이미지 하단에 걸려
   줄이 어긋난다 → center. flex:none이 없으면 컨테이너가 원형을 타원으로 찌그러뜨린다. */
.scout__batter { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
       padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 14px; }
.scout__batter-face { width: 28px; height: 28px; border-radius: var(--r-full); flex: none; }
.scout__batter:last-child { border-bottom: none; }
.scout__batter-slot { color: var(--text-tertiary); }
.scout__batter-name { font-weight: 600; }
.scout__bvp { color: var(--text-secondary); font-size: 13px; }
.scout__batter.is-small-sample .scout__bvp { color: var(--text-tertiary); }
.scout__lineup-empty { color: var(--text-secondary); }
.scout__form, .scout__h2h { background: var(--surface); border-radius: var(--r-s);
       padding: 14px 20px; margin-bottom: 16px; font-size: 14px; }
.scout__form h3, .scout__h2h h3 { margin: 0 0 6px; font-size: 15px; }

/* NRFI 8열 변형 — index의 b-grid를 재사용하되 트랙만 교체. 선발 전용 열이 팀 칸
   안으로 옮겨가면서(Task 2) 원정/홈 칸이 각자 1fr을 받는다. 8번째는 1회 배당(Task 6).
   배분 의도: 팀명+선발 두 줄을 담는 원정/홈(1fr)에 여유를 주고, 값이 짧은
   팀1회(max 150)·구장(max 210)·배당(72)의 상한을 낮춰 남는 폭이 앞쪽으로 흐르게 한다. */
/* 열 최소폭은 3언어 실렌더에서 "그 열의 가장 긴 한 줄"을 Pretendard 글리프 폭으로
   실측해 잡았다(문자수 × 평균폭 추정은 20% 넘게 과대평가했다). 최소폭을 실제
   필요치로 두어야, 표가 그보다 좁아졌을 때 셀 안에서 문장이 끊기는 대신
   overflow-x 스크롤로 폴백한다.
   실측(px): 상태 77 · 원정 235 · 홈 220 · 시작 72 · 팀1회 117 · 무득점 90 · 구장 183 ·
   배당 60("初回オッズ"가 3언어 중 가장 넓다 — 값 "1.83"보다 헤더가 폭을 결정한다)

   폭 예산(Task 6에서 갱신): 최소폭 합 84+240+240+104+124+96+190+72 = 1150
   + gap 10×7=70 + 패딩 32 + 보더 2 = 1254px ≤ .container 콘텐츠 박스(1320-64=1256).

   **이 표만 열 간 gap이 10px인 이유**: 배당 열이 붙어 7열→8열이 되면서 열 사이 공기가
   72(12×6)→84(12×7)px로 저절로 늘었다. 그 늘어난 몫을 되돌려 받는 게 어느 열의 실측
   여유를 깎는 것보다 싸다 — 2px만 줄이면 14px이 통째로 나오고, 그 덕에 구장 열이
   Task 6 이전 값(190/210)을 그대로 지킨다. 다른 열은 한 px도 건드리지 않았다.

   폭을 열에서 회수하면 안 되는 이유(시도했다가 되돌린 기록):
   - 구장을 190→160으로 낮추면 최대 폭에서도 접힌다. 그리드의 "Maximize Tracks"는
     남는 free space를 상한 여유가 있는 **비-fr 트랙에 균등 배분**하는데, 대상이
     팀1회·구장 둘뿐이라 9px씩만 간다 → 구장 169px < 실측 183px. 상한만 210으로
     올려도 free space 자체가 18px이라 효과가 없다(725d8bb가 고친 증상의 재발).
   - 시작(104, 실측 72)의 32px 쿠션도 낭비가 아니다 — local-time.js가 비US 방문자에게
     텍스트를 로컬 시각으로 갈아끼우고, 로컬 날짜가 슬레이트와 다르면 월·일까지 앞에
     붙인다(ac798e5). 서버가 구운 "6:40 PM ET" 기준 실측 72px은 하한일 뿐이다.

   남는 여유는 2px뿐이다 — 다음에 열을 더할 땐 어딘가에서 반드시 같은 만큼 회수해야
   한다. 그보다 좁은 화면은 .b-table-wrap의 overflow-x가 스크롤로 폴백한다. */
.b-table-head--nrfi, .b-row--nrfi { gap: 12px 10px; grid-template-columns:
  84px minmax(240px, 1fr) minmax(240px, 1fr) 104px minmax(124px, 150px) 96px minmax(190px, 210px) 72px; }
.b-sortable { cursor: pointer; user-select: none; }
.b-sortable:hover { color: var(--text); }
.b-composite { font-weight: 700; font-feature-settings: "tnum"; }
/* 1회 배당 칸. 표의 다른 값은 우리가 센 기록이고 이건 시장 가격이라, .b-meta와 같은
   보조 층(13px/tertiary)에 둔다. tabular-nums로 소수점을 세로로 맞춘다. */
.b-odds-cell { font-size: 13px; color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
.b-row.is-insufficient { color: var(--text-tertiary); }
.b-row--nrfi.is-insufficient, .b-row--nrfi.is-insufficient .b-team-name,
.b-row--nrfi.is-insufficient .b-team-sp, .b-row--nrfi.is-insufficient .b-pitcher .name,
.b-row--nrfi.is-insufficient .b-composite
{ color: var(--text-tertiary); }
/* 날짜 선택 — 가로 스트립(서버 렌더) + 캘린더 팝오버(JS, static/date-picker.js) */
.date-nav { margin: 8px 0 16px; }
/* [오늘] ‹ 연월 › [캘린더]가 한 묶음으로 가운데 모인다(참조 컴포넌트 배치). */
.date-nav__header { position: relative; display: flex; justify-content: center;
       align-items: center; gap: 8px; margin-bottom: 8px; }
.date-nav__month-group { display: flex; align-items: center; gap: 2px; }
.date-nav__month { font-size: 14px; font-weight: 700; color: var(--text);
       font-feature-settings: "tnum"; min-width: 62px; text-align: center; }
/* 인접 날짜 이동(‹ ›) — 링크지만 버튼처럼 보인다. 갈 곳이 없으면 is-disabled span. */
.date-nav__date-nav { display: inline-flex; align-items: center; justify-content: center;
       color: var(--text-tertiary); font-size: 16px; line-height: 1;
       width: 28px; height: 28px; border-radius: var(--r-xs); }
.date-nav__date-nav:hover { background: var(--neutral-weak); color: var(--text); }
.date-nav__date-nav.is-disabled { color: var(--text-quaternary); pointer-events: none; }
/* 팝오버 안 월 이동 버튼(진짜 달 이동) — 위 날짜 이동과 다른 컨트롤이다. */
.date-nav__month-nav { border: none; background: none; color: var(--text-tertiary);
       font-size: 16px; line-height: 1; width: 28px; height: 28px; border-radius: var(--r-xs);
       cursor: pointer; font-family: inherit; }
.date-nav__month-nav:hover { background: var(--neutral-weak); color: var(--text); }
.date-nav__today { font-size: 12px; font-weight: 600; padding: 5px 10px;
       border-radius: var(--r-full); border: 1px solid var(--border-strong);
       background: var(--surface); color: var(--text-secondary); cursor: pointer;
       font-family: inherit; }
.date-nav__today:hover { background: var(--neutral-weak); color: var(--text); }
/* 아이콘 버튼(캘린더 + 캐럿) — 텍스트가 없으므로 이름은 aria-label이 준다. */
.date-nav__toggle { justify-self: end; display: inline-flex; align-items: center; gap: 2px;
       padding: 5px 6px; border-radius: var(--r-xs); border: 1px solid transparent;
       background: none; color: var(--text-secondary); cursor: pointer; font-family: inherit; }
.date-nav__toggle:hover { background: var(--neutral-weak); color: var(--text); }
.date-nav__toggle-icon { width: 22px; height: 22px; }
.date-nav__toggle-caret { width: 14px; height: 14px; transition: transform 0.15s; }
.date-nav__toggle[aria-expanded="true"] { background: var(--brand-weak); color: var(--brand-strong);
       border-color: var(--brand-weak); }
.date-nav__toggle[aria-expanded="true"] .date-nav__toggle-caret { transform: rotate(180deg); }
/* `safe center`의 safe를 빼지 말 것 — 그냥 `center`면 칩이 컨테이너보다 넓어졌을 때
   넘친 부분이 왼쪽으로 밀려 스크롤로도 닿을 수 없게 된다(한 달치가 좁은 화면을 넘길 때
   실제로 발생). safe는 넘칠 때만 flex-start로 자동 폴백한다. 이 키워드를 모르는 구형
   브라우저는 선언 전체를 무시해 좌측 정렬이 되므로, 폴백도 안전하다. */
.date-nav__strip { display: flex; gap: 6px; overflow-x: auto; padding: 2px 2px 6px;
       justify-content: safe center;
       -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
.date-nav__chip { flex: none; display: flex; flex-direction: column; align-items: center;
       gap: 2px; min-width: 44px; padding: 6px 4px; border-radius: var(--r-s);
       color: var(--text-secondary); }
.date-nav__chip:hover { background: var(--neutral-weak); }
.date-nav__chip.is-current { background: var(--brand); color: #fff; }
.date-nav__weekday { font-size: 11px; opacity: 0.75; }
.date-nav__day { font-size: 15px; font-weight: 700; font-feature-settings: "tnum"; }
/* 캘린더 팝오버 — JS가 열고/그린다. 요소는 항상 마크업에 있고 hidden 속성으로만
   숨겨져 있으므로(disabled 버튼이 뒤섞인 그리드), JS가 아예 안 뜨면 hidden이 그대로
   남아 화면엔 나타나지 않는다(스트립만으로도 전체 기능이 동작). */
.date-nav__popover { position: absolute; top: 100%; right: 0; margin-top: 8px; z-index: 30;
       background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-m);
       padding: 12px; box-shadow: 0 8px 24px rgba(2, 32, 71, 0.14); width: 272px;
       max-width: calc(100vw - 32px); }
.date-nav__popover-head { display: flex; align-items: center; justify-content: space-between;
       margin-bottom: 8px; font-size: 13px; font-weight: 700; color: var(--text); }
.date-nav__popover-month { font-feature-settings: "tnum"; }
.date-nav__popover-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.date-nav__weekday-cell { text-align: center; font-size: 11px; color: var(--text-tertiary);
       padding: 4px 0; }
.date-nav__weekday-cell.is-sun { color: var(--danger); }
.date-nav__weekday-cell.is-sat { color: var(--brand); }
.date-nav__cal-day { display: flex; flex-direction: column; align-items: center; gap: 1px;
       padding: 6px 0; border: 1px solid transparent; border-radius: var(--r-xs);
       background: none; color: var(--text-primary); font-family: inherit; font-size: 13px;
       cursor: pointer; }
.date-nav__cal-day:disabled { color: var(--text-quaternary); cursor: default; }
.date-nav__cal-day:not(:disabled):hover { background: var(--neutral-weak); }
.date-nav__cal-day.is-today { border-color: var(--brand); }
.date-nav__cal-day.is-selected { background: var(--brand); color: #fff; }
.date-nav__cal-dot { font-size: 9px; color: var(--brand-strong); font-weight: 700;
       font-feature-settings: "tnum"; }
.date-nav__cal-day.is-selected .date-nav__cal-dot { color: rgba(255, 255, 255, 0.85); }

/* 모바일 */
@media (max-width: 720px) {
  .container { padding: 16px 16px 48px; }
  .site-header { flex-direction: column; align-items: flex-start; gap: 8px; }
  .nav a { margin-left: 0; margin-right: 4px; padding: 6px 8px; }
  /* 헤더 줄(월 이동 ‹›·오늘·캘린더 버튼)이 좁은 화면에서 넘치지 않게 줄바꿈을
     허용한다 — 스트립 자체는 이 줄과 무관하게 항상 overflow-x:auto라 이동
     기능은 이 줄이 두 줄이 되어도 그대로 유지된다. */
  /* 좁은 화면에서도 3분할을 유지한다 — 가운데 연월이 중심에 있어야 좌우 화살표가
     라벨 양옆에 붙어 보인다. 좌우 칸은 min 0으로 눌러 가운데를 우선 확보. */
  .date-nav__header { gap: 6px; }
  .date-nav__today { font-size: 11px; padding: 4px 8px; }
  .b-table-head { display: none; }
  .b-score { text-align: left; }
  /* ── index 모바일 카드 (컨셉 B) ──
     away/home은 이제 각자 자기 칸(.b-team-cell)이라 grid-area로 직접 배치하면
     된다(과거의 .b-match display:contents 트릭은 매치업 한 칸을 쪼개려고 쓴 것 —
     열이 이미 분리된 지금은 대상이 없다). 스코어는 두 팀 칸 사이 그대로 둔다. */
  /* 래퍼(.b-table-body)는 index/NRFI가 클래스를 공유한다(수식자 없음) — 카드형
     리셋을 index에만 적용하려면 상위 .b-table-wrap의 --nrfi 수식자로 좁혀야
     NRFI 래퍼의 배경·테두리·하단 라운딩이 유지된다. */
  .b-table-wrap:not(.b-table-wrap--nrfi) .b-table-body { background: none; border: none; border-radius: 0; }
  .b-row:not(.b-row--nrfi) {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-m); margin-bottom: 8px; padding: 16px;
    grid-template-columns: 1fr auto 1fr;
    grid-template-areas:
      "status status venue"
      "away   score  home"
      "model  model  model"
      "odds   odds   odds";
    gap: 12px 8px; align-items: center;
  }
  .b-row:not(.b-row--nrfi) > :nth-child(1)      { grid-area: status; justify-self: start; }
  .b-row:not(.b-row--nrfi) > .b-team-cell--away { grid-area: away; }
  .b-row:not(.b-row--nrfi) > .b-score           { grid-area: score; }
  .b-row:not(.b-row--nrfi) > .b-team-cell--home { grid-area: home; }
  .b-row:not(.b-row--nrfi) > .b-model           { grid-area: model; }
  /* 배당 열은 모바일에서 모델 아래 자기 행이 된다. area를 안 주면 자동 배치로
     흘러가 카드가 깨진다(명시적 areas를 쓰는 그리드의 함정).
     배당이 없는 슬레이트(수집 이전 아카이브)에서는 이 셀이 비어 카드 밑에 row-gap
     12px이 남는다. 없애려면 행에 수식자 클래스를 달고 areas를 3행으로 다시 써야
     하는데, 12px 때문에 열 구성이 조건부로 갈라지는 값은 아니라 두었다. */
  .b-row:not(.b-row--nrfi) > .b-odds-col        { grid-area: odds; }
  .b-row:not(.b-row--nrfi) > .b-meta            { grid-area: venue; justify-self: end; }
  .b-row:not(.b-row--nrfi) .b-team-cell {
    align-items: center; text-align: center; gap: 6px; }
  .b-row:not(.b-row--nrfi) .b-team {
    flex-direction: column; gap: 6px; }
  .b-row:not(.b-row--nrfi) .b-team .team-logo {
    width: 44px; height: 44px; margin-right: 0; }
  .b-row:not(.b-row--nrfi) .b-team-name { font-size: 13px; }
  /* 모바일은 폭이 좁아 이름이 자주 두 줄로 접힌다 — 얼굴을 20px로 줄여 선발 줄이
     팀 블록보다 커 보이지 않게 한다. 가운데 정렬은 팀 블록이 세로로 쌓이는 오늘 표에만
     건다 — NRFI 행은 1열 스택이라 왼쪽 정렬을 유지해야 한다. */
  .b-sp-face { width: 20px; height: 20px; }
  .b-row:not(.b-row--nrfi) .b-sp { justify-content: center; }
  .b-row:not(.b-row--nrfi) .b-sp-body { align-items: center; }
  /* 모델 줄은 팀/스코어 행 아래 구분선 위 서브 정보(과거엔 선발 행이 이 구분선을 졌다) */
  .b-row:not(.b-row--nrfi) > .b-model {
    padding-top: 12px; border-top: 1px solid var(--border); }
  /* 배당 행에는 같은 구분선을 주지 않는다. 그 선의 일은 "경기 사실(팀·스코어)"과
     "숫자 층"을 가르는 것인데 모델과 배당은 둘 다 숫자 층이다 — 선을 하나 더 그으면
     카드가 세 토막이 나고 배당이 남의 경기 정보처럼 떨어져 보인다. 둘의 구분은
     이미 색이 진다(.b-model secondary vs .b-odds tertiary) + row-gap 12px. */
  .b-row:not(.b-row--nrfi) .b-score { text-align: center; font-size: 24px; }
  .b-row:not(.b-row--nrfi) .b-score.upcoming { font-size: 16px; color: var(--brand-strong); }
  .b-row:not(.b-row--nrfi) .b-commentary { grid-column: 1 / -1; }
  /* NRFI 행은 기존 1열 스택 유지 */
  .b-row--nrfi { grid-template-columns: 1fr; gap: 6px; }
  /* I-5(final-review): 데스크톱은 .b-table-head가 away/home을 알려주지만 모바일은
     헤더 자체가 display:none(위 규칙)이라 두 팀 블록만 봐서는 어느 쪽이 원정인지
     알 수 없었다. 배지형 라벨로 표시하되, 바로 아래 .b-pitcher 안의 일반 텍스트
     "Away/Home" 라벨(.b-pitcher .label, 무배경)과는 다른 모양(배경 칩)을 줘서
     두 라벨이 붙어 있어도 서로 구분되게 한다. */
  .b-row--nrfi .b-team-cell-label { display: inline-block; font-size: 10px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-tertiary);
    background: var(--neutral-weak); border-radius: var(--r-xs); padding: 1px 6px; }
  /* Pre-existing(같이 처리): 예전엔 이 자리가 ::before 의사요소로 한국어 접두어
     문자열을 CSS에 직접 박아 en/ja 페이지에도 그대로 노출됐다. 지금은 각 헤더
     라벨과 같은 t() 문자열을 템플릿에서 span으로 내보내고, 여기서는 시각
     스타일만 준다. */
  .b-row--nrfi .b-row-label { display: inline; color: var(--text-tertiary); font-size: 12px;
    font-weight: 400; margin-right: 4px; }
  /* 얼굴 두 개는 가로로 유지한다(세로로 쌓으면 두 선발이 한 화면에 안 보인다).
     대신 얼굴을 88px→56px로 줄이고 시각·모델%만 아래 행으로 내린다. */
  .a-detail-hero { padding: 20px 16px; }
  .a-detail-hero-inner { gap: 14px 8px;
    grid-template-areas: "away status home"
                         "meta meta   meta"; }
  .a-detail-status-col { align-self: center; }
  .a-detail-meta-col { align-self: center; min-width: 0; width: 100%;
    padding-top: 12px; border-top: 1px solid rgba(255, 255, 255, 0.1); }
  .a-detail-face { width: 56px; height: 56px; }
  .a-detail-face-badge { width: 22px; height: 22px; }
  .a-detail-sp-name { font-size: 13px; }
  .a-detail-team-meta { font-size: 11px; }
  .a-detail-time { font-size: 26px; }
  .a-detail-score-value { font-size: 40px; }
  .a-game-info { grid-template-columns: 1fr 1fr; }
  /* ── game 상세 모바일: 카드를 화면 끝까지 펼치고 8px 밴드로 섹션을 끊는다
     (컨셉 A의 gray-band). container의 좌우 16px 패딩을 음수 마진으로 상쇄. */
  .a-detail-hero { margin: -16px -16px 8px; border-radius: 0; }
  .a-card, .a-game-info, .scout__lineup, .scout__form, .scout__h2h {
    margin-left: -16px; margin-right: -16px; margin-bottom: 8px;
    border-radius: 0; padding-left: 16px; padding-right: 16px; }
  .a-section-title { font-size: 15px; color: var(--text-secondary); }
  /* 선발 2명은 모바일에서도 2열 — 세로로 쌓으면 두 선발 비교가 안 된다
     (히어로 얼굴 2열 유지와 같은 근거). Task 이전의 1열 규칙을 되돌린다. */
  .scout__pitchers { grid-template-columns: 1fr 1fr; gap: 8px;
    margin-left: -16px; margin-right: -16px; }
  .scout__pitcher { border-radius: 0; font-size: 13px; }
  .a-scoreboard-table th, .a-scoreboard-table td { padding: 10px 4px; font-size: 14px; }
  .tabbar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
    background: var(--surface); border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .tabbar__item { flex: 1; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 3px; padding: 8px 4px 10px;
    font-size: 11px; font-weight: 600; color: var(--text-tertiary); }
  .tabbar__item.is-current { color: var(--text); }
  .tabbar__icon { width: 24px; height: 24px; }
  /* 탭바가 마지막 콘텐츠를 가리지 않게 컨테이너 하단 여백을 준다.
     라벨이 브라우저 최소 글꼴 확대 등으로 2줄이 되면 탭바가 72px→81px로 커질 수 있어
     88px로 방어(nowrap은 넘침, 말줄임은 정보 손실이라 채택하지 않음). */
  .container { padding-bottom: calc(88px + env(safe-area-inset-bottom, 0px)); }
  /* 상단 네비의 섹션 링크는 탭바와 중복 — 언어 전환만 남긴다 */
  .nav > a { display: none; }
  .nav-lang { margin-left: 0; }
}
