/* 우.아.금 모바일 — 반응형 (모바일 우선, 시안 폭 360px) */

:root {
  --main: #2b4bb1;
  --main-dark: #22398a;
  --sub: #83acdd;
  --pale: #eaf1fa;
  --accent: #ffd252;
  --danger: #d9534f;
  --pay: #ff425f;     /* 결제 계열(결제 버튼·결제 플로팅) */

  --s50: #f8fafc;
  --s100: #f1f5f9;
  --s200: #e2e8f0;
  --s300: #cbd5e1;
  --s400: #94a3b8;
  --s500: #64748b;
  --s600: #475569;
  --s700: #334155;
  --s800: #1e293b;

  --tap: 44px;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--s50);
  color: var(--s800);
  font-family: Pretendard, system-ui, 'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
  -webkit-font-smoothing: antialiased;
  font-size: 14px;
  line-height: 1.5;
}
[hidden] { display: none !important; }
button { font-family: inherit; cursor: pointer; }
/* ⚠️ 폼 요소는 font-family 를 **상속하지 않는다** — 브라우저 기본 UI 폰트로 떨어진다.
   `.input` 에만 걸어 뒀더니 클래스를 안 붙인 select 와 **펼친 목록(option)** 이 다른 글꼴로 나와
   유독 이질적으로 보였다. 태그 자체에 걸어 둔다 (2026-07-29). */
input, select, textarea, option { font-family: inherit; }
/* 아직 오지 않은 회차 등 「목록에는 두되 고를 수 없는」 항목 (2026-08-07).
   ⚠️ 브라우저 기본 disabled 색은 OS·브라우저마다 제각각이라(윈도우 크롬은 거의 안 흐려진다)
      색을 직접 지정한다. 지우지 않고 흐리게 두는 이유 = 전체 일정이 보여야 하기 때문이다. */
option.opt-future, option:disabled { color: var(--s400); }

/* ---------- 공통 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 0; border-radius: 10px; padding: 10px 16px;
  font-size: 14px; font-weight: 700;
  min-height: var(--tap);
  transition: background-color .15s, filter .15s;
}
.btn:disabled { cursor: not-allowed; }
.btn-main { background: var(--main); color: #fff; }
.btn-main:not(:disabled):hover { background: var(--main-dark); }
.btn-main:disabled { background: var(--s300); color: #fff; }
.btn-accent { background: var(--accent); color: var(--main-dark); }
.btn-ghost { background: #fff; color: var(--s600); box-shadow: inset 0 0 0 1px var(--s200); }
.btn-ghost:hover { background: var(--s50); }
.btn-sm { min-height: 34px; padding: 6px 12px; font-size: 12px; border-radius: 8px; }

/* ⚠️ font-size 는 16px 미만으로 내리지 말 것.
   iOS 사파리는 16px 미만 input/select 를 포커스하면 화면을 자동 확대한다. */
.input, select.input {
  width: 100%; min-height: var(--tap);
  border: 1px solid var(--s300); border-radius: 10px;
  padding: 10px 12px; font-size: 16px; font-family: inherit;
  background: #fff; color: var(--s800); outline: none;
}
/* 아직 안 고른 <select> 의 안내 글자(「시/도」·「시/군/구」)만 한 단계 작게 (2026-08-03 사용자 지시).
   고르고 나면 다시 16px 로 돌아온다 — 실제 값은 크게 읽혀야 한다.
   ⚠️★★위 16px 규칙을 어기는 유일한 자리라 **:focus 에서 16px 로 되돌린다** —
      iOS 사파리는 **포커스 시점의 글자 크기**로 확대 여부를 정하므로 이러면 확대되지 않는다.
      (이 두 줄은 한 묶음이다. :focus 줄을 지우면 탭할 때마다 화면이 확대된다) */
select.input.is-ph { font-size: 14px; }
select.input.is-ph:focus { font-size: 16px; }
.input:focus { border-color: var(--main); box-shadow: 0 0 0 3px rgba(43,75,177,.18); }
.input::placeholder { color: var(--s400); }
.input:disabled { background: var(--s100); color: var(--s400); }

.label { display: block; margin-bottom: 6px; font-size: 13px; font-weight: 600; color: var(--s700); }
.hint { margin-top: 6px; font-size: 12px; color: var(--s400); word-break: keep-all; }

/* ---------- 랜딩 ---------- */
.landing {
  display: flex; min-height: 100vh; align-items: center; justify-content: center;
  padding: 24px 16px;
  background: linear-gradient(to bottom right, var(--main), var(--sub));
}
.landing-card {
  width: 100%; max-width: 400px;
  background: #fff; border-radius: 18px; padding: 26px 22px;
  box-shadow: 0 20px 25px -5px rgba(0,0,0,.15);
}
.logo { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 20px; }
.logo img { width: 40px; height: 40px; object-fit: contain; }
.logo-t1 { font-size: 14px; font-weight: 800; color: var(--main); line-height: 1.2; }
.logo-t2 { font-size: 10px; color: var(--s400); }
.landing-title { margin: 0 0 4px; text-align: center; font-size: 18px; font-weight: 800; }
.landing-sub { margin: 0 0 20px; text-align: center; font-size: 12px; color: var(--s400); }
.field + .field { margin-top: 14px; }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
/* ⚠️ 가로 2칸 안에서는 `.field + .field` 의 **세로** 간격이 걸리면 안 된다 —
 *    오른쪽 칸만 14px 내려가 라벨·입력이 어긋난다(2026-07-30 「내 정보 수정」에서 실제로 발생). */
.two-col > .field + .field { margin-top: 0; }
/* 앞 필드와의 간격은 .two-col 이 대신 받는다 — .two-col 은 .field 가 아니라
 * `.field + .field` 가 안 걸려서 위쪽만 붙어 보였다. 다른 필드 간격과 같은 값으로 맞춘다. */
.field + .two-col { margin-top: 14px; }
.err-box {
  margin-bottom: 12px; border-radius: 8px; padding: 9px 12px;
  background: rgba(217,83,79,.1); color: var(--danger);
  font-size: 12px; text-align: center;
}
/* 오류가 아니라 「상황 안내」 — 세션 만료처럼 사용자가 잘못한 게 없는 경우에 쓴다 (2026-07-27).
   붉은 err-box 와 톤을 구분해야 「데이터가 지워졌다」는 오해를 부르지 않는다. */
.warn-box {
  margin-bottom: 12px; border-radius: 8px; padding: 10px 12px;
  background: #fff8e1; color: #8a6100;
  font-size: 12px; line-height: 1.6; text-align: center;
}
.consent { display: flex; gap: 8px; align-items: flex-start; background: var(--s50); border-radius: 10px; padding: 10px 12px; }
.consent input { margin: 3px 0 0; width: 16px; height: 16px; accent-color: var(--main); flex: none; }
.consent label { font-size: 12.5px; color: var(--s600); line-height: 1.55; word-break: keep-all; }

/* ---------- 앱 셸 ---------- */
.appbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  /* 안전영역: 일반 브라우저에선 0. 홈 화면에 추가해 전체화면으로 열었을 때만 값이 생겨
     헤더가 노치·다이나믹 아일랜드 밑으로 들어가는 것을 막는다. */
  padding: calc(10px + env(safe-area-inset-top)) 16px 10px;
  background: rgba(255,255,255,.94); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--s200);
}
.appbar .logo { margin: 0; gap: 8px; }
.appbar-actions { display: flex; gap: 6px; align-items: center; }
/* ★2026-08-15 신설(사용자 지시) — 문의하기가 **하단 플로팅에서 헤더(내 정보 옆)로** 왔다.
   지시는 「현재의 말풍선 이모지만 남기기 · 색은 메인 파란색」이다 = 글자·배경·테두리 없음.
   ⚠️ 그림만 남으면 누를 자리가 그림 크기로 줄어든다 → `min-width/height` 로 손가락 자리(≥40px)를
      따로 준다. 헤더 높이는 안 늘어난다(옆 버튼 `.btn-sm` 이 이미 그만큼 높다).
   ⚠️ 색은 `currentColor` 로 svg 에 흘러간다 — path 에 색을 박지 말 것. */
.appbar-ask {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 40px; min-height: 40px; margin-right: -6px;
  color: var(--main);
  text-decoration: none;
  border-radius: 10px;
}
.appbar-ask:hover, .appbar-ask:focus-visible { background: var(--pale); }
.appbar-ask:focus { outline: none; }
.appbar-ask:focus-visible { box-shadow: 0 0 0 3px rgba(43, 75, 177, .28); }
.appbar-ask svg { display: block; }

.wrap {
  max-width: 460px; margin: 0 auto;
  padding: 14px 16px calc(48px + env(safe-area-inset-bottom));
}

/* 히어로 */
/* ★★2026-08-15 사용자 지시 — 캐릭터를 **1.5배**(74 → 111px)로 키웠다.
   ⚠️ 오른쪽 패딩은 아이콘 자리라 **함께 커져야 한다** = 111 + 오른쪽 여백 14 + 글자와의 숨통 8
      → 96 → **133px**. 패딩만 그대로 두면 글자 위에 캐릭터가 올라앉는다. */
.hero {
  position: relative;
  background: var(--pale);
  border-radius: 16px;
  padding: 18px 133px 18px 18px;
  margin-bottom: 14px;
}
.hero-l1 { font-size: 14px; font-weight: 600; color: var(--s700); }
.hero-l2 { font-size: 19px; font-weight: 800; color: var(--s800); margin-top: 2px; letter-spacing: -.4px; }
.hero-l2 b { color: var(--main); }
.hero-sub { margin-top: 10px; font-size: 13px; color: var(--s500); line-height: 1.6; word-break: keep-all; }
/* ★2026-08-13 사용자 지시 — 📣 이모지에서 캐릭터 이미지(`/class_main.webp`)로 바꿨다.
   ★★2026-08-15 사용자 지시 — **1.5배로 키웠다(74 → 111px).** 위 `.hero` 의 오른쪽 패딩을
      96 → 133px 로 함께 올렸다(= 111 + 오른쪽 여백 14 + 숨통 8).
   ⚠️★★그 대가로 **좁은 폰에서 `.hero-guide` 한 줄이 접힌다** — 아래 그 규칙의 주석에 적어 둔
      계산대로 320px 에서 글자가 쓸 수 있는 폭이 174 → 137px 이 된다(14.5px 로는 두 줄).
      의도한 맞바꿈이다. 다시 한 줄로 만들려면 캐릭터를 줄이는 수밖에 없다.
   ⚠️ 원본은 439×512(세로가 길다) — `height:auto` 로 두어 비율을 코드에 박지 않는다.
      세로는 111 × 512/439 ≈ 129px 이 되어 히어로 높이(글자 3~4줄)를 아직 넘지 않는다. */
.hero-icon {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  width: 111px; height: auto; display: block;
}
/* ★2026-08-08 신설 — 히어로 맨 아래의 「신청하는 방법」 안내 링크(사용자 지시:
   메인 파랑 + 볼드 + 밑줄). 네이버 블로그 글로 나간다.
   ⚠️ `.hero` 는 오른쪽 패딩 96px 로 📣 아이콘 자리를 비워 둔다 — 이 링크도 그 안쪽에 서므로
      **아이콘과 겹치지 않는다**. 대신 폭이 좁으니 `word-break: keep-all` 로 낱말째 접는다.
   ⚠️ `inline-block` + 위 여백 = 밑줄이 글자 폭만큼만 그어지게 하려는 것이다
      (block 으로 두면 줄 전체에 밑줄이 깔린다). */
.hero-guide {
  /* ★2026-08-12: `<a href>` 에서 **버튼**이 됐다(블로그 → 팝업). 링크처럼 보여야 하므로
     버튼 기본값(테두리·배경·안쪽 여백)을 지운다 — 지우지 않으면 회색 알약으로 보인다. */
  border: 0; background: none; padding: 0; text-align: left;
  display: inline-block; margin-top: 12px;
  /* 12.5 → 13.5 → **14.5px** (2026-08-10 사용자 지시: 「살짝 더 키워서 강조」).
     ★첫 화면이 클래스 목록이 되면서 이 링크가 「어떻게 신청하나」의 유일한 안내가 됐다.
     ⚠️ 더 올리면 320px 폰에서 접힌다 — `.hero` 오른쪽 96px 은 📣 아이콘 자리라 글자가 쓸 수
        있는 폭은 320px 에서 174px 뿐이고, 이 줄은 13.5px 에서 158.7px 였다(≈11.76 × 글자크기).
        14.5px → 약 170px 으로 아직 한 줄이다. 15px 을 넘기면 접힌다. */
  font-size: 14.5px; font-weight: 800; color: var(--main);
  text-decoration: underline; text-underline-offset: 2px;
  word-break: keep-all; line-height: 1.5;
}

/* 탭 */
.tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 18px; }
.tab {
  min-height: var(--tap);
  border: 1px solid var(--s200); border-radius: 12px; background: #fff;
  font-size: 14px; font-weight: 700; color: var(--s500);
}
.tab[aria-selected='true'] { background: var(--main); border-color: var(--main); color: #fff; }
/* ★검정 테두리의 정체 = **브라우저 기본 포커스 링**이다 (2026-08-11 사용자 지시로 제거).
   `.tab` 에 `:focus` 규칙이 없으면 UA 가 자기 검정 outline 을 그린다 — 눌러서 고른 탭에
   계속 남아 「선택됨」과 다른 축의 테두리가 하나 더 생긴 것처럼 보인다(0806 `.opt` 와 같은 함정).
   ⚠️ 지우기만 하면 키보드 사용자가 지금 어디 있는지 알 수 없다 → 브랜드 색 링으로 **바꾼다**. */
.tab:focus { outline: none; }
.tab:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(43, 75, 177, .28); }

/* ---------- 요청 폼 ---------- */
.form-title { margin: 0 0 12px; font-size: 15px; font-weight: 800; color: var(--s800); }

/* ---- 3단계 인디케이터 (2026-08-10 신설) ----
   「지금 몇 번째이고 앞으로 몇 개 남았나」를 보여 준다. 지나온 단계는 눌러 돌아갈 수 있고,
   아직 안 온 단계는 **비활성**이다(눌러 건너뛰면 검사를 건너뛰게 된다 → m-app.js paintStepBar).
   ⚠️ 세 칸이 같은 폭(1fr)이라야 단계 이름 길이에 따라 칸이 들쭉날쭉하지 않는다. */
.req-steps {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
  margin: 0 0 16px; padding: 0; list-style: none;
}
.req-step-btn {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 100%; padding: 8px 0;
  border: 0; background: none;
}
.req-step-btn:disabled { cursor: default; }
/* ★2026-08-12 사용자 지시 — 단계 이름을 **1.5배**(10.5 → 16px)로. 「화면을 넘칠 것 같으면
   숫자 사이 간격을 줄여 공간을 확보하라」는 지시대로, 동그라미를 22 → 20px 로 줄이고
   버튼 좌우 padding 을 0 으로 뒀다.
   ⚠️★★`white-space: nowrap` 을 **유지**한다 — 「일정·장소」가 접히면 세 칸 높이가 달라져
      줄이 어긋난다. 대신 320px 에서도 안 잘리는지는 **실측으로** 확인할 것(글자를 키웠으니
      다음에 이름이 길어지면 여기가 가장 먼저 터진다). */
.req-step-n {
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--s200); color: var(--s500); font-size: 11px; font-weight: 800;
}
.req-step-t { font-size: 16px; font-weight: 700; color: var(--s400); white-space: nowrap;
  letter-spacing: -.3px; }
