/* 基礎重置 */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

body {
  background-color: #f8f5ee; /* 暖米白底色 */
  color: #1a1a1a;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* ============================================================
   Homepage V2（正式版，移植自 prototypes/home-v2/ 已驗收的視覺 baseline）。
   Street Editorial / Neo-Brutalism：紙張底色、黃／藍撞色、粗黑框、
   flat color only（無 gradient／blur／glow／glassmorphism／soft shadow）；
   「offset」一律是硬邊、不透明、zero-blur 的疊層（box-shadow 或 ::before），
   不是傳統柔和陰影。
   整段 scope 在 body.home-v2 底下（跟 body.map-page 已經覆寫共用 body{} 的
   模式一致），不會外洩到 map.html，也不會被 map.html 的樣式影響。 */
body.home-v2 {
  display: flex;
  flex-direction: column;
  /* 共用的 body{} 只設了 display/justify-content/align-items/min-height 四個
     屬性；這裡覆寫了 display，但先前遺漏覆寫 justify-content／align-items，
     導致那兩個屬性仍套用共用 body{} 的 center／center，使 .topbar、
     .site-footer 這種沒有自己明確寬度的 flex 子元素被壓成內容本身的寬度
     並置中，而不是撐滿整行——這就是 Header／Footer 在較寬版面「偏縮在中間」
     的根因。明確設回 flex-start／stretch 才能讓子元素正常撐滿寬度。 */
  justify-content: flex-start;
  align-items: stretch;
  min-height: 100vh;
  background-color: var(--color-paper);
  color: var(--color-black);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;

  /* ---- Neo-Brutalist color tokens ---- */
  --color-paper: #f4f4f0;
  --color-black: #000000;
  --color-yellow: #ffd400; /* Pantone 012 C 方向 */
  --color-blue: #0057ff; /* 高飽和亮藍 */
  --color-blue-deep: #001489; /* Pantone Reflex Blue C 方向，用於偏移疊層 */
  --border-thick: 4px;
  --border-thin: 2px;

  /* ---- Font tokens（Section E）：集中管理，不在各 selector 各自 hardcode ---- */
  --font-display-zh: "Chiron Hei HK WS", "PingFang TC", "Heiti TC",
    "Microsoft JhengHei", sans-serif;
  --font-display-latin: "Unbounded", sans-serif;
  --font-body-zh: "Chiron Hei HK WS", "PingFang TC", "Heiti TC",
    "Microsoft JhengHei", sans-serif;

  font-family: var(--font-body-zh);
  font-weight: 400;
}

body.home-v2 img {
  max-width: 100%;
  display: block;
}

body.home-v2 button {
  /* 共用的全域 * { font-family: 系統字型 } reset 會直接鎖定每個元素本身，
     單純 inherit 會拿到那個系統字型而不是 body.home-v2 想要的中文字型，
     所以這裡直接指定 --font-body-zh，個別 button（如 .cta-btn）需要別的
     字型時再各自覆寫。 */
  font-family: var(--font-body-zh);
}

/* ============ Top Bar ============
   寬度對齊主要內容欄（跟 .page 用同一個 max-width，一起置中），讓左側品牌
   與右側 Language dropdown 貼齊內容區左右邊界，divider（border-bottom）也
   只橫跨這個內容寬度，不是滿版視窗寬——避免版面較寬時 header 與下方內容
   欄的邊界對不齊。手機寬度（<560px）視覺上不受影響，效果等同原本滿版。 */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: 9px 16px;
  border-bottom: var(--border-thick) solid var(--color-black);
  background-color: var(--color-paper);
  position: relative;
  z-index: 40;
  flex: 0 0 auto;
}

.topbar-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.topbar-logo {
  height: 26px;
  width: auto;
  flex: 0 0 auto;
  /* Logo 素材帶白底；multiply 讓白底融入紙張背景，只留下黑色線稿。
     純顯示層處理，不修改原始檔案。 */
  mix-blend-mode: multiply;
}

.topbar-title {
  font-family: var(--font-body-zh);
  font-size: 0.95rem;
  font-weight: 800;
  line-height: 1.2;
  /* 正式站名較長的語言（en／id／vi）在 360px 與語言選單同列時，允許在單字間換成兩行，
     不撐開 Header、不造成橫向溢出；zh／ja／ko 的標題夠短，維持單行。 */
  white-space: normal;
  min-width: 0;
}

.lang-dropdown {
  position: relative;
  flex: 0 0 auto;
}

.lang-dropdown-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 32px;
  padding: 0 11px;
  background-color: var(--color-yellow);
  border: var(--border-thin) solid var(--color-black);
  border-radius: 6px;
  font-family: var(--font-body-zh);
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--color-black);
  cursor: pointer;
  white-space: nowrap;
}

.lang-dropdown-toggle:active {
  transform: translateY(1px);
}

.lang-caret {
  font-size: 0.7rem;
  line-height: 1;
}

.lang-dropdown-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 45;
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 168px;
  max-width: calc(100vw - 32px);
  background-color: var(--color-paper);
  border: var(--border-thick) solid var(--color-black);
  border-radius: 6px;
  overflow: hidden;
}

.lang-dropdown-menu[hidden] {
  display: none;
}

.lang-dropdown-menu li {
  padding: 9px 12px;
  font-family: var(--font-body-zh);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  border-bottom: 1.5px solid var(--color-black);
}

.lang-dropdown-menu li:last-child {
  border-bottom: none;
}

.lang-dropdown-menu li:hover,
.lang-dropdown-menu li:focus-visible {
  background-color: var(--color-yellow);
  outline: none;
}

.lang-dropdown-menu li[aria-selected="true"] {
  background-color: var(--color-blue);
  color: var(--color-paper);
  font-weight: 800;
}

/* ============ Page shell ============ */
.page {
  flex: 1 0 auto;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: 0 16px 40px;
}

/* ============ Hero ============ */
.hero {
  padding-top: 14px;
}

.hero-tag {
  display: inline-block;
  font-family: var(--font-body-zh);
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--color-paper);
  background-color: var(--color-blue);
  border-radius: 5px;
  padding: 4px 10px;
}

.hero-title {
  margin: 8px 0 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* 純色 editorial 標題——不做 sticker box、不加框、不旋轉、不加 offset
   shadow，兩行文字單純靠顏色對比建立層級。中文用 --font-display-zh
   （Chiron Hei HK），刻意不讓 Unbounded 出現在這裡的 font-family 名單裡。 */
.hero-line {
  font-family: var(--font-display-zh);
  font-size: 38px;
  line-height: 1.08;
  font-weight: 900;
  letter-spacing: -0.01em;
}

.hero-line--blue {
  color: var(--color-blue);
  margin-top: 1px;
}

/* 非 zh 語言時，中文 Hero 下方加一行該語言翻譯：視覺刻意弱於 Hero（小字、
   一般字重、灰階），不加框、不加 badge，不與 Hero 搶焦點。zh 時這個元素
   不存在於 DOM（由 app.js 動態插入／移除），不是用 CSS 隱藏。 */
.hero-translation {
  margin: 6px 0 0;
  font-family: var(--font-body-zh);
  font-size: 14px;
  line-height: 1.4;
  font-weight: 500;
  color: #55554f;
}

/* Homepage 韓文字體對齊 Map／Detail：Chiron Hei HK 沒有韓文字形，原本 Homepage 這些
   元素的 font-family 是 Chiron／PingFang TC／Heiti TC／Microsoft JhengHei，韓文會落到
   「zh-TW 語境」的 fallback；Map／Detail 的韓文則是全域 * reset 的系統 sans-serif
   （-apple-system…）。只在 ko 時，把 Homepage 會隨語言切換的元素改成同一組系統字型；
   zh／en／ja／id／vi 與 font-weight 都不動。 */
body.home-v2[data-lang="ko"] :is(.topbar-title, .hero-tag, .hero-translation, .cta-btn, .how-header-sub) {
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

.hero-media-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-top: 16px;
}

.monster-frame {
  position: relative;
  flex: 1 1 auto;
  max-width: 260px;
  aspect-ratio: 4 / 3.4;
  border: var(--border-thick) solid var(--color-black);
  background-color: var(--color-blue);
  /* 單一硬邊黃色 offset：純色、zero-blur，無自己的邊框，因此這個元件只有一圈黑框
     （frame 本身的），不是雙重外框。以 box-shadow 取代原本 z-index:-1 的 ::before 疊層
     （-8px 8px、spread -4px 與原本「padding box 平移 (-8px, 8px)」的幾何完全相同，
     露出來的左側與下側黃邊像素一致），陰影一定畫在元素自己的邊框與背景「之下」，
     不依賴負 z-index 的疊放順序，避免部分手機瀏覽器把黃色疊層畫到底邊黑框上。
     這裡不設 overflow:hidden——黃色 offset 需要露出到這個元素的邊界之外；
     裁切改在下一層的 .monster-frame-crop 處理。 */
  box-shadow: -8px 8px 0 -4px var(--color-yellow);
}

/* 裁切層絕對定位鋪滿 frame 的 padding box（也就是黑框「內側」）：高度不再靠
   height:100% 去解析 aspect-ratio 推算出來的父層高度（部分手機瀏覽器對此不是 definite，
   會讓圖片以自然比例撐高、蓋過底邊黑框）。 */
.monster-frame-crop {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.monster-frame-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 原始 JPG 本身帶手繪黑框＋白色留白；在這層裁掉留白與手繪框，只露出
     藍底＋小怪獸主體，改用我們自己的黑框——純顯示層裁切，原始檔案未被修改。 */
  object-position: 50% 42%;
}

/* 近正方形 CTA：兩行短字，黑粗框，黃底，藍色硬式 offset（zero-blur
   box-shadow）。按鈕／Badge 類文字優先用 --font-body-zh 700–900。 */
.cta-btn {
  flex: 0 0 auto;
  width: 92px;
  height: 92px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 0;
  background-color: var(--color-yellow);
  border: var(--border-thick) solid var(--color-black);
  color: var(--color-black);
  font-family: var(--font-body-zh);
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.3;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 6px 6px 0 var(--color-blue-deep);
}

.cta-btn:active {
  transform: translate(3px, 3px);
  box-shadow: 3px 3px 0 var(--color-blue-deep);
}

/* en/id/vi 的翻譯詞比中文/日文/韓文長，維持同一顆正方形按鈕尺寸／視覺，
   只縮小字級與字距，避免在 360px 也不溢出。由 app.js 依目前語言加上。 */
.cta-btn--compact {
  font-size: 0.8rem;
  letter-spacing: 0;
}

/* CTA 文案只有一個來源；兩行的視覺由 CSS 折行產生：
   中文／日文用字數上限（em）讓文字折成兩行，其餘語言依單字自然折行（text-wrap:balance）。 */
.cta-btn-label {
  display: block;
  max-width: 100%;
  padding: 0 6px;
  text-align: center;
  text-wrap: balance;
  overflow-wrap: break-word;
}

body.home-v2[data-lang="zh"] .cta-btn-label {
  max-width: 2.3em;
  padding: 0;
}

body.home-v2[data-lang="ja"] .cta-btn-label {
  max-width: 3.3em;
  padding: 0;
}

.cta-btn:focus-visible {
  outline: 3px solid var(--color-blue);
  outline-offset: 3px;
}

/* ============ HOW TO DRINK（大型 media frame） ============
   刻意夠高、允許頁面超過一個 viewport——重點是標題與 frame 上緣已經在
   首屏可見，讓使用者自然知道下面還有內容。 */
.how-section {
  margin-top: 40px;
  padding-top: 20px;
  border-top: var(--border-thick) solid var(--color-black);
}

.how-header {
  margin-bottom: 16px;
}

/* 英文 editorial 標題用 --font-display-latin（Unbounded 900）；中文副標
   用 --font-body-zh（Chiron Hei HK），字重不做到 Black，維持次要層級。 */
.how-header-title {
  margin: 0;
  font-family: var(--font-display-latin);
  font-size: 20px;
  font-weight: 900;
  letter-spacing: 0.01em;
}

.how-header-sub {
  margin: 3px 0 0;
  font-family: var(--font-body-zh);
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--color-black);
}

