:root {
  --bg: #121418;
  --surface: #1A1D24;
  --sheet: #16181E;
  --hairline: #2A2E38;
  --divider: #22252E;
  --text: #EDEFF3;
  --text-2: #B8BDC9;
  --muted: #8A8F9C;
  /* --faint (#6E7484) fails WCAG AA at body text sizes on --sheet/--bg — decorative or large-text use only. */
  --faint: #6E7484;
  --accent: #FF4D66;
  --on-accent: #16060A;
  --trust: #E8A93C;
  --open: #6BCB77;
  --closed: #E05A5A;
  /* 지도 레벨 5~6 2급 마커용 채도 낮춘 점 색 — --accent보다 차분해 1급
     도트+링과 위계가 갈리도록. 근거가 영상이냐 동네 후기냐에 따라
     --accent/--trust 계열로 갈리므로 낮춘 색도 두 벌 둔다. */
  --dot-muted: #C96B6B;
  --dot-muted-trust: #B8974E;

  --radius-chip: 999px;
  --radius-card: 12px;
  --radius-sheet: 20px;
  --radius-cta: 14px;

  --font-body: "Pretendard Variable", Pretendard, "Noto Sans KR", system-ui, sans-serif;
  --font-display: "Do Hyeon", sans-serif;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
}

.map-screen {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
}

/* 모바일에서 지도가 주인공이 되도록 상단 크롬은 최대한 얇게 —
   워드마크와 부제를 한 줄로 붙인다. */
.wordmark-row {
  flex-shrink: 0;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 10px 12px 0;
  background: var(--bg);
}

/* 모바일에서는 이 묶음에 알약 껍질이 입혀져 지도 위에 뜬다(아래 오버레이
   블록). 데스크톱에서는 껍질 없이 한 줄로만 남는다. */
.wordmark-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.wordmark {
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--text);
  letter-spacing: 0.01em;
}

.wordmark-subtitle {
  font-size: 10px;
  color: var(--muted);
}

.chip-rows {
  flex-shrink: 0;
  padding: 4px 8px 2px;
  background: var(--bg);
  z-index: 2;
}

.chip-row {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding: 3px 0;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to right, black calc(100% - 12px), transparent 100%);
  mask-image: linear-gradient(to right, black calc(100% - 12px), transparent 100%);
}

.chip-row::-webkit-scrollbar {
  display: none;
}

.chip {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  padding: 6px 12px;
  background: var(--surface);
  color: var(--text-2);
  white-space: nowrap;
  font-size: 14px;
  font-family: var(--font-body);
}

/* 선호 채널 칩 — 아바타를 달아 이름만으로는 잘 안 붙는 채널 식별을
   돕는다. 여러 개를 동시에 고를 수 있어 상황/종류 칩과 달리 활성 칩이
   여럿 남는다. */
.chip-channel {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.chip-avatar {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg);
}

.chip-channels {
  white-space: nowrap;
}

.channel-count {
  font-variant-numeric: tabular-nums;
}

/* 근거 렌즈 칩 — 앞의 색 점이 지도 마커 색과 같은 값이라 칩 자체가
   범례가 된다. 교차검증은 두 색이 합쳐진 모양(앰버 링 + 빨강 코어)으로
   1급 마커를 그대로 축소한 것이다. */
.chip-lens {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.chip-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  box-sizing: border-box;
}

.chip-dot-video {
  background: var(--accent);
}

.chip-dot-review {
  background: var(--trust);
}

.chip-dot-both {
  background: var(--accent);
  border: 2px solid var(--trust);
}

.chip-row + .chip-row .chip {
  padding: 5px 10px;
  font-size: 13px;
}

/* hidden 속성이 display:flex/grid에 밀리지 않게 — 채널 줄과 종류 격자는
   접힌 상태가 기본이다. UA의 [hidden] 규칙은 클래스 선택자와 특정도가 같아
   저자 스타일에 진다(그래서 채널 줄이 늘 펼쳐져 있었다). */
.chip-row[hidden],
.category-panel[hidden],
.directions-menu[hidden] {
  display: none;
}

/* 길찾기 앱 고르기 — 지도앱은 사람마다 고정돼 있어 하나로 강제하면 매번 두
   단계를 버린다. 마지막에 쓴 앱이 맨 앞(“최근”)으로 온다. */
.directions-menu {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 8px;
}

.dir-app {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-cta);
  background: var(--surface);
  color: var(--text-2);
  font-size: 14px;
  text-decoration: none;
}

.dir-recent {
  border-color: var(--accent);
  color: var(--text);
}

.dir-recent::after {
  content: "최근";
  padding: 2px 6px;
  border-radius: var(--radius-chip);
  background: var(--accent);
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 700;
}

/* 종류 선택 칩 — 누르면 격자가 열리고, 열린 상태는 꺾쇠 회전으로 알린다. */
.chip-select {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.chip-caret {
  flex-shrink: 0;
  transition: transform 140ms ease;
}

.chip-select[aria-expanded="true"] .chip-caret {
  transform: rotate(180deg);
}

/* 종류 격자 — 전체 + 아홉 종류를 한눈에. 칩 줄로 늘어놓으면 가로 스크롤에
   절반이 가리고 줄 수만 늘어 지도를 덮는다. */
.category-panel {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
  margin: 8px 0 2px;
  padding: 10px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}

.cat-cell {
  min-height: 44px;
  padding: 0 4px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-cta);
  background: var(--bg);
  color: var(--text-2);
  font-family: var(--font-body);
  font-size: 14px;
  cursor: pointer;
}

.cat-cell.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
}

.chip.active {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}

/* 모바일 상단 오버레이 — 하단 시트와 같은 원리로 상단도 지도 위에 띄운다.
   워드마크·칩이 세로를 먹지 않으므로 지도가 화면 전체를 쓴다(지도 앱 표준).
   데스크톱은 아래 그리드 블록에서 display:contents로 풀린다. */
