/* Alpine 초기화 전 깜빡임 방지. 이 규칙이 없으면 x-cloak 이 무의미하다. */
[x-cloak] { display: none !important; }

/* 메뉴 · CI 자리. **웹페이지 아이콘과 같은 그림**을 쓴다 (2026-10-13 지시 ·
   `static/icons/icon.svg`). 점선 칸으로 자리만 잡아 두던 그때의 크기를 그대로 지킨다 —
   크기가 바뀌면 띠 높이가 바뀌어 그 아래 고정된 것들이 함께 밀린다. */
.nav-ci { display: block; width: 1.75rem; height: 1.75rem; flex: none; }

/* 메뉴 · 모바일 옆 패널 폭 (2026-10-13 지시 · Bootstrap 기본 400px → 250px).
   **이 패널만** 좁힌다 — `.offcanvas` 에 걸면 앞으로 생길 다른 패널도 따라 좁아진다.
   화면이 이보다 좁으면 Bootstrap 의 `max-width: 100%` 가 화면 폭에 맞춘다. */
#gnb { --bs-offcanvas-width: 250px; }

/* 메뉴 · 로그아웃 단추 (2026-10-13 · 통합 로그인 공통 표준 — 하이라이트 블루).
   **서비스마다 같은 색이다** — 크기만 그 서비스의 단추 규격(`btn-sm`)을 따른다. */
