@charset "utf-8";
/* ════════════════════════════════════════════════════════════════════
   璞玥建設　PRO YUE DEVELOPMENT
   ────────────────────────────────────────────────────────────────────
   黑底、克制的字、照片有絕對的發言權，換屏時像一道推刀掃過去，
   畫面才慢慢清出來。
   （注意：以前這裡寫過一句用「磨」做比喻的話，Ethan 說那太 AI，
   全站已經拿掉。**不要再寫回來**，連註解都不要。）

   效能規則（不可違反）：連續動的東西只碰 transform 與 opacity。
   不用 blur 在會動的元素上、不用動態 mask、不用 drop-shadow、
   不用跟隨滑鼠的全屏漸層重繪。
   ════════════════════════════════════════════════════════════════════ */

:root{
  --ink:#000;
  --ink-2:#07070a;
  --ink-3:#0e0e11;
  --paper:#e7e7e7;          /* 唯一的白，略帶灰 */
  --paper-2:#9d9a93;
  --paper-3:#67655f;
  --bronze:#b9975f;
  --bronze-hi:#e8dbbe;
  --hair:rgba(231,231,231,.15);
  --hair-2:rgba(231,231,231,.07);

  --serif:"Noto Serif TC","Source Han Serif TC","Songti TC",serif;
  /* 展示用的明體。案名與四大理念用這一支——思源宋體是為了「不搶戲」設計的，
     當標題字太平（Ethan：「字形太普通，無藝術感」）。昭源宋體筆畫對比高、
     起收筆銳利，放大之後才有題字的份量。Google Fonts 依 unicode-range 分片，
     實際只會下載用到的那幾片。
     "Chiron Sung HK WS" 是本機驗證用的別名（npm chiron-sung-hk-webfont），
     上線時抓不到也沒關係，會往後退到思源宋體。 */
  --disp:"Chiron Sung HK","Chiron Sung HK WS","Noto Serif TC","Source Han Serif TC",serif;
  --sans:"Noto Sans TC","PingFang TC","Microsoft JhengHei",system-ui,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  /* 標準字用的拉丁字。2026-08-18 Ethan：「PRO YUE 的字，用很漂亮的英文字。」
     Cormorant Garamond：舊風格（old-style）襯線體，筆畫對比高、
     襯線細、字腔開——**跟昭源宋體是同一種骨架**（高對比、銳利的起收筆），
     所以中英疊在一起是同一個聲音，不是兩種字硬拼在一起。
     只用在標準字與頁尾那一組，其餘的拉丁小字照舊用 --mono
     （那些是資訊，等寬體才排得整齊）。
     抓不到的時候退到系統的 Georgia／Times，不會變成無襯線。 */
  --latin:"Cormorant Garamond",Cormorant,Garamond,Georgia,"Times New Roman",serif;

  --slow:cubic-bezier(.16,1,.3,1);
  --vslow:cubic-bezier(.19,1,.22,1);   /* 起步幾乎不動，尾巴拖很長 */
  --deep:cubic-bezier(.62,0,.12,1);
  --gut:clamp(22px,5vw,74px);
}

*{margin:0;padding:0;box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html:not(.deck){scroll-behavior:smooth}
body{background:var(--ink);color:var(--paper);
  font-family:var(--sans);font-weight:300;font-size:15px;line-height:2.0;
  letter-spacing:.05em;-webkit-font-smoothing:antialiased;
  /* clip 不會建立捲動容器，hidden 會——後者會讓 position:sticky 整個失效 */
  overflow-x:clip}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
::selection{background:var(--bronze);color:#000}
::-webkit-scrollbar{width:6px}
::-webkit-scrollbar-track{background:#000}
::-webkit-scrollbar-thumb{background:#241f16}

/* ══════════════════════════════════════════════
   一、氣氛層（整站共用，與內容完全解耦）
   ══════════════════════════════════════════════ */

/* 顆粒：靜態，不做動畫。負責把「數位的平」變成「照片的糙」 */
.grain{position:fixed;inset:0;z-index:70;pointer-events:none;opacity:.04;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* 微光暈：極淡，只讓注意力被輕輕推向指標所在 */
#glow{position:fixed;inset:0;z-index:52;pointer-events:none;
  opacity:0;transition:opacity 2s ease}
body.woke #glow{opacity:1}

/* ── 游標＝進度環 ──────────────────────────────
   一枚細環跟著指標，環上那道亮弧就是這一卷看到哪裡了。
   游標同時是指標與頁碼，不必另外再擺一個進度元件。 */
#cur{position:fixed;left:0;top:0;z-index:200;pointer-events:none;
  width:40px;height:40px;margin:-20px 0 0 -20px;
  opacity:0;transition:opacity 1.2s ease;will-change:transform}
body.woke #cur{opacity:1}
#cur svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;
  transform:rotate(-90deg);transition:transform 1.1s var(--vslow)}
#cur .trk{fill:none;stroke:rgba(231,231,231,.22);stroke-width:1}
#cur .arc{fill:none;stroke:var(--bronze-hi);stroke-width:1.4;
  stroke-linecap:round;transition:stroke-dashoffset 1.3s var(--vslow),opacity .9s ease}
#cur .dot{position:absolute;left:50%;top:50%;width:3px;height:3px;margin:-1.5px 0 0 -1.5px;
  background:var(--paper);transition:transform .9s var(--vslow),opacity .7s ease}
#cur .lb{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  font-family:var(--mono);font-size:8.5px;letter-spacing:.2em;color:var(--paper);
  white-space:nowrap;opacity:0;transition:opacity .8s ease}
/* 滑到可點的東西上：環張開、亮弧退淡、中心給文字讓位 */
#cur.on{transform-origin:50% 50%}
body.cur-hot #cur{width:74px;height:74px;margin:-37px 0 0 -37px}
body.cur-hot #cur .dot{transform:scale(0);opacity:0}
body.cur-hot #cur .arc{opacity:.25}
body.cur-hot #cur .lb{opacity:1}
#cur{transition:opacity 1.2s ease,width .95s var(--vslow),height .95s var(--vslow),
  margin .95s var(--vslow)}
body.woke,body.woke a,body.woke button,body.woke [role="button"]{cursor:none}
body.woke input,body.woke textarea,body.woke select{cursor:auto}
@media (pointer:coarse),(prefers-reduced-motion:reduce){#cur,#glow{display:none!important}}

/* ══════════════════════════════════════════════
   二、標記 · 選單
   ══════════════════════════════════════════════ */
/* ── 左上角的標記 ──────────────────────────────────────────────
   2026-08-18 Ethan：「左上角璞玥建設四個字**最大為主，視覺明顯**。
   英文先 PRO YUE 就好，字體的質感調整更好、更美，DEVELOPMENT 都刪掉。」

   三件事：
   ① **中文放大成主角**：14–16px → 20–27px，而且從 `--serif`（思源宋體）
      換成 `--disp`（昭源宋體）。思源宋體是為了「不搶戲」設計的，
      當標準字太平；昭源的筆畫對比高、起收筆銳利，放大之後才有題字的份量。
      這一支本來就是站上大標在用的，換過來整站的字也統一了。
   ② 字距從 .44em 收到 .3em。小字要靠字距撐開才不糊，
      **放大之後字距太寬反而會散**，四個字讀起來會變成四個獨立的字。
      收到 .3em 剛好還看得出是標準字、又連得成一個詞。
      末尾多出來的那一格用 `text-indent` 補回去，左緣才對得齊。
   ③ 英文只留 PRO YUE，退成一行很安靜的墊底：字級小一階、字距放到 .5em、
      顏色壓到 --paper-3。**它的角色是註腳，不是第二個標題。** */
/* ── 2026-08-20 再改：小一些，而且兩行**左右都要切齊** ──────────
   Ethan：「左上的璞玥建設太大了，小一些。並且璞玥建設、pro yue，
            左右兩邊要對齊，才不會看起來那麼怪。」

   **為什麼不能靠調字距對齊。** 中文四個字每個都剛好 1em，
   英文 PRO YUE 的字寬各不相同，而且**這一頁的字是 Google Fonts 抓的**——
   網路慢的時候會先用替代字型畫一次，字寬完全不一樣。
   寫死一個 letter-spacing，只在我這台、字體load完、那個視窗寬度對得齊，
   換一個條件就歪掉。

   所以改成**讓英文自己撐開**：英文那一行是 flex，
   一個字母一個 `<b>`，`justify-content:space-between`。
   兩端的字母天生就貼齊容器的兩邊，中間的空隙瀏覽器自己均分——
   **不管字體有沒有load好、不管視窗多寬，永遠是齊的。**

   容器的寬度由中文那一行決定：`width:max-content` 讓整塊縮到內容寬，
   中文那一行末尾多出來的一格字距用 `margin-right` 負值收掉
   （不收的話英文會比中文寬出一個字距）。
   `text-indent` 整個拿掉了——收掉尾巴之後左緣本來就對齊版心，
   不必再往右推。

   字距寫成 `--ls`，手機那兩段只要覆蓋這一個變數，
   負的 margin 會自己跟著算。 */
.mark{position:fixed;top:clamp(20px,2.8vw,36px);left:var(--gut);z-index:80;
  --ls:.28em;
  width:max-content;
  font-family:var(--disp);font-weight:500;font-size:clamp(18.5px,1.6vw,25px);
  color:var(--paper);line-height:1.1;
  opacity:0;transition:opacity 1.8s ease .3s}
.mark span{display:block;letter-spacing:var(--ls);
  margin-right:calc(var(--ls) * -1)}
body.up .mark{opacity:1}

/* ── 只給搜尋引擎與螢幕報讀器的標題 ────────────────────────────
   2026-08-20：首頁與 about 本來**沒有 h1**。h1 是 Google 判斷
   「這一頁在講什麼」最重的一個訊號，缺了它等於把主題交給它自己猜。
   但這兩頁的版面沒有可以放大標的位置（首頁是滿版膠捲、about 是水線），
   所以放一個看不見的。
   **不能用 display:none**——那樣 Google 會當作隱藏內容降權、
   螢幕報讀器也讀不到。要用「移出畫面 ＋ 裁成 1px」這個標準寫法。 */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);
  white-space:nowrap;border:0}

/* PRO YUE：換成 Cormorant Garamond（見 :root 的 --latin）。
   **字級要跟著中文一起放大**——它是同一個標準字的下半，
   停在 10px 的話會變成一行離很遠的小注記，整組就散了。
   字距 .34em：襯線體本來就有襯線在牽線，不需要像等寬體那樣拉到 .5em；
   拉太開反而會把單字拆成一個一個字母。 */
.mark i{display:flex;justify-content:space-between;
  font-style:normal;font-family:var(--latin);font-weight:600;
  font-size:.66em;letter-spacing:0;
  color:rgba(200,195,186,.72);margin-top:clamp(6px,.7vw,10px)}
.mark i b{font-weight:inherit;line-height:1}
/* PRO 跟 YUE 中間要看得出是兩個字：給 Y 一點左邊界。
   flex 會把「剩下的」空間平均分，所以每一格還是一樣寬，
   斷字的地方多這一點。 */
.mark i b:nth-child(4){margin-left:.5em}

.menu-btn{position:fixed;top:clamp(24px,3.2vw,40px);right:var(--gut);z-index:82;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.4em;color:var(--paper);
  padding:6px 0;opacity:0;transition:opacity 1.8s ease .42s,color .6s ease}
body.up .menu-btn{opacity:1}
.menu-btn:hover{color:var(--bronze)}

#nav{position:fixed;inset:0;z-index:81;background:#000;
  display:flex;align-items:center;justify-content:center;
  opacity:0;visibility:hidden;transition:opacity 1s var(--slow),visibility 1s}
body.nav-open #nav{opacity:1;visibility:visible}
#nav ol{list-style:none;text-align:center}
#nav li{margin:clamp(11px,1.9vh,22px) 0;opacity:0;transform:translateY(24px);
  transition:opacity 1.5s ease,transform 1.4s var(--vslow)}
body.nav-open #nav li{opacity:1;transform:none}
body.nav-open #nav li:nth-child(1){transition-delay:.16s}
body.nav-open #nav li:nth-child(2){transition-delay:.29s}
body.nav-open #nav li:nth-child(3){transition-delay:.42s}
body.nav-open #nav li:nth-child(4){transition-delay:.55s}
body.nav-open #nav li:nth-child(5){transition-delay:.68s}
#nav a{display:grid;grid-template-columns:minmax(0,1fr) clamp(76px,9vw,120px);
  gap:clamp(16px,2.4vw,34px);align-items:baseline;
  width:min(430px,80vw);margin:0 auto;text-align:right;
  font-family:var(--serif);font-weight:500;font-size:clamp(20px,2.5vw,31px);
  letter-spacing:.3em;transition:color .7s ease}
#nav a em{font-style:normal;text-align:left;font-family:var(--mono);
  font-size:9.5px;letter-spacing:.26em;color:var(--paper-3);transition:color .7s ease}
#nav a:hover,#nav a:hover em,#nav a[aria-current]{color:var(--bronze)}

/* ══════════════════════════════════════════════
   三、開場：三拍
   一條線畫開 → 兩句話 → 第一個案子清出來
   ══════════════════════════════════════════════ */
#ov{position:fixed;inset:0;z-index:110;background:#000;
  transition:opacity 1.6s ease,visibility 1.6s}
body.done #ov{opacity:0;visibility:hidden;pointer-events:none}
#ov .rule{position:absolute;left:50%;top:50%;translate:-50% 0;height:1px;width:0;
  background:linear-gradient(90deg,transparent,rgba(231,231,231,.5),transparent);
  transition:width 2.2s var(--vslow)}
body.act1 #ov .rule{width:min(460px,62vw)}
body.out #ov .rule{width:0;transition:width 1.4s var(--deep)}
#ov .act{position:absolute;left:50%;top:calc(50% - 42px);translate:-50% -50%;
  white-space:nowrap;font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(16px,2.1vw,27px);letter-spacing:.4em;margin-left:.4em;
  opacity:0;transition:opacity 2.1s ease}
#ov .act.on{opacity:1}
#skip{position:fixed;right:var(--gut);bottom:clamp(22px,4vh,40px);z-index:115;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.34em;
  color:rgba(231,231,231,.34);transition:color .7s ease,opacity 1.2s ease}
#skip:hover{color:var(--paper)}
body.done #skip{opacity:0;pointer-events:none}

/* ══════════════════════════════════════════════
   四、首頁：全螢幕垂直翻頁
   ══════════════════════════════════════════════ */
html.deck,html.deck body{height:100%;overflow:hidden}
#deck{position:fixed;inset:0;z-index:1}
.scr{position:absolute;inset:0;visibility:hidden;pointer-events:none}
.scr.live{visibility:visible;pointer-events:auto}
.scr.prev{visibility:visible}

/* 照片層：進場時輕微收縮，慢到幾乎看不出來，但體感上「還在動」 */
/* 不要在這裡鋪不透明黑底：這幾屏是疊在一起的，
   任何一屏只要可見就會整片蓋住前一屏。底色交給 body。 */
.scr .ph{position:absolute;inset:0;overflow:hidden}
.scr .ph img{width:100%;height:100%;object-fit:cover;object-position:var(--op,center);
  transform:scale(1.07);opacity:0;
  transition:transform 4.2s var(--vslow),opacity 2.4s ease}
.scr.live .ph img{transform:scale(1);opacity:1}
.scr.prev .ph img{opacity:0;transform:scale(1.02);transition:opacity 1.3s ease,transform 1.6s var(--deep)}

/* 壓暗只往字要待的那一角走（左下），對角線遞減。
   不用兩層全屏漸層互乘——那會把夜景整片壓成黑的。 */
.scr .veil{position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(to top right,rgba(0,0,0,.88) 0%,rgba(0,0,0,.62) 20%,
      rgba(0,0,0,.26) 42%,rgba(0,0,0,.05) 62%,rgba(0,0,0,0) 78%),
    linear-gradient(180deg,rgba(0,0,0,.46) 0%,rgba(0,0,0,.06) 18%,rgba(0,0,0,0) 34%)}

/* ── 推刀顯影：一道推刀掃過去，畫面才清出來 ──
   只有 transform 位移，沒有 blur、沒有遮罩運算。 */
.scr .polish{position:absolute;top:0;bottom:0;left:0;width:46vw;margin-left:-23vw;
  pointer-events:none;opacity:0;
  background:linear-gradient(90deg,transparent,
    rgba(255,250,238,.035) 26%,rgba(255,250,238,.13) 50%,
    rgba(255,250,238,.035) 74%,transparent)}
.scr.live .polish{animation:polish 2.6s cubic-bezier(.44,0,.14,1) .18s both}
@keyframes polish{
  0%{opacity:0;transform:translate3d(-24vw,0,0)}
  14%{opacity:1}
  86%{opacity:1}
  100%{opacity:0;transform:translate3d(124vw,0,0)}}

/* 案名：左下，不置中——照片自己會找中心，字不必跟它搶 */
.scr .cap{position:absolute;left:var(--gut);bottom:clamp(74px,12vh,124px);z-index:5;
  max-width:min(640px,58vw)}
.scr .idx{font-family:var(--mono);font-size:10px;letter-spacing:.34em;color:var(--bronze);
  opacity:0;transform:translateY(14px);
  transition:opacity 1.6s ease .5s,transform 1.6s var(--vslow) .5s}
.scr.live .idx{opacity:1;transform:none}
.scr h2{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(30px,4.6vw,62px);line-height:1.4;letter-spacing:.24em;
  margin:clamp(16px,2.2vh,26px) 0 0 .24em}
/* 逐字浮現：JS 把每個字包成 span，一個一個上來 */
.scr h2 i{display:inline-block;font-style:normal;opacity:0;
  transform:translate3d(0,.42em,0);
  transition:opacity 1.5s ease,transform 1.5s var(--vslow)}
.scr.live h2 i{opacity:1;transform:none}
.scr .loc{font-family:var(--mono);font-size:10.5px;letter-spacing:.26em;color:var(--paper-2);
  margin-top:clamp(16px,2.4vh,26px);opacity:0;transform:translateY(14px);
  transition:opacity 1.6s ease 1.05s,transform 1.6s var(--vslow) 1.05s}
.scr.live .loc{opacity:1;transform:none}
/* CTA：文字 ＋ 一條金色短線 ＋ 細箭頭。全站通用，不綁在首頁上。 */
.go{display:inline-flex;align-items:center;gap:13px;margin-top:clamp(20px,3vh,34px);
  font-family:var(--mono);font-size:10px;letter-spacing:.32em;color:var(--paper);
  position:relative;padding-left:15px;transition:color .7s ease}
.go::before{content:"";position:absolute;left:0;top:50%;translate:0 -50%;
  width:1px;height:12px;background:var(--bronze);transition:height .8s var(--slow)}
.go svg{width:24px;height:6px;overflow:visible;flex:0 0 auto;
  transition:transform .9s var(--slow)}
.go svg *{stroke:currentColor;stroke-width:1;fill:none}
.go:hover{color:var(--bronze)}
/* 放大版：出口那一個「認識團隊」。2026-08-17 Ethan：「把認識團隊放大。」
   等寬字在中文上是走 fallback，放大之後會很鬆，所以改用明體。 */
.go.big{font-family:var(--disp);font-weight:500;font-size:clamp(17px,1.9vw,24px);
  letter-spacing:.22em;gap:18px;padding-left:21px;margin-top:clamp(24px,3.6vh,40px)}
.go.big::before{height:22px}
.go.big svg{width:34px;height:8px}
.go:hover::before{height:22px}
.go:hover svg{transform:translateX(8px)}
/* 首頁的那顆另外加進場 */
.scr .go{opacity:0;transform:translateY(14px);
  transition:opacity 1.6s ease 1.25s,transform 1.6s var(--vslow) 1.25s,color .7s ease}
.scr.live .go{opacity:1;transform:none}

/* 直書索引：右緣，全部案名一次看得見，也是目錄 */
#vidx{position:fixed;right:var(--gut);top:50%;translate:0 -50%;z-index:80;
  display:flex;flex-direction:row-reverse;gap:clamp(14px,1.6vw,24px);
  opacity:0;transition:opacity 1.8s ease .8s}
body.up #vidx{opacity:1}
/* 直書不靠 writing-mode——它在 flex 項目裡把兩個字疊進同一格。
   一個字一個 block，最穩，字距也完全可控。 */
#vidx .vi{display:block;cursor:pointer;padding:0}
/* 淺灰而不是深灰：這排字會壓在天空上，深色在亮天空會整個不見 */
#vidx .vi b{display:block;text-align:center;
  font-family:var(--serif);font-weight:500;font-size:12.5px;line-height:1.72;
  color:rgba(231,231,231,.44);transition:color .9s ease}
#vidx::before{content:"";position:absolute;left:-18px;right:-18px;top:-22px;bottom:-22px;
  z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse at center,rgba(0,0,0,.42),rgba(0,0,0,0) 72%)}
#vidx .vi:hover b{color:rgba(231,231,231,.82)}
#vidx .vi.on b{color:var(--bronze)}

/* 屏序與捲動提示 */
#cue{position:fixed;left:50%;bottom:clamp(22px,3.6vh,38px);translate:-50% 0;z-index:80;
  font-family:var(--mono);font-size:9px;letter-spacing:.36em;color:var(--paper-3);
  opacity:0;transition:opacity 1.6s ease}
body.up #cue{opacity:1}
body.moved #cue{opacity:0}
#cue i{display:block;width:1px;height:30px;margin:11px auto 0;
  background:rgba(231,231,231,.2);position:relative;overflow:hidden}
#cue i::after{content:"";position:absolute;left:0;top:-100%;width:1px;height:100%;
  background:var(--paper);animation:cd 3s var(--slow) infinite}
@keyframes cd{to{top:100%}}

/* ══════════════════════════════════════════════
   五、內頁
   ══════════════════════════════════════════════ */
.page{padding-top:clamp(130px,19vh,210px)}
.wrap{width:min(1180px,calc(100vw - var(--gut) * 2));margin:0 auto}
.narrow{max-width:44em}

.prog{position:fixed;left:0;top:0;height:1px;z-index:90;background:var(--bronze);width:0}

.crumb{font-family:var(--mono);font-size:9.5px;letter-spacing:.3em;color:var(--paper-3);
  margin-bottom:clamp(24px,3.4vh,42px)}
.crumb b{font-weight:400;color:var(--bronze)}

.h1{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(31px,4.4vw,60px);line-height:1.42;letter-spacing:.22em;margin-left:.22em}
.h2{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(23px,2.9vw,38px);line-height:1.5;letter-spacing:.22em;margin-left:.22em}
.h3{font-family:var(--serif);font-weight:500;font-size:clamp(17px,1.7vw,22px);
  letter-spacing:.2em;color:var(--paper)}
.lede{font-size:clamp(14px,1.05vw,16px);line-height:2.3;color:var(--paper-2);
  letter-spacing:.07em;margin-top:clamp(24px,3.4vh,42px);max-width:40em}
.body p{font-size:14.5px;line-height:2.35;color:var(--paper-2);letter-spacing:.07em}
.body p+p{margin-top:1.6em}
.body b{font-weight:400;color:var(--paper)}

.sec{padding:clamp(72px,11vh,150px) 0}
.sec-hd{display:flex;align-items:baseline;gap:clamp(16px,2.6vw,38px);
  padding-bottom:22px;border-bottom:1px solid var(--hair-2);
  margin-bottom:clamp(38px,5.6vh,70px)}
.sec-hd .n{font-family:var(--mono);font-size:10px;letter-spacing:.3em;color:var(--bronze)}
.sec-hd .t{font-family:var(--serif);font-weight:500;font-size:clamp(18px,2.1vw,26px);
  letter-spacing:.2em}
.sec-hd .e{margin-left:auto;font-family:var(--mono);font-size:9px;letter-spacing:.28em;
  color:var(--paper-3)}
.rule{height:1px;background:var(--hair-2)}

/* 顯影 */
.rv{opacity:0;transform:translate3d(0,34px,0);
  transition:opacity 2.2s ease,transform 2s var(--vslow)}
.rv.on{opacity:1;transform:none}
.rv.d1{transition-delay:.18s}.rv.d2{transition-delay:.36s}
.rv.d3{transition-delay:.54s}.rv.d4{transition-delay:.72s}
/* 圖片顯影：遮幕整片滑出框，前緣那道亮線就是推刀 */
.rvi{position:relative;overflow:hidden;background:var(--ink-3)}
.rvi img{width:100%;height:100%;object-fit:cover;transform:scale(1.05);
  transition:transform 3.4s var(--vslow)}
.rvi.on img{transform:scale(1)}
.rvi::after{content:"";position:absolute;inset:0;z-index:2;background:var(--ink);
  transform:translate3d(0,0,0);
  transition:transform 2.3s var(--deep) .1s}
.rvi.on::after{transform:translate3d(0,101%,0)}
.rvi::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:3;
  background:linear-gradient(90deg,transparent,rgba(255,250,238,.9) 20%,
    rgba(255,250,238,.9) 80%,transparent);
  transform:translate3d(0,0,0);opacity:0;
  transition:transform 2.3s var(--deep) .1s,opacity .5s ease}
.rvi.on::before{transform:translate3d(0,var(--rh,420px),0);opacity:1}

/* 規格列（保留給日後補資料，目前僅用最少欄位） */
.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  gap:1px;background:var(--hair-2);border-top:1px solid var(--hair-2);
  border-bottom:1px solid var(--hair-2)}
.facts>div{background:var(--ink);padding:clamp(22px,3vw,34px) clamp(18px,2vw,26px)}
.facts b{display:block;font-family:var(--mono);font-weight:400;font-size:9px;
  letter-spacing:.28em;color:var(--bronze);margin-bottom:13px}
.facts strong{display:block;font-family:var(--serif);font-weight:500;font-size:17px;
  letter-spacing:.14em}

/* 建案索引 */
.plist{border-top:1px solid var(--hair-2)}
.pitem{display:grid;grid-template-columns:clamp(150px,20vw,290px) minmax(0,1fr) auto;
  gap:clamp(20px,3.4vw,54px);align-items:center;
  padding:clamp(18px,2.6vh,30px) 0;border-bottom:1px solid var(--hair-2);
  transition:background .9s ease}
.pitem:hover{background:rgba(231,231,231,.018)}
.pitem .th{aspect-ratio:16/10;overflow:hidden;background:var(--ink-3)}
.pitem .th img{width:100%;height:100%;object-fit:cover;
  filter:brightness(.78) saturate(.9);
  transition:transform 1.8s var(--slow),filter 1.2s ease}
.pitem:hover .th img{transform:scale(1.05);filter:brightness(1) saturate(1)}
.pitem .nm{font-family:var(--serif);font-weight:500;font-size:clamp(19px,2.1vw,27px);
  letter-spacing:.2em}
.pitem .mt{font-family:var(--mono);font-size:9.5px;letter-spacing:.24em;
  color:var(--paper-3);margin-top:12px}
.pitem .ar{font-family:var(--mono);font-size:9.5px;letter-spacing:.26em;
  color:var(--paper-3);transition:color .7s ease}
.pitem:hover .ar{color:var(--bronze)}

/* 團隊 */
.mb{padding:clamp(64px,10vh,130px) 0;border-top:1px solid var(--hair-2)}
.mb:first-of-type{border-top:0;padding-top:0}
.mb-top{display:grid;grid-template-columns:clamp(190px,22vw,300px) minmax(0,1fr);
  gap:clamp(28px,5vw,80px);align-items:start}
.mb.nofoto .mb-top{grid-template-columns:clamp(150px,17vw,220px) minmax(0,1fr)}
.mb-ph{position:relative;aspect-ratio:3/4;overflow:hidden;background:var(--ink-3);
  border:1px solid var(--hair-2)}
/* 棚拍白底在黑色網站上會變成一塊漏光。壓成近單色再收暗，才收得進這個調子。 */
.mb-ph img{width:100%;height:100%;object-fit:cover;object-position:var(--op,center 22%);
  transform:scaleX(var(--flip,1));
  filter:grayscale(.42) contrast(1.04) brightness(.8)}
/* 無照片時用一枚字碑代替，不留醜的灰框 */
/* ── 沒有頭貼的人，換一種版式 ──────────────────────
   不留空位、也不拿字碑假裝有照片。整列拿掉左欄，名字放到最大、
   橫過整個版心，視覺重量交給下方的作品／版圖帶去扛。
   於是四個人的節奏變成：圖文、圖文、大字、大字——是編排，不是缺角。 */
.mb.nofoto .mb-top{grid-template-columns:minmax(0,1fr);gap:0}
.mb.nofoto .mb-nm{font-size:clamp(40px,6.6vw,96px);letter-spacing:.18em;
  margin:clamp(16px,2.4vh,28px) 0 0 .18em;line-height:1.16}
.mb.nofoto .mb-lat{margin-top:20px;font-size:10.5px;letter-spacing:.34em}
.mb.nofoto .mb-ti{margin-top:clamp(24px,3.4vh,40px);
  padding-top:clamp(20px,2.8vh,30px);font-size:14px}
.mb.nofoto .mb-bio{max-width:none;margin-top:clamp(22px,3vh,34px);
  columns:2;column-gap:clamp(36px,5.4vw,88px)}
.mb.nofoto .mb-bio p{break-inside:avoid}
.mb.nofoto .mb-bio p+p{margin-top:1.5em}
@media (max-width:820px){
  .mb.nofoto .mb-bio{columns:1}
  .mb.nofoto .mb-nm{font-size:clamp(34px,10vw,52px)}
}

.mb-no{font-family:var(--mono);font-size:9px;letter-spacing:.3em;color:var(--bronze)}
.mb-nm{font-family:var(--serif);font-weight:500;font-size:clamp(28px,3.4vw,46px);
  letter-spacing:.26em;margin:clamp(14px,2vh,20px) 0 0 .26em}
.mb-lat{font-family:var(--mono);font-size:9.5px;letter-spacing:.3em;color:var(--paper-3);
  margin-top:13px}
.mb-ti{margin-top:clamp(16px,2.2vh,24px);padding-top:clamp(14px,2vh,20px);
  border-top:1px solid var(--hair);font-size:13px;letter-spacing:.1em;color:var(--bronze);
  line-height:1.95}
.mb-bio{margin-top:clamp(16px,2.4vh,26px);max-width:42em}
.mb-bio p{font-size:14px;line-height:2.3;color:var(--paper-2);letter-spacing:.07em}
.mb-bio p+p{margin-top:1.4em}
.chips{display:flex;flex-wrap:wrap;gap:0 3px;margin-top:clamp(20px,2.8vh,30px);
  padding-top:4px;border-top:1px solid var(--hair-2)}
.chips span{font-size:11.5px;letter-spacing:.1em;color:var(--paper-2);
  padding:9px 18px;border-left:1px solid var(--hair);line-height:1.6}

/* 事務所作品（明確與璞玥自有案分開） */
.wks{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;
  background:var(--hair-2);margin-top:clamp(26px,3.6vh,44px)}
.wk{background:var(--ink);display:block}
.wk .im{aspect-ratio:3/4;overflow:hidden;background:var(--ink-3)}
.wk .im img{width:100%;height:100%;object-fit:cover;
  filter:brightness(.74) saturate(.86);transition:filter 1.3s ease,transform 1.8s var(--slow)}
.wk:hover .im img{filter:brightness(.96) saturate(1);transform:scale(1.04)}
.wk .tx{padding:16px 16px 22px}
.wk .tg{font-family:var(--mono);font-size:8.5px;letter-spacing:.24em;color:var(--bronze)}
.wk .nm{font-family:var(--serif);font-weight:500;font-size:16px;letter-spacing:.14em;margin-top:10px}
.wk .lc{font-size:11.5px;color:var(--paper-3);letter-spacing:.08em;margin-top:8px}
.wks.c3{grid-template-columns:repeat(3,minmax(0,1fr))}
.wks.c2{grid-template-columns:repeat(2,minmax(0,1fr))}
.wks.vent .im{aspect-ratio:16/10}
.wk .ds{font-size:12px;line-height:1.95;color:var(--paper-2);margin-top:10px;letter-spacing:.04em}
.wk .lk{display:block;margin-top:13px;font-family:var(--mono);font-size:9px;
  letter-spacing:.16em;color:var(--bronze);transition:color .6s ease;
  overflow-wrap:anywhere;word-break:break-word}
.wk .lk:hover{color:var(--bronze-hi)}
.wk.txt-only{display:flex;align-items:center;background:var(--ink-2)}
.wk.txt-only .tx{padding:clamp(22px,3vw,36px)}
.note{margin-top:clamp(20px,2.8vh,30px);padding:clamp(16px,2.2vw,24px);
  border:1px solid var(--hair-2);font-size:12px;line-height:2.05;color:var(--paper-3)}

/* 洽詢 */
.form{display:grid;gap:clamp(20px,2.8vh,30px);max-width:600px}
.fld label{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.26em;
  color:var(--paper-3);margin-bottom:11px}
.fld input,.fld textarea{width:100%;background:transparent;border:0;
  border-bottom:1px solid var(--hair);color:var(--paper);
  font-family:var(--sans);font-weight:300;font-size:14.5px;letter-spacing:.06em;
  padding:11px 0;transition:border-color .7s ease}
.fld textarea{resize:vertical;min-height:110px;line-height:2}
.fld input:focus,.fld textarea:focus{outline:0;border-bottom-color:var(--bronze)}
.submit{display:inline-flex;align-items:center;gap:13px;
  font-family:var(--mono);font-size:10px;letter-spacing:.32em;color:var(--paper);
  position:relative;padding:14px 0 14px 15px;transition:color .7s ease}
.submit::before{content:"";position:absolute;left:0;top:50%;translate:0 -50%;
  width:1px;height:13px;background:var(--bronze);transition:height .8s var(--slow)}
.submit:hover{color:var(--bronze)}
.submit:hover::before{height:24px}

/* 頁尾 */
footer{border-top:1px solid var(--hair-2);margin-top:clamp(60px,9vh,120px);
  padding:clamp(50px,7vh,86px) 0 44px}
.ft{display:grid;grid-template-columns:1.6fr 1fr 1fr;gap:clamp(26px,4.6vw,70px)}
.ft .b{font-family:var(--serif);font-weight:500;font-size:17px;letter-spacing:.36em}
/* 頁尾這一組是同一個標準字的縮小版，字也要跟著換，不然兩處會像兩間公司 */
.ft .be{font-family:var(--latin);font-weight:600;font-size:13px;letter-spacing:.3em;
  text-indent:.3em;color:var(--bronze);margin-top:10px}
.ft p{font-size:12.5px;line-height:2.1;color:var(--paper-3);margin-top:18px;max-width:24em;
  letter-spacing:.06em}
.ft h5{font-family:var(--mono);font-size:9px;letter-spacing:.3em;color:var(--paper-3);
  font-weight:400;margin-bottom:18px}
.ft a,.ft span.li{display:block;font-size:12.5px;color:var(--paper-2);padding:6px 0;
  letter-spacing:.1em;transition:color .6s ease}
.ft a:hover{color:var(--bronze)}
.ft-b{margin-top:clamp(38px,5vh,60px);padding-top:22px;border-top:1px solid var(--hair-2);
  display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;
  font-family:var(--mono);font-size:9px;letter-spacing:.2em;color:var(--paper-3)}

/* ══════════════════════════════════════════════
   六、響應
   ══════════════════════════════════════════════ */
