/*
 * 前台（電商）design token 與基礎樣式
 *
 * 色票取自品牌 icon（Backend/Web/SiteAssets/favicon.ico）的實測像素值：
 *   底色 #d7c0a6（沙棕，佔 icon 約 9 成面積）、線稿 #241814（深可可）。
 *   兩色為整站的骨架，其餘階調都是由這兩色調出的明暗變化。
 * 版型走圓角（--site-radius 系列），與 icon 的圓形輪廓一致。
 *
 * 本檔案放在 Backend/Web/SiteAssets/ 而非 wwwroot/，
 * 因為 ClientApp 的 vite build 設定了 emptyOutDir，會清空 wwwroot。
 * 由 Program.cs 額外掛載為 /site 靜態路徑。
 */

:root {
  /* ---- 品牌原色（直接取自 icon） ---- */
  --site-sand: #d7c0a6;       /* icon 底色 */
  --site-cocoa: #241814;      /* icon 線稿色 */

  /* 底色：由 --site-sand 往亮處調，維持同一個暖色相 */
  --site-cream: #faf5ee;      /* 頁面底 */
  --site-white: #fffdf9;      /* 卡片底 */
  --site-cream2: #f0e5d7;     /* 次級區塊 */
  --site-sand-soft: #e6d5c0;  /* 沙色淡版，用於底紋與 hover */
  --site-border: #e8dbc9;     /* 分隔線 */

  /* 主色：沙棕與可可之間的中間調，可壓白字 */
  --site-brand: #8a6a4b;
  --site-brand-dark: #6b5138;

  /*
   * 舊變數名（前一版參考站的玫瑰棕）保留為別名。
   * 全站既有規則都寫 --site-rose，改為指向品牌色即可一次換色，
   * 不必逐條改選擇器，也不會漏掉。
   */
  --site-rose: var(--site-brand);
  --site-rose-dark: var(--site-brand-dark);

  /* 文字 */
  --site-ink: #241814;
  --site-dark: #3f2f24;
  --site-muted: #8d7b6b;
  --site-mist: #b8a794;

  /* 點綴 */
  --site-sage: #94a68d;
  --site-gold: #c0996a;

  /* 陰影：暖色調的陰影才不會讓奶油底發灰 */
  --site-shadow-sm: 0 2px 8px rgba(36, 24, 20, 0.05);
  --site-shadow: 0 8px 24px rgba(36, 24, 20, 0.07);
  --site-shadow-lg: 0 16px 40px rgba(36, 24, 20, 0.1);

  /* ---- 版面寬度 ---- */
  --site-max-width: 1200px;
  --site-gutter: 20px;

  /*
   * 內文量測寬（measure）：單欄頁面的可讀寬度。
   * 各頁原本各自用 inline style 寫死 max-width，收成一組 token 之後，
   * 大螢幕只要改這裡就能整組放寬，不必逐頁去改 Razor。
   * 對應的 class 在 .site-narrow 附近。
   */
  --site-measure-xs: 420px;   /* 登入／註冊等窄表單 */
  --site-measure-sm: 560px;   /* 轉導頁、單則訊息 */
  --site-measure: 760px;      /* 內容頁本文 */
  --site-measure-lg: 840px;   /* 會員專區、訂單明細 */
  --site-measure-xl: 900px;   /* 訂單列表 */

  --site-aside-w: 320px;      /* 購物車／結帳的摘要側欄 */
  --site-minicart-w: 340px;   /* 頁首購物車快速預覽 */
  --site-modal-w: 520px;      /* 地址編輯對話框 */

  /* ---- 字階 ----
   *
   * 全站的 font-size 一律引用這組 token，不再各處寫死 px。
   * 大螢幕的放大就是在下方的 media query 裡整組換掉這 10 個值，
   * 規則本身一條都不必重寫。
   */
  --site-fs-3xs: 11.5px;      /* 徽章、QR 標題 */
  --site-fs-2xs: 12.5px;      /* 註記、原價、版權列 */
  --site-fs-xs: 13.5px;       /* 頁首導覽、頁尾連結、次要說明 */
  --site-fs-sm: 14.5px;       /* 按鈕、表單、卡片名稱 */
  --site-fs-md: 15px;         /* 內文 */
  --site-fs-lg: 16px;         /* 小標、合計 */
  --site-fs-xl: 20px;         /* 內容頁 h2、手機版大標 */
  --site-fs-2xl: 23px;        /* 區塊標題、商品售價 */
  --site-fs-3xl: 26px;        /* 商品名稱、橫幅標題 */
  --site-fs-4xl: 30px;        /* 主視覺標題 */

  /* ---- 垂直節奏與版位內距 ---- */
  --site-section-y: 64px;     /* 區塊上下留白 */
  --site-hero-pt: 88px;
  --site-hero-pb: 72px;
  --site-grid-gap-y: 28px;    /* 商品格線 */
  --site-grid-gap-x: 22px;
  --site-card-pad: 16px;      /* 商品卡文字區 */
  --site-panel-pad: 22px;     /* 摘要卡、訂單面板 */
  --site-product-gap: 48px;   /* 商品頁左右兩欄 */
  --site-cart-thumb: 96px;    /* 購物車／訂單的商品縮圖 */

  /* ---- 頁首 ---- */
  --site-header-h: 72px;
  /*
   * 頁首在版面上實際佔掉的高度＝膠囊列高 ＋ .site-header 的上下內距（12px×2）。
   * 主視覺要吃滿頁首以下的首屏，高度得用這個值去扣，不能只扣膠囊列。
   * .site-header 的 padding 改了，這裡要一起改。
   * 註：≤900px 的膠囊列高度是寫死的 64px（見該斷點的 .site-header__bar），
   * 不吃 --site-header-h，所以窄版另外用 --site-hero-header-sm。
   */
  --site-header-total: calc(var(--site-header-h) + 24px);
  --site-header-pad-x: 14px;
  --site-logo-h: 46px;        /* 圓標 */
  --site-logo-text-h: 16px;   /* 字標 */
  --site-iconbtn: 42px;       /* 圓形圖示鈕（漢堡、商品圖切換） */
  --site-nav-pad-y: 9px;      /* 導覽／動作膠囊 */
  --site-nav-pad-x: 14px;

  /* ---- 控制項 ---- */
  --site-btn-pad-y: 13px;
  --site-btn-pad-x: 22px;
  --site-input-pad-y: 10px;
  --site-input-pad-x: 12px;

  /* ---- 頁尾 ---- */
  --site-footer-gap: 48px;   /* 頁尾三段（品牌／QR／連結）之間 */
  --site-footer-mt: 72px;
  --site-footer-pt: 56px;
  --site-footer-pb: 28px;
  --site-footer-logo-h: 56px;
  --site-footer-logo-text-h: 20px;
  --site-social-size: 40px;
  /*
   * QR 小卡寬度（圖片是卡寬扣掉左右 8px 內距的正方形）。
   * 只留一個值：以前卡寬、圖寬分成兩個 token，
   * 兩者一不同步就會變成「寬卡配小圖」，而且 QR 被拉伸就掃不出來。
   */
  --site-qr-card: 136px;

  /* ---- 其他 ---- */
  --site-slider-arrow: 46px;  /* 主視覺輪播左右鈕 */

  /*
   * 收尾很慢的緩動，用在「浮現／推近」這類要有景深感的變化
   * （商品卡的 Lens Blur、主視覺文字框）。取自 taste-patterns-3 的同一條曲線。
   */
  --site-ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /*
   * 捲動進場用的曲線與位移，取自 /taste-demo-c（taste-demo-c.css 的 --tc-ease 與 translateY）。
   * 行為在 site.js 的 initReveal，樣式在本檔案的「捲動進場」。
   */
  --site-ease-reveal: cubic-bezier(0.32, 0.72, 0, 1);
  --site-reveal-y: 56px;

  /* ---- 首頁主視覺（滿版圖 ＋ 左下深色文案卡，≥1024px 才成立，見該段 media query） ----
   *
   * 版位是滿版的一整條：寬度貼齊視窗左右緣，高度吃滿頁首以下的整個首屏，
   * 圖佔滿整塊版位、Ken Burns 仍在裡面跑；
   * 深色文案卡貼齊版位左下角，下緣與版位（也就是螢幕底）切齊。
   * 卡片寬度隨標題長短（auto），上限是版位寬的 --site-hero-panel-max-w，
   * 超過就換行，不會把卡片拉到整個畫面寬。
   */
  --site-hero-panel-w: auto;     /* 文案卡寬度：隨內容 */
  --site-hero-panel-max-w: 64%;  /* 文案卡最寬佔版位多少，超過就換行 */

  /*
   * 文案卡的底。半透明＋backdrop-filter 是「毛玻璃」而不是實色板，
   * 但透明度不能無限降：標題是淺色的，卡片底一旦比標題亮就讀不到字了。
   *
   * 實測 0.55 不夠：現在這批主視覺是接近白的淺藍調，
   * 0.55 的可可疊上去只會變成中灰（約 rgb(124,121,124)），
   * 而標題本身是淺色的，對比只剩 2:1 左右，整段字會糊掉。
   * 0.72 疊在同一張圖上約是 rgb(80,72,71)，標題才拉得開。
   *
   * 主視覺是後台可換的，不能假設它一定夠深，所以這個值要照最亮的那張抓。
   * 想再透一點就調小，但請拿最亮的那張回頭確認字還讀得到。
   */
  --site-hero-panel-bg: rgba(36, 24, 20, 0.72);
  --site-hero-panel-blur: 22px;

  --site-hero-panel-border: rgba(250, 245, 238, 0.14);
  --site-hero-panel-solid: rgba(36, 24, 20, 0.88); /* 不支援 backdrop-filter 時的退路 */
  --site-hero-subtitle-color: var(--site-mist);
  --site-hero-panel-pad: 26px 26px;     /* 上下、右側內距 */
  --site-hero-panel-pad-start: 56px;    /* 左側內距：文字靠右，左邊刻意留一段空 */
  --site-hero-title-fs: 32px;    /* 標題；筆畫要夠粗，裡面的漸層才看得出來 */
  --site-hero-title-fs-sm: 26px; /* 手機版（≤900px）標題；同上，原本的 --site-fs-xl（20px）漸層太細看不出來 */

  /*
   * 手機版（≤900px）主視覺吃滿首屏，高度 = 可視高度 − 頁首。
   * .site-header 上下內距 12px×2 ＋ 手機膠囊列 64px（見 ≤900px 的 .site-header__bar）。
   * 膠囊列的高度在該斷點是寫死的，不吃 --site-header-h，所以這裡另開一個值；
   * 任一邊改了（頁首內距、膠囊列高度），這裡要一起調。
   *
   * 原本還會再扣一段「露出量」讓底下的 SELECTED 眉標露出來，現已移除：
   * 首屏要的是整張圖滿版，往下還有內容改由捲動提示（如果日後需要）另外處理。
   */
  --site-hero-header-sm: 88px;

  /* ---- 圓角 ---- */
  --site-radius-xs: 6px;      /* 標籤、徽章 */
  --site-radius-sm: 10px;     /* 輸入框、小按鈕 */
  --site-radius: 16px;        /* 一般容器（卡片、面板） */
  --site-radius-lg: 24px;     /* 大版位（主視覺、頁尾） */
  --site-radius-pill: 999px;  /* 膠囊按鈕、圓形圖示鈕 */

  --site-font: "Zen Kaku Gothic New", "PingFang TC", "Noto Sans TC",
    "Microsoft JhengHei", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}

/* ---------------------------------------------------------------------------
 * 大螢幕尺度（≥1400px / ≥1680px）
 *
 * 上面那組 token 是為 1366〜1280 的筆電視窗定的：內容欄 1200px、內文 15px。
 * 同一份數值放到 1600 以上的桌機螢幕，兩側會空掉三、四百像素，
 * 字與圖示卻還維持筆電的尺寸，整頁看起來就是「小一號」。
 *
 * 這裡不重寫任何規則，只把 token 整組換掉——
 * 字級、內距、圖示、圓角、欄寬會一起等比長大，版面比例維持不變。
 * 1400 以下完全不受影響，筆電看到的仍是原本的設計。
 *
 * 兩段斷點的取法：
 *   1400px  1440／1600 級螢幕，以及 1920 螢幕上沒有最大化的視窗
 *   1680px  1680／1920 級螢幕最大化時的視窗寬度
 * ------------------------------------------------------------------------- */

@media (min-width: 1400px) {
  :root {
    --site-max-width: 1280px;
    --site-gutter: 28px;

    --site-measure-xs: 440px;
    --site-measure-sm: 600px;
    --site-measure: 800px;
    --site-measure-lg: 880px;
    --site-measure-xl: 960px;

    --site-aside-w: 340px;
    --site-minicart-w: 360px;
    --site-modal-w: 560px;

    --site-fs-3xs: 12.5px;
    --site-fs-2xs: 13.5px;
    --site-fs-xs: 14.5px;
    --site-fs-sm: 15.5px;
    --site-fs-md: 16px;
    --site-fs-lg: 17.5px;
    --site-fs-xl: 22px;
    --site-fs-2xl: 25px;
    --site-fs-3xl: 29px;
    --site-fs-4xl: 34px;

    --site-section-y: 76px;
    --site-hero-pt: 100px;
    --site-hero-pb: 84px;
    --site-grid-gap-y: 32px;
    --site-grid-gap-x: 26px;
    --site-card-pad: 18px;
    --site-panel-pad: 24px;
    --site-product-gap: 56px;
    --site-cart-thumb: 104px;

    --site-header-h: 78px;
    --site-header-pad-x: 16px;
    --site-logo-h: 50px;
    --site-logo-text-h: 17.5px;
    --site-iconbtn: 44px;
    --site-nav-pad-y: 10px;
    --site-nav-pad-x: 16px;

    --site-btn-pad-y: 14px;
    --site-btn-pad-x: 26px;
    --site-input-pad-y: 11px;
    --site-input-pad-x: 14px;

    --site-footer-gap: 58px;
    --site-footer-mt: 84px;
    --site-footer-pt: 64px;
    --site-footer-pb: 32px;
    --site-footer-logo-h: 62px;
    --site-footer-logo-text-h: 22px;
    --site-social-size: 44px;
    --site-qr-card: 152px;

    --site-slider-arrow: 52px;

    --site-hero-panel-w: auto;
    --site-hero-panel-pad: 34px 34px;
    --site-hero-panel-pad-start: 72px;
    --site-hero-title-fs: 42px;

    --site-radius-xs: 7px;
    --site-radius-sm: 11px;
    --site-radius: 18px;
    --site-radius-lg: 27px;
  }
}

