/* NcCycleSense 網頁免費版的樣式。
   外部檔案而不是行內 <style>：CSP 的 style-src 是 'self'，沒有
   'unsafe-inline' —— 行內樣式會被瀏覽器擋掉。 */
  :root {
    --bg: #fbfbfa; --fg: #1a1a18; --muted: #6b6b66; --line: #e2e2dd;
    --card: #ffffff; --band: #f4f4f1; --accent: #1f5f4f; --warn: #8a5a00; --mono: ui-monospace, "Cascadia Mono", Consolas, monospace;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --bg: #16181a; --fg: #e8e8e4; --muted: #9a9a94; --line: #2c2f33;
      --card: #1d2023; --band: #1b1e21; --accent: #6fd0b4; --warn: #d4a24a;
    }
  }
  * { box-sizing: border-box; }
  body {
    margin: 0; background: var(--bg); color: var(--fg);
    font: 16px/1.65 system-ui, "Noto Sans TC", "Microsoft JhengHei", sans-serif;
  }
  /* 版面：文字保持易讀的行寬，工作區放到滿版。
     這是 full-bleed 的標準做法 —— 用具名的 grid 欄，
     預設子元素落在 content，需要滿版的元素明說 grid-column: full。

     為什麼不乾脆整頁加寬：一行 200 個字的說明文字讀起來很痛苦，
     而這一頁的說明是使用者第一次來時真的會讀的東西。
     3D 檢視則相反 —— 它給多少用多少。 */
  .wrap {
    display: grid;
    grid-template-columns:
      [full-start] minmax(20px, 1fr)
      [content-start] min(1040px, 100% - 32px) [content-end]
      minmax(20px, 1fr) [full-end];
    padding: 0 0 80px;
  }
  /* grid 子項預設 min-width: auto —— 裡面的 <pre> 會撐破欄寬而不是自己捲動。
     這是 grid 版面最常見的溢位來源，所以明說 0。 */
  .wrap > * { grid-column: content; min-width: 0; }

  /* `hidden` 必須贏過任何 display。
     瀏覽器內建的規則是 `[hidden] { display: none }`，而**作者樣式一律贏過
     瀏覽器內建樣式** —— 所以 `.workspace { display: grid }` 讓那個屬性
     完全失效：3D 與報告的空框在還沒計算時就一直顯示在畫面上。
     這是加了 display 之後最容易踩的一腳，所以在這裡一次擋掉。 */
  [hidden] { display: none !important; }
  /* 工作區與它底下的檢視選項是**同一個帶狀區塊**。
     它們原本各自對齊不同的欄（工作區滿版、選項在 880px 的文字欄裡），
     所以計算完之後畫面上會出現一個對不齊的落差 —— 那就是「排版怪怪的」。
     現在兩者共用同一組左右內距，左邊界對齊；上下細線把這一段
     從說明文字裡分出來，讓寬度的變化讀起來是刻意的分區，而不是跑版。 */
  .wrap > .workspace,
  .wrap > .scenebar,
  .wrap > #viewrow {
    grid-column: full;
    /* 左右留白縮到 16px、可用寬度放到 1840px。
       這幾個帶狀區塊放的是 3D、報告與 NC 原文 —— 它們給多少用多少，
       而正文段落仍然留在 1040px 的欄裡，不會變成一行 200 個字。 */
    padding-left: max(24px, calc((100% - 1840px) / 2));
    padding-right: max(24px, calc((100% - 1840px) / 2));
  }
  .wrap > .workspace {
    padding-top: 20px; padding-bottom: 0;
    border-top: 1px solid var(--line);
    background: var(--band);
  }
  .wrap > #viewrow {
    padding-top: 12px; padding-bottom: 18px; margin-top: 0;
    border-bottom: 1px solid var(--line);
    background: var(--band);
  }
  /* 工作區隱藏時，底下的選項列不該自己留一條孤立的橫線。 */
  .wrap > .workspace[hidden] + #viewrow { border-top: 1px solid var(--line); }
  header { padding: 56px 0 28px; }
  h1 { font-size: 30px; margin: 0 0 6px; letter-spacing: -0.01em; }
  h1 small { font-weight: 400; color: var(--muted); font-size: 15px; display: block; margin-top: 8px; letter-spacing: 0; }
  h2 { font-size: 17px; margin: 40px 0 12px; }
  h3 { font-size: 14px; margin: 24px 0 8px; color: var(--fg); }
  h4 { font-size: 13px; margin: 18px 0 6px; color: var(--fg); }
  code {
    font-family: var(--mono); font-size: 0.92em; background: var(--card);
    border: 1px solid var(--line); border-radius: 3px; padding: 1px 4px;
  }
  /* 資料流聲明那張表。左對齊、細線，不要試著變好看 —— */
  /* 它的用途是讓 IT 一眼掃完，不是排版展示。 */
  table { border-collapse: collapse; margin: 12px 0; font-size: 13px; }
  th, td { text-align: left; padding: 6px 14px 6px 0; border-bottom: 1px solid var(--line); }
  th { font-weight: 600; color: var(--fg); }
  p { margin: 0 0 14px; }
  .muted { color: var(--muted); }

  /* 紅線的宣告要顯眼 —— 那是我們最主要的差異點（docs/03 §1.6） */
  .redline {
    border: 1px solid var(--line); border-left: 3px solid var(--accent);
    background: var(--card); border-radius: 4px; padding: 14px 16px; margin: 0 0 28px;
    font-size: 15px;
  }
  .redline strong { color: var(--accent); }

  .drop {
    border: 2px dashed var(--line); border-radius: 8px; background: var(--card);
    padding: 40px 20px; text-align: center; cursor: pointer; transition: border-color .15s, background .15s;
  }
  .drop:hover, .drop.over { border-color: var(--accent); }
  .drop input { display: none; }
  .drop .big { font-size: 17px; margin-bottom: 6px; }

  /* 對齊上緣而不是下緣：機台那一欄底下多了兩個連結，比其他欄高得多，
     對齊下緣會讓其他欄的標籤莫名其妙地掉到半空中。 */
  .opts { display: flex; gap: 20px; flex-wrap: wrap; align-items: flex-start; margin: 20px 0 0; }
  .opts > button { margin-top: 22px; }
  .field { display: flex; flex-direction: column; gap: 5px; }
  label { font-size: 13px; color: var(--muted); }
  /* **用排除法而不是逐一列舉型別。**
     原本是 `input[type=text]`，於是聯絡頁的 `type="email"` 完全沒有樣式 ——
     它在那一列裡比旁邊兩個矮一截、框也不一樣。加一種輸入型別就要記得
     回來加一次的規則，遲早會漏；漏掉的樣子又剛好是「看起來壞掉但不報錯」。 */
  input:not([type=file]):not([type=checkbox]):not([type=radio]),
  select,
  textarea {
    font: inherit; padding: 8px 10px; border: 1px solid var(--line);
    border-radius: 4px; background: var(--card); color: var(--fg); min-width: 150px;
  }
  textarea { min-width: 0; width: 100%; resize: vertical; }
  button {
    font: inherit; padding: 9px 18px; border: 0; border-radius: 4px;
    background: var(--accent); color: var(--bg); cursor: pointer;
  }
  button:disabled { opacity: .45; cursor: default; }
  /* 次要動作：載入設定檔。刻意不搶「計算工時」的視覺重量 —— */
  /* 零摩擦的首次體驗是拖檔就算，載設定是之後才會做的事。 */
  button.secondary {
    background: transparent; color: var(--muted); padding: 4px 0;
    text-align: left; text-decoration: underline; font-size: 13px;
  }
  button.secondary:hover { color: var(--fg); }
  .secondary-link { font-size: 13px; }
  input.bad { border-color: #b4392f; }
  /* 3D 檢視。高度固定 —— 讓它跟著內容長會讓頁面在載入時跳動。 */
  /* 工作區：3D 是主線，報告在旁邊。
     不是「報告在上、3D 在下」—— 那會讓路徑變成附屬品，
     而互動分析（點路徑查行號）需要兩者同時看得見。 */
  /* ------------------------------------------------------------------------
     工作區：[報告 | 3D 路徑 | NC 資訊]
     ------------------------------------------------------------------------
     原本報告在 3D 旁邊，而 NC 原文在整個工作區的**下方** —— 於是點一下
     3D 路徑，資訊出現在畫面外，使用者得捲下去看、再捲回來點下一段。
     那是這個頁面最常做的動作，而它每一次都要捲兩趟。

     三欄的顧慮是「每一欄都太窄」，但兩側是**內容決定寬度**的東西：
     報告最寬的一行是 70 個半形欄（約 582px），NC 原文 40 個欄（約 300px）。
     兩邊固定住，中間的 3D 拿剩下的 —— 1840px 時 3D 還有 800px 以上。

     窄一點時報告先跨到整列（它是讀一次的東西），3D 與原文維持併排 ——
     因為那兩個才是要互相對照的。 */
  .workspace {
    display: grid;
    /* 欄寬是變數，由欄與欄之間的把手調整。
       預設值的來源：報告最寬的一行是逐刀具那一列（約 70 個半形欄，
       13px 等寬字型下約 546px），所以 600px 剛好不折行；NC 原文
       40 個等寬欄約 300px，加上行號與內距取 400px。 */
    grid-template-columns:
      var(--col-report, 600px) var(--grip) minmax(240px, 1fr) var(--grip) var(--col-inspect, 400px);
    grid-template-areas: "report g1 view g2 inspect";
    gap: 0 6px; margin: 0; align-items: stretch;
  }
  .workspace { --grip: 8px; }
  .workspace > * { min-width: 0; }
  .workspace > .report { grid-area: report; margin: 0; }
  .workspace > #viewport { grid-area: view; }
  .workspace > .inspect { grid-area: inspect; }

  /* 三欄的門檻是 1600px。
     再窄下去 3D 會被擠到 400px 左右，而 3D 是這一區的主角 ——
     那時寧可讓報告跨整列（它是讀一次的東西），把寬度都給 3D 與原文，
     因為那兩個才是要互相對照的。 */
  @media (max-width: 1599px) {
    /* 報告跨整列，只留 3D 與原文之間那一支把手 */
    .workspace {
      grid-template-columns: minmax(240px, 1fr) var(--grip) var(--col-inspect, 400px);
      grid-template-areas: "report report report" "view g2 inspect";
      row-gap: 12px;
    }
    .workspace > #colgrip1 { display: none; }
  }
  @media (max-width: 900px) {
    /* 單欄堆疊：欄寬把手在這裡沒有意義（沒有「另一欄」可以讓寬度給它） */
    .workspace {
      grid-template-columns: 1fr;
      grid-template-areas: "report" "view" "inspect";
      row-gap: 12px;
    }
    .workspace > .colgrip { display: none; }
  }

  /* **三欄共用同一個高度。**
     少了這個，格線列的高度由最高的那一項決定 —— 而 NC 原文有多長就多長，
     於是 `.inspect` 的 `overflow: auto` 永遠不會生效：報告與 3D 停在
     一半的位置，原文那一欄一路往下跑，三欄的底部差了好幾百像素。 */
  .workspace > .report,
  .workspace > #viewport,
  .workspace > .inspect {
    height: var(--work-h, 66vh);
    min-height: 320px;
  }
  /* 報告：**橫向捲動，不換行。**
     報告是等寬字型排出來的表格 —— 逐刀具、時間分解、行程檢查每一段都靠
     欄位對齊。一旦換行，那些欄就錯開，而錯開的表比截斷的表更難讀。
     所以寧可橫捲：捲軸至少是看得見的，錯位不是。

     （原本是 `pre-wrap`，理由是「側欄底部的橫捲很難發現」。
     那個顧慮在報告上不成立 —— 它現在是自己一欄、而且欄寬可以拖。） */
  .workspace > .report {
    overflow: auto;
    white-space: pre;
  }
    @media (max-width: 1599px) {
    /* 兩列版：報告在上，不需要跟下面兩欄一樣高 */
    .workspace > .report { height: auto; max-height: 42vh; }
  }

  #viewport {
    border: 1px solid var(--line);
    border-radius: 6px; overflow: hidden; background: var(--card);
  }
  @media (max-width: 900px) { .workspace > * { height: 420px; min-height: 0; } }

  /* 欄與欄之間的把手。與底下的高度把手同一套視覺語彙：
     平時是一條淺色的短線，滑過或拖曳時變主色。 */
  .colgrip {
    cursor: ew-resize; touch-action: none;
    display: flex; align-items: center; justify-content: center;
    background: none; border: 0; padding: 0;
  }
  .colgrip#colgrip1 { grid-area: g1; }
  .colgrip#colgrip2 { grid-area: g2; }
  .colgrip::before {
    content: ""; width: 4px; height: 64px; border-radius: 2px;
    background: var(--line); transition: background .12s;
  }
  .colgrip:hover::before, .colgrip:focus-visible::before,
  .colgrip.dragging::before { background: var(--accent); }
  .colgrip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

  /* ------------------------------------------------------------------------
     高度拖曳把手
     ------------------------------------------------------------------------
     等高解決了「三欄底部對不齊」，但那個高度該是多少沒有標準答案 ——
     筆電上 66vh 是 500px（3D 太扁），外接螢幕上是 900px（要捲很久才看到
     下面的說明）。與其挑一個誰都不滿意的數字，不如讓使用者自己拉。

     用 pointer 事件而不是 mouse：同一段程式碼就同時支援觸控與手寫筆。
     `touch-action: none` 是必要的 —— 少了它，觸控拖曳會被瀏覽器
     解釋成捲動頁面，把手完全沒有反應。 */
  .resize-h {
    grid-column: full;
    height: 14px; margin: 2px 0 0; cursor: ns-resize;
    display: flex; align-items: center; justify-content: center;
    touch-action: none;
  }
  .resize-h::before {
    content: ""; width: 64px; height: 4px; border-radius: 2px;
    background: var(--line); transition: background .12s;
  }
  .resize-h:hover::before, .resize-h:focus-visible::before,
  .resize-h.dragging::before { background: var(--accent); }
  .resize-h:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* 場景控制列：刀具直徑、工件模型、工件平移。
     跟 #viewrow 一樣是滿版帶裡的一條，所以左邊界跟工作區對齊。 */
  .scenebar {
    display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: flex-end;
    padding: 10px 0 2px;
  }
  .scenebar .field { gap: 4px; }
  .scenebar label { font-size: 12px; }
  .scenebar input[type=text] { min-width: 0; width: 92px; padding: 6px 8px; font-size: 14px; }
  .scenebar .wpxyz { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
  .scenebar > p { flex: 1 1 340px; margin: 0; align-self: center; }

  /* ---- 互動分析：點路徑看資訊、查 NC 碼看路徑 ---- */
  /*
     放在工作區**下方**而不是再切一欄：三欄在 1440px 上每一欄都太窄，
     而原文需要至少 40 個等寬欄才不會每一行都折。
  */
  .inspect {
    border: 1px solid var(--line); border-radius: 6px;
    background: var(--card); overflow: hidden;
    /* 與 viewport 等高，而且**內部自己捲** —— 不然原文一長，
       整個頁面就被它撐高，3D 又跑出視線外了。 */
    display: flex; flex-direction: column; min-height: 0;
  }
  .inspect-head {
    display: flex; gap: 10px; align-items: center;
    padding: 8px 10px; border-bottom: 1px solid var(--line); background: var(--band);
  }
  .inspect-head input {
    flex: 0 1 340px; min-width: 0; font: inherit; font-family: var(--mono);
    padding: 4px 8px; border: 1px solid var(--line); border-radius: 4px;
    background: var(--card); color: var(--fg);
  }
  /* 側欄裡是**上下**而不是左右：一欄再切兩欄，兩邊都會窄到不能讀。
     段落資訊短（五六行），原文長 —— 上短下長剛好。 */
  .inspect-body { display: flex; flex-direction: column; min-height: 0; }
  .inspect-panel {
    padding: 10px 12px; border-bottom: 1px solid var(--line);
    flex: 0 0 auto; max-height: 40%; overflow: auto;
  }
  .segdl { display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; margin: 0 0 8px; }
  .segdl dt { color: var(--muted); font-size: 13px; }
  .segdl dd { margin: 0; font-family: var(--mono); font-size: 13px; }
  .segcode {
    margin: 0; padding: 6px 8px; background: var(--band); border-radius: 4px;
    font-family: var(--mono); font-size: 12px; white-space: pre-wrap;
    overflow-wrap: anywhere; color: var(--fg);
  }
  /* NC 原文。**它從頭到尾在瀏覽器裡** —— 顯示它不等於上傳它。 */
  /* 這兩個框的捲軸刻意畫得出來 —— 橫向捲軸的問題不是它存在，
     是它細到讓人以為內容就這麼多。 */
  .workspace > .report,
  .ncsrc {
    scrollbar-width: auto;
  }
  .workspace > .report::-webkit-scrollbar,
  .ncsrc::-webkit-scrollbar { height: 10px; width: 10px; }
  .workspace > .report::-webkit-scrollbar-thumb,
  .ncsrc::-webkit-scrollbar-thumb {
    background: var(--line); border-radius: 5px;
  }
  .workspace > .report::-webkit-scrollbar-thumb:hover,
  .ncsrc::-webkit-scrollbar-thumb:hover { background: var(--muted); }

  .ncsrc {
    margin: 0; padding: 8px 0; flex: 1 1 auto; min-height: 160px; overflow: auto;
    font-family: var(--mono); font-size: 12px; line-height: 1.45;
    background: var(--card); color: var(--fg);
  }
  /* NC 原文：**橫向捲動，不換行。**
     一行 NC 就是一個 block，換行之後「哪些字在同一個 block」要重新判斷 ——
     而那正是讀 NC 時最基本的一件事。行號的縮排也會跟著亂掉。

     橫捲的顧慮是「捲軸在側欄底部不容易發現」，所以 `.ncsrc` 的捲軸
     樣式加粗了一點（見下）。 */
  .ncline { display: block; padding: 0 10px; white-space: pre; }
  /* 行號用 `i` 而不是絕對定位：等寬字型下對齊靠 padStart 就夠，
     而絕對定位在捲動時會有一格的漂移。 */
  .ncline i { color: var(--muted); font-style: normal; user-select: none; }
  .ncline:hover { background: var(--band); cursor: pointer; }
  /* 命中的行。用背景而不是文字顏色 —— 文字顏色會和語法著色打架，
     而且弱視的人分辨不出兩個接近的前景色。 */
  .ncline.on { background: color-mix(in srgb, var(--warn) 22%, transparent); }
  #viewport { position: relative; }
  #viewport canvas { display: block; }
  /* 工具列疊在畫面上而不是排在外面：3D 檢視是一塊固定高度的區域，
     把按鈕放外面會讓它離操作對象太遠。 */
  .view-bar {
    position: absolute; left: 8px; top: 8px; right: 8px;
    display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
    pointer-events: none;
  }
  .view-bar > * { pointer-events: auto; }
  button.view-btn {
    background: var(--bg); color: var(--muted); border: 1px solid var(--line);
    padding: 3px 9px; font-size: 12px; border-radius: 4px; opacity: .92;
  }
  button.view-btn:hover { color: var(--fg); border-color: var(--accent); }
  button.view-btn.on { color: var(--bg); background: var(--accent); border-color: var(--accent); }
  .view-sep { width: 10px; }
  /* 色票：圖例不是控制項，所以不做成按鈕的樣子。 */
  .view-swatches {
    position: absolute; left: 8px; bottom: 8px; right: 8px;
    display: flex; flex-wrap: wrap; gap: 4px 12px;
    font-size: 12px; color: var(--muted);
    background: var(--bg); padding: 5px 9px; border-radius: 4px; opacity: .92;
  }
  .view-swatch { display: inline-flex; align-items: center; gap: 5px; }
  .view-swatch i {
    width: 11px; height: 11px; border-radius: 2px; display: inline-block;
  }
  .view-legend {
    font-size: 12px; color: var(--muted); background: var(--bg);
    padding: 3px 8px; border-radius: 4px; opacity: .92;
  }
  .grid2-wrap > .field { max-width: 420px; }
  /* 範例按鈕：一排小標籤，點下去就載入。 */
  /* 進階區塊：預設收起。低摩擦的那條路不該被它擋住。 */
  /* ------------------------------------------------------------------------
     頂欄
     ------------------------------------------------------------------------
     站名在左、主導覽在中、語言在右上 —— 這是使用者在別的平台上已經學會的
     位置。把語言切換放在頁面正文裡（先前的作法）不會有人找得到，
     因為沒有人會為了找語言而往下讀。

     滿版的底線，但裡面的內容對齊文字欄 —— 那條線讓頁首與內容分開，
     而對齊讓它不像是另外貼上去的東西。 */
  .wrap > .topbar {
    grid-column: full;
    border-bottom: 1px solid var(--line);
    background: var(--card);
    padding-left: max(16px, calc((100% - 1040px) / 2));
    padding-right: max(16px, calc((100% - 1040px) / 2));
    margin-bottom: 8px;
  }
  .topbar-inner {
    display: flex; align-items: center; gap: 8px 20px;
    flex-wrap: wrap;
    min-height: 52px; padding: 8px 0;
  }
  .brand {
    font-weight: 700; font-size: 16px; letter-spacing: -0.01em;
    color: var(--fg); text-decoration: none; margin-right: 4px;
  }
  .topnav { display: flex; gap: 18px; flex-wrap: wrap; font-size: 14px; }
  .topnav a { color: var(--muted); text-decoration: none; padding: 4px 0; }
  .topnav a:hover { color: var(--fg); }
  /* 目前所在的頁面用底線標出來 —— 只靠顏色的話，
     色覺差異或低對比螢幕上就分不出來了。 */
  .topnav a[aria-current="page"] {
    color: var(--fg); font-weight: 600;
    box-shadow: inset 0 -2px 0 var(--accent);
  }

  /* 語言切換靠右。`margin-left: auto` 讓它在窄螢幕換行後仍然貼右邊。 */
  .langswitch {
    margin-left: auto; display: flex; align-items: center; gap: 10px;
    font-size: 13px; color: var(--muted);
  }
  .langswitch a { color: var(--muted); text-decoration: none; }
  .langswitch a:hover { color: var(--fg); text-decoration: underline; }
  .langswitch [aria-current="page"] { color: var(--fg); font-weight: 600; }

  @media (max-width: 640px) {
    /* 窄螢幕：站名與語言一行，導覽自己一行。
       擠在同一行的話導覽會被壓成兩三個字換一次。 */
    .topbar-inner { min-height: 0; }
    .topnav { order: 3; width: 100%; gap: 16px; padding-bottom: 4px; }
    .langswitch { order: 2; }
  }

  /* 頁面標題。與頂欄之間留白，讓兩者不會讀成同一塊。 */
  .wrap > header { padding-top: 18px; }

  /* 收合起來的次要內容。與 details.type2 同樣的外觀 —— 兩者的用途一樣：
     「預設不看，但要看得到」。 */
  details.more,
  details.type2 {
    border: 1px solid var(--line); border-radius: 6px;
    padding: 12px 16px; margin: 18px 0 0; background: var(--card);
  }
  details.more summary,
  details.type2 summary { cursor: pointer; font-size: 14px; }
  details.more .field,
  details.type2 .field { margin-top: 14px; }

  #samples { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: 2px; }
  button.sample {
    background: var(--card); color: var(--fg); border: 1px solid var(--line);
    padding: 3px 9px; font-size: 12px; border-radius: 999px;
  }
  button.sample:hover { border-color: var(--accent); color: var(--accent); }

  pre.report {
    font-family: var(--mono); font-size: 13px; line-height: 1.55;
    background: var(--card); border: 1px solid var(--line); border-radius: 6px;
    padding: 18px; overflow-x: auto; white-space: pre; margin: 24px 0 0;
  }
  .err { color: #b4392f; }
  /* 行內 style 屬性也被 CSP 擋（style-src 沒有 'unsafe-inline'），
     所以連一句話的樣式也要有類別名稱。 */
  .hint-line { margin-top: 14px; font-size: 13px; }
  /* --- 回饋表單 --- */
  .grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin-bottom: 18px; }
  .field textarea {
    font: inherit; padding: 8px 10px; border: 1px solid var(--line);
    border-radius: 4px; background: var(--card); color: var(--fg); resize: vertical;
  }
  /* 探測輸出的貼上區（機台建立頁）。控制器打出來的是等寬對齊的表，
     用比例字型看會錯行 —— 而使用者要靠肉眼確認自己貼完整了。 */
  #probe-input {
    font-family: var(--mono);
    font-size: 12px; width: 100%; box-sizing: border-box; padding: 8px 10px;
    border: 1px solid var(--line); border-radius: 4px;
    background: var(--card); color: var(--fg); resize: vertical;
  }
  #probe-box .opts { margin-top: 10px; align-items: center; }
  #probe-box .opts > button { margin-top: 0; }
  /* 座標列：左邊一個名稱，右邊每一軸一個小輸入格。
     用 grid 而不是 flex —— 六列的軸欄要對齊，
     不對齊的話沒有人看得出哪一格是 Y。 */
  .coordrow {
    display: grid;
    grid-template-columns: minmax(140px, 1.4fr) repeat(auto-fit, minmax(70px, 1fr));
    gap: 6px 10px; align-items: end;
    padding: 6px 0; border-bottom: 1px solid var(--line);
  }
  .coordrow:last-child { border-bottom: 0; }
  .coordname { font-size: 14px; padding-bottom: 8px; }
  .coordcell label { font-size: 12px; }
  .coordcell input { min-width: 0; padding: 6px 8px; font-size: 14px; }
  @media (max-width: 640px) {
    .coordrow { grid-template-columns: repeat(auto-fit, minmax(70px, 1fr)); }
    .coordname { grid-column: 1 / -1; padding-bottom: 0; }
  }

  .req { color: var(--warn); font-weight: 600; }
  .small { font-size: 13px; }
  .ok { color: var(--accent); font-weight: 600; }
  form { margin-top: 8px; }
  /* ------------------------------------------------------------------------
     頁尾
     ------------------------------------------------------------------------
     兩段：連結一段、細字一段。原本全部混在一行用「·」串起來，
     於是「使用條款」跟「引擎版本」看起來一樣重要 —— 而它們不是。 */
  footer {
    border-top: 1px solid var(--line); margin-top: 56px; padding-top: 20px;
    font-size: 13px; color: var(--muted);
  }
  .footlinks {
    display: flex; flex-wrap: wrap; gap: 8px 20px;
    margin-bottom: 12px; font-size: 14px;
  }
  .footlinks a { color: var(--fg); text-decoration: none; }
  .footlinks a:hover { text-decoration: underline; }
  .footnote { line-height: 1.7; }
  .footnote strong { color: var(--fg); }
  a { color: var(--accent); }
  ul, ol { padding-left: 22px; }
  ol { margin: 10px 0; }
  li { margin-bottom: 6px; }