.how-frame {
  position: relative;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background-color: var(--color-paper);
  border: var(--border-thick) solid var(--color-black);
}

/* 單一硬邊藍色 offset 層，右＋下（不是只有右側），純色、無自己的邊框。 */
.how-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: translate(8px, 8px);
  background-color: var(--color-blue);
  z-index: -1;
}

.how-frame-play {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background-color: var(--color-yellow);
  border: var(--border-thick) solid var(--color-black);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

.how-frame-play:active {
  transform: translateY(1px);
}

.how-frame-play:focus-visible {
  outline: 3px solid var(--color-blue);
  outline-offset: 3px;
}

.how-frame-caption {
  margin: 0;
  font-family: var(--font-body-zh);
  font-size: 0.86rem;
  font-weight: 800;
  letter-spacing: 0.06em;
}

/* ============ Footer ============
   一般 document flow（body.home-v2 是 flex column，.page 用 flex:1 0 auto
   吃滿剩餘高度）：內容短時 footer 自然貼在 viewport 底部；內容變長（例如
   之後放入正式 GIF／影片）時 footer 自然跟著往下，不用 position:fixed／
   sticky，也不會在 footer 後方留下人工撐出的空白。 */
.site-footer {
  flex: 0 0 auto;
  background-color: var(--color-black);
  color: var(--color-paper);
  text-align: center;
  font-family: var(--font-body-zh);
  font-size: 0.68rem;
  font-weight: 700;
  padding: 12px 16px;
}

/* ============ Responsive safety ============ */
@media (max-width: 380px) {
  .cta-btn {
    width: 82px;
    height: 82px;
    font-size: 0.95rem;
  }
}

/* 頁面二：地圖頁專屬樣式（Map Mode UI Redesign 收尾：Header 直接沿用首頁現行
   正式版 .topbar／.topbar-brand／.topbar-logo／.topbar-title／.lang-dropdown*
   這幾個共用 class 與 DOM 結構（定義於本檔案上方首頁區塊），不再另外維護一份
   視覺副本——同一份 CSS 規則同時驅動兩個頁面的 header，保證「完全一致」不會
   日後改一邊漏改另一邊。這些共用 class 讀的 --color- 系列與 --font-body-zh
   這幾個 token，已在上方 body.map-page 規則裡用相同的值再宣告一次（見該處註解）。
   地圖頁 header 與首頁唯一的行為差異：logo 改成可點擊、點擊返回首頁（見
   map.html 的 #map-logo-home 與 map.js 的對應 click handler）；首頁本身沒有
   這個互動，因為首頁本身就是首頁。 */
/* 首頁的 .topbar-brand 是純 div（不可點擊）；地圖頁需要可點擊回首頁，改用 <a>
   包住同一份 Logo DOM（不是改成有樣式的 button，避免瀏覽器原生 button 外觀／
   appearance 造成不該存在的框線）。這裡只重置這顆連結自己的原生外觀，不動
   .topbar-brand 共用規則本身，首頁完全不受影響。focus-visible 才顯示外框
   （鍵盤導覽可見），不是常駐外框。 */
#map-logo-home {
  display: flex;
  border: 0;
  background: none;
  padding: 0;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}

#map-logo-home:focus-visible {
  outline: 2px solid #0057ff;
  outline-offset: 2px;
}

/* 地圖容器 (手繪粗框風) */
#map {
  width: 100%;
  flex: 1; /* 佔滿剩餘高度 */
  border: 2.5px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 3.5px 3.5px 0px #1a1a1a;
  z-index: 1;
}

/* ============================
   Phase 1：地圖頁 (map.html) 專屬容器
   Mobile First + 100dvh（含 100vh fallback），
   避免行動版網址列伸縮造成外層頁面出現捲軸
   ============================ */
body.map-page {
  /* Header 內縮根因：共用的 body{} 只設了 display/justify-content/align-items/
     min-height；body.map-page 先前只覆寫 min-height/overflow，align-items:center
     仍從 body{} 繼續套用。.topbar 現在是 body 的直接子元素（不再包在
     .map-container-page 裡），若不覆寫成 column／stretch，會被那個殘留的
     align-items:center 壓成內容寬度並置中，而不是撐滿整行——這正是「Header
     明顯向內縮」的根因（跟先前 body.home-v2 同一類根因，見該處註解）。 */
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: stretch;
  min-height: 100vh;
  min-height: 100dvh;
  /* Map Mode 單一 viewport：用固定的 100dvh 高度（含 100vh fallback）取代只有 min-height，
     內容再多也不會把 body 撐高；剩餘高度 = viewport − Topbar − Controls，由
     .map-container-page → .content-area → #map-view → #map 這條 flex:1／min-height:0
     鏈吃滿，不寫任何固定 px 的地圖高度。List Mode 則由 #card-view 自己捲動。 */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  /* 共用的 body{} 背景色是 #f8f5ee，跟首頁 body.home-v2 用的 --color-paper
     (#f4f4f0) 不同色階；地圖頁整體背景色要與首頁完全一致，這裡明確覆寫一次。 */
  background-color: #f4f4f0;

  /* Header 直接沿用首頁的 .topbar／.topbar-brand／.topbar-logo／.topbar-title／
     .lang-dropdown* 這幾個共用 class（見下方 HTML），不再另外維護一份視覺副本
     ——避免兩邊各自一套規則，日後改一邊忘了改另一邊，樣式跟著跑掉。這些共用
     class 本身讀的是 --color-*／--font-body-zh 這幾個 token，原本只 scope 在
     body.home-v2 底下，這裡用同樣的值再宣告一次給 body.map-page，讓同一份 CSS
     規則在兩個頁面都能正確取值。 */
  --color-paper: #f4f4f0;
  --color-black: #000000;
  --color-yellow: #ffd400;
  --color-blue: #0057ff;
  --border-thick: 4px;
  --border-thin: 2px;
  --font-body-zh: "Chiron Hei HK WS", "PingFang TC", "Heiti TC",
    "Microsoft JhengHei", sans-serif;
  --font-display-latin: "Unbounded", sans-serif; /* 與 body.home-v2 同一個 token／同一份自架 asset */
}

.map-container-page {
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  /* Header 移到 body 外層、跟 .map-container-page 變成 sibling 後，這裡不能再用
     固定 height:100vh（那會跟 Header 自己的高度疊加、超出 100vh）。改用
     flex:1 撐滿 body 扣掉 Header 後的剩餘高度，min-height:0 讓內部
     overflow/flex 子元素（#map 等）在 flex 容器裡也能正確收縮，不被內容撐爆。 */
  flex: 1 1 auto;
  min-height: 0;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* ============================
   Phase 2：Place UI Prototype
   ============================ */

/* 地圖 / 清單 View 切換：Map Mode UI Redesign 改為同一顆 segmented control 的
   左右兩半——共用一圈黑粗框＋圓角，中間一條分隔線；選取時填滿藍色底＋白字，
   未選取則是淺底＋黑字，不另外加誇張陰影（維持跟 Filter Chip 一致的克制陰影
   語彙）。data-view 屬性與既有 click handler 完全不變，只換視覺。 */
.view-switch {
  flex: 0 0 auto;
  display: flex;
  min-width: 0;
  border: 2px solid #1a1a1a;
  border-radius: 0;
  overflow: hidden;
  background-color: #f8f5ee;
}

/* min-width:0 + ellipsis：翻譯較長的語言（例如 vi「Danh Sách」）在 360px 且與
   Filter Chip 同一列時，寧可文字省略號截斷，也不能撐開整列造成橫向溢出。 */
.view-switch-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  position: relative;
  background-color: transparent;
  border: none;
  padding: 0.3rem 0.4rem;
  font-size: 0.6rem;
  font-weight: 700;
  color: #1a1a1a;
  cursor: pointer;
  white-space: nowrap;
  min-height: 34px;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.view-switch-btn + .view-switch-btn {
  border-left: 2px solid #1a1a1a;
}

.view-switch-btn.active {
  background-color: #0057ff;
  color: #ffffff;
}

.view-switch-btn:active {
  opacity: 0.85;
}

/* 控制列固定兩層、全部靠左（不用 space-between／不靠右／不等寬拉伸）：
   Row 1（.filter-bar-row，Utility）：.view-switch（Map／List）＋ .location-entry-group
   （定位＋Info，只在 List Mode 顯示）。兩個 group 各自保持完整，用 flex-wrap 以「group」
   為單位換行（較長語言空間不足時，定位 group 自然換到下一列，Map／List 兩半不會被拆散）。
   Row 2（.filter-chip-group）：Filter Chip，同樣靠左，空間不足時以「chip」為單位換行。
   position:relative 是 .location-info-popover 的定位錨點（見該規則）。 */
.filter-bar {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding-bottom: 0.15rem;
  margin-bottom: 0.5rem;
  flex: 0 0 auto;
}

.filter-bar-row {
  position: relative;
  max-width: 100%;
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 6px 8px;
  --control-label-h: 38px; /* .view-switch 本身 34px＋上下 2px 外框 */
}

/* Controls 說明文字（「模式：」「類別：」）：純文字，不是 button／chip——黑字、無框、無底、
   無陰影、無圓角，字重 700。min-height 對齊該列第一排控制項的高度（--control-label-h），
   讓 label 與 Map／List 切換、Filter Chip 的第一排垂直置中；group 換行後 label 仍停在第一排。
   nowrap：label 本身不換行，空間不足時換行的是右側的 group／chip。 */
.control-row-label {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: var(--control-label-h, 34px);
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1.25;
  color: #000000;
  text-align: right; /* label 在左欄內右對齊（controls 本身仍靠左） */
  justify-content: flex-end;
  white-space: nowrap;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}

/* Row 1 右側：.view-switch ＋ .location-entry-group。兩個 group 各自完整不被拆開，
   空間不足（例如 vi／id 在 360px）時以 group 為單位換到下一排，並停在 label 右側的同一條左緣。 */
.control-row-items {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: center;
  gap: 6px 14px;
}

/* Row 2：「類別：」＋ .filter-chip-group */
.filter-chip-row {
  max-width: 100%;
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 6px 8px;
}

.filter-chip-row .filter-chip-group {
  flex: 0 1 auto;
}

/* Two-column layout：左欄是共用寬度的 label 欄（max-content，由最長的 label 決定，
   不是固定 px），右欄是 controls 欄（minmax(0,1fr)，靠左、可換行）。兩個 row 用 subgrid
   共用同一組欄，所以「模式」「類別」在 label 欄內右對齊、右側 controls 的左緣在所有語言
   都是同一條線。label 用 text-align:right，不用 transform／absolute／magic margin。
   不支援 subgrid 的舊瀏覽器退回上面的 flex 版本（label 各自貼在 controls 左側）。 */
@supports (grid-template-columns: subgrid) {
  .filter-bar {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    justify-items: start;
    align-items: start;
    column-gap: 10px;
  }

  .filter-bar-row,
  .filter-chip-row {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    column-gap: 10px;
    width: 100%;
  }

  .control-row-label {
    justify-self: stretch;
  }
}

/* 靠左的自然寬度 group（不是 flex:1 平分空間）；三顆篩選按鈕依 icon+文字內容自然撐開，
   不等寬。flex-wrap + gap 取代原本的 margin-right，讓換行後行與行之間也有一致間距。 */
.filter-chip-group {
  max-width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: center;
  gap: 6px 3px;
  min-width: 0;
}

/* 篩選按鈕：寬度依內容自然決定（flex:0 0 auto，不是 flex:1 平分、不強制等寬）；
   彼此間距用 margin-right（最後一顆歸零），不是容器 gap。
   未選取＝paper 底＋1px 黑框＋黑字；選取＝黑底＋白字（icon 跟隨白色），邊框維持 1px 黑，
   不加陰影；三顆 Category 共用同一套 neutral 互動，藍色只屬於 Mode 切換／特殊身分。
   無圓角（Map Mode 全面改直角）。 */
.filter-chip {
  flex: 0 0 auto;
  width: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  max-width: 100%; /* 單一 chip 翻譯長到超過整排時，才允許文字換行（最後 fallback） */
  background-color: #f8f5ee;
  border: 1px solid #1a1a1a;
  border-radius: 0;
  padding: 0.3rem 0.36rem;
  font-size: 0.52rem;
  font-weight: bold;
  color: #1a1a1a;
  cursor: pointer;
  min-height: 34px;
}

/* Filter Icon：與 Marker 共用同一份 ICON_SVG（由 map.js 注入，stroke-only、
   fill:none），僅在此控制顯示尺寸，未選取／選取都不額外套用填色。 */
.filter-chip-icon {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}

.filter-chip-icon svg {
  width: 11px;
  height: 11px;
  display: block;
}

.filter-chip.active {
  background-color: #1a1a1a;
  border-color: #1a1a1a;
  color: #ffffff;
}

/* 選取時 icon 跟隨白字（ICON_SVG 的 stroke 是 attribute，CSS 可直接覆寫） */
.filter-chip.active .filter-chip-icon svg {
  stroke: #ffffff;
}

.filter-chip {
  transition: transform 100ms ease, border-color 100ms ease;
}

.filter-chip:active {
  transform: translate(1px, 1px) scale(0.97);
}

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

/* Filter Chip（美食／販賣機／景點）與 Map／List 切換的統一字級：六語共用同一個
   baseline（0.8rem／700），不再逐語言縮字。較長的語言改由上方兩層 Layout 的 flex-wrap
   吸收（group 換行、chip 換行），不用 transform:scale()、不縮小 touch target。
   Map／List 兩半維持 nowrap（segmented control 不拆散）；Chip 文字只在單顆長到超過
   整排時才自然換行。Marker label 字級是完全獨立的規則，不在這裡。 */
.filter-chip-label {
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1.25;
}

.view-switch-btn {
  font-size: 0.8rem;
  font-weight: 700;
  white-space: nowrap;
}

/* 內容區（地圖 / 清單 共用容器） */
.content-area {
  width: 100%;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative; /* 供 #toast 定位：Toast 放在這一層，Map／List 兩種模式共用 */
}

.content-view {
  display: none;
  width: 100%;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  position: relative;
}

.content-view.active {
  display: flex;
}

/* List Mode 捲動容器：Cards ＋ Footer 一起在這裡捲動，Topbar／Controls 維持在上方不動。
   負 margin 抵消 .map-container-page 的 1rem padding，讓捲動區（與其中的 Footer）
   貼齊內容欄兩側與底部，Footer 才能跟 Homepage 一樣滿版；內層用 padding 把 Cards
   還原回原本的左右 1rem 位置，Cards 位置不變。 */
#card-view {
  width: auto;
  margin: 0 -1rem -1rem;
  padding: 0 1rem;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Footer 重用 Homepage .site-footer（黑底／白字／置中／同字級字重）；這裡只處理在
   捲動區內的位置：緊接在最後一張 Card 之後（不 sticky、不 fixed，捲到底才會看到），
   負 margin 讓黑底橫向延伸到捲動區邊緣。 */
.list-site-footer {
  margin: 8px -1rem 0;
}

/* Marker（Map Mode UI Redesign mockup 版二方向）：藍色圓圈 pin 標示實際座標點，
   搭配獨立、圓角對話框式的 label 浮在 pin 正上方（不再是尖角尾巴的傳統氣泡）。
   iconAnchor 對齊 pin 圓心（0,0），label／pin 都用 translate 相對這個錨點定位，
   沿用既有 iconSize:[0,0] + iconAnchor:[0,0] 的作法，只是視覺結構整個換掉。 */
/* Filter 切換時的淡入淡出：用同一個 .is-hidden class 驅動，opacity/scale 都是
   極輕微、非常 subtle 的變化（不做 bounce/spring/旋轉/大幅縮放），套用在整個
   marker wrap（label＋pin 一起淡入淡出）。transform-origin 用預設 50% 50%
   （wrap 本身無視覺內容、子元素各自用自己的 translate 定位，縮放中心點不影響
   實際視覺位置）。pointer-events:none 確保淡出中的 marker 不會再被點擊。 */
.place-marker-wrap {
  background: transparent;
  border: none;
  opacity: 1;
  transform: scale(1);
  transition: opacity 200ms ease, transform 200ms ease;
}

.place-marker-wrap.is-hidden {
  opacity: 0;
  transform: scale(0.96);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .place-marker-wrap {
    transition: none;
  }
}

/* Pin：實際座標點，藍底＋白框圓點，不隨選取變色（樣式在所有狀態下維持一致，
   只有上方的 label 會變化），單純標示「這裡是座標」。 */
.place-marker-pin {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background-color: #0057ff;
  border: 2.5px solid #ffffff;
  box-shadow: 0 0 0 1.4px #1a1a1a;
  pointer-events: none;
}

.place-marker {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, calc(-100% - 11px));
  transform-origin: 50% 100%;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* 不設 max-width：每行都是單行不換行（見 .place-marker-label-zh/-alt 的
     white-space:nowrap），label 寬度必須完全依文字內容自然展開，不能有會造成
     折行的寬度上限。 */
  padding: 4px 8px;
  background-color: #f8f5ee;
  border: 2px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 2px 2px 0px #1a1a1a;
  font-size: 11px;
  font-weight: 700;
  color: #1a1a1a;
  cursor: pointer;
  transition: transform 180ms ease, box-shadow 180ms ease, border-width 180ms ease,
    background-color 150ms ease;
}