@media (max-width: 899px) {
  .map-top {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10;
    padding-bottom: 12px;
    /* 배경 띠(스크림)를 깔지 않는다 — 네이버·카카오·구글 지도 모두 상단을
       그라디언트로 덮지 않고, 각 요소가 자기 배경을 가진 알약으로 떠 있어
       그 사이로 지도가 그대로 보인다. 띠를 깔면 오버레이가 아니라 반투명
       헤더가 되어 지도를 가린 채 경계만 흐려진다. */
    background: none;
    /* 누를 것이 없는 자리는 지도로 통과시킨다 — 여기가 터치를 먹으면
       화면 위쪽에서 지도를 끌 수 없다. */
    pointer-events: none;
  }

  /* 칩 줄만 되돌려 잡는다 — 탭도 받아야 하고 가로 스크롤도 해야 한다. */
  .map-top .chip-rows {
    pointer-events: auto;
    background: transparent;
  }

  .map-top .wordmark-row {
    background: transparent;
    padding-bottom: 2px;
  }

  /* 지도 위에 뜨는 요소는 저마다 불투명한 배경 + 그림자를 갖는다. 이것이
     스크림을 대신해 밝은 지도 위에서도 글자를 읽히게 한다. */
  .wordmark-pill {
    padding: 5px 12px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-chip);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.38);
  }

  .map-top .chip {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.38);
  }

  /* 끝을 흐리게 지우던 마스크는 불투명한 헤더 위에서나 "더 있다"로 읽힌다 —
     지도 위에서는 알약이 녹아 없어지는 것처럼 보인다. 지도 앱들처럼 화면
     끝에서 그냥 잘리게 둔다. */
  .map-top .chip-row {
    -webkit-mask-image: none;
    mask-image: none;
  }
}

.map-wrap {
  position: relative;
  display: flex;
  flex: 1;
  min-height: 40dvh;
}

.map-canvas {
  flex: 1;
}

.locate-btn {
  position: absolute;
  right: 12px;
  bottom: 14px;
  z-index: 3;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  background: rgba(26, 29, 36, 0.94);
  color: var(--text-2);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
  cursor: pointer;
}

/* 모바일에선 시트가 지도 아래를 덮으므로 그 위에 띄우고, 시트를 끌면 함께
   따라 올라간다 — sheet_controller가 :root에 심는 --sheet-h를 읽는다. */
@media (max-width: 899px) {
  .locate-btn {
    bottom: calc(var(--sheet-h, 35dvh) + 12px);
    transition: bottom 120ms linear;
  }
}

/* 위치 점의 파랑은 지도 앱 관례색 — 액센트(선택 마커)와 겹치지 않게 분리. */
.my-loc-dot {
  width: 14px;
  height: 14px;
  border-radius: var(--radius-chip);
  background: #5B9DFF;
  border: 2.5px solid #FFFFFF;
  box-shadow: 0 0 0 2px rgba(91, 157, 255, 0.35), 0 1px 4px rgba(0, 0, 0, 0.5);
}

.bottom-sheet {
  max-height: 35dvh;
  overflow-y: auto;
  background: var(--sheet);
  border-top: 1px solid var(--hairline);
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.3);
  padding: 8px 16px;
}

.expand-btn {
  width: 100%;
  padding: 10px;
  border: 1px dashed var(--hairline);
  border-radius: var(--radius-cta);
  background: transparent;
  color: var(--muted);
  font-family: var(--font-body);
  margin-bottom: 8px;
}

/* --- 마커 카드 (탭 즉시 표시) ------------------------------------------- */

.place-card {
  padding: 0 4px 16px;
}

.card-grabber {
  width: 36px;
  height: 4px;
  border-radius: var(--radius-chip);
  background: var(--hairline);
  margin: 4px auto 12px;
}

.card-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.card-name {
  font-family: var(--font-display);
  font-size: 20px;
  color: var(--text);
}

.card-category {
  font-size: 12px;
  color: var(--muted);
}

/* 시각적으론 작은 텍스트지만 패딩+네거티브 마진으로 44px 탭 영역을 확보한다. */
.card-detail-link {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 2px;
  color: var(--muted);
  font-size: 13px;
  text-decoration: none;
  padding: 14px 0 14px 14px;
  margin-top: -14px;
  margin-bottom: -14px;
}

.card-status-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  font-size: 12px;
}

.card-open { color: var(--open); }
.card-closed { color: var(--closed); }

.card-signal {
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--trust);
}

.card-signal svg { flex-shrink: 0; }

.card-address {
  margin-top: 4px;
  font-size: 13px;
  color: var(--text-2);
}

.card-actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
}

.card-action {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 62px;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-cta);
  color: var(--text-2);
  font-size: 12px;
  font-family: var(--font-body);
  text-decoration: none;
  cursor: pointer;
}

.card-action-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
}

.list-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 4px;
  border-bottom: 1px solid var(--divider);
  text-decoration: none;
  color: var(--text);
}

