/* =============================================================================
   亞藍 Yalan Ponsford — landing page
   -----------------------------------------------------------------------------
   原則：一個區塊最多三個元素。留白就是質感。

   色彩   白（底）· 黑（字）· 翠綠 #72D98A（進度與行動）· 櫻花粉 #EFA6A8（點綴）
          全站純白，只有最後的預約區塊翻成黑底。
   字體   GenYoMin TW 源雲明體（所有標題與內文）· ChenYuLuoYan（手寫，極少量）
============================================================================= */

/* ------------------------------------------------------------- fonts --- */
/* 源雲明體 GenYoMin TW —— 台灣字形的明體。
   之前用的 BIZ UDP Mincho 是日文字型：說、直、骨 都是日文寫法，
   台灣沒有的字還會整個掉到系統字型，同一行混到兩套字。
   換成 TW 之後全站中文只有這一套，不需要任何補字。
   子集與檔案大小由 tools/subset-fonts.py 產生，改完文案要重跑。 */
@font-face{
  font-family:'GenYoMin TW'; font-style:normal; font-weight:400; font-display:swap;
  src:url('../fonts/GenYoMin2TW-R.woff2?v=20250904e') format('woff2');
}
@font-face{
  font-family:'GenYoMin TW'; font-style:normal; font-weight:500; font-display:swap;
  src:url('../fonts/GenYoMin2TW-M.woff2?v=20250904e') format('woff2');
}
/* 600 只給手機主標題用，所以只裁了主標題那幾個字（2KB）。
   unicode-range 一併鎖住，其他文字不會誤用這支。 */
@font-face{
  font-family:'GenYoMin TW'; font-style:normal; font-weight:600; font-display:swap;
  src:url('../fonts/GenYoMin2TW-SB.woff2?v=20250904e') format('woff2');
  unicode-range:U+0020,U+002E,U+4E00,U+4E0D,U+4E8C,U+59B3,U+5BE6,U+7528,U+8001,U+8AAA,U+9078;
}
/* 備援字型：借系統的明體，但把行高相關的量測改成跟 GenYoMin 一樣，
   字型載入完成的那一刻不會有跳版。 */
@font-face{
  font-family:'GenYoMin fallback';
  src:local('Songti TC'), local('Songti SC'), local('Noto Serif CJK TC'),
      local('Source Han Serif TC'), local('PingFang TC');
  size-adjust:100%; ascent-override:88%; descent-override:12%; line-gap-override:0%;
}
/* 手寫字型只出現在兩則註記，其餘地方一律不用 */
@font-face{
  font-family:'ChenYuLuoYan'; font-style:normal; font-weight:400; font-display:swap;
  src:url('../fonts/ChenYuluoyan-Thin.woff2?v=20250904e') format('woff2');
}

/* ------------------------------------------------------------ tokens --- */
:root{
  --bg:#FFFFFF;
  --ink:#0E0E0E;
  --ink-2:rgba(14,14,14,.66);
  --ink-3:rgba(14,14,14,.44);
  --rule:rgba(14,14,14,.11);

  --green:#72D98A;
  --green-deep:#2B7442;      /* 白底上的綠字，對比達標 */
  --green-soft:rgba(114,217,138,.13);

  /* 粉色已從全站退場，只保留給「兩則手寫註記」——
     全頁唯一的非正式元素。這是刻意的稀缺，不是裝飾用色。 */
  --pink:#EFA6A8;
  --pink-deep:#A85258;

  --dark:#0B0B0B;            /* 深色底：成果與 FAQ 交錯使用 */
  --on-dark:#FFFFFF;
  --on-dark-2:rgba(255,255,255,.62);
  --on-dark-3:rgba(255,255,255,.38);

  --font-display:'GenYoMin TW','GenYoMin fallback','Noto Serif CJK TC','Songti TC',serif;
  --font-hand:'ChenYuLuoYan','GenYoMin TW','GenYoMin fallback',cursive;

  /* 間距刻度：全站只允許這幾個值（§2） */
  --s1:8px; --s2:16px; --s3:24px; --s4:40px; --s5:64px; --s6:96px;

  /* 區塊之間唯一的間距來源。數值取自原本 FAQ → 預約 的 160px，
     每個區塊各出一半，邊界相加就是 --section-gap。改這一行就改全站。 */
  --section-gap:240px;   /* 桌機：留白就是自信（手機另設） */
  --sec-half:calc(var(--section-gap) / 2);
  /* 區塊內部：標題→內容、內容→CTA，全站共用這兩個值 */
  --measure:640px;       /* 所有內文的行長上限 */
  --gap-head:var(--s4);
  --gap-cta:var(--s5);

  --maxw:1140px;
  --pad:clamp(22px,4vw,48px);
  --ease:cubic-bezier(.42,0,.24,1);
  --ease-out:cubic-bezier(.16,.84,.34,1);

  --shadow-card:0 1px 3px rgba(14,14,14,.07), 0 16px 38px rgba(14,14,14,.10);
}

/* ------------------------------------------------------------- reset --- */
*,*::before,*::after{box-sizing:border-box}
/* 畫布上緣過捲露白、下緣過捲露黑（iOS 橡皮筋）；頁面本體照常由各區塊上色 */
html{
  -webkit-text-size-adjust:100%; scroll-behavior:smooth; scroll-padding-top:100px;
  background:linear-gradient(var(--bg) 0%, var(--bg) 50%, var(--dark) 50%);
}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:var(--font-display); font-size:16.5px; line-height:1.95;
  letter-spacing:.03em; -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
/* height:auto 一定要有，否則 HTML 的 height 屬性會蓋掉 CSS 的 aspect-ratio */
img,svg,video{display:block; max-width:100%; height:auto}
picture{display:block}
a{color:inherit; text-decoration:none}
button{font:inherit; color:inherit; background:none; border:0; cursor:pointer}
ul,ol{margin:0; padding:0; list-style:none}
h1,h2,h3{margin:0; font-weight:400; font-family:var(--font-display); letter-spacing:.035em}
p{margin:0}
::selection{background:var(--green-soft); color:var(--ink)}