/* Selected Marker：不換 icon、不 pulse，label 填滿黃色底＋放大／陰影加重，標示目前
   對應 Bottom Sheet 的地點；pin 本身不變色，只有 label 反應選取狀態。
   z-index 使用 !important，因為 Leaflet 會依緯度對每個 marker 的 wrap 元素設定 inline
   z-index，外部 stylesheet 若不加 !important 無法蓋過 inline style。 */
.place-marker-wrap.is-selected {
  z-index: 620 !important;
}

.place-marker-wrap.is-selected .place-marker {
  /* 不填色（維持白底），改用藍色外框＋藍色右下陰影＋更明顯的放大效果來標示
     選取狀態，讓使用者一眼看出這個點目前被選到。 */
  background-color: #f8f5ee;
  border-color: #0057ff;
  transform: translate(-50%, calc(-100% - 11px)) scale(1.18);
  border-width: 2.6px;
  box-shadow: 3px 3px 0px #0057ff;
}

/* 限定特調合作店家／販賣機 Badge：附加在 label 右上角的星星徽章，不是第四種
   Marker，只是 attribute 標記（見 getPlaceBadge()）；一般景點／一般店家不會有。 */
.place-marker-star {
  position: absolute;
  top: -7px;
  right: -7px;
  width: 15px;
  height: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #ffd400;
  border: 1.4px solid #1a1a1a;
  border-radius: 50%;
  box-shadow: 1px 1px 0px #1a1a1a;
}

.place-marker-star svg {
  width: 9px;
  height: 9px;
  display: block;
}

/* Icon：不自動填色，維持 ICON_SVG 本身的線稿（stroke-only, fill:none）觀感，
   不論未選取／選取都不额外套用填色，只有外層 label 的底色會變。 */
.place-marker-icon {
  line-height: 1;
  flex: 0 0 auto;
  display: inline-flex;
}

.place-marker-icon svg {
  width: 14px;
  height: 14px;
  display: block;
}

/* 文字區：上方第一行固定中文，下方第二行（非 zh 介面才存在）為目前語言翻譯，
   各自獨立一行、不與中文混排在同一行。 */
/* 名稱需完整顯示、不截斷：不設 max-width／ellipsis，讓 label 依文字內容自然
   撐開寬度（.place-marker 本身仍有 max-width 上限，過長時才會自然換行）。 */
/* Bug fix：這裡先前沒有給 min-width，flex-shrink 在容器擠壓時會把這個文字欄位
   壓到「自動最小寬度」（CJK 文字在 overflow:visible 下的自動最小寬度＝單一字元
   寬度，因為中文每個字之間本來就是合法斷行點），造成中文名稱被壓成一字一行的
   直排效果——不是 writing-mode，純粹是 flex-shrink 把可用寬度壓到只剩一個字。
   給一個 min-width 底線，讓文字有足夠寬度可以正常橫向多字排列，只有真的很長
   的名稱才會自然換行到第二行，不會一開始就被壓縮成一字一行。 */
.place-marker-label {
  display: flex;
  flex-direction: column;
}

/* 中文第一行／外語第二行都強制單行不換行、不截斷：.place-marker 本身沒有
   max-width，所以這裡的 nowrap 不會有可用寬度不足需要換行或裁切的情況——
   label 的寬度會直接依文字內容自然展開。 */
.place-marker-label-zh {
  white-space: nowrap;
}

.place-marker-label-alt {
  white-space: nowrap;
  font-size: 0.95em; /* 原 0.82em：9px→10.5px，仍小於中文第一行 11px */
  font-weight: 600;
  color: #555;
  margin-top: 1px;
}

/* 狀態提示 Toast（非阻塞，數秒後自動消失） */
.toast {
  position: absolute;
  top: 10px;
  left: 50%;
  max-width: 86%;
  background-color: #1a1a1a;
  color: #f8f5ee;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 0.5rem 0.9rem;
  border-radius: 0;
  box-shadow: 2px 2px 0px #1a1a1a;
  z-index: 800;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -8px);
  transition:
    opacity 0.2s ease,
    transform 0.2s ease;
}

.toast[hidden] {
  display: none;
}

.toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* 定位失敗的完整說明（多行）：同一個 Toast 元素，只是文字較長——靠左對齊、保留換行、
   寬度跟著內容但以容器寬度為上限（不橫向溢出），疊在 Leaflet 控制項（z-index 1000）之上。 */
.toast.toast--guide {
  width: max-content;
  max-width: min(calc(100% - 24px), 340px);
  padding: 0.65rem 2.4rem 0.65rem 0.85rem; /* 右側留給關閉按鈕 */
  pointer-events: auto; /* 完整說明有可點擊的關閉按鈕 */
  font-size: 0.74rem;
  line-height: 1.55;
  text-align: left;
  overflow-wrap: anywhere;
  z-index: 1100;
}

/* 保留訊息中的換行只作用在文字本身（不影響 Toast 內其他元素之間的空白） */
.toast.toast--guide .toast-text {
  display: block;
  white-space: pre-line;
}

/* 關閉按鈕：只在完整定位說明出現；右上角、方形（無圓角）、白色細框＋白色 ×，鍵盤可聚焦。 */
.toast-close {
  display: none;
  position: absolute;
  top: 6px;
  right: 6px;
  width: 26px;
  height: 26px;
  margin: 0;
  padding: 0;
  border: 1.5px solid #f8f5ee;
  border-radius: 0;
  background: transparent;
  color: #f8f5ee;
  font-family: inherit;
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.toast--guide .toast-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.toast-close:focus-visible {
  outline: 2px solid var(--color-yellow, #ffd400);
  outline-offset: 2px;
}

.toast-close:active {
  opacity: 0.75;
}

/* 使用者目前位置 Marker（與 Place Marker 明顯區隔） */
.user-marker-wrap {
  background: transparent;
  border: none;
}

.user-marker-dot {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background-color: #1a1a1a;
  border: 2px solid #f8f5ee;
  box-shadow: 0 0 0 2px #1a1a1a;
}

.user-marker-pulse {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background-color: rgba(26, 26, 26, 0.35);
  animation: user-marker-pulse 1.8s ease-out infinite;
}

@keyframes user-marker-pulse {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.6;
  }
  100% {
    transform: translate(-50%, -50%) scale(3.2);
    opacity: 0;
  }
}

.user-marker-label {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -145%);
  white-space: nowrap;
  background-color: #1a1a1a;
  color: #f8f5ee;
  font-size: 10px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 8px;
}