.list-item-head {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.item-pill {
  flex-shrink: 0;
  margin-left: auto;
  padding: 3px 8px;
  border-radius: var(--radius-chip);
  font-size: 11px;
  white-space: nowrap;
}

.item-pill-tier1 {
  background: var(--trust);
  color: var(--on-accent);
  font-weight: bold;
}

.item-pill-signal {
  border: 1px solid var(--trust);
  color: var(--trust);
}

.item-pill-video {
  border: 1px solid var(--hairline);
  color: var(--muted);
}

.item-meta {
  font-size: 12px;
  color: var(--muted);
}

.signal-badge {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-basis: 100%;
  margin-top: 2px;
  font-size: 12px;
  color: var(--trust);
}

.signal-icon {
  flex-shrink: 0;
  color: var(--trust);
}

.signal-badge-filled {
  background: var(--trust);
  color: var(--on-accent);
  border-radius: var(--radius-chip);
  padding: 2px 8px;
  font-weight: bold;
}

.signal-badge-filled .signal-icon {
  color: var(--on-accent);
}

.video-badge {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-basis: 100%;
  margin-top: 2px;
  font-size: 12px;
  color: var(--muted);
}

.item-name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 400;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.item-category {
  font-size: 12px;
  color: var(--muted);
}

.item-address {
  font-size: 12px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.empty {
  color: var(--muted);
  padding: 16px 4px;
}

/* 공개 서비스 고지 — 읽히긴 해야 하되 목록/상세를 방해하지 않는 크기. */
.disclosure {
  margin: 20px 4px 8px;
  font-size: 11px;
  line-height: 1.6;
  color: var(--muted);
  border-top: 1px solid var(--divider);
  padding-top: 12px;
}

.detail {
  min-height: 100dvh;
  background: var(--sheet);
  color: var(--text);
  padding: 16px;
  font-family: var(--font-body);
}

/* 지도 화면 위의 상세 오버레이 — 내용이 로드되면 map#detailLoaded가 .open을
   붙여 전면으로 띄운다. 페이지 이동이 없으므로 닫아도 지도 상태가 남는다. */
.detail-overlay {
  display: none;
}

.detail-overlay.open {
  display: block;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  /* 카드 시트(z-30)보다 위 — 카드에서 '상세'를 열면 오버레이가 카드를
     완전히 덮고, 닫으면 카드·선택이 그대로 돌아온다. */
  z-index: 40;
  overflow-y: auto;
  background: var(--sheet);
}

.detail-top {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.detail-back {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  margin-left: -12px;
  color: var(--muted);
  text-decoration: none;
}

/* V7 데스크톱 패널 안 상세: turbo-frame#list 안에서 렌더되는 파셜이라
   .detail의 min-height:100dvh(전체 페이지 전용)는 걷어낸다 — 패널은
   .bottom-sheet가 이미 height:100%; overflow-y:auto라 자체 높이를
   강제할 필요가 없다. "← 목록"은 back-link 톤을 그대로 쓰되 버튼 기본
   스타일(테두리/배경/패딩)만 리셋한다. */
.panel-detail {
  min-height: 0;
}

.panel-back {
  display: inline-flex;
  align-items: center;
  border: none;
  background: none;
  padding: 0;
  font-family: var(--font-body);
  font-size: 14px;
  cursor: pointer;
}

.detail-heading {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.detail-top h1,
.detail h1 {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 400;
  color: var(--text);
  margin: 0;
}

.detail-top .signal-pill {
  margin-left: auto;
}

.info-rows {
  margin-top: 14px;
}

.info-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--divider);
}

.info-row > svg {
  flex-shrink: 0;
  color: var(--muted);
}

.info-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.info-label {
  font-size: 11px;
  color: var(--muted);
}

.info-value {
  font-size: 14px;
  color: var(--text);
}

/* 인라인 링크지만 세로 패딩으로 탭 영역을 키운다 (시각 크기는 그대로). */
.info-value a {
  color: var(--accent);
  text-decoration: none;
  display: inline-block;
  padding: 10px 0;
  margin: -10px 0;
}

.info-open { color: var(--open); }
.info-closed { color: var(--closed); }

.signal-pill {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border: 1px solid var(--trust);
  border-radius: var(--radius-chip);
  color: var(--trust);
  font-size: 12px;
}

.local-stories {
  margin-top: 20px;
}

.local-stories h2 {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 400;
  color: var(--text);
  margin: 0 0 10px;
}

.note-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  padding: 12px;
  margin-bottom: 10px;
}

.note-text {
  font-family: "Gowun Batang", serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-2);
  margin: 0 0 6px;
}

.note-meta {
  font-size: 11px;
  color: var(--muted);
  margin: 0;
}

.detail-cta-row {
  display: flex;
  gap: 8px;
  margin-top: 22px;
}

.detail-cta {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-cta);
  color: var(--text-2);
  font-size: 15px;
  text-decoration: none;
}

.detail-cta-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
}

.map-error {
  padding: 24px 16px;
  color: var(--muted);
  text-align: center;
}

.videos-section {
  margin-top: 20px;
}

.videos-section h2 {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 400;
  color: var(--text);
  margin: 0 0 10px;
}

/* V9: 카드 박스(.video-card)와 클릭 대상(.video-card-trigger)을 분리한다 —
   재생 시 삽입되는 플레이어가 앵커 안이 아니라 형제로 들어가야 하기
   때문이다(링크 안에 iframe·버튼을 넣으면 잘못된 마크업이 된다). */
.video-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  padding: 10px;
  margin-bottom: 10px;
}

.video-card-trigger {
  display: flex;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
}

.video-thumb-wrap {
  position: relative;
  flex-shrink: 0;
  width: 100px;
  height: 56px;
}

.video-thumb {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
  background: var(--bg);
}

.video-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.video-title {
  margin: 0;
  font-size: 14px;
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.video-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--muted);
}

.video-channel-avatar {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.video-badges {
  display: flex;
  gap: 6px;
}

/* .badge-external은 임베드가 막힌 영상이 유튜브로 나간다는 예고 —
   중립 톤이라 .badge-short와 같은 스타일을 공유한다. */
.badge-short,
.badge-external {
  font-size: 11px;
  color: var(--muted);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  padding: 1px 6px;
}

.badge-ad {
  font-size: 11px;
  color: var(--trust);
  border: 1px solid var(--trust);
  border-radius: var(--radius-chip);
  padding: 1px 6px;
}

/* 지도 위에서는 <button>(V10 — 눌러서 바로 재생), 카드 시트 안에서는
   <div>로 쓰인다. 버튼 기본 스타일만 걷어내면 두 쓰임이 같아진다. */
.marker-avatar-stack {
  position: relative;
  display: flex;
  padding: 6px 10px 6px 4px;
  border: none;
  background: none;
  font-family: var(--font-body);
  cursor: pointer;
}

.marker-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid var(--sheet);
  object-fit: cover;
  background: var(--surface);
  margin-left: -6px;
}

.marker-avatar:first-child {
  margin-left: 0;
}

.marker-avatar-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-display);
  font-size: 12px;
}

/* level<=4(동네) 뷰포트 내 1급 상위 20개용 네임태그 알약 마커
   (CustomOverlay). 다크 알약 + 헤어라인 + 좌측 앰버 도트 + 흰 가게명. */
.marker-nametag {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px 5px 8px;
  border-radius: var(--radius-chip);
  background: var(--sheet);
  border: 1px solid var(--hairline);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  white-space: nowrap;
  cursor: pointer;
}

.marker-nametag-dot {
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--trust);
}

.marker-nametag-label {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
}