.wrap{max-width:var(--maxw); margin:0 auto; padding-inline:var(--pad)}

/* --------------------------------------------------------- typography --- */
.h-xl{font-size:clamp(30px,3.9vw,48px); line-height:1.34; letter-spacing:.04em}
.h-lg{font-size:clamp(24px,2.9vw,36px); line-height:1.45; letter-spacing:.045em}
.small{font-size:13px; line-height:1.85; color:var(--ink-3); letter-spacing:.04em}
.hand{font-family:var(--font-hand); letter-spacing:.04em}

.proof .sec-title,.faq .sec-title{color:var(--on-dark)}
.sec-title{text-align:center; max-width:22em; margin-inline:auto}

.underline-hand{position:relative; display:inline-block; white-space:nowrap}
.underline-hand svg{position:absolute; left:-2%; bottom:-.3em; width:104%; height:.34em; overflow:visible}

section{position:relative}

/* ------------------------------------------------------------ buttons --- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:12px;
  font-family:var(--font-display); padding:19px 40px; border-radius:2px;
  font-size:16px; letter-spacing:.12em; white-space:nowrap;
  transition:transform .5s var(--ease), box-shadow .5s var(--ease), background .4s var(--ease), color .4s var(--ease);
}
.btn .arw{transition:transform .5s var(--ease-out); display:inline-block}
.btn:hover .arw{transform:translateX(5px)}
.btn:focus-visible{outline:2px solid var(--green-deep); outline-offset:3px}
.btn-primary{background:var(--green); color:#0B2415; box-shadow:0 10px 30px rgba(114,217,138,.26)}
.btn-primary:hover{background:#61CD7B; transform:translateY(-2px); box-shadow:0 16px 40px rgba(114,217,138,.34)}
.btn-ghost{border:1.5px solid var(--rule); color:var(--ink)}
.btn-ghost:hover{border-color:var(--green); background:var(--green-soft)}
.btn-lg{padding:22px 48px; font-size:17px}
.btn-text{
  display:inline-flex; align-items:center; gap:10px; font-size:16px; letter-spacing:.08em;
  border-bottom:1.5px solid rgba(255,255,255,.22); padding-bottom:6px;
  transition:border-color .45s var(--ease), color .45s var(--ease);
}

/* -------------------------------------------------------------- nav --- */
.nav{
  position:sticky; top:0; z-index:200; background:rgba(255,255,255,.92);
  backdrop-filter:saturate(150%) blur(16px); -webkit-backdrop-filter:saturate(150%) blur(16px);
  border-bottom:1px solid transparent; transition:border-color .6s var(--ease);
}
.nav.stuck{border-bottom-color:var(--rule)}
.nav-in{display:flex; align-items:center; justify-content:center; height:88px}
.nav-logo img{height:40px; width:auto}
@media(max-width:768px){ .nav-in{height:68px} .nav-logo img{height:30px} }

/* ------------------------------------------------------------- hero --- */
/* 三個元素：主文案 ·（照片＋資歷）· CTA。照片是配角，CTA 摺線以上。 */
.hero{padding-top:var(--s4); padding-bottom:var(--sec-half)}
.hero-inner{position:relative; text-align:center; display:flex; flex-direction:column; align-items:center}
.hero-line{max-width:15em}
.hero-photo{margin:var(--s4) 0 0; width:100%; max-width:710px}
.hero-photo img{
  width:100%; aspect-ratio:16/8.4; object-fit:cover; border-radius:18px;
  object-position:center 12%;   /* 新主圖：臉在上方 1/5，橫向裁切只留一半高，要靠上才留得住臉與上半身 */
  box-shadow:0 2px 4px rgba(14,14,14,.06), 0 14px 30px rgba(14,14,14,.12), 0 34px 70px rgba(14,14,14,.14);
}
.hero-photo figcaption{
  margin-top:var(--s3); font-size:13.5px; letter-spacing:.06em; color:var(--ink-2); line-height:1.8;
}
.hero-photo figcaption b{font-weight:400; color:var(--green-deep)}
.hero-cta{margin-top:var(--s4)}
/* 矮視窗（如 1024×768 筆電）：照片縮一階，CTA 保持在摺線以上 */
@media(min-width:900px) and (max-height:840px){
  .hero{padding-top:var(--s3)}
  .hero-photo{max-width:560px; margin-top:var(--s3)}
  .hero-cta{margin-top:var(--s3)}
}

@media(max-width:700px){
    /* 與成果卡同為 1:1，整頁比例語言一致；也讓 hero 不會比下面的區塊還弱 */
  .hero-photo img{aspect-ratio:1/1; border-radius:14px}
  .hero{padding-top:var(--s3); padding-bottom:var(--sec-half)}
  .hero-photo{margin-top:var(--s3)}
  .hero-photo figcaption{margin-top:var(--s2)}
  .hero-cta{margin-top:var(--s3)}
}

@keyframes heroIn{ from{opacity:0; transform:translateY(var(--rise,24px))} to{opacity:1; transform:none} }
.hero-line{animation:heroIn 1s var(--ease-out) .05s both}
.hero-photo{animation:heroIn 1s var(--ease-out) .3s both}
.hero-cta{animation:heroIn .85s var(--ease-out) .55s both}

/* 成果區塊在手機上與 hero 同屏，必須一起進場，否則 hero 在動、它卻是靜的。
   同一組 keyframes、同一條緩動，只是接在 hero 之後。 */
.proof .proof .sec-title,.faq .sec-title{color:var(--on-dark)}
.sec-title{animation:heroIn 1s var(--ease-out) .7s both}
.proof-grid .polaroid{animation:heroIn 1s var(--ease-out) both}
.proof-grid .polaroid:nth-child(1){animation-delay:.82s}
.proof-grid .polaroid:nth-child(2){animation-delay:.90s}
.proof-grid .polaroid:nth-child(3){animation-delay:.98s}

/* ------------------------------------------------------------ proof --- */
/* 兩個元素：主文案、拍立得。 */
/* 下緣多留一段：手寫註記要往下站開，箭頭才有畫得完的長度 */
.proof{padding-block:var(--sec-half); padding-bottom:calc(var(--sec-half) + 40px);
  background:var(--dark); color:var(--on-dark)}
