/* 공용 컴포넌트.
 *
 * ⚠️ 색·간격·서체를 여기 직접 쓰지 않는다. **`tokens.css` 의 변수만 참조한다.**
 *    그래야 Figma 시안이 확정될 때 토큰 값 교체만으로 전 화면이 바뀐다.
 *
 * 모바일 퍼스트다. 기본 규칙은 375px 기준으로 쓰고, 넓은 화면은 맨 아래
 * `@media (min-width: 720px)` / `(min-width: 1024px)` 에서 확장한다.
 * 이후 Capacitor 로 앱을 감쌀 때 이 순서가 그대로 쓰인다.
 */

/* ══ 기본 ══════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  overflow-wrap: break-word;
  /* 한글은 어절 단위로 끊는다. 없으면 '제안합니 / 다' 처럼 단어 중간에서
     갈라져 읽기가 크게 느려진다(주 이용층이 40~60대다). */
  word-break: keep-all;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: var(--lh-tight);
  margin: 0 0 var(--sp-3);
}
h1 { font-size: var(--fs-h1); font-weight: 700; }
h2 { font-size: var(--fs-h2); font-weight: 700; }
h3 { font-size: var(--fs-h3); font-weight: 700; }
p { margin: 0 0 var(--sp-3); }

/* 링크도 **기능**이다 — 버튼과 같은 청록을 쓴다. 골드는 서비스 단계
   (브랜드·섹션 제목·활성 내비/탭)와 돈 숫자에만 남긴다. */
a { color: var(--action-fn); text-decoration: none; }
a:hover { text-decoration: underline; }

button, input, select { font: inherit; color: inherit; }

:focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--radius-sm);
}

/* 숫자는 어디서든 고정폭이다 — 자릿수가 흔들리면 표·매트릭스가 어긋나 보인다. */
.num, .mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* ══ 레이아웃 ══════════════════════════════════════════════════ */
.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: var(--sp-4) var(--sp-4) var(--sp-6);
}

/* 상단바 — 모바일에선 브랜드+상태만, 넓은 화면에서 메뉴가 나온다 */
.appbar {
  position: sticky; top: 0; z-index: var(--z-header);
  display: flex; align-items: center; gap: var(--sp-3);
  height: var(--header-h);
  padding: 0 var(--sp-4);
  /* 본문보다 밝은 틀 색 + 아래로 떨어지는 그림자 — 본문이 이 바 **밑으로**
     지나간다는 것이 눈에 보여야 한다(색 차이만으로는 약하다). */
  background: color-mix(in srgb, var(--chrome) 94%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line-strong);
  box-shadow: 0 2px 8px rgb(0 0 0 / 30%);
}
/* 로고는 '오늘은 馬요일' 한 덩어리다 — 마크가 이름 **안**의 글자라
   flex gap 을 쓰면 '오늘은 · 馬 · 요일' 로 벌어진다. 간격은 마크가 직접 갖는다. */
.brand {
  display: flex; align-items: center; gap: 0;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h3);
  color: var(--text); flex: 1; min-width: 0;
}
.brand:hover { text-decoration: none; }
.brand-mark {
  width: 26px; height: 26px; flex: none;
  margin: 0 2px 0 var(--sp-2);
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  background: var(--gold); color: var(--text-on-gold);
  font-family: var(--font-latin); font-weight: 700; font-size: var(--fs-sm);
}
.appbar-nav { display: none; }             /* 모바일은 하단 탭이 대신한다 */
.appbar-nav a {
  color: var(--text-muted); padding: var(--sp-2) var(--sp-2);
  border-radius: var(--radius-sm); font-size: var(--fs-sm);
  white-space: nowrap;
}
.appbar-nav a:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
.appbar-nav a.is-active { color: var(--gold); }

/* 우측 회원 상태 */
.appbar-me {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); color: var(--text-muted); white-space: nowrap;
  flex: none;
}
.avatar {
  width: 28px; height: 28px; border-radius: var(--radius-pill);
  display: grid; place-items: center; flex: none;
  background: var(--surface-3); color: var(--text);
  font-size: var(--fs-sm); font-weight: 700;
}

/* 하단 탭 — 모바일 전용 */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-nav);
  display: flex;
  height: calc(var(--nav-h) + var(--safe-b));
  padding-bottom: var(--safe-b);
  /* 상단바와 같은 틀 색. 위로 떨어지는 그림자로 본문이 탭 아래로 흐르는 것을
     드러낸다 — 마지막 줄이 탭에 가려지는지 아닌지가 그제야 읽힌다. */
  background: var(--chrome);
  border-top: 1px solid var(--line-strong);
  box-shadow: 0 -2px 8px rgb(0 0 0 / 30%);
}
.tabbar a {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
  color: var(--text-dim); font-size: var(--fs-xs); text-decoration: none;
}
.tabbar a.is-active { color: var(--gold); }
.tabbar-ico { font-size: 1.1rem; line-height: 1; }
/* 아직 열리지 않은 탭 — 눌리기는 하되 준비중임을 배지로 알린다 */
.tabbar a.is-soon { position: relative; }
.tabbar .soon-dot {
  position: absolute; top: 4px; left: 50%; transform: translateX(2px);
  padding: 0 4px; border-radius: var(--radius-pill);
  background: var(--gold); color: var(--text-on-gold);
  font-size: 9px; font-weight: 700; line-height: 14px;
}

/* 하단 탭·개발툴바에 가리지 않도록 본문 아래 여백 */
body { padding-bottom: calc(var(--nav-h) + var(--safe-b)); }
.has-devbar { padding-bottom: calc(var(--nav-h) + var(--safe-b) + var(--dev-h)); }

.footer {
  border-top: 1px solid var(--line);
  padding: var(--sp-4);
  color: var(--text-dim);
  font-size: var(--fs-sm);
  text-align: center;
}
.footer .age {

  display: inline-block; margin-right: var(--sp-2);

  padding: 1px 7px; border-radius: var(--radius-pill);

  background: var(--danger); color: var(--text-on-color);

  font-size: var(--fs-xs); font-weight: 700;

}



/* 법정 표시 — 전자상거래법·정보통신망법·게임산업법이 요구하는 항목.
   작은 글씨지만 **읽을 수 있어야** 한다. 숨기거나 접지 않는다. */
.footer-links {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--sp-2) var(--sp-4);
  margin: var(--sp-4) 0 var(--sp-3);
}
.footer-links a { color: var(--text-dim); text-decoration: none; }
.footer-links a:hover { color: var(--text); text-decoration: underline; }
/* 개인정보처리방침은 굵게 — 다른 안내와 구분되게 표시하도록 정해져 있다. */
.footer-links b { font-weight: 700; }

.footer-biz {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 2px var(--sp-3);
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-xs); line-height: 1.7;
}
.footer-biz > div { display: flex; gap: 4px; white-space: nowrap; }
.footer-biz dt { opacity: .7; }
.footer-biz dt::after { content: ''; }
.footer-biz dd { margin: 0; }
.footer-biz a { color: inherit; }

/* ══ 약관·방침 원문 ═════════════════════════════════════════════ */
.legal { line-height: 1.85; }
.legal h2 { margin: var(--sp-5) 0 var(--sp-2); font-size: var(--fs-lg); }
.legal h3 { margin: var(--sp-4) 0 var(--sp-2); font-size: var(--fs-md); }
.legal h2:first-child, .legal h3:first-child { margin-top: 0; }
.legal p { margin: 0 0 var(--sp-3); }
.legal ul { margin: 0 0 var(--sp-3); padding-left: 1.2em; }
.legal li { margin-bottom: 4px; }
.legal hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-5) 0; }
/* 표는 좁은 화면에서 **가로로만** 넘긴다. 페이지 전체가 흔들리면 안 된다. */
.legal-table { overflow-x: auto; margin: 0 0 var(--sp-3); }
.legal-table table { border-collapse: collapse; width: 100%; }
.legal-table th, .legal-table td {
  border: 1px solid var(--line); padding: var(--sp-2); text-align: left;
  font-size: var(--fs-sm); white-space: nowrap;
}
.legal-table th { background: var(--surface-2, var(--surface)); }

/* ══ 카드 · 섹션 ═══════════════════════════════════════════════ */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-4);
  margin-bottom: var(--sp-4);
}
.card-tight { padding: var(--sp-3); }

/* 큰 카테고리 머리말. 색을 통일해 '여기서 새 구획이 시작된다'가 먼저 보이게 한다. */
.sec-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3); margin: var(--sp-6) 0 var(--sp-3);
}
.sec-head:first-child { margin-top: var(--sp-2); }
.sec-head h2, .sec-head h3 { margin: 0; }
.sec-head h2 { color: var(--gold); }
.sec-head .more { font-size: var(--fs-sm); color: var(--text-muted); }

/* ══ 버튼 ══════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: 11px var(--sp-4); min-height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:hover { background: var(--surface-3); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: .4; cursor: not-allowed; transform: none;
  pointer-events: none;                 /* `a` 로 만든 버튼도 눌리지 않게 */
}
/* 버튼에는 **골드를 쓰지 않는다.** 골드는 서비스 단계(브랜드·섹션 제목·활성
   내비)만 갖는다. 버튼까지 골드면 화면 전체가 노란 한 덩어리로 읽힌다.
     primary/outline = 기능(fn, 복승 블루) — 예상하기·배당보기·경주목록·조회…
     buy             = 구매(적색)          — **잔액이 줄어드는 버튼 하나뿐** */
.btn-primary {
  background: var(--action-fn); border-color: var(--action-fn);
  color: var(--action-fn-text); font-weight: 700;
}
.btn-primary:hover { background: var(--action-fn-dim); border-color: var(--action-fn-dim); }
/* 채움(primary) 과 중립(ghost) 사이 — 같은 줄의 버튼들이 한 묶음으로 보이게 한다 */
.btn-outline {
  background: transparent; border-color: var(--action-fn);
  color: var(--action-fn); font-weight: 700;
}
.btn-outline:hover { background: var(--action-fn-tint); }
/* 구매하기 — 유일하게 잔액이 줄어드는 버튼이라 혼자만 다른 색을 갖는다. */
.btn-buy {
  background: var(--action-buy); border-color: var(--action-buy);
  color: var(--action-buy-text); font-weight: 700;
}
.btn-buy:hover { background: var(--action-buy-dim); border-color: var(--action-buy-dim); }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--text-muted); }
.btn-ghost:hover { color: var(--text); background: var(--surface-2); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: var(--text-on-color); }
.btn-sm { min-height: 34px; padding: 6px var(--sp-3); font-size: var(--fs-sm); }
/* 아이콘 하나짜리 버튼. 손가락이 닿는 크기(36px)는 유지한다. */
.btn-icon {
  width: 36px; height: 36px; min-height: 36px; padding: 0;
  font-size: var(--fs-h3); line-height: 1;
}
.btn-icon.is-busy { opacity: .5; pointer-events: none; }
.btn-icon.is-busy .ico { display: inline-block; animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.btn-lg { min-height: 52px; font-size: var(--fs-h3); }
.btn-block { display: flex; width: 100%; }

.actions { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.actions .btn { flex: 1; }

/* 카카오 로그인 — 공식 색을 쓴다(브랜드 규격) */
.btn-kakao {
  background: var(--kakao); border-color: var(--kakao);
  color: var(--text-on-kakao); font-weight: 700;
}
.btn-kakao:hover { background: var(--kakao-hover); border-color: var(--kakao-hover); }

/* ══ 배지 · 칩 ═════════════════════════════════════════════════ */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px var(--sp-2); border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 700; white-space: nowrap;
  border: 1px solid transparent;
}
/* 경주 상태 — 오픈만 강하게. 지금 예상할 수 있는 유일한 상태다. */
.st-대기   { background: transparent; border-color: var(--line-strong); color: var(--text-muted); border-style: dashed; }
.st-오픈   { background: var(--gold); color: var(--text-on-gold); }
.st-마감   { background: var(--surface-3); color: var(--text-muted); }
/* 확정중 = 도착순위는 나왔고 확정 전. 확정으로 가는 중이라 같은 초록 계열이되
   아직 끝나지 않았음을 테두리만으로 표시한다. */
.st-확정중 {
  background: var(--track-green-tint); border-color: var(--track-green);
  color: var(--track-green-text);
}
.st-확정   { background: var(--track-green); color: var(--text-on-color); }
.st-종료   { background: transparent; border-color: var(--line); color: var(--text-dim); }
.st-노게임 { background: var(--warn-tint); border-color: var(--warn); color: var(--warn); }
/* 예상 결과 상태(예상내역)
   ⚠️ '정산대기' 는 경주 상태 '대기'(아직 열리지 않은 경주)와 **다른 뜻**이다.
   같은 화면에서 두 배지가 같이 보이므로 글자도 색도 겹치지 않게 둔다. */
.st-정산대기 { background: var(--surface-3); border-color: var(--line-strong); color: var(--text-dim); }
.st-적중   { background: var(--win-tint); border-color: var(--win); color: var(--win); }
.st-미적중 { background: var(--surface-3); color: var(--text-muted); }
.st-환불   { background: var(--warn-tint); border-color: var(--warn); color: var(--warn); }

.chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px var(--sp-2); border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--text-muted); white-space: nowrap;
}
.chip-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* 경주번호 배지. `a` 로도 쓰인다(오늘의경주 목록에서 상세로 가는 입구) */
.rno {
  display: grid; place-items: center; flex: none;
  width: 44px; height: 44px; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--line-strong);
  font-family: var(--font-mono); font-size: var(--fs-mono-l); font-weight: 700;
  color: var(--text); text-decoration: none;
}
a.rno:hover { background: var(--surface-3); text-decoration: none; }
.rno-open { background: var(--gold-tint); border-color: var(--gold); color: var(--gold); }
/* 좁은 줄(결과판 머리·예상내역 카드)에 쓰는 작은 판. 화면마다 인라인 style 로
   줄여 쓰던 것을 한 이름으로 모았다 — 경주번호는 어디서나 같은 부품이다. */