@media (max-width:1000px){
  .wks{grid-template-columns:repeat(2,minmax(0,1fr))}
    .ft{grid-template-columns:1fr;gap:32px}
}
@media (max-width:760px){
  #vidx{display:none}
  .scr .cap{right:var(--gut);max-width:none;bottom:clamp(84px,14vh,120px)}
  .scr h2{letter-spacing:.16em;margin-left:.16em}
  .h1,.h2{letter-spacing:.16em;margin-left:.16em}
  .mb-top,.mb.nofoto .mb-top{grid-template-columns:minmax(0,1fr);gap:24px}
  .mb-ph,    .pitem{grid-template-columns:minmax(0,1fr);gap:16px}
  .pitem .ar{display:none}
  #ov .act{white-space:normal;text-align:center;width:80vw;letter-spacing:.24em;margin-left:.24em}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important}
  .rv{opacity:1;transform:none}
  .rvi::after,.rvi::before{display:none}
  .full .on-band>*{opacity:1;transform:none}
  .scr .ph img{opacity:1;transform:none}
  .scr h2 i{opacity:1;transform:none}
}

/* ════════════════════════════════════════════════════════════════════
   七、案件樹　THE PIPELINE TREE
   ────────────────────────────────────────────────────────────────────
   種子在下、樹幹往上長、每個亮起的節點是一個正在進行的案子。
   上半是那棵樹；下半順著同一條樹幹往下展開，每個節點接住一個案子的照片。
   一張圖變成整頁的骨架。

   進場動畫全部是一次性的（stroke-dashoffset ／ transform ／ opacity），
   沒有 blur、沒有無限循環的描邊動畫。
   ════════════════════════════════════════════════════════════════════ */
.treesec{position:relative;padding:clamp(30px,5vh,70px) 0 clamp(20px,4vh,50px)}
.ptree{display:block;width:100%;height:auto;max-height:76vh;margin:0 auto;overflow:visible}

.ptree .ground{stroke:var(--paper);stroke-width:.8;opacity:0;
  transition:opacity 1.6s ease .2s}
.on .ptree .ground{opacity:.13}

.ptree .seed{transform-box:fill-box;transform-origin:center;transform:scale(0);
  transition:transform 1.1s cubic-bezier(.2,1.35,.35,1) .35s}
.on .ptree .seed{transform:scale(1)}

.ptree .trunk{stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset 3.4s cubic-bezier(.45,0,.2,1) .8s}
.on .ptree .trunk{stroke-dashoffset:0}

.ptree .branch{stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset 1.5s cubic-bezier(.35,0,.2,1) var(--bd)}
.on .ptree .branch{stroke-dashoffset:0}

.ptree .node{transform-box:fill-box;transform-origin:center;transform:scale(0);
  transition:transform 1s cubic-bezier(.2,1.4,.35,1) var(--nd)}
.on .ptree .node{transform:scale(1)}

.ptree .bud{transform-box:fill-box;transform-origin:center;transform:scale(0);
  transition:transform .9s cubic-bezier(.2,1.4,.35,1) var(--bd2)}
.on .ptree .bud{transform:scale(1)}

.ptree .halo{opacity:0;transition:opacity 2.4s ease 3.4s}
.on .ptree .halo{opacity:1}
.ptree .bloom{transform-box:fill-box;transform-origin:center;transform:scale(0);
  transition:transform 1.3s cubic-bezier(.2,1.35,.35,1) 3.5s}
.on .ptree .bloom{transform:scale(1)}
/* 樹冠那一點光很慢地呼吸——整張圖唯一持續的動作，而且只動 opacity */
.on .ptree .bloom-ring{animation:bloomBreathe 7s ease-in-out infinite 4.6s}
@keyframes bloomBreathe{0%,100%{opacity:.16}50%{opacity:.46}}

.ptree .lead{stroke-dasharray:1;stroke-dashoffset:1;stroke:var(--bronze);stroke-width:.7;
  opacity:.55;transition:stroke-dashoffset 1.1s ease var(--ld)}
.on .ptree .lead{stroke-dashoffset:0}
.ptree .ldot{opacity:0;transition:opacity .9s ease var(--ld)}
.on .ptree .ldot{opacity:1}
.ptree .ltag,.ptree .lmain{opacity:0;transition:opacity 1.5s ease var(--ld)}
.on .ptree .ltag,.on .ptree .lmain{opacity:1}
.ptree .ltag{fill:var(--bronze);font-family:var(--mono);font-size:8.6px;letter-spacing:.22em}
.ptree .lmain{fill:var(--paper);font-family:var(--serif);font-weight:500;
  font-size:16px;letter-spacing:.16em}
.ptree .lsub{fill:var(--paper-2);font-family:var(--sans);font-weight:300;
  font-size:10.5px;letter-spacing:.1em}
.ptree a{cursor:pointer}
.ptree a .lmain{transition:opacity 1.5s ease var(--ld),fill .6s ease}
.ptree a:hover .lmain{fill:var(--bronze-hi)}

/* ── 展開：同一條樹幹往下走，每個節點接一個案子 ── */
.tl{--sp:clamp(20px,4.6vw,76px);position:relative;padding-left:var(--sp)}
.tl-line{position:absolute;left:0;top:0;bottom:0;width:1px;background:var(--hair-2)}
.tl-line i{position:absolute;left:0;top:0;width:1px;height:100%;
  background:linear-gradient(180deg,var(--bronze-hi),var(--bronze) 26%,var(--bronze-d,#7a6238));
  transform:scaleY(0);transform-origin:top center;will-change:transform}
.tl-row{position:relative;padding:clamp(56px,9vh,128px) 0}
.tl-row:first-child{padding-top:clamp(30px,5vh,64px)}
.tl-row .dot{position:absolute;left:calc(var(--sp) * -1 - 4.5px);
  top:clamp(58px,9.2vh,130px);width:10px;height:10px;border-radius:50%;
  background:var(--ink);border:1px solid var(--bronze);
  transform:scale(.5);opacity:.35;
  transition:transform 1.2s var(--vslow),opacity 1.2s ease,background .9s ease}
.tl-row:first-child .dot{top:clamp(32px,5.2vh,66px)}
.tl-row.on .dot{transform:scale(1);opacity:1;background:var(--bronze-hi)}
.tl-row .dot::after{content:"";position:absolute;left:50%;top:50%;
  width:30px;height:30px;margin:-15px 0 0 -15px;border-radius:50%;
  border:1px solid var(--bronze);opacity:0;
  transition:opacity 1.4s ease .5s,transform 1.6s var(--vslow) .5s;transform:scale(.6)}
.tl-row.on .dot::after{opacity:.28;transform:scale(1)}

.tl-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:clamp(26px,4.4vw,72px);align-items:center}
.tl-row:nth-child(even) .tl-grid{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr)}
.tl-row:nth-child(even) .tl-ph{order:2}
.tl-ph{aspect-ratio:16/10}
.tl-no{font-family:var(--mono);font-size:9.5px;letter-spacing:.3em;color:var(--bronze)}
.tl-nm{font-family:var(--serif);font-weight:500;font-size:clamp(26px,3.3vw,44px);
  letter-spacing:.2em;margin:clamp(14px,2vh,20px) 0 0 .2em;line-height:1.36}
.tl-mt{font-family:var(--mono);font-size:9.5px;letter-spacing:.24em;color:var(--paper-3);
  margin-top:clamp(14px,2vh,20px);padding-top:clamp(12px,1.8vh,18px);
  border-top:1px solid var(--hair-2)}
.tl-ds{font-size:13.5px;line-height:2.25;color:var(--paper-2);letter-spacing:.06em;
  margin-top:clamp(14px,2vh,20px);max-width:32em}

@media (max-width:820px){
  .tl-grid,.tl-row:nth-child(even) .tl-grid{grid-template-columns:minmax(0,1fr);gap:22px}
  .tl-row:nth-child(even) .tl-ph{order:0}
  .ptree{max-height:none}
  .ptree .lmain{font-size:19px}
  .ptree .ltag{font-size:10px}
  .ptree .lsub{font-size:12px}
}

/* 窄螢幕：卡片改單欄。兩欄時寬度只剩 170px，長網址會撐破版面。 */
@media (max-width:640px){
  .wks,.wks.c2,.wks.c3,.wks.c4{grid-template-columns:minmax(0,1fr)}
  .wk .lk{font-size:9.5px;letter-spacing:.1em}
}


/* ════════════════════════════════════════════════════════════════════
   八、編輯式版面　EDITORIAL
   ────────────────────────────────────────────────────────────────────
   給客戶看的頁面：照片大、留白多、字少而準。
   不畫圖解、不玩觀念——版面本身就是設計。
   ════════════════════════════════════════════════════════════════════ */

/* 滿版影像：整片出血，上下留很大的呼吸 */
.full{position:relative;width:100vw;margin-left:calc(50% - 50vw);overflow:hidden;background:#000}
.full img{width:100%;height:auto;display:block}
.full.tall{height:min(92vh,940px)}
.full.tall img{height:100%;object-fit:cover;object-position:var(--op,center)}
.full .veil{position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.60) 0%,rgba(0,0,0,.10) 32%,
    rgba(0,0,0,.30) 62%,rgba(0,0,0,.80) 100%)}
.full .on-band{position:absolute;z-index:3;left:var(--gut);right:var(--gut);
  bottom:clamp(40px,7vh,88px)}

/* 建案首屏：影像極慢收合，字一段一段浮上。一次性動畫，只動 transform／opacity。 */
@keyframes heroIn{from{transform:scale(1.075)}to{transform:scale(1)}}
@keyframes heroCap{from{opacity:0;transform:translate3d(0,26px,0)}to{opacity:1;transform:none}}
.full.tall img{animation:heroIn 6s var(--vslow) both}
.full .on-band>*{animation:heroCap 1.7s var(--vslow) both}
.full .on-band>*:nth-child(1){animation-delay:.30s}
.full .on-band>*:nth-child(2){animation-delay:.52s}
.full .on-band>*:nth-child(3){animation-delay:.78s}
/* 首屏下緣的細線：往下走完就停 */
.full .on-band .hair{height:1px;background:linear-gradient(90deg,
  rgba(232,219,190,.75),rgba(232,219,190,0));transform-origin:0 50%;
  animation:heroRule 2.2s var(--vslow) .95s both}
@keyframes heroRule{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* 一句話：大字、極大留白。整頁的呼吸點。 */
.say{padding:clamp(90px,20vh,240px) 0;text-align:center}
.say p{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(22px,3.4vw,46px);line-height:1.85;letter-spacing:.2em;
  margin:0 auto;max-width:22em}
.say .sub{margin-top:clamp(26px,4vh,52px);font-family:var(--mono);font-size:9.5px;
  letter-spacing:.3em;color:var(--bronze)}
.say.left{text-align:left}
.say.left p{margin-left:0}

/* 圖組：兩張並置，刻意不等高 */
.pair{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(14px,2.2vw,38px);align-items:end}
.pair .hi{margin-bottom:clamp(30px,7vh,90px)}
.figc{font-family:var(--mono);font-size:9px;letter-spacing:.22em;color:var(--paper-3);
  margin-top:13px}

.pair figure{margin:0}
.pair .ph-box{aspect-ratio:16/9}
.pair figure.tall .ph-box{aspect-ratio:3/4}
@media (max-width:700px){
  .pair{grid-template-columns:minmax(0,1fr);gap:clamp(18px,4vh,34px)}
  .pair .hi{margin-bottom:0}
}

/* 偏移大圖：圖靠一邊出血，另一邊留給文字 */
.off{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.55fr);
  gap:clamp(24px,4.6vw,84px);align-items:center}
.off.r{grid-template-columns:minmax(0,1.55fr) minmax(0,1fr)}
.off.r .off-tx{order:2}
.off-tx h3{font-family:var(--serif);font-weight:500;
  font-size:clamp(19px,2.2vw,29px);letter-spacing:.2em;line-height:1.6;margin-left:.2em}
.off-tx p{font-size:13.5px;line-height:2.3;color:var(--paper-2);letter-spacing:.06em;
  margin-top:clamp(18px,2.6vh,28px)}
.off-tx .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.3em;color:var(--bronze);
  margin-bottom:clamp(16px,2.2vh,24px)}

/* 事實列：只有該公開的三格 */
.spec{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  border-top:1px solid var(--hair-2);border-bottom:1px solid var(--hair-2)}
.spec>div{padding:clamp(26px,4vh,44px) 0;border-left:1px solid var(--hair-2);
  padding-left:clamp(20px,3vw,42px)}
.spec>div:first-child{border-left:0;padding-left:0}
/* 佔滿一整列的那一格（聯絡頁的地址：一行放得下，不要自己孤零零留在第二列的
   第一欄，右邊空一大片）。**不要叫 .full** —— 那個名字已經被滿版元件佔走了。 */
.spec>div.sp-w{grid-column:1 / -1;border-left:0;padding-left:0;
  border-top:1px solid var(--hair-2)}
.spec b{display:block;font-family:var(--mono);font-weight:400;font-size:9px;
  letter-spacing:.28em;color:var(--bronze);margin-bottom:16px}
.spec strong{display:block;font-family:var(--serif);font-weight:500;
  font-size:clamp(17px,1.9vw,24px);letter-spacing:.16em}

/* 下一個案子 */
.nextp{position:relative;display:block;width:100vw;margin-left:calc(50% - 50vw);
  height:min(56vh,520px);overflow:hidden;background:#000}
.nextp img{width:100%;height:100%;object-fit:cover;object-position:var(--op,center);
  filter:brightness(.44) saturate(.85);transition:filter 1.6s var(--vslow),transform 2.4s var(--vslow)}
.nextp:hover img{filter:brightness(.72) saturate(1);transform:scale(1.03)}
.nextp .lb{position:absolute;inset:0;display:grid;place-items:center;text-align:center}
.nextp .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.32em;color:var(--bronze)}
.nextp .t{font-family:var(--serif);font-weight:500;font-size:clamp(26px,3.4vw,46px);
  letter-spacing:.24em;margin-top:18px}

/* 中景滿版：換氣用，不必到滿屏那麼高 */
.full.mid{height:min(64vh,620px)}
.full.mid img{height:100%;object-fit:cover;object-position:var(--op,center)}

/* ── 材質標本：四片表面，全部用 CSS 疊出來，沒有一張貼圖 ──────
   游標移上去，那道高光跟著手走＝換一個入射角。
   高光只寫 transform（位移一個固定尺寸的漸層圓），不逐幀重畫漸層。 */
.mlab{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(10px,1.4vw,22px)}
.mat{position:relative;margin:0}
/* 高光與表面都關在這一層裡，放大或位移都不會溢出去 */
.mat .pl{position:relative;display:block;overflow:hidden}
.mat .surf{position:relative;display:block;aspect-ratio:3/4;
  background:var(--ink-3);transition:transform 1.2s var(--vslow)}
.mat .spec-l{position:absolute;left:0;top:0;z-index:2;width:520px;height:520px;
  margin:-260px 0 0 -260px;pointer-events:none;opacity:0;
  background:radial-gradient(circle,rgba(255,250,238,.20) 0%,rgba(255,250,238,.07) 30%,
    rgba(255,250,238,.02) 52%,transparent 70%);
  transition:opacity .9s ease;will-change:transform}
.mat:hover .spec-l{opacity:1}
.mat figcaption{display:block;padding-top:15px}
.mat .mn{display:block;font-family:var(--serif);font-weight:500;font-size:15px;
  letter-spacing:.18em}
.mat .me{display:block;font-family:var(--mono);font-size:8.5px;letter-spacing:.24em;
  color:var(--bronze);margin-top:7px}
.mat .mx{display:block;font-size:12px;line-height:2.05;color:var(--paper-3);
  letter-spacing:.05em;margin-top:11px}
/* 微水泥：雲斑，低對比 */
.m-cement .surf{background:
  radial-gradient(60% 44% at 26% 22%,rgba(255,255,255,.09),transparent 62%),
  radial-gradient(52% 40% at 74% 68%,rgba(255,255,255,.06),transparent 60%),
  radial-gradient(46% 52% at 52% 92%,rgba(0,0,0,.28),transparent 64%),
  linear-gradient(168deg,#787571,#5f5c58 58%,#514f4c)}
/* 手刮鋼刷木皮：不等寬條紋＋順紋刷痕 */
.m-wood .surf{background:
  repeating-linear-gradient(93deg,rgba(0,0,0,.22) 0 2px,transparent 2px 7px,
    rgba(255,255,255,.05) 7px 8px,transparent 8px 17px),
  repeating-linear-gradient(93deg,#6b4b32 0 26px,#5c3f29 26px 41px,#75543a 41px 63px,
    #573a26 63px 88px),
  linear-gradient(#6b4b32,#4d3422)}
/* 奢石：礦脈是天生的，只能挑不能改。粗細與走向都刻意不一致。 */
.m-stone .surf{background:
  linear-gradient(72deg,transparent 37.2%,rgba(255,252,244,.50) 38.3%,
    rgba(255,252,244,.16) 39.1%,transparent 40.2%),
  linear-gradient(66deg,transparent 51%,rgba(255,250,238,.26) 51.7%,transparent 52.6%),
  linear-gradient(84deg,transparent 62%,rgba(226,214,190,.30) 63.1%,transparent 64.4%),
  linear-gradient(104deg,transparent 27%,rgba(210,198,172,.20) 27.9%,transparent 29%),
  linear-gradient(58deg,transparent 74%,rgba(255,250,238,.14) 74.8%,transparent 75.8%),
  radial-gradient(78% 60% at 30% 26%,rgba(255,255,255,.16),transparent 68%),
  radial-gradient(64% 50% at 76% 82%,rgba(0,0,0,.34),transparent 66%),
  linear-gradient(158deg,#575349,#413d35 58%,#2e2b25)}
/* 鈦金屬：方向性很強。髮絲紋一律同向，明暗帶要平，不然會像圓管。 */
.m-titan .surf{background:
  repeating-linear-gradient(95deg,rgba(255,255,255,.06) 0 1px,transparent 1px 3px),
  repeating-linear-gradient(95deg,rgba(0,0,0,.05) 0 1px,transparent 1px 7px),
  linear-gradient(95deg,#585e63 0%,#7c8388 22%,#646a6f 41%,#868d92 58%,
    #5d6368 78%,#71787d 100%)}

/* 流程：一條線 ＋ 五個站，看得懂就好 */
.flow{border-top:1px solid var(--hair-2);margin-top:clamp(30px,5vh,64px)}
.flow-i{display:grid;grid-template-columns:clamp(52px,7vw,96px) minmax(0,1fr);
  gap:clamp(18px,3vw,48px);align-items:baseline;
  padding:clamp(24px,4vh,44px) 0;border-bottom:1px solid var(--hair-2)}
.flow-i .n{font-family:var(--mono);font-size:10px;letter-spacing:.24em;color:var(--bronze)}
.flow-i h4{font-family:var(--serif);font-weight:500;font-size:clamp(17px,1.9vw,23px);
  letter-spacing:.2em}
.flow-i p{font-size:13px;line-height:2.2;color:var(--paper-3);margin-top:12px;max-width:34em}

@media (max-width:820px){
  .pair,.off,.off.r{grid-template-columns:minmax(0,1fr);gap:22px}
  .off.r .off-tx{order:0}
  .pair .hi{margin-bottom:0}
  .spec{grid-template-columns:minmax(0,1fr)}
  .spec>div{border-left:0;padding-left:0;border-top:1px solid var(--hair-2)}
  .spec>div:first-child{border-top:0}
  .full.tall{height:64vh}
  .full.mid{height:42vh}
  .flow-i{grid-template-columns:minmax(0,1fr);gap:6px}

  .mlab{grid-template-columns:repeat(2,minmax(0,1fr))}
  .mat .surf{aspect-ratio:1/1}
}




/* ════════════════════════════════════════════════════════════════════
   九、電影感　CINEMA
   ──────────────────────────────────────────────────────────────────
   一套有版式變化的沉浸語彙。核心判斷：滿版影像一頁只能出現兩三次，
   多了就變成投影片。其餘的時候，影像要小、要準、要被黑包住——
   留白比影像更決定質感。

   版式：
   .stage  開場定格　影像從 1.14 慢慢落定到 1，標題字距同時收緊
   .split  不對稱分割　影像出血一側，文字站另一側
   .plate  裱框影像　小、置中、被大量黑包住，外面掛一行 mono 說明
   .strip  橫向影像帶　垂直捲動換成水平推移
   .hold   沾黏字幕　標題釘住不動，影像從旁邊走過
   .cine   滿版　留給真正的高潮

   效能：全部只寫 transform 與 opacity；位置只量一次；
   位移量取整數、同值不重寫；不在視窗附近的直接跳過。
   ════════════════════════════════════════════════════════════════════ */

/* ── 共用：影像容器與運鏡 ── */
.ph-box{position:relative;overflow:hidden;background:var(--ink-3)}
.ph-box>img{width:100%;height:100%;object-fit:cover;display:block;
  will-change:transform;transform:translate3d(0,0,0)}
.ph-box.tallim{position:absolute;left:0;right:0;top:-7%;bottom:-7%}

/* 推刀顯影：一片黑從影像上退開，前緣帶一道亮線 */
.ph-box::before{content:"";position:absolute;inset:0;z-index:4;background:var(--ink);
  transform:translate3d(0,0,0);transition:transform 1.9s var(--deep);pointer-events:none}
.ph-box::after{content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:5;
  background:linear-gradient(90deg,transparent,rgba(232,220,196,.7),transparent);
  opacity:0;transition:opacity .5s ease;pointer-events:none}
.on .ph-box::before,.ph-box.on::before{transform:translate3d(0,-101%,0)}
.on .ph-box::after,.ph-box.on::after{opacity:0;transition:opacity 1.4s ease 1.2s}

/* ── 開場定格 ── */
.stage{position:relative;width:100vw;margin-left:calc(50% - 50vw);
  height:100vh;min-height:520px;overflow:hidden;background:#000}
.stage .im{position:absolute;inset:0;overflow:hidden}
.stage .im img{width:100%;height:100%;object-fit:cover;display:block;
  transform:scale(1.10);transform-origin:50% 52%;will-change:transform}
.stage::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(to bottom,rgba(0,0,0,.66) 0%,rgba(0,0,0,.1) 28%,
    rgba(0,0,0,.08) 52%,rgba(0,0,0,.9) 100%)}
.stage .tx{position:absolute;left:var(--gut);right:var(--gut);bottom:clamp(58px,10vh,124px);z-index:3}
.stage .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.36em;color:var(--bronze);
  opacity:0;transition:opacity 1.6s ease .5s}
.stage h1{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(30px,5.6vw,78px);line-height:1.34;margin-top:clamp(14px,2vh,22px);
  letter-spacing:.42em;opacity:0;
  transition:opacity 2.4s ease .2s,letter-spacing 2.8s var(--vslow) .2s}
.stage .sub{margin-top:clamp(16px,2.4vh,26px);font-size:13.5px;line-height:2.2;
  color:var(--paper-2);letter-spacing:.06em;max-width:26em;
  opacity:0;transform:translate3d(0,16px,0);
  transition:opacity 1.8s var(--vslow) .9s,transform 1.8s var(--vslow) .9s}
body.up .stage .k{opacity:1}
body.up .stage h1{opacity:1;letter-spacing:.16em}
body.up .stage .sub{opacity:1;transform:none}
.stage .scr{position:absolute;left:50%;bottom:clamp(20px,3vh,34px);translate:-50% 0;z-index:3;
  font-family:var(--mono);font-size:8.5px;letter-spacing:.34em;color:var(--paper-3);
  opacity:0;transition:opacity 1.4s ease 1.8s}
body.up .stage .scr{opacity:.9}

/* ── 不對稱分割 ── */
.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  align-items:center;gap:clamp(30px,5vw,88px);
  width:100vw;margin-left:calc(50% - 50vw);
  padding:clamp(60px,11vh,140px) var(--gut) clamp(60px,11vh,140px) 0}
.split.r{grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);
  padding:clamp(60px,11vh,140px) 0 clamp(60px,11vh,140px) var(--gut)}
.split.r .sp-im{order:2}
.split .sp-im{position:relative;aspect-ratio:4/5;max-height:82vh}
.split .sp-tx{max-width:30em}
.split .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.32em;color:var(--bronze)}
.split h3{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(23px,3.2vw,42px);letter-spacing:.18em;line-height:1.5;margin-top:15px}
.split p{font-size:13.5px;line-height:2.3;color:var(--paper-2);letter-spacing:.06em;margin-top:clamp(16px,2.4vh,26px)}
.split .sp-tx>*{opacity:0;transform:translate3d(0,20px,0);
  transition:opacity 1.7s var(--vslow),transform 1.7s var(--vslow)}
.split.on .sp-tx>*{opacity:1;transform:none}
.split .sp-tx>*:nth-child(2){transition-delay:.16s}
.split .sp-tx>*:nth-child(3){transition-delay:.32s}
@media (max-width:860px){
  .split,.split.r{grid-template-columns:1fr;padding:clamp(46px,8vh,90px) var(--gut);gap:clamp(24px,5vh,44px)}
  .split.r .sp-im{order:0}
  .split .sp-im{aspect-ratio:3/2;max-height:none}
}

/* ── 裱框影像：小、準、被黑包住 ── */
.plate{padding:clamp(64px,13vh,170px) var(--gut);text-align:center}
.plate figure{margin:0 auto;max-width:min(560px,80vw)}
.plate.wide figure{max-width:min(980px,90vw)}
.plate .ph-box{aspect-ratio:3/4;border:1px solid var(--hair-2)}
.plate.wide .ph-box{aspect-ratio:16/9}
.plate figcaption{margin-top:clamp(16px,2.4vh,26px);
  font-family:var(--mono);font-size:9px;letter-spacing:.3em;color:var(--paper-3)}
.plate figcaption b{display:block;font-family:var(--serif);font-weight:500;font-size:15px;
  letter-spacing:.24em;color:var(--paper-2);margin-bottom:9px}

/* ── 橫向影像帶：垂直捲動換成水平推移 ── */
.strip{position:relative;overflow:hidden;padding:clamp(48px,9vh,110px) 0}
.strip .rail{display:flex;gap:clamp(14px,2vw,30px);padding:0 var(--gut);
  will-change:transform;transform:translate3d(0,0,0)}
.strip .card{flex:0 0 clamp(230px,26vw,340px);position:relative}
.strip .card .num{font-family:var(--mono);font-size:9.5px;letter-spacing:.3em;color:var(--bronze)}
.strip .card h4{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(18px,2vw,25px);letter-spacing:.2em;margin:12px 0 0}
.strip .card p{font-size:12.5px;line-height:2.15;color:var(--paper-2);letter-spacing:.05em;margin-top:13px}
.strip .card .rule{height:1px;background:var(--hair-2);margin:clamp(18px,2.6vh,28px) 0 clamp(14px,2vh,20px);
  position:relative;overflow:hidden}
.strip .card .rule i{position:absolute;inset:0;background:var(--bronze);
  transform:scaleX(0);transform-origin:0 50%;transition:transform 1.4s var(--vslow)}
.strip.on .card .rule i{transform:scaleX(1)}
.strip.on .card:nth-child(2) .rule i{transition-delay:.12s}
.strip.on .card:nth-child(3) .rule i{transition-delay:.24s}
.strip.on .card:nth-child(4) .rule i{transition-delay:.36s}
.strip.on .card:nth-child(5) .rule i{transition-delay:.48s}
@media (max-width:700px){.strip .card{flex:0 0 74vw}}

/* ── 沾黏字幕 ── */
.hold{position:relative;display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);
  gap:clamp(30px,5vw,80px);padding:0 var(--gut)}
.hold .hd{position:sticky;top:0;height:100vh;display:flex;flex-direction:column;
  justify-content:center;align-self:start}
.hold .hd .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.32em;color:var(--bronze)}
.hold .hd h3{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(24px,3.4vw,46px);letter-spacing:.18em;line-height:1.5;margin-top:16px}
.hold .hd p{font-size:13px;line-height:2.25;color:var(--paper-2);margin-top:20px;max-width:22em}
.hold .stack>figure{margin:0 0 clamp(20px,4vh,54px)}
.hold .stack .ph-box{aspect-ratio:4/5}
.hold .stack figcaption{margin-top:12px;font-family:var(--mono);font-size:9px;
  letter-spacing:.26em;color:var(--paper-3)}
.hold .stack{padding:clamp(60px,12vh,150px) 0}
@media (max-width:860px){
  .hold{grid-template-columns:1fr;gap:0}
  .hold .hd{position:static;height:auto;padding:clamp(50px,9vh,100px) 0 clamp(20px,4vh,40px)}
  .hold .stack{padding:0 0 clamp(50px,9vh,100px)}
}

/* ── 滿版：留給高潮 ── */
.cine{position:relative;width:100vw;margin-left:calc(50% - 50vw);
  height:100vh;min-height:480px;overflow:hidden;background:#000}
.cine.mid{height:min(78vh,760px)}
.cine .im{position:absolute;left:0;right:0;top:-7%;bottom:-7%;overflow:hidden}
.cine .im img{width:100%;height:100%;object-fit:cover;display:block;
  will-change:transform;transform:translate3d(0,0,0)}
.cine::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
  background:linear-gradient(to bottom,rgba(0,0,0,.6) 0%,rgba(0,0,0,.12) 24%,
    rgba(0,0,0,.06) 46%,rgba(0,0,0,.86) 100%)}
.cine.ctr::after{background:radial-gradient(ellipse 62% 54% at 50% 50%,
    rgba(0,0,0,.82) 0%,rgba(0,0,0,.54) 46%,rgba(0,0,0,.18) 74%,transparent 92%),
  linear-gradient(to bottom,rgba(0,0,0,.5) 0%,transparent 24%,transparent 66%,rgba(0,0,0,.74) 100%)}
.cine .tx{position:absolute;left:var(--gut);right:var(--gut);z-index:3;
  bottom:clamp(52px,9vh,112px);max-width:min(620px,80vw)}
.cine.ctr .tx{left:0;right:0;margin:0 auto;text-align:center;max-width:min(700px,86vw);
  top:50%;bottom:auto;transform:translateY(-50%)}
.cine .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.34em;color:var(--bronze)}
.cine h2{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(25px,3.9vw,52px);letter-spacing:.16em;line-height:1.46;margin-top:15px}
.cine p{font-size:13.5px;line-height:2.3;color:var(--paper-2);letter-spacing:.06em;
  margin-top:clamp(14px,2.2vh,22px);max-width:30em}
.cine.ctr p{margin-left:auto;margin-right:auto}
.cine .tx>*{opacity:0;transform:translate3d(0,22px,0);
  transition:opacity 1.9s var(--vslow),transform 1.9s var(--vslow)}
.cine.on .tx>*{opacity:1;transform:none}
.cine .tx>*:nth-child(2){transition-delay:.18s}
.cine .tx>*:nth-child(3){transition-delay:.36s}
.cine .tx>*:nth-child(4){transition-delay:.54s}

/* ── 黑場剪接、一句話 ── */
.cut{height:clamp(84px,15vh,180px);background:var(--ink);position:relative}
.cut i{position:absolute;left:50%;top:50%;translate:-50% -50%;width:1px;
  height:clamp(26px,4.6vh,50px);opacity:.42;
  background:linear-gradient(to bottom,transparent,var(--bronze),transparent)}
.cut.tall{height:clamp(120px,24vh,280px)}
.line{padding:clamp(96px,22vh,260px) var(--gut);text-align:center;background:var(--ink)}
.line p{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(21px,3.1vw,40px);letter-spacing:.2em;line-height:2.05;max-width:22em;margin:0 auto}
.line .sub{margin-top:clamp(24px,4vh,50px);font-family:var(--mono);font-size:9px;
  letter-spacing:.36em;color:var(--paper-3)}

/* ── 意象示意圖標註 ──
   一定要有定位過的祖先，否則它會掉到整頁的右下角去（踩過一次）。 */
.plate figure,.pair figure,.stack figure,figure.ph{position:relative}
.imgnote{position:absolute;right:clamp(9px,1.2vw,15px);bottom:clamp(7px,.9vh,11px);z-index:6;
  font-family:var(--mono);font-size:7.5px;letter-spacing:.18em;
  color:rgba(231,231,231,.28);pointer-events:none;user-select:none}

@media (max-width:820px){
  .cine{height:86vh;min-height:430px}
  .cine.mid{height:62vh}
  .stage h1{letter-spacing:.2em}
  body.up .stage h1{letter-spacing:.1em}
}
@media (prefers-reduced-motion:reduce){
  .ph-box::before{display:none}
  .stage .im img{transform:none!important}
  .cine .im img,.ph-box>img,.strip .rail{transform:none!important}
  .cine .tx>*,.split .sp-tx>*{opacity:1!important;transform:none!important;transition:none}
  .bm-d,.bm-d.on{transition:none;transform:none}
  .strip{overflow-x:auto}
}

/* 人像：頭要在框裡。臉部照片不做運鏡，構圖偏上，避免把頭切掉 */
.split .sp-im.face{aspect-ratio:3/4;max-height:74vh}
.split .sp-im.face .ph-box{position:absolute;inset:0}
.split .sp-im.face img{object-position:center 20%;transform:none!important}
@media (max-width:860px){.split .sp-im.face{aspect-ratio:3/4;max-width:min(340px,72vw);margin:0 auto}}
/* 棚拍白底在黑色網站上會變成一塊漏光。壓亮度、收飽和，再用漸層把四邊收進黑裡。 */
.split .sp-im.face img{filter:brightness(.86) contrast(1.05) saturate(.9)}
.split .sp-im.face::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(to bottom,rgba(0,0,0,.32) 0%,transparent 22%,transparent 66%,rgba(0,0,0,.55) 100%),
    linear-gradient(to right,rgba(0,0,0,.28),transparent 18%,transparent 82%,rgba(0,0,0,.28))}

/* ════════════════════════════════════════════════════════════════════
   十、一鏡到底　FILM
   ──────────────────────────────────────────────────────────────────
   首頁不分頁。開場字幕淡出時，第一個案子已經滿版在後面；
   往下捲是一連串交叉溶接，影像全程極慢地推近，中間不縮回、不切換。

   所有層疊在同一個 sticky 舞台上，只寫 opacity 與 scale。
   ════════════════════════════════════════════════════════════════════ */
.film{position:relative}
.film .fi-stage{position:sticky;top:0;height:100vh;overflow:hidden;background:var(--ink)}
.film .fi-lay{position:absolute;inset:0;opacity:0;will-change:opacity}
.film .fi-lay img{width:100%;height:100%;object-fit:cover;display:block;
  will-change:transform;transform:scale(1.08);transform-origin:50% 52%}
.film .fi-stage::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(to bottom,rgba(0,0,0,.6) 0%,rgba(0,0,0,.1) 24%,
    rgba(0,0,0,.08) 48%,rgba(0,0,0,.88) 100%)}

/* 字卡：跟影像一起溶進溶出 */
.film .fi-cap{position:absolute;left:var(--gut);right:var(--gut);
  bottom:clamp(58px,10vh,124px);z-index:5;opacity:0;
  transform:translate3d(0,20px,0);will-change:opacity,transform;pointer-events:none}
.film .fi-cap.live{pointer-events:auto}
.film .fi-cap .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.34em;color:var(--bronze)}
.film .fi-cap h2{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(28px,4.8vw,66px);letter-spacing:.2em;line-height:1.36;margin-top:15px}
.film .fi-cap .loc{margin-top:13px;font-family:var(--mono);font-size:10px;
  letter-spacing:.26em;color:var(--paper-2)}
.film .fi-cap .go{margin-top:clamp(18px,2.6vh,30px)}

