/* ═══════════════════════════════════════════════════════════════════════════
   OddsDiff 웹 디자인 시스템 — v2 (플래시스코어형 · 라이트/다크 전환)
   ───────────────────────────────────────────────────────────────────────────
   구조 원칙 (플래시스코어에서 가져온 것)
     · 좌측 리그 트리 → 본문 리그별 그룹 → 초압축 경기 행. 3단 그리드.
     · 헤더는 라이트/다크 모두 어둡게 유지한다(브랜드 식별의 축).
     · 경기 행은 40px 안팎. 정보가 화면을 채우는 것이 이 도메인의 미학이다.
     · 날짜 스트립으로 어제/오늘/내일을 한 번에 이동한다.

   색 규칙 (의뢰인 확정 사항 — 절대 바꾸지 않는다)
     · 국내(배트맨)가 유리 = 붉은색   · 해외가 유리 = 푸른색
     · 리그 배지는 리그명 해시로 hue를 배정해 언제나 같은 색

   테마
     · 토큰 이름은 v1과 동일하다 → 기존 페이지가 수정 없이 두 테마를 탄다.
     · <html data-theme="light|dark">. 미지정이면 OS 설정을 따른다.
     · 최초 페인트 전에 wwwroot/theme.js가 data-theme을 세팅해 깜빡임을 막는다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. 토큰 ───────────────────────────────────────────────────────────── */

:root {
    /* 헤더는 두 테마 공통으로 어둡다 */
    --hdr: #171a1e;
    --hdr-2: #1f242a;
    --hdr-line: #2b3239;
    --hdr-text: #e7eaee;
    --hdr-text-2: #9aa4ae;

    /* 의미색 — 테마와 무관하게 같은 뜻을 갖는다 */
    --dom: #e0574c;
    --for: #3d82d0;
    --ok: #1faa6c;
    --warn: #d99b2b;
    --danger: #d64a45;

    /* 타이포 */
    --font: -apple-system, "Segoe UI", Roboto, "Malgun Gothic", "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
    --mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, "D2Coding", monospace;

    /* 치수 */
    --hdr-h: 50px;
    --sport-h: 38px;
    --sub-h: 40px;
    --shell: 1500px;
    --nav-w: 212px;
    --aside: 286px;
    /* sticky 요소가 헤더 아래에 붙는 높이. 헤더는 1행(로고)+2행(종목탭)이 함께 고정되므로 둘을 더한다.
       종목탭이 없는 페이지에서는 38px만큼 여유가 더 생기는데, 모자라서 내용이 가리는 것보다 낫다. */
    --stick: calc(var(--hdr-h) + var(--sport-h));
    --r: 3px;
    --r-2: 6px;
    --r-3: 10px;
}

/* 다크 (기본) */
:root, :root[data-theme="dark"] {
    color-scheme: dark;

    --bg: #14171a;
    --surface: #1b1f23;
    --surface-2: #23282d;
    --surface-3: #2b3137;
    --surface-4: #343b42;

    --line: #303840;
    --line-soft: #23292f;
    --line-strong: #3e474f;

    --text: #e4e8ec;
    --text-2: #a2acb5;
    /* 표면 대비 AA(4.5:1)를 넘기면서 3→4 위계를 유지한다. 이전 #79838d/#5b646d는 4.30/2.75로 낮았다. */
    --text-3: #8d969f;
    --text-4: #7e8892;

    --accent: #4d90d8;
    /* 흰 글자를 얹는 <b>채워진 면</b> 전용. --accent(#4d90d8)는 흰색 대비 3.3:1로 AA(4.5:1) 미달이라
       주 버튼 라벨이 밝은 곳에서 묻힌다. --accent 자체를 낮추면 이 토큰을 글자색으로 쓰는 곳
       (.faq .qm, .tbl.grouped .gh-for)이 반대로 미달이 되므로, 배경용만 따로 갈라 둔다.
       색상(210°)은 그대로 두고 명도만 낮춘 값이다 — 흰색 대비 5.4:1,
       :hover 의 brightness(1.1) 상태에서도 4.7:1로 AA를 유지한다.
       라이트 테마의 --accent(#1f6dc0)는 이미 5.3:1이라 같은 값을 그대로 쓴다. */
    --accent-solid: #2a6bb0;
    --accent-2: #74aae6;
    --accent-dim: rgba(77, 144, 216, .14);
    --accent-line: #3a5f8a;

    --dom-soft: #f09a92;
    --dom-tint: rgba(224, 87, 76, .17);
    --dom-sw: rgba(224, 87, 76, .72);
    --for-soft: #93c0ee;
    --for-tint: rgba(61, 130, 208, .07);
    --for-sw: rgba(61, 130, 208, .72);

    --ok-soft: #6fd6a6;
    --ok-dim: rgba(31, 170, 108, .14);
    --warn-soft: #e6bd6e;
    --warn-dim: rgba(217, 155, 43, .14);
    --danger-soft: #ef9490;
    --danger-dim: rgba(214, 74, 69, .14);

    /* PREMIUM TIP 강조(보라) — 국내(적)·해외(청)·가치(녹)와 겹치지 않는 유일한 계열.
       -2는 행 테두리 그라데이션 링의 밝은 끝이다(§16 .mrow.is-tip). */
    --tippick: #977ef0;
    --tippick-2: #bfa8fa;
    --tippick-dim: rgba(139, 92, 246, .16);

    --pop: 0 12px 34px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .35);
    --pop-sm: 0 6px 18px rgba(0, 0, 0, .45);
    --row-alt: rgba(255, 255, 255, .016);
    --row-hover: rgba(255, 255, 255, .05);
    --lg-l: 27%;      /* 리그 배지 명도 — 다크에선 어둡게 */
    --lg-bl: 40%;
    --lg-fg: #eef2f7;
}

/* 라이트 */
:root[data-theme="light"] {
    color-scheme: light;

    --bg: #eceef1;
    --surface: #ffffff;
    --surface-2: #f5f7f9;
    --surface-3: #e9edf1;
    --surface-4: #dde3e9;

    --line: #dadfe5;
    --line-soft: #e8ecf0;
    --line-strong: #c3cbd4;

    --text: #14181c;
    --text-2: #4b555f;
    /* WCAG AA(4.5:1) 충족을 위해 어둡게 잡는다 — 흰 배경에서 #6f7a85는 4.38로 미달이었다. */
    --text-3: #5f6973;
    --text-4: #6a747e;

    --accent: #1f6dc0;
    --accent-solid: #1f6dc0;   /* 라이트는 이미 흰색 대비 5.3:1 — 다크와 달리 나눌 필요가 없다 */
    --accent-2: #17559a;
    --accent-dim: rgba(31, 109, 192, .09);
    --accent-line: #a9c6e6;

    --dom-soft: #c43024;
    --dom-tint: rgba(224, 87, 76, .13);
    --dom-sw: rgba(196, 48, 36, .8);
    --for-soft: #1c5fa8;
    --for-tint: rgba(61, 130, 208, .06);
    --for-sw: rgba(28, 95, 168, .8);

    --ok-soft: #10784b;
    --ok-dim: rgba(31, 170, 108, .12);
    --warn-soft: #8f6410;
    --warn-dim: rgba(217, 155, 43, .16);
    --danger-soft: #b32e29;
    --danger-dim: rgba(214, 74, 69, .11);

    --tippick: #6d3fd1;
    --tippick-2: #9a6cf0;
    --tippick-dim: rgba(124, 58, 237, .1);

    --pop: 0 12px 30px rgba(23, 32, 43, .16), 0 2px 6px rgba(23, 32, 43, .08);
    --pop-sm: 0 4px 14px rgba(23, 32, 43, .12);
    --row-alt: rgba(16, 24, 32, .022);
    --row-hover: rgba(16, 24, 32, .05);
    --lg-l: 38%;
    --lg-bl: 32%;
    --lg-fg: #ffffff;
}

/* OS 설정이 라이트인데 사용자가 고르지 않았으면 라이트로 */
@media (prefers-color-scheme: light) {
    :root:not([data-theme]) {
        color-scheme: light;
        --bg: #eceef1; --surface: #ffffff; --surface-2: #f5f7f9; --surface-3: #e9edf1; --surface-4: #dde3e9;
        --line: #dadfe5; --line-soft: #e8ecf0; --line-strong: #c3cbd4;
        --text: #14181c; --text-2: #4b555f; --text-3: #5f6973; --text-4: #6a747e;
        --accent: #1f6dc0; --accent-solid: #1f6dc0; --accent-2: #17559a; --accent-dim: rgba(31, 109, 192, .09); --accent-line: #a9c6e6;
        --dom-soft: #c43024; --dom-tint: rgba(224, 87, 76, .13); --dom-sw: rgba(196, 48, 36, .8);
        --for-soft: #1c5fa8; --for-tint: rgba(61, 130, 208, .06); --for-sw: rgba(28, 95, 168, .8);
        --ok-soft: #10784b; --ok-dim: rgba(31, 170, 108, .12);
        --warn-soft: #8f6410; --warn-dim: rgba(217, 155, 43, .16);
        --danger-soft: #b32e29; --danger-dim: rgba(214, 74, 69, .11);
        --tippick: #6d3fd1; --tippick-2: #9a6cf0; --tippick-dim: rgba(124, 58, 237, .1);
        --pop: 0 12px 30px rgba(23, 32, 43, .16), 0 2px 6px rgba(23, 32, 43, .08);
        --pop-sm: 0 4px 14px rgba(23, 32, 43, .12);
        --row-alt: rgba(16, 24, 32, .022); --row-hover: rgba(16, 24, 32, .05);
        --lg-l: 38%; --lg-bl: 32%; --lg-fg: #ffffff;
    }
}

/* ── 1-b. 테마 전환 연출(2026-10-10 교체) ────────────────────────────────
   토글을 누르면 다음 테마의 바탕색 원(.theme-wash-disc)이 누른 자리에서 퍼져 화면을 덮고, 덮인 동안 테마가 바뀐 뒤 원이 걷힌다
   (theme.js 주석). 움직이는 것은 이 원 하나의 transform·opacity뿐이라 GPU 합성 단계에서 돌고, 요소가 수천 개인 보드에서도
   끊기지 않는다. 종전의 '전 요소 색 transition'(.theme-fade)은 매 프레임 전부를 다시 칠해서 끊겼다.
   위치·크기·색은 theme.js가 누른 자리에 맞춰 넣는다. 상자(.theme-wash)는 원을 잘라 내는 틀이다 — 토글이 머리글 안이면 top을
   머리글 아래로 잡아, 두 테마 모두 어두운 머리글은 덮지 않는다. z-index 300은 모달(100)·오류 띠(200) 위다(§21 예산 밖, 1초 미만만 존재).
   .theme-swap은 바꾸는 순간(두 프레임)만 요소별 색 transition을 끈다 — 원이 걷힐 때 몇몇 칸만 늦게 물들지 않게.
   토글 아이콘(☾/☀)은 새 화면이 드러날 때 돌면서 나타난다(.theme-flip, 약 0.6초). */
.theme-wash {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 300;
    overflow: hidden; pointer-events: none;
}
.theme-wash-disc {
    position: absolute; border-radius: 50%;
    transform: scale(0); will-change: transform, opacity;
}
@media (forced-colors: active) { .theme-wash { display: none; } }
html.theme-swap *, html.theme-swap *::before, html.theme-swap *::after { transition: none !important; }
html.theme-flip[data-theme="light"] .themetog .ti.t-dark,
html.theme-flip[data-theme="dark"] .themetog .ti.t-light {
    display: inline-block;
    animation: themetog-spin .6s cubic-bezier(.2, .7, .2, 1) both;
}
@keyframes themetog-spin {
    from { transform: rotate(-150deg) scale(.3); opacity: 0; }
    60%  { opacity: 1; }
    to   { transform: none; opacity: 1; }
}

/* ── 2. 리셋 ───────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0; min-height: 100%;
    background: var(--bg); color: var(--text);
    /* 기준 14px — 13px에서 상향(2026-08-23 의뢰인: "전체적으로 폰트가 너무 작아서 안 보인다"). */
    font-family: var(--font); font-size: 14px; line-height: 1.5;
    -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
    transition: background-color .16s ease, color .16s ease;
}

h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: 700; line-height: 1.3; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; font-size: inherit; color: inherit; }
img { max-width: 100%; display: block; }
table { border-collapse: collapse; width: 100%; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 2px; }
/* 화면 이동 때 Blazor(FocusOnNavigate)가 제목에 옮기는 초점은 스크린리더용이다 — 테두리를 그리지 않는다. */
h1[tabindex="-1"]:focus { outline: none; }

/*  사용자가 써 넣은 본문에만 강제 줄바꿈을 건다. 한글은 어디서나 끊기지만 라틴 연속(URL)은 안 끊겨서,
    .panel { overflow: hidden } 안에서는 넘친 글자가 스크롤도 없이 그냥 잘려 나간다(읽을 방법이 없다).
    body 전역에 걸지 않는 이유 — 배당 그리드·숫자 셀의 줄바꿈까지 바뀌어 표 정렬이 흔들린다. */
.post-body, .cmt-body, .doc, .modal-body { overflow-wrap: anywhere; }

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--text-3); }
.dim { color: var(--text-2); }
.nowrap { white-space: nowrap; }
.tr { text-align: right; }
.tc { text-align: center; }
.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 5px; border: 2px solid var(--bg); }
*::-webkit-scrollbar-track { background: transparent; }

/* ── 3. 셸 ─────────────────────────────────────────────────────────────── */
.site { display: flex; flex-direction: column; min-height: 100vh; }
.wrap { width: 100%; max-width: var(--shell); margin: 0 auto; padding: 0 14px; }

/* 3-1. 헤더 (두 테마 공통 다크) */
.head {
    flex: none; position: sticky; top: 0; z-index: 60;
    background: var(--hdr); color: var(--hdr-text);
    border-bottom: 1px solid var(--hdr-line);
}
.head-main { height: var(--hdr-h); display: flex; align-items: center; gap: 18px; }

.logo { display: flex; align-items: center; gap: 8px; flex: none; }
/* 로고(2026-10-18 새 로고 — OD 심볼 + OddsDiff 글자, 원본 래스터를 투명 PNG로). 마크업의 'ODDSDIFF' 글자는 낭독용으로 남기고(크기 0)
   바탕에 맞는 그림을 깐다: 어두운 바탕 = logo-on-dark.png(흰 Odds), 밝은 바탕 = logo-on-light.png(남색 Odds).
   머리글은 두 테마 모두 어두워 늘 어두운 바탕용이다. 비율 829:160은 그림 원본 그대로(바꾸면 찌그러진다). */
:root { --logo-img: url(logo-on-dark.png); }
:root[data-theme="light"] { --logo-img: url(logo-on-light.png); }
/* 테마 미선택 + OS 밝은 모드도 밝은 바탕이다 — 이 줄이 없어 로그인 창 · 인증 카드에서 흰 'Odds'가 흰 바탕에 묻혔다(2026-10-20 앱 시연 점검). */
@media (prefers-color-scheme: light) { :root:not([data-theme]) { --logo-img: url(logo-on-light.png); } }
.logo-mark {
    display: inline-block; flex: none; height: 26px; aspect-ratio: 829 / 160; vertical-align: middle;
    font-size: 0; line-height: 0; letter-spacing: 0; color: transparent; overflow: hidden;
    background: var(--logo-img) left center / contain no-repeat;
}
.logo-mark em { display: none; }
.head-main .logo-mark { background-image: url(logo-on-dark.png); }
.logo-sub { font-size: 11.5px; color: var(--hdr-text-2); padding-left: 8px; border-left: 1px solid var(--hdr-line); }

/* 주 메뉴(GNB) — 헤더 1행. 좁아지면 감추고 햄버거로 넘긴다. */
.gnb { display: flex; align-items: stretch; height: var(--hdr-h); flex: 1 1 auto; min-width: 0; overflow: hidden; }
.gnb a {
    position: relative; display: inline-flex; align-items: center; gap: 5px;
    padding: 0 12px; color: var(--hdr-text-2); font-size: 14.5px; font-weight: 600; white-space: nowrap;
    transition: color .12s, background .12s;
}
.gnb a:hover { color: var(--hdr-text); background: rgba(255, 255, 255, .04); }
.gnb a.on { color: #fff; }
.gnb a.on::after { content: ""; position: absolute; left: 10px; right: 10px; bottom: 0; height: 2px; background: #5aa0e6; border-radius: 2px 2px 0 0; }

.head-act { display: flex; align-items: center; gap: 7px; flex: none; margin-left: auto; }

/* 테마 토글 */
.themetog {
    display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 9px;
    background: transparent; border: 1px solid var(--hdr-line); border-radius: 999px;
    color: var(--hdr-text-2); font-size: 11.5px; font-weight: 600; cursor: pointer;
    transition: color .12s, border-color .12s;
}
.themetog:hover { color: var(--hdr-text); border-color: #434c56; }
.themetog .ti { font-size: 12px; line-height: 1; }
/* 아이콘은 테마에 따라 하나만 보인다 — JS가 클래스를 갈아끼우지 않아도 CSS가 처리한다 */
/* 드로어의 '다크/라이트' 배지도 같은 규칙(2026-10-10 — 종전엔 .themetog에만 걸려 드로어에서 두 단어가 함께 보였다). */
.themetog .t-dark, .drawer .t-dark { display: none; }
:root[data-theme="light"] .themetog .t-dark, :root[data-theme="light"] .drawer .t-dark { display: inline; }
:root[data-theme="light"] .themetog .t-light, :root[data-theme="light"] .drawer .t-light { display: none; }
@media (prefers-color-scheme: light) {
    :root:not([data-theme]) .themetog .t-dark, :root:not([data-theme]) .drawer .t-dark { display: inline; }
    :root:not([data-theme]) .themetog .t-light, :root:not([data-theme]) .drawer .t-light { display: none; }
}

.feed {
    display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px;
    background: var(--hdr-2); border: 1px solid var(--hdr-line); border-radius: 999px;
    font-size: 12px; font-weight: 600; color: var(--hdr-text-2);
}
.feed .pip { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px var(--ok-dim); animation: pip 2s ease-in-out infinite; }
@keyframes pip { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
/* (삭제) .feed.is-stale/.is-down — 배지가 상시 '실시간' 상수가 되면서(2026-09-01 writing-for-pros)
   상태 클래스를 붙이는 코드가 사라진 고아 규칙이었다. */
.feed b { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 700; }

.hbtn {
    display: inline-flex; align-items: center; height: 28px; padding: 0 11px;
    background: transparent; border: 1px solid var(--hdr-line); border-radius: var(--r-2);
    color: var(--hdr-text-2); font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap;
    transition: color .12s, border-color .12s, background .12s;
}
.hbtn:hover { color: var(--hdr-text); border-color: #434c56; }
.hbtn-solid { background: #2a5d96; border-color: #3574b8; color: #eaf2fb; }
.hbtn-solid:hover { background: #326ba9; color: #fff; }

.burger { display: none; width: 34px; height: 28px; flex: none; align-items: center; justify-content: center; flex-direction: column; gap: 4px; background: transparent; border: 1px solid var(--hdr-line); border-radius: var(--r); cursor: pointer; }
.burger i { display: block; width: 15px; height: 1.5px; background: var(--hdr-text-2); }

/* 3-2. 종목 탭 — 플래시스코어의 축구/야구/농구 줄 */
.sports { height: var(--sport-h); background: var(--hdr-2); border-top: 1px solid var(--hdr-line); overflow-x: auto; overflow-y: hidden; }
.sports .wrap { height: 100%; display: flex; align-items: stretch; gap: 0; }
.sports a, .sports button {
    position: relative; display: inline-flex; align-items: center; gap: 6px;
    padding: 0 14px; background: transparent; border: 0; cursor: pointer;
    color: var(--hdr-text-2); font-size: 14px; font-weight: 600; white-space: nowrap;
    transition: color .12s, background .12s;
}
.sports a:hover, .sports button:hover { color: var(--hdr-text); background: rgba(255, 255, 255, .04); }
.sports a.on, .sports button.on { color: #fff; background: rgba(255, 255, 255, .06); }
.sports a.on::after, .sports button.on::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: #5aa0e6;
}
.sports .n { font-size: 11px; color: var(--hdr-text-2); font-family: var(--mono); }

/*  종목 단색 아이콘(Ui.SportIcon — 2026-09-18 의뢰인: 이모지 대신 흑백만). 글자색(currentColor)을 그대로 쓰므로
    헤더의 밝은 글자, 본문의 어두운 글자, 켜진 탭의 흰 글자를 자동으로 따른다. 크기는 글자 크기에 맞춘다. */
.sico { display: inline-block; width: 1.05em; height: 1.05em; vertical-align: -0.17em; flex: none; }
.sports .sico { width: 16px; height: 16px; opacity: .9; }
.sports a.on .sico, .sports button.on .sico { opacity: 1; }

/* 3-3. 서브바 — 마켓 탭 · 날짜 · 검색 */
.subnav { flex: none; background: var(--surface); border-bottom: 1px solid var(--line); }
.subnav .wrap { min-height: var(--sub-h); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding-top: 5px; padding-bottom: 5px; }
.subnav a, .subnav button {
    display: inline-flex; align-items: center; height: 30px; padding: 0 12px;
    background: transparent; border: 1px solid transparent; border-radius: var(--r);
    font-size: 13.5px; color: var(--text-3); cursor: pointer; white-space: nowrap;
    transition: color .12s, background .12s, border-color .12s;
}
.subnav a:hover, .subnav button:hover { color: var(--text); background: var(--surface-2); }
.subnav a.on, .subnav button.on { color: var(--text); background: var(--surface-3); border-color: var(--line); font-weight: 600; }
.subnav .vr { width: 1px; height: 16px; background: var(--line); flex: none; }

/* 날짜 스트립 */
/*  overflow를 hidden으로 두면 좁은 폭에서 넘친 버튼이 <b>스크롤도 안 되고 그냥 잘려 나간다</b> —
    자식은 nowrap이라 안 줄고, 이 상자는 스크롤 컨테이너라 플렉스 최소크기가 0으로 풀려 컨테이너까지 줄기 때문이다.
    x축만 auto로 열어 잘리는 대신 스트립 안에서 밀리게 한다(모바일에서는 아래 .d 숨김으로 애초에 다 들어간다). */
.datestrip { display: inline-flex; align-items: center; gap: 2px; max-width: 100%; border: 1px solid var(--line); border-radius: var(--r-2); overflow-x: auto; overflow-y: hidden; }
.datestrip button {
    height: 30px; padding: 0 11px; border: 0; border-radius: 0; background: transparent;
    font-size: 13px; color: var(--text-3); cursor: pointer; white-space: nowrap;
}
.datestrip button + button { border-left: 1px solid var(--line); }
.datestrip button:hover { background: var(--surface-2); color: var(--text); }
.datestrip button.on { background: var(--surface-4); color: var(--text); font-weight: 700; }
.datestrip .d { font-family: var(--mono); font-size: 11.5px; color: var(--text-4); margin-left: 4px; }
.datestrip button.on .d { color: var(--text-2); }

/* 3-4. 3단 본문 */
.main { flex: 1 1 auto; padding: 12px 0 40px; }
.shell { display: grid; grid-template-columns: var(--nav-w) minmax(0, 1fr) var(--aside); gap: 12px; align-items: start; }
.shell.no-left { grid-template-columns: minmax(0, 1fr) var(--aside); }
.shell.no-aside { grid-template-columns: var(--nav-w) minmax(0, 1fr); }
.shell.solo { grid-template-columns: minmax(0, 1fr); }

/* 기존 페이지 호환 — v1의 .cols를 그대로 유지한다 */
.cols { display: grid; grid-template-columns: minmax(0, 1fr) var(--aside); gap: 12px; align-items: start; }
.cols.narrow { grid-template-columns: minmax(0, 1fr); max-width: 880px; margin: 0 auto; }
.cols.wide { grid-template-columns: minmax(0, 1fr); }

/*  z-index: 8 — sticky는 스택 컨텍스트를 만들어 안의 fixed 모달(가상영수증 등)이 갇힌다.
    표 sticky 머리글(z 2·5·6)보다 위, 사이트 크롬(헤더 60·탭바 70·독 80·드로어 90)보다 아래로 둬야
    모달이 표 위로 뜨면서도 아사이드가 크롬을 덮지 않는다(2026-09-02 실측 — 영수증 모달 위로 표 머리글이 떴다). */
.leftnav, .aside { position: sticky; top: calc(var(--stick) + 8px); z-index: 8; display: flex; flex-direction: column; gap: 10px; }

.phead { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 12px; flex-wrap: wrap; }
.phead h1 { font-size: 20px; letter-spacing: -.01em; }
.phead .lede { margin-top: 5px; font-size: 13.5px; color: var(--text-3); max-width: 64ch; line-height: 1.6; }
.phead-act { display: flex; align-items: center; gap: 8px; }
.crumb { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-4); margin-bottom: 8px; }
.crumb a:hover { color: var(--text-2); }
.crumb i { font-style: normal; }

/* ── 4. 리그 트리(좌측) ────────────────────────────────────────────────── */
.tree { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2); overflow: hidden; }
.tree-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 8px 11px; background: var(--surface-2); border-bottom: 1px solid var(--line);
    font-size: 12px; font-weight: 700; color: var(--text-2); letter-spacing: .03em;
}
.tree-head button { background: transparent; border: 0; color: var(--text-4); font-size: 12px; cursor: pointer; }
.tree-head button:hover { color: var(--text-2); }
/* 정적 SSR 화면(/proto)은 버튼 대신 링크로 같은 자리를 쓴다 — 겉모습은 버튼과 같아야 한다. */
.tree-head a { color: var(--text-4); font-size: 12px; font-weight: 400; }
.tree-head a:hover { color: var(--text-2); }
.tree-body { max-height: calc(100vh - var(--hdr-h) - 140px); overflow-y: auto; }
.tree-sec { padding: 5px 0; border-bottom: 1px solid var(--line-soft); }
.tree-sec:last-child { border-bottom: 0; }
.tree-sec h5 { padding: 4px 11px 3px; font-size: 11px; color: var(--text-4); letter-spacing: .06em; }
.tree-item {
    display: flex; align-items: center; gap: 7px; width: 100%; padding: 6px 11px;
    background: transparent; border: 0; cursor: pointer; text-align: left;
    font-size: 13.5px; color: var(--text-2); transition: background .1s, color .1s;
}
.tree-item:hover { background: var(--surface-2); color: var(--text); }
.tree-item.on { background: var(--accent-dim); color: var(--text); font-weight: 600; }
.tree-item .sw { flex: none; }
.tree-item .nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tree-item .n { flex: none; font-family: var(--mono); font-size: 11.5px; color: var(--text-4); }
.tree-item .star { flex: none; font-size: 12.5px; color: var(--text-4); }
.tree-item .star.on { color: var(--warn); }

/* ── 5. 경기 목록 (플래시스코어형) ─────────────────────────────────────── */
/*  ⚠ overflow는 반드시 clip이다 — hidden으로 두면 .mcols가 첫 경기 행을 덮는다.
    hidden은 <b>스크롤 컨테이너</b>를 만들기 때문에, 자식의 position:sticky가 뷰포트가 아니라 이 상자를 기준으로
    풀린다. 그러면 sticky의 top(=--stick, 88px)이 보드 안쪽 88px 지점으로 해석돼 컬럼 헤더가 제자리(보드 최상단)가
    아니라 첫 행 한가운데에 얹힌다(실측: 헤더 y=311, 첫 행 286~351 — 팀명이 가려졌다).
    clip은 같은 모서리 잘라내기를 하면서 스크롤 컨테이너를 만들지 않아 sticky가 뷰포트 기준으로 정상 동작한다. */
.board { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2); overflow: clip; }

/* 컬럼 헤더 — 목록 상단에 한 번만, sticky */
.mcols {
    position: sticky; top: var(--stick); z-index: 5;
    display: grid; align-items: center; gap: 0;
    padding: 6px 10px; background: var(--surface-2); border-bottom: 1px solid var(--line);
    font-size: 12px; font-weight: 700; letter-spacing: .05em; color: var(--text-4);
}
.mcols .g { text-align: center; }

/*  컬럼 정렬 — 헤더(.mcols)와 행(.mrow)이 같은 트랙을 쓴다.
    셀렉션 수는 2(승패)와 3(승무패)뿐이라 가변 repeat() 대신 클래스 두 벌로 못박는다.
    가변 개수를 var()로 넘기는 방법은 브라우저별 지원이 갈려 정렬이 어긋날 위험이 있다. */
.mcols, .mrow { grid-template-columns: 26px 72px minmax(0, 1fr) repeat(3, 76px) 96px 64px; }
.mcols.n2, .mrow.n2 { grid-template-columns: 26px 72px minmax(0, 1fr) repeat(2, 76px) 96px 64px; }

/*  배당 셀 묶음. 데스크톱에선 display:contents로 부모 그리드에 그대로 참여하고,
    모바일에선 한 줄을 통째로 차지하는 자체 그리드가 된다(경기명이 눌리지 않는다). */
.m-os { display: contents; }

/* 리그 그룹 */
.mgroup + .mgroup { border-top: 1px solid var(--line); }
.mgroup-head {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 7px 10px; background: var(--surface-2); border: 0; border-bottom: 1px solid var(--line-soft);
    cursor: pointer; text-align: left; transition: background .1s;
}
.mgroup-head:hover { background: var(--surface-3); }
.mgroup-head .ch { flex: none; width: 10px; font-size: 9px; color: var(--text-4); transition: transform .15s; }
.mgroup-head.closed .ch { transform: rotate(-90deg); }
.mgroup-head .lg { flex: none; }
.mgroup-head .nm { font-size: 13.5px; font-weight: 700; color: var(--text); }
.mgroup-head .sp { font-size: 12px; color: var(--text-4); }
.mgroup-head .n { margin-left: auto; font-family: var(--mono); font-size: 12px; color: var(--text-4); }

/* 경기 행 — 그리드로 컬럼을 맞춘다(테이블 없이도 정렬이 어긋나지 않는다) */
.mrow {
    display: grid; align-items: center; gap: 0;
    padding: 5px 10px; border-bottom: 1px solid var(--line-soft);
    transition: background .1s;
}
.mrow:last-child { border-bottom: 0; }
.mrow:nth-child(even) { background: var(--row-alt); }
.mrow:hover { background: var(--row-hover); }
.mrow.is-off { opacity: .5; }
.mrow.is-value { box-shadow: inset 3px 0 0 var(--dom); }

.m-star { background: transparent; border: 0; padding: 0 2px; cursor: pointer; color: var(--text-4); font-size: 14px; line-height: 1; }
.m-star:hover { color: var(--warn); }
.m-star.on { color: var(--warn); }

.m-when { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.m-when .t { font-size: 13.5px; color: var(--text); }
.m-when .c { font-size: 11.5px; color: var(--text-4); }
.m-when .c[data-state="soon"] { color: var(--warn); font-weight: 700; }

.m-no { font-family: var(--mono); font-size: 12px; color: var(--text-4); }

/* 팀 셀은 2줄로 고정한다(홈/원정). 경기번호·라인 칩은 홈 줄에 같이 실어 행 높이를 44px 안쪽으로 잡는다 —
   플래시스코어의 행 리듬이 이 정도이고, 한 화면에 담기는 경기 수가 이 화면의 값어치다. */
.m-teams { min-width: 0; }
.m-teams .h { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; color: var(--text); min-width: 0; }
.m-teams .h .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.m-teams .a { font-size: 13px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 배당 셀 — 큰 값=국내, 작은 값=해외, 배경 틴트=유불리 */
.m-o {
    text-align: center; padding: 2px 3px; margin: 0 1px; border-radius: var(--r);
    border: 1px solid transparent;
}
.m-o .lbl { display: none; }   /* 데스크톱은 상단 컬럼 헤더가 승/무/패를 알려준다 */
.m-o .v { display: block; font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 15px; font-weight: 700; color: var(--text); line-height: 1.25; }
.m-o .f { display: block; font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 11px; color: var(--text-3); line-height: 1.3; }
.m-o .d { font-size: 11px; font-weight: 700; margin-left: 3px; }
.m-o.is-na .v { color: var(--text-4); font-weight: 400; }
.m-o.adv-dom { background: var(--dom-tint); border-color: rgba(224, 87, 76, .45); }
.m-o.adv-dom .v { color: var(--dom-soft); }
.m-o.adv-dom .d { color: var(--dom-soft); }
.m-o.adv-for { background: var(--for-tint); border-color: transparent; }
.m-o.adv-for .v { color: var(--for-soft); }
.m-o.adv-for .d { color: var(--for-soft); }

/*  별도 해외 — 북을 가리지 않은 전량 중 최저 하나 + 그 사이트.
    승/무/패 칸(.m-o)과 같은 리듬을 쓰되, 값 아래에 북 칩이 한 줄 더 들어가므로 글자를 한 단계 줄인다. */
.m-alt {
    text-align: center; padding: 2px 3px; margin: 0 1px; border-radius: var(--r);
    border: 1px solid transparent; min-width: 0;
}
.m-alt .v { display: block; font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 15px; font-weight: 700; color: var(--text); line-height: 1.25; }
.m-alt .bk { display: block; line-height: 1; margin: 1px 0; }
.m-alt .f { display: flex; align-items: center; justify-content: center; gap: 3px; font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 11px; color: var(--text-3); line-height: 1.3; }
.m-alt .f .lbl { font-family: var(--font); font-size: 10.5px; color: var(--text-4); font-weight: 700; }
.m-alt .d { font-weight: 700; }
.m-alt.is-na .v { color: var(--text-4); font-weight: 400; }
.m-alt.adv-dom { background: var(--dom-tint); border-color: rgba(224, 87, 76, .45); }
.m-alt.adv-dom .v, .m-alt.adv-dom .d { color: var(--dom-soft); }
.m-alt.adv-for { background: var(--for-tint); }
.m-alt.adv-for .v, .m-alt.adv-for .d { color: var(--for-soft); }
.m-alt.clickable { cursor: pointer; }
.m-alt.clickable:hover { outline: 1px solid var(--accent-line); }
.m-alt.is-open { outline: 1px solid var(--accent); }

/*  해외 배당 <b>익명 기호</b> 칩(해외 A·B·C…) — 리그 배지(.lg)와 같은 테마 변수를 쓴다.
    다크가 기본이고 라이트가 오버라이드인 이 사이트에서 명도를 여기서 새로 정하면 한쪽 테마가 깨진다.
    2026-08-30 법률 검토로 배당사 <b>실명·로고 표시를 없앴다</b> — .bklogo(로고 이미지) 규칙도 함께 지웠다.
    남은 것은 이 칩 하나뿐이고, 담기는 글자는 Ui.BookAnon이 만든 순번 기호다. */
.bkchip {
    display: inline-block; max-width: 100%; vertical-align: middle;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    padding: 3px 9px; border-radius: 4px; line-height: 1.5;
    background: hsl(var(--h, 210) 38% var(--lg-l));
    border: 1px solid hsl(var(--h, 210) 44% var(--lg-bl));
    font-size: 13.5px; font-weight: 700; color: var(--lg-fg);
}
.bkchip.sm { font-size: 12px; padding: 1px 6px; line-height: 1.45; }

.m-tag { text-align: center; }

/* 해외 칸 — 전체 평균은 붉은색(2026-08-26 의뢰인: "해외배당 전체 평균도 붉은색으로"),
   주요 4곳 평균은 작은 병기 줄. 붉은색(--dom)이 '국내 유리' 의미색과 같은 축임은 의뢰인 지정. */
.bi-o.for .o-now.o-avg-all { color: var(--dom); }
.bi-o.for .o-avg4 { display: block; font-size: 10.5px; line-height: 1.3; color: var(--text-4); font-family: var(--mono); }

/* ── 가상영수증(저장 조합, 2026-08-26) — 실물 영수증풍: 좁은 폭·점선 절취선·도장.
   실제 구매로 오인되지 않게 머리/바닥 문구가 '가상'임을 박는다(컴포넌트 주석). */
.receipt {
    max-width: 360px; margin: 0 auto; padding: 14px 14px 16px;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px;
    font-size: 12.5px; position: relative; overflow: hidden;
}
.receipt .rc-head { text-align: center; }
.receipt .rc-brand { font-size: 16px; font-weight: 800; letter-spacing: 4px; color: var(--text); }
.receipt .rc-sub { font-size: 11px; color: var(--text-4); margin-top: 2px; }
.receipt .rc-meta { display: flex; justify-content: space-between; margin-top: 8px; color: var(--text-3); font-size: 11.5px; }
.receipt .rc-cut { border-top: 1px dashed var(--line); margin: 10px -14px; }
.receipt .rc-item { padding: 6px 0; }
.receipt .rc-item + .rc-item { border-top: 1px solid var(--line-soft); }
.receipt .rc-line1 { display: flex; align-items: center; gap: 6px; }
.receipt .rc-no { color: var(--accent-2); font-weight: 700; }
.receipt .rc-mkt { color: var(--text-3); font-size: 11.5px; }
.receipt .rc-line1 .badge { margin-left: auto; }
.receipt .rc-line2 { margin-top: 3px; font-weight: 600; color: var(--text); }
.receipt .rc-line2 .x { color: var(--text-4); padding: 0 4px; font-weight: 400; }
.receipt .rc-line2 .sc { color: var(--dom); }
.receipt .rc-line3 { display: flex; justify-content: space-between; margin-top: 2px; color: var(--text-3); font-size: 11.5px; }
.receipt .rc-pick b { color: var(--text); }
.receipt .rc-sum div { display: flex; justify-content: space-between; padding: 2px 0; color: var(--text-3); }
.receipt .rc-sum b { color: var(--text); }
.receipt .rc-total { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 6px !important; font-size: 14px; }
.receipt .rc-total b { color: var(--accent-2); }
.receipt .rc-stamp {
    position: absolute; right: 14px; top: 44px; transform: rotate(12deg);
    border: 2px solid var(--text-4); color: var(--text-4); border-radius: 6px;
    padding: 3px 9px; font-weight: 800; font-size: 13px; letter-spacing: 2px; opacity: .85;
}
.receipt .rc-stamp.hit { border-color: var(--dom); color: var(--dom); }
.receipt .rc-stamp.miss { border-color: var(--for); color: var(--for); }
.receipt .rc-foot { margin-top: 10px; text-align: center; font-size: 10.5px; color: var(--text-4); }

/* 저장 조합 목록(/myslips) */
.sliplist { display: flex; flex-direction: column; gap: 4px; }
.sliprow {
    display: grid; grid-template-columns: 84px 48px 64px minmax(0, 1fr) auto;
    gap: 8px; align-items: center; width: 100%; text-align: left;
    padding: 9px 11px; background: var(--surface-2); border: 1px solid var(--line-soft);
    border-radius: 6px; color: var(--text-2); cursor: pointer; font-size: 12.5px;
}
.sliprow:hover, .sliprow.is-on { background: var(--surface-3); border-color: var(--line); }
.slipdetail { padding: 10px 4px 14px; }
@media (max-width: 480px) {
    .sliprow { grid-template-columns: 74px 40px 56px minmax(0, 1fr) auto; font-size: 12px; }
}

/* 동일배당 — 배당을 누르면 그 행 아래로 조용히 펼쳐지는 얇은 띠.
   떠 있는 팝오버로 만들면 .board 의 overflow 에 잘리고 모바일에서 자리를 못 잡는다.
   의뢰인 요구도 "와이즈토토처럼 요란하지 않게"였다. */
.sostrip {
    padding: 10px 12px 12px; background: var(--surface-2);
    border-bottom: 1px solid var(--line); animation: sofade .14s ease;
}
@keyframes sofade { from { opacity: 0; } to { opacity: 1; } }
.sostrip-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; color: var(--text-3); }
.sostrip-head b { color: var(--text); font-size: 14px; }
.sostrip-head .x { margin-left: auto; background: transparent; border: 0; color: var(--text-4); cursor: pointer; font-size: 15px; }
.sostrip-head .x:hover { color: var(--text); }

.sobar { display: flex; height: 9px; margin: 9px 0 6px; border-radius: 2px; overflow: hidden; background: var(--surface-4); }
.sobar i { display: block; height: 100%; }
.sobar .b-h { background: var(--dom); }
.sobar .b-d { background: var(--text-3); }
.sobar .b-a { background: var(--for); }

.solegend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12.5px; }
.solegend span { display: inline-flex; align-items: center; gap: 5px; color: var(--text-2); }
.solegend b { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); }

/* 동일배당 — 셀렉션별 단일 배당 통계(2026-09-19, 와이즈토토 상단 표) + 조합 머리글 + 더 보기 */
.so-singles { display: grid; grid-template-columns: 1fr; gap: 4px 16px; margin-top: 8px; }   /* 블록당 한 줄 — 승·무·패 분포가 길어 2열이면 겹친다(2026-09-21 실측) */
.so-single { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-2); min-height: 24px; padding: 2px 8px; margin: 0 -8px; border-radius: 6px; cursor: pointer; border-left: 2px solid transparent; }
.so-single:hover { background: var(--surface-2); }
.so-single.on { background: var(--surface-2); border-left-color: var(--dom); }
.so-combo { cursor: pointer; border-radius: 6px; padding: 4px 8px; margin: 8px -8px 0; border-left: 2px solid transparent; }
.so-combo:hover { background: var(--surface-2); }
.so-combo.on { background: var(--surface-2); border-left-color: var(--dom); }
.so-combo .so-combo-head { margin-top: 0; }
.so-combo-head .so-cnt { margin-left: 6px; font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; }
.so-tabline { margin-top: 12px; font-size: 12.5px; color: var(--text-2); }
.so-tabline b { color: var(--text); }
.sostrip .pb-odds.q { box-shadow: inset 0 -2px 0 var(--dom); }
.so-single-sel { flex: none; min-width: 92px; }
.so-single-bar.three { max-width: 160px; }
.sostrip .so-info { white-space: nowrap; }
.so-single-sel b { color: var(--text); }
.so-single-bar { flex: 1 1 60px; height: 6px; border-radius: 2px; background: var(--surface-4); overflow: hidden; }
.so-single-bar i { display: block; height: 100%; background: var(--dom); }
.so-single-bar.three { display: flex; }
.so-single-bar.three .b-h { background: var(--dom); }
.so-single-bar.three .b-d { background: var(--text-3); }
.so-single-bar.three .b-a { background: var(--for); }
.so-single-dist { flex: none; display: inline-flex; gap: 8px; white-space: nowrap; color: var(--text-3); }
.so-single-dist span.me { color: var(--text); }
.so-single-dist span.me b { color: var(--text); }
.so-single-dist b { color: var(--text-2); }
.sostrip .so-line { color: var(--text-2); font-size: 12px; white-space: nowrap; }
.so-single-rate { flex: none; white-space: nowrap; }
.so-single-rate b { color: var(--text); }
.so-single-none { color: var(--text-4); }
.so-singles-note { grid-column: 1 / -1; margin-top: 0; }
.so-combo-head { margin-top: 12px; font-size: 13px; color: var(--text); font-weight: 600; }
.so-more { margin-top: 6px; height: 28px; padding: 0 12px; font-size: 12.5px; }
@media (max-width: 760px) {
    .so-singles { grid-template-columns: 1fr; gap: 4px; }
}

.solist { margin-top: 8px; display: flex; flex-direction: column; gap: 3px; }
.solist div { display: flex; gap: 8px; font-size: 12.5px; color: var(--text-3); }
.solist .o { flex: none; width: 34px; font-weight: 700; }
.solist .o-h { color: var(--dom-soft); }
.solist .o-d { color: var(--text-2); }
.solist .o-a { color: var(--for-soft); }

.m-o.clickable { cursor: pointer; }
.m-o.clickable:hover { outline: 1px solid var(--accent-line); }
.m-o.is-open { outline: 1px solid var(--accent); }

/*  해외 북 상세 — 동일배당 띠와 같은 톤. 목록이 20~35줄이라 세로 스크롤을 띠 안쪽에 가둔다
    (그대로 두면 행 하나가 화면 서너 개를 밀어내 목록을 훑을 수 없다).
    글자는 본문 표보다 오히려 크게 간다(2026-08-23 의뢰인) — 이 표의 목적이 배당사 이름 식별이다. */
.bkstrip { padding: 12px 14px 14px; background: var(--surface-2); border-bottom: 1px solid var(--line); animation: sofade .14s ease; }
.bkstrip .tablewrap { max-height: 440px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.bktbl { width: 100%; }
.bktbl td:first-child, .bktbl th:first-child { width: 45%; }
.bktbl tbody td { font-size: 14.5px; padding-top: 7px; padding-bottom: 7px; }
.bktbl tbody td .badge { margin-left: 6px; }
/* 기준선(국내·평균·최저) — 목록과 섞이지 않게 위에 붙여 두고 배경을 달리한다. */
.bktbl tbody tr.bkref td { background: var(--surface-2); font-weight: 600; border-bottom: 1px solid var(--line); }
.bktbl tbody tr.bkref.is-min td { color: var(--dom-soft); }
.bktbl tbody tr.bkref .bkchip { margin-left: 5px; }
/* 셀렉션별 최저 셀 — 이 열의 기준값이 어느 북에서 나왔는지 표에서 바로 보이게. */
.bktbl tbody td.is-min { color: var(--dom-soft); font-weight: 700; background: var(--dom-tint); }

/* ── 가치 판정(2026-09-17 의뢰인 공식: 해외 마진 제거 × 국내 환급률 = 적정 국내배당) ──
   판정 열(72px)의 세 가지 버튼과, 눌렀을 때 행 아래로 펼쳐지는 근거 띠(.vbstrip).
     · 가치 ▼     — 적정선 초과(적색 알약). ▼ 해외 하락=우선 · ▲ 해외 상승=후순위(.v-low: 테두리만)
     · 미달 / 보류 — 점선 고스트(판정은 했지만 기준 미만 / 적정선을 만들지 않음)
   셋 다 <button>이다 — 배지처럼 보이되 눌린다는 것을 커서와 hover로 알린다. 숫자는 배지에 넣지 않는다
   (2026-09-18 의뢰인 — 두 줄로 깨진 배지). 초과율은 툴팁·근거 띠·가치 경기 TOP이 말한다. */
button.badge-value { cursor: pointer; font-family: var(--font); }
button.badge-value:hover, button.badge-value.on { box-shadow: 0 0 0 3px var(--dom-tint); }
.badge-value .vd { font-style: normal; font-size: 7.5px; opacity: .95; }
.badge-value.v-low { background: transparent; color: var(--dom-soft); border-color: var(--dom-sw); }
.bi-why {
    height: 22px; padding: 0 8px; background: transparent;
    border: 1px dashed var(--line-strong); border-radius: var(--r);
    color: var(--text-4); font-family: var(--font); font-size: 11px; font-weight: 700; letter-spacing: .04em; cursor: pointer;
}
.bi-why:hover, .bi-why.on { color: var(--text-2); border-style: solid; border-color: var(--accent-line); background: var(--accent-dim); }
.bi-verdict { cursor: pointer; font-family: var(--font); }
.bi-verdict.on { outline: 2px solid var(--warn); outline-offset: 1px; }
.mrow.is-value.is-value-low { box-shadow: inset 3px 0 0 var(--dom-sw); }
/* 사이드 위젯(가치 경기 TOP)의 초과율 + 방향 */
.vb-top { display: inline-flex; align-items: center; gap: 4px; }
.vb-top .vd { font-style: normal; font-size: 9px; }
.vb-top .vd.dn { color: var(--dom-soft); }
.vb-top .vd.up { color: var(--for-soft); }

/*  근거 띠 — 동일배당·해외 분포 띠와 같은 톤(surface-2 바닥, 얇은 선). 구성은 위에서 아래로
      본문(이 경기의 숫자를 넣은 문장 두세 개) + 오른쪽 요약 카드(초과율·픽·적정/실제·기준·방향)
      → 근거 표(셀렉션별 해외→적정확률→적정 국내→국내→초과, 역수 열 없음) → 계산 흐름 한 줄.
    숫자는 전부 mono·tabular, 픽 줄은 국내 유리색 틴트 + 왼쪽 막대(본문 행의 is-value와 같은 문법).
    (2026-09-18 개작 — 의뢰인: "표와 숫자만이 아니라 문장으로, 역수는 보여줄 필요 없음, 디자인은 세련되게") */
.vbstrip { padding: 14px 16px 16px; background: var(--surface-2); border-bottom: 1px solid var(--line); animation: sofade .14s ease; }
.vb-body { display: grid; grid-template-columns: minmax(0, 1fr) 210px; gap: 14px; align-items: start; margin-top: 10px; }
.vb-body.no-key { grid-template-columns: minmax(0, 1fr); }
.vb-prose { font-size: 13.5px; line-height: 1.75; color: var(--text-2); }
.vb-prose p { margin: 0; }
.vb-prose p + p { margin-top: 6px; }
.vb-prose b.mono { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }
.vb-key {
    display: flex; flex-direction: column; gap: 5px; padding: 11px 13px 12px;
    background: var(--surface); border: 1px solid var(--line); border-top: 3px solid var(--dom); border-radius: var(--r-2);
}
.vb-key.is-miss { border-top-color: var(--line-strong); }
.vb-key .k-tag { font-size: 11px; font-weight: 800; letter-spacing: .08em; color: var(--dom-soft); }
.vb-key.is-miss .k-tag { color: var(--text-4); }
.vb-key .k-edge { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 28px; font-weight: 800; line-height: 1; margin-top: 1px; }
.vb-key .k-sel { font-size: 12.5px; font-weight: 700; color: var(--text); margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vb-key .k-line { display: flex; justify-content: space-between; align-items: baseline; font-size: 12px; color: var(--text-3); }
.vb-key .k-line b { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); font-size: 13px; }
.vb-key .k-drift { margin-top: 6px; padding-top: 7px; border-top: 1px solid var(--line-soft); font-size: 12px; font-weight: 700; color: var(--text-3); }
.vb-key .k-drift.dn { color: var(--dom-soft); }
.vb-key .k-drift.up { color: var(--for-soft); }

/*  ⚠ 선택자는 전부 .vbstrip 아래로 한 단계 더 특정한다 — §10의 `.tbl thead th`/`.tbl tbody td`가 이 블록보다
    <b>뒤에</b> 있어 같은 특정도(0,1,2)면 이 규칙이 전부 진다(2026-09-17 검토에서 실제로 죽어 있었다). */
.vbstrip .tablewrap { margin-top: 12px; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.vbstrip .vbtbl { width: 100%; }
.vbstrip .vbtbl thead th { font-size: 11px; position: static; }
.vbstrip .vbtbl tbody td { font-size: 13.5px; padding-top: 6px; padding-bottom: 6px; }
.vbstrip .vbtbl td.mono { font-variant-numeric: tabular-nums; }
.vbstrip .vbtbl .sub { display: block; font-size: 10.5px; line-height: 1.25; color: var(--text-4); font-family: var(--mono); }
.vbstrip .vbtbl .sub .arr { font-size: 9px; }
.vbstrip .vbtbl tbody tr.is-pick td { background: var(--dom-tint); color: var(--text); }
.vbstrip .vbtbl tbody tr.is-pick td:first-child { box-shadow: inset 3px 0 0 var(--dom); font-weight: 700; }
.vbstrip .vbtbl td.vb-exp { font-weight: 800; color: var(--text); }
.vbstrip .vbtbl tbody tr.vb-sum td { background: var(--surface-2); color: var(--text-3); font-size: 12px; border-top: 1px solid var(--line); }
.vbstrip .vbtbl tbody tr.vb-sum td b { color: var(--text-2); }
.vb-flow { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 10px; font-size: 12px; color: var(--text-3); }
.vb-flow .st { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); color: var(--text-2); white-space: nowrap; }
.vb-flow .st b { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); }
.vb-flow .ar { color: var(--text-4); }
@media (max-width: 760px) {
    .vbstrip { padding: 10px 10px 12px; }
    .vb-body { grid-template-columns: minmax(0, 1fr); gap: 10px; }
    .vb-prose { font-size: 13px; line-height: 1.7; }
    .vb-key { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px 12px; }
    .vb-key .k-edge { font-size: 22px; }
    .vb-key .k-sel { flex-basis: 100%; margin-bottom: 0; }
    .vb-key .k-drift { margin-top: 0; padding-top: 0; border-top: 0; margin-left: auto; }
    .vbstrip .vbtbl thead th, .vbstrip .vbtbl tbody td { padding-left: 5px; padding-right: 5px; }
    .vbstrip .vbtbl tbody td { font-size: 12.5px; }
}

/* ── 6. 패널 · 위젯 ────────────────────────────────────────────────────── */
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2); overflow: hidden; }
.panel + .panel { margin-top: 12px; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 40px; padding: 8px 13px; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.panel-head h2, .panel-head h3 { font-size: 14.5px; }
.panel-head .sub { font-size: 12px; color: var(--text-3); font-weight: 400; margin-left: 8px; }
.panel-head-act { display: flex; align-items: center; gap: 6px; }
.panel-body { padding: 13px; }
.panel-body.flush { padding: 0; }
.panel-body.tight { padding: 9px 11px; }
.panel-foot { padding: 9px 13px; background: var(--surface-2); border-top: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; color: var(--text-3); flex-wrap: wrap; }

.widget { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2); overflow: hidden; }
.widget-head { display: flex; align-items: center; justify-content: space-between; padding: 8px 11px; background: var(--surface-2); border-bottom: 1px solid var(--line-soft); font-size: 13.5px; font-weight: 700; color: var(--text); }
.widget-head a, .widget-head button { font-size: 12px; font-weight: 500; color: var(--text-3); background: transparent; border: 0; cursor: pointer; }
.widget-head a:hover, .widget-head button:hover { color: var(--accent-2); }
.widget-body { padding: 10px 11px; }
.widget-body.flush { padding: 0; }

/* ── 7. 버튼 ───────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    height: 32px; padding: 0 14px; border-radius: var(--r-2);
    background: var(--surface-3); border: 1px solid var(--line);
    color: var(--text-2); font-size: 13.5px; font-weight: 600; cursor: pointer; white-space: nowrap;
    transition: background .12s, border-color .12s, color .12s;
}
.btn:hover { color: var(--text); border-color: var(--line-strong); background: var(--surface-4); }
.btn:active { transform: translateY(.5px); }
.btn:disabled, .btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }

/* 흰 글자를 얹으므로 --accent 가 아니라 --accent-solid 를 쓴다(토큰 주석 참조 — 다크에서 대비 미달). */
.btn-primary { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; }
.btn-primary:hover { filter: brightness(1.1); background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; }
.btn-ghost { background: transparent; }
.btn-ghost:hover { background: var(--surface-2); }
.btn-line { background: transparent; border-color: var(--accent-line); color: var(--accent-2); }
.btn-line:hover { background: var(--accent-dim); color: var(--accent-2); }
.btn-danger { background: var(--danger-dim); border-color: rgba(214, 74, 69, .42); color: var(--danger-soft); }
.btn-danger:hover { background: var(--danger-dim); border-color: var(--danger); color: var(--danger-soft); }

.btn-sm { height: 28px; padding: 0 11px; font-size: 12.5px; border-radius: var(--r); }
.btn-lg { height: 40px; padding: 0 20px; font-size: 14px; }
.btn-block { width: 100%; }
.btn-icon { width: 32px; padding: 0; }
.btn-icon.btn-sm { width: 26px; }

.btngroup { display: inline-flex; border: 1px solid var(--line); border-radius: var(--r-2); overflow: hidden; }
.btngroup button { height: 30px; padding: 0 13px; background: transparent; border: 0; font-size: 13px; color: var(--text-3); cursor: pointer; transition: background .12s, color .12s; }
.btngroup button + button { border-left: 1px solid var(--line); }
.btngroup button:hover { color: var(--text); background: var(--surface-2); }
.btngroup button.on { background: var(--surface-4); color: var(--text); font-weight: 600; }

.btn-social { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; height: 44px; border-radius: var(--r-2); border: 1px solid transparent; font-size: 13.5px; font-weight: 700; cursor: pointer; transition: filter .12s; }
.btn-social:hover { filter: brightness(1.06); }
.btn-social .si { width: 18px; height: 18px; flex: none; display: grid; place-items: center; font-size: 13px; font-weight: 900; border-radius: 3px; }
.sc-kakao { background: #FEE500; color: #191600; }
.sc-kakao .si { background: #191600; color: #FEE500; }
.sc-naver { background: #03C75A; color: #fff; }
.sc-naver .si { background: #fff; color: #03C75A; }
.sc-google { background: #fff; color: #1f1f1f; border-color: #dadce0; }
.sc-google .si { background: #1f1f1f; color: #fff; }
/*  소셜 로그인 폼(카카오, 2026-09-10) — 로그인 폼·모달·가입 1단계에 같은 모양으로 놓인다. */
.login-social { margin: 0; }
.login-social + .auth-alt { margin-top: 14px; }

/* ── 8. 폼 ─────────────────────────────────────────────────────────────── */
.field { display: block; margin-bottom: 14px; }
.field > label, .flabel { display: block; margin-bottom: 6px; font-size: 13px; font-weight: 600; color: var(--text-2); }
.field .req { color: var(--dom); margin-left: 3px; }

.input, .select, .textarea {
    width: 100%; height: 36px; padding: 0 11px;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2);
    color: var(--text); font-family: inherit; font-size: 14px; outline: none;
    transition: border-color .12s, background .12s;
}
.textarea { height: auto; min-height: 110px; padding: 9px 11px; line-height: 1.6; resize: vertical; }
.input:hover, .select:hover, .textarea:hover { border-color: var(--line-strong); }
.input:focus, .select:focus, .textarea:focus { border-color: var(--accent); background: var(--surface); }
.input::placeholder, .textarea::placeholder { color: var(--text-4); }
.input:disabled, .select:disabled, .textarea:disabled { opacity: .55; cursor: not-allowed; }
.input.is-bad, .select.is-bad, .textarea.is-bad { border-color: var(--danger); }
.select {
    appearance: none; padding-right: 28px; cursor: pointer;
    background-image: linear-gradient(45deg, transparent 50%, var(--text-3) 50%), linear-gradient(135deg, var(--text-3) 50%, transparent 50%);
    background-position: calc(100% - 15px) 15px, calc(100% - 10px) 15px;
    background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.input-sm { height: 30px; font-size: 13px; padding: 0 9px; }

.fhelp { margin-top: 5px; font-size: 12.5px; color: var(--text-4); line-height: 1.55; }
/* α — 프라임 전용 추가 해외 소스 칩(배당비교 핸디캡 칸) */
.o-alpha { color: var(--accent-2); font-weight: 700; font-size: 10.5px; margin-left: 4px; white-space: nowrap; }

/* 인증번호 남은 시간 — 정적(auth.js 카운트다운)·대화형(Alerts C# 틱) 공용 표시 */
.vtimer-row .vtimer { color: var(--text); font-weight: 600; }
.vtimer-row.expired { color: var(--danger); }
.ferr { margin-top: 5px; font-size: 12.5px; color: var(--danger-soft); }
.inline-form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.inline-form .input, .inline-form .select { width: auto; min-width: 0; }
.grid-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 14px; }
.grid-form .span2 { grid-column: 1 / -1; }

.check { display: inline-flex; align-items: flex-start; gap: 8px; cursor: pointer; font-size: 13.5px; color: var(--text-2); line-height: 1.5; }
.check input { margin: 2px 0 0; accent-color: var(--accent); width: 14px; height: 14px; flex: none; cursor: pointer; }
.check:hover { color: var(--text); }
.check b { color: var(--text); font-weight: 600; }
.checklist { display: flex; flex-direction: column; gap: 10px; }

.switch { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font-size: 12.5px; color: var(--text-2); }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track { width: 34px; height: 19px; border-radius: 999px; flex: none; background: var(--surface-4); border: 1px solid var(--line); position: relative; transition: background .16s, border-color .16s; }
.switch .track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 13px; height: 13px; border-radius: 50%; background: var(--text-3); transition: transform .16s, background .16s; }
.switch input:checked + .track { background: var(--accent); border-color: var(--accent); }
.switch input:checked + .track::after { transform: translateX(15px); background: #fff; }

.searchbox { position: relative; }
.searchbox .input { padding-left: 30px; }
.searchbox::before { content: "⌕"; position: absolute; left: 10px; top: 50%; transform: translateY(-52%); color: var(--text-4); font-size: 15px; pointer-events: none; }

/* ── 9. 배지 · 칩 ──────────────────────────────────────────────────────── */
.badge { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px; border-radius: var(--r); background: var(--surface-3); border: 1px solid var(--line); font-size: 12px; font-weight: 700; color: var(--text-2); letter-spacing: .02em; white-space: nowrap; }
.badge-ok { color: var(--ok-soft); border-color: rgba(31, 170, 108, .38); background: var(--ok-dim); }
.badge-warn { color: var(--warn-soft); border-color: rgba(217, 155, 43, .38); background: var(--warn-dim); }
.badge-danger { color: var(--danger-soft); border-color: rgba(214, 74, 69, .38); background: var(--danger-dim); }
.badge-accent { color: var(--accent-2); border-color: var(--accent-line); background: var(--accent-dim); }
.badge-dom { color: var(--dom-soft); border-color: rgba(224, 87, 76, .4); background: var(--dom-tint); }

/*  '가치' 배지 — 알약형 한 줄. 판정 열(72px)에서 절대 줄바꿈되지 않아야 한다(2026-09-18: 숫자를 넣었다가 "가/치"로
    두 줄이 깨졌다). 글자는 '가치'와 방향 화살표(▼ 해외 하락=우선 · ▲ 상승=후순위)뿐이고 숫자는 넣지 않는다. */
.badge-value {
    display: inline-flex; align-items: center; gap: 3px; height: 21px; padding: 0 9px;
    background: var(--dom); border: 1px solid var(--dom); border-radius: 999px;
    color: #fff; font-size: 11.5px; font-weight: 800; letter-spacing: .06em; line-height: 1; white-space: nowrap;
}

/*  리그 배지 — 인라인 스타일로는 색상(--h)만 받고 명도·채도는 테마가 정한다.
    (라이트 모드에서 배지만 어둡게 남는 사고를 막는 유일한 방법이다.) */
.lg {
    display: inline-block; min-width: 42px; max-width: 132px; text-align: center;
    padding: 2px 8px; border-radius: var(--r);
    background: hsl(var(--h, 210) 38% var(--lg-l));
    border: 1px solid hsl(var(--h, 210) 44% var(--lg-bl));
    font-size: 12px; font-weight: 700; color: var(--lg-fg); letter-spacing: .02em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle;
}

.chip { display: inline-flex; align-items: center; height: 20px; padding: 0 6px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 2px; font-size: 11.5px; color: var(--text-2); font-weight: 600; white-space: nowrap; }
.chip-mkt { color: var(--accent-2); border-color: var(--accent-line); background: var(--accent-dim); }
.chip-line { font-family: var(--mono); }

/* ── 10. 표 ────────────────────────────────────────────────────────────── */
.tablewrap { width: 100%; overflow-x: auto; }
.tbl { font-size: 14px; }
.tbl thead th { position: sticky; top: 0; z-index: 2; background: var(--surface-2); padding: 8px 10px; text-align: left; white-space: nowrap; font-size: 12px; font-weight: 700; letter-spacing: .05em; color: var(--text-3); border-bottom: 1px solid var(--line); }
.tbl tbody td { padding: 8px 10px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
.tbl tbody tr { transition: background .1s; }
.tbl tbody tr:hover { background: var(--row-hover); }
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl.compact tbody td { padding: 5px 10px; }
.tbl.zebra tbody tr:nth-child(even) { background: var(--row-alt); }
.tbl.zebra tbody tr:nth-child(even):hover { background: var(--row-hover); }
.tbl tbody tr.is-off { opacity: .48; }
.tbl tbody tr.is-off .diff { color: var(--text-3) !important; }
.tbl .rowlink { cursor: pointer; }

.tbl.grouped thead tr.g1 th { top: 0; height: 28px; padding: 5px 8px; text-align: center; }
.tbl.grouped thead tr.g2 th { top: 28px; height: 24px; padding: 3px 8px; font-size: 11px; text-align: right; }
.tbl.grouped thead th.gh { border-left: 1px solid var(--line); }
.tbl.grouped thead th.gh-for { color: var(--accent); }
.tbl.grouped thead th.gh-bm { color: var(--dom-soft); background: var(--dom-tint); }
.tbl.grouped thead th.gh-df { color: var(--text-2); }
.tbl.grouped thead th.sh-bm { background: var(--dom-tint); }

.c-no { width: 60px; text-align: right; color: var(--text-3); font-size: 13px; }
.c-when { width: 102px; }
.c-lg { width: 112px; }
.c-vs { min-width: 180px; }
.c-o { width: 74px; text-align: right; padding: 5px 8px !important; }
.c-d { width: 70px; text-align: right; }
.c-rec { width: 70px; text-align: center; }

.when-d { font-size: 13.5px; color: var(--text); }
.when-c { font-size: 11.5px; color: var(--text-3); margin-top: 1px; }
.when-c[data-state="soon"] { color: var(--warn); font-weight: 700; }

.vs-h { font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.vs-a { color: var(--text-2); font-size: 13.5px; margin-top: 1px; }
.vs-a::before { content: "vs "; color: var(--text-4); font-size: 11px; }

.o-now { font-size: 15px; font-weight: 700; color: var(--text); font-family: var(--mono); font-variant-numeric: tabular-nums; }
.o-open { font-size: 11.5px; color: var(--text-4); margin-top: 1px; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.o-sel { font-size: 10.5px; color: var(--text-4); font-weight: 700; letter-spacing: .04em; }
.c-o.is-na .o-now { font-weight: 400; color: var(--text-4); }
.c-o.for { background: var(--accent-dim); }
.c-o.bm.adv-dom { background: var(--dom-tint); }
.c-o.bm.adv-dom .o-now { color: var(--dom-soft); }
.c-o.bm.adv-for { background: var(--for-tint); }
.c-o.bm.adv-for .o-now { color: var(--for-soft); }

.arr { font-style: normal; font-size: 9.5px; margin-left: 2px; vertical-align: 1px; }
.arr.up { color: var(--dom); }
.arr.dn { color: var(--for); }

.diff { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13.5px; }
.diff.pos { color: var(--dom-soft); }
.diff.neg { color: var(--for-soft); }
.diff.zero { color: var(--text-2); }
.diff.na { color: var(--text-4); font-weight: 400; }

/* ── 11. 게시판 · 글 ───────────────────────────────────────────────────── */
.blist li { border-bottom: 1px solid var(--line-soft); }
.blist li:last-child { border-bottom: 0; }
.blist a { display: flex; align-items: center; gap: 10px; padding: 10px 13px; transition: background .1s; }
.blist a:hover { background: var(--row-hover); }
.blist .bcat { flex: none; width: 58px; font-size: 11px; color: var(--accent-2); font-weight: 600; }
.blist .bti { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.blist .bti .cnt { color: var(--warn); font-size: 11px; font-weight: 700; margin-left: 5px; }
.blist .bti .new { color: var(--dom); font-size: 9px; font-weight: 800; margin-left: 5px; vertical-align: 2px; }
.blist .bmeta { flex: none; display: flex; align-items: center; gap: 12px; font-size: 11px; color: var(--text-4); }
.blist .bmeta .au { color: var(--text-3); min-width: 62px; text-align: right; }
.blist .bmeta .vw, .blist .bmeta .dt { min-width: 40px; text-align: right; font-family: var(--mono); }

.post-head { padding: 15px 15px 12px; border-bottom: 1px solid var(--line); }
.post-head h1 { font-size: 18px; line-height: 1.45; }
.post-meta { display: flex; align-items: center; gap: 12px; margin-top: 10px; font-size: 11.5px; color: var(--text-4); flex-wrap: wrap; }
.post-meta .au { color: var(--text-2); font-weight: 600; }
.post-body { padding: 18px 15px 26px; font-size: 13.5px; line-height: 1.85; color: var(--text-2); }
.post-body p + p { margin-top: 14px; }
.post-body b, .post-body strong { color: var(--text); }
.post-act { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 0 15px 18px; }

.cmt { padding: 12px 13px; border-bottom: 1px solid var(--line-soft); }
.cmt:last-child { border-bottom: 0; }
.cmt-head { display: flex; align-items: center; gap: 8px; font-size: 11.5px; margin-bottom: 5px; }
.cmt-head .au { color: var(--text); font-weight: 700; }
.cmt-head .dt { color: var(--text-4); }
.cmt-body { font-size: 13px; line-height: 1.7; color: var(--text-2); }
.cmt.reply { padding-left: 34px; background: var(--row-alt); position: relative; }
.cmt.reply::before { content: "↳"; position: absolute; left: 15px; top: 12px; color: var(--text-4); font-size: 12px; }

.av { width: 26px; height: 26px; border-radius: 50%; flex: none; display: grid; place-items: center; font-size: 11px; font-weight: 800; color: #fff; background: var(--text-3); }
.av-lg { width: 44px; height: 44px; font-size: 17px; }

.pager { display: flex; align-items: center; justify-content: center; gap: 4px; padding: 15px 0 4px; }
.pager a, .pager button, .pager span { min-width: 30px; height: 30px; padding: 0 8px; border-radius: var(--r); display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 1px solid transparent; font-size: 12.5px; color: var(--text-3); cursor: pointer; font-family: var(--mono); transition: color .12s, background .12s, border-color .12s; }
.pager a:hover, .pager button:hover { color: var(--text); background: var(--surface-2); }
.pager .on { background: var(--surface-4); border-color: var(--line); color: var(--text); font-weight: 700; }
.pager .gap { cursor: default; }

/* ── 12. 상태 ──────────────────────────────────────────────────────────── */
.empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 50px 20px; text-align: center; color: var(--text-3); }
td.empty { display: table-cell; }   /* 표 칸의 빈 상태는 colspan을 지켜야 한다(리뷰 FE-3) */
.empty .ei { font-size: 26px; opacity: .38; }
.empty h4 { font-size: 15px; color: var(--text-2); font-weight: 600; }
.empty p { font-size: 13.5px; color: var(--text-4); max-width: 44ch; line-height: 1.65; }

.notice { display: flex; gap: 10px; padding: 11px 13px; border-radius: var(--r-2); background: var(--surface-2); border: 1px solid var(--line); border-left: 2px solid var(--text-3); font-size: 13.5px; line-height: 1.65; color: var(--text-2); }
.notice b { color: var(--text); }
.notice .ni { flex: none; font-size: 13px; line-height: 1.4; }
.notice-info { border-left-color: var(--accent); }
.notice-warn { border-left-color: var(--warn); background: var(--warn-dim); }
.notice-danger { border-left-color: var(--danger); background: var(--danger-dim); }
.notice-ok { border-left-color: var(--ok); background: var(--ok-dim); }

.sk { background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%); background-size: 400% 100%; animation: shimmer 1.3s ease infinite; border-radius: var(--r); }
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
.sk-line { height: 11px; margin: 6px 0; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
.tile { padding: 11px 13px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2); }
.tile .tl { font-size: 12px; color: var(--text-3); }
.tile .tv { margin-top: 4px; font-size: 21px; font-weight: 800; color: var(--text); font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.tile .td { margin-top: 3px; font-size: 12px; color: var(--text-4); }
.tile .tv.pos { color: var(--dom-soft); }
.tile .tv.acc { color: var(--accent-2); }
.tile .tv.ok { color: var(--ok-soft); }

/* ── 13. 모달 · 드롭다운 ───────────────────────────────────────────────── */
.modal-veil { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; padding: 20px; background: rgba(6, 9, 12, .6); backdrop-filter: blur(3px); animation: fade .16s ease; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.modal { width: min(560px, 100%); max-height: 86vh; display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-3); box-shadow: var(--pop); animation: pop .18s cubic-bezier(.2, .8, .3, 1); }
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(.99); } to { opacity: 1; transform: none; } }
.modal-sm { width: min(420px, 100%); }
.modal-lg { width: min(820px, 100%); }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 18px; border-bottom: 1px solid var(--line); flex: none; }
.modal-head h3 { font-size: 16px; }
.modal-x { background: transparent; border: 0; color: var(--text-3); font-size: 16px; cursor: pointer; line-height: 1; padding: 4px; }
.modal-x:hover { color: var(--text); }
.modal-body { padding: 16px 18px; overflow-y: auto; font-size: 14px; line-height: 1.7; color: var(--text-2); }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--line); flex: none; }

/*  로그인 모달 — 항상 DOM에 있고 hidden 으로만 닫힌다(auth.js). .modal-veil 의 display:grid 가
    UA 의 [hidden]{display:none} 을 이기므로 반드시 명시적으로 꺼야 한다(.pop-win 과 같은 함정).
    등장은 일반 모달(.16s/.18s)보다 느긋하게 — "스멀스멀"(2026-09-02 의뢰인). 닫았다 다시 열면
    display 가 none→grid 로 바뀌며 애니메이션이 처음부터 다시 돈다. */
.modal-veil[hidden] { display: none !important; }
.login-veil { animation: fade .38s ease both; }
.login-modal { position: relative; width: min(400px, 100%); padding: 28px 26px 22px; animation: loginrise .46s cubic-bezier(.16, .84, .28, 1) both; }
@keyframes loginrise { from { opacity: 0; transform: translateY(16px) scale(.98); } to { opacity: 1; transform: none; } }
.login-x { position: absolute; top: 10px; right: 10px; }
.login-hero { text-align: center; margin-bottom: 18px; }
.login-hero .logo-mark { height: 30px; }
.login-hero h3 { margin-top: 12px; font-size: 17px; }
.login-hero p { margin-top: 6px; font-size: 12.5px; line-height: 1.6; color: var(--text-3); }
.login-form .field { margin-bottom: 10px; }
.login-form .btn { margin-top: 4px; }
/* (삭제) .login-keep — "2주간 유지" 안내 문구를 뺐다(2026-09-02 의뢰인). 유지 동작 자체는 그대로다. */
.login-modal .auth-alt { margin-top: 14px; text-align: center; font-size: 12.5px; }

.pop { position: relative; }
.pop-panel { position: absolute; right: 0; top: calc(100% + 6px); z-index: 50; min-width: 210px; padding: 8px; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-2); box-shadow: var(--pop-sm); display: flex; flex-direction: column; gap: 4px; }
.pop-panel .pi { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 9px; border-radius: var(--r); background: transparent; border: 0; font-size: 12.5px; color: var(--text-2); cursor: pointer; text-align: left; width: 100%; }
.pop-panel .pi:hover { background: var(--surface-2); color: var(--text); }
.pop-panel .pi.on { color: var(--accent-2); }
.pop-sep { height: 1px; background: var(--line); margin: 4px 0; }
.pop-label { padding: 4px 9px; font-size: 10px; color: var(--text-4); letter-spacing: .06em; }

/* ── 14. 인증 · 요금제 · 관리자 · 계산기 · 문서 ────────────────────────── */
.auth { display: grid; place-items: center; min-height: calc(100vh - var(--hdr-h) - var(--sport-h)); padding: 34px 14px 60px; }
.auth-card { width: min(400px, 100%); }
.auth-card .logo { justify-content: center; margin-bottom: 6px; }
.auth-card .logo-mark { height: 28px; }
.auth-title { text-align: center; font-size: 17px; margin-bottom: 4px; }
.auth-lede { text-align: center; font-size: 12.5px; color: var(--text-3); margin-bottom: 20px; line-height: 1.6; }
.auth-box { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-3); padding: 22px; }
.auth-socials { display: flex; flex-direction: column; gap: 8px; }
.auth-or { display: flex; align-items: center; gap: 12px; margin: 18px 0; color: var(--text-4); font-size: 11px; }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.auth-alt { margin-top: 16px; text-align: center; font-size: 12.5px; color: var(--text-3); }
.auth-alt a { color: var(--accent-2); font-weight: 600; }
.auth-legal { margin-top: 18px; font-size: 11px; color: var(--text-4); line-height: 1.7; text-align: center; }
.auth-legal a { color: var(--text-3); text-decoration: underline; text-underline-offset: 2px; }

.steps { display: flex; align-items: center; gap: 0; margin-bottom: 20px; }
.steps .st { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: 11px; color: var(--text-4); position: relative; }
.steps .st .sn { width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: var(--surface-3); border: 1px solid var(--line); font-size: 11px; font-weight: 700; color: var(--text-3); }
.steps .st.on .sn { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; }
.steps .st.on { color: var(--text); font-weight: 600; }
.steps .st.done .sn { background: var(--ok-dim); border-color: rgba(31, 170, 108, .45); color: var(--ok-soft); }
.steps .st + .st::before { content: ""; position: absolute; left: -50%; top: 12px; width: 100%; height: 1px; background: var(--line); z-index: -1; }


.adm { display: grid; grid-template-columns: 194px minmax(0, 1fr); gap: 14px; align-items: start; }
.adm-nav { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2); padding: 8px; position: sticky; top: calc(var(--stick) + 8px); }
.adm-nav h5 { padding: 8px 10px 5px; font-size: 10px; color: var(--text-4); letter-spacing: .06em; }
.adm-nav a { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 7px 10px; border-radius: var(--r); font-size: 12.5px; color: var(--text-2); cursor: pointer; transition: background .1s, color .1s; }
.adm-nav a:hover { background: var(--surface-2); color: var(--text); }
.adm-nav a.on { background: var(--surface-4); color: var(--text); font-weight: 600; }
.adm-nav a .n { font-size: 10.5px; color: var(--text-4); font-family: var(--mono); }
.adm-nav .sep { height: 1px; background: var(--line-soft); margin: 6px 4px; }

.calc-slip { display: flex; flex-direction: column; gap: 6px; }
.calc-row { display: grid; grid-template-columns: minmax(0, 1fr) 84px 28px; gap: 8px; align-items: center; padding: 8px 10px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2); }
.calc-row .cm { min-width: 0; }
.calc-row .cm .t { font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.calc-row .cm .s { font-size: 12px; color: var(--text-4); margin-top: 2px; display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.calc-row .input { height: 30px; text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 700; }
.calc-sum { margin-top: 12px; padding: 13px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2); }
.calc-line { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 6px 0; font-size: 14px; color: var(--text-2); }
.calc-line + .calc-line { border-top: 1px solid var(--line-soft); }
.calc-line b { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 700; color: var(--text); font-size: 15px; }
.calc-line.total { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--line); }
.calc-line.total span { font-size: 14px; color: var(--text); font-weight: 600; }
/* 항목명은 줄바꿈하지 않는다 — 좁은 아사이드에서 "이용 기간"이 "이용 기/간"으로 쪼개졌다(2026-09-29). 값 쪽이 줄어든다. */
.calc-line > span:first-child { white-space: nowrap; flex: none; }
.calc-line > b { text-align: right; }
.calc-line.total b { font-size: 23px; color: var(--ok-soft); letter-spacing: -.02em; }
.calc-pick { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 10px; border-radius: var(--r); background: var(--surface-3); border: 1px solid var(--line); font-size: 13.5px; color: var(--text-2); cursor: pointer; transition: all .12s; }
.calc-pick:hover { border-color: var(--accent-line); color: var(--text); }
.calc-pick.on { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; font-weight: 700; }
/*  선택 버튼 안의 차이율은 <b>보조 정보</b>다 — 배당(굵은 mono)보다 작고 흐리게 두어야
    "무엇을 고르는 버튼인지"가 먼저 읽힌다. 담긴 상태(.on)에서는 흰 글자 위라 색을 물려받는다. */
.calc-pick .diff { font-weight: 600; }
.calc-pick.on .diff { color: #fff; opacity: .9; }

/*  '최대차' 칸의 셀렉션 표기 — (승) -4.7% 처럼 숫자 앞에 붙는다(의뢰인 2026-08-30).
    숫자와 같은 크기로 두면 어느 쪽이 값인지 헷갈리므로 한 단계 작고 흐리게 둔다. */
.c-d-sel { display: block; font-size: 11.5px; color: var(--text-4); line-height: 1.4; white-space: nowrap; }

/*  다중 조합 대기 목록(2026-09-02 의뢰인: "여러 조합을 동시에") — 조합 1·2·3… 카드 스택.
    슬립·조합기와 같은 면(surface-2) 위에 조합 카드(surface)를 얹어 계층이 읽히게 한다. */
.heldbox { margin-top: 12px; padding: 10px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2); display: flex; flex-direction: column; gap: 8px; }
/* 한 열로 쌓는다 — 좁은 아사이드(286px)에서 옆 배치는 요약 줄이 두 자씩 꺾인다(실측). */
.heldrow { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--r-2); }
.heldrow .hm { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.heldrow .hm .t { display: flex; align-items: center; gap: 6px; font-size: 12.5px; flex-wrap: wrap; }
.heldrow .hm .s { font-size: 11.5px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.heldrow .ha { display: flex; justify-content: flex-end; gap: 4px; }
.heldbox .calc-sum { margin-top: 2px; padding: 10px 12px; background: var(--surface); }

/*  마이페이지 이용권 구매 카드(2026-09-02 토스 연동) — /pricing 카드의 축약형. 3열, 좁으면 접힌다. */
.buyplans { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.buyplan { display: flex; flex-direction: column; gap: 8px; padding: 14px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2); }
.buyplan.best { border-color: var(--accent-line); background: var(--accent-dim); }
.buyplan .bp-head { display: flex; align-items: center; gap: 6px; font-size: 14.5px; }
.buyplan .bp-price { font-size: 19px; font-weight: 800; font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.buyplan .bp-price small { font-size: 11.5px; font-weight: 400; color: var(--text-4); font-family: var(--font); }
.buyplan .bp-desc { font-size: 12px; line-height: 1.6; color: var(--text-3); min-height: 36px; }
.buyplan .bp-points { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--text-2); flex: 1; }
.buyplan .bp-points li { list-style: none; padding-left: 14px; position: relative; }
.buyplan .bp-points li::before { content: "✓"; position: absolute; left: 0; color: var(--ok-soft); font-size: 11px; }

/*  내 조합 목록의 제목 칸 — 길면 말줄임(제목은 60자까지 저장된다). */
.sliprow .slip-title { font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px; }

/*  가상영수증 미리보기 모달 — 영수증(.receipt, max-width 360px)을 가운데 세운다. */
.rc-modal .rc-center { display: flex; justify-content: center; margin-top: 4px; }
.rc-title { margin-top: 7px; font-size: 13.5px; font-weight: 800; letter-spacing: .02em; }
.rc-memo { margin-top: 2px; font-size: 11.5px; color: var(--text-3); }

/*  조합기 — 슬립 아래로 펼쳐지는 조합표. 계산기 독(우측 하단)에서도 쓰이므로 폭을 넘기지 않는다. */
.combo-box { padding: 11px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2); }
/*  조합 목록 — 카드(머리줄 + 경기 줄). 표 5열은 아사이드 폭(≈210px)에서 가로로 넘쳐 카드로 바꿨다(2026-09-10).
    경기 줄은 번호·홈 : 원정·(라인)·선택·배당 — 이름 칸만 말줄임하고 선택·배당은 절대 안 잘린다
    (2026-09-09 의뢰인: 번호 배지만으로는 어떤 경기·몇 배당인지 알 수 없다). */
.combo-legend { display: flex; gap: 8px; font-size: 11px; color: var(--text-4); padding: 0 2px 4px; border-bottom: 1px solid var(--line); }
.combo-legend span:first-child { min-width: 18px; }
.combo-legend .tr { margin-left: auto; }
.combo-list { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.combo-item { padding: 6px 8px; border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); min-width: 0; }
.combo-hd { display: flex; align-items: center; gap: 6px; font-size: 12.5px; }
.combo-hd .cno { min-width: 18px; color: var(--text-3); font-weight: 700; }
.combo-hd .combo-odds { margin-left: auto; color: var(--text-2); }
.combo-hd .combo-pay { color: var(--accent-2); }
.combo-hd .btn { height: 24px; padding: 0 8px; }
.combo-legs { margin-top: 4px; overflow: hidden; }
.combo-leg { display: flex; align-items: center; gap: 5px; min-width: 0; line-height: 18px; white-space: nowrap; }
.combo-leg + .combo-leg { margin-top: 2px; }
.combo-leg .slip-no { margin-right: 0; flex: none; }
.combo-leg-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--text-2); }
.combo-leg-name .muted { margin: 0 1px; }
.combo-leg .chip-line { flex: none; }
.combo-leg-sel { flex: none; color: var(--text); }
.combo-leg-odds { flex: none; min-width: 34px; text-align: right; color: var(--accent-2); font-weight: 700; }
/*  슬립 번호 — 슬립 목록과 조합표의 경기 줄이 같은 모양으로 찍어 눈으로 대조한다. */
.slip-no {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 18px; margin-right: 3px; padding: 0 4px;
    border-radius: 4px; background: var(--surface-3); border: 1px solid var(--line);
    font-size: 11px; font-weight: 700; color: var(--text-3); line-height: 1;
}

.doc { font-size: 13px; line-height: 1.85; color: var(--text-2); }
.doc h2 { font-size: 14.5px; color: var(--text); margin: 24px 0 10px; padding-bottom: 8px; border-bottom: 1px solid var(--line-soft); }
.doc h2:first-child { margin-top: 0; }
.doc h3 { font-size: 13px; color: var(--text); margin: 16px 0 6px; }
.doc p + p { margin-top: 10px; }
.doc ul { margin: 8px 0; padding-left: 16px; list-style: disc; }
.doc ol { margin: 8px 0; padding-left: 18px; list-style: decimal; }
.doc li { margin: 4px 0; }
.doc .updated { font-size: 11.5px; color: var(--text-4); margin-bottom: 18px; }

.faq li { border-bottom: 1px solid var(--line-soft); }
.faq li:last-child { border-bottom: 0; }
.faq .q { display: flex; align-items: center; gap: 10px; width: 100%; padding: 13px 13px; background: transparent; border: 0; text-align: left; cursor: pointer; font-size: 13px; color: var(--text); font-weight: 500; transition: background .1s; }
.faq .q:hover { background: var(--row-hover); }
.faq .q .qm { flex: none; width: 18px; color: var(--accent); font-weight: 800; font-size: 12px; }
.faq .q .ch { margin-left: auto; color: var(--text-4); font-size: 10px; transition: transform .16s; }
.faq .q.on .ch { transform: rotate(180deg); }
.faq .a { padding: 0 13px 15px 41px; font-size: 12.5px; line-height: 1.8; color: var(--text-2); }

/* ── 15. 푸터 · 모바일 ─────────────────────────────────────────────────── */
.foot { flex: none; background: var(--surface); border-top: 1px solid var(--line); padding: 24px 0 28px; font-size: 12px; color: var(--text-3); }
.foot-top { display: flex; justify-content: space-between; gap: 32px; flex-wrap: wrap; padding-bottom: 18px; border-bottom: 1px solid var(--line-soft); }
.foot-brand { max-width: 340px; }
.foot-brand .logo-mark { height: 24px; }
.foot-brand p { margin-top: 9px; line-height: 1.65; color: var(--text-4); font-size: 11.5px; }
.foot-links { display: flex; gap: 38px; flex-wrap: wrap; }
.foot-links section { min-width: 94px; }
.foot-links h4 { font-size: 11.5px; color: var(--text-2); margin-bottom: 9px; }
.foot-links li + li { margin-top: 6px; }
.foot-links a { color: var(--text-4); transition: color .12s; }
.foot-links a:hover { color: var(--text-2); }
.foot-legal { padding-top: 15px; display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; font-size: 11px; color: var(--text-4); line-height: 1.7; }
.foot-legal b { color: var(--text-3); font-weight: 600; }
/*  합법 이용 안내(LegalUseNotice) — 축약형은 표 아래·푸터처럼 안내 띠를 세울 수 없는 자리에 쓴다.
    기본형은 .notice 규칙을 그대로 타므로 여기서는 축약형만 정의한다. */
.legal-use.compact { font-size: 11.5px; line-height: 1.7; color: var(--text-3); }
.legal-use.compact b { color: var(--text-2); }

.foot-disc { margin-top: 12px; padding: 10px 12px; border: 1px solid var(--line-soft); border-left: 2px solid var(--warn); border-radius: 0 var(--r) var(--r) 0; background: var(--warn-dim); color: var(--text-3); font-size: 11px; line-height: 1.65; }

.tabbar { display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 70; height: calc(52px + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom); background: var(--surface); border-top: 1px solid var(--line); }
.tabbar ul { display: flex; height: 52px; }
.tabbar li { flex: 1 1 0; }
.tabbar a, .tabbar label { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; height: 100%; font-size: 11px; color: var(--text-3); font-weight: 600; cursor: pointer; }
.tabbar a.on { color: var(--accent-2); }
.tabbar .ic { font-size: 16px; line-height: 1; }

/* 드로어는 <input type=checkbox #nav-open> 하나로 연다.
   @onclick 으로 열던 시절에는 <b>정적 SSR 페이지(랜딩·약관·계정)에서 회로가 없어 햄버거가 죽어 있었다</b> —
   그 폭(≤860px)에서는 GNB도 숨겨지므로 모바일 방문자에게 이동 수단이 아예 없었다.
   체크박스는 회로가 있든 없든 똑같이 동작하므로 두 렌더 모드에서 같은 코드로 열린다. */
.nav-open { position: fixed; top: 0; left: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.drawer-veil { display: none; position: fixed; inset: 0; z-index: 90; background: rgba(6, 9, 12, .62); backdrop-filter: blur(2px); animation: fade .18s ease; }
.drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 91; width: min(310px, 86vw); background: var(--surface); border-left: 1px solid var(--line); display: flex; flex-direction: column; overflow-y: auto; visibility: hidden; transform: translateX(100%); transition: transform .2s cubic-bezier(.2, .8, .3, 1), visibility .2s; }
.nav-open:checked ~ .drawer-veil { display: block; }
.nav-open:checked ~ .drawer { visibility: visible; transform: none; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; height: var(--hdr-h); padding: 0 14px; border-bottom: 1px solid var(--line); flex: none; }
.drawer-head .logo-mark { height: 24px; }
.drawer-body { padding: 8px 0 20px; }
.drawer-sec { padding: 10px 0; border-bottom: 1px solid var(--line-soft); }
.drawer-sec h5 { padding: 0 16px 6px; font-size: 10.5px; color: var(--text-4); letter-spacing: .06em; }
.drawer a.dl { display: flex; align-items: center; justify-content: space-between; padding: 9px 16px; font-size: 13.5px; color: var(--text-2); font-weight: 500; }
.drawer a.dl:hover, .drawer a.dl.on { color: var(--text); background: var(--surface-2); }
.drawer-foot { padding: 14px 16px; display: flex; gap: 8px; }

/* ── 16. 유틸 ──────────────────────────────────────────────────────────── */
.row { display: flex; align-items: center; gap: 8px; }
.row.wrap { flex-wrap: wrap; }
.row.between { justify-content: space-between; }
.row.end { justify-content: flex-end; }
.col { display: flex; flex-direction: column; gap: 8px; }
.grow { flex: 1 1 auto; min-width: 0; }
.gap4 { gap: 4px; } .gap12 { gap: 12px; } .gap16 { gap: 16px; }
.mt8 { margin-top: 8px; } .mt12 { margin-top: 12px; } .mt16 { margin-top: 16px; } .mt24 { margin-top: 24px; }
.mb8 { margin-bottom: 8px; } .mb12 { margin-bottom: 12px; } .mb16 { margin-bottom: 16px; }
.hide { display: none !important; }
/* 화면에는 안 보이고 스크린리더·검색엔진에는 읽히는 제목. 보드처럼 설명 문구를 세우지 않는 화면(writing-for-pros)의
   페이지 제목(h1)에 쓴다 — 내용은 그 화면을 정확히 설명하는 한 줄이어야 한다(검색어 나열은 숨김 텍스트 스팸이다).
   display:none·visibility:hidden은 접근성 트리에서도 빠지므로 쓰지 않는다. */
.sr-only {
    position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* 리그별 공개 페이지(League.razor · Leagues.razor, 2026-10-10 SEO). 배당 칸은 보드와 같은 뜻의 색을 쓴다:
   국내 유리=적 틴트(--dom-*), 해외 유리=청(--for-*). 정적 SSR 화면이라 상호작용은 링크와 공유 버튼뿐이다. */
.lg-tbl td.o { text-align: center; white-space: nowrap; min-width: 74px; }
.lg-tbl th.o { text-align: center; }
.lg-tbl td.o b { display: block; font-family: var(--mono); font-size: 14.5px; font-variant-numeric: tabular-nums; }
.lg-tbl td.o small { display: block; font-family: var(--mono); font-size: 11.5px; color: var(--text-3); }
.lg-tbl td.o.adv-dom { background: var(--dom-tint); }
.lg-tbl td.o.adv-dom b { color: var(--dom-soft); }
.lg-tbl td.o.adv-for small { color: var(--for-soft); }
.lg-tbl .tm a { color: var(--text); font-weight: 600; }
.lg-tbl .tm .vs { color: var(--text-3); margin: 0 4px; font-weight: 400; }
.lg-tbl .tm .more { display: block; margin-top: 2px; font-size: 11.5px; color: var(--text-3); }
.lg-tbl .m-meta { display: none; }
/* 휴대폰: 배당 칸이 가로 스크롤 밖으로 밀리지 않게 번호·시작·최대 차이 칸을 접고 팀명 아래 한 줄(.m-meta)로 싣는다. */
@media (max-width: 640px) {
    .lg-tbl .c-seq, .lg-tbl .c-time, .lg-tbl .c-max { display: none; }
    .lg-tbl .m-meta { display: block; }
    .lg-tbl td.o { min-width: 50px; padding-left: 4px; padding-right: 4px; }
    .lg-tbl td.o b { font-size: 13.5px; }
}
/* 보드 행의 경기 공유 아이콘(Board.razor .m-teams 끝). 팀명 줄의 오른쪽 끝으로 민다 — 칩이 많아 줄이 넘치면 다음 줄 끝에 선다.
   평소엔 옅게, 행에 올리면 진하게(보드는 훑는 화면이라 행마다 진한 아이콘이 서면 시선을 뺏는다). 터치 기기는 늘 진하게·넓게. */
.m-share { margin-left: auto; display: inline-flex; align-items: center; padding: 3px 5px; border-radius: 3px; color: var(--text-4); opacity: .7; }
.mrow:hover .m-share { opacity: 1; }
.m-share:hover { color: var(--text); background: var(--surface-2); }
.m-share[data-copied]::after { font-size: 11.5px; margin-left: 3px; white-space: nowrap; }
@media (hover: none) { .m-share { opacity: 1; padding: 6px 8px; margin-right: -6px; } }
.lg-share { font-size: 12px; color: var(--text-3); white-space: nowrap; }
.lg-share:hover { color: var(--text); }
[data-share][data-copied]::after { content: " ✓ 복사됨"; color: var(--accent-2); }
.lg-sec { padding: 14px 16px; margin-bottom: 12px; }
.lg-sec h2 { font-size: 14px; margin-bottom: 10px; display: flex; align-items: center; gap: 6px; }
.lg-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 6px; }
.lg-list a { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-2); color: var(--text); }
.lg-list a:hover { border-color: var(--line-strong); background: var(--surface-2); }
.lg-list .nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.lg-list .lb { font-size: 11.5px; color: var(--text-3); }
.lg-list .n { font-family: var(--mono); font-size: 12px; color: var(--text-3); }
.sw { display: inline-block; width: 9px; height: 9px; border-radius: 2px; vertical-align: -1px; flex: none; }
.sw-dom { background: var(--dom-sw); }
.sw-for { background: var(--for-sw); }

tr.expired-row, .mrow.expired-row, .mcard.expired-row { display: none; }

/* v1 모바일 카드 — 다른 페이지가 아직 쓰고 있어 유지한다 */
.mcards { display: none; flex-direction: column; gap: 8px; }
.mcard { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2); border-left: 3px solid var(--line-strong); overflow: hidden; }
.mcard.is-value { border-left-color: var(--dom); }
.mcard.is-off { opacity: .5; }
.mcard-top { display: flex; align-items: center; gap: 8px; padding: 8px 10px; background: var(--surface-2); border-bottom: 1px solid var(--line-soft); font-size: 12px; }
.mcard-top .no { color: var(--text-3); font-family: var(--mono); }
.mcard-top .when { margin-left: auto; color: var(--text-2); font-family: var(--mono); }
.mcard-vs { padding: 9px 10px 4px; }
.mcard-vs .h { font-size: 15px; font-weight: 700; }
.mcard-vs .a { font-size: 13.5px; color: var(--text-2); margin-top: 2px; }
.mcard-odds { display: grid; padding: 8px 10px 10px; grid-template-columns: 44px repeat(3, minmax(0, 1fr)); }
.mcard-odds .rl { display: flex; align-items: center; font-size: 11.5px; color: var(--text-4); font-weight: 700; }
.mcard-odds .cell { text-align: center; padding: 5px 2px; border-radius: var(--r); background: var(--surface-2); border: 1px solid var(--line-soft); }
.mcard-odds .cell .v { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 700; font-size: 15px; }
.mcard-odds .cell.adv-dom { background: var(--dom-tint); border-color: rgba(224, 87, 76, .3); }
.mcard-odds .cell.adv-dom .v { color: var(--dom-soft); }
.mcard-odds .cell.adv-for { background: var(--for-tint); border-color: rgba(61, 130, 208, .3); }
.mcard-odds .cell.adv-for .v { color: var(--for-soft); }
.mcard-odds .hd { font-size: 11px; color: var(--text-4); text-align: center; font-weight: 700; padding-bottom: 3px; }
.mcard-foot { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-top: 1px solid var(--line-soft); font-size: 12px; color: var(--text-3); }

/* ── 17. 반응형 ────────────────────────────────────────────────────────── */
@media (max-width: 1360px) {
    :root { --aside: 258px; --nav-w: 196px; }
}

/*  좌측 리그 트리는 1460px부터 접는다(종전 1180) — 본문(경기 목록)이 우선이다.
    §20 트랙이 굵어진 뒤로는(고정폭 648px + 경기명) 그 아래 폭에서 트리·경기명이 공존할 수 없다
    (실측: 1500px에서도 트리를 두면 경기명이 140px로 눌려 글자가 세로로 깨졌다).
    .shell 3단(leftnav 포함)은 배당 비교 화면 전용이라 다른 화면에는 영향이 없다. */
@media (max-width: 1460px) {
    .shell { grid-template-columns: minmax(0, 1fr) var(--aside); }
    .shell > .leftnav { display: none; }
}

@media (max-width: 1180px) {
    .shell.no-aside { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 1000px) {
    .shell, .shell.no-left, .cols { grid-template-columns: minmax(0, 1fr); }
    .aside { position: static; flex-direction: row; flex-wrap: wrap; }
    .aside > * { flex: 1 1 258px; }
    .adm { grid-template-columns: minmax(0, 1fr); }
    .adm-nav { position: static; display: flex; flex-wrap: wrap; gap: 2px; }
    .adm-nav h5, .adm-nav .sep { display: none; }
    .adm-nav a { flex: 0 0 auto; }
}

/*  GNB→햄버거 임계는 <b>1300px</b>이다(1120 아님 — 2026-08-23 재산정).
    .gnb 는 overflow:hidden 인데 그 안의 링크는 nowrap 이라 한 픽셀도 줄지 않는다 —
    폭이 모자라면 말줄임 없이 <b>글자 중간에서 잘린다</b>. 메뉴가 8개('전체 경기' 추가)로 늘고
    폰트가 14.5px로 커져 (padding 24×8 + 한글 27자) ≈ 570px 이 필요하고, 로고(≈250)와
    로그인 시 계정 영역(쪽지·닉네임·로그아웃 ≈ 415px)·gap을 빼면 뷰포트 약 1300px 부터다.
    임계가 낮던 시절에는 그 사이 구간에서 '커뮤니티'가 통째로 잘린 채 <b>햄버거도 없어</b>
    그 메뉴로 갈 방법이 화면에서 사라졌다 — 메뉴·폰트를 바꾸면 이 수치를 다시 계산할 것.
    계정 버튼(.opt)을 숨기는 임계는 860 그대로 둔다 — 그 폭까지는 로그인·회원가입이 보이는 편이 낫다. */
@media (max-width: 1300px) {
    .gnb { display: none; }
    .burger { display: flex; }
    .logo-sub { display: none; }
    .head-main { gap: 10px; }
}

@media (max-width: 860px) {
    .head-act .opt { display: none; }
}

@media (max-width: 760px) {
    :root { --hdr-h: 48px; --sport-h: 36px; }
    .main { padding: 10px 0 74px; }
    .wrap { padding: 0 10px; }
    .tabbar { display: block; }

    /*  탭바는 fixed·불투명이고 <b>푸터는 .main 의 형제</b>다 — .main 의 하단 74px 은 푸터를 지켜 주지 못한다.
        이게 없으면 문서 최하단의 법정 고지문("미성년자는 이용할 수 없습니다")이 탭바 뒤로 잘린다
        (안드로이드 13px, 노치 기기 47px ≈ 2.6줄). 하필 잘리는 문장이라 반드시 확보한다. */
    .foot { padding-bottom: calc(28px + 52px + env(safe-area-inset-bottom)); }
    .phead h1 { font-size: 17px; }
    .board { border-left: 0; border-right: 0; border-radius: 0; margin: 0 -10px; }

    /*  날짜 스트립에서 날짜칩(08/16 13시)을 뺀다. 칩까지 그리면 버튼 5개가 약 510px라
        360~430px 화면에서 '12시간·24시간'이 통째로 잘려 나가 필터를 아예 못 쓴다.
        칩을 빼면 약 270px라 그대로 들어간다 — 가로 스크롤 UI를 새로 만드는 것보다 안전하고,
        라벨(3·6·12·24시간)만으로 뜻이 통한다. */
    .datestrip .d { display: none; }

    /* 경기 행을 2줄로 접는다: 위=별·시각·팀·판정, 아래=배당 3칸.
       좁은 화면에서 팀명과 배당을 한 줄에 밀어 넣으면 둘 다 못 읽는다. */
    .mcols { display: none; }
    /* 첫 칼럼은 별 버튼 자리. 20px이면 아래에서 넓힌 히트 영역이 칼럼에 막혀 눌리는 폭이 그대로다. */
    .mcols, .mrow, .mcols.n2, .mrow.n2 { grid-template-columns: 24px 52px minmax(0, 1fr) auto; }
    .mrow { padding: 7px 10px; row-gap: 6px; }

    /*  터치 타겟 — 시각 크기는 그대로 두고 히트 영역만 넓힌다(패딩만큼 음수 마진을 줘 배치는 불변).
        별(★)은 스크롤되는 목록 안에서 12px짜리라 자주 빗나가고, 띠의 ✕는 그 띠의 유일한 닫기 수단이다.
        ✕는 margin-left:auto 로 오른쪽 끝에 붙어 있으므로 왼쪽 마진만은 auto를 유지해야 한다. */
    .m-star { padding: 10px; margin: -10px; }
    .sostrip-head .x { padding: 10px; margin: -10px -10px -10px auto; }

    /* 배당 묶음은 2행 전체를 쓰고, 판정 배지는 1행 오른쪽 끝에 고정한다.
       자동 배치에 맡기면 배지가 3행으로 밀려 혼자 왼쪽 아래에 떨어진다. */
    .m-tag { grid-row: 1; grid-column: 4; }
    .m-os { display: grid; grid-row: 2; grid-column: 1 / -1; gap: 4px; }
    .mrow.n3 .m-os { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .mrow.n2 .m-os { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .m-o { padding: 4px 3px; margin: 0; border: 1px solid var(--line-soft); background: var(--surface-2); }
    .m-o .lbl { display: block; font-size: 10.5px; color: var(--text-4); font-weight: 700; }

    /*  별도 해외는 3행 전체를 쓰는 한 줄로 눕힌다. 좁은 화면에서 배당 3칸 옆에 끼워 넣으면
        네 칸 모두 못 읽는 폭이 되고, 북 이름은 잘려서 "어느 사이트인지"를 못 말하게 된다. */
    .m-alt {
        grid-row: 3; grid-column: 1 / -1; margin: 0; padding: 4px 7px;
        display: flex; align-items: center; gap: 6px; text-align: left;
        border: 1px solid var(--line-soft); background: var(--surface-2);
    }
    .m-alt::before { content: "별도 해외"; flex: none; font-size: 10.5px; font-weight: 700; color: var(--text-4); }
    .m-alt .v { display: inline; }
    .m-alt .bk { display: inline; margin: 0; }
    .m-alt .f { margin-left: auto; }
    .m-alt.is-na { display: none; }   /* 값이 없는 행(핸디캡·언더오버)은 모바일에서 줄을 낭비하지 않는다 */

    .bkstrip { padding: 9px 10px 10px; }
    .bkstrip .tablewrap { max-height: 260px; }
    .bktbl td:first-child, .bktbl th:first-child { width: auto; }

    /*  동일배당 사례 표 — 8열 594px는 375px 화면에서 승/무/패·결과가 화면 밖으로 밀려
        "동일배당이 안 보인다"가 된다(2026-08-26 모바일 실측). 게임정보(회차#번호)·리그를 숨기고
        밀도를 줄이면 남는 열(일시·팀:스코어·배당 3칸·결과)이 한 화면에 들어온다 —
        적중 칸 강조와 결과 배지가 이 표의 핵심이라 그 둘은 반드시 화면 안에 있어야 한다. */
    .sostrip .so-info, .sostrip .so-lg, .sostrip .so-line { display: none; }
    .sostrip .tbl { font-size: 12px; }
    .sostrip .tbl thead th { padding: 6px 4px; }
    .sostrip .tbl tbody td { padding: 6px 4px; }
    /*  table-layout:fixed — 자동 레이아웃은 셀 min-content("25.10.05(일)" 71px 등) 밑으로 못 줄어
        지정 폭이 무시된다. 고정 레이아웃 + 줄바꿈 허용으로 375px 안에 강제로 맞춘다. */
    .sostrip .tbl { table-layout: fixed; width: 100%; }
    .sostrip .so-when { width: 56px !important; white-space: normal; word-break: break-all; }
    .sostrip .tbl .pb-odds { width: 40px !important; padding-left: 2px; padding-right: 2px; }
    .sostrip .so-res { width: 48px !important; padding-left: 2px; padding-right: 2px; }
    .sostrip .so-res .badge { padding: 2px 4px; font-size: 10.5px; }
    .sostrip .pb-team { white-space: normal; overflow-wrap: anywhere; }

    .tbl { font-size: 13px; }
    .tbl thead th { padding: 7px 8px; font-size: 11px; }
    .tbl tbody td { padding: 7px 8px; }

    .blist .bcat { display: none; }
    .blist .bmeta .vw { display: none; }
    .blist a { padding: 10px 12px; gap: 8px; }
    .blist .bti { font-size: 12.5px; }

    .panel-body { padding: 11px; }
    .grid-form { grid-template-columns: minmax(0, 1fr); }
    .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .foot-links { gap: 22px; }
    .modal { max-height: 92vh; }
    .modal-veil { padding: 10px; }
    .auth { min-height: auto; padding: 22px 10px 70px; }
    .calc-row { grid-template-columns: minmax(0, 1fr) 66px 24px; }
    .board-table { display: none; }
    .mcards { display: flex; }
}

@media (max-width: 420px) {
    .tiles { grid-template-columns: minmax(0, 1fr); }
    .mcard-odds { grid-template-columns: 38px repeat(3, minmax(0, 1fr)); }
}

@media print {
    .head, .sports, .subnav, .tabbar, .foot, .phead-act, .leftnav, .aside { display: none !important; }
    body { background: #fff; color: #111; }
    .panel, .board { border-color: #ccc; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

#blazor-error-ui { display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 200; background: #7a1f1f; color: #fff; padding: 9px 16px; font-size: 13px; }
#blazor-error-ui .reload { color: #fff; text-decoration: underline; }
#blazor-error-ui .dismiss { cursor: pointer; float: right; }

/* ══════════════════════════════════════════════════════════════════════════
   18. 랜딩(/) — 비로그인 방문자 전용 표면
   ──────────────────────────────────────────────────────────────────────────
   여기만 다른 리듬을 쓴다. 앱 화면(.wrap/.phead/.panel)은 13px 밀도로 "일하는 화면"이지만,
   랜딩은 처음 온 사람이 3초 안에 무엇인지 알아야 하는 "읽는 화면"이다. 그래서 이 섹션에서만
   유동 타이포(clamp)와 섹션 리듬(48~88px)을 쓴다 — 대신 DESIGN.md §2의 금지는 그대로 지킨다:
   장식 그라데이션 없음(격자는 1px 헤어라인 패턴이다), 라운드는 --r-3(10px)이 상한,
   그림자는 히어로 데모 카드 하나만, 색은 의미색(--dom 국내 / --for 해외)만 쓴다.

   ※ 랜딩 루트는 .wrap 이 아니라 .ld 다. 배경 띠(.ld-band)가 화면 폭을 꽉 채워야 하고,
     읽기 폭은 .ld-in(1180px)이 따로 잡기 때문이다. 이 예외는 DESIGN.md §7에 적어 두었다.
   ══════════════════════════════════════════════════════════════════════════ */

.ld { margin-top: -12px; }
.ld-in { max-width: 1180px; margin: 0 auto; padding: 0 clamp(14px, 3vw, 28px); }
.ld-band { padding: clamp(44px, 6.5vw, 84px) 0; border-top: 1px solid var(--line-soft); }
.ld-band.alt { background: var(--surface-2); }
.ld-band.tight { padding: clamp(28px, 4vw, 46px) 0; }

/* 타이포 — 랜딩 전용 스케일 */
.ld-eyebrow { display: inline-flex; align-items: center; gap: 7px; font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); margin-bottom: 14px; }
.ld-eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px var(--ok-dim); animation: pip 2s ease-in-out infinite; }
h1.ld-h1 { font-size: clamp(25px, 4.2vw, 43px); line-height: 1.22; letter-spacing: -.022em; font-weight: 800; color: var(--text); margin: 0; }
.ld-h1 .em { color: var(--dom-soft); }
.ld-lede { margin-top: 16px; font-size: clamp(13.5px, 1.35vw, 15.5px); line-height: 1.75; color: var(--text-2); max-width: 47ch; }
.ld-h2 { font-size: clamp(18px, 2.2vw, 26px); line-height: 1.3; letter-spacing: -.015em; font-weight: 750; color: var(--text); margin: 0; }
.ld-h2s { margin-top: 9px; font-size: 13px; line-height: 1.7; color: var(--text-2); max-width: 62ch; }
.ld-head { margin-bottom: clamp(20px, 2.6vw, 32px); }

/* 히어로 */
.ld-hero { position: relative; overflow: hidden; border-top: 0; padding-top: clamp(34px, 5vw, 66px); }
/* 데이터 표를 연상시키는 1px 격자. 장식 그라데이션이 아니라 선 패턴이며, 중간 회색 알파라
   라이트·다크 양쪽에서 같은 세기로 보인다(테마 토큰이 필요 없다). */
.ld-hero::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background-image: linear-gradient(to right, rgba(128, 140, 152, .085) 1px, transparent 1px),
                      linear-gradient(to bottom, rgba(128, 140, 152, .085) 1px, transparent 1px);
    background-size: 44px 44px;
    -webkit-mask-image: radial-gradient(115% 80% at 20% 0%, #000 35%, transparent 78%);
    mask-image: radial-gradient(115% 80% at 20% 0%, #000 35%, transparent 78%);
}
.ld-hero > * { position: relative; }
.ld-hero-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.06fr); gap: clamp(26px, 4.4vw, 54px); align-items: center; }
.ld-cta-row { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 24px; }
.ld-cta-note { margin-top: 11px; font-size: 12px; color: var(--text-3); }
.ld-cta-note b { color: var(--text-2); }

/* 히어로 데모 — 실제 배당 화면의 축약. 지어낸 수치가 아니라 '화면 예시'임을 라벨로 못 박는다. */
.ld-demo { border: 1px solid var(--line); border-radius: var(--r-3); background: var(--surface); box-shadow: var(--pop-sm); overflow: hidden; }
.ld-demo-head { display: flex; align-items: center; gap: 8px; padding: 9px 12px; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.ld-demo-head .t { font-size: 11.5px; font-weight: 700; color: var(--text-2); }
.ld-demo-head .sp { flex: 1; }
.ld-dcols { display: grid; grid-template-columns: minmax(0, 1fr) 64px 64px 62px; gap: 8px; padding: 7px 12px; background: var(--surface-2); border-bottom: 1px solid var(--line-soft); font-size: 10.5px; color: var(--text-3); letter-spacing: .02em; }
.ld-dcols span:not(:first-child) { text-align: right; }
.ld-drow { display: grid; grid-template-columns: minmax(0, 1fr) 64px 64px 62px; gap: 8px; align-items: center; padding: 9px 12px; border-bottom: 1px solid var(--line-soft); }
.ld-drow:last-child { border-bottom: 0; }
.ld-drow .lg { flex: none; }
.ld-dteam { min-width: 0; }
.ld-dteam .h { font-size: 12.5px; font-weight: 650; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ld-dteam .a { font-size: 12.5px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ld-dteam .m { margin-top: 2px; font-size: 10.5px; color: var(--text-4); }
.ld-dv { font-family: var(--mono); font-size: 13.5px; font-weight: 700; text-align: right; }
.ld-dv.dom { color: var(--dom-soft); }
.ld-dv.for { color: var(--for-soft); }
.ld-dv .u { display: block; font-size: 9.5px; font-weight: 500; color: var(--text-4); letter-spacing: .02em; }
.ld-ddiff { text-align: right; font-family: var(--mono); font-size: 12.5px; font-weight: 800; padding: 3px 0; }
.ld-drow.hit { background: var(--dom-tint); }
.ld-demo-foot { padding: 8px 12px; background: var(--surface-2); border-top: 1px solid var(--line); font-size: 11px; color: var(--text-3); }

/* 스펙 스트립 — 지어낸 홍보 수치가 아니라 수집 범위의 사실을 적는다 */
.ld-spec { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); overflow: hidden; }
.ld-spec-i { padding: 15px 16px; border-left: 1px solid var(--line-soft); }
.ld-spec-i:first-child { border-left: 0; }
.ld-spec-v { font-family: var(--mono); font-size: clamp(17px, 2vw, 21px); font-weight: 800; color: var(--text); letter-spacing: -.01em; }
.ld-spec-v small { font-size: 12px; font-weight: 600; color: var(--text-3); margin-left: 2px; }
.ld-spec-l { margin-top: 5px; font-size: 11.5px; line-height: 1.55; color: var(--text-3); }

/* 3단계 도해 */
.ld-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.ld-step { position: relative; padding: 20px 18px; border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); }
.ld-step-n { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--r); background: var(--surface-3); font-family: var(--mono); font-size: 11.5px; font-weight: 800; color: var(--text-2); }
.ld-step svg { display: block; margin: 14px 0 12px; color: var(--accent); }
.ld-step h3 { font-size: 14px; font-weight: 700; margin: 0 0 7px; color: var(--text); }
.ld-step p { font-size: 12.5px; line-height: 1.72; color: var(--text-2); margin: 0; }

/* 기능 카드 */
.ld-feats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.ld-feat { padding: 18px; border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); transition: border-color .16s, transform .16s; }
.ld-feat:hover { border-color: var(--line-strong); transform: translateY(-2px); }
.ld-feat h3 { display: flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 700; margin: 0 0 8px; color: var(--text); }
.ld-feat h3 svg { color: var(--accent); flex: none; }
.ld-feat p { font-size: 12.5px; line-height: 1.72; color: var(--text-2); margin: 0; }
.ld-mini { margin-top: 13px; padding: 9px 10px; border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--surface-2); font-family: var(--mono); font-size: 11.5px; color: var(--text-2); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* FAQ — 정적 SSR이라 details/summary로 연다(회로 불필요) */
.ld-faq { border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); overflow: hidden; }
.ld-faq details { border-bottom: 1px solid var(--line-soft); }
.ld-faq details:last-child { border-bottom: 0; }
.ld-faq summary { display: flex; align-items: center; gap: 10px; padding: 15px 16px; cursor: pointer; font-size: 13.5px; font-weight: 650; color: var(--text); list-style: none; }
.ld-faq summary::-webkit-details-marker { display: none; }
.ld-faq summary::after { content: "+"; margin-left: auto; font-family: var(--mono); font-size: 15px; color: var(--text-3); transition: transform .16s; }
.ld-faq details[open] summary::after { transform: rotate(45deg); }
.ld-faq summary:hover { background: var(--row-hover); }
.ld-faq .a { padding: 0 16px 16px 16px; font-size: 12.5px; line-height: 1.8; color: var(--text-2); }

/* 마무리 CTA */
.ld-end { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; padding: clamp(22px, 3vw, 32px); border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); }
.ld-end h2 { font-size: clamp(17px, 2vw, 22px); font-weight: 750; margin: 0 0 7px; color: var(--text); }
.ld-end p { font-size: 12.5px; color: var(--text-2); margin: 0; }

/* 등장 애니메이션 — land.js가 <html>에 .js-reveal을 붙일 때만 숨긴다(JS 실패 시 그냥 다 보인다) */
.js-reveal .ld-reveal { opacity: 0; transform: translateY(9px); }
.js-reveal .ld-reveal.is-in { opacity: 1; transform: none; transition: opacity .52s cubic-bezier(.22, .61, .36, 1), transform .52s cubic-bezier(.22, .61, .36, 1); }
.js-reveal .ld-reveal[data-d="1"].is-in { transition-delay: .07s; }
.js-reveal .ld-reveal[data-d="2"].is-in { transition-delay: .14s; }
.js-reveal .ld-reveal[data-d="3"].is-in { transition-delay: .21s; }

@media (max-width: 1000px) {
    .ld-hero-cols { grid-template-columns: minmax(0, 1fr); gap: 30px; }
    .ld-lede { max-width: none; }
    .ld-steps, .ld-feats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ld-feats > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}

@media (max-width: 760px) {
    /* .ld의 음수 마진은 .main 의 위쪽 패딩을 정확히 상쇄하려는 것인데, 이 폭에서 그 패딩이
       12px→10px로 줄어 2px만큼 헤더 위로 파고들었다. 같은 값으로 맞춘다. */
    .ld { margin-top: -10px; }

    .ld-spec { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ld-spec-i:nth-child(3) { border-left: 0; }
    .ld-spec-i:nth-child(n+3) { border-top: 1px solid var(--line-soft); }
    .ld-steps, .ld-feats { grid-template-columns: minmax(0, 1fr); }
    .ld-cta-row .btn { flex: 1 1 auto; justify-content: center; }
    .ld-dcols, .ld-drow { grid-template-columns: minmax(0, 1fr) 54px 54px 56px; gap: 6px; padding-left: 10px; padding-right: 10px; }
    .ld-end { flex-direction: column; align-items: stretch; }
    .ld-end .btn { justify-content: center; }
}

@media (max-width: 420px) {
    .ld-dcols span:nth-child(3), .ld-drow > .ld-dv.for { display: none; }
    .ld-dcols, .ld-drow { grid-template-columns: minmax(0, 1fr) 56px 58px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   19. 이용권 잠금(플랜 게이트)

   상위 이용권에서만 열리는 기능을 만났을 때의 표면이다. 두 가지를 동시에 해야 한다:
     (1) 왜 막혔는지 즉시 알린다 — "권한이 없습니다" 같은 오류 화면으로 보이면 안 된다.
     (2) 여기서 바로 결제로 갈 수 있게 한다 — 무엇이 열리는지 · 얼마인지 · 어디를 누르는지.

   장식은 넣지 않는다(DESIGN.md §2). 강조는 좌측 3px 강조선과 자물쇠 하나뿐이고,
   나머지는 본문과 같은 밀도·같은 글자 크기를 쓴다.
   ═══════════════════════════════════════════════════════════════════════ */

.plock {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent-2);
    border-radius: var(--r-3);
    padding: 20px 22px 18px;
}

.plock-top { display: flex; align-items: flex-start; gap: 12px; }

.plock-ic {
    flex: none; width: 34px; height: 34px; display: grid; place-items: center;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2);
    color: var(--accent-2);
}
.plock-ic svg { width: 17px; height: 17px; display: block; }

.plock-kicker {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    font-size: 12px; color: var(--text-4); letter-spacing: .02em;
}
.plock h3 { font-size: 17px; margin-top: 3px; }
.plock-lede { margin-top: 8px; font-size: 13.5px; line-height: 1.75; color: var(--text-2); }
/* 설명 위 강조 한 줄(Info.Headline) — 지금은 PREMIUM TIP뿐이라 그 정체색(--tippick, 보드 is-tip 링과 같은 보라)을 쓴다.
   그라데이션 글자는 background-clip:text 미지원 브라우저에서 투명 글자가 되므로 단색을 먼저 깔고 @supports로만 덮는다. */
.plock-headline {
    margin-top: 10px; font-size: 18px; font-weight: 800; line-height: 1.4; letter-spacing: -.01em;
    color: var(--tippick);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .plock-headline {
        background: linear-gradient(90deg, var(--tippick), var(--tippick-2));
        -webkit-background-clip: text; background-clip: text; color: transparent;
        width: fit-content; max-width: 100%;
    }
}
.plock-headline + .plock-lede { margin-top: 4px; }
.plock-headline.sm, .plock.sm .plock-headline { font-size: 15px; margin-top: 6px; }

/* 무엇이 열리는지 — 잠긴 화면에서 가장 많이 읽히는 부분이라 본문 밀도로 촘촘히 쌓는다. */
.plock-pts { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.plock-pts li {
    position: relative; padding-left: 17px;
    font-size: 13px; line-height: 1.65; color: var(--text-2);
}
.plock-pts li::before {
    content: ""; position: absolute; left: 2px; top: 7px;
    width: 5px; height: 5px; border-radius: 50%; background: var(--accent-2);
}

.plock-buy {
    margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line-soft);
    display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
}
.plock-price { display: flex; align-items: baseline; gap: 4px; }
.plock-price b { font-size: 20px; color: var(--text); }
.plock-price small { font-size: 11.5px; color: var(--text-4); }
.plock-act { display: flex; gap: 8px; flex-wrap: wrap; }

.plock-foot { margin-top: 12px; font-size: 11px; line-height: 1.7; color: var(--text-4); }

/* 사이드 위젯·행 안에 끼우는 축소판. 값이 아니라 안내가 목적이라 가격·버튼만 남긴다. */
.plock.sm { padding: 14px 15px 13px; }
.plock.sm h3 { font-size: 14.5px; }
.plock.sm .plock-lede { font-size: 12.5px; margin-top: 6px; }
.plock.sm .plock-buy { margin-top: 12px; padding-top: 11px; }
.plock.sm .plock-price b { font-size: 16px; }

/* 잠긴 버튼(서브내비 등) — 누를 수는 있고, 누르면 잠금 안내가 뜬다.
   disabled로 두지 않는 이유: 클릭이 곧 결제 동선의 시작점이기 때문이다. */
.lockbtn { opacity: .72; }
.lockbtn .lk {
    display: inline-flex; align-items: center; margin-left: 5px;
    font-size: 10.5px; font-weight: 800; letter-spacing: .06em;
    color: var(--accent-2); border: 1px solid var(--accent-2);
    border-radius: 3px; padding: 0 3px; line-height: 1.5;
}
.lockbtn:hover { opacity: 1; }

/* 드로어·GNB의 잠금 표시 — 메뉴 폭을 늘리지 않도록 배지만 얹는다. */
.gnb a .lk, .drawer a.dl .lk {
    font-size: 10.5px; font-weight: 800; letter-spacing: .05em;
    color: var(--accent-2); border: 1px solid var(--accent-2);
    border-radius: 3px; padding: 0 3px; margin-left: 4px;
}

/* /pricing 에서 어떤 카드로 가라는 것인지 표시 — 링크로 넘어왔을 때만 붙는다. */

@media (max-width: 620px) {
    .plock { padding: 16px 15px 15px; }
    .plock-buy { align-items: stretch; }
    .plock-act { width: 100%; }
    .plock-act .btn { flex: 1 1 auto; justify-content: center; }
}

/* ═══════════════ §18-b 랜딩 전체 경기 목록(프로토 보드, Home.razor) ═══════════════
   와이즈토토형 전 경기 표. 회차·종목 탭은 정적 SSR이라 쿼리스트링 링크(?round=&sport=)다. */
.pb-bar { display: flex; flex-direction: column; gap: 8px; }
.pb-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.pb-tab {
    display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 13px;
    border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
    color: var(--text-2); font-size: 13.5px; font-weight: 700; text-decoration: none; white-space: nowrap;
}
.pb-tab:hover { background: var(--surface-2); }
.pb-tab.is-on { color: var(--accent-2); border-color: var(--accent-line); background: var(--accent-dim); }
.pb-tab .n { font-family: var(--mono); font-size: 11.5px; font-weight: 600; color: var(--text-3); }
.pb-tab.is-on .n { color: var(--accent-2); }

/* 표가 화면을 다 먹지 않게 자체 스크롤 — 회차당 수백 행이라 페이지 스크롤로 두면 아래 소개 섹션이 묻힌다. */
.pb-wrap { max-height: 640px; overflow-y: auto; }
.pb-no { color: var(--accent); font-weight: 700; }
.pb-team .h { font-weight: 700; }
.pb-team .x { color: var(--text-3); font-size: 11.5px; padding: 0 2px; }
.pb-team .a { color: var(--text-2); }
.pb-odds { font-family: var(--mono); text-align: right; font-size: 15px; font-weight: 700; }
.pb-score { margin-left: 6px; color: var(--text-2); font-size: 12.5px; }

@media (max-width: 620px) {
    .pb-wrap { max-height: 520px; }
}

/* ═══════════════ §20 벳인포형 3단 배치 (/odds, .board.bi) ═══════════════
   2026-08-19 의뢰인 요구. 예전 배치는 한 칸에 국내(13px)·해외(10px)·차이를 겹쳐 쌓고
   글자 크기로 값의 출처를 인코딩했는데, "눈에 안 들어오고 헷갈린다"는 지적을 받았다.
   크기 대신 <b>열</b>로 가른다: 국내 3칸 | 해외 3칸 | 차이 3칸. 모든 배당이 같은 크기다. */

/*  트랙: [★ 24][시작 60][경기 1fr][국내×3 56][해외×3 56][차이×3 54][판정 66]
    합계 고정폭 = 24+60+168+168+162+66 = 648px + 경기명 가변. --shell 1500에서 트리(212)·사이드바(286)를
    빼면 경기명에 약 270px가 남는다(실측 2026-08-23 — 748px였을 때 경기명이 140px로 눌려 세로로 깨졌다).
    배당 숫자는 16px(의뢰인: "시원시원하게")이고 "0.00" 네 자리가 56px 안에 들어간다. */
/*  ⚠ 열 폭 재배분(2026-08-25) — 해외 칸에만 배당사 칩이 붙어 글자 예산이 필요하다(의뢰인: "로고가 너무 작다").
    레이아웃 전체 폭은 못 늘린다(shell 1448px가 이미 노트북 뷰포트에 꽉 참) → 남는 데서 가져온다.
    실측 최대 내용: 국내 47px("14.00") · 차이 49px("-10.8%") · 해외는 칩이 지배한다.
    국내 56→51 · 차이 54→51 · 해외 56→64. <b>합계는 498px로 정확히 동일</b>하므로
    경기명(minmax(0,1fr))이 받는 폭은 1px도 변하지 않는다 — 팀명 잘림 위험 없음. */
/*  판정 열 66→72(2026-09-02 의뢰인: "핸디→일반승이 잘려 보인다") — 국내·차이 51→50에서 가져와
    합계는 그대로다(국내 실측 최대 47px·차이 49px라 50px로도 안 잘린다). */
.board.bi .bicols, .board.bi .bigroups, .board.bi .mrow {
    grid-template-columns: 24px 60px minmax(0, 1fr) repeat(3, 50px) repeat(3, 64px) repeat(3, 50px) 72px;
}
.board.bi .bicols.n2, .board.bi .bigroups.n2, .board.bi .mrow.n2 {
    grid-template-columns: 24px 60px minmax(0, 1fr) repeat(2, 50px) repeat(2, 64px) repeat(2, 50px) 72px;
}

/* 1단: 그룹 이름(국내·해외·차이). 각 그룹이 제 칸 수만큼 span 한다.
   높이를 고정한다 — 아래 .bicols 의 sticky top 이 이 높이에 정확히 이어져야 한다. */
.board.bi .bigroups {
    position: sticky; top: var(--stick); z-index: 6;
    display: grid; align-items: center; height: 30px; padding: 0 10px;
    background: var(--surface-2); border-bottom: 1px solid var(--line-soft);
    font-size: 12.5px; font-weight: 700; letter-spacing: .04em;
}
.board.bi .bigroups .gg { grid-column: span 3; text-align: center; border-left: 1px solid var(--line); }
.board.bi .bigroups.n2 .gg { grid-column: span 2; }
.board.bi .bigroups .gg-bm { color: var(--dom-soft); background: var(--dom-tint); }
.board.bi .bigroups .gg-for { color: var(--for-soft); }
.board.bi .bigroups .gg-df { color: var(--text-2); }

/*  2단: 셀렉션 라벨(승·무·패). 그룹 색을 옅게 이어받아 어느 그룹의 칸이었는지 유지한다.
    ⚠ 이 요소는 .mcols 클래스를 달지 않는다 — grid·sticky·배경을 <b>여기서 전부</b> 줘야 한다.
    top 만 주면 display 가 기본값이라 span 들이 "시작경기승무패승무패…" 한 줄로 뭉개진다(실측 2026-08-23). */
.board.bi .bicols {
    position: sticky; top: calc(var(--stick) + 30px); z-index: 5;
    display: grid; align-items: center; gap: 0;
    padding: 6px 10px; background: var(--surface-2); border-bottom: 1px solid var(--line);
    font-size: 12px; font-weight: 700; letter-spacing: .04em; color: var(--text-4);
}
.board.bi .bicols .g { text-align: center; }
.board.bi .bicols .gh-bm { background: var(--dom-tint); color: var(--dom-soft); }
.board.bi .bicols .gh-for { color: var(--for-soft); }
.board.bi .bicols .gh-df { color: var(--text-3); }

/* 배당·차이 칸 — 세 그룹 모두 같은 글자 크기(출처는 열이 말한다) */
.board.bi .bi-o { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; min-height: 38px; }
.board.bi .bi-o .o-now { font-size: 16px; }
/*  칸 이름(언더/오버 · 승/무/패) — 2026-09-21 의뢰인: "어디가 오버인지 언더인지 헷갈린다".
    마크업에는 항상 싣고 <b>보일 자리만</b> 여기서 정한다(뷰포트는 서버가 모른다).
    ① 기본(넓은 화면 + 탭 보기)은 숨긴다 — 열 머리글(.bicols)이 이미 언더/오버를 적는다.
    ② 추출·프라임 추출은 머리글이 ①②③이다(마켓이 섞여 행마다 뜻이 다르다) → 세 묶음 전부 켠다.
    ③ 좁은 화면(≤1180)은 머리글이 통째로 접힌다 → 아래 §16에서 국내 줄에만 켠다. */
.board.bi .bi-o .o-sel { display: none; font-size: 10px; line-height: 1.15; white-space: nowrap; }
.board.bi.is-extract .bi-o .o-sel { display: block; }
/*  추출 화면은 해외 칸에 '4곳 평균'(prime이면 α까지) 줄이 더 붙어 칸마다 높이가 다르다. .mrow가
    align-items:center라 그대로 두면 같은 행의 '언더' 라벨이 국내·해외·차이에서 서로 다른 높이에
    앉는다 — 이름이 어긋나 보이면 이름을 붙인 뜻이 없다. 칸을 행 높이에 맞춰 늘리고 위에서부터 쌓는다. */
.board.bi.is-extract .bi-o { align-self: stretch; justify-content: flex-start; }
.board.bi .bi-o .o-open { font-size: 11px; display: inline-flex; align-items: center; gap: 1px; }
.board.bi .bi-o .diff { font-size: 14px; }
/* 핸디캡·언더오버 칸의 출처 배당사(의뢰인 2026-08-23 요구). 값이 하나뿐인 마켓이라 출처가 단일 북으로
   확정된다 — 승무패(평균) 칸에는 붙이지 않는다.
   ⚠ 처음엔 BookChip(로고 우선)을 그대로 넣었는데 <b>칸 폭이 56px</b>이라 로고가 높이 10px로 뭉개져
/*  (삭제) .o-book — 배당 칸에 배당사 실명을 찍던 칩이다. 2026-08-30 법률 검토로
    해외 업체의 상호를 어떤 표면에도 내보내지 않기로 하면서 마크업과 함께 규칙도 지웠다. */
/*  좁은 화면(≤1180)에서는 보드가 3행으로 접혀 해외 행이 폭을 통째로 나눠 쓴다(칸이 오히려 넓어진다) —
    글자를 줄일 이유가 없다. 줄바꿈만은 절대 금지(white-space: nowrap): 칩이 두 줄이 되면 행 높이가 폭발한다. */
/* 계산기 독에 담긴 픽 — 어느 칸이 슬립에 있는지 표에서 바로 보이게 */
.board.bi .bi-o.in-slip { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r); }

/*  판정 열(배지 무더기) — 세로로 쌓는다. 핸디 배지 + 해외N 버튼이 옆으로 나란히 서면 72px를 넘는다.
    배지 글자는 10px — "핸디→일반승" 여섯 자가 72px 안에 들어가는 크기다(2026-09-02 의뢰인: 잘림 수정). */
.board.bi .m-tag { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; }
.board.bi .m-tag .badge { font-size: 10px; padding: 2px 4px; white-space: nowrap; letter-spacing: -.01em; }

/*  PREMIUM TIP 예상 픽 칸(2026-09-02 의뢰인: "보라색으로 굵게, 다만 세련되게") — 굵은 단색 테두리 대신
    보라 이중 링: 안쪽 1.5px 실선 + 옅은 보라 면. 프라임(FreeTips) 세션에만 클래스가 붙는다. */
.board.bi .bi-o.tip-pick {
    box-shadow: inset 0 0 0 1.5px var(--tippick);
    background: var(--tippick-dim);
    border-radius: var(--r);
}
.board.bi .bi-o.tip-pick .o-now { color: var(--tippick); }

/*  PREMIUM TIP 경기 행(2026-09-02 의뢰인: "테두리를 보라색으로 — 단순 보라 말고 세련되게,
    좌상단에 PREMIUM TIP 팻말"). 굵은 단색 테두리 대신 행을 카드처럼 살짝 띄우고:
      · 마스크로 속을 뚫은 1.5px 보라 그라데이션 링(::before) — 내용은 전혀 가리지 않는다
      · 링을 6초에 한 번 훑고 지나가는 광택(그라데이션 팬) — 동작 최소화 설정에선 멈춘다.
        그라데이션은 시작·끝 색이 같은 2주기 반복이라 루프 이음새가 보이지 않는다.
      · 좌상단 팻말(::after) — 마크업 없이 CSS content로 세워 그리드 배치에 끼어들지 않는다
    ⚠ 좌우 마진은 주지 않는다 — 고정폭 배당 칼럼이 머리글(.bicols)과 어긋난다. 수직 마진만 줘
      팻말이 앞 행을 덮지 않을 방을 만든다. */
.board.bi .mrow.is-tip {
    position: relative;
    margin: 14px 0 8px;
    border-radius: 10px;
    border-bottom-color: transparent;
    background: linear-gradient(165deg, var(--tippick-dim), transparent 52%);
    box-shadow: 0 4px 18px rgba(109, 63, 209, .12);
}
.board.bi .mrow.is-tip::before {
    content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px;
    background: linear-gradient(115deg,
        var(--tippick), var(--tippick-2) 25%, var(--tippick) 50%, var(--tippick-2) 75%, var(--tippick))
        0 0 / 200% 100%;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    animation: tipring 6s linear infinite;
}
@keyframes tipring { to { background-position: 100% 0; } }
@media (prefers-reduced-motion: reduce) { .board.bi .mrow.is-tip::before { animation: none; } }
.board.bi .mrow.is-tip::after {
    content: "PREMIUM TIP";
    position: absolute; top: -9px; left: 12px; z-index: 1;
    padding: 3px 8px;
    border-radius: 4px;
    background: linear-gradient(120deg, #6d28d9, #9333ea);
    color: #fff; font-size: 9.5px; font-weight: 800; letter-spacing: .14em; line-height: 1;
    box-shadow: 0 2px 6px rgba(76, 29, 149, .35), inset 0 1px 0 rgba(255, 255, 255, .25);
}
.board.bi .bi-o.is-na .o-now { font-weight: 400; color: var(--text-4); }
/* 국내 칸만 유불리 틴트를 받는다 — 셋 다 칠하면 행 전체가 색으로 덮여 오히려 안 읽힌다. */
.board.bi .bi-o.dom.adv-dom { background: var(--dom-tint); }
.board.bi .bi-o.dom.adv-dom .o-now { color: var(--dom-soft); }
.board.bi .bi-o.dom.adv-for { background: var(--for-tint); }
.board.bi .bi-o.dom.adv-for .o-now { color: var(--for-soft); }
.board.bi .bi-o.clickable { cursor: pointer; }
.board.bi .bi-o.clickable:hover { background: var(--surface-3); }
.board.bi .bi-o.is-open { box-shadow: inset 0 -2px 0 var(--accent); }
/* 그룹 경계 세로선을 본문까지 이어 내린다(헤더에서만 그으면 열이 흩어져 보인다) */
.board.bi .bi-dom > .bi-o:first-child,
.board.bi .bi-for > .bi-o:first-child,
.board.bi .bi-dif > .bi-o:first-child { border-left: 1px solid var(--line); }

/* 경기 표기 "#4816 김포FC : 김천상무" — 한 줄, 홈은 굵게 원정은 흐리게 */
.bi-teams { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.bi-teams .h { font-size: 14.5px; font-weight: 700; color: var(--text); }
.bi-teams .x { font-size: 12px; color: var(--text-4); }
.bi-teams .a { font-size: 14.5px; color: var(--text-2); }
.bi-teams .m-no { flex: none; font-family: var(--mono); font-size: 12.5px; font-weight: 700; color: var(--accent); }

/* 판정 칸의 전 북 펼침 버튼 */
.bi-books {
    height: 24px; padding: 0 8px; margin-left: 4px;
    background: var(--surface-3); border: 1px solid var(--line); border-radius: 3px;
    font-size: 12px; font-weight: 700; color: var(--text-3); cursor: pointer;
}
.bi-books:hover, .bi-books.on { color: var(--accent-2); border-color: var(--accent-line); background: var(--accent-dim); }

/*  좁은 화면: 13열은 접는다. 1행 경기명, 2행 국내, 3행 해외, 4행 차이 —
    DESIGN.md §5의 "760px 이하에서 가로 스크롤 금지"를 지킨다.
    임계는 1180(종전 980) — 981~1180 구간에서 13열을 유지하면 경기명이 130px대로 눌린다(폰트 확대 여파). */
@media (max-width: 1180px) {
    .board.bi .bigroups, .board.bi .bicols { display: none; }
    .board.bi .mrow {
        grid-template-columns: 24px 60px minmax(0, 1fr);
        grid-auto-rows: auto; row-gap: 3px; padding: 7px 10px;
    }
    .board.bi .mrow.n2 { grid-template-columns: 24px 60px minmax(0, 1fr); }
    .board.bi .m-tag { grid-row: auto; grid-column: 1 / -1; }
    /*  ⚠ ≤760의 구 보드용 규칙(.m-os { grid-row: 2 })이 여기도 걸린다 — bi 보드의 세 묶음이
        전부 2행에 겹쳐 숫자가 포개진다(실측 2026-08-23). grid-row를 자동으로 되돌려 소스 순서대로
        국내→해외→차이가 한 줄씩 내려가게 한다. */
    .board.bi .bi-dom, .board.bi .bi-for, .board.bi .bi-dif {
        display: grid; grid-row: auto; grid-column: 1 / -1;
        grid-template-columns: 34px repeat(3, minmax(0, 1fr)); align-items: center; gap: 3px;
    }
    .board.bi .mrow.n2 .bi-dom, .board.bi .mrow.n2 .bi-for, .board.bi .mrow.n2 .bi-dif {
        grid-template-columns: 34px repeat(2, minmax(0, 1fr));
    }
    /* 행 앞에 무슨 값인지 라벨을 붙인다(헤더가 접혔으므로) */
    .board.bi .bi-dom::before, .board.bi .bi-for::before, .board.bi .bi-dif::before {
        font-size: 11.5px; font-weight: 700; color: var(--text-4); letter-spacing: .03em;
    }
    .board.bi .bi-dom::before { content: "국내"; color: var(--dom-soft); }
    .board.bi .bi-for::before { content: "해외"; color: var(--for-soft); }
    .board.bi .bi-dif::before { content: "차이"; }
    .board.bi .bi-dom > .bi-o:first-child,
    .board.bi .bi-for > .bi-o:first-child,
    .board.bi .bi-dif > .bi-o:first-child { border-left: 0; }
    .board.bi .bi-o { min-height: 32px; }
    /*  열 머리글(.bicols)이 위에서 display:none이 됐으므로 <b>언더/오버·승/무/패를 말해 줄 곳이 없다</b>
        (2026-09-21 의뢰인 신고의 실제 화면). 국내 줄에만 붙인다 — 해외·차이 줄은 같은 열 위치를
        공유하므로 세 줄 모두 붙이면 뜻은 그대로인 채 행 높이만 세 배가 된다. */
    .board.bi .bi-dom .bi-o .o-sel { display: block; }
    .board.bi .bi-for .bi-o .o-sel, .board.bi .bi-dif .bi-o .o-sel { display: none; }
}

/*  (삭제 2026-09-29) 시작된 경기를 흐리게 남기던 §20 재정의 — 의뢰인이 진행중 경기 배당을 빼기로 해,
    킥오프가 지난 행은 §16의 expired-row(display:none)대로 사라진다. */

/*  발매전 회차 안내 띠(메인 전체 경기 목록). 배당 칸이 전부 "—"인 이유를 그 자리에서 밝힌다 —
    안내가 없으면 "배당이 전부 없다"(2026-08-21 실보고)로 읽힌다. */
.pb-note {
    display: flex; flex-wrap: wrap; align-items: center; gap: 5px;
    padding: 9px 11px; border: 1px solid var(--accent-line); border-radius: var(--r);
    background: var(--accent-dim); font-size: 12px; color: var(--text-2);
}
.pb-note b { color: var(--text); }
.pb-note a { color: var(--accent-2); font-weight: 700; }

/* ── §18-b 확장(2026-08-23): 메인 전면 개편 — 경기판 하나가 곧 페이지다 ──
   와이즈토토·벳인포의 정보 어휘(종목 아이콘·적중 강조·스코어 인라인)만 가져오고
   색·모양은 기존 토큰 그대로(의뢰인: "기존 색감·추세 유지, 저곳들의 장점만"). */

/* 종목 이모지 열 — 이모지 자체가 색이라 배경·테두리 없이 크기만 준다 */
.pb-ico { text-align: center; font-size: 15px; line-height: 1; padding-left: 2px !important; padding-right: 2px !important; color: var(--text-2); }
.pb-ico .sico { vertical-align: middle; }
.pb-tab .ico { font-size: 13px; margin-right: 1px; }

/* 팀 사이 스코어 인라인(끝난 경기) — "텍사레인 2 : 0 워싱내셔" */
.pb-team .sc { font-family: var(--mono); font-weight: 800; font-size: 14px; color: var(--text); margin: 0 1px; }

/* 적중 셀렉션 배당 강조 — 와이즈토토의 주황 배경 역할을 우리 dom 틴트로 */
.pb-odds.hit { background: var(--dom-tint); color: var(--dom-soft); font-weight: 800; box-shadow: inset 0 0 0 1px rgba(224, 87, 76, .25); }

/* 메인이 경기판 하나뿐이므로 표가 화면을 넉넉히 쓴다(종전 640px 고정은 마케팅 밴드와 공존하던 시절 값) */
.pb-wrap.pb-tall { max-height: calc(100vh - 240px); min-height: 480px; }
@media (max-width: 620px) {
    .pb-wrap.pb-tall { max-height: calc(100vh - 200px); min-height: 400px; }
}

/* 팀 구분자 ':' 간격 — Razor if 블록이 스팬 사이 공백을 먹어 팀명이 붙어 보인다(실측) */
.pb-team .x { margin: 0 4px; }
.pb-team .sc + .x, .pb-team .x + .sc { margin: 0 2px; }

/* ═══════════════ §18-c 메인 포털 레이아웃(Home.razor) ═══════════════
   2026-08-23 의뢰인: "아직 비어 보인다 — 있는 기능 전부 넣고 색감까지". 와이즈토토식 밀도를
   우리 토큰으로 옮겼던 화면인데, 2026-09-01 의뢰인 지시로 좌측을 배당 비교(Board)의 트리 문법으로
   다시 줄였다: 리그 트리(.tree) + 발매 현황(.pb-sale)만 남는다(로그인·도구·바로가기 CSS도 함께 삭제). */
.pb-portal { display: grid; grid-template-columns: 236px minmax(0, 1fr); gap: 14px; align-items: start; }
.pb-side { position: sticky; top: calc(var(--stick) + 8px); display: flex; flex-direction: column; gap: 10px; }

/* 발매 현황 — 상태 점 · 게임명 · 회차 · 상태 배지 한 줄. 현재 보고 있는 회차는 켜져 보인다. */
.pb-sale { display: flex; flex-direction: column; gap: 2px; padding: 5px; }
.pb-sale a {
    display: flex; align-items: center; gap: 7px; padding: 7px 9px; font-size: 13px;
    border: 1px solid transparent; border-radius: var(--r-2);
    transition: background .1s, border-color .1s;
}
.pb-sale a:hover { background: var(--surface-2); border-color: var(--line-soft); }
.pb-sale a.is-on { background: var(--accent-dim); border-color: var(--accent-line); }
.pb-sale .nm { font-weight: 700; color: var(--text); }
.pb-sale .rd { font-family: var(--mono); font-size: 12.5px; color: var(--text-3); }
.pb-sale .badge { margin-left: auto; }
/* 상태 점 — 발매중은 헤더의 실시간 배지와 같은 초록 점멸(.feed .pip), 발매전은 주황, 마감은 무채색 */
.pb-sale .st { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--line-strong); }
.pb-sale .st.live { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-dim); animation: pip 2s ease-in-out infinite; }
.pb-sale .st.pre { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-dim); }

/* 본문 표 헤더를 네이비 밴드로 — 와이즈토토의 인상. --accent-solid는 흰 글자 대비(AA)가
   보장된 유일한 파랑 면 토큰이다(§1 주석). 스크롤 시 sticky 헤더가 이 색으로 떠 있는다. */
.pb-main .pb-wrap .tbl thead th {
    background: var(--accent-solid); color: #fff;
    border-bottom: 1px solid var(--accent-solid);
}

/* 번호 링크(→ /odds?q=) — 눌러진다는 것이 보여야 한다 */
a.pb-no { text-decoration: none; }
a.pb-no:hover { text-decoration: underline; }

/* 검색 폼(GET) — panel-head 우측. 정적 SSR이라 @bind 대신 폼 제출이다(2026-09-02). */
.pb-search { margin-left: auto; }

/* 배당 → 계산기 담기 링크. 칸 전체가 눌리게 블록으로 펴고, 링크 티는 호버에서만 낸다 —
   상시 밑줄·파랑이면 배당표가 링크 무더기로 보인다(의뢰인 색감 유지 원칙). */
.pb-odds a.pb-calc { display: block; margin: -6px -8px; padding: 6px 8px; color: inherit; border-radius: var(--r); }
.pb-odds a.pb-calc:hover { background: var(--accent-dim); color: var(--accent-2); }

@media (max-width: 1000px) {
    /* 모바일: 경기판 먼저, 사이드바 패널들은 아래에 2열로(sticky는 세로 흐름에서만 뜻이 있어 푼다) */
    .pb-portal { grid-template-columns: minmax(0, 1fr); }
    .pb-side { position: static; order: 2; display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); align-items: start; }
}

/* ═══════════════ §21 우측 하단 독 — 계산기·PREMIUM TIP (배당 비교) ═══════════════
   2026-08-23 의뢰인 요구: "계산기를 배당비교 페이지 안에서, PREMIUM TIP은 우측 하단 사이드바처럼".
   버튼 두 개가 항상 떠 있고, 패널은 한 번에 하나만 열린다. z-index는 탭바(70) 위 · 드로어(90) 아래. 팝업 딤(84)·창(85)은 독 위 · 드로어(90/91)·모달(100) 아래. */
.dock { position: fixed; right: 16px; bottom: 16px; z-index: 80; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.dock-btns { display: flex; gap: 8px; }
.dock-btn {
    display: inline-flex; align-items: center; gap: 6px; height: 42px; padding: 0 17px;
    border-radius: 999px; background: var(--accent-solid); border: 1px solid var(--accent-solid);
    color: #fff; font-size: 14.5px; font-weight: 700; cursor: pointer; box-shadow: var(--pop-sm);
    transition: filter .12s, background .12s, color .12s, border-color .12s;
}
.dock-btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.dock-btn { transition: filter .12s, background .12s, color .12s, border-color .12s, transform .12s; }
.dock-btn.on { background: var(--surface); border-color: var(--accent); color: var(--accent-2); filter: none; transform: none; }
.dock-btn .ic { font-size: 16px; line-height: 1; }
.dock-btn .n {
    min-width: 21px; height: 21px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 999px; background: rgba(255, 255, 255, .24); font-size: 12.5px; font-weight: 800;
}
.dock-btn.on .n { background: var(--accent-dim); color: var(--accent-2); }

/*  패널 — 2026-09-02 상용화급 정돈: 폭 430px(다중 조합 목록이 눕지 않게), 머리에 기능명·이동 링크·
    닫기만 남기고 본문 여백을 12px로 통일. 과한 라운드·그라데이션은 금지(DESIGN.md §2). */
.dock-panel {
    width: min(430px, calc(100vw - 32px)); max-height: min(76vh, 700px);
    display: flex; flex-direction: column; overflow: hidden;
    background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-3);
    box-shadow: var(--pop); animation: pop .18s cubic-bezier(.2, .8, .3, 1);
}
.dock-head { display: flex; align-items: center; gap: 10px; padding: 12px 16px; background: var(--surface-2); border-bottom: 1px solid var(--line); flex: none; }
.dock-head b { font-size: 15px; letter-spacing: -.01em; }
.dock-head a { margin-left: auto; font-size: 12.5px; color: var(--text-3); }
.dock-head a:hover { color: var(--accent-2); }
.dock-body { overflow-y: auto; padding: 12px; }
/* 패널 자체가 카드라 내부 widget의 테두리는 이중선이 된다 — 지운다. */
.dock-body .widget { border: 0; }
.dock-hint {
    margin-bottom: 10px; padding: 9px 11px; border: 1px solid var(--accent-line); border-radius: var(--r);
    background: var(--accent-dim); font-size: 13px; line-height: 1.6; color: var(--text-2);
}
.dock-hint b { color: var(--text); }

@media (max-width: 760px) {
    /* 탭바(52px + safe-area)가 하단을 차지한다 — 그 위로 띄운다. */
    .dock { right: 8px; bottom: calc(62px + env(safe-area-inset-bottom)); }
    .dock-panel { width: calc(100vw - 16px); max-height: 60vh; }
}

/* PREMIUM TIP 미니 리스트(독 패널 안) */
.tipmini { padding: 10px 11px; border-bottom: 1px solid var(--line-soft); }
.tipmini:last-child { border-bottom: 0; }
.tipmini .tm { margin-top: 6px; font-size: 14px; color: var(--text-2); }
.tipmini .tm b { color: var(--text); }
.tipmini .tm .x { color: var(--text-4); }
.tipmini .pk { margin-top: 6px; flex-wrap: wrap; }
/* (삭제) .tipmini .src — 출처 상호 비표시(2026-08-30) 이후 .src 요소가 없는 고아 규칙이었다. */

/* (삭제) .board.veiled — 회차 전환기 가림막은 상태 안내 전면 금지(2026-09-01 writing-for-pros)로
   안내 띠와 함께 제거됐다. 보드는 언제나 그대로 그린다. */

/* ═══════════════ §22 관리자 팝업 · 상단 배너 · 알림함 (2026-08-27) ═══════════════

   팝업은 관리자가 쓴 HTML을 담는 <b>그릇</b>만 제공한다. 안쪽 서식은 관리자가 정하므로
   여기서는 위치·크기·머리띠·바닥만 잡고 본문에는 최소한의 기본값(문단 간격·이미지 폭)만 준다.
   그 최소값마저 없으면 <p> 두 줄이 붙어 나와 "고장 난 것처럼" 보인다.

   ⚠ 팝업은 hidden 으로 렌더되고 popup.js 가 벗긴다(닫아 둔 팝업의 깜빡임 방지). 그래서
     .pop-win[hidden] 에 display:none 을 다시 적지 않는다 — hidden 기본 동작으로 충분하다. */

.pop-veil {
    position: fixed; inset: 0; z-index: 84;
    background: rgba(8, 10, 12, .58);
    backdrop-filter: blur(1.5px);
}

.pop-win {
    position: fixed; z-index: 85;
    max-width: calc(100vw - 16px); max-height: calc(100vh - 16px);
    display: flex; flex-direction: column;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r-3); box-shadow: var(--pop);
    overflow: hidden;
}
/* 좌표를 지정하지 않은 팝업은 화면 중앙. 드래그가 시작되면 popup.js가 left/top으로 바꾼다. */
.pop-win.is-center { left: 50%; top: 50%; transform: translate(-50%, -50%); }
.pop-win.is-dragging { user-select: none; cursor: grabbing; box-shadow: var(--pop-lg, var(--pop)); }

.pop-head {
    flex: none; display: flex; align-items: center; gap: 8px;
    padding: 11px 12px 11px 14px; border-bottom: 1px solid var(--line);
    background: var(--surface-2); cursor: grab;
}
.pop-win[data-draggable="0"] .pop-head { cursor: default; }
.pop-head b { font-size: 13.5px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 머리띠가 없는 전면 배너형의 닫기 — 본문 위에 겹쳐 띄운다. */
.pop-x {
    position: absolute; top: 8px; right: 8px; z-index: 2;
    width: 26px; height: 26px; border-radius: 50%;
    display: grid; place-items: center;
    background: rgba(12, 14, 16, .62); border: 0; color: #fff;
    font-size: 12px; cursor: pointer; transition: background .12s;
}
.pop-x:hover { background: rgba(12, 14, 16, .84); }

.pop-body { flex: 1 1 auto; overflow: auto; padding: 16px; font-size: 13px; line-height: 1.75; color: var(--text-2); }
.pop-body.flush { padding: 0; }

/* 관리자가 쓴 본문의 기본값. 여기 없는 모양은 관리자가 인라인 style로 정한다. */
.pop-body > :first-child { margin-top: 0; }
.pop-body > :last-child { margin-bottom: 0; }
.pop-body p { margin: 0 0 10px; }
.pop-body h1, .pop-body h2, .pop-body h3 { margin: 0 0 8px; color: var(--text); line-height: 1.4; }
.pop-body h1 { font-size: 19px; } .pop-body h2 { font-size: 16px; } .pop-body h3 { font-size: 14px; }
.pop-body ul, .pop-body ol { margin: 8px 0; padding-left: 18px; }
.pop-body ul { list-style: disc; } .pop-body ol { list-style: decimal; }
.pop-body li { margin: 3px 0; }
.pop-body a { color: var(--accent-2); text-decoration: underline; text-underline-offset: 2px; }
.pop-body img { max-width: 100%; height: auto; display: block; border-radius: var(--r); }
.pop-body.flush img { border-radius: 0; }
.pop-body hr { margin: 12px 0; border: 0; border-top: 1px solid var(--line-soft); }
.pop-body table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 12.5px; }
.pop-body th, .pop-body td { padding: 6px 8px; border: 1px solid var(--line-soft); text-align: left; }
.pop-body th { background: var(--surface-2); font-weight: 600; }
.pop-body strong, .pop-body b { color: var(--text); }

.pop-foot {
    flex: none; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 9px 12px; border-top: 1px solid var(--line); background: var(--surface-2);
}
.pop-foot .check { font-size: 12px; color: var(--text-3); }
.pop-foot .btn { margin-left: auto; }

@media (max-width: 520px) {
    /* 좁은 화면에서는 관리자가 정한 폭·좌표를 무시하고 화면에 맞춘다 — 420px 팝업이
       375px 화면에서 잘리면 닫기 버튼에 손이 닿지 않는다. */
    .pop-win {
        left: 8px !important; right: 8px !important;
        width: auto !important; max-width: none;
        transform: none !important;
        top: auto !important; bottom: calc(62px + env(safe-area-inset-bottom)) !important;
        max-height: 72vh;
    }
}

/* ── 상단 띠 배너 ── .notice 를 그대로 쓰고 닫기 버튼 자리만 잡는다. */
.gbanner { position: relative; align-items: center; }
.gbanner .modal-x { flex: none; margin-left: 4px; }
.gbanner a { color: var(--accent-2); }

/* ── 알림함(/notifications) ── 목록 자체가 아코디언이다. 제목 줄만 보고 훑다가 필요한 것만 편다. */
.notilist { display: flex; flex-direction: column; }
.notilist li { border-bottom: 1px solid var(--line-soft); }
.notilist li:last-child { border-bottom: 0; }
.notilist li.is-new { background: var(--accent-dim); }

.nt-head {
    display: flex; align-items: center; gap: 9px; width: 100%;
    padding: 11px 13px; background: transparent; border: 0; text-align: left; cursor: pointer;
    font-size: 13px; color: var(--text); transition: background .1s;
}
.nt-head:hover { background: var(--row-hover); }
.nt-head .nt-ti { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notilist li.is-new .nt-head .nt-ti { font-weight: 700; }
.nt-head .nt-dt { flex: none; font-size: 11px; color: var(--text-4); }
.nt-head .ch { flex: none; font-size: 9px; color: var(--text-4); }
.nt-body { padding: 2px 13px 15px 13px; }

/* ═══════════════ §23 관리자 콘솔 확장 (2026-08-27) ═══════════════

   구획이 7개에서 13개로 늘면서 좌측 내비가 길어졌고, 로그·팝업 편집처럼 폭을 크게 쓰는 화면이
   생겼다. §14의 .adm/.adm-nav 는 그대로 두고 여기서 필요한 조각만 더한다. */

/* 구획 안의 하위 탭(로그의 감사/접근/커뮤니티/앱). .btngroup 과 달리 개수가 늘어도 줄바꿈된다. */
.adm-sub { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 12px; }
.adm-sub button {
    height: 28px; padding: 0 11px; border-radius: var(--r);
    background: var(--surface-2); border: 1px solid var(--line);
    font-size: 12.5px; color: var(--text-3); cursor: pointer; transition: all .12s;
}
.adm-sub button:hover { color: var(--text); border-color: var(--accent-line); }
.adm-sub button.on { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; font-weight: 600; }

/* 로그 표 — 행이 많고 열이 좁다. 폰트를 한 단계 줄이고 줄 높이를 낮춘다. */
.logtbl { font-size: 12px; }
.logtbl td, .logtbl th { padding: 5px 8px; vertical-align: top; }
.logtbl .lg-when { white-space: nowrap; font-family: var(--mono); color: var(--text-4); font-size: 11px; }
.logtbl .lg-ip { font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.logtbl .lg-msg { color: var(--text-2); word-break: break-word; }
.logtbl .lg-ex {
    margin-top: 4px; padding: 6px 8px; border-radius: var(--r);
    background: var(--surface-3); border: 1px solid var(--line-soft);
    font-family: var(--mono); font-size: 10.5px; line-height: 1.6; color: var(--warn-soft, var(--text-3));
    white-space: pre-wrap; max-height: 132px; overflow: auto;
}
.logtbl .lv { font-family: var(--mono); font-size: 10px; font-weight: 700; }
.logtbl .lv-w { color: var(--warn); } .logtbl .lv-e { color: var(--danger, #d9534f); } .logtbl .lv-i { color: var(--text-4); }

/* 키-값 표(회원 상세·감사 상세). .tbl compact 보다 촘촘하고 라벨 폭이 고정이다. */
.kv { width: 100%; font-size: 12.5px; }
.kv td { padding: 4px 0; vertical-align: top; }
.kv td:first-child { width: 92px; color: var(--text-4); white-space: nowrap; }
.kv td:last-child { color: var(--text-2); word-break: break-word; }

/* 14일 추이 막대. 라이브러리를 쓰지 않는다 — 높이를 %로 주는 것으로 충분하다. */
.spark { display: flex; align-items: flex-end; gap: 3px; height: 46px; }
.spark i { flex: 1 1 0; min-width: 3px; background: var(--accent-line); border-radius: 2px 2px 0 0; display: block; }
.spark i.on { background: var(--accent-solid); }
.spark-x { display: flex; gap: 3px; margin-top: 4px; font-size: 9.5px; color: var(--text-4); font-family: var(--mono); }
.spark-x span { flex: 1 1 0; text-align: center; overflow: hidden; }

/* HTML 편집기 + 미리보기 2단. 좁아지면 세로로 쌓인다. */
.htmled { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; align-items: start; }
.htmled textarea { min-height: 260px; font-family: var(--mono); font-size: 12px; line-height: 1.65; }
.htmled .prev {
    min-height: 260px; max-height: 460px; overflow: auto;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2); padding: 14px;
}
.htmled .prev-h { font-size: 11px; color: var(--text-4); margin-bottom: 7px; letter-spacing: .04em; }
@media (max-width: 900px) { .htmled { grid-template-columns: minmax(0, 1fr); } }

/* 서식 넣기 버튼 줄 — 관리자가 태그를 외우지 않아도 되게. */
.htmlbar { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.htmlbar button {
    height: 25px; padding: 0 8px; border-radius: var(--r);
    background: var(--surface-3); border: 1px solid var(--line);
    font-size: 11.5px; color: var(--text-3); cursor: pointer;
}
.htmlbar button:hover { color: var(--text); border-color: var(--accent-line); }

/* 업로드한 이미지 목록 */
.medialist { display: flex; flex-wrap: wrap; gap: 8px; }
.medialist figure { width: 104px; margin: 0; }
.medialist img { width: 104px; height: 72px; object-fit: cover; border-radius: var(--r); border: 1px solid var(--line); display: block; }
.medialist figcaption { margin-top: 3px; font-size: 10px; color: var(--text-4); font-family: var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 좌측 내비가 13항목이 되면서 화면 높이를 넘긴다 — 자체 스크롤을 준다. */
@media (min-width: 1081px) {
    .adm-nav { max-height: calc(100vh - var(--stick) - 24px); overflow-y: auto; }
}
@media (max-width: 1080px) {
    /* 좁은 화면에서는 내비를 위로 눕힌다(§14는 2단 그리드 그대로였다). */
    .adm { grid-template-columns: minmax(0, 1fr); }
    .adm-nav { position: static; display: flex; flex-wrap: wrap; gap: 4px; }
    .adm-nav h5 { width: 100%; padding: 4px 4px 0; }
    .adm-nav a { flex: 0 0 auto; }
}

/* ═══════════════ §24 팝업 캔버스 편집기 (2026-08-28) ═══════════════

   "그림판처럼 텍스트·사진을 얹고 마우스로 옮긴다"(의뢰인). 3단이다 —
   왼쪽 도구·레이어 / 가운데 캔버스(실제 크기 1:1) / 오른쪽 속성.

   ⚠ 캔버스 안의 요소는 <b>인라인 style이 정본</b>이다. 끄는 동안 popup-editor.js가 그 값을 직접 고치고
     손을 뗄 때 서버로 보낸다. 그래서 여기서는 .pc-el 의 left/top/width/height 를 건드리지 않는다. */

.pc { display: grid; grid-template-columns: 176px minmax(0, 1fr) 232px; gap: 10px; align-items: start; }
@media (max-width: 1240px) { .pc { grid-template-columns: 152px minmax(0, 1fr); } .pc-props { grid-column: 1 / -1; } }
@media (max-width: 820px) { .pc { grid-template-columns: minmax(0, 1fr); } }

.pc-side { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-2); padding: 9px; }
.pc-side h4 { font-size: 10.5px; color: var(--text-4); letter-spacing: .05em; margin: 0 0 6px; }
.pc-side + .pc-side { margin-top: 8px; }

/* 요소 추가 버튼 — 큼직해야 "여기서 얹는다"가 읽힌다. */
.pc-add { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
.pc-add button {
    height: 46px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
    font-size: 11px; color: var(--text-2); cursor: pointer; transition: all .12s;
}
.pc-add button:hover { border-color: var(--accent-line); color: var(--text); background: var(--surface-3); }
.pc-add button .ic { font-size: 15px; line-height: 1; color: var(--text-4); }
.pc-add button:hover .ic { color: var(--accent-2); }

/* 레이어 목록 — 겹친 요소를 캔버스에서 고르기 어려울 때의 유일한 손잡이다. */
.pc-layers { display: flex; flex-direction: column; gap: 2px; max-height: 210px; overflow-y: auto; }
.pc-layers button {
    display: flex; align-items: center; gap: 6px; width: 100%; padding: 5px 7px;
    background: transparent; border: 1px solid transparent; border-radius: var(--r);
    font-size: 11.5px; color: var(--text-3); text-align: left; cursor: pointer;
}
.pc-layers button:hover { background: var(--surface-3); color: var(--text); }
.pc-layers button.on { background: var(--accent-dim); border-color: var(--accent-line); color: var(--text); font-weight: 600; }
.pc-layers button .k { flex: none; width: 13px; color: var(--text-4); font-size: 10px; }
.pc-layers button .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 캔버스 무대 — 격자 배경이라 팝업의 실제 경계가 눈에 보인다. */
.pc-stage {
    background:
        linear-gradient(45deg, var(--surface-3) 25%, transparent 25%, transparent 75%, var(--surface-3) 75%),
        linear-gradient(45deg, var(--surface-3) 25%, transparent 25%, transparent 75%, var(--surface-3) 75%);
    background-size: 16px 16px; background-position: 0 0, 8px 8px;
    background-color: var(--surface-2);
    border: 1px solid var(--line); border-radius: var(--r-2);
    padding: 18px; overflow: auto; max-height: 620px;
    display: flex; justify-content: center;
}
.pc-canvas {
    position: relative; flex: none;
    box-shadow: 0 0 0 1px var(--line), var(--pop-sm, 0 2px 10px rgba(0,0,0,.18));
    overflow: hidden; user-select: none; touch-action: none;
}

.pc-el { position: absolute; cursor: move; }
/* box-sizing은 여기서 준다 — TextStyle에서 뺐기 때문이다(최종 HTML은 BoxStyle이 넣는다).
   없으면 padding이 100% 위에 더해져 편집기에서만 글상자가 넘친다. */
.pc-el .pc-text { width: 100%; height: 100%; display: flex; outline: 0; box-sizing: border-box; }
.pc-el img { pointer-events: none; }
.pc-el.is-sel { outline: 1px solid var(--accent-solid); outline-offset: 0; }
.pc-el.is-moving { outline: 1px dashed var(--accent-solid); }

/* 크기 손잡이 8개. 선택된 요소에만 그린다. */
.pc-handle {
    position: absolute; width: 9px; height: 9px; background: #fff;
    border: 1px solid var(--accent-solid); border-radius: 2px; z-index: 2;
}
.pc-handle[data-dir="nw"] { left: -5px; top: -5px; cursor: nwse-resize; }
.pc-handle[data-dir="n"]  { left: calc(50% - 5px); top: -5px; cursor: ns-resize; }
.pc-handle[data-dir="ne"] { right: -5px; top: -5px; cursor: nesw-resize; }
.pc-handle[data-dir="w"]  { left: -5px; top: calc(50% - 5px); cursor: ew-resize; }
.pc-handle[data-dir="e"]  { right: -5px; top: calc(50% - 5px); cursor: ew-resize; }
.pc-handle[data-dir="sw"] { left: -5px; bottom: -5px; cursor: nesw-resize; }
.pc-handle[data-dir="s"]  { left: calc(50% - 5px); bottom: -5px; cursor: ns-resize; }
.pc-handle[data-dir="se"] { right: -5px; bottom: -5px; cursor: nwse-resize; }

/* 속성 패널 — 선택한 요소 하나만 다룬다. */
.pc-props .field { margin-bottom: 8px; }
.pc-props label { font-size: 10.5px; color: var(--text-4); display: block; margin-bottom: 3px; }
.pc-props .input, .pc-props .select, .pc-props .textarea { height: 28px; font-size: 12px; padding: 0 7px; }
.pc-props .textarea { height: auto; min-height: 62px; padding: 6px 7px; line-height: 1.5; }
.pc-props .row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.pc-props input[type="color"] { width: 100%; height: 28px; padding: 2px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); cursor: pointer; }
.pc-seg { display: flex; gap: 3px; }
.pc-seg button {
    flex: 1; height: 28px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
    font-size: 11.5px; color: var(--text-3); cursor: pointer;
}
.pc-seg button.on { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; font-weight: 700; }

.pc-empty { text-align: center; padding: 22px 10px; font-size: 12px; color: var(--text-4); line-height: 1.7; }

/* 캔버스에 넣을 이미지 고르기 */
.pc-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(58px, 1fr)); gap: 5px; max-height: 168px; overflow-y: auto; }
.pc-pick img { width: 100%; height: 42px; object-fit: cover; border-radius: var(--r); border: 1px solid var(--line); cursor: pointer; display: block; }
.pc-pick img:hover { border-color: var(--accent-solid); }

/* 캔버스는 끌기 중 글자가 선택되지 않게 user-select:none 이다. 다만 화면에서 바로 고치는
   중(contenteditable)에는 선택이 되어야 커서를 옮길 수 있다 — 그때만 되돌린다. */
.pc-canvas [contenteditable] { user-select: text; cursor: text; }

/* ═══════════════ §25 위지윅 편집기 (공지·알림, 2026-08-28) ═══════════════

   팝업은 캔버스(§24), 공지·알림은 이 편집기다 — 흐르는 문서라 문단이 위에서 아래로 쌓인다.
   편집 영역에 .doc 를 함께 걸어 <b>고객센터에서 보게 될 서식 그대로</b> 편집한다. */

.rt { border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); overflow: hidden; }

.rt-bar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 3px;
    padding: 6px 7px; background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.rt-grp { display: flex; gap: 2px; align-items: center; }
.rt-grp + .rt-grp { margin-left: 5px; padding-left: 6px; border-left: 1px solid var(--line); }
.rt-bar button {
    min-width: 26px; height: 26px; padding: 0 7px;
    background: transparent; border: 1px solid transparent; border-radius: var(--r);
    font-size: 11.5px; color: var(--text-2); cursor: pointer; transition: all .1s;
}
.rt-bar button:hover { background: var(--surface-3); border-color: var(--line); color: var(--text); }
.rt-bar button.on { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; font-weight: 700; }
.rt-bar .rt-color { width: 18px; min-width: 18px; height: 18px; padding: 0; border-radius: 50%; border: 1px solid var(--line); }
.rt-bar .rt-color:hover { transform: scale(1.15); }

.rt-sub {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 7px 9px; background: var(--surface-3); border-bottom: 1px solid var(--line);
}
.rt-sub.col { flex-direction: column; align-items: stretch; }

.rt-edit {
    min-height: 260px; max-height: 520px; overflow-y: auto;
    padding: 14px 15px; outline: 0; background: var(--surface);
}
.rt-edit:focus { box-shadow: inset 0 0 0 2px var(--accent-dim); }
/* 빈 편집 영역이 완전히 비면 클릭할 곳이 없어 보인다 — 안내를 깔아 준다. */
.rt-edit:empty::before { content: "내용을 적으세요."; color: var(--text-4); }
.rt-edit img { max-width: 100%; height: auto; border-radius: var(--r); }

.rt-src {
    min-height: 260px; border: 0; border-radius: 0;
    font-family: var(--mono); font-size: 12px; line-height: 1.65;
}

/* ⚠ hidden 이 실제로 먹게 한다.
   .pop-win 은 display:flex, .gbanner 는 .notice(flex)라 <b>브라우저 기본 [hidden] 규칙(UA 스타일시트)이
   작성자 규칙에 밀린다</b> — 즉 hidden 을 세워도 그대로 보인다. popup.js가 Blazor 소유 노드를
   지우지 않고 숨기기만 하도록 바뀌었으므로(회로가 죽던 원인) 여기서 반드시 막아 줘야 한다. */
.pop-win[hidden], .pop-veil[hidden], .gbanner[hidden], .js-all-expired[hidden] { display: none !important; }

/* ── 이용권 진입점 · 구독 신청 화면(2026-09-29 정기결제 전환) ───────────────────────── */
/* 요금제 진입점 — 주 메뉴 탭(.nav-plan)은 금색 글자, 주 메뉴가 접히는 761~1300px에서만 헤더 버튼(.hbtn-plan)이 보인다.
   760px 이하는 하단 탭바의 '요금제'가 맡는다. 종전 금색 채움 버튼은 모든 폭에 떠서 360~412px 폰 헤더를
   넘치게 했다(리뷰 FE-4: 가로 스크롤·햄버거가 화면 밖). */
.gnb a.nav-plan { color: #e3b04a; }
.gnb a.nav-plan:hover, .gnb a.nav-plan.on { color: #f1c766; }
.gnb a.nav-plan.on::after { background: #e3b04a; }
.drawer a.dl.nav-plan > span:first-child { color: var(--warn-soft); font-weight: 700; }
.tabbar a.nav-plan .ic { color: var(--warn); }
.hbtn-plan { display: none; color: #e3b04a; border-color: rgba(227, 176, 74, .45); }
.hbtn-plan:hover { color: #f1c766; border-color: #e3b04a; }
@media (max-width: 1300px) and (min-width: 761px) { .hbtn-plan { display: inline-flex; } }
@media (max-width: 480px) {
    /* 360px 폰에서 헤더가 넘치지 않게 — 테마 전환·로그인은 드로어(≡)와 하단 탭에 있다. 회원가입은 남긴다. */
    .head-act .themetog, .head-act .hbtn-login { display: none; }
}

/* ── 요금제(.pr) — 2026-09-29 재디자인 ───────────────────────────────────────────── */
.pr { max-width: 1180px; }
.pr-hero {
    position: relative; overflow: hidden; margin: 6px 0 22px; padding: 38px 28px 30px; text-align: center;
    border: 1px solid var(--line); border-radius: 16px;
    background:
        radial-gradient(620px 220px at 50% -40px, var(--accent-dim), transparent 70%),
        linear-gradient(180deg, var(--surface), var(--surface-2));
}
.pr-eyebrow { display: inline-flex; align-items: center; height: 24px; padding: 0 11px; border-radius: 999px; border: 1px solid var(--accent-line); color: var(--accent-2); font-size: 12px; font-weight: 700; letter-spacing: .06em; }
.pr-hero h1 { margin: 14px 0 0; font-size: 30px; font-weight: 800; letter-spacing: -.02em; line-height: 1.25; }
.pr-lede { margin: 10px auto 0; max-width: 40em; font-size: 14px; line-height: 1.7; color: var(--text-2); }
.pr-trust { margin: 18px 0 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 18px; font-size: 12.5px; color: var(--text-2); }
.pr-trust li { display: inline-flex; align-items: center; gap: 6px; }
.pr-trust li::before { content: "✓"; color: var(--ok); font-weight: 800; font-size: 11px; }
.pr-trial { display: inline-flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 4px 10px; margin-top: 18px; padding: 9px 16px; border-radius: 10px; background: var(--warn-dim); border: 1px solid rgba(217, 155, 43, .35); font-size: 13px; color: var(--text); }
.pr-trial b { color: var(--warn-soft); }

.pr-plans { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; align-items: stretch; }
.pr-card {
    position: relative; display: flex; flex-direction: column; padding: 26px 22px 22px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
    transition: border-color .15s, box-shadow .15s, transform .15s;
}
.pr-card:hover { border-color: var(--line-strong); box-shadow: var(--pop-sm); }
.pr-card.is-best {
    border-color: var(--accent); transform: translateY(-6px);
    background: linear-gradient(180deg, var(--accent-dim), transparent 42%), var(--surface);
    box-shadow: 0 0 0 1px var(--accent), var(--pop);
}
.pr-card.is-current { border-color: var(--ok); }
.pr-card.is-target { box-shadow: 0 0 0 2px var(--accent-2); }
.pr-ribbon { position: absolute; top: -11px; left: 50%; transform: translateX(-50%); height: 22px; padding: 0 12px; display: inline-flex; align-items: center; border-radius: 999px; background: var(--accent-solid); color: #fff; font-size: 11px; font-weight: 800; letter-spacing: .04em; white-space: nowrap; box-shadow: var(--pop-sm); }
.pr-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.pr-card-head h2 { margin: 0; font-size: 18px; font-weight: 800; }
.pr-desc { margin: 8px 0 0; min-height: 40px; font-size: 12.5px; line-height: 1.65; color: var(--text-3); }
.pr-price { margin-top: 18px; display: flex; align-items: baseline; gap: 5px; }
.pr-price b { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 32px; font-weight: 800; letter-spacing: -.03em; color: var(--text); }
.pr-price span { font-size: 13px; color: var(--text-3); }
.pr-daily { margin-top: 2px; font-size: 12px; color: var(--text-4); }
.pr-cta { margin-top: 18px; }
.pr-card .pr-cta[aria-disabled="true"] { cursor: default; opacity: .7; }
.pr-note { margin-top: 8px; text-align: center; font-size: 11.5px; color: var(--text-4); }
.pr-feats { margin: 18px 0 0; padding: 16px 0 0; list-style: none; border-top: 1px solid var(--line-soft); display: flex; flex-direction: column; gap: 10px; font-size: 13px; color: var(--text-2); }
.pr-feats li { display: flex; gap: 9px; align-items: flex-start; line-height: 1.55; }
.pr-feats li::before { content: "✓"; flex: none; margin-top: 1px; color: var(--ok); font-weight: 800; font-size: 12px; }
.pr-feats li.is-inherit { color: var(--text); font-weight: 700; }
.pr-feats li.is-inherit::before { content: "+"; color: var(--accent-2); font-size: 14px; margin-top: -1px; }

.pr-sec { margin-top: 34px; }
.pr-h2 { margin: 0 0 12px; font-size: 18px; font-weight: 800; letter-spacing: -.01em; }
.pr-cmp th small { display: block; margin-top: 2px; font-size: 11px; font-weight: 500; color: var(--text-4); }
.pr-cmp th.is-best, .pr-cmp td.is-best { background: var(--accent-dim); }
.pr-cmp th.is-best { color: var(--accent-2); }
.pr-yes { color: var(--ok); font-weight: 800; }
.pr-no { color: var(--text-4); }
.pr-info { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.pr-info > div { padding: 16px 18px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; }
.pr-info h3 { margin: 0; font-size: 14px; font-weight: 800; }
.pr-info p { margin: 7px 0 0; font-size: 12.5px; line-height: 1.75; color: var(--text-2); }
.pr-info a, .pr-help a { color: var(--accent-2); }
.pr-help { margin: 14px 0 0; text-align: center; font-size: 12.5px; color: var(--text-3); }
@media (max-width: 1000px) {
    .pr-plans { grid-template-columns: minmax(0, 1fr); max-width: 520px; margin: 0 auto; gap: 22px; }
    .pr-card.is-best { transform: none; }
    .pr-info { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
    .pr-hero { padding: 28px 16px 22px; border-radius: 12px; }
    .pr-hero h1 { font-size: 23px; }
    .pr-info { grid-template-columns: minmax(0, 1fr); }
    .pr-price b { font-size: 28px; }
}

.co-prod { display: flex; align-items: center; gap: 14px; }
.co-badge { flex: none; width: 54px; height: 54px; border-radius: 12px; display: flex; align-items: center; justify-content: center;
    background: var(--accent-dim, rgba(53,116,184,.14)); color: var(--accent-2); font-weight: 800; font-size: 13px; }
.co-info { flex: 1; min-width: 0; }
.co-info h2 { margin: 0; font-size: 16px; }
.co-info p { margin: 4px 0 0; color: var(--text-3); font-size: 12.5px; line-height: 1.6; }
.co-cycle { margin-left: 6px; padding: 2px 7px; border-radius: 10px; background: var(--surface); border: 1px solid var(--line); font-size: 11px; font-weight: 600; color: var(--text-2); vertical-align: 2px; }
.co-price { flex: none; text-align: right; }
.co-price b { font-family: var(--mono); font-size: 20px; color: var(--text); }
.co-price small { margin-left: 3px; color: var(--text-3); font-size: 12px; }
.co-points { margin: 12px 0 0; padding: 12px 0 0; border-top: 1px dashed var(--line); list-style: none;
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 16px; font-size: 12.5px; color: var(--text-2); }
.co-points li::before { content: "✓"; margin-right: 6px; color: var(--ok); font-weight: 700; }
.co-method { display: flex; gap: 12px; padding: 12px; border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); }
.co-method-ic { flex: none; width: 34px; height: 26px; border-radius: 5px; background: var(--accent-2); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 14px; }
.co-method b { font-size: 13.5px; }
.co-method p { margin: 3px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--text-3); }
.co-agree { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; font-size: 13px; line-height: 1.6; }
.co-agree .check { align-items: flex-start; }
.co-agree .check input { margin-top: 3px; }
.co-agree .check:first-child { padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.co-agree a { color: var(--accent-2); }
.co-legal p { margin: 0 0 8px; font-size: 12.5px; line-height: 1.65; color: var(--text-3); }
.co-legal p:last-child { margin-bottom: 0; }
.co-legal a { color: var(--accent-2); }
.co-flow { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; }
.co-step { flex: 1 1 180px; display: flex; flex-direction: column; gap: 3px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface); }
.co-step b { font-size: 15px; }
.co-step small { color: var(--text-3); font-size: 12px; }
.co-step.is-next { border-color: var(--accent-2); }
.co-arrow { align-self: center; color: var(--text-3); font-size: 18px; }
.linkbtn { padding: 0; border: 0; background: none; color: var(--accent-2); font: inherit; cursor: pointer; text-decoration: underline; }
.linkbtn:disabled { opacity: .5; cursor: default; }
@media (max-width: 760px) {
    .co-prod { flex-wrap: wrap; }
    .co-price { width: 100%; text-align: left; }
    .co-points { grid-template-columns: 1fr; }
}

/* ═══════════════ §27 배당률 적중 · 기대값 (프라임, /odds-rate, 2026-10-10) ═══════════════
   윈토토 '배당률 당첨 % 및 기대값'과 같은 표. 기대값 1,000 초과(지금까지 이익이었던 배당)만 --ok 틴트 —
   윈토토의 초록 칸 역할. 숫자 열은 우측 정렬(.tbl.grouped g2 머리글과 맞춤). */
.or-tbl td { text-align: right; white-space: nowrap; }
.or-tbl td.gh { border-left: 1px solid var(--line-soft); }
.or-tbl .or-odds { text-align: center; font-weight: 700; color: var(--text); width: 64px; }
.or-tbl tbody tr.is-focus { background: var(--accent-dim); }
.or-tbl .or-ev.up { background: var(--ok-dim); color: var(--ok-soft); font-weight: 700; }
.or-link { padding: 0; border: 0; background: none; color: var(--accent-2); font: inherit; font-weight: 600; cursor: pointer; }
.or-link:hover { text-decoration: underline; }
.or-note { padding: 8px 13px 10px; margin-top: 0; }
.or-league { width: auto; min-width: 120px; }
.or-modal-n { margin-left: 6px; font-size: 13px; font-weight: 500; color: var(--text-3); }
.so-rate { margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--line); }
.so-rate-head { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 700; color: var(--text-2); }
.so-rate-head a { margin-left: auto; font-weight: 600; color: var(--accent-2); }
.so-rate-grid { margin-top: 4px; display: grid; grid-template-columns: auto 1fr 1fr; gap: 3px 14px; font-size: 12.5px; color: var(--text-3); align-items: baseline; }
.so-rate-grid b { color: var(--text-2); }
.so-rate-grid .up { color: var(--ok-soft); font-weight: 700; }
.so-rate-grid a { color: inherit; text-decoration: none; }
.so-rate-grid a:hover { text-decoration: underline; }
/* 해외 업체별 배당(윈토토) — 업체 줄을 누르면 그 업체 동일배당이 띠 안에 펼쳐진다. 평균·프로토는 머리글 톤. */
.so-books { max-width: 420px; }
.so-books .rowlink { cursor: pointer; }
.so-books tbody tr.is-focus { background: var(--accent-dim); }
.so-books tbody tr.so-books-sum td { background: var(--surface-2); }
.or-wrap.is-loading { opacity: .55; transition: opacity .12s; }
/* 2026-10-13 의뢰인 — 동일배당 가시성("회원들이 더 쉽게") · 프라임 '역대 전체' 줄 · 배당률 표를 띠 안에서(페이지 이동 없이).
   ① .so-single-hit: 자리별 블록의 머리 숫자(그 자리 적중률) — 분포 막대·세 % 앞에서 먼저 읽힌다. 색은 중립(가치·국내 의미색 아님).
   ② .so-single-all: 프라임만 — 같은 배당의 역대 전체 횟수·적중·기대값(배당률 표 그 칸). 블록 아래 줄, 머리 숫자 열에 맞춘다.
   ③ .so-rate-cell: 배당률 칸(전체 리그·이 리그) — 누르면 띠 안에 그 경기 목록. ④ .or-panel: '표 전체 보기'(OddsRatePanel).
   ⑤ .or-seg: 작은 구분 버튼 묶음(앱 시트 표의 자리 선택 · 프로토 동일배당 구분). ⑥ .or-tbl .is-mine/.is-me: 이 경기 배당 줄·그 자리 묶음. */
.so-single { flex-wrap: wrap; }
.so-single-hit { flex: none; display: inline-flex; align-items: baseline; gap: 5px; min-width: 112px; }
.so-single-hit small { font-size: 11px; color: var(--text-3); }
.so-single-hit b { font-size: 16px; font-weight: 800; line-height: 1; color: var(--text); letter-spacing: -.01em; }
.so-single-hit .dim { font-size: 11px; }
.so-single.on .so-single-hit small { color: var(--text-2); }
.so-single-all { flex: 1 0 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 2px 12px; padding: 1px 0 3px 100px; font-size: 12px; color: var(--text-3); }
.so-single-all b { font-weight: 700; color: var(--text); }
.so-single-all b.up { color: var(--ok-soft); }
.so-single-all .chip { padding: 0 5px; font-size: 10px; line-height: 16px; }
.so-rate-head .so-rate-all { margin-left: auto; font-weight: 600; text-decoration: none; color: var(--accent-2); }
.so-rate-head .so-rate-all:hover { text-decoration: underline; }
.so-rate-head .chev { display: inline-block; margin-left: 2px; font-size: 10px; }
.so-rate-cell { display: inline; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; }
button.so-rate-cell { cursor: pointer; border-radius: 4px; }
button.so-rate-cell:hover { color: var(--text-2); text-decoration: underline; }
button.so-rate-cell.on { color: var(--text); box-shadow: inset 0 -2px 0 var(--accent); }
.or-panel { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); }
.or-panel-ctl { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 6px; }
.or-panel-note { margin-top: 4px; }
.or-panel-games { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px; }
.or-panel-games .or-panel-x { margin-left: auto; font-size: 12px; }
.or-seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); }
.or-seg button { padding: 3px 10px; border: 0; border-radius: 6px; background: none; font: inherit; font-size: 12px; color: var(--text-3); cursor: pointer; }
.or-seg button:hover { color: var(--text); }
.or-seg button.on { background: var(--surface); color: var(--text); font-weight: 700; box-shadow: var(--pop-sm); }
.so-proto-seg { margin-top: 6px; }
.or-tbl tbody tr.is-mine td.or-odds { box-shadow: inset 2px 0 0 var(--accent); }
.or-tbl tbody td.is-me { background: var(--accent-dim); font-weight: 700; }
.or-wrap.is-compact .or-tbl { width: 100%; }
.or-tbl tbody tr.or-gap td { padding: 0 8px; height: 18px; line-height: 18px; text-align: center; font-size: 11px; letter-spacing: .2em; color: var(--text-4); background: var(--surface-2); }
@media (max-width: 760px) {
    .so-rate-grid { grid-template-columns: auto 1fr; }
    .so-rate-grid .lg-col { display: none; }
    .so-single-hit { min-width: 0; }
    .so-single-all { padding-left: 0; }
}

/* ═══════════════ §28 배당 흐름 · 가치 흐름 (2026-10-11 의뢰인 — 오즈포털식 흐름 호버 · 가치 그래프) ═══════════════
   그림은 서버가 그린 인라인 SVG(OddsFlow.StepSvg) — 색은 여기 클래스가 정한다. 선 1.5px(확대해도 두께 고정), 면 채움·그라데이션 없음,
   헤어라인 격자. 의미색만: 해외 = --for(청), 국내 = --dom(적), 적정 국내 = 중립, 가치 기준선 = 중립 점선.
   ① .oflow-pop — 해외 칸 호버 팝오버(oddsflow.js가 body 끝에 붙이는 자기 노드, 웹 전용). z 50 = .pop-panel과 같은 층(§21 예산 안).
   ② .ofl — '해외 N' 띠의 배당 흐름(셀렉션별 작은 계단선 + 바뀐 시각 표).  ③ .vfl — 가치 근거의 가치 흐름. */
.fl-svg { display: block; width: 100%; height: auto; overflow: visible; }
.fl-grid { stroke: var(--line-soft); stroke-width: 1; vector-effect: non-scaling-stroke; }
.fl-line { fill: none; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.fl-line.fl-for { stroke: var(--for); }
.fl-line.fl-dom { stroke: var(--dom); }
.fl-line.fl-exp { stroke: var(--text-2); }
.fl-line.fl-thr { stroke: var(--text-3); stroke-dasharray: 3 3; }
.fl-end, .fl-start { stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.fl-end.fl-for { fill: var(--for); stroke: var(--for); }
.fl-end.fl-dom { fill: var(--dom); stroke: var(--dom); }
.fl-end.fl-exp { fill: var(--text-2); stroke: var(--text-2); }
.fl-end.fl-thr { fill: none; stroke: none; }
.fl-start { fill: var(--surface); }
.fl-start.fl-for { stroke: var(--for); }
.fl-start.fl-dom { stroke: var(--dom); }
.fl-start.fl-exp { stroke: var(--text-2); }
.fl-start.fl-thr { stroke: none; }

/* ① 호버 팝오버 */
.oflow-pop {
    position: fixed; z-index: 50; width: 272px; max-height: min(380px, calc(100vh - 16px)); overflow: auto; overscroll-behavior: contain;
    padding: 10px 12px 8px; border: 1px solid var(--line-strong); border-radius: var(--r-2); background: var(--surface);
    box-shadow: var(--pop-sm); font-size: 12px; color: var(--text-2);
    animation: fade .12s ease;
}
.oflow-pop[hidden] { display: none; }
.oflow-pop:focus { outline: none; }
.oflow-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.oflow-head b { font-size: 12.5px; font-weight: 700; color: var(--text); }
.oflow-head span { font-size: 12px; color: var(--text-2); }
.oflow-note { margin-top: 3px; font-size: 11px; line-height: 1.45; color: var(--text-3); }
.oflow-pop .fl-svg { margin: 8px 0 2px; }
.oflow-range { display: flex; justify-content: space-between; font-size: 11px; color: var(--text-3); }
.oflow-range b { font-weight: 600; color: var(--text-2); }
.oflow-list { list-style: none; margin: 6px 0 0; padding: 0; border-top: 1px solid var(--line-soft); }
.oflow-list li { display: grid; grid-template-columns: 1fr auto 14px; align-items: baseline; gap: 6px; padding: 3px 0; border-bottom: 1px solid var(--line-soft); }
.oflow-list li:last-child { border-bottom: 0; }
.oflow-list .t { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 11px; color: var(--text-3); }
.oflow-list li.o .t { font-family: var(--font); }
.oflow-list b { font-weight: 600; color: var(--text); }
.oflow-list .arr { font-style: normal; }
.board.bi .bi-o.for.has-flow { cursor: help; }
.board.bi .bi-o.for.has-flow:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ② '해외 N' 띠의 배당 흐름 */
.ofl { margin: 10px 0 2px; padding-bottom: 8px; border-bottom: 1px dashed var(--line); }
.ofl-head { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; color: var(--text-3); }
.ofl-head b { font-weight: 700; color: var(--text-2); }
.ofl-grid { display: grid; gap: 8px 14px; margin-top: 6px; }
.ofl-grid.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ofl-grid.n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ofl-cell { min-width: 0; }
.ofl-sel { font-size: 11.5px; font-weight: 600; color: var(--text-2); }
.ofl-cell .fl-svg { max-width: 240px; margin: 2px 0; }
.ofl-se { font-size: 12px; color: var(--text); }
.ofl-tbl { margin-top: 8px; }
.ofl-tbl td.t { color: var(--text-3); white-space: nowrap; }
.ofl-tbl td.ch { font-weight: 700; color: var(--text); }
@media (max-width: 520px) { .ofl-grid.n3 { grid-template-columns: 1fr; } }

/* ③ 가치 근거의 가치 흐름 */
.vfl { margin: 10px 0 8px; }
.vfl-head { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; color: var(--text-3); }
.vfl-head b { font-weight: 700; color: var(--text-2); }
.vfl-chart { max-width: 560px; margin-top: 6px; }
.vfl-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 6px; font-size: 11.5px; color: var(--text-3); }
.vfl-legend b { font-weight: 600; color: var(--text); }
.vfl-legend .k i { display: inline-block; width: 14px; height: 0; margin-right: 5px; vertical-align: middle; border-top: 1.5px solid currentColor; }
.vfl-legend .k.dom i { color: var(--dom); }
.vfl-legend .k.exp i { color: var(--text-2); }
.vfl-legend .k.thr i { color: var(--text-3); border-top-style: dashed; }
.vfl-legend .k.edge { margin-left: auto; }

/* ═══════════════ §29 해외 구매율 (2026-10-22 의뢰인 — /buy-rate 목록 · '해외 N' 띠 머리 · 앱 경기 시트 '해외 전체') ═══════════════
   막대 칸 너비 = 구매 비율(인라인 flex-grow). 강조색은 <b>가장 많이 산 자리 하나</b>뿐(.brv-max) — 의미색(국내 적 · 해외 청)은 쓰지 않는다
   (그 색은 '어느 쪽이 유리한가'에 이미 쓰인다). 375pt에서 가로 스크롤 없음(범례는 칸 안에서 줄바꿈). */
.brv { display: grid; gap: 12px; }
.brv-title { font-size: 12.5px; font-weight: 700; color: var(--text); }
.brv-row { display: grid; gap: 5px; min-width: 0; }
.brv-h { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 12px; color: var(--text-3); }
.brv-h b { color: var(--text-2); font-weight: 600; }
.brv-bar { display: flex; gap: 2px; height: 22px; border-radius: var(--r-2); overflow: hidden; background: var(--surface-3); }
.brv-bar i { flex: 1 1 0; min-width: 3px; display: flex; align-items: center; justify-content: center; justify-content: safe center; overflow: hidden;
    background: var(--surface-4); font-style: normal; transition: flex-grow .5s cubic-bezier(.2, .7, .2, 1); }
.brv-bar i.brv-max { background: var(--accent-solid); }
.brv-bar em { font-style: normal; font-size: 11px; font-weight: 600; color: var(--text-2); white-space: nowrap; padding: 0 4px;
    min-width: 0; overflow: hidden; text-overflow: ellipsis; }   /* 들어가지 않으면 끝만 잘린다(양끝이 잘려 '버 14.'로 보이던 것 — 리뷰) */
.brv-bar i.brv-max em { color: #fff; }
.brv-leg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px 8px; font-size: 12px; }
.brv-leg.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.brv-leg > span { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; min-width: 0; color: var(--text-3); }
.brv-leg > span:last-child { justify-content: flex-end; text-align: right; }
.brv-leg.n3 > span:nth-child(2) { justify-content: center; }
.brv-leg b { font-weight: 600; color: var(--text-2); }
.brv-leg .brv-p { color: var(--text); font-weight: 600; }
.brv-leg .brv-max .brv-p { color: var(--accent-2); }
.brv-leg .brv-a { font-size: 11px; }
.brv.is-compact { gap: 10px; }
.brv.is-compact .brv-bar { height: 18px; }
.brv.is-compact .brv-bar em { font-size: 10.5px; }
@media (prefers-reduced-motion: reduce) { .brv-bar i { transition: none; } }
.brv.is-mini .brv-bar { height: 14px; border-radius: var(--r); }
.brv.is-mini .brv-bar em { font-size: 10px; }

/* 보드 aside는 sticky인데 높이 제한이 없어, 화면보다 길면(가치 경기 TOP만으로도 1366×860에서 약 600px 넘침 — 10-22 실측) 아래 위젯이
   보드 끝까지 스크롤하기 전엔 보이지 않았다. 화면 높이로 묶고 안에서 스크롤한다 — 보드 aside에만(다른 화면의 .aside는 그대로).
   z-index 8(§21 예산 · sticky 함정)은 그대로 둔다. 1000px 이하는 aside가 정적 배치라 해당 없음. */
@media (min-width: 1001px) {
    .aside.aside-board { max-height: calc(100vh - var(--stick) - 16px); overflow-y: auto; scrollbar-width: thin; padding-bottom: 56px; }   /* 끝 줄이 오른쪽 아래 독(계산기 · PREMIUM TIP) 위로 올라오게 */
    .aside.aside-board > * { flex-shrink: 0; }   /* flex 열이라 높이를 묶으면 위젯이 줄어들며 안을 잘랐다 — 줄이지 말고 aside가 스크롤 */
}

/* 보드 aside '해외 구매율 TOP' — 줄 전체가 그 경기로 가는 링크. */
.brw > li { border-bottom: 1px solid var(--line-soft); }
.brw > li:last-child { border-bottom: 0; }
.brw-it { display: grid; gap: 5px; padding: 8px 11px; color: inherit; text-decoration: none; }
.brw-it:hover { background: var(--row-hover); }
.brw-it:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.brw-t { font-size: 11.5px; color: var(--text-3); }
.brw-tm { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brw-tm .x { color: var(--text-4); font-weight: 400; }
.brw-sum { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--text-3); }
.brw-sum b { color: var(--accent-2); font-weight: 600; }

/* 앱: 글자 크기 설정(--fs, app-bridge.js)과 앱 안 '동작 줄이기'를 따른다 — 경기 시트의 이웃 블록과 같은 계약(앱-12). */
html.odx-app .brv-title { font-size: calc(12.5px * var(--fs, 1)); }
html.odx-app .brv-h,
html.odx-app .brv-leg { font-size: calc(12px * var(--fs, 1)); }
html.odx-app .brv-leg .brv-a { font-size: calc(11px * var(--fs, 1)); }
html.odx-app .brv-bar em { font-size: calc(11px * var(--fs, 1)); }
html.odx-app .brv.is-compact .brv-bar { height: calc(18px * var(--fs, 1)); }
html.odx-app .brv.is-compact .brv-bar em { font-size: calc(10.5px * var(--fs, 1)); }
html.odx-app .brl-day { font-size: calc(12.5px * var(--fs, 1)); }
html.odx-app .brl-meta { font-size: calc(12px * var(--fs, 1)); }
html.odx-app .brl-teams { font-size: calc(14px * var(--fs, 1)); }
html.odx-app[data-odx-motion="reduced"] .brv-bar i { transition: none; }
html.odx-app[data-odx-fs="l"] .brv-bar i:not(.brv-max) em { display: none; }   /* 큰 글자(--fs ≥ 1.2)에선 가장 많이 산 자리만 막대 안에 — 범례가 나머지를 말한다 */

/* '해외 N' 띠 머리 — 분포표 위 한 칸. */
.bk-br { margin: 10px 0 12px; padding: 10px 12px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2); max-width: 560px; }

/* /buy-rate 목록 — 카드 격자(넓은 화면 3열 · 좁은 화면 1열). 카드 전체가 보드의 그 경기로 가는 링크다. */
.brl { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 10px; }
.brl-day { grid-column: 1 / -1; margin: 8px 0 -2px; font-size: 12.5px; font-weight: 700; color: var(--text-2); }
.brl-day:first-child { margin-top: 0; }
.brl-card { display: grid; align-content: start; gap: 8px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-3);
    color: inherit; text-decoration: none; min-width: 0; transition: border-color .15s, background-color .15s; }
.brl-card:hover { border-color: var(--line-strong); background: var(--surface-2); }
.brl-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.brl-card.is-plain:hover { border-color: var(--line); background: var(--surface); }   /* 링크가 아닌 카드(발매 전 경기)는 눌림 표시가 없다 */
.brl-meta { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 12px; color: var(--text-3); }
.brl-meta .no { color: var(--text-3); }
.brl-meta .t { margin-left: auto; color: var(--text-2); }
.brl-meta .pb-ico { padding: 0 !important; font-size: 14px; }
.brl-teams { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brl-teams .x { color: var(--text-4); font-weight: 400; }
@media (max-width: 640px) {
    .brl { grid-template-columns: minmax(0, 1fr); }
    .brl-card { padding: 11px 12px; }
}

/* ═══════════════ §30 관리자 — 모바일 웹 (2026-10-22 의뢰인 "모바일 웹 · 앱에서 관리자 페이지가 너무 불편") ═══════════════
   범위: 웹(:root:not(.odx-app))의 관리자 화면만 — Admin.razor 뿌리 고리 .adm-page(앱 세션이 앱-14에서 html.odx-app 범위로 쓰는 같은 클래스).
   .adm/.adm-nav는 내정보 · 쪽지 화면도 쓰므로 고리 없이 걸면 그 화면들이 바뀐다. 진입점(헤더 · 서랍 '관리자')은 SiteLayout(역할 기준).
   ① 구획 15개가 4줄로 쌓여 매번 화면 위 190px을 먹었다 → 한 줄 가로 스크롤 띠로 눕혀 헤더 밑에 붙인다(어디까지 내려가도 구획 전환).
   ② 넓은 표(회원 1000px · 결제 · 문의 · 게시판)는 가로 스크롤 그대로 두고 글자 · 여백만 줄인다. (첫 칸 고정은 뺐다 — 게시판 보류 큐처럼
      첫 칸이 긴 제목 · 발췌인 표에서 고정 칸이 화면을 다 덮어 처리 버튼이 가려졌다, 리뷰 3라운드.)
   ③ 손가락으로 누르는 것(작은 버튼 · 하위 탭 · 구획 칩)은 34px 이상. ④ 머리 설명 한 줄은 뺀다(모바일은 제목 · 상태 배지만). */
@media (max-width: 760px) {
    :root:not(.odx-app) .adm-page > .phead { margin-bottom: 8px; }
    :root:not(.odx-app) .adm-page > .phead .lede { display: none; }
    :root:not(.odx-app) .adm-page .adm-nav {
        position: sticky; top: calc(var(--hdr-h) + 1px); z-index: 5;
        flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
        gap: 4px; padding: 6px; margin-bottom: 10px; scroll-snap-type: x proximity;
        box-shadow: 0 6px 12px -10px rgba(0, 0, 0, .5);
    }
    :root:not(.odx-app) .adm-page .adm-nav::-webkit-scrollbar { display: none; }
    :root:not(.odx-app) .adm-page .adm-nav a { flex: 0 0 auto; min-height: 36px; padding: 0 12px; white-space: nowrap; scroll-snap-align: start; }
    :root:not(.odx-app) .adm-page .tbl { font-size: 12.5px; }
    :root:not(.odx-app) .adm-page .tbl thead th,
    :root:not(.odx-app) .adm-page .tbl tbody td { padding: 7px 8px; }
    :root:not(.odx-app) .adm-page :is(.btn-sm, .adm-sub button) { min-height: 34px; }
}

/* ═══════════════ § 앱 셸 — iOS·Android 앱 WebView (2026-10-10, docs/app/APP-SPEC.md §3.3) ═══════════════
   앱은 이 사이트를 WebView 하나로 띄우고 탭바·상태바·스플래시는 네이티브가 그린다. 이 절의 규칙은 전부
   html.odx-app 아래에만 걸린다 — 서버가 앱 UA일 때만 그 클래스를 렌더하므로(App.razor) 웹 화면은 한 픽셀도 바뀌지 않는다.

   치수의 출처
     --app-safe-top / --app-safe-bottom / --app-tabbar : 네이티브가 알려 준 값(app-bridge.js가 <html> style에 넣는다).
       iOS는 viewport-fit=cover라 env(safe-area-inset-*)도 같은 값을 주지만 Android WebView는 0인 경우가 많다 —
       그래서 둘 중 큰 값(max)을 쓴다(이중으로 더하지 않는다).
     --app-st / --app-sb : 상단(상태바)·하단(홈 인디케이터) 안전영역.  --app-bar : 네이티브 탭바 + 하단 안전영역.

   z-index는 새로 만들지 않는다(§21 예산 그대로: 헤더 60 · 탭바 70 · 독 80 · 팝업 84/85 · 드로어 90/91 · 모달 100).
   숨은 탭 목록(#odx-app-tabs)은 hidden이라 층이 없다. 네이티브 탭바는 WebView 바깥(위)에 있다.

   overscroll-behavior는 일부러 건드리지 않는다 — html/body에 none을 걸면 iOS WebView의 당겨서 새로고침
   (UIRefreshControl)과 바운스가 함께 죽는다. 기본값이 앱 관례에 맞다. */
html.odx-app {
    --app-st: max(env(safe-area-inset-top, 0px), var(--app-safe-top, 0px));
    --app-sb: max(env(safe-area-inset-bottom, 0px), var(--app-safe-bottom, 0px));
    --app-bar: calc(var(--app-tabbar, 49px) + var(--app-sb));
    /* sticky 요소(표 머리글·아사이드)가 붙는 높이에 상태바만큼을 더한다 — 헤더가 그만큼 키가 커졌다. */
    --stick: calc(var(--hdr-h) + var(--sport-h) + var(--app-st));
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

/* 웹 하단 탭바는 네이티브 탭바가 대신한다. */
html.odx-app .tabbar { display: none !important; }

/* 헤더 1행(두 테마 공통 다크)이 상태바 밑까지 이어진다 — 상태바 글자는 언제나 밝다(네이티브 light-content). */
html.odx-app .head { padding-top: var(--app-st); }

/* 본문 하단 여백 — 문서의 마지막은 푸터다. 법정 고지문이 네이티브 탭바 뒤로 잘리지 않게 탭바 + 안전영역만큼 띄운다.
   계정 화면(AuthLayout)·결제·관리자는 탭바가 숨으므로(data-tabbar="hide" 또는 목록 없음) 안전영역만 띄운다. */
html.odx-app .foot { padding-bottom: calc(28px + var(--app-sb)); }
html.odx-app #odx-app-tabs[data-tabbar="show"] ~ .site .foot { padding-bottom: calc(28px + var(--app-bar)); }
@media (max-width: 760px) {
    /* 웹은 탭바(52px) 몫으로 74px을 두지만 앱에서는 그 몫을 푸터가 진다. */
    html.odx-app .main { padding-bottom: 24px; }
}

/* 하단에 떠 있는 것들은 네이티브 탭바 위로 — 독(계산기·PREMIUM TIP), 좁은 화면의 관리자 팝업, 오류 띠. */
html.odx-app .dock { bottom: calc(var(--app-bar) + 12px); }
@media (max-width: 760px) {
    html.odx-app .dock { right: 10px; bottom: calc(var(--app-bar) + 10px); }
    html.odx-app .dock-panel { max-height: calc(100vh - var(--app-bar) - var(--stick) - 72px); }
}
@media (max-width: 520px) {
    html.odx-app .pop-win { bottom: calc(var(--app-bar) + 10px) !important; max-height: calc(100vh - var(--app-bar) - var(--app-st) - 24px); }
}
html.odx-app #blazor-error-ui { bottom: var(--app-bar); }

/* 모달 딤은 화면 전체를 덮는다(그동안 네이티브 탭바는 숨는다 — 브리지 overlay). 창은 상태바·홈 인디케이터를 피한다. */
html.odx-app .modal-veil { padding-top: calc(var(--app-st) + 10px); padding-bottom: calc(var(--app-sb) + 10px); }

/* 드로어: 상태바 자리는 헤더와 같은 어두운 띠로 채운다(밝은 테마의 흰 면 위에서는 상태바 글자가 안 보인다).
   머리도 헤더 색으로 맞춰, 열었을 때 상단이 한 덩어리로 보이게 한다. */
html.odx-app .drawer { border-top: var(--app-st) solid var(--hdr); padding-bottom: var(--app-sb); }
html.odx-app .drawer-head { background: var(--hdr); border-bottom-color: var(--hdr-line); }
html.odx-app .drawer-head .logo-mark { background-image: url(logo-on-dark.png); }   /* 앱 서랍 머리는 어둡다(새 로고 2026-10-18) */
html.odx-app .drawer-head .modal-x { color: var(--hdr-text-2); }

/* 입력 글자 16px 이상 — iOS는 그보다 작은 입력에 포커스하면 화면을 확대한다(뷰포트 maximum-scale=1과 이중 방어). */
html.odx-app input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
html.odx-app select,
html.odx-app textarea { font-size: 16px; }
/* 확대 판정은 입력칸 자신의 글자 크기로만 한다 — 안내문(placeholder)은 웹과 같은 크기(13px)로 두어 좁은 칸(보드 검색 170px)에서
   잘리지 않게 하고, 그래도 넘치면 말줄임으로 끝낸다(2026-10-10 계약 검토 CC-7: 14px에서 '팀 · 리그 · 경기번ㅎ'로 잘렸다). */
html.odx-app input::placeholder,
html.odx-app textarea::placeholder { font-size: 13px; }
html.odx-app input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]) { text-overflow: ellipsis; }

/* 길게 누르기: 링크·버튼에서 iOS 미리보기/복사 말풍선을 띄우지 않는다(본문 글은 그대로 선택·복사된다). */
html.odx-app a,
html.odx-app button,
html.odx-app label,
html.odx-app summary,
html.odx-app [role="button"] { -webkit-touch-callout: none; }
/* 내비 크롬만 글자 선택을 끈다(탭을 길게 누르다 선택 막대가 뜨지 않게). 입력이 든 줄(.subnav)에는 걸지 않는다 —
   iOS는 user-select:none 조상 안의 입력칸을 편집하지 못하게 만든다. */
html.odx-app .head-main,
html.odx-app .sports,
html.odx-app .drawer-head,
html.odx-app .drawer a.dl,
html.odx-app .dock-btns { -webkit-user-select: none; user-select: none; }

/* 누름 반응 — 탭 하이라이트를 끈 대신 눌린 순간을 직접 보여 준다(손끝에 즉시 반응하는 촉감). */
html.odx-app :is(.btn, .hbtn, .dock-btn, .themetog, .burger, .modal-x, .pop-x, .calc-pick):active { opacity: .72; }
html.odx-app :is(.drawer a.dl, .sports a, .sports button, .subnav a, .subnav button, .datestrip button, .blist a, .pb-sale a):active { background: var(--row-hover); }

/* ─────────── § 앱 셸 하위 절(docs/app/APP-DESIGN.md §5.1-2) — 2026-10-11 골격 ───────────
   병렬 작업 규칙: 각 하위 절은 [ ] 안의 담당만 고친다. 위의 1차 규칙(W1)·남의 블록·블록 밖은 건드리지 않는다.
   한 절을 둘이 나눠 가진 곳(앱-8·앱-10·앱-13)은 블록이 둘이다 — 자기 블록 안에만 쓴다.
   모든 규칙은 html.odx-app 아래(플랫폼은 html.odx-app-ios / html.odx-app-android) — 웹은 1px도 바뀌지 않는다.
   새 z-index 값 금지(§21 예산) · 애니메이션은 transform/opacity만 · 루트 :has() 금지 ·
   color-mix()·dvh·@starting-style·@property·animation-timeline은 @supports 안에서만(밖에 리터럴 폴백) · Android 블러 금지. */

/* ── 앱-1 토큰 [B1] ── APP-DESIGN §2(앱 색 토큰 넷 · --app-title-h · --app-tabs-h · --hair-w · --fs · 곡선) */
/*  앱 색 토큰은 이 넷뿐이다(§2.1): --ink · --ink-text · --app-mat · --app-scrim. 그 밖의 색은 site.css §1 토큰을 이름·값 그대로 쓴다.
    --app-mat은 color-mix가 아닌 리터럴이다 — iOS 15.1–16.1에서 var() 안 color-mix는 계산값 무효로 투명이 된다.
    치수: --app-title-h(제목 줄 44) · --app-tabs-h(마켓 탭 44) · --hair-w(헤어라인 두께 — 네이티브 HAIRLINE과 같은 값) ·
          --fs(큰 글자 배율 1.0–1.3 — 브리지가 prefs.fontScale을 <html> style에 쓴다. 앱 층 글자 크기는 calc(Npx * var(--fs, 1))).
    --stick = 상태바 + 44 — 마켓 탭 화면은 제목 줄이 접혀 탭 44가, 그 밖은 접히지 않는 제목 줄 44가 남아 화면마다 같다(§2.4).
              스크롤마다 바뀌지 않는다(레이아웃을 다시 하지 않는다). W1 규칙(헤더 50 + 종목 38)을 덮는다.
    --ax-h-l / --ax-h-m = 시트 디텐트(크게 · 중간, §3.10). dvh는 @supports 안에서만 — 밖은 vh 폴백(iOS 15.1–15.3).
    곡선(§4.1) — 네이티브 mobile/src/ui/motion.ts와 같은 값. 브리지(WAAPI)도 같은 값을 쓴다. */
html.odx-app {
    --ink: #e9edf0;
    --ink-text: #121518;
    --app-mat: rgba(23, 26, 30, .82);
    --app-scrim: rgba(0, 0, 0, .52);
    --app-title-h: 44px;
    --app-tabs-h: 44px;
    --hair-w: 1px;
    --fs: 1;
    --stick: calc(var(--app-st) + 44px);
    --ax-h-l: calc(100vh - var(--app-st) - 10px);
    --ax-h-m: 62vh;
    --ease-out: cubic-bezier(.215, .61, .355, 1);
    --ease-in-out: cubic-bezier(.645, .045, .355, 1);
    --ease-grow: cubic-bezier(.2, .9, .25, 1);
    --ease-fly: cubic-bezier(.2, .8, .2, 1);
    --ease-sheet: cubic-bezier(.32, .72, 0, 1);
    /* 길이 · 스프링 근사 곡선(docs/app/APP-MOTION.md §4.1 — 네이티브 motion.ts와 짝). 웹은 linear() 스프링을 쓰지 않는다(iOS 15–17.1). */
    --t-press: 80ms;     /* 누름 들어감 */
    --t-release: 160ms;  /* 누름 돌아옴 */
    --t-fade: 120ms;     /* 짧은 페이드 · 동작 줄이기 대체 */
    --t-rise: 220ms;     /* 드러남(6px 오름) */
    --t-slide: 200ms;    /* 옆으로(세그먼트 내용 12px) */
    --t-route: 160ms;    /* 경로 · 탭(10px) */
    --t-move: 240ms;     /* 계기 · 밑줄 미끄러짐 */
    --ease-press: cubic-bezier(.2, .9, .3, 1);    /* SPRING_PRESS 520/46(ζ≈1.01) 근사 */
    --ease-glide: cubic-bezier(.25, .8, .25, 1);  /* SPRING_GLIDE 420/41(ζ≈1.00) 근사 */
}
@supports (height: 100dvh) {
    html.odx-app { --ax-h-l: calc(100dvh - var(--app-st) - 10px); --ax-h-m: 62dvh; }
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) { html.odx-app { --hair-w: .5px; } }
@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 3dppx) { html.odx-app { --hair-w: .67px; } }
html.odx-app[data-theme="light"] { --ink: #15191d; --ink-text: #ffffff; --app-scrim: rgba(12, 16, 20, .34); }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) { --ink: #15191d; --ink-text: #ffffff; --app-scrim: rgba(12, 16, 20, .34); }
}
/* ── /앱-1 ── */

/* ── 앱-2 셸 [B1] ── §5.2(상태바 띠 · 웹 크롬 숨김 · 안전영역 · 접힘) */
/*  상태바 띠(§2.7) — 두 테마 공통 어두운 띠(D4 기본). 불투명 --hdr이 기본이고, iOS에서 스크롤 연동 애니메이션을 지원하면(접힌 제목 글자가
    사라지는 경우에만) 앱-3이 반투명 재질 + 블러로 바꾼다. 블러는 언제나 가상 요소에 건다(조상에 backdrop-filter가 있으면 fixed 시트가 그 안에
    갇힌다). z 60 = 헤더와 같은 값(DOM 뒤라 위에 그려진다).
    [APP-MOTION M23] 누르기는 띠가 받는다 — 접힌 제목 줄(앱-3, 글자 불투명도 0)이 띠 밑에 남아 있어도 눌리지 않게(접힘 키프레임에서
    visibility를 뺐다 — 합성 단계에서 돌게). 띠 밑에는 누를 것이 없다(펼친 베젤은 margin-top: --app-st로 띠 아래에서 시작한다). */
html.odx-app .site::after {
    content: ""; position: fixed; top: 0; left: 0; right: 0; height: var(--app-st); z-index: 60;
    background: var(--hdr); pointer-events: auto;
}

/*  [FIX DF-01] 한글 줄바꿈(§2.3) — 낱말 가운데서 끊지 않는다(띄어쓰기에서만). 긴 영숫자 줄은 넘치지 않게 끊는다. 앱 범위라 웹은 그대로. */
html.odx-app body { word-break: keep-all; line-break: strict; overflow-wrap: break-word; }

/*  웹 크롬 숨김(§5.2.2): 종목 탭 줄(→ 필터 시트 · 칩 레일) · 독(→ 슬립 막대 · 레일 칩) · 햄버거 · 드로어(→ 네이티브 탭바 · 내정보) · 보드 범례.
    탭바(.tabbar)는 W1 규칙이 숨긴다. 드로어는 DOM에 남는다 — 그 안의 로그아웃 폼을 브리지 RPC logout이 제출한다. */
html.odx-app .sports,
html.odx-app .dock,
html.odx-app .burger,
html.odx-app .board .panel-foot { display: none; }
html.odx-app .drawer,
html.odx-app .drawer-veil { display: none !important; }

/*  공통 화면 규칙(§5.2.5 · §2.4): 웹 페이지 머리(.phead)와 빵부스러기는 숨긴다(제목은 베젤이 말한다 — 필요한 화면만 본문 첫 줄을 남긴다).
    좌우 여백 16(4pt 격자). 본문은 베젤 바로 아래에서 시작한다. .panel은 반경 · 테두리 없는 구획(목록 화면은 그룹 목록 문법). */
html.odx-app .phead,
html.odx-app .crumb { display: none; }
html.odx-app .wrap { padding-left: 16px; padding-right: 16px; }
/* [FIX V-05 2026-10-20] '.row … wrap'의 wrap은 줄바꿈 유틸리티(.row.wrap = flex-wrap)인데 위 페이지 틀 규칙(.wrap)에도 걸려 여백이 한 겹 더 붙었다
   (FAQ 검색 상자 · '모두 펼치기' 줄이 x=32에서 시작, 그룹 목록은 16). 앱에서는 줄바꿈 유틸리티에 틀 여백 · 폭 상한을 주지 않는다. */
html.odx-app .row.wrap { max-width: none; margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }
html.odx-app .main { padding-top: 0; }
html.odx-app .panel { border: 0; border-radius: 0; }

/*  2차 네이티브에서만 보일 줄(앱 설정 ›, 알림 설정의 이 기기 줄) / 구버전 셸에서만 보일 폴백 줄. 브리지가 첫 prefs에서 html[data-odx-native]를 칠한다. */
html.odx-app:not([data-odx-native]) .odx-need-native { display: none !important; }
html.odx-app[data-odx-native] .odx-no-native { display: none !important; }

/*  푸터(SiteFooter — §5.2.2 축약형)의 앱 모양은 앱-10b (p)가 정한다(한 벌만 둔다). */

/*  웹 토스트(§6.1 N7 · §7) — 브리지 OdxApp.toast()가 body 끝에 붙이는 자기 노드. 탭바 위 16, 반경 10, 불투명 #2b3137, 13/1.4, 2.4초.
    슬립 막대가 있으면 그 위로, 탭바가 숨은 화면이면 안전영역 위로. z 100(모달 층 — DOM 맨 끝이라 시트 위). */
html.odx-app .odx-toast {
    position: fixed; left: 16px; right: 16px; bottom: calc(var(--app-bar) + 16px); z-index: 100;
    width: max-content; max-width: calc(100% - 32px); margin: 0 auto; padding: 10px 14px; border-radius: 10px;
    background: #2b3137; color: #eef1f4; font-size: calc(13px * var(--fs, 1)); line-height: 1.4; text-align: center;
    pointer-events: none;
}
html.odx-app .odx-toast[hidden] { display: none; }
/* [FIX RV-WEB-6] 빈 토스트는 보이지 않을 뿐 접근성 트리에는 남는다(live region이 미리 있어야 첫 글자 변화가 읽힌다 — display·visibility로 숨기지 않는다). */
html.odx-app .odx-toast:empty { opacity: 0; }
html.odx-app .site.has-slipbar ~ .odx-toast { bottom: calc(var(--app-bar) + 16px + 64px); }
html.odx-app #odx-app-tabs[data-tabbar="hide"] ~ .odx-toast { bottom: calc(var(--app-sb) + 16px); }
/* ── /앱-2 ── */

/* ── 앱-3 베젤 [B1] ── §3.1(앱 제목 줄 · 하위 화면 베젤) */
/*  베젤 = 상태바 띠(앱-2) + 제목 줄 44(.head > .head-main.ax — SiteLayout · AuthLayout) + 마켓 탭 44(.subnav — 있는 화면만).
    두 테마 공통 어두운 베젤(D4 기본, 선택안은 앱-13b). 배경은 ::before 가상 요소에 — iOS는 반투명 재질 + 블러, Android는 불투명 --hdr(§2.7).
    헤어라인(rgba(255,255,255,.07))도 그 가상 요소가 긋는다(레이아웃을 바꾸지 않는 inset 그림자).
    접힘(§3.1 · §4.2): 마켓 탭이 있는 화면에서만 제목 줄이 상태바 띠 밑으로 접힌다(sticky 음수 top) — 스크롤 연동 애니메이션을 지원하면
    제목 글자도 1→0으로 사라지고(iOS 15–17은 불투명한 상태바 띠가 덮는다). :has는 .head 자기 기준이라 성능 규칙 안이다(§5.1-7). */
html.odx-app .head {
    padding-top: 0; margin-top: var(--app-st); top: var(--app-st);
    background: transparent; border-bottom: 0; isolation: isolate;
}
html.odx-app .head:has(+ .subnav) { top: calc(var(--app-st) - var(--app-title-h)); }
html.odx-app .subnav {
    position: sticky; top: var(--app-st); z-index: 60;
    background: transparent; border-bottom: 0; isolation: isolate; color: var(--hdr-text);
}
html.odx-app .head::before,
html.odx-app .subnav::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background: var(--hdr); box-shadow: inset 0 calc(-1 * var(--hair-w)) 0 rgba(255, 255, 255, .07);
}
html.odx-app .head:has(+ .subnav)::before { box-shadow: none; }
html.odx-app-ios .head::before,
html.odx-app-ios .subnav::before {
    background: var(--app-mat);
    -webkit-backdrop-filter: blur(20px) saturate(170%); backdrop-filter: blur(20px) saturate(170%);
}
@supports (animation-timeline: scroll()) {
    html.odx-app-ios .site::after {
        background: var(--app-mat);
        -webkit-backdrop-filter: blur(20px) saturate(170%); backdrop-filter: blur(20px) saturate(170%);
    }
    html.odx-app .head:has(+ .subnav) .ax {
        animation: ax-fold linear both; animation-timeline: scroll(root); animation-range: 0 44px;
    }
    /* 다 접히면(브리지 data-odx-folded — scrollY ≥ 44) 투명한 버튼을 접근성 트리 · 초점에서 뺀다. 접힘 애니메이션이 걸린 .ax 자신이 아니라
       그 자식에 건다(합성 판정을 건드리지 않게 — 리뷰 RG-3). */
    html.odx-app .head[data-odx-folded]:has(+ .subnav) .ax > * { visibility: hidden; }
}
/*  라이트 테마(iOS): 같은 재질(.82)이 밝은 바탕 위에서는 중간 회색으로 비쳐 '두 테마 공통 어두운 베젤'(그림 03 · D4 현행)로 읽히지 않는다 —
    재질 농도만 .95로 올린다(리터럴 — 색 토큰을 새로 만들지 않는다). 블러는 그대로. D4 선택안(앱-13b)이 켜지면 그쪽이 이긴다. */
html.odx-app-ios[data-theme="light"] :is(.head, .subnav)::before { background: rgba(23, 26, 30, .95); }
@media (prefers-color-scheme: light) {
    html.odx-app-ios:not([data-theme]) :is(.head, .subnav)::before { background: rgba(23, 26, 30, .95); }
}
@supports (animation-timeline: scroll()) {
    html.odx-app-ios[data-theme="light"] .site::after { background: rgba(23, 26, 30, .95); }
    @media (prefers-color-scheme: light) {
        html.odx-app-ios:not([data-theme]) .site::after { background: rgba(23, 26, 30, .95); }
    }
}
/* 접힌 제목 줄은 상태바 띠 밑에 남는다 — 누르기는 띠(앱-2 .site::after, pointer-events: auto)가 받는다.
   [APP-MOTION PF-1] visibility를 키프레임에 두면 합성되지 않는다(실측 compositeFailed 8192 — 스크롤 3화면 20회) → 불투명도만. */
@keyframes ax-fold { to { opacity: 0; } }

/*  제목 줄 — 왼쪽: (보드 계열) 로고 두 막대 20 + 제목 버튼(⌄ → 보드 전환 메뉴) · (탭 첫 화면) 제목 17.5/700 ·
    (하위 화면) ‹ 부모 이름 16/400 + 가운데 제목. 오른쪽: 페이지가 채우는 동작 칸(.ax-act ← SectionContent "appactions"). */
html.odx-app .head-main.ax {
    position: relative; height: var(--app-title-h); max-width: none; gap: 9px; padding: 0 4px 0 16px;
    -webkit-user-select: none; user-select: none;
}
html.odx-app .ax-mark { display: block; flex: none; width: 20px; height: 20px; }
html.odx-app .ax-t {
    min-width: 0; margin: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
    color: var(--hdr-text); font-size: calc(17.5px * var(--fs, 1)); font-weight: 700; line-height: 22px; letter-spacing: -.02em;
}
html.odx-app .ax-switch {
    display: inline-flex; align-items: center; gap: 4px; flex: 0 1 auto; height: 44px; padding: 0;
    background: none; border: 0; font-family: inherit; cursor: pointer;
}
html.odx-app .ax-switch .ax-i { width: 16px; height: 16px; color: var(--hdr-text-2); transition: transform .2s var(--ease-out); }
html.odx-app .ax-switch[aria-expanded="true"] .ax-i { transform: rotate(180deg); }
html.odx-app .ax-act { display: flex; align-items: center; flex: none; margin-left: auto; color: var(--hdr-text-2); }
/* 하위 화면 — 제목은 양쪽 88을 비운 채 가운데(긴 제목은 말줄임), '‹'는 대상 44. */
html.odx-app .ax-sub { padding: 0 4px; }
html.odx-app .ax-sub .ax-t { position: absolute; left: 88px; right: 88px; top: 0; line-height: var(--app-title-h); text-align: center; pointer-events: none; }
html.odx-app .ax-back {
    position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 1px;
    min-width: 44px; height: 44px; padding: 0 8px 0 4px; background: none; border: 0;
    color: var(--hdr-text); font-family: inherit; font-size: calc(16px * var(--fs, 1)); font-weight: 400; white-space: nowrap; cursor: pointer;
}
html.odx-app .ax-back .ax-i { width: 24px; height: 24px; }
html.odx-app .ax-sub .ax-act { position: relative; z-index: 1; }
html.odx-app :is(.ax-back, .ax-switch):active { opacity: .6; }

/*  마켓 탭 줄(§3.2 · §5.2.3) — 높이 44 · 간격 24 · 여백 0 16. 배경 · 테두리 없는 글자 탭(15/600 + 숫자 11/500 mono), 켜짐 = 흰 글자 + 바닥 2pt
    액센트 밑줄(탭 폭 전체 — 두 테마 모두 어두운 베젤이라 다크 액센트 값). 같은 문법을 보드 · 계산기 마켓 · 커뮤니티 분류 · 알림 · 약관 · 고객센터가 쓴다.
    한 줄 — 넘치면 줄 안에서 가로로 밀린다(스크롤 막대 없음). */
html.odx-app .subnav .wrap {
    height: var(--app-tabs-h); min-height: 0; max-width: none; padding: 0 16px; gap: 24px;
    flex-wrap: nowrap; align-items: stretch; overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none; overscroll-behavior-x: contain; -webkit-user-select: none; user-select: none;
}
html.odx-app .subnav .wrap::-webkit-scrollbar { display: none; }
html.odx-app .subnav .wrap > :is(a, button) {
    position: relative; display: inline-flex; align-items: center; gap: 5px; flex: none;
    height: auto; padding: 0; border: 0; border-radius: 0; background: none;
    color: var(--hdr-text-2); font-size: calc(15px * var(--fs, 1)); font-weight: 600; letter-spacing: -.015em;
}
html.odx-app .subnav .wrap > :is(a, button):is(:hover, :active) { background: none; }
html.odx-app .subnav .wrap > :is(a, button).on { color: #fff; background: none; border: 0; font-weight: 600; }
html.odx-app .subnav .wrap > :is(a, button).on::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; border-radius: 1px 1px 0 0; background: #4d90d8;
    transform-origin: 0 50%;   /* [APP-MOTION M07] 브리지가 옛 탭 자리에서 새 탭으로 밑줄을 미끄러뜨린다(WAAPI pseudoElement) */
}
/* [INT] 탭 히트 영역 — 칸 사이 24의 반(12)씩 양옆에 더해 짧은 탭('공지' 30pt)도 44 이상(§2.4 · §9-16). 모양 · 간격은 그대로. */
html.odx-app .subnav .wrap > :is(a, button)::before { content: ""; position: absolute; top: 0; bottom: 0; left: -12px; right: -12px; }
html.odx-app .subnav .wrap > :is(a, button) .n {
    font-family: var(--mono); font-size: calc(11px * var(--fs, 1)); font-weight: 500; letter-spacing: -.02em; color: var(--hdr-text-2); opacity: .7;
}
html.odx-app .subnav .wrap > :is(a, button).on .n { opacity: 1; }
html.odx-app .subnav .wrap > .vr { display: none; }

/*  선 아이콘(§2.8) — wwwroot/app-icons/<이름>.svg(네이티브 iconPaths.ts와 같은 경로 데이터)를 mask-image로, 색은 currentColor 하나.
    크기는 쓰는 자리가 정한다(베젤 22 · 목록 20 · 칩 14 · 메타 12). CSP img-src 'self' 안. 사용: <span class="ax-i ax-i-search" aria-hidden="true"></span> */
html.odx-app .ax-i {
    display: inline-block; flex: none; width: 22px; height: 22px; background-color: currentColor;
    -webkit-mask-position: center; mask-position: center; -webkit-mask-size: contain; mask-size: contain;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
html.odx-app .ax-i-bell { -webkit-mask-image: url(app-icons/bell.svg); mask-image: url(app-icons/bell.svg); }
html.odx-app .ax-i-board { -webkit-mask-image: url(app-icons/board.svg); mask-image: url(app-icons/board.svg); }
html.odx-app .ax-i-calc { -webkit-mask-image: url(app-icons/calc.svg); mask-image: url(app-icons/calc.svg); }
html.odx-app .ax-i-card { -webkit-mask-image: url(app-icons/card.svg); mask-image: url(app-icons/card.svg); }
html.odx-app .ax-i-chat { -webkit-mask-image: url(app-icons/chat.svg); mask-image: url(app-icons/chat.svg); }
html.odx-app .ax-i-check { -webkit-mask-image: url(app-icons/check.svg); mask-image: url(app-icons/check.svg); }
html.odx-app .ax-i-chevron-down { -webkit-mask-image: url(app-icons/chevron-down.svg); mask-image: url(app-icons/chevron-down.svg); }
html.odx-app .ax-i-chevron-left { -webkit-mask-image: url(app-icons/chevron-left.svg); mask-image: url(app-icons/chevron-left.svg); }
html.odx-app .ax-i-chevron-right { -webkit-mask-image: url(app-icons/chevron-right.svg); mask-image: url(app-icons/chevron-right.svg); }
html.odx-app .ax-i-chevron-up { -webkit-mask-image: url(app-icons/chevron-up.svg); mask-image: url(app-icons/chevron-up.svg); }
html.odx-app .ax-i-close { -webkit-mask-image: url(app-icons/close.svg); mask-image: url(app-icons/close.svg); }
html.odx-app .ax-i-code { -webkit-mask-image: url(app-icons/code.svg); mask-image: url(app-icons/code.svg); }
html.odx-app .ax-i-device { -webkit-mask-image: url(app-icons/device.svg); mask-image: url(app-icons/device.svg); }
html.odx-app .ax-i-doc { -webkit-mask-image: url(app-icons/doc.svg); mask-image: url(app-icons/doc.svg); }
html.odx-app .ax-i-face { -webkit-mask-image: url(app-icons/face.svg); mask-image: url(app-icons/face.svg); }
html.odx-app .ax-i-filter { -webkit-mask-image: url(app-icons/filter.svg); mask-image: url(app-icons/filter.svg); }
html.odx-app .ax-i-gear { -webkit-mask-image: url(app-icons/gear.svg); mask-image: url(app-icons/gear.svg); }
html.odx-app .ax-i-haptic { -webkit-mask-image: url(app-icons/haptic.svg); mask-image: url(app-icons/haptic.svg); }
html.odx-app .ax-i-info { -webkit-mask-image: url(app-icons/info.svg); mask-image: url(app-icons/info.svg); }
html.odx-app .ax-i-lock { -webkit-mask-image: url(app-icons/lock.svg); mask-image: url(app-icons/lock.svg); }
html.odx-app .ax-i-motion { -webkit-mask-image: url(app-icons/motion.svg); mask-image: url(app-icons/motion.svg); }
html.odx-app .ax-i-msg { -webkit-mask-image: url(app-icons/msg.svg); mask-image: url(app-icons/msg.svg); }
html.odx-app .ax-i-out { -webkit-mask-image: url(app-icons/out.svg); mask-image: url(app-icons/out.svg); }
html.odx-app .ax-i-pencil { -webkit-mask-image: url(app-icons/pencil.svg); mask-image: url(app-icons/pencil.svg); }
html.odx-app .ax-i-person { -webkit-mask-image: url(app-icons/person.svg); mask-image: url(app-icons/person.svg); }
html.odx-app .ax-i-plus { -webkit-mask-image: url(app-icons/plus.svg); mask-image: url(app-icons/plus.svg); }
html.odx-app .ax-i-receipt { -webkit-mask-image: url(app-icons/receipt.svg); mask-image: url(app-icons/receipt.svg); }
html.odx-app .ax-i-search { -webkit-mask-image: url(app-icons/search.svg); mask-image: url(app-icons/search.svg); }
html.odx-app .ax-i-share { -webkit-mask-image: url(app-icons/share.svg); mask-image: url(app-icons/share.svg); }
html.odx-app .ax-i-shield { -webkit-mask-image: url(app-icons/shield.svg); mask-image: url(app-icons/shield.svg); }
html.odx-app .ax-i-sort { -webkit-mask-image: url(app-icons/sort.svg); mask-image: url(app-icons/sort.svg); }
html.odx-app .ax-i-star-fill { -webkit-mask-image: url(app-icons/star-fill.svg); mask-image: url(app-icons/star-fill.svg); }
html.odx-app .ax-i-star { -webkit-mask-image: url(app-icons/star.svg); mask-image: url(app-icons/star.svg); }
html.odx-app .ax-i-theme { -webkit-mask-image: url(app-icons/theme.svg); mask-image: url(app-icons/theme.svg); }
html.odx-app .ax-i-user { -webkit-mask-image: url(app-icons/user.svg); mask-image: url(app-icons/user.svg); }
/* ── /앱-3 ── */

/* ── 앱-4 레일 [B2] ── §3.2–3.3(마켓 탭 · 칩 레일) */
/* 이 블록부터 앱-8b까지(앞머리 axb- · ax-rail · mk · mtime · m-lg · msheet)는 배당 보드와 그 시트만 쓴다(Board.razor · MatchSheet ·
   PlanGate/PlanLockModal 앱판 · TipsPanel Sheet). 값은 APP-DESIGN §2–§3. 색은 site.css §1 토큰 + 앱 토큰(--ink · --ink-text · --app-scrim —
   앱-1, 없을 때를 위한 폴백만 적는다). 헤어라인 = --line-soft × --hair-w(앱-1, 없으면 1px). 글자 = calc(N × --fs). 새 z-index 없음. */

/* 아이콘(§2.8) — wwwroot/app-icons 마스크, currentColor 하나. */
html.odx-app .axb-i {
    display: inline-block; flex: none; width: 18px; height: 18px; background: currentColor; vertical-align: middle;
    -webkit-mask: var(--axb-ic) center / contain no-repeat; mask: var(--axb-ic) center / contain no-repeat;
}
html.odx-app .axb-i-search { --axb-ic: url(app-icons/search.svg); }
html.odx-app .axb-i-filter { --axb-ic: url(app-icons/filter.svg); }
html.odx-app .axb-i-star { --axb-ic: url(app-icons/star.svg); }
html.odx-app .axb-i-star-fill { --axb-ic: url(app-icons/star-fill.svg); }
html.odx-app .axb-i-share { --axb-ic: url(app-icons/share.svg); }
html.odx-app .axb-i-close { --axb-ic: url(app-icons/close.svg); }
html.odx-app .axb-i-chevron-down { --axb-ic: url(app-icons/chevron-down.svg); }
html.odx-app .axb-i-chevron-up { --axb-ic: url(app-icons/chevron-up.svg); }
html.odx-app .axb-i-chevron-right { --axb-ic: url(app-icons/chevron-right.svg); }
html.odx-app .axb-i-lock { --axb-ic: url(app-icons/lock.svg); }
html.odx-app .axb-i-check { --axb-ic: url(app-icons/check.svg); }

/* 베젤 동작 칸(⌕ · 필터) — 아이콘 22, 누르는 자리 44. 자리 잡기는 베젤(앱-3)이 한다. */
html.odx-app .axb-act {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 44px; height: 44px; margin: 0; padding: 0; border: 0; border-radius: 0; background: none;
    color: var(--hdr-text-2); cursor: pointer;
}
html.odx-app .axb-act .axb-i { width: 22px; height: 22px; }
html.odx-app .axb-act:active { opacity: .6; }

/* 마켓 탭(§3.2) — 활성 = 흰 글자 + 2pt 액센트 밑줄(탭 폭 전체), 칸 사이 24, 숫자 = mono 11/500. 베젤은 두 테마 공통 어둡다. */
html.odx-app .subnav .wrap:has(> .mk) {
    min-height: 0; height: 44px; display: flex; align-items: stretch; flex-wrap: nowrap; gap: 24px;
    padding: 0 16px; overflow-x: auto; scrollbar-width: none;
}
html.odx-app .subnav .wrap:has(> .mk)::-webkit-scrollbar { display: none; }
html.odx-app .subnav .wrap > .mk {
    position: relative; display: inline-flex; align-items: center; gap: 5px; flex: none;
    height: 44px; min-width: 0; margin: 0; padding: 0;
    background: none; border: 0; border-radius: 0; box-shadow: none;
    font-family: var(--font); font-size: calc(15px * var(--fs, 1)); font-weight: 600; line-height: 20px; letter-spacing: -.015em;
    color: var(--hdr-text-2); white-space: nowrap; cursor: pointer; transition: color .12s;
}
html.odx-app .subnav .wrap > .mk:hover { background: none; color: var(--hdr-text); }
html.odx-app .subnav .wrap > .mk .n { font-size: calc(11px * var(--fs, 1)); font-weight: 500; letter-spacing: -.02em; color: var(--hdr-text-2); opacity: .7; }
html.odx-app .subnav .wrap > .mk.on { color: #fff; background: none; border: 0; font-weight: 600; }
html.odx-app .subnav .wrap > .mk.on .n { opacity: 1; }
html.odx-app .subnav .wrap > .mk.on::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; border-radius: 1px 1px 0 0; background: #4d90d8;   /* [FIX DF-03] 베젤은 두 테마 모두 어둡다 — 라이트 --accent(#1f6dc0) 대신 다른 탭(앱-3 · 앱-10b)과 같은 값 */
    transform-origin: 0 50%;   /* [APP-MOTION M07] 밑줄 미끄러짐(브리지 WAAPI) */
}

/* 칩 레일(§3.3) — 한 줄 가로 스크롤 하나, 스크롤바 없음. 보드 위(.main의 첫 자식)라 위 여백을 걷는다. */
html.odx-app .main:has(> .ax-rail) { padding-top: 0; }
html.odx-app .ax-rail {
    display: flex; align-items: center; gap: 6px; height: 46px; padding: 0 16px;
    overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity; scroll-padding: 0 16px; overscroll-behavior-x: contain;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    background: var(--bg); box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
    -webkit-user-select: none; user-select: none;
}
html.odx-app .ax-rail::-webkit-scrollbar { display: none; }
html.odx-app .ax-rail > * { flex: none; scroll-snap-align: start; }
html.odx-app .ax-rail > .vr { width: 1px; height: 16px; margin: 0 3px; background: var(--line); }

/* 칩 — 높이 30 · 반경 6 · 안쪽 선 1px. 켜짐 = --surface-2 면 + 진한 선 + --text. 누르는 자리는 위아래로 넓혀 44. */
html.odx-app .axb-chip {
    position: relative; display: inline-flex; align-items: center; gap: 5px; flex: none;
    height: 30px; margin: 0; padding: 0 10px; border: 0; border-radius: 6px;
    background: none; box-shadow: inset 0 0 0 1px var(--line);
    font-family: var(--font); font-size: calc(12.5px * var(--fs, 1)); font-weight: 550; line-height: 1; letter-spacing: -.01em;
    color: var(--text-2); white-space: nowrap; cursor: pointer;
}
html.odx-app .axb-chip::after { content: ""; position: absolute; left: -3px; right: -3px; top: -7px; bottom: -7px; }
html.odx-app .axb-chip .n { font-family: var(--mono); font-size: calc(11px * var(--fs, 1)); font-weight: 500; letter-spacing: -.02em; color: var(--text-3); }
html.odx-app .axb-chip .sp { display: inline-flex; color: var(--text-3); }
html.odx-app .axb-chip .sp .sico { width: 14px; height: 14px; display: block; }
html.odx-app .axb-chip .axb-i { width: 14px; height: 14px; color: var(--text-3); }
html.odx-app .axb-chip .cv { width: 12px; height: 12px; margin-left: 1px; }
html.odx-app .axb-chip.on { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); }
html.odx-app .axb-chip.on .axb-i, html.odx-app .axb-chip.on .sp { color: var(--text-2); }
/* 누름 = scale(.96)(브리지 누름 모듈 data-odx-press — 앱-12). :active 면은 스크롤 시작마다 번쩍여 지웠다(APP-MOTION M02). */

/* 비교 기준 두 칸(평균 | 전 북 최저) */
html.odx-app .axb-seg2 { display: inline-flex; flex: none; height: 30px; border-radius: 6px; box-shadow: inset 0 0 0 1px var(--line); }
html.odx-app .axb-seg2 > button {
    position: relative; display: inline-flex; align-items: center; gap: 5px; height: 30px; margin: 0; padding: 0 9px;
    border: 0; border-radius: 6px; background: none;
    font-family: var(--font); font-size: calc(12.5px * var(--fs, 1)); font-weight: 550; line-height: 1; color: var(--text-2); white-space: nowrap; cursor: pointer;
}
html.odx-app .axb-seg2 > button::after { content: ""; position: absolute; left: 0; right: 0; top: -7px; bottom: -7px; }
html.odx-app .axb-seg2 > button + button { box-shadow: inset 1px 0 0 var(--line); border-radius: 0 6px 6px 0; }
html.odx-app .axb-seg2 > button .n { font-family: var(--mono); font-size: calc(11px * var(--fs, 1)); font-weight: 500; color: var(--text-3); }
html.odx-app .axb-seg2 > button.on { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); border-radius: 6px; }

/* 잠금 꼬리표(무채 — 액센트 청 아님, §2.2): 자물쇠 + PRO/PRIME */
html.odx-app .ax-rail .lk {
    display: inline-flex; align-items: center; gap: 2px; height: 15px; margin: 0 0 0 1px; padding: 0 4px 0 3px;
    border: 0; border-radius: 3px; box-shadow: inset 0 0 0 1px var(--line-strong); background: none;
    font-family: var(--mono); font-size: 9.5px; font-weight: 700; line-height: 1; letter-spacing: .05em; color: var(--text-3);
}
html.odx-app .ax-rail .lk .axb-i { width: 9px; height: 9px; color: inherit; }

/* 라이트: 레일 = 흰 면, 켜진 칩 = --surface-3(그림 03) */
html.odx-app[data-theme="light"] .ax-rail { background: var(--surface); }
html.odx-app[data-theme="light"] :is(.axb-chip.on, .axb-seg2 > button.on) { background: var(--surface-3); }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) .ax-rail { background: var(--surface); }
    html.odx-app:not([data-theme]) :is(.axb-chip.on, .axb-seg2 > button.on) { background: var(--surface-3); }
}
/* ── /앱-4 ── */

/* ── 앱-5 보드 행 [B2] ── §3.5 · §3.7–3.9(경기 행 · 판정 꼬리표 · PREMIUM TIP 행 · 차이 계기) */
/* ⚠ 행 재배치는 Board.razor .mrow의 자식 순서(.m-star → .m-when → .m-teams → .bi-dom → .bi-for → .bi-dif → .m-tag)와 세 묶음 안
   .bi-o의 nth-child에 묶여 있다(Board.razor 머리 경고). 106pt = 위 8 + 메타 16 + 2 + 팀 22 + 2 + (4 + 칸 44) + 아래 8.
   웹 규칙(§16 ≤760 · §20 ≤1180)이 같은 요소에 걸리므로 여기서 덮는다 — 폭과 무관하게(태블릿 포함) 같은 배치다. */

/* 보드 판 — 테두리·반경 없는 전폭 목록. 바탕: 다크 --bg · 라이트 흰 면. .wrap 여백과 무관하게 화면 폭을 채운다. */
html.odx-app .board.bi {
    margin: 0 calc(50% - 50vw); border: 0; border-radius: 0; background: var(--bg);
}
html.odx-app[data-theme="light"] .board.bi { background: var(--surface); }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .board.bi { background: var(--surface); } }
html.odx-app .board.bi .panel-foot { display: none; }
html.odx-app .board.bi .mgroup + .mgroup { border-top: 0; }

/* 행 */
html.odx-app .board.bi .mrow,
html.odx-app .board.bi .mrow.n2 {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: calc(16px * var(--fs, 1)) calc(22px * var(--fs, 1)) calc(4px + 44px * var(--fs, 1));
    row-gap: 2px; column-gap: 0; align-items: stretch;
    position: relative; margin: 0; padding: 8px 16px; border: 0; border-radius: 0; background: none;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
    content-visibility: auto; contain-intrinsic-size: auto 106px;
    max-height: 180px;
    transition: max-height 240ms var(--ease-in-out, cubic-bezier(.645, .045, .355, 1)), opacity 160ms linear;
}
html.odx-app .board.bi .mrow.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
html.odx-app .board.bi .mrow:nth-child(even),
html.odx-app .board.bi .mrow:hover { background: none; }

/* 메타 줄(16) + 팀 줄(22) — 한 플렉스 상자를 ::after(폭 100%)로 두 줄로 나눈다. 팀(.h .x .a)은 order:2로 둘째 줄. */
html.odx-app .board.bi .m-teams {
    grid-row: 1 / 3; grid-column: 1 / -1; align-self: stretch;
    display: flex; flex-wrap: wrap; align-items: center; align-content: space-between; column-gap: 6px; row-gap: 0;
    min-width: 0; padding-right: 36px; overflow: hidden;
    font-size: calc(11px * var(--fs, 1)); line-height: calc(16px * var(--fs, 1)); color: var(--text-3); white-space: nowrap;
}
html.odx-app .board.bi .m-teams::after { content: ""; order: 1; flex-basis: 100%; height: 0; }
html.odx-app .board.bi .m-teams > :is(.h, .x, .a) { order: 2; }
html.odx-app .board.bi .m-teams > .m-share { display: none; }
html.odx-app .board.bi .m-teams > .pb-ico { display: inline-flex; flex: none; padding: 0 !important; color: var(--text-3); }   /* [FIX DF-16] 웹 .pb-ico 좌우 2px !important를 걷어 16pt 여백에 맞춘다 */
html.odx-app .board.bi .m-teams > .pb-ico .sico { width: calc(12px * var(--fs, 1)); height: calc(12px * var(--fs, 1)); }
html.odx-app .board.bi .m-teams > .m-no {
    flex: none; font-family: var(--mono); font-size: calc(11px * var(--fs, 1)); font-weight: 600; letter-spacing: -.02em; color: var(--text-2);
}
/* 리그(경기번호순 · 추출) — 리그 hue 눈금 2×10(채도 30% · 명도 56%, 장식 색은 이것뿐) + 이름 */
html.odx-app .board.bi .m-teams > .m-lg {
    flex: 0 1 auto; min-width: 0; max-width: 9.5em; overflow: hidden; text-overflow: ellipsis;
    font-size: calc(11px * var(--fs, 1)); color: var(--text-3);
}
html.odx-app .board.bi .m-teams > .m-lg::before {
    content: ""; display: inline-block; width: 2px; height: 10px; margin-right: 5px; border-radius: 1px; vertical-align: -1px;
    background: hsl(var(--h, 210) 30% 56%);
}
/* 라인 칩(H -1 · U/O 2.5) · '해외 없음' · 마켓 칩(추출) — 무채 테두리 꼬리표 */
html.odx-app .board.bi .m-teams > .chip {
    flex: none; height: calc(16px * var(--fs, 1)); padding: 0 4px; border: 0; border-radius: 3px; background: none;
    box-shadow: inset 0 0 0 1px var(--line);
    font-size: calc(11px * var(--fs, 1)); font-weight: 600; line-height: 1; color: var(--text-2);   /* [FIX V-13 2026-10-20] 10.5 → 11(§2.3 하한 — 한글 '해외 없음'이 든다) */
}
html.odx-app .board.bi .m-teams > .chip-line { font-family: var(--mono); letter-spacing: -.02em; }
html.odx-app .board.bi .m-teams > .chip-mkt { color: var(--text-2); }
html.odx-app .board.bi .m-teams > .badge-warn { height: 16px; padding: 0 4px; font-size: 10px; }
/* 팀 — 홈 650 · ':' --text-4 · 원정 400 --text-2, 말줄임(줄바꿈 없음). 원정이 남은 폭을 갖는다. */
html.odx-app .board.bi .m-teams > :is(.h, .a) {
    display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis;
    font-size: calc(15.5px * var(--fs, 1)); line-height: calc(22px * var(--fs, 1)); letter-spacing: -.02em;
}
html.odx-app .board.bi .m-teams > .h { flex: 0 1 auto; max-width: calc(100% - 64px); font-weight: 650; color: var(--text); }
html.odx-app .board.bi .m-teams > .x { flex: none; font-size: calc(15.5px * var(--fs, 1)); line-height: calc(22px * var(--fs, 1)); color: var(--text-4); }
html.odx-app .board.bi .m-teams > .a { flex: 1 1 0; font-weight: 400; color: var(--text-2); }

/* 별(고정) — 오른쪽, 그림 18 · 대상 44. ★☆ 글자는 font-size 0 + 마스크(§2.8). */
html.odx-app .board.bi .m-star {
    grid-row: 1 / 3; grid-column: -2; justify-self: end; align-self: center; position: relative;
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; margin: 0 -12px 0 0; padding: 0; border: 0; background: none;
    font-size: 0; line-height: 0; color: var(--text-4);
}
html.odx-app .board.bi .m-star::before {
    content: ""; width: 18px; height: 18px; background: currentColor;
    -webkit-mask: url(app-icons/star.svg) center / contain no-repeat; mask: url(app-icons/star.svg) center / contain no-repeat;
}
html.odx-app .board.bi .m-star.on { color: var(--text); }
html.odx-app .board.bi .m-star.on::before { -webkit-mask-image: url(app-icons/star-fill.svg); mask-image: url(app-icons/star-fill.svg); }
html.odx-app .board.bi .m-star:hover { color: var(--text-4); }
html.odx-app .board.bi .m-star.on:hover { color: var(--text); }

/* 시각(정렬이 경기번호순이 아닐 때만 — 경기번호순은 구획 머리가 말한다) */
html.odx-app .board.bi .m-when {
    grid-row: 1; grid-column: -2; justify-self: end; align-self: center; margin-right: 32px;
    font-family: var(--mono); font-size: calc(11px * var(--fs, 1)); font-weight: 500; line-height: 1; color: var(--text-2);
}
html.odx-app .board.bi .m-when .t { font-size: inherit; color: inherit; }
html.odx-app .board.bi .m-when .c { display: none; }
html.odx-app .board.has-tgroups .m-when { display: none; }

/* 판정 꼬리표(§3.7, 회원만) — 높이 18 · 반경 4 · 11/700, 숫자 없음. 메타 줄 오른쪽(시각 왼쪽). */
html.odx-app .board.bi .m-tag {
    grid-row: 1; grid-column: 1 / -1; justify-self: end; align-self: center;
    display: flex; flex-direction: row; align-items: center; gap: 4px;
    margin-right: calc(32px + 6px + 33px * var(--fs, 1));
}
html.odx-app .board.has-tgroups .m-tag { margin-right: 32px; }
html.odx-app .board.bi .m-tag .bi-books { display: none; }
html.odx-app .board.bi .m-tag :is(.badge, .badge-value, .bi-why) {
    display: inline-flex; align-items: center; gap: 2px; height: 18px; margin: 0; padding: 0 6px;
    border: 0; border-radius: 4px; box-shadow: none; background: none;
    font-family: var(--font); font-size: calc(11px * var(--fs, 1)); font-weight: 700; line-height: 1; letter-spacing: .02em; white-space: nowrap;
}
html.odx-app .board.bi .m-tag .badge-value { background: var(--dom); color: #fff; }
html.odx-app .board.bi .m-tag .badge-value .vd { font-size: 8px; margin-left: 1px; opacity: 1; }
html.odx-app .board.bi .m-tag .badge-value.v-low { background: none; box-shadow: inset 0 0 0 1px var(--dom-sw); color: var(--dom-soft); }
html.odx-app .board.bi .m-tag .badge-value:hover,
html.odx-app .board.bi .m-tag .badge-value.on { box-shadow: none; }
html.odx-app .board.bi .m-tag .badge-value.v-low.on { box-shadow: inset 0 0 0 1px var(--dom-sw); }
html.odx-app .board.bi .m-tag .bi-why { border: 1px dashed var(--line-strong); color: var(--text-4); font-weight: 600; }
html.odx-app .board.bi .m-tag .bi-why:hover, html.odx-app .board.bi .m-tag .bi-why.on { border-style: dashed; border-color: var(--line-strong); background: none; color: var(--text-4); }
html.odx-app .board.bi .m-tag .badge-warn { box-shadow: inset 0 0 0 1px rgba(217, 155, 43, .45); color: var(--warn-soft); }
html.odx-app .board.bi .m-tag .bi-verdict.on { outline: 0; }
html.odx-app .board.bi .m-tag .badge-dom { background: var(--dom-tint); box-shadow: inset 0 0 0 1px rgba(224, 87, 76, .5); color: var(--dom-soft); }
/* [APP-MOTION V02] 가치 꼬리표에 셀렉션 이름(`가치▼ 패` — 숫자 없음, Board.razor 앱 분기 .vsel). 화살표 뒤 1px 구분선, 선 앞뒤 4px씩
   (꼬리표 flex gap 2 + margin 2 = 앞 4 · padding 5 − 선 1 = 뒤 4 — 리뷰 DF-5: 종전 6 · 3으로 선이 이름에 붙어 보였다).
   큰 글자(--fs ≥ 1.2)에서는 숨는다(375pt 겹침 0 — 꼬리표 왼쪽 여유 실측 최소 64px, .vsel ≈ 31px). */
html.odx-app .board.bi .m-tag .badge-value .vsel { margin-left: 2px; padding-left: 5px; box-shadow: inset 1px 0 0 rgba(255, 255, 255, .45); }
html.odx-app .board.bi .m-tag .badge-value.v-low .vsel { box-shadow: inset 1px 0 0 var(--dom-sw); }
html.odx-app[data-odx-fs="l"] .board.bi .m-tag .vsel { display: none; }
/* [APP-MOTION §3.2(b)] 판정 꼬리표는 누르는 자리(가치 근거로 시트가 열린다) — 히트 44(위아래 13 · 왼쪽 4). 오른쪽은 늘리지 않는다:
   바로 오른쪽이 별(.m-star 44)이라 4px만 넓혀도 별의 왼쪽 가장자리 탭이 꼬리표로 갔다(리뷰 RG-6). 누름 = 칩과 같은 .96(앱-12). */
html.odx-app .board.bi .m-tag :is(.badge-value, .bi-why) { position: relative; }
html.odx-app .board.bi .m-tag :is(.badge-value, .bi-why)::after { content: ""; position: absolute; inset: -13px 0 -13px -4px; }

/* 가치 행 — 왼쪽 2pt --dom 선(후순위 ▲는 --dom-sw). 모든 행에 투명으로 두고 .is-value에서 scaleY 1(가치 드러남 200ms).
   웹의 inset 3px 막대 · PREMIUM TIP 링(::before)은 여기서 끈다. */
html.odx-app .board.bi .mrow::before {
    content: ""; position: absolute; inset: 0 auto 0 0; width: 2px; height: auto; padding: 0; border-radius: 0;
    background: var(--dom); -webkit-mask: none; mask: none; animation: none; pointer-events: none;
    transform: scaleY(0); transform-origin: 50% 0;
    transition: transform 200ms var(--ease-out, cubic-bezier(.215, .61, .355, 1));
}
html.odx-app .board.bi .mrow.is-value::before { transform: scaleY(1); }
html.odx-app .board.bi .mrow.is-value-low::before { background: var(--dom-sw); }
html.odx-app .board.bi .mrow.is-value,
html.odx-app .board.bi .mrow.is-value.is-value-low { box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); }

/* PREMIUM TIP 행(§3.8, 프라임 세션만) — 바깥 여백 6/8 · 안쪽 8 · 반경 8. 팻말은 행 상자 안 메타 줄 첫 항목
   (웹처럼 top:-9px로 행 밖에 걸면 content-visibility의 페인트 봉쇄에 잘린다).
   현행(D2 기본) = 웹의 그라데이션 링 + 6초 광택을 ::after로 옮겨 그대로(의뢰인 승인 표현 — 그라데이션 예외). 권장 단색은 앱-13a.
   [APP-MOTION PF-2] 광택(tipring = background-position)은 합성되지 않아 도는 동안 매 프레임 재계산 · 페인트가 난다 — 그래서 <b>기본은 멈춤</b>이고
   브리지가 보이는(IntersectionObserver) TIP 행에만 data-odx-shine을 쓴다(스크롤 중 · 시트/틀/메뉴가 덮은 동안은 지운다). content-visibility는
   CSS 애니메이션을 멈추지 않아 화면 밖 행의 광택이 유휴 비용 대부분이었다(리뷰 PERF-1).
   [APP-MOTION M15] 가치가 새로 붙은 보이는 행의 꼬리표(.badge-value)는 브리지 WAAPI가 4px 밀어 넣는다 — CSS 삽입 애니메이션으로 만들지 않는다
   (회로 시작 때 프리렌더 행이 통째로 바뀌어 모든 가치 행에서 돈다). 선(.mrow::before)은 위 클래스 전이 그대로. */
html.odx-app .board.bi .mrow.is-tip {
    margin: 6px 8px; padding: 10px 8px; border-radius: 8px;
    background: linear-gradient(165deg, var(--tippick-dim), transparent 52%);
    box-shadow: none; contain-intrinsic-size: auto 130px;
}
html.odx-app .board.bi .mrow.is-tip::after {
    content: ""; position: absolute; inset: 0; top: 0; left: 0; z-index: auto; padding: 1.5px; border-radius: inherit;
    background: linear-gradient(115deg, var(--tippick), var(--tippick-2) 25%, var(--tippick) 50%, var(--tippick-2) 75%, var(--tippick)) 0 0 / 200% 100%;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
    box-shadow: none; color: transparent; font-size: 0; letter-spacing: 0; pointer-events: none;
    animation: tipring 6s linear infinite paused;
}
html.odx-app .board.bi .mrow.is-tip[data-odx-shine]::after { animation-play-state: running; }
html.odx-app .board.bi .mrow.is-tip .m-teams::before {
    content: "PREMIUM TIP"; order: -1; flex: none; display: inline-flex; align-items: center;
    height: calc(16px * var(--fs, 1)); padding: 0 6px; border-radius: 3px; background: #6d3fd1; color: #fff;
    font-family: var(--font); font-size: calc(9.5px * var(--fs, 1)); font-weight: 700; letter-spacing: .1em;
}

/* 킥오프 0초 — 행이 접힌다(live.js가 붙이는 expired-row; 웹은 display:none). :has 없이도 같다. */
html.odx-app .board.bi .mrow.expired-row {
    display: grid; max-height: 0; padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0;
    opacity: 0; overflow: hidden; pointer-events: none;
}

/* 동작 줄이기(OS 설정 · 네이티브 prefs) — 이동·확대 없이 즉시 */
@media (prefers-reduced-motion: reduce) {
    html.odx-app .board.bi .mrow, html.odx-app .board.bi .mrow::before { transition: none; }
    html.odx-app .board.bi .mrow.is-tip::after { animation: none; }
}
html.odx-app[data-odx-motion="reduced"] .board.bi .mrow,
html.odx-app[data-odx-motion="reduced"] .board.bi .mrow::before { transition: none; }
html.odx-app[data-odx-motion="reduced"] .board.bi .mrow.is-tip::after { animation: none; }
/* ── /앱-5 ── */

/* ── 앱-6 칸 [B2] ── §3.6(칸 tile) */
/* 칸(§3.6) — n번째 셀렉션의 국내 · 해외 · 차이 세 .bi-o를 같은 칸(3행 n열)에 겹친다. 국내 .bi-o가 칸 상자(누르는 자리)이고
   해외 · 차이는 그 위 둘째 줄에 얹힌 글자일 뿐이다(누르기 통과 · aria-hidden). 그리드 2열 × 2행: [이름 | 국내] / [해외 평균▲▼ | 차이율]. */
html.odx-app .board.bi :is(.bi-dom, .bi-for, .bi-dif) { display: contents; }
html.odx-app .board.bi :is(.bi-dom, .bi-for, .bi-dif)::before { content: none; }
html.odx-app .board.bi .bi-o { grid-row: 3; min-height: 0; align-self: end; border-left: 0; }
html.odx-app .board.bi :is(.bi-dom, .bi-for, .bi-dif) > .bi-o:first-child { border-left: 0; }
html.odx-app .board.bi :is(.bi-dom, .bi-for, .bi-dif) > .bi-o:nth-child(1) { grid-column: 1; }
html.odx-app .board.bi :is(.bi-dom, .bi-for, .bi-dif) > .bi-o:nth-child(2) { grid-column: 2; }
html.odx-app .board.bi :is(.bi-dom, .bi-for, .bi-dif) > .bi-o:nth-child(3) { grid-column: 3; }

/* 국내 칸(누르는 자리) — 119×44(390pt). 누름(APP-MOTION M01) = 브리지 누름 모듈(data-odx-press — 60ms 의도 지연, 스크롤이면 취소)이
   쓰는 속성으로 scale(.97) + 틴트 층(::before) --text 7%(라이트 6%). 들어감 80ms --ease-out · 복귀 160ms --ease-press.
   국내 유리 틴트(background-color 160ms)는 이 한 칸의 예외 전이(§8-1). [PF-3] --m 전이는 지웠다 — 계기는 ::after의 transform이 옮긴다. */
html.odx-app .board.bi .bi-o.dom {
    display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: calc(22px * var(--fs, 1)) calc(14px * var(--fs, 1));
    column-gap: 4px; row-gap: 2px; align-items: center; justify-items: stretch;
    height: calc(44px * var(--fs, 1)); padding: 3px 8px; border-radius: 6px; position: relative; overflow: hidden;
    background: none; box-shadow: none; outline: 0;
    transition: background-color 160ms linear, transform var(--t-release, 160ms) var(--ease-press, cubic-bezier(.2, .9, .3, 1));
    -webkit-user-select: none; user-select: none;
}
html.odx-app .board.bi .bi-o.dom .o-sel {
    display: inline-flex; align-items: center; gap: 3px; grid-area: 1 / 1; justify-self: start;
    font-family: var(--font); font-size: calc(11px * var(--fs, 1)); font-weight: 500; line-height: 1; letter-spacing: 0; color: var(--text-3);
}
/* 국내 숫자의 자리(.o-cl — Board.razor 앱 분기의 래퍼): 첫 줄 오른쪽 칸. 틱 굴림(M12)을 이 줄 높이로 자른다(오도미터 — 옛 값 · 새 값이
   숫자 줄 안에서만 오가고 둘째 줄(해외 평균 · 차이율) 위를 지나지 않는다, 리뷰 DF-3). 가로는 칸의 안쪽 여백(8)까지 — 종전 칸 잘림과 같다. */
html.odx-app .board.bi .bi-o.dom .o-cl {
    grid-area: 1 / 2; justify-self: stretch; min-width: 0; overflow: hidden;
    margin-right: -8px; padding-right: 8px; text-align: right;
}
html.odx-app .board.bi .bi-o.dom .o-now {
    grid-area: 1 / 2; justify-self: end; min-width: 0;
    font-family: var(--mono); font-size: calc(17.5px * var(--fs, 1)); font-weight: 600; line-height: 1; letter-spacing: -.04em;
    font-variant-numeric: tabular-nums; color: var(--text);
}
html.odx-app .board.bi .bi-o.dom .o-cl > .o-now { display: block; justify-self: normal; }
html.odx-app .board.bi .bi-o.dom .o-open { display: none; }
html.odx-app .board.bi .bi-o.dom.is-na .o-now { color: var(--text-4); font-weight: 400; }   /* 국내 배당 없음('—'). 해외만 없는 칸은 .nof(국내 숫자 그대로) */
html.odx-app .board.bi .bi-o.dom.clickable:hover:not(.adv-dom):not(.adv-for) { background: none; }
html.odx-app .board.bi .bi-o.is-open { box-shadow: none; }
/* 누름(M01) — :active 면은 지웠다(스크롤을 시작하는 손가락에도 번쩍였다). 틴트는 섬광 층(::before)을 같이 쓴다(색만 --text로). */
html.odx-app .board.bi .bi-o.dom.clickable[data-odx-press="on"] { transform: scale(.97); transition-duration: var(--t-press, 80ms); }
html.odx-app .board.bi .bi-o.dom[data-odx-press]::before { background: var(--text); transition: opacity var(--t-release, 160ms) linear; }
html.odx-app .board.bi .bi-o.dom[data-odx-press="on"]::before { opacity: .07; transition-duration: var(--t-press, 80ms); }
html.odx-app[data-theme="light"] .board.bi .bi-o.dom[data-odx-press="on"]::before { opacity: .06; }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .board.bi .bi-o.dom[data-odx-press="on"]::before { opacity: .06; } }

/* 국내 유리(.adv-dom) = 틴트 + 국내 숫자 --dom-soft + 바닥 2pt 계기 막대(길이 = 계기 m, 왼쪽 기준 — §3.9). */
html.odx-app .board.bi .bi-o.dom.adv-dom { background: var(--dom-tint); }
html.odx-app .board.bi .bi-o.dom.adv-dom .o-now { color: var(--dom-soft); }
/* 현행 색(D1 web — 기본값): 해외 유리 칸 = --for-tint + 국내 숫자 --for-soft(웹 표현 그대로). 권장(signal)은 앱-13a. */
html.odx-app .board.bi .bi-o.dom.adv-for { background: var(--for-tint); }
html.odx-app .board.bi .bi-o.dom.adv-for .o-now { color: var(--for-soft); }

/* 칸 사이 세로 헤어라인(위아래 9 남김) — 국내 유리 칸 옆에는 긋지 않는다. ::after는 국내 유리 칸에서 계기 막대가 쓴다. */
html.odx-app .board.bi .bi-dom > .bi-o + .bi-o::after {
    content: ""; position: absolute; left: 0; top: 9px; bottom: 9px; width: var(--hair-w, 1px); background: var(--line-soft); pointer-events: none;
}
html.odx-app .board.bi .bi-dom > .bi-o.adv-dom + .bi-o::after { content: none; }
/* [FIX V-04 2026-10-20] 행의 마켓에 없는 자리(3열 보드의 2-way 행 '무' · 추출 화면 언더오버 행의 빈 ③ — Board.razor IsVoidSlot)는 자리만 지킨다.
   '무 — —'는 결측처럼 읽혔다(야구에는 무승부가 없다). 칸 상자 · 해외 · 차이 세 줄 모두 숨기고, 다음 칸의 헤어라인도 긋지 않는다. */
html.odx-app .board.bi .bi-o.is-void { visibility: hidden; pointer-events: none; }
html.odx-app .board.bi .bi-dom > .bi-o.is-void + .bi-o::after { content: none; }
html.odx-app .board.bi .bi-dom > .bi-o.dom.adv-dom::after {
    content: ""; position: absolute; left: 0; right: auto; top: auto; bottom: 0; width: 100%; height: 2px;
    background: var(--dom); pointer-events: none;
    transform-origin: 0 50%; transform: scaleX(var(--m, 0));
    transition: transform var(--t-move, 240ms) var(--ease-out, cubic-bezier(.215, .61, .355, 1));
}
/* 계기 이동(서버가 --m을 바꿈) 240ms — [APP-MOTION M14 · PF-3] 계기 요소의 transform 전이(합성 단계). 종전 --m 전이는 메인 스레드에서 보간됐다.
   새로 생긴 계기(.adv-dom이 붙음)는 움직이지 않는다 — 삽입 애니메이션 없음, 옆 칸 헤어라인(같은 ::after)에서 넘어온 전이는 브리지가 끝낸다. */
@supports (transform: scaleX(1)) {
    @property --m { syntax: '<number>'; inherits: true; initial-value: 0; }
}
/* 틱 섬광 층 — 브리지가 WAAPI로 불투명도만 움직인다(pseudoElement '::before'). 국내 유리 쪽 변화 = 적, 반대 = 청. */
html.odx-app .board.bi .bi-o.dom::before {
    content: ""; position: absolute; inset: 0; border-radius: inherit; opacity: 0; pointer-events: none; background: var(--for);
}
html.odx-app .board.bi .bi-o.dom[data-tick-dir="dom"]::before { background: var(--dom); }

/* 배당 틱 굴림(§4.2) — 브리지가 바뀐 .o-now에 data-prev(옛 글자) · data-tick(a/b 번갈아 — 같은 키프레임 재시작)을 쓴다.
   옛 값(::before)이 위로 빠지고 새 값이 아래서 올라온다 220ms — 숫자 줄(.o-cl)이 잘라 오도미터처럼 그 줄 안에서만 오간다. 화면 밖 · 13칸 이상 묶음 ·
   설정 끔 · 동작 줄이기면 브리지가 속성을 쓰지 않는다. 섬광은 위 ::before 층(브리지 WAAPI).
   채움은 backwards(시작 전 자리만) — 끝난 굴림이 'both'로 붙들려 칸마다 쌓이지 않게(리뷰 PERF-2). 끝값 = 기본값(제자리 · 옛 값 불투명도 0)이라 모습은 같다. */
html.odx-app .board.bi .bi-o.dom .o-now[data-tick] { position: relative; }
html.odx-app .board.bi .bi-o.dom .o-now[data-tick]::before {
    content: attr(data-prev); position: absolute; right: 0; bottom: 100%; opacity: 0; pointer-events: none;
}
html.odx-app .board.bi .bi-o.dom .o-now[data-tick="a"] { animation: axb-roll-a 220ms var(--ease-out, cubic-bezier(.215, .61, .355, 1)) backwards; }
html.odx-app .board.bi .bi-o.dom .o-now[data-tick="b"] { animation: axb-roll-b 220ms var(--ease-out, cubic-bezier(.215, .61, .355, 1)) backwards; }
html.odx-app .board.bi .bi-o.dom .o-now[data-tick="a"]::before { animation: axb-prev-a 220ms linear backwards; }
html.odx-app .board.bi .bi-o.dom .o-now[data-tick="b"]::before { animation: axb-prev-b 220ms linear backwards; }
@keyframes axb-roll-a { from { transform: translateY(100%); } }
@keyframes axb-roll-b { from { transform: translateY(100%); } }
@keyframes axb-prev-a { 0%, 99% { opacity: 1; } 100% { opacity: 0; } }
@keyframes axb-prev-b { 0%, 99% { opacity: 1; } 100% { opacity: 0; } }
/* [APP-MOTION M12] 굴림 방향 = 값의 방향. 위(기본)는 국내가 오른 경우(data-tick-dir="dom" — 아래에서 올라온다). 내린 경우(for)는 새 값이
   위에서 내려오고 옛 값(::before)은 아래로 빠진다. 브리지는 data-tick-dir → data-prev → data-tick 순으로 써서 a/b 재시작보다 방향이 먼저 선다. */
html.odx-app .board.bi .bi-o.dom[data-tick-dir="for"] .o-now[data-tick="a"] { animation-name: axb-roll-dn-a; }
html.odx-app .board.bi .bi-o.dom[data-tick-dir="for"] .o-now[data-tick="b"] { animation-name: axb-roll-dn-b; }
html.odx-app .board.bi .bi-o.dom[data-tick-dir="for"] .o-now[data-tick]::before { bottom: auto; top: 100%; }
/* 아래로 빠지는 옛 값도 숫자 줄(.o-cl)이 자른다 — 오르는 경우와 같은 오도미터(종전 60% 흐림 키프레임은 지웠다, 리뷰 DF-3). */
@keyframes axb-roll-dn-a { from { transform: translateY(-100%); } }
@keyframes axb-roll-dn-b { from { transform: translateY(-100%); } }

/* 슬립에 담김 = 이름 옆 체크(11pt — APP-MOTION V07, 잉크) — 링 · 테두리 · 색 채움 없음(§2.2). */
html.odx-app .board.bi .bi-o.in-slip { outline: 0; border-radius: 6px; }
html.odx-app .board.bi .bi-o.dom.in-slip .o-sel { color: var(--text); font-weight: 700; }
html.odx-app .board.bi .bi-o.dom.in-slip .o-sel::after {
    content: ""; width: 11px; height: 11px; background: var(--ink, var(--text));
    -webkit-mask: url(app-icons/check.svg) center / contain no-repeat; mask: url(app-icons/check.svg) center / contain no-repeat;
}
/* PREMIUM TIP 예상 칸 = 이름표만 보라(높이 15 · 반경 3) — 칸 링 · 숫자 보라 없음. */
html.odx-app .board.bi .bi-o.tip-pick { box-shadow: none; }
html.odx-app .board.bi .bi-o.dom.tip-pick:not(.adv-dom):not(.adv-for) { background: none; }
html.odx-app .board.bi .bi-o.dom.tip-pick .o-sel {
    height: calc(15px * var(--fs, 1)); padding: 0 4px; border-radius: 3px; background: var(--tippick); color: #fff; font-weight: 700;
}
html.odx-app .board.bi .bi-o.dom.tip-pick.in-slip .o-sel::after { background: #fff; }

/* 해외 평균 · 차이율(칸 둘째 줄) — 누르기 통과, 칸이 한 문장으로 읽힌다(aria-hidden). */
html.odx-app .board.bi .bi-o.for,
html.odx-app .board.bi .bi-o.dif {
    display: flex; flex-direction: row; align-items: center; gap: 1px;
    align-self: end; height: calc(14px * var(--fs, 1)); min-height: 0; margin: 0 0 3px; padding: 0 8px;
    background: none; pointer-events: none;
}
html.odx-app .board.bi .bi-o.for { justify-self: start; }
html.odx-app .board.bi .bi-o.dif { justify-self: end; }
html.odx-app .board.bi .bi-o.for :is(.o-sel, .o-avg4, .o-alpha) { display: none; }
html.odx-app .board.bi .bi-o.dif .o-sel { display: none; }
html.odx-app .board.bi .bi-o.for .o-now {
    font-family: var(--mono); font-size: calc(11px * var(--fs, 1)); font-weight: 400; line-height: 1; letter-spacing: -.03em; color: var(--text-3);
}
html.odx-app .board.bi .bi-o.for.is-na .o-now { color: var(--text-4); }
/* 현행 색(D1 web — 기본값): 해외 전체 평균 = 적색(2026-08-26 의뢰인), 11px · 400으로 낮춘다. */
html.odx-app .board.bi .bi-o.for .o-now.o-avg-all { color: var(--dom); }
/* 초기 대비 ▲▼ 7.5px --text-4(무채 — 적·청 화살표는 앱에서 쓰지 않는다). 값은 숨기고 화살표만. */
html.odx-app .board.bi .bi-o.for .o-open { display: inline-flex; align-items: center; margin: 0; font-size: 0; line-height: 1; }
html.odx-app .board.bi .bi-o.for .o-open .arr { margin-left: 1px; font-size: 7.5px; vertical-align: 0; color: var(--text-4); }
/* [APP-MOTION V01] 차이율은 회원이 '찾지 않고 보는' 둘째 숫자 — 국내 유리(양수)만 12/650으로 올린다(위계: 국내 17.5 > 양수 차이율 12 >
   그 밖 차이율 11/600 > 해외 평균 11/400). 보드 차이율의 대부분(실측 162칸 중 131)이 음수라 전부 올리면 '굵은 청색 판'이 됐다 —
   강조는 볼 곳에만(리뷰 DF-9). 색 규칙은 그대로. */
html.odx-app .board.bi .bi-o.dif .diff {
    font-family: var(--mono); font-size: calc(11px * var(--fs, 1)); font-weight: 600; line-height: 1; letter-spacing: -.03em;
}
html.odx-app .board.bi .bi-o.dif .diff.pos { font-size: calc(12px * var(--fs, 1)); font-weight: 650; }
html.odx-app .board.bi .bi-o.dif .diff.zero { color: var(--text-3); }
html.odx-app .board.bi .bi-o.dif .diff.na { color: var(--text-4); font-weight: 400; }

/* 큰 글자(prefs.fontScale ≥ 1.2 → data-odx-fs="l"): 칸은 이름 · 국내 · 차이율만(해외 평균은 시트 · 접근성 라벨에 남는다). */
html.odx-app[data-odx-fs="l"] .board.bi .bi-o.for { display: none; }

@media (prefers-reduced-motion: reduce) {
    html.odx-app .board.bi .bi-o.dom .o-now[data-tick], html.odx-app .board.bi .bi-o.dom .o-now[data-tick]::before { animation: none; }
    html.odx-app .board.bi .bi-o.dom { transition: background-color 120ms linear; }
    html.odx-app .board.bi .bi-dom > .bi-o.dom.adv-dom::after { transition: none; }
}
html.odx-app[data-odx-motion="reduced"] .board.bi .bi-o.dom { transition: background-color 120ms linear; }
html.odx-app[data-odx-motion="reduced"] .board.bi .bi-o.dom .o-now[data-tick],
html.odx-app[data-odx-motion="reduced"] .board.bi .bi-o.dom .o-now[data-tick]::before { animation: none; }
html.odx-app[data-odx-motion="reduced"] .board.bi .bi-dom > .bi-o.dom.adv-dom::after { transition: none; }
/* 누름의 크기는 앱-12 동작 줄이기 묶음이 끈다(틴트만 남는다 — [data-odx-press] transform: none). */
/* ── /앱-6 ── */

/* ── 앱-7 구획 머리 [B2] ── §3.4 */
/* 구획 머리(§3.4) — 높이 30 · sticky top --stick · 불투명(블러 없음) · 위아래 헤어라인. 바탕: 다크 --surface · 라이트 --surface-2.
   킥오프(.mtime, 경기번호순): '오늘 14:00 · 4경기' ……… '8시간 9분 뒤'(live.js data-fmt="coarse" — 10분 이하만 mm:ss + 황색 글자).
   리그(.mgroup-head, 그 밖의 정렬): '▎K리그2 축구' ……… '최고 +2.9% · 4경기'. 누르면 접힘(웹 그대로). */
html.odx-app .board.bi .mtime,
html.odx-app .board.bi .mgroup-head {
    position: sticky; top: var(--stick); z-index: 5;
    display: flex; align-items: center; gap: 6px; width: 100%; height: calc(30px * var(--fs, 1)); margin: 0; padding: 0 16px;
    border: 0; border-radius: 0; background: var(--surface);
    box-shadow: inset 0 var(--hair-w, 1px) 0 var(--line-soft), inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
    font-family: var(--font); font-size: calc(12px * var(--fs, 1)); font-weight: 600; line-height: 1; color: var(--text);
    text-align: left; white-space: nowrap; overflow: hidden;
    transition: height 240ms var(--ease-in-out, cubic-bezier(.645, .045, .355, 1)), opacity 160ms linear;
}
html.odx-app[data-theme="light"] .board.bi :is(.mtime, .mgroup-head) { background: var(--surface-2); }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .board.bi :is(.mtime, .mgroup-head) { background: var(--surface-2); } }
html.odx-app .board.bi .mgroup-head:hover { background: var(--surface); }
html.odx-app[data-theme="light"] .board.bi .mgroup-head:hover { background: var(--surface-2); }

html.odx-app .board.bi .mtime > b { font-weight: 600; }
html.odx-app .board.bi .mtime > .d { font-weight: 500; color: var(--text-3); }
html.odx-app .board.bi .mtime > .cd {
    margin-left: auto; font-size: calc(11.5px * var(--fs, 1)); font-weight: 500; color: var(--text-2);
}
html.odx-app .board.bi .mtime > .cd :is(b, .n) { font-family: var(--mono); font-size: calc(11.5px * var(--fs, 1)); font-weight: 600; letter-spacing: -.02em; color: var(--text); }
html.odx-app .board.bi .mtime > .cd[data-state="soon"],
html.odx-app .board.bi .mtime > .cd[data-state="soon"] :is(b, .n) { color: var(--warn); }
/* 킥오프 0초 — 구획 머리도 접힌다(:has 미지원 기기는 머리만 남고 행은 expired-row로 사라진다). */
html.odx-app .board.bi .mtime:has(> .cd[data-state="started"]) { height: 0; opacity: 0; pointer-events: none; }

html.odx-app .board.bi .mgroup-head .ch { display: none; }
html.odx-app .board.bi .mgroup-head .lg {
    display: inline-flex; align-items: center; flex: none; min-width: 0; max-width: 50%; margin: 0; padding: 0;
    border: 0; border-radius: 0; background: none; overflow: hidden; text-overflow: ellipsis;
    font-size: calc(12px * var(--fs, 1)); font-weight: 600; letter-spacing: 0; color: var(--text);
}
html.odx-app .board.bi .mgroup-head .lg::before {
    content: ""; flex: none; width: 3px; height: 12px; margin-right: 7px; border-radius: 1px; background: hsl(var(--h, 210) 30% 56%);
}
html.odx-app .board.bi .mgroup-head .sp { margin-right: auto; font-size: calc(12px * var(--fs, 1)); font-weight: 500; color: var(--text-3); }
html.odx-app .board.bi .mgroup-head .diff { font-size: calc(11.5px * var(--fs, 1)); font-weight: 600; letter-spacing: -.02em; }
html.odx-app .board.bi .mgroup-head .diff::before {
    content: "최고 "; font-family: var(--font); font-size: calc(11px * var(--fs, 1)); font-weight: 500; letter-spacing: 0; color: var(--text-3);
}
html.odx-app .board.bi .mgroup-head .n { margin-left: 4px; font-family: var(--font); font-size: calc(11px * var(--fs, 1)); font-weight: 500; color: var(--text-3); }
html.odx-app .board.bi .mgroup-head .n::before { content: "· "; }

@media (prefers-reduced-motion: reduce) { html.odx-app .board.bi :is(.mtime, .mgroup-head) { transition: none; } }
html.odx-app[data-odx-motion="reduced"] .board.bi :is(.mtime, .mgroup-head) { transition: none; }
/* ── /앱-7 ── */

/* ── 앱-8a 시트 · 공통 [B1] ── §3.12–3.13 · §5.2(모달 → 시트 · 손잡이 · 잠금 시트 · 필터/전환 시트) */
/*  시트 공통 — 두 꼴(브리지 app-bridge.js 머리 주석의 계약과 같다):
    ① 앱 시트 뿌리 .ax-sheet(화면 전체 고정, z 100 = 모달 층) > 딤 .ax-scrim + 면 .ax-panel(> .grab). 경기 시트 · 필터 · 가치 TOP ·
       PREMIUM TIP · 잠금 시트가 쓴다(슬립 시트는 같은 계약에 자기 이름 .ss-scrim/.ss-panel — 앱-9).
    ② Blazor 모달 .modal-veil > .modal — 앱에서는 아래 정렬 바닥 시트(§5.2.5). 블러는 끈다(블러는 세 곳뿐 — §2.7, Android 0).
    등장 = 삽입 애니메이션(면 translateY 100%→0 300ms iOS 시트 곡선, 딤 페이드). 채움은 backwards — 끝난 뒤에는 브리지가 면에 쓰는
    transform(끌어내림)을 덮지 않는다. 닫힘은 브리지가 240ms 내리는 연출 뒤 [data-odx-close]를 눌러 Blazor가 지운다. 바탕 페이지는 줄이지 않는다.
    디텐트(§3.10): 크게 = 100dvh − 상태바 − 10(기본) · 중간 = 62dvh(.is-mid, 또는 브리지가 끌어내려 뿌리에 쓰는 data-odx-detent="mid") ·
    꼭 맞게 = .is-fit(내용 높이, 크게 상한). */
html.odx-app .ax-sheet { position: fixed; inset: 0; z-index: 100; }
html.odx-app .ax-scrim {
    position: absolute; inset: 0; background: var(--app-scrim);
    animation: ax-fade-in 300ms linear backwards;
}
html.odx-app .ax-panel {
    position: absolute; left: 0; right: 0; bottom: 0;
    display: flex; flex-direction: column; height: var(--ax-h-l); max-height: var(--ax-h-l); overflow: hidden;
    padding-bottom: var(--app-sb); border-radius: 13px 13px 0 0;
    background: var(--surface); color: var(--text); overscroll-behavior: contain;
    animation: ax-sheet-in 300ms var(--ease-sheet) backwards;
}
html.odx-app-android .ax-panel { border-radius: 14px 14px 0 0; }
html.odx-app .ax-sheet.is-mid > .ax-panel,
html.odx-app .ax-sheet[data-odx-detent="mid"] > :is(.ax-panel, .ss-panel) { height: var(--ax-h-m); }
html.odx-app .ax-sheet.is-fit > .ax-panel { height: auto; }
@keyframes ax-sheet-in { from { transform: translateY(100%); } }
@keyframes ax-fade-in { from { opacity: 0; } }
/*  [APP-MOTION M03] 면이 올라오는 동안 안쪽이 차례로 선다(6px 오름 + 페이드 220ms, 30ms 간격 — 키프레임 odx-rise는 앱-12).
    시트는 대화형으로만 그려진다(프리렌더 교체와 무관). 선택자는 요소 자신의 클래스 + 안정된 조상만(§4.3 — 상태로 고르지 않는다).
    경기 시트(5덩이)는 앱-8b, 슬립 시트는 앱-9. 동작 줄이기면 없음(면의 120ms 페이드만 — 앱-12). */
html.odx-app .ax-sheet :is(.fs-head, .fs-scroll, .ls-body, .ls-foot),
html.odx-app .modal-veil > .modal > :is(.modal-head, .modal-body) {
    animation: odx-rise var(--t-rise, 220ms) var(--ease-out) backwards;
}
html.odx-app .ax-sheet :is(.fs-head, .ls-body),
html.odx-app .modal-veil > .modal > .modal-head { animation-delay: 40ms; }
html.odx-app .ax-sheet :is(.fs-scroll, .ls-foot),
html.odx-app .modal-veil > .modal > .modal-body { animation-delay: 70ms; }

/*  손잡이 36×5(Android 32×4) — 끌기 시작 자리라 누르는 영역을 위아래·양옆으로 넓힌다. 세로 끌기를 스크롤에 빼앗기지 않게 touch-action: none. */
html.odx-app :is(.ax-panel, .odx-sf-sheet) > .grab {
    position: absolute; top: 6px; left: 50%; z-index: 2; width: 36px; height: 5px; margin-left: -18px;
    border-radius: 3px; background: var(--line-strong); touch-action: none;
}
html.odx-app .ax-panel > .grab::before { content: ""; position: absolute; left: -44px; right: -44px; top: -6px; bottom: -14px; }
html.odx-app-android :is(.ax-panel, .odx-sf-sheet) > .grab { top: 10px; width: 32px; height: 4px; margin-left: -16px; border-radius: 2px; }

/*  낙관적 시트 틀(브리지 소유 — 보드 칸을 놓는 그 프레임에 뜨는 딤 + 빈 시트). 크게 디텐트와 같은 높이 · 면 색 · 반경이라
    경기 시트(.ax-sheet.msheet)가 들어오는 순간 높이 점프가 없다(§9-9). 1200ms 안에 시트가 안 오면 브리지가 걷는다. */
html.odx-app .odx-sheet-frame { position: fixed; inset: 0; z-index: 100; }
html.odx-app .odx-sf-veil { position: absolute; inset: 0; background: var(--app-scrim); }
html.odx-app .odx-sf-sheet {
    position: absolute; left: 0; right: 0; bottom: 0; height: var(--ax-h-l);
    border-radius: 13px 13px 0 0; background: var(--surface);
}
html.odx-app-android .odx-sf-sheet { border-radius: 14px 14px 0 0; }

/*  ② Blazor 모달 → 바닥 시트. 폭 100% · 반경 13 13 0 0 · 최대 = 앱 시트의 크게 디텐트(--ax-h-l) · 위 손잡이(가상 요소). ✕는 OS 모양 닫기 원 32(누르는 영역 44).
    로그인 모달도 같은 모양이다(여닫기는 auth.js 그대로).
    [FIX V-02 2026-10-20] 상한이 92dvh였을 때 면의 위 끝(844pt에서 68pt)이 베젤 제목 글자(58–80pt)를 가로질러 제목 윗부분이 면 위로 삐져나왔다 —
    .ax-panel과 같은 크게 디텐트(상태바 + 10)로 맞춘다(딤의 위 여백과 같은 값이라 면이 제목을 깨끗이 덮는다). */
html.odx-app .modal-veil {
    align-items: end; justify-items: stretch; padding: calc(var(--app-st) + 10px) 0 0;
    background: var(--app-scrim); -webkit-backdrop-filter: none; backdrop-filter: none;
}
/* [INT] 사이트 팝업 딤(SitePopups, 앱에서도 유지)도 블러 없이 — 블러는 iOS 세 곳(상태바 띠 · 베젤 · 슬립 막대)뿐, Android 0(§2.7 · §5.1-10). */
html.odx-app .pop-veil { background: var(--app-scrim); -webkit-backdrop-filter: none; backdrop-filter: none; }
html.odx-app .modal-veil > .modal {
    position: relative; width: 100%; max-width: none; max-height: var(--ax-h-l);   /* --ax-h-l: 앱-1(vh 폴백 + dvh @supports) */
    padding-bottom: var(--app-sb); border: 0; border-radius: 13px 13px 0 0; box-shadow: none;
    animation: ax-sheet-in 300ms var(--ease-sheet) backwards;
}
html.odx-app-android .modal-veil > .modal { border-radius: 14px 14px 0 0; }
html.odx-app .modal-veil > .modal::before {
    content: ""; position: absolute; top: 6px; left: 50%; z-index: 2; width: 36px; height: 5px; margin-left: -18px;
    border-radius: 3px; background: var(--line-strong); pointer-events: none;
}
html.odx-app-android .modal-veil > .modal::before { top: 10px; width: 32px; height: 4px; margin-left: -16px; border-radius: 2px; }
html.odx-app .modal-veil .modal-head { padding: 22px 16px 10px; border-bottom: 0; touch-action: none; }
html.odx-app .modal-veil .modal-head h3 { font-size: calc(17px * var(--fs, 1)); letter-spacing: -.02em; }
html.odx-app .modal-veil .modal-x {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 32px; height: 32px; padding: 0; border-radius: 50%; background: var(--surface-2); color: var(--text-2); font-size: 13px;
}
html.odx-app .modal-veil .modal-head .modal-x { position: relative; }
html.odx-app .modal-veil .login-x { top: 14px; right: 14px; }   /* 로그인 모달의 ✕는 웹처럼 오른쪽 위 고정(절대 위치) */
html.odx-app .modal-veil .modal-x::after { content: ""; position: absolute; inset: -6px; }
html.odx-app .modal-veil .modal-body { padding: 4px 16px 16px; font-size: calc(14px * var(--fs, 1)); }
html.odx-app .modal-veil .modal-foot { padding: 10px 16px; border-top: 0; }

/*  보드 전환 메뉴(§3.12 · 그림 26) — 보드 계열 제목(⌄)을 누르면 제목 줄 바로 아래에 뜨는 272pt 팝오버(반경 12, 불투명 면).
    두 테마 모두 어두운 베젤에 붙은 크롬이라 면도 어둡다(D4 선택안은 앱-13b). 딤은 제목 줄 아래부터 덮는다(제목은 그대로 보인다).
    항목 = 제목 15 + 설명 12, 현재 화면 = 체크. 잠긴 화면은 PRO/PRIME 무채 꼬리표(가격 · 결제 링크 없음). 층 100(모달과 같은 값). */
html.odx-app .ax-menu-veil {
    position: fixed; left: 0; right: 0; bottom: 0; top: calc(var(--app-st) + var(--app-title-h)); z-index: 100;
    background: var(--app-scrim); animation: ax-fade-in 160ms linear backwards;
}
html.odx-app .ax-menu {
    position: fixed; z-index: 100; left: 10px; top: calc(var(--app-st) + var(--app-title-h) + 2px);
    width: 272px; max-width: calc(100% - 20px); overflow: hidden; border-radius: 12px;
    background: #2c3035; box-shadow: inset 0 0 0 var(--hair-w) rgba(255, 255, 255, .07);
    transform-origin: 32px 0; animation: ax-menu-in 180ms var(--ease-out) backwards;
}
@keyframes ax-menu-in { from { opacity: 0; transform: translateY(-6px) scale(.98); } }
/* [FIX RV-WEB-2] 회로가 없는 정적 SSR 보드(/proto)의 전환 메뉴 — SiteLayout이 늘 그려 두고 체크박스(#ax-switch-open, .site 앞 형제)로 연다
   (드로어 #nav-open과 같은 방법). 닫혀 있으면 그리지 않는다(등장 애니메이션은 열 때마다 다시 돈다). 대화형 화면에는 체크박스가 없다. */
html.odx-app .ax-switch-open:not(:checked) ~ :is(.ax-menu-veil, .ax-menu) { display: none; }
html.odx-app .ax-switch-open:checked ~ .site .ax-switch .ax-i { transform: rotate(180deg); }
html.odx-app .ax-mi {
    display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 11px 14px;
    color: #eef1f4; box-shadow: inset 0 calc(-1 * var(--hair-w)) 0 rgba(255, 255, 255, .07);
}
html.odx-app .ax-mi:last-child { box-shadow: none; }
html.odx-app .ax-mi[data-odx-press="on"] { background: rgba(255, 255, 255, .06); }   /* [APP-MOTION M02] 누름 모듈 — 면만, 즉시 */
html.odx-app .ax-mi-ck { display: flex; flex: none; width: 18px; }
html.odx-app .ax-mi-ck .ax-i { width: 16px; height: 16px; }
html.odx-app .ax-mi-tx { flex: 1; min-width: 0; }
html.odx-app .ax-mi-tx > b { display: block; font-size: calc(15px * var(--fs, 1)); font-weight: 500; line-height: 1.3; }
html.odx-app .ax-mi.on .ax-mi-tx > b { font-weight: 650; }
html.odx-app .ax-mi-tx > span { display: block; margin-top: 2px; font-size: calc(12px * var(--fs, 1)); line-height: 1.3; color: #8d969f; }
html.odx-app .ax-lk {
    display: inline-flex; align-items: center; height: 15px; margin-left: 6px; padding: 0 5px; vertical-align: 2px;
    border-radius: 4px; box-shadow: inset 0 0 0 1px #4a535c; color: #a2acb5;
    font-family: var(--mono); font-size: 9.5px; font-weight: 700; letter-spacing: .06em;
}
/* ── /앱-8a ── */

/* ── 앱-8b 시트 · 경기 시트 [B2] ── §3.10(MatchSheet) */
/* 보드 시트 — 경기 시트(.msheet, §3.10) · 필터(.fsheet) · 가치 TOP(.tsheet) · PREMIUM TIP(.psheet) · 잠금(.lsheet, §3.13).
   뼈대(.ax-sheet > .ax-scrim + .ax-panel > .grab · 디텐트 · 등장 애니메이션 · 손잡이)는 앱-8a 공통 그대로 — 여기는 안쪽만.
   경기 시트 · 필터 = 크게(--ax-h-l, 낙관적 틀과 같은 높이 → 높이 점프 0), 가치 TOP · PREMIUM TIP · 잠금 = 꼭 맞게(.is-fit, 크게 상한).
   패널의 바닥 안전영역은 앱-8a가 띄운다(padding-bottom: --app-sb). */

/* 낙관적 틀(.odx-sheet-frame — 브리지 소유, 앱-8a)은 [FIX RV-WEB-3] 칸의 click(캡처 단계 — Blazor 처리기보다 먼저, 클릭 대상은 이미 칸으로 정해진 뒤)에서
   붙는다. 그래서 틀이 누르기를 받아도 그 탭의 click을 빼앗지 않고, 시트가 도착하기 전 딤을 누른 탭이 아래 보드에 닿지도 않는다
   (종전: pointerup에서 붙여 틀을 pointer-events:none으로 뚫어 두었다 — 2026-10-11 리뷰 RV-WEB-3). */

/* 둥근 동작 단추(공유 · 닫기) 32 — 누르는 자리 44. */
html.odx-app .ms-acts { position: absolute; top: 16px; right: 12px; z-index: 2; display: flex; gap: 8px; }
html.odx-app .ms-act {
    position: relative; display: flex; align-items: center; justify-content: center; flex: none;
    width: 32px; height: 32px; margin: 0; padding: 0; border: 0; border-radius: 16px;
    background: var(--surface-2); color: var(--text-2); cursor: pointer;
}
html.odx-app .ms-act::after { content: ""; position: absolute; inset: -6px; }
html.odx-app .ms-act .axb-i-close { width: 15px; height: 15px; }
html.odx-app .ms-act .axb-i-share { width: 17px; height: 17px; }
html.odx-app .ms-act[data-copied]::after { content: none; }
html.odx-app[data-theme="light"] .ms-act { background: var(--surface-3); }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .ms-act { background: var(--surface-3); } }

/* ── 경기 시트 ─────────────────────────────────────────────────────────── */
html.odx-app .ms-scroll { position: relative; isolation: isolate; flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
/* [APP-MOTION M03] 틀(낙관적 · 면 300ms)이 올라오고 그 안이 다섯 덩이로 선다 — 머리 40 · 마켓 칩 70 · 요약 표 100 · 세그먼트 130 · 내용 160ms,
   6px 오름 + 페이드 220ms(키프레임 odx-rise — 앱-12). 접힌 머리(.ms-mini — 스크롤 연동)는 빼고, 덩이는 5개를 넘기지 않는다.
   시트가 도착한 때부터 돈다(틀의 바통 터치 adoptFrame은 면 · 딤만 옮긴다 — 빈 틀이 올라오고 → 내용이 선다). */
html.odx-app .msheet .ms-scroll > :is(.ms-head, .ms-mchips, .ms-sum, .ms-segbar, .ms-body) {
    animation: odx-rise var(--t-rise, 220ms) var(--ease-out) backwards;
}
html.odx-app .msheet .ms-scroll > .ms-head { animation-delay: 40ms; }
html.odx-app .msheet .ms-scroll > .ms-mchips { animation-delay: 70ms; }
html.odx-app .msheet .ms-scroll > .ms-sum { animation-delay: 100ms; }
html.odx-app .msheet .ms-scroll > .ms-segbar { animation-delay: 130ms; }
html.odx-app .msheet .ms-scroll > .ms-body { animation-delay: 160ms; }
html.odx-app .ms-head { position: relative; padding: 20px 16px 0; }
html.odx-app :is(.ms-head, .ms-mini) .ms-m1 {
    display: flex; align-items: center; gap: 6px; min-width: 0; margin-right: 84px; overflow: hidden; white-space: nowrap;
    font-size: calc(11px * var(--fs, 1)); line-height: calc(16px * var(--fs, 1)); color: var(--text-3);
}
/* [FIX DF-12] 넘친 항목은 패딩이 아니라 테두리 상자에서 잘린다 — 공유 · 닫기 원(12 + 32 + 8 + 32 = 84) 자리는 바깥 여백으로 비우고
   (제목 .ms-title의 오른쪽 끝과 같은 선), 마지막 항목(남은 시간 · 마켓)이 말줄임으로 줄어든다. */
html.odx-app :is(.ms-head, .ms-mini) .ms-m1 > :last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
html.odx-app .ms-m1 .sp { display: inline-flex; color: var(--text-3); }
html.odx-app .ms-m1 .sp .sico { width: 12px; height: 12px; }
html.odx-app .ms-m1 .no { font-size: calc(11px * var(--fs, 1)); font-weight: 600; letter-spacing: -.02em; color: var(--text-2); }
html.odx-app .ms-m1 .lg {
    display: inline-flex; align-items: center; gap: 5px; flex: none; min-width: 0; max-width: none; margin: 0; padding: 0;
    border: 0; border-radius: 0; background: none; font-size: inherit; font-weight: 400; letter-spacing: 0; color: var(--text-3);
}
html.odx-app .ms-m1 .lg::before { content: ""; width: 2px; height: 10px; border-radius: 1px; background: hsl(var(--h, 210) 30% 56%); }
html.odx-app .ms-m1 .mono { letter-spacing: -.02em; }
html.odx-app .ms-m1 .cd :is(b, .n) { font-family: var(--mono); font-weight: 500; letter-spacing: -.02em; }
html.odx-app .ms-m1 .cd[data-state="soon"] { color: var(--warn); }
html.odx-app .ms-title {
    margin: 6px 0 0; padding-right: 84px;
    font-family: var(--font); font-size: calc(21px * var(--fs, 1)); line-height: calc(28px * var(--fs, 1)); font-weight: 700; letter-spacing: -.025em; color: var(--text);
    overflow-wrap: anywhere; word-break: keep-all;
}
html.odx-app .ms-title .x { margin: 0 2px; font-weight: 400; color: var(--text-4); }
html.odx-app .ms-title .a { font-weight: 400; color: var(--text-2); }
/* [APP-MOTION V03] 판정 줄 — 문장 13 --text-2, 적정 배당 13/600 --text, 초과율이 주인공: 가치 15/700 mono --dom-soft · 미달 15/650 --text-2.
   줄은 기준선 정렬(꼬리표 높이 18은 그대로 — 꼬리표만 가운데). 새 색 · 면 · 테두리 없음(크기 · 굵기 · 명도로만). */
html.odx-app .ms-verdict { display: flex; align-items: baseline; gap: 8px; margin-top: 8px; font-size: calc(13px * var(--fs, 1)); line-height: 1.35; color: var(--text-2); }
html.odx-app .ms-verdict > .vt { align-self: center; }
html.odx-app .ms-verdict b { font-weight: 600; color: var(--text); letter-spacing: -.02em; }
html.odx-app .ms-verdict b:first-of-type { font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text); }
html.odx-app .ms-verdict b.pos { font-family: var(--mono); font-size: calc(15px * var(--fs, 1)); font-weight: 700; letter-spacing: -.03em; color: var(--dom-soft); }
html.odx-app .ms-verdict b:last-of-type:not(:first-of-type):not(.pos) { font-family: var(--mono); font-size: calc(15px * var(--fs, 1)); font-weight: 650; letter-spacing: -.03em; color: var(--text-2); }
/* 판정 꼬리표 — 보드와 같은 모양(§3.7) */
html.odx-app .msheet .vt {
    display: inline-flex; align-items: center; gap: 2px; flex: none; height: 18px; padding: 0 6px; border-radius: 4px;
    font-family: var(--font); font-size: calc(11px * var(--fs, 1)); font-weight: 700; line-height: 1; letter-spacing: .02em;
}
html.odx-app .msheet .vt i { font-style: normal; font-size: 8px; margin-left: 1px; }
html.odx-app .msheet .vt-v { background: var(--dom); color: #fff; }
html.odx-app .msheet .vt-low { box-shadow: inset 0 0 0 1px var(--dom-sw); color: var(--dom-soft); }
html.odx-app .msheet .vt-m { border: 1px dashed var(--line-strong); color: var(--text-4); font-weight: 600; }
html.odx-app .msheet .vt-x { box-shadow: inset 0 0 0 1px rgba(217, 155, 43, .45); color: var(--warn-soft); }

/* 접힌 머리 — 스크롤 연동 애니메이션이 있는 WebView만(없으면 펼친 머리가 그대로 올라간다). 자리를 차지하지 않는다(음수 아래 여백). */
html.odx-app .ms-mini { display: none; }
@supports (animation-timeline: scroll()) {
    html.odx-app .ms-mini {
        display: block; position: sticky; top: 0; z-index: 2; height: 58px; margin-bottom: -58px; padding: 10px 16px 0;
        background: var(--surface); pointer-events: none; opacity: 0;
        animation: axb-mini linear both; animation-timeline: scroll(nearest); animation-range: 72px 96px;
        animation-range: min(72px, 100%) min(96px, 100%);
    }
    /* [FIX V-03 2026-10-20] 펼친 머리의 글자는 접힌 머리가 들어오기 <b>전에</b> 다 빠진다(24→72px, 접힌 머리 72→96px) — 반투명 접힌 머리 밑으로
       펼친 제목이 비쳐 두 제목이 겹쳐 보였다(스크롤이 72–112px 사이에서 멈추면 늘 그랬다 — 내용이 시트보다 조금 긴 '해외 전체'가 그 경우).
       스크롤 범위가 96px보다 짧으면 두 구간을 그 끝(100%)까지로 줄여, 끝까지 내리면 언제나 접힌 머리 하나만 남는다.
       min()을 못 읽는 엔진은 바로 위 px 선언이 남는다. 머리 자체(.ms-head)의 등장 애니메이션(M03)과 동작 줄이기 규칙은 건드리지 않게 자식에 건다. */
    html.odx-app .msheet .ms-scroll > .ms-head > * {
        animation: axb-head-out linear both; animation-timeline: scroll(nearest); animation-range: 24px 72px;
        animation-range: min(24px, 100%) min(72px, 100%);
    }
    html.odx-app .ms-mini .ms-mt {
        padding-right: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        font-size: calc(17px * var(--fs, 1)); line-height: calc(24px * var(--fs, 1)); font-weight: 700; letter-spacing: -.02em; color: var(--text);
    }
    html.odx-app .ms-mini .ms-mt .x { margin: 0 2px; font-weight: 400; color: var(--text-4); }
    html.odx-app .ms-mini .ms-mt .a { font-weight: 400; color: var(--text-2); }
    html.odx-app .msheet .ms-segbar { top: 58px; }   /* 접힌 머리 아래에 붙는다(아래 기본 규칙보다 특정) */
}
@keyframes axb-mini { to { opacity: 1; } }
@keyframes axb-head-out { to { opacity: 0; } }

/* 같은 경기의 마켓 칩 */
html.odx-app .ms-mchips {
    display: flex; gap: 6px; padding: 14px 16px 2px; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
}
html.odx-app .ms-mchips::-webkit-scrollbar { display: none; }
html.odx-app .ms-mchips .axb-chip { height: 28px; font-size: calc(12px * var(--fs, 1)); }
html.odx-app .ms-mchips .axb-chip .n { font-size: calc(10.5px * var(--fs, 1)); }
html.odx-app .ms-mchips .axb-chip::after { top: -8px; bottom: -8px; }
/* [INT] 가로 스크롤 줄은 세로로도 잘린다 — 아래 여백 2pt로는 칩 히트(위 8 · 아래 8)가 38에서 끊겼다. 여백 8 + 음수 6으로 배치는 그대로. */
html.odx-app .ms-mchips { padding-bottom: 8px; margin-bottom: -6px; }

/* 요약 표 — 열 = 셀렉션, 행 = 국내 · 해외 평균(라인 마켓 '해외 최저') · 주요 4곳 · 차이율[계기 30×12]. 누른 칸의 열 = 면 + 머리 2pt 잉크 밑줄. */
html.odx-app .ms-sum { margin: 12px 16px 0; }
html.odx-app .ms-sum .rw {
    display: grid; grid-template-columns: 70px repeat(3, minmax(0, 1fr)); align-items: stretch;
    height: calc(32px * var(--fs, 1)); box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
}
html.odx-app .ms-sum.n2 .rw { grid-template-columns: 70px repeat(2, minmax(0, 1fr)); }
html.odx-app .ms-sum .rw > * {
    display: flex; align-items: center; justify-content: flex-end; gap: 2px; min-width: 0; margin: 0; padding: 0 8px 0 0;
    border: 0; border-radius: 0; background: none; text-align: right; white-space: nowrap; color: inherit; font: inherit;
}
html.odx-app .ms-sum .rw > :first-child {
    justify-content: flex-start; padding: 0; font-family: var(--font); font-size: calc(12px * var(--fs, 1)); font-weight: 500; color: var(--text-3);
}
html.odx-app .ms-sum .rw > button { cursor: pointer; }
html.odx-app .ms-sum .rw > .selc { background: var(--surface-2); }
html.odx-app .ms-sum .hd { height: calc(28px * var(--fs, 1)); }
html.odx-app .ms-sum .hd > * { font-family: var(--font); font-size: calc(11.5px * var(--fs, 1)); font-weight: 600; color: var(--text-3); }
html.odx-app .ms-sum .hd > .selc { color: var(--text); box-shadow: inset 0 -2px 0 var(--ink, var(--text)); }
html.odx-app .ms-sum .dom { height: calc(42px * var(--fs, 1)); }
html.odx-app .ms-sum .dom > :not(:first-child) {
    font-family: var(--mono); font-size: calc(19px * var(--fs, 1)); font-weight: 600; letter-spacing: -.04em; color: var(--text);
}
html.odx-app .ms-sum .dom > .adv { color: var(--dom-soft); }
html.odx-app .ms-sum .dom > .advf { color: var(--for-soft); }   /* 현행 D1 — 권장(signal)은 앱-13a에서 무채 */
html.odx-app .ms-sum .dom > .na { color: var(--text-4); font-weight: 400; }
html.odx-app .ms-sum .fo > :not(:first-child) {
    font-family: var(--mono); font-size: calc(13.5px * var(--fs, 1)); font-weight: 500; letter-spacing: -.03em; color: var(--text-2);
}
html.odx-app .ms-sum .fo .ar { font-style: normal; font-size: 8px; margin-left: 2px; color: var(--text-4); }
html.odx-app .ms-sum .f4 > :not(:first-child) {
    font-family: var(--mono); font-size: calc(13px * var(--fs, 1)); font-weight: 400; letter-spacing: -.03em; color: var(--text-3);
}
html.odx-app .ms-sum .dif > :not(:first-child) { gap: 5px; }
html.odx-app .ms-sum .dif .diff { font-size: calc(12px * var(--fs, 1)); font-weight: 600; letter-spacing: -.03em; }
html.odx-app .ms-sum .dif .diff.zero { color: var(--text-3); }

/* 차이 계기(§3.9) — 트랙 1px · 가운데 0 눈금 · 막대 4pt(오른쪽 --dom · 왼쪽 --for). 막대는 가운데에서 scaleX(m) — 음수면 왼쪽으로 자란다. */
html.odx-app .mtr { position: relative; display: inline-block; flex: none; width: 30px; height: 12px; }
html.odx-app .mtr::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; margin-top: -.5px; background: var(--line-strong); }
html.odx-app .mtr::after { content: ""; position: absolute; left: 50%; top: 1px; bottom: 1px; width: 1px; margin-left: -.5px; background: var(--text-3); }
html.odx-app .mtr > i {
    position: absolute; left: 50%; top: 4px; width: 50%; height: 4px; border-radius: 1px; background: var(--text-3);
    transform-origin: 0 50%; transform: scaleX(var(--m, 0));
}
html.odx-app .mtr.pos > i { background: var(--dom); }
html.odx-app .mtr.neg > i { background: var(--for); }
/* [APP-MOTION M04] 시트 계기 — 첫 열림에 0에서 그어진다(280ms, 열 순 180 · 210 · 240ms — 요약 표 덩이가 선 뒤). 0에서 세는 숫자는 없다(막대만).
   셀렉션 · 마켓을 바꿔 값이 바뀌면 transform 전이 240ms로 옮겨간다(합성 단계). */
html.odx-app .msheet .ms-sum .mtr > i {
    animation: odx-sweep 280ms var(--ease-out) 180ms backwards;
    transition: transform var(--t-move, 240ms) var(--ease-out);
}
html.odx-app .msheet .ms-sum .dif > :nth-child(3) .mtr > i { animation-delay: 210ms; }
html.odx-app .msheet .ms-sum .dif > :nth-child(4) .mtr > i { animation-delay: 240ms; }

/* 세그먼트 — 높이 32 · 바탕 --surface-2 · 썸 반경 6. 썸 = style="--i"(브리지가 pointerdown에서 먼저 옮긴다) 200ms. 스크롤하면 위에 붙는다. */
html.odx-app .ms-segbar { position: sticky; top: 0; z-index: 1; padding: 16px 16px 4px; background: var(--surface); }
html.odx-app .ms-seg { position: relative; display: flex; height: 32px; padding: 2px; border-radius: 8px; background: var(--surface-2); }
html.odx-app .ms-seg > .seg-thumb {
    position: absolute; top: 2px; bottom: 2px; left: 2px; width: calc((100% - 4px) / 3); border-radius: 6px;
    background: var(--surface-4); transform: translateX(calc(var(--i, 0) * 100%));
    transition: transform 200ms var(--ease-out, cubic-bezier(.215, .61, .355, 1));
}
html.odx-app .ms-seg > button {
    position: relative; z-index: 1; flex: 1 1 0; display: flex; align-items: center; justify-content: center; gap: 4px;
    min-width: 0; margin: 0; padding: 0; border: 0; border-radius: 6px; background: none; cursor: pointer;
    font-family: var(--font); font-size: calc(13px * var(--fs, 1)); font-weight: 600; letter-spacing: -.01em; color: var(--text-2); white-space: nowrap;
}
html.odx-app .ms-seg > button::after { content: ""; position: absolute; left: 0; right: 0; top: -10px; bottom: -6px; }   /* [INT] 28 + 16 = 히트 44(§2.4) */
html.odx-app .ms-seg > button.on { color: var(--text); }
html.odx-app .ms-seg > button .n { font-size: calc(11px * var(--fs, 1)); font-weight: 500; color: var(--text-3); }
html.odx-app[data-theme="light"] .ms-seg { background: var(--surface-3); }
html.odx-app[data-theme="light"] .ms-seg > .seg-thumb { background: #fff; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .08); }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) .ms-seg { background: var(--surface-3); }
    html.odx-app:not([data-theme]) .ms-seg > .seg-thumb { background: #fff; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .08); }
}
/* Android: 선 테두리 캡슐(16) + 선택 칸 체크(썸 없음) */
html.odx-app-android.odx-app .ms-seg { height: 36px; padding: 0; border-radius: 18px; background: none; box-shadow: inset 0 0 0 1px var(--line-strong); }   /* 라이트 면 규칙보다 뒤 · 같은 특정도 */
html.odx-app-android .ms-seg > .seg-thumb { display: none; }
html.odx-app-android .ms-seg > button { border-radius: 0; }
html.odx-app-android .ms-seg > button + button { box-shadow: inset 1px 0 0 var(--line-strong); }
html.odx-app-android .ms-seg > button:first-of-type { border-radius: 18px 0 0 18px; }
html.odx-app-android .ms-seg > button:last-of-type { border-radius: 0 18px 18px 0; }
html.odx-app-android .ms-seg > button.on { background: var(--surface-4); }
html.odx-app-android .ms-seg > button.on::before {
    content: ""; width: 14px; height: 14px; background: currentColor;
    -webkit-mask: url(app-icons/check.svg) center / contain no-repeat; mask: url(app-icons/check.svg) center / contain no-repeat;
}

/* 세그먼트 내용 */
html.odx-app .ms-body { padding: 0 16px 20px; }
html.odx-app .ms-blk { padding-top: 16px; }
html.odx-app .ms-blk .bh { display: flex; align-items: baseline; gap: 8px; }
html.odx-app .ms-blk .bh b { font-size: calc(13.5px * var(--fs, 1)); font-weight: 700; color: var(--text); }
html.odx-app .ms-blk .bh span { font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }

/* 해외 분포(§3.10) — 회색 눈금 1×11(북 하나) · 평균 2×19 + 아래 '평균 x' · 국내 2×30(국내 유리 = 적) + 위 '국내 x' · 오른쪽 최저 – 최고.
   이름 · 기호 · 업체별 색 없음. */
html.odx-app .ms-dist {
    display: grid; grid-template-columns: 30px minmax(0, 1fr) 64px; align-items: center; gap: 10px;
    height: 62px; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
}
html.odx-app .ms-dist .k { font-size: calc(12.5px * var(--fs, 1)); font-weight: 600; color: var(--text-2); }
html.odx-app .ms-dist.on .k { color: var(--text); }
html.odx-app .ms-dist .trk { position: relative; height: 62px; }
html.odx-app .ms-dist .trk::before { content: ""; position: absolute; left: 0; right: 0; top: 34px; height: 1px; background: var(--line); }
html.odx-app .ms-dist .tk { position: absolute; top: 29px; width: 1px; height: 11px; background: var(--text-3); }
html.odx-app .ms-dist .av { position: absolute; top: 25px; display: block; width: 2px; height: 19px; margin-left: -1px; border-radius: 0; background: var(--text); }   /* [FIX DF-02] 커뮤니티 아바타 .av(원형 · grid)를 걷는다 */
html.odx-app .ms-dist .dm { position: absolute; top: 10px; width: 2px; height: 30px; margin-left: -1px; background: var(--text-2); }
html.odx-app .ms-dist .dm.adv { background: var(--dom); }
html.odx-app .ms-dist :is(.av, .dm) em {
    position: absolute; left: 50%; transform: translateX(-50%); font-style: normal; white-space: nowrap; letter-spacing: -.02em;
}
html.odx-app .ms-dist .av em { top: 22px; font-size: calc(10.5px * var(--fs, 1)); font-weight: 500; color: var(--text-2); }
html.odx-app .ms-dist .dm em { top: -1px; left: 6px; transform: none; font-size: calc(11.5px * var(--fs, 1)); font-weight: 600; color: var(--text); }
html.odx-app .ms-dist .dm.adv em { color: var(--dom-soft); }
html.odx-app .ms-dist .av.l em { left: -1px; transform: none; }
html.odx-app .ms-dist .av.r em { left: auto; right: -1px; transform: none; }
html.odx-app .ms-dist .dm.r em { left: auto; right: 6px; }
html.odx-app .ms-dist .rg { text-align: right; font-size: calc(11px * var(--fs, 1)); line-height: 1.5; color: var(--text-3); }
html.odx-app .ms-dfoot { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 44px; margin-top: 2px; }
html.odx-app .ms-dfoot .meta { font-size: calc(11px * var(--fs, 1)); line-height: 1.55; color: var(--text-3); }
html.odx-app .ms-more {
    display: inline-flex; align-items: center; gap: 2px; flex: none; height: 44px; margin: 0; padding: 0; border: 0; background: none; cursor: pointer;
    font-family: var(--font); font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text);
}
html.odx-app .ms-more .axb-i { width: 16px; height: 16px; transition: transform 200ms var(--ease-out); }
/* [APP-MOTION §3.2(b)] 펼치는 것에는 회전 셰브런 — 아이콘은 chevron-down 고정(MatchSheet.razor), 펼치면 180°(aria-expanded). */
html.odx-app .ms-more[aria-expanded="true"] .axb-i { transform: rotate(180deg); }
html.odx-app .ms-open { margin: 8px 0 0; }

/* 바닥 고정: [☆ 50×50] [슬립에 담기 | 패 7.30(잉크)] — 10 + 50 + 안전영역 */
html.odx-app .ms-foot {
    flex: none; position: relative; display: flex; gap: 8px;
    padding: 10px 16px 8px;
    background: var(--surface); box-shadow: inset 0 var(--hair-w, 1px) 0 var(--line-soft);
}
html.odx-app .ms-star {
    display: flex; align-items: center; justify-content: center; flex: none; width: 50px; height: 50px; margin: 0; padding: 0;
    border: 0; border-radius: 8px; background: var(--surface-2); color: var(--text-2); cursor: pointer;
}
html.odx-app .ms-star .axb-i { width: 22px; height: 22px; }
html.odx-app .ms-star.on { color: var(--text); }
html.odx-app[data-theme="light"] .ms-star { background: var(--surface-3); }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .ms-star { background: var(--surface-3); } }
html.odx-app .ms-cta {
    flex: 1 1 auto; display: flex; align-items: center; justify-content: center; gap: 8px; min-width: 0; height: 50px; margin: 0; padding: 0 12px;
    border: 0; border-radius: 8px; background: var(--ink, var(--text)); color: var(--ink-text, var(--surface)); cursor: pointer; text-decoration: none;
    font-family: var(--font); font-size: calc(15.5px * var(--fs, 1)); font-weight: 700; letter-spacing: -.01em; white-space: nowrap;
    transition: transform var(--t-release, 160ms) var(--ease-press), opacity var(--t-release, 160ms) linear;
}
html.odx-app .ms-cta b { font-weight: 700; letter-spacing: -.02em; }
html.odx-app .ms-cta .dv { width: 1px; height: 14px; background: currentColor; opacity: .3; }
/* 누름(APP-MOTION M02 — 단단한 버튼): scale(.98) + 불투명도 .86, 누름 모듈 속성으로(:active는 지웠다). */
html.odx-app .ms-cta:not(:disabled)[data-odx-press="on"] { transform: scale(.98); opacity: .86; transition-duration: var(--t-press, 80ms); }
html.odx-app .ms-cta.is-in { background: none; box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); }
html.odx-app .ms-cta:disabled { opacity: .4; cursor: default; }
html.odx-app .ms-cta .lb { animation: axb-fade 120ms linear; }
@keyframes axb-fade { from { opacity: 0; } }

/* 시트 안의 웹 띠(Embedded) — 내용 · 계산 · 잠금 · 표는 그대로, 겉모양만(§5.3.5) */
html.odx-app .msheet :is(.sostrip, .bkstrip, .vbstrip) { margin: 0; padding: 12px 0 0; border: 0; border-radius: 0; background: none; animation: none; }
html.odx-app .msheet .sostrip-head { margin-top: 18px !important; font-size: calc(12px * var(--fs, 1)); }
html.odx-app .msheet .sostrip-head b { font-size: calc(13.5px * var(--fs, 1)); }
html.odx-app .msheet .so-singles { display: flex; flex-direction: column; gap: 0; margin-top: 0; }
html.odx-app .msheet .so-singles-note { order: -1; margin: 0 0 4px; font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .msheet .so-single {
    display: grid; grid-template-columns: 62px minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 10px; row-gap: 5px; align-items: center;
    min-height: 0; margin: 0; padding: 9px 0; border: 0; border-radius: 0; background: none;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); font-size: calc(12px * var(--fs, 1));
}
html.odx-app .msheet .so-single.on { background: none; border: 0; }
html.odx-app .msheet .so-single:hover { background: none; }
html.odx-app .msheet .so-single-sel { grid-row: 1 / 3; min-width: 0; font-size: calc(12px * var(--fs, 1)); font-weight: 500; color: var(--text-3); }
html.odx-app .msheet .so-single-sel b { margin-left: 3px; font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text); }
html.odx-app .msheet .so-single.on .so-single-sel { color: var(--text); font-weight: 650; }
html.odx-app .msheet .so-single-bar.three { max-width: none; height: 6px; gap: 2px; border-radius: 3px; background: none; }
html.odx-app .msheet .so-single-bar.three i { border-radius: 0; }
html.odx-app .msheet .so-single-dist { display: flex; gap: 10px; min-width: 0; font-size: calc(10.5px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .msheet .so-single-dist b { font-weight: 600; color: var(--text-2); }
html.odx-app .msheet .so-single-dist > :last-child { margin-left: auto; font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .msheet .so-single-none { font-size: calc(11px * var(--fs, 1)); color: var(--text-4); }
html.odx-app .msheet .so-combo { margin: 6px 0 0; padding: 10px 0; border: 0; border-radius: 0; background: none; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); }
html.odx-app .msheet .so-combo.on, html.odx-app .msheet .so-combo:hover { background: none; border: 0; }
html.odx-app .msheet .so-combo-head { font-size: calc(13.5px * var(--fs, 1)); font-weight: 700; }
/* [FIX DF-06] 동일배당 세그먼트(§3.10 · §7 · 그림 s05) — '자리별 적중' 머리, '세 배당 모두 일치 · 역대 전체 · N년~ ……… N경기' 한 줄,
   색 범례 대신 수 + '목록 보기'(목록 표는 접혀 시작). SameOddsStrip · WisetotoStatsView의 Embedded 분기만 이 마크업을 낸다(웹 띠는 그대로). */
html.odx-app .msheet .so-bh { padding-top: 4px; padding-bottom: 2px; }
html.odx-app .msheet .so-combo.is-embedded { margin-top: 8px; padding: 16px 0 4px; cursor: default; }
html.odx-app .msheet .so-combo .bh { display: flex; align-items: baseline; gap: 8px; }
html.odx-app .msheet .so-combo .bh b { font-size: calc(13.5px * var(--fs, 1)); font-weight: 700; color: var(--text); }
html.odx-app .msheet .so-combo .bh span { font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .msheet .so-combo .bh .so-cnt { margin-left: auto; font-family: var(--font); font-size: calc(12px * var(--fs, 1)); font-weight: 400; color: var(--text-2); }
html.odx-app .msheet .so-combo .bh .so-cnt .mono { font-size: inherit; color: inherit; }
html.odx-app .msheet .pb-team .sc { margin: 0 4px; }   /* [FIX V-10 2026-10-20] 목록 줄 스코어가 팀명에 붙었다('뉴욕양키9 : 2보스레드') */
html.odx-app .msheet .so-cfoot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: -6px; }
html.odx-app .msheet .so-cnts { display: flex; gap: 10px; font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .msheet .so-cnts b { font-weight: 600; color: var(--text-2); }
html.odx-app .msheet .sobar { height: 6px; margin: 8px 0 6px; gap: 2px; border-radius: 3px; background: none; }
html.odx-app .msheet .solegend { gap: 10px; font-size: calc(11px * var(--fs, 1)); }
html.odx-app .msheet .so-tabline { margin-top: 14px; font-size: calc(12px * var(--fs, 1)); }
html.odx-app .msheet .sostrip .tbl { font-size: calc(12px * var(--fs, 1)); }
/* [INT] 일시 칸 — 웹 ≤760 규칙(56px · break-all)은 시트에서 '26.10. / 01(목) / 09:00' 세 줄로 쪼갰다(행 132pt). 날짜 · 시각 두 줄로. */
html.odx-app .msheet .sostrip .so-when { width: 88px !important; word-break: keep-all; font-size: calc(11px * var(--fs, 1)); line-height: 1.35; }
/* [INT] 웹 표 머리(.tbl thead th sticky top 0 · z 2)가 시트 스크롤 안에서 붙은 세그먼트 줄(z 1)을 덮었다(430 라이트 실측). 시트 안 표 머리는 흐른다. */
html.odx-app .msheet .tbl thead th { position: static; }
/* [INT] 시트 안 작은 동작의 히트 44(§2.4 · §9-16) — '더 보기' · 배당률 적중 링크(웹 28 · 19pt). */
html.odx-app .msheet .so-more { height: 44px; }
html.odx-app .msheet .so-rate-head a { display: inline-flex; align-items: center; min-height: 44px; }
/* [FINAL] 표 안 링크는 inline-flex면 글자·숫자 조각이 따로 접혀('전체/리그 · 261회 ·') 칸이 깨지고, 웹 ≤760의 .lg-col 숨김까지 덮어
   2열 격자에 3칸이 흘렀다(430 라이트 실측). 줄 흐름은 그대로 두고 위아래 여백으로 44를 채우며, 좁은 폭의 리그 칸 숨김은 웹과 같게. */
html.odx-app .msheet .so-rate-grid a { display: block; min-height: 44px; padding: 12px 0; box-sizing: border-box; }
@media (max-width: 760px) { html.odx-app .msheet .so-rate-grid .lg-col { display: none; } }
html.odx-app .msheet :is(.sostrip, .bkstrip) .tablewrap { max-height: none; margin-top: 8px; border: 0; border-radius: 0; background: none; }
html.odx-app .msheet .fhelp { font-size: calc(11.5px * var(--fs, 1)); }
html.odx-app .msheet .bkstrip.is-embedded { padding-top: 4px; }
/* [FIX DF-01] 100경기 표의 팀 칸 — 웹 ≤760 규칙(white-space: normal · overflow-wrap: anywhere)이 팀명을 낱말 가운데서 두 줄로 쪼갰다. 말줄임 한 줄로. */
html.odx-app .msheet .sostrip td.pb-team { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; overflow-wrap: normal; }
/* [FIX DF-05] 데이터 표면에 액센트 청 금지(§2.1 · §2.2 · §9-5) — 결과 배지 '홈패'(.badge-accent)는 해외 쪽 통로(D3 현행 홈패 = 청),
   전 북 띠의 'n/4 기준'은 무채 꼬리표. Razor는 그대로(웹 표현 불변). */
html.odx-app .msheet .so-res .badge-accent { color: var(--for-soft); border-color: rgba(61, 130, 208, .4); background: var(--for-tint); }
html.odx-app .msheet .bkstrip .badge-accent { color: var(--text-2); border-color: var(--line-strong); background: none; }
html.odx-app .msheet .bkchip { display: inline; padding: 0; border: 0; border-radius: 0; background: none; font-size: calc(12px * var(--fs, 1)); font-weight: 500; color: var(--text-2); }

/* 가치 근거(그림 06) — 문장 → 표 한 줄 → 기준 한 줄 */
html.odx-app .vbstrip.is-embedded { padding-top: 16px; }
html.odx-app .vbstrip.is-embedded .vb-prose p { margin: 0 0 8px; font-size: calc(13.5px * var(--fs, 1)); line-height: 1.68; color: var(--text-2); }
html.odx-app .vbstrip.is-embedded .vb-prose b { font-weight: 600; color: var(--text); }
html.odx-app .vb-kv {
    display: grid; grid-template-columns: 1fr 1fr 1fr 1.35fr; margin-top: 14px;
    box-shadow: inset 0 var(--hair-w, 1px) 0 var(--line-soft), inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
}
html.odx-app .vb-kv > div { min-width: 0; padding: 10px 0 11px; }
html.odx-app .vb-kv > div + div { padding-left: 10px; box-shadow: inset var(--hair-w, 1px) 0 0 var(--line-soft); }
html.odx-app .vb-kv span { display: block; font-size: calc(11px * var(--fs, 1)); font-weight: 500; line-height: 1; color: var(--text-3); }
html.odx-app .vb-kv b {
    display: block; margin-top: 7px; white-space: nowrap;
    font-size: calc(16px * var(--fs, 1)); font-weight: 600; line-height: 1; letter-spacing: -.04em; color: var(--text);
}
html.odx-app .vb-kv b.pos { color: var(--dom-soft); }
html.odx-app .vb-kv b i { font-style: normal; font-size: 9px; margin-left: 2px; }
html.odx-app .vb-crit { margin-top: 10px; font-size: calc(11px * var(--fs, 1)); line-height: 1.55; color: var(--text-3); }

/* 잠금 안내(PlanGate 앱판 — §3.13): 선 자물쇠 + 'N 이용권 기능' → 제목 → 설명 → 번호 목록. 카드 테두리 없이. */
html.odx-app .plock.alock { margin: 0; padding: 16px 0 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
html.odx-app .plock.alock .alock-k {
    display: flex; align-items: center; gap: 6px; font-size: calc(11.5px * var(--fs, 1)); font-weight: 700; line-height: 1; letter-spacing: .02em; color: var(--text-3);
}
html.odx-app .plock.alock .alock-k .axb-i { width: 14px; height: 14px; }
html.odx-app .plock.alock h3 {
    margin: 10px 0 0; font-size: calc(21px * var(--fs, 1)); line-height: calc(28px * var(--fs, 1)); font-weight: 700; letter-spacing: -.025em; color: var(--text);
}
html.odx-app .plock.alock.sm h3 { font-size: calc(17px * var(--fs, 1)); line-height: 1.4; }
html.odx-app .plock.alock .plock-headline { margin-top: 6px; font-size: calc(15px * var(--fs, 1)); }
html.odx-app .plock.alock .plock-lede { margin-top: 6px; font-size: calc(14px * var(--fs, 1)); line-height: 1.68; color: var(--text-2); }
html.odx-app .alock-pts { list-style: none; margin: 14px 0 0; padding: 0; box-shadow: inset 0 var(--hair-w, 1px) 0 var(--line-soft); }
html.odx-app .alock-pts li {
    display: grid; grid-template-columns: 24px minmax(0, 1fr); padding: 10px 0;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
    font-size: calc(13px * var(--fs, 1)); line-height: 1.5; color: var(--text-2);
}
html.odx-app .alock-pts .no { font-size: calc(11px * var(--fs, 1)); line-height: calc(19px * var(--fs, 1)); color: var(--text-4); }
html.odx-app .alock-act { margin-top: 14px; }
html.odx-app .axb-btn-line {
    display: flex; align-items: center; justify-content: center; height: 48px; border-radius: 8px;
    box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); text-decoration: none;
    font-size: calc(15px * var(--fs, 1)); font-weight: 650;
}
html.odx-app .ms-body > .plock.alock { padding-top: 18px; }

/* 잠금 시트(중간 높이, 내용만큼) */
html.odx-app .ls-panel { padding-top: 10px; }
html.odx-app .ls-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 16px 4px; }
html.odx-app .ls-body .plock.alock h3 { padding-right: 48px; }
html.odx-app .ls-worth {
    display: flex; justify-content: space-between; gap: 8px; margin-top: 12px;
    font-size: calc(13px * var(--fs, 1)); font-weight: 500; line-height: 1.4; color: var(--text-2);
}
html.odx-app .ls-worth b { color: var(--text); }
html.odx-app .ls-foot { flex: none; padding: 14px 16px 8px; }
html.odx-app .ls-foot .ms-cta { width: 100%; }

/* ── 필터 · 가치 TOP · PREMIUM TIP 시트(§3.12) ─────────────────────────── */
html.odx-app .bsheet .fs-head {
    flex: none; display: flex; align-items: center; gap: 8px; height: 56px; padding: 18px 12px 0 16px; touch-action: none;
}
html.odx-app .bsheet .fs-head h2 { margin: 0; font-size: calc(18px * var(--fs, 1)); font-weight: 700; line-height: 1; color: var(--text); }
html.odx-app .bsheet .fs-head .sub { flex: 1 1 auto; min-width: 0; font-size: calc(12px * var(--fs, 1)); color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.odx-app .fsheet .fs-head h2 { flex: 1 1 auto; }
html.odx-app .bsheet .fs-head .flag {
    flex: none; display: inline-flex; align-items: center; height: 18px; padding: 0 6px; border-radius: 3px; background: #6d3fd1; color: #fff;
    font-size: 10px; font-weight: 700; letter-spacing: .1em;
}
html.odx-app .fs-reset {
    height: 44px; margin: 0; padding: 0 12px; border: 0; background: none; cursor: pointer;
    font-family: var(--font); font-size: calc(15px * var(--fs, 1)); font-weight: 500; color: var(--text-2);
}
html.odx-app .bsheet .fs-scroll {
    flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    padding: 12px 16px 24px;
}
html.odx-app .fs-search {
    display: flex; align-items: center; gap: 7px; height: 38px; padding: 0 10px; border-radius: 9px; background: var(--surface-2); color: var(--text-3);
}
html.odx-app .fs-search input {
    flex: 1 1 auto; min-width: 0; height: 100%; margin: 0; padding: 0; border: 0; outline: 0; background: none; box-shadow: none; color: var(--text);
}
html.odx-app .fs-search input::-webkit-search-cancel-button { -webkit-appearance: none; }
html.odx-app .fs-h { padding: 18px 0 8px; font-size: calc(12px * var(--fs, 1)); font-weight: 500; line-height: 1; color: var(--text-3); }
html.odx-app .fs-chips { display: flex; flex-wrap: wrap; gap: 14px 6px; }   /* [INT] 줄 간격 14 — 칩 히트 44(§2.4)가 겹치지 않게 */
html.odx-app .fs-chips .axb-chip::after { top: -7px; bottom: -7px; }
html.odx-app .axb-segm { display: flex; height: 32px; padding: 2px; border-radius: 8px; background: var(--surface-2); }
html.odx-app .axb-segm > button {
    flex: 1 1 0; position: relative; margin: 0; padding: 0; border: 0; border-radius: 6px; background: none; cursor: pointer;
    font-family: var(--font); font-size: calc(12.5px * var(--fs, 1)); font-weight: 600; color: var(--text-2); white-space: nowrap;
}
html.odx-app .axb-segm > button::after { content: ""; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px; }
html.odx-app .axb-segm > button.on { background: var(--surface-4); color: var(--text); }
html.odx-app[data-theme="light"] .axb-segm { background: var(--surface-3); }
html.odx-app[data-theme="light"] .axb-segm > button.on { background: #fff; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .08); }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) .axb-segm { background: var(--surface-3); }
    html.odx-app:not([data-theme]) .axb-segm > button.on { background: #fff; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .08); }
}
/* [FIX DF-15] Android(§3.14): 시간 세그먼트 = 선 테두리 캡슐 + 선택 칸 체크(경기 시트 .ms-seg · 앱-10a .segm과 같은 문법, 썸 없음).
   버튼 히트(위아래 6)를 자르지 않게 overflow 대신 양끝 버튼에 반경을 준다. 라이트 면 규칙보다 뒤 · 같거나 높은 특정도. */
html.odx-app-android.odx-app .axb-segm { height: 36px; padding: 0; border-radius: 18px; background: none; box-shadow: inset 0 0 0 1px var(--line-strong); }
html.odx-app-android .axb-segm > button { display: flex; align-items: center; justify-content: center; gap: 4px; min-width: 0; border-radius: 0; }
html.odx-app-android .axb-segm > button:first-of-type { border-radius: 18px 0 0 18px; }
html.odx-app-android .axb-segm > button:last-of-type { border-radius: 0 18px 18px 0; }
html.odx-app-android.odx-app .axb-segm > button.on { background: var(--surface-4); box-shadow: none; }
html.odx-app-android.odx-app .axb-segm > button + button,
html.odx-app-android.odx-app .axb-segm > button + button.on { box-shadow: inset 1px 0 0 var(--line-strong); }
html.odx-app-android .axb-segm > button.on::before {
    content: ""; flex: none; width: 14px; height: 14px; background: currentColor;
    -webkit-mask: url(app-icons/check.svg) center / contain no-repeat; mask: url(app-icons/check.svg) center / contain no-repeat;
}
html.odx-app .fs-opt {
    display: flex; align-items: center; width: 100%; height: 44px; margin: 0; padding: 0; border: 0; background: none; cursor: pointer; text-align: left;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
    font-family: var(--font); font-size: calc(15px * var(--fs, 1)); font-weight: 400; color: var(--text-2);
}
html.odx-app .fs-opt > span { flex: 1 1 auto; }
html.odx-app .fs-opt.on { font-weight: 650; color: var(--text); }
html.odx-app .fs-opt .axb-i { width: 18px; height: 18px; color: var(--text); }
html.odx-app .fs-lg { display: flex; align-items: center; height: 44px; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); }
html.odx-app .fs-lg-pick {
    flex: 1 1 auto; display: flex; align-items: center; gap: 8px; min-width: 0; height: 100%; margin: 0; padding: 0; border: 0; background: none; cursor: pointer; text-align: left;
    font-family: var(--font); font-size: calc(15px * var(--fs, 1)); font-weight: 500; color: var(--text);
}
html.odx-app .fs-lg-pick .tick { flex: none; width: 3px; height: 14px; border-radius: 1px; background: hsl(var(--h, 210) 30% 56%); }
html.odx-app .fs-lg-pick .nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.odx-app .fs-lg-pick .n { font-size: calc(12.5px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .fs-lg.on .fs-lg-pick { font-weight: 700; }
html.odx-app .fs-lg.on .fs-lg-pick .nm::after { content: ""; display: inline-block; width: 14px; height: 14px; margin-left: 6px; vertical-align: -2px; background: currentColor; -webkit-mask: url(app-icons/check.svg) center / contain no-repeat; mask: url(app-icons/check.svg) center / contain no-repeat; }
html.odx-app .fs-star {
    display: flex; align-items: center; justify-content: flex-end; flex: none; width: 44px; height: 44px; margin: 0 -4px 0 0; padding: 0;
    border: 0; background: none; color: var(--text-4); cursor: pointer;
}
html.odx-app .fs-star.on { color: var(--text); }
html.odx-app .fs-sw { margin-top: 10px; }
/* 스위치 — OS 모양 51×31, 켜짐 #3a9b6f(녹 = 확인 계열 · §3.14). 줄 전체가 누르는 자리. */
html.odx-app .axb-switch {
    position: relative; display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 48px;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
    font-size: calc(15px * var(--fs, 1)); color: var(--text); cursor: pointer;
}
html.odx-app .axb-switch > input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
html.odx-app .axb-switch > i { position: relative; flex: none; width: 51px; height: 31px; border-radius: 16px; background: var(--surface-4); transition: background-color 200ms linear; }
html.odx-app .axb-switch > i::after {
    content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 14px; background: #fff;
    transition: transform 200ms var(--ease-out, cubic-bezier(.215, .61, .355, 1));
}
html.odx-app .axb-switch > input:checked + i { background: #3a9b6f; }
html.odx-app .axb-switch > input:checked + i::after { transform: translateX(20px); }
html.odx-app .axb-switch > input:focus-visible + i { outline: 2px solid var(--accent); outline-offset: 2px; }
/* [FIX V-15 2026-10-20] 알림 규칙 시트의 '조용한 시간' 켬/끔(Alerts.razor 앱 분기) — 폼 칸 안이라 줄 밑 헤어라인 없이, 켜면 시각 select 줄이 6 아래에 선다. */
html.odx-app .modal .al-quiet { box-shadow: none; }
html.odx-app .modal .al-quiet + .row:not(:empty) { margin-top: 6px; }
html.odx-app[data-theme="light"] .axb-switch > i { background: #e3e6ea; }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .axb-switch > i { background: #e3e6ea; } }
/* [FIX DF-15] Android = M3 스위치(§3.14): 트랙 52×32 · 꺼짐 2pt 테두리 + 손잡이 16(같은 24 손잡이를 scale .667 — transform만 움직인다) · 켜짐 손잡이 24 흰색. 켜짐 색은 #3a9b6f 그대로. */
html.odx-app-android .axb-switch > i { width: 52px; height: 32px; border-radius: 16px; box-shadow: inset 0 0 0 2px var(--text-4); }
html.odx-app-android .axb-switch > input:checked + i { box-shadow: none; }
html.odx-app-android .axb-switch > i::after { top: 4px; left: 4px; width: 24px; height: 24px; border-radius: 12px; background: var(--text-3); transform: scale(.667); }
html.odx-app-android .axb-switch > input:checked + i::after { background: #fff; transform: translateX(20px); }
html.odx-app .fs-sig { display: flex; flex-wrap: wrap; gap: 8px 18px; }
html.odx-app .fs-sig label { display: inline-flex; align-items: center; gap: 6px; font-size: calc(13px * var(--fs, 1)); color: var(--text-2); }
html.odx-app .fs-sig input {
    width: 68px; height: 36px; margin: 0; padding: 0 8px; border: 0; border-radius: 8px; background: var(--surface-2); color: var(--text); text-align: right;
}

/* 가치 TOP 줄 = 리그 · 킥오프 / 경기 / 마켓 · 셀렉션 · +12.3% ▼ — 누르면 시트가 그 경기 시트로 바뀐다(이동 = 오른쪽 ›, APP-MOTION §3.2(b)). */
html.odx-app .ts-row {
    position: relative; display: block; width: 100%; margin: 0; padding: 12px 22px 12px 0; border: 0; background: none; color: inherit; text-align: left; cursor: pointer;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); font-family: var(--font);
}
html.odx-app .ts-row::after {
    content: ""; position: absolute; right: 0; top: 50%; width: 14px; height: 14px; margin-top: -7px; background: var(--text-4);
    -webkit-mask: url(app-icons/chevron-right.svg) center / 14px 14px no-repeat; mask: url(app-icons/chevron-right.svg) center / 14px 14px no-repeat;
}
html.odx-app .ts-row .m1 { display: flex; align-items: center; gap: 6px; font-size: calc(11px * var(--fs, 1)); line-height: 1; color: var(--text-3); }
html.odx-app .ts-row .m1 .tick { flex: none; width: 2px; height: 10px; border-radius: 1px; background: hsl(var(--h, 210) 30% 56%); }
html.odx-app .ts-row .m1 .gap { flex: 1; }
html.odx-app .ts-row .m1 .mono { letter-spacing: -.02em; color: var(--text-2); }
html.odx-app .ts-row .tm {
    display: block; margin-top: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: calc(15px * var(--fs, 1)); line-height: 1.35; color: var(--text-2);
}
html.odx-app .ts-row .tm .no { margin-right: 4px; font-size: calc(12px * var(--fs, 1)); font-weight: 600; color: var(--text-2); }
html.odx-app .ts-row .tm b { font-weight: 650; color: var(--text); }
html.odx-app .ts-row .tm .x { color: var(--text-4); }
html.odx-app .ts-row .m2 { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: calc(12.5px * var(--fs, 1)); color: var(--text-2); }
html.odx-app .ts-row .m2 .dot { color: var(--text-4); }
html.odx-app .ts-row .m2 b { font-weight: 600; letter-spacing: -.02em; }
html.odx-app .ts-row .m2 b.pos { color: var(--dom-soft); }
html.odx-app .ts-row .m2 .dr { font-style: normal; font-size: 8px; color: var(--text-4); }
html.odx-app .ts-empty { margin: 0; padding: 28px 0; text-align: center; font-size: calc(13px * var(--fs, 1)); color: var(--text-3); }

/* PREMIUM TIP 시트 — TipsPanel(Sheet) 줄: 리그 · 킥오프 / 번호 · 경기 / [예상 보라 이름표] [마켓] [라인] [참고 배당] */
html.odx-app .ps-lede { margin: 0; padding: 0 0 8px; font-size: calc(13px * var(--fs, 1)); line-height: 1.68; color: var(--text-2); }
html.odx-app .tips-sheet { margin: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
html.odx-app .tips-sheet .widget-body { padding: 0; }
html.odx-app .tips-sheet ul { margin: 0; padding: 0; list-style: none; }
html.odx-app .tips-sheet .tipmini { padding: 12px 0; border: 0; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); }
html.odx-app .tips-sheet .tipmini > .row:first-child { gap: 6px; }
html.odx-app .tips-sheet .tipmini .lg {
    display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 70%; padding: 0; border: 0; background: none;
    font-size: calc(11px * var(--fs, 1)); font-weight: 400; letter-spacing: 0; color: var(--text-3);
}
html.odx-app .tips-sheet .tipmini .lg::before { content: ""; flex: none; width: 2px; height: 10px; border-radius: 1px; background: hsl(var(--h, 210) 30% 56%); }
html.odx-app .tips-sheet .tipmini > .row:first-child > .chip {
    height: auto; padding: 0; border: 0; background: none; font-size: calc(11px * var(--fs, 1)); font-weight: 400; color: var(--text-2);
}
html.odx-app .tips-sheet .tipmini .tm { margin-top: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: calc(15px * var(--fs, 1)); line-height: 1.35; color: var(--text-2); }
html.odx-app .tips-sheet .tipmini .tm b { font-weight: 650; color: var(--text); }
html.odx-app .tips-sheet .tipmini .tm .m-no { margin-right: 2px; font-family: var(--mono); font-size: calc(12px * var(--fs, 1)); font-weight: 600; color: var(--text-2); }
html.odx-app .tips-sheet .tipmini .pk { margin-top: 8px; gap: 6px; }
html.odx-app .tips-sheet .tipmini .pk .badge {
    height: 22px; padding: 0 8px; border: 0; border-radius: 4px; background: var(--tippick); color: #fff;
    font-size: calc(12px * var(--fs, 1)); font-weight: 700; letter-spacing: 0;
}
html.odx-app .tips-sheet .tipmini .pk .chip {
    height: 22px; padding: 0 8px; border: 0; border-radius: 6px; background: none; box-shadow: inset 0 0 0 1px var(--line);
    font-size: calc(11.5px * var(--fs, 1)); font-weight: 550; color: var(--text-2);
}
html.odx-app .tips-sheet .tipmini .pk .tp-odds b { margin-left: 3px; font-weight: 600; color: var(--text); }
html.odx-app .tips-sheet .plock.alock { padding-top: 8px; }

/* 시트 안 누름(APP-MOTION M02 — 브리지 누름 모듈 data-odx-press). 원 · 테두리 버튼 = scale(.96), 표 머리 · 목록 줄 = 면 --surface-2 즉시(크기 그대로).
   크기는 동작 줄이기 묶음(앱-12)이 끈다. */
html.odx-app :is(.ms-act, .ms-star, .ms-more) { transition: transform var(--t-release, 160ms) var(--ease-press); }
html.odx-app :is(.ms-act, .ms-star, .ms-more)[data-odx-press="on"] { transform: scale(.96); transition-duration: var(--t-press, 80ms); }
html.odx-app :is(.ts-row, .fs-opt, .fs-lg-pick, .ms-sum .rw > button)[data-odx-press="on"] { background: var(--surface-2); }

/* 동작 줄이기 — 이동 · 확대 없이 120ms 불투명도만 */
@media (prefers-reduced-motion: reduce) {
    html.odx-app .ms-seg > .seg-thumb, html.odx-app .axb-switch > i::after { transition: none; }
    html.odx-app .msheet .ms-scroll > :is(.ms-head, .ms-mchips, .ms-sum, .ms-segbar, .ms-body), html.odx-app .msheet .ms-sum .mtr > i { animation: none; transition: none; }
    html.odx-app .ms-more .axb-i { transition: none; }
}
html.odx-app[data-odx-motion="reduced"] .ms-seg > .seg-thumb { transition: none; }
html.odx-app[data-odx-motion="reduced"] .msheet .ms-scroll > :is(.ms-head, .ms-mchips, .ms-sum, .ms-segbar, .ms-body),
html.odx-app[data-odx-motion="reduced"] .msheet .ms-sum .mtr > i { animation: none; transition: none; }
html.odx-app[data-odx-motion="reduced"] .ms-more .axb-i { transition: none; }
/* 배당 흐름 · 가치 흐름(2026-10-11 의뢰인) — 시트 '해외 전체'의 .ofl.is-embedded(고른 셀렉션 하나)와 '가치 근거'의 .vfl.is-embedded.
   그림 규칙은 §28과 같다(선 1.5 · 면/그림자 없음 · 헤어라인 · 의미색만). 숫자 mono, 글자는 --fs를 따른다, 375pt에서 가로 스크롤 없음(SVG 100%). */
html.odx-app .ofl.is-embedded { margin: 0; padding-bottom: 0; border-bottom: 0; }
html.odx-app .ofl.is-embedded .ofl-chart { margin-top: 10px; }
html.odx-app .ofl.is-embedded .ofl-ends {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-top: 6px;
    font-size: calc(11px * var(--fs, 1)); color: var(--text-3);
}
html.odx-app .ofl.is-embedded .ofl-ends span:last-child { text-align: right; }
html.odx-app .ofl.is-embedded .ofl-ends b { display: block; margin-top: 2px; font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text); }
html.odx-app .ofl.is-embedded .ofl-ends span:last-child b { color: var(--for-soft); }
html.odx-app .ofl.is-embedded .ofl-list { list-style: none; margin: 10px 0 0; padding: 0; }
html.odx-app .ofl.is-embedded .ofl-list li {
    display: grid; grid-template-columns: 1fr auto 14px; align-items: baseline; gap: 8px; min-height: 36px; padding: 8px 0;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); font-size: calc(12.5px * var(--fs, 1));
}
html.odx-app .ofl.is-embedded .ofl-list .t { color: var(--text-3); }
html.odx-app .ofl.is-embedded .ofl-list li.o .t { font-family: var(--font); }
html.odx-app .ofl.is-embedded .ofl-list b { font-weight: 600; color: var(--text); }
html.odx-app .ofl.is-embedded .ofl-list .ar { font-style: normal; font-size: 7.5px; color: var(--text-4); text-align: right; }
html.odx-app .vfl.is-embedded { margin: 14px 0 4px; }
html.odx-app .vfl.is-embedded .bh { display: flex; align-items: baseline; gap: 8px; }
html.odx-app .vfl.is-embedded .bh b { font-size: calc(13.5px * var(--fs, 1)); font-weight: 700; color: var(--text); }
html.odx-app .vfl.is-embedded .bh span { font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .vfl.is-embedded .vfl-chart { max-width: none; margin-top: 10px; }
html.odx-app .vfl.is-embedded .vfl-legend { gap: 6px 12px; font-size: calc(11px * var(--fs, 1)); }
html.odx-app .vfl.is-embedded .vfl-legend .k.edge { margin-left: 0; }
html.odx-app .oflow-pop { display: none !important; }
/* 동일배당 프라임 상세(2026-10-13 웹 세션 — 앱 모양은 앱 세션이 다듬는다): 블록 안 '역대' 줄은 격자 전폭, 배당률 칸·'표 전체 보기'는 버튼이 되어
   종전 a 규칙(히트 44)을 같은 값으로 옮긴다. 띠 안 표(.or-panel)는 Compact(한 자리 네 칸)라 가로 스크롤이 없다. */
html.odx-app .msheet .so-single-all { grid-column: 1 / -1; padding-left: 0; font-size: calc(11px * var(--fs, 1)); }
html.odx-app .msheet .so-rate-head .so-rate-all { display: inline-flex; align-items: center; min-height: 44px; }
html.odx-app .msheet .so-rate-grid .so-rate-cell:not(.lg-col) { display: block; width: 100%; min-height: 44px; padding: 12px 0; box-sizing: border-box; }
html.odx-app .msheet .or-seg button { min-height: 36px; padding: 6px 12px; font-size: calc(12px * var(--fs, 1)); }
html.odx-app .msheet .or-panel .select { min-height: 44px; }
html.odx-app .msheet .or-panel .or-link { display: inline-flex; align-items: center; justify-content: flex-end; min-height: 44px; min-width: 44px; }
html.odx-app .msheet .or-panel .or-panel-x { display: inline-flex; align-items: center; min-height: 44px; }
/* [APP-MOTION M11] 큰 목록 드러남('목록 보기' · '표 전체 보기' · '표로 보기') — 컨테이너 하나가 4px 오름 + 페이드 180ms, 높이 애니메이션 없음
   (키프레임 odx-rise4 — 앱-12). '더 보기'로 붙는 줄은 움직이지 않는다. 위 다른 세션 규칙 뒤에 덧붙인다(그 규칙은 그대로). */
html.odx-app .msheet .sostrip > :is(.so-tabline, .tablewrap),
html.odx-app .msheet .or-panel,
html.odx-app .msheet .ms-blk > .bkstrip { animation: odx-rise4 180ms var(--ease-out) backwards; }
@media (prefers-reduced-motion: reduce) {
    html.odx-app .msheet .sostrip > :is(.so-tabline, .tablewrap), html.odx-app .msheet .or-panel, html.odx-app .msheet .ms-blk > .bkstrip { animation: none; }
}
html.odx-app[data-odx-motion="reduced"] .msheet .sostrip > :is(.so-tabline, .tablewrap),
html.odx-app[data-odx-motion="reduced"] .msheet .or-panel,
html.odx-app[data-odx-motion="reduced"] .msheet .ms-blk > .bkstrip { animation: none; }
/* ── /앱-8b ── */

/* ── 앱-9 슬립 [B4] ── §3.11(슬립 막대 · 슬립 시트) */
/* 이 블록이 그리는 것: 슬립 막대(CalcSlipBar .slipbar) · 슬립 시트(.slipsheet = CalcSlipPanel AppMode .slipp) · 자릿수 굴림(OdoNum .odo) ·
   계산기 목록(Calculator 앱판 .cx — 보드 행 문법 §3.5–3.6을 계산기 칸으로) · 내 조합 목록 줄(MySlips .myslips).
   · 헤어라인 색은 기존 --line-soft(두 테마), 두께는 --hair-w(앱-1, 없으면 1px). 색 토큰은 새로 만들지 않는다(앱 토큰 넷은 앱-1 — 없을 때를 위한 폴백만 적는다).
   · 층: 막대 80(독 자리 — 앱에서 독은 숨는다) · 시트 100(모달 층) · 구획 머리 5(.bigroups 값). 새 z-index 값 없음.
   · 블러는 막대의 ::before 한 곳(iOS만, Android는 불투명 --surface-2). 애니메이션은 transform/opacity만(칸 누름의 면 색만 예외 — 한 칸).
   · 시트 등장 = 삽입 애니메이션(클래스 토글 없음). 닫힘은 Blazor가 지운다(브리지 끌어내림은 .ss-panel에 transform만 쓴 뒤 [data-odx-close] click()).
   · 밀어서 빼기: [data-odx-swipe] > .sw-row에 브리지가 transform을 쓴다(Blazor는 그 요소에 style을 렌더하지 않는다). 뒤의 .sw-act = '빼기'(84pt). */

/* 숫자 런 — 고정폭 · 표 숫자(한글은 넣지 않는다, §2.3) */
html.odx-app :is(.slipbar, .slipsheet, .cx, .myslips) .n { font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.03em; }

/* ── 자릿수 굴림(OdoNum) — 바뀐 자리만 아래에서 올라온다(220ms, 왼→오 24ms 간격). clip-path는 기준선을 바꾸지 않는다(overflow:hidden은 바꾼다). */
html.odx-app .odo { -webkit-clip-path: inset(0 -2px); clip-path: inset(0 -2px); }
html.odx-app .odo > .d { display: inline-block; white-space: pre; }
html.odx-app .odo > .d.is-in { animation: odx-odo-in 220ms var(--ease-out, cubic-bezier(.215, .61, .355, 1)) backwards; animation-delay: calc(var(--i, 0) * 24ms); }
@keyframes odx-odo-in { from { transform: translateY(.95em); } }
/* [APP-MOTION M16] 굴림 방향 = 값의 방향: 내린 값의 새 자리(OdoNum이 생길 때 한 번 정한 .dn)는 위에서 내려온다. */
html.odx-app .odo > .d.is-in.dn { animation-name: odx-odo-in-dn; }
@keyframes odx-odo-in-dn { from { transform: translateY(-.95em); } }
/* [APP-MOTION M17] 슬립 수는 Blazor가 그리는 즉시 굴러가고(손이 먼저), 칩이 닿는 순간 원이 .86→1로 받는다(브리지 WAAPI — 팝 하나가 '담았다').
   굴림을 도착까지 미루던 --odx-land는 지웠다: 옛 자리가 이미 지워진 원이 170–200ms 비어 보였다(2026-10-13 리뷰 DF-2). */

/* ── 슬립 막대 — 탭바 위 8pt, 좌우 8, 높이 56, 반경 12 ── */
html.odx-app .slipbar-space { height: 64px; }   /* 본문 끝 받침: 푸터 고지문이 막대 뒤로 숨지 않게(§5.2.4) */
html.odx-app .slipbar {
    position: fixed; left: 8px; right: 8px; bottom: calc(var(--app-bar) + 8px); z-index: 80;
    height: 56px; border-radius: 12px;
    animation: odx-slipbar-in 320ms cubic-bezier(.32, .72, 0, 1) backwards;
}
html.odx-app .slipbar::before {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
    background: var(--surface-2); box-shadow: inset 0 0 0 var(--hair-w, 1px) var(--line);
}
html.odx-app-ios .slipbar::before {
    background: rgba(40, 45, 50, .82); box-shadow: inset 0 0 0 var(--hair-w, 1px) rgba(255, 255, 255, .075);
    -webkit-backdrop-filter: blur(24px) saturate(170%); backdrop-filter: blur(24px) saturate(170%);
}
html.odx-app-ios[data-theme="light"] .slipbar::before { background: rgba(255, 255, 255, .84); box-shadow: inset 0 0 0 var(--hair-w, 1px) rgba(0, 0, 0, .09); }
@media (prefers-color-scheme: light) {
    html.odx-app-ios:not([data-theme]) .slipbar::before { background: rgba(255, 255, 255, .84); box-shadow: inset 0 0 0 var(--hair-w, 1px) rgba(0, 0, 0, .09); }
}
@keyframes odx-slipbar-in { from { transform: translateY(calc(100% + 16px)); } }
html.odx-app .slipbar-btn {
    display: flex; align-items: center; gap: 11px; width: 100%; height: 100%; margin: 0;
    padding: 0 4px 0 12px; border: 0; border-radius: inherit; background: transparent;
    color: var(--text); font-family: var(--font); text-align: left; cursor: pointer;
    -webkit-user-select: none; user-select: none;
}
html.odx-app .slipbar-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 누름(APP-MOTION M02) — 막대 안쪽 버튼만 .96(막대 ::before 재질은 그대로). */
html.odx-app .slipbar-btn { transition: transform var(--t-release, 160ms) var(--ease-press); }
html.odx-app .slipbar-btn[data-odx-press="on"] { transform: scale(.96); transition-duration: var(--t-press, 80ms); }
html.odx-app .slipbar .acc-count {
    flex: none; display: flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 13px;
    background: var(--ink, var(--text)); color: var(--ink-text, var(--surface));
    font: 700 13px/1 var(--mono);
}
html.odx-app .slipbar .sb-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
html.odx-app .slipbar .sb-l1 {
    font-size: calc(13.5px * var(--fs, 1)); line-height: 1.33; font-weight: 650; letter-spacing: -.01em; color: var(--text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.odx-app .slipbar .sb-l2 {
    margin-top: 1px; font-size: calc(11px * var(--fs, 1)); line-height: 1.36; color: var(--text-3);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.odx-app .slipbar .sb-l2 .n { color: var(--text); font-weight: 500; }
/* [APP-MOTION V04] 둘째 줄의 주인공은 예상 적중금 — 12.5/700 mono --text. 차이율 11/600 의미색(양수 국내 · 음수 해외). 글자는 --text-3. */
html.odx-app .slipbar .sb-l2 .sb-pay { font-size: calc(12.5px * var(--fs, 1)); font-weight: 700; letter-spacing: -.03em; color: var(--text); }
html.odx-app .slipbar .sb-l2 .sb-dif { font-weight: 600; }
html.odx-app .slipbar .sb-l2 .sb-dif.pos { color: var(--dom-soft); }
html.odx-app .slipbar .sb-l2 .sb-dif.neg { color: var(--for-soft); }
html.odx-app .slipbar .sb-ic { flex: none; display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; color: var(--text-2); }

/* ── 슬립 시트(크게) — 딤 + 아래 정렬 면(반경 13, Android 14), 높이 = 화면 − 상태바 − 10 ── */
html.odx-app .slipsheet { position: fixed; inset: 0; z-index: 100; }
html.odx-app .slipsheet .ss-scrim {
    position: absolute; inset: 0; background: var(--app-scrim, rgba(0, 0, 0, .52)); touch-action: none;
    animation: odx-ss-fade 300ms var(--ease-out, cubic-bezier(.215, .61, .355, 1)) backwards;
}
html.odx-app .slipsheet .ss-panel {
    position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column;
    height: var(--ax-h-l, calc(100vh - var(--app-st) - 10px)); border-radius: 13px 13px 0 0; overflow: hidden;
    background: var(--surface); color: var(--text);
    animation: odx-ss-up 300ms var(--ease-sheet, cubic-bezier(.32, .72, 0, 1)) backwards;
}
html.odx-app-android .slipsheet .ss-panel { border-radius: 14px 14px 0 0; }
@keyframes odx-ss-up { from { transform: translateY(100%); } }
@keyframes odx-ss-fade { from { opacity: 0; } }
/* [APP-MOTION M03] 면이 올라오는 동안 머리(40ms) · 본문(70ms)이 6px 올라 선다(odx-rise — 앱-12). */
html.odx-app .slipsheet :is(.ss-head, .ss-body) { animation: odx-rise var(--t-rise, 220ms) var(--ease-out) 40ms backwards; }
html.odx-app .slipsheet .ss-body { animation-delay: 70ms; }
html.odx-app .slipsheet .grab {
    position: absolute; top: 6px; left: 50%; width: 36px; height: 5px; margin-left: -18px; border-radius: 3px;
    background: var(--line-strong);
}
html.odx-app-android .slipsheet .grab { top: 10px; width: 32px; height: 4px; margin-left: -16px; border-radius: 2px; }   /* [FIX DF-15] 다른 Android 시트(앱-8a)와 같은 손잡이 */
html.odx-app .slipsheet .ss-head { flex: none; position: relative; padding: 20px 16px 6px; touch-action: none; }
html.odx-app .slipsheet .ss-head h2 {
    margin: 0; padding-right: 48px; font-size: calc(21px * var(--fs, 1)); line-height: 1.33; font-weight: 700; letter-spacing: -.025em; color: var(--text);
}
html.odx-app .slipsheet .ss-head h2 .n { font-weight: 600; color: var(--text-2); }
html.odx-app .slipsheet .ss-sub { margin-top: 2px; font-size: calc(11px * var(--fs, 1)); line-height: 1.45; color: var(--text-3); }
html.odx-app .slipsheet .ss-x {
    position: absolute; top: 16px; right: 12px; display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; padding: 0; border: 0; border-radius: 16px; background: var(--surface-2); color: var(--text-2); cursor: pointer;
}
html.odx-app .slipsheet .ss-x::after { content: ""; position: absolute; inset: -6px; }   /* 히트 44 */
html.odx-app[data-theme="light"] .slipsheet .ss-x { background: var(--surface-3); }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .slipsheet .ss-x { background: var(--surface-3); } }
html.odx-app .slipsheet .ss-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
/* 본문이 짧아도 바닥 줄(.sp-bar)은 시트 바닥에 — 본문을 시트 높이까지 늘리고 바닥 줄을 margin-top:auto로 민다(길면 sticky로 붙는다). */
html.odx-app .slipsheet .slipp { display: flex; flex-direction: column; min-height: 100%; }

/* 픽 줄 — 번호 원 · 경기 / 리그 · 마켓 · 셀렉션 · 시각 · 오른쪽 국내 / 해외. 왼쪽으로 밀면 '빼기'(무채, 84pt) */
html.odx-app .slipp .sp-pick { position: relative; overflow: hidden; }
html.odx-app .slipp .sp-pick::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: var(--hair-w, 1px); background: var(--line-soft); pointer-events: none; }
html.odx-app .slipp .sw-act {
    position: absolute; top: 0; right: 0; bottom: 0; width: 84px; margin: 0; padding: 0; border: 0;
    background: var(--surface-4); color: var(--text); font-size: calc(13px * var(--fs, 1)); font-weight: 650; font-family: var(--font); cursor: pointer;
}
html.odx-app .slipp .sw-row {
    position: relative; z-index: 1; display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 10px; align-items: center;
    min-height: 44px; padding: 10px 16px; background: var(--surface); touch-action: pan-y;
}
html.odx-app .slipp .sp-pick:focus-within .sw-row { transform: translateX(-84px); }   /* 키보드 · 보조기기로 '빼기'에 닿으면 드러낸다 */
html.odx-app .slipp .sw-no {
    display: flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 10px;
    box-shadow: inset 0 0 0 1px var(--line-strong); font-size: 11px; color: var(--text-2);
}
html.odx-app .slipp .sw-m { min-width: 0; }
html.odx-app .slipp .sw-t { font-size: calc(14px * var(--fs, 1)); line-height: 1.3; font-weight: 650; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; word-break: keep-all; }
html.odx-app .slipp .sw-t .x { margin: 0 .3em; font-weight: 400; color: var(--text-4); }
html.odx-app .slipp .sw-t .a { font-weight: 400; color: var(--text-2); }
html.odx-app .slipp .sw-s { margin-top: 2px; font-size: calc(11px * var(--fs, 1)); line-height: 1.45; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.odx-app .slipp .sw-s .dt { margin: 0; }
html.odx-app .slipp .sw-s b { font-weight: 700; color: var(--text); }
html.odx-app :is(.slipp .sw-s, .cx-m) .lgn::before {
    content: ""; display: inline-block; width: 2px; height: 10px; margin-right: 5px; border-radius: 1px; vertical-align: -1px;
    background: hsl(var(--h, 210) 30% 56%);
}
html.odx-app .slipp .sw-o { text-align: right; }
html.odx-app .slipp .sw-o .dn { display: block; font-size: calc(17px * var(--fs, 1)); line-height: 1; font-weight: 600; letter-spacing: -.04em; color: var(--text); }
html.odx-app .slipp .sw-o .fo { display: block; margin-top: 4px; font-size: calc(11px * var(--fs, 1)); line-height: 1.2; color: var(--text-3); }
html.odx-app .slipp .sp-tag {
    display: inline-block; margin-left: 6px; padding: 0 5px; border-radius: 3px; vertical-align: 1px;
    box-shadow: inset 0 0 0 1px rgba(217, 155, 43, .45); color: var(--warn-soft); font-size: 10.5px; line-height: 16px; font-weight: 700;
}

/* 구매 금액 — 라벨 / 입력 48(22pt 고정폭, 16px 이상) / +1천 +1만 +10만 지우기 */
html.odx-app .slipp .sp-stake { padding: 14px 16px 0; }
html.odx-app .slipp .sp-sh { display: flex; justify-content: space-between; align-items: baseline; }
html.odx-app .slipp .sp-sh label { margin: 0; font-size: calc(13px * var(--fs, 1)); font-weight: 650; color: var(--text); }
html.odx-app .slipp .sp-sh .u { font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .slipp .sp-in { position: relative; margin-top: 8px; }
/* 앞 절의 '입력 16px' 규칙(:not() 다섯 겹)보다 구체적이어야 22pt가 선다 — 속성 선택자를 겹친다. */
html.odx-app .slipp .sp-in input[type="text"][inputmode="numeric"][autocomplete] {
    display: block; width: 100%; height: 48px; margin: 0; padding: 0 38px 0 14px; border: 0; border-radius: 9px;
    background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); color: var(--text); text-align: right;
    font: 600 calc(22px * var(--fs, 1))/1 var(--mono); letter-spacing: -.04em; -webkit-appearance: none; appearance: none;
}
html.odx-app .slipp .sp-in input[type="text"][inputmode="numeric"][autocomplete]:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--accent); }
html.odx-app .slipp .sp-in .won { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); font-size: 15px; color: var(--text-3); pointer-events: none; }
html.odx-app .slipp .sp-q { display: flex; gap: 6px; margin-top: 8px; }
html.odx-app .slipp .sp-q button {
    position: relative; flex: 1; height: 32px; margin: 0; padding: 0 10px; border: 0; border-radius: 6px; background: transparent;
    box-shadow: inset 0 0 0 1px var(--line); color: var(--text-2); font: 550 calc(12.5px * var(--fs, 1))/1 var(--font); cursor: pointer;
}
html.odx-app .slipp .sp-q button::after { content: ""; position: absolute; inset: -6px 0; }   /* 히트 44 */
html.odx-app .slipp .sp-q .clr { flex: none; }

/* 합계 표 — 34 높이 줄, 숫자 고정폭 · 예상 적중금 34pt */
html.odx-app .slipp .sp-sum { margin: 14px 16px 0; box-shadow: inset 0 var(--hair-w, 1px) 0 var(--line-soft); }
html.odx-app .slipp .sp-sum .ln {
    display: flex; justify-content: space-between; align-items: center; gap: 8px; min-height: 34px;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); font-size: calc(13px * var(--fs, 1)); color: var(--text-2);
}
html.odx-app .slipp .sp-sum .ln b { font-size: calc(13.5px * var(--fs, 1)); font-weight: 600; color: var(--text); white-space: nowrap; }
html.odx-app .slipp .sp-sum .ln b.pos { color: var(--dom-soft); }
html.odx-app .slipp .sp-sum .ln b.neg { color: var(--for-soft); }
html.odx-app .slipp .sp-sum .ln b.na { color: var(--text-4); font-weight: 400; }
html.odx-app .slipp .sp-sum .dv { display: flex; align-items: center; gap: 8px; }
html.odx-app .slipp .sp-sum .tot { display: flex; justify-content: space-between; align-items: flex-end; gap: 8px; padding-top: 14px; }
html.odx-app .slipp .sp-sum .tot > span:first-child { padding-bottom: 6px; font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text-2); }
html.odx-app .slipp .sp-sum .tot .pay { white-space: nowrap; }
html.odx-app .slipp .sp-sum .tot .pay .odo { font: 600 calc(34px * var(--fs, 1))/1 var(--mono); letter-spacing: -.05em; color: var(--text); font-variant-numeric: tabular-nums; }
html.odx-app .slipp .sp-sum .tot .won { margin-left: 3px; font-size: 15px; color: var(--text-2); }
html.odx-app .slipp .sp-sum-sm { margin: 8px 0 0; }
/* 차이 계기(표 안 44×12 — 트랙 1px · 0 눈금 · 막대 4pt, 오른쪽 국내 · 왼쪽 해외, √ 눈금은 서버 값 --m) */
html.odx-app .slipp .mtr { position: relative; display: inline-block; flex: none; width: 44px; height: 12px; }
html.odx-app .slipp .mtr::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--line-strong); }
html.odx-app .slipp .mtr::after { content: ""; position: absolute; left: 50%; top: 1px; bottom: 1px; width: 1px; margin-left: -.5px; background: var(--text-3); }
html.odx-app .slipp .mtr .b { position: absolute; top: 4px; left: 50%; width: 50%; height: 4px; border-radius: 1px; background: var(--dom); transform-origin: 0 50%; transform: scaleX(var(--m, 0)); }
html.odx-app .slipp .mtr .b.ng { left: auto; right: 50%; background: var(--for); transform-origin: 100% 50%; }
/* [APP-MOTION M04] 슬립 시트 계기 — 시트가 열릴 때 0에서 그어지고(280ms, 본문 덩이 뒤 200ms), 값이 바뀌면 transform 전이 240ms. */
html.odx-app .slipsheet .slipp .mtr .b {
    animation: odx-sweep 280ms var(--ease-out) 200ms backwards;
    transition: transform var(--t-move, 240ms) var(--ease-out);
}

/* 규칙 안내 — 상자 없이 한 줄씩(상태 설명이 아니라 구매 규칙) */
html.odx-app .slipp .sp-notes { padding: 6px 16px 0; }
html.odx-app .slipp .sp-note { margin-top: 6px; font-size: calc(12px * var(--fs, 1)); line-height: 1.55; color: var(--text-3); }
html.odx-app .slipp .sp-note b { font-weight: 600; color: var(--text-2); }
html.odx-app .slipp .sp-note.is-warn, html.odx-app .slipp .sp-note.is-warn b { color: var(--warn-soft); }
html.odx-app .slipp .sp-note a { color: var(--accent); }
html.odx-app .slipp .sp-save { margin: 10px 16px 0; }
html.odx-app .slipp .sp-login { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
html.odx-app .slipp .sp-login-act { display: flex; flex: none; gap: 6px; }
html.odx-app .slipp .sp-login-act .btn {
    position: relative; height: 32px; padding: 0 12px; border: 0; border-radius: 6px; background: transparent;
    box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); font-size: calc(12.5px * var(--fs, 1)); font-weight: 600;
}
html.odx-app .slipp .sp-login-act .btn::after { content: ""; position: absolute; inset: -6px 0; }   /* [FIX DF-04] 히트 44(.sp-q와 같은 방법) */
html.odx-app .slipp .sp-hint { margin: 0; padding: 16px; font-size: calc(12.5px * var(--fs, 1)); line-height: 1.55; color: var(--text-3); }
html.odx-app .slipp .sp-sec .sp-hint { padding: 8px 0 0; font-size: calc(11.5px * var(--fs, 1)); }

/* 보조 동작(조합기 · 슬립 비우기 · 내 조합) — 글자 버튼, 터치 44 */
html.odx-app .slipp .sp-more { display: flex; align-items: center; gap: 2px; padding: 6px 6px 16px; }
html.odx-app .slipp :is(.sp-more button, .sp-more a, .sp-tx) {
    display: inline-flex; align-items: center; height: 44px; margin: 0; padding: 0 10px; border: 0; background: transparent;
    color: var(--text-2); font: 600 calc(13px * var(--fs, 1))/1 var(--font); text-decoration: none; cursor: pointer;
}
html.odx-app .slipp .sp-more .on { color: var(--text); }
html.odx-app .slipp .sp-more .q { padding: 0 6px 0 10px; font-size: calc(13px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .slipp :is(.sp-more button, .sp-tx, .sp-ln, .sp-ink):disabled { opacity: .4; cursor: default; }

/* 조합기 · 담아둔 조합 — 헤어라인으로 나눈 구획 */
html.odx-app .slipp .sp-sec { margin: 14px 16px 0; padding-top: 6px; box-shadow: inset 0 var(--hair-w, 1px) 0 var(--line-soft); }
html.odx-app .slipp .sp-sec-h { display: flex; justify-content: space-between; align-items: center; gap: 8px; min-height: 40px; font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text); }
html.odx-app .slipp .sp-sec-h .sp-tx { margin-right: -10px; }
html.odx-app .slipp .sp-k { display: flex; flex-wrap: wrap; gap: 12px 4px; }   /* [FIX DF-04] 줄 간격 12 — 히트(위아래 6)가 다음 줄과 겹치지 않게 */
html.odx-app .slipp .sp-k button {
    position: relative; min-width: 36px; height: 32px; margin: 0; padding: 0 8px; border: 0; border-radius: 6px; background: transparent;
    box-shadow: inset 0 0 0 1px var(--line); color: var(--text-2); font-size: 12.5px; font-weight: 600; cursor: pointer;
}
html.odx-app .slipp .sp-k button::after { content: ""; position: absolute; inset: -6px 0; }   /* [FIX DF-04] 32 + 12 = 히트 44 */
html.odx-app .slipp .sp-k button.on { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); }
html.odx-app .slipp .sp-combo { display: flex; align-items: center; gap: 4px; min-height: 44px; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); }
html.odx-app .slipp .sp-combo .cm {
    flex: 1; min-width: 0; display: grid; grid-template-columns: 18px minmax(0, 1fr) auto auto; gap: 8px; align-items: center;
    font-size: calc(12.5px * var(--fs, 1)); color: var(--text-2);
}
html.odx-app .slipp .sp-combo .cno { color: var(--text-4); font-size: 11px; }
html.odx-app .slipp .sp-combo .legs { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.odx-app .slipp .sp-combo .co { color: var(--text); }
html.odx-app .slipp .sp-combo .cp { color: var(--text); font-weight: 600; }
html.odx-app .slipp .sp-combo .sp-tx { margin-right: -10px; }
html.odx-app .slipp .sp-held { display: flex; align-items: center; gap: 6px; padding: 8px 0; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); }
html.odx-app .slipp .sp-held .hm { flex: 1; min-width: 0; }
html.odx-app .slipp .sp-held .t { font-size: calc(13px * var(--fs, 1)); line-height: 1.4; font-weight: 600; color: var(--text); }
html.odx-app .slipp .sp-held .s { font-size: calc(11.5px * var(--fs, 1)); line-height: 1.45; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.odx-app .slipp .sp-held .ha { display: flex; flex: none; margin-right: -10px; }
html.odx-app .slipp .sp-held .ha .sp-tx { padding: 0 8px; }
html.odx-app .slipp .sp-sec-f { padding: 10px 0 2px; }

/* 시트 바닥(고정) — [조합 담기(선)] [가상영수증 · 저장(잉크)] + 합법 이용 안내. 스크롤 영역 끝에 붙는다(sticky). */
html.odx-app .slipp .sp-bar {
    position: sticky; bottom: 0; display: flex; flex-direction: column; gap: 10px; margin-top: auto;
    padding: 10px 16px max(16px, calc(var(--app-sb) + 6px)); background: var(--surface);
    box-shadow: inset 0 var(--hair-w, 1px) 0 var(--line-soft);
}
html.odx-app .slipp .sp-btns { display: flex; gap: 8px; }
html.odx-app .slipp .sp-ln {
    flex: none; height: 50px; margin: 0; padding: 0 18px; border: 0; border-radius: 8px; background: transparent;
    box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); font: 650 calc(15px * var(--fs, 1))/1 var(--font); cursor: pointer;
}
html.odx-app .slipp .sp-ln-sm { width: 100%; height: 44px; }
html.odx-app .slipp .sp-ink {
    flex: 1; height: 50px; margin: 0; padding: 0 12px; border: 0; border-radius: 8px;
    background: var(--ink, var(--text)); color: var(--ink-text, var(--surface));
    font: 700 calc(15.5px * var(--fs, 1))/1 var(--font); letter-spacing: -.01em; cursor: pointer;
}
/* 누름(APP-MOTION M02 — 누름 모듈 data-odx-press): 잉크 = scale(.98) + 불투명도 .86, 테두리 버튼 = scale(.96). */
html.odx-app .slipp :is(.sp-ln, .sp-ink, .sp-q button) { transition: transform var(--t-release, 160ms) var(--ease-press), opacity var(--t-release, 160ms) linear; }
html.odx-app .slipp .sp-ink:not(:disabled)[data-odx-press="on"] { transform: scale(.98); opacity: .86; transition-duration: var(--t-press, 80ms); }
html.odx-app .slipp :is(.sp-ln, .sp-q button):not(:disabled)[data-odx-press="on"] { transform: scale(.96); transition-duration: var(--t-press, 80ms); }
html.odx-app .slipp .legal-use.sp-legal { margin: 0; font-size: calc(11px * var(--fs, 1)); line-height: 1.5; color: var(--text-3); }
html.odx-app .slipp .legal-use.sp-legal b { color: var(--text-2); }
/* 가상영수증 미리보기(시트 위 모달 — 앱-8a가 바닥 시트로 바꾼다)의 저장 = 데이터 표면 주 버튼 → 잉크(§2.1). 영수증 자체는 그대로(§5.3.13). */
html.odx-app .slipsheet .rc-modal .modal-foot .btn-primary { border-color: transparent; background: var(--ink, var(--text)); color: var(--ink-text, var(--surface)); }

/* ── 계산기 목록(앱판) — 보드 행 문법: 메타 16 / 팀 22 / 칸 44 × 3, 행 106 ── */
html.odx-app .cx { padding-bottom: 8px; }
html.odx-app .cx-search {
    display: flex; align-items: center; gap: 7px; height: 36px; margin: 8px 16px; padding: 0 10px; border-radius: 9px;
    background: var(--surface-2); color: var(--text-3);
}
html.odx-app .cx-search:focus-within { box-shadow: inset 0 0 0 1px var(--accent); }
html.odx-app .cx-search .ic { flex: none; }
html.odx-app .cx-search input[type="search"] {
    flex: 1; min-width: 0; height: 36px; margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none;
    color: var(--text); font-family: var(--font); outline: none; -webkit-appearance: none; appearance: none;
}
html.odx-app .cx-search input[type="search"]::placeholder { font-size: 15px; color: var(--text-3); }
html.odx-app .cx-empty { margin: 0; padding: 28px 16px; font-size: calc(13px * var(--fs, 1)); color: var(--text-3); text-align: center; }
html.odx-app .cx-list { background: var(--bg); }
html.odx-app[data-theme="light"] .cx-list { background: var(--surface); }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .cx-list { background: var(--surface); } }
/* 킥오프가 지나면 그 구획(머리 + 행)이 통째로 빠진다 — 요소 자신 기준의 짧은 :has(§5.1-7). 미지원 기기는 다음 렌더(수집 주기)에 빠진다. */
html.odx-app .cx-grp:has(> .cx-time [data-state="started"]) { display: none; }
html.odx-app .cx-time {
    position: sticky; top: var(--stick); z-index: 5; display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 16px;
    background: var(--surface); box-shadow: inset 0 var(--hair-w, 1px) 0 var(--line-soft), inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
    font-size: calc(12px * var(--fs, 1)); font-weight: 600; color: var(--text); white-space: nowrap;
}
html.odx-app[data-theme="light"] .cx-time { background: var(--surface-2); }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .cx-time { background: var(--surface-2); } }
html.odx-app .cx-time .d { font-weight: 500; color: var(--text-3); }
html.odx-app .cx-time .d .n { color: var(--text-2); }
html.odx-app .cx-time .cd { margin-left: auto; font-size: calc(11.5px * var(--fs, 1)); font-weight: 500; color: var(--text-2); font-variant-numeric: tabular-nums; }
html.odx-app .cx-time .cd b { font-weight: 600; color: var(--text); }
html.odx-app .cx-time .cd[data-state="soon"], html.odx-app .cx-time .cd[data-state="soon"] b { color: var(--warn); }
html.odx-app .cx-row {
    position: relative; padding: 8px 16px; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
    content-visibility: auto; contain-intrinsic-size: auto 106px;
}
html.odx-app .cx-m {
    display: flex; align-items: center; gap: 6px; height: 16px; font-size: calc(11px * var(--fs, 1)); line-height: 16px; color: var(--text-3);
    white-space: nowrap; overflow: hidden;
}
html.odx-app .cx-m .spi { display: inline-flex; color: var(--text-3); }
html.odx-app .cx-m .spi .sico { width: 12px; height: 12px; vertical-align: 0; }
html.odx-app .cx-m .no { font-size: 11px; font-weight: 600; line-height: 1; color: var(--text-2); letter-spacing: -.02em; }
html.odx-app .cx-m .lgn { min-width: 0; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; }
html.odx-app .cx-m :is(.ln, .cx-chip) {
    flex: none; padding: 2px 4px; border-radius: 3px; box-shadow: inset 0 0 0 1px var(--line); color: var(--text-2);
    font-size: 11px; font-weight: 600; line-height: 1; letter-spacing: -.02em;   /* [FIX V-13] 10.5 → 11(§2.3 하한) */
}
html.odx-app .cx-m .cx-chip { font-weight: 500; letter-spacing: 0; color: var(--text-3); }
html.odx-app .cx-tm {
    display: flex; align-items: baseline; gap: 5px; height: 22px; margin-top: 2px; min-width: 0;
    font-size: calc(15.5px * var(--fs, 1)); line-height: 22px; white-space: nowrap; word-break: keep-all;
}
html.odx-app .cx-tm .h { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: 650; color: var(--text); letter-spacing: -.02em; }
html.odx-app .cx-tm .x { flex: none; font-weight: 400; color: var(--text-4); }
html.odx-app .cx-tm .a { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: 400; color: var(--text-2); letter-spacing: -.02em; }
html.odx-app .cx-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 6px; min-height: calc(44px * var(--fs, 1)); }
html.odx-app .cx-row.n2 .cx-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* 칸 — [이름 | 국내] / [해외 평균▲▼ | 차이율]. 누르면 담긴다(담김 = 이름 옆 잉크 체크, 링 · 채움 없음). */
html.odx-app .cx-o {
    position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: 22px 14px; row-gap: 2px; align-items: center;
    min-width: 0; min-height: calc(44px * var(--fs, 1)); margin: 0; padding: 3px 8px; border: 0; border-radius: 6px; background: transparent;
    color: var(--text); font-family: var(--font); text-align: left; cursor: pointer; -webkit-user-select: none; user-select: none;
    transition: transform var(--t-release, 160ms) var(--ease-press, cubic-bezier(.2, .9, .3, 1));
}
html.odx-app .cx-o + .cx-o::before { content: ""; position: absolute; left: 0; top: 9px; bottom: 9px; width: var(--hair-w, 1px); background: var(--line-soft); }
html.odx-app .cx-o:is(.adv-dom, .adv-for) + .cx-o::before, html.odx-app .cx-o + .cx-o:is(.adv-dom, .adv-for)::before { content: none; }
html.odx-app .cx-o .o-sel {
    grid-area: 1 / 1; justify-self: start; display: inline-flex; align-items: center; gap: 3px;
    font-size: calc(11px * var(--fs, 1)); font-weight: 500; line-height: 1; color: var(--text-3);
}
html.odx-app .cx-o .o-now { grid-area: 1 / 2; justify-self: end; font-size: calc(17.5px * var(--fs, 1)); font-weight: 600; line-height: 1; letter-spacing: -.04em; color: var(--text); }
html.odx-app .cx-o .o-for {
    grid-area: 2 / 1; justify-self: start; display: inline-flex; align-items: center; gap: 1px;
    font-size: calc(11px * var(--fs, 1)); font-weight: 400; line-height: 1; color: var(--dom);   /* D1 현행(기본값): 해외 평균 적색 11 · 400 */
}
html.odx-app .cx-o .o-for .arr { margin-left: 1px; font-style: normal; font-size: 7.5px; color: var(--text-4); }
html.odx-app .cx-o .o-for.na { color: var(--text-4); }
html.odx-app .cx-o .o-dif { grid-area: 2 / 2; justify-self: end; font-size: calc(11px * var(--fs, 1)); font-weight: 600; line-height: 1; letter-spacing: -.03em; }
html.odx-app .cx-o .o-dif.pos { color: var(--dom-soft); }
html.odx-app .cx-o .o-dif.neg { color: var(--for-soft); }
html.odx-app .cx-o .o-dif.zero { color: var(--text-3); }
html.odx-app .cx-o .o-dif.na { color: var(--text-4); font-weight: 400; }
html.odx-app .cx-o.adv-dom { overflow: hidden; background: var(--dom-tint); }
html.odx-app .cx-o.adv-dom .o-now { color: var(--dom-soft); }
html.odx-app .cx-o.adv-dom::after {
    content: ""; position: absolute; left: 0; bottom: 0; width: 100%; height: 2px; background: var(--dom);
    transform-origin: 0 50%; transform: scaleX(var(--m, 0));
    transition: transform var(--t-move, 240ms) var(--ease-out, cubic-bezier(.215, .61, .355, 1));   /* [APP-MOTION M14 · PF-3] 계기 이동 = transform 전이(합성) */
}
html.odx-app .cx-o.adv-for { background: var(--for-tint); }   /* D1 현행(기본값): 해외 유리 칸 청 틴트 + 청 숫자 */
html.odx-app .cx-o.adv-for .o-now { color: var(--for-soft); }
html.odx-app .cx-o.in-slip .o-sel { font-weight: 700; color: var(--text); }
html.odx-app .cx-o .ck { flex: none; width: 11px; height: 11px; color: var(--ink, var(--text)); }   /* [APP-MOTION V07] 담김 체크 11pt(보드 칸과 같다) */
html.odx-app .cx-o.nf { grid-template-rows: minmax(0, 1fr); }   /* 해외 비교가 잠긴 세션(비로그인): 아래 줄이 없으니 이름 · 국내를 가운데에 */
html.odx-app .cx-o.is-na { cursor: default; }
html.odx-app .cx-o.is-na .o-now { font-weight: 400; color: var(--text-4); }
/* 누름(APP-MOTION M01 — 누름 모듈): 계산기 칸의 ::before는 칸 사이 선, ::after는 계기라 틴트 층이 없다 — 면을 즉시 바꾼다(전이 없음) + 같은 크기 움직임. */
html.odx-app button.cx-o[data-odx-press="on"] { background-color: var(--surface-2); transform: scale(.97); transition-duration: var(--t-press, 80ms); }
html.odx-app button.cx-o:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* 큰 글자(--fs ≥ 1.2): 칸은 이름 · 국내 · 차이율만(해외 평균은 접근성 라벨에 남는다, §2.3) */
html.odx-app[data-odx-fs="l"] .cx-o { grid-template-rows: auto auto; }
html.odx-app[data-odx-fs="l"] .cx-o .o-for { display: none; }
html.odx-app[data-odx-fs="l"] .cx-o .o-dif { grid-area: 2 / 1 / 3 / 3; }
html.odx-app[data-odx-fs="l"] .cx-m { height: auto; }
html.odx-app[data-odx-fs="l"] .cx-tm { height: auto; line-height: 1.4; }
/* D1 권장(odx-d1-signal) — 국내 숫자 무채 · 해외 평균 회색 · 적색은 국내 유리 칸과 양수 차이율에만(앱-13a와 같은 결정의 계산기 칸 몫) */
html.odx-app.odx-d1-signal .cx-o .o-for { color: var(--text-3); }
html.odx-app.odx-d1-signal .cx-o.adv-for { background: transparent; }
html.odx-app.odx-d1-signal .cx-o.adv-for .o-now { color: var(--text); }
html.odx-app.odx-d1-signal .cx-o + .cx-o.adv-for::before, html.odx-app.odx-d1-signal .cx-o.adv-for + .cx-o::before { content: ""; }
html.odx-app .cx-more {
    display: block; width: calc(100% - 32px); height: 44px; margin: 12px 16px 0; border: 0; border-radius: 8px; background: transparent;
    box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text-2); font: 600 calc(13.5px * var(--fs, 1))/1 var(--font); cursor: pointer;
}
/* 베젤 글자 동작('내 조합') — 15/500 --hdr-text-2, 터치 44 */
html.odx-app .ax-tx {
    display: inline-flex; align-items: center; height: 44px; padding: 0 12px; color: var(--hdr-text-2);
    font-size: calc(15px * var(--fs, 1)); font-weight: 500; text-decoration: none; white-space: nowrap;
}

/* ── 내 조합(/myslips) 목록 줄 — 그룹 목록(§3.14): 제목 15 / 부제 12 · 오른쪽 판정 꼬리표 + ⌄. 영수증(SlipReceipt)은 그대로. ── */
html.odx-app .myslips { padding: 0; }
html.odx-app .myslips > .panel { border: 0; border-radius: 0; background: transparent; box-shadow: none; }
html.odx-app .myslips .panel-head { padding: 14px 16px 6px; border: 0; background: transparent; }
html.odx-app .myslips .panel-head h2, html.odx-app .myslips .panel-head .btn { display: none; }
html.odx-app .myslips .panel-head .muted { font-weight: 500; color: var(--text-3); }
html.odx-app .myslips .panel-body { padding: 0 16px; }
html.odx-app .empty .ei { display: none; }   /* [FIX V-12 2026-10-20] 웹 빈 상태 기호 '◎'는 앱에서 덜 읽힌 고리(스피너)처럼 보였다 — 내 조합만이 아니라 앱 전체에서 뺀다 */
html.odx-app .myslips .sliplist { gap: 0; border-radius: 10px; background: var(--surface); overflow: hidden; }
html.odx-app .myslips .sliprow {
    display: grid; grid-template-columns: minmax(0, 1fr) auto 16px; gap: 10px; align-items: center; min-height: 56px;
    padding: 9px 14px; border: 0; border-radius: 0; background: transparent; color: var(--text);
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
}
html.odx-app .myslips .sliprow:hover { background: transparent; }
html.odx-app .myslips .sliprow[data-odx-press="on"], html.odx-app .myslips .sliprow.is-on { background: var(--surface-2); }   /* 누름 = 누름 모듈(APP-MOTION M02) */
html.odx-app .myslips .ms-m { min-width: 0; }
html.odx-app .myslips .ms-t { display: block; font-size: calc(15px * var(--fs, 1)); line-height: 1.33; font-weight: 550; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.odx-app .myslips .ms-s { display: block; margin-top: 1px; font-size: calc(12px * var(--fs, 1)); line-height: 1.42; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.odx-app .myslips .ms-st {
    display: inline-flex; align-items: center; height: 18px; padding: 0 6px; border-radius: 4px;
    box-shadow: inset 0 0 0 1px var(--line); color: var(--text-3); font-size: 11px; font-weight: 700; white-space: nowrap;
}
html.odx-app .myslips .ms-st[data-st="hit"] { background: var(--dom); box-shadow: none; color: #fff; }
html.odx-app .myslips .ms-st[data-st="miss"] { box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text-2); }
html.odx-app .myslips .ms-st[data-st="unk"] { box-shadow: inset 0 0 0 1px rgba(217, 155, 43, .45); color: var(--warn-soft); }
html.odx-app .myslips .ms-chev { color: var(--text-4); transition: transform 200ms var(--ease-out, cubic-bezier(.215, .61, .355, 1)); }
html.odx-app .myslips .sliprow.is-on .ms-chev { transform: rotate(180deg); }
html.odx-app .myslips .slipdetail { padding: 12px 12px 10px; background: var(--surface); box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft); }
html.odx-app .myslips .panel-foot { padding: 10px 16px 0; border: 0; background: transparent; font-size: calc(12px * var(--fs, 1)); line-height: 1.55; color: var(--text-3); }

/* 동작 줄이기(OS 설정 · 네이티브 prefs.motion='reduced' → <html data-odx-motion="reduced">): 이동 · 굴림을 끄고 120ms 페이드만.
   누름의 크기(data-odx-press)는 앱-12 묶음이 끈다(계산기 칸은 면만 남는다). */
@media (prefers-reduced-motion: reduce) {
    html.odx-app .odo > .d.is-in { animation: none; }
    html.odx-app .slipbar { animation: odx-ss-fade 120ms linear backwards; }
    html.odx-app .slipsheet .ss-panel, html.odx-app .slipsheet .ss-scrim { animation: odx-ss-fade 120ms linear backwards; }
    html.odx-app .slipsheet :is(.ss-head, .ss-body), html.odx-app .slipsheet .slipp .mtr .b { animation: none; transition: none; }
    html.odx-app :is(.cx-o, .slipp .sp-ln, .slipp .sp-ink, .slipp .sp-q button, .slipbar-btn) { transition: none; }
    html.odx-app .cx-o.adv-dom::after { transition: none; }
}
html.odx-app[data-odx-motion="reduced"] .odo > .d.is-in { animation: none; }
html.odx-app[data-odx-motion="reduced"] .slipbar { animation: odx-ss-fade 120ms linear backwards; }
html.odx-app[data-odx-motion="reduced"] .slipsheet :is(.ss-panel, .ss-scrim) { animation: odx-ss-fade 120ms linear backwards; }
html.odx-app[data-odx-motion="reduced"] .slipsheet :is(.ss-head, .ss-body),
html.odx-app[data-odx-motion="reduced"] .slipsheet .slipp .mtr .b { animation: none; transition: none; }
html.odx-app[data-odx-motion="reduced"] :is(.cx-o, .slipp .sp-ln, .slipp .sp-ink, .slipp .sp-q button, .slipbar-btn) { transition: none; }
html.odx-app[data-odx-motion="reduced"] .cx-o.adv-dom::after { transition: none; }
/* ── /앱-9 ── */

/* ── 앱-10a 목록 화면 · 문법 [B1] ── §3.14(그룹 목록 · 세그먼트 · 버튼) */
/*  공용 부품 문법(§3.14). 그룹 목록(iOS 인셋) 자체는 앱-10b의 axl-*(머리 · 그룹 · 줄 · 아이콘 열 · 값 · › · 꼬리말)가 정본이다 —
    목록 화면을 새로 그리면 그것을 쓴다(같은 문법을 두 벌 두지 않는다). 이 블록은 어느 화면에서나 같은 모양이어야 하는 부품만 둔다:
    · 스위치(.switch — 기존 마크업 그대로): OS 모양 51×31, 켜짐 #3a9b6f(녹 = 확인 계열), 끄기 면 --surface-4. 누르는 영역 44.
    · 세그먼트(.segm > button.on): 높이 32 · 바탕 --surface-2 · 썸 반경 6. Android = 선 테두리 캡슐(16) + 선택 칸 체크.
    · 잉크 버튼(.btn-ink): 데이터 표면의 주 버튼(슬립에 담기 · 가상영수증 저장 · 확인) — 50 높이, 반경 8, 15.5/700. 폼 화면의 주 버튼은 .btn-primary(앱-11).
    · 선 버튼(.btn-outline): 1px --line-strong. 파괴 동작(로그아웃 · 탈퇴 · 빼기 · 삭제)도 무채 — 적색을 쓰지 않는다. */
html.odx-app .switch { min-height: 44px; }
html.odx-app .switch .track { width: 51px; height: 31px; border: 0; border-radius: 16px; background: var(--surface-4); }
html.odx-app .switch .track::after { top: 2px; left: 2px; width: 27px; height: 27px; background: #fff; }
html.odx-app .switch input:checked + .track { background: #3a9b6f; border-color: #3a9b6f; }
html.odx-app .switch input:checked + .track::after { transform: translateX(20px); background: #fff; }
html.odx-app .switch input:disabled + .track { opacity: .5; }
html.odx-app .switch input:focus-visible + .track { outline: 2px solid var(--accent); outline-offset: 2px; }
html.odx-app[data-theme="light"] .switch .track { background: #e3e6ea; }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) .switch .track { background: #e3e6ea; }
}
html.odx-app[data-theme="light"] .switch input:checked + .track { background: #3a9b6f; }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) .switch input:checked + .track { background: #3a9b6f; }
}

html.odx-app .segm {
    display: inline-flex; align-items: stretch; height: 32px; padding: 2px; gap: 0;
    border-radius: 8px; background: var(--surface-2);
}
html.odx-app .segm > button {
    display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-width: 44px; padding: 0 11px;
    border: 0; border-radius: 6px; background: none; color: var(--text-2);
    font-family: inherit; font-size: calc(13px * var(--fs, 1)); font-weight: 600; line-height: 1; cursor: pointer;
}
html.odx-app .segm > button.on { background: var(--surface-4); color: var(--text); }
html.odx-app[data-theme="light"] .segm > button.on { background: #ffffff; }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) .segm > button.on { background: #ffffff; }
}
html.odx-app-android .segm { height: 36px; padding: 0; border-radius: 16px; background: none; box-shadow: inset 0 0 0 1px var(--line-strong); overflow: hidden; }
html.odx-app-android .segm > button { border-radius: 0; }
html.odx-app-android .segm > button + button { box-shadow: inset 1px 0 0 var(--line-strong); }
html.odx-app-android .segm > button.on { background: var(--surface-4); }
html.odx-app-android .segm > button.on::before {
    content: ""; width: 14px; height: 14px; background-color: currentColor;
    -webkit-mask: url(app-icons/check.svg) center / contain no-repeat; mask: url(app-icons/check.svg) center / contain no-repeat;
}

html.odx-app .btn-ink {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 50px; padding: 0 18px;
    border: 0; border-radius: 8px; background: var(--ink); color: var(--ink-text);
    font-family: inherit; font-size: calc(15.5px * var(--fs, 1)); font-weight: 700; cursor: pointer;
}
html.odx-app .btn-outline {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 50px; padding: 0 18px;
    border: 0; border-radius: 8px; background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text);
    font-family: inherit; font-size: calc(15.5px * var(--fs, 1)); font-weight: 600; cursor: pointer;
}
html.odx-app :is(.btn-ink, .btn-outline):disabled { opacity: .45; cursor: not-allowed; }
/* 누름(APP-MOTION M02 — 브리지 누름 모듈 data-odx-press): 잉크 = scale(.98) + .86, 선 버튼 = scale(.96). 세그먼트(.segm)는 목록 밖이라 :active 그대로. */
html.odx-app :is(.btn-ink, .btn-outline) { transition: transform var(--t-release, 160ms) var(--ease-press), opacity var(--t-release, 160ms) linear; }
html.odx-app .btn-ink:not(:disabled)[data-odx-press="on"] { transform: scale(.98); opacity: .86; transition-duration: var(--t-press, 80ms); }
html.odx-app .btn-outline:not(:disabled)[data-odx-press="on"] { transform: scale(.96); transition-duration: var(--t-press, 80ms); }
html.odx-app .segm > button:active { transform: scale(.98); }
/* ── /앱-10a ── */

/* ── 앱-10b 목록 화면 · 페이지 [B3] ── §5.3(페이지별 명세) */
/* 이 블록의 부품(이름 앞머리 axl- · axp-)은 이 블록의 화면들(내정보·알림 설정·알림함·쪽지·커뮤니티 …)만 쓴다. 모양 값은 APP-DESIGN §3.14·§5.3.
   헤어라인 색은 리터럴(새 색 토큰 금지 — §2.1): 다크 rgba(255,255,255,.075) · 라이트 rgba(0,0,0,.09). 글자 크기는 calc(N * --fs). */

/* (a) 화면 틀 · 2차 네이티브 판정 ─────────────────────────────────────────── */
html.odx-app .wrap.axp { padding: 4px 16px 8px; }
/* 2차 네이티브(<html data-odx-native="2"> — 브리지가 첫 prefs에서 칠하고 enhancedload마다 다시 칠한다) 전용 줄 / 구버전 셸 폴백 줄. */
html.odx-app:not([data-odx-native="2"]) .axp-n2 { display: none !important; }
html.odx-app[data-odx-native="2"] .axp-n1 { display: none !important; }

/* 베젤 동작 칸(SectionContent "appactions") — 아이콘 44 · 글자 15/500. 자리 잡기는 베젤(앱-3)이 한다. */
html.odx-app .axp-act {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    min-width: 44px; height: 44px; margin: 0; padding: 0;
    background: none; border: 0; border-radius: 0; color: var(--hdr-text); cursor: pointer;
    -webkit-user-select: none; user-select: none;
}
html.odx-app .axp-act-t { padding: 0 12px; font-size: calc(15px * var(--fs, 1)); font-weight: 500; color: var(--hdr-text-2); white-space: nowrap; }
html.odx-app .axp-act:active { opacity: .6; }
html.odx-app .axp-aic {
    display: block; width: 22px; height: 22px; background: currentColor;
    -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 22px 22px; mask-size: 22px 22px;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}

/* 하위 탭(운영진 알림 · 쪽지 / 커뮤니티 분류) — 마켓 탭 문법(§3.2): 활성 = 밝은 글자 + 2pt 액센트 밑줄, 칸 사이 24. */
html.odx-app .subnav .wrap > .axp-tab {
    position: relative; display: inline-flex; align-items: center; gap: 5px; flex: none;
    height: 44px; min-width: 0; margin: 0; padding: 0;
    background: none; border: 0; border-radius: 0; box-shadow: none;
    font-size: calc(15px * var(--fs, 1)); font-weight: 600; line-height: 20px; color: var(--hdr-text-2); white-space: nowrap; cursor: pointer;
}
html.odx-app .subnav .wrap > .axp-tab:hover,
html.odx-app .subnav .wrap > .axp-tab:active { background: none; }
html.odx-app .subnav .wrap > .axp-tab.on { color: var(--hdr-text); background: none; border: 0; font-weight: 650; }
html.odx-app .subnav .wrap > .axp-tab.on::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: #4d90d8; transform-origin: 0 50%; }   /* [INT] 마켓 탭(앱-3)과 같은 값 — 베젤은 두 테마 모두 어둡다(§5.2.3). transform-origin = 밑줄 미끄러짐(APP-MOTION M07) */
html.odx-app .subnav .wrap > .axp-tab .n { font: 500 calc(11px * var(--fs, 1))/1 var(--mono); color: var(--hdr-text-2); }

/* (b) 그룹 목록(iOS 인셋 — §3.14) ──────────────────────────────────────────
   axl-h 머리 · axl-g 그룹 · axl-r 줄(48↑) · axl-i 아이콘(22 열) · axl-b 글(axl-t 제목 15/550 · axl-s 부제 12) · axl-v 값 14 · axl-c › · axl-f 꼬리말. */
html.odx-app .axl-h {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    margin: 22px 4px 7px; font-size: calc(12px * var(--fs, 1)); line-height: 16px; font-weight: 500; color: var(--text-3);
}
html.odx-app .axl-h:first-child { margin-top: 2px; }
html.odx-app .axl-h .mono { font-size: calc(11.5px * var(--fs, 1)); }
html.odx-app .axl-g { position: relative; background: var(--surface); border-radius: 10px; overflow: hidden; }
html.odx-app .axl-g + .axl-g { margin-top: 18px; }
html.odx-app .axl-g:first-child { margin-top: 0; }
/* [FIX DF-07] 그룹 목록 화면의 첫 그룹 · 첫 머리는 베젤 헤어라인에서 띄운다(§2.4 바깥 여백 16 — 그림 p14 · a13). .wrap.axp 위 여백 4는
   목록이 화면 폭 끝까지 가는 화면(알림함 · 쪽지 · 커뮤니티 — 음수 여백)이 기대므로 그대로 두고 첫 자식에만 더한다. */
html.odx-app .wrap.axp > .axl-g:first-child { margin-top: 12px; }
html.odx-app .wrap.axp > .axl-h:first-child { margin-top: 18px; }
html.odx-app .axl-f { margin: 8px 4px 0; font-size: calc(12px * var(--fs, 1)); line-height: 1.55; color: var(--text-3); }
html.odx-app .axl-r {
    position: relative; display: flex; align-items: center; gap: 12px;
    box-sizing: border-box; width: 100%; min-height: 48px; margin: 0; padding: 10px 14px;
    background: transparent; border: 0; border-radius: 0; color: var(--text);
    font: inherit; font-size: calc(15px * var(--fs, 1)); text-align: left; text-decoration: none; cursor: pointer;
    -webkit-user-select: none; user-select: none;
}
html.odx-app .axl-r:not(:last-child)::after {
    content: ""; position: absolute; left: 48px; right: 0; bottom: 0; height: var(--hair-w, 1px);
    background: rgba(255, 255, 255, .075); pointer-events: none;
}
html.odx-app .axl-r.noi:not(:last-child)::after { left: 14px; }
/* 누름(APP-MOTION M02) — 전폭 줄은 면 --surface-2 즉시(크기 그대로). 브리지 누름 모듈(data-odx-press)이 스크롤 시작에는 쓰지 않는다. */
html.odx-app :is(a, button, [role="button"]).axl-r[data-odx-press="on"] { background: var(--surface-2); }
html.odx-app .axl-r:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 0; }
html.odx-app .axl-i {
    flex: none; width: 22px; height: 20px; background: var(--text-2);
    -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px 20px; mask-size: 20px 20px;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
html.odx-app .axl-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
html.odx-app .axl-t { font-size: calc(15px * var(--fs, 1)); line-height: 20px; font-weight: 550; color: var(--text); overflow-wrap: anywhere; word-break: keep-all; }
html.odx-app .axl-s { font-size: calc(12px * var(--fs, 1)); line-height: 17px; font-weight: 400; color: var(--text-3); overflow-wrap: anywhere; word-break: keep-all; }
html.odx-app .axl-s .mono, html.odx-app .axl-t .mono { font-size: .96em; }
html.odx-app .axl-v {
    flex: 0 1 auto; min-width: 0; max-width: 55%; font-size: calc(14px * var(--fs, 1)); line-height: 20px; color: var(--text-3);
    text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.odx-app .axl-v.mono, html.odx-app .axl-v .mono { font-size: calc(13.5px * var(--fs, 1)); }
html.odx-app .axl-c {
    flex: none; width: 14px; height: 14px; margin-right: -2px; background: var(--text-4);
    -webkit-mask: url(app-icons/chevron-right.svg) center / 14px 14px no-repeat; mask: url(app-icons/chevron-right.svg) center / 14px 14px no-repeat;
}
html.odx-app .axl-ok { color: var(--ok-soft); font-weight: 600; }
/* 아이콘 — wwwroot/app-icons(§2.8, 네이티브 iconPaths와 같은 형상). */
html.odx-app .i-gear { -webkit-mask-image: url(app-icons/gear.svg); mask-image: url(app-icons/gear.svg); }
html.odx-app .i-bell { -webkit-mask-image: url(app-icons/bell.svg); mask-image: url(app-icons/bell.svg); }
html.odx-app .i-person { -webkit-mask-image: url(app-icons/person.svg); mask-image: url(app-icons/person.svg); }
html.odx-app .i-card { -webkit-mask-image: url(app-icons/card.svg); mask-image: url(app-icons/card.svg); }
html.odx-app .i-receipt { -webkit-mask-image: url(app-icons/receipt.svg); mask-image: url(app-icons/receipt.svg); }
html.odx-app .i-pencil { -webkit-mask-image: url(app-icons/pencil.svg); mask-image: url(app-icons/pencil.svg); }
html.odx-app .i-info { -webkit-mask-image: url(app-icons/info.svg); mask-image: url(app-icons/info.svg); }
html.odx-app .i-out { -webkit-mask-image: url(app-icons/out.svg); mask-image: url(app-icons/out.svg); }
html.odx-app .i-device { -webkit-mask-image: url(app-icons/device.svg); mask-image: url(app-icons/device.svg); }
html.odx-app .i-plus { -webkit-mask-image: url(app-icons/plus.svg); mask-image: url(app-icons/plus.svg); }
html.odx-app .i-search { -webkit-mask-image: url(app-icons/search.svg); mask-image: url(app-icons/search.svg); }
html.odx-app .i-msg { -webkit-mask-image: url(app-icons/msg.svg); mask-image: url(app-icons/msg.svg); }
html.odx-app .i-doc { -webkit-mask-image: url(app-icons/doc.svg); mask-image: url(app-icons/doc.svg); }
html.odx-app .i-shield { -webkit-mask-image: url(app-icons/shield.svg); mask-image: url(app-icons/shield.svg); }   /* 내정보 '관리자 페이지'(운영진) */

/* 스위치 — OS 모양 51×31, 켜짐 #3a9b6f(§3.14). 목록 안에서만. */
html.odx-app .axl-g .switch { flex: none; gap: 0; min-height: 44px; }
html.odx-app .axl-g .switch .track { width: 51px; height: 31px; border: 0; border-radius: 16px; background: var(--surface-4); }
html.odx-app .axl-g .switch .track::after { top: 2px; left: 2px; width: 27px; height: 27px; background: #fff; }
html.odx-app .axl-g .switch input:checked + .track { background: #3a9b6f; }
html.odx-app .axl-g .switch input:checked + .track::after { transform: translateX(20px); background: #fff; }
html.odx-app .axl-g .switch input:disabled + .track { opacity: .5; }

/* 무채 버튼 — 앱의 파괴 동작(로그아웃 · 해지 · 탈퇴 · 삭제)은 적색이 아니라 무채 + 확인 단계(§3.14 · §9-5). */
html.odx-app :is(.axp, .axp-sheet) .btn-danger,
html.odx-app .axp-btn-neutral { background: var(--surface-3); border-color: var(--line-strong); color: var(--text); }
html.odx-app :is(.axp, .axp-sheet) .btn-danger:hover,
html.odx-app .axp-btn-neutral:hover { background: var(--surface-4); color: var(--text); }

/* 확인 시트(로그아웃 확인 등) — 제목 한 줄 + 설명 한 줄 + 세로 버튼 둘. */
html.odx-app .axp-confirm .modal-body { padding: 22px 18px 6px; text-align: center; }
html.odx-app .axp-confirm .modal-body h3 { font-size: calc(17px * var(--fs, 1)); line-height: 24px; font-weight: 700; color: var(--text); }
html.odx-app .axp-confirm .modal-body p { margin-top: 6px; font-size: calc(13.5px * var(--fs, 1)); line-height: 1.6; color: var(--text-3); }
html.odx-app .axp-confirm .modal-foot { display: flex; flex-direction: column; gap: 8px; padding: 14px 16px calc(14px + var(--app-sb, 0px)); border-top: 0; }
html.odx-app .axp-confirm .modal-foot form { margin: 0; }
html.odx-app .axp-confirm .modal-foot .btn { height: 50px; border-radius: 8px; font-size: calc(15.5px * var(--fs, 1)); font-weight: 700; }

/* (c) 내정보 /mypage(§5.3.9 · 그림 14) ───────────────────────────────────── */
html.odx-app .axp-my .adm { display: block; }
html.odx-app .axl-prof { min-height: 74px; padding: 14px; cursor: default; }
html.odx-app .axp-av {
    flex: none; display: grid; place-items: center; width: 46px; height: 46px; border-radius: 50%;
    background: var(--surface-3); color: var(--text); font-size: 17px; font-weight: 700;
}
html.odx-app .axp-nick { font-size: calc(17px * var(--fs, 1)); line-height: 22px; font-weight: 700; }
html.odx-app .axp-planv { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
/* [APP-MOTION V05] 이용권 남은 날 — PRIME 꼬리표 아래 D-n 15/650 mono --text, 그 아래 'MM/dd까지' 11 --text-3(세 줄, 줄 높이 74 그대로). */
/*  18 + 1 + 15 + 1 + 11 = 46 = 74 − 위아래 14 — 세 줄이 줄 높이를 늘리지 않는다. */
html.odx-app .axp-planv:has(> .axp-dd) { gap: 1px; }
html.odx-app .axp-dd { font-family: var(--mono); font-size: calc(15px * var(--fs, 1)); line-height: calc(15px * var(--fs, 1)); font-weight: 650; letter-spacing: -.03em; color: var(--text); }
html.odx-app .axp-planv > .axp-dd + .axl-s { font-size: calc(11px * var(--fs, 1)); line-height: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .axp-planv > .axl-s .mono { font-size: inherit; }   /* [FIX V-13] 'MM/dd'가 .axl-s .mono(.96em)에 10.56px로 줄었다 — §2.3 하한 11 */
html.odx-app .axp-tag {
    display: inline-flex; align-items: center; height: 18px; padding: 0 6px;
    border: 1px solid var(--line-strong); border-radius: 3px;
    font: 700 10px/1 var(--mono); letter-spacing: .08em; color: var(--text-2);
}
/* 구획 시트 안: 웹 패널을 테두리 없는 구획으로, 탈퇴 줄은 맨 아래 무채 그룹으로. */
html.odx-app .axp-secsheet .modal-body { padding: 4px 16px calc(20px + var(--app-sb, 0px)); }
html.odx-app .axp-secsheet .panel { border: 0; border-radius: 10px; background: transparent; overflow: visible; }
html.odx-app .axp-secsheet .panel + .panel { margin-top: 18px; }
html.odx-app .axp-secsheet .panel-head { min-height: 0; padding: 14px 4px 7px; background: none; border: 0; }
html.odx-app .axp-secsheet .panel-head h2 { font-size: calc(12px * var(--fs, 1)); line-height: 16px; font-weight: 500; color: var(--text-3); }
html.odx-app .axp-secsheet .panel-head .sub { font-size: calc(12px * var(--fs, 1)); }
html.odx-app .axp-secsheet .panel-body { padding: 14px; background: var(--surface-2); border-radius: 10px; }
html.odx-app .axp-secsheet .panel-body.flush { padding: 0; overflow: hidden; }
html.odx-app .axp-secsheet .panel-foot { padding: 8px 4px 0; background: none; border: 0; font-size: calc(12px * var(--fs, 1)); line-height: 1.55; }
html.odx-app .axp-secsheet .grid-form { grid-template-columns: 1fr; }
html.odx-app .axp-secsheet .axl-g { background: var(--surface-2); }
html.odx-app .axp-leave { margin-top: 18px; }

/* (d) 알림 설정 /alerts(§5.3.6 · 그림 13) ─────────────────────────────────── */
/* 이 기기: 2차 네이티브면 한 줄뿐 — 뒤에 숨은 종전 스위치 줄 때문에 남는 아래 선을 지운다. */
html.odx-app[data-odx-native="2"] #app-push .axp-n2::after { content: none; }
html.odx-app .axp-rowbtn { flex: none; height: 32px; padding: 0 12px; border-radius: 8px; font-size: calc(13px * var(--fs, 1)); white-space: nowrap; }
html.odx-app .axp-rowbtn { position: relative; }
html.odx-app .axp-rowbtn::after { content: ""; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px; }   /* [INT] 히트 44(§2.4) — 모양은 32 그대로 */
html.odx-app .axp-rule { padding-top: 11px; padding-bottom: 11px; }
html.odx-app .axp-rule .axl-t { font-weight: 650; }
html.odx-app .axp-rmeta { color: var(--text-4); }
/* [APP-MOTION V06] 조건의 숫자가 먼저 읽히게(글자는 --text-3 그대로) · 꺼진 규칙은 글이 흐리다(스위치는 그대로). 정적 — 전이 없음. */
html.odx-app .axp-rule .axl-s .mono { font-weight: 600; color: var(--text); }
html.odx-app .axp-rule .axp-rmeta .mono { font-weight: 400; color: inherit; }
html.odx-app .axp-rule.is-off .axl-b { opacity: .5; }
html.odx-app .axp-addrow { gap: 10px; min-height: 52px; }
html.odx-app .axp-addrow .axl-t { font-weight: 550; }
html.odx-app .axp-plus {
    flex: none; width: 18px; height: 18px; background: var(--text);
    -webkit-mask: url(app-icons/plus.svg) center / 18px 18px no-repeat; mask: url(app-icons/plus.svg) center / 18px 18px no-repeat;
}
/* 발송 미리보기 — 실제 앱 푸시 배너 모양(앱 아이콘 · 제목 · 세 줄 · '지금'). 반경 14(OS 시트 값). */
html.odx-app .axp-pv { display: flex; align-items: flex-start; gap: 12px; padding: 13px 14px; border-radius: 14px; background: var(--surface-3); }
html.odx-app .axp-pv-ic { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 8px; background: #14171a; }
html.odx-app .axp-pv-ic img { width: 20px; height: 20px; }
html.odx-app .axp-pv-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; font-size: calc(13.5px * var(--fs, 1)); line-height: 19px; color: var(--text); }
html.odx-app .axp-pv-h { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
html.odx-app .axp-pv-h b { min-width: 0; font-weight: 650; }
html.odx-app .axp-pv-now { flex: none; font-size: calc(12px * var(--fs, 1)); color: var(--text-3); }
/* 수신 번호 인증(최초 1회) · 안내 띠 — 테두리 없는 구획. */
html.odx-app .axp-alerts .panel { margin-top: 18px; border: 0; border-radius: 10px; background: var(--surface); }
html.odx-app .axp-alerts .panel-head { min-height: 0; padding: 12px 14px 4px; background: none; border: 0; }
html.odx-app .axp-alerts .panel-head h2 { font-size: calc(15px * var(--fs, 1)); font-weight: 650; }
html.odx-app .axp-alerts .panel-body { padding: 8px 14px 14px; }
html.odx-app .axp-alerts .field { max-width: none !important; }
html.odx-app .axp-alerts > .notice,
html.odx-app .axp-alerts .notice { margin-top: 12px; border-radius: 10px; }
/* 편집 시트 — 한 줄에 한 칸, 삭제는 왼쪽 끝 무채. */
html.odx-app .axp-rulesheet .grid-form { grid-template-columns: minmax(0, 1fr); }
html.odx-app .axp-rulesheet .grid-form .span2 { grid-column: auto; }
html.odx-app .axp-rulesheet .axp-del { margin-right: auto; color: var(--text-2); }

/* (e) 알림함 /notifications(§5.3.7 · 그림 12) — 왼쪽 7pt 액센트 점(새 것) · 분류 11/650 · 날짜 mono · 제목 15(새 것 650). ── */
html.odx-app .axp-noti .cols { display: block; max-width: none; }
html.odx-app .axp-noti .panel { margin: -4px -16px 0; border: 0; border-radius: 0; background: transparent; overflow: visible; }
html.odx-app .axp-noti .notilist li { position: relative; border-bottom: 0; background: transparent; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(255, 255, 255, .075); }
html.odx-app .axp-noti .notilist li.is-new { background: transparent; }
html.odx-app .axp-noti .nt-head {
    position: relative;
    display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "lv dt" "ti ti"; align-items: baseline;
    column-gap: 12px; row-gap: 3px; min-height: 64px; padding: 13px 40px 14px 30px; font-size: calc(15px * var(--fs, 1));
}
html.odx-app .axp-noti .nt-head:hover { background: none; }
html.odx-app .axp-noti .nt-head[data-odx-press="on"] { background: var(--surface-2); }   /* 누름 모듈(APP-MOTION M02) */
html.odx-app .axp-noti .nt-head > .badge {
    grid-area: lv; justify-self: start; height: auto; padding: 0; border: 0; background: none; letter-spacing: 0;
    font-size: calc(11px * var(--fs, 1)); line-height: 16px; font-weight: 650; color: var(--text-2);
}
html.odx-app .axp-noti .nt-head .nt-ti {
    grid-area: ti; white-space: normal; overflow: visible; word-break: keep-all; overflow-wrap: anywhere;
    font-size: calc(15px * var(--fs, 1)); line-height: 21px; font-weight: 400; color: var(--text-2);
}
html.odx-app .axp-noti .notilist li.is-new .nt-head .nt-ti { font-weight: 650; color: var(--text); }
html.odx-app .axp-noti .nt-ti .badge { height: 18px; padding: 0 5px; font-size: 11px; vertical-align: 1px; }
html.odx-app .axp-noti .nt-head .nt-dt { grid-area: dt; font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
/* [APP-MOTION §3.2(b)] 펼치는 줄 = 오른쪽 가운데 회전 셰브런(chevron-down 14 --text-4, 펼치면 180° — aria-expanded, Notifications.razor 앱 분기). */
html.odx-app .axp-noti .nt-head .ch {
    position: absolute; right: 16px; top: 50%; width: 14px; height: 14px; margin-top: -7px;
    font-size: 0; line-height: 0; color: transparent; background: var(--text-4);
    -webkit-mask: url(app-icons/chevron-down.svg) center / 14px 14px no-repeat; mask: url(app-icons/chevron-down.svg) center / 14px 14px no-repeat;
    transition: transform 200ms var(--ease-out);
}
html.odx-app .axp-noti .nt-head[aria-expanded="true"] .ch { transform: rotate(180deg); }
html.odx-app .axp-noti .notilist li.is-new .nt-head::before {
    content: ""; position: absolute; left: 13px; top: 19px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
}
html.odx-app .axp-noti .nt-body { padding: 0 16px 16px 30px; }   /* 앱 분기는 안쪽 래퍼(.odx-dz)가 이 여백을 진다 — 펼침 M10, 아래 (r) */
html.odx-app .axp-noti .notilist .nt-body .doc { font-size: calc(13.5px * var(--fs, 1)); line-height: 1.6; color: var(--text-2); }
html.odx-app .axp-noti .nt-body .row { font-size: calc(11.5px * var(--fs, 1)) !important; }

/* (f) 쪽지 /messages(§5.3.7) — 목록 = 상대 · 마지막 글 한 줄 · 시각, 대화 = .cmt 시간순(말풍선 없음), 입력칸은 바닥. ── */
html.odx-app .axp-dm .adm { display: block; }
html.odx-app .axp-dm .adm.axp-dm-list > div,
html.odx-app .axp-dm .adm.axp-dm-thread > .adm-nav,
html.odx-app .axp-dm .adm.axp-dm-empty > .adm-nav { display: none; }
html.odx-app .axp-dm .adm-nav { position: static; display: block; max-height: none; margin: -4px -16px 0; padding: 0; background: transparent; border: 0; border-radius: 0; overflow: visible; }
html.odx-app .axp-dm .adm-nav h5 { display: none; }
html.odx-app .axp-dm .adm-nav a {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; min-height: 64px; padding: 12px 16px;
    border-radius: 0; background: none; color: var(--text); font-size: calc(15px * var(--fs, 1));
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(255, 255, 255, .075);
}
html.odx-app .axp-dm .adm-nav a[data-odx-press="on"] { background: var(--surface-2); }   /* 누름 모듈(APP-MOTION M02) */
html.odx-app .axp-dm .adm-nav a > span:first-child { flex: 1 1 auto; min-width: 0; }
html.odx-app .axp-dm .adm-nav a b { font-size: calc(15px * var(--fs, 1)) !important; font-weight: 650; }
html.odx-app .axp-dm .adm-nav a .muted { max-width: none !important; margin-top: 3px; font-size: calc(13px * var(--fs, 1)) !important; color: var(--text-3); }
html.odx-app .axp-dm .adm-nav a > .n { flex: none; font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .axp-dm .adm-nav a .row .n { font: 600 calc(12px * var(--fs, 1)) var(--mono); }
html.odx-app .axp-dm-thread .panel,
html.odx-app .axp-dm-empty .panel { margin: -4px -16px 0; border: 0; border-radius: 0; background: transparent; overflow: visible; }
html.odx-app .axp-dm-thread .panel-head { min-height: 0; padding: 10px 16px 6px; background: none; border: 0; }
html.odx-app .axp-dm-thread .panel-head h2 { font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text-2); }
html.odx-app .axp-dm .cmt { padding: 12px 16px; border-bottom: 0; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(255, 255, 255, .075); }
html.odx-app .axp-dm .cmt-head { font-size: calc(12px * var(--fs, 1)); }
html.odx-app .axp-dm .cmt.is-mine .cmt-head .au { color: var(--text-3); font-weight: 600; }
html.odx-app .axp-dm .cmt-body { font-size: calc(15px * var(--fs, 1)); line-height: 1.6; color: var(--text); }
/* 입력칸 — 탭바 위 바닥에 붙는다(Android adjustResize·iOS 키보드는 시각 뷰포트가 줄어 함께 올라온다). */
html.odx-app .axp-dm-thread .panel > .panel-body:last-child { position: sticky; bottom: var(--app-bar, 0px); padding: 8px 16px 10px; background: var(--bg); }
html.odx-app .axp-dm-thread .panel > .panel-body:last-child .field { margin-bottom: 8px; }
html.odx-app .axp-dm-thread .panel > .panel-body:last-child .field > label { display: none; }
html.odx-app .axp-dm-thread .panel > .panel-body:last-child .textarea { min-height: 44px; height: 72px; border-radius: 8px; }
html.odx-app .axp-dm-thread .panel > .panel-body:last-child .fhelp { font-size: calc(11px * var(--fs, 1)); }

/* (g) 커뮤니티 /community(§5.3.8 · 그림 11) — 줄 = 분류 · 작성자 · 시각 → 제목 15/550 + [댓글] → 조회 N. 아바타 · 'N' · 공지 배지 없음. ── */
html.odx-app .axp-comm .cols { display: block; }
html.odx-app .axp-comm .panel { margin: -4px -16px 0; border: 0; border-radius: 0; background: transparent; overflow: visible; }
html.odx-app .axp-comm .panel-head { min-height: 0; padding: 4px 16px 10px; background: none; border: 0; }
html.odx-app .axp-comm .panel-head > .row { flex: 1 1 auto; }
html.odx-app .axp-comm .panel-head .badge,
html.odx-app .axp-comm .panel-head-act { display: none; }
html.odx-app .axp-comm .searchbox { flex: 1 1 auto; width: auto !important; }
html.odx-app .axp-comm .searchbox .input { height: 38px; border-radius: 9px; background: var(--surface-2); border-color: transparent; }
html.odx-app .axp-act.on { color: #4d90d8; }   /* [FIX DF-03] 베젤은 두 테마 모두 어둡다 — 라이트 --accent(#1f6dc0)는 어두운 베젤에서 흐리다(탭 밑줄과 같은 값) */
html.odx-app .axp-comm .blist li { border-bottom: 0; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(255, 255, 255, .075); }
html.odx-app .axp-comm .blist a {
    display: grid; grid-template-columns: auto auto minmax(0, 1fr); grid-template-areas: "cat au dt" "ti ti ti" "vw vw vw";
    align-items: baseline; column-gap: 0; row-gap: 3px; padding: 12px 16px 13px;
}
html.odx-app .axp-comm .blist a:hover { background: none; }
/* 누름(APP-MOTION M02) — 1차 규칙(W1 :active --row-hover)은 스크롤 시작마다 번쩍여 이 목록에서 끈다. 누름 모듈 속성으로 면 --surface-2 즉시. */
html.odx-app .axp-comm .blist a:active { background: none; }
html.odx-app .axp-comm .blist a[data-odx-press="on"] { background: var(--surface-2); }
html.odx-app .axp-comm .blist .bcat { grid-area: cat; display: block; width: auto; font-size: calc(11.5px * var(--fs, 1)); line-height: 16px; font-weight: 650; color: var(--text-2); }
html.odx-app .axp-comm .blist .bmeta,
html.odx-app .axp-comm .blist .bmeta > .row { display: contents; }
html.odx-app .axp-comm .blist .bmeta .av { display: none; }
html.odx-app .axp-comm .blist .bmeta .au,
html.odx-app .axp-comm .blist .bmeta .dt { min-width: 0; text-align: left; font-size: calc(11.5px * var(--fs, 1)); line-height: 16px; color: var(--text-3); white-space: nowrap; }
html.odx-app .axp-comm .blist .bmeta .au { grid-area: au; overflow: hidden; text-overflow: ellipsis; }
html.odx-app .axp-comm .blist .bmeta .dt { grid-area: dt; }
html.odx-app .axp-comm .blist .bmeta .au::before,
html.odx-app .axp-comm .blist .bmeta .dt::before { content: "·"; margin: 0 6px; color: var(--text-4); font-family: var(--font); }
html.odx-app .axp-comm .blist .bmeta .vw {
    grid-area: vw; display: block; min-width: 0; text-align: left; font-size: calc(11.5px * var(--fs, 1)); line-height: 16px; color: var(--text-3);
}
html.odx-app .axp-comm .blist .bmeta .vw::before { content: "조회 "; font-family: var(--font); }
html.odx-app .axp-comm .blist .bti {
    grid-area: ti; white-space: normal; overflow: visible; word-break: keep-all; overflow-wrap: anywhere;
    font-size: calc(15px * var(--fs, 1)); line-height: 21px; font-weight: 550; color: var(--text);
}
html.odx-app .axp-comm .blist .bti:has(> .badge-accent) { font-weight: 650; }
html.odx-app .axp-comm .blist .bti > .badge,
html.odx-app .axp-comm .blist .bti .new { display: none; }
html.odx-app .axp-comm .blist .bti > .badge + span { margin-left: 0 !important; }
html.odx-app .axp-comm .blist .bti .cnt { margin-left: 5px; font: 500 calc(13px * var(--fs, 1)) var(--mono); color: var(--text-3); }
html.odx-app .axp-comm .blist .bti .chip { height: 18px; padding: 0 5px; font-size: 11px; vertical-align: 2px; }
html.odx-app .axp-comm .pager { margin: 14px 0 4px; }

/* (h) 글 · 글쓰기 /community/{id} · /community/write(§5.3.8) — 본문 15/1.7, 댓글 입력은 본문 끝(고정 바닥 입력 없음). ── */
html.odx-app :is(.axp-post, .axp-write) .crumb { display: none; }
html.odx-app :is(.axp-post, .axp-write) .cols { display: block; max-width: none; }
html.odx-app .axp-post .panel { margin: 0 -16px; border: 0; border-radius: 0; background: transparent; overflow: visible; }
html.odx-app .axp-post .panel + .panel { margin-top: 10px; box-shadow: inset 0 var(--hair-w, 1px) 0 rgba(255, 255, 255, .075); }
html.odx-app .axp-post .post-head { padding: 6px 16px 12px; border-bottom: 0; }
html.odx-app .axp-post .post-head h1 { font-size: calc(19px * var(--fs, 1)); line-height: 1.4; word-break: keep-all; overflow-wrap: anywhere; }
html.odx-app .axp-post .post-meta { gap: 8px; margin-top: 8px; font-size: calc(11.5px * var(--fs, 1)); }
html.odx-app .axp-post .post-meta .badge { height: auto; padding: 0; border: 0; background: none; font-size: calc(11.5px * var(--fs, 1)); font-weight: 650; color: var(--text-2); }
html.odx-app :is(.axp-post, .axp-comm) .av { display: none; }
html.odx-app .axp-post .post-body { padding: 4px 16px 22px; font-size: calc(15px * var(--fs, 1)); line-height: 1.7; color: var(--text); }
html.odx-app .axp-post .post-body .panel { margin: 16px 0 0; border-radius: 10px; background: var(--surface); }
html.odx-app .axp-post .post-body .panel-head { background: none; border: 0; min-height: 0; padding: 12px 14px 4px; }
html.odx-app .axp-post .post-act { justify-content: flex-start; flex-wrap: wrap; gap: 8px; padding: 0 16px 16px; }
html.odx-app .axp-post .post-act .btn { min-height: 44px; }   /* [FIX DF-04] 터치 44(§2.4 · §9-16) */
html.odx-app .axp-post .panel-head { min-height: 0; padding: 12px 16px 4px; background: none; border: 0; }
html.odx-app .axp-post .panel-head h2 { font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text-2); }
html.odx-app .axp-post .cmt { padding: 12px 16px; border-bottom: 0; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(255, 255, 255, .075); }
html.odx-app .axp-post .cmt.reply { padding-left: 34px; }
html.odx-app .axp-post .cmt-body { font-size: calc(14.5px * var(--fs, 1)); line-height: 1.65; color: var(--text); }
html.odx-app .axp-post .panel-body { padding: 12px 16px; border-top: 0 !important; }
html.odx-app .axp-write .phead { display: none; }
html.odx-app .axp-write .panel { margin-top: 12px; border: 0; border-radius: 10px; background: var(--surface); }
html.odx-app .axp-write .panel-head { min-height: 0; padding: 12px 14px 4px; background: none; border: 0; }
html.odx-app .axp-write .panel-head h2 { font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text-2); }
html.odx-app .axp-write .panel-body { padding: 8px 14px 14px; }
html.odx-app .axp-write .select { max-width: none !important; }
html.odx-app .axp-write .textarea { height: 220px !important; }

/* (i) 프로토 전체 경기 /proto(§5.3.2) — 사이드바 없음 · 회차 = 베젤 탭 · 종목 = 칩 한 줄 · 표는 가로 스크롤 · 행 44 · 숫자 mono. ── */
html.odx-app .axp-proto .pb-portal { display: block; }
html.odx-app .axp-proto .pb-side { display: none; }
html.odx-app .axp-proto .pb-main { margin: 0 -16px; border: 0; border-radius: 0; background: transparent; overflow: visible; }
html.odx-app .axp-proto .pb-main > .panel-head { display: none; }
html.odx-app .axp-proto .pb-wrap,
html.odx-app .axp-proto .pb-wrap.pb-tall { max-height: none; min-height: 0; overflow-y: visible; }
html.odx-app .axp-proto .tbl { min-width: 760px; }
html.odx-app .axp-proto .tbl td { height: 44px; white-space: nowrap; }
html.odx-app .axp-proto .tbl thead th { background: var(--surface-2); color: var(--text-3); border-color: var(--line); }
html.odx-app .axp-proto .axp-rail { margin: 0; }
html.odx-app .axp-proto .pb-sale .st.live { display: none; }
html.odx-app .axp-proto .pb-note { margin: 0; font-size: calc(13px * var(--fs, 1)); line-height: 1.6; }
html.odx-app .axp-proto .panel-foot { padding: 10px 16px; background: none; border-top: 0; font-size: calc(12px * var(--fs, 1)); line-height: 1.55; }
html.odx-app .subnav .wrap > .axp-tab .st { font-size: calc(11px * var(--fs, 1)); font-weight: 500; color: var(--hdr-text-2); }
/* 칩 레일(§3.3 문법 — 한 줄, 가로 스크롤 하나, 칩 30 · 반경 6 · 1px 안쪽 선, 켜짐 = --surface-2 면 + 진한 선). */
html.odx-app .axp-rail {
    display: flex; align-items: center; gap: 6px; height: 46px; margin: 0 -16px; padding: 0 16px;
    overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity; scroll-padding-inline: 16px; overscroll-behavior-x: contain; scrollbar-width: none;
}
html.odx-app .axp-rail::-webkit-scrollbar { display: none; }
html.odx-app .axp-chip {
    position: relative; flex: none; display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 10px; scroll-snap-align: start;
    border-radius: 6px; box-shadow: inset 0 0 0 1px var(--line); background: none; color: var(--text-2);
    font-size: calc(12.5px * var(--fs, 1)); font-weight: 550; line-height: 1; white-space: nowrap;
}
html.odx-app .axp-chip::after { content: ""; position: absolute; left: -3px; right: -3px; top: -7px; bottom: -7px; }   /* [FIX DF-04] 칩 30 + 14 = 히트 44(보드 .axb-chip과 같은 방법) */
/* 누름 = scale(.96)(APP-MOTION M02 — 공용 칩 규칙은 앱-12). */
html.odx-app .axp-chip.on { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); }
html.odx-app .axp-chip .n { font: 500 calc(11px * var(--fs, 1))/1 var(--mono); color: var(--text-3); }
html.odx-app .axp-chip .ico { display: inline-flex; width: 14px; height: 14px; }
html.odx-app .axp-chip .ico svg { width: 14px; height: 14px; }
html.odx-app .axp-chip .axp-x, html.odx-app .axp-chip .axp-dn { font-size: 10px; color: var(--text-3); }
html.odx-app .axp-rail-sep { flex: none; width: 1px; height: 16px; margin: 0 4px; background: var(--line); }
/* 필터 시트(링크로 여닫는 정적 SSR 시트) — 딤 전체가 '닫기' 링크다. */
html.odx-app .axp-linkveil { padding: 0; }
html.odx-app .axp-veil-x { position: absolute; inset: 0; }
html.odx-app .axp-pbsheet { position: relative; }
html.odx-app .axp-pbsheet .modal-head { gap: 8px; }
html.odx-app .axp-pbsheet .modal-head h3 { flex: 1 1 auto; }
html.odx-app .axp-reset { display: inline-flex; align-items: center; min-height: 44px; padding: 0 6px; font-size: calc(14px * var(--fs, 1)); color: var(--text-2); }
html.odx-app .axp-pbsheet .modal-x { display: inline-grid; place-items: center; min-width: 44px; min-height: 44px; }
html.odx-app .axp-pbsheet .modal-body { padding: 12px 16px calc(20px + var(--app-sb, 0px)); }
html.odx-app .axp-pbsearch .searchbox .input { height: 40px; border-radius: 9px; background: var(--surface-2); border-color: transparent; }
html.odx-app .axp-pbsheet .axl-g { background: var(--surface-2); }
html.odx-app .axp-lgtick { flex: none; width: 3px; height: 12px; border-radius: 1px; }
html.odx-app .axp-chk {
    flex: none; width: 16px; height: 16px; background: var(--text);
    -webkit-mask: url(app-icons/check.svg) center / 16px 16px no-repeat; mask: url(app-icons/check.svg) center / 16px 16px no-repeat;
}

/* (j) 기록식 배당 /record(§5.3.3) — 회차 · 경기 select를 베젤 아래 한 줄에 반반(네이티브 피커), 표는 .tablewrap. ── */
html.odx-app .axp-record .phead { display: flex !important; margin: 0 0 10px; }
html.odx-app .axp-record .phead > div:first-child { display: none; }
html.odx-app .axp-record .phead-act { display: grid !important; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; width: 100%; }
html.odx-app .axp-record .phead-act .select { width: 100% !important; max-width: none; height: 40px; border-radius: 8px; }
html.odx-app .axp-record .cols { display: block; }
html.odx-app .axp-record .aside { display: none; }
html.odx-app .axp-record .panel { margin: 0 -16px; border: 0; border-radius: 0; background: transparent; }
html.odx-app .axp-record .panel-head { padding: 8px 16px; background: none; border: 0; }
html.odx-app .axp-record .panel-head h2 { font-size: calc(15px * var(--fs, 1)); }
/* D1 권장(signal)일 때만 — 해외 유리 칸의 청 틴트를 끈다(국내 유리 칸만 색). 기본(현행)은 웹과 같다. */
html.odx-app.odx-d1-signal .axp-record .c-o.bm.adv-for { background: none; }
/* [FIX V-01 2026-10-20] 배당률 적중 · 기대값(/odds-rate) — 종목 · 연도 · 리그 조건 줄(OddsRate.razor 앱 분기 .or-ctl). 웹의 종목 줄(.sports)은 앱에서
   숨어(앱-2) 종목을 바꿀 수 없었고, 연도 · 리그 select는 베젤 탭 줄 끝(390pt)에서 잘렸다 — 기록식(.axp-record)과 같은 문법으로 베젤 아래 한 줄에 셋. */
html.odx-app .or-ctl { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.3fr); gap: 8px; margin: 12px 0 10px; }
html.odx-app .or-ctl .select { width: 100%; max-width: none; height: 40px; border-radius: 8px; }
/* [FIX V-06 2026-10-20] 리그 페이지(/league/{name} — 정적 SSR 웹 표 그대로): 마지막 '공유' 칸은 앱에서 뺀다 — 390pt에서 오른쪽 끝에 잘린 '공' 한 글자만
   보였다(공유는 경기 시트 · 길게 누르기가 맡는다). 표는 화면 폭으로 펴서(좌우 16 회수) 팀 이름 줄바꿈을 줄인다. */
html.odx-app .lg-tbl :is(th, td):last-child { display: none; }
html.odx-app .panel:has(> .lg-tbl) { margin-left: -16px; margin-right: -16px; }
html.odx-app.odx-d1-signal .axp-record .c-o.bm.adv-for .o-now { color: var(--text); }

/* (k) PREMIUM TIP /tips(§5.3.13) — 시트와 같은 목록 문법, 고지는 맨 위 그대로. ── */
html.odx-app .axp-tips .notice { margin-top: 2px; border-radius: 10px; }
html.odx-app .axp-tiplist { margin: 0 -16px; border: 0; border-radius: 0; background: transparent; }
html.odx-app .axp-tiplist .tipmini { padding: 12px 16px; border-bottom: 0; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(255, 255, 255, .075); }
/* 줄 안의 모양(리그 눈금 · 보라 예상 이름표 · 무채 칩)은 PREMIUM TIP 시트와 같은 규칙(.tips-sheet — 앱-8b)을 그대로 쓴다. 여기서는 화면 폭 여백만. */

/* (l) 이용권 /pricing — 결제 비활성판(§5.3.10): 그라데이션 · 16 이상 반경 · 캡슐 · 그림자 없이. 가격 · CTA는 이 분기에 없다. ── */
html.odx-app .axp-pricing .pr-hero { margin: 12px 0 18px; padding: 18px 16px; text-align: left; border: 0; border-radius: 10px; background: var(--surface); }
html.odx-app .axp-pricing .pr-eyebrow { display: none; }
html.odx-app .axp-pricing .pr-hero h1 { margin: 0; font-size: calc(19px * var(--fs, 1)); font-weight: 700; }
html.odx-app .axp-pricing .pr-lede { margin: 6px 0 0; font-size: calc(13.5px * var(--fs, 1)); line-height: 1.6; }
html.odx-app .axp-pricing .pr-lede .mono { white-space: nowrap; }   /* [FIX DF-17] 'D-30'이 하이픈에서 끊기지 않게 */
html.odx-app .axp-pricing .pr-sec { margin-top: 22px; }
html.odx-app .axp-pricing .pr-h2 { margin: 0 4px 7px; font-size: calc(12px * var(--fs, 1)); font-weight: 500; color: var(--text-3); letter-spacing: 0; }
html.odx-app .axp-pricing .panel { border: 0; border-radius: 10px; }
html.odx-app .axp-pricing .tbl td { height: 48px; font-size: calc(14px * var(--fs, 1)); }
html.odx-app .axp-pricing .pr-plans { grid-template-columns: minmax(0, 1fr); gap: 12px; }
html.odx-app .axp-pricing .pr-card { padding: 16px 14px; border: 0; border-radius: 10px; box-shadow: none; transition: none; }
html.odx-app .axp-pricing .pr-card:hover { box-shadow: none; }
html.odx-app .axp-pricing .pr-card.is-current { box-shadow: inset 0 0 0 1px var(--line-strong); }
html.odx-app .axp-pricing .pr-card-head h2 { font-size: calc(17px * var(--fs, 1)); font-weight: 700; }
html.odx-app .axp-pricing .pr-desc { min-height: 0; }

/* (m) 고객센터 /support(§5.3.12) — 하위 화면 베젤 + 베젤 탭, FAQ = 그룹 목록 아코디언(질문 15/550 · 답 13.5/1.7). ── */
html.odx-app .axp-support .cols { display: block; }
html.odx-app .axp-support .aside { display: none; }
html.odx-app .axp-support .panel { border: 0; border-radius: 10px; }
html.odx-app .axp-support .panel + .panel { margin-top: 18px; }
html.odx-app .axp-support .panel-head { min-height: 0; padding: 12px 14px 6px; background: none; border: 0; }
html.odx-app .axp-support .panel-head h2 { font-size: calc(13px * var(--fs, 1)); font-weight: 600; color: var(--text-2); }
html.odx-app .axp-support .faq li { border-bottom: 0; box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(255, 255, 255, .075); }
html.odx-app .axp-support .faq li:last-child { box-shadow: none; }
html.odx-app .axp-support .faq .q { min-height: 48px; padding: 12px 14px; font-size: calc(15px * var(--fs, 1)); font-weight: 550; line-height: 1.45; }
html.odx-app .axp-support .faq .q .qm { display: none; }
/* [FIX V-05] FAQ 검색 줄 — 검색 상자는 화면 폭(웹의 260 고정 폭은 앱에서 반쪽이었다), 베젤 탭 밑줄과 12 띄운다. */
html.odx-app .axp-support .row.between.wrap { margin-top: 12px; row-gap: 8px; }
html.odx-app .axp-support .row.between.wrap > .searchbox { width: 100% !important; }
html.odx-app .axp-support .faq .a { padding: 0 14px 14px; font-size: calc(13.5px * var(--fs, 1)); line-height: 1.7; }
/* [APP-MOTION §3.2(b)] FAQ 셰브런 — ▾ 글자를 chevron-down 마스크로(14 --text-4), 펼치면 180°(aria-expanded — Support · Pricing 앱 분기). 누름 = 면 즉시. */
html.odx-app :is(.axp-support, .axp-pricing) .faq .q .ch {
    flex: none; width: 14px; height: 14px; margin-left: auto; font-size: 0; line-height: 0; color: transparent; background: var(--text-4);
    -webkit-mask: url(app-icons/chevron-down.svg) center / 14px 14px no-repeat; mask: url(app-icons/chevron-down.svg) center / 14px 14px no-repeat;
    transition: transform 200ms var(--ease-out);
}
html.odx-app :is(.axp-support, .axp-pricing) .faq .q[aria-expanded="true"] .ch { transform: rotate(180deg); }
html.odx-app :is(.axp-support, .axp-pricing) .faq .q:hover { background: transparent; }
html.odx-app :is(.axp-support, .axp-pricing) .faq .q[data-odx-press="on"] { background: var(--surface-2); }
html.odx-app .axp-support .blist a { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "cat dt" "ti ti"; row-gap: 3px; padding: 12px 14px; }
html.odx-app .axp-support .blist .bcat { grid-area: cat; display: block; width: auto; font-size: 11.5px; color: var(--text-2); font-weight: 650; }
html.odx-app .axp-support .blist .bmeta { grid-area: dt; justify-self: end; }
html.odx-app .axp-support .blist .bmeta .au,
html.odx-app .axp-support .blist .bmeta .vw { display: none; }
html.odx-app .axp-support .blist .bti { grid-area: ti; white-space: normal; font-size: calc(15px * var(--fs, 1)); line-height: 21px; word-break: keep-all; }
html.odx-app .axp-support .blist .bti .new { display: none; }

/* (n) 문서(약관 · 개인정보처리방침 · 환불 규정, §5.3.12) — 15/1.75, 좌우 20. 글자는 한 자도 바꾸지 않는다(모양만). ── */
html.odx-app .cols.narrow .doc { font-size: calc(15px * var(--fs, 1)); line-height: 1.75; }
html.odx-app .cols.narrow .doc h2 { font-size: calc(16px * var(--fs, 1)); }
html.odx-app .cols.narrow .doc h3 { font-size: calc(15px * var(--fs, 1)); }

/* (o) 로그인 · 가입 · 계정 화면(§5.3.11, AuthLayout 정적 SSR) — 카드 테두리 없는 전폭, 입력 48 · 16px, 주 버튼 = 액센트. ── */
html.odx-app .auth { display: block; min-height: 0; padding: 12px 0 28px; }   /* [INT] 좌우 여백은 바깥 .wrap 16(§2.4)이 준다 — 16+16=32 겹침 제거 */
html.odx-app .auth-card { width: 100%; }
html.odx-app .auth-card > .logo { display: none; }
html.odx-app .auth-title { display: none; }
html.odx-app .auth-lede { text-align: left; margin: 2px 0 16px; font-size: calc(13.5px * var(--fs, 1)); }
html.odx-app .auth-box { padding: 0; background: none; border: 0; border-radius: 0; }
html.odx-app .auth .input, html.odx-app .auth .select { height: 48px; border-radius: 8px; }
html.odx-app .auth .btn-lg, html.odx-app .auth .btn-block { min-height: 48px; border-radius: 8px; }
html.odx-app .auth-alt { font-size: calc(13.5px * var(--fs, 1)); }
html.odx-app .auth-alt a { display: inline-flex; align-items: center; min-height: 44px; }
html.odx-app .auth-legal { text-align: left; font-size: calc(13px * var(--fs, 1)); line-height: 1.6; }

/* (p) 푸터(§5.2.2) — 앱은 사업자정보 · 약관 · 합법 이용 안내만, 13/1.6. 서비스 소개 · 탐색 링크는 탭바가 맡는다. ── */
html.odx-app .foot { padding-top: 18px; font-size: calc(13px * var(--fs, 1)); background: transparent; border-top: 0; box-shadow: inset 0 var(--hair-w, 1px) 0 rgba(255, 255, 255, .075); }
html.odx-app .foot-top { padding-bottom: 10px; border-bottom: 0; }
html.odx-app .foot-brand,
html.odx-app .foot-links section:not(.foot-terms) { display: none; }
html.odx-app .foot-links { display: block; }
html.odx-app .foot-terms h4 { display: none; }
html.odx-app .foot-terms ul { display: flex; flex-wrap: wrap; gap: 0 16px; }
html.odx-app .foot-terms li + li { margin-top: 0; }
html.odx-app .foot-terms a { display: inline-flex; align-items: center; min-height: 44px; color: var(--text-3); }   /* [FIX DF-04] 터치 44 */
html.odx-app .foot-legal { padding-top: 6px; font-size: calc(12px * var(--fs, 1)); line-height: 1.6; }
html.odx-app .foot-disc { margin-top: 12px; font-size: calc(12.5px * var(--fs, 1)); line-height: 1.6; }
/* [INT] 앱 푸터의 합법 이용 안내는 상자 없이 한 단락(그림 10 — 색은 뜻일 때만: 황색 경고 띠 · 면을 쓰지 않는다). 고지 문단(정보 제공 · 무보장)은
   [FIX L2] 웹과 같이 그대로 그린다(Release-1 출력 — 법적 고지는 §9-20 '베팅' 0의 예외, SiteFooter 주석). */
html.odx-app .foot-disc { padding: 0; border: 0; border-radius: 0; background: none; }
html.odx-app .foot-disc .legal-use.compact { margin-top: 8px; font-size: calc(12.5px * var(--fs, 1)); line-height: 1.6; }   /* [FIX L2] 위 고지 문단과 한 줄 띄운다 */

/* (q) 리그 /leagues(§5.3.13, 다른 세션 화면 — CSS만) — 종목 머리 + 그룹 목록(이름 · 약칭 · 경기 수 ›). ── */
html.odx-app .lg-sec { margin: 0 0 18px; padding: 0; border: 0; background: transparent; }
html.odx-app .lg-sec h2 { margin: 14px 4px 7px; font-size: calc(12px * var(--fs, 1)); font-weight: 500; color: var(--text-3); }
html.odx-app .lg-sec h2 svg { width: 14px; height: 14px; }
html.odx-app .lg-list { display: block; border-radius: 10px; background: var(--surface); overflow: hidden; }
html.odx-app .lg-list li { margin: 0; }
html.odx-app .lg-list a {
    min-height: 48px; padding: 10px 14px; border: 0; border-radius: 0; background: none; gap: 10px;
    box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(255, 255, 255, .075);
}
html.odx-app .lg-list li:last-child a { box-shadow: none; }
html.odx-app .lg-list a:hover { background: none; }
html.odx-app .lg-list a[data-odx-press="on"] { background: var(--surface-2); }   /* 누름 모듈(APP-MOTION M02) */
html.odx-app .lg-list .nm { font-size: calc(15px * var(--fs, 1)); font-weight: 550; }
html.odx-app .lg-list .lb { font-size: calc(12px * var(--fs, 1)); }
html.odx-app .lg-list .n { font-size: calc(13px * var(--fs, 1)); }
html.odx-app .lg-list a::after {
    content: ""; flex: none; width: 14px; height: 14px; margin-right: -2px; background: var(--text-4);
    -webkit-mask: url(app-icons/chevron-right.svg) center / 14px 14px no-repeat; mask: url(app-icons/chevron-right.svg) center / 14px 14px no-repeat;
}

/* 라이트 테마 — 헤어라인 색만 바뀐다. */
html.odx-app[data-theme="light"] .axl-r:not(:last-child)::after { background: rgba(0, 0, 0, .09); }
html.odx-app[data-theme="light"] :is(.axp-noti .notilist li, .axp-dm .adm-nav a, .axp-dm .cmt, .axp-comm .blist li, .axp-post .cmt, .axp-tiplist .tipmini, .axp-support .faq li:not(:last-child), .lg-list li:not(:last-child) a) { box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(0, 0, 0, .09); }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) .axl-r:not(:last-child)::after { background: rgba(0, 0, 0, .09); }
    html.odx-app:not([data-theme]) :is(.axp-noti .notilist li, .axp-dm .adm-nav a, .axp-dm .cmt, .axp-comm .blist li, .axp-post .cmt, .axp-tiplist .tipmini, .axp-support .faq li:not(:last-child), .lg-list li:not(:last-child) a) { box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 rgba(0, 0, 0, .09); }
}
html.odx-app[data-theme="light"] .axp-post .panel + .panel,
html.odx-app[data-theme="light"] .foot { box-shadow: inset 0 var(--hair-w, 1px) 0 rgba(0, 0, 0, .09); }
@media (prefers-color-scheme: light) {
    html.odx-app:not([data-theme]) .axp-post .panel + .panel,
    html.odx-app:not([data-theme]) .foot { box-shadow: inset 0 var(--hair-w, 1px) 0 rgba(0, 0, 0, .09); }
}

/* [FIX DF-11] 발송 미리보기 배너 — 라이트에서 --surface-3(#e9edf1)은 페이지 바탕(#eceef1)과 3단계 차이라 카드가 사라졌다. 흰 면으로. */
html.odx-app[data-theme="light"] .axp-pv { background: var(--surface); }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .axp-pv { background: var(--surface); } }
/* [FIX DF-18] 라이트 인셋 그룹 목록 = #fff on #f2f3f6(§2.1 · §3.14). 그룹 목록이 첫 자식인 화면의 본문만(요소 자신 기준의 짧은 :has — 루트 :has 아님). */
html.odx-app[data-theme="light"] .main:has(> .wrap.axp > :is(.axl-g, .axl-h):first-child) { background: #f2f3f6; }
@media (prefers-color-scheme: light) { html.odx-app:not([data-theme]) .main:has(> .wrap.axp > :is(.axl-g, .axl-h):first-child) { background: #f2f3f6; } }
/* [FIX DF-08] 한글이 든 상대 시각('5시간 전' · '1일 전')은 고정폭 런에 넣지 않는다(§2.3) — UI 글꼴 + 숫자 폭 고정. */
html.odx-app :is(.axp-comm .blist .bmeta .dt, .axp-noti .nt-head .nt-dt, .axp-dm .adm-nav a > .n, .axp-post .post-meta > .mono, :is(.axp-post, .axp-dm) .cmt .dt) {
    font-family: var(--font); font-variant-numeric: tabular-nums; letter-spacing: 0;
}
/* [FIX DF-15] Android 스위치 = M3(§3.14): 트랙 52×32 · 꺼짐 2pt 테두리 + 손잡이 16(같은 24 손잡이를 scale .667 — transform만 움직인다) ·
   켜짐 손잡이 24 흰색. 켜짐 색은 #3a9b6f 그대로. 목록 안(.axl-g) 규칙보다 특정하게 :is로 묶는다. */
html.odx-app-android.odx-app :is(.switch, .axl-g .switch) .track { width: 52px; height: 32px; border-radius: 16px; box-shadow: inset 0 0 0 2px var(--text-4); }
html.odx-app-android.odx-app :is(.switch, .axl-g .switch) .track::after { top: 4px; left: 4px; width: 24px; height: 24px; border-radius: 12px; background: var(--text-3); transform: scale(.667); }
html.odx-app-android.odx-app :is(.switch, .axl-g .switch) input:checked + .track { box-shadow: none; }
html.odx-app-android.odx-app :is(.switch, .axl-g .switch) input:checked + .track::after { background: #fff; transform: translateX(20px); }

/* (b5) 회원 차단 · 신고 [B5] — 2026-10-11(App Store 1.2 · Google Play UGC). 내정보 › 차단 목록 줄 아이콘(app-icons/block.svg),
   글 보기의 가려진 댓글 한 줄(차단한 회원의 댓글 — 본문 크기·색을 낮춘다). 확인 시트는 로그아웃과 같은 .axp-confirm을 그대로 쓴다. */
html.odx-app .i-block { -webkit-mask-image: url(app-icons/block.svg); mask-image: url(app-icons/block.svg); }
html.odx-app .axp-post .cmt-masked .cmt-body { font-size: calc(13.5px * var(--fs, 1)); color: var(--text-3); }
html.odx-app :is(.axp-blknote, .axp-blk p) { word-break: keep-all; }

/* (r) 작은 목록 펼침(APP-MOTION M10) — 알림함 본문 · 고객센터 · 이용권 FAQ 답 · 내 조합 영수증. Blazor가 본문을 넣으면 0fr → 1fr(220ms)로
   아래 줄을 밀며 열린다(레이아웃 애니메이션 허용 상한: 이 네 목록만 — 본문 ≤ 600px · 목록 ≤ 60줄). 안쪽 래퍼 .odx-dz(Razor 앱 분기)가
   원래의 여백을 진다(0fr에서도 바깥 여백이 남아 튀지 않게). 접힘은 브리지가 160ms로 접은 뒤 같은 토글을 다시 누른다(P1).
   내 조합의 첫 영수증(진입 때 열려 있는 것 — 프리렌더되는 첫 내용)은 펼치지 않는다(data-odx-first, 사용자가 토글하면 그 요소와 함께 사라진다).
   iOS 15.x는 grid-template-rows 보간이 없을 수 있다(추론) → 즉시 열림. */
@keyframes odx-rows { from { grid-template-rows: 0fr; opacity: 0; } }
html.odx-app :is(.axp-noti .nt-body, .axp-support .faq .a, .axp-pricing .faq .a, .myslips .slipdetail) {
    display: grid; grid-template-rows: 1fr; padding: 0; animation: odx-rows var(--t-rise, 220ms) var(--ease-out) backwards;
}
html.odx-app :is(.axp-noti .nt-body, .axp-support .faq .a, .axp-pricing .faq .a, .myslips .slipdetail) > .odx-dz { min-height: 0; overflow: hidden; }
html.odx-app .axp-noti .nt-body > .odx-dz { padding: 0 16px 16px 30px; }
html.odx-app .axp-support .faq .a > .odx-dz { padding: 0 14px 14px; }
html.odx-app .axp-pricing .faq .a > .odx-dz { padding: 0 13px 15px 41px; }
html.odx-app .myslips .slipdetail > .odx-dz { padding: 12px 12px 10px; }
html.odx-app .myslips .slipdetail[data-odx-first] { animation: none; }
@media (prefers-reduced-motion: reduce) {
    html.odx-app :is(.axp-noti .nt-body, .axp-support .faq .a, .axp-pricing .faq .a, .myslips .slipdetail) { animation: none; }
    html.odx-app :is(.axp-noti .nt-head, .faq .q) .ch { transition: none; }
}
html.odx-app[data-odx-motion="reduced"] :is(.axp-noti .nt-body, .axp-support .faq .a, .axp-pricing .faq .a, .myslips .slipdetail) { animation: none; }
html.odx-app[data-odx-motion="reduced"] :is(.axp-noti .nt-head, .faq .q) .ch { transition: none; }
/* ── /앱-10b ── */

/* ── 앱-11 폼 [B1] ── §5.3 폼 규칙 */
/*  폼 규칙(§5.3.8 · §5.3.11 · §5.3.12) — 라벨 위 · 입력 48 높이 · 글자 16px 이상(W1 — iOS 포커스 확대 방지) · 반경 8.
    주 버튼은 폼 화면이라 웹 그대로 .btn-primary(액센트)이고, 블록 · 큰 버튼은 50 높이(터치 44 이상). 크기만 바꾼다 — 색 · 문구는 웹 그대로.
    입력 높이는 폼 자리(.field · 계정 화면 · 글쓰기)에만 건다 — 보드 레일 · 필터 시트의 검색칸은 그 화면 블록이 정한다. */
html.odx-app .field { margin-bottom: 16px; }
html.odx-app .field > label,
html.odx-app .flabel { margin-bottom: 8px; font-size: calc(13px * var(--fs, 1)); }
html.odx-app :is(.field, .auth-box) :is(.input, .select) { height: 48px; padding: 0 14px; border-radius: 8px; }
html.odx-app :is(.field, .auth-box) .select { padding-right: 32px; background-position: calc(100% - 19px) 21px, calc(100% - 14px) 21px; }
html.odx-app :is(.field, .auth-box) .textarea { padding: 12px 14px; border-radius: 8px; }
html.odx-app .fhelp,
html.odx-app .ferr { font-size: calc(12.5px * var(--fs, 1)); line-height: 1.55; }
html.odx-app :is(.btn-block, .btn-lg) { height: 50px; border-radius: 8px; font-size: calc(15.5px * var(--fs, 1)); font-weight: 700; }
html.odx-app .btn-block.btn-sm { height: 44px; font-size: calc(14px * var(--fs, 1)); }

/*  계정 화면(AuthLayout — 정적 SSR)의 카드 · 소셜 버튼 · 약관 안내 모양은 앱-10b (o)가 정한다(한 벌만 둔다). 베젤(‹ + 가운데 제목)은 앱-3. */
/* ── /앱-11 ── */

/* ── 앱-12 모션 [B1] ── §4(곡선 · 모션 표 · 동작 줄이기) */
/*  모션(§4) — 셸 몫. 움직임은 transform/opacity만, 무한 반복 없음. 곡선 · 길이는 앱-1 변수(네이티브와 같은 값).
    브리지가 WAAPI로 그리는 것: 경로 전환(main .6→1 120ms) · 낙관적 시트 틀 · 시트 닫힘(240ms) · 끌어내림 되돌림(200ms) · 배당 틱 섬광 ·
    밀어서 빼기 · 토스트. CSS 삽입 애니메이션: 시트 등장(앱-8a) · 메뉴 등장 · 베젤 접힘 글자(앱-3).
    동작 줄이기(§4.4): OS 설정(prefers-reduced-motion) 또는 네이티브 prefs.motion='reduced'(브리지 → html[data-odx-motion="reduced"]) —
    이동 · 확대 · 굴림 · 섬광 · 비행을 끄고 120ms 불투명도만 남긴다(브리지도 같은 판정). 보드 · 슬립 몫은 각 블록이 같은 두 선택자로 끈다. */
@media (prefers-reduced-motion: reduce) {
    html.odx-app :is(.ax-panel, .modal-veil > .modal, .ax-menu) { animation: ax-fade-in 120ms linear backwards; }
    html.odx-app :is(.ax-scrim, .ax-menu-veil) { animation-duration: 120ms; }
    html.odx-app .ax-switch .ax-i { transition: none; }
}
html.odx-app[data-odx-motion="reduced"] :is(.ax-panel, .modal-veil > .modal, .ax-menu) { animation: ax-fade-in 120ms linear backwards; }
html.odx-app[data-odx-motion="reduced"] :is(.ax-scrim, .ax-menu-veil) { animation-duration: 120ms; }
html.odx-app[data-odx-motion="reduced"] .ax-switch .ax-i { transition: none; }

/*  밀어서 빼기(§3.11): 가로 끌기를 브라우저 제스처가 가져가지 않게(세로 스크롤은 그대로). 브리지가 .sw-row에 transform을 쓴다. */
html.odx-app [data-odx-swipe] .sw-row { touch-action: pan-y; }

/*  ── 모션 · 가시성 2차(docs/app/APP-MOTION.md — 이 문서가 §4 모션 표를 대체하는 줄에서는 그것이 정본) ──
    어휘(§1-4): 새 층 = 아래에서 올라옴 · 옆자리 = 10–12px 옆으로 + 페이드 · 안쪽이 드러남 = 6px 오름(≤ 5덩이 · 30ms 간격) ·
    값 변화 = 굴림(방향 = 값의 방향) · 계기 · 섬광 · 내 손이 닿음 = .97 눌림 + 면 틴트. 움직이는 속성은 transform · opacity뿐(예외: M10 네 목록의
    grid-template-rows · 킥오프 접힘 · 국내 유리 틴트 한 칸). 프리렌더되는 내용(보드 행 · 칸 · 꼬리표 · 구획 머리 · 계산기 행)에는 CSS 삽입
    애니메이션을 걸지 않는다(회로 시작 때 노드가 바뀌어 한 번 더 돈다 — 실측). 그런 것은 브리지 WAAPI가 보이는 것만 움직인다. */
@keyframes odx-rise { from { opacity: 0; transform: translateY(6px); } }    /* M03 시트 덩이 · 모달 */
@keyframes odx-rise4 { from { opacity: 0; transform: translateY(4px); } }   /* M11 큰 목록 드러남 */
@keyframes odx-sweep { from { transform: scaleX(0); } }                     /* M04 계기 그어짐 */

/*  누름(M01 · M02) — 브리지 누름 모듈이 누르는 것에 data-odx-press="on|off"를 쓴다(60ms 의도 지연 · 8px 움직이거나 스크롤이면 취소 ·
    60ms보다 빠른 탭도 한 번은 on). 칸(앱-6 · 앱-9) · 단단한 버튼(앱-8b · 앱-9 · 앱-10a) · 목록 줄(앱-8b · 앱-10b)은 각 블록에,
    칩 · 테두리 · 원 버튼의 공용 규칙은 여기. 들어감 80ms(--t-press) · 복귀 160ms(--ease-press — 넘침 없는 스프링 근사). */
html.odx-app :is(.axb-chip, .axb-seg2 > button, .axp-chip, .board.bi .m-star, .board.bi .m-tag :is(.badge-value, .bi-why, .bi-verdict)) { transition: transform var(--t-release, 160ms) var(--ease-press); }
html.odx-app :is(.axb-chip, .axb-seg2 > button, .axp-chip, .board.bi .m-star, .board.bi .m-tag :is(.badge-value, .bi-why, .bi-verdict))[data-odx-press="on"] { transform: scale(.96); transition-duration: var(--t-press, 80ms); }
/*  베젤 탭(마켓 · 하위 탭)의 글자색은 즉시 바뀐다 — 바뀜은 밑줄 미끄러짐(M07, 합성) 하나가 말한다. 웹 .subnav 규칙의 color .12s 전이가
    밑줄 옆에서 메인 스레드 재계산 · 페인트를 20프레임 냈다(리뷰 PERF-5). 앱 범위라 웹은 그대로. */
html.odx-app .subnav .wrap > :is(.mk, .axp-tab, a, button) { transition: none; }

/*  코치 마크(§3.3 · M24) — 브리지 소유 노드(<body> 끝, 토스트와 같은 생명주기). 처음 쓰는 사람에게 누를 곳을 한 번씩 짚는 말풍선(최대 3개 · 1회).
    잉크(무채) 말풍선 + 앵커를 3px 넓힌 링. 그림자 · 딤 · 구멍 뚫린 막 · 맥박 없음. z 100(모달 층 — 새 값 아님). 누르기는 통과한다
    (어디든 누르면 사라지고 그 누름은 그대로 동작한다). 큰 글자(--fs)를 따른다. */
html.odx-app .odx-coach { position: fixed; inset: 0; z-index: 100; pointer-events: none; }   /* 비어 있어도 트리에 남는다(live region — 토스트 RV-WEB-6과 같은 이유) */
html.odx-app .odx-coach-ring { position: absolute; border-radius: 9px; box-shadow: inset 0 0 0 1.5px var(--ink); }
html.odx-app .odx-coach-tip {
    position: absolute; max-width: min(280px, calc(100vw - 32px)); padding: 10px 12px; border-radius: 10px;
    background: var(--ink); color: var(--ink-text); font-size: calc(13px * var(--fs, 1)); line-height: 1.45; font-weight: 550;
    word-break: keep-all; line-break: strict;
}
html.odx-app .odx-coach-ar { position: absolute; width: 10px; height: 10px; background: var(--ink); transform: rotate(45deg); }
/*  줄 길이를 고르게(지원하는 WebView만 — 문구 쪽은 두 낱말 항목을 줄바꿈 없는 공백으로 묶었다, 리뷰 DF-7). */
@supports (text-wrap: balance) { html.odx-app .odx-coach-tip > span { text-wrap: balance; } }

/*  동작 줄이기(M01–M24 묶음) — 두 근원(OS prefers-reduced-motion · 네이티브 prefs.motion → html[data-odx-motion="reduced"]) 모두에.
    누름은 속성은 쓰되 크기를 끈다(틴트 · 면만). 삽입 애니메이션(덩이 · 계기 · 펼침 · 드러남)은 각 블록이 끄고, 면의 120ms 페이드만 남는다. */
@media (prefers-reduced-motion: reduce) {
    html.odx-app [data-odx-press] { transform: none !important; }
    html.odx-app .ax-sheet :is(.fs-head, .fs-scroll, .ls-body, .ls-foot),
    html.odx-app .modal-veil > .modal > :is(.modal-head, .modal-body) { animation: none; }
}
html.odx-app[data-odx-motion="reduced"] [data-odx-press] { transform: none !important; }
/*  앱 설정만 줄인 경우(OS는 그대로)에도 누름의 복귀 페이드(틴트 · 불투명도 160ms)를 120ms 안으로 — OS 쪽은 전역 .01ms 규칙이 이미 접는다(리뷰 RG-9). */
html.odx-app[data-odx-motion="reduced"] [data-odx-press="off"],
html.odx-app[data-odx-motion="reduced"] [data-odx-press="off"]::before { transition-duration: var(--t-fade, 120ms) !important; }
html.odx-app[data-odx-motion="reduced"] .ax-sheet :is(.fs-head, .fs-scroll, .ls-body, .ls-foot),
html.odx-app[data-odx-motion="reduced"] .modal-veil > .modal > :is(.modal-head, .modal-body) { animation: none; }
/* ── /앱-12 ── */

/* ── 앱-13a 결정 스위치 D1–D3 [B2] ── §8(html.odx-d1-signal · .odx-d2-solid · .odx-d3-mono — 클래스가 있을 때만 걸리는 덮어쓰기) */
/* 클래스가 없으면(기본 = 현행 — 08-26 · 09-02 의뢰인 승인 표현) 이 블록은 아무것도 하지 않는다. 클래스는 App.razor가 App:Look:* 설정으로 서버 렌더한다.
   D1 signal: 국내 숫자 무채 · 해외 평균 회색 · 적색은 국내 유리 칸과 양수 차이율에만(해외 유리 칸 청 틴트 · 청 숫자 없음). */
html.odx-app.odx-d1-signal .board.bi .bi-o.dom.adv-for { background: none; }
html.odx-app.odx-d1-signal .board.bi .bi-o.dom.adv-for .o-now { color: var(--text); }
html.odx-app.odx-d1-signal .board.bi .bi-o.dom.clickable.adv-for:hover { background: none; }
html.odx-app.odx-d1-signal .board.bi .bi-o.for .o-now.o-avg-all { color: var(--text-3); }
html.odx-app.odx-d1-signal .ms-sum .dom > .advf { color: var(--text); }
html.odx-app.odx-d1-signal .ms-sum .fo.avg > :not(:first-child) { color: var(--text-2); }

/* D2 solid: PREMIUM TIP 행 = 단색 1.5pt 보라 틀, 배경 · 링 애니메이션 없음. */
html.odx-app.odx-d2-solid .board.bi .mrow.is-tip { background: none; box-shadow: inset 0 0 0 1.5px var(--tippick); }
html.odx-app.odx-d2-solid .board.bi .mrow.is-tip::after { content: none; animation: none; }

/* D3 mono: 동일배당 막대 = 그 자리 결과만 잉크, 나머지 --line-strong(색 범례 칩도 뺀다). 자리별 줄은 조회한 자리(.me),
   '모두 일치' 막대는 시트에서 누른 칸의 자리(.ms-body[data-q]). */
html.odx-app.odx-d3-mono .msheet :is(.so-single-bar, .sobar) i { background: var(--line-strong); }
html.odx-app.odx-d3-mono .msheet .so-single:has(.so-single-dist > span.me:first-child) .b-h,
html.odx-app.odx-d3-mono .msheet .so-single:has(.so-single-dist > span.me:nth-child(2):not(:nth-last-child(2))) .b-d,
html.odx-app.odx-d3-mono .msheet .so-single:has(.so-single-dist > span.me:nth-last-child(2)) .b-a { background: var(--ink, var(--text)); }
html.odx-app.odx-d3-mono .msheet .ms-body[data-q="h"] .so-combo .sobar .b-h,
html.odx-app.odx-d3-mono .msheet .ms-body[data-q="d"] .so-combo .sobar .b-d,
html.odx-app.odx-d3-mono .msheet .ms-body[data-q="a"] .so-combo .sobar .b-a,
html.odx-app.odx-d3-mono .msheet .ms-body[data-q="h"] .sostrip > .sobar .b-h,
html.odx-app.odx-d3-mono .msheet .ms-body[data-q="d"] .sostrip > .sobar .b-d,
html.odx-app.odx-d3-mono .msheet .ms-body[data-q="a"] .sostrip > .sobar .b-a { background: var(--ink, var(--text)); }
html.odx-app.odx-d3-mono .msheet .solegend .sw { display: none; }
/* ── /앱-13a ── */

/* ── 앱-13b 결정 스위치 D4 [B1] ── §8(html.odx-d4-light) */
/*  D4 선택안(§8 — App:Look:LightChrome=true → <html class="… odx-d4-light">): 라이트 테마일 때만 베젤 · 상태바 띠 · 보드 전환 메뉴를
    밝은 크롬 재질 rgba(249,250,251,.96) + 어두운 글자로. 다크 테마는 그대로(어두운 베젤). 클래스가 없으면(기본 = 현행) 아무것도 바뀌지 않는다.
    ⚠ 상태바 글자색(밝음/어두움)은 네이티브 몫인데 지금 브리지 신호가 없다 — 켜기 전에 네이티브 작업이 필요하다(통합 보고 열린 항목). */
html.odx-app.odx-d4-light[data-theme="light"] .site::after,
html.odx-app.odx-d4-light[data-theme="light"] .head::before,
html.odx-app.odx-d4-light[data-theme="light"] .subnav::before { background: rgba(249, 250, 251, .96); }
html.odx-app.odx-d4-light[data-theme="light"] .head::before,
html.odx-app.odx-d4-light[data-theme="light"] .subnav::before { box-shadow: inset 0 calc(-1 * var(--hair-w)) 0 rgba(0, 0, 0, .08); }
html.odx-app.odx-d4-light[data-theme="light"] .head:has(+ .subnav)::before { box-shadow: none; }
html.odx-app.odx-d4-light[data-theme="light"] :is(.ax-t, .ax-back) { color: #14181c; }
html.odx-app.odx-d4-light[data-theme="light"] :is(.ax-act, .ax-switch .ax-i) { color: #4b555f; }
html.odx-app.odx-d4-light[data-theme="light"] .subnav .wrap > :is(a, button) { color: #5f6973; }
html.odx-app.odx-d4-light[data-theme="light"] .subnav .wrap > :is(a, button).on { color: #14181c; }
html.odx-app.odx-d4-light[data-theme="light"] .subnav .wrap > :is(a, button) .n { color: #5f6973; }
html.odx-app.odx-d4-light[data-theme="light"] .ax-menu { background: #ffffff; box-shadow: inset 0 0 0 var(--hair-w) rgba(0, 0, 0, .09); }
html.odx-app.odx-d4-light[data-theme="light"] .ax-mi { color: #14181c; box-shadow: inset 0 calc(-1 * var(--hair-w)) 0 rgba(0, 0, 0, .09); }
html.odx-app.odx-d4-light[data-theme="light"] .ax-mi:last-child { box-shadow: none; }
html.odx-app.odx-d4-light[data-theme="light"] .ax-mi[data-odx-press="on"] { background: rgba(0, 0, 0, .05); }
html.odx-app.odx-d4-light[data-theme="light"] .ax-mi-tx > span { color: #5f6973; }
html.odx-app.odx-d4-light[data-theme="light"] .ax-lk { color: #4b555f; box-shadow: inset 0 0 0 1px #c3cbd4; }
/* [FIX DF-03] 밝은 베젤에서는 탭 밑줄 · 켜진 베젤 동작을 라이트 액센트로(어두운 베젤 값 #4d90d8은 기본 D4에서만). */
html.odx-app.odx-d4-light[data-theme="light"] .subnav .wrap > :is(a, button).on::after { background: var(--accent); }
html.odx-app.odx-d4-light[data-theme="light"] .axp-act.on { color: var(--accent); }
@media (prefers-color-scheme: light) {
    html.odx-app.odx-d4-light:not([data-theme]) .site::after,
    html.odx-app.odx-d4-light:not([data-theme]) .head::before,
    html.odx-app.odx-d4-light:not([data-theme]) .subnav::before { background: rgba(249, 250, 251, .96); }
    html.odx-app.odx-d4-light:not([data-theme]) .head::before,
    html.odx-app.odx-d4-light:not([data-theme]) .subnav::before { box-shadow: inset 0 calc(-1 * var(--hair-w)) 0 rgba(0, 0, 0, .08); }
    html.odx-app.odx-d4-light:not([data-theme]) .head:has(+ .subnav)::before { box-shadow: none; }
    html.odx-app.odx-d4-light:not([data-theme]) :is(.ax-t, .ax-back) { color: #14181c; }
    html.odx-app.odx-d4-light:not([data-theme]) :is(.ax-act, .ax-switch .ax-i) { color: #4b555f; }
    html.odx-app.odx-d4-light:not([data-theme]) .subnav .wrap > :is(a, button) { color: #5f6973; }
    html.odx-app.odx-d4-light:not([data-theme]) .subnav .wrap > :is(a, button).on { color: #14181c; }
    html.odx-app.odx-d4-light:not([data-theme]) .subnav .wrap > :is(a, button) .n { color: #5f6973; }
    html.odx-app.odx-d4-light:not([data-theme]) .subnav .wrap > :is(a, button).on::after { background: var(--accent); }
    html.odx-app.odx-d4-light:not([data-theme]) .axp-act.on { color: var(--accent); }
    html.odx-app.odx-d4-light:not([data-theme]) .ax-menu { background: #ffffff; box-shadow: inset 0 0 0 var(--hair-w) rgba(0, 0, 0, .09); }
    html.odx-app.odx-d4-light:not([data-theme]) .ax-mi { color: #14181c; box-shadow: inset 0 calc(-1 * var(--hair-w)) 0 rgba(0, 0, 0, .09); }
    html.odx-app.odx-d4-light:not([data-theme]) .ax-mi:last-child { box-shadow: none; }
    html.odx-app.odx-d4-light:not([data-theme]) .ax-mi[data-odx-press="on"] { background: rgba(0, 0, 0, .05); }
    html.odx-app.odx-d4-light:not([data-theme]) .ax-mi-tx > span { color: #5f6973; }
    html.odx-app.odx-d4-light:not([data-theme]) .ax-lk { color: #4b555f; box-shadow: inset 0 0 0 1px #c3cbd4; }
}
/* ── /앱-13b ── */

/* ── 앱-14 관리자(/admin) — 운영진이 폰으로 처리한다(2026-10-22 "앱 화면 폭에서 쓰기 불편") ──
   범위: Admin.razor 뿌리의 .adm-page(모바일 웹 §30과 같은 고리 — 이 블록은 html.odx-app 범위만, 넓은 웹 모양은 §14 · §23 그대로). 진입은 내정보 '관리자 페이지', 나가기는 베젤 '‹ 내정보'.
   · 13개 구획 내비: 웹 좁은 화면 규칙(§23 ≤1080)은 그룹 머리째 칩 덩어리로 펼쳐 첫 화면을 다 덮었다 → 베젤 아래 한 줄 가로 칩(보드 칩 .axb-chip과 같은 치수 · 켜짐 모양),
     그룹 머리 숨김, 베젤 밑에 붙는다(--stick). 켜진 칩이 보이게 하는 스크롤은 브리지가 아니라 사람이 한다(13개 — 한 번 밀면 다 보인다).
   · 머리(.phead): 앱 공통 규칙이 숨기지만 관리자에게는 '점검 중' · '수집 실시간' 배지가 필요하다 → 배지 줄만 살린다(제목은 베젤, '서비스 화면으로'는 '‹'가 대신).
   · 구획(.panel): 앱 공통 규칙(테두리 · 반경 0, 목록 화면 문법)을 되돌린다 — 관리자 화면은 판 여러 장이 쌓이는 구조라 경계가 있어야 읽힌다.
   · 타일: ≤420 한 줄(1열) 대신 2열 — 대시보드 숫자를 한 화면에.
   · 작은 단추(.btn-sm): 누르는 높이 34(손가락). 표는 .tablewrap이 이미 가로 스크롤한다. */
html.odx-app .adm-page > .phead { display: flex; margin: 10px 0 2px; }
html.odx-app .adm-page > .phead > div:first-child,
html.odx-app .adm-page > .phead .phead-act > a.btn { display: none; }
html.odx-app .adm-page > .phead .phead-act { flex-wrap: wrap; gap: 6px; }
html.odx-app .adm-page > .phead .phead-act:not(:has(.badge)) { display: none; }
html.odx-app .adm-page > .adm { display: block; }
html.odx-app .adm-page > .adm > .adm-nav {
    position: sticky; top: var(--stick); z-index: 6;
    display: flex; flex-wrap: nowrap; align-items: center; gap: 6px; max-height: none;
    margin: 0 -16px 12px; padding: 8px 16px; border: 0; border-radius: 0;
    overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: none; -webkit-overflow-scrolling: touch;
    background: var(--bg); box-shadow: inset 0 calc(-1 * var(--hair-w, 1px)) 0 var(--line-soft);
}
html.odx-app .adm-page > .adm > .adm-nav::-webkit-scrollbar { display: none; }
html.odx-app .adm-page > .adm > .adm-nav :is(h5, .sep) { display: none; }
html.odx-app .adm-page > .adm > .adm-nav a {
    flex: none; gap: 5px; height: 32px; padding: 0 11px; border-radius: 6px;
    background: none; box-shadow: inset 0 0 0 1px var(--line);
    font-size: calc(13px * var(--fs, 1)); font-weight: 550; color: var(--text-2); white-space: nowrap;
}
html.odx-app .adm-page > .adm > .adm-nav a.on { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); font-weight: 650; }
html.odx-app .adm-page > .adm > .adm-nav a .n { font-size: calc(11px * var(--fs, 1)); color: var(--text-3); }
html.odx-app .adm-page .panel { border: 1px solid var(--line); border-radius: 10px; }
html.odx-app .adm-page .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
html.odx-app .adm-page .btn-sm { min-height: 34px; }
/* ── /앱-14 ── */