/* 卡片模式：List Mode 真正的捲動容器是外層 #card-view（見下方 #card-view 規則），
   #card-list 只負責 Cards（不再自己 overflow），這樣 Footer 才能是 #card-list 後面的
   sibling，不進入 Card 的 keyed reconciliation。
   flex: 1 0 auto（sticky-footer pattern，不是 position:sticky）：內容不足一個 viewport 時，
   #card-list 吃掉 #card-view 剩餘高度，Footer 自然被推到最底；內容超過時 grow 為 0、
   依內容自然增高（不 shrink），Footer 就是捲動內容的最後一塊，其後沒有任何 spacer。 */
.card-list {
  width: 100%;
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1rem; /* Phase 3.1.1：原本 0.7rem(11.2px) 太緊，+4.8px 到 16px 增加一點呼吸感，仍維持快速瀏覽密度 */
  padding: 0.2rem 0.15rem 1rem;
}

/* 定位控制 group：Location 按鈕＋Info Icon＋Popover。Map／List 兩種模式都顯示，位於 Utility Row
   的 .view-switch 右側（[地圖][列表][定位][ⓘ]），兩種模式的 DOM 與位置完全相同、切換不跳位。
   Controls Layout：這個 group 與 .view-switch 同在 Utility Row（靠左、自然寬度，兩個 group 之間只留
   .filter-bar-row 的 gap），空間不足時整個 group 換到下一列。
   不設 position:relative——Popover 的定位錨點是 .filter-bar-row（見 .location-info-popover）。 */
.location-entry-group {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 2px;
  flex: 0 0 auto;
  max-width: 100%;
  min-width: 0;
}

/* Location 按鈕：與 .view-switch（Map／List）同一視覺層級——同樣的 34px 控制高度、2px 黑框、
   無圓角、0.8rem／700 字級；黃底＋黑字＋黑框是整站的 action 樣式（不是藍色：藍色只屬於
   「目前選取的模式」），不加陰影，維持與 Map／List 同一個視覺層級。
   文字依狀態切換（開啟定位／定位中…／重新定位），定位中降低透明度、不做 spinner。 */
.location-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0.3rem 0.55rem;
  min-height: 38px; /* = .view-switch 外框高度（34px＋上下各 2px 框） */
  border: 2px solid #1a1a1a;
  border-radius: 0;
  background-color: var(--color-yellow, #ffd400); /* 正式 action 色：黃底＋黑字＋黑框 */
  box-shadow: none;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1.25;
  color: #1a1a1a;
  white-space: nowrap;
  cursor: pointer;
  transition: opacity 120ms ease;
}

.location-btn:active {
  opacity: 0.85;
}

.location-btn:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 3px;
}

/* isLocating 進行中：降低視覺權重，不做 spinner／大動畫 */
.location-btn.is-pending {
  opacity: 0.55;
  cursor: default;
}

.location-btn[hidden] {
  display: none;
}

/* 窄螢幕 compact sizing：最長的狀態（例如 vi 定位成功後的「Cập nhật vị trí」）也要讓
   [模式][地圖|列表][定位][ⓘ] 留在同一列，不把定位 group 擠到下一列、不推開下方 Filter。
   ≤400px：縮小 Utility Row 的 group 間距與 Location 按鈕內距；
   ≤380px：Map／List 與 Location 按鈕「一起」縮小字級，所以兩者的視覺層級（字級、高度、框線）
   在每個寬度都維持一致。不移除任何控制項。 */
@media (max-width: 400px) {
  .control-row-items {
    column-gap: 6px;
  }

  .location-entry-group {
    gap: 0;
  }

  .location-btn {
    padding: 0.3rem 0.45rem;
  }
}

@media (max-width: 380px) {
  .view-switch-btn {
    padding: 0.3rem 0.3rem;
    font-size: 0.7rem;
  }

  .location-btn {
    padding: 0.3rem 0.35rem;
    font-size: 0.7rem;
  }
}

/* Phase 3.1.3：定位隱私說明 Info Icon。Icon 本身維持小巧、低調（跟 Location Entry 同一個
   視覺量級），但用透明 padding 撐出足夠的 touch target，不做成明顯的大圓形按鈕。 */
.location-info-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: #1a1a1a;
  opacity: 0.6;
  cursor: pointer;
}

.location-info-btn:hover,
.location-info-btn:focus-visible,
.location-info-btn.is-active {
  opacity: 1;
}

.location-info-btn:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 1px;
}

.location-info-btn svg {
  display: block;
}

/* Phase 3.1.3：定位隱私說明 Popover。半透明深色系統提示風格（不是奶油色 Card），
   以 Info Icon 為錨點、右側對齊、往左展開，避免在窄螢幕超出 viewport。
   用 opacity + visibility（而非 display）做淡入淡出：關閉時 visibility 延遲到 transition
   結束才切換，確保 fade-out 動畫能真正播放完，同時維持不可互動／不佔用 hit-test。 */
.location-info-popover {
  /* 錨點是 .filter-bar-row（position:relative），不是 .location-entry-group：Controls 全部
     靠左後 group 不再貼右緣，若繼續 right:0 或 left:0 對齊 group，360px 時會超出 viewport。
     left:0 對齊 Utility Row 左緣、顯示在整列下方，加上 max-width 的 viewport 上限，
     在任何寬度都不會超出。 */
  position: absolute;
  top: 100%;
  left: 0;
  right: auto;
  margin-top: 8px;
  width: max-content;
  max-width: min(230px, calc(100vw - 32px));
  padding: 0.55rem 0.65rem;
  background: rgba(20, 20, 20, 0.8);
  color: #fff;
  border-radius: 0;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
  font-size: 0.62rem;
  line-height: 1.55;
  text-align: left;
  z-index: 1300; /* Map Mode 也會開在地圖上，要高於 Leaflet 的 pane／控制項（最高 1000） */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 140ms ease, visibility 0ms linear 140ms;
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .location-info-popover {
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
  }
}

.location-info-popover.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 140ms ease, visibility 0ms linear 0ms;
}

/* Desktop hover：只是 enhancement，不是必要操作；用 (hover:hover) 排除觸控裝置，
   避免 tap 造成「卡住的 hover」跟下面 JS 的 click-toggle 互相打架。 */
@media (hover: hover) and (pointer: fine) {
  .location-info-btn:hover ~ .location-info-popover,
  .location-info-btn:focus-visible ~ .location-info-popover {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: opacity 140ms ease, visibility 0ms linear 0ms;
  }
}

.location-info-popover-emphasis {
  font-weight: 700;
}


@media (prefers-reduced-motion: reduce) {
  .location-info-popover {
    transition: none;
  }
}

/* Phase 2.3-H.3：整張卡片可點擊進入地點介紹，取代原本獨立的「探索這裡」CTA。
   List Mode 精修：卡片本體重新加回 5px 圓角＋右／下黃色 hard-offset 陰影（跟整站
   一致的陰影語彙），背景維持 #f4f4f0（與頁面主背景一致）。.place-card 本身改為
   flex-direction:column：第一個子元素是 Badge（見 .place-card > .detail-badges，
   沒有 Badge 的地點完全不 render 這個元素，不佔用高度），第二個子元素是
   .place-card-row，才是原本縮圖＋文字這組橫向排列（見下方）。overflow 維持 visible，
   縮圖自己的陰影／圓角跟卡片圓角是各自獨立的兩層視覺，不需要卡片幫忙裁切。 */
.place-card {
  width: 100%;
  background-color: #f4f4f0;
  border: 2.5px solid #1a1a1a;
  border-radius: 5px;
  box-shadow: 3px 3px 0px #ffd400;
  display: flex;
  flex-direction: column;
  overflow: visible;
  cursor: pointer;
  transition: transform 180ms ease, opacity 180ms ease;
}

/* 縮圖＋文字的橫向排列，從 .place-card 本體搬出來的第二層 row，讓 Badge 可以是
   .place-card 的第一個直接子元素、獨立於這個橫向 row 之外。 */
.place-card-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.place-card:active {
  transform: translate(1px, 1px);
}

/* Phase 3.1 Final Delta：Filter 造成的個別 Card fade in／out，只用 opacity／transform，
   不 animate height/width/margin/top/left。.is-entering 是新增回來的 Card 的起始樣式
   （移除此 class 後套用上面 .place-card 的 180ms transition 回到正常狀態）。
   Phase 3.1.1：.is-leaving 由 140ms 放慢到 210ms（實機感覺太快、下方補位像閃退），
   仍是非常輕的 opacity/scale，不做大幅縮小／slide／bounce。
   排序改變（Distance re-sort）依然不做 FLIP；Filter 造成的 remaining Card 補位動畫見下方
   renderCardList() 內以 inline transform 實作的 FLIP，同樣沿用 .place-card 的 180ms transform transition。
   Phase 3.1.3：.is-entering 移除 translateY 位移，只保留 opacity——新增 Card 是純淡入，
   不再有任何上滑／浮入感（實際淡入時長由 reconcileCardOrder() 的 inline transition 控制，見 map.js）。 */
.place-card.is-entering {
  opacity: 0;
}

.place-card.is-leaving {
  transition: opacity 210ms ease, transform 210ms ease;
  opacity: 0;
  transform: scale(0.985);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .place-card {
    transition: none;
  }
  .place-card.is-entering,
  .place-card.is-leaving {
    opacity: 1;
    transform: none;
  }
}

.place-card:focus-visible {
  outline: 2.5px solid #1a1a1a;
  outline-offset: 2px;
}

/* 縮圖區塊：不再貼齊卡片左／上／下邊緣滿版——改成一個純留白的「左側圖片區塊」，
   用 padding 跟卡片邊界保持間距（右側不留 padding，改由 .place-card-row 的 gap
   統一控制圖片跟文字區的間距，避免雙重間距）。
   List Mode 精修：padding-top 刻意跟 .place-card-body 的 top padding（0.6rem）
   用同一個值，讓圖片 top edge 跟地點名稱 top edge 對齊在同一條水平線——兩者現在都是
   從 .place-card-row（align-items:flex-start）的頂端起算相同距離，不用 transform
   或負 margin 硬拉對齊。 */
.place-card-thumb {
  flex: 0 0 auto;
  padding: 0.6rem 0 12px 12px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
}

/* 圖片本身（正方形 1:1，不變形）：黑色外框＋右方／下方黃色 hard-offset 陰影，不用圓角——
   卡片整體的陰影拿掉後，這是 Card 上唯一還保留陰影的元件，刻意突顯縮圖。
   fallback icon（無 place.image 時的 svg）套用同一組尺寸／外框／陰影，維持兩種情況
   視覺一致；background-color 只在 fallback 情況看得到（icon 描邊之間的底色），
   有真實圖片時完全被 object-fit:cover 蓋住，不影響視覺。 */
.place-card-thumb img,
.place-card-thumb svg {
  flex: 0 0 auto;
  display: block;
  width: clamp(72px, 22vw, 92px);
  height: clamp(72px, 22vw, 92px);
  object-fit: cover;
  background-color: #f8f5ee;
  border: 2.5px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 3px 3px 0px #ffd400;
}

.place-card-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 0.6rem 0.6rem 0.6rem 0;
}

/* List Mode 精修：Badge 搬到整張卡片最上方，是 .place-card 的第一個直接子元素
   （不再包在 .place-card-body 裡），獨立於縮圖＋文字這個橫向 row 之上。
   margin-left:12px 對齊縮圖左邊界（縮圖左邊界＝.place-card-thumb 自己的 12px 左
   padding，見上方），margin-top／margin-bottom 則是卡片頂端與縮圖列之間的呼吸空間。
   padding 直接比照 Bottom Sheet（.info-card-special-badge 基礎規則）的正式設定
   4px 8px，不另外創一套數值；font-size／svg 尺寸維持 List 既有的縮小版本。
   沒有 Badge 時 placeBadgeHtml() 回傳空字串，完全不 render 這個元素，不佔用任何高度，
   .place-card-row 直接從卡片最上方開始（見 .place-card-thumb 自己的 12px 上 padding）。 */
