/* 慶旺清潔 —— 設計系統
   來源：kingown-design（慶旺興業品牌規範）。色彩取自制服印製色票
   PANTONE 2228 U #12B6CB（主）與 PANTONE 2008 U #F7C376（輔），
   標準字灰 #7C7D7D 展開為中性階。字體為源泉圓體 GenSenMaruGothicTW。

   本檔是全站樣式的唯一來源。各頁 inline style 大量引用下方的 CSS 變數，
   因此變數名沿用舊有命名（--color-accent-* 等），只把值換成品牌色，
   改這裡即可整站換色。 */

/* ── 字體 ───────────────────────────────────────────────────────────
   子集化的 woff2 由 tools/build-fonts.sh 產生（原始 TTF 每個 14MB）。
   子集只含站內出現過的字，改文案後請重跑該腳本。 */
@font-face{font-family:"GenSenMaruGothicTW";font-style:normal;font-weight:400;font-display:swap;
  src:url("assets/fonts/GenSenMaruGothicTW-Regular.woff2") format("woff2")}
@font-face{font-family:"GenSenMaruGothicTW";font-style:normal;font-weight:500;font-display:swap;
  src:url("assets/fonts/GenSenMaruGothicTW-Medium.woff2") format("woff2")}
@font-face{font-family:"GenSenMaruGothicTW";font-style:normal;font-weight:700;font-display:swap;
  src:url("assets/fonts/GenSenMaruGothicTW-Bold.woff2") format("woff2")}
@font-face{font-family:"GenSenMaruGothicTW";font-style:normal;font-weight:900;font-display:swap;
  src:url("assets/fonts/GenSenMaruGothicTW-Heavy.woff2") format("woff2")}

:root {
  --color-bg: #ffffff;
  --color-surface: #f4f5f5;       /* 沉陷面：分區底色、卡片底 */
  --color-text: #1e1f1f;
  --color-accent: #12b6cb;        /* PANTONE 2228 U */
  --color-accent-2: #f7c376;      /* PANTONE 2008 U —— 全站唯一的強調色，一個畫面最多一處 */
  --color-divider: #e9eaea;
  --color-foot: #383f33;          /* 頁尾底色，深橄欖 */

  /* 中性階 —— 以標準字灰 #7C7D7D 為 500 展開 */
  --color-neutral-25: #fafbfb;
  --color-neutral-50: #f4f5f5;
  --color-neutral-100: #e9eaea;
  --color-neutral-200: #d6d7d7;
  --color-neutral-300: #bcbdbd;
  --color-neutral-400: #9c9d9d;
  --color-neutral-500: #7c7d7d;
  --color-neutral-600: #626363;
  --color-neutral-700: #4a4b4b;
  --color-neutral-800: #333434;
  --color-neutral-900: #1e1f1f;

  /* 主色階 —— 青 */
  --color-accent-50:  #e7f8fa;
  --color-accent-100: #e7f8fa;
  --color-accent-200: #c4eff4;
  --color-accent-300: #8ee0ea;
  --color-accent-400: #52cedd;
  --color-accent-500: #12b6cb;
  --color-accent-600: #0e96a8;
  --color-accent-700: #0b7685;
  --color-accent-800: #095b66;
  --color-accent-900: #06424a;

  /* 輔色階 —— 沙 */
  --color-accent-2-100: #fef7eb;
  --color-accent-2-200: #fdecd1;
  --color-accent-2-300: #fbdca9;
  --color-accent-2-400: #f9ce8b;
  --color-accent-2-500: #f7c376;
  --color-accent-2-600: #de9528;
  --color-accent-2-700: #b4761d;
  --color-accent-2-800: #8a5a16;
  --color-accent-2-900: #5e3d0f;

  /* 狀態色 —— 刻意壓抑，不與品牌青搶眼 */
  --color-danger-100: #fbddd8;
  --color-danger-500: #e04e3c;
  --color-danger-700: #a33325;
  --color-success-100: #d6f2e5;
  --color-success-500: #1fa971;
  --color-success-700: #14724d;

  --font-body: "GenSenMaruGothicTW", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif;
  --font-heading: var(--font-body);
  --font-heading-weight: 700;

  /* 中文需要字距才透氣；純英數串用 0 */
  --tracking-cjk: 0.04em;
  --tracking-cjk-tight: 0.02em;
  --tracking-caps: 0.12em;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;

  /* 標誌是四塊磚，每塊被切掉一個特大四分圓；圓角因此走得寬 */
  --radius-sm: 6px;
  --radius-md: 10px;   /* 控件 */
  --radius-lg: 20px;   /* 卡片 */
  --radius-xl: 28px;   /* 大面板 */
  --radius-pill: 999px;
  --radius-tile-cut: 70px;  /* 那個特大四分圓，一個畫面用一到兩次 */

  /* 陰影一律低對比、純中性、無彩色偏移 */
  --shadow-sm: 0 1px 2px rgba(30, 31, 31, .06);
  --shadow-md: 0 6px 16px -4px rgba(30, 31, 31, .10);
  --shadow-lg: 0 14px 32px -8px rgba(30, 31, 31, .14);
  --shadow-brand: 0 8px 20px -6px rgba(18, 182, 203, .45);  /* 唯一的彩色陰影：主按鈕 hover */
  --ring-brand: 0 0 0 3px rgba(18, 182, 203, .28);
  --ring-danger: 0 0 0 3px rgba(224, 78, 60, .26);

  /* 主要動作色 —— 刻意偏離供稿規範，請見下方說明。
     kingown-design 的 Button 規格是 --action-primary: cyan-500 (#12B6CB) 配白字，
     但白字對 #12B6CB 的對比只有 2.45:1，遠低於 WCAG AA 對 14px 粗體所要求的 4.5:1。
     這裡改用 cyan-700 (#0B7685)，對比 5.36:1，通過 AA，色相仍在品牌青系內。
     若要回到規範原色，把下面三行換成 -500 / -600 / -700 即可（會失去 AA 合規）。 */
  --action-primary: var(--color-accent-700);
  --action-primary-hover: var(--color-accent-800);
  --action-primary-active: var(--color-accent-900);

  /* 黏著元素的上緣位移。頁首捲動後約 61px 高，留一點空隙。
     試算面板、篩選欄、金額摘要都用這個值，改一次全站一致。 */
  --sticky-top: 76px;

  /* 動態：短、單向、無彈跳 */
  --ease-out: cubic-bezier(.22, .61, .36, 1);
  --dur-fast: 140ms;
  --dur-base: 200ms;
}

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

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-neutral-700);
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.65;
  letter-spacing: var(--tracking-cjk);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  line-height: 1.2;
  letter-spacing: var(--tracking-cjk-tight);
  margin: 0 0 var(--space-2);
  text-wrap: balance;
}
h1 { font-size: 44px; }
h2 { font-size: 30px; }
h3 { font-size: 24px; }
h4 { font-size: 18px; }
h5 { font-size: 16px; }
h6 { font-size: 13px; letter-spacing: var(--tracking-caps); text-transform: uppercase; }