.proof-grid{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(18px,2.2vw,30px);
  margin-top:var(--gap-head); align-items:stretch;
}
/* 三張卡：桌機一排三張，手機直排。中間不做兩欄——三張會落單一張。 */
@media(max-width:1000px){ .proof-grid{gap:18px} }
/* 手機：每張卡吃滿內容寬（375 → 327）；440 只擋平板，任何手機都到不了。 */
@media(max-width:768px){ .proof-grid{grid-template-columns:minmax(0,1fr); gap:26px; max-width:440px; margin-inline:auto} }

.polaroid{
  background:#fff; padding:12px 12px 0; border-radius:2px; position:relative;
  box-shadow:var(--shadow-card); display:flex; flex-direction:column; margin:0;
  width:100%; max-width:100%; min-width:0;   /* 相框跟著容器走，不跟著圖片的原始尺寸走 */
  border:1px solid var(--rule);
  transition:transform .7s var(--ease), box-shadow .7s var(--ease);
}
.polaroid:nth-child(odd){transform:rotate(-1deg)}
.polaroid:nth-child(even){transform:rotate(.85deg)}
.polaroid:hover{transform:rotate(0deg) translateY(-8px); box-shadow:0 3px 8px rgba(14,14,14,.10), 0 30px 60px rgba(14,14,14,.16)}
/* ── 圖片盒：只准跟著容器縮放，永遠不能被圖片的原始尺寸撐開 ──────
   Safari 算 flex/grid 項目的最小尺寸時，會把 width:100% 的圖片用「原始寬度」
   （800、948、1000px）算進去；1fr 或 min-width:auto 一碰到就把整排撐出視窗。
   所以：軌道用 minmax(0,1fr)、項目 min-width:0、裝圖的盒子 overflow:hidden。
   三張圖都預先裁成 4:5（手機 800×1000、桌機 1000×1250），這裡只是把框釘住。 */