.place-card > .detail-badges {
  align-self: flex-start;
  max-width: calc(100% - 24px);
  margin: 10px 0 1.5px 12px;
}

.place-card > .detail-badges .info-card-special-badge {
  white-space: nowrap;
  margin: 0;
  font-size: 0.6rem;
  padding: 4px 8px;
}

.place-card > .detail-badges .info-card-special-badge svg {
  width: 9px;
  height: 9px;
}

.place-card > .detail-badges .info-card-special-badge.info-card-category-badge {
  padding: 3px 7px;
}

/* 完整地點名稱：可自然換行，不用 ellipsis 截斷；字級略低於 Bottom Sheet 的 0.98rem */
.place-card-name {
  font-size: 0.9rem;
  font-weight: bold;
  line-height: 1.25;
}

.place-card-type {
  font-size: 0.68rem;
  color: #777;
  font-weight: 600;
  margin-top: 0.2rem;
}

/* cardSummary：僅 1 行，超出可用寬度以 ellipsis 截斷，不修改原始文字內容 */
.place-card-summary {
  font-size: 0.8rem;
  font-weight: 400;
  color: #333;
  line-height: 1.42;
  margin-top: 0.15rem;
  /* 讀同一份 cardSummary：資料裡的換行（\n）要生效（pre-line），最多顯示 3 行，超出才省略號 */
  white-space: pre-line;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow-wrap: break-word;
}

.place-card-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.55rem;
}

/* Phase 3.0：Footer row 同時容納 Distance（靠左）與 Google Maps（靠右），取代原本只有
   .place-card-maps 自己 align-self:flex-end 的做法。margin-top:auto 讓整個 footer 固定貼齊
   卡片底部——不同卡片內容長度不一（縮圖被拉伸得較高、或 Summary 長度不同）時，footer 都會被
   推到 .place-card-body 這個 flex column 的最底部，穩定靠右下。 */
.place-card-footer {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: auto;
}

/* Distance：純資訊文字，非 click target，視覺權重比照 Meta Line（灰階、無框、無底線、無 Badge）；
   userLocation===null 且非 isLocating 時，distanceHtml() 回傳空字串，此處完全不會出現在 DOM 中，
   footer 因此只剩 Google Maps 一個子元素——Google Maps 靠 margin-left:auto 自行推到最右側，
   不依賴 justify-content:space-between（單一子元素時 space-between 不會把它推到右邊）。 */
.place-card-distance {
  font-size: 0.68rem;
  color: #777;
  font-weight: 600;
  white-space: nowrap;
}

.place-card-distance.is-pending {
  color: #999;
  font-weight: 500;
}

/* Google Maps：Phase 2.3-H.3 起改為右側內容欄底部的次要 action；
   Phase 2.3-H.4 起進一步降級為純文字連結（無框線／背景／固定按鈕高度），靠右對齊，
   避免視覺搶過 Card 本身的主要互動（點卡片進 Detail）。List Card 內現在只剩這一顆連結
   （「探索這裡」已移除，改由整張卡片本身可點擊取代），因此直接調整既有的 List scoped
   選擇器即可，不需要新增第二套選擇器與 Bottom Sheet 打架。
   margin-left:auto 確保 Google Maps 永遠靠右，不論 Distance 是否一起出現在 footer 中。 */
.place-card-maps {
  margin-left: auto;
}

/* border-bottom 當作「設計過的底線」，取代瀏覽器預設 text-decoration 底線觀感；
   padding 保留隱形的 touch target 緩衝，讓看起來像文字連結但仍好點。
   font-weight 由 600 降為 500、水平 padding 收窄，讓底線更貼合文字寬度本身，
   視覺權重再降一階，不與 Name / Badge 搶重量。 */
#card-list .place-btn {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  min-height: 0;
  border: none;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  padding: 0.5rem 0.02rem 0.35rem;
  font-size: 0.72rem;
  font-weight: 500;
  color: #1a1a1a;
  text-decoration: none;
  border-bottom: 2.5px solid #1a1a1a;
  line-height: 1.2;
  transition: opacity 120ms ease, border-color 120ms ease;
}

#card-list .place-btn:hover {
  opacity: 0.72;
  border-bottom-width: 3px;
}

#card-list .place-btn:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 3px;
}

.place-btn {
  flex: 1;
  font-size: 0.72rem;
  font-weight: bold;
  padding: 0.35rem 0.4rem;
  border: 2px solid #1a1a1a;
  border-radius: 10px;
  background-color: #f8f5ee;
  color: #1a1a1a;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  min-height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.place-btn:disabled,
.place-btn.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.card-empty-state {
  text-align: center;
  color: #888;
  font-size: 0.85rem;
  padding: 2rem 1rem;
}

/* Marker 資訊卡（自訂樣式，取代 Leaflet 預設 Popup） */
.info-card-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(26, 26, 26, 0.44); /* Phase 2.3-G：再加深一階，地圖退到第二層，但道路／Marker 仍要看得清楚 */
  z-index: 1090;
}

.info-card-backdrop[hidden] {
  display: none;
}

/* Outer positioning layer：只負責定位／置中／z-index，overflow 必須維持 visible，
   否則 Close Button 浮出上緣的那一半會被裁掉（Phase 2.3-F.1.2 root cause）。
   實際卡片外觀（背景／外框／圓角／陰影／捲動）全部交給 .info-card-body（Visual surface）。 */
.info-card {
  position: fixed;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: 100%;
  max-width: 480px;
  z-index: 1100;
  overflow: visible;
}

.info-card[hidden] {
  display: none;
}

/* Close Button：位於 Outer positioning layer 內、Visual surface 之外，
   因此不受 .info-card-body 的 overflow-y:auto 裁切影響，可完整呈現半浮圓形。 */
/* Bottom Sheet 關閉鈕：位置（absolute／top:0／right:7px／translateY(-50%)／z-index）沿用既有
   定位方式（right 較原本的 2px 往左移 5px）；視覺數值與 Vending Detail 正式版 .detail-overlay-close.is-vending 完全一致——
   38×38 直角、2px #1a1a1a 外框、#0057ff 藍底、白色 X（map.html 內的 SVG，與
   DETAIL_VENDING_CLOSE_SVG 同尺寸／線寬）、3px 3px 0 #ffd400 hard offset。
   三種 category 的 Bottom Sheet 共用這一顆，沒有 category 專屬規則。
   視覺縮成 38px 後，用 ::after 把可點擊範圍補回原本的 44×44（右緣不動，往左／上／下
   外擴），避免觸控目標變小。 */
.info-card-close {
  position: absolute;
  top: 0;
  right: 7px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 2px solid #1a1a1a;
  background-color: #0057ff;
  border-radius: 0;
  box-shadow: 3px 3px 0px #ffd400;
  width: 38px;
  height: 38px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}

.info-card-close::after {
  content: "";
  position: absolute;
  /* 偏移量是從 padding box（2px 外框內側）起算，所以多補 2px，
     讓整個可點擊範圍＝以外框為準的 44×44，右緣與原本一致。 */
  top: -5px;
  bottom: -5px;
  left: -8px;
  right: -2px;
}

.info-card-close svg {
  display: block;
  pointer-events: none;
}

/* Welcome Monster（Map Mode UI Redesign 收尾：改用 monster2.png，只在販賣機地點
   的 Bottom Sheet 出現，見 map.js updateWelcomeMonster()）。
   故意是 .info-card（見上方，overflow:visible 的外層定位層）的子元素，用
   position:absolute 直接相對卡片本身的左上角定位——不再是獨立的 position:fixed
   元素、不需要 JS 動態量測 bottom 座標，牠會永遠精準貼著卡片角落，不會漂浮到
   卡片外側，也不需要在卡片高度變化時重新計算位置。
   left:10px（正值、內縮，不會超出卡片左邊界）＋往上位移自身高度的 58%，讓上半身
   露在卡片外、爪子與下半身疊進卡片頂端一小段（貼合「趴靠在卡片左上角」的視覺），
   寬度與下探比例都刻意壓低，疊入卡片的範圍只會壓到照片（.info-card-banner）
   的上緣，不會延伸到 Badge／地點名稱／介紹文等主要文字資訊；水平位置也在
   .info-card-close（top:0;right:7px）的另一側，兩者不會互相遮擋。
   pointer-events:none：純裝飾，不吃點擊，不會擋住卡片內任何互動。 */
/* 趴在卡片上緣正中央（不是靠左掛在卡片外側）：水平置中對齊卡片，垂直方向大部分
   露在卡片外、只有下半身／爪子疊進卡片頂端一小段。尺寸比上一輪更大，但下探
   比例仍壓低，只會壓到照片（.info-card-banner）上緣，不會碰到右上角關閉鈕
   （水平置中、寬度遠小於卡片全寬，不會延伸到卡片右側）或下方的主要文字。 */
/* 縮小懸空比例，讓牠更明確「趴在卡片上緣」而不是浮在地圖區塊中央；水平置中
   對齊卡片本身，跟卡片形成合理比例。 */
/* 參考父層是 .info-card（Bottom Sheet 的外層定位層，overflow:visible），不是
   viewport／地圖容器；left 用小 inset 靠左（不是水平置中），top:0 對齊卡片本身
   的上緣（.info-card 唯一在一般文件流內的子元素就是 .info-card-body，兩者上緣
   重合），只往上位移自身高度的一小部分，讓底部（爪子）貼齊、視覺接觸卡片上緣，
   像趴著一樣，只有一小部分稍微超出上緣，不會蓋住右上角關閉鈕，也不會大面積
   蓋住照片。 */
/* 純裝飾 overlay，不影響 document flow、不撐高卡片、不推動 badge/title/meta：
   .welcome-monster 是 position:absolute，跟 .info-card-close 一樣脫離文件流，
   三種地點類型（vending_machine／partner_store／attraction）的卡片 padding／
   layout 完全共用同一套規則，不會因為要不要顯示小怪獸而有差異。
   定位基準：.info-card-body 已加上 position:relative 標明它是「真正的白色
   資訊卡」；.welcome-monster 這裡寫在同層的 #info-card（也是 position:fixed
   的定位層）而非 .info-card-body 內部，純粹是為了借用 #info-card 的
   overflow:visible——.info-card-body 自己有 overflow-y:auto（捲動長介紹用），
   若小怪獸真的巢狀在裡面，露出卡片上緣的部分會被直接裁掉。因為
   .info-card-body 是 #info-card 唯一還在一般文件流內、會撐開 auto-height 的
   子元素，兩者 box 座標保證相同，所以效果等同「相對 .info-card-body 定位」。
   top:0 是卡片本身的頂端座標，跟地圖實際高度、有沒有捲動都無關。
   下探幅度（translateY）純以視覺自然為準，不強求固定 px 區間：卡片本身沒有
   額外幫小怪獸預留空間，安全上限落在卡片自身 padding-top（13.6px）／badge
   起始位置（約 16px）之前，維持不遮住 badge 主要文字。 */
.welcome-monster {
  position: absolute;
  left: 14px;
  top: 0;
  /* 在原本 -89% 的基礎上再往下加 10px（calc 混合 %／px，同一個 translateY，
     水平位置／尺寸皆不變）。 */
  transform: translateY(calc(-89% + 10px));
  width: clamp(108px, 30vw, 150px);
  z-index: 3;
  pointer-events: none;
  animation: welcome-monster-fade-in 200ms ease-out;
}

.welcome-monster-img {
  display: block;
  width: 100%;
  height: auto;
  /* monster2.png 本身已是透明背景（非白底 JPG），不需要 multiply 去背；
     水平翻轉讓牠從左上角往左下方趴靠，而不是原始素材朝右下斜的方向。 */
  transform: scaleX(-1);
}

@keyframes welcome-monster-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .welcome-monster {
    animation: none;
  }
}