p { margin: 0 0 var(--space-3); }
a { color: var(--color-accent-700); text-decoration: none; text-underline-offset: 3px;
    transition: color var(--dur-fast) var(--ease-out); }
a:hover { color: var(--color-accent-800); text-decoration: underline; }
img { display: block; max-width: 100%; }
figure { margin: 0; }
figcaption { font-size: 12px; margin-top: var(--space-1); color: var(--color-neutral-500); }
.text-muted { color: var(--color-neutral-500); }
:focus { outline: none; }
:focus-visible { outline: none; box-shadow: var(--ring-brand); border-radius: var(--radius-sm); }
::selection { background: var(--color-accent-200); color: var(--color-accent-900); }

/* 品牌造型母題：磚塊被切掉一個特大四分圓 */
.tile-cut-br { border-bottom-right-radius: var(--radius-tile-cut); }
.tile-cut-tr { border-top-right-radius: var(--radius-tile-cut); }

/* — 分隔線 — */
.hr { height: 1px; border: 0; margin: var(--space-4) 0; background: var(--color-divider); }

/* — 圖框 —
   品牌不做濾鏡、不加顆粒、不用網點：照片就是照片，只給圓角與底色。 */
.fig {
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--color-neutral-100);
}

/* — 數據 —
   取代原本的 CMYK 分色數字；重量由字重與青色承擔，不靠印刷特效。 */
.stat-num {
  font-family: var(--font-heading);
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: 0;
  color: var(--color-accent-700);
}

/* — 圖示 —
   規範明訂不用 emoji、也不用 unicode 符號（✓ ★ ✕）當圖示。這裡以 CSS mask
   內嵌 Lucide 圖形（2px 圓端圓角描邊，與圓體的圓收筆同調），因此會繼承
   currentColor，尺寸跟著字級走。 */
.icon {
  display: inline-block; width: 1em; height: 1em; flex: none;
  vertical-align: -0.13em; background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}
.i-check {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6 9 17l-5-5'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6 9 17l-5-5'/></svg>");
}
.i-star {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 2.6l2.9 5.9 6.5.9-4.7 4.6 1.1 6.4-5.8-3-5.8 3 1.1-6.4L2.6 9.4l6.5-.9z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 2.6l2.9 5.9 6.5.9-4.7 4.6 1.1 6.4-5.8-3-5.8 3 1.1-6.4L2.6 9.4l6.5-.9z'/></svg>");
}
.i-bell {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10.3 21a2 2 0 0 0 3.4 0'/><path d='M3.3 15.3A1 1 0 0 0 4 17h16a1 1 0 0 0 .7-1.7C19.4 14 18 12.5 18 8A6 6 0 0 0 6 8c0 4.5-1.4 6-2.7 7.3'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10.3 21a2 2 0 0 0 3.4 0'/><path d='M3.3 15.3A1 1 0 0 0 4 17h16a1 1 0 0 0 .7-1.7C19.4 14 18 12.5 18 8A6 6 0 0 0 6 8c0 4.5-1.4 6-2.7 7.3'/></svg>");
}
/* 未讀圓點 */
.unread {
  display: inline-block; width: 8px; height: 8px; flex: none;
  border-radius: 50%; background: var(--color-accent-2-600); margin-right: 10px;
  vertical-align: 0.1em;
}