.rno-sm {
  width: 38px; height: 30px; border-radius: var(--radius-sm);
  font-size: var(--fs-mono);
}

/* ── 마번 배지 — KRA 번호포 ──────────────────────────────────
   말 등에 다는 실제 번호천(번호포) 색을 그대로 쓴다. 경마장에서 눈으로 익힌
   약속이라 **테마가 바뀌어도 이 색은 바뀌지 않는다** — 그래서 토큰이 아니라
   여기에 실제 색값을 박아 둔다.
   글자는 바탕 밝기에 따라 검정 아니면 흰색 하나만 쓴다(대비 4.5:1 이상).

   ⚠️ 1~10번(백·흑·적·청·황·녹·등·분홍·하늘·보라)은 표준이다.
      11~16번은 드물게 쓰여 표기가 통일돼 있지 않다 — 서로 구분되는 색으로
      채워 뒀으니, 실제와 다르면 **여기 여섯 줄만** 고치면 된다. */
/* ⚠️ **동그라미가 아니라 셀이다**(2026-09-07 지시). 색깔 동그라미가 로또 공을
   연상시켜 사행성 인상을 준다 — 색은 그대로 두고 모양만 표의 칸으로 바꿨다.
   두 자리 마번에서도 폭이 흔들리지 않게 `min-width` + 좌우 여백으로 잡는다. */
.gate {
  display: inline-grid; place-items: center; flex: none;
  min-width: 26px; height: 24px; padding: 0 5px; border-radius: 4px;
  background: var(--gate-bg, var(--surface-3));
  color: var(--gate-fg, var(--text));
  font-family: var(--font-mono); font-size: var(--fs-mono-s); font-weight: 700;
  /* 흰색·연한 번호포가 어두운 바탕에 묻히지 않게 얇은 테두리를 둔다. */
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 22%);
}
.gate-lg { min-width: 32px; height: 28px; font-size: var(--fs-mono); }
/* 판(단승 표·복승 매트릭스)의 칸은 좁다 — 칸을 넓히지 않고 배지를 줄인다. */
.gate-sm { min-width: 22px; height: 20px; padding: 0 3px; font-size: var(--fs-mono-s); }

/* 지급율 판(`odds.html`)의 마번 — **번호포 색을 쓰지 않는다**(2026-09-07 지시).
   숫자가 빽빽한 표에 16색이 들어가면 값(지급율)을 읽는 눈을 색이 계속 끊는다.
   판에서는 마번을 전광판 색 하나로 통일하고, 색으로 말을 짚는 일은 마필정보·
   예상하기 화면이 맡는다. 바탕을 비우는 것이 요점이라 `--gate-bg` 도 지운다. */
.gate.is-plain {
  --gate-bg: transparent;
  --gate-fg: var(--num-yellow);
  box-shadow: none;
}
/* ── KRA 마번 색상표 ────────────────────────────────────────────
   **진실원본 = `docs/72_마번색상표_KRA.md`.** 여기는 옮겨 적은 것이고,
   어긋나면 그 문서가 맞다. 1~10 은 단색, **11~14 는 하늘 바탕 + 줄 색**이다.
   15 번 이상은 규격에 없어 클래스를 두지 않는다(기본 회색으로 떨어진다). */
.g1  { --gate-bg: #ffffff; --gate-fg: #111111; }   /* 하양 */
.g2  { --gate-bg: #f7d417; --gate-fg: #111111; }   /* 노랑 */
.g3  { --gate-bg: #d92b2b; --gate-fg: #ffffff; }   /* 빨강 */
.g4  { --gate-bg: #1a1a1a; --gate-fg: #ffffff; }   /* 검정 */
.g5  { --gate-bg: #1a5fbf; --gate-fg: #ffffff; }   /* 파랑 */
.g6  { --gate-bg: #1a7a44; --gate-fg: #ffffff; }   /* 초록 */
.g7  { --gate-bg: #7a4a24; --gate-fg: #ffffff; }   /* 고동 */
.g8  { --gate-bg: #f7a8c0; --gate-fg: #111111; }   /* 분홍 */
.g9  { --gate-bg: #7a4bb0; --gate-fg: #ffffff; }   /* 보라 */
.g10 { --gate-bg: #6fc9e8; --gate-fg: #111111; }   /* 하늘 */
/* 11~14 — 하늘 바탕에 줄 색만 바뀐다(KRA 규격). */
.g11 { --gate-bg: #6fc9e8; --gate-fg: #111111; --gate-stripe: #ffffff; }
.g12 { --gate-bg: #6fc9e8; --gate-fg: #111111; --gate-stripe: #f7d417; }
.g13 { --gate-bg: #6fc9e8; --gate-fg: #111111; --gate-stripe: #d92b2b; }
.g14 { --gate-bg: #6fc9e8; --gate-fg: #111111; --gate-stripe: #1a1a1a; }
/* 줄무늬는 **배지 아래 띠**로 그린다. 실물 모자는 대각 줄무늬지만 26px 배지에
   대각선을 깔면 줄이 숫자를 가린다 — 특히 14번(검은 줄)은 검정 글자와 겹쳐
   안 읽힌다. 구분이 목적이니 숫자를 건드리지 않는 자리에 색을 둔다.
   ⚠️ 기본 테두리(`.gate` 의 inset box-shadow)를 여기서 다시 적어야 한다 —
      box-shadow 는 덮어쓰기라 하나만 쓰면 테두리가 사라진다. */
.g11, .g12, .g13, .g14 {
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 22%),
              inset 0 -5px 0 0 var(--gate-stripe);
}

/* 승식 배지 — 색 + 글자 2중 구분(색각 이상 대응) */
.pool {
  display: inline-block; padding: 2px 7px; border-radius: var(--radius-sm);
  font-weight: 700; font-size: var(--fs-sm); white-space: nowrap;
}
.pool-win { background: var(--pool-win-tint); color: var(--pool-win); }
.pool-qnl-badge { background: var(--pool-qnl-tint); color: var(--pool-qnl); }
/* 쌍승·삼복승이 붙을 자리. 색은 `tokens.css` 에서 이미 같은 청색 계열로 잡아 뒀다 —
   승식이 늘어날 때 색을 새로 고르지 말고 여기에 이름만 연결한다(ui.js 의 `승식색표`). */
.pool-3 { background: rgb(106 125 232 / 14%); color: var(--pool-3); }
.pool-4 { background: rgb(143 116 224 / 14%); color: var(--pool-4); }
.c-win { color: var(--pool-win); }
.c-qnl { color: var(--pool-qnl); }
/* 잔액 부족·초과처럼 **경고**를 말하는 글자. 승식 색(청색)과 절대 겹치면 안 된다. */
.c-danger { color: var(--danger); }

/* ══ 통계 · 게이지 · 스텝퍼 ════════════════════════════════════ */
.stat-hero {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
}
.stat-hero .k { font-size: var(--fs-sm); color: var(--text-muted); display: block; }
.stat-hero .v {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-xl); font-weight: 700; color: var(--gold);
  line-height: 1.1;
}
.stat-row {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--text-muted);
}
.stat-row > div { display: flex; gap: 6px; align-items: baseline; }
.stat-row b { font-family: var(--font-mono); color: var(--text); font-weight: 600; }

/* 오늘의경주 상단 요약 — 왼쪽 잔여포인트 / 오른쪽 경주수 3개.
   상단이 길면 정작 경주목록이 밀려서 한 줄에 둘씩 붙였다. */
.sum-top { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3); }
.sum-cell { min-width: 0; }
.sum-cell.is-right { text-align: right; }
.sum-cell .k {
  display: block; font-size: var(--fs-sm); color: var(--text-muted);
  line-height: 1.3;                    /* 라벨이 길면 두 줄로 접힌다 */
}
.sum-cell .v {
  display: block;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-xl); font-weight: 700; color: var(--gold);
  line-height: 1.15; white-space: nowrap;
}
.sum-cell.is-right .v { color: var(--text); }
.sum-cell .sep { color: var(--text-dim); margin: 0 4px; font-weight: 400; }

/* 마포인트 전환 · 지급/예상/환급 — 각각 한 줄 */
.sum-line {
  /* 지급·예상·환급 세 쌍이 한 줄에 들어가야 한다 — 간격을 좁게 잡는다 */
  display: flex; flex-wrap: wrap; gap: 4px var(--sp-3); align-items: baseline;
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--text-muted);
}
.sum-line b {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text); font-weight: 700; font-size: var(--fs-mono-s);
}
.sum-line span + b { margin-left: 4px; }

.gauge { height: 6px; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; }
.gauge > i { display: block; height: 100%; background: var(--gold); border-radius: inherit; }
.gauge.is-done > i { background: var(--win); }

/* 진행 스텝퍼 — 1R..nR */
.stepper { display: flex; gap: 6px; overflow-x: auto; padding: 2px 0; }
.step {
  flex: none; min-width: 34px; height: 30px; padding: 0 6px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--surface-2); color: var(--text-dim);
  font-family: var(--font-mono); font-size: var(--fs-mono-s); text-decoration: none;
}
.step:hover { text-decoration: none; border-color: var(--line-strong); }
/* 아래 카드와 **같은 색 규칙**을 쓴다(today.html 의 `카드색`).
   빨강=지금 급한 경주 · 노랑=오픈 · 초록=예정 · 회색=지난 경주 */
.step.is-done { color: var(--text-muted); border-color: var(--line-strong); }
.step.is-hot  { background: var(--danger-tint); border-color: var(--danger);
                color: var(--danger); font-weight: 700; }
.step.is-open { background: var(--gold-tint); border-color: var(--gold);
                color: var(--gold); font-weight: 700; }
.step.is-wait { background: var(--track-green-tint); border-color: var(--track-green);
                color: var(--track-green-text); }
.step.is-bet::after {
  content: ''; position: absolute; margin: 22px 0 0 0;
  width: 4px; height: 4px; border-radius: 50%; background: var(--win);
}
.step { position: relative; }

/* ══ 표 ════════════════════════════════════════════════════════ */
.table { width: 100%; border-collapse: collapse; }
.table th, .table td {
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--line);
  text-align: left;
}
.table th {
  color: var(--text-muted); font-weight: 600; font-size: var(--fs-sm);
  white-space: nowrap;
}
/* 숫자 칸은 줄바꿈하지 않는다 — '3 - 4' 가 세 줄로 쪼개지면 조합이 안 읽힌다 */
.table td.num, .table th.num { text-align: right; white-space: nowrap; }
.table tbody tr:last-child td { border-bottom: none; }

/* 가로 스크롤은 이 컨테이너 안에서만 — 본문은 절대 가로로 밀리지 않는다 */
.scroll-x { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }

/* 열이 많아 좁은 화면에 안 들어가는 표(착순·성적표).
   `width:100%` 만 두면 표가 줄어들면서 '마 / 명' 처럼 글자 단위로 쪼개진다.
   최소 폭을 줘서 `.scroll-x` 가 실제로 가로 스크롤되게 한다. */
.table-wide { min-width: 560px; }
.table-wide th, .table-wide td { white-space: nowrap; }

/* ══ 오늘의경주 — 경주 카드 리스트 ═════════════════════════════ */
.summary-bar {
  position: sticky; top: var(--header-h); z-index: var(--z-sticky);
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
}

.race-list { display: grid; gap: var(--sp-3); }

.race-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-3);
  align-items: start;
  padding: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
/* 카드 색 (개발메모 UX디자인.txt)
     is-hot  적색 — 마감이 가장 임박한 경주 한 장
     is-open 노랑 — 참여 가능(오픈). 동시에 2장이 열릴 수 있어 과하지 않게.
     is-wait 초록 — 아직 오픈 전 */
.race-card.is-hot {
  border-color: var(--danger);
  background: linear-gradient(180deg, var(--danger-tint), transparent 60%), var(--surface);
}
.race-card.is-open {
  border-color: var(--gold);
  background: linear-gradient(180deg, var(--gold-tint-2), transparent 60%), var(--surface);
}
.race-card.is-wait {
  border-color: var(--track-green);
  background: linear-gradient(180deg, var(--track-green-tint-2), transparent 60%), var(--surface);
}
/* 경주번호 배지도 카드 색을 따라간다 (.rno-open 은 배지 절에 이미 있다) */
.rno-hot  { background: var(--danger-tint); border-color: var(--danger); color: var(--danger); }

/* 홈의 '오늘의경주' 2장.
   주 이용층이 40~60대다. 한 카드에 여러 정보를 가로로 욱여넣으면 산만해서
   읽히지 않는다 — **세로로 풀고, 항목마다 이름표를 달고, 크게** 간다. */
.now-list { display: grid; gap: var(--sp-4); }

.now-card {
  padding: var(--sp-4);
  background: var(--surface);
  border: 2px solid var(--line-strong);      /* 둘째 카드도 테두리가 있어야 경계가 읽힌다 */
  border-radius: var(--radius);
}
.now-card.is-hot {
  border-color: var(--danger);
  background: linear-gradient(180deg, var(--danger-tint), transparent 55%), var(--surface);
}
.now-card.is-next { border-color: var(--track-green); }

.nc-head { display: flex; align-items: center; gap: var(--sp-3); }
.nc-no {
  font-family: var(--font-board); font-weight: var(--fw-board);
  font-size: var(--fs-display); line-height: 1; color: var(--text);
}
.is-hot .nc-no { color: var(--danger); }
.is-next .nc-no { color: var(--track-green-text); }

.nc-title {
  margin-top: var(--sp-2);
  font-family: var(--font-display); font-size: var(--fs-h1); font-weight: 700;
}

/* 항목마다 이름표를 단다 — 숫자만 나열하면 무슨 값인지 되묻게 된다 */
.nc-info {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5);
  margin: var(--sp-3) 0 0;
}
.nc-info > div { display: flex; align-items: baseline; gap: var(--sp-2); }
.nc-info dt { color: var(--text-muted); font-size: var(--fs-sm); margin: 0; }
.nc-info dd {
  margin: 0; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-l); font-weight: 700;
}

.nc-mine {
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  font-size: var(--fs-body);
}
.nc-mine b { font-family: var(--font-mono); }

.nc-btns { display: flex; gap: var(--sp-2); margin-top: var(--sp-4); }
.nc-btns .btn { flex: 1; }

/* AI 동영상 예상 — 광고 배너 */
.promo-card {
  display: grid; grid-template-columns: auto 1fr auto; gap: var(--sp-4);
  align-items: center; color: var(--text);
  background: linear-gradient(135deg, var(--gold-tint-2), transparent 60%), var(--surface);
  border-color: var(--gold-deep);
}
.promo-card:hover { text-decoration: none; border-color: var(--gold); }
.promo-card .ico { font-size: 2.2rem; }
.promo-card .t {
  display: block; font-family: var(--font-display);
  font-size: var(--fs-h2); font-weight: 700; line-height: var(--lh-tight);
}
.promo-card .d { display: block; margin-top: 4px; font-size: var(--fs-sm); color: var(--text-muted); }
.promo-card .go { color: var(--gold); font-size: var(--fs-h1); }
.rno-wait {
  background: var(--track-green-tint); border-color: var(--track-green);
  color: var(--track-green-text);
}
.rc-main { min-width: 0; }
.rc-top {
  display: flex; align-items: center; gap: var(--sp-2);
  flex-wrap: wrap; margin-bottom: 2px;
}
.rc-title { font-weight: 700; }
.rc-meta { font-size: var(--fs-sm); color: var(--text-muted); }
.rc-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-2); margin-top: var(--sp-3);
  flex-wrap: wrap;                  /* 좁으면 버튼이 아랫줄로 내려간다 */
}
.rc-mine { font-size: var(--fs-sm); color: var(--text-muted); min-width: 0; }
/* 버튼 글자는 절대 쪼개지 않는다 — '예상하 기' 처럼 보였다 */
.rc-actions .btn { white-space: nowrap; }
.rc-mine b { font-family: var(--font-mono); color: var(--text); }
.rc-actions { display: flex; gap: var(--sp-2); }

