/* ══════════════════════════════════════════════════════════════
   Podosul 홈페이지 전용 스타일 (index.html에서 참조)
   ══════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* 페이지 스크롤바는 html이 담당한다.
   scrollbar-gutter: stable로 공간을 미리 예약해 스크롤바 등장/소멸 시 좌우 흔들림을 방지한다.
   ※ theme.css에도 동일 선언이 있으나 index.html은 theme.css를 직접 import하지 않으므로 여기서도 선언 유지. */
html { scrollbar-gutter: stable; }

:root {
  --bg:        #0f0d13;
  --surface:   #1a1724;
  --card:      #221e2e;
  --border:    #2e2940;
  --accent:    #c084fc;
  --accent2:   #818cf8;
  --gold:      #fbbf24;
  --text:      #e2dff0;
  --muted:     #7c748e;
  --danger:    #f87171;
  --success:   #4ade80;
  --radius:    14px;
  --radius-sm: 8px;
  /* rgba() 합성용 RGB 트리플 — theme.css 와 같은 값 (index.html 은 theme.css 미로드) */
  --bg-rgb:    15, 13, 19;         /* --bg #0f0d13 */
  --muted-rgb: 124, 116, 142;      /* --muted #7c748e */
  --accent-rgb: 192, 132, 252;     /* --accent #c084fc */
  /* 와인 이미지 상자 (2026-10-02) — 로컬 썸네일(비비노 268×960 투명 PNG · 데일리샷 정사각 흰 배경)을
   * object-fit: contain 으로 전체가 보이게. 상자 배경은 흰색 하나로 통일(투명 PNG·흰 배경 사진 모두 경계 없음).
   * 검색 카드 .card-img-wrap · 상세 .wd-image-card · 나의 와인 .mw-thumb 가 모두 이 토큰을 쓴다. */
  --card-img-bg:  #fff;
  --card-img-fit: 92%;             /* 이미지가 상자에서 차지하는 최대 비율 — 위아래 4% 씩 여백 */

  /* 와인잔 뱃지 (2026-10-02, js/my-wine-glass.js) — 검색 카드 "나의 와인" 등록 표시. 확정 시안 "골드 링".
   * 색·크기는 여기 한 곳에서 바꾼다(도형은 js 의 SHAPE 상수). cqw 는 .card-img-wrap 폭 기준. */
  --glass-wine-top:    #e0446e;    /* 와인 그라데이션 위(루비) */
  --glass-wine-bottom: #7a1233;    /* 와인 그라데이션 아래(버건디) */
  --glass-wine-back:   #f08aa6;    /* 뒤 물결 — 밝은 톤 */
  --glass-line:        #55505c;    /* 빈 잔 윤곽선 */
  --glass-line-on:     #8c1c3f;    /* 채워진 잔 윤곽선 */
  --glass-gloss:       #fff;       /* 유리 광택 한 줄 */
  --glass-ring:        #e2b04a;    /* 등록된 잔의 칩 둘레 금색 링 */
  --glass-ring-w:      2.5px;
  --glass-chip-bg:     rgba(255, 255, 255, .96);
  --glass-plus-bg:     linear-gradient(145deg, var(--glass-wine-top), var(--glass-wine-bottom));   /* + 원 배경 */
  --glass-plus-fg:     #fff;                         /* + 기호·테두리 */
  --glass-right:       8px;                          /* 오른쪽 여백 — 카테고리 배지(.kind-overlay right)와 같은 선 */
  --glass-top-solo:    8px;                          /* 카테고리 배지가 없는 카드: 배지 자리(우상단)로 올라간다 */
  --glass-size:        clamp(26px, 15.5cqw, 36px);   /* 원형 칩 지름 — 카드 폭 230px 에서 36px */
  --glass-touch:       44px;                         /* 잔 터치 영역 지름 (::before 로 확장) */
  /* 카테고리 배지(top 8 + 높이 19 = 27px) 바로 아래. 금색 링(2.5px)·+ 가 칩 위로 튀어나오므로 그만큼 간격을 둔다 */
  --glass-top:         calc(27px + clamp(5px, 3.5cqw, 9px));
  --glass-plus-min:    13px;       /* + 원 최소 지름 (칩의 42% 가 이보다 작아지는 모바일용) */
  --glass-plus-border: clamp(1.5px, .8cqw, 2px);
  --glass-fill-ms:     1s;         /* 방금 추가됐을 때 차오르는 시간 */

  /*
   * 콘텐츠 기준선 SSOT (2026-10-01).
   * 헤더 inner·최근 검색어·필터 바·상태바·결과 영역이 모두 같은 최대 폭과 좌우 패딩을 공유해
   * 왼쪽 정렬선이 한 줄로 맞는다. 브레이크포인트에서는 --content-pad만 재정의한다
   * (≤1023px: 20px, ≤767px: 12px). 각 셀렉터에 px를 다시 쓰지 말 것.
   */
  --content-max: 1280px;
  --content-pad: 24px;

  /* 타이포그래피 — theme.css의 --font-base와 동일 스택 유지 (index.html은 theme.css 미로드) */
  --font-base: 'Pretendard Variable', Pretendard, -apple-system, system-ui,
               'Apple SD Gothic Neo', 'Noto Sans KR', 'Segoe UI', 'Malgun Gothic', sans-serif;

  /*
   * --columns: 컬럼 수의 단일 진리원천(SSOT).
   * PC 기본 5열, 태블릿 3열, 모바일 3열로 아래 미디어쿼리에서 자동 분기된다.
   * 이 값이 2~6 범위로 변하면 calc()/clamp()가 폰트·패딩·오버레이를 자동 조정한다.
   * PC 컬럼 수 변경 시 config.js의 columnsPerRow(=pageSize 계산용)도 함께 갱신해야 한다.
   */
  --columns: 5;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-base);
  min-height: 100vh;
  /*
   * 하단 네비(.bottom-nav)가 fixed로 떠 있으므로 페이지 본문이 가려지지 않도록 여백 확보.
   * 네비 높이(약 64px) + 외부 패딩(16px) + 안전영역(env(safe-area-inset-bottom)).
   * 모바일 브라우저 노치/제스처 영역까지 자동 회피.
   */
  padding-bottom: calc(80px + env(safe-area-inset-bottom, 0px));
}

/* ── Header ── */
header {
  background: linear-gradient(135deg, #1e1530 0%, #0f0d13 100%);
  border-bottom: 1px solid var(--border);
  padding: 20px 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  position: relative;
}

/* ── 사이트 헤더 레이아웃 (index.html 전용) ──
 * 2026-10-01: 헤더 = [타이틀][검색창][로그인/프로필] 한 줄 (사용자 승인 시안 index-proto 이관).
 * - 위 `header {}` 요소 규칙은 index-page.css를 import하는 label.html(<header class="label-header">)에도
 *   닿으므로 건드리지 않고, 새 레이아웃은 header.site-header / .site-header__* 범위로만 적용한다.
 * - .site-header__inner가 검색 결과 영역(.results-wrap / .filter-bar: max-width 1280px, padding 0 24px)과
 *   같은 좌우 기준선 → 타이틀·검색창이 결과 그리드와 왼쪽 정렬로 맞는다. (요소 header의 좌우 패딩은
 *   0으로 두고 inner가 패딩을 가진다.)
 * - 검색창(.search-card)은 #homeView 밖(헤더)에 있어 와인 상세가 열려 있어도 보인다
 *   → index-page.js doSearch()가 상세를 먼저 닫는다. */
header.site-header {
  justify-content: flex-start;
  padding: 14px 0;
}
.site-header__inner {
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 var(--content-pad);
  display: flex;
  align-items: center;
  gap: 24px;
}
/* 타이틀(아이콘 + 로고 + 부제) — 고정 폭, 줄바꿈 없음 */
.site-header__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
}

/* 헤더 맨 오른쪽 — 로그인/프로필 슬롯 (auth.js 상태에 따라 토글)
 * 2026-10-01: absolute 배치 → flex 흐름(margin-left:auto)으로 전환. 검색창이 헤더 가운데를 차지하므로
 * 겹치지 않게 흐름 안에서 오른쪽 끝에 붙인다. */
.header-auth-slot {
  flex: none;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.header-auth-slot__login {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  background: rgba(255, 255, 255, .06);
  border: 1px solid var(--border);
  border-radius: 999px;
  text-decoration: none;
  transition: border-color .15s, background .15s;
  cursor: pointer;
}
.header-auth-slot__login:hover {
  border-color: var(--accent);
  background: rgba(192, 132, 252, .1);
  color: var(--accent);
}

.header-auth-profile {
  position: relative;
}

.header-auth-profile__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px 4px 4px;
  background: rgba(255, 255, 255, .06);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  transition: border-color .15s;
}
.header-auth-profile__btn:hover { border-color: var(--accent); }

.header-auth-profile__avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 800;
  overflow: hidden;
}
.header-auth-profile__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.header-auth-profile__name {
  max-width: 120px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 드롭다운 메뉴 */
.header-auth-profile__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 180px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 250;
}
.header-auth-profile__menu[hidden] { display: none; }
.header-auth-profile__menu-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 9px 12px;
  font-size: 13px;
  color: var(--text);
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
  transition: background .12s, color .12s;
}
.header-auth-profile__menu-item:hover {
  background: rgba(192, 132, 252, .12);
  color: var(--accent);
}

/* 모바일 좁은 화면 — 헤더 패딩 축소, 닉네임 숨김
 * (header 요소 패딩은 label.html에도 닿는 규칙이라 유지. index.html은 header.site-header 규칙이
 *  specificity로 이기므로 767px 블록의 값이 적용된다. 슬롯은 flex 흐름이라 right 보정 불필요.) */
@media (max-width: 480px) {
  header { padding: 16px 14px; }
  .header-auth-profile__name { display: none; }
  .header-auth-profile__btn { padding: 4px; }
}
.logo {
  font-size: 24px;
  font-weight: 800;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  letter-spacing: -0.5px;
}
.logo-sub {
  font-size: 13px;
  color: var(--muted);
  margin-top: 2px;
}
/* 썸네일 출처 미리보기 배지 (2026-10-02) — URL ?thumb=local|cdn 일 때만 JS(thumb-preview.js)가
 * .logo 바로 뒤에 생성. 문구는 "썸네일: 로컬 미리보기" / "썸네일: CDN", 응답 thumbnailSource 로 갱신. */
.thumb-preview-badge {
  display: inline-block;
  vertical-align: middle;
  margin-left: 8px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--gold);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.thumb-preview-badge[data-thumb-source="cdn"] { color: var(--accent); }

/* ── 스태프 전용 사진 출처 배지 (2026-10-02, js/image-source-badge.js) ──
 * admin/operator 로그인 + imageSource dailyshot("wr") / cdn("cdn") 일 때만 JS 가 이미지 상자에 추가.
 * 4코너 배지(국기·카테고리·빈티지·평점)와 겹치지 않도록 이미지 상자 상단 중앙, z-index 는 코너 배지와 동급(2).
 * 적용 상자: 검색 카드 .card-img-wrap · 상세 .wd-image-card__inner · 나의 와인 .mw-thumb (모두 position:relative). */
.img-source-badge {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0;
  color: #fff;
  background: rgba(var(--bg-rgb), .82);
  border: 1px solid rgba(255,255,255,.22);
  box-shadow: 0 2px 6px rgba(0,0,0,.45);
  pointer-events: none;
  z-index: 2;
}
.img-source-badge--cdn {
  background: rgba(var(--muted-rgb), .85);
  font-size: 8px;
}
/* 나의 와인 리스트 행 썸네일 — 소형 */
.img-source-badge--sm {
  top: 3px;
  width: 14px;
  height: 14px;
  font-size: 7px;
  border-width: 0;
}
.img-source-badge--sm.img-source-badge--cdn { font-size: 6px; }
/* 상세 이미지 카드 — 코너 배지와 같은 cqw 기준 상단 여백 */
.wd-image-card__inner > .img-source-badge { top: clamp(8px, 2.2cqw, 12px); }
@media (max-width: 767px) {
  .img-source-badge:not(.img-source-badge--sm) { width: 18px; height: 18px; font-size: 9px; }
  .img-source-badge--cdn:not(.img-source-badge--sm) { font-size: 7px; }
}