.ph{width:100%; max-width:100%; min-width:0; min-height:0; height:auto; overflow:hidden}
.polaroid img{display:block; width:100%; max-width:100%; height:auto; min-height:0; aspect-ratio:4/5; object-fit:cover; background:#fff}
/* 說明文字靠左：原話（可多段）、佐證。原話用內文字體，佐證再小一階、顏色退後。 */
.polaroid-cap{padding:14px 6px 18px; text-align:left; flex:1; display:flex; flex-direction:column; align-items:flex-start; justify-content:flex-start}
.polaroid-cap .quote{font-size:14px; line-height:1.85; color:var(--ink-2); margin:8px 0 0; text-wrap:pretty}
.polaroid-cap .quote + .quote{margin-top:13px}   /* 兩段原話之間空一行的感覺 */
.polaroid-cap .res{margin-top:13px; font-size:12.5px; line-height:1.7; letter-spacing:.02em; color:var(--ink-3)}
.pin{
  position:absolute; top:-9px; left:50%; transform:translateX(-50%); z-index:3;
  width:16px; height:16px; border-radius:50%;
  background:radial-gradient(circle at 34% 30%, #FFFFFF, #CFCFCF 48%, #9A9A9A);
  box-shadow:0 3px 7px rgba(14,14,14,.26), inset 0 -2px 3px rgba(0,0,0,.10);
}
.pin::after{content:''; position:absolute; left:50%; top:74%; width:2px; height:8px; background:#B08386; transform:translateX(-50%) rotate(7deg)}
.todo{
  font-size:11px; line-height:1.65; letter-spacing:.04em; text-align:left;
  color:var(--ink-3); background:rgba(14,14,14,.04); border:1px dashed rgba(14,14,14,.20);
  padding:8px 10px;
}
.todo b{display:block; font-weight:400; letter-spacing:.12em; margin-bottom:3px}

/* ============================================================ roadmap === */
/* 三個元素：提示、賽道、CTA。整條賽道一個螢幕看得完。 */
.roadmap{padding-block:var(--sec-half)}
.rm-hint{margin-top:var(--s2);
  display:flex; align-items:center; justify-content:center; gap:11px;
  font-size:14px; color:var(--green-deep); letter-spacing:.14em;
}
.rm-hint .tapdot{width:9px; height:9px; border-radius:50%; background:var(--green); flex:none; position:relative}
.rm-hint .tapdot::after{content:''; position:absolute; inset:-5px; border-radius:50%; border:1.5px solid var(--green); animation:tap 2.6s var(--ease-out) infinite}
@keyframes tap{0%{transform:scale(.6); opacity:.9} 100%{transform:scale(1.8); opacity:0}}
.rm-cta{text-align:center; margin-top:var(--gap-cta)}

.rm-stage{position:relative; width:100%; padding-top:80%; margin-top:var(--gap-head)}
/* 賽道 SVG 疊在卡片之上（z2 > auto），一定要放行滑鼠事件，
   否則整張卡片都點不到 —— 只有號誌自己接事件。 */
.track-svg{position:absolute; inset:0; width:100%; height:100%; z-index:2; pointer-events:none}
.nodes-top{z-index:16; pointer-events:none}
.nodes-top .rm-node{pointer-events:auto; cursor:pointer}
.rm-node circle{transition:stroke .5s var(--ease), stroke-width .5s var(--ease)}
.rm-node text{transition:fill .5s var(--ease)}

.walker{position:absolute; z-index:14; width:4.8%; transform:translate(-50%,-94%); pointer-events:none}
.walker-bob{animation:bob 2.8s ease-in-out infinite}
@keyframes bob{0%,100%{transform:translateY(0)} 50%{transform:translateY(-3%)}}

/* 站點卡：一整排，全部看得見 */
.stopcard{
  position:absolute; width:24%; text-align:left; display:block;
  background:#fff; padding:9px 9px 0; border-radius:2px; border:1px solid var(--rule);
  box-shadow:0 1px 3px rgba(14,14,14,.07), 0 12px 26px rgba(14,14,14,.09);
  transition:transform .7s var(--ease), box-shadow .7s var(--ease), border-color .7s var(--ease);
}
.stopcard{cursor:pointer}
.stopcard:hover{transform:translateY(-5px); border-color:var(--green);
  box-shadow:0 2px 6px rgba(14,14,14,.09), 0 20px 40px rgba(14,14,14,.13)}
/* hover 時預覽清晰（還沒點開的也給一點回饋） */
.blur-stages .stopcard:hover .sc-img,
.blur-stages .stopcard:hover .sc-cap{filter:blur(2.5px) saturate(.9)}
.stopcard.active{
  z-index:9; border-color:var(--green);
  box-shadow:0 0 0 1.5px var(--green), 0 3px 8px rgba(14,14,14,.10), 0 26px 52px rgba(14,14,14,.16);
}
.stopcard:focus-visible{outline:2px solid var(--green-deep); outline-offset:4px}
.sc-img{position:relative; display:block; overflow:hidden; aspect-ratio:4/3; background:#EFEFEF}
.sc-img img{width:100%; height:100%; object-fit:cover; transition:filter .8s var(--ease), transform 1.1s var(--ease)}
/* 未點開的階段先模糊，點開才清晰 —— 製造好奇感。
   不想要這個效果：把 CONFIG.blurInactiveStages 改成 false。 */
/* 尚未點開的站點：圖片與文字一起模糊。
   看得出「有東西」，但讀不出內容 —— 好奇心就是這樣來的。 */
.blur-stages .stopcard .sc-img,
.blur-stages .stopcard .sc-cap{filter:blur(6px) saturate(.75); transition:filter .55s var(--ease)}
.blur-stages .stopcard.seen .sc-img,
.blur-stages .stopcard.seen .sc-cap{filter:none}
.stopcard.active .sc-img img{transform:scale(1.03)}
.sc-cap{display:block; padding:9px 9px 11px}
.sc-cap b{display:block; font-weight:400; font-size:clamp(10.5px,.88vw,12px); letter-spacing:.01em; line-height:1.45; text-wrap:pretty; margin-top:3px; color:var(--ink-2)}
.sc-cap i{display:block; font-style:normal; font-size:clamp(9px,.82vw,10.5px); letter-spacing:.1em; color:var(--green-deep)}
.sc-check{
  position:absolute; top:8px; right:8px; z-index:2; width:19px; height:19px; border-radius:50%;
  background:var(--green); display:grid; place-items:center;
  opacity:0; transform:scale(.5); transition:opacity .6s var(--ease), transform .6s var(--ease);
}
.stopcard.done .sc-check,.stopcard.active.complete .sc-check{opacity:1; transform:scale(1)}

/* 進場：號碼與文字一起滑上來（唯一保留的區塊內動畫） */
/* 起點刻意不是 opacity:0 —— 換站時卡片不能有「空掉」的一瞬間。
   舊內容淡出與新內容淡入重疊，讀起來是換頁，不是壞掉。 */
@keyframes riseIn{
  from{opacity:.3; transform:translateY(var(--rise,10px))}
  to{opacity:1; transform:translateY(0)}
}
.rise-in{animation:riseIn .7s var(--ease-out) both}
.sc-cap.rise-in{animation-delay:.30s; animation-duration:.5s}
.rm-card-img.rise-in{animation-delay:.30s}
.rm-card-tag.rise-in{animation-delay:.30s}
.rm-card-body.rise-in{animation-delay:.36s}

/* 手寫註記：箭頭一律往右，把視線帶向下一站 */
/* 註記：箭頭「從圖片內側出發、往外指向文字」（參考稿的畫法）。
   svg 在前、文字在後，橫向排成一句。 */

/* 進度與角色由 app.js 的同一個 rAF 驅動（同一個 t 值），
   這裡「不能」再放 transition，否則會疊出第二層緩動。 */
#trackProgress,#mProgress,.walker,.m-walker{transition:none}
.finish-dots{opacity:0; transition:opacity .4s var(--ease)}
.rm-stage.at-finish .finish-dots{opacity:.7}

/* 桌機：目前階段的內容（賽道元件的一部分） */


/* ---- 手機：橫向賽道 + 單張卡 ---- */
.rm-mobile{display:none}
@media(max-width:900px){
  .rm-stage{display:none}
  .rm-mobile{display:block; margin-top:var(--gap-head)}
  .rm-strip{position:relative; width:100%; padding-top:44%; margin-bottom:6px}
  /* 只針對賽道本身的 SVG（直接子元素）；角色的 SVG 若套 height:100% 會塌成 0 */
  .rm-strip > svg{position:absolute; inset:0; width:100%; height:100%; pointer-events:none}
  .m-nodes-top{z-index:16; pointer-events:none}
  .m-nodes-top .m-node{pointer-events:auto; cursor:pointer}
  .m-walker{position:absolute; z-index:14; width:12%; aspect-ratio:200/380; transform:translate(-50%,-90%)}

  .rm-card{background:#fff; border:1px solid var(--rule); border-radius:2px; box-shadow:var(--shadow-card); overflow:hidden}
  /* 1:1。原本是 16/7.6（2.11:1），但來源都是 760×950 的直式（4:5），
     裁到 2.11:1 只剩 38% 的高度——頭和腳都在畫面外。
     不用 4:5 是因為整張卡會超過一屏。
     --focus 讓個別照片可以微調裁切點，不用改比例。 */
  .rm-card-img{position:relative; aspect-ratio:1/1; overflow:hidden; background:#EFEFEF}
  .rm-card-img img{
    width:100%; height:100%; object-fit:cover;
    object-position:var(--focus, center 35%);
    /* 來源偏灰，稍微提一點才不會被近黑的字壓過去。只到這裡，不能更多。 */
    filter:contrast(1.06) saturate(1.04);
  }
  .rm-card-tag{
    position:absolute; left:12px; bottom:12px; background:rgba(255,255,255,.95); padding:6px 12px;
    font-size:11.5px; letter-spacing:.14em; color:var(--green-deep); box-shadow:0 2px 8px rgba(14,14,14,.16);
  }
  .rm-card-body{padding:20px}
  .rm-card-phase{display:flex; align-items:baseline; gap:12px}
  .rm-card-phase b{font-weight:400; font-size:18px; letter-spacing:.09em}
  .rm-card-phase i{font-style:normal; font-size:12px; letter-spacing:.13em; color:var(--green-deep)}
  .rm-card-title{font-size:15px; line-height:1.65; letter-spacing:.05em; margin-top:7px; text-wrap:pretty}
  .rm-card-text{margin-top:5px; font-size:13px; line-height:1.7; color:var(--ink-3); text-wrap:pretty}

  .rm-dots{display:flex; align-items:center; justify-content:space-between; margin-top:16px}
  .rm-dotrow{display:flex; gap:9px}
  .rm-dot{width:7px; height:7px; border-radius:50%; background:rgba(14,14,14,.13); transition:background .5s var(--ease), transform .5s var(--ease)}
  .rm-dot.done{background:var(--green-deep)}
  .rm-dot.on{background:var(--green); transform:scale(1.5)}
  .rm-nav{display:flex; gap:10px}
  .rm-arrow{width:44px; height:44px; border:1.5px solid var(--rule); border-radius:50%; color:var(--green-deep); display:grid; place-items:center; transition:border-color .5s var(--ease), opacity .4s}
  .rm-arrow:hover:not(:disabled){border-color:var(--green)}
  .rm-arrow:disabled{opacity:.28; cursor:default}
}

/* -------------------------------------------------------------- faq --- */
/* 三個元素：主文案、FAQ、CTA。 */
.faq{padding-block:var(--sec-half); background:var(--dark); color:var(--on-dark)}
.faq-list{margin:var(--gap-head) auto 0; border-top:1.5px solid var(--rule)}
.faq-item{border-bottom:1px solid var(--rule)}
.faq-q{
  width:100%; display:flex; align-items:flex-start; gap:clamp(14px,1.5vw,22px);
  padding:clamp(19px,2.1vw,26px) 0; text-align:left;
  font-size:clamp(16px,1.4vw,18.5px); line-height:1.7; letter-spacing:.045em;
  transition:color .45s var(--ease);
}
.faq-q:hover{color:var(--green-deep)}
.faq-n{flex:none; font-size:12.5px; letter-spacing:.14em; color:var(--green-deep); opacity:.5; padding-top:.5em; min-width:2.3em; transition:opacity .45s var(--ease)}
.faq-item.open .faq-n{opacity:1}
.faq-t{flex:1}
.faq-ico{position:relative; width:15px; height:15px; flex:none; margin-top:.55em}
.faq-ico::before,.faq-ico::after{content:''; position:absolute; background:var(--ink-3); transition:transform .6s var(--ease), background .45s var(--ease)}
.faq-ico::before{left:0; top:7px; width:15px; height:1.5px}
.faq-ico::after{left:7px; top:0; width:1.5px; height:15px}
.faq-item.open .faq-ico::after{transform:rotate(90deg) scaleX(0)}
.faq-item.open .faq-ico::before{background:var(--green)}
.faq-a{overflow:hidden; height:0; transition:height .6s var(--ease)}
.faq-a-in{padding:0 40px 26px calc(2.3em + clamp(14px,1.5vw,22px)); font-size:15px; line-height:2.1; color:var(--ink-2); text-wrap:pretty}
@media(max-width:560px){ .faq-a-in{padding-left:0} }
.faq-cta{text-align:center; margin-top:var(--gap-cta)}

/* ---------------------------------------------------------- booking --- */
/* 全站唯一的黑色區塊。三個元素：主文案、Cal.com、IG。 */
.booking{background:var(--bg); color:var(--ink); padding-top:var(--sec-half); padding-bottom:var(--sec-half)}
.booking h2{color:var(--ink)}
.cal-shell{
  margin:var(--gap-head) auto 0; background:#fff; border-radius:3px;
  padding:clamp(8px,1vw,14px); box-shadow:0 30px 80px rgba(0,0,0,.5);
  border-top:3px solid var(--green); min-height:560px;
}
#cal-inline{width:100%; min-height:544px; overflow:auto}
.cal-fallback{padding:56px 24px; text-align:center; color:var(--ink-3)}
.cal-fallback .btn{margin-top:18px}
.booking-alt{text-align:center; margin-top:var(--gap-cta)}
.booking-alt .btn-text{color:var(--ink-2); border-color:var(--rule)}
.booking-alt .btn-text:hover{color:var(--green); border-color:var(--green)}

/* ----------------------------------------------------------- footer --- */
footer{background:var(--dark); color:var(--on-dark-3); padding:0 0 20px; font-size:12.5px; letter-spacing:.05em}
.disclaimer{
  max-width:52em; margin:0 auto var(--s2); padding-top:var(--s3);
  font-size:12px; line-height:2; color:rgba(255,255,255,.56); text-align:center; letter-spacing:.05em;
}
.foot-in{display:flex; justify-content:center; align-items:center; padding-top:16px; border-top:1px solid rgba(255,255,255,.09)}
.foot-in a:hover{color:var(--on-dark)}

/* ------------------------------------------------------- sticky cta --- */
/* 這條只存在於手機／窄視窗（≤900），桌機是 display:none，
   所以連位移與動畫都一起關在 media query 裡，桌機完全碰不到。 */
.sticky-cta{
  position:fixed; left:0; right:0; bottom:0; z-index:190;
  padding:11px var(--pad) calc(11px + env(safe-area-inset-bottom));
  background:rgba(255,255,255,.95); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  border-top:1px solid var(--rule); display:none;
}
.sticky-cta .btn{width:100%; padding:15px 20px}

@media(max-width:900px){
  /* 進出只靠 transform 與 opacity。transition 寫在基底類別上，
     兩個方向才會用同一條曲線——只寫在 .is-visible 上的話，
     進場有動畫、退場會直接切掉。
     display 只在這裡決定「這個裝置有沒有這條」，JS 全程只加減 .is-visible。
     110% 是為了讓陰影也一起退出畫面外。
     420ms 的 expo ease-out（.16,1,.3,1）：快速離開、緩慢落定。
     進場要的就是 ease-out；ease-in 是從靜止開始加速，反而像先卡了一下。 */
  .sticky-cta{
    display:block;
    transform:translateY(110%); opacity:0;
    transition:
      transform 420ms cubic-bezier(.16,1,.3,1),
      opacity   240ms ease-out;
    will-change:transform, opacity;
  }
  .sticky-cta.is-visible{transform:translateY(0); opacity:1}
}
/* 系統開了「減少動態效果」就直接切換。
   注意：這台機器目前是開著的，所以在這裡看到的一定是瞬間切換，不是動畫壞掉。 */
@media(max-width:900px) and (prefers-reduced-motion:reduce){
  .sticky-cta{transition:none}
}

/* ---------------------------------------------------------- Lenis --- */
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-stopped{overflow:hidden}

#scrollProgress{
  position:fixed; top:0; left:0; right:0; height:3px; z-index:300;
  background:var(--green); transform:scaleX(0); transform-origin:left center; pointer-events:none;
}

/* --------------------------------------------------- reduced motion --- */
/* 移除「位移」，保留淡入與顏色 —— 頁面不會變成一張靜止的圖。 */
@media(prefers-reduced-motion:reduce){
  :root{--rise:0px}
  html{scroll-behavior:auto}
  .walker-bob{animation:none}
  .rm-hint .tapdot::after{animation:none}
  .polaroid:hover,.stopcard:hover,.btn:hover,.btn-primary:hover{transform:none}
}


/* ── 深色區塊（成果 / FAQ）：文字、互動狀態 ───────────────── */
.proof .sec-title,.faq .sec-title{color:var(--on-dark)}
.faq-q{color:var(--on-dark)}
.faq-q:hover{color:var(--green)}
.faq-a-in{color:var(--on-dark-2)}
.faq-n{color:var(--green)}
.faq-ico::before,.faq-ico::after{background:var(--on-dark-3)}
.faq-item.open .faq-ico::before{background:var(--green)}
/* 分隔線全部移除：靠留白與背景換色分章，不靠線 */
.faq-list{border-top:none}
.faq-item{border-bottom:none}
.faq-q{padding-block:var(--s3)}
.faq-a-in{padding-right:0}

/* ── 行長上限：全站內文一律 ~640px ───────────────────────── */
.lede,.faq-a-in,.disclaimer,.booking-head p,.hero-photo figcaption{
  max-width:var(--measure); margin-inline:auto;
}

/* ── 寬度節奏：hero 窄 → 成果/賽道 寬 → 預約 收窄 → 頁尾 放開 ── */
.hero-inner{max-width:var(--measure); margin-inline:auto}
.booking .wrap{max-width:820px}


/* ── hero 照片：與成果卡同一種容器語言（拍立得白框） ───────── */
/* 拍立得的四邊都要有白框，而且下緣最寬——那是它最好認的比例。
   側邊與上緣同寬，下緣約四倍寬。 */
.hero-photo .frame{
  background:#fff; border-radius:2px;
  padding:clamp(10px,1.2vw,14px) clamp(10px,1.2vw,14px) clamp(38px,4.8vw,56px);
  box-shadow:0 1px 3px rgba(14,14,14,.10), 0 18px 40px rgba(14,14,14,.13);
  min-width:0; max-width:100%; overflow:hidden;   /* 同 .ph：相框只跟容器走 */
}
.hero-photo picture{width:100%; max-width:100%; min-width:0; overflow:hidden}
.hero-photo .frame img{border-radius:0; box-shadow:none; display:block; max-width:100%; height:auto; min-height:0}

/* ── 成果區：手寫註記（全站第二則，也是最後一則） ──────────── */
.proof-wrap{position:relative}
/* 手寫字連同底線，落在拍立得下緣與區塊下緣的正中間。
   對齊要看「墨跡」不是元素的框：手寫字上面有一段行距，
   底線的 SVG 下面也留了白，照框對會偏低。 */
.proof-note{
  position:absolute; right:6px; bottom:-81px; z-index:9; pointer-events:none;
}
.proof-note span{
  display:inline-block; font-family:var(--font-hand); font-size:clamp(15px,1.6vw,22px);
  color:var(--pink); letter-spacing:.04em; white-space:nowrap;
  transform:rotate(-2.5deg); transform-origin:right center;
}
/* 底線由 app.js 依實際位置畫出來（drawNoteUnderline）：
   筆畫有粗細變化，還帶一點起伏與傾斜。 */
.note-underline{position:absolute; z-index:17; pointer-events:none; overflow:visible}

@media(max-width:700px){
  .proof{padding-bottom:calc(var(--sec-half) + 40px)}
  .proof-note{right:auto; left:4px; bottom:-48px}
}


/* ══ 手機 ══════════════════════════════════════════════ */
@media(max-width:900px){
  /* 區塊間距在手機收斂（桌機 240 太大）；仍是同一個變數 */
  :root{ --section-gap:112px; --gap-cta:var(--s4); }

  /* hero 佔滿第一屏：捲動之前看不到下一個區塊的任何東西 */
  .hero{
    min-height:100svh; display:flex; align-items:center;
    padding-top:var(--s3); padding-bottom:var(--s3);
  }
  .hero-inner{width:100%}
}


/* ── 成果卡：先身分、後佐證 ─────────────────────────────── */
.pf-identity{
  display:block; font-weight:400; font-size:14.5px; line-height:1.6;
  letter-spacing:.03em; color:var(--ink); text-wrap:pretty;
}
.pf-ctx{display:block; margin-top:6px; font-size:12.5px; line-height:1.65; color:var(--ink-3)}
.pf-name{display:block; margin-top:8px; font-size:12px; letter-spacing:.08em; color:var(--ink-3)}
.pf-result{
  display:inline-block; margin-top:8px; font-size:11.5px; letter-spacing:.06em;
  color:var(--green-deep); background:var(--green-soft); padding:3px 8px; border-radius:2px;
}


/* ── 2. FAQ：答案與問題共用同一條左邊界 ─────────────────── */
.faq-list{text-align:left}
.faq-q{text-align:left}
.faq-a-in{
  text-align:left;
  margin-inline:0;                 /* 覆寫 --measure 的置中 */
  max-width:var(--measure);
}

/* ── 3. Cal.com：收斂尺寸，標題與選時間同屏可見 ──────────── */
.cal-shell{max-width:760px}
#cal-inline{max-height:600px; overflow:auto; -webkit-overflow-scrolling:touch}
@media(max-width:900px){
  .cal-shell{max-width:100%}
  #cal-inline{max-height:520px}
}

/* hero 第二行 */
.hero-sub{
  margin-top:var(--s2); font-size:clamp(15px,1.35vw,19px); line-height:1.85;
  color:var(--ink-2); max-width:var(--measure); margin-inline:auto;
}


/* FAQ 縮排用固定 px：編號與答案的 em 基準不同，用 em 會對不齊。
   欄寬要吃得下最寬的「Q13｜」，並且鎖死寬度，否則各題會各自縮放。 */
:root{ --faq-num-w:50px; --faq-gap:18px; }
.faq-n{width:var(--faq-num-w); min-width:var(--faq-num-w); flex:0 0 var(--faq-num-w)}
.faq-q{gap:var(--faq-gap)}
.faq-a-in{padding-left:calc(var(--faq-num-w) + var(--faq-gap))}
@media(max-width:560px){
  :root{ --faq-num-w:46px; --faq-gap:12px; }
}


/* ── 斷行：只在句子邊界換行，句中不切開 ───────────────────── */
.hero-line{text-wrap:balance; white-space:nowrap}   /* 主文案永遠一行 */
.hero-sub,.sec-title{text-wrap:balance}
/* FAQ 答案已逐句換行，放寬行長讓整句放得下 */
.faq-a-in{max-width:none; text-wrap:pretty}
.sc-cap b{text-wrap:pretty}
@media(max-width:600px){
  .hero-line{white-space:normal}      /* 窄螢幕允許換行，否則會溢出畫面 */
}


/* 白色愛心：自己的圖檔，對齊手寫字的字高與基線 */
.emo-heart{
  display:inline-block; width:.92em; height:.92em;
  vertical-align:-.12em; margin-left:.14em;
}


/* ── 中文標點的細節 ───────────────────────────────────────
   palt：讓標點改用比例寬度，「，、。」後面那塊死白會收掉。
   line-break:strict：套用禁則，標點不會被丟到行首。
   hanging-punctuation：行尾標點可以微微掛出去，右邊界更整齊。 */
html{
  font-feature-settings:"palt" 1;
  line-break:strict;
  hanging-punctuation:allow-end;
  text-spacing-trim:space-first;
}
/* 大字級的標點空隙最明顯，額外收一點 */
.h-xl,.h-lg,.sec-title,.hero-line,.hero-sub{
  font-feature-settings:"palt" 1, "kern" 1;
}
/* 手寫註記維持原本的鬆度，不套 palt（會破壞手寫感） */
.proof-note span{font-feature-settings:normal}


/* ══════════════════════════════════════════════════════════════════════
   手機（≤768）：這一整段只影響手機，桌機的版面、間距與斷行完全不動。
   放在檔案最後面，蓋掉前面 900 / 700 / 600 的手機規則。
   ────────────────────────────────────────────────────────────────────
   一屏最多三個焦點。hero 的三個是「主標題 · CTA · 照片」，
   logo、副標、佐證行都刻意收小、降對比，退到後面去。
   ══════════════════════════════════════════════════════════════════ */

/* 只在手機生效的換行（文案裡寫 [[br]]）；
   [[sep]] 則是「桌機一條分隔線、手機改成換行」。 */
.br-m{display:none}
/* 數字與單位是一個單位，中間那個空格不可以變成斷點 */
.nw{white-space:nowrap}
.sep-d{display:inline}

@media(max-width:768px){
  /* 保險絲：就算哪個盒子還是被撐開，也不准出現橫向捲動。掛在 html 不掛 body——
     掛 body 會把 body 變成捲動容器，100svh、sticky、IntersectionObserver 全部走樣。 */
  html{overflow-x:hidden}
  .rm-card-img{max-width:100%; min-width:0; overflow:hidden}
  .br-m{display:inline}
  .sep-d{display:none}

  :root{ --pad:24px; --hero-measure:318px; }

  /* 中文的斷行：
       line-break:strict  禁則，標點不會被丟到行首
       word-break:keep-all 優先斷在標點，不從詞中間切開
       overflow-wrap:break-word 例外閥門——真的塞不下的長句才允許硬斷，
                                沒有它，keep-all 會把幾段 FAQ 撐出容器
     短而顯眼的句子（佐證行、免責聲明）另外用 [[br]] 手動斷在標點上。 */
  p,h1,h2,h3,li,.faq-t,.faq-a-in,.faq p{
    line-break:strict; word-break:keep-all; overflow-wrap:break-word;
  }
  .faq-t{font-size:15px; line-height:1.6; text-wrap:balance}

  /* ── 1. HERO ─────────────────────────────────────────────────
     不再垂直置中撐滿一屏——那正是 logo 底下那塊空白的來源。
     logo 到 CTA 是一個由上往下越收越緊的區塊，照片排在 CTA 之後。 */
  .nav-in{height:52px}
  .nav-logo img{height:26px; opacity:.85}

  /* hero 就是一屏。用 100svh 不是 100vh——iOS Safari 的 100vh 是對著
     「收起來的網址列」量的，所以區塊永遠比看得到的高度短一截，
     下一區塊的深色上緣就會從摺線下面透進來。
     擋住下一區塊的是 min-height，跟 justify-content 無關；用 flex-start
     是為了讓上緣的距離固定——置中的話，螢幕越高、logo 到主標題就越開。 */
  .hero{
    min-height:100svh; display:flex; flex-direction:column; justify-content:flex-start;
    /* logo 到主標題要 48：導覽列自己在 logo 下面已經留了 13，這裡補 35。
       用固定值不用 svh——svh 會跟著螢幕高度長，667 到 932 之間
       這個間距會從 53 漲到 69，就守不住 40–56 的範圍了。
       27 + 導覽列的 13 + 行距與字身的 8 = 量出來剛好 48。 */
    padding-top:27px;
    padding-bottom:5svh;
  }
  .hero-inner{width:100%}

  /* figure 讓出版位，讓「圖說」和「相框」各自排序 */
  .hero-photo{display:contents}

  /* 間距一律用 margin-block-end，由上往下遞給下一塊，
     全區塊只有這一種方法——先前 margin-top 與 gap 混用才會忽寬忽窄。
     節奏：48 / 14 / 20 / 32 / 40。同一個意思的兩行貼緊（主標題→副標 14），
     換一種功能就拉開（佐證行→CTA 32）。 */
  .hero-line{order:1; margin:0 0 14px}
  .hero-sub{order:2; margin:0 0 20px}
  .hero-photo figcaption{order:3; margin:0 0 32px}
  .hero-cta{order:4; margin:0 0 40px}
  .hero-photo .frame{order:5; margin:0; width:100%; min-width:0}

  /* ── hero 進場：六個元素依序浮起 ───────────────────────────
     原本 heroIn 是掛在 <figure class="hero-photo"> 上的，但手機版把它
     設成 display:contents 好讓圖說和相框各自排序——display:contents 的
     元素不產生任何 box，動畫等於畫在一個不存在的盒子上。
     圖說、相框都變成 flex item 之後就沒有人接手了；副標更是從頭到尾
     都沒被指定過動畫。這裡改成掛在真正會產生 box 的元素上。

     延遲照「看到的順序」給，不是 DOM 順序——手機版用 order 重排過，
     nth-child 會照 DOM 走，剛好是錯的。 */
  .nav-logo{animation:heroIn 640ms cubic-bezier(.16,1,.3,1) 0ms both}
  .hero-line{animation:heroIn 640ms cubic-bezier(.16,1,.3,1) 80ms both}
  .hero-sub{animation:heroIn 640ms cubic-bezier(.16,1,.3,1) 140ms both}
  .hero-photo figcaption{animation:heroIn 640ms cubic-bezier(.16,1,.3,1) 200ms both}
  .hero-cta{animation:heroIn 640ms cubic-bezier(.16,1,.3,1) 260ms both}
  .hero-photo{animation:none}          /* 沒有 box，掛在它上面沒有意義 */
  .hero-photo .frame{animation:heroIn 640ms cubic-bezier(.16,1,.3,1) 340ms both}

  /* ── 3. CTA 上方那條綠色 ──────────────────────────────────
     不是多出來的元素，是它自己的陰影：0 10px 30px 的模糊半徑比位移大，
     30 的模糊往上鋪 15，扣掉 10 的位移還剩 5 露在按鈕上緣，
     左右各多出 30——所以看起來是一條比按鈕寬、往左偏的綠色橫條。
     用負的 spread 把陰影收回按鈕輪廓內，只會往下落。 */
  .hero-cta.btn-primary,.sticky-cta .btn-primary{
    box-shadow:0 12px 24px -12px rgba(114,217,138,.32);
  }

  /* ── 4. hero 照片 ─────────────────────────────────────────
     36svh 是量出來的：上面那疊到 CTA 結束在 319，加上相框的
     10 + 38 內距，整個拍立得（含最寬的下緣白邊）剛好收在摺線上方
     還有 20 的餘裕。高度被夾住之後靠 object-fit 裁切，不會變形。 */
  .hero-photo img{
    max-height:36svh; width:100%; max-width:100%; min-height:0; object-fit:cover;
    object-position:center 25%;   /* 1:1 被 36svh 夾住只看得到 73% 高，靠上一點把臉和上半身留在畫面裡 */
    border-radius:14px;
  }

  /* ── 5. 手機字級與寬度收斂 ─────────────────────────────────
     除了大小、字重、顏色，寬度也要往下收。眼睛先讀形狀再讀大小——
     副標如果比主標題寬，看起來就比主標題重要，整塊會自己打架。
     量出來的寬度（375 可用 327）：
       主標題 30px/.03em  → 317.5   100%   全頁最寬的一行
       副標   14px/-.01em → 285.1   89.8%
       佐證行 12px        → 217.2   68.4%
     副標的字級被 14px 的下限綁住，靠 ±.01em 的字距把比例拉進 85–90%：
     標題放一點、內文收一點，兩邊都在察覺不到的範圍內。 */
  .hero-line{
    font-size:30px; line-height:1.25; font-weight:600;
    letter-spacing:.03em; white-space:nowrap; max-width:none;
  }
  .hero-sub{
    font-size:14px; line-height:1.65; font-weight:400; white-space:nowrap;
    letter-spacing:-.01em; color:var(--ink-2);
    margin-inline:auto; max-width:var(--hero-measure);
  }
  .hero-photo figcaption{
    font-size:12px; line-height:1.6; color:var(--ink-3);
    margin-inline:auto; max-width:calc(var(--hero-measure) * .75);
  }
  .hero-cta{font-size:17px}
  body{font-size:16px; line-height:1.75}

  /* 觸控目標至少 44 */
  .btn{min-height:48px}
  .faq-q{min-height:48px}
  .nav-logo{display:inline-flex; align-items:center; min-height:44px}

  /* ── 手寫註記：手機收起來 ─────────────────────────────────
     手機沒有側邊留白，它只能疊在拍立得上，跟照片互相干擾；
     移到角落又會變成一張貼紙。桌機的側欄放得下它，所以只在手機藏起來，
     標記本身留在 HTML 裡。 */
  .proof-note,.note-underline{display:none}
}

/* 更窄的機器：主標題與副標一起再降一階，維持各自一行。
   下限是 24px（再小就不像標題了）。 */
/* 更窄的機器：三行等比往下收，主標題 > 副標 > 佐證行的順序不變 */
@media(max-width:365px){
  :root{ --hero-measure:284px; }
  .hero-line{font-size:27px}
  .hero-sub{font-size:12.5px}
  .hero-photo figcaption{font-size:11px}
}
@media(max-width:330px){
  :root{ --hero-measure:252px; }
  .hero-line{font-size:24px}
  .hero-sub{font-size:11px}
  .hero-photo figcaption{font-size:10px}
}