/* 남은 시간 — **마감 시각은 항상 적색이다.**
   전에는 5분 전부터 노랑(warn)이었는데, 화면의 다른 노랑(골드·오픈배지)과
   섞여서 "서두르라"는 신호로 읽히지 않았다. 마감은 처음부터 끝까지 붉은색으로
   두고, 남은 시간에 따라 **굵기와 점멸**로만 단계를 올린다. */
.tleft {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--danger);
}
.tleft.is-soon { color: var(--danger); font-weight: 700; }
.tleft.is-urgent, .is-urgent {
  color: var(--danger); font-weight: 700;
  font-variant-numeric: tabular-nums;
  animation: 초점멸 1s steps(2) infinite;
}
@keyframes 초점멸 { 50% { opacity: .5; } }
@media (prefers-reduced-motion: reduce) { .is-urgent { animation: none; } }

/* 경주상세 상단의 잔여포인트 한 줄 — 버튼을 누를지 말지가 이 숫자로 정해진다 */
.race-bal {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3); margin-top: var(--sp-4);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.race-bal .k { font-size: var(--fs-sm); color: var(--text-muted); }
.race-bal .v {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-l);
}

/* ══ 경주 상세 — 헤더 · 탭 ════════════════════════════════════ */
.race-head {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--sp-4); margin-bottom: var(--sp-3);
}
.rh-top { display: flex; align-items: center; gap: var(--sp-3); }
.rh-title { flex: 1; min-width: 0; }
.rh-title h1 { margin: 0; }
.rh-sub { font-size: var(--fs-sm); color: var(--text-muted); }
.rh-time { text-align: right; }
.rh-time .k { display: block; font-size: var(--fs-xs); color: var(--text-dim); }
.rh-time .v { font-family: var(--font-mono); font-size: var(--fs-mono-l); }
.rh-chips { margin-top: var(--sp-3); }
.rh-prize {
  margin-top: var(--sp-3); font-size: var(--fs-sm); color: var(--text-muted);
}
.rh-prize summary { cursor: pointer; color: var(--text-muted); }

.tabs {
  display: flex; gap: var(--sp-1);
  background: var(--surface-2); border-radius: var(--radius-sm);
  padding: var(--sp-1); margin-bottom: var(--sp-4);
}
.tab {
  flex: 1; position: relative;
  padding: var(--sp-2) var(--sp-2); min-height: 40px;
  border: none; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-muted);
  font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.tab.is-active { background: var(--surface); color: var(--gold); }
.tab .dot {
  position: absolute; top: 6px; right: 8px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--gold);
}
/* 체험으로 열린 탭에 붙는 이모티콘. 비어 있을 때 자리를 먹지 않아야 탭 너비가
   적용 응답이 도착하는 순간 덜컥 흔들리지 않는다(:empty → margin 0). */
.tab .ev { margin-right: 4px; font-size: var(--fs-sm); }
.tab .ev:empty { margin-right: 0; }

/* ══ 출전표 ════════════════════════════════════════════════════ */
.entry-tools {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-2); margin-bottom: var(--sp-3);
}
.entry-list { display: grid; gap: var(--sp-2); }
/* 기본은 말 정보만. 오픈된 경주에서만 배당 열이 붙는다(.has-odds). */
.entry-list.has-odds .entry { grid-template-columns: auto 1fr auto; }
.entry {
  display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3);
  /* 줄이 넷(마명·제원·전적·기수)이라 가운데 정렬하면 마번 배지가 마명에서
     떨어져 어느 말의 번호인지 읽히지 않는다 — 첫 줄에 맞춘다. */
  align-items: start;
  padding: var(--sp-3);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.entry-name { font-weight: 700; }
.entry-sub { font-size: var(--fs-sm); color: var(--text-muted); }
.entry-sub .sep { color: var(--text-dim); margin: 0 4px; }
/* 전적 줄 — 숫자가 세로로 줄 맞아야 위아래 말을 견줄 수 있다. */
.entry-rec {
  font-size: var(--fs-sm); color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.entry-rec .k { color: var(--text-dim); margin-right: 5px; }
.entry-rec .n { font-family: var(--font-mono); }
.entry-rec + .entry-rec { margin-top: 1px; }
/* 기수·조교사는 **이름이 먼저**다(무료 칸). 전적은 자료집이 있을 때만 붙는다. */
.entry-rec .who { color: var(--text); font-weight: 600; }
.entry-rec .one { white-space: nowrap; }
/* 부담중량 옆 감량 — 숫자에 붙는 보조값이라 한 단계 죽인다. */
.entry-sub .cut { color: var(--text-dim); }
.entry-odds {
  text-align: right; font-family: var(--font-mono);
  font-variant-numeric: tabular-nums; font-size: var(--fs-mono-l); font-weight: 700;
}
.entry-odds .u { font-size: var(--fs-xs); color: var(--text-dim); margin-left: 2px; }
.entry.is-scratched { opacity: .5; }
.entry.is-scratched .entry-name { text-decoration: line-through; }
tr.is-scratched { opacity: .5; }
tr.is-scratched td:nth-child(2) { text-decoration: line-through; }

/* ══ 지급율 보기 ═══════════════════════════════════════════════ */
/* 상단바 — 해외 거래소형 배당판(Betfair Exchange)의 머리를 따왔다.
   왼쪽에 경주 한 줄, 오른쪽에 큰 모노 카운트다운. 판(단승 2줄 표 · 복승
   매트릭스)은 실제 경마장 전광판 모양 그대로 두고, 머리와 칸 색만 빌렸다. */
.ob-top {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4);
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.ob-left { display: flex; align-items: center; gap: var(--sp-3); flex: 1; min-width: 0; }
.ob-title { font-weight: 700; }
.ob-meta { font-size: var(--fs-xs); color: var(--text-dim); margin-top: 2px; }
.ob-right { text-align: right; }
/* 카운트다운은 이 판에서 가장 큰 숫자다 — 남은 시간이 곧 판단 시간이다. */
.ob-clock {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-l); font-weight: 800; color: var(--gold);
}
.ob-clock.is-urgent { color: var(--danger); }
.ob-clock.is-done { color: var(--text-muted); }
.ob-clock-k { font-size: var(--fs-xs); color: var(--text-dim); }

/* 단승 — 마번 줄 / 지급율 줄, 두수로 폭을 나눠 화면을 꽉 채운다.
   실제 경마장 전광판과 같은 모양이다(개발요청/참고자료/배당판예시1.jpg).
   글자는 절대 줄바꿈하지 않고, 칸이 좁아지면 크기가 따라 줄어든다(clamp). */
.odds-win {
  width: 100%; table-layout: fixed; border-collapse: collapse;
  /* 지급율이 잘리면 오독한다 — 돈이 걸린 숫자다. 이보다 좁아지면 줄이지 말고
     `.scroll-x` 로 넘긴다. 두수(--cols)는 odds.html 이 넣어 준다.
     한 칸이 감당할 폭은 소수 한 자리까지 붙인 **다섯 글자**(`48.0`~`298.8`)다. */
  min-width: calc(var(--cols, 10) * 40px);
}
.odds-win th, .odds-win td {
  border: 1px solid var(--line);
  padding: var(--sp-2) 1px;
  text-align: center; white-space: nowrap;
  overflow: hidden;
  font-family: var(--font-board); font-variant-numeric: tabular-nums;
  font-weight: var(--fw-board);
}
.odds-win th.hd {
  color: var(--num-yellow);
  font-size: clamp(11px, 3vw, var(--fs-h3));
  background: var(--surface-2);
}
.odds-win td {
  font-size: clamp(11px, 3.4vw, var(--fs-h2));
  background: var(--surface);
}

/* 복승 매트릭스 — 상삼각을 접어 정사각형을 다 쓰는 구조(race.html 주석 참조) */
.odds-legend {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  padding: var(--sp-3); margin-bottom: var(--sp-3);
  background: var(--surface-2); border-radius: var(--radius-sm);
  font-size: var(--fs-sm); color: var(--text-muted);
}
.odds-legend .k { display: inline-flex; align-items: center; gap: 6px; }
.odds-legend .sw {
  width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--line-strong);
}
.sw-diag { background: var(--surface-3); }
.sw-fold { background: var(--gold-tint); border-color: var(--gold-deep); }

