/*
 * 통학버스 — 화면 공용 스타일
 *
 * ⚠️ 색은 `veh-tokens.css` 의 토큰만 쓴다. 여기에 색을 직접 쓰면 어두운
 *    화면에서 그 부분만 안 바뀌어 글자가 배경에 묻는다.
 * ⚠️ **폰이 기준이다.** 학원장이 앱 안에서 설정을 한다 — 손가락으로.
 *    누르는 것은 전부 최소 44px 로 둔다.
 */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  min-height: 100%;
  background: var(--paper); color: var(--ink);
  font-family: 'Gothic A1', -apple-system, BlinkMacSystemFont,
               'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
  font-size: var(--t-base); line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  padding-bottom: env(safe-area-inset-bottom);

  /* ⚠️⚠️ **한글은 `keep-all` 이 없으면 낱말 한가운데서 잘린다.**
     기본값(`normal`)은 한글을 글자 단위로 끊어도 된다고 보기 때문에
     "학원장님이 설정에서 바꿉/니다" 처럼 뚝 끊긴다. 영문은 원래 낱말
     단위로만 끊기므로 이 문제가 없어서 놓치기 쉽다.
     `keep-all` 이면 **띄어쓰기에서만** 줄이 바뀐다 — 문구를 하나씩
     줄이는 것보다 이 한 줄이 훨씬 넓게 듣는다.
     ⚠️ 짝으로 `overflow-wrap: anywhere` 가 필요하다. 안 그러면 띄어쓰기
        없는 긴 것(주소·토큰·아이디)이 칸을 뚫고 나가 **가로 스크롤**이
        생긴다 — keep-all 이 그것마저 안 끊기 때문이다. */
  word-break: keep-all;
  overflow-wrap: anywhere;
}

/* ⚠️ 여러 줄로 넘어가는 글은 **끝줄에 두세 글자만 남지 않게** 한다.
   `pretty` 는 브라우저가 줄을 나눌 때 고아 줄을 피하도록 하는 것이다.
   모르는 브라우저는 그냥 무시하므로 안전하다. */
p, li, .hint, .note, .ask-s, .card p { text-wrap: pretty; }
.num { font-variant-numeric: tabular-nums; }