/* — 按鈕 —
   Hover 加深一階，主按鈕亮起品牌陰影；Press 下移 1px 再深一階。
   永不縮放：scale 與圓體的柔和收筆相衝。 */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: 700;
  font-size: 14px; line-height: 1.2; letter-spacing: var(--tracking-cjk-tight);
  color: var(--color-neutral-800);
  background: transparent; border: 1.5px solid transparent;
  padding: 11px 20px; min-height: 44px;
  border-radius: var(--radius-md);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn svg { display: block; }
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--color-neutral-100); color: var(--color-neutral-400);
  border-color: transparent; cursor: not-allowed; transform: none; box-shadow: none;
}
.btn-primary { background: var(--action-primary); color: #fff; border-color: var(--action-primary); }
.btn-primary:hover { background: var(--action-primary-hover); border-color: var(--action-primary-hover);
                     color: #fff; box-shadow: var(--shadow-brand); }
.btn-primary:active { background: var(--action-primary-active); border-color: var(--action-primary-active); box-shadow: none; }
/* 次要按鈕依規範是青色髮絲外框，不是中性灰框 */
.btn-secondary { background: #fff; color: var(--color-accent-700); border-color: var(--color-accent-500); }
.btn-secondary:hover { background: var(--color-accent-100); color: var(--color-accent-800); border-color: var(--color-accent-500); }
.btn-secondary:active { background: var(--color-accent-200); }
.btn-ghost { color: var(--color-accent-700); padding-inline: var(--space-3); }
.btn-ghost:hover { background: var(--color-neutral-50); color: var(--color-accent-800); }
.btn-ghost:active { background: var(--color-neutral-100); }
.btn-icon { width: 44px; height: 44px; padding: 0; }
.btn-block { width: 100%; margin-top: var(--space-2); }

/* — 表單 — */
.field > label {
  display: block; font-size: 14px; font-weight: 500; margin-bottom: 6px;
  color: var(--color-neutral-800);
}
.input {
  width: 100%; min-height: 44px; padding: 10px 14px; font: inherit;
  font-size: 15px; letter-spacing: var(--tracking-cjk);
  color: var(--color-neutral-900); caret-color: var(--color-accent-500);
  background: #fff;
  border: 1.5px solid var(--color-neutral-200); border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.input::placeholder { color: var(--color-neutral-400); }
.input:hover { border-color: var(--color-neutral-300); }
.input:focus-visible { border-color: var(--color-accent-500); box-shadow: var(--ring-brand); }
.input[aria-invalid="true"] { border-color: var(--color-danger-500); }
.input[aria-invalid="true"]:focus-visible { box-shadow: var(--ring-danger); }
textarea.input { min-height: 110px; resize: vertical; line-height: 1.65; }
select.input { appearance: none; padding-right: 40px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--color-neutral-500) 50%),
                    linear-gradient(135deg, var(--color-neutral-500) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; }

.radio { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 15px; }
.radio input, .seg-opt input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.radio .dot {
  width: 20px; height: 20px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-neutral-300);
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.radio:hover .dot { border-color: var(--color-accent-500); }
.radio input:checked + .dot {
  border-color: var(--color-accent-500); background: var(--color-accent-500);
  box-shadow: inset 0 0 0 5px #fff;
}
.radio input:focus-visible + .dot { box-shadow: var(--ring-brand); }

/* 分段控制項 */
.seg {
  display: inline-flex; overflow: hidden;
  border: 1.5px solid var(--color-neutral-200); border-radius: var(--radius-md);
  background: #fff;
}
.seg-opt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 16px; font-size: 14px; font-weight: 500; cursor: pointer;
  color: var(--color-neutral-700);
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.seg-opt + .seg-opt { border-left: 1.5px solid var(--color-neutral-200); }
.seg-opt:has(input:checked) { background: var(--action-primary); color: #fff; }
.seg-opt:not(:has(input:checked)):hover { background: var(--color-neutral-50); }
.seg-opt:has(input:focus-visible) { box-shadow: inset var(--ring-brand); }

/* — 卡片 — */
.card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-6); border-radius: var(--radius-lg);
  background: #fff; border: 1px solid var(--color-divider);
}
.card-kicker {
  font-size: 12px; font-weight: 500; letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-accent-700);
}
.card-title {
  font-family: var(--font-heading); font-weight: 700;
  font-size: 18px; line-height: 1.3; letter-spacing: var(--tracking-cjk-tight);
  color: var(--color-text);
}
.card-body { margin: 0; font-size: 14px; color: var(--color-neutral-600); flex: 1; }
.card-meta { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--color-neutral-500); }
.elev-sm { box-shadow: var(--shadow-sm); }
.elev-md { box-shadow: var(--shadow-md); }
.elev-lg { box-shadow: var(--shadow-lg); }

/* — 標籤 — */
.tag {
  display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 500;
  letter-spacing: var(--tracking-cjk-tight); padding: 4px 12px;
  border-radius: var(--radius-pill);
}
.tag-accent { background: var(--color-accent-100); color: var(--color-accent-800); }
.tag-accent-2 { background: var(--color-accent-2-200); color: var(--color-accent-2-900); }
.tag-neutral { background: var(--color-neutral-100); color: var(--color-neutral-700); }
.tag-outline { border: 1.5px solid var(--color-accent-500); color: var(--color-accent-700); }
.tag-danger { background: var(--color-danger-100); color: var(--color-danger-700); }
.tag-success { background: var(--color-success-100); color: var(--color-success-700); }

/* — 導覽 —
   黏性頁首是全站唯一的黏性元素，白色 88% + blur(14px)。
   各頁 nav 帶著 inline 的 max-width:1160px，這裡用 padding 把內容列置中，
   讓底色能滿版出血；因此需要 !important 蓋掉那個 inline 寬度。 */
.nav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  position: sticky; top: 0; z-index: 40;
  max-width: none !important;
  padding-inline: max(var(--space-6), calc((100% - 1160px) / 2));
  background: rgba(255, 255, 255, .88);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--color-divider);
}
.nav-brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-heading); font-weight: 700;
  font-size: 20px; letter-spacing: var(--tracking-cjk-tight);
  color: var(--color-text); margin-right: auto;
}
/* 橫式標誌最小使用高度 28px；34px 讓副標的 KING OWN Ltd. 還讀得出來 */
.nav-brand img { height: 34px; width: auto; }
.nav-brand:hover { text-decoration: none; color: var(--color-text); }
.nav a { color: var(--color-neutral-700); text-decoration: none; font-size: 15px; font-weight: 500; }
.nav a:hover { color: var(--color-accent-700); text-decoration: none; }
.nav a[aria-current='page'] { color: var(--color-accent-700); }
.nav .btn-primary, .nav .btn-secondary, .nav .btn-ghost { color: unset; }
.nav .btn-primary { color: #fff; }

/* — 表格 — */
.table { width: 100%; border-collapse: collapse; font-size: 15px; }
.table th {
  text-align: left; font-size: 12px; font-weight: 500;
  letter-spacing: var(--tracking-caps); text-transform: uppercase;
  color: var(--color-neutral-500);
  padding: var(--space-3) var(--space-2); border-bottom: 1px solid var(--color-neutral-200);
}
.table td { padding: var(--space-3) var(--space-2); border-bottom: 1px solid var(--color-divider); }
.table tbody tr { transition: background-color var(--dur-fast) var(--ease-out); }
.table tbody tr:hover { background: var(--color-neutral-25); }

/* — 對話框 — */
.dialog-backdrop {
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4);
  background: rgba(30, 31, 31, .55);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.dialog {
  width: min(480px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-8); border-radius: var(--radius-xl);
  background: #fff; box-shadow: var(--shadow-lg);
}
.dialog-title {
  font-family: var(--font-heading); font-weight: 700; font-size: 24px;
  letter-spacing: var(--tracking-cjk-tight); color: var(--color-text);
}
.dialog-body { font-size: 15px; color: var(--color-neutral-600); }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }

/* ══════════════════════════════════════════════════════════════════════
   平台擴充 —— king-own-platform
   site1 是單一服務商官網，靠 inline style 排版就夠。這裡是多廠商市集，
   服務卡、分類磚、價格標這些單元會被 js/render.js 大量重複產生，
   所以改成正式的 class，樣式只在這裡定義一次。
   ══════════════════════════════════════════════════════════════════════ */

/* — 版面骨架 — */
.wrap { max-width: 1160px; margin: 0 auto; padding-inline: var(--space-6); }
.wrap-text { max-width: 760px; }
.sec { padding-block: 72px; }
.sec-sunken { background: var(--color-neutral-50); }
.sec-head { display: flex; align-items: flex-end; justify-content: space-between;
            gap: var(--space-6); margin-bottom: var(--space-8); }