/* 복승 매트릭스 — 화면 폭에 맞춰 꽉 차게 늘어난다(개발메모 UX디자인.txt).
   table-layout:fixed 라 열이 균등하게 나뉘고, 두수가 많으면 min-width 아래로만 스크롤. */
.odds-qnl {
  width: 100%; table-layout: fixed; border-collapse: collapse;
  /* 한 칸이 감당할 폭은 소수 한 자리까지 붙인 **다섯 글자**(`298.8`)다.
     열 수(--cols)는 odds.html 이 그린 뒤에 실제 값으로 넣어 준다. */
  min-width: calc(var(--cols, 8) * 42px);
}
.odds-qnl td, .odds-qnl th {
  border: 1px solid var(--line);
  height: 34px;
  padding: 2px 1px;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  /* 배당판은 숫자가 주인공이다 — 칸이 허용하는 만큼 크게, 볼드로.
     4자리 배당(1096.5)까지 칸 안에 들어가야 해서 상한을 vw 로 묶는다. */
  font-size: clamp(10px, 3.1vw, var(--fs-mono));
  font-weight: 700;
  /* 숫자는 **오른쪽 정렬**이다 — 자릿수가 맞아야 위아래·좌우로 견줄 수 있다.
     소수 한 자리를 늘 붙이므로(118.0) 가장 긴 값은 `298.8` 다섯 글자다. */
  text-align: right; padding-right: 4px;
  white-space: nowrap; overflow: hidden;
}
/* 값 칸 — **칸 자체가 색**이고 숫자는 흰 고딕이다(해외 배당판 방식).
   낮을수록(인기일수록) 뜨겁다. 색이 곧 인기 구간이라 판을 훑기만 해도
   어디가 인기인지 보인다. 배경색은 흰 글자가 읽히도록 어둡게 잡았다. */
.odds-qnl td.num {
  color: var(--text-on-color);
  font-family: var(--font-board); font-weight: var(--fw-board);
}
.odds-qnl td.odds-top  { background: var(--odds-bg-top); }
.odds-qnl td.odds-hot  { background: var(--odds-bg-1); }
.odds-qnl td.odds-warm { background: var(--odds-bg-2); }
.odds-qnl td.odds-mid  { background: var(--odds-bg-3); }
.odds-qnl td.odds-cold { background: var(--odds-bg-4); }
/* 칸을 색으로 채우면 접어 넣은 블록의 배경 구분이 묻힌다 — 테두리를 금색으로
   돌려 접기 블록임을 남긴다(행·열 라벨은 그대로 금색이다). */
.odds-qnl td.fold.num { border-color: var(--gold-deep); }
/* 마번 머리칸만 가운데 — 숫자가 아니라 이름표다.
   숫자 자리에는 **번호포 배지**가 들어간다(`.gate`) — 판에서도 마필정보와
   같은 색으로 짚이게. 접기 블록의 금색 배경은 그대로 두어 구분이 남는다. */
.odds-qnl td.hd, .odds-qnl th.hd {
  color: var(--num-yellow); text-align: center; padding-right: 1px;
}
/* 판에서는 마번 배지의 **상자를 지우고 글자만** 남긴다(2026-09-07 지시).
   `.is-plain` 이라 바탕·테두리가 이미 안 보이는데 상자 규격(min-width/height/
   padding)만 남아 있어서, 마번이 같은 칸의 지급율 숫자보다 작게 읽혔다.
   크기·서체를 **그 판의 값과 똑같이** 맞춘다 — 실물 전광판도 마번과 배당을
   같은 크기로 쓴다(`개발요청/참고자료/서울경마장배당판.jpg`). */
.odds-win .gate, .odds-qnl .gate {
  margin: 0 auto;
  min-width: 0; height: auto; padding: 0;
  font-family: var(--font-board); font-weight: var(--fw-board);
}
.odds-win .gate { font-size: clamp(11px, 3.4vw, var(--fs-h2)); }
/* `.is-plain` 이 색을 지우므로 11~14 의 줄 띠도 함께 지운다 — 색을 안 쓰는
   판에 띠만 남으면 그 마번만 다른 것처럼 보인다. */
.odds-win .gate, .odds-qnl .gate { box-shadow: none; }
.odds-qnl .gate { font-size: clamp(10px, 3.1vw, var(--fs-mono)); }
.odds-qnl td.diag { background: var(--surface-3); }
.odds-qnl td.blank, .odds-qnl th:empty { background: var(--bg); border-color: var(--bg); }
/* 값 없는 칸 — 색을 칠하지 않는다. `td.num` 의 흰 글자를 다시 눌러 준다. */
.odds-qnl td.blank-dot { color: var(--text-dim); }
/* 접어 넣은 블록 — 라벨(행·열 머리)만 배경으로 표시한다. 값 칸은 구간 색이
   차지하므로 테두리로 구분한다(위 `td.fold.num`). */
.odds-qnl td.hd.fold, .odds-qnl th.fold { background: var(--gold-tint-2); }
.odds-qnl th.fold, .odds-qnl td.hd.fold { color: var(--gold-dim); }
.odds-qnl td.is-hl { outline: 2px solid var(--gold); outline-offset: -2px; }

/* 인기배당 */
.fav-list { display: grid; gap: var(--sp-2); }
.fav {
  display: grid; grid-template-columns: auto 1fr auto; gap: var(--sp-3);
  align-items: center; padding: var(--sp-2) var(--sp-3);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.fav-rank {
  width: 24px; height: 24px; border-radius: var(--radius-pill);
  display: grid; place-items: center;
  background: var(--surface-3); color: var(--text-muted);
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
}
.fav:nth-child(-n+3) .fav-rank { background: var(--gold); color: var(--text-on-gold); }
.fav-pair { display: flex; align-items: center; gap: 6px; }

/* 배당 구간 — 낮을수록(인기일수록) 뜨겁다. `odds-top` 은 그 경주의 최저 배당 하나. */
.odds-top  { color: var(--odds-top); }
.odds-hot  { color: var(--odds-1); }
.odds-warm { color: var(--odds-2); }
.odds-mid  { color: var(--odds-3); }
.odds-cold { color: var(--odds-4); }

/* ══ 동영상 ════════════════════════════════════════════════════ */
.vp { display: grid; gap: var(--sp-3); }
.vp-stage {
  position: relative; aspect-ratio: 16 / 9;
  /* 표기·버튼 크기를 무대 너비에 매단다(cqw). 폰과 전체화면이 같은 비율로 보인다. */
  container-type: inline-size;
  border-radius: var(--radius); overflow: hidden;
  background: var(--video-bg) center/cover no-repeat;
  border: 1px solid var(--line);
}
.vp-video { width: 100%; height: 100%; display: block; background: var(--video-bg); }

/* 좌상단 표기 — 렌더에 굽지 않고 화면이 얹는다. 문구가 바뀌어도 영상을 다시
   만들 필요가 없고, 화면 크기에 따라 글자가 같이 줄어든다.
   `cqw`(무대 너비 기준)로 잡아 폰이든 전체화면이든 비율이 유지된다.
   영상 위 어떤 밝기에서도 읽히도록 그림자를 깔되, 판을 덧대지는 않는다 —
   경주 초반 좌상단은 관중석이라 판을 대면 그쪽이 더 눈에 띈다. */
.vp-badge {
  position: absolute; top: 2.2cqw; left: 2.6cqw; z-index: 2;
  display: grid; gap: 0.3cqw;
  pointer-events: none;                /* 컨트롤·재생 클릭을 가리지 않는다 */
  text-shadow: 0 1px 3px rgba(0, 0, 0, .9), 0 0 1px rgba(0, 0, 0, .9);
  line-height: 1.15; letter-spacing: -.01em;
}
/* clamp 의 최소값이 없으면 카드 안 작은 무대에서 10px 밑으로 떨어져 못 읽고,
   최대값이 없으면 데스크톱 전체화면에서 화면을 절반 가린다. */
.vp-badge-1 { font-size: clamp(13px, 4cqw, 34px); font-weight: 700; color: var(--gold); }
/* 경주거리는 경기장 이름과 **색을 달리** 한다 — 같은 금색으로 붙여 두면
   '馬요일파크1400m' 이 한 낱말로 읽힌다. 골드보다 한 톤 밝게만 둔다
   (다른 색을 쓰면 무대 위에서 두 개의 강조가 서로 다툰다). */
.vp-badge-m { color: var(--text); opacity: .92; font-weight: 600; }
/* 둘째 줄은 **회차가 크고 날짜가 작다.** 지금 몇 번째 경주인지가 먼저 읽혀야
   하고, 날짜는 어느 회차 묶음인지 확인하는 보조값이다. 크기가 다르니
   baseline 으로 맞춘다 — 가운데로 맞추면 작은 쪽이 떠 보인다. */
.vp-badge-2 {
  display: flex; align-items: baseline; gap: .45em;
  color: #fff; font-weight: 600;
}
.vp-badge-r { font-size: clamp(15px, 4.6cqw, 38px); font-weight: 700; }
.vp-badge-d { font-size: clamp(9px, 2.5cqw, 21px); font-weight: 500; opacity: .8; }

/* 전체화면은 무대를 통째로 넣는다(표기가 <video> 밖이라 그래야 남는다).
   그래서 버튼도 직접 둔다 — 네이티브 버튼은 controlsList 로 감췄다.
   컨트롤바(하단)와 겹치지 않게 우상단이다. */
.vp-fs {
  position: absolute; top: 2.2cqw; right: 2.6cqw; z-index: 2;
  width: 7cqw; height: 7cqw; min-width: 28px; min-height: 28px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, .45); color: #fff;
  font-size: 3.4cqw; line-height: 1; cursor: pointer;
}
.vp-fs:hover { background: rgba(0, 0, 0, .7); }
/* 전체화면일 때는 16:9 고정을 풀어야 화면을 다 쓴다. */
.vp-stage:fullscreen { aspect-ratio: auto; width: 100%; height: 100%; border-radius: 0; }
.vp-stage:fullscreen .vp-video { object-fit: contain; }
.vp-poster {
  /* 표기·전체화면 버튼(z-index 2)보다 위다 — 못 트는 경주의 안내를
     표기가 덮으면 안 된다. 재생이 시작되면 포스터가 숨어 표기가 드러난다. */
  position: absolute; inset: 0; z-index: 3;
  display: grid; place-content: center; justify-items: center; gap: var(--sp-3);
  padding: var(--sp-4); text-align: center;
  background: radial-gradient(120% 80% at 50% 40%, var(--surface-2), var(--bg));
}
.vp-play {
  width: 68px; height: 68px; border-radius: 50%;
  display: grid; place-items: center;
  border: 2px solid var(--action-fn); background: var(--action-fn-tint); color: var(--action-fn);
  font-size: 1.5rem; cursor: pointer;
}
.vp-play:hover { background: var(--action-fn); color: var(--action-fn-text); }
.vp-msg { color: var(--text-muted); font-size: var(--fs-sm); }

/* 재생 갈래 — 일반화질 / HD. 큰 [▶] 하나로 몰면 어느 화질로 트는지 모르고
   누르게 된다. 줄 버튼으로 늘어놓고 각자 무엇인지 적는다. */
.vp-picks { display: grid; gap: var(--sp-2); width: min(320px, 100%); }
.vp-pick {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-sm);
  border: 1px solid var(--action-fn); background: var(--action-fn-tint);
  color: var(--action-fn); font-weight: 600; cursor: pointer; text-align: left;
}
.vp-pick:hover { background: var(--action-fn); color: var(--action-fn-text); }
/* HD 는 **유형 색(`--pt-hd` 보라)** 이다(2026-09-07 지시). 상점·경주목록의
   [HD영상] 칩과 같은 색이라야 "거기서 산 그것" 이 여기 열렸다고 읽힌다.
   (전에는 골드였는데, 2026-09-04 에 상점이 유형별 색으로 가면서 여기만 남았다.) */
.vp-pick.is-hd {
  border-color: var(--pt-hd); background: var(--pt-hd-tint); color: var(--pt-hd);
}
.vp-pick.is-hd:hover { background: var(--pt-hd); color: var(--bg); }
/* 못 산 HD — **자리는 보여 준다**(감추면 무엇을 못 보는지 알 수 없다).
   재생이 아니라는 것을 점선과 자물쇠로 알리고, 눌리면 이용권 화면으로 간다. */