@media (min-width: 1680px) {
  :root {
    /* 1920 螢幕最大化時左右各留約 220px，四欄商品格線每張卡約 330px 寬 */
    --site-max-width: 1480px;
    --site-gutter: 36px;

    --site-measure-xs: 480px;
    --site-measure-sm: 640px;
    /* 內文 860px 搭 17px 字約 50 個全形字一行，仍在好讀的範圍內 */
    --site-measure: 860px;
    --site-measure-lg: 960px;
    --site-measure-xl: 1040px;

    --site-aside-w: 380px;
    --site-minicart-w: 400px;
    --site-modal-w: 600px;

    --site-fs-3xs: 13px;
    --site-fs-2xs: 14.5px;
    --site-fs-xs: 15.5px;
    --site-fs-sm: 16.5px;
    --site-fs-md: 17px;
    --site-fs-lg: 19px;
    --site-fs-xl: 24px;
    --site-fs-2xl: 28px;
    --site-fs-3xl: 33px;
    --site-fs-4xl: 40px;

    --site-section-y: 92px;
    --site-hero-pt: 120px;
    --site-hero-pb: 100px;
    --site-grid-gap-y: 40px;
    --site-grid-gap-x: 32px;
    --site-card-pad: 22px;
    --site-panel-pad: 28px;
    --site-product-gap: 64px;
    --site-cart-thumb: 116px;

    --site-header-h: 86px;
    --site-header-pad-x: 20px;
    --site-logo-h: 56px;
    --site-logo-text-h: 20px;
    --site-iconbtn: 48px;
    --site-nav-pad-y: 12px;
    --site-nav-pad-x: 20px;

    --site-btn-pad-y: 16px;
    --site-btn-pad-x: 30px;
    --site-input-pad-y: 13px;
    --site-input-pad-x: 16px;

    --site-footer-gap: 72px;
    --site-footer-mt: 100px;
    --site-footer-pt: 76px;
    --site-footer-pb: 38px;
    --site-footer-logo-h: 72px;
    --site-footer-logo-text-h: 26px;
    --site-social-size: 50px;
    --site-qr-card: 172px;

    --site-slider-arrow: 58px;

    --site-hero-panel-w: auto;
    --site-hero-panel-pad: 44px 44px;
    --site-hero-panel-pad-start: 96px;
    --site-hero-title-fs: 54px;

    --site-radius-xs: 8px;
    --site-radius-sm: 12px;
    --site-radius: 20px;
    --site-radius-lg: 30px;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

/*
 * hidden 屬性必須勝過元件自己的 display。
 * 沒有這條，.site-cart 的 display:grid、徽章的 inline-block 都會讓 [hidden] 失效，
 * 空購物車會同時出現「空車提示」與「訂單摘要」。
 */
[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--site-cream);
  color: var(--site-ink);
  font-family: var(--site-font);
  font-weight: 400;
  font-size: var(--site-fs-md);
  line-height: 1.8;
  letter-spacing: 0.02em;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  color: var(--site-rose);
}

h1,
h2,
h3 {
  font-weight: 500;
  letter-spacing: 0.06em;
  line-height: 1.5;
  margin: 0;
}

.site-container {
  width: 100%;
  max-width: var(--site-max-width);
  margin: 0 auto;
  padding: 0 var(--site-gutter);
}

/* ---------- 頁首 ----------
 *
 * 版型是「浮起的膠囊列」：頁首本身只是一層半透明底，
 * 實際的框線與陰影落在內層的 .site-header__bar 上。
 * 三欄 grid（1fr / auto / 1fr）讓 logo 不論左右內容多寡都固定置中。
 * 手機把左欄換成漢堡鈕，導覽移到下方的 .site-navpanel。
 */

/*
 * 底色不再疊 backdrop-filter。
 * 頁首是 sticky，底下的內容每捲一格都在變，模糊就得每一格對整條頁首重算一次，
 * 桌機寬度大時是捲動最主要的負擔。而膠囊列本身是不透明白底，
 * 模糊實際上只露在上下各 12px 的窄邊與兩側留白，所以改成接近不透明的奶油底，
 * 看起來幾乎沒有差別。
 */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  padding: 12px 0;
  background: rgba(250, 245, 238, 0.94);
}

.site-header__bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  height: var(--site-header-h);
  padding: 0 var(--site-header-pad-x);
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-pill);
  box-shadow: var(--site-shadow-sm);
}

.site-header__left {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/*
 * 漢堡鈕只在手機出現；桌機的導覽直接排在左欄。
 * 選擇器同時寫上 .site-iconbtn，特異性才蓋得過後面 .site-iconbtn 的 display:inline-flex。
 */
.site-iconbtn.site-header__toggle {
  display: none;
}

/* 開／關圖示疊在同一顆鈕上，靠 aria-expanded 決定誰現身 */
.site-header__toggle .site-header__toggle-close,
.site-header__toggle[aria-expanded='true'] .site-header__toggle-open {
  display: none;
}

.site-header__toggle[aria-expanded='true'] .site-header__toggle-close {
  display: block;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  font-size: var(--site-fs-xs);
  letter-spacing: 0.1em;
  color: var(--site-dark);
}

.site-header__actions {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--site-fs-xs);
  letter-spacing: 0.08em;
  white-space: nowrap;
}

/* 圓形圖示鈕（漢堡、輪播箭頭以外的單一圖示操作共用） */
.site-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--site-iconbtn);
  height: var(--site-iconbtn);
  padding: 0;
  color: var(--site-dark);
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-pill);
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.site-iconbtn:hover {
  background: var(--site-sand-soft);
  border-color: var(--site-sand);
  color: var(--site-ink);
}

.site-iconbtn:focus-visible {
  outline: 2px solid var(--site-brand);
  outline-offset: 2px;
}

/* ---------- 手機導覽面板 ---------- */

.site-navpanel {
  margin-top: 10px;
  padding: 8px;
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius);
  box-shadow: var(--site-shadow);
}

.site-navpanel__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border-radius: var(--site-radius-sm);
  font-size: var(--site-fs-sm);
  letter-spacing: 0.08em;
  color: var(--site-dark);
  transition: background 0.2s ease, color 0.2s ease;
}

.site-navpanel__link:hover {
  background: var(--site-cream2);
  color: var(--site-ink);
}

.site-navpanel__link .site-icon {
  color: var(--site-muted);
}

/* 面板裡的按鈕（登出）：外觀與連結一致 */
.site-navpanel__link--button {
  width: 100%;
  border: 0;
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

/* ---------- 下拉重新整理（手機） ----------
 *
 * 標記：_SiteLayout.cshtml 的 #sitePull（表單頁不輸出，見 SitePageModel.PullRefreshOffKey）
 * 行為：site.js 的 initPullRefresh
 *
 * 取自 taste-patterns-3 的 47 Liquid Pull-to-Refresh：往下拉時，畫面最上緣像液體一樣
 * 被拉出一顆水滴，腰身隨拉動變細；沒拉到門檻就用彈簧彈回去，拉過門檻放開就重新載入。
 * 圖形是一條 path（形狀由 JS 逐格重算），圓鈕與圖示疊在水滴的球心上。
 */

.site-pull {
  display: none;
}

@media (max-width: 900px) {
  .site-pull {
    display: block;
    position: fixed;
    /*
     * 固定貼齊畫面最上緣，不隨頁首高度變動。
     * 原本是由 JS 在每次下拉開始時改成頁首的下緣，水滴因此滴在主視覺上。
     */
    top: 0;
    left: 50%;
    /*
     * 壓在頁首（20）底下。下拉時整頁（含頁首）會往下位移，畫面最上緣讓出一段空隙，
     * 水滴就在那段空隙裡，不必蓋在頁首上，也就不會遮住 logo；
     * 球與頁面上緣接觸的那一小段被頁首蓋住，看起來才像是頁面被水滴拉著。
     */
    z-index: 19;
    width: 120px;
    height: 140px;
    margin-left: -60px;
    pointer-events: none;
    visibility: hidden;
  }

  .site-pull.is-visible {
    visibility: visible;
  }

  /*
   * 關掉瀏覽器內建的下拉重新整理（Chrome Android、iOS Safari 15+），否則兩個會一起觸發。
   * 只在 JS 確認啟用後才加上 class：JS 沒載入時仍保有原生的下拉重新整理。
   * 代價是 iOS 在頁面頂端與底端的回彈也會一起消失。
   * body 也要寫：部分 WebKit 版本是從 body 讀根捲動區的 overscroll-behavior。
   */
  html.site-pull-on,
  html.site-pull-on body {
    overscroll-behavior-y: none;
  }
}

.site-pull__drop {
  display: block;
  width: 100%;
  height: 100%;
}

.site-pull__path {
  fill: var(--site-brand);
  transition: fill 0.2s ease;
}

/* 拉過門檻：顏色加深，告訴使用者「現在放開就會更新」 */
.site-pull.is-armed .site-pull__path {
  fill: var(--site-brand-dark);
}

/* 位置、縮放與跟著拉動的旋轉由 JS 寫在圓鈕上；載入中的自轉交給裡面的圖示，兩者才不會互相覆蓋 */
.site-pull__knob {
  position: absolute;
  left: 50%;
  top: 0;
  width: 20px;
  height: 20px;
  color: var(--site-cream);
  opacity: 0;
  transform: translate(-50%, -50%);
}

.site-pull__icon {
  display: block;
  fill: currentColor;
}

.site-pull.is-refreshing .site-pull__icon {
  animation: sitePullSpin 0.8s linear infinite;
}

@keyframes sitePullSpin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-pull.is-refreshing .site-pull__icon {
    animation: none;
  }
}

/* ---------- 主視覺 ---------- */

.site-hero {
  padding: var(--site-hero-pt) 0 var(--site-hero-pb);
  text-align: center;
}

.site-hero__title {
  font-size: var(--site-fs-4xl);
  letter-spacing: 0.16em;
  margin-bottom: 18px;
}

.site-hero__lead {
  color: var(--site-muted);
  font-size: var(--site-fs-sm);
  letter-spacing: 0.08em;
  margin: 0 auto;
  max-width: 34em;
}

/* ---------- 區塊 ----------
 *
 * 標題改為置中直排（眉標／主標／說明），
 * 「查看全部」不再擠在標題右側，移到商品格線下方的 .site-section__foot 置中。
 */

.site-section {
  padding: var(--site-section-y) 0;
}

.site-section__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  margin-bottom: 36px;
}

/* 眉標：主標上方的小字，用沙色膠囊圈起來 */
.site-section__eyebrow {
  display: inline-block;
  padding: 0.348em 1.217em;
  border-radius: var(--site-radius-pill);
  background: var(--site-cream2);
  color: var(--site-brand-dark);
  font-size: var(--site-fs-3xs);
  letter-spacing: 0.18em;
}

.site-section__title {
  font-size: var(--site-fs-2xl);
  letter-spacing: 0.14em;
}

.site-section__lead {
  margin: 0;
  max-width: 34em;
  color: var(--site-muted);
  font-size: var(--site-fs-xs);
  letter-spacing: 0.06em;
}

.site-section__foot {
  display: flex;
  justify-content: center;
  margin-top: 40px;
}

/* ---------- 全部商品的分類列 ---------- */

/*
 * 分類切換只重換商品區塊、頁面不重載（見 site.js 的 initStoreFilter），
 * 因此目前選到哪一個分類要自己標出來，不能靠換頁。
 */
.site-storefilter {
  flex-wrap: wrap;
  margin-bottom: 24px;
  /* 捲回列表頂端時，sticky 頁首不要蓋住第一排分類 */
  scroll-margin-top: var(--site-header-total);
}

.site-storefilter .site-nav__link.is-active {
  background: var(--site-cocoa);
  color: var(--site-cream);
}

.site-storefilter .site-nav__link.is-active:hover {
  background: var(--site-brand);
  color: var(--site-cream);
}

/* 等新的一批商品回來的空檔先淡掉，讓人看得出這一塊正在換 */
.site-products {
  transition: opacity 0.2s ease;
}

.site-products[aria-busy='true'] {
  opacity: 0.4;
}

/* ---------- 商品格線 ---------- */

.site-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--site-grid-gap-y) var(--site-grid-gap-x);
}

/*
 * hover 的加深陰影不直接過渡 box-shadow（每一格都要重畫陰影），
 * 改成把大陰影畫在 ::after 上、只淡入它的 opacity，陰影本身只畫一次。
 *
 * ::after 的陰影在卡片外圍，卡片若 overflow: hidden 會把它裁掉，
 * 所以圓角裁切改由裡面的 .site-card__link 負責（它包住卡片全部內容，見 _ProductCard.cshtml）。
 */
.site-card {
  position: relative;
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius);
  box-shadow: var(--site-shadow-sm);
  transition: transform 0.32s ease, border-color 0.32s ease;
}

.site-card::after {
  content: '';
  position: absolute;
  /* 蓋到 1px 邊框外緣，陰影才從卡片最外圈開始 */
  inset: -1px;
  border-radius: inherit;
  box-shadow: var(--site-shadow);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s ease;
}

.site-card:hover {
  transform: translateY(-4px);
  border-color: var(--site-sand);
}

.site-card:hover::after {
  opacity: 1;
}

.site-card__media {
  aspect-ratio: 3 / 4;
  background: var(--site-cream2);
}

.site-card__body {
  padding: var(--site-card-pad) var(--site-card-pad) calc(var(--site-card-pad) + 4px);
}

.site-card__name {
  font-size: var(--site-fs-sm);
  letter-spacing: 0.04em;
  margin-bottom: 6px;
}

.site-card__desc {
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
  line-height: 1.7;
  margin-bottom: 12px;
}

.site-card__price {
  font-size: var(--site-fs-sm);
  color: var(--site-brand-dark);
  letter-spacing: 0.04em;
}

/*
 * 卡片上的「查看商品」：Lens Blur Depth——滑過時商品圖散焦並略微推近，
 * 清楚的按鈕浮在前面，注意力自然落到前景。
 * 不再用不透明的遮罩把圖蓋掉，只留一層很淡的奶油色把按鈕托起來；
 * 分離主要來自模糊而不是覆蓋，圖看得見但退到後面。
 *
 * 整張卡片本身已是 <a>，這兩層只能是視覺元素（span），
 * 不能再放 <a>／<button>，否則巢狀互動元素不合法。
 */
.site-card__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(250, 245, 238, 0.32);
  opacity: 0;
  transition: opacity 0.42s var(--site-ease-out);
}

.site-card__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0.88em 1.76em;
  border-radius: var(--site-radius-pill);
  background: var(--site-white);
  color: var(--site-ink);
  font-size: var(--site-fs-2xs);
  letter-spacing: 0.1em;
  white-space: nowrap;
  /* 前景卡要比散焦的底圖再浮一階，陰影就不能只是 sm */
  box-shadow: var(--site-shadow-lg);
  transform: scale(0.94);
  transition: transform 0.42s var(--site-ease-out);
}

.site-card__link:hover .site-card__overlay,
.site-card__link:focus-visible .site-card__overlay {
  opacity: 1;
}

.site-card__link:hover .site-card__cta,
.site-card__link:focus-visible .site-card__cta {
  transform: scale(1);
}

/*
 * 觸控裝置沒有 hover，散焦與按鈕都不會被觸發（:focus-visible 也不會在點擊時成立）。
 * 遮罩常駐顯示只會擋住商品圖，所以直接不輸出——點卡片本來就會進商品頁。
 */
@media (hover: none) {
  .site-card__overlay {
    display: none;
  }
}

/* ---------- 佔位狀態 ---------- */