/* ==========================================================================
   說明頁（about.html）
   ==========================================================================
   圖是**內嵌 SVG**，不是圖檔也不是繪圖程式庫。三個理由：

     - CSP 是 script-src / img-src 'self'，外部繪圖程式庫載不進來，
       而夾帶一個只為了畫六個方塊的程式庫不划算。
     - 圖檔要為深淺兩種主題各出一份，然後它們會各自過期。
       內嵌 SVG 用 currentColor 與 var(--…)，跟著主題走。
     - 圖裡的字是**真的文字** —— 可以選取、可以被搜尋、螢幕閱讀器讀得到。
       每張圖都有 <title> 與 <desc>。
   ========================================================================== */

.pagenav {
  margin: 0 0 2rem;
  font-size: 0.92rem;
  color: var(--muted);
}
.pagenav a { color: var(--muted); }
.pagenav a:hover { color: var(--accent); }

.figure { margin: 1.5rem 0 2rem; }

/* 圖比版面寬時**自己捲**，而不是把整頁撐寬 —— 手機上整頁橫向捲動
   會讓每一段文字都要左右拉。 */
.figscroll {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  padding: 1rem 0.75rem;
}
.dia { display: block; width: 100%; min-width: 480px; height: auto; }
.figcap {
  margin: 0.6rem 0 0;
  font-size: 0.9rem;
  color: var(--muted);
}