/* Visual surface：實際卡片外觀（背景／頂部框線／陰影）＋ 內容捲動全部集中於此，
   與 Outer positioning layer（.info-card）分離，讓 Close Button 可浮出此層之外不被裁切。
   Bottom Sheet 版二重新編排：卡片只有「上方」保留黑色框線，左／右／下方不再是
   完整外框（border-top 取代四邊 border；移除原本 box-shadow:0 -3px，避免跟
   border-top 疊出兩條平行線）；背景色改用跟首頁／Map 共用的紙張色
   #f4f4f0（body.map-page／首頁 body.home-v2 同一個值），讓沒有邊框的
   左右／下方能自然融入頁面背景，不會露出色差接縫。
   overflow-y:auto 保留「內容過長才捲動」行為。 */
.info-card-body {
  /* 這是真正的白色資訊卡本體（背景／頂部框線都畫在這裡）。position:relative
     標明它是小怪獸「概念上」的定位基準——見 .welcome-monster 的說明：因為
     overflow-y:auto 會裁掉超出邊界的內容，小怪獸實際上仍寫在外層 #info-card
     （overflow:visible）避免被裁切，但 #info-card 的 box 保證跟這裡完全一致。 */
  position: relative;
  background-color: #f4f4f0;
  border: none;
  border-top: 2.5px solid #1a1a1a;
  border-radius: 0;
  padding: 0.85rem 1rem calc(0.7rem + env(safe-area-inset-bottom, 0px));
  max-height: 62vh; /* 原本是 .info-card 的 62%（相對 viewport），改由 Visual surface 承接，故改用 62vh 維持等效高度 */
  overflow-y: auto;
}


/* 左側正方形圖片：1:1、黑色外框、右＋下黃色硬邊 offset 陰影，無圓角，
   object-fit:cover 不變形；尺寸依 viewport clamp，刻意壓小避免佔掉過多寬度，
   讓右側地點介紹欄有足夠空間維持橫向閱讀，不擠成過窄直排。 */
.info-card-image {
  flex: 0 0 auto;
  width: clamp(90px, 26vw, 116px);
  aspect-ratio: 1 / 1;
  background-color: #fff2d8;
  border: 2.5px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 3px 3px 0px #ffd400;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.info-card-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  display: block;
}

.info-card-image svg {
  width: 34px;
  height: 34px;
}

/* 中間內容區：左圖片／右地點介紹雙欄。align-items:flex-start 讓圖片維持自己的
   高度，不會被右側較長的介紹文字拉伸變形；圖片欄不縮小，避免在窄螢幕被壓成
   變形；介紹欄 min-width:0 才能正常換行、不會把版面撐爆變成直排。 */
.info-card-media {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 0.6rem;
}

/* 完整地點名稱：可自然換行，不截斷成看不到完整名稱 */
.info-card-name {
  font-size: 0.94rem;
  font-weight: bold;
  line-height: 1.3;
}

/* 地點特殊身份 Badge（Phase 2.3-G.1.2 起移到地點名稱上方）：僅有 Badge 時才 render，不 render 時不留空白高度。
   緊接在 Hero 圖片下方、地點名稱之上（第二層視覺，不與名稱搶重量，比 CTA 更輕巧的 compact badge）。
   Map Mode UI Redesign：填滿黃色底色（取代原本淺米色），與 Marker Badge／Filter Chip
   選取態統一同一套視覺語言；List Card（.place-card-body）與 Detail Overlay
   （.detail-header）皆共用這個 base class，一起套用新樣式，不需另外覆寫背景色。 */
/* 「小怪獸的家」／「店內限定特調」徽章：比照首頁「在地導遊」標籤語言——
   藍色實心底、無邊框、白色粗體字，border-radius:5px（本頁少數明確指定圓角的
   例外元件）。兩種徽章共用同一套樣式，不再用黃底／藍底區分。 */
.info-card-special-badge {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 3px;
  margin-bottom: 0.4rem;
  padding: 4px 8px;
  background-color: #0057ff;
  border: none;
  border-radius: 5px;
  font-size: 0.68rem;
  font-weight: 700;
  color: #ffffff;
}

.info-card-special-badge svg {
  width: 10px;
  height: 10px;
  display: block;
  fill: #ffffff;
}

/* 一般分類 Badge（美食／景點）：neutral——paper 底、黑字、1px 黑框，沒有任何顏色陰影／
   強調色；尺寸、圓角與特殊身分 Badge 相同（border 佔 1px，所以 padding 各減 1px，整體大小不變）。
   藍色只保留給特殊身分（小怪獸的家／店內限定特調）。List Card／Bottom Sheet／Detail 共用。 */
.info-card-special-badge.info-card-category-badge {
  background-color: #f8f5ee;
  color: #1a1a1a;
  border: 1px solid #1a1a1a;
  padding: 3px 7px;
}

/* 「類別 · 營業資訊」，無 businessInfo 時只顯示類別；視覺權重低於名稱 */
.info-card-type {
  font-size: 0.72rem;
  color: #777;
  font-weight: 600;
  margin-top: 0.25rem;
}

/* cardSummary：Bottom Sheet 主要說明文字，現在是 .info-card-media 的右欄
   （跟左側圖片同一列），不再是堆疊在 Meta Line 下方的獨立區塊，margin-top 歸零
   交由 .info-card-media 自己的 gap 控制間距；flex:1 撐滿剩餘寬度、min-width:0
   讓文字能正常換行，不會被擠成過窄直排。 */
.info-card-summary {
  flex: 1 1 auto;
  min-width: 0;
  margin-top: 0;
  font-size: 0.86rem;
  font-weight: 400;
  color: #333;
  line-height: 1.5;
  white-space: pre-line; /* 店家介紹資料裡的換行（\n）照樣顯示 */
}

/* Bottom Sheet 內的 CTA 列：獨立在雙欄下方滿版，跟上方區塊保留間距。 */
#info-card-body .place-card-actions {
  margin-top: 0.85rem;
}

/* Bottom Sheet 內的 CTA 按鈕：Phase 2.3-G.1.1 降至 36px（使用者確認可低於先前 44px 門檻），
   padding 進一步縮小避免撐高；僅限 Bottom Sheet，不影響清單卡片的既有 34px。
   Map Mode UI Redesign：加上箭頭／外部連結圖示（純 CSS content，不改共用 HTML
   generator，不影響 List Card／Detail Overlay footer 沿用同一份 .place-btn 標記）；
   維持既有「探索這裡」／「開啟 Google Maps」兩顆功能不變，只換視覺。 */
#info-card-body .place-btn {
  min-height: 36px;
  padding: 0.2rem 0.4rem;
  gap: 4px;
  border-radius: 0;
}

/* Bottom Sheet 兩顆 CTA 都是黃底黑框（探索這裡／Google Maps），無圓角；停用狀態
   （.is-disabled，尚未有 Detail 資料的地點）維持原本淺底＋降低透明度，不套用
   黃底，避免看起來像可點擊。 */
/* 「探索這裡」／「Google Maps」兩顆 CTA 視覺規格完全一致：黃色底＋右下黑色硬邊
   offset 陰影，無圓角。 */
#info-card-body .place-btn:not(.is-disabled) {
  background-color: #ffd400;
  box-shadow: 2px 2px 0px #1a1a1a;
}

#info-card-body .place-btn:not(.is-disabled):active {
  transform: translate(1px, 1px);
  box-shadow: 1px 1px 0px #1a1a1a;
}

#info-card-body .detail-explore-btn::after {
  content: "→";
  font-weight: 700;
}

/* ============================
   Phase 4.0：共用 Full-screen Detail Overlay
   ============================ */

/* List Card 點擊淡入淡出／FLIP 補位期間，Overlay 開啟時要鎖住 List 自己的捲動，
   但不能動 scrollTop（由 map.js 記錄／還原），純粹只是暫時禁止手勢捲動。 */
#card-view.is-scroll-locked {
  overflow: hidden;
}

.detail-overlay {
  position: fixed;
  inset: 0;
  z-index: 1400; /* 高於 .welcome-monster 的 1150，Overlay 必須蓋過 Bottom Sheet／小怪獸 */
  background-color: #f8f5ee;
  display: flex;
  flex-direction: column;
}

.detail-overlay[hidden] {
  display: none;
}

.detail-overlay-close {
  position: absolute;
  top: calc(0.6rem + env(safe-area-inset-top, 0px));
  right: 0.7rem;
  z-index: 2;
  width: 38px;
  height: 38px;
  border: 1.5px solid #1a1a1a;
  background-color: #fff2d8;
  border-radius: 50%;
  font-size: 1.1rem;
  font-weight: bold;
  line-height: 1;
  cursor: pointer;
  box-shadow: 1.5px 1.5px 0px #1a1a1a;
}

.detail-overlay-close:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 3px;
}

.detail-overlay-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Phase 4.0.1：一致的 vertical rhythm token，取代先前各區塊各自任意的 margin 數值。
   每個元素只宣告自己的 margin-top（「我跟前一個元素的間距」），不使用 margin-bottom，
   避免相鄰兄弟元素的 margin 互相 collapse 造成間距難以預期。 */
.detail-overlay-body {
  padding: calc(3.2rem + env(safe-area-inset-top, 0px)) 1.1rem 1.5rem;
  max-width: 480px;
  margin: 0 auto;
  /* Phase 4.0.3：4 級 vertical rhythm——同一組內容用小距離、真正換 Section 才用大距離。
     Audit 發現：Meta→cardSummary、Tabs→Product Name、Guide Image→Step1、Step 與 Step
     這幾組「中距離」原本都直接借用 --rail-section-gap（30px）或 --rail-image-gap（22px），
     視覺上跟真正的 Section 切換（例如 Product Image →「怎麼喝？」）沒有區隔，因此新增
     --rail-block-gap 補上 M 這一級；--rail-image-gap／--rail-step-gap 的用途已被
     --rail-paragraph-gap／--rail-block-gap 取代，故不再保留，避免多餘的 token。 */
  --rail-heading-gap: 10px; /* XS/S：Heading 緊接 Content（同一組） */
  --rail-paragraph-gap: 14px; /* S：一般 Paragraph 間／圖片與同組文字 */
  --rail-block-gap: 22px; /* M：中距離（小區塊切換，但還算同一內容模組） */
  --rail-section-gap: 27px; /* L：真正 Section 切換 */
}

.detail-loading,
.detail-error {
  padding: 2rem 0.5rem;
  text-align: center;
  color: #666;
  font-size: 0.85rem;
}

.detail-error {
  color: #a33;
}

/* ---- Header：Badge／Name／Meta，與 Bottom Sheet 共用 getPlaceBadge() / metaLineHtml() ---- */
/* Badge 群組（可 1～2 顆）：靠左、自然寬度、flex-wrap，外語長字串不會 overflow。單顆時視覺與
   原本一致（badge 自己的 margin-bottom 移到群組上）。 */
.detail-badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 6px;
  margin-bottom: 8px;
}

.detail-header .info-card-special-badge,
.info-card-body .detail-badges .info-card-special-badge {
  margin-bottom: 0;
}

/* Bottom Sheet 也用 .detail-badges（與 Detail 同一套 Badge taxonomy）；群組下方保持原本
   單顆 Badge 的 0.4rem 間距，Special Partner 兩顆放不下時自然 wrap。 */
.info-card-body .detail-badges {
  margin-bottom: 0.4rem;
}

.detail-name {
  font-size: 1.15rem;
  font-weight: bold;
  line-height: 1.35;
}

.detail-meta {
  font-size: 0.76rem;
  color: #777;
  font-weight: 600;
  margin-top: 6px;
}

/* Phase 4.0.1：主要介紹直接沿用 place.cardSummary（由 cardSummaryHtml() 產生，
   與 List／Bottom Sheet 共用同一份文字來源，不在 Detail JSON 內複製第二份介紹文字）。
   Phase 4.0.2：拉高視覺權重（粗體／深色），確立為「主要介紹」的第一層級。 */
.detail-summary {
  margin-top: var(--rail-block-gap);
  font-size: 1rem;
  font-weight: 700;
  color: #1a1a1a;
  line-height: 1.7;
  white-space: pre-line; /* 店家介紹資料裡的換行（\n）照樣顯示 */
}