.site-placeholder {
  border: 1px dashed var(--site-border);
  border-radius: var(--site-radius);
  padding: 3.259em 1.481em;
  text-align: center;
  color: var(--site-muted);
  font-size: var(--site-fs-xs);
  letter-spacing: 0.06em;
  background: var(--site-white);
}

/* ---------- 頁尾 ----------
 *
 * 版型是一塊沙色的大圓角面板，上緣兩角收圓、與奶油底的內文區分開。
 * 左欄為品牌（logo／標語／聯絡方式／社群），右側兩欄是連結；
 * 版權列獨立成一條白色膠囊，不再用細線切分。
 */

.site-footer {
  margin-top: var(--site-footer-mt);
  background: var(--site-cream2);
  border-radius: var(--site-radius-lg) var(--site-radius-lg) 0 0;
  padding: var(--site-footer-pt) 0 var(--site-footer-pb);
}

/*
 * 頁尾兩段：左邊品牌，右邊 .site-footer__nav 收著「服務」與「關於」。
 * 兩組連結自己是一個 2 欄 grid，窄畫面仍並排，不會各佔一整段把頁尾拉長。
 */
.site-footer__cols {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--site-footer-gap);
}

/*
 * 有 QR 時的排法分三段寬度：
 *
 *   ≥1280    品牌 ｜ QR ｜ 連結        一排三欄
 *   901–1279 品牌＋QR 疊在左欄，連結在右欄
 *   ≤900     全部直排（見響應式那一段）
 *
 * 三欄版在 1280 以下放不下：聯絡小卡最少約 270px、三張 QR 約 430px、
 * 連結欄約 180px，加上兩道間距，1024 寬時內容區只有 969px。
 * 欄位又是 minmax(0, …)，擠不下就把連結欄一路壓到只剩兩個字寬，
 * 「關於我們」會斷成「關於／我們」。
 *
 * 中間寬度讓 QR 疊到品牌欄下面：聯絡方式、社群圖示、QR 本來就都是「聯絡管道」，
 * 放在同一欄語意也順。連結欄給 auto，依內容決定寬度，不會再被壓扁。
 *
 * 用 grid-template-areas 而不是改標記順序：三段寬度的排法不同，
 * 標記只能有一種順序，靠 area 名稱各自擺位置最直接。
 * 沒有 QR 就維持上面 .site-footer__cols 的兩欄，連結欄不會被推到中間那格。
 */
.site-footer__cols--qr {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "brand nav"
    "qrs   nav";
  row-gap: 32px;
}

.site-footer__cols--qr > .site-footer__brand {
  grid-area: brand;
}

.site-footer__cols--qr > .site-footer__qrs {
  grid-area: qrs;
}

.site-footer__cols--qr > .site-footer__nav {
  grid-area: nav;
}

/* 夠寬了才排成一排三欄：QR 欄寬由三張卡自己決定（auto），左右兩欄再分剩下的空間 */
@media (min-width: 1280px) {
  .site-footer__cols--qr {
    grid-template-columns: minmax(0, 1.4fr) auto minmax(0, 1fr);
    grid-template-areas: "brand qrs nav";
    row-gap: 0;
  }
}

.site-footer__nav {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.6em 2.133em;
}

/*
 * width:fit-content + display:flex，而不是 inline-flex：
 * 標語留空時，inline-flex 會讓後面的聯絡小卡接在同一行右邊。
 */
.site-footer__logo {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 0.933em;
  margin-bottom: 1.067em;
}

.site-footer__logo img {
  height: var(--site-footer-logo-h);
  width: auto;
}

/*
 * 字標比圓標矮很多，height 各自定。
 * 選擇器要帶上 .site-footer__logo，否則特異性輸給上面的 `.site-footer__logo img`。
 */
.site-footer__logo .site-footer__logo-text {
  height: var(--site-footer-logo-text-h);
}

.site-footer__title {
  position: relative;
  padding-bottom: 10px;
  font-size: var(--site-fs-xs);
  letter-spacing: 0.14em;
  color: var(--site-dark);
  margin-bottom: 12px;
}

/* 標題下的短飾線，取代整條分隔線 */
.site-footer__title::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 24px;
  height: 2px;
  border-radius: var(--site-radius-pill);
  background: var(--site-sand);
}

.site-footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--site-fs-xs);
  color: var(--site-muted);
  line-height: 2.2;
}

/* 連結滑過時往右挪一點，取代底線 */
.site-footer__list li a {
  display: inline-block;
  transition: transform 0.22s ease, color 0.22s ease;
}

.site-footer__list li a:hover {
  transform: translateX(3px);
  color: var(--site-brand-dark);
}

/* 聯絡方式：白色圓角小卡，跟連結欄的純文字拉開層次 */
.site-footer__contact {
  display: flex;
  width: fit-content;
  flex-direction: column;
  gap: 4px;
  margin-top: 14px;
  padding: 0.889em 1.333em;
  background: var(--site-white);
  border-radius: var(--site-radius);
  font-size: var(--site-fs-xs);
  color: var(--site-dark);
}

.site-footer__contact-row {
  display: flex;
  align-items: baseline;
  gap: 2px;
}

/* 標籤給固定寬度，「客服信箱」與「聯絡電話」的冒號才會對齊成一直線 */
.site-footer__contact-label {
  flex: 0 0 auto;
  min-width: 5em;
  color: var(--site-muted);
}

/* 社群圖示：品牌色底 + 白色 logo 的圓形鈕。
   品牌色是各家的官方識別色，不套用站台色票，才認得出來。 */
.site-social {
  display: flex;
  gap: 0.667em;
  margin-top: 1.333em;
}

.site-social__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--site-social-size);
  height: var(--site-social-size);
  border-radius: var(--site-radius-pill);
  color: #fff;
  transition: transform 0.28s ease, opacity 0.28s ease, box-shadow 0.28s ease;
}

.site-social__link:hover {
  transform: translateY(-3px);
  opacity: 0.92;
  box-shadow: var(--site-shadow-sm);
}

.site-social__link:focus-visible {
  outline: 2px solid var(--site-brand);
  outline-offset: 3px;
}

.site-social__icon {
  fill: currentColor;
  display: block;
}

.site-social__link--fb {
  background: #1877f2;
}

/* Instagram 沒有單一品牌色，官方識別是這條由左下到右上的漸層 */
.site-social__link--ig {
  background: linear-gradient(45deg, #f9ce34 0%, #ee2a7b 50%, #6228d7 100%);
}

.site-social__link--line {
  background: #06c755;
}

/* ---------- 頁尾 QR Code ----------
 *
 * 後台「前台設定」可維護三格，沒上傳圖的格子不會輸出。
 * 白色小卡的語彙與上方的聯絡方式小卡一致，在沙色頁尾上浮出來。
 * 沒填連結網址的格子不會有 href，因此 hover 與焦點框都以 [href] 限定，
 * 不可點的卡片就不該表現得像可以點。
 */

/*
 * 一張卡一個欄位（grid-auto-flow: column），欄寬就是 --site-qr-card。
 * 後台沒上傳圖的格子不會輸出，所以卡片可能只有一兩張——
 * 用 auto-columns 而不是 repeat(3, …)，才不會留下空的欄位把 QR 欄撐寬。
 * 窄畫面把欄寬改成 minmax(0, 卡寬)，三張會一起縮，見響應式那一段。
 */
.site-footer__qrs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--site-qr-card);
  justify-content: start;
  align-self: center;
  gap: 0.8em;
}

.site-qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 8px;
  background: var(--site-white);
  border-radius: var(--site-radius-sm);
  text-align: center;
  transition: transform 0.28s ease, box-shadow 0.28s ease;
}

/*
 * QR 一定要是正方形，被拉伸就掃不出來。
 * 寬度跟著卡片走、高度由 aspect-ratio 鎖成 1:1，
 * 卡片在窄畫面縮小時圖也等比縮，不必再為每個斷點另寫一組圖寬。
 */
.site-qr__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border-radius: var(--site-radius-xs);
}

.site-qr__title {
  font-size: var(--site-fs-3xs);
  line-height: 1.4;
  letter-spacing: 0.04em;
  color: var(--site-muted);
}

.site-qr[href]:hover {
  transform: translateY(-3px);
  box-shadow: var(--site-shadow-sm);
}

.site-qr[href]:hover .site-qr__title {
  color: var(--site-brand-dark);
}

.site-qr[href]:focus-visible {
  outline: 2px solid var(--site-brand);
  outline-offset: 3px;
}

.site-footer__copy {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 44px;
  padding: 1.12em 1.92em;
  background: var(--site-white);
  border-radius: var(--site-radius-pill);
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
  letter-spacing: 0.06em;
}

/* ---------- 響應式 ---------- */

@media (max-width: 900px) {
  .site-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .site-footer__cols,
  .site-footer__cols--qr {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  /* area 也要一起改成直排，否則中間寬度那組「兩欄」的 area 會自己多開一欄出來 */
  .site-footer__cols--qr {
    grid-template-areas:
      "brand"
      "qrs"
      "nav";
  }

  /*
   * 單欄時沒有「另一欄」可對齊，回到正常的文件流。
   * 欄寬改成 minmax(0, 卡寬)：放得下時維持原尺寸，
   * 最窄的手機上三張會一起縮到剛好擺進一行，不必再寫死一組手機尺寸。
   */
  .site-footer__qrs {
    align-self: start;
    grid-auto-columns: minmax(0, var(--site-qr-card));
  }

  .site-footer__copy {
    justify-content: center;
    text-align: center;
    border-radius: var(--site-radius);
  }


  /*
   * 只收掉頁首那一組導覽，改由漢堡鈕展開 .site-navpanel。
   * 選擇器限定在 .site-header__left，Store 頁用同一個 .site-nav 排分類，
   * 那組在手機仍要看得到。
   */
  .site-header__left .site-nav {
    display: none;
  }

  .site-iconbtn.site-header__toggle {
    display: inline-flex;
  }

  .site-header__bar {
    height: 64px;
    padding: 0 10px;
  }

  .site-logo__img {
    height: 40px;
  }

  .site-logo__text {
    height: 14px;
  }

  /* 手機的頁首只留圖示，膠囊收成圓形 */
  .site-action {
    width: 42px;
    height: 42px;
    padding: 0;
    justify-content: center;
    gap: 0;
  }

  .site-action__text {
    display: none;
  }

  .site-hero {
    padding: 56px 0 44px;
  }

  .site-hero__title {
    font-size: var(--site-fs-2xl);
  }

  .site-section {
    padding: 44px 0;
  }

  .site-section__title {
    font-size: var(--site-fs-xl);
  }
}

/*
 * 頁首在這個寬度以下只放得下圓標＋漢堡＋兩顆動作鈕，
 * 字標先收起來（品牌名仍由圓標的 alt 提供）。
 */
@media (max-width: 700px) {
  .site-logo__text {
    display: none;
  }
}

/* ---------- 表單（會員登入／註冊） ---------- */

.site-narrow {
  max-width: var(--site-measure-xs);
}

/*
 * 內文量測寬。原本各頁是在 .site-container 上加 inline style 寫死 max-width
 * （560／760／840／900），大螢幕時無法一起放寬，也重複散在八個 .cshtml 裡。
 * 收成這組 class 之後寬度由 token 決定，跟著斷點一起長。
 *
 * 必須排在 .site-container 之後：兩者特異性相同，靠出現順序才蓋得過去。
 */
.site-measure--sm {
  max-width: var(--site-measure-sm);
}

.site-measure {
  max-width: var(--site-measure);
}

.site-measure--lg {
  max-width: var(--site-measure-lg);
}

.site-measure--xl {
  max-width: var(--site-measure-xl);
}

.site-form {
  display: flex;
  flex-direction: column;
}

.site-form__label {
  font-size: var(--site-fs-xs);
  letter-spacing: 0.08em;
  color: var(--site-dark);
  margin: 14px 0 6px;
}

.site-form__input {
  font-family: inherit;
  font-size: var(--site-fs-sm);
  padding: var(--site-input-pad-y) var(--site-input-pad-x);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-sm);
  background: var(--site-white);
  color: var(--site-ink);
}

.site-form__input:focus {
  outline: none;
  border-color: var(--site-rose);
}

.site-form__error {
  background: var(--site-cream2);
  border-left: 2px solid var(--site-rose);
  padding: 0.741em 1.037em;
  font-size: var(--site-fs-xs);
  color: var(--site-rose-dark);
  margin-bottom: 20px;
}

/*
 * 驗證碼：輸入框與圖片並排。
 * 圖片包在 button 內，讓「換一張」不只滑鼠可用，鍵盤 Tab 到也能按。
 */
.site-captcha {
  display: flex;
  align-items: stretch;
  gap: 10px;
}

.site-captcha__input {
  flex: 1;
  /* min-width 0 讓 flex 子項可以縮小，否則 input 的預設寬度會把圖片擠出去 */
  min-width: 0;
  text-transform: uppercase;
  letter-spacing: 0.3em;
}

.site-captcha__refresh {
  padding: 0;
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-sm);
  background: var(--site-white);
  /* 去掉 inline 元素的行高留白，圖片才會貼齊邊框 */
  line-height: 0;
  cursor: pointer;
}

.site-captcha__refresh:focus-visible {
  outline: 2px solid var(--site-rose);
  outline-offset: 2px;
}

.site-captcha__image {
  display: block;
  /* 尺寸鎖成後端產圖的大小，避免被 flex 拉伸而糊掉 */
  width: 130px;
  height: 44px;
  border-radius: var(--site-radius-sm);
}

.site-captcha__hint {
  margin: 6px 0 0;
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
}

.site-form__foot {
  margin-top: 20px;
  font-size: var(--site-fs-xs);
  color: var(--site-muted);
  text-align: center;
}

.site-form__sep {
  margin: 0 8px;
  color: var(--site-border);
}

.site-btn {
  display: block;
  width: 100%;
  margin-top: 24px;
  padding: var(--site-btn-pad-y) var(--site-btn-pad-x);
  font-family: inherit;
  font-size: var(--site-fs-sm);
  letter-spacing: 0.14em;
  text-align: center;
  /* 主按鈕用 icon 的線稿色，比中間調的品牌棕更沉、對比也更足 */
  color: var(--site-cream);
  background: var(--site-cocoa);
  border: 1px solid var(--site-cocoa);
  border-radius: var(--site-radius-pill);
  cursor: pointer;
  transition: background 0.2s ease;
}

.site-btn:hover {
  background: var(--site-brand);
  border-color: var(--site-brand);
  color: var(--site-cream);
}

.site-btn:disabled {
  background: var(--site-sand-soft);
  border-color: var(--site-sand-soft);
  color: var(--site-muted);
  cursor: not-allowed;
}

.site-btn--outline {
  margin-top: 0;
  color: var(--site-ink);
  background: var(--site-white);
  border-color: var(--site-border);
}

.site-btn--outline:hover {
  background: var(--site-sand-soft);
  border-color: var(--site-sand);
  color: var(--site-ink);
}

/* 帶箭頭的按鈕：滑過時箭頭往右挪，方向感比單純變色明確 */
.site-btn__arrow {
  transition: transform 0.28s ease;
}