/* V8: 네임태그가 없는 마커(도트+링/소형 점/일반 원형) 호버 시 뜨는 소형
   식별 툴팁. .marker-nametag 스타일을 재사용하되 클릭 불가 — 마우스
   이벤트가 아래 마커로 통과해야 하므로 pointer-events는 항상 없앤다. */
.marker-tooltip {
  pointer-events: none;
}

/* V8: 리스트 행 호버로 강조된 네임태그 — 링 굵게 + 살짝 스케일업. */
.marker-nametag.marker-hover-emphasis {
  transform: scale(1.08);
  box-shadow: 0 0 0 2px var(--trust), 0 2px 6px rgba(0, 0, 0, 0.35);
}

/* V8: 마커 호버로 강조된 리스트 행 — 밝힌 서페이스 + 좌측 앰버 바.
   보더만큼 좌측 패딩을 줄여 하이라이트 시 본문이 밀리지 않게 한다. */
.list-item-hover {
  background: color-mix(in srgb, var(--surface) 85%, white 15%);
  border-left: 3px solid var(--trust);
  padding-left: 1px;
}

/* 마커 탭 → 카드 시트(V4). 화면 하단 고정, 슬라이드업으로 열고 닫는다. */
.card-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  max-height: 45vh;
  overflow-y: auto;
  background: var(--sheet);
  border-top: 1px solid var(--hairline);
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.35);
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom, 0px));
  transform: translateY(100%);
  transition: transform 200ms ease;
}

.card-sheet.open {
  transform: translateY(0);
}

/* V11 데스크톱: 카드가 마커 위에 직접 뜬다 — 왼쪽 패널은 목록만 맡고,
   고른 가게 이야기는 지도 위에서 끝난다. 아래 padding은 마커를 가리키는
   꼬리 자리이고, 오버레이 기준점(yAnchor 1)이 그 아래 끝이라 꼬리 끝이
   마커에 닿는다. */
.place-card-overlay {
  position: relative;
  width: 300px;
  padding-bottom: 14px;
}

.place-card-overlay .place-card {
  background: var(--surface);
  border: 1px solid var(--trust);
  border-radius: var(--radius-card);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
  padding: 14px;
  max-height: 60vh;
  overflow-y: auto;
  overflow-x: hidden;
}

.place-card-overlay::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 7px;
  width: 14px;
  height: 14px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--surface);
  border-right: 1px solid var(--trust);
  border-bottom: 1px solid var(--trust);
}

.place-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.place-card-name {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 400;
  color: var(--text);
  margin: 0;
}

.place-card-category {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--muted);
}

.place-card-close {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-2);
  font-size: 14px;
  line-height: 1;
}

.place-card-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
}

.place-card-closed {
  flex-basis: 100%;
  margin: 2px 0 0;
  font-size: 12px;
}

.place-card-summary {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--text-2);
}

.place-card-note {
  font-family: "Gowun Batang", serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-2);
  margin: 8px 0 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 재생 가능한 영상이 있으면 이 줄 전체가 버튼이 된다(V10). */
.place-card-channels {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  text-align: left;
  font-family: var(--font-body);
}

button.place-card-channels {
  cursor: pointer;
}

.place-card-play {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 12px;
  color: var(--accent);
  white-space: nowrap;
}

/* 지도에서 받아온 재생 데크는 값만 담은 자리라 화면에 보이지 않는다 —
   플레이어는 오버레이로 뜬다. */
.video-deck {
  display: none;
}

.place-card-avatar-stack {
  padding: 0 6px 0 0;
}

/* 300px 오버레이 카드에서는 채널명 + "영상 N편 바로 보기"가 한 줄에 다
   들어가지 않는다 — 재생 안내는 온전히 남기고 채널명 쪽을 줄인다. */
.place-card-channel-label {
  font-size: 12px;
  color: var(--muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 큐레이션 입력(개발 전용) — 카드 안에서 한 줄 적고 Enter. */
.curation {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* 카드가 300px라 감정 칩과 입력창을 한 줄에 두면 입력창이 눌린다 —
   칩을 윗줄로 빼서 입력창이 카드 폭을 다 쓰게 한다. */
.curation-sentiments {
  display: flex;
  gap: 4px;
  flex-basis: 100%;
}

.curation-chip {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  padding: 2px 8px;
  background: var(--sheet);
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 12px;
  cursor: pointer;
}

.curation-chip.active {
  background: var(--trust);
  border-color: var(--trust);
  color: var(--on-accent);
}

.curation-text {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 5px 8px;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13px;
}

.curation-save {
  border: 1px solid var(--trust);
  border-radius: 8px;
  padding: 5px 10px;
  background: transparent;
  color: var(--trust);
  font-family: var(--font-body);
  font-size: 13px;
  cursor: pointer;
}

.curation-result {
  flex-basis: 100%;
  margin: 0;
  font-size: 11px;
  color: var(--muted);
}

.place-card-address {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--text-2);
}

.place-card-actions {
  display: flex;
  gap: 8px;
  margin-top: 14px;
}

.place-card-cta,
.place-card-kakao {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  box-sizing: border-box;
  border-radius: var(--radius-cta);
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: bold;
  text-decoration: none;
}

.place-card-cta {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 50%, transparent);
}

.place-card-kakao {
  border: 1px solid var(--hairline);
  background: transparent;
  color: var(--muted);
  font-weight: normal;
}

.marker-avatar-badge {
  position: absolute;
  top: 0;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 10px;
  line-height: 16px;
  text-align: center;
  font-weight: bold;
}

/* V9 재생 어포던스 — 썸네일 위 배지로 "누르면 어떻게 되는지"를 미리
   알린다: ▶는 사이트 안에서 바로 재생, ↗는 업로더가 임베드를 막아
   유튜브로 나가는 영상. */
.video-play-badge {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.62);
  color: #fff;
}

/* 삼각형은 좌우 여백이 달라 보여 시각 중심을 1px 민다. */
.video-card-playable .video-play-badge svg {
  margin-left: 1px;
}

/* 롱폼 인라인 재생: 썸네일 자리를 카드 폭 전체의 16:9 플레이어로 바꾼다.
   지도는 그대로 남아 있으므로 영상을 보면서 위치를 계속 확인할 수 있다. */
.video-card-playing .video-thumb-wrap {
  display: none;
}