.sec-head h2 { margin: 0; }
.sec-kicker { font-size: 12px; font-weight: 500; letter-spacing: var(--tracking-caps);
              text-transform: uppercase; color: var(--color-accent-700); margin-bottom: 6px; }
.sec-sub { margin: var(--space-2) 0 0; font-size: 15px; color: var(--color-neutral-600); }

.grid { display: grid; gap: var(--space-4); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-5 { grid-template-columns: repeat(5, 1fr); }

/* — 麵包屑 — */
.crumb { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
         font-size: 13px; color: var(--color-neutral-500); padding-block: var(--space-4); }
.crumb a { color: var(--color-neutral-600); font-weight: 400; }
.crumb .sep { color: var(--color-neutral-300); }

/* — 分類磚 —
   標誌的四塊磚母題：hover 時右下角展開那個特大四分圓。整站的切角就用在這裡，
   所以其他區塊不再重複使用，避免變成裝飾。 */
.cat-tile {
  display: flex; flex-direction: column; gap: 10px; align-items: flex-start;
  padding: var(--space-6) var(--space-4); min-height: 132px;
  background: #fff; border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg); color: var(--color-text); text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              border-radius var(--dur-base) var(--ease-out);
}
.cat-tile:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-lg);
  border-color: var(--color-accent-200); color: var(--color-text); text-decoration: none;
  border-bottom-right-radius: 44px;
}
.cat-tile:active { transform: translateY(1px); }
.cat-tile .icon { font-size: 24px; color: var(--color-accent-600); }
.cat-tile .t { font-family: var(--font-heading); font-weight: 700; font-size: 16px;
               letter-spacing: var(--tracking-cjk-tight); }
.cat-tile .n { font-size: 12px; color: var(--color-neutral-500); margin-top: auto; }

/* — 服務卡 —
   市集要能一屏看到多張，所以比 site1 的 .card 緊湊：內距 16px、標題 16px。 */
.svc-card {
  display: flex; flex-direction: column; overflow: hidden;
  background: #fff; border: 1px solid var(--color-divider); border-radius: var(--radius-lg);
  color: inherit; text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.svc-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg);
                  color: inherit; text-decoration: none; }
.svc-card:active { transform: translateY(1px); }
.svc-thumb { background: var(--color-neutral-100); }
.svc-thumb .tag { position: absolute; top: 10px; left: 10px; box-shadow: var(--shadow-sm); }
.svc-b { display: flex; flex-direction: column; gap: 6px; padding: var(--space-4); flex: 1; }
.svc-t { font-family: var(--font-heading); font-weight: 700; font-size: 16px; line-height: 1.35;
         letter-spacing: var(--tracking-cjk-tight); color: var(--color-text); }
.svc-d { font-size: 13px; color: var(--color-neutral-600); margin: 0;
         display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* 價格與評分同一行；窄螢幕的雙欄卡片擠不下時換行，
   否則評分會被卡片的 overflow:hidden 裁掉（實測 500px 寬時溢出 23px）。 */
.svc-foot { display: flex; align-items: flex-end; justify-content: space-between;
            flex-wrap: wrap; gap: 4px var(--space-2); margin-top: auto; padding-top: var(--space-3); }

/* — 廠商標記 —
   自營與合作廠商必須一眼分得出來，這是平台信任感的根。
   自營用品牌青，合作廠商用中性灰＋認證勾，兩者不互搶。 */
.vendor { display: inline-flex; align-items: center; gap: 5px; font-size: 12px;
          color: var(--color-neutral-500); }
.vendor .icon { font-size: 14px; }
.vendor-own { color: var(--color-accent-700); font-weight: 500; }

/* — 價格標 —
   平台的每張卡都必須講清楚「怎麼算的」，不然使用者無法比較。
   數字用青色 700，單位與「起」壓成小字灰色。 */
.price { display: flex; align-items: baseline; gap: 3px; white-space: nowrap; }
.price .n { font-family: var(--font-heading); font-weight: 700; font-size: 20px;
            line-height: 1.1; letter-spacing: 0; color: var(--color-accent-700); }
.price .u { font-size: 12px; color: var(--color-neutral-500); }
.price-quote .n { font-size: 15px; color: var(--color-neutral-700); }

/* — 評分 — */
.rating { display: inline-flex; align-items: center; gap: 4px; font-size: 12px;
          color: var(--color-neutral-600); }
.rating .icon { font-size: 13px; color: var(--color-accent-2-600); }
.rating b { font-weight: 700; color: var(--color-neutral-800); letter-spacing: 0; }

/* — 篩選列 — */
.filterbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
             padding-block: var(--space-4); border-bottom: 1px solid var(--color-divider); }