.dia-box rect { fill: var(--band); stroke: var(--line); stroke-width: 1.5; }
.dia-box.inner rect { fill: var(--card); }
.dia-box.dashed rect { fill: none; stroke-dasharray: 5 4; }
.dia-boxtext text { fill: var(--fg); font-size: 15px; text-anchor: middle; }
.dia-boxtext text.s { fill: var(--muted); font-size: 12px; }
.dia-boxtext.muted text { fill: var(--muted); }
.dia-arrow path { fill: none; stroke: var(--muted); stroke-width: 1.5; }
.dia-arrow.blocked path { stroke-dasharray: 5 4; }
.dia-axis line { stroke: var(--line); stroke-width: 1.5; }
.dia-tick line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 3; }
.dia-lbl { fill: var(--muted); font-size: 13px; }
.dia-note { fill: var(--muted); font-size: 12px; }
.dia-note.warn { fill: var(--warn); }
.dia-cam { fill: none; stroke: var(--muted); stroke-width: 2; stroke-dasharray: 6 4; }
.dia-act { fill: none; stroke: var(--accent); stroke-width: 2.5; }
.dia-cross path { stroke: var(--warn); stroke-width: 2.5; stroke-linecap: round; }

/* 表格與報告、NC 清單一樣：寬了就自己捲，不換行。 */
.tablescroll { overflow-x: auto; margin: 1rem 0 1.5rem; }
table.grid { border-collapse: collapse; width: 100%; min-width: 460px; }
table.grid th,
table.grid td {
  border: 1px solid var(--line);
  padding: 0.55rem 0.75rem;
  text-align: left;
  vertical-align: top;
}
table.grid th { background: var(--band); font-weight: 600; }

