/* 공개 화면 스타일. index.html 이 <link> 로 불러온다.
   코치스에서 배운 것 하나를 그대로 가져왔다 — 화면 파일이 2000줄을 넘기면
   문서 끝에 남은 확인용 <script> 가 눈에 안 띈다. 그래서 처음부터 나눠 둔다.

   ── 검은 바탕 (2026-10-16 CHOI) ────────────────────────────────────
   *"직관적으로는 하얀 배경이 좋긴 한데 코브의 느낌이 좀 덜하다.
     코브 홈페이지처럼 블랙 베이스로 기존 코브 감도를 넣어보자."*

   값은 지어내지 않았다. `~/dev/cov-site/public/site.css` 의 토큰을 그대로
   가져왔다 — `--bg:#000` · `--ink:#f4f4f4` · `--ink-2:#8c8c8c` ·
   `--line:#262626`. 두 화면이 각자 고른 검정을 쓰면 같은 날 둘을 본 사람에게
   다른 회사로 보인다. 숫자를 여기서 다시 정하지 않는 것이 요점이다.

   검은 바탕에서 지켜야 하는 것 둘(cov-site 머리말에서 그대로 온다).
     ① **흰 글자를 굵게 크게 쓰면 번져 보인다**(halation). 그래서 본문 굵기를
        올리지 않는다. 대신 `--ink-2` 를 흰 바탕 때(#5E6266)보다 **밝게**
        잡는다 — 그 값을 그대로 가져오면 검은 바탕에서 거의 안 읽힌다.
     ② **자리채움은 `--bg` 보다 밝아야 한다.** 같으면 사진이 안 실렸을 때
        칸이 사라져서 격자가 깨진 것처럼 보인다.

   들림(lift)이 흰 바탕과 반대로 뒤집힌다. 흰 바탕에서는 `--panel`(#FAFAFA)이
   약한 들림이고 `--soft`(#F4F5F6)가 강한 들림이었다 — 둘 다 흰색에서 **내려간**
   값이다. 검은 바탕에서는 둘 다 **올라간** 값이 되므로 대소가 뒤집힌다.
   역할은 그대로 둔다(panel = 칩 · 카드 · 표 머리 / soft = 막대 바닥 · 입력칸 ·
   비활성). 역할까지 같이 뒤집으면 50군데를 다시 봐야 한다.

   ⚠ **색 세 개(`--ok` · `--warn` · `--err`)는 cov-site 규칙과 어긋난다.**
     cov-site 는 *"색은 쓰지 않는다. 사진이 유일한 색이다"* 다. 여기서는 셋을
     남겼다 — 이 화면의 색은 장식이 아니라 **돈의 상태**를 가리킨다(모집중 ·
     마감임박 · 미개설 · 입금 확인 · 환급). 그걸 회색조로 돌리면 '마감 임박'
     과 '종료' 가 같은 색이 되고, 그건 참가자가 돈을 넣을지 말지 판단하는
     자리다. 대신 **값을 다시 켰다** — 원래 셋은 흰 바탕용 어두운 색이라
     검은 바탕에서 글자로 쓰면 안 읽힌다. 셋을 아예 뺄지는 CHOI 판단이다. */
:root{
  --bg:#000000;--soft:#1E1E1E;--panel:#121212;--ink:#F4F4F4;--ink-2:#8C8C8C;
  --line:#262626;--ok:#1E7F48;--warn:#D08A2C;--err:#E05A52;
  /* ── 보여야 하는 선 (2026-10-16 CHOI — "흰색 · 점선 가독성") ──────────
     `--line` 은 바탕과의 **대비가 1.2:1** 이다(흰 바탕 #EBEDEF 일 때 1.17:1,
     검은 바탕 #262626 일 때 1.21:1 — 뒤집어도 거의 같다). 그 선으로 그린
     1px 점선은 사실상 안 보인다 — 점선은 틈 때문에 같은 색 실선보다
     한 단 더 약하게 읽히기 때문이다. 그래서 화면에 상자가 있는데 보이지
     않는 자리가 셋 있었다: 입력 칸 · 영상 올리는 칸 · 매칭 요청 블록.

     입력 칸이 특히 나빴다. 테두리가 안 보이면 **어디에 쓰는지를 모른다** —
     placeholder 글자만 공중에 떠 있다. WCAG 1.4.11 이 '컴포넌트를 알아보는
     데 필요한 선' 에 요구하는 값이 3:1 이고, 이 색이 검은 바탕에서
     4.1:1 이다(#6E6E6E. 흰 바탕의 #8C949C 는 3.07:1 이었다).

     ⚠ **`--line` 자체를 밝게 하지 않는다.** 그 값은 카드 테두리 · 머리
       아래 선 · 안내 표의 칸 선처럼 **나누기만 하는 선**이 전부 같이 쓴다.
       거기까지 3:1 로 올리면 검은 화면이 통째로 회색 격자가 된다 — 나누는
       선은 보이지 않아도 화면을 쓸 수 있고, 조작하는 선은 보여야 쓸 수 있다.
       그 둘을 한 값에 묶어 두고 있던 것이 이 결함의 원인이다.

     쓰는 자리: 입력 칸 · 고르는 버튼 · 점선 상자(영상 · 매칭 요청 · 빈 목록).
     안 쓰는 자리: 카드 테두리 · 구분선 · 표의 칸 선. */
  --line-2:#6E6E6E;
  /* ── 작고 넓은 글자는 회색으로 두지 않는다 (2026-10-16 CHOI) ──────────
     *"코브로고랑 그 저기 클럽 텍스트 하얀색으로 바꾸자. … 가독성 좀 올려야
       되니까 완전 블랙으로 갈 거면."* → *"아니다, 다크그레이 같은 것도
       적절히 섞어주면 좋을 것"*

     보내온 화면은 로고 옆 `SPORTS CLUB` 이 검정 위에서 안 읽히는 것이었다.
     그런데 **대비가 모자라서 그런 것이 아니다.** `--ink-2`(#8C8C8C)는 검정
     대비 **6.2:1** 로 AA(4.5:1)를 넉넉히 넘긴다. 숫자로는 통과하는 색이
     눈으로는 안 읽혔다.

     안 읽히는 쪽은 대비가 아니라 **획 두께**다. 자간(letter-spacing)을 벌리면
     글자가 서로를 받쳐 주지 않아 획이 더 얇게 읽히고, 11~12px 에서는 그
     얇아진 획이 검은 바탕에 먹힌다. 흰 바탕에서는 반대로 획이 **번져서**
     굵어 보이기 때문에 같은 색 같은 크기가 멀쩡했다 — 그래서 바탕을 뒤집기
     전까지 아무도 몰랐다.

     그래서 가르는 기준을 **크기 × 자간**으로 잡는다.

       흰색(`--ink`)   작고(≤12.5px) 굵고(800) 자간을 벌린 **이름표**
                       — 워드마크 · eyebrow · 묶음 제목 · 표의 열 이름
       회색(`--ink-2`) **읽는 글**(설명 · 안내 · 주석)과 **구조**(칸 이름 ·
                       비활성 · 법정 고지). 자간이 0 이고 크기가 13px 이상
                       이면 6.2:1 로 충분히 읽힌다

     ⚠ **회색을 더 어둡게 하는 쪽으로는 가지 않는다.** '다크그레이를 섞어
       달라' 는 말은 *전부 흰색으로 밀지 말라* 는 뜻이지 지금 회색을 더
       내리라는 뜻이 아니다. 세 번째 단을 만들어 아래로 깔면 (E) 가 고치려던
       것을 다른 자리에서 다시 만든다. 지금 회색이 곧 그 '다크그레이' 단이다.

     ⚠ **머리 메뉴(`.gnb a` · `.subbar a`)는 올리지 않는다.** 둘은 cov-site 의
       `.nav-links a{color:var(--muted)}` → `.on`/hover 에서 흰색과 **같은
       구조**다. 여기서 쉬는 색을 흰색으로 올리면 ① 지금 어느 탭에 있는지를
       알려 주는 **유일한 신호가 색** 이라 그게 사라지고, ② 같은 날 코브
       홈페이지와 이 화면을 본 사람에게 머리가 서로 다른 모양이 된다.
       메뉴 글자는 15px · 자간 0 이라 위 기준에도 애초에 안 걸린다.

     ⚠ **로고는 파일이 이미 흰색이다**(`/logo-mark-white.png`). `filter:invert(1)`
       을 다시 깔지 않는다 — 왜 안 되는지는 `.brand .mark` 주석에 있다. */
  --sans:"Pretendard Variable",Pretendard,system-ui,sans-serif;
  /* 칩 모서리. 2026-09-30 CHOI — 알약(완전한 반원) 말고 라운드 사각형.
     한 곳에 두는 이유는 칩이 여섯 군데에 흩어져 있어서다(거르개 · 카드 머리 ·
     상태 · 코치 이름 · 경력 · 조회 결과). 값을 각자 적어 두면 다음에 고칠 때
     반드시 몇 개가 남고, 그 몇 개는 화면에서 '덜 고친 자리' 로 보인다.
     값은 **높이에 대한 비율**로 정한다. 2026-09-30 CHOI 가 보내온 참고 모양은
     모서리가 높이의 12~14% 였다 — 상자로 읽히되 각지지는 않은 정도다.
     칩 높이가 31~33px 이라 4px 이 그 비율이다. 9px 이면 28% 가 되어
     알약 쪽으로 다시 끌려간다. 고칠 일이 생기면 '몇 px 로 보이나' 가 아니라
     '높이의 몇 %인가' 로 판단한다 — 글자 크기가 바뀌면 같은 px 도 다르게 보인다. */
  --r-chip:4px;
}
*{box-sizing:border-box;margin:0;padding:0}
/* `color-scheme:dark` 는 장식이 아니다. 이게 없으면 스크롤바 · 기본 폼 위젯 ·
   `<select>` 의 펼친 목록 · 날짜 고르개가 밝은 회색으로 남는다 — 검은 화면
   오른쪽에 흰 막대가 붙어 있고, 신청서의 고르는 칸만 흰 바탕이 된다.
   CSS 로 칠할 수 없는 것들이라 여기서 한 번에 넘긴다. */
html{-webkit-font-smoothing:antialiased;color-scheme:dark}
body{font-family:var(--sans);background:var(--bg);color:var(--ink);line-height:1.5}
::selection{background:var(--ink);color:var(--bg)}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,select,textarea{font-family:inherit}
img{display:block;width:100%;height:100%;object-fit:cover}
.wrap{max-width:1040px;margin:0 auto;padding:0 20px}

/* ── 헤더 ───────────────────────────────────────────────────────── */
/* 반투명이라 `var(--bg)` 를 못 쓴다(알파가 필요하다). 머리가 뒤 내용 위로
   붙어 있을 때 글자가 비쳐 보이면 메뉴를 못 읽는다 — 흰 바탕 때의 .92 를
   그대로 두면 검정에서는 더 많이 비친다. 어두운 색은 비치는 것이 눈에 덜
   띄어서, 비치고 있는 줄도 모르고 지나간다. .94 로 올렸다. */