.chip {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  padding: 7px 14px; font-size: 13px; font-weight: 500;
  letter-spacing: var(--tracking-cjk-tight); color: var(--color-neutral-700);
  background: #fff; border: 1.5px solid var(--color-neutral-200);
  border-radius: var(--radius-pill);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.chip:hover { border-color: var(--color-accent-400); color: var(--color-accent-800); }
.chip[aria-pressed="true"] { background: var(--action-primary); border-color: var(--action-primary); color: #fff; }

/* — 數量增減 — */
.stepper { display: inline-flex; align-items: center;
           border: 1.5px solid var(--color-neutral-200); border-radius: var(--radius-md); background: #fff; }
.stepper button {
  width: 40px; height: 42px; flex: none; cursor: pointer; font: inherit; font-size: 18px;
  color: var(--color-neutral-700); background: transparent; border: 0;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.stepper button:hover { background: var(--color-neutral-50); color: var(--color-accent-700); }
.stepper button:disabled { color: var(--color-neutral-300); cursor: not-allowed; background: transparent; }
.stepper input {
  width: 56px; height: 42px; text-align: center; font: inherit; font-size: 15px; font-weight: 500;
  color: var(--color-neutral-900); background: transparent; border: 0;
  border-inline: 1.5px solid var(--color-neutral-200);
  -moz-appearance: textfield;
}
.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper input:focus-visible { box-shadow: inset var(--ring-brand); }

/* — 試算面板 —
   黏在側欄，捲動時價格一直在視線內。每一列都要看得到組成，
   「NT$8,600」單獨出現沒有說服力，「25 坪 × NT$500」才有。 */
.calc { display: flex; flex-direction: column; gap: var(--space-4);
        padding: var(--space-6); background: #fff; border: 1px solid var(--color-divider);
        border-radius: var(--radius-xl); box-shadow: var(--shadow-md); }
.calc-lines { display: flex; flex-direction: column; gap: 8px; font-size: 14px;
              padding-top: var(--space-4); border-top: 1px solid var(--color-divider); }
.calc-line { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); }
.calc-line .l { color: var(--color-neutral-600); }
.calc-line .v { font-variant-numeric: tabular-nums; letter-spacing: 0; color: var(--color-neutral-800); }
.calc-line-sub .l, .calc-line-sub .v { font-size: 13px; color: var(--color-neutral-500); }
.calc-total { display: flex; align-items: baseline; justify-content: space-between;
              padding-top: var(--space-3); border-top: 1px solid var(--color-divider); }
.calc-total .l { font-size: 14px; font-weight: 500; color: var(--color-neutral-700); }
.calc-total .v { font-family: var(--font-heading); font-weight: 900; font-size: 30px; line-height: 1.1;
                 letter-spacing: 0; font-variant-numeric: tabular-nums; color: var(--color-accent-700); }
.calc-note { margin: 0; font-size: 12px; color: var(--color-neutral-500); }

/* 試算面板裡的每一個輸入項 */
.opt { display: flex; flex-direction: column; gap: 8px; }
.opt > .lab { font-size: 14px; font-weight: 500; color: var(--color-neutral-800); }
.opt-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
           padding: 10px 0; border-bottom: 1px solid var(--color-divider); font-size: 14px; }
.opt-row:last-child { border-bottom: 0; }
.opt-row .price-delta { font-size: 13px; color: var(--color-neutral-500);
                        font-variant-numeric: tabular-nums; }
.check { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 14px; }
.check input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.check .box { width: 20px; height: 20px; flex: none; border-radius: var(--radius-sm);
              border: 1.5px solid var(--color-neutral-300); display: grid; place-items: center;
              transition: border-color var(--dur-fast) var(--ease-out),
                          background-color var(--dur-fast) var(--ease-out); }
.check .box .icon { font-size: 14px; color: #fff; opacity: 0; }
.check:hover .box { border-color: var(--color-accent-500); }
.check input:checked + .box { background: var(--color-accent-500); border-color: var(--color-accent-500); }
.check input:checked + .box .icon { opacity: 1; }
.check input:focus-visible + .box { box-shadow: var(--ring-brand); }

/* — 包含／不包含 —
   多廠商平台最大的客訴來源是「我以為有含」。這個區塊在每個服務頁都必填。 */
.incl { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-6); }
.incl ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.incl li { display: flex; align-items: flex-start; gap: 8px; font-size: 14px; }
.incl .icon { font-size: 16px; margin-top: 3px; flex: none; }
.incl-yes .icon { color: var(--color-success-500); }
.incl-no .icon { color: var(--color-neutral-400); }
.incl-no li { color: var(--color-neutral-500); }

/* — 流程步驟 — */
.steps { counter-reset: s; display: grid; gap: var(--space-6); }
.step { position: relative; padding-left: 52px; }
.step::before {
  counter-increment: s; content: counter(s, decimal-leading-zero);
  position: absolute; left: 0; top: 0; width: 36px; height: 36px;
  display: grid; place-items: center;
  font-family: var(--font-heading); font-weight: 700; font-size: 13px; letter-spacing: 0;
  color: var(--color-accent-700); background: var(--color-accent-100);
  border-radius: var(--radius-md);
}
.step h4 { margin: 6px 0 4px; }
.step p { margin: 0; font-size: 14px; color: var(--color-neutral-600); }

/* — 常見問題 — */
.faq { border-top: 1px solid var(--color-divider); }
.faq details { border-bottom: 1px solid var(--color-divider); }
.faq summary { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
               cursor: pointer; list-style: none; padding: var(--space-4) 0;
               font-family: var(--font-heading); font-weight: 700; font-size: 16px;
               letter-spacing: var(--tracking-cjk-tight); color: var(--color-text); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary .icon { font-size: 18px; color: var(--color-neutral-400); flex: none;
                     transition: transform var(--dur-base) var(--ease-out); }
.faq details[open] summary .icon { transform: rotate(90deg); }
.faq p { margin: 0 0 var(--space-4); font-size: 14px; color: var(--color-neutral-600); max-width: 70ch; }

/* — 商品卡 — */
.prod-card { display: flex; flex-direction: column; overflow: hidden; background: #fff;
             border: 1px solid var(--color-divider); border-radius: var(--radius-lg);
             color: inherit; text-decoration: none;
             transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out); }
.prod-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); color: inherit; text-decoration: none; }
.prod-thumb { background: var(--color-neutral-50); }

/* — 頁尾 — */
/* 頁尾的前景一律用半透明白，不用中性階的固定灰。
   底色是會被換的（先前 #1E1F1F、現在 #383F33），固定灰只要底色一變亮就掉出對比範圍：
   實測 neutral-500 在新底色上只剩 2.64、neutral-400 剩 4.01，都低於 AA 要求的 4.5。
   半透明白會跟著底色走，換色不必重調。目前對比：.72 → 6.55、.55 → 4.56，皆過 AA。 */
.foot { background: var(--color-foot); color: rgba(255, 255, 255, .72); padding-block: 56px 32px; }
.foot h5 { color: #fff; font-size: 13px; letter-spacing: var(--tracking-caps);
           text-transform: uppercase; margin-bottom: var(--space-3); }
.foot a { color: rgba(255, 255, 255, .72); font-size: 14px; }
.foot a:hover { color: #fff; text-decoration: none; }
.foot-cols { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--space-8); }
.foot-links { display: flex; flex-direction: column; gap: 10px; }
.foot-links span { font-size: 14px; color: rgba(255, 255, 255, .55); }
.foot-base { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
             flex-wrap: wrap; margin-top: var(--space-8); padding-top: var(--space-6);
             border-top: 1px solid rgba(255, 255, 255, .14); font-size: 12px;
             color: rgba(255, 255, 255, .55); }

/* — 圖示 —
   全部是 Lucide 0.474.0，以 CSS mask 內嵌（規範：不用 emoji、不用 unicode 符號當圖示）。 */