/* ── Search Box (헤더 안) ──
 * 2026-10-01: 검색창을 헤더 타이틀 오른쪽으로 이동 (사용자 승인 시안 index-proto 이관).
 * - 기존 .search-wrap(800px 카드 블록)은 제거. .search-card는 더 이상 카드(배경·테두리·패딩)가 아니라
 *   .site-header__inner flex 행에서 타이틀과 로그인 슬롯 사이를 채우는 가변 폭 슬롯이다.
 * - 왼쪽 기준선은 .site-header__inner가 결과 영역(1280px)과 맞춘다.
 * - 헤더 한 줄 높이에 맞춰 입력창 상하 패딩 11px·15px 글자, 검색 버튼 좌우 22px (시안 값). */
.search-card {
  flex: 1 1 auto;
  min-width: 0; /* flex item 기본 min-width:auto 오버라이드 — 긴 placeholder가 행을 밀지 않게 */
}
.input-row {
  display: flex;
  gap: 12px;
  align-items: stretch;
}
.ocr-input {
  width: 100%;
  box-sizing: border-box;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 11px 18px 11px 42px; /* 왼쪽: clear-btn(X) 공간 확보 — 글자·placeholder 가 X 뒤에서 시작 */
  font-size: 15px;
  color: var(--text);
  outline: none;
  transition: border-color .2s;
}
.ocr-input:focus { border-color: var(--accent); }
.ocr-input::placeholder { color: var(--muted); }

.search-btn {
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  border: none;
  border-radius: 10px;
  padding: 0 22px;
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  cursor: pointer;
  transition: opacity .2s, transform .1s;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
}
.search-btn:hover   { opacity: .9; }
.search-btn:active  { transform: scale(.97); }
.search-btn:disabled { opacity: .45; cursor: not-allowed; }

.input-area {
  flex: 1;
  min-width: 0;
  display: flex;
}
/* input + X 버튼을 감싸는 래퍼: X 버튼의 절대 위치 기준점 */
.input-wrap {
  position: relative;
  display: flex;
  flex: 1;
}
/* 검색어 지우기 버튼 (입력창 오른쪽 끝 위에 올라탐) */
.clear-btn {
  position: absolute;
  left: 14px; /* 2026-10-01: 오른쪽 끝 → 왼쪽 끝 (사용자 요청). .ocr-input 왼쪽 패딩이 이 공간을 비워 둔다 */
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  background: none;
  border: none;
  padding: 4px;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: color .15s, background .15s;
  line-height: 0;
}
.clear-btn:hover { color: var(--text); background: rgba(255,255,255,.08); }
/* hidden 속성 존중 — 위 display:flex(클래스)가 UA [hidden]{display:none}보다 우선해 빈 입력창에서도
 * X가 보이던 기존 버그 보강 (index-page.js는 clearBtn.hidden = !ocrInput.value 로 토글한다) */
.clear-btn[hidden] { display: none; }
/* ── 최근 검색어 ──
 * 위치는 그대로(헤더 아래, 필터 바 위). 2026-10-01: 검색 결과창(.results-wrap 1280px / padding 0 24px)과
 * 같은 왼쪽 기준선으로 맞춤 (이전 800px 검색 카드 폭 기준 → 결과 영역 기준). */
.recent-wrap {
  max-width: var(--content-max);
  margin: 24px auto 0; /* 헤더 하단과 칩 사이 숨 쉴 간격 (2026-10-01 14px → 24px, 사용자 요청) */
  padding: 0 var(--content-pad);
}
/* hidden 속성이 있으면 감춤 */
.recent-wrap[hidden] { display: none; }
/* 최근 검색어가 없을 때는 필터 바가 헤더 바로 아래 오므로 같은 24px 간격을 준다
 * (있을 때: 헤더 → 24px → 칩 → 10px → 필터 바) */
.recent-wrap[hidden] + .filter-bar { margin-top: 24px; }

/* 횡 스크롤 컨테이너 — 스크롤바 숨김, 드래그 가능 */
.recent-list {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: none;        /* Firefox */
  cursor: grab;
  user-select: none;            /* 드래그 중 텍스트 선택 방지 */
  -webkit-user-select: none;
}
.recent-list::-webkit-scrollbar { display: none; } /* Chrome/Safari */
.recent-list.is-dragging {
  cursor: grabbing;
  scroll-behavior: auto;        /* 드래그 중 smooth 스크롤 비활성화 */
}

/* 개별 pill */
.recent-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
  background: rgba(255,255,255,.06);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 4px 10px 4px 12px;
  cursor: pointer;
  transition: background .15s, border-color .15s;
  white-space: nowrap;
}
.recent-pill:hover {
  background: rgba(192,132,252,.12);
  border-color: rgba(192,132,252,.4);
}
.recent-pill-label {
  font-size: 13px;
  color: var(--text);
  pointer-events: none;
  /* 긴 검색어는 ellipsis로 잘라 표시 — 약 10자(em 기준) 폭에서 자름 */
  max-width: 10em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* X 삭제 버튼 */
.recent-pill-del {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: color .15s, background .15s;
}
.recent-pill-del:hover {
  color: var(--text);
  background: rgba(255,255,255,.1);
}

/* ── 필터 & 정렬 바 ── */
.filter-bar {
  max-width: var(--content-max);
  margin: 10px auto 0;
  padding: 0 var(--content-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

/* filter-left: filter-group + prev-filter-btn 을 가로 배치하는 래퍼 */
.filter-left {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* 필터 그룹 / 정렬 그룹 — 공통 박스 스타일 */
.filter-group,
.sort-group {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 4px;
}

.filter-btn,
.sort-btn {
  position: relative; /* 정렬 우선순위 배지(.sort-badge) 앵커 */
  background: transparent;
  border: none;
  border-radius: 7px;
  padding: 5px 12px;
  font-size: 13px;
  font-family: inherit;
  color: var(--muted);
  cursor: pointer;
  transition: background .15s, color .15s;
  white-space: nowrap;
}

/* 정렬 우선순위 배지 — 버튼 좌상단의 작은 원형 숫자 */
.sort-badge {
  position: absolute;
  top: -5px;
  left: -3px;
  min-width: 14px;
  height: 14px;
  padding: 0 3px;
  border-radius: 7px;
  background: var(--accent2);
  color: var(--bg);
  font-size: 9px;
  font-weight: 700;
  line-height: 14px;
  text-align: center;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.filter-btn:hover,
.sort-btn:hover {
  background: rgba(255,255,255,.06);
  color: var(--text);
}

/* 필터 활성 상태 — 값이 설정된 경우 */
.filter-btn.is-active {
  background: rgba(192,132,252,.18);
  color: var(--accent);
  font-weight: 600;
}

/* 정렬 활성 상태 */
.sort-btn.is-active {
  background: rgba(129,140,248,.18);
  color: var(--accent2);
  font-weight: 600;
}

/* 필터 바 돋보기 검색 버튼 — 필터그룹 높이에 맞춘 라운드 박스 */
.filter-search-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 30px;
  padding: 0 11px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: background .15s, border-color .15s, color .15s;
}
.filter-search-btn:hover {
  border-color: var(--accent2);
  color: var(--text);
  background: rgba(129,140,248,.12);
}
.filter-search-btn:active {
  transform: scale(.94);
}
/* 필터가 하나 이상 설정된 경우 강조 */
.filter-search-btn.is-active {
  border-color: var(--accent);
  background: rgba(192,132,252,.18);
  color: var(--accent);
}
.filter-search-btn.is-active:hover {
  background: rgba(192,132,252,.28);
}

/* 직전필터 / 필터해제 토글 버튼 */
.prev-filter-btn {
  height: 30px;
  padding: 0 13px;
  border: 1px solid var(--border);
  border-radius: 15px;
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, opacity .15s;
  white-space: nowrap;
  flex-shrink: 0;
}
.prev-filter-btn:hover {
  border-color: var(--accent);
  color: var(--text);
}
/* 필터해제 모드 (활성 필터 존재) */
.prev-filter-btn.is-active {
  border-color: var(--accent);
  background: rgba(192,132,252,.14);
  color: var(--accent);
  font-weight: 600;
}
/* 저장된 스냅샷 없음 — 흐리게 표시 */
.prev-filter-btn.no-snapshot {
  opacity: 0.38;
  pointer-events: none;
}

/* ── 필터 팝업 ── */
/* 투명 오버레이 — 팝업 외부 클릭 감지용 (화면 어둡게 하지 않음) */
.filter-popup-overlay {
  position: fixed;
  inset: 0;
  z-index: 500;
}
.filter-popup-overlay[hidden] { display: none; }

/* 팝업 카드 — JS가 top/left를 버튼 위치 기준으로 주입 */
.filter-popup {
  position: fixed;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0,0,0,.55);
  width: 280px;
  z-index: 501;
  animation: popupIn .14s ease;
  overflow: hidden;
}
@keyframes popupIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.filter-popup-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
}
.filter-popup-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--gold);
  letter-spacing: .2px;
}
.filter-popup-header-actions {
  display: flex;
  align-items: center;
  gap: 2px;
}
.filter-clear-btn {
  background: none;
  border: none;
  font-size: 12px;
  font-family: inherit;
  color: var(--muted);
  cursor: pointer;
  padding: 3px 8px;
  border-radius: 4px;
  white-space: nowrap;
  transition: color .15s, background .15s;
}
.filter-clear-btn:hover {
  color: var(--danger);
  background: rgba(248,113,113,.08);
}
.filter-popup-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 3px 6px;
  border-radius: 4px;
  transition: color .15s, background .15s;
}
.filter-popup-close:hover {
  color: var(--text);
  background: rgba(255,255,255,.08);
}
/* body는 내부 컴포넌트가 padding을 직접 관리 */
.filter-popup-body { overflow: hidden; }

/* ── 국가 필터 — 선택된 국가 pills ── */
.filter-selected-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 14px 8px;
  border-bottom: 1px solid var(--border);
}
.filter-selected-pills[hidden] { display: none; }

.filter-selected-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: rgba(192,132,252,.15);
  border: 1px solid rgba(192,132,252,.35);
  border-radius: 20px;
  padding: 3px 6px 3px 8px;
  font-size: 12px;
  color: var(--accent);
}
.filter-selected-pill-del {
  background: none;
  border: none;
  color: var(--accent);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 2px;
  opacity: .7;
  transition: opacity .15s;
}
.filter-selected-pill-del:hover { opacity: 1; }

/* ── 국가 필터 — 검색 입력 ── */
.filter-search-wrap {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
}
.filter-search-input {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 11px;
  font-size: 13px;
  font-family: inherit;
  color: var(--text);
  outline: none;
  transition: border-color .2s;
}
.filter-search-input:focus { border-color: var(--accent); }
.filter-search-input::placeholder { color: var(--muted); }

/* ── 국가 필터 — 체크박스 리스트 ── */
.filter-list {
  max-height: 230px;
  overflow-y: auto;
  padding: 4px 0;
}
.filter-list::-webkit-scrollbar       { width: 4px; }
.filter-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.filter-list-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 14px;
  cursor: pointer;
  transition: background .12s;
  user-select: none;
}
.filter-list-item:hover    { background: rgba(255,255,255,.04); }
.filter-list-item.is-checked { background: rgba(192,132,252,.07); }

.filter-checkbox {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.filter-flag {
  width: 22px;
  height: 16px;
  object-fit: cover;
  border-radius: 2px;
  border: 1px solid rgba(255,255,255,.1);
  flex-shrink: 0;
}
.filter-selected-pill .filter-flag {
  width: 18px;
  height: 13px;
}
.filter-item-name {
  font-size: 13px;
  color: var(--text);
  flex: 1;
}
.filter-no-results {
  padding: 18px 14px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}
.filter-category-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
  outline: 1px solid rgba(255,255,255,.15);
}
.filter-variety-icon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  line-height: 1;
}

/* ── 가격 필터 — 입력 행 ── */
/* 최소/최대 입력창 + ~ 구분자를 가로 배치한다 */
.price-range-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 12px 10px;
}

/* 최소/최대 가격 래퍼 — 입력창+suffix를 하나의 입력 박스처럼 표시
   border/background를 wrap에 두고, 내부 input은 border 없이 투명 처리 */
.price-input-wrap {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color .2s;
}
.price-input-wrap:focus-within { border-color: var(--accent); }

/* 가격 입력창 — wrap 안에서 남은 공간 차지, 테두리 없음 */
.price-input {
  flex: 1;
  min-width: 0;        /* flex item 내 텍스트 오버플로 방지 */
  width: 0;            /* flex:1이 실제 크기를 결정하므로 초기값 0 설정 */
  background: transparent;
  border: none;
  outline: none;
  padding: 6px 0 6px 10px;
  font-size: 13px;
  font-family: inherit;
  color: var(--text);
  text-align: right;   /* 숫자는 오른쪽 정렬이 자연스러움 */
}
.price-input::placeholder { color: var(--muted); text-align: left; }