/* ── 껍데기 ─────────────────────────────────────────────────── */
.wrap { max-width: 520px; margin: 0 auto; padding: 0 18px 40px; }
.top {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 10px;
  padding: calc(12px + env(safe-area-inset-top)) 18px 12px;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.top h1 { font-size: var(--t-lg); font-weight: 800; letter-spacing: -.02em; flex: 1; min-width: 0;
          white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.top .back { flex: none; width: 34px; height: 34px; border-radius: var(--r-sm); border: 0;
             background: var(--raise); color: var(--ink2); font-size: var(--t-lg); cursor: pointer; }

/* ⚠️ 섹션 제목은 **작고 진한 라벨**이다. 크고 흐린 회색으로 두면 제목인지
   본문인지 알 수 없고, 화면이 그만큼 길어진다(밀도가 낮으면 '빈 화면에
   카드 몇 개' 로 보인다 — 그게 생성된 화면의 느낌이다). */
h2 { font-size: var(--t-sm); font-weight: 800; color: var(--ink2);
     letter-spacing: .02em; margin: var(--s5) 0 var(--s2); }
h2:first-of-type { margin-top: var(--s3); }

/* ── 카드 ───────────────────────────────────────────────────── */
/* ⚠️ 지면에 **붙어 있는** 것은 테두리만, 지도 위에 **떠 있는** 것은 그림자만.
      1px 테두리와 넓은 그림자를 같이 쓰면 '생성된 화면' 티가 난다. */
/* ⚠️ 붙어 있는 것은 **테두리만**, 떠 있는 것은 **그림자만**. 둘을 같이 쓰면
   '생성된 화면' 티가 난다(토큰 파일의 그림자 설명 참고). */
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 14px var(--s4); margin-bottom: var(--s3);
}
.card + .card { margin-top: 12px; }
.card p { font-size: var(--t-md); color: var(--ink3); line-height: 1.7; }
.card p + .btn, .card p + .row { margin-top: 12px; }

/* ── 입력 ───────────────────────────────────────────────────── */
label { display: block; font-size: var(--t-sm); font-weight: 700; color: var(--ink3); margin-bottom: 6px; }
/*
 * ⚠️⚠️ **입력칸 글자는 `--t-lg`(17px)여야 한다. `--t-base`(15px)로 내리지 말 것.**
 *    아이폰 사파리는 **16px 미만인 칸에 손을 대면 화면을 통째로 확대한다.**
 *    그게 거슬려서 예전에는 `map.html` 의 viewport 에 `user-scalable=no` 를
 *    걸어 확대를 **아예 막아** 두었다 — 그러면 눈이 어두운 학원장·학부모가
 *    잔글씨를 키워 볼 방법이 없어진다(WCAG 1.4.4 위반).
 *    칸을 16px 위로 올리면 자동 확대가 안 일어나므로 **확대를 막을 이유가
 *    사라진다.** 원인을 고치는 쪽이다.
 * ⚠️ 새 크기를 만들지 않는다 — 여덟 단계 중 `--t-lg` 를 쓴다.
 *    자기가 친 글자가 라벨보다 큰 것은 원래 읽기 좋은 모양이기도 하다.
 */
input[type=text], input[type=email], input[type=password], input[type=time], input[type=number], select {
  width: 100%; min-height: 46px; padding: 11px 13px;
  border: 1.5px solid var(--line2); border-radius: var(--r-sm);
  background: var(--card); color: var(--ink);
  font: inherit; font-size: var(--t-lg);
}
/* ⚠️⚠️ **`outline: none` 을 여기에 다시 쓰지 말 것.** 아래 `:focus-visible`
   규칙이 `:where()` 로 감싸여 있어 **특정도가 0** 인데, `input:focus` 는
   요소+가상클래스라 그걸 이긴다 — 그래서 키보드로 입력칸에 갔을 때
   **테두리가 통째로 사라졌다**(실측: `:focus-visible` 은 걸리는데
   `outline-style: none`). 마우스로 눌렀을 때만 지운다. */
input:focus:not(:focus-visible), select:focus:not(:focus-visible) { outline: none; }
input:focus, select:focus { border-color: var(--amber-b); }
input::placeholder { color: var(--ink3); }
.field + .field { margin-top: 12px; }
.row { display: flex; gap: 8px; align-items: center; }
.row > * { min-width: 0; }
.row.wrap2 { flex-wrap: wrap; }

/* ── 키보드로 쓸 때 지금 어디인지 ──────────────────────────────
   ⚠️⚠️ **여기에 포커스 표시가 통째로 없었다.** `map.html` 에만 있어서,
      로그인·설치·약관 화면을 키보드(또는 폰의 외장 키보드·스위치)로 쓰면
      **지금 어디에 있는지 전혀 보이지 않았다**(WCAG 2.4.7).
   ⚠️ `:focus` 가 아니라 `:focus-visible` 이다 — 마우스로 눌렀을 때까지
      테두리가 남으면 지저분하다.
   ⚠️ 색은 **먹색**이다(종이 위 16.46:1). 황색은 3.62:1 이라 기준(3:1)은
      넘지만 밝은 배경에서 흐릿하고, 무엇보다 **황색은 버스 전용**이다.
   ⚠️ `outline` 을 지우고 그림자만 쓰지 말 것 — 고대비 모드에서 그림자는
      통째로 사라진다. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
/* 어두운 바탕의 주된 단추 위에서는 먹색이 안 보인다 — 종이색으로 뒤집는다. */
.btn.pri:focus-visible { outline-color: var(--paper); outline-offset: -4px; }

/* ── 단추 ───────────────────────────────────────────────────── */
/* ⚠️ 누를 수 있는 것에는 `touch-action: manipulation` 을 준다. 없으면 브라우저가
   **더블탭 확대인지 기다렸다가** 반응해서 한 박자 늦게 눌린다. */
button, .btn, .timebtn, summary, a { touch-action: manipulation; }
button, .btn, .timebtn { -webkit-tap-highlight-color: transparent; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 46px; padding: 12px 16px; border-radius: var(--r-sm);
  border: 1.5px solid var(--line2); background: var(--card); color: var(--ink);
  font: inherit; font-size: var(--t-base); font-weight: 700; cursor: pointer;
  /* ⚠️ **`<a class="btn">` 은 밑줄이 그어진다.** `.btn` 은 `<button>` 을 두고
     만든 규칙이라 밑줄을 끌 이유가 없었는데, 링크에 씌우면 브라우저 기본
     밑줄이 그대로 남는다 — 단추처럼 생긴 것에 밑줄이 있으면 어중간해 보인다.
     [앱 내려받기 (APK)]·[이 코드로 합류하기] 가 그 상태였다. */
  text-decoration: none;
  /* ⚠️⚠️ **누르는 순간은 전환을 두지 않는다**(`0s`). 손가락이 닿았는데 8ms든
     80ms든 늦게 반응하면 그게 '딱딱하고 느린 느낌' 이다. 대신 **뗄 때만**
     부드럽게 돌아온다(`.16s`) — 그래야 딸깍이지 않는다. */
  transition: transform .16s ease-out, filter .16s, background-color .16s, border-color .16s;
}
.btn:active {
  transform: scale(.97);
  transition-duration: 0s;      /* 눌림은 즉시 */
}
@media (prefers-reduced-motion: reduce) {
  .btn, .btn:active { transition: none; transform: none; }
}
.btn.pri { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn.wide { width: 100%; }
.btn.sm { min-height: 38px; padding: 8px 12px; font-size: var(--t-md); border-radius: var(--r-sm); }
/* ⚠️⚠️ **위험한 동작을 주된 동작과 같은 크기로 두지 말 것.** [로그아웃] 이
   [학원 만들기] 와 같은 무게이면 눈이 둘을 같은 것으로 읽는다. 테두리를
   빼고 글자만 남긴다 — 찾을 수는 있되 먼저 눈에 띄지는 않게. */
.btn.danger { color: var(--stop); border-color: color-mix(in srgb, var(--stop) 40%, transparent); }
.btn.quiet {
  border-color: transparent; background: none; color: var(--ink3);
  font-weight: 600; min-height: 40px;
}
.btn.quiet:hover { color: var(--ink2); }
.btn:disabled { opacity: .45; cursor: default; }

.linkbtn { background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
           color: var(--ink3); text-decoration: underline; text-underline-offset: 3px; }

/* ── 알림 ───────────────────────────────────────────────────── */
.note { font-size: var(--t-sm); line-height: 1.7; color: var(--ink3); margin-top: 10px; }
.note b { color: var(--ink2); font-weight: 700; }
.warn {
  font-size: var(--t-sm); line-height: 1.7; padding: 11px 13px; border-radius: var(--r-md);
  background: var(--warn-s); color: var(--warn); font-weight: 600; margin-top: 12px;
}
.err {
  font-size: var(--t-md); line-height: 1.6; padding: 11px 13px; border-radius: var(--r-md);
  background: var(--stop-s); color: var(--stop); font-weight: 700; margin-top: 12px;
}
.ok {
  font-size: var(--t-md); padding: 11px 13px; border-radius: var(--r-md);
  background: var(--live-s); color: var(--live); font-weight: 700; margin-top: 12px;
}
[hidden] { display: none !important; }

/* ── 목록 한 줄 ─────────────────────────────────────────────── */
.item {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 14px 15px; border-radius: var(--r-md);
  border: 1.5px solid var(--line); background: var(--card); color: var(--ink);
  font: inherit; cursor: pointer; margin-bottom: 9px;
}
.item:hover { border-color: var(--line2); }
/* ⚠️ 줄마다 같은 이모지를 넣지 않는다 — 아무것도 구별해 주지 않는다.
   학원 이름 첫 글자를 쓰면 목록에서 눈이 바로 걸린다. */
.item .ico {
  flex: none; width: 36px; height: 36px; border-radius: var(--r-sm); display: grid;
  place-items: center; background: var(--raise); color: var(--ink2);
  font-size: var(--t-base); font-weight: 800; letter-spacing: -.02em;
}
.item .t { flex: 1; min-width: 0; }
.item .t b { display: block; font-size: var(--t-base); font-weight: 800; letter-spacing: -.02em; }
.item .t span { font-size: var(--t-sm); color: var(--ink3); }
.item .go { flex: none; color: var(--ink3); font-size: var(--t-lg); }

/* ── 목록 줄에 얹는 [지우기] ──────────────────────────────────────
   ⚠️⚠️ **줄 전체가 `<button class="item">` 이라 그 안에 또 단추를 넣을 수
      없다**(HTML 이 금지한다 — 넣으면 브라우저가 조용히 밖으로 빼낸다).
      그래서 줄 위에 **겹쳐 놓는다.** 줄은 그대로 두고 오른쪽만 비워 준다.
   ⚠️ 누르는 면은 40×40 이다. 24 는 기준을 겨우 넘길 뿐이고, 지우기는 옆의
      줄(학원 열기)과 붙어 있어서 잘못 눌리면 되돌릴 수 없다. */
.itemw { position: relative; }
.itemw > .item { padding-right: 58px; }
.itemx {
  position: absolute; top: 50%; right: 11px; transform: translateY(-50%);
  width: 40px; height: 40px; border-radius: var(--r-sm);
  border: 0; background: none; color: var(--ink3);
  font: inherit; font-size: var(--t-lg); line-height: 1; cursor: pointer;
  display: grid; place-items: center;
}
.itemx:hover { background: var(--stop-s); color: var(--stop); }
/* ⚠️ 키보드로 옮겨 왔을 때 어디에 있는지 보여야 한다 — 겹쳐 있어서 더 그렇다. */
.itemx:focus-visible { outline: 2px solid var(--stop); outline-offset: 2px; }

/* ── 큰 고르개 (차량용 / 보기용) ─────────────────────────────── */
.pick { display: grid; gap: 12px; margin-top: 4px; }
.pick button {
  display: grid; gap: 4px; padding: 22px 18px; text-align: left;
  border: 1.5px solid var(--line); border-radius: var(--r-md);
  background: var(--card); color: var(--ink); font: inherit; cursor: pointer;
}
.pick button { transition: transform .16s ease-out, border-color .16s; }
.pick button:active { transform: scale(.985); transition-duration: 0s; }
/* ⚠️⚠️ **이모지를 쓰지 않는다.** 폰마다 그림이 다르고 색을 맞출 수 없다.
   차량 쪽만 통학버스 황색을 쓴다 — 이 앱에서 황색이 뜻하는 것은 '차' 하나다. */
.pick .e { width: 34px; height: 34px; margin-bottom: 10px; color: var(--ink3); }
.pick .e svg { display: block; width: 100%; height: 100%; }
.pick .e[data-i="car"] { color: var(--amber); }
.pick .h { font-size: var(--t-lg); font-weight: 800; letter-spacing: -.02em; }
.pick .d { font-size: var(--t-md); color: var(--ink3); line-height: 1.6; }

/* ── 기다림 막 ─────────────────────────────────────────────────
 *
 * ⚠️⚠️ **단추를 '일하는 중' 으로 바꾸는 것만으로는 부족하다.** 폰에서
 *    로그인은 아이디·비밀번호를 치고 **키보드가 올라온 채로** 누른다 —
 *    그 단추는 키보드 뒤에 가려 안 보인다. 그래서 2초쯤 아무 일도 안
 *    일어나는 것처럼 보이다가 화면이 갑자기 넘어갔다.
 *    만든 사람은 알고 기다리지만 처음 쓰는 사람은 눌리긴 한 건지 모른다.
 * ⚠️ 화면 **한가운데**여야 한다. 키보드는 아래에서 올라오므로 아래에 두면
 *    또 가려진다.
 * ⚠️ `position: fixed` + `inset: 0` — 뒤를 못 만지게 막는 것도 몫이다
 *    (기다리는 동안 [로그인] 을 또 누르면 요청이 두 번 나간다).
 */
/* ── 물어보는 창 (SB.ask) ─────────────────────────────────────
   ⚠️ 브라우저 기본 `confirm()` 대신이다. 이유는 `app-core.js` 의 `ask()` 주석.
   ⚠️ `.wait`(9000)보다 위에 둔다 — 기다리는 중에도 물어볼 일이 있다. */
.ask {
  /* safe-area: ok — 막은 화면 전체를 덮는 것이 맞고(뒤를 못 만지게),
     내용은 `place-items: center` 로 한가운데에 있다. */
  position: fixed; inset: 0; z-index: 9500;
  display: grid; place-items: center; padding: 20px;
  /* ⚠⚠ **막은 두 화면 다 어두워야 한다 — 토큰을 쓰지 않는다.**
     `var(--ink)` 로 둔 적이 있는데, 어두운 화면에서는 그 값이 거의 흰색
     (#F1F3F6)이라 **막이 하얀 안개처럼 덮였다.** 뒤가 어두워야 앞의
     카드가 떠 보이므로 여기만 고정값이다. */
  background: rgba(6, 9, 13, .52);  /* ui-audit: ok — 막은 밝기와 무관하게 어둡다 */
  animation: askIn .12s ease-out;
}
@keyframes askIn { from { opacity: 0 } }
.ask-b {
  width: min(360px, 100%); background: var(--card);
  border-radius: var(--r-md); padding: 22px 20px 16px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .28);
}
.ask-t {
  margin: 0; font-size: var(--t-lg); font-weight: 800;
  letter-spacing: -.02em; color: var(--ink); line-height: 1.45;
}
.ask-s { margin: 8px 0 0; font-size: var(--t-md); line-height: 1.7; color: var(--ink3); }
/* ⚠️ 단추는 **같은 너비**다. 되돌릴 수 없는 쪽을 더 크게 만들면 그쪽을
   누르기 쉬워진다 — 확인창에서 그러면 안 된다. */
.ask-r { display: flex; gap: 8px; margin-top: 18px; }
.ask-r .btn { flex: 1; }
@media (prefers-reduced-motion: reduce) { .ask { animation: none } }

.wait {
  /* safe-area: ok — 글자는 `place-items: center` 로 **한가운데**에 있다.
     막 자체는 시계·알림 밑까지 덮는 것이 맞다(그래야 뒤를 못 만진다). */
  position: fixed; inset: 0; z-index: 9000;
  display: grid; place-items: center; gap: 14px;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
}
.wait[hidden] { display: none; }
.wait-b {
  display: grid; place-items: center; gap: 12px;
  padding: 26px 34px; border-radius: var(--r-md);
  background: var(--card); box-shadow: var(--shadow-l);
  font-size: var(--t-base); font-weight: 700; color: var(--ink);
}
.wait-s {
  width: 26px; height: 26px; border-radius: var(--r-full);
  border: 3px solid var(--line); border-top-color: var(--ink);
  animation: waitspin .7s linear infinite;
}
@keyframes waitspin { to { transform: rotate(360deg); } }
/* ⚠️ 움직임을 줄여 달라는 설정을 지킨다 — 도는 대신 밝기만 바뀐다.
   ⚠️ `sk` 를 빌려 쓰지 말 것 — 그건 `map.html` 안에만 있어서 다른 화면에서는
      **아무 애니메이션도 없는** 회색 동그라미가 된다. */
@keyframes waitfade { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }
@media (prefers-reduced-motion: reduce) {
  .wait-s { animation: waitfade 1.2s ease-in-out infinite; }
}

/* ── 코드 보여주기(초대) ────────────────────────────────────── */
/*
 * QR 상자.
 *
 * ⚠️ **흰 바탕을 우리가 깔지 않는다.** qrcode-generator 가 그리는 SVG 안에
 *    이미 흰 사각형이 들어 있다(`fill="white"`). 밖에서 또 깔면 어두운
 *    화면에서 흰 테두리가 한 겹 더 생겨 둥둥 뜬 것처럼 보인다.
 * ⚠️ **너무 크게 만들지 말 것.** 찍는 거리는 30cm 남짓이라 180px 이면 충분
 *    하고, 그보다 크면 코드 숫자가 화면 밖으로 밀려 같이 안 보인다 —
 *    QR 이 안 읽히는 폰에서는 그 숫자가 유일한 길이다.
 */
.qrbox { margin: 12px auto 0; width: min(180px, 62%); }
.qrbox[hidden] { display: none; }
.qrbox svg { display: block; width: 100%; height: auto; border-radius: var(--r-sm); }

.code {
  font-size: var(--t-2xl); font-weight: 800; letter-spacing: .12em; text-align: center;
  padding: 18px; border-radius: var(--r-md); background: var(--raise);
  font-variant-numeric: tabular-nums; user-select: all;
}

/* ── 지도 (설정에서 위치·정류장 찍기) ───────────────────────── */
.map { width: 100%; height: 300px; border-radius: var(--r-md); overflow: hidden;
       background: var(--raise); border: 1px solid var(--line); }
.maptip { font-size: var(--t-sm); color: var(--ink3); margin-top: 8px; line-height: 1.7; }

/* ── 설정용 지도: 한 손가락은 화면을 내린다 ────────────────────
   ⚠️⚠️ **카카오가 안쪽 div 에 `touch-action: none` 을 건다**(배포본에서 실측).
      그래서 손가락이 지도에 닿으면 **한 손가락도 지도가 먹어** 화면을 내릴
      수가 없었다. 세로 넘김만 브라우저에 돌려준다.
   ⚠️ 두 손가락(이동·확대)은 카카오가 JS 로 잡으므로 `pan-y` 여도 그대로 된다.
   ⚠️ **`#map`(지도 탭의 큰 지도)에는 걸지 말 것** — 거기는 지도가 화면 전체라
      한 손가락으로 움직이는 것이 맞다. 여기 `.map` 은 설정용 작은 지도다. */
.map, .map * { touch-action: pan-y !important; }

/* 위치가 이미 정해진 경우 지도 대신 보여 주는 줄 */
.setdone {
  display: grid; gap: 3px; padding: 12px 14px; border-radius: var(--r-sm);
  background: var(--live-s);
}
.setdone b { font-size: var(--t-md); font-weight: 700; color: var(--live); }
.setdone span { font-size: var(--t-sm); color: var(--ink2);
                overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ⚠️ 마우스로 쓰는 기기에는 **보여주지 않는다** — 거기서는 한 손가락 규칙
   자체가 없어서 거짓말이 된다. */
.mapgest { display: none; }
@media (hover: none) and (pointer: coarse) { .mapgest { display: block; } }

/* ⚠️ `.maphint`(끌 때만 잠깐 뜨던 말풍선)는 없앴다 — **이미 헤맨 사람에게만**
   보여서 안내 구실을 못 했다. 지금은 지도 밑에 `.mapgest` 로 늘 적어 둔다. */
/* 정해졌다는 것은 **눈에 띄어야** 한다 — 잔글씨로 적으면 안 정해진 것과 같아 보인다. */
.maptip.done { color: var(--live); font-weight: 600; }
.maptip.done b { color: var(--live); }
.maptip .warnish { color: var(--warn); font-weight: 700; }

/* ── 정류장 줄 ──────────────────────────────────────────────── */
.stop {
  display: flex; align-items: center; gap: 10px; padding: 10px 0;
}
.stop + .stop { border-top: 1px solid var(--line); }
.stop .n { flex: 1; min-width: 0; }
.stop .n input { min-height: 40px; }
/* 지우기 단추 — 정류장 줄과 수업 시간대가 같이 쓴다.
   ⚠️⚠️ `.stop .x` 로 두지 말 것. 수업 시간대의 지우기 단추도 `.x` 인데
      `.stop` 안에 있지 않아서 **아무 꾸밈도 안 붙은 기본 단추**로 나왔다.
   ⚠️ `.btn.danger` 와 같은 말을 쓴다(테두리는 옅은 빨강, 글자는 빨강).
      한 화면에서 지우는 단추가 두 가지로 보이면 안 된다. */
.x {
  flex: none; width: 38px; height: 38px; border-radius: var(--r-sm);
  border: 1.5px solid color-mix(in srgb, var(--stop) 30%, transparent);
  background: var(--card); color: var(--stop);
  font-size: var(--t-base); line-height: 1; cursor: pointer;
  display: grid; place-items: center;
  transition: background-color .16s, transform .16s ease-out;
}
.x:hover { background: var(--stop-s); }
.x:active { transform: scale(.94); transition-duration: 0s; }

/* ── 밝게/어둡게 단추 ───────────────────────────────────────── */
.thm { flex: none; width: 34px; height: 34px; border-radius: var(--r-sm);
       border: 1px solid var(--line); background: var(--raise); color: var(--ink2);
       font-size: var(--t-base); cursor: pointer; }

@media (prefers-reduced-motion: reduce) { .pick button { transition: none; } }

/* 제목 옆 꼬리표 — 무엇을 꼭 해야 하는지 한눈에 갈라 준다.
   설정할 것이 여섯 가지라 다 필수로 보이면 시작하기 어렵다. */
.tag { font-size: var(--t-xs); font-weight: 700; letter-spacing: -.01em;
       padding: 3px 7px; border-radius: var(--r-sm); vertical-align: 2px; margin-left: 6px; }
.tag.req { color: var(--live); background: var(--live-s); }
.tag.opt { color: var(--ink3); background: var(--raise); }

/* ══ 작은 창(모달) ═══════════════════════════════════════════════
 *
 * ⚠️ 폰에서는 **아래에서 올라오는 시트**로 둔다. 화면 가운데에 띄우면
 *    키보드가 올라올 때 창이 가려진다.
 * ⚠️ 바깥을 누르면 닫힌다(`event.target === this`). 안쪽을 눌러도 닫히면
 *    글자를 고르다가 창이 사라진다.
 */
.mask {
  /* safe-area: ok — 가림막은 화면을 **다 덮는 것이 맞다**(상태 표시줄까지).
     피해야 하는 것은 그 위에 얹히는 시트이고, 그건 `#mask .sheet2` 의
     `max-height` 가 안전영역만큼 덜 쓰는 것으로 맞춰 뒀다. */
  position: fixed; inset: 0; z-index: 200; display: grid;
  align-items: end; justify-items: stretch;
  background: rgba(0, 0, 0, .5); padding: 0;
}
.sheet2 {
  background: var(--card); border-radius: var(--r-md) var(--r-md) 0 0;
  padding: 22px 20px calc(22px + env(safe-area-inset-bottom));
  box-shadow: 0 -12px 40px rgba(0, 0, 0, .3);
  animation: rise .22s cubic-bezier(.2, .8, .3, 1);
}
@keyframes rise { from { transform: translateY(14px); opacity: .6 } to { transform: none; opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .sheet2 { animation: none } }
.sheet2 h3 { font-size: var(--t-lg); font-weight: 800; letter-spacing: -.02em; margin-bottom: 8px; }

/* 넓은 화면에서는 가운데 상자로. */
@media (min-width: 560px) {
  .mask { align-items: center; justify-items: center; padding: 20px; }
  .sheet2 { width: min(420px, 100%); border-radius: var(--r-md); box-shadow: 0 20px 60px rgba(0, 0, 0, .35); }
  @keyframes rise { from { transform: scale(.97); opacity: .6 } to { transform: none; opacity: 1 } }
}

/* ── 이름-값 한 줄 ─────────────────────────────────────────────
   ⚠️ `index.html`·`setup.html` 에는 `<style>` 블록이 **없다**. 화면 전용
      스타일이라도 여기에 넣어야 한다(전에 `</style>` 뒤에 붙이려다
      조용히 아무 데도 안 들어갔다). */
/* 이름-값은 **표**다. 줄 사이가 넓으면 무엇과 무엇이 한 줄인지 흐려진다. */
.kv { display: flex; align-items: center; gap: var(--s3); padding: 9px 0;
      border-bottom: 1px solid var(--line); font-size: var(--t-md); }
.kv:last-of-type { border-bottom: 0; }
.kv > span { color: var(--ink3); flex: none; min-width: 76px; }
.kv > b { font-weight: 700; color: var(--ink); min-width: 0; overflow: hidden;
          text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.kv .btn { margin-left: auto; }

/* 하단 탭 바에 내용이 가리지 않게. 바가 없으면 --nav 가 0 이다. */
.wrap { padding-bottom: calc(var(--nav, 0px) + 28px); }

/* ── 안내 문구 (칸 아래 작은 글씨) ─────────────────────────────── */
.hint { font-size: var(--t-sm); line-height: 1.6; color: var(--ink3); margin-top: 6px; }
.hint.ok { color: var(--live); font-weight: 600; }
.hint.bad { color: var(--stop); font-weight: 600; }

/* ── 스위치 ────────────────────────────────────────────────────
   ⚠️ 켬/끔이 **한눈에** 보여야 한다. 자동 로그인은 켠 줄 모르고 두면
      남이 폰을 열었을 때 그대로 들어가진다. */
.sw { display: flex; align-items: center; gap: 12px; margin-top: 16px; cursor: pointer; }
.sw input { position: absolute; opacity: 0; width: 0; height: 0; }
.sw-t { flex: none; width: 46px; height: 28px; border-radius: var(--r-full);
        background: var(--line2); position: relative; transition: background .18s; }
.sw-t::after { content: ''; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
               border-radius: 50%; background: var(--card); transition: transform .18s;
               box-shadow: 0 1px 3px rgba(0,0,0,.3); }
/* ⚠️⚠️ **켜짐에 상태색(초록)을 쓰지 말 것.** 초록은 이 앱에서 '차가 지금
   달리고 있다' 는 뜻으로 예약돼 있다. 설정 스위치까지 초록이면 지도에서
   초록을 봤을 때 그것이 상태인지 그냥 켜진 것인지 알 수 없다. */
.sw input:checked + .sw-t { background: var(--ink); }
.sw input:checked + .sw-t::after { transform: translateX(18px); }
.sw input:focus-visible + .sw-t { outline: 2px solid var(--ink); outline-offset: 2px; }
.sw-x { display: grid; min-width: 0; }
.sw-x b { font-size: var(--t-md); font-weight: 700; }

/* ── 첫 화면 인사 ──────────────────────────────────────────────
   ⚠️ 처음 여는 사람이 **무엇을 하는 앱인지** 3초 안에 알아야 한다. */
.hero { text-align: center; padding: 26px 8px 22px; }
.hero-e { font-size: var(--t-3xl); line-height: 1; margin-bottom: 12px; }
.hero h2 { font-size: var(--t-xl); font-weight: 800; letter-spacing: -.03em; margin: 0 0 8px; }
.hero p { font-size: var(--t-md); line-height: 1.7; color: var(--ink3); margin: 0; }

/* ── 누르는 줄 (동작) ──────────────────────────────────────────
   ⚠️⚠️ **값이 없는 것을 '이름 : 값' 표에 넣지 말 것.** 비밀번호처럼 보여줄
      값이 아예 없는 것은 **동작**이다. 표에 두면 값이 비어 있는 칸으로
      읽혀서 "고장났나" 로 보인다. 꺾쇠(›)가 누를 수 있다는 표시다. */
/* ⚠️⚠️ **격자(grid)로 두 칸을 만들지 말 것 — 두 번째로 겪는 실수다.**
   `grid-row` 만 정해 준 칸(꺾쇠)을 자동 배치가 **왼쪽에 먼저 앉혀서**,
   `› 비밀번호 바꾸기` 처럼 좌우가 뒤바뀌었다(운영 화면 표에서도 똑같이 겪었다).
   **flex 는 쓴 순서대로 놓는다.** 한 줄에 왼쪽 덩어리·오른쪽 표시를 두려면
   flex 를 쓸 것. */
.arow {
  display: flex; align-items: center; gap: var(--s3);
  width: 100%; padding: 13px var(--s4); border: 0; border-bottom: 1px solid var(--line);
  background: none; font: inherit; text-align: left; cursor: pointer;
}
.arow:last-child { border-bottom: 0; }
.arow:hover { background: var(--raise); }
.arow > .l { flex: 1; min-width: 0; display: grid; gap: 2px; }
.arow b { font-size: var(--t-md); font-weight: 700; color: var(--ink); }
.arow .d { font-size: var(--t-sm); color: var(--ink3);
           overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.arow::after { content: '›'; flex: none; color: var(--ink3); font-weight: 700; }

/* ── 접어 두는 곁다리 ──────────────────────────────────────────
   ⚠️ 늘 필요한 것이 아닌데 펼쳐 두면, 처음 쓰는 사람이 **자기가 뭘 안 했나**
      싶어진다. 접어 두고 제목으로 무엇인지 밝힌다. */
.more { margin-top: var(--s3); }
.more > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 6px;
  padding: 11px 2px; font-size: var(--t-md); font-weight: 700; color: var(--ink3);
}
.more > summary::-webkit-details-marker { display: none; }
.more > summary::before { content: '＋'; font-weight: 700; }
.more[open] > summary::before { content: '－'; }
.more[open] > summary { color: var(--ink2); }
.more-h { display: block; font-size: var(--t-md); font-weight: 800; color: var(--ink);
          margin-bottom: 4px; }
.more .hint { margin-top: 0; }

/* ── 번호가 붙은 순서 ──────────────────────────────────────────
   ⚠️ 순서를 `1` `2` `3` 을 굵게 쓴 문단으로 흉내내지 말 것. 진짜 `<ol>` 이면
      화면 읽어 주는 도구가 "3개 중 2번째" 라고 읽어 준다. */
.steps-n { list-style: none; counter-reset: n; display: grid; gap: 10px; margin-top: var(--s3); }
.steps-n li {
  counter-increment: n; display: grid; grid-template-columns: 22px 1fr; gap: 10px;
  font-size: var(--t-md); line-height: 1.6; color: var(--ink2);
}
.steps-n li::before {
  content: counter(n); grid-row: 1 / span 2;
  width: 22px; height: 22px; border-radius: var(--r-full);
  background: var(--ink); color: var(--card);
  font-size: var(--t-xs); font-weight: 800; display: grid; place-items: center;
}
.steps-n li b { color: var(--ink); font-weight: 700; }
.steps-n li span { grid-column: 2; font-size: var(--t-sm); color: var(--ink3); }

/* ── 설정을 마친 뒤 ────────────────────────────────────────────
   ⚠️ 축하 이모지를 넣지 않는다 — 아무것도 알려주지 않는다. 무엇이 끝났고
      다음에 무엇을 하면 되는지만 적는다. */
.done-h { display: grid; gap: 6px; padding: 4px 0 18px; }
.done-h b { font-size: var(--t-xl); font-weight: 800; letter-spacing: -.03em; color: var(--ink); }
.done-h span { font-size: var(--t-md); line-height: 1.7; color: var(--ink3); }

/* ── 개발자 현황 ──────────────────────────────────────────────── */
.ch { font-size: var(--t-md); font-weight: 800; letter-spacing: -.02em; margin: 0 0 6px; }
.ch .num { font-weight: 600; color: var(--ink3); font-size: var(--t-sm); margin-left: 6px; }

/* ── 남은 단계 ────────────────────────────────────────────────
   ⚠️ 설정이 여섯 가지라 어디까지 했는지 모르면 중간에 그만둔다. */
.steps { margin-bottom: 18px; padding: 14px 16px; border-radius: var(--r-md);
         background: var(--raise); }
.steps-h { font-size: var(--t-md); line-height: 1.6; color: var(--ink2); margin: 0 0 10px; }
.steps-h b { color: var(--ink); font-weight: 800; }
.steps-l { display: flex; flex-wrap: wrap; gap: 6px; }
.steps-l span { font-size: var(--t-sm); font-weight: 600; color: var(--ink3);
                padding: 4px 9px; border-radius: var(--r-sm); background: var(--card); }
.steps-l .on { color: var(--live); }
.steps-l .opt { opacity: .7; }
/* 아직 안 한 필수 — 위 `.secv.miss` 와 같은 뜻이라 같은 색을 쓴다. */
.steps-l .miss { color: var(--stop); background: var(--stop-s); font-weight: 700; }
/* 다음에 할 일 — ✓ 가 아니다(우리가 확인할 수 없는 일이라 했다고 못 한다). */
.steps-l .next { color: var(--ink); font-weight: 700; }

/*
 * 잠긴 [사람 부르기] 카드.
 *
 * ⚠️⚠️ **"설정을 마치세요" 로 끝내지 말 것.** 무엇이 안 됐는지 모르면
 *    학원장은 초대 코드가 왜 안 나오는지 화면에서 찾을 수 없다. 남은 것을
 *    이름으로 짚고 **그 자리로 가는 단추**를 준다.
 */
.lock { border-color: color-mix(in srgb, var(--stop) 40%, transparent); }
.lock-h { display: block; font-size: var(--t-base); font-weight: 800;
          letter-spacing: -.02em; color: var(--stop); }
/* 다 채우고 **저장만** 남은 상태 — 잘못이 아니라 다음 걸음이다. */
.lock.ready { border-color: var(--line); }
.lock.ready .lock-h { color: var(--ink); }
.lock-l { display: grid; gap: 6px; margin-top: 12px; }
.lock-i {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 11px 13px; border-radius: var(--r-sm);
  border: 1px solid color-mix(in srgb, var(--stop) 35%, transparent);
  background: var(--stop-s); color: var(--stop);
  font: inherit; font-size: var(--t-md); font-weight: 700;
}
.lock-i .go { font-weight: 600; opacity: .85; }
.lock-i:active { transform: scale(.99); }

/* ── 접히는 설정 항목 ──────────────────────────────────────────
   ⚠️ 여섯 가지가 세로로 쭉 있으면 화면이 너무 길어 끝까지 안 내려간다.
      한 번에 하나만 편다(`wireSections`). */
.sec { margin-bottom: 10px; }
.sec > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px;
  padding: 15px 16px; border-radius: var(--r-md); background: var(--card);
  border: 1px solid var(--line);
  font-size: var(--t-base); font-weight: 800; letter-spacing: -.02em; color: var(--ink);
}
.sec > summary::-webkit-details-marker { display: none; }
.sec > summary::after {
  content: '⌄'; margin-left: auto; color: var(--ink3); font-weight: 700;
  transition: transform .18s; flex: none;
}
/*
 * 접힌 줄에 지금 값을 적는다 — 열지 않고도 무엇이 들어 있는지 보이게.
 *
 * ⚠️ **꺾쇠(::after)보다 앞에 와야 한다.** `margin-left: auto` 가 그 꺾쇠를
 *    오른쪽 끝으로 밀고 있으므로, 값은 그 사이에서 남는 자리를 차지한다.
 * ⚠️ **한 줄로 자른다.** 학원 이름이 길면 줄이 두 줄이 되어 접힌 목록의
 *    높이가 제각각이 된다 — 그러면 접어 둔 이유(짧게 보기)가 무너진다.
 *    (`min-width: 0` 이 없으면 flex 자식이라 아예 안 줄어든다)
 */
.secv {
  margin-left: auto; min-width: 0; flex: 0 1 auto;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--t-sm); font-weight: 600; color: var(--ink3); letter-spacing: 0;
}
/*
 * ⚠️⚠️ **`display: none` 으로 감추지 말 것.** 오른쪽 꺾쇠(⌄)를 줄 끝으로 미는
 *    것이 이 요소의 `margin-left: auto` 다. 통째로 감추면 밀 것이 없어져서
 *    **값이 없는 줄에서만 꺾쇠가 이름표 바로 옆에 붙는다** — [수업 시간대]·
 *    [정류장] 줄만 화살표 자리가 달라 보이던 것이 이것이다.
 *    폭을 0 으로 두면 글자는 안 보이면서 미는 힘은 그대로 남는다
 *    (`overflow: hidden` 이 위에 이미 걸려 있다).
 */
.secv:empty { width: 0; padding: 0; }
/*
 * 아직 안 한 **필수** 항목.
 *
 * ⚠️⚠️ **색만으로 말하지 않는다.** 글자가 그대로 '아직 안 함' 이라고 적혀
 *    있고, 색은 눈이 먼저 가게 도울 뿐이다(색을 못 가리는 사람도 읽는다).
 * ⚠️ **선택 항목에는 붙이지 않는다.** 넷이 다 붉으면 무엇이 급한지가
 *    오히려 안 보인다 — 정류장·수업 시간대는 없어도 차량 위치는 나온다.
 */
.secv.miss { color: var(--stop); font-weight: 700; }
.sec.todo > summary { border-color: color-mix(in srgb, var(--stop) 45%, transparent);
                      border-left: 3px solid var(--stop); }
.sec.todo > summary .tag.req { color: var(--stop); background: var(--stop-s); }
.sec.todo[open] > .card { border-color: color-mix(in srgb, var(--stop) 45%, transparent);
                          border-left: 3px solid var(--stop); }
.sec[open] > summary .secv { width: 0; padding: 0; }   /* 펴 놓으면 안에 그 값이 그대로 보인다 */
.sec > summary::after { margin-left: 8px; }
.sec[open] > summary::after { transform: rotate(180deg); }
.sec[open] > summary { border-radius: var(--r-md) var(--r-md) 0 0; border-bottom: 0; }
.sec[open] > .card { border-radius: 0 0 var(--r-md) var(--r-md); border-top: 0; margin-top: 0; }
@media (prefers-reduced-motion: reduce) { .sec > summary::after { transition: none } }

/* ── 첫 화면 ──────────────────────────────────────────────────
   ⚠️ 처음 여는 사람이 무엇을 하는 앱인지 3초 안에 알아야 한다.
      로고를 크게 두되, 화면 한 판을 다 쓰지는 않는다 — 아래 로그인 칸이
      첫 화면에서 같이 보여야 바로 시작할 수 있다. */
.splash { text-align: center; padding: 12px 8px 12px; }

/* ── 시각 단추 ────────────────────────────────────────────────
   ⚠️ 누를 수 있게 보여야 한다. 작은 회색 칸이면 무엇을 하라는지 모른다. */
.timebtn {
  flex: 1; display: grid; gap: 2px; padding: 12px 14px; border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--card); cursor: pointer;
  font: inherit; text-align: left;
}
.timebtn span { font-size: var(--t-sm); color: var(--ink3); font-weight: 600; }
.timebtn b {
  font-size: var(--t-2xl); font-weight: 800; letter-spacing: -.03em; color: var(--ink3);
  font-variant-numeric: tabular-nums;
}
.timebtn.set b { color: var(--ink); }
.timebtn:active { transform: scale(.99); }
/* 수업 시간대는 한 줄에 네 개(등원 두 개 · 하원 두 개)라 작게 쓴다.
   ⚠️ 운행 시간과 **같은 단추**여야 한다 — 한쪽만 브라우저 기본 시각 칸이면
   같은 화면에서 두 가지 방식으로 시간을 정하게 된다. */
.timebtn.mini { padding: 7px 10px; border-radius: var(--r-sm); }
.timebtn.mini b { font-size: var(--t-base); }
.timebtn.mini span { font-size: var(--t-xs); }

/* ── 이름으로 찾은 후보 ───────────────────────────────────────
   ⚠️ 같은 이름의 학원이 여러 곳 있다. 첫 번째를 말없이 찍으면 남의 학원
      자리가 들어가고, 그러면 운행 기록이 통째로 어긋난다. */
.cand-l { display: grid; gap: 8px; margin-bottom: 14px; }
.cand {
  display: grid; gap: 3px; width: 100%; padding: 12px 14px; border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--card); cursor: pointer;
  font: inherit; text-align: left;
}
.cand b { font-size: var(--t-md); font-weight: 700; color: var(--ink); }
.cand span { font-size: var(--t-sm); color: var(--ink3); }
.cand:active { transform: scale(.99); }