.i-sparkles  { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9.9 2.5 12 8l5.5 2.1L12 12.2 9.9 17.7 7.8 12.2 2.3 10.1 7.8 8z'/><path d='M18 5v4'/><path d='M20 7h-4'/><path d='M17 17v3'/><path d='M18.5 18.5h-3'/></svg>"); }
.i-wind      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12.8 19.6A2 2 0 1 0 14 16H2'/><path d='M17.5 8a2.5 2.5 0 1 1 2 4H2'/><path d='M9.8 4.4A2 2 0 1 1 11 8H2'/></svg>"); }
.i-hammer    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m15 12-8.4 8.4a2.1 2.1 0 0 1-3-3L12 9'/><path d='M17.6 6.4 22 10.8'/><path d='m18 15 4-4a3 3 0 0 0-4.2-4.2L9.4 15.2'/><path d='m21.5 11.5-1.9-1.9'/></svg>"); }
.i-bug       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m8 2 1.9 1.9'/><path d='M14.1 3.9 16 2'/><path d='M9 7.1V6a3 3 0 1 1 6 0v1.1'/><path d='M7.1 12H2'/><path d='M22 12h-5.1'/><path d='M3 19a9 9 0 0 1 3-7'/><path d='M21 19a9 9 0 0 0-3-7'/><path d='M12 20v-9'/><path d='M6.5 9.5A6 6 0 0 1 12 7a6 6 0 0 1 5.5 2.5'/><path d='M6 12v3a6 6 0 0 0 12 0v-3'/></svg>"); }
.i-truck     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2'/><path d='M14 9h4l4 4v4a1 1 0 0 1-1 1h-2'/><circle cx='7' cy='18' r='2'/><circle cx='17' cy='18' r='2'/><path d='M9 18h6'/></svg>"); }
.i-leaf      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.5 19 2c1 2 2 4.2 2 8 0 5.5-4.8 10-10 10Z'/><path d='M2 21c0-3 1.9-5.5 4-7'/></svg>"); }
.i-heart     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M19 14c1.5-1.5 3-3.2 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.8 0-3 .5-4.5 2-1.5-1.5-2.7-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4 3 5.5l7 7Z'/></svg>"); }
.i-paw       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='4' r='2'/><circle cx='18' cy='8' r='2'/><circle cx='20' cy='16' r='2'/><path d='M9 10a5 5 0 0 1 5 5v3.5a3.5 3.5 0 0 1-6.8 1.2l-.4-1a3.5 3.5 0 0 0-1.7-1.9l-.9-.5A3.5 3.5 0 0 1 4 10Z'/></svg>"); }
.i-bag       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z'/><path d='M3 6h18'/><path d='M16 10a4 4 0 0 1-8 0'/></svg>"); }
.i-building  { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z'/><path d='M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2'/><path d='M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2'/><path d='M10 6h4'/><path d='M10 10h4'/><path d='M10 14h4'/><path d='M10 18h4'/></svg>"); }
.i-droplets  { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M7 16.3c2.2 0 4-1.8 4-4 0-2-2-4-4-6.7C5 8.3 3 10.3 3 12.3c0 2.2 1.8 4 4 4Z'/><path d='M12.6 21.3c2.2 0 4-1.8 4-4 0-2-2-4-4-6.7-2 2.7-4 4.7-4 6.7 0 2.2 1.8 4 4 4Z'/></svg>"); }
.i-badge     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3.9 8.1a2 2 0 0 1 0-2.2l1.1-1.6a2 2 0 0 1 1.2-.8l1.9-.4a2 2 0 0 0 1.2-.8L10.4 1a2 2 0 0 1 3.2 0l1.1 1.3a2 2 0 0 0 1.2.8l1.9.4a2 2 0 0 1 1.2.8l1.1 1.6a2 2 0 0 1 0 2.2l-1 1.7a2 2 0 0 0-.3 1.4l.2 1.9a2 2 0 0 1-.6 1.4l-1.4 1.4a2 2 0 0 1-1.4.6l-1.9-.2a2 2 0 0 0-1.4.3l-1.7 1a2 2 0 0 1-2.2 0l-1.7-1a2 2 0 0 0-1.4-.3l-1.9.2a2 2 0 0 1-1.4-.6L3 15.5a2 2 0 0 1-.6-1.4l.2-1.9a2 2 0 0 0-.3-1.4Z'/><path d='m9 12 2 2 4-4'/></svg>"); }
.i-shield    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 13c0 5-3.5 7.5-7.7 9a1 1 0 0 1-.6 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.2-2.7a1 1 0 0 1 1.5 0C14.5 3.8 17 5 19 5a1 1 0 0 1 1 1Z'/><path d='m9 12 2 2 4-4'/></svg>"); }
.i-clock     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 6v6l4 2'/></svg>"); }
.i-pin       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z'/><circle cx='12' cy='10' r='3'/></svg>"); }
.i-chevron-r { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m9 18 6-6-6-6'/></svg>"); }
.i-search    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='8'/><path d='m21 21-4.3-4.3'/></svg>"); }
.i-cart      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='8' cy='21' r='1'/><circle cx='19' cy='21' r='1'/><path d='M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12'/></svg>"); }
.i-ticket    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z'/><path d='M13 5v2'/><path d='M13 17v2'/><path d='M13 11v2'/></svg>"); }
.i-file      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z'/><path d='M14 2v4a2 2 0 0 0 2 2h4'/><path d='M10 9H8'/><path d='M16 13H8'/><path d='M16 17H8'/></svg>"); }
.i-x         { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 6 6 18'/><path d='m6 6 12 12'/></svg>"); }
.i-sparkles, .i-wind, .i-hammer, .i-bug, .i-truck, .i-leaf, .i-heart, .i-paw, .i-bag,
.i-building, .i-droplets, .i-badge, .i-shield, .i-clock, .i-pin, .i-chevron-r,
.i-search, .i-cart, .i-ticket, .i-file, .i-x {
  -webkit-mask-image: var(--d); mask-image: var(--d);
}

/* — 窄螢幕 —
   市集在手機上一律降成單欄或雙欄；試算面板取消黏性，改放在內容流裡。 */
@media (max-width: 1000px) {
  .grid-5 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .foot-cols { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 720px) {
  .sec { padding-block: 48px; }
  .grid-5, .grid-4, .grid-3, .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .sec-head { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
  .calc { position: static; }
  .incl { grid-template-columns: 1fr; gap: var(--space-4); }
  .foot-cols { grid-template-columns: 1fr; gap: var(--space-6); }
  h1 { font-size: 34px; }
  h2 { font-size: 24px; }
}
@media (max-width: 480px) {
  .grid-5, .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr; }
  .cat-grid { grid-template-columns: 1fr 1fr !important; }
}

/* — 導覽列的兩組項目（render.js 產生） — */
.navlinks { display: flex; gap: var(--space-6); }
.navside { display: flex; gap: var(--space-2); align-items: center; }
@media (max-width: 820px) { .navlinks { display: none; } }

/* — 縮圖佔位板 —
   品牌供稿沒有攝影素材。與其塞不相干的圖庫照，不如用分類圖標做成一致的底板；
   整排看起來是刻意的目錄樣式，而不是缺圖。
   要換成實拍照時，把 data/*.json 的 photo 欄位填上網址即可，程式不用改。 */
.thumb-ph {
  display: grid; place-items: center;
  background: linear-gradient(160deg, var(--color-accent-100), var(--color-neutral-50));
}
.thumb-ph .icon { font-size: 44px; color: var(--color-accent-400); }
.prod-thumb.thumb-ph .icon { font-size: 52px; }

/* 原價刪除線 */
.price .u s { color: var(--color-neutral-400); }

/* — 平台標準字 —
   平台改名後不再沿用慶旺的標誌（那是慶旺的資產）。「生活家」為暫定名，
   這裡先用文字標準字：品牌圓體 Heavy 900 配主色，日後換成正式 logo 只要改
   render.js 的 wordmark()。字距收緊，讓三個字讀起來是一個整體而不是三個字。 */
.wordmark {
  font-family: var(--font-heading); font-weight: 900; font-size: 25px; line-height: 1;
  letter-spacing: 0.01em; color: var(--color-accent-700); white-space: nowrap;
}
.wordmark-light { color: #fff; font-size: 22px; }
.nav-brand .wordmark { display: block; }


/* — 卡片縮圖的統一尺寸 —
   服務卡與商品卡一律 4:3。圖庫照片的原始比例天差地遠（同一排量到 198 / 301 / 352 / 396），
   光靠 aspect-ratio 壓不住：縮圖是縱向 flex 卡片裡的 flex 項目，預設 min-height: auto 會
   讓它不得低於內容的最小高度，而 height:100% 的 <img> 在父層高度未定時會退回自己的原始高度，
   反過來把父層撐開，aspect-ratio 就形同虛設。

   解法是把 <img> 絕對定位移出文件流 —— 縮圖的內容高度變成 0，高度就只能由 aspect-ratio 決定。
   兩種卡片共用同一組規則，之後不會再有一邊改到、一邊沒改到的情況。 */
.svc-thumb, .prod-thumb {
  position: relative; flex: none; min-height: 0;
  aspect-ratio: 4 / 3; overflow: hidden;
}
.svc-thumb > img, .prod-thumb > img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}

/* — 固定頁首 —
   .nav 自己有 position: sticky，但 render.js 是把它注入 <div id="nav"> 裡，
   而 sticky 的活動範圍是父層盒子；父層高度剛好等於 nav 高度，於是一捲動就跟著離場。
   真正需要 sticky 的是這個外層容器。 */
#nav { position: sticky; top: 0; z-index: 40; }

/* — 頁首的兩種狀態 —
   置頂時放大、透明，讓主視覺完整；一捲動就收窄成毛玻璃列，把內容和導覽分開。
   切換由 render.js 在 scrollY > 8 時掛上 .is-stuck。
   動態依規範：短、單向、無彈跳，140 至 200ms。 */
.nav {
  position: static;              /* sticky 移到外層 #nav，這裡只負責外觀 */
  padding-block: var(--space-4);
  background: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
  transition: padding-block var(--dur-base) var(--ease-out),
              background-color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
#nav.is-stuck .nav {
  padding-block: var(--space-2);
  background: rgba(255, 255, 255, .88);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--color-divider);
  box-shadow: var(--shadow-sm);
}
.wordmark { transition: font-size var(--dur-base) var(--ease-out); }
#nav.is-stuck .wordmark { font-size: 21px; }
.nav-brand img { transition: height var(--dur-base) var(--ease-out); }
#nav.is-stuck .nav-brand img { height: 28px; }

/* ══════════════════════════════════════════════════════════════════════
   購物車、結帳、預約、會員 —— 交易流程用到的元件
   ══════════════════════════════════════════════════════════════════════ */

/* — 購物車數量 —
   掛在導覽列圖示右上角。用輔色 #F7C376 是刻意的：這是整個頁面唯一
   需要「有東西在等你」的訊號，符合規範裡沙色一畫面只出現一處的原則。 */
.cart-btn { position: relative; }
.cart-dot {
  position: absolute; top: 4px; right: 2px; min-width: 18px; height: 18px;
  display: grid; place-items: center; padding: 0 5px;
  font-family: var(--font-heading); font-weight: 700; font-size: 11px; letter-spacing: 0;
  color: var(--color-accent-2-900); background: var(--color-accent-2-500);
  border: 2px solid #fff; border-radius: var(--radius-pill);
}

/* — 浮出提示 —
   加入購物車後的回饋。單向、320ms、無彈跳。 */
.toast {
  position: fixed; left: 50%; bottom: 28px; z-index: 60;
  display: flex; align-items: center; gap: 10px;
  max-width: calc(100vw - 32px); padding: 12px 20px;
  font-size: 14px; color: #fff; background: var(--color-neutral-900);
  border-radius: var(--radius-pill); box-shadow: var(--shadow-lg);
  transform: translate(-50%, 12px); opacity: 0;
  transition: opacity 320ms var(--ease-out), transform 320ms var(--ease-out);
}
.toast.is-on { opacity: 1; transform: translate(-50%, 0); }
.toast .icon { color: var(--color-success-500); font-size: 18px; flex: none; }
.toast a { color: var(--color-accent-300); font-weight: 500; white-space: nowrap; }
.toast a:hover { color: #fff; }

/* — 交易頁的共用骨架 —
   左邊是內容，右邊是金額摘要；摘要黏住，金額永遠在視線內。 */
.pay-layout { display: grid; grid-template-columns: 1fr 360px; gap: 48px; align-items: start;
              padding-block: var(--space-6) 72px; }
/* 金額摘要要跟著捲動。sticky 掛在 aside 而不是 .pay-box —— .pay-box 的父層是
   aside，align-items:start 讓 aside 只有內容高度，掛在裡層等於沒有可黏的空間。 */
.pay-layout > aside { /* 見下方 .sticky-side */ }
.pay-box { display: flex; flex-direction: column; gap: var(--space-4);
           padding: var(--space-6); background: #fff; border: 1px solid var(--color-divider);
           border-radius: var(--radius-xl); box-shadow: var(--shadow-md); }
.pay-box h3 { margin: 0; font-size: 18px; }

/* — 購物車列 — */
.cart-list { display: flex; flex-direction: column; border-top: 1px solid var(--color-divider); }
.cart-row { display: grid; grid-template-columns: 96px 1fr auto; gap: var(--space-4);
            padding: var(--space-4) 0; border-bottom: 1px solid var(--color-divider); }
.cart-thumb { position: relative; aspect-ratio: 1 / 1; overflow: hidden;
              border-radius: var(--radius-md); background: var(--color-neutral-50); }
.cart-thumb > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cart-thumb.thumb-ph .icon { font-size: 32px; }
.cart-main { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cart-main .t { font-family: var(--font-heading); font-weight: 700; font-size: 16px;
                letter-spacing: var(--tracking-cjk-tight); color: var(--color-text); }
.cart-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-3); }
.cart-amt { font-family: var(--font-heading); font-weight: 700; font-size: 17px; letter-spacing: 0;
            font-variant-numeric: tabular-nums; color: var(--color-text); white-space: nowrap; }
.cart-del { cursor: pointer; font: inherit; font-size: 13px; color: var(--color-neutral-500);
            background: none; border: 0; padding: 4px; }
.cart-del:hover { color: var(--color-danger-500); }

/* 服務列底下攤開的試算組成。使用者要看得到這個金額是怎麼來的。 */
.cart-detail { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 12px;
               color: var(--color-neutral-500); }
.cart-detail span::after { content: '・'; margin-left: 10px; color: var(--color-neutral-300); }
.cart-detail span:last-child::after { content: ''; }

/* — 預約時段 — */
.slot-card { padding: var(--space-4); border: 1px solid var(--color-divider);
             border-radius: var(--radius-lg); margin-bottom: var(--space-4); }
.slot-card > h4 { margin: 0 0 var(--space-3); font-size: 16px; }
.slot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
             gap: var(--space-2); }
.slot {
  display: flex; flex-direction: column; align-items: center; gap: 2px; cursor: pointer;
  padding: 10px 6px; font-size: 13px; text-align: center;
  border: 1.5px solid var(--color-neutral-200); border-radius: var(--radius-md); background: #fff;
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.slot .d { font-family: var(--font-heading); font-weight: 700; font-size: 14px; color: var(--color-text); }
.slot .w { font-size: 11px; color: var(--color-neutral-500); }
.slot:hover { border-color: var(--color-accent-400); }
.slot:has(input:checked) { border-color: var(--action-primary); background: var(--color-accent-50); }
.slot:has(input:checked) .d { color: var(--color-accent-800); }
.slot input { position: absolute; opacity: 0; width: 0; height: 0; }

/* — 空狀態 — */
.blank { display: flex; flex-direction: column; align-items: center; gap: var(--space-4);
         padding: 88px 24px; text-align: center; }
.blank .icon { font-size: 48px; color: var(--color-neutral-300); }
.blank p { margin: 0; color: var(--color-neutral-500); }

/* — 會員中心 — */
.tabs { display: flex; gap: var(--space-2); flex-wrap: wrap;
        border-bottom: 1px solid var(--color-divider); margin-bottom: var(--space-8); }
.tabs button {
  cursor: pointer; font: inherit; font-size: 15px; font-weight: 500;
  padding: 12px 4px; margin-bottom: -1px; color: var(--color-neutral-600);
  background: none; border: 0; border-bottom: 2px solid transparent;
  margin-right: var(--space-6);
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.tabs button:hover { color: var(--color-accent-700); }
.tabs button[aria-selected="true"] { color: var(--color-accent-800); border-bottom-color: var(--action-primary); }

.order { padding: var(--space-6); border: 1px solid var(--color-divider);
         border-radius: var(--radius-lg); margin-bottom: var(--space-4); }
.order-head { display: flex; align-items: baseline; justify-content: space-between;
              gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-4);
              padding-bottom: var(--space-3); border-bottom: 1px solid var(--color-divider); }
.order-no { font-family: var(--font-heading); font-weight: 700; font-size: 15px; letter-spacing: 0; }
.order-item { display: flex; align-items: baseline; justify-content: space-between;
              gap: var(--space-4); padding: 6px 0; font-size: 14px; }
.order-item .v { font-variant-numeric: tabular-nums; color: var(--color-neutral-700); }

@media (max-width: 900px) {
  .pay-layout { grid-template-columns: 1fr; gap: var(--space-6); }
  .pay-layout > aside { position: static; }
}
@media (max-width: 560px) {
  .cart-row { grid-template-columns: 72px 1fr; }
  .cart-side { grid-column: 1 / -1; flex-direction: row; align-items: center;
               justify-content: space-between; }
}


/* — 黏著側欄 —
   sticky 掛在 <aside>（grid 項目，活動範圍是整個 grid area），不是掛在裡面的面板：
   .pay-layout / .svc-layout / .prod-layout 都設了 align-items:start，aside 因此只有
   內容高度，把 sticky 寫在子元素上等於沒有可黏的空間。

   高度上限是必要的：加購項目多的服務，試算面板實測 989px，而視窗只有 773px。
   面板比視窗高的話，黏住之後底部的按鈕會永遠落在畫面外，使用者根本按不到。
   超過就讓面板自己捲，overscroll-behavior 避免捲到底時把整頁一起帶走。 */
.sticky-side {
  position: sticky; top: var(--sticky-top); align-self: start;
  max-height: calc(100vh - var(--sticky-top) - var(--space-4));
  overflow-y: auto; overscroll-behavior: contain;
}
@media (max-width: 900px) {
  .sticky-side { position: static; max-height: none; overflow: visible; }
}