.vp-pick.is-locked { border-style: dashed; }
.vp-pick .vp-go {
  margin-left: auto; font-size: var(--fs-sm); font-weight: 600;
  text-decoration: underline; white-space: nowrap;
}
.vp-pick .vp-ico { font-size: 1.1rem; line-height: 1; }
.vp-pick .vp-t { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.vp-res { font-family: var(--font-mono); font-size: var(--fs-xs); opacity: .85; }
/* 안내문은 무대(16:9) **밖**이다. 안에 얹으면 작은 화면에서 잘리는데, 하필
   잘리는 것이 [구매하기] 다. `:empty` 면 자리도 먹지 않는다. */
.vp-info:empty { display: none; }
.vp-note {
  color: var(--text-muted); font-size: var(--fs-sm); line-height: 1.5;
}
.vp-note b { color: var(--win); }
/* HD 설명 — 위 [HD동영상] 줄과 **같은 색 계열**로 둘러 그 줄의 설명임을 보인다.
   본문까지 보라로 칠하지는 않는다(긴 문장은 유채색이면 읽기 나쁘다) —
   칩·테두리·링크만 유형 색을 쓰고 글자는 그대로 둔다. */
.vp-note.is-hd {
  padding: var(--sp-2) var(--sp-3);
  border-left: 3px solid var(--pt-hd);
  border-radius: var(--radius-sm);
  background: var(--pt-hd-tint);
}
.vp-note.is-hd .ptype { margin-right: 4px; vertical-align: 1px; }
.vp-note.is-hd a { color: var(--pt-hd); }
.vp-lock { font-size: 1.6rem; }
.vp-after {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3);
}

/* ══ 경주결과 ══════════════════════════════════════════════════ */
.result-hero {
  padding: var(--sp-4); margin-bottom: var(--sp-4);
  border-radius: var(--radius); border: 1px solid var(--line);
  text-align: center;
}
.result-hero .rh-k { font-size: var(--fs-sm); color: var(--text-muted); }
.result-hero .rh-v {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-xl); font-weight: 700; line-height: 1.2;
}
/* 적중 — 축하하되 카지노 연출은 하지 않는다(사행성 최소화) */
.result-hero.is-hit {
  border-color: var(--gold);
  background: linear-gradient(160deg, var(--gold-tint), transparent 70%), var(--surface);
}
.result-hero.is-hit .rh-v { color: var(--gold); }
.result-hero.is-miss { background: var(--surface); }
.result-hero.is-miss .rh-v { color: var(--text-muted); font-size: var(--fs-h2); }
.result-hero.is-refund { border-color: var(--warn); background: var(--warn-tint); }
.result-hero.is-refund .rh-v { color: var(--warn); }

/* 경주 결과판 — 실제 경마장 결과판 형식 */
.board { padding: var(--sp-3); }
.board-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-2); flex-wrap: wrap;
  padding-bottom: var(--sp-2); border-bottom: 1px solid var(--line);
}
/* 머리 = 경주번호(공통 배지) + 거리. 경마장은 넣지 않는다. */
.board-title {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-h3);
}
.board-lamps { display: flex; gap: var(--sp-3); }
.lamp {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-sm); color: var(--text-dim);
}
.lamp > i {
  width: 11px; height: 11px; border-radius: 50%;
  border: 2px solid var(--line-strong); background: transparent;
}
.lamp.on { color: var(--win); }
.lamp.on > i { border-color: var(--win); background: var(--win); }

.board-body { padding: var(--sp-2) 0; }
.board-row {
  display: grid; grid-template-columns: 28px 34px 1fr auto;
  gap: var(--sp-2); align-items: center;
  padding: 5px 0; border-bottom: 1px solid var(--line);
}
.board-row:last-child { border-bottom: none; }
.board-rank { color: var(--text-muted); text-align: center; }
.board-row .gate { margin: 0 auto; }
.board-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-gap {
  font-family: var(--font-mono); font-size: var(--fs-mono-s);
  color: var(--text-muted); white-space: nowrap;
}
.board-foot {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  padding-top: var(--sp-2); border-top: 1px solid var(--line);
  font-size: var(--fs-sm);
}
.board-foot > div { display: flex; gap: 6px; align-items: baseline; }
.board-foot .k { color: var(--text-muted); }
.board-foot b { font-family: var(--font-mono); }

.podium { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); margin-bottom: var(--sp-3); }
.pod {
  display: grid; gap: 4px; justify-items: center; text-align: center;
  padding: var(--sp-3) var(--sp-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.pod-1 { border-color: var(--gold); background: linear-gradient(180deg, var(--gold-tint-2), transparent), var(--surface); }
.pod-rank { font-size: var(--fs-xs); color: var(--text-muted); font-weight: 700; }
.pod-1 .pod-rank { color: var(--gold); }
.pod-name { font-size: var(--fs-sm); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.pod-sub { font-size: var(--fs-xs); color: var(--text-muted); }

.odds-line {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: baseline;
  padding: var(--sp-3); margin-bottom: var(--sp-3);
  background: var(--surface-2); border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-size: var(--fs-mono-s);
}

/* ══ 예상하기(배팅) ════════════════════════════════════════════ */
.bet-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-3);
  padding: var(--sp-3); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.bet-head .bh-race { display: flex; align-items: center; gap: var(--sp-2); }
.bet-head .bh-time { text-align: right; }
.bet-head .bh-time .k { display: block; font-size: var(--fs-xs); color: var(--text-dim); }
.bet-head .bh-time .v { font-family: var(--font-mono); font-size: var(--fs-mono-l); }
/* 팝업처럼 닫는 [X] — 눌러야 하는 곳이라 넉넉하게 잡는다 */
.bet-close {
  flex: none; width: 48px; height: 48px;
  display: grid; place-items: center;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text);
  font-size: 1.5rem; line-height: 1; font-weight: 700; cursor: pointer;
}
.bet-close:hover { background: var(--surface-3); color: var(--text); }

.seg { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.seg-btn {
  flex: 1; min-height: 48px; padding: var(--sp-2);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text-muted);
  font-weight: 700; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
}
.seg-btn .en { font-size: var(--fs-xs); font-weight: 500; opacity: .75; }
/* 고른 예상종류의 규칙 한 줄 — 버튼 밑에 붙어 있어야 무엇의 설명인지 읽힌다. */
.seg-desc {
  margin: calc(var(--sp-2) * -1) 0 var(--sp-4);
  font-size: var(--fs-sm); color: var(--text-muted);
}
/* 승식 색이 밝은 청색이라 흰 글자는 3:1 대비도 안 나온다 — 어두운 글자를 쓴다. */
.seg-btn.is-win.is-active {
  background: var(--pool-win); border-color: var(--pool-win); color: var(--pool-text);
}
.seg-btn.is-qnl.is-active {
  background: var(--pool-qnl); border-color: var(--pool-qnl); color: var(--pool-text);
}
/* 파생 승식(쌍승·삼복승). 색은 `ui.js` 의 승식색표와 짝이다 — 한쪽만 바꾸면
   배지와 버튼이 다른 색이 된다. 인디고·보라는 청색 계열보다 어두워서 흰 글자다. */
.seg-btn.is-ex.is-active {
  background: var(--pool-3); border-color: var(--pool-3); color: #fff;
}
.seg-btn.is-tr.is-active {
  background: var(--pool-4); border-color: var(--pool-4); color: #fff;
}

.pick { margin-bottom: var(--sp-4); }
.pick-label {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-2);
  font-size: var(--fs-sm); font-weight: 600; margin-bottom: var(--sp-2);
}
.pick-label .hint { font-weight: 400; color: var(--text-muted); font-size: var(--fs-xs); }
/* 둘째·셋째 선택 블록은 좌측 띠로 첫 블록과 형태를 구분한다
   (라벨만으로 두지 않는다). 띠 색은 지금 고른 승식 색을 따라간다 — 삼복승은
   블록이 셋이라 색까지 같으면 어디를 고르는 중인지 눈으로 끊기지 않는다. */
.pick-2, .pick-3 {
  padding-left: var(--sp-3);
  border-left: 3px solid var(--pool-qnl);
}
.pool-ex .pick-2, .pool-ex .pick-3 { border-left-color: var(--pool-3); }
.pool-tr .pick-2, .pool-tr .pick-3 { border-left-color: var(--pool-4); }

.grid { display: grid; grid-template-columns: repeat(var(--cols, 5), 1fr); gap: var(--sp-2); }
.cell {
  display: grid; gap: 1px; place-content: center; justify-items: center;
  min-height: 56px; padding: var(--sp-2) 2px;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text);
  cursor: pointer; overflow: hidden;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.cell .no { font-family: var(--font-mono); font-size: var(--fs-mono-l); font-weight: 700; line-height: 1.1; }
/* 마번 칸은 번호포 배지가 곧 번호다 — 마필정보와 같은 색으로 짚인다. */
.cell .gate { margin-bottom: 1px; }
.cell .nm {
  font-size: var(--fs-xs); color: var(--text-muted);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cell .od { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-dim); }
.cell:disabled { opacity: .35; cursor: not-allowed; }
/* 고른 칸 — 승식 색이 밝은 청색이라 글자는 어둡게 간다(흰 글자는 안 읽힌다). */
.cell.on { background: var(--pool-win); border-color: var(--pool-win); color: var(--pool-text); }
.cell.on .nm, .cell.on .od { color: var(--pool-text); opacity: .78; }
.pool-qnl .cell.on {
  background: var(--pool-qnl); border-color: var(--pool-qnl); color: var(--pool-text);
}
.pool-qnl .cell.on .nm, .pool-qnl .cell.on .od { color: var(--pool-text); opacity: .78; }
.pool-ex .cell.on { background: var(--pool-3); border-color: var(--pool-3); color: #fff; }
.pool-tr .cell.on { background: var(--pool-4); border-color: var(--pool-4); color: #fff; }
.pool-ex .cell.on .nm, .pool-ex .cell.on .od,
.pool-tr .cell.on .nm, .pool-tr .cell.on .od { color: #fff; opacity: .8; }

.grid-amt { --cols: 3; }
.grid-amt .cell { min-height: 48px; }
.grid-amt .cell .no { font-size: var(--fs-mono); }
.amt-hint { margin-top: var(--sp-2); font-size: var(--fs-xs); color: var(--text-dim); }

/* 하단 고정 구매 바 — "무엇을 얼마에 사는지"가 항상 보인다 */
.buybar {
  position: fixed; left: 0; right: 0; z-index: var(--z-sticky);
  bottom: calc(var(--nav-h) + var(--safe-b));
  padding: var(--sp-3) var(--sp-4) calc(var(--sp-3));
  background: color-mix(in srgb, var(--surface) 96%, transparent);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--line);
}
.has-devbar .buybar { bottom: calc(var(--nav-h) + var(--safe-b) + var(--dev-h)); }
.buybar-inner { max-width: var(--wrap); margin: 0 auto; display: grid; gap: var(--sp-2); }
.buybar-sel {
  font-family: var(--font-mono); font-size: var(--fs-mono-s);
  color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.buybar-row { display: flex; align-items: center; gap: var(--sp-3); }
.buybar-sum { flex: 1; min-width: 0; display: grid; gap: 2px; }
/* 라벨 폭을 맞춰 두 줄의 숫자가 세로로 정렬되게 한다 */
.bar-line {
  display: grid; grid-template-columns: 88px auto 1fr; gap: var(--sp-2);
  align-items: baseline;
}
.buybar-sum .k { font-size: var(--fs-xs); color: var(--text-dim); }
.buybar-sum .cnt { font-size: var(--fs-xs); color: var(--text-dim); }
.buybar-sum .v, .buybar-sum .v-left {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-l); font-weight: 700;
}
.buybar-sum .v { color: var(--gold); }
.buybar-sum .v.over { color: var(--danger); }
/* 잔여포인트는 늘 눈에 띄어야 한다 — 예상액을 정하는 기준이 이 숫자다. */
.buybar-sum .v-left { color: var(--danger); font-size: var(--fs-mono); }
.buybar .btn { min-width: 140px; }
/* 구매바가 콘텐츠를 가리지 않도록 */
.bet-page { padding-bottom: 120px; }

/* ══ 구매내역 ══════════════════════════════════════════════════ */
.filter { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.filter label { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); }
.filter input[type="date"] {
  padding: 9px var(--sp-3); background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}

.hist { margin-bottom: var(--sp-3); padding: var(--sp-3); }
.hist-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-2); margin-bottom: var(--sp-2);
}
.hist-lines { display: grid; gap: 2px; margin: var(--sp-2) 0; }
.hist-line {
  display: grid; grid-template-columns: auto auto 1fr auto; gap: var(--sp-2);
  align-items: center; font-size: var(--fs-sm);
}
.hist-line .res { justify-self: end; }
.hist-line .no { font-family: var(--font-mono); }
.hist-line .amt { font-family: var(--font-mono); text-align: right; color: var(--text-muted); }
.hist-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-2); margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}
.hist-money { display: flex; align-items: baseline; gap: var(--sp-2); font-family: var(--font-mono); }
.hist-money .buy { color: var(--text-muted); }
.hist-money .arrow { color: var(--text-dim); }
.hist-money .back { font-size: var(--fs-mono-l); font-weight: 700; }
.hist-money .back.plus { color: var(--win); }
.hist-time { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-dim); }