.site-btn:hover .site-btn__arrow {
  transform: translateX(4px);
}

.site-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 22px 0 4px;
  color: var(--site-muted);
  font-size: var(--site-fs-2xs);
}

.site-divider::before,
.site-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--site-border);
}


/* ---------- 頁首 logo ---------- */

.site-logo {
  /* 三欄 grid 的中欄，靠 justify-self 讓 logo 對齊版面正中 */
  justify-self: center;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  transition: transform 0.3s ease;
}

.site-logo__img {
  height: var(--site-logo-h);
  width: auto;
  transition: opacity 0.25s ease;
}

/*
 * 字標（logoText.png，720x73）排在圓標右邊。
 * 用 height 定尺寸、width 交給 auto，換圖時只要比例不同也不會變形。
 */
.site-logo__text {
  height: var(--site-logo-text-h);
  width: auto;
  transition: opacity 0.25s ease;
}

.site-logo:hover {
  transform: scale(1.04);
}

.site-logo:hover .site-logo__img,
.site-logo:hover .site-logo__text {
  opacity: 0.8;
}

/* ---------- 頁首連結：膠囊 hover ----------
 * 前一版是「底線由中間展開」；改版後頁首本身已是膠囊列，
 * 連結改用同形狀的底色塊，滑過時才不會出現方框與圓角混用。
 */

.site-nav__link,
.site-action {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: var(--site-nav-pad-y) var(--site-nav-pad-x);
  border-radius: var(--site-radius-pill);
  color: var(--site-dark);
  transition: background 0.25s ease, color 0.25s ease;
}

.site-nav__link:hover,
.site-action:hover {
  background: var(--site-sand-soft);
  color: var(--site-ink);
}

/* 購物車是主要動作，用品牌色實心膠囊拉開層級 */
.site-action--cart {
  background: var(--site-cocoa);
  color: var(--site-cream);
}

.site-action--cart:hover {
  background: var(--site-brand);
  color: var(--site-cream);
}

/* ---------- 圖示（inline SVG，path 見 WebApp.Site._Core.SiteIcons） ---------- */

.site-icon {
  fill: currentColor;
  flex: 0 0 auto;
  display: block;
}

.site-action .site-icon {
  transition: transform 0.28s ease;
}

.site-action:hover .site-icon {
  transform: translateY(-2px);
}

/* 鍵盤操作也要看得到焦點 */
.site-nav__link:focus-visible,
.site-action:focus-visible {
  outline: 2px solid var(--site-rose);
  outline-offset: 3px;
}

/* ---------- 按鈕 hover 動畫 ---------- */

.site-btn {
  position: relative;
  transition: background 0.25s ease, border-color 0.25s ease, transform 0.2s ease,
    box-shadow 0.25s ease;
}

.site-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(36, 24, 20, 0.18);
}

.site-btn:active {
  transform: translateY(0);
  box-shadow: none;
}

/* 停用的按鈕不做浮起動畫 */
.site-btn:disabled:hover {
  transform: none;
  box-shadow: none;
  background: var(--site-sand-soft);
  border-color: var(--site-sand-soft);
  color: var(--site-muted);
}

/* Google 按鈕：依品牌指南保持白底、不改 logo 顏色 */
.site-btn--google {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
}

/* 官方 G 標誌原圖為 200x204（非正方形），用 width:auto 維持原比例，
   品牌指南不允許變形或改色 */
.site-btn--google .site-btn__icon {
  width: auto;
  height: 18px;
  flex: 0 0 auto;
}

.site-btn--google:hover {
  box-shadow: 0 6px 18px rgba(36, 24, 20, 0.12);
}

/* ---------- 商品卡片狀態標記 ---------- */

/*
 * 卡片的圓角裁切在這一層（原本在 .site-card，為了讓 ::after 的陰影露在卡片外面而移下來）。
 * inherit 取卡片的圓角，taste-demo 各頁把卡片圓角改掉時也會跟著對上。
 *
 * 裁切移到這層之後，連結自己的預設焦點框就不再被卡片裁掉。
 * 原本鍵盤聚焦時看不到它，焦點提示是遮罩與「查看商品」按鈕（見 .site-card__overlay），
 * 這裡維持原本的外觀。
 */
.site-card__link {
  display: block;
  overflow: hidden;
  border-radius: inherit;
}

.site-card__link:focus-visible {
  outline: none;
}

.site-card__link:hover .site-card__name {
  color: var(--site-rose);
}

.site-card__media {
  position: relative;
  overflow: hidden;
}

.site-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--site-ease-out), filter 0.5s var(--site-ease-out);
}

/*
 * 推近的幅度是被模糊半徑決定的，不是隨手挑的：
 * blur() 會向外取樣，圖只放大一點點的話四個邊會透出半透明的暈邊。
 *
 * blur(4px) 的擴散範圍約 3σ = 12px，圖每一邊要溢出容器至少這麼多才蓋得住。
 * 卡片最窄的情況是基準斷點的四欄（約 265px），scale(1.16) 溢出 (265×0.16)/2 ≈ 21px，
 * 大於 12px。兩個值要一起看：模糊加大或推近縮小，都要重算一次會不會露邊。
 *
 * 模糊原本是 6px，降到 4px 是為了桌機的順暢度：模糊半徑越大，每一格要取樣的範圍越大，
 * 大螢幕的卡片面積又大，滑鼠掃過一整排時好幾張會同時在跑。推近維持 1.16，外觀不變。
 */
.site-card__link:hover .site-card__img,
.site-card__link:focus-visible .site-card__img {
  transform: scale(1.16);
  filter: blur(4px);
}

/*
 * 觸控裝置的遮罩與按鈕在上面已經關掉（見 @media (hover: none)），
 * 沒有前景可襯的散焦只會變成一張糊掉的商品圖，這裡一併關掉。
 * :hover 在觸控裝置不會成立，但外接鍵盤的 :focus-visible 會。
 *
 * 這段必須排在上面那條 hover 規則之後：兩者特異性相同，靠順序決勝。
 */
@media (hover: none) {
  .site-card__link:hover .site-card__img,
  .site-card__link:focus-visible .site-card__img {
    transform: none;
    filter: none;
  }
}

/*
 * 使用者要求減少動態：散焦與推近都停掉，退回原本的淺色遮罩。
 * 不能只拿掉 scale 留下 blur——推近正是用來蓋掉模糊暈邊的，
 * 少了它邊緣會透出來，比不做效果還糟。
 */
@media (prefers-reduced-motion: reduce) {
  .site-card__img,
  .site-card__link:hover .site-card__img,
  .site-card__link:focus-visible .site-card__img {
    transform: none;
    filter: none;
    transition-duration: 120ms;
  }

  .site-card__overlay {
    background: rgba(250, 245, 238, 0.62);
  }

  .site-card__cta,
  .site-card__link:hover .site-card__cta,
  .site-card__link:focus-visible .site-card__cta {
    transform: none;
  }
}

.site-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 0.261em 0.783em;
  font-size: var(--site-fs-3xs);
  letter-spacing: 0.1em;
  color: var(--site-white);
  background: var(--site-rose);
  border-radius: var(--site-radius-pill);
}

.site-badge--soldout {
  background: var(--site-muted);
}

.site-badge--preorder {
  background: var(--site-sage);
}

.site-price__list {
  color: var(--site-muted);
  text-decoration: line-through;
  margin-right: 8px;
  font-size: var(--site-fs-2xs);
}

/* ---------- 商品頁 ---------- */

.site-product {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: var(--site-product-gap);
  padding: 40px 0 24px;
}

/* ---------- 商品圖切換 ----------
 *
 * 兩層圖片疊在同一個框裡做交叉淡入：新圖先塞進背層、
 * 等 decode() 完成才互換 .is-active，中途不會露出底色或半載入的圖。
 * 兩層都是 alt=""＋aria-hidden，可讀名稱掛在外層 .site-product__frame 的
 * role="img" / aria-label 上，避免同一張圖被讀兩次。
 */

.site-product__gallery {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.site-product__stage {
  position: relative;
  border-radius: var(--site-radius-lg);
  overflow: hidden;
  background: var(--site-cream2);
  border: 1px solid var(--site-border);
  box-shadow: var(--site-shadow-sm);
}

.site-product__frame {
  position: relative;
  aspect-ratio: 3 / 4;
}

.site-product__main-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.03);
  transition: opacity 0.45s ease, transform 0.7s ease;
}

.site-product__main-img.is-active {
  opacity: 1;
  transform: scale(1);
  /* 疊在上層，離場的那張才會被蓋住而不是穿透 */
  z-index: 2;
}

/* 滑鼠停在圖上時極輕微推近，暗示這區是可互動的 */
.site-product__stage:hover .site-product__main-img.is-active {
  transform: scale(1.03);
}

/* 左右切換鈕：平常半透明，滑進圖片區才浮現 */
.site-product__nav {
  position: absolute;
  top: 50%;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--site-iconbtn);
  height: var(--site-iconbtn);
  padding: 0;
  transform: translateY(-50%);
  color: var(--site-ink);
  background: rgba(255, 253, 249, 0.9);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-pill);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.28s ease, background 0.25s ease;
}

.site-product__stage:hover .site-product__nav,
.site-product__nav:focus-visible {
  opacity: 1;
}

.site-product__nav:hover {
  background: var(--site-white);
}

.site-product__nav:focus-visible {
  outline: 2px solid var(--site-brand);
  outline-offset: 2px;
}

.site-product__nav--prev {
  left: 12px;
}

.site-product__nav--next {
  right: 12px;
}

/* 第幾張 / 共幾張 */
.site-product__counter {
  position: absolute;
  right: 14px;
  bottom: 14px;
  z-index: 3;
  padding: 0.348em 1.043em;
  border-radius: var(--site-radius-pill);
  background: rgba(36, 24, 20, 0.62);
  color: var(--site-cream);
  font-size: var(--site-fs-3xs);
  letter-spacing: 0.1em;
}

.site-product__thumbs {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}

.site-product__thumb {
  position: relative;
  display: block;
  padding: 0;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--site-cream2);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-sm);
  cursor: pointer;
  transition: border-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

.site-product__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.site-product__thumb:hover {
  border-color: var(--site-sand);
  transform: translateY(-2px);
  box-shadow: var(--site-shadow-sm);
}

.site-product__thumb:hover img {
  transform: scale(1.08);
}

.site-product__thumb[aria-current='true'] {
  border-color: var(--site-brand);
  box-shadow: 0 0 0 2px var(--site-sand-soft);
}

.site-product__thumb:focus-visible {
  outline: 2px solid var(--site-brand);
  outline-offset: 2px;
}

/* 使用者要求減少動態時，切換仍要看得出來，但不做位移與縮放 */
@media (prefers-reduced-motion: reduce) {
  .site-product__main-img,
  .site-product__main-img.is-active,
  .site-product__stage:hover .site-product__main-img.is-active {
    transform: none;
    transition-duration: 120ms;
  }

  .site-product__thumb,
  .site-product__thumb img {
    transition: none;
  }
}

.site-product__title {
  font-size: var(--site-fs-3xl);
  letter-spacing: 0.1em;
  margin-bottom: 10px;
}

.site-product__lead {
  color: var(--site-muted);
  font-size: var(--site-fs-sm);
  margin-bottom: 22px;
}

.site-product__price {
  font-size: var(--site-fs-2xl);
  color: var(--site-rose-dark);
  letter-spacing: 0.04em;
  margin-bottom: 24px;
}

.site-product__section-title {
  font-size: var(--site-fs-xs);
  letter-spacing: 0.12em;
  color: var(--site-dark);
  margin-bottom: 10px;
}

.site-variants {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 24px;
}

.site-variant {
  padding: 0.667em 1.333em;
  font-size: var(--site-fs-xs);
  letter-spacing: 0.04em;
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-pill);
  background: var(--site-white);
  color: var(--site-ink);
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}

.site-variant:hover:not(:disabled) {
  border-color: var(--site-sand);
  background: var(--site-sand-soft);
  color: var(--site-ink);
}

/* 選取態改成實心，跟 hover 的淡底一眼分得開 */
.site-variant[aria-pressed='true'] {
  border-color: var(--site-cocoa);
  color: var(--site-cream);
  background: var(--site-cocoa);
}

.site-variant:disabled {
  color: var(--site-muted);
  background: var(--site-cream);
  cursor: not-allowed;
  text-decoration: line-through;
}

/*
 * 顏色／尺寸分組：與另一軸目前的選擇組不出可購買規格的選項。
 * 仍可點（會連帶改選另一軸），所以只用虛線框提示，不畫刪除線，避免被當成售完。
 */
.site-variant.is-unavailable:not([aria-pressed='true']) {
  border-style: dashed;
  color: var(--site-muted);
}

/* 分組時兩組選項之間的距離由 .site-variants 的下邊距撐開，庫存提示緊貼最後一組 */
.site-product__stock {
  margin: -14px 0 20px;
  font-size: var(--site-fs-xs);
  letter-spacing: 0.04em;
  color: #9c4a42;
}

.site-product__desc {
  border-top: 1px solid var(--site-border);
  padding-top: 22px;
  margin-top: 8px;
  font-size: var(--site-fs-sm);
  line-height: 2;
  white-space: pre-wrap;
}

.site-product__note {
  background: var(--site-cream2);
  border: 1px solid var(--site-sand);
  border-radius: var(--site-radius);
  padding: 0.889em 1.333em;
  font-size: var(--site-fs-xs);
  color: var(--site-dark);
  margin-bottom: 20px;
}

.site-breadcrumb {
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
  letter-spacing: 0.06em;
  padding-top: 24px;
}

.site-breadcrumb a:hover {
  color: var(--site-rose);
}

.site-empty {
  padding: 4.138em 1.379em;
  text-align: center;
  color: var(--site-muted);
  font-size: var(--site-fs-sm);
  letter-spacing: 0.06em;
}

@media (max-width: 900px) {
  .site-product {
    grid-template-columns: 1fr;
    gap: 28px;
    padding-top: 24px;
  }
}

/* ---------------------------------------------------------------------------
 * 交易流程（購物車 / 結帳 / 訂單）
 * 沿用既有 token，不另外定義色票。
 * ------------------------------------------------------------------------- */

/*
 * .site-btn 預設是滿版（登入、註冊等表單的送出鈕）。
 * 交易流程裡多數按鈕要跟其他元素並排，用這個 modifier 收回寬度，
 * 不動既有 .site-btn 以免影響現有表單。
 */
.site-btn--inline {
  /*
   * 用 inline-flex 而非 inline-block：按鈕內可能含 inline SVG，
   * 而 .site-icon 是 display:block，放在 inline-block 裡會被擠成第二行。
   */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  margin-top: 0;
}