header{position:sticky;top:0;z-index:50;background:rgba(0,0,0,.94);
  backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.hbar{display:flex;align-items:center;gap:26px;height:60px}
.brand{display:flex;align-items:center;gap:9px;flex:none;text-decoration:none;color:inherit}
/* COV 심볼. 검정 원본을 그대로 쓴다 — 예전 로고가 흰색이라 여기에
   `filter:invert(1)` 이 있었는데, 파일만 바꾸고 이 줄을 남기면 흰 바탕에
   흰 로고가 되어 통째로 사라진다.
   높이 26px. 심볼은 거의 정사각형이라(2799x3032) 글자 로고와 같은 높이로
   맞추면 훨씬 작아 보인다 — 가로폭이 절반도 안 되기 때문이다. */
.brand .mark{height:26px;width:auto;object-fit:contain;display:block}
/* 흰색이다. 로고와 한 덩어리로 읽혀야 하는 **이름**이고, 로고 파일이 흰색이라
   여기만 회색이면 묶음의 반쪽만 흐린 것이 된다. 12px · 자간 .08em 으로 이
   파일에서 획이 가장 얇은 글자이기도 하다(위 `--line-2` 아래 기준 참고). */
.brand .wordmark{font-size:12px;font-weight:800;letter-spacing:.08em;color:var(--ink);white-space:nowrap}
.gnb{display:flex;gap:20px;margin-left:auto}
/* nowrap 이 없으면 자리가 모자랄 때 글자가 낱말 안에서 접힌다 — `프로그`/`램`.
   줄바꿈으로 버티면 넘친 사실이 화면에 안 보이고 헤더 높이만 60 에서
   조용히 늘어난다. 넘치면 넘친 것이 보여야 고친다. */
.gnb a{font-size:15px;font-weight:700;color:var(--ink-2);text-decoration:none;
  white-space:nowrap;transition:.15s}
.gnb a.on,.gnb a:hover{color:var(--ink)}

/* ── 헤더 둘째 줄 ───────────────────────────────────────────────────
   신청 조회 · 프로그램 등록. 위 세 탭보다 한 단 약하게 둔다 — 같은 굵기로
   두면 다섯 개가 한 덩어리로 보여서 '클럽 · 트레이닝 · 코치' 가 축이라는
   것이 안 읽힌다. 글자만 작게 하는 것으로는 부족해서 선을 하나 더 깐다.

   `position:sticky` 를 따로 걸지 않는다. 부모인 `header` 가 이미 붙어
   있어서 두 줄이 같이 따라온다. 대신 붙은 머리의 높이가 60 에서 95 가 됐다 —
   화면 안의 닻(anchor)이나 `scroll-margin` 을 건드리는 날 이 수를 본다. */
.subbar{border-top:1px solid var(--line);background:rgba(18,18,18,.72)}
.subbar .wrap{display:flex;gap:18px;align-items:center;height:35px}
.subbar a{font-size:12.5px;font-weight:700;color:var(--ink-2);text-decoration:none;
  white-space:nowrap;transition:.15s}
.subbar a.on,.subbar a:hover{color:var(--ink)}

/* ── 좁은 화면의 헤더 ──────────────────────────────────────────────
   이름과 메뉴가 같이 안 들어간다. 375px 폰에서 쓸 수 있는 가로는
   335px 이다(.wrap 이 양쪽 20 을 먹는다).

   한때 388 까지 가서 53 이 넘쳤다 — 이름이 세 낱말(`[V] SPORTS CLUB`,
   127)이 되고 메뉴가 `프로그램 · 신청 조회 · 프로그램 등록`(261)이던 때다.
   그때의 처방은 **메뉴를 줄이지 않고 이름을 줄이는 것**이었고, 아래 두
   미디어 쿼리가 그 처방이다. 메뉴는 눌러야 하는 것이고 지우면 그 기능으로
   가는 길이 화면에서 없어진다. 이름은 다른 데서도 읽힌다 — 첫 화면의 큰
   제목, 브라우저 탭, 카톡으로 전달될 때 뜨는 카드 제목이 다 같은 이름이다.

   공통 GNB 로 바뀌면서 윗줄이 짧아졌다. 긴 두 낱말이 둘째 줄로 내려갔다.

     이름  [V] + SPORTS CLUB                  127
     메뉴  클럽 · 트레이닝 · 코치               140
                                              ───
                                              281   (54 남는다)

   그래도 아래 쿼리를 걷어내지 않는다 — 코치 탭은 주소가 비면 안 보이고
   (index.html), 탭 이름은 언제든 길어진다. 남는 54 는 여유지 보장이 아니다. */
@media(max-width:480px){
  .hbar{gap:14px}
  .gnb{gap:14px}
  .gnb a{font-size:14px}
  .brand{gap:7px}
  .brand .wordmark{font-size:11px;letter-spacing:.03em}
}
/* 여기부터는 이름을 접는다. 심볼만 남지만 심볼도 목록으로 가는 버튼이고,
   그 목록 맨 위에 이름이 26px 로 다시 나온다. */
@media(max-width:430px){.brand .wordmark{display:none}}

/* ── 히어로 ─────────────────────────────────────────────────────── */
.hero{padding:36px 0 10px}
.hero h1{font-size:26px;font-weight:900;letter-spacing:-.03em}
.hero .hsub{margin-top:6px;font-size:14px;font-weight:600;color:var(--ink-2)}
/* 자간 .12em — 이 파일에서 가장 넓다. 회색으로 두면 제목 위에 흐린 점선처럼
   깔린다. 흰색으로 올려도 제목(26px·900)과 다투지 않는다 — 크기 차이가
   두 배가 넘어서 위아래 관계가 색이 아니라 크기로 읽힌다. */
.eyebrow{font-size:11.5px;font-weight:800;letter-spacing:.12em;color:var(--ink);margin-bottom:8px}

/* ── 거르개 한 줄 ────────────────────────────────────────────────
   종목(테니스 · 러닝)이다. 이름은 서버가 준다 — 여기에 '테니스' 를 적지 않는다.

   **한때 두 줄이었다.** 윗줄이 종류(클럽 · 트레이닝)였고, 그 줄을 트랙에
   담아(`.seg`) 아랫줄과 모양을 갈라 놓는 데 긴 주석이 붙어 있었다.
   2026-10-04 에 종류를 GNB 탭이 가져가면서 윗줄이 사라졌다 — 같은 낱말이
   탭과 칩에 동시에 서면 누른 사람이 그게 종류를 고르는 것인지 홈으로 가는
   것인지 알 수 없다(index.html 에 이유를 적어 뒀다).
   그래서 `.seg` 와 '두 줄의 모양을 가른다' 는 규칙은 통째로 걷어냈다.
   남은 줄이 하나뿐이라 **가를 상대가 없다.** 종류를 다시 칩으로 내리는 날이
   오면 그때 다시 세운다 — 쓰는 데가 없는 규칙을 '나중에 쓸지도 모른다' 로
   남겨 두면, 다음 사람은 그게 지금 어디에 걸리는 모양인지 찾느라 시간을 쓴다. */
.tabs{display:flex;gap:8px;flex-wrap:wrap;padding:20px 0 0;align-items:center}
.tabs:empty{display:none}
/* 거르개는 **누르는 것**이라 `--line-2` 다(맨 위 `:root`). 바로 아래 `.pcat` ·
   `.pstate` 는 모양이 같지만 못 누르는 이름표라 `--line` 을 그대로 쓴다 —
   같은 칩처럼 보이는 둘을 가르는 기준은 모양이 아니라 누를 수 있는지다. */
.tab{font-size:13.5px;font-weight:700;padding:9px 16px;border-radius:var(--r-chip);
  border:1px solid var(--line-2);background:var(--bg);color:var(--ink-2);cursor:pointer;transition:.15s}
.tab:hover{border-color:var(--ink);color:var(--ink)}
.tab.on{background:var(--ink);border-color:var(--ink);color:var(--bg)}

/* ── 종목 줄 ─ 트랙 없이 따로 선 칸 ─────────────────────────────
   라운드 사각형을 담는 트랙 없이 나란히 둔다. 한 단 작게 잡는다 — 머리글
   아래에 딸린 줄이지 제목과 겨루는 줄이 아니다.

   `.sub` 라는 이름은 '아랫줄' 이라는 뜻으로 붙은 것이다. 위에 있던 종류 줄이
   사라진 뒤로는 유일한 줄이지만 이름은 그대로 둔다 — 쓰는 데가
   `index.html` 의 `class="tabs sub"` 한 곳이고, 이름을 고치는 값에 비해
   두 파일이 동시에 어긋날 위험이 크다.

   ⚠️ `:first-of-type{margin-left:3px}` 이 있었다. 윗줄 트랙의 3px 패딩만큼
      아랫줄 첫 칩을 밀어서 두 줄의 왼쪽 끝을 맞추던 값이다. 맞출 윗줄이
      없어졌으므로 뺐다 — 남겨 두면 종목 줄만 혼자 3px 안으로 들어가 있고,
      그건 머리글·카드의 왼쪽 선과 어긋난다. */
.tabs.sub{padding-top:11px}
.tabs.sub .tab{font-size:12.5px;padding:7px 13px}

/* 줄 앞의 이름표. 칩만 서 있으면 무엇으로 나눈 줄인지가 어디에도 안 적혀
   있다 — '테니스 / 러닝' 만 놓이면 그게 거르개인지 지금 열린 종목의 목록인지
   읽는 사람이 눌러 보고 알아낸다. */
.tabs .tlab{flex:0 0 40px;font-size:11.5px;font-weight:800;letter-spacing:.02em;
  color:var(--ink-2)}
@media(max-width:560px){.tabs .tlab{flex:0 0 100%;margin-bottom:-2px}}

/* ── 프로그램 카드 ───────────────────────────────────────────────
   사진은 코트다. 코치스의 카드 사진은 사람이었지만 여기서 팔리는 것은
   사람이 아니라 '거기서 3개월을 보낸다' 는 것이라, 얼굴 자리에 코트가 온다.
   (촬영 자산이 없는 프로그램도 있으므로 사진은 없으면 그냥 빠진다.)

   사진을 넣어도 조건(언제·어디서·얼마)은 카드 본문에 그대로 둔다 —
   목록에서 실제로 비교되는 것은 사진이 아니라 그 세 줄이고,
   그걸 상세로 밀어 넣으면 비교하려고 카드를 하나씩 열어야 한다. */
.grid{display:grid;grid-template-columns:repeat(2,1fr);gap:18px;padding:18px 0 40px}
@media(max-width:760px){.grid{grid-template-columns:1fr}}
/* ⚠️ 한 장일 때 칸을 넓히던 규칙을 **걷어냈다** (2026-10-16 CHOI).

   있던 규칙은 이것이었다.

     @media(min-width:761px){
       .grid:has(.pcard:only-child){grid-template-columns:minmax(0,640px)}
     }

   취지는 '2열에 카드가 하나면 오른쪽이 통째로 비어 아직 안 만든 자리처럼
   읽힌다' 였다. 그런데 그 처방이 **카드 폭을 두 종류로 만들었다.** 한 장
   짜리 화면에서는 640px, 두 장짜리에서는 (1200-18)/2 ≈ 591px 다. 클럽은
   프로그램이 하나고 트레이닝은 둘이어서, 두 탭을 번갈아 보면 같은 모양의
   카드가 탭마다 다른 크기로 선다.

   2026-10-16 CHOI: *"멤버십 클럽 보여주는 크기도 트레이닝 크기랑 동일하게
   해줘. 한 칸에 두 개 들어갈 수 있게끔, 밑으로 두 개씩 정렬될 수 있게끔.
   만약에 하나만 있더라도 센터에 있지만 왼쪽 정렬."*

   그래서 칸의 수를 장수에 따라 바꾸지 않는다. 한 장이면 왼쪽 칸에 서고
   오른쪽은 빈다 — 그 빈자리는 결함이 아니라 **'칸은 둘인데 하나뿐'** 이라는
   사실이고, 다음 프로그램이 들어올 자리를 보여 준다.

   같은 판단이 코치 명단에 이미 한 번 있었다 — '명단은 왼쪽부터 차례대로
   채운다'(`.ccards` · b193290). 마지막 한 장만 가운데로 빠지니 읽는 순서가
   거기서 끊겼다. 여기도 같은 이유로 왼쪽에 둔다. 가운데로 옮기지 않는 것은
   원래 규칙의 판단이 맞았다 — 제목과 거르개가 왼쪽에 붙어 있다.

   되돌리고 싶어지면 **폭이 두 종류가 되는 것**을 먼저 본다. 넓히는 것이
   아니라 둘째 프로그램을 올리는 것이 답이다.
   (.empty 는 grid-column:1/-1 로 두 칸을 다 쓰므로 여기 해당되지 않았다.) */
.pcard{cursor:pointer;text-align:left;width:100%;border:1px solid var(--line);border-radius:18px;
  background:var(--panel);padding:0;overflow:hidden;transition:.2s;display:flex;flex-direction:column}
.pbody{padding:24px 24px 22px;display:flex;flex-direction:column;gap:14px}
/* 사진 칸의 높이를 aspect-ratio 로 고정한다. 이미지가 늦게 도착해도
   카드 높이가 안 변해서, 목록이 다 뜬 뒤 아래가 밀리는 일이 없다. */
.pshot{aspect-ratio:16/9;background:var(--line);overflow:hidden}
.pshot img{width:100%;height:100%;object-fit:cover;display:block;transition:.35s}
.pcard:hover .pshot img{transform:scale(1.03)}
/* 코치 얼굴 줄 — 사진 아래쪽에 걸쳐 얹는다.
   `.pbody` 의 첫 칸이라 margin-top 음수가 padding 위로 뚫고 올라간다.
   `position:relative` 가 없으면 사진 뒤로 깔린다(배경은 앞 형제의 이미지보다 먼저 칠해진다).
   테두리는 `box-shadow` 로 준다 — border 로 주면 4:5 가 테두리만큼 어긋난다.
   색은 **카드 바탕색**이다(흰 바탕 때는 그래서 흰색이었다). 얼굴이 6px 간격으로
   겹쳐 서는 줄이라, 그 틈이 카드와 같은 색이어야 얼굴 네 개가 따로 떨어져
   보인다. `#fff` 를 그대로 두면 검은 카드 위에 흰 윤곽선 네 개가 남는다.
   `height:auto` 를 빼면 위쪽 전역 `img{height:100%}` 가 aspect-ratio 를 눌러
   사진 칸만 키가 커진다(맨 위 img 규칙 참고). */
.pfaces{margin-top:-30px;position:relative;display:flex;gap:6px;padding-bottom:2px}
.pfaces.bare{margin-top:0}
.pfaces img{width:38px;height:auto;aspect-ratio:4/5;border-radius:9px;
  object-fit:cover;background:var(--soft);display:block;box-shadow:0 0 0 3px var(--panel)}
/* 호버 그림자를 뺐다. 검은 바탕에서 검은 그림자는 아무것도 하지 않는다 —
   규칙은 남아 있고 화면에는 효과가 없어서, 다음에 보는 사람이 '들린 느낌이
   왜 안 나지' 를 규칙 바깥에서 한참 찾게 된다. 들림은 테두리와 `translateY`
   둘이 말한다. 빛나는 그림자(흰 글로우)로 바꾸지 않는다 — 카드 네 장이
   동시에 빛나면 사진이 유일한 색이라는 규칙이 먼저 깨진다. */
.pcard:hover{border-color:var(--ink);transform:translateY(-3px)}
.pcard:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.pcard-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* 카드 머리에 종류 알약(`.pkind`)이 같이 있었다. 검은 알약으로 종류, 테두리
   알약으로 종목을 적어 위 거르개 두 줄과 같은 순서를 가르치던 것이다.
   2026-10-04 에 종류가 GNB 탭으로 올라가면서 뺐다 — 트레이닝 탭 아래 선
   카드가 전부 '트레이닝' 이라고 적으면 탭 · 머리글 · 카드가 같은 낱말을 한
   화면에서 세 번 말한다. 규칙도 같이 지운다. 안 쓰는 클래스가 남아 있으면
   다음 사람이 화면에서 그걸 찾느라 시간을 쓴다.

   종목 알약은 남는다. 한 화면에 테니스와 러닝이 같이 서기 때문이다. */
.pcat{font-size:11px;font-weight:800;padding:4px 9px;border-radius:var(--r-chip);
  border:1px solid var(--line);background:var(--bg);color:var(--ink-2)}
.pstate{font-size:11px;font-weight:800;padding:5px 10px;border-radius:var(--r-chip);
  border:1px solid var(--line);color:var(--ink-2)}
.pstate.open{background:var(--ok);border-color:var(--ok);color:#FFFFFF}
.pstate.few{background:var(--bg);border-color:var(--warn);color:var(--warn)}
/* 미개설. 회색으로 두지 않는다 — '종료' 와 같은 색이면 같은 소식으로 읽힌다.
   이건 환급이 걸린 소식이라 눈에 걸려야 한다. */
.pstate.off{background:var(--bg);border-color:var(--err);color:var(--err)}
.pcard h2{font-size:19px;font-weight:900;letter-spacing:-.02em}
.pcard h2 span{display:block;margin-top:4px;font-size:13.5px;font-weight:700;color:var(--ink-2)}
.ptag{font-size:13.5px;color:var(--ink-2);line-height:1.6}
.pfacts{display:flex;flex-direction:column;gap:7px;border-top:1px solid var(--line);padding-top:14px}
.pfact{display:flex;gap:12px;font-size:13.5px}
.pfact b{flex:0 0 62px;font-weight:700;color:var(--ink-2)}
.pfact span{font-weight:600}
.pcard-cta{font-size:13.5px;font-weight:800;margin-top:2px}
.pcard-cta.off{color:var(--ink-2)}

/* ── 모집 현황 ──────────────────────────────────────────────────────
   목표 · 최소 개설선 · 마감. 카드에서는 compact, 상세에서는 전체를 그린다.
   같은 마크업을 공유하므로 여기 한 벌만 있다. */
.goal{display:flex;flex-direction:column;gap:10px}
.ghead{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
/* 모집 현황 묶음의 이름표. 아래 숫자가 무엇을 센 것인지 말하는 유일한 줄이라
   흐리면 막대만 보고 무엇의 몇 %인지 모른다. */
.glabel{font-size:12px;font-weight:800;letter-spacing:.02em;color:var(--ink)}
/* 남은 시간. 마감이 다가오는 것이 이 화면에서 유일하게 움직이는 값이라
   숫자 폭이 흔들리지 않게 tabular-nums 를 준다. */
.gleft{font-size:12px;font-weight:800;color:var(--warn);font-variant-numeric:tabular-nums}
.gnum{display:flex;align-items:baseline;gap:6px}
.gnum b{font-size:26px;font-weight:900;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.gnum span{font-size:13px;font-weight:700;color:var(--ink-2)}
.gnum em{margin-left:auto;font-style:normal;font-size:13px;font-weight:800;color:var(--ink-2);
  font-variant-numeric:tabular-nums}

/* 막대. height 를 명시하는 이유 — app.css 맨 위의 img 전역 규칙과 같은 함정이
   여기에도 있다. 안쪽 <i> 는 width 만 인라인으로 받으므로 높이는 여기서 준다. */
.gbar{position:relative;height:8px;border-radius:100px;background:var(--soft);overflow:hidden}
.gbar>i{display:block;height:100%;border-radius:100px;background:var(--ink);
  transition:width .4s ease}
/* 최소 개설선 눈금. overflow:hidden 안에 있으므로 100% 위치에서도 잘리지 않게
   translateX 로 폭의 절반을 되돌린다. */
.gbar>u{position:absolute;top:-2px;width:2px;height:12px;background:var(--warn);
  transform:translateX(-1px);text-decoration:none}

/* 한 문장 안내. 세 구간의 색이 다르다 — 아직 모자란 것과 이미 넘긴 것은
   같은 톤으로 읽히면 안 된다. */
.gsay{font-size:13px;line-height:1.6;font-weight:600;color:var(--ink-2)}
.gsay.need{color:var(--warn)}
.gsay.safe,.gsay.done{color:var(--ok)}
/* 분자가 무엇인지 못 박는 줄. 이걸 빼면 '24명 중 9명' 이 신청자 수로 읽힌다. */
.gnote{font-size:11.5px;line-height:1.6;color:var(--ink-2)}
.gnote b{font-weight:800;color:var(--ink)}

/* 카드 안의 축소판. 문장과 주석은 상세가 갖고, 카드는 숫자만 남긴다 —
   카드는 비교하는 자리다. 다만 '목표 · 입금 · 퍼센트' 세 가지는 줄여서라도
   남긴다(app.js goalBlock 의 주석 참고). */
.goal.compact{gap:7px;border-top:1px solid var(--line);padding-top:14px}
.gmeta{display:flex;align-items:baseline;gap:8px}
.gmeta b{font-size:13.5px;font-weight:800;font-variant-numeric:tabular-nums}
/* 퍼센트는 숫자 바로 옆에 붙인다. 오른쪽 끝으로 밀면 마감 문구와 자리를
   다투고, 마감일이 없는 프로그램에서는 카드 한가운데가 비어 보인다. */
.gmeta em{font-style:normal;font-size:12px;font-weight:800;color:var(--ink-2);
  font-variant-numeric:tabular-nums}
.gmeta span{margin-left:auto;font-size:12px;font-weight:700;color:var(--warn);
  font-variant-numeric:tabular-nums}

/* 다 찬 카드. 목록에서 훑을 때 막대 길이만으로는 100% 와 90% 가 구별되지
   않는다 — 둘 다 그냥 긴 검은 줄이다. 색을 바꿔서 '이건 다른 상태' 라는
   신호를 먼저 주고, 숫자 대신 말로 못 박는다. */
.gbar.full>i{background:var(--ok)}
/* ⚠️ `.done` 을 쓰지 않는다. 그건 이미 **신청 완료 화면** 전체가 쓰는 이름이다
   (아래 `.done{max-width:600px;margin:0 auto;text-align:center}`). 카드 안의
   모집 블록에 그 이름을 붙였더니 완료 화면용 규칙이 그대로 걸려서 막대가
   441px → 73px 로 쪼그라들고 글자가 가운데로 몰렸다(2026-09-20).
   이 파일의 클래스 이름은 전역이다 — 한 블록 안에서만 쓰는 수식어라도
   접두사를 붙인다. */
.goal.compact.gdone .gmeta b{color:var(--ok)}

/* 목록이 비었을 때. 지어내지 않는다 — 없으면 없다고 쓴다.
   점선은 `--line-2` 다(맨 위 `:root` 참조). `--line` 으로 그리면 1px 점선이
   흰 바탕에서 안 보여서, '없다' 고 적어 둔 상자가 떠 있는 글자 뭉치로 읽힌다. */
.empty{grid-column:1/-1;text-align:center;padding:64px 20px;border:1px dashed var(--line-2);border-radius:18px}
.empty-t{font-size:16px;font-weight:800}
.empty-b{margin-top:8px;font-size:14px;color:var(--ink-2);line-height:1.7}

/* ── 상세 ───────────────────────────────────────────────────────── */
.detail{padding:14px 0 40px}
/* 코트 사진. 첫 장을 크게 두고 나머지를 아래에 나란히 놓는다.
   전부 같은 크기로 늘어놓으면 셋 중 무엇을 보라는 것인지가 없어진다. */
.dshots{margin:20px 0 4px;display:flex;flex-direction:column;gap:10px}
.dshots img{width:100%;display:block;border-radius:14px;background:var(--line);object-fit:cover}
/* max-height 가 없으면 넓은 화면에서 첫 장이 600px 넘게 자라서
   일정·참가비가 전부 스크롤 아래로 밀린다. 사진은 분위기고
   사람이 실제로 확인하러 온 것은 그 조건이다. */
.dshots .lead{aspect-ratio:2/1;max-height:360px}
.dshots .rest{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.dshots .rest img{aspect-ratio:2/1}
@media(max-width:560px){.dshots .rest{grid-template-columns:1fr}}
.back{font-size:14px;font-weight:700;color:var(--ink-2);padding:8px 0;margin-bottom:8px}
.back:hover{color:var(--ink)}
.dhead{padding:12px 0 24px;border-bottom:1px solid var(--line)}
.dhead h1{font-size:30px;font-weight:900;letter-spacing:-.03em;line-height:1.25}
@media(max-width:560px){.dhead h1{font-size:24px}}
.dhead .dsub{margin-top:8px;font-size:15px;font-weight:700;color:var(--ink-2)}
.dhead .dtag{margin-top:14px;font-size:15px;line-height:1.7;max-width:640px}

/* 마감 뒤의 결과. 뒤로가기 바로 아래, 제목보다 위에 둔다 —
   이미 신청한 사람이 결과를 보러 들어오는 자리라서, 프로그램 소개를
   스크롤해 내려가야 결과가 나오면 그건 결과를 알린 것이 아니다. */
.dresult{margin:8px 0 4px;padding:16px 18px;border-radius:14px;border:1.5px solid var(--line);
  display:flex;flex-direction:column;gap:6px}
.dresult b{font-size:15.5px;font-weight:900;letter-spacing:-.02em}
.dresult span{font-size:13.5px;line-height:1.65;color:var(--ink-2)}
/* 바탕 물들이기는 알파 5% 였다 — 흰 바탕에서 그게 '아주 옅은 초록' 이다.
   검은 바탕에서는 어두운 색을 5% 섞어도 아무 변화가 없다(검정에 검정을
   섞는 셈이다). 상자가 통째로 안 물들고 테두리만 남는데, 테두리 색이
   초록인지 빨강인지는 1.5px 에서 잘 구분되지 않는다 — 그 두 상자는
   '배정됐다' 와 '못 열었다' 라서 헷갈려서는 안 되는 쌍이다. 14% 로 올렸다. */
.dresult.confirmed{border-color:var(--ok);background:rgba(30,127,72,.16)}
.dresult.confirmed b{color:var(--ok)}
.dresult.canceled{border-color:var(--err);background:rgba(224,90,82,.14)}
.dresult.canceled b{color:var(--err)}

/* 상세의 모집 현황. 조건 표 바로 위에 상자로 세운다. */
.detail>.goal{margin:24px 0 0;padding:18px;border:1px solid var(--line);border-radius:16px;
  background:var(--panel)}

/* 모집 · 개설 방식.
   모집 현황 바로 아래에 붙인다 — 숫자를 본 다음 문장이 그 숫자의 정체를
   설명하는 순서다. 유의사항 쪽으로 내리면 안 읽힌다. 그러면 안 적은 것과 같다.
   경고 색을 쓰지 않는다. 겁주는 고지가 아니라 운영 방식 설명이다. */
.pact{margin:16px 0 0;padding:20px;border:1.5px solid var(--ink);border-radius:16px;background:var(--bg)}
.pact-h{font-size:16px;font-weight:900;letter-spacing:-.02em}
.pact-s{margin-top:8px;font-size:13.5px;line-height:1.7;color:var(--ink-2)}
.pact-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:18px}
@media(max-width:640px){.pact-grid{grid-template-columns:1fr}}
.pact-col{padding:15px 16px;border-radius:12px;background:var(--panel)}
.pact-col>b{display:block;font-size:12px;font-weight:800;letter-spacing:.02em;margin-bottom:9px}
.pact-col.cov>b{color:var(--ok)}
.pact-col.you>b{color:var(--ink)}
.pact-col ul,.pact-back ul{list-style:none;display:flex;flex-direction:column;gap:8px}
.pact-col li,.pact-back li{position:relative;padding-left:13px;font-size:13px;line-height:1.65;
  font-weight:600;color:var(--ink-2)}
.pact-col li::before,.pact-back li::before{content:"";position:absolute;left:0;top:8px;
  width:4px;height:4px;border-radius:50%;background:var(--ink-2)}
.pact-col li b,.pact-back li b{font-weight:800;color:var(--ink)}
.pact-back{margin-top:16px;padding-top:16px;border-top:1px solid var(--line)}
.pact-back>b{display:block;font-size:13px;font-weight:800;margin-bottom:9px}

/* 입금 안내 안에서 같은 말을 한 번 더. 실제로 돈이 나가는 자리다. */
.pay .trust{margin-top:10px;padding-top:10px;border-top:1px solid var(--line);
  font-size:12.5px;line-height:1.7;color:var(--ink-2)}
.pay .trust b{font-weight:800;color:var(--ink)}

/* 다음 기수 알림. 두 칸을 나란히 두되 폰에서는 접는다 —
   신청 폼의 두 칸 줄이 480px 아래에서 붙어 읽혔던 것과 같은 함정이다. */
.arow{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:14px}
@media(max-width:480px){.arow{grid-template-columns:1fr}}
.alertbox .submit{margin-top:16px}

/* 조건 표 — 언제·어디서·얼마. 상세에서 가장 먼저 읽히는 자리다.

   **항목 이름과 값의 크기를 뒤집어 놓는다.** 예전에는 둘 다 14px 이고
   굵기만 700/600 으로 달라서, 눈이 '일정' 과 '매주 목요일 20:00' 중
   어느 쪽을 먼저 읽어야 하는지 모르는 표였다. 읽으려고 오는 것은 값이고
   항목 이름은 값이 무엇인지 알려 주는 꼬리표다. 그래서 이름은 12.5px 회색으로
   내리고 값은 16px 로 올렸다. 칸 폭도 74 → 52px 로 줄여 값 쪽에 넘긴다.

   `tabular-nums` — 시각·금액·회차가 이 표의 대부분이다. 비례폭 숫자는
   `20:00` 과 `23:00` 의 자릿수가 어긋나 보여서, 한 줄 안에서도 숫자가
   덜컹거린다. `baseline` 정렬은 크기가 다른 이름과 값의 밑선을 맞춘다 —
   안 맞추면 작은 글자가 큰 글자 위쪽에 떠 있다. */
.dspec{display:grid;grid-template-columns:repeat(2,1fr);gap:0;border:1px solid var(--line);
  border-radius:16px;overflow:hidden;margin:24px 0 4px}
@media(max-width:560px){.dspec{grid-template-columns:1fr}}
.dspec .row{display:flex;gap:18px;align-items:baseline;padding:17px 20px;
  border-bottom:1px solid var(--line);font-variant-numeric:tabular-nums}
.dspec .row:nth-child(2n){border-left:1px solid var(--line)}
@media(max-width:560px){.dspec .row:nth-child(2n){border-left:none}}
/* 줄 수가 홀수면 마지막 한 줄이 왼쪽 칸에만 앉고 오른쪽 절반이 빈 흰 칸으로
   남는다 — 표가 덜 그려진 것처럼 보인다. 그 줄만 두 칸을 걸친다.
   (specRow 가 빈 값을 안 그리므로 줄 수는 프로그램마다 다르다.) */
.dspec .row:last-child:nth-child(odd){grid-column:1/-1}
.dspec .row b{flex:0 0 52px;font-size:12.5px;font-weight:700;color:var(--ink-2)}
.dspec .row span{font-size:16px;font-weight:700;letter-spacing:-.015em;line-height:1.35}
.dspec .row em{display:block;font-style:normal;margin-top:5px;font-size:13px;
  font-weight:500;letter-spacing:0;line-height:1.5;color:var(--ink-2)}

.sec{padding:34px 0 0}
.sec-h{font-size:18px;font-weight:900;letter-spacing:-.02em;margin-bottom:4px}
.sec-s{font-size:13.5px;color:var(--ink-2);line-height:1.6;margin-bottom:16px}

/* ── 커리큘럼 슬라이드 (2026-10-16 CHOI) ───────────────────────────
   **한 장씩 넘긴다.** 코트 사진(`.dshots`)과 정반대 규칙이 걸린다.

   `object-fit:contain` — 전역 `img` 규칙의 cover 를 되돌린다. 커리큘럼은
   사진이 아니라 **읽는 장**이고, cover 는 그걸 꽉 채우려고 위아래를
   잘라 낸다. 잘리는 곳에 제목이 있으면 화면은 아무 오류도 내지 않고
   그냥 글자를 숨긴다 — 가장 늦게 발견되는 종류의 결함이다.
   그래서 비율을 모르는 이미지를 받는 자리에는 cover 를 쓰지 않는다.
   남는 자리는 `--soft` 로 둔다. 흰 바탕에 흰 여백이면 장의 경계가
   사라져서 몇 장인지가 안 보인다.

   `scroll-snap` 으로 끊는다. 폰에서는 손가락으로 넘기고, 데스크톱에는
   화살표를 둔다 — 마우스에는 옆으로 밀 방법이 없어서, 화살표가 없으면
   데스크톱 사용자는 **첫 장이 전부라고 생각하고 지나간다.**
   `scrollbar-width:none` 으로 가로 막대를 감추되 `overflow-x:auto` 는
   남긴다. 막대를 감추는 것과 넘기는 길을 막는 것은 다른 일이다. */
.curwrap{position:relative}
.curtrack{display:grid;grid-auto-flow:column;grid-auto-columns:100%;gap:14px;
  overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  scrollbar-width:none}
.curtrack::-webkit-scrollbar{display:none}
.curslide{scroll-snap-align:start;min-width:0}
.curslide img{width:100%;height:auto;aspect-ratio:16/10;object-fit:contain;
  background:var(--soft);border:1px solid var(--line);border-radius:14px}
.curslide figcaption{margin-top:10px;display:flex;align-items:baseline;gap:10px}
.curslide figcaption em{flex:none;font-style:normal;font-size:12px;font-weight:800;
  letter-spacing:.02em;color:var(--ink-2);font-variant-numeric:tabular-nums}
.curslide figcaption span{font-size:13.5px;font-weight:600;line-height:1.5;
  color:var(--ink);word-break:keep-all}
/* 화살표는 묶음 오른쪽 위, 제목 줄 높이에 둔다. 슬라이드 위에 얹으면
   이미지의 글자를 가린다 — 가리는 자리가 어디인지는 받는 이미지마다
   달라서 안전한 자리가 없다. */
/* -35px 는 눈대중이 아니다. 제목 줄 가운데와 단추 가운데를 맞춘 값이다
   (제목 27px + 아래 여백 4px → 묶음 위로 35px 올리면 두 중심이 겹친다).
   -44px 로 두면 단추가 제목보다 9px 높이 뜨고, 오른쪽만 한 칸 올라간
   것처럼 보인다. 실측으로 잡은 값이니 글자 크기를 고치면 같이 고친다. */
.curnav{position:absolute;top:-35px;right:0;display:flex;gap:6px}
.curnav button{width:34px;height:34px;border:1.5px solid var(--line-2);border-radius:999px;
  font-size:14px;font-weight:800;color:var(--ink-2);background:var(--bg)}
.curnav button:hover{color:var(--ink);border-color:var(--ink)}
@media(max-width:560px){
  /* 폰에서는 화살표를 지운다. 손가락으로 넘기는 것이 더 빠르고,
     34px 단추 두 개가 제목 줄을 밀어낸다. 넘기는 길은 그대로 있다. */
  .curnav{display:none}
  .curslide img{aspect-ratio:4/3}
}

/* 개념 카드 (point) */
.points{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media(max-width:760px){.points{grid-template-columns:1fr}}
.point{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:18px}
.point b{display:block;font-size:14.5px;font-weight:800;margin-bottom:6px}
.point span{font-size:13.5px;color:var(--ink-2);line-height:1.65}

/* 아카데미 */
.acads{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media(max-width:760px){.acads{grid-template-columns:1fr}}
.acad{border:1px solid var(--line);border-radius:14px;padding:18px}
/* 아카데미가 하나면 폭을 다 쓴다. (2026-10-04 CHOI — "이렇게 여백이 많은데
   중요한 코치를 꼬딱지만하게 만들거야? 4칸 가로로 한줄 넓게쓰자")
   위 3칸 격자는 **세 아카데미가 나란히 서는 로테이션**을 보고 만든 것이다.
   클럽처럼 아카데미가 하나뿐이면 그 한 상자가 1/3 칸에 그대로 들어앉아서
   폭 1000px 중 325px만 쓰고 오른쪽 2/3 가 비었다. 상자가 좁으니 그 안의
   얼굴 격자(.faces, 또 3칸)는 칸마다 90px 밖에 못 받는다 — 화면에서 가장
   중요한 것이 가장 작게 나오고 있었다. 칸이 하나뿐인데 격자를 지키는 것은
   격자를 지키는 게 아니라 쓰지 않는 자리를 지키는 것이다. */
.acad:only-child{grid-column:1/-1}
.acad .an{font-size:15px;font-weight:900}
.acad .ax{margin-top:12px;font-size:13px;color:var(--ink-2);line-height:1.6}

/* 코치 얼굴 줄. 사진이 있는 사람은 사진, 없는 사람은 이니셜 타일이다.
   둘 다 같은 크기·같은 검은 바탕이라 한 줄에 섞여도 어긋나 보이지 않는다.

   **flex 가 아니라 3칸 그리드다.** flex 로 채우면 코치가 둘인 아카데미의 얼굴이
   셋인 아카데미보다 1.5배 커져서, 카드 세 장을 나란히 놓았을 때 얼굴 크기가
   제각각이 된다. max-width 로 눌러도 이번엔 오른쪽에 빈 자리가 남아 잘린 것처럼
   보인다. 칸을 셋으로 고정하면 어느 카드든 얼굴 크기가 같고, 둘뿐인 카드의
   빈 칸은 사고가 아니라 격자로 읽힌다. 넷 이상이면 다음 줄로 넘어간다.

   `height:auto` 를 빼면 안 된다. 위쪽 전역 규칙에 `img{height:100%}` 가 있어서,
   이 규칙이 선택자 우선순위로 이기더라도 height 를 적지 않으면 그 100% 가 그대로
   남는다. 그러면 aspect-ratio 가 무시되어 사진 타일만 키가 커지고, 이름 줄이
   아래 설명 문단을 덮는다. 이니셜 타일은 img 가 아니라서 멀쩡해 보이는 탓에
   화면만 보고는 원인을 못 찾는다. */
.acad .faces{margin-top:12px;display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
/* 상자가 폭을 다 쓰면 얼굴은 4칸이다. 칸마다 약 240px — 3칸 시절의 90px 에서
   두 배 반이다. 여기서도 칸 수를 고정하는 이유는 위 3칸과 같다: 코치가 둘인
   프로그램과 넷인 프로그램의 얼굴 크기가 같아야 한다. 1fr 로 늘리면 둘뿐인
   곳에서 얼굴만 480px 로 커진다. 넷을 넘으면 다음 줄로 넘어가고, 그때도
   칸 폭은 그대로다.
   글자도 같이 올린다. 사진이 두 배 반이 됐는데 이름이 12.5px 에 머물면
   사진 설명처럼 읽히고, 누를 수 있다는 것이 눈에 안 들어온다. */
.acad:only-child .faces{grid-template-columns:repeat(4,1fr);gap:14px}
.acad:only-child .face b{margin-top:10px;font-size:15px}
.acad:only-child .face em{font-size:12.5px}
.acad:only-child .face .more{margin-top:6px;font-size:11.5px}
/* 폰에서는 두 장씩. 좁은 화면에서 4칸을 지키면 칸이 110px 로 내려가서
   고치기 전보다 더 작아진다 — .ccards 가 같은 이유로 2칸을 쓴다. */
@media(max-width:560px){
  .acad:only-child .faces{grid-template-columns:repeat(2,1fr);gap:12px}
  .acad:only-child .face b{font-size:14px}
}
/* `align-self:start` 를 빼면 안 된다. 역할 줄이 한 줄인 코치(‘GCM 아카데미 코치’)와
   두 줄인 코치(‘GCM 아카데미 헤드코치’)가 한 격자에 섞이는데, 그때 짧은 칸이
   세로 가운데로 내려가서 사진 윗변이 옆 칸과 어긋난다. 얼굴 셋이 계단처럼
   보이는데, 원인이 역할 글자 수라는 것은 화면만 보고는 알 수 없다. */
.acad .face{min-width:0;align-self:start}
.acad .face img{width:100%;height:auto;aspect-ratio:4/5;border-radius:10px;
  object-fit:cover;background:var(--soft);display:block}
.acad .face b{display:block;margin-top:7px;font-size:12.5px;font-weight:700;text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 역할 한 줄. 이름 밑에 작게. 없는 코치도 있어서 자리를 비워 두지 않는다 —
   비워 두면 격자에서 어떤 칸만 아래로 길어진 것처럼 보인다. */
/* `word-break:keep-all` — 없으면 '헤드코치' 가 '헤드 / 코치' 로 잘린다.
   한국어는 기본값(break-word)에서 어절 한가운데를 끊는다. */
.acad .face em{display:block;margin-top:2px;font-size:11px;font-weight:600;font-style:normal;
  text-align:center;color:var(--ink-2);line-height:1.35;word-break:keep-all}

/* 누를 수 있는 얼굴.
   button 기본 스타일을 전부 지우고 시작한다 — 브라우저 기본 배경·테두리가
   남으면 격자 안에서 이 칸만 회색 상자가 된다.
   '소개 보기' 칩은 항상 보인다. hover 에만 나오게 하면 폰에서는 영원히
   안 보이고, 이 화면은 대부분 폰에서 열린다. */
.acad button.face{-webkit-appearance:none;appearance:none;background:none;border:0;padding:0;
  font:inherit;color:inherit;text-align:inherit;cursor:pointer;display:block;width:100%}
.acad button.face img{transition:filter .12s,transform .12s}
.acad button.face:hover img{filter:brightness(1.08);transform:translateY(-2px)}
.acad button.face:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:12px}
.acad .face .more{display:block;margin-top:4px;font-size:10.5px;font-weight:800;letter-spacing:.02em;
  text-align:center;color:var(--ink-2);text-decoration:underline;text-underline-offset:2px}

/* 사진이 아직 없는 코치의 이름 줄. 얼굴 격자 밑에 따로 선다.
   빈 사진 칸을 만들지 않으면서 누를 것은 남기는 자리다.
   폰에서 손가락으로 눌러야 하므로 높이를 34px 밑으로 내리지 않는다. */
.cnames{margin-top:12px;display:flex;flex-wrap:wrap;gap:7px}
.cname{-webkit-appearance:none;appearance:none;cursor:pointer;font:inherit;
  min-height:34px;padding:7px 13px;border-radius:var(--r-chip);
  border:1px solid var(--line-2);background:none;color:var(--ink);
  font-size:12.5px;font-weight:700;text-decoration:underline;text-underline-offset:2px}
.cname:hover{background:var(--panel)}
.cname:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* 로스터(코치 섹션)의 이름 줄. 위 `.cnames` 를 그대로 쓰고 **머리말 한 줄만
   더한다**(`.cnh`). 프로그램 상세에서는 아카데미 상자 안이라 그 줄이
   무엇인지 자리가 말해 주는데, 로스터에서는 얼굴 격자 바로 아래에 이름
   알약이 깔려서 머리말이 없으면 '이건 뭔가' 가 된다. 그리고 몇 명인지
   적어야 위 격자가 명단 전체라는 오해가 안 생긴다. */
.cnrow{margin-top:26px;padding-top:20px;border-top:1px solid var(--line)}
.cnh{font-size:13px;font-weight:700;color:var(--ink-2);line-height:1.6;word-break:keep-all}

/* 코치 카드 — 사람마다 한 장. (2026-08-31 CHOI)
   아카데미가 하나뿐인 프로그램이 쓴다. 아카데미 상자가 없으므로 위 .acad
   규칙은 안 걸린다.

   **auto-fit 이다. 고정 칸이 아니다.** 코치 수가 프로그램마다 다른데
   3칸으로 박아 두면 두 사람인 코트에서 오른쪽 한 칸이 통째로 빈다 —
   지금 고치고 있는 것이 정확히 그 증상이다. auto-fit 은 남는 트랙을
   접어서 있는 카드끼리 폭을 나눠 갖는다.

   **사진이 카드 폭을 다 쓴다. 옆에 붙는 섬네일이 아니다.**
   (2026-09-20 CHOI — "코치 이미지 임팩트 더 살려줘. 코브의 장점은 이미지니까.")
   예전에는 96px 짜리를 왼쪽에 세우고 오른쪽에 이름을 뒀는데, 카드 폭이
   300px 을 넘어가면 사진이 카드의 3분의 1도 안 돼서 나머지가 통째로 빈
   흰 공간이 됐다. 우리가 가진 것 중 가장 좋은 것이 화면에서 가장 작았다.
   지금은 세로로 세워 사진 → 이름 순이고, 사진 면적이 4배가 됐다.

   **대신 칸 폭에 상한(320px)을 둔다.** 이게 없으면 카드가 넓어질수록
   얼굴만 커져서, 코치가 둘인 코트와 셋인 코트의 얼굴 크기가 달라진다.
   1fr 로 늘리지 않고 320 에서 멈추고 왼쪽으로 붙인다(`justify-content:start`) —
   섹션 제목과 왼쪽 선이 맞아서 오른쪽에 남는 자리가 '빈 칸' 으로 안 읽힌다.

   위쪽 전역 규칙에 `img{width:100%;height:100%}` 가 있으므로 width 와
   height 를 둘 다 적어야 aspect-ratio 가 산다. */
/* `grid-auto-rows:1fr` — 줄끼리 높이를 맞춘다. 없으면 마지막 줄에 혼자
   남은 카드만 짧다(실측 529 vs 559). 한 줄 안에서는 격자가 알아서
   맞춰 주지만 **줄과 줄 사이는 안 맞춰 준다** — 늘려 줄 짝이 없어서다.
   그 한 장만 짧으면 사진 크기가 달라 보여서 '덜 중요한 사람' 으로 읽힌다. */
.ccards{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,320px));
  justify-content:start;gap:16px;grid-auto-rows:1fr}
.ccards.one{grid-template-columns:minmax(0,360px)}
/* ⚠ **가운데 모으기(`.mid`)는 2026-10-15 CHOI 지시로 걷어냈다. 다시 넣지 않는다.**
   2026-10-06 에 '마지막 줄에 한 장만 남으면 빈 칸이 아니라 빠진 자리로 읽힌다'
   고 보고 명단만 flex 로 바꿔 덜 찬 줄을 가운데로 모았었다. 실제 화면에서는
   반대로 읽혔다 — 위 세 장은 왼쪽 선이 섹션 제목과 맞는데 마지막 한 장만
   혼자 가운데에 서니, **순서가 끊긴 것**처럼 보인다. 명단은 읽는 순서가 있는
   목록이지 전시물이 아니다.

   그래서 **명단도 아카데미 카드와 같이 왼쪽부터 차례대로 채운다.**
   위 `.ccards` 의 `justify-content:start` 하나가 둘을 다 맡는다 — 격자는
   원래 왼쪽에서 오른쪽으로 흘러서, 마지막 줄 한 장은 저절로 맨 왼쪽에 선다.
   `.ccards.mid` 를 되살리면 그 흐름이 마지막 줄에서만 끊긴다. */
/* 폰에서는 두 장씩. 한 장씩 세우면 사진이 화면 폭을 다 먹어서 코치 셋을
   지나는 데만 스크롤 세 판이 필요하다 — 임팩트가 아니라 장애물이 된다. */
@media(max-width:560px){
  .ccards{grid-template-columns:repeat(2,1fr);gap:12px}
  .ccards.one{grid-template-columns:minmax(0,260px)}
  /* 폰도 격자 하나로 끝난다. `.mid` 를 걷어내면서 여기 있던
     `.ccards.mid>.ccard{flex:0 1 calc(50% - 6px)}` 도 같이 뺐다 —
     짝이던 규칙이라 한쪽만 남으면 아무 데도 안 걸리는 죽은 줄이 된다. */
  .ccard .ci{padding:11px 12px 13px}
  .ccard .ci b{font-size:15px}
  /* ⚠ 아래 둘은 **`em` 하나로 못 줄인다.** 바탕 규칙이 `:first-of-type` ·
     `em+em` 으로 갈라져 있어서(아래 '두 줄을 가른다' 참조) 그쪽이 더 세다 —
     여기 `.ccard .ci em` 만 적으면 미디어쿼리 안이어도 안 걸린다. */
  .ccard .ci em:first-of-type{font-size:11.5px}
  .ccard .ci em+em{font-size:12.5px}
  .ccard .ci .more{font-size:12px;padding-top:8px}
}
/* `overflow:hidden` 이 사진의 위쪽 두 모서리를 카드 둥근 모서리에 맞춰 자른다.
   그래서 사진 자체에는 border-radius 를 안 준다. */
.ccard{display:flex;flex-direction:column;text-align:left;min-width:0;
  border:1px solid var(--line);border-radius:14px;padding:0;overflow:hidden}
.ccard img{width:100%;height:auto;aspect-ratio:4/5;
  object-fit:cover;background:var(--soft);display:block}
/* 글상자를 세로 flex 로 세운다. 아래 `.more{margin-top:auto}` 한 줄을
   받기 위해서다 — 왜 그래야 하는지는 거기 적었다. */
.ccard .ci{min-width:0;padding:13px 15px 15px;
  flex:1;display:flex;flex-direction:column;align-items:flex-start}
.ccard .ci b{display:block;font-size:17px;font-weight:800;letter-spacing:-.02em}
/* `word-break:keep-all` — 없으면 '헤드코치' 가 '헤드 / 코치' 로 잘린다. */
.ccard .ci em{display:block;margin-top:5px;font-size:13px;font-weight:600;font-style:normal;
  color:var(--ink-2);line-height:1.45;word-break:keep-all}
/* ── 두 줄을 가른다 (2026-10-16 CHOI — "전체 타이포") ──────────────────
   `em` 이 둘인데 크기 · 굵기 · 색이 같아서 회색 덩어리 하나로 읽혔다.
   둘은 성질이 다르다.
     첫 줄 '코치 · 테니스'      — **모든 카드에 똑같이 있는 분류.**
     둘째 줄 'GCM 아카데미 헤드코치' — **이 사람만의 사실.**
   카드를 훑는 사람이 찾는 건 둘째 줄인데, 첫 줄이 같은 무게로 앞에 서서
   매번 먼저 읽힌다. 그래서 분류줄은 한 치수 내리고, 소속줄은 본문 색으로
   올린다. 상세 화면이 이미 같은 위계다(`.dsub` 작게 / `.dtag` 크게) —
   카드와 상세가 같은 순서로 읽히게 맞춘 것이지 새로 만든 규칙이 아니다. */
.ccard .ci em:first-of-type{font-size:12px;color:var(--ink-2);letter-spacing:.01em}
.ccard .ci em+em{margin-top:4px;font-size:13.5px;font-weight:700;color:var(--ink)}
/* 받는 일(센터계약 · 이벤트 …). 카드에서 제일 좁은 자리라 상세의 칩보다
   한 치수 작다. 폰에서는 한 줄에 둘까지 들어가고 셋째부터 다음 줄로 넘어간다 —
   `flex-wrap` 없이 두면 카드 밖으로 밀려 잘린다.
   `em` 과 달리 회색이 아니다. 이 줄은 '설명' 이 아니라 **누를 조건**이고,
   명단을 읽는 센터 사장이 찾는 바로 그 값이다(2026-10-06 CHOI). */
.ccard .ci .cwant{display:flex;flex-wrap:wrap;gap:5px;margin-top:9px}
.ccard .ci .cwant i{font-style:normal;font-size:11.5px;font-weight:800;
  line-height:1;padding:5px 8px;border-radius:var(--r-chip);
  background:var(--panel);color:var(--ink);word-break:keep-all}
@media(max-width:560px){
  .ccard .ci .cwant{gap:4px;margin-top:7px}
  .ccard .ci .cwant i{font-size:10.5px;padding:4px 7px}
}
/* '소개 보기' 는 항상 보인다. hover 에만 나오게 하면 폰에서는 영원히 안 보이고,
   이 화면은 대부분 폰에서 열린다.

   ── 바닥에 붙인다 (2026-10-16 CHOI — "전체 배치") ─────────────────────
   `margin-top:auto` 다. 한 줄이지만 고치는 건 눈에 띄는 결함이다.
   희망 업무 칩이 없는 코치(쏘요니 · 이소라)의 카드에서 이 줄이 **30px 떠
   있었다**(실측). 한 줄에 선 카드 셋의 마지막 줄 높이가 제각각이면 격자가
   흔들린 것처럼 보이고, 읽는 사람은 그 들쭉날쭉을 '칩이 없다' 가 아니라
   '덜 그려졌다' 로 읽는다. 칩은 있는 사람만 있는 게 맞으니, 비는 자리를
   메우는 대신 **행동 줄을 바닥에 못 박는다.**
   받는 쪽은 위 `.ci` 의 `flex:1;flex-direction:column` 이다. 둘은 짝이라
   한쪽만 지우면 이 줄이 조용히 안 듣는다.

   크기는 11.5 → 13px. 카드에서 **유일한 행동 문구**인데 희망 업무 칩과
   같은 크기여서 이름표들 사이에 섞여 있었다. */
.ccard .ci .more{display:inline-block;margin-top:auto;padding-top:10px;
  font-size:13px;font-weight:800;
  color:var(--ink-2);text-decoration:underline;text-underline-offset:2px}
button.ccard{-webkit-appearance:none;appearance:none;background:none;font:inherit;
  color:inherit;cursor:pointer;width:100%;padding:0}
button.ccard img{transition:filter .18s,transform .18s}
/* 확대로 반응한다. 띄우기(translateY)로 두면 카드가 사진을 잘라내고 있어서
   사진이 올라간 자리에 아래쪽 빈 줄이 생긴다. */
button.ccard:hover img{filter:brightness(1.06);transform:scale(1.035)}
button.ccard:focus-visible{outline:2px solid var(--ink);outline-offset:3px}

/* 코치 소개 창. 동의 전문과 같은 창(privacyOverlay)을 쓴다. */
/* 사진이 없으면 `.cp` 자체가 안 그려진다(이니셜 타일을 얼굴 자리에 놓지
   않는다 — 2026-08-30 CHOI). 그때 `.ch` 하나만 남고 `gap` 은 묶을 것이
   없어 접힌다. 왼쪽에 빈 상자를 남기지 않으려면 자리를 CSS 로 잡지 않고
   요소 유무로 잡아야 한다. */
.coach{display:flex;gap:14px;align-items:center}
.coach .cp{width:88px;height:110px;flex:none;border-radius:12px;object-fit:cover;background:var(--soft);display:block}
.coach .ch{min-width:0}
.coach h3{font-size:21px;font-weight:900;letter-spacing:-.02em}
.coach .crole{margin-top:5px;font-size:13px;font-weight:700;color:var(--ink-2);line-height:1.5}
.coach .cig{display:inline-block;margin-top:8px;font-size:12px;font-weight:800;color:var(--ink-2);
  text-decoration:underline;text-underline-offset:2px}
/* 경력이 짧은 태그 두어 개일 때만. 긴 줄을 알약에 넣으면 알약이 두 줄로
   접히고, 그게 서너 개 서면 어디까지가 한 항목인지 눈으로 못 자른다. */
.ccar{list-style:none;margin-top:16px;display:flex;flex-wrap:wrap;gap:6px}
.ccar li{padding:6px 11px;border-radius:var(--r-chip);background:var(--panel);font-size:12px;font-weight:700;color:var(--ink)}
/* 경력이 여러 줄이고 묶음이 있을 때(선수 경력 / 코치 경력 / COV Training).
   여기서 칩을 쓰면 열두 개가 줄바꿈되며 뒤엉켜서 어느 것이 어느 묶음인지
   사라진다. 묶음이 있는 순간 칩을 버리고 목록으로 간다. */
.cgrp{margin-top:18px}
/* 묶음 사이에 선을 긋는다. 024 로 쏘요니가 26줄, 잭슨이 18줄이 되면서
   18px 여백만으로는 세 묶음이 한 덩어리로 읽혔다 — 줄 간격(1.6)과 묶음
   간격이 비슷하면 눈이 어디서 끊어야 할지 모른다. */
.cgrp+.cgrp{margin-top:16px;padding-top:16px;border-top:1px solid var(--line)}
/* 묶음 제목이 흰색인 이유는 위 두 곳과 같지만, 여기는 **거꾸로 돼 있던 것**을
   바로잡는 쪽이다. 26줄짜리 경력을 세 덩어리로 끊어 읽게 만드는 것이 이 줄인데,
   그러면서 블록 안에서 **가장 흐린 글자**였다 — 구조를 세우는 줄이 제일 안
   보였다. 항목과 같은 흰색이어도 섞이지 않는다: 제목은 800 · 자간 있음 ·
   점(불릿) 없음이고, 항목은 600 · 자간 0 · 점 있음이다. */
.cgrp>b{display:block;font-size:11.5px;font-weight:800;letter-spacing:.03em;color:var(--ink)}
.cgrp ul{list-style:none;margin-top:8px;display:grid;gap:6px}
/* 묶음 제목이 없는 코치(받은 자료에 제목이 없었다). 제목 자리만큼 더
   벌어지면 위 요소와 남남처럼 읽힌다. */
.cgrp>ul:first-child{margin-top:0}
/* 항목은 600 이다. 700 이었는데 제목(800·11.5px)보다 항목(13.5px)이 더 무거워서,
   열 줄이 넘어가면 제목이 목록에 묻혀 묶음이 안 보였다.
   ⚠ 여기 적혀 있던 `제목(…·회색)` · `항목(…·검정)` 은 흰 바탕 때의 말이다.
     2026-10-16 에 바탕이 검정이 되고 제목이 흰색으로 올라가면서 둘 다 틀렸다 —
     지금 둘을 가르는 것은 색이 아니라 굵기와 자간이다. 이 줄의 600 은 그대로
     남는다. 색이 같아진 만큼 굵기 차이가 더 중요해졌다. */
.cgrp li{position:relative;padding-left:11px;font-size:13.5px;font-weight:600;
  line-height:1.6;word-break:keep-all}
.cgrp li::before{content:"";position:absolute;left:0;top:.66em;width:3px;height:3px;
  border-radius:50%;background:var(--ink-2)}
/* 창이 560px 까지 넓어지면 제목을 왼쪽으로 뺀다. 세로로 쌓으면 제목 줄이
   목록 사이에 끼어 전체가 한 줄기로 길어지는데, 왼쪽에 두면 묶음 경계가
   선 하나로 보이고 스무 줄짜리 경력도 세 덩어리로 읽힌다.
   폰에서는 쓰지 않는다 — 제목 칸을 떼면 '윌슨 X 코스모폴리탄 하얏트 호텔
   클래스 헤드코치' 같은 줄이 서너 줄로 접힌다. */
@media(min-width:600px){
  /* 104px 는 가장 긴 제목('SELECTED WORK')이 한 줄로 서는 폭이다. */
  .cgrp{display:grid;grid-template-columns:104px 1fr;gap:0 20px;align-items:start}
  .cgrp>b{padding-top:3px}
  .cgrp ul{margin-top:0}
  .cgrp>ul:first-child{grid-column:2}
}
/* 명단에서 들어가는 한 사람의 **화면**. 위 `.coach` 는 프로그램 상세의
   아카데미 카드에서 여는 시트가 쓰고, 이쪽은 `coachDetailView` 가 쓴다.
   둘을 한 선택자로 묶지 않는다 — 시트는 88px 얼굴에 `h3`, 화면은 132px 에
   `h1` 이라 같은 숫자를 공유할 수 있는 자리가 거의 없다.
   `.dhead` 를 같이 걸어서 이름·부제·역할 줄은 프로그램 상세와 같은 크기로
   선다. 코치 화면만 다른 글자 크기를 갖게 되는 쪽이 더 나쁘다. */
.cdhead{min-width:0}
.cdhead .cdt{min-width:0}

/* ── 사진 묶음 + 이름표의 배치 (2026-10-16 CHOI — "전체 타이포 · 배치") ──
   **장수가 배치를 정한다.**

   셋이면 사진 줄이 1010px 를 가로지르고 그 아래 이름이 선다 — CHOI 가
   말한 '위에 크게, 아래 정보' 그대로다.

   한 장이면 그 배치가 성립하지 않는다. 420px 사진 하나를 위에 놓으면
   **오른쪽 700px 가 통째로 빈다.** 실측이다(1280 폭, 사진 420 + gap).
   그 여백은 '여백' 이 아니라 **빠진 자리**로 읽힌다 — 셋 깔 자리에 하나만
   온 화면처럼 보인다. 그래서 한 장일 때만 이름표를 사진 **옆**에 세운다.
   사진은 그대로 크고, 오른쪽은 이름 · 소속 · 계정이 채운다.

   ⚠ 이걸 `.n2 .n3` 에도 적용하지 않는다. 둘 · 셋은 사진 줄이 이미 폭을
     채우고 있어서, 옆에 이름을 붙이면 사진이 그만큼 작아진다 — 크게
     보여 주려고 만든 묶음이 작아지는 역주행이다.

   ⚠ `.n0`(사진이 아예 없는 사람)은 아무 규칙도 안 걸린다. 그대로 블록으로
     서면 이름이 맨 위에 오고, 그게 맞다 — 옆에 둘 사진이 없다. */
.cdtop{margin-bottom:26px}
.cdtop .cdshots{margin-bottom:0}
.cdtop.n1{display:grid;grid-template-columns:minmax(0,420px) minmax(0,1fr);
  gap:30px;align-items:center}
/* 860 아래에서는 사진 옆에 남는 폭이 이름 한 줄도 못 받는다. 옆에 두면
   '오성국' 이 세로로 쪼개진다 — 그 전에 위·아래로 되돌린다.
   폰(560) 이 아니라 **860** 인 이유: 끊기는 자리는 화면 종류가 아니라
   420px 를 빼고 남는 폭이라서다. */
@media(max-width:860px){
  .cdtop.n1{display:block}
  .cdtop.n1 .cdshots{margin-bottom:20px}
}
.cdhead .cig{display:inline-block;margin-top:12px;font-size:12px;font-weight:800;
  color:var(--ink-2);text-decoration:underline;text-underline-offset:2px}

/* ── 상세 화면의 사진 묶음 (038) ──────────────────────────────────────
   **위에 크게, 정보는 아래.** 2026-10-16 CHOI.

   ⚠ 전에 여기 있던 `.cdhead .cdp`(132x165 얼굴 하나를 이름표 옆에)는
     걷어냈다. 명단 카드와 같은 사진 · 같은 크기였고, 그래서 카드를 눌러
     들어와도 새로 보이는 것이 글자뿐이었다. 다시 넣지 않는다.

   **칸 수를 장수로 못 박는다.** `auto-fit` 을 쓰면 폭에 따라 칸이 생겨서
   두 장일 때 셋째 칸이 빈 채로 선다. 빈 칸은 '아직 안 찍었다' 가 아니라
   '망가졌다' 로 읽힌다(app.js 의 같은 자리 주석). 그래서 `.n1 .n2 .n3`
   셋으로 가른다 — 세 줄이지만 각각이 무엇인지 한눈에 보이고, 테스트가
   못 박을 수 있는 모양이다.

   `max-width` 대신 칸 자체를 `minmax(0,Npx)` 로 재는 이유: 왼쪽 선이
   섹션 제목과 맞아야 한다(명단 격자에서 2026-10-15 에 정한 것과 같은
   규칙 — `justify-content:start`). 묶음에 max-width 를 걸고 가운데로
   모으면 사진 왼쪽 선만 혼자 안쪽으로 들어온다. */
.cdshots{display:grid;gap:10px;justify-content:start;margin-bottom:26px}
.cdshots.n1{grid-template-columns:minmax(0,420px)}
.cdshots.n2{grid-template-columns:repeat(2,minmax(0,330px))}
.cdshots.n3{grid-template-columns:repeat(3,minmax(0,330px))}
/* 전역의 `img{width:100%;height:100%}` 중 **height 를 되돌려야** 한다.
   `aspect-ratio` 는 `height:auto` 가 같이 있어야 듣는다 — 안 적으면
   높이가 부모를 따라가고 비율은 무시된다. 칸이 유동이라 얼굴 칸처럼
   픽셀로 못 박을 수 없어서, 여기는 비율로 잡는다.
   4:5 는 원본 규격이다(`public/coach/*.jpg` 가 640x800). 그래서 `cover`
   가 실제로 자르는 것은 없다 — 다른 비율의 사진이 섞여 들어오는 날
   얼굴이 아니라 가장자리가 잘리도록 `center` 가 아니라 위쪽을 잡는다. */
.cdshots img{width:100%;height:auto;aspect-ratio:4/5;display:block;
  border-radius:14px;object-fit:cover;object-position:50% 20%;background:var(--soft)}
@media(max-width:560px){
  /* 폰에서 셋을 나란히 놓으면 한 칸이 110px 즈음이다 — 사람을 판단할 수
     없는 크기고, 그 크기면 사진을 셋 깐 뜻이 없어진다. 그래서 **옆으로
     미는 줄**로 바꾼다. 78% 로 두면 둘째 장의 왼쪽이 살짝 보여서, 더
     있다는 사실이 화살표 없이도 전해진다.
     한 장뿐이면 밀 것이 없으므로 그대로 꽉 채운다. */
  /* 아래 간격은 이제 `.cdtop` 이 들고 있다. 여기서 `.cdshots` 에 다시
     적으면 `.cdtop .cdshots{margin-bottom:0}` 이 더 세서 안 걸리는
     죽은 줄이 된다. */
  .cdtop{margin-bottom:20px}
  .cdshots{grid-auto-flow:column;grid-auto-columns:78%;grid-template-columns:none;
    overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch}
  .cdshots.n1{grid-auto-columns:100%}
  .cdshots img{scroll-snap-align:start}
}
/* 희망 업무. 쉼표로 이으면 몇 가지인지 눈으로 세야 한다(app.js 주석).
   `.dspec .row` 가 flex 라 알약을 바로 넣으면 18px gap 이 끼므로 한 겹 싼다. */
.dspec .row .cwant{display:flex;flex-wrap:wrap;gap:6px}
.dspec .row .cwant i{font-style:normal;font-size:12.5px;font-weight:700;
  letter-spacing:0;padding:5px 10px;border-radius:var(--r-chip);background:var(--panel)}
.cbio{margin-top:14px;font-size:14px;line-height:1.75;font-weight:600;color:var(--ink-2)}
/* 소개 창을 닫기 전에 마지막으로 남는 문장. 코치 개인의 자랑이 아니라
   코브가 무엇을 하는 회사인지를 적는다. 이 창을 여는 이유가 그것이다. */
.cnote{margin-top:18px;padding-top:14px;border-top:1px solid var(--line);
  font-size:12.5px;font-weight:700;line-height:1.7;color:var(--ink-2)}

/* 로테이션 표 — 이 프로그램의 핵심이라 표로 보여 준다.
   서버가 계산해서 준 것을 그대로 그린다. 같은 식을 여기서 다시 계산하지 않는다. */
/* 표가 520px 라 375px 폰에서는 '3개월 차' 열이 화면 밖에 있다. 옆으로 밀면
   보이지만, 미는 줄을 모르면 그냥 잘린 표로 읽힌다 — 실제로 오른쪽 끝에서
   '쏘요니&잭슨 아카데'까지만 보여서 깨진 화면처럼 보였다.
   3개월 로테이션이 이 프로그램의 핵심인데 3개월 차가 안 보이면 안 된다.

   그래서 오른쪽에 그림자를 깐다. `background-attachment: local, scroll` 이
   핵심이다 — 첫 레이어(흰색 덮개)는 내용을 따라 같이 밀리고 둘째 레이어
   (그림자)는 칸에 붙어 있는다. 끝까지 밀면 덮개가 그림자 자리로 와서
   저절로 사라진다. 스크롤 이벤트를 듣는 JS 가 필요 없고, 따라서 표가
   늘거나 줄어도 손댈 곳이 없다. */
.rotwrap{overflow-x:auto;border:1px solid var(--line);border-radius:14px;
  background:
    linear-gradient(to left, var(--bg) 0 30px, transparent 30px) right center / 30px 100% no-repeat,
    linear-gradient(to left, rgba(244,244,244,.16), transparent 26px) right center / 26px 100% no-repeat;
  background-attachment:local, scroll}
.rot{border-collapse:collapse;width:100%;min-width:520px;font-size:13.5px}
.rot th,.rot td{padding:13px 14px;text-align:left;border-bottom:1px solid var(--line)}
.rot tr:last-child td{border-bottom:none}
.rot th{background:var(--panel);font-weight:800;font-size:12.5px;color:var(--ink-2);white-space:nowrap}
.rot td b{font-weight:800}
.rot td small{display:block;margin-top:2px;color:var(--ink-2);font-weight:600}
.rot .gcell{font-weight:900;white-space:nowrap}
.rot .gcell em{font-style:normal;display:block;margin-top:2px;font-size:12px;
  font-weight:700;color:var(--ink-2)}

/* 유의사항 · FAQ */
.notes{border:1px solid var(--line);border-radius:14px;overflow:hidden}
.note{padding:16px 18px;border-bottom:1px solid var(--line)}
.note:last-child{border-bottom:none}
.note b{display:block;font-size:14px;font-weight:800;margin-bottom:5px}
.note span{font-size:13.5px;color:var(--ink-2);line-height:1.7;white-space:pre-line}
.faq summary{list-style:none;cursor:pointer;font-size:14.5px;font-weight:800;
  padding:16px 18px;display:flex;align-items:center;gap:10px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:'+';margin-left:auto;font-size:16px;color:var(--ink-2);font-weight:700}
.faq[open] summary::after{content:'−'}
.faq div{padding:0 18px 18px;font-size:13.5px;color:var(--ink-2);line-height:1.75;white-space:pre-line}
.faq{border-bottom:1px solid var(--line)}
.faq:last-child{border-bottom:none}

/* 상세 하단 CTA. 자리 수를 여기서 한 번 더 말한다 — 위까지 스크롤해서
   올라가 확인하게 만들면 그 왕복에서 사람이 빠진다. */
.dcta{position:sticky;bottom:0;z-index:30;margin:36px -20px 0;padding:14px 20px 20px;
  background:linear-gradient(180deg,rgba(0,0,0,0),#000 26%);
  display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.dcta .seats{font-size:13.5px;font-weight:700;color:var(--ink-2)}
.dcta .seats b{color:var(--ink);font-weight:900}
.submit{margin-left:auto;flex:0 0 auto;background:var(--ink);color:var(--bg);border-radius:13px;
  padding:16px 34px;font-size:15px;font-weight:800;transition:.15s}
.submit:hover:not(:disabled){transform:translateY(-1px)}
.submit:disabled{background:var(--soft);color:var(--ink-2);cursor:not-allowed;transform:none;box-shadow:none}
@media(max-width:520px){.submit{width:100%;margin-left:0}}

/* ── 폼 (신청 · 조회) ────────────────────────────────────────────── */
.form,.lookup{max-width:640px;margin:0 auto;padding:26px 0 60px}
.form h1,.lookup h1{font-size:26px;font-weight:900;letter-spacing:-.03em;line-height:1.3}
.form .lead,.lookup .lead{margin-top:10px;font-size:14.5px;color:var(--ink-2);line-height:1.7}
/* 폼의 묶음 상자. 테두리가 섹션의 경계를 말하는 선이라 `--line-2` 다.
   ⚠ **`.opt` 도 같은 색이다.** 점선이 실선보다 약하게 읽히므로 색을 한 단
     더 내리면 '선택 항목' 이 아니라 '없는 상자' 가 된다. 반대로 `.opt` 만
     어둡게 하면 선택 묶음이 필수 묶음보다 강해 보인다 — 틈만으로 충분하다. */
.fsec{border:1px solid var(--line-2);border-radius:16px;padding:20px;margin-top:22px}
.fsec.opt{border-style:dashed}
.fsec-h{margin-bottom:16px}
.fsec-h b{display:block;font-size:15px;font-weight:900}
/* 직계 자식만 잡는다. `>` 를 빼면 제목 안의 `<b>…<span class="req">*</span></b>` 까지
   같이 걸려서, 필수 별표가 회색으로 작아진 채 다음 줄로 떨어진다. */
.fsec-h > span{display:block;margin-top:5px;font-size:13px;color:var(--ink-2);line-height:1.6}
.fg{margin-bottom:16px}
.fg:last-child{margin-bottom:0}
.fg label{display:block;font-size:13.5px;font-weight:800;margin-bottom:7px}
.req{color:var(--err);margin-left:3px}
/* 입력 칸. 테두리가 안 보이면 placeholder 글자만 공중에 떠 있어서 어디에
   쓰는 칸인지를 모른다 — `--line-2` 를 쓰는 가장 중요한 자리다. */
.inp{width:100%;border:1.5px solid var(--line-2);border-radius:11px;padding:13px 14px;
  font-size:15px;background:var(--soft);color:var(--ink);transition:.15s}
.inp:focus{outline:none;border-color:var(--ink)}
.inp::placeholder{color:#A6ACB2}
.inp.ta{resize:vertical;line-height:1.6}
/* 두 칸 줄은 아래 여백을 스스로 갖는다. 안쪽 `.fg` 에 맡기면 안 된다 —
   `.fg:last-child{margin-bottom:0}` 이 두 번째 칸에 걸리는데, 480px 아래에서
   한 줄로 접히면 그 칸이 맨 아래가 되면서 다음 항목 이름이 바로 붙는다.
   '성별' 버튼과 '인스타그램 아이디' 가 붙어 한 덩어리로 읽혔다.
   두 칸일 때는 첫 칸의 여백이 줄 높이를 만들어 주고 있어서 화면상 티가 나지 않는다. */
.two{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px}
.two .fg{margin-bottom:0}
.two:last-child{margin-bottom:0}
@media(max-width:480px){.two{grid-template-columns:1fr}}
.hint{margin-top:7px;font-size:12.5px;color:var(--ink-2);line-height:1.6}
/* 입력칸을 채워 주는 도구 줄(주소 검색 · 일정 만들기 · 기간 만들기).
   칸 자체를 대신하지 않는다 — 도구가 만든 문장을 그 위 `.inp` 에 넣고,
   사람은 거기서 그대로 고친다. 그래서 도구가 못 만드는 모양도 막히지 않는다.
   관리자 화면(`admin.css`)에 같은 이름의 규칙이 따로 있다. 한 파일로 합치지
   않는 이유는 `app.js` 쪽 주석에 적어 뒀다 — 합치면 신청자 전화번호와 관리자
   토큰을 든 화면이 참가자 화면의 파일을 같이 읽게 된다. */
.tool{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px}
.btn{border:1.5px solid var(--ink);background:var(--ink);color:var(--bg);border-radius:11px;
  padding:10px 15px;font-size:13px;font-weight:800;cursor:pointer;transition:.15s}
.btn:hover{transform:translateY(-1px)}
.btn.ghost{background:var(--bg);color:var(--ink)}
/* 요일 알약. 폰에서 손가락으로 누르므로 34px 밑으로 내리지 않는다
   (코치 이름 알약 `.cname` 과 같은 이유). */
.wd{border:1.5px solid var(--line-2);background:var(--bg);color:var(--ink-2);border-radius:10px;
  width:38px;height:38px;font-size:13px;font-weight:800;cursor:pointer;transition:.15s}
.wd:hover{border-color:var(--ink)}
.wd.on{background:var(--ink);border-color:var(--ink);color:var(--bg)}
/* 도구 줄 안의 입력칸은 `.inp` 의 `width:100%` 를 벗는다. 안 벗기면 시각 칸
   하나가 줄을 통째로 차지하고 버튼이 다음 줄로 밀린다. */
.tin{width:auto;flex:0 0 auto;padding:9px 11px;font-size:13px}
.tsep{color:var(--ink-2);font-size:13px;margin:0 2px}
.opts{display:flex;flex-wrap:wrap;gap:7px}
.opt2{font-size:13.5px;font-weight:700;padding:11px 16px;border-radius:11px;
  border:1.5px solid var(--line-2);color:var(--ink-2);transition:.15s}
.opt2:hover{border-color:var(--ink)}
.opt2.on{background:var(--ink);color:var(--bg);border-color:var(--ink);font-weight:800}
/* 여러 개를 고르는 줄. 하나만 고르는 줄과 눌린 모양이 같으면 사람이
   '하나만 고르는 줄' 로 읽고 하나만 고른다. 채우지 않고 테두리만 굵힌다. */
.opts.multi .opt2.on{background:var(--bg);color:var(--ink);border-width:2px;padding:10px 15px}
.opts.multi .opt2.on::before{content:"✓ ";font-weight:900}

/* ── 동의 ────────────────────────────────────────────────────────
   다섯 줄이 한 덩어리로 보여야 한다. 흩어 놓으면 '전부 필수' 로 읽혀서,
   선택 두 줄까지 눌러야 하는 줄 알고 마지못해 누른다. */
.agree{display:flex;gap:10px;align-items:flex-start;margin-top:14px;cursor:pointer;
  font-size:13.5px;color:var(--ink-2);line-height:1.6}
.agree input{margin-top:3px;width:17px;height:17px;flex:0 0 auto;accent-color:var(--ink)}
.agree b{color:var(--ink);font-weight:800}
.agree em{display:block;margin-top:3px;font-style:normal;font-size:12.5px;color:var(--ink-2)}
/* 선택 항목은 한 눈에 구별돼야 한다 — 안 눌러도 되는 줄이라는 것이
   글자('(선택)')만으로는 잘 안 읽힌다. */
.agree.opt b{color:var(--ink-2)}
.agree.all{margin-top:0;padding-bottom:14px;border-bottom:1px solid var(--line);font-size:14.5px}
.agree.all b{font-weight:900}
.agree-sec{margin-top:22px}
/* 금액은 값이라 서버에서 온다. 동의 바로 위에 둔다 — 1기 신청서의
   [최종확인] 자리다. 여기서 한 번 더 보이지 않으면 '얼마인지 몰랐다' 가 나온다. */
.agree-price{margin-bottom:16px;padding:13px 16px;border-radius:12px;
  background:var(--ink);color:var(--bg);font-size:14px;font-weight:800}
.plink{color:var(--ink);font-weight:700;text-decoration:underline;text-underline-offset:3px}
/* 제출이 막은 칸. 안내 문구는 제출 버튼 옆에 뜨는데 그 칸은 화면 밖일 수 있어서
   app.js 의 `fail()` 이 여기까지 데려온다 — 데려다 놓기만 하면 여러 칸 중
   어느 것인지 다시 못 찾는다. 손대는 순간 클래스가 떨어진다. */
.fg.bad .inp,.fg.bad .opt2,.fg.bad .filebtn{border-color:var(--err)}
.fg.bad > label,.agree.bad b{color:var(--err)}
/* 번호 인증 줄 — 입력칸 하나 + 버튼 하나가 한 줄에 선다 (코치 · 선수 등록).
   `.vmsg` 는 이미 있었다(그쪽은 영상 칸의 안내 줄이다). 두 줄 모양만 없었다.

   **버튼 폭을 내용에 맡긴다**(`flex:none`). 1fr 로 나누면 '인증번호 받기'
   와 '확인' 의 폭이 같아지고, 두 줄이 위아래로 서면서 글자 수가 다른
   버튼 둘이 같은 폭이라 이상하게 벌어진다. `white-space:nowrap` 은
   '인증번호 / 받기' 로 접히는 것을 막는다 — 접히면 줄 높이가 입력칸보다
   커져서 칸이 위로 밀린다.

   **폰에서도 한 줄로 둔다.** 세로로 쌓으면 입력칸과 버튼 사이가 벌어져서,
   번호를 적고 나서 눌러야 하는 것이 무엇인지 한눈에 안 붙는다.
   그래서 버튼 글자만 줄인다. */
.vrow{display:flex;gap:8px;align-items:stretch}
.vrow .inp{flex:1 1 auto;min-width:0}
.vbtn{flex:none;white-space:nowrap;-webkit-appearance:none;appearance:none;
  cursor:pointer;font:inherit;padding:0 16px;border-radius:11px;
  border:1.5px solid var(--ink);background:var(--ink);color:var(--bg);
  font-size:13.5px;font-weight:800;transition:.15s}
.vbtn:hover:not(:disabled){transform:translateY(-1px)}
.vbtn:disabled{background:var(--soft);border-color:var(--soft);color:var(--ink-2);
  cursor:not-allowed;transform:none}
.vbtn:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
@media(max-width:400px){.vbtn{padding:0 12px;font-size:12.5px}}
.vmsg{margin-top:12px;font-size:13.5px;font-weight:700;line-height:1.6}
.vmsg.err{color:var(--err)}
.vmsg.ok{color:var(--ok)}
.form .submit,.lookup .submit{margin:22px 0 0;width:100%;text-align:center}

/* 영상 칸 — 1기에 가장 막혔던 자리라 화면에서 가장 공들인 칸이다. */
.vidbox{border:1.5px solid var(--line-2);border-radius:14px;padding:18px;background:var(--panel)}
.vidbox.filled{border-color:var(--ink);background:var(--bg)}
.vidpick{display:flex;gap:8px;margin-bottom:14px}
.vidpick button{flex:1;font-size:13.5px;font-weight:700;padding:11px 8px;border-radius:10px;
  border:1.5px solid var(--line-2);background:var(--bg);color:var(--ink-2);transition:.15s}
.vidpick button.on{background:var(--ink);color:var(--bg);border-color:var(--ink);font-weight:800}
.filebtn{width:100%;border:1.5px dashed var(--line-2);border-radius:11px;padding:22px 14px;
  background:var(--bg);font-size:13.5px;font-weight:700;color:var(--ink-2);transition:.15s}
.filebtn:hover{border-color:var(--ink);color:var(--ink)}
.filebtn.has{border-style:solid;border-color:var(--ink);color:var(--ink)}
.bar{height:5px;border-radius:100px;background:var(--soft);overflow:hidden;margin-top:12px;display:none}
.bar.on{display:block}
.bar i{display:block;height:100%;background:var(--ink);width:0;transition:width .2s}

/* ── 접수 완료 ──────────────────────────────────────────────────── */
.done{max-width:600px;margin:0 auto;padding:60px 0 80px;text-align:center}
.done .mk{width:56px;height:56px;border-radius:50%;background:var(--ink);color:var(--bg);
  display:flex;align-items:center;justify-content:center;font-size:26px;margin:0 auto 22px}
.done h2{font-size:23px;font-weight:900;letter-spacing:-.02em}
.done p{margin-top:14px;font-size:14.5px;color:var(--ink-2);line-height:1.8}
.done .card{margin-top:26px;text-align:left;border:1px solid var(--line);border-radius:16px;padding:20px}
.done .card b{display:block;font-size:14px;font-weight:900;margin-bottom:8px}
.done .card p{margin-top:0;font-size:13.5px}
/* 프로그램이 직접 하는 말(apply_note). 제목이 없는 유일한 카드라, 다른
   카드처럼 굵은 머리줄로 시작하지 않는다 — 위의 접수 문장에 이어지는
   같은 목소리다. 그래서 테두리 대신 옅은 바탕으로만 구분한다. */
.done .card.note{background:var(--soft);border-color:transparent;
  font-size:13.5px;color:var(--ink-2);line-height:1.85}
/* 접수 화면의 계좌 칸. 위의 `.done .card b{display:block}` 이 .kv 안의 <b>
   에도 걸려서 '계좌' 라벨이 제 줄을 차지해 버린다 — 되돌려 준다. */
.done .card.pay .kv b{display:inline;flex:0 0 74px;font-size:14px;font-weight:700;
  color:var(--ink-2);margin-bottom:0}
.done .card.pay .kv{margin-top:0}
.done .card.pay p{margin-top:14px;color:var(--ink-2);line-height:1.75}
/* 문단 안의 <b> 도 마찬가지다. 카드 제목만 block 이면 되는데 셀렉터가 카드 전체를
   잡고 있어서, 문장 중간의 <b>신청 조회</b> 가 제 줄을 차지하며 한 문장이 세 줄로
   끊겼다("진행 상황은 / 신청 조회 / 에서 이름과…"). .pay 에만 되돌려 놨던 것을
   문단 전체로 넓힌다 — 카드가 하나 더 생길 때마다 같은 줄을 또 적게 된다. */
.done .card p b{display:inline;font-size:inherit;font-weight:800;color:var(--ink);margin-bottom:0}
.done .btns{display:flex;gap:10px;margin-top:28px}
.done .btns button{flex:1;border:1.5px solid var(--line-2);border-radius:12px;padding:14px;
  font-size:14px;font-weight:800;transition:.15s}
.done .btns button:hover{border-color:var(--ink)}
.done .btns button.key{background:var(--ink);color:var(--bg);border-color:var(--ink)}

/* ── 조회 결과 ──────────────────────────────────────────────────── */
.res{max-width:640px;margin:0 auto 60px;border:1px solid var(--line);border-radius:18px;overflow:hidden}
.res-h{padding:22px;border-bottom:1px solid var(--line)}
.res-h .rtitle{font-size:17px;font-weight:900}
.res-h .rsub{margin-top:5px;font-size:13.5px;color:var(--ink-2)}
.chip{display:inline-block;font-size:12px;font-weight:800;padding:6px 12px;border-radius:var(--r-chip);
  background:var(--soft);color:var(--ink-2);margin-bottom:12px}
.chip.ok{background:var(--ok);color:#FFFFFF}
.chip.act{background:var(--ink);color:var(--bg)}
.res-b{padding:22px}
.res-b + .res-b{border-top:1px solid var(--line)}
.res-b h3{font-size:14px;font-weight:900;margin-bottom:12px}
.kv{display:flex;gap:14px;font-size:14px;padding:9px 0;border-bottom:1px solid var(--line)}
.kv:last-child{border-bottom:none}
.kv b{flex:0 0 84px;font-weight:700;color:var(--ink-2)}
.kv span{font-weight:700;word-break:break-all}
.kv span.big{font-size:17px;font-weight:900}
.copy{margin-left:auto;flex:0 0 auto;font-size:11.5px;font-weight:800;padding:5px 10px;
  border-radius:8px;border:1.5px solid var(--line-2);color:var(--ink-2);transition:.15s}
.copy:hover{border-color:var(--ink);color:var(--ink)}
.paynote{margin-top:14px;font-size:13px;color:var(--ink-2);line-height:1.75;white-space:pre-line}
.steps{display:flex;gap:0;margin-bottom:6px}
.step{flex:1;text-align:center;padding:12px 4px;border:1px solid var(--line);border-right:none;
  font-size:12px;font-weight:700;color:var(--ink-2);background:var(--panel)}
.step:first-child{border-radius:11px 0 0 11px}
.step:last-child{border-right:1px solid var(--line);border-radius:0 11px 11px 0}
.step.on{background:var(--ink);color:var(--bg);border-color:var(--ink);font-weight:800}
.step small{display:block;font-size:10px;font-weight:700;opacity:.72;margin-bottom:2px}

/* ── 푸터 ───────────────────────────────────────────────────────── */
footer{border-top:1px solid var(--line);padding:26px 0 44px;margin-top:20px}
.fmeta{display:flex;align-items:center;gap:12px;flex-wrap:wrap;font-size:12.5px;color:var(--ink-2)}
.fbrand{display:flex;align-items:center;gap:5px;font-weight:700}
.fbrand img{height:15px;width:auto;object-fit:contain}
.sep{width:1px;height:11px;background:var(--line)}
/* 구분선은 한 줄로 들어갈 때만 구분선이다. 폰에서는 바닥글이 세 줄로 접히면서
   구분선이 줄 맨 앞으로 밀려나 '| 개인정보처리방침' 처럼 읽혔다 — 무엇과 무엇을
   나누는지 알 수 없는 막대가 문장 앞에 하나 붙어 있는 꼴이다.
   접히는 폭에서는 지우고 줄바꿈이 대신 나누게 둔다.
   가로 간격까지 0 으로 두지는 않는다. 세 줄로 다 접히는 건 아니어서 — 로고와
   이메일은 한 줄에 같이 남는다 — 0 으로 두면 구분선도 없고 사이도 없어
   `©▮covsportainment@…` 처럼 마크가 글자에 붙는다. 세로만 0 으로 한다. */
@media (max-width:560px){ .fmeta .sep{display:none} .fmeta{gap:8px 10px} }
.fcontact{font-weight:600}
.flink{color:var(--ink-2);text-decoration:none;font-weight:700}
.flink:hover{color:var(--ink)}
/* 사업자 정보. 연락처보다 한 단계 작고 흐리다 — 법이 요구하는 것은 '쉽게 알 수
   있도록' 이지 '눈에 띄도록' 이 아니고, 여섯 항목을 연락처와 같은 크기로 두면
   바닥글의 주인이 바뀐다. 찾으면 있고, 읽으면 읽힌다.

   :empty 가 필요한 이유 — 사업자등록 전에는 여섯 칸이 다 비어서 이 줄이
   빈 상자가 된다. 그때 margin-top 만 남으면 바닥글 아래에 이유를 알 수 없는
   여백이 생긴다. 값이 들어오는 날 저절로 나타난다. */
.fbiz{margin-top:12px;font-size:11.5px;line-height:1.75;color:var(--ink-2);opacity:.75;word-break:keep-all}
.fbiz:empty{display:none}

/* ── 오버레이 (개인정보처리방침) ─────────────────────────────────── */
/* 뒤를 가리는 막. 흰 바탕에서는 .5 로도 뒤가 눌렸는데, 검은 바탕에서는
   검정을 반만 덮는 것이라 뒤 글자가 그대로 읽힌다 — 전문을 열어 둔 채
   뒤 화면의 문장이 같이 보이면 어느 쪽을 읽는 중인지 흐려진다.
   .88 까지 올린 이유는 하나 더 있다. 검은 바탕에서는 **막과 종이가 같은
   계열**이라 .76 에서는 뒤 화면이 희미하게 비쳐 종이의 테두리가 뭉갠다 —
   뒤를 거의 지워야 종이가 종이로 떠오른다. */
.overlay{position:fixed;inset:0;z-index:100;background:rgba(0,0,0,.88);
  display:none;align-items:flex-end;justify-content:center}
.overlay.open{display:flex}
@media(min-width:640px){.overlay{align-items:center}}
/* 종이는 **가장 밝은 들림**(--soft)을 쓴다. 흰 바탕에서는 흰 종이가 어두운
   막 위에 떠서 저절로 갈라졌는데, 검은 바탕에서는 그 대비가 사라진다.
   --panel 로 두면 막(거의 #000)과 1.1:1 이라 모서리가 어디서 끝나는지
   보이지 않는다. --soft 로 올리고 머리카락 선을 한 겹 둘러 **끝을 그린다.**
   선에 --line-2 를 쓰지 않는 이유: 그 값은 '누를 수 있는 것' 전용이다.
   종이는 누르는 물건이 아니라서 다른 테두리와 같은 --line 을 쓴다. */
.sheet{background:var(--soft);box-shadow:0 0 0 1px var(--line);
  width:100%;max-width:560px;max-height:88vh;overflow-y:auto;
  border-radius:20px 20px 0 0}
@media(min-width:640px){.sheet{border-radius:20px}}
.sheet-body{padding:26px 24px 8px;position:relative}
.close{position:absolute;top:16px;right:18px;font-size:24px;line-height:1;color:var(--ink-2)}
.privacy-doc h4{font-size:13.5px;font-weight:900;margin:18px 0 7px}
.privacy-doc ul{padding-left:17px}
.privacy-doc li{font-size:13px;color:var(--ink-2);line-height:1.75;margin-bottom:3px}
.cta{padding:16px 24px 24px}
.btn-ghost{width:100%;border:1.5px solid var(--line-2);border-radius:12px;padding:14px;
  font-size:14px;font-weight:800}
.btn-ghost:hover{border-color:var(--ink)}