/* suffix 텍스트 (",000" 등) — 입력창 오른쪽에 고정 표시 */
.price-input-suffix {
  flex-shrink: 0;
  padding: 0 8px 0 1px;
  font-size: 13px;
  color: var(--muted);
  user-select: none;
  pointer-events: none;
  line-height: 1;
}

/* ~ 구분자 */
.price-range-sep {
  flex-shrink: 0;
  font-size: 14px;
  color: var(--muted);
  user-select: none;
}

/* ── 가격 필터 — 최근 입력 드롭다운 ── */
/* position: fixed 사용 — .filter-popup의 overflow:hidden에 잘리지 않도록 뷰포트 기준으로 배치.
   JS에서 _minInput.getBoundingClientRect()로 top/left/width를 직접 주입한다. */
.price-history-dropdown {
  position: fixed;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,.5);
  z-index: 600;
  overflow: hidden;
  animation: popupIn .12s ease;
}
.price-history-dropdown[hidden] { display: none; }

/* 드롭다운 항목 */
.price-history-item {
  padding: 8px 12px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  transition: background .12s;
  user-select: none;
}
.price-history-item:hover { background: rgba(192,132,252,.12); }
.price-history-item:not(:last-child) { border-bottom: 1px solid var(--border); }

/* ── Status bar ──
 * 2026-10-01: 필터 바 아래 별도 줄 → .filter-bar 안(.filter-left 와 .sort-group 사이) 가운데로 이동.
 * - flex:1 로 두 그룹 사이 남는 폭을 차지하고 내용은 가운데 정렬.
 * - 비어 있으면(:empty) display:none — 필터 바는 space-between 이라 두 그룹 위치가 변하지 않고,
 *   모바일에서 빈 줄이 row-gap 을 먹는 일도 없다. setStatus('ok','') 는 innerHTML 을 비운다.
 * - 긴 메시지(오류 문구 등)는 span 에서 말줄임. */
.status-bar {
  flex: 1 1 0%; /* basis 0: 두 그룹이 쓰고 남은 폭만 차지 — 긴 문구가 이웃 그룹을 밀거나 줄이지 않는다 */
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 13px;
  color: var(--muted);
}
.status-bar:empty { display: none; }
.status-bar > span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.status-bar .spinner { flex: none; }
.spinner {
  width: 16px; height: 16px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.status-error { color: var(--danger); }
.status-ok    { color: var(--success); }

/* ── Results ── */
.results-wrap {
  max-width: var(--content-max);
  /* 상태바가 필터 바 안으로 들어가(2026-10-01) 필터 바 → 결과 그리드가 바로 이어지므로
   * 이전 체감 간격(상태바 줄 포함 약 44px)보다는 좁고 12px보다는 넉넉한 20px. 모바일은 9px 유지. */
  margin: 20px auto 60px;
  padding: 0 var(--content-pad);
}
.results-grid {
  display: grid;
  /*
   * --columns(:root + 미디어쿼리)에 따라 열 수가 자동 결정된다.
   * PC=6 / 태블릿=3 / 모바일=2 — 모든 분기를 CSS 단독으로 처리한다.
   */
  grid-template-columns: repeat(var(--columns), 1fr);
  gap: 14px;
}

/* ── Wine Card ── */
.wine-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform .2s, border-color .2s, box-shadow .2s;
  cursor: pointer;
}
.wine-card:hover         { transform: translateY(-3px); border-color: var(--accent); box-shadow: 0 8px 20px rgba(0,0,0,.4); }
.wine-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.card-img-wrap {
  position: relative;
  background: var(--card-img-bg);
  aspect-ratio: 1 / 1.1;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  /* 와인잔 뱃지(.wine-glass) 크기 cqw 의 기준 컨테이너 — 폭은 카드가 정하므로 레이아웃 영향 없음 (2026-10-02) */
  container-type: inline-size;
}
/* 2026-10-02: cover → contain. 세로로 긴 병 사진이 라벨만 확대돼 잘리던 문제 수정.
 * --card-img-fit(92%) 로 상자 위아래에 딱 붙지 않게 여백을 두고, 4코너 배지·🍷 폴백 위치는 그대로. */
.card-img {
  width: var(--card-img-fit);
  height: var(--card-img-fit);
  object-fit: contain;
  object-position: center;
  display: block;
}
.card-img-placeholder {
  font-size: 56px;
  opacity: .2;
}
/* 썸네일 로드 실패 폴백 — 기본 숨김, JS error 위임 리스너가 flex 로 활성화 */
.card-img-placeholder--fallback {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
}

/* (매치 점수 배지 제거됨) */

/* v2.1: 별점 배지 — 우하단 단독
 * 빈티지 배지는 좌하단(.vintage-badge 기본 규칙)에 별도 배치된다.
 * 위치와 패딩은 --columns 값에 따라 calc()/clamp()로 자동 스케일된다.
 * 공식: clamp(5, 11 - cols*0.5, 8) — 현재 cols 범위(2~6)에선 항상 상한 8px 고정.
 *  의도가 컬럼별 단계적 축소라면 공식 자체를 재산정해야 하지만, 별도 작업으로 분리한다.
 */
.vivino-overlay {
  position: absolute;
  bottom: clamp(5px, calc(11px - var(--columns) * 0.5px), 8px);
  right:  clamp(5px, calc(11px - var(--columns) * 0.5px), 8px);
  background: rgba(0,0,0,.72);
  backdrop-filter: blur(6px);
  border-radius: 6px;
  /* 빈티지 뱃지(.vintage-badge)와 동일한 padding·gap·line-height로 두 뱃지 높이 통일 */
  padding: 2px 6px;
  display: flex; align-items: center; gap: 3px;
  line-height: 1.2;
  /* 클릭 시 빈티지 차트 모달로 진입 — 사용자에게 클릭 가능함을 명시 */
  cursor: pointer;
}
/* 빈티지 뱃지 font-size 공식과 동일하게 통일 — clamp(9, 13-cols*0.5, 11) */
.star           { color: var(--gold); font-size: clamp(9px, calc(13px - var(--columns) * 0.5px), 11px); }
/*
 * Vivino 점수 폰트: 2열=14px, 4열=11px, 6열=9px
 * v2: font-weight 500으로 다운 (700 → 500)
 * 공식: clamp(9px, calc(15px - columns * 1px), 14px)
 */
/* 빈티지 뱃지 font-size 공식과 동일 — 두 뱃지 텍스트 높이 통일 */
.vivino-score   { font-size: clamp(9px, calc(13px - var(--columns) * 0.5px), 11px); font-weight: 500; color: var(--gold); }

/* 국기 오버레이 (좌상단)
 * 크기: width 2열=26px, 4열=22px, 6열=14px / height 2열=19px, 4열=16px, 6열=10px
 */
.country-flag {
  position: absolute; top: 8px; left: 8px;
  /* 카테고리 뱃지(.kind-overlay)와 동일 높이로 통일 — 두 상단 뱃지의 효과적 박스 크기 일치.
   * .kind-overlay 효과적 높이 = font 11 + padding 4*2 + line-height 1 + border 0 = ~19px. */
  height: 19px;
  width: 29px;
  object-fit: cover;
  border-radius: 2px;
  border: 1px solid rgba(255,255,255,.18);
  box-shadow: 0 2px 6px rgba(0,0,0,.45);
  pointer-events: none;
}

/* 와인 종류 태그 오버레이 (우상단) — sample-a 그라데이션 알약 스타일 (열 수 무관)
 * base에는 배경·색상 없음 → modifier가 그라데이션·텍스트 색을 강제 지정.
 * 검색 카드는 이미지 위 오버레이라 가독성 위해 box-shadow로 살짝 띄움. */
.kind-overlay {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  border: none;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: .04em;
  pointer-events: none;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0,0,0,.4);
}
/* 색상 진리원천: js/index-page.js FILTER_CATEGORIES[].dot
 * 각 카테고리 dot 색을 lighter end, 동계열 어두운 톤을 darker end로 설정.
 * 화이트는 베이지 배경이라 텍스트만 어두운 색 사용. */