/* 提示訊息：右下角浮出，不打斷操作 */
.site-toast {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 60;
  max-width: 320px;
  padding: 12px 18px;
  background: var(--site-ink);
  color: var(--site-white);
  font-size: var(--site-fs-sm);
  letter-spacing: 0.04em;
  white-space: pre-line;
  border-radius: var(--site-radius);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.site-toast.is-shown {
  opacity: 1;
  transform: translateY(0);
}

.site-toast--error {
  background: #9c4a42;
}

/* 購物車數量徽章：疊在購物車膠囊的右上角，不佔膠囊內的寬度 */
.site-badge-count {
  position: absolute;
  top: -3px;
  right: -3px;
  display: inline-block;
  min-width: 20px;
  padding: 0 5px;
  background: var(--site-sand);
  color: var(--site-cocoa);
  font-size: var(--site-fs-3xs);
  font-weight: 500;
  line-height: 20px;
  text-align: center;
  /* 外框與頁首列同色，數字疊在膠囊邊緣上才不會糊在一起 */
  border: 2px solid var(--site-white);
  border-radius: var(--site-radius-pill);
}

/* ---------- 頁首購物車快速預覽 ----------
 * 面板由 Layout 在「非購物車頁」才輸出，開關行為在 site.js 的 initCartPreview。
 * 觸控裝置不啟用（JS 以 hover 能力判斷），所以這裡不需要另做手機版位。
 */

.site-cartmenu {
  position: relative;
  display: inline-flex;
}

.site-minicart {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 30;
  width: var(--site-minicart-w);
  max-width: calc(100vw - 2 * var(--site-gutter));
  /* 上方留白同時是膠囊與面板之間的透明橋接，游標移過去時不會離開容器 */
  margin-top: 10px;
  padding: 8px;
  color: var(--site-dark);
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius);
  box-shadow: var(--site-shadow-lg);
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.site-minicart::before {
  content: '';
  position: absolute;
  top: -10px;
  right: 0;
  left: 0;
  height: 10px;
}

.site-minicart.is-open {
  opacity: 1;
  transform: translateY(0);
}

/* 品項多時面板自己捲動，不把頁首撐到整個畫面 */
.site-minicart__lines {
  max-height: 320px;
  overflow-y: auto;
}

.site-minicart__line {
  display: grid;
  grid-template-columns: 48px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: var(--site-radius-sm);
  transition: background 0.2s ease;
}

.site-minicart__line:hover {
  background: var(--site-cream);
}

.site-minicart__media {
  display: block;
  width: 48px;
  height: 64px;
  overflow: hidden;
  background: var(--site-cream2);
  border-radius: var(--site-radius-sm);
}

.site-minicart__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.site-minicart__info {
  display: block;
  min-width: 0;
}

.site-minicart__name {
  /* 標題過長時只顯示兩行，面板高度才不會被單一品項撐開 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: var(--site-fs-xs);
  color: var(--site-ink);
}

.site-minicart__variant,
.site-minicart__meta {
  display: block;
  margin-top: 2px;
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
}

.site-minicart__price {
  font-size: var(--site-fs-xs);
  color: var(--site-rose-dark);
  white-space: nowrap;
}

.site-minicart__empty {
  padding: 24px 8px;
  font-size: var(--site-fs-xs);
  text-align: center;
  color: var(--site-muted);
}

.site-minicart__foot {
  margin-top: 8px;
  padding: 12px 8px 8px;
  border-top: 1px solid var(--site-border);
}

.site-minicart__total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 10px;
  font-size: var(--site-fs-xs);
  color: var(--site-ink);
}

.site-minicart__btn {
  display: block;
  width: 100%;
  text-align: center;
}

/* 數量輸入 */
.site-buy {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  margin-top: 8px;
}

/* 加入購物車＋直接購買：兩顆並排、等寬，填滿數量欄右側 */
.site-buy__actions {
  display: flex;
  flex: 1;
  gap: 12px;
  min-width: 0;
}

.site-buy__actions .site-btn {
  flex: 1;
  white-space: nowrap;
}

/* 手機寬度放不下數量欄＋兩顆按鈕，按鈕整排換到下一行 */
@media (max-width: 600px) {
  .site-buy {
    flex-wrap: wrap;
  }

  .site-buy__actions {
    flex-basis: 100%;
  }
}

.site-qty {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.site-qty__label {
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
  letter-spacing: 0.08em;
}

.site-qty__input {
  width: 5em;
  padding: 9px 10px;
  border: 1px solid var(--site-border);
  background: var(--site-white);
  color: var(--site-ink);
  font-family: inherit;
  font-size: var(--site-fs-sm);
  border-radius: var(--site-radius-sm);
}

.site-qty__input:focus {
  outline: none;
  border-color: var(--site-rose);
}

/*
 * 數量 −／＋（行為在 site.js 的 stepper）。
 * 外框畫在容器上，三個子元素共用同一條邊；聚焦時整組變色，看起來是一個控制項。
 */
.site-stepper {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-sm);
  background: var(--site-white);
  overflow: hidden;
}

.site-stepper:focus-within {
  border-color: var(--site-rose);
}

.site-stepper__btn {
  width: 2.4em;
  padding: 0;
  border: 0;
  background: none;
  color: var(--site-dark);
  font-family: inherit;
  font-size: var(--site-fs-md);
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.site-stepper__btn:hover:not(:disabled) {
  background: var(--site-sand-soft);
}

.site-stepper__btn:disabled {
  color: var(--site-mist);
  cursor: not-allowed;
}

.site-stepper__btn:focus-visible {
  outline: 2px solid var(--site-rose);
  outline-offset: -2px;
}

/* 輸入框的外框交給 .site-stepper，自己只留數字；隱藏原生的上下箭頭，避免與 −／＋ 重複 */
.site-stepper .site-stepper__input {
  width: 3em;
  border: 0;
  border-radius: 0;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}

.site-stepper__input::-webkit-outer-spin-button,
.site-stepper__input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/*
 * 商品頁手機版底部購買列（標記與顯示邏輯在 Product.cshtml）。
 * 寬螢幕的購買區永遠在首屏右欄，不需要這條，直接不顯示。
 * z-index 壓在對話框（50）與提示訊息（60）之下。
 */
.site-buybar {
  display: none;
}

@media (max-width: 900px) {
  .site-buybar {
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px var(--site-gutter) calc(10px + env(safe-area-inset-bottom));
    background: var(--site-white);
    border-top: 1px solid var(--site-border);
    box-shadow: 0 -6px 18px rgba(36, 24, 20, 0.08);
    transform: translateY(100%);
    visibility: hidden;
    transition: transform 0.25s ease, visibility 0s linear 0.25s;
  }

  .site-buybar.is-shown {
    transform: translateY(0);
    visibility: visible;
    transition: transform 0.25s ease, visibility 0s;
  }

  .site-buybar__info {
    flex: 1;
    min-width: 0;
  }

  .site-buybar__price {
    font-size: var(--site-fs-md);
    letter-spacing: 0.04em;
  }

  .site-buybar__variant {
    overflow: hidden;
    font-size: var(--site-fs-2xs);
    color: var(--site-muted);
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  /* 列很窄，按鈕收緊內距與字距，兩顆加價格才放得下 375px */
  .site-buybar .site-btn {
    padding: 0.8em 1em;
    letter-spacing: 0.06em;
    white-space: nowrap;
  }

  /* 頁尾最後一段不要被購買列蓋住；提示訊息往上挪到購買列上方 */
  body.has-buybar {
    padding-bottom: calc(72px + env(safe-area-inset-bottom));
  }

  body.has-buybar .site-toast {
    bottom: calc(84px + env(safe-area-inset-bottom));
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-buybar,
  .site-buybar.is-shown {
    transition: none;
  }
}

/* 購物車 */
.site-cart {
  display: grid;
  grid-template-columns: 1fr var(--site-aside-w);
  gap: 40px;
  align-items: start;
}

.site-cart__line {
  display: grid;
  /* 數量欄用 max-content：−／＋ 元件寬度固定，各列一致，不必另外寫死 em */
  grid-template-columns: var(--site-cart-thumb) 1fr max-content 7.4em 4em;
  gap: 16px;
  align-items: center;
  padding: 18px 0;
  border-bottom: 1px solid var(--site-border);
}

.site-cart__media {
  display: block;
  width: var(--site-cart-thumb);
  aspect-ratio: 3 / 4;
  background: var(--site-cream2);
  border-radius: var(--site-radius-sm);
  overflow: hidden;
}

.site-cart__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.site-cart__name {
  display: block;
  font-size: var(--site-fs-md);
  letter-spacing: 0.04em;
}

.site-cart__variant {
  margin-top: 2px;
  font-size: var(--site-fs-xs);
  color: var(--site-muted);
}

.site-cart__warn {
  margin-top: 4px;
  font-size: var(--site-fs-2xs);
  color: #9c4a42;
}

.site-cart__price {
  text-align: right;
  letter-spacing: 0.04em;
}

.site-cart__remove {
  padding: 0;
  border: 0;
  background: none;
  color: var(--site-muted);
  font-family: inherit;
  font-size: var(--site-fs-xs);
  cursor: pointer;
  transition: color 0.2s ease;
}

.site-cart__remove:hover {
  color: #9c4a42;
}

.site-cart__summary,
.site-checkout__summary {
  padding: var(--site-panel-pad);
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius);
  position: sticky;
  top: 20px;
}

.site-cart__checkout,
.site-checkout__submit {
  display: block;
  width: 100%;
  margin-top: 16px;
  text-align: center;
}

/* 格線項目會被拉滿欄寬，−／＋ 外框只包住自身內容 */
.site-cart__qty {
  justify-self: start;
}

/* 結帳連結停用（有品項不可購買時）：<a> 沒有 disabled，用 aria-disabled 套停用樣式 */
.site-btn[aria-disabled='true'],
.site-btn[aria-disabled='true']:hover {
  background: var(--site-sand-soft);
  border-color: var(--site-sand-soft);
  color: var(--site-muted);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.site-cart__block {
  margin: 10px 0 0;
  font-size: var(--site-fs-2xs);
  color: #9c4a42;
  line-height: 1.7;
}

/* 購物車的免運進度 */
.site-freeship {
  margin-top: 12px;
  padding: 12px 14px;
  background: var(--site-cream);
  border-radius: var(--site-radius-sm);
}

.site-freeship__text {
  margin: 0 0 8px;
  font-size: var(--site-fs-xs);
  line-height: 1.7;
  color: var(--site-dark);
}

.site-freeship__text strong {
  font-weight: 500;
  color: var(--site-brand-dark);
}

.site-freeship__bar {
  height: 6px;
  background: var(--site-sand-soft);
  border-radius: 999px;
  overflow: hidden;
}

.site-freeship__fill {
  display: block;
  width: 0;
  height: 100%;
  background: var(--site-sage);
  border-radius: inherit;
  transition: width 0.4s ease;
}

@media (prefers-reduced-motion: reduce) {
  .site-freeship__fill {
    transition: none;
  }
}

/* 結帳 */
.site-checkout {
  display: grid;
  grid-template-columns: 1fr var(--site-aside-w);
  gap: 40px;
  align-items: start;
}

/*
 * 比照 .site-form 用 flex column：.site-form__label 是 label（預設 inline），
 * 沒有這層堆疊就會跟 input 擠在同一行。
 */
.site-fieldset {
  display: flex;
  flex-direction: column;
  margin: 0 0 28px;
  padding: 0;
  border: 0;
}

/*
 * fieldset 裡依條件顯示的一組欄位（宅配欄位、超商欄位、地址簿）。
 * 多包一層 div 就不是 .site-fieldset 的直接子元素，標籤與輸入框會變成行內排列擠在一起，
 * 所以這一層要沿用同樣的直向排列。按鈕維持自身寬度，不被拉滿。
 */
.site-fieldset__group {
  display: flex;
  flex-direction: column;
}

.site-fieldset__group > .site-btn--inline {
  align-self: flex-start;
}

.site-fieldset__legend {
  padding: 0 0 12px;
  font-size: var(--site-fs-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--site-dark);
}

.site-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}

.site-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius);
  cursor: pointer;
  transition: border-color 0.2s ease;
}

.site-option:hover {
  border-color: var(--site-rose);
}

.site-option__text {
  display: flex;
  flex-direction: column;
}

.site-option__name {
  font-size: var(--site-fs-sm);
  letter-spacing: 0.04em;
}

.site-option__hint {
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
}

.site-store {
  margin-bottom: 10px;
  padding: 0.828em 0.966em;
  background: var(--site-cream2);
  font-size: var(--site-fs-sm);
  border-radius: var(--site-radius);
}

.site-coupon {
  display: flex;
  gap: 10px;
  align-items: stretch;
}

.site-coupon .site-form__input {
  flex: 1;
  margin-bottom: 0;
}

/* 摘要 */
.site-summary__title {
  padding-bottom: 12px;
  font-size: var(--site-fs-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  border-bottom: 1px solid var(--site-border);
}

.site-summary__lines {
  padding: 12px 0;
  border-bottom: 1px solid var(--site-border);
}

.site-summary__line {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--site-fs-xs);
  color: var(--site-muted);
}

.site-summary__line-name {
  flex: 1;
}

.site-summary__row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  font-size: var(--site-fs-sm);
}

.site-summary__row--total {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--site-border);
  font-size: var(--site-fs-lg);
  font-weight: 500;
}

.site-summary__note {
  margin: 10px 0 0;
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
  line-height: 1.7;
}

/* 通知條 */
.site-notice {
  margin-bottom: 20px;
  padding: 0.828em 1.103em;
  font-size: var(--site-fs-sm);
  border-radius: var(--site-radius);
  border: 1px solid var(--site-border);
}

.site-notice--ok {
  background: #eef2ec;
  border-color: var(--site-sage);
}

.site-notice--warn {
  background: #f7f0e6;
  border-color: var(--site-gold);
}

/* 訂單 */
.site-order__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

.site-order__tags {
  display: flex;
  gap: 6px;
}

/*
 * 訂單狀態時間軸（節點由 SiteOrderTimeline 組出）。
 * 桌機橫排、節點之間以線相連；手機直排，線改在左側。
 * 狀態：is-done 已發生、is-current 下一個要等的、is-todo 尚未發生、is-end 取消／退回／退款。
 */
.site-timeline {
  display: flex;
  margin: 0 0 24px;
  padding: var(--site-panel-pad);
  list-style: none;
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius);
}

.site-timeline__step {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
  text-align: center;
}

/* 連到前一個節點的線，畫在圓點中線的高度 */
.site-timeline__step + .site-timeline__step::before {
  content: '';
  position: absolute;
  top: 6px;
  right: 50%;
  width: 100%;
  height: 2px;
  background: var(--site-border);
}

.site-timeline__step.is-done + .site-timeline__step::before {
  background: var(--site-sage);
}

.site-timeline__dot {
  position: relative;
  z-index: 1;
  width: 14px;
  height: 14px;
  border: 2px solid var(--site-border);
  border-radius: 50%;
  background: var(--site-white);
}

.site-timeline__step.is-done .site-timeline__dot {
  border-color: var(--site-sage);
  background: var(--site-sage);
}

.site-timeline__step.is-current .site-timeline__dot {
  border-color: var(--site-gold);
  box-shadow: 0 0 0 4px rgba(192, 153, 106, 0.2);
}

.site-timeline__step.is-end .site-timeline__dot {
  border-color: var(--site-muted);
  background: var(--site-muted);
}

.site-timeline__label {
  margin-top: 4px;
  font-size: var(--site-fs-xs);
  letter-spacing: 0.04em;
  color: var(--site-dark);
}

