/* ============================================================
   POKAMAP — Pokémon Card Map (Unofficial Fan Service)
   Design Tokens: Navy/Charcoal + Electric Blue + Holo Cyan
   ============================================================ */

:root {
  /* Surface */
  --bg-base: #0F172A;
  --bg-elev-1: #111827;
  --bg-elev-2: #1E293B;
  --surface: #FFFFFF;
  --surface-soft: #F8FAFC;
  --surface-mid: #E2E8F0;

  /* Text */
  --text-strong: #0F172A;
  --text-on-dark: #F8FAFC;
  --text-muted: #64748B;
  --text-subtle: #94A3B8;

  /* Brand */
  --brand: #2563EB;
  --brand-hover: #1D4ED8;
  --brand-soft: #DBEAFE;
  --holo: #06B6D4;
  --holo-soft: #CFFAFE;
  --accent-yellow: #FACC15;

  /* Stock states */
  --st-ample: #22C55E;
  --st-normal: #2563EB;
  --st-low: #F97316;
  --st-soldout: #94A3B8;
  --st-incoming: #06B6D4;
  --st-preorder: #FACC15;

  /* Energy / danger */
  --danger: #EF4444;
  --danger-soft: #FEE2E2;

  /* Borders & shadows */
  --border: rgba(15, 23, 42, 0.08);
  --border-strong: rgba(15, 23, 42, 0.16);
  --border-dark: rgba(248, 250, 252, 0.08);
  --shadow-1: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.04);
  --shadow-2: 0 4px 12px rgba(15, 23, 42, 0.08), 0 2px 4px rgba(15, 23, 42, 0.04);
  --shadow-3: 0 12px 32px rgba(15, 23, 42, 0.12);
  --shadow-overlay: 0 -8px 24px rgba(15, 23, 42, 0.08);

  /* Radii */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-pill: 999px;

  /* Spacing */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-8: 32px;
  --s-10: 40px;
  --s-12: 48px;

  /* Type */
  --f-sans: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  /* Numeric badges/counts/prices used to render in JetBrains Mono. Per spec
     the entire app should be Pretendard — keep the --f-mono token (it's
     referenced widely) but point it at the same Pretendard chain so legacy
     call sites automatically follow. tabular-nums feature still applied via
     `.mono` class for digit alignment where it matters. */
  --f-mono: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;

  /* Layout */
  --bottomnav-h: 64px;
  --header-h: 56px;
  --side-panel-w: 420px;
  --side-panel-w-xl: 480px;

  /* Z layers */
  --z-toast: 80;
  --z-modal: 70;
  --z-sheet: 60;
  --z-nav: 50;
  --z-header: 40;
  --z-marker: 20;

  /* Safe-area insets — env() 를 var 로 한 번만 picking. JS 가 동일 값을
     읽어서 sheet drag 상한 계산에 사용 (iPhone 노치/Dynamic Island 회피). */
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  /* App-level dimensions — alias 패턴으로 새 이름 (--app-*) + 기존 (--safe-*)
     둘 다 사용 가능. PWA standalone layout 의 진실의 원천.
     --app-vh / --mobile-nav-h 는 JS (index.html inline) 가 동적 업데이트:
       resize / orientationchange / visibilitychange / load 이벤트마다 재계산.
     --app-vh: window.innerHeight 기반 — iOS Safari URL bar 가 100vh 에 포함되어
       뷰포트가 실제보다 길게 잡히는 문제 보정.
     --mobile-nav-h: .mobile-cat-bar 의 getBoundingClientRect().height —
       PWA 모드에서 safe-area-bottom 포함된 실측값. 광고 / FAB / 실시간현황 panel
       의 bottom 계산이 이 값을 따라가서 nav 위에 정확히 정렬. */
  --app-safe-top:    env(safe-area-inset-top, 0px);
  --app-safe-bottom: env(safe-area-inset-bottom, 0px);
  --app-vh: 100vh;
  --mobile-nav-h: 64px;

  /* OS 다크모드 무시하고 라이트 스킴 고정. iOS Safari / Android Chrome 이
     color-scheme 메타 없을 때 input/scrollbar/form 색을 자동 invert 하는
     것을 차단. 아래 html/body 의 명시 색상 + @media dark override 와 세트. */
  color-scheme: light;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  /* 라이트 스킴 고정 — 모바일 OS 다크모드에서 배경/텍스트가 어두워지지
     않도록 :root 의 color-scheme 과 함께 명시. 기존 배경/텍스트 색은
     아래 줄에서 기존 라이트 테마 토큰 (--surface-soft / --text-strong)
     으로 유지. */
  color-scheme: light;
  font-family: var(--f-sans);
  /* Pretendard supports tabular numerals — opt in globally so badge/count
     digits stay column-aligned even though we no longer use a mono font. */
  font-feature-settings: "tnum" 1, "ss03" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--text-strong);
  background: var(--surface-soft);
  line-height: 1.5;
  font-size: 16px;
  /* UI zoom 잠금 — 더블탭 줌 / iOS 자동 텍스트 확대 차단. viewport meta 가
     user-scalable=no 를 무시하는 신형 iOS Safari 대응 안전망. 단, 지도 캔버스
     (.map-canvas / .naver-map) 는 SDK 가 자체 pointer/gesture 처리하므로
     pinch-zoom 그대로 동작. */
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
input, button, select, textarea {
  font-family: inherit;
  font-feature-settings: inherit;
}

body {
  /* iOS Safari 의 100vh 가 URL bar 를 포함해서 실제 가시 영역보다 길게 잡히는
     문제 보정 — JS 가 set 한 --app-vh (window.innerHeight) 를 우선 사용.
     PWA standalone 에선 둘이 같지만, Safari 모드에선 --app-vh 가 정확.
     fallback 으로 100dvh (dynamic vh, 최신 브라우저) → 100vh (legacy). */
  min-height: 100vh;             /* legacy fallback */
  min-height: 100dvh;            /* modern dynamic */
  min-height: var(--app-vh, 100vh); /* JS-corrected (가장 정확) */
  overflow-x: hidden;
}

button { font-family: inherit; cursor: pointer; }
input, select, textarea { font-family: inherit; }
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-hover); }

img { max-width: 100%; display: block; }

/* ===== Typography ===== */

h1, h2, h3, h4 { margin: 0; line-height: 1.25; letter-spacing: -0.01em; color: var(--text-strong); }
h1 { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; }
h2 { font-size: 22px; font-weight: 700; }
h3 { font-size: 17px; font-weight: 600; }
h4 { font-size: 15px; font-weight: 600; }
p { margin: 0; }

.mono { font-family: var(--f-mono); font-feature-settings: "tnum" 1; }
.muted { color: var(--text-muted); }
.subtle { color: var(--text-subtle); }

/* ===== Buttons ===== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--r-md);
  font-size: 14px;
  font-weight: 600;
  border: 1px solid transparent;
  background: var(--surface-mid);
  color: var(--text-strong);
  transition: background 180ms ease, border-color 180ms ease, color 180ms ease, transform 120ms ease;
  min-height: 40px;
  white-space: nowrap;
}
.btn:hover { background: #CBD5E1; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.btn-primary {
  background: var(--brand);
  color: #fff;
}
.btn-primary:hover { background: var(--brand-hover); }

.btn-ghost {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--text-strong);
}
.btn-ghost:hover { background: var(--surface-soft); }

.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #DC2626; }

.btn-sm { padding: 6px 12px; min-height: 32px; font-size: 13px; }
.btn-lg { padding: 14px 22px; min-height: 48px; font-size: 15px; }
.btn-icon {
  width: 40px; height: 40px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-strong);
}
.btn-icon:hover { background: var(--surface-soft); }

.btn-block { width: 100%; }

/* ===== Form ===== */