.kind-overlay--red       { background: linear-gradient(135deg, #e05c5c, #a83838); color: #fff; }
.kind-overlay--white     { background: linear-gradient(135deg, #f4f0e3, #d8d0b5); color: #3d3424; }
.kind-overlay--sparkling { background: linear-gradient(135deg, #818cf8, #4f57cc); color: #fff; }
.kind-overlay--rose      { background: linear-gradient(135deg, #f472b6, #c7458a); color: #fff; }
.kind-overlay--dessert   { background: linear-gradient(135deg, #fb923c, #d36e1a); color: #fff; }
.kind-overlay--fortified { background: linear-gradient(135deg, #d97706, #a35a04); color: #fff; }
.kind-overlay--orange    { background: linear-gradient(135deg, #f97316, #cb540a); color: #fff; }
.kind-overlay--port      { background: linear-gradient(135deg, #3b82f6, #1e4fbc); color: #fff; }
.kind-overlay--other     { background: linear-gradient(135deg, #64748b, #3f4756); color: #fff; }

/* v2: 가격 행 — 카드 바디 안쪽, 우측 정렬
 * 이전: 이미지 우하단 .price-overlay → 카드 바디 마지막 .price-row 로 이동
 * 와인명 영역과 1px 보더로 구분하고, 가격은 accent(보라) 컬러로 강조.
 */
/* v2.1: 지역·품종 칩 — 와인명 아래, 가격 위
 * SubRegion(세부지역) > Region(지역) 한 칩 + GrapeVariety 한 칩.
 * 둘 다 옵셔널이라 데이터 없으면 .meta-chips 자체가 생략된다.
 */
.meta-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 2px;
}
.chip {
  font-size: clamp(9px, calc(13px - var(--columns) * 0.7px), 11px);
  padding: 2px 7px;
  border-radius: 10px;
  background: rgba(255,255,255,.05);
  color: var(--muted);
  border: 1px solid var(--border);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.price-row {
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
}
/*
 * 가격 폰트: 2열=16px, 4열=13px, 6열=11px (baseline 14~16px 정도)
 * 공식: clamp(11px, calc(17px - columns * 1px), 16px)
 * font-weight 700 (bold) / color: var(--accent)
 */
.price-krw      { font-size: clamp(11px, calc(17px - var(--columns) * 1px), 16px); font-weight: 700; color: var(--accent); }
.discount-badge { font-size: clamp(8px, calc(13px - var(--columns) * 0.8px), 11px); color: #f87171; font-weight: 600; }

/* 카드 바디
 * 패딩: 2열=16px, 4열=10px(기준), 6열=6px
 * 공식: clamp(6px, calc(20px - columns * 2px), 16px)
 */
.card-body { padding: clamp(6px, calc(20px - var(--columns) * 2px), 16px); }

/*
 * 와인 한글명 폰트: 2열=18px, 4열=14px, 6열=14px
 * 공식: clamp(14px, calc(22px - columns * 2px), 18px)
 */
.wine-name-ko {
  font-size: clamp(14px, calc(22px - var(--columns) * 2px), 18px);
  font-weight: 700;
  color: var(--text);
  line-height: 1.35;
  margin-bottom: 2px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/*
 * 와인 영문명 폰트: 2열=13px, 4열=11px, 6열=9px
 * 공식: clamp(9px, calc(15px - columns * 1px), 13px)
 */
.wine-name-en {
  font-size: clamp(9px, calc(15px - var(--columns) * 1px), 13px);
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ══════════════════════════════════════════════════════════════
   반응형 (PC ≥1024 / 태블릿 768~1023 / 모바일 <768)
   --columns 단일 진리원천: :root 기본값(PC=5)을 미디어쿼리로 재정의해
   clamp()/calc() 기반 폰트·오버레이·패딩까지 자동 축소시킨다.
   ══════════════════════════════════════════════════════════════ */

/* === 태블릿 (768~1023px) === */
@media (max-width: 1023px) {
  /* --content-pad 한 곳만 바꾸면 헤더 inner·최근 검색어·상태바·결과 영역이 같이 20px로 맞춰진다 */
  :root { --columns: 3; --content-pad: 20px; }
  /* 레이아웃 */
  header        { padding: 18px 24px; }
  .site-header__inner { gap: 18px; }
  .results-grid { gap: 12px; }
  /* 필터바 — 태블릿만 기준선보다 4px 안쪽(16px, 기존 값 유지) */
  .filter-bar   { padding: 0 16px; gap: 8px; flex-wrap: wrap; }
  .filter-left  { gap: 6px; }
  .filter-btn,
  .sort-btn     { padding: 5px 10px; font-size: 12px; }
}

/* === 모바일 (<768px) === */
@media (max-width: 767px) {
  /* --content-pad 12px: 헤더 inner·최근 검색어·필터 바·상태바·결과 영역 공통 기준선 */
  :root { --columns: 3; --content-pad: 12px; }
  /* 레이아웃 */
  header        { padding: 14px 16px; gap: 10px; }
  .logo         { font-size: 20px; }
  .logo-sub     { font-size: 11px; }
  /* 사이트 헤더 두 줄 배치 (시안 모바일 블록):
   * 첫 줄 [타이틀 ... 로그인], 둘째 줄 [검색창 전체 폭]. flex-wrap + order로 재배치.
   * inner 좌우 패딩은 --content-pad(12px) = 결과 영역과 같은 기준선.
   * 480px 블록의 `header { padding }`보다 header.site-header가 specificity로 이기므로 여기 값이 적용된다. */
  header.site-header   { padding: 12px 0 10px; }
  .site-header__inner  { flex-wrap: wrap; gap: 10px 12px; }
  .site-header__brand  { order: 1; }
  .header-auth-slot    { order: 2; }
  .search-card         { order: 3; flex-basis: 100%; }
  /* 검색창 + 검색버튼 한 줄 유지
   * - input-row는 row 방향 유지 (column으로 떨어뜨리지 않음)
   * - input-area는 min-width:0 으로 flex item 기본 min-width:auto 오버라이드 → 버튼이 wrap되지 않음
   * - search-btn은 flex-shrink:0으로 고정 폭 유지 */
  .input-row    { gap: 8px; align-items: stretch; }
  .input-area   { min-width: 0; }
  .input-wrap   { min-width: 0; }
  .ocr-input    { font-size: 15px; padding: 11px 14px 11px 38px; min-width: 0; } /* 왼쪽: clear-btn 공간 */
  .search-btn   { flex-shrink: 0; padding: 0 16px; min-width: 48px; }
  /* 모바일: 필터 바가 두 줄(필터 그룹 / 정렬 그룹)로 접히므로 상태 표시는 맨 마지막 줄 전체 폭 가운데.
   * 비어 있으면 :empty 로 숨겨져 줄 자체가 생기지 않는다. */
  .status-bar  { order: 3; flex-basis: 100%; }
  .results-grid { gap: 8px; }
  /* 모바일 3열에선 카드 폭이 좁아 와인명 폰트를 한 단계 축소 (자동 스케일 공식 위에 명시적 오버라이드) */
  .wine-name-ko { font-size: 14px; }
  .wine-name-en { font-size: 10px; }
  /* 필터바: 두 줄 분리 (위: filter-left, 아래: sort-group)
   * - flex-wrap: wrap으로 sort-group이 폭 부족 시 자연스럽게 다음 줄로 떨어짐
   * - 1023~768 태블릿 블록에서 이미 flex-wrap: wrap 설정됨 → 모바일에서도 유지
   * - sort-group의 margin-left: auto는 한 줄일 때 우측 정렬, wrap 시 좌측 정렬됨
   * - row-gap(필터그룹↔정렬그룹) 14px: 두 그룹의 시각적 분리 강조
   *   ※ wrap이 안 일어났을 때(한 줄)는 row-gap 무영향 → 태블릿/데스크톱에 영향 없음
   * - .results-wrap의 margin-top을 9px로 축소해 정렬그룹↔결과 그리드 사이를 좁힘
   *   (4px은 너무 답답해 8~10px 범위로 조정 — row-gap 14px보다는 작아 그룹핑 의도 유지)
   *   → "정렬은 결과에 얹힌 느낌"의 시각적 그룹핑 형성 */
  /* 태블릿 블록의 16px 오버라이드를 기준선(--content-pad 12px)으로 되돌린다 */
  .filter-bar   { gap: 8px; row-gap: 14px; flex-wrap: wrap; padding: 0 var(--content-pad); }
  .filter-left  { gap: 6px; flex-wrap: wrap; row-gap: 6px; }
  /* 정렬그룹은 모바일에서 거의 항상 두 번째 줄로 떨어진다 (filter-bar flex-wrap).
   * 두 번째 줄에선 "결과 위에 얹힌 보조 컨트롤" 인상을 주기 위해
   * 필터그룹 대비 약 75% 시각 크기로 축소한다 (내부 padding·버튼 padding·폰트 동시 축소).
   * wrap이 안 일어나는 케이스(가로 iPad 등 매우 드묾)에선 정렬그룹만 살짝 작아
   * 보조 컨트롤로 보이는 부작용이 있지만, 시각적 계층상 자연스러우므로 허용. */
  .filter-btn   { padding: 5px 9px; font-size: 12px; }
  .sort-group   { margin-left: auto; padding: 3px; }
  .sort-btn     { padding: 3px 8px; font-size: 11px; }
  /* 결과 그리드와 정렬그룹 사이 숨 쉴 공간 — 기본 12px 보다는 좁고 row-gap(14px)보다는 좁아 그룹핑 의도 유지 */
  .results-wrap { margin-top: 9px; }
  /* 필터 팝업: 모바일에선 화면 폭에 맞춰 축소 */
  .filter-popup { width: calc(100vw - 24px); max-width: 320px; }

  /* ── v2.1 모바일 3열: 별점(.vivino-overlay 우하단) 폰트·패딩만 축소 ──
   * 별점은 우하단, 빈티지는 좌하단 단독 — 화면 폭 분기 없는 단일 규칙.
   * 빈티지 배지 모바일 오버라이드는 파일 하단 @media(<768px) 블록에 둔다
   * (.vintage-badge 기본 규칙 뒤에 위치해야 동일 specificity에서 source order로 승리).
   */
  .vivino-overlay {
    padding: 2px 6px;
    gap: 3px;
  }
  /* 모바일 별점 폰트 — 11px line-height:1 */
  .vivino-score,
  .star {
    font-size: 11px;
    line-height: 1;
  }
}

/* ── 맨 위로 버튼 ── */
/* 첫 페이지 이후 추가 로드 시 JS가 hidden 속성을 제거해 표시한다 */
.scroll-top-btn {
  position: fixed;
  /* 하단 네비(.bottom-nav: max-width 480px 중앙 배치)와 가로로 겹치지 않으므로
   * 네비 오른쪽 빈 공간에 살짝 위로 배치. 네비 top edge(약 80px) 보다 살짝 위에 옴. */
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  right: 20px;
  z-index: 900;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(192,132,252,.4);
  background: rgba(26,23,36,.88);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--accent);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 16px rgba(0,0,0,.45);
  transition: transform .15s, background .15s, border-color .15s;
  animation: fadeInUp .22s ease;
}
.scroll-top-btn:hover {
  background: rgba(192,132,252,.18);
  border-color: var(--accent);
  transform: translateY(-2px);
}
.scroll-top-btn:active { transform: translateY(0); }
/* hidden 속성이 붙어 있으면 display:none으로 감춤 */
.scroll-top-btn[hidden] { display: none; }

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (max-width: 767px) {
  /* 모바일은 네비 위로 확실히 띄움 — 네비 top edge(~80px)보다 +20px 위로. */
  .scroll-top-btn {
    bottom: calc(100px + env(safe-area-inset-bottom, 0px));
    right: 14px;
    width: 40px;
    height: 40px;
  }
}

/* ══════════════════════════════════════════════════════════════
   풀페이지 와인 상세 뷰 (Design A · 클래식 2열)
   sample-a.html을 기반으로 인페이지 전환용으로 통합.
   - 뷰포트 ≥1024px: 좌측 4fr / 우측 6fr 2열 그리드
   - 뷰포트 <1024px: 1열 (좌·우 컬럼 세로 적층)
   ══════════════════════════════════════════════════════════════ */

/* 상세 뷰 컨테이너 — hidden일 때 자식 sentinel/observer가 동작하지 않도록 display:none 보장 */
.wd-view[hidden] { display: none; }

.wd-shell {
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px 20px 80px;
}

/* 공통 스피너 (로딩 인디케이터) — 상세 본문·리뷰 로딩 모두 사용 */
.detail-spinner {
  width: 28px; height: 28px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}

/* 뒤로가기 네비 */
.wd-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 24px;
}
.wd-nav__back {
  background: transparent;
  border: none;
  color: var(--accent);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
  transition: background .15s;
}
.wd-nav__back:hover { background: rgba(192,132,252,.08); }
.wd-nav__title {
  font-size: 13px;
  color: var(--muted);
}
.wd-nav__spacer { width: 60px; }

/* 본문(상태 전환: 로딩 / 오류 / 그리드+리뷰) */
.wd-body {
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.wd-loading, .wd-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 20px;
  gap: 12px;
  color: var(--muted);
  font-size: 14px;
}
.wd-error__icon { font-size: 36px; }

/* 메인 2열 그리드 */
.wd-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}
@media (min-width: 1024px) {
  .wd-grid {
    grid-template-columns: 4fr 6fr;
    align-items: start;
  }
}

/* ── 좌측 컬럼: 이미지 카드만 (빈티지 셀렉터·가격은 헤더 안으로 이동) ── */
.wd-left {
  display: flex;
  flex-direction: column;
}

.wd-image-card {
  /* 2026-10-02: 어두운 그라데이션 → 검색 카드와 같은 흰 상자(--card-img-bg). 보라 glow(::before) 제거.
   * aspect-ratio 4/5 고정 상자(아래 주석의 원래 의도) — 로컬 병 사진(268×960)이 natural 높이로 상자를
   * 1000px 가까이 키우던 문제 차단. 이미지 최대 크기는 .wd-image-card__img 의 cqw 단위로 92% 로 제한. */
  background: var(--card-img-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  aspect-ratio: 4 / 5;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  /* 컨테이너 폭 기준으로 자식 뱃지가 자연스럽게 줄어들도록 (이미지 카드 폭 변화에 응답) */
  container-type: inline-size;
}
/* 이미지(또는 폴백 이모지)를 감싸는 wrapper — 2026-10-02 재설계.
 * 이전엔 img 를 shrink-wrap(fit-content) 해서 배지가 "이미지 모서리"에 붙었는데, 로컬 병 사진(268×960)은
 * 폭이 148px 정도로 좁아 cqw 로 커진 배지가 병목·라벨을 가렸다. 이제 wrapper 가 흰 상자 전체(4/5)를
 * 채우고 img 는 그 안에서 contain·가운데, 4코너 배지는 **흰 상자의 네 모서리**(8~12px 안쪽)에 붙는다. */
.wd-image-card__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  line-height: 0;
  flex: 1 1 auto;
}
.wd-image-card__bottle {
  font-size: clamp(120px, 22vw, 200px);
  filter: drop-shadow(0 12px 24px rgba(0,0,0,.6));
  display: inline-block;
  line-height: 1;
}
.wd-image-card__img {
  display: block;
  /* 상자(container-type: inline-size, 폭 W·높이 1.25W) 기준 92% 안에 전체 이미지 contain —
   * 92cqw = 폭의 92%, 115cqw = 높이(125cqw)의 92%. 검색 카드 --card-img-fit(92%) 와 같은 여백. */
  max-width: 92cqw;
  max-height: 115cqw;
  width: auto;
  height: auto;
  object-fit: contain;
  /* 흰 상자 위라 그림자는 옅게 (투명 PNG 병 윤곽만 살짝 띄움) */
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.18));
}
/* 이미지 카드 4코너 오버레이 — 검색 카드(buildCard)와 동일한 배치.
 *   좌상단: .country-flag (검색 카드 스타일 재사용 + .wd-image-card__flag 위치 보정)
 *   우상단: .kind-overlay (.wd-image-card__kind 위치 보정)
 *   좌하단: .vintage-badge (.wd-image-card__vintage 위치 보정 — 골드)
 *   우하단: .vivino-overlay (.wd-image-card__rating 위치 보정 — 별점)
 * 위치값은 .wd-image-card의 inline-size container query 기준으로 동적 스케일.
 * 2026-10-02: 배지가 흰 상자 모서리에 붙으므로 크기는 검색 카드와 같은 감각(국기 29×19, 글자 11~12px)에서
 * 상자 폭(PC 454px) 기준으로 조금만 키우고 상한을 낮게 clamp — 병을 가리지 않게.
 * specificity (0,2,0) 셀렉터로 base + 모바일 미디어쿼리 (0,1,0)를 모두 이겨 재정의한다. */
/* 국기 뱃지 — 검색 카드 29×19 → 상자 폭 기준 clamp(29~40 × 19~26). 카테고리 뱃지와 높이 짝. */
.country-flag.wd-image-card__flag {
  top: clamp(8px, 2.2cqw, 12px);
  left: clamp(8px, 2.2cqw, 12px);
  height: clamp(19px, 5.3cqw, 26px);
  width: clamp(29px, 8cqw, 40px);
  z-index: 2;
}

/* 좌하단 빈티지 뱃지 — 검색 카드 .vintage-badge 색·텍스트 차용, 위치/사이즈만 이미지 카드 cqw 기준으로 재정의.
 * .vintage-badge는 기본 display:none이라 JS가 .visible 클래스를 부여해야 표시된다.
 * specificity (0,2,0)로 .vintage-badge base 및 @media .vintage-badge 모바일 오버라이드까지 이긴다. */
.vintage-badge.wd-image-card__vintage {
  bottom: clamp(8px, 2.2cqw, 12px);
  left: clamp(8px, 2.2cqw, 12px);
  padding: clamp(4px, 1.2cqw, 6px) clamp(9px, 2.5cqw, 12px);
  font-size: clamp(12px, 3.2cqw, 15px);
  border-radius: clamp(8px, 2cqw, 10px);
  gap: clamp(4px, 1cqw, 6px);
  line-height: 1.2;
  z-index: 2;
}

/* 우하단 별점 뱃지 — 빈티지 뱃지(.wd-image-card__vintage)와 사이즈 통일.
 * padding/font/border-radius/gap/line-height 모두 동일 공식 사용해 짝 맞춤. */
.vivino-overlay.wd-image-card__rating {
  bottom: clamp(8px, 2.2cqw, 12px);
  right: clamp(8px, 2.2cqw, 12px);
  padding: clamp(4px, 1.2cqw, 6px) clamp(9px, 2.5cqw, 12px);
  border-radius: clamp(8px, 2cqw, 10px);
  gap: clamp(4px, 1cqw, 6px);
  z-index: 2;
  cursor: pointer;
}
.wd-image-card__rating .star,
.wd-image-card__rating .vivino-score {
  font-size: clamp(12px, 3.2cqw, 15px);
  line-height: 1.2;
}
.wd-image-card__rating:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.wd-image-card__rating--hidden { display: none; }

/* 빈티지 셀렉터 (combobox: trigger 버튼 + dropdown[필터 input + listbox])
 * 헤더(.wd-header) 안 산지 아래 dashed 보더 다음에 배치됨 — 별도 카드 배경은 제거하고 헤더 톤과 조화. */
.wd-vintage-selector {
  background: transparent;
  border: none;
  padding: 0;
}
.wd-vintage-selector__combo { position: relative; }

/* Closed 상태: trigger 버튼 (현재 선택값 표시 + ▾ caret) */
.wd-vintage-selector__trigger {
  appearance: none;
  width: 100%;
  padding: 7px 36px 7px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.wd-vintage-selector__trigger:hover {
  border-color: var(--accent);
}
.wd-vintage-selector__trigger:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(192,132,252,.2);
}
.wd-vintage-selector__trigger[aria-expanded="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(192,132,252,.2);
}
.wd-vintage-selector__current {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wd-vintage-selector__caret {
  color: var(--muted);
  font-size: 12px;
  pointer-events: none;
  transition: transform .15s;
}
.wd-vintage-selector__trigger[aria-expanded="true"] .wd-vintage-selector__caret {
  transform: rotate(180deg);
  color: var(--accent);
}

/* Open 상태: dropdown 팝업 (필터 input + listbox) */
.wd-vintage-selector__dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0; right: 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 12px 32px rgba(0,0,0,.5);
  z-index: 20;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.wd-vintage-selector__dropdown[hidden] { display: none; }
.wd-vintage-selector__filter {
  width: 100%;
  padding: 9px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  outline: none;
  transition: border-color .15s, box-shadow .15s;
  box-sizing: border-box;
}
.wd-vintage-selector__filter:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(192,132,252,.2);
}
.wd-vintage-selector__filter::placeholder {
  color: var(--muted);
  opacity: .8;
}
.wd-vintage-selector__listbox {
  max-height: 240px;
  overflow-y: auto;
  padding: 2px;
}
.wd-vintage-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  color: var(--text);
  transition: background .12s;
}
.wd-vintage-option:hover { background: rgba(192,132,252,.08); }
.wd-vintage-option--selected {
  background: rgba(192,132,252,.12);
  color: var(--accent);
  font-weight: 600;
}
.wd-vintage-option__radio {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 2px solid var(--muted);
  flex-shrink: 0;
  position: relative;
}
.wd-vintage-option--selected .wd-vintage-option__radio { border-color: var(--accent); }
.wd-vintage-option--selected .wd-vintage-option__radio::after {
  content: '';
  position: absolute; inset: 2px;
  background: var(--accent);
  border-radius: 50%;
}
.wd-vintage-option__best {
  margin-left: auto;
  font-size: 10px;
  padding: 2px 6px;
  background: rgba(251,191,36,.15);
  color: var(--gold);
  border-radius: 4px;
  font-weight: 700;
}
.wd-vintage-option__empty {
  padding: 14px;
  color: var(--muted);
  text-align: center;
  font-size: 13px;
}

/* 별점·시음적기는 이미지 카드 4코너 오버레이(.wd-image-card__rating / .wd-image-card__vintage)로 이전됨.
   빈티지별 상세 점수는 빈티지 차트 모달로 위임. */

/* ── 우측 컬럼: 헤더(이름·산지·빈티지셀렉터·가격) + 테이스팅 노트 ── */
.wd-right {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.wd-header {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 24px;
}
.wd-header__top {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 14px;
}
.wd-header__flag {
  width: 22px; height: 16px;
  object-fit: cover;
  border-radius: 2px;
  box-shadow: 0 0 0 1px var(--border);
}
.wd-header__country {
  font-size: 13px;
  color: var(--muted);
}
.wd-header__name-ko {
  font-size: clamp(22px, 3vw, 30px);
  font-weight: 800;
  letter-spacing: -.01em;
  line-height: 1.25;
  margin-bottom: 6px;
  word-break: keep-all;
}
.wd-header__name-en {
  font-size: 14px;
  color: var(--muted);
  font-style: italic;
}
/* 이름 줄 — 한글명·영문명(왼쪽) + "나의 와인" 와인잔 버튼(오른쪽, js/my-wine-glass.js) (2026-10-03).
 * 잔은 검색 카드와 같은 마크업·상태(.wine-glass / .is-filled …)이고, 여기서는 이미지 위가 아니라 흐름 안에 둔다.
 * 크기는 cqw(카드 폭) 대신 고정 토큰 --wd-glass-size, 터치 영역은 카드와 같은 --glass-touch(44px). */
.wd-header__title-row {
  --wd-glass-size: 40px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.wd-header__titles {
  flex: 1 1 auto;
  min-width: 0;
}
.wd-header__glass {
  flex: 0 0 auto;
  /* 칩 둘레 금색 링·+ 장식이 칩 밖으로 살짝 나가므로 위·오른쪽 여유 */
  padding: 4px 4px 0 0;
}
.wd-header__glass > .wine-glass {
  --glass-size: var(--wd-glass-size);
  position: relative;
  top: auto;
  right: auto;
}
.wd-header__region {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 13px;
  color: var(--text);
}
.wd-header__region-sep { color: var(--muted); }
.wd-header__region-leaf { color: var(--accent); font-weight: 700; }
/* 산지 segment 링크 — 매칭되는 지도 페이지로 navigate (없으면 alert) */
.wd-header__region-link {
  appearance: none;
  background: none;
  border: 0;
  padding: 2px 6px;
  margin: 0 -4px;
  font: inherit;
  color: var(--text);
  cursor: pointer;
  border-radius: 4px;
  text-decoration: underline;
  text-decoration-color: rgba(192,132,252,.35);
  text-underline-offset: 3px;
  transition: background .12s, color .12s, text-decoration-color .12s;
}
.wd-header__region-link:hover {
  background: rgba(192,132,252,.12);
  color: var(--accent);
  text-decoration-color: var(--accent);
}
.wd-header__region-link.wd-header__region-leaf {
  color: var(--accent);
  font-weight: 700;
  text-decoration-color: var(--accent);
}
.wd-header__region-link.wd-header__region-leaf:hover {
  color: var(--gold);
  text-decoration-color: var(--gold);
  background: rgba(251,191,36,.1);
}

/* 헤더 상단 행 안 품종 — 국기·국가·카테고리 뱃지 오른쪽 inline 배치.
 * 산지 행 아래 별도 행이 아닌 .wd-header__top 안에 합쳐 시각적 밀도를 높임.
 * 비어있으면 _buildRightColumnHtml에서 출력 자체를 생략. */
.wd-header__grape-inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--muted);
  word-break: keep-all;
}

/* 헤더 상단 행 안 도수 — 품종 바로 다음 inline. 품종과 같은 톤(13px·muted), "도수" 라벨 + 값.
 * nowrap: 좁은 화면에서 "도수"와 "13.5%"가 갈라지지 않고 한 덩어리로 다음 줄로 넘어감.
 * alcoholPct가 null이면 _buildRightColumnHtml에서 출력 자체를 생략. */
.wd-header__alcohol-inline {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
}
.wd-header__alcohol-label {
  color: var(--muted);
}

/* 헤더 안 카테고리 뱃지 — 국기 오른쪽. .kind-overlay의 absolute 위치 속성을 무효화하고 inline 배치.
 * sample-a 그라데이션 알약 스타일을 그대로 상속(font/padding/radius는 base와 동일하므로 위치만 재정의).
 * 헤더는 이미지 위가 아니므로 box-shadow는 제거해 평평하게. */
.wd-header__kind {
  position: static;
  top: auto;
  right: auto;
  box-shadow: none;
}

/* (구) .wd-header__rating·.wd-meta·.wd-rating-btn* 블록은 모두 제거됨.
 * 별점은 이미지 카드 우하단 .wd-image-card__rating(.vivino-overlay)으로 이동,
 * 가격은 헤더 안 .wd-header__price로 이동했다. 빈티지별 상세 점수는 빈티지 차트 모달로 위임. */

/* 이미지 카드 우상단 카테고리 뱃지 — sample-a 그라데이션 알약 스타일 (배경은 modifier가 지정).
 * 검색 카드 .kind-overlay 기본 위치(top/right 8px)를 cqw 기준으로 재정의 — 이미지 카드 폭에 비례.
 * specificity (0,2,0)로 .kind-overlay base를 확실히 이긴다. */
.kind-overlay.wd-image-card__kind {
  top: clamp(8px, 2.2cqw, 12px);
  right: clamp(8px, 2.2cqw, 12px);
  padding: clamp(4px, 1.2cqw, 6px) clamp(10px, 2.8cqw, 14px);
  font-size: clamp(11px, 3cqw, 14px);
  z-index: 2;
}

/* 헤더 안 divider — 산지 아래, 빈티지 셀렉터 위 (메타 그리드 폐기로 헤더가 빈티지·가격까지 담는다). */
.wd-header__divider {
  margin-top: 16px;
  margin-bottom: 14px;
  border-top: 1px dashed var(--border);
}

/* 헤더 안 가격 — 빈티지 셀렉터 아래, 큰 폰트로 강조. */
.wd-header__price {
  margin-top: 12px;
  display: flex;
  justify-content: flex-end;
}
.wd-header__price-value {
  font-size: clamp(20px, 3vw, 28px);
  font-weight: 800;
  color: var(--text);
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  letter-spacing: -.01em;
}

/* 테이스팅 노트 placeholder */
.wd-tasting-note {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 24px;
}
.wd-tasting-note__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.wd-tasting-note__title {
  font-size: 15px;
  font-weight: 700;
}
.wd-tasting-note__sub {
  font-size: 12px;
  color: var(--muted);
}
.wd-tasting-note__body {
  font-size: 14px;
  color: var(--text);
  line-height: 1.7;
}

/* ── 리뷰 섹션 (하단 풀폭) ── */
.wd-reviews {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 24px;
}
.wd-reviews__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 18px;
  flex-wrap: wrap;
  gap: 8px;
}
.wd-reviews__title {
  font-size: 17px;
  font-weight: 700;
}
.wd-reviews__count {
  font-size: 13px;
  color: var(--muted);
}
.wd-reviews__filter-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  background: rgba(192,132,252,.12);
  color: var(--accent);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
}
.wd-review {
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
}
.wd-review:last-of-type { border-bottom: none; }
.wd-review__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.wd-review__avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  flex-shrink: 0;
}
.wd-review__name { font-weight: 700; font-size: 14px; }
.wd-review__date { font-size: 12px; color: var(--muted); }
.wd-review__rating {
  color: var(--gold);
  font-size: 14px;
  font-weight: 700;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.wd-review__rating-star  { font-size: 15px; line-height: 1; }
.wd-review__rating-value { font-variant-numeric: tabular-nums; }
.wd-review__vintage-tag {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--bg);
  color: var(--muted);
  border: 1px solid var(--border);
}
.wd-review__body {
  font-size: 14px;
  color: var(--text);
  line-height: 1.65;
  padding-left: 46px;
  word-break: break-word;
  white-space: pre-line;      /* 리뷰 본문 줄바꿈 유지, 연속 공백은 접힘 */
  overflow-wrap: anywhere;    /* 긴 URL·단어 강제 줄바꿈 */
}

.wd-reviews__status {
  margin-top: 16px;
  text-align: center;
}
.wd-reviews__empty,
.wd-reviews__end,
.wd-reviews__error {
  padding: 18px 14px;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: 13px;
  line-height: 1.6;
}
.wd-reviews__error { color: var(--danger); }

/* ── 태블릿·모바일 반응형 (<1024px) — 단일 컬럼 + 섹션 순서 ──
 *
 * 표시 순서 (태블릿·모바일 동일): 이미지(.wd-image-card) → 헤더(.wd-header — 이름+산지+빈티지셀렉터+가격 포함)
 *               → 테이스팅 노트(.wd-tasting-note) → 리뷰(.wd-reviews)
 *
 * 데스크탑(≥1024px) DOM 구조는 좌(이미지만) / 우(헤더+테이스팅) 2열 컬럼이므로
 * 단일 컬럼 분기에서는 `.wd-left`·`.wd-right`를 display:contents로 평탄화하고 flex order로 재배치한다.
 * 빈티지 셀렉터·가격은 이제 헤더 내부 요소라 별도 order 불필요.
 */
@media (max-width: 1023px) {
  .wd-grid { gap: 16px; display: flex; flex-direction: column; }
  /* 좌·우 컬럼 래퍼 평탄화 — 자식이 .wd-grid의 직접 자식이 되도록 */
  .wd-left, .wd-right {
    display: contents;
  }
  /* 평탄화된 자식들의 표시 순서 (이미지 → 헤더 → 테이스팅) */
  .wd-image-card     { order: 1; }
  .wd-header         { order: 2; }
  .wd-tasting-note   { order: 3; }
  /* .wd-reviews는 .wd-grid 바깥 형제라 order 영향 없음 — 자동으로 마지막에 옴 */
}

/* ── 모바일 전용 (≤767px) — 패딩·폰트·이미지 비율 등 모바일 특화 ── */
@media (max-width: 767px) {
  .wd-shell { padding: 16px 14px 60px; }
  .wd-nav { padding: 10px 12px; margin-bottom: 16px; }
  .wd-header, .wd-tasting-note, .wd-reviews { padding: 16px 18px; }
  .wd-vintage-selector__filter { font-size: 16px; padding: 11px 12px; }
  .wd-vintage-selector__dropdown { padding: 8px; }
  .wd-vintage-option { padding: 11px 12px; min-height: 44px; }
  .wd-review__body { padding-left: 0; }

}

/* ── 카드 바디 메타 행 (빈티지 배지 등) ── */

/* ── 빈티지 배지 버튼 ── */
/*
 * v2.1: 시음 적기 배지 — 좌하단 단독 (별점은 우하단 .vivino-overlay).
 *
 * .card-img-wrap 직계 자식으로 absolute 배치. 화면 폭 분기 없음 (단일 규칙).
 * 위치값은 .vivino-overlay와 대칭(left ↔ right) — 같은 clamp 공식 사용.
 *
 * 기본 display:none → JS가 .visible 클래스 추가 시 inline-flex로 표시.
 */
.vintage-badge {
  position: absolute;
  bottom: clamp(5px, calc(11px - var(--columns) * 0.5px), 8px);
  left:   clamp(5px, calc(11px - var(--columns) * 0.5px), 8px);
  display: none;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  border-radius: 10px;
  background: #f0c040;
  color: #2a2010;
  font-size: clamp(9px, calc(13px - var(--columns) * 0.5px), 11px);
  font-weight: 800;
  border: none;
  cursor: pointer;
  white-space: nowrap;
  line-height: 1.2;
  transition: background .15s, transform .1s;
}
.vintage-badge.visible { display: inline-flex; }
/* 상태 색(.vintage-status--*)을 가진 뱃지(my-wines 상세 카드)는 hover 시 금색으로 바뀌지 않게 제외 (2026-10-01) */
.vintage-badge:not([class*="vintage-status--"]):hover { background: #e6b400; }
.vintage-badge:active  { transform: scale(.94); }
.vintage-badge--unknown { background: rgba(156,163,175,.25); color: #9ca3af; }
.vintage-badge--unknown:hover { background: rgba(156,163,175,.35); }

/* ── 빈티지 차트 모달 오버레이 ── */
/*
 * z-index: 1100 — 와인 상세 모달(z-index:1000)보다 위에 표시해
 * 상세 모달이 열린 상태에서도 빈티지 모달을 별도로 열 수 있다.
 */
.vintage-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .72);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 1100;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 8vh 20px 20px;
  animation: fadeIn .18s ease;
  overflow-y: auto;
}
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ── 빈티지 모달 패널 ── */
.vintage-modal {
  background: #1e1a2c;
  border: 1px solid var(--border);
  border-radius: 18px;
  width: 100%;
  max-width: 480px;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: slideUp .22s ease;
  box-shadow: 0 16px 48px rgba(0, 0, 0, .65);
}

/* ── 빈티지 모달 헤더 ── */
.vintage-modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.vintage-modal__header-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.vintage-modal__title {
  font-size: 16px;
  font-weight: 800;
  color: var(--text);
  line-height: 1.3;
  word-break: keep-all;
  margin: 0;
}
/* 영문명 — 와인 상세 페이지 .wd-header__name-en 과 동일한 폰트/색.
 * 헤더-info 가 flex column + gap:4px 이므로 margin:0 으로 간격은 부모 gap 에 위임. */
.vintage-modal__title-en {
  font-size: 13px;
  color: var(--muted);
  margin: 0;
  word-break: keep-all;
}
.vintage-modal__region {
  font-size: 12px;
  color: var(--accent);
  margin: 0;
  /* 기본: 한 줄 — JS가 scrollWidth로 넘침 감지해 축약/wrap 단계 결정 */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: clip;
  min-width: 0;
}
/* 축약해도 안 들어가면 wrap 허용 (renderRegionLine이 적용) */
.vintage-modal__region--wrap {
  white-space: normal;
  word-break: keep-all;
  overflow-wrap: anywhere;
  overflow: visible;
}
.vintage-modal__variety {
  font-size: 12px;
  color: var(--muted);
  margin: 0;
  word-break: keep-all;
  overflow-wrap: anywhere;
}
.vintage-modal__close {
  background: rgba(255, 255, 255, .08);
  border: none;
  border-radius: 50%;
  width: 30px;
  height: 30px;
  font-size: 14px;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background .15s;
}
.vintage-modal__close:hover { background: rgba(255, 255, 255, .15); }

/* ── 빈티지 모달 바디 ── */
.vintage-modal__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 14px 20px 20px;
  min-height: 0;
}

/* 로딩 상태 */
.vintage-modal__loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 48px 20px;
  color: var(--muted);
  font-size: 14px;
}

/* 에러 상태 */
.vintage-modal__error {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 40px 20px;
  color: var(--danger);
  font-size: 14px;
  text-align: center;
}

/* 데이터 없음 메시지 */
.vintage-modal__empty {
  text-align: center;
  padding: 48px 20px;
  color: var(--muted);
  font-size: 14px;
}
.vintage-modal__empty--unknown { color: #9ca3af; }
.vintage-modal__unknown-note { display: block; margin-top: 8px; font-size: 12px; opacity: .7; }

/* ── Best Now 하이라이트 박스 ── */
.vintage-modal__best-now {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(251, 191, 36, .12);
  border: 1px solid rgba(251, 191, 36, .35);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 14px;
}
.vintage-modal__best-now-icon {
  font-size: 18px;
  flex-shrink: 0;
}
.vintage-modal__best-now-text {
  font-size: 14px;
  color: var(--gold);
}
.vintage-modal__best-now-text strong {
  color: var(--gold);
}
.vintage-modal__best-now-score {
  color: var(--gold);
  font-weight: 700;
}

/* ── 빈티지 테이블 스크롤 래퍼 ── */
.vintage-modal__table-wrap {
  flex: 1;
  overflow-x: auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: 10px;
  border: 1px solid var(--border);
  min-height: 0;
}
.vintage-modal__table-wrap::-webkit-scrollbar       { width: 4px; height: 4px; }
.vintage-modal__table-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

/* ── 빈티지 테이블 ── */
.vintage-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.vintage-table__head {
  position: sticky;
  top: 0;
  z-index: 2;
  background: #2a2440;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .6px;
  padding: 9px 14px;
  text-align: center;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.vintage-table__head--btn {
  padding: 4px 6px;
}
.vintage-sort-btn {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  padding: 4px 10px;
  min-width: 90px;
  white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, .2) !important;
  background: rgba(255, 255, 255, .06) !important;
  border-radius: 6px !important;
}
.vintage-sort-btn:hover {
  background: rgba(255, 255, 255, .12) !important;
  color: var(--text) !important;
}
.vintage-sort-btn.is-active {
  border-color: rgba(129, 140, 248, .5) !important;
  background: rgba(129, 140, 248, .15) !important;
  color: var(--accent2) !important;
}
.vsort-thumb-icon {
  width: 14px;
  height: 14px;
  vertical-align: middle;
  margin-left: 2px;
  /* brightness(0)으로 원본 정규화 후 --accent2(#818cf8) 인디고 tint */
  filter: brightness(0) saturate(100%) invert(64%) sepia(30%) saturate(700%) hue-rotate(204deg) brightness(103%);
}
.vsort-star {
  color: var(--gold, #fbbf24) !important;
  font-style: normal;
}
.vintage-table__row {
  background: rgba(255, 255, 255, .03);
  border-bottom: 1px solid rgba(255, 255, 255, .06);
  transition: background .12s;
}
.vintage-table__row:nth-child(even) { background: rgba(255, 255, 255, .065); }
.vintage-table__row:last-child { border-bottom: none; }
.vintage-table__row:hover { background: rgba(255, 255, 255, .11); }

/* Best Now 행 강조 — 노란색 얇은 테두리 + 황금빛 반투명 배경 */
.vintage-table__row--best {
  background: rgba(240, 192, 64, .10);
  outline: 1px solid rgba(240, 192, 64, .7);
  outline-offset: -1px;
  position: relative;
  z-index: 1;
}
.vintage-table__row--best:hover {
  background: rgba(240, 192, 64, .16);
}
.vintage-table__row--best .vintage-table__cell--year {
  font-weight: 700;
  color: #f0c040;
}

.vintage-table__cell {
  padding: 9px 14px;
  color: var(--text);
  vertical-align: middle;
  text-align: center;
}
.vintage-table__cell--year    { font-weight: 600; white-space: nowrap; }
/* 점수 컬럼: pill이 담당하므로 기본 색상 제거 */
.vintage-table__cell--score   { font-weight: 600; }
.vintage-table__cell--wrscore { font-size: 13px; color: var(--gold, #fbbf24); }
/* 별점 뱃지 — 라운드 박스 + 노란 텍스트 */
.vintage-wrscore {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  min-width: 46px;
  padding: 2px 7px;
  border-radius: 6px;
  background: rgba(251, 191, 36, .12);
  border: 1px solid rgba(251, 191, 36, .35);
  color: var(--gold, #fbbf24);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  justify-content: center;
}

/* ── 점수 pill ── */
/*
 * 배경색·텍스트색은 JS(_vintageScorePillStyle)가 인라인 style로 주입한다.
 * 80~89: 초록 그라데이션, 90~100: 보라 그라데이션, 80 미만/null: 어두운 회색
 */
.vintage-score-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  padding: 3px 7px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, .18);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}

/* ── 빈티지 상태 배지 — .vintage-score-pill과 동일한 박스 형상으로 통일 ── */
.vintage-status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  padding: 3px 7px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, .18);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}
.vintage-status--too-young  { background: #14B8A6; color: #fff; border-color: rgba(20, 184, 166, .6); }
.vintage-status--ready      { background: #16A34A; color: #fff; border-color: rgba(22, 163, 74, .6); }
.vintage-status--can-drink  { background: #16A34A; color: #fff; border-color: rgba(22, 163, 74, .6); }
.vintage-status--best-now   { background: #7C3AED; color: #fff; border-color: rgba(124, 58, 237, .6); }
.vintage-status--declining  { background: #4D4D4D; color: #fff; border-color: rgba(77, 77, 77, .6); }
.vintage-status--past-peak  { background: #92400E; color: #fff; border-color: rgba(146, 64, 14, .6); }
.vintage-status--undeclared { background: #C5C5C5; color: #555; border-color: rgba(197, 197, 197, .6); }

/* ── 빈티지 상태 필터 바 — 콤보 리스트 박스 ── */
.vintage-modal__filter-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

/* 콤보 래퍼 — 트리거 + 팝오버의 위치 기준 */
.vfilter-combo-wrap {
  position: relative;
}

/* 트리거 버튼 */
.vfilter-trigger {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 12px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  border: 1.5px solid rgba(255, 255, 255, .15);
  cursor: pointer;
  background: rgba(255, 255, 255, .07);
  color: var(--muted);
  transition: background .14s, border-color .14s, color .14s;
}
.vfilter-trigger:hover {
  background: rgba(255, 255, 255, .12);
  color: var(--text);
}
.vfilter-trigger.is-open {
  background: rgba(255, 255, 255, .14);
  border-color: rgba(255, 255, 255, .35);
  color: var(--text);
}
.vfilter-trigger.is-active {
  background: rgba(192, 132, 252, .18);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

/* 활성 선택 수 배지 */
.vfilter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .25);
  font-size: 10px;
  font-weight: 700;
  color: var(--text);
}

/* 팝오버 — 체크박스 리스트 */
.vfilter-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 200;
  min-width: 150px;
  background: var(--surface, #1e1e2e);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
  padding: 6px 0;
  overflow: hidden;
}

/* 팝오버 내 각 체크박스 행 */
.vfilter-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  cursor: pointer;
  font-size: 12px;
  color: var(--muted);
  transition: background .1s;
  user-select: none;
}
.vfilter-item:hover {
  background: rgba(255, 255, 255, .07);
  color: var(--text);
}
.vfilter-item.is-checked {
  color: var(--text);
}
.vfilter-item input[type="checkbox"] {
  accent-color: var(--accent, #6b8cff);
  width: 13px;
  height: 13px;
  flex-shrink: 0;
}

/* 상태 색상 도트 */
.vfilter-item-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.vfilter-item-name {
  white-space: nowrap;
}

/* 직전필터 버튼 */
.vfilter-prev-btn {
  padding: 5px 11px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  border: 1.5px solid rgba(255, 255, 255, .15);
  cursor: pointer;
  background: rgba(255, 255, 255, .07);
  color: var(--muted);
  transition: background .14s, border-color .14s, color .14s;
  white-space: nowrap;
}
.vfilter-prev-btn:hover {
  background: rgba(255, 255, 255, .12);
  color: var(--text);
}
.vfilter-prev-btn.is-active {
  border-color: var(--accent);
  background: rgba(192, 132, 252, .14);
  color: var(--accent);
}
.vfilter-prev-btn.no-snapshot {
  opacity: 0.4;
  pointer-events: none;
}

/* 팝오버 내 검색 입력창 + X 닫기 버튼 (같은 행) */
.vfilter-search-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 4px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.vfilter-search-input {
  flex: 1 1 auto;
  min-width: 0;
  box-sizing: border-box;
  padding: 5px 8px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, .15);
  background: rgba(255, 255, 255, .07);
  color: var(--text);
  font-size: 11px;
  font-family: inherit;
  outline: none;
}
.vfilter-search-input::placeholder { color: var(--muted); }
.vfilter-search-input:focus { border-color: rgba(255, 255, 255, .3); }

/* 팝오버 우상단 X 닫기 버튼 — vintage-modal__close와 시각적 일관성, 크기는 작게 */
.vfilter-popover__close {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .08);
  border: none;
  border-radius: 50%;
  color: var(--muted);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  padding: 0;
  transition: background .15s, color .15s;
}
.vfilter-popover__close:hover {
  background: rgba(255, 255, 255, .15);
  color: var(--text);
}

@media (max-width: 767px) {
  /* v2.1: 빈티지 배지 모바일 — 기본 .vintage-badge(좌하단 absolute) 위에 폰트·패딩만 축소.
   * .card-bottom-left stack은 v2.1에서 제거됨 — 빈티지·별점이 각자 absolute 단독 배치.
   */
  .vintage-badge {
    font-size: 9px;
    line-height: 1.2;
    padding: 2px 6px;
    gap: 2px;
  }

  /* ── 빈티지 모달: 모바일 풀스크린 시트 ──
   * 이전: align-items: flex-end + max-height: 92dvh
   *  → 컨텐츠가 짧거나 와인상태 필터로 행이 줄어들면 모달이 더 아래로 밀려 위쪽 빈 공간 발생
   * 변경: align-items: stretch + height/min-height: 100dvh
   *  → 컨텐츠 길이·필터 상태와 무관하게 항상 최상단부터 화면 전체를 채움
   */
  .vintage-modal-overlay {
    align-items: stretch;
    justify-content: center;
    padding: 0;
    /* 외부 스크롤 차단 — 본문만 스크롤하도록 한다 */
    overflow: hidden;
  }
  .vintage-modal {
    border-radius: 0;
    width: 100%;
    max-width: 100%;
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    /* flex column + overflow:hidden 유지 → 본문만 스크롤 */
  }
  /* 헤더 sticky 처리 — 와인 이름이 본문 스크롤 중에도 항상 보이도록 한다 */
  .vintage-modal__header {
    position: sticky;
    top: 0;
    z-index: 5;
    background: #1e1a2c;
    padding: 14px 16px 12px;
  }
  .vintage-modal__title    { font-size: 15px; }
  .vintage-modal__title-en { font-size: 12px; }
  .vintage-modal__region   { font-size: 11px; }
  .vintage-modal__variety  { font-size: 11px; }
  .vintage-modal__close   { width: 28px; height: 28px; }
  .vintage-modal__body   { padding: 12px 14px 18px; }

  /* 빈티지 테이블 — 가로 스크롤 완전 차단
   * 이전: overflow-x: visible (스크롤바는 없지만 부모 hidden에 의해 잘려보임)
   * 변경: overflow-x: hidden + table-layout: fixed + 셀 wrap 허용으로 100% 폭 안에 자연스럽게 배치
   */
  .vintage-modal__table-wrap { overflow-x: hidden; }
  .vintage-table             { font-size: 12px; table-layout: fixed; width: 100%; }
  .vintage-table__head       { padding: 7px 4px; font-size: 10px; letter-spacing: .3px; }
  .vintage-table__cell       { padding: 8px 4px; word-break: keep-all; overflow-wrap: anywhere; }
  /* 연도 컬럼: 폭 절약 (nowrap 유지하되 폰트만 축소) */
  .vintage-table__cell--year { font-size: 11px; }
  /* 헤더 정렬 버튼 — min-width 풀고 폰트 축소, wrap 허용 */
  .vintage-sort-btn          { min-width: 0; width: 100%; padding: 3px 4px; font-size: 10px; letter-spacing: .2px; white-space: normal; line-height: 1.15; }
  /* 상태 배지·점수 pill — 동일 박스 형상 유지, 길어도 줄바꿈 허용 (가로 스크롤 방지) */
  .vintage-status            { white-space: normal; min-width: 0; padding: 3px 5px; font-size: 10px; line-height: 1.25; }
  .vintage-score-pill        { white-space: normal; min-width: 0; padding: 3px 5px; font-size: 10px; line-height: 1.25; }
  .vintage-wrscore           { min-width: 0; padding: 2px 4px; font-size: 11px; }

  /* 와인상태 필터 바 — 화면 폭 안에 wrap 허용 */
  .vintage-modal__filter-bar { flex-wrap: wrap; }
  .vfilter-trigger,
  .vfilter-prev-btn { font-size: 11px; padding: 5px 10px; }

  /* 와인 상세 페이지 모바일 추가 조정은 .wd-* 클래스 자체 미디어 쿼리에서 처리. */
}

/* ── Empty / initial state ── */
.empty-state { text-align: center; padding: 80px 20px; color: var(--muted); }
.empty-icon  { font-size: 64px; margin-bottom: 16px; opacity: .3; }
.empty-text  { font-size: 15px; }

/* ── Load more indicator ── */
.load-more {
  text-align: center;
  padding: 24px 0 48px;
  color: var(--muted); font-size: 13px;
}
.load-more .spinner { display: inline-block; margin: 0 auto 8px; }

/* ══════════════════════════════════════════════════════════════
   하단 네비게이션 (시안 F · 미니멀 라인 + 떠 있는 섬)
   - 외곽 .bottom-nav-wrap는 fixed 컨테이너 (안전영역 패딩 흡수)
   - 내부 .bottom-nav가 라운드 박스(섬) 본체
   - z-index 200: 빈티지 모달(1100)·필터 팝업(500)에 자연 가려짐
   - HTML onclick 금지 — index-page.js에서 이벤트 위임 처리
   ══════════════════════════════════════════════════════════════ */
.bottom-nav-wrap {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 200;
  padding: 0 16px calc(3px + env(safe-area-inset-bottom, 0px));
  /* 네비 박스 밖 영역은 클릭 통과 (스크롤 등 본문 조작 방해 금지) */
  pointer-events: none;
}

.bottom-nav {
  pointer-events: auto;
  max-width: 480px;
  margin: 0 auto;
  background: rgba(26, 23, 36, .92);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 28px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .55),
              0 2px 6px rgba(0, 0, 0, .35),
              inset 0 1px 0 rgba(255, 255, 255, .05);
  padding-bottom: 6px;
}

.bottom-nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 8px 8px 4px;
}

/* 라인 아이콘 + 텍스트 라벨 아이템 (홈/검색/나의 와인/더보기) */
.bottom-nav__item {
  flex: 1;
  background: none;
  border: 0;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 6px 0;
  cursor: pointer;
  font-family: inherit;
  transition: color .12s;
}
.bottom-nav__item:hover { color: var(--text); }

.bottom-nav__svg {
  width: 22px;
  height: 22px;
  stroke: currentColor;
  stroke-width: 1.6;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.bottom-nav__label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: -.005em;
}

.bottom-nav__item.is-active { color: var(--accent); }
.bottom-nav__item.is-active .bottom-nav__svg { stroke-width: 2; }

/* 중앙 카메라 — 라운드 박스 안 보라 원 (튀어나오지 않음, 텍스트 라벨 없음) */
.bottom-nav__cam-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 2px 0 4px;
}

.bottom-nav__cam {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--accent);
  border: 0;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(192, 132, 252, .35);
  transition: transform .15s, box-shadow .15s;
}
.bottom-nav__cam:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(192, 132, 252, .5);
}
.bottom-nav__cam svg {
  width: 22px;
  height: 22px;
  stroke: #fff;
  stroke-width: 1.8;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ══════════════════════════════════════════════════════════════
   더보기 메뉴 (2026-10-02, js/more-menu.js) — 하단 네비 "더보기" 를 누르면 네비 바로 위에 뜨는 작은 메뉴.
   하단 네비가 있는 모든 페이지 공용(홈·나의 와인·와인 마시는 순서 — 모두 이 파일을 로드한다).
   위치: JS 가 네비 위치를 재서 --more-menu-right / --more-menu-bottom 으로 넘긴다(네비 오른쪽 끝·위쪽에 맞춤).
   z-index 210: 하단 네비(200) 위, 필터 팝업(500)·와인 상세 오버레이(1000) 아래.
   ══════════════════════════════════════════════════════════════ */
.more-menu {
  --more-menu-item-h: 56px;      /* 항목 높이 — 터치 영역 44px 이상 */
  --more-menu-icon: 22px;
  position: fixed;
  right: var(--more-menu-right, 16px);
  bottom: var(--more-menu-bottom, calc(84px + env(safe-area-inset-bottom, 0px)));
  z-index: 210;
  width: max-content;
  min-width: 232px;
  max-width: calc(100% - 32px);   /* fixed — 기준은 화면(초기 포함 블록) 폭 */
  padding: 6px;
  border-radius: 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .35);
  font-family: var(--font-base);
  animation: more-menu-in .14s ease-out;
  transform-origin: bottom right;
}
.more-menu[hidden] { display: none; }
/* 바깥 누르기를 받는 투명 막 — 하단 네비(200)까지 덮고 메뉴(210) 아래. 바깥 누르기는 닫기만 한다(밑의 카드·네비 버튼은 눌리지 않음) */
.more-menu-backdrop { position: fixed; inset: 0; z-index: 205; background: transparent; }
.more-menu-backdrop[hidden] { display: none; }
@keyframes more-menu-in {
  from { opacity: 0; transform: translateY(6px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.more-menu__item {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--more-menu-item-h);
  padding: 8px 14px 8px 12px;
  border-radius: 12px;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  transition: background .12s;
}
.more-menu__item:hover { background: rgba(var(--accent-rgb), .1); opacity: 1; }
.more-menu__item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.more-menu__icon {
  flex: none;
  width: var(--more-menu-icon);
  height: var(--more-menu-icon);
  stroke: var(--muted);
  stroke-width: 1.6;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.more-menu__text  { display: flex; flex-direction: column; min-width: 0; }
.more-menu__label { font-size: 15px; font-weight: 600; line-height: 1.35; white-space: nowrap; }
.more-menu__desc  { font-size: 12px; line-height: 1.35; color: var(--muted); white-space: nowrap; }
/* 현재 페이지에 해당하는 항목 */
.more-menu__item.is-active { background: rgba(var(--accent-rgb), .14); }
.more-menu__item.is-active .more-menu__label { color: var(--accent); }
.more-menu__item.is-active .more-menu__icon  { stroke: var(--accent); stroke-width: 2; }
/* 메뉴가 열려 있는 동안 더보기 버튼 강조 */
.bottom-nav__item[aria-expanded="true"] { color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .more-menu { animation: none; }
}

/* ══════════════════════════════════════════════════════════════
   와인잔 뱃지 — 검색 카드 "나의 와인" (2026-10-02, js/my-wine-glass.js)
   확정 시안 "골드 링": 흰 원형 칩 + 벌룬 와인잔, 상태 3가지.
     ① (기본) 빈 잔            — 윤곽선만, 링 없음
     ② .is-filled 채워진 잔    — 루비→버건디 그라데이션 와인 + 물결 2겹 찰랑 + 유리 광택 한 줄, 칩 둘레 금색 링
        + 우상단 작은 원형 + 장식(.wine-glass__plus). 버튼은 .wine-glass__btn 하나 — + 는 따로 눌리지 않고
        아이콘 어디를 눌러도 "한 번 더 추가" 확인으로 간다
     .is-filling 방금 추가 — 아래에서 위로 차오르는 1회 트랜지션 / .is-busy 요청 중
   위치: .card-img-wrap 우상단 카테고리 배지(.kind-overlay) 바로 아래. 스태프 출처 배지(상단 중앙)·
         하단 두 뱃지(빈티지·별점)와 겹치지 않는다.
   크기: .card-img-wrap(본 규칙에 container-type: inline-size) 폭 기준 cqw — :root 의 --glass-* 토큰에서 조절.
   성능: 움직임은 전부 transform(가로 이동·상하 출렁임) — 레이아웃을 건드리지 않는다.
         애니메이션은 .is-filled 뱃지에서만 돈다(빈 잔은 정지).
   SVG:  잔 볼 clipPath 는 문서 공용 <defs> 1개(#wineGlassBowlClip)를 참조. 도형 좌표·clip-path·수면 높이는
         SVG attribute(js SHAPE 상수), CSS 는 색·움직임만 담당.
   ══════════════════════════════════════════════════════════════ */
.wine-glass-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}
/* 공용 그라데이션(#wineGlassRuby)의 stop 색 */
.wine-glass-defs__stop--top    { stop-color: var(--glass-wine-top); }
.wine-glass-defs__stop--bottom { stop-color: var(--glass-wine-bottom); }
.wine-glass {
  position: absolute;
  top: var(--glass-top);
  right: var(--glass-right);
  z-index: 2;
  width: var(--glass-size);
  height: var(--glass-size);
  display: block;
}
/* 잔 본체 — 흰 원형 칩 */
.wine-glass__btn {
  position: absolute;
  inset: 0;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--glass-chip-bg);
  color: var(--glass-line);
  box-shadow: 0 2px 8px rgba(40, 20, 30, .22);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s, box-shadow .2s, opacity .15s;
}
/* 터치 영역 확장 — 보이는 원은 작게 두고 누를 수 있는 범위만 --glass-touch 로 넓힌다 */
.wine-glass__btn::before {
  content: '';
  position: absolute;
  inset: calc((var(--glass-size) - var(--glass-touch)) / 2);
  /* 원이 아니라 둥근 사각형 — 칩 모서리 밖으로 살짝 나간 + 장식까지 덮어 그 위의 탭이 카드로 새지 않게 */
  border-radius: 30%;
}
.wine-glass__btn:hover         { transform: scale(1.08); box-shadow: 0 3px 10px rgba(40, 20, 30, .32); }
.wine-glass__btn:active        { transform: scale(.92); }
.wine-glass__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wine-glass.is-filled .wine-glass__btn {
  color: var(--glass-line-on);
  /* 등록 표시 — 칩 둘레 금색 링 (hover 에도 유지) */
  box-shadow: 0 0 0 var(--glass-ring-w) var(--glass-ring), 0 2px 8px rgba(40, 20, 30, .25);
}
.wine-glass.is-filled .wine-glass__btn:hover { box-shadow: 0 0 0 var(--glass-ring-w) var(--glass-ring), 0 3px 10px rgba(40, 20, 30, .32); }
/* 방금 추가된 순간 — 금색 링은 잔이 다 찬 뒤에 나타난다 */
.wine-glass.is-filling .wine-glass__btn { transition: transform .12s, box-shadow .3s ease-out var(--glass-fill-ms); }
/* 요청 중 — 시각 표시만. pointer-events 를 끄면 재클릭이 카드로 통과해 상세가 열리므로 끄지 않는다(중복 요청은 JS busy Set 이 막는다) */
.wine-glass.is-busy { opacity: .6; }
/* 카테고리 배지가 없는 카드 — 잔 위가 비지 않게 배지 자리로 올린다 */
.card-img-wrap:not(:has(> .kind-overlay)) > .wine-glass { top: var(--glass-top-solo); }
/* 검색 카드의 카테고리 배지 — 잔의 (보이지 않는) 터치 확장 영역보다 위에서 탭을 받아 카드 열기로 넘긴다 */
.card-img-wrap > .kind-overlay { pointer-events: auto; z-index: 3; }

.wine-glass__svg {
  display: block;
  width: 68%;
  height: 80%;
  overflow: visible;
  pointer-events: none;
}
.wine-glass__outline {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke .3s;
}
/* 앞 물결의 fill 은 SVG attribute(url(#wineGlassRuby)) — 외부 CSS 의 url(#…) 은 브라우저에 따라 스타일시트 기준으로 풀려 CSS 에 두지 않는다 */
.wine-glass__wave--back  { fill: var(--glass-wine-back); opacity: .85; }
/* 유리 광택 — 채워졌을 때만 */
.wine-glass__gloss {
  fill: none;
  stroke: var(--glass-gloss);
  stroke-width: 1.8;
  stroke-linecap: round;
  opacity: 0;
}
.wine-glass.is-filled  .wine-glass__gloss { opacity: .75; }
.wine-glass.is-filling .wine-glass__gloss { transition: opacity .3s ease-out var(--glass-fill-ms); }

/* 와인 높이 — 빈 잔은 잔 볼 아래로 내려 보이지 않게, 채워지면 제자리로 */
.wine-glass__liquid { transform: translateY(26px); }
.wine-glass.is-filled  .wine-glass__liquid { transform: translateY(0); }
.wine-glass.is-filling .wine-glass__liquid { transition: transform var(--glass-fill-ms) cubic-bezier(.22, .8, .3, 1); }

/* 찰랑임 — 앞·뒤 물결이 서로 반대 방향·다른 속도로 흐르고, 수면 전체가 살짝 오르내린다 */
.wine-glass.is-filled .wine-glass__wave--front { animation: wine-glass-wave 2.4s linear infinite; }
.wine-glass.is-filled .wine-glass__wave--back  { animation: wine-glass-wave 3.6s linear infinite reverse; }
.wine-glass.is-filled .wine-glass__bob         { animation: wine-glass-bob 2.6s ease-in-out infinite; }
/* 화면 밖 잔은 정지 — JS IntersectionObserver 가 화면 안 잔에만 .is-inview 를 붙인다 (위 animation 축약형 뒤에 와야 이긴다) */
.wine-glass:not(.is-inview) .wine-glass__wave,
.wine-glass:not(.is-inview) .wine-glass__bob { animation-play-state: paused; }
@keyframes wine-glass-wave {
  from { transform: translateX(-24px); }   /* 물결 한 주기(24 단위) — 이음매 없이 반복 */
  to   { transform: translateX(0); }
}
@keyframes wine-glass-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(1.2px); }
}

/* + 장식 — 등록된 잔의 우상단. 버튼 안의 그림일 뿐 따로 눌리지 않는다(pointer-events: none).
 * 칩 밖으로 살짝 나간 부분의 탭은 버튼의 터치 확장 영역(::before)이 받아 같은 동작으로 간다. */
.wine-glass__plus {
  position: absolute;
  top: -7%;
  right: -7%;
  width: 42%;
  height: 42%;
  min-width: var(--glass-plus-min);
  min-height: var(--glass-plus-min);
  display: none;
  place-items: center;
  box-sizing: border-box;
  border: var(--glass-plus-border) solid var(--glass-plus-fg);
  border-radius: 50%;
  background: var(--glass-plus-bg);
  box-shadow: 0 2px 5px rgba(60, 10, 25, .35);
  pointer-events: none;
}
.wine-glass.is-filled .wine-glass__plus { display: grid; }
/* 방금 추가된 순간에는 잔이 다 찬 뒤에 + 가 나타난다 */
.wine-glass.is-filling .wine-glass__plus { animation: wine-glass-plus-in .25s ease-out var(--glass-fill-ms) backwards; }
.wine-glass__plus svg  { display: block; width: 60%; height: 60%; }
.wine-glass__plus path { fill: none; stroke: var(--glass-plus-fg); stroke-width: 3; stroke-linecap: round; }
@keyframes wine-glass-plus-in {
  from { opacity: 0; transform: scale(.4); }
  to   { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  /* 움직임 줄이기 — 정지된 채움으로 표시 */
  .wine-glass__btn,
  .wine-glass__outline,
  .wine-glass.is-filling .wine-glass__btn,
  .wine-glass.is-filling .wine-glass__gloss,
  .wine-glass.is-filling .wine-glass__liquid { transition: none; }
  .wine-glass.is-filled .wine-glass__wave--front,
  .wine-glass.is-filled .wine-glass__wave--back,
  .wine-glass.is-filled .wine-glass__bob,
  .wine-glass.is-filling .wine-glass__plus { animation: none; }
}

/* ══════════════════════════════════════════════════════════════
   공용 확인 다이얼로그 (2026-10-02, js/confirm-dialog.js) — window.confirm 대체
   z-index 1200: 와인 상세(1000)·빈티지 차트(1100) 위.
   ══════════════════════════════════════════════════════════════ */
.confirm-dialog {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(0, 0, 0, .6);
  font-family: var(--font-base);
  animation: confirm-dialog-in .14s ease-out;
}
.confirm-dialog[hidden] { display: none; }
.confirm-dialog__box {
  width: 100%;
  max-width: 340px;
  padding: 22px 20px 16px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .55);
}
.confirm-dialog__msg {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text);
  word-break: keep-all;
}
.confirm-dialog__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 18px;
}
.confirm-dialog__btn {
  min-width: 76px;
  min-height: 40px;
  padding: 9px 16px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted);
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: background .15s, color .15s, opacity .15s;
}
.confirm-dialog__btn:hover         { color: var(--text); background: rgba(255, 255, 255, .04); }
.confirm-dialog__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.confirm-dialog__btn--ok {
  border-color: transparent;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #fff;
}
.confirm-dialog__btn--ok:hover {
  color: #fff;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  opacity: .92;
}
@keyframes confirm-dialog-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .confirm-dialog { animation: none; }
}

/* ══════════════════════════════════════════════════════════════
   공용 토스트 (2026-10-02, js/toast.js) — 하단 네비 위. 확인 다이얼로그(1200)보다 위.
   ══════════════════════════════════════════════════════════════ */
.app-toast {
  position: fixed;
  left: 50%;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 1250;
  max-width: calc(100vw - 32px);
  padding: 10px 18px;
  border-radius: 999px;
  background: rgba(var(--bg-rgb), .96);
  border: 1px solid var(--accent);
  color: var(--text);
  font-family: var(--font-base);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
  pointer-events: none;
}
.app-toast[hidden] { display: none; }
.app-toast--error  { border-color: var(--danger); }