.site-timeline__step.is-todo .site-timeline__label {
  color: var(--site-mist);
}

.site-timeline__step.is-current .site-timeline__label {
  font-weight: 500;
  color: var(--site-ink);
}

.site-timeline__time {
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
}

@media (max-width: 600px) {
  .site-timeline {
    flex-direction: column;
    gap: 14px;
  }

  .site-timeline__step {
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
    text-align: left;
  }

  /* 從上一個圓點的中心連到自己的圓點中心：各節點同高，往上半個自身高度再加上間距 */
  .site-timeline__step + .site-timeline__step::before {
    top: calc(-50% - 14px);
    right: auto;
    left: 6px;
    width: 2px;
    height: calc(100% + 14px);
  }

  .site-timeline__dot {
    flex-shrink: 0;
    align-self: center;
  }

  .site-timeline__label {
    margin-top: 0;
  }
}

/* 訂單明細底部：回列表、再買一次、取消訂單 */
.site-order__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

/* 取消是次要且具破壞性的動作，用文字按鈕放在最右，不與主要按鈕搶視覺 */
.site-order__cancel {
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  color: #9c4a42;
  font-family: inherit;
  font-size: var(--site-fs-xs);
  letter-spacing: 0.04em;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.site-order__cancel:disabled {
  color: var(--site-muted);
  cursor: not-allowed;
}

.site-tag {
  padding: 0.24em 0.8em;
  background: var(--site-cream2);
  color: var(--site-dark);
  font-size: var(--site-fs-2xs);
  letter-spacing: 0.06em;
  border-radius: 999px;
}

/*
 * 惠員專區分頁（行為在 Account/Index.cshtml）。
 * 外觀比照商品列表的分類膠囊（.site-storefilter），選中為可可色實心。
 * 手機寬度放不下時橫向捲動，不換行，分頁順序才不會被拆成兩排。
 */
.site-tabs {
  display: flex;
  gap: 6px;
  /* 留 3px 給聚焦外框：overflow-x 會連帶裁掉垂直方向超出的部分 */
  margin: -3px -3px 17px;
  padding: 3px;
  overflow-x: auto;
  scrollbar-width: none;
}

.site-tabs::-webkit-scrollbar {
  display: none;
}

.site-tabs__tab {
  flex-shrink: 0;
  padding: var(--site-nav-pad-y) var(--site-nav-pad-x);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius-pill);
  background: var(--site-white);
  color: var(--site-dark);
  font-family: inherit;
  font-size: var(--site-fs-sm);
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.site-tabs__tab:hover {
  background: var(--site-sand-soft);
  color: var(--site-ink);
}

.site-tabs__tab[aria-selected='true'] {
  background: var(--site-cocoa);
  border-color: var(--site-cocoa);
  color: var(--site-cream);
}

.site-tabs__tab:focus-visible {
  outline: 2px solid var(--site-rose);
  outline-offset: 2px;
}

/* 訂單狀態色調（SiteOrderSummaryDto.StatusTone）：底色沿用 .site-notice 的兩種提示色 */
.site-tag--warn {
  background: #f7f0e6;
  color: #8a5a1f;
  box-shadow: inset 0 0 0 1px var(--site-gold);
}

.site-tag--ok {
  background: #eef2ec;
  color: #4c6046;
}

.site-tag--muted {
  background: transparent;
  color: var(--site-muted);
  box-shadow: inset 0 0 0 1px var(--site-border);
}

.site-order__meta {
  margin: 0 0 20px;
  font-size: var(--site-fs-xs);
  color: var(--site-muted);
}

.site-order__pay {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
  padding: 16px 20px;
  background: var(--site-white);
  border: 1px solid var(--site-gold);
  border-radius: var(--site-radius);
}

.site-order__pay p {
  margin: 0;
  font-size: var(--site-fs-sm);
}

.site-panel {
  margin-bottom: 20px;
  padding: calc(var(--site-panel-pad) - 2px) var(--site-panel-pad);
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius);
  font-size: var(--site-fs-sm);
}

.site-panel__title {
  margin-bottom: 12px;
  font-size: var(--site-fs-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
}

.site-order__line {
  display: grid;
  grid-template-columns: 1fr 4em 7.4em;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--site-border);
}

.site-order__line-variant {
  margin-left: 8px;
  font-size: var(--site-fs-xs);
  color: var(--site-muted);
}

.site-order__line-qty {
  text-align: center;
  color: var(--site-muted);
}

.site-order__line-price {
  text-align: right;
}

/* 訂單列表 */
.site-orders__row {
  display: grid;
  grid-template-columns: 1fr auto 8em;
  gap: 16px;
  align-items: center;
  padding: 18px 20px;
  background: var(--site-white);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius);
  margin-bottom: 10px;
  transition: border-color 0.2s ease;
}

.site-orders__row:hover {
  border-color: var(--site-rose);
  color: inherit;
}

.site-orders__no {
  font-size: var(--site-fs-xs);
  color: var(--site-muted);
  letter-spacing: 0.06em;
}

.site-orders__name {
  font-size: var(--site-fs-md);
  letter-spacing: 0.04em;
}

.site-orders__meta {
  font-size: var(--site-fs-2xs);
  color: var(--site-muted);
}

.site-orders__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.site-orders__amount {
  text-align: right;
  font-size: var(--site-fs-md);
}

.site-orders__action {
  margin: -4px 0 16px;
  text-align: right;
}

@media (max-width: 900px) {
  .site-cart,
  .site-checkout {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .site-cart__summary,
  .site-checkout__summary {
    position: static;
  }

  .site-cart__line {
    grid-template-columns: 72px 1fr auto;
    grid-template-areas:
      "media info info"
      "media qty price"
      "media remove remove";
    row-gap: 8px;
  }

  .site-cart__media { grid-area: media; width: 72px; }
  .site-cart__info { grid-area: info; }
  .site-cart__qty { grid-area: qty; }
  .site-cart__price { grid-area: price; }
  .site-cart__remove { grid-area: remove; text-align: left; }

  .site-orders__row {
    grid-template-columns: 1fr;
    row-gap: 10px;
  }

  .site-orders__amount {
    text-align: left;
  }
}

/* ---------------------------------------------------------------------------
 * CMS 內容（橫幅、內容頁）
 * ------------------------------------------------------------------------- */

.site-banners,
.site-strips {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/*
 * 橫幅條原本是滿版的一整條；改版後收進與 .site-container 相同的量測寬度，
 * 才能跟其他區塊一樣把四角收圓，而不是橫貫整個視窗的直角色塊。
 */
.site-strips {
  width: calc(100% - var(--site-gutter) * 2);
  max-width: var(--site-max-width);
  margin: 12px auto 0;
}

.site-banner {
  position: relative;
  overflow: hidden;
  border-radius: var(--site-radius);
}

/* a 與 picture 預設是 inline，會在圖片下方留出行高的縫隙 */
.site-banner > a,
.site-banner picture {
  display: block;
}

/*
 * 版位用固定長寬比，不跟著圖片的原始比例走。
 * 這樣容器高度在圖片下載完成前就確定了，不會有版面跳動（CLS）——
 * 橫幅沒有存圖片尺寸，無法輸出 width／height 屬性，只能靠 aspect-ratio。
 * 代價是不符比例的圖會被 object-fit 裁掉邊緣，所以後台的建議尺寸要跟這裡一致。
 */
.site-banner__img {
  width: 100%;
  height: auto;
  display: block;
  aspect-ratio: 8 / 3;
  object-fit: cover;
}

/* 橫幅條是公告用的窄長條，比例與主視覺不同 */
.site-strips .site-banner__img {
  aspect-ratio: 12 / 1;
}

.site-strips .site-banner__caption {
  padding: 12px 20px 10px;
}

.site-strips .site-banner__title {
  font-size: var(--site-fs-lg);
}

.site-strips .site-banner__subtitle {
  font-size: var(--site-fs-xs);
}

.site-banner__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 28px 20px 24px;
  /* 由下往上的漸層，確保文字在任何圖片上都讀得清楚 */
  background: linear-gradient(to top, rgba(42, 39, 36, 0.55), rgba(42, 39, 36, 0));
  color: #fff;
  text-align: center;
}

.site-banner__title {
  font-size: var(--site-fs-3xl);
  font-weight: 500;
  letter-spacing: 0.14em;
  line-height: 1.5;
}

.site-banner__subtitle {
  margin-top: 6px;
  font-size: var(--site-fs-sm);
  letter-spacing: 0.1em;
}

/*
 * 內容頁的 HTML 由後台富文字編輯器產生，標籤組合不可預期，
 * 這裡只給基本的排版節奏，不做細部樣式。
 */
.site-cms {
  font-size: var(--site-fs-md);
  line-height: 1.9;
  color: var(--site-dark);
}

.site-cms h2,
.site-cms h3 {
  margin: 32px 0 12px;
  letter-spacing: 0.08em;
}

.site-cms h2 {
  font-size: var(--site-fs-xl);
}

.site-cms h3 {
  font-size: var(--site-fs-lg);
}

.site-cms p {
  margin: 0 0 16px;
}

.site-cms ul,
.site-cms ol {
  margin: 0 0 16px;
  padding-left: 22px;
}

.site-cms li {
  margin-bottom: 6px;
}

.site-cms a {
  color: var(--site-rose);
  text-decoration: underline;
}

.site-cms img {
  margin: 16px 0;
  border-radius: var(--site-radius);
}

.site-cms table {
  width: 100%;
  margin: 16px 0;
  border-collapse: collapse;
}

.site-cms th,
.site-cms td {
  padding: 8px 12px;
  border: 1px solid var(--site-border);
  text-align: left;
}

.site-cms th {
  background: var(--site-cream2);
  font-weight: 500;
}

.site-cms blockquote {
  margin: 16px 0;
  padding: 8px 0 8px 16px;
  border-left: 2px solid var(--site-rose);
  color: var(--site-muted);
}

@media (max-width: 900px) {
  /*
   * 手機是直式螢幕，主視覺沿用桌機的 8:3 會扁到只剩一條。
   * 斷點必須與 _SiteBanner.cshtml 的 source media 一致：
   * 有上傳手機圖時這裡顯示的是那張圖，沒上傳則是主圖被裁切後的中央區塊。
   */
  .site-banner__img {
    aspect-ratio: 4 / 3;
  }

  .site-strips .site-banner__img {
    aspect-ratio: 6 / 1;
  }

  .site-banner__title {
    font-size: var(--site-fs-xl);
  }

  .site-banner__caption {
    padding: 20px 16px 16px;
  }
}

/* ---------------------------------------------------------------------------
 * 首頁主視覺輪播
 *
 * 標記：Pages/Site/Shared/_SiteHeroSlider.cshtml
 * 行為：SiteAssets/js/hero-slider.js
 *
 * 切換是疊層淡入（不是橫向捲動），因此每張圖能各自跑 Ken Burns 緩推。
 * 第一張的 .is-active 由伺服器輸出，JS 沒載入時仍看得到圖，只是不會自動切換。
 * ------------------------------------------------------------------------- */

.site-hero-slider {
  position: relative;
  overflow: hidden;
  /*
   * 滿版：主視覺是首屏唯一的版位，貼齊視窗左右緣，不收進 .site-container。
   * 它是 <main> 的直接子元素、外層沒有內距，所以 width:100% 就是整個視窗寬。
   */
  width: 100%;
  margin: 0;
  /* 圖片載入完成前的底色，避免首屏出現白塊 */
  background: var(--site-cream2);
  /* 自動播放間隔，由 JS 依 data-interval 覆寫；指示器的進度條共用同一個值 */
  --site-hero-interval: 6000ms;
}

/*
 * 版位高度＝頁首以下的整個可視高度，也就是滿版吃滿首屏。
 * 不用固定長寬比、也不跟著圖片的原始比例走，理由同 .site-banner__img：
 * 容器高度在圖片下載完成前就確定，不會有版面跳動（CLS）。
 * 代價是不符比例的圖會被 object-fit 裁掉邊緣，後台的建議尺寸要跟這裡一致。
 *
 * 用 svh（瀏覽器網址列、工具列都展開時的可視高度）而不是 vh：
 * 100vh 是工具列收起後的高度，用它會讓版位比可視範圍高一截，
 * 圖的底部（與貼在底部的文案）會被工具列蓋掉。
 * 前一行的 vh 是不支援 svh 的舊瀏覽器的退路。
 *
 * max() 的下限給橫拿的窄螢幕用：那時可視高度只剩三、四百，扣完會扁成一條。
 *
 * 扣除值 --site-header-total 是頁首實際佔用的高度（定義在 :root）。
 * ≤900px 的膠囊列高度是寫死的，不吃那個 token，該斷點另外覆寫（見下方）。
 */
.site-hero-slider__stage {
  position: relative;
  height: max(320px, calc(100vh - var(--site-header-total)));
  height: max(320px, calc(100svh - var(--site-header-total)));
}

.site-hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  /* 非當前頁不可點，否則疊在上層的透明圖層會吃掉點擊 */
  pointer-events: none;
  transition: opacity 900ms ease;
}

.site-hero-slide.is-active {
  opacity: 1;
  pointer-events: auto;
  z-index: 2;
}

/* 離場的那張留在下層淡出，新圖才不會被它蓋住 */
.site-hero-slide.is-leaving {
  opacity: 0;
  z-index: 1;
}

.site-hero-slide__link,
.site-hero-slide__media {
  display: block;
  height: 100%;
}

.site-hero-slide__media picture {
  display: block;
  height: 100%;
}

.site-hero-slide__img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  /* 起始就放大一點點，Ken Burns 收回時才不會露出邊緣 */
  transform: scale(1.06);
}

/*
 * Ken Burns：整個停留時間內極慢地推近再回正。
 * 只有 .is-active 跑，切換時 class 被移除再加上，動畫自然從頭開始。
 */
.site-hero-slide.is-active .site-hero-slide__img {
  animation: siteHeroKenBurns 9s ease-out forwards;
}

@keyframes siteHeroKenBurns {
  from {
    transform: scale(1.06) translate3d(1.2%, 0.6%, 0);
  }
  to {
    transform: scale(1) translate3d(0, 0, 0);
  }
}

/* ---------- 文案 ---------- */

.site-hero-slide__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 64px 20px 44px;
  /* 由下往上的漸層，確保文字在任何圖片上都讀得清楚 */
  background: linear-gradient(to top, rgba(42, 39, 36, 0.62), rgba(42, 39, 36, 0));
  color: #fff;
  text-align: center;
  pointer-events: none;
}

.site-hero-slide__title,
.site-hero-slide__subtitle {
  opacity: 0;
  transform: translateY(14px);
}

/*
 * 標題與副標分兩段進場（副標晚 140ms），比整塊一起淡入更有層次。
 * 位移方向跟著切換方向走，往回切時文字從另一側進來。
 *
 * 標題同時要跑常駐的漸層平移（Text Mask Reveal，見下方）。兩者必須寫在同一個 animation 裡——
 * 分成兩條規則的話，權重高的那條會把另一條整個蓋掉。
 */