/* ══ 마이페이지 ════════════════════════════════════════════════ */
/* 메뉴 리스트 */
.menu { display: grid; gap: var(--sp-2); }
.menu a {
  display: grid; grid-template-columns: auto 1fr auto; gap: var(--sp-3);
  align-items: center; padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); color: var(--text);
}
.menu a:hover { background: var(--surface-2); text-decoration: none; }
.menu .ico { font-size: 1.2rem; }
.menu .t { font-weight: 600; }
.menu .d { font-size: var(--fs-sm); color: var(--text-muted); }
.menu .go { color: var(--text-dim); }

/* 성적 타일 — 2열 격자. 숫자가 주인공이라 라벨은 작게 아래에 둔다. */
.tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-2); }
.tile {
  padding: var(--sp-3); text-align: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.tile .v {
  display: block;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-l); font-weight: 700; line-height: 1.2;
}
.tile .k { font-size: var(--fs-xs); color: var(--text-muted); }
.tile-hero { grid-column: 1 / -1; }
.tile-hero .v { font-size: var(--fs-mono-xl); color: var(--gold); }

/* 회수율 — 100 이 본전. 넘으면 녹색, 모자라면 회색 */
.v-plus { color: var(--win); }
.v-gold { color: var(--gold); }

/* 일자별 막대 — 라이브러리 없이 div 로 그린다(SPA 로 가지 않는다) */
.chart {
  display: flex; align-items: flex-end; justify-content: center; gap: 4px;
  height: 120px; padding: var(--sp-3) 0;
  overflow-x: auto;
}
/* 폭을 묶어 둔다 — 하루치만 있을 때 막대가 화면 폭만큼 부풀지 않게. */
.bar-col {
  flex: 0 1 32px; max-width: 44px; min-width: 24px;
  display: flex; flex-direction: column;
  align-items: center; justify-content: flex-end; gap: 3px; height: 100%;
}
.bar-wrap { display: flex; align-items: flex-end; gap: 2px; height: 100%; width: 100%; }
.bar { flex: 1; border-radius: 2px 2px 0 0; min-height: 2px; }
.bar-bet { background: var(--surface-3); }
.bar-back { background: var(--gold); }
.bar-lab {
  font-family: var(--font-mono); font-size: 9px; color: var(--text-dim);
  white-space: nowrap;              /* '08-10' 이 두 줄로 접히지 않게 */
}
.chart-legend {
  display: flex; gap: var(--sp-3); font-size: var(--fs-xs); color: var(--text-muted);
}
.chart-legend .sw { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }

/* 가로 비율 막대 (승식별·구간별) */
.hbar { display: grid; gap: var(--sp-3); }
.hbar-row { display: grid; grid-template-columns: 72px 1fr auto; gap: var(--sp-3); align-items: center; }
.hbar-k { font-size: var(--fs-sm); }
.hbar-track { height: 10px; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; }
.hbar-track > i { display: block; height: 100%; border-radius: inherit; background: var(--gold); }
.hbar-track.is-win > i { background: var(--pool-win); }
.hbar-track.is-qnl > i { background: var(--pool-qnl); }
.hbar-v {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-mono-s); min-width: 64px; text-align: right;
}

/* 베스트 적중 */
.best {
  display: grid; grid-template-columns: auto 1fr auto; gap: var(--sp-3);
  align-items: center; padding: var(--sp-3);
  background: linear-gradient(180deg, var(--gold-tint-2), transparent), var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.best-odds {
  font-family: var(--font-mono); font-size: var(--fs-mono-l); font-weight: 700;
  color: var(--gold);
}

/* Home 의 AI 동영상 예상 티저 — 기능이 붙으면 이 자리가 맨 위로 온다 */
/* 제목 크기로 올린다 — 카드가 여럿 있는 화면에서 눈에 걸려야 한다 */

/* 이용안내 */
.guide h2 { margin-top: var(--sp-5); }
.guide .card p:last-child { margin-bottom: 0; }
.faq { border-bottom: 1px solid var(--line); padding: var(--sp-3) 0; }
.faq:last-child { border-bottom: none; }
.faq summary { cursor: pointer; font-weight: 600; }
.faq p { margin: var(--sp-2) 0 0; color: var(--text-muted); font-size: var(--fs-sm); }

/* ══ 모달 · 바텀시트 ═══════════════════════════════════════════ */
.modal {
  position: fixed; inset: 0; z-index: var(--z-sheet);
  background: var(--overlay);
  display: flex; align-items: flex-end; justify-content: center;
}
/* 개발 툴바는 모달보다 위에 뜬다(z-index 100). 툴바가 있으면 시트를 그만큼
   올려서 [구매하기] 가 가려지지 않게 한다. 툴바를 모달 아래로 내리지 않는 이유는
   모달을 띄운 채로도 시각 이동·회원 전환을 써야 하기 때문이다. */
.has-devbar .modal { bottom: var(--dev-h); }
.modal-box {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: var(--sp-4) var(--sp-4) calc(var(--sp-4) + var(--safe-b));
  width: 100%; max-width: 520px; max-height: 88vh; overflow-y: auto;
  box-shadow: var(--shadow-lg);
  animation: 시트등장 var(--dur) var(--ease);
}
@keyframes 시트등장 { from { transform: translateY(16px); opacity: .6; } }
@media (prefers-reduced-motion: reduce) { .modal-box { animation: none; } }
.modal-box h3 { text-align: center; }
.modal-wide { max-width: 760px; }

/* 안내 배너.
 * ⚠️ **flex 가 아니라 block 이다.** flex 로 두면 배너 안의 맨 텍스트와 `<b>` 가
 *    **각각 flex 아이템**이 되어, 한 문장이 낱말 덩어리로 쪼개져 세로로 흩어진다
 *    ("기간제 / 정식 / 이고, / …" — 2026-09-04 실제로 그렇게 보였다).
 *    아이콘을 앞에 세우는 배너만 `.banner-icon` 으로 flex 를 켠다.
 */
.banner {
  display: block;
  padding: var(--sp-3); border-radius: var(--radius-sm);
  font-size: var(--fs-sm); margin-bottom: var(--sp-3);
  line-height: 1.6;
}
.banner-icon { display: flex; gap: var(--sp-2); align-items: flex-start; }
.banner-warn { background: var(--warn-tint); color: var(--warn); border: 1px solid var(--warn); }
.banner-info { background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--line); }
/* 이벤트로 열린 것 — 카드의 체험 표시(.ptype + 🎁)와 **같은 초록**이다.
   "산 것"(골드)과 "이번만 열린 것"(초록)이 화면마다 같은 색이어야 읽힌다. */
.banner-event { background: var(--win-tint); color: var(--win); border: 1px solid var(--win); }

/* 안내문 끝에 붙는 구매·이용권 링크. 버튼으로 만들지 않는다 — 안내는 읽는
   것이고, 누를 것은 그 문장 안의 마지막 한 마디다. */
.link {
  color: var(--action-fn); font-weight: 600; white-space: nowrap;
  text-decoration: underline; text-underline-offset: 2px;
}

/* 체험(이벤트) 표시 — 이름 **앞에** 붙는다. 뒤에 달면 제목을 다 읽고 나서야
   "이번만 열린 것" 을 알게 된다(요구사항: AI예상 앞에 체험하기 표시). */
.trial {
  display: inline-flex; align-items: center; gap: 2px;
  color: var(--win); font-weight: 700; font-size: var(--fs-sm);
}

.confirm-race { text-align: center; color: var(--gold); font-weight: 700; }
.confirm-list { margin: var(--sp-3) 0; max-height: 40vh; overflow-y: auto; }
.confirm-list > div {
  display: flex; justify-content: space-between; gap: var(--sp-2); align-items: baseline;
  padding: var(--sp-2) 0; border-bottom: 1px solid var(--line);
}
.confirm-total { text-align: right; font-size: var(--fs-h3); }
.confirm-total b { font-family: var(--font-mono); color: var(--gold); }

/* ══ 토스트 ════════════════════════════════════════════════════ */
.toasts {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--nav-h) + var(--safe-b) + var(--sp-4));
  z-index: var(--z-toast);
  display: grid; gap: var(--sp-2); width: min(92vw, 460px);
  pointer-events: none;
}
.toast {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
  background: var(--surface-3); color: var(--text);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-lg);
  font-size: var(--fs-sm);
  animation: 토스트등장 var(--dur) var(--ease);
}
.toast-error { border-color: var(--danger); color: var(--danger); background: var(--surface); }
.toast-ok { border-color: var(--win); color: var(--win); background: var(--surface); }
@keyframes 토스트등장 { from { transform: translateY(8px); opacity: 0; } }

/* ══ 빈 상태 · 스켈레톤 ═══════════════════════════════════════ */
.empty {
  display: grid; gap: var(--sp-3); justify-items: center; text-align: center;
  padding: var(--sp-6) var(--sp-4);
  color: var(--text-muted);
}
.empty-ico { font-size: 2rem; opacity: .6; }
.skel {
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--surface-2), var(--surface-3), var(--surface-2));
  background-size: 200% 100%;
  animation: 스켈 1.2s linear infinite;
}
@keyframes 스켈 { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }
.skel-row { height: 72px; margin-bottom: var(--sp-2); }

/* ══ 히어로(홈) ════════════════════════════════════════════════ */
.hero { padding: var(--sp-6) 0 var(--sp-4); }
.hero h1 { font-size: var(--fs-display); }
.hero .sub { color: var(--text-muted); max-width: 42ch; }
.steps { display: grid; gap: var(--sp-2); }
.stepbox {
  display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3); align-items: center;
  padding: var(--sp-3); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.stepbox .n {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--gold-tint); color: var(--gold);
  font-family: var(--font-mono); font-size: var(--fs-mono-s); font-weight: 700;
}
.stepbox .t { font-size: var(--fs-sm); }

/* ══ 비회원 홈 — 명승부 다시보기 ═══════════════════════════════
 * 첫 장은 화면 폭을 꽉 채운다. 무엇을 하는 서비스인지 글보다 이 한 편이 빠르다
 * (개발요청 2.비회원 · A안). 캡션은 영상 **위에** 얹는다 — 아래에 달면
 * 16:9 밑으로 글줄이 하나 더 붙어 첫 화면에서 카드가 밀린다. */
.film-list { display: grid; gap: var(--sp-4); }
.film {
  position: relative; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line);
  /* 영상이 뜨기 전에도 자리가 검게 서 있어야 화면이 덜컹거리지 않는다 */
  background: var(--track-green-dim);
}
.film video {
  display: block; width: 100%; aspect-ratio: 16 / 9;
  object-fit: cover; background: #0b1f14;
}
/* 컨트롤 막대가 캡션에 가리지 않도록 캡션은 클릭을 통과시킨다 */
/* 이용권 목록의 그룹 머리 — `?t=` 로 들어왔을 때만 생긴다.
   본문 h2 보다 작게 둔다: 화면 제목이 아니라 목록 안의 칸막이다. */
.shop-group { margin-top: var(--sp-5); }
.shop-group h3 { font-size: var(--fs-md); }

/* 명승부 섹션의 광고 한 줄. 섹션 제목 바로 밑이라 제목과 붙여 둔다 —
   사이가 벌어지면 어느 섹션을 설명하는 문장인지 끊긴다. */
.film-ad {
  margin: calc(var(--sp-2) * -1) 0 var(--sp-3);
  color: var(--gold); font-size: var(--fs-sm); font-weight: 600;
}
.film-cap {
  position: absolute; left: 0; right: 0; bottom: 0; pointer-events: none;
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-6) var(--sp-3) var(--sp-3);
  background: linear-gradient(to top, rgb(0 0 0 / 78%), transparent);
}
.film-cap .t {
  font-size: var(--fs-h3); font-weight: 700; color: #fff;
  text-shadow: 0 1px 3px rgb(0 0 0 / 60%);
}
/* 착차가 이 카드의 주인공이다 — '코차' 를 못 읽으면 왜 명승부인지 모른다 */
.film-cap .t em { font-style: normal; color: var(--warn); }
.film-cap .d {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: rgb(255 255 255 / 80%); white-space: nowrap;
}

/* 체험 배지 — **초록**이다. 구매로 열린 것이 골드, 무료로 열린 것이 초록이라는
   규칙(CLAUDE.md 이벤트 절)을 비회원 체험도 그대로 따른다. */
.badge-try {
  background: var(--track-green-tint); border-color: var(--track-green);
  color: var(--track-green-text);
}