/* ---- Tabs：整條寬版分段切換（兩個 tab 等寬、直角、黑框）。未選中＝paper 底＋黑字，
   選中＝藍底＋白字（同「出發探險」藍按鈕）；tab 之間用 2px 黑線分隔。切換邏輯（.detail-tab-btn／.active／
   aria-selected）不變，只換視覺。 ---- */
.detail-tabs {
  display: flex;
  margin-top: var(--rail-section-gap);
  border: 2px solid #1a1a1a;
  border-radius: 0;
  background-color: #f8f5ee;
}

.detail-tab-btn {
  flex: 1 1 0;
  min-width: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  padding: 0.5rem 0.4rem;
  font-size: 0.9rem;
  font-weight: 700;
  line-height: 1.25;
  color: #1a1a1a;
  cursor: pointer;
}

.detail-tab-btn + .detail-tab-btn {
  border-left: 2px solid #1a1a1a;
}

.detail-tab-btn.active {
  background-color: #0057ff; /* 同全站藍色 CTA（出發探險） */
  color: #ffffff;
}

.detail-tab-btn:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: -5px;
}

.detail-tab-panel {
  padding-top: var(--rail-block-gap);
}

/* ---- partner_store Detail：「小怪獸推薦」Tab ----
   Editorial／手繪風的簡單清單，不做外送平台卡片（無 border card、無陰影、無星等）。
   Rank／品名／特殊食材是整個 recommendation 共用的標頭，全部在圖文 row 之上；
   圖文 row（.detail-recommendation-row）只放縮圖＋介紹文字，縮圖是獨立的
   .detail-recommendation-thumb。沒有圖片時
   description 直接 fallback 成 full-width 段落，不產生 row wrapper、不建立
   placeholder／空圖框。 ---- */
.detail-recommendation + .detail-recommendation {
  margin-top: var(--rail-section-gap);
}

/* TOP 1／2／3：沿用 .vending-heading（Unbounded 900）的標題語感，右下黃色 hard offset
   （同 WHY 標題的 text-shadow），字級比 section 大標略小，清楚但不巨大。 */
.detail-recommendation-index.vending-heading {
  font-size: 1.15rem;
  text-shadow: 3px 3px 0 #ffd400;
  text-align: left;
}

/* 中文品名：沿用 .vending-subtitle（1rem／700），翻譯品名在下方一行，字級／字重／顏色
   比照地點翻譯名稱放大後的可讀性（0.9rem／600／#555），仍小於中文品名。 */
.detail-recommendation-name.vending-subtitle {
  text-align: left;
  margin-top: 6px;
}

.detail-recommendation-name-translated {
  margin-top: 2px;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.35;
  color: #555555;
  text-align: left;
}

/* 圖文 row：左圖（正方形）＋右欄（介紹 → 食材）。右欄 min-width:0，長文自然換行。 */
.detail-recommendation-row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-top: 14px;
}

.detail-recommendation-thumb-btn {
  flex: 0 0 auto;
  display: block;
  padding: 0 6px 6px 0; /* 讓右下 6px 黃色 hard shadow 落在按鈕範圍內，不被裁切也不撐出版面 */
  border: none;
  border-radius: 0;
  background: none;
  cursor: pointer;
}

.detail-recommendation-thumb-btn:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 2px;
}

/* 正方形、直角、2px 黑框＋右下黃色 hard shadow（點擊放大後的 Lightbox 沿用同一套）。
   寬度 360px≈108px、390px≈117px、430px≈129px（clamp 104–132px）。 */
.detail-recommendation-thumb {
  display: block;
  width: clamp(104px, 30vw, 132px);
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: 2px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 6px 6px 0 #ffd400;
}

.detail-recommendation-body {
  flex: 1 1 0;
  min-width: 0;
}

.detail-recommendation-description {
  font-size: 0.86rem;
  color: #333;
  line-height: 1.6;
  text-align: left;
  overflow-wrap: break-word;
}

/* 特殊食材：在品名（有翻譯時是翻譯品名）之下、圖文 row 之上，整條 Content Rail 寬。
   「特殊食材」小標（粗黑字）＋「icon＋名稱」清單同一排，放不下時自然換行；icon 用 currentColor。 */
.detail-recommendation-ingredients {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  column-gap: 12px;
  row-gap: 6px;
  margin-top: 10px;
  text-align: left;
}

.detail-recommendation-ingredients-label {
  font-size: 0.78rem;
  font-weight: 800;
  color: #1a1a1a;
}

.detail-recommendation-ingredients-list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  column-gap: 14px;
  row-gap: 6px;
  font-size: 0.8rem;
  color: #444;
  font-weight: 600;
}

.detail-ingredient {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.detail-ingredient svg {
  flex: 0 0 auto;
  display: block;
}

/* 小知識／補充說明：.vending-explore-block（黑框＋黃色底板）放在品項最後。外層 wrapper 建立
   stacking context（isolation），讓 block 的 ::before 黃色底板（z-index:-1）落在 block 後面
   而不是跑到 Overlay 背景後面；右／下各留 6px 給黃色底板的 offset。 */
.detail-recommendation-note {
  isolation: isolate;
  padding: 0 6px 6px 0;
  margin-top: 16px;
}

.detail-recommendation-note .vending-explore-block {
  margin-top: 0;
}

.detail-recommendation-note .vending-explore-item-copy {
  white-space: pre-line;
}

/* ---- partner_store Detail：「菜單」Tab ----
   分類式簡潔列表，不做 Card Grid、不放圖片。 ---- */
.detail-menu-category + .detail-menu-category {
  margin-top: var(--rail-section-gap);
}

.detail-menu-category-title {
  font-size: 0.95rem;
  font-weight: bold;
  text-align: left;
  text-decoration: none;
  border-bottom: none;
  box-shadow: none;
  background: none;
}

.detail-menu-items {
  margin-top: var(--rail-heading-gap);
  display: flex;
  flex-direction: column;
  gap: var(--rail-heading-gap);
}

/* TOP marker 在品名前面，兩者是各自獨立的 span（不是拼成單一字串），未來品名換成其他
   語言時 TOP box 仍是清楚獨立的 UI element。中間用可伸縮的淡色 leader 線把視線導到價格；
   價格固定不換行、靠右。leader 太窄時會自然縮到 min-width，不會直接貼字。
   .detail-menu-item-main 只在真的放不下時才會 flex-shrink（min-width:0 讓子元素可以
   真正縮小／換行，而不是被 nowrap 撐出 overflow）；沒有 rank 的品項因為 DOM 裡根本沒有
   .detail-menu-item-rank，不會預留任何 rank 欄寬，天生就是從 Content Rail 起始位置開始。 */
/* 一個品項：（有 TOP 才有）TOP 標籤一行 → 「中文品名＋價格」一列（含第二行翻譯）。
   TOP 標籤獨立在上方、靠左，與下方品名的起點對齊，不佔品名寬度、不跟價格同列。 */
.detail-menu-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}

.detail-menu-item-row {
  align-self: stretch;
  display: flex;
  align-items: flex-start; /* 品名可能有第二行翻譯：價格與 leader 對齊第一行 */
  gap: 9px;
}

.detail-menu-item-main {
  flex: 0 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: baseline;
}

/* 品名是 main 裡唯一會伸縮的子元素：名稱太長放不下時，先由品名換行（min-width:0 +
   預設 white-space:normal），price 依然不換行、靠右。
   不透過縮小 font-size 硬塞。中文品名在第一行；非中文介面的翻譯品名在下一行
   （.detail-menu-item-name-translated，同字級、用次要文字色建立主次）。 */
.detail-menu-item-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.84rem;
  line-height: 1.45;
  color: #333;
  text-align: left;
  overflow-wrap: break-word;
}

.detail-menu-item-name-translated {
  display: block;
  color: #555555; /* 同「翻譯名稱」的次要文字色，不新增色票 */
}

/* TOP 1／2／3：從 recommendations[].menuItemId + rank 動態推導，不是 menu item 自己的
   欄位。黃底＋黑框＋直角的小標籤（無 shadow／pill／emoji）。 */
.detail-menu-item-rank {
  flex: 0 0 auto;
  font-size: 0.7rem;
  font-weight: 800;
  color: #1a1a1a;
  background-color: #ffd400;
  border: 1.5px solid #1a1a1a;
  border-radius: 0;
  padding: 2px 6px;
  line-height: 1.2;
  white-space: nowrap;
}

/* leader 與第一行同高，細線畫在這一行的垂直中央 */
.detail-menu-item-leader {
  flex: 1 1 0%;
  min-width: 8px;
  align-self: flex-start;
  height: calc(0.84rem * 1.45);
  background: linear-gradient(rgba(26, 26, 26, 0.16), rgba(26, 26, 26, 0.16)) center / 100% 1px no-repeat;
}

.detail-menu-item-price {
  flex: 0 0 auto;
  font-size: 0.84rem;
  line-height: 1.45;
  font-weight: 700;
  color: #1a1a1a;
  white-space: nowrap;
}

/* ---- Google Maps：固定於 Overlay 最底部，不隨 Tab 切換消失、不隨內容捲動 ---- */
.detail-overlay-footer {
  flex: 0 0 auto;
  padding: 0.7rem 1.1rem calc(0.7rem + env(safe-area-inset-bottom, 0px));
  border-top: 1.5px solid #e4ddc9;
  background-color: #f8f5ee;
}

/* 整條寬版 Google Maps 按鈕：與「出發探險」同一套按鈕語言——藍底＋白字＋2px 黑框＋直角＋
   右下黑色 hard shadow。寬度 calc(100% - 4px)＋下方 4px margin，給陰影 offset 留空間，不造成橫向溢出。 */
.detail-overlay-footer .place-btn {
  display: flex;
  width: calc(100% - 4px);
  min-height: 46px;
  margin-bottom: 4px;
  border: 2px solid #1a1a1a;
  border-radius: 0;
  background-color: #0057ff;
  color: #ffffff;
  box-shadow: 4px 4px 0 #1a1a1a;
  font-size: 0.9rem;
  font-weight: 700;
  transition: transform 100ms ease, box-shadow 100ms ease;
}

.detail-overlay-footer .place-btn:active {
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 #1a1a1a;
}

.detail-overlay-footer .place-btn:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 3px;
}

/* Overlay 底色統一（三種 Detail 都是 .is-vending-v2）：footer 底也用 #f4f4f0 */
.detail-overlay.is-vending-v2 .detail-overlay-footer {
  background-color: #f4f4f0;
}

.detail-overlay-footer:empty {
  display: none;
}

/* ============================================================
   Vending Detail Page V2（本輪新增，只套用在 category === "vending_machine"）。
   Partner Store／Attraction 完全不會套用到下面這些 class（它們的 render path
   沒有產生這些 class 名稱），不需要另外用 :not() 排除。
   ============================================================ */

/* Topbar 在 Detail 開啟時為可見／可操作（見 map.js
   applyDetailOverlayEditorialChrome()，用 JS 量測 Topbar 高度讓出 top，不是改
   .topbar 本身），背景改成跟首頁/地圖頁一致的 #f4f4f0（三種 Detail 共用）。 */
.detail-overlay.is-vending-v2 {
  background-color: #f4f4f0;
}

/* Vending 專用關閉鈕（取代原本圓形「×」鈕的樣式；JS 換成白色 X）：藍底／白色 X／黑色外框／
   黃色右下 hard shadow／直角。只在 is-vending 這個 modifier 下生效，
   選擇器比基礎 .detail-overlay-close 多一個 class、優先權更高，不需要 !important，
   三種 Detail 開啟時都會套用這個 modifier。 */
.detail-overlay-close.is-vending {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #0057ff;
  border: 2px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 3px 3px 0px #ffd400;
}

.vending-hr {
  border: none;
  border-top: 2px solid #1a1a1a;
  margin: 24px 0;
}

/* Vending 首屏 vertical spacing 收緊（只在 .is-vending-v2 底下，不動共用的
   .detail-overlay-body／.detail-summary）：
   原本共用規則為了讓出右上 floating 鈕預留 3.2rem；Badge／名稱欄在左側、X 在右上，
   實際不會重疊，所以縮到 0.9rem。Meta → Summary、Summary → 第一條 hr 一併收緊。 */