.site-hero-slide.is-active .site-hero-slide__title {
  animation:
    siteHeroCaptionIn 760ms 220ms ease-out forwards,
    siteHeroGradientPan 9s linear infinite;
}

.site-hero-slide.is-active .site-hero-slide__subtitle {
  animation: siteHeroCaptionIn 760ms 360ms ease-out forwards;
}

@keyframes siteHeroCaptionIn {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.site-hero-slide__title {
  font-size: var(--site-fs-4xl);
  font-weight: 500;
  letter-spacing: 0.18em;
  line-height: 1.6;
}

/* ---------- 標題：Text Mask Reveal（所有寬度共用） ----------
 *
 * 筆畫裡是一條會橫向平移的漸層（取自 taste-patterns-3 的 42 Text Mask Reveal）。
 * 色階全取品牌色票裡偏亮的幾支（cream／sand／gold／sand-soft）：
 * 桌機版壓在深可可卡片上、窄版壓在照片底部的深色漸層上，兩者都是深底，
 * 若照 taste-patterns-3 原樣用到 --site-brand（中深棕），那一段會沉進底色裡，字看起來會斷掉。
 *
 * 兩個選擇器共用同一組設定，因為上色的元素會換：
 * 沒拆字時文字直接掛在標題上；拆字之後改由每一個字（.site-hero-char）各自上色。
 * 理由是 background-clip: text 只在「背景與文字同屬一個元素」時才可靠——
 * 逐字進場需要 perspective 與 transform，被推上獨立合成層的字，
 * 不會再被祖先的文字裁切帶到，標題會整段變成空白。
 *
 * size／pos 由 hero-slider.js 的 alignGradient() 寫入，
 * 讓所有字共用同一條橫跨整段標題的漸層（理由見該函式的註解）。
 * 退路是 260% 的舊寫法，沒拆字時本來就只有一個元素，那樣也對。
 *
 * 不能搭 text-shadow：陰影畫在文字那一層、蓋在被裁切的背景上面，漸層會整片變髒。
 * 窄版需要的陰影改用 filter: drop-shadow，見下方。
 */
.site-hero-slide__title,
.site-hero-char {
  background-image: linear-gradient(
    100deg,
    var(--site-cream) 0%,
    var(--site-sand) 22%,
    var(--site-gold) 44%,
    var(--site-sand-soft) 66%,
    var(--site-cream) 88%
  );
  background-size: var(--site-hero-grad-w, 260%) 100%;
  background-position: var(--site-hero-grad-x, 0px) 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/*
 * 拆字之後標題自己的背景要關掉：它已經沒有自己的文字節點可以裁，
 * 留著的話 Chrome 會在行首留下一小塊沒被裁乾淨的殘影
 * （實機上是首字左上方一個約 3×8px 的亮點）。
 */
.site-hero-slide__title.is-kinetic {
  background-image: none;
}

/*
 * 漸層平移是常駐的、與逐字進場無關，所以每個字各跑同一組 keyframes。
 *
 * 這裡不能給 animation-delay：漸層是整段標題共用的一條，所有字必須同步移動，
 * 色帶才會連續地掃過去。之前給過逐字相位差，那時每個字各有自己的一條漸層，
 * 相鄰兩字差了近 0.7 秒，色帶前緣是一格一格跳過去的。
 *
 * 只有看得到的那一張在跑。background-position 不能交給合成器，
 * 每個字每一格都要主執行緒重新計算、重畫；以前是所有張的字一起跑，
 * 看不到的那幾張也照跑不誤（兩張主視覺時共 31 個無限循環動畫，其中 18 個在隱藏的那張）。
 *
 * .is-leaving 也要列：換頁時 is-active 與 is-leaving 是同一刻交換的，
 * 兩條規則給的 animation 相同，瀏覽器會把它當成同一個動畫繼續跑，
 * 淡出中的舊標題不會因為動畫被拿掉而跳回漸層起點。
 * 反過來，一張重新變成當前頁時動畫從頭開始，起點就是原本的底色位置，所以也不會跳。
 *
 * 主視覺捲出畫面時整段暫停，見下方的 .site-hero-slider.is-offscreen。
 */
.site-hero-slide.is-active .site-hero-char,
.site-hero-slide.is-leaving .site-hero-char {
  animation: siteHeroGradientPan 9s linear infinite;
}

/*
 * 不支援 background-clip: text 時退回實心色（窄版沿用 caption 的白字，桌機版另有規則）。
 * 背景也要一併拿掉——裁不到字的話漸層會鋪滿整個標題框，變成一塊色帶。
 */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .site-hero-slide__title,
  .site-hero-char {
    background-image: none;
    color: inherit;
  }
}

/*
 * 窄版（非分割版）的字直接壓在照片上，原本靠 text-shadow 在亮圖上撐住輪廓。
 * text-shadow 會蓋髒漸層（見上），改成 drop-shadow：它是對整個標題算好的結果取輪廓，
 * 陰影在字的外面，不會疊到筆畫裡。數值沿用原本的 text-shadow。
 * 桌機版有深色卡片墊底，不需要。
 */
@media (max-width: 1023px) {
  .site-hero-slide__title {
    filter: drop-shadow(0 1px 12px rgba(42, 39, 36, 0.35));
  }
}

.site-hero-slide__subtitle {
  margin-top: 10px;
  font-size: var(--site-fs-sm);
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.88);
}

/* ---------- 左右箭頭 ---------- */

.site-hero-slider__arrow {
  position: absolute;
  top: 50%;
  z-index: 3;
  width: var(--site-slider-arrow);
  height: var(--site-slider-arrow);
  margin-top: calc(var(--site-slider-arrow) / -2);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(251, 250, 247, 0.72);
  cursor: pointer;
  opacity: 0;
  transition: opacity 260ms ease, background-color 260ms ease;
}

/* 平時收起，滑鼠移入輪播或鍵盤聚焦時才出現，維持版面乾淨 */
.site-hero-slider:hover .site-hero-slider__arrow,
.site-hero-slider__arrow:focus-visible {
  opacity: 1;
}

.site-hero-slider__arrow:hover {
  background: rgba(251, 250, 247, 0.95);
}

.site-hero-slider__arrow--prev {
  left: 18px;
}

.site-hero-slider__arrow--next {
  right: 18px;
}

/* 細線箭頭：用兩條邊框旋轉 45 度，不必額外載入圖檔 */
.site-hero-slider__chevron {
  display: block;
  width: 10px;
  height: 10px;
  margin: 0 auto;
  border-top: 1.5px solid var(--site-ink);
  border-right: 1.5px solid var(--site-ink);
}

.site-hero-slider__arrow--next .site-hero-slider__chevron {
  transform: translateX(-2px) rotate(45deg);
}

.site-hero-slider__arrow--prev .site-hero-slider__chevron {
  transform: translateX(2px) rotate(-135deg);
}

/* ---------- 指示器 ---------- */

.site-hero-slider__dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 18px;
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: 10px;
}

/* 細線而非圓點：與站上的日系細字調性一致，也才有空間放進度 */
.site-hero-slider__dot {
  position: relative;
  width: 34px;
  height: 14px;
  padding: 6px 0;
  border: 0;
  background: none;
  cursor: pointer;
}

/*
 * 線用深色而不是白色。這批主視覺是接近白的淺色調，
 * 原本的 45% 白疊上去幾乎看不見，使用者不知道現在是第幾張。
 * 深色線在淺色圖上才拉得開；底圖若換成深色主視覺，這兩個值要回頭確認。
 */
.site-hero-slider__dot::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 6px;
  height: 2px;
  background: rgba(36, 24, 20, 0.3);
}

.site-hero-slider__dot-fill {
  position: absolute;
  left: 0;
  top: 6px;
  height: 2px;
  width: 100%;
  background: var(--site-ink);
  /* 未播放時維持 0 寬，只有當前那條會被動畫拉開 */
  transform: scaleX(0);
  transform-origin: left center;
}

/* 已切換過去但尚未開始計時（例如暫停中）時，該條維持全滿 */
.site-hero-slider__dot.is-active .site-hero-slider__dot-fill {
  transform: scaleX(1);
}

/*
 * 自動播放中，當前指示器的填充從左長到右，等於下一張的倒數。
 * 動畫長度綁 --site-hero-interval，JS 會依 data-interval 覆寫它，
 * 兩邊因此不會各說各話。
 */
.site-hero-slider.is-playing .site-hero-slider__dot.is-active .site-hero-slider__dot-fill {
  animation: siteHeroDotFill var(--site-hero-interval) linear forwards;
}

