/* 셈톡 웹 — 공통 컴포넌트 (토스 톤). tokens.css 위에서 동작. */

/* Reset */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  /* 🔴 body의 **글자** 기본값(서체 스택·크기·행간·자간·font-synthesis)은 여기 없다 — typography.css 한 곳이다(타이포그래피 C2, D-891).
     본문 서체는 SemTalk Sans Round(셈톡 산스 라운드, D-890 · C1), 스택 문자열은 typography.css `--font-sans`에만 있고 body가 그것을 쓴다.
     옛 값(C1까지): font-family 리터럴 스택 · letter-spacing -0.2px · line-height 1.5 · 크기는 UA 16px → 지금은 body2(14/22, ≥768 15/24) ·
     --ls-14(+0.02em) · font-synthesis: none. @font-face는 tokens.css.
     ⚠ 여기에 font-family·font-size·line-height·letter-spacing을 다시 적지 마라 — 같은 속성이 두 파일에 있으면 «어느 쪽이 진실인가»가
       링크 순서에 매달린다(TypographyTokensContractTest가 잰다). 색·바탕·줄바꿈만 여기 둔다. */
  color: var(--text-primary);
  background: var(--background);
  /* 🔴 한글은 낱말 단위로 꺾는다(D-880, P-078) — 기본값(normal)은 음절 사이 어디서나 끊어
        «보여 / 요.»·«입 / 니다»가 실제로 났다. keep-all + break-word는 chat.css가 D-295에서 짝으로 쓴
        값이다: 띄어쓰기 없는 긴 낱말(URL·숫자열)은 줄 배치 단계에서 칸 끝에 닿을 때 꺾인다.
     ⚠ 칸의 최소 폭(min-content)은 커진다(3차 후속 K17): keep-all은 최소 폭을 가장 긴 어절 폭으로 키우고,
       overflow-wrap: break-word는 그 최소 폭을 줄이지 않는다(옛 word-break: break-word·anywhere는 줄였다).
       그래서 최소 폭으로 폭이 정해지는 칸 — 격자의 1fr·auto 트랙, table-layout: auto 표, min-width: 0 없는
       flex 항목 — 에 사용자 글이 들어가면 칸이 긴 값 폭으로 넓어져 폰에서 넘친다. 그런 칸은 트랙을
       minmax(0, 1fr)로 두거나 min-width: 0을 주거나, 표 칸이면 overflow-wrap: anywhere를 함께 둔다
       (brief .iw-view-rows · annotate .iq-rows · contract 당사자·표·조항 · sisun .sisun-pop-cap span).
     ⚠ 지면이 이 규칙을 덮어 음절 단위로 되돌리지 마라 — 긴 낱말 넘침은 `overflow-wrap: break-word`로 잡는다
       (`word-break: break-word`는 keep-all을 덮어 한글을 다시 음절로 끊는다). 한 줄 말줄임(nowrap +
       ellipsis)은 이 규칙과 무관하게 그대로다(D-704). */
  word-break: keep-all;
  overflow-wrap: break-word;
}
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }
button { font-family: inherit; cursor: pointer; border: none; background: none; }
/* 🔴 **폼 요소는 서체를 상속하지 않는다**(D-363). 브라우저 기본이 input은 Arial,
   `<textarea>`는 **monospace**다 — body에 본문 서체(당시 Pretendard, 지금 SemTalk Sans Round)를 걸어도 사용자가 «글을 쓰는 칸»만
   다른 얼굴로 그려진다. 실측으로 잡았다: 질문 작성 화면의 placeholder가 monospace였고,
   그래서 한글 자간이 눈에 띄게 넓고 가운뎃점 같은 글자가 어긋나 보였다.
   ⚠ chat.css·brief.css 등 몇 곳이 각자 `font-family: inherit`을 붙여 두었는데, 그건 이 줄이
     없어서 지면마다 따로 때운 흔적이다. 여기 한 줄이 정본이다. */
input, textarea, select, optgroup { font-family: inherit; }
ul { list-style: none; }

/* Typography (app_typography 매핑)
   🔴 **아래 .t-* 12종은 typography.css가 덮는다**(타이포그래피 C2, D-891 · 이행 1단계). typography.css가 app.css 뒤에 실려
      같은 특이성의 «나중 규칙»으로 크기·행간·굵기·자간을 새 토큰(var(--fs-*) …)으로 다시 정의한다 — 여기 숫자는 더 이상 화면에
      닿지 않는다(.t-caption1·.t-caption2의 **색**만 여기 값이 남는다). 새 글자 규격은 여기가 아니라 typography.css의 .st-*·토큰을 쓴다.
      지우는 것은 C5(마크업이 .st-*로 다 옮겨간 뒤).
   ⚠ (옛 설명) 자간은 **크기에서 따라온다**(D-161) — 칸마다 손으로 정하지 말고 --ls-* 에서 고른다. 옛 --ls-2xl/xl/lg/md/sm도
      typography.css가 새 곡선(--ls-22/18/14/14/12)으로 재정의한다. 새 크기를 추가할 땐 자간도 같이 붙일 것: 안 붙이면 그 요소만
      body 자간으로 남아 같은 화면의 이웃 제목과 어긋난다(이게 정확히 D-161에서 고친 문제다). */
.t-display { font-size: 28px; font-weight: 700; line-height: 1.3; letter-spacing: var(--ls-2xl); }
.t-h1 { font-size: 24px; font-weight: 700; line-height: 1.3; letter-spacing: var(--ls-2xl); }
.t-h2 { font-size: 22px; font-weight: 700; line-height: 1.3; letter-spacing: var(--ls-xl); }
.t-title1 { font-size: 20px; font-weight: 700; line-height: 1.4; letter-spacing: var(--ls-xl); }
.t-title2 { font-size: 18px; font-weight: 700; line-height: 1.4; letter-spacing: var(--ls-lg); }
.t-title3 { font-size: 17px; font-weight: 600; line-height: 1.4; letter-spacing: var(--ls-lg); }
.t-body1 { font-size: 16px; font-weight: 400; line-height: 1.6; letter-spacing: var(--ls-lg); }
.t-body2 { font-size: 15px; font-weight: 400; line-height: 1.6; }
.t-label1 { font-size: 16px; font-weight: 600; letter-spacing: var(--ls-lg); }
.t-label2 { font-size: 14px; font-weight: 500; }
.t-caption1 { font-size: 13px; color: var(--text-secondary); }
.t-caption2 { font-size: 12px; color: var(--text-tertiary); }
.c-secondary { color: var(--text-secondary); }
.c-tertiary { color: var(--text-tertiary); }
.c-primary { color: var(--primary); }
/* 문장 속 링크(P-068 (가)) — 전역 a는 글자색 상속·밑줄 없음이라 문장에 끼운 링크가 주변 글자와 똑같았다.
   파랑 #1B64DA(흰 바탕 5.41:1) + 1px 밑줄(간격 3px) — 색과 밑줄 둘로 말해 색각·흑백에서도 성립한다(RQ-019 Q&A 링크와 같은 색).
   🔴 이름을 붙인 곳에만 단다 — 전역 선택자(p a)로 칠하지 마라(푸터·카드 속 문단 링크까지 바뀐다).
   버튼·카드·목록 줄·이미 색을 가진 링크(«이 건 문의하기»)에는 달지 않는다. 지금은 탈퇴 «고객센터»·의뢰인 프로필 «세무사 지도» 두 곳. */
.t-link { color: var(--primary-pressed); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* Layout */
.container { width: 100%; max-width: var(--content-max); margin: 0 auto; padding: 0 var(--s-xl); }

/* Header / Nav */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.site-header .bar { display: flex; align-items: center; gap: var(--s-2xl); height: 64px; }
.site-header .brand { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 18px; }
.site-header .brand .dot { width: 8px; height: 8px; border-radius: var(--r-full); background: var(--primary); }
.site-header nav { display: flex; gap: var(--s-xl); margin-left: auto; }
.site-header nav a { color: var(--text-secondary); font-weight: 500; font-size: 15px; }
.site-header nav a:hover { color: var(--text-primary); }

/* Buttons (app_theme CTA 54h 라운드12) */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 54px; padding: 0 22px; border-radius: var(--r-md);
  font-size: 16px; font-weight: 600; transition: background .15s, opacity .15s;
}
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-pressed); }
.btn-ghost { background: var(--surface); color: var(--text-primary); border: 1px solid var(--border); }
.btn-ghost:hover { background: var(--surface-alt); }
/* 작은 버튼 글자 = label2 크기·행간 14/20(타이포 점검 2026-10-03 F13 — 옛 15px·행간 상속 22/24). 굵기는 .btn의 600 그대로. */
.btn-sm { height: 44px; padding: 0 16px; font-size: var(--fs-label2); line-height: var(--lh-label2); }
/* 잠긴 버튼 한 벌(D-880, P-069 ⓤ — D-811 판정 i항의 값을 전역으로) — 배경 #F2F4F6 · 글자 #6B7684(4.19:1) ·
   테두리 1px #E5E8EB · 불투명도 1 · cursor not-allowed. 라벨은 그대로 둔다(무엇이 잠겼는지 라벨이 말한다).
   🔴 불투명도로 흐리지 마라 — 흐린 파랑(opacity .45·.55)은 흰 글자가 1.74~1.99:1이라 «무엇을 하면 열리는지»를
      알려 주는 라벨이 안 읽혔고, 지면마다 흐린 파랑·회색 두 벌이 섞여 잠김이 네 모양이었다.
   ⚠ 지면 CSS에 `…:disabled`를 따로 적지 마라 — 이 규칙이 .btn-primary:hover(0,2,0)보다 **뒤에** 있어 잠긴 채
     색이 바뀌지 않는다. 지면이 더 무거운 선택자로 덮으면 다시 네 모양이 된다. */
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: 1; background: var(--grey100); color: var(--grey600);
  border: 1px solid var(--border); box-shadow: none; cursor: not-allowed;
}
/* 두 버튼 줄(D-880, P-073 (나)) — 보조 + 주 두 버튼이 한 줄에 **반반 두 칸**(높이 54px · 주 16px/600, .btn 기본값).
   후기 쓰기·취소·완료 확인이 쓰던 문법을 프로필 편집·계약서 작성·세무사 등록까지 한 부품으로.
   🔴 보조 이름은 둘뿐이다 — 단계를 되돌리면 «이전», 저장 없이 떠나면 «돌아가기». «취소»는 «예약 취소»와 겹쳐
      쓰지 않는다. 상담노트 위저드(단계 이동)는 양 끝 그대로다(D-243 시안 3-E) — 이 부품을 씌우지 마라.
   ⚠ 버튼이 하나뿐인 지면(/book 제출·광고 신청·발행판)은 이 규칙 밖이다. */
.act-pair { display: flex; gap: 8px; margin-top: 16px; }
.act-pair > .btn { flex: 1 1 0; min-width: 0; }

/* Card (AppCard: 흰 카드 + 헤어라인 + 은은한 그림자) */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: var(--s-lg);
}
.card-flat { box-shadow: none; }

/* 공통 플래시 슬롯 (S-05) — layout.html이 content 위에 그린다. 모든 지면이 상속하는 정본이다.
   error는 경고색(§7 #FFFBEB 계열, --warning), notice는 중립. 하드 레드(--error)는 폼 인라인
   오류(W-03) 몫이라 여기서 쓰지 않는다. 개별 화면이 자체 슬롯을 그리면 이중으로 뜨므로 걷어낼 것.
   ⚠ client.css의 `.flash`와 이름이 겹치지 않도록 `.page-flash`로 둔다(client.css는 전역 로드가 아니다).
   🔴 여기는 **틀**(여백·모서리·테두리)만이다. 글자(크기·행간·굵기)는 아래 «① 홀로 서는 안내» 묶음의 `.page-flash` 한 곳(body1)이
      정한다 — 옛 이 자리의 14px/500/1.5는 뒤 규칙(15px/400/1.75)에 덮여 화면에 닿지 않던 죽은 선언이라 걷었다(타이포 3단계 묶음 ①). */
.page-flash {
  margin: 0 0 16px; padding: 12px 16px; border-radius: var(--r-md); border: 1px solid transparent;
}
/* 오류형 글자 = --tint-warm-ink #C2410C(사용자 결정 2026-10-03, 옛 --warning-dark #B35F00 4.45:1) — #FFFBEB 위 4.99:1(계산).
   경고 띠의 주황 계열은 그대로이고, 하드 레드(--error)는 여전히 쓰지 않는다. */