/* ══ 개발 툴바 (AIRACE_DEV_LOGIN=1 일 때만) ═══════════════════ */
.devbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-dev);
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: var(--sp-2) var(--sp-3);
  background: #1a1207; border-top: 2px solid var(--warn);
  font-size: var(--fs-sm);
}
.devbar-tag {
  padding: 2px var(--sp-2); border-radius: 4px;
  background: var(--warn); color: #201800; font-weight: 700; font-size: var(--fs-xs);
}
.devbar select, .devbar-btn {
  padding: 5px 10px; font-size: var(--fs-sm); cursor: pointer;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.devbar-btn:hover { border-color: var(--warn); }
.devbar-btn:disabled { opacity: .4; cursor: wait; }
.devbar-danger { color: var(--danger); }
.devbar-time { font-family: var(--font-mono); }
.devbar-sep { width: 1px; height: 18px; background: var(--line); margin: 0 4px; }
.devbar-out {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  flex: 1 1 100%; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.devbar-out:empty { display: none; }
/* 개발 툴바가 뜨면 하단 탭을 그 위로 올린다 (높이는 dev-bar.js 가 실측) */
.has-devbar .tabbar { bottom: var(--dev-h); }

/* ══ 유틸 ══════════════════════════════════════════════════════ */
.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.small { font-size: var(--fs-sm); }
.is-hidden { display: none !important; }
.total { color: var(--gold); }
.total.over { color: var(--danger); }
.plus { color: var(--win); }
.nowrap { white-space: nowrap; }
.out {
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: var(--sp-3); font-family: var(--font-mono); font-size: var(--fs-sm);
  overflow-x: auto; white-space: pre;
}
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* ══ 충전 · 이용권 구매 ════════════════════════════════════════ */
/* 금액/기간 버튼은 DB(`충전상품`·`상품옵션`)가 개수를 정한다. 칸 수를 고정하지
   않고 `auto-fill` 로 두는 이유 — 상품을 늘려도 CSS 를 고치지 않으려는 것. */
.chg-grid, .opt-grid {
  display: grid; gap: var(--sp-2); margin-bottom: var(--sp-4);
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}
.chg-card, .opt {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  padding: var(--sp-3); cursor: pointer;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.chg-card:hover, .opt:hover { border-color: var(--line-strong); }
.chg-card.is-on, .opt.is-on {
  border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold);
}
.chg-card .amt, .opt .p { font-family: var(--font-mono); font-size: var(--fs-h3); }
.chg-card .bonus { color: var(--win); font-size: var(--fs-sm); }
.chg-card .tot, .opt .t { color: var(--text-muted); font-size: var(--fs-sm); }

.pay-methods { display: grid; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.pay {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3); border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--surface); cursor: pointer;
}
.pay:has(input:checked) { border-color: var(--gold); }
/* 오픈예정 수단은 눌리지 않는다 — 눌러 놓고 안 되는 것보다 아예 막는 편이 낫다 */
.pay.is-off { opacity: .55; cursor: not-allowed; }



/* 과몰입 방지 — 이번 달 남은 충전 한도 안내. 경고가 아니라 **안내**라서
   danger 색을 쓰지 않는다. 겁을 주는 것이 목적이 아니다. */
.limit-note {
  margin: 0 0 var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text-dim);
  font-size: var(--fs-sm);
  line-height: 1.6;
}
.limit-note b { color: var(--text); }
.opt.is-off { opacity: .45; cursor: not-allowed; }
.opt.is-off .p { color: var(--text-dim); }
.pay .t { flex: 1; }

.acct { display: grid; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.acct-line { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); }
.acct-line .k { color: var(--text-muted); font-size: var(--fs-sm); }

.field { display: block; margin-bottom: var(--sp-3); }
.field .lab { display: block; font-size: var(--fs-sm); color: var(--text-muted); margin-bottom: 4px; }
.field .lab em { font-style: normal; color: var(--danger); }
.inp {
  width: 100%; padding: var(--sp-3);
  background: var(--bg); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: var(--fs-base);
}
.inp:focus { outline: none; border-color: var(--gold); }
.field .hint { display: block; margin-top: 4px; font-size: var(--fs-sm); color: var(--text-dim); }
.check { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); }

.banner-ok { background: var(--surface-2); color: var(--win); border: 1px solid var(--win); }
ul.tight { margin: var(--sp-2) 0 0; padding-left: 1.1em; }
ul.tight li { margin-bottom: 2px; }

/* 이용 중인 권한 — 있으면 금색, 없으면 흐리게. 개수는 상품유형 수(3)로 고정이다 */
.own-list { display: grid; gap: var(--sp-2); grid-template-columns: repeat(3, 1fr); }
.own {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--sp-2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); text-align: center;
}
.own .t { font-size: var(--fs-sm); color: var(--text-muted); }
.own .d { font-size: var(--fs-sm); color: var(--text-dim); }
/* 보유한 것만 유형 색으로 켠다 — 미보유는 무채색이라 "없다" 가 먼저 읽힌다.
   색은 `.ptype-*` 가 `color` 로 주고, 여기서는 그것을 테두리와 날짜에 옮긴다. */
.own.is-on { border-color: currentColor; }
.own.is-on .t { color: var(--text); }
.own.is-on .d { color: currentColor; font-weight: 700; }
/* 미보유 칸은 유형 색을 끈다(칸이 켜져 보이면 안 된다) */
.own:not(.is-on) { color: var(--text-dim); background: var(--surface); }

.prod { display: block; width: 100%; text-align: left; cursor: pointer; }
.prod-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); }
.prod-head .from { font-family: var(--font-mono); color: var(--gold); }
.prod-types { display: flex; gap: 4px; flex-wrap: wrap; margin: var(--sp-2) 0; }
.prod .d { margin: 0; color: var(--text-muted); font-size: var(--fs-sm); }

/* ── 유료상품 유형 칩 ═══════════════════════════════════════════
 * 혼합상품이 무엇으로 이뤄졌는지 한눈에 보이게 한다(2026-09-04 지시).
 * 색만으로 말하지 않는다 — 칩에는 언제나 이름이 함께 있다.
 */
.ptype {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px var(--sp-2); border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 700; white-space: nowrap;
  border: 1px solid currentColor;
}
/* 점은 칩이 작아졌을 때(경주 카드의 perk)도 색을 남긴다 */
.ptype::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex: 0 0 auto;
}
.ptype-book { color: var(--pt-book); background: var(--pt-book-tint); }
.ptype-ai   { color: var(--pt-ai);   background: var(--pt-ai-tint); }
.ptype-hd   { color: var(--pt-hd);   background: var(--pt-hd-tint); }

/* 상품 카드 왼쪽 띠 — **구성을 색 면적으로** 보여준다. 단품이면 한 색,
   혼합이면 그 수만큼 나뉜다. 그라데이션은 JS 가 `--구성` 으로 넣는다. */
.prod { position: relative; padding-left: calc(var(--sp-4) + 6px); }
.prod::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--구성, var(--line));
}

/* 지금 예상할 수 있는 경주 — **버튼처럼 보이지 않는 링크.**
 *
 * 목록에서 곧장 예상 화면으로 보내면 마필정보·지급율을 보지 못한 채 마번을
 * 고르게 된다(정보 단절 · 2026-09-04 지시). 그래서 테두리도 배경도 padding 도
 * 주지 않는다 — 칸처럼 보이면 "여기서 바로 산다"로 읽힌다.
 *
 * 그래도 **누르면 열린다.** 목적지는 예상 화면이 아니라 [경주상세]다. 습관대로
 * 누른 사람을 죽은 글자로 막지 않으면서, 도착하는 곳은 정보 먼저인 자리다. */
.open-note {
  color: var(--gold); font-weight: 700; text-decoration: none;
}
.open-note:hover { text-decoration: underline; text-underline-offset: 2px; }

.minus { color: var(--danger); }

/* 이름·금액이 겹치는 입금 대기 건. 위쪽 것을 무심코 누르면 남의 돈이
   남의 계정에 붙는다 — 목록에서 먼저 눈에 걸리게 한다. */
.hist.is-dup { border-color: var(--danger); }

/* 경주 카드에 붙는 유료컨텐츠 표시를 감싸는 줄.
   ⚠️ 배지 자체는 `.ptype-*`(유형별 색)이다 — 2026-09-04 에 골드/초록 한 벌에서
   유형별 색으로 바꿨다. 이용권 화면에서 산 것과 **같은 색**이라야 같은 상품으로
   읽힌다. 체험(이벤트)은 색을 바꾸지 않고 🎁 를 앞에 붙여 구분한다. */
.rc-perks { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 4px; }

/* 잠긴 전적 줄 — 값을 흐리게 두지 않는다. 값 자체가 응답에 없다. */
.locked { font-style: italic; opacity: .7; }

.pick { margin-bottom: var(--sp-3); padding: var(--sp-3); }
.pick-head { display: flex; justify-content: space-between; align-items: center; }
.pick-row {
  display: flex; gap: var(--sp-2); margin: var(--sp-2) 0;
  align-items: center; flex-wrap: wrap;
}
/* ⚠️ 인기마 줄에는 **`.gate` 마번 배지를 그대로 쓴다** — 색을 다시 적지 않는다
   (CLAUDE.md). 예전에는 `.pick-no` 라는 별도 원형 배지였는데, ① 동그라미가
   로또 공을 연상시키고 ② 같은 마번이 화면마다 다른 모양으로 보였다. 둘 다
   2026-09-07 에 걷어냈다. `.pick-win`/`.pick-lab`/`.pick-sep`(우승유력 표시)도
   같이 없앴다 — 인기마는 지목을 하지 않는다. */
.pick p { margin: 0; }
/* 체험으로 열린 인기마 — 테두리 색으로 "이번만" 을 말한다(카드 뱃지와 같은 초록). */
.pick.is-trial { border-color: var(--win); }
.trial-note { color: var(--text-muted); margin-top: var(--sp-2); }

/* ══ 넓은 화면 ═════════════════════════════════════════════════ */
/* 상단 메뉴는 **다 들어갈 때만** 쓴다. 720px 에서는 브랜드+메뉴 5개+회원명이
   넘쳐 오른쪽이 잘렸다(개발메모 UX디자인 피드백). 900px 부터로 올리고,
   그 아래는 계속 하단 탭이 맡는다. */
/* 내비게이션 전환 — 창을 줄여도 **상단 메뉴는 계속 보이게** 한다.
   브라우저 창을 좁힌 데스크톱에서 메뉴가 통째로 사라지는 게 문제였다.
   560px 부터는 상단 메뉴로, 그 아래(진짜 폰 폭)에서만 하단 탭으로 간다.
   라벨을 짧게 줄이고 닉네임을 숨겨 두어 560px 에도 넉넉히 들어간다. */
@media (min-width: 560px) {
  .appbar-nav { display: flex; gap: var(--sp-1); }
  .tabbar { display: none; }
  body { padding-bottom: 0; }
  .has-devbar { padding-bottom: var(--dev-h); }
  .buybar { bottom: 0; }
  .has-devbar .buybar { bottom: var(--dev-h); }
  .toasts { bottom: var(--sp-5); }

  .modal { align-items: center; padding: var(--sp-4); }
  .modal-box { border-radius: var(--radius-lg); padding-bottom: var(--sp-4); }
}

/* 상단 메뉴가 나와 있는 좁은 구간에서는 닉네임을 접는다 — 메뉴를 밀어낸다. */
@media (max-width: 860px) { .appbar-me .small { display: none; } }

/* 넓어지면 격자를 늘린다(내비게이션과는 별개 관심사라 끊어 뒀다). */
@media (min-width: 720px) {
  .race-list { grid-template-columns: repeat(2, 1fr); }
  .grid-amt { --cols: 5; }
  .podium { gap: var(--sp-3); }
  .tiles { grid-template-columns: repeat(4, 1fr); }
  .tile-hero { grid-column: span 2; }
  .menu { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .wrap { padding: var(--sp-5) var(--sp-4) var(--sp-6); }
  .hero { padding: var(--sp-6) 0; }
  .steps { grid-template-columns: repeat(3, 1fr); }
}


/* ── 경주자료(예상지) ────────────────────────────────────────
   세로 = 말 고르기 / 가로 = 시간 거슬러가기. 축을 나누면 엄지 하나로
   훑기 → 좁히기 → 파고들기가 끊기지 않는다.

   ⚠️ 가로 트랙에 **스와이프 핸들러를 두지 않는다.** CSS scroll-snap 이
      관성·고무줄·접근성까지 준다. 손으로 만든 터치 핸들러는 세로 스크롤과
      반드시 싸운다.

   ⚠️ **`touch-action: pan-x` 를 걸면 안 된다**(2026-08-23 되돌림). 그러면 트랙 위에서
      세로로 쓸 때 **아무 일도 일어나지 않는다** — 트랙 자체는 세로 여유가 0 인데
      페이지는 수천 px 가 남아 있어, 손가락이 트랙에 얹히는 순간 갇힌다.
      '모두 펼치기' 로 12두가 늘어서면 화면 대부분이 트랙이라 더 심하다.
      브라우저는 제스처가 시작되면 **우세한 축으로 알아서 잠근다**. 가로 스와이프는
      그대로 되고 세로는 페이지로 넘어간다 — 막을 필요가 없었다. */
#program-list { display: flex; flex-direction: column; gap: 8px; }

.pg-row, .pg-hd {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface);
}
.pg-hd { border: 0; border-radius: 0; background: var(--gold-tint); }
.pg-nm { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis;
          white-space: nowrap; }