@keyframes siteHeroDotFill {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

@media (max-width: 900px) {
  /*
   * 手機是直式螢幕，主視覺沿用桌機的 8:3 會扁到只剩一條。
   * 斷點必須與 _SiteHeroSliderPicture.cshtml 的 source media 一致。
   *
   * 高度與基準樣式一樣是「可視高度 − 頁首」滿版吃滿首屏，
   * 只是這個斷點的膠囊列高度是寫死的 64px、不吃 --site-header-h，
   * 所以扣除值改用 --site-hero-header-sm（其餘說明見基準樣式）。
   * 原本還會再扣一段讓底下的 SELECTED 眉標露出來，滿版後移除。
   *
   * 版位比原本的 4:3 高很多（滿版後常見手機約 3:5〜4:5），沒上傳手機圖時，
   * 桌機的橫式主圖會被 object-fit 裁到只剩中間一小段。
   */
  .site-hero-slider__stage {
    height: max(320px, calc(100vh - var(--site-hero-header-sm)));
    height: max(320px, calc(100svh - var(--site-hero-header-sm)));
  }

  .site-hero-slide__title {
    font-size: var(--site-hero-title-fs-sm);
  }

  .site-hero-slide__subtitle {
    font-size: var(--site-fs-xs);
  }

  .site-hero-slide__caption {
    padding: 44px 16px 34px;
  }

  /* 手機用滑動切換，箭頭只會擋到圖 */
  .site-hero-slider__arrow {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
 * 主視覺分割版：滿版圖 ＋ 貼齊左下角的深色文案卡
 *
 * 只在 ≥1024px 成立。窄畫面卡片會擠掉大半張圖，
 * 維持原本的「文案壓在底部漸層上」，那一段完全沒有動。
 * 是否採用由 Razor 決定：任何一張有標題或副標時才加上 --split。
 *
 * 版面：
 *   卡片貼齊版位左緣——不跟 .site-container 對齊，任何寬度都在最左邊；
 *   左側與下緣都不收圓角，看起來是從畫面左下角拉出來的一片；
 *   下緣與版位切齊，也就是剛好貼在螢幕最下方；
 *   文字靠右對齊，卡片左側留一段空（--site-hero-panel-pad-start）。
 *
 * 標題：Text Mask Reveal——筆畫裡是一條橫跨整段標題、緩慢平移的品牌色漸層。
 * ------------------------------------------------------------------------- */

@media (min-width: 1024px) {
  /*
   * 版位高度由基準樣式負責（吃滿頁首以下的整個首屏），這裡不再覆寫。
   *
   * 卡片下緣與版位切齊、不再凸出，所以外層維持 hidden（基準樣式就是）：
   * Ken Burns 推近的圖與卡片都不會溢出到下一個區塊。
   * 圖那層自己的 overflow（見下一條）留著不動，兩層各裁各的互不影響。
   *
   * 高度隨視窗變動，版位的可視比例也跟著變，桌機常見約 2.0:1〜2.5:1
   * （1440×900 的瀏覽器可視區約 1440×790 → 1440×688 ≈ 2.09:1；
   *   1920×1080 約 1920×955 → 1920×845 ≈ 2.27:1）。
   * 後台的建議尺寸要照這個範圍給，不再是 8:3。
   */

  /*
   * 圖維持滿版。有連結時外層是 <a>、沒有時是 <span>，兩者都是 .site-hero-slide
   * 的直接子元素，用子選擇器一次涵蓋；巢狀的那層 __media 仍是 100% 填滿。
   * overflow 掛在這裡而不是外層：Ken Burns 會把圖推到 1.06 倍，
   * 要裁掉的是圖，不是凸出去的卡片。
   */
  .site-hero-slider--split .site-hero-slide > .site-hero-slide__link,
  .site-hero-slider--split .site-hero-slide > .site-hero-slide__media {
    position: absolute;
    inset: 0;
    height: auto;
    overflow: hidden;
  }

  /*
   * 外層 __caption 只負責定位，不畫任何東西。
   *
   * left: 0 貼齊版位左緣；right 留 auto，寬度就是 shrink-to-fit（隨卡片內容），
   * 再用 max-width 設上限——標題很長時換行，不會把卡片拉到整個畫面寬。
   * bottom: 0 讓卡片下緣與版位切齊；版位已經吃滿首屏，等於貼在螢幕最下方。
   */
  .site-hero-slider--split .site-hero-slide__caption {
    top: auto;
    right: auto;
    bottom: 0;
    left: 0;
    z-index: 4;
    display: flex;
    width: auto;
    max-width: var(--site-hero-panel-max-w);
    margin: 0;
    padding: 0;
    background: none;
    text-align: right;
  }

  /*
   * 切換時的層次。
   *
   * 文案卡是 slide 的子元素，會跟著整張 slide 一起淡入淡出。
   * 若放著不管，交叉淡入的中段兩張卡各半透明疊在一起，深底只剩約 75% 不透明，
   * 底下的圖會透出來，同時新標題還在進場延遲裡——畫面上是一個「深色空框」。
   *
   * 所以把兩張卡的時間錯開，而且舊卡退得比圖快很多（160ms）：
   * 卡片先乾脆地消失，中間約 0.25 秒只有圖在交叉淡入，
   * 新卡跟標題同一刻起跑（420ms 後），而且淡入的速度跟著文字走——
   * 同一條緩動曲線，最後一個字落定時卡片剛好完全不透明。
   * 任何一刻畫面上都不會出現「有卡片但沒有字」的狀態。
   */
  .site-hero-slider--split .site-hero-slide__caption {
    opacity: 0;
    transition: opacity 160ms ease;
  }

  /*
   * 這裡的 opacity 只用來做「進場／退場」，不要拿它調卡片的透明度：
   * opacity 作用在整個 caption 上，連標題與副標一起變淡，
   * 設成 0.2 的話字也只剩兩成，怎麼調對比都沒用。
   * 要讓卡片透，改 --site-hero-panel-bg 的 alpha（只影響底，不影響字）。
   *
   * 進場用 animation 而不是 transition：
   *   - 首次載入時第一張的 .is-active 是伺服器直接輸出的，transition 不會在首次繪製觸發，
   *     卡片會直接出現、不等文字；animation 首次繪製就會跑。
   *   - transition 在疊層順序上高於 animation，這裡一定要 transition: none，
   *     否則「變成當前頁」那一刻的 0→1 會被 transition 接走，animation 的時間軸就沒作用了。
   *     退場時 .is-active 被拿掉，套回上一條的 160ms transition，淡出不受影響。
   *
   * 三個時間值由 hero-slider.js 的 syncCardTiming() 依逐字進場的參數與字數逐張寫入；
   * 預設值對應 GSAP 沒載入時標題的 siteHeroCaptionIn（760ms、延遲 420ms、ease-out）。
   */
  .site-hero-slider--split .site-hero-slide.is-active .site-hero-slide__caption {
    opacity: 1;
    transition: none;
    animation: siteHeroCardIn
      var(--site-hero-card-dur, 760ms)
      var(--site-hero-card-ease, ease-out)
      var(--site-hero-card-delay, 420ms)
      both;
  }

  /* 副標的淡入延後到卡片出現之後，不然位移會發生在卡片還看不見的時候 */
  .site-hero-slider--split .site-hero-slide.is-active .site-hero-slide__subtitle {
    animation-delay: 540ms;
  }

  /*
   * 卡片本體：毛玻璃而不是實色板。
   *
   * backdrop-filter 把卡片後面那塊圖糊掉，卡片因此仍看得出底圖的顏色與明暗走向，
   * 但沒有細節可以跟標題搶。標題是淺色系的漸層，卡片底必須夠深才拉得開對比。
   *
   * 卡片貼著畫面左緣與下緣，所以左側兩個角與右下角都不收圓、也不畫左邊框與下邊框——
   * 收了圓角會在畫面邊緣露出缺口，看起來像是卡片被放歪了。
   * 只剩右上角收圓，形狀才看得出是從左下角拉出來的一片。
   * 右側與上方那一圈很淡的亮邊把卡片與底圖分開，沒有它毛玻璃在淺色圖上會找不到邊界。
   */
  .site-hero-slider--split .site-hero-slide__caption-inner {
    width: var(--site-hero-panel-w);
    padding: var(--site-hero-panel-pad);
    padding-left: var(--site-hero-panel-pad-start);
    background: var(--site-hero-panel-bg);
    -webkit-backdrop-filter: blur(var(--site-hero-panel-blur)) saturate(1.1);
    backdrop-filter: blur(var(--site-hero-panel-blur)) saturate(1.1);
    border: 1px solid var(--site-hero-panel-border);
    border-left: 0;
    border-bottom: 0;
    border-radius: 0 var(--site-radius-lg) 0 0;
    box-shadow: var(--site-shadow-lg);
  }

  /*
   * 不支援 backdrop-filter 時（少數舊版 Firefox）沒有模糊可用，
   * 底圖的細節會直接透上來把字吃掉，所以把底加深成接近實色。
   */
  @supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    .site-hero-slider--split .site-hero-slide__caption-inner {
      background: var(--site-hero-panel-solid);
    }
  }

  /* ---------- 標題 ----------
   *
   * 漸層（Text Mask Reveal）本身是所有寬度共用的，定義在 .site-hero-slide__title 那一段；
   * 這裡只調分割版的字級與字距。
   *
   * 字級另開 token 不共用 --site-fs-4xl：筆畫要夠粗，裡面的漸層才看得出來。
   * .site-hero-char 也要寫：拆字後每個字各自上色，字級要跟標題一致。
   */
  .site-hero-slider--split .site-hero-slide__title,
  .site-hero-slider--split .site-hero-char {
    font-size: var(--site-hero-title-fs);
    letter-spacing: 0.04em;
    line-height: 1.24;
  }

  /*
   * 沒拆字（GSAP 沒載入）時，標題要同時跑兩個動畫：進場的淡入，以及常駐的漸層平移。
   * 兩者必須寫在同一個 animation 裡——分成兩條規則的話，
   * 權重高的那條會把另一條整個蓋掉，不是標題停在全透明，就是漸層不動。
   */
  .site-hero-slider--split .site-hero-slide.is-active .site-hero-slide__title {
    animation:
      siteHeroCaptionIn 760ms 420ms ease-out forwards,
      siteHeroGradientPan 9s linear infinite;
  }

  /*
   * 不支援 background-clip: text 時，分割版的實心色用沙色（窄版是白字，見共用那段）。
   * 動畫不能關：淡入是標題唯一的進場，關掉的話標題會停在全透明。
   */
  @supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .site-hero-slider--split .site-hero-slide__title,
    .site-hero-slider--split .site-hero-char {
      background-image: none;
      color: var(--site-sand);
    }
  }

  /* ---------- Kinetic-Type：標題逐字翻上來 ----------
   *
   * hero-slider.js 用 GSAP SplitText 把標題拆成一個字一個元素（.site-hero-char），
   * 再逐字補間。中文每個字都是獨立字元，拆起來比英文單字乾淨。
   *
   * 拆字之後標題整段的淡入要交出去，不然 CSS 的淡入與 GSAP 的補間會互相蓋。
   * 這個 class 由 JS 在真的拆成功之後才加，GSAP 沒載入時什麼都不會變。
   * （標題自己的背景也要關掉，那條是所有寬度共用的，見 .site-hero-slide__title.is-kinetic。）
   */
  .site-hero-slider--split .site-hero-slide__title.is-kinetic,
  .site-hero-slider--split .site-hero-slide.is-active .site-hero-slide__title.is-kinetic {
    opacity: 1;
    transform: none;
    animation: none;
  }

  /*
   * rotateX 需要透視才看得出是「翻」而不是「壓扁」，
   * 透視掛在父層才會共用同一個消失點。
   */
  .site-hero-slider--split .site-hero-slide__title.is-kinetic {
    perspective: 600px;
  }

  /*
   * 每個字要能各自位移與翻轉，就必須是 inline-block（inline 元素吃不到 transform）。
   * 每個字的漸層平移是所有寬度共用的，見 .site-hero-char 那一條。
   */
  .site-hero-slider--split .site-hero-char {
    display: inline-block;
  }

  .site-hero-slider--split .site-hero-slide__subtitle {
    margin-top: 16px;
    font-size: var(--site-fs-xs);
    line-height: 1.9;
    letter-spacing: 0.14em;
    color: var(--site-hero-subtitle-color);
  }

  /*
   * 左下角讓給文案卡，指示器移到量測線的右端，
   * 兩者一左一右不會互相擋到。箭頭是上下置中的，不受影響。
   */
  .site-hero-slider--split .site-hero-slider__dots {
    left: 0;
    right: 0;
    width: auto;
    max-width: var(--site-max-width);
    margin: 0 auto;
    padding: 0 var(--site-gutter);
    justify-content: flex-end;
  }
}

/*
 * 平移的距離剛好是一個 background-size，頭尾才接得上（背景預設是 repeat）。
 * 起點也要寫出來：每個字的起始位移不同，只寫 to 的話會從 0 開始跑，
 * 共用漸層的對位就毀了。
 */
@keyframes siteHeroGradientPan {
  from {
    background-position: var(--site-hero-grad-x, 0px) 0;
  }
  to {
    background-position: calc(var(--site-hero-grad-x, 0px) + var(--site-hero-grad-w, 260%)) 0;
  }
}

/* 分割版文案卡的進場（見 .site-hero-slide.is-active .site-hero-slide__caption） */
@keyframes siteHeroCardIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/*
 * 主視覺捲出畫面時，標題的漸層平移暫停（is-offscreen 由 hero-slider.js 以 IntersectionObserver 切換）。
 * 無限循環的 background-position 動畫在畫面外仍是 running，照樣每一格佔用主執行緒。
 *
 * 權重要高過套上動畫的那幾條：animation 簡寫會把 play-state 重設回 running。
 *   逐字：.site-hero-slide.is-active .site-hero-char（0,3,0），這裡是 0,4,0。
 *   沒拆字的標題：分割版那條是 0,4,0，同權重靠順序，所以這段必須排在分割版的 media query 之後。
 * 標題的進場淡入跟漸層寫在同一個 animation 裡，會一起暫停；那時標題本來就不在畫面上，看不出差別。
 */
.site-hero-slider.is-offscreen .site-hero-slide .site-hero-char,
.site-hero-slider.is-offscreen .site-hero-slide .site-hero-slide__title {
  animation-play-state: paused;
}

/*
 * 使用者要求減少動態：常駐跑動的漸層停掉。
 * 權重要跟上面那兩條「淡入＋平移」（窄版一條、分割版一條）一樣高，不然蓋不過去；
 * 淡入也一起停，標題直接以最終狀態出現（JS 端也不會做逐字進場）。
 * 逐字的漸層只掛在當前頁與離場中的那一張（0,3,0），那兩條也要列進來。
 */
@media (prefers-reduced-motion: reduce) {
  .site-hero-slide.is-active .site-hero-slide__title,
  .site-hero-char,
  .site-hero-slide.is-active .site-hero-char,
  .site-hero-slide.is-leaving .site-hero-char,
  .site-hero-slider--split .site-hero-slide.is-active .site-hero-slide__title,
  .site-hero-slider--split .site-hero-char {
    opacity: 1;
    transform: none;
    animation: none;
  }

  /* 文案卡跟著標題直接出現，不等淡入 */
  .site-hero-slider--split .site-hero-slide.is-active .site-hero-slide__caption {
    animation: none;
  }
}

/*
 * 使用者要求減少動態：關掉 Ken Burns 與進度條，切換改為極短的淡入。
 * JS 端同樣會停掉自動播放，兩邊要一起維持。
 */
@media (prefers-reduced-motion: reduce) {
  /* 購物車快速預覽直接出現，不做位移 */
  .site-minicart {
    transform: none;
    transition-duration: 1ms;
  }

  .site-minicart.is-open {
    transform: none;
  }

  .site-hero-slide {
    transition-duration: 1ms;
  }

  .site-hero-slide__img,
  .site-hero-slide.is-active .site-hero-slide__img {
    animation: none;
    transform: none;
  }

  .site-hero-slide__title,
  .site-hero-slide__subtitle {
    opacity: 1;
    transform: none;
    animation: none;
  }

  .site-hero-slider.is-playing .site-hero-slider__dot.is-active .site-hero-slider__dot-fill {
    animation: none;
  }
}

/* ---------------------------------------------------------------------------
 * 會員中心
 * ------------------------------------------------------------------------- */

.site-check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0 18px;
  font-size: var(--site-fs-sm);
  cursor: pointer;
}

.site-address {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--site-border);
}

.site-address__head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--site-fs-md);
}

.site-address__line {
  margin-top: 4px;
  font-size: var(--site-fs-xs);
  color: var(--site-muted);
}

.site-address__actions {
  display: flex;
  gap: 14px;
  flex-shrink: 0;
}

/* 地址編輯的簡易對話框，前台沒有引入 UI 框架，用固定定位自行實作 */
.site-modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(42, 39, 36, 0.45);
  overflow-y: auto;
}

.site-modal__panel {
  width: 100%;
  max-width: var(--site-modal-w);
  max-height: 90vh;
  overflow-y: auto;
  padding: 24px;
  background: var(--site-white);
  border-radius: var(--site-radius);
}

.site-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}

@media (max-width: 600px) {
  .site-address {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
}

/* ---------------------------------------------------------------------------
 * 捲動進場（全站）
 *
 * 取自 /taste-demo-c：捲到才浮上來、同一批進場的依序錯開。
 * 哪些元素會套用、何時觸發，都在 site.js 的 initReveal；這裡只有兩個狀態。
 *
 * 與 taste-demo-c 刻意不同的地方：
 *   - 不做 blur。filter 動畫每一格都要重新點陣化再模糊，商品格線一次進場七、八張卡，
 *     桌機大尺寸時是整頁最貴的一項（taste-demo-c.js 的註解也這麼寫）。只留 opacity 與位移，
 *     兩者都能交給合成器跑，不佔主執行緒。
 *   - 位移用 translate 屬性而不是 transform：.site-card 的 hover 已經用 transform 往上浮，
 *     兩者是獨立屬性、會疊加，進場期間 hover 不會被蓋掉。
 *   - 用 animation 而不是 transition：各元件自己的 transition（卡片的 hover）不必改寫。
 *     動畫跑完 JS 會把兩個 class 都拿掉，元素回到原本的樣式，不會一直掛著合成層。
 *
 * .site-reveal 只會加在「初始化當下還在首屏以下」的元素上（見 initReveal），
 * 首屏內容一律不藏：藏了會先閃一下再進場，也會拖慢 LCP。
 * ------------------------------------------------------------------------- */

.site-reveal {
  opacity: 0;
  translate: 0 var(--site-reveal-y);
}

.site-reveal.is-revealing {
  animation: siteRevealIn 0.85s var(--site-ease-reveal) both;
}

@keyframes siteRevealIn {
  from {
    opacity: 0;
    translate: 0 var(--site-reveal-y);
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* 列印時還沒捲到的元素也要印出來 */
@media print {
  .site-reveal {
    opacity: 1;
    translate: none;
    animation: none;
  }
}

/* ---------------------------------------------------------------------------
 * 換頁轉場（跨文件 View Transitions）
 *
 * 前台是 Razor Pages 的多頁式站台，換頁仍是完整的伺服器導覽 ——
 * 每個網址回的還是同一份 HTML，爬蟲拿到的內容沒有任何改變，因此不影響 SEO。
 * 這裡只是請瀏覽器在同源換頁時補一段轉場動畫，不支援的瀏覽器就是原本的瞬間換頁。
 *
 * 跨文件轉場要求「前後兩份文件都有 @view-transition」才會啟動，
 * 而本檔案只被前台 Layout 載入，所以從前台點進後台 SPA（/app、/login）不會觸發轉場。
 * ------------------------------------------------------------------------- */

@view-transition {
  navigation: auto;
}

/*
 * 頁首與頁尾在每一頁都是同一份內容，命名後會從 root 快照中獨立出來，
 * 中間內容淡入時它們維持原樣。
 */
.site-header {
  view-transition-name: site-header;
}

.site-footer {
  view-transition-name: site-footer;
}

/*
 * 這兩塊不需要任何補間：
 * group 若做位置補間，頁尾會因為兩頁長度不同而從舊高度滑到新高度；
 * 舊快照若淡出，同一份頁尾會在兩個高度上交叉淡入，看起來像重影。
 * 所以停掉 group 動畫、直接移除舊快照，新的就位即可。
 */
::view-transition-group(site-header),
::view-transition-group(site-footer) {
  animation: none;
}

::view-transition-old(site-header),
::view-transition-old(site-footer) {
  display: none;
}

::view-transition-new(site-header),
::view-transition-new(site-footer) {
  animation: none;
}

/*
 * 其餘內容（root 快照，頁首與頁尾已被抽離）走淡入淡出並帶一點位移。
 * 自訂動畫要把 mix-blend-mode 收回 normal：預設的 plus-lighter 是為了
 * 兩張快照對等交叉淡入而設，這裡舊的先走、新的後到，沿用會在銜接處泛白。
 * 新頁面延遲到舊頁面幾乎淡完才進場，兩份內容重疊的時間短到看不出來。
 */
::view-transition-old(root) {
  animation: site-page-out 0.1s ease both;
  mix-blend-mode: normal;
}

::view-transition-new(root) {
  animation: site-page-in 0.16s 0.08s ease both;
  mix-blend-mode: normal;
}

@keyframes site-page-out {
  to {
    opacity: 0;
    transform: translateY(-6px);
  }
}

@keyframes site-page-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

/* 使用者要求減少動態：換頁照常，但轉場短到看不出來（位移也就跟著看不見） */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 1ms;
    animation-delay: 0s;
  }
}