/* 400px 패널에서는 100%가 곧 카드 폭이지만, 전체 페이지 상세(모바일·딥링크
   레이아웃이 넓은 화면에도 그대로 쓰인다)에서는 100%가 1500px를 넘어
   플레이어만 화면을 채운다 — 상한을 둔다. 닫기 버튼도 이 상자 안에서
   오른쪽 정렬되므로 플레이어 오른쪽 끝과 항상 맞는다. */
.video-player-box {
  max-width: 560px;
}

.video-player {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  margin-bottom: 6px;
  border-radius: 8px;
  overflow: hidden;
  background: #000;
}

.video-player iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* 플레이어 아래 오른쪽 정렬 — 유튜브 플레이어를 덮지 않는 자리. */
.video-player-close {
  display: block;
  margin: 0 0 8px auto;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  padding: 3px 10px;
  background: var(--sheet);
  color: var(--text-2);
  font-family: var(--font-body);
  font-size: 12px;
  cursor: pointer;
}

/* V9 쇼츠 오버레이 — 9:16을 400px 패널에 넣으면 높이가 700px를 넘어 패널을
   통째로 잡아먹으므로 화면 중앙에서 크게 재생한다. 높이만 확정 축으로 두고
   너비는 비율로 파생시키되, 좁은 화면에서 너비가 넘치지 않도록 뷰포트
   폭 기준값을 min()에 함께 넣는다(오른쪽 ▲▼ 컬럼과 여백 몫을 뺀 값). */
/* <dialog>.showModal()이 최상위 레이어에 올려 주므로 z-index가 필요 없고,
   어둡게 까는 배경은 ::backdrop이 맡는다. dialog의 기본 스타일(테두리·흰
   배경·max-width/height·자동 마진)은 전부 걷어내고 뷰포트를 채운다. */
.video-overlay {
  position: fixed;
  inset: 0;
  /* dialog 기본값이 fit-content라 auto로 되돌려야 inset:0이 뷰포트를
     채운다. 100vw/100dvh를 직접 주면 스크롤바 폭까지 포함해 오른쪽
     ✕ 버튼이 화면 밖으로 밀려난다. */
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  margin: 0;
  border: 0;
  padding: 16px;
  background: transparent;
  color: var(--text);
  overflow: hidden;
}

.video-overlay[open] {
  display: flex;
  align-items: center;
  justify-content: center;
}

.video-overlay::backdrop {
  background: rgba(0, 0, 0, 0.86);
}