.btn.btn-logout { background: #1a73e8; border-color: #1a73e8; color: #ffffff; font-weight: 500; }
.btn.btn-logout:hover,
.btn.btn-logout:active { background: #1765cc; border-color: #1765cc; color: #ffffff; }
.btn.btn-logout:focus-visible { outline: 2px solid #1a73e8; outline-offset: 2px; }

/* 최소한만 둔다. 나머지는 Bootstrap 을 그대로 쓴다. */
.ball {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.2rem; height: 2.2rem; border-radius: 50%;
  font-weight: 600; font-size: .95rem; color: #fff;
}
.ball-1  { background: #fbc400; }   /*  1~10 */
.ball-11 { background: #69c8f2; }   /* 11~20 */
.ball-21 { background: #ff7272; }   /* 21~30 */
.ball-31 { background: #aaa; }      /* 31~40 */
.ball-41 { background: #b0d840; }   /* 41~45 */
.ball-bonus { outline: 2px dashed #adb5bd; outline-offset: 2px; }

.num-list { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.plus { color: #adb5bd; font-weight: 600; }

/* 통계 요약 — 캡션 길이와 무관하게 공 간격을 일정하게 유지한다. */
.stat-item {
  display: inline-flex; flex-direction: column; align-items: center;
  min-width: 2.6rem;
}
.stat-cap {
  font-size: .7rem; line-height: 1.4; color: #6c757d;
  font-variant-numeric: tabular-nums;
}

/* 업로드 · 사진 고르기 영역. 등록 버튼보다 먼저 눈에 들어와야 한다. */
.border-dashed { border-style: dashed !important; }
.picker-drop { cursor: pointer; transition: background-color .12s, border-color .12s; }
.picker-drop:hover { background-color: var(--bs-tertiary-bg); border-color: var(--bs-primary) !important; }

/* 업로드 · 썸네일 목록 */
.thumb-box { aspect-ratio: 14 / 5; background: var(--bs-tertiary-bg); cursor: pointer; overflow: hidden; }
.thumb-box img { width: 100%; height: 100%; object-fit: contain; display: block; }
.thumb-box:hover img { opacity: .85; }

/* 화면 뼈대 — 모든 화면이 같은 것을 쓴다 (CLAUDE.md 13-1 · 2026-09-18 확정)

     .topbar   메뉴 + 오류.  `base.html` 이 갖는다. 어느 화면에나 같은 것이 붙는다
     .fnbar    기능.         페이지가 갖는다. 화면마다 다르다

   도는 일은 스크롤을 내려도 눈에 있어야 한다 — 목록이 수백 장이면 진행 배너가
   화면 밖으로 밀려 무엇이 도는지 안 보인다.

   **고정은 둘이고 `top` 계산은 하나다.** 셋을 각각 고정하면 오류가 떴다 질 때마다
   기능 띠의 `top` 을 다시 재야 한다. `.topbar` 가 제 높이를 `--topbar-h` 에
   **스스로** 넣고(ResizeObserver) `.fnbar` 는 그 값만 받는다. 재는 쪽과 붙는 쪽이
   갈리면 어긋난다 — 화면이 재던 `--gnb-h` 를 여기서 걷어냈다.

   내용이 없으면 자식이 전부 숨어 높이가 0 이다 — 빈 띠가 남지 않는다.
   배경을 깔지 않으면 아래 카드가 비쳐 글자가 겹친다.

   **이 요소에는 `overflow` 를 주지 않는다.** 붙는 쪽이든 조상이든 `overflow` 가
   끼면 sticky 가 죽는다. 길어질 수 있는 것(반려 목록)은 안쪽 자식에서 자른다. */
.topbar { position: sticky; top: 0; z-index: 1020;
          background: var(--bs-body-bg); }
/* **아래쪽 여백은 띠가 갖는다** (2026-09-24 지시). 본문 첫 요소에 `margin-top`
   을 주면 화면마다 값이 갈리고, 첫 요소가 바뀔 때마다 따라다녀야 한다.
   띠가 제 아래 자리를 비워 두면 어느 화면에서나 같은 만큼 뜬다.
   `padding` 이라 sticky 높이에 함께 들어간다 — 그 아래 붙는 것(`--fnbar-h`)도
   같은 만큼 내려와 어긋나지 않는다. */
.fnbar  { position: sticky; top: var(--topbar-h, 3.5rem); z-index: 1010;
          background: var(--bs-tertiary-bg); padding-bottom: .75rem; }
.fnbar .reject-list { max-height: 30vh; overflow: auto; }

/* 화면 제목 (2026-09-24 지시). **여러 화면이 같은 것을 쓴다** — 화면 제목이든
   그 안의 구역 제목이든 같은 글꼴이다. `h1`·`h2` 어느 태그에 붙여도 같게 보이게
   값을 여기 둔다. Bootstrap `.h4` 와 같은 크기다. */
.page-title { font-size: calc(1.275rem + .3vw); font-weight: 500;
              line-height: 1.2; margin-bottom: .75rem; }
@media (min-width: 1200px) { .page-title { font-size: 1.5rem; } }

/* 구역과 구역 사이 (2026-09-25 지시 · 「상단과 섹션 사이가 왜 다른거야」).
   **화면 맨 위 제목 위와 같은 만큼 벌린다.** 그 값은 둘이 만든 것이다 —
   `main.py-4` 의 위 여백 1.5rem + 띠(`.fnbar`)가 갖는 아래 여백 .75rem.
   **`.fnbar` 의 `padding-bottom` 을 고치면 여기도 따라 고친다.**

   제목 전용이 아니다. 구역을 여는 것이면 무엇이든 이 값으로 벌린다 —
   자리마다 `mt-3`·`mt-4` 를 골라 붙이면 화면마다 또 갈린다. */
.section-gap { margin-top: calc(1.5rem + .75rem); }

/* 맨 위로 (2026-09-25 지시). **모든 화면 오른쪽 아래.** 반 화면쯤 내리면 뜬다 —
   뜨고 지는 판정은 `base.html` 이 하고 여기는 꼴만 갖는다.

   **띠(1010·1020)보다 아래, 검수 창(1080)보다 한참 아래에 둔다** — 창이 열리면
   가려져야 한다. `display` 로 감추지 않고 흐리게 둔다 — 딱 끊기면 튀어 보인다. */
.to-top { position: fixed; right: 1rem; bottom: 1rem; z-index: 1000;
          width: 2.75rem; height: 2.75rem; padding: 0;
          display: flex; align-items: center; justify-content: center;
          font-size: 1.15rem; line-height: 1;
          border: 1px solid var(--bs-border-color); border-radius: 50%;
          background: var(--bs-body-bg); color: var(--bs-secondary-color);
          box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .15);
          opacity: 0; visibility: hidden;
          transition: opacity .15s linear, visibility .15s linear; }
.to-top.is-on { opacity: 1; visibility: visible; }
.to-top:hover { color: var(--bs-body-color); background: var(--bs-tertiary-bg); }

/* 검수 · 원본과 수집 결과를 나란히 놓는다 */

/* 검수 창이 열린 동안 **뒤 페이지가 스크롤되지 않는다** (2026-09-19 지시).
   `.topbar`·`.fnbar` 의 sticky 가 이때 죽지만, 오버레이가 덮고 있어 보이지 않고
   닫으면 돌아온다. 붙였다 떼는 것은 `_review.html` 의 `x-effect` 가 한다. */
body.no-scroll { overflow: hidden; }

.review { position: fixed; inset: 0; z-index: 1080; background: rgba(0, 0, 0, .55);
          display: flex; align-items: center; justify-content: center; padding: .5rem; }
.review-box { background: var(--bs-body-bg); border-radius: .5rem; width: min(1100px, 100%);
              max-height: 100%; display: flex; flex-direction: column; overflow: hidden; }
.review-head, .review-foot { display: flex; align-items: center; justify-content: space-between;
              gap: .75rem; padding: .6rem .8rem; }
.review-head { border-bottom: 1px solid var(--bs-border-color); }
.review-foot { border-top: 1px solid var(--bs-border-color); }
/* 실패 사유. 사유가 없어도 한 줄 자리를 비워 둔다 (모바일에서 끝에 붙는다) */
.review-why { margin-top: .5rem; padding-bottom: 1.5em; }
.review-body { display: grid; gap: .75rem; padding: .8rem; overflow: auto;
               grid-template-columns: 1fr; }
@media (min-width: 768px) { .review-body { grid-template-columns: 1fr 1fr; } }
.review-pane { min-width: 0; }
.review-label { font-size: .8rem; color: var(--bs-secondary-color); margin-bottom: .3rem; }
.review-pane img { width: 100%; border: 1px solid var(--bs-border-color); border-radius: .3rem; }

/* 용지 모양. 픽셀을 맞추지 않고 순서만 같게 둔다 */
.paper { border: 1px solid var(--bs-border-color); border-radius: .3rem;
         padding: 1rem; font-size: .85rem; background: var(--bs-body-bg); }
.paper-drw { text-align: center; font-size: 1.1rem; font-weight: 600; margin-bottom: .9rem; }
/* 수집 정보의 모든 줄은 같은 높이·같은 간격을 쓴다. 기준은 입력칸이 들어가는
   발행일 줄이다 — 이보다 높은 줄은 없다. 줄 사이 1px 은 위아래 입력칸의 빨간
   테두리가 맞닿아 굵게 보이는 것을 막는다. */
.paper-rows, .paper-games { display: flex; flex-direction: column; gap: 1px; }
.paper-rows > div, .paper-games > div, .paper-amount {
                    min-height: 2.1rem; }
/* 항목에 붙는 말(못 읽음·검산·형식)이 길면 그 항목 아래로 접힌다. 줄을 바꿔도
   같은 블록 안이라 어느 항목 이야기인지 헷갈리지 않는다. */
.paper-rows > div { display: flex; align-items: center; gap: .4rem;
                    flex-wrap: wrap; }
/* 문구를 자리에 맞춰 줄이지 않는다. 자리가 문구를 받아낸다.
   `keep-all` 은 한국어를 **어절 단위**로 접는다 — 이것이 없으면 "수집을 실
   패 했어요" 처럼 글자 사이가 끊어진다. 폭이 모자라면 항목 줄 안에서 제 줄을
   갖는다(`flex-basis`). 모바일에서 더 좁아져도 같은 규칙으로 접힐 뿐이다. */
.paper-note { font-size: .8rem; color: var(--bs-danger);
              flex: 1 1 14rem; min-width: 0; word-break: keep-all; }
.paper-key { display: inline-block; min-width: 3.8rem; color: var(--bs-secondary-color); }
.paper-games { margin: .8rem 0; }
.paper-games > div { display: flex; align-items: center; gap: .35rem; }
/* 게임 표시(A~E)는 한 글자다. 항목 이름과 같은 너비를 쓰면 유형이 밀린다.
   번호가 주인공이므로 앞의 둘은 작고 옅게, 번호는 크고 진하게 둔다. */
.paper-label { display: inline-block; min-width: 1rem; font-size: .8em; }
/* 자동(2자)·반자동·미확인(3자)은 글자 수가 다르다. 형광펜 바탕까지 칸 폭으로
   고정해야 게임끼리 줄이 맞는다. 글자는 그 안에서 가운데 */
.paper-type { display: inline-block; min-width: 2.7rem; font-size: .8em;
              text-align: center; }
/* 유형 고르개. **번호는 못 고치고 이것만 고친다** (2026-09-18 지시).
   용지 표기 자리를 그대로 차지해야 게임끼리 줄이 맞는다 — 「반자동」 석 자에
   화살표까지 들어갈 만큼만 잡는다. */
.paper-type-pick { display: inline-block; width: auto; min-width: 5.4rem;
                   font-size: .8em; line-height: 1.5; height: auto;
                   padding: .05rem 1.5rem .05rem .4rem; }
.paper-type-pick.src-none { border-color: var(--bs-danger); color: var(--bs-danger); }
.paper-nums { font-family: var(--bs-font-monospace); font-size: 1.05em;
              font-weight: 600; letter-spacing: .06em; white-space: pre;
              margin-left: .2rem; }
/* 2022-08-27 15:58:00 은 19자다. ch 는 그 글꼴의 '0' 폭이라 글꼴을 바꿔도 맞는다. */
.paper-input { width: calc(19ch + 1.2rem); }
/* 2022-08-20 은 10자다 */
.date-input { width: calc(10ch + 1.2rem); }

/* 발행일시 입력 · 남은 자리를 밑줄로 미리 보여준다 */
/* iOS 는 입력칸 글자가 16px 미만이면 화면을 확대하고, 닫아도 되돌리지 않는다.
   iOS 의 크롬·파이어폭스도 사파리 엔진을 쓰므로 브라우저를 가리지 않는다.
   viewport 로 막으면 손가락 확대까지 막히므로 글자 크기로 푼다. */
.mask-input { font-family: var(--bs-font-monospace); font-size: 16px;
              padding-left: .4rem; padding-right: .4rem; }
/* 안내 문구는 옅게. 내가 친 값처럼 보이면 안 된다. */
.mask-input::placeholder { color: var(--bs-secondary-color); opacity: .45; }
/* 이 칸은 발행일시를 못 읽었을 때만 뜬다. 다 채우기 전까지 테두리만 빨강.
   글자색은 건드리지 않는다 — 안내 문구는 옅은 회색이어야 한다 (185번) */
.mask-input.is-bad { border-color: var(--bs-danger); }
.mask-input.is-bad:focus { border-color: var(--bs-danger);
        box-shadow: 0 0 0 .2rem rgba(var(--bs-danger-rgb), .2); }
.paper-amount { display: flex; align-items: center; justify-content: flex-end;
                gap: .4rem; margin-top: .5rem; }
/* 읽지 않는 바코드 자리. 자리만 표시한다 */
.paper-bar { height: 1.4rem; margin: .4rem 0;
             background: repeating-linear-gradient(135deg,
               var(--bs-border-color) 0 2px, transparent 2px 6px); }
.paper-bar-thin { height: .9rem; }

/* 값의 출처 (claude_rule.md 185번)
   검수는 **틀린 것을 찾는 일**이다. 대부분인 정상에 색을 칠하면 강조가 죽는다.
   정상은 기본색으로 두고 예외에만 색을 쓴다. */
/* 사진에서 읽은 값에는 형광펜처럼 옅은 바탕을 깐다.
   "긁어온 자리"가 눈에 보이게 하되 색으로 시끄럽게 하지 않는다. */
.src-qr, .src-ocr { color: var(--bs-body-color);
                    background: color-mix(in srgb, var(--bs-primary) 10%, transparent);
                    box-shadow: 0 1px 0 color-mix(in srgb, var(--bs-primary) 35%, transparent);
                    border-radius: .15rem; padding: 0 .2rem; }
.src-calc { color: var(--bs-secondary-color); }      /* 읽지 않음. 조회·계산 */
.src-none { color: var(--bs-danger); }               /* 읽기 실패 */
.src-warn { color: var(--bs-warning-text-emphasis); }
/* 사람이 채워 넣은 값. 사진에서 읽은 것도, 못 읽은 것도 아니다.
   형광펜(읽음)과 구분되게 점선 밑줄만 둔다 */
.src-manual { color: var(--bs-body-color);
              border-bottom: 1px dashed var(--bs-secondary-color); }


/* 게임 목록의 번호. 용지에는 검은 글자지만 **여기서는 공 색**으로 본다.
   등록 화면은 용지를 그대로 옮기는 자리라 이 표현을 쓰지 않는다 (193번). */
/* **원만 한 단계 줄인다** (2026-09-18 지시). 차지하는 가로 자리(원 + 오른쪽 여백)는
   36.8px 그대로 두고 글꼴도 건드리지 않는다 — 줄어든 만큼 여백으로 돌려준다.
   2rem + .3rem  →  1.75rem + .55rem */
.ball { display: inline-flex; align-items: center; justify-content: center;
        width: 1.75rem; height: 1.75rem; border-radius: 50%;
        font-family: var(--bs-font-monospace); font-size: .85rem; font-weight: 600;
        color: #fff; margin-right: .55rem; }
.ball-1 { background: #fbc400; }   /*  1~10 */
.ball-2 { background: #69c8f2; }   /* 11~20 */
.ball-3 { background: #ff7272; }   /* 21~30 */
.ball-4 { background: #aaaaaa; }   /* 31~40 */
.ball-5 { background: #b0d840; }   /* 41~45 */

/* 당첨번호 강조에서 **맞지 않은 공**. 끄되 지우지는 않는다 — 무엇을 골랐는지는
   그대로 보여야 한다. 산 게임의 98%가 낙첨이라, 칠한 채로 두면 맞은 셋이 묻힌다
   (검수 화면의 "정상에 색을 칠하지 않는다"와 같은 줄기 · 185번). */
.ball-off { background: transparent; color: var(--bs-secondary-color);
            border: 1px solid var(--bs-border-color); font-weight: 400; }

/* **과거 회차에서 맞은 공** (2026-09-24 지시). **「검수 완료」 딱지와 같은 색**을
   쓴다 — 화면에 이미 있는 색이라 새로 외울 것이 안 는다. 굵기는 꺼진 공의
   테두리와 같은 1px 이다.
   **이 회차에서 맞은 공 위에도 얹는다** — 양쪽에서 다 맞은 번호가 실제로 있다
   (1217회 C조는 `15·20·31` 셋이 겹친다).
   **`border` 로 준다.** `box-sizing: border-box` 라 바깥 크기가 그대로다 —
   공 크기가 바뀌면 위아래 줄과 자리가 어긋난다 (2026-09-24 지시). */
.ball { box-sizing: border-box; }
.ball-edge { border: 1px solid var(--bs-primary); }


/* ── 게임 화면 ── 통계 모듈 · 필터 모듈 · 회차 카드 (2026-09-18)
   묶는 단위가 회차다. 당첨을 회차가 판정하므로 구매 건으로 늘어놓으면
   같은 당첨번호를 네 번 그리게 된다. */

/* 통계 머리 — 여섯 칸. 넓으면 한 줄, 좁으면 두 칸씩 세 줄이다.
   **좁은 화면에서 세 칸으로 쪼개지 않는다** — 375px 에서 칸 안쪽이 92px 인데
   `1,290,000원` 이 100px 을 먹어 넘친다. 값을 줄여 맞추는 것은 거꾸로다. */
/* **모서리는 카드에 맞춘다** (2026-09-19 지시). 안쪽 그리드가 직각이면
   카드의 둥근 모서리와 어긋나 지저분해진다. `inherit` 으로 같은 값을 받는다. */
.stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
             gap: 1px; background: var(--bs-border-color);
             border-radius: inherit; overflow: hidden; }
@media (min-width: 768px)  { .stat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .stat-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.stat-cell { background: var(--bs-body-bg); padding: .5rem .75rem .6rem; }
.stat-name { font-size: .75rem; color: var(--bs-secondary-color); white-space: nowrap; }
.stat-val  { font-size: 1.15rem; font-weight: 600; font-variant-numeric: tabular-nums;
             white-space: nowrap; }
.stat-unit { font-size: .75rem; font-weight: 400; color: var(--bs-secondary-color);
             margin-left: .1rem; }

/* 통계 상세 — 한 줄이 [이름][막대][수] 다. 막대는 서로를 견주는 것이라
   가장 큰 값을 100 으로 본다. 절대 수는 오른쪽 숫자가 말한다. */
.stat-row   { display: flex; align-items: center; gap: .4rem; padding: .12rem 0;
              font-size: .8rem; }
.stat-key   { min-width: 2rem; }
/* 막대는 얇아서 알약 꼴이 자연스럽다. **값을 손으로 적지 않는다** —
   Bootstrap 변수를 쓰면 화면끼리 어긋나지 않는다 (2026-09-19 지시) */
.stat-track { flex: 1; height: .3rem; border-radius: var(--bs-border-radius-pill);
              background: var(--bs-tertiary-bg); overflow: hidden; }
.stat-fill  { display: block; height: 100%; background: var(--bs-primary);
              border-radius: var(--bs-border-radius-pill); }
.stat-num   { min-width: 2.2rem; text-align: right; font-variant-numeric: tabular-nums; }
.stat-nums  { display: flex; flex-wrap: wrap; gap: .5rem; }
.stat-num-one { display: flex; flex-direction: column; align-items: center; gap: .1rem; }
.stat-num-one .ball { margin-right: 0; }
/* 등수별과 적중 개수는 **좁은 화면에서 한 줄에 나란히** 선다 (2026-09-18 지시).
   세로로 쌓으면 화면을 두 배로 먹어 카드에 닿기까지 한참 내려야 한다.
   넓은 화면에서는 오른쪽 칸이 좁아 한 줄씩으로 돌아간다. */
.stat-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 .5rem; }
@media (min-width: 992px) { .stat-pair { grid-template-columns: 1fr; gap: 0; } }

/* 필터 — 기능 영역 안에 산다. **블록으로 감싼다** — 맨몸으로 두면 띠 배경에
   묻혀 어디까지가 한 덩이인지 안 읽힌다 (2026-09-18 지시). */
.filter-bar { display: flex; align-items: center; flex-wrap: wrap;
              gap: .4rem .9rem; }
.filter-one { display: flex; align-items: center; gap: .35rem; font-size: .9rem;
              cursor: pointer; margin: 0; }
.filter-one input { margin: 0; cursor: pointer; }
/* **조건은 왼쪽에 모으고 결과는 오른쪽 끝**에 붙인다 (2026-09-19 지시).
   한때 셋을 화면 폭에 고르게 펼쳤는데, 덩어리가 커져 읽히지 않았다. */
.filter-count { margin-left: auto; white-space: nowrap; }
/* 조건 사이의 금 (2026-09-24 지시). 앞의 둘은 이 회차, 뒤엣것은 다른 회차라
   축이 다르다. 글자가 아니라 선이므로 읽어 주는 장치는 건너뛴다 */
.filter-sep { width: 1px; align-self: stretch; min-height: 1.2em;
              background: var(--bs-border-color); }

/* 좌·우 칸과 필터는 붙어 있고 **가운데 카드만 흐른다** (2026-09-18 지시).
   셋 다 같은 자리에 붙는다 — 윗단(`.topbar` + `.fnbar`)이 제 높이를 알려 주므로
   높이가 바뀌어도 여기서 다시 잴 것이 없다.

   **`.row` 안 `col` 에 직접 걸지 않는다.** flex item 이라 높이가 늘어 sticky 가
   제 자리를 못 잡는다. 안쪽 껍데기에 건다. */
/* **필터는 어느 폭에서나 붙는다** (2026-09-19 지시). 목록을 조종하는 것이라
   카드 곁에 있어야 쓸모가 있다. 카드가 뒤로 지나가므로 배경을 깐다 —
   안 깔면 글자가 겹친다. */
/* **아래 여백은 이 띠가 갖는다** (2026-09-24 지시) — `.fnbar` 와 같은 규칙이다.
   게임 화면에서는 이것이 본문 바로 위에 오는 마지막 띠다. */
.filter-hold { position: sticky; top: var(--topbar-h, 3.5rem); z-index: 1005;
               background: var(--bs-tertiary-bg);
               padding: .5rem 0 .75rem; margin-top: -.5rem; }

/* **좁은 화면에서는 필터만 붙는다** (2026-09-19 지시). 통계 머리와 상세 패널은
   함께 올라간다 — 셋을 다 붙이면 426px 이 되어 목록을 덮는다.
   `.fnbar` 는 공용이라 이 화면 것만 따로 푼다.

   **`padding` 을 준 까닭은 배경이다** (2026-09-19). 안쪽 카드의 `margin` 이
   `padding` 없는 껍데기 밖으로 새어(margin collapse) 그 자리에 배경이 안 깔렸고,
   **고정된 띠 뒤로 게임 줄이 지나가 보였다.** 카드 쪽 `margin` 은 걷었다. */
.fnbar-loose { padding: .5rem 0; }


/* ── 당첨정보 화면 ── 회차를 쌓고 머리줄만 보인다 (2026-09-24 지시 · B안)
   여는 상태는 `<details>` 가 갖는다. 회차마다 따로이고 다른 곳에서 볼 일이 없다. */
.prize-row > summary { list-style: none; cursor: pointer; }
.prize-row > summary::-webkit-details-marker { display: none; }
.prize-row > summary:hover { background: var(--bs-tertiary-bg); }
/* 접혀 있을 때도 모서리가 카드를 따라야 한다 — 펼치면 아래 모서리는 본문이 갖는다 */
.prize-row > summary { border-radius: var(--bs-border-radius); }
.prize-row[open] > summary { border-radius: var(--bs-border-radius)
                                            var(--bs-border-radius) 0 0; }
.prize-no   { min-width: 3.5rem; }
.prize-date { min-width: 5.5rem; }

/* 머리줄 안의 당첨번호. `.draw-nums` 를 그대로 쓰되 **띠 꼴은 벗긴다** —
   한 줄 안에 들어가야 해서 배경도 아래 여백도 필요 없다.

   **둘을 다 적는다** (2026-09-25 지시 · 「희미한 회색은 의미가 없어 보인다」).
   `.draw-nums` 가 이 규칙보다 **뒤에 있어** 같은 특이성에서 이겼고, 벗기려던
   배경·여백이 그대로 남아 있었다. 클래스를 둘 겹쳐 특이성으로 이긴다 —
   자리를 옮겨 푸는 것은 다음에 규칙이 하나 끼면 또 뒤집힌다. */
.draw-nums.prize-inline { padding: 0; margin-bottom: 0; background: none; }

/* 등수 딱지. 색은 공과 같은 다섯 단계에서 셋만 쓴다 — 1·2·3등만 눈에 띄면 된다 */
.prize-rank   { min-width: 2.4rem; background: var(--bs-secondary-bg);
                color: var(--bs-secondary-color); }
.prize-rank-1 { background: #fbc400; color: #fff; }
.prize-rank-2 { background: #69c8f2; color: #fff; }
.prize-rank-3 { background: #ff7272; color: #fff; }

/* **금액은 끊지 않는다.** 좁은 화면에서 「3,281,029,250 / 원」으로 갈라져
   두 줄이 되면 자릿수를 읽을 수 없다. 넘치는 것은 `table-responsive` 가 민다 */
.prize-tbl td, .prize-tbl th { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* **폭을 묶는다.** 회차 화면에서는 내가 맞은 줄에 성적(「5등 1건 · 5,000원」)이
   이 칸에 들어가, 자동 배분에 맡기면 줄마다 칸 너비가 달라진다.
   **값은 막대가 아니라 숫자다** (2026-09-25 지시 · 「막대기 봐도 어느 정도인지
   알 수 없어」). 다른 숫자 칸과 같이 오른쪽에 붙인다. */
.prize-share { width: 7rem; min-width: 7rem; padding-left: 1rem !important; }
/* 좁은 화면에서는 「비중」을 버린다. 총액 숫자가 이미 옆에 있다 */
@media (max-width: 575.98px) {
  .prize-share { display: none; }
  .prize-tbl td, .prize-tbl th { font-size: .8rem; padding-left: .4rem; padding-right: .4rem; }
}

/* 1등 구매 유형 — 한 줄 막대. 셋을 이어 붙여 비율을 그대로 보여준다 */
.prize-seg { display: flex; height: .55rem; overflow: hidden;
             border-radius: var(--bs-border-radius-pill);
             background: var(--bs-tertiary-bg); }
.prize-seg > i { display: block; }
.prize-dot { display: inline-block; width: .5rem; height: .5rem; margin-right: .3rem;
             border-radius: 50%; vertical-align: middle; }
.seg-auto   { background: #69c8f2; }
.seg-manual { background: #ff7272; }
.seg-semi   { background: #b0d840; }

/* **내가 맞은 등수 줄** (2026-09-24 지시). 강조 대상은 회차가 아니라 **그 등수**다 —
   5등에 맞았으면 등수표의 5등 줄이 물든다. 색은 게임 화면과 같은 규칙이다
   (1~4등 파랑 · 5등 초록). 누르면 게임 화면으로 간다 —
   **어떤 번호로 맞았는지는 거기서 본다.** 여기는 회차 결과를 보는 곳이다. */
.prize-tbl tr.prize-hit { cursor: pointer; }
.prize-tbl tr.is-win-hi > td { background: var(--bs-primary-bg-subtle); }
.prize-tbl tr.is-win-lo > td { background: var(--bs-success-bg-subtle); }
.prize-tbl tr.is-win-hi:hover > td { background: var(--bs-primary-border-subtle); }
.prize-tbl tr.is-win-lo:hover > td { background: var(--bs-success-border-subtle); }
/* 그 줄의 「비중」 자리에 내 성적을 쓴다. 막대는 그때 안 그린다 */
.prize-my { font-size: .8rem; font-weight: 600; white-space: nowrap;
            color: var(--bs-primary-text-emphasis); }
.prize-tbl tr.is-win-lo .prize-my { color: var(--bs-success-text-emphasis); }

/* 판매·당첨금 칸. 넓은 화면에서만 왼쪽에 선을 둔다 —
   좁은 화면에서는 위아래로 쌓여 세로선이 엉뚱한 자리에 남는다 */
.prize-money { font-variant-numeric: tabular-nums; }
@media (min-width: 768px) {
  .prize-money { border-left: 1px solid var(--bs-border-color); }
}
@media (max-width: 991.98px) { .fnbar-loose { position: static; } }

/* 넓은 화면에서는 통계 머리가 띠에 남으므로 그 아래에 붙는다.
   좌·우 칸도 같은 자리다 — 윗단 높이가 바뀌어도 한 값만 따라간다. */
@media (min-width: 992px) {
  /* **필터는 통계 띠에 딱 붙인다.** 사이를 띄우면 붙었을 때 그 틈으로
     게임 줄이 지나간다 (2026-09-19). 좌·우 칸은 띠가 아니라 여백을 둔다. */
  .filter-hold { top: calc(var(--topbar-h, 3.5rem) + var(--fnbar-h, 0px));
                 margin-top: 0; }
  .side-hold { position: sticky;
               top: calc(var(--topbar-h, 3.5rem) + var(--fnbar-h, 0px) + .75rem); }
  .side-hold > div:last-child > .card:last-child { margin-bottom: 0; }
}

/* 회차 카드. 주소의 `#` 로 건너올 때 띠 밑에 숨지 않게 자리를 비워 둔다 —
   윗단(메뉴+통계)에 **필터 띠까지** 더해야 가려지지 않는다 */
.draw-card { scroll-margin-top: calc(var(--topbar-h, 3.5rem)
                                     + var(--fnbar-h, 0px) + 4.5rem); }
/* 당첨번호 줄 — **좁은 화면에서도 한 줄에 선다** (2026-09-18 지시).
   공의 오른쪽 여백을 걷고 `gap` 하나로만 띄운다 — 그래야 `+` 양옆이 같아진다.
   여백이 두 군데(margin + gap)에서 오면 `+` 왼쪽만 넓어져 대칭이 깨진다. */
.draw-nums { display: flex; align-items: center; flex-wrap: wrap; gap: .2rem;
             padding: .5rem .6rem; margin-bottom: .5rem;
             background: var(--bs-tertiary-bg);
             border-radius: var(--bs-border-radius); }
.draw-nums .ball { margin-right: 0; }
/* 「당첨번호」 글자와 첫 공 사이도 `+` 양옆과 같은 값이다 (2026-09-18 지시).
   한쪽만 `gap` 이고 한쪽은 `gap + margin` 이면 같은 줄에서 간격이 둘이 된다. */
.draw-nums .stat-cap { margin-right: .25rem; }
.draw-nums .plus { margin: 0 .25rem; }

/* 한 회차 안의 구매 건. 여러 장을 산 날은 여러 덩이가 된다 */
.paper-block { padding: .5rem 0; border-top: 1px solid var(--bs-border-color); }
.paper-block:first-of-type { border-top: 0; }
.paper-head { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem;
              margin-bottom: .35rem; }
/* 추첨일 · 지급기한 · 금액. **게임 줄보다 작아야 한다** (2026-09-18 지시).
   `small`(.875rem)로 두었더니 유형(.75)·적중(.8)보다 커서, 곁들이는 값이
   번호와 같은 무게로 읽혔다 — 「다 동일하니까 정신 없다」. */
.paper-foot { margin-top: .5rem; font-size: .7rem; }

/* 게임 한 줄. 번호가 주인공이라 앞의 둘은 작고 옅게 둔다 */
.game-row  { display: flex; align-items: center; flex-wrap: wrap; gap: .3rem;
             padding: .2rem .35rem; margin: 0 -.35rem;
             border-radius: var(--bs-border-radius); }
.game-nums { display: flex; flex-wrap: wrap; }
/* 줄 오른쪽 끝의 칸들 (2026-09-25 지시). 왼쪽부터 **당첨 등수·금액 · 과거 회차
   등수 · 구매회수** 순이다. **적중 개수는 뺐다** — 맞은 공이 이미 켜져 있어
   세면 나오는 값이고, 등수가 있으면 그 옆에서 같은 말을 두 번 한다.

   **폭을 묶지 않는다.** 값이 있는 것만 제 너비로 선다.
   **사이는 가운데 점이다** (2026-09-25 지시) — 세로 금은 칸을 만든 것처럼
   보인다. 화면의 다른 글(`win_one` 따위)이 쓰는 것과 같은 기호다. */
.game-tail { margin-left: auto; display: flex; align-items: center; }
.game-cell { font-size: .8rem; color: var(--bs-secondary-color); white-space: nowrap; }
/* 앞에 무엇이 있을 때만 붙는다. **점은 어느 칸의 색도 따르지 않는다** —
   당첨은 파랑 굵게, 과거 회차는 노랑 굵게라 물려받으면 구분자가 튄다 */
.game-sep::before { content: "·"; padding: 0 .35rem; font-weight: 400;
                    color: var(--bs-secondary-color); }
/* 당첨된 줄. **당첨정보 보기를 켰을 때만** 깐다 — 강조만 켠 상태에서 줄까지
   칠하면 "당첨게임은 강조하지 않는다"가 깨진다 (2026-09-18 지시) */
.is-win-hi { background: var(--bs-primary-bg-subtle); }
.is-win-lo { background: var(--bs-success-bg-subtle); }
.is-win-hi .game-mark { color: var(--bs-primary-text-emphasis); font-weight: 600; }
.is-win-lo .game-mark { color: var(--bs-success-text-emphasis); font-weight: 600; }

/* ── 분석 화면 ── 구역 셋 (2026-09-25 지시 · 종합 · 통계 · 그 밖)

   순위 목록 — 종합의 「가장 높았던/낮았던 회차」. 회차는 왼쪽, 값은 오른쪽
   끝에 붙는다. **자릿수를 맞춘다**(`tabular-nums`) — 금액이 세로로 서는 자리라
   글자 폭이 흔들리면 숫자가 어긋나 보인다. */
.rank-list { list-style: none; margin: 0; padding: 0;
             font-variant-numeric: tabular-nums; }
.rank-list li { display: flex; align-items: baseline; gap: .4rem;
                padding: .15rem 0; font-size: .8rem; }
.rank-no  { width: 1rem; color: var(--bs-tertiary-color); }
.rank-drw { color: var(--bs-secondary-color); white-space: nowrap; }
.rank-val { margin-left: auto; font-weight: 600; white-space: nowrap; }

/* 연속 번호 쌍. **공 하나에 두 수가 안 들어가 알약 꼴로 낸다** — 색과 높이는
   `.ball` 그대로라 번호 카드와 줄이 어긋나지 않는다. 색은 앞수의 열을 따른다. */
.ball.is-pair { width: auto; min-width: 2.9rem; padding: 0 .45rem;
                border-radius: var(--bs-border-radius-pill); font-size: .78rem; }

/* 「과거 회차 비교」가 걸린 줄 (2026-09-24 지시). **색을 달리한다** — 실제로 받은
   돈이 아니라 「다른 회차였다면」이라, 이 회차 당첨(파랑·초록)과 섞이면 안 된다.
   이 회차에서도 당첨된 줄은 위 둘이 이긴다 — 실제로 받은 쪽을 보여준다. */
.is-past { background: var(--bs-warning-bg-subtle); }
.is-past .game-other { color: var(--bs-warning-text-emphasis); font-weight: 600; }
