/* app.css — 레이아웃/컴포넌트. 색은 전부 theme.css 토큰(var) 참조. */

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* 배율 고정 — 핀치·더블탭 줌을 CSS 단계에서 차단한다. viewport meta 의
   user-scalable=no 를 iOS 웹뷰가 무시하는 사례가 있어 이중으로 잠근다.
   pan-x pan-y 는 스크롤만 허용하고 줌 제스처를 막는다. 자식 요소가 기본값
   auto 로 되돌리면 그 요소 위에서 핀치가 다시 열리므로 전역 * 에 건다. */
* { touch-action: pan-x pan-y; }

/* display 를 지정한 요소는 UA 의 [hidden]{display:none} 이 먹지 않는다.
   숨김은 항상 동작해야 하므로 전역으로 못박는다. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-family);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "tnum" 1;
  overscroll-behavior-y: none;
  /* OS 접근성 글꼴 확대가 텍스트만 임의 배율로 키워 레이아웃을 깨는 것을 막는다. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* 가로 원천 봉쇄 — 어떤 요소가 1px 넘쳐도 페이지는 좌우로 못 움직인다.
   넘침의 발생원(긴 베트남어·닉네임·어드민 입력)을 하나씩 쫓는 대신 축을 잠근다.
   반드시 html 에만 건다: body 에 overflow-x:hidden 을 주면 짝 규칙으로 body 의
   overflow-y 가 auto 가 되어 body 가 스크롤 컨테이너로 바뀌고, 그 순간
   position:sticky 헤더가 뷰포트가 아닌 body 기준이 되어 고정이 풀린다.
   hidden 은 구형 엔진 폴백. root 의 clip 은 명세상 뷰포트에 hidden 으로 전파돼
   제스처만 막고 JS 스크롤은 남는다 — body 의 clip 이 그 마지막 구멍을 막는다.
   clip 은 hidden 과 달리 스크롤 컨테이너를 만들지 않아 body 에 얹어도
   sticky 가 죽지 않는다(구형 엔진은 clip 을 무시하므로 부작용도 없다). */
html { overflow-x: hidden; overflow-x: clip; }
body { overflow-x: clip; }

body {
  /* 상단 인셋은 body 가 아니라 sticky 헤더가 가진다 — body padding 이면
     스크롤 시 헤더가 인셋만큼 노치·텔레그램 버튼 밑으로 밀려 올라간다. */
  padding-bottom: calc(var(--bottombar-h) + var(--tg-bottom-inset));
  padding-left: var(--tg-left-inset);
  padding-right: var(--tg-right-inset);
  min-height: 100vh;
}

button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; border: 0; background: none; }
a { color: var(--accent); text-decoration: none; }
img { max-width: 100%; }

/* ── 헤더 ───────────────────────────────────────────── */
.app-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  /* 서브 화면 제목은 텔레그램 칩 밴드(< 뒤로/✕)까지 피한다 — safe-top 만으로는
     칩과 제목이 같은 줄에 렌더돼 겹쳤다. */
  height: calc(54px + var(--tg-content-top));
  padding: var(--tg-content-top) 14px 0;
  background: var(--nav-bg);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--line-soft);
}
.app-header.is-brand {
  /* 홈 로고는 상태바만 피한다 — 칩이 로고 위에 뜨는 디자인, 위 빈 띠 방지 */
  height: calc(clamp(146px, 40vw, 184px) + var(--tg-safe-top));
  padding-top: var(--tg-safe-top);
  padding-inline: 0;
  /* iOS 웹뷰가 컴팩트→풀스크린 전환 뒤 블러 헤더를 재도장하지 않아
     로고 하단이 검게 잘렸다 — 배경이 사실상 불투명해 블러가 필요 없다. */
  backdrop-filter: none;
  background:
    radial-gradient(80% 155% at 50% 100%, rgba(var(--brand-wash-rgb, 191, 136, 28), .10), transparent 64%),
    var(--nav-bg);
}
.app-header h1 {
  flex: 1; min-width: 0; margin: 0;
  display: flex; align-items: center;
  font-size: 17px; font-weight: 700; letter-spacing: -0.01em;
}
.header-title-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.header-brand-logo {
  display: none; width: 100%; max-width: none; height: auto; object-fit: contain;
}
.app-header h1.is-brand { justify-content: center; }
.app-header h1.is-brand .header-title-text { display: none; }
.app-header h1.is-brand .header-brand-logo { display: block; }
.app-header.is-brand .header-sub { display: none; }

/* ── 브랜드 로고 발광 (공 글로우 펄스 + 79TV 글자별 순차 점등) ──
   PNG 위에 mix-blend-mode:screen 레이어를 %좌표로 얹는다 — 로고 이미지의
   3:1 비율 안에서 공(좌측 28%)과 7·9·T·V 글자 위치에 맞춰져 있다. */
/* isolation — blend 레이어를 로고 스택 안에서만 합성한다 (iOS 웹뷰 합성 버그 방지) */
.brand-glow { position: relative; display: block; isolation: isolate; }
.brand-glow > i, .brand-glow .bg-orbit { position: absolute; pointer-events: none; }
.app-header h1 .brand-glow { display: none; width: min(100%, 540px); }
.app-header h1.is-brand .brand-glow { display: block; }
.brand-glow .header-brand-logo { display: block; }
.bg-ball-glow { left: 19.5%; top: 19%; width: 17%; height: 52%; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,214,120,.75), rgba(255,150,40,.28) 55%, transparent 72%);
  mix-blend-mode: screen; animation: bgBallPulse 2.4s ease-in-out infinite; }
.bg-orbit { left: 19.5%; top: 19%; width: 17%; height: 52%; animation: bgOrbit 3.6s linear infinite; }
.bg-orbit i { position: absolute; left: 50%; top: -3px; width: 8px; height: 8px; margin-left: -4px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 8px 3px rgba(255,240,190,.95), 0 0 16px 7px rgba(255,200,90,.5);
  mix-blend-mode: screen; }
/* 글자 점등 — 사전 밝힘본(-lit.png)을 글자 영역 "창"(overflow:hidden)으로
   겹쳐 7→9→T→V 가 실제 글자 모양 그대로 파도타듯 순차 점등된다.
   clip-path/filter/blend 를 전부 피한 이유: 일부 웹뷰(iOS/텔레그램)에서
   무시되어 전체가 깜박이는 오동작이 났다 — overflow 클리핑은 어디서나 된다. */
/* 글자 점등 — 서버에서 글자별로 미리 잘라낸 스프라이트(assets/79tv-lit-*.png)를
   같은 % 박스에 얹고 opacity 만 바꾼다 (index.html 인라인 rAF 가 구동).
   창/오프셋/블렌드/클리핑 계산이 전혀 없어 어떤 웹뷰에서도 동작한다. */
.brand-glow .bg-letter { position: absolute; top: 10%; height: 64%;
  opacity: 0; pointer-events: none; }
.bg-letter-7 { left: 38%; width: 11%; }
.bg-letter-9 { left: 49%; width: 11.6%; }
.bg-letter-t { left: 60.6%; width: 12.3%; }
.bg-letter-v { left: 72.9%; width: 12.1%; }
@keyframes bgBallPulse { 0%, 100% { opacity: .16; } 50% { opacity: .85; } }
@keyframes bgOrbit { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .bg-ball-glow, .bg-orbit { animation: none; }
  .bg-ball-glow { opacity: .3; }
  .bg-orbit { display: none; }
}
.app-header .header-sub {
  font-size: 11.5px; font-weight: 600; color: var(--muted);
  letter-spacing: 0.01em;
}
.header-btn {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: var(--radius-sm);
  color: var(--muted); font-size: 18px;
  transition: background .15s, color .15s;
}
.header-btn:active { background: var(--panel2); color: var(--text); }
/* 헤더 오른쪽 「배팅하러 가기」(core.js syncHeaderCta) — 이벤트 카드의 .ev-go 와 같은 금색 알약.
   제목보다 튀지 않게 옅은 채움 + 테두리. 홈(브랜드 헤더)에서는 없다. */
.header-cta {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  height: 30px; padding: 0 11px 0 9px; margin-left: auto;
  border: 1px solid var(--accent-line, rgba(217, 180, 95, 0.32)); border-radius: 999px;
  background: var(--accent-soft, rgba(217, 180, 95, 0.13)); color: var(--accent-strong, #f0cd7d);
  font-size: 11.5px; font-weight: 800; letter-spacing: -0.01em; white-space: nowrap;
}
.header-cta:active { background: var(--accent-line, rgba(217, 180, 95, 0.32)); }
.header-cta-ic { font-size: 13px; line-height: 1; }
.header-cta-ar { font-size: 13px; opacity: .8; margin-left: -1px; }
.app-header.is-brand .header-cta { display: none; }

/* ── 뷰 컨테이너 ─────────────────────────────────────── */
#app { padding: 12px 14px 22px; }
#app.no-pad { padding: 0; }
.app-header.is-brand + #app { padding: 6px clamp(16px, 4.2vw, 28px) 20px; }

/* ── 79TV 메인 로비 ─────────────────────────────────── */
.matchday-home { display: flex; flex-direction: column; gap: clamp(11px, 3.4vw, 16px); padding: 0 0 10px; }
.lobby-card {
  position: relative; isolation: isolate; overflow: hidden; width: 100%; min-height: clamp(136px, 36vw, 166px);
  padding: clamp(16px, 4vw, 20px); text-align: left; color: var(--text); border: 1px solid var(--line);
  /* 첫 화면 카드의 모서리. 여기가 리터럴이면 어드민의 '모서리' 선택이
     유저가 처음 보는 화면에서 아무것도 안 바꾼다 — 실제로 그랬다. */
  border-radius: var(--radius-card, 19px); background: var(--panel-grad, var(--panel)); box-shadow: var(--shadow-sm);
  transition: transform .16s ease, border-color .16s ease, opacity .16s ease;
}
.lobby-card > * { position: relative; z-index: 1; }

/* 로비 카드 넉 장은 하나의 색 시스템으로 통일한다.
   **var() 폴백은 지우지 마라.** app.css 는 세 업체가 공유하는 단일 파일인데,
   이 커밋 이전에 만들어진 테마의 theme.css 에는 아래 토큰이 없다. 미정의
   var() 는 선언 **전체**를 무효로 만들고(앞선 선언으로 되돌아가지 않는다)
   그 자리는 initial 이 된다 — 카드 배경이 사라지고 테두리가 currentColor(흰색),
   모서리가 0 이 되어 흰 테두리 각진 빈 상자가 된다. 폴백 값은 오늘 운영 값이다.
   **값은 theme.css 가 준다.** 예전에는 여기 79TV 샴페인 골드가 박혀 있어서,
   어떤 강조색으로 테마를 만들어도 유저가 **처음 보는 화면** 네 장은 금색이었다.
   app.css 는 세 업체가 공유하는 단일 파일이라 여기서 색을 정하면 테마가 못 이긴다. */
.lobby-card {
  border-color: var(--lc-line, rgba(226, 184, 89, 0.43));
  background:
    radial-gradient(78% 132% at 88% 40%, var(--lc-glow, rgba(225, 181, 79, 0.15)), transparent 62%),
    radial-gradient(65% 110% at 100% 100%, var(--lc-deep, rgba(126, 85, 16, 0.30)), transparent 72%),
    linear-gradient(145deg, var(--lc-base-from, #17171a) 0%, var(--lc-base-to, #0a0a0e) 74%);
  box-shadow: var(--shadow-md);
}

/* ── 배경 일러스트 ─────────────────────────────────────────────────
   카드 오른쪽을 세로로 꽉 채운다. 왼쪽 절반은 제목·설명이 덮으므로 그쪽으로
   어두운 그라데이션을 씌워 글씨가 그림 위에서도 읽히게 한다. */
.lobby-card-art {
  position: absolute; z-index: 0; pointer-events: none;
  right: -2%; top: 0; bottom: 0; width: 66%;
  opacity: .62;
}
.lobby-card-art svg {
  width: 100%; height: 100%; display: block;
  filter: grayscale(1) sepia(.72) saturate(1.25) hue-rotate(350deg) brightness(.88);
}
/* 1안의 축구공·달력·커뮤니티·선물은 어두운 금색 질감 이미지로 고정한다.
   원래 SVG용 색상 필터를 적용하지 않아 검정 음영과 샴페인 골드가 흐려지지 않는다. */
.lobby-card-art.is-raster {
  right: -2%; overflow: hidden; opacity: .94;
  background: linear-gradient(90deg, transparent 0%, rgba(var(--bg-rgb, 10, 10, 14), .72) 50%, rgb(var(--bg-rgb, 10, 10, 14)) 78%);
}
.lobby-card-art.is-raster img {
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: right center;
  transform: translateX(-21%);
  /* 이미지의 빈 검정 영역이 카드 배경과 만나는 지점을 부드럽게 녹여
     카드 가운데에 세로 경계가 생기지 않게 한다. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 30%, #000 100%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 30%, #000 100%);
}
/* 채팅 말풍선은 위쪽으로 크게 솟아 COMMUNITY 태그를 파고든다 — 그림만 내린다
   (가림막 ::after 는 제자리에 둬서 상단 어둡게는 그대로 유지) */
.lobby-card-chat .lobby-card-art svg { transform: translateY(7%); }
.lobby-card-chat .lobby-card-art.is-raster img { transform: translateX(-21%) translateY(-8%); }
.lobby-card-event .lobby-card-art.is-raster img { transform: translateX(-21%) translateY(-22%); }
/* 글씨가 얹히는 세 방향(왼쪽=제목/설명, 위=태그, 아래=CTA)으로 그림을 눌러 준다.
   가림막 없이 두면 COMMUNITY·D-26 태그와 "이벤트 참여" 가 그림에 묻혀 안 읽힌다. */
.lobby-card-art::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(90deg, rgb(var(--bg-rgb, 10, 10, 14)) 0%, rgba(var(--bg-rgb, 10, 10, 14), .84) 34%, rgba(var(--bg-rgb, 10, 10, 14), .24) 67%, transparent 92%),
    linear-gradient(180deg, rgba(var(--bg-rgb, 10, 10, 14), .76) 0%, rgba(var(--bg-rgb, 10, 10, 14), .19) 29%, transparent 47%),
    linear-gradient(0deg, rgba(var(--bg-rgb, 10, 10, 14), .76) 0%, rgba(var(--bg-rgb, 10, 10, 14), .12) 24%, transparent 43%);
}
/* 질감 이미지에는 자체 암부와 좌측 페이드가 들어 있다. SVG 전용 가림막을 겹치면
   카드 중간에 직선 경계가 생기므로 사용하지 않는다. */
.lobby-card-art.is-raster::after { display: none; }
.lobby-card-future {
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  min-height: clamp(96px, 25vw, 114px);
  border-style: dashed; border-color: rgba(217, 180, 95, .3); background:
    radial-gradient(70% 85% at 50% 100%, rgba(217, 180, 95, .07), transparent 70%), var(--panel);
}
.lobby-card:active { transform: scale(.985); }
.lobby-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.lobby-card-kicker { display: inline-flex; align-items: center; gap: 7px; color: var(--lc-hi, var(--accent-strong)); font-size: 10.5px; font-weight: 850; letter-spacing: .11em; }
.lobby-live-dot { display: block; width: 8px; height: 8px; border-radius: 50%; background: var(--live); box-shadow: 0 0 0 4px rgba(229, 72, 77, .13); }
.home-icon { display: inline-flex; align-items: center; justify-content: center; color: var(--lc-hi, var(--accent-strong)); }
.home-icon svg { width: 100%; height: 100%; display: block; }
/* top 은 우측 상단 태그(79TV/COMMUNITY) 아래로 충분히 내린 값 —
   태그와 겹치지 않으면서 하단 CTA 와도 떨어지게 유지한다. */
/* 아이콘은 일러스트 위에 얹히므로 발광을 줘서 배경과 분리한다 */
.lobby-card .home-icon { position: absolute; right: 16px; top: 44px; width: 43px; height: 43px; opacity: .98;
  filter: drop-shadow(0 0 6px rgba(0,0,0,.85)) drop-shadow(0 0 3px currentColor); }
.lobby-card-title { display: block; max-width: 68%; margin-top: 17px; font-size: 25px; line-height: 1.05; letter-spacing: -.045em;
  text-shadow: 0 2px 10px rgba(0,0,0,.95), 0 1px 3px rgba(0,0,0,.9); }
.lobby-card-sevenm .lobby-card-title, .lobby-card-event .lobby-card-title { font-size: 20px; line-height: 1.13; }
.lobby-card-desc { display: block; max-width: 68%; margin-top: 8px; color: #b6b0a6; font-size: 11.5px; line-height: 1.4;
  word-break: keep-all; text-shadow: 0 1px 6px rgba(0,0,0,.95); }
.lobby-card-cta { position: absolute; right: 16px; bottom: 16px; color: var(--lc-hi, var(--accent-strong)); font-size: 11px; font-weight: 850;
  text-shadow: 0 1px 4px rgba(0,0,0,.9), 0 0 10px rgba(0,0,0,.7); }
.lobby-card-future .home-icon { position: static; width: 32px; height: 32px; margin-bottom: 6px; color: var(--accent); opacity: .8; }
.lobby-card-future .lobby-card-title { margin-top: 0; font-size: 17px; }
.lobby-card-future .lobby-card-desc { max-width: none; margin-top: 4px; font-size: 10.5px; }
.lobby-card.is-disabled { opacity: .5; }

@media (max-width: 355px) {
  .app-header.is-brand { padding-inline: 0; }
  .header-brand-logo { width: 100%; max-width: none; height: auto; }
  .app-header.is-brand + #app { padding: 5px 14px 14px; }
  .lobby-card { min-height: 128px; padding: 14px; }
  .lobby-card-future { min-height: 96px; }
  .lobby-card-title { margin-top: 14px; font-size: 22px; }
  .lobby-card-sevenm .lobby-card-title, .lobby-card-event .lobby-card-title { font-size: 18px; }
  .lobby-card .home-icon { right: 14px; top: 42px; width: 37px; height: 37px; }
  .lobby-card-desc { font-size: 10.5px; }
  .lobby-card-cta { right: 13px; bottom: 12px; font-size: 10px; }
  .lobby-card-future .home-icon { width: 29px; height: 29px; margin-bottom: 5px; }
  .lobby-card-future .lobby-card-title { font-size: 16px; }
}

/* ── 7M 베트남어 경기정보 (서버 파싱 → ls-* 카드 재사용) ───────────── */
.sv-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sevenm-brand { min-width: 0; }
.sevenm-brand small {
  display: block; color: var(--accent-strong); font-size: 9px; font-weight: 850;
  letter-spacing: .12em; line-height: 1.2;
}
.sevenm-brand strong {
  display: block; overflow: hidden; margin-top: 3px; color: var(--text);
  font-size: 14px; line-height: 1.25; text-overflow: ellipsis; white-space: nowrap;
}
.sevenm-action {
  display: inline-flex; align-items: center; justify-content: center; min-height: 34px;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel2); color: var(--text); font-size: 10.5px; font-weight: 750;
  white-space: nowrap;
}
.sevenm-action:active { transform: scale(.97); }
/* 리그 식별색 — 7M 데이터의 리그별 색상값 그대로. */
.sv-dot { flex: none; width: 8px; height: 8px; border-radius: 3px; background: #4a4f58; }
/* 종료 스코어는 라이브와 구분되게 차분한 톤으로. */
.ls-score.sv-done { color: var(--muted); }
.ls-score.sv-done b { color: var(--text); }
/* 퇴장 수 — 팀명 옆 작은 레드카드 칩. */
.sv-red {
  flex: none; min-width: 13px; padding: 1px 3px; border-radius: 3px;
  background: #b3121a; color: #fff; font-size: 8.5px; font-weight: 850;
  line-height: 1.3; text-align: center;
}
.sv-half { margin-top: 5px; color: var(--muted); font-size: 9.5px; text-align: center; font-variant-numeric: tabular-nums; }
.sevenm-hint { margin: 4px 0 8px; color: var(--muted); font-size: 10px; line-height: 1.4; text-align: center; }

.section-title {
  margin: 18px 0 8px;
  font-size: 11.5px; font-weight: 700; color: var(--muted);
  letter-spacing: 0.06em; text-transform: uppercase;
}
.empty {
  padding: 56px 24px; text-align: center;
  color: var(--muted); font-size: 14px; line-height: 1.75;
}
.empty .empty-icon { display: block; font-size: 32px; margin-bottom: 12px; opacity: .5; }

.spinner {
  width: 20px; height: 20px; margin: 36px auto;
  border: 2px solid var(--line); border-top-color: var(--accent);
  border-radius: 50%; animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── 필터 칩 ─────────────────────────────────────────── */
.chips {
  display: flex; gap: 6px; overflow-x: auto;
  padding: 2px 0 12px; scrollbar-width: none;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto; padding: 7px 14px; border-radius: 999px;
  background: var(--panel); border: 1px solid var(--line);
  color: var(--muted); font-size: 12.5px; font-weight: 600;
  letter-spacing: -0.005em; white-space: nowrap;
  transition: background .15s, color .15s, border-color .15s;
}
.chip.active {
  background: var(--accent-soft); border-color: var(--accent-line);
  color: var(--accent-strong);
}

/* ── 경기 카드 ───────────────────────────────────────── */
.schedule-page-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 3px 1px 12px;
}
.schedule-page-title { font-size: 20px; letter-spacing: -.04em; }
.schedule-page-date { color: var(--muted); font-size: 11px; font-weight: 650; }
.match-list { display: flex; flex-direction: column; gap: 9px; }
.match-card {
  position: relative; overflow: hidden;
  background: var(--panel-grad, var(--panel));
  border: 1px solid var(--line-soft);
  border-radius: 16px;
  padding: 14px 14px 13px;
  box-shadow: var(--shadow-sm);
}
.match-card.is-live {
  border-color: var(--accent-line);
  background:
    radial-gradient(100% 105% at 50% 115%, rgba(46, 92, 153, .40), transparent 57%),
    radial-gradient(55% 80% at 50% -15%, rgba(217, 180, 95, .14), transparent 65%),
    linear-gradient(145deg, #17181d 0%, #0b0d12 100%);
}
.match-card.is-live::after {
  content: ''; position: absolute; left: 15%; right: 15%; bottom: -20px; height: 39px;
  border: 1px solid rgba(217, 180, 95, .26); border-bottom: 0; border-radius: 50% 50% 0 0;
  box-shadow: 0 -11px 0 rgba(217, 180, 95, .025), 0 -22px 0 rgba(217, 180, 95, .02);
  pointer-events: none;
}
.match-meta {
  display: flex; align-items: center; gap: 8px; margin-bottom: 11px;
  font-size: 11.5px; color: var(--muted);
}
.match-league {
  font-weight: 700; letter-spacing: 0.03em;
  color: var(--accent); opacity: .82;
}
.match-when { margin-left: auto; font-weight: 500; letter-spacing: -0.01em; }
.badge {
  padding: 2.5px 8px; border-radius: 999px;
  font-size: 10px; font-weight: 800; letter-spacing: 0.05em;
}
.badge.live {
  background: var(--live); color: #fff;
  animation: live-pulse 1.9s ease-in-out infinite;
}
@keyframes live-pulse { 50% { opacity: .62; } }
.badge.ended { background: var(--panel2); color: var(--muted); }
.badge.canceled { background: var(--panel2); color: var(--danger); }
.badge.postponed { background: var(--panel2); color: var(--warn); }

.match-scoreboard {
  position: relative; z-index: 1; display: grid; align-items: center;
  grid-template-columns: minmax(0, 1fr) 62px minmax(0, 1fr); gap: 8px;
  min-height: 55px;
}
.match-team { min-width: 0; display: flex; align-items: center; gap: 8px; }
.match-team-away { flex-direction: row-reverse; text-align: right; }
.match-team-logo {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px 12px 9px 12px;
  background: var(--panel2); object-fit: contain;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 750; color: var(--muted);
  border: 1px solid var(--line-soft);
}
.match-team-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13.5px; font-weight: 720; letter-spacing: -.025em;
}
.match-score-center { min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.match-score {
  color: var(--text); font-size: 17px; font-weight: 850; letter-spacing: .015em;
  font-variant-numeric: tabular-nums;
}
.match-score-state { color: var(--muted); font-size: 9.5px; font-weight: 650; white-space: nowrap; }
.match-card.is-live .match-score { color: var(--accent-strong); }
.match-team.loser .match-team-name { color: var(--muted); font-weight: 600; }
.match-team.winner .match-team-name { color: var(--accent-strong); }

/* ── TV ─────────────────────────────────────────────── */
.tv-wrap { padding: 14px 14px 23px; }
.tv-page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin: 1px 1px 11px; }
.tv-page-title { display: flex; flex-direction: column; gap: 2px; }
.tv-page-title strong { font-size: 20px; line-height: 1.12; letter-spacing: -.04em; }
.tv-eyebrow { color: var(--accent); font-size: 9.5px; font-weight: 850; letter-spacing: .13em; }
.tv-channel-count { padding-bottom: 2px; color: var(--muted); font-size: 11px; font-weight: 650; }
/* width 를 반드시 못 박아야 한다. 폭이 없으면 min-height 가 16:9 비율을 타고
   최소 가로폭(196 x 16/9 = 348.44px)으로 되돌아와, 362px 미만 화면에서 페이지
   전체가 가로로 밀린다(320px 에서 42px). 높이 하한도 없앤다 — 하한이 걸리는
   순간 그 기기만 플레이어 비율이 달라진다. */
.tv-player-shell {
  position: relative; isolation: isolate; overflow: hidden;
  /* 경기 클릭 → scrollIntoView(start) 목적지 — sticky 헤더(54px+인셋)에
     플레이어가 깔리지 않게 스크롤 도착점을 헤더 아래로 내린다. */
  scroll-margin-top: calc(54px + var(--tg-content-top) + 10px);
  aspect-ratio: 16 / 9; width: 100%; min-height: 0;
  border: 1px solid var(--accent-line); border-radius: 16px;
  background:
    radial-gradient(105% 76% at 50% 113%, rgba(21, 65, 112, .80), transparent 53%),
    radial-gradient(58% 50% at 50% 4%, rgba(217, 180, 95, .16), transparent 63%),
    linear-gradient(145deg, #15171d 0%, #07080b 100%);
  box-shadow: var(--shadow-md);
}
.tv-player-shell::before {
  content: ''; position: absolute; z-index: -1; left: -8%; right: -8%; bottom: 18px; height: 74px;
  border-top: 1px solid rgba(217, 180, 95, .34); border-radius: 50% 50% 0 0;
  box-shadow: 0 -12px 0 rgba(217, 180, 95, .035), 0 -25px 0 rgba(217, 180, 95, .022);
}
.tv-player-live {
  position: absolute; z-index: 3; top: 11px; left: 11px; display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 8px; border: 1px solid rgba(255,255,255,.12); border-radius: 999px;
  background: rgba(7, 8, 11, .72); color: #fff; font-size: 9px; font-weight: 850; letter-spacing: .08em;
}
.tv-live-dot, .tv-notice-dot { display: inline-block; width: 6px; height: 6px; flex: 0 0 auto; border-radius: 50%; background: var(--live); box-shadow: 0 0 0 3px rgba(229, 72, 77, .13); }
.tv-player-caption {
  position: absolute; z-index: 3; left: 13px; right: 13px; bottom: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center;
  color: #fff; font-size: 13px; font-weight: 750; text-shadow: 0 1px 7px rgba(0,0,0,.8);
}
.tv-player-loading {
  position: absolute; z-index: 2; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px;
  color: var(--muted); font-size: 11.5px; font-weight: 600; background: rgba(8, 8, 10, .18);
}
.tv-loading-spinner { width: 25px; height: 25px; border: 2px solid rgba(217,180,95,.18); border-top-color: var(--accent); border-radius: 50%; animation: spin .7s linear infinite; }
.tv-tabs { display: flex; gap: 7px; padding: 11px 0; overflow-x: auto; scrollbar-width: none; }
.tv-tabs::-webkit-scrollbar { display: none; }
.tv-channel {
  flex: 0 0 auto; min-width: 79px; padding: 9px 13px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--muted); font-size: 11px; font-weight: 750; letter-spacing: .02em;
  transition: background .15s, border-color .15s, color .15s;
}
.tv-channel.active { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong); }
.tv-notice { display: flex; align-items: flex-start; gap: 10px; padding: 13px; border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--panel-grad, var(--panel)); }
.tv-notice-dot { margin: 5px 1px 0 2px; }
.tv-notice-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tv-notice-copy strong { font-size: 12.5px; letter-spacing: -.02em; }
.tv-notice-copy span { color: var(--muted); font-size: 10.5px; line-height: 1.45; letter-spacing: -.02em; }
.tv-empty { padding: 64px 24px; }
.tv-frame-stage {
  position: absolute; z-index: 1; inset: 0 auto auto 0; width: 100%; height: 100%;
  transform-origin: top left;
}
.tv-frame {
  position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; border: 0; display: block;
  background: var(--panel); opacity: 0; transition: opacity .18s ease;
}
.tv-player-shell.is-ready .tv-frame { opacity: 1; }
.tv-player-shell.has-error .tv-frame { display: none; }
/* 높이 신호 없는 문서형 임베드(예: arena/tv_test.html) — 세로형 + 내부 스크롤 */
.tv-player-shell.is-page { aspect-ratio: auto; height: min(74vh, 620px); }
.tv-player-shell.is-page .tv-player-live,
.tv-player-shell.is-page .tv-player-caption { display: none; }

/* ── 자체 경기 목록 + HLS 플레이어 (베트남 스펙) ───────── */
.tv-video {
  position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%;
  display: block; background: #000; object-fit: contain;
}
/* 경기를 고르기 전에는 LIVE 뱃지를 숨긴다 — 아직 재생 중인 게 없다. */
.tv-player-shell.is-list:not(.is-ready) .tv-player-live { display: none; }
/* 대기 화면은 스피너 대신 재생 아이콘 — 도는 스피너는 "로딩 중"으로 읽힌다. */
.tv-player-shell.is-idle .tv-loading-spinner {
  position: relative; width: 52px; height: 52px; animation: none;
  border: 1.5px solid var(--accent-line); background: rgba(217, 180, 95, .07);
}
.tv-player-shell.is-idle .tv-loading-spinner::after {
  content: ''; position: absolute; left: 54%; top: 50%; transform: translate(-50%, -50%);
  border-left: 15px solid var(--accent); border-top: 9px solid transparent; border-bottom: 9px solid transparent;
}
.tv-player-shell.is-idle .tv-loading-copy { font-size: 12.5px; color: var(--text); opacity: .82; }
.tv-player-shell.is-list.is-ready .tv-player-caption {
  background: linear-gradient(180deg, transparent, rgba(7, 8, 11, .82));
  padding: 18px 10px 6px; border-radius: 0 0 15px 15px; left: 0; right: 0; bottom: 0;
}

/* 종목 필터 — 가로 스크롤 칩. 재생 가능한 경기가 많은 종목이 앞에 온다. */
.tv-filters {
  display: flex; gap: 7px; padding: 12px 0 3px;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.tv-filters::-webkit-scrollbar { display: none; }
.tv-filter {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 11px 7px 9px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--muted);
  font-size: 11.5px; font-weight: 750; letter-spacing: -.01em; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s, transform .12s;
}
.tv-filter:active { transform: scale(.97); }
.tv-filter.active {
  border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong);
  box-shadow: var(--glow);
}
.tv-filter-icon { font-size: 13px; line-height: 1; }
.tv-filter-count {
  min-width: 18px; padding: 1px 5px; border-radius: 999px;
  background: var(--panel2); color: var(--muted);
  font-size: 10px; font-weight: 800; text-align: center; font-variant-numeric: tabular-nums;
}
.tv-filter-count.has-live { background: rgba(229, 72, 77, .16); color: #ff8b8f; }
.tv-filter.active .tv-filter-count { background: rgba(217, 180, 95, .18); color: var(--accent-strong); }

/* 구역 머리 — 지금 볼 수 있는 경기 / 예정 */
.tv-section {
  display: flex; align-items: center; gap: 7px; padding: 14px 2px 7px;
  color: var(--muted); font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
.tv-section::after { content: ''; flex: 1; height: 1px; background: var(--line-soft); }
.tv-section.is-live .tv-section-title { color: var(--live); }
.tv-section-count {
  order: 3; padding: 1px 7px; border-radius: 999px; background: var(--panel2);
  font-size: 10px; font-variant-numeric: tabular-nums; letter-spacing: 0;
}

.tv-matchlist { display: flex; flex-direction: column; gap: 8px; padding-bottom: 4px; }
.tv-match {
  position: relative; display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 11px 12px; text-align: left; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius-md);
  background: var(--panel-grad, var(--panel)); color: var(--text);
  transition: border-color .15s, transform .12s, box-shadow .15s;
}
.tv-match:active { transform: scale(.99); }
/* 재생 가능한 경기만 왼쪽에 금색 띠가 선다 — 목록에서 눈이 먼저 가는 지점. */
.tv-match.is-live::before {
  content: ''; position: absolute; left: 0; top: 10px; bottom: 10px; width: 3px;
  border-radius: 0 3px 3px 0; background: linear-gradient(180deg, var(--accent-strong), var(--accent));
}
.tv-match.is-live { border-color: var(--accent-line); }
.tv-match.active {
  border-color: var(--accent-strong);
  box-shadow: var(--glow), 0 6px 20px rgba(0, 0, 0, .45);
}
.tv-match:not(.is-live) { opacity: .58; }
.tv-match-icon {
  flex: 0 0 auto; display: grid; place-items: center; width: 34px; height: 34px;
  border: 1px solid var(--line-soft); border-radius: 11px;
  background: var(--card-canvas, var(--panel2)); font-size: 16px; line-height: 1;
}
.tv-match-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.tv-match-top { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: 10.5px; font-weight: 750; }
.tv-match-league {
  max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--accent-strong); letter-spacing: .03em; text-transform: uppercase;
}
.tv-match-time { color: var(--muted); font-variant-numeric: tabular-nums; }
/* 1fr 두 칸으로 나누면 긴 팀명이 짧은 쪽과 같은 폭에 갇혀 먼저 잘린다.
   auto 로 두면 긴 이름이 남는 공간을 먼저 가져간다. */