.video-overlay-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.video-overlay-dialog {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.video-overlay-stage {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 같은 오버레이가 쇼츠(9:16)와 롱폼(16:9)을 모두 받는다. 어느 쪽이든
   확정 축을 하나만 두고 나머지는 비율로 파생시킨다 — 양쪽을 다 고정하면
   비율이 깨져 플레이어 안에 검은 여백이 생긴다. min()에 뷰포트 반대 축
   기준값을 함께 넣어 좁거나 낮은 화면에서도 넘치지 않게 한다(오른쪽
   ▲▼ 컬럼과 여백 몫 110px을 뺀다). */
.video-overlay-player {
  border-radius: 14px;
  overflow: hidden;
  background: #000;
}

.video-overlay-player.is-short {
  aspect-ratio: 9 / 16;
  width: auto;
  height: min(76vh, calc((100vw - 110px) * 16 / 9), 720px);
}

.video-overlay-player.is-wide {
  aspect-ratio: 16 / 9;
  height: auto;
  width: min(calc(100vw - 110px), calc(76vh * 16 / 9), 1000px);
}

.video-overlay-player iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.video-overlay-nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.video-overlay-nav-btn {
  width: 40px;
  height: 40px;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}

.video-overlay-nav-btn:disabled {
  opacity: 0.35;
  cursor: default;
}

.video-overlay-counter {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.video-overlay-caption {
  width: min(100%, 420px);
  text-align: center;
}

.video-overlay-title {
  margin: 0;
  font-size: 14px;
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.video-overlay-meta {
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--muted);
}

.video-overlay-external {
  display: inline-block;
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-2);
  text-decoration: none;
  border-bottom: 1px solid var(--hairline);
}

/* 모달 dialog가 뒤 화면의 조작 자체는 막아 주지만 스크롤까지 막지는
   않는다. 지도 화면은 body가 원래 스크롤되지 않아(.map-screen이
   100dvh) 무해하고, body가 실제로 스크롤되는 전체 페이지 상세에서만
   효과가 있다. */
body.overlay-open {
  overflow: hidden;
}

/* 화면에는 안 보이되 스크린리더에는 읽히는 라벨. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* 데스크톱 2패널(≥900px): 좌 정보 패널 400px + 우 전체 높이 지도.
   grid-area로 배치하므로 index.html.erb의 DOM 순서는 그대로 둔다.
   모바일(<900px)은 기존 세로 flex 스택 그대로 유지. */
@media (min-width: 900px) {
  .map-screen {
    display: grid;
    grid-template-columns: 400px 1fr;
    grid-template-rows: auto auto 1fr;
    grid-template-areas:
      "header map"
      "chips  map"
      "list   map";
    overflow: hidden;
  }

  /* 모바일 오버레이용 묶음을 풀어, 워드마크·칩이 그리드 자식으로 남게 한다. */
  .map-top {
    display: contents;
  }

  .wordmark-row {
    grid-area: header;
  }

  .chip-rows {
    grid-area: chips;
  }

  .map-wrap {
    grid-area: map;
    height: 100%;
    min-height: 0;
  }

  .map-canvas {
    height: 100%;
    min-height: 0;
  }

  .bottom-sheet {
    grid-area: list;
    height: 100%;
    max-height: none;
    min-height: 0;
    border-top: none;
    border-radius: 0;
    box-shadow: none;
  }

  /* V11: 데스크톱에서는 카드가 지도 위 마커 오버레이로 뜬다 — 패널 안의
     카드 자리는 더 이상 쓰지 않는다(목록이 패널 전체를 쓴다). */
  .card-sheet {
    display: none;
  }
}

/* 큐레이션 검색(개발 전용) — 지도에 안 뜨는 가게를 이름으로 찾는 칸과 결과. */
.curation-search {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 8px;
  padding: 9px 12px;
  border: 1px solid var(--trust);
  border-radius: var(--radius-cta);
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
}

.curation-hit {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--divider);
}

.curation-hit-head {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

/* 왜 지도에 안 뜨는지 — 폐업 기록이나 좌표 결측. */
.item-pill-hidden {
  border: 1px solid var(--closed);
  color: var(--closed);
}

/* 공공데이터에 없는 가게를 직접 추가하는 폼(개발 전용). */
.curation-add {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 8px 0 16px;
  padding: 12px;
  border: 1px dashed var(--trust);
  border-radius: var(--radius-card);
  background: var(--surface);
}

.curation-add-title {
  margin: 0;
  font-size: 12px;
  color: var(--trust);
}

.curation-add input,
.curation-add select {
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 6px 8px;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13px;
}

/* 좌표를 찍기 전과 후를 눈으로 구분해야 한다 — 이름만 채우고 저장을
   눌렀다가 거절당하는 흐름을 줄인다. */
.curation-add-point {
  margin: 0;
  font-size: 11px;
  color: var(--muted);
}

.curation-add-point.is-set {
  color: var(--open);
}

/* 좌표 없는 가게에 위치를 찍어주는 버튼 — 평가만 적으면 지도에 안 올라가므로
   위치가 먼저라는 것을 눈에 띄게 둔다. */
.curation-locate {
  align-self: flex-start;
  border: 1px solid var(--closed);
  border-radius: var(--radius-chip);
  padding: 3px 10px;
  background: transparent;
  color: var(--closed);
  font-family: var(--font-body);
  font-size: 12px;
  cursor: pointer;
}

/* ─── 채널 신뢰도 배지 ────────────────────────────────────────────────
   등수를 붙이지 않고 잘하는 채널만 표시한다. 지역 유튜버를 키워서 같이 가는
   구조라 공개로 깎는 표시는 두지 않는다. --trust는 교차검증 배지와 같은 색으로,
   "근거가 두껍다"는 신호를 화면에서 한 계열로 묶는다. */
.badge-trusted {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid color-mix(in srgb, var(--trust) 45%, transparent);
  border-radius: var(--radius-chip);
  color: var(--trust);
  font-size: 10.5px;
  line-height: 1.5;
  white-space: nowrap;
}

/* ==========================================================================
   모바일 터치 레이어
   ==========================================================================
   손가락 입력에만 해당하는 규칙을 여기 모은다. 위쪽 본문은 레이아웃과
   색·위계를 맡고, 이 아래는 "눌리는 느낌"만 맡는다 — 둘을 섞으면 나중에
   어느 쪽이 무엇을 고쳤는지 못 읽는다.

   기준: 터치 타깃 44px(Apple HIG) / 48dp(Material)의 낮은 쪽인 44px.
   ========================================================================== */

/* --- 전역 탭 기본값 ------------------------------------------------------ */

/* 탭할 때마다 회색 사각형이 번쩍이는 기본 동작을 끈다. 대신 아래에서
   :active로 직접 피드백을 준다 — 끄기만 하고 대체를 안 주면 "안 눌렸다"가
   된다. */
button,
a,
.chip,
.list-item,
.video-card-trigger,
.curation-chip {
  -webkit-tap-highlight-color: transparent;
}

/* 버튼·링크는 더블탭 확대 대상이 아니다. 이걸 안 주면 iOS가 두 번째 탭을
   기다리느라 첫 탭 반응이 약 300ms 늦는다. */
button,
a[href],
.chip,
.list-item {
  touch-action: manipulation;
}

/* 가로 스크롤 칩 줄이 끝에 닿았을 때 페이지가 좌우로 딸려가지 않게. */
.chip-row {
  overscroll-behavior-x: contain;
  touch-action: pan-x;
}

/* --- 눌림 피드백 --------------------------------------------------------- */

/* 서버 응답을 기다리는 동안 화면이 죽어 보이지 않게 하는 최소한의 신호.
   transform은 레이아웃을 건드리지 않아 리플로우가 없다. */
.chip:active,
.expand-btn:active,
.place-card-cta:active,
.place-card-kakao:active,
.curation-chip:active,
.video-card-trigger:active {
  transform: scale(0.97);
  transition: transform 60ms ease-out;
}

.chip:active {
  background: var(--hairline);
}

.list-item:active,
.video-card:active {
  background: var(--surface);
}

.place-card-close:active,
.video-player-close:active,
.video-overlay-close:active,
.video-overlay-nav-btn:active {
  background: var(--hairline);
  transform: scale(0.92);
}

/* 키보드 이동 경로도 같이 살린다 — :active만 주면 탭 이동 시 지금 어디에
   있는지 보이지 않는다. :focus-visible이라 마우스 클릭에는 안 뜬다. */
.chip:focus-visible,
.expand-btn:focus-visible,
.list-item:focus-visible,
.place-card-close:focus-visible,
.place-card-cta:focus-visible,
.place-card-kakao:focus-visible,
.video-card-trigger:focus-visible,
.video-overlay-close:focus-visible,
.video-overlay-nav-btn:focus-visible,
.sheet-handle:focus-visible {
  outline: 2px solid var(--trust);
  outline-offset: 2px;
}

/* --- 안전영역 ------------------------------------------------------------ */

/* 상태바가 black-translucent라 콘텐츠가 노치/다이나믹 아일랜드 밑으로
   들어간다. 워드마크가 첫 요소이므로 여기서 밀어 준다. */
.wordmark-row {
  padding-top: calc(14px + env(safe-area-inset-top, 0px));
}

/* 가로 모드에서 노치가 있는 쪽 여백. 지도 캔버스는 일부러 제외한다 —
   지도는 화면 끝까지 차는 편이 낫고, 그 위 컨트롤만 피하면 된다. */
.wordmark-row,
.chip-rows {
  padding-left: max(12px, env(safe-area-inset-left, 0px));
  padding-right: max(12px, env(safe-area-inset-right, 0px));
}

/* --- 터치 타깃 44px ------------------------------------------------------ */

/* 마우스에는 지금 크기가 알맞다. 손가락일 때만 키운다. */
@media (pointer: coarse) {
  .chip {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 14px;
  }

  /* 둘째·셋째 줄 칩을 더 작게 줄이던 규칙(padding 5px 10px / 13px)을
     되돌린다 — 글자만 작게 두고 누르는 면적은 같이 유지한다. */
  .chip-row + .chip-row .chip {
    min-height: 44px;
    padding: 0 12px;
    font-size: 13px;
  }

  .chip-row {
    gap: 8px;
  }

  .expand-btn {
    min-height: 44px;
  }

  .list-item {
    padding: 14px 4px;
    min-height: 44px;
  }

  /* 28px·36px·40px짜리 닫기·이동 버튼들. 보이는 원은 그대로 두고 누르는
     면적만 ::after로 넓힌다 — 원을 키우면 카드 헤더 균형이 깨진다. */
  .place-card-close,
  .video-player-close,
  .video-overlay-close,
  .video-overlay-nav-btn {
    position: relative;
  }

  .place-card-close::after,
  .video-player-close::after,
  .video-overlay-close::after,
  .video-overlay-nav-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }
}

/* --- 3단 드래그 바텀시트 -------------------------------------------------- */

/* 지도 앱 표준: peek(가게 한 장) / half(현재) / full(목록 전체)을 핸들
   드래그와 플릭으로 오간다. 데스크톱(≥900px)은 시트가 아니라 좌측 그리드
   패널이므로 이 블록 전체를 적용하지 않는다. */
@media (max-width: 899px) {
  .map-screen {
    position: relative;
  }

  /* 시트가 지도 위에 뜨므로 캔버스는 남는 세로를 전부 쓴다. 시트가 커져도
     지도 크기가 바뀌지 않아 카카오 relayout()을 부를 일이 없다. */
  .map-canvas {
    flex: 1;
    min-height: 0;
  }

  .bottom-sheet {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
    /* border-box여야 --sheet-h가 곧 눈에 보이는 높이가 된다. content-box로
       두면 드래그가 시작 높이를 getBoundingClientRect()(=패딩·보더 포함)로
       잡고 끝에서 content 높이로 되돌려 놓아, 만질 때마다 시트가 그
       차이만큼 자란다. */
    box-sizing: border-box;
    height: var(--sheet-h, 35dvh);
    max-height: none;
    overflow: visible;
    padding: 0 16px calc(8px + env(safe-area-inset-bottom, 0px));
  }

  /* 드래그 중에는 손가락을 그대로 따라가야 하므로 전환을 끈다. 놓는 순간
       컨트롤러가 이 속성을 켜서 스냅 애니메이션만 보이게 한다. */
  .bottom-sheet[data-animating="true"] {
    transition: height 260ms cubic-bezier(0.32, 0.72, 0, 1);
  }

  .sheet-handle {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 28px;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: grab;
    /* 핸들 위 드래그만 브라우저에게서 뺏는다. 이 값을 시트 루트에 주면
       touch-action이 조상과 교집합으로 계산돼 안쪽 목록 스크롤까지 죽는다. */
    touch-action: none;
  }

  .sheet-handle:active {
    cursor: grabbing;
  }

  .sheet-handle::before {
    content: "";
    width: 36px;
    height: 4px;
    border-radius: 999px;
    background: var(--muted);
  }

  .sheet-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    /* 목록 끝에서 더 밀어도 지도나 페이지로 스크롤이 새지 않는다 —
       당겨서 새로고침 오발도 여기서 막힌다. */
    overscroll-behavior: contain;
    touch-action: pan-y;
  }

  /* peek에서는 목록이 한 장만 보이면 되므로 범위 확장 버튼은 접는다 —
     12dvh 안에서 버튼이 목록을 다 밀어낸다. */
  .bottom-sheet[data-snap="peek"] .expand-btn,
  .bottom-sheet[data-snap="peek"] .curation-search {
    display: none;
  }
}