/* 右緣的直書索引，同時是目錄 */
.film .fi-idx{position:fixed;right:var(--gut);top:50%;translate:0 -50%;z-index:78;
  display:flex;flex-direction:column;gap:clamp(14px,2.4vh,26px);
  opacity:0;transition:opacity 1.4s ease}
body.up .film .fi-idx{opacity:1}
.film .fi-idx a{display:block;font-family:var(--serif);font-weight:500;font-size:12px;
  letter-spacing:.3em;color:var(--paper-3);writing-mode:vertical-rl;
  transition:color .8s ease;padding:2px 0}
.film .fi-idx a.on{color:var(--bronze)}
.film .fi-idx a:hover{color:var(--paper)}
.film .fi-meter{position:fixed;right:calc(var(--gut) + 26px);top:50%;translate:0 -50%;z-index:78;
  width:1px;height:clamp(90px,16vh,160px);background:rgba(231,231,231,.14);
  opacity:0;transition:opacity 1.4s ease}
body.up .film .fi-meter{opacity:1}
.film .fi-meter i{position:absolute;left:0;right:0;top:0;height:0;background:var(--bronze-hi)}

@media (max-width:820px){
  .film .fi-idx,.film .fi-meter{display:none}
  .film .fi-cap h2{letter-spacing:.1em}
}
@media (prefers-reduced-motion:reduce){
  .film .fi-lay img{transform:none!important}
}

/* ════════════════════════════════════════════════════════════════════
   十、電影放大　EXPAND
   ──────────────────────────────────────────────────────────────────
   影像先是畫面中央一塊小銀幕，捲動時往外撐開成滿版，
   走過去之後再收回來——像戲院的銀幕拉開。
   只寫 scale，撐開所需的倍率由 JS 量一次算好寫進 --sc。
   ════════════════════════════════════════════════════════════════════ */
.expand{position:relative;height:220vh}
.expand .ex-stage{position:sticky;top:0;height:100vh;overflow:hidden;
  display:grid;place-items:center;background:var(--ink)}
.expand .ex-frame{position:relative;width:46vw;aspect-ratio:16/9;overflow:hidden;
  will-change:transform;transform:scale(1);transform-origin:50% 50%;
  box-shadow:0 0 0 1px rgba(231,231,231,.09)}
.expand .ex-frame img{width:100%;height:100%;object-fit:cover;display:block}
.expand .ex-frame::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to bottom,rgba(0,0,0,.34) 0%,transparent 22%,
    transparent 54%,rgba(0,0,0,.72) 100%);opacity:0;transition:opacity 1.1s ease}
.expand.opened .ex-frame::after{opacity:1}
.expand.opened .ex-frame{box-shadow:none}

.expand .ex-tx{position:absolute;left:var(--gut);bottom:clamp(56px,10vh,124px);z-index:4;
  opacity:0;transform:translate3d(0,26px,0);
  transition:opacity 1.4s var(--vslow),transform 1.4s var(--vslow)}
.expand.opened .ex-tx{opacity:1;transform:none}
.expand .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.34em;color:var(--bronze)}
.expand h2{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(28px,4.6vw,62px);letter-spacing:.2em;line-height:1.4;margin-top:14px}
.expand .loc{margin-top:12px;font-family:var(--mono);font-size:10px;letter-spacing:.26em;color:var(--paper-2)}

/* 縮小狀態時，中央銀幕外的區域壓一層更深的黑，銀幕才像發光 */
.expand .ex-stage::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(ellipse 58% 58% at 50% 50%,transparent 40%,rgba(0,0,0,.55) 100%);
  opacity:1;transition:opacity 1s ease}
.expand.opened .ex-stage::before{opacity:0}
.expand .ex-frame{z-index:2}
.expand .ex-tx{z-index:4}

@media (max-width:820px){
  .expand{height:190vh}
  .expand .ex-frame{width:82vw}
  .expand h2{letter-spacing:.12em}
}
@media (prefers-reduced-motion:reduce){
  .expand{height:100vh}
  .expand .ex-frame{width:100vw;height:100vh;aspect-ratio:auto;transform:none!important}
  .expand .ex-tx{opacity:1;transform:none}
  .expand .ex-stage::before{opacity:0}
}

/* ════════════════════════════════════════════════════════════════════
   十一、直式膠卷　ROLL
   ──────────────────────────────────────────────────────────────────
   首頁的建案不是一張一張換掉，是一卷膠片在黑房間裡往上走。
   每一格是一張裱起來的畫面：走到正中央才長到滿尺寸、字才亮起來，
   上一格與下一格留在畫面外緣，看得到邊，看不清內容。

   一次滾輪＝一格。捲動被接管，格位由 JS 補間。
   全程只寫 transform 與 opacity；PITCH 只在載入與改變視窗時量一次。
   ════════════════════════════════════════════════════════════════════ */
.roll{position:relative;--cw:min(52vw,104svh)}
.roll .ro-stage{position:relative;height:100svh;overflow:hidden;background:var(--ink);
  touch-action:pan-y}

/* 每一格都是一整屏，疊在同一個位置上，靠 transform 去排隊 */
.roll .ro-fr{position:absolute;inset:0;display:grid;place-items:center;
  opacity:0;visibility:hidden;will-change:transform,opacity;transform:translate3d(0,0,0);
  transform-origin:50% 50%;z-index:2;pointer-events:none}

/* 卡片刻意**沒有外框**。原本有一圈 box-shadow:0 0 0 1px rgba(231,231,231,.08)，
   那條線畫在裁切框外面，而整張卡片在換格時是被 scale() 帶著動的
   （卡片左緣停在 345.59px 這種小數位置），1px 的線就會落在兩個實體像素之間，
   每一幀重新取樣一次＝白線在抖。仁愛那張渲染圖邊緣是亮的，所以特別明顯；
   玥蓉是夜景，同一條線就看不出來。**不要把外框加回來。** */
/* grid-area 一定要跟黑環寫同一格。環寫了 `grid-area:1/1` 之後，
   卡片若還是自動排位就會被擠到第二列（量到整卷往下掉 227px）。 */
.roll .ro-card{position:relative;display:block;overflow:hidden;pointer-events:auto;
  grid-area:1/1;place-self:center;
  width:var(--cw);aspect-ratio:16/9;text-align:left}

/* ── 小圖的白邊：真正的原因與解法（2026-08-18 量出來的） ──────────
   症狀：不是當下這一格、被縮小的那兩張小圖，**上緣會有一條會抖的亮線**，
   亮圖（仁愛、三重）看得很清楚，夜景（玥蓉）看不出來。

   量法：把小圖上緣往上四列、往下十列的像素亮度印出來。量到的是——
   `… 6 6 6 [212] 6 51 168 195 …`
   **那條亮線落在卡片上緣的「外面」一個實體像素**（卡片自己的第一列是 6，黑的）。

   原因：`.ro-fr` 是被 `scale(0.56)` 帶著的合成層，裡面的 `.ro-reel` 又是
   自己一個合成層。**兩層各自對齊到實體像素網格，進位方向不一定一樣**，
   所以影像那一層可以多吐出一個實體像素，落在卡片裁切框的外面。
   卡片自己的 `::after` 黑框幫不上忙——它被 `overflow:hidden` 關在裡面。

   試過沒用的（都量過，亮度還是 212）：
   `contain:paint`、`translateZ(0)`、`isolation:isolate`、`border-radius:.5px`、
   `overflow:clip`、把卡片自己也促成一層。
   把 `.ro-reel` 反促（`will-change:auto`）只從 212 降到 54，而且會犧牲推近的效能。

   **有效的做法只有一個：把黑框畫在卡片「外面」，而且畫在同一層裡。**
   所以黑環掛在 `.ro-fr::before`——它跟卡片同一個合成層（一起進位），
   z-index 比卡片高（蓋得住吐出來的那一列），
   而且不受卡片 `overflow:hidden` 的限制。
   用 grid 的同一格（`grid-area:1/1` ＋ `place-self:center`）跟卡片對齊，
   所以卡片大小一改，環自己會跟著跑。 */
.roll .ro-fr::before{content:"";grid-area:1/1;place-self:center;z-index:5;
  width:calc(var(--cw) + 20px);height:calc(var(--cw) / (16 / 9) + 20px);
  box-shadow:inset 0 0 0 10px var(--ink);pointer-events:none}
/* 放映窗：該案的渲染圖全部疊在這裡，只有一張亮著。
   JS 只寫 .ro-reel 的 transform（膠卷的推近），單張圖的溶接與推近純 CSS，
   兩邊各管各的元素，不會搶同一個屬性。 */
/* **這裡不要寫 will-change。** 它一旦自己一層，就會跟卡片各自對齊實體像素，
   小圖上緣會吐出一個亮像素（見上面 .ro-fr::before 的說明）。

   2026-08-18 重量了一次，把小圖上緣「外面」那一列的最亮值，
   在十四個不同的次像素位置各量一次（＝走完轉場中卡片會經過的每一個位置）：
       原始（沒有黑環、有促層）   212，而且會隨位置跳動 ← 這就是他說的「白邊在抖」
       有黑環 ＋ 促成一層          48–50，穩定不跳
       有黑環 ＋ 不促（現在）      15–16，穩定不跳（頁面底色本身是 6–7）
   兩種都已經不抖了，黑環才是止抖的那一手；促不促決定的是那條線「有多亮」。
   15 在黑底上等於看不見，50 是看得出來的一條灰髮絲。所以選不促。

   **代價是真的，別把它寫成沒有代價**：不促＝每幀重畫整張圖。
   四倍節流、按一次方向鍵，桌機掉格 18（促成一層是 6），手機 2（促是 1）。
   已經用 py.js 裡推近的量化（千分之五）把 26 壓到 18，
   再往下壓就會看到影像在跳——那一段的取捨寫在 py.js 的 im2 上面。 */
.roll .ro-reel{position:absolute;inset:0;display:block;
  transform:scale(1.06);transform-origin:50% 52%}
/* 這裡千萬不要寫 visibility。
   整格不在畫面上的時候是靠 .ro-fr 的 visibility:hidden 收掉的，
   而子層只要寫了 visibility:visible 就會蓋過祖先的 hidden——
   那張圖會把整個畫面的點擊吃掉（症狀：點玥蓉卻跑到 about.html）。
   溶接只要 opacity 就夠了，圖本身也不是可點的東西。 */
.roll .ro-reel img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transform:scale(1.055);transform-origin:50% 50%;
  transition:opacity 1.05s ease,transform 5.2s var(--vslow)}
.roll .ro-reel img.on{opacity:1;transform:scale(1)}
/* 卡片刻意**沒有外框，也沒有四邊虛化**。
   外框（1px box-shadow）在縮放時會抖，2026-08-10 拿掉；
   同一天試過把四邊漸層化進黑底，Ethan 說「首頁渲染圖還是不要虛化」，也拿掉了。
   兩個都不要再加回來。 */
/* 字要待的那一側壓暗；靜態漸層，不參與動畫。
   另外用一圈 2px 的 inset 陰影把卡片最外圈畫成跟頁面同一個黑：
   整格在縮放時裁切線落在小數像素上，那一排的覆蓋率每一幀都在變，
   亮圖（仁愛、三重）就會看到邊緣在閃。最外圈本來就是黑的話，
   黑混黑，怎麼混都看不出來。**這不是虛化**——只有 2px，而且是硬邊。 */
.roll .ro-card::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  box-shadow:inset 0 0 0 2px var(--ink);
  background:linear-gradient(90deg,rgba(0,0,0,.68) 0%,rgba(0,0,0,.30) 24%,
    rgba(0,0,0,0) 52%),
    linear-gradient(to top,rgba(0,0,0,.44) 0%,rgba(0,0,0,0) 34%)}

/* ── 字卡：只有案名，直排 ──────────────────────────────────
   Ethan：「左邊的建案說明都拿掉……或是只顯示玥蓉即可。
   然後要**很有藝術感**的呈現。」

   所以收起來的時候，影像左邊只剩案名：直排、明體、大。
   旁邊一條短的青銅細線接一行直排的英文，像落款。
   地區、類型、進度都沒有不見，全部在攤開之後的資訊欄裡；
   「下一個推案」與「建案介紹」那顆按鈕也一起收了——
   影像下緣的指引已經寫著「點開　建案介紹」。

   直排在手機上不成立（字卡是貼在影像下面的一橫排），窄螢幕改回橫排。 */
.roll .ro-cap{position:absolute;left:var(--gut);top:50%;translate:0 -50%;z-index:6;
  display:flex;align-items:flex-start;gap:clamp(12px,1.4vw,22px);
  opacity:0;will-change:opacity;pointer-events:none}
.roll .ro-cap.live{pointer-events:auto}
/* 2026-08-18 Ethan：「建案的名稱調小，**不能比左上的璞玥建設大**。」
   舊版是 clamp(32px,5vw,72px)——1440 寬時是 72px，標記才 34px，
   等於建案名比公司名還大。現在收到 30px 以下，
   桌機的關係是 34（標記）> 30（案名），手機是 26 > 23。
   **改標記的字級時這一條要一起改**，不然關係會反過來。 */
.roll .ro-cap h2{margin:0;writing-mode:vertical-rl;text-orientation:upright;
  font-family:var(--disp);font-weight:700;color:var(--paper);
  font-size:clamp(22px,1.95vw,30px);letter-spacing:.24em;line-height:1;
  text-shadow:0 0 46px rgba(0,0,0,.7),0 2px 12px rgba(0,0,0,.45)}
/* 一個字一個 <i>，走到正中央才一個一個從左邊落定。
   直排裡 inline-block 是往下排的，所以位移用 X。 */
.roll .ro-cap h2 i{display:inline-block;font-style:normal;
  opacity:0;transform:translate3d(-18px,0,0);
  transition:opacity 1.1s ease,transform 1.5s var(--vslow)}
.roll .ro-cap.live h2 i{opacity:1;transform:none}
.roll .ro-cap.live h2 i:nth-child(2){transition-delay:.12s}
.roll .ro-cap.live h2 i:nth-child(3){transition-delay:.24s}
.roll .ro-cap.live h2 i:nth-child(4){transition-delay:.36s}
.roll .ro-cap.live h2 i:nth-child(5){transition-delay:.48s}
.roll .ro-cap .en{opacity:0;transform:translate3d(-10px,0,0);
  transition:opacity 1s ease .5s,transform 1.2s var(--vslow) .5s}
.roll .ro-cap.live .en{opacity:1;transform:none}
.roll .ro-cap .en{writing-mode:vertical-rl;text-orientation:sideways;
  margin-top:clamp(24px,4vh,54px);padding-top:clamp(14px,2.2vh,24px);
  border-top:1px solid rgba(185,151,95,.45);
  font-family:var(--mono);font-size:9px;letter-spacing:.34em;color:var(--bronze);
  text-shadow:0 0 18px rgba(0,0,0,.85)}

/* ── 一顆星　ONE STAR ──────────────────────────────────────
   這一塊改過六版。過程記在這裡，免得下一個人再繞一次：
   v1 一條細線＋圓點＋兩撇葉子　　　→「非常沒有質感，也沒有驚艷到我」
   v2 月下梅枝＋五瓣梅花　　　　　　→「動態感不夠」（一張靜止的插畫）
   v3 一道光＋五個光點＋會跑的亮點　→「亮點自己往下移動整個超怪」
   v4 一顆會長的月（月相）　　　　　→「別亂做一顆很怪的月亮」
   v5 月＋細光＋一顆不動的亮星　　　→ 質感對了，但線還是多的
   v6（現在）**一顆星，加建案名稱。就這樣。**

   Ethan 定案：「我不要有線條，就是一顆星星＋建案名稱即可。」
   **不要再往上加東西。** 前五版每一次都是「再加一點」，
   結果每一次都被打回來；拿掉之後反而立得住。

   星對齊的是**案名那幾個大字的中線**，不是整塊字的中線——
   英文掛在絕對位置不佔高度，所以 -50% 對到的就是案名本身。
   （偏下的那一版就是把英文算進高度了。）

   **效能**：SVG 是靜止的，捲動與換格時一個字都不寫（換格只切一個 class）。
   會一直動的兩件事都是 HTML 元素、各自合成層：星很慢的明滅、旁邊的浮塵。 */
.roll .vine{position:absolute;left:clamp(16px,3vw,74px);top:0;bottom:0;z-index:6;
  width:clamp(180px,20vw,270px);pointer-events:none;
  opacity:0;will-change:opacity;
  /* ── 光的直徑。星跟案名的左界**是同一個數算出來的**，不要分開調 ──
     左邊這一欄真正能用的寬度 = 卡片左緣 − 版心左界。
     卡片固定站在 24vw，版心是 3vw，案名寬約字級的 6.9 倍，
     所以能給光的空間隨視窗寬**線性**變多，clamp 的 vw 項就是這條線。
     50px 是下限（901–1100 那一段本來就沒地方，只能比改版前大一點），
     140px 是上限（再大 1500 上下那一段的案名就會頂到卡片）。
     驗法：`node /home/claude/py/starfit.js`，七個寬度會直接印
     「芯-字」與「字-卡」兩個間隙，任何一個變負的就是撞到了。 */
  --vs:clamp(50px,calc(20vw - 165px),140px)}

/* ── 星：鏡頭裡的一點光 ───────────────────────────────────────
   2026-08-20，同一天改了兩次。

   ① Ethan：「左邊的十字燈光請完全重新設計，
               要有呼吸感、動態感、質感、美感。」
      → 我把 SVG 的細十字換成漸層的星芒（六層互質秒數的橢圓）。
   ② 他看了：「**沒有驚艷到我。**」

   兩次被退的共同點不是造型，是**份量**：左邊這一欄 270px 寬、整個視窗高，
   裡面只擺一個 60px 的小東西，再怎麼精緻都撐不住那片黑。
   所以這一版做兩件事——**放大一個量級**（68px → 146px），
   而且**不畫圖案，畫鏡頭真的會拍到的東西**：

     後面　四顆**沒對到焦**的暖光斑，各自在不同深淺上極慢地漂
     前面　一顆**對到焦**的芯，加一道橫向散光

   失焦的光斑長什麼樣是有規矩的：**中間偏暗、邊緣一圈亮**（光圈邊緣的繞射）。
   `.fl-b*` 那條 gradient 的重點就在 56%→80% 那一段爬升，不是中心。
   兩個地雷：那圈亮**壓不夠淡就變肥皂泡**；顏色**一走灰白就變髒鏡頭**，
   所以全部走暖金（240,222,182 一路到 222,193,138）。

   秒數互質（19 / 29 / 41 / 53 / 31 / 11 / 6.5），永遠不會排成同一個樣子。

   效能：七層都是 HTML 元素、各自合成層，只動 transform 與 opacity，
   完全不碰 SVG（SVG 裡只要有東西在補間就是整張一直重刷）。
   置中用 translate 這個**獨立屬性**，transform 整個留給動畫。
   ⚠ 不要加「會擴散出去的圈」——那是 HUD 的語彙，
     團隊頁的脈衝環就是這樣被打回來的（「太科技感」）。 */
.roll .vn-star{position:absolute;left:0;top:50%;translate:0 -50%;
  width:var(--vs);aspect-ratio:1;
  opacity:0;animation:vnIn 2.6s var(--vslow) 1.9s forwards}
@keyframes vnIn{to{opacity:1}}
.roll .vn-star i{position:absolute;left:50%;top:50%;translate:-50% -50%;
  display:block;border-radius:50%;will-change:transform,opacity}

/* 最外層的暖空氣：不是光斑，是整顆的底 */
.roll .vn-star .fl-air{width:215%;height:215%;
  background:radial-gradient(circle,rgba(255,244,222,.125) 0%,
    rgba(240,224,192,.058) 32%,rgba(226,205,166,.02) 60%,rgba(226,205,166,0) 78%);
  animation:vnAir 19s ease-in-out infinite alternate}
@keyframes vnAir{from{transform:scale(.86);opacity:.5}
                 to{transform:scale(1.12);opacity:1}}

/* 四顆失焦的光斑。共用同一條「中間暗、邊緣一圈亮」的漸層，
   只差大小、秒數與飄的方向——大的在後面（慢、淡），小的在前面（快、亮）。 */
.roll .vn-star .fl-b1,.roll .vn-star .fl-b2,
.roll .vn-star .fl-b3,.roll .vn-star .fl-b4{
  background:radial-gradient(circle,rgba(240,222,182,.035) 0%,
    rgba(238,218,176,.055) 56%,rgba(230,203,150,.105) 80%,
    rgba(222,193,138,.05) 93%,rgba(222,193,138,0) 100%)}
.roll .vn-star .fl-b1{width:84%;height:84%;
  animation:vnB1 29s ease-in-out -6s infinite alternate}
.roll .vn-star .fl-b2{width:112%;height:112%;
  animation:vnB2 41s ease-in-out -3s infinite alternate}
.roll .vn-star .fl-b3{width:38%;height:38%;
  animation:vnB3 53s ease-in-out -21s infinite alternate}
.roll .vn-star .fl-b4{width:26%;height:26%;
  animation:vnB4 31s ease-in-out -8s infinite alternate}
@keyframes vnB1{from{transform:translate(-24%,13%) scale(.84);opacity:.45}
                to{transform:translate(28%,-17%) scale(1.1);opacity:.95}}
@keyframes vnB2{from{transform:translate(14%,-9%) scale(.92);opacity:.28}
                to{transform:translate(-16%,11%) scale(1.06);opacity:.62}}
@keyframes vnB3{from{transform:translate(-80%,44%) scale(.7);opacity:.25}
                to{transform:translate(120%,-52%) scale(1.1);opacity:.75}}
@keyframes vnB4{from{transform:translate(150%,-46%) scale(1);opacity:.7}
                to{transform:translate(-130%,58%) scale(.55);opacity:.18}}

/* 前景：對到焦的那一道橫向散光。兩端自己淡掉，所以看不到端點。 */
.roll .vn-star .fl-h{width:215%;height:6%;border-radius:0;
  background:radial-gradient(closest-side,rgba(255,252,245,.5) 0%,
    rgba(253,244,225,.16) 34%,rgba(247,234,206,0) 100%);
  animation:vnH 11s ease-in-out -2s infinite alternate}
@keyframes vnH{from{transform:scale(.72,.62);opacity:.48}
               to{transform:scale(1.05,1);opacity:.96}}

/* 芯：整顆唯一一個對到焦、也是唯一一個快到看得出來的節奏 */
.roll .vn-star .fl-core{width:5.5%;height:5.5%;
  background:radial-gradient(circle,#fffdf7 0%,rgba(255,250,238,.82) 40%,
    rgba(252,242,222,0) 100%);
  box-shadow:0 0 15px 3px rgba(255,246,224,.3);
  animation:vnCore 6.5s ease-in-out -1s infinite alternate}
@keyframes vnCore{from{transform:scale(.76);opacity:.78}
                  to{transform:scale(1.2);opacity:1}}

/* ── 案名：一次只有一個，就在星的右邊 ── */
/* 案名的左界跟著光走：.95 倍直徑是光**看得出來**的邊（再外面的暈已經
   不到 3% 不透明度了），再加 20px 才是字。改係數要重跑 starfit.js。 */
.roll .vn-lbs{position:absolute;left:calc(var(--vs) * .95 + 20px);right:0;top:50%;height:0}
.roll .vn-lb{position:absolute;left:0;top:0;display:block;white-space:nowrap;
  will-change:opacity,transform;
  opacity:0;transform:translate3d(0,calc(-50% + 10px),0);
  transition:opacity .3s ease,transform .3s ease}
.roll .vn-lb.cur{opacity:1;transform:translate3d(0,-50%,0);
  transition:opacity .8s ease .14s,transform 1s var(--vslow) .14s}
/* 不要那麼白、不要那麼大。純白的粗明體在黑底上很吵；
   換成 500 的字重、帶一點暖的米白（86%），字級收下來、字距拉開，
   質感是靠字距與灰階撐的，不是靠大和白。 */
/* 字級的規矩：**永遠比左上角的「璞玥建設」小。**
   標記是 clamp(24px,2.1vw,34px)，這裡收到 clamp(17px,1.55vw,23px)，
   1920 / 1440 / 1280 / 1024 四個寬度都是 23<34、22.3<30.2、19.8<26.9、
   17<24——每一格都小一截，公司名才是畫面上最大的字。
   小了之後質感反而更好：靠字距與灰階撐，不是靠大和白。 */
.roll .vn-lb b{display:block;font-family:var(--disp);font-weight:500;
  color:rgba(233,228,217,.86);
  font-size:clamp(15px,1.25vw,18.5px);letter-spacing:.34em;line-height:1;
  text-indent:.34em;text-shadow:0 0 30px rgba(0,0,0,.7)}
.roll .vn-lb.last b{font-size:clamp(12px,1vw,15px);letter-spacing:.38em;text-indent:.38em}
/* 一個字一個 span，走到才一個一個落定——跟膠卷字卡同一組秒數 */
.roll .vn-lb b span{display:inline-block;
  opacity:0;transform:translate3d(0,16px,0);
  transition:opacity .3s ease,transform .3s ease}
.roll .vn-lb.cur b span{opacity:1;transform:none;
  transition:opacity 1s ease .18s,transform 1.3s var(--vslow) .18s}
.roll .vn-lb.cur b span:nth-child(2){transition-delay:.3s}
.roll .vn-lb.cur b span:nth-child(3){transition-delay:.42s}
.roll .vn-lb.cur b span:nth-child(4){transition-delay:.54s}
/* 英文掛在絕對位置、**不佔高度**——這樣 -50% 對到的是案名的中線，
   星才會對齊字的中間而不是偏下。 */
.roll .vn-lb i{position:absolute;left:0;top:calc(100% + 12px);
  font-style:normal;font-family:var(--mono);color:rgba(185,151,95,.8);
  font-size:clamp(7.5px,.58vw,8.5px);letter-spacing:.34em;white-space:nowrap}

/* ── 浮塵 ──
   一顆＝一個元素＝一個合成層，「飄、擺、明滅」全部烘進同一組 keyframes；
   **完全不碰 SVG**。 */
.roll .vn-fall{position:absolute;left:clamp(16px,3vw,74px);top:0;bottom:0;
  width:clamp(180px,20vw,270px);z-index:5;pointer-events:none}
.roll .vn-fall .vf{position:absolute;width:3px;height:3px;
  opacity:0;will-change:transform,opacity;
  animation:vnFall var(--dur,22s) linear var(--dl,0s) infinite,
            vnFade var(--dur,22s) linear var(--dl,0s) infinite}
.roll .vn-fall .vf:nth-child(2n){width:4px;height:4px}
.roll .vn-fall .vf b{display:block;width:100%;height:100%;border-radius:50%;
  background:radial-gradient(circle,rgba(255,250,240,.95) 0%,
    rgba(246,238,218,.5) 42%,rgba(246,238,218,0) 100%)}

/* 桌機收起舊的左側大字卡，改由這顆星標名字 */
@media (min-width:901px){
  .roll .ro-cap{display:none}
}
@media (max-width:900px){
  .roll .vine,.roll .vn-fall{display:none}
}
@media (prefers-reduced-motion:reduce){
  .roll .vn-fall{display:none}
  /* 保險用的：不要動畫的人整卷會攤平，下面那個 reduce 區塊已經把
     `.roll .vine` 整個 display:none 了，所以這幾行**現在看不到**。
     留著是為了萬一以後攤平的版面又把星放回來——那時候它要能停得住。
     停下來就是每一層 scale(1)、opacity:1，看起來還是完整的一顆光。
     ⚠ 一定要寫 i[class]：`.roll .vn-star i` 只有 (0,2,1)，
       壓不過上面 `.roll .vn-star .fl-air` 的 (0,3,0)，
       加一個 [class] 才變 (0,3,1) 壓得住。 */
  .roll .vn-star{animation:none;opacity:1}
  .roll .vn-star i[class]{animation:none;opacity:1}
  /* 光斑本來就只是「在漂」，不動的時候會疊在芯上變一團，直接不要 */
  .roll .vn-star .fl-b1,.roll .vn-star .fl-b2,
  .roll .vn-star .fl-b3,.roll .vn-star .fl-b4{display:none}
}

/* ── 右緣的走帶：齒孔 ──
   平常只有幾道短橫線，像膠捲邊上的齒孔。走到哪一格，那一道才變長，
   案名跟著從左邊推出來。攤開之後同一支走帶換成放映的張數。
   只寫 transform 與 opacity，width 的變化只發生在換格那一刻。 */
/* ── 指引：下緣一行字 ──────────────────────────────────────
   Ethan 要「有質感的動態指引點擊渲染圖」。

   第一版在影像四角加了攝影的裁切標記（L 形細線，很慢地往內收再放開），
   他看了說「**邊框不需要**」，整組拿掉了。**不要再加回來。**
   現在只剩下緣一行字，動的是它進場那一下：一條青銅細線從中央拉開，
   字跟著浮上來，**走一次就停**。
   會來回跑的線就是進度條、脈衝環就是 HUD——那一套在團隊頁被打回來過
   （「太科技感，與本網站的風格不搭」），這裡是同一個標準。

   顯示條件完全交給 CSS：`.ro-fr.live`。
   那是 JS 既有的狀態，條件剛好就是我們要的——
   走到正中央、開場字幕跑完、而且還沒攤開。
   第五格（台北與新北）是連結不是放映，HTML 裡就沒放這一段。 */
.roll .ro-hint{position:absolute;inset:0;z-index:3;pointer-events:none;
  opacity:0;transition:opacity 1s ease}
.roll .ro-fr.live .ro-hint{opacity:1;transition:opacity 1.1s ease .4s}
.roll.spread .ro-hint{opacity:0;transition:opacity .4s ease}
/* 渲染圖有夜景也有大白天（玥蓉是夜、三重是晴天大逆光），
   下緣不收一點黑的話字會糊進樹叢。這一層跟著指引一起淡入淡出，
   攤開之後整層退掉，照片還是照片。 */
.roll .ro-hint::after{content:"";position:absolute;display:block;pointer-events:none;
  left:0;right:0;bottom:0;height:26%;
  background:linear-gradient(to top,rgba(0,0,0,.56),rgba(0,0,0,0))}

.roll .ro-hint b{position:absolute;z-index:2;left:0;right:0;bottom:clamp(17px,2.3vh,26px);
  display:block;text-align:center;font-family:var(--mono);font-weight:400;
  font-size:9.5px;letter-spacing:.28em;color:var(--paper);
  /* 渲染圖下緣不一定是暗的（玥蓉那張正好是亮的入口），字會糊在裡面。
     text-shadow 是靜態的，不會每幀重畫，比在字後面墊一塊底乾淨。 */
  text-shadow:0 0 14px rgba(0,0,0,.9),0 1px 3px rgba(0,0,0,.85);
  opacity:0;transform:translate3d(0,8px,0);
  transition:opacity 1.1s ease .75s,transform 1.3s var(--vslow) .75s}
.roll .ro-fr.live .ro-hint b{opacity:1;transform:none}
.roll .ro-hint b em{font-style:normal;color:var(--bronze-hi);margin-left:1.1em}
.roll .ro-hint b u{position:absolute;left:50%;bottom:calc(100% + 11px);
  display:block;width:38px;height:1px;margin-left:-19px;text-decoration:none;
  background:var(--bronze);transform:scaleX(0);transform-origin:50% 50%;
  transition:transform 1.6s var(--vslow) .35s}
.roll .ro-fr.live .ro-hint b u{transform:scaleX(1)}

@media (max-width:860px){
  .roll .ro-hint b{font-size:8.5px;letter-spacing:.22em;bottom:16px}
  .roll .ro-hint b em{display:block;margin:7px 0 0}
  .roll .ro-hint b u{bottom:calc(100% + 8px)}
}
@media (prefers-reduced-motion:reduce){
  /* 減動時整個膠卷引擎不啟動，卡片點了不會有反應，
     所以這一行「點開」不能出現，不然是騙人的。 */
  .roll .ro-hint{display:none}
}

/* ── 攤開之後的指引 ──────────────────────────────────────────
   一條很細的線，一顆光點從上往下走，下面一行字。
   點開才出現（晚 1.1 秒，讓資訊欄先站定），**換過一張之後就收起來**——
   已經知道怎麼看的人不需要再被提醒（.seen 由 py.js 在 showShot 加上）。
   走的那一點是 ::after 的 transform，合成層上跑，零重繪。 */
/* **class 撞車踩第四次。** 這一行字本來寫 `<b class="mb">`（mobile 的縮寫），
   結果吃到第五節那個名片元件的 `.mb`，帶著 84px 的上下 padding，
   整個框變成 224px 高、字被推到資訊欄裡面。改成 `.ro-mb` / `.ro-pc`。
   **新增 class 前一定要先 grep 一次。**（同 7-21） */
.roll .ro-more{position:absolute;left:50%;bottom:clamp(20px,3.4vh,40px);z-index:79;
  translate:-50% 0;text-align:center;pointer-events:none;
  opacity:0;transition:opacity .7s ease}
.roll.spread .ro-more{opacity:1;transition:opacity 1.2s ease 1.1s}
.roll.spread.seen .ro-more{opacity:0;transition:opacity .6s ease}
.ro-more i{position:relative;display:block;width:1px;height:28px;margin:0 auto 11px;
  overflow:hidden;background:rgba(232,220,196,.2)}
.ro-more i::after{content:"";position:absolute;left:0;top:0;width:1px;height:10px;
  background:var(--bronze-hi);will-change:transform;
  animation:roMore 2.3s cubic-bezier(.45,0,.35,1) infinite}
@keyframes roMore{0%{transform:translate3d(0,-10px,0)}
  58%,100%{transform:translate3d(0,28px,0)}}
.ro-more b{display:inline-block;line-height:1.4;vertical-align:top;
  font-family:var(--mono);font-weight:400;font-size:9.5px;letter-spacing:.3em;
  color:var(--paper-2);white-space:nowrap;
  text-shadow:0 0 14px rgba(0,0,0,.9),0 1px 3px rgba(0,0,0,.85)}
.ro-more .ro-mb{display:none}
@media (max-width:860px){
  /* 位置在第十一之二節的手機段用 `--iy` 重寫（貼在圖的下緣裡面）。
     這裡只留一個沒有 --iy 時的保底值。 */
  .roll .ro-more{bottom:calc(40svh + 18px)}
  .ro-more .ro-pc{display:none}
  .ro-more .ro-mb{display:inline-block;font-size:11px;letter-spacing:.24em}
}
@media (prefers-reduced-motion:reduce){
  /* 減動時膠卷引擎不啟動，點不開，這一行也不能出現 */
  .roll .ro-more{display:none}
}

/* ── 收起來時的指引：往下還有別的建案 ──────────────────────────
   2026-08-18 Ethan：「首頁的建案要有小提醒下滑更多。讓人家知道可以下滑。」

   **位置是算出來的，不是貼在畫面下緣。** 貼下緣的話桌機會壓到下一格
   露出來的那一條（量到 y=837 就是下一格的上緣），看起來像疊版。
   這裡吊在「當下這一格的下緣 ＋ 26px」——那一段是兩格之間本來就空著的帶，
   桌機量到 84px、手機 84px，放得下一行字加一條線。
   高度用同一組變數換算：桌機 var(--cw)/(16/9)，手機 var(--roh)。

   開場字幕跑完才出現（body.done），換過一格就收掉（body.moved）——
   已經知道可以往下捲了，就不必再提醒。 */
.roll .ro-nx{position:absolute;left:50%;z-index:79;
  top:calc(50% + var(--cw) / (16 / 9) / 2 + 26px);
  translate:-50% 0;text-align:center;pointer-events:none;
  opacity:0;transition:opacity .6s ease}