.page-flash-error  { background: #FFFBEB; border-color: #F3E3B3; color: var(--tint-warm-ink); }
.page-flash-notice { background: var(--grey50); border-color: var(--border); color: var(--text-secondary); }

/* Chip */
.chip {
  display: inline-flex; align-items: center; height: 34px; padding: 0 14px;
  border-radius: var(--r-sm); background: var(--surface-alt);
  font-size: 14px; font-weight: 500; color: var(--text-secondary);
}

/* ══ 상태 칩 두 톤 — 보는 사람 기준 세 단계 (P-072 1-(나), 사용자 결정 — D-880) ══════════════
   예약·계약 상태 칩의 **색은 여기 한 곳**이다. 모양(크기·면)은 지면의 칩(.chip·.st·.ct-status)이 갖고,
   이 세 클래스는 면과 글자 두 톤만 얹는다. 어느 톤인지는 서버가 고른다 — 예약 Reservation.tone(…) ·
   계약 ContractStatus.tone(…)·ContractTicket.tone(). 템플릿이 상태 문자열로 색을 고르지 마라.
     내 차례 = 파랑 틴트 #E8F3FF 위 #1B64DA (4.82:1) — 의뢰인의 결제 대기, 의뢰인의 서명 전 계약, 세무사의 작성 중
     진행     = 회색     #F2F4F6 위 #333D4B (9.97:1) — 예약 확정·상담 중, 전달됨·열람됨·서명 대기
     끝       = 옅은 회색 #F9FAFB 위 #4E5968 (6.81:1) — 완료·취소·노쇼, 서명 완료·거절됨·철회됨
                (글자는 한 단 진하게 — D-881, 사용자 결정 ⓨ, 3차 후속: 13px 칩 글자가 #6B7684로는 4.42:1로 AA 4.5:1에 못 미쳤다. 면은 그대로)
   🔴 초록(성공 톤)·주황·웜을 더하지 마라 — 상태 색 배열 금지(design.md §2, D-673). 유채색은 «내 차례» 파랑 하나다.
   ⚠ 이 블록은 .chip **뒤**에 있어야 한다 — 같은 무게(0,1,0)라 나중 규칙이 면을 이긴다. */
.state-turn { background: var(--primary-light); color: var(--primary-pressed); }
.state-live { background: var(--grey100); color: var(--grey800); }
.state-over { background: var(--grey50); color: var(--grey700); }

/* ══ 알림 유형 칩 색 — 시안 B «파랑 하나» (사용자 결정 2026-10-12, D-957) ═══════════════════════════════
   알림함 줄의 유형 칩(.noti-kind «예약»·«Q&A»·«광고»·«알림»…)은 두 톤이다 — 탭에 드는 유형(상담·Q&A·광고·구독)은 파랑 틴트,
   «전체»에만 있는 유형(공지·심사·문의·신고·알림·모르는 유형)은 회색. 묶음마다 다른 색을 주는 시안 A(초록·보라)는 사용자가
   반려했다 — 강조색은 파랑 하나다(위 상태 칩과 같은 원칙). 이것은 유형 색이지 상태 색이 아니다 — «상태 색 배열 금지»와 별건.
   어느 톤인지는 서버가 고른다(NotificationRepository.Item.tone() ← NotificationTabs.tabOf — 탭 매핑 하나가 정본,
   값은 consult·qna·biz·etc — 세 탭 값은 같은 파랑이지만 묶음 정보는 남겨 둔다). 칩 모양(크기·면·글자)은 client.css .noti-kind ·
   noti-panel.css .np .noti .noti-kind가 갖고, 여기는 색만 --kind-bg/--kind-ink로 넘긴다(사용자 지정 속성이라 무게 싸움이 없다).
   🔴 읽은 줄도 칩 색은 그대로다 — 가라앉는 것은 제목 글자(grey600)뿐. 줄마다 파란 점은 금지(P-067).
     탭 유형(consult·qna·biz) = 파랑 틴트 #E8F3FF 위 #1B64DA (4.82:1 — «내 차례» 칩과 같은 쌍)
     그 밖(etc)               = 회색     #F2F4F6 위 #4E5968 (6.4:1)
   🔴 초록·보라·빨강·웜을 더하지 마라. 새 유형은 NotificationTabs에만 등록한다. */
.noti-kind[data-tone="consult"], .noti-kind[data-tone="qna"], .noti-kind[data-tone="biz"] { --kind-bg: var(--primary-light); --kind-ink: var(--primary-pressed); }
.noti-kind[data-tone="etc"] { --kind-bg: var(--grey100); --kind-ink: var(--grey700); }

/* Presence dot */
.dot-presence { width: 10px; height: 10px; border-radius: var(--r-full); display: inline-block; }
.dot-online { background: var(--presence-online); }
.dot-away { background: var(--presence-away); }
.dot-busy { background: var(--presence-busy); }
.dot-offline { background: var(--presence-offline); }

/* Hero (홈 상단 — 앱 히어로 톤) */
.hero {
  background: linear-gradient(135deg, #3182F6, #1B64DA);
  color: #fff; border-radius: var(--r-xl);
  padding: 40px 32px; margin-top: var(--s-2xl);
}
.hero h1 { font-size: 32px; font-weight: 700; line-height: 1.3; }
.hero p { margin-top: 10px; font-size: 16px; color: rgba(255,255,255,.88); }
.hero .btn { margin-top: 24px; background: #fff; color: var(--primary); }
.hero .btn:hover { background: #f0f6ff; }

/* Feature grid */
.grid { display: grid; gap: var(--s-lg); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.feature .ic {
  width: 44px; height: 44px; border-radius: var(--r-md);
  background: var(--primary-light); color: var(--primary);
  display: flex; align-items: center; justify-content: center; font-size: 22px; margin-bottom: 12px;
}
.feature h3 { font-size: 17px; font-weight: 700; }
.feature p { margin-top: 4px; font-size: 14px; color: var(--text-tertiary); }

/* Section */
.section { margin-top: var(--s-3xl); }
/* 지면 맨 위 맨 h2(아직 .pg-head로 옮기지 않은 지면)도 페이지 머리 제목(.pg-title)과 **같은 값**이다(D-880, P-075) —
   title1 토큰(24/32 · ≥768 28/38 · 600 · --ls-22) · #191F28 · balance. 값은 아래 .pg-title 규칙 한 곳에서 함께 정한다. */
.section > h2 { margin-bottom: var(--s-lg); }

/* Footer */
.site-footer { margin-top: 64px; border-top: 1px solid var(--border); background: var(--surface-alt); }
.site-footer .inner { padding: 28px 0 40px; color: var(--text-tertiary); font-size: 13px; }
.site-footer a { color: var(--text-secondary); }

/* ── 로그인 (D-165) ────────────────────────────────────────────────────────
   참고 지면 accounts.yanolja.com 실측(1280×720):
     배경 #F2F2F2(흰 카드 없음) · 칼럼 600px에 좌우 패딩 32 → 내용 폭 536
     버튼 536×52 · 흰 배경 · 테두리 1px #DADBDF · 모서리 16 · 글자 16/700 가운데
     버튼 간격 8 · 심볼 20×20(왼쪽 끝에서 17)
     로고 250×30 · 안내문 16/400/24 가운데 · 하단 고지 12/400

   ⚠ 색은 새로 만들지 않고 기존 토큰으로 맞춘다 — #F2F2F2→--surface-alt(#F2F4F6),
      #DADBDF→--border(#E5E8EB), 모서리 16→--r-lg. 눈에 안 보이는 차이다. */
.login-page {
  /* 🔴 **흰 배경이다**(D-704, 사용자 지시). 예전에는 `--surface-alt`(#F2F4F6) 회색 띠였다
     (D-165 — 참고 지면 accounts.yanolja.com을 그대로 옮긴 값).
     회색을 걷으면서 **셸 패딩을 되돌리던 음수 마진도 함께 걷었다**. 그 마진이 있던 이유는
     「회색 바탕이 화면을 가득 채우게」 하나뿐이었다 — 칠할 색이 흰색이면 되돌릴 것이 없다.
     그 마진이 남기던 부작용 셋도 함께 사라진다(전부 헤드리스 실측):
       ⓐ 하단 −64px이 `.shell-footer`를 8px 끌어올려, 푸터 헤어라인이 띠 **안쪽**에 그려졌다
          (띠 하단 y=813 vs 푸터 top y=805).
       ⓑ 모바일(≤768)에서 `margin-top:-24px` vs `.main`의 `padding-top:16px`이라 띠가 8px 위에서
          시작해 상단바 밑으로 들어갔다(불투명 상단바가 덮어 안 보였을 뿐이다 — y=48 vs 56).
       ⓒ `/login?app=1`(app-embed)에서 가로 스크롤이 났다. shell.css의 `.app-embed .main`이
          좌우 패딩만 0으로 만드는데 여기 `-shell-pad` 좌우 마진은 아무도 되돌리지 않아
          칼럼이 뷰포트를 31px 넘어갔다(실측 우측 끝 1471 > 1440).
     ⚠ `min-height`는 셸이 정한 «한 화면»(`--main-fill` = 100vh − 상단바 − 본문 위 패딩)을
       그대로 쓴다(D-736). 예전에는 88px(상 24 + 하 64)을 손으로 뺐는데, 셸이 본문 칸을 한
       화면으로 늘리기 시작한 뒤로는 그 값이 64px 모자라 로그인 카드 아래에 흰 띠가 남았다.
     ⚠ 좌우 패딩도 `--shell-pad`에서 0으로 내린다 — 이제 `.main`이 그 여백을 준다.
       여기서 한 번 더 주면 칼럼이 두 겹으로 안쪽으로 들어간다. */
  min-height: var(--main-fill, calc(100vh - var(--topbar-h) - 24px));
  display: flex; align-items: center; justify-content: center;
  padding: 32px 0;
  background: var(--background);
}
.login-col { width: 100%; max-width: 536px; text-align: center; }

/* 칼럼 맨 위 = **공식 가로 락업**(로그인 A안, D-885 · 사용자 결정 2026-10-01).
   예전엔 글자 «셈톡»(.login-word 30px · 폰 25px)만 두고 심볼을 뺐다(주석이 D-168로 인용) — 상단바에 같은
   로고가 있어 한 화면에 두 번 나왔기 때문이다. «한 화면에 로고 한 번»은 그대로 지킨다: 이제 로고는 칼럼이
   들고 /login 상단바 가운데 링크를 내린다(layout.html `hideTopBrand`). .login-word 규칙은 걷었다.
   🔴 잉크 창 계산(이미지 높이·창 너비·밀기 다섯 숫자)은 **shell.css `.brand-mark` 한 곳**이다. 여기에
      다시 쓰지 마라 — 자산이 바뀌면 한 곳만 고쳐져 로고가 잘린다. 여기서 주는 것은 `--brand-ink` 하나다
      (푸터 `.shell-footer .brand-mark { --brand-ink: 32px }`와 같은 방식).
   ⚠ 44px = 옛 글자 줄 높이(30px × 1.5 = 45px)와 거의 같아 칼럼 높이·오류 문구 자리가 그대로다.
     폰(≤768)은 36px — 아래 @media. 둘 다 가이드 최소 24px 위다.
   ⚠ 링크는 `display:flex` + `width: fit-content`로 세운다 — inline-flex로 두면 줄 상자의 글자 기준선 아래
     여백(몇 px)이 붙어 칼럼이 옛 높이보다 늘고, 링크가 칼럼 폭 전체를 먹지도 않는다(누를 자리 = 락업).
   ⚠ 로고 자체는 손대지 않는다(브랜드 가이드: 색 변형·회전·그림자 금지). */
.login-brand {
  display: flex; width: fit-content; margin: 0 auto;
  border-radius: var(--r-sm);              /* 키보드 링(아래 focus-visible)의 모서리 */
}
.login-brand:focus-visible { outline: 2px solid var(--primary); outline-offset: 4px; }
.login-brand .brand-mark { --brand-ink: 44px; }
.login-lead {
  margin: 18px 0 0; font-size: 16px; line-height: 1.5;
  letter-spacing: var(--ls-lg); color: var(--text-secondary);
}
.login-next {
  margin: 10px 0 0; font-size: 13.5px; line-height: 1.45;
  letter-spacing: var(--ls-md); color: var(--text-secondary);
}
/* 로그인 오류 두 문구(정지·실패) — 채움 없는 13.5px --error 글자 하나(D-880, P-070 (가)).
   🔴 오류 빨강은 --error 토큰 하나다. 새 빨강 값(#c53037·#DC2626 같은)을 만들지 마라 — 서비스에 오류 빨강이
      넷이던 것을 하나로 모았다. 칩 글자용 --tint-red-ink는 칩 전용이다(오류 글자에 쓰지 않는다).
   ⚠ 상태는 글자가 먼저 말한다(role=alert는 템플릿에 그대로). */
.login-error {
  margin: 12px 0 0; padding: 0; background: none;
  font-size: 13.5px; line-height: 1.5; color: var(--error);
}

.login-sns { display: flex; flex-direction: column; gap: 8px; margin-top: 36px; }
/* 네 버튼은 높이·모서리·글자 크기를 한 규칙으로 그린다(D-165).
   Q-132: **카카오만** 공식 노랑(--kakao)으로 살린다. 첫 행동이 보이게.
   네이버·구글·애플은 흰 버튼. 심볼은 각 사 공식 아트워크 그대로. */
/* 🔴 테두리를 `--border`(#E5E8EB)에서 `--grey300`(#D1D6DB)로 한 단 올렸다(D-704).
   바탕이 흰색이 되면서 흰 버튼 셋(네이버·구글·애플)의 **면 대비가 사라졌기** 때문이다 —
   회색 띠 위에서는 면만으로 1.10:1이 났지만 흰 바탕에서는 1.00:1, 즉 버튼임을 말하는 것이
   1px 테두리 하나뿐이 된다. 실측: #E5E8EB 1.23:1 → #D1D6DB **1.46:1**.
   ⚠ 3:1(WCAG 1.4.11 비텍스트 대비)에 닿으려면 `--grey500`(#8B95A1, 3.04:1)이라야 한다.
     그건 로그인 첫 화면에 놓기엔 확연히 무거워서 «한 단만» 올렸다 — 대신 hover를 그 값으로
     두어, 만질 수 있는 것임을 손이 닿는 순간 확실히 말한다.
   ⚠ 카카오 버튼은 아래 `.login-btn-kakao`가 테두리를 노랑으로 덮는다(공식 가이드) — 이 값이
     카카오에는 닿지 않는다.
   글자 = label1(16/22/600/+.01em — 큰 버튼 48~56px, 타이포그래피 C1 · D-890, REQUEST §3-3). C1 전엔 16/700/−.3px(--ls-lg)였다.
     폰(≤768)도 16 그대로다(아래 @media — 15px 변형을 걷었다. 320에서도 네 문구가 한 줄, 실측). 값은 리터럴 — 토큰은 C2.
     🔴 700 굵기·음수 px 자간을 되돌리지 마라(LoginTypeScaleContractTest). */
.login-btn {
  position: relative; display: flex; align-items: center; justify-content: center;
  height: 52px; border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--grey300);
  color: var(--text-primary); font-size: 16px; line-height: 22px; font-weight: 600;
  letter-spacing: .01em;
  transition: background .15s ease, border-color .15s ease;
}
.login-btn:hover { background: var(--grey50); border-color: var(--grey500); }
.login-btn:active { background: var(--grey100); }
.login-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* 카카오 공식 버튼색. 노랑 위 글자는 --kakao-text(#191919).
   hover는 노랑을 조금만 눌러 버튼임이 보이게 — 색을 바꾸면 가이드를 깬다. */
.login-btn-kakao {
  background: var(--kakao); border-color: var(--kakao); color: var(--kakao-text);
}
.login-btn-kakao:hover { background: #F5DC00; border-color: #F5DC00; }
.login-btn-kakao:active { background: #E8D000; border-color: #E8D000; }
/* 심볼은 글자와 **같이 흐르지 않는다** — 왼쪽에 고정해야 네 버튼의 글자가 모두 같은
   자리(가운데)에서 시작한다. 문구 길이가 달라도 줄이 흔들리지 않는다. */
/* ⚠ 네 심볼은 **상자 크기가 아니라 잉크(실제 그림) 높이**를 맞춰야 같아 보인다(D-168).
   같은 20px 상자에 넣었더니 각 로고가 캔버스를 채우는 정도가 달라 크기가 제각각으로 보였다
   — 실측 세로 채움률: 카카오 89% · 네이버 100% · 구글 98% · **애플 70%**.
   애플이 유독 작아 보인 건 상자가 작아서가 아니라 로고 주변 여백이 커서다.
   그래서 잉크 높이가 모두 **약 18px**이 되도록 상자만 개별로 키우고 줄인다.
   ⚠ 로고 자체(파일)는 손대지 않는다 — 각 사 공식 아트워크라 잘라내거나 늘리면 안 된다. */
.login-ic {
  position: absolute; left: 17px; top: 50%; transform: translateY(-50%);
  display: block; object-fit: contain;
  width: 20px; height: 20px;
}
/* 아래 주석의 잉크 높이는 **브라우저에 그려진 것을 캔버스로 잰 실측값**이다(파일을 트림해
   구한 값과 다르다 — 구글은 파일 기준 98%였지만 실제로는 93%로 그려진다). 값을 고칠 땐
   눈대중이 아니라 같은 방식으로 다시 재라. */
.ic-kakao  { width: 20px; height: 20px; }   /* 잉크 18.3px */
.ic-naver  { width: 18px; height: 18px; }   /* 잉크 18.0px */
.ic-google { width: 19px; height: 19px; }   /* 잉크 17.6px — 18px에선 16.7px로 혼자 작았다 */
.ic-apple  { width: 26px; height: 26px; }   /* 잉크 17.9px — 로고 여백이 커서 상자만 크다 */

/* ⚠ `--text-tertiary`를 쓰지 마라. 회색 바탕(--surface-alt) 위에서 대비가 **4.2:1**이라
   12px 본문 기준(4.5:1)에 미달한다(실측). 약관 동의 고지는 특히 읽혀야 하는 글이다.
   참고 지면도 이 문구를 거의 검정(rgb(27,28,31))으로 쓴다.
   글자 = caption2(12/18/500/+.02em — 법적 고지, 최소 크기. 타이포그래피 C1 · D-890). C1 전엔 12/1.6/400/body −.2px였다. */
.login-legal {
  margin: 22px 0 0; font-size: 12px; line-height: 18px; font-weight: 500; letter-spacing: .02em; color: var(--text-secondary);
}
/* 밑줄이 글자 바닥에 닿지 않게 3px 띄우고 1px로(타이포 점검 2026-10-03 F11). */
.login-legal a { color: var(--text-primary); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }

@media (max-width: 768px) {
  /* 높이는 `--main-fill`이 알아서 따라온다(셸이 좁은 화면에서 --main-pad-t를 16px로 내린다).
     좌우는 `.main`이 16px을 주므로 여기서는 0이다(base와 같은 이유). */
  .login-page { padding: 16px 0; }
  /* 폰 락업 잉크 36px(로그인 A안) — 상단바 로고(24px)보다 또렷하다. 창 계산은 shell.css 그대로다. */
  .login-brand .brand-mark { --brand-ink: 36px; }
  .login-lead { font-size: 15px; }
  .login-sns { margin-top: 28px; }
  .login-btn { height: 50px; }   /* 글자는 label1 16 그대로(C1 전 15px 변형은 걷었다 — 320에서도 한 줄) */
}
/* ── 입력 칸 한 문법 (D-880, P-076 1-(가)·3-(가)) ────────────────────────────────────────
   흰 바탕 · 1px #D1D6DB(grey300) · 모서리 10px. 포커스는 2px #3182F6 + 바깥 3px rgba(49,130,246,.2) 링,
   잠김은 #F2F4F6 채움 + #6B7684 글자, 오류 칸 테두리는 오류 토큰 --error(P-070).
   🔴 회색 채움(#F2F4F6)을 «적을 칸»에 쓰지 마라 — 채워진 바탕은 어디서나 «잠김» 신호다(D-243이 상담노트에서
      먼저 버린 이유). 예전엔 같은 회색이 상담노트에서는 잠김, 다른 지면에서는 적을 칸이었다. 검색 칸도 흰 칸이다(3-(가)).
   ⚠ 포커스 2px는 **1px 테두리 + 안쪽 1px 그림자**로 그린다 — 테두리를 2px로 키우면 글자가 1px 밀려 지면마다
     padding을 따로 깎아야 했다(옛 .br-page 규칙). 이 방식은 칸 크기·글자 자리가 그대로다.
   ⚠ 지면 CSS가 이 칸의 바탕·테두리를 다시 칠하지 마라(옛 .br-page .input·.ob-fld .input·.cb-d .cb-form .input·
     .ct-party-rw .input 덮어쓰기를 걷었다). 크기(높이·글자)만 지면이 정한다. */
.input {
  width: 100%; height: 48px; padding: 0 14px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--grey300); font-size: 15px; color: var(--text-primary);
}
.input:focus, .input:focus-visible {
  outline: none; border-color: var(--primary); background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--primary), 0 0 0 3px rgba(49, 130, 246, .2);
}
.input:disabled { background: var(--grey100); color: var(--grey600); border-color: var(--border); cursor: not-allowed; opacity: 1; }
.input.is-err, .input[aria-invalid="true"] { border-color: var(--error); }
/* 여러 줄 칸 — 전역에서 48px 못을 푼다(옛 client.css 한 곳에만 있던 보정). ⚠ `:where()`로 명시도를 .input과 같게
   (0,1,0) 낮췄다 — 지면의 `.ct-area`·`.iw-ta-tall` 같은 클래스 하나짜리 높이 규칙이 뒤에 실려 그대로 이긴다. */
.input:where(textarea) { height: auto; min-height: 132px; padding: 12px 14px; resize: vertical; line-height: 1.6; }

/* ── 사진 고르기 상자 (.pc-drop, D-809 → 전역 D-880 P-076 2-(나)) ───────────────────────────
   사례 노트 드롭존(cases-write.css .cw-drop)과 같은 문법. 세무사 사진 패널(photo-crop.js)·의뢰인 프로필 사진·후기 사진
   (pick-drop.js)이 이 한 벌을 쓴다. 네이티브 [파일 선택]은 JS 전에만 보인다(무JS면 상자 안 기본 칸).
   🔴 파일 칸을 브라우저 기본 모양 그대로 드러내지 마라 — 새 파일 칸은 이 상자로 감싼다. */
.pc-drop {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 3px;
  border: 1.5px dashed var(--border); border-radius: 14px; padding: 16px 14px 14px; margin-bottom: 12px;
  text-align: center; background: var(--grey50);
}
.pc-drop.over, .pc-drop:focus-within { border-color: var(--primary); }
.pc-drop.over { background: var(--primary-light); }
.pc-drop-t { font-size: 13.5px; font-weight: 600; color: var(--text-primary); }
.pc-drop-s { font-size: 12px; color: var(--text-tertiary); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 무JS의 네이티브 입력 — 그대로 보이되 [파일 선택] 버튼만 카드 결로(::file-selector-button). */
.pc-file { display: block; margin: 8px auto 0; max-width: 100%; font-size: 12px; color: var(--text-tertiary); }
.pc-file::file-selector-button {
  border: 1px solid var(--border); background: var(--surface); color: var(--text-primary);
  font: inherit; font-size: 12.5px; font-weight: 600; border-radius: 10px; padding: 8px 14px; margin-right: 10px; cursor: pointer;
}
.pc-file::file-selector-button:hover { background: var(--surface-alt); }
/* 표시 버튼 — JS가 없으면 숨는다(눌러도 아무 일 없는 버튼을 세우지 않는다). 히트는 상자 전체(투명 입력). */
.pc-drop-btn {
  display: none; height: 36px; padding: 0 14px; margin-top: 8px;
  align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  color: var(--text-primary); font-size: 13px; font-weight: 600;
}
.pc-drop.is-js .pc-drop-btn { display: inline-flex; }
.pc-drop.is-js .pc-file { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.pc-drop.is-js:hover .pc-drop-btn { background: var(--surface-alt); }
/* 파일을 고른 뒤 — 한 줄로 접힌다: 「이름.jpg」 + [다른 사진 고르기]. 무대가 아래에 열리므로 상자는 작아야 한다. */
.pc-drop.has-file { flex-direction: row; justify-content: center; gap: 12px; padding: 9px 12px; }
.pc-drop.has-file .pc-drop-t { display: none; }
.pc-drop.has-file .pc-drop-btn { margin-top: 0; height: 32px; font-size: 12.5px; }
.pc-drop.has-file .pc-drop-s { flex: 0 1 auto; min-width: 0; }


/* Key-Value (마이) */
.kv { display: flex; gap: 16px; padding: 10px 0; border-bottom: 1px solid var(--divider); }
.kv:last-child { border-bottom: none; }
.kv .k { width: 72px; color: var(--text-tertiary); font-size: 14px; flex-shrink: 0; }
.kv .v { color: var(--text-primary); font-size: 15px; font-weight: 500; word-break: break-all; }

/* 세무사 카드(디렉토리·인기) */
/* 공용 목록 컨테이너(세무사·예약·견적 등 9개 화면이 함께 쓴다).
   본문이 전폭이 되면서(D-154) 한 줄짜리 목록은 **가운데가 텅 비었다** — 왼쪽에 이름,
   오른쪽 끝에 상태 배지, 사이에 1000px의 공백(실측). 폭을 도로 좁히는 대신 **넓어지면
   여러 열로 접는다** — 그게 공간을 실제로 쓰는 방법이고, 한 화면에 보이는 항목도 늘어난다.
   520px는 카드 한 장이 답답하지 않은 최소 폭이다(아바타+이름+사무소+한줄소개+별점+분야칩).
   좁은 화면에서는 자동으로 1열이 되므로 기존 모습 그대로다. */
.tax-list {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(520px, 1fr));
  gap: 12px; margin-top: var(--s-lg);
}
@media (max-width: 560px) { .tax-list { grid-template-columns: 1fr; } }

/* ══════════════════════════════════════════════════════════════════════════
   세무사 지도(/directory/map) 조작부 — D-248 필터바(검색 + 지역 2단 드롭다운 + 분야 복수선택 드롭다운).
   옛 목록(/directory)의 적용 칩·결과 줄·리스트형 행(.tax-row·.tr-*)·번호식 페이지네이션·[지도|목록] 스위치는
   목록 뷰와 함께 걷었다(D-880, 사용자 지시 «항상 지도로만») — 지도 옆 패널이 유일한 목록이다. */

/* ── 필터바 ── */
.dir-filters { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 20px 0 4px; position: relative; }
.dir-search { display: flex; gap: 8px; flex: 1 1 240px; min-width: 200px; margin: 0; }
.dir-search .input { flex: 1; min-width: 0; }

/* 드롭다운(지역·분야) — <details>로 여닫는다(JS 없이도 열린다). */
/* ⚠ 패널의 기준은 버튼이 아니라 **조작 줄**이다(.dir-filters가 relative) — 버튼 기준
   right:0은 모바일(버튼이 화면 중간)에서 왼쪽이 잘린다(실측). 줄 기준이면 양끝이 안전하다. */
.dir-facet, .dir-facet-d { position: static; margin: 0; }
.dir-facet-btn {
  list-style: none; cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 14px;
  border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface);
  font-size: 14px; font-weight: 600; color: var(--text-primary); white-space: nowrap;
}
.dir-facet-btn::-webkit-details-marker { display: none; }
.dir-facet[open] > .dir-facet-btn, .dir-facet-d[open] > .dir-facet-btn {
  border-color: var(--primary); color: var(--primary);
}
.dir-caret { font-size: 10px; color: var(--text-tertiary); }
/* 🔴 오른쪽 끝 정렬(사용자 실측 D-470) — 지역·분야 버튼은 조작 줄의 **오른쪽 끝**에 산다.
   left:0(버튼 왼끝 기준, 오른쪽으로 펼침)이면 460px 지역 패널·분야 패널의 오른쪽이
   뷰포트 밖으로 잘려 구 칩·분야 체크가 안 보였다. 버튼의 오른끝에 맞춰 왼쪽으로 펼친다. */
.dir-facet-pop {
  position: absolute; z-index: 30; top: calc(100% + 6px); left: auto; right: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: 0 12px 32px rgba(20, 36, 61, .16); padding: 12px;
}

/* 지역 2단(시/도 좌 · 구 칩 우) */
.dir-region-pop { display: grid; grid-template-columns: 140px 1fr; gap: 12px; width: 460px; max-width: calc(100vw - 40px); }
.dir-region-sido {
  display: flex; flex-direction: column; gap: 2px;
  max-height: 300px; overflow-y: auto; border-right: 1px solid var(--border); padding-right: 8px;
}
.dir-region-opt { padding: 8px 10px; border-radius: var(--r-sm); font-size: 14px; color: var(--text-secondary); cursor: pointer; white-space: nowrap; }
.dir-region-opt:hover { background: var(--surface-alt); }
.dir-region-opt.on { background: var(--primary-light); color: var(--primary-pressed); font-weight: 700; }
.dir-region-gu { display: flex; flex-wrap: wrap; gap: 6px; align-content: flex-start; max-height: 300px; overflow-y: auto; }
.dir-region-gu-chip { padding: 6px 10px; border-radius: var(--r-full); background: var(--surface-alt); font-size: 13px; color: var(--text-secondary); cursor: pointer; border: 1px solid transparent; }
.dir-region-gu-chip:hover { background: var(--primary-light); color: var(--primary); }
.dir-region-gu-chip.on { background: var(--primary-light); border-color: var(--primary); color: var(--primary-pressed); font-weight: 700; }
.dir-region-hint { color: var(--text-tertiary); font-size: 13px; padding: 8px; }

/* 분야 복수 선택 */
.dir-spec-pop { display: flex; flex-direction: column; gap: 2px; width: 220px; max-width: calc(100vw - 40px); }
.dir-check { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: var(--r-sm); font-size: 14px; color: var(--text-primary); cursor: pointer; }
.dir-check:hover { background: var(--surface-alt); }
.dir-check input { width: 16px; height: 16px; accent-color: var(--primary); }
.dir-facet-actions { margin-top: 6px; padding-top: 8px; border-top: 1px solid var(--border); text-align: right; }

/* 좁은 화면 — 지역 2단 패널의 시·도 칸을 줄이고 패널을 화면 폭에 맞춘다. */
@media (max-width: 768px) {
  .dir-region-pop { grid-template-columns: 110px 1fr; width: calc(100vw - 40px); }
}

.tax-card { display: flex; gap: 14px; align-items: flex-start; }
.tax-card:hover { border-color: var(--grey300); }
.avatar {
  width: 56px; height: 56px; border-radius: var(--r-lg); flex-shrink: 0;
  background: var(--surface-alt); object-fit: cover;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 20px; color: var(--primary);
}
.avatar-sm { width: 44px; height: 44px; font-size: 16px; border-radius: var(--r-md); }
.tax-main { flex: 1; min-width: 0; }
.tax-name-row { display: flex; align-items: center; gap: 8px; }
.tax-name { font-size: 17px; font-weight: 700; }
.badge {
  font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: var(--r-full);
  background: var(--primary-light); color: var(--primary);
}
/* 답변대기 등 '아직 처리 전' 상태 배지. */
.badge-pending { background: #FFF3E8; color: #C2410C; }
.tax-sub { margin-top: 3px; font-size: 13px; color: var(--text-tertiary); }
.tax-rating { margin-top: 4px; font-size: 13px; color: var(--text-secondary); }
.tax-rating .star { color: var(--rating-star); }   /* 관리자 광고 미리보기(admin-ad-preview.js) — 평점 별 노랑(사용자 요청 2026-10-08 · D-915) */
/* 글자 별 «★» 한 클래스 — 별 글자를 점수와 따로 감싼 자리(관리자 광고 목록 · 옛 홈 카드 .pf-card · 지도 광고 레일 .dad-*)가 쓴다.
   점수·후기 수 글자색은 부모 그대로(평점 별 노랑(사용자 요청 2026-10-08 · D-915)). */
.rating-star { color: var(--rating-star); }
.spec-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.spec { font-size: 12px; padding: 3px 8px; border-radius: var(--r-sm); background: var(--primary-light); color: var(--primary); }
.presence { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-tertiary); }

/* 필터 바 */
.filter-bar { display: flex; gap: 8px; margin: 16px 0; flex-wrap: wrap; }
.filter-chip {
  padding: 8px 16px; border-radius: var(--r-full); background: var(--surface-alt);
  /* 켜질 때 테두리가 생겨도 칸이 밀리지 않게 자리를 미리 잡아 둔다(border-box라 높이 불변). */
  border: 1px solid transparent;
  font-size: 14px; font-weight: 600; color: var(--text-secondary);
}
/* 켜진 칩 — **색만으로 구분하지 않는다**(§7 관례): 테두리·굵기를 함께 바꾼다.
   ⚠ 예전의 파랑 바탕 + 흰 글자(#fff on #3182F6)는 대비 3.7:1로 14px 본문 기준(4.5:1)
     미달이었다(실측). 지금 조합(--primary-pressed #1B64DA on --primary-light #E8F3FF)은
     4.8:1로 통과한다 — 색을 바꾸면 같은 방식으로 다시 재라. */
.filter-chip.on {
  background: var(--primary-light); border-color: var(--primary);
  color: var(--primary-pressed); font-weight: 700;
}
/* 검색바 — 제목과 필터 사이에서 **숨 쉴 자리**를 준다(사용자 지적: "여백이 너무 없는 느낌").
   아래 필터 줄이 margin-top:12px이라 8px만 두면 검색·지역·분야가 한 덩어리로 붙어 보였다. */
.search-box { display: flex; gap: 8px; margin-top: 20px; margin-bottom: 20px; }
.search-box input { flex: 1; }

/* ── 세무사 지도 조작부 (D-189) ──────────────────────────────────────────────
   조각: templates/fragments/directory-controls.html — /directory/map이 쓴다(옛 /directory 목록은 걷었다).
   새 디자인 언어를 만들지 않는다: 칩은 위 `.filter-chip` 그대로, 버튼은 `.btn` 그대로다. */

/* 필터 한 줄 — [라벨] [입력·칩들] [더보기]. 시·도 18개 + 분야 10개를 그냥 늘어놓으면 좁은 화면에서
   세 줄을 먹어 정작 목록이 화면 밖으로 밀린다(§3.4, 사용자 지적). */
/* position:relative는 장식이 아니다 — 이 줄 안의 눈에 안 보이는 요소들(.chip-more-cb·.sr-only)이
   position:absolute라, 기준 조상이 없으면 페이지 왼쪽 위 구석으로 날아가 남의 자리에 겹친다. */
/* 라벨 한 칸 + 칩 묶음 한 칸. 칩은 자기들끼리 줄바꿈하고 라벨은 **첫 줄에 고정**된다 —
   예전처럼 같은 flex 줄에 섞어 두면 칩이 넘칠 때 라벨이 칩 사이로 밀려 들어간다. */
.filter-row { position: relative; display: flex; align-items: flex-start; gap: 10px; margin-top: 14px; }
.filter-lab {
  flex: none; width: 34px; height: 36px; display: inline-flex; align-items: center;
  font-size: 13px; font-weight: 600; color: var(--text-tertiary);
}
.filter-chips { display: flex; flex-wrap: wrap; gap: 8px; min-width: 0; }
/* 칩 높이를 못 박는다 — 아래 한 줄 접기(max-height)가 **정확히 한 줄**이어야 해서,
   글꼴이 바뀌어 높이가 1~2px 달라지면 둘째 줄 윗머리가 삐져나온다. */
.filter-row .filter-chip { display: inline-flex; align-items: center; height: 36px; padding: 0 14px; }

/* ── 필터 묶음 (사용자 지시 2026-08-09) — 지역·분야·정렬 세 줄을 한 영역으로 ──────────
   라벨 열(지역/분야/정렬, 34px)이 나란히 서고 칩 크기(36px)·간격(8px)은 세 줄이 같다.
   지역 17개가 두세 줄로 쏟아지던 것을 **한 줄 가로 스크롤 + 오른쪽 끝 페이드**로 눕혔다.
   · D-129("모든 지역 이름이 버튼으로")는 그대로다 — 접기·셀렉트가 아니라 같은 버튼 전부가
     한 줄로 이어질 뿐이다. [더보기] 접기를 다시 쓰지 않은 이유: 한때 접었다가 걷어낸 이력이
     있고(directory.html 주석), 접으면 무엇이 더 있는지 아예 안 보인다 — 페이드는 계속을
     말해 준다. 지역·분야가 **같은 규칙**을 쓴다(한 화면 두 규칙 금지, 기존 원칙 유지).
   · 고른 칩이 스크롤 밖에 숨지 않게 directory.js가 첫 화면에서 끌어온다(JS 없어도 스크롤로
     닿는다). 새 문구는 없다(P5). */
.filter-panel { margin-top: 6px; }
.filter-panel .filter-row { margin-top: 10px; align-items: center; }
/* 위아래 4px는 초점 테두리 자리다 — overflow가 걸리면 칩 밖 outline이 잘린다.
   왼쪽도 같은 이유로 4px 주되 음수 마진으로 당겨 라벨 열과 칩 첫 글자를 맞춘다.
   오른쪽 끝 페이드는 mask로 그린다 — 안쪽 padding-right(32px)가 페이드 구간(28px)보다
   넓어서, 끝까지 스크롤하면 빈 여백이 흐려질 뿐 마지막 칩은 또렷하다. */
.filter-panel .filter-chips {
  flex-wrap: nowrap; overflow-x: auto; padding: 4px 32px 4px 4px; margin-left: -4px;
  scrollbar-width: none; -ms-overflow-style: none;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}
.filter-panel .filter-chips::-webkit-scrollbar { display: none; }
/* 스크롤로 왼쪽이 잘려 있으면(JS가 data-scrolled를 켠다) 왼쪽 끝도 흐려 "이쪽에도 더 있다"를
   알린다. 정지 상태(scrollLeft 0)에는 안 켠다 — 첫 칩이 이유 없이 흐려 보이면 안 된다. */
.filter-panel .filter-chips[data-scrolled] {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);
}
.filter-panel .filter-chip { flex: none; }
/* 정렬 줄(공용 조각 .sort-bar)을 위 두 줄과 같은 간격으로 — 라벨 폭은 .sort-lab이 맞춘다. */
.filter-panel .sort-bar { margin: 10px 0 0; }

/* 목록 조각을 받아 오는 동안 (dir-filter.js, 사용자 지시 2026-08-09) ─────────────
   필터를 눌렀는데 아무 표시가 없으면 눌린 건지 알 수 없어 같은 칩을 또 누르게 된다.
   ⚠ **0.15초 늦게** 흐려진다(transition-delay). 대부분의 응답은 그보다 빨라서, 지연이 없으면
     누를 때마다 화면이 번쩍인다 — 느릴 때만 보이는 표시가 목적이다.
   ⚠ 자리(높이)는 그대로 두고 투명도만 낮춘다. 내용을 비우면 스크롤이 튀고, 방금 보던 카드가
     사라졌다 돌아오는 것처럼 보인다.
   ⚠ 클릭은 막지 않는다 — 기다리는 동안 다른 필터로 바꿀 수 있어야 한다(마지막 요청만 반영). */
[data-dir-results] { transition: opacity .12s ease; }
[data-dir-results][aria-busy="true"] { opacity: .5; transition-delay: .15s; }
@media (prefers-reduced-motion: reduce) {
  [data-dir-results] { transition: none; }
}

/* 옛 .region-form·.region-select(회색 채움 알약 select)는 쓰는 템플릿·스크립트가 없어 걷었다(3차 정리 X1 — 칸은 전역 .input 한 문법). */

/* 옛 «고른 값 칩»(.chip-x — 글자 ✕로 푸는 칩)은 쓰는 템플릿·스크립트가 없어 걷었다(3차 정리 — 닫기 ✕는 선 아이콘). */

/* 한 줄만 보이는 칩 묶음 + [더보기].
   ⚠ 토글을 **CSS 체크박스**로 한 이유: JS로 접었다 폈다 하면 스크립트가 죽었을 때 나머지 분야로
     갈 길이 아예 사라진다. 체크박스는 눈에 안 보이되 초점은 받으므로 키보드로도 열린다. */
.chip-clamp {
  flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 8px;
  overflow: hidden; max-height: 36px;
}
.chip-more-cb {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.chip-more-cb:checked ~ .chip-clamp { max-height: none; }
.chip-more {
  flex: none; align-self: flex-start; padding: 9px 4px;
  font-size: 13px; font-weight: 600; color: var(--primary); cursor: pointer; white-space: nowrap;
}
.chip-more .m-close { display: none; }
.chip-more-cb:checked ~ .chip-more .m-open { display: none; }
.chip-more-cb:checked ~ .chip-more .m-close { display: inline; }
/* 체크박스가 안 보이므로 초점 테두리를 라벨에 대신 그린다 — 안 그리면 키보드 사용자가
   지금 [더보기]에 와 있다는 걸 알 방법이 없다. */
.chip-more-cb:focus-visible ~ .chip-more { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: var(--r-sm); }

/* 정렬 칩 (§3.3) — 켜진 칩은 **실제로 적용된 정렬**이다. '가까운순'은 위치를 받은 뒤에만 켜진다. */
.sort-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: var(--s-lg) 0 4px; }
/* 폭 34px은 .filter-lab과 같은 값이다 — 필터 묶음 안에서 세 줄의 라벨 열이 나란히 선다. */
.sort-lab { flex: none; width: 34px; font-size: 13px; font-weight: 600; color: var(--text-tertiary); }
.sort-bar .sort-chip { display: inline-flex; align-items: center; height: 36px; padding: 0 14px; }
/* 위치를 못 받았을 때 "그래서 지금 무슨 순서인지"를 적는 줄 — 한 줄을 통째로 쓴다. */
.sort-note { flex-basis: 100%; margin: 2px 0 0; font-size: 13px; color: var(--text-tertiary); }
.sort-note[hidden] { display: none; }

/* 필터 묶음 바로 뒤에 광고 레일이 붙으면 제목이 칩에 닿는다 — 여백은 여기서 준다.
   레일 쪽(home.css .dad-sec)을 고치면 지도 화면까지 함께 벌어진다(거기는 이미 여백이 있다).
   (2026-08-09 필터 묶음 도입으로 이웃이 .filter-row → .filter-panel로 바뀌었다.) */
.filter-panel + .dad-sec { margin-top: var(--s-xl); }

/* 조건에 맞는 사람이 전부 위 광고 레일로 올라간 경우. */
.list-allads { margin-top: var(--s-lg); color: var(--text-tertiary); }

/* 눈에는 안 보이고 화면낭독기에만 읽히는 글 — 글자 없는 칸·버튼이 무엇인지 알려 준다. */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* 상세 */
.detail-cover { height: 120px; border-radius: var(--r-xl); background: linear-gradient(135deg,#3182F6,#1B64DA); }
.detail-head { display: flex; gap: 16px; align-items: center; margin-top: -28px; padding: 0 8px; }
.detail-head .avatar { width: 72px; height: 72px; border: 3px solid #fff; font-size: 26px; }
.product-row { display: flex; align-items: center; justify-content: space-between; padding: 14px 0; border-bottom: 1px solid var(--divider); }
.product-row:last-child { border-bottom: none; }
.price { font-weight: 700; color: var(--primary); }

/* 선택 칩 (체크박스·라디오 공용) — 분야·상담방식·전달대상 */
.choice-grid { display: flex; flex-wrap: wrap; gap: 8px; }

/* 고정가 카탈로그 라디오 (D-312) — 유형과 가격이 «한 몸»으로 읽히게 세로 2줄.
   가격을 chip 밖 캡션으로 빼면 어느 유형의 가격인지 시선이 왕복한다. */
.prov-catalog { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.prov-catalog-chip { width: auto; }
.prov-catalog-label { display: flex; flex-direction: column; gap: 2px; text-align: left; }
.prov-catalog-label b { font-size: 13px; }
.choice-chip { position: relative; display: inline-flex; align-items: center; padding: 9px 14px; border: 1px solid var(--border); border-radius: 999px; cursor: pointer; font-size: 14px; font-weight: 500; background: var(--surface); user-select: none; }
.choice-chip input { position: absolute; opacity: 0; pointer-events: none; }
/* 고른 칩 글자 --primary-pressed(primary-light 위 4.82:1 — --primary는 3.31:1, D-799 F-33 · Q-279 재개). 굵기는 700 → 600(design.md §2 — 700은 머리만). */
.choice-chip:has(input:checked) { border-color: var(--primary); color: var(--primary-pressed); background: var(--primary-light); font-weight: 600; }
/* 키보드 포커스 — 체크박스는 opacity:0이라 칩이 대신 링을 그린다(D-799 F-07). */
.choice-chip:has(input:focus-visible) { outline: 2px solid var(--primary); outline-offset: 2px; }
/* 상한(D-129)에 닿아 지금은 고를 수 없는 항목 — 눌리지 않는 이유를 눈으로 알려 준다. */
.choice-chip.is-locked { opacity: .45; cursor: not-allowed; }

/* 질문 칸 늘리기 (`[질문 추가]`, question-rows.js) — 견적요청서 작성·수정 화면이 쓴다.
   ⚠ 접두사가 `.qw-`인 것은 견적 위저드에서 온 이름이라서다. 위저드는 걷어냈지만(D-191 B4)
     이 부품은 견적요청서 화면이 **그대로 물려받아** 쓰고 있다 — 지우지 마라.
   ⚠ 지역 접기(.qw-region*)는 함께 지웠다: 지역을 아예 묻지 않게 됐다(Q-071 ⓒ). */
.qw-qlist { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.qw-qrow { display: flex; gap: 8px; align-items: center; }
.qw-qrow .input { flex: 1; min-width: 0; }
/* 지우기는 보조 동작이라 칸보다 조용하게 — 색은 올려놓을 때만 경고색으로 바뀐다.
   높이는 .input(48px)에 맞춘다 — 한 줄 안에서 위아래로 어긋나 보이지 않게. */
/* 안쪽은 인라인 SVG다(fragments/chat-icons :: close, 동적 생성분은 question-rows.js).
   전역 `svg{display:block}`이라 가운데 정렬은 버튼이 직접 해야 한다. */
.qw-qdel {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 44px; height: 48px; padding: 0;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); color: var(--text-tertiary); cursor: pointer;
}
.qw-qdel svg { width: 18px; height: 18px; }
.qw-qdel:hover { border-color: var(--error); color: var(--error); }
.qw-qadd {
  margin-top: 10px; padding: 9px 14px; border: 1px dashed var(--border); border-radius: var(--r-md);
  background: var(--surface); color: var(--text-secondary); font-size: 14px; font-weight: 600; cursor: pointer;
}
.qw-qadd:hover { border-color: var(--primary); color: var(--primary); }

/* ── 위저드에서 물려받은 부품 (D-191 B4에서 남긴 것) ─────────────────────────────
   견적 작성 위저드(D-188)는 걷어냈다. 아래는 그때 만든 부품 중 **지금도 화면이 쓰는 것**만
   남긴 것이다 — 이름의 `.qw-` 접두는 출신을 말할 뿐 위저드가 살아 있다는 뜻이 아니다.

     .qw-progress / .qw-progress-fill  견적요청서 작성 진행 바 (brief-new.html)
     .qw-opt*                          견적요청서 고르기 라디오 줄 (fragments/brief-picker.html)
     .qw-error                         본문 검증 문구 (brief-new.html)
     .qw-nav                           단계 이동 줄 배치 (brief-new.html의 `qw-nav br-nav`)
     .qw-in-fwd / .qw-in-back          단계 전환 애니메이션 (brief-write.js)

   ⚠ 함께 지운 것(소비처 0으로 실측): .qw-head · .qw-step · .qw-group(-lead) · .qw-reveal ·
     .qw-intro · .qw-bubble* · .qw-opts · .choice-chip.qw-unsure · .qw-hint ·
     [data-wizard-submit|tail|prev|next]. 되살릴 일이 생기면 CSS부터가 아니라 D-191을 먼저 뒤집어라.
   ⚠ 감추기는 JS가 `hidden` 속성으로만 한다. 여기서 `display:none`을 기본값으로 두면 JS가
     죽었을 때 화면이 영영 안 보인다(.ip 패널에서 겪은 함정과 같다 — annotate.css:143).
     대신 `[hidden]`이 author의 display 선언에 지지 않게 못박아 둔다 — 상자 단위는 brief.css가
     (`.br-step`·`.br-nav`·`[data-brief-*]`), 버튼 단위는 아래 `.qw-nav .btn[hidden]`이 맡는다.
   ⚠ 새 색·모서리·자간을 만들지 않는다. 전부 tokens.css의 값이다. */

/* 진행률 — 값은 JS가 채운다(마크업에 적지 않는다). */
.qw-progress {
  height: 6px; border-radius: var(--r-full); background: var(--surface-alt); overflow: hidden;
}
.qw-progress-fill {
  display: block; height: 100%; width: 0; border-radius: var(--r-full);
  background: var(--primary); transition: width .25s ease;
}

/* 고르는 줄 — 부제가 붙어 칩으로는 좁다. 카드 줄로 두고 상태는 칩과 같은 규칙으로 칠한다.
   ⚠ 라디오로 쓰는 곳(견적요청서 고르기)은 brief.css가 네모 표시를 동그라미로 바꾼다. */
.qw-opt {
  position: relative; display: flex; align-items: flex-start; gap: 10px; padding: 14px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); cursor: pointer; user-select: none;
}
.qw-opt input { position: absolute; opacity: 0; pointer-events: none; }
.qw-opt::before {
  content: ''; flex: none; width: 20px; height: 20px; margin-top: 1px;
  border: 1.5px solid var(--grey300); border-radius: 6px; background: var(--surface);
}
.qw-opt:has(input:checked) { border-color: var(--primary); background: var(--primary-light); }
/* 체크 표시는 인라인 data URI다 — 외부 파일을 하나 더 물지 않으려고. */
.qw-opt:has(input:checked)::before {
  border-color: var(--primary); background: var(--primary)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5 6.5 12 13 4.5'/%3E%3C/svg%3E")
    center / 13px no-repeat;
}
.qw-opt-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.qw-opt-title { line-height: 1.35; }
.qw-opt-desc { line-height: 1.45; }

/* 막힌 이유는 **그 자리에** 뜬다. 위로 올려 모아 두면 어느 칸이 문제인지 다시 찾아야 한다. */
.qw-error { margin-top: 8px; color: var(--error); font-weight: 500; }

/* 단계 이동 줄 — 폭 배분은 쓰는 쪽이 정한다(brief.css의 `.br-nav [data-brief-prev|next]`).
   🔴 아래 `[hidden]` 규칙을 지우지 마라. `.btn`이 `display:inline-flex`를 주는 순간 UA의
      `[hidden]{display:none}`을 이겨서, JS가 감춘 [이전]·[다음]이 계속 보인다
      (brief-write.js는 prevBtn/nextBtn을 `hidden` 속성으로만 여닫는다).
      줄 전체를 감추는 것은 brief.css의 `.br-nav[hidden]`이 맡는다. */
.qw-nav { display: flex; gap: 10px; }
.qw-nav .btn[hidden] { display: none; }

/* 단계 전환 애니메이션 (사용자 지시: "단계적으로 애니메이션되며 다음 단계로").
   ⚠ 들어오는 카드만 움직인다. 나가는 카드까지 겹쳐 보이려면 position:absolute로 자리를 겹쳐야
     하고, 그러면 컨테이너 높이가 순간 0이 되어 화면이 더 크게 튄다 — 전환을 부드럽게 하려다
     오히려 점프를 키우는 셈이다.
   ⚠ 방향이 상태를 말한다: 앞으로 갈 땐 아래에서 올라오고, [이전]은 위에서 내려온다. */
@keyframes qw-in-fwd {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes qw-in-back {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}
.qw-in-fwd  { animation: qw-in-fwd  200ms ease-out both; }
.qw-in-back { animation: qw-in-back 200ms ease-out both; }

@media (prefers-reduced-motion: reduce) {
  .qw-progress-fill { transition: none; }
  /* 움직임을 끄되 **보이기는 해야 한다** — both로 끝난 상태(opacity:1)에 머물게 0s로 준다.
     animation:none으로 지우면 from의 opacity:0이 남는 브라우저가 있다. */
  .qw-in-fwd, .qw-in-back { animation-duration: 0s; }
}

/* 예약 슬롯 선택 */
.slot-group { margin-top: 18px; }
.slot-group-label { font-weight: 700; margin-bottom: 10px; }
/* /book 시간 칩 격자(P-034) — 오전·오후 두 묶음(book.html이 걸러 두 번 그린다), 묶음 사이 10px.
   🔴 칸 수는 **3의 배수**다: 예약 단위가 20분 고정(D-787)이라 3칸이 한 시간이고, 그래야 같은 열에
      같은 분(:00·:20·:40)이 선다. 옛 flex-wrap은 칩 폭이 글자마다 달라(88~100px) 줄마다 열이 어긋났다.
      폭은 카드(.bk-picker)의 폭으로 고른다(@container) — 사이드바가 있는 화면과 없는 화면이 같은 뷰포트에서
      본문 폭이 다르다. 폰 390 = 3칸, 중간 = 6칸, 본문 전폭(1280 · 카드 안 약 970px) = 9칸.
      문턱은 칩 한 칸의 최소 폭(«오전 10:00» 15px 약 75px + 좌우 6px·테두리 = 약 89px)에서 셈했다 —
      6칸 = 89×6 + 8×5 ≈ 574 → 600, 9칸 = 89×9 + 8×8 ≈ 865 → 880. 문턱을 낮추면 칩 글자가 칸을 넘는다.
   ⚠ 예약 모달(tax-detail)의 칩은 .bw-chips 안이라 이 격자를 쓰지 않는다 — 칩 안쪽 여백·숫자 폭 규칙도
     .slot-grid 안으로만 좁혔다. 칩 표기(«오전 10:00»)와 고른 모양은 그대로다. */
.slot-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.slot-grid + .slot-grid { margin-top: 10px; }
.bk-picker { container-type: inline-size; container-name: bkpick; }
@container bkpick (min-width: 600px) { .slot-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
@container bkpick (min-width: 880px) { .slot-grid { grid-template-columns: repeat(9, minmax(0, 1fr)); } }
.slot-chip { position: relative; display: inline-flex; align-items: center; justify-content: center; min-width: 62px; padding: 10px 14px; border: 1px solid var(--border); border-radius: 10px; cursor: pointer; font-size: 15px; font-weight: 500; background: var(--surface); user-select: none; }
.slot-grid .slot-chip { min-width: 0; padding: 10px 6px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.slot-chip input { position: absolute; opacity: 0; pointer-events: none; }
.slot-chip:has(input:checked) { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); color: var(--primary); background: var(--surface-alt); font-weight: 700; }
/* 결제 기한 안내 두 줄(P-005) — 예약 창(tax-detail .bk-foot)과 /book이 같은 모양을 쓴다.
   1줄 13px grey700, «10분 안에»만 500 잉크 · 2줄 12px grey600(흰 바탕 4.6:1). 왼쪽 정렬. */
.pay-note { margin: 8px 0 0; text-align: left; line-height: 1.6; word-break: keep-all; }
.pay-note-l1 { display: block; font-size: 13px; color: var(--grey700); margin-bottom: 2px; }
.pay-note-l1 b { font-weight: 500; color: var(--text-primary); }
.pay-note-l2 { display: block; font-size: 12px; color: var(--grey600); }
.review-item { padding: 14px 0; border-bottom: 1px solid var(--divider); }
.review-item:last-child { border-bottom: none; }

/* 채팅 */
.chat-msgs { margin: 16px 0; min-height: 200px; display: flex; flex-direction: column; gap: 10px; }
.msg-row { display: flex; align-items: flex-end; gap: 6px; }
.msg-row.mine { flex-direction: row-reverse; }
.bubble { max-width: 72%; padding: 10px 14px; border-radius: var(--r-lg); font-size: 15px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: break-word; }
.bubble-peer { background: var(--surface-alt); color: var(--text-primary); border-top-left-radius: 4px; }
.bubble-mine { background: var(--primary); color: #fff; border-top-right-radius: 4px; }
.msg-time { font-size: 11px; color: var(--text-tertiary); margin-bottom: 2px; }
.chat-send { display: flex; gap: 8px; position: sticky; bottom: 12px; background: var(--background); padding-top: 8px; }
.chat-send input { flex: 1; }

/* ── 페이지 머리 한 부품 (D-880, P-075 1-(가)·2-(다)) ─────────────────────────
   의뢰인·세무사 지면이 **같은 머리 한 벌**을 쓴다: [뒤로 가기(.pg-back, 있을 때만)] → 제목 → 부제 한 줄,
   오른쪽에 행동 하나까지(.pg-head-act). 예전엔 사이드바를 옮겨 다닐 때마다 제목이 22·24·26·21·20px로 바뀌었다.
   🔴 제목은 **title1 토큰(24/32 · ≥768 28/38) · 600 · --ls-22 · #191F28 · balance** 한 값이다. 지면 CSS가 크기를 덮지 마라.
      (사용자 결정 2026-10-03 — 타이포 3단계 묶음 ①, 옛 22px/700/1.35/−0.4px · 보류값 22/30 걷음) audit §3 «22~26px 페이지 제목 → title1»·
      요청서 §3-3 «title1 = 화면 제목». 위계는 «화면 제목(title1) > 섹션 제목 > 카드 안 이름·제목»이다 — 지면 안 제목을 화면 제목보다
      크거나 같게 두지 마라(예외는 사용자 결정: 프리미엄 광고 카드 이름 · 세무시선 히어로 제목. 큰 숫자·금액은 num-lg 몫).
      ⚠ 아직 리터럴인 지면 안 제목 중 화면 제목과 같거나 큰 것(검증 실측)은 각 지면 묶음 몫이다 — 예약 티켓 .rsv-tk-who 25px
        (601~767에서 제목 24보다 큼, D-541) · 상담노트 질문 legend.iw-q 24/700(320~767 전부에서 제목 24와 같음 — 검증 실측).
   🔴 같은 머리를 베낀 세 곳 — 지도(content.css .page-head h1)·등록 레일(onboarding.css .ob-title)·상담노트 만들기(brief.css .br-title)는
      **같은 선언**이다(P-075 «한 값» — CrossShapeI1Test가 이 규칙 본문과 대조한다). 여기를 바꾸면 셋을 같은 PR에서 바꾼다.
   🔴 세무사 캡션(옛 .dash-cap «관리»·«상담»·«고객»)은 **모두 걷었다**(2-(다) — D-777의 «캡션 = 사이드바 묶음
      이름»을 뒤집음). 의뢰인 지면과 같은 제목 하나다 — 캡션을 되살리지 마라.
   ⚠ 무대 지면 셋(/fit 잉크 카드 D-605 · 세무사 프로필 머리 · 세무시선 본문)과 상담 채팅 패널 제목은 이 부품
     밖이다. 세무사 찾기 제목 위 여백(사용자 지시 2026-08-08)도 지면 값 그대로다.
   ⚠ 이름이 `.page-head`가 아니라 `.pg-head`인 이유: `.page-head`는 content.css가 이미 쓰고 있다. */
.pg-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap;
  margin-bottom: 16px;
}
/* 지면 탭 줄(fragments/page-tabs — 메뉴 개편, 사용자 결정 2026-10-10): 사이드바 한 줄이 든 두 지면 «내 상담노트 | 내 예약» · «세무 Q&A | 세무시선».
   진짜 링크(주소 그대로). 모양은 고객 관리 탭 바(provider.css .crm-tabs — 밑줄형)와 같은 결이고, 지면 안 갈래 칩(.seg 알약 트랙)과 갈라 둔다.
   글자는 탭 토큰 label1(16/22 · 600) — 꺼진 칸 --text-tertiary · 켜진 칸 --primary + 2px 밑줄. 눌리는 높이 44. */
.page-tabs {
  display: flex; gap: 2px; margin: 0 0 16px; overflow-x: auto; scrollbar-width: none;
  border-bottom: 1px solid var(--border);
}
.page-tabs::-webkit-scrollbar { display: none; }
.page-tab {
  flex: 0 0 auto; display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; margin-bottom: -1px;
  font-size: var(--fs-label1); line-height: var(--lh-label1); font-weight: var(--fw-semibold); letter-spacing: var(--ls-14);
  color: var(--text-tertiary); text-decoration: none; white-space: nowrap; border-bottom: 2px solid transparent;
}
.page-tab.on { color: var(--primary); border-bottom-color: var(--primary); }
.page-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
@media (hover: hover) and (pointer: fine) { .page-tab:not(.on):hover { color: var(--text-secondary); } }
.pg-head-main { min-width: 0; }
.pg-title { margin: 0; }
.pg-title, .section > h2 {
  font-size: var(--fs-title1); line-height: var(--lh-title1); font-weight: var(--fw-semibold); letter-spacing: var(--ls-22);   /* title1(옛 22/1.35/700/−0.4px) */
  color: var(--grey900); text-wrap: balance;
}
/* 부제는 «무엇을 하는 화면인지»를 당근 톤으로 한 줄. 규칙이 아니라 안내다.
   body2(14/22 · ≥768 15/24, 옛 14px/400/1.5) + pretty(끝줄에 한두 글자만 남기지 않는다). grey600 #6B7684 = 흰 바탕 4.62:1.
   🔴 지도 머리 부제(content.css .page-head p)도 같은 값이다(P-075). */
.pg-sub {
  margin: 6px 0 0;
  font-size: var(--fs-body2); line-height: var(--lh-body2); font-weight: var(--fw-regular); letter-spacing: var(--ls-14);
  color: var(--grey600); text-wrap: pretty;
}
/* 오른쪽 행동은 **하나**까지(모두 읽음 · 일정 추가 · 접속 상태 같은). 둘 이상이면 본문으로 내린다. */
.pg-head-act { flex: none; display: flex; align-items: center; gap: 8px; }

/* ── 뒤로 가기 한 부품 (D-880, P-074 (나)) ─────────────────────────────────────
   회색 글자 14px/500 #4E5968(흰 바탕 7.11:1) 앞에 16px 선 아이콘(svg, aria-hidden) — 사례 쓰기·세무시선 쓰기가
   쓰던 문법을 모든 지면으로. 마크업은 fragments/pg-back 한 벌이다(지면마다 svg를 베껴 쓰지 마라).
   🔴 라벨 = **가는 곳의 제목**(«고객 관리»·«내 계약»·«세무시선»·«김민수 세무사 사례 노트»·«김답변 세무사»).
      «목록으로»·«돌아가기»처럼 어디로 가는지 말하지 않는 낱말, 화살표 글자(←)·홑화살괄호(‹)는 쓰지 않는다
      (design.md 2절 특수문자 · 10절 기호 대조).
   🔴 출구는 **한 지면에 하나**다 — 머리의 뒤로 가기와 맨 아래 «…로 돌아가기» 버튼을 함께 두지 마라.
   ⚠ 누르는 영역은 세로 44px(padding 12px 0)이고 margin -12px 0이 보이는 간격을 그대로 둔다(design.md §4). */
.pg-back {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-start;
  padding: 12px 0; margin: -12px 0;
  font-size: var(--fs-label2); line-height: var(--lh-label2); font-weight: var(--fw-medium); letter-spacing: var(--ls-14);   /* label2 14/20/500(옛 리터럴 같은 값) */
  color: var(--grey700); white-space: nowrap;
  text-decoration: none;
}
.pg-back:hover { color: var(--text-primary); }
.pg-back svg { width: 16px; height: 16px; flex: none; }
/* 머리 앞에 설 때 — 제목과 8px. */
.pg-back + .pg-head, .pg-back + .pg-title { margin-top: 8px; }

/* ── 방향 선 아이콘 (3차 정리 통합 — 사용자 답 2026-09-28) ──────────────────────────
   마크업은 fragments/line-icons 한 벌(16px 선 1.8 · currentColor · aria-hidden) — 뒤로 가기 부품과 같은 문법이다.
   · .row-go — 줄 전체가 링크인 목록 줄의 끝(마이·계정·고객센터·공지·지도 패널 행·홈 배너 알약·관리 화면 바로가기).
     «누르는 줄» 신호라 연한 회색 grey400(#B0B8C1)이고 이름은 줄의 글자가 든다. 줄은 flex라 margin-left:auto로 끝에 붙는다.
   · .ic-dir — 이름(aria-label)이 붙은 방향 버튼(캐러셀·쪽 넘기기·채팅방 뒤로)의 안쪽. 색·크기·누름 영역은 버튼이 정한다.
   🔴 글자 기호(‹ › ← →)로 되돌리지 마라(design.md §2). 링크 끝 글자 꼬리(«전체 보기» 같은 것)에는 달지 않는다(P-051 — 글자만). */
.row-go { flex: none; width: 16px; height: 16px; margin-left: auto; color: var(--grey400); }
.ic-dir { flex: none; width: 16px; height: 16px; }

/* ── 720 기둥 (D-880, P-073 (나)) — 예약 상세·취소·완료 확인·의뢰인 프로필 편집.
   .rsv-col(내 예약)·.mn-col(후기 쓰기)·탈퇴 화면과 **같은 값**이다(D-739 «예약 흐름 전체가 한 폭»). 왼쪽 정렬.
   🔴 늘리지 마라 — 넓히는 만큼 티켓의 이름과 상태 칩 사이가 빈다(D-673이 목록에서 고친 증상). */
.pg-col { max-width: 720px; }

/* 요약 카드 줄 — 아이콘 칩 34 틴트 + 값 24 tabular + 이동 링크.
   ⚠ 값은 반드시 tabular-nums다. 비례폭 숫자로 두면 자동 갱신·페이지 이동마다 숫자 폭이
     달라져 카드가 미세하게 들썩인다. */
.sum-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(212px, 1fr)); }
.sum-card {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 16px; border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--border);
}
.sum-ic {
  width: 34px; height: 34px; flex: 0 0 34px; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary-light); color: var(--primary-pressed);
}
.sum-ic svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.sum-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sum-label { font-size: 13px; color: var(--text-tertiary); }
.sum-val { font-size: 24px; font-weight: 700; line-height: 1.25; letter-spacing: var(--ls-2xl); font-variant-numeric: tabular-nums; color: var(--text-primary); }
.sum-link { font-size: 13px; font-weight: 600; color: var(--primary); }

/* 흰 콘텐츠 카드 — 회색 지면(--shell-bg) 위에 서는 본문 판. */
.pg-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 20px;
}

/* 폭 — 값의 근거와 «전역 상한이 아닌 이유»는 tokens.css 주석에. */
.pg-panel { max-width: var(--panel-max); }
.pg-editor { max-width: var(--editor-max); }

/* Responsive */
@media (max-width: 720px) {
  .grid-3, .grid-2 { grid-template-columns: 1fr; }
  .site-header nav { display: none; }
  .hero { padding: 32px 22px; }
  .hero h1 { font-size: 26px; }
  /* 좁은 화면에서는 요약 카드도 한 줄에 하나 — 212px 두 칸이 들어가면 값이 잘린다. */
  .sum-grid { grid-template-columns: 1fr; }
}

/* ══ 서체 적용 (D-260) ══════════════════════════════════════════════════════
   서체는 Pretendard 한 벌이다 — 그 배경은 tokens.css의 서체 주석에 있다(D-363).
   여기는 **어디에 씌우는지**만 적는다. 목록을 늘릴 때는 그 주석을 먼저 읽어라. */

/* ── 제목 (D-271) — 전용 서체 없이 **크기 × 굵기**로 세운다 ────────────────
   🔴 잘난체 2를 걷어냈다(사용자 지시). 그 서체는 굵기가 한 벌뿐이라 ① 굵게 하면 브라우저가
      «가짜 굵게»를 덧그려 획이 뭉개지고(「제목이 두꺼워 보인다」로 돌아왔다) ② 19px 미만에서
      뭉개져 목록 카드 제목에는 못 썼다 — 결국 같은 위계가 지면마다 다른 얼굴이었다.

   ⚠ **여기서 font-family를 지정하지 않는다.** body의 산스(SemTalk Sans Round, D-890 — D-271 당시 Pretendard)를 그대로 물려받는다.
     제목임을 만드는 것은 서체가 아니라 **크기·굵기·자간**이고, 그 값은 각 지면 CSS에 이미 있다
     (`.sisun-article-title` 34px/800 · `.qna-question-title` 23px/700 …).
   ⚠ 그래서 예전의 `font-weight: 400 !important`도 함께 걷었다 — 그것은 «가짜 굵게»를 막으려던
     장치였고, 서체가 사라진 지금은 **제목을 도로 얇게 만드는 버그**일 뿐이다.
   ⚠ 제목을 더 세우고 싶으면 굵기를 800까지 올려라. (D-271 당시 Pretendard는 400·500·600·700 실제 굵기가
     있고 800은 700을 합성했다.) SemTalk Sans Round는 400·500·600 세 벌이고 550–1000 선언은 전부 600으로 그려져
     가짜 굵게가 없다 — 700·800 선언은 C2 토큰 정리 때 600으로 거둔다.

   🔴 이 자리에 새 «브랜드 제목 서체»를 다시 들이려거든 위 두 가지를 먼저 확인할 것:
      **굵기가 여러 벌인가 · 15px에서도 읽히는가.** 둘 중 하나라도 아니면 같은 일이 반복된다. */

/* ── 안내 — 우리가 말을 거는 자리 ────────────────────────────────────────────
   🔴 **여기서 font-family를 지정하지 않는다**(D-363). 예전엔 주아체를 입혔는데 사용자 지적으로
      걷어냈다: 자간이 넓어 같은 안내가 지면마다 다른 얼굴이었고, 가운뎃점 「·」처럼 **글리프가
      빠진 글자가 그냥 공백으로** 그려졌다(「세액 · 신고」가 「세액   신고」로 보였다).
   ⚠ 안내를 안내로 만드는 것은 서체가 아니라 **크기·색**이다. 그 둘만 남긴다. */

/* ① 홀로 서는 안내 — 화면에 이것 하나뿐일 때(빈 상태·결과 알림). 조금 커도 된다.
   ⚠ 의뢰인 지면 빈 상태(옛 .empty-box)·세무 Q&A 빈 상태(옛 .qna-empty)·관리자 빈 상태(옛 .adm2-empty)는 3차 정리(X4)에서
     아래 .empty 부품으로 옮겨 이 묶음에서 뺐다. 쓰는 곳이 없던 에디터 익명 안내(.ed-strip-anon)도 3차 정리 통합에서 걷었다. */
.page-flash {             /* 저장·승인 같은 결과 알림 — 글자의 정본(틀은 위 공통 플래시 슬롯 규칙) */
  font-size: var(--fs-body1);       /* body1 16/28(옛 15px/1.75 = 26.25px) — «안내 문단», 홀로 서서 body2보다 한 단 크다 */
  line-height: var(--lh-body1);
  font-weight: var(--fw-regular);
  letter-spacing: var(--ls-14);
  text-wrap: pretty;                /* 끝줄에 한두 글자만 남기지 않는다 */
}

/* ② 곁들이는 안내 — 제목·목록 옆에 붙는 한 줄(캡션 자리).
   ⚠ 본문을 거들지, 본문보다 소리치면 안 된다 — 그래서 색을 한 단계 눌러 둔다.
   쓰는 곳이 없던 세무 Q&A 수정 안내(.qna-edit-note)는 3차 정리 통합에서 걷었다. */
.sisun-note,              /* 세무시선 지면 안내 */
.dir-region-hint,         /* 세무사 지도 — 「시·도를 먼저 골라 주세요」 */
.qna-field-note,          /* 세무 Q&A 작성 — 칸마다 붙는 한 줄 안내 */
.sort-note {              /* 세무사 지도 — 「위치를 알 수 없어 인기순으로…」 */
  font-weight: 400;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-tertiary);
}

/* ⚠ 옛 «되돌림» 블록(계약서·법적 문구를 Pretendard로 강제)은 함께 걷었다 — 서체가 하나뿐인
     지금은 아무 일도 하지 않는 죽은 규칙이고, 남겨 두면 다음 사람이 «서체가 둘인가»로 읽는다.
     아래 한 줄만 남긴다: 숫자가 줄 맞춰 서야 하는 자리다(서체와 무관한 요구다). */
[class*="amount"], [class*="money"], [class*="price"], .num, table
{ font-variant-numeric: tabular-nums; }

/* ══════════════════════════════════════════════════════════════════════════
   빈 상태 부품 (.empty) — P-079 1-(나)·2-(가), D-880
   ══════════════════════════════════════════════════════════════════════════
   빈·오류 상태는 이 한 벌이다. 차례: 40px 선 아이콘(fragments/empty-icons, grey400 · aria-hidden, 선택)
   → 제목 heading 16/24/600 grey800(«무엇이 없는지», 마침표 없음, balance) → 설명 body2 14/22 · ≥768 15/24 · 400 grey600
     (다음 행동이나 **사실인** 약속, pretty) — 타이포 3단계 묶음 ①(옛 15px/600/1.5 · 14px/400/1.6)
   → ghost 44px 버튼 **하나까지**(.btn.btn-ghost.btn-sm.empty-act).
   틀은 놓인 자리가 정한다 — 카드 안이면 틀 없이(.empty), 지면에 홀로 서면 1px 점선 grey300 · 모서리 12px(.empty-solo).
   🔴 이모지·상태 기호로 아이콘을 대신하지 마라(design.md 2절). 막다른 화면 금지(4절) — 설명이나 버튼 중 하나는 둔다.
   쓰는 곳: 지도 칸 안내(directory-map) · 세무시선 댓글 0개 · 예약 관리 빈 카드(D-782) · 달력 빈 날(D-784) ·
   채팅 자리잡이(chat-list) · 마이 빈 카드(mypage) · 내 예약 빈 목록(reservations) · 프로필 후기(tax-detail) · 광고 집행 내역(dashboard-ads-report).
   3차 정리(X4)에서 넓힌 곳: 세무 Q&A(목록·내 활동·상세 오른쪽 칼럼·세무사 데스크) · 세무시선 목록 · 공개 사례·사례 관리 ·
   내 계약·내 상담노트·내 신고 · 알림 · 공지사항 · 고객센터 문의 내역 · 채팅 빈 방·더하기 메뉴 고르기 · 세무사 지도 패널 ·
   예약 창의 빈 시간·상담노트 · 계약서 쓰기 · 예약 설정 운영시간 · 검수 센터.
   🔴 아이콘은 지면에 홀로 서거나 카드의 목록 자리를 채울 때 둔다. 채워진 카드 안의 좁은 칸(세무사 데스크 첨부값·사례 관리
      «프로필에 보이는 노트»·더하기 메뉴 고르기·예약 창 상담노트)은 글자만 — 40px 그림이 칸보다 커진다.
   ⚠ 설명 안의 문장 속 링크는 `.t-link`(design.md §4), 다음 행동이 하나 있으면 그것은 ghost 버튼(.empty-act)이다.
   ⚠ 빛 지면 전용이다 — /fit·/fit/more 어두운 무대(.fp-empty)는 이 부품 밖이다(글자색이 흰 바탕 기준). */
.empty {
  display: flex; flex-direction: column; align-items: center;
  padding: 28px 20px; text-align: center;
}
/* 🔴 가운데 정렬 flex 열의 자식은 폭이 fit-content(최소 min-content)라, 공백 없는 긴 낱말(검색어로 넣은 주소·긴 문장)이
   칸보다 넓어져 틀 밖·화면 밖으로 넘친다 — body의 keep-all + break-word는 min-content를 줄이지 않는다(K17, 머리 주석).
   anywhere는 최소 폭 계산에만 끊을 자리를 더해 자식 폭이 칸 폭을 넘지 않게 한다 — 줄바꿈은 그대로 어절 단위(keep-all)이고,
   칸보다 긴 낱말만 틀 끝에서 끊긴다(3차 정리 검토 — 폰 390 Q&A 검색 0건). 음절 단위 되돌림(word-break)이 아니다. */
.empty > * { overflow-wrap: anywhere; }
/* 🔴 JS가 hidden으로 여닫는 빈 상태(지도 패널 «보이는 세무사 없음»·예약 창 «열어 둔 시간 없음»·채팅 빈 방 버튼)가 있다 —
   author display(flex·inline-flex)가 UA의 [hidden]{display:none}을 이기므로 못박는다. */
.empty[hidden], .empty-act[hidden] { display: none; }
.empty-solo { border: 1px dashed var(--grey300); border-radius: 12px; }
.empty-ic {
  flex: none; width: 40px; height: 40px; margin-bottom: 12px;
  color: var(--grey400); fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
/* 빈 제목 = heading(옛 15/1.5/600) — 카드 안 목록 항목 제목 자리. 카드 제목보다 아래, 설명(body2)보다 위.
   ⚠ «카드 제목보다 아래»는 카드 제목이 title3(18)일 때만 선다 — 카드 CSS가 아직 리터럴이면 같거나 거꾸로 선다. 검증 실측(4폭)으로
     찾은 두 곳(정산 «지급 내역» .crm-group-head .ttl 15/700 · 날 레일 .sc-day-title 16/600)은 묶음 ①에서 title3으로 올렸다.
     광고 판 .cb-sec의 «내역 · 10월»(.cb-cap 12)은 판 제목(.cb-ptitle) 아래 눈썹 캡션이라 이 순서의 대상이 아니다. */
.empty-t {
  font-size: var(--fs-heading); line-height: var(--lh-heading); font-weight: var(--fw-semibold); letter-spacing: var(--ls-14);
  color: var(--grey800); text-wrap: balance;
}
.empty-s {   /* body2(옛 14/1.6/400) — grey600 #6B7684는 흰 바탕 4.62:1(회색 지면은 .empty-solo가 흰 채움을 깐다, admin-console.css) */
  margin-top: 4px; font-size: var(--fs-body2); line-height: var(--lh-body2); font-weight: var(--fw-regular); letter-spacing: var(--ls-14);
  color: var(--grey600);
  word-break: keep-all; overflow-wrap: break-word; text-wrap: pretty;
}
.empty-act { margin-top: 16px; }

/* ══════════════════════════════════════════════════════════════════════════
   세무사 명함 = 메뉴 (D-267) — 커뮤니티 지면 공용(fragments/tax-menu.html)
   ══════════════════════════════════════════════════════════════════════════
   메뉴 알맹이(.acct-item)는 상단바 계정 메뉴와 **같은 클래스를 쓴다**(shell.css) —
   두 벌로 만들면 한쪽만 고쳐진다. 여기서는 «명함처럼 생긴 버튼»만 정의한다. */
.taxm { position: relative; }
.taxm-sum {
  display: flex; align-items: center; gap: 12px; min-width: 0;
  padding: 8px 10px; border-radius: var(--r-md); cursor: pointer;
  list-style: none;                      /* 사파리·파이어폭스의 기본 삼각형 제거 */
  transition: background .15s ease;
}
.taxm-sum::-webkit-details-marker { display: none; }   /* 구형 웹킷 */
.taxm-sum:hover { background: var(--surface-alt); }
.taxm-sum:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.taxm-av { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; flex: none; }
.taxm-av-empty {
  display: flex; align-items: center; justify-content: center;
  background: var(--primary-light); color: var(--primary); font-size: 17px; font-weight: 700;
}
.taxm-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.taxm-name { font-size: 15.5px; font-weight: 700; color: var(--text-primary); }
.taxm-sub {
  font-size: 12.5px; color: var(--text-tertiary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.taxm-caret { flex: none; color: var(--text-tertiary); transition: transform .15s ease; }
.taxm[open] .taxm-caret { transform: rotate(180deg); }
/* 메뉴는 명함 **왼쪽 끝**에 맞춘다 — 상단바는 화면 오른쪽 끝이라 right:0이지만,
   여기는 명함이 지면 왼쪽에 있어 right:0이면 메뉴가 카드 밖으로 밀린다. */
.taxm-menu {
  position: absolute; left: 0; top: calc(100% + 6px); z-index: 40;
  min-width: 200px; padding: 6px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--shadow-float);
}

/* ══ 이미지 드래그 금지 (D-280) ═════════════════════════════════════════════
   🔴 **범위를 넓혔다.** D-279에서는 캐러셀 이미지에만 걸고 「프로필·후기 사진은 끌 수 있어야
      한다」고 일부러 좁혔는데, 실제로 써 보니 세무사 프로필 사진·세무시선 첨부·Q&A 첨부를 끌 때
      **똑같은 사진 고스트**가 나왔다(사용자 지적). 그 예외는 상상한 요구였고 실제 요구가 아니었다.
   ⇒ 이제 **모든 이미지**가 대상이다. 지면마다 클래스를 세어 가며 붙이는 방식은 새 화면이
     생길 때마다 빠진다 — 기본을 막고, 정말 끌어야 할 자리가 생기면 그때 예외를 둔다.

   ⚠ 이 규칙은 **WebKit·Blink 전용**이다(표준 아님). Firefox는 무시하므로 `shell.js`의
     dragstart 위임 처리가 함께 있어야 한다. 한쪽만 두면 「내 브라우저에서는 되는데」가 된다.
   ⚠ 막는 것은 **이미지 끌기**뿐이다. 파일을 밖에서 끌어다 놓는 업로드(세무시선 에디터·보관함)는
     `drop`/`dragover`를 쓰므로 영향이 없다 — 실제로 확인하고 넓혔다.
   ⚠ `user-select`·`pointer-events`를 여기 얹지 마라. 전자는 글 선택을, 후자는 링크 클릭을 죽인다. */
img {
  -webkit-user-drag: none;
}

/* 상세 후기도 홈 카드와 **같은 인용 처리**(D-280). 한쪽만 하면 같은 후기가 지면마다
   다른 얼굴이 된다 — 값은 home.css의 `.rv-body::before/after`와 함께 고칠 것. */
.rev-body::before,
.rev-body::after {
  color: var(--primary);
  opacity: 0.55;
  font-size: 1.5em;
  line-height: 0;
  vertical-align: -0.28em;
  font-weight: 700;
}
.rev-body::before { content: '\201C'; margin-right: 2px; }
.rev-body::after  { content: '\201D'; margin-left: 2px; }

/* 전자계약서 링크 카드 (D-327) — 예약(파랑)·결제(주황)와 갈리는 남색 계열.
   ⚠ 세 톤이 서로 충분히 멀어야 한다 — 채팅방에서 스치듯 보는 카드라 색이 곧 종류다. */
.chat-card.card-contract .link-strip { background: #EEF2FB; color: #1E3A5F; }

/* ══ 예약 화면 개편 (D-482 보강 ⑨, 사용자 지시) ═══════════════════════════════
   날짜를 먼저 고르고 그 날의 시간만 본다 — 2주치 시간을 한 번에 깔지 않는다.
   🔴 무JS: 라디오(.bk-r)가 슬롯 묶음의 **형제로 앞에** 있고, 아래 규칙이 «N번째가 켜지면
      N번째 묶음만 보인다»를 그린다. :has()가 아니라 형제 결합자라 구형에서도 동작한다.
   ⚠ 날짜 수 상한은 BookingController.DAYS_AHEAD(14)다 — 늘리면 아래 규칙 개수도 늘려라
      (규칙이 모자라면 그 날짜를 골라도 시간이 안 뜬다). 지금은 18까지 깔아 뒀다. */

.bk-head { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.bk-avatar { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; flex: none; }
.bk-avatar-empty { display: flex; align-items: center; justify-content: center;
  background: var(--surface-alt, #f2f4f6); color: var(--text-secondary, #4e5968); font-weight: 700; }
.bk-who { min-width: 0; }
.bk-name { display: flex; align-items: baseline; gap: 8px; }
.bk-profile-link { font-size: 12px; color: var(--primary, #3182f6); }

.bk-product { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.bk-product-l { display: flex; flex-direction: column; gap: 2px; }
.bk-product .price { margin-left: auto; }
.bk-credit-tag { margin-left: auto; font-size: 12px; font-weight: 700; color: #0b8043;
  background: #e6f4ea; border-radius: 999px; padding: 6px 11px; white-space: nowrap; }

.bk-picker { margin-top: 12px; }
.bk-days { display: flex; gap: 8px; overflow-x: auto; padding: 10px 2px 4px;
  scrollbar-width: thin; -webkit-overflow-scrolling: touch; }
.bk-day { flex: none; min-width: 84px; padding: 9px 12px; border: 1px solid var(--border, #e5e8eb);
  border-radius: 10px; background: #fff; cursor: pointer; text-align: center; line-height: 1.3;
  transition: border-color .12s, background .12s; }
.bk-day:hover { border-color: #c6d3e4; }
.bk-day b { display: block; font-size: 13px; font-weight: 700; letter-spacing: -.01em; }
.bk-day i { display: block; font-style: normal; font-size: 11px; color: var(--text-tertiary, #8b95a1); margin-top: 2px; }
.bk-set { display: none; padding-top: 10px; border-top: 1px solid var(--border-light, #f2f4f6); margin-top: 6px; }
.bk-set-label { font-size: 12.5px; font-weight: 700; color: var(--text-secondary, #4e5968); margin-bottom: 9px; }

/* 선택된 날짜만 보이고, 그 칩만 파랗게 선다. */
.bk-r:nth-of-type(1):checked ~ .bk-sets .bk-set:nth-child(1),
.bk-r:nth-of-type(2):checked ~ .bk-sets .bk-set:nth-child(2),
.bk-r:nth-of-type(3):checked ~ .bk-sets .bk-set:nth-child(3),
.bk-r:nth-of-type(4):checked ~ .bk-sets .bk-set:nth-child(4),
.bk-r:nth-of-type(5):checked ~ .bk-sets .bk-set:nth-child(5),
.bk-r:nth-of-type(6):checked ~ .bk-sets .bk-set:nth-child(6),
.bk-r:nth-of-type(7):checked ~ .bk-sets .bk-set:nth-child(7),
.bk-r:nth-of-type(8):checked ~ .bk-sets .bk-set:nth-child(8),
.bk-r:nth-of-type(9):checked ~ .bk-sets .bk-set:nth-child(9),
.bk-r:nth-of-type(10):checked ~ .bk-sets .bk-set:nth-child(10),
.bk-r:nth-of-type(11):checked ~ .bk-sets .bk-set:nth-child(11),
.bk-r:nth-of-type(12):checked ~ .bk-sets .bk-set:nth-child(12),
.bk-r:nth-of-type(13):checked ~ .bk-sets .bk-set:nth-child(13),
.bk-r:nth-of-type(14):checked ~ .bk-sets .bk-set:nth-child(14),
.bk-r:nth-of-type(15):checked ~ .bk-sets .bk-set:nth-child(15),
.bk-r:nth-of-type(16):checked ~ .bk-sets .bk-set:nth-child(16),
.bk-r:nth-of-type(17):checked ~ .bk-sets .bk-set:nth-child(17),
.bk-r:nth-of-type(18):checked ~ .bk-sets .bk-set:nth-child(18) { display: block; }
.bk-r:nth-of-type(1):checked ~ .bk-days .bk-day:nth-child(1),
.bk-r:nth-of-type(2):checked ~ .bk-days .bk-day:nth-child(2),
.bk-r:nth-of-type(3):checked ~ .bk-days .bk-day:nth-child(3),
.bk-r:nth-of-type(4):checked ~ .bk-days .bk-day:nth-child(4),
.bk-r:nth-of-type(5):checked ~ .bk-days .bk-day:nth-child(5),
.bk-r:nth-of-type(6):checked ~ .bk-days .bk-day:nth-child(6),
.bk-r:nth-of-type(7):checked ~ .bk-days .bk-day:nth-child(7),
.bk-r:nth-of-type(8):checked ~ .bk-days .bk-day:nth-child(8),
.bk-r:nth-of-type(9):checked ~ .bk-days .bk-day:nth-child(9),
.bk-r:nth-of-type(10):checked ~ .bk-days .bk-day:nth-child(10),
.bk-r:nth-of-type(11):checked ~ .bk-days .bk-day:nth-child(11),
.bk-r:nth-of-type(12):checked ~ .bk-days .bk-day:nth-child(12),
.bk-r:nth-of-type(13):checked ~ .bk-days .bk-day:nth-child(13),
.bk-r:nth-of-type(14):checked ~ .bk-days .bk-day:nth-child(14),
.bk-r:nth-of-type(15):checked ~ .bk-days .bk-day:nth-child(15),
.bk-r:nth-of-type(16):checked ~ .bk-days .bk-day:nth-child(16),
.bk-r:nth-of-type(17):checked ~ .bk-days .bk-day:nth-child(17),
.bk-r:nth-of-type(18):checked ~ .bk-days .bk-day:nth-child(18) { border-color: var(--primary, #3182f6); background: #f0f6ff; }
.bk-r:nth-of-type(1):checked ~ .bk-days .bk-day:nth-child(1) b,
.bk-r:nth-of-type(2):checked ~ .bk-days .bk-day:nth-child(2) b,
.bk-r:nth-of-type(3):checked ~ .bk-days .bk-day:nth-child(3) b,
.bk-r:nth-of-type(4):checked ~ .bk-days .bk-day:nth-child(4) b,
.bk-r:nth-of-type(5):checked ~ .bk-days .bk-day:nth-child(5) b,
.bk-r:nth-of-type(6):checked ~ .bk-days .bk-day:nth-child(6) b,
.bk-r:nth-of-type(7):checked ~ .bk-days .bk-day:nth-child(7) b,
.bk-r:nth-of-type(8):checked ~ .bk-days .bk-day:nth-child(8) b,
.bk-r:nth-of-type(9):checked ~ .bk-days .bk-day:nth-child(9) b,
.bk-r:nth-of-type(10):checked ~ .bk-days .bk-day:nth-child(10) b,
.bk-r:nth-of-type(11):checked ~ .bk-days .bk-day:nth-child(11) b,
.bk-r:nth-of-type(12):checked ~ .bk-days .bk-day:nth-child(12) b,
.bk-r:nth-of-type(13):checked ~ .bk-days .bk-day:nth-child(13) b,
.bk-r:nth-of-type(14):checked ~ .bk-days .bk-day:nth-child(14) b,
.bk-r:nth-of-type(15):checked ~ .bk-days .bk-day:nth-child(15) b,
.bk-r:nth-of-type(16):checked ~ .bk-days .bk-day:nth-child(16) b,
.bk-r:nth-of-type(17):checked ~ .bk-days .bk-day:nth-child(17) b,
.bk-r:nth-of-type(18):checked ~ .bk-days .bk-day:nth-child(18) b { color: var(--primary, #3182f6); }

/* ══ 히어로 노트 — «빈 상태·시작 관문»의 표준 얼굴 (D-485, 사용자 확정 A-3안) ═══════
   🔴 **이 서비스의 빈 상태는 전부 이 얼굴을 쓴다.** 파란 그라디언트 판 위에 일러스트를
      «배경으로 옅게» 깔고, 글이 주인공이 된다 — 글과 그림이 다투지 않는 것이 이 안의 핵심이다.
      새 빈 상태를 만들 때 회색 «항목이 없습니다» 판을 새로 짜지 마라. 이 조각을 써라
      (`fragments/hero.html` :: note).
   ⚠ 아트는 **장식**이다: `aria-hidden`이고, 좁은 화면에서는 더 옅어진다. 아트에 정보를
     싣지 마라 — 읽어야 하는 것은 전부 왼쪽 글에 있어야 한다.
   ⚠ 글 칸에 `max-width`가 있는 이유는 아트와 글이 겹치지 않게 하기 위해서다. 지우면
     넓은 화면에서 제목이 그림 위로 올라탄다. */
/* 🔴 **아트는 절대배치가 아니라 «칸»이다.** 예전엔 판 전체에 깔고 글에 max-width를 줘서
      피했는데, 그 방식은 판이 높아질수록(줄이 늘수록) 그림이 함께 커져 **글 위로 걸어 들어왔다**
      — 사용자 지적으로 걸렸다. 격자 칸으로 두면 글칸과 그림칸이 자리를 나눠 갖기 때문에
      어떤 높이·너비에서도 겹칠 수가 없다. 절대배치로 되돌리지 마라. */
.hero-note {
  position: relative; overflow: hidden;
  /* ⚠ 그림칸 크기는 **여기서** 정한다. svg 쪽에 `width: 30%`를 주면 auto 칸에서 순환 참조가
     되어 칸이 0으로 접힌다(라이브에서 그림이 통째로 사라졌다). 퍼센트는 격자 컨테이너
     기준으로 풀리는 이 자리에 둬야 한다. */
  display: grid; align-items: center;
  grid-template-columns: minmax(0, 1fr) clamp(148px, 26%, 264px);
  border: 1px solid #D7E6FF; border-radius: var(--r-lg, 16px);
  background: linear-gradient(105deg, #EAF2FF 0%, #F5F9FF 52%, #FBFDFF 100%);
}
/* 그림칸 — 폭은 판을 따라 줄지만 제 크기를 넘지 않는다(늘리면 선이 굵어져 배경답지 않다). */
.hero-note-art {
  width: 100%; height: auto;
  margin-right: 16px; opacity: .55; pointer-events: none;
}
.hero-note-body {
  position: relative; min-width: 0;
  padding: 30px var(--s-2xl, 24px) 26px;
}
.hero-note-eyebrow {
  display: inline-flex; align-items: center;
  font-size: 12px; font-weight: 700; letter-spacing: var(--ls-sm, -.1px);
  color: var(--primary-pressed, #1B64DA); background: var(--primary-light, #E8F3FF);
  border-radius: var(--r-full, 999px); padding: 4px 10px;
}
.hero-note-title {
  margin: 12px 0 9px; font-size: 23px; font-weight: 700; line-height: 1.34;
  letter-spacing: var(--ls-xl, -.4px); color: var(--text-primary, #191F28);
  word-break: keep-all;
}
.hero-note-lead {
  margin: 0; font-size: 13px; line-height: 1.7;
  color: var(--text-tertiary, #6B7684); word-break: keep-all;
}
.hero-note-cta { margin-top: 20px; }
.hero-note-foot {
  margin: 10px 0 0; font-size: 12px; line-height: 1.5;
  color: var(--text-disabled, #9AA3AE);
}

/* 좁은 화면 — 아트를 더 옅게 물리고 글 칸을 풀어 준다. 글이 그림 위에 얹히는 구조라
   여기서 대비를 확보하지 않으면 모바일에서 제목이 읽히지 않는다. */
@media (max-width: 560px) {
  /* 좁은 화면에서는 그림을 **버린다** — 줄여서 끼워 넣으면 글칸이 읽기 어려운 폭이 된다.
     장식과 본문이 다투면 본문이 이긴다. */
  .hero-note { grid-template-columns: minmax(0, 1fr); }
  .hero-note-art { display: none; }
  .hero-note-body { padding: 26px 20px 22px; }
  .hero-note-title { font-size: 21px; }
}

/* 판만 좁은 자리(넓은 화면의 2열 배치 등)에 넣을 때 — 미디어 쿼리는 «화면» 기준이라
   여기까지 못 잡는다. 이 수식어를 붙이면 그림 칸이 통째로 사라진다. */
.hero-note--narrow { grid-template-columns: minmax(0, 1fr); }
.hero-note--narrow .hero-note-art { display: none; }

/* ══ 예약 맥락 머리 (D-529, 사용자 확정 T1) ═══════════════════════════════════════
   Q&A 답변을 읽고 넘어온 예약에서 «어느 질문인지»를 세운다 — 없으면 여정의 실이 여기서 끊긴다.
   ⚠ 이 카드는 Q&A를 거친 예약에만 뜬다. 프로필에서 바로 온 예약에는 없다. */
.bk-ctx {
  border-color: var(--tint-blue-line); background: var(--surface-tint);
  padding: 16px 18px; margin-bottom: 10px;
}
/* ⚠ 자간을 벌리지 마라 — 이건 «결제 완료» 같은 두세 글자 눈썹이 아니라 한 문장이다.
     한글 문장에 트래킹을 넣으면 낱글자로 흩어져 읽는 속도가 떨어진다. */
.bk-ctx-lbl { font-size: 11.5px; font-weight: 600; color: var(--text-tertiary); }
.bk-ctx-title {
  display: block; margin-top: 7px; font-size: 15px; font-weight: 700;
  letter-spacing: -.01em; color: var(--text-primary); word-break: keep-all;
}
.bk-ctx-title:hover { color: var(--primary-pressed); }
.bk-ctx-note {
  margin: 6px 0 0; font-size: 12.5px; line-height: 1.6;
  color: var(--grey700); word-break: keep-all;
}

/* ══ 세무사 사진 object-position — 규칙은 «50% 10%» 하나, 선언은 이 묶음 한 곳 (D-808 · D-869) ═════════
   규칙: 세무사 사진은 어느 지면이든 마스터의 위쪽을 남긴다. 새 마스터는 4:5 세로(ImageSpec.TAX_PROFILE — 편집 폼의 자르기가 만들고
     무대 안내는 머리를 세로 9~51%·어깨선을 67%에 둔다. JS 없음·앱 업로드는 서버가 가로 가운데·세로 위 10%로 4:5를 자른다 —
     사용자 결정 2026-10-08 · 8차 F1~F11, D-916). 4:5 사본(webp 160/480/1200)도 같은 값이 맞다: 4:5·1:1 창에서는 위아래 자름이
     작거나 없고, 4:5보다 좁은 창(PC 헤로 9:16 · 아치 0.769)에서는 cover가 좌우를 자르므로 세로 값이 무효다.
   옛 마스터(9:16 — D-808, 데모 사진 교체 ③ 전까지 지면에 남음)의 산식: 창이 마스터보다 넓으면 cover가 위아래를 자르고,
     보이는 시작점은 y0 = (1 - 0.5625 / 창비율) * 10%다(아래 줄은 그 옛 사진 기준 — 머리 9~39% · 어깨 50%).
     1:1 창 4.4~60.6% · 3:4 창 2.5~77.5% · 4:5 창 3.0~73.3% — 머리(9~39%)와 어깨선(50%)이 어느 창에도 든다.
     9:16 이하(마스터와 같거나 더 좁은) 창은 cover가 좌우를 자르므로 세로 값이 무효다 — 같은 선택자의 폰 변형
     (히어로 900 이하 4:5 · fit 768 이하 4:5 · 미니어처 원형)은 넓은 창이라 거기서 10%가 맞는 값이 된다.
   금지: 이 파일 밖에서 세무사 사진에 object-position 50% N%를 선언하지 마라 — 히어로 20%·홈 카드 18%/8%·
     지금 상담 12%·미니어처 18%가 제각각이던 것을 걷어 하나로 모았다(PhotoCropContractTest.surfacesKeepTheHead가
     페이지 CSS의 0건을 잰다). ID 선택자로 덮으면 이 묶음이 못 이긴다.
   예외 0건: 홈 «지금 상담 가능한 세무사» 원형 112의 18% 예외(사용자 결정 2026-09-25)는 그 카드가 세무사 카드 v4 아치(.tc-photo, 이 묶음 10%)로
     바뀌며 걷었다(사용자 결정 2026-10-07 범위 변경) — 옛 .on-img도 이 목록에서 뺐다.
   같은 뜻: photo-crop.js 미리보기 다섯(PC 헤로 · 홈 프리미엄 · 아치 · 지도 1:1 · 원형 — 8차 F5 ⓐ)의 data-pos 0.1이 이 값이다 — 미리보기와 지면이 같은 사각형을 본다.
   목록: 옛 사진(1:1·4:5 원본)은 영향이 거의 없다(1:1은 창과 같아 자를 게 없고, 4:5는 시작점이 2% 위로 옮겨질 뿐).
     .avatar img는 자식 img만 잡으므로 <img class="avatar">(지도 패널·채팅 목록/머리·찾기 광고 레일)는 img.avatar로
     따로 잡는다. .dad-photo는 <img> 자신이라 .dad-photo img는 헛발이었다. 새 사진 클래스는 여기에 더하라.
     img.avatar·.msg-avatar·.photo-current는 채팅 상대·의뢰인 사진도 잡는다 — 의뢰인 마스터는 1:1이라 무크롭(창과 같아
     object-position이 아무것도 옮기지 않는다).
   .tc-photo = 세무사 카드 v4 아치 사진(tax-card.css — 116×152 · 좁은 카드 110×146 · 145 캡처 변형 112×145, 사용자 결정 2026-10-07 T18·T20) —
     홈 «지금 상담 가능한 세무사» 카드와 미리보기 둘이 쓴다.
   .pmc-img = 홈 «프리미엄 세무사» 세로 카드 사진(home.css — 4:5 창 · 확대는 transform(배율 = 서버 설정값 ImageSpec.PREMIUM_PHOTO_ZOOM — 7차 P8),
     기준점은 위 끝 50% 0% — 확대분이 아래 양복을 먹는다, 사용자 요청 2026-10-08 · 검토 UX-02). 위치는 이 묶음 10% 그대로다(4:5 창 3.0~73.3%). */
.avatar img, img.avatar, .qna-ans-pic, .qna-tax-avatar, .bk-avatar, .hub-ava, .qna-credit-ava,
.sp-av-img, .sisun-avatar, .qna-home-avatar, .top-avatar-img, .my-photo, .dad-photo,
.hub-card-ph, .rv-avatar img, .map-card-photo, .msg-avatar, .msg-avatar img, .qna-wait-f img, .qna-wait-fc img,
.qna-face, .taxm-av, .photo-current, .ph-img, .fp-img, .cb-mini-pi, .tc-photo, .pmc-img {
  object-position: 50% 10%;
}


/* ── 질문하기 단계 표시(fragments/qna-steps — 질문하기 P1, 사용자 승인 2026-10-11) ──
   상담노트 고르기·상담노트 만들기(next=qna)·질문 작성이 쓴다 — qna.css와 brief.css 양쪽 지면이라 공용 파일에 둔다.
   1 상담노트 › 2 질문 쓰기 › 3 30분 뒤 답변 + 한 줄 «세무사가 상담노트를 함께 보고 답해요»(사용자 지정). 13px·400/600·토큰 색만. */
.qna-steps { margin: 0 0 16px; container-type: inline-size; container-name: qsteps; }
/* 🔴 한 줄·어절 nowrap(질문하기 P2, 2026-10-11) — 좁은 칸에서 «질문 쓰기»가 «질문/쓰기»로, «30분 뒤 답변»이 세 토막으로 꺾였다(상담노트 만들기 레일 62px, 사용자 제보).
   목록이 칸보다 넓으면(아래 @container) 목록을 숨기고 «1/3 상담노트» 토막(.qna-steps-c)만 보인다. */
.qna-steps-l { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: nowrap; align-items: center; gap: 4px 8px; }
.qna-steps-l li {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-size: var(--fs-caption1); line-height: var(--lh-caption1); letter-spacing: var(--ls-13); color: var(--text-tertiary);
}
.qna-steps-c {
  display: none; align-items: center; gap: 6px; white-space: nowrap;
  font-size: var(--fs-caption1); line-height: var(--lh-caption1); letter-spacing: var(--ls-13); color: var(--text-primary); font-weight: var(--fw-semibold);
}
.qna-steps-c b { font-weight: var(--fw-semibold); color: var(--primary-pressed); font-variant-numeric: tabular-nums; }
@container qsteps (max-width: 323px) {
  .qna-steps-l { display: none; }
  .qna-steps-c { display: inline-flex; }
}
.qna-steps-l li + li::before { content: ""; width: 12px; height: 1px; background: var(--grey300); margin-right: 2px; }
.qna-steps-l i {
  font-style: normal; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border-radius: var(--r-full); background: var(--grey100); color: var(--text-tertiary);
  font-size: var(--fs-caption1); line-height: var(--lh-caption1); font-weight: var(--fw-semibold);
}
.qna-steps-l li.on { color: var(--text-primary); font-weight: var(--fw-semibold); }
.qna-steps-l li.on i { background: var(--primary); color: var(--surface); }
.qna-steps-l li.done i { background: var(--primary-light); color: var(--primary-pressed); }
.qna-steps-note { margin: 6px 0 0; font-size: var(--fs-caption1); line-height: var(--lh-caption1); letter-spacing: var(--ls-13); color: var(--text-secondary); word-break: keep-all; }

/* «내 질문» 카드(fragments/my-questions-card, D-963) — 질문하기 시작·홈 공용. 상태는 글자 농도만(600 진함 / 400 옅음). */
.mq-card { margin: 0 0 20px; }
.mq-home { margin-top: 16px; }
.mq-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.mq-title { margin: 0; font-size: var(--fs-title2); line-height: var(--lh-title2); font-weight: var(--fw-semibold); letter-spacing: var(--ls-14); color: var(--text-primary); }
.mq-all { flex: none; white-space: nowrap; font-size: var(--fs-label2); line-height: var(--lh-label2); color: var(--primary); text-decoration: none; }
.mq-list { list-style: none; margin: 0; padding: 0 16px; background: var(--surface); border: 1px solid var(--border); border-radius: 16px; }
.mq-list li + li { border-top: 1px solid var(--border); }
.mq-row, .mq-more { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 48px; text-decoration: none; word-break: keep-all; }
.mq-t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-body2); line-height: var(--lh-body2); color: var(--text-primary); }
.mq-meta { flex: none; display: inline-flex; align-items: baseline; gap: 8px; white-space: nowrap; font-size: var(--fs-caption1); line-height: var(--lh-caption1); }
.mq-st { font-weight: var(--fw-regular); color: var(--text-tertiary); }
.mq-st.on { font-weight: var(--fw-semibold); color: var(--text-primary); }
.mq-day { font-weight: var(--fw-regular); color: var(--text-tertiary); }
.mq-more { margin-top: 8px; padding: 0 4px; font-size: var(--fs-label2); line-height: var(--lh-label2); color: var(--primary); white-space: nowrap; }
.mq-row:focus-visible, .mq-more:focus-visible, .mq-all:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