.req-step.is-on .req-step-n { background: var(--main); color: #fff; }
.req-step.is-on .req-step-t { color: var(--main); }
/* ★2026-08-12(3차) 사용자 지시 — **끝난 단계(✓)는 서브 파랑 → 메인 파랑.**
   서브 파랑은 흰 글자와의 대비가 낮아 ✓ 가 흐리게 보였고, 「끝났다」는 표시는 이 화면에서
   가장 분명해야 하는 신호다. ⚠️ **디폴트(아직 안 온 단계)는 그대로 회색**이다 — 셋이 다 파래지면
   어디까지 왔는지가 사라진다. 잇는 선도 같이 맞춘다(선만 서브로 남으면 색이 두 갈래가 된다). */
.req-step.is-done .req-step-n { background: var(--main); color: #fff; }
.req-step.is-done .req-step-t { color: var(--s600); }
/* 칸 사이를 잇는 선 — 「이어진 한 흐름」으로 읽히게 한다.
   ⚠️ 마지막 칸에는 긋지 않는다(오른쪽이 비어 끊긴 선만 남는다). */
.req-step { position: relative; }
/* ⚠️ 동그라미가 22 → 20px 로 줄어 **선의 높이·좌우 시작점도 같이** 내려/좁혀야 한다
   (top = 버튼 padding 8 + 동그라미 20 / 2 = 18 · 좌우 = 동그라미 반지름 10 + 여백 4). */
.req-step:not(:last-child)::after {
  content: ''; position: absolute; top: 18px; left: calc(50% + 14px); right: calc(-50% + 14px);
  height: 2px; background: var(--s200);
}
.req-step.is-done::after { background: var(--main); }

/* ★2026-08-13(3차) 사용자 지시 — **3단계(함께할 친구)만** 인디케이터와 내용 사이를 **2배**로.
   3단계는 0813 에 화면 제목(`.form-title`)을 없애서, 인디케이터 바로 밑에 소제목이 붙어 있었다
   (1·2단계는 제목이 그 사이를 벌린다). 16 → 32px.
   ⚠️★★`margin-top` 으로 주면 안 된다 — 위 형제(`.req-steps`)의 `margin-bottom: 16px` 과
      **상쇄(margin collapsing)** 되어 그대로 16px 다. 상쇄되지 않는 `padding-top` 으로 준다. */
#req-pane-3 { padding-top: 16px; }
/* ★2026-08-13(4차) 사용자 지시 — 1단계의 화면 제목(「어떤 클래스인가요?」)을 없애면서
   **「여백은 그대로 두라」**는 지시가 함께 왔다. `.form-title` 이 차지하던 자리
   = 글자 15px × line-height 1.2(18) + margin-bottom 12 = **30px**.
   ⚠️ 여기도 `padding` 이다 — margin 은 `.req-steps` 의 margin-bottom 과 상쇄된다. */
#req-pane-1 { padding-top: 30px; }

/* 단계 이동 버튼 — 한 줄에 [이전][다음]. 1·3단계는 버튼이 하나뿐이라 그 칸이 오른쪽/왼쪽에 선다. */
.step-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 20px; }
.step-nav .btn { min-height: 48px; font-size: 15px; }
/* 버튼이 하나인 단계 — 1단계는 「다음」만(오른쪽), 3단계는 「이전」만(왼쪽) */
.step-nav-1 { grid-template-columns: 1fr; }

/* ★2026-08-11 사용자 지시 — 좌측 대분류(.row-key)와 우측 내용(.row-val)의 **세로 길이를 맞춘다.**
   예전 `align-items: start` 는 두 칸을 각자 높이로 두어, 내용이 짧은 줄(수업 구분·클래스 형태)에서
   오른쪽만 8px 쯤 짧게 끝나 계단처럼 보였다.
   ⚠️ `stretch` 로 바꾸는 것만으로는 부족하다 — `.row-val` 은 세로 flex 라 늘어난 높이가 **마지막
      자식 아래 빈 자리**로 남는다. 안에 든 옵션 격자(.opts)가 함께 늘어나야 실제로 채워진다. */
.row { display: grid; grid-template-columns: 92px 1fr; gap: 10px; align-items: stretch; margin-bottom: 10px; }
.row-key {
  background: var(--pale); border-radius: 10px;
  padding: 12px 8px; min-height: 56px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
}
.row-key b { font-size: 13px; font-weight: 700; color: var(--s700); }
.row-key span { margin-top: 3px; font-size: 9.5px; color: var(--s500); line-height: 1.35; }
.row-val { display: flex; flex-direction: column; gap: 6px; }
/* 내용이 **한 덩어리뿐인** 줄에서만 그 덩어리를 세로로 늘려 좌측 상자와 끝을 맞춘다.
   ⚠️ `.row-val > *` 에 걸지 말 것 — 지역·요일·시간 줄처럼 자식이 여럿인 곳에서는 안내 상자와
      알약까지 함께 늘어나 화면이 통째로 헐거워진다. `:only-child` 가 그 경계다. */
.row-val > .opts:only-child, .row-val > .input:only-child { flex: 1 1 auto; }

/* 옵션 버튼 */
.opts { display: grid; gap: 6px; }
.opts-2 { grid-template-columns: 1fr 1fr; }
.opts-3 { grid-template-columns: 1fr 1fr 1fr; }
.opts-7 { grid-template-columns: repeat(7, 1fr); gap: 4px; }
.opts-1 { grid-template-columns: 1fr; }

.opt {
  border: 1px solid var(--s300); border-radius: 10px; background: #fff;
  min-height: var(--tap); padding: 8px 6px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: 12.5px; font-weight: 600; color: var(--s600);
  transition: all .12s; text-align: center;
}
.opt small { font-size: 10px; font-weight: 500; color: var(--s400); margin-top: 2px; }
.opt:hover { border-color: var(--sub); }
.opt[aria-pressed='true'] {
  border-color: var(--main); border-width: 2px;
  background: var(--pale); color: var(--main); font-weight: 800;
}
.opt[aria-pressed='true'] small { color: var(--main); }
/* ★2026-08-13 사용자 지시 — **클래스 형태 칸만** 키운다. 두 칸뿐이라 자리가 남고,
   이 화면에서 **가장 먼저 고르는 것**이다.
   ⛔`.opt` 자체는 못 키운다 — 인원·요일·시간이 함께 쓴다(요일은 7칸이라 키우면 320px 에서 넘친다).
   ★★2026-08-13(3차) 사용자 지시 — 두 줄(「원데이」 + 작은 「1회」)을 **한 줄 「원데이 · 1회」**로
   합치고 **크기를 하나로 통일**했다(18.5/15 → 16px). **(4차)에 한 번 더 「아주 살짝」 줄여 15px.**
   ⚠️ `.opt small` 규칙을 여기서 되돌리지 않는다 — 이제 이 칸에 `<small>` 자체가 없다
      (m-app 의 optButton 에 sub 를 안 넘긴다). 되살릴 일이 생기면 그때 다시 적을 것. */
#q-form .opt { font-size: 15px; }

.opt-day { padding: 8px 0; font-size: 13px; }
.opt-time { flex-direction: row; justify-content: flex-start; padding-left: 14px; font-size: 13px; }

/* ---------- 공통 부품 (2026-07-25 공통화) ----------
 * 아래 4종은 원래 teacher.html 의 <style> 안에만 있어서, 같은 클래스명을 쓴
 * 어드민 「강사 등록」 팝업에서는 아무 스타일도 안 먹고 브라우저 기본 모양으로 나왔다.
 * 두 페이지가 같은 부품을 쓰도록 공용 CSS 로 옮긴다. */

/* 선택한 값을 아래에 쌓아 보여주는 알약 (선호 지역·선호 시간대) */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* ⚠️★★`line-height: 1` 은 **정렬을 위한 것**이다 (2026-08-28 실측).
   `align-items: center` 는 글자의 **줄상자**를 가운데에 두는데, 줄상자가 글자보다 크면
   (본문에서 물려받은 줄간격) 그 안에서 글자 잉크가 위로 치우쳐 **「×」만 아래로 내려간 것처럼**
   보인다. 실측(실제 신청 화면 · 8배 확대 · 글자 잉크 중심 대비 × 잉크 중심):
     줄간격 물려받을 때 **+1.62px** → `line-height: 1` 로 **+0.62px**.
   ⛔되돌리지 말 것 — 되돌리면 알약 안에서 × 가 다시 처진다. */
.chip { display: inline-flex; align-items: center; gap: 4px;
  background: var(--pale); color: var(--main); border-radius: 999px;
  padding: 6px 6px 6px 12px; font-size: 12.5px; font-weight: 700; line-height: 1; }
/* 알약의 「×」 — ★2026-08-28 사용자 지시로 **글자와 세로 가운데를 맞췄다.**
 * ⚠️★★글리프 「×」를 그대로 쓰면 맞출 방법이 없다 — 폰트마다 × 가 놓이는 높이가 다르다.
 *    실측(헤드리스 8배 확대 · 글자 잉크 중심 대비 × 잉크 중심, CSS px):
 *      맑은고딕 +1.38 · Segoe UI +1.38 · 돋움 +0.88 · 굴림 +0.13 · 바탕 −0.38
 *    → 「몇 px 올린다」로 고치면 **한 폰트에서만** 맞는다(우리는 웹폰트를 안 실어서
 *      기기마다 다른 시스템 폰트로 그려진다 — iOS 애플 SD 산돌고딕 / 안드로이드 Noto).
 * ★그래서 글리프를 안 쓰고 **선 두 개를 회전시켜 상자 한가운데**에 그린다 — 폰트와 무관하게
 *   기하학적으로 가운데다. 글자 쪽은 실측상 알약 상자 중심과 ±0.5px 안이라 이걸로 맞는다.
 *   고친 뒤 실측: 다섯 폰트 전부 |어긋남| ≤ 0.5px (전에는 최대 1.38px).
 * ⚠️ `font-size: 0` 은 **글리프만** 감춘다 — 접근성 트리에는 남는다(aria-label 도 그대로).
 * ⚠️ 이 부품은 강사 「선호 시간대·가능 지역」·어드민 강사등록도 쓴다 — 가운데 정렬은
 *    그 셋에도 똑같이 옳으므로 여기 한 곳에서 고친다(⛔색은 여전히 따로 두지 말 것). */
.chip button { border: 0; background: none; color: var(--main); padding: 0; flex: none;
  position: relative; display: inline-block; width: 18px; height: 18px;
  font-size: 0; line-height: 0;
  /* ★남은 0.62px 은 **글자 잉크가 자기 em 상자 안에서도 살짝 위**라서 생긴다 — 폰트가 정하는
     값이라 CSS 로는 알 수 없다. 그래서 **실제 화면에서 재서** 그만큼만 올린다.
     ⚠️`top`/`margin` 은 소수점이 스냅돼 안 먹는다(실측: -0.5px·-0.25px 둘 다 변화 0) —
        **`transform` 만** 소수점이 그대로 먹는다.
     실측 결과(고친 뒤 · 글자 잉크 중심 대비): Pretendard **0.00** · 맑은고딕 −0.62 · 본고딕 −0.75.
       (고치기 전: Pretendard +1.62 · 맑은고딕 +0.00 · 본고딕 +0.88 — 최대 오차가 줄었다)
     ★사장님 화면은 Pretendard 다(이 PC 에 설치돼 있다) — 거기에 맞춘다. */
  transform: translateY(-0.6px); }
.chip button::before,
.chip button::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 10px; height: 1.6px; border-radius: 1px; background: currentColor;
}
.chip button::before { transform: translate(-50%, -50%) rotate(45deg); }
.chip button::after { transform: translate(-50%, -50%) rotate(-45deg); }
/* 브랜드 옐로 알약 (2026-08-28 사용자 지시).
   쓰는 곳 = **클래스 신청의 「희망 시간」** · **강사 「내 정보 수정」 팝업의 가능 지역·시간대**
     · **강사 지원서의 가능 지역·시간대**(2026-09-01 추가).
   ⛔`.chip` 을 통째로 칠하지 말 것 — **어드민 강사등록 팝업은 파란 알약 그대로**다.
   ⚠️이름이 `chip-time` 이었는데 지역에도 붙으면서 **`chip-accent`(색을 가리키는 이름)** 로 바꿨다 —
     「시간」이라는 이름으로 지역 알약을 칠하면 다음 사람이 잘못 읽는다.
   ★대비비 = #000 on #ffd252 → **14.6:1** (AAA). 옐로에 흰 글자였다면 1.4 라 안 보인다. */