body.done .roll:not(.spread) .ro-nx{opacity:1;transition:opacity 1.4s ease 1.5s}
body.moved .roll .ro-nx{opacity:0;transition:opacity .5s ease}
.ro-nx b{display:inline-block;line-height:1.4;vertical-align:top;
  font-family:var(--mono);font-weight:400;font-size:9.5px;letter-spacing:.3em;
  text-indent:.3em;color:var(--paper-2);white-space:nowrap;
  text-shadow:0 0 14px rgba(0,0,0,.9),0 1px 3px rgba(0,0,0,.85)}
.ro-nx i{position:relative;display:block;width:1px;height:26px;margin:10px auto 0;
  overflow:hidden;background:rgba(232,220,196,.18)}
.ro-nx i::after{content:"";position:absolute;left:0;top:0;width:1px;height:9px;
  background:var(--bronze-hi);will-change:transform;
  animation:roNx 2.3s cubic-bezier(.45,0,.35,1) infinite}
@keyframes roNx{0%{transform:translate3d(0,-9px,0)}
  58%,100%{transform:translate3d(0,26px,0)}}
.ro-nx .ro-mb{display:none}
@media (max-width:860px){
  .roll .ro-nx{top:calc(50% + var(--roh) / 2 + 22px)}
  .ro-nx .ro-pc{display:none}
  .ro-nx .ro-mb{display:inline-block;font-size:10.5px;letter-spacing:.24em}
  .ro-nx i{height:22px;margin-top:8px}
}
@media (prefers-reduced-motion:reduce){
  .roll .ro-nx{display:none}
}

.roll .ro-rail{position:absolute;right:var(--gut);top:50%;translate:0 -50%;z-index:78;
  display:flex;flex-direction:column;align-items:flex-end;gap:13px;
  opacity:0;transition:opacity 1.4s ease}
body.up .roll .ro-rail{opacity:1}
.roll .ro-rail>button{display:grid;place-items:center;width:22px;height:14px;
  opacity:.42;transition:opacity .6s ease;margin-right:5px}
.roll .ro-rail>button:hover{opacity:1}
.roll .ro-rail>button[disabled]{opacity:.13;cursor:default}
.roll .ro-rail svg{width:9px;height:6px;overflow:visible}
.roll .ro-rail svg path{fill:var(--paper);stroke:none}

.roll .ro-perf{display:flex;flex-direction:column;align-items:flex-end;gap:13px}
.roll .ro-perf.shot{display:none}
.roll .ro-perf .pf{display:flex;align-items:center;gap:8px;padding:3px 0;
  background:none;border:0}
.roll .ro-perf .pf u{display:block;width:11px;height:1px;text-decoration:none;
  background:rgba(231,231,231,.26);
  transition:width .7s var(--slow),background .7s ease}
.roll .ro-perf .pf:hover u{width:16px;background:rgba(231,231,231,.6)}
.roll .ro-perf .pf.on u{width:20px;background:var(--bronze-hi)}
/* 直書：一個字一個 block，不靠 writing-mode，字距完全可控 */
.roll .ro-perf .vn{display:block;opacity:0;transform:translate3d(6px,0,0);
  transition:opacity .7s ease,transform .8s var(--slow);pointer-events:none}
.roll .ro-perf .pf.on .vn{opacity:1;transform:none}
.roll .ro-perf .vn b{display:block;text-align:center;font-family:var(--serif);
  font-weight:500;font-size:10.5px;line-height:1.6;color:var(--bronze)}
/* 攤開後走帶只剩齒孔，不掛號碼——號碼會頂到資訊欄的字，
   而且圖說那一列開頭就寫著第幾張了，不必寫兩次 */
.roll .ro-perf.shot .vn{display:none}


@media (max-width:860px){
  /* ── 手機的建案格：一張電影劇照 ────────────────────────────
     2026-08-17 Ethan：「首頁的建案呈現，用手機反而變得沒有質感。
     建案圖片少了原本的電影感、**建案名稱也會被圖片檔到**。」

     舊版把案名放在影像**下面**，結果它被夾在自己這一格與下一格中間，
     上下都是圖，名字沒有立足的地方，整組也擠得沒有留白。

     改成**案名壓在影像上**（左下角，底下自己帶一道收黑），
     格子拉高到 58svh 並且四周留白，下一格只露出一條邊——
     一張劇照加一個片名，這才是桌機那個版本在做的事。
     `--roh` 是格子的高度，py.js 的 PITCH 也照這個比例走（0.72），
     **兩邊要一起改，不然格子會互相疊到。** */
  .roll{--roh:58svh}
  .roll .ro-fr{display:block}
  .roll .ro-card{position:absolute;left:50%;top:50%;translate:-50% -50%;
    width:92vw;height:var(--roh);aspect-ratio:auto}
  /* 環跟著卡片走（手機的卡片是絕對定位，不是 grid 的那一格） */
  .roll .ro-fr::before{position:absolute;left:50%;top:50%;translate:-50% -50%;
    width:calc(92vw + 20px);height:calc(var(--roh) + 20px)}
  /* 案名壓在格子的左下角。位置從畫面中線推算，跟格子共用 --roh，
     所以改高度不必再算一次字的位置。 */
  .roll .ro-cap{position:absolute;left:calc(4vw + clamp(16px,4.6vw,24px));right:auto;
    top:calc(50% + var(--roh) / 2 - clamp(18px,3vh,26px));translate:0 -100%;
    width:auto;max-width:76vw;display:block;padding:0}
  .roll .ro-cap h2{writing-mode:horizontal-tb;text-orientation:mixed;
    letter-spacing:.16em;   /* 字級在 900 區塊，不要在這裡再寫一次 */
    text-shadow:0 0 30px rgba(0,0,0,.9),0 2px 10px rgba(0,0,0,.8)}
  .roll .ro-cap .en{writing-mode:horizontal-tb;text-orientation:mixed;
    display:block;margin:8px 0 0;padding:0;border-top:0;
    text-shadow:0 0 16px rgba(0,0,0,.9)}   /* 字級在 900 區塊 */
  /* 壓字就要壓黑，而且要壓得夠——底下三分之一都要收下去 */
  .roll .ro-card::after{background:linear-gradient(to top,rgba(0,0,0,.82) 0%,
    rgba(0,0,0,.46) 18%,rgba(0,0,0,.12) 38%,rgba(0,0,0,0) 58%)}
  /* 「點開」讓開左下角的案名，改站右下角 */
  .roll .ro-hint b{left:auto;right:clamp(14px,4vw,22px);translate:0 0;text-align:right}
  .roll .ro-hint b u{left:auto;right:0}
  .roll .ro-rail{right:11px;gap:11px}
  .roll .ro-perf{gap:11px}
  .roll .ro-perf .vn{display:none}
}

/* 不要動畫的人：整卷攤平成一列，該看的都看得到 */
@media (prefers-reduced-motion:reduce){
  .roll .vine{display:none}
  .roll .ro-cap{display:block!important}
  .roll .ro-stage{height:auto;overflow:visible;padding-top:clamp(90px,14vh,160px)}
  .roll .ro-fr{position:relative;inset:auto;opacity:1!important;visibility:visible!important;
    transform:none!important;padding:clamp(40px,7vh,84px) 0;
    grid-template-columns:minmax(0,1fr)}
  .roll .ro-reel{transform:none!important}
  .roll .ro-reel img{transition:none}
  .roll .ro-cap{position:relative;left:auto;top:auto;translate:0 0;display:block;
    opacity:1!important;pointer-events:auto;margin:26px auto 0;width:min(90vw,520px)}
  .roll .ro-cap h2{writing-mode:horizontal-tb;text-orientation:mixed;letter-spacing:.16em}
  .roll .ro-cap .en{writing-mode:horizontal-tb;text-orientation:mixed;
    display:block;margin:11px 0 0;padding:0;border-top:0}
  .roll .ro-card::after{background:linear-gradient(to top,rgba(0,0,0,.4) 0%,
    rgba(0,0,0,0) 40%)}
  .roll .ro-rail{display:none}
}

/* ────────────────────────────────────────────────────────────────
   十一之二　點開：影像放大靠左，資訊在右邊站出來
   ──────────────────────────────────────────────────────────────
   放大倍率由 JS 量一次算好，寫在膠卷同一支 paint() 的 transform 上，
   不另開一套動畫。刻意不做滿版——留白還在，才不會變成燈箱。

   狀態 class 叫 .spread，不叫 .opened —— .opened 已經被 .expand 佔走了。
   ──────────────────────────────────────────────────────────────── */
/* 右緣要留給走帶，資訊欄再往左讓 30px，兩者才不會疊在一起
   （走帶以前攤開時會收掉，現在改成換成張數，所以一直都在） */
.roll .ro-info{position:absolute;right:calc(var(--gut) + 30px);top:50%;translate:0 -50%;z-index:9;
  width:min(26vw,370px);max-height:80svh;overflow:auto;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .8s ease}
.roll .ro-info.on{visibility:visible}
.roll.spread .ro-info.on{opacity:1;pointer-events:auto;transition:opacity 1s ease .22s}
.roll .ro-info::-webkit-scrollbar{width:0}

/* 每一列各自晚一點上來，像字幕一行一行打出來 */
.roll .ro-info>*{opacity:0;transform:translate3d(0,16px,0);
  transition:opacity .9s ease,transform 1.1s var(--vslow)}
.roll.spread .ro-info.on>*{opacity:1;transform:none}
.roll.spread .ro-info.on>*:nth-child(2){transition-delay:.30s}
.roll.spread .ro-info.on>*:nth-child(3){transition-delay:.38s}
.roll.spread .ro-info.on>*:nth-child(4){transition-delay:.46s}
.roll.spread .ro-info.on>*:nth-child(5){transition-delay:.54s}
.roll.spread .ro-info.on>*:nth-child(6){transition-delay:.62s}
.roll.spread .ro-info.on>*:nth-child(7){transition-delay:.70s}
.roll.spread .ro-info.on>*:nth-child(8){transition-delay:.78s}

.roll .ro-info .ro-x{position:absolute;right:-6px;top:-6px;width:34px;height:34px;
  display:grid;place-items:center;opacity:.4;transition:opacity .6s ease}
.roll .ro-info .ro-x:hover{opacity:1}
.roll .ro-info .ro-x svg{width:11px;height:11px;overflow:visible}
.roll .ro-info .ro-x svg line{stroke:var(--paper);stroke-width:1}
.roll .ro-info .k{display:block;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.34em;color:var(--bronze)}
/* ⚠ 這一行的字級是**跟左上角的標記綁在一起**的。
   2026-08-20 抓到：它本來是 clamp(20px,1.9vw,29px)，1440 時 27.4px，
   比標記的 25.9px 還大——一直違反「建案名不能比璞玥建設大」那條規矩，
   因為我之前只量了星旁邊的 `.vn-lb b`，沒量點開之後的這一個。
   改標記字級的時候**這一行要一起改**，然後跑 starfit.js 與 mobtype.js。 */
.roll .ro-info h3{margin-top:15px;font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(14px,1.2vw,18px);letter-spacing:.16em;line-height:1.4}
.roll .ro-info .en{display:block;margin-top:11px;font-family:var(--mono);font-size:8.5px;
  letter-spacing:.44em;color:var(--paper-3)}
.roll .ro-info .rule{height:1px;background:var(--hair-2);margin:clamp(20px,3vh,30px) 0}
.roll .ro-info p{font-size:12.5px;line-height:2.25;color:var(--paper-2);letter-spacing:.05em}
.roll .ro-info dl{margin-top:clamp(20px,3vh,30px);border-top:1px solid var(--hair-2)}
.roll .ro-info dl>div{display:grid;grid-template-columns:auto minmax(0,1fr);gap:16px;
  align-items:baseline;padding:13px 0;border-bottom:1px solid var(--hair-2)}
.roll .ro-info dt{font-family:var(--mono);font-size:8.5px;letter-spacing:.26em;color:var(--paper-3)}
.roll .ro-info dd{font-family:var(--serif);font-weight:500;font-size:13px;
  letter-spacing:.12em;color:var(--paper);text-align:right}
.roll .ro-info .go{margin-top:clamp(20px,3vh,30px)}


/* 攤開時：走帶從「五個案子」換成「這一卷有幾張」 */
.roll.spread .ro-perf.proj{display:none}
.roll.spread .ro-perf.shot{display:flex}
/* 攤開的那一張加一道細框，跟關起來時區分開 */

@media (max-width:860px){
  /* 手機也要能看放映——建案頁已經沒了，這裡是唯一看得到渲染圖的地方。
     **資訊欄站在圖的下面，不疊在圖上。**（2026-08-18 Ethan：「點開後
     project 跟建案名稱整個會擋到圖片。」）

     `--iy` 是 py.js 量出來的「那一格攤開後的下緣 ＋ 18px」，
     所以這一塊的上緣永遠貼著圖的下緣，換手機、轉向都不必再調。
     沒有 --iy 的時候（理論上不會發生）退回舊的貼下緣寫法。 */
  .roll .ro-info{position:absolute;left:7vw;right:7vw;translate:0 0;
    top:var(--iy,auto);bottom:clamp(14px,3vh,30px);width:auto;max-height:none;
    padding:clamp(15px,3.4vw,20px) clamp(15px,3.4vw,20px) clamp(16px,3.4vw,22px);
    background:none;box-shadow:none;
    display:flex;flex-direction:column;justify-content:flex-start}
  .roll .ro-info .ro-x{right:0;top:-2px}
  .roll .ro-info .k{font-size:9px;letter-spacing:.32em}
  .roll .ro-info h3{margin-top:11px}   /* 字級在 900 區塊 */
  .roll .ro-info .en{display:none}
  .roll .ro-info .rule{margin:clamp(13px,2.2vh,20px) 0}
  /* 行距 2.05 → 1.9：最矮的機型（320×568）圖已經縮到下限了，
     剩下的差距從行距補。1.9 對 12.5px 的內文仍然很鬆。 */
  .roll .ro-info p{font-size:12.5px;line-height:1.9}
  .roll .ro-info dl{display:none}
  /* 引導改貼在圖的下緣裡面（那裡本來就是收黑的），不要飄在圖的正中央 */
  .roll .ro-more{bottom:calc(100% - var(--iy,60svh) + 30px)}
  }
@media (prefers-reduced-motion:reduce){
  .roll .ro-info{display:none}
}

/* ════════════════════════════════════════════════════════════════════
   十二、掃描顯影　SWEEP
   ──────────────────────────────────────────────────────────────────
   進頁是完全的黑。一道極細的光線從上緣往下掃過整屏，
   掃過的地方畫面才顧出來——像一張剖面圖在被掃描。
   光走到底就淡掉，字這時候才浮上來。整段約 3.2 秒。

   遮幕只寫一個 translateY，影像自己收一點 scale，光只有位移。
   沒有 mask、沒有 clip-path、沒有 filter。
   ════════════════════════════════════════════════════════════════════ */
.sweep{position:relative;height:100svh;min-height:540px;overflow:hidden;background:var(--ink)}
.sweep .sw-im{position:absolute;inset:0;overflow:hidden;z-index:2}
.sweep .sw-im img{width:100%;height:100%;object-fit:cover;display:block;
  will-change:transform;transform:scale(1.05);transform-origin:50% 46%}
/* 遮幕：一整片黑往下退，退到哪裡畫面就顯到哪裡 */
.sweep .sw-mask{position:absolute;inset:0;z-index:4;background:var(--ink);
  will-change:transform;transform:translate3d(0,0,0)}
/* 那道光：橫的，跟著遮幕的下緣走 */
.sweep .sw-bar{position:absolute;left:-2%;right:-2%;top:0;height:40px;margin-top:-20px;
  z-index:5;pointer-events:none;will-change:transform;
  background:linear-gradient(to bottom,transparent 0%,rgba(232,220,196,.05) 30%,
    rgba(232,220,196,.28) 45%,rgba(255,253,248,.95) 50%,rgba(232,220,196,.28) 55%,
    rgba(232,220,196,.05) 70%,transparent 100%)}

@keyframes swDown{to{transform:translate3d(0,101%,0)}}
@keyframes swBarDown{
  0%{transform:translate3d(0,-2vh,0);opacity:0}
  8%{opacity:1} 82%{opacity:1}
  100%{transform:translate3d(0,102vh,0);opacity:0}
}
@keyframes swSettle{from{transform:scale(1.05)}to{transform:scale(1)}}
@keyframes swIn{from{opacity:0;transform:translate3d(0,20px,0)}to{opacity:1;transform:none}}

.sweep .sw-mask{animation:swDown 1.95s var(--deep) .35s both}
.sweep .sw-bar{animation:swBarDown 1.95s var(--deep) .35s both}
.sweep .sw-im img{animation:swSettle 3.4s var(--vslow) .35s both}

/* 只留一行編號與一行說明。標語不放在首屏，留到頁面中間才出現。 */
.sweep::after{content:"";position:absolute;inset:0;z-index:6;pointer-events:none;
  background:linear-gradient(to bottom,rgba(0,0,0,.34) 0%,transparent 26%,
      transparent 46%,rgba(0,0,0,.76) 100%),
    linear-gradient(90deg,rgba(0,0,0,.46) 0%,rgba(0,0,0,.1) 32%,transparent 58%)}
.sweep .sw-tx{position:absolute;left:var(--gut);right:var(--gut);
  bottom:clamp(56px,10vh,124px);z-index:7;max-width:min(34em,74vw)}
.sweep .sw-tx .k{display:block;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.34em;color:var(--bronze);opacity:0;
  animation:swIn 1.4s var(--vslow) 2.5s both}
.sweep .sw-tx .sub{margin-top:20px;font-size:13px;line-height:2.25;color:var(--paper-2);
  letter-spacing:.06em;max-width:24em;opacity:0;
  animation:swIn 1.6s var(--vslow) 2.75s both}
.sweep .sw-cue{position:absolute;left:50%;bottom:clamp(20px,3.2vh,34px);translate:-50% 0;z-index:7;
  font-family:var(--mono);font-size:9px;letter-spacing:.36em;color:var(--paper-3);
  opacity:0;animation:swIn 1.6s ease 3.1s both}
body.moved .sweep .sw-cue{opacity:0;animation:none}

@media (max-width:820px){
  .sweep .sw-tx{max-width:none}
  .sweep::after{background:linear-gradient(to bottom,rgba(0,0,0,.3) 0%,transparent 22%,
    transparent 34%,rgba(0,0,0,.84) 100%)}
}
@media (prefers-reduced-motion:reduce){
  .sweep .sw-mask,.sweep .sw-bar{display:none}
  .sweep .sw-im img{animation:none!important;transform:none!important}
  .sweep .sw-tx>*,.sweep .sw-cue{opacity:1;animation:none!important;transform:none!important}
}

/* ════════════════════════════════════════════════════════════════════
   十三、建案頁的四個版式　FIGSET／LAY／PAIR.TALK／SURVEY
   ──────────────────────────────────────────────────────────────────
   建案頁原本四頁同一套模板，Ethan 的評語是「好像只是把渲染圖放上去而已」。
   這四個是拿來交錯用的，不要一頁只用一種：

     .figset      圖組　　同一段裡放尺寸差到四倍的兩張圖
     .lay         疊圖　　局部特寫壓在滿版圖的一角，往下超出邊界
     .pair.talk   並置　　不同來源的兩張圖，不等高也不等寬
     .survey      量測　　圖是證據，右欄是基地講得出來的事實

   玥蓉用 .survey 當骨架，其餘三個交錯；另外三個案子以 .figset 為主，
   .survey 留給玥蓉獨有——它是唯一講得出基地數字的案子。
   ════════════════════════════════════════════════════════════════════ */
/* ── A　圖組：同一段裡放極端不同尺寸的兩張圖 ────────────────── */
.figset{padding:clamp(30px,6vh,70px) 0}
.figset .fs-top{display:grid;grid-template-columns:minmax(0,.34fr) minmax(0,1fr);
  gap:clamp(24px,5vw,90px);align-items:end;padding:0 var(--gut)}
.figset .fs-sm .ph-box{aspect-ratio:3/4}
.figset .fs-tx{padding-bottom:clamp(6px,1.4vh,18px)}
.figset .fs-tx h3{font-family:var(--serif);font-weight:500;
  font-size:clamp(19px,2.3vw,30px);letter-spacing:.2em;line-height:1.6}
.figset .fs-tx p{font-size:13.5px;line-height:2.3;color:var(--paper-2);
  letter-spacing:.06em;margin-top:clamp(16px,2.4vh,26px);max-width:26em}
/* 寬幅橫過整個版心，跟上面那張小圖差到四倍寬 */
.figset .fs-wide{margin-top:clamp(48px,9vh,120px);padding:0 var(--gut)}
.figset .fs-wide .ph-box{aspect-ratio:21/9}
.figset .figc{display:flex;justify-content:space-between;gap:20px}
@media (max-width:820px){
  .figset .fs-top{grid-template-columns:minmax(0,1fr);gap:clamp(20px,4vh,34px)}
  .figset .fs-sm{max-width:62vw}
  .figset .fs-wide .ph-box{aspect-ratio:16/9}
}

/* ── B　疊圖：局部特寫壓在滿版圖的一角 ─────────────────────── */
.lay{position:relative;padding-bottom:clamp(70px,13vh,170px)}
.lay .ly-bed{position:relative;width:100vw;margin-left:calc(50% - 50vw);
  height:min(88vh,860px);overflow:hidden;background:#000}
.lay .ly-bed .im{position:absolute;left:0;right:0;top:-7%;bottom:-7%;overflow:hidden}
.lay .ly-bed img{width:100%;height:100%;object-fit:cover;display:block;
  will-change:transform;transform:translate3d(0,0,0)}
.lay .ly-bed::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(to bottom,rgba(0,0,0,.5) 0%,rgba(0,0,0,.1) 26%,
      rgba(0,0,0,.08) 46%,rgba(0,0,0,.82) 100%),
    linear-gradient(90deg,rgba(0,0,0,.62) 0%,rgba(0,0,0,.22) 32%,rgba(0,0,0,0) 58%)}
.lay .ly-tx{position:absolute;left:var(--gut);bottom:clamp(52px,9vh,110px);z-index:4;
  max-width:min(30em,52vw)}
.lay .ly-tx .k{display:block;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.34em;color:var(--bronze)}
.lay .ly-tx h3{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(21px,2.9vw,40px);letter-spacing:.18em;line-height:1.5;margin-top:15px}
.lay .ly-tx p{font-size:13.5px;line-height:2.3;color:var(--paper-2);
  letter-spacing:.06em;margin-top:clamp(14px,2.2vh,22px)}
/* 壓上去那一張：往下超出底圖的邊界，兩層才有前後 */
.lay .ly-inset{position:relative;z-index:5;width:min(30vw,400px);
  margin:clamp(-140px,-13vh,-90px) var(--gut) 0 auto}
/* 框線與投影只包影像，不要把圖說也框進去 */
.lay .ly-inset .ph-box{aspect-ratio:4/5;
  box-shadow:0 0 0 1px rgba(231,231,231,.14),0 40px 80px rgba(0,0,0,.7)}
.lay .ly-inset .figc{padding:0 2px}
@media (max-width:820px){
  .lay .ly-bed{height:min(72vh,620px)}
  .lay .ly-tx{max-width:none;right:var(--gut)}
  .lay .ly-inset{width:56vw;margin-top:-56px}
}

/* ── C　並置對話：不同來源的兩張圖，不等高也不等寬 ──────────── */
.pair.talk{display:grid;grid-template-columns:minmax(0,1.18fr) minmax(0,1fr);
  gap:clamp(16px,3vw,54px);align-items:start}
.pair.talk figure{position:relative;margin:0}
.pair.talk .t-a .ph-box{aspect-ratio:4/5}
.pair.talk .t-b{margin-top:clamp(60px,13vh,170px)}
.pair.talk .t-b .ph-box{aspect-ratio:1/1}
.pair.talk .src{display:block;font-family:var(--mono);font-size:8.5px;
  letter-spacing:.24em;color:var(--bronze);margin-bottom:7px}
@media (max-width:820px){
  .pair.talk{grid-template-columns:minmax(0,1fr)}
  .pair.talk .t-b{margin-top:0;margin-left:18vw}
}

/* ── D　量測：圖是證據，右欄是基地講得出來的事實 ─────────────── */
.survey{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);
  gap:clamp(28px,5vw,86px);align-items:center}
.survey .sv-im .ph-box{aspect-ratio:3/2}
.survey .sv-list{border-top:1px solid var(--hair-2)}
.survey .sv-list .row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:18px;
  align-items:baseline;padding:clamp(15px,2.4vh,24px) 0;border-bottom:1px solid var(--hair-2)}
.survey .sv-list b{font-family:var(--mono);font-weight:400;font-size:9px;
  letter-spacing:.26em;color:var(--paper-3)}
.survey .sv-list strong{font-family:var(--serif);font-weight:500;
  font-size:clamp(14px,1.35vw,19px);letter-spacing:.14em;color:var(--paper);text-align:right}
.survey .sv-list strong i{font-style:normal;font-family:var(--mono);font-size:.72em;
  letter-spacing:.16em;color:var(--paper-2);margin-left:.5em}
.survey .sv-note{margin-top:clamp(18px,2.6vh,28px);font-size:11.5px;line-height:2.1;
  color:var(--paper-3);letter-spacing:.05em}
@media (max-width:820px){
  .survey{grid-template-columns:minmax(0,1fr);gap:clamp(24px,4vh,40px)}
  .survey .sv-im .ph-box{aspect-ratio:16/10}
}

/* ════════════════════════════════════════════════════════════════════
   十四、進程尺　PROCESS
   ──────────────────────────────────────────────────────────────────
   「我們怎麼做」原本是五張卡片水平推移，看起來像簡報。改成一支尺：
   五站排在同一條軸上，一枚讀頭停在正在看的那一站，說明在下面換一段。
   進場時一道光掃過整條軸，掃完就停——只有這一次。

   全部只寫 transform 與 opacity。讀頭的位置只在載入、字體就緒、
   改變視窗時各量一次，換站時寫一次 transform，不掛在捲動上。
   ════════════════════════════════════════════════════════════════════ */
.proc{padding:clamp(18px,3vh,40px) 0 clamp(26px,5vh,70px)}
/* --pt 同時是上留白與軌道的高度位置：軌道、讀頭、五顆點都對齊同一條線，
   改一個地方就整排一起動。 */
.pr-axis{--pt:clamp(26px,4vh,46px);position:relative;padding-top:var(--pt)}
/* 軌道自己負責裁切——掃描線走到底會超出版心，不裁的話整頁會多出一條水平捲軸 */
.pr-rail{position:absolute;left:0;right:0;top:var(--pt);height:1px;background:var(--hair-2);
  overflow:hidden}

/* 掃描線：進場從左掃到右，一次就停 */
.pr-scan{position:absolute;left:0;top:0;height:100%;width:30%;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(232,219,190,.9),transparent);
  transform:translate3d(-40%,0,0);will-change:transform;pointer-events:none}
.proc.on .pr-scan{animation:prScan 2.3s cubic-bezier(.42,0,.16,1) .3s both}
@keyframes prScan{
  0%{opacity:0;transform:translate3d(-40%,0,0)}
  12%{opacity:1} 82%{opacity:1}
  100%{opacity:0;transform:translate3d(370%,0,0)}}

/* 讀頭：一顆立起來的小方塊，停在選到的那一站。位置由 JS 寫一次 transform。 */
.pr-head{position:absolute;left:0;top:calc(var(--pt) - 4px);width:8px;height:8px;
  margin-left:-4px;
  border:1px solid var(--bronze-hi);opacity:0;pointer-events:none;
  transform:translate3d(0,0,0) rotate(45deg);will-change:transform;
  transition:transform 1s var(--vslow),opacity 1.2s ease .5s}
.proc.on .pr-head{opacity:1}

.pr-stops{display:grid;grid-template-columns:repeat(5,minmax(0,1fr))}
.pr-st{position:relative;text-align:left;
  padding:clamp(18px,2.8vh,28px) clamp(10px,1.4vw,20px) 0 0;
  opacity:.4;transition:opacity .7s ease}
.pr-st.on{opacity:1}
.pr-st:hover,.pr-st:focus-visible{opacity:1;outline:0}
/* .pr-st 的上緣就是軌道那條線（--pt 之後），所以 -3px 剛好把 7px 的點壓在線上 */
.pr-st .dot{position:absolute;left:0;top:-3px;width:7px;height:7px;
  background:var(--paper-3);transform:scale(.62);
  transition:transform .9s var(--vslow),background .7s ease}
.pr-st.on .dot{transform:scale(1);background:var(--bronze-hi)}
.pr-st .n{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.3em;
  color:var(--bronze)}
.pr-st .t{display:block;margin-top:12px;font-family:var(--serif);font-weight:500;
  font-size:clamp(14px,1.55vw,20px);letter-spacing:.14em;color:var(--paper);line-height:1.5}
.pr-st .d{display:block;margin-top:10px;font-family:var(--mono);font-size:8.5px;
  letter-spacing:.22em;color:var(--paper-3)}

/* ── 一塊地的一生 ────────────────────────────────────────────
   Ethan 2026-08-16：「這邊每一個步驟，都要有相關對應的超厲害動畫。
   我指的是網站的一個**很創意的設計**，而不只是單單一個簡單的動畫而已。」

   所以五站不是五個各自的動畫，是**同一張圖被改五次**：
   01 量地　　現地上打三個測點，量出一條基線
   02 整合　　六塊地的分割線一條一條收掉，六個地主的點併到中間 ← 這是整合本身
   03 規劃設計　樓層線與柱線在圖桌上畫出來，輪廓先是虛的
   04 興建　　虛的變實的，一層一層從地面長上去，塔吊的鉤子放下來
   05 交屋　　塔吊收走，燈一格一格亮起來，產權界線繞一圈收口，蓋一個印

   往下走是累積的（前面畫過的留著，只是退到後面），往回走就倒回去。
   狀態寫在 .proc 的 data-st 上，其餘全部是 CSS——**換站才寫一次，捲動零成本**。
   線都帶 pathLength="1"，dasharray／offset 是 0–1 的比例，改幾何不必重算長度。 */
.pr-body{display:grid;grid-template-columns:minmax(0,1.28fr) minmax(0,1fr);
  gap:clamp(24px,3.4vw,60px);align-items:start;
  margin-top:clamp(24px,3.6vh,40px);padding-top:clamp(20px,2.8vh,28px);
  border-top:1px solid var(--hair-2)}
.pr-stage{position:relative}
.pr-stage svg{display:block;width:100%;height:auto;overflow:visible}
.pr-stage .ln{fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:1;
  stroke:var(--paper-3)}
.pr-stage .gr{stroke:rgba(231,231,231,.34)}
.pr-stage .ctx{stroke:rgba(231,231,231,.11)}

/* 01 量地 */
.pr-stage .mk{stroke:var(--bronze-hi);stroke-width:1.1;
  opacity:0;transform:translate3d(0,7px,0);transform-box:fill-box;transform-origin:50% 100%;
  transition:opacity .7s ease var(--d,0s),transform 1s var(--vslow) var(--d,0s)}
.pr-stage .dim{stroke:rgba(185,151,95,.5);stroke-dasharray:3 4;
  opacity:0;transform:scaleX(.2);transform-box:fill-box;transform-origin:0 50%;
  transition:opacity .8s ease .18s,transform 1.2s var(--vslow) .18s}
.proc[data-st="1"] .sv .mk,.proc[data-st="1"] .sv .dim{opacity:1;transform:none}
.proc .sv{opacity:.3;transition:opacity .9s ease}
.proc[data-st="1"] .sv{opacity:1}

/* 02 整合：分割線收掉、地主的點併到中間 */
.pr-stage .plot{stroke:rgba(231,231,231,.5);
  opacity:0;transition:opacity .9s ease .2s}
.pr-stage .cut{stroke:rgba(231,231,231,.42);stroke-dasharray:2 3;
  transform-box:fill-box;transform-origin:50% 100%;
  transition:transform 1s var(--vslow) var(--d,0s),opacity .7s ease var(--d,0s)}
.pr-stage .ow{fill:var(--bronze);opacity:0;
  transition:transform 1.4s var(--vslow) var(--d,0s),opacity .8s ease}
.proc[data-st="1"] .pc .plot{opacity:.5}
.proc[data-st="1"] .pc .ow{opacity:.75}
/* 走到 02 以後：線收掉、點併到中間、地成為一塊 */
.proc[data-st="2"] .pc .plot,.proc[data-st="3"] .pc .plot,
.proc[data-st="4"] .pc .plot,.proc[data-st="5"] .pc .plot{opacity:1}
.proc[data-st="2"] .pc .cut,.proc[data-st="3"] .pc .cut,
.proc[data-st="4"] .pc .cut,.proc[data-st="5"] .pc .cut{transform:scaleY(0);opacity:0}
.proc[data-st="2"] .pc .ow{opacity:1;transform:translate3d(var(--x),0,0)}
.proc[data-st="3"] .pc .ow,.proc[data-st="4"] .pc .ow,
.proc[data-st="5"] .pc .ow{opacity:0;transform:translate3d(var(--x),0,0)}

/* 03 規劃設計：線在圖桌上畫出來 */
.pr-stage .fl,.pr-stage .cl{stroke:rgba(185,151,95,.38);
  stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset 1s var(--vslow) var(--d,0s),opacity .8s ease}
.pr-stage .prof{stroke:rgba(231,231,231,.5);stroke-dasharray:4 4;
  stroke-dashoffset:1;opacity:0;transition:opacity .9s ease .5s}
.proc .pl{opacity:0;transition:opacity .8s ease}
.proc[data-st="3"] .pl,.proc[data-st="4"] .pl,.proc[data-st="5"] .pl{opacity:1}
.proc[data-st="3"] .pl .fl,.proc[data-st="3"] .pl .cl,
.proc[data-st="4"] .pl .fl,.proc[data-st="4"] .pl .cl,
.proc[data-st="5"] .pl .fl,.proc[data-st="5"] .pl .cl{stroke-dashoffset:0}
.proc[data-st="3"] .pl .prof{opacity:1}
.proc[data-st="4"] .pl,.proc[data-st="5"] .pl{opacity:.42}

/* 04 興建：一層一層長上去 ＋ 塔吊 */
.pr-stage .sl{fill:rgba(231,231,231,.075);stroke:rgba(231,231,231,.34);stroke-width:.9;
  opacity:0;transform:scaleY(0);transform-box:fill-box;transform-origin:50% 100%;
  transition:transform 1.05s var(--vslow) var(--d,0s),opacity .5s ease var(--d,0s)}
.proc[data-st="4"] .bd .sl,.proc[data-st="5"] .bd .sl{opacity:1;transform:none}
.proc .cr{opacity:0;transition:opacity .8s ease}
.pr-stage .cr .ln{stroke:rgba(231,231,231,.3)}
.pr-stage .hk{transform:translate3d(0,-70px,0);
  transition:transform 1.6s var(--vslow) .5s}
.proc[data-st="4"] .cr{opacity:1}
.proc[data-st="4"] .hk{transform:none}

/* 05 交屋：燈亮、界線收口、蓋印 */
.pr-stage .wn{fill:var(--bronze-hi);opacity:0;
  transform:scale(.3);transform-box:fill-box;transform-origin:50% 50%;
  transition:opacity .55s ease var(--d,0s),transform .8s var(--vslow) var(--d,0s)}