.input,
.select,
.textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-strong);
  font-size: 14px;
  min-height: 40px;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);
}
.textarea { min-height: 96px; resize: vertical; }
.label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.field { margin-bottom: 14px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* ===== Badges ===== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  font-size: 12px;
  font-weight: 600;
  background: var(--surface-soft);
  color: var(--text-muted);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.badge.ample    { color: #15803D; background: #DCFCE7; border-color: #BBF7D0; }
.badge.normal   { color: #1D4ED8; background: var(--brand-soft); border-color: #BFDBFE; }
.badge.low      { color: #C2410C; background: #FFEDD5; border-color: #FED7AA; }
.badge.sold_out { color: #475569; background: #F1F5F9; border-color: #E2E8F0; }
.badge.incoming { color: #0E7490; background: var(--holo-soft); border-color: #A5F3FC; }
.badge.preorder { color: #92400E; background: #FEF3C7; border-color: #FDE68A; }
.badge.holo {
  color: #fff;
  background: linear-gradient(90deg, #06B6D4 0%, #2563EB 50%, #06B6D4 100%);
  border-color: transparent;
}

.badge.lang-ko { color: #1E40AF; background: var(--brand-soft); border-color: #BFDBFE; }
.badge.lang-jp { color: #B91C1C; background: var(--danger-soft); border-color: #FECACA; }
.badge.lang-en { color: #334155; background: var(--surface-mid); border-color: #CBD5E1; }

.badge.partner { color: #fff; background: var(--brand); border-color: transparent; }
.badge.hidden  { color: #475569; background: #E2E8F0; border-color: #CBD5E1; }

/* Provider badges */
.badge.provider-google { color: #1F2937; background: #fff; border-color: #E5E7EB; }
.badge.provider-kakao  { color: #3D2E00; background: #FEE500; border-color: #F2D200; }
.badge.provider-naver  { color: #fff; background: #03C75A; border-color: transparent; }
.badge.provider-email  { color: #475569; background: #F1F5F9; border-color: #CBD5E1; }

/* Status (applications) */
.badge.status-none      { color: #475569; background: #F1F5F9; }
.badge.status-pending   { color: #92400E; background: #FEF3C7; border-color: #FDE68A; }
.badge.status-review    { color: #0E7490; background: var(--holo-soft); border-color: #A5F3FC; }
.badge.status-approved  { color: #15803D; background: #DCFCE7; border-color: #BBF7D0; }
.badge.status-rejected  { color: #B91C1C; background: var(--danger-soft); border-color: #FECACA; }

/* ===== Cards / Panels ===== */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}
.card-pad { padding: 18px; }

.divider { height: 1px; background: var(--border); border: 0; margin: 12px 0; }

.toast-stack {
  position: fixed;
  bottom: calc(var(--bottomnav-h) + 12px);
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
  max-width: 92vw;
}
.toast {
  background: var(--bg-elev-2);
  color: var(--text-on-dark);
  padding: 10px 14px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 500;
  box-shadow: var(--shadow-3);
  pointer-events: auto;
  animation: toast-in 220ms ease both;
  border: 1px solid rgba(255,255,255,0.06);
}
.toast.error { background: #7F1D1D; }
.toast.holo  { background: linear-gradient(90deg, #06B6D4 0%, #2563EB 100%); }
@keyframes toast-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ===== App Shell ===== */

.app-shell {
  min-height: 100vh;
  padding-bottom: var(--bottomnav-h);
  background: var(--surface-soft);
}

.page-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: rgba(255,255,255,0.92);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--border);
}
.page-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--header-h);
  padding: 0 16px;
  max-width: 1440px;
  margin: 0 auto;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.01em;
  color: var(--text-strong);
}
.brand-mark {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: linear-gradient(135deg, #2563EB 0%, #06B6D4 100%);
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff;
  box-shadow: 0 2px 6px rgba(37, 99, 235, 0.25);
}
.brand-name small { color: var(--text-muted); font-weight: 500; font-size: 11px; display: block; letter-spacing: 0.06em; text-transform: uppercase; }

.header-actions { display: flex; gap: 8px; align-items: center; }

/* ===== Bottom nav ===== */

.bottom-nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--z-nav);
  height: var(--bottomnav-h);
  background: rgba(255,255,255,0.96);
  backdrop-filter: saturate(160%) blur(8px);
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}
.bottom-nav button, .bottom-nav a {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  text-decoration: none;
  position: relative;
  transition: color 160ms ease;
}
.bottom-nav button.active, .bottom-nav a.active { color: var(--brand); }
.bottom-nav button.active::before,
.bottom-nav a.active::before {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  width: 24px; height: 2px;
  background: var(--brand);
  border-radius: 0 0 2px 2px;
  transform: translateX(-50%);
}
.bottom-nav svg { width: 22px; height: 22px; }

/* ===== Map page ===== */

/* v16 layout tokens — single source of truth for the panel widths.
   #map-canvas / .search-bar / .map-fab use .map-shell[data-layout=...] to pick
   the correct left offset so no panel ever overlaps the map. */
.map-shell {
  --rail-w: 80px;
  --list-w: 380px;
  /* detail panel matches list width — same panel size for parity. */
  --detail-w: var(--list-w);
  position: relative;
  height: calc(100vh - var(--bottomnav-h));
  min-height: 320px;
  background: #E5E7EB; /* light neutral so failed tiles don't reveal navy */
  overflow: hidden;
}
@media (min-width: 1440px) {
  .map-shell { --list-w: 420px; }
}
@media (max-width: 1023px) {
  .map-shell { --list-w: 320px; }
}
@media (max-width: 600px) {
  .map-shell { --rail-w: 56px; }
}

/* v17 — search shell + chip row positioned independently.
   - search-shell-anchor: rides INSIDE the open list sidebar, centered horizontally;
     when no sidebar is open, sits at the top-left of the map area with a fixed width.
   - chip-row-anchor: ALWAYS over map-only area. left offset follows data-layout. */
.search-shell-anchor {
  position: absolute;
  top: 12px;
  left: calc(var(--rail-w) + 12px);
  width: 400px;
  z-index: 28;        /* above sidebar(24) so the field rides on top of the panel */
  transition: left 240ms ease-out, width 240ms ease-out;
}
.map-shell[data-layout="rail-list"] .search-shell-anchor,
.map-shell[data-layout="rail-list-detail"] .search-shell-anchor {
  left: calc(var(--rail-w) + 12px);
  width: calc(var(--list-w) - 24px);
}

.chip-row-anchor {
  position: absolute;
  top: 12px;
  left: calc(var(--rail-w) + 12px + 400px + 12px); /* default: right after search shell */
  right: 16px;
  z-index: 28;
  transition: left 240ms ease-out;
  pointer-events: none;  /* the inner row picks up clicks; container ignores */
}

/* =====================================================================
   실시간 현황 (데스크탑 전용) — 검색창 바로 아래 플로팅 anchor.
   search-shell-anchor 와 동일한 left 좌표를 따라가서 사이드바 열릴 때 함께 이동.
   모바일에서는 hide.
   ===================================================================== */
.live-status-anchor {
  position: absolute;
  top: 72px;                                    /* search-shell-anchor (12px) + height (~46px) + 14px 약간 띄움 */
  /* 기본 상태(사이드바 닫힘): 검색창 바로 아래, 왼쪽 정렬 — 원래 자리. */
  left: calc(var(--rail-w) + 12px);
  width: 360px;
  z-index: 27;                                  /* search-shell(28) 보다 한 단계 아래 */
  transition: left 240ms ease-out, width 240ms ease-out;
  pointer-events: none;                          /* 내부 요소만 클릭 받음 */
}
.live-status-anchor > * { pointer-events: auto; }
/* 사이드바 1회 열림 — 검색창은 사이드바 안으로 들어가고, live-status 는
   chip-row-anchor 와 동일하게 "인페르노 X" 칩 줄 아래 위치로 점프. */
.map-shell[data-layout="rail-list"] .live-status-anchor {
  left: calc(var(--rail-w) + var(--list-w) + 12px);
}
/* 상세까지 열림 — 인페르노 X 처럼 더 오른쪽으로 함께 이동. */
.map-shell[data-layout="rail-list-detail"] .live-status-anchor {
  /* floating detail right edge = rail+list+12 (gap) +detail. Add 22 for toggle + 12 gap. */
  left: calc(var(--rail-w) + var(--list-w) + var(--detail-w) + 46px);
}

/* 접힘 — pill 버튼 */
.live-status-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 12px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 999px;
  box-shadow: var(--shadow-1);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-strong);
  cursor: pointer;
  transition: background 100ms ease, box-shadow 140ms ease;
}
.live-status-btn:hover {
  background: var(--surface-soft);
  box-shadow: var(--shadow-2);
}
.live-status-btn-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #22c55e;                          /* 라이브 점멸 — 가벼운 시그널 */
  box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.15);
  animation: live-pulse 1.6s ease-in-out infinite;
}
@keyframes live-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.4; }
}
.live-status-btn-arrow {
  transition: transform 180ms ease-out;
  color: var(--text-muted);
}
.live-status-anchor[data-state="expanded"] .live-status-btn {
  background: var(--surface-soft);
  border-color: var(--text-muted);
}
.live-status-anchor[data-state="expanded"] .live-status-btn-arrow {
  transform: rotate(180deg);                    /* ▼ → ▲ */
  color: var(--text-strong);
}

/* 펼침 — 패널 */
.live-status-panel {
  margin-top: 6px;
  width: 100%;
  max-width: 380px;
  max-height: 560px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-2);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.live-status-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.live-status-panel-title {
  margin: 0;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: -0.01em;
}
.live-status-close {
  background: transparent;
  border: 0;
  padding: 4px;
  border-radius: 6px;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 100ms ease;
}
.live-status-close:hover {
  background: var(--surface-soft);
  color: var(--text-strong);
}
.live-status-tabs {
  display: flex;
  gap: 0;
  padding: 0;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.live-status-tab {
  flex: 1;
  padding: 10px 8px;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 100ms ease, border-color 100ms ease;
}
.live-status-tab:hover { color: var(--text-strong); }
.live-status-tab.is-active {
  color: var(--text-strong);
  border-bottom-color: var(--accent-cyan, #06b6d4);
}
.live-status-list {
  overflow-y: auto;
  flex: 1;
  min-height: 80px;
}
.live-status-list::-webkit-scrollbar { width: 8px; }
.live-status-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
.live-status-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 100ms ease;
  font: inherit;
  color: inherit;
}
.live-status-row:last-child { border-bottom: 0; }
.live-status-row:hover { background: var(--surface-soft); }
.live-status-row-main { flex: 1; min-width: 0; }
.live-status-row-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.live-status-row-body {
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.live-status-row-time {
  flex: 0 0 auto;
  font-size: 11.5px;
  color: var(--text-subtle, #94A3B8);
  white-space: nowrap;
}
.live-status-empty {
  padding: 28px 16px;
  text-align: center;
  font-size: 12.5px;
  color: var(--text-muted);
}
.live-status-empty--err { color: #ef4444; }

/* =====================================================================
   데스크탑/모바일 variant 가시성 분기.
   - desktop variant: ≥769px 에서만 보임 (검색창 바로 아래 왼쪽)
   - mobile  variant: ≤768px 에서만 보임 (chip-row-anchor 마지막 자식 — 칩 wrap 마지막 줄)
   ===================================================================== */
@media (max-width: 768px) {
  .live-status-anchor--desktop { display: none !important; }
}
@media (min-width: 769px) {
  .live-status-anchor--mobile { display: none !important; }
}

/* =====================================================================
   모바일 — chip-row-anchor 의 sibling 으로 absolute 배치. top 위치는 JS 가
   chip-row-anchor 의 실제 bottom 을 측정해서 --live-mobile-top 변수에 set.
   left/right 는 모바일 검색창/칩 row 와 정확히 동일하게 12px (모바일에서는
   .map-rail 이 display:none 이라 rail-w 좌표를 쓰면 안 됨).
   width: auto 로 base 의 width:360px 를 override.
   ===================================================================== */
.live-status-anchor--mobile {
  position: absolute;
  top:   var(--live-mobile-top, 72px);  /* JS 가 동적 set; 미설정 fallback 72px */
  left:  12px;
  right: 12px;
  width: auto;
  z-index: 28;
  pointer-events: none;
}
.live-status-anchor--mobile > * { pointer-events: auto; }
.live-status-btn--compact {
  /* 데스크탑 버튼보다 살짝 작게 + 칩 톤에 맞춤. height 36 + 패딩으로 터치 44px 확보 */
  padding: 8px 12px 8px 10px;
  border-radius: 999px;
  font-size: 12.5px;
  min-height: 36px;
}

/* 모바일 펼친 패널 — button 바로 아래에 absolute 로 띄움. width 100% (= viewport - 72px). */
.live-status-anchor--mobile .live-status-panel {
  position: absolute;
  top: 100%;                    /* button 바로 아래 */
  left: 0;
  margin-top: 6px;
  width: 100%;
  max-width: 460px;             /* 큰 태블릿 폭에서 너무 넓어지지 않게 */
  max-height: 58vh;
  max-height: 58dvh;
  border-radius: 14px;
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.18);
  z-index: 29;                  /* chip-row-anchor(28) 위, sheet(30+) 아래 — 상세 sheet 열리면 가려짐 */
}
/* 모바일 패널 row 살짝 compact */
@media (max-width: 768px) {
  .live-status-row { padding: 9px 12px; }
  .live-status-row-name { font-size: 12.5px; }
  .live-status-row-body { font-size: 11.5px; }
  .live-status-row-time { font-size: 11px; }
}
.chip-row-anchor > .chip-row { pointer-events: auto; }
.map-shell[data-layout="rail-list"] .chip-row-anchor {
  left: calc(var(--rail-w) + var(--list-w) + 12px);
}
.map-shell[data-layout="rail-list-detail"] .chip-row-anchor {
  /* floating detail right edge = rail+list+12 (gap) +detail. Add 22 for toggle + 12 gap. */
  left: calc(var(--rail-w) + var(--list-w) + var(--detail-w) + 46px);
}
@media (max-width: 600px) {
  .search-shell-anchor,
  .map-shell[data-layout="rail-list"] .search-shell-anchor,
  .map-shell[data-layout="rail-list-detail"] .search-shell-anchor {
    left: calc(var(--rail-w) + 8px);
    width: calc(100vw - var(--rail-w) - 16px);
  }
  .chip-row-anchor,
  .map-shell[data-layout="rail-list"] .chip-row-anchor,
  .map-shell[data-layout="rail-list-detail"] .chip-row-anchor {
    /* on small screens, chips wrap below the search */
    top: 60px;
    left: calc(var(--rail-w) + 8px);
    right: 8px;
  }
}

.search-shell {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 6px 10px;
  box-shadow: var(--shadow-2);
  position: relative;
  overflow: hidden;
}
.search-shell::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 1px;
  background: linear-gradient(180deg, transparent 0%, var(--holo) 50%, transparent 100%);
  opacity: 0;
  transition: opacity 200ms ease;
}
.search-shell:focus-within::before { opacity: 1; }

.search-shell .search-icon { color: var(--text-muted); }
.search-shell input {
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  font-size: 15px;
  color: var(--text-strong);
  padding: 8px 4px;
  min-width: 0;
}
.search-shell input::placeholder { color: var(--text-subtle); }
.search-clear {
  background: transparent; border: 0; padding: 4px;
  color: var(--text-muted); border-radius: 50%;
  display: none;
}
.search-shell.has-value .search-clear { display: inline-flex; }

.chip-row {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.chip-row::-webkit-scrollbar { display: none; }
.chip {
  flex-shrink: 0;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: rgba(255,255,255,0.92);
  border: 1px solid var(--border);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-strong);
  box-shadow: var(--shadow-1);
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.chip:hover { background: var(--brand-soft); color: var(--brand); border-color: #BFDBFE; }
.chip.active { background: var(--brand); color: #fff; border-color: var(--brand); }

/* Desktop vs mobile chip rows live in the same anchor; only one is visible. */
.chip-row--mobile { display: none; }
@media (max-width: 768px) {
  .chip-row--desktop { display: none; }
  /* Mobile: chips 자연스럽게 줄바꿈. 가로 스크롤 / fade indicator / touch-
     action override 모두 제거 (사용자 의도 = 단순 wrap). chip-row-anchor
     는 별개 flex 자식 두 개 (chip-row + 제보 버튼) — 칩들이 wrap 으로
     2~3줄 늘어나도 제보 버튼은 anchor flex 의 align-items: flex-start 로
     첫 줄 우측 끝에 고정. 사용자 손가락 reachability 일관성. */
  .chip-row--mobile {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding-bottom: 2px;
  }
  .chip-row--mobile .chip {
    white-space: nowrap;       /* 개별 칩은 한 줄 / 칩 간 wrap */
  }
}

/* Type toggle chips (모바일 전용) — distinguish from search-keyword chips.
   Inactive: white/ghost. Active: brand-fill (matches generic .chip.active). */
.chip--toggle {
  background: #fff;
  color: var(--text-strong);
  border: 1px solid var(--border);
  font-weight: 600;
}
.chip--toggle.active {
  background: var(--brand);
  color: #fff;
  border-color: var(--brand);
  box-shadow: 0 1px 4px rgba(37,99,235,0.25);
}
.chip--toggle:not(.active):hover {
  background: var(--surface-soft);
  color: var(--text-strong);
  border-color: var(--border);
}
/* Featured-pack chips: 토글 칩(.chip--toggle) 과 동일한 흰색 톤으로 통일.
   이전엔 옅은 푸른 톤(rgba(37,99,235,0.06)) 이라 옆 토글들과 시각적으로
   안 어울려 "투명해 보인다" 는 피드백. 클릭 가능한 칩이라는 정보는 hover
   에서 brand-soft 로 표현. */
.chip--featured {
  background: #fff;
  color: var(--text-strong);
  border: 1px solid var(--border);
  font-weight: 600;
}
.chip--featured:hover {
  background: var(--brand-soft);
  color: var(--brand);
  border-color: #BFDBFE;
}

#map-canvas {
  position: absolute;
  /* left is set per layout; right/top/bottom anchor to shell. */
  left: var(--rail-w);
  top: 0; right: 0; bottom: 0;
  z-index: 1;
  background: #E5E7EB;
  min-height: 320px;
  transition: left 240ms ease-out;
}
.map-shell[data-layout="rail-list"] #map-canvas,
.map-shell[data-layout="rail-list-detail"] #map-canvas {
  /* Detail is a floating overlay (see .map-detail) so the map keeps the same
     left offset whether detail is open or not — the panel sits ON TOP of the
     map, never splitting it. */
  left: calc(var(--rail-w) + var(--list-w));
}
@media (max-width: 1023px) {
  /* tablet/mobile: panels float over the map (no canvas push), keep inset */
  #map-canvas,
  .map-shell[data-layout="rail-list"] #map-canvas,
  .map-shell[data-layout="rail-list-detail"] #map-canvas {
    left: 0;
  }
}

#map-canvas > div {
  width: 100% !important;
  height: 100% !important;
}

.map-fab {
  position: absolute;
  right: 14px;
  bottom: 18px;
  z-index: 30;
  width: 48px; height: 48px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-3);
  display: flex; align-items: center; justify-content: center;
  color: var(--brand);
}
.map-fab:hover { background: var(--brand); color: #fff; }

/* Feedback FAB — 모바일 전용. locate-fab(48px) 바로 위에 같은 크기로.
   데스크탑에선 사이드바 FEEDBACK 버튼이 동일 진입점이라 숨김.
   ⚠️ specificity: 아래 .map-shell .map-fab (0,2,0) 의 bottom !important 와
   충돌하므로 id 선택자 (#feedback-fab) 로 우선순위 확보. */
.map-fab--feedback { display: none; }
@media (max-width: 768px) {
  /* 모바일 세로 배치 (위→아래): locate-fab → FEEDBACK pill → 하단 nav.
     feedback 이 가장 가로로 길어서 nav 바로 위에 두고, locate 는 그 위로 올림.
     - feedback: bottom = base (위에서 .map-shell .map-fab 가 잡아주는 값을 그대로 사용)
     - locate  : bottom = base + 54px (feedback pill 높이 44 + 시각 gap 10) */
  #locate-fab.map-fab {
    bottom: calc(var(--mobile-overlay-bottom, 72px) + var(--mobile-ad-h, 0px) + 54px) !important;
  }
  #feedback-fab.map-fab {
    display: flex;
    /* pill 형태 — 원형 48×48 이 아니라 가로 텍스트 ("FEEDBACK") 가 들어가도록
       width: auto + 좌우 padding + 큰 border-radius. .map-fab 의 width:48px /
       height:48px / border-radius:50% 는 모두 덮어씀. */
    width: auto !important;
    min-width: 96px;
    height: 44px !important;
    padding: 0 18px;
    border-radius: 22px !important;
    /* Discord 톤 + 텍스트 가독성용 자간/굵기. */
    background: #5865F2;
    border-color: #5865F2;
    color: #FFFFFF;
    font-size: 12.5px;
    font-weight: 800;
    letter-spacing: 0.06em;
    box-shadow: 0 4px 12px rgba(88, 101, 242, 0.35);
  }
  #feedback-fab.map-fab .map-fab-text {
    line-height: 1;
    white-space: nowrap;
  }
  #feedback-fab.map-fab:hover {
    background: #4752C4;
    border-color: #4752C4;
    color: #FFFFFF;
  }
  #feedback-fab.map-fab:active { transform: translateY(1px); }
  #feedback-fab.map-fab:focus-visible {
    outline: 2px solid #5865F2;
    outline-offset: 2px;
  }
}

/* ========== Feedback sheet ========== */
.feedback-sheet .ps-card { max-width: 420px; }
.feedback-sheet .fb-section {
  padding: 24px 24px 32px;
  text-align: center;
}
.feedback-sheet .fb-message {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--text-strong);
  margin: 0 0 18px;
}
.feedback-sheet .fb-email {
  display: inline-block;
  font-size: 14px;
  font-weight: 700;
  color: var(--brand);
  letter-spacing: 0.01em;
  padding: 10px 16px;
  border-radius: 10px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  text-decoration: none;
  transition: background 120ms ease;
}
.feedback-sheet .fb-email:hover { background: var(--surface); }

/* Discord 피드백 진입 버튼 — Discord 브랜드색 (#5865F2) fill, 흰 텍스트.
   소셜 로그인 버튼과 같은 톤 (아이콘 + 라벨, 명확한 액션). 모바일 / 데스크탑
   동일 스타일. */
.feedback-sheet .fb-discord {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 10px 22px;
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: #FFFFFF;
  background: #5865F2;
  border: 1px solid #5865F2;
  border-radius: 12px;
  text-decoration: none;
  box-shadow: 0 1px 4px rgba(88, 101, 242, 0.25);
  transition: background 120ms ease, box-shadow 120ms ease, transform 80ms ease;
}
.feedback-sheet .fb-discord:hover  { background: #4752C4; border-color: #4752C4; box-shadow: 0 2px 8px rgba(88, 101, 242, 0.35); }
.feedback-sheet .fb-discord:active { transform: translateY(1px); }
.feedback-sheet .fb-discord:focus-visible {
  outline: 2px solid #5865F2;
  outline-offset: 2px;
}
.feedback-sheet .fb-discord-icon {
  display: inline-flex;
  align-items: center;
  color: #FFFFFF;
}
.feedback-sheet .fb-discord-label { white-space: nowrap; }

/* "또는 이메일로" 구분선 — Discord 버튼 아래, 이메일 링크 위. 양옆에 가는
   회색 라인을 두어 옵션이 둘이라는 시각 신호. */
.feedback-sheet .fb-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0 12px;
  font-size: 12px;
  color: var(--text-muted, #6B7280);
}
.feedback-sheet .fb-divider::before,
.feedback-sheet .fb-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border, #E5E7EB);
}

/* ===== Custom zoom column (+/-) — desktop right-bottom, above locate FAB.
   Replaces Naver SDK's built-in zoomControl, which silently dropped its
   position option (Position.RIGHT_BOTTOM) on some SDK builds and fell back
   to TOP_LEFT. This DOM-owned version is positioned deterministically. */
.map-zoom {
  position: absolute;
  right: 14px;
  bottom: 132px;          /* sits above locate FAB (bottom 72px + 48px + ~12px gap) */
  z-index: 30;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow-3);
  overflow: hidden;
}
.map-zoom-btn {
  width: 36px;
  height: 36px;
  background: transparent;
  border: 0;
  font-size: 18px;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
}
.map-zoom-btn + .map-zoom-btn { border-top: 1px solid var(--border); }
.map-zoom-btn:hover  { background: rgba(15, 23, 42, 0.05); }
.map-zoom-btn:active { background: rgba(15, 23, 42, 0.1); }
.map-zoom-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* Custom scale bar — Naver-style line + tick + distance label.
   Width (--scale-px) is set inline by JS to match a "nice" distance at the
   current zoom (50m / 100m / 200m / 500m / 1km / …). */
.map-scale {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  pointer-events: none;
  user-select: none;
}
.map-scale-label {
  font-size: 11px;
  font-weight: 600;
  color: #0F172A;
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.9),
    0 0 4px rgba(255, 255, 255, 0.7);
  letter-spacing: 0.01em;
  line-height: 1;
}
.map-scale-bar {
  display: block;
  width: var(--scale-px, 100px);
  height: 6px;
  /* U-shape: left tick + right tick + bottom line — Naver-style scale. */
  border-left:   2px solid #0F172A;
  border-right:  2px solid #0F172A;
  border-bottom: 2px solid #0F172A;
  background: rgba(255, 255, 255, 0.55);
  transition: width 180ms ease-out;
}

/* Map provider attribution — sits inside the actual map viewport (right of
   the rail on desktop, above the cat-bar on mobile). Subtle text-only — no
   pill, no green status dot, no shadow. Should NOT look interactive. */
.map-status {
  position: absolute;
  /* Desktop default: inside the map area, just right of the rail. Use the same
     --rail-w token the rail itself reads so the offset stays in sync. */
  bottom: 10px;
  left: calc(var(--rail-w, 80px) + 12px);
  z-index: 10;          /* below rail (25) + cat bar (40) + sheets (30/31) */
  background: transparent;
  color: rgba(100, 116, 139, 0.55);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
  pointer-events: none;
  display: inline-flex;
  align-items: center;
  user-select: none;
}
/* Hide the legacy status dot — not needed in the subtle attribution form. */
.map-status .dot { display: none; }
.map-status.demo,
.map-status.demo-fail { color: rgba(120, 53, 15, 0.7); }

/* Mock map */
.mock-map {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 20% 25%, rgba(37,99,235,0.18) 0%, transparent 40%),
    radial-gradient(circle at 80% 70%, rgba(6,182,212,0.16) 0%, transparent 45%),
    linear-gradient(180deg, #0F172A 0%, #1E293B 100%);
  overflow: hidden;
}
.mock-map .grid {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(148,163,184,0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(148,163,184,0.06) 1px, transparent 1px);
  background-size: 48px 48px;
}
.mock-map .roads {
  position: absolute; inset: 0;
  pointer-events: none;
}

.mock-marker {
  position: absolute;
  transform: translate(-50%, -100%);
  cursor: pointer;
  z-index: var(--z-marker);
  transition: opacity 180ms ease, transform 180ms ease, filter 180ms ease;
}
.mock-marker:hover { transform: translate(-50%, -103%) scale(1.06); }
.mock-marker.is-dim { opacity: 0.32; filter: saturate(0.4); }
.mock-marker.is-highlight { filter: drop-shadow(0 0 8px rgba(6,182,212,0.7)) drop-shadow(0 0 18px rgba(37,99,235,0.45)); }
.mock-marker.is-active { transform: translate(-50%, -100%); }

/* Naver-rendered marker.
   IMPORTANT: NO `transform: translate(-50%, -100%)` here. Naver's overlay
   already positions the icon so its anchor pixel lands on the lat/lng (we set
   the anchor in NaverMapAdapter via icon.anchor). A CSS translate would shift
   the icon by a CONSTANT pixel offset on top of that, which translates to a
   zoom-DEPENDENT geographic offset (e.g. 56px = ~1km at zoom 13 vs ~30m at
   zoom 18) — making markers appear to "drift" as the user zooms. */
.naver-pack-marker {
  width: 44px;
  height: 56px;
  display: block;
  transition: opacity 180ms ease, filter 180ms ease;
}
.naver-pack-marker.is-dim { opacity: 0.32; filter: saturate(0.4); }
.naver-pack-marker.is-highlight { filter: drop-shadow(0 0 8px rgba(6,182,212,0.7)) drop-shadow(0 0 18px rgba(37,99,235,0.45)); }
/* active = visual emphasis only — anchor / position unchanged. */
.naver-pack-marker.is-active { /* no transform; only z-index + halo via .is-active svg */ }

.user-location-marker,
.naver-user-marker {
  position: absolute;
  width: 24px;
  height: 24px;
  transform: translate(-50%, -50%);
  border-radius: 999px;
  background: rgba(37, 99, 235, 0.18);
  border: 1px solid rgba(37, 99, 235, 0.3);
  box-shadow: 0 0 0 8px rgba(37, 99, 235, 0.12);
  pointer-events: none;
}
.naver-user-marker {
  position: relative;
  transform: none;
}
.user-location-marker::before,
.naver-user-marker span {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: inherit;
  background: var(--brand);
  border: 2px solid #fff;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.25);
}

/* Result panel - mobile bottom sheet */

.result-panel {
  position: fixed;
  left: 0; right: 0;
  bottom: var(--bottomnav-h);
  z-index: var(--z-sheet);
  background: var(--surface);
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
  box-shadow: var(--shadow-overlay);
  max-height: 75vh;
  display: flex;
  flex-direction: column;
  transform: translateY(calc(100% - 96px));
  transition: transform 280ms cubic-bezier(.2,.7,.2,1);
}
.result-panel.expanded { transform: translateY(0); }
.result-panel.collapsed { transform: translateY(calc(100% - 56px)); }

.sheet-handle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 0 4px;
  cursor: grab;
}
.sheet-handle::before {
  content: "";
  width: 36px; height: 4px;
  border-radius: 2px;
  background: var(--surface-mid);
}

.sheet-tabs {
  display: flex;
  gap: 4px;
  padding: 4px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  position: sticky;
  top: 0;
  z-index: 1;
}
.sheet-tab {
  flex: 1;
  padding: 10px 12px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: 0;
  border-radius: var(--r-md);
  position: relative;
}
.sheet-tab.active { color: var(--brand); background: var(--brand-soft); }
.sheet-tab .count { font-family: var(--f-mono); font-size: 11px; margin-left: 4px; opacity: 0.8; }

.sheet-body {
  overflow-y: auto;
  padding: 8px 12px 24px;
  flex: 1;
}

/* Result cards */

.store-card {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: 12px;
  width: 100%;
  padding: 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  margin-bottom: 8px;
  text-align: left;
  cursor: pointer;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.store-card:hover { border-color: var(--brand); box-shadow: var(--shadow-2); }
.store-card.is-active { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }

.store-card .thumb {
  width: 56px; height: 56px;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--bg-base), var(--bg-elev-2));
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  position: relative;
}
.store-card .thumb svg { width: 32px; height: 32px; color: var(--holo); }
.store-card .body { min-width: 0; display: grid; gap: 6px; }
.store-card .row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.store-card .title-row { justify-content: space-between; gap: 8px; }
.store-card .name {
  font-size: 14.5px; font-weight: 700; color: var(--text-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  flex: 1; min-width: 0; line-height: 1.3; margin: 0;
}
.store-card .rating { font-size: 12px; color: var(--text-strong); white-space: nowrap; flex-shrink: 0; display: inline-flex; align-items: baseline; gap: 2px; }
.store-card .rating .muted { color: var(--text-muted); margin-left: 4px; }
.store-card .addr { font-size: 12.5px; color: var(--text-muted); }
.store-card .addr .muted { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.store-card .badges { flex-wrap: nowrap; overflow: hidden; }
.store-card .badges .badge { white-space: nowrap; flex-shrink: 0; }
.store-card .meta { justify-content: space-between; font-size: 12px; color: var(--text-muted); }
.store-card .meta .holo.today {
  background: linear-gradient(120deg, #06B6D4, #2563EB, #06B6D4);
  background-size: 200% 200%;
  animation: holo-shift 2.4s ease infinite;
  color: #fff;
  border: 0;
}
@keyframes holo-shift {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}

.product-card {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  gap: 12px;
  padding: 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  margin-bottom: 8px;
  cursor: pointer;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.product-card:hover { border-color: var(--brand); box-shadow: var(--shadow-1); }
.product-card .icon {
  width: 44px; height: 44px;
  border-radius: var(--r-sm);
  background: var(--surface-soft);
  display: flex; align-items: center; justify-content: center;
  color: var(--holo);
}
.product-card .info h4 { font-size: 14px; margin-bottom: 2px; }
.product-card .info .meta { font-size: 12px; color: var(--text-muted); }
.product-card .info .badges { display: flex; gap: 4px; margin-top: 4px; flex-wrap: wrap; }
.product-card .right { text-align: right; font-size: 11px; color: var(--text-muted); display: flex; flex-direction: column; gap: 4px; align-items: flex-end; }
.product-card .right .count { font-family: var(--f-mono); font-size: 13px; font-weight: 600; color: var(--brand); }

.empty {
  text-align: center;
  padding: 36px 16px;
  color: var(--text-muted);
  font-size: 14px;
}
.empty svg { color: var(--text-subtle); margin-bottom: 12px; }

.section-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  color: var(--text-muted);
  padding: 12px 4px 6px;
}
.section-title .count { font-family: var(--f-mono); }

/* Filter drawer */
.filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-strong);
  box-shadow: var(--shadow-1);
}
.filter-toggle.has-active { background: var(--brand); color: #fff; border-color: var(--brand); }
.filter-toggle .pill-count {
  background: rgba(255,255,255,0.32);
  font-family: var(--f-mono);
  font-size: 11px;
  padding: 0 6px;
  border-radius: 999px;
  min-width: 18px;
  text-align: center;
}

.filter-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(15, 23, 42, 0.5);
  backdrop-filter: blur(2px);
  display: none;
  align-items: flex-end;
  justify-content: center;
}
.filter-modal.open { display: flex; }
.filter-modal-inner {
  background: var(--surface);
  width: 100%;
  max-width: 560px;
  max-height: 86vh;
  border-radius: 16px 16px 0 0;
  padding: 16px;
  overflow-y: auto;
  box-shadow: var(--shadow-3);
  animation: sheet-up 240ms ease;
}
@keyframes sheet-up { from { transform: translateY(20px); opacity: 0;} to { transform: translateY(0); opacity: 1;} }

.filter-section { padding: 12px 0; border-bottom: 1px solid var(--border); }
.filter-section:last-child { border-bottom: 0; }
.filter-section h4 { margin-bottom: 8px; font-size: 13px; }
.filter-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-pill {
  padding: 6px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  font-size: 13px;
  color: var(--text-strong);
}
.filter-pill:hover { border-color: var(--brand); color: var(--brand); }
.filter-pill.on { background: var(--brand); color: #fff; border-color: var(--brand); }
.filter-pill[disabled] { opacity: 0.5; cursor: not-allowed; }

.filter-actions { display: flex; gap: 8px; margin-top: 12px; }

/* Store detail panel */
.detail-panel {
  position: fixed;
  inset: auto 0 var(--bottomnav-h) 0;
  z-index: var(--z-modal);
  background: var(--surface);
  max-height: 88vh;
  border-radius: 16px 16px 0 0;
  box-shadow: var(--shadow-3);
  display: none;
  flex-direction: column;
  overflow: hidden;
}
.detail-panel.open { display: flex; animation: sheet-up 260ms ease; }

.detail-header {
  position: relative;
  padding: 16px;
  background: linear-gradient(180deg, var(--bg-base) 0%, var(--bg-elev-1) 100%);
  color: var(--text-on-dark);
}
.detail-close {
  position: absolute;
  top: 12px; right: 12px;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: rgba(255,255,255,0.12);
  color: #fff;
  border: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.detail-header h2 { color: var(--text-on-dark); font-size: 20px; margin-bottom: 4px; padding-right: 36px; }
.detail-header .meta { font-size: 13px; color: var(--text-subtle); display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.detail-header .meta .badge { background: rgba(255,255,255,0.10); border-color: rgba(255,255,255,0.14); color: #fff; }

.detail-body {
  overflow-y: auto;
  padding: 16px;
  background: var(--surface-soft);
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 16px;
}
.summary-cell {
  padding: 10px 8px;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--border);
  text-align: center;
}
.summary-cell .num { font-family: var(--f-mono); font-size: 18px; font-weight: 700; }
.summary-cell .label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.summary-cell.ample .num    { color: var(--st-ample); }
.summary-cell.low .num      { color: var(--st-low); }
.summary-cell.soldout .num  { color: var(--st-soldout); }

.detail-info { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 12px; margin-bottom: 16px; }
.detail-info .row { display: flex; gap: 8px; padding: 6px 0; font-size: 13px; align-items: flex-start; }
.detail-info .row .k { width: 72px; flex-shrink: 0; color: var(--text-muted); }
.detail-info .row .v { flex: 1; color: var(--text-strong); }

.detail-products { display: flex; flex-direction: column; gap: 8px; }
.detail-product {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.detail-product .name { font-weight: 600; font-size: 14px; }
.detail-product .meta { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.detail-product .badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.detail-product .right { text-align: right; }
.detail-product .stock-num { font-family: var(--f-mono); font-size: 16px; font-weight: 700; color: var(--text-strong); }
.detail-product .stock-num.zero { color: var(--st-soldout); }
.detail-product .price { font-family: var(--f-mono); font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.detail-product .small { font-size: 11px; color: var(--text-muted); margin-top: 4px; }

details.soldout-block {
  margin-top: 12px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface-soft);
}
details.soldout-block summary {
  padding: 10px 12px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  list-style: none;
}
details.soldout-block summary::-webkit-details-marker { display: none; }
details.soldout-block summary::after { content: "▾"; float: right; transition: transform 200ms; }
details.soldout-block[open] summary::after { transform: rotate(180deg); }
details.soldout-block .detail-products { padding: 8px 12px 12px; }

/* Nearby + FAQ in sheet */
.nearby-section { margin-bottom: 18px; }
.nearby-section .section-title svg { color: var(--brand); }

.faq-list { display: flex; flex-direction: column; gap: 6px; }
.faq-item {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--r-md);
}
.faq-item summary {
  cursor: pointer;
  padding: 12px;
  font-weight: 600;
  font-size: 14px;
  list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; float: right; font-weight: 400; color: var(--text-muted); transition: transform 200ms; }
.faq-item[open] summary::after { content: "−"; }
.faq-item .answer { padding: 0 12px 12px; font-size: 13px; color: var(--text-muted); line-height: 1.6; }

/* ===== Owner login ===== */

.center-shell {
  min-height: calc(100vh - var(--bottomnav-h));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
}

.login-card {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: 28px 24px;
  box-shadow: var(--shadow-2);
  border: 1px solid var(--border);
}
.login-card h1 { margin-bottom: 6px; }
.login-card p.lead { color: var(--text-muted); font-size: 14px; margin-bottom: 24px; }

.oauth-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.oauth-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  font-weight: 600;
  font-size: 14px;
  border: 1px solid transparent;
  min-height: 48px;
  position: relative;
  transition: filter 160ms ease;
}
.oauth-btn:hover { filter: brightness(0.96); }
.oauth-btn .spinner {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  display: none;
  animation: spin 700ms linear infinite;
}
.oauth-btn.loading .spinner { display: inline-block; }
.oauth-btn.loading .icon { display: none; }
@keyframes spin { to { transform: rotate(360deg); } }

.oauth-google { background: #fff; color: #1F2937; border-color: #E5E7EB; }
.oauth-kakao  { background: #FEE500; color: #3D2E00; }
.oauth-kakao .spinner { color: #3D2E00; }
.oauth-naver  { background: #03C75A; color: #fff; }

.oauth-divider { display: flex; align-items: center; gap: 10px; color: var(--text-muted); font-size: 12px; margin: 14px 0; }
.oauth-divider::before, .oauth-divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }

.guest-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  font-weight: 600;
  background: var(--surface-soft);
  border: 1px dashed var(--border-strong);
  color: var(--text-strong);
  min-height: 48px;
}

.login-links { display: flex; justify-content: center; gap: 16px; margin-top: 18px; font-size: 13px; }
.login-foot { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--border); font-size: 11px; color: var(--text-subtle); text-align: center; line-height: 1.6; }

/* ===== Dashboard ===== */

.dash-grid {
  max-width: 1200px;
  margin: 0 auto;
  padding: 16px;
  display: grid;
  gap: 16px;
}

.state-switcher {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #FEF3C7;
  border: 1px dashed #FBBF24;
  border-radius: var(--r-md);
  padding: 10px 12px;
  font-size: 12px;
  color: #92400E;
}
.state-switcher select { padding: 4px 8px; border-radius: var(--r-sm); }

.dash-banner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  padding: 14px;
  border-radius: var(--r-lg);
  background: linear-gradient(135deg, #0F172A 0%, #1E293B 50%, #0F172A 100%);
  color: #fff;
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(6, 182, 212, 0.18);
}
.dash-banner::before {
  content: "";
  position: absolute;
  top: -2px; right: -2px; bottom: -2px; left: -2px;
  background: linear-gradient(120deg, transparent 30%, rgba(6,182,212,0.18) 50%, transparent 70%);
  pointer-events: none;
}
.dash-banner .row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.dash-banner .pill {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.16);
  padding: 6px 12px;
  border-radius: var(--r-pill);
  font-size: 13px;
  font-weight: 600;
}
.dash-banner .pill.warn { background: rgba(249,115,22,0.18); border-color: rgba(249,115,22,0.32); }
.dash-banner .pill.danger { background: rgba(239,68,68,0.18); border-color: rgba(239,68,68,0.32); }
.dash-banner .updated-at { font-family: var(--f-mono); font-size: 11px; color: var(--text-subtle); }

.dash-section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 16px;
}
.dash-section h2 { font-size: 16px; margin-bottom: 8px; }
.dash-section .section-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.dash-section .section-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; gap: 8px; flex-wrap: wrap; }

/* Product table */
.product-table-wrap { overflow-x: auto; }
.product-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.product-table th, .product-table td {
  text-align: left;
  padding: 10px 8px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.product-table th {
  background: var(--surface-soft);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.product-table tr:hover td { background: rgba(37,99,235,0.04); }
.product-table .stock-cell { font-family: var(--f-mono); font-weight: 700; }
.product-table .actions { display: flex; gap: 4px; }
.product-table input[type=checkbox] { width: 16px; height: 16px; }

.qty-stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.qty-stepper button {
  background: var(--surface);
  border: 0;
  padding: 4px 8px;
  font-size: 14px;
  color: var(--text-strong);
  min-width: 28px;
  min-height: 30px;
}
.qty-stepper input {
  width: 48px;
  text-align: center;
  border: 0;
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
  padding: 4px 2px;
  font-family: var(--f-mono);
  font-size: 13px;
  outline: 0;
  min-height: 30px;
}

/* Product card list (mobile) */
.product-cards { display: none; flex-direction: column; gap: 8px; }
.product-cards .pcard {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--r-md);
  padding: 12px;
}
.product-cards .pcard header { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 8px; }
.product-cards .pcard h3 { font-size: 14px; }
.product-cards .pcard .meta { font-size: 12px; color: var(--text-muted); }
.product-cards .pcard .row { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.product-cards .pcard .badges { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 6px; }

/* Modal */
.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(15, 23, 42, 0.6);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.modal.open { display: flex; }
.modal-card {
  width: 100%;
  max-width: 520px;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}
.modal-head { padding: 16px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; }
.modal-body { padding: 16px; overflow-y: auto; }
.modal-foot { padding: 12px 16px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 8px; }

/* Account / settings */
.account-card { display: grid; gap: 12px; }
.account-row { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; gap: 8px; flex-wrap: wrap; }
.account-row .lab { font-size: 13px; color: var(--text-muted); }
.account-row .val { font-size: 14px; font-weight: 500; }

.banner-guest {
  background: var(--accent-yellow);
  color: #92400E;
  padding: 10px 14px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid #FBBF24;
}

/* Empty / state-specific cards */
.state-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 24px;
  text-align: center;
  box-shadow: var(--shadow-1);
}
.state-card svg { color: var(--brand); margin-bottom: 12px; }
.state-card h2 { margin-bottom: 6px; }
.state-card p { color: var(--text-muted); margin-bottom: 16px; }
.state-card .actions { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }

/* ===== Guide page ===== */

.guide-shell { max-width: 960px; margin: 0 auto; padding: 24px 16px 60px; }
.guide-hero {
  background: linear-gradient(135deg, #0F172A 0%, #1E293B 50%, #2563EB 200%);
  color: #fff;
  border-radius: var(--r-lg);
  padding: 36px 24px;
  margin-bottom: 24px;
  position: relative;
  overflow: hidden;
}
.guide-hero::after {
  content: "";
  position: absolute;
  inset: -40% -20% auto auto;
  width: 320px; height: 320px;
  background: radial-gradient(circle, rgba(6,182,212,0.32) 0%, transparent 60%);
  pointer-events: none;
}
.guide-hero h1 { font-size: 32px; color: #fff; margin-bottom: 10px; max-width: 26ch; }
.guide-hero p  { color: var(--text-subtle); max-width: 50ch; font-size: 15px; }
.guide-hero .actions { margin-top: 20px; display: flex; gap: 8px; flex-wrap: wrap; }

.guide-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: 24px;
}
.guide-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.guide-tile .num {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: var(--brand-soft);
  color: var(--brand);
  font-family: var(--f-mono);
  font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.guide-tile h3 { font-size: 16px; }
.guide-tile p { font-size: 13px; color: var(--text-muted); line-height: 1.65; }

.guide-types {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin: 16px 0;
}
.guide-types .type-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
}
.guide-types .type-tile svg { color: var(--brand); }

.guide-section { margin-bottom: 28px; }
.guide-section h2 { font-size: 20px; margin-bottom: 10px; }
.guide-section p { color: var(--text-muted); font-size: 14px; line-height: 1.7; }
.guide-section ul { padding-left: 20px; color: var(--text-muted); font-size: 14px; line-height: 1.8; }

.cta-block {
  background: var(--bg-base);
  color: #fff;
  border-radius: var(--r-lg);
  padding: 28px 24px;
  text-align: center;
}
.cta-block h2 { color: #fff; margin-bottom: 6px; }
.cta-block p { color: var(--text-subtle); margin-bottom: 16px; }
.cta-block .actions { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }

/* ===== Terms ===== */

.terms-shell {
  max-width: 760px;
  margin: 0 auto;
  padding: 28px 18px 60px;
}
.terms-shell h1 { font-size: 26px; margin-bottom: 6px; }
.terms-shell .meta { color: var(--text-muted); font-size: 13px; margin-bottom: 24px; }
.terms-shell article { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 22px; }
.terms-shell article h2 { font-size: 18px; margin-top: 24px; margin-bottom: 8px; }
.terms-shell article h2:first-child { margin-top: 0; }
.terms-shell article p, .terms-shell article li { font-size: 14px; line-height: 1.75; color: var(--text-strong); }
.terms-shell article ul { padding-left: 20px; }
.terms-shell .callout {
  background: var(--brand-soft);
  border: 1px solid #BFDBFE;
  border-radius: var(--r-md);
  padding: 12px 14px;
  margin: 12px 0;
  font-size: 13px;
  color: #1E3A8A;
  line-height: 1.7;
}

/* ===== Admin ===== */

.admin-shell { max-width: 1280px; margin: 0 auto; padding: 16px; display: grid; gap: 16px; }
.admin-tabs { display: flex; gap: 4px; }
.admin-tab {
  padding: 8px 14px;
  border-radius: var(--r-md);
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-strong);
  font-weight: 600;
  font-size: 13px;
}
.admin-tab.active { background: var(--brand); color: #fff; border-color: var(--brand); }

/* =====================================================================
   Admin — 사업자 / 매장 연결 탭 (Phase 4)
   ===================================================================== */
.owner-link-form {
  display: grid;
  grid-template-columns: 1fr 1.4fr 1fr auto;
  gap: 10px;
  align-items: end;
  padding: 12px 16px 16px;
}
@media (max-width: 900px) {
  .owner-link-form { grid-template-columns: 1fr 1fr; }
  .owner-link-actions { grid-column: 1 / -1; }
}
@media (max-width: 540px) {
  .owner-link-form { grid-template-columns: 1fr; }
}
.owner-link-field { display: flex; flex-direction: column; gap: 4px; }
.owner-link-label {
  font-size: 12px;
  color: var(--text-muted, #6B7280);
  font-weight: 600;
}
.owner-link-form input,
.owner-link-form select {
  padding: 8px 10px;
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 6px;
  font-size: 13.5px;
  background: var(--surface, #FFFFFF);
  color: var(--text-strong, #0F172A);
  font-family: inherit;
}
.owner-link-form input:focus,
.owner-link-form select:focus {
  outline: none;
  border-color: var(--brand, #2563EB);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.owner-link-actions {
  display: flex;
  gap: 6px;
  align-items: stretch;
}

/* 사장 목록 테이블 */
.owner-table-wrap {
  padding: 0 16px 16px;
  overflow-x: auto;
}
.owner-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  background: var(--surface, #FFFFFF);
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 8px;
  overflow: hidden;
}
.owner-table th,
.owner-table td {
  text-align: left;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border, #E5E7EB);
  vertical-align: top;
}
.owner-table th {
  background: var(--surface-soft, #F3F4F6);
  font-weight: 700;
  font-size: 12px;
  color: var(--text-muted, #6B7280);
  letter-spacing: 0.02em;
}
.owner-table tr:last-child td { border-bottom: 0; }
.owner-email { font-weight: 600; }
.owner-name { font-size: 11.5px; color: var(--text-muted, #6B7280); margin-top: 2px; }
.owner-place-name { font-weight: 600; }
.owner-place-meta { font-size: 11.5px; color: var(--text-muted, #6B7280); margin-top: 2px; }
.owner-when { font-size: 12px; color: var(--text-muted, #6B7280); white-space: nowrap; }
.owner-role {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  text-transform: lowercase;
}
.owner-role--admin    { background: rgba(220, 38, 38, 0.12); color: #DC2626; }
.owner-role--business { background: rgba(37, 99, 235, 0.12); color: #2563EB; }
.owner-role--user     { background: rgba(107, 114, 128, 0.14); color: #4B5563; }
.owner-unlink {
  background: transparent;
  border: 1px solid var(--border, #E5E7EB);
  color: #DC2626;
  padding: 5px 10px;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
}
.owner-unlink:hover { background: rgba(220, 38, 38, 0.08); border-color: #DC2626; }

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 14px;
}
.kpi .num { font-family: var(--f-mono); font-size: 22px; font-weight: 700; }
.kpi .lab { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.kpi.brand { background: linear-gradient(135deg, var(--brand) 0%, var(--holo) 200%); color: #fff; border-color: transparent; }
.kpi.brand .lab { color: rgba(255,255,255,0.8); }

/* Stock summary bar */
.stock-bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; min-width: 96px; }
.stock-bar span { display: block; height: 100%; }
.stock-bar .ample { background: var(--st-ample); }
.stock-bar .normal { background: var(--st-normal); }
.stock-bar .low { background: var(--st-low); }
.stock-bar .soldout { background: var(--st-soldout); }

.application-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 14px;
  margin-bottom: 8px;
}
.application-card header { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 8px; }
.application-card h3 { font-size: 15px; margin-bottom: 2px; }
.application-card .meta { font-size: 12px; color: var(--text-muted); }
.application-card .grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
  font-size: 13px;
  margin: 8px 0;
}
.application-card .grid .k { color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
.application-card .actions { display: flex; gap: 6px; flex-wrap: wrap; }
.application-card .reason { background: var(--danger-soft); padding: 8px 10px; border-radius: var(--r-sm); font-size: 12px; color: #7F1D1D; margin-top: 6px; }

/* ===== Stocks holo border on hover ===== */

.holo-border {
  position: relative;
}
.holo-border::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from 0deg, transparent 0%, var(--holo) 25%, var(--brand) 50%, var(--accent-yellow) 75%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms ease;
  animation: spin-slow 4s linear infinite;
}
.holo-border:hover::after { opacity: 1; }
@keyframes spin-slow {
  to { transform: rotate(360deg); }
}

/* ===== Reduced motion ===== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ===== Responsive Breakpoints ===== */

@media (min-width: 640px) {
  h1 { font-size: 32px; }
  .guide-grid { grid-template-columns: repeat(3, 1fr); }
  .guide-types { grid-template-columns: repeat(3, 1fr); }
  .kpi-grid { grid-template-columns: repeat(4, 1fr); }
}

@media (min-width: 768px) {
  .product-cards { display: none !important; }
  .product-table-wrap { display: block; }
  .field-row { grid-template-columns: 1fr 1fr 1fr; }
}

@media (max-width: 767px) {
  .product-table-wrap { display: none; }
  .product-cards { display: flex; }
}

@media (min-width: 1024px) {
  .map-shell {
    height: 100vh;
    padding-bottom: 0;
  }
  .app-shell { padding-bottom: 0; }
  .bottom-nav { display: none; }
  /* v17: .search-bar deprecated — split into .search-shell-anchor + .chip-row-anchor.
     Top anchor is 16px on desktop (matches FAB right). */
  .search-shell-anchor, .chip-row-anchor { top: 16px; }
  /* Desktop: locate FAB sits ABOVE the scale bar (bottom 16px + ~24px tall +
     ~32px gap = bottom 72px) and BELOW the custom zoom column. */
  .map-shell .map-fab { right: 16px; bottom: 72px; }

  .result-panel, .detail-panel { display: none !important; }
  .sheet-handle { display: none; }

  /* Desktop attribution: stay INSIDE the map area (rail occupies the first
     --rail-w pixels). When the list sidebar is also open, push past it so the
     attribution stays in the actual visible map strip — never under a panel. */
  .map-status { bottom: 12px; left: calc(var(--rail-w, 80px) + 14px); }
  .map-shell[data-layout="rail-list"] .map-status,
  .map-shell[data-layout="rail-list-detail"] .map-status {
    left: calc(var(--rail-w, 80px) + var(--list-w, 380px) + 14px);
  }

  /* desktop header for non-map pages */
  .desktop-only { display: inline-flex; }

  .dash-grid, .admin-shell {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 1440px) {
  .chip-row-anchor { right: 24px; }
  .map-shell .map-fab { right: 24px; }
  /* Keep custom zoom + scale aligned to the same right gutter as the FAB. */
  .map-zoom  { right: 22px; }
  .map-scale { right: 24px; }
  .summary-grid { grid-template-columns: repeat(4, 1fr); }
}

/* ===== Utilities ===== */

.row { display: flex; gap: 8px; align-items: center; }
.col { display: flex; flex-direction: column; gap: 8px; }
.gap-4 { gap: 4px; } .gap-8 { gap: 8px; } .gap-12 { gap: 12px; } .gap-16 { gap: 16px; }
.mb-8 { margin-bottom: 8px; } .mb-12 { margin-bottom: 12px; } .mb-16 { margin-bottom: 16px; }
.mt-8 { margin-top: 8px; } .mt-12 { margin-top: 12px; } .mt-16 { margin-top: 16px; }
.text-center { text-align: center; }
.f-bold { font-weight: 700; }
.hidden { display: none !important; }
.spacer { flex: 1; }

/* Visually hidden */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ===== Diagnostic panel (?diag=1) ===== */
.diag-panel {
  position: fixed;
  top: 12px; right: 12px;
  z-index: 99999;
  background: rgba(15, 23, 42, 0.94);
  color: #F8FAFC;
  border: 1px solid rgba(6, 182, 212, 0.4);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: var(--f-mono);
  font-size: 11px;
  line-height: 1.45;
  max-width: 320px;
  box-shadow: 0 10px 24px rgba(15,23,42,0.45);
  pointer-events: none;
}
.diag-panel .diag-title { font-weight: 700; color: #06B6D4; letter-spacing: 0.06em; margin-bottom: 6px; }
.diag-panel .diag-row { display: flex; justify-content: space-between; gap: 12px; }
.diag-panel .diag-v { font-weight: 600; }
.diag-panel .diag-v.pending { color: #94A3B8; }
.diag-panel .diag-v.ok { color: #22C55E; }
.diag-panel .diag-v.fail { color: #EF4444; }
.diag-panel .diag-v.warn { color: #F97316; }

/* ===== Rail + Wide sidebar ===== */
.map-rail {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  z-index: 25;
  width: var(--rail-w);
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  align-items: stretch;
  padding: 12px 6px;
  gap: 6px;
}

/* Rail-top logo — sits at the very top of the desktop rail above the
   category buttons. Click resets the home state (close detail/sidebar,
   deselect category). The PNG asset is RGB without alpha (white bg) — the
   rail surface is also white, so the two blend without showing a square. */
.rail-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 6px 2px 8px;
  margin: -4px 0 4px;            /* pull tight against the rail's top padding */
  border: 0;
  background: transparent;       /* PNG 가 transparent corners 라 wrapper 도 투명 */
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.rail-logo:hover { background: rgba(15, 23, 42, 0.04); }
.rail-logo img {
  display: block;
  width: 100%;
  max-height: 56px;
  object-fit: contain;            /* preserve 2:1 ratio — no crop/squish */
}
.rail-item {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  padding: 10px 4px;
  border: 0; background: transparent;
  border-radius: var(--r-md);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 11px; font-weight: 600;
  position: relative;
}
.rail-item:hover { background: var(--surface-soft); color: var(--text-strong); }
.rail-item.active { background: var(--brand-soft); color: var(--brand); }
.rail-item.active::before {
  content: ""; position: absolute; left: -6px; top: 8px; bottom: 8px;
  width: 3px; border-radius: 0 2px 2px 0; background: var(--brand);
}
/* Rail category icons — 투명 배경 PNG (`_t.png` 시리즈) 사용. wrapper 자체는
   배경/테두리/그림자/border-radius 없이 완전 투명 → 사각형 흔적 0. rail 자체가
   --surface(#fff) 위에 놓여 있으므로 PNG 의 anti-alias 가장자리도 자연스럽게 합쳐짐. */
.rail-icon {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
}
.rail-icon svg { width: 22px; height: 22px; }
/* Asset-based rail icons (card_shop / pokemon_vending_machine) — preserve the
   1:1 source aspect via object-fit:contain. No mask / clip-path / border-radius. */
.rail-icon .rail-icon-img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
}
.rail-count {
  font-family: var(--f-mono);
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-muted);
  background: var(--surface-soft);
  border-radius: 8px;
  padding: 1px 6px;
  margin-top: 2px;
}
/* 카드샵/자판기/문구점 numeric 카운트는 rail 표시 안 함 — 단순 라벨만. */
.rail-count[data-count-for="card_shop"],
.rail-count[data-count-for="pokemon_vending_machine"],
.rail-count[data-count-for="stationery_store"] {
  display: none;
}
.rail-item.active .rail-count { background: var(--brand); color: #fff; }
.rail-item[data-cat="pokemon_vending_machine"].active .rail-count { background: var(--accent-yellow); color: #1F2937; }

/* === Disabled (Coming Soon) rail items ===
   - Gray out icon + label + count.
   - Block all hover/active visual feedback so users see the category is inert.
   - cursor: not-allowed signals "click does nothing". JS onCategoryClick also
     early-returns for disabled cats — both layers, in case one regresses. */
.rail-item[data-disabled="true"] {
  opacity: 0.42;
  cursor: not-allowed;
  filter: grayscale(0.95);
}
.rail-item[data-disabled="true"]:hover,
.rail-item[data-disabled="true"]:active,
.rail-item[data-disabled="true"].active {
  background: transparent;
  color: var(--text-muted);
}
.rail-item[data-disabled="true"]:hover .rail-icon-img,
.rail-item[data-disabled="true"] .rail-icon-img {
  filter: grayscale(1) opacity(0.85);
}
/* Coming-Soon count pill: replaces the numeric count with a small label. */
.rail-count.rail-count--soon {
  background: #1F2937;
  color: #FDE68A;
  font-size: 8.5px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 1px 4px;
  font-family: var(--f-mono);
  font-weight: 700;
}

.map-sidebar {
  position: absolute;
  left: var(--rail-w); top: 0; bottom: 0;
  z-index: 24;
  width: var(--list-w);
  background: var(--surface);
  border-right: 1px solid var(--border);
  box-shadow: 6px 0 24px rgba(15,23,42,0.08);
  display: flex; flex-direction: column;
  /* search-shell-anchor (top: 12-16, height ~44) rides on top of this aside.
     Push content down by anchor-bottom + 10px so the head divider sits below it. */
  padding-top: 64px;
  transform: translateX(-100%);
  transition: transform 240ms ease-out;
}
.map-sidebar[data-mode="category"],
.map-sidebar[data-mode="search"],
.map-sidebar[data-mode="detail"] {
  transform: translateX(0);
}
.map-sidebar[aria-hidden="true"] { pointer-events: none; }

.sidebar-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px 8px;
  border-bottom: 1px solid var(--border);
}
.sidebar-title { font-size: 15px; font-weight: 700; color: var(--text-strong); margin: 0; flex: 1 1 auto; min-width: 0; }
.sidebar-close { background: transparent; border: 0; color: var(--text-muted); font-size: 16px; padding: 6px; cursor: pointer; border-radius: 6px; }
.sidebar-close:hover { background: var(--surface-soft); color: var(--text-strong); }
.sidebar-back {
  background: transparent; border: 0;
  color: var(--text-strong);
  font-size: 22px; line-height: 1;
  padding: 0; margin: 0 4px 0 -4px;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  cursor: pointer;
  flex-shrink: 0;
}
.sidebar-back:hover { background: var(--surface-soft); }
.sidebar-back[hidden] { display: none; }

.sidebar-search { padding: 10px 16px; border-bottom: 1px solid var(--border); }
.sidebar-search input {
  width: 100%; padding: 9px 12px; border-radius: var(--r-md);
  border: 1px solid var(--border); background: var(--surface-soft);
  font-size: 14px; color: var(--text-strong); outline: none;
}
.sidebar-search input:focus { border-color: var(--brand); background: var(--surface); }
.sidebar-search input::placeholder { color: var(--text-subtle); }

.sidebar-body { flex: 1; overflow-y: auto; padding: 10px 12px 24px; }
.sidebar-section { display: block; }
.sidebar-section[hidden] { display: none; }
.sidebar-list { display: flex; flex-direction: column; gap: 8px; }
.sidebar-empty { padding: 32px 16px; text-align: center; color: var(--text-muted); font-size: 13px; }

.sidebar-collapse {
  position: absolute;
  right: -16px; top: 50%; transform: translateY(-50%);
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-2);
  color: var(--text-muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 700;
}
.sidebar-collapse:hover { color: var(--brand); border-color: var(--brand); }
.map-sidebar[data-mode="closed"] .sidebar-collapse { display: none; }

/* ===== Rail-edge sidebar toggle (always available) =====
   Position is driven by .map-shell[data-layout=...]:
     rail               → rail's outer edge
     rail-list          → list panel's outer edge
     rail-list-detail   → detail panel's outer edge
   Sticking to data-layout (single source of truth) keeps the toggle aligned
   with whichever panel is the right-most open one. */
.rail-toggle {
  position: absolute;
  left: var(--rail-w); top: 50%;
  transform: translateY(-50%);
  width: 22px; height: 56px;
  z-index: 27;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 0;
  border-radius: 0 12px 12px 0;
  box-shadow: 4px 0 12px rgba(15,23,42,0.08);
  color: var(--text-muted);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; line-height: 1;
  transition: left 240ms ease-out, color 160ms ease, border-color 160ms ease;
  padding: 0;
}
.map-shell[data-layout="rail-list"] .rail-toggle {
  left: calc(var(--rail-w) + var(--list-w));
}
.map-shell[data-layout="rail-list-detail"] .rail-toggle {
  /* sit flush against the floating detail's right edge (panel left = rail+list+12) */
  left: calc(var(--rail-w) + var(--list-w) + 12px + var(--detail-w));
}
@media (max-width: 600px) {
  .map-shell[data-layout="rail-list"] .rail-toggle,
  .map-shell[data-layout="rail-list-detail"] .rail-toggle {
    left: calc(100vw - 22px);
  }
}
.rail-toggle:hover { color: var(--brand); border-color: var(--brand); }
.rail-toggle .rail-toggle-arrow { display: inline-block; transition: transform 200ms ease; }
.rail-toggle[aria-expanded="true"] .rail-toggle-arrow { transform: rotate(180deg); }
@media (max-width: 600px) {
  .rail-toggle { left: 56px; height: 48px; width: 20px; }
}

/* search-bar / chip-row 위치 보정: rail 폭 만큼 오른쪽으로 */
/* search-bar / FAB never overlap a sidebar — left offset follows data-layout. */
.map-shell .search-bar {
  left: calc(var(--rail-w) + 12px);
  right: 16px;
  transition: left 240ms ease-out, right 240ms ease-out;
}
.map-shell[data-layout="rail-list"] .search-bar {
  left: calc(var(--rail-w) + var(--list-w) + 12px);
}
.map-shell[data-layout="rail-list-detail"] .search-bar {
  left: calc(var(--rail-w) + var(--list-w) + var(--detail-w) + 12px);
}
@media (max-width: 768px) {
  /* Mobile uses bottom nav; the rail logo isn't shown on mobile. */
  .rail-logo { display: none !important; }
}
@media (max-width: 600px) {
  .map-rail { padding: 8px 4px; }
  .rail-item { font-size: 10.5px; padding: 8px 2px; }
  .map-sidebar { width: calc(100vw - var(--rail-w)); }
  .map-shell .search-bar,
  .map-shell[data-layout="rail-list"] .search-bar,
  .map-shell[data-layout="rail-list-detail"] .search-bar {
    left: calc(var(--rail-w) + 8px);
    right: 8px;
  }
}

/* 자판기 카테고리 활성 시 — rail-item 좌측 인디케이터 노란 액센트 */
.rail-item.active[data-cat="pokemon_vending_machine"]::before {
  background: var(--accent-yellow);
}

.sidebar-detail { padding: 0 4px; }
.sidebar-detail .detail-empty { padding: 32px 16px; text-align: center; color: var(--text-muted); font-size: 13px; }

/* Vending machine card / detail */
.badge.type.vending {
  background: #FEF3C7;
  color: #78350F;
  border: 1px solid #FCD34D;
}
.store-card--vending .thumb-vending {
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  /* No overflow:hidden — original aspect of the asset must show in full. */
}
.store-card--vending .thumb-vending svg { width: 80%; height: 80%; }
.store-card--vending .thumb-vending .thumb-vending-img {
  /* Keep original 1:1 ratio (asset is 1254×1254). object-fit: contain prevents
     the photo from being cropped to fill the thumb container. */
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
}
.store-card--vending .meta a.link {
  color: var(--brand);
  font-weight: 600;
  text-decoration: none;
}
.store-card--vending .meta a.link:hover { text-decoration: underline; }

/* Card-shop list card — uses the same shell as vending but with the asset
   PNG of the red storefront pin (matches the marker on the map). */
.store-card--cardshop .thumb-cardshop {
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  /* No overflow:hidden / mask — pin shape must render uncut. */
}
.store-card--cardshop .thumb-cardshop svg { width: 80%; height: 80%; }
.store-card--cardshop .thumb-cardshop .thumb-cardshop-img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
}
.store-card--official-cardshop .thumb-cardshop {
  background:
    radial-gradient(circle at 50% 42%, rgba(255, 255, 255, 0.96), rgba(248, 250, 252, 0.72) 48%, rgba(239, 246, 255, 0.55));
  box-shadow: inset 0 0 0 1px rgba(37, 99, 235, 0.12);
}
.store-card--cardshop .meta a.link {
  color: var(--brand);
  font-weight: 600;
  text-decoration: none;
}
.store-card--cardshop .meta a.link:hover { text-decoration: underline; }
.badge.type.cardshop {
  background: #FEE2E2;
  color: #991B1B;
  border: 1px solid #FCA5A5;
}
.badge.type.cardshop.official {
  color: #1E3A8A;
  border-color: rgba(37, 99, 235, 0.28);
  background: linear-gradient(135deg, #DBEAFE 0%, #F8FAFC 48%, #FEF3C7 100%);
}

/* 문구점 리스트 카드 + 배지 — 카드샵과 동일 레이아웃, 컬러만 파란 톤. */
.store-card--stationery .thumb-stationery {
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
}
.store-card--stationery .thumb-stationery svg { width: 80%; height: 80%; }
.store-card--stationery .meta a.link {
  color: var(--brand);
  font-weight: 600;
  text-decoration: none;
}
.store-card--stationery .meta a.link:hover { text-decoration: underline; }
.badge.type.stationery {
  background: #DBEAFE;
  color: #1E3A8A;
  border: 1px solid #93C5FD;
}

/* =====================================================================
   문구점 안내 배너 — 카테고리 첫 클릭 시 1회 노출 modal.
   고경고 톤 X. 깔끔한 정보 카드 + brand 한 줄 액센트.
===================================================================== */
.stationery-notice {
  position: fixed;
  inset: 0;
  z-index: 1500;          /* login modal(1000) 보다 위, 시스템 dialog 톤 */
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  font-family: var(--f-sans);
}
.stationery-notice.is-open { display: flex; }
.stationery-notice-backdrop {
  position: absolute; inset: 0;
  background: rgba(15, 23, 42, 0.45);
  -webkit-backdrop-filter: blur(2px);
          backdrop-filter: blur(2px);
}
.stationery-notice-card {
  position: relative;
  z-index: 1;
  width: min(420px, 100%);
  background: #FFFFFF;
  border-radius: 16px;
  padding: 22px 22px 18px;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.6) inset,
    0 20px 50px rgba(15,23,42,0.22),
    0 6px 12px rgba(15,23,42,0.06);
  overflow: hidden;
}
.stationery-notice-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, #2563EB 0%, #93C5FD 100%);
}
.stationery-notice-close {
  position: absolute;
  top: 8px; right: 8px;
  width: 30px; height: 30px;
  z-index: 2;
  pointer-events: auto;
  border: none;
  background: transparent;
  color: rgba(15,23,42,0.45);
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.stationery-notice-close:hover {
  background: rgba(15,23,42,0.06);
  color: rgba(15,23,42,0.85);
}
.stationery-notice-title {
  margin: 4px 36px 10px 0;
  font-size: 16px;
  font-weight: 700;
  color: #0F172A;
  letter-spacing: -0.01em;
}
.stationery-notice-body {
  margin: 0 0 16px;
  font-size: 13.5px;
  line-height: 1.55;
  color: rgba(15,23,42,0.72);
}
.stationery-notice-actions {
  display: flex;
  justify-content: flex-end;
}
.stationery-notice-btn {
  background: #2563EB;
  color: #FFFFFF;
  border: none;
  padding: 9px 18px;
  border-radius: 9px;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background 120ms ease;
}
.stationery-notice-btn:hover { background: #1D4ED8; }
.stationery-notice-btn:active { background: #1E40AF; }

@media (max-width: 480px) {
  .stationery-notice { padding: 12px; align-items: flex-end; padding-bottom: max(12px, env(safe-area-inset-bottom)); }
  .stationery-notice-card { width: 100%; }
  .stationery-notice-actions .stationery-notice-btn { width: 100%; padding: 12px 18px; }
}

.detail-vending {
  display: flex; flex-direction: column; gap: 10px;
  padding: 16px;
}
.detail-vending .vending-thumb {
  width: 88px; height: 88px;
  background: var(--surface);
  border-radius: 50%;
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  align-self: center;
}
.detail-vending .vending-thumb svg { width: 64px; height: 64px; }
.detail-vending h3 { font-size: 16px; font-weight: 700; text-align: center; margin: 0; color: var(--text-strong); }
.detail-vending .meta-line { text-align: center; font-size: 13px; color: var(--text-muted); }
.detail-vending .actions { display: flex; gap: 8px; justify-content: center; margin-top: 8px; }
.detail-vending .btn-primary {
  background: var(--brand); color: #fff; padding: 10px 16px; border-radius: var(--r-md);
  font-weight: 600; font-size: 14px; text-decoration: none;
}

/* ===== Vending marker sizing =====
   Mock: keep 44x56 wrapper with flex-center so the SVG visually nests inside
   the larger hit area (mock's translate(-50%,-100%) handles bottom-center).
   Naver: wrapper MUST equal the rendered SVG size (35x45) so the icon.anchor
   we configure (pin tip pixel) actually lines up with the lat/lng. A larger
   wrapper would force the SVG to the wrapper's center, putting the pin tip
   above the anchor and visibly drifting as zoom changes. */
.mock-marker[data-store-type="pokemon_vending_machine"] {
  width: 44px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Map markers — wrapper sizes MUST match the inline SVG render dims so the
   anchor we set in pinAnchorFor (SVG pin-tip pixel) lines up with the actual
   tip and stays fixed across zoom levels.
   IMPORTANT: markers use inline SVG (transparent canvas) — never the asset
   PNGs. The pin-reference PNGs are RGB (no alpha) with a solid white square
   background; using them here would paint a white card over map tiles and
   hide road labels/POIs.
   HIT AREA: every marker's wrapper IS the click target — `pointer-events: auto`
   on the wrapper and `pointer-events: all` on the inner SVG so clicks land on
   transparent areas of the SVG too (default `visiblePainted` ignores them). */
.naver-pack-marker[data-store-type="pokemon_vending_machine"] {
  width: 35px;
  height: 45px;
  display: block;
  background: transparent;
}
.naver-pack-marker[data-store-type="pokemon_vending_machine"] svg {
  display: block;
  width: 100%;
  height: 100%;
  background: transparent;
}
.naver-pack-marker[data-store-type="card_shop"] {
  width: 40px;
  height: 50px;
  display: block;
  background: transparent;
}
.naver-pack-marker[data-store-type="card_shop"] svg {
  display: block;
  width: 100%;
  height: 100%;
  background: transparent;
}
.mock-marker[data-store-type="card_shop"][data-official="true"] {
  width: 44px;
  height: 55px;
  display: block;
}
.naver-pack-marker[data-store-type="card_shop"][data-official="true"] {
  width: 44px;
  height: 55px;
  display: block;
  background: transparent;
  overflow: visible;
}
/* 공인 카드샵 marker — 두 레이어 합성:
   (bg) 빨강 SVG 핀 + 얇은 파란 stroke + blue glow → 자판기 노랑 / 일반 카드샵
        빨강 단독 양쪽과 모두 구분
   (img) 기존 공인샵 PNG 의 inner-circle 영역만 clip-path 로 보여서 매장 아이콘
        그래픽 유지. 외곽 노란 핀 부분은 클립으로 잘려나가 안 보임.
   두 레이어 모두 background / border / box-shadow 0 — 사각형 박스 흔적 X. */
.marker-official-cardshop {
  position: relative;
  display: block;
  width: 44px;
  height: 55px;
  overflow: visible;
  pointer-events: all;
  background: transparent;
  background-color: transparent;
  border: 0;
  box-shadow: none;
}
.marker-official-cardshop-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  background: transparent;
  pointer-events: none;
  /* 빨강 베이스 홀로 fill 강조용 외곽 glow — 알파/블러 모두 약 50% 약화.
     주변 핀(자판기/일반 카드샵)을 가리지 않으면서도 공식샵 식별성 유지. */
  filter:
    drop-shadow(0 0 1.5px rgba(239,  68,  68, 0.32))
    drop-shadow(0 0 2.5px rgba(236,  72, 153, 0.22))
    drop-shadow(0 3px 6px  rgba( 15,  23,  42, 0.18));
}
.marker-official-cardshop-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: transparent;
  background-color: transparent;
  border: 0;
  box-shadow: none;
  pointer-events: all;
  /* SVG 의 inner-circle (cx=22 cy=21 r=11.5 in viewBox 44×56) 와 동일 영역만
     노출. center: (50%, 37.5%), radius ≈ 25%. 외곽의 노란 PNG 픽셀은 모두
     이 클립 바깥이라 화면에 안 보임. */
  clip-path: circle(25% at 50% 37.5%);
}
/* Defensive: nothing inside any naver marker should ever pick up a wrapper bg.
   And ensure the entire wrapper rect catches pointer events (Naver auto-detect
   for click hit area can come up short). */
.naver-pack-marker {
  background: transparent;
  cursor: pointer;
  pointer-events: auto;
}
.naver-pack-marker svg {
  /* "all" means hit-test fires on every pixel of the SVG box regardless of
     fill/visibility — so clicks on the SVG's transparent corners still bubble
     up to the wrapper's click handler. */
  pointer-events: all;
}

/* ===== v12 — active marker = red halo (shape preserved) ===== */
.mock-marker.is-active svg,
.mock-marker.is-active .marker-official-cardshop,
.naver-pack-marker.is-active svg,
.naver-pack-marker.is-active .marker-official-cardshop {
  /* shape stays the same; outer glow + tight outline both in red. */
  filter:
    drop-shadow(0 0 0 #EF4444)
    drop-shadow(0 0 1px #EF4444)
    drop-shadow(0 0 2px #EF4444)
    drop-shadow(0 4px 14px rgba(239, 68, 68, 0.55));
  transition: filter 160ms ease;
}
.mock-marker.is-active,
.naver-pack-marker.is-active { z-index: 9999; }

/* ===== Saved shortcut (rail 하단 항목) =====
   다른 rail 항목과 동일한 톤 — 테두리/배경 박스 없음, 아이콘 색 강조 없음.
   active 일 때만 brand 강조 (.rail-item.active 와 같은 패턴). */
.saved-shortcut {
  background: transparent;
  border: 0;
  border-radius: var(--r-md);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  padding: 10px 4px;
  cursor: pointer;
  width: 100%;
  line-height: 1.2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.saved-shortcut:hover { background: var(--surface-soft); color: var(--text-strong); }
.saved-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  color: inherit;            /* line stroke 가 라벨과 같은 회색 → active 시 brand */
  line-height: 1;
}
.saved-icon svg { display: block; }
.saved-label { font-size: 11px; font-weight: 600; }
/* 저장 개수 badge — rail 노출하지 않음 (스펙: rail 카운트 제거). 데이터는 그대로
   유지되어 ProfileSheet 의 빠른 메뉴에는 노출됨. */
.saved-count { display: none !important; }

/* ===== v11 — Naver-style 자판기 상세 ===== */
.detail-vending-naver { padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
/* Hero image at the top of the floating detail panel — pulled to the panel
   edges (negative margins cancel the parent padding) so it spans full width.
   Asset (vending_main_pic.png) is 1254×1254, so the hero uses a 1:1 aspect
   ratio with `object-fit: contain` to preserve the asset's exact shape — no
   crop, no squish. Capped via max-height to avoid eating the whole panel. */
.dv-hero {
  margin: -14px -16px 4px;
  width: calc(100% + 32px);
  aspect-ratio: 1 / 1;
  max-height: 240px;
  background: #fff;            /* main_pic 자산 흰 배경에 맞춰 wrapper 도 흰색 */
  display: flex;
  align-items: center;
  justify-content: center;
}
.dv-hero img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
}
/* Fallback state if the hero image 404s — class is set by the inline onerror. */
.dv-hero--fallback {
  aspect-ratio: 16 / 6;
  max-height: 120px;
  background:
    radial-gradient(circle at 30% 50%, #FCD34D 0%, transparent 60%),
    linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%);
}
.dv-head .dv-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--text-strong);
  margin: 0 0 6px;
  line-height: 1.3;
}
.dv-head .dv-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
.dv-head .meta-line.muted.small { font-size: 12px; color: var(--text-muted); }
.dv-actions {
  /* 액션 수 (3 or 4) 에 자동 적응 — grid 고정 3-col 대신 flex 로 균등 분할.
     댓글 액션이 추가되면 4 columns 동작. 지도/길찾기 가 없으면 3 columns. */
  display: flex;
  gap: 6px;
  padding: 10px 0 12px;
  border-bottom: 1px solid var(--border);
}
.dv-action {
  flex: 1 1 0;
  min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: transparent; border: 0; padding: 8px 6px;
  font-size: 12.5px; color: var(--text-strong); cursor: pointer;
  border-radius: var(--r-md);
  text-decoration: none;
}
/* 모바일 — 4개 액션 (저장 / 공유 / 댓글 / 지도) 이 좁은 폭에 들어가도록 살짝 축소 */
@media (max-width: 768px) {
  .dv-actions { gap: 4px; padding: 8px 0 10px; }
  .dv-action { padding: 7px 4px; font-size: 11.5px; gap: 3px; }
  .dv-action-icon, .dv-action-icon svg { width: 22px !important; height: 22px !important; }
}
.dv-action:hover { background: var(--surface-soft); }
.dv-action:hover .dv-action-icon { color: #0F172A; }
.dv-action[aria-pressed="true"] { color: var(--brand); }
.dv-action[aria-pressed="true"] .dv-action-icon { color: var(--accent-yellow); }
/* Line-icon container: matches Naver-style stroke icons. */
.dv-action-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; line-height: 1;
  color: #64748B;
}
.dv-action-icon svg { width: 24px; height: 24px; display: block; }
/* Saved state: fill the star with the stroke color so it reads as "active". */
.dv-action[aria-pressed="true"] .dv-action-icon svg { fill: currentColor; }
.dv-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;                /* mobile fallback if 4 tabs overflow */
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.dv-tabs::-webkit-scrollbar { display: none; }
.dv-tab {
  background: transparent; border: 0;
  padding: 8px 12px; cursor: pointer;
  font-size: 13px; font-weight: 600;
  color: var(--text-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  flex-shrink: 0;                  /* don't squish tabs to ellipsis */
  white-space: nowrap;
}
.dv-tab.active { color: var(--brand); border-color: var(--brand); }
.dv-tab-count {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 700;
  background: rgba(37,99,235,0.14);
  color: var(--brand);
  padding: 1px 6px;
  border-radius: 999px;
  margin-left: 2px;
}
.dv-tab-body { padding: 8px 0 4px; display: flex; flex-direction: column; }
.dv-tab-pane { display: none; flex-direction: column; gap: 10px; padding: 4px 0; }
.dv-tab-pane.is-active { display: flex; }

/* Card-shop home tab — surface card */
.cs-home-desc {
  font-size: 13px;
  color: var(--text-strong);
  line-height: 1.55;
  margin: 0 0 4px;
}
.cs-home-news {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--surface-soft);
  border-radius: 10px;
  border: 1px solid var(--border);
  font-size: 12.5px;
}
.cs-home-news-tag {
  font-size: 10.5px; font-weight: 700;
  background: #0F172A; color: #fff;
  padding: 2px 8px; border-radius: 999px;
  flex-shrink: 0;
}
.cs-home-news-title {
  color: var(--text-strong);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.cs-home-inv {
  font-size: 12px;
  color: var(--text-muted);
  padding: 8px 0;
}
.cs-home-inv--empty { color: var(--text-muted); }

/* Card-shop inventory tab — read-only product rows */
.cs-inv-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.cs-inv-row {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 12px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}
.cs-inv-row.is-sold { background: var(--surface-soft); }
.cs-inv-img {
  width: 56px; height: 56px;
  object-fit: contain;
  background: #fff;            /* 카탈로그/제공 PNG 가 흰 배경 → wrapper 도 흰색 */
  border: 1px solid var(--border);
  border-radius: 8px;
  display: block;
}
.cs-inv-img--placeholder {
  display: flex; align-items: center; justify-content: center;
  font-size: 24px;
  color: var(--text-muted);
}
.cs-inv-meta { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.cs-inv-name {
  font-size: 13px; font-weight: 700;
  color: var(--text-strong);
  word-break: break-word;
}
.cs-inv-sub { font-size: 11px; color: var(--text-muted); }
.cs-inv-meta-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 2px;
}
.cs-inv-stock {
  font-size: 12px; font-weight: 700;
  color: var(--brand);
  font-family: var(--f-mono);
}
.cs-inv-row.is-sold .cs-inv-stock { color: #B91C1C; }
.cs-inv-price {
  font-size: 12px; font-weight: 700;
  color: var(--text-strong);
  font-family: var(--f-mono);
}
.cs-inv-price.is-muted {
  font-weight: 500;
  color: var(--text-muted);
}

/* Card-shop news tab */
.cs-news-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.cs-news-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cs-news-head { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.cs-news-tag {
  font-size: 10.5px; font-weight: 700;
  background: #0F172A; color: #fff;
  padding: 2px 8px; border-radius: 999px;
}
.cs-news-date { color: var(--text-muted); font-family: var(--f-mono); }
.cs-news-title { font-size: 14px; font-weight: 700; color: var(--text-strong); }
.cs-news-body { font-size: 12.5px; color: var(--text-strong); line-height: 1.5; }
.cs-news-img {
  width: 100%; max-height: 200px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
}

/* Empty state inside detail tabs */
.cs-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 32px 12px;
  gap: 6px;
  color: var(--text-muted);
}
.cs-empty-icon { font-size: 30px; line-height: 1; }
.cs-empty-title { font-size: 13px; font-weight: 600; color: var(--text-strong); }
.info-row {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 10px;
  align-items: start;
  font-size: 13.5px;
}
.info-row .info-label { color: var(--text-muted); font-size: 12.5px; }
.info-row .info-value { color: var(--text-strong); line-height: 1.5; }
.info-row .info-value a { color: var(--brand); text-decoration: none; }
.info-row .info-value a:hover { text-decoration: underline; }

/* ===== v15 — 2차 detail sidebar (자판기 전용) ===== */
/* Floating detail panel (Naver-style) — sits ON TOP of the map with a gap
   from the list sidebar, rounded corners, vertical viewport margins, and a
   soft drop shadow. Map underneath stays continuous; only the panel area
   covers it. No top padding — header anchors to the panel top. */
.map-detail {
  position: absolute;
  left: calc(var(--rail-w) + var(--list-w) + 12px);
  top: 16px;
  bottom: 16px;
  z-index: 23;
  width: var(--detail-w);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.18);
  padding-top: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  /* fade + tiny lift on enter; visibility flips off after the fade completes
     so a closed panel never paints over a closing list. */
  opacity: 0;
  transform: translateY(6px);
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 200ms ease-out,
    transform 220ms ease-out,
    visibility 0s linear 220ms;
}
.map-detail[data-open="true"] {
  opacity: 1;
  transform: translateY(0);
  visibility: visible;
  pointer-events: auto;
  transition:
    opacity 200ms ease-out,
    transform 220ms ease-out,
    visibility 0s linear 0s;
}
.md-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.md-back, .md-close {
  width: 32px; height: 32px;
  background: transparent; border: 0;
  color: var(--text-strong);
  font-size: 18px; line-height: 1;
  cursor: pointer; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.md-back:hover, .md-close:hover { background: var(--surface-soft); }
.md-eyebrow {
  flex: 1 1 auto;
  text-align: center;
  font-size: 13px; font-weight: 700;
  color: var(--text-muted);
}
.md-body { flex: 1; overflow-y: auto; }

/* ===========================================================================
   MOBILE LAYOUT — single source of truth at 768px breakpoint.

   Strategy: KEEP the same DOM (.map-sidebar / .map-detail) and the same JS
   render functions (paintCategoryList / renderDetailSidebar / openVendingDetail).
   Only swap the CSS positioning so the panels become bottom sheets at mobile.
   This guarantees every desktop fix (rAF recenter, hit-area click, no zoom
   drift, asset image policy, etc.) automatically applies to mobile.

   Hidden on mobile:
     - .map-rail   (left desktop rail — replaced by bottom .mobile-cat-bar)
     - .rail-toggle (desktop edge toggle — sheet handle replaces it)
     - .result-panel, .detail-panel (LEGACY mobile UI — kept in DOM but never
                                     rendered to avoid duplicate-render confusion)

   Visible only on mobile:
     - .mobile-cat-bar (bottom nav)
     - .map-sidebar / .map-detail in bottom-sheet form
   =========================================================================== */

/* Default (desktop / tablet ≥769px): hide the mobile cat bar entirely. */
.mobile-cat-bar { display: none; }

@media (max-width: 768px) {
  /* --- HIDE desktop / legacy mobile UI --- */
  .map-rail        { display: none !important; }
  .rail-toggle     { display: none !important; }
  .result-panel    { display: none !important; }
  .detail-panel    { display: none !important; }

  /* --- map canvas: full width since the rail is gone, leave room for cat bar --- */
  #map-canvas,
  .map-shell[data-layout="rail-list"] #map-canvas,
  .map-shell[data-layout="rail-list-detail"] #map-canvas {
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
  }

  /* --- search shell + chips: stretch to full width --- */
  .search-shell-anchor,
  .map-shell[data-layout="rail-list"] .search-shell-anchor,
  .map-shell[data-layout="rail-list-detail"] .search-shell-anchor {
    left: 12px;
    right: 12px;
    width: auto;
    top: calc(12px + env(safe-area-inset-top, 0px));
  }
  .chip-row-anchor,
  .map-shell[data-layout="rail-list"] .chip-row-anchor,
  .map-shell[data-layout="rail-list-detail"] .chip-row-anchor {
    left: 12px;
    right: 12px;
    top: calc(64px + env(safe-area-inset-top, 0px));
  }

  /* --- locate FAB + map-status: dynamic bottom that follows the visible
     map area. JS (updateMobileOverlayBottom) sets --mobile-overlay-bottom
     based on whichever is closer to the viewer:
       - top edge of an open sheet (list/detail), or
       - top edge of the bottom cat bar.
     CSS transition smooths the change so the controls glide along with the
     sheet's slide animation. Fallback uses the cat bar height + safe-area. */
  .map-shell .map-fab {
    right: 16px;
    bottom: var(--mobile-overlay-bottom, calc(72px + env(safe-area-inset-bottom, 0px))) !important;
    transition: bottom 220ms cubic-bezier(.2,.7,.2,1);
  }
  .map-status {
    bottom: var(--mobile-overlay-bottom, calc(72px + env(safe-area-inset-bottom, 0px))) !important;
    left: 12px;
    transition: bottom 220ms cubic-bezier(.2,.7,.2,1), opacity 200ms ease-out;
  }
  /* Hide the attribution when a sheet is at FULL state — it would otherwise
     float over the (now mostly-covered) map and look like sheet content.
     Sibling combinator works because .map-status is later in DOM than the sheets. */
  .map-detail[data-open="true"][data-sheet-state="full"] ~ .map-status,
  .map-sidebar[data-sheet-state="full"][data-mode="category"] ~ .map-status,
  .map-sidebar[data-sheet-state="full"][data-mode="search"] ~ .map-status,
  .map-sidebar[data-sheet-state="full"][data-mode="detail"] ~ .map-status {
    display: none;
  }

  /* Mobile: hide both custom controls. Pinch-zoom replaces the +/- column,
     and the scale bar would compete with the bottom sheet for vertical room.
     Naver's built-in controls are already disabled at the SDK level (see
     map-adapter.js init), so nothing else needs to be force-hidden here. */
  .map-zoom,
  .map-scale {
    display: none !important;
  }

  /* --- BOTTOM SHEETS (list + detail) — 3 snap states --------------------
     State                CSS variable               Approx. height
     collapsed            120px                      title peek only
     half (default)       50vh                       map visible above
     full                 100vh − safe-area − 24     near full screen

     Drag is wired in JS (setupSheetDrag) — it sets `--sheet-h` inline during
     drag; on release it removes the inline var and snaps to the closest state
     by writing data-sheet-state. CSS .is-dragging disables the height
     transition so finger movement feels 1:1. */
  .map-sidebar,
  .map-detail {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    top: auto;
    width: 100%;
    border-right: 0;
    border-top: 1px solid var(--border);
    border-radius: 16px 16px 0 0;
    padding-top: 28px;     /* room for the grab handle */
    padding-bottom: calc(env(safe-area-inset-bottom, 0px));
    --sheet-h: 50dvh;
    height: var(--sheet-h);
    /* 부드러운 ease-out curve — 끊김 적게. iOS Safari 가 height 애니메이션을
       CPU 로 처리해서 끊김이 보일 수 있어, will-change: height 를 항상 유지하고
       drag 중엔 transition 0s 로 1:1 추적. */
    transition: transform 340ms cubic-bezier(.16,1,.3,1),
                height    300ms cubic-bezier(.16,1,.3,1);
    overscroll-behavior: contain;
    /* will-change 를 항상 유지 — drag 직후 height transition 도 compositor 에서.
       단점: 메모리 약간. iOS Safari 에서 끊김 줄이는 효과가 더 큼. */
    will-change: height;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
  }
  .map-sidebar.is-dragging,
  .map-detail.is-dragging {
    transition: transform 0s, height 0s;     /* 1:1 finger tracking */
  }
  .map-sidebar[data-sheet-state="collapsed"],
  .map-detail[data-sheet-state="collapsed"] { --sheet-h: 120px; }
  .map-sidebar[data-sheet-state="half"],
  .map-detail[data-sheet-state="half"]      { --sheet-h: 50dvh; }
  /* full 상태 — iPhone 노치/Dynamic Island/Android status bar 위로 침범 금지.
     env() 직접 사용 (var() 가 일부 iOS Safari 환경에서 env() 미해석 케이스 회피).
     안전 여백 24px — 노치 아래로 충분히 띄워서 그립바/헤더 가시성 보장.
     dvh fallback 으로 vh 도 같이 정의. */
  .map-sidebar[data-sheet-state="full"],
  .map-detail[data-sheet-state="full"] {
    --sheet-h: calc(100vh  - env(safe-area-inset-top, 0px) - 24px);          /* fallback */
    --sheet-h: calc(100dvh - env(safe-area-inset-top, 0px) - 24px);
  }

  /* List sheet — driven by data-mode (closed vs open) */
  .map-sidebar {
    box-shadow: 0 -8px 24px rgba(15,23,42,0.15);
    transform: translateY(100%);
    z-index: 30;
  }
  .map-sidebar[data-mode="category"],
  .map-sidebar[data-mode="search"],
  .map-sidebar[data-mode="detail"] {
    transform: translateY(0);
  }

  /* 모바일 detail 이 열려있을 때 underlying mapSidebar 를 완전히 차단.
     translateY(100%) 만으론 iOS Safari 의 visual viewport 변동 (키보드 등장)
     이나 inline transform clear 타이밍 race 에서 가끔 노출되는 케이스가 있어
     display:none 으로 hard guard. JS 의 has-mobile-detail body class 토글이
     applyDetailUI 에서 같이 동기화됨. */
  body.has-mobile-detail .map-sidebar {
    display: none !important;
  }

  /* Detail sheet — driven by data-open and sits ABOVE the list */
  .map-detail {
    margin: 0;
    border: 0;
    border-top: 1px solid var(--border);
    box-shadow: 0 -10px 28px rgba(15,23,42,0.22);
    opacity: 1;
    transform: translateY(100%);
    visibility: hidden;
    transition: transform 340ms cubic-bezier(.16,1,.3,1),
                height 300ms cubic-bezier(.16,1,.3,1),
                visibility 0s linear 340ms;
    z-index: 31;
  }
  .map-detail[data-open="true"] {
    transform: translateY(0);
    visibility: visible;
    transition: transform 340ms cubic-bezier(.16,1,.3,1),
                height 300ms cubic-bezier(.16,1,.3,1),
                visibility 0s linear 0s;
  }

  /* Grab handle — full-width invisible hit zone with a centered visual bar.
     `touch-action: none` on the hit zone prevents native scrolling so JS owns
     the drag gesture. Made tall (40px) and the bar slightly thicker so users
     can easily find/grab it — especially when retracting from "full" state. */
  .sheet-grab {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 40px;
    z-index: 5;
    cursor: grab;
    touch-action: none;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .map-sidebar.is-dragging .sheet-grab,
  .map-detail.is-dragging .sheet-grab { cursor: grabbing; }
  .sheet-grab-bar {
    width: 44px; height: 5px;
    background: #cbd5e1;
    border-radius: 3px;
    pointer-events: none;
    transition: background 120ms ease, width 120ms ease;
  }
  .map-sidebar.is-dragging .sheet-grab-bar,
  .map-detail.is-dragging .sheet-grab-bar {
    background: var(--brand);
    width: 56px;
  }
  /* Sheet header: in addition to the small grab, the header itself is wired
     as a drag zone in JS — give it a subtle "grabbable" cursor so desktop
     pointers also see the affordance. (Buttons inside have their own cursor.) */
  .map-sidebar > .sidebar-head,
  .map-detail > .md-head {
    cursor: grab;
    touch-action: none;
    user-select: none;
  }
  .map-sidebar.is-dragging > .sidebar-head,
  .map-detail.is-dragging > .md-head { cursor: grabbing; }
  .map-sidebar > .sidebar-head button,
  .map-detail > .md-head button {
    cursor: pointer;
    touch-action: auto;
  }
  /* Padding adjustment: grab grew to 40px so head needs a bit more breathing room. */
  .map-sidebar, .map-detail { padding-top: 40px; }

  /* Body content: only the FULL state allows internal scroll; in collapsed/half
     the sheet is small enough that scrolling competes with the drag gesture.
     overscroll-behavior: contain prevents page-level overscroll on iOS. */
  .map-sidebar .sidebar-body,
  .map-detail .md-body {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  .map-sidebar:not([data-sheet-state="full"]) .sidebar-body,
  .map-detail:not([data-sheet-state="full"]) .md-body {
    overflow-y: auto;
  }
  .map-sidebar[data-sheet-state="full"] .sidebar-body,
  .map-detail[data-sheet-state="full"] .md-body {
    overflow-y: auto;
  }
  .map-sidebar[data-sheet-state="collapsed"] .sidebar-body,
  .map-detail[data-sheet-state="collapsed"] .md-body {
    /* keep DOM but hide inner scroll while peek */
    overflow: hidden;
  }

  /* shrink the detail hero on half/collapsed so map stays visible above it */
  .map-detail[data-sheet-state="half"] .dv-hero,
  .map-detail[data-sheet-state="collapsed"] .dv-hero {
    max-height: 140px;
  }
  .map-detail[data-sheet-state="full"] .dv-hero {
    max-height: 240px;
  }

  /* --- MOBILE CATEGORY BAR --- */
  .mobile-cat-bar {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 40;
    background: var(--surface);
    border-top: 1px solid var(--border);
    /* padding-bottom = env(safe-area-inset-bottom) 만 (홈 인디케이터 영역).
       이전엔 +6px 버퍼 추가했는데 사용자가 "흰 여백 너무 큼" 신고 → 제거.
       padding-top 도 6px 로 시각 여유 유지. */
    padding: 6px 4px env(safe-area-inset-bottom, 0px);
    box-shadow: 0 -4px 16px rgba(15,23,42,0.06);
  }
  .mcb-item {
    flex: 1;
    display: flex; flex-direction: column;
    align-items: center; gap: 2px;
    background: transparent; border: 0;
    padding: 6px 4px;
    cursor: pointer;
    color: var(--text-muted);
    border-radius: 8px;
    transition: color 120ms ease, background 120ms ease;
  }
  .mcb-item:hover, .mcb-item.active {
    color: var(--brand);
    background: var(--brand-soft);
  }
  .mcb-item[data-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
    filter: grayscale(0.95);
  }
  .mcb-item[data-disabled="true"]:hover,
  .mcb-item[data-disabled="true"].active {
    background: transparent;
    color: var(--text-muted);
  }
  .mcb-icon {
    width: 26px; height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .mcb-icon img {
    width: 100%; height: 100%;
    max-width: 100%; max-height: 100%;
    object-fit: contain;
    object-position: center;
    display: block;
  }
  .mcb-label {
    font-size: 11px;
    font-weight: 600;
    line-height: 1.15;
    text-align: center;
  }
  .mcb-label small {
    display: inline-block;
    font-size: 8px;
    background: #1F2937;
    color: #FDE68A;
    padding: 1px 4px;
    border-radius: 3px;
    margin-left: 4px;
    letter-spacing: 0.04em;
    font-family: var(--f-mono);
    font-weight: 700;
  }
}

/* ===========================================================================
   LOGIN — rail bottom button + modal (desktop) / bottom sheet (mobile)
   ---------------------------------------------------------------------------
   Rail button uses .rail-item shell so visual style matches the categories.
   The mobile cat bar gets a 4th .mcb-item (.mcb-login). Modal sits at z-index
   above all map overlays / sheets so login is reachable from any state.
   =========================================================================== */

/* Rail bottom anchor — pushes the login item to the bottom of the rail flex
   column. Above-the-rail savedShortcut still sits with its own margin-top:10px
   directly under the categories. */
/* feedback + siteInfo + login form a bottom-anchored stack. The FIRST
   .rail-info (feedback) takes the auto-margin + dashed separator; subsequent
   .rail-info siblings (siteInfo) flow tightly under it without re-creating
   the gap/border. login then flows directly under siteInfo. */
.rail-info {
  margin-top: auto;
  border-top: 1px dashed var(--border);
  padding-top: 10px;
  color: var(--text-muted);
}
.rail-info + .rail-info {
  margin-top: 0;
  border-top: none;
  padding-top: 4px;
}
.rail-info:hover { color: var(--text-strong); }
.rail-login {
  padding-top: 4px;
}
.rail-login.is-loggedin { color: var(--brand); }
.rail-avatar {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 26px; height: 26px;
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  font-size: 12px;
  border-radius: 50%;
  font-family: var(--f-mono);
}

/* === Modal === */
.login-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;       /* above floating detail (31), cat bar (40), all sheets */
  display: none;
  align-items: center;
  justify-content: center;
}
.login-modal.is-open { display: flex; }
.login-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(15, 23, 42, 0.42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.login-modal-card {
  position: relative;
  z-index: 1;
  background: var(--surface);
  border-radius: 14px;
  width: min(380px, calc(100% - 32px));
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  padding: 24px 24px 20px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);
  animation: login-modal-in 200ms cubic-bezier(.2,.7,.2,1);
}
@keyframes login-modal-in {
  from { transform: translateY(8px) scale(0.98); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.login-modal-close {
  position: absolute;
  top: 10px; right: 10px;
  width: 32px; height: 32px;
  background: transparent; border: 0;
  font-size: 16px; color: var(--text-muted);
  cursor: pointer;
  border-radius: 8px;
}
.login-modal-close:hover { background: var(--surface-soft); color: var(--text-strong); }
.login-title {
  font-size: 20px;
  font-weight: 700;
  color: var(--text-strong);
  margin: 0 0 6px;
}
.login-sub {
  font-size: 12.5px;
  color: var(--text-muted);
  margin: 0 0 18px;
  line-height: 1.5;
}
.login-form { display: flex; flex-direction: column; gap: 12px; margin-bottom: 14px; }
.login-field { display: flex; flex-direction: column; gap: 4px; }
.login-field-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.login-field input {
  font: inherit;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text-strong);
  outline: none;
  transition: border-color 120ms ease, background 120ms ease;
}
.login-field input:focus {
  border-color: var(--brand);
  background: var(--surface);
}
.login-submit {
  font: inherit;
  font-weight: 700;
  padding: 11px 14px;
  border-radius: 10px;
  border: 0;
  background: var(--brand);
  color: #fff;
  cursor: pointer;
  margin-top: 4px;
  transition: filter 120ms ease;
}
.login-submit:hover { filter: brightness(0.95); }
.login-submit--ghost {
  background: transparent;
  color: var(--text-strong);
  border: 1px solid var(--border);
}
.login-submit--ghost:hover { background: var(--surface-soft); }
.login-secondary {
  display: flex; justify-content: space-between; gap: 8px;
  margin-top: 4px;
}
.login-link {
  background: transparent; border: 0;
  color: var(--text-muted);
  font-size: 12px;
  cursor: pointer;
  padding: 4px 2px;
}
.login-link:hover { color: var(--brand); text-decoration: underline; }
.login-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 14px 0 12px;
  color: var(--text-subtle);
  font-size: 11px;
}
.login-divider::before,
.login-divider::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}
/* Wrapper — vertical stack of provider buttons. */
.login-social { display: flex; flex-direction: column; gap: 10px; font: inherit; }

/* Each button: full width, fixed height, icon at left edge, label centered.
   Using position: relative on the button + position: absolute on the icon
   keeps the text optically centered regardless of icon width — the button
   doesn't shift when icons change. Class `login-social` is preserved so the
   click selector (button.login-social) and provider mapping still work. */
button.login-social {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 46px;
  padding: 0 18px 0 48px;
  border-radius: 10px;
  border: 1px solid transparent;
  background: var(--surface);
  color: var(--text-strong);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: filter 120ms ease, box-shadow 120ms ease;
}
button.login-social:hover  { filter: brightness(0.96); }
button.login-social:active { filter: brightness(0.92); }
button.login-social:disabled { opacity: 0.5; cursor: not-allowed; filter: none; }

.login-social-icon {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
}
.login-social-icon svg { display: block; }
.login-social-text {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* Per-provider colors. Borders match background to keep buttons solid. */
button.login-social--kakao {
  background: #FEE500;
  color: #181600;
  border-color: #FEE500;
}
button.login-social--naver {
  background: #03C75A;
  color: #FFFFFF;
  border-color: #03C75A;
}
button.login-social--google {
  background: #FFFFFF;
  color: #1F2937;
  border-color: #E5E7EB;
}

/* Mobile: keep height + font readable on bottom-sheet width (≤768px). */
@media (max-width: 768px) {
  button.login-social {
    height: 48px;
    font-size: 14.5px;
    padding: 0 16px 0 46px;
  }
  .login-social-icon { left: 14px; }
}

/* ===== Tabs (일반 / 사업자) — segmented control ===== */
.login-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 4px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin: 4px 0 16px;
}
.login-tab {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  background: transparent;
  border: 0;
  color: var(--text-muted);
  padding: 8px 10px;
  border-radius: 7px;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.login-tab:hover { color: var(--text-strong); }
.login-tab.is-active {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
}
.login-pane { display: block; }

/* Helper text & 사업자-only sub copy */
.login-sub--biz { color: var(--text-strong); font-weight: 500; }
.login-helper-text {
  font-size: 11.5px;
  color: var(--text-muted);
  margin: 6px 0 0;
}
.login-helper-text--err {
  color: #DC2626;
  font-weight: 600;
}
.login-mode-toggle {
  justify-content: center;
  align-items: center;
  margin-top: 14px;
}
.login-link-prefix {
  font-size: 12px;
  color: var(--text-muted);
}

/* 사이트 정보 / 약관 진입 — 비회원도 로그인 모달에서 볼 수 있게. */
.login-site-info-row {
  justify-content: center;
  margin-top: 8px;
}
.login-link.login-link--muted {
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 500;
}
.login-link.login-link--muted:hover {
  color: var(--text-strong);
  text-decoration: underline;
}

/* 사업자 form: 2열 row + 사업자번호 row */
.login-form--biz { gap: 14px; }
.login-field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.login-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
}
.login-row input { min-width: 0; }
.login-verify-btn {
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 0 14px;
  border-radius: 8px;
  border: 1px solid var(--brand);
  background: var(--surface);
  color: var(--brand);
  cursor: pointer;
  white-space: nowrap;
  transition: background 120ms ease, color 120ms ease;
}
.login-verify-btn:hover:not(:disabled)  { background: var(--brand); color: #fff; }
.login-verify-btn:disabled { opacity: 0.55; cursor: progress; }

/* Verify status pill (idle / pending / verified / failed) */
.verify-status {
  margin-top: 6px;
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 11.5px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  line-height: 1.3;
}
.verify-status--idle    { background: rgba(100,116,139,0.10); color: #475569; }
.verify-status--pending { background: rgba(234,179,8,0.14);   color: #854D0E; }
.verify-status--ok      { background: rgba(34,197,94,0.14);   color: #166534; }
.verify-status--err     { background: rgba(239,68,68,0.12);   color: #991B1B; }
.verify-spinner {
  width: 12px; height: 12px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  animation: verify-spin 700ms linear infinite;
  display: inline-block;
}
@keyframes verify-spin { to { transform: rotate(360deg); } }

/* Radio group (매장 종류) */
.login-radio-group {
  border: 0;
  padding: 0;
  margin: 0;
}
.login-radio-group .login-field-label { padding: 0; margin-bottom: 6px; display: block; }
.login-radio {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-strong);
  cursor: pointer;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-right: 8px;
  background: var(--surface);
  transition: background 120ms ease, border-color 120ms ease;
}
.login-radio:hover { background: var(--surface-soft); }
.login-radio input[type="radio"] {
  accent-color: var(--brand);
  margin: 0;
}
.login-radio:has(input[type="radio"]:checked) {
  background: rgba(37,99,235,0.08);
  border-color: var(--brand);
}

/* Email-verify code row appears below the email row when a code has been
   sent. Spacing matches the biz-num row above. */
.login-row--code { margin-top: 8px; }

/* 약관 동의 체크박스 — 회원가입 form 하단 */
.login-terms {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-strong);
  line-height: 1.5;
  padding: 4px 2px;
  cursor: pointer;
}
.login-terms input[type="checkbox"] {
  accent-color: var(--brand);
  margin-top: 2px;
  flex-shrink: 0;
}
.login-terms-link {
  color: var(--brand);
  text-decoration: underline;
  cursor: pointer;
}
.login-terms-link:hover { filter: brightness(0.9); }
.login-terms-required {
  color: #B91C1C;
  font-weight: 600;
  font-size: 11.5px;
  white-space: nowrap;
}

/* Dev-only test login button — visually distinct from real submit (dashed
   outline + monospace meta) so testers immediately recognize it as a shortcut. */
.login-test-btn {
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 9px 12px;
  border-radius: 8px;
  border: 1.5px dashed #94A3B8;
  background: var(--surface-soft);
  color: var(--text-strong);
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.login-test-btn:hover { background: #FEF3C7; border-color: #F59E0B; }
.login-test-meta {
  font-family: var(--f-mono);
  font-size: 10.5px;
  font-weight: 500;
  color: var(--text-muted);
}

/* 사업자 submit variant — slightly different tone so the role is obvious */
.login-submit--biz { background: #0F172A; }
.login-submit--biz:hover:not(:disabled) { background: #1E293B; filter: none; }
.login-submit:disabled { opacity: 0.5; cursor: not-allowed; }

/* Logged-in business meta block */
.login-user-role {
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 600;
  margin-top: 1px;
  letter-spacing: 0.02em;
}
.login-biz-meta {
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px;
  margin: 0 0 14px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-soft);
  font-size: 12px;
}
.login-biz-meta > div {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 8px;
}
.login-biz-meta dt {
  margin: 0;
  color: var(--text-muted);
  font-weight: 600;
}
.login-biz-meta dd {
  margin: 0;
  color: var(--text-strong);
  word-break: break-word;
}

/* Business avatar tinted differently from user avatar */
.rail-avatar--biz { background: #0F172A; }

/* Application status pill in the logged-in business view */
.biz-app-status {
  margin: 4px 0 12px;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
}
.biz-app-status--pending { background: rgba(234,179,8,0.14); color: #854D0E; }
.biz-app-status--ok      { background: rgba(34,197,94,0.14); color: #166534; }
.biz-app-status--err     { background: rgba(239,68,68,0.12); color: #991B1B; }

/* ===== Admin panel (mock — ?admin=1 or pokemapAdmin.open()) ===== */
.admin-panel {
  position: fixed;
  bottom: 16px;
  left: 16px;
  width: min(380px, calc(100% - 32px));
  max-height: calc(100vh - 32px);
  z-index: 50;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-size: 13px;
}
.admin-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  background: #0F172A;
  color: #fff;
}
.admin-panel-head h3 { margin: 0; font-size: 13px; font-weight: 700; letter-spacing: 0.02em; }
.admin-close {
  background: transparent; border: 0;
  color: rgba(255,255,255,0.7); cursor: pointer;
  font-size: 14px; padding: 4px 8px; border-radius: 6px;
}
.admin-close:hover { background: rgba(255,255,255,0.1); color: #fff; }

.admin-panel-body { overflow-y: auto; padding: 8px 12px 12px; }

.admin-section { margin-top: 10px; }
.admin-section-title {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 6px;
  font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted);
}
.admin-count {
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--text-muted);
}
.admin-status-badge {
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.02em;
}
.admin-status-badge--pending { background: rgba(234,179,8,0.18);  color: #854D0E; }
.admin-status-badge--ok      { background: rgba(34,197,94,0.18);  color: #166534; }
.admin-status-badge--err     { background: rgba(239,68,68,0.16);  color: #991B1B; }

/* Admin sheet status badges (Supabase-driven) — match the legacy palette
   above but keyed by the application_status enum value names. */
.badge.admin-status-badge--pending_review { background: rgba(234,179,8,0.18);  color: #854D0E; }
.badge.admin-status-badge--approved       { background: rgba(34,197,94,0.18);  color: #166534; }
.badge.admin-status-badge--rejected       { background: rgba(239,68,68,0.16);  color: #991B1B; }

.admin-app {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 6px;
  background: var(--surface-soft);
}
.admin-app-meta { min-width: 0; }
.admin-app-name {
  font-size: 13px; font-weight: 700; color: var(--text-strong);
  word-break: break-word;
}
.admin-app-type {
  font-size: 10.5px; font-weight: 600;
  color: var(--text-muted);
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 1px 6px; border-radius: 4px;
  margin-left: 4px;
}
.admin-app-sub {
  font-size: 11.5px; color: var(--text-muted);
  margin-top: 2px;
  word-break: break-word;
}
.admin-app-reason {
  font-size: 11px; color: #991B1B;
  margin-top: 4px;
}
.admin-app-actions {
  display: flex; flex-direction: column; gap: 4px;
}
.admin-btn {
  font: inherit;
  font-size: 11.5px; font-weight: 700;
  padding: 6px 12px;
  border-radius: 6px;
  border: 0; cursor: pointer;
  white-space: nowrap;
  transition: filter 120ms ease;
}
.admin-btn:hover { filter: brightness(0.95); }
.admin-btn--approve { background: #16A34A; color: #fff; }
.admin-btn--reject  { background: #DC2626; color: #fff; }
.admin-btn--ghost   { background: var(--surface); color: var(--text-strong); border: 1px solid var(--border); }
.admin-empty {
  font-size: 12px;
  color: var(--text-muted);
  padding: 6px 0 4px;
}

@media (max-width: 768px) {
  /* Mobile: anchor to top so it doesn't fight the bottom sheet stack. */
  .admin-panel {
    top: calc(env(safe-area-inset-top, 0px) + 8px);
    left: 8px; right: 8px; bottom: auto;
    width: auto;
    max-height: 60vh;
  }
}

/* Logged-in user card */
.login-user {
  display: flex; align-items: center; gap: 12px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-soft);
  margin-bottom: 14px;
}
.login-avatar {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700;
  font-family: var(--f-mono);
}
.login-user-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.login-user-name { font-size: 14px; font-weight: 700; color: var(--text-strong); }
.login-user-email { font-size: 12px; color: var(--text-muted); }

/* Mobile: present as a bottom sheet instead of a centered modal. */
@media (max-width: 768px) {
  .login-modal { align-items: flex-end; }
  .login-modal-card {
    width: 100%;
    max-width: 100%;
    max-height: 84vh;
    border-radius: 16px 16px 0 0;
    padding-top: 28px;
    padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px));
    animation: login-sheet-in 240ms cubic-bezier(.2,.7,.2,1);
  }
  /* tiny grab indicator at the top of the mobile sheet */
  .login-modal-card::before {
    content: '';
    position: absolute;
    top: 8px; left: 50%;
    transform: translateX(-50%);
    width: 44px; height: 5px;
    border-radius: 3px;
    background: #cbd5e1;
  }
  .login-modal-close { top: 18px; right: 14px; }
}
@keyframes login-sheet-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* =====================================================================
   Profile sheet (내정보) — naver-style account/settings panel.
   Desktop: centered modal-like card (~440px wide).
   Mobile : full-height bottom-anchored sheet.
===================================================================== */
.profile-sheet {
  position: fixed;
  inset: 0;
  z-index: 1100;             /* above login-modal (1000) */
  display: none;
  align-items: center;
  justify-content: center;
}
.profile-sheet.is-open { display: flex; }
.ps-backdrop {
  position: absolute; inset: 0;
  background: rgba(15, 23, 42, 0.42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.ps-card {
  position: relative;
  z-index: 1;
  background: var(--surface);
  border-radius: 16px;
  width: min(440px, calc(100% - 32px));
  max-height: calc(100vh - 64px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);
  animation: ps-card-in 220ms cubic-bezier(.2,.7,.2,1);
}
@keyframes ps-card-in {
  from { transform: translateY(8px) scale(0.98); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.ps-body { overflow-y: auto; padding: 0 0 16px; }

/* Top bar */
.ps-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px 6px;
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 2;
}
.ps-topbar-left, .ps-topbar-right { display: flex; align-items: center; gap: 4px; }
.ps-title {
  font-size: 16px;
  font-weight: 700;
  margin: 0;
  color: var(--text-strong);
}
.ps-icon-btn {
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: var(--text-strong);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  transition: background 120ms ease;
}
.ps-icon-btn:hover { background: var(--surface-soft); }

/* Sub-view top bar (with back arrow). Same layout, different left content. */
.ps-topbar--sub .ps-topbar-left .ps-icon-btn {
  font-size: 22px;
  font-weight: 700;
  margin-right: 4px;
}

/* Profile area */
.ps-profile {
  padding: 4px 24px 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  border-bottom: 1px solid var(--border);
}
.ps-avatar-wrap {
  position: relative;
  margin-bottom: 12px;
}
.ps-avatar {
  width: 88px; height: 88px;
  border-radius: 50%;
  background: linear-gradient(135deg, #DBEAFE, #BFDBFE);
  display: flex; align-items: center; justify-content: center;
  border: 3px solid var(--surface);
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.10);
}
.ps-avatar-emoji   { font-size: 44px; line-height: 1; }
.ps-avatar-initial {
  font-family: var(--f-mono);
  font-size: 38px; font-weight: 700;
  color: var(--brand);
}
.ps-avatar-edit {
  position: absolute;
  right: -2px; bottom: -2px;
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 2px solid var(--surface);
  background: var(--brand);
  color: #fff;
  cursor: pointer;
  font-size: 13px;
  display: flex; align-items: center; justify-content: center;
}
.ps-avatar-edit:hover { filter: brightness(0.95); }
.ps-name {
  font-size: 17px;
  font-weight: 700;
  color: var(--text-strong);
  margin-bottom: 2px;
}
.ps-sub {
  font-size: 12.5px;
  color: var(--text-muted);
  margin-bottom: 8px;
  word-break: break-all;
}
.ps-bio {
  font-size: 13px;
  color: var(--text-strong);
  line-height: 1.5;
  max-width: 320px;
}
.ps-bio-empty { color: var(--text-muted); font-style: normal; font-size: 12.5px; }

/* Quick menu (2x2 grid) */
.ps-quick {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding: 16px;
  border-bottom: 1px solid var(--border);
}
.ps-quick-item {
  position: relative;
  background: var(--surface-soft);
  border: 0;
  border-radius: 12px;
  padding: 12px 6px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font: inherit;
  color: var(--text-strong);
  transition: background 120ms ease, transform 120ms ease;
}
.ps-quick-item:hover { background: rgba(37,99,235,0.08); }
.ps-quick-item:active { transform: scale(0.97); }
.ps-quick-icon  {
  font-size: 22px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #2563EB;                    /* primary brand for quick menu icons */
}
.ps-quick-icon svg { display: block; }
.ps-quick-label { font-size: 11.5px; font-weight: 600; }
.ps-quick-badge {
  position: absolute;
  top: 6px; right: 6px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  font-family: var(--f-mono);
  line-height: 16px;
  text-align: center;
}

/* =====================================================================
   Admin — 장소 추가/수정 폼.
   섹션 단위 (.apf-section) + 라벨 위 input + 짧은 helper. 데스크탑 2열 grid,
   모바일 1열. 모달/시트 내부에 들어갈 예정이므로 .ps-card 폭 안에서 깨지지
   않게 100% 기준 박싱.
===================================================================== */

.apf-header {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 14px;
}
.apf-header h3 {
  margin: 0; font-size: 16px; font-weight: 700; flex: 1;
  color: var(--text-strong);
}
.apf-error {
  background: #FEE2E2;
  border: 1px solid #FCA5A5;
  color: #991B1B;
  padding: 10px 12px;
  border-radius: 10px;
  font-size: 13px;
  margin-bottom: 14px;
  line-height: 1.4;
}

.admin-place-form {
  display: flex; flex-direction: column;
  gap: 14px;
}

.apf-section {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 14px 16px;
  margin: 0;
  min-width: 0;
}
.apf-section-title {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0 6px;
  margin-bottom: 8px;
}

.apf-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 12px;
}
@media (max-width: 640px) {
  .apf-grid { grid-template-columns: 1fr; gap: 14px; }
}

.apf-field {
  display: flex; flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.apf-field--full { grid-column: 1 / -1; }

.apf-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-strong);
}
.apf-required { color: #DC2626; margin-left: 2px; }
.apf-helper {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.45;
}

.admin-place-form input[type="text"],
.admin-place-form input[type="tel"],
.admin-place-form input[type="url"],
.admin-place-form input[type="number"],
.admin-place-form input[type="search"],
.admin-place-form select,
.admin-place-form textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13.5px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text-strong);
  box-sizing: border-box;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.admin-place-form input:focus,
.admin-place-form select:focus,
.admin-place-form textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12);
}
.admin-place-form textarea { resize: vertical; min-height: 60px; }

.apf-inline-row {
  display: flex;
  gap: 6px;
  align-items: center;
}
.apf-inline-row input { flex: 1; min-width: 0; }
@media (max-width: 480px) {
  .apf-inline-row { flex-wrap: wrap; }
  .apf-inline-row > .ps-btn { flex: 1; }
}

.apf-quick-row {
  display: flex; flex-wrap: wrap;
  gap: 5px;
  margin-top: 2px;
}
.apf-quick-row .apf-quick-btn {
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 999px;
}

.apf-checkbox-row {
  display: flex; align-items: center; gap: 8px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text-strong);
  font-weight: 500;
  padding: 4px 0;
}
.apf-checkbox-row input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: var(--brand);
  margin: 0;
}

.apf-meta {
  padding-top: 6px;
  border-top: 1px dashed var(--border);
  margin-top: 4px;
}

.apf-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding-top: 6px;
  margin-top: 4px;
}
@media (max-width: 480px) {
  .apf-footer { flex-direction: column-reverse; }
  .apf-footer > .ps-btn { width: 100%; }
}

/* Settings list */
.ps-list {
  display: flex;
  flex-direction: column;
  padding: 8px 8px;
}
.ps-list-item {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: transparent;
  border: 0;
  cursor: pointer;
  font: inherit;
  font-size: 13.5px;
  color: var(--text-strong);
  text-align: left;
  border-radius: 10px;
  transition: background 120ms ease;
}
.ps-list-item:hover { background: var(--surface-soft); }
.ps-list-icon  {
  font-size: 16px;
  text-align: center;
  line-height: 1;
  color: #64748B;                    /* default neutral grey for line icons */
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ps-list-icon svg { display: block; }
.ps-list-label { min-width: 0; }
.ps-list-arrow { color: var(--text-muted); font-size: 16px; line-height: 1; }
.ps-list-tag {
  font-size: 11px;
  color: var(--text-muted);
  background: var(--surface-soft);
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.ps-list-item--brand .ps-list-icon  { color: var(--brand); }
.ps-list-item--brand .ps-list-label { color: var(--brand); font-weight: 700; }
.ps-list-item--danger { color: #B91C1C; }
.ps-list-item--danger .ps-list-icon { color: #B91C1C; }
.ps-list-item--danger-strong { color: #fff; background: #DC2626; margin-top: 6px; }
.ps-list-item--danger-strong:hover { background: #B91C1C; }
.ps-list-item--danger-strong .ps-list-icon { color: #FCA5A5; }

/* 회원탈퇴 약화 스타일 — 빨간 텍스트만, 배경/아이콘 없음, 좌측 정렬.
   실수 클릭 줄이고 시각 비중 낮춤. 기능(confirm → deleteCurrentAccount) 은 유지.
   .ps-list-item base 가 3-column grid 라 label 만 있는 이 버튼에선 24px 첫
   컬럼에 글자가 들어가 "회원/탈퇴" 로 줄바꿈됨 → display: flex 로 override. */
.ps-list-item--danger-soft {
  display: flex;
  align-items: center;
  color: #DC2626;
  background: transparent;
  border: 0;
  justify-content: flex-start;
  font-size: 12.5px;
  font-weight: 500;
  margin-top: 4px;
  min-height: 36px;
  padding-top: 6px;
  padding-bottom: 6px;
}
.ps-list-item--danger-soft .ps-list-label { white-space: nowrap; }
.ps-list-item--danger-soft:hover,
.ps-list-item--danger-soft:focus-visible {
  background: rgba(220, 38, 38, 0.06);
  color: #B91C1C;
}
.ps-list-item--danger-soft .ps-list-label {
  color: inherit;
  font-weight: inherit;
}

/* 개발자 도와주기 메뉴 entry — 분홍/하트 hint 살짝. */
.ps-list-item--donate .ps-list-icon { color: #EC4899; }
.ps-list-item--donate:hover .ps-list-icon { color: #DB2777; }

/* ---- Sub-view forms (edit / password / notif / social / location / reviews) ---- */
.ps-form {
  padding: 16px 20px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.ps-form-section { display: flex; flex-direction: column; gap: 8px; }
.ps-section-label {
  font-size: 11.5px; font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ps-form-field { display: flex; flex-direction: column; gap: 4px; }
.ps-form-label {
  font-size: 11.5px; font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.ps-form-field input,
.ps-form-field textarea {
  font: inherit;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text-strong);
  outline: none;
  transition: border-color 120ms ease, background 120ms ease;
  resize: vertical;
}
.ps-form-field input:focus,
.ps-form-field textarea:focus { border-color: var(--brand); background: var(--surface); }
.ps-form-readonly {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 0;
  border-top: 1px dashed var(--border);
}
.ps-form-readvalue {
  font-size: 13px;
  color: var(--text-strong);
  font-family: var(--f-mono);
  word-break: break-all;
}
.ps-form-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 8px;
}
.ps-btn {
  font: inherit;
  font-weight: 700;
  font-size: 13px;
  padding: 9px 18px;
  border-radius: 8px;
  border: 0;
  cursor: pointer;
  transition: filter 120ms ease, background 120ms ease;
}
.ps-btn--primary { background: var(--brand); color: #fff; }
.ps-btn--primary:hover { filter: brightness(0.95); }
.ps-btn--ghost {
  background: transparent;
  color: var(--text-strong);
  border: 1px solid var(--border);
}
.ps-btn--ghost:hover { background: var(--surface-soft); }

/* Avatar picker grid */
.ps-avatar-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
}
.ps-avatar-pick {
  aspect-ratio: 1 / 1;
  background: var(--surface-soft);
  border: 2px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  line-height: 1;
  font: inherit;
  color: var(--text-strong);
  transition: background 120ms ease, border-color 120ms ease;
  padding: 0;
}
.ps-avatar-pick:hover { background: rgba(37,99,235,0.10); }
.ps-avatar-pick.is-selected {
  border-color: var(--brand);
  background: rgba(37,99,235,0.12);
}
.ps-avatar-pick .ps-avatar-initial {
  font-size: 16px;
  color: var(--brand);
}

/* Toggle rows for notification settings */
.ps-toggle-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.ps-toggle-row:last-of-type { border-bottom: 0; }
.ps-toggle-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-strong);
}
.ps-toggle-sub {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-muted);
}
.ps-toggle-row input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 40px; height: 22px;
  background: #CBD5E1;
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background 140ms ease;
  flex-shrink: 0;
}
.ps-toggle-row input[type="checkbox"]::before {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 18px; height: 18px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
  transition: left 140ms ease;
}
.ps-toggle-row input[type="checkbox"]:checked { background: var(--brand); }
.ps-toggle-row input[type="checkbox"]:checked::before { left: 20px; }

/* Social list rows */
.ps-helper {
  font-size: 12px;
  color: var(--text-muted);
  margin: 0;
  line-height: 1.5;
}
.ps-social-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.ps-social-row {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-soft);
  font-size: 13px;
}
.ps-social-mark {
  width: 24px; height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center; justify-content: center;
  font-weight: 800;
  font-size: 12px;
}
.ps-social-name { font-weight: 600; color: var(--text-strong); }
.ps-social-status {
  font-size: 11.5px;
  color: var(--text-muted);
  background: var(--surface);
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.ps-social-status.is-connected {
  background: rgba(34,197,94,0.14);
  color: #166534;
  border-color: rgba(34,197,94,0.4);
}

/* Bullet list (location info) */
.ps-bullet-list {
  font-size: 12.5px;
  color: var(--text-strong);
  line-height: 1.6;
  padding-left: 18px;
  margin: 4px 0 0;
}

/* Empty state (no reviews etc.) */
.ps-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 40px 16px;
  gap: 8px;
}
.ps-empty-icon {
  font-size: 36px;
  line-height: 1;
  color: #94A3B8;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ps-empty-icon svg { display: block; }
.ps-empty-title { font-size: 14px; font-weight: 700; color: var(--text-strong); }
.ps-empty-sub  { font-size: 12px; color: var(--text-muted); line-height: 1.5; max-width: 280px; }

/* ---- Mobile: full-height sheet anchored to bottom ---- */
@media (max-width: 768px) {
  .profile-sheet { align-items: flex-end; }
  .ps-card {
    width: 100%;
    max-width: 100%;
    height: 100vh;
    max-height: 100vh;
    border-radius: 16px 16px 0 0;
    padding-top: 28px;             /* room for the grab handle (above) */
    animation: ps-sheet-in 240ms cubic-bezier(.2,.7,.2,1);
    will-change: transform;
  }
  .ps-body {
    padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  }
  .ps-topbar {
    padding-top: calc(env(safe-area-inset-top, 0px) + 4px);
  }
  .login-modal-card {
    padding-top: 28px;             /* room for the grab handle */
    will-change: transform;
  }
  /* The login-modal-card already had a ::before grab indicator — hide it now
     that we inject a real grab element with pointer events. */
  .login-modal-card::before { display: none; }
}

/* ===== Site info sheet (사이트 정보 / 약관) =====
   Reuses .profile-sheet shell so mobile dismiss-drag, full-height layout,
   and grab handle are all inherited. Only content-specific rules below. */
.si-section {
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
}
.si-section:last-of-type { border-bottom: 0; }
.si-section-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-strong);
  margin: 0 0 8px;
}
.si-section-en {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
}
.si-desc {
  font-size: 13px;
  color: var(--text-strong);
  line-height: 1.6;
  margin: 0;
}
.si-keywords {
  list-style: none;
  padding: 0;
  margin: 10px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.si-keywords li {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--brand);
  background: rgba(37,99,235,0.08);
  padding: 4px 10px;
  border-radius: 999px;
}
.si-meta {
  margin: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px;
  font-size: 13px;
}
.si-meta > div {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 8px;
  align-items: start;
}
.si-meta dt { font-weight: 600; color: var(--text-muted); margin: 0; }
.si-meta dd { margin: 0; color: var(--text-strong); }
.si-en { font-size: 12px; color: var(--text-muted); }

/* Terms link list — blue text per spec (참고: dubaicookiemap 약관 톤). */
.si-terms-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.si-terms-list li {
  border-bottom: 1px solid var(--border);
}
.si-terms-list li:last-child { border-bottom: 0; }
.si-link {
  display: block;
  padding: 11px 2px;
  color: #2563EB;            /* 파란색 텍스트 — 약관 링크 표준 */
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  transition: color 120ms ease, text-decoration 120ms ease;
}
.si-link:hover {
  color: #1D4ED8;
  text-decoration: underline;
}
.si-link::after {
  content: '›';
  float: right;
  color: var(--text-muted);
  font-weight: 400;
  font-size: 14px;
}
.si-trademark .si-desc {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.7;
}
.si-footer {
  padding: 14px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--border);
  background: var(--surface-soft);
}
.si-copyright {
  margin: 0;
  font-size: 11.5px;
  color: var(--text-muted);
  text-align: center;
}

/* Terms body — long-form prose with scrollable container (parent .ps-body
   already has overflow-y:auto, so we just style the typography). */
.si-terms-body {
  padding: 16px 20px 24px;
  font-size: 13.5px;
  line-height: 1.75;
  color: var(--text-strong);
}
.si-terms-body h4 {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-strong);
  margin: 20px 0 8px;
}
.si-terms-body h4:first-child { margin-top: 0; }
.si-terms-body p { margin: 0 0 10px; }
.si-terms-body ul {
  margin: 0 0 10px;
  padding-left: 20px;
}
.si-terms-body ul li { margin: 0 0 4px; }

/* Dismiss-grab — a real DOM element (not pseudo) so it can own pointer events
   with touch-action: none. Visible only on mobile; auto-injected by JS into
   .ps-card and .login-modal-card. The bar inside is the visual indicator. */
.sheet-dismiss-grab {
  display: none;
}
@media (max-width: 768px) {
  .sheet-dismiss-grab {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 28px;
    z-index: 6;
    cursor: grab;
    touch-action: none;             /* JS owns vertical gesture */
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .sheet-dismiss-grab:active { cursor: grabbing; }
  .sheet-dismiss-grab-bar {
    width: 44px;
    height: 5px;
    border-radius: 3px;
    background: #cbd5e1;
    pointer-events: none;
    transition: background 120ms ease, width 120ms ease;
  }
  .sheet-dismiss-grab:active .sheet-dismiss-grab-bar {
    background: var(--brand);
    width: 56px;
  }
}
@keyframes ps-sheet-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* =====================================================================
   Shop management sheet (.shop-sheet) — card-shop owner panel.
   Reuses .profile-sheet shell + adds content-specific styling.
===================================================================== */

/* Top store card (above menu) */
.shop-storecard {
  margin: 8px 16px 0;
  padding: 14px 16px;
  background: linear-gradient(135deg, #DBEAFE, #EFF6FF);
  border: 1px solid #BFDBFE;
  border-radius: 12px;
}
.shop-storecard-name { font-size: 15px; font-weight: 700; color: var(--text-strong); }
.shop-storecard-addr { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.shop-storecard-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(37,99,235,0.20);
}
.shop-storecard-stats > div { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.shop-stat-num   { font-family: var(--f-mono); font-size: 18px; font-weight: 700; color: var(--brand); }
.shop-stat-label { font-size: 11px; color: var(--text-muted); }

/* Inventory toolbar */
.shop-inv-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 12px 16px 4px;
}
.shop-inv-toolbar input[type="search"] {
  flex: 1; min-width: 0;
  font: inherit;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  outline: none;
}
.shop-inv-toolbar input:focus { border-color: var(--brand); background: var(--surface); }
.shop-inv-instock { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-muted); cursor: pointer; }
.shop-inv-instock input { accent-color: var(--brand); }

/* Inventory list */
.shop-inv-list { list-style: none; padding: 8px 16px 4px; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.shop-inv-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}
.shop-inv-img {
  width: 64px; height: 64px;
  object-fit: contain;
  border-radius: 8px;
  background: #fff;
  border: 1px solid var(--border);
  display: block;
}
.shop-inv-img--placeholder {
  display: flex; align-items: center; justify-content: center;
  font-size: 26px;
  color: var(--text-muted);
}
.shop-inv-meta { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.shop-inv-name {
  font-size: 13.5px; font-weight: 700;
  color: var(--text-strong);
  word-break: break-word;
}
.shop-inv-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.shop-tag {
  display: inline-flex; align-items: center;
  font-size: 10.5px; font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  letter-spacing: 0.02em;
}
.shop-tag--ghost {
  background: var(--surface-soft);
  color: var(--text-strong);
  border: 1px solid var(--border);
  font-weight: 500;
}
.shop-tag--news { background: #0F172A; color: #fff; }
.shop-tag--status        { background: rgba(100,116,139,0.18); color: #475569; }
.shop-tag--ample         { background: rgba(34,197,94,0.18);   color: #166534; }
.shop-tag--normal        { background: rgba(37,99,235,0.16);   color: #1E40AF; }
.shop-tag--low           { background: rgba(234,179,8,0.18);   color: #854D0E; }
.shop-tag--sold_out      { background: rgba(239,68,68,0.16);   color: #991B1B; }
.shop-tag--incoming      { background: rgba(6,182,212,0.18);   color: #155E75; }
.shop-tag--preorder      { background: rgba(250,204,21,0.20);  color: #854D0E; }

.shop-inv-controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  margin-top: 4px;
}
.shop-step {
  font: inherit;
  font-weight: 700;
  font-size: 11.5px;
  padding: 5px 8px;
  min-width: 30px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  color: var(--text-strong);
  font-family: var(--f-mono);
}
.shop-step:hover { background: var(--surface-soft); }
.shop-stock {
  font: inherit;
  font-family: var(--f-mono);
  font-weight: 700;
  font-size: 13px;
  width: 56px;
  text-align: center;
  padding: 5px 4px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-soft);
  outline: none;
  -moz-appearance: textfield;
}
.shop-stock::-webkit-outer-spin-button,
.shop-stock::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.shop-stock:focus { border-color: var(--brand); background: var(--surface); }
.shop-soldout {
  font: inherit;
  font-size: 11.5px;
  font-weight: 700;
  padding: 5px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  color: var(--text-strong);
  margin-left: auto;
}
.shop-soldout.is-on { background: #DC2626; color: #fff; border-color: #DC2626; }
.shop-soldout:hover:not(.is-on) { background: var(--surface-soft); }
.shop-delete {
  font: inherit;
  font-size: 14px;
  padding: 4px 8px;
  border-radius: 6px;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted);
}
.shop-delete:hover { color: #DC2626; background: rgba(239,68,68,0.08); }

/* Price row under quantity controls */
.shop-inv-price-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
}
.shop-inv-price-label {
  font-size: 11px; font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.shop-price {
  font: inherit;
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 700;
  width: 110px;
  text-align: right;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-soft);
  outline: none;
  -moz-appearance: textfield;
}
.shop-price::-webkit-outer-spin-button,
.shop-price::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.shop-price:focus { border-color: var(--brand); background: var(--surface); }
.shop-inv-price-unit {
  font-size: 11px;
  color: var(--text-muted);
}

/* Custom-add 2-column row (qty + price) */
.ps-form-row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* Catalog */
.shop-cat-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px 4px;
}
.shop-cat-toolbar input[type="search"] {
  flex: 1; min-width: 0;
  font: inherit;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  outline: none;
}
.shop-cat-toolbar input:focus { border-color: var(--brand); background: var(--surface); }
.shop-cat-count { font-size: 11px; color: var(--text-muted); white-space: nowrap; }

.shop-cat-grid {
  list-style: none; padding: 8px 16px 4px; margin: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.shop-cat-card {
  position: relative;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.shop-cat-img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  background: #fff;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.shop-cat-img--placeholder {
  display: flex; align-items: center; justify-content: center;
  font-size: 32px;
  color: var(--text-muted);
}
.shop-cat-name {
  font-size: 12px; font-weight: 700;
  color: var(--text-strong);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.shop-cat-series { font-size: 10.5px; color: var(--text-muted); }
.shop-cat-actions { display: flex; gap: 4px; flex-wrap: wrap; margin-top: auto; }
.shop-cat-add {
  font-size: 11px !important;
  padding: 5px 10px !important;
}
.shop-cat-added {
  font-size: 10.5px;
  color: #166534;
  background: rgba(34,197,94,0.14);
  padding: 4px 8px;
  border-radius: 6px;
  text-align: center;
  font-weight: 700;
}

/* News */
.shop-news-toolbar { padding: 12px 16px 4px; }
.shop-news-list { list-style: none; padding: 8px 16px 4px; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.shop-news-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.shop-news-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  font-size: 11px;
}
.shop-news-date { color: var(--text-muted); font-family: var(--f-mono); }
.shop-news-public {
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 6px;
  background: var(--surface-soft);
  color: var(--text-muted);
  border: 1px solid var(--border);
  margin-left: auto;
}
.shop-news-public.is-public { background: rgba(34,197,94,0.16); color: #166534; border-color: rgba(34,197,94,0.4); }
.shop-news-title { font-size: 14px; font-weight: 700; color: var(--text-strong); }
.shop-news-body { font-size: 12.5px; color: var(--text-strong); line-height: 1.5; }
.shop-news-img {
  width: 100%; max-height: 180px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
}
.shop-news-actions {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin-top: 4px;
}
.shop-news-actions .ps-btn {
  font-size: 11.5px !important;
  padding: 6px 12px !important;
}
.shop-news-actions .shop-news-del { color: #B91C1C !important; }

/* Mobile-specific tweaks */
@media (max-width: 768px) {
  .shop-cat-grid { grid-template-columns: repeat(2, 1fr); }
  .shop-inv-controls { gap: 3px; }
  .shop-step { min-width: 28px; padding: 4px 6px; font-size: 11px; }
  .shop-stock { width: 48px; font-size: 12px; }
  .shop-soldout { font-size: 11px; padding: 4px 8px; }
}

/* =====================================================================
   Google AdSense slot scaffold.
   - Production default: ALL ad slots hidden (display:none, no UI space taken).
   - Visibility opt-in via body[data-ads]:
       data-ads="real"        — real AdSense markup rendered (window.POKAMAP_AD_CONFIG)
       data-ads="on"          — dev placeholder boxes (POKAMAP_SHOW_AD_PLACEHOLDERS / ?ads=1)
   - Per-device gating: desktop variants only on >768px, mobile only on ≤768px.
   - z-index stays below mobile bottom-nav (40) and FAB (30) so ads never
     block map interactions; pointer-events:none on map-bottom slots.
===================================================================== */

/* =====================================================================
   사업자 입점 신청 플로팅 배너 (.biz-onboard-banner)
   - 데스크탑: iOS frosted-glass 스타일 프로모션 카드. 우측 상단(16/16),
     320px width. backdrop-filter blur + saturate, 다층 shadow, 좌측 가는
     리본으로 브랜드 액센트.
   - 모바일: 검색 헤더 아래 가로 풀폭 한 줄 컴팩트 (icon/eyebrow/sub/arrow
     CSS 로 숨김). 검색바·필터·하단 nav·광고와 안 겹침.
   - z-index 25 = locate-fab(30) 보다 낮게, ad-slot(11) 보다 위.
   - 닫기 X 는 부모 click 으로 bubble 안 되게 JS 에서 stopPropagation.
===================================================================== */
/* 모바일에선 배너 + X 둘 다 완전히 숨김. 검색바·필터 버튼과 위치가 겹쳐
   layout 충돌이 발생하므로 임시로 비활성. 데스크탑(>768px) 에서는 정상 표시. */
@media (max-width: 768px) {
  .biz-onboard-banner,
  .bob-close-extern { display: none !important; }
}

.biz-onboard-banner {
  position: absolute;
  /* 데스크탑: 우측 상단 chip-row (top:12 + 제보 52 = 약 64) 바로 아래로.
     같은 가로축에 있던 제보 버튼과 겹침 방지. 모바일은 어차피 display:none. */
  top: 80px;
  right: 16px;
  z-index: 25;
  width: 280px;
  aspect-ratio: 1 / 1;                 /* square image-driven layout */
  padding: 6px;
  background: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(20px) saturate(1.6);
          backdrop-filter: blur(20px) saturate(1.6);
  border: 0.5px solid rgba(255, 255, 255, 0.7);
  border-radius: 20px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 0 0 0.5px rgba(15, 23, 42, 0.06),
    0 18px 44px rgba(15, 23, 42, 0.16),
    0 6px 14px rgba(15, 23, 42, 0.06);
  cursor: pointer;
  font-family: var(--f-sans);
  overflow: hidden;
  transition: transform 220ms cubic-bezier(.2,.8,.2,1), box-shadow 220ms ease;
  outline: none;
}
/* 이미지/fallback 은 순수 visual — pointer-events 없음. banner 자체가 click 을
   받음. X 버튼은 z-index + 명시적 pointer-events 로 banner click 보다 먼저 잡힘. */
.bob-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 14px;
  pointer-events: none;
}
.bob-fallback,
.bob-icon,
.bob-content,
.bob-eyebrow,
.bob-title,
.bob-sub,
.bob-arrow {
  pointer-events: none;                /* 모든 텍스트 자식들 click 패스스루 */
}
/* Fallback text card — hidden by default, shown only when image fails to load.
   .bob-fallback / inner pieces are <span> (because <button> can't contain
   block-level elements per HTML spec). Force display:block for the text spans
   so vertical stacking works. */
.bob-fallback { display: none; }
.biz-onboard-banner--no-img .bob-image { display: none; }
.biz-onboard-banner--no-img {
  aspect-ratio: auto;
  width: 320px;
  padding: 12px 44px 12px 14px;
  background: rgba(255, 255, 255, 0.72);
}
.biz-onboard-banner--no-img .bob-fallback {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
}
.biz-onboard-banner--no-img .bob-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.biz-onboard-banner--no-img .bob-eyebrow,
.biz-onboard-banner--no-img .bob-title { display: block; }
.biz-onboard-banner--no-img::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: linear-gradient(180deg, #FF5A5F 0%, #DC2626 100%);
  opacity: 0.85;
  border-radius: 20px 0 0 20px;
}
.biz-onboard-banner:hover,
.biz-onboard-banner:focus-visible {
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 0 0 0.5px rgba(15, 23, 42, 0.06),
    0 18px 44px rgba(15, 23, 42, 0.14),
    0 6px 14px rgba(15, 23, 42, 0.06);
}
.biz-onboard-banner:focus-visible {
  outline: 2px solid rgba(220, 38, 38, 0.35);
  outline-offset: 2px;
}

.bob-icon {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  background: linear-gradient(135deg, #FFE4E1 0%, #FFD0CB 100%);
  color: #DC2626;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: inset 0 0 0 0.5px rgba(220, 38, 38, 0.12);
}

.bob-content { flex: 1; min-width: 0; }

.bob-eyebrow {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #DC2626;
  opacity: 0.85;
}
.bob-title {
  font-size: 14px;
  font-weight: 700;
  color: #0F172A;
  letter-spacing: -0.01em;
  line-height: 1.25;
  margin-top: 1px;
}
.bob-sub {
  margin-top: 3px;
  font-size: 11.5px;
  color: rgba(15, 23, 42, 0.62);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bob-arrow {
  position: absolute;
  right: 36px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 18px;
  font-weight: 400;
  color: rgba(15, 23, 42, 0.32);
  transition: transform 220ms cubic-bezier(.2,.8,.2,1), color 220ms ease;
  pointer-events: none;
}
.biz-onboard-banner:hover .bob-arrow,
.biz-onboard-banner:focus-visible .bob-arrow {
  transform: translateY(-50%) translateX(2px);
  color: rgba(15, 23, 42, 0.55);
}

/* X 닫기 (외부 element) — banner 와 DOM 분리. position 좌표만 banner 우상단
   align. 이 element 는 .map-shell 의 직속 자식이므로 banner 의 어떤 layering /
   pointer-events / overflow 와도 격리됨. */
.bob-close-extern {
  position: absolute;
  top: 86px;            /* banner top(80) + inner padding(6) — chip-row 제보 버튼 아래 */
  right: 22px;          /* banner right(16) + inner padding(6) */
  width: 36px;
  height: 36px;
  z-index: 9999;
  pointer-events: auto;
  border: 1px solid rgba(255, 255, 255, 0.4);
  background: rgba(15, 23, 42, 0.65);
  color: #FFFFFF;
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  margin: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
  -webkit-user-select: none;
  font-family: var(--f-sans);
  transition: background 120ms ease, transform 120ms ease;
}
.bob-close-extern:hover {
  background: rgba(15, 23, 42, 0.85);
  transform: scale(1.05);
}
.bob-close-extern:active {
  background: rgba(15, 23, 42, 0.95);
  transform: scale(0.95);
}

@media (max-width: 768px) {
  .bob-close-extern {
    top: calc(env(safe-area-inset-top, 0px) + 70px);   /* mobile banner top(64) + 6 */
    right: 18px;
    width: 38px;
    height: 38px;
    background: rgba(255, 255, 255, 0.95);
    border: 1px solid rgba(15, 23, 42, 0.18);
    color: rgba(15, 23, 42, 0.75);
  }
  .bob-close-extern:hover, .bob-close-extern:active {
    background: #FFFFFF;
    color: rgba(15, 23, 42, 0.95);
  }
}

/* (legacy — 더 이상 사용 안 함, 향후 제거 가능) */
.bob-close {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 36px;
  height: 36px;
  z-index: 999;
  pointer-events: auto;
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: rgba(15, 23, 42, 0.55);
  color: #FFFFFF;
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
  -webkit-user-select: none;
  transition: background 120ms ease;
}
.bob-close:hover {
  background: rgba(15, 23, 42, 0.78);
}
.bob-close:active {
  background: rgba(15, 23, 42, 0.88);
}

/* X 닫기 — 텍스트 fallback / 모바일 (밝은 배경) 위에서는 어두운 톤으로 전환. */
.biz-onboard-banner--no-img .bob-close {
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  border: none;
  background: transparent;
  color: rgba(15, 23, 42, 0.4);
  border-radius: 6px;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
}
.biz-onboard-banner--no-img .bob-close:hover {
  background: rgba(15, 23, 42, 0.06);
  color: rgba(15, 23, 42, 0.78);
}

/* Mobile — 이미지 비활성, 기존 1줄 텍스트 배너 형태 유지. */
@media (max-width: 768px) {
  .biz-onboard-banner {
    /* 이미지 모드 → 텍스트 카드 모드로 전환 (사각형 비율/내부 padding 무효). */
    top: calc(env(safe-area-inset-top, 0px) + 64px);
    left: 12px;
    right: 12px;
    width: auto;
    aspect-ratio: auto;
    padding: 9px 32px 9px 12px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.92);
    -webkit-backdrop-filter: blur(12px) saturate(1.4);
            backdrop-filter: blur(12px) saturate(1.4);
    border: 0.5px solid rgba(15, 23, 42, 0.08);
    box-shadow:
      0 6px 18px rgba(15, 23, 42, 0.10),
      0 1px 2px rgba(15, 23, 42, 0.04);
  }
  /* 모바일에선 이미지 안 띄움. fallback 텍스트 표시. */
  .biz-onboard-banner { padding: 9px 44px 9px 12px; }
  .biz-onboard-banner .bob-image { display: none; }
  .biz-onboard-banner .bob-fallback {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
  }
  .biz-onboard-banner .bob-content { display: flex; flex-direction: column; flex: 1; min-width: 0; }
  .biz-onboard-banner .bob-title { display: block; }
  /* 좌측 brand ribbon 모바일에서도 노출. */
  .biz-onboard-banner::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: linear-gradient(180deg, #FF5A5F 0%, #DC2626 100%);
    opacity: 0.85;
    border-radius: 12px 0 0 12px;
  }
  /* 모바일 컴팩트 — 타이틀만 표시. */
  .bob-icon, .bob-eyebrow, .bob-sub, .bob-arrow { display: none; }
  .bob-title { font-size: 13px; color: #0F172A; }
  /* X 모바일 — 솔리드 배경, 큰 터치 영역, z-index 최대로. */
  .bob-close {
    top: 50%;
    right: 4px;
    transform: translateY(-50%);
    width: 36px;
    height: 36px;
    z-index: 999;
    pointer-events: auto;
    border: 1px solid rgba(15, 23, 42, 0.15);
    background: rgba(255, 255, 255, 0.85);
    color: rgba(15, 23, 42, 0.7);
    border-radius: 50%;
    font-size: 18px;
  }
  .bob-close:hover, .bob-close:active {
    background: rgba(255, 255, 255, 1);
    color: rgba(15, 23, 42, 0.9);
  }
  .bob-close:hover {
    background: rgba(15, 23, 42, 0.06);
    color: rgba(15, 23, 42, 0.78);
  }
}

.ad-slot {
  /* Production default: collapsed completely — no flash, no reserved space.
     중요: base 에는 visual chrome (background/border/color) 없음.
     실 모드(real)에서 AdSense 가 fill 전 빈 회색 박스 가 사용자에게 보이지
     않도록. chrome 은 dev placeholder 모드(body[data-ads="on"]) 에서만 적용. */
  display: none;
  align-items: center;
  justify-content: center;
  user-select: none;
  pointer-events: auto;
  font-family: var(--f-sans);
  /* AdSense 가 가끔 컨테이너 보다 큰 iframe 을 들이밀 때를 대비한 안전망. */
  overflow: hidden;
}
/* Dev placeholder 모드 — 광고 위치 시각 확인용 chrome. real 모드에는 적용 X. */
body[data-ads="on"] .ad-slot {
  background: #F3F4F6;
  border: 1px dashed #CBD5E1;
  color: #94A3B8;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: 6px;
}
/* 실 모드: AdSense 가 아직 fill 안 한 동안은 슬롯 자체를 시각/클릭 영역에서
   완전히 빼둠. 크기는 그대로 유지해야 AdSense 가 bid 가능 (size 0 으로 만들면
   광고를 못 받음). chrome 은 어차피 base 에서 빠진 상태라 빈 박스 안 보임. */
body[data-ads="real"] .ad-slot:not(.ad-slot--filled) {
  opacity: 0;
  pointer-events: none;
}
body[data-ads="real"] .ad-slot.ad-slot--filled {
  opacity: 1;
  pointer-events: auto;
  transition: opacity 160ms ease;
}
.ad-slot-label { font-size: 10.5px; font-weight: 700; }

/* ----- Variants (sizing only — visibility gated by body[data-ads] below) ----- */
.ad-slot--desktop-horizontal {
  width: 728px; height: 90px; max-width: calc(100% - 32px);
  margin: 8px auto;
}
.ad-slot--desktop-detail {
  width: 100%; min-height: 90px; max-height: 96px;
  margin: 8px 0 0;
}
.ad-slot--desktop-rect {
  width: 300px; height: 250px; max-width: 100%;
  margin: 12px auto 16px;
}
.ad-slot--mobile-banner {
  width: 320px; height: 50px; max-width: calc(100vw - 32px);
  margin: 0 auto;
}
.ad-slot--mobile-rect {
  width: 100%; max-width: 320px; aspect-ratio: 6 / 5;
  margin: 12px auto 16px;
}

/* ----- Visibility gate ----- */
/* Desktop (>768px): show desktop variants only when body[data-ads] is set. */
body[data-ads] .ad-slot--desktop-horizontal,
body[data-ads] .ad-slot--desktop-detail,
body[data-ads] .ad-slot--desktop-rect { display: flex; }

/* Mobile (≤768px): show mobile variants only when body[data-ads] is set;
   desktop variants stay hidden. */
@media (max-width: 768px) {
  body[data-ads] .ad-slot--desktop-horizontal,
  body[data-ads] .ad-slot--desktop-detail,
  body[data-ads] .ad-slot--desktop-rect { display: none; }
  body[data-ads] .ad-slot--mobile-banner,
  body[data-ads] .ad-slot--mobile-rect { display: flex; }
}

/* ----- Map-bottom slots (positioned over the map viewport) ----- */
.ad-slot--map-bottom {
  position: absolute;
  z-index: 11;                          /* above attribution (10), below FAB (30) */
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;                 /* ad placeholder doesn't block map clicks */
}
.ad-slot--map-bottom .ad-slot-label { pointer-events: auto; }
/* Desktop: center within the visible map strip. Sidebar / detail open layouts
   shift the strip's left edge — use left+right anchors so margin:auto centers
   the fixed-width 728px banner correctly. */
@media (min-width: 1024px) {
  .ad-slot--desktop-horizontal.ad-slot--map-bottom {
    bottom: 20px;
    left: var(--rail-w, 80px);
    right: 0;
    transform: none;
    margin: 0 auto;
  }
  .map-shell[data-layout="rail-list"] .ad-slot--desktop-horizontal.ad-slot--map-bottom,
  .map-shell[data-layout="rail-list-detail"] .ad-slot--desktop-horizontal.ad-slot--map-bottom {
    left: calc(var(--rail-w, 80px) + var(--list-w, 380px));
  }
}

/* Mobile map-bottom: sit above the bottom nav, with FAB pushed up by
   --mobile-ad-h ONLY when ads are actually rendered. Default 0px → no shift
   in production. Hidden when a sheet is at FULL state (over opaque sheet). */
@media (max-width: 768px) {
  .ad-slot--mobile-banner.ad-slot--map-bottom {
    bottom: calc(var(--mobile-overlay-bottom, 72px) + 8px);
    z-index: 11;
    transition: bottom 220ms cubic-bezier(.2,.7,.2,1);
  }
  /* Sheet-full hide (only matters when ad is showing). */
  body[data-ads] .map-detail[data-open="true"][data-sheet-state="full"] ~ .ad-slot--mobile-banner.ad-slot--map-bottom,
  body[data-ads] .map-sidebar[data-sheet-state="full"][data-mode="category"] ~ .ad-slot--mobile-banner.ad-slot--map-bottom,
  body[data-ads] .map-sidebar[data-sheet-state="full"][data-mode="search"]   ~ .ad-slot--mobile-banner.ad-slot--map-bottom,
  body[data-ads] .map-sidebar[data-sheet-state="full"][data-mode="detail"]   ~ .ad-slot--mobile-banner.ad-slot--map-bottom {
    display: none;
  }

  /* Default: 0px (no FAB shift in production). Opt-in to 66px only when ads
     are actually showing. 66px = 50px banner + 16px gap. */
  .map-shell { --mobile-ad-h: 0px; }
  body[data-ads] .map-shell { --mobile-ad-h: 66px; }
  /* Real-ad mode but AdSense has not yet filled (or returned unfilled) for
     the mobile-bottom slot → reset to 0 so the FAB / locate / Naver logo
     don't stay pushed up by a phantom 66px ad height. JS sets the
     .mobile-bottom-ad-filled class on body when the slot actually fills.
     Dev placeholder mode (body[data-ads="on"]) keeps the 66px shift so
     layout testing still works. */
  body[data-ads="real"]:not(.mobile-bottom-ad-filled) .map-shell {
    --mobile-ad-h: 0px;
  }
  .map-shell .map-fab {
    bottom: calc(var(--mobile-overlay-bottom, 72px) + var(--mobile-ad-h, 0px)) !important;
  }
  .map-status {
    bottom: calc(var(--mobile-overlay-bottom, 72px) + var(--mobile-ad-h, 0px)) !important;
  }
}

/* AdSense returned no ad for this slot → hide the entire container so the
   dashed placeholder box never shows to users. Outside the mobile media
   block because it applies to all viewports. */
.ad-slot--unfilled {
  display: none !important;
}

/* =====================================================================
   장소 댓글 / 리뷰 섹션
   ===================================================================== */
.pc-section {
  margin-top: 18px;
  padding: 16px 16px 24px;
  border-top: 1px solid var(--border, #E5E7EB);
}
.pc-section--disabled { color: var(--text-muted, #6B7280); }
.pc-disabled-msg { font-size: 13px; margin: 8px 0 0; }
.pc-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.pc-title {
  font-size: 15px;
  font-weight: 700;
  margin: 0;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  color: var(--text-strong, #0F172A);
}
.pc-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--brand, #2563EB);
}
.pc-sort-pills {
  display: inline-flex;
  background: var(--surface-soft, #F3F4F6);
  border-radius: 999px;
  padding: 3px;
}
.pc-sort-pill {
  font-size: 12.5px;
  font-weight: 600;
  padding: 6px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted, #6B7280);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.pc-sort-pill.active {
  background: #FFFFFF;
  color: var(--text-strong, #0F172A);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
}

/* ----- compose: 로그인 안내 + 비회원 폼 ----- */
.pc-compose { margin-bottom: 14px; }
.pc-login-hint {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--surface-soft, #F3F4F6);
  border-radius: 10px;
  font-size: 13px;
  color: var(--text-muted, #6B7280);
  margin-bottom: 10px;
}
.pc-login-btn {
  margin-left: auto;
  padding: 6px 14px;
  border: 0;
  border-radius: 8px;
  background: var(--brand, #2563EB);
  color: #FFFFFF;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
.pc-login-btn:hover { background: #1D4ED8; }

.pc-form { display: flex; flex-direction: column; gap: 8px; }
.pc-form-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 8px;
}
@media (max-width: 540px) {
  .pc-form-grid { grid-template-columns: 1fr; }
}
.pc-nick-wrap {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 6px;
}
.pc-nick-wrap .pc-input { flex: 1; }
.pc-random {
  flex: 0 0 auto;
  width: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border, #E5E7EB);
  background: var(--surface, #FFFFFF);
  color: var(--text-muted, #6B7280);
  border-radius: 8px;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.pc-random:hover { background: var(--surface-soft, #F3F4F6); color: var(--brand, #2563EB); }
.pc-random:focus-visible {
  outline: 2px solid var(--brand, #2563EB);
  outline-offset: 1px;
}
.pc-input, .pc-textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 8px;
  font-size: 14px;
  background: #FFFFFF;
  color: var(--text-strong, #0F172A);
  font-family: inherit;
}
.pc-textarea { resize: vertical; min-height: 78px; line-height: 1.5; }
.pc-input:focus, .pc-textarea:focus {
  outline: none;
  border-color: var(--brand, #2563EB);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.pc-form-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.pc-form-row--meta { padding-top: 2px; }
.pc-hint-text {
  font-size: 12px;
  color: var(--text-muted, #6B7280);
}
.pc-counter {
  font-size: 11.5px;
  color: var(--text-muted, #6B7280);
  font-variant-numeric: tabular-nums;
}
.pc-submit {
  padding: 10px 18px;
  border: 0;
  border-radius: 8px;
  background: var(--brand, #2563EB);
  color: #FFFFFF;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  min-width: 80px;
}
.pc-submit:hover { background: #1D4ED8; }
.pc-submit:disabled { opacity: 0.5; cursor: not-allowed; }
.pc-submit--sm { padding: 8px 14px; font-size: 12.5px; min-width: 64px; }

/* ----- list ----- */
.pc-list { display: flex; flex-direction: column; gap: 4px; }
.pc-skeleton, .pc-empty {
  padding: 18px 4px;
  text-align: center;
  color: var(--text-muted, #6B7280);
  font-size: 13px;
}

.pc-item { padding: 12px 0; }
.pc-item + .pc-item { border-top: 1px solid var(--border, #E5E7EB); }
.pc-item--reply {
  margin-left: 26px;
  padding: 10px 0 10px 12px;
  border-top: 1px dashed var(--border, #E5E7EB);
  border-left: 2px solid var(--surface-soft, #F3F4F6);
}
.pc-item--reply + .pc-item--reply { border-top: 1px dashed var(--border, #E5E7EB); }
.pc-item--deleted { opacity: 0.7; }

.pc-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.pc-body-col { flex: 1; min-width: 0; }

.pc-meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 4px;
}
.pc-author {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-strong, #0F172A);
}
.pc-time {
  font-size: 11.5px;
  color: var(--text-muted, #6B7280);
}
.pc-body {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text-strong, #0F172A);
  word-break: break-word;
  white-space: pre-wrap;
}
.pc-item--deleted .pc-body { font-style: italic; color: var(--text-muted, #6B7280); }

.pc-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
}
.pc-like, .pc-reply-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 8px;
  border: 1px solid transparent;
  background: transparent;
  border-radius: 7px;
  cursor: pointer;
  font-size: 12px;
  color: var(--text-muted, #6B7280);
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.pc-like:hover, .pc-reply-btn:hover {
  background: var(--surface-soft, #F3F4F6);
  color: var(--text-strong, #0F172A);
}
.pc-like.liked {
  color: #EF4444;
  border-color: rgba(239, 68, 68, 0.25);
  background: rgba(239, 68, 68, 0.06);
}
.pc-like-icon { display: inline-flex; align-items: center; }
.pc-like-count { font-variant-numeric: tabular-nums; }

.pc-reply-form-slot:not(:empty) {
  margin-top: 10px;
  padding-left: 0;
}

/* ----- 더보기 메뉴 ----- */
.pc-menu-wrap { position: relative; flex: 0 0 auto; }
.pc-menu-btn {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--text-muted, #6B7280);
  border-radius: 50%;
  cursor: pointer;
}
.pc-menu-btn:hover { background: var(--surface-soft, #F3F4F6); color: var(--text-strong, #0F172A); }
.pc-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 20;
  min-width: 120px;
  background: #FFFFFF;
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
  padding: 4px;
  display: flex;
  flex-direction: column;
}
.pc-menu[hidden] { display: none; }
.pc-menu-item {
  text-align: left;
  padding: 8px 12px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  font-size: 13px;
  color: var(--text-strong, #0F172A);
  cursor: pointer;
}
.pc-menu-item:hover { background: var(--surface-soft, #F3F4F6); }
.pc-menu-item--danger { color: #EF4444; }
.pc-menu-item--danger:hover { background: rgba(239, 68, 68, 0.08); }

/* ----- 모달 (삭제 확인 / 신고) ----- */
.pc-modal {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.pc-modal.is-open { display: flex; }
.pc-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.5);
  backdrop-filter: blur(2px);
}
.pc-modal-card {
  position: relative;
  width: min(420px, 100%);
  background: #FFFFFF;
  border-radius: 14px;
  padding: 20px;
  box-shadow: 0 12px 36px rgba(15, 23, 42, 0.22);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.pc-modal-title {
  font-size: 16px;
  font-weight: 700;
  margin: 0;
  color: var(--text-strong, #0F172A);
}
.pc-modal-msg {
  margin: 0;
  font-size: 13px;
  color: var(--text-muted, #6B7280);
}
.pc-modal-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 8px;
  font-size: 14px;
  background: #FFFFFF;
  color: var(--text-strong, #0F172A);
  font-family: inherit;
}
.pc-modal-input:focus {
  outline: none;
  border-color: var(--brand, #2563EB);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.pc-modal-error {
  font-size: 12.5px;
  color: #EF4444;
  margin-top: -4px;
}
.pc-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}
.pc-modal-btn {
  padding: 9px 16px;
  border: 0;
  border-radius: 8px;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
}
.pc-modal-btn--ghost {
  background: var(--surface-soft, #F3F4F6);
  color: var(--text-strong, #0F172A);
}
.pc-modal-btn--ghost:hover { background: #E5E7EB; }
.pc-modal-btn--primary {
  background: var(--brand, #2563EB);
  color: #FFFFFF;
}
.pc-modal-btn--primary:hover { background: #1D4ED8; }
.pc-modal-btn--danger {
  background: #EF4444;
  color: #FFFFFF;
}
.pc-modal-btn--danger:hover { background: #DC2626; }
.pc-modal-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.pc-report-reasons {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.pc-report-reason {
  padding: 7px 12px;
  border: 1px solid var(--border, #E5E7EB);
  background: #FFFFFF;
  border-radius: 999px;
  font-size: 12.5px;
  color: var(--text-muted, #6B7280);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.pc-report-reason:hover { background: var(--surface-soft, #F3F4F6); }
.pc-report-reason.active {
  background: var(--brand, #2563EB);
  border-color: var(--brand, #2563EB);
  color: #FFFFFF;
}

/* ----- 모바일 ----- */
@media (max-width: 540px) {
  .pc-section { padding: 14px 14px 28px; }
  .pc-item--reply { margin-left: 18px; }
  .pc-actions { gap: 6px; }
  .pc-submit { width: 100%; }
  .pc-form-row { flex-direction: column; align-items: stretch; gap: 6px; }
  .pc-form-row--meta { flex-direction: row; }
}

/* =====================================================================
   샵 관리 — 이미지 업로더 (매장 대표 / 소식 1장)
   ===================================================================== */
.shop-img-uploader {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  background: var(--surface-soft, #F3F4F6);
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 10px;
}
.shop-img-preview {
  width: 100%;
  height: 160px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #FFFFFF;
  border: 1px dashed var(--border, #E5E7EB);
  border-radius: 8px;
  overflow: hidden;
}
.shop-img-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.shop-img-placeholder {
  font-size: 13px;
  color: var(--text-muted, #6B7280);
}
.shop-img-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}
.shop-img-actions .ps-btn {
  cursor: pointer;
}
.shop-img-actions input[type="file"] { display: none; }
.shop-img-clear { color: #EF4444; }
.ps-form-help {
  font-size: 11.5px;
  color: var(--text-muted, #6B7280);
  display: block;
  margin-top: 4px;
}

/* =====================================================================
   Phase 5 — 프로필 시트의 business 전용 카드
   ===================================================================== */
.ps-biz-card {
  margin: 12px 14px;
  padding: 14px 16px;
  background: linear-gradient(135deg, rgba(37,99,235,0.08), rgba(37,99,235,0.02));
  border: 1px solid rgba(37,99,235,0.22);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ps-biz-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.ps-biz-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--brand, #2563EB);
  color: #FFFFFF;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.ps-biz-tag {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(37, 99, 235, 0.10);
  color: var(--brand, #2563EB);
  font-size: 11px;
  font-weight: 700;
}
.ps-biz-places {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ps-biz-place {
  padding: 8px 10px;
  background: #FFFFFF;
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 8px;
}
.ps-biz-place-name {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-strong, #0F172A);
}
.ps-biz-place-meta {
  font-size: 11.5px;
  color: var(--text-muted, #6B7280);
  margin-top: 2px;
  word-break: keep-all;
}
.ps-biz-place-meta em {
  font-style: normal;
  color: #DC2626;
  font-weight: 600;
}
.ps-biz-places-empty {
  font-size: 12.5px;
  color: var(--text-muted, #6B7280);
  padding: 8px 4px;
}
.ps-biz-card-actions {
  display: flex;
  justify-content: flex-end;
}
.ps-biz-card-actions .ps-btn {
  min-height: 36px;
}

/* ============================================================
   Light-scheme lock — OS dark-mode override safety net.
   ============================================================
   :root color-scheme + index.html <meta name="color-scheme"> 가 1차 방어.
   여기서는 모바일 Safari/Chrome 의 auto-dark heuristic 이 form 컨트롤 /
   배경 / 핀 이미지에 invert/brightness 보정을 거는 경우를 완전 차단하는
   2차 방어. 기존 라이트 테마 색은 그대로 유지 — 다크모드일 때도 동일한
   라이트 토큰을 강제할 뿐. */

/* Form 컨트롤이 OS 다크에서 시스템 색으로 invert 되는 것 방지.
   bg/text 는 명시 — Safari 가 prefers-color-scheme 만 보고 input 배경을
   #1c1c1e 같은 시스템 색으로 바꾸는 케이스가 흔함. */
input, textarea, select, button {
  color-scheme: light;
}

/* 지도 핀 / 로고 / 아이콘이 다크모드 보정 (filter: invert / brightness /
   contrast / mix-blend-mode) 을 어떤 경로로든 받아 색이 변하는 것 방지. */
.rail-icon-img,
.map-pin img,
.map-pin svg,
.marker-icon,
.brand-mark img,
.brand-mark svg,
.ps-avatar-emoji,
.dv-pin,
.holo-pin {
  filter: none !important;
  mix-blend-mode: normal !important;
}

@media (prefers-color-scheme: dark) {
  /* OS 다크모드라도 모든 라이트 토큰을 그대로 유지. :root color-scheme
     이 대부분 막아주지만, 일부 사용자 에이전트가 무시하는 경우를 위해
     명시. 색상 값은 :root 의 기본값과 동일 — 토큰 변경 없음. */
  :root {
    color-scheme: light;
  }
  html, body {
    background: var(--surface-soft);
    color: var(--text-strong);
    color-scheme: light;
  }
  /* form 컨트롤 — 시스템이 배경/텍스트를 강제로 바꾸려 할 때 명시값으로
     덮어쓰기. */
  input, textarea, select {
    background-color: #FFFFFF;
    color: var(--text-strong);
    border-color: var(--border-strong);
  }
  /* 이미지/핀에 다크 보정 못 걸게 한 번 더 못박음 (cascade specificity 확보). */
  img, svg,
  .rail-icon-img,
  .map-pin img, .map-pin svg,
  .marker-icon,
  .brand-mark img, .brand-mark svg {
    filter: none !important;
    mix-blend-mode: normal !important;
  }
}

/* ============================================================
   Stationery 클러스터 마커.
   ============================================================
   문구점이 줌아웃 상태에서 그리드 셀로 묶일 때 표시되는 동그라미.
   indigo gradient — 카드샵(파랑)/자판기(노랑)/공식샵(빨강) 어디와도 헷갈리지
   않는 색. 개수별 사이즈는 NaverMapAdapter.addClusterMarker 가 modifier
   클래스 (--lg/--xl) 로 전환. */
.stationery-cluster {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: linear-gradient(135deg, #818CF8 0%, #6366F1 60%, #4F46E5 100%);
  color: #FFFFFF;
  border: 2px solid rgba(255, 255, 255, 0.92);
  box-shadow:
    0 2px 6px rgba(15, 23, 42, 0.28),
    0 0 0 0.5px rgba(79, 70, 229, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--f-sans);
  font-weight: 700;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  user-select: none;
  pointer-events: auto;
  transition: transform 120ms ease, box-shadow 160ms ease;
}
.stationery-cluster:hover {
  transform: scale(1.08);
  box-shadow:
    0 4px 12px rgba(15, 23, 42, 0.36),
    0 0 0 0.5px rgba(79, 70, 229, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.45);
}
.stationery-cluster--lg {
  width: 48px;
  height: 48px;
  font-size: 14px;
}
.stationery-cluster--xl {
  width: 56px;
  height: 56px;
  font-size: 15px;
}
.stationery-cluster-num {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.2px;
}

/* ============================================================
   Mobile gesture / viewport lock.
   ============================================================
   증상: "맵이 아래로만 가지고 위로 안 가진다"
   원인: body { min-height: 100vh } + 모바일 Safari 의 "large viewport
   (URL bar 숨김)" 100vh 정의 때문에 URL bar 가 보이는 상태에서는 body 가
   viewport 보다 미세하게 길어서 native scroll 이 가능한 상태가 됨. 사용자가
   지도를 위로 드래그하면 iOS 가 그 제스처를 "스크롤 ↑ → URL bar 보이게"
   로 가로채 지도 pan 이 막힘.
   해결:
   (1) body.page-map 의 height 를 100dvh (dynamic viewport) 로 고정 +
       overflow: hidden + overscroll-behavior: none → body 가 native
       scroll 불가능 → iOS 가 제스처를 가져가지 않음.
   (2) .map-shell 의 height 도 100dvh 기반으로 — URL bar 변동 시 지도가
       리사이즈되지 않고 안정적으로 채움.
   (3) floating UI (검색창 / 칩 / 카테고리바 / FAB) 에 touch-action:
       manipulation 명시 — 더블탭 줌만 차단, single tap/drag/pinch 는 통과.
   (4) #map-canvas 안쪽엔 touch-action 제한 두지 않음 — Naver SDK 의 pan/
       pinch/rotate 멀티터치가 그대로 동작.
   safe-area-inset-top 은 이미 .search-shell-anchor / .chip-row-anchor 에
   적용됨 — 노치/Dynamic Island 영향 받지 않음 (line 3039, 3046).
*/
@media (max-width: 768px) {
  /* ----- FIXED VIEWPORT LAYOUT (모바일 map 페이지) -----
     이전엔 calc(100vh - nav-h) 로 map-shell height 를 계산했는데, iOS PWA
     standalone 에서 100vh/100dvh/window.innerHeight 가 미세하게 어긋나서
     하단에 빈 영역이 남는 문제 발생. 해결: anchor-based layout.

     - html, body: 화면 자체에 100% 고정. overflow: hidden 으로 스크롤 차단.
     - body.page-map .map-shell: position fixed + top:0, bottom:var(--nav-h).
       높이 계산 없이 nav top 까지 자동으로 stretch. iOS viewport 미스매치 무관.
     - .mobile-cat-bar: 그대로 position fixed; bottom: 0 (변동 없음).
     - safe-area-inset-bottom 은 .mobile-cat-bar 의 padding-bottom 으로만
       반영 — map-shell 의 bottom 변수에 추가로 더하지 X (이중 카운트 X). */
  html, body {
    height: 100%;
    overflow: hidden;
    overscroll-behavior: none;
  }
  body.page-map {
    /* fixed 화면. height: 100% 가 html 의 100% (== 100% of viewport) 따라감.
       --app-vh fallback 유지 (혹시 html height: 100% 가 0 으로 잡히는 edge case). */
    height: 100%;
    height: var(--app-vh, 100%);
    min-height: 0;
    overflow: hidden;
  }
  body.page-map .map-shell {
    /* anchor-based: top 0 부터 nav-top (= viewport bottom - nav-h) 까지. */
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: var(--mobile-nav-real-h, var(--mobile-cat-bar-h, 64px)) !important;
    width: auto !important;
    height: auto !important;
  }
  /* UI surface 더블탭 줌 차단. 지도(#map-canvas) 는 손대지 않음. */
  .search-shell-anchor,
  .search-shell,
  .chip-row-anchor,
  .chip-row,
  .mobile-cat-bar,
  .mcb-item,
  .map-fab,
  #feedback-fab.map-fab {
    touch-action: manipulation;
  }
  /* 지도 캔버스: Naver SDK 의 멀티터치 제스처 (pan/pinch/rotate) 가 부모
     touch-action 상속에 영향받지 않도록 명시. pan-x pan-y pinch-zoom 은
     SDK 가 필요한 제스처 전부 포함 — double-tap zoom 만 SDK 가 별도 처리. */
  #map-canvas,
  #map-canvas > div,
  #map-canvas canvas {
    touch-action: pan-x pan-y pinch-zoom;
  }
}

/* ============================================================
   장소 제보 — chip-row 의 우측 끝 "제보" 버튼 + 모달
   ============================================================
   chip-row-anchor 안에 chip-row (스크롤 가능) 와 chip-report-btn (sticky right)
   를 flex 로 배치해서 칩이 가로로 늘어나도 제보 버튼은 항상 우측 끝에 보임. */
#chip-row-anchor {
  display: flex;
  align-items: center;
  gap: 8px;
  pointer-events: none;          /* 빈 공간은 통과; 자식 chip-row / chip-report-btn 가 받음 */
}
#chip-row-anchor > .chip-row {
  flex: 1 1 auto;
  min-width: 0;
  pointer-events: auto;
}
/* 제보 버튼 — 데스크탑/모바일 동일한 정사각 cyan 아이콘 버튼.
   라벨 ("제보") 텍스트는 hide, aria-label / title 이 접근성 보장.
   아이콘 정중앙 정렬을 위해 flex + justify-content: center + padding/gap/
   line-height 0 모두 명시. */
.chip-report-btn {
  flex: 0 0 auto;
  pointer-events: auto;
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 0;
  line-height: 1;
  border-radius: 14px;
  border: 1px solid #06B6D4;
  background: linear-gradient(135deg, #67E8F9 0%, #22D3EE 55%, #06B6D4 100%);
  color: #FFFFFF;
  font-family: var(--f-sans);
  font-size: 0;
  letter-spacing: 0;
  cursor: pointer;
  white-space: nowrap;
  box-shadow:
    0 0 0 1px rgba(34, 211, 238, 0.25),
    0 6px 16px rgba(6, 182, 212, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.55);
  transition: transform 120ms ease, box-shadow 160ms ease, filter 120ms ease;
}
.chip-report-btn:hover {
  filter: brightness(1.05);
  box-shadow:
    0 0 0 1px rgba(34, 211, 238, 0.35),
    0 10px 22px rgba(6, 182, 212, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.chip-report-btn:active { transform: translateY(1px); }
.chip-report-label {
  /* 시각적으로 숨김 — aria-label / title 이 접근성 보장 */
  display: none;
}
.chip-report-icon {
  display: block;                /* inline SVG baseline 정렬 영향 제거 */
  width: 22px;
  height: 22px;
  margin: 0;
  flex: 0 0 auto;
}

/* 모바일 특화 — 칩이 wrap 으로 2-3줄 늘어나도 제보 버튼은 첫 줄 우측 끝
   고정 (손가락 reachability). desktop 은 base 의 align-items: center 그대로 사용.
   flex-wrap 은 의도적으로 nowrap (제보 버튼 첫 줄 유지). 실시간 현황 모바일 anchor 는
   chip-row-anchor 밖 sibling 으로 분리 + absolute 로 chip row 아래에 위치 (JS 동적). */
@media (max-width: 768px) {
  #chip-row-anchor {
    align-items: flex-start;
    gap: 6px;
  }
}

/* ============================================================
   제보 모달 (.report-sheet) — profile-sheet shell 재사용
   ============================================================ */

/* 단계 진행 도트 */
.report-progress {
  display: flex; gap: 6px;
  justify-content: center;
  padding: 4px 0 12px;
}
.report-progress-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--surface-mid);
  transition: background 160ms ease;
}
.report-progress-dot.is-on { background: var(--brand); }

.report-form {
  display: flex; flex-direction: column; gap: 14px;
  padding: 0 18px 18px;
}
.report-section-label {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-muted);
  margin-bottom: -4px;
}
.report-note {
  background: #FEF3C7;
  border: 1px solid #FDE68A;
  color: #92400E;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12.5px;
}

/* 장소 타입 선택 */
.report-type-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.report-type-card {
  position: relative;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 4px;
  padding: 12px 6px;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  user-select: none;
  transition: border-color 120ms ease, box-shadow 120ms ease, background 120ms ease;
}
.report-type-card.is-selected {
  border-color: var(--brand);
  background: var(--brand-soft);
  box-shadow: 0 0 0 1px var(--brand);
}
.report-type-card input[type="radio"] {
  position: absolute; opacity: 0; pointer-events: none;
}
.report-type-icon {
  /* SVG 아이콘 (사이트 chip/마커와 동일). currentColor 사용 — 선택 시 brand 색으로. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  color: var(--text-strong);
  line-height: 1;
}
.report-type-icon svg { width: 28px; height: 28px; display: block; }
.report-type-card.is-selected .report-type-icon { color: var(--brand); }
.report-type-label { font-size: 13px; font-weight: 700; color: var(--text-strong); }

/* 주소 입력 + 확인 버튼 */
.report-address-row {
  display: flex; gap: 6px;
  align-items: stretch;
}
.report-address-row .ps-form-input { flex: 1; min-width: 0; }

/* Phase 2-2: 사진 첨부 — preview grid */
.report-img-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
  gap: 8px;
  margin-top: 6px;
}
.report-img-tile {
  position: relative;
  aspect-ratio: 1 / 1;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  background: var(--surface-soft);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  cursor: default;
}
.report-img-tile--add {
  cursor: pointer;
  flex-direction: column;
  gap: 2px;
  color: var(--text-muted);
  transition: border-color 120ms ease, background 120ms ease, color 120ms ease;
}
.report-img-tile--add:hover {
  border-color: var(--brand);
  background: var(--brand-soft);
  color: var(--brand);
}
.report-img-tile-plus {
  font-size: 22px;
  font-weight: 300;
  line-height: 1;
}
.report-img-tile-add-label {
  font-size: 11px;
  font-weight: 600;
}
.report-img-tile--full {
  color: var(--text-subtle);
  border-style: solid;
}
.report-img-tile-thumb {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.report-img-tile-remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 0;
  background: rgba(15, 23, 42, 0.78);
  color: #fff;
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.report-img-tile-remove:hover { background: rgba(220, 38, 38, 0.92); }
.report-img-tile.is-failed { border-color: #DC2626; }
.report-img-tile-err {
  position: absolute;
  bottom: 4px; left: 4px;
  background: rgba(220, 38, 38, 0.92);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 3px;
}

/* Phase 2-1: 장소 검색 row + 후보 카드 list */
.report-search-row {
  display: flex; gap: 6px;
  align-items: stretch;
}
.report-search-row .ps-form-input { flex: 1; min-width: 0; }
.report-search-panel {
  margin-top: -6px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  max-height: 280px;
  overflow-y: auto;
  display: flex; flex-direction: column;
}
.report-search-msg {
  padding: 12px;
  font-size: 12.5px;
  color: var(--text-muted);
  text-align: center;
}
.report-search-msg--err { color: #B91C1C; }
.report-search-item {
  display: block; width: 100%;
  background: transparent; border: 0;
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 120ms ease;
}
.report-search-item:last-child { border-bottom: 0; }
.report-search-item:hover { background: var(--brand-soft); }
.report-search-item-name {
  font-size: 13.5px; font-weight: 700;
  color: var(--text-strong);
  margin-bottom: 2px;
}
.report-search-item-addr {
  font-size: 12px; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.report-search-item-meta {
  display: flex; gap: 8px; flex-wrap: wrap;
  font-size: 11px; color: var(--text-muted);
  margin-top: 4px;
}
.report-search-item-meta span:not(:last-child)::after {
  content: '·';
  margin-left: 8px;
  color: var(--text-subtle);
}
.report-addr-ok      { color: #15803D; font-weight: 600; }
.report-addr-err     { color: #B91C1C; font-weight: 600; }
.report-addr-pending { color: var(--text-muted); font-style: italic; }

/* dedupe 경고 (step 3) */
.report-dedupe {
  border-radius: 10px;
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.report-dedupe--hard {
  background: #FEE2E2;
  border: 1px solid #FCA5A5;
  color: #991B1B;
}
.report-dedupe--soft {
  background: #FEF9C3;
  border: 1px solid #FDE68A;
  color: #854D0E;
}
.report-dedupe-title { font-weight: 800; font-size: 13.5px; }
.report-dedupe-place {
  background: rgba(255, 255, 255, 0.75);
  border-radius: 6px;
  padding: 6px 8px;
}
.report-dedupe-name { font-weight: 700; font-size: 13.5px; color: var(--text-strong); }
.report-dedupe-addr { font-size: 12px; color: var(--text-muted); }
.report-dedupe-confirm {
  display: inline-flex; gap: 6px; align-items: center;
  font-size: 12.5px; font-weight: 600;
  cursor: pointer;
}

/* 제보자 카드 */
.report-reporter-card {
  border-radius: 10px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
}
.report-reporter-label { font-size: 11px; color: var(--text-muted); font-weight: 700; }
.report-reporter-id    { font-size: 14px; font-weight: 700; color: var(--text-strong); margin-top: 2px; }
.report-reporter-group { display: flex; flex-direction: column; gap: 10px; }

/* 정책 안내 */
.report-policy {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-muted);
  background: var(--surface-soft);
  border-radius: 8px;
  padding: 10px 12px;
}
.report-policy strong { color: var(--text-strong); font-weight: 700; }

/* 에러 박스 */
.report-error {
  background: #FEE2E2;
  border: 1px solid #FCA5A5;
  color: #991B1B;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12.5px;
  font-weight: 600;
}

/* Step 액션 버튼 줄 */
.report-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 4px;
}
.report-actions .ps-btn { min-height: 38px; }

/* 필수 표시 */
.report-form .req { color: #DC2626; font-style: normal; font-weight: 700; margin-left: 2px; }

/* ============================================================
   admin: 사용자 제보 탭 row 스타일
   ============================================================ */
.report-row {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
  background: var(--surface);
}
.report-row-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-bottom: 4px;
}
.report-row-type {
  background: var(--surface-mid);
  color: var(--text-strong);
  font-size: 11px; font-weight: 700;
  padding: 2px 6px; border-radius: 4px;
}
.report-row-name {
  font-weight: 700; font-size: 14px; color: var(--text-strong);
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.report-row-dup {
  background: #FEF3C7; color: #92400E;
  font-size: 11px; font-weight: 700;
  padding: 2px 6px; border-radius: 4px;
}
.report-row-status {
  font-size: 11px; font-weight: 700;
  padding: 2px 6px; border-radius: 4px;
  background: var(--surface-mid); color: var(--text-strong);
}
.report-row-status--published { background: #DCFCE7; color: #166534; }
.report-row-status--hidden    { background: #FEF9C3; color: #854D0E; }
.report-row-status--removed   { background: #FEE2E2; color: #991B1B; }
.report-row-status--merged    { background: #E0E7FF; color: #3730A3; }
.report-row-meta {
  font-size: 12px; color: var(--text-muted);
  margin-bottom: 6px;
}
.report-row-reporter { font-weight: 600; }
.report-row-note {
  background: var(--surface-soft);
  border-left: 3px solid var(--brand);
  padding: 4px 8px;
  margin: 6px 0;
  font-size: 12px;
  color: var(--text-strong);
}
.report-row-actions {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.report-row-actions .ps-btn { min-height: 30px; padding: 4px 10px; font-size: 12px; }
.report-row-note-edit {
  margin-top: 6px;
}

/* Phase 2-3: admin 중복 병합 picker */
.report-row-merge-edit {
  margin-top: 8px;
  padding: 10px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--surface-soft);
}
.report-merge-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 8px;
}
.report-merge-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-strong);
}
.report-merge-sub {
  font-size: 11.5px;
  color: var(--text-muted);
}
.report-merge-search-row {
  display: flex;
  margin-bottom: 6px;
}
.report-merge-search-row .ps-form-input { flex: 1; min-width: 0; }
.report-merge-results {
  max-height: 220px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  display: flex; flex-direction: column;
}
.report-merge-msg {
  padding: 10px;
  font-size: 12px;
  color: var(--text-muted);
  text-align: center;
}
.report-merge-msg--err { color: #B91C1C; }
.report-merge-result {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 120ms ease;
}
.report-merge-result:last-child { border-bottom: 0; }
.report-merge-result:hover { background: var(--brand-soft); }
.report-merge-result.is-selected {
  background: var(--brand-soft);
  box-shadow: inset 3px 0 0 var(--brand);
}
.report-merge-result-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-strong);
  display: flex; gap: 6px; align-items: center;
}
.report-merge-result-type {
  font-size: 10.5px;
  font-weight: 700;
  background: var(--surface-mid);
  color: var(--text-strong);
  padding: 1px 5px;
  border-radius: 3px;
}
.report-merge-result-addr {
  font-size: 11.5px;
  color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-top: 2px;
}
.report-merge-selected {
  margin-top: 8px;
  font-size: 12px;
  background: #ECFCCB;
  border: 1px solid #BEF264;
  color: #365314;
  border-radius: 6px;
  padding: 6px 8px;
}
.report-merge-selected strong { color: #1A2E05; }
.report-merge-selected-addr {
  display: block;
  font-size: 11px;
  color: #4D7C0F;
  margin-top: 2px;
}

/* ============================================================
   Phase 3: 사용자 제보 row 확장 영역 + lightbox
   ============================================================ */
.report-row-toggle {
  background: transparent; border: 0;
  width: 22px; height: 22px;
  padding: 0; margin-right: 2px;
  font-size: 14px; color: var(--text-muted);
  cursor: pointer; border-radius: 4px;
  display: inline-flex; align-items: center; justify-content: center;
}
.report-row-toggle:hover { background: var(--brand-soft); color: var(--brand); }
.report-row.is-expanded {
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand-soft);
}

.report-row-detail {
  margin-top: 10px;
  border-top: 1px solid var(--border);
  padding-top: 10px;
  display: flex; flex-direction: column; gap: 10px;
}
.report-detail-sec {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
}
.report-detail-sec > summary {
  font-size: 12px; font-weight: 700;
  color: var(--text-strong);
  cursor: pointer;
  padding: 2px 0;
  user-select: none;
}
.report-detail-sec > summary::-webkit-details-marker { display: none; }
.report-detail-sec > summary::before {
  content: '▾';
  display: inline-block; width: 14px;
  color: var(--text-muted);
  transition: transform 120ms ease;
}
.report-detail-sec:not([open]) > summary::before { transform: rotate(-90deg); }

.report-detail-list {
  margin: 8px 0 0;
  display: grid;
  grid-template-columns: 84px 1fr;
  gap: 4px 12px;
  font-size: 12.5px;
}
.report-detail-field { display: contents; }
.report-detail-field > dt {
  color: var(--text-muted);
  font-weight: 600;
}
.report-detail-field > dd {
  margin: 0;
  color: var(--text-strong);
  word-break: break-all;
}
.report-detail-field a { color: var(--brand); text-decoration: underline; }
.report-detail-field code {
  background: rgba(15,23,42,0.06);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 11.5px;
}
.report-detail-empty {
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
  margin-top: 6px;
}

.report-detail-dup {
  margin-top: 6px;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 12px;
}
.report-detail-dup--hard {
  background: #FEE2E2;
  border: 1px solid #FCA5A5;
  color: #991B1B;
}
.report-detail-dup--soft {
  background: #FEF9C3;
  border: 1px solid #FDE68A;
  color: #854D0E;
}
.report-detail-dup-label { font-weight: 800; font-size: 12px; margin-bottom: 4px; }
.report-detail-dup-row { padding: 4px 0; border-top: 1px solid rgba(0,0,0,0.06); }
.report-detail-dup-row:first-of-type { border-top: 0; }
.report-detail-dup-name { font-weight: 700; color: var(--text-strong); }
.report-detail-dup-addr { font-size: 11.5px; color: var(--text-muted); }
.report-detail-dup-reason { font-size: 11px; opacity: 0.8; margin-top: 2px; }

/* 사진 그리드 (admin view) */
.report-detail-img-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 8px;
  margin-top: 8px;
}
.report-detail-img-tile {
  position: relative;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface);
}
.report-detail-img-tile.is-cover {
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand-soft);
}
.report-detail-img-tile.is-removing { opacity: 0.5; }
.report-detail-img-thumb {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  cursor: zoom-in;
  transition: transform 160ms ease;
}
.report-detail-img-thumb:hover { transform: scale(1.04); }
.report-detail-img-cover {
  position: absolute;
  top: 4px; left: 4px;
  background: var(--brand);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
}
.report-detail-img-remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 0;
  background: rgba(15, 23, 42, 0.78);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.report-detail-img-remove:hover { background: rgba(220, 38, 38, 0.92); }
.report-detail-img-remove:disabled {
  background: rgba(15, 23, 42, 0.4);
  cursor: not-allowed;
}

/* Lightbox — 풀스크린 이미지 보기 */
.report-img-lightbox {
  position: fixed;
  inset: 0;
  z-index: 99999;
  display: none;
  align-items: center;
  justify-content: center;
}
.report-img-lightbox.is-open { display: flex; }
.report-img-lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.88);
  cursor: zoom-out;
}
.report-img-lightbox-close {
  position: absolute;
  top: max(16px, env(safe-area-inset-top, 0px));
  right: 16px;
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
  font-size: 22px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.report-img-lightbox-close:hover { background: rgba(255, 255, 255, 0.28); }
.report-img-lightbox-img {
  position: relative;
  z-index: 1;
  max-width: 92vw;
  max-height: 86vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 24px 48px rgba(0, 0, 0, 0.6);
}

/* ============================================================
   Phase 2-5: 내 제보 관리 (.my-reports-sheet)
   ============================================================ */

/* 제보 모달 Step 1 의 진입 링크 */
.report-mylink {
  display: flex;
  justify-content: flex-end;
  margin-bottom: -4px;
}
.report-mylink-btn {
  background: transparent;
  border: 0;
  color: var(--brand);
  font-size: 12px;
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
  padding: 4px 0;
}
.report-mylink-btn:hover { color: var(--brand-hover); }

/* my-reports 시트 — 목록 */
.my-reports-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 18px 0;
}
.my-report-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.my-report-info {
  flex: 1;
  min-width: 0;
}
.my-report-name {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-strong);
  display: flex;
  gap: 6px;
  align-items: center;
}
.my-report-type {
  font-size: 10.5px;
  font-weight: 700;
  background: var(--surface-mid);
  color: var(--text-strong);
  padding: 1px 5px;
  border-radius: 3px;
}
.my-report-meta {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.my-report-time {
  font-size: 11px;
  color: var(--text-subtle);
  margin-top: 2px;
}
.my-report-member-note {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  padding: 3px 8px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 4px;
}
.my-reports-note {
  padding: 12px 18px 18px;
  font-size: 11.5px;
  color: var(--text-muted);
  line-height: 1.5;
}

/* delete form 의 대상 카드 */
.my-report-target {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 8px;
}
.my-report-target-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-strong);
}
.my-report-target-meta {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 2px;
}

/* =====================================================================
   수정 요청 (Correction report) — 자판기/문구점 상세 → 모달
   상세 액션바의 [수정 요청] 버튼은 다른 dv-action 톤을 살짝 다르게
   (경고색 hint) 줘서 일반 액션과 구분.
   ===================================================================== */
.dv-action--correction .dv-action-icon { color: #F59E0B; }
.dv-action--correction:hover { background: rgba(245, 158, 11, 0.10); }
.dv-action--correction:hover .dv-action-icon { color: #B45309; }

/* 시트 자체는 profile-sheet 셀을 그대로 재사용 — 추가 색만 살짝 */
.correction-sheet .ps-card { max-width: 480px; }

.cr-section {
  padding: 6px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.cr-place {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
}
.cr-place-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-strong);
}
.cr-place-addr {
  font-size: 12.5px;
  color: var(--text-muted);
  margin-top: 2px;
  word-break: break-all;
}

.cr-block-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-strong);
  margin-bottom: 8px;
}
.cr-required { color: #DC2626; font-weight: 700; }

.cr-check-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cr-check {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}
.cr-check:hover { background: var(--surface-soft); }
.cr-check.is-on {
  border-color: var(--brand);
  background: rgba(99, 102, 241, 0.06);
}
.cr-check input { position: absolute; opacity: 0; pointer-events: none; }
.cr-check-box {
  width: 20px; height: 20px;
  border-radius: 6px;
  border: 1.5px solid var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  background: var(--surface);
  flex: 0 0 auto;
  transition: background 120ms ease, border-color 120ms ease;
}
.cr-check.is-on .cr-check-box {
  background: var(--brand);
  border-color: var(--brand);
}
.cr-check-label {
  font-size: 14px;
  color: var(--text-strong);
  font-weight: 600;
}

.cr-field { display: flex; flex-direction: column; gap: 6px; }
.cr-field-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
}
.cr-input, .cr-textarea {
  font: inherit;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text-strong);
  outline: none;
  width: 100%;
  box-sizing: border-box;
  transition: border-color 120ms ease, background 120ms ease;
}
.cr-textarea { resize: vertical; min-height: 64px; }
.cr-input:focus, .cr-textarea:focus { border-color: var(--brand); background: var(--surface); }

.cr-error {
  background: rgba(220, 38, 38, 0.10);
  border: 1px solid rgba(220, 38, 38, 0.30);
  border-radius: 8px;
  padding: 8px 12px;
  color: #B91C1C;
  font-size: 12.5px;
}

.cr-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}

@media (max-width: 768px) {
  .correction-sheet .ps-card { max-width: 100%; }
  .cr-section { padding: 6px 16px 18px; }
  .cr-actions .ps-btn { flex: 1; }
}

/* =====================================================================
   Admin 수정 요청 탭 — row 카드
   ===================================================================== */
.cr-row {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
  background: var(--surface);
}
.cr-row-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.cr-row-head-left {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.cr-row-type {
  font-size: 11.5px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  color: var(--text-strong);
}
.cr-row-kind {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-strong);
}
.cr-row-status {
  font-size: 11px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text-strong);
}
.cr-row-status--pending  { background: #FEF3C7; color: #92400E; border-color: #FCD34D; }
.cr-row-status--reviewed { background: #DBEAFE; color: #1E3A8A; border-color: #93C5FD; }
.cr-row-status--resolved { background: #DCFCE7; color: #14532D; border-color: #86EFAC; }
.cr-row-status--rejected { background: #FEE2E2; color: #7F1D1D; border-color: #FCA5A5; }

.cr-row-time { font-size: 11.5px; color: var(--text-muted); }

.cr-row-body { display: flex; flex-direction: column; gap: 6px; }
.cr-row-place {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
}
.cr-row-place-name {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-strong);
}
.cr-row-place-addr {
  font-size: 11.5px;
  color: var(--text-muted);
  margin-top: 2px;
}
.cr-row-tag {
  display: inline-block;
  margin-top: 6px;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 700;
}
.cr-row-tag--warn { background: #FEF3C7; color: #92400E; border: 1px solid #FCD34D; }

.cr-row-line {
  display: flex;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-strong);
}
.cr-row-line--admin { color: #1E3A8A; }
.cr-row-label {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  min-width: 60px;
}
.cr-row-reporter { font-weight: 600; }
.cr-row-reporter--guest { color: var(--text-muted); }

.cr-row-note-editor {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
}
.cr-row-note-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
}

.cr-row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
}
.cr-row-actions .ps-btn {
  font-size: 12px;
  padding: 6px 12px;
}

/* =====================================================================
   개발자 후원 / 제휴 — 사이트 정보 모달 / FEEDBACK 시트 / 내정보 sub-view
   모두 동일한 .donate-btn 톤. 포카맵 브랜드 액센트 = 노랑(--accent-yellow)
   배경 + 다크 잉크(#0F172A) 테두리/텍스트. 자판기 핀과 같은 컬러 계열.
   ===================================================================== */
.donate-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 22px;
  min-height: 48px;
  border-radius: 14px;
  border: 1.5px solid #0F172A;           /* 진한 잉크 — 자판기/공식 핀 라인 톤 */
  background: var(--accent-yellow);      /* #FACC15 — 포카맵 브랜드 노랑 */
  color: #0F172A;
  font-family: var(--f-sans);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  box-sizing: border-box;
  transition: background 140ms ease, border-color 140ms ease, transform 100ms ease, box-shadow 140ms ease;
}
.donate-btn:hover,
.donate-btn:focus-visible {
  background: #EAB308;                   /* yellow-500 — 한 톤 진하게 */
  border-color: #000000;
  color: #0F172A;
  box-shadow: 0 1px 0 rgba(15, 23, 42, 0.06), 0 4px 14px rgba(15, 23, 42, 0.12);
}
.donate-btn:active { transform: translateY(1px); }
.donate-btn-icon {
  display: inline-flex;
  width: 18px;
  height: 18px;
  color: #0F172A;                        /* 아이콘도 동일 잉크 */
  flex: 0 0 auto;
}
.donate-btn-icon svg { width: 18px; height: 18px; display: block; stroke-width: 2.2; }
.donate-btn-label { white-space: nowrap; }

/* ---- Surface-specific spacing ---- */

/* 사이트 정보 모달 — 제휴 문의 행 + 후원 버튼 */
.si-contact .si-contact-row {
  margin: 6px 0 12px;
  font-size: 14px;
}
.si-contact .si-contact-email {
  font-family: var(--f-mono, monospace);
  font-size: 13.5px;
}
.si-donate-row {
  margin-top: 4px;
  display: flex;
  justify-content: center;
}

/* FEEDBACK 시트 — 후원 버튼은 이메일 아래 한 박자 간격 두고 풀폭. */
.fb-donate-row {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
  display: flex;
  justify-content: center;
}
.fb-donate-row .donate-btn {
  width: 100%;
  max-width: 320px;
  justify-content: center;
}

/* 내정보 sub-view — 메뉴 항목과 통일된 패딩 + 리드 텍스트 */
.ps-donate-view { gap: 12px; }
.ps-donate-lead {
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-muted);
}
.ps-donate-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-soft);
}
.ps-donate-label {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.ps-donate-email {
  font-family: var(--f-mono, monospace);
  font-size: 13.5px;
  color: var(--text-strong);
  text-decoration: none;
  word-break: break-all;
}
.ps-donate-email:hover { color: var(--brand); }
.ps-donate-cta {
  display: flex;
  justify-content: center;
}
.ps-donate-cta .donate-btn {
  width: 100%;
  justify-content: center;
}

@media (max-width: 768px) {
  .donate-btn { font-size: 14px; padding: 13px 20px; min-height: 50px; }
}

/* =====================================================================
   포카톡 (Community) — Phase C-1
   - body[data-route="community"] 일 때만 .cm-root 노출, 그 외 시 hide.
   - map-shell / map-rail / map-fab 등 지도 chrome 은 community 진입 시 안 보임.
   - 모든 클래스는 .cm- prefix 로 격리 (기존 컴포넌트와 충돌 X).
   ===================================================================== */

/* 기본 — community-root 는 항상 DOM 에 있지만 hidden. */
.cm-root {
  display: none;
  position: fixed;
  inset: 0;
  background: #F8FAFC;                         /* slate-50 — 연한 회색 톤. 중앙 main 박스가 흰색이라 대비 */
  z-index: 100;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  font-family: var(--f-sans);
  color: var(--text-strong);
  /* iOS safe area */
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* community 라우트 진입 시 cm-root 만 위에 띄움. 지도는 그 아래에 그대로 살아
   있게 둠 — Naver Maps SDK 는 display:none 상태에서 dimension 0 으로 깨지면서
   재진입 시 mock 으로 fallback 되거나 "네이버 지도 연결 실패" 배너로 바뀌는
   문제가 있어 z-index stacking 으로 해결. cm-root 가 viewport 를 덮으므로 시각
   적으로는 동일.
   - .map-shell display 그대로 → SDK alive
   - cm-root z-index 100 + opaque background → 지도 시각 차단
   - 모바일 하단 nav 는 cm-root bottom: 64px 로 노출 유지 (이미 적용됨) */
body[data-route="community"] .cm-root   { display: block; }
body[data-route="community"] .map-fab,
body[data-route="community"] .biz-onboard-banner,
body[data-route="community"] .bob-close-extern {
  /* 시각만 차단 (display:none 안 씀 — 다시 보일 때 layout race 방지) */
  visibility: hidden !important;
  pointer-events: none !important;
}
/* 모바일 하단 nav 는 community 안에서도 유지 — 다른 탭으로 이동 가능. */

/* 데스크탑: rail (좌측 카테고리) 은 community 안에서도 유지. 그래야 "지도로
   돌아가기" 가 한 번에 가능. cm-root 의 left 만 rail 폭만큼 띄움. */
@media (min-width: 769px) {
  body[data-route="community"] .cm-root {
    left: var(--rail-w, 80px);
  }
}

/* 모바일: 하단 nav 공간 비워두기.
   --mobile-cat-bar-h 는 JS 가 측정한 nav 의 getBoundingClientRect().height —
   이미 padding-bottom (safe-area-inset-bottom 포함) 까지 포함된 실측값.
   따라서 별도로 env(safe-area-inset-bottom) 더하면 중복 → 하단에 흰 여백 발생.
   fallback 64px 만 PWA standalone 모드에서 부족할 수 있어 max() 로 보호. */
@media (max-width: 768px) {
  body[data-route="community"] .cm-root {
    bottom: var(--mobile-cat-bar-h, 64px);
  }
}

/* ----- 3-column 데스크탑 레이아웃 ----- */
/* 데스크탑: 좌측 광고/랭킹 (placeholder) + 중앙 본문 + 우측 광고 (placeholder).
   현재는 양옆 비어있음 — 빈 칸이 시각적 노이즈 안 되도록 background 만 회색.
   모바일/태블릿(<1024px) 은 단일 column. */
.cm-layout {
  max-width: 1500px;
  margin: 0 auto;
  padding: 0;
}
.cm-main {
  background: var(--surface, #FFFFFF);
  min-height: calc(100vh - 60px);              /* 헤더 높이 빼고 채우기 */
}
.cm-side { display: none; }                    /* 모바일 default — hide */

@media (min-width: 1024px) {
  .cm-layout {
    display: grid;
    grid-template-columns: minmax(200px, 280px) minmax(640px, 860px) minmax(200px, 280px);
    gap: 20px;
    padding: 16px 20px 32px;
    align-items: start;
  }
  .cm-side {
    display: block;
    min-height: 200px;
    /* placeholder — 광고 추가 전엔 빈 공간이라 background 도 줄임 */
    position: sticky;
    top: 76px;
  }
  .cm-main {
    border-radius: 12px;
    border: 1px solid var(--border);
    overflow: hidden;
    min-height: 70vh;
  }
}

/* 데스크탑에서 topbar 가 cm-layout 바깥에 있음 — 전체폭 sticky 유지 */
@media (min-width: 1024px) {
  .cm-root .cm-topbar {
    background: #FFFFFF;
    border-bottom: 1px solid var(--border);
  }
}

/* ----- 헤더 ----- */
.cm-topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 14px 16px 10px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.cm-topbar-left  { display: flex; align-items: center; gap: 8px; min-width: 0; }
.cm-topbar-right { display: flex; align-items: center; gap: 4px; }
.cm-title {
  margin: 0;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.cm-icon-btn {
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 10px;
  color: var(--text-strong);
  cursor: pointer;
  transition: background 120ms ease;
}
.cm-icon-btn:hover { background: var(--surface-soft); }

/* ----- 카테고리 chip row ----- */
.cm-chips {
  display: flex;
  gap: 6px;
  padding: 10px 16px 6px;
  overflow-x: auto;
  scrollbar-width: none;
}
.cm-chips::-webkit-scrollbar { display: none; }
.cm-chip {
  flex-shrink: 0;
  padding: 7px 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-strong);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.cm-chip:hover { background: var(--surface-soft); }
.cm-chip.is-on {
  background: var(--brand);
  color: #fff;
  border-color: var(--brand);
}

/* ----- 정렬 ----- */
.cm-sortbar {
  display: flex;
  gap: 12px;
  padding: 4px 16px 10px;
  border-bottom: 1px solid var(--border);
}
.cm-sort {
  background: transparent;
  border: 0;
  font-size: 12.5px;
  color: var(--text-muted);
  font-weight: 600;
  padding: 4px 2px;
  cursor: pointer;
}
.cm-sort.is-on {
  color: var(--text-strong);
  border-bottom: 2px solid var(--brand);
}

/* ----- 게시글 카드 리스트 ----- */
.cm-list {
  padding: 4px 16px 80px;
  display: flex;
  flex-direction: column;
}
@media (min-width: 1024px) {
  .cm-list { padding: 8px 20px 32px; }
}

.cm-card {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
  padding: 14px 4px;
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.cm-card:hover { background: var(--surface-soft); }
.cm-card.is-notice { background: rgba(250, 204, 21, 0.06); }
.cm-card.is-notice:hover { background: rgba(250, 204, 21, 0.10); }

.cm-card-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}
.cm-badge {
  font-size: 11px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  color: var(--text-strong);
}
.cm-badge--notice {
  background: var(--accent-yellow);
  color: #0F172A;
  border-color: #0F172A;
}
.cm-card-time { font-size: 11.5px; color: var(--text-muted); margin-left: auto; }

.cm-card-body {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.cm-card-text { flex: 1; min-width: 0; }
.cm-card-thumb {
  flex: 0 0 80px;
  width: 80px;
  height: 80px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-soft);
}
.cm-card-thumb img { width: 100%; height: 100%; object-fit: cover; }

.cm-card-title {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--text-strong);
  /* 1줄 ellipsis */
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.cm-card-excerpt {
  margin: 0 0 8px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-muted);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.cm-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 6px;                /* body 와 분리 — foot 이 카드 전체 너비로 떨어져 나옴 */
  font-size: 11.5px;
  color: var(--text-muted);
}
.cm-card-author { font-weight: 600; }
.cm-card-stats { display: inline-flex; gap: 10px; align-items: center; }
.cm-card-stats > span { display: inline-flex; align-items: center; gap: 3px; }
.cm-card-stats svg { width: 14px; height: 14px; }

.cm-more { padding: 12px 4px 24px; text-align: center; }

/* 거래 금지 안내문 — 글쓰기 화면 카테고리 선택 바로 아래 노출.
   강한 경고보다 운영 정책을 차분히 알리는 톤. */
.cm-trade-disclaimer {
  margin: -4px 0 12px;
  padding: 10px 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: #475569;
  background: #f8fafc;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent-cyan, #06b6d4);
  border-radius: 6px;
}

/* 페이지네이션 — 1, 2, 3 ... 버튼 */
.cm-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 20px 4px 24px;
  flex-wrap: wrap;
}
.cm-page-btn {
  min-width: 34px;
  height: 34px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: transparent;
  color: var(--text-strong);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 100ms ease, border-color 100ms ease;
}
.cm-page-btn:hover:not(:disabled):not(.is-current) {
  background: var(--surface-soft);
  border-color: var(--text-muted);
}
.cm-page-btn.is-current {
  background: var(--accent-yellow);
  border-color: #0F172A;
  color: #0F172A;
  cursor: default;
}
.cm-page-btn:disabled,
.cm-page-btn.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.cm-page-ellipsis {
  padding: 0 4px;
  color: var(--text-muted);
  font-size: 13px;
  user-select: none;
}
/* 데스크탑에서 FAB 가 페이지네이션 우측 끝 가리지 않게 우측 padding 보강 */
@media (min-width: 1280px) {
  .cm-pagination { padding-right: 80px; }
}

/* ----- 빈 상태 ----- */
.cm-empty {
  padding: 48px 24px;
  text-align: center;
  color: var(--text-muted);
  font-size: 13px;
}
.cm-empty--inline { padding: 24px 0; }
.cm-empty-title { font-size: 14px; font-weight: 700; color: var(--text-strong); margin-bottom: 4px; }
.cm-empty-sub   { font-size: 12.5px; color: var(--text-muted); }

/* ----- FAB (글쓰기) ----- */
.cm-fab {
  position: fixed;
  right: 18px;
  /* 기본 (지도 화면일 때 — 사실 community 가 아니면 cm-fab 자체가 안 그려짐).
     community route 에선 아래 모바일 mq 에서 cat-bar 높이 + safe-area 로 override. */
  bottom: calc(var(--mobile-overlay-bottom, 80px) + 12px);
  z-index: 50;
  height: 48px;
  padding: 0 18px;
  border-radius: 999px;
  border: 1.5px solid #0F172A;
  background: var(--accent-yellow);
  color: #0F172A;
  font-size: 14px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(15, 23, 42, 0.15);
  transition: transform 100ms ease, box-shadow 140ms ease;
}
.cm-fab:hover { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(15, 23, 42, 0.22); }
.cm-fab:active { transform: translateY(0); }
.cm-fab svg { width: 18px; height: 18px; }
@media (min-width: 769px) {
  .cm-fab { right: 32px; bottom: 32px; }
}
/* 데스크탑 3-column 영역에 맞춰서 중앙 column 우측 끝 근처에 위치.
   center column 최대폭 860px, layout 최대폭 1500px. 50vw 중심에서 한쪽 폭 430.
   FAB 오른쪽 정렬: viewport center + 430(center half) - 32(여백) 까지가 center column
   오른쪽 끝. 거기서 24px 안쪽으로. 너무 좁은 viewport 에서는 max() 로 32px 보장. */
@media (min-width: 1280px) {
  .cm-fab {
    right: max(32px, calc(50vw - 430px + 32px));
    bottom: 40px;
  }
}

/* ====================================================================
   모바일 포카톡 보강 — FAB / 안내 박스 / 리스트 compact / 광고 슬롯
   ==================================================================== */

/* 모바일: FAB 를 mobile bottom nav (--mobile-cat-bar-h, JS 가 측정한 실측값으로
   safe-area-inset-bottom 이미 포함) + AdSense bottom bar (--mobile-ad-h,
   채워졌을 때 ~66px) 위로 띄움.
   광고 미충원 시 --mobile-ad-h = 0px 라서 기존 위치 유지 (회귀 없음).
   env(safe-area-inset-bottom) 별도로 더하지 않음 — --mobile-cat-bar-h 에 이미 포함. */
@media (max-width: 768px) {
  body[data-route="community"] .cm-fab {
    bottom: calc(var(--mobile-cat-bar-h, 64px) + var(--mobile-ad-h, 0px) + 16px);
    right: 16px;
  }
  /* 리스트 마지막 글 / 페이지네이션이 FAB·하단 nav·광고 에 가리지 않게 충분한 padding */
  body[data-route="community"] .cm-list {
    padding-bottom: calc(var(--mobile-cat-bar-h, 64px) + var(--mobile-ad-h, 0px) + 80px);
  }
}

/* 비회원 안내 박스 — 모바일에서 너무 큰 카드 같아 보이지 않게 축소.
   텍스트 + [로그인/회원가입] 버튼을 같은 행에 붙임. */
@media (max-width: 768px) {
  .cm-login-banner {
    padding: 8px 10px;
    gap: 8px;
    border-radius: 10px;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
  }
  .cm-login-banner p {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.35;
    flex: 1 1 auto;
    min-width: 0;
  }
  .cm-login-banner .cm-btn--sm {
    flex: 0 0 auto;
    white-space: nowrap;
  }
  .cm-btn--sm { font-size: 12px; padding: 6px 10px; min-height: 30px; }
}

/* 글 카드 compact — 모바일 한 화면에 더 많이 보이게 */
@media (max-width: 768px) {
  .cm-card {
    padding: 10px 6px;
  }
  .cm-card-meta {
    margin-bottom: 4px;
    gap: 4px;
  }
  .cm-card-title {
    font-size: 14px;
    margin-bottom: 2px;
    -webkit-line-clamp: 1;
  }
  .cm-card-excerpt { display: none; }           /* 본문 미리보기 모바일 숨김 */
  .cm-card-body {
    gap: 8px;
    align-items: flex-start;                    /* 썸네일 + 제목 모두 상단 정렬 → 시각적으로 위에 붙음 */
  }
  .cm-card-thumb {
    flex: 0 0 56px;
    width: 56px;
    height: 56px;
    border-radius: 6px;
  }
  .cm-card-foot {
    font-size: 11px;
    margin-top: 4px;                            /* 모바일은 살짝만 띄움 */
  }
  .cm-card-stats { gap: 8px; }
  /* 모바일에서는 meta 안의 time 만 표시 (foot 안의 데스크탑용 time 은 숨김) */
  .cm-card-time--desktop { display: none; }
}

/* ===== 데스크탑 compact (≥769px) — 게시판 리스트 형태로 row 높이 축소 =====
   목표: 빈 글 row ~80px, 썸네일 있는 row ~96px. 한 화면에 더 많이.
   - padding/margin 축소
   - 제목 1줄, 본문 preview 1줄
   - 썸네일 64×64
   - meta 한 줄 (카테고리 badge 만), 시간/통계는 foot 한 줄에 합침
*/
@media (min-width: 769px) {
  .cm-list {
    padding: 0 20px 24px;
    gap: 0;                        /* row 간격은 border-bottom 으로 */
  }
  .cm-card {
    padding: 10px 8px;             /* 14px 4px → 10px 8px */
  }
  .cm-card-meta {
    margin-bottom: 4px;            /* 6px → 4px */
    gap: 6px;
  }
  /* 데스크탑에서는 meta 의 time 을 숨기고, foot 안의 time--desktop 으로 한 줄 정리 */
  .cm-card-time--mobile { display: none; }
  .cm-badge {
    font-size: 10.5px;             /* 11px → 10.5px (compact) */
    padding: 1px 7px;
  }
  .cm-card-body {
    gap: 12px;
    align-items: center;           /* 썸네일이 작아도 vertically center */
  }
  .cm-card-title {
    font-size: 14.5px;             /* 15px → 14.5px */
    margin-bottom: 2px;
    line-height: 1.3;
    -webkit-line-clamp: 1;         /* 데스크탑도 1줄 */
  }
  .cm-card-excerpt {
    font-size: 12px;
    margin-bottom: 4px;            /* 8px → 4px */
    -webkit-line-clamp: 1;         /* 데스크탑도 1줄 */
    line-height: 1.4;
  }
  .cm-card-thumb {
    flex: 0 0 64px;                /* 80px → 64px */
    width: 64px;
    height: 64px;
    border-radius: 6px;
  }
  .cm-card-foot {
    font-size: 11.5px;
    gap: 8px;
    margin-top: 2px;               /* 데스크탑 compact — body 와 거의 붙임 */
    justify-content: flex-start;   /* author / stats / time 순서대로 한 줄 */
  }
  .cm-card-author { flex: 0 0 auto; }
  .cm-card-stats { gap: 10px; }
  .cm-card-time--desktop {
    margin-left: auto;             /* 우측 끝 */
    color: var(--text-muted);
    white-space: nowrap;
  }
}

/* 광고 슬롯 (.cm-ad-slot) — 6개 글마다 들어가는 wrapper. 광고 채워지지
   않으면 hidden — 빈 회색 박스 X. 향후 AdSense <ins> 추가 시 height auto. */
.cm-ad-slot { display: none; }
.cm-ad-slot.ad-slot--filled {
  display: block;
  margin: 8px 0;
  border-radius: 8px;
  overflow: hidden;
}

/* ----- 상세 ----- */
.cm-detail {
  padding: 16px 18px 0;
  /* .cm-main 안에 들어가므로 max-width 제거 — 부모 column 폭에 맞춤 */
}
.cm-detail-head { padding-bottom: 14px; border-bottom: 1px solid var(--border); }
.cm-detail-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.cm-detail-time { font-size: 11.5px; color: var(--text-muted); margin-left: auto; }
.cm-detail-title {
  margin: 0 0 10px;
  font-size: 22px;
  line-height: 1.3;
  font-weight: 800;
  color: var(--text-strong);
}
.cm-detail-sub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12.5px;
  color: var(--text-muted);
}
.cm-detail-stats { display: inline-flex; gap: 12px; }
.cm-detail-stats > span { display: inline-flex; align-items: center; gap: 4px; }
.cm-detail-stats svg { width: 14px; height: 14px; }

.cm-detail-body {
  padding: 18px 0;
  font-size: 15px;
  line-height: 1.7;
  color: var(--text-strong);
  white-space: normal;
  word-wrap: break-word;
}

.cm-detail-actions {
  display: flex;
  gap: 8px;
  padding: 8px 0 18px;
  border-top: 1px dashed var(--border);
  padding-top: 14px;
}

/* ----- 댓글 ----- */
.cm-comments {
  padding: 18px 18px 80px;
  border-top: 6px solid var(--surface-soft);
}
.cm-comments-title { font-size: 15px; font-weight: 700; margin: 0 0 12px; }
.cm-comment-list { display: flex; flex-direction: column; gap: 0; }
.cm-comment {
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}
.cm-comment.is-reply {
  margin-left: 24px;
  padding-left: 12px;
  border-left: 2px solid var(--brand-soft, #DBEAFE);
  /* 회색 배경으로 댓글과 시각 구분 강화 */
  background: rgba(15, 23, 42, 0.025);
  border-radius: 0 6px 6px 0;
}
.cm-comment-replies { margin-top: 8px; }

/* ↳ 화살표 — 대댓글 head 앞에 작게 */
.cm-reply-arrow {
  font-size: 13px;
  color: var(--text-muted);
  margin-right: 2px;
}

/* 답글 모드 배너 — 메인 댓글 박스 상단에 노란색으로 명확히 표시.
   "@닉네임 에게 답글 작성 중" + 우측 X 버튼으로 즉시 일반 모드 복귀.
   (Instagram/Threads 패턴) */
.cm-reply-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px 8px 12px;
  margin-bottom: 10px;
  background: rgba(250, 204, 21, 0.18);
  border: 1px solid var(--accent-yellow);
  border-radius: 8px;
  font-size: 13px;
  color: #0F172A;
}
.cm-reply-banner-icon  { font-size: 14px; }
.cm-reply-banner-text  { flex: 1; line-height: 1.4; }
.cm-reply-banner-text strong { color: #0F172A; font-weight: 700; }
.cm-reply-banner-close {
  flex: 0 0 auto;
  width: 24px; height: 24px;
  background: transparent;
  border: 0;
  border-radius: 50%;
  font-size: 18px;
  line-height: 1;
  color: #0F172A;
  cursor: pointer;
  transition: background 100ms ease;
}
.cm-reply-banner-close:hover { background: rgba(15, 23, 42, 0.08); }

/* 답글 작성 대상 댓글 — 시각 단서 (좌측 노란 라인) */
.cm-comment.is-reply-target {
  background: rgba(250, 204, 21, 0.06);
  border-left: 3px solid var(--accent-yellow);
  padding-left: 9px;          /* border 두께만큼 보정 */
  margin-left: -12px;          /* 들여쓰기 보정 */
  padding-right: 4px;
  border-radius: 0 6px 6px 0;
}
/* 대댓글에서 답글 대상이면 두 가지 모두 적용 (cyan + yellow 우측 강조) */
.cm-comment.is-reply.is-reply-target {
  margin-left: 24px;
  border-left: 3px solid var(--accent-yellow);
}

.cm-compose-actions {
  display: flex; gap: 6px; align-items: center;
}

/* 댓글/답글 더 보기 버튼 — 작고 muted 한 톤 */
.cm-more-comments,
.cm-more-replies {
  display: block;
  width: 100%;
  padding: 8px 12px;
  margin: 8px 0;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 6px;
  color: var(--text-muted);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease, border-color 100ms ease;
}
.cm-more-comments:hover,
.cm-more-replies:hover {
  background: var(--surface-soft);
  color: var(--text-strong);
  border-color: var(--text-muted);
}
.cm-more-replies {
  margin-left: 24px;        /* 답글 들여쓰기와 정렬 */
  font-size: 12px;
}

/* === 포카맵 (pc-*) — 대댓글/더 보기 시각 구분 === */
.pc-item--reply {
  margin-left: 24px;
  padding-left: 12px;
  border-left: 2px solid var(--brand-soft, #DBEAFE);
  background: rgba(15, 23, 42, 0.025);
  border-radius: 0 6px 6px 0;
}
.pc-reply-mention {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-right: 6px;
  font-size: 11.5px;
  color: var(--text-muted);
}
.pc-reply-arrow { font-size: 12px; color: var(--text-muted); }
.pc-mention {
  font-weight: 600;
  color: var(--accent-cyan, #06b6d4);
}
/* 포카톡 대댓글 헤더의 @멘션 — 동일 스타일 */
.cm-mention {
  font-weight: 600;
  font-size: 12.5px;
  color: var(--accent-cyan, #06b6d4);
  margin-right: 2px;
}
.pc-more-comments,
.pc-more-replies {
  display: block;
  width: 100%;
  padding: 8px 12px;
  margin: 8px 0;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 6px;
  color: var(--text-muted);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.pc-more-comments:hover,
.pc-more-replies:hover {
  background: var(--surface-soft);
  color: var(--text-strong);
  border-color: var(--text-muted);
}
.pc-more-replies {
  margin-left: 24px;
  font-size: 12px;
}
.cm-comment-head {
  display: flex; gap: 8px; align-items: center;
  margin-bottom: 4px;
}
.cm-comment-author { font-size: 12.5px; font-weight: 700; color: var(--text-strong); }
.cm-comment-time   { font-size: 11px; color: var(--text-muted); }
.cm-comment-body {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text-strong);
  margin-bottom: 6px;
  word-wrap: break-word;
}
.cm-comment-actions {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}
.cm-comment-action {
  background: transparent;
  border: 0;
  font-size: 11.5px;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px 2px;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-weight: 600;
}
.cm-comment-action:hover { color: var(--text-strong); }
.cm-comment-action.is-on { color: var(--brand); }
.cm-comment-action--danger { color: #B91C1C; }
.cm-comment-action--danger:hover { color: #DC2626; }
.cm-comment-action svg { width: 12px; height: 12px; }

.cm-comment-compose {
  margin-top: 16px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-soft);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cm-reply-hint {
  font-size: 11.5px;
  color: var(--brand);
  font-weight: 600;
}
.cm-link {
  background: transparent;
  border: 0;
  color: var(--brand);
  cursor: pointer;
  font: inherit;
  padding: 0;
  text-decoration: underline;
}

/* ----- 입력 공통 ----- */
.cm-input, .cm-textarea {
  font: inherit;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text-strong);
  outline: none;
  box-sizing: border-box;
  transition: border-color 120ms ease;
}
.cm-textarea { resize: vertical; min-height: 64px; }
.cm-input:focus, .cm-textarea:focus { border-color: var(--brand); }

.cm-guest-row {
  display: flex;
  gap: 8px;
}
.cm-guest-row .cm-input { flex: 1; }

/* ----- 글쓰기 form ----- */
.cm-compose {
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.cm-field { display: flex; flex-direction: column; gap: 6px; }
.cm-field-label {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.cm-compose-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 4px;
}

.cm-error {
  padding: 8px 12px;
  border: 1px solid rgba(220, 38, 38, 0.30);
  background: rgba(220, 38, 38, 0.08);
  border-radius: 8px;
  color: #B91C1C;
  font-size: 12.5px;
}

/* ----- 버튼 ----- */
.cm-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 16px;
  border-radius: 8px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.cm-btn--primary {
  background: var(--accent-yellow);
  color: #0F172A;
  border-color: #0F172A;
}
.cm-btn--primary:hover { background: #EAB308; }
.cm-btn--primary:disabled { opacity: 0.6; cursor: not-allowed; }
.cm-btn--ghost {
  background: transparent;
  color: var(--text-strong);
  border-color: var(--border);
}
.cm-btn--ghost:hover { background: var(--surface-soft); }
.cm-btn--liked {
  background: var(--brand-soft, #DBEAFE);
  color: var(--brand);
  border-color: var(--brand);
}
.cm-btn--danger {
  background: transparent;
  color: #B91C1C;
  border-color: rgba(220, 38, 38, 0.30);
}
.cm-btn--danger:hover { background: rgba(220, 38, 38, 0.06); }
.cm-btn svg { width: 16px; height: 16px; }
.cm-count { font-weight: 600; }

/* ----- rail community entry ----- */
.rail-community .rail-icon { color: var(--brand); }
.rail-community.active .rail-icon { color: var(--brand); }

/* ----- mobile bottom nav: 4-column 균등 ----- */
@media (max-width: 768px) {
  .mobile-cat-bar .mcb-item { flex: 1; }
}

/* =====================================================================
   알림 — 빨간 점 badge + 리스트 UI + 댓글 highlight
   ===================================================================== */

/* unread 점 — 내정보 진입 버튼 (rail / mobile nav) + 프로필 시트 안 알림 entry.
   position 기반 — 호스트 element 가 position:relative 여야 함. .ps-list-item /
   .ps-quick-item / .mcb-item / .rail-item 모두 이미 그 조건이거나 자식 layout
   이라 안전. 부정확하면 안에 별도 .has-noti-dot 정렬 컨테이너 추가 가능. */
.has-noti-dot { position: relative; }
.has-noti-dot::after {
  content: '';
  position: absolute;
  top: 6px;
  right: 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #DC2626;
  box-shadow: 0 0 0 2px var(--surface, #fff);
  pointer-events: none;
}
/* mobile bottom nav 의 mcb-item 은 폭이 좁아 우측 정렬을 살짝 보정 */
.mcb-item.has-noti-dot::after { top: 6px; right: calc(50% - 16px); }
.rail-item.has-noti-dot::after { top: 6px; right: 10px; }

/* 알림 리스트 view (프로필 sub-view 안) */
.cm-noti-view {
  padding: 8px 0 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cm-noti-tabs {
  display: flex;
  gap: 6px;
  padding: 4px 18px 8px;
  border-bottom: 1px solid var(--border);
}
.cm-noti-tab {
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-muted);
  padding: 8px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.cm-noti-tab:hover { background: var(--surface-soft); color: var(--text-strong); }
.cm-noti-tab.is-on { background: var(--text-strong); color: #fff; }

.cm-noti-list { padding: 0 14px; display: flex; flex-direction: column; }

.cm-noti-row {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 10px;
  padding: 12px 6px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 120ms ease;
}
.cm-noti-row:hover { background: var(--surface-soft); }
.cm-noti-row.is-unread { background: rgba(250, 204, 21, 0.06); }
.cm-noti-row.is-unread:hover { background: rgba(250, 204, 21, 0.10); }

.cm-noti-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  margin-top: 2px;
  color: #fff;
}
.cm-noti-icon--like       { background: #EC4899; }     /* pink-500 */
.cm-noti-icon--reply      { background: #2563EB; }     /* blue-600 */
.cm-noti-icon--correction { background: #10B981; }     /* emerald-500 — 제보 처리 */

.cm-noti-body { min-width: 0; }
.cm-noti-head {
  display: flex;
  align-items: baseline;
  gap: 4px;
  flex-wrap: wrap;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-strong);
}
.cm-noti-actor  { font-weight: 700; }
/* 포카맵 장소 댓글 알림에서 장소 이름 강조 — 작은 배지 톤 */
.cm-noti-place {
  display: inline-block;
  padding: 0 6px;
  margin-right: 2px;
  font-size: 11px;
  font-weight: 700;
  color: var(--accent-cyan, #06b6d4);
  background: rgba(6, 182, 212, 0.08);
  border-radius: 4px;
  vertical-align: 1px;
}
.cm-noti-action { color: var(--text-strong); }
.cm-noti-time   { font-size: 11px; color: var(--text-muted); margin-left: auto; }

/* 좋아요 알림: 내 글/댓글 일부 — 살짝 들여쓰기 한 회색 박스 */
.cm-noti-target {
  margin-top: 4px;
  font-size: 12.5px;
  color: var(--text-muted);
  background: var(--surface-soft);
  border-radius: 8px;
  padding: 6px 10px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* 답글 알림: 원문 인용 (회색) — 좌측 라인 */
.cm-noti-target--quoted {
  border-left: 3px solid var(--border);
  background: transparent;
  padding: 2px 0 2px 10px;
  border-radius: 0;
}
/* 답글 본문 (검정) */
.cm-noti-reply {
  margin-top: 4px;
  font-size: 13px;
  color: var(--text-strong);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 댓글 highlight — 알림 클릭으로 들어왔을 때 잠깐 강조 */
.cm-comment.cm-comment-highlight {
  background: rgba(250, 204, 21, 0.18);
  border-radius: 8px;
  outline: 2px solid #FACC15;
  outline-offset: 2px;
  animation: cmHighlightFade 2.4s ease-out forwards;
}
@keyframes cmHighlightFade {
  0%   { background: rgba(250, 204, 21, 0.28); }
  60%  { background: rgba(250, 204, 21, 0.18); }
  100% { background: transparent; outline-color: transparent; }
}

/* =====================================================================
   비회원 작성 안내 / 랜덤 닉 / 글자수 카운터 — 장소 댓글과 동일 톤
   ===================================================================== */

/* 로그인 안내 박스 (비회원 only) */
.cm-login-banner {
  background: #F8FAFC;                         /* slate-50 */
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.cm-login-banner p {
  margin: 0;
  font-size: 13px;
  color: var(--text-strong);
  line-height: 1.5;
  flex: 1 1 240px;
}

/* small primary 버튼 — 안내 박스 안의 [로그인/회원가입] */
.cm-btn--sm {
  font-size: 12.5px;
  padding: 8px 14px;
  min-height: 36px;
}

/* 랜덤 닉네임 버튼 — 닉네임 input 과 비번 input 사이의 작은 정사각 버튼 */
.cm-random {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 8px;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.cm-random:hover {
  background: var(--surface-soft);
  color: var(--text-strong);
}
.cm-random svg { width: 18px; height: 18px; display: block; }

/* guest row 의 닉네임/비번 input 들 — 랜덤 버튼 사이에 끼게 flex */
.cm-guest-row { align-items: stretch; }

/* compose 폼 하단 — 도움말/카운터 + 등록 버튼 */
.cm-compose-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 4px;
}
.cm-compose-foot-left {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: wrap;
}
.cm-compose-foot--inline {           /* 글쓰기 본문 textarea 바로 아래 — 카운터만 */
  justify-content: flex-end;
  margin-top: 2px;
}

.cm-helper-text {
  font-size: 11.5px;
  color: var(--text-muted);
  line-height: 1.4;
}
.cm-char-count {
  font-size: 11.5px;
  color: var(--text-muted);
  font-family: var(--f-mono, monospace);
  white-space: nowrap;
  margin-left: auto;
}

/* 모바일에서 cm-login-banner / cm-guest-row 가 좁아질 때 자연 wrap */
@media (max-width: 480px) {
  /* column stack → row 유지. 텍스트와 버튼을 한 행에 붙임 (요청: "두 개를 붙여줘"). */
  .cm-login-banner {
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    gap: 8px;
  }
  .cm-login-banner p {
    margin: 0;
    flex: 1 1 auto;
    min-width: 0;        /* 텍스트가 wrap 가능하도록 */
  }
  .cm-login-banner .cm-btn--sm {
    width: auto;
    flex: 0 0 auto;
    white-space: nowrap;
  }
}

/* =====================================================================
   내정보 > 내글 (.mp-*) — 포카톡 / 포카맵 탭 + sub-tab + 페이지네이션
   ===================================================================== */
.mp-view {
  padding: 12px 18px 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* 1차 탭 — 포카톡 / 포카맵 (큰 토글) */
.mp-tabs {
  display: flex;
  gap: 6px;
  padding: 4px;
  background: var(--surface-soft);
  border-radius: 10px;
}
.mp-tab {
  flex: 1;
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-muted);
  padding: 8px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.mp-tab.is-on {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: 0 1px 2px rgba(15,23,42,0.08);
}

/* 2차 탭 — 내가 쓴글 / 내 댓글 */
.mp-subtabs {
  display: flex;
  gap: 16px;
  padding: 4px 4px 8px;
  border-bottom: 1px solid var(--border);
}
.mp-subtab {
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-muted);
  padding: 4px 2px;
  cursor: pointer;
}
.mp-subtab.is-on {
  color: var(--text-strong);
  border-bottom: 2px solid var(--brand);
}

/* 리스트 row */
.mp-list { display: flex; flex-direction: column; }
.mp-row {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
  padding: 12px 4px;
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: background 120ms ease;
}
.mp-row:hover { background: var(--surface-soft); }
.mp-row-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.mp-badge {
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  color: var(--text-strong);
}
.mp-badge--warn { background: #FEF3C7; color: #92400E; border-color: #FCD34D; }
.mp-row-time { font-size: 11px; color: var(--text-muted); margin-left: auto; }
.mp-row-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-strong);
  line-height: 1.4;
  margin-bottom: 4px;
}
.mp-row-target {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 4px;
  /* 1줄 ellipsis */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mp-row-body {
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.5;
  margin-bottom: 6px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.mp-row-body--mine { color: var(--text-strong); }
.mp-row-stats {
  display: flex;
  gap: 10px;
  font-size: 11px;
  color: var(--text-muted);
}
.mp-row-stats > span { display: inline-flex; align-items: center; gap: 3px; }
.mp-row-stats svg { width: 12px; height: 12px; }

/* 페이지네이션 */
.mp-pager {
  display: flex;
  justify-content: center;
  gap: 4px;
  padding: 12px 0 4px;
  flex-wrap: wrap;
}
.mp-pager:empty { display: none; }
.mp-pager-btn {
  min-width: 32px;
  height: 32px;
  padding: 0 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-strong);
  cursor: pointer;
  transition: background 120ms ease;
}
.mp-pager-btn:hover { background: var(--surface-soft); }
.mp-pager-btn.is-on {
  background: var(--brand);
  color: #fff;
  border-color: var(--brand);
}
.mp-pager-gap {
  display: inline-flex;
  align-items: center;
  padding: 0 4px;
  color: var(--text-muted);
  font-size: 12.5px;
}

/* place_comment highlight — 내글에서 진입 시 잠깐 강조 (community 와 동일 톤) */
.pc-item.pc-item-highlight {
  background: rgba(250, 204, 21, 0.18);
  border-radius: 8px;
  outline: 2px solid #FACC15;
  outline-offset: 2px;
  animation: pcHighlightFade 2.4s ease-out forwards;
}
@keyframes pcHighlightFade {
  0%   { background: rgba(250, 204, 21, 0.28); }
  60%  { background: rgba(250, 204, 21, 0.18); }
  100% { background: transparent; outline-color: transparent; }
}

/* ====================================================================
   이미지 업로드 — 포카톡 새 글 (cm-*) + 위치별 댓글 (pc-*) 공통 톤.
   클라이언트 압축 (1280px / JPEG 80%) 후 Supabase Storage 업로드.
   ==================================================================== */

/* ----- 포카톡 새 글 compose (최대 4장) ----- */
.cm-compose-images { margin-top: 6px; }
.cm-image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
  margin-top: 6px;
}
.cm-image-tile {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface-mid, #E5E7EB);
}
.cm-image-tile img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.cm-image-overlay {
  position: absolute; inset: 0;
  background: rgba(15, 23, 42, 0.55);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600;
  text-align: center; padding: 6px;
}
.cm-image-overlay--err { background: rgba(220, 38, 38, 0.85); }
.cm-image-remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 0;
  background: rgba(15, 23, 42, 0.75);
  color: #fff;
  font-size: 14px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.cm-image-remove:hover { background: rgba(220, 38, 38, 0.9); }
.cm-image-add {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  aspect-ratio: 1 / 1;
  border: 1.5px dashed var(--border-strong, #94A3B8);
  border-radius: 10px;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 11px;
  background: var(--surface, #fff);
  transition: border-color .15s, background .15s;
}
.cm-image-add:hover { border-color: var(--brand); background: var(--brand-soft, #DBEAFE); color: var(--brand); }
.cm-image-add-plus { font-size: 22px; font-weight: 300; line-height: 1; }
.cm-image-add-label { margin-top: 2px; font-weight: 500; }

/* ----- 포카톡 detail 갤러리 (1~4장) ----- */
.cm-detail-gallery {
  display: grid;
  gap: 6px;
  margin: 14px 0 4px;
  border-radius: 10px;
  overflow: hidden;
}
.cm-detail-gallery[data-count="1"] { grid-template-columns: 1fr; }
.cm-detail-gallery[data-count="2"] { grid-template-columns: 1fr 1fr; }
.cm-detail-gallery[data-count="3"],
.cm-detail-gallery[data-count="4"] { grid-template-columns: 1fr 1fr; }
.cm-gallery-tile {
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--surface-mid, #E5E7EB);
  overflow: hidden;
  border-radius: 8px;
}
.cm-gallery-tile img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.cm-detail-gallery[data-count="1"] .cm-gallery-tile { aspect-ratio: 3 / 2; }

/* ----- 위치별 댓글 compose (최대 1장) ----- */
.pc-image-block { margin: 8px 0; }
.pc-image-tile {
  position: relative;
  width: 120px;
  height: 120px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface-mid, #E5E7EB);
}
.pc-image-tile img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.pc-image-overlay {
  position: absolute; inset: 0;
  background: rgba(15, 23, 42, 0.55);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600;
  text-align: center; padding: 6px;
}
.pc-image-overlay--err { background: rgba(220, 38, 38, 0.85); }
.pc-image-remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 0;
  background: rgba(15, 23, 42, 0.75);
  color: #fff;
  font-size: 14px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.pc-image-remove:hover { background: rgba(220, 38, 38, 0.9); }
.pc-image-add {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  border: 1.5px dashed var(--border-strong, #94A3B8);
  border-radius: 8px;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 12.5px; font-weight: 600;
  background: var(--surface, #fff);
  transition: border-color .15s, background .15s, color .15s;
}
.pc-image-add:hover { border-color: var(--brand); background: var(--brand-soft, #DBEAFE); color: var(--brand); }
.pc-image-add-plus { font-size: 18px; line-height: 1; font-weight: 300; }

/* ----- 댓글 row 의 첨부 이미지 thumbnail ----- */
.pc-image-attached {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 8px 0 4px;
}
.pc-image-thumb {
  display: block;
  width: 140px;
  max-width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-mid, #E5E7EB);
}
.pc-image-thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .2s;
}
.pc-image-thumb:hover img { transform: scale(1.04); }
/* 포카맵 댓글 사진 — 작게 (사이드바 좁아서). 클릭 시 lightbox 확대. */
.pc-image-thumb {
  width: 84px;
  height: 84px;
  aspect-ratio: 1 / 1;
  border: 0;
  padding: 0;
  cursor: zoom-in;
}

/* ====================================================================
   썸네일 지정 badge — 포카톡 compose 의 첫 이미지에 표시
   ==================================================================== */
.cm-image-tile.is-thumb { box-shadow: 0 0 0 2px var(--brand, #2563EB); }
.cm-image-thumb-badge {
  position: absolute;
  bottom: 4px; left: 4px;
  background: var(--brand, #2563EB);
  color: #fff;
  font-size: 10px; font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  pointer-events: none;
}
.cm-image-set-thumb {
  position: absolute;
  bottom: 4px; left: 4px;
  background: rgba(15, 23, 42, 0.72);
  color: #fff;
  font-size: 10px; font-weight: 600;
  padding: 3px 7px;
  border-radius: 4px;
  border: 0;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s;
}
.cm-image-tile:hover .cm-image-set-thumb { opacity: 1; }
@media (max-width: 768px) {
  .cm-image-set-thumb { opacity: 1; }
}

/* ====================================================================
   포카맵 위치 detail — 사용자 사진 갤러리 (네이버 지도 스타일)
   1 large (왼) + 2x2 small (오) + 5번째에 +N 더보기 overlay
   ==================================================================== */
.dv-photo-gallery-slot { padding: 0; }
.dv-pg {
  display: grid;
  gap: 4px;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  overflow: hidden;
}
.dv-pg--1 { grid-template-columns: 1fr; }
.dv-pg--2 { grid-template-columns: 1fr 1fr; }
.dv-pg--3 {
  grid-template-columns: 2fr 1fr;
  grid-template-rows: 1fr 1fr;
}
.dv-pg--3 .dv-pg-tile:first-child { grid-row: span 2; }
.dv-pg--4,
.dv-pg--5 {
  grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}
.dv-pg--4 .dv-pg-tile:first-child,
.dv-pg--5 .dv-pg-tile:first-child { grid-row: span 2; }
.dv-pg-tile {
  position: relative;
  display: block;
  overflow: hidden;
  border: 0;
  padding: 0;
  background: var(--surface-mid, #E5E7EB);
  cursor: zoom-in;
}
.dv-pg-tile img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .25s;
}
.dv-pg-tile:hover img { transform: scale(1.04); }
.dv-pg-more {
  position: absolute; inset: 0;
  background: rgba(15, 23, 42, 0.55);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700;
  text-align: center;
  pointer-events: none;
  line-height: 1.3;
}
/* 사용자 갤러리가 표시되면 stock hero 는 숨김 (DOM 에선 유지 — 사진 0 일 때 다시 보이게). */
.dv-photo-gallery-slot:not(:empty) + .dv-hero { display: none; }

/* ====================================================================
   Lightbox — 공용 (포카톡 detail / 포카맵 댓글 / 위치 갤러리 모두 사용)
   ==================================================================== */
.lightbox {
  position: fixed; inset: 0;
  z-index: 9999;
  display: none;
}
.lightbox.is-open { display: block; }
.lightbox[aria-hidden="false"] { display: block; }
.lightbox-backdrop {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, 0.92);
  cursor: zoom-out;
}
.lightbox-stage {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 40px 16px env(safe-area-inset-bottom, 0px);
  pointer-events: none;
}
.lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  background: transparent;
  border-radius: 4px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
  pointer-events: auto;
}
.lightbox-close {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 12px);
  right: 12px;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
  font-size: 28px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  z-index: 2;
  transition: background .15s;
}
.lightbox-close:hover { background: rgba(255, 255, 255, 0.32); }
.lightbox-prev,
.lightbox-next {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  width: 48px; height: 64px;
  border-radius: 8px;
  border: 0;
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  font-size: 36px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  z-index: 2;
  transition: background .15s;
}
.lightbox-prev { left: 12px; }
.lightbox-next { right: 12px; }
.lightbox-prev:hover,
.lightbox-next:hover { background: rgba(0, 0, 0, 0.55); }
.lightbox-counter {
  position: absolute;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  left: 50%; transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 13px; font-weight: 600;
  padding: 6px 12px;
  border-radius: 20px;
  pointer-events: none;
}
body.lightbox-open { overflow: hidden; }

/* =====================================================================
   PWA standalone 모드 — iPhone/Android 홈화면 추가 후 실행 시 추가 보정.
   기본 layout 은 모바일 모드 (Safari/Chrome) 와 동일한 env(safe-area-inset-*)
   기반으로 동작 — PWA 모드에선 추가로:
     1) 상단: Dynamic Island 와 검색 UI 사이에 시각적 여백 +12px (status bar
        과 너무 가까워 보이는 인상 보정)
     2) 하단: 추가 padding 없음. 기존 env(safe-area-inset-bottom) 만 사용.
        (home indicator 영역만 정확히 비워두고 그 이상 흰 여백 X)

   감지: html.pwa-standalone (JS 가 navigator.standalone + display-mode 둘 다
   체크해서 부여) + @media (display-mode: standalone) (보조 fallback).

   변수: --app-safe-top / --app-safe-bottom / --app-vh / --mobile-nav-h
   는 :root 에 정의 (이 파일 상단). JS 가 --app-vh / --mobile-nav-h 동적 업데이트.
   ===================================================================== */

/* (1) JS-class 기반 — 가장 신뢰성 높음. iOS 모든 케이스 cover. */
html.pwa-standalone .search-shell-anchor,
html.pwa-standalone .map-shell[data-layout="rail-list"] .search-shell-anchor,
html.pwa-standalone .map-shell[data-layout="rail-list-detail"] .search-shell-anchor {
  top: calc(24px + var(--app-safe-top)) !important;
}
html.pwa-standalone .chip-row-anchor,
html.pwa-standalone .map-shell[data-layout="rail-list"] .chip-row-anchor,
html.pwa-standalone .map-shell[data-layout="rail-list-detail"] .chip-row-anchor {
  top: calc(76px + var(--app-safe-top)) !important;
}
/* 실시간 현황 panel — chip-row 변위와 동일하게 12px 더 내려서 겹침 방지. */
html.pwa-standalone .live-status-anchor--mobile {
  top: calc(var(--live-mobile-top, 72px) + 12px) !important;
}

/* (2) @media fallback — JS 안 돌거나 클래스 부여 실패 시. */
@media (display-mode: standalone) and (max-width: 768px) {
  .search-shell-anchor,
  .map-shell[data-layout="rail-list"] .search-shell-anchor,
  .map-shell[data-layout="rail-list-detail"] .search-shell-anchor {
    top: calc(24px + env(safe-area-inset-top, 0px)) !important;
  }
  .chip-row-anchor,
  .map-shell[data-layout="rail-list"] .chip-row-anchor,
  .map-shell[data-layout="rail-list-detail"] .chip-row-anchor {
    top: calc(76px + env(safe-area-inset-top, 0px)) !important;
  }
}

/* =====================================================================
 * Phase 2 — User Points / Tier UI
 * ===================================================================== */

/* 등급 아이콘 슬롯 — 댓글 row 닉네임 옆에 작게 */
/* 부모(.pc-meta / .cm-comment-head)가 flex + gap 8px → 슬롯이 너무 멀어보임.
   negative margin-left 로 gap 상쇄해서 닉네임 바로 옆에 붙임 + 텍스트와 수직 정렬 맞춤. */
.pa-tier-slot {
  display: inline-flex;
  align-items: center;
  align-self: center;            /* 부모 baseline 정렬 override — 텍스트 중앙에 맞춤 */
  margin-left: -6px;             /* parent gap 8px → 실효 2px 간격 */
  line-height: 1;
  flex: 0 0 auto;
}
.pa-tier-slot .tier-icon {
  width: 14px;
  height: 14px;
  object-fit: contain;
  display: block;                /* inline 의 baseline 오프셋 제거 */
  vertical-align: middle;
}
.pa-tier-slot .tier-badge {
  font-size: 9px;
  padding: 1px 4px;
  line-height: 1.3;
}

/* 예상 포인트 라벨 (compose form 옆) */
.pa-est-points {
  display: inline-block;
  font-size: 11.5px;
  color: var(--text-muted, #6b7280);
  margin-left: 8px;
  font-weight: 500;
}
.pa-est-points:empty {
  display: none;
}

/* 내정보 등급 패널 — Pretendard, 간결하게 */
.ps-tier-panel {
  margin: 12px 16px 0;
  font-family: var(--f-sans);
}
.ps-tier-loading,
.ps-tier-breakdown-loading,
.ps-tier-breakdown-empty {
  padding: 12px 16px;
  font-size: 12.5px;
  color: var(--text-muted, #6b7280);
  text-align: center;
}
.ps-tier-card {
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 12px;
  background: #fff;
  padding: 14px 16px;
}
.ps-tier-row {
  display: flex;
  align-items: center;
  gap: 14px;
}
.ps-tier-icon {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ps-tier-info {
  flex: 1;
  min-width: 0;
}
.ps-tier-label {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.4px;
  line-height: 1.2;
  margin-bottom: 4px;
}
.ps-tier-points {
  font-size: 12.5px;
  color: var(--text-muted, #6b7280);
  margin-bottom: 8px;
}
.ps-tier-points strong {
  color: var(--text-strong, #111827);
  font-weight: 700;
  margin-left: 2px;
}
.ps-tier-hint {
  font-size: 12px;
  color: var(--text-muted, #6b7280);
}
.ps-tier-progress-text {
  font-size: 12px;
  color: var(--text-muted, #6b7280);
  margin-bottom: 5px;
}
.ps-tier-progress-text strong {
  color: var(--text-strong, #111827);
  font-weight: 700;
}
.ps-tier-progress-bar {
  height: 5px;
  background: var(--surface-soft, #f3f4f6);
  border-radius: 3px;
  overflow: hidden;
}
.ps-tier-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #FACC15, #F59E0B);
  border-radius: 3px;
  transition: width 0.3s ease;
}

/* breakdown 영역 — 최근 N일 요약 + 활동 리스트 */
.ps-tier-breakdown {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border, #f3f4f6);
}
.ps-tier-summary-inline {
  display: flex;
  gap: 10px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.ps-tier-summary-chip {
  font-size: 12px;
  color: var(--text-muted, #6b7280);
  background: var(--surface-soft, #f9fafb);
  border-radius: 6px;
  padding: 4px 9px;
  white-space: nowrap;
}
.ps-tier-summary-chip-label {
  color: var(--text-muted, #6b7280);
  margin-right: 4px;
}
.ps-tier-summary-chip strong {
  color: var(--brand, #F59E0B);
  font-weight: 700;
}
.ps-tier-breakdown-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.ps-tier-row-li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 2px;
  font-size: 12.5px;
  border-bottom: 1px solid var(--border, #f3f4f6);
}
.ps-tier-row-li:last-child {
  border-bottom: none;
}
.ps-tier-row-label {
  color: var(--text, #374151);
}
.ps-tier-row-meta {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  color: var(--text-muted, #6b7280);
}
.ps-tier-row-count {
  font-size: 11px;
}
.ps-tier-row-pts {
  color: var(--brand, #F59E0B);
  font-weight: 700;
}

/* =====================================================================
 * Phase 3 — Freshness / Daily Cap / Streak UX
 * ===================================================================== */

/* 신선도 배지 — 위치 댓글 root 에만 */
.pc-freshness {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 4px;
  margin-left: 2px;
  vertical-align: middle;
  line-height: 1.4;
}
.pc-freshness--stale {
  background: #f3f4f6;
  color: #6b7280;
}
.pc-freshness--old {
  background: #fef3c7;
  color: #92400e;
}

/* 30일+ 댓글 — 흐림 처리 */
.pc-item--old .pc-body,
.pc-item--old .pc-image-attached,
.pc-item--old .pc-meta {
  opacity: 0.55;
}
.pc-item--old .pc-actions {
  opacity: 0.75;
}
.pc-freshness-notice {
  margin: 4px 0 6px;
  padding: 6px 9px;
  font-size: 11.5px;
  color: #92400e;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: 6px;
}

/* 7-30일 — 좀 옅게만 (텍스트는 그대로) */
.pc-item--stale .pc-meta {
  /* 변화 없음 — 배지만 표시 */
}

/* 출석 streak chip */
.ps-tier-streak-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ps-tier-streak-chip strong {
  color: var(--text-strong, #111827);
}
.ps-tier-streak-hint {
  font-size: 10.5px;
  color: var(--text-muted, #9ca3af);
}

/* =====================================================================
 * Phase 4 — Admin Points/Sanction Tab
 * ===================================================================== */

.adm-pts-search-row {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}
.adm-pts-search-input {
  flex: 1;
  font-family: var(--f-sans);
}

.adm-pts-layout {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 14px;
}
@media (max-width: 768px) {
  .adm-pts-layout { grid-template-columns: 1fr; }
}

.adm-pts-list-head {
  font-size: 12px;
  color: var(--text-muted, #6b7280);
  margin-bottom: 6px;
}
.adm-pts-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 60vh;
  overflow-y: auto;
}
.adm-pts-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: var(--f-sans);
}
.adm-pts-row:hover { background: var(--surface-soft, #f9fafb); }
.adm-pts-row.is-selected {
  border-color: var(--brand, #F59E0B);
  background: #fffbeb;
}
.adm-pts-row-icon { flex: 0 0 18px; }
.adm-pts-row-info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.adm-pts-row-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-strong, #111827);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.adm-pts-row-email {
  font-size: 11px;
  color: var(--text-muted, #6b7280);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.adm-pts-row-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  flex: 0 0 auto;
}
.adm-pts-row-pts {
  font-size: 14px;
  color: var(--brand, #F59E0B);
}
.adm-pts-tag {
  font-size: 9.5px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
}
.adm-pts-tag--penalty {
  background: #fee2e2;
  color: #b91c1c;
}
.adm-pts-tag--sanction {
  background: #fef3c7;
  color: #92400e;
}

/* 상세 panel */
.adm-pts-detail {
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 10px;
  padding: 14px;
  background: #fff;
}
.adm-pts-detail-head {
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border, #f3f4f6);
}
.adm-pts-detail-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  margin-bottom: 4px;
}
.adm-pts-detail-email {
  font-size: 12px;
  color: var(--text-muted, #6b7280);
  margin-bottom: 10px;
}
.adm-pts-detail-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  font-size: 12.5px;
}
.adm-pts-detail-stats .muted {
  color: var(--text-muted, #6b7280);
  margin-right: 3px;
  font-size: 11.5px;
}
.adm-pts-detail-stats strong {
  color: var(--text-strong, #111827);
  font-weight: 700;
}
.adm-pts-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}
.ps-btn--sm {
  font-size: 11.5px;
  padding: 4px 10px;
}

.adm-pts-hist-title {
  font-size: 13px;
  font-weight: 700;
  margin: 8px 0;
  color: var(--text-strong, #111827);
}
.adm-pts-hist-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 380px;
  overflow-y: auto;
}
.adm-pts-hist-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 6px 4px;
  font-size: 12px;
  border-bottom: 1px solid var(--border, #f3f4f6);
}
.adm-pts-hist-row.is-revoked {
  opacity: 0.5;
}
.adm-pts-hist-row:last-child { border-bottom: none; }
.adm-pts-hist-main {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex: 1;
  min-width: 0;
  flex-wrap: wrap;
}
.adm-pts-hist-action {
  font-weight: 600;
  color: var(--text, #374151);
}
.adm-pts-hist-src {
  color: var(--text-muted, #6b7280);
  font-size: 11px;
}
.adm-pts-hist-time {
  margin-left: auto;
  font-size: 10.5px;
  color: var(--text-muted, #9ca3af);
}
.adm-pts-hist-side {
  display: flex;
  align-items: center;
  gap: 6px;
}
.adm-pts-hist-pts {
  font-weight: 700;
  color: var(--brand, #F59E0B);
  min-width: 30px;
  text-align: right;
}
.adm-pts-hist-pts--revoked {
  color: #9ca3af;
  text-decoration: line-through;
}
.adm-pts-hist-empty {
  padding: 10px;
  text-align: center;
  color: var(--text-muted, #9ca3af);
  font-size: 12px;
}