.chip.chip-accent { background: var(--accent); color: #000; }
.chip.chip-accent button { color: #000; }

/* ---------------- 세그먼티드 컨트롤 (2026-08-28 신설 · 사용자 지시) ----------------
   두 갈래 중 하나를 고르는 알약 막대. 지금 쓰는 곳 =
     · 강사 「내 클래스」 — 진행 중인 클래스 / 완료 클래스
     · 어드민 「기타 일정 등록」 — 문화센터의 원데이 / 정규
   ★두 화면이 **같은 부품**을 쓰도록 app.css 에 둔다(화면마다 따로 만들면 모양이 갈라진다).
   ⚠️ 칸 수를 세지 않는다 — `grid-auto-flow: column` 이라 갈래가 셋이 돼도 CSS 를 안 고친다.
   ⚠️ 고른 칸은 **`aria-selected`** 로 표시한다(클래스가 아니라) — 보조기기에도 그대로 전해진다.
   ⚠️ 강사 「내 정보」의 `.mi-tabs` 와 모양이 비슷하지만 그건 teacher.html 안에만 있는
      3칸 전용이다 — 합치지 말 것(저쪽은 슬라이딩 트랙과 한 몸이다). */
.seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px;
  background: var(--s100); border-radius: 12px; padding: 4px; }
.seg-btn { border: 0; background: transparent; border-radius: 9px; min-height: 38px; padding: 0 6px;
  font-size: 12.5px; font-weight: 700; color: var(--s500); white-space: nowrap;
  transition: background .15s, color .15s; }
.seg-btn[aria-selected="true"] { background: #fff; color: var(--main); box-shadow: 0 1px 3px rgba(0,0,0,.1); }
/* 칸 이름 옆의 개수 — 목록이 비어 있어도 「0」이 보여야 「없다」가 전해진다 */
.seg-btn .seg-n { margin-left: 4px; font-weight: 800; color: var(--s400); }
.seg-btn[aria-selected="true"] .seg-n { color: var(--main); }
/* 「+ 무엇을 추가」 형태의 점선 알약 버튼 */
.add-btn { margin-top: 8px; width: 100%; min-height: 40px;
  border: 1px dashed var(--s300); border-radius: 999px; background: #fff;
  color: var(--main); font-size: 13px; font-weight: 700; }
.add-btn:hover { border-color: var(--main); background: var(--pale); }

/* 파일 첨부 — 고른 뒤에는 파란 실선으로 바뀌어 「붙었다」가 보인다 */
.file-btn { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; min-height: var(--tap);
  border: 1px dashed var(--s300); border-radius: 10px; background: var(--s50);
  padding: 10px 12px; font-size: 13px; color: var(--s500); text-align: left; }
.file-btn > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-btn.has { border-style: solid; border-color: var(--main); color: var(--main);
  font-weight: 700; background: var(--pale); }
.file-btn small { flex: none; font-weight: 700; color: var(--s400); }

/* 상태 배지. admin.html 은 표가 빽빽해 자체 .pill 로 덮어쓴다(뒤에 선언돼 우선). */
.pill { display: inline-block; border-radius: 999px; padding: 4px 10px;
  font-size: 11px; font-weight: 800; line-height: 1.35; white-space: nowrap; }

/* 인원 */
.opt-people { gap: 2px; }
.opt-people .icons { font-size: 11px; letter-spacing: -1px; }
.people-msg {
  margin-top: 2px; border-radius: 8px; padding: 9px 12px;
  background: #fff8e1; color: #7a5a00;
  font-size: 12px; font-weight: 700; text-align: center;
}

/* 지역 */
.region-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
/* font-size 16px 유지 (iOS 자동확대 방지) — 좁은 폭은 padding 으로 흡수.
   글자는 가운데 (2026-08-05 사용자 지시). ⚠️ select 는 `text-align` 만으로는 안 먹는
   브라우저가 있어 **`text-align-last` 를 함께** 준다(닫혀 있을 때 보이는 줄이 이쪽 규칙이다). */
.region-grid .input { min-height: 44px; padding: 8px 6px; text-align: center; text-align-last: center; }
.station-input { min-height: 44px; padding: 8px 10px; }

/* 일정 */
.date-btn {
  width: 100%; min-height: var(--tap);
  border: 1px solid var(--s300); border-radius: 10px; background: #fff;
  font-size: 13px; font-weight: 600; color: var(--s400);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.date-btn.filled { border-color: var(--main); border-width: 2px; background: var(--pale); color: var(--main); font-weight: 800; }
.date-btn:disabled { background: var(--s100); color: var(--s400); cursor: not-allowed; }

.schedule-box {
  border-radius: 10px; padding: 10px 12px;
  background: var(--s50); box-shadow: inset 0 0 0 1px var(--s200);
  font-size: 12px; color: var(--s600); line-height: 1.7;
}
.schedule-box b { color: var(--main); }
.schedule-skip { margin-top: 4px; font-size: 12px; color: var(--danger); word-break: keep-all; }

/* 안내 박스 */
.note-box {
  border-radius: 8px; padding: 8px 10px; background: var(--s50);
  font-size: 10.5px; color: var(--s500); line-height: 1.7;
}
.note-box b { color: var(--s700); }
/* 남은 개설 가능 수 — 시간대를 고를 때마다 실시간으로 바뀐다 */
.times-left { display: block; margin-top: 4px; font-size: 12px; font-weight: 800; color: var(--main); }
.times-left.is-zero { color: var(--s500); }
.times-left.is-over { color: var(--danger); }

/* 제출 */
.submit-wrap { margin-top: 20px; }
.submit-wrap .btn { width: 100%; min-height: 52px; font-size: 15px; border-radius: 12px; }
.submit-note { margin-top: 8px; text-align: center; font-size: 12px; color: var(--s400); word-break: keep-all; }
/* ★「클래스 개설하기」 = 브랜드 옐로 (2026-08-06, 랜딩 CTA `.lp-go` 와 같은 약속).
   ⚠️ 옐로 위 흰 글자는 대비비 1.44 라 안 보인다 → 글자는 딥블루(--main), 대비비 5.32.
   ⚠️ `.btn-main:not(:disabled):hover` 와 `.btn-main:disabled` 가 특이도에서 이기므로
      **hover 와 disabled 를 여기서 다시 덮어야** 한다(안 덮으면 눌렀을 때 파랗게 돌아간다). */
.btn-create-go:not(:disabled) { background: var(--accent); color: var(--main); }
.btn-create-go:not(:disabled):hover,
.btn-create-go:not(:disabled):focus-visible { background: #f2c02f; color: var(--main); }
/* 수강료 안내 — 버튼 바로 아래 한 줄. 랜딩에서 옮겨 왔다.
   ⚠️**한글은 기본값이 아무 글자에서나 잘린다** → keep-all 로 띄어쓰기에서만 접는다. */
.submit-fee {
  margin: 9px 0 0; text-align: center;
  font-size: 12px; font-weight: 700; color: var(--main); line-height: 1.45;
  word-break: keep-all; text-wrap: balance;
}
/* 동적 안내(#create-note)가 비면 위 여백이 남는다 → 비었을 때는 아예 자리를 안 준다 */
.submit-note:empty { display: none; }

/* ---------- 클래스 목록 ---------- */
/* ★★2026-08-12 개편(사용자 지시) — 「지역 드롭다운 + 버튼」 한 줄에서
     **시·도/시·군·구/지하철역 3단 + 체크 한 줄**로 바뀌었다. 세로로 두 줄을 쓰지만
     버튼이 차지하던 오른쪽 칸이 사라져 드롭다운이 화면 폭을 그대로 쓴다. */
.filters { display: grid; gap: 8px; margin-bottom: 14px; }
/* ⚠️ 신청 폼의 `.region-grid` 와 같은 처방이 필요하다 — select 는 **가장 긴 선택지**만큼을
   최소 너비로 잡아서, `min-width: 0` 과 좁은 padding 이 없으면 세 칸이 화면 밖으로 넘친다. */
.filter-region { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px; }
/* 글자는 가운데, 크기는 신청 폼 select(13.5px)에 맞춘다 — 기본 .input 의 16px 은
   이 줄에서 혼자 커 보였다 (2026-08-05 사용자 지시).
   ⚠️ 16px 규칙은 **텍스트 입력**이 대상이다(iOS 확대). select 는 탭하면 피커가 떠 확대되지 않는다.
   ⚠️ 3칸이 되면서 `padding` 을 6px 로 더 줄였다 — 320px 에서 「시·군·구」가 잘리지 않게. */
.filters .input { min-width: 0; min-height: 44px; padding: 8px 6px; font-size: 13px; text-align: center; text-align-last: center; }
.filters .input:disabled { background: var(--s100); color: var(--s400); }

/* ⚠️★★`.filter-toggle` 는 **지우면 안 된다.** 학부모 목록에서는 2026-08-12 에 체크로 바뀌었지만
   어드민(「매칭 가능만」)·강사(「내 선호 지역만」·「내 선호 시간대만」)가 아직 그대로 쓴다.
   app.css 는 네 페이지 공용이라, 학부모 화면에서 안 쓴다고 지우면 **그 세 버튼이 민짜가 된다**
   (에러가 안 나서 그 화면을 열어 본 사람만 안다). */
.filter-toggle {
  border: 1px solid var(--s300); border-radius: 10px; background: #fff;
  padding: 8px 12px; font-size: 12px; font-weight: 700; color: var(--s500);
  white-space: nowrap;
}
.filter-toggle[aria-pressed='true'] { background: var(--main); border-color: var(--main); color: #fff; }

/* 「신청 가능한 클래스만 보기」 — 버튼형(옛 .filter-toggle)에서 체크로 바뀌었다.
   ⚠️ 동그란 체크다(라디오처럼 보이게, 사용자 지시) — 동작은 켜고 끄는 **토글**이라
      마크업은 checkbox 다. radio 로 만들면 한 번 켠 뒤 끌 수가 없다. */
/* ★2026-08-12(3차) 사용자 지시 — **우측 정렬**(오후에 좌측으로 했던 것을 되돌린다).
   오른쪽 padding 을 0 으로 둬서 글자의 오른쪽 끝이 위 드롭다운 **마지막 칸의 오른쪽 끝**과
   정확히 같은 x 에 선다(실측으로 맞춘다 — 눈대중 금지).
   ⚠️ `justify-content` 를 명시해 둔다. 부모가 grid 라 안 적으면 flex-start 로 돌아간다.
   ⚠️ `.filter-check` 는 label 이라 **글자를 눌러도 켜진다** — 정렬을 바꿔도 그 성질은 그대로다. */
.filter-check {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 2px 0 0; cursor: pointer;
  font-size: 13px; font-weight: 700; color: var(--s600);
  text-align: right;
}
.filter-check input {
  appearance: none; -webkit-appearance: none;
  flex: none; width: 20px; height: 20px; margin: 0;
  border: 1.5px solid var(--s300); border-radius: 50%; background: #fff;
  display: grid; place-content: center; cursor: pointer;
}
/* 체크 표시는 가운데 점 하나 — 라디오와 같은 모양이다(::after 를 키워 채운다) */
.filter-check input::after {
  content: ''; width: 9px; height: 9px; border-radius: 50%;
  background: #fff; transform: scale(0); transition: transform .12s;
}
.filter-check input:checked { border-color: var(--main); background: var(--main); }
.filter-check input:checked::after { transform: scale(1); }
.filter-check input:focus-visible { outline: 2px solid var(--main); outline-offset: 2px; }
.filter-check:has(input:checked) { color: var(--main); }

.klist { display: flex; flex-direction: column; gap: 10px; }

/* ★★2026-08-12(3차) 사용자 지시 — 카드 안 간격이 뒤죽박죽이라 통일하고 글자를 키웠다.
   옛 값: 위 12.5px → 2px → 17px → 8px → 12.5px → 8px → 알약. 붙은 데는 2px, 떨어진 데는 8px 이라
   **어디가 한 덩어리인지**가 안 읽혔고, 기간이 두 줄이 되면서 더 헐거워 보였다.

   ★새 규칙은 **두 값뿐**이다 — 한 덩어리 안은 var(--kcard-gap-tight), 덩어리 사이는 var(--kcard-gap).
     [단계] ↕tight [지역]  ↕gap  [기간/시각]  ↕gap  [D-day]
   ⚠️ 새 줄을 넣을 때도 **이 두 변수만** 쓸 것. 픽셀을 직접 적기 시작하면 곧 다시 뒤죽박죽이 된다.
   ⚠️ 오른쪽 칸(.kcard-right)이 절대배치라 **왼쪽 padding-right 는 그 폭 + 여백**이라야 겹치지
      않는다(96 + 14 + 여유). 글자를 키워도 이 값은 같이 봐야 한다. */
.kcard {
  --kcard-gap: 10px;
  --kcard-gap-tight: 4px;
  position: relative;
  background: var(--pale); border-radius: 14px; padding: 16px 122px 16px 18px;
}
/* ★맨 윗줄 = 단계(학년대). 2026-08-10 에 학년대만 있던 자리에 **단계**를 올렸다 —
   무엇을 배우는 반인지가 카드에서 가장 먼저 읽혀야 한다. */
.kcard-level { font-size: 13.5px; font-weight: 700; color: var(--s600); line-height: 1.45; word-break: keep-all; }
.kcard-place { margin-top: var(--kcard-gap-tight); font-size: 19px; font-weight: 800; color: var(--main);
  letter-spacing: -.4px; line-height: 1.3; word-break: keep-all; }
/* ★2026-08-17 사용자 지시 — 원데이 카드의 **체험 게임** 줄(이모지 · 이름 · 핵심개념).
   원데이는 「어느 게임을 하는 반인가」가 고르는 기준이라, 지역 바로 아래에서 눈에 띄어야 한다.
   ⚠️ 지역과 **한 덩어리**로 읽히게 tight 간격을 준다(그 아래 일정과는 gap 으로 벌어진다).
   ⚠️ 정규 반에는 이 줄이 아예 안 그려진다 — 없는 줄에 margin 을 걱정할 필요가 없다. */
.kcard-game { margin-top: var(--kcard-gap-tight); font-size: 13.5px; font-weight: 700;
  color: var(--main-dark); line-height: 1.45; word-break: keep-all; }
/* ★2026-08-12 사용자 지시 — 정규처럼 회차가 여럿인 반은 **기간 / 시각**이 두 줄이다.
   줄바꿈은 klassPeriodText 가 `\n` 으로 넣으므로 여기서 **보이게만** 해 준다.
   ⚠️ `pre-line` 이 없으면 그 `\n` 은 그냥 공백으로 보인다(에러 없이 옛 모습 그대로다). */
.kcard-period { margin-top: var(--kcard-gap); font-size: 13.5px; color: var(--s600); line-height: 1.55;
  word-break: keep-all; white-space: pre-line; }
/* ⛔`.kcard-venue`(📍 진행 장소 줄)는 2026-08-10 사용자 지시로 카드에서 뺐다 —
   어느 반이든 「OO역 인근 · 확정 후 안내」로 같아서 고를 때 쓰는 정보가 아니었다.
   지금은 신청 팝업의 `.join-venue` 가 그 역할을 한다. */
.mini-map { display: inline-flex; align-items: center; margin-top: 8px; font-size: 11.5px;
  font-weight: 700; color: var(--main); text-decoration: none; }
/* 리포트 보관함 (2026-07-24) — 아이별 아코디언 → 클래스별 → 회차 */
.arc-stu { border: 1px solid var(--s200); border-radius: 12px; overflow: hidden; margin-bottom: 10px; }
.arc-stu-head { display: flex; align-items: center; gap: 8px; width: 100%; background: #fff;
  border: 0; padding: 12px 14px; text-align: left; }
.arc-stu-head.open { background: var(--pale); }
.arc-stu-name { flex: 1; min-width: 0; font-size: 14px; font-weight: 800; color: var(--s800); }
.arc-stu-name small { font-weight: 600; color: var(--s500); font-size: 11.5px; margin-left: 5px; }
.arc-cnt { flex: none; font-size: 11px; font-weight: 700; color: var(--main); background: var(--pale);
  border-radius: 999px; padding: 3px 9px; }
.arc-stu-head.open .arc-cnt { background: #fff; }
.arc-caret { flex: none; font-size: 11px; color: var(--s400); width: 14px; text-align: center; }
.arc-body { border-top: 1px solid var(--s100); }
.arc-cls { padding: 9px 14px 5px; font-size: 11px; font-weight: 800; color: var(--s400); background: var(--s50); }
.arc-item { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px; border-top: 1px solid var(--s100); text-decoration: none; }
.arc-date { font-size: 13px; font-weight: 700; color: var(--s800); }
.arc-concept { margin-top: 2px; font-size: 11px; color: var(--s500); }
.arc-go { flex: none; font-size: 12px; font-weight: 800; color: var(--main); }
/* ⚠️ 알약은 자기 padding 이 있어 **같은 margin 이라도 더 떨어져 보인다** → 위 여백을 2px 덜어 준다 */
.kcard-dday { margin-top: calc(var(--kcard-gap) - 2px); display: inline-block; border-radius: 7px;
  padding: 3px 9px; background: #fff; font-size: 12px; font-weight: 800; color: var(--danger); }

.kcard-right {
  position: absolute; right: 14px; top: 14px; bottom: 14px; width: 96px;
  display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between;
}
.kcard-count { font-size: 14px; font-weight: 600; color: var(--s500); }
.kcard-count b { font-size: 28px; font-weight: 800; color: var(--s800); }
.kcard-btn {
  width: 100%; min-height: 44px; border: 0; border-radius: 10px;
  font-size: 14px; font-weight: 800;
}
.st-open { background: var(--accent); color: var(--main-dark); }
.st-pending { background: var(--sub); color: #fff; cursor: default; }
.st-confirmed { background: var(--main); color: #fff; cursor: default; }
/* 운영 중 = 개설확정보다 한 걸음 더 간 상태라, 같은 브랜드 블루의 더 짙은 톤을 쓴다 (2026-07-29) */
.st-running { background: var(--main-dark); color: #fff; cursor: default; }
.st-closed { background: var(--s300); color: #fff; cursor: default; }
/* 종료 = 마지막 수업일이 지난 반(2026-08-21). 「완료」 직전 단계라 완료(초록)와 이웃한 색으로
   두되 아직 끝나지 않은 일이라는 뜻으로 한 톤 어둡게 — #334155 on #fff 글씨 = 대비비 10.9. */
.st-ended { background: #334155; color: #fff; cursor: default; }
/* 완료 = 수업까지 끝난 클래스. 진행 중 상태들과 구분되도록 초록 계열로 둔다. */
.st-done { background: #16a34a; color: #fff; cursor: default; }
/* 자격 잠금 (2026-08-03) — 앞 단계를 아직 수료하지 않아 신청할 수 없는 반.
   ⚠️ 상태색(st-*)과 **섞이면 안 된다** — 「모집중인데 나는 못 든다」라서 모집 상태와 다른 축이다.
   ⚠️대비비를 재서 정한 색이다 — --s500 은 3.86 으로 **기준 미달이었다**(눈으로는 멀쩡해 보인다).
   지금 = #475569 on #e2e8f0 → 6.15:1. 13px 굵은 글씨는 '큰 글씨' 예외에 못 드니 4.5 를 넘겨야 한다. */
.kcard-btn-lock { background: var(--s200); color: var(--s600); cursor: default; }
/* ⚠️2026-08-15: 한글은 **아무 글자에서나 잘린다** — 실화면에서 「단계 수료가 필/요해요.」로
   접혔다. 낱말째 접도록 `keep-all` 을 건다(이 프로젝트의 좁은 칸 공통 처방이다). */
.kcard-lock {
  margin-top: var(--kcard-gap); padding: 8px 11px; border-radius: 8px;
  background: #fff; font-size: 12px; font-weight: 700; color: var(--s600); line-height: 1.5;
  word-break: keep-all;
}

.empty { padding: 40px 0; text-align: center; font-size: 13px; color: var(--s400); }

.pager { display: flex; gap: 6px; justify-content: center; margin-top: 16px; flex-wrap: wrap; }
.pager button { min-width: 38px; min-height: 38px; border: 1px solid var(--s200); border-radius: 8px; background: #fff;
  font-size: 13px; font-weight: 700; color: var(--s600); padding: 0 8px; }
.pager button.cur { background: var(--main); border-color: var(--main); color: #fff; }
.pager button:disabled { color: var(--s300); }
.pager-info { align-self: center; font-size: 12px; color: var(--s400); margin-left: 6px; }

/* ---------- 모달 ---------- */
/* 팝업이 열린 동안 뒤 화면 잠금 (2026-08-03 사용자 지시). 스위치는 m-core.js 가 켜고 끈다.
   ⚠️ `overflow:hidden` 만으로는 iOS 사파리가 뒤 화면을 계속 끈다 → position:fixed 로 세운다.
   ⚠️ 세우면 스크롤 위치를 잃으므로 m-core 가 top 으로 자리를 잡고 닫을 때 되돌린다. */
body.modal-open { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; }
.backdrop {
  /* ★2026-08-05: 40 → 70. 팝업은 **화면에서 가장 앞**이어야 한다(사용자 지시) —
     예전에는 플로팅 버튼(60)과 랜딩 하단 CTA(55)가 팝업 **위로** 떠서 모달 내용을 가렸다.
     ⚠️ 토스트(80)만 이보다 위다. */
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: center; justify-content: center; padding: 20px 16px;
  background: rgba(15,23,42,.55); overflow-y: auto;
}
.modal {
  width: 100%; max-width: 400px; background: #fff; border-radius: 16px;
  max-height: calc(100vh - 40px); display: flex; flex-direction: column;
  box-shadow: 0 20px 25px -5px rgba(0,0,0,.25);
}
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 18px; border-bottom: 1px solid var(--s100); }
.modal-title { margin: 0; font-size: 15px; font-weight: 800; }
.modal-close { border: 0; background: none; font-size: 22px; color: var(--s400); line-height: 1; padding: 0 4px; }
.modal-body { padding: 18px; overflow-y: auto; }
.modal-foot { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 0 18px 18px; }
.modal-foot .btn { width: 100%; }
.modal-msg { font-size: 13px; color: var(--s600); line-height: 1.7; white-space: pre-line; word-break: break-all; }
.modal-msg b { color: var(--s800); }
/* 비면 자리를 주지 않는다 — 개설 확인 팝업의 마지막 줄은 시간대가 하나면 통째로 빈다
   (2026-08-13). `.submit-note:empty` 와 같은 처방이다. */
.modal-msg:empty { display: none; }
/* ★2026-08-12(3차) 사용자 지시 — 개설 확인 팝업의 **마지막 한 줄만** 가운데.
   ⚠️ `.modal-msg` 전체를 가운데로 두면 안 된다 — 같은 클래스를 신청·중복·결제 팝업이 함께 쓰는데
      그쪽은 여러 줄짜리 설명이라 가운데 정렬하면 읽기가 나빠진다. **이 id 로만** 좁혀서 덮는다. */
#open-confirm-msg { text-align: center; }

/* 결제하기 버튼 (개설 확정 클래스) */
.btn-pay { width: 100%; margin-top: 10px; background: var(--pay); color: #fff; }
.btn-pay:not(:disabled):hover { background: #e63a54; }
.btn-cancel-req { width: 100%; margin-top: 8px; min-height: 40px; color: var(--danger); box-shadow: inset 0 0 0 1px rgba(217,83,79,.35); }
.btn-cancel-req:hover { background: rgba(217,83,79,.06); }
.pay-done { margin-top: 10px; text-align: center; font-size: 12.5px; font-weight: 800; color: #16a34a; }
.pay-todo { margin-top: 10px; text-align: center; font-size: 12px; font-weight: 700; color: var(--pay); }
.lock-note { margin-top: 8px; font-size: 12.5px; color: var(--s400); line-height: 1.55; word-break: keep-all; }
/* ★2026-08-26(8차) 사용자 확정 — 「모집 마감」된 반의 한 줄 안내(내 정보 카드).
   ⚠️ `.lock-note`(회색)와 **색을 나눈다** — 저쪽은 「지금은 못 한다」이고 이쪽은 「이 반은 끝났다」라
      뜻이 다르다. 옅은 주황 바탕은 상태 알약 `.st-closed` 와 같은 계열이다.
   ⚠️ 대비비 = #7c2d12 on #fff7ed → 8.71 (기준 4.5 통과). */
.closed-note { margin-top: 8px; padding: 9px 11px; border-radius: 9px;
  background: #fff7ed; color: #7c2d12;
  font-size: 12.5px; line-height: 1.55; word-break: keep-all; }

.info-row { display: grid; grid-template-columns: 76px 1fr; gap: 10px; padding: 6px 0; }
.info-k { font-size: 12.5px; color: var(--s500); }
.info-v { font-size: 12.5px; font-weight: 700; color: var(--s800); }
/* ★2026-08-13(3차) 사용자 지시 — **내 정보 팝업의 이름·연락처만 2배**(12.5 → 25px).
   ⚠️★★`.info-row` 자체는 못 건드린다 — 어드민 클래스 상세·문자 수신자·강사 문서까지 함께 쓴다.
      `#my-profile` 안으로만 스코프를 건다.
   ⚠️★★라벨 칸 76px 은 25px 글자에 안 맞는다(「연락처」가 접힌다) → **글자 폭(auto)** 으로 바꾸고
      `nowrap` 을 건다. 값은 320px 폰에서도 한 줄에 들어가야 하므로 자간을 조금 좁힌다. */
/* ★2026-08-13(4차) 재지시 — **25px 은 너무 컸다 → 그 70%인 17.5px.**
   ⚠️ 그러면 좁은 폭에서도 접히지 않으므로 **360px 예외는 없앴다**(21px 규칙 삭제) —
      규칙이 하나면 「폰마다 다르게 보인다」는 걱정 자체가 사라진다. */
/* ★★2026-08-13(6차) 사용자 지시 — 「✏️ 수정」을 **이름·연락처와 같은 줄의 오른쪽 위**로.
   ⚠️★★버튼의 **위쪽 끝을 「이름」 줄의 위쪽 끝에 맞춘다**(지시). `.info-row` 가 위아래로 4px 씩
      패딩을 갖고 있으므로 버튼에도 **같은 4px** 을 준다 — 안 주면 버튼만 4px 위로 뜬다.
      그 패딩을 바꾸면 여기도 함께 볼 것(두 값은 짝이다). */
/* ⚠️ position:relative 는 `?` 말풍선의 기준이다 (2026-08-14) — 여기가 아니라 버튼 묶음에
   걸면 말풍선이 버튼 폭(≈70px)으로 눌려 한 글자씩 끊긴다. */
/* ⚠️ position:relative 는 `?` 말풍선의 기준이다 (2026-08-14) — 여기가 아니라 버튼 묶음에
   걸면 말풍선이 버튼 폭(≈70px)으로 눌려 한 글자씩 끊긴다.
   ⚠️★★`flex-wrap` 과 `flex-basis:190px` 이 한 쌍이다 — 버튼이 둘로 늘면서 묶음이 188px 가 됐고,
      안 접으면 **320px 폰에서 이름·연락처 칸이 54px 로 눌린다**(실측). 190 은 「연락처
      010-1234-5678 이 한 줄에 들어가는 최소 폭」이라 그보다 좁아지면 버튼 줄이 아래로 내려간다. */
.mi-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 10px; position: relative; }
.mi-head > #my-profile { flex: 1 1 190px; min-width: 0; }
.mi-head > .btn { flex: none; margin-top: 4px; }
/* 「✏️ 수정 · 🔒 다시 인증 · ?」 한 묶음 (2026-08-14)
   ★자리는 그대로(이름·연락처 **아랫줄**)이고 **좌측 정렬**이다 (0814 2차 사용자 지시).
   ⚠️ `margin-left:auto` 를 되살리지 말 것 — 그 한 줄이 묶음을 오른쪽 끝으로 밀어낸다. */
.mi-acts { flex: 0 0 auto; margin-right: auto; display: flex; align-items: center; justify-content: flex-start; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.mi-acts .btn { flex: none; margin-top: 0; }

#my-profile .info-row { grid-template-columns: auto 1fr; gap: 12px; padding: 4px 0; align-items: baseline; }
#my-profile .info-k { font-size: 17.5px; white-space: nowrap; letter-spacing: -.5px; }
#my-profile .info-v { font-size: 17.5px; letter-spacing: -.5px; }

/* 섹션 제목은 브랜드 서브 파란색 (2026-08-01) — 어드민·강사·신청 3사이트 공용 */
.sec-title { margin: 20px 0 10px; font-size: 12px; font-weight: 800; color: var(--sub); letter-spacing: .4px; word-break: keep-all; }
.sec-title:first-child { margin-top: 0; }
/* ★클래스 요청 폼 안에서만 한 단계 키운다 — 「클래스를 같이 개설할 인원」·「개설자 기본 정보」가
   11px 이라 화면 제목(`.form-title` 15px)과 너무 벌어져 소제목으로 읽히지 않았다
   (2026-08-11 사용자 지시: 상단 제목보다 **살짝 작은 정도**로).
   ⚠️ `.sec-title` 자체를 키우지 말 것 — 이 클래스는 학부모 팝업·강사·어드민이 함께 쓴다
      (신청 팝업의 「참여 학생 정보」, 개설 확인 팝업의 「클래스 정보」 등). 여기만 스코프를 건다. */
/* ★2026-08-13 사용자 지시 — 이 자리를 키운다(13.5 → 20 → **18px**. 20 은 조금 컸다는 재지시).
   3단계에서 화면 제목(「누가 함께 하나요?」)을 없앴으므로 이 두 줄이 그 화면의 제목 노릇을 한다.
   ⚠️ 여전히 `#panel-request` 안으로만 스코프를 건다 — `.sec-title` 은 학부모 팝업·강사·
      어드민이 함께 쓰는 클래스다.
   ⛔`#req-pane-3 .sec-title:first-child { margin-top: 16px }`(0813 2차)는 **아무 일도 안 하고
     있었다** — `.req-pane` 은 padding·border 가 없는 맨 div 라, 첫 자식의 margin-top 이 부모 밖으로
     빠져나와(margin collapsing) 위 형제 `.req-steps` 의 margin-bottom 16px 과 **상쇄**됐다.
     지시대로 실제로 벌리는 규칙은 위 「3단계 간격」 절의 `#req-pane-3 { padding-top }` 이다.
     ⚠️★★이 함정을 기억할 것 — **여백이 안 벌어지면 먼저 margin collapsing 을 의심한다.** */
#panel-request .sec-title { font-size: 18px; letter-spacing: -.4px; }

/* ★개설 확인 팝업의 「클래스 정보」만 두 배(12 → 24px · 2026-08-13 사용자 지시).
   그 팝업에서 가장 먼저 읽어야 할 줄이라 순서를 맨 위로 올리면서 크기도 함께 올렸다.
   ⚠️ `.sec-title` 자체를 키우지 말 것 — 위와 같은 이유(4개 화면 공용). */
.sec-title-lg { font-size: 24px; letter-spacing: -.6px; line-height: 1.3; }
/* ⛔`.sec-title-xl`(내 정보 팝업의 「신청자 정보」)은 **2026-08-13(4차)에 쓰는 곳이 없어졌다** —
   제목 자체를 없앴다(팝업 제목 「내 정보」가 같은 말을 한다). 정의만 남겨 둔다. */
.sec-title-xl { font-size: 22px; letter-spacing: -.6px; line-height: 1.3; }
/* ★함께하기 팝업의 「참여 학생 정보」 — 팝업 제목(`.modal-title` 15px)과 **같은 크기**
   (2026-08-13(4차) 사용자 지시). ⚠️ 색·굵기는 `.sec-title` 그대로 둔다(소제목의 얼굴은 유지). */
.sec-title-md { font-size: 15px; letter-spacing: -.2px; }

/* ---- `?` 말풍선 (2026-08-13 신설 · 사용자 지시) ----
   소제목 아래 늘 펼쳐져 있던 설명을 물음표 뒤로 감춘다. 터치하면 뜨고, 밖을 누르면 닫힌다.
   ⚠️★★말풍선은 **소제목 폭에 맞춰 눕힌다**(`left:0; right:0`) — 물음표에 붙여 띄우면
      제목이 긴 줄에서 화면 오른쪽으로 삐져나간다(320px 에서 바로 깨진다).
   ⚠️ 부모(`.sec-title`)가 서브 파랑·800·자간을 갖고 있으므로 말풍선에서 **전부 되돌린다**. */
.sec-title-q { position: relative; }
.hint-tip { display: inline; }
.hint-q {
  display: inline-flex; align-items: center; justify-content: center;
  position: relative; vertical-align: middle;
  width: 20px; height: 20px; margin: -2px 0 0 5px; padding: 0;
  border: 0; border-radius: 50%;
  background: var(--pale); color: var(--main);
  font-size: 12px; font-weight: 800; line-height: 1; letter-spacing: 0;
}
/* 손가락이 닿는 자리는 44px 로 넓힌다 — 보이는 원은 20px 그대로 두고 판만 키운다
   (크기를 키우면 소제목 줄 높이가 따라 올라간다). */
.hint-q::after { content: ''; position: absolute; inset: -12px; }
.hint-q[aria-expanded="true"] { background: var(--main); color: #fff; }
.hint-bubble {
  position: absolute; left: 0; right: 0; top: calc(100% + 7px); z-index: 40;
  padding: 11px 13px; border-radius: 10px;
  background: var(--s800); color: #fff;
  font-size: 13px; font-weight: 500; line-height: 1.65; letter-spacing: 0;
  word-break: keep-all; text-align: left;
  box-shadow: 0 8px 22px rgba(15, 23, 42, .24);
}
/* 제목 오른쪽에 작은 버튼을 두는 줄 (내 정보 → ✏️ 수정) */
.sec-title-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sec-title-row .btn { flex: none; }

/* 내 정보 수정 — 클래스별 학생 명단 (2026-07-25) */
.em-cls + .em-cls { margin-top: 12px; }
.em-cls-t { font-size: 12px; font-weight: 800; color: var(--main); margin-bottom: 6px; }
.em-stu { display: grid; grid-template-columns: 1fr 92px; gap: 6px; }
.em-stu + .em-stu { margin-top: 6px; }
/* font-size 는 위 경고대로 16px 유지 — iOS 자동 확대 방지 */
.em-stu .input { min-width: 0; min-height: 42px; padding: 8px 10px; }

/* ⛔`.about-*`(더 알아보기 팝업의 외부 링크 카드 2장)은 2026-08-10 사용자 지시로 없앴다 —
   그 팝업(#modal-about) 자체가 사라지고 헤더 버튼이 **더 알아보기 페이지**로 간다. */

/* 신청 팝업의 진행 장소 — ★2026-08-10 에 목록 카드(.kcard-venue)에서 이리로 옮겼다.
   어드민이 장소를 확정해 넣기 전에는 「OO역 인근 · 확정 후 안내」로 보인다(회색),
   확정되면 장소명이 들어오며 브랜드 색으로 선다. */
.join-venue {
  margin-top: 10px; border-radius: 10px; padding: 9px 12px;
  background: var(--s50); color: var(--s500);
  font-size: 12px; line-height: 1.5; word-break: keep-all;
}
.join-venue.has { background: var(--pale); color: var(--main); font-weight: 700; }

/* 환불·이용 규정 (2026-08-10 신설) — 개설 확인 팝업에서 「개설하기」 바로 위에 선다.
   ⚠️ 글자를 키우지 않는다 — 읽히기는 해야 하지만 금액·클래스 정보보다 앞설 자리는 아니다. */
.rule-box {
  margin-top: 16px; border-radius: 12px; padding: 12px 13px;
  background: var(--s50); box-shadow: inset 0 0 0 1px var(--s200);
}
.rule-t { font-size: 12.5px; font-weight: 800; color: var(--s800); }
.rule-list { margin: 8px 0 0; padding-left: 16px; }
.rule-list li { font-size: 12.5px; color: var(--s600); line-height: 1.65; word-break: keep-all; }
.rule-list li + li { margin-top: 4px; }
.rule-list b { color: var(--s800); font-weight: 700; }
.rule-more { margin: 9px 0 0; font-size: 12px; color: var(--s500); line-height: 1.6; word-break: keep-all; }
/* 팝업 위에 팝업(이용약관)을 연다 — 문서 뒤쪽에 있는 `#modal-terms` 가 위에 그려진다 */
.rule-link {
  display: inline; padding: 0; border: 0; background: none;
  color: var(--main); font: inherit; font-weight: 800;
  text-decoration: underline; text-underline-offset: 2px;
}

.mini-card { border-radius: 10px; padding: 11px 12px; background: var(--s50); box-shadow: inset 0 0 0 1px var(--s200); }
.mini-card + .mini-card { margin-top: 8px; }
.mini-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.mini-place { font-size: 13px; font-weight: 800; color: var(--main); }
.mini-badge { border-radius: 6px; padding: 2px 8px; font-size: 10.5px; font-weight: 800; }
.mini-meta { margin-top: 4px; font-size: 12px; color: var(--s500); line-height: 1.6; word-break: keep-all; }

/* 신청자/개설자 기본 정보 (이름·학년) */
.field-hint { margin: 2px 0 10px; font-size: 13px; color: var(--s500); line-height: 1.55; word-break: keep-all; }
.students { display: flex; flex-direction: column; gap: 12px; }
.student-row { border-radius: 10px; padding: 10px 12px; background: var(--s50); box-shadow: inset 0 0 0 1px var(--s200); }
.sr-label { margin-bottom: 6px; font-size: 11px; font-weight: 800; color: var(--s400); letter-spacing: .3px; }
.student-row .input { margin-bottom: 8px; }
/* 2026-08-28 — 함께하기의 「내 아이 불러오기」. 이름 칸을 절반으로 줄이고 그 옆에 세운다.
   ⚠️min-width:0 이 없으면 select 의 최소 너비 때문에 이름 칸이 밀려 360px 에서 넘친다. */
.sr-name-row { display: flex; gap: 6px; margin-bottom: 8px; }
.sr-name-row .input { flex: 1 1 50%; min-width: 0; margin-bottom: 0; }
/* 「내 아이 불러오기」 기본 줄 — 다른 안내 글자와 **같은 규칙**(14px · --s400).
   ⚠️★★★선택자를 `.sr-kid-pick` 하나로 쓰면 **안 먹는다** — 위 `.input, select.input` 의
      `select.input` 이 (0,1,1) 이라 (0,1,0) 을 이긴다. 2026-08-28 에 실제로 이걸로 한 번
      「고쳤다」고 잘못 보고했다. `select.input.sr-kid-pick` (0,1,2) 로 확실히 이긴다.
      ⛔확인은 눈이 아니라 **getComputedStyle** 로 할 것.
   ⚠️고른 뒤 곧바로 빈 값으로 되돌리므로 이 줄은 늘 기본 안내다(상태 토글이 필요 없다).
   ⚠️펼친 목록(option)은 본문 색으로 되돌린다 — 안 되돌리면 항목까지 회색으로 보인다. */
select.input.sr-kid-pick { font-size: 14px; color: var(--s400); }
select.input.sr-kid-pick option { font-size: 16px; color: var(--s700); }
/* 2026-08-28 — 클래스 형태를 고르기 전 **잠긴** 커리큘럼 드롭다운 */
.csel-btn:disabled { background: var(--s100); color: var(--s400); cursor: not-allowed; }
.csel-btn:disabled::after { opacity: .4; }
.grade-opts { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }
.grade-opts .opt { min-height: 38px; padding: 6px 0; font-size: 12px; }
.grade-opts .opt.off { opacity: .45; }

/* 학생 행 안의 학부모 칸 (2026-07-29) — 아이마다 학부모가 다를 수 있어서 행 안으로 들어왔다 */
.sr-parent { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--s200); }
.sr-p-title { margin-bottom: 8px; font-size: 11px; font-weight: 800; color: var(--s400); letter-spacing: .3px; }
.sr-parent .input { margin-bottom: 8px; }
.sr-parent .input:last-child { margin-bottom: 0; }
.sr-parent .input:disabled { background: var(--s100); color: var(--s400); }
/* 「위와 동일해요」 — 누르는 면적을 넉넉히 (모바일에서 체크박스만 노리기 어렵다) */
.sr-same { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; cursor: pointer;
  font-size: 12.5px; font-weight: 700; color: var(--main); }
.sr-same input { width: 17px; height: 17px; accent-color: var(--main); flex: none; }

/* 개설 금액·정보 확인 */
.price-box { border-radius: 12px; padding: 16px; background: var(--pale); text-align: center; }
.price-label { font-size: 12px; font-weight: 700; color: var(--s500); }
/* ★★★2026-09-02 사용자 지시 — 「회 당 가격」 줄. **전체 금액 바로 위**에 온다.
   ⚠️큰 숫자(.price-amount)가 **실제 청구액**이고 이 줄은 그것을 회차로 나눈 참고 값이다.
     그래서 글자가 작다 — ⛔크기를 뒤집지 말 것(무엇이 청구액인지 헷갈린다). */
.price-unit { margin-top: 6px; font-size: 13.5px; font-weight: 700; color: var(--s500); }
.price-amount { margin-top: 4px; font-size: 26px; font-weight: 800; color: var(--main); }
.price-calc { margin-top: 4px; font-size: 12.5px; color: var(--s500); word-break: keep-all; }
.classinfo { border-radius: 10px; padding: 12px 14px; background: var(--s50); box-shadow: inset 0 0 0 1px var(--s200); }
/* ★2026-08-13(3차) 사용자 지시 — 개설 확인 팝업의 단계·지역·기간·시각 네 줄을 **1.5배**로.
   ★★(4차) 재지시 — **가장 긴 제목이 한 줄에 들어가는 크기까지 내린다.**
   ⚠️★★가장 긴 조합은 `🚀 MONEY MARBLE · 정규 (6회)` 다(단계 이름이 제일 길고 회차도 붙는다).
      19.5px 에서는 두 줄로 접혔다 → **16px**(실측으로 정한 값 · 아래 `.ci-row` 는 같은 비율로 14.8px).
   ⚠️ 이 값을 다시 올릴 거면 **그 문자열로 실측**하고 올릴 것 — 눈으로는 STARTER 로만 보게 된다.
   ⚠️ 이 두 클래스는 **이 팝업 전용**이다(`#open-classinfo` 안에서만 만들어진다). */
.ci-title { font-size: 16px; font-weight: 800; color: var(--main); line-height: 1.35; word-break: keep-all; }
.ci-row { margin-top: 5px; font-size: 14.8px; color: var(--s600); line-height: 1.4; word-break: keep-all; }

/* ★★확인 체크박스 (2026-08-13(4차) 신설 · 사용자 지시) — 「개설하기」의 게이트다.
   ⚠️ **가운데 정렬**이 지시다. 손가락 자리를 넓히려고 `<label>` 통째로 누르게 두고,
      체크박스 자체도 18px 로 키운다(기본 13px 은 폰에서 노리기 어렵다). */
.agree-check {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 14px; padding: 10px 4px; cursor: pointer;
  font-size: 13.5px; font-weight: 700; color: var(--s700); word-break: keep-all; text-align: center;
}
.agree-check input { width: 18px; height: 18px; flex: none; accent-color: var(--main); }

/* 헤더 액션 버튼 */
.btn-about { font-size: 11.5px; padding: 6px 10px; white-space: nowrap; }
/* 🏠 = 랜딩으로. 이모지 하나뿐이라 「더 알아보기」와 높이를 맞춰 준다 (2026-08-03) */
.btn-landing { font-size: 14px; line-height: 1; padding: 6px 9px; }
.btn-icon { min-width: var(--tap); padding: 6px 8px; font-size: 18px; }
/* 좁은 화면: 헤더가 넘치지 않도록 로고 글자를 숨기고 이미지만 남긴다 */
@media (max-width: 470px) {
  .appbar .logo > div { display: none; }
  .btn-about { font-size: 11px; padding: 6px 8px; }
}

/* 캘린더 */
.cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.cal-title { font-size: 14px; font-weight: 800; }
.cal-nav { width: 34px; height: 34px; border: 1px solid var(--s200); border-radius: 8px; background: #fff; font-size: 14px; color: var(--s600); }
.cal-nav:disabled { color: var(--s300); cursor: not-allowed; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-dow { text-align: center; font-size: 10.5px; font-weight: 700; color: var(--s400); padding: 4px 0; }
/* ★2026-08-12 사용자 지시 — 달력 관례대로 **토요일 파랑 · 일요일 빨강**.
   ⚠️ 붙이는 것은 **머리글 한 줄뿐**이다 — 날짜 칸은 「고를 수 있나」(able/pick/holiday)를
      색으로 말하고 있어서, 요일 색까지 섞으면 무슨 뜻인지 읽을 수 없게 된다.
   ⚠️ 클래스는 m-app.js 가 **인덱스로** 붙인다(0=일 · 6=토) — 글자로 판정하지 않는다. */
.cal-dow.is-sun { color: var(--danger); }
.cal-dow.is-sat { color: var(--main); }
.cal-day {
  aspect-ratio: 1; border: 0; border-radius: 8px; background: #fff;
  font-size: 12.5px; font-weight: 600; color: var(--s700);
}
.cal-day:disabled { color: var(--s300); background: transparent; cursor: not-allowed; }
.cal-day.holiday:disabled { color: #e5a3a1; }
.cal-day.pick { background: var(--main); color: #fff; font-weight: 800; }
.cal-day.able { background: var(--pale); color: var(--main); font-weight: 800; }
/* ★2026-08-13 사용자 지시 — 회색(--s400)에서 **빨강**으로. 이 줄은 「왜 앞쪽 날짜가 다
   잠겼나」의 답이라 눈에 걸려야 한다(회색이라 아무도 안 읽고 「달력이 고장났다」로 봤다).
   ⚠️ --danger(#d9534f)는 흰 배경에서 대비비 4.1 — 11px 로는 얇다 → **12px + 700** 으로 세운다. */
.cal-legend { margin-top: 12px; font-size: 12px; font-weight: 700; color: var(--danger); line-height: 1.6; word-break: keep-all; }

/* 토스트 */
/* ⚠️★★2026-08-13(4차) — **`left: 50%` + `translateX(-50%)` 를 버렸다.**
   그 조합이 「글자가 짧은데도 접히는」 원인이었다: 폭이 auto 인 fixed 요소는 **`left` 지점부터
   오른쪽 끝까지**를 쓸 수 있는 폭으로 보므로, `left:50%` 면 **화면의 절반(390px 폰에서 195px)**
   밖에 못 쓴다. `max-width: calc(100% - 32px)` 는 그보다 넓어서 아무 일도 하지 않았다.
   → **양쪽을 16px 로 잡고 `margin: 0 auto` 로 가운데**에 세운다. 이제 실제로 화면 폭까지 쓴다.
   ⚠️ 팝업(.backdrop = 70)보다 위여야 한다 — 팝업 안에서 저장하면 토스트가 그 위에 뜬다.
      이 셋의 순서를 바꾸지 말 것: 플로팅 버튼 60 < 팝업 70 < 토스트 80 */
.toast {
  position: fixed; left: 16px; right: 16px; bottom: 24px;
  width: fit-content; max-width: calc(100% - 32px); margin: 0 auto;
  transform: translateY(14px);
  z-index: 80; border-radius: 10px; padding: 11px 18px;
  background: var(--s800); color: #fff; font-size: 13px; font-weight: 700;
  opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s;
  text-align: center;
  /* ★두 줄짜리 문구를 위해 `\n` 을 그대로 살린다(토스트는 textContent 로 넣는다 — HTML 을 넣지 않는다).
     ⚠️ 끊을 자리를 우리가 정하되, 안 끊기는 줄은 낱말째 접히게 `word-break: keep-all` 을 함께 둔다. */
  white-space: pre-line; word-break: keep-all;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast.err { background: var(--danger); }

.proto-note { margin-top: 28px; text-align: center; font-size: 11px; color: var(--s400); }
.link-btn { border: 0; background: none; color: var(--main); font-size: 11px; font-weight: 700; text-decoration: underline; }

/* ---------- 푸터 (2026-08-05 신설) ----------
   사업자 정보 + 약관·개인정보 처리방침. ⚠️ 이름은 `foot-` 로 시작한다 — app.css 는 네 페이지
   공용이라 `.footer` 같은 흔한 이름을 새로 만들면 다른 화면이 조용히 눌린다(0731 `.cal-nav` 사고).
   ⚠️ `.modal-foot` 과 헷갈리지 말 것(그건 팝업 바닥 버튼 줄이다). */
.site-foot {
  margin-top: 32px; padding-top: 18px;
  /* ⚠️ 아래를 비워 둔다 — 페이지 끝까지 내리면 플로팅 버튼(문의·결제)이 **약관 링크를 덮어**
     오른쪽 절반이 안 눌린다. 버튼이 차지하는 높이(16px + 56px)보다 넉넉히 둔다 (2026-08-05 실측). */
  padding-bottom: 44px;
  border-top: 1px solid var(--s200);
  text-align: center; color: var(--s400); font-size: 11px; line-height: 1.7;
}
.site-foot p { margin: 0; }
.foot-links { margin-top: 8px; display: flex; justify-content: center; align-items: center; gap: 10px; }
/* 링크처럼 보이지만 버튼이다(팝업을 연다) — 밑줄로 「누를 수 있음」을 남긴다 */
.foot-link {
  padding: 4px 2px; border: 0; background: none;
  color: var(--s500); font-size: 11px; font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px;
}
.foot-sep { color: var(--s300); }

/* 약관·처리방침 본문 — 조문이 길어 팝업 안에서 스크롤된다(.modal-body 가 이미 스크롤한다) */
.doc-body { color: var(--s600); font-size: 12.5px; line-height: 1.65; }
.doc-body h3 { margin: 16px 0 6px; color: var(--s800); font-size: 13px; font-weight: 800; }
.doc-body h3:first-child { margin-top: 0; }
.doc-body p { margin: 0 0 6px; }
.doc-body ul { margin: 0 0 6px; padding-left: 18px; }
.doc-body li { margin-bottom: 3px; }
/* 확인 버튼 하나뿐인 바닥 — `.modal-foot` 은 2칸 격자라 그냥 두면 버튼이 **왼쪽 칸에 박힌다**
   (0803 커리큘럼 팝업과 같은 처방). ⚠️ 이 두 팝업으로만 좁혀서 덮는다. */
#modal-terms .modal-foot,
#modal-privacy .modal-foot { grid-template-columns: 1fr; }

/* ---------- 반응형 ---------- */
@media (min-width: 560px) {
  .wrap { padding: 20px 20px 60px; }
  /* ★2026-08-15: 캐릭터 1.5배(74→111px)에 맞춰 여기도 함께 올렸다 = 111 + 여백 14 + 숨통 22 */
  .hero { padding: 22px 147px 22px 22px; }
  .hero-l2 { font-size: 21px; }
  .row { grid-template-columns: 104px 1fr; }
}
@media (max-width: 360px) {
  .row { grid-template-columns: 80px 1fr; }
  .kcard { padding-right: 106px; }
  /* ⚠️ 오른쪽 칸을 줄이면 **왼쪽 padding-right 도 같이** 줄여야 한다 — 안 그러면 글자 폭만 좁아진다 */
  .kcard { padding-right: 112px; }
  .kcard-right { width: 86px; }
}

/* ---------------- 플로팅 버튼 (수강료 · 결제) ----------------
   하단 우측 고정. 목록을 끝까지 스크롤해도 항상 닿는 곳에 둔다.
   결제   = 개설 확정된 내 클래스의 수강료 결제(2026-07-20 신설).
   수강료 = 어드민이 올린 클래스별 수강료 이미지(2026-08-15 신설 · 사용자 지시).
   ⛔문의는 2026-08-15 에 **헤더(내 정보 옆 말풍선)로 옮겼다** — `.appbar-ask` 를 볼 것.
   ⚠️★★버튼 개수는 **둘**이다. 랜딩 하단 CTA 막대(`.lp-cta`)의 `padding-left: 122px` 가
      「44px 버튼 두 개」를 전제로 비워 둔 자리라, 개수를 바꾸면 그 값도 함께 고쳐야 한다. */
.fab-stack {
  position: fixed;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 60;
  display: flex;
  flex-direction: row-reverse;   /* 결제를 바깥(오른쪽)에 둔다 */
  align-items: center;
  gap: 10px;
}
.fab {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: 56px;
  height: 56px;
  flex: none;
  border: 0;
  border-radius: 50%;
  background: var(--main);
  color: #fff;
  text-decoration: none;
  box-shadow: 0 4px 14px rgba(43, 75, 177, .38);
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.fab:hover,
.fab:focus-visible { background: var(--main-dark); box-shadow: 0 6px 18px rgba(43, 75, 177, .48); }
.fab:active { transform: scale(.94); }
.fab svg { display: block; margin-top: 2px; }
.fab-label { font-size: 10px; font-weight: 700; letter-spacing: -.3px; line-height: 1; }

/* ★2026-08-15 신설 — 수강료. 색은 기본(메인 파랑) 그대로다: 결제만 「해야 할 일」 색을 갖고
   나머지는 브랜드 색이라는 규칙을 유지한다.
   ⚠️ 글자가 **세 글자**라 기본 10px 로는 지름 56px 안에서 좌우가 빠듯하다 → 이 버튼만 9.5px.
      ⛔`.fab-label` 을 통째로 줄이지 말 것 — 「결제」 두 글자까지 같이 작아진다. */
.fab-tuition .fab-label { font-size: 9.5px; letter-spacing: -.5px; }

/* 결제는 「해야 할 일」이라 눈에 띄는 색으로 구분한다 */
.fab-pay { background: var(--pay); box-shadow: 0 4px 14px rgba(255, 66, 95, .38); }
/* 장바구니 그림은 viewBox 안에서 오른쪽으로 치우쳐 있다(칠해진 폭이 x 4~21.7 → 중심 12.85,
   viewBox 중심은 12). 그대로 두면 아래 「결제」 글자보다 1px 쯤 오른쪽에 앉는다 →
   그 차이만큼 되민다 (2026-08-05 사용자 지시). ⚠️ 아이콘만 옮긴다 — 버튼은 그대로다. */
.fab-pay svg { transform: translateX(-1px); }
.fab-pay:hover,
.fab-pay:focus-visible { background: #e63a54; box-shadow: 0 6px 18px rgba(255, 66, 95, .48); }
.fab-badge {
  position: absolute;
  top: -2px; right: -2px;
  min-width: 20px; height: 20px;
  padding: 0 5px;
  border-radius: 999px;
  background: #fff;
  color: var(--pay);
  font-size: 11px; font-weight: 800; line-height: 20px;
  box-shadow: 0 1px 4px rgba(0,0,0,.2);
}

/* 결제 팝업 안의 클래스 카드 */
.pay-item { border: 1px solid var(--s200); border-radius: 12px; padding: 12px 14px; margin-top: 10px; }
.pay-item .btn-pay { margin-top: 10px; width: 100%; }
.pay-item-t { font-size: 14px; font-weight: 800; color: var(--main); }
.pay-item-m { margin-top: 3px; font-size: 12.5px; color: var(--s600); line-height: 1.6; word-break: keep-all; }

/* 토스트가 버튼에 가리지 않도록 살짝 띄운다 */
.toast.show ~ .fab-stack { transform: translateY(-4px); }

/* 팝업이 열려 있는 동안에는 플로팅 버튼을 **아예 감춘다** (2026-08-05 사용자 지시).
   z-index 만으로도 팝업이 앞에 오지만, 반투명 막(rgba .55) 뒤로 빨간 결제 버튼이 비쳐
   「팝업 위에 떠 있는 것처럼」 보였다. ⚠️ `:has` 는 이 프로젝트가 이미 쓰고 있다
   (`.lp-bn-dots:has(...)`). 못 쓰는 브라우저에서도 z-index 덕에 가려지기는 한다. */
body:has(.backdrop:not([hidden])) .fab-stack { display: none; }

/* ================================================================
   학부모 리포트 템플릿 (.wr-*)  — 2026-07-25
   ★ js/rpt-view.js 의 renderParentReport() 가 만드는 DOM 전용 스타일.
     학부모 열람 화면(/report)과 강사 미리보기 팝업이 **같은 마크업**을 쓰므로
     이 블록만 고치면 양쪽이 함께 바뀐다.
   브랜드 3색만 쓴다: 딥블루 #2b4bb1(--main) / 라이트블루 #83acdd(--sub) / 옐로 #ffd252(--accent)
================================================================= */
.wr {
  background: #fff;
  border-radius: 18px;
  overflow: hidden;                    /* 헤더 밴드의 둥근 모서리를 유지 */
  box-shadow: 0 6px 22px rgba(43,75,177,.10), inset 0 0 0 1px var(--s100);
}
.wr + .wr { margin-top: 16px; }

/* ---- 헤더 밴드 ---- */
.wr-top {
  position: relative;
  padding: 18px 20px 16px;
  background: linear-gradient(135deg, var(--main) 0%, #3a63c9 55%, var(--sub) 100%);
  color: #fff;
}
/* 옐로 라인 = 브랜드 포인트. 밴드와 본문을 가르는 경계 역할도 한다 */
.wr-top::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  background: var(--accent);
}
/* 오른쪽 위 동전 느낌의 옅은 원 — 이미지 없이 브랜드 톤만 얹는다 */
.wr-top::before {
  content: ''; position: absolute; right: -26px; top: -30px;
  width: 116px; height: 116px; border-radius: 50%;
  background: rgba(255,210,82,.18);
}
.wr-brand { position: relative; display: flex; align-items: center; gap: 9px; }
/* 로고 원본이 흰 바탕 정사각이라 파란 밴드 위에 그대로 얹어도 읽힌다 */
.wr-logo {
  flex: none; width: 36px; height: 36px; display: block;
  border-radius: 10px; background: #fff; object-fit: contain;
  box-shadow: 0 2px 8px rgba(0,0,0,.14);
}
.wr-brand-t { font-size: 12px; font-weight: 700; color: rgba(255,255,255,.94); }
.wr-who { position: relative; margin-top: 12px; display: flex; align-items: baseline; flex-wrap: wrap; gap: 7px; }
.wr-who b { font-size: 22px; font-weight: 800; letter-spacing: -.6px; }
/* 학년(이름 줄)·회차(날짜 줄) 알약은 **같은 높이·같은 글자 크기**를 쓴다.
   자리는 서로 다르지만 높이가 어긋나면 두 알약이 다른 부품처럼 보인다.
   높이를 만드는 값(글자 크기·세로 여백·행간)을 한 규칙에 모아 둬야 둘이 갈라지지 않는다.
   ⚠️ 가로 여백은 각자 유지한다 — 회차 쪽 폭은 지금 그대로 두기로 했다(2026-07-24). */
.wr-grade, .wr-session {
  border-radius: 999px;
  font-size: 11px; font-weight: 700; line-height: 1.45;
  padding-top: 2px; padding-bottom: 2px;
}
.wr-grade {
  background: rgba(255,255,255,.22);
  padding-left: 9px; padding-right: 9px;
}
.wr-badge {
  background: var(--accent); color: var(--main-dark); border-radius: 999px;
  padding: 2px 9px; font-size: 10.5px; font-weight: 800;
}
.wr-date {
  position: relative; margin-top: 5px;
  display: flex; align-items: center; flex-wrap: wrap; gap: 7px;
  font-size: 12px; font-weight: 600; color: rgba(255,255,255,.9);
}
/* 회차 — 특강·정규만 붙는다 (원데이는 총 1회라 표시하지 않는다).
   높이·글자 크기는 위의 `.wr-grade, .wr-session` 공용 규칙이 정한다. */
.wr-session {
  display: inline-flex; align-items: baseline; gap: 4px;
  background: var(--accent); color: var(--main-dark);
  padding-left: 10px; padding-right: 10px;
}
.wr-session b { font-weight: 800; }
.wr-session small { font-size: 10px; font-weight: 700; opacity: .72; }
.wr-place { position: relative; margin-top: 2px; font-size: 11px; color: rgba(255,255,255,.75); }

/* ★금융 성장 스토리 (2026-08-19) — 파일 한 장이 본문이라 폭을 꽉 채우고, 여는 버튼은 크게.
   ⚠️ 이미지 세로 길이를 제한하지 않는다 — 스토리는 세로로 긴 한 장이 기본이다. */
.wr-story-img { display: block; width: 100%; height: auto; border-radius: 12px;
  border: 1px solid var(--s200); margin: 14px 0; background: var(--s50); }
.wr-story-open { display: block; margin: 14px 0 0; padding: 14px 16px; border-radius: 12px;
  background: var(--main); color: #fff; font-size: 14px; font-weight: 800;
  text-align: center; text-decoration: none; }
.wr-body { padding: 18px 20px 6px; }

/* ---- 오늘 배운 것 ---- */
.wr-learn { background: var(--pale); border-radius: 12px; padding: 12px 14px; }
.wr-learn-row { display: flex; align-items: flex-start; gap: 10px; }
.wr-learn-row + .wr-learn-row { margin-top: 8px; }
.wr-learn-k {
  flex: none; width: 62px; text-align: center;
  background: #fff; color: var(--main); border-radius: 999px;
  padding: 3px 0; font-size: 10.5px; font-weight: 800;
}
.wr-learn-v { font-size: 13px; font-weight: 700; color: var(--main-dark); line-height: 1.5; word-break: keep-all; }
.wr-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.wr-tag {
  background: var(--sub); color: #fff; border-radius: 999px;
  padding: 3px 10px; font-size: 11px; font-weight: 700;
}

/* ---- 성향 유형 리본 ---- */
.wr-type {
  display: flex; align-items: center; gap: 9px;
  margin-top: 12px; padding: 11px 14px;
  background: #fffaeb; border-radius: 12px;
  box-shadow: inset 0 0 0 1.5px var(--accent);
}
.wr-type-k { flex: none; font-size: 10.5px; font-weight: 800; color: #8a6100; }
.wr-type-v { font-size: 14.5px; font-weight: 800; color: var(--main-dark); letter-spacing: -.3px; }

/* ---- 3단 문안 ---- */
.wr-sec { margin-top: 18px; }
.wr-sec-h { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.wr-no {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--main); color: #fff; font-size: 11.5px; font-weight: 800;
}
.wr-no-cam { background: var(--sub); font-size: 11px; }
.wr-sec-t { font-size: 13px; font-weight: 800; color: var(--main); letter-spacing: -.3px; }
.wr-sec-p {
  margin: 0; padding-left: 30px;
  font-size: 13.5px; color: var(--s700); line-height: 1.85;
  word-break: keep-all; white-space: pre-line;
}

/* ---- 활동 사진 ---- */
.wr-photos { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding-left: 30px; }
.wr-photos.one { grid-template-columns: 1fr; }
.wr-photo {
  aspect-ratio: 4 / 3; border-radius: 12px; overflow: hidden;
  background: var(--s100); box-shadow: inset 0 0 0 1px var(--s200);
}
.wr-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---- 푸터 ---- */
.wr-foot {
  margin-top: 18px; padding: 14px 20px 16px;
  background: var(--s50); border-top: 1px solid var(--s100); text-align: center;
}
.wr-foot-t { font-size: 12.5px; font-weight: 800; color: var(--main); }
.wr-foot-s { margin-top: 3px; font-size: 10.5px; color: var(--s400); letter-spacing: .2px; }

/* 좁은 화면(360) — 여백을 줄이고 본문 들여쓰기를 없앤다 */
@media (max-width: 380px) {
  .wr-top { padding: 16px 16px 14px; }
  .wr-body { padding: 16px 16px 6px; }
  .wr-sec-p, .wr-photos { padding-left: 0; }
  .wr-foot { padding: 13px 16px 15px; }
}

/* ================= 커리큘럼 (2026-08-01 신설) =================
   학부모 신청 폼의 「커리큘럼」 줄 + 「커리큘럼 알아보기」 팝업.
   ⚠️ 이름은 전부 `cur-` / `course-` 로 시작한다 — app.css 는 학부모·강사·어드민·리포트
      네 페이지가 함께 쓰므로, 흔한 이름을 새로 만들면 다른 화면이 조용히 눌린다
      (0731 `.cal-nav` 사고). 색은 브랜드 3색만 쓴다. */

/* ---- 신청 폼: 클래스 선택 드롭다운 ----
   ⛔`.course-fixed`·`.course-badge`·`.course-txt`(자동 확정된 커리큘럼을 보여 주던 상자)는
     2026-08-11 에 사라졌다 — 학부모가 **직접 고르는 드롭다운**으로 바뀌었기 때문이다.
   ★값·목록은 **왼쪽 정렬 + 약간의 좌측 패딩**이다(사용자 지시). 긴 단계 이름이 가운데 정렬이면
     한 줄마다 시작점을 다시 찾게 된다 — 강사 리포트 화면에서 0810 에 같은 이유로 뒤집었다.
   ⚠️ 닫힌 줄(고른 값)의 정렬은 `text-align` 이 아니라 **`text-align-last`** 가 정한다. */
/* ⚠️ `select.sel-left` 로 쓴다 — 그냥 `.sel-left` 면 위쪽 `select.input` 의 padding 이 이겨
   (같은 특이도에서 **먼저 선언된 쪽이 아니라 더 구체적인 쪽**이 이긴다) 좌측 패딩이 안 먹는다. */
select.sel-left { text-align: left; text-align-last: left; padding-left: 12px; }

/* ================= 클래스 선택 — **우리가 그리는 드롭다운** (2026-08-13 3차 지시) ==========
   ⛔사라진 것 = `select.sel-left option { … font-size: 14px }` + m-app 의 FIGURE SPACE 채우기.
     **iOS 는 펼친 목록을 우리 CSS 로 그리지 않는다** — 아이폰 16 Pro 실화면에서 이모지·글자가
     크게 나오고 자물쇠가 아랫줄로 접혔다(사용자 스크린샷). 네이티브 피커로는 여기까지가 한계다.
   ★그래서 우리 마크업으로 그린다. 그 결과 **접힘이 구조적으로 불가능**해졌다 —
     이름은 `nowrap + ellipsis` 라 절대 두 줄이 되지 않고, 자물쇠는 `margin-left: auto` 로
     **재지 않고** 오른쪽 끝에 선다.
   ⚠️ 닫힌 줄(버튼)은 16px 를 유지한다 — 값은 크게 읽혀야 한다. **펼친 목록만 14px** 다.
   ⚠️ iOS 자동확대(16px 미만) 규칙은 <input>/<select> 에만 걸린다 — 목록은 <button> 이라 무관하다. */
.csel { position: relative; width: 100%; }
/* 값의 원본. ⚠️★★지우지 말 것 — 「고른 값」과 「잠긴 값이 들어오면 떨어진다」를 이 요소가 맡는다.
   보이지 않을 뿐 살아 있는 모델이다(m-app 의 paintCourse 가 이걸 채우고 읽는다). */
.csel-native { display: none; }
.csel-btn {
  display: flex; align-items: center; gap: 8px;
  text-align: left; padding-right: 34px;
  color: var(--s800); position: relative;
}
.csel-btn-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 화살표 — 네이티브 select 가 그려 주던 것을 대신한다(펼치면 뒤집는다) */
.csel-btn::after {
  content: ''; position: absolute; right: 14px; top: 50%;
  width: 8px; height: 8px; margin-top: -6px;
  border-right: 2px solid var(--s400); border-bottom: 2px solid var(--s400);
  transform: rotate(45deg); transition: transform .15s;
}
.csel-btn[aria-expanded="true"]::after { transform: rotate(-135deg); margin-top: -2px; }
.csel-btn[aria-expanded="true"] { border-color: var(--main); box-shadow: 0 0 0 3px rgba(43,75,177,.18); }
/* 안 고른 동안만 안내 글자를 한 단계 작게 — 옛 `select.input.is-ph` 와 같은 규칙 */
.csel-btn.is-ph .csel-btn-t { font-size: 14px; color: var(--s400); }

/* ⚠️★★z-index 는 **플로팅 버튼(60)보다 위**여야 한다 — 원데이는 줄이 8개라 목록이 화면 아래까지
   내려오는데, 30 으로 두면 「결제·문의」 동그라미가 목록 위에 얹혀 마지막 줄들을 가린다
   (네이티브 피커는 늘 최상단이라 이 문제가 없었다 — 우리가 그리면 우리가 챙겨야 한다).
   ⚠️ 팝업(.backdrop 70)보다는 **아래**다. 팝업이 열려 있으면 그게 화면에서 가장 앞이다. */
.csel-list {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 65;
  max-height: 320px; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: #fff; border: 1px solid var(--s300); border-radius: 10px;
  box-shadow: 0 10px 24px rgba(15, 23, 42, .16);
}
.csel-opt {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 10px 12px;
  border: 0; background: none; text-align: left;
  font-size: 14px; font-weight: 600; color: var(--s800);
}
.csel-opt + .csel-opt { border-top: 1px solid var(--s100); }
/* ★이모지도 목록 글자와 같은 크기다 — 네이티브 피커는 이모지를 글자보다 크게 그려서
   이름이 쓸 폭을 먹었다(그게 자물쇠를 아랫줄로 밀어낸 실제 원인이다). */
.csel-badge { flex: none; font-size: 14px; line-height: 1; }
/* ⚠️★★`nowrap` 이 이 화면의 계약이다 — 이름이 아무리 길어도 두 줄이 되지 않는다(줄임표로 끝난다) */
.csel-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ★자물쇠는 **오른쪽 끝**. 폭을 재지 않으므로 글꼴·기기 폭이 달라져도 어긋날 수 없다. */
/* ★2026-08-26 — 클래스 선택 줄의 「추천」 알약. 자물쇠와 **같은 자리**(오른쪽 끝)다.
   ⚠️ 자물쇠와 함께 붙는 일은 없다 — 잠긴 단계는 추천하지 않는다. */
/* ★★2026-08-26 — BEGINNER 추천 팝업은 **함께하기 팝업 위**에 떠야 한다.
   ⚠️ 둘 다 `.backdrop`(z-index 70)이고 `#modal-join` 이 문서에서 **뒤에** 있어,
      z-index 를 안 올리면 뒤엣것이 이겨 팝업이 안 보인 채 흐름만 멈춘다. */
#modal-first { z-index: 72; }
.csel-rec { margin-left: auto; flex: none; padding: 2px 9px; border-radius: 999px;
  background: var(--accent); color: var(--main-dark); font-size: 11px; font-weight: 800; }
.csel-lock { flex: none; margin-left: auto; font-size: 13px; line-height: 1; }
.csel-opt.is-lock { color: var(--s400); }
.csel-opt[aria-selected="true"] { background: var(--pale); color: var(--main); font-weight: 800; }

/* ★2026-08-13(5차) 사용자 지시 — 함께하기 팝업의 **섹션 간격을 약간 벌린다**.
   순서가 「클래스 정보 → 장소 → 금액 → 결제 안내」로 바뀌면서 상자 셋이 붙어 한 덩어리로 읽혔다.
   ⚠️ `.price-box`·`.pay-notice` 자체는 못 건드린다 — 신청하기 확인 팝업이 함께 쓴다. */
#join-price-box { margin-top: 14px; }
#modal-join .pay-notice { margin-top: 16px; }
/* 안내 한 줄은 드롭다운에 붙여 둔다 — `.field-hint` 기본 여백(아래 10px)은 여기서 과하다
   (부모 `.row-val` 의 gap 6px 이 이미 벌리고 있다). */
#q-course-hint { margin: 0; }

.link-more {
  margin-top: 8px; padding: 0;
  background: none; border: 0;
  color: var(--main); font-size: 13px; font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
/* ★부모(.row-val)가 세로 flex 라 기본은 폭을 꽉 채워 늘어난다 → 버튼 글자가 가운데로 가서
   위 커리큘럼 상자와 어긋나 보였다. 내용 폭으로 줄이고 **오른쪽 끝을 상자와 맞춘다**
   (2026-08-03 사용자 지시). ⚠️ `text-align:right` 로는 안 된다 — 늘어난 폭 자체가 남는다. */
/* ⚠️ 부모(.row-val)의 `gap: 6px` 이 먼저 벌린다 — margin-top 을 0으로 해도 6px 이 남는다.
   더 붙이려면 **음수 margin 으로 그 gap 을 덜어내야** 한다 (2026-08-05 사용자 지시로 한 번 더 축소). */
/* ★★2026-08-12(3차) 사용자 지시 — `.row` **밖으로** 나왔다(그 줄 바로 아래·오른쪽 끝).
   안에 있을 때는 설명 칸에 얹혀 「클래스 선택의 부속」처럼 보였고, 부모의 `gap` 을 음수 margin 으로
   덜어내야 하는 자리이기도 했다. 이제 자기 줄이라 그 잔재주가 통째로 필요 없다.
   ⚠️ 오른쪽 끝은 **`.row` 의 오른쪽 끝과 같아야** 한다 — `.row` 는 폭을 꽉 채우므로 이 줄도
      블록으로 두고 `margin-left: auto` 로 내용 폭만큼만 오른쪽에 붙인다. */
.row-after { display: flex; justify-content: flex-end; margin: -2px 0 12px; }
#q-course-more { font-size: 14px; padding: 4px 0; }

/* ---- 팝업 ---- */
.cur-modal { max-width: 400px; }

/* ★★커리큘럼 상세는 **폰에서 전체 화면**으로 연다 (2026-08-10 밤 사용자 지시 — 가시성 확보).
   이 팝업만 안에 상세 이미지 18장이 들어와서, 여백에 갇힌 400px 상자로는 그림이 작아
   무엇을 배우는지가 안 읽혔다.
   ⚠️ 넓은 화면(태블릿·데스크톱)에서는 **그대로 상자**다 — 전체 화면으로 펼치면 한 줄이
      너무 길어져 오히려 읽기 어렵다. 그래서 폭 조건을 건다.
   ⚠️ `.backdrop` 의 `padding: 20px 16px` 과 `.modal` 의 `border-radius`·`max-height` 를
      **셋 다** 되돌려야 진짜 끝까지 찬다 — 하나만 빠뜨리면 가장자리에 흰 띠가 남는다.
   ⚠️ 안전영역(노치·홈 인디케이터)은 여기서 챙긴다 — 전체 화면이 되면 그 자리를 우리가 쓴다. */
/* ★★2026-08-12(2차) 사용자 지시 — **「클래스 신청하는 방법」 팝업도 같은 UI 다.**
   그쪽도 내용이 어드민이 올린 세로 이미지라 요구가 똑같다(작으면 못 읽는다).
   ⚠️ 셀렉터를 **한 벌로 묶어** 둔다 — 따로 적으면 한쪽만 고쳐져 두 팝업이 달라진다. */
/* ★2026-08-13: **보드게임 소개 팝업(#modal-games)도 같은 UI 다** — 내용이 세로로 긴 소개
   이미지 한 장이 되면서 요구가 위 둘과 똑같아졌다(작으면 못 읽는다). 셋을 한 벌로 묶는다. */
/* ★2026-08-15: **수강료 팝업(#modal-tuition)도 같은 UI 다** — 역시 어드민이 올린 세로 이미지다.
   ⚠️ 이 셀렉터 묶음에 팝업을 더할 때는 **여섯 규칙 전부**에 넣어야 한다. 하나만 빠뜨리면
      「전체화면인데 바닥 버튼만 떠 있는」 식으로 조용히 어긋난다(에러가 안 난다). */
@media (max-width: 560px) {
  #modal-curriculum,
  #modal-howto,
  #modal-games,
  #modal-tuition,
  #modal-reports,
  #modal-gamepick { padding: 0; align-items: stretch; justify-content: stretch; }
  #modal-curriculum .cur-modal,
  #modal-howto .cur-modal,
  #modal-games .cur-modal,
  #modal-tuition .cur-modal,
  #modal-reports .cur-modal,
  #modal-gamepick .cur-modal {
    max-width: none; width: 100%;
    border-radius: 0;
    max-height: none; height: 100%;
  }
  /* ★★2026-08-13(3차) 사용자 지시 — 「확인」 버튼을 **떠 있는 바에서 내용의 끝으로** 내린다.
     예전에는 `.modal` 이 세로 flex 라 `.modal-foot` 이 바닥에 붙박여 **내용 위에 떠 있었고**,
     세로로 긴 이미지를 읽는 내내 화면 아래를 가리고 있었다. 나가는 길은 **오른쪽 위 ×** 가 이미
     맡고 있으므로(그게 지시의 근거다) 확인 버튼이 늘 보일 이유가 없다.
     ★그래서 **스크롤 주체를 `.modal-body` 에서 `.modal` 로 옮긴다** — 머리·본문·바닥이 한 흐름으로
     흐르고, 버튼은 끝까지 내렸을 때 나온다.
     ⚠️★★머리는 `sticky` 로 붙여 둔다 — 통째로 흐르게 두면 **× 가 스크롤 밖으로 사라져** 지시의
        전제(「× 로 나갈 수 있으니」)가 깨진다. 배경을 반드시 칠할 것(투명이면 글자가 겹쳐 보인다).
     ⚠️ 넓은 화면(561px~)은 그대로 상자 + 붙박이 바닥이다 — 거기서는 가리는 문제가 없다. */
  #modal-curriculum .cur-modal,
  #modal-howto .cur-modal,
  #modal-games .cur-modal,
  #modal-tuition .cur-modal,
  #modal-reports .cur-modal,
  #modal-gamepick .cur-modal { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  #modal-curriculum .modal-body,
  #modal-howto .modal-body,
  #modal-games .modal-body,
  #modal-tuition .modal-body,
  #modal-reports .modal-body,
  #modal-gamepick .modal-body { overflow: visible; }
  #modal-curriculum .modal-head,
  #modal-howto .modal-head,
  #modal-games .modal-head,
  #modal-tuition .modal-head,
  #modal-reports .modal-head,
  #modal-gamepick .modal-head {
    position: sticky; top: 0; z-index: 2; flex: none; background: #fff;
    padding-top: calc(16px + env(safe-area-inset-top));
  }
  /* 버튼이 내용 끝에 서므로 위쪽 여백을 갖는다(예전에는 붙박이라 필요 없었다) */
  #modal-curriculum .modal-foot,
  #modal-howto .modal-foot,
  #modal-games .modal-foot,
  #modal-tuition .modal-foot,
  #modal-reports .modal-foot,
  #modal-gamepick .modal-foot { padding-top: 4px; padding-bottom: calc(18px + env(safe-area-inset-bottom)); }

  /* ★★2026-08-13(5차) 사용자 지시 — **신청하기 확인 팝업도 같은 처방**이다.
     내용이 길어(정보·금액·규정·확인 체크) 바닥에 붙박인 버튼이 규정 글을 계속 가리고 있었다.
     ⚠️ 이 팝업은 전체화면이 아니라 **여백 안의 상자**다 → `.modal` 이 스크롤 주체가 되게만 하고
        모서리·최대높이는 건드리지 않는다(그대로 상자로 남는다).
     ⚠️ 머리는 sticky — 나가는 길(×)이 스크롤 밖으로 사라지면 안 된다. 모서리 반경이 있으므로
        배경을 칠할 때 **위쪽 모서리도 함께** 둥글려야 흰 사각형이 삐져나오지 않는다. */
  #modal-open2 .modal { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  #modal-open2 .modal-body { overflow: visible; }
  #modal-open2 .modal-head {
    position: sticky; top: 0; z-index: 2; flex: none;
    background: #fff; border-radius: 16px 16px 0 0;
  }
  /* 지시 = 「버튼 컴포넌트 위에 패딩 약간」 — 규정 글과 버튼이 붙어 읽히던 자리다 */
  #modal-open2 .modal-foot { padding-top: 12px; }
  #modal-howto .modal-body,
  #modal-games .modal-body,
  #modal-tuition .modal-body,
  #modal-reports .modal-body,
  #modal-gamepick .modal-body { padding-left: 14px; padding-right: 14px; padding-bottom: 30px; }
  /* 전체 화면이 되면 가운데 칸이 길어진다 — 그림이 화면 폭을 그대로 쓰게 좌우 여백을 줄인다.
     ★2026-08-12 사용자 지시 — **아래는 반대로 넓힌다.** 끝까지 내리면 상세 이미지가 하단
     「확인」 버튼에 거의 붙어 끝났다. ⚠️ `.cur-mid` 의 margin-bottom 으로는 모자라다 —
     아래 `.cur-meta` 의 margin-top 과 **상쇄(margin collapsing)** 되어 4px 밖에 안 늘어난다. */
  #modal-curriculum .modal-body { padding-left: 14px; padding-right: 14px; padding-bottom: 30px; }
}

/* ================= 원데이 체험 보드게임 고르기 (2026-08-17 사용자 지시) =================
 * 안내 이미지 한 장 위에 **칸마다 투명한 버튼**을 얹는다.
 * ⚠️★★칸의 위치는 백분율이라 **이미지와 함께 늘어난다** — 그래서 `.gp-wrap` 이
 *    그림과 **정확히 같은 크기**여야 한다(`display:block` + `font-size:0` 으로 밑줄 여백 제거).
 *    래퍼가 그림보다 크면 칸이 통째로 밀려 **엉뚱한 게임이 골라진다.** */
.gp-wrap { position: relative; display: block; font-size: 0; line-height: 0; }
.gp-img { display: block; width: 100%; height: auto; border-radius: 12px; }
.gp-spot {
  position: absolute; margin: 0; padding: 0;
  border: 3px solid transparent; border-radius: 14px;
  background: transparent; cursor: pointer;
  /* 칸 위에 글자가 없다(그림이 이미 말하고 있다) — 읽는 이름은 aria-label 로만 준다 */
  -webkit-tap-highlight-color: transparent;
}
.gp-spot:focus-visible { outline: 3px solid var(--main); outline-offset: 2px; }
/* ★고른 칸 = **반짝이는 노란 테두리**(사용자 지시).
   ⚠️ 그림자와 테두리를 함께 흔든다 — 테두리 색만 바꾸면 밝은 배경에서 거의 안 보인다.
   ⚠️ `prefers-reduced-motion` 에서는 깜빡임을 멈추고 **켜진 상태로 고정**한다(선택은 계속 보여야 한다). */
.gp-spot.is-on { border-color: var(--accent); animation: gpGlow 1.1s ease-in-out infinite; }
@keyframes gpGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 210, 82, .85), 0 0 10px 2px rgba(255, 210, 82, .55); }
  50%      { box-shadow: 0 0 0 6px rgba(255, 210, 82, 0), 0 0 22px 8px rgba(255, 210, 82, .95); }
}
@media (prefers-reduced-motion: reduce) {
  .gp-spot.is-on { animation: none; box-shadow: 0 0 14px 4px rgba(255, 210, 82, .9); }
}

/* 학년대 토글 */
.cur-track { display: flex; gap: 6px; padding: 3px; background: var(--s100); border-radius: 10px; }
.cur-track-btn {
  flex: 1; padding: 8px 0;
  background: none; border: 0; border-radius: 8px;
  color: var(--s600); font-size: 13px; font-weight: 600;
}
.cur-track-btn[aria-selected="true"] { background: #fff; color: var(--main); box-shadow: 0 1px 3px rgba(0,0,0,.12); }

.cur-intro { margin: 10px 2px 12px; color: var(--s600); font-size: 12.5px; line-height: 1.5; }
/* ★안내 문구가 없는 단계(ADVANCED 위)에서는 **줄과 여백을 통째로** 없앤다 (2026-08-05).
   `hidden` 대신 `:empty` 인 이유 = 문구를 넣고 빼는 쪽(paintCurriculum)이 textContent 하나만
   다루면 되기 때문이다. 빈 문자열을 넣으면 자리도 함께 사라진다. */
.cur-intro:empty { display: none; }

/* 단계 세그먼티드 컨트롤
   ⚠️ 6칸을 360px 에 균등 분할하면 칸당 60px 이라 뱃지+이름이 눌린다 →
      가로 스크롤로 두고 칸 폭을 고정한다. 사다리가 선형이라 스크롤 자체가 진행감을 준다. */
.cur-seg-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.cur-seg-wrap::-webkit-scrollbar { display: none; }
/* ★★2026-08-02: 가로 한 줄을 포기하고 3×2 격자로 접는다.
   커리큘럼명이 한글 2~3자(씨앗·열매)에서 영문(BEGINNER·MONEY MARBLE)으로 길어져,
   360px 을 6칸으로 나누면 칸당 58px 이라 「MONEY MARBLE」이 세 줄로 쪼개진다.
   3칸이면 칸당 약 112px 이라 한 줄에 들어간다. 스크롤은 쓰지 않는다 —
   목표 단계(MONEY MARBLE)가 스크롤해야 보이면 사다리의 끝이 안 보인다(0801 결론 유지). */
.cur-seg {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 4px; padding: 3px;
  background: var(--s100); border-radius: 12px;
}
.cur-seg-btn {
  min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 7px 2px 6px;
  background: none; border: 0; border-radius: 9px;
  /* 기본은 랜딩 탭과 같은 규칙 — 전부 검은 글자로 통일하고 색은 고른 단계에만 (2026-08-03) */
  color: var(--s800); font-size: 11px; font-weight: 600;
}
.cur-seg-btn[aria-selected="true"] { background: var(--main); color: #fff; }
/* 확인 버튼 하나뿐인 바닥 — `.modal-foot` 이 2칸 격자라 버튼이 **왼쪽 칸에 박혀** 쏠려 보였다.
   폭을 꽉 채운다 (2026-08-03 사용자 확정 · 다른 단일버튼 모달과 같은 처방).
   ⚠️ `.modal-foot` 은 4개 페이지 공용이므로 **이 팝업으로만** 좁혀서 덮는다. */
.cur-modal .modal-foot { grid-template-columns: 1fr; }

.cur-seg-badge { font-size: 17px; line-height: 1.1; }
/* 이름이 칸보다 길면 줄바꿈 대신 줄여 준다 — 격자가 들쭉날쭉해지지 않게 */
.cur-seg-name {
  font-size: 11px; letter-spacing: -.2px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 고른 단계의 색 3갈래 — **더 알아보기 페이지의 사다리(.lp-rung)와 같은 규칙**이다
   (2026-08-03 사용자 확정 · 0810 에 상대가 가로 탭 `.lp-seg-btn` 에서 사다리로 바뀌었다).
   한쪽만 고치면 같은 사다리가 두 화면에서 다른 색이 된다 → 바꿀 땐 반드시 둘 다.
   ⚠️ 격자에서는 margin-left 로 띄우면 칸이 밀려 나가므로 색으로만 구분한다.
   ⚠️ **비선택 상태에는 색을 넣지 않는다** — 위 통일 규칙(--s800)을 덮어쓰지 말 것. */
.cur-seg-btn.is-first[aria-selected="true"] { background: var(--sub); color: var(--s800); }
.cur-seg-btn.is-last[aria-selected="true"] { background: var(--accent); color: var(--main); }

/* 상세 패널 */
.cur-panel { margin-top: 14px; }
.cur-head { display: flex; align-items: center; gap: 12px; }
.cur-head-badge {
  flex: 0 0 auto; width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  background: var(--pale); border-radius: 50%; font-size: 26px;
}
.cur-head-txt { min-width: 0; }
/* ⛔`.cur-head-step`(「n단계 / 총 6단계」)은 2026-08-14(4차) 사용자 지시로 삭제됐다.
   높이는 위 `.cur-head` 의 `align-items:center` 가 맞춘다 — 뱃지와 글자 묶음의 가운데가 만난다. */
.cur-head-name { color: var(--main); font-size: 18px; font-weight: 700; line-height: 1.3; }
.cur-head-desc { color: var(--s600); font-size: 13px; }
/* 학년대로 갈리는 단계에만 붙는 한 줄 (2026-08-05 사용자 지시로 색은 브랜드 서브 파랑).
   ⚠️ 흰 배경 위 --sub(#83acdd) 는 **대비비 2.36** 이다(작은 글씨 권장 4.5). 같은 패널의
      회차 번호(.cur-outline-no)가 이미 같은 색이라 톤은 맞지만, 읽기 힘들다는 말이 나오면
      --main 으로 내릴 것(대비비 8.6). 색을 바꿀 땐 반드시 대비비를 다시 잴 것. */
/* ⚠️ 한글은 기본값이 아무 글자에서나 잘린다(「달라 / 요!」) → 띄어쓰기에서만 접는다 */
.cur-head-note { margin-top: 3px; color: var(--sub); font-size: 12px; font-weight: 700; word-break: keep-all; }

/* 가운데 칸 — 회차표 또는 어드민이 올린 상세 이미지가 들어온다 (2026-08-05 신설).
   ⚠️ 위 간격은 **여기**가 가진다 — 안쪽(.cur-outline)에 두면 사이가 두 번 벌어진다. */
/* ★2026-08-12 사용자 지시 — 상세 이미지가 하단 「확인」 버튼에 딱 붙어 있었다.
   ⚠️ 여백을 `.modal-body` 의 padding-bottom 으로 주면 **회차표만 뜨는 단계**에서는 과해진다
      → 가운데 칸 자신이 아래 여백을 갖는다(그림이 있든 없든 같은 자리에서 끝난다). */
/* ★2026-08-13 사용자 지시 — 스크롤이 끝나는 자리(이미지 끝)와 하단 「확인」 버튼 사이에 여백을
   더 준다. 18 → 28px. ⚠️ 아래 요소가 사라져(`.cur-mine` 삭제) 상쇄될 margin 이 없으므로
   이 값이 그대로 보인다 — 전체화면일 때는 `.modal-body` 의 padding-bottom 30px 이 더 붙는다. */
.cur-mid { margin-top: 14px; margin-bottom: 28px; }
/* 상세 이미지가 들어올 때 = BEGINNER 의 회색 안내 칸과 같은 자리·같은 바탕 */
.cur-mid-img { background: var(--s50); border-radius: 10px; overflow: hidden; }
/* 같은 단계에 올린 이미지는 **위에서부터 끊김 없이** 이어 붙는다(한 장짜리 상세페이지처럼).
   ⚠️ 낱장에 모서리 반경을 주면 이어 붙인 자리가 패인다 — 반경은 감싼 `.cur-mid-img` 가 잘라 준다.
   ⚠️★★이 세 줄이 없으면 원본 크기(619~930px)로 나와 팝업을 뚫고 나간다.
      2026-08-10 에 랜딩 전용이던 `.lp-det-img` 를 지우면서 여기로 옮겼다. */
.lp-det-img { display: block; width: 100%; height: auto; }

.cur-outline { border-top: 1px solid var(--s200); }
.cur-outline-row { display: flex; gap: 10px; padding: 9px 2px; border-bottom: 1px solid var(--s100); }
.cur-outline-no { flex: 0 0 44px; color: var(--sub); font-size: 12px; font-weight: 700; }
/* 게임명(b) + 설명 한 줄(small). 아직 개발 전인 게임은 설명이 길어 두 줄이 될 수 있다 */
.cur-outline-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; color: var(--s700); font-size: 13px; }
.cur-outline-txt b { color: var(--s800, var(--main)); font-weight: 700; }
.cur-outline-txt small { color: var(--s500); font-size: 11.5px; line-height: 1.45; }
.cur-outline-todo {
  padding: 22px 12px; text-align: center;
  color: var(--s500); font-size: 13px;
  background: var(--s50); border-radius: 10px; margin-top: 10px;
}

/* ⛔`.cur-meta` · `.cur-meta-row` · `.cur-meta-sale`(회차·조건·할인 줄)은 2026-08-12 사용자
   지시로 사라졌다 — 어드민이 올린 상세 이미지가 같은 말을 이미 하고 있어, 확인 버튼 바로 위에서
   같은 내용이 두 번 보였다. 되살릴 일이 생기면 m-app.js 의 paintCoursePanel 에 다시 그리면 된다. */

/* ⛔`.cur-mine`(「우리 아이가 시작하는 단계예요」 옐로 알약)은 2026-08-13 사용자 지시로 사라졌다 —
   상세 이미지 끝과 「확인」 버튼 사이를 막고 있었다. 그 자리는 이제 아래 여백이 쓴다. */

@media (min-width: 640px) {
  .cur-modal { max-width: 520px; }
  /* 데스크톱은 flex 로 알아서 늘어난다 — 폭 고정 불필요 */
}

/* ================= 결제 시점 안내 (2026-08-03 신설) =================
   「신청 = 즉시 결제」로 오해하는 것을 막는다. 클래스 개설 확인 팝업과 클래스 신청
   팝업 두 곳에 같은 부품으로 들어간다.
   ⚠️ 글자 크기를 키우지 말 것 — 모달 안의 다른 글(.modal-msg 13px · .field-hint)과
      어긋나 레이아웃이 흐트러진다. **위치(금액 바로 밑)와 색**으로만 세운다.
   색은 브랜드 옐로(--accent #ffd252) 계열의 옅은 바탕이다. 파란 금액 상자(.price-box)
   바로 아래에서 확실히 갈라져 보이면서 경고(--danger)처럼 겁주지는 않는다. */
.pay-notice {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 12px; padding: 11px 12px;
  border-radius: 10px;
  background: #fff8e3;
  box-shadow: inset 0 0 0 1px #ffdf8f;
  /* ★2026-08-13 사용자 지시 — 글자를 **빨강**으로(갈색 #7a5c00 에서 바뀌었다). 노란 상자 안에서
     갈색은 배경에 묻혀 「그냥 안내」로 넘겨졌는데, 이 줄은 **지금 돈이 안 나간다**는 약속이라
     읽히지 않으면 뜻이 없다.
     ⚠️ --danger(#d9534f)는 이 노란 바탕(#fff8e3)에서 대비비 **3.73** 으로 12.5px 에는 모자라
        (AA 4.5) 한 단계 진한 빨강을 쓴다 — 본문 #c62828 = **5.31** · 굵은 줄 #a51c1c = **7.13**.
     ⚠️ 글자 크기는 그대로다(모달 본문 13px 보다 크면 레이아웃이 흐트러진다 — 검사가 지킨다). */
  color: #c62828;
  font-size: 12.5px; line-height: 1.55;
}
.pay-notice b { color: #a51c1c; font-weight: 800; }
.pay-notice-ic { flex: none; font-size: 14px; line-height: 1.45; }

/* ================= 랜딩 (2026-08-03 신설) =================
   시안 = 「우.아.금 클래스 개설 플랫폼(360*800)」 3페이지.
   ⚠️ 이름은 전부 `lp-` 로 시작한다 — app.css 는 학부모·강사·어드민·리포트 네 페이지가
      함께 쓰므로 흔한 이름을 새로 만들면 다른 화면이 조용히 눌린다(0731 `.cal-nav` 사고).
   ⚠️ 커리큘럼 상세는 팝업과 **같은 부품**(.cur-*)을 그대로 쓴다. 여기서 새로 만들면
      두 화면이 곧 어긋난다 — m-app.js 의 paintCoursePanel() 하나가 둘 다 그린다. */

/* 로고를 버튼으로 바꿔도 생김새는 그대로여야 한다 */
.logo-btn {
  padding: 0; border: 0; background: none;
  text-align: left; font: inherit; color: inherit;
}

.lp-wrap {
  /* 하단 고정 CTA 에 내용이 가리지 않도록 그만큼 비워 둔다.
     ★2026-08-06: 막대 높이를 줄였으므로 96px 을 박아 두면 그만큼이 그냥 빈 칸이 된다 —
     m-landing.js 가 실측해 넣는 --lp-cta-h 를 쓰고, 그 값이 아직 없을 때만 76px 로 어림한다.
     ★2026-08-10: **+18px** — 막대 높이와 정확히 같게 두면 맨 아래까지 내렸을 때 푸터 마지막 줄이
     막대에 **딱 붙는다**(헤드리스 실측: 여유 0px). 옛 화면은 고정 높이 상세 카드가 스크롤 끝을
     대신 잡아 줘서 이 문제가 드러나지 않았다 — 6블록으로 바뀌며 페이지가 통으로 스크롤된다. */
  padding-bottom: calc(var(--lp-cta-h, 76px) + 18px + env(safe-area-inset-bottom));
}

/* ---- 배너 (가로:세로 = 2.25:1) ----
   transform 대신 스크롤 스냅을 쓴다 — 손가락 스와이프가 공짜로 따라온다. */
.lp-banner { margin-bottom: 14px; }
.lp-bn-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  border-radius: 16px;
  background: var(--pale);
}
.lp-bn-track::-webkit-scrollbar { display: none; }
.lp-bn {
  flex: 0 0 100%;
  scroll-snap-align: start;
  display: block;
  aspect-ratio: 2.25 / 1;
}
.lp-bn img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 16px; }
.lp-bn-dots { display: flex; justify-content: center; gap: 6px; margin-top: 8px; }
.lp-bn-dot {
  width: 7px; height: 7px; padding: 0;
  border: 0; border-radius: 50%; background: var(--s300);
  transition: background .15s, width .15s;
}
.lp-bn-dot[aria-selected='true'] { width: 18px; border-radius: 4px; background: var(--main); }
/* 배너가 하나뿐이면 점은 의미가 없다 */
.lp-bn-dots:has(.lp-bn-dot:only-child) { display: none; }

/* ⛔`.lp-feats`·`.lp-feat*`(4대 특징 카드 4장)은 2026-08-08 사용자 지시로 없앴다. */

/* ================= 더 알아보기 페이지 (2026-08-10 재정의) =================
   ⛔ 여기서 통째로 사라진 것 = `.lp-h2` · `.lp-segbar`/`.lp-seg*`(가로 스티키 커리큘럼 탭) ·
      `.lp-track` · `.lp-detail`(고정 높이 상세 카드) · `.lp-det-img`.
      단계 상세는 이제 **세로 사다리를 눌러 커리큘럼 팝업**(.cur-*)이 그린다 — 그래서
      「단계마다 카드 높이가 달라 화면이 튀던」 문제도 그 구조와 함께 없어졌다.
   ⚠️ `.cur-*` 는 팝업이 계속 쓰므로 **지우지 말 것**(위쪽에 그대로 있다). */

/* ---- ① 히어로 + 두 갈래 ---- */
.lp-hero { background: var(--pale); border-radius: 16px; padding: 20px 18px; }
.lp-hero-t1 { font-size: 14px; font-weight: 600; color: var(--s700); }
.lp-hero-t2 {
  margin-top: 2px; font-size: 21px; font-weight: 800; color: var(--s800);
  letter-spacing: -.5px; line-height: 1.35; word-break: keep-all;
}
.lp-hero-t2 b { color: var(--main); }
.lp-hero-sub { margin: 10px 0 0; font-size: 12.5px; color: var(--s600); line-height: 1.65; word-break: keep-all; }
.lp-hero-sub b { color: var(--s800); font-weight: 700; }
/* ⛔`.lp-chips`·`.lp-chip`(히어로 알약 4개)은 2026-08-11 사용자 지시로 없앴다.
   같은 사실(정원·대상)은 ② 블록의 `.lp-stat` 이 이미 말하고 있었다. */

/* 두 갈래 — 이 화면에서 할 수 있는 일은 둘뿐이라는 사실을 최상단에서 못 박는다.
   ★2026-08-11 재설계(사용자 지시) — 가로 2칸 작은 카드 → **세로 개조식 한 줄씩**.
     한 줄이 [번호][아이콘+제목][설명][›] 로 읽히고, 두 줄 다 화면 폭을 꽉 쓴다.
   ⚠️ 두 줄이 **같은 무게**여야 한 쪽이 덜 중요해 보이지 않는다 — 크기·여백은 같게 두고
      차이는 색(개설 쪽만 딥블루 채움)으로만 준다. */
.lp-two { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
/* ⛔2026-08-14(2차) 사용자 지시 — 앞 번호 뱃지를 없애면서 **격자 열도 30px 을 뺐다.**
   비운 42px(뱃지 30 + gap 12)이 그대로 글자 폭이 되어 제목이 한 줄에 들어간다.
   ⚠️ `.lp-way-n` 규칙은 아래에 그대로 남겨 둔다 — 되살릴 때 CSS 를 다시 짜지 않아도 되게. */
.lp-way {
  display: grid; grid-template-columns: 1fr 14px; align-items: center; gap: 12px;
  width: 100%; padding: 16px 16px; text-align: left;
  /* ★2026-09-03 사용자 지시 — 테두리는 **딥블루**다(두 갈래 모두 · 안은 비운다) */
  background: #fff; border: 1.5px solid var(--main); border-radius: 16px;
  transition: transform .12s, border-color .12s, box-shadow .12s;
}
.lp-way:hover { transform: translateY(-2px); border-color: var(--main); box-shadow: 0 6px 18px rgba(43,75,177,.14); }
/* 번호 — 「① 열거나 ② 참여하거나」라는 개조식의 뼈대다 */
.lp-way-n {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--pale); color: var(--main);
  font-size: 14px; font-weight: 800; line-height: 1;
}
.lp-way-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.lp-way-i { font-size: 17px; line-height: 1; }
.lp-way-t {
  display: flex; align-items: center; gap: 7px;
  font-size: 16px; font-weight: 800; color: var(--s800);
  letter-spacing: -.4px; word-break: keep-all;
}
.lp-way-d { font-size: 12px; color: var(--s500); line-height: 1.5; word-break: keep-all; }
.lp-way-go { color: var(--s300); font-size: 20px; font-weight: 700; line-height: 1; text-align: right; }
/* ⛔2026-09-03 사용자 지시 — **두 갈래 다 빈 상자**이고 테두리만 딥블루다.
   그전에는 「개설」 쪽만 딥블루로 채워 강조했는데, 사장님이 「아래 열려있는 클래스 참여하기랑
   동일한 비어있는 컴포넌트로」라고 지시했다. 채우기는 m-landing 의 `hi` 한 줄을 빼서 없앴고,
   아래 `.is-hi` 규칙은 **되살릴 자리로 남겨 둔다**(지금은 붙는 요소가 없다).
   ⚠️ 딥블루 위 흰 글자다(대비비 8.6). 브랜드 옐로를 배경으로 쓰면 흰 글자가 안 보인다. */
.lp-way.is-hi { background: var(--main); border-color: var(--main); }
.lp-way.is-hi:hover { box-shadow: 0 6px 18px rgba(43,75,177,.35); }
.lp-way.is-hi .lp-way-n { background: rgba(255,255,255,.22); color: #fff; }
.lp-way.is-hi .lp-way-t { color: #fff; }
.lp-way.is-hi .lp-way-d { color: rgba(255,255,255,.82); }
.lp-way.is-hi .lp-way-go { color: rgba(255,255,255,.7); }

/* ---- 섹션 공통 ---- */
/* ★2026-08-12 사용자 지시 — 영역 사이 여백을 **2배**(28 → 56px). 블록이 붙어 있어
   어디까지가 한 덩어리인지 안 읽혔다. ⚠️ 첫 섹션은 위 블록(두 갈래·배너)과 이미 떨어져 있다. */
.lp-sec { margin-top: 56px; }
/* 맨 위 섹션은 헤더 바로 아래라 56px 이 과하다 (2026-08-13 순서 변경) */
.lp-sec-first { margin-top: 20px; }
/* ★2026-08-13(2차 지시) — 첫 섹션과 그 아래(히어로) 사이가 **다른 섹션 사이보다 좁아 보였다**.
   히어로는 `.lp-sec` 가 아니라 위 여백을 스스로 갖지 않았기 때문이다 → 섹션 간격(56px)을
   그대로 준다. ⚠️ 값을 두 곳에 적지 않으려면 `.lp-sec` 를 고칠 때 이 줄도 함께 볼 것. */
.lp-hero-mid { margin-top: 56px; }
/* ★수업 흐름 소개 이미지 — 스탯 3칸 아래 (2026-08-13 사용자 지시)
   ★★(6차) 두 가지를 함께 고쳤다:
     ① 스탯 3칸과의 간격을 **70%** 로(14 → 10px) — 둘은 한 덩어리로 읽혀야 한다.
     ② **좌우로 화면 끝까지 넓힌다**(full-bleed). 이 그림은 「수업이 어떻게 흘러가나」를 보여 주는
        것이라 클수록 읽힌다. `.wrap` 의 좌우 패딩 16px 을 음수 마진으로 되찾으면
        **390px 폰에서 358 → 390px(+9%)** 가 된다 — 이 화면에서 폭을 더 얻을 방법은 이것뿐이다.
   ⚠️★★음수 마진은 **`.wrap` 의 좌우 패딩과 같은 값**이어야 한다(16px). 그 값을 바꾸면 여기도
      함께 바꿀 것 — 어긋나면 그림이 화면 밖으로 나가 **가로 스크롤이 생긴다**.
   ⚠️ 화면 끝에 닿으므로 **모서리 반경을 없앤다** — 둥근 모서리가 화면 가장자리에서 잘려 보인다.
   ⚠️ 넓은 화면(≥460px)에서는 `.wrap` 이 460px 로 가운데 서므로, 이 그림도 그 칸 + 32px 까지만
      넓어진다(화면을 뚫지 않는다). */
/* ⚠️ 스탯 3칸(`.lp-stats`)과 이 이미지 사이의 간격은 **이 margin-top 하나**가 정한다
   (형제 사이라 위쪽 요소의 margin-bottom 과 상쇄되는데 `.lp-stats` 는 0이다).
   2026-08-14(2차) 사용자 지시로 10px → **7px**(70%)로 줄였다. */
.lp-intro-img {
  display: block; height: auto; margin-top: 7px;
  width: calc(100% + 32px); margin-left: -16px; margin-right: -16px;
  border-radius: 0;
}
/* ★★2026-08-12 사용자 지시 — 섹션 제목 앞에 **공통 표식**을 붙여 「여기서 한 덩어리가 시작된다」를
   보이게 한다. 이모지를 넷 다 같은 것으로 두면 장식만 되므로, **브랜드 딥블루 세로 막대**로 뒀다.
   ⚠️ 마크업이 아니라 `::before` 다 — 제목을 새로 추가해도 **자동으로 붙는다**(넣는 걸 잊을 수 없다).
   ⚠️★★**flex 로 만들지 말 것.** 처음에 `display:flex; gap:9px` 로 했다가, 제목 안의
      `<b class="lp-brand">우.아.금</b>` 이 **별개의 flex 항목**이 되면서 그 gap 이
      **낱말 사이에 끼어** 「우.아.금 은 이런 곳이에요」로 벌어졌다(헤드리스 캡처로 잡았다).
      → 흐름은 그대로 두고 **막대만 절대배치**한다. 그러면 제목이 두 줄이 돼도 막대는 첫 줄에 선다. */
.lp-sec-t { position: relative; margin: 0; padding-left: 13px;
  font-size: 18px; font-weight: 800; color: var(--s800); letter-spacing: -.4px; word-break: keep-all; }
.lp-sec-t::before {
  content: ''; position: absolute; left: 0; top: 4px; width: 4px; height: 18px;
  border-radius: 2px; background: var(--main);
}
/* 제목 안의 브랜드 이름만 딥블루 (2026-08-11 사용자 지시). ⚠️ `.lp-sec-t b` 로 잡지 말 것 —
   다른 섹션 제목이 굵게 강조할 낱말이 생기면 그것까지 파래진다. */
.lp-sec-t .lp-brand { color: var(--main); }
/* ★2026-08-12 사용자 지시 — 섹션 설명 줄을 키우되 **제목보다는 작게**.
   경위: 처음에 「1.5배」 지시대로 18.75px 로 했더니 **제목(.lp-sec-t 18px)보다 커져서**
   섹션을 여는 말과 그 설명의 위아래가 뒤집혔다 → 사용자가 다시 낮추라고 지시.
   지금 = **15px**(옛 12.5px 보다는 크고, 제목 18px 보다는 확실히 작다).
   ⚠️★★**언제나 `.lp-sec-t` 보다 작아야 한다.** 제목을 키우거나 여기를 키울 때 **둘을 같이 볼 것**
      (검사가 「제목 > 설명」을 숫자로 비교한다 — 숫자를 박은 검사가 아니라 관계를 본다).
   ⚠️ 이 클래스는 「우.아.금은 이런 곳이에요」 아래와 「한 번 배우고 끝나지 않아요」 아래
      **둘 다** 쓴다 — 같은 역할이라 한쪽만 바꿀 수 없다. */
.lp-sec-d { margin: 8px 0 0; font-size: 15px; color: var(--s600); line-height: 1.6; word-break: keep-all; }
.lp-sec-d b { color: var(--s800); font-weight: 700; }
/* ⛔0811 의 「설명문 낱말 = 서브 파랑 + 밑줄」은 2026-08-12 사용자 지시로 **없앴다**
   (링크처럼 보였다). 마크업의 `<u>` 도 함께 지웠으니 이 자리에 규칙을 되살리지 말 것. */
.lp-sec-foot { margin: 12px 0 0; font-size: 12.5px; color: var(--s500); line-height: 1.6; word-break: keep-all; }
.lp-sec-foot b { color: var(--main); font-weight: 700; }
/* 안내 줄 — ★2026-08-12 부터 **밖으로 나가지 않는다**(블로그 → #modal-howto 팝업).
   `<a>` 에서 `<button>` 이 됐으므로 버튼 기본 테두리를 지우고 폭을 100% 로 편다. */
.lp-link {
  border: 0; width: 100%; text-align: left;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 12px; padding: 12px 14px; min-height: var(--tap);
  background: var(--pale); border-radius: 12px;
  color: var(--main); font-size: 13px; font-weight: 800; text-decoration: none;
  word-break: keep-all;
}
.lp-link:hover { background: #dfeaf8; }
/* 「누를 수 있다」를 알리는 한 줄 — 모르면 팝업은 없는 기능이나 마찬가지다 */
.lp-tip {
  margin-top: 10px; border-radius: 10px; padding: 8px 11px;
  background: #fff8e1; color: #8a6100; font-size: 11.5px; font-weight: 700;
  word-break: keep-all;
}

/* ---- ② 회사·콘텐츠 ---- */
.lp-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 14px; }
.lp-stat {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 4px; background: #fff; border: 1px solid var(--s200); border-radius: 12px;
}
/* ⚠️ 「55~65분」은 「8종」보다 글자가 길다 — 셋을 같은 크기로 두면 좁은 폰에서 그것만 넘친다.
      숫자 줄은 폭에 따라 줄어드는 clamp 로 잡고, 넘칠 때는 낱말째 접는다. */
.lp-stat b { font-size: clamp(14px, 4.4vw, 17px); font-weight: 800; color: var(--main); white-space: nowrap; }
.lp-stat span { font-size: 11.5px; color: var(--s500); text-align: center; word-break: keep-all; }
/* 첫 칸만 눌러서 게임 소개 팝업을 연다 (2026-08-11).
   ⚠️ 모양은 옆 두 칸과 **같아야** 한다 — 크기가 달라지면 셋이 한 줄로 안 읽힌다.
      「누를 수 있다」는 테두리 색과 아래 「보기 ›」 한 조각으로만 알린다. */
.lp-stat-btn { border-color: var(--sub); cursor: pointer; }
.lp-stat-btn:hover { background: var(--pale); border-color: var(--main); }
/* 「보기 ›」 — ★2026-08-12 사용자 지시로 **줄을 바꿔 아래에 두고 글자를 두 배**로 키웠다
   (설명 뒤에 조그맣게 붙어 있어서 「누를 수 있다」가 안 보였다).
   ⚠️ `display:block` 이라야 줄이 바뀐다 — `<i>` 는 기본이 inline 이다. */
/* ★2026-08-12 사용자 지시 — 21px 은 그 칸의 숫자(clamp 최대 17px)보다 커서 혼자 튀었다.
   **아래 설명(11.5px)과 숫자 사이**로 낮추고, 색을 **서브 파랑**으로.
   ⚠️★★대비비를 재 두면 = `--sub`(#83acdd) on #fff = **2.36:1** 로 WCAG AA(4.5) 미달이다.
      「눌러야 한다」는 신호가 흐려질 수 있다는 뜻이라, 안 보이면 `--main`(8.6:1)이나
      진한 파랑으로 되돌릴 것. 지금은 **사용자 지시대로** 서브 파랑을 쓴다. */
.lp-stat-more { display: block; margin: 3px 0 0; font-style: normal; font-size: 13px; font-weight: 800; color: var(--sub); line-height: 1.25; }

/* ⛔`.lp-games`·`.lp-game`(아이콘+이름 격자 8칸)은 2026-08-11 사용자 지시로 사라졌다.
   그 내용은 **눌러서 여는 팝업**(`#modal-games` · `.gm-*`)으로 옮겼다 — 이름만 늘어놓아서는
   무엇을 배우는 게임인지 말하지 못했고, 한 줄 소개를 붙일 자리도 없었다. */

/* ---- 보드게임 소개 팝업 (2026-08-11 신설) ----
   ⚠️ 이름은 `gm-` 접두사다 — app.css 는 네 페이지가 공유하므로 흔한 이름을 새로 만들면
      다른 화면이 조용히 눌린다(0731 `.cal-nav` 사고). */
.gm-lead { margin: 0 0 12px; font-size: 12.5px; color: var(--s600); line-height: 1.6; word-break: keep-all; }
.gm-list { display: flex; flex-direction: column; gap: 8px; }
.gm-row {
  display: grid; grid-template-columns: 34px 1fr; align-items: center; gap: 10px;
  padding: 10px 12px; background: var(--s50); border-radius: 12px;
}
.gm-i { font-size: 24px; font-style: normal; line-height: 1; text-align: center; }
.gm-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gm-txt b { font-size: 13.5px; font-weight: 800; color: var(--s800); }
.gm-txt span { font-size: 12.5px; color: var(--s500); line-height: 1.55; word-break: keep-all; }

/* ---- 클래스 신청하는 방법 팝업 (2026-08-12 신설 · 같은 날 이미지형으로 개편) ----
   ★★사용자 지시로 **내용이 어드민이 올린 이미지 한 벌**이 됐다 → 남는 CSS 는 두 줄뿐이다.
   ⛔사라진 것 = .hw-lead · .hw-seg* · .hw-when* · .hw-step* · .hw-note (글로 쓰던 안내 44줄)
     + #modal-howto .modal-foot 의 2칸 격자(바닥 버튼이 「확인」 하나가 됐다 → .cur-modal 규칙).
   ★전체 화면 처방은 **커리큘럼 팝업과 함께** 잡는다(위 @media 블록) — 같은 UI 라는 지시라,
     한쪽만 고치면 두 팝업이 서로 다르게 열린다.
   ⚠️ 낱장 <img> 는 .lp-det-img 를 그대로 쓴다(커리큘럼 상세와 같은 그림 규칙). */
.hw-imgs { background: var(--s50); border-radius: 10px; overflow: hidden; }

/* ★★2026-08-15(6차) 사용자 지시 — **갈래 탭을 제목과 한 덩어리로 상단에 붙박는다.**
   안내물이 세로로 긴 이미지 여러 장이라, 내려 읽는 동안 탭이 화면 밖으로 나가 있었다 —
   「지금 어느 쪽을 보는지」와 「반대쪽으로 가는 길」이 **동시에** 사라진다.
   ★★얼개 = **탭을 `.modal-head` 안으로 옮겼다**(마크업이 그렇게 돼 있다). 붙박이를 **하나**로
     두려는 것이다 — 탭만 따로 `position: sticky` 로 만들면 `top` 에 **머리 높이**를 줘야 하는데
     그 높이는 노치(`env(safe-area-inset-top)`)·글꼴에 따라 달라져 **숫자로 박으면 늙는다.**
   ⚠️ 그래서 `#hw-track` 에는 `position: sticky` 가 **없다** — 머리가 붙박이라 딸려 간다.
   ⚠️ 두 화면 모두 따로 할 일이 없다: ≤560px 는 `.modal-head` 가 이미 sticky 이고(전체화면 여섯 규칙
      한 벌), 561px~ 는 `.modal-body` 만 스크롤하고 머리는 상자 위에 그대로 고정이다.
   ⚠️ `.modal-head` 는 원래 **가로 flex**(제목 ↔ ×)다 → 여기서만 세로로 풀고, 그 한 줄을
      `.hw-head-row` 가 대신 맡는다. ⛔`.modal-head` 자체를 고치지 말 것(팝업 전부가 흔들린다). */
#modal-howto .modal-head { display: block; }
#modal-howto .hw-head-row { display: flex; align-items: center; justify-content: space-between; }
/* 제목과 탭 사이 숨통 — ★2026-08-15(7차) 사용자 지시로 **10 → 20px**(두 배).
   ⚠️ 아래 간격은 `.modal-head` 의 padding 이 이미 갖고 있다(더 주지 말 것). */
#modal-howto #hw-track { margin-top: 20px; }

/* ---- 수강료 팝업의 가로 넘김 (2026-08-15 2차 사용자 지시) ----
   ★배너(`.lp-bn-track`)와 **같은 처방**이다 = 스크롤 스냅. 손가락 스와이프가 공짜로 따라온다.
   ⛔transform 으로 옮기는 방식으로 바꾸지 말 것 — 그 순간 스와이프를 직접 만들어야 한다.
   ⛔★★**‹ › 버튼(`.tu-wrap`/`.tu-nav`/`.tu-prev`/`.tu-next`)은 3차에 통째로 없앴다**(사용자 지시)
      — 그림 위에 얹혀 가격표 글자를 가렸고, 아래 점이 이미 「몇 장인지」를 말한다. 되살리지 말 것.
   ⚠️ `overscroll-behavior-x: contain` 이 없으면 끝 장에서 한 번 더 밀 때 **브라우저 뒤로가기**가
      먹는다(iOS·안드로이드 가장자리 제스처). 이 팝업은 히스토리 한 겹이라 증상이 더 나쁘다. */
.tu-track {
  display: flex;
  /* ⚠️ `stretch`(기본)면 짧은 장이 가장 긴 장 높이로 늘어나며 그림이 찌그러진다 */
  align-items: flex-start;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  background: var(--s50); border-radius: 10px;
}
.tu-track::-webkit-scrollbar { display: none; }
/* ⚠️ `min-width: 0` 이 없으면 flex 항목이 내용 폭만큼 부풀어 한 화면에 두 장이 걸친다 */
.tu-slide { flex: 0 0 100%; min-width: 0; scroll-snap-align: start; }
.tu-slide img { display: block; width: 100%; height: auto; }

/* ‹ › — 지시는 「창 좌측과 우측」이다. 전체화면 팝업에서 트랙이 곧 화면 폭이라 그 두 자리가 같다.
   ⚠️ 세로 기준은 **트랙의 가운데**다(화면 가운데가 아니다) — 아주 긴 그림을 올리면 버튼이
      그림 한가운데에 앉으므로 내려야 닿는다. 지금 쓰는 가격표는 정사각형이라 화면 가운데다.
   ⚠️ 반투명 흰 원 + 그림자 = 어떤 그림 위에 얹혀도 보이게 하려는 것이다(그림 색을 우리가 못 정한다). */
/* ★★2026-08-15(3차) 사용자 지시 — ‹ › 를 없앤 만큼 **그림을 창 끝까지 넓힌다.**
   전체화면(≤560px)에서는 팝업 본문의 **좌우 패딩을 0** 으로 만들어 그림이 화면 폭을 그대로 쓴다
   (390px 폰 기준 362 → **390px**). 그러면 트랙 모서리가 화면 가장자리에 닿으므로 **둥글리지 않는다.**
   ⚠️ 좌우만 0 이다 — 아래 패딩은 위 묶음 규칙(30px)이 준 그대로 둔다(점·「확인」과 붙지 않게).
   ⚠️ 점은 본문 안에 있으므로 가운데 정렬이라 패딩 0 이어도 자리가 안 흔들린다. */
@media (max-width: 560px) {
  #modal-tuition .modal-body { padding-left: 0; padding-right: 0; }
  #modal-tuition .tu-track { border-radius: 0; }
}
/* 넓은 화면은 상자(400px)라 끝까지 붙이면 둥근 모서리 밖으로 삐져나온다 —
   대신 좌우 패딩만 18 → 10px 로 줄여 그만큼 넓게 본다. */
@media (min-width: 561px) {
  #modal-tuition .modal-body { padding-left: 10px; padding-right: 10px; }
}

/* 점 — 배너와 같은 모양을 일부러 쓴다(같은 뜻의 부품이 화면마다 다르면 안 된다).
   ★★‹ › 를 없앤 뒤로 **여기가 「몇 장인지」를 말하는 유일한 자리**다 — 지우지 말 것.
   ⚠️ 눌러서도 넘어간다(m-app 이 `scrollTo` 를 건다) — 넘기는 길이 스와이프 하나만 남지 않게. */
.tu-dots { display: flex; justify-content: center; gap: 6px; margin-top: 10px; }
.tu-dot {
  width: 7px; height: 7px; padding: 0;
  border: 0; border-radius: 50%; background: var(--s300);
  transition: background .15s, width .15s;
}
.tu-dot[aria-selected='true'] { width: 18px; border-radius: 4px; background: var(--main); }
/* 아직 안 올렸을 때 — 빈 상자 대신 한 줄로 말해 준다 */
.hw-empty {
  padding: 40px 16px; border-radius: 10px; background: var(--s50);
  color: var(--s500); font-size: 13px; font-weight: 600; text-align: center; word-break: keep-all;
}

/* ---- ③ 어떻게 열리나 ---- */
.lp-steps { margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.lp-step { display: flex; gap: 10px; align-items: flex-start; }
.lp-step-n {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--main); color: #fff; font-size: 12px; font-weight: 800;
}
.lp-step-txt { min-width: 0; }
.lp-step-t { font-size: 13.5px; font-weight: 800; color: var(--s800); word-break: keep-all; }
.lp-step-d { margin-top: 3px; font-size: 12.5px; color: var(--s500); line-height: 1.6; word-break: keep-all; }

/* ---- ④ 커리큘럼 세로 사다리 ----
   ★가로 탭이었을 때는 6개가 나란히 놓인 **선택지**처럼 보였다. 실제 구조는 **순서**다 —
   세로로 세우고 자물쇠를 붙이면 그 규칙이 그림 하나로 설명된다.
   ⚠️ 격자 4칸 = [뱃지] [이름·설명] [자물쇠] [›]. 가운데만 `min-width:0` 이라야 긴 이름에서
      자물쇠가 밖으로 밀려나지 않는다. */
.lp-ladder { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.lp-rung {
  display: grid; grid-template-columns: 30px 1fr auto 12px;
  align-items: center; gap: 9px;
  width: 100%; min-height: 56px; padding: 9px 11px; text-align: left;
  background: #fff; border: 1px solid var(--s200); border-radius: 12px;
  transition: border-color .12s, box-shadow .12s;
}
.lp-rung:hover { border-color: var(--s300); box-shadow: 0 3px 10px rgba(0,0,0,.06); }
.lp-rung-i { font-size: 21px; line-height: 1; text-align: center; }
.lp-rung-txt { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.lp-rung-n { font-size: 13px; font-weight: 800; color: var(--s800); letter-spacing: -.2px; }
.lp-rung-d { font-size: 12px; color: var(--s500); line-height: 1.45; word-break: keep-all; }
.lp-rung-lock {
  border-radius: 999px; padding: 3px 8px;
  background: var(--s100); color: var(--s500);
  font-size: 10px; font-weight: 700; white-space: nowrap;
}
.lp-rung-lock.is-open { background: var(--pale); color: var(--main); }
/* ★★2026-09-03 사용자 지시로 **뱃지가 없는 칸이 생겼다**(BEGINNER·STARTER 둘만 단다).
   그 줄은 알약이 빠져 화살표가 3번 칸으로 미끄러지고, 그러면 화살표 자리가 줄마다 21px 씩
   어긋난다 → **4번 칸에 못박는다**(빈 3번 칸은 폭 0으로 접힌다). */
.lp-rung-caret { grid-column: 4; color: var(--s300); font-size: 17px; line-height: 1; text-align: right; }
/* ⛔2026-08-12: BEGINNER·MONEY MARBLE 만 테두리 색이 달랐던 것을 **없앴다**(사용자 지시).
   일곱 칸이 한 목록이므로 테두리도 같아야 한다 — 구분은 뱃지와 자물쇠 알약이 이미 하고 있다.
   ⚠️ `.is-first`·`.is-last` 클래스 자체는 m-landing 이 계속 붙인다(다시 색을 줄 자리). */

/* ---- ⑤ 신뢰 ----
   ★후기가 아직 없다. 없는 숫자를 지어내지 않고 **이미 사실인 것 네 개**로 채운다. */
.lp-trust { margin-top: 12px; display: flex; flex-direction: column; gap: 2px; }
.lp-trust-row {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 11px 0; border-bottom: 1px solid var(--s100);
}
.lp-trust-row:last-child { border-bottom: 0; }
/* ★2026-08-13 사용자 지시 — 번호 동그라미와 두 줄을 **한 단계씩 키운다**.
   ⚠️ 「레벨에 따라 크기가 조금 다른 형태는 유지」가 지시의 절반이다 → 제목 > 설명의 차이를
      그대로 두고 셋을 같은 비율로 올렸다: 번호 20→26px(글자 11→13) · 제목 13→15.5 · 설명 12.5→14. */
.lp-trust-i {
  flex: none; width: 26px; height: 26px; margin-top: 1px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--pale); color: var(--main); font-size: 13px; font-weight: 800;
}
.lp-trust-txt { min-width: 0; }
.lp-trust-t { font-size: 15.5px; font-weight: 700; color: var(--s800); word-break: keep-all; }
.lp-trust-d { margin-top: 4px; font-size: 14px; color: var(--s500); line-height: 1.6; word-break: keep-all; }

/* ---- ⑥ 푸터 ---- */
#lp-foot { margin-top: 22px; }

/* ⛔2026-08-10 삭제 — 옛 랜딩의 **가로 스티키 커리큘럼 탭**(.lp-segbar/.lp-seg*)과
   **학년대 토글**(.lp-track) · **고정 높이 상세 카드**(.lp-detail/.lp-det-img) 132줄.
   더 알아보기 페이지가 6블록으로 바뀌면서 단계 상세는 **세로 사다리 → 커리큘럼 팝업**이 맡는다.
   ⚠️ 되살릴 일이 생기면 git 에 있다(0808 시점). --lp-segbar-h 실측도 함께 사라졌다. */

/* ---- 하단 고정 CTA ----
   ★2026-08-05: **왼쪽은 플로팅 버튼(결제·문의) 자리로 비운다**(사용자 지시) —
   버튼 2개(44px×2 + 사이 10px) + 좌우 여백. 그만큼 CTA 버튼은 좁아지고 오른쪽으로 붙는다.
   ⚠️ 이 폭을 바꾸면 아래 `body.on-landing .fab-stack` 의 left 도 함께 봐야 한다.

   ★2026-08-06: 막대가 화면을 너무 먹어 정작 상세 이미지가 안 보인다는 지적 → **높이를 70% 로**.
   줄인 곳 = 위아래 여백 10→8 · 버튼 50→42 · 안내 문구를 **한 줄**로(11→10px 대) ·
   랜딩에서만 플로팅 버튼 56→44. 대략 107px → 75px 다.
   ⚠️ 실제 높이는 m-landing.js 가 재서 --lp-cta-h 로 넣는다 — 여기 숫자는 그 결과일 뿐 근거가 아니다. */
.lp-cta {
  position: fixed; left: 0; right: 0;
  bottom: 0; z-index: 55;
  /* ★2026-08-06(2차): 안내문구를 요청 탭으로 옮겨 **버튼 한 줄만** 남았다 →
     위아래 여백을 12/8 로 두어 버튼을 살짝 아래로 앉히고 막대는 더 얇아졌다(76px → 62px).
     ⚠️ 위가 아래보다 큰 것은 의도다 — 문구가 있던 자리를 버튼이 아래로 내려가 메운다. */
  padding: 12px 16px calc(8px + env(safe-area-inset-bottom));
  /* 왼쪽은 플로팅 버튼 자리 = 16(여백) + 44 + 10(사이) + 44 + 8(숨통) */
  padding-left: 122px;
  background: rgba(255,255,255,.96);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--s200);
}
/* ★버튼 색 = 브랜드 옐로 (2026-08-06 사용자 지시).
   ⚠️ 옐로 위 **흰 글자는 대비비 1.44** 라 안 보인다 → 글자는 딥블루(--main)다(대비비 5.32, AA 통과).
   ⚠️ .btn-main:not(:disabled):hover 가 특이도에서 이기므로 hover 도 여기서 다시 덮어야 한다. */
.lp-go {
  display: block;
  /* ★폭 (2026-08-06 2차) — 안내문구가 사라져 기준이 없어졌으므로 **직전 폭을 그대로 옮겨 적고
     좌우 5%씩(=합 10%) 넓혔다**(사용자 지시).
     직전 폭 = 문구의 max-content = 18.16 × 문구 글자크기(clamp(9.5px, 2.7vw, 10.5px))
             → 320px:172.5 / 360px:176.5 / 390px 이상:190.7 (CDP 실측)
     ×1.1 → 계수 19.98 → clamp(190px, 53.9vw, 210px).
     ⚠️ `max-width` 로 거는 이유 = 320px 처럼 자리가 그보다 좁으면 `width:100%` 가 이겨
        막대 밖으로 안 삐져나간다(`width` 로 박으면 넘친다). */
  width: 100%;
  max-width: clamp(190px, 53.9vw, 210px);
  margin: 0 auto;
  min-height: 42px; font-size: 14px;
  background: var(--accent); color: var(--main);
}
.lp-go:not(:disabled):hover,
.lp-go:not(:disabled):focus-visible { background: #f2c02f; color: var(--main); }
/* ⛔`.lp-cta-sub` 는 2026-08-06(2차)에 사라졌다 — 그 문구는 클래스 요청 탭의
   개설 버튼 아래(`.submit-fee`)로 옮겼다. 하단 막대에는 버튼 하나만 남는다. */

/* ★2026-08-05: 랜딩에서는 플로팅 버튼이 **하단 막대 안 왼쪽**에 앉는다 (사용자 지시).
   예전에는 막대 **위로** 올려 두었는데(0803), 그러면 상세 이미지를 가린다.
   ⚠️ --lp-cta-h 는 m-landing.js 가 막대를 **실측**해 넣는다 — 문구가 두 줄이 되면 막대가
      두꺼워지고 이 식이 알아서 따라간다(픽셀을 박으면 그 순간 어긋난다).
   ⚠️ 44px 은 **랜딩에서의** `.fab` 지름이다(아래 참조). 그 값을 바꾸면 여기도 함께 고칠 것. */
body.on-landing .fab-stack {
  left: 16px; right: auto;
  bottom: calc((var(--lp-cta-h, 76px) - 44px) / 2);
}
/* ★2026-08-06: 랜딩에서만 플로팅 버튼을 56 → 44px 로 줄인다 (사용자 지시).
   막대 높이를 70% 로 줄이는데 버튼이 56px 그대로면 버튼이 막대보다 커져 위아래로 삐져나온다.
   ⚠️ **랜딩에서만** 이다 — 목록·신청 화면의 버튼 크기는 그대로 둔다(`body.on-landing` 한정).
   ⚠️ svg 는 width/height **속성**이 26 으로 박혀 있어 CSS 로 덮어야 줄어든다. */
body.on-landing .fab { width: 44px; height: 44px; gap: 0; }
body.on-landing .fab svg { width: 20px; height: 20px; margin-top: 1px; }
body.on-landing .fab-label { font-size: 9px; }
body.on-landing .fab-badge {
  min-width: 17px; height: 17px; padding: 0 4px;
  font-size: 10px; line-height: 17px;
}

/* ⛔ `@media (min-width:560px) { .lp-segbar … }` 는 2026-08-10 에 함께 사라졌다
   (그 스티키 탭이 `.wrap` 패딩 밖으로 나가 있어 넓은 화면에서 되돌리던 규칙이었다). */