.tv-match-teams {
  display: grid; grid-template-columns: minmax(0, auto) auto minmax(0, auto);
  justify-content: space-between; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 750; letter-spacing: -.02em;
}
.tv-match-teams.is-single { grid-template-columns: 1fr; }
.tv-team { display: flex; align-items: center; gap: 6px; min-width: 0; }
.tv-team.is-end { justify-content: flex-end; }
.tv-team.is-end .tv-team-logo { order: 2; }
.tv-team-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 로고는 api-sports 원본(투명 PNG)이라 어두운 배경에서 그대로 잘 보인다. */
.tv-team-logo { width: 18px; height: 18px; flex: 0 0 auto; object-fit: contain; }
.tv-vs { color: var(--muted); font-size: 9.5px; font-weight: 850; letter-spacing: .06em; opacity: .75; }
/* 재생 표시는 윗줄 오른쪽 — 팀명 줄이 카드 폭을 온전히 쓴다. */
.tv-match-cta {
  margin-left: auto; flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: 999px;
  background: rgba(229, 72, 77, .14); color: #ff8b8f;
  font-size: 10px; font-weight: 850; letter-spacing: .02em; white-space: nowrap;
}
.tv-match.active .tv-match-cta { background: var(--accent-soft); color: var(--accent-strong); }
.tv-match-empty { padding: 30px 12px; text-align: center; color: var(--muted); font-size: 12px; }

/* ── 채팅: 대화 ─────────────────────────────────────── */
.chat-view { display: flex; flex-direction: column; height: 100%; }
.pin-banner {
  position: sticky; top: calc(54px + var(--tg-content-top)); z-index: 15;
  display: flex; align-items: center; gap: 8px;
  padding: 9px 14px;
  background: var(--panel2); border-bottom: 1px solid var(--line);
  font-size: 12.5px; color: var(--muted);
}
.pin-banner .pin-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.msg-list { padding: 12px 14px 6px; display: flex; flex-direction: column; gap: 9px; }
.day-divider {
  align-self: center; margin: 12px 0 6px; padding: 3.5px 13px;
  background: var(--panel2); border: 1px solid var(--line-soft);
  border-radius: 999px; font-size: 11px; font-weight: 600; color: var(--muted);
  letter-spacing: 0.01em;
}
.sys-msg {
  align-self: center; max-width: 84%; text-align: center;
  font-size: 11.5px; color: var(--muted); padding: 4px 0; letter-spacing: -0.005em;
}

.msg { display: flex; gap: 8px; max-width: 84%; }
.msg.mine { align-self: flex-end; flex-direction: row-reverse; }
.msg-avatar {
  flex: 0 0 auto; width: 31px; height: 31px; border-radius: 50%;
  background: var(--panel2); color: var(--muted); object-fit: cover;
  border: 1px solid var(--line-soft);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
}
.msg-main { min-width: 0; }
.msg-nick {
  font-size: 11.5px; color: var(--muted); margin-bottom: 4px;
  font-weight: 600; letter-spacing: -0.005em;
}
.msg-nick .mgr { color: var(--accent); }
.bubble {
  padding: 9px 12px; border-radius: var(--radius-md);
  background: var(--bubble-other); color: var(--bubble-other-text);
  border: 1px solid var(--line-soft);
  font-size: 14.5px; letter-spacing: -0.012em;
  word-break: break-word; white-space: pre-wrap;
}
.msg.mine .bubble {
  background: var(--bubble-mine); color: var(--bubble-mine-text);
  border-color: transparent; font-weight: 550;
}
.bubble.pending { opacity: .5; }
.bubble .reply-quote {
  display: block; margin: -3px -5px 7px; padding: 6px 9px;
  border-left: 3px solid var(--accent); background: rgba(0, 0, 0, .2);
  border-radius: var(--radius-sm); font-size: 12.5px; opacity: .9;
}
.bubble .reply-quote .rq-nick { font-weight: 700; display: block; }
.bubble img.msg-img {
  display: block; margin-top: 5px;
  border-radius: var(--radius-sm); max-height: 260px;
}
.msg-foot {
  display: flex; gap: 6px; margin-top: 4px;
  font-size: 10.5px; color: var(--muted); letter-spacing: 0.01em;
}
.msg.mine .msg-foot { justify-content: flex-end; }
.msg-like { font-weight: 700; }
.msg-like.liked { color: var(--danger); }

.typing-line { padding: 0 14px 6px; font-size: 11.5px; color: var(--muted); height: 18px; }

/* 입력창 */
.composer {
  position: fixed; left: var(--tg-left-inset); right: var(--tg-right-inset);
  bottom: calc(var(--bottombar-h) + var(--tg-bottom-inset));
  display: flex; align-items: flex-end; gap: 8px;
  padding: 9px 12px;
  background: var(--nav-bg); backdrop-filter: blur(16px);
  border-top: 1px solid var(--line-soft);
}
.composer textarea {
  flex: 1; max-height: 96px; min-height: 40px; padding: 10px 14px; resize: none;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius-lg); color: var(--text); outline: none;
  font-size: 14.5px; letter-spacing: -0.012em;
  transition: border-color .15s;
}
.composer textarea:focus { border-color: var(--accent-line); }
.composer .icon-btn {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%;
  background: var(--panel); border: 1px solid var(--line-soft);
  color: var(--muted);
  display: flex; align-items: center; justify-content: center; font-size: 16px;
}
.composer .send-btn {
  background: var(--accent); border-color: transparent;
  color: var(--accent-on); font-weight: 800; font-size: 17px;
  box-shadow: var(--glow);
}
.composer .send-btn:disabled { opacity: .4; }
.reply-bar {
  position: fixed; left: var(--tg-left-inset); right: var(--tg-right-inset);
  bottom: calc(var(--bottombar-h) + var(--tg-bottom-inset) + 58px);
  display: flex; align-items: center; gap: 8px; padding: 7px 14px;
  background: var(--panel2); border-top: 1px solid var(--line);
  font-size: 12.5px;
}
.reply-bar .rb-text {
  flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--muted);
}
.chat-pad { height: 64px; }

/* ── 하단 내비 ───────────────────────────────────────── */
.bottom-nav {
  position: fixed; left: var(--tg-left-inset); right: var(--tg-right-inset); bottom: 0; z-index: 30;
  display: flex;
  height: calc(var(--bottombar-h) + var(--tg-bottom-inset));
  padding-bottom: var(--tg-bottom-inset);
  background:
    radial-gradient(68% 135% at 50% 0%, rgba(202, 152, 48, .12), transparent 62%),
    var(--nav-bg);
  backdrop-filter: blur(16px);
  border-top: 1px solid var(--line-soft);
  border-radius: 22px 22px 0 0;
}
.nav-item {
  position: relative;
  flex: 1; min-width: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 3px;
  color: var(--muted); font-size: 10.5px; font-weight: 600;
  letter-spacing: -0.01em;
  transition: color .15s;
}
.nav-item .nav-icon { width: 20px; height: 20px; line-height: 1; }
/* 'THÔNG TIN TRẬN' 같은 긴 라벨이 좁은 화면에서 두 줄로 꺾여 탭 높이를 흔들지 않게. */
.nav-item > span { white-space: nowrap; }
.nav-svg { display: block; }
.nav-item.active { color: var(--nav-active); }
.nav-item.active::before {
  content: ''; position: absolute; top: 0; left: 50%;
  width: 26px; height: 2px; margin-left: -13px;
  background: var(--accent); border-radius: 0 0 2px 2px;
}
.lobby-bottom-nav .nav-item { flex: 1 1 0; }
.lobby-bottom-nav .nav-item:first-child { color: var(--accent-strong); }
.nav-menu-placeholder:active { color: var(--accent-strong); }
.nav-invite-fab {
  z-index: 1; isolation: isolate; align-self: flex-start; height: 92px; min-width: 0;
  justify-content: flex-start; padding: 0; transform: translateY(-24px);
}
.nav-invite-fab::before {
  content: ''; position: absolute; z-index: 0; top: 0; left: 50%; width: 88px; height: 88px;
  transform: translateX(-50%); border: 1px solid #f5d77a; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 50% 35%, #fbecac 0%, #d9ae4c 51%, #7f5010 100%);
  box-shadow:
    0 9px 16px rgba(0,0,0,.52),
    0 0 0 2px rgba(15, 12, 5, .92),
    0 0 0 3px rgba(235, 196, 89, .26);
}
.nav-fab-icon {
  position: relative; z-index: 1; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; width: 78px; height: 78px; margin-top: 5px; border: 2px solid #ffdf82; border-radius: 50%; color: var(--accent-on);
  background:
    radial-gradient(circle at 32% 23%, rgba(255,255,255,.78) 0%, rgba(255,255,255,.18) 15%, transparent 35%),
    radial-gradient(circle at 68% 79%, #bc811c 0%, #d6aa49 40%, #f2d27c 76%, #ffe5a0 100%);
  box-shadow:
    0 5px 9px rgba(0,0,0,.34),
    0 0 0 1px rgba(120, 82, 12, .74),
    inset 0 2px 0 rgba(255,255,255,.52),
    inset 0 -5px 7px rgba(121, 83, 18, .20);
  transition: transform .15s ease;
}
.nav-fab-icon::after {
  content: ''; position: absolute; z-index: 0; inset: 5px; border: 1px solid rgba(91, 61, 11, .55); border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.18);
}
.nav-fab-icon svg { position: relative; z-index: 1; width: 26px; height: 26px; margin-top: 1px; }
.nav-fab-label { position: relative; z-index: 1; color: var(--accent-on); font-size: 9.5px; font-weight: 900; line-height: 1; white-space: nowrap; letter-spacing: -.045em; }
.nav-invite-fab:active .nav-fab-icon { transform: scale(.94); }

@media (max-width: 355px) {
  .nav-item { font-size: 9.5px; }
  .nav-item .nav-icon { width: 18px; height: 18px; }
  .nav-invite-fab { height: 84px; transform: translateY(-20px); }
  .nav-invite-fab::before { width: 80px; height: 80px; }
  .nav-fab-icon { width: 71px; height: 71px; margin-top: 4px; }
  .nav-fab-icon svg { width: 24px; height: 24px; }
  .nav-fab-label { font-size: 8.8px; }
}

/* ── 모달 ───────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0 var(--tg-right-inset) 0 var(--tg-left-inset); z-index: 60;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(0, 0, 0, .62); backdrop-filter: blur(3px);
}
.modal {
  width: 100%; max-width: 460px;
  background: var(--panel);
  border-top: 1px solid var(--line);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 22px 18px calc(22px + var(--tg-bottom-inset));
  box-shadow: var(--shadow-md);
  animation: sheet-up .2s cubic-bezier(.22,.9,.35,1);
}
@keyframes sheet-up { from { transform: translateY(18px); opacity: .5; } }

/* ── 프로필 사진 고르기 시트 (광고형·고급형) ──────────────────────
   히어로 8종 격자 + 「📷 사진 올리기」 + 「기본으로 되돌리기」. 마이페이지·초대
   모달이 같이 쓰므로 .mp- 가 아니라 .av- 다. 초대 모달(z-index 60) 위에 열린다.
   320px 폰: 4 칸 × 56px + 간격 3 × 10px + 좌우 18px 여백 = 296px < 320px. */
.av-sheet-backdrop {
  position: fixed; inset: 0 var(--tg-right-inset) 0 var(--tg-left-inset); z-index: 70;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(0, 0, 0, .62); backdrop-filter: blur(3px);
}
.av-sheet {
  width: 100%; max-width: 460px; box-sizing: border-box;
  background: var(--panel-grad, var(--panel));
  border-top: 1px solid var(--accent-line, var(--line));
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 16px 18px calc(20px + var(--tg-bottom-inset, 0px));
  box-shadow: var(--shadow-md);
  animation: sheet-up .2s cubic-bezier(.22,.9,.35,1);
}
.av-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.av-title { margin: 0; font-size: 17px; font-weight: 850; letter-spacing: -.02em; color: var(--text); }
.av-close { width: 32px; height: 32px; border: 0; border-radius: 50%; background: var(--panel2, rgba(255,255,255,.06));
  color: var(--muted); font-size: 15px; line-height: 1; cursor: pointer; }