.proc[data-st="5"] .wd .wn{opacity:.8;transform:none}
.pr-stage .bl{stroke:var(--bronze);stroke-width:1;stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset 1.7s var(--vslow) .25s}
.pr-stage .sl-seal{fill:none;stroke:var(--bronze-hi);stroke-width:1;
  opacity:0;transform:scale(.4) rotate(-12deg);transform-box:fill-box;transform-origin:50% 50%;
  transition:opacity .7s ease 1.5s,transform .9s var(--vslow) 1.5s}
.proc .bo{opacity:0;transition:opacity .6s ease}
.proc[data-st="5"] .bo{opacity:1}
.proc[data-st="5"] .bl{stroke-dashoffset:0}
.proc[data-st="5"] .sl-seal{opacity:1;transform:none}

/* 說明：五段疊在同一個位置。**出場要比進場快而且不重疊**——
   兩段字疊著各半透明地互相溶接，看起來就是重影（Ethan 回報過）。
   走的那一段 .22s 收掉，來的那一段 .3s 之後才開始。 */
.pr-panes{position:relative;min-height:clamp(150px,20vh,186px)}
.pr-pn{position:absolute;left:0;right:0;top:0;
  opacity:0;transform:translate3d(0,10px,0);pointer-events:none;
  transition:opacity .22s ease,transform .22s ease}
.pr-pn.on{opacity:1;transform:none;pointer-events:auto;
  transition:opacity .7s ease .3s,transform .9s var(--vslow) .3s}
.pr-pn h4{font-family:var(--serif);font-weight:500;font-size:clamp(16px,1.8vw,22px);
  letter-spacing:.2em;color:var(--paper)}
.pr-pn p{margin-top:clamp(13px,1.9vh,19px);font-size:13.5px;line-height:2.3;
  color:var(--paper-2);letter-spacing:.06em}

@media (max-width:960px){
  .pr-body{grid-template-columns:minmax(0,1fr);gap:clamp(20px,3vh,32px)}
  .pr-stage{order:2}
}
@media (max-width:820px){
  /* 窄螢幕排不下五欄。改成三欄兩列，點就好，讀頭沒有意義就收掉。 */
  .pr-stops{grid-template-columns:repeat(3,minmax(0,1fr));row-gap:clamp(16px,2.6vh,26px)}
  .pr-head,.pr-scan{display:none}
  .pr-st{padding-top:14px}
  .pr-st .dot{position:static;display:block;margin-bottom:12px;transform:scale(1)}
  .pr-st.on .dot{transform:scale(1.4)}
  .pr-panes{min-height:clamp(180px,30vh,230px)}
}
@media (prefers-reduced-motion:reduce){
  .pr-scan,.pr-head{display:none}
  /* 不做動畫的人：圖停在最後一個狀態（蓋好的房子），字直接換 */
  .pr-stage *{transition:none!important}
  .pr-pn{transition:none!important}
}

/* 版圖／作品區的小標。比 .sec-hd 輕，掛在某一個人底下用。 */
.wk-hd{display:flex;align-items:baseline;gap:clamp(12px,2vw,26px);
  margin-top:clamp(28px,5vh,58px);padding-bottom:14px;
  border-bottom:1px solid var(--hair-2)}
.wk-hd b{font-family:var(--mono);font-weight:400;font-size:9px;letter-spacing:.3em;
  color:var(--bronze)}
.wk-hd span{font-size:12.5px;letter-spacing:.08em;color:var(--paper-3)}
/* ════════════════════════════════════════════════════════════════════
   十五、四塊料　THE BLOCK
   ──────────────────────────────────────────────────────────────────
   ⚠ 2026-08-10 起**沒有頁面在用這一節**。Ethan 說「退回今天一開始的版本」，
   團隊頁換回 08-09 那一份（首屏定格＋四個人各一段）。
   這一整節與 py.js 的「四塊料」模組都留著，沒有副作用
   （JS 找不到 #board 就直接 return）。要接回來：把 team.html 換成
   四塊料的版面即可，作法寫在 _交接文件.md 第六節。
   下面這一段是當初的設計說明，留著備查。
   ──────────────────────────────────────────────────────────────────
   四個人＝四塊料。**這塊板子是底，不是主角。**

   第一版做成一塊會發光、有梳齒、有計數器與狀態標籤的板子，
   Ethan 的評語是「拼圖目前看起來太科技感，與本網站的風格不搭」，
   問他哪裡出戲，他指的是**梳齒的形狀**，方向是**「拼圖變安靜的背景」**。
   所以這一版：

     · 接縫改成一道慢慢遊走的**裂縫**（中段一個柔和的圓瓣），不是銑出來的方齒
     · 料面壓到近乎全黑，礦脈只留兩道、淡到幾乎看不見
     · 切口那道會呼吸的青銅光**拿掉了**，只剩一條靜態的細線
     · 計數器、「散開／已歸位」、✓、中間那個章，全部拿掉
     · 格子不再是有內陰影的凹槽，改成全站慣用的細線框
     · 名字放大成明體，圖也放大——**前面是人與圖，後面才是料**

   「切自同一塊料」還在：四塊的表面是同一組 background，
   而且每一塊都是整塊板那麼大的方塊，只是被 clip-path 切出自己那一片，
   所以拼回去礦脈是連續的，散開就斷掉。這件事是自動成立的，不是畫上去的。

   散開的幅度只有 ±1.3%（第一版是 ±5%）。這一版不是要人來玩它，
   是讓「四塊」這件事在眼角餘光裡成立。

   幾何（clip-path 與散開方向）由 `_gen-bk.py` 產生，附在這一節的最後。
   要改裂縫的走法、圓瓣的位置，改那支腳本重跑，把輸出貼回來，
   **不要手改那幾行座標，也不要改回方齒**。
   ════════════════════════════════════════════════════════════════════ */
/* 上緣要讓開固定在左上角的標記，跟其他內頁的 .page 同一個量。 */
.bk-sec{padding:clamp(112px,16vh,180px) 0 clamp(24px,3.6vh,48px)}
/* 抬頭排成一列：標題靠左、說明靠右下。豎著排會把板子整個推到摺線以下。 */
.bk-hd{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;
  gap:clamp(14px,3vw,56px);padding-bottom:clamp(16px,2.4vh,26px);
  border-bottom:1px solid var(--hair-2)}
.bk-hd .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.36em;color:var(--bronze)}
.bk-hd h1{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(22px,2.7vw,38px);line-height:1.3;letter-spacing:.2em;margin-top:12px}
.bk-hd .sub{flex:1 1 22em;font-size:13px;line-height:2.1;color:var(--paper-2);
  letter-spacing:.06em;max-width:30em}

/* ── 板子 ── */
.bk-board{position:relative;width:100%;aspect-ratio:1.5/1;margin-top:clamp(26px,4.4vh,48px)}
.bk{position:absolute;inset:0;display:block;padding:0;border:0;background:none;
  text-align:left;
  transform:translate3d(calc(var(--ox) * var(--k,1)),calc(var(--oy) * var(--k,1)),0);
  transition:transform 1.5s var(--vslow)}
.bk.set{transform:translate3d(0,0,0)}
/* contain:paint 讓這三層各自獨立成一塊，捲動時不會互相拖著重畫。 */
.bk>i{position:absolute;inset:0;display:block;contain:paint}
/* 一、板厚：同樣的形狀往右下位移。clip 掛在這一層自己身上，
   掛到 .bk 上的話這一層會被父層切掉，厚度就消失了（踩過）。
   薄一點，這一版不需要看起來像一塊很厚的板子。 */