/* 단승 지급율 — 마필정보에서 옮겨 온 칸. 등급 색은 배당판과 같은 것을 쓴다. */
.pg-od { font-family: var(--font-mono); font-size: .82rem; font-weight: 600;
         min-width: 3.2em; text-align: right; flex: 0 0 auto; }
/* 갈매기 — 이 줄이 펴진다는 신호. 없으면 아무도 누르지 않는다. */
.pg-chev { color: var(--text-dim); font-size: .9rem; line-height: 1; flex: 0 0 auto;
           transition: color .12s ease; }
.pg-chev.is-open { color: var(--gold); }
.pg-row:hover .pg-chev { color: var(--text); }
.pg-rec { margin-left: auto; font-family: var(--font-mono); font-size: .82rem;
          color: var(--text-muted); white-space: nowrap; }
.pg-open { border: 1px solid var(--gold); border-radius: 10px; overflow: hidden; }
.pg-open .pg-rec { color: var(--gold); }
.pg-in { padding: 10px 12px; display: flex; flex-direction: column; gap: 10px; }

.pg-spec { display: flex; flex-direction: column; gap: 3px;
           font-family: var(--font-mono); font-size: .82rem; }
.pg-spec > div { display: flex; gap: 8px; }
.pg-spec .k { color: var(--text-dim); min-width: 3.2em; font-family: var(--font-sans); }
.pg-spec em { font-style: normal; color: var(--track-green-text); }
/* 1년 / 통산 같은 잣대 이름 — 숫자보다 한 단 낮춰 읽는 순서를 정한다. */
.pg-spec .k2 { color: var(--text-dim); font-size: .86em; }

/* 가로 트랙 — 다음 카드를 살짝 보여야 "옆에 더 있다"를 학습한다. */
/* PC 대응 — 여기 터치가 없다.
   모바일은 스와이프가 전부지만 마우스로는 가로 스크롤이 아예 안 된다. 그래서
   이동 경로를 셋으로 둔다: **좌우 화살표 · 색상바 클릭 · 키보드 ←/→**.
   그리고 화면이 넓으면 애초에 **여러 장을 동시에** 보여 이동 자체를 줄인다. */
.pg-trackwrap { position: relative; }
.pg-track {
  display: flex; gap: 8px; overflow-x: auto;
  /* 세로는 페이지로 넘긴다(위 주석). 확대/축소도 막지 않는다. */
  touch-action: auto;
  scroll-snap-type: x mandatory; scrollbar-width: none;
  margin: 0 -12px; padding: 0 12px;
}
.pg-track:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.pg-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 1;
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--overlay);
  color: var(--text); font-size: 1rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: opacity .15s ease, background .15s ease;
}
.pg-arrow:hover { background: var(--surface-3); }
.pg-prev { left: -4px; }
.pg-next { right: -4px; }
/* 끝에 닿으면 사라진다 — 남은 방향이 곧 "더 갈 데가 있다" 는 표시다. */
.pg-arrow.is-off { opacity: 0; pointer-events: none; }
.pg-track::-webkit-scrollbar { display: none; }
.pg-slide {
  /* `flex-basis` 만으로는 안 된다 — 내용의 min-content 가 더 넓으면 그쪽으로
     밀려 다음 카드가 안 보인다. `min-width:0` 로 그 바닥을 풀어 준다. */
  flex: 0 0 auto; width: 86%; min-width: 0; scroll-snap-align: center;
  background: var(--surface-2); border: 1px solid var(--line-strong);
  border-radius: 10px; padding: 9px 10px;
  display: flex; flex-direction: column; gap: 7px;
}
/* 헤더는 **한 줄**이다. 줄바꿈을 허용하면 4장을 넘길 때 카드 높이가 들쭉날쭉해
   본문이 위아래로 흔들린다. 좁으면 뒤쪽 조건이 잘린다. */
.pg-sh { display: flex; align-items: baseline; gap: 6px; flex-wrap: nowrap;
         white-space: nowrap; overflow: hidden;
         font-family: var(--font-mono); font-size: .72rem; color: var(--text-muted); }
.pg-sh .pg-cond { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pg-sh b { color: var(--text); font-size: .8rem; }
.pg-cond { color: var(--text-dim); }
/* 등급 + 거리 — 그 경주가 어떤 판이었나. 날짜 다음으로 먼저 읽혀야 한다. */
.pg-cls { color: var(--text); font-weight: 600; }
/* 주로빠르기 동그라미 — 헤더가 .72rem 인데 ⓪①② 글리프는 같은 크기에서도 유독
   작게 보인다(글자틀 안에 원을 그리느라 여백이 크다). 한 단계 키우고 앞을 한 칸
   띄운다. `line-height:1` 로 잡아 헤더 한 줄 높이는 그대로 둔다. */
.pg-tk { font-size: 1.25em; line-height: 1; }

/* 슬라이드 번호 — 문장 대신 번호 + 고유색. 하단 막대가 같은 색이라
   위치가 두 군데서 읽힌다. */
.pg-sn { display: inline-flex; align-items: center; justify-content: center;
         width: 18px; height: 18px; border-radius: 5px; flex: 0 0 auto;
         font-family: var(--font-mono); font-size: .72rem; font-weight: 700;
         color: var(--text-on-gold); }
.sn-1 { background: var(--gold); }
.sn-2 { background: var(--pool-1); }
.sn-3 { background: var(--pool-2); }
.sn-4 { background: var(--pool-3); }
/* 색상바 = 슬라이드 바로가기. 지금 보고 있는 칸만 굵어진다. */
.pg-dots { display: flex; gap: 6px; justify-content: center; }
.pg-dot {
  width: 22px; height: 5px; border-radius: 3px; border: 0; padding: 0;
  cursor: pointer; opacity: .45; transition: opacity .15s ease, height .15s ease;
}
.pg-dot:hover { opacity: .8; }
.pg-dot.is-on { opacity: 1; height: 7px; }
.pg-dot:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.pg-fin { display: flex; flex-direction: column; gap: 3px;
          font-family: var(--font-mono); font-size: .72rem; }
.pg-f { display: flex; gap: 6px; align-items: baseline; border-radius: 4px;
        padding: 1px 3px; margin: 0 -3px; }
.pg-p  { color: var(--text-dim); width: 1.6em; text-align: right; flex: 0 0 auto; }
.pg-mb { color: var(--text-dim); width: 1.6em; text-align: right; flex: 0 0 auto; }
.pg-h  { flex: 1; min-width: 0; color: var(--text-muted); white-space: nowrap;
         overflow: hidden; text-overflow: ellipsis; }
.pg-g  { width: 3.6em; text-align: right; color: var(--text); flex: 0 0 auto; }
.pg-w  { width: 4.2em; text-align: right; color: var(--text-dim); flex: 0 0 auto; }
.pg-j  { width: 4.4em; text-align: right; color: var(--text-dim); flex: 0 0 auto; }
.pg-f.is-me { background: var(--gold-tint); }
.pg-f.is-me .pg-p, .pg-f.is-me .pg-h, .pg-f.is-me .pg-g { color: var(--gold); font-weight: 600; }
/* 직접대결 — 밑줄로 먼저 눈에 걸리고, 배지가 오늘 몇 번인지 말해 준다. */
.pg-f.is-vs .pg-h { color: var(--track-green-text);
  text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1.5px; }
.pg-vs { background: var(--track-green-tint); color: var(--track-green-text);
         border-radius: 3px; padding: 0 4px; margin-left: 4px;
         font-size: .64rem; font-weight: 700; }
.pg-sum { display: flex; gap: 6px; flex-wrap: wrap; border-top: 1px solid var(--line);
          padding-top: 5px; font-family: var(--font-mono); font-size: .72rem;
          color: var(--text-muted); }
.pg-sum b { color: var(--gold); }

/* 기록 모아보기 — 해당거리·초반·중반·종반 Top 5 */
.pg-rank { margin-top: 6px; border: 1px solid var(--line); border-radius: 10px;
           background: var(--surface); padding: 12px;
           display: flex; flex-direction: column; gap: 12px; }
.pg-rank-h { font-weight: 600; }
.pg-t5 { display: flex; flex-direction: column; gap: 4px; }
.pg-t5h { display: flex; gap: 8px; align-items: baseline;
          font-size: .82rem; color: var(--text-muted); }
.pg-t5h .muted { margin-left: auto; font-family: var(--font-mono); font-size: .72rem; }
.pg-t5r { display: flex; align-items: center; gap: 8px; padding: 5px 8px;
          border-radius: 6px; background: var(--surface-2);
          font-family: var(--font-mono); font-size: .78rem; }
.pg-t5r.is-top { background: var(--gold-tint); }
.pg-rk { color: var(--text-dim); width: 1em; flex: 0 0 auto; }
.pg-t5r.is-top .pg-rk { color: var(--gold); font-weight: 700; }
.pg-t5n { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
          white-space: nowrap; font-family: var(--font-sans); }
.pg-t5v { color: var(--text); font-weight: 600; flex: 0 0 auto; }


/* 마체중 증감 — 색이 먼저 말한다. 0 이상 빨강(불었다) / 미만 파랑(빠졌다).
   숫자를 읽기 전에 방향이 잡혀야 12두를 훑을 수 있다. */
.wt-up   { color: var(--danger); }
.wt-down { color: var(--pool-2); }


/* 경주자료 — 넓은 화면에서는 슬라이드를 고정폭으로 두어 **여러 장을 한꺼번에**
   보여준다. `--wrap: 960px` 기준으로 트랙이 약 928px 라 300px 슬라이드가 3장
   들어온다. 이동해야 할 일 자체가 줄어드는 것이 PC 대응의 본체이고,
   화살표·색상바는 남는 한 장을 위한 보조다. */
@media (min-width: 700px) {
  .pg-slide { width: 300px; }
  .pg-arrow { width: 34px; height: 34px; }
}
/* 마우스가 있는 환경에서만 화살표를 상시 노출한다. 터치에서는 스와이프가
   먼저이고, 화살표는 손가락이 가리는 자리에 놓인다. */
@media (hover: none) {
  .pg-arrow { opacity: .35; }
  .pg-arrow.is-off { opacity: 0; }
}


/* 경주자료 상단 스위치 — '경주 펼치기 / 접기'.
   표기는 **상태가 아니라 누르면 일어날 일**이다('경주 접기' = 눌러서 접는다).
   목록 위 오른쪽에 둔다 — 훑다가 "다 펴서 비교하고 싶다" 가 되는 자리다. */
.pg-bar { display: flex; justify-content: flex-end; margin-bottom: var(--sp-2); }
.pg-toggle {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--line-strong); background: var(--surface);
  color: var(--text-muted); font-size: var(--fs-sm); font-family: inherit;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
.pg-toggle:hover { color: var(--text); border-color: var(--text-dim); }
.pg-toggle.is-on {
  background: var(--gold-tint); border-color: var(--gold); color: var(--gold);
  font-weight: 600;
}
.pg-toggle .pg-tico { font-size: .9rem; line-height: 1; }
.pg-toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }


/* 주로빠르기 · SI — **기록을 읽는 잣대**다. 같은 1:26.8 도 주로가 빠른 날이면
   덜 좋은 기록이라, 기록 옆에서 눈에 걸려야 뜻이 산다.
   하단 줄의 **오른쪽 끝**에 붙인다(`margin-left:auto`) — 기록·구간·마체중은 그 말이
   어떻게 달렸나이고, 이 둘은 그것을 재는 잣대라 한 덩이로 떨어져 있어야 읽힌다.
   ⚠️ `주로빠르기=0` 은 주행심사(측정 없음)라 화면이 아예 그리지 않는다 —
      '가장 느림' 으로 읽히면 안 된다. */
/* 적색은 **SI 에만**. 굵게까지 하면 기록보다 세져서 주객이 바뀐다.
   하단 줄의 **오른쪽 끝**으로 민다 — 기록·구간·마체중은 그 말이 어떻게 달렸나이고
   SI 는 그것을 재는 잣대라, 떨어져 있어야 섞여 읽히지 않는다. */
.pg-si { color: var(--danger); margin-left: auto; flex: 0 0 auto; }
