/* calm.css — 「天象檔案館」主題：深海軍藍夜空、舊黃銅髮絲線、暖象牙文字。
   設計語言：古典天文圖誌／銅版雕刻線稿／博物館展示面板——
   精確、節制、緩慢；不炫技、不奇幻、不像 SaaS。 */

/* 亮度基準：一般手機「中等亮度」即可輕鬆閱讀——
   整體明度上調（背景、文字、線條同步），保留深藍＋舊金色系與柔和感 */
:root {
  --bg: #101823;            /* 深海軍藍（調亮） */
  --bg-soft: #182233;       /* 石板藍面板 */
  --panel: rgba(24, 34, 51, .72);
  --ink: #f7f2e6;           /* 暖象牙（再調亮，降低久讀疲勞） */
  --ink-dim: #ddd4c0;       /* 次要文字：提高飽和與亮度 */
  --ink-faint: #b3a98f;     /* 最淡的註記文字 */
  --accent: #e0c184;        /* 舊黃銅（提高飽和） */
  --accent-dim: #bda06a;
  --line: rgba(211, 181, 120, .24);        /* 金色髮絲線 */
  /* 解讀正文的暗色面板。理由見 .r-section .r-block p 那一段的註解：長頁面滾過
     星圖亮區時，文字必須自己帶底才讀得清楚。
     ⚠ 這三個值是**唯一定義處**。吃它的有五個地方——解讀各節的段落、占星的
     .as-seg、梅花的 .mh-tip、雷諾曼的 .lg-para，以及靈感卡下方的解讀文
     .oc-note。以前是四份字面值各寫一遍，調一次要改四處，一定漏一個。 */
  --panel-bg: rgba(13, 20, 31, .48);
  --panel-line: rgba(214, 183, 122, .14);
  --panel-blur: blur(5px);
  --line-strong: rgba(211, 181, 120, .42);
  /* 預設＝繁體中文。其他語系在下方依 html[lang] 覆寫這兩個變數 */
  --serif: 'Songti TC', 'Noto Serif TC', 'PMingLiU', Georgia, 'Times New Roman', serif;
  --sans: 'Noto Sans TC', 'PingFang TC', 'Microsoft JhengHei', -apple-system, sans-serif;
  /* 占星符號（☉☽♀⚷…）專用：CJK 字體多半沒有這些字符，要另外指定符號字型。
     js/chartWheel.js 的缺字偵測會讀這個變數，兩邊必須是同一組堆疊才量得準。 */
  --symbol: 'Apple Symbols', 'Segoe UI Symbol', 'Noto Sans Symbols 2', sans-serif;
}

/* hidden 屬性一定要贏。
   任何寫了 display:flex／grid／block 的元件，都會蓋掉瀏覽器預設的
   [hidden] { display:none }，於是「藏起來的東西還看得見」。這個 bug 在本專案
   已經出現三次（.astro-saved、.weaving-slow、.filter-bar），每次都是各自補一條
   `.x[hidden]{display:none}`。這裡一次擋掉，之後新元件不必再記得補。 */
[hidden] { display: none !important; }

/* ---- 各語系字型 ----
   為什麼要分：Songti TC 有漢字但沒有假名，也沒有諺文。日文頁面若用繁中堆疊，
   漢字由 Songti TC 畫（而且是中文字形）、假名 fallback 到系統日文字體，
   同一句話會出現兩套字體。韓文的諺文同理，英文則會被 Songti TC 的拉丁字形接走。
   html 的 lang 由 initDocumentLang() 設定，所以只覆寫變數就好，元件 CSS 不必改。 */