/* --- 접근성 ------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* 데스크톱(≥900px)은 시트가 좌측 그리드 패널이라 핸들이 필요 없다.
   .sheet-scroll도 높이 제약 없이 흘러 .bottom-sheet가 그대로 스크롤한다. */
@media (min-width: 900px) {
  .sheet-handle {
    display: none;
  }
}

/* --- 초대 관리 (큐레이터 자기서비스) ------------------------------------ */

/* 지도 화면(.map-screen)과 별개인 일반 페이지라 색 토큰만 재사용한다. */
.invites-page {
  min-height: 100dvh;
  box-sizing: border-box;
  background: var(--sheet);
  color: var(--text);
  padding: 16px;
  padding-top: calc(16px + env(safe-area-inset-top, 0px));
  font-family: var(--font-body);
  max-width: 480px;
  margin: 0 auto;
}

.invites-page h1 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 400;
  margin: 12px 0 4px;
}

.invites-sub {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.5;
  margin: 0 0 20px;
}

.invite-form {
  display: flex;
  gap: 8px;
  margin-bottom: 6px;
}

.invite-form input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-cta);
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  box-sizing: border-box;
}

.invite-form button {
  min-height: 44px;
  padding: 0 16px;
  border: none;
  border-radius: var(--radius-cta);
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  font-size: 14px;
  font-family: var(--font-body);
}

.invites-remaining {
  font-size: 12px;
  color: var(--muted);
  margin: 0 0 20px;
}

.invites-empty {
  color: var(--muted);
  font-size: 13px;
  padding: 16px 0;
}

.invitee-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 12px 0;
  border-bottom: 1px solid var(--divider);
}

.invitee-name {
  font-size: 15px;
  flex: 1 1 auto;
  min-width: 80px;
}

.invitee-status {
  font-size: 12px;
  padding: 3px 8px;
  border-radius: var(--radius-chip);
}

.invitee-pending {
  color: var(--trust);
  border: 1px solid var(--trust);
}

.invitee-claimed {
  color: var(--open);
}

.invitee-blocked {
  color: var(--closed);
}

/* 탭하면 전체 선택 + 복사(copy_controller) — 시스템 공유 시트가 없는
   페이지에서 카톡 등으로 옮기기 쉽게 한다. */