.bk .side{transform:translate3d(6px,7px,0);
  background:linear-gradient(135deg,#201c15 0%,#16130e 38%,#0b0a08 74%,#060605 100%)}
/* 二、切口：靜態的一條細線。**不要再加會循環的光**，那是上一版被打回來的原因之一。 */
.bk .rim{transform:scale(1.0022);
  background:linear-gradient(135deg,rgba(185,151,95,.5) 0%,rgba(150,124,80,.3) 44%,
    rgba(90,76,50,.18) 72%,rgba(48,42,30,.12) 100%);
  opacity:.2;transition:opacity .9s ease}
.bk.set .rim{opacity:.28}
.bk:hover .rim{opacity:.5}
/* 三、料的表面。四塊共用同一組漸層，每一塊都是整塊板那麼大，
   所以拼回去礦脈是連續的。這一版只留兩道礦脈，而且淡到要找才看得到。 */
.bk .face{
  background:
    linear-gradient(74deg,transparent 21.6%,rgba(226,218,202,.05) 21.82%,transparent 22.04%),
    linear-gradient(81deg,transparent 55.5%,rgba(214,204,184,.035) 55.7%,transparent 55.92%),
    radial-gradient(80% 64% at 26% 18%,rgba(231,231,231,.022),transparent 68%),
    radial-gradient(66% 54% at 80% 84%,rgba(0,0,0,.5),transparent 66%),
    linear-gradient(158deg,#111110,#0d0c0b 56%,#080807)}
.bk:focus{outline:none}

/* 每一塊裡面的內容。整組貼在自己那個象限上，跟著那一塊一起飛。 */
.bk .in{position:absolute;left:var(--l);top:var(--t);width:50%;height:50%;
  display:flex;flex-direction:column;z-index:3;
  padding:clamp(18px,2.4vw,38px) clamp(18px,2.4vw,38px) clamp(20px,2.6vw,42px)}
.bk .hd{display:flex;align-items:baseline;gap:clamp(10px,1.3vw,20px);flex:0 0 auto}
.bk .hd .no{font-family:var(--mono);font-weight:400;font-size:9px;letter-spacing:.3em;color:var(--bronze)}
.bk .hd .pr{font-family:var(--serif);font-weight:500;font-size:clamp(19px,2.1vw,30px);
  letter-spacing:.2em;color:var(--paper);line-height:1.4}
.bk .hd .ti{font-family:var(--sans);font-weight:300;font-size:12px;letter-spacing:.14em;
  color:var(--paper-2)}
.bk .sk{display:block;flex:0 0 auto;margin-top:10px;
  padding-bottom:clamp(14px,1.9vh,22px);
  font-family:var(--mono);font-weight:400;font-size:8.5px;letter-spacing:.26em;
  color:var(--paper-3)}

/* 格子：全站慣用的細線框，不是有內陰影的凹槽（凹槽像 UI 面板，被打回來過）。 */
.bk .cells{display:grid;flex:1 1 auto;min-height:0;gap:clamp(10px,1.2vw,19px)}
.bk .cells.c3{grid-template-columns:repeat(3,minmax(0,1fr))}
.bk .cells.c4{grid-template-columns:repeat(4,minmax(0,1fr))}
.bk .cell{position:relative;display:flex;flex-direction:column;min-width:0;min-height:0}
.bk .cell .im{position:relative;display:block;flex:1 1 auto;min-height:0;overflow:hidden;
  background:var(--ink-3);border:1px solid var(--hair-2);
  transition:border-color .6s ease}
.bk a.cell:hover .im{border-color:rgba(185,151,95,.55)}
.bk .cell .im img{width:100%;height:100%;object-fit:cover;object-position:top center;
  filter:grayscale(.62) brightness(.5) saturate(.55);transform:scale(1.02);
  transition:filter .9s ease,transform 1.6s var(--slow)}
/* 歸位之後整塊都亮一階，不然沒有連結的那幾格永遠停在最暗，等於白放。
   hover 的選擇器要帶 .bk 才壓得過這一條。 */
.bk.set .cell .im img{filter:grayscale(.42) brightness(.68) saturate(.72)}
.bk a.cell:hover .im img{filter:grayscale(.04) brightness(.95) saturate(.95);transform:scale(1.06)}
.bk .cell .tx{display:block;flex:0 0 auto;padding-top:clamp(9px,1vw,14px)}
.bk .cell .tx b{display:block;font-family:var(--serif);font-weight:500;
  font-size:clamp(11.5px,1.05vw,15px);letter-spacing:.14em;color:var(--paper);line-height:1.5;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bk .cell .tx em{display:block;margin-top:6px;font-style:normal;font-family:var(--mono);
  font-size:7.5px;letter-spacing:.14em;color:var(--paper-3);line-height:1.7;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bk .cell .ar{position:absolute;right:9px;top:9px;
  margin:0;font-style:normal;font-size:9px;color:var(--bronze);opacity:0;
  transition:opacity .5s ease,transform .7s var(--slow)}
.bk a.cell:hover .ar{opacity:1;transform:translate(3px,-3px)}

/* ── 名字清單 ── */
.bk-lg{display:flex;flex-wrap:wrap;gap:clamp(13px,2.2vw,40px);
  margin-top:clamp(16px,2.4vh,26px)}
.bk-lg a{display:flex;align-items:baseline;gap:11px;opacity:.5;transition:opacity .55s ease}
.bk-lg a.done{opacity:.78}
.bk-lg a:hover,.bk-lg a.on{opacity:1}
.bk-lg .ro{font-family:var(--mono);font-size:9px;letter-spacing:.26em;color:var(--bronze)}
.bk-lg .nm{font-family:var(--serif);font-weight:500;font-size:14px;letter-spacing:.2em}
.bk-lg .ct{font-family:var(--mono);font-size:9px;letter-spacing:.2em;color:var(--paper-3)}

/* ── 板子下面：四個人，兩欄兩列 ──────────────────────────────
   事業版圖已經鑲在板子裡了，這裡不再重複一次網站卡，
   只講「這個人在璞玥負責哪一段」。所以段落要短、要並排；
   一人一屏的 .split 在這裡會留下三大片空白（試過）。

   **四個人都不放照片**（2026-08-10 Ethan 指定，簡連成與林子愷的頭貼撤掉）。
   所以四篇一律 .tx：上緣一條細線，字級完全相同，沒有誰比誰大。 */
.duo{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(30px,5vw,84px) clamp(24px,4vw,70px);
  margin-top:clamp(38px,7vh,88px)}
.duo article{display:flex;flex-direction:column}
.duo article.tx{padding-top:clamp(16px,2.4vh,24px);border-top:1px solid var(--hair-2)}
.duo .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.32em;color:var(--bronze)}
.duo h3{font-family:var(--serif);font-weight:500;color:var(--paper);
  font-size:clamp(21px,2.5vw,32px);letter-spacing:.18em;line-height:1.5;margin:12px 0 0}
.duo .rl{display:block;margin-top:11px;font-size:12.5px;letter-spacing:.1em;color:var(--paper)}
.duo p{font-size:13.5px;line-height:2.3;color:var(--paper-2);letter-spacing:.06em;
  margin-top:clamp(13px,1.9vh,19px);max-width:27em}
.duo p.fine{font-size:12px;line-height:2;color:var(--paper-3)}

@media (max-width:860px){
  .duo{grid-template-columns:minmax(0,1fr);gap:clamp(30px,5vh,46px);
    margin-top:clamp(30px,5vh,56px)}
}

@media (max-width:860px){
  /* 散開的幅度收一半，不然四塊會頂出版心，右邊多出一條水平捲軸 */
  .bk{--k:.5}
  /* 手機是兩欄兩列，每一格只有三十幾 px 高，窗口會變成一條細縫。
     板子改成直的，把高度還給格子——寬度是螢幕給的，改不了，只能往下長。 */
  .bk-board{aspect-ratio:.62/1}
  .bk-sec{padding-top:clamp(96px,13vh,140px)}
  .bk .in{padding:clamp(12px,3.2vw,18px)}
  .bk .hd{flex-wrap:wrap;gap:4px 10px}
  .bk .hd .pr{font-size:clamp(15px,4.2vw,19px);letter-spacing:.12em}
  .bk .hd .ti{display:none}
  .bk .sk{display:none}
  .bk .cells,.bk .cells.c3,.bk .cells.c4{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  /* 窄欄放不下六個字，不換行就一路吃掉變成「象玥建築…」。直板有高度，讓它折 */
  .bk .cell .tx{padding-top:6px}
  .bk .cell .tx b{font-size:10.5px;letter-spacing:.04em;line-height:1.45;white-space:normal}
  .bk .cell .tx em{display:none}
  .bk-lg{gap:11px 20px}
  .bk-lg .ct{display:none}
}
@media (prefers-reduced-motion:reduce){
  .bk{transform:none!important}
}
/* ── 以下由 _gen-bk.py 產生，不要手改 ── */
.bk1>i{clip-path:polygon(0% 0%,50% 0%,50.374% 1.923%,50.547% 3.846%,50.388% 5.769%,50.261% 7.692%,50.206% 9.615%,50.231% 11.538%,50.315% 13.462%,50.417% 15.385%,50.502% 17.308%,50.573% 19.231%,50.675% 21.154%,50.849% 23.077%,51.048% 25.0%,51.115% 26.923%,50.91% 28.846%,50.469% 30.769%,50.006% 32.692%,49.736% 34.615%,49.721% 36.538%,49.878% 38.462%,50.075% 40.385%,50.218% 42.308%,50.267% 44.231%,50.235% 46.154%,50.091% 48.077%,50.0% 50.0%,48.077% 50.325%,46.154% 50.491%,44.231% 50.365%,42.308% 50.269%,40.385% 50.254%,38.462% 50.353%,36.538% 50.596%,34.615% 51.0%,32.692% 51.526%,30.769% 52.012%,28.846% 52.203%,26.923% 51.915%,25.0% 51.205%,23.077% 50.349%,21.154% 49.64%,19.231% 49.227%,17.308% 49.108%,15.385% 49.205%,13.462% 49.428%,11.538% 49.69%,9.615% 49.92%,7.692% 50.07%,5.769% 50.124%,3.846% 50.098%,1.923% 50.02%,0.0% 50.0%)}
.bk1{--ox:-1.35%;--oy:-1.15%}
.bk2>i{clip-path:polygon(50% 0%,100% 0%,100% 50%,98.077% 50.059%,96.154% 50.335%,94.231% 50.451%,92.308% 50.453%,90.385% 50.366%,88.462% 50.219%,86.538% 50.017%,84.615% 49.732%,82.692% 49.358%,80.769% 48.983%,78.846% 48.79%,76.923% 48.914%,75.0% 49.288%,73.077% 49.675%,71.154% 49.86%,69.231% 49.79%,67.308% 49.559%,65.385% 49.304%,63.462% 49.132%,61.538% 49.094%,59.615% 49.189%,57.692% 49.381%,55.769% 49.609%,53.846% 49.81%,51.923% 49.966%,50.0% 50.0%,50.091% 48.077%,50.235% 46.154%,50.267% 44.231%,50.218% 42.308%,50.075% 40.385%,49.878% 38.462%,49.721% 36.538%,49.736% 34.615%,50.006% 32.692%,50.469% 30.769%,50.91% 28.846%,51.115% 26.923%,51.048% 25.0%,50.849% 23.077%,50.675% 21.154%,50.573% 19.231%,50.502% 17.308%,50.417% 15.385%,50.315% 13.462%,50.231% 11.538%,50.206% 9.615%,50.261% 7.692%,50.388% 5.769%,50.547% 3.846%,50.374% 1.923%)}
.bk2{--ox:1.45%;--oy:-0.95%}
.bk3>i{clip-path:polygon(0% 50%,1.923% 50.02%,3.846% 50.098%,5.769% 50.124%,7.692% 50.07%,9.615% 49.92%,11.538% 49.69%,13.462% 49.428%,15.385% 49.205%,17.308% 49.108%,19.231% 49.227%,21.154% 49.64%,23.077% 50.349%,25.0% 51.205%,26.923% 51.915%,28.846% 52.203%,30.769% 52.012%,32.692% 51.526%,34.615% 51.0%,36.538% 50.596%,38.462% 50.353%,40.385% 50.254%,42.308% 50.269%,44.231% 50.365%,46.154% 50.491%,48.077% 50.325%,50.0% 50.0%,50.12% 51.923%,50.13% 53.846%,50.127% 55.769%,50.185% 57.692%,50.255% 59.615%,50.284% 61.538%,50.223% 63.462%,50.047% 65.385%,49.751% 67.308%,49.332% 69.231%,48.79% 71.154%,48.163% 73.077%,47.592% 75.0%,47.316% 76.923%,47.522% 78.846%,48.174% 80.769%,49.008% 82.692%,49.728% 84.615%,50.176% 86.538%,50.359% 88.462%,50.365% 90.385%,50.29% 92.308%,50.217% 94.231%,50.201% 96.154%,50.145% 98.077%,50.0% 100.0%,0% 100%)}
.bk3{--ox:-1.2%;--oy:1.1%}
.bk4>i{clip-path:polygon(50% 50%,51.923% 49.966%,53.846% 49.81%,55.769% 49.609%,57.692% 49.381%,59.615% 49.189%,61.538% 49.094%,63.462% 49.132%,65.385% 49.304%,67.308% 49.559%,69.231% 49.79%,71.154% 49.86%,73.077% 49.675%,75.0% 49.288%,76.923% 48.914%,78.846% 48.79%,80.769% 48.983%,82.692% 49.358%,84.615% 49.732%,86.538% 50.017%,88.462% 50.219%,90.385% 50.366%,92.308% 50.453%,94.231% 50.451%,96.154% 50.335%,98.077% 50.059%,100.0% 50.0%,100% 100%,50% 100%,50.145% 98.077%,50.201% 96.154%,50.217% 94.231%,50.29% 92.308%,50.365% 90.385%,50.359% 88.462%,50.176% 86.538%,49.728% 84.615%,49.008% 82.692%,48.174% 80.769%,47.522% 78.846%,47.316% 76.923%,47.592% 75.0%,48.163% 73.077%,48.79% 71.154%,49.332% 69.231%,49.751% 67.308%,50.047% 65.385%,50.223% 63.462%,50.284% 61.538%,50.255% 59.615%,50.185% 57.692%,50.127% 55.769%,50.13% 53.846%,50.12% 51.923%)}
.bk4{--ox:1.3%;--oy:1.25%}
/* 每一塊的象限原點：裡面那組內容貼在自己的象限上 */
.bk1{--l:0%;--t:0%}
.bk2{--l:50%;--t:0%}
.bk3{--l:0%;--t:50%}
.bk4{--l:50%;--t:50%}

/* ════════════════════════════════════════════════════════════════════
   十六、地平線　HORIZON　（about.html 專用）
   ──────────────────────────────────────────────────────────────────
   Ethan 的規格：「電影級別、大師級別」「不要只是看圖說故事」
   「要有非常新穎的動畫設計」。四個選項裡他挑了「地平線」。

   概念：**整頁只有一條線，而且它從頭到尾沒有動過。**
   開場那張台北全景的地平線是它的起點；往下捲，照片一張一張換掉，
   尺度從整個盆地跳到一條街、跳到一塊石檯面、跳到一扇窗，
   但那條線始終停在同一個高度——因為**每一張照片都被算過，
   讓它自己的地平線剛好落在那條線上**。

   對齊是算出來的，不是眼睛喬的。每張圖在 HTML 上標了 data-hz
   （地平線在原圖高度的比例，用程式量出來再目視校正過），
   JS 依當下的視窗尺寸換算 object-position，讓那一列剛好落在 --hy。
   只在載入、字體就緒、改變視窗時各算一次，捲動時零成本。

   捲動時只寫兩件事：照片的 opacity（交叉溶接）與外框的 translateX
   （沿著地平線很慢地橫移）。**沒有任何垂直位移**——垂直一動，
   地平線就散了，整個概念就沒了。
   ════════════════════════════════════════════════════════════════════ */
/* 那條線在螢幕上的高度。整頁所有的對齊都以它為準。 */
.hz{position:relative;--hy:48svh}
.hz-fix{position:sticky;top:0;height:100svh;overflow:hidden;background:var(--ink)}

/* 照片：整張蓋滿舞台。**不用 object-fit**——cover 對寬圖只會左右裁，
   上下完全沒有餘裕，地平線就推不動了（六張裡有四張對不到線，量過）。
   改成自己算：JS 依 data-hz 算出剛好能蓋滿又讓地平線落在線上的縮放與位移，
   寫成一個 transform。橫移也併進同一個 transform，不另外再包一層。 */
/* will-change 不寫死在 CSS 裡。六張全螢幕的圖同時常駐圖層＝三十幾 MB 的
   顯示記憶體，筆電的內顯會被拖垮。改由 JS 只把「現在這張與下一張」升起來，
   換格的時候才寫一次。 */
.hz-ph{position:absolute;inset:0;overflow:hidden;opacity:0}
/* 開場：全黑 → 線畫開 → 第一張照片才清出來。
   CSS 動畫的優先權高於行內樣式，所以就算 JS 已經把 opacity 寫成 1，
   這一段還是會照放；跑完就交還給 JS。fill 用 backwards（不要用 both）。 */
.hz-ph:first-of-type{opacity:1;animation:hzIn 2.1s ease 1.15s backwards}
@keyframes hzIn{from{opacity:0}}
.hz-ph img{position:absolute;left:0;top:0;display:block;max-width:none;
  transform-origin:0 0;will-change:transform}
/* 字要待的那一側壓暗，跟膠卷同一套做法。靜態漸層，不參與動畫。 */
/* 這一層是全螢幕的靜態漸層，壓在會換的照片上面。translateZ(0) 把它推成
   自己的圖層，底下的照片換的時候它就不必跟著重畫。 */
.hz-fix::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  transform:translateZ(0);
  background:linear-gradient(90deg,rgba(0,0,0,.88) 0%,rgba(0,0,0,.6) 28%,rgba(0,0,0,.16) 56%,
      rgba(0,0,0,0) 74%),
    linear-gradient(to bottom,rgba(0,0,0,.5) 0%,rgba(0,0,0,0) 22%,
      rgba(0,0,0,0) 62%,rgba(0,0,0,.56) 100%)}

/* ── 那條線 ── */
.hz-rule{position:absolute;left:0;right:0;top:var(--hy);height:1px;z-index:5;
  background:linear-gradient(90deg,rgba(232,220,196,0) 0%,rgba(232,220,196,.5) 12%,
    rgba(232,220,196,.5) 88%,rgba(232,220,196,0) 100%);
  transform:scaleX(0);transform-origin:50% 50%;
  animation:hzDraw 1.7s var(--vslow) .5s backwards;transform:scaleX(1)}
@keyframes hzDraw{from{transform:scaleX(0)}}
/* 線上的那一顆點：停在版心，標出「現在讀到哪一段」 */
.hz-dot{position:absolute;left:var(--gut);top:var(--hy);width:5px;height:5px;z-index:6;
  margin:-2px 0 0 -2px;background:var(--bronze-hi);
  transform:scale(0);animation:hzDot .9s var(--vslow) 1.9s backwards;transform:scale(1)}
@keyframes hzDot{from{transform:scale(0)}}

/* ── 字：名字壓在線上面，說明落在線下面 ── */
.hz-cap{position:absolute;left:var(--gut);right:var(--gut);top:0;bottom:0;z-index:7;
  pointer-events:none;opacity:0}
.hz-cap>.up{position:absolute;left:0;bottom:calc(100% - var(--hy));
  padding-bottom:clamp(14px,2.2vh,26px);max-width:min(46vw,30em)}
.hz-cap>.dn{position:absolute;left:0;top:var(--hy);
  padding-top:clamp(16px,2.6vh,30px);max-width:min(38vw,26em)}
.hz-cap .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.36em;
  color:var(--bronze);text-shadow:0 0 18px rgba(0,0,0,.9)}
/* 照片有夜景也有大白天，字一定要自己帶保護。text-shadow 是靜態的，不重繪。 */
.hz-cap h2{margin-top:clamp(12px,1.8vh,20px);font-family:var(--disp);font-weight:500;
  color:var(--paper);font-size:clamp(34px,6vw,86px);line-height:1.14;letter-spacing:.16em;
  text-shadow:0 0 26px rgba(0,0,0,.8),0 2px 8px rgba(0,0,0,.55)}
.hz-cap h2.sm{font-size:clamp(26px,3.6vw,52px);line-height:1.28;letter-spacing:.2em}
/* 照片有夜景也有大白天，說明一定要自己站得住。
   2026-08-16 Ethan：「說明的內容太不明顯了」——那一張是白天的街景，
   `--paper-2`（#9d9a93）壓在亮牆上就糊掉了。三件事一起做：
   字提到接近 --paper、影子加重加大、再給那一塊一層很淡的壓黑（下面的 .dn::before）。 */
.hz-cap p{font-size:13.5px;line-height:2.3;color:#dcd8d1;letter-spacing:.06em;
  text-shadow:0 0 26px rgba(0,0,0,.96),0 0 8px rgba(0,0,0,.9),0 1px 4px rgba(0,0,0,.85)}
/* 壓黑是靜態的漸層，往右往下都化掉，不會看起來像一個方塊。
   放在 ::before 並且把內容墊到 z-index:1，字才不會被自己的底蓋住。 */
.hz-cap>.up,.hz-cap>.dn{isolation:isolate}
.hz-cap>.up>*,.hz-cap>.dn>*{position:relative;z-index:1}
.hz-cap>.up::before,.hz-cap>.dn::before{content:"";position:absolute;z-index:0;
  inset:-20px -46% -26px -40%;pointer-events:none;
  background:radial-gradient(70% 76% at 26% 50%,rgba(0,0,0,.82) 0%,
    rgba(0,0,0,.5) 46%,rgba(0,0,0,0) 100%)}
.hz-cap .no{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.3em;
  color:var(--paper-3);margin-bottom:11px}

/* ── 四大理念：字站在水線上，水裡有它的倒影 ────────────────
   Ethan 2026-08-16：「圖一的字**請換個概念加入**，現在看起來很普通廉價。」
   舊版是同一個詞印兩份、上下各切一半，進場在線上合起來——說穿了就是
   「一行字被一條線畫過去」，太像預設效果。

   現在那條地平線是**水線**：字站在水線上，水裡有一個倒下去的它。
   倒影翻過來、壓到兩成的濃度，再用一道靜態的遮罩讓它往下化掉。
   進場是**字從水線裡升起來**（上半的框把線以下切掉，字從框底推上來），
   升到位之後倒影才跟著出現——**先有實體，才有影子**。

   遮罩是靜態的（只設一次，不參與補間），動的只有 transform 與 opacity。
   `.up` / `.dn` 兩個框都是 overflow:hidden，字在框裡位移，
   所以「從線裡長出來」是裁出來的，不是用 clip-path 每幀重算。 */
/* --fs 是字級，--hu 是字站在線上的高度，--hr 是倒影在線下的深度。
   小標與內文要讓過這兩塊，不然會疊在字上。 */
/* **class 撞車踩第五次。** 這個「字站在水線上」的版式本來叫 `.hz-cap.split`，
   結果吃到第五節那個滿版兩欄元件的 `.split`——
   `width:100vw; margin-left:calc(50% - 50vw)`，還有它 860 那一段的
   `padding:… var(--gut)`。於是這一格在手機上變成 100vw 寬又被往右推 22px，
   **右邊那一欄的字整個被 overflow:hidden 切掉**（畫面上看到的是
   「…集團有」換行之後少了一個「自」）。桌機因為 .dn 有 max-width 蓋著，
   剛好看不出來，所以躲了很久。
   改成 `.hz-split`——**這一頁的 class 一律加 `hz-` 前綴**。
   （前四次：`.full`／`.opened`／`.line`／`.mb`，見第八節第 2 條。） */
.hz-cap.hz-split{--fs:clamp(38px,6.6vw,96px);
  --hu:calc(var(--fs) * 1.12);--hr:calc(var(--fs) * .9)}
.hz-cap.hz-split>.up{bottom:calc(100% - var(--hy) + var(--hu) + clamp(12px,2vh,22px));
  padding-bottom:0}
.hz-cap.hz-split>.dn{top:calc(var(--hy) + var(--hr) + clamp(16px,2.6vh,30px));padding-top:0}
/* 整塊往上吊，讓 .t 的底邊剛好落在水線上 */
.hz-cap .mid{position:absolute;left:0;top:var(--hy);translate:0 -100%;margin:0;
  width:max-content;max-width:100%;
  font-family:var(--disp);font-weight:700;color:var(--paper);
  font-size:var(--fs);line-height:1;letter-spacing:.2em;
  text-shadow:0 0 30px rgba(0,0,0,.82),0 2px 10px rgba(0,0,0,.6)}
/* 水線上：框的底邊就是水線，字從框底升上來。
   **內層的兩個框刻意不叫 .up／.dn**——.hz-cap 已經有同名的直接子元素
   （小標與內文），共用會互相蓋到。 */
.hz-cap .mid .t{display:block;position:relative;overflow:hidden;
  height:1.08em;padding-right:.3em}
.hz-cap .mid .t i{display:block;font-style:normal;line-height:1.08;
  transform:translate3d(0,104%,0);
  transition:transform 1.7s var(--vslow)}
.hz-cap.on .mid .t i{transform:none}
/* 水裡：翻過來、淡、往下化掉。遮罩是靜態的，不參與補間。 */
.hz-cap .mid .r{display:block;position:absolute;left:0;top:100%;width:100%;
  overflow:hidden;height:.9em;padding-right:.3em;opacity:.4;
  -webkit-mask-image:linear-gradient(to bottom,#000 0%,rgba(0,0,0,.62) 46%,transparent 98%);
  mask-image:linear-gradient(to bottom,#000 0%,rgba(0,0,0,.62) 46%,transparent 98%)}
.hz-cap .mid .r i{display:block;font-style:normal;line-height:1.08;
  /* 原點一定要在自己的中心。放在 50% 0 的話 scaleY(-1) 會把整塊翻到框的上面，
     被 overflow 切光——倒影就整個看不見（踩過一次）。 */
  transform:scaleY(-1) translate3d(0,104%,0);transform-origin:50% 50%;
  transition:transform 1.9s var(--vslow) .36s}
.hz-cap.on .mid .r i{transform:scaleY(-1) translate3d(0,0,0)}
/* 開場與收尾那兩段（兩行的標題）不騎線，維持在線的上面，進場單純浮上來 */
.hz-cap h2.sm{opacity:0;transform:translate3d(0,20px,0);
  transition:opacity 1.1s ease .15s,transform 1.4s var(--vslow) .15s}
.hz-cap.on h2.sm{opacity:1;transform:none}

/* 捲到最後放行的提示 */
.hz-more{position:absolute;left:50%;bottom:clamp(20px,3.4vh,36px);z-index:8;
  translate:-50% 0;font-family:var(--mono);font-size:8.5px;letter-spacing:.3em;
  color:var(--paper-3);opacity:0;transition:opacity .8s ease}
.hz.tail .hz-more{opacity:.85}

@media (max-width:860px){
  .hz-cap>.up{max-width:none;right:0}
  .hz-cap>.dn{max-width:none;right:0}
  .hz{--hy:46svh}
  .hz-cap h2{font-size:clamp(30px,10vw,52px);letter-spacing:.1em}
  .hz-cap h2.sm{font-size:clamp(22px,6.6vw,32px);letter-spacing:.12em}
  .hz-cap.hz-split{--fs:clamp(34px,11vw,56px);--hu:calc(var(--fs) * 1.12);--hr:calc(var(--fs) * .9)}
  .hz-cap .mid{font-size:clamp(34px,11vw,56px);letter-spacing:.14em}
  .hz-cap p{font-size:12.5px;line-height:2.15}
  .hz-fix::after{background:linear-gradient(to bottom,rgba(0,0,0,.55) 0%,rgba(0,0,0,.1) 26%,
    rgba(0,0,0,.12) 54%,rgba(0,0,0,.72) 100%)}
}

/* 減動：不接管捲動，攤平成一段一段的照片＋字，那條線每一段各畫一次 */
@media (prefers-reduced-motion:reduce){
  .hz{height:auto!important}
  .hz-fix{position:relative;height:auto;overflow:visible}
  .hz-ph{position:relative;inset:auto;width:100%;opacity:1;aspect-ratio:16/9}
  .hz-ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
    transform:none!important}
  .hz-rule,.hz-dot,.hz-more{display:none}
  /* left/right 是給 absolute 用的；改成 relative 之後 left 會把整塊往右推
     而寬度不變，撐出一條橫向捲軸（量到 72px）。要一起解掉。 */
  .hz-cap{position:relative;left:auto;right:auto;opacity:1!important;transform:none!important;
    padding:clamp(24px,5vh,48px) var(--gut) clamp(40px,8vh,80px)}
  .hz-cap>.up,.hz-cap>.dn{position:relative;left:0;top:0;bottom:auto;max-width:none;padding:0}
  /* 攤平之後字沒有壓在照片上，壓黑不需要；而且它的負百分比內縮會撐出橫向捲軸 */
  .hz-cap>.up::before,.hz-cap>.dn::before{display:none}
  .hz-cap>.dn{margin-top:18px}
  /* 攤平之後沒有水線可以站，倒影收掉、字回到一般的標題。
     .mid 本來是 absolute＋translate:0 -100%，不解掉會撐出橫向捲軸。 */
  .hz-cap .mid{position:relative;top:auto;translate:0 0;width:auto;
    margin:clamp(10px,2vh,18px) 0 0;font-size:clamp(30px,5.4vw,58px)}
  .hz-cap .mid .t{height:auto;overflow:visible;padding-right:0}
  .hz-cap .mid .t i{transform:none!important}
  .hz-cap .mid .r{display:none}
}

/* ════════════════════════════════════════════════════════════════════
   十七、長卷　HANDSCROLL　（team.html 專用）
   ──────────────────────────────────────────────────────────────────
   Ethan：「團隊的部分打掉重做。一定要有**非常新穎的動畫呈現**。
   由你直接創意設計。至少讓別人覺得這個公司很會做網站。非常非常厲害。」

   概念：**往下捲，畫面往旁邊走。** 用的是中國手卷的看法——
   卷軸是橫著展開的，一段一段過去，人名直排像題跋，事業與作品是卷上的格。
   講的事情是團隊跨足不動產的上下游，四個人各守一段，
   橫向的長卷正好就是那條路本身。

   為什麼不再用一條線：那是 about 的招式，同一個站不能兩頁用同一手。
   這一頁的連續元素是**卷的天頭與地腳**（上下兩道細線），
   從頭到尾框著整條卷，走到哪裡都在。

   捲動只換一個數字：track 的 translateX。跟 about 一樣掛慣性，
   滾輪一格是滑行不是跳格。每一段的內容再依離畫面中心的遠近做微幅視差，
   全部只有 X 位移。**沒有 HUD、沒有計數器、沒有會呼吸的光、沒有外框**——
   那幾樣在這一頁的前七版被打回來過。

   手機沒有橫向的餘裕，整條卷攤平成直的一段一段（減動偏好同理）。
   ════════════════════════════════════════════════════════════════════ */
.sr{position:relative;
  --perf-t:clamp(104px,13.8vh,134px);   /* 上排齒孔離畫面頂端（要閃過頁首那條線） */
  --perf-b:clamp(34px,4.6vh,48px);      /* 下排齒孔離畫面底端 */
  --perf-h:21px}
.sr-fix{position:sticky;top:0;height:100svh;overflow:hidden}

/* ── 天頭與地腳：這一卷是一條膠捲 ──
   Ethan：「這個手卷概念超棒，但我感覺可以上下用得像是相機膠捲的概念?」

   齒孔畫在 **.sr-track 上**，不是畫在 .sr-fix 上——所以它跟著卷一起走，
   卷走多少齒孔就走多少，**完全不必另外算位置、每一格零成本**。
   （畫在 .sr-fix 上齒孔會定住不動，那就變成一張靜止的相框，不是在放的片子。）

   **孔要用挖的，不是用畫的。** 第一版把齒孔畫成亮的方塊，在純黑上就變成
   一整排亮虛線，像加了一圈虛線外框，很難看（Ethan：「上下的相機膠捲做得不好看欸」）。
   真正的膠捲是**片基比周圍亮一點，孔是黑的**——所以現在整條帶子先鋪一層
   極淡的片基（白 3.4%），再把孔用頁面的黑挖回去。安靜很多，而且一眼就知道是膠捲。
   節距 34px、孔 20×12、圓角 2.6——照 35mm KS 規格的比例縮下來的。

   一張 SVG 平鋪，瀏覽器只解一次；track 的位移是整數，所以不會有重取樣的閃爍。 */
.sr-track::before,.sr-track::after{content:"";position:absolute;left:0;right:0;z-index:1;
  height:var(--perf-h);
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34' height='21'%3E%3Crect width='34' height='21' fill='%23E8DCC4' fill-opacity='0.034'/%3E%3Crect x='7' y='4.5' width='20' height='12' rx='2.6' fill='%23000000'/%3E%3C/svg%3E") repeat-x 0 50%;
  background-size:34px 21px;
  animation:srFilm 1.7s var(--vslow) .3s backwards}
.sr-track::before{top:var(--perf-t)}
.sr-track::after{bottom:var(--perf-b)}
@keyframes srFilm{from{opacity:0}to{opacity:1}}

.sr-track{position:absolute;left:0;top:0;height:100%;display:flex;align-items:stretch;
  will-change:transform;transform:translate3d(0,0,0)}
/* 段寬由段自己的內容決定（min-width 只是最小的餘裕）。
   **不要改回固定寬度**——第八版就是寫死 width，四張圖的那兩段撐不下，
   圖會溢出去壓到下一段的名字上。加一張圖、換一段字都不必再算寬度。 */
.sr-p{position:relative;flex:0 0 auto;height:100%;
  padding:clamp(142px,18vh,168px) clamp(30px,4vw,72px) clamp(68px,9.4vh,94px);
  display:flex;align-items:center;gap:clamp(26px,3.4vw,60px)}
/* 格與格之間的分割線——膠捲的 frame line。只有一條頭髮那麼細，
   而且只走在兩排齒孔之間（真的膠捲上齒孔那一條是不切的）。 */
.sr-p::before{content:"";position:absolute;left:0;z-index:2;width:1px;
  top:calc(var(--perf-t) + var(--perf-h));bottom:calc(var(--perf-b) + var(--perf-h));
  background:rgba(232,220,196,.085)}
.sr-p:last-child::after{content:"";position:absolute;right:0;z-index:2;width:1px;
  top:calc(var(--perf-t) + var(--perf-h));bottom:calc(var(--perf-b) + var(--perf-h));
  background:rgba(232,220,196,.085)}

/* ── 題首與卷尾 ── */
.sr-p.head{min-width:clamp(420px,54vw,700px)}
.sr-p.tail{min-width:clamp(380px,46vw,580px)}
/* 手機才用得到的那一層外框：桌機是 display:contents，
   等於整個不存在，四個子元素照樣是 .sr-p 的 flex 子項，版面一個像素都不變。
   手機（見 900 那一段）才把它變成一個佔滿一個螢幕的區塊。 */
.sr-col{display:contents}

/* ── 排版：不要一整片直排的白色大字 ──
   2026-08-16 Ethan：「這邊的直列大字我不喜歡，請更換新的排版設計方式。
   並且**不要都只是白色大字，沒有質感**。」

   換成一落編排：小標（青銅色等寬）→ 名字（橫排、明體 500、暖米白、字距拉開）
   → 一條很短的青銅細線 → 職稱。後面再壓一個**很淡的大字**當底紋。
   質感是靠字距、灰階與層次撐的，不是靠大和白。 */
.sr-hd{display:block;flex:0 0 auto;position:relative;z-index:1}
.sr-hd .k{display:block;max-width:14em;font-family:var(--mono);font-size:10px;
  letter-spacing:.34em;color:var(--bronze)}
.sr-hd .ttl{margin:clamp(14px,2.2vh,22px) 0 0;
  font-family:var(--disp);font-weight:500;color:rgba(233,228,217,.88);
  font-size:clamp(24px,2.9vw,40px);letter-spacing:.3em;line-height:1.5;text-indent:.3em;
  white-space:nowrap}
.sr-hd .ttl i{display:inline-block;font-style:normal;
  opacity:0;transform:translate3d(0,14px,0);
  transition:opacity 1s ease,transform 1.3s var(--vslow)}
.sr-p.on .sr-hd .ttl i{opacity:1;transform:none}
.sr-p.on .sr-hd .ttl i:nth-child(2){transition-delay:.1s}
.sr-p.on .sr-hd .ttl i:nth-child(3){transition-delay:.2s}
.sr-p.on .sr-hd .ttl i:nth-child(4){transition-delay:.3s}
.sr-p.on .sr-hd .ttl i:nth-child(5){transition-delay:.4s}
.sr-p.on .sr-hd .ttl i:nth-child(6){transition-delay:.5s}
.sr-p.on .sr-hd .ttl i:nth-child(7){transition-delay:.6s}
.sr-hd .rule{display:block;width:clamp(30px,3.4vw,52px);height:1px;
  margin:clamp(15px,2.4vh,24px) 0 0;background:rgba(185,151,95,.6);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform 1.2s var(--vslow) .5s}
.sr-p.on .sr-hd .rule{transform:scaleX(1)}

/* 底紋的大字 2026-08-17 從 team.html 整個拿掉了（Ethan：「把大大的底字刪掉」）。
   樣式留著沒刪，要加回來直接在段裡補 <i class="sr-gh">X</i>。
   ── 以下是原本的說明 ──
   底紋：一個很淡的大字壓在後面。它是質地不是內容——
   要淡到**看得出有字、但不會去讀它**。純白大字改成這個之後整頁才不吵。 */
/* **一個字就好。** 兩個字會寬到溢出這一段、壓進隔壁；
   而且底紋要的是一個形，不是一個詞。 */
.sr-gh{position:absolute;left:clamp(10px,1.4vw,26px);top:50%;translate:0 -50%;z-index:0;
  font-family:var(--disp);font-weight:700;font-style:normal;
  font-size:clamp(210px,30vw,470px);line-height:.86;color:#fff;opacity:0;
  pointer-events:none;user-select:none;
  transition:opacity 2.2s ease .3s}
.sr-p.on .sr-gh{opacity:.038}
.sr-p .body{max-width:24em;font-size:15px;line-height:2.2;color:var(--paper-2);
  letter-spacing:.06em;position:relative;z-index:1}
.sr-p .body p+p{margin-top:1.1em}

/* ── 一個人 ── */
.sr-p.who{min-width:clamp(560px,62vw,860px)}
/* 遠近兩層：名字是遠景（走得慢），圖是近景（走得快），字是不動的基準面。
   位移由 py.js 每格寫一次，只有 X。到畫面正中央時兩層都歸零，
   所以真正在讀的那一刻看到的是排版原本的位置，飄移只發生在進出場。 */
.sr-nm,.sr-im{will-change:transform}
/* 一個人：名字 → 細線 → 職稱，疊成一落。
   **編號（01／02／03）2026-08-18 拿掉了**（Ethan：「團隊介紹的 01 02 03
   這個標籤都拿掉」）。`.sr-nm .no` 的樣式留著沒刪，要加回來直接改 HTML；
   加回去的時候記得把下面 h3 的 margin-top 一起改回 clamp(13px,2vh,20px)。 */
.sr-nm{display:block;flex:0 0 auto;position:relative;z-index:1}
.sr-nm .no{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.4em;
  color:var(--bronze);
  opacity:0;transform:translate3d(0,8px,0);
  transition:opacity .9s ease,transform 1.1s var(--vslow)}
.sr-p.on .sr-nm .no{opacity:1;transform:none}
.sr-nm h3{margin:0;
  font-family:var(--disp);font-weight:500;color:rgba(233,228,217,.9);
  font-size:clamp(25px,2.95vw,40px);letter-spacing:.28em;line-height:1.2;
  white-space:nowrap;text-indent:.28em}
.sr-nm h3 i{display:inline-block;font-style:normal;
  opacity:0;transform:translate3d(0,14px,0);
  transition:opacity 1s ease .1s,transform 1.3s var(--vslow) .1s}
.sr-p.on .sr-nm h3 i{opacity:1;transform:none}
.sr-p.on .sr-nm h3 i:nth-child(2){transition-delay:.21s}
.sr-p.on .sr-nm h3 i:nth-child(3){transition-delay:.32s}
.sr-nm .rule{display:block;width:clamp(28px,3vw,46px);height:1px;
  margin:clamp(14px,2.2vh,22px) 0;background:rgba(185,151,95,.6);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform 1.2s var(--vslow) .46s}
.sr-p.on .sr-nm .rule{transform:scaleX(1)}
.sr-nm .side{display:block;font-family:var(--sans);font-weight:300;
  font-size:13px;letter-spacing:.28em;color:var(--paper-2);
  opacity:0;transform:translate3d(0,6px,0);
  transition:opacity .9s ease .56s,transform 1.1s var(--vslow) .56s}
.sr-p.on .sr-nm .side{opacity:1;transform:none}
.sr-tx{flex:0 0 auto;max-width:22em;position:relative;z-index:1}
.sr-tx .sk{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.3em;
  color:var(--bronze);margin-bottom:clamp(14px,2.2vh,22px)}
.sr-tx p{font-size:13.5px;line-height:2.3;color:var(--paper-2);letter-spacing:.06em}
.sr-tx .fine{margin-top:1.2em;font-size:12.5px;line-height:2;color:var(--paper-3)}
/* 陳金水那一段的 .sr-tx 只剩這一行免責說明，不必再留一整欄的寬度 */
.sr-tx.only-fine{max-width:15em}
.sr-tx.only-fine .fine{margin-top:0}
.sr-tx .fine a{color:var(--bronze)}

/* ── 底氣：一個人後面接三段 ──────────────────────────────────────
   2026-08-17 Ethan 把投資簡報裡三位的頁面丟過來，要「完整化加入」。
   簡報上是米色的圓角卡片；**這裡不能照抄**——這一頁沒有卡片、沒有圓角、
   沒有色塊，照抄就是把一頁簡報貼到網站上。

   換成同一套版式語彙：青銅色編號 ＋ 小標 → 明體的一句 → 一行說明
   → 一條細線 → 幾個帶青銅點的小項。進場跟名字、圖同一組秒數（錯開 .14s）。

   **三段是直的疊起來，不是橫的並排。** 橫排要 660px，一個人的段會撐到
   2600px，名字跟圖看不到同一個畫面；直排只要 270px，而且剛好用掉版面
   上下本來就空著的那一塊。 */
.sr-cr{flex:0 0 auto;width:clamp(248px,20.5vw,318px);
  position:relative;z-index:1}
.sr-cr .cr{opacity:0;transform:translate3d(0,14px,0);
  transition:opacity 1s ease .12s,transform 1.25s var(--vslow) .12s}
.sr-p.on .sr-cr .cr{opacity:1;transform:none}
.sr-p.on .sr-cr .cr:nth-child(2){transition-delay:.26s}
.sr-p.on .sr-cr .cr:nth-child(3){transition-delay:.4s}
.sr-cr .cr+.cr{margin-top:clamp(16px,2.9vh,30px);
  padding-top:clamp(15px,2.7vh,28px);border-top:1px solid rgba(232,220,196,.09)}
/* 小標（家學・開發、事務所資歷…）2026-08-17 全部拿掉了。
   **編號（01／02／03）2026-08-18 也拿掉了**，一格現在只剩標題 ＋ 一段文字。
   `.n` 與 `.lb` 的樣式都留著沒刪，要加回來直接改 HTML；
   加回去的時候記得把下面 h4 的 margin-top 一起改回 clamp(10px,1.6vh,16px)。 */
.sr-cr .n{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.26em;
  color:var(--bronze)}
.sr-cr .lb{margin-left:10px;font-family:var(--sans);font-weight:300;
  font-size:11.5px;letter-spacing:.18em;color:var(--paper-3)}
.sr-cr h4{margin:0;
  font-family:var(--disp);font-weight:500;color:rgba(233,228,217,.92);
  font-size:clamp(18px,1.75vw,24px);letter-spacing:.2em;line-height:1.35;text-indent:.2em}
.sr-cr p{margin-top:clamp(6px,1vh,10px);font-size:12px;line-height:1.95;
  color:var(--paper-2);letter-spacing:.05em}
/* 2026-08-17 Ethan：「圖二的條列，改為一段文字呈現。其他人比照辦理。」
   小項本來是橫著排的清單，現在併成一句話。`ul`／`li` 的樣式留著沒刪，
   之後要換回清單直接改 HTML 就好。 */
.sr-cr .ls{margin-top:clamp(10px,1.7vh,16px);
  font-size:13px;line-height:2;color:var(--paper-2);letter-spacing:.05em}

/* 小項橫著排、自己換行——直排的版面裡，一項一行太高 */
.sr-cr ul{display:flex;flex-wrap:wrap;gap:4px clamp(13px,1.3vw,20px);
  margin:clamp(11px,1.8vh,17px) 0 0;padding:0;list-style:none}
.sr-cr li{position:relative;padding-left:14px;
  font-size:13px;line-height:1.9;color:var(--paper-2);letter-spacing:.06em}
.sr-cr li::before{content:"";position:absolute;left:0;top:.7em;
  width:3.5px;height:3.5px;border-radius:50%;background:rgba(185,151,95,.75)}
/* 矮螢幕：段是 align-items:center，超出去是上下各裁一半，
   第一段的小標與最後一段的小項會直接不見。字級放大之後 1024×700 又頂到了
   （532 vs 可用 490），所以這一層一定要留。改字級或行距之後要重量。 */
@media (max-height:770px){
  .sr-cr .cr+.cr{margin-top:13px;padding-top:13px}
  .sr-cr h4{margin-top:0;font-size:clamp(16px,1.6vw,20px)}
  .sr-cr ul{margin-top:8px;gap:3px 14px}
  .sr-cr li{font-size:12px;line-height:1.75}
}
/* 說明句 2026-08-17 拿掉了（Ethan：「圖一的內容都刪掉，太冗長了」）——
   那幾句本來就跟下面的小項重複。`.sr-cr p` 的樣式留著，之後要加回來直接用。
   拿掉之後這一塊從 455–645px 降到 327–475px，六個尺寸都剩很多餘裕，
   原本為了塞下說明句而寫的三層 max-height 收法也一併刪了。 */

/* ── 卷上的格：人、事業、作品 ──
   一個人的第一格是他本人，後面是他的事業與作品——就是這一段的片子。
   格子的大小全站統一（膠捲的片門是固定的），來源的長寬比不同由 cover 收。
   3:4 是折衷：林子愷與陳金水的圖本來就是直的；簡連成與張志成是網站截圖，
   `object-position:top` 之後剛好留下最認得出來的那一塊（選單＋主視覺）。 */
.sr-im{display:flex;align-items:center;gap:clamp(12px,1.5vw,26px);flex:0 0 auto;
  position:relative;z-index:1}
.sr-im>*{position:relative;display:block;flex:0 0 auto;
  aspect-ratio:3/4;height:min(clamp(258px,25.5vw,432px),62vh);width:auto;overflow:hidden;
  background:var(--ink-3);
  opacity:0;transform:translate3d(0,16px,0);
  transition:opacity 1.1s ease,transform 1.3s var(--vslow)}
.sr-p.on .sr-im>*{opacity:1;transform:none}
.sr-p.on .sr-im>*:nth-child(2){transition-delay:.1s}
.sr-p.on .sr-im>*:nth-child(3){transition-delay:.2s}
.sr-p.on .sr-im>*:nth-child(4){transition-delay:.3s}
.sr-im img{width:100%;height:100%;object-fit:cover;object-position:top center;
  filter:grayscale(.6) brightness(.6) saturate(.6);transform:scale(1.02);
  transition:filter .9s ease,transform 1.6s var(--slow)}
.sr-im a:hover img{filter:none;transform:scale(1.06)}
.sr-im .cap{position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:clamp(30px,4.4vh,50px) 12px 11px;
  background:linear-gradient(to top,rgba(0,0,0,.88),rgba(0,0,0,0));
  font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;color:var(--paper);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 箭頭前面用不斷行空白：圖說在手機會換行，用一般的全形空白的話
   箭頭會自己掉到第三行變成孤兒（2026-08-18 在台聯電訊那一格看到）。 */
.sr-im a .cap::after{content:"\00A0\00A0↗";color:var(--bronze)}
/* ── 沒有截圖的那一格：用字排一塊牌 ──────────────────────────
   2026-08-18 欣德芮（sterileright.com.tw）換進張志成那一排，
   但這個容器連不到外網、抓不到那個站的畫面，所以那一格不放圖，
   改成一塊排字的牌：中文名大、英文名小、網址墊底，外框跟其他格一模一樣。
   **之後拿到截圖就把 .plate 整個換成 <img>**，外框與圖說都不用動。
   （比隨便塞一張不相干的圖好——那才會讓人覺得是湊數的。） */
.sr-im .plate{background:linear-gradient(165deg,#0f0f13 0%,#08080b 58%,#0b0b0e 100%);
  box-shadow:inset 0 0 0 1px rgba(232,220,196,.08)}
.sr-im .plate .pl{position:absolute;inset:0;z-index:1;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(9px,1.4vh,15px);padding:0 12px;text-align:center;
  transition:transform 1.6s var(--slow)}
.sr-im .plate:hover .pl{transform:scale(1.04)}
.sr-im .plate .pl b{display:block;font-family:var(--disp);font-weight:500;
  font-size:clamp(21px,2.1vw,30px);letter-spacing:.28em;text-indent:.28em;
  color:rgba(238,232,220,.92);line-height:1.2}
.sr-im .plate .pl em{display:block;font-style:normal;font-family:var(--mono);
  font-size:10.5px;letter-spacing:.28em;text-indent:.28em;color:var(--bronze)}
.sr-im .plate .pl u{display:block;text-decoration:none;margin-top:2px;
  font-family:var(--mono);font-size:10px;letter-spacing:.12em;color:var(--paper-2)}
/* 這裡本來有一條青銅細線當裝飾，2026-08-18 拿掉了——
   內容是置中的，那條線不管放哪個高度都會從中文名上面劃過去。
   牌本身已經夠乾淨，不需要再加東西。 */

/* 人的那一格：**不要做成黑白**（2026-08-16 Ethan 指定），顏色留著，
   只把亮度壓下來一點。棚拍白底在黑底上會變成一塊漏光，
   靠橢圓暗角把背景收回黑裡，人臉那一塊留著。構圖偏上，頭不會被切到。不做運鏡。 */
.sr-im .face img{object-position:50% 18%;
  filter:brightness(.8) contrast(1.02) saturate(.92)}
.sr-im .face::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(ellipse 74% 60% at 50% 30%,rgba(0,0,0,0) 40%,rgba(0,0,0,.9) 100%),
    linear-gradient(to top,rgba(0,0,0,.72) 0%,rgba(0,0,0,0) 34%)}

/* 走到最後放行的提示 */
.sr-more{position:absolute;left:50%;bottom:clamp(20px,3.2vh,34px);z-index:8;translate:-50% 0;
  font-family:var(--mono);font-size:8.5px;letter-spacing:.3em;color:var(--paper-3);
  opacity:0;transition:opacity .8s ease}
.sr.tail-on .sr-more{opacity:.85}

/* 「左右滑動看團隊」——只有手機看得到，走過一點點就收掉。
   一條細線加一點光橫著走，跟首頁那個上下走的指引是同一組語彙
   （只有 transform 在動，合成層上跑，零重繪）。
   **桌機不顯示**：滑鼠使用者不會去撥畫面，而且那裡本來就沒有東西。 */
/* 直立膠捲的引導：**掛在第一格裡面**，跟著那一格捲走。
   （舊版是 absolute 吊在整段的下緣——橫向卷的時候那裡是畫面底部，
   直立之後那裡變成整頁的最後面，等於沒有人看得到。） */
.sr-swipe{display:none;margin-top:clamp(30px,5vh,52px);
  text-align:left;pointer-events:none;
  opacity:0;transition:opacity .8s ease}
/* **2026-08-18 傍晚從橫的改成直的。** 字改成「上下滑動」之後，
   底下那條光還在左右跑，講的跟看到的不一樣——指引最忌諱這個。
   現在是字在上、一條直線在下，光往下走。 */
.sr-swipe i{position:relative;display:block;width:1px;height:26px;margin:10px 0 0 8px;
  overflow:hidden;background:rgba(232,220,196,.2)}
.sr-swipe i::after{content:"";position:absolute;left:0;top:0;width:1px;height:9px;
  background:var(--bronze-hi);will-change:transform;
  animation:srSwipe 2.4s cubic-bezier(.45,0,.35,1) infinite}
@keyframes srSwipe{0%{transform:translate3d(0,-9px,0)}
  58%,100%{transform:translate3d(0,26px,0)}}
.sr-swipe b{display:inline-block;font-family:var(--mono);font-weight:400;
  font-size:10.5px;letter-spacing:.26em;color:var(--paper-2);white-space:nowrap;
  text-shadow:0 0 14px rgba(0,0,0,.9)}
@media (max-width:900px){
  .sr-swipe{display:block;opacity:1;transition:opacity 1.1s ease 1.1s}
}
@media (prefers-reduced-motion:reduce){
  .sr-swipe{display:none}
}

/* 小筆電：四張圖的那兩段會比視窗寬一點，把說明的欄寬收窄讓一段剛好進得來。
   一段要能整段看完，名字與圖不能分兩次看到。 */
/* 視窗越窄，說明欄跟著收，把寬度讓給格子——
   格子是這一頁的主角（Ethan：「裡面的網站，感覺也可以再放大一點」），
   要收先收字，不要先收圖。 */
@media (max-width:1690px){
  .sr-tx{max-width:18em}
  .sr-p .body{max-width:20em}
  .sr-im>*{height:min(clamp(258px,24vw,432px),62vh)}
}
@media (min-width:901px) and (max-width:1200px){
  .sr-tx{max-width:17em}
  .sr-cr{width:clamp(228px,21vw,268px)}
  .sr-p .body{max-width:18em}
  .sr-im>*{height:min(clamp(212px,23vw,432px),58vh)}
  /* 格子跟著窄，說明要跟著收字距，不然會被切成「…」 */
  .sr-im .cap{letter-spacing:.02em;font-size:10px;padding-left:8px;padding-right:8px}
}
@media (min-width:901px) and (max-width:1040px){
  .sr-p{padding-left:clamp(22px,2.6vw,72px);padding-right:clamp(22px,2.6vw,72px)}
  .sr-tx{max-width:14em}
  .sr-cr{width:clamp(216px,22vw,246px)}
  .sr-p .body{max-width:15em}
  .sr-im>*{height:min(clamp(184px,22vw,432px),56vh)}
}

/* ── 手機：一樣是膠捲，只是**捲的方向轉九十度** ──────────────
   2026-08-18 傍晚 Ethan 定的：
   「團隊頁在手機顯示時，全面改成上下移動的相機膠捲。這樣比較直觀，
   　也符合手上下滑動。」

   走過的兩版都不對：
   ① 攤平成一般的直排文件——齒孔、frame line、膠捲感全沒了。
   ② 保留橫向長卷、手指左右撥——他用過之後說上下比較順手。

   現在是**直立的膠捲**：齒孔從上下兩排改成**左右兩直排**，
   一格一格由上往下排，格與格之間一條很細的 frame line。
   往下滑就是在看片子，跟手機的操作方向完全一致。
   sticky 與 JS 的位移在手機都不啟動（py.js 的 innerWidth <= 900 分支）。

   一個人 ＝ **兩格**：先字、再圖。跟桌機一段之內的兩塊對得起來。
   每一格至少 66svh，內容垂直置中——一次看一格，不會兩格擠在同一屏。 */
@media (max-width:900px){
  .sr{height:auto!important;
    --perf-x:8px;      /* 齒孔那一條離畫面左右邊 */
    --perf-w:21px}     /* 齒孔那一條的寬（＝桌機的 --perf-h 轉九十度） */
  .sr-fix{position:relative;height:auto;overflow:hidden}
  .sr-track{position:relative;display:block;width:auto;height:auto;
    transform:none!important;will-change:auto}
  /* 齒孔：橫的兩排 → 直的兩排。SVG 也要跟著轉九十度（21×34、孔 12×20）。 */
  .sr-track::before,.sr-track::after{
    top:0;bottom:0;left:auto;right:auto;height:auto;width:var(--perf-w);
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='21' height='34'%3E%3Crect width='21' height='34' fill='%23E8DCC4' fill-opacity='0.034'/%3E%3Crect x='4.5' y='7' width='12' height='20' rx='2.6' fill='%23000000'/%3E%3C/svg%3E");
    background-repeat:repeat-y;background-position:50% 0;background-size:21px 34px}
  .sr-track::before{left:var(--perf-x)}
  .sr-track::after{right:var(--perf-x)}
  /* 直立之後每一段不再是「一欄」，而是一疊格子 */
  .sr-p{width:auto!important;min-width:0!important;height:auto;display:block;
    padding:0;gap:0}
  /* 桌機那條直的 frame line 收掉，改由每一格自己的上邊界畫 */
  .sr-p::before,.sr-p:last-child::after{display:none}

  /* ── 一格 ──
     頭尾各自一格；一個人拆成「字」與「圖」兩格。
     左右內距要讓開齒孔那兩條，不然字會壓在孔上面。 */
  /* **align-items 一定要一起改。** 基底的 .sr-p 是 align-items:center，
     這裡只改 flex-direction 的話，每一塊會變成「置中的收縮寬度」——
     引導那一行就會自己飄到畫面正中間，跟左邊對齊的名字對不起來
     （量到 left:155 vs 76，2026-08-18 踩到）。 */
  .sr-p.head,.sr-p.tail,.sr-col,.sr-p.who>.sr-im{
    display:flex;flex-direction:column;justify-content:center;align-items:stretch;
    width:auto;min-height:66svh;
    padding:clamp(46px,7vh,74px)
            calc(var(--perf-x) + var(--perf-w) + clamp(13px,4.2vw,24px));
    border-top:1px solid rgba(232,220,196,.085)}
  .sr-p.head{border-top:0;min-height:78svh;padding-top:clamp(120px,17vh,160px)}
  .sr-p.tail{min-height:60svh}
  /* 圖那一格：2×2，整組垂直置中 */
  .sr-p.who>.sr-im{flex-direction:row;flex-wrap:wrap;align-content:center;
    align-items:flex-start;justify-content:center;gap:9px;margin:0}
  /* **不要寫 calc(50% - 4.5px)。** 兩格加中間的縫剛好等於 100%，
     次像素進位一超過就換行，四張圖會變成直的一長條（量到一格 923px 高）。
     多讓 1.5px 出來，兩張才穩穩地並排。 */
  .sr-im>*{flex:0 0 calc(50% - 6px);width:auto;height:auto;aspect-ratio:3/4}
  .sr-im .cap{white-space:normal;padding:clamp(20px,4.4vw,32px) 9px 9px;line-height:1.5;
    font-size:11.5px;letter-spacing:.02em}

  /* ── 一格之內的字 ── */
  .sr-nm{margin-bottom:clamp(16px,2.6vh,26px)}
  .sr-nm h3{font-size:clamp(26px,7.4vw,34px);letter-spacing:.2em}
  .sr-nm .rule{margin:clamp(12px,2vh,19px) 0 clamp(10px,1.6vh,15px)}
  .sr-hd{max-width:none}
  .sr-hd .ttl{font-size:clamp(24px,6.6vw,32px);letter-spacing:.26em}
  .sr-tx{max-width:none;margin-top:clamp(12px,2vh,19px)}
  .sr-p .body{max-width:none;margin-top:16px}
  .sr-cr{width:auto;max-width:none;margin-top:0}
  .sr-cr .cr+.cr{margin-top:clamp(13px,2.2vh,20px);padding-top:clamp(12px,2vh,19px)}
  .sr-cr h4{font-size:clamp(16px,4.4vw,19px);letter-spacing:.16em}
  .sr-cr .ls{margin-top:8px;font-size:13.5px;line-height:1.98}
  /* CONTINUE 是橫向卷走到底才有意義的東西，直立版不需要 */
  .sr-more{display:none}
}

@media (prefers-reduced-motion:reduce){
  .sr{height:auto!important}
  .sr-fix{position:relative;height:auto;overflow:visible}
  .sr-track{position:relative;display:block;transform:none!important}
  .sr-track::before,.sr-track::after,.sr-p::before,.sr-p:last-child::after{display:none}
  .sr-p{width:auto!important;min-width:0!important;height:auto;display:block;
    padding:clamp(40px,7vh,70px) var(--gut)}
  .sr-nm,.sr-im{transform:none!important;will-change:auto}
  .sr-p{overflow:hidden}
  .sr-gh{font-size:clamp(150px,40vw,260px);left:auto;right:-.06em}
  .sr-nm h3 i,.sr-nm .no,.sr-nm .side,.sr-hd .ttl i,.sr-im>*{opacity:1;transform:none}
  .sr-nm .rule,.sr-hd .rule{transform:scaleX(1)}
  .sr-cr{width:auto;margin-top:clamp(20px,3.4vh,30px)}
  .sr-cr .cr{opacity:1;transform:none;transition:none}
  .sr-gh{opacity:.035}
  .sr-more{display:none}
}

/* ════════════════════════════════════════════════════════════════════
   十八、環形空間　ORBIT　（index-orbit.html 專用．試作）
   ──────────────────────────────────────────────────────────────────
   Ethan 2026-08-16：「首頁我想要改成不是上下滑動，是一整個**空間感的圓形空間**。
   一樣滾輪滑動後就會往下一個建案的方式。我想這樣更符合**月亮環繞**的意象。
   這個你先另外做出來一版讓我看看。」

   所以這是**另存的試作**，index.html 一個字都沒有動。要換過去就把
   index-orbit.html 改名成 index.html（第十一節的膠卷可以整節留著不刪）。

   做法：五個建案排在一個傾斜的圓軌上繞著中間的月亮走。
   每一格算三個數：
     x  ＝ RX · sin(θ)            往左右走
     y  ＝ RY · cos(θ)            前面的低、後面的高＝軌道是斜的
     z  ＝ (cos(θ)+1)/2           0 在最後面、1 在最前面
   由 z 決定縮放、亮度與 z-index，**前後遮擋是 z-index 做的，沒有用 3D**，
   所以每一格只寫 transform 與 opacity，跟膠卷是同一套規矩。

   滾輪一格轉 72 度，掛慣性（cur += (tgt-cur)*0.1），滑行不跳格。
   轉到頭（第五個）再往下就把捲動還給頁面。
   ════════════════════════════════════════════════════════════════════ */
.orb{position:relative}
.ob-stage{position:relative;height:100svh;overflow:hidden;background:var(--ink);
  touch-action:pan-y}

/* 中間**不放任何東西**。第一版在圓心放了一顆月亮，
   Ethan：「中間不需要有那顆太陽」——放大之後它讀起來就是太陽不是月，
   而且把最前面那張卡片壓掉了。現在圓心是空的，空間感全部由卡片自己的遠近撐起來。 */

/* 軌道：一圈細線。寬高由 py.js 依當下的 RX／RY 寫一次。 */
.ob-ring{position:absolute;left:50%;top:50%;z-index:2;
  border:1px solid rgba(232,219,190,.14);border-radius:50%;
  translate:-50% -50%;pointer-events:none;
  opacity:0;animation:obIn 2.6s var(--vslow) .75s forwards}
@keyframes obIn{to{opacity:1}}

.ob-ring-wrap{position:absolute;inset:0;z-index:3}
.ob-it{position:absolute;left:50%;top:50%;
  width:min(34vw,58svh);aspect-ratio:16/9;margin:0;
  translate:-50% -50%;will-change:transform,opacity;
  transform:translate3d(0,0,0);
  opacity:0;animation:obIn 2.2s var(--vslow) forwards}
.ob-it:nth-child(1){animation-delay:.55s}
.ob-it:nth-child(2){animation-delay:.72s}
.ob-it:nth-child(3){animation-delay:.89s}
.ob-it:nth-child(4){animation-delay:1.06s}
.ob-it:nth-child(5){animation-delay:1.23s}
/* 進場跑完就交還給 py.js（它每一格會寫 opacity） */
.orb.live .ob-it{animation:none}
.ob-card{position:relative;display:block;width:100%;height:100%;overflow:hidden;
  padding:0;border:0;background:var(--ink-3);cursor:pointer;text-align:left}
/* 影像永遠比裁切框大 2%，裁切線切在實心的影像上，縮放時邊緣才不會閃
   （跟膠卷同一個理由，見第八節 7-9） */
/* 影像的慢推近：走到最前面才從 1.055 慢慢落定到 1.02（5.2s），
   跟膠卷的 .ro-reel img 是同一條曲線、同一個秒數——這一下是整個站的手感。
   停在 1.02 不是 1.00：影像永遠比裁切框大 2%，裁切線切在實心的影像上，
   縮放時邊緣才不會閃（見第八節 7-9）。 */
.ob-card img{width:100%;height:100%;object-fit:cover;transform:scale(1.055);
  transition:transform 5.2s var(--vslow)}
.ob-it.front .ob-card img{transform:scale(1.02)}
.ob-card::after{content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 2px var(--ink);
  background:linear-gradient(to top,rgba(0,0,0,.4) 0%,rgba(0,0,0,0) 42%)}
.ob-it.back{pointer-events:none}
.ob-it.front .ob-card:hover img{transform:scale(1.05)}

/* 案名：只顯示正前方那一個，在軌道下面 */
/* 案名的位置由 py.js 依「圓心 ＋ RY ＋ 卡片的一半」算出來——
   用 vh 猜的話，矮視窗一定會被最前面那張卡片壓到（640 高時量到疊 33px）。 */
.ob-cap{position:absolute;left:0;right:0;top:0;z-index:6;
  text-align:center;pointer-events:none;height:clamp(74px,10vh,104px)}
/* 案名：一個字一個 <span>，走到正前方才一個一個落定——
   跟膠卷字卡（.ro-cap h2 i）**同一組秒數與延遲**。
   出場要比進場快而且不重疊，不然兩個案名會疊成重影。 */
.ob-nm{position:absolute;left:0;right:0;top:0;display:block;
  opacity:0;transition:opacity .3s ease}
.ob-nm.on{opacity:1;transition:opacity .8s ease}
.ob-nm b{display:block;font-family:var(--disp);font-weight:700;color:var(--paper);
  font-size:clamp(28px,3.6vw,50px);letter-spacing:.22em;line-height:1;
  text-shadow:0 0 34px rgba(0,0,0,.8)}
.ob-nm b span{display:inline-block;
  opacity:0;transform:translate3d(0,20px,0);
  transition:opacity .34s ease,transform .34s ease}
.ob-nm.on b span{opacity:1;transform:none;
  transition:opacity 1.1s ease .34s,transform 1.5s var(--vslow) .34s}
.ob-nm.on b span:nth-child(2){transition-delay:.46s}
.ob-nm.on b span:nth-child(3){transition-delay:.58s}
.ob-nm.on b span:nth-child(4){transition-delay:.7s}
.ob-nm i,.ob-nm u{opacity:0;transform:translate3d(0,10px,0);
  transition:opacity .3s ease,transform .3s ease}
.ob-nm.on i,.ob-nm.on u{opacity:1;transform:none}
.ob-nm.on i{transition:opacity 1s ease .78s,transform 1.2s var(--vslow) .78s}
.ob-nm.on u{transition:opacity 1s ease .92s,transform 1.2s var(--vslow) .92s}
.ob-nm i{display:block;margin-top:clamp(11px,1.6vh,16px);font-style:normal;
  font-family:var(--mono);font-size:9px;letter-spacing:.34em;color:var(--bronze)}
.ob-nm u{display:block;margin-top:clamp(8px,1.2vh,12px);text-decoration:none;
  font-size:11.5px;letter-spacing:.16em;color:var(--paper-3)}

/* 指引：跟膠卷同一支，走一次就停 */
.ob-hint{position:absolute;left:0;right:0;bottom:clamp(18px,2.6vh,30px);z-index:6;
  text-align:center;pointer-events:none}
.ob-hint b{display:inline-block;position:relative;
  font-family:var(--mono);font-size:9px;letter-spacing:.3em;color:var(--paper-3);
  opacity:0;transform:translate3d(0,8px,0);
  animation:obHint 1.6s var(--vslow) 1.5s forwards}
@keyframes obHint{to{opacity:1;transform:none}}
.ob-hint b u{position:absolute;left:50%;bottom:calc(100% + 10px);
  width:52px;height:1px;margin-left:-26px;background:rgba(185,151,95,.55);
  transform:scaleX(0);transform-origin:50% 50%;
  animation:obRule 1.4s var(--vslow) 1.7s forwards}
@keyframes obRule{to{transform:scaleX(1)}}
.orb.moved .ob-hint{opacity:0;transition:opacity .6s ease}
/* 矮視窗擠不下：指引本來就只是提示，收掉 */
@media (max-height:860px){.ob-hint{display:none}}

/* 五顆點：現在在第幾個 */
.ob-dots{position:absolute;left:50%;bottom:clamp(22px,3.4vh,38px);z-index:6;
  display:none;gap:9px;translate:-50% 0}
.ob-dots i{display:block;width:5px;height:5px;border-radius:50%;
  background:rgba(231,231,231,.22);transition:background .6s ease,transform .8s var(--vslow)}
.ob-dots i.on{background:var(--bronze-hi);transform:scale(1.35)}

@media (max-width:900px){
  .ob-it{width:74vw}
  .ob-nm b{font-size:clamp(24px,7vw,34px)}
  .ob-hint{display:none}
  .ob-dots{display:flex}
  .ob-cap{bottom:clamp(46px,8vh,80px)}
}
@media (prefers-reduced-motion:reduce){
  /* 不做動畫的人：圓軌攤平成一疊，該看的都看得到 */
  .ob-stage{height:auto;overflow:visible;padding:clamp(80px,12vh,140px) var(--gut)}
  .ob-ring,.ob-hint,.ob-dots{display:none}
  .ob-ring-wrap{position:relative;inset:auto;display:grid;gap:clamp(26px,5vh,52px)}
  .ob-it{position:relative;left:auto;top:auto;width:100%;translate:0 0;
    transform:none!important;opacity:1!important;animation:none}
  .ob-cap{position:relative;left:auto;right:auto;bottom:auto;height:auto;
    text-align:left;margin-top:20px}
  .ob-nm{position:relative;opacity:1!important;margin-bottom:14px}
  .ob-nm b span,.ob-nm i,.ob-nm u{opacity:1!important;transform:none!important}
}

/* ════════════════════════════════════════════════════════════════════
   十九、層層精磨　FIVE PASSES　（about.html 專用）
   ──────────────────────────────────────────────────────────────────
   Ethan 2026-08-16：「把我們怎麼做的區塊全部刪掉，換成【層層精磨】。
   這邊要給我**最強、最天馬行空**的動畫設計去介紹，因為這裡是我們核心。」

   不必另外找比喻——**璞玥的「璞」本來就是未經雕琢的玉石**，
   公司的名字自己就是比喻：一塊粗料，磨五道，現出裡面那顆玥。
   （這也剛好接上首頁開場改的那一句「璞石成玥　永續傳家」。）

   五道 ＝ 科技、產權、建築、媒體、銷售。往下捲一段，磨掉一層：
   那一層的十二片碎料**錯開時間飛出去**，露出裡面比較細的一層，
   中間那顆珠再亮一點。五層磨完，切面線畫出來，珠子整個亮起。
   往回捲就一層一層長回去。

   **效能**（這一段的規矩跟全站一樣，違反就會卡）：
   - 石頭的自轉與那道打磨的光，轉的是**外面的 HTML 那一層**（各自一個合成層），
     不是 SVG 裡的東西。SVG 裡只要有東西一直在動，就是整張一直重刷。
   - 每一格只寫兩個 transform（石頭的角度、光的角度），值沒變就不寫。
   - 碎料飛出去是**換段時的 class 切換**，交給 CSS transition，不是每格算。
   ════════════════════════════════════════════════════════════════════ */
.gr{position:relative;height:430svh}
.gr-fix{position:sticky;top:0;height:100svh;overflow:hidden;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  align-items:center;gap:clamp(20px,4vw,80px);
  padding:clamp(88px,13vh,140px) var(--gut) clamp(40px,7vh,80px)}

/* ── 天體 ──
   2026-08-17 重做。碎料那一版拿掉了（見 about.html 裡的說明）。
   中間一彎月，外面五道光弧繞著它走；捲一段收掉一道，最後只剩月。 */
.gr-art{position:relative;justify-self:center;
  width:min(100%,46vw,74svh);aspect-ratio:1}

/* 五道光弧。
   一道 ＝ 外框（負責「收進月裡」那一下，很少動）＋ 裡面的環（一直在轉）。
   環是一個 border-radius:50% 的框，**只有某幾邊上色**，所以自然就是一段弧：
   一邊＝90°、兩邊＝180°、三邊＝270°。旋轉交給 CSS 無限動畫，
   合成器自己跑，主執行緒一格都不用寫。 */
.gr-orbits{position:absolute;inset:0;opacity:0;transition:opacity 1.6s ease}
.gr.live .gr-orbits{opacity:1}
.gr-o{position:absolute;left:50%;top:50%;width:var(--sz);aspect-ratio:1;
  translate:calc(-50% + var(--ox,0px)) calc(-50% + var(--oy,0px));
  transition:opacity 1.6s ease,transform 2.1s cubic-bezier(.32,.8,.3,1)}
.gr-o b{position:absolute;inset:0;border-radius:50%;
  border:1px solid transparent;border-top-color:var(--c);
  will-change:transform;
  animation:grSpin var(--sp,120s) linear calc(var(--sp,120s) * var(--ph,0)) infinite}
.gr-o[data-dir="r"] b{animation-direction:reverse}
@keyframes grSpin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
/* 弧長不要每一道都一樣，不然會變成標靶 */
.gr-o[data-k="1"] b{border-right-color:var(--c)}
.gr-o[data-k="3"] b{border-right-color:var(--c);border-bottom-color:var(--c)}
/* 弧上嵌的那一點光：掛在會轉的環裡面，跟著走一圈，不另外算。

   **它同時要把弧的自轉抵銷掉**，字才會永遠是正的：
   同樣的 keyframes、同樣的秒數、同樣的相位，方向相反 → 兩個旋轉互相抵消，
   淨轉角恆為 0。所以不必每一格算角度，主執行緒一個字都不寫。
   （弧本身是反轉的那兩道，這一層就要正轉，見下面的 [data-dir="r"]。） */
.gr-o u{position:absolute;left:50%;top:0;translate:-50% -50%;
  width:var(--bd,18px);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(255,253,247,.95) 0%,
    rgba(255,248,233,.5) 20%,rgba(246,238,218,.13) 44%,rgba(246,238,218,0) 72%);
  will-change:transform;
  animation:grSpin var(--sp,120s) linear calc(var(--sp,120s) * var(--ph,0)) infinite;
  animation-direction:reverse}
.gr-o[data-dir="r"] u{animation-direction:normal}

/* 環節的名字，掛在那一點光的正下方。青銅色的編號在上，名字在下，置中。
   只掛在光點下面（不是往外或往內），左右最多各 ±20px，
   所以不管走到圓周的哪個角度都不會撞到月，也不會侵到右邊那一欄。 */
.gr-o em{position:absolute;left:50%;top:calc(100% + 4px);translate:-50% 0;
  font-style:normal;white-space:nowrap;text-align:center;line-height:1;
  font-family:var(--serif);font-weight:500;
  font-size:clamp(10.5px,.85vw,12.5px);letter-spacing:.26em;text-indent:.26em;
  color:rgba(240,232,214,.9);text-shadow:0 0 14px rgba(0,0,0,.9),0 0 5px rgba(0,0,0,.8);
  opacity:.4;transition:opacity 1.1s ease}
.gr-o em i{display:block;margin-bottom:6px;
  font-family:var(--mono);font-style:normal;font-size:8px;letter-spacing:.26em;
  text-indent:.26em;color:var(--bronze);text-shadow:0 0 10px rgba(0,0,0,.9)}
/* 正在磨的那一道，名字亮起來——跟右邊那一列 01–05 同步。 */
.gr-o.cur em{opacity:1}

/* 磨掉一道 ＝ 那一道收進月裡。由外而內，第五道收完畫面上就只剩月了。
   名字要比弧先收掉（.4s），不然縮放中的字會一路重繪。 */
.gr-o.off{opacity:0;transform:scale(.08)}
.gr-o.off em{opacity:0;transition:opacity .4s ease}

/* 月旁邊那一點空氣。**很淡**——只是把月周圍的黑提亮一點點而已。
   踩過兩次的坑：這一層只要一亮，月就變成「一顆髒掉的灰球」（填滿的圓），
   或者「一圈煙」（中空的環）。峰值壓到 .05 上下，看得出來有光就夠了。 */
.gr-shine{position:absolute;left:50%;top:50%;translate:-50% -50%;pointer-events:none;
  width:104%;aspect-ratio:1;border-radius:50%;opacity:0;
  background:radial-gradient(circle closest-side,
    rgba(255,249,235,.044) 0%,rgba(255,248,233,.032) 32%,
    rgba(253,244,226,.014) 56%,rgba(250,240,218,0) 78%);
  transition:opacity 1.4s ease}
.gr[data-st="2"] .gr-shine{opacity:.45}
.gr[data-st="3"] .gr-shine{opacity:.7}
.gr[data-st="4"] .gr-shine{opacity:.88}
.gr[data-st="5"] .gr-shine{opacity:1}

/* 月：大小一路跟著捲動長（py.js 每一格寫這一個 transform，值沒變就不寫），
   所以這裡**不要**對 transform 加 transition，不然會跟 JS 搶同一個屬性、變得黏黏的。
   「會閃爍發亮」做在這一層的 **opacity**——合成層上的 opacity 動畫零重繪，
   而且跟 JS 寫的 transform 是兩個不同屬性，不會打架。 */
.gr-stone{position:absolute;inset:0;will-change:transform,opacity;transform:scale(.5);
  animation:grBreathe 6.5s ease-in-out 1.2s infinite alternate}
@keyframes grBreathe{from{opacity:.78}to{opacity:1}}
.gr-stone svg{display:block;width:100%;height:100%;overflow:visible}
.gr-art path{fill:none}
/* 月牙本身：填漸層，不描邊；外緣再壓一條更亮的唇 */
.gr-art .cres{fill:url(#grMn);stroke:none}
.gr-art .lip{fill:none;stroke:#FFFDF7;stroke-width:1.4;opacity:.42;
  transition:opacity 1.2s ease}
.gr[data-st="5"] .lip{opacity:.85}
/* 亮度分五段。只動 opacity，大小交給外面的 .gr-stone。 */
.gr-art .mn{opacity:.2;transition:opacity 1.5s ease}
.gr[data-st="1"] .mn{opacity:.32}
.gr[data-st="2"] .mn{opacity:.5}
.gr[data-st="3"] .mn{opacity:.68}
.gr[data-st="4"] .mn{opacity:.86}
.gr[data-st="5"] .mn{opacity:1}

/* ── 字 ── */
.gr-side{max-width:34em;justify-self:start}
.gr-hd .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.36em;
  color:var(--bronze)}
.gr-hd h2{margin-top:clamp(12px,1.8vh,20px);font-family:var(--disp);font-weight:700;
  color:var(--paper);font-size:clamp(30px,4.2vw,58px);letter-spacing:.24em;line-height:1}
.gr-hd p{margin-top:clamp(14px,2.2vh,22px);font-size:13.5px;line-height:2.3;
  color:var(--paper-2);letter-spacing:.06em;max-width:26em}

.gr-steps{display:flex;flex-wrap:wrap;gap:clamp(10px,1.4vw,22px);
  margin:clamp(20px,3.4vh,38px) 0 0;padding:0;list-style:none}
.gr-st{display:flex;align-items:baseline;gap:8px;opacity:.26;
  transition:opacity .8s ease}
.gr-st.on{opacity:1}
.gr-st .n{font-family:var(--mono);font-size:9px;letter-spacing:.24em;color:var(--bronze)}
.gr-st .t{font-family:var(--serif);font-weight:500;font-size:clamp(14px,1.5vw,19px);
  letter-spacing:.16em;color:var(--paper)}

/* 說明：出場比進場快而且不重疊，不然兩段字會疊成重影 */
.gr-panes{position:relative;margin-top:clamp(18px,2.8vh,30px);
  padding-top:clamp(16px,2.4vh,24px);border-top:1px solid var(--hair-2);
  min-height:clamp(150px,21vh,190px)}
.gr-pn{position:absolute;left:0;right:0;top:clamp(16px,2.4vh,24px);
  opacity:0;transform:translate3d(0,10px,0);pointer-events:none;
  transition:opacity .22s ease,transform .22s ease}
.gr-pn.on{opacity:1;transform:none;pointer-events:auto;
  transition:opacity .7s ease .3s,transform .9s var(--vslow) .3s}
.gr-pn h4{font-family:var(--serif);font-weight:500;font-size:clamp(16px,1.8vw,22px);
  letter-spacing:.2em;color:var(--paper)}
.gr-pn p{margin-top:clamp(11px,1.7vh,17px);font-size:13.5px;line-height:2.3;
  color:var(--paper-2);letter-spacing:.06em;max-width:27em}
.gr-pn .ot{display:block;margin-top:clamp(12px,1.8vh,18px);
  font-family:var(--mono);font-size:9px;letter-spacing:.3em;color:var(--paper-3)}
.gr-pn .ot b{font-family:var(--serif);font-weight:500;font-size:13px;
  letter-spacing:.18em;color:var(--bronze-hi)}
.gr-end .ot b{font-size:17px}

/* ── 手機：跟桌機跑同一段，只是排成直的 ────────────────────────
   2026-08-18 Ethan：「層層精磨的動畫，在手機不會動阿。」
   舊版在 980 以下整段換成**一張定格的儀器圖**（弧不轉、月不長、
   六段說明一次攤開），py.js 那邊也直接 `grDraw = null` 收工。
   那等於把整段最重要的東西關掉——這一段本來就是靠「一道一道收掉」
   在講層層精磨，不動就只剩一張圖。

   現在手機跑的是**同一支引擎**：一樣 sticky、一樣捲一段收一道、
   月一樣長大、說明一樣一段一段換。差別只有排版——
   左右兩欄改成上下：月在上，字在下。
   （`.gr` 的高度縮到 340svh：手機一次捲得比較多，430svh 會覺得卡太久。） */
@media (max-width:980px){
  .gr{height:340svh}
  .gr-fix{grid-template-columns:minmax(0,1fr);
    align-content:center;align-items:start;
    gap:clamp(12px,2.2vh,24px);
    padding:clamp(72px,10.5vh,110px) var(--gut) clamp(18px,3vh,34px)}
  .gr-art{width:min(58vw,30svh);justify-self:center}
  .gr-side{max-width:none;justify-self:stretch}
  .gr-hd .k{font-size:8.5px;letter-spacing:.3em}
  .gr-hd h2{margin-top:8px;font-size:clamp(25px,7.2vw,34px);letter-spacing:.2em}
  /* 這一句跟下面那一列 01–05 講的是同一件事，直排時擺兩份太佔高度 */
  .gr-hd p{display:none}
  .gr-steps{margin-top:clamp(12px,2vh,20px);gap:7px 13px}
  .gr-st{gap:6px}
  .gr-st .t{font-size:14px;letter-spacing:.12em}
  .gr-panes{margin-top:clamp(12px,2vh,20px);padding-top:clamp(11px,1.8vh,17px);
    min-height:clamp(128px,19vh,168px)}
  .gr-pn{top:clamp(11px,1.8vh,17px)}
  .gr-pn h4{font-size:16.5px;letter-spacing:.16em}
  .gr-pn p{margin-top:9px;font-size:12.5px;line-height:2.02}
  .gr-pn .ot{margin-top:10px;font-size:8.5px}
  .gr-pn .ot b{font-size:12.5px}
  .gr-end .ot b{font-size:15px}
  /* 月旁邊那五個名字：月縮小了，字不能跟著縮到看不見 */
  .gr-o em{font-size:10.5px;letter-spacing:.2em;text-indent:.2em}
  .gr-o em i{margin-bottom:4px;font-size:7.5px}
}
@media (prefers-reduced-motion:reduce){
  .gr{height:auto}
  .gr-fix{position:relative;height:auto;grid-template-columns:minmax(0,1fr);
    padding:clamp(56px,9vh,100px) var(--gut)}
  .gr-art{width:min(80vw,420px)}
  .gr-orbits{opacity:1}
  .gr-o{opacity:1!important;transform:none!important}
  /* 不轉了就要自己把五個角度岔開（--ma 寫在 about.html 上），
     不然五個名字會擠成兩坨。字照樣要反轉回正。 */
  .gr-o b{animation:none;transform:rotate(var(--ma,0deg))}
  .gr-o[data-dir="r"] b{transform:rotate(var(--ma,0deg))}
  .gr-o u{animation:none;transform:rotate(calc(var(--ma,0deg) * -1))}
  .gr-o[data-dir="r"] u{transform:rotate(calc(var(--ma,0deg) * -1))}
  .gr-o em,.gr-o.off em{opacity:.85}  /* .off 的權重比較高，這裡要一起蓋掉 */
  .gr-stone{transform:scale(.66)}
  .gr-art .mn{opacity:1}
  .gr-stone{animation:none;opacity:1}
  .gr-art *{transition:none!important}
  .gr-panes{min-height:0}
  .gr-pn{position:relative;top:auto;opacity:1!important;transform:none!important;
    margin-bottom:clamp(22px,4vh,40px);transition:none!important}
  .gr-st{opacity:1}
}


/* ════════════════════════════════════════════════════════════════════
   二十、手機　MOBILE　（全站最後一節，靠位置蓋掉前面的手機規則）
   ──────────────────────────────────────────────────────────────────
   Ethan 2026-08-17：「請全面調整手機也都可以超級完美顯示的。」

   量出來的問題有三類，這一節一次處理完：

   一、**字太小。** 四個頁面上量到 7.5～10.5px 的字有三十幾處
       （版權標記的英文 8px、選單的英文 9.5px、圖說 10px、
       「意象示意圖」7.5px…）。桌機上那是「細節」，手機上那是看不清楚。
       這一節把**所有微標籤拉到 11px 以上、內文拉到 15px 上下**。
       字距同時收一點——手機的行寬只有桌機的一半，字距不收就會斷得很難看。

   二、**版面沒有把螢幕用滿。** 首頁的建案卡只有 86vw × 4:3（335×251），
       844px 高的螢幕上下各空 250px；團隊的四個格子擠成一排，
       一格只剩 85px 寬，圖說被壓成三行。

   三、**兩處會撞到。** 地平線那一段的長說明會把標題頂到頁首的標記上面；
       360px 寬的機器上字塊還會探出版心 5px。

   規矩沒有變：只動 transform 與 opacity 的東西一個都沒碰，
   這裡改的全是字級、間距與版位。
   ════════════════════════════════════════════════════════════════════ */
@media (max-width:900px){

  /* ── 一、字級 ────────────────────────────────────────────── */
  /* 頁首與選單 */
  /* 2026-08-20 Ethan：「手機看還是太大，再小一些。然後手機看的時候，
     建案名稱也是再小一些。」
     **三個字級搬到同一個區塊裡**——標記在 900 區塊、建案名本來在 860 區塊，
     861～900 那一段會各走各的，結果建案名比標記還大。
     現在三個都用 vw、都在這個區塊裡。

     **2026-08-20 第三次收**（他：「手機板左上角的璞玥建設還是太大，
     很沒有質感」）：標記 22 → 16px。這已經是版面容許的下限——
     再小就會低於攤開後的標題（`.ro-info h3`），
     而那個標題又不能低於它下面的內文 12.5px 太多。
     **三個是一組的，動一個就要重算另外兩個**，
     然後跑 `node /home/claude/py/mobtype.js` 確認標記還是最大。

     字距順手從 .22 放到 .26em：字級收小之後，字距要補回來才像標準字，
     不然四個字會擠成一團。英文的比例從 .66 提到 .7em，
     不然 PRO YUE 會掉到 10px 以下變成一條灰線。 */
  .mark{font-size:clamp(13.5px,4vw,16px);--ls:.26em}
  .mark i{font-size:.7em}
  .roll .ro-cap h2{font-size:clamp(11.5px,3.4vw,13.5px)}
  .roll .ro-cap .en{font-size:9.5px;letter-spacing:.34em}
  .roll .ro-info h3{font-size:clamp(13px,3.8vw,15px)}
  .mark i{margin-top:5px}
  .menu-btn{font-size:12px;letter-spacing:.28em}
  nav ol li a{font-size:clamp(26px,7.4vw,34px)}
  #nav a em{font-size:11px;letter-spacing:.28em}
  #skip{font-size:11px;letter-spacing:.3em}
  /* 開場三拍：手機上 16px 的一句話撐不起整個開場 */
  #ov .act{font-size:clamp(21px,5.8vw,30px);letter-spacing:.28em;margin-left:.28em}

  /* 小標與微標籤：一律 11px 起跳 */
  .hz-cap .k,.gr-hd .k,.sr-hd .k,.cine .tx .k,.off-tx .k,.nextp .k,
  .stage .tx .k,.sec-hd .n{font-size:11px;letter-spacing:.3em}
  .hz-cap .no,.gr-st .n,.sec-hd .e,.spec b,.ft .be,.ft h5,
  .line .sub{font-size:10.5px;letter-spacing:.26em}   /* .ro-cap .en 的字級在上面 */
  .hz-more,.stage .scr,.ft-b span,.sr-more{font-size:10.5px;letter-spacing:.26em}
  .imgnote{font-size:10.5px;letter-spacing:.16em}
  .gr-o em{font-size:13px}
  .gr-o em i{font-size:10.5px;letter-spacing:.2em}
  .sr-nm .no,.sr-cr .n{font-size:11.5px}
  .sr-cr .lb{font-size:12px}

  /* 內文：手機上 12.5～13.5px 讀起來很吃力，一律拉到 15px 上下 */
  .hz-cap p{font-size:14.5px;line-height:2.05;letter-spacing:.04em}
  .gr-hd p,.gr-pn p,.cine .tx p,.off-tx p,.stage .tx p.sub,
  .body.narrow p,.sr-p .body p{font-size:15px;line-height:2.05;letter-spacing:.04em}
  .ft p,.ft a,.ft span.li{font-size:14px;line-height:2}
  .sr-cr li,.sr-cr .ls{font-size:13.5px;line-height:1.98}
  .sr-im .cap{font-size:11.5px;letter-spacing:.02em}
  /* 這三個字級 2026-08-18 收了一階：層層精磨在手機上改成 sticky 之後，
     月與整欄字要塞進同一個螢幕，字級跟著 980 那一段走。 */
  .gr-st .t{font-size:14.5px}
  .gr-pn .ot b{font-size:12.5px}
  .gr-end .ot b{font-size:15px}
  .sr-nm .side{font-size:13.5px;letter-spacing:.24em}

  /* ── 二、把螢幕用滿 ──────────────────────────────────────── */
  /* 首頁的建案卡：3:4 直的，佔掉大半個螢幕。
     渲染圖本來就是 cover 裁的，直的反而把樓拍得更完整。 */
  .roll .ro-cap{width:min(92vw,60svh)}
  .roll .ro-fr{gap:clamp(16px,2.6vh,26px)}
  .roll .ro-hint b{font-size:11px;letter-spacing:.2em;bottom:18px}
  .roll .ro-hint b em{margin-top:8px}

  /* 團隊的格子：2×2，一格 3:4。
     **圖說一定要能換行**：一段之內圖只佔右邊那一欄（約 200px），
     一格才 96px 寬，「璞昕地政士聯合事務所」一行放不下，
     寫 nowrap 就會被切成「璞昕地政…」。（2026-08-18 踩到。） */
  /* **不要寫 calc(50% - 4px) 配 gap:8px。** 兩格加中間那道縫剛好等於 100%，
     次像素一進位就換行，四張圖會變成直的一長條（量到一格 923px 高）。
     多讓 1.5px 出來才穩。這一條在 860 這一段，**權重比上面 900 那一段高**，
     要改就改這裡——只改 900 那一段是沒有用的（2026-08-18 踩到）。 */
  .sr-im{flex-wrap:wrap;gap:9px}
  .sr-im>*{flex:0 0 calc(50% - 6px);width:auto;height:auto;aspect-ratio:3/4}
  .sr-im .cap{white-space:normal;padding:clamp(20px,4.4vw,32px) 9px 9px;line-height:1.5}

  /* 聯絡頁的三格：直排之後每一格 114px 太鬆，收一點 */
  .spec>div{padding:clamp(18px,2.6vh,26px) 0}
  .spec b{margin-bottom:11px}
  /* 那句大字本來上下各留 186px，手機上就變成一大塊黑 */
  .line{padding:clamp(72px,13vh,130px) var(--gut)}
  .line p{font-size:clamp(20px,5.4vw,28px);line-height:1.95;letter-spacing:.16em}

  /* 層層精磨的天體。**2026-08-18 改了**：手機不再是攤平的一張圖，
     而是跟桌機一樣捲一段收一道（見上面 980 那一段的說明），
     所以月要跟下面那一整欄字**共用一個螢幕的高度**——
     88vw（＝330px）會把字擠出 sticky 框外。改成寬高兩邊都設上限。 */
  .gr-art{width:min(62vw,29svh);margin-bottom:0}
  .gr-o em{font-size:11px}
  .cut{height:clamp(56px,9vh,110px)}
  .cut.tall{height:clamp(76px,13vh,160px)}

  /* 題首那一行小標放大之後會斷成兩行，字距收一點讓它一行放得下 */
  .sr-hd .k{letter-spacing:.2em;max-width:none}

  /* ── 三、不要撞到 ────────────────────────────────────────── */
  /* 地平線：水線往下挪，並且給線上那一塊一個上界——
     長的說明會把標題一路頂到頁首的標記上面（收尾那一段量到 y=30）。
     bottom 對齊水線、top 卡住頁首，中間用 flex 貼底。 */
  .hz{--hy:54svh}
  .hz-cap>.up{top:clamp(104px,15svh,150px);
    display:flex;flex-direction:column;justify-content:flex-end}
  .hz-cap>.up,.hz-cap>.dn{left:0;right:0;max-width:none}
  /* 字壓在照片上，壓黑一定要夠。
     **這裡收過一次是錯的**：把負內縮從 −46%／−40% 收到 −12% 之後，
     白天那幾張的字整個糊掉（量測誤判成「探出版心」，其實那是換段時的位移，
     而且 .hz-fix 是 overflow:hidden，本來就不會撐出捲軸）。
     手機的字更小、螢幕更亮，壓黑要比桌機更重。 */
  .hz-cap>.up::before,.hz-cap>.dn::before{inset:-24px -22% -30px -18%;
    background:radial-gradient(80% 86% at 30% 50%,rgba(0,0,0,.92) 0%,
      rgba(0,0,0,.66) 46%,rgba(0,0,0,0) 100%)}
  /* 站在水線上的那兩個字，43px 在手機上撐不起一整屏 */
  .hz-cap.hz-split{--fs:clamp(46px,14vw,64px)}
  .hz-cap h2{text-shadow:0 0 30px rgba(0,0,0,.92),0 2px 10px rgba(0,0,0,.7)}
  .hz-cap .mid{text-shadow:0 0 34px rgba(0,0,0,.9),0 2px 12px rgba(0,0,0,.7)}
  .hz-cap p{text-shadow:0 0 28px rgba(0,0,0,.98),0 0 9px rgba(0,0,0,.95),0 1px 4px rgba(0,0,0,.9)}
}

/* 更窄的機器（360 以下）：字距再收，不然兩個字就要斷一行 */
@media (max-width:380px){
  .mark{--ls:.18em}   /* 字級由 900 區塊的 clamp 處理（360 時 18px）*/
  .hz-cap .k,.gr-hd .k,.sr-hd .k,.cine .tx .k,.stage .tx .k{letter-spacing:.24em}
  .sr-cr .lb{letter-spacing:.14em}
  .sr-im .cap{font-size:11px;letter-spacing:0}
}

/* ════════════════════════════════════════════════════════════════════
   二十一、服務項目　FOUR　（疊在地平線開場那一段的照片上）
   ──────────────────────────────────────────────────────────────────
   Ethan 2026-08-17：
   ①「1.全案管理 2.都市更新 3.危老建築 4.素地開發 **這個就是我們網站重點**。
      一定要搭配很有創意的設計、動畫、動態呈現。要有質感、呼吸感。」
   ②「服務項目要放在關於璞玥的**開場**。就疊在圖片上面是可以的。」
   ③「四個項目**不要有高低之分**。」

   **四道站在水線上的光。** 柱腳全部落在那條從頭到尾不動的地平線上——
   那條線本來就是這一頁的主角，光從線上長出來剛好接得起來。
   四根一樣高、一樣寬、等距；差別只在**呼吸的節奏**。

   走過的兩個彎路（不要再走一次）：
   1. 第一版做成照片旁邊的一行小清單 →「請你不要隨意做」。重點不能是註腳。
   2. 第二版做成獨立的一段、四根高矮不同 → 那是長條圖。
      **高矮不同就會被讀成數值大小**，等高反而乾淨。

   讓它不是「四根長方形」的兩件事：
   - **左右兩邊一定要化掉**（靜態 `mask-image`）。硬邊的長方形就是長條圖，光沒有邊。
   - 柱要**細**、顏色要**暖**。第一版 34–62px 太胖像蠟燭，純灰的漸層很塑膠。

   **呼吸感**：柱身 opacity（.62↔1）四根週期互質（11／13／17／19 秒），
   柱頂那一點光另外一組（5.5／6.5／7.5／8.5 秒），兩件事不會同時到頂。

   **效能**：柱身、柱頂、光暈都是 HTML 元素、各自合成層，只動 transform 與 opacity。
   長高是進場一次的 transition（`scaleY`，transform-origin 在底），
   跟著這一段的 `.on` 走，**捲動時一個字都不寫**。
   ════════════════════════════════════════════════════════════════════ */
/* 整塊掛在 .hz-cap 裡，底邊貼著水線 */
.hz-cap .hz-sv{position:absolute;left:0;right:0;bottom:calc(100% - var(--hy));
  height:min(26svh,232px);z-index:1;pointer-events:none}
/* 小標放在**水線下面**、跟第一根對齊。放上面會撞到 01 那一格的名字
   （柱頂的名字本來就在那個高度），而且再往上就頂到頁首的標記了。 */
.hz-sv .t{position:absolute;left:44%;top:calc(100% + clamp(20px,3.2vh,34px));
  translate:-50% 0;white-space:nowrap;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.3em;color:var(--bronze-hi);
  text-shadow:0 0 20px rgba(0,0,0,.95),0 0 7px rgba(0,0,0,.9),0 1px 4px rgba(0,0,0,.85);
  opacity:0;transition:opacity 1.1s ease .3s}
.hz-cap.on .hz-sv .t{opacity:1}

/* 一根光。四根一樣高一樣寬——「不要有高低之分」。 */
.sv-t{position:absolute;left:var(--x);bottom:0;translate:-50% 0;
  width:clamp(11px,1.35vw,19px);height:100%;font-style:normal}
.sv-t>b{position:absolute;inset:0;display:block;
  transform:scaleY(0);transform-origin:50% 100%;
  transition:transform 2.2s cubic-bezier(.22,.82,.28,1)}
.hz-cap.on .sv-t>b{transform:scaleY(1)}
.hz-cap.on .sv-t[data-k="0"]>b{transition-delay:.45s}
.hz-cap.on .sv-t[data-k="1"]>b{transition-delay:.61s}
.hz-cap.on .sv-t[data-k="2"]>b{transition-delay:.77s}
.hz-cap.on .sv-t[data-k="3"]>b{transition-delay:.93s}

/* 柱身：下面化進照片裡，越往上越亮、越暖。呼吸做在這一層的 opacity。
   **左右一定要化掉**——靜態遮罩只光柵化一次，這一層又只補間 opacity。 */
.sv-t s{position:absolute;inset:0;display:block;text-decoration:none;
  background:linear-gradient(to top,
    rgba(238,230,212,0) 0%,rgba(240,231,209,.08) 14%,
    rgba(244,235,215,.22) 46%,rgba(250,242,224,.46) 80%,rgba(255,251,240,.72) 100%);
  -webkit-mask-image:linear-gradient(to right,transparent 0%,#000 30%,#000 70%,transparent 100%);
  mask-image:linear-gradient(to right,transparent 0%,#000 30%,#000 70%,transparent 100%);
  will-change:opacity;
  animation:svBreathe var(--sp,15s) ease-in-out var(--dl,0s) infinite alternate}
@keyframes svBreathe{from{opacity:.62}to{opacity:1}}
/* 柱外面那一圈很淡的空氣 */
.sv-t>b::after{content:"";position:absolute;left:50%;top:-8%;bottom:0;width:1100%;
  translate:-50% 0;pointer-events:none;
  background:radial-gradient(44% 50% at 50% 68%,rgba(255,248,233,.085) 0%,
    rgba(255,248,233,.032) 44%,rgba(255,248,233,0) 100%)}
/* 柱頂那一點光：另一組週期 */
.sv-t u{position:absolute;left:50%;top:0;translate:-50% -50%;
  width:clamp(46px,5.4vw,76px);aspect-ratio:1;border-radius:50%;text-decoration:none;
  background:radial-gradient(circle closest-side,rgba(255,253,247,.8) 0%,
    rgba(255,248,233,.32) 20%,rgba(246,238,218,.08) 46%,rgba(246,238,218,0) 100%);
  will-change:transform,opacity;
  animation:svCap var(--cp,7s) ease-in-out var(--dl,0s) infinite alternate}
@keyframes svCap{from{opacity:.55;transform:scale(.82)}to{opacity:1;transform:scale(1.1)}}

/* 名字：落在自己的柱頂上方。照片有夜景也有白天，自己要帶壓黑。 */
.sv-t em{position:absolute;left:50%;bottom:calc(100% + clamp(18px,2.8vh,30px));
  translate:-50% 0;font-style:normal;white-space:nowrap;text-align:center;line-height:1;
  font-family:var(--disp);font-weight:500;color:rgba(243,237,224,.95);
  font-size:clamp(15px,1.5vw,20px);letter-spacing:.24em;text-indent:.24em;
  text-shadow:0 0 24px rgba(0,0,0,.92),0 1px 6px rgba(0,0,0,.85);
  opacity:0;transform:translate3d(0,12px,0);
  transition:opacity 1s ease,transform 1.2s var(--vslow)}
.sv-t em i{display:block;margin-bottom:9px;font-style:normal;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.28em;text-indent:.28em;
  color:var(--bronze);text-shadow:0 0 14px rgba(0,0,0,.9)}
.hz-cap.on .sv-t em{opacity:1;transform:none}
.hz-cap.on .sv-t[data-k="0"] em{transition-delay:1.5s}
.hz-cap.on .sv-t[data-k="1"] em{transition-delay:1.66s}
.hz-cap.on .sv-t[data-k="2"] em{transition-delay:1.82s}
.hz-cap.on .sv-t[data-k="3"] em{transition-delay:1.98s}

@media (max-width:900px){
  /* 手機：水線上面被標題佔滿了，四根改成站在畫面下緣，柱短一點。 */
  .hz-cap .hz-sv{top:auto;bottom:clamp(74px,10.5vh,104px);
    height:clamp(122px,16.5svh,156px)}
  .sv-t{width:clamp(9px,2.4vw,13px)}
  .sv-t[data-k="0"]{left:13%}
  .sv-t[data-k="1"]{left:38%}
  .sv-t[data-k="2"]{left:63%}
  .sv-t[data-k="3"]{left:88%}
  /* 手機：小標要放在名字**上面**，不然會跟四個名字印在同一行 */
  .hz-sv .t{left:0;top:auto;bottom:calc(100% + 56px);translate:0 0;
    font-size:11px;letter-spacing:.2em}
  .sv-t u{width:clamp(34px,9vw,44px)}
  .sv-t em{font-size:clamp(12.5px,3.4vw,15px);letter-spacing:.1em;text-indent:.1em;
    bottom:calc(100% + 13px)}
  .sv-t em i{font-size:9.5px;margin-bottom:6px;letter-spacing:.18em}
}
@media (prefers-reduced-motion:reduce){
  /* 不做動畫的人：四根直接站好 */
  .hz-cap .hz-sv{position:relative;left:auto;right:auto;bottom:auto;top:auto;
    height:clamp(150px,22vh,220px);margin-top:clamp(30px,5vh,52px)}
  .hz-sv .t{position:relative;left:auto;top:auto;bottom:auto;translate:0 0;display:block;
    opacity:1;margin-bottom:clamp(28px,4.4vh,46px)}
  .sv-t>b{transform:scaleY(1)}
  .sv-t s,.sv-t u{animation:none;opacity:1}
  .sv-t em{opacity:1;transform:none}
}

/* ════════════════════════════════════════════════════════════════════
   二十二、聯絡頁：四道可以點的光　＋　洽詢表單
   ──────────────────────────────────────────────────────────────────
   Ethan 2026-08-18：
   ①「聯絡我們請調整互動式網頁。」
   ②「同樣的光束質感方式呈現服務項目。」
   ③「全案管理才是我們的重點項目！」（但 08-17 定的「四個項目不要有
      高低之分」沒有取消——他選的是「等高，全案管理更亮更寬」，
      而且**只在這一頁強調**，about 那一頁維持完全等值。）

   光的做法整組沿用第二十一節（`.sv-t` 那一套：柱身漸層、左右靜態遮罩、
   柱頂的光、互質的呼吸週期），**沒有另外寫一份**——
   這一頁只多寫「站在哪裡」「怎麼被選中」「怎麼強調第一道」。

   底不是照片是純黑：這一頁的光要當主角，而且下面要放說明與表單，
   照片會把字吃掉。水線改成一條很細的橫線，跟 about 的地平線同一個語彙。

   效能：柱身、柱頂與光暈全部沿用原本的合成層動畫（只動 transform／opacity）；
   選中／沒選中只切 class，交給 CSS transition，JS 一格都不寫。
   ════════════════════════════════════════════════════════════════════ */
.bm{padding:clamp(60px,9vh,110px) 0 clamp(30px,5vh,60px)}
/* 名字掛在柱頂**上面**，會探出 .bm-set 的上緣，
   所以這裡要先留出那一段，不然會撞到上面的節標題。 */
.bm-stage{position:relative;margin-top:clamp(96px,13vh,152px);
  padding:0 var(--gut)}
/* 水線：四道光的柱腳全部落在這一條上 */
.bm-hz{position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(to right,rgba(231,231,231,0) 0%,
    rgba(231,231,231,.16) 12%,rgba(231,231,231,.16) 88%,rgba(231,231,231,0) 100%);
  transform:scaleX(0);transform-origin:50% 50%;
  transition:transform 2.4s var(--vslow)}
.bm.on .bm-hz{transform:scaleX(1)}
.bm-set{position:relative;height:min(30svh,268px)}

/* 一道光。`.sv-t` 已經給了柱身、柱頂、遮罩與呼吸，這裡只接手互動。 */
.bm-t{-webkit-appearance:none;appearance:none;background:none;border:0;padding:0;margin:0;
  color:inherit;font:inherit;cursor:pointer;pointer-events:auto;
  -webkit-tap-highlight-color:transparent}
.bm-t>b{transform:scaleY(0);transform-origin:50% 100%;
  transition:transform 2.2s cubic-bezier(.22,.82,.28,1)}
.bm.on .bm-t>b{transform:scaleY(1)}
.bm.on .bm-t[data-k="0"]>b{transition-delay:.35s}
.bm.on .bm-t[data-k="1"]>b{transition-delay:.51s}
.bm.on .bm-t[data-k="2"]>b{transition-delay:.67s}
.bm.on .bm-t[data-k="3"]>b{transition-delay:.83s}
.bm.on .bm-t em{opacity:1;transform:none}
.bm.on .bm-t[data-k="0"] em{transition-delay:1.35s}
.bm.on .bm-t[data-k="1"] em{transition-delay:1.51s}
.bm.on .bm-t[data-k="2"] em{transition-delay:1.67s}
.bm.on .bm-t[data-k="3"] em{transition-delay:1.83s}
/* 沒被選中的先收一階；選中／滑過再亮回來。
   **收的是整道的 opacity**，不是高度——高度四道永遠一樣。 */
.bm-t>b{opacity:.42;transition:transform 2.2s cubic-bezier(.22,.82,.28,1),
  opacity .9s ease}
.bm-t em{color:rgba(243,237,224,.5);transition:opacity 1s ease,
  transform 1.2s var(--vslow),color .8s ease}
.bm-t.on>b,.bm-t:hover>b,.bm-t:focus-visible>b{opacity:1}
.bm-t.on em,.bm-t:hover em,.bm-t:focus-visible em{color:rgba(243,237,224,.96)}
.bm-t:focus-visible{outline:1px solid rgba(232,220,196,.5);outline-offset:10px}
/* 加大可以點的範圍：柱身只有十幾像素寬，手指點不到。
   透明的、蓋在自己那一欄上，不影響畫面。 */
.bm-t::before{content:"";position:absolute;left:50%;top:-14%;bottom:-16%;
  width:180px;max-width:22vw;translate:-50% 0}

/* ── 重點項目：全案管理 ───────────────────────────────────────
   等高、等寬，只有「亮度、光暈、字級」不一樣。 */
.bm-t.lead s{background:linear-gradient(to top,
  rgba(240,232,214,0) 0%,rgba(243,234,212,.13) 14%,
  rgba(247,238,218,.32) 46%,rgba(252,245,228,.62) 80%,rgba(255,252,244,.92) 100%)}
.bm-t.lead>b::after{width:1700%;
  background:radial-gradient(44% 50% at 50% 68%,rgba(255,248,233,.14) 0%,
    rgba(255,248,233,.05) 44%,rgba(255,248,233,0) 100%)}
.bm-t.lead u{width:clamp(58px,7vw,96px)}
.bm-t.lead em{font-size:clamp(17px,1.75vw,23px)}
.bm-t.lead em i{color:var(--bronze-hi)}
/* 沒被選到的時候也要比其他三道亮一點——它是重點項目 */
.bm-t.lead>b{opacity:.66}
/* 「重點項目」那一枚小牌 —— **2026-08-18 從 HTML 拿掉了**
   （Ethan：「全案管理不用特別寫重點項目」）。樣式留著沒刪，
   要加回來直接在 em 裡面補 <span class="ld">。
   ── 以下是原本的說明 ──
   **一定要絕對定位**：
   寫在 em 裡面當一般的行會把整塊撐高，而 em 是靠 bottom 定位的，
   結果就是「全案管理」四個字比另外三個高一截——那正是他不要的高低之分。 */
.bm-t .ld{position:absolute;left:50%;top:calc(100% + 9px);translate:-50% 0;
  white-space:nowrap;
  font-family:var(--mono);font-size:8.5px;letter-spacing:.3em;text-indent:.3em;
  color:var(--bronze);text-shadow:0 0 12px rgba(0,0,0,.9)}

/* ── 說明：四段疊在同一個位置，跟層層精磨同一組秒數 ──
   出場要比進場快而且不重疊，不然兩段字會疊成重影。 */
.bm-desc{position:relative;margin-top:clamp(34px,5.4vh,64px);
  padding-top:clamp(20px,3vh,30px);border-top:1px solid var(--hair-2);
  min-height:clamp(140px,18vh,176px)}
/* 2026-08-24 放慢：原本出場 .22s、進場 .7s 起跳 .3s，但**進場那一段
   實際上從來沒有跑過**——見 py.js 的 pick()，元素是在同一個 tick 裡
   從 display:none 變成最終狀態的，瀏覽器沒有可以起算的前一幀，
   transition 整段被跳過（量到的是點下去 102ms 就已經 opacity 1）。
   py.js 那邊改成「先解除 hidden、強制回流、下一幀才上 .on」之後，
   這裡的曲線才會真的生效，所以順便把秒數拉到跟全站同一個節奏。
   出場 .42s 走完，進場延遲 .44s 才起步——**兩段不重疊**，
   不然兩組字會疊成重影（這是原本就定下的規則，沒有改）。 */
.bm-d{position:absolute;left:0;right:0;top:clamp(20px,3vh,30px);
  opacity:0;transform:translate3d(0,14px,0);pointer-events:none;
  transition:opacity .42s ease,transform .42s ease}
.bm-d.on{opacity:1;transform:none;pointer-events:auto;
  transition:opacity .9s var(--slow) .44s,transform 1.05s var(--vslow) .44s}
.bm-d h3{font-family:var(--disp);font-weight:500;color:var(--paper);
  font-size:clamp(20px,2.4vw,30px);letter-spacing:.22em;line-height:1.3}
.bm-d p{margin-top:clamp(12px,1.9vh,20px);max-width:34em;
  font-size:14px;line-height:2.25;color:var(--paper-2);letter-spacing:.05em}
/* 說明那一格的小牌也一起拿掉了（同上）。樣式留著。 */
.bm-d .ot{display:inline-block;margin-top:clamp(13px,2vh,20px);
  padding:6px 13px;border:1px solid rgba(185,151,95,.34);
  font-family:var(--mono);font-size:10px;letter-spacing:.3em;text-indent:.3em;
  color:var(--bronze-hi)}

/* ── 洽詢表單 ────────────────────────────────────────────────
   沒有卡片、沒有圓角、沒有填色——只有一條底線與字，
   跟整站「線與字」的語彙一致。 */
.ask-note{margin-bottom:clamp(20px,3vh,30px);padding:14px 16px;
  border:1px solid rgba(185,151,95,.3);
  font-size:12.5px;line-height:1.9;color:var(--paper-2);letter-spacing:.04em}
.ask-g{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(22px,3.4vh,34px) clamp(24px,3.4vw,52px)}
.ask-f{display:block;min-width:0}
.ask-f.wide{grid-column:1 / -1}
/* 表單的欄位標籤是**功能性**的字，不是裝飾——不要跟站上那些
   9px 的編號一樣小。桌機 10.5px、手機 11px。 */
.ask-f>span{display:block;margin-bottom:11px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.26em;color:var(--paper-2)}
.ask-f>span i{font-style:normal;margin-left:5px;color:var(--bronze)}
.ask-f input,.ask-f select,.ask-f textarea{
  -webkit-appearance:none;appearance:none;
  display:block;width:100%;box-sizing:border-box;
  background:transparent;border:0;border-bottom:1px solid var(--hair);
  border-radius:0;padding:9px 2px 11px;
  font-family:var(--sans);font-weight:300;font-size:15px;letter-spacing:.04em;
  color:var(--paper);
  transition:border-color .5s ease}
.ask-f textarea{resize:vertical;line-height:1.9;min-height:96px}
.ask-f select{cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,rgba(157,154,147,.9) 50%),
    linear-gradient(135deg,rgba(157,154,147,.9) 50%,transparent 50%);
  background-position:calc(100% - 9px) 55%,calc(100% - 4px) 55%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:22px}
.ask-f select option{background:var(--ink-2);color:var(--paper)}
.ask-f input::placeholder,.ask-f textarea::placeholder{color:var(--paper-3);opacity:1}
.ask-f input:focus,.ask-f select:focus,.ask-f textarea:focus{
  outline:none;border-bottom-color:rgba(185,151,95,.75)}
.ask-f.bad input,.ask-f.bad textarea{border-bottom-color:rgba(190,110,90,.85)}
.ask-b{display:flex;align-items:center;gap:clamp(18px,3vw,34px);flex-wrap:wrap;
  margin-top:clamp(34px,5vh,56px)}
.ask-go{-webkit-appearance:none;appearance:none;cursor:pointer;
  display:inline-flex;align-items:center;gap:14px;
  background:none;border:1px solid rgba(231,231,231,.22);
  padding:15px clamp(24px,3vw,38px);
  font-family:var(--serif);font-weight:500;font-size:14px;letter-spacing:.24em;
  text-indent:.24em;color:var(--paper);
  transition:border-color .6s ease,color .6s ease,background-color .6s ease}
.ask-go svg{width:24px;height:6px;overflow:visible;flex:0 0 auto}
.ask-go svg line,.ask-go svg path{stroke:currentColor;stroke-width:1;fill:none}
.ask-go:hover{border-color:rgba(185,151,95,.7);color:var(--bronze-hi)}
.ask-go[disabled]{cursor:default;opacity:.45}
.ask-msg{font-size:12.5px;line-height:1.9;color:var(--paper-2);letter-spacing:.04em}
.ask-msg.ok{color:var(--bronze-hi)}
.ask-msg.no{color:#c98a76}
.ask.sent .ask-g,.ask.sent .ask-go{display:none}

@media (max-width:900px){
  .bm-stage{padding:0 clamp(14px,4vw,26px)}
  .bm-set{height:clamp(146px,21svh,196px)}
  .bm-t{width:clamp(9px,2.4vw,13px)}
  .bm-t[data-k="0"]{left:12%}
  .bm-t[data-k="1"]{left:37.3%}
  .bm-t[data-k="2"]{left:62.6%}
  .bm-t[data-k="3"]{left:88%}
  .bm-t u{width:clamp(34px,9vw,44px)}
  .bm-t.lead u{width:clamp(44px,11.5vw,58px)}
  .bm-t em{font-size:clamp(12px,3.3vw,15px);letter-spacing:.08em;text-indent:.08em;
    bottom:calc(100% + 22px)}
  .bm-t.lead em{font-size:clamp(13px,3.7vw,17px)}
  .bm-t em i{font-size:9.5px;margin-bottom:6px;letter-spacing:.16em}
  /* 手機沒有那個空隙——那一枚小牌會壓在柱頂的光上面。
     說明那一格已經有同一枚牌了，這裡直接收掉。 */
  .bm-t .ld{display:none}
  .bm-t::before{width:24vw;max-width:24vw}
  .bm-desc{min-height:clamp(158px,24vh,200px)}
  .bm-d p{font-size:13.5px;line-height:2.1}
  .ask-g{grid-template-columns:minmax(0,1fr);gap:clamp(20px,3vh,28px)}
  .ask-f>span{font-size:11px;letter-spacing:.22em}
  .bm-d .ot{font-size:10.5px}
  .ask-f input,.ask-f select,.ask-f textarea{font-size:16px}  /* iOS 小於 16px 會自動放大整頁 */
  .ask-go{width:100%;justify-content:center}
}
@media (prefers-reduced-motion:reduce){
  .bm-hz{transform:scaleX(1)}
  .bm-t>b{transform:scaleY(1);opacity:1}
  .bm-t em{opacity:1;transform:none;color:rgba(243,237,224,.96)}
  .bm-t s,.bm-t u{animation:none;opacity:1}
  .bm-d{position:relative;top:auto;opacity:1;transform:none;pointer-events:auto;
    transition:none;margin-bottom:clamp(24px,4vh,40px)}
  .bm-d[hidden]{display:block}
  .bm-desc{min-height:0}
}

/* ════════════════════════════════════════════════════════════════════
   二十三、聯絡方式（contact.html）
   ──────────────────────────────────────────────────────────────────
   2026-08-18 Ethan：「聯繫方式請完整重作，做漂亮一點。記得手機也要一起調整好。」

   舊版是三欄一列的 `.spec`：四筆資料塞不進三欄、地址只好自己佔一列、
   右邊空一大片；而且四筆長得一模一樣，讀起來像規格表，不像一張名片。

   現在是**左右兩塊**：
   左邊是公司（中文名、英文名、一條青銅細線、地址中英各一行），
   右邊是三筆可以直接動作的（打電話、寄信、傳真），一筆一列、有分隔線。
   電話與信箱是真的連結，手機按下去就撥號／開信箱；傳真沒有動作，
   所以**不給箭頭也不給 hover**（`.no-go`）——會亮的東西就要點得下去。

   手機：兩塊改成上下，公司在上、三筆在下，一筆的高度給足手指按。
   ════════════════════════════════════════════════════════════════════ */
.ct-g{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:clamp(30px,5vw,90px);align-items:start}

/* ── 左：公司 ── */
.ct-id h3{font-family:var(--disp);font-weight:500;color:var(--paper);
  font-size:clamp(24px,3vw,40px);letter-spacing:.24em;line-height:1.25;text-indent:.24em}
.ct-id h3 span{display:block;margin-top:clamp(6px,1vh,10px);
  font-size:clamp(13px,1.25vw,17px);letter-spacing:.3em;text-indent:.3em;
  color:var(--paper-2)}
.ct-id .en{display:block;margin-top:clamp(12px,1.8vh,18px);
  font-family:var(--mono);font-size:9.5px;letter-spacing:.26em;color:var(--bronze)}
.ct-id .ln{display:block;width:clamp(34px,4vw,58px);height:1px;
  margin:clamp(22px,3.4vh,34px) 0;background:rgba(185,151,95,.55);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform 1.3s var(--vslow) .35s}
.ct-id.on .ln{transform:scaleX(1)}
.ct-id .ad{font-family:var(--serif);font-weight:500;color:rgba(233,228,217,.92);
  font-size:clamp(16px,1.55vw,21px);letter-spacing:.14em;line-height:1.95}
.ct-id .ad-en{display:block;margin-top:clamp(10px,1.5vh,15px);
  font-family:var(--mono);font-size:9px;letter-spacing:.1em;line-height:1.9;
  color:var(--paper-3)}

/* ── 右：三筆 ── */
.ct-l{margin:0;padding:0;list-style:none;border-top:1px solid var(--hair-2)}
.ct-l li{border-bottom:1px solid var(--hair-2)}
.ct-l a,.ct-l li>span{display:flex;align-items:baseline;gap:clamp(14px,2vw,26px);
  padding:clamp(20px,3vh,30px) 0;text-decoration:none;color:inherit}
.ct-l .k{flex:0 0 auto;width:clamp(76px,8vw,108px);
  font-family:var(--mono);font-size:9.5px;letter-spacing:.24em;color:var(--bronze);
  transition:color .6s ease}
.ct-l strong{flex:1 1 auto;min-width:0;font-family:var(--serif);font-weight:500;
  font-size:clamp(17px,1.75vw,24px);letter-spacing:.1em;color:rgba(233,228,217,.94);
  word-break:break-all;transition:color .6s ease}
.ct-l i{flex:0 0 auto;display:block;width:24px;height:6px;overflow:visible;
  opacity:.34;transition:opacity .6s ease,transform .7s var(--slow)}
.ct-l i svg{display:block;width:24px;height:6px;overflow:visible}
.ct-l i svg line,.ct-l i svg path{stroke:var(--bronze-hi);stroke-width:1;fill:none}
.ct-l a:hover .k{color:var(--bronze-hi)}
.ct-l a:hover strong{color:#fff}
.ct-l a:hover i{opacity:1;transform:translate3d(6px,0,0)}
.ct-l a:focus-visible{outline:1px solid rgba(232,220,196,.5);outline-offset:4px}
/* 傳真沒有動作，就不要長得像可以按的 */
.ct-l .no-go strong{color:var(--paper-2)}

@media (max-width:900px){
  .ct-g{grid-template-columns:minmax(0,1fr);gap:clamp(26px,4.4vh,40px)}
  .ct-id h3{font-size:clamp(23px,6.4vw,30px)}
  .ct-id h3 span{font-size:clamp(12.5px,3.4vw,15px)}
  .ct-id .ln{margin:clamp(16px,2.6vh,24px) 0}
  .ct-id .ad{font-size:clamp(15.5px,4.2vw,19px);line-height:1.9}
  .ct-id .en{font-size:10.5px;letter-spacing:.2em}
  .ct-id .ad-en{font-size:10px;letter-spacing:.05em}
  /* 一筆的字級不能收——這三筆是整頁最需要被讀到的東西。
     改成上下兩行：小標在上、內容在下，箭頭靠右。 */
  .ct-l a,.ct-l li>span{flex-wrap:wrap;gap:8px 12px;padding:clamp(17px,2.6vh,24px) 0}
  .ct-l .k{flex:1 1 100%;width:auto;font-size:10.5px}
  .ct-l strong{flex:1 1 auto;font-size:clamp(17px,4.7vw,21px);letter-spacing:.06em}
  .ct-l i{align-self:center}
}
@media (prefers-reduced-motion:reduce){
  .ct-id .ln{transform:scaleX(1)}
}

/* ════════════════════════════════════════════════════════════════════
   二十四、聯絡頁的三個「房間」
   ──────────────────────────────────────────────────────────────────
   2026-08-18 Ethan：「服務項目、聯絡方式、線上洽詢的版面有點太融合，
   導致畫面很難區分。」

   他說得對。三段全是純黑底、同樣的節標題、同樣的間距——
   捲下來就是一條連續的黑，讀的人不知道自己走到第幾段了。

   分開的三手，**都不加卡片、不加圓角、不加填色**（整站的語彙是線與字）：

   ① **一條滿版的線** 壓在每一段的開頭。不是版心那條，是**整個畫面寬**的，
      所以它讀起來是「換一章」，不是「又一個小標」。
   ② **中間那一段抬起來一階**（`#08080b`，比純黑亮一點點）。
      黑 → 微亮 → 黑，三段的界線用底色就分得出來，不必畫框。
      服務項目那一段一定要留純黑——四道光要在純黑上才亮得起來。
   ③ **編號變大、變成章節號**。從 10px 的小字改成 22px 的青銅數字，
      跟標題垂直對齊成一落，一眼就知道走到第幾段。
   ④ 段與段的上下留白拉開到 clamp(96px,15vh,190px)。

   每一段開頭再補一句話（`.rm-lead`），讓標題底下不是直接就撞到內容——
   這也是「太融合」的一部分：中間沒有喘息，眼睛找不到落點。
   ════════════════════════════════════════════════════════════════════ */
.rm{position:relative;padding:clamp(96px,15vh,190px) 0}
/* 滿版的一條線：版心那條只有內容寬，讀起來像小標；這條要橫過整個畫面 */
.rm::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(to right,rgba(231,231,231,0) 0%,
    rgba(231,231,231,.13) 14%,rgba(231,231,231,.13) 86%,rgba(231,231,231,0) 100%)}
/* 中間那一段抬起來一階。滿版，所以要自己吐出版心。 */
.rm-lift{background:#08080b}
.rm-lift::before{background:linear-gradient(to right,rgba(231,231,231,0) 0%,
  rgba(185,151,95,.26) 14%,rgba(185,151,95,.26) 86%,rgba(231,231,231,0) 100%)}
/* 這一頁的節標題改成「章節」的樣子：大編號 ＋ 標題，直的疊成一落 */
.rm .sec-hd{display:grid;grid-template-columns:auto minmax(0,1fr);
  align-items:center;gap:0 clamp(14px,2vw,26px);
  padding-bottom:clamp(18px,2.6vh,26px);margin-bottom:clamp(20px,3vh,32px)}
.rm .sec-hd .n{font-size:clamp(19px,2vw,24px);letter-spacing:.16em;
  color:var(--bronze);line-height:1}
.rm .sec-hd .t{font-size:clamp(21px,2.4vw,30px);letter-spacing:.22em;line-height:1.2}
.rm .sec-hd .e{grid-column:2;grid-row:2;margin-left:0;margin-top:7px;
  font-size:9px;letter-spacing:.3em}
/* 標題與內容之間的一句話——讓眼睛有地方落 */
.rm-lead{max-width:34em;margin:0 0 clamp(34px,5.4vh,64px);
  font-size:13.5px;line-height:2.3;color:var(--paper-2);letter-spacing:.06em}
/* 四道光那一段：小標下面直接接光，中間那句話與光之間再空一段 */
.rm.bm{padding-bottom:clamp(70px,11vh,130px)}
.rm.bm .bm-stage{margin-top:clamp(70px,10vh,120px)}

@media (max-width:900px){
  .rm{padding:clamp(62px,9.5vh,110px) 0}
  .rm .sec-hd{padding-bottom:15px;margin-bottom:16px}
  .rm .sec-hd .n{font-size:17px}
  .rm .sec-hd .t{font-size:19px;letter-spacing:.18em}
  .rm .sec-hd .e{font-size:9.5px;margin-top:6px}
  .rm-lead{margin-bottom:clamp(26px,4.4vh,44px);font-size:13px;line-height:2.1}
  .rm.bm .bm-stage{margin-top:clamp(56px,8vh,90px)}
}

/* ── 頁首標準字：往下滑收起來（見 py.js 的 markDraw）──────────────
   三個狀態，秒數各自不同：
     開場淡入      .mark 自己的 1.8s ease .3s ——**沒有動**，
                   那是網站開場的節奏，不要被下面兩條蓋掉
     往下滑收起來  body.mk-off    .34s —— 擋到人就要快點退
     往上滑回來    body.mk-armed  .5s  —— 這個類別是第一次收起來
                   之後 JS 才掛上的，所以開場那一次不受影響
   **用 opacity 不用 display**：突然不見比疊在一起還糟。
   pointer-events 一起關掉，看不見的東西不應該還能點。
   這兩條要放在 `body.up .mark{opacity:1}` 後面（同分，後面的贏）。 */
body.mk-armed .mark{transition:opacity .5s ease}
body.mk-off .mark{opacity:0;pointer-events:none;transition:opacity .34s ease}


/* ═══════════════════════════════════════════════════════════════════
   第三十節　作品放大檢視（team.html 的建築師個案）── 2026-08-24
   ───────────────────────────────────────────────────────────────────
   Ethan：「建築師的個案圖片要可以滑鼠移過去後變成彩色，也可以點擊放大，
   要有順暢、質感緩慢的動態感。」

   **原本 hover 變彩色是壞的。** `.sr-im a:hover img{filter:none}` 只寫給
   `<a>`，而建築師那四格外層是 `<span>`（其他人的格子才是連到外站的
   `<a>`），所以那四張永遠停在灰階。現在四格改成 `<button class="zm">`，
   底下的選擇器一併補上。
   ═══════════════════════════════════════════════════════════════════ */

/* ── 一、可以放大的那一格 ── */
.sr-im .zm{-webkit-appearance:none;appearance:none;padding:0;border:0;margin:0;
  background:var(--ink-3);cursor:pointer;text-align:left;color:inherit;font:inherit}
.sr-im .zm:focus-visible{outline:1px solid rgba(232,220,196,.55);outline-offset:4px}
/* hover 變彩色：**a 與 zm 兩種都要**（原本只有 a） */
.sr-im a:hover img,.sr-im .zm:hover img,.sr-im .zm:focus-visible img{
  filter:none;transform:scale(1.06)}
/* 圖說後面的記號：連到外站是 ↗，可以放大的是一個框 */
.sr-im .zm .cap::after{content:"\00A0\00A0⤢";color:var(--bronze)}

/* ── 二、放大檢視 ── */
.lb{position:fixed;inset:0;z-index:200;display:grid;place-items:center;
  padding:clamp(48px,7vh,86px) clamp(52px,7vw,110px)}
.lb[hidden]{display:none}
.lb-bg{position:absolute;inset:0;background:rgba(0,0,0,.95);
  opacity:0;transition:opacity .7s ease}
.lb.on .lb-bg{opacity:1}

.lb-fig{position:relative;z-index:1;margin:0;display:flex;flex-direction:column;
  align-items:center;gap:clamp(14px,2.2vh,24px);max-width:100%;
  opacity:0;transform-origin:50% 50%;will-change:transform,opacity}
.lb-fig{cursor:pointer}
.lb-fig img{display:block;max-width:min(88vw,1360px);max-height:78svh;
  width:auto;height:auto;object-fit:contain;background:var(--ink-3)}
.lb-fig figcaption{display:flex;align-items:baseline;gap:clamp(12px,1.6vw,22px);
  opacity:0;transition:opacity .8s ease}
.lb.on .lb-fig figcaption{opacity:1;transition:opacity .9s ease .55s}
.lb-fig .n{font-family:var(--mono);font-size:9.5px;letter-spacing:.3em;color:var(--bronze)}
.lb-fig .t{font-family:var(--serif);font-weight:500;font-size:clamp(13px,1.4vw,17px);
  letter-spacing:.18em;color:var(--paper)}

/* 換圖：舊的先淡掉一點點再換，不要硬切 */
.lb.swap .lb-fig img{opacity:0;transform:scale(.985);
  transition:opacity .38s ease,transform .38s ease}
.lb .lb-fig img{opacity:1;transform:none;
  transition:opacity .75s ease,transform 1.1s var(--vslow)}

/* 關閉鈕與左右 */
.lb-x,.lb-a{position:absolute;z-index:2;-webkit-appearance:none;appearance:none;
  background:none;border:0;padding:0;cursor:pointer;color:var(--paper);
  opacity:0;transition:opacity .7s ease .35s,color .5s ease}
.lb.on .lb-x,.lb.on .lb-a{opacity:.55}
.lb.on .lb-x:hover,.lb.on .lb-a:hover,
.lb.on .lb-x:focus-visible,.lb.on .lb-a:focus-visible{opacity:1;color:var(--bronze-hi)}
.lb-x{right:clamp(18px,2.6vw,40px);top:clamp(18px,2.6vh,40px);
  width:40px;height:40px;display:grid;place-items:center}
.lb-x svg{width:12px;height:12px;overflow:visible}
.lb-x svg line{stroke:currentColor;stroke-width:1}
.lb-a{top:50%;translate:0 -50%;width:52px;height:52px;display:grid;place-items:center}
.lb-a.p{left:clamp(10px,1.6vw,26px)}
.lb-a.n{right:clamp(10px,1.6vw,26px)}
.lb-a svg{width:26px;height:7px;overflow:visible}
.lb-a svg line,.lb-a svg path{stroke:currentColor;stroke-width:1;fill:none}

@media (max-width:860px){
  .lb{padding:clamp(56px,9vh,80px) 16px}
  .lb-fig img{max-width:94vw;max-height:68svh}
  .lb-a{top:auto;bottom:clamp(14px,3vh,26px);translate:0 0}
  .lb-a.p{left:22vw}
  .lb-a.n{right:22vw}
}

/* 減少動態：不要飛、不要縮放，直接出現 */
@media (prefers-reduced-motion:reduce){
  .lb-fig{transition:none!important;transform:none!important;opacity:1}
  .lb-bg,.lb-fig figcaption,.lb-x,.lb-a{transition:none}
  .lb .lb-fig img,.lb.swap .lb-fig img{transition:none;transform:none;opacity:1}
}