html[lang^="ja"] {
  --serif: 'Hiragino Mincho ProN', 'Hiragino Mincho Pro', 'Yu Mincho', YuMincho,
    'Noto Serif JP', serif;
  --sans: 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', YuGothic,
    'Noto Sans JP', -apple-system, sans-serif;
}
/* iOS 沒有可靠的系統諺文明朝體，所以韓文的 serif 實際上多半會落到 gothic */
html[lang^="ko"] {
  --serif: AppleMyungjo, 'Nanum Myeongjo', 'Noto Serif KR', serif;
  --sans: 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR',
    -apple-system, sans-serif;
}
html[lang^="en"] {
  --serif: Georgia, 'Times New Roman', serif;
  --sans: -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body { height: 100%; }
body {
  background:
    radial-gradient(1400px 900px at 50% -12%, #131c2c 0%, var(--bg) 58%) fixed var(--bg);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.95;
  -webkit-font-smoothing: antialiased;
}

/* ---- 星圖背景：站主提供的星圖攝影 + 可讀性暗色塗層 ----
   橫向視窗用方形圖（bg-square）、直向視窗用縱向圖（bg-portrait）。 */
.sky {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background: url('../assets/bg-square.jpg') center / cover no-repeat #05070c;
  filter: saturate(1.05); /* 新星圖本身已夠暗，不再額外提亮 */
}
@media (orientation: portrait) {
  .sky { background-image: url('../assets/bg-portrait.jpg'); }
}
/* 可讀性塗層：新星圖底色已深，僅在中央星盤亮核處輕壓一層即可 */
.sky::after {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(closest-side at 50% 45%,
      rgba(5, 8, 13, .42), rgba(5, 8, 13, .26) 55%, rgba(5, 8, 13, .1) 82%, rgba(5, 8, 13, .04)),
    linear-gradient(180deg, rgba(5, 8, 13, .2), rgba(5, 8, 13, 0) 30%, rgba(5, 8, 13, 0) 70%, rgba(5, 8, 13, .26));
}
/* ---- --sky-clear／--sky-text：背景金色造型的淨空高度 ----------------------
   站主 2026-09：「背景最上面那個金色圈圈（裡面一個實心的圓、外面一個空心的大圓）
   不要被遮住，文字跟我們自己加上去的星軌圈圈都要在它下面。」

   ── 那個造型在視窗裡的位置（bg-portrait.jpg，1024×1536＝2:3）──
   沿垂直中線量亮度剖面（tools 沒有腳本，用 PIL 量的）：
     ・實心亮核在圖高 9.7%，外圈那個**空心大圓**的下緣到 15.5%
     ・再往下 18.9% 另有一顆小的「實心點＋細圓環」，下緣到 20.2%
   兩者之間只差 2.8% 的高度（393×715 上約 20px），一行字放不進去——所以字只能
   「從小點旁邊過」或「整個讓到小點下面」，沒有中間值。站主看過三種距離的對照圖
   之後選了前者，於是變成兩條線：

   --sky-clear（裝飾／動畫用，＝大圓＋小點都讓開，20.2% ＋ 18px）
     給等待畫面那組會轉的星軌用。站主：星軌跟背景造型「像首飾一樣，幾乎寶石要
     連在一起」，小點正好接在星軌大圈的上面，那個距離就是要的效果。

   --sky-text（要閱讀的字用，＝只讓開空心大圓，15.5% ＋ 8px）
     站主：「原本的位置還可以，跟金色圈圈擺起來不會醜，要移也只能小幅度」。
     所以字只避開大圓，那顆小點就讓它從字旁邊穿過去——首頁在 393×715 上是
     從 79px 移到 119px（讓到小點下面的話會是 150px，站主覺得太多）。

   cover 的縮放分兩種，所以下面各有兩條 media query（f＝該特徵在圖高的比例）：
     ・視窗比 2:3 更高瘦 → 靠高度填滿、垂直不裁切 → 位置 ＝ f × 視窗高
     ・視窗比 2:3 寬（但仍是直向）→ 靠寬度填滿、上下對稱裁掉
       → 位置 ＝ 50dvh + 1.5 × 視窗寬 × (f − 0.5)
       f=0.202 就是 50dvh − 44.7vw；f=0.155 就是 50dvh − 51.75vw
   兩條在 2:3 交界上算出來的值一模一樣，所以轉向、改變視窗大小時不會跳。

   用法是 padding-top: max(這一頁原本的留白, var(--sky-text))——非直向視窗時
   兩個變數都是 0px，max() 自動退回原本的值，不必再包一層 media query。

   ⚠ 橫向視窗不必淨空：那時候換成 bg-square.jpg，那張圖的構圖裡**沒有**這個造型
     （它從那顆小點下面才開始，實測 bg-square.jpg 3.5% 處就是上面說的那顆小點）。
   ⚠ 用 dvh 不是 vh：iOS Safari 的 vh 是「網址列收起來」的大視窗高，網址列還在時
     背景（position: fixed）只鋪滿目前的小視窗，用 vh 會算出偏低的位置。
     不支援 dvh 的瀏覽器由 @supports 外面那一行的 vh 版本接手。 */
:root { --sky-clear: 0px; --sky-text: 0px; }
@media (orientation: portrait) and (max-aspect-ratio: 2/3) {
  :root { --sky-clear: calc(20.2vh + 18px); --sky-text: calc(15.5vh + 8px); }
  @supports (height: 1dvh) {
    :root { --sky-clear: calc(20.2dvh + 18px); --sky-text: calc(15.5dvh + 8px); }
  }
}
@media (orientation: portrait) and (min-aspect-ratio: 2/3) {
  :root { --sky-clear: calc(50vh - 44.7vw + 18px); --sky-text: calc(50vh - 51.75vw + 8px); }
  @supports (height: 1dvh) {
    :root { --sky-clear: calc(50dvh - 44.7vw + 18px); --sky-text: calc(50dvh - 51.75vw + 8px); }
  }
}

/* 後台：縱向星圖＋較深的塗層（資料密度高，可讀性優先） */
.sky-admin { background-image: url('../assets/bg-portrait.jpg'); }
/* 後台把星圖壓得比前台重得多：這裡是密集表格與數字，可讀性優先於氣氛。
   星圖仍看得見（還是同一個產品），但不再跟資料搶注意力。 */
.sky-admin::after {
  background:
    linear-gradient(180deg, rgba(5, 8, 13, .9), rgba(5, 8, 13, .86) 40%, rgba(5, 8, 13, .92));
}
/* 後台不需要那層為照片背景加的文字陰影，數字反而變糊 */
.admin-body .screen { text-shadow: none; }

/* ⚠ min-height 一定要有 dvh 這一版。iOS Safari 的 100vh 是「網址列收起來」的
   大視窗高，網址列還在時它比看得到的畫面高出約 120px——於是每一頁都憑空多出
   一段可以捲的空白。背景（.sky）是 fixed 的，內容一捲就整片壓到背景那個金色
   造型上（站主 2026-09 回報的等待畫面重疊，成因就是這一行而不是那一頁的排版）。 */
.app { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; align-items: center; position: relative; z-index: 1; }

.screen { display: none; width: 100%; max-width: 660px; padding: 0 22px 60px; }
/* 照片背景上的文字可讀性：全域細字陰影（發光面按鈕除外） */
.screen { text-shadow: 0 1px 3px rgba(3, 7, 13, .75); }
.btn.primary { text-shadow: none; }
.screen.active { display: block; animation: fadein 1s ease both; }
@keyframes fadein { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---- 入口 ---- */
.intake { text-align: center; padding-top: max(11vh, var(--sky-text)); }
.eyebrow {
  font-size: 13px; letter-spacing: .5em; text-indent: .5em;
  text-transform: uppercase;
  color: #cbb075; margin-bottom: 30px;
  font-family: Georgia, 'Times New Roman', serif;
  text-shadow: 0 0 14px rgba(203, 176, 117, .35), 0 1px 3px rgba(3, 7, 13, .8);
}
.intake h1 {
  font-family: var(--serif); font-weight: 500;
  font-size: 44px; letter-spacing: .35em; text-indent: .35em;
  color: var(--ink); margin-bottom: 26px;
}
.intake h1.h1-long {
  font-size: clamp(24px, 5.4vw, 32px); letter-spacing: .14em; text-indent: .14em;
}
.lede { color: var(--ink-dim); font-size: 15px; margin: 0 auto 44px; }

/* UI 文案排版：置中、提早換行、上下行長度接近（text-wrap: balance），
   並收窄文字欄寬避免「第一行滿、第二行只剩幾個字」 */
.h1-long, .lede, .divine-lede, .fineprint, .r-sub, .r-closing,
.r-continue-title, .r-continue-hint, .r-advanced-hint, .num-picked, .copy-toast {
  text-wrap: balance;
}
.lede, .divine-lede { max-width: 30em; margin-left: auto; margin-right: auto; }
.fineprint, .r-continue-hint, .r-advanced-hint { max-width: 26em; margin-left: auto; margin-right: auto; }
/* 按鈕文字永不斷行 */
.btn { white-space: nowrap; }

/* 分隔飾線：兩端淡出的金線 + 中央發光星點（呼應照片裡的星節點） */
.rule-orn {
  width: 220px; height: 1px; margin: 0 auto 30px; position: relative;
  background: linear-gradient(90deg, transparent, rgba(214, 183, 122, .6), transparent);
}
.rule-orn::after {
  content: ''; position: absolute; left: 50%; top: -2.5px;
  width: 6px; height: 6px; border-radius: 50%; transform: translateX(-50%);
  background: #ecd7a4;
  box-shadow: 0 0 10px 2px rgba(236, 215, 164, .55);
}

/* 提問區：毛玻璃暗色面板＋柔光金邊（文字浮在照片上仍清晰） */
.ask-box {
  text-align: left; margin-bottom: 30px; position: relative;
  padding: 20px 20px 18px; border: 1px solid rgba(214, 183, 122, .28);
  border-radius: 3px;
  background: rgba(13, 20, 31, .55);
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  box-shadow: 0 0 22px rgba(214, 183, 122, .08), 0 10px 34px rgba(0, 0, 0, .4);
}
.ask-box label {
  display: flex; align-items: center; gap: 12px;
  font-size: 14px; color: var(--accent); margin-bottom: 14px;
  font-family: var(--sans); letter-spacing: .24em;
}
.ask-box label::after { content: ''; flex: 1; border-top: 1px solid var(--line); }
/* 面板內的輸入區：極淡邊框（避免「框中框」的重複感） */
textarea {
  width: 100%; resize: vertical;
  background: rgba(0, 0, 0, .22);
  color: var(--ink);
  border: 1px solid rgba(214, 183, 122, .14); border-radius: 2px;
  box-shadow: inset 0 0 18px rgba(0, 0, 0, .3);
  padding: 14px 16px; font: inherit; font-size: 16.5px; line-height: 1.8;
}
textarea:focus { outline: none; border-color: rgba(226, 198, 138, .5); }
/* 提示句要一眼看得出「這不是已填好的字」：半透明壓淡，
   與真正輸入時的亮象牙色（--ink）拉開明顯距離。
   Chrome 的 placeholder 預設不帶透明度，必須明寫。 */
textarea::placeholder { color: var(--ink-faint); opacity: .45; }

/* ---- 首頁：分析工具選擇 ---- */
.tool-pick { margin-bottom: 30px; }
.tool-pick-label {
  font-size: 14px; color: var(--accent); font-family: var(--sans);
  letter-spacing: .22em; margin-bottom: 14px;
}
/* minmax(0, 1fr) 而不是 1fr：1fr 等於 minmax(auto, 1fr)，欄位縮不到內容的最小寬度以下。
   手機上的襯線 CJK 比桌機的寬，工具名一撐，grid 就比可用寬度寬 → 整份文件被撐寬 →
   置中的標題與選單看起來全部往右偏。minmax(0, …) 讓欄位可以縮，字自己換行就好。 */
.tool-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.tool-opt {
  position: relative; font: inherit; font-size: 17px;
  font-family: var(--serif); color: var(--ink);
  background: rgba(13, 20, 31, .5);
  border: 1px solid rgba(214, 183, 122, .3); border-radius: 3px;
  padding: 16px 8px; cursor: pointer; text-align: center;
  transition: color .3s, border-color .3s, background .3s, box-shadow .4s;
}
.tool-opt:hover:not(.soon) { color: var(--ink); border-color: rgba(226, 198, 138, .6); }
.tool-opt.on {
  color: #f3eddd; border-color: #e6cd96;
  background: rgba(214, 183, 122, .14);
  box-shadow: 0 0 18px rgba(224, 195, 132, .22), inset 0 0 12px rgba(224, 195, 132, .1);
}
.tool-opt.on::after {
  content: '✓'; position: absolute; top: 5px; right: 8px;
  font-size: 11px; color: #e6cd96;
}
/* 停用項：仍看得清楚，但以虛線框與較低對比表示不可選 */
.tool-opt.soon {
  color: var(--ink-dim); cursor: not-allowed; opacity: .82; border-style: dashed;
  background: rgba(10, 15, 24, .58);
  /* 這兩格只有 Coming Soon 一行字，靠 flex 置中，才不會貼在有工具名那幾格的頂端 */
  display: flex; align-items: center; justify-content: center;
}
.tool-opt.soon .soon-tag { margin-top: 0; }
.soon-tag {
  display: block; margin-top: 5px; font-size: 11px; letter-spacing: .04em;
  font-family: var(--sans); color: var(--accent-dim); text-transform: uppercase;
  /* 字距收一點，一般寬度下「COMING SOON」自然排得下一行。這裡刻意不寫 white-space: nowrap：
     窄螢幕或較寬的字型下，nowrap 會撐破欄位 → 撐寬整份文件 → 全站置中的東西往右偏。
     真的排不下時讓它折成兩行，比整頁歪掉好。 */
}
/* 工具小標：一眼看出這個工具擅長回答哪一類問題 */
.tool-sub {
  display: block; margin-top: 6px; font-size: 12.5px; line-height: 1.45;
  letter-spacing: .06em; font-family: var(--sans); color: var(--ink-faint);
  transition: color .3s;
}
.tool-opt.on .tool-sub { color: var(--accent-dim); }
@media (max-width: 560px) {
  .tool-opt { font-size: 14.5px; padding: 14px 6px; }
  .tool-sub { font-size: 11.5px; margin-top: 4px; letter-spacing: .02em; }
}

/* ---- 結果頁：使用者回饋（星等＋選填文字） ---- */
.r-feedback {
  margin: 26px auto 0; max-width: 440px; padding: 22px 20px 24px;
  text-align: center; border: 1px solid rgba(214, 183, 122, .22); border-radius: 3px;
  background: linear-gradient(180deg, rgba(10, 15, 24, .74), rgba(8, 12, 20, .86));
  box-shadow: inset 0 0 26px rgba(0, 0, 0, .42);
}
.fb-title {
  font-family: var(--serif); font-size: 15px; color: var(--ink);
  line-height: 1.8; margin-bottom: 14px;
}
.fb-stars { display: flex; justify-content: center; gap: 6px; }
.fb-star {
  background: none; border: none; cursor: pointer; padding: 2px 4px;
  font-size: 27px; line-height: 1; color: rgba(179, 169, 143, .38);
  transition: color .18s, transform .18s, text-shadow .18s;
}
.fb-star:hover { transform: translateY(-1px); color: var(--accent-dim); }
.fb-star.on { color: var(--accent); text-shadow: 0 0 12px rgba(224, 193, 132, .55); }
.fb-scale {
  min-height: 1.5em; margin-top: 6px; font-family: var(--sans);
  font-size: 12.5px; letter-spacing: .06em; color: var(--accent-dim);
}
.fb-more { margin-top: 8px; }
.fb-text {
  display: block; width: 100%; box-sizing: border-box; resize: vertical;
  margin-bottom: 12px; padding: 11px 12px;
  /* 16px 是下限（iOS 自動放大，見檔尾說明）——原本 14px */
  font-family: var(--sans); font-size: 16px; line-height: 1.7;
  color: var(--ink); background: rgba(6, 10, 17, .7);
  border: 1px solid rgba(214, 183, 122, .26); border-radius: 3px;
}
.fb-text:focus { outline: none; border-color: var(--accent-dim); box-shadow: 0 0 14px rgba(214, 183, 122, .14); }
.fb-text::placeholder { color: var(--ink-faint); opacity: .45; }
.fb-hint {
  margin-top: 12px; font-family: var(--sans); font-size: 12px;
  line-height: 1.7; color: var(--ink-faint);
  max-width: 22em;   /* 斷行規則見「短文案的斷行」那一段（結果頁與視窗共用） */
}
.fb-msg { margin-top: 8px; font-family: var(--sans); font-size: 12.5px; color: #e0a08a; }
/* 送出後的唯讀回看：不是輸入框，只是把當時填的內容靜靜放著 */
.fb-echo { margin-top: 10px; }
.fb-echo-stars { color: var(--accent); font-size: 15px; letter-spacing: .3em; }
.fb-echo-text {
  margin: 8px 0 0; padding: 10px 12px;
  font-family: var(--sans); font-size: 13.5px; line-height: 1.7;
  color: var(--ink-dim); white-space: pre-wrap;
  /* 區塊本身置中，但留言是使用者自己寫的句子——置中會很難讀 */
  text-align: left;
  border-left: 2px solid rgba(214, 183, 122, .3);
  background: rgba(6, 10, 17, .45);
}
.fb-done {
  font-family: var(--serif); font-size: 14.5px; line-height: 1.8; color: var(--accent);
}
.r-feedback.done { padding: 18px 20px; }

/* ---- 結果頁：梅花易數卦象（本卦／互卦／變卦） ---- */
/* 與雷諾曼九宮格同一套卡片語言：同樣的框線、底色與內陰影 */
.mh-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  max-width: 420px; margin: 0 auto 22px;
}
.mh-cell {
  position: relative; margin: 0; padding: 10px 8px 8px;
  border: 1px solid rgba(214, 183, 122, .28); border-radius: 3px;
  background: linear-gradient(180deg, rgba(10, 15, 24, .82), rgba(8, 12, 20, .9));
  box-shadow: inset 0 0 20px rgba(0, 0, 0, .5), 0 0 12px rgba(214, 183, 122, .05);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.mh-role {
  font-family: var(--sans); font-size: 10.5px; letter-spacing: .18em;
  color: var(--accent-dim);
}
/* 六爻：由上而下排（DOM 已反轉，上爻在最上） */
/* 左側留白給動爻的記號，六條線本身才對齊居中 */
.mh-lines {
  display: flex; flex-direction: column; gap: 6px;
  width: 70%; padding: 0 11px; box-sizing: content-box;
}
.mh-yao { position: relative; display: block; height: 6px; border-radius: 1px; }
/* 陽爻＝整條；陰爻＝中間斷開 */
.mh-yao.yang { background: var(--accent-dim); }
.mh-yao.yin {
  background: linear-gradient(90deg,
    var(--accent-dim) 0 38%, transparent 38% 62%, var(--accent-dim) 62% 100%);
}
/* 動爻：提亮並在左側點一個記號 */
.mh-yao.moving.yang { background: var(--accent); box-shadow: 0 0 9px rgba(224, 193, 132, .5); }
.mh-yao.moving.yin {
  background: linear-gradient(90deg,
    var(--accent) 0 38%, transparent 38% 62%, var(--accent) 62% 100%);
  box-shadow: 0 0 9px rgba(224, 193, 132, .35);
}
.mh-yao.moving::before {
  content: ''; position: absolute; top: 50%; left: -11px;
  width: 4px; height: 4px; margin-top: -2px;
  border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 6px rgba(224, 193, 132, .8);
}
.mh-name {
  font-family: var(--serif); font-size: 12.5px; line-height: 1.4;
  color: var(--ink-dim); text-align: center;
}
@media (max-width: 420px) {
  .mh-cell { padding: 8px 5px 6px; }
  .mh-name { font-size: 11.5px; }
  .mh-role { font-size: 9.5px; letter-spacing: .1em; }
}

/* ---- 結果頁：本命盤星盤輪 ---- */
/* 與雷諾曼牌卡、梅花卦象卡同一套語言：同樣的框線、底色與內陰影 */
.cw-wrap { margin: 0 auto 22px; max-width: 460px; }
.cw-canvas {
  position: relative; padding: 10px;
  border: 1px solid rgba(214, 183, 122, .28); border-radius: 3px;
  background: linear-gradient(180deg, rgba(10, 15, 24, .82), rgba(8, 12, 20, .9));
  box-shadow: inset 0 0 26px rgba(0, 0, 0, .5), 0 0 12px rgba(214, 183, 122, .05);
  /* 整塊是可點的（開啟放大檢視），所以要看得出來 */
  cursor: zoom-in; transition: border-color .2s, box-shadow .2s;
}
.cw-canvas:hover, .cw-canvas:focus-visible {
  border-color: var(--accent-dim);
  box-shadow: inset 0 0 26px rgba(0, 0, 0, .5), 0 0 16px rgba(214, 183, 122, .16);
}
.cw-canvas:focus-visible { outline: 1px solid var(--accent-dim); outline-offset: 2px; }
.cw-canvas svg { display: block; width: 100%; height: auto; overflow: visible; }
/* 右上角的放大鏡：靜態的可點提示，不必等使用者去猜 */
.cw-zoom-badge {
  position: absolute; top: 8px; right: 8px;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid rgba(214, 183, 122, .38);
  background: rgba(8, 12, 20, .82);
}
.cw-zoom-badge svg {
  width: 15px; height: 15px; fill: none;
  stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round;
}
.cw-hint {
  margin: 8px 0 0; font-family: var(--sans); font-size: 11.5px;
  color: var(--ink-faint); text-align: center; letter-spacing: .02em;
}

/* 盤上方那一行出生資料：使用者要能核對，所以不能太暗到看不見；
   但它是身分標示、不是內容，所以比內文小一級、用 sans、不加框。
   數字用 tabular-nums，日期時間對齊起來才像檔案標籤而不像句子。 */
/* 用 .cw-wrap 前綴不是為了好看，是為了權重：`.r-block p` 是 (0,1,1)，
   單寫 `.cw-birth` 只有 (0,1,0) 會被它蓋成 16px。目前星盤是 .r-block 的
   兄弟節點所以碰不到，但這行的字級不該取決於將來有沒有人把它搬進去。 */
.cw-wrap .cw-birth {
  margin: 0 0 8px; font-family: var(--sans); font-size: 12.5px;
  color: var(--ink-dim); text-align: center; letter-spacing: .03em;
  font-variant-numeric: tabular-nums; white-space: normal;
}
.cw-wrap .cw-birth-k {
  margin-right: .5em; color: var(--ink-faint);
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
}

/* 環線與刻度 */
.cw-ring { fill: none; stroke: rgba(214, 183, 122, .26); stroke-width: 1; }
.cw-cusp { stroke: rgba(214, 183, 122, .16); stroke-width: 1; }
.cw-axis { stroke: rgba(224, 193, 132, .5); stroke-width: 1.4; }
/* 1°／5°／10° 度數刻度：越粗的節點越亮，才數得出度數 */
.cw-g1 { stroke: rgba(214, 183, 122, .2); stroke-width: .5; }
.cw-g5 { stroke: rgba(214, 183, 122, .32); stroke-width: .6; }
.cw-g10 { stroke: rgba(214, 183, 122, .46); stroke-width: .8; }
/* 行星的真實度數刻度與指示線：符號可以被推開，度數不會 */
.cw-btick { stroke: rgba(224, 193, 132, .62); stroke-width: 1.1; }
.cw-lead { stroke: rgba(224, 193, 132, .32); stroke-width: .7; }

/* 相位線。tone 決定顏色（暖＝和諧、冷＝張力、key＝合相），
   粗細與虛實由 major/aux/weak 疊上去；逐條的透明度由 SVG 的 style 給。 */
.cw-asp { stroke-linecap: round; }
.cw-asp-warm { stroke: var(--accent-dim); }
.cw-asp-cool { stroke: #9fb4cf; }
.cw-asp-key { stroke: #e6c98a; }
.cw-asp-major { stroke-width: 1.1; }
.cw-asp-major.cw-asp-weak { stroke-width: .7; }
.cw-asp-aux { stroke-width: .6; }
/* 次要相位預設收起：一次看七十條線讀不出結構。開關就在圖例裡。 */
.cw-wrap:not(.show-aux) .cw-asp-aux { display: none; }

.cw-sign, .cw-planet, .cw-house, .cw-deg, .cw-cusp-deg {
  text-anchor: middle; dominant-baseline: central;
  font-family: var(--symbol);
  /* 與 JS 附加的 U+FE0E 同一個目的：要文字形，不要彩色 emoji。
     支援這個屬性的瀏覽器不多，所以兩道保險並用。 */
  font-variant-emoji: text;
}
.cw-sign { font-size: 17px; fill: var(--accent-dim); }
.cw-planet { font-size: 20px; fill: var(--accent); }
/* 小行星、交點、莉莉絲、福點、Vertex：畫，但不搶主星的視覺重量 */
.cw-planet.cw-minor-body { font-size: 16px; fill: rgba(214, 183, 122, .72); }
/* 退回拉丁縮寫時字要小一點，才塞得進同一個位置 */
.cw-planet.cw-abbr { font-size: 12px; letter-spacing: .02em; }
.cw-planet.cw-abbr.cw-minor-body { font-size: 10.5px; }
.cw-house { font-size: 11px; fill: var(--ink-faint); }
/* 沿半徑書寫的度數：起點就是錨點，所以基線要中線對齊 */
.cw-deg, .cw-cusp-deg { dominant-baseline: middle; }
.cw-deg { font-size: 9px; fill: rgba(224, 193, 132, .78); letter-spacing: .01em; }
/* 逆行的度數換色標出來。用的是相位線那組藍灰，不另外引入第三種色調 */
.cw-deg.retro { fill: #a9b6cd; }
.cw-cusp-deg { font-size: 8.5px; fill: rgba(214, 183, 122, .42); }
.cw-cusp-deg.strong { fill: rgba(224, 193, 132, .72); }

/* 相位圖例 */
.cw-legend-box { margin-top: 12px; }
.cw-legend {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 5px 7px; justify-content: center;
}
.cw-legend.aux { margin-top: 7px; }
.cw-wrap:not(.show-aux) .cw-legend.aux { display: none; }
.cw-lg-item {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px; border-radius: 2px;
  border: 1px solid var(--line); background: rgba(10, 15, 24, .5);
  font-family: var(--sans); font-size: 11px; color: var(--ink-dim);
}
.cw-lg-item.aux { opacity: .8; }
.cw-lg-mark {
  font-family: var(--symbol); font-size: 13px; line-height: 1;
  font-variant-emoji: text;
}
.cw-lg-mark.abbr { font-size: 10px; letter-spacing: .02em; }
.cw-lg-warm .cw-lg-mark { color: var(--accent-dim); }
.cw-lg-cool .cw-lg-mark { color: #9fb4cf; }
.cw-lg-key .cw-lg-mark { color: #e6c98a; }
.cw-lg-n { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.cw-toggle {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 9px; cursor: pointer;
  font-family: var(--sans); font-size: 11.5px; color: var(--ink-faint);
}
.cw-toggle input { accent-color: var(--accent-dim); }
.cw-toggle-n {
  margin-left: 5px; padding: 0 5px; border-radius: 8px;
  border: 1px solid var(--line); font-variant-numeric: tabular-nums;
}
.cw-note {
  margin-top: 12px; padding: 0 4px;
  font-family: var(--sans); font-size: 12px; line-height: 1.75;
  color: var(--ink-faint); text-align: center; text-wrap: balance;
}

/* ---- 星盤輪的放大檢視（js/chartZoom.js）---- */
body.cz-open { overflow: hidden; }
.cz-overlay {
  position: fixed; inset: 0; z-index: 90;
  display: flex; flex-direction: column;
  /* 必須是全不透明：留 4% 透明度時，底下結果頁的圖例與文字會透上來，
     疊在放大的盤面上完全讀不出是什麼（實測踩到）。 */
  background: #04070c;
  animation: fadein-soft .18s ease both;
}
.cz-bar {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--line);
}
.cz-title {
  font-family: var(--serif); font-size: 13px; color: var(--ink-dim);
  letter-spacing: .04em;
}
.cz-stage {
  flex: 1 1 auto; overflow: hidden; position: relative;
  display: grid; place-items: center;
  /* 手勢要自己處理，不能讓瀏覽器先把觸控事件吃掉去滾頁面 */
  touch-action: none; -webkit-user-select: none; user-select: none;
  cursor: grab;
}
.cz-overlay.zoomed .cz-stage { cursor: grab; }
.cz-inner {
  width: min(96vw, 96vh, 720px);
  transform-origin: 50% 50%;
  will-change: transform;
}
.cz-inner svg { display: block; width: 100%; height: auto; overflow: visible; }
/* SVG 外面那層是 .cw-wrap（次要相位的顯示靠它決定），把它的版面設定歸零 */
.cz-fig { max-width: none; margin: 0; }
.cz-hint {
  position: absolute; left: 50%; bottom: 84px; transform: translateX(-50%);
  margin: 0; padding: 8px 14px; border-radius: 3px; max-width: 88vw;
  border: 1px solid rgba(214, 183, 122, .3); background: rgba(8, 12, 20, .92);
  font-family: var(--sans); font-size: 12px; line-height: 1.6;
  color: var(--ink-dim); text-align: center;
  transition: opacity .6s;
}
.cz-hint.gone { opacity: 0; pointer-events: none; }
.cz-tools {
  flex: none; display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px; border-top: 1px solid var(--line);
}
.cz-readout {
  min-width: 46px; text-align: center;
  font-family: var(--sans); font-size: 12px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.cz-btn {
  min-width: 44px; min-height: 40px; padding: 0 12px;
  border: 1px solid rgba(214, 183, 122, .38); border-radius: 3px;
  background: rgba(224, 193, 132, .07);
  font-family: var(--sans); font-size: 14px; color: var(--accent);
  cursor: pointer; transition: background .18s, border-color .18s;
}
.cz-btn:hover { background: rgba(224, 193, 132, .18); border-color: var(--accent); }
.cz-btn:active { background: rgba(224, 193, 132, .26); }
.cz-btn.cz-reset { font-size: 12.5px; }
.cz-aux {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-family: var(--sans); font-size: 11.5px; color: var(--ink-faint);
}
.cz-aux input { accent-color: var(--accent-dim); }
@media (max-width: 420px) {
  /* 工具列在窄螢幕上會擠成兩行，提示語要讓開，不然會被壓住 */
  .cz-tools { flex-wrap: wrap; gap: 6px; }
  .cz-hint { bottom: 96px; font-size: 11.5px; }
  .cz-aux { flex-basis: 100%; justify-content: center; }
}

/* ---- 贊助創作者（結果頁結尾、靈感卡完成頁、回饋視窗共用同一列） ----
   兩顆直排：Stripe 刷卡在上（開發者實拿較多，見 js/app.js 的 sponsorRowHtml）、
   BMC 在下。直排而不是並排——這兩顆是同一件事的兩條路，並排會看起來像
   要使用者比較、選一個「對的」。
   舊的 .bmc-btn 亮黃樣式一併移除：它其實從來沒有生效（被後面的 .btn 蓋掉，
   見 git 歷史裡 .oc-donate-btn 旁的註記），而現在兩顆都該用站上一致的按鈕樣。 */
.r-sponsor {
  margin-top: 10px; padding: 34px 20px 40px; text-align: center;
  border-top: 1px solid var(--line);
}
/* 兩顆贊助鈕上面那一句（站主回報這裡漏了）。與彈出視窗共用同一組輪替句，
   而且同一則解讀抽到的是同一句（見 js/app.js 的 sponsorLede）。
   欄寬 21em 跟按鈕的 max-width 300px 差不多齊，看起來是同一組東西。
   斷行規則見上面「短文案的斷行」那一段。 */
.r-sponsor-lede {
  font-family: var(--sans); font-size: 13px; line-height: 1.8;
  color: var(--ink-dim); letter-spacing: .02em;
  margin: 0 auto 18px; max-width: 21em;
}
.sp-row { display: flex; flex-direction: column; gap: 10px; align-items: center; }
.sp-btn { width: 100%; max-width: 300px; }

/* ---- 結果頁：雷諾曼九宮格牌卡（星座圖案） ---- */
.lenormand-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  max-width: 420px; margin: 0 auto 22px;
}
.lg-cell {
  position: relative; aspect-ratio: 3 / 4; padding: 6px 4px;
  border: 1px solid rgba(214, 183, 122, .28); border-radius: 3px;
  background: linear-gradient(180deg, rgba(10, 15, 24, .82), rgba(8, 12, 20, .9));
  box-shadow: inset 0 0 20px rgba(0, 0, 0, .5), 0 0 12px rgba(214, 183, 122, .05);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  overflow: hidden;
}
.lg-cell::before { /* 牌面內框 */
  content: ''; position: absolute; inset: 4px;
  border: 1px solid rgba(214, 183, 122, .12); border-radius: 2px; pointer-events: none;
}
.lg-pos {
  position: absolute; top: 5px; left: 8px;
  font-size: 10px; color: var(--accent-dim); font-family: Georgia, serif; opacity: .8;
}
.lg-ico { width: 78%; margin: 2px auto 4px; }
.cst { width: 100%; height: auto; display: block; overflow: visible; }
.cst-lines line { stroke: rgba(214, 183, 122, .5); stroke-width: 0.9; }
.cst-stars circle { fill: #f0dca6; }
.lg-name {
  font-family: var(--serif); font-size: 12.5px; color: var(--ink-dim);
  letter-spacing: .12em; text-align: center;
}
@media (max-width: 420px) {
  .lg-name { font-size: 11.5px; }
  .lenormand-grid { gap: 6px; }
}

/* ---- 牌義小詞典（九宮格下方，預設收合）----
   純前台顯示：只讀已抽出的九張牌，依 card.id 查 data/lenormandGloss.js 的固定詞點。

   ⚠ 站主 2026-09 實測回報三件事，這一版全部處理：
   ① 展開鈕幾乎看不見 → summary 整條做成可點的橫條（自帶面板底），右邊的 ＋／－
      改成有外框的圓鈕，而不是一個淡淡的符號。
   ② 展開後文字直接壓在星圖上，讀起來很吃力 → 內容套用與解讀正文同一組面板
      變數（--panel-bg／--panel-blur／--panel-line），跟 .as-seg、.lg-para 同一套。
   ③ 字太小 → 牌名 14px、詞點 13.5px（解讀正文是 16px，這裡是輔助資訊，略小一級
      但不再是註記級的 11px）。

   ⚠ 牌名一欄、詞點一欄（站主指定）：詞點換行時對齊自己那一欄，不會繞到牌名底下。
   牌名欄用 auto 寬度而不是固定值——「書」與「Crossroads」差很多，固定值一定有一邊不對。 */
.gloss { max-width: 420px; margin: 0 auto 22px; }
.gloss > summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 12px; cursor: pointer; list-style: none;
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur); -webkit-backdrop-filter: var(--panel-blur);
  border: 1px solid var(--panel-line); border-radius: 3px;
}
.gloss > summary::-webkit-details-marker { display: none; }
.gloss[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.gloss > summary::after {
  content: '＋'; margin-left: auto; flex-shrink: 0;
  width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1; color: var(--accent);
  border: 1px solid var(--line-strong); border-radius: 50%;
}
.gloss[open] > summary::after { content: '－'; }
.gloss > summary:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.gloss-t {
  font-family: var(--serif); font-size: 14px; font-weight: 400;
  color: var(--accent); letter-spacing: .16em;
}
.gloss-hint {
  font-family: var(--sans); font-size: 12px; font-weight: 400;
  color: var(--ink-faint); letter-spacing: .02em;
}
.gloss-list {
  display: grid; grid-template-columns: auto 1fr; gap: 11px 14px;
  margin: 0; padding: 16px 14px 18px; align-items: baseline;
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur); -webkit-backdrop-filter: var(--panel-blur);
  border: 1px solid var(--panel-line); border-top: 0;
  border-radius: 0 0 3px 3px;
}
.gloss-list dt {
  font-family: var(--serif); font-size: 14px; color: var(--ink-dim);
  letter-spacing: .08em; white-space: nowrap;
}
.gloss-list dd {
  margin: 0; font-family: var(--sans); font-size: 13.5px;
  color: var(--ink-dim); line-height: 1.75;
}
@media (max-width: 420px) {
  .gloss-list { gap: 10px 11px; padding: 14px 12px 16px; }
  .gloss-list dt { font-size: 13px; }
  .gloss-list dd { font-size: 12.5px; }
}

/* 章節前的對照小牌卡 */
/* ---- 結果頁：分節解析 ---- */
.r-section { margin-bottom: 30px; }
.r-sec-head {
  display: flex; align-items: center; gap: 12px;
  font-size: 12.5px; font-weight: 500; letter-spacing: .28em;
  color: var(--accent); font-family: var(--sans); margin-bottom: 14px;
}
.r-sec-head::before {
  content: ''; width: 6px; height: 6px; flex-shrink: 0;
  border: 1px solid var(--accent-dim); transform: rotate(45deg);
}
.r-sec-head::after { content: ''; flex: 1; border-top: 1px solid var(--line); }

/* 按鈕：柔光金線（hover 光暈增強），主要鈕為發光的暖金面 */
.btn {
  font: inherit; font-size: 14px; letter-spacing: .24em; text-indent: .24em;
  color: var(--ink-dim);
  background: rgba(13, 20, 31, .42);
  border: 1px solid rgba(214, 183, 122, .34); border-radius: 3px;
  padding: 12px 34px; cursor: pointer;
  box-shadow: 0 0 12px rgba(214, 183, 122, .07);
  transition: color .35s, border-color .35s, background .35s, box-shadow .45s;
}
.btn:hover:not(:disabled) {
  color: var(--ink); border-color: rgba(226, 198, 138, .7);
  box-shadow: 0 0 20px rgba(220, 190, 130, .22);
}
.btn.primary {
  color: #171207;
  background: linear-gradient(180deg, #e0c384 0%, #c8aa66 60%, #b3945a 100%);
  border-color: #ecd7a0;
  box-shadow: 0 0 22px rgba(224, 195, 132, .32), inset 0 1px 0 rgba(255, 245, 216, .45);
}
.btn.primary:hover:not(:disabled) {
  background: linear-gradient(180deg, #ecd194 0%, #d4b672 60%, #bd9e62 100%);
  color: #171207;
  box-shadow: 0 0 30px rgba(228, 200, 138, .45), inset 0 1px 0 rgba(255, 245, 216, .5);
}
.btn.primary:disabled { opacity: .35; cursor: default; box-shadow: none; }

/* 次要按鈕：原本把框線、底色、陰影全部拿掉，結果只剩淡字浮在星圖上，
   使用者看不出可以點。改為保留金邊與暗色底，只是比主要按鈕收斂——
   三個層級才分得開：primary（填滿）> .btn（一般）> .ghost（淡金邊）。
   刻意不用虛線邊：本站的虛線框是「COMING SOON」的語言，會被讀成不能點。 */
/* 底色壓得比一般按鈕更暗：這些鈕會落在星圖最亮的區域，
   邊框太淡就融進背景（錯誤頁實測過），寧可暗一點也要看得出是個框。 */
.btn.ghost {
  color: var(--ink-dim);
  background: rgba(9, 14, 23, .62);
  border-color: rgba(214, 183, 122, .34);
  box-shadow: 0 0 10px rgba(214, 183, 122, .05);
}
.btn.ghost:hover:not(:disabled) {
  color: var(--ink); border-color: rgba(226, 198, 138, .58);
  box-shadow: 0 0 16px rgba(220, 190, 130, .16);
}
/* 手機沒有 hover，按下去要看得到反應 */
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn.ghost:active:not(:disabled) {
  color: var(--ink); border-color: rgba(226, 198, 138, .7);
  background: rgba(20, 30, 45, .7);
}

.fineprint {
  margin-top: 40px; font-size: 13.5px; color: var(--ink-dim);
  font-family: var(--sans); line-height: 1.9;
}

.care { padding-top: max(16vh, var(--sky-text)); }
.care-title { font-family: var(--serif); font-size: 24px; letter-spacing: .1em; margin-bottom: 24px; }
.care .btn { margin-top: 28px; }

/* ---- 雷諾曼：36 張牌池選牌（銅版雕刻牌背） ---- */
.pick-count {
  font-size: 12px; color: var(--accent-dim); letter-spacing: .3em; text-indent: .3em;
  margin-bottom: 18px; font-family: var(--sans);
}
.deck-grid {
  display: grid; grid-template-columns: repeat(9, 1fr); gap: 8px;
  max-width: 560px; margin: 0 auto 36px;
}
.deck-card {
  aspect-ratio: 5 / 7; border-radius: 0; cursor: pointer;
  border: 1px solid var(--line-strong);
  background:
    radial-gradient(circle at 5px 5px, rgba(194, 168, 105, .55) 0 .9px, transparent 1.6px),
    radial-gradient(circle at calc(100% - 5px) 5px, rgba(194, 168, 105, .55) 0 .9px, transparent 1.6px),
    radial-gradient(circle at 5px calc(100% - 5px), rgba(194, 168, 105, .55) 0 .9px, transparent 1.6px),
    radial-gradient(circle at calc(100% - 5px) calc(100% - 5px), rgba(194, 168, 105, .55) 0 .9px, transparent 1.6px),
    radial-gradient(circle at 50% 42%, rgba(194, 168, 105, .12), transparent 62%),
    var(--bg-soft);
  position: relative; transition: transform .2s, border-color .3s, opacity .4s;
}
.deck-card::before {
  content: ''; position: absolute; inset: 3px;
  border: 1px solid var(--line); pointer-events: none;
}
.deck-card::after {
  content: '✶'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--accent-dim); font-size: 11px; opacity: .7;
}
.deck-card:hover:not(.sel) { transform: translateY(-3px); border-color: var(--accent-dim); }
.deck-card.sel {
  border-color: #e3c98d; transform: translateY(-3px);
  box-shadow: 0 0 0 1px rgba(227, 201, 141, .75), 0 0 16px rgba(224, 195, 132, .4),
    inset 0 0 12px rgba(224, 195, 132, .16);
}
.deck-card.sel::after { color: #f0dca6; opacity: 1; text-shadow: 0 0 8px rgba(240, 220, 166, .8); }

/* ---- 占卜 ---- */
.spread, .numbers { text-align: center; padding-top: max(7vh, var(--sky-text)); }
.divine-lede {
  font-family: var(--serif); font-size: 16px; color: var(--ink-dim);
  margin-bottom: 40px;
}
.divine-actions { margin-top: 40px; display: flex; justify-content: center; gap: 14px; flex-wrap: wrap; }

/* 已帶入上次出生資料的提示（可一鍵改用其他資料） */
.astro-saved {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 6px 12px; margin: 0 auto 14px; max-width: 30em;
  font-family: var(--sans); font-size: 12.5px; color: var(--accent);
}
.astro-saved::before { content: '✓'; opacity: .85; }
/* display:flex 會蓋掉 hidden 屬性，這行讓沒存過資料時真的不顯示 */
.astro-saved[hidden] { display: none; }
.link-btn {
  font: inherit; color: var(--ink-dim); background: none;
  border: none; border-bottom: 1px solid var(--line);
  padding: 0 1px 1px; cursor: pointer; transition: color .2s, border-color .2s;
}
.link-btn:hover { color: var(--ink); border-color: var(--accent-dim); }

/* ---- 占星出生資料：毛玻璃登錄卡 ---- */
.astro-form {
  max-width: 400px; margin: 0 auto; text-align: left; position: relative;
  padding: 22px 20px 8px; border: 1px solid rgba(214, 183, 122, .28);
  border-radius: 3px;
  background: rgba(13, 20, 31, .55);
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  box-shadow: 0 0 22px rgba(214, 183, 122, .08), 0 10px 34px rgba(0, 0, 0, .4);
}
.af-row { margin-bottom: 16px; }
.af-row > label:not(.flt-chk) {
  display: flex; align-items: center; gap: 12px;
  font-size: 11px; color: var(--accent-dim); margin-bottom: 8px;
  font-family: var(--sans); letter-spacing: .26em;
}
.af-row > label:not(.flt-chk)::after { content: ''; flex: 1; border-top: 1px solid var(--line); }
/* ⚠ 16px 是下限，不要調小。iOS Safari 一點進 font-size < 16px 的輸入框就會把整頁
   放大 16÷字級 倍，而且失焦之後不會縮回去——整個網站從此往右偏，直到使用者自己
   捏回來。原本是 15px，站主回報的「整頁往右偏」量出來剛好是 1.0665 倍（16/15）。
   詳見本檔最下方「iOS 自動放大」那一段。 */
.af-row input[type="date"], .af-row input[type="time"], .af-row input[type="text"] {
  width: 100%; font: inherit; font-size: 16px;
  background: linear-gradient(180deg, rgba(17, 24, 38, .9), rgba(12, 18, 28, .9));
  color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 0; padding: 11px 14px;
  box-shadow: inset 0 0 14px rgba(0, 0, 0, .3);
  color-scheme: dark;
}
.af-row input::placeholder { color: var(--ink-faint); opacity: .45; }
.af-row input:focus { outline: none; border-color: var(--accent-dim); }
.af-check { padding-top: 2px; }

/* 勾選框＝黃銅鉚釘：方形細框，選取時中央亮起銅點 */
input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 16px; height: 16px; flex-shrink: 0;
  border: 1px solid var(--accent-dim); border-radius: 0;
  background: rgba(11, 16, 23, .5); cursor: pointer;
  transition: background .25s, box-shadow .25s;
  vertical-align: middle;
}
input[type="checkbox"]:checked {
  background:
    radial-gradient(circle at 50% 50%, var(--accent) 0 3.2px, rgba(194, 168, 105, .25) 3.8px, transparent 5.5px);
  box-shadow: inset 0 0 0 1px var(--line);
}
input[type="checkbox"]:indeterminate {
  background: linear-gradient(var(--accent), var(--accent)) center / 8px 1.5px no-repeat;
}
input[type="checkbox"]:hover { border-color: var(--accent); }

/* 下拉選單：去原生外觀，黃銅箭頭 */
select.flt-select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' stroke='%238a774d' fill='none'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
  padding-right: 30px;
}

/* 城市／國家搜尋下拉（combobox） */
.combo { position: relative; }
.combo-list {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 30;
  max-height: 248px; overflow-y: auto;
  background: #0e1520; border: 1px solid var(--line-strong);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .5);
}
.combo-list[hidden] { display: none; }
.combo-item {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  padding: 9px 14px; font-size: 14px; color: var(--ink-dim);
  cursor: pointer; font-family: var(--sans);
}
.combo-item:hover { background: rgba(194, 168, 105, .08); color: var(--ink); }
.combo-item small { color: var(--ink-faint); font-size: 12px; }
.combo-empty { padding: 9px 14px; font-size: 13px; color: var(--ink-faint); font-family: var(--sans); }
.combo-picked { margin-top: 6px; font-size: 12px; color: var(--accent-dim); min-height: 1.5em; font-family: var(--sans); }

.num-row { display: flex; justify-content: center; gap: 16px; }

/* 報數格＝儀器讀數窗：金屬凹面＋底部刻度尺。
   改為滑動選取後仍是同一個外觀，只是內容變成可捲動的數字帶。
   高度＝3 格（1 個選中 + 上下各露一格），讓人一眼看出「這是可以撥的」。
   外框與中央標示帶做在 .num-cell 上，捲動只發生在裡面的 .num-pick。 */
.num-cell {
  position: relative; width: 92px; height: 138px;
  background:
    repeating-linear-gradient(90deg, rgba(194, 168, 105, .35) 0 1px, transparent 1px 9px) bottom / 100% 5px no-repeat,
    linear-gradient(180deg, rgba(17, 24, 38, .92), rgba(12, 18, 28, .92));
  border: 1px solid var(--line-strong); border-radius: 0;
  box-shadow: inset 0 0 16px rgba(0, 0, 0, .4);
}
.num-pick {
  width: 100%; height: 100%;
  overflow-y: scroll;
  /* 這兩行是必要的，不是保險：
     ① CSS 規定只設 overflow-y 時，overflow-x 會從 visible 變成 auto。
        而 .np-opt.on 的 scale(1.06) 會把選中那格撐得比容器寬 —— 兩件事加起來，
        使用者就能把數字左右拖走。這裡明確關掉橫向捲動。
     ② touch-action: pan-y 讓瀏覽器把斜向的手勢解讀成純垂直，
        不然手指稍微斜一點（斜上／斜下）就會同時帶動橫向。 */
  overflow-x: hidden;
  touch-action: pan-y;
  overscroll-behavior: contain;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  cursor: grab;
}
.num-pick::-webkit-scrollbar { display: none; }
.num-pick:focus-visible { outline: 1px solid var(--accent-dim); outline-offset: -2px; }
/* 上下留白：讓第一格與最後一格也能捲到正中央（46px 格高、138px 視窗） */
.np-track { padding: 46px 0; }
.np-opt {
  display: block; width: 100%; height: 46px;
  scroll-snap-align: center;
  font: inherit; font-family: var(--serif); font-size: 26px; line-height: 46px;
  color: var(--ink-faint); background: none; border: none; padding: 0;
  cursor: pointer;
  transition: color .2s, opacity .2s, font-size .2s;
  opacity: .45;
}
/* 選中的那一格才是亮的；其餘壓暗，視覺上自然指向中央。
   放大用 font-size 而不是 transform: scale()——scale 會把整個區塊撐得比容器寬，
   讓捲動容器產生橫向溢出（就是「數字可以左右拖走」那個問題的根源）。
   改字級的視覺效果一樣，但版面寬度完全不變。 */
.np-opt.on { color: var(--accent); opacity: 1; font-size: 27.6px; }
.np-blank { color: var(--ink-faint); }
/* 中央的兩條髮絲線：標出「這一格才是你選的」。
   放在 .num-cell 裡、.num-pick 外，才不會跟著內容捲走。 */
.np-band {
  position: absolute; left: 0; right: 0; top: 50%; height: 46px;
  transform: translateY(-50%); pointer-events: none;
  border-top: 1px solid rgba(214, 183, 122, .34);
  border-bottom: 1px solid rgba(214, 183, 122, .34);
  background: rgba(214, 183, 122, .045);
}
.num-picked {
  margin-top: 18px; min-height: 1.8em;
  font-family: var(--serif); font-size: 15px; color: var(--accent); letter-spacing: .1em;
}
@media (max-width: 400px) {
  .num-row { gap: 10px; }
  .num-cell { width: 82px; }
}

/* ---- 分析中：星軌（三層軌道繞著文字運行） ---- */
/* 下方多了階段進度與輪播提示，上緣留白收窄才放得進一個螢幕 */
.weaving { text-align: center; padding-top: max(8vh, var(--sky-text)); padding-bottom: 40px; color: var(--ink-dim); font-family: var(--serif); font-size: 16px; }
/* ---- 分析中：整個視覺垂直居中於「使用者現在真正看得到的高度」 ----------------
   站主回報「整體有點偏上、下面很空」「轉圈圈畫面整體太高了，希望降下來一點」。
   成因是這一頁沒有在排版上被居中：.weaving 從 padding-top: 8vh 起排，排完就結束，
   剩下的空間全部留在下面。實測 390×844 上內容上緣離頂 70px、底下空 349px，
   中心比視窗中心高了 140px——手機越高就越明顯。

   ⚠ 用 **dvh** 而不是 vh，也不用 JS 去量 innerHeight：
   ・dvh 就是「使用者此刻真正看得到的高度」，行動版瀏覽器的網址列與底部工具列
     收起／展開時它會跟著變。vh 永遠算的是工具列收起後的**最大**高度，所以拿 vh
     居中，在工具列還露著的時候仍然會偏上——那正是站主截圖裡的狀況。
   ・JS 量 innerHeight 做的是同一件事，但要自己聽 resize／orientationchange，
     還多一次 reflow，而且捲動中網址列縮放時會抖。瀏覽器原生的單位已經處理好了。

   safe center：內容比可視高度還高時（小螢幕、大字級、四行的階段文字）退回從頂端
   排，不會把上緣切掉捲不到。舊瀏覽器解析不了整條就退回 flex-start，也是同一個結果。

   上下內距對稱：.screen 本來是 padding: 0 22px 60px，那 60px 會讓「內容盒的中心」
   比視窗中心低 30px，居中就不是真的居中了。

   ⚠ 只作用在 #screenWeaving。牌卡視窗裡的等待畫面共用 .weaving 這個 class，
   但它自己已經是全版置中的（見 .ocm.ocm-busy），套進去會打架。 */
#screenWeaving.active {
  display: flex;
  flex-direction: column;
  justify-content: safe center;
  min-height: 100vh;
  min-height: 100dvh;
  padding-top: 24px;
  padding-bottom: 24px;
}
#screenWeaving .weaving { padding-top: 0; padding-bottom: 0; width: 100%; }

/* ---- 分析中：錨在背景星圖那圈金色造型的下方 --------------------------------
   站主回報兩次：「轉圈圈壓在背景最上方那個金色圈圈上，應該在它下方一些」。
   上面那段居中處理的是「整體偏上、下面很空」，但居中的基準是視窗，不是背景圖，
   所以星軌還是會壓在造型上。淨空線的算法與量測見檔案開頭的 --sky-clear。

   2026-09 第二次回報時查出來的真正成因，記在這裡免得又繞一次遠路：
   ① .app 的 min-height 只有 100vh。iOS Safari 的 vh 是網址列收起來的大視窗高，
      網址列還在時整頁憑空多出約 120px 可以捲——一捲，星軌就壓上去了（背景是
      fixed 的，不會跟著捲）。已改成 100dvh，見 .app 的註解。
   ② 原本這條規則加了 min-height: 830px，矮螢幕刻意不套用（理由是空間不夠、
      硬移會把提示卡推出畫面）。站主的要求是「都要在造型以下」，沒有例外，
      所以斷點拿掉，改成矮螢幕把星軌縮小（見 .orbit-stage 的 --orb）來擠出空間。

   ⚠ 要驗這件事，量 .orbit-stage 的 top，**不要**量圓環或 .orb-guide 的
   getBoundingClientRect：.or1/.or2/.or3 是三個方形 svg 各自在旋轉，方框的
   軸對齊 bounding box 會隨角度脹縮，實測同一個位置在 178–230px 之間擺動約 50px。
   圓環在視覺上並沒有上下跳動，那純粹是量法的假象，但足以讓人量出完全錯誤的結論。
   .orbit-stage 的 top 等於 padding-top（flex-start 的第一個子元素），是確定值。

   ⚠ 橫向視窗（bg-square.jpg）沒有這個造型，維持原本的垂直居中。 */
@media (orientation: portrait) {
  #screenWeaving.active {
    justify-content: flex-start;
    padding-top: max(24px, var(--sky-clear));
  }
}
.orbit-stage {
  position: relative; width: var(--orb); height: var(--orb); margin: 0 auto;
  display: grid; place-items: center;
  /* 星軌的邊長。三圈與三顆行星都是從這個值算出來的，所以改一個地方就整組跟著縮
     （之前是六條規則各寫死一組 px，矮螢幕要縮就得再抄一組）。
     比例沿用站主定的那一組：300 / 216 / 140（＝1 / .72 / .4667）。手機那一組
     原本寫死 250 / 182 / 122，換算過去是 250 / 180 / 117，差 2–5px 看不出來。
     --orb-max 是這個版面願意給的最大邊長，--orb 是實際用的（矮螢幕會再縮，
     見下面的 media query）。 */
  --orb-max: 300px;
  --orb: var(--orb-max);
}
.orbit-rig { position: absolute; inset: 0; display: grid; place-items: center; }
.orbit-rig svg { position: absolute; overflow: visible; }
.orb-guide { fill: none; stroke: rgba(224, 193, 132, .13); stroke-width: 1; }
.orb-arc { fill: none; stroke: var(--accent); stroke-linecap: round; }

.orb-ring { animation: orbspin linear infinite; transform-origin: 50% 50%; }
.or1 { width: var(--orb); height: var(--orb); animation-duration: 7s; }
.or2 { width: calc(var(--orb) * .72); height: calc(var(--orb) * .72); animation-duration: 4.6s; animation-name: orbspinback; }
.or3 { width: calc(var(--orb) * .4667); height: calc(var(--orb) * .4667); animation-duration: 3.1s; }
.or1 .orb-arc { stroke-width: 3; stroke-dasharray: 168 420; }
.or2 .orb-arc { stroke-width: 2.6; stroke-dasharray: 120 302; stroke: #f0dca6; }
.or3 .orb-arc { stroke-width: 2.2; stroke-dasharray: 74 200; }

/* 行星節點：獨立轉盤，把亮點推到各自軌道半徑上 */
.orb-planet { position: absolute; animation: orbspin linear infinite; transform-origin: 50% 50%; }
.orb-planet i {
  position: absolute; left: 50%; top: 0; width: 7px; height: 7px; margin-left: -3.5px;
  border-radius: 50%; background: #f0dca6;
  box-shadow: 0 0 12px 3px rgba(240, 220, 166, .6);
}
.op1 { width: var(--orb); height: var(--orb); animation-duration: 7s; }
.op2 { width: calc(var(--orb) * .72); height: calc(var(--orb) * .72); animation-duration: 4.6s; animation-name: orbspinback; }
.op3 { width: calc(var(--orb) * .4667); height: calc(var(--orb) * .4667); animation-duration: 3.1s; }
.op3 i { width: 5px; height: 5px; margin-left: -2.5px; }

.orbit-label {
  position: relative; z-index: 3;
  font-family: var(--serif); font-size: 16.5px; letter-spacing: .18em; text-indent: .18em;
  color: var(--ink-dim); text-shadow: 0 1px 6px rgba(3, 7, 13, .9);
}

@keyframes orbspin { to { transform: rotate(360deg); } }
@keyframes orbspinback { to { transform: rotate(-360deg); } }
/* 結果頁的匯聚圖光暈仍沿用此淡入淡出 */
@keyframes orbpulse { 0%, 100% { opacity: .65; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .orb-ring, .orb-planet { animation: none; }
}
@media (max-width: 420px) {
  .orbit-stage { --orb-max: 250px; }
}
/* ---- 矮螢幕：把星軌縮到剛好塞得下，而不是讓等待畫面捲出去 ------------------
   等待畫面現在一律錨在背景造型下方（見上面 #screenWeaving.active），矮螢幕不再
   有例外。代價是上緣讓掉了 var(--sky-clear)，SE（667）那種高度就塞不下原本的
   內容——但等待畫面捲動很糟：一捲，星軌就又壓回那個造型上（背景是 fixed 的）。
   所以改成讓星軌自己讓步：它是裝飾，縮小不會少掉任何資訊。

   382px ＝ 星軌以外的內容 353px（階段字 109＋提示卡 192＋兩段 26px 間距，
   四語系實測最高的那一組，見 tests/ui.test.mjs）＋ 下緣留白 24px ＋ 5px 餘裕。
   內容變高就要一起改這個數字，測試會擋下來。 */
/* ⚠ 包在 @supports 裡：不認得 dvh 的瀏覽器如果讀到這條，min() 會在計算時整條
   失效，width 就退回 auto、整個星軌垮掉。認不得就維持原本的 --orb-max。 */
@supports (height: 1dvh) {
  @media (orientation: portrait) {
    /* 下限 120px：極端視窗（桌機把視窗拉成又窄又扁的直向）算出來會是負數，
       負的寬度＝整條失效。縮到 120 還塞不下就讓它捲，那已經不是手機的情境。 */
    .orbit-stage { --orb: clamp(120px, calc(100dvh - var(--sky-clear) - 382px), var(--orb-max)); }
  }
}

/* ---- 結果頁：三系統匯聚圖（同一份底層圖樣） ---- */
.r-converge { max-width: 480px; margin: 0 auto 34px; }
.r-converge svg { width: 100%; height: auto; display: block; }
.cv-line {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: cvdraw 2.8s cubic-bezier(.4, .2, .2, 1) .4s forwards;
}
@keyframes cvdraw { to { stroke-dashoffset: 0; } }
.cv-halo { animation: orbpulse 4.5s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .cv-line { animation: none; stroke-dashoffset: 0; }
  .cv-halo { animation: none; }
}

/* ---- 結果頁：原始素材索引（弱化為文末備註；自帶毛玻璃底保住可讀性） ---- */
.r-index {
  margin: 46px auto 8px; padding: 18px 16px 14px;
  border: 1px solid rgba(214, 183, 122, .2); border-radius: 3px;
  background: rgba(13, 20, 31, .55);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  text-align: center; font-family: var(--sans); font-weight: 300;
}
.r-index-label {
  font-size: 11px; color: #bfa76f;
  letter-spacing: .38em; text-indent: .38em; margin-bottom: 8px;
}
.r-index .r-converge { max-width: 340px; margin: 0 auto 10px; opacity: .9; }
.idx-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px 10px;
  max-width: 320px; margin: 2px auto 10px;
}
.idx-cell { font-size: 13.5px; color: #cdc3a9; white-space: nowrap; }
.idx-cell i {
  font-style: normal; color: var(--accent); font-size: 11px;
  margin-right: 6px; font-family: Georgia, serif;
}
.r-index-line {
  font-size: 13.5px; color: #cdc3a9; line-height: 2;
  letter-spacing: .04em;
}
.r-index-line span {
  color: var(--accent); font-size: 11.5px;
  letter-spacing: .18em; margin-right: 10px;
}

/* ---- 結果頁：進階報告 ---- */
.r-advanced {
  margin-top: 10px; padding: 30px 20px 44px; text-align: center;
  border-top: 1px solid var(--line);
}
.r-advanced-hint {
  margin-top: 12px; font-size: 12.5px; color: var(--ink-faint); font-family: var(--sans);
}

/* ---- 結果頁：欄位五「分享給朋友＋回到首頁」＋結尾的社群 icon ----
   分享的說明句與「追蹤最新消息」的標題文案都依站主 2026-09 重排拿掉；
   社群入口改成兩顆品牌 icon（Threads／IG），與上一欄之間**不再隔線**。 */
.r-follow {
  margin-top: 10px; padding: 32px 20px 10px; text-align: center;
  border-top: 1px solid var(--line);
  display: flex; justify-content: center; gap: 14px; flex-wrap: wrap;
}
.r-social { padding: 26px 20px 46px; display: flex; justify-content: center; gap: 24px; }
.r-social-link {
  display: inline-flex; padding: 6px; color: var(--ink-dim);
  transition: color .35s;
}
.r-social-link:hover { color: var(--accent); }
.r-social-link svg { width: 25px; height: 25px; }

/* ---- 結果頁：帶去 AI 繼續聊 ---- */
.r-continue {
  margin-top: 14px; padding: 30px 20px 26px; text-align: center;
  border-top: 1px solid var(--line);
}
.r-continue-title {
  font-family: var(--serif); font-size: 17px; color: var(--ink);
  letter-spacing: .08em; margin-bottom: 10px;
}
.r-continue-hint { font-size: 13px; color: var(--ink-dim); margin-bottom: 20px; font-family: var(--sans); }
/* 「複製這則內容」夾在「想繼續聊下去？」與「選一個你慣用的 AI」之間
   （站主 2026-09 指定的順序） */
.r-copy { margin: 18px 0 22px; }
/* 三顆 AI 鈕固定同一排（站主 2026-09 指定不換行；手機版縮小，見媒體查詢） */
.ai-row { display: flex; justify-content: center; gap: 12px; flex-wrap: nowrap; }
.ai-btn { letter-spacing: .05em; text-indent: 0; text-decoration: none; display: inline-block; }
.copy-toast {
  margin-top: 16px; font-size: 12.5px; color: var(--accent);
  opacity: 0; transition: opacity .4s; min-height: 1.6em; font-family: var(--sans);
}
.copy-toast.show { opacity: 1; }

/* ---- 靈感訊息文件（展覽圖錄式排版） ---- */
.reading-wrap { padding-top: max(8vh, var(--sky-text)); }
.r-title {
  font-family: var(--serif); font-size: 26px; letter-spacing: .2em; text-indent: .2em;
  text-align: center; margin-bottom: 10px;
}
.r-sub {
  text-align: center; font-size: 12px; color: var(--ink-faint);
  letter-spacing: .3em; text-indent: .3em; margin-bottom: 40px; font-family: var(--sans);
}
/* 結果頁開頭：直接呈現使用者的主題（已不放標題句），因此比 .r-sub 再明顯一些 */

.r-topic {
  text-align: center; font-family: var(--serif);
  font-size: 18px; color: var(--ink-dim);
  letter-spacing: .14em; text-indent: .14em;
  margin-bottom: 30px; text-wrap: balance;
}

.r-block { margin-bottom: 40px; }
.r-block h3 {
  font-size: 12px; font-weight: 500; letter-spacing: .38em; text-indent: .1em;
  color: var(--accent-dim); margin-bottom: 16px; font-family: var(--sans);
  padding-bottom: 10px; border-bottom: 1px solid var(--line);
}
.r-block p { font-family: var(--serif); font-size: 16px; color: var(--ink); white-space: pre-wrap; }
/* 各節內文自帶暗色底：長頁面滾過照片亮區時仍清晰 */
.r-block.core p, .r-section .r-block p {
  font-size: 16px;
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur); -webkit-backdrop-filter: var(--panel-blur);
  border: 1px solid var(--panel-line); border-radius: 3px;
  padding: 20px 18px;
}
/* 占星：每一組配置一塊面板，內部分三層——白話標題（金色）、配置清單（淡註記）、
   分析（明體本文）。標題是一句話而不是標籤，所以不縮小、不拉字距、不加底線：
   那些是給「過去／現在／未來」這種標籤用的處理，套在句子上只會更難讀。 */
.r-section .r-block .as-seg {
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur); -webkit-backdrop-filter: var(--panel-blur);
  border: 1px solid var(--panel-line); border-radius: 3px;
  padding: 18px 18px 20px;
}
.r-section .r-block .as-seg + .as-seg { margin-top: 14px; }
/* .r-section .r-block p 會給每個段落自己一塊面板底色＋邊框；面板已經移到
   .as-seg 上，這裡把內層的重設掉（雷諾曼的 .lg-para p 做的是同一件事）。 */
.r-section .r-block .as-seg .as-head,
.r-section .r-block .as-seg .as-cfg,
.r-section .r-block .as-seg .as-body {
  background: none; border: none; padding: 0;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
/* 標題必須大於本文（16.5px）。原本 14.5px 比本文還小，層次是反的——標題比它
   引導的內文小，眼睛會先讀到本文。
   用 --serif 而不是 --sans：這個標題是一句完整的話，跟本文同一個語氣，同一套字
   靠大小與金色分層就夠了；換成無襯線會像 UI 標籤。站上其他用 --sans 的地方
   （.r-sec-head、.cw-hint）都是標籤或註記，不是句子。 */
.r-section .r-block .as-seg .as-head {
  font-family: var(--serif); font-size: 18px; letter-spacing: .02em;
  color: var(--accent); margin: 0 0 10px; line-height: 1.7;
}
/* 配置行也走金色（站主指定）。用 --accent-dim 而不是 --accent：同一個色系，
   比標題深一階，兩行都是金的時候還看得出哪一行是標題。 */
.r-section .r-block .as-seg .as-cfg {
  font-family: var(--sans); font-size: 13.5px; letter-spacing: .02em;
  color: var(--accent-dim); margin: 0 0 15px; line-height: 1.85;
}
.r-section .r-block .as-seg .as-body {
  font-family: var(--serif); font-size: 16.5px; color: var(--ink);
  line-height: 1.95; margin: 0;
}
.r-section .r-block .as-seg .as-body + .as-body { margin-top: 1.1em; }

/* 收束段（整體意義）＝條列筆記。前面各段是長段落，這裡換成清單，讀者才有
   「最後快速看過一遍」的節奏，也知道報告要結束了。
   ・不用 list-style：預設的圓點在深色底上太重，改用金色小菱形對齊站上的 ◇ 語彙
   ・字級比本文小半級、行距收緊：它是筆記大綱，不是要細讀的段落
   ・整段左側一條金線，與雷諾曼收束段（.lg-close）同一個手法 */
.r-section .r-block .as-seg.as-close { border-left: 2px solid var(--accent-dim); }
.r-section .r-block .as-list {
  margin: 0; padding: 0; list-style: none;
  font-family: var(--serif); font-size: 16px; color: var(--ink);
}
.r-section .r-block .as-list li {
  position: relative; padding-left: 1.15em; line-height: 1.72;
}
.r-section .r-block .as-list li + li { margin-top: .55em; }
.r-section .r-block .as-list li::before {
  content: '◇'; position: absolute; left: 0; top: 0;
  color: var(--accent-dim); font-size: 11px; line-height: 2.5;
}

/* 梅花易數：卦象提點卡。整節的引言——置中、比本文大半級、上下細金線做出
   「籤」的儀式感。用暗色玻璃面板（與 .as-seg 同一組底色），不引入新視覺系統。 */
.r-section .r-block .mh-tip {
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur); -webkit-backdrop-filter: var(--panel-blur);
  border: 1px solid var(--panel-line); border-radius: 3px;
  border-top: 1px solid rgba(214, 183, 122, .4);
  border-bottom: 1px solid rgba(214, 183, 122, .4);
  padding: 20px 20px 22px; margin-bottom: 14px; text-align: center;
}
.r-section .r-block .mh-tip .mh-tip-label,
.r-section .r-block .mh-tip .mh-tip-text {
  background: none; border: none; padding: 0;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
.r-section .r-block .mh-tip .mh-tip-label {
  font-family: var(--sans); font-size: 12px; letter-spacing: .3em; text-indent: .3em;
  color: var(--accent-dim); margin: 0 0 12px;
}
.r-section .r-block .mh-tip .mh-tip-text {
  font-family: var(--serif); font-size: 17px; line-height: 1.9;
  color: var(--ink); margin: 0; text-wrap: balance;
}
.r-section .r-block .mh-tip .mh-tip-text + .mh-tip-text { margin-top: .9em; }

/* 雷諾曼：對照牌卡＋該段文字包在同一塊暗色面板，牌卡置於面板最上方，
   底色與段落一致，不再浮在段落之間被切斷 */
.r-section .r-block .lg-para {
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur); -webkit-backdrop-filter: var(--panel-blur);
  border: 1px solid var(--panel-line); border-radius: 3px;
  padding: 18px 18px 20px;
}
.r-section .r-block .lg-para + .lg-para { margin-top: 14px; }
.r-section .r-block .lg-para p { /* 面板已由 .lg-para 提供，內層文字不再自帶底色 */
  margin: 0; background: none; border: none; padding: 0;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  line-height: 1.95;                 /* 中文長段落要比預設更鬆才讀得下去 */
}
/* 同一段裡的第二段起要有呼吸。沒有這條，模型寫成兩段會黏成一大塊 */
.r-section .r-block .lg-para p + p { margin-top: 1.1em; }

/* 組別小標題。加一條細底線：八個面板長得一樣時，眼睛需要一個明確的起點才好掃。 */
.r-section .r-block .lg-para .lg-sub {
  font-family: var(--sans); font-size: 13px; letter-spacing: .22em;
  color: var(--accent); margin: 0 0 14px; padding-bottom: 9px;
  border-bottom: 1px solid rgba(214, 183, 122, .18);
}
/* 收束的兩段（值得注意的牌組、整體意義）沒有對應牌卡，改用左側金線標出
   「這裡開始是收攏，不是新的一組牌」，讀者才知道報告要結束了。 */
.r-section .r-block .lg-para.lg-close {
  border-left: 2px solid rgba(214, 183, 122, .42);
  background: rgba(16, 24, 36, .52);
}
.r-section .r-block .lg-para.lg-close + .lg-para.lg-close { margin-top: 12px; }
@media (max-width: 420px) {
  .r-section .r-block .lg-para { padding: 16px 14px 18px; }
  .r-section .r-block .lg-para p { line-height: 1.9; }
  .r-section .r-block .lg-para .lg-sub { font-size: 12.5px; letter-spacing: .18em; }
}
.r-questions { list-style: none; }
.r-questions li {
  font-family: var(--serif); font-size: 16px; color: var(--ink);
  padding: 14px 0 14px 26px; position: relative;
}
.r-questions li + li { border-top: 1px dashed var(--line); }
.r-questions li::before { content: '—'; position: absolute; left: 0; color: var(--accent-dim); }
.r-block.r-basis { border-top: 1px dashed var(--line); padding-top: 26px; }
.r-block.r-basis p { font-size: 14px; color: var(--ink-dim); font-family: var(--sans); }
.r-closing { text-align: center; font-family: var(--serif); color: var(--accent); font-size: 16px; margin: 54px 0 40px; }

/* 欄位一的下半：「製作專屬靈感卡」緊跟在回饋區塊底下（同一欄，中間不隔線）。
   說明句已依站主 2026-09 重排要求拿掉。 */
.r-makecard { margin-top: 22px; padding: 0 20px 34px; text-align: center; }

/* ---- Admin 後台 ---- */
/* 860px 對「處理時間」那張 13 欄的表太窄，欄位全被擠扁；放寬到 1180px。
   登入畫面維持窄版（見 .admin-screen#adminLogin）。 */
.admin-screen { max-width: 1180px; font-family: var(--sans); }
#adminLogin.admin-screen { max-width: 660px; }
.admin-screen .intake h1, .admin-title { font-family: var(--serif); }

/* 頁首＋分頁固定在頂端：資料很長，切分頁不該先滑回最上面 */
.admin-bar {
  position: sticky; top: 0; z-index: 20;
  margin: 0 -22px 20px; padding: 0 22px;
  background: linear-gradient(180deg, rgba(6, 10, 16, .97) 0%, rgba(6, 10, 16, .95) 72%, rgba(6, 10, 16, 0) 100%);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.admin-brand { display: flex; align-items: baseline; gap: 12px; }
.admin-sub {
  font-family: var(--sans); font-size: 11.5px; letter-spacing: .24em;
  color: var(--ink-faint);
}

/* 分頁列：八個分頁在手機上一行排不下。原本是不換行也不捲的 flex，於是後面幾顆
   被壓成「一字一行」的直書，最右邊那顆整個被切掉——點都點不到。
   改成橫向捲動＋標籤不斷字：排在後面的分頁一樣碰得到，切分頁時 admin.js 會把
   選中的那顆捲到中間。兩側的漸層淡出（--tabfade-l／--tabfade-r，由 admin.js
   依捲動位置切換）就是「這一側還有分頁」的提示——沒有它的話，一列切齊的分頁
   看起來就是全部了。捲軸本身藏起來：它會壓在分頁的底線上，很醜。 */
.a-tabs { border-bottom: 1px solid var(--line); }
.a-tabs-track {
  display: flex; gap: 2px;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  --tabfade-l: 0px; --tabfade-r: 0px;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--tabfade-l),
    #000 calc(100% - var(--tabfade-r)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--tabfade-l),
    #000 calc(100% - var(--tabfade-r)), transparent 100%);
}
.a-tabs-track::-webkit-scrollbar { display: none; }
.a-tabs-track.fade-l { --tabfade-l: 30px; }
.a-tabs-track.fade-r { --tabfade-r: 30px; }
.a-tab-btn {
  font: inherit; font-size: 13px; letter-spacing: .14em;
  color: var(--ink-faint); background: none; border: none;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  padding: 9px 18px 10px; cursor: pointer;
  flex: 0 0 auto; white-space: nowrap;
  transition: color .25s, border-color .25s, background .25s;
}
.a-tab-btn:hover { color: var(--ink-dim); background: rgba(214, 183, 122, .05); }
.a-tab-btn.on {
  color: var(--accent); border-bottom-color: var(--accent);
  background: rgba(214, 183, 122, .06);
}

/* 手機（站主主要在手機上看後台）：釘在上面的只留分頁列，頁首讓它跟著內容捲走。
   頁首那一塊（站名＋憑證期限＋兩顆登出）在手機寬度會排成三行，跟分頁列疊起來
   吃掉將近三分之一個畫面，而它是開頁時看一眼的東西，不是捲資料時要一直看的。
   display: contents 把 .admin-bar 這層盒子從版面上拿掉，頁首與分頁列變成各自
   獨立的區塊——非這樣不可：sticky 只能在自己的父盒子裡黏，分頁列留在
   .admin-bar 裡的話，.admin-bar 一捲出畫面它就跟著不見了。
   捲回最上面頁首自己會回來，所以沒有「收合／展開」這種狀態要記，
   版面高度也全程沒變，不會有內容突然往上跳一段的問題。 */
@media (max-width: 700px) {
  .admin-bar { display: contents; }
  .a-tabs {
    position: sticky; top: 0; z-index: 20;
    margin: 0 -22px 20px;
    /* 這一條是整片釘在資料上面的，所以底色不留透明度——實測過 .96～.98 都還
       看得到底下的字浮在分頁名稱上，深色底配亮字，幾個百分比就夠礙眼。
       （原本那條頁首下緣本來就是漸層淡出的，半透明在那裡是效果，在這裡是雜訊。
       後台的原則是可讀性優先於氣氛。）底色是不透明的，就不必再花一層模糊。 */
    background: rgb(6, 10, 16);
  }
  /* 內縮跟內文對齊，但捲的是整條 track——分頁可以一路捲到畫面邊緣再淡掉 */
  .a-tabs-track { padding: 0 22px; }
  /* 字距與左右留白縮一點：同樣寬度多露出一顆分頁，要橫向捲的距離就短一截 */
  .a-tab-btn { font-size: 12.5px; letter-spacing: .06em; padding: 10px 13px 11px; }
  /* 釘住的分頁列會蓋住「捲到定位」的東西（展開詳情、跳到某一區），
     所以給它們留一段等於分頁列高度的上緣邊界 */
  .a-group, .a-block, .a-pane details { scroll-margin-top: 58px; }
}
@media (max-width: 560px) {
  /* .screen 在這個寬度的左右留白是 26px，滿版的分頁列要跟著對齊 */
  .a-tabs { margin-left: -26px; margin-right: -26px; }
  .a-tabs-track { padding-left: 26px; padding-right: 26px; }
}

.a-pane { display: none; }
.a-pane.on { display: block; animation: fadein-soft .35s ease both; }

/* 只淡入、不位移。切分頁時滑一下 8px 會顯得晃，資料工具不需要。
   另外附帶一個好處：fadein 的 keyframe 有 translateY，配上 fill-mode: both
   之後 computed transform 會停在 matrix(1,0,0,1,0,0)——單位矩陣仍然會建立
   包含區塊，讓內部所有 position:sticky／fixed 的定位基準跑掉。純淡入沒這問題。 */
@keyframes fadein-soft { from { opacity: 0; } to { opacity: 1; } }
.admin-body .screen.active { animation: fadein-soft .5s ease both; }

/* 面板：把每一組資料收進一張卡，區塊之間才有呼吸 */
.a-card {
  padding: 18px 20px 20px;
  border: 1px solid rgba(214, 183, 122, .16); border-radius: 3px;
  background: rgba(11, 17, 27, .5);
}
/* 寬表格在窄螢幕上自己橫向捲，不要撐破版面。
   ⚠ 這一層在 css 檔尾的 overflow-x: clip 護欄之後變成必要的：整頁已經不能橫捲了，
   放不下的表格如果沒有自己的捲動容器，右邊的欄位就永遠碰不到。
   -webkit-overflow-scrolling 是給舊版 iOS 用的慣性捲動。 */
.a-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* 手機上捲軸只有在捲的時候才看得見，所以放不下的時候要主動說一聲——
   站主就是因為不知道可以捲，才以為右邊的欄位不見了。
   sticky + left:0 讓這行提示固定在容器左緣，不會跟著內容捲走。
   桌機（表格放得下）不顯示。 */
@media (max-width: 1100px) {
  .a-scroll::before {
    content: '← 左右滑動可看到右邊的欄位 →';
    position: sticky; left: 0; display: block; width: max-content;
    font-family: var(--sans); font-size: 11.5px; letter-spacing: .1em;
    color: var(--accent-dim); padding: 2px 0 7px;
  }
}
.admin-login-box { max-width: 380px; margin: 0 auto 30px; }
input.admin-pw {
  width: 100%; color: var(--ink);
  background: linear-gradient(180deg, rgba(17, 24, 38, .9), rgba(12, 18, 28, .9));
  border: 1px solid var(--line-strong); border-radius: 0;
  box-shadow: inset 0 0 14px rgba(0, 0, 0, .3);
  padding: 13px 16px; font: inherit; font-size: 16px; letter-spacing: .2em;
}
input.admin-pw:focus { outline: none; border-color: var(--accent-dim); }
.admin-error { margin-top: 10px; font-size: 13px; color: #bd8484; min-height: 1.6em; }
/* 頁首右側：憑證期限提示 ＋ 登出兩顆。手機（站主主要在手機上看後台）寬度不夠時
   整組換到下一行，而不是把左邊的站名擠成一個字一行。 */
.admin-sess { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.admin-sessnote { font-size: 11px; color: var(--ink-faint); }
@media (max-width: 560px) {
  /* 手機：站名一行、期限提示一行、兩顆按鈕一行。擠在同一行的話站名會被壓成一字一行 */
  .admin-head { flex-wrap: wrap; row-gap: 8px; }
  .admin-sess { flex: 1 1 100%; justify-content: flex-start; }
  .admin-sessnote { flex: 1 1 100%; }
}

.admin-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 26px 0 18px;
}
.admin-title { font-size: 19px; letter-spacing: .12em; }

/* 一個分頁裡放兩份不同的資料時（目前是「系統觀測」＝處理時間＋篇幅），
   每一份要有自己的標題與一條看得出來的界線，否則往下捲會分不出來到底換了主題。
   刻意比 .a-block h3（區塊標題）重一級：襯線體、大一級、上面一條分隔線。 */
.a-group + .a-group { margin-top: 44px; padding-top: 30px; border-top: 1px solid var(--line); }
.a-group-h {
  font-family: var(--serif); font-size: 17px; letter-spacing: .16em;
  color: var(--accent); margin: 0 0 6px;
}
.a-group-sub { font-size: 12.5px; color: var(--ink-faint); margin-bottom: 20px; }

.a-block { margin-bottom: 34px; }
/* 區塊標題＝展區圖說：前置菱形飾記＋延伸髮絲線 */
.a-block h3 {
  display: flex; align-items: center; gap: 12px;
  font-size: 12px; font-weight: 500; letter-spacing: .32em; text-indent: 0;
  color: var(--accent-dim); margin-bottom: 14px;
}
.a-block h3::before {
  content: ''; width: 6px; height: 6px; flex-shrink: 0;
  border: 1px solid var(--accent-dim); transform: rotate(45deg);
}
.a-block h3::after { content: ''; flex: 1; border-top: 1px solid var(--line); }
.a-hint { font-size: 12.5px; color: var(--ink-faint); margin-bottom: 10px; }
.a-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; }
@media (max-width: 700px) { .a-cols { grid-template-columns: 1fr; } }

/* 等寬自動換行：原本用 flex-wrap，卡片會隨內容長度變寬變窄看起來歪；
   改用 auto-fit 之後增減卡片不必回來改欄數。 */
.stat-row {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.stat-note { font-style: normal; font-size: 10.5px; color: var(--accent-dim); opacity: .8; }
/* 容量卡多了一條進度條與按鈕，grid 會把其他卡拉到一樣高留下大片空白，
   所以內容垂直居中，看起來才是同一組卡片而不是四個空盒子。 */
.stat {
  display: flex; flex-direction: column; justify-content: center;
  text-align: center;
  border: 1px solid rgba(214, 183, 122, .18); border-radius: 3px; padding: 18px 12px 16px;
  background: rgba(11, 17, 27, .5);
}
.stat b {
  display: block; font-family: var(--serif); font-size: 34px; line-height: 1.15;
  color: var(--accent); font-variant-numeric: tabular-nums; margin-bottom: 8px;
}
.stat span { font-size: 12px; line-height: 1.6; color: var(--ink-faint); letter-spacing: .04em; }
.stat b.warn { color: #cba95e; }
.stat b.crit { color: #c47f7f; }
.cap-bar {
  height: 5px; border-radius: 0; background: rgba(194, 168, 105, .12);
  margin: 10px 8px 8px; overflow: hidden;
}
.cap-fill { height: 100%; background: linear-gradient(90deg, var(--accent-dim), var(--accent)); }
.cap-fill.warn { background: linear-gradient(90deg, #97803e, #cba95e); }
.cap-fill.crit { background: linear-gradient(90deg, #96504e, #c47f7f); }
.cap-stat .btn.small { margin-top: 2px; padding: 3px 14px; font-size: 11.5px; }
.recalc-note { display: block; margin-top: 5px; font-size: 11px; color: var(--accent-dim); }

.cap-banner {
  margin: 20px 0 6px; padding: 12px 16px; border-radius: 0;
  font-size: 13.5px; line-height: 1.7; color: var(--ink);
}
.cap-banner.warn { border: 1px solid #6b5a2e; background: rgba(203, 169, 94, .07); }
.cap-banner.crit { border: 1px solid #6b3f3d; background: rgba(196, 127, 127, .07); }
.cap-banner b { color: var(--accent); }
/* 總覽統計的時間戳：伺服器把結果快取了幾分鐘，所以要看得到「這是幾點算的」 */
.ov-stamp { margin-top: 8px; font-size: 11px; color: var(--accent-dim); opacity: .75; text-align: right; }
.ov-stamp button { margin-left: 8px; }
.cap-banner.crit b { color: #c47f7f; }

.a-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.a-table td, .a-table th { padding: 8px 10px; border-bottom: 1px solid var(--line); text-align: left; }
.a-table th {
  font-size: 11.5px; color: var(--ink-faint); letter-spacing: .15em; font-weight: 500;
  border-bottom-color: var(--line-strong);
}
/* 這裡原本想讓表頭跟著捲，試過 th 與 thead、也排除了祖先的 transform
   （見下方 fadein-soft 的註解），實測都黏不住——sticky 在表格元素上受限於
   自己所在的列，沒有可位移的空間。與其留一條沒有作用的規則，直接不做。
   要往上看欄位名的話，上方的 .admin-bar 是真的固定住的，捲回去很快。 */
/* 隔列淡底：一列橫跨十幾欄時，眼睛才不會跳行 */
.a-table tbody tr:nth-child(even of :not([hidden])) { background: rgba(255, 255, 255, .014); }
/* 數字等寬對齊才比得出大小 */
.a-table .num, .a-table .tm-num {
  text-align: right; font-variant-numeric: tabular-nums;
}
.a-table .num { color: var(--accent); font-family: var(--serif); }
.a-table .empty, .empty { color: var(--ink-faint); font-size: 13px; padding: 12px 4px; }
.a-table code { font-size: 12px; color: var(--ink-dim); }

/* 圓餅圖（conic-gradient 甜甜圈 + 圖例） */
.pie-wrap { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.pie {
  width: 132px; height: 132px; border-radius: 50%; flex-shrink: 0;
  position: relative;
  outline: 1px solid var(--line); outline-offset: 4px;
}
.pie::after {
  content: ''; position: absolute; inset: 26%;
  border-radius: 50%; background: var(--bg);
}
.pie-legend { flex: 1; min-width: 200px; }
.pl-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: 13px; }
.pl-dot { width: 10px; height: 10px; border-radius: 0; flex-shrink: 0; }
.pl-label { flex: 1; color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-val { color: var(--accent); font-family: var(--serif); }
.pl-pct { width: 44px; text-align: right; color: var(--ink-faint); font-size: 12px; }

.filter-bar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-bottom: 14px; padding: 10px 12px;
  border: 1px solid rgba(214, 183, 122, .24); border-radius: 3px;
  background: rgba(13, 20, 31, .58);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.scope-bar { margin: 18px 0 26px; }
.scope-label { font-size: 12.5px; color: var(--accent-dim); letter-spacing: .2em; }
/* 手機：這一條壓成一行。原本是「標籤／下拉／說明」各佔一行的一張卡，
   在 390px 的畫面上量到 147px，壓成一行之後 61px——而它只是一個下拉，
   底下的資料才是要看的東西。
   說明那一句（套用到哪裡）在這個寬度收起來：三個選項自己就寫得很清楚，
   而且它只在總覽與使用紀錄兩個分頁出現，本來就在資料的正上方。 */
@media (max-width: 700px) {
  .scope-bar { gap: 10px; margin: 12px 0 18px; padding: 7px 10px; flex-wrap: nowrap; }
  .scope-label { font-size: 11.5px; letter-spacing: .1em; flex: 0 0 auto; }
  /* min-width: 0 才肯縮——flex 子項預設不會縮到內容寬以下 */
  .scope-bar .flt-select { flex: 1 1 auto; min-width: 0; }
  .scope-bar .flt-count { display: none; }
}
.flt-chk {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink-dim); cursor: pointer; user-select: none;
}
.flt-chk input { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }
.flt-select {
  font: inherit; font-size: 13px; color: var(--ink-dim);
  background: var(--bg-soft); border: 1px solid var(--line-strong); border-radius: 0;
  padding: 6px 10px; cursor: pointer;
}
.flt-select:focus { outline: none; border-color: var(--accent-dim); }
.flt-count { margin-left: auto; font-size: 12px; color: var(--ink-faint); }

/* 趨勢頁的時間區段列。這一條管整頁，所以跟「資料範圍」用同一種外框與位置，
   讓兩者一眼看得出是同一個層級的東西。
   常用區段用按鈕（選中的那顆與趨勢圖的期間鈕同樣式），要別的就改日期欄。 */
.td-range-bar { margin: 18px 0 26px; }
.td-presets { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.td-presets .btn.on { border-color: var(--accent-dim); color: var(--accent); }
.td-custom { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* color-scheme: dark 讓瀏覽器原生的日曆圖示與面板跟著暗底，
   不然 Chrome 會在深色欄位上畫一個白底的日曆鈕 */
.flt-date {
  font: inherit; font-size: 13px; color: var(--ink-dim); color-scheme: dark;
  background: var(--bg-soft); border: 1px solid var(--line-strong); border-radius: 0;
  padding: 5px 8px; cursor: pointer;
}
.flt-date:focus { outline: none; border-color: var(--accent-dim); }
.td-dash { color: var(--ink-faint); font-size: 12px; }
/* 手機：標籤與說明讓位，剩下的自己換行——這一條有五顆按鈕加兩個日期欄，
   硬壓成一行只會每一個都小到按不準。 */
@media (max-width: 700px) {
  .td-range-bar { gap: 10px; margin: 12px 0 18px; padding: 8px 10px; }
  .td-range-bar .scope-label { font-size: 11.5px; letter-spacing: .1em; }
  .td-range-bar .flt-count { margin-left: 0; flex-basis: 100%; }
}

.chk-col { width: 34px; text-align: center !important; }
.chk-col input {
  accent-color: var(--accent); width: 15px; height: 15px;
  cursor: pointer; vertical-align: middle;
}
.bulk-bar {
  display: flex; align-items: center; gap: 14px;
  margin-bottom: 12px; padding: 9px 14px;
  border: 1px solid #5f403e; border-radius: 0;
  background: rgba(95, 64, 62, .12);
}
#bulkCount { font-size: 13px; color: var(--ink-dim); }

.sess-row { cursor: pointer; transition: background .2s; }
.sess-row:hover { background: rgba(194, 168, 105, .05); }
/* 可排序表頭：點擊切換遞增／遞減，並以箭頭標示目前排序欄 */
.a-table th.sortable {
  cursor: pointer; user-select: none; white-space: nowrap;
  position: relative; padding-right: 18px;
  transition: color .2s ease;
}
.a-table th.sortable:hover { color: var(--accent); }
.a-table th.sortable::after {
  content: '⇅'; position: absolute; right: 5px;
  font-size: 10px; opacity: .3;
}
.a-table th.sortable.asc::after { content: '↑'; opacity: 1; color: var(--accent); }
.a-table th.sortable.desc::after { content: '↓'; opacity: 1; color: var(--accent); }
.a-table th.sorted { color: var(--accent); }

/* 訪客 ID：可點，用來只看這位訪客的紀錄 */
.vid-btn {
  font: inherit; background: none; border: none; padding: 2px 4px; margin: -2px -4px;
  border-radius: 2px; cursor: pointer; color: inherit;
  transition: background .2s, color .2s;
}
.vid-btn:hover { background: rgba(214, 183, 122, .12); }
.vid-btn:hover code { color: var(--accent); }
.vid-btn.on { background: rgba(214, 183, 122, .18); }
.vid-btn.on code { color: var(--accent); }
.visit-cell { white-space: nowrap; }
.badge.repeat { color: var(--accent); border-color: rgba(214, 183, 122, .45); }
button.badge.repeat {
  font: inherit; font-size: 11.5px; cursor: pointer;
  background: rgba(224, 193, 132, .07);
  transition: background .2s, border-color .2s;
}
button.badge.repeat:hover {
  background: rgba(224, 193, 132, .18); border-color: var(--accent-dim);
}

/* 展開的「這位訪客歷次來訪」 */
.vl-head { font-size: 13px; color: var(--ink-dim); margin-bottom: 10px; }
.vl-head code { color: var(--accent); }
.vl-scope { color: var(--ink-faint); font-size: 12px; }
.vl-list { list-style: none; margin: 0 0 10px; padding: 0; }
.vl-item {
  display: grid; gap: 12px; align-items: center; padding: 7px 10px;
  /* 第一欄要放得下「第 100 / 128 次」——只寫「第 N 次」時 62px 就夠，
     加上總次數之後不加寬會換行。 */
  grid-template-columns: 96px 118px 1fr auto auto;
  border-left: 2px solid transparent;
  font-size: 13px; color: var(--ink-dim);
}
.vl-item + .vl-item { border-top: 1px solid var(--line); }
/* 每一次都可以點開，所以要看得出是可互動的 */
.vl-item { cursor: pointer; transition: background .18s, border-color .18s; }
.vl-item:hover { background: rgba(214, 183, 122, .09); }
.vl-item:focus-visible { outline: 1px solid var(--accent-dim); outline-offset: -2px; }
/* 標出「你從哪一列點進來的」，才知道自己在時間軸上的哪裡 */
.vl-item.now {
  background: rgba(224, 193, 132, .07); border-left-color: var(--accent-dim);
}
/* 目前展開的那一次 */
.vl-item.open { border-left-color: var(--accent); background: rgba(224, 193, 132, .12); }
.vl-detail { list-style: none; padding: 0; }
.vl-detail .detail-cell {
  padding: 12px 14px; margin: 0 0 4px;
  border-left: 2px solid var(--accent-dim);
  background: rgba(6, 10, 17, .5);
}
.vl-no { color: var(--accent); font-variant-numeric: tabular-nums; }
.vl-time { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.vl-topic { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vl-foot { font-size: 12px; color: var(--ink-faint); }
@media (max-width: 760px) {
  .vl-item { grid-template-columns: 96px 1fr; }
  .vl-time, .vl-tool, .vl-fb { grid-column: 2; }
}

/* 工具標籤 */
.tool-tag {
  display: inline-block; font-size: 11.5px; letter-spacing: .04em;
  color: var(--accent); border: 1px solid var(--line);
  border-radius: 2px; padding: 2px 7px; white-space: nowrap;
  background: rgba(224, 193, 132, .07);
}

/* ---- 後台：使用者回饋 ---- */
.fb-summary {
  display: flex; align-items: center; gap: 26px; flex-wrap: wrap;
  padding: 14px 16px; margin-bottom: 14px;
  border: 1px solid var(--line); border-radius: 2px; background: var(--panel);
}
.fb-avg { display: flex; flex-direction: column; gap: 2px; }
.fb-avg b { font-family: var(--serif); font-size: 30px; color: var(--accent); line-height: 1; }
.fb-avg span { font-size: 11.5px; color: var(--ink-faint); }
.fb-dist { flex: 1; min-width: 220px; display: flex; flex-direction: column; gap: 3px; }
/* 每一條就是一顆星的篩選鈕：可點、可用鍵盤 focus，所以是 <button> 而非 <div> */
.fbd-row {
  display: flex; align-items: center; gap: 8px; width: 100%;
  font: inherit; font-size: 11.5px; text-align: left; color: inherit;
  padding: 3px 6px; margin: 0 -6px; border: 0; border-radius: 2px;
  background: none; cursor: pointer; transition: background .15s;
}
.fbd-row:hover:not(:disabled) { background: rgba(224, 193, 132, .07); }
.fbd-row.on { background: rgba(224, 193, 132, .14); box-shadow: inset 2px 0 0 var(--accent); }
.fbd-row.on .fbd-star, .fbd-row.on .fbd-num { color: var(--accent); }
.fbd-row.on .fbd-fill { background: var(--accent); }
/* 一筆都沒有的星等按不動——點了只會得到空白清單 */
.fbd-row:disabled { cursor: default; opacity: .45; }
.fbd-star { color: var(--accent-dim); letter-spacing: .06em; white-space: nowrap; }
.fbd-bar { flex: 1; height: 6px; background: rgba(224, 193, 132, .1); border-radius: 3px; overflow: hidden; }
.fbd-fill { display: block; height: 100%; background: var(--accent-dim); }
.fbd-num { width: 2.4em; text-align: right; color: var(--ink-dim); }

/* 篩選中的提示：捲到清單下面也要知道自己只看到一部分 */
.fb-flt {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--ink-faint);
}
.fb-flt-star { color: var(--accent); letter-spacing: .08em; }
.fb-flt-clear {
  font: inherit; color: var(--accent-dim); background: none;
  border: 1px solid var(--line); border-radius: 2px; padding: 2px 8px; cursor: pointer;
}
.fb-flt-clear:hover { color: var(--accent); background: rgba(224, 193, 132, .07); }

.fb-list { display: flex; flex-direction: column; gap: 10px; }
/* ── 後台「贊助點擊」分頁 ──
   卡片沿用回饋那一套（.fb-card），只補這一頁自己的三件事。 */
.sp-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
/* .fb-summary 是 flex row，這一頁的內容要由上往下排 → 包一層佔滿寬度的容器 */
.sp-summary-inner { width: 100%; }
/* 決策用的那一個數字（彈出視窗佔多少）——站主要看的就是它，
   所以獨立成一行、字放大，不要跟其他比例混在同一份清單裡比大小。 */
.sp-headline {
  display: flex; align-items: baseline; gap: 8px; margin: 12px 0 4px;
  font-family: var(--sans);
}
.sp-headline b { font-size: 22px; color: var(--accent); letter-spacing: .02em; }
.sp-headline span { font-size: 12px; color: var(--ink-faint); }
/* 分佈列借用回饋星等分佈那一套（.fbd-*），只是把星星換成文字標籤。
   那幾列是可點的按鈕，這裡只是顯示，所以把游標與 hover 收掉。 */
/* 長條圖在寬螢幕上不必拉滿——超過這個寬度就只是把數字推遠 */
.sp-dist-group { margin-top: 10px; max-width: 520px; }
.sp-dist-head {
  margin: 10px 0 4px; font-family: var(--sans); font-size: 11.5px;
  color: var(--ink-faint); letter-spacing: .04em;
}
.sp-dist { cursor: default; }
.sp-dist:hover { background: none; }
/* 「🍰 Buy Me a Coffee」是最長的一個標籤，欄寬要放得下它，不然會折行 */
.sp-dist-label { width: 10.5em; flex: none; white-space: nowrap; color: var(--ink-dim); }
.sp-dist-pct { width: 3em; flex: none; text-align: right; color: var(--accent-dim); font-variant-numeric: tabular-nums; }
.sp-dist .fbd-num { flex: none; }
/* 彈出視窗那一列標起來：整份清單裡它是唯一要拿來做決定的 */
.sp-dist.sp-hi .sp-dist-label,
.sp-dist.sp-hi .sp-dist-pct { color: var(--accent); }
.sp-dist.sp-hi .fbd-fill { background: var(--accent); }
.sp-dist-note {
  margin: 12px 0 0; font-family: var(--sans); font-size: 11.5px; line-height: 1.7;
  color: var(--ink-faint); max-width: 40em;
}
/* 真正收到的贊助擺在點擊統計上面：錢比意願重要，先看得到的應該是錢 */
.sp-paid { margin-bottom: 18px; }
.sp-paid .fb-avg { margin-bottom: 10px; }
.sp-paid.empty-block { color: var(--ink-faint); font-size: 12.5px; font-family: var(--sans); }
.sp-pay { border-left: 2px solid var(--accent-dim); }
/* 退款那幾筆刻意留著、只是變淡＋刪節線：無聲消失才是對帳時最花時間的那種 */
.sp-pay.refunded { opacity: .55; }
.sp-pay.refunded .fb-card-stars { text-decoration: line-through; }
.sp-refund { color: #d9a08a; font-size: 11.5px; text-decoration: none; }
.sp-clicks-head {
  margin: 4px 0 8px; font-family: var(--sans); font-size: 12.5px;
  color: var(--ink-faint); letter-spacing: .04em;
}
.sp-card { cursor: pointer; transition: border-color .18s, background .18s; }
.sp-card:hover { border-color: rgba(214, 183, 122, .5); background: rgba(214, 183, 122, .05); }
.sp-visits { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 8px; }
/* 清單只列有題目的來訪，所以「第 N / M 次」的 M 跟總來訪次數不同——講明白 */
.sp-visits-head {
  margin-bottom: 6px; font-family: var(--sans); font-size: 11.5px;
  color: var(--ink-faint); letter-spacing: .04em;
}
/* 展開的來訪清單在這裡只是「看」，不像使用紀錄那一頁可以再點進去，
   所以把 .vl-item 借來的手指游標與 hover 收掉——看得到卻點不動最惱人。 */
.sp-visits .vl-item { cursor: default; }
.sp-visits .vl-item:hover { background: none; }

.fb-card {
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 2px;
  background: var(--panel); font-size: 13px; color: var(--ink-dim);
}
.fb-card-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.fb-card-stars { color: var(--accent); letter-spacing: .08em; }
.fb-card-meta { font-size: 11.5px; color: var(--ink-faint); }
.fb-card-topic { font-size: 12.5px; color: var(--ink-faint); margin-bottom: 6px; }
.fb-card-text { color: var(--ink); line-height: 1.8; white-space: pre-wrap; }
.fb-card-text.dim { color: var(--ink-faint); }
.fb-card-sid { margin-top: 6px; font-size: 11px; color: var(--ink-faint); }
.fb-card-sid code { color: var(--accent-dim); }

/* ---- 後台：處理時間 ---- */
.tm-stats { margin-bottom: 14px; }
.tm-stats-head { font-size: 11.5px; color: var(--ink-faint); margin-bottom: 8px; }
.a-table.tm-summary { max-width: 560px; }
.a-table.tm-summary th, .a-table.tm-summary td { padding: 5px 10px; }
.tm-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tm-num.dim { color: var(--ink-faint); }
.a-table.timings { font-size: 12px; }
.a-table.timings th, .a-table.timings td { padding: 5px 8px; }
.a-table.timings tbody tr:hover { background: rgba(224, 193, 132, .05); }

/* 失敗原因：整串錯誤訊息（含供應商的 code）要看得完整，所以准許換行、不截斷。
   截掉的話正好會截在 code 那一段，而那一段就是唯一有用的資訊。 */
#tfTable .tm-err { max-width: 34em; white-space: normal; word-break: break-word; line-height: 1.5; }
#tfTable .tm-err .dim { color: var(--ink-faint); margin-left: 4px; }

/* 清單中的主題欄：只露前段，全文放 title 與展開的詳情 */
.topic-cell { max-width: 10em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 清單中的回饋欄 */
.fb-cell { white-space: nowrap; }
.fb-stars-cell { color: var(--accent); letter-spacing: .06em; }
.fb-has-text { margin-left: 5px; color: var(--accent-dim); }
.fb-detail-text { margin-top: 6px; white-space: pre-wrap; max-height: 200px; }

/* 標記＝典藏章：雙框戳記 */
.badge {
  font-size: 11px; color: var(--accent); border: 1px solid var(--accent-dim);
  border-radius: 0; padding: 2px 10px; letter-spacing: .14em;
  outline: 1px solid var(--line); outline-offset: 2px;
  /* 欄位變多之後表格會擠壓每一欄，若允許折行，「有題目」會被拆成三行 */
  white-space: nowrap;
}
/* 語言與地區都是短標籤，折行只會變醜（「繁體中／文」）。
   地區只顯示國名，完整的「國名（國碼）」放在 title 裡。 */
.lang-cell, .geo-cell { white-space: nowrap; }

/* 後台：訪客標註（vid → 這是誰）。名字在上、vid 在下；
   鉛筆平常收暗，滑到那一列才亮起來——低頻操作不該常駐搶視線 */
.vid-cell { white-space: nowrap; }
.vid-label { display: block; font-size: 12px; color: var(--accent); line-height: 1.5; }
.vid-row { display: inline-flex; align-items: center; gap: 4px; }
.vid-edit {
  border: none; background: none; cursor: pointer; padding: 1px 4px;
  font-size: 12px; color: var(--ink-faint); opacity: .35; border-radius: 3px;
}
.sess-row:hover .vid-edit, .vid-edit:focus-visible { opacity: 1; color: var(--accent-dim); }

/* 後台：來訪趨勢圖。分層直條（下段＝回訪者的來訪），文字用文字色、不用序列色 */
.trend-range { float: right; display: inline-flex; gap: 6px; }
.trend-range .btn.on { border-color: var(--accent-dim); color: var(--accent); }
.trend-svg { display: block; width: 100%; height: auto; }
.trend-svg .tr-grid { stroke: rgba(214, 183, 122, .5); stroke-width: 1; }
/* 站主回報 .12 在黑底上看不清，提到 .3；基線同步提到 .5 保持「基線＞格線」的層次 */
.trend-svg .tr-grid.faint { stroke: rgba(214, 183, 122, .3); stroke-dasharray: 3 4; }
.trend-svg .tr-lab { fill: var(--ink-faint); font-family: var(--sans); font-size: 10.5px; }
.trend-svg .tr-val { fill: var(--ink-dim); font-family: var(--sans); font-size: 11px; }
/* 回訪那一段的數字。這一個用序列色（金），不用文字色：同一欄裡上下兩個數字，
   顏色是唯一能讓人一眼對上「哪個數字屬於哪一段」的線索 */
.trend-svg .tr-bval { fill: var(--accent); font-family: var(--sans); font-size: 10.5px; }
/* 滑過某一天：bar 打亮、數字浮出；今天與峰值的常駐數字在滑過那組時讓位 */
.trend-svg .tr-hval { fill: var(--ink); font-family: var(--sans); font-size: 11px; display: none; }
.trend-svg .tr-hback { fill: var(--accent); font-family: var(--sans); font-size: 10.5px; display: none; }
.trend-svg .tr-bar:hover .tr-hval, .trend-svg .tr-bar:hover .tr-hback { display: block; }
.trend-svg .tr-bar:hover .tr-val, .trend-svg .tr-bar:hover .tr-bval { display: none; }
/* 滑過只打亮、不改顏色：顏色現在分的是回訪／新訪客兩段，改掉就把分層抹平了 */
.trend-svg .tr-bar:hover .tr-fill { opacity: 1; }
/* 圖例。色塊的顏色與透明度要跟 bar 對得起來，否則對照不到 */
.tr-legend {
  display: flex; flex-wrap: wrap; gap: 6px 18px; justify-content: center;
  margin-top: 8px; font-family: var(--sans); font-size: 11px; color: var(--ink-faint);
}
.tr-legend i {
  display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 6px;
  vertical-align: -1px; background: var(--accent-dim); opacity: .7;
}
.tr-legend i.back { background: var(--accent); opacity: 1; }
.tr-legend .dim { opacity: .7; }

/* 後台：每日時段趨勢的熱力圖。「一天一列 × 24 格」的網格；量值是順序性的，
   所以只用一個色相（金）由淡到亮表示多寡，不用多色階——多色階讀起來像分類。
   格值 0 刻意留一個極淡的底：「沒有」與「還沒畫到」在圖上不能長得一樣。 */
.hm { font-family: var(--sans); font-size: 10.5px; color: var(--ink-faint); }
.hm-row { display: grid; grid-template-columns: 58px 1fr; align-items: center; gap: 8px; margin-top: 3px; }
.hm-day { text-align: right; white-space: nowrap; }
/* 週末的列標亮一階：「週末跟平日是不是兩回事」正是這張圖最常要回答的問題 */
.hm-day.we { color: var(--accent-dim); }
.hm-cells { display: grid; grid-template-columns: repeat(24, 1fr); gap: 2px; }
.hm-cell { aspect-ratio: 1 / 1; min-height: 9px; border-radius: 2px; background: rgba(255, 255, 255, .045); }
.hm-head { margin-bottom: 2px; }
.hm-head .hm-cell { background: none; aspect-ratio: auto; text-align: center; }
.vid-edit:hover { background: rgba(214, 183, 122, .12); color: var(--accent); }
/* 工具說明裡的界線註記（目前只有占星用：講明不看流年運勢）。
   字級與字體跟這一頁的內文一致（16.5px 襯線）——它是要被讀完的一段話，
   不是註腳。層次差異只靠左側那條金線與稍暗的顏色表示，不靠縮小字級。 */
.gd-note {
  margin: 16px 0 0; padding: 2px 0 2px 14px;
  font-family: var(--serif); font-size: 16.5px; line-height: 1.95;
  color: var(--ink-dim); border-left: 1px solid var(--accent-dim);
}

/* 一次性資料修正（收在 details 裡，平常不佔版面也不會誤觸） */
.a-fix { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 12px; }
.a-fix summary {
  cursor: pointer; font-size: 13px; color: var(--accent-dim);
  font-family: var(--sans); letter-spacing: .06em;
}
.a-fix summary:hover { color: var(--accent); }
.a-fix .a-hint { margin: 10px 0; }
.fix-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 10px 0; }
.fix-before {
  font: inherit; font-size: 13px; color: var(--ink); color-scheme: dark;
  background: rgba(6, 10, 17, .7); border: 1px solid var(--line-strong);
  border-radius: 0; padding: 6px 10px;
}
.fix-note { font-size: 12.5px; color: var(--ink-dim); line-height: 1.7; min-height: 1.2em; }

/* 字數：數字靠右對齊才好比大小；「+」標記＝觸到 4000 的紀錄上限 */
.chars-cell { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.chars-cap { color: var(--ink-faint); margin-left: 1px; }
/* 英文紀錄的 words 換算：退成註記，不要跟字元數搶讀 */
.chars-w { color: var(--ink-faint); font-size: 11px; margin-left: 2px; }
/* 使用紀錄的「靈感卡」欄。做過卡的那幾列要跳出來——那是全站唯一每次都有明確
   成本的產出，掃清單時會想先看它們；「?」是索引還沒建過（查不到，不是沒有）。 */
.cards-cell { white-space: nowrap; text-align: center; }
/* 回填估算的常駐數字也要淡一點，不然只有 bar 淡、數字照亮，看起來像沒對齊 */
.trend-svg .tr-val.est { opacity: .7; }

/* 金額靠右、等寬數字：一整欄的錢要能直接比大小 */
.cost-cell { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cards-badge { cursor: default; }
.cards-unknown { color: #d9b98a; letter-spacing: .1em; }

/* 索引還沒建過時才出現的那一列。補齊之後永遠消失，所以不必做成常駐的工具列。 */
.oaidx-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin: 10px 0 4px; padding: 10px 14px;
  border: 1px solid rgba(214, 183, 122, .18); border-left: 3px solid #d9b98a;
  background: rgba(10, 15, 24, .55);
}
.oaidx-text, .oaidx-note {
  font-family: var(--sans); font-size: 12.5px; line-height: 1.8; color: var(--ink-faint);
}
.oaidx-text b { color: var(--ink-dim); font-weight: 500; }
.oaidx-note { color: var(--accent-dim); }
.oaidx-bar .btn { flex: none; }

/* 單筆詳情裡的「這一則做出的靈感卡」。卡面句是英文，所以那一行用等寬 LTR
   （.oa-ltr）；每一張一個小框，與候選句（.oa-pickopt）同一套語彙。 */
.d-line.d-cards { display: flex; align-items: flex-start; }
.d-cards-box { flex: 1; }
.d-card {
  padding: 9px 11px; margin-bottom: 7px; border-radius: 7px;
  border: 1px solid rgba(226, 201, 150, .28); background: rgba(226, 201, 150, .05);
}
.d-card:last-child { margin-bottom: 0; }
.d-card-head {
  font-family: var(--sans); font-size: 11.5px; color: var(--ink-faint);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-bottom: 4px;
}
.d-card-head b { display: inline; min-width: 0; margin: 0; color: var(--ink); letter-spacing: .06em; font-size: 13px; }
.d-card-line { font-size: 12.5px; line-height: 1.6; color: var(--ink-dim); }
.d-card-local { font-size: 12.5px; line-height: 1.7; color: var(--ink-faint); margin-top: 3px; }
.d-card .btn { margin-top: 7px; }
.d-card .oa-img { margin-top: 7px; }

.badge.dim { color: var(--ink-faint); border-color: var(--line); }
.sess-detail .detail-cell {
  background: var(--panel); font-size: 13px; color: var(--ink-dim);
  padding: 14px 16px;
}
.d-line { margin-bottom: 6px; }
.astro-sub { font-size: 12px; color: var(--ink-faint); }
.prompt-wrap { flex: 1; }
.prompt-meta { font-size: 12px; color: var(--ink-faint); margin-bottom: 6px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.prompt-meta code { color: var(--accent-dim); }
.prompt-meta .btn.small { padding: 2px 12px; font-size: 11px; }
.prompt-text { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; line-height: 1.7; max-height: 340px; }
.seg-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.seg-tab {
  font: inherit; font-size: 11.5px; color: var(--ink-faint);
  background: none; border: 1px solid var(--line); border-radius: 0;
  padding: 3px 14px; cursor: pointer; transition: all .2s;
}
.seg-tab:hover { color: var(--ink-dim); }
.seg-tab.on { color: var(--accent); border-color: var(--accent-dim); }
.sys-text { margin-top: 8px; border-left-color: var(--accent-dim); }

/* 後台除錯問答（帶 prompt 脈絡問 LLM） */
.ask-chat { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line); }
.ask-hint { font-size: 12px; color: var(--ink-faint); margin-bottom: 8px; }
.ask-log { max-height: 320px; overflow-y: auto; }
.ask-log:not(:empty) { margin-bottom: 10px; }
.ask-msg {
  white-space: pre-wrap; line-height: 1.8; font-size: 12.5px;
  padding: 8px 12px; margin-bottom: 8px; border-radius: 0;
}
.ask-msg.user { color: var(--ink); background: rgba(194, 168, 105, .08); border: 1px solid var(--line); }
.ask-msg.assistant { color: var(--ink-dim); border-left: 2px solid var(--accent-dim); padding-left: 12px; }
.ask-msg.error { color: #bd8484; font-size: 12px; }
.ask-row { display: flex; gap: 10px; }
.ask-input {
  flex: 1; font: inherit; font-size: 13px;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 0; padding: 8px 12px;
}
.ask-input:focus { outline: none; border-color: var(--accent-dim); }
.note-cell { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-dim); font-size: 12.5px; }
.dim-dash { color: var(--ink-faint); }
.d-note { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.note-input {
  flex: 1; max-width: 420px; font: inherit; font-size: 13px;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 0; padding: 7px 12px;
}
.note-input:focus { outline: none; border-color: var(--accent-dim); }
.note-saved { font-size: 12px; color: var(--accent); min-width: 60px; }
.btn.small { font-size: 12.5px; padding: 6px 18px; }
.btn.danger { color: #bd8484; border-color: #5f403e; }
.btn.danger:hover:not(:disabled) { color: #d8a3a1; border-color: #8a5a57; }
.d-actions-row { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--line); }
.d-line.d-message { display: flex; align-items: flex-start; }
.d-msg-text {
  flex: 1; white-space: pre-wrap; line-height: 1.8;
  border-left: 2px solid var(--line-strong); padding-left: 12px; margin-top: 2px;
  color: var(--ink-dim); font-size: 12.5px; max-height: 300px; overflow-y: auto;
}
.d-line b {
  display: inline-block; min-width: 3.2em; margin-right: 10px;
  color: var(--accent-dim); font-weight: 500; font-size: 12px; letter-spacing: .2em;
}
.a-actions { padding: 16px 0; text-align: center; }

/* 細金捲軸（清單、訊息、問答內的滾動區） */
.combo-list::-webkit-scrollbar, .d-msg-text::-webkit-scrollbar, .ask-log::-webkit-scrollbar { width: 6px; }
.combo-list::-webkit-scrollbar-track, .d-msg-text::-webkit-scrollbar-track, .ask-log::-webkit-scrollbar-track { background: transparent; }
.combo-list::-webkit-scrollbar-thumb, .d-msg-text::-webkit-scrollbar-thumb, .ask-log::-webkit-scrollbar-thumb {
  background: rgba(194, 168, 105, .28);
}

/* ---- 手機版：邊距加寬、按鈕改堆疊整寬、字距收斂避免斷行 ---- */
@media (max-width: 560px) {
  .intake h1 { font-size: 34px; }
  .screen { padding: 0 26px 48px; }
  .btn { letter-spacing: .16em; text-indent: .16em; padding: 13px 22px; }
  .divine-actions, .r-follow {
    flex-direction: column; align-items: center; gap: 12px;
  }
  .divine-actions .btn, .r-follow .btn { width: 100%; max-width: 320px; }
  /* 三顆 AI 鈕在窄螢幕仍然同一排：整排等寬縮小，字距收緊才塞得下 */
  .ai-row { gap: 8px; }
  .ai-row .btn {
    flex: 1 1 0; min-width: 0; max-width: 120px;
    padding: 11px 6px; font-size: 13px;
    letter-spacing: .05em; text-indent: .05em;
  }
  .deck-grid { gap: 6px; }
}

/* ---- 左上角選單 ---- */
/* ⚠ 兩個站主指定的決定，都推翻了先前的做法，理由一併記在這裡：
   ① position 是 absolute 而不是 fixed：「滑動的時候應該要一起向上滑，不會一直
      固定在左上角，因為這樣子版面不好看。」代價是捲到長頁面下半部之後這顆鈕就
      不在畫面上，要開選單得先回到頂端。
   ② 沒有「選單」小字標籤：「左上角選單不需要把中文寫上去。」
      ⚠ 那個標籤是刻意加的，理由是「站主觀察到很多人不知道三線能點，也就找不到
      我的靈感訊息」——拿掉等於把那個可發現性問題放回去，而且與 ① 疊加
      （字沒了、鈕還會捲走）。站主知情後仍決定拿掉，可發現性改由 onboarding
      的首次導覽負責（js/onboarding.js 的 introTour 第二步就是指這顆鈕）。
   ⚠ js/diag.js 用這顆鈕的 left 反推整頁縮放倍率——absolute 之後那裡必須加上
      scrollX 才算得對，已一併修正。 */
.menu-toggle {
  position: absolute; top: 16px; left: 16px; z-index: 60;
  width: 42px; height: 42px; padding: 11px 9px;
  display: flex; flex-direction: column; justify-content: space-between;
  background: rgba(13, 20, 31, .55); border: 1px solid var(--line); border-radius: 4px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); cursor: pointer;
  box-shadow: 0 0 16px rgba(0, 0, 0, .35);
}
.menu-toggle span {
  display: block; height: 2px; width: 100%; border-radius: 2px;
  background: linear-gradient(90deg, var(--accent), #f0dca6);
  transition: transform .28s ease, opacity .2s ease;
}
/* 選單開啟時隱藏三線鈕——關閉改由面板右上角的 × 負責 */
.menu-toggle.is-open { opacity: 0; pointer-events: none; transition: opacity .2s ease; }

/* 面板右上角的關閉鈕：淺銀白細線、小尺寸 */
.menu-close {
  position: absolute; top: 14px; right: 14px; z-index: 2;
  width: 26px; height: 26px; padding: 0;
  background: none; border: none; cursor: pointer;
}
.menu-close::before, .menu-close::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 15px; height: 1px; margin: -1px 0 0 -7.5px;
  background: rgba(233, 237, 242, .7); transition: background .2s ease;
}
.menu-close::before { transform: rotate(45deg); }
.menu-close::after { transform: rotate(-45deg); }
.menu-close:hover::before, .menu-close:hover::after { background: #f4f7fa; }

.side-menu { position: fixed; inset: 0; z-index: 55; visibility: hidden; }
.side-menu.open { visibility: visible; }
.menu-backdrop {
  position: absolute; inset: 0; background: rgba(4, 7, 12, .5);
  opacity: 0; transition: opacity .3s ease;
}
.side-menu.open .menu-backdrop { opacity: 1; }
.menu-panel {
  position: absolute; top: 0; left: 0; height: 100%; width: 78%; max-width: 300px;
  padding: 78px 22px 30px;
  background: linear-gradient(180deg, rgba(14, 21, 33, .96), rgba(9, 14, 22, .98));
  border-right: 1px solid var(--line);
  box-shadow: 0 0 40px rgba(0, 0, 0, .5);
  transform: translateX(-100%); transition: transform .3s ease;
  display: flex; flex-direction: column; gap: 4px;
}
.side-menu.open .menu-panel { transform: translateX(0); }
.menu-brand {
  display: flex; align-items: center; gap: .6em;
  font-family: var(--serif); font-size: 15px; letter-spacing: .22em; color: var(--accent);
  padding-bottom: 16px; margin-bottom: 10px; border-bottom: 1px solid var(--line);
}
/* 標誌尺寸以 em 綁定標題字級，改字級時自動等比縮放 */
.menu-logo { width: 1.9em; height: 1.9em; flex: 0 0 auto; object-fit: contain; display: block; }
.menu-item {
  display: block; width: 100%; text-align: left; text-decoration: none;
  font-family: var(--serif); font-size: 16px; letter-spacing: .1em; color: var(--ink);
  background: none; border: none; border-radius: 3px; cursor: pointer;
  padding: 14px 12px; transition: background .2s ease, color .2s ease;
}
.menu-item:hover:not(.is-disabled) { background: rgba(211, 181, 120, .1); color: var(--accent); }
.menu-item.is-disabled { color: rgba(197, 187, 163, .32); cursor: not-allowed; }
/* 語言切換 */
.menu-lang { margin-top: auto; padding: 18px 12px 6px; border-top: 1px solid var(--line); }
.menu-lang-label {
  font-family: var(--sans); font-size: 10.5px; letter-spacing: .26em;
  color: var(--accent-dim); margin-bottom: 10px;
}
.menu-lang-row { display: flex; flex-wrap: wrap; gap: 7px; }
.lang-opt {
  font-family: var(--sans); font-size: 12.5px; letter-spacing: .04em;
  color: var(--ink-dim); background: rgba(255, 255, 255, .03);
  border: 1px solid var(--line); border-radius: 3px;
  padding: 6px 10px; cursor: pointer; transition: all .2s ease;
}
.lang-opt:hover { color: var(--ink); border-color: var(--accent-dim); }
/* 選中的語言：色調對齊 .btn.primary（站主 2026-09 指出原本 #ffdd66／#f5c542
   太黃太亮，跟站上其他「已選定」的金色調不是同一套——改用同一組古銅金漸層，
   跟主要按鈕、被選中的工具鈕看起來才是同一個系統。 */
.lang-opt.on {
  color: #171207; background: linear-gradient(180deg, #e0c384 0%, #c8aa66 60%, #b3945a 100%);
  border-color: #ecd7a0; text-shadow: none;
}
/* 每顆語言鈕用**它自己那個語言**的字型堆疊（特異度比上面的 .lang-opt 高，
   所以蓋掉那條的 var(--sans)）。
   為什麼不能只吃 var(--sans)：那個變數是「當前頁面語系」的堆疊，而這一排鈕
   同時寫著四種文字。繁中頁面的堆疊是 Songti TC／PingFang TC——兩者都沒有諺文，
   後面的 -apple-system 與 sans-serif 在 iOS 上也接不到韓文字型，於是「한국어」
   三個字全部變成豆腐格（站主 2026-08 在 iPhone 上抓到）。
   「日本語」剛好三個字都是漢字、中文字型畫得出來，所以一直沒露出來——
   但那是中文字形而不是日文字形，順手一起指定對。
   ⚠ 這不是 App 專屬問題：網頁版的 iOS／macOS 使用者看到的是同一格豆腐。
   按鈕上的 lang 屬性由 js/app.js 產生（見 langRow 那段），選擇器靠它。 */
.lang-opt[lang^="ko"] {
  font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR',
    'Nanum Gothic', sans-serif;
}
.lang-opt[lang^="ja"] {
  font-family: 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', YuGothic,
    'Noto Sans JP', sans-serif;
}
.lang-opt[lang^="zh"] {
  font-family: 'Noto Sans TC', 'PingFang TC', 'Microsoft JhengHei', sans-serif;
}

/* 選單的贊助區：與上面的語言區用一條金線隔開（同 .menu-lang 的分隔語彙）。
   兩顆都是一般樣式（不帶 .btn.primary）——站主 2026-09 試過兩顆都金色填滿，
   覺得「好啦抖內」不必特別搶眼，改回跟「投餵開發者」同一個份量。
   .btn 的字距（.24em）在 300px 的窄面板裡會讓英文那顆貼邊，這裡收斂一階。 */
.menu-sponsor {
  margin-top: 14px; padding: 16px 12px 4px; border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 10px;
}
.menu-sponsor .btn {
  display: block; text-align: center; text-decoration: none;
  font-size: 14px; letter-spacing: .08em; text-indent: .08em; padding: 12px 10px;
}
/* App 版整塊藏（.is-native 規則指的是 .menu-item-coffee，兩顆都中；
   容器只剩線與留白，一併收掉才不會多一條孤零零的金線） */
.is-native .menu-sponsor { display: none !important; }
/* 隱私政策（選單最後一項）：法務入口，不該跟功能項目搶注意力，
   所以字級小一級、顏色暗一階，並用一條上緣金線與上面的功能區隔開。
   App 版看到的位置一樣，只是它上面那顆贊助鈕被 .is-native 藏起來了。 */
.menu-item-legal {
  font-family: var(--sans); font-size: 12.5px; letter-spacing: .06em;
  color: var(--ink-faint); padding: 12px;
  margin-top: 12px; border-top: 1px solid var(--line);
}
.menu-item-legal:hover { color: var(--ink-dim); background: rgba(211, 181, 120, .06); }

/* ---- 分析中的等待提示 ／ 解讀失敗頁 ---- */
/* ---- 分析中：階段進度 ---- */
.weave-stage { margin-top: 26px; text-align: center; }
.weave-stage-text {
  font-family: var(--serif); font-size: 17px; line-height: 1.8;
  color: var(--ink-dim); max-width: 22em; margin: 0 auto; min-height: 1.8em;
}
.weave-dots { display: flex; justify-content: center; gap: 7px; margin: 12px 0 8px; }
.weave-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: rgba(214, 183, 122, .22); transition: background .5s, box-shadow .5s;
}
.weave-dot.on { background: var(--accent-dim); box-shadow: 0 0 7px rgba(224, 193, 132, .45); }
.weave-stage-sub {
  font-family: var(--sans); font-size: 13.5px; line-height: 1.7;
  color: var(--ink-faint); max-width: 20em; margin: 0 auto; min-height: 1.7em;
}

/* ---- 分析中：輪播小提示 ---- */
.weave-tip {
  max-width: 22em; margin: 26px auto 0; padding: 18px 20px 20px;
  border: 1px solid rgba(214, 183, 122, .18); border-radius: 3px;
  background: linear-gradient(180deg, rgba(10, 15, 24, .68), rgba(8, 12, 20, .78));
  box-shadow: inset 0 0 22px rgba(0, 0, 0, .4);
  opacity: 0; transition: opacity .26s ease;
  /* 高度壓住，內容垂直居中。
     分析中那一頁改成垂直居中之後（見 #screenWeaving.active），小知識每次輪播
     換一則、行數不同（實測 390px 上 2–4 行、320px 上到 5 行），整個區塊就會跟著
     上下跳——居中之前不會，因為那時候靠上排，框往下長不影響上面的星軌。
     所以把框固定成最長那一則的高度，短的那幾則就讓文字在框裡居中。
     這不是為了填空：文字居中之後它讀起來是「一塊安靜的面板」，
     而不是「一段字底下空了兩行」。 */
  min-height: 12em;
  display: flex; flex-direction: column; justify-content: center;
}
.weave-tip.show { opacity: 1; }
/* 未輪播到第一則前真的不顯示（避免 hidden 被 padding/border 撐出空框） */
.weave-tip[hidden] { display: none; }
.weave-tip-label {
  font-family: var(--sans); font-size: 12px; letter-spacing: .16em;
  color: var(--accent-dim); margin-bottom: 9px;
}
.weave-tip-text {
  font-family: var(--serif); font-size: 15.5px; line-height: 1.85;
  color: var(--ink-dim); text-wrap: balance;
}

.err-wrap { padding-top: max(12vh, var(--sky-text)); }
.err-wrap .lede { max-width: 24em; margin: 0 auto 26px; }
.err-wrap .fineprint { margin-top: 22px; }

/* ---- 探索工具介紹 ---- */
/* ---- 專屬靈感牌卡 ---- */
/* ---- 後台：靈感牌卡審核 ---- */
.oa-count {
  font-family: var(--sans); font-size: 12.5px; color: var(--ink-faint); letter-spacing: .1em;
}
.oa-count + .oa-count { margin-left: 14px; }
/* 今天有失敗才變色。平常不上色——每天都紅的話等於沒有標記。 */
.oa-count-bad { color: #e6a2a2; }
.oa-count-bad b { color: #f0b4b4; font-weight: 600; }
.oa-list { display: flex; flex-direction: column; gap: 16px; margin-top: 14px; }
.oa-card {
  border: 1px solid var(--line); border-radius: 4px; padding: 16px 18px;
  background: rgba(10, 15, 24, .55);
}
.oa-meta {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: baseline;
  font-family: var(--sans); font-size: 12px; color: var(--ink-faint);
  padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--line);
}
.oa-meta code { color: var(--accent-dim); font-size: 11.5px; }
.oa-ms { color: var(--ink-faint); opacity: .8; }
.oa-noimg { color: #d9a08a; }

/* 後台：使用者面前擺過的候選句。被選中的那一句要一眼看得出來，
   但**沒被選的那幾句才是要讀的**——它們說明模型寫得夠不夠好。 */
.oa-pickopt {
  padding: 9px 11px; margin-bottom: 7px; border-radius: 7px;
  border: 1px solid rgba(255, 255, 255, .07);
  background: rgba(255, 255, 255, .02);
}
.oa-pickopt.on {
  border-color: rgba(226, 201, 150, .45);
  background: rgba(226, 201, 150, .06);
}
.oa-pickmark { font-size: 11px; color: #8d94a3; margin-bottom: 4px; letter-spacing: .04em; }
.oa-pickopt.on .oa-pickmark { color: #e2c996; }
.oa-pickline { font-size: 13px; line-height: 1.55; }
.oa-picklocal { font-size: 12.5px; color: #a9b0bd; margin-top: 3px; line-height: 1.6; }
.oa-pickwhy { font-size: 11.5px; color: #7f8797; margin-top: 4px; line-height: 1.6; }
/* 「合成重試」不是失敗——那一筆是成功的，使用者手上有卡。用另一個顏色，
   免得在清單上掃過去時跟「合成失敗」「生圖失敗」混成同一類。 */
.oa-retry { color: #9db9a6; }
/* 兩欄：左邊是欄位名，右邊是內容。窄螢幕改成上下排 */
.oa-row { display: grid; grid-template-columns: 108px 1fr; gap: 14px; margin-bottom: 14px; }
.oa-k {
  font-family: var(--sans); font-size: 11.5px; letter-spacing: .14em;
  color: var(--accent-dim); padding-top: 3px;
}
.oa-len { display: block; margin-top: 4px; color: var(--ink-faint); letter-spacing: .06em; }
.oa-v { font-family: var(--serif); font-size: 14.5px; line-height: 1.85; color: var(--ink-dim); }
/* 靈魂精髓是所有東西的源頭，所以在視覺上也給它最高的權重 */
.oa-essence .oa-v {
  color: var(--ink); font-size: 15.5px;
  border-left: 2px solid rgba(214, 183, 122, .5); padding-left: 12px;
}
.oa-title { color: var(--ink); font-size: 16px; letter-spacing: .06em; }
.oa-kw { font-family: var(--sans); font-size: 11.5px; letter-spacing: .18em; color: var(--accent-dim); margin: 5px 0 6px; }
.oa-msg { font-size: 14px; }
.oa-long p { margin-bottom: 9px; }
.oa-long p:last-child { margin-bottom: 0; }
.oa-more { margin-bottom: 8px; }
.oa-more summary {
  font-family: var(--sans); font-size: 12px; color: var(--ink-faint);
  cursor: pointer; padding: 4px 0;
}
.oa-more summary:hover { color: var(--accent-dim); }
/* 候選句的「其餘 N 句」：這一顆比別的 <details> 值得被看見一點——站主要判斷
   「句子寫得好不好」，跳過的那幾句比選中的那一句更有訊息，所以摘要不要淡到
   像註腳。但仍然預設收起：九句 × 三行會把一筆紀錄撐成整個螢幕高。 */
/* 複製鈕長在 <details> 外面：站主最常做的事是「複製整段貼到別的 LLM」，
   而讀它反而不常做。所以按鈕永遠看得到，長長的內文才收起來。
   flex 讓按鈕與 summary 對齊在同一行；details 要 min-width:0，
   不然裡面那個會橫向捲動的 <pre> 會把整條撐寬、把按鈕擠出畫面。 */
.oa-copyscope { display: flex; align-items: flex-start; gap: 10px; }
.oa-copyscope > details { flex: 1; min-width: 0; }
.oa-copyscope > .oa-copy { flex: none; margin-top: 2px; }

/* ---- 來訪速覽（回饋與靈感卡兩頁共用）----
   這一塊只為了「他原本問了什麼」存在，所以問題本身用最大的字級、其餘（回訪、
   靈感卡、回饋、時間、ID）壓成註腳大小——展開時眼睛要先落在問題上，而不是在
   一排 ID 裡找它。左緣的色帶跟「靈魂精髓」同一套語彙：那是源頭。 */
.vp-q {
  font-family: var(--serif); font-size: 15.5px; line-height: 1.9; color: var(--ink);
  border-left: 2px solid rgba(214, 183, 122, .5); padding-left: 12px; margin: 6px 0 8px;
  white-space: pre-wrap; word-break: break-word;
}
.vp-meta, .vp-ids {
  font-family: var(--sans); font-size: 11.5px; line-height: 1.9; color: var(--ink-faint);
}
.vp-ids code { color: var(--accent-dim); font-size: 11px; }
/* 「使用紀錄」表頭那幾樣：每一格是「名稱＋值」，名稱淡、值亮，一排掃過去就
   知道有沒有卡、有沒有回饋、是第幾次來。空的格子不畫（見 vpTag）。 */
.vp-tags { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 6px 0; }
.vp-tag {
  display: inline-flex; align-items: baseline; gap: 5px;
  font-size: 11.5px; color: var(--ink-dim);
  border: 1px solid var(--line); border-radius: 2px; padding: 2px 8px;
}
.vp-tag .vp-tk { color: var(--ink-faint); font-size: 11px; }
.vp-act { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }

/* 點得下去的訪客 ID：在回饋卡的頁腳與靈感卡的表頭各出現一次，兩邊都是
   「點他就看得到他問了什麼」，所以長得一樣。 */
.vp-btn {
  display: inline-flex; align-items: baseline; gap: 6px;
  font: inherit; color: var(--ink-dim); background: none;
  border: 1px solid var(--line); border-radius: 2px; padding: 1px 7px; cursor: pointer;
}
.vp-btn:hover { color: var(--accent); background: rgba(224, 193, 132, .07); }
.vp-btn.on { color: var(--accent); border-color: var(--accent-dim); background: rgba(224, 193, 132, .1); }
.vp-btn code { color: var(--accent-dim); font-size: 11px; }
.vp-btn:hover code, .vp-btn.on code { color: var(--accent); }
/* 提示字：說明「這顆按下去會發生什麼」。第一次看到才需要，所以壓得比 ID 更小。 */
.vp-cue { font-size: 10.5px; color: var(--ink-faint); }
.vp-btn:hover .vp-cue, .vp-btn.on .vp-cue { color: var(--accent-dim); }
.vp-dim { margin-left: 10px; }
.vp-box { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); }
/* 反查那一塊的摘要比別的 <details> 值得被看見一點：判斷「這一句提煉得準不準」
   的第一步就是去看他問了什麼，所以摘要不要淡到像註腳。 */
.oa-src > summary { color: var(--accent-dim); font-size: 12.5px; }
.oa-src > summary:hover { color: var(--accent); }

.oa-pickmore { margin-top: 8px; }
.oa-pickmore > summary { color: var(--accent-dim); font-size: 12.5px; }
.oa-pickmore > summary:hover { color: var(--accent); }
.oa-pre {
  font-family: var(--sans); font-size: 12.5px; line-height: 1.85;
  color: var(--ink-dim); white-space: pre-wrap; word-break: break-word;
  background: rgba(0, 0, 0, .25); border-radius: 3px; padding: 10px 12px; margin-top: 6px;
}
/* 圖像 prompt 是英文，強制左至右並用等寬字，方便逐字比對 */
.oa-ltr { direction: ltr; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
/* 對外開關。狀態要一眼看得出來，所以左緣用一條色帶：關著是灰的、開著是金的。
   只用文字的話，站主掃過去很容易看錯自己現在是開還是關。 */
.osw {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 16px; border: 1px solid rgba(214, 183, 122, .18); border-radius: 3px;
  border-left: 3px solid rgba(160, 160, 160, .45);
  background: linear-gradient(180deg, rgba(10, 15, 24, .7), rgba(8, 12, 20, .82));
  margin-bottom: 8px;
}
.osw.on { border-left-color: var(--accent); }
.osw-label { font-family: var(--sans); font-size: 13.5px; color: var(--ink); letter-spacing: .06em; }
.osw-state { font-family: var(--sans); font-size: 12.5px; color: var(--ink-faint); margin-top: 4px; }
.osw.on .osw-state { color: var(--accent-dim); }
.osw .btn { flex: none; }

/* 用量與成本：數字用等寬字才對得齊，掃一眼就能比較幾張之間的差異 */
.oa-usage { font-family: var(--sans); font-size: 12.5px; line-height: 2; }
.oa-usage > div { color: var(--ink-dim); font-variant-numeric: tabular-nums; }
/* 標籤固定寬度，右邊的 token 數字才對得齊（兩行一眼就能比較） */
.oa-ulab { display: inline-block; min-width: 12.5em; color: var(--ink-faint); }
.oa-usub { margin-left: 14px; color: var(--ink-faint); font-size: 11.5px; }
.oa-utotal { margin-top: 4px; color: var(--accent-dim) !important; }
.oa-cost {
  font-family: var(--sans); font-size: 11.5px; color: var(--accent-dim);
  font-variant-numeric: tabular-nums;
}
/* 原始 prompt 很長（約 3 萬字，整副牌都在裡面），所以給固定高度＋自己滾，
   否則一展開就把整頁推到幾十個螢幕高，別的紀錄都找不到了。 */
.oa-promptdump {
  max-height: 420px; overflow-y: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px;
  line-height: 1.7;
}
/* 一鍵複製：標籤在左、複製鈕在右，下面才是那一段 prompt。
   刻意不用絕對定位把按鈕壓在文字右上角——prompt 常常很長又要捲動，
   壓在上面的按鈕會跟著蓋住第一行。 */
.oa-copybox { margin-top: 10px; }
.oa-copyhead {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 2px;
}
.oa-copylab {
  font-family: var(--sans); font-size: 11.5px; letter-spacing: .1em;
  color: var(--accent-dim);
}
/* 按鈕的字會換成「已複製 N 字 ✓」，寬度別跟著跳 */
.oa-copy { min-width: 8.5em; flex: none; }
/* 兩張圖並排：左邊是圖像模型畫的原始畫作、右邊是合成後的卡，對照 prompt 用 */
.oa-imgbox { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-start; }
.oa-imgcap { font-family: var(--sans); font-size: 11.5px; color: var(--ink-faint); margin-bottom: 5px; }
.oa-img { display: block; width: 100%; max-width: 240px; height: auto; border-radius: 3px; }
@media (max-width: 720px) {
  .oa-row { grid-template-columns: 1fr; gap: 4px; }
  .oa-k { padding-top: 0; }
  .oa-len { display: inline; margin-left: 8px; }
}

/* 功能被關閉時的「即將開放」 */
.oc-soon {
  font-family: var(--serif); font-size: 16px; line-height: 2;
  color: var(--ink-dim); text-align: center; padding: 46px 10px 30px;
}
/* 貼上一則解讀的那張表單（.oc-lede／.oc-panel／.oc-field／.oc-label／
   #oracleReading／.oc-note／.oc-actions-sub）連同整頁已於 2026-08 刪除——
   牌卡只剩結果頁那一個入口，畫在彈出視窗裡。 */
.oc-hint {
  margin-top: 8px;
  font-family: var(--sans); font-size: 12px; line-height: 1.8; color: var(--ink-faint);
}
/* 用量：主要按鈕下方一行小字，不搶注意力 */
.oc-usage {
  font-family: var(--sans); font-size: 12px; letter-spacing: .1em;
  color: var(--ink-faint); text-align: center;
}
.oc-err { font-family: var(--sans); font-size: 13px; color: #d9a08a; text-align: center; margin-top: 14px; }
.oc-err-block { margin: 30px 0; line-height: 1.9; }
.oc-actions { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; padding: 24px 0 10px; }

/* 生成中：一個緩慢呼吸的光點。圖像生成要等 20–40 秒，畫面必須有東西在動，
   不然使用者會以為卡住了（跟「分析中」那頁同一個判斷）。 */
/* 牌卡的生成中畫面直接套 .weaving（探索工具那一套星軌與階段列），這裡只調上緣：
   彈出視窗自己已經有邊距，不需要 .weaving 原本那 8vh 的留白。 */
.oc-weaving { padding-top: 2vh; }

/* 牌卡本身是象牙白的實體卡，不套站上的深色面板——讓它看起來像一張卡躺在星圖上 */
.oc-card-wrap { display: flex; justify-content: center; padding: 4px 0 30px; }
.oc-card-img {
  width: 100%; max-width: 340px; height: auto; border-radius: 4px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .55), 0 0 0 1px rgba(214, 183, 122, .18);
}
/* 牌卡下方的譯文區：卡面是英文，這裡是使用者語言的版本（英文使用者＝原文）。
   圖沒生出來時，這一塊就是讀者唯一看得到卡面內容的地方。 */
.oc-trans { text-align: center; margin: 2px 0 26px; }

/* ── 挑句子（2026-08）── */
/* 按下「製作專屬靈感卡」之後的第一關：三句候選，最多三輪＝九句，只能選一句。 */

/* 讀解讀時的等待：刻意比生成卡片那套星軌輕。那一套的份量代表「要等比較久的
   大事」，這裡通常十幾秒就回來，用同一套反而讓人以為卡住了。 */

.oc-pick-h {
  font-size: 17px; font-weight: 500; text-align: center;
  margin: 4px 0 6px; color: var(--ink); letter-spacing: .02em;
}
.oc-pick-sub {
  font-size: 13px; text-align: center; color: var(--ink-soft);
  margin: 0 auto 20px; max-width: 22em; line-height: 1.7; text-wrap: balance;
}
.oc-opts { display: flex; flex-direction: column; gap: 10px; }

/* 一句一格。整格都可以按——手機上句子有三四行，只讓某個小圓點可按很難戳中。 */
.oc-opt {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 15px 16px 14px; border-radius: 10px;
  border: 1px solid rgba(226, 201, 150, .2);
  background: rgba(255, 255, 255, .028);
  color: inherit; font: inherit;
  transition: border-color .18s ease, background .18s ease;
}
.oc-opt:hover { border-color: rgba(226, 201, 150, .38); background: rgba(255, 255, 255, .05); }
/* 選中：金線加粗＋左緣一道實金，掃過去一眼就看得出選了哪一格。
   不用勾勾圖示——那會讓它看起來像待辦清單，可以多選。 */
.oc-opt.on {
  border-color: rgba(226, 201, 150, .62);
  background: rgba(226, 201, 150, .07);
  box-shadow: inset 3px 0 0 rgba(226, 201, 150, .68);
}
.oc-opt-en {
  display: block; font-size: 15px; line-height: 1.55;
  color: var(--ink); letter-spacing: .01em;
}
.oc-opt-local {
  display: block; margin-top: 7px; font-size: 13px;
  line-height: 1.7; color: var(--ink-soft);
}

/* 送出鈕黏在視窗底部。九句排下來比視窗高（.ocm-box 是 92vh 捲動的），
   不黏住的話使用者選完還要往下捲才找得到送出——選了卻不知道怎麼送出，
   是最容易讓人以為壞掉的一種。負邊距是為了貼齊面板內緣（面板左右 20、下 24）。 */
/* bottom 是 -24px 而不是 0：sticky 的貼齊基準是捲動容器的**內容盒**，而 .ocm-box
   下緣還有 24px 的內距。寫 0 的話按鈕會停在內距上方，下面露出一條 24px 的縫，
   後面那一句從縫裡透出來——看起來像按鈕浮在半空中。負值把它推到內距底下貼齊，
   它自己的 padding-bottom 正好把那塊補起來。（一次列滿九句之後一定會捲動，
   所以這條縫是每一次都看得到，不是邊角情況。） */
.oc-pick-act {
  position: sticky; bottom: -24px; z-index: 1;
  display: flex; flex-direction: column; gap: 10px;
  margin: 22px -20px -24px; padding: 14px 20px 24px;
  background: rgba(10, 15, 24, .97);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
}
/* 上緣一道漸層，讓捲動中的句子淡出而不是被一條硬邊切斷 */
.oc-pick-act::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 100%; height: 24px;
  background: linear-gradient(to top, rgba(10, 15, 24, .97), rgba(10, 15, 24, 0));
  pointer-events: none;
}
.oc-pick-act .btn { width: 100%; }
.oc-pick-act .btn:disabled { opacity: .42; cursor: default; }
.oc-t-title { font-family: var(--serif); font-size: 22px; letter-spacing: .14em; color: var(--ink); }
.oc-t-title + .oc-t-msg { margin-top: 12px; }
/* 刻意不用 italic：中日韓字型沒有真正的斜體，瀏覽器會機械地把字斜過去，
   看起來是歪的而不是斜的。改用字級與顏色與上下文區隔。
   （卡面上的英文句子仍然用 italic——英文有真的斜體字。） */
.oc-t-msg {
  font-family: var(--serif); font-size: 15.5px; line-height: 1.95;
  color: var(--ink);
  /* 這一句常常剛好排不下一行，第二行只剩兩三個字，看起來像斷掉。balance 讓瀏覽器
     在不增加行數的前提下把兩行排得一樣長。舊瀏覽器不認得就當沒寫，維持原本的貪心
     斷行——不會壞，只是沒變好。（卡面上那句英文在 SVG 裡，沒有這個屬性可用，
     所以 js/oracleCard.js 的 wrapLatin() 自己算了一份同樣邏輯的平衡斷行。） */
  text-wrap: balance;
}
/* 牌義的第一段（核心訊息）：牌組原文，是這張牌最核心的一兩句，所以比洞見重一級。
   左側金線與後台的精髓欄同一個手法——一眼就知道這一段的份量不一樣。 */
.oc-essence {
  border-left: 2px solid var(--accent-dim);
  padding-left: 14px; margin: 0 0 22px;
}
.oc-essence p {
  font-family: var(--serif); font-size: 16.5px; line-height: 1.95;
  color: var(--ink); margin: 0;
}
.oc-long p {
  font-family: var(--serif); font-size: 16px; line-height: 2.05;
  color: var(--ink-dim); margin-bottom: 16px;
}

.guide-wrap { padding-top: max(9vh, var(--sky-text)); }
.gd-h2 {
  font-family: var(--serif); font-size: 20.5px; color: var(--ink);
  letter-spacing: .06em; text-align: center; margin-bottom: 12px;
}
.gd-lede {
  font-family: var(--serif); font-size: 16.5px; line-height: 1.95;
  color: var(--ink-dim); margin-bottom: 14px;
}
.gd-overview .gd-lede { text-align: center; max-width: 28em; margin: 0 auto 20px; }

/* 速覽卡：三種工具的差異，滑一下就看完 */
.gd-cards { display: flex; flex-direction: column; gap: 10px; margin-bottom: 6px; }
.gd-card {
  padding: 14px 16px; border: 1px solid rgba(214, 183, 122, .26); border-radius: 3px;
  background: linear-gradient(180deg, rgba(10, 15, 24, .74), rgba(8, 12, 20, .86));
  box-shadow: inset 0 0 22px rgba(0, 0, 0, .4);
}
.gd-card-name {
  font-family: var(--serif); font-size: 17px; color: var(--accent);
  letter-spacing: .04em; margin-bottom: 5px;
}
.gd-mark { margin-right: 7px; opacity: .8; }
.gd-card-line { font-family: var(--sans); font-size: 14.5px; line-height: 1.75; color: var(--ink-dim); }

/* 各工具的詳細介紹 */
.gd-sec { margin: 4px 0; }
.gd-sec-name {
  font-family: var(--serif); font-size: 19.5px; color: var(--accent);
  letter-spacing: .06em; text-align: center; margin-bottom: 14px;
}
.gd-label {
  font-family: var(--sans); font-size: 12.5px; letter-spacing: .24em;
  color: var(--accent-dim); margin: 18px 0 8px;
}
/* 起源／使用系統與參考提問的內文，與簡介（.gd-lede）用同一級字體與顏色，
   整頁的正文才是一致的一種聲音 */
.gd-meta-text {
  font-family: var(--serif); font-size: 16.5px; line-height: 1.95; color: var(--ink-dim);
}
.gd-meta-text b { color: var(--ink); font-weight: normal; }
.gd-ask-list, .gd-rows { list-style: none; }
.gd-ask-list li, .gd-row {
  position: relative; padding-left: 18px; margin-bottom: 8px;
  font-family: var(--serif); font-size: 16.5px; line-height: 1.95; color: var(--ink-dim);
}
.gd-ask-list li::before, .gd-row::before {
  content: '·'; position: absolute; left: 3px; color: var(--accent-dim);
}
.gd-rows { margin-bottom: 16px; }
.gd-row-name { color: var(--accent); margin-right: 6px; }
.gd-row-name::after { content: '：'; color: var(--ink-faint); }
.gd-example-q {
  font-family: var(--serif); font-size: 17px; line-height: 1.9; color: var(--ink);
  padding: 12px 14px; margin-bottom: 16px;
  border-left: 2px solid var(--accent-dim); background: rgba(214, 183, 122, .06);
}
.gd-actions { display: flex; justify-content: center; padding: 26px 0 30px; }
@media (max-width: 560px) {
  .gd-row-name { display: block; margin-bottom: 2px; }
  .gd-row-name::after { content: ''; }
}

/* ---- 占卜觀 ---- */
/* 與「探索工具介紹」共用整頁的節奏（reading-wrap ＋ rule-orn 分隔），
   但這一頁是一篇說理，不是清單——所以正文行距放到 2.05，段距也拉開，
   讓每一段之間有停頓感。 */
.divination-wrap { padding-top: max(9vh, var(--sky-text)); }

/* 開場的水晶球：站主原稿標題上帶的 🔮。放大、置中、單獨一行，
   當成這一頁的裝飾印記，而不是句子裡的一個表情符號。 */
.dv-sigil { font-size: 28px; text-align: center; margin-bottom: 12px; opacity: .9; }
.dv-h2 {
  font-family: var(--serif); font-size: 20.5px; line-height: 1.7; color: var(--ink);
  letter-spacing: .04em; text-align: center; margin-bottom: 22px;
}
.dv-p {
  font-family: var(--serif); font-size: 16.5px; line-height: 2.05;
  color: var(--ink-dim); margin-bottom: 18px;
}
.dv-p:last-child { margin-bottom: 0; }
/* rule-orn 只有下邊距，所以上一段的呼吸空間由這裡給——否則正文會貼著金線 */
.dv-intro, .dv-belief-sec { margin: 4px 0 26px; }

/* 三條信念：與工具介紹的速覽卡同一種語彙（金線細框＋✦），
   一眼就能讀完，也和上下的段落拉出對比。 */
.dv-label {
  font-family: var(--sans); font-size: 12.5px; letter-spacing: .24em;
  color: var(--accent-dim); text-align: center; margin: 4px 0 12px;
}
.dv-lead {
  font-family: var(--serif); font-size: 16.5px; line-height: 1.95;
  color: var(--ink); text-align: center; margin-bottom: 14px;
}
.dv-beliefs { list-style: none; display: flex; flex-direction: column; gap: 10px; margin-bottom: 22px; }
.dv-belief {
  position: relative; padding: 14px 16px 14px 40px;
  border: 1px solid rgba(214, 183, 122, .26); border-radius: 3px;
  background: linear-gradient(180deg, rgba(10, 15, 24, .74), rgba(8, 12, 20, .86));
  box-shadow: inset 0 0 22px rgba(0, 0, 0, .4);
  font-family: var(--serif); font-size: 16.5px; line-height: 1.85; color: var(--ink);
}
.dv-belief .dv-mark {
  position: absolute; left: 16px; top: 14px;
  color: var(--accent); opacity: .85;
}

/* 核心命題：整頁真正想問的一句話。
   與底下的引言塊（.dv-quote）刻意走**不同的強調軸線**——這裡是顏色＋置中，
   像一句刻上去的提問；那裡是區塊＋左金線，像一段引文。兩個都做成大字會互相
   打架，讀者就不知道該看哪一個。
   上下的細線用 .rule-orn 同一種兩端淡出的漸層，維持整站同一套裝飾語彙。 */
.dv-p-lead { margin-bottom: 10px; }
.dv-focus {
  position: relative;
  font-family: var(--serif); font-size: 18.5px; line-height: 1.95;
  color: var(--accent); letter-spacing: .04em; text-align: center;
  /* 32em＝桌機上這一句剛好排得下一行；手機放不下時由 text-wrap: balance 拆成
     兩行等長。刻意不設更窄，否則桌機也會被迫斷成兩行。 */
  max-width: 32em; margin: 0 auto; padding: 24px 8px;
  /* 置中的多行句子要讓每一行長度接近，否則會出現「第二行只剩幾個字」的畫面。
     不支援的瀏覽器就是原本的斷行，不會壞。 */
  text-wrap: balance;
  /* 這一句是金色的，而星圖有些地方很亮——比整站那層通用陰影再多一圈暗halo，
     確保它落在星盤亮核上也讀得清楚。 */
  text-shadow: 0 1px 4px rgba(3, 7, 13, .9), 0 0 18px rgba(5, 8, 13, .75);
}
.dv-focus::before, .dv-focus::after {
  content: ''; position: absolute; left: 50%; transform: translateX(-50%);
  width: 180px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(214, 183, 122, .55), transparent);
}
.dv-focus::before { top: 0; }
.dv-focus::after { bottom: 0; }
/* 韓文有詞間空白，預設的 CJK 斷行規則卻允許在詞中間斷（實測斷出「진／짜」）。
   keep-all 讓它只在空白處斷。中日文不能這樣設——它們整句沒有空白，keep-all
   會變成一整條不可斷的字串而衝出版心，所以只掛在韓文上。 */
html[lang^="ko"] .dv-focus { word-break: keep-all; }

/* 翻書那一段：全篇的比喻核心，值得自己一塊地方。 */
.dv-quote {
  font-family: var(--serif); font-size: 18px; line-height: 2.05; color: var(--ink);
  padding: 18px 20px; margin: 26px 0 22px;
  border-left: 2px solid var(--accent-dim);
  background: rgba(214, 183, 122, .06);
}
/* 收束一句：置中、字色回到最亮的一階，讀完就停在這裡。 */
.dv-closing {
  font-family: var(--serif); font-size: 17px; line-height: 2.05; color: var(--ink);
  text-align: center; max-width: 30em; margin: 0 auto;
}
@media (max-width: 560px) {
  /* 這一句夠短，手機上維持置中（.dv-closing 那段長，置中會變成參差的鋸齒） */
  .dv-focus { font-size: 17.5px; padding: 20px 4px; }
  .dv-quote { padding: 16px 14px; font-size: 17px; }
  .dv-closing { text-align: left; }
}

/* ---- 我的靈感訊息（歷史列表） ---- */
.history-wrap { padding-top: max(9vh, var(--sky-text)); }
.hist-empty {
  text-align: center; font-family: var(--serif); color: var(--ink-dim);
  font-size: 15px; line-height: 2; margin-top: 40px;
}
/* 工具列：筆數 ＋ 全部清空 */
.hist-bar {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px; padding-bottom: 10px; border-bottom: 1px solid var(--line);
}
.hist-count { font-family: var(--sans); font-size: 12px; letter-spacing: .1em; color: var(--ink-dim); }
.hist-clear {
  font-family: var(--sans); font-size: 12px; letter-spacing: .08em;
  color: var(--ink-dim); background: none; border: 1px solid var(--line);
  border-radius: 3px; padding: 7px 12px; cursor: pointer; transition: all .2s ease;
}
.hist-clear:hover { color: #e0a0a0; border-color: rgba(224, 160, 160, .5); }
.hist-clear.confirm { color: #e8b0b0; border-color: rgba(224, 140, 140, .65); background: rgba(90, 40, 40, .28); }

.hist-card {
  display: flex; align-items: stretch;
  background: rgba(10, 15, 24, .72); backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  border: 1px solid var(--line); border-radius: 3px;
  box-shadow: 0 0 18px rgba(0, 0, 0, .3);
  margin-bottom: 14px; overflow: hidden; transition: border-color .2s ease, background .2s ease;
}
.hist-card:hover { border-color: var(--accent-dim); background: rgba(15, 23, 36, .8); }
.hist-open {
  flex: 1; min-width: 0; text-align: left; cursor: pointer;
  background: none; border: none; padding: 16px 14px 16px 18px;
}
.hist-del {
  flex: 0 0 auto; align-self: stretch; cursor: pointer;
  font-family: var(--sans); font-size: 11.5px; letter-spacing: .06em; line-height: 1.4;
  color: var(--ink-faint); background: rgba(255, 255, 255, .03);
  border: none; border-left: 1px solid var(--line);
  padding: 0 13px; max-width: 88px; transition: all .2s ease;
}
.hist-del:hover { color: #e0a0a0; background: rgba(90, 40, 40, .22); }
.hist-del.confirm { color: #f0bcbc; background: rgba(110, 45, 45, .38); }
.hist-card-title { font-family: var(--serif); font-size: 17px; color: var(--ink); margin-bottom: 6px; }
.hist-card-topic { font-family: var(--serif); font-size: 14px; color: var(--ink-dim); margin-bottom: 8px; }
.hist-card-meta { font-family: var(--sans); font-size: 12px; letter-spacing: .06em; color: var(--accent-dim); }

/* ---- 後台：結果頁預覽（js/admin.js 的 openPreview）---- */
/* 用 iframe 載入正式的結果頁，所以預覽與使用者看到的是同一份渲染程式 */
body.pv-open { overflow: hidden; }
.pv-overlay {
  position: fixed; inset: 0; z-index: 95;
  display: flex; flex-direction: column;
  background: #04070c;
  animation: fadein-soft .18s ease both;
}
.pv-bar {
  flex: none; display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.pv-title { font-family: var(--sans); font-size: 13px; color: var(--ink-dim); }
.pv-title code { color: var(--accent); }
.pv-state { flex: 1; font-family: var(--sans); font-size: 12px; color: var(--ink-faint); }
.pv-stage { flex: 1 1 auto; overflow: hidden; display: flex; justify-content: center; }
/* 固定成手機寬度：站主要體驗的是使用者的畫面，而多數使用者在手機上 */
.pv-frame { width: 100%; max-width: 420px; height: 100%; border: 0; background: #060a11; }
.prev-cell { white-space: nowrap; }

/* ---- 後台：圖庫（js/admin.js 的 renderGallery／openLightbox）---- */
/* 格子固定 2:3（神諭卡比例）：圖還沒載進來時版面就先站好，載入不跳版 */
.ga-grid {
  display: grid; gap: 12px; margin-top: 14px;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
}
.ga-item {
  aspect-ratio: 2 / 3; padding: 0; border-radius: 4px; overflow: hidden;
  border: 1px solid var(--line); background: rgba(224, 193, 132, .04);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  transition: border-color .15s ease, transform .15s ease;
}
.ga-item:hover { border-color: var(--accent-dim); transform: translateY(-2px); }
.ga-ph {
  padding: 8px; font-family: var(--sans); font-size: 12px; line-height: 1.5;
  color: var(--ink-faint); text-align: center; word-break: break-word;
}
.ga-thumb { display: block; width: 100%; height: 100%; object-fit: cover; }

/* 燈箱。z-index 與 .pv-overlay 同層（95）：兩者不會同時開 */
body.ga-lb-open { overflow: hidden; }
.ga-lb {
  position: fixed; inset: 0; z-index: 95;
  display: flex; flex-direction: column;
  background: rgba(4, 7, 12, .96);
  animation: fadein-soft .18s ease both;
}
.ga-lb-bar {
  flex: none; display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.ga-lb-meta { flex: 1; font-family: var(--sans); font-size: 13px; color: var(--ink-dim); }
.ga-lb-meta b { color: var(--accent); font-weight: 600; }
.ga-lb-kind { display: flex; gap: 6px; }
.ga-lb-kind .btn.on { border-color: var(--accent-dim); color: var(--accent); }
.ga-lb-stage {
  flex: 1 1 auto; min-height: 0;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 14px;
}
.ga-lb-imgwrap {
  position: relative; height: 100%; min-width: 0;
  display: flex; align-items: center; justify-content: center;
}
.ga-lb-img {
  max-width: 100%; max-height: 100%; border-radius: 4px;
  transition: opacity .12s ease;
}
.ga-lb-img.dim { opacity: .35; }
.ga-lb-state { position: absolute; font-family: var(--sans); font-size: 13px; color: var(--ink-dim); }
.ga-lb-nav {
  flex: none; width: 44px; height: 72px; border-radius: 4px;
  border: 1px solid var(--line); background: rgba(224, 193, 132, .05);
  color: var(--ink-dim); font-size: 26px; line-height: 1; cursor: pointer;
}
.ga-lb-nav:hover:not(:disabled) { border-color: var(--accent-dim); color: var(--accent); }
.ga-lb-nav:disabled { opacity: .3; cursor: default; }
.ga-lb-count {
  flex: none; padding: 8px 14px 12px; text-align: center;
  font-family: var(--sans); font-size: 12px; letter-spacing: .08em; color: var(--ink-faint);
}
/* 手機：箭頭改浮在圖上，不佔橫幅（滑動翻頁仍然可用） */
@media (max-width: 560px) {
  .ga-lb-stage { padding: 10px; gap: 0; }
  .ga-lb-nav { position: absolute; z-index: 2; height: 56px; width: 38px; }
  .ga-lb-prev { left: 6px; }
  .ga-lb-next { right: 6px; }
  .ga-lb-stage { position: relative; }
}

/* ---- 結果頁的預覽模式橫幅（index.html?preview=1）---- */
.preview-bar {
  margin-bottom: 18px; padding: 12px 14px; border-radius: 3px;
  border: 1px solid rgba(214, 183, 122, .34);
  background: rgba(224, 193, 132, .08);
  font-family: var(--sans); font-size: 12.5px; line-height: 1.75; color: var(--ink-dim);
}
.preview-bar b { color: var(--accent); }
.preview-bar ul { margin: 8px 0 0; padding-left: 18px; }
.preview-bar li + li { margin-top: 4px; }
.preview-err { color: #d9a2a2; font-family: var(--sans); font-size: 13px; }

/* ===== iOS 自動放大（整頁往右偏的真正原因）=====================================
   症狀：站主在 iPhone 上看到整頁往右偏，標題與面板沒有置中，右邊的留白不見了。
   headless 怎麼量都是正的（左右留白 26／26），所以一直對不上。

   原因不在版面，在**縮放**。iOS Safari 只要你點進一個 font-size 小於 16px 的
   輸入框，就會自動把整頁放大 16÷字級 倍好讓你看得清楚在打什麼；而且**失焦之後
   不會縮回去**，也會跨頁面留著。放大是以左緣為錨點，所以右邊的留白被推出畫面外，
   看起來就是「整頁往右偏」。

   量出來的證據（站主的截圖 vs headless 同尺寸同 DPR 的參考圖）：
       面板寬度   362.3 CSS px  ÷  340.0 CSS px  =  1.0665
       16 ÷ 15                              =  1.0667
   對得上，而當時 .af-row 的輸入框正好是 15px。

   所以規則是：**任何會叫出鍵盤的輸入框（input 的文字類 type、textarea）字級一律
   >= 16px**。checkbox／radio 不會叫出鍵盤，不在此限。
   已知曾經違規的：.af-row input（15px）、.fb-text（14px）。

   ⚠ 不要改用 <meta name="viewport" maximum-scale=1> 來擋。那會連使用者自己想
   放大都做不到（無障礙倒退），而且 iOS 10 之後本來就不理這個設定。

   迴歸測試：scratchpad/ios_zoom.mjs
   ============================================================================ */

/* 後台的下拉選單與時間欄位比較小（版面密），桌機維持原字級；
   只有觸控裝置才提到 16px——後台幾乎都在桌機用，不必為了手機改掉整個版面。 */
@media (pointer: coarse) {
  /* 選擇器要壓得過 .flt-select（0,1,0）——只寫 select（0,0,1）比不過它，
     跟原始碼順序無關，是權重輸了。 */
  select, select.flt-select, input[type="datetime-local"] { font-size: 16px; }
}

/* ===== 置中的結構保險 ==========================================================
   置中是相對「文件寬」算的，所以只要有任何一個元素把文件撐寬，全站置中的東西就會
   整組往右移。與其每次去追是哪個元素撐的，不如從結構上讓它不可能發生：
   文件寬永遠不超過視窗寬。

   用 clip 而不是 hidden 是刻意的——hidden 會產生一個捲動容器，會把 position:
   sticky 的表頭與 position: fixed 的選單、星圖背景一起弄壞。clip 只裁切，不建立
   捲動容器，也不會變成 fixed 的包含塊。舊瀏覽器不認得 clip 就整條忽略，維持現狀，
   不會壞。
   ⚠ 這是保險，不是修法。真的溢出時仍然要去修那個元素——被裁掉的內容一樣看不到。
   scratchpad/sweep_all.mjs 會掃四語系 × 六寬度 × 全部畫面，確保沒有東西真的溢出。 */
html { overflow-x: clip; }
body { overflow-x: clip; max-width: 100%; }
.app { max-width: 100%; }

/* ===== 版面診斷面板（index.html?diag=1）===================================== */
#diagPanel {
  position: fixed; left: 8px; right: 8px; top: 8px; z-index: 9999;
  max-height: 88vh; overflow: auto;
  background: rgba(6, 10, 17, .97); color: #e6ddc8;
  border: 1px solid rgba(214, 183, 122, .5); border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .7);
}
.dg-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 10px; border-bottom: 1px solid rgba(214, 183, 122, .28);
  letter-spacing: .12em; color: #e6cd96;
}
.dg-head button {
  background: none; border: none; color: #e6cd96; font-size: 16px;
  cursor: pointer; padding: 0 4px; line-height: 1;
}
.dg-verdict { padding: 10px; line-height: 1.7; border-bottom: 1px solid rgba(214, 183, 122, .2); }
.dg-verdict.dg-ok { color: #9fd6a8; }
.dg-verdict.dg-bad { color: #f0b48a; }
.dg-row {
  display: flex; gap: 8px; padding: 5px 10px; line-height: 1.5;
  border-bottom: 1px solid rgba(255, 255, 255, .05);
}
.dg-k { flex: 1 1 auto; min-width: 0; color: #a89f88; }
.dg-v { flex: 0 0 auto; text-align: right; word-break: break-all; }
.dg-row.dg-ok .dg-v { color: #9fd6a8; }
.dg-row.dg-bad .dg-v { color: #f2a1a1; }
.dg-ua { padding: 8px 10px; color: #7d7565; line-height: 1.5; word-break: break-all; }
.dg-acts { display: flex; gap: 8px; padding: 10px; }
.dg-acts button {
  flex: 1; font: inherit; padding: 9px 6px; cursor: pointer;
  background: rgba(214, 183, 122, .14); color: #e6cd96;
  border: 1px solid rgba(214, 183, 122, .45); border-radius: 3px;
}

/* ===== 靈感卡的彈出視窗（結果頁的「製作專屬靈感卡」）===================== */
/* 站主要的是「比較像是跳出來的一個視窗」。金色星軌的等待動畫也在視窗裡跑，
   所以按下去就看得到它已經開始，不會以為沒反應。 */
body.ocm-open { overflow: hidden; }
.ocm { position: fixed; inset: 0; z-index: 96; display: flex;
  align-items: center; justify-content: center; padding: 18px; }
/* 站主回報「原本的星空背景不見了」。原因是這兩層都幾乎不透明：
   遮罩 .82 再加模糊，面板又是 .98／.99 的漸層——整個站的星圖被蓋掉了。
   兩層都改成半透明，星點就透得上來；文字仍然讀得到，因為星圖本身是深色的
   （站上其他浮層，例如舊的 .oc-panel，用的也是同一套半透明＋模糊的作法）。 */
.ocm-back { position: absolute; inset: 0; background: rgba(4, 7, 12, .5); }
.ocm-box {
  position: relative; z-index: 1; width: 100%; max-width: 400px;
  max-height: 92vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 34px 20px 24px;
  background: rgba(10, 15, 24, .62);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(214, 183, 122, .34); border-radius: 4px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, .55);
  animation: ocmIn .28s ease;
}
/* 視窗裡的小知識：與解讀等待畫面同一份內容，但上緣的距離收一點——
   視窗本身已經有邊距了。 */
.ocm .weave-tip { margin-top: 26px; }
@keyframes ocmIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.ocm-x {
  position: absolute; top: 9px; right: 9px; z-index: 2;
  width: 30px; height: 30px; padding: 0; cursor: pointer;
  background: none; border: none;
}
/* 用兩條線畫叉，不放字元——字元在不同系統上大小差很多 */
.ocm-x::before, .ocm-x::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 14px; height: 1px; background: var(--accent-dim);
}
.ocm-x::before { transform: translate(-50%, -50%) rotate(45deg); }
.ocm-x::after { transform: translate(-50%, -50%) rotate(-45deg); }
.ocm-x:hover::before, .ocm-x:hover::after { background: var(--accent); }
/* 視窗裡的牌卡不必再留 max-width，容器已經夠窄了 */
.ocm .oc-card-wrap { padding: 0 0 20px; }
.ocm .oc-card-img { max-width: 100%; }
/* iOS 網頁版才出現：把「下載圖片」那顆按鈕換成這一句說明。
   長按圖片選「加入照片」是唯一一步到位進相簿的方法（見 js/app.js 的 iosSaveMode）。
   站主 2026-09 定案：**放在圖片正上方、小號金字、兩側細金線、不做框**。
   之前是虛線框、放在分享鈕上方——試過，兩個問題：位置與形狀都像一顆按鈕
   （使用者會一直按，按了沒反應）；而且要捲到最底才看得到，那時圖片早捲出畫面。
   要長按的是圖片，說明就貼著圖片；飾線沿用塔羅進度標題那一套（.tpc-orn），
   細線只是收邊，不會被讀成可以點的東西。 */
.oc-saveinfo {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin: 2px 0 12px;
  font-family: var(--sans); font-size: 12px; line-height: 1.5;
  letter-spacing: .22em; text-indent: .22em;
  color: var(--accent-dim);
}
.oc-saveinfo::before, .oc-saveinfo::after {
  content: ''; flex: none; width: 34px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(214, 183, 122, .55), transparent);
}
/* 「我的靈感卡」那一區共用同一句：那裡標題在上、卡片格在下，說明夾在中間，
   下方留白對齊卡片格的 gap */
.r-mycards .oc-saveinfo { margin: -6px 0 16px; }
/* 等待動畫在視窗裡要有高度，不然星軌會被壓扁 */
.ocm .oc-weaving { min-height: 320px; }

/* ---- 生成途中：攤成全版，讓底下的星圖直接當背景 ----------------------------
   站主：「loading 的畫面可以讓它看起來像全版，不一定要是 dialog…背景請用原本
   網頁的星空圖，比照占卜時的 loading 過場」（＝ index.html 的 #screenWeaving）。
   那一頁之所以看得到星圖，是因為它上面**什麼都沒有蓋**——.sky 是 fixed 的整頁
   底層。所以這裡要做的不是「換一張背景圖」，而是把面板本身讓開：邊框、底色、
   模糊、陰影全部拿掉，星圖就自己上來了。留著半透明底色也不行，那還是一塊布。 */
.ocm.ocm-busy { padding: 0; }
/* 遮罩改成**自己就是星圖**，不是一層半透明的黑。
   為什麼不能只是把黑色調淡：這個遮罩壓在整個站上面，調淡的話底下結果頁的
   九宮格與整段解讀就一起透出來，跟星軌動畫疊在一起（實測過，很亂）；調深的話
   星圖也一起被壓掉，又回到站主說的「都沒有任何圖示」。兩件事只能靠同一層不透明度
   調的話必然二選一，所以直接讓這一層鋪上跟 .sky 一樣的星圖：底下的頁面被完全蓋掉，
   看到的就是星圖，跟占卜的等待畫面（#screenWeaving）長得一樣。
   ⚠ 這裡的圖與塗層是照抄檔案開頭的 .sky／.sky::after，換星圖時兩邊要一起改
   （不能直接合併選擇器：.sky 是 fixed／z-index 0，這一層是視窗裡的 absolute）。 */
.ocm.ocm-busy .ocm-back {
  background: url('../assets/bg-square.jpg') center / cover no-repeat #05070c;
  filter: saturate(1.05);
}
@media (orientation: portrait) {
  .ocm.ocm-busy .ocm-back { background-image: url('../assets/bg-portrait.jpg'); }
}
.ocm.ocm-busy .ocm-back::after {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(closest-side at 50% 45%,
      rgba(5, 8, 13, .42), rgba(5, 8, 13, .26) 55%, rgba(5, 8, 13, .1) 82%, rgba(5, 8, 13, .04)),
    linear-gradient(180deg, rgba(5, 8, 13, .2), rgba(5, 8, 13, 0) 30%, rgba(5, 8, 13, 0) 70%, rgba(5, 8, 13, .26));
}
.ocm.ocm-busy .ocm-box {
  width: 100%; max-width: none; height: 100%; max-height: none;
  /* safe center：內容比視窗高的時候退回從頂端排，不會把上緣切掉捲不到
     （橫放的小手機真的會遇到）。舊瀏覽器解析不了整條就退回 flex-start，
     那也是可以接受的結果。
     ⚠ 直向視窗改成靠上排：這一層鋪的是同一張星圖，居中的話星軌會壓在最上面
     那個金色造型上（跟 #screenWeaving 同一件事，站主 2026-09 指名「製作中」
     那個會轉的圈圈）。淨空線見檔案開頭的 --sky-clear。 */
  display: flex; align-items: safe center; justify-content: center;
  padding: 20px 18px;
  background: none; backdrop-filter: none; -webkit-backdrop-filter: none;
  border: none; box-shadow: none; animation: none;
}
@media (orientation: portrait) {
  .ocm.ocm-busy .ocm-box {
    align-items: flex-start;
    padding-top: max(20px, var(--sky-clear));
  }
}
.ocm.ocm-busy #ocModalHost { width: 100%; max-width: 420px; }
/* 全版之後不必再靠 min-height 撐開，上緣的留白也交給置中 */
.ocm.ocm-busy .oc-weaving { min-height: 0; padding-top: 0; }
/* 生成途中不給關（站主：不要讓它從中途取消）。點背景與 Esc 由 JS 擋，
   叉叉在這裡收起來——留著卻按不動比直接不顯示更糟。 */
.ocm.ocm-busy .ocm-x { display: none; }

/* 「製作專屬靈感卡」的說明句、三顆一排的 .r-actions、「分享給朋友」的說明句
   （.r-act-cell／.r-makecard-hint／.r-sharesite）都在 2026-09 的結尾重排中移除：
   靈感卡鈕改成回饋底下自己一欄（.r-makecard），分享鈕與回到首頁併進 .r-follow。 */

/* ---- 結果頁：這一則做過的靈感卡（純本機，見 js/engine/cards.js） ----
   一則解讀可以做好幾張，所以是格狀排列而不是單張。手機一排一張、寬一點兩張——
   卡是 2:3 直式，一排塞三張的話每一張都會小到看不清卡面的字。 */
.r-mycards {
  margin-top: 10px; padding: 30px 0 6px; text-align: center;
  border-top: 1px solid var(--line);
}
.r-mycards-title {
  font-family: var(--serif); font-size: 16px; color: var(--ink);
  letter-spacing: .08em; margin-bottom: 18px;
}
.r-mycards-grid {
  display: grid; gap: 20px; justify-content: center;
  grid-template-columns: minmax(0, 1fr);
}
/* ⚠ 用 auto-fit，不可以寫成 repeat(2, …)。
   固定兩欄的話，**軌道**永遠是 260＋20＋260＝540px 寬，`justify-content: center`
   置中的是這一整組軌道；只有一張卡時它待在左邊那一欄，於是整塊往左偏 140px。
   站主 2026-08 在桌機上拍到：卡片與按鈕的中心比標題與說明文字左了一大截。
   （日配額是 2，所以「只有一張」是最常見的狀態，不是邊界情況。）
   auto-fit 會把沒有卡片的軌道收成 0 寬並一併收掉它的 gap，一張卡時整組軌道就是
   260px，置中才會落在真正的中間。 */
/* 欄寬 2026-09 由 260 放到 320：每一格現在帶著一整篇三段解讀（不再只是縮圖＋
   一行譯文），260px 的欄寬在 16px 本文下只有 14.6 個中文字一行，擠到不能讀。
   ⚠ 副作用是**桌機上會變成一欄**：.screen 的內容寬最多 616px，放不下
   320＋20＋320＝660。這是刻意的——一格是一篇解讀，並排兩篇反而更難讀。
   auto-fit 保留著，理由見上面那一段（一張卡時的置中）。 */
@media (min-width: 560px) {
  .r-mycards-grid { grid-template-columns: repeat(auto-fit, minmax(0, 320px)); }
}
.mycard { margin: 0; }
/* 卡片本身是白的，直接放在深色星圖上會像貼上去的——給它一點陰影當落地感 */
.mycard-img {
  display: block; width: 100%; height: auto; border-radius: 2px;
  box-shadow: 0 6px 26px rgba(0, 0, 0, .45);
}
.mycard-act {
  display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin-top: 12px;
}
.mycard-act .btn { font-size: 12.5px; padding: 9px 18px; }
.r-mycards-hint {
  margin: 18px auto 0; max-width: 23em; text-wrap: balance;
  font-family: var(--sans); font-size: 12px; line-height: 1.7; color: var(--ink-faint);
}

/* 牌卡視窗的兩列按鈕：第一列下載／分享，第二列「贊助一塊蛋糕」。
   兩列**等寬**（站主：不等寬看起來不和諧），做法是兩列都撐滿視窗的內容寬度——
   那也正好是上面那張卡的寬度，三者的左右緣因此對齊。
   第一列用 grid 而不是 flex：grid-auto-columns:1fr 會把寬度平均分給按鈕，
   所以「下載圖片」與「分享」字數不同也一樣寬；桌機沒有 Web Share API 時
   只剩一顆，那一顆就自己撐滿整列，仍然跟第二列對齊。 */
.ocm .oc-actions {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 12px; width: 100%;
}
/* 內容換成共用的 .sp-row（兩顆贊助鈕，見 js/app.js 的 sponsorRowHtml）。
   容器類名留著不改：.is-native 的隱藏規則與打包白名單都指著它。 */
.oc-donate { padding: 4px 0 8px; }

/* 牌卡的母語翻譯：卡面上放的是英文，這一句顯示在圖片**下方**（規格明訂不疊進圖片）。
   襯線、置中、比卡面小一級——它是輔助閱讀，不該跟卡面搶。 */
.oc-t-local {
  margin: 16px auto 0; max-width: 22em; text-wrap: balance;
  font-family: var(--serif); font-size: 15px; line-height: 1.9;
  color: var(--ink); text-align: center;
}
.mycard-local {
  margin: 10px auto 0; max-width: 20em; text-wrap: balance;
  font-family: var(--serif); font-size: 13px; line-height: 1.8;
  color: var(--ink-dim); text-align: center;
}

/* ── 牌卡下方的解讀文：吃**解讀正文那一套**，不是自己一套 ──
   站主 2026-08：「這段文字內容也是解讀的一部分，所以它的文字處理方式應該要跟
   上面解讀的處理方式一樣，包括翻譯的部分，全部一起做一個正式版的處理。」

   所以這一塊改成與 .lg-para／.as-seg 同一種暗色面板（值取自 --panel-*），而且
   譯文**收進同一塊面板裡**，不再自己在上面置中一塊。三層的分工直接對齊占星那種
   面板，理由與那裡相同：
     .oc-note-h  小標「這張卡在說什麼」＝標籤 → 無襯線、小、金、加底線（同 .lg-sub）
     .oc-note-q  卡面那一句的母語版＝一整句話 → 明體、大於本文、金（同 .as-head）
     .oc-note-b  三段解讀 → 明體本文、--ink（同 .as-body）

   ⚠ 之前的版本是「靠左、一條上緣髮絲線、--ink-dim 的 15.5px」。在實機上那條線與
   小標在星圖背景上幾乎看不見，三段又直接壓在星圖的同心圓與亮弧上；而註解寫著
   「加一條左界線」但程式其實從來沒有左界線。整組換掉，不與舊版並存。

   ⚠ 這裡刻意**不設 max-width**：面板寬度跟著容器（.ocm-box 是 400px），與解讀
   各節的面板一樣占滿可用寬度。原本的 24em 在 400px 的視窗裡本來就吃不到。 */
.oc-note {
  margin: 0 0 24px; padding: 18px 18px 20px; text-align: left;
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur); -webkit-backdrop-filter: var(--panel-blur);
  border: 1px solid var(--panel-line); border-radius: 3px;
}
.oc-note-h {
  font-family: var(--sans); font-size: 13px; letter-spacing: .22em;
  color: var(--accent); margin: 0 0 14px; padding-bottom: 9px;
  border-bottom: 1px solid rgba(214, 183, 122, .18);
}
/* 卡面那一句的母語版。用 --serif 而不是 --sans、也不縮小不拉字距：它是一整句
   話，不是標籤——與 .as-head 同一個判斷（那裡的註解寫得更詳細）。
   大於本文半級以上，層次才不是反的。 */
.oc-note-q {
  margin: 0 0 14px; font-family: var(--serif); font-size: 18px;
  letter-spacing: .02em; line-height: 1.7; color: var(--accent);
}
/* 三段解讀＝本文。字級與行高**逐字比照占星那一節的 .as-body（16.5 / 1.95）**。
   站主 2026-09：「要比照正式解讀的呈現方式，字要一樣大。」
   為什麼取占星那一個值而不是雷諾曼的 16px：這一塊的結構跟占星那種面板一模一樣
   ——上面一句 18px 的金色整句話，下面是本文。.as-head 的註解寫著「標題必須大於
   本文」，16.5 就是為了配 18px 的標題訂的；同一個結構就該用同一組值。
   ⚠ 我在 #257 曾把它降到 16px 去搶行寬（每行 16.5 → 17.8 字）。那個取捨錯了：
   站主要的是字一樣大，行寬短一點可以接受。不要再為了行寬把它降回去。 */
.oc-note-b {
  margin: 0; font-family: var(--serif); font-size: 16.5px; line-height: 1.95;
  color: var(--ink);
  /* ⚠ 這裡**不可以**加 text-wrap: pretty（#257 加過，2026-09 移除）。
     加它的動機是收掉過短的末行，但它是**段落層級**的斷行最佳化器：拿行長的
     平整度去換末行長度。Safari 17.5+ 對中日韓會真的做全段重新分配，結果是段落
     中間出現「明明還放得下三個字卻換行」的短行——站主在 iPhone 上拍到，右緣參差
     到不協調。（Chromium 對中日韓幾乎不作用，所以本機 A/B 量不出差別：非末行
     落差兩組都是 20px；末行也只差 17px。代價很大，好處近乎沒有。）
     解讀正文（.lg-para p／.as-body）從來沒有用它——這一塊也不該用。
     預設的貪心斷行「塞到塞不下才換」，右緣落差最多一個字，那一個字來自中文的
     禁則處理（下一個字是。，、」之類不能排在行首的標點，就把前一個字一起帶下去），
     那是正確的排版行為，不要去改。 */
}
/* 段距與解讀各節同一個值（.as-body + .as-body、.lg-para p + p 都是 1.1em）。
   用相鄰選擇器而不是給每段 margin-bottom：最後一段就不會在面板底部多出空白。 */
.oc-note-b + .oc-note-b { margin-top: 1.1em; }
@media (max-width: 420px) {
  /* 內距比 .lg-para 的手機版（14px）再收 2px：解讀各節是整頁寬（346px），
     結果頁那一塊在彈出視窗裡只有 354px 又要扣掉視窗自己的 20px 內距，
     每一個 px 都要讓給行寬。 */
  .oc-note { padding: 16px 12px 18px; }
  .oc-note-h { font-size: 12.5px; letter-spacing: .18em; }
  .oc-note-q { font-size: 17px; }
  /* ⚠ 本文的 line-height 不在這裡改。占星的 .as-body 沒有手機版覆寫，
     一律 1.95；「字要一樣大」包含行高一樣，收緊行高等於又變回不一樣。 */
}
/* 我的靈感卡裡的同一段：小一級，跟著那張卡的譯文之後 */
.oa-note {
  margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line);
  font-size: 14px; line-height: 1.9; color: var(--ink-dim);
}
.oa-note p { margin: 0 0 .8em; }
.oa-note p:last-child { margin-bottom: 0; }
/* 舊格式那一段（前台已經不顯示）：壓淡，一眼分得出跟現行格式不是同一批 */
.oa-note-legacy { opacity: .55; }
/* 「我的靈感卡」裡的解讀文＝**跟結果頁同一塊面板**（.oc-note，見上面那一段）。
   站主 2026-09：「我想要比較解讀的方式呈現。」上一版這裡縮了一級（13.5px、
   沒有小標與引句），理由是「這一排是縮圖牆」——那個判斷錯了：一張卡帶的是一整篇
   三段解讀，不是縮圖的說明文字。字級與層次現在兩處完全一樣，只有外距不同：
   這裡接在卡片下面，不需要結果頁那個 24px 的下緣。 */
.mycard .oc-note { margin: 10px 0 0; }

/* ==== 首次使用引導（coach marks，見 js/onboarding.js） ====
   聚光燈的原理：.ob-ring 是一個透明的框，box-shadow 撐到 9999px 當變暗遮罩，
   框內就是「亮著的洞」——被指的元素原封不動地透出來（它在遮罩下面）。
   所以有光圈的步驟，.ob-back 要透明（不然暗兩層）；置中的步驟才用 .ob-back 變暗。
   z-index 82：要蓋過選單鈕（60）與側選單（55），但在牌卡視窗之下沒有交集
   （導覽只出現在首頁與結果頁，視窗開著時不會啟動）。 */
.ob { position: fixed; inset: 0; z-index: 82; opacity: 0; transition: opacity .3s ease; }
.ob.show { opacity: 1; }
.ob-back { position: absolute; inset: 0; background: rgba(4, 7, 12, .66); }
.ob.anchored .ob-back { background: transparent; }
.ob-ring {
  position: absolute; border-radius: 9px; pointer-events: none;
  border: 1px solid rgba(224, 193, 132, .9);
  box-shadow: 0 0 18px rgba(224, 193, 132, .35), 0 0 0 9999px rgba(4, 7, 12, .66);
}
/* 呼吸光圈畫在 ::after 上：主框的 shadow 兼作全頁遮罩，不能跟著閃 */
.ob-ring::after {
  content: ''; position: absolute; inset: -5px; border-radius: 12px;
  border: 1px solid rgba(224, 193, 132, .55);
  animation: obPulse 1.9s ease-in-out infinite;
}
@keyframes obPulse {
  0%, 100% { transform: scale(1); opacity: .9; }
  50% { transform: scale(1.05); opacity: .35; }
}
.ob-card {
  position: absolute; width: min(320px, calc(100vw - 24px));
  padding: 18px 18px 14px;
  background: linear-gradient(180deg, rgba(21, 30, 46, .97), rgba(13, 20, 32, .98));
  border: 1px solid var(--line-strong); border-radius: 10px;
  box-shadow: 0 14px 44px rgba(0, 0, 0, .55);
}
/* 附範例卡縮圖的步驟寬一點：圖與字併排，字欄還要留得下三行。
   寬度只在這裡定義，js/onboarding.js 的 reposition() 讀 offsetWidth 來夾邊界，
   所以改這個數字不必動 JS。 */
.ob-card.has-shot { width: min(364px, calc(100vw - 24px)); }
.ob-main { display: flex; align-items: flex-start; gap: 13px; }
.ob-text { flex: 1 1 auto; min-width: 0; }
/* 有範例圖時改用格線，讓**按鈕也排進右欄**：圖比三行字高，按鈕若還是橫跨整張卡，
   圖的右下方會空出一大塊。版面：進度點橫跨上方，圖佔左欄兩列，字與按鈕疊在右欄。
   .ob-main 用 display:contents 把圖與字直接交給外層格線排——舊瀏覽器不支援時
   會退回上面那組 flex（圖左、字右、按鈕在下），版面仍然成立，只是鬆一點。 */
.ob-card.has-shot { display: grid; grid-template-columns: auto 1fr; column-gap: 13px; }
.ob-card.has-shot .ob-dots { grid-column: 1 / -1; }
.ob-card.has-shot .ob-main { display: contents; }
.ob-card.has-shot .ob-shot { grid-row: span 2; }
.ob-card.has-shot .ob-actions { align-self: end; flex-wrap: wrap; row-gap: 8px; }
/* 公告版面：首頁導覽的第一步（專屬靈感牌卡）。站主要的是「很像新功能推出的公告，
   又有點像廣告」——但風格要跟站上一致，所以只加重份量，不換語言：卡片寬一點、
   上緣一道金色細線、頂部一層淡金光暈，配上 .ob-badge 那枚「新功能」徽章。
   金線與光暈刻意都做在 background／box-shadow 上，**不用 ::before**：這張卡在
   .has-shot 時是 grid，多一個偽元素就會變成多一個格線項目，把版面擠掉。
   寬度寫在這裡就好，reposition() 讀 offsetWidth 夾邊界，不必動 JS。 */
.ob-card.is-promo {
  width: min(400px, calc(100vw - 24px));
  border-color: rgba(226, 201, 150, .42);
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(224, 193, 132, .13), transparent 62%),
    linear-gradient(180deg, rgba(21, 30, 46, .97), rgba(13, 20, 32, .98));
  box-shadow: 0 14px 44px rgba(0, 0, 0, .55), 0 0 26px rgba(224, 193, 132, .1),
    inset 0 1px 0 rgba(226, 201, 150, .5);
}
.ob-card.is-promo .ob-shot { width: 120px; }
/* 範例卡：2:3 直式，稍微歪一點角度＋金邊，讓它看起來是一張「卡」而不是插圖。
   站主要的是「讓大家感受到」——所以給它實體感，不要只是縮圖。 */
.ob-shot {
  flex: 0 0 auto; width: 106px; aspect-ratio: 2 / 3; display: block;
  object-fit: cover; border-radius: 5px;
  border: 1px solid rgba(226, 201, 150, .45);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .5), 0 0 14px rgba(224, 193, 132, .14);
  transform: rotate(-2deg);
}
/* 窄螢幕（≤360px，例如 iPhone SE）：併排會把字欄擠成一行三四個字。
   改成上下排，圖置中——寧可卡片高一點，也不要字被壓成一條。 */
@media (max-width: 360px) {
  .ob-card.has-shot { display: block; }
  .ob-card.has-shot .ob-main { display: flex; flex-direction: column; align-items: center; }
  .ob-shot { width: 120px; margin-bottom: 2px; }
  .ob-text { width: 100%; }
}
.ob-card.centered { left: 50% !important; top: 50% !important; transform: translate(-50%, -50%); }
.ob-dots { display: flex; gap: 6px; margin-bottom: 12px; }
.ob-dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(224, 193, 132, .25); }
.ob-dot.on { background: var(--accent); }
/* 「新功能」徽章。uppercase 只對英文有作用（New → NEW），中日韓不受影響。
   ⚠ [hidden] 那一條不能省：display 一旦被指定就會壓掉 hidden 屬性的 display:none，
   不是公告的步驟會留下一枚空徽章。 */
.ob-badge {
  display: inline-block; margin-bottom: 9px; padding: 3px 9px;
  border: 1px solid rgba(226, 201, 150, .4); border-radius: 999px;
  background: rgba(224, 193, 132, .1);
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent);
}
.ob-badge[hidden] { display: none; }
.ob-title {
  margin: 0 0 8px; font-family: var(--serif); font-weight: 600;
  font-size: 17px; letter-spacing: .04em; color: var(--accent);
}
.ob-body { margin: 0 0 14px; font-size: 13.5px; line-height: 1.75; color: var(--ink-dim); }
.ob-actions { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.ob-skip {
  background: none; border: none; padding: 6px 2px; cursor: pointer;
  font-size: 12.5px; letter-spacing: .06em; color: var(--ink-faint);
}
.ob-skip:hover { color: var(--ink-dim); }
/* 下一步鈕沿用 .btn.primary，只縮小成卡片內合適的尺寸 */
.ob-card .ob-next { width: auto; min-width: 0; padding: 9px 20px; font-size: 13.5px; }

/* ===== 結束區段的回饋視窗（滑到結尾彈出：星等＋留言＋贊助）=================
   外框沿用靈感卡那一套（.ocm／.ocm-back／.ocm-box／.ocm-x）——同一個站不該有
   兩種對話框長相，而且那一套的 iOS 安全區、捲動、動畫都在實機上調過。
   星等與文字框直接複用頁面上回饋區塊的 .fb-* 類（同一件事就長同一個樣）。 */
/* 站主 2026-08：「整體縮小，不要好像佔了快要整個螢幕，讓它可愛一點親切一點。」
   這個視窗跟靈感卡不一樣——那個要展示一張 2:3 的卡，本來就該大；
   這個只是輕輕問一句，體積應該對得上語氣。四個地方一起收：
     ・窄一點（380 → 320）並把圓角放大到 18px：小 ＋ 圓 ＝ 不具壓迫感
     ・內距、字級、星星、段距全部收一階（明細見各自的規則）
     ・彈進來改成「從 92% 放大」的輕彈，不是從下方推上來——
       推上來像通知，放大像有人探頭問一句
   收完之後高度掉約三成（實測 430px 寬：520 → 366px）。 */
.fbm .ocm-box {
  max-width: 320px; padding: 24px 20px 20px; text-align: center;
  border-radius: 18px;
  animation: fbmPop .32s cubic-bezier(.34, 1.42, .64, 1);
}
@keyframes fbmPop {
  from { opacity: 0; transform: scale(.92); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .fbm .ocm-box { animation: none; }
}
/* 叉叉跟著往內縮，不然圓角變大之後它會壓在弧線上 */
.fbm .ocm-x { top: 6px; right: 6px; }
/* 星等下方那行評語的保留高度：留著（選了星才出現，不留會讓版面跳一下），
   但在這個縮小過的視窗裡收一點，不然星星與分隔線之間會空一大塊。 */
.fbm .fb-scale { min-height: 1.25em; margin-top: 4px; font-size: 12px; }
/* 陰影加一層很淡的暖光：純黑陰影會把它壓成「挖在畫面上的一個洞」，
   帶一點金的話比較像一張浮在星圖上的小卡。濃度刻意壓得很低——
   這個站的金色是細線與文字在用的，大面積的光暈會俗氣。 */
.fbm .ocm-box {
  box-shadow: 0 14px 44px rgba(0, 0, 0, .5), 0 0 0 1px rgba(214, 183, 122, .06),
    0 6px 26px rgba(196, 160, 96, .09);
}
.fbm-title {
  /* 字級跟著視窗縮：日文那句標題有 15 個字的子句，19px 固定字級在 375px
     的手機上放不進一行，會被 overflow-wrap 硬斷成「⋯響きましたか／？」，
     留一個問號在第三行。縮到 17px 就進得去。上限維持 19px，寬螢幕不變。
     （站上既有的 .h1-long 也是這個作法。） */
  font-family: var(--serif); font-size: clamp(16px, 4.3vw, 17.5px); line-height: 1.55;
  letter-spacing: .05em; color: var(--ink); margin: 0 auto 10px;
  /* 17em 比任何手機的視窗內寬都大＝手機上由容器決定，這裡只是替平板／桌機封頂 */
  max-width: 17em;
}
.fbm .fb-star { font-size: 26px; }
.fbm .fb-stars { gap: 4px; }
.fbm .fb-send { width: 100%; margin-top: 8px; }
.fbm .fb-text { text-align: left; }
/* 視窗裡的按鈕比站上其他地方矮一階、也更圓：這個視窗整體縮小之後，
   原本 12px 上下內距的按鈕會佔掉一半高度。34px 的左右內距在這裡也沒有意義
  （按鈕本來就是滿寬的）。 */
.fbm .btn { padding: 10px 18px; border-radius: 12px; font-size: 13.5px; }
/* 贊助段：隔一條線，字級退一階——先問感受，才提贊助 */
.fbm-sponsor { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.fbm .sp-row { gap: 8px; }
/* ⚠ 這一句要套本檔開頭那條 UI 文案排版的約定（見「UI 文案排版」那一段）：
   text-wrap: balance ＋ 收窄欄寬，否則會出現「第一行滿、第二行只剩一兩個字」。
   實測過，不套的話四個語系都會中：英文最慘的一句尾行只有整行的 7%
  （只剩一個 "us."），韓文 13%、中文 11%。 */
/* ── 短文案的斷行（回饋視窗的標題／說明句／小字共用）─────────────────
   本檔開頭那條「UI 文案排版」的約定只做了 text-wrap: balance ＋ 收窄欄寬，
   對英文夠用，對中日文不夠：那兩種語言預設可以斷在**任何兩個字之間**，
   所以 balance 雖然把兩行拉成等長，卻會斷出「可以斗內一／下」這種把詞
   切一半的行（實測抓到的）。

   ・word-break: keep-all  禁掉「字與字之間」的斷點，只剩標點與空格 →
                           中日文的斷句因此落在，、；。上，一行一個意思
   ・overflow-wrap         保險：某個子句長到一行放不下時仍然斷得開，
                           不會爆出容器（日文有一句 20 字的子句會用到）
   ・max-width 21em        實測掃過 19–23em，21em 是「中日文零個壞斷句」
                           的最窄值；再窄會逼出強制斷詞，再寬則第一行過長

   ⚠ 改文案之後值得再看一次斷在哪：規則管得住「不切詞」，但一句話裡
   只有一個逗號時，兩行的長短仍然由那個逗號的位置決定。 */
.fbm-title, .fbm-sponsor-lede, .r-sponsor-lede, .fb-hint {
  text-wrap: balance;
  word-break: keep-all;
  overflow-wrap: break-word;
  margin-left: auto; margin-right: auto;
}
.fbm-sponsor-lede {
  font-family: var(--sans); font-size: 12.5px; line-height: 1.7;
  color: var(--ink-dim); letter-spacing: .02em; margin: 0 auto 12px;
  max-width: 21em;
}

/* ==== App 殼（原生版）限定的隱藏規則 ====
   is-native 由 js/native/boot.js 在原生殼啟動時掛上 <html>，一般瀏覽器永遠
   沒有這個 class，所以以下規則對 web 完全不生效。

   贊助入口在 App 內必須藏起來：Apple 審查準則 3.1.1 不允許 App 裡出現導向
   外部付款的按鈕或連結（BuyMeACoffee 正是這種）。Android 雖然寬鬆，但兩個
   平台用同一包 web 資產，統一藏掉最不會出錯。三個入口：
     選單的「支持開發者」（index.html）、結果頁的贊助鈕（.r-sponsor）、
     牌卡視窗的「贊助一塊蛋糕」（.oc-donate）。
   之後上 IAP 時，加購按鈕會放回這些位置（見 docs/mobile-release.md）。 */
.is-native .menu-item-coffee,
.is-native .oc-donate { display: none !important; }
/* 回饋視窗照常彈（星等與留言 App 版也要收），只藏掉底下的贊助段 */
.is-native .fbm-sponsor { display: none !important; }

/* ⚠ .r-sponsor **不可以**整塊 display: none。
   它的 border-top ＋ 上下 padding 是「回饋區」與「下面三顆按鈕」之間唯一的
   間隔（web 上量到 176px）。整塊藏掉的話那個間距歸零，兩區直接黏在一起
   ——2026-08 站主在 Android 實機上回報的正是這個。
   所以只藏裡面的按鈕與提示，保留那條金線與段落間距。 */
.is-native .r-sponsor > * { display: none !important; }
.is-native .r-sponsor { margin-top: 28px; padding: 0 20px 28px; }

/* ==== App 殼（原生版）：iOS 安全區域 ====
   問題：Capacitor 的 WebView 是**整個螢幕**，內容會跑到動態島／狀態列底下。
   站主 2026-08 在 iPhone 上回報「左上角選單點不太到」——三線鈕的 top:16px
   落在狀態列裡，上半部被系統列吃掉了（點下去變成捲到頂，不是按到按鈕）。
   底部同理：家用手勢指示條會壓住最後一排內容。

   為什麼要 --sat／--sab 兩個變數而不直接寫 env()：
   ① 一處定義、多處使用，改的時候不會漏掉某個 fixed 元素；
   ② 測試時可以覆寫成固定值來模擬有劉海的機型（env() 在桌機瀏覽器永遠是 0，
      不覆寫就完全驗不到）。
   env() 要回報真實數值，前提是 <meta viewport> 帶 viewport-fit=cover——
   那一段由 tools/build-mobile.mjs 在打包時加進 App 的 index.html，
   **刻意不加進網站的 index.html**：網頁版加了會讓橫向時內容伸進「耳朵」區域，
   那是實際的版面改變，不符合「web 行為完全不變」。
   web 永遠沒有 .is-native，所以以下整段對網站沒有任何作用。 */
.is-native {
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
}
/* 三線鈕：整顆往下推，離狀態列有 16px */
.is-native .menu-toggle { top: calc(16px + var(--sat)); }
/* 選單面板：上緣本來就留 78px 給三線鈕，再加上安全區；下緣避開家用指示條 */
.is-native .menu-panel { padding-top: calc(78px + var(--sat)); padding-bottom: calc(30px + var(--sab)); }
/* 面板右上角的 × 跟著三線鈕一起下來，否則它會貼在狀態列上同樣按不到 */
.is-native .menu-close { top: calc(14px + var(--sat)); }
/* 一般內容：所有畫面共用 .screen。上緣給狀態列、下緣給家用指示條 */
.is-native .screen { padding-top: var(--sat); padding-bottom: calc(60px + var(--sab)); }
/* 牌卡視窗是 fixed 滿版的 flex 容器，它的內距要含安全區，
   不然視窗頂到螢幕邊時右上角的關閉鈕會落進狀態列 */
.is-native .ocm { padding-top: calc(18px + var(--sat)); padding-bottom: calc(18px + var(--sab)); }
/* 版面診斷面板（?diag=1）：站主自己用的，同樣別被狀態列蓋住 */
.is-native #diagPanel { top: calc(8px + var(--sat)); }

/* ═══════════ 塔羅（核心流動五張牌陣） ═══════════ */

/* ---- 抽牌場景：旋轉牌環 ----
   全螢幕場景，不走 .screen 的 660px 版心。文字極簡（站主核定）：
   頂端 TAROT、一句「請選擇五張牌」、底部五顆進度星。 */
/* ⚠ 不能用 position:fixed 滿版：.screen.active 的 fadein 動畫帶 transform，
   會把 fixed 的包含塊變成這個高度為 0 的 section（實測整個場景消失）。
   改成 section 自己撐滿視窗高、舞台用 absolute。 */
#screenTarot { max-width: none; padding: 0; height: 100vh; height: 100dvh; position: relative; overflow: hidden; }
.tarot-stage { position: absolute; inset: 0; overflow: hidden; }
.tarot-head {
  position: absolute; top: 0; left: 0; right: 0; z-index: 30;
  text-align: center; pointer-events: none;
  /* 原本是 32px，正好落在背景那個金色造型的上半圈（造型的上緣在視窗高的 3.9%，
     32px 幾乎一定在裡面）。站主 2026-09：那個造型不能被字蓋住，所以 TAROT 也
     一起讓到造型下方——牌環的最上排在 51%−0.2h 附近，讓下去還是在牌的上方。
     淨空線見檔案開頭的 --sky-clear。 */
  padding-top: max(32px, var(--sky-text));
}
.tarot-kicker {
  font-family: var(--sans); font-size: 15px; letter-spacing: .5em;
  text-indent: .5em; /* 置中補償字距 */
  color: var(--accent-dim); text-transform: uppercase;
}
.tarot-space {
  position: absolute; inset: 0; z-index: 10;
  perspective: 1000px; perspective-origin: 50% 47%;
}
/* 牌環中心略低於畫面中心；後續依站主實機回饋微調回 51%（與進度區拉開） */
.tarot-cloud { position: absolute; left: 50%; top: 51%; transform-style: preserve-3d; }
.tc-wrap { position: absolute; transform-style: preserve-3d; }
.tc-face {
  position: absolute; left: 50%; top: 50%;
  background-size: cover; background-position: center;
  border-radius: 5px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .45);
  backface-visibility: hidden;   /* 轉過去看不到牌背——由光點接手 */
}
.tc-face.pick { cursor: pointer; }
.tc-face.pick:hover {
  box-shadow: 0 0 0 1.5px rgba(240, 220, 170, .95), 0 0 26px rgba(232, 205, 146, .6),
              0 10px 30px rgba(0, 0, 0, .5);
}
/* 遠側的牌：正面朝向使用者，但只見一點白芒 */
.tc-lume { position: absolute; left: 0; top: 0; opacity: 0; pointer-events: none; }
.tc-halo {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(255, 250, 236, .95) 0%, rgba(244, 226, 180, .5) 30%,
    rgba(224, 193, 132, .18) 58%, rgba(224, 193, 132, 0) 100%);
}
.tc-dot {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border-radius: 50%; background: #fffaf0;
  box-shadow: 0 0 6px rgba(255, 248, 230, .9);
}
/* 點牌後沿弧形光軌飛向底部的殘影 */
.tc-fly {
  position: fixed; z-index: 500; pointer-events: none;
  background-size: cover; background-position: center; border-radius: 4px;
  box-shadow: 0 0 24px rgba(232, 205, 146, .75), 0 8px 22px rgba(0, 0, 0, .5);
}

/* ---- 一鍵感應抽牌（站主 2026-09 定案）：牌環與進度星座之間、置中的小圓角鈕 ----
   刻意比 .btn 小一號、用圓角：這一頁沒有其他按鈕，做成一般尺寸會搶過牌環；
   金邊＋暗底沿用 .btn.ghost 的語言，前面一顆 ✦ 讓它融進星圖。
   位置量的是進度區（標題＋星座約 80px）再往上留一口氣，底排牌在 51%＋0.2h 附近，
   844 高的手機兩者之間還有約 100px；667 高的小螢幕實測仍不相碰。 */
.tarot-quick {
  position: absolute; left: 50%; transform: translateX(-50%);
  /* 進度區（標題＋星座）約 92px 高，再留 12px 呼吸 */
  bottom: calc(104px + env(safe-area-inset-bottom, 0px));
  z-index: 30;
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-family: var(--sans); font-size: 12.5px; line-height: 1;
  letter-spacing: .16em; text-indent: .16em;
  color: var(--ink-dim); background: rgba(9, 14, 23, .62);
  border: 1px solid rgba(214, 183, 122, .38); border-radius: 999px;
  padding: 8px 16px 8px 13px; cursor: pointer;
  box-shadow: 0 0 10px rgba(214, 183, 122, .08);
  transition: opacity .45s, color .35s, border-color .35s, box-shadow .45s;
}
.tarot-quick::before {
  content: '✦'; font-size: 11px; letter-spacing: 0; text-indent: 0;
  color: #e3c98d; text-shadow: 0 0 8px rgba(240, 220, 166, .8);
}
.tarot-quick:hover:not(:disabled) {
  color: var(--ink); border-color: rgba(226, 198, 138, .58);
  box-shadow: 0 0 16px rgba(220, 190, 130, .16);
}
.tarot-quick:active:not(:disabled) { color: var(--ink); background: rgba(20, 30, 45, .7); }
/* 按下去或五張已滿：淡出，不再接受點擊 */
.tarot-quick.off { opacity: 0; pointer-events: none; }
/* 矮螢幕（iPhone SE 一類，667 高）：底排牌與進度區之間只剩約 40px，鈕再收一號 */
@media (max-height: 700px) {
  .tarot-quick { font-size: 11.5px; padding: 6px 13px 6px 11px; gap: 6px; }
  .tarot-quick::before { font-size: 10px; }
}

/* ---- 底部進度：標題＋逐步連成的星座（站主 2026-09 依參考圖改定） ----
   收到一張＝亮起一個造型星並連上細金線；未收的節點是小空心菱形。
   節點座標與造型在 js/app.js（TPC_NODES／tpcGlyph）。 */
.tarot-progress {
  /* 貼到最底（含 iOS 安全區）：進度區越低，跟底排的牌越分得開（站主 2026-09） */
  position: absolute; left: 0; right: 0;
  bottom: calc(2px + env(safe-area-inset-bottom, 0px));
  z-index: 30; text-align: center; pointer-events: none;
}
.tpc-label {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--serif); font-size: 15px; letter-spacing: .18em;
  color: var(--ink); white-space: nowrap;
  margin-bottom: 2px;
}
/* 英文標題最長，窄螢幕收斂字距與飾線，一行放得下 */
@media (max-width: 480px) {
  .tpc-label { font-size: 13.5px; letter-spacing: .08em; gap: 6px; }
  .tpc-orn { width: 22px; }
}
.tpc-orn {
  width: 42px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(214, 183, 122, .55), transparent);
}
.tpc-dia {
  width: 5px; height: 5px; transform: rotate(45deg);
  border: 1px solid rgba(224, 193, 132, .75);
}
.tpc-sky { width: 292px; height: 51px; overflow: visible; }
/* 連線與亮星：先隱形，收到才浮現 */
.tpc-line { opacity: 0; transition: opacity .7s ease; }
.tpc-line.on { opacity: .75; }
.tpc-lit {
  opacity: 0;
  transform-box: fill-box; transform-origin: center;
  /* 兩層光：內層亮白、外層暖金——星要亮得像遠側牌化成的光點（站主 2026-09 加亮） */
  filter: drop-shadow(0 0 4px rgba(255, 248, 230, .95)) drop-shadow(0 0 12px rgba(236, 209, 150, .8));
}
.tpc-node.on .tpc-lit { opacity: 1; animation: tpPop .55s ease-out; }
.tpc-node.on .tpc-hollow { opacity: 0; }
.tpc-hollow { transition: opacity .4s ease; }
.tarot-progress.resonate .tpc-node.on .tpc-lit { animation: tpPulse 1.2s ease-in-out; }
@keyframes tpPop {
  from { transform: scale(.15); opacity: 0; }
  60% { transform: scale(1.3); }
  to { transform: scale(1); opacity: 1; }
}
@keyframes tpPulse {
  0%, 100% { transform: scale(1); filter: brightness(1); }
  50% { transform: scale(1.35); filter: brightness(1.55); }
}
@media (prefers-reduced-motion: reduce) {
  .tpc-node.on .tpc-lit, .tarot-progress.resonate .tpc-node.on .tpc-lit { animation: none; }
}

/* ---- 結果頁：正式牌陣（站主 2026-09 改定）：上排視覺順序 1・3・2
   （當前核心置中，左右是累積根源與內在取向），下排 4、5 置中，五張同尺寸。
   使用者看不到編號，順序純屬視覺安排。六欄格：上排各佔兩欄，
   下排從第 2、4 欄起各佔兩欄——下排自然置中，不需要 area 命名。
   ⚠ p2/p3 的欄位在 DOM 順序之外跳位，三張都要明寫 grid-row:1，
   否則 sparse 自動排版會把 p3 掉到第二排。 ---- */
.tarot-spread {
  display: grid; gap: 10px 8px; align-items: start;
  grid-template-columns: repeat(6, 1fr);
  /* 牌陣縮到約一半、置中——牌是索引，主角是下面的解讀。
     手機上純 50% 會小到看不清，230px 是下限。 */
  width: 50%; min-width: 230px;
  margin: 4px auto 16px;
}
.ts-card { margin: 0; text-align: center; }
.ts-p1 { grid-column: 1 / 3; grid-row: 1; }
.ts-p3 { grid-column: 3 / 5; grid-row: 1; }
.ts-p2 { grid-column: 5 / 7; grid-row: 1; }
.ts-p4 { grid-column: 2 / 4; grid-row: 2; } .ts-p5 { grid-column: 4 / 6; grid-row: 2; }
.ts-pos {
  font-family: var(--sans); font-size: 10px; letter-spacing: .06em;
  color: var(--accent-dim); margin-bottom: 4px;
  /* 固定兩行高、文字貼底：英文牌位名會折行（Accumulated roots），
     不固定的話該張牌會被推低、跟同排對不齊。3em 才裝得下
     兩行 ×  line-height 1.45，2.5em 實測仍會被撐開。 */
  min-height: 3em; line-height: 1.45;
  display: flex; align-items: flex-end; justify-content: center;
}
.ts-imgwrap {
  display: block; width: 100%; padding: 0; border: none; background: none;
  cursor: zoom-in; border-radius: 6px;
}
.ts-imgwrap img {
  display: block; width: 100%; border-radius: 6px;
  border: 1px solid rgba(211, 181, 120, .38);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .4);
}
/* 逆位不旋轉牌面（站主 2026-09 改定）：只在牌名旁標一枚「逆位」小籤 */
.ts-rev {
  display: inline-block; margin-left: 4px; padding: 0 6px 1px;
  font-family: var(--sans); font-size: 9.5px; letter-spacing: .06em;
  color: var(--accent-dim);
  border: 1px solid rgba(211, 181, 120, .38); border-radius: 999px;
  vertical-align: 1px;
}
.ts-name { margin-top: 5px; font-size: 11px; line-height: 1.45; color: var(--ink-dim); }
.ts-p3 .ts-name { color: var(--ink); }
@media (max-width: 420px) {
  .tarot-spread { gap: 6px; }
  .ts-pos { font-size: 9px; letter-spacing: .02em; }
  .ts-name { font-size: 10px; }
}
/* 點牌放大：整頁覆蓋層（點任意處關閉） */
.ts-zoom {
  position: fixed; inset: 0; z-index: 1000; cursor: zoom-out;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 8, 13, .88);
}
.ts-zoom img {
  max-height: 88vh; max-width: 92vw; border-radius: 10px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .7);
}

/* 螢幕閱讀器專用文字（塔羅進度的 aria-live 用；視覺上不佔位） */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* 塔羅按鈕的「新」小籤：寫死在 index.html 的一顆 span，正式開放後不再靠
   JS 動態掛上（enableTarotEntry 已隨開放拿掉）。使用者點過塔羅工具鈕之後
   js/app.js 會把這顆 span 移除並記旗標（tarot_seen），下次進站就不再出現
   ——見 app.js 的 hideTarotNewTag／markTarotSeen。
   .tool-opt 補 position:relative 讓小籤能定位在角上——對既有版面無影響。 */
.tool-opt { position: relative; }
.tool-new {
  position: absolute; top: -8px; right: -6px;
  padding: 1px 8px 2px;
  font-family: var(--sans); font-size: 10px; letter-spacing: .1em;
  color: #14203a;
  background: linear-gradient(180deg, #f0dcae, #dcb977);
  border-radius: 999px;
  box-shadow: 0 0 10px rgba(232, 205, 146, .5), 0 2px 6px rgba(0, 0, 0, .35);
  text-shadow: none;
}