.invitee-link {
  flex-basis: 100%;
  min-height: 40px;
  padding: 8px 10px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-cta);
  background: var(--bg);
  color: var(--text-2);
  font-size: 12px;
  box-sizing: border-box;
}

/* --- 관리자 화면 --------------------------------------------------------- */

.admin-section {
  margin-top: 24px;
}

.admin-section h2 {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 400;
  margin: 0 0 8px;
}

.admin-badge {
  margin-left: 6px;
  padding: 2px 6px;
  border-radius: var(--radius-chip);
  background: var(--trust);
  color: var(--bg);
  font-size: 10px;
  font-weight: 700;
}

.invitee-invited-by {
  margin-left: 6px;
  font-size: 12px;
  color: var(--muted);
}

.admin-note-count {
  font-size: 12px;
  color: var(--muted);
  min-width: 32px;
  text-align: right;
}

.admin-action {
  min-height: 32px;
  padding: 0 10px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-cta);
  background: var(--surface);
  color: var(--text-2);
  font-family: var(--font-body);
  font-size: 12px;
}

.admin-action-danger {
  border-color: var(--closed);
  color: var(--closed);
}

.admin-note-row {
  padding: 10px 0;
  border-bottom: 1px solid var(--divider);
}

.admin-note-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
}

.admin-note-restaurant {
  color: var(--text);
  font-weight: 700;
}

.admin-note-text {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--text-2);
  line-height: 1.4;
}

/* --- Admin 서브내비 · 사용량 보드(P1) ------------------------------------ */

.admin-subnav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 4px;
}

.admin-subnav-link {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 10px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  background: var(--surface);
  color: var(--text-2);
  font-size: 12px;
  text-decoration: none;
}

.admin-subnav-link.is-active {
  border-color: var(--trust);
  color: var(--trust);
  font-weight: 700;
}

.admin-subnav-link.is-disabled {
  opacity: 0.45;
  cursor: default;
}

.admin-usage-window {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--muted);
}

.admin-usage-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.admin-usage-table th,
.admin-usage-table td {
  padding: 8px 4px;
  border-bottom: 1px solid var(--divider);
  text-align: left;
}

.admin-usage-table th {
  color: var(--muted);
  font-weight: 600;
}

.admin-usage-count {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.admin-upload-note {
  margin: 0 0 10px;
  font-size: 13px;
  color: var(--text-2);
  line-height: 1.45;
}

.admin-upload-next {
  padding: 8px 10px;
  border-left: 3px solid var(--trust);
  background: var(--surface);
}

.admin-upload-form {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-top: 8px;
}

.admin-upload-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

.admin-upload-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.admin-upload-table th,
.admin-upload-table td {
  padding: 8px 4px;
  border-bottom: 1px solid var(--divider);
  text-align: left;
  vertical-align: top;
}

.admin-upload-table th {
  color: var(--muted);
  font-weight: 600;
}

.admin-upload-status {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.admin-upload-row[data-status="failed"] .admin-upload-status {
  color: #b42318;
}

.admin-upload-row[data-status="parsed"] .admin-upload-status,
.admin-upload-row[data-status="import_ready"] .admin-upload-status {
  color: var(--trust);
}

.admin-upload-error {
  color: #b42318;
  font-size: 12px;
}

.admin-upload-empty {
  color: var(--muted);
  font-size: 13px;
}

.admin-upload-filename {
  word-break: break-all;
}

/* --- Admin YouTube 판단 큐(P3) ----------------------------------------- */

.admin-yt-week {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--muted);
}

.admin-yt-week-key {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.admin-yt-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.admin-yt-card {
  padding: 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  background: var(--surface);
}

.admin-yt-card-head {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
  margin-bottom: 6px;
}

.admin-yt-title {
  font-weight: 700;
  font-size: 14px;
}

.admin-yt-proposed {
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--divider);
  color: var(--text-2);
}

.admin-yt-proposed[data-type="내돈내산"] {
  color: var(--trust);
}

.admin-yt-proposed[data-type="광고공장"] {
  color: #b42318;
}

.admin-yt-confidence {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.admin-yt-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 10px;
  font-size: 12px;
  color: var(--muted);
}

.admin-yt-url {
  color: var(--trust);
  word-break: break-all;
}

.admin-yt-channel-id {
  font-size: 11px;
}

.admin-yt-decide-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.admin-yt-feedback-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

.admin-yt-feedback {
  min-height: 32px;
  padding: 4px 8px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  font-size: 13px;
}

.admin-yt-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.admin-yt-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.admin-yt-table th,
.admin-yt-table td {
  padding: 8px 4px;
  border-bottom: 1px solid var(--divider);
  text-align: left;
  vertical-align: top;
}

.admin-yt-table th {
  color: var(--muted);
  font-weight: 600;
}

.admin-yt-action {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}


/* --- Admin P4 폴시 · 빈 상태 · 플래시 · 통계 위젯 ---------------------- */

.admin-sunday-blurb {
  margin: 8px 0 0;
  padding: 8px 10px;
  border-left: 3px solid var(--hairline);
  background: var(--surface);
  font-size: 12px;
  color: var(--muted);
  line-height: 1.45;
}

.admin-sunday-blurb code {
  font-size: 11px;
  color: var(--text-2);
}

.admin-flash {
  margin: 10px 0 0;
}

.admin-flash-notice,
.admin-flash-alert {
  margin: 0 0 6px;
  padding: 8px 10px;
  border-radius: var(--radius-cta);
  font-size: 13px;
  line-height: 1.4;
}

.admin-flash-notice {
  background: color-mix(in srgb, var(--trust) 18%, var(--surface));
  color: var(--text);
  border: 1px solid var(--trust);
}

.admin-flash-alert {
  background: color-mix(in srgb, var(--closed) 16%, var(--surface));
  color: var(--text);
  border: 1px solid var(--closed);
}

.admin-empty {
  margin: 0;
  padding: 16px 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.45;
}

.admin-empty code {
  font-size: 12px;
  color: var(--text-2);
}

.admin-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 0;
}

.admin-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 64px;
  padding: 8px 10px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-chip);
  background: var(--surface);
}

.admin-stat-n {
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  line-height: 1.1;
}

.admin-stat-l {
  margin-top: 2px;
  font-size: 11px;
  color: var(--muted);
}