/* ── 계정 한 줄 (운영 화면) ──────────────────────────────────── */
.urow {
  display: grid; gap: 2px; width: 100%; padding: 11px 0; border: 0; border-bottom: 1px solid var(--line);
  background: none; font: inherit; text-align: left; cursor: pointer;
}
.urow:last-child { border-bottom: 0; }
.urow b { font-size: var(--t-md); font-weight: 700; color: var(--ink); }
.urow .ue { font-size: var(--t-sm); color: var(--ink3); overflow: hidden;
            text-overflow: ellipsis; white-space: nowrap; }
.urow .ut { display: flex; gap: 6px; margin-top: 2px; }
.urow .ut i {
  font-style: normal; font-size: var(--t-xs); font-weight: 700; padding: 2px 7px;
  border-radius: var(--r-sm); background: var(--raise); color: var(--ink3);
}
.urow .ut i.ok   { background: var(--live-s); color: var(--live); }
.urow .ut i.warn { background: var(--warn-s); color: var(--warn); }
.urow .ut i.bad  { background: var(--stop-s); color: var(--stop); }

/* 시트 안이 길어지면 시트 안에서 굴린다 — 화면 밖으로 넘치면 못 누른다. */
/* ⚠️ 시트가 길면 위쪽이 상태 표시줄까지 올라간다 — 안전영역만큼 덜 쓴다. */
#mask .sheet2 { max-height: calc(88vh - env(safe-area-inset-top)); overflow-y: auto; }