.roadmap { display: grid; gap: 1rem; margin: 1rem 0 1.5rem; }
@media (min-width: 900px) {
  .roadmap { grid-template-columns: repeat(3, 1fr); align-items: start; }
}
.rm {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  padding: 0.25rem 1rem 1rem;
}
/* 三段用左邊一條色帶區分，而不是三種背景色 ——
   背景色在深色主題下很難同時保持可讀與可分辨。 */
.rm { border-left: 3px solid var(--line); }
.rm-now { border-left-color: var(--accent); }
.rm-next { border-left-color: var(--muted); }
.rm h3 { font-size: 1rem; margin: 1rem 0 0.5rem; }
.rm ul { margin: 0; padding-left: 1.1rem; }
.rm li { margin-bottom: 0.8rem; }
.rm li:last-child { margin-bottom: 0; }

/* ==========================================================================
   報告摘要列（#verdict）
   ==========================================================================
   整個產品的高潮是「引擎工時 vs 既有估值」這兩個數字的差 ——
   完整報告是等寬文字，那兩個數字埋在中段。這一列把它們抬出來。
   它**不新增任何報告沒有的數字**，所以不會與報告漂移。 */
.verdict {
  display: flex; flex-wrap: wrap; align-items: stretch;
  gap: 0.75rem 2.5rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.9rem 1.4rem;
  margin: 1rem 0;
}
.v-group { display: flex; flex-wrap: wrap; gap: 0.75rem 2.5rem; }
.v-cell { display: flex; flex-direction: column; }
.v-label {
  font-size: 0.78rem;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.v-num,
.v-diff {
  font-family: var(--mono);
  font-size: 1.7rem;
  font-weight: 600;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}
/* 差異的顏色只分「值不值得看一眼」：10% 以內不上色。
   正（我們算得比較久 = 既有估值偏低）用警示色 —— 那正是要賣的那一課。 */
.v-diff.hot { color: var(--warn); }
.v-diff.cold { color: var(--accent); }
.v-invite { align-self: center; margin: 0; font-size: 0.9rem; }

/* 下載報告：從摘要列的右端出。
   原本它是 `.secondary`（13px 灰色底線文字）與 3D 切換擠在同一行 ——
   實測「剛剛沒看到」。而這份 HTML 報告是客戶真正要的交付物（`02` §3.2 P1），
   也是回饋回流的載體（DR-99）：看不到它，那條動線整條不存在。 */
.v-actions { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.v-actions button { white-space: nowrap; }
.v-sub { font-size: 12px; color: var(--muted); }
@media (max-width: 640px) {
  .v-actions { margin-left: 0; align-items: flex-start; width: 100%; }
}