.detail-overlay.is-vending-v2 .detail-overlay-body {
  padding-top: calc(0.9rem + env(safe-area-inset-top, 0px));
}

.detail-overlay.is-vending-v2 .detail-summary {
  margin-top: 12px;
  line-height: 1.55;
}

.detail-overlay.is-vending-v2 .detail-summary + .vending-hr {
  margin-top: 14px;
}

.vending-section {
  margin-top: 0;
}

.vending-section + .vending-section {
  margin-top: 32px;
}

/* HOW TO DRINK 的藍色 offset 往下多出 7px，後面接 FROM HERE 的分隔線時補一點空間 */
.vending-section--how + .vending-hr {
  margin-top: 34px;
}

/* 英文 Editorial 大標：與 Homepage .how-header-title 同一個 token
   （--font-display-latin = Unbounded 900，自架 asset，見 map.html／body.map-page）。
   Unbounded 字寬明顯大於 Arial Black，字級配合調小，維持同樣的視覺佔比。 */
.vending-heading {
  margin: 0;
  /* Unbounded 只含拉丁字：Attraction 大標在 ja／ko 語言下為 CJK，明確接 --font-body-zh，
     不落到瀏覽器預設 sans-serif（Vending 大標固定英文，不受影響）。 */
  font-family: "Unbounded", var(--font-body-zh);
  font-weight: 900;
  font-size: 1.3rem;
  line-height: 1.25;
  letter-spacing: 0.01em;
  color: #1a1a1a;
}

/* 只有 WHY 標題有黃色 hard offset（flat、無 blur／gradient），不是所有 .vending-heading。 */
.vending-heading--why {
  text-shadow: 3px 3px 0 #ffd400;
}

.vending-heading-highlight {
  box-shadow: inset 0 -0.38em 0 0 #ffd400;
}

.vending-subtitle {
  margin-top: 6px;
  font-size: 1rem;
  font-weight: 700;
  color: #1a1a1a;
}

.vending-body-text {
  margin-top: 10px;
  font-size: 0.94rem;
  font-weight: 400;
  color: #333333;
  line-height: 1.7;
}

/* FIRST FLAVOR：heading／subtitle 在整列最上方，下方 .vending-flavor-row 為左圖
   （.vending-flavor-image）＋右文（.vending-flavor-copy），360／390／430 三個寬度都維持
   左右並排（不改成上下堆疊）。產品 PNG 本身已含透明背景與黃色 offset，CSS 不加
   border／shadow／背景框，只做 contain、保持原始比例（height:auto，不 stretch、不裁切）。
   右欄 min-width:0 ＋ overflow-wrap，en／id／vi 長文自然換行，不溢出、不截斷、不縮字。 */
.vending-flavor-row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-top: 14px;
}

.vending-flavor-image {
  flex: 0 0 auto;
  width: 40%;
  max-width: 190px;
  height: auto;
  object-fit: contain;
  border: 0;
  box-shadow: none;
  background: none;
}

.vending-flavor-copy {
  flex: 1 1 0;
  min-width: 0;
  margin: 0;
  font-size: 0.9rem;
  font-weight: 400;
  color: #333333;
  line-height: 1.65;
  overflow-wrap: break-word;
}

.vending-flavor-copy p {
  margin: 0;
}

/* HOW TO DRINK？media frame：正式 GIF 尚未製作，沿用 Homepage .how-frame
   完全相同的 placeholder 結構／視覺語彙（黑框＋藍色右下 hard shadow），
   只是換了 class 名稱以配合這裡的 scope，不是另外設計一套。 */
.vending-gif-frame {
  position: relative;
  margin-top: 14px;
  min-height: 160px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background-color: #f4f4f0;
  border: 2px solid #1a1a1a;
}

.vending-gif-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: translate(7px, 7px);
  background-color: #0057ff;
  z-index: -1;
}

.vending-gif-play {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background-color: #ffd400;
  border: 2px solid #1a1a1a;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

.vending-gif-play:active {
  transform: translateY(1px);
}

.vending-gif-play:focus-visible {
  outline: 3px solid #0057ff;
  outline-offset: 3px;
}

.vending-gif-caption {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: #1a1a1a;
}

/* FROM HERE, EXPLORE QINGSHUI：單一資訊框，裝「合作店家」／「限定特調」兩個條目
   ＋「出發探險」CTA。 */
/* 雙層結構：前方是黑框紙卡（本體），後方是自己也有黑框的黃色實心底板（::before，
   右＋下偏移）。沿用 .vending-gif-frame::before 同樣的 z-index:-1 作法——本體刻意
   不設 z-index／不建立 stacking context，底板才會落在本體背景「後面」而不是蓋住
   文字或 CTA；全程 flat color，無 blur／gradient／soft shadow。 */
.vending-explore-block {
  position: relative;
  margin-top: 14px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  background-color: #f4f4f0;
  border: 2px solid #1a1a1a;
}

.vending-explore-block::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: translate(6px, 6px);
  background-color: #ffd400;
  border: 2px solid #1a1a1a;
  z-index: -1;
}

.vending-explore-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.vending-star-marker {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-color: #ffd400;
  border: 2px solid #1a1a1a;
  display: flex;
  align-items: center;
  justify-content: center;
}

.vending-star-marker svg {
  width: 13px;
  height: 13px;
  display: block;
}

.vending-explore-item-text {
  flex: 1;
  min-width: 0;
}

.vending-explore-item-title {
  font-size: 0.98rem;
  font-weight: bold;
  color: #1a1a1a;
}

.vending-explore-item-copy {
  margin-top: 2px;
  font-size: 0.86rem;
  font-weight: 400;
  color: #555555;
  line-height: 1.55;
}

.vending-explore-cta {
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.6rem 1.1rem;
  background-color: #0057ff;
  color: #ffffff;
  border: 2px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 3px 3px 0px #1a1a1a;
  font-size: 0.9rem;
  font-weight: 700;
  text-decoration: none; /* Attraction 的 Explore 是 <a>，Vending 是 <button>，共用同一個視覺 */
  cursor: pointer;
  transition: transform 100ms ease, box-shadow 100ms ease;
}

.vending-explore-cta.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.vending-explore-cta:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0px #1a1a1a;
}

.vending-explore-cta:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .vending-explore-cta {
    transition: none;
  }
}

/* 窄螢幕：FIRST FLAVOR 仍維持左圖＋右文（不再改成上下堆疊），只微調圖寬／gap，
   讓右側文字欄保有足夠寬度、不被壓成極窄直欄。 */
@media (max-width: 390px) {
  .vending-flavor-row {
    gap: 12px;
  }

  .vending-flavor-image {
    width: 36%;
  }

  .vending-flavor-copy {
    font-size: 0.86rem;
  }
}

/* 底部 Copyright Footer：視覺跟首頁 .site-footer 完全一致（黑底／白字／置中／同樣
   字級字重），用負 margin 抵消 .detail-overlay-body 自己的左右 padding，讓黑底延伸到
   跟內容欄同寬的滿版，不是陷在側邊留白中間的一條短黑色塊。 */
.vending-footer {
  margin: 32px -1.1rem calc(-1.5rem - env(safe-area-inset-bottom, 0px));
  padding: 12px 1.1rem calc(12px + env(safe-area-inset-bottom, 0px));
  background-color: #1a1a1a;
  color: #f4f4f0;
  text-align: center;
  font-size: 0.68rem;
  font-weight: 700;
}

/* ============================================================
   Attraction Detail V2：沿用 Vending Detail 的 Overlay chrome（.is-vending-v2）與 .vending-*
   設計語言（標題、副標、內文、分隔線、Explore 區塊、Footer），這裡只補景點專屬的兩個元件：
   主照片、icon tags。沒有任何共用規則被改動。
   ============================================================ */

/* 主照片：黑色外框＋右／下藍色 hard offset，直角，保持原始比例（height:auto，不裁切）。
   跟 .vending-gif-frame 一樣讓陰影落在 .detail-overlay-body 左右 padding 內，不造成橫向溢出。 */
.attraction-hero-image {
  display: block;
  width: 100%;
  height: auto;
  margin: 16px 0 22px; /* 下方留 22px（含 6px 藍色 offset），比原 32px 更貼近 GOOD TO KNOW */
  border: 2px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 6px 6px 0 #0057ff;
}

/* icon tags（GOOD TO KNOW）：藍色線稿 icon＋右下一小塊黃色 hard accent，只做快速視覺辨識，
   畫面上不顯示文字（語意由 .attraction-tag-icon 的 aria-label 承載）。無圓底／外框，比
   LOCAL NOTE 的黃色燈泡 marker（黃圓＋黑框＋藍 offset）輕，兩者共用黃／藍品牌色但不是同一種
   元件。黃色塊用 ::after 疊在 icon 後面（isolation 建立自己的 stacking context，z-index:-1
   才會落在線稿「後面」而不是跑到容器外），三顆共用同一組尺寸／線寬／accent，視覺一致。 */
.attraction-tags {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: center;
  gap: 18px 26px;
}

.attraction-tag-icon {
  position: relative;
  isolation: isolate;
  display: block;
  width: 34px;
  height: 34px;
}

.attraction-tag-icon::after {
  content: "";
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 19px;
  height: 19px;
  background-color: #ffd400;
  z-index: -1;
}

.attraction-tag-icon svg {
  display: block;
  width: 100%;
  height: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .detail-tab-btn {
    transition: none;
  }
}

/* ---- Image Lightbox：全站共用單一實例，只放大顯示當下點擊的縮圖原圖 ----
   z-index 1500，高於 .detail-overlay 的 1400，確保疊在 Detail Overlay 之上；
   本身不是第二個 Detail Overlay，不套用 Content Rail／Vertical Rhythm token。 */
.image-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1500;
  background-color: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.image-lightbox[hidden] {
  display: none;
}

.image-lightbox-img {
  display: block;
  max-width: calc(92vw - 8px); /* 留 8px 給右下黃色 hard shadow，不超出畫面 */
  max-height: calc(85vh - 8px);
  width: auto;
  height: auto;
  object-fit: contain;
  border: 2px solid #1a1a1a;
  border-radius: 0;
  box-shadow: 6px 6px 0 #ffd400;
}

.image-lightbox-close {
  position: fixed;
  top: calc(0.6rem + env(safe-area-inset-top, 0px));
  right: 0.7rem;
  z-index: 2;
  width: 38px;
  height: 38px;
  border: 1.5px solid #1a1a1a;
  background-color: #fff2d8;
  border-radius: 50%;
  font-size: 1.1rem;
  font-weight: bold;
  line-height: 1;
  cursor: pointer;
  box-shadow: 1.5px 1.5px 0px #1a1a1a;
}

.image-lightbox-close:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 3px;
}

/* ---- Localization Pass 1：店家／景點名稱第二行（自然翻譯顯示名稱） ----
   只在外語介面出現（中文介面完全不 render 這個 div，見 placeNameHtml()）。三處標題
   （List Card／Bottom Sheet／Detail Overlay）共用同一個 class，用 em 讓字級跟著各自
   主標題的字級走，維持統一的視覺層級比例，不需要三份各自的字級規則。 */
.place-card-name-translated,
.info-card-name-translated,
.detail-name-translated {
  /* font-size 的 em 是相對容器（16px），不是相對旁邊的中文主名稱；原本三處都是 0.78em＝12.5px。
     改成各自的 rem：List 13.4px（+0.9，中文主名稱 14.4px）、Bottom Sheet 13.8px（+1.3，
     主名稱 15px）、Detail 14.4px（+1.9，主名稱 18.4px），全部仍小於中文主名稱。 */
  font-weight: 600;
  line-height: 1.35;
  color: #555;
  margin-top: 2px;
}

.place-card-name-translated {
  font-size: 0.84rem;
}

.info-card-name-translated {
  font-size: 0.86rem;
}

.detail-name-translated {
  font-size: 0.9rem;
}