.av-grid { display: grid; grid-template-columns: repeat(4, 56px); justify-content: space-between; gap: 12px 10px; }
.av-item { width: 56px; height: 56px; padding: 0; border: 2px solid transparent; border-radius: 50%; overflow: hidden;
  background: var(--panel2, #1e1e23); cursor: pointer; box-shadow: 0 3px 10px rgba(0,0,0,.28);
  transition: transform .12s, box-shadow .12s, border-color .12s; }
.av-item img { width: 100%; height: 100%; display: block; object-fit: cover; pointer-events: none; }
.av-item:active { transform: scale(.94); }
/* 지금 얼굴 — 강조색 링. */
.av-item.on { border-color: var(--accent-strong, #f0cd7d);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb, 217, 180, 95), .28), 0 3px 10px rgba(0,0,0,.28); }
.av-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.av-action { width: 100%; padding: 12px 14px; border-radius: var(--radius-sm, 12px); font: inherit; font-size: 14px; font-weight: 800;
  cursor: pointer; }
.av-upload { border: 1px solid var(--accent-line, rgba(217, 180, 95, 0.32)); background: var(--accent-soft, rgba(217, 180, 95, 0.13));
  color: var(--accent-strong, #f0cd7d); }
.av-reset { border: 1px solid var(--line); background: transparent; color: var(--muted); font-weight: 700; }
.av-action:active { opacity: .8; }
.modal h2 { margin: 0 0 7px; font-size: 18px; letter-spacing: -0.02em; }
.modal p.modal-desc {
  margin: 0 0 18px; font-size: 13px; color: var(--muted); line-height: 1.65;
}
.modal .field { margin-bottom: 12px; }
.modal label {
  display: block; margin-bottom: 7px;
  font-size: 11.5px; color: var(--muted); font-weight: 700;
  letter-spacing: 0.03em; text-transform: uppercase;
}
.modal input[type="text"], .modal textarea {
  width: 100%; padding: 11px 13px;
  background: var(--panel2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); color: var(--text); outline: none;
  font-size: 14px;
}
.modal input:focus, .modal textarea:focus { border-color: var(--accent-line); }
.modal .btn-row { display: flex; gap: 8px; margin-top: 18px; }
.btn {
  flex: 1; padding: 13px; border-radius: var(--radius-md);
  background: var(--panel2); border: 1px solid var(--line-soft);
  color: var(--text); font-weight: 700; font-size: 14px;
  letter-spacing: -0.01em; text-align: center;
}
.btn.primary {
  background: var(--accent); border-color: transparent;
  color: var(--accent-on); box-shadow: var(--glow);
}
.btn:disabled { opacity: .5; }

/* ── 친구초대 미니 마이페이지 ─────────────────────────── */
.invite-modal-backdrop { align-items: flex-end; }
.invite-modal {
  width: 100%; max-width: 500px; max-height: calc(100dvh - var(--tg-top-inset)); overflow-y: auto;
  padding: 10px 16px calc(24px + var(--tg-bottom-inset));
  background:
    radial-gradient(115% 45% at 50% 0%, rgba(217,180,95,.13), transparent 54%),
    linear-gradient(180deg, #111116 0%, #08090d 44%, #0b0c10 100%);
  border-color: rgba(217,180,95,.35); border-radius: 24px 24px 0 0;
  scrollbar-width: none;
}
.invite-modal::-webkit-scrollbar { display: none; }
.invite-modal-top { display: flex; align-items: center; justify-content: space-between; min-height: 28px; }
.invite-modal-top > span { color: var(--accent-strong); font-size: 9px; font-weight: 850; letter-spacing: .16em; }
.invite-close-btn {
  display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  border: 1px solid var(--line); border-radius: 50%; color: var(--muted); font-size: 22px; line-height: 1;
}
.invite-close-btn:active { color: var(--accent-strong); border-color: var(--accent-line); }
.invite-brand-lockup { display: flex; justify-content: center; margin: 2px 0 1px; }
.invite-brand-lockup .brand-glow { width: min(310px, 80vw); }
/* :not(.bg-letter) 필수 — 점등 글자는 % 폭 스프라이트라 width:100% 를 물려주면
   로고 전체 폭으로 커져 모달 오른쪽으로 넘친다(가로 빈 공간의 원인이었다). */
.invite-brand-lockup img:not(.bg-letter) { display: block; width: 100%; height: auto; object-fit: contain; }
.invite-heading { margin: -3px 0 12px; text-align: center; }
.invite-heading p { margin: 0 0 2px; color: var(--accent-strong); font-size: 9px; font-weight: 850; letter-spacing: .14em; }
.invite-heading h2 { margin: 0; font-size: 25px; line-height: 1.12; letter-spacing: -.045em; }
.invite-heading > span { display: block; margin-top: 4px; color: var(--muted); font-size: 11px; }
.invite-profile-card {
  display: flex; align-items: center; gap: 11px; padding: 12px;
  border: 1px solid var(--accent-line); border-radius: 17px;
  background: linear-gradient(125deg, rgba(217,180,95,.13), rgba(255,255,255,.018) 50%, rgba(11,31,61,.24));
}
.invite-profile-avatar {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center; width: 52px; height: 52px;
  overflow: hidden; border: 2px solid var(--accent); border-radius: 50%; color: var(--accent-on); font-size: 21px; font-weight: 850;
  background:
    radial-gradient(circle at 35% 26%, rgba(255,255,255,.63), transparent 24%),
    linear-gradient(145deg, #f1d47d, #bf8020);
  box-shadow: inset 0 -4px 7px rgba(73,43,5,.25), 0 4px 12px rgba(0,0,0,.28);
}
/* 사진 자리(광고형·고급형): 사진이 들어가면 채우고, 📷 표식은 동그라미 밖 형제로 둔다(overflow:hidden). */
.invite-profile-avatar.is-editable { cursor: pointer; }
.invite-profile-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.invite-profile-card { position: relative; }
.invite-avatar-badge { position: absolute; left: 50px; top: 50px; width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 10px; line-height: 1; pointer-events: none;
  background: var(--panel2, #1e1e23); border: 1px solid var(--accent-line, rgba(217, 180, 95, 0.32)); }
.invite-profile-copy { min-width: 0; display: flex; flex: 1; flex-direction: column; }
.invite-profile-copy > span { color: var(--accent-strong); font-size: 10px; font-weight: 750; letter-spacing: .08em; }
.invite-profile-copy strong { overflow: hidden; margin-top: 2px; color: var(--text); font-size: 19px; letter-spacing: -.04em; text-overflow: ellipsis; white-space: nowrap; }
.invite-nickname-btn {
  flex: 0 0 auto; padding: 7px 9px; border: 1px solid var(--accent-line); border-radius: var(--radius-sm);
  color: var(--accent-strong); font-size: 10px; font-weight: 750;
}
.invite-stat-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; margin-top: 9px; }
.invite-stat-card {
  min-width: 0; padding: 11px 5px 10px; text-align: center; border: 1px solid var(--line-soft); border-radius: 13px;
  background: linear-gradient(145deg, rgba(255,255,255,.035), rgba(255,255,255,.012));
}
.invite-stat-card span { display: block; overflow: hidden; color: var(--muted); font-size: 9.5px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
.invite-stat-card strong { display: block; margin-top: 1px; color: var(--accent-strong); font-size: 22px; line-height: 1.1; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.invite-mission-card {
  display: grid; grid-template-columns: 46px minmax(0, 1fr); column-gap: 11px; row-gap: 8px; margin-top: 10px; padding: 13px;
  border: 1px solid rgba(217,180,95,.36); border-radius: 17px;
  background:
    radial-gradient(75% 110% at 0% 100%, rgba(55,95,172,.18), transparent 68%),
    linear-gradient(125deg, #17161a, #0d0e12 70%);
}
.invite-mission-icon {
  display: flex; align-items: center; justify-content: center; width: 46px; height: 46px; color: var(--accent-strong);
  border: 1px solid var(--accent-line); border-radius: var(--radius-md); background: rgba(217,180,95,.07);
}
.invite-mission-icon svg { width: 30px; height: 30px; }
.invite-mission-copy { min-width: 0; display: flex; flex-direction: column; justify-content: center; }
.invite-mission-copy span { color: var(--accent-strong); font-size: 10px; font-weight: 800; letter-spacing: .08em; }
.invite-mission-copy strong { margin-top: 2px; font-size: 14px; line-height: 1.3; letter-spacing: -.035em; }
.invite-progress-row { grid-column: 1 / -1; display: flex; align-items: center; gap: 9px; }
.invite-progress { flex: 1; height: 10px; overflow: hidden; border: 1px solid rgba(217,180,95,.36); border-radius: 999px; background: #090a0d; }
.invite-progress > span { display: block; width: 0; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #b87a18, #f5d47b); box-shadow: 0 0 10px rgba(217,180,95,.5); transition: width .3s ease; }
.invite-progress-row > strong { min-width: 43px; color: var(--accent-strong); font-size: 13px; letter-spacing: -.03em; text-align: right; font-variant-numeric: tabular-nums; }
.invite-mission-status { grid-column: 1 / -1; padding: 7px 9px; border: 1px solid rgba(217,180,95,.24); border-radius: 10px; color: var(--muted); font-size: 10.5px; text-align: center; }
.invite-mission-status.is-ready { color: var(--accent-on); border-color: transparent; background: var(--accent); font-weight: 800; }
.invite-event-card {
  display: grid; grid-template-columns: 52px minmax(0, 1fr); column-gap: 11px; row-gap: 7px; margin-top: 10px; padding: 13px;
  border: 1px solid var(--line); border-radius: 17px; background: linear-gradient(145deg, #15161b, #0d0e12);
}
.invite-event-art { grid-row: span 2; display: flex; align-items: center; justify-content: center; width: 52px; min-height: 62px; color: var(--accent-strong); border-radius: 15px; background: radial-gradient(circle at 45% 28%, rgba(255,255,255,.13), transparent 35%), rgba(217,180,95,.08); }
.invite-event-art svg { width: 35px; height: 35px; }
.invite-event-copy { min-width: 0; }
.invite-event-copy > span { color: var(--accent-strong); font-size: 10px; font-weight: 800; letter-spacing: .08em; }
.invite-event-copy strong { display: block; margin-top: 2px; font-size: 14px; line-height: 1.25; letter-spacing: -.035em; }
.invite-event-copy p { margin: 4px 0 0; color: var(--muted); font-size: 10px; line-height: 1.35; }
.invite-event-btn {
  justify-self: start; padding: 6px 8px; color: var(--accent-strong); border: 1px solid var(--accent-line); border-radius: 8px;
  font-size: 10px; font-weight: 750;
}
.invite-event-btn b { margin-left: 3px; font-size: 15px; line-height: 0; }
.invite-event-details { grid-column: 1 / -1; padding: 8px 9px; color: var(--muted); border-top: 1px solid var(--line-soft); font-size: 10.5px; line-height: 1.5; }
.invite-apply-row { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 9px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.invite-apply-mine { color: var(--muted); font-size: 11px; font-weight: 650; font-variant-numeric: tabular-nums; }
.invite-apply-btn {
  padding: 9px 16px; color: var(--accent-on); border: 1px solid rgba(255,241,180,.62); border-radius: 10px;
  background: linear-gradient(135deg, #f1cf73, #bf7d18); font-size: 12px; font-weight: 850; letter-spacing: -.02em;
}
.invite-apply-btn:disabled { opacity: .45; }
.invite-apply-btn:active:not(:disabled) { transform: scale(.97); }
.invite-share-button {
  display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; margin-top: 11px; padding: 14px 12px;
  color: var(--accent-on); border: 1px solid rgba(255,241,180,.62); border-radius: var(--radius-md);
  background: linear-gradient(135deg, #f1cf73, #bf7d18); box-shadow: var(--glow); font-size: 15px; font-weight: 850; letter-spacing: -.03em;
}
.invite-share-button svg { width: 21px; height: 21px; }
.invite-share-button:active { transform: scale(.985); }
.invite-event-btn:active, .invite-nickname-btn:active { background: rgba(217,180,95,.11); }

@media (max-width: 355px) {
  .invite-modal { padding-inline: 13px; }
  .invite-brand-lockup .brand-glow { width: min(282px, 82vw); }
  .invite-heading h2 { font-size: 23px; }
  .invite-profile-card { gap: 9px; padding: 11px; }
  .invite-profile-avatar { width: 48px; height: 48px; font-size: 19px; }
  .invite-profile-copy strong { font-size: 17px; }
  .invite-mission-card, .invite-event-card { padding: 12px; }
  .invite-mission-copy strong { font-size: 13px; }
  .invite-event-copy strong { font-size: 13px; }
}

/* ── 토스트 ─────────────────────────────────────────── */
#toasts {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--bottombar-h) + var(--tg-bottom-inset) + 18px);
  z-index: 80; display: flex; flex-direction: column; gap: 7px; align-items: center;
  pointer-events: none; width: max-content; max-width: 88vw;
}
.toast {
  padding: 10px 16px; border-radius: 999px;
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em;
  background: var(--panel2); border: 1px solid var(--line);
  color: var(--text); box-shadow: var(--shadow-md);
  animation: toast-in .18s ease-out;
}
.toast.err { background: var(--danger); border-color: transparent; color: #fff; }
.toast.ok { background: var(--accent); border-color: transparent; color: var(--accent-on); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }

/* 세션 만료 오버레이 */
#sessionOverlay {
  position: fixed; inset: 0 var(--tg-right-inset) 0 var(--tg-left-inset); z-index: 90;
  display: flex; align-items: center; justify-content: center; text-align: center;
  background: var(--bg); padding: 30px;
}
#sessionOverlay .so-box { max-width: 320px; }
#sessionOverlay h2 { margin: 0 0 10px; font-size: 18px; letter-spacing: -0.02em; }
#sessionOverlay p { color: var(--muted); font-size: 13.5px; line-height: 1.7; margin: 0 0 20px; }

/* 이미지 라이트박스 */
#lightbox {
  position: fixed; inset: 0 var(--tg-right-inset) 0 var(--tg-left-inset); z-index: 95;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .92);
}
#lightbox img { max-width: 94vw; max-height: 88vh; border-radius: var(--radius-sm); }

/* ── 포인트룰렛 ─────────────────────────────────────── */
.rl-wrap { display: flex; flex-direction: column; gap: 13px; align-items: center; padding: 4px 2px 10px; }
.rl-head { text-align: center; }
.rl-eyebrow { color: var(--accent); font-size: 10px; font-weight: 850; letter-spacing: .14em; }
.rl-head h2 { margin: 2px 0 0; font-size: 21px; letter-spacing: -.03em; }
.rl-head p { margin: 3px 0 0; color: var(--muted); font-size: 11px; }
.rl-balance { display: flex; align-items: center; gap: 8px; width: 100%; padding: 11px 14px;
  border: 1px solid var(--accent-line); border-radius: 13px; background: var(--accent-soft); }
/* 라벨·버튼은 고정, 잔액 숫자만 줄어들며 말줄임 — 베트남어 라벨이 길어도 한 줄 유지. */
.rl-balance > span { flex: none; color: var(--muted); font-size: 11.5px; font-weight: 700; white-space: nowrap; }
.rl-balance > strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 16px; color: var(--accent-strong); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.rl-balance-shop { flex: none; margin-left: auto; padding: 6px 11px; border: 1px solid var(--accent-line); border-radius: 999px;
  background: none; color: var(--accent-strong); font-size: 11px; font-weight: 800; white-space: nowrap; }
/* 룰렛 휠 — 네온 페스티벌(D1): 어두운 바탕에 원색 칸, 경계선과 전구가 푸르게 빛난다. */
.rl-zone { position: relative; width: 296px; height: 296px; }
.rl-rim { position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 50% 26%, #2b3350, #141a2c 60%, #0a0d18 100%);
  box-shadow: 0 10px 34px rgba(0,0,0,.7), inset 0 0 22px rgba(120,190,255,.3); }
.rl-dots { position: absolute; inset: 7px; border-radius: 50%; }
/* 전구는 순서대로 켜지며 림을 한 바퀴 도는 마퀴 — 점등 간격은 JS 가 animation-delay 로 준다. */
.rl-dots i { position: absolute; left: 50%; top: 50%; width: 7px; height: 7px; margin: -3.5px;
  border-radius: 50%; background: #eafaff;
  animation: rlBulb 1.6s linear infinite; }
@keyframes rlBulb {
  0%, 100% { background: #4c6a80; box-shadow: 0 0 4px rgba(120,190,235,.4); }
  12%      { background: #ffffff; box-shadow: 0 0 12px 3px rgba(160,235,255,1); }
  38%      { background: #7fb6d2; box-shadow: 0 0 6px 1px rgba(140,210,245,.6); }
}
.rl-rotor { position: absolute; inset: 17px; border-radius: 50%; will-change: transform; }
.rl-wheel { position: absolute; inset: 0; border-radius: 50%; border: 3px solid rgba(150,225,255,.55); }
.rl-lines { position: absolute; inset: 0; border-radius: 50%; overflow: hidden; }
.rl-lines i { position: absolute; left: 50%; top: 0; width: 1px; height: 50%;
  background: linear-gradient(rgba(200,245,255,.95), rgba(200,245,255,.2)); transform-origin: bottom center; }
/* 라벨 반지름 — 테마마다 로터 크기가 달라 변수로 두고 테마 CSS 가 덮어쓴다. */
.rl-labels { position: absolute; inset: 0; --rl-label-r: 104px; }
.rl-labels span { position: absolute; left: 50%; top: 50%; transform-origin: 0 0;
  font-size: 11px; font-weight: 850; color: #fff; white-space: nowrap;
  max-width: 56px; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 0 7px rgba(255,255,255,.55), 0 2px 3px rgba(0,0,0,.75); }
.rl-labels span.gold { color: #ffe066; font-size: 12px; }
.rl-labels span.dim { color: #cfcbd8; opacity: .72; text-shadow: 0 2px 3px rgba(0,0,0,.75); }
/* 8자 이상 긴 라벨은 축소 — .gold 보다 뒤에 두어 최고상 라벨도 줄어들게 한다.
   48px = 인접 조각 라벨 중심 간 현폭(약 46~50px)에 맞춘 실측값. */
.rl-labels span.long { font-size: 8px; letter-spacing: -.02em; max-width: 48px; }
.rl-pointer { position: absolute; left: 50%; top: -7px; transform: translateX(-50%); z-index: 4;
  width: 0; height: 0; border: 12px solid transparent; border-top: 20px solid #ff4d6d;
  filter: drop-shadow(0 0 6px rgba(255,77,109,.8)); }
.rl-spin { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); z-index: 3;
  width: 84px; height: 84px; border-radius: 50%; border: 4px solid rgba(150,230,255,.85);
  padding: 0 9px; overflow: hidden;
  background: radial-gradient(circle at 50% 32%, #1b2740, #0b1120 85%);
  color: #bff0ff; font-weight: 900; font-size: 17px; letter-spacing: .02em;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  box-shadow: 0 0 26px rgba(120,220,255,.5), inset 0 0 18px rgba(120,220,255,.25);
  transition: filter .15s; }
.rl-spin:disabled { filter: grayscale(.5) brightness(.75); }
/* text-indent 는 letter-spacing 이 마지막 글자 뒤에 남기는 공백의 광학 보정. */
.rl-spin small { font-size: 9px; font-weight: 800; letter-spacing: .12em; text-indent: .12em; color: #7fd3f0; }
.rl-spin-label { display: block; max-width: 100%; line-height: 1.05; }
/* 긴 문구(DONE 등)는 줄여서 두 줄로 — 태그+클래스 2개 특이도(0-2-1)로
   뒤에 로드되는 .fest-* .rl-spin(0-2-0)의 font-size 지정을 이긴다. */
button.rl-spin.is-long { font-size: 12.5px; letter-spacing: -.01em; }
button.rl-spin.is-long .rl-spin-label { white-space: normal; }
@media (prefers-reduced-motion: reduce) {
  .rl-dots i { animation: none; background: #cfeeff; box-shadow: 0 0 8px 2px rgba(150,225,255,.7); }
}
/* 텍스트 흐름으로 렌더 — flex 로 두면 텍스트 노드가 익명 아이템으로 쪼개져
   베트남어 문장이 덩어리마다 제각각 줄바꿈되며 어긋나 보인다. */
.rl-bar { display: block; text-align: center; line-height: 1.5; width: 100%;
  padding: 10px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel);
  font-size: 12.5px; font-weight: 700; }
.rl-bar b { color: var(--accent-strong); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rl-bar .rl-bar-status { display: inline-block; white-space: nowrap; }
.rl-bar.rl-tip { color: var(--muted); font-size: 11px; font-weight: 600; text-align: center; }
.rl-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; width: 100%; }
.rl-btns button { padding: 12px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--panel-grad); color: var(--text); font-size: 12.5px; font-weight: 750; }
.rl-shop-cta { width: 100%; padding: 14px; border: 1px solid rgba(255,241,180,.6); border-radius: 13px;
  background: linear-gradient(135deg, #f1cf73, #bf7d18); color: #241a05; font-size: 14px; font-weight: 850; }
.rl-extra { width: 100%; padding: 12px 13px; border: 1px solid var(--line); border-radius: 13px; background: var(--panel); }
.rl-extra > b { display: block; margin-bottom: 8px; font-size: 12.5px; color: var(--accent-strong); }
.rl-extra-empty { color: var(--muted); font-size: 11.5px; }
.rl-hist-row { display: flex; align-items: center; gap: 9px; padding: 7px 2px; border-top: 1px solid var(--line-soft); font-size: 12px; }
.rl-hist-row:first-of-type { border-top: 0; }
.rl-hist-row > span:nth-child(2) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rl-hist-time { color: var(--muted); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.rl-hist-row b.win { color: var(--success); font-variant-numeric: tabular-nums; }
.rl-hist-row b.lose { color: var(--muted); }
.rl-guide-line { display: flex; gap: 6px; margin: 5px 0 0; color: var(--muted); font-size: 11.5px; line-height: 1.5; }
.rl-guide-line i { color: var(--accent); font-style: normal; }

/* ── 포인트 상점 ────────────────────────────────────── */
.sh-wrap { display: flex; flex-direction: column; gap: 12px; padding: 4px 0 12px; }
.sh-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* flex column — 같은 줄 카드끼리 설명 줄 수가 달라도 가격 버튼이 하단에 정렬된다. */
.sh-card { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 15px; overflow: hidden; background: var(--panel-grad); }
.sh-thumb { flex: none; display: flex; align-items: center; justify-content: center; height: 92px; font-size: 42px;
  background: radial-gradient(80% 90% at 50% 20%, rgba(217,180,95,.14), transparent 70%), #101014; }
/* contain — 슬롯이 가로로 넓어 cover 로 채우면 세로형 상품 사진이 잘린다.
   업로드 시 정규화된 이미지는 바탕이 --card-canvas 와 같아 여백이 보이지 않는다. */
.sh-thumb img { width: 100%; height: 100%; object-fit: contain; }
.sh-thumb.has-img { background: var(--card-canvas); }
.sh-body { flex: 1; padding: 10px 11px 12px; display: flex; flex-direction: column; gap: 3px; }
/* 베트남어 상품명·설명이 길어도 카드가 무한정 늘어나지 않게 줄 수를 제한한다. */
.sh-body > b { font-size: 13px; letter-spacing: -.02em;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
/* :not(.sh-stock) — 마지막의 빈 .sh-stock 스팬까지 min-height 를 먹어 카드 하단에
   유령 여백이 생기지 않게 설명 스팬만 고른다. */
.sh-body > span:not(.sh-stock) { color: var(--muted); font-size: 10px; line-height: 1.35; min-height: 27px; margin-bottom: 3px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
.sh-price { margin-top: auto; padding: 9px 0; border-radius: var(--radius-sm); text-align: center;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  color: var(--accent-strong); font-size: 12.5px; font-weight: 850; transition: background .15s, color .15s; }
.sh-price.armed { background: var(--accent); color: var(--accent-on); }
.sh-price:disabled { background: #1c1c20; border-color: var(--line); color: var(--muted); }
.sh-stock { color: var(--muted); font-size: 9px; text-align: right; margin-top: 4px; }
.sh-orders-title { margin-top: 4px; font-size: 12.5px; color: var(--accent-strong); }
.sh-orders { border: 1px solid var(--line); border-radius: 13px; padding: 4px 13px; background: var(--panel); }
.sh-status { font-size: 10.5px; font-weight: 800; }
.sh-status.pending { color: var(--warn); }
.sh-status.done { color: var(--success); }
.sh-status.canceled { color: var(--muted); }

/* ── 라이브스코어 ───────────────────────────────────── */
.ls-wrap { display: flex; flex-direction: column; gap: 8px; padding: 2px 0 12px; }
.ls-tabs { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.ls-tabs::-webkit-scrollbar { display: none; }
.ls-tab { flex: 0 0 auto; padding: 7px 13px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--muted); font-size: 11.5px; font-weight: 750; }
.ls-tab.on { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong); }
/* 고정 리그 칩(태국어 업체 전용) — 탭과 같은 알약꼴이되 살짝 크게, 줄을 따로 차지한다 */
.ls-pin-row { display: flex; }
.ls-pin { flex: 0 0 auto; padding: 7px 15px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--text); font-size: 12.5px; font-weight: 800; }
.ls-pin.on { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong); }
/* 날짜 줄 — 어제·오늘·내일. 탭줄과 같은 알약꼴이되 한 단계 작게(상위 축이
   아니라 '언제' 라는 곁가지다). 「리그별」 토글이 오른쪽 끝에 붙는다. */
.ls-days { display: flex; align-items: center; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.ls-days::-webkit-scrollbar { display: none; }
.ls-day { flex: 0 0 auto; padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--muted); font-size: 11px; font-weight: 750; }
.ls-day.on { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong); }
.ls-group { margin-left: auto; flex: 0 0 auto; padding: 6px 11px; border: 1px solid var(--line);
  border-radius: 999px; background: var(--panel); color: var(--muted); font-size: 11px; font-weight: 750;
  white-space: nowrap; }
.ls-group.on { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong); }

/* 지금 대화 중인 경기 — 목록 맨 위 한 줄. 가로로 흘려서 목록을 밀어내지
   않게 한다(세로로 쌓으면 정작 경기가 화면 밖으로 나간다). */
.ls-hot { display: flex; flex-direction: column; gap: 5px; }
.ls-hot-title { color: var(--muted); font-size: 10px; font-weight: 800; letter-spacing: .04em; }
.ls-hot-strip { display: flex; gap: 7px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.ls-hot-strip::-webkit-scrollbar { display: none; }
.ls-hot-item { flex: 0 0 auto; max-width: 62vw; display: flex; flex-direction: column; gap: 3px;
  padding: 6px 10px; border: 1px solid var(--accent-line); border-radius: var(--radius-sm);
  background: var(--accent-soft); }
.ls-hot-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text); font-size: 11.5px; font-weight: 800; }
.ls-hot-n { color: var(--accent-strong); font-size: 9.5px; font-weight: 800;
  font-variant-numeric: tabular-nums; }
/* 응원 쏠림 — 표가 실제로 있을 때만 그려진다(JS 가 판정한다) */
.ls-hot-bar { height: 3px; border-radius: 999px; background: rgba(255,255,255,.14); overflow: hidden; }
.ls-hot-bar i { display: block; height: 100%; background: var(--accent-strong); }
/* 지금 목록에 없는 경기 — 열 수가 없으니 눌리는 것처럼 보이지 않게 */
.ls-hot-item.ls-hot-flat { opacity: .62; }
/* 대화 줄 안에서는 카드용 '입장' 꼬리말이 자리만 먹는다 */
.ls-hot-item .mr-enter { display: none; }

/* 즐겨찾기 — 담아 둔 것 칩 줄. 무엇을 담았는지 늘 보이고 ✕ 로 바로 뺀다. */
.ls-favrow { display: flex; flex-direction: column; gap: 5px; }
.ls-fav-title { color: var(--muted); font-size: 9.5px; font-weight: 800; letter-spacing: .05em; }
.ls-fav-strip { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.ls-fav-strip::-webkit-scrollbar { display: none; }
.ls-favchip { flex: 0 0 auto; display: flex; align-items: center; padding: 0 4px 0 11px;
  border: 1px solid var(--accent-line); border-radius: 999px; background: var(--accent-soft);
  color: var(--accent-strong); font-size: 11px; font-weight: 800; white-space: nowrap; }
.ls-favchip-name { padding: 6px 0; border: 0; background: none; color: inherit;
  font-size: inherit; font-weight: inherit; white-space: nowrap; }
/* ✕ 는 **따로 눌러야** 빠진다. 칩 전체가 삭제면 이름을 눌러 보려던 손이 지운다. */
.ls-favchip-x { width: 24px; height: 24px; margin-left: 2px; padding: 0; border: 0;
  background: none; color: var(--accent-strong); opacity: .6; font-size: 11px; line-height: 1; }

/* 카드의 별. 카드 전체가 눌리는 버튼이라 별은 클릭을 삼킨다(JS) —
   여기서는 손가락이 닿을 크기만 확보한다. */
.ls-star { flex: none; width: 24px; height: 24px; margin: -3px 0 -3px -4px; padding: 0;
  display: flex; align-items: center; justify-content: center; border: 0; background: none;
  color: var(--muted); font-size: 14px; line-height: 1; }
.ls-star.on { color: var(--accent-strong); }

/* 경기 알림 벨. 별과 같은 자리·같은 크기 — 둘 다 카드 클릭을 삼킨다. */
.ls-bell { flex: none; width: 24px; height: 24px; margin: -3px 0 -3px 2px; padding: 0;
  display: flex; align-items: center; justify-content: center; border: 0; background: none;
  color: var(--muted); font-size: 12px; line-height: 1; opacity: .55; }
.ls-bell.on { color: var(--accent-strong); opacity: 1; }
/* 벨을 못 다는 카드(7M·끝난 경기)의 빈자리. 이게 없으면 섞인 목록에서 별 열이
   카드마다 28px 씩 튀어 눈이 세로줄을 못 잡는다. 너비는 .ls-bell 과 같게. */
.ls-bell-gap { flex: none; width: 24px; height: 24px; margin: -3px 0 -3px 2px; }
/* 저장 왕복 중. 이 앱은 탭 하이라이트를 전역으로 껐고(app.css 맨 위) 시트에도
   덮개가 없어서, 표시가 없으면 유저는 「안 눌렸다」고 읽고 다시 누른다. */
.ls-sheet-opt.busy, .ls-sheet-done.busy, .ma-row.busy { opacity: .55; }

/* 알림 시트의 스위치 줄 */
.ls-alert-row { display: flex; align-items: center; gap: 11px; width: 100%; margin-bottom: 8px;
  padding: 12px; border: 1px solid var(--line); border-radius: 11px; background: var(--panel);
  color: var(--text); text-align: left; }
.ls-alert-row.on { border-color: var(--accent-line); background: var(--accent-soft); }
.ls-alert-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ls-alert-tx b { font-size: 13.5px; font-weight: 750; }
.ls-alert-tx i { font-style: normal; color: var(--muted); font-size: 11px; font-weight: 600; }
.ls-sw { flex: none; width: 42px; height: 24px; border-radius: 999px; background: #33333b;
  position: relative; }
.ls-sw::after { content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px;
  border-radius: 50%; background: #8d8d96; }
.ls-sw.on { background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-line); }
.ls-sw.on::after { left: auto; right: 3px; background: var(--accent-strong); }
.ls-sheet-done { width: 100%; margin-top: 4px; padding: 13px; border: 1px solid var(--accent-line);
  border-radius: 11px; background: var(--accent-soft); color: var(--accent-strong);
  font-size: 13.5px; font-weight: 800; }
.ls-sheet-sub { margin: -6px 0 12px; color: var(--muted); font-size: 11.5px; }
.ls-sheet-more { width: 100%; margin-top: 8px; padding: 10px; border: 0; background: none;
  color: var(--muted); font-size: 11.5px; font-weight: 700; }

/* 무엇을 담을지 고르는 시트 — body 에 붙으므로 화면 전체를 덮는다 */
.ls-sheet-back { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.55); }
.ls-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 61;
  padding: 8px 14px calc(16px + env(safe-area-inset-bottom)); background: var(--panel2);
  border-top: 1px solid var(--line); border-radius: 16px 16px 0 0; }
.ls-sheet-grab { width: 38px; height: 4px; border-radius: 999px; background: #33333b; margin: 0 auto 12px; }
.ls-sheet-h { margin: 0 0 10px; font-size: 12.5px; font-weight: 800; color: var(--text); }
.ls-sheet-opt { display: flex; align-items: center; gap: 10px; width: 100%; margin-bottom: 8px;
  padding: 12px; border: 1px solid var(--line); border-radius: 11px; background: var(--panel);
  color: var(--text); font-size: 13.5px; font-weight: 750; text-align: left; }
.ls-sheet-opt.on { border-color: var(--accent-line); background: var(--accent-soft); }
.ls-sheet-ic { flex: none; font-size: 15px; color: var(--accent-strong); }
.ls-sheet-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ls-sheet-note { flex: none; color: var(--muted); font-size: 10.5px; font-weight: 700; }

.ls-list { display: flex; flex-direction: column; gap: 9px; }
/* 리그 헤더 — 상태 섹션(.ls-section)보다 한 단계 아래여야 한다. 같은 띠 모양이
   연달아 나오면 어느 쪽이 상위인지 안 보이므로, 여기는 테두리 없이 밑줄만.

   높이를 42px 로 잡는다. 예전 padding(7px 4px 6px)이면 실측 30.7px 인데,
   **기본이 접힘**이 되면서 이 줄이 목록의 거의 전부가 된다 — 줄 사이 간격을
   더해도 40px 이 안 돼 옆 리그가 눌린다. 같은 파일 .bet-main-more 가 42px 다. */
.ls-lg-head { display: flex; align-items: center; gap: 7px; width: 100%;
  min-height: 42px; padding: 6px 4px;
  border: 0; border-bottom: 1px solid var(--line); background: none; color: var(--text);
  font-size: 11.5px; font-weight: 800; text-align: left; }
.ls-lg-arrow { flex: none; color: var(--accent-strong); font-size: 11px; }
.ls-lg-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ls-lg-count { flex: none; padding: 1px 7px; border-radius: 999px; background: var(--panel2);
  color: var(--muted); font-size: 9.5px; font-weight: 800; font-variant-numeric: tabular-nums; }
/* 상태색은 **펼침**에 준다. 예전에는 접힘을 --muted 로 흐리게 했는데, 접힘이
   정상 상태가 된 지금 그러면 화면 전체가 대비 5.67:1 짜리 회색 덩어리가 된다
   (펼침은 17.73:1). 접힘은 제 색으로 두고, 열린 쪽을 accent 로 켠다. */
.ls-lg-head.on { color: var(--accent-strong); }
/* 이 앱은 탭 하이라이트를 전역으로 껐다(파일 맨 위) — 누른 표시를 직접 준다. */
.ls-lg-head:active { background: var(--panel2); }
/* 검색 중 헤더는 이름표다 — 누를 수 없으므로 눌린 표시도 화살표도 없다. */
.ls-lg-label { color: var(--muted); }
.ls-lg-label:active { background: none; }
/* 「모두 펼치기」 — 리그별 버튼과 같은 계열, 날짜 줄 오른쪽 끝. */
.ls-expand-all { margin-left: 6px; }
/* 그룹 안 카드는 리그 줄을 숨긴다 — 바로 위 헤더가 같은 말을 하고 있다.
   시각·LIVE 배지는 margin-left:auto 라 그대로 오른쪽에 남는다.
   7M 카드의 왼쪽 색 점(.sv-dot)도 같이 숨긴다 — 그건 리그 이름 옆에서만
   뜻이 있는 표식이라, 이름 없이 홀로 남으면 정체 모를 점이 된다. */
.ls-card.ls-in-group .ls-league,
.ls-card.ls-in-group .sv-dot { display: none; }
/* 섹션 헤더 — 진행중/예정/결과 경계가 목록에서 딱 걸리게 띠 모양으로.
   (예전엔 10.5px 회색 글자뿐이라 결과 섹션이 어디서 시작하는지 안 보인다는
   운영자 피드백이 있었다 — 2026-09-01) */
.ls-section { margin: 6px 0 0; padding: 9px 12px; border: 1px solid var(--line);
  border-left: 3px solid var(--accent-line); border-radius: var(--radius-sm);
  background: var(--panel); color: var(--text); font-size: 13.5px; font-weight: 800; letter-spacing: .03em; }
.ls-card { border: 1px solid var(--line); border-radius: var(--radius-md); padding: 11px 13px; background: var(--panel-grad); }
.ls-top { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.ls-league { color: var(--muted); font-size: 10px; font-weight: 750; letter-spacing: .04em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ls-live { margin-left: auto; flex: none; display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px;
  border-radius: 999px; background: rgba(229,72,77,.16); color: #ff8a8e; font-size: 9.5px; font-weight: 850; }
.ls-live i { width: 5px; height: 5px; border-radius: 50%; background: var(--live); animation: lsBlink 1.2s infinite; }
@keyframes lsBlink { 50% { opacity: .3; } }
.ls-time { margin-left: auto; flex: none; color: var(--muted); font-size: 10.5px; font-weight: 650; }
.ls-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; }
.ls-team { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 750; min-width: 0; }
.ls-team span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ls-team.right { justify-content: flex-end; text-align: right; }
.ls-team i { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
  border-radius: 50%; background: #23232a; font-size: 12px; flex: none; font-style: normal; overflow: hidden; }
.ls-team i img { width: 100%; height: 100%; object-fit: contain; }
.ls-score { font-size: 18px; font-weight: 900; letter-spacing: .02em; font-variant-numeric: tabular-nums; }
.ls-score b { color: var(--accent-strong); }
.ls-score.live-nodata { font-size: 11px; color: #ff8a8e; font-weight: 800; }
/* 격투기 승·패 — 숫자가 아니라 글자라 점수만큼 클 필요가 없다 */
.ls-score.ls-verdict { font-size: 12.5px; letter-spacing: 0; }
/* 보드 헤더의 승·패도 같은 이유로 숫자보다 작게 */
.mr-bh-score.mr-bh-verdict { font-size: 15px; letter-spacing: 0; }
/* 보드 헤더 아래 보조 한 줄(전반 점수·퇴장) — 카드의 .sv-half 와 같은 위계 */
.mr-bh-extra { margin-top: 4px; text-align: center; color: var(--muted);
  font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums; }
.ls-vs { font-size: 12px; color: var(--muted); font-weight: 800; }

/* 찾기 줄 — 200건 넘는 목록에서 우리 팀을 눈으로 훑던 문제. 서버를 다시 부르지
   않고 화면에 올라온 것만 거른다.

   스크롤을 따라 붙어 있어야 쓸모가 있다: 검색이 필요한 순간은 목록이 길어서
   한참 내려간 뒤인데, 흐름에 두면 그때는 화면 밖이라 맨 위로 돌아와야 한다.
   .pin-banner 와 같은 방식(헤더 54px 아래)이되 z-index 는 헤더보다 낮게. */
.ls-search-row { position: sticky; top: calc(54px + var(--tg-content-top)); z-index: 14;
  display: flex; align-items: center; gap: 6px;
  margin: 0 -14px; padding: 6px 14px 15px; background: var(--bg); }
.ls-search { flex: 1 1 auto; min-width: 0; padding: 9px 12px; border: 1px solid var(--line);
  border-radius: 999px; background: var(--panel); color: var(--text); font-size: 12.5px; font-weight: 650; }
.ls-search::placeholder { color: var(--muted); font-weight: 600; }
.ls-search:focus { outline: none; border-color: var(--accent-line); background: var(--accent-soft); }
/* iOS 사파리가 type=search 에 넣는 기본 취소 버튼 — 우리 ✕ 와 둘이 뜬다 */
.ls-search::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.ls-search-x { flex: none; width: 30px; height: 30px; border: 1px solid var(--line); border-radius: 50%;
  background: var(--panel); color: var(--muted); font-size: 11px; font-weight: 800; }

/* 「N초 전 갱신」 — 조용히 30초마다 갈리는 화면이 지금 것인지 알려 준다.
   눈에 걸리면 안 되는 정보라 오른쪽 끝에 아주 작게. */
/* 고정 검색 띠 안 오른쪽 아래에 얹힌다(위 padding-bottom 이 그 자리다) */
.ls-updated { position: absolute; right: 14px; bottom: 2px; color: var(--muted);
  font-size: 9.5px; font-weight: 650; font-variant-numeric: tabular-nums; }
/* 일부 소스를 못 받았을 때 — 회색으로 두면 그냥 시각으로 읽고 지나간다 */
.ls-updated.bad { color: #ff8a8e; font-weight: 800; }

/* 연기·취소 카드 — 열리지도 정산되지도 않는 경기라 한 단계 물러나 보이게 */
.ls-card-off { opacity: .72; border-style: dashed; }
.ls-off-tag { margin-left: auto; flex: none; padding: 3px 8px; border-radius: 999px;
  background: rgba(229,72,77,.14); color: #ff8a8e; font-size: 9.5px; font-weight: 850; }
.ls-card-off .ls-time { margin-left: 6px; }

/* 득점 반짝임 — 보고 있는 사이에 점수가 바뀌면 그 카드만 잠깐 물든다.
   한 번만 도는 애니메이션이라, 30초 뒤 다시 그릴 때 클래스가 없으면 사라진다.

   **카드 자신의 background/border-color 는 건드리지 않는다.** 애니메이션 선언은
   명시도와 무관하게 일반 선언을 이기므로, 카드 속성을 애니메이트하면 (1) 배경
   그라데이션(--panel-grad 의 background-image)이 none 으로 리셋돼 카드가 납작해
   보이고 (2) 선택된 카드 강조(.ls-card.lsc-sel)가 2.4초 동안 눌렸다가 툭 되돌아
   온다. 그래서 덧대는 층(::after) 하나만 물들인다. */
.ls-flash { position: relative; }
.ls-flash::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-line);
  pointer-events: none; animation: lsScored 2.4s ease-out 1 forwards;
}
@keyframes lsScored { 0% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  /* 움직임 없이도 "여기가 바뀌었다" 는 남아야 한다 — 옅게 켜 두고 멈춘다. */
  .ls-flash::after { animation: none; opacity: .55; }
}

/* ── 경품 이벤트: 목록 ──────────────────────────────── */
.lobby-card-event { border-color: var(--accent-line); background:
  radial-gradient(110% 100% at 50% 0%, rgba(217,180,95,.18), transparent 58%),
  radial-gradient(60% 100% at 100% 100%, rgba(120,60,20,.32), transparent 70%),
  linear-gradient(145deg, #17151a 0%, #0a0a0e 72%); }
.ev-wrap { display: flex; flex-direction: column; gap: 11px; padding: 2px 0 14px; }
.ev-head { display: flex; align-items: center; gap: 10px; }
.ev-head strong { font-size: 19px; letter-spacing: -.035em; }
.ev-tickets { margin-left: auto; padding: 6px 11px; border: 1px solid var(--accent-line); border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-strong); font-size: 11.5px; font-weight: 800; white-space: nowrap; }
/* 탭 3개가 좁은 화면에서 찌그러졌다. 줄바꿈이나 가로 스크롤로 처리하면
   기기마다 배치가 달라지므로, 여백만 비례로 줄여 어디서나 한 줄을 유지한다. */
.ev-tabs { display: flex; gap: 6px; }
.ev-tab { padding: 7px clamp(9px, 3.4vw, 14px); border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--muted); font-size: 11.5px; font-weight: 750;
  white-space: nowrap; }
.ev-tab.on { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong); }
.ev-list { display: flex; flex-direction: column; gap: 11px; }
.ev-card { overflow: hidden; border: 1px solid var(--line); border-radius: 16px;
  background: var(--panel-grad); cursor: pointer; transition: transform .15s, border-color .15s; }
.ev-card.hot { border-color: var(--accent-line); }
.ev-card:active { transform: scale(.99); }
.ev-thumb { position: relative; height: 138px; display: flex; align-items: center; justify-content: center;
  font-size: 60px; overflow: hidden;
  background: radial-gradient(75% 90% at 50% 25%, rgba(217,180,95,.15), transparent 70%), #0d0d11; }
.ev-thumb img { width: 100%; height: 100%; object-fit: contain; }
.ev-thumb.has-img { background: var(--card-canvas); }
.ev-state { position: absolute; left: 11px; top: 11px; padding: 4px 10px; border-radius: 999px;
  font-size: 9.5px; font-weight: 850; letter-spacing: .04em; }
.ev-state.live { background: var(--live); color: #fff; }
.ev-state.upcoming { background: #2a2a31; color: #b6b1a6; }
.ev-state.ended { background: #1c1c20; color: #7d786e; }
.ev-state.drawn { background: rgba(95,191,139,.9); color: #06210f; }
.ev-left { position: absolute; right: 11px; top: 11px; padding: 4px 10px; border-radius: 999px;
  background: rgba(6,6,9,.82); color: var(--accent-strong); font-size: 10px; font-weight: 800; }
.ev-body { padding: 12px 13px 13px; }
.ev-name { font-size: 15px; font-weight: 800; letter-spacing: -.03em; }
.ev-prize { margin-top: 3px; color: var(--accent-strong); font-size: 12px; font-weight: 750; }
.ev-meta { margin-top: 9px; display: flex; align-items: center; gap: 8px; }
.ev-meta .cnt { color: var(--muted); font-size: 10.5px; }
.ev-go { margin-left: auto; padding: 8px 14px; border-radius: var(--radius-sm); font-size: 11.5px; font-weight: 800;
  background: var(--accent-soft); border: 1px solid var(--accent-line); color: var(--accent-strong); }
.ev-go.dim { background: #1a1a1e; border-color: var(--line); color: var(--muted); }
.ev-mine { margin-top: 8px; padding: 7px 9px; border-radius: var(--radius-sm); border: 1px solid rgba(217,180,95,.22);
  color: var(--accent-strong); font-size: 10.5px; font-weight: 700; text-align: center; }

/* ── 경품 이벤트: 상세 ──────────────────────────────── */
.evd-wrap { margin: -12px -14px -22px; }
.evd-hero { position: relative; height: 212px; display: flex; align-items: center; justify-content: center;
  font-size: 92px; overflow: hidden; border-bottom: 1px solid var(--line-soft);
  background: radial-gradient(70% 85% at 50% 30%, rgba(217,180,95,.2), transparent 72%), #0c0c10; }
.evd-hero img { width: 100%; height: 100%; object-fit: cover; }
.evd-hero.off { filter: grayscale(.55); }
.evd-hero .ev-state { left: 14px; top: 14px; }
.evd-body { padding: 15px 14px 26px; display: flex; flex-direction: column; gap: 12px; }
.evd-title { font-size: 22px; letter-spacing: -.035em; line-height: 1.22; }
.evd-prize { margin-top: 5px; color: var(--accent-strong); font-size: 13.5px; font-weight: 800; }
.evd-desc { color: var(--muted); font-size: 12px; line-height: 1.6; white-space: pre-wrap; }
.evd-rows { border: 1px solid var(--line); border-radius: 13px; background: var(--panel); overflow: hidden; }
.evd-row { display: flex; align-items: center; gap: 10px; padding: 11px 13px;
  border-top: 1px solid var(--line-soft); font-size: 12px; }
.evd-row:first-child { border-top: 0; }
.evd-row span { color: var(--muted); }
.evd-row b { margin-left: auto; font-variant-numeric: tabular-nums; }
.evd-row b.gold { color: var(--accent-strong); }
.evd-apply { width: 100%; padding: 15px; border-radius: 13px; border: 1px solid rgba(255,241,180,.6);
  background: linear-gradient(135deg, #f1cf73, #bf7d18); color: #241a05; font-size: 15px; font-weight: 850; }
.evd-apply.dim, .evd-apply:disabled { background: #1c1c20; border-color: var(--line); color: var(--muted); }
.evd-note { color: #6f6b63; font-size: 10.5px; line-height: 1.7; }
.evd-note i { color: var(--accent); font-style: normal; }
.evd-win { padding: 12px 13px; border-radius: 13px; border: 1px solid rgba(95,191,139,.35); background: rgba(95,191,139,.08); }
.evd-win b { color: var(--success); font-size: 12.5px; }
.evd-win p { margin-top: 3px; color: var(--muted); font-size: 11px; }
.evd-winners { padding: 12px 13px; border: 1px solid var(--line); border-radius: 13px; background: var(--panel); }
.evd-winners > b { display: block; margin-bottom: 7px; color: var(--accent-strong); font-size: 12.5px; }
.evd-winners-empty { color: var(--muted); font-size: 11.5px; }
.evd-winner-row { display: flex; align-items: center; gap: 9px; padding: 6px 2px;
  border-top: 1px solid var(--line-soft); font-size: 12px; }
.evd-winner-row:nth-of-type(1) { border-top: 0; }
.evd-winner-row.me { color: var(--accent-strong); font-weight: 800; }
.evd-winner-row .no { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
  border-radius: 50%; background: var(--panel2); color: var(--muted); font-size: 9.5px; font-weight: 800; }

/* 친구초대 모달 이벤트 카드 — 경품 사진/이모지 표시 */
/* 이벤트 사진은 16:9 정규화(배경 --card-canvas) — cover 로 52px 폭에 우겨넣으면
   세로 띠만 남아 경품이 안 보인다. 칸을 넓히고 contain + 같은 배경색으로 통째로 보여준다. */
.invite-event-card.has-photo { grid-template-columns: 96px minmax(0, 1fr); }
.invite-event-card.has-photo .invite-event-art { width: 96px; }
.invite-event-art.has-photo { padding: 0; overflow: hidden; background: var(--card-canvas); }
.invite-event-art.has-photo img { width: 100%; height: 100%; min-height: 62px; object-fit: contain; }
.invite-event-art.has-emoji { font-size: 30px; }
.invite-mission-status.is-link { cursor: pointer; }
.invite-mission-status.is-link:active { transform: scale(.985); }
/* 이벤트 카드 자리 — 비어 있으면 레이아웃(gap)에서 완전히 빠진다 */
.home-event-slot:empty { display: none; }
.home-event-slot { display: contents; }

/* ── 전광판 (당첨 발표 흐르는 띠) ─────────────────────── */
.board { position: relative; overflow: hidden; margin: -12px -14px 12px; padding: 9px 0;
  border-bottom: 1px solid rgba(217,180,95,.3);
  background: linear-gradient(90deg, #1a1206, #241a08 50%, #1a1206); }
.board-track { display: flex; gap: 34px; white-space: nowrap; padding-left: 100%;
  animation: boardRoll 18s linear infinite; }
@keyframes boardRoll { to { transform: translateX(-100%); } }
.board-item { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 800; color: #ffe9ad; }
.board-item .lamp { width: 7px; height: 7px; border-radius: 50%; background: #ff4d4f;
  box-shadow: 0 0 7px #ff4d4f; flex: none; }
@media (prefers-reduced-motion: reduce) { .board-track { animation: none; padding-left: 12px; } }

/* ── 티켓함 ─────────────────────────────────────────── */
.tk-wrap { display: flex; flex-direction: column; gap: 11px; padding: 2px 0 14px; }
.tk-head { display: flex; align-items: center; gap: 10px; }
.tk-head strong { font-size: 19px; letter-spacing: -.035em; }
.tk-chip { margin-left: auto; padding: 6px 11px; border: 1px solid var(--accent-line); border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-strong); font-size: 11.5px; font-weight: 800; white-space: nowrap; }
.tk-summary { display: flex; align-items: center; gap: 10px; padding: 12px 14px;
  border: 1px solid var(--accent-line); border-radius: var(--radius-md); background: var(--accent-soft); }
.tk-summary span { display: block; color: var(--muted); font-size: 11.5px; font-weight: 700; }
.tk-summary strong { font-size: 20px; color: var(--accent-strong); letter-spacing: -.02em; }
.tk-go { margin-left: auto; padding: 7px 12px; border: 1px solid var(--accent-line);
  border-radius: 999px; background: none; color: var(--accent-strong); font-size: 11px; font-weight: 800; }
.tk-progress-note { color: var(--muted); font-size: 11px; text-align: center; }
.tk-tabs { display: flex; gap: 6px; }
.tk-tab { padding: 7px 14px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--muted); font-size: 11.5px; font-weight: 750; }
.tk-tab.on { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong); }
.tk-list { display: flex; flex-direction: column; gap: 9px; }
.tk-round { margin: 6px 1px 0; color: var(--muted); font-size: 10.5px; font-weight: 800; letter-spacing: .04em; }

/* 복권 티켓 카드 — 좌측 스텁 + 절취선 */
.ticket { position: relative; display: grid; grid-template-columns: 62px minmax(0,1fr);
  border: 1px solid rgba(217,180,95,.34); border-radius: 13px; overflow: hidden;
  background: linear-gradient(120deg, #191720, #100f14); }
.ticket.win { border-color: rgba(95,191,139,.6); background: linear-gradient(120deg, #14231a, #0d1611); }
.ticket.lose { opacity: .55; }
.tk-stub { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  background: repeating-linear-gradient(135deg, rgba(217,180,95,.13) 0 6px, transparent 6px 12px);
  border-right: 1px dashed rgba(217,180,95,.45); }
.tk-stub b { font-size: 15px; color: var(--accent-strong); }
.tk-stub span { font-size: 8.5px; color: var(--muted); font-weight: 800; letter-spacing: .08em; }
.ticket::before, .ticket::after { content: ''; position: absolute; left: 62px; width: 11px; height: 11px;
  margin-left: -6px; border-radius: 50%; background: var(--bg); }
.ticket::before { top: -6px; }
.ticket::after { bottom: -6px; }
.tk-main { padding: 11px 13px; min-width: 0; }
.tk-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 24px; font-weight: 800;
  letter-spacing: .2em; color: #fff; text-shadow: 0 0 14px rgba(217,180,95,.45); }
.ticket.win .tk-code { color: #8ef0b6; text-shadow: 0 0 14px rgba(95,191,139,.6); }
.tk-meta { margin-top: 5px; display: flex; align-items: center; gap: 7px; }
.tk-meta small { color: var(--muted); font-size: 10px; }
.tk-badge { margin-left: auto; padding: 3px 9px; border-radius: 999px; font-size: 9.5px; font-weight: 850; }
.tk-badge.wait { background: #2a2a31; color: #b6b1a6; }
.tk-badge.win { background: rgba(95,191,139,.9); color: #06210f; }
.tk-badge.lose { background: #1c1c20; color: #7d786e; }
.tk-badge.stock { background: rgba(217,180,95,.9); color: #241a05; }
.ev-tickets.tap { cursor: pointer; }
.ev-tickets.tap:active { opacity: .7; }

/* ── 이벤트 응모(wallet) — 장수 선택 + 확인 시트 ────────── */
.ev-enter { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--accent-line);
  border-radius: 13px; background: var(--accent-soft); }
.ev-enter-l { font-size: 12px; color: var(--muted); }
.ev-enter-l b { display: block; color: var(--text); font-size: 13px; }
.ev-enter-ctl { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.ev-step { width: 34px; height: 34px; border-radius: 10px; border: 1px solid var(--accent-line); color: var(--accent-strong); font-size: 18px; }
.ev-step:disabled { opacity: .35; }
.ev-step-n { font-size: 20px; font-weight: 800; min-width: 28px; text-align: center; }
.ev-sheet-wrap { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.6); display: flex; align-items: flex-end; padding: 0 14px 20px; }
.ev-sheet { width: 100%; background: var(--panel); border: 1px solid var(--accent-line); border-radius: 18px; padding: 16px; }
.ev-sheet h3 { font-size: 16px; margin: 0 0 6px; }
.ev-sheet p { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 0 0 4px; }
.ev-sheet-after { color: var(--accent-strong) !important; }
.ev-sheet-btns { display: flex; gap: 8px; margin-top: 12px; }
.ev-sheet-btns button { flex: 1; padding: 12px; border-radius: 12px; font-weight: 800; font-size: 14px; }
.ev-sheet-ok { background: var(--accent); color: #0d0b06; }
.ev-sheet-no { background: none; border: 1px solid var(--line); color: var(--muted); }

/* 이벤트 상세 — 내 티켓 번호 */
.evd-mytk { padding: 12px 13px; border: 1px solid rgba(217,180,95,.3); border-radius: 13px;
  background: radial-gradient(80% 100% at 50% 0%, rgba(217,180,95,.1), transparent 70%), var(--panel); }
.evd-mytk > b { display: block; margin-bottom: 8px; color: var(--accent-strong); font-size: 12px; }
.evd-mytk-codes { display: flex; flex-wrap: wrap; gap: 6px; }
.evd-mytk-codes code { font-family: ui-monospace, Menlo, monospace; font-size: 13px; font-weight: 800;
  letter-spacing: .12em; padding: 6px 10px; border: 1px dashed rgba(217,180,95,.45);
  border-radius: 8px; background: #16151b; color: #fff; }
.evd-mytk-codes code.more { border-style: solid; color: var(--muted); }

/* ── 업체 메뉴 구성: gametv ────────────────────────────────────────
   생성 테마의 셸(index.html)은 동결 복사본이라 마크업을 못 바꾼다. 그래서
   헤더 로고와 5칸 하단 네비는 core.js 가 body.menu-profile-gametv 를 붙인 뒤
   이 규칙으로만 그려진다 — 다른 업체 화면에는 영향이 없다. */

/* 79TV 전용 발광 레이어는 이 로고와 좌표가 맞지 않는다 (core.js 가 지우지만,
   JS 없이 뜨는 데모 페이지를 위해 CSS 로도 막아 둔다) */
body.menu-profile-gametv .brand-glow .bg-letter,
body.menu-profile-gametv .brand-glow .bg-ball-glow,
body.menu-profile-gametv .brand-glow .bg-orbit { display: none; }

/* 광택 훑기 — 79TV 는 글자별로 잘라낸 스프라이트를 순차 점등하지만, 한 장짜리
   로고는 대신 빛이 좌→우로 지나간다. 마스크는 제자리에 두고 그라디언트 배경만
   흘려서 로고 픽셀 위에서만 빛나게 한다(transform 을 쓰면 마스크가 같이 움직여
   효과가 사라진다). 마스크 미지원 웹뷰에서는 헤더 폭 전체를 훑는 부드러운
   빛띠로 자연스럽게 떨어진다.

   **프로파일이 아니라 로고 모양으로 켠다.** 예전에는 이 규칙이
   body.menu-profile-gametv 에만 걸리고 마스크가 gametv-logo.png 로 하드코딩돼
   있었다. 그래서 (a) 같은 프로파일을 쓰는 두 번째 업체는 자기 로고를 넣어도
   GAME TV 로고 모양으로 빛나고 (b) 기본형 프로파일로 만든 생성 테마는 헤더가
   정지 이미지 한 장이 되어 79TV 의 살아 있는 헤더를 잃었다.
   이제 core.js 가 '한 장짜리 로고를 쓰는 셸' 에 data-brand-shine 을 붙이고,
   마스크는 --brand-logo 토큰이 정한다(테마별 theme.css 가 자기 값을 준다). */
body[data-brand-shine] .brand-glow::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: linear-gradient(105deg,
    transparent 38%, rgba(255,242,200,.55) 46%, rgba(255,255,255,.92) 50%,
    rgba(255,242,200,.55) 54%, transparent 62%) no-repeat;
  background-size: 260% 100%; background-position: 100% 0;
  mix-blend-mode: screen;
  /* 마스크는 core.js 가 실제로 그려진 로고 <img> 를 보고 body 인라인 스타일로
     정한다(enableBrandShine). CSS 로 두면 app.css 의 프로파일 선언이 테마의
     :root 를 이기고, 옛 테마에는 토큰 자체가 없어 마스크가 통째로 무효가 된다.
     none 폴백은 안전망 — 값이 없으면 마스크 대신 아무 효과도 안 낸다. */
  -webkit-mask-image: var(--brand-logo, none); mask-image: var(--brand-logo, none);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  animation: gtvShine 3.4s ease-in-out infinite;
}
@keyframes gtvShine { 0% { background-position: 100% 0; } 55%, 100% { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) {
  body[data-brand-shine] .brand-glow::after { animation: none; opacity: 0; }
}


/* 5칸 네비 — 칸이 좁아지므로 글자를 한 단계 줄인다 */
body.menu-profile-gametv .bottom-nav .nav-item { font-size: 9.5px; letter-spacing: -.03em; }
body.menu-profile-gametv .bottom-nav .nav-item .nav-icon { width: 19px; height: 19px; }

/* 스포츠 베팅 카드 — 아트가 아직 없어도 다른 카드와 같은 질감을 유지한다 */
.lobby-card-bet .lobby-card-art.is-raster img { transform: translateX(-21%) translateY(-6%); }

/* ── 테더 충전·환전 ─────────────────────────────────── */
.usdt-wrap { padding: 12px; display: flex; flex-direction: column; gap: 12px; }
.usdt-loading { padding: 24px; text-align: center; opacity: .6; }
.usdt-card { background: var(--card, #1b1e26); border-radius: var(--radius-md); padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.usdt-card-title { font-weight: 700; font-size: 15px; }
.usdt-net { font-size: 12px; opacity: .6; }
.usdt-addr { display: flex; align-items: center; gap: 8px; background: rgba(255,255,255,.06); border-radius: 10px; padding: 10px; }
/* 주소는 길어서 반드시 줄바꿈시킨다 — 잘리면 유저가 일부만 복사한다 */
.usdt-addr-text { flex: 1; font-size: 12px; word-break: break-all; line-height: 1.5; }
.usdt-copy { flex: none; border: 0; border-radius: 8px; padding: 8px 12px; font-size: 13px; background: var(--accent, #3d7eff); color: #fff; }
.usdt-warn { margin: 0; font-size: 12px; line-height: 1.6; color: #ffb84d; }
.usdt-note { margin: 0; font-size: 12px; line-height: 1.6; opacity: .65; }
.usdt-row { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; }
.usdt-row-k { opacity: .65; }
.usdt-row-v { font-weight: 600; }
.usdt-input { width: 100%; box-sizing: border-box; border: 1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.05); color: inherit; border-radius: 10px; padding: 11px 12px; font-size: 14px; }
.usdt-btn { border: 0; border-radius: 10px; padding: 12px; font-size: 14px; font-weight: 600; background: var(--accent, #3d7eff); color: #fff; }
.usdt-btn[disabled] { opacity: .5; }
.usdt-btn-sub { background: rgba(255,255,255,.12); }
.usdt-sec-title { font-size: 13px; font-weight: 600; opacity: .7; padding: 0 2px; }
.usdt-list { display: flex; flex-direction: column; gap: 8px; }
.usdt-item { background: var(--card, #1b1e26); border-radius: 12px; padding: 12px; display: flex; flex-direction: column; gap: 4px; }
.usdt-item-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.usdt-item-sub { font-size: 11px; opacity: .55; word-break: break-all; }
.usdt-chip { font-size: 11px; border-radius: 999px; padding: 3px 9px; white-space: nowrap; }
.usdt-chip-ok { background: rgba(52,199,89,.18); color: #34c759; }
.usdt-chip-wait { background: rgba(255,255,255,.12); opacity: .8; }
.usdt-chip-warn { background: rgba(255,159,10,.18); color: #ff9f0a; }

/* 내역 화면(#/history) — 마이페이지의 「충전 내역」·「환전 내역」이 여기로 온다.
   목록 카드(.usdt-item)는 실행 화면과 같은 것을 쓰고, 여기서는 날짜·탭·거르개·
   펼침 상세만 더한다. 날짜는 서버가 계속 보내던 값인데 화면에 없었다. */
.usdt-when { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.usdt-amt.in { color: var(--success); }
.usdt-item.tapable { cursor: pointer; }
.usdt-tabs { display: flex; gap: 6px; margin-bottom: 11px; }
.usdt-tab { flex: 1; padding: 9px; border-radius: 10px; border: 1px solid var(--line);
  background: transparent; color: var(--muted); font-size: 13px; font-weight: 700; }
.usdt-tab.on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-strong); }
.usdt-fchips { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 11px; }
.usdt-fchip { padding: 5px 11px; border-radius: 999px; border: 1px solid var(--line);
  background: transparent; color: var(--muted); font-size: 11.5px; }
.usdt-fchip.on { background: var(--accent-soft); border-color: var(--accent-line);
  color: var(--accent-strong); font-weight: 700; }
.usdt-det { border-top: 1px solid var(--line-soft); margin-top: 7px; padding-top: 7px;
  display: flex; flex-direction: column; gap: 3px; }
.usdt-det-row { display: flex; justify-content: space-between; gap: 10px; font-size: 11.5px; }
.usdt-det-row .k { color: var(--muted); }
.usdt-det-row .v { word-break: break-all; text-align: right; }
.usdt-copy { font-size: 10.5px; color: var(--accent-strong); border: 1px solid var(--accent-line);
  border-radius: 6px; padding: 2px 8px; background: transparent; }
.usdt-more { width: 100%; text-align: center; font-size: 12px; color: var(--accent-strong);
  padding: 10px; border: 1px solid var(--accent-line); border-radius: 10px;
  background: var(--accent-soft); }

/* ── 충전 · 환전 단계 · 문의 ────────────────────────────────────────
   돈이 오가는 화면은 한 번에 하나씩 보여 준다. 사고는 어려워서가 아니라
   순서를 건너뛰어서 나기 때문이다. */
.usdt-steps { display: flex; flex-direction: column; gap: 7px; margin: 0 0 14px; }
.usdt-step { display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 13px; background: var(--panel); }
.usdt-step.on { border-color: var(--accent-line); background:
  radial-gradient(80% 130% at 88% 30%, rgba(225, 181, 79, .13), transparent 62%), var(--panel); }
.usdt-step.done { opacity: .82; }
.usdt-step-n { flex: none; width: 21px; height: 21px; border-radius: 50%; font-style: normal;
  display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700;
  background: var(--panel2); color: var(--muted); }
.usdt-step.on .usdt-step-n { background: #d9b45f; color: #241a05; }
.usdt-step.done .usdt-step-n { background: #14402c; color: #7fdca5; }
.usdt-step b { display: block; font-size: 13px; }
.usdt-step span span, .usdt-step > span > span { display: block; font-size: 11px; color: var(--muted); }
.usdt-step-edit { margin-left: auto; flex: none; background: none; border: 0; padding: 2px 4px;
  color: var(--muted); font-size: 11px; text-decoration: underline; cursor: pointer; }

.usdt-preview { font-size: 12.5px; color: #f2ce76; margin: 6px 0 0; min-height: 1.2em; }
/* 충전 보너스 — .ev-mine 과 같은 톤(금색 테두리). 원금(초록)과 갈라 읽힌다. */
.usdt-bonus { display: flex; align-items: center; gap: 8px; border: 1px solid var(--accent-line); background: var(--accent-soft);
  border-radius: 10px; padding: 8px 10px; font-size: 12px; color: var(--accent-strong); font-weight: 700; }
.usdt-bonus.dim { opacity: .72; } /* 매일 충전 — 아직 주기가 안 됐을 때 안내만 */
.usdt-bonus > span { white-space: nowrap; }
/* 보조 문구가 접힌다 — 본문(+10%)이 두 줄이 되는 것보다 낫다. 375px 에서 실측. */
.usdt-bonus small { font-weight: 400; color: var(--muted); margin-left: auto; font-size: 11px; text-align: right; line-height: 1.3; }
.usdt-bonus-line { font-size: 12px; color: var(--accent-strong); font-weight: 700; }
.ev-thumb-emoji { display: flex; align-items: center; justify-content: center; font-size: 28px; background: var(--accent-soft); }
.usdt-err { font-size: 12px; color: #ff9a9e; margin: 5px 0 0; }
.usdt-row.strong { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 9px; }
.usdt-row.strong .usdt-row-v { font-size: 17px; font-weight: 800; color: #f2ce76; }
.usdt-addr-check { font-size: 11.5px; color: var(--muted); margin: 6px 0 0; line-height: 1.6; }
.usdt-addr-pick { display: block; width: 100%; text-align: left; border: 1px solid var(--line);
  border-radius: 11px; background: var(--panel2); padding: 10px 11px; margin: 0 0 7px; cursor: pointer; }
.usdt-addr-pick.on, .usdt-addr-pick:active { border-color: var(--accent-line); }
.usdt-addr-pick code { font-size: 11px; color: var(--text); word-break: break-all; }

/* 문의 */
.sup-wrap { padding: 4px 0 24px; }
.sup-head h2 { font-size: 19px; margin: 0 0 5px; }
.sup-head p { font-size: 13px; color: var(--muted); margin: 0 0 14px; }
.sup-cta { display: block; text-align: center; border-radius: 13px; padding: 13px;
  font-weight: 800; font-size: 14.5px; color: #241a05; text-decoration: none;
  background: linear-gradient(135deg, #f1cf73, #bf7d18); box-shadow: var(--shadow-sm); }
.sup-note { text-align: center; font-size: 11.5px; color: var(--muted); margin: 7px 0 0; }
.sup-sec { font-size: 12px; color: var(--muted); margin: 22px 0 8px; font-weight: 700; }
.sup-faq { border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--panel); overflow: hidden; }
.sup-item + .sup-item { border-top: 1px solid var(--line); }
.sup-q { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: 0; color: var(--text); font-size: 13.5px; padding: 13px 14px;
  cursor: pointer; font-family: inherit; }
.sup-q span { flex: 1; }
.sup-caret { flex: none; font-style: normal; color: #d9b45f; font-size: 14px; }
.sup-item.open .sup-q { color: #f2ce76; }
.sup-a { padding: 0 14px 13px; font-size: 12.5px; line-height: 1.75; color: var(--muted); }
/* 문의 연결 대상 — 어디로 가는지 눌러 보기 전에 보인다(탭하면 복사). */
.sup-handle { display: block; margin: 8px auto 0; background: none; border: 0;
  color: #d9b45f; font-size: 13px; font-family: inherit; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; }
.sup-alt { display: block; margin: 14px auto 0; background: none; border: 1px solid var(--line);
  border-radius: 11px; padding: 9px 14px; color: var(--muted); font-size: 12.5px;
  font-family: inherit; cursor: pointer; }
.sup-note.sup-ok { color: #7fdca5; }
.sup-note.sup-bad { color: #ff9a9e; }

/* ── 경기별 스코어 + 채팅방 (고급형 전용) ──────────────────────────────
   선택자는 전부 .mr- 로 시작한다. 기존 규칙은 한 줄도 안 고친다 — 이 파일은
   79TV 두 업체가 같이 쓰고, 예전에 기존 규칙을 토큰으로 바꿨다가 그 업체들의
   첫 화면이 무너질 뻔했다. 새 이름만 더하면 안 쓰는 셸에서는 아무 일도 없다.

   색은 테마 토큰에서 온다. 진영 색(--mr-home/--mr-away)만 여기서 정하고
   .mr-wrap 안에 가둔다 — 밖으로 새면 다른 화면의 색을 건드린다. */
.mr-wrap { --mr-home: var(--accent-strong, #f0b429); --mr-away: #4aa3ff;
  display: flex; flex-direction: column; gap: 12px; padding: 2px 0 14px; }

.mr-sb { padding: 12px 14px 14px; border: 1px solid var(--line); border-radius: var(--radius-md, 14px);
  background: radial-gradient(125% 135% at 50% 0%, rgba(var(--accent-rgb, 217, 180, 95), .13), transparent 62%),
    var(--panel2); }
.mr-sb-top { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.mr-league { color: var(--muted); font-size: 10.5px; font-weight: 750; letter-spacing: .04em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mr-state { margin-left: auto; flex: none; display: inline-flex; align-items: center; gap: 5px;
  color: var(--muted); font-size: 10.5px; font-weight: 800; }
.mr-state.is-live { padding: 3px 8px; border-radius: 999px;
  background: rgba(229, 72, 77, .14); color: #ff8a8e; }
.mr-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--live, #e5484d);
  animation: mrBlink 1.2s infinite; }
@keyframes mrBlink { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .mr-dot { animation: none; } }

.mr-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; }
.mr-team { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
/* keep-all — 한글은 단어 중간에서 끊지 않는다. 없으면 '인천 현대제철 레드엔젤스'
   가 '…레드엔젤 / 스' 로 갈려 마지막 한 글자만 다음 줄에 남는다(실측). */
.mr-team-name { font-size: 11.5px; font-weight: 750; text-align: center; line-height: 1.3;
  word-break: keep-all; overflow-wrap: anywhere;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; }
.mr-badge, .mr-logo { width: 42px; height: 42px; border-radius: 50%; flex: none; }
.mr-badge { display: inline-flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 900; font-style: normal; background: var(--panel);
  border: 2px solid var(--line); }
/* 폴백을 붙인다. --mr-* 는 .mr-wrap 안에서만 선언되므로 지금은 항상 풀리지만,
   폴백 없는 var() 는 값이 없으면 **선언 전체가 무효**가 되어 테두리가 통째로
   사라진다 — 공용 app.css 에서 그 사고를 이미 겪었다. */
.mr-badge.mr-home { border-color: var(--mr-home, #f0b429); color: var(--mr-home, #f0b429); }
.mr-badge.mr-away { border-color: var(--mr-away, #4aa3ff); color: var(--mr-away, #4aa3ff); }
.mr-logo { object-fit: contain; background: var(--panel); border: 1px solid var(--line); }

/* 경기장 보드 — 잔디·흙은 테마와 무관한 실제 경기장 색(종목 정체성)이라 고정값,
   틀·글자만 테마 토큰을 쓴다. SVG 는 line-height 여백이 붙지 않게 블록으로. */
.mr-field { margin-top: 10px; border-radius: 10px; overflow: hidden; line-height: 0; }
.mr-field svg { width: 100%; height: auto; display: block; }
.mr-innings { margin-top: 8px; overflow-x: auto; }
.mr-innings table { width: 100%; border-collapse: collapse; text-align: center;
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--text); }
.mr-innings th { color: var(--muted); font-weight: 700; padding: 3px 0; font-size: 10px; }
.mr-innings td { padding: 3.5px 0; border-top: 1px solid var(--line); }
.mr-innings .tm { font-weight: 800; text-align: left; padding-left: 6px; max-width: 52px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mr-innings td.mr-home { color: var(--mr-home, #f0b429); }
.mr-innings td.mr-away { color: var(--mr-away, #4aa3ff); }
.mr-innings .cur { background: rgba(var(--accent-rgb, 217, 180, 95), .16); font-weight: 800; }
.mr-innings .r { font-weight: 900; }

/* 보드 헤더(서랍용) — 시작 전에도 팀·엠블럼·상태가 먼저 선다 */
.mr-bh-top { display: flex; align-items: center; gap: 8px; margin-top: 10px;
  font-size: 11px; color: var(--muted); }
.mr-bh-badge { font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 7px; }
.mr-bh-badge.is-live { background: var(--live, #e5484d); color: #fff; }
.mr-bh-badge.is-upcoming { background: var(--panel); color: var(--muted); border: 1px solid var(--line); }
.mr-bh-badge.is-done { background: var(--panel); color: var(--muted); border: 1px solid var(--line); }
.mr-bh-league { color: var(--text); font-size: 11.5px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.mr-bh-state { margin-left: auto; font-variant-numeric: tabular-nums; }
.mr-bh-teams { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 8px; margin-top: 8px; }
.mr-bh-team { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
.mr-bh-mid { text-align: center; flex: none; min-width: 86px; }
.mr-bh-score { font-size: 24px; font-weight: 900; font-variant-numeric: tabular-nums; }
.mr-bh-vs { font-size: 19px; font-weight: 900; color: var(--muted); }
.mr-bh-sub { font-size: 11px; font-weight: 700; color: var(--accent, #f0b429); margin-top: 1px; }

/* 타임라인 칸 — 제목 줄 + (이벤트 | 빈 틀 안내). 틀이 먼저, 내용은 나중에 */
.mr-tlbox { margin-top: 8px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel); overflow: hidden; }
.mr-tlbox .mr-tl { margin-top: 0; padding: 4px 6px; }
.mr-tl-head { display: flex; justify-content: space-between; align-items: center;
  padding: 7px 10px; font-size: 11px; color: var(--text); font-weight: 700;
  border-bottom: 1px solid var(--line); }
.mr-tl-head i { font-style: normal; color: var(--muted); font-weight: 400; font-size: 10.5px; }
.mr-tl-empty { padding: 13px 10px; text-align: center; font-size: 11.5px; color: var(--muted); }

/* KBO 중계판 — 투수 | B/S/O | 타자. 데이터(네이버 relay)가 있을 때만 그려진다 */
.mr-relay { margin-top: 8px; display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 10px; background: var(--panel);
  border: 1px solid var(--line); font-size: 11.5px; color: var(--text); }
.mr-relay .mr-who { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mr-relay .mr-who.right { text-align: right; }
.mr-relay .mr-who small { color: var(--muted); font-size: 10px; }
.mr-relay .mr-who b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mr-cnts { display: flex; flex-direction: column; gap: 3px; flex: none; }
.mr-cnt { display: flex; align-items: center; gap: 3px; }
.mr-cnt b { font-size: 9.5px; color: var(--muted); width: 10px; }
.mr-dot2 { width: 8px; height: 8px; border-radius: 50%; background: var(--line); }
.mr-dot2.on-b { background: #4cc38a; }
.mr-dot2.on-s { background: #f5c451; }
.mr-dot2.on-o { background: #ff5d5d; }

/* 축구 타임라인 — 홈 왼쪽 · 원정 오른쪽. 줄만 훑어도 두 팀 흐름이 갈린다.
   높이를 잠근다: 풀타임이면 17~25행이라, 안 잠그면 후반에 들어온 유저의 첫
   화면에서 이 방의 본 기능(채팅·입력창)이 타임라인 벽 아래로 밀려난다. */
.mr-tl { margin-top: 8px; display: flex; flex-direction: column; gap: 2px;
  max-height: 216px; overflow-y: auto; }
.mr-tl-ev { display: flex; align-items: center; gap: 7px; padding: 2.5px 4px;
  font-size: 12px; color: var(--text); }
.mr-tl-ev.is-away { flex-direction: row-reverse; }
.mr-tl-min { color: var(--muted); font-variant-numeric: tabular-nums;
  min-width: 32px; text-align: right; flex: none; }
.mr-tl-ev.is-away .mr-tl-min { text-align: left; }
.mr-tl-ico { flex: none; }
.mr-tl-who { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mr-mid { display: flex; flex-direction: column; align-items: center; gap: 2px; flex: none; }
.mr-score { font-size: 26px; font-weight: 900; letter-spacing: .01em; font-variant-numeric: tabular-nums;
  white-space: nowrap; color: var(--muted); }
.mr-score b { color: var(--text); }
.mr-noscore { font-size: 11px; font-weight: 800; color: #ff8a8e; white-space: nowrap; }

.mr-empty { text-align: center; color: var(--muted); font-size: 13px; padding: 40px 18px; }
.mr-back { display: block; margin: 14px auto 0; background: none; border: 1px solid var(--line);
  border-radius: 11px; padding: 9px 14px; color: var(--muted); font-size: 12.5px;
  font-family: inherit; cursor: pointer; }

/* ── 경기방 M4: 응원 게이지 · 진영 고르기 · 목록 입구 ─────────────────
   위 블록과 같은 규칙 — 선택자는 전부 .mr- 다. 목록 카드에 붙는 .mr-tap /
   .mr-enter 도 .ls- 가 아니라 .mr- 인 것은 의도다: 이 이름들은 고급형에서만
   붙고, 네임스페이스 가드가 한 블록으로 전부 본다. */
.mr-cheer { display: flex; align-items: center; gap: 8px; }
.mr-side { display: inline-flex; align-items: center; gap: 5px; flex: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: 999px;
  padding: 6px 11px; color: var(--muted); font-family: inherit; font-size: 11.5px;
  font-weight: 800; cursor: pointer; }
.mr-side b { font-variant-numeric: tabular-nums; color: var(--text); }
.mr-side.mr-home.is-mine { border-color: var(--mr-home, #f0b429); color: var(--mr-home, #f0b429); }
.mr-side.mr-away.is-mine { border-color: var(--mr-away, #4aa3ff); color: var(--mr-away, #4aa3ff); }
.mr-check { font-size: 10px; }
.mr-bar { flex: 1; height: 9px; border-radius: 999px; overflow: hidden; min-width: 40px;
  background: var(--mr-away, #4aa3ff); }
.mr-bar-home { height: 100%; background: var(--mr-home, #f0b429); transition: width .35s ease; }
@media (prefers-reduced-motion: reduce) { .mr-bar-home { transition: none; } }

/* 모달은 document.body 에 붙는다(화면 전체를 덮어야 하므로). 그래서 .mr-wrap
   **밖**이고, 거기 선언한 진영 색이 안 닿는다 — 게이지는 테마 강조색인데 모달만
   금색으로 굳는 어긋남이 생긴다. 로비 카드에서 한 번 겪은 그 실수다. 같은
   토큰을 여기에도 선언한다. */
.mr-pick-back { --mr-home: var(--accent-strong, #f0b429); --mr-away: #4aa3ff;
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: center;
  justify-content: center; padding: 22px; background: rgba(0, 0, 0, .62); }
.mr-pick { width: 100%; max-width: 320px; background: var(--panel2); border: 1px solid var(--line);
  border-radius: var(--radius-lg, 22px); padding: 20px 18px 16px; text-align: center; }
.mr-pick h3 { margin: 0 0 6px; font-size: 15.5px; font-weight: 800; color: var(--text); }
.mr-pick p { margin: 0 0 16px; font-size: 11.5px; color: var(--muted); line-height: 1.55; }
.mr-pick-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mr-pick-btn { display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 14px 8px; border-radius: var(--radius-md, 14px); background: var(--panel);
  border: 2px solid var(--line); font-family: inherit; cursor: pointer; min-width: 0; }
.mr-pick-btn.mr-home { border-color: var(--mr-home, #f0b429); }
.mr-pick-btn.mr-away { border-color: var(--mr-away, #4aa3ff); }
.mr-pick-short { font-size: 19px; font-weight: 900; }
.mr-pick-btn.mr-home .mr-pick-short { color: var(--mr-home, #f0b429); }
.mr-pick-btn.mr-away .mr-pick-short { color: var(--mr-away, #4aa3ff); }
.mr-pick-name { font-size: 10.5px; color: var(--muted); word-break: keep-all;
  overflow-wrap: anywhere; line-height: 1.35; }
.mr-pick-skip { display: block; margin: 14px auto 0; background: none; border: 0;
  color: var(--muted); font-family: inherit; font-size: 11.5px; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; }

.mr-tap { cursor: pointer; }
.mr-enter { margin-top: 8px; font-size: 10px; font-weight: 800; letter-spacing: .02em;
  color: var(--accent-strong); text-align: right; }

/* ── 경기방 M5: 대화 ─────────────────────────────────────────────
   여기도 선택자는 전부 .mr- 다. 진영 색(--mr-home/away)은 .mr-wrap 에서
   내려온다 — 대화 패널은 모달과 달리 .mr-wrap **안**이라 다시 선언하지 않는다.
   그래도 var() 폴백은 붙인다: 값이 없으면 선언 전체가 무효가 되어 배지가
   통째로 사라지기 때문이다. */
.mr-chat { display: flex; flex-direction: column; border: 1px solid var(--line);
  border-radius: var(--radius-md, 14px); background: var(--panel2); overflow: hidden; }
/* 목록만 스크롤한다. overscroll-behavior 가 없으면 목록 끝에서 계속 밀 때
   페이지가 따라 움직여 대화 중에 화면이 튄다. */
.mr-msgs { display: flex; flex-direction: column; gap: 10px; padding: 12px;
  min-height: 180px; max-height: 46dvh; overflow-y: auto; overscroll-behavior: contain; }
.mr-msg { display: flex; flex-direction: column; gap: 3px; }
.mr-msg-head { display: flex; align-items: center; gap: 6px; min-width: 0; }
.mr-msg-side { flex: none; font-style: normal; font-size: 9.5px; font-weight: 900;
  line-height: 1; padding: 3px 6px; border-radius: 999px; border: 1px solid currentColor;
  max-width: 76px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mr-msg-side.mr-home { color: var(--mr-home, #f0b429); }
.mr-msg-side.mr-away { color: var(--mr-away, #4aa3ff); }
.mr-msg-who { font-size: 11px; font-weight: 800; color: var(--text); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mr-msg-time { margin-left: auto; flex: none; font-size: 9.5px; color: var(--muted);
  font-variant-numeric: tabular-nums; }
.mr-msg-quote { font-size: 10.5px; color: var(--muted); line-height: 1.4;
  padding: 5px 8px; border-left: 2px solid var(--line); background: var(--panel);
  border-radius: 0 8px 8px 0; overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
/* 한글은 단어 중간에서 끊지 않는다(팀명에서와 같은 이유). 붙여쓴 긴 URL 은
   anywhere 로 강제로 접어 가로 스크롤을 막는다. */
.mr-msg-body { font-size: 13px; line-height: 1.5; color: var(--text);
  word-break: keep-all; overflow-wrap: anywhere; }
.mr-msg.is-me .mr-msg-who { color: var(--accent-strong); }

.mr-send { display: flex; gap: 8px; padding: 9px 10px; border-top: 1px solid var(--line-soft, var(--line)); }
.mr-input { flex: 1; min-width: 0; background: var(--panel); border: 1px solid var(--line);
  border-radius: 999px; padding: 9px 13px; color: var(--text); font-family: inherit;
  font-size: 13px; }
.mr-input::placeholder { color: var(--muted); }
.mr-input:disabled { opacity: .75; cursor: not-allowed; }
.mr-send-btn { flex: none; border: 0; border-radius: 999px; padding: 9px 15px;
  background: var(--accent-strong, #f0b429); color: var(--on-accent, #17130a);
  font-family: inherit; font-size: 12.5px; font-weight: 900; cursor: pointer; }
.mr-chat.is-locked .mr-send-btn { opacity: .45; pointer-events: none; }
.mr-msgs-empty { margin: auto; text-align: center; color: var(--muted); font-size: 11.5px; }
.mr-more { align-self: center; flex: none; background: none; border: 1px solid var(--line);
  border-radius: 999px; padding: 5px 12px; color: var(--muted); font-family: inherit;
  font-size: 10.5px; font-weight: 800; cursor: pointer; }
.mr-more:disabled { opacity: .5; cursor: default; }
.mr-top { display: flex; flex-direction: column; gap: 12px; }
/* 보낸 말은 서버가 되돌려 줄 때까지 흐리게 남는다. 못 보낸 것은 지우지 않는다 —
   사라지는 것이 이 버그의 본체였다. */
.mr-msg.is-pending { opacity: .55; }
.mr-msg.is-failed .mr-msg-time { color: #ff8a8e; }
.mr-msg.is-failed .mr-msg-body { opacity: .7; }

/* ── 경기방 CSS 끝 ─────────────────────────────────────────────
   위쪽 블록은 전부 .mr- 여야 한다(가드가 여기까지만 본다). 다른 화면 규칙은
   이 아래에 둔다. */

/* ── 고급형 로비 아트: 오른쪽으로 더 민다 ─────────────────────────
   기본값 translateX(-21%) 는 79TV 그림에 맞춘 값이다. 그 그림들은 주제가
   오른쪽 끝에 앉아 있어 왼쪽으로 당겨야 카드 안에 들어온다.

   고급형 그림은 생성기가 다르게 그려서 주제가 원본 50~80% 에 앉는다. 그대로
   당기면 제목이 덮는 띠(원본 12~73%)와 겹친다 — 실측으로 그 구간의 밝은
   픽셀이 34% 였고, 79TV 는 0% 다. 스크림으로 누르면 주제까지 죽으므로
   그림을 미는 쪽이 맞다. 덜 당기면 오른쪽에 남던 빈 띠(21%)도 같이 사라진다.

   실측(제목 자리 밝은 픽셀 / 오른쪽 빈 띠):
     -21%(기본) 9%·8% / 21%      -4%  2%·5% / 4%
     -2%        1%·4% / 2%       0%   1%·3% / 0%   ← 79TV 는 0% / 0%

   79TV 는 이 선택자에 안 걸린다. */
body.menu-profile-gametv .lobby-card-art.is-raster img { transform: none; }
/* 그림을 오른쪽으로 민 대가로 카드 아래쪽 CTA(「들어가기 ›」)가 밝은 부분 위에
   올라온다 — 실측 평균 밝기가 79TV 의 2~13 대비 13~30 이었다. 아래 띠만 눌러
   글자 자리를 되찾는다. 위쪽 제목은 이미 어두우므로 건드리지 않는다.
   .is-raster::after 는 공용 규칙에서 꺼져 있어, 여기서 고급형만 다시 켠다. */
body.menu-profile-gametv .lobby-card-art.is-raster::after {
  display: block;
  background: linear-gradient(0deg, rgba(var(--bg-rgb, 10, 10, 14), .92) 0%,
    rgba(var(--bg-rgb, 10, 10, 14), .55) 16%, rgba(var(--bg-rgb, 10, 10, 14), .12) 32%, transparent 46%);
}

/* 브랜드가 정해지기 전에는 헤더 로고·제목을 감춘다. index.html 의 부트 스크립트가
   지난 실행의 메뉴 구성을 보고 이 클래스를 붙이고, core.js 가 로고를 갈아끼운 뒤
   뗀다. 감추는 것은 남의 브랜드가 잠깐 보이는 것보다 낫다 —
   기본형(79TV)만 쓰는 기기는 이 클래스가 붙지 않아 지금과 똑같이 곧바로 보인다.
   여러 업체 봇을 번갈아 쓰는 기기는(boot-unsure) 기본형도 설정이 올 때까지 가린다. */
html.brand-swap-pending .brand-glow,
html.brand-swap-pending .header-title-text { visibility: hidden; }
/* 하단 메뉴도 같이 — 헤더만 가리면 베트남어 기본형 메뉴가 그대로 보인다.
   display:none 이 아니라 visibility 인 이유: 자리를 지켜야 화면이 안 튄다. */
html.brand-swap-pending .bottom-nav { visibility: hidden; }

/* 베트남어가 아닌 테마 셸은 하단 메뉴 글자가 베트남어로 박혀 있다(생성기가
   메뉴 글자는 안 바꾼다). 기본형이면 위 가림막도 안 붙어서, 언어 파일이 올
   때까지 매번 베트남어 메뉴가 보였다. core.js 가 사전을 입히며 i18n-ready 를
   붙일 때까지 감춘다.
   · 공용 셸은 lang="vi" 라 이 규칙에 안 걸린다.
   · 동결된 옛 테마 셸도 이 CSS 는 공용에서 받는다 — 그래서 **스스로 풀린다.**
     옛 core.js 가 캐시에 남아 i18n-ready 를 안 붙이는 기기도, 이 규칙이 걸린
     때(가림막이 없거나 걷힌 때)부터 3초 뒤엔 보인다.
   · 가림막(brand-swap-pending)이 붙어 있는 동안은 그쪽이 맡는다 — 이 규칙의
     3초 풀림이 그 가림막까지 걷어 버리면 안 된다.
   · .bottom-nav 가 아니라 #bottomNav 인 이유: 데모 페이지(preview.html)의 메뉴는
     id 가 없고 core.js 도 없어서 i18n-ready 가 영영 안 붙는다.
   · 나중에 '움직임 줄이기' 로 animation 을 전부 끄는 규칙을 넣으면 이 규칙은 빼야
     한다 — 풀림 장치가 꺼져 메뉴가 영영 안 보인다. */
html:not([lang="vi"]):not(.i18n-ready):not(.brand-swap-pending) #bottomNav {
  visibility: hidden;
  animation: i18nNavFailOpen 0s linear 3s forwards;
}
@keyframes i18nNavFailOpen { to { visibility: visible; } }

/* ── 마이페이지 (고급형 전용) ─────────────────────────────────────
   선택자는 전부 .mp- 다. app.css 는 세 업체가 같이 쓰므로, 이 화면이 기존
   화면의 규칙을 건드리지 않는다는 것이 이름만으로 보여야 한다. */
.mp-wrap { display: flex; flex-direction: column; gap: 12px; padding: 2px 0 16px; }

.mp-prof { display: flex; align-items: center; gap: 12px; }
.mp-ava { width: 52px; height: 52px; border-radius: 50%; flex: none; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(80% 80% at 50% 20%, rgba(var(--accent-rgb, 217, 180, 95), .3), transparent 70%), var(--panel2);
  border: 2px solid var(--accent-strong); color: var(--lc-hi, var(--accent-strong));
  font-size: 20px; font-weight: 900; }
.mp-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 사진 동그라미는 버튼이다 — 📷 표식이 「눌러서 바꾼다」를 말한다. GIF 는 그대로 움직인다. */
.mp-ava-wrap { position: relative; flex: none; }
.mp-ava { padding: 0; cursor: pointer; font: inherit; }
.mp-ava-letter { font-size: 20px; font-weight: 900; color: var(--lc-hi, #f2ce76); }
.mp-ava-badge { position: absolute; right: -3px; bottom: -3px; width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 10px; line-height: 1; pointer-events: none;
  background: var(--panel2, #1e1e23); border: 1px solid var(--accent-line, rgba(217, 180, 95, 0.32)); }
.mp-ava:active { transform: scale(.96); }
.mp-who { min-width: 0; }
.mp-name { font-size: 17px; font-weight: 850; letter-spacing: -.02em; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mp-uid { margin-top: 3px; font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.mp-edit { margin-left: auto; flex: none; background: none; border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 12px; color: var(--muted); font-family: inherit;
  font-size: 11px; font-weight: 700; cursor: pointer; }

.mp-bal { border: 1px solid var(--line); border-radius: var(--radius-md, 14px); padding: 15px 16px 14px;
  background: radial-gradient(120% 130% at 50% 0%, rgba(var(--accent-rgb, 217, 180, 95), .13), transparent 62%), var(--panel2); }
.mp-bal-k { font-size: 10px; font-weight: 850; letter-spacing: .1em; color: var(--lc-hi, var(--accent-strong)); }
/* 잔액은 이 화면에서 가장 큰 글자다(A안). tabular-nums 로 자릿수가 흔들리지
   않게 한다 — 폴링으로 값이 바뀔 때 글자가 덜컹거린다. */
.mp-bal-v { margin-top: 7px; font-size: 31px; font-weight: 900; letter-spacing: -.03em;
  line-height: 1; color: var(--text); font-variant-numeric: tabular-nums; }
.mp-bal-v small { margin-left: 4px; font-size: 15px; font-weight: 800; color: var(--muted); }
.mp-bal-sub { margin-top: 6px; font-size: 11px; color: var(--muted); }
.mp-bal-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin-top: 14px; }
.mp-btn { padding: 11px 0; border-radius: 11px; text-align: center; font-family: inherit;
  font-size: 12.5px; font-weight: 850; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--text); }
/* 폴백을 붙인다 — 값 없는 var() 는 선언 전체를 무효로 만들어 버튼이 통째로
   민무늬가 된다(로비 카드에서 겪은 그 사고). */
.mp-btn.is-primary { border-color: var(--accent-strong, #e6bf63);
  background: linear-gradient(180deg, var(--accent-strong, #f0c974), var(--accent, #d9a83e));
  color: var(--on-accent, #1a1408); }
.mp-btn.is-off { opacity: .5; }

/* 칸 수는 내용에 따라 달라진다(룰렛을 뺀 뒤 2칸). 개수를 박아 두면 한 칸이
   비어 화면이 어긋난다 — 브라우저가 세게 한다. */
.mp-tiles { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 9px; }
.mp-tile { border: 1px solid var(--line); border-radius: 12px; padding: 12px 8px;
  text-align: center; background: var(--panel); font-family: inherit; cursor: pointer; min-width: 0; }
.mp-tile b { display: block; font-size: 19px; font-weight: 900;
  color: var(--lc-hi, var(--accent-strong)); font-variant-numeric: tabular-nums; }
.mp-tile span { display: block; margin-top: 4px; font-size: 10.5px; color: var(--muted);
  font-weight: 700; word-break: keep-all; }

.mp-sec { margin: 6px 0 -4px 2px; font-size: 10px; font-weight: 850;
  letter-spacing: .1em; color: var(--muted); }
.mp-list { border: 1px solid var(--line); border-radius: var(--radius-md, 14px);
  overflow: hidden; background: var(--panel2); }
.mp-item { display: flex; align-items: center; gap: 11px; width: 100%; padding: 13px 14px;
  background: none; border: 0; border-bottom: 1px solid var(--line-soft, var(--line));
  font-family: inherit; text-align: left; cursor: pointer; }
.mp-item:last-child { border-bottom: 0; }
.mp-ico { width: 20px; flex: none; text-align: center; font-style: normal;
  font-size: 14px; color: var(--lc-hi, var(--accent-strong)); }
.mp-lab { font-size: 13px; font-weight: 700; color: var(--text); }
.mp-val { margin-left: auto; font-size: 11.5px; color: var(--muted);
  font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mp-badge { margin-left: auto; flex: none; border-radius: 999px; padding: 2px 8px;
  font-size: 10px; font-weight: 850; background: rgba(var(--accent-rgb, 217, 180, 95), .16);
  color: var(--lc-hi, var(--accent-strong)); }
.mp-arw { flex: none; margin-left: 8px; font-size: 15px; color: var(--line); }
.mp-empty { text-align: center; color: var(--muted); font-size: 13px; padding: 40px 18px; }
/* ── 마이페이지 CSS 끝 ───────────────────────────────────────────
   위쪽 블록은 전부 .mp- 여야 한다(가드가 여기까지만 본다). 다른 화면
   규칙은 이 아래에 둔다. */

/* ── 스포츠 베팅 (betting.js) ───────────────────────────────────────────
   배당 시트·베팅표·내 베팅. 색은 전부 테마 변수를 쓴다 — 업체마다 테마 셸이
   다르므로 여기서 색을 굳히면 한 업체에서만 글씨가 안 보인다. */

/* 베팅 화면 목록 — 라이브스코어와 별개 화면이다(betting.js 헤더 참조).
   ls-* 클래스를 재사용하지 않는다: 두 화면이 서로 다른 이유로 바뀌므로
   공유하면 한쪽을 고칠 때마다 다른 쪽을 확인해야 한다. */
.bet-wrap { padding: 4px 0 20px; }
.bet-head { display: flex; justify-content: flex-end; margin: 0 0 8px; }
.bet-mybtn { background: none; border: 1px solid var(--line); border-radius: 999px;
  padding: 6px 13px; color: var(--muted); font-size: 12px; font-family: inherit; cursor: pointer; }
.bet-mybtn:active { background: var(--panel2); color: var(--text); }
.bet-chips { margin: 0 0 10px; }

/* 도구 줄 — 「리그별」 묶기. 업체 스위치(arena_bet_browse_enabled)를 지난
   업체에만 그려진다. 종목 칩 줄과 나눠 두는 이유는 .bet-chips 가 격자라
   버튼 하나가 줄을 하나 더 만들기 때문이다.

   값은 .ls-group 에서 베꼈지만 클래스는 새로 만든다 — 위 주석의 규칙 그대로.
   두 화면은 서로 다른 이유로 바뀐다. */
.bet-tools { display: flex; align-items: center; gap: 6px; margin: 0 0 10px; }
.bet-tool { flex: 0 0 auto; padding: 6px 11px; border: 1px solid var(--line);
  border-radius: 999px; background: var(--panel); color: var(--muted);
  font-family: inherit; font-size: 11px; font-weight: 750; white-space: nowrap; cursor: pointer; }
.bet-tool.on { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-strong); }
.bet-tool-all { margin-left: auto; }
/* ⭐ 칩은 글자가 아니라 기호 하나라 좌우 여백이 남아 다른 칩보다 커 보인다. */
.bet-tool-fav { padding: 6px 9px; font-size: 12px; line-height: 1; }
.bet-tool-fav.on { border-color: var(--accent-line); background: var(--accent-soft); }

/* 리그 헤더의 별. 헤더 자체가 접기 버튼이라 버튼을 또 넣을 수 없어 span 이다 —
   그래서 손가락이 닿을 크기를 여기서 직접 준다. */
.bet-star { flex: none; width: 30px; min-height: 30px; display: inline-flex;
  align-items: center; justify-content: center; margin-right: -4px;
  color: var(--muted); font-size: 14px; line-height: 1; cursor: pointer; }
.bet-star.on { color: var(--accent-strong); }
/* 왕복 중에는 눌린 것이 먹혔는지 알 수 있어야 한다 — 두 번 누르는 것도 막는다. */
.bet-star.busy { opacity: .45; pointer-events: none; }

/* 목록이 상한에 걸려 잘렸을 때의 한 줄. 카드가 아니라 안내라서 테두리를 안 준다 —
   상자로 그리면 '경기 한 건' 처럼 보인다. */
.bet-cut { margin: 10px 2px 0; color: var(--muted); font-size: 11px; line-height: 1.5; text-align: center; }

/* 리그 헤더. 카드(.bet-ev)가 테두리 있는 상자라, 헤더까지 상자로 만들면 어느
   쪽이 상위인지 안 보인다 — 여기는 테두리 없이 밑줄만.
   높이 42px 는 .bet-main-more 와 같다(손가락이 닿는 최소 크기). */
.bet-lg-head { display: flex; align-items: center; gap: 7px; width: 100%;
  min-height: 42px; margin: 10px 0 0; padding: 6px 4px;
  border: 0; border-bottom: 1px solid var(--line); background: none; color: var(--text);
  font-family: inherit; font-size: 11.5px; font-weight: 800; text-align: left; cursor: pointer; }
.bet-lg-arrow { flex: none; color: var(--accent-strong); font-size: 11px; }
.bet-lg-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 배당처럼 자주 바뀌는 숫자는 아니지만, 리그마다 자릿수가 달라 정렬이 흔들린다. */
.bet-lg-count { flex: none; color: var(--muted); font-size: 11px; font-weight: 700;
  font-variant-numeric: tabular-nums; }

/* 묶음 안에서는 카드 윗줄의 리그 이름이 헤더와 같은 말이다 — 12장이면 12번 반복된다.
   시각은 남긴다: 그게 이 화면에서 카드를 고르는 기준이다. */
.bet-in-group .bet-ev-league { display: none; }
.bet-in-group .bet-ev-when { margin-left: auto; }

/* 행 전체를 눌러 시트로 들어가던 시절의 흔적(오른쪽 '›' 와 눌림 효과)을 걷었다.
   지금 행은 아무 데도 안 간다 — 눌러야 할 것은 배당 칸과 「＋」다. 화살표를
   남겨 두면 '여기 눌러 들어가라' 는 신호가 진짜 버튼과 섞인다.
   오른쪽 여백 22px 도 그 화살표 자리였다. */
.bet-ev { position: relative; border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 12px; margin: 0 0 8px; background: var(--panel2); }
.bet-ev-top { display: flex; align-items: center; gap: 8px; margin: 0 0 7px; }
.bet-ev-league { flex: 1; min-width: 0; font-size: 11px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bet-ev-when { font-size: 11px; color: var(--muted); flex: none; }
.bet-ev-row { display: flex; align-items: center; gap: 8px; }
.bet-ev-team { flex: 1; min-width: 0; font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bet-ev-team.right { text-align: right; }
.bet-ev-vs { flex: none; font-size: 10.5px; color: var(--muted); }

/* 슬립 바(.bet-slipbar)는 도크(.bet-dock)로 대체돼 2026-09-03 에 지웠다.
   JS 어디서도 안 만드는 죽은 규칙이었는데, 도크와 똑같이 정의 없는 변수와
   env(safe-area-inset-bottom) 을 쓰고 있어서 그대로 두면 다음 사람이 살아 있는
   코드로 보고 베낀다. */

/* 시트 */
.bet-sheet-back { position: fixed; inset: 0; z-index: 70; background: rgba(0,0,0,.6);
  display: flex; align-items: flex-end; }
.bet-sheet { width: 100%; max-height: 82vh; display: flex; flex-direction: column;
  border-radius: 16px 16px 0 0; background: var(--panel); border-top: 1px solid var(--line); }
.bet-sheet-head { display: flex; align-items: center; gap: 10px; padding: 13px 15px;
  border-bottom: 1px solid var(--line-soft); }
.bet-sheet-head strong { flex: 1; font-size: 13.5px; line-height: 1.4; }
.bet-sheet-x { background: none; border: 0; color: var(--muted); font-size: 16px;
  padding: 4px 6px; cursor: pointer; font-family: inherit; }
.bet-sheet-body { padding: 13px 15px calc(18px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto; -webkit-overflow-scrolling: touch; }

/* 마켓 */
.bet-market { border: 1px solid var(--line); border-radius: 12px; padding: 10px 11px; margin: 0 0 9px; }
.bet-market-head { display: flex; align-items: center; gap: 8px; margin: 0 0 8px;
  font-size: 12px; font-weight: 700; color: var(--muted); }
.bet-market-off { font-size: 10.5px; font-weight: 600; color: #d9c184;
  border: 1px solid #3a3213; border-radius: 999px; padding: 1px 8px; }
.bet-outcomes { display: flex; gap: 7px; flex-wrap: wrap; }
.bet-pick { flex: 1 1 0; min-width: 92px; display: flex; align-items: center;
  justify-content: space-between; gap: 8px; padding: 10px 11px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel2); color: var(--text);
  font-family: inherit; font-size: 12px; cursor: pointer; }
.bet-pick-name { color: var(--muted); }
.bet-pick-odds { font-size: 13.5px; }
.bet-pick.on { border-color: var(--accent); background: var(--accent); color: #0b0b0d; }
.bet-pick.on .bet-pick-name { color: rgba(0,0,0,.6); }
.bet-pick:disabled { opacity: .4; cursor: default; }

/* 베팅표 */
.bet-slip-list { margin: 0 0 12px; }
.bet-slip-row { display: flex; align-items: center; gap: 9px; padding: 9px 0;
  border-bottom: 1px solid var(--line-soft); }
.bet-slip-txt { flex: 1; min-width: 0; }
.bet-slip-ev { display: block; font-size: 11px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bet-slip-txt b { font-size: 12.5px; }
.bet-slip-odds { font-size: 13.5px; }
.bet-slip-x { background: none; border: 0; color: var(--muted); font-size: 13px;
  padding: 3px 5px; cursor: pointer; font-family: inherit; }

.bet-stake { display: flex; align-items: center; gap: 9px; margin: 0 0 7px; }
.bet-stake > span:first-child { font-size: 12px; color: var(--muted); }
.bet-stake input { flex: 1; min-width: 0; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel2); color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 15px; text-align: right; }
.bet-unit { font-size: 12px; color: var(--muted); }
.bet-note { font-size: 11.5px; color: var(--muted); line-height: 1.7; margin: 0 0 10px; }

.bet-sum { border: 1px solid var(--line); border-radius: 11px; padding: 10px 12px; margin: 0 0 11px; }
.bet-sum-row { display: flex; justify-content: space-between; align-items: baseline; padding: 3px 0; }
.bet-sum-row span { font-size: 12px; color: var(--muted); }
.bet-sum-row b { font-size: 14.5px; }
.bet-sum-win { color: #7fdca5; }
.bet-sum-err { font-size: 12px; color: #ff9a9e; line-height: 1.7; }
.bet-sum-wait { font-size: 12px; color: var(--muted); }

.bet-actions { display: flex; gap: 9px; }
.bet-clear { flex: 0 0 auto; border: 1px solid var(--line); border-radius: 11px;
  padding: 12px 16px; background: none; color: var(--muted); font-family: inherit;
  font-size: 13px; cursor: pointer; }
.bet-place { flex: 1; border: 0; border-radius: 11px; padding: 12px 16px;
  background: var(--accent); color: #0b0b0d; font-family: inherit; font-size: 14px;
  font-weight: 800; cursor: pointer; }
.bet-place:disabled { opacity: .45; cursor: default; }

/* 내 베팅 */
.bet-page { padding: 4px 0 20px; }
.bet-card { border: 1px solid var(--line); border-radius: 13px; padding: 11px 12px; margin: 0 0 10px; }
.bet-card-top { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.bet-card-type { font-size: 11.5px; font-weight: 700; }
.bet-card-when { margin-left: auto; font-size: 11px; color: var(--muted); }
.bet-st { font-size: 10.5px; font-weight: 700; border-radius: 999px; padding: 2px 9px; }
.bet-st-wait { color: var(--muted); border: 1px solid var(--line); }
.bet-st-won  { color: #0b0b0d; background: #7fdca5; }
.bet-st-lost { color: #ffb9bc; border: 1px solid #6a2226; }
.bet-st-void { color: #d9c184; border: 1px solid #3a3213; }
.bet-card-leg { display: flex; align-items: center; gap: 8px; padding: 6px 0;
  border-top: 1px solid var(--line-soft); }
.bet-leg-ev { flex: 1; min-width: 0; font-size: 11.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bet-leg-pick { font-size: 11.5px; }
.bet-leg-odds { font-size: 12.5px; }
.bet-leg-win .bet-leg-pick { color: #7fdca5; }
.bet-leg-lose .bet-leg-pick { color: #ffb9bc; }
.bet-leg-void .bet-leg-pick { color: #d9c184; }
.bet-card-foot { display: flex; align-items: baseline; gap: 10px; padding: 8px 0 0;
  border-top: 1px solid var(--line-soft); margin-top: 4px; font-size: 11.5px; color: var(--muted); }
.bet-card-foot b { margin-left: auto; font-size: 13px; color: var(--text); }

/* ── 베팅 목록: 행 안의 대표 마켓 (1단계) ────────────────────────────
   선택자는 전부 .bet- 다(들어온 베팅 화면과 같은 이름 공간).
   경기를 눌러 시트로 들어가지 않고 여기서 바로 담는다. */
.bet-main { display: flex; align-items: center; gap: 6px; margin-top: 7px; }
/* 칸 수(야구 2칸 · 축구 3칸)에 상관없이 폭을 **균등하게 채운다.**

   처음에는 6칸 격자에 2칸/3칸씩 걸치고 그 구분을 `[style*="--n:2"]` 로 골랐는데,
   브라우저가 인라인 스타일을 `--n: 2;` 로 **공백을 넣어** 직렬화해서 선택자가
   한 번도 안 맞았다 — 야구 행이 폭의 2/3만 채웠다(실측 239 vs 340). 문자열로
   스타일을 맞히는 방식 자체를 버리고, 열 개수를 브라우저가 세게 한다. */
.bet-main-picks { flex: 1; min-width: 0; display: grid;
  grid-auto-flow: column; grid-auto-columns: 1fr; gap: 6px; }
.bet-main-pick { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; min-width: 0; min-height: 42px; padding: 5px 4px;
  background: var(--panel2); border: 1px solid var(--line); border-radius: var(--radius-sm, 9px);
  font-family: inherit; cursor: pointer; }
.bet-main-k { font-size: 9.5px; font-weight: 750; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
/* 배당은 실시간으로 바뀐다. tabular-nums 가 없으면 값이 바뀔 때마다 칸이 덜컹인다. */
.bet-main-v { font-size: 13.5px; font-weight: 850; color: var(--text);
  font-variant-numeric: tabular-nums; }
.bet-main-pick.on { background: var(--accent); border-color: var(--accent-strong); }
.bet-main-pick.on .bet-main-k { color: rgba(13, 11, 6, .72); }
.bet-main-pick.on .bet-main-v { color: var(--accent-on, #0d0b06); }
.bet-main-more { flex: none; width: 26px; min-height: 42px; padding: 0;
  background: var(--panel2); border: 1px solid var(--line); border-radius: var(--radius-sm, 9px);
  color: var(--muted); font-family: inherit; font-size: 13px; font-weight: 800; cursor: pointer; }
.bet-main.is-off .bet-main-off { flex: 1; min-height: 42px; display: flex; align-items: center;
  justify-content: center; border: 1px dashed var(--line); border-radius: var(--radius-sm, 9px);
  color: var(--muted); font-size: 10.5px; font-weight: 700; }
/* ── 2단계: 목록 안에서 펼치기 ───────────────────────────────────────
   시트로 나가지 않고 이 자리에서 다른 마켓을 본다. 접힌 행들과 확실히
   구분돼야 지금 어디를 보고 있는지 알 수 있다 — 왼쪽 금색 선 + 한 단계 어두운
   바탕 + 들여쓰기 셋을 같이 쓴다(하나만으로는 어두운 화면에서 잘 안 보인다). */
.bet-expand { margin: 8px 0 2px; padding: 10px 10px 10px 12px;
  border-left: 3px solid var(--accent); border-radius: 0 var(--radius-sm, 9px) var(--radius-sm, 9px) 0;
  background: rgba(var(--bg-rgb, 10, 10, 14), .55); }
.bet-expand .bet-market + .bet-market { margin-top: 10px; }
.bet-expand-msg { text-align: center; color: var(--muted); font-size: 11.5px; padding: 10px 6px; }
.bet-expand-all { display: block; width: 100%; margin-top: 10px; min-height: 38px;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: var(--radius-sm, 9px); color: var(--lc-hi, var(--accent-strong));
  font-family: inherit; font-size: 11.5px; font-weight: 800; cursor: pointer; }
.bet-main-more.on { background: var(--accent-soft); border-color: var(--accent-line);
  color: var(--lc-hi, var(--accent-strong)); }
/* ── 3단계: 베팅표 도크 ──────────────────────────────────────────────
   접힌 모습은 예전 얇은 바와 같고, 손잡이를 누르면 그 자리에서 펼쳐진다.
   시트로 띄우지 않는 이유는 목록을 떠나지 않기 위해서다 — 금액을 정하고
   베팅하는 동안 위쪽 경기가 계속 보인다. */
/* 하단 메뉴 **위**에 앉는다. 높이는 반드시 토큰으로 잰다 —
   예전엔 `calc(var(--nav-h, 62px) + env(safe-area-inset-bottom, 0px))` 이었는데
   두 값 다 틀렸다. `--nav-h` 는 저장소 어디에도 정의된 적이 없어 언제나 폴백
   62px 이 쓰였고(실제 메뉴는 --bottombar-h = 72px), env(safe-area-inset-bottom)
   은 텔레그램 웹뷰에서 0 으로 나온다(그래서 이 앱은 텔레그램 API 로 직접 재서
   --tg-bottom-inset 에 넣어 둔다 — core.js 의 applyInsets).
   결과는 `겹침 = 10px + 인셋`. 홈 인디케이터가 있는 기기(인셋 34px)에서는
   46px 짜리 도크의 44px 이 메뉴에 묻혀 **배팅창이 안 보였다.**
   같은 자리의 .composer·.reply-bar 가 쓰는 관용구와 맞춘다. */
.bet-dock { position: fixed; left: 0; right: 0; z-index: 40;
  bottom: calc(var(--bottombar-h) + var(--tg-bottom-inset));
  background: var(--panel); border-top: 1px solid var(--accent-line);
  box-shadow: 0 -10px 26px rgba(0, 0, 0, .55);
  display: flex; flex-direction: column; }
.bet-dock-head { display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 14px 8px; background: none; border: 0; font-family: inherit;
  color: var(--text); cursor: pointer; }
.bet-dock-grip { width: 30px; height: 3px; border-radius: 999px; flex: none;
  background: var(--line); font-style: normal; }
.bet-dock-info { display: inline-flex; align-items: baseline; gap: 5px; font-size: 12px; }
.bet-dock-info b { font-size: 15px; font-weight: 900; color: var(--lc-hi, var(--accent-strong));
  font-variant-numeric: tabular-nums; }
.bet-dock-arrow { margin-left: auto; color: var(--muted); font-size: 12px; }
/* 펼친 높이는 화면 절반까지. 더 키우면 목록이 사라져 무엇에 걸고 있는지 안 보인다. */
.bet-dock-body { max-height: 50dvh; overflow-y: auto; overscroll-behavior: contain;
  padding: 2px 14px 14px; }
.bet-chips { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; margin-top: 9px; }
.bet-chip { min-height: 38px; background: var(--panel2); border: 1px solid var(--line);
  border-radius: var(--radius-sm, 9px); color: var(--text); font-family: inherit;
  font-size: 12px; font-weight: 800; cursor: pointer; }
.bet-note-warn { color: var(--live, #e5484d); font-weight: 800; }
/* ── 접힌 도크: 금색 CTA + 예상 당첨금 ────────────────────────────────
   예전에는 손잡이(3px, --line)와 화살표(--muted 12px)가 어두운 바탕과 거의
   같은 색이라 무엇을 눌러야 하는지 안 보였다. 누를 곳을 버튼처럼 만든다. */
.bet-dock { border-top: 2px solid var(--accent); }
.bet-dock-head { padding: 11px 14px; gap: 10px; }
.bet-dock-sum { margin-left: auto; text-align: right; line-height: 1.2; }
/* 금액은 절대 줄바꿈하지 않는다. 접히면 바 높이가 값에 따라 달라져서,
   담을 때마다 아래 바가 위아래로 들썩인다. */
.bet-dock-sum b { display: block; white-space: nowrap; font-size: 13.5px; font-weight: 900;
  color: var(--lc-hi, var(--accent-strong)); font-variant-numeric: tabular-nums; }
.bet-dock-sum span { font-size: 9.5px; font-weight: 700; color: var(--muted); }
.bet-dock-cta { flex: none; display: inline-flex; align-items: center; gap: 5px;
  padding: 9px 15px; border-radius: 999px; font-size: 12.5px; font-weight: 900;
  background: linear-gradient(180deg, var(--accent-strong, #f0cd7d), var(--accent, #d9b45f));
  color: var(--accent-on, #0d0b06); }
/* 예상 당첨금이 없을 때(아직 계산 전)는 버튼이 오른쪽 끝에 붙어야 한다. */
.bet-dock-head > .bet-dock-cta:nth-child(2) { margin-left: auto; }
/* 합계 배당 — 금액 바로 위. 둘은 같은 사실의 두 면이라 붙여 둔다.
   숫자가 바뀌어도 칸이 안 흔들리게 tabular, 줄바꿈은 막는다. */
.bet-dock-odds { display: block; white-space: nowrap; font-size: 10px; font-weight: 800;
  color: var(--lc-hi, var(--accent-strong)); font-variant-numeric: tabular-nums; }
/* 버튼 글자도 접히면 안 된다 — 접히는 순간 바 높이가 달라진다. */
.bet-dock-cta { white-space: nowrap; }
/* 아주 좁은 화면(구형 소형 폰)에서는 '예상 당첨' 설명을 접는다. 금액과 배당은
   남긴다 — 실측상 320px 에서 이 줄 때문에 바가 58→77px 로 커졌다. */
@media (max-width: 344px) {
  .bet-dock-head { gap: 7px; padding-inline: 11px; }
  .bet-dock-cta { padding: 9px 12px; font-size: 11.5px; }
  .bet-dock-sum b { font-size: 12.5px; }
}
/* 갱신 중인 값. 숨기면 바 폭이 들썩이므로 흐리게만 둔다. */
.bet-dock-sum.is-stale { opacity: .38; }

/* ── 보증업체 (광고형) ─────────────────────────────────────── */
.pt-wrap { padding: 4px 2px 24px; }
.pt-title-line { display: flex; align-items: center; gap: 8px; margin: 4px 2px 2px; }
.pt-title-line .pt-logo { height: 26px; width: auto; max-width: 120px; object-fit: contain; display: block; }
.pt-head h2 { margin: 0; font-size: 18px; }
.pt-head p { margin: 0 2px 12px; color: var(--muted, #8a8578); font-size: 11.5px; }
/* 대표 — 가로 스냅 레일. 한 장이 화면 폭을 꽉 채우고, 손으로 넘긴다. */
.pt-hero-zone { position: relative; margin-bottom: 14px; }
.pt-hero { display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; border-radius: 14px; }
.pt-hero::-webkit-scrollbar { display: none; }
.pt-hero-item { position: relative; flex: 0 0 100%; scroll-snap-align: start;
  border: 0; padding: 0; background: none; cursor: pointer; }
/* 대표는 일반의 두 배 높이(3:2). 그림도 그 비율로 받는다 — 3:1 그림을 여기
   넣으면 좌우가 절반씩 잘린다(어드민 권장 문구가 3:2 로 안내한다). */
.pt-hero-item .pt-art { width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  display: block; border-radius: 14px;
  /* 그림이 오기 전(큰 GIF)에도 투명한 구멍 대신 카드 바탕이 보이게 — 목록 카드와 같은 색 */
  background: #131318; }
.pt-ad-tag { position: absolute; right: 8px; top: 8px; background: rgba(0, 0, 0, .55);
  color: #d9c184; font-size: 9.5px; font-weight: 700; padding: 2px 7px; border-radius: 4px; }
.pt-dots { position: absolute; left: 0; right: 0; bottom: 7px; text-align: center; }
.pt-dots i { display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: rgba(255, 255, 255, .35); margin: 0 3px; }
.pt-dots i.on { background: #f2ce76; }
/* 목록 — 등록한 만큼 전부, 세로 스크롤 */
.pt-list { display: flex; flex-direction: column; gap: 10px; }
.pt-card { display: block; width: 100%; text-align: left; border: 1px solid #26262c;
  border-radius: 12px; overflow: hidden; background: #131318; padding: 0; cursor: pointer; }
.pt-card .pt-art { width: 100%; aspect-ratio: 24 / 7; object-fit: cover; display: block; }
.pt-meta { padding: 9px 12px 10px; }
.pt-line { display: flex; align-items: center; gap: 8px; }
.pt-line b { color: #e8e4da; font-size: 13.5px; }
.pt-badge { background: #1c2a17; color: #7ed957; border: 1px solid #2c4a22;
  border-radius: 4px; font-size: 9.5px; font-weight: 800; padding: 1px 6px; }
.pt-go { margin-left: auto; background: linear-gradient(180deg, #ffe9a8, #d9a62a);
  color: #241a05; font-size: 11px; font-weight: 900; border-radius: 8px; padding: 6px 13px; }
.pt-meta p { color: #8a8578; font-size: 11px; margin: 4px 0 0; }

/* ── 라이브스코어 통합채팅 서랍 (고급채팅분리형 전용, livescore.js lsc-*) ──
   B안+꼬리표. 서랍은 fixed 로 하단 내비(z-30) 위, 모달(z-60) 아래에 뜬다.
   목록 쪽은 .lsc-openpad 로 아래 여백을 확보해 카드가 서랍에 안 가린다.
   여기 선택자는 전부 .lsc- 접두사(카드 강조 .ls-card.lsc-sel 포함 lsc- 조건부)
   — 공용 화면 규칙은 하나도 건드리지 않는다. */
.lsc-openpad { padding-bottom: 48vh; padding-bottom: calc(max(44vh, 290px) + 4vh); }
.ls-card.lsc-sel { border-color: var(--accent-line); background: var(--accent-soft); }
.ls-card.lsc-sel .mr-enter { color: var(--accent-strong); font-weight: 800; }
.lsc-drawer { position: fixed; left: 0; right: 0;
  bottom: calc(var(--bottombar-h) + var(--tg-bottom-inset));
  height: 44vh; min-height: 290px; display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-bottom: none;
  border-radius: 16px 16px 0 0; box-shadow: 0 -14px 34px rgba(0, 0, 0, 0.55);
  z-index: 40; }
.lsc-handle { padding: 7px 0 3px; cursor: pointer; flex: none; }
.lsc-handle i { display: block; width: 44px; height: 4px; border-radius: 2px;
  background: var(--line); margin: 0 auto; }
/* 서랍의 경기장 보드 — 채팅 위에 경기장이 먼저 보인다. 서랍은 보드가 있을
   때만 커지고(lsc-tall), 보드 폭을 줄여 세로를 아낀다. 보드 내부(.mr-*)의
   원본 규칙은 경기방 구역에 있다 — 여기는 서랍 맞춤 덮개만. */
.lsc-drawer.lsc-tall { height: 68vh; min-height: 480px; }
.lsc-board { flex: none; overflow-y: auto; max-height: 56%; padding: 0 12px 4px; }
.lsc-board .mr-field { max-width: 300px; margin: 8px auto 0; }
.lsc-board .mr-relay, .lsc-board .mr-innings, .lsc-board .mr-tl { margin-top: 6px; }
.lsc-board .mr-tl { max-height: 132px; }

.lsc-head { display: flex; align-items: center; gap: 8px; padding: 2px 12px 8px;
  border-bottom: 1px solid var(--line-soft); flex: none; }
.lsc-title { color: var(--accent-strong); font-size: 12.5px; font-weight: 800; white-space: nowrap; }
.lsc-watch { color: var(--muted); font-size: 11px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }
.lsc-count { color: var(--success); font-size: 10.5px; font-weight: 700; white-space: nowrap; }
.lsc-close { background: none; border: none; color: var(--muted); font-size: 14px;
  padding: 2px 4px; cursor: pointer; flex: none; }
.lsc-list { flex: 1; overflow-y: auto; padding: 10px 12px; display: flex;
  flex-direction: column; gap: 7px; overscroll-behavior: contain; }
.lsc-m { display: flex; flex-direction: column; align-items: flex-start; max-width: 86%; }
.lsc-m.mine { align-self: flex-end; align-items: flex-end; }
.lsc-nick { color: var(--muted); font-size: 10px; font-weight: 700; margin-bottom: 2px; }
.lsc-tag { display: block; width: fit-content; max-width: 100%;
  background: rgba(88, 129, 216, 0.14); border: 1px solid rgba(88, 129, 216, 0.35);
  color: #8fb3ff; border-radius: 5px; padding: 1px 6px; font-size: 9.5px;
  font-weight: 800; margin-bottom: 3px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.lsc-bubble { background: var(--bubble-other); color: var(--bubble-other-text);
  border-radius: 4px 12px 12px 12px; padding: 6px 10px; font-size: 13px;
  line-height: 1.45; white-space: pre-wrap; word-break: break-word; }
.lsc-m.mine .lsc-bubble { background: var(--bubble-mine); color: var(--bubble-mine-text);
  border-radius: 12px 4px 12px 12px; }
.lsc-bubble.pending { opacity: 0.55; }
.lsc-m.lsc-failed .lsc-bubble { opacity: 0.45; border: 1px solid var(--danger); }
.lsc-m.lsc-failed .lsc-foot { color: var(--danger); }
.lsc-img { max-width: 180px; max-height: 180px; border-radius: 8px; display: block; }
.lsc-foot { color: var(--muted); font-size: 9.5px; margin-top: 2px; }
.lsc-sys { align-self: center; color: var(--muted); font-size: 10.5px;
  background: var(--card-canvas); border-radius: 999px; padding: 3px 10px; }
.lsc-empty { color: var(--muted); font-size: 12px; text-align: center; padding: 24px 0; }
.lsc-inputrow { display: flex; gap: 8px; padding: 8px 12px 10px;
  border-top: 1px solid var(--line-soft); flex: none; align-items: flex-end; }
.lsc-input { flex: 1; background: var(--card-canvas); border: 1px solid var(--line);
  border-radius: 12px; padding: 8px 12px; color: var(--text); font-size: 13px;
  resize: none; max-height: 72px; font-family: inherit; }
.lsc-send { width: 36px; height: 36px; border-radius: 50%; border: none; flex: none;
  background: var(--bubble-mine); color: var(--bubble-mine-text); font-weight: 900;
  font-size: 14px; cursor: pointer; }

/* 통합 채팅 화면(chat.js)의 경기 꼬리표 — 서랍 .lsc-tag 와 같은 생김새.
   79TV 방에는 꼬리표 달린 메시지가 존재할 수 없으므로(서랍이 고급채팅분리형
   전용) 그 화면들에서는 죽은 규칙이다. */
.msg-mtag { display: block; width: fit-content; max-width: 100%;
  background: rgba(88, 129, 216, 0.14); border: 1px solid rgba(88, 129, 216, 0.35);
  color: #8fb3ff; border-radius: 5px; padding: 1px 6px; font-size: 9.5px;
  font-weight: 800; margin-bottom: 3px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.msg.mine .msg-mtag { margin-left: auto; }

/* ── 로비 공지 팝업 (home.js lnp-*, A안 중앙 팝업형) ──
   업체가 어드민에서 켠 공지 1건. z-70: 서랍(40)·경기방 모달(60) 위,
   전역 오버레이(90·95) 아래. 선택자는 전부 .lnp- 접두사. */
.lnp-back { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.6);
  z-index: 70; display: flex; align-items: center; justify-content: center; padding: 24px; }
.lnp-card { width: 100%; max-width: 340px; max-height: 82vh; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--accent-line);
  border-radius: 16px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.7); }
.lnp-img { width: 100%; max-height: 180px; object-fit: cover; display: block; }
.lnp-bd { padding: 15px 16px 12px; }
.lnp-title { font-size: 16.5px; color: var(--accent-strong); margin: 0 0 8px; }
/* 여러 건일 때 — 제목 줄 오른쪽 「1 / 3」, 본문 아래 점. 한 건이면 둘 다 없다. */
.lnp-tr { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.lnp-tr .lnp-title { margin: 0; }
.lnp-cnt { flex: none; font-size: 10.5px; font-weight: 900; color: #241a05; background: var(--accent); border-radius: 999px; padding: 2px 8px; }
.lnp-dots { display: flex; gap: 5px; justify-content: center; margin: 0 0 9px; }
.lnp-dots i { display: block; width: 6px; height: 6px; border-radius: 50%; background: var(--line); }
.lnp-dots i.on { width: 16px; border-radius: 3px; background: var(--accent); }
.lnp-body { font-size: 12.5px; color: var(--text); line-height: 1.65;
  white-space: pre-wrap; word-break: break-word; margin-bottom: 13px; }
.lnp-go { display: block; width: 100%; text-align: center; border: none; cursor: pointer;
  background: var(--bubble-mine); color: var(--bubble-mine-text); font-weight: 900;
  font-size: 13px; border-radius: 10px; padding: 11px 0; margin-bottom: 11px; }
.lnp-foot { display: flex; justify-content: space-between; align-items: center;
  border-top: 1px solid var(--line-soft); margin: 0 -16px; padding: 9px 16px 2px; }
.lnp-hide, .lnp-x { background: none; border: none; cursor: pointer;
  font-size: 11.5px; font-weight: 700; padding: 2px 0; }
.lnp-hide { color: var(--muted); }
.lnp-x { color: var(--text); }

/* ── 문의 화면 공지사항 (support.js, 자주 묻는 질문과 같은 아코디언) ── */
.sup-new { background: #3a1a1d; color: #ff8a90; font-size: 9px; font-weight: 900;
  border-radius: 4px; padding: 1px 6px; margin-left: 6px; flex: none; }
.sup-date { color: var(--muted); font-size: 10px; font-weight: 600; margin-left: 6px; flex: none; }
.sup-a.sup-nbody { white-space: pre-wrap; word-break: break-word; }

/* ── 이벤트 안내 게시판 (events.js evb-*, 응모권 위) + 문의 공지 하이라이트 ── */
.evb-sec { font-size: 12px; color: var(--muted); margin: 4px 0 8px; font-weight: 700; }
.evb-post { border: 1px solid var(--line); border-radius: 13px; background: var(--panel);
  overflow: hidden; margin-bottom: 10px; }
.evb-post.evb-hl, .evb-post.open { border-color: var(--accent-line); }
.evb-img { width: 100%; max-height: 150px; object-fit: cover; display: none; }
.evb-post.open .evb-img { display: block; }
.evb-bd { padding: 11px 13px 12px; }
.evb-tl { display: flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: 800; cursor: pointer; }
.evb-tl span:first-child { flex: 1; min-width: 0; }
.evb-new { background: #3a1a1d; color: #ff8a90; font-size: 9px; font-weight: 900;
  border-radius: 4px; padding: 1px 6px; flex: none; }
.evb-date { color: var(--muted); font-size: 10px; font-weight: 600; flex: none; }
.evb-body { color: var(--muted); font-size: 11.5px; line-height: 1.65; margin: 6px 0 0;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.evb-post.open .evb-body { display: block; -webkit-line-clamp: unset; color: var(--text);
  white-space: pre-wrap; word-break: break-word; }
.evb-more { background: none; border: none; color: var(--accent); font-size: 10.5px;
  font-weight: 800; padding: 7px 0 0; cursor: pointer; }
.sup-item.sup-hl { box-shadow: inset 3px 0 0 var(--accent); }

/* ── 로비 상단 티커 (home.js lnt-*, 로고와 첫 카드 사이 흐르는 광고 한 줄) ── */
.lnt-bar { display: flex; align-items: center; height: 32px; margin: 0 0 12px;
  background: var(--card-canvas); border: 1px solid var(--line-soft);
  border-radius: 10px; overflow: hidden; }
.lnt-tag { flex: none; background: var(--accent); color: var(--accent-on);
  font-size: 9.5px; font-weight: 900; border-radius: 4px; padding: 1px 7px;
  margin: 0 8px; }
.lnt-clip { flex: 1; min-width: 0; overflow: hidden; }
.lnt-rail { display: inline-flex; white-space: nowrap; align-items: center;
  animation: lnt-roll 18s linear infinite; will-change: transform; }
.lnt-item { font-size: 11.5px; font-weight: 700; color: var(--text); cursor: pointer; }
.lnt-sep { color: var(--accent); margin: 0 13px; font-size: 10px; flex: none; }
.lnt-gap { display: inline-block; flex: none; }
@keyframes lnt-roll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .lnt-rail { animation: none; }
}

/* ── 초대 USDT 보상 현황판 (invite.js, B안) — 보상 활성 업체에서만 열린다 ── */
.invite-reward-card { background: var(--panel); border: 1px solid var(--accent-line);
  border-radius: 14px; padding: 13px 14px; margin-top: 12px; }
.invite-reward-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.invite-reward-head strong { font-size: 13px; color: var(--text); }
.invite-reward-per { background: var(--accent-soft); color: var(--accent-strong);
  border-radius: 5px; font-size: 9.5px; font-weight: 900; padding: 2px 7px; }
.invite-reward-grid { display: flex; gap: 8px; margin-bottom: 10px; }
.invite-reward-grid > div { flex: 1; background: var(--card-canvas); border: 1px solid var(--line-soft);
  border-radius: 10px; padding: 8px 10px; min-width: 0; }
.invite-reward-grid span { display: block; font-size: 9.5px; color: var(--muted);
  font-weight: 800; margin-bottom: 3px; white-space: nowrap; }
.invite-reward-grid strong { font-size: 13.5px; font-weight: 900; color: var(--accent-strong);
  white-space: nowrap; }
.invite-reward-claim { display: block; width: 100%; border: none; cursor: pointer;
  background: var(--bubble-mine); color: var(--bubble-mine-text); font-weight: 900;
  font-size: 13.5px; border-radius: 11px; padding: 12px 0; }
.invite-reward-claim:disabled { background: var(--card-canvas); color: var(--muted); cursor: default; }
.invite-reward-note { color: var(--muted); font-size: 10.5px; margin-top: 8px; line-height: 1.5; }
.invite-reward-hist { margin-top: 6px; }
.invite-reward-row { display: flex; align-items: center; gap: 8px; padding: 8px 2px;
  border-top: 1px solid var(--line-soft); font-size: 11.5px; }
.invite-reward-row .irr-nm { flex: 1; min-width: 0; color: var(--text); font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.invite-reward-row .irr-dt { color: var(--muted); font-size: 10px; flex: none; }
.invite-reward-row .irr-st { color: var(--accent-strong); font-weight: 900; font-size: 11px; flex: none; }
.invite-reward-row .irr-st.paid { color: var(--success); }
.invite-reward-row .irr-st.pend { color: var(--muted); font-weight: 700; }

/* ── AI 상담 화면 (cschat.js) ────────────────────────────────────────
   선택자는 전부 .cs- 로 시작한다. 기존 규칙은 한 줄도 안 고친다 — 이 파일은
   79TV 두 업체가 같이 쓰기 때문이다(.mr- 와 같은 원칙). 게다가 이 클래스들은
   상담 스위치를 켠 업체에서만 DOM 에 나타난다(cschat.js 는 cs_enabled 인 업체만
   내려받는다). 안 쓰는 셸에서는 규칙이 붙을 요소 자체가 없다.

   레이아웃: 화면을 세로로 꽉 채우고 가운데 대화만 스크롤한다. 입력칸이 늘
   같은 자리에 있어야 대화 중에 손가락 위치가 안 바뀐다. */
.cs-wrap { display: flex; flex-direction: column;
  /* 화면에서 이 칸이 쓸 수 있는 높이 = 뷰포트 − 위아래 고정물.
       88px  = 헤더 54px + #app 세로 여백 34px(12+22)
       나머지는 토큰: 텔레그램 칩 밴드, 하단 메뉴, 하단 인셋
     처음엔 헤더만 어림잡아 56px 로 뺐다가 10px 이 모자라, 「직원 연결」 버튼이
     하단 메뉴에 가려 **눌리지 않았다**. 상담을 못 넘기는 상담창이 된다. */
  height: calc(100dvh - 88px - var(--tg-content-top) - var(--bottombar-h) - var(--tg-bottom-inset));
  min-height: 320px; margin: 0 -2px; }

/* 상단 띠 — 지금 누구와 말하고 있는지. 상태가 바뀌면 색이 바뀐다. */
.cs-status { display: flex; align-items: center; gap: 8px; flex: none;
  padding: 8px 2px 10px; border-bottom: 1px solid var(--line-soft); }
.cs-pill { font-size: 10.5px; font-weight: 800; border-radius: 999px; padding: 3px 9px;
  background: var(--panel2); color: var(--muted); }
.cs-pill-ai { background: linear-gradient(180deg, #f0cd7d, #d9b45f); color: #0d0b06; }
.cs-pill-wait { background: rgba(217, 164, 65, 0.16); color: var(--warn);
  border: 1px solid rgba(217, 164, 65, 0.4); }
.cs-pill-live { background: rgba(95, 191, 139, 0.16); color: var(--success);
  border: 1px solid rgba(95, 191, 139, 0.4); }
.cs-who { font-size: 11.5px; color: var(--muted); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }

/* 대화 — 여기만 스크롤한다. */
.cs-log { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 8px; padding: 12px 2px; }
.cs-row { display: flex; }
.cs-row.cs-user { justify-content: flex-end; }
.cs-bub { max-width: 82%; padding: 8px 12px; border-radius: 14px; font-size: 13.5px;
  line-height: 1.6; }
/* 말은 통제할 수 없는 길이로 들어온다(주소·해시). 줄을 강제로 끊어 가로 스크롤을 막는다. */
.cs-text { white-space: pre-wrap; overflow-wrap: anywhere; }
.cs-ai .cs-bub, .cs-staff .cs-bub { background: var(--bubble-other);
  color: var(--bubble-other-text); border: 1px solid var(--line);
  border-top-left-radius: 4px; }
/* 사람이 말하기 시작하면 테두리 색으로 구분한다 — AI 와 직원을 헷갈리면 안 된다. */
.cs-staff .cs-bub { border-color: var(--accent-line); }
.cs-user .cs-bub { background: var(--bubble-mine); color: var(--bubble-mine-text);
  border-top-right-radius: 4px; font-weight: 500; }
.cs-from { display: block; font-size: 10px; font-weight: 800; color: var(--accent);
  margin-bottom: 2px; }
.cs-sys { align-self: center; text-align: center; font-size: 11.5px; color: var(--muted);
  padding: 2px 10px; }

/* 생각 중 — 점 세 개. 답이 몇 초 걸리므로 아무 표시가 없으면 멈춘 것으로 보인다. */
.cs-typing { display: flex; gap: 4px; align-items: center; padding: 12px; }
.cs-typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--muted);
  animation: cs-blink 1.2s infinite; }
.cs-typing i:nth-child(2) { animation-delay: 0.2s; }
.cs-typing i:nth-child(3) { animation-delay: 0.4s; }
@keyframes cs-blink { 0%, 60%, 100% { opacity: 0.28; } 30% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .cs-typing i { animation: none; opacity: 0.55; }
}

/* 입력칸 + 아래 버튼줄 */
.cs-foot { flex: none; border-top: 1px solid var(--line-soft); padding: 10px 0 4px;
  display: flex; flex-direction: column; gap: 8px; }
.cs-bar { display: flex; gap: 8px; align-items: flex-end; }
.cs-bar.is-off { opacity: 0.45; }
.cs-input { flex: 1; background: var(--panel2); border: 1px solid var(--line);
  border-radius: 18px; padding: 9px 14px; color: var(--text); font-size: 13.5px;
  font-family: inherit; line-height: 1.5; resize: none; max-height: 96px; overflow-y: auto; }
.cs-input::placeholder { color: var(--muted); }
.cs-send { flex: none; width: 36px; height: 36px; border-radius: 50%; border: 0;
  background: linear-gradient(180deg, #f0cd7d, #d9b45f); color: #0d0b06;
  font-size: 17px; font-weight: 900; cursor: pointer; font-family: inherit; }
.cs-send:disabled { opacity: 0.5; cursor: default; }
.cs-actions { display: flex; flex-direction: column; gap: 6px; }
.cs-actions .sup-cta, .cs-cta { display: block; text-align: center; border-radius: 13px;
  padding: 12px; font-weight: 800; font-size: 14px; color: #241a05; text-decoration: none;
  background: linear-gradient(135deg, #f1cf73, #bf7d18); }
.cs-alt { display: block; width: 100%; background: none; border: 1px solid var(--accent-line);
  border-radius: 11px; padding: 10px 14px; color: var(--accent); font-size: 13px;
  font-weight: 700; font-family: inherit; cursor: pointer; }
.cs-alt:disabled { opacity: 0.5; cursor: default; }
.cs-hint { font-size: 11.5px; color: var(--muted); text-align: center; line-height: 1.6; }

/* 상담 자체를 못 여는 상태(하루 한도·기능 꺼짐) — 입력칸을 남기지 않는다. */
.cs-empty { display: flex; flex-direction: column; gap: 14px; align-items: center;
  padding: 40px 12px; text-align: center; }
.cs-empty p { margin: 0; font-size: 13.5px; color: var(--muted); line-height: 1.7; }
.cs-empty .cs-cta { width: 100%; }

/* ── 경기 알림 설정 화면 ─────────────────────────────── */
.ma-wrap { display: flex; flex-direction: column; gap: 8px; padding: 2px 0 16px; }
.ma-head { margin: 10px 0 -2px; color: var(--muted); font-size: 10.5px; font-weight: 800;
  letter-spacing: .06em; }
.ma-row { display: flex; align-items: center; gap: 11px; width: 100%; padding: 13px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel);
  color: var(--text); text-align: left; }
.ma-row.on { border-color: var(--accent-line); background: var(--accent-soft); }
.ma-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ma-tx b { font-size: 13.5px; font-weight: 750; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.ma-tx i { font-style: normal; color: var(--muted); font-size: 11px; font-weight: 600; }
/* 마스터를 끄면 아래가 무의미해진다 — 흐리게 두되 지우지는 않는다.
   사라지면 「내 설정이 날아갔나」가 된다. */
.ma-body { display: flex; flex-direction: column; gap: 8px; }
.ma-body.off { opacity: .45; }
.ma-sub { background: var(--panel2); }
.ma-x { flex: none; width: 28px; height: 28px; padding: 0; border: 0; background: none;
  color: var(--muted); font-size: 12px; }
.ma-empty { padding: 22px 14px; text-align: center; color: var(--muted); font-size: 12.5px;
  border: 1px dashed var(--line); border-radius: 12px; }

/* ── 유저 활동 순위 (ranking.js rk-*, 고급형 전용) ───────────────────
   선택자는 전부 .rk- 다(마이페이지의 .mp- 와 같은 이유 — 세 업체가 같은
   app.css 를 받는다). var() 에는 폴백을 붙인다: 옛 테마 셸(kr-sports)에는
   --lc-hi·--accent-rgb 가 없고, 토큰이 비면 선언 전체가 무효가 되어 흰
   테두리 각진 상자가 된다. 탭·버튼은 이벤트 화면의 .ev-tab / .btn 을 그대로
   빌려 쓴다 — 같은 앱 안에서 탭이 두 가지 생김새면 안 된다. */
.rk-wrap { display: flex; flex-direction: column; gap: 0; padding: 2px 0 16px; }
.rk-wrap.is-loading { opacity: .55; pointer-events: none; }
.rk-ends { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 2px 0 10px;
  font-size: 11.5px; color: var(--muted); }
.rk-ends b { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }
.rk-ends .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--live, #e5484d);
  box-shadow: 0 0 0 3px rgba(229, 72, 77, .25); flex: none; }
.rk-badge { padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: 850;
  background: var(--panel2); color: var(--muted); border: 1px solid var(--line); }
.rk-badge.is-final { background: rgba(95, 191, 139, .18); color: var(--success, #5fbf8b); border-color: transparent; }

.rk-me { border: 1px solid var(--accent-line, rgba(217, 180, 95, .32)); border-radius: var(--radius-md, 14px); padding: 14px 16px 13px;
  background: radial-gradient(120% 130% at 50% 0%, rgba(var(--accent-rgb, 217, 180, 95), .16), transparent 62%), var(--panel2); }
.rk-me-k { font-size: 10px; font-weight: 850; letter-spacing: .1em; color: var(--lc-hi, var(--accent-strong)); }
.rk-me-row { display: flex; align-items: baseline; gap: 10px; margin-top: 6px; }
.rk-me-rank { font-size: 34px; font-weight: 900; letter-spacing: -.03em; line-height: 1; font-variant-numeric: tabular-nums; }
.rk-me-pct { font-size: 12px; font-weight: 800; color: var(--accent-strong); }
.rk-me-score { margin-left: auto; text-align: right; }
.rk-me-score b { display: block; font-size: 20px; font-weight: 900; color: var(--lc-hi, var(--accent-strong)); font-variant-numeric: tabular-nums; }
.rk-me-score span { font-size: 10.5px; color: var(--muted); font-weight: 700; }
.rk-me-hint { margin-top: 8px; font-size: 11.5px; color: var(--muted); line-height: 1.5; }
.rk-me-hint b { color: var(--text); }
.rk-cta { margin-top: 10px; display: flex; }
.rk-cta .btn { width: 100%; }

/* 탭 줄 — 지표 4개 + 지난 주. 좁은 폰에서는 옆으로 밀어 본다(스크롤바는 숨김). */
.rk-tabs { display: flex; gap: 6px; margin: 12px 0 8px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.rk-tabs::-webkit-scrollbar { display: none; }
.rk-sub { margin: 0 2px 8px; font-size: 10.5px; color: var(--muted); font-weight: 700; }

.rk-podium { display: grid; grid-template-columns: 1fr 1.15fr 1fr; gap: 8px; align-items: end; margin: 2px 0 8px; }
.rk-pod { min-width: 0; border: 1px solid var(--line); border-radius: 14px; background: var(--panel-grad, var(--panel));
  text-align: center; padding: 10px 6px 9px; }
.rk-pod.first { border-color: var(--accent-line, rgba(217, 180, 95, .32)); padding-top: 14px;
  background: radial-gradient(90% 80% at 50% 0%, rgba(var(--accent-rgb, 217, 180, 95), .22), transparent 70%), var(--panel-grad, var(--panel)); }
.rk-pod.me { border-color: var(--accent-strong); }
.rk-pod .medal { font-size: 20px; line-height: 1; }
.rk-pod .av { width: 40px; height: 40px; margin: 6px auto 4px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--panel2); border: 2px solid var(--accent-strong); color: var(--lc-hi, var(--accent-strong)); font-weight: 900; font-size: 15px; }
.rk-pod.first .av { width: 48px; height: 48px; }
.rk-pod .nm { font-size: 12px; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rk-pod .val { font-size: 13px; font-weight: 900; color: var(--lc-hi, var(--accent-strong)); font-variant-numeric: tabular-nums; }

.rk-list { border: 1px solid var(--line); border-radius: 13px; background: var(--panel); overflow: hidden; }
.rk-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-top: 1px solid var(--line-soft, var(--line)); font-size: 13px; }
.rk-row:first-child { border-top: 0; }
.rk-row .no { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%;
  background: var(--panel2); color: var(--muted); font-size: 10.5px; font-weight: 800; flex: none; font-variant-numeric: tabular-nums; }
/* 포디움 없이 줄로만 그릴 때(3명 미만)의 1·2·3 — 금·은·동. */
.rk-row .no.g { background: linear-gradient(135deg, #f1cf73, #bf7d18); color: #241a05; }
.rk-row .no.s { background: linear-gradient(135deg, #e6e6ea, #9a9aa3); color: #1b1b20; }
.rk-row .no.b { background: linear-gradient(135deg, #e0a072, #8a5a34); color: #1b1b20; }
.rk-row .av { width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--panel2); border: 1px solid var(--line); color: var(--lc-hi, var(--accent-strong)); font-size: 12px; font-weight: 900; flex: none; }
.rk-row .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }
.rk-row .nm small { display: block; font-size: 10.5px; color: var(--muted); font-weight: 600; }
.rk-row .val { font-variant-numeric: tabular-nums; font-weight: 800; flex: none; }
.rk-row .val small { font-size: 10px; color: var(--muted); font-weight: 700; margin-left: 2px; }
.rk-row.me { background: var(--accent-soft, rgba(217, 180, 95, .13)); color: var(--accent-strong); }
.rk-row.me .nm small { color: var(--accent-strong); opacity: .8; }
.rk-gap { text-align: center; color: var(--muted); font-size: 12px; padding: 4px 0; letter-spacing: .2em; border-top: 1px solid var(--line-soft, var(--line)); }

/* 참가자가 하한에 못 미쳐 목록을 숨긴 자리 — 빈 목록 대신 '몇 명 더' 와 채팅으로 가는 길. */
.rk-few { padding: 26px 16px 18px; text-align: center; border: 1px dashed var(--line); border-radius: 13px; background: var(--panel); }
.rk-few p { margin: 0; font-size: 13px; color: var(--muted); line-height: 1.6; }
.rk-few .rk-cta { margin-top: 14px; }

/* 규칙 — 접혀 있다. 숫자는 응답(weights/caps)에서 온다. */
.rk-rule { margin-top: 12px; border: 1px solid var(--line); border-radius: 12px; padding: 10px 13px;
  font-size: 11.5px; color: var(--muted); line-height: 1.55; background: var(--panel); }
.rk-rule summary { cursor: pointer; color: var(--text); font-weight: 800; list-style: none; }
.rk-rule summary::-webkit-details-marker { display: none; }
.rk-rule summary::after { content: '›'; float: right; color: var(--muted); transition: transform .15s; }
.rk-rule[open] summary::after { transform: rotate(90deg); }
.rk-rule p { margin: 8px 0 0; }
.rk-rule b { color: var(--text); }

/* 마이페이지 숫자 칸의 순위 강조(mypage.js 가 App.Ranking.tile 로 붙이는 .is-rank). */
.mp-tile.is-rank { border-color: var(--accent-line, rgba(217, 180, 95, .32)); background: var(--accent-soft, rgba(217, 180, 95, .13)); }
.mp-tile.is-rank b { color: var(--accent-strong); }
