/* Hallmark · genre: modern-minimal · theme: custom "Instrument" (teal 205°) · design-system: design.md · designed-as-app
   トークンの正典は tokens.css (index.html/test.html が style.css より先に読み込む)。
   ここにはトークンを定義しない — 値の変更は tokens.css と design.md で行う。 */

/* ============ 基本 ============ */
* { box-sizing: border-box; }
[hidden] { display: none !important; }

/* R11-1: フォームコントロールはブラウザ既定の書体 (Chrome では Arial) を使う。
   `font` は継承されないので、ここで 1 度だけ全部に継がせる。個々の部品で
   `font: inherit` を書き足す方式は取りこぼしを生み、実測で 53 要素
   (ツールバーのラベル `.tb-lbl` / `.wt-lbl` / `.gt-lbl`、`.tb-btn` `.wt-btn`
   `.exp-hbtn` `.mdi-btn` ほか) が Arial のまま残っていた。
   `font-family` だけを継がせる (`font` 一括だと size/weight まで巻き込む)。 */
button, input, select, textarea, optgroup { font-family: inherit; }

/* ============ 線画アイコンの唯一の契約 (R11-16) ============
   依頼の規約: 「16px または 18px を基本」「同じツールバー内で複数サイズを混在させない」
   「線幅を統一する」。実測では**寸法 8 種 (11/12/13/14/15/16 と非正方 12×13 / 14×15)・
   線幅 9 種 (1 / 1.2 / 1.3 / 1.4 / 1.5 / 1.6 / 1.8 / 2)** が混在していた。原因は
   寸法と線幅が 11 箇所の個別規則と SVG のインライン属性に散っていたこと。

   ここで一括して決める。CSS は SVG のプレゼンテーション属性 (width/height/stroke-width)
   に**優先する**ので、既存のインライン属性はこの規則で上書きされる。
   fill は触らない — 塗りアイコン (整列/分布・面グラフ・ヒートマップ) を潰さないため。

   段は 2 つだけ:
     --icon-md(16) = 既定 (メニューバー / 第1層 / 第2層 / 窓タイトルバー / メニュー項目)
     --icon-sm(14) = 高密度な行 (Explorer のツリー行 / ステータスバー / パネル内の小操作) */
#menubar-row svg, #toolbar svg, .mdi-titlebar svg, .mdi-wintoolbar svg,
#explorer svg, #pp-host svg, #statusbar svg, .menu-drop svg, .graph-tools svg {
  width: var(--icon-md);
  height: var(--icon-md);
  flex: none;
  /* svg 要素にも置く: 子を持たない字形と、`getComputedStyle(svg).strokeWidth` を
     読む検査の両方が同じ値を見られるようにする (下の子規則が最終的な描画を決める)。 */
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* 線幅は**図形そのもの**に掛ける。svg 要素にだけ書くと、子の `stroke-width` 属性
   (GRAPH_TOOL_ICONS などが持つ 1.7 / 2.8) が継承値に勝って残る。
   `non-scaling-stroke` を併用するのは、一部の字形が 24 単位で描かれて
   `<g transform="scale(0.667)">` で縮められており、変換のぶんだけ線幅がずれるため
   (実測 1.13 / 1.2 / 1.87 と不揃いだった)。画面上の線幅を直接指定して揃える。 */
#menubar-row svg *, #toolbar svg *, .mdi-titlebar svg *, .mdi-wintoolbar svg *,
#explorer svg *, #pp-host svg *, #statusbar svg *, .menu-drop svg *, .graph-tools svg * {
  stroke-width: var(--icon-stroke);
  vector-effect: non-scaling-stroke;
}
/* 高密度な面: 1 つの帯 / 行の中では**必ず同じ寸法**にする
   (依頼の規約「同じツールバー内で複数サイズを混在させない」)。
   窓タイトルバー (28px) と Explorer のツリーは帯ごと sm へ寄せる —
   旧実装は同じタイトルバーの中で種別アイコン 16 と窓ボタン 13 が混ざっていた。 */
/* 窓タイトルバーは **md(16) のまま** 帯ごと揃える (種別アイコンも窓ボタンも 16)。
   28px の帯に 16px は収まり、T3.19 が求める「タイトルバーのアイコンは 16px」とも一致する。
   旧実装の混在 (種別 16 / 窓ボタン 13) だけを解消する。 */
#explorer svg, #statusbar svg,
.pp-sec-caret svg, .pp-ds-del svg, .pp-levtab svg,
.link-chip svg, .ds-chip svg {
  width: var(--icon-sm);
  height: var(--icon-sm);
}
/* 線画の既定。塗りを明示している字形 (整列/分布・面グラフ・ヒートマップ) は
   自分の fill 属性を持つので、ここでは **svg 要素にだけ** 既定を置く
   (子へ fill:none を配ると属性より CSS が勝って塗りアイコンが消える)。 */
#menubar-row svg, #toolbar svg, .mdi-titlebar svg, .mdi-wintoolbar svg,
#explorer svg, #pp-host svg, #statusbar svg, .menu-drop svg, .graph-tools svg {
  fill: none;
  stroke: currentColor;
}

/* ============ 自作カーソルをアプリ全体に適用 ============
   変数は main.js 起動時に CURSORS から注入される */
html, body, * { cursor: var(--cur-arrow, default); }

/* クリック可能要素 → 人差し指ポインタ */
button, .btn, .tb-btn, .menu-label, .menu-item, .exp-item, .exp-folder,
.dlg-tab, .dlg-subtab, .axis-side-item, .br-chip, .check-label,
.tb-flyout-menu button, .gt-sub button, .graph-tools button,
.mdi-btn, .log-titlebar .btn, label[for], select,
input[type="checkbox"], input[type="color"],
.ws-colhead th[data-col], tr.sel-row,
.series-table .rl-del, .ds-del {
  cursor: var(--cur-pointer, pointer);
}
button *, .btn *, .menu-item *, .tb-btn *, .graph-tools button * {
  cursor: var(--cur-pointer, pointer);
}

/* テキスト入力 → I ビーム */
input[type="text"], input[type="number"], textarea, .ws-edit, .anno-input {
  cursor: var(--cur-text, text);
}

/* ワークシートのデータセル → 精密十字 */
.ws-table tbody td { cursor: var(--cur-text, text); }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--ui-font-size, 13px);   /* 設定画面で変更可。基準 UI テキストサイズ */
  line-height: 1.5;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}
body { display: flex; flex-direction: column; }
.spacer { flex: 1; }
.muted { color: var(--muted); }

/* ============ メニューバー ============ */
#menubar-row {
  display: flex;
  align-items: center;
  min-height: var(--menubar-h);
  /* D-110 (2026-08-05): メニューバーは**筐体**。tokens.css は当初から
     「--bg = 装置の筐体 (メニューバー / ステータスバー / スプリッタの地)」と
     定義していたのに、実装は --panel を使っており、筐体という面がアプリの
     どこにも存在しなかった。結果、上端 (メニュー) → ツールバー → パネルが
     ほぼ同じ明度で続き、画面に「本体の外枠」が無く上から下まで均一に見えていた。
     下端のステータスバーは既に --bg なので、これで上下が同じ面で挟む形になり、
     作業面 (机 + 紙) が筐体に収まっている構図が成立する。 */
  background: var(--chrome-bg);
  border-bottom: 1px solid var(--chrome-border);
  padding: 0 14px;
  color: var(--chrome-ink);
  gap: 0;
  user-select: none;
}
.brand { flex: none; display: flex; align-items: center; gap: 10px; padding: 0; min-width: 92px; }
.brand .logo { display: block; flex: none; width: 22px; height: 22px; border-radius: 6px; object-fit: cover; }
/* Wordmark: the supplied logo artwork is pure white on the dark application chrome.
   Trebuchet MS Bold gives TANUKI a sturdy, compact silhouette without Impact's density. */
.brand-name {
  color: #fff;
  font-family: "Trebuchet MS", Arial, sans-serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .015em;
  line-height: 1;
}
.chrome-divider { width: 1px; height: 20px; margin: 0 16px 0 14px; background: var(--chrome-border); flex: none; }

/* 右上の設定ギア (アイコンのみ・テキスト無し) */
.menubar-settings {
  flex: none; display: grid; place-items: center; width: 30px; height: 26px; margin-right: 2px;
  border: none; background: transparent; color: var(--chrome-ink-muted); border-radius: var(--radius-md);
  cursor: var(--cur-pointer, pointer);
}
.menubar-settings:hover { color: var(--chrome-ink); background: var(--chrome-hover); }
.menubar-settings:focus-visible { box-shadow: var(--focus-ring); outline: none; }
.menubar-settings svg { display: block; }

/* メニュー(File…Help)は十分な幅では自然配置。狭幅では縮んで横スクロール可にし、
   右端の設定ギア(.menubar-settings)を常にビューポート内へ留める。スクロールバーは隠す。 */
#menubar { display: flex; flex: 0 1 auto; min-width: 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
#menubar::-webkit-scrollbar { display: none; }
.menu-label { flex: none; }
.menu-label {
  display: inline-flex;
  align-items: center;
  height: 100%;
  padding: 0 12px;
  /* D-70: メニューバーのラベルはメニュー項目 (本文 = --fs-md) と同じ字送り。
     旧実装だけが --fs-lg (14px) で、アプリ内で唯一この段を使っていた。
     --fs-lg は「数値結果 (.fit-metric-v)」とドロップ先の大きな案内に予約する。 */
  font-size: var(--fs-md);
  cursor: var(--cur-pointer, pointer);
  color: var(--chrome-ink-muted);
  border-radius: var(--radius-sm);
}
.menu-label:hover { background: var(--chrome-hover); color: var(--chrome-ink); }
.menu-label.open { background: var(--chrome-hover); color: var(--chrome-ink); }

.menu-drop {
  position: fixed;
  z-index: var(--z-menu);   /* モーダル(--z-modal)より上。#workspace の isolation で窓の z とは別コンテキスト */
  min-width: 190px;
  background: var(--panel-2);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlay);
  padding: 4px;
  user-select: none;
  /* 長いメニュー(プロット等)が画面下端を超えても全項目に届くよう縦スクロール */
  max-height: calc(100vh - 44px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.menu-item {
  display: flex;
  align-items: center;
  /* 高さはトークンで決める (--menu-item-h)。padding で高さを作ると
     「同じ役割は同じ寸法」という規約から静かに外れる。 */
  min-height: var(--menu-item-h);
  padding: 0 10px 0 4px;
  border-radius: var(--radius-sm);
  cursor: var(--cur-pointer, pointer);
  white-space: nowrap;
}
.menu-item:hover { background: var(--surface-hover); color: var(--text); }
.menu-item.disabled { opacity: 0.4; cursor: default; pointer-events: none; }
.menu-item .check { width: 18px; text-align: center; font-size: var(--fs-sm); flex: none; }
.menu-item .shortcut { margin-left: auto; padding-left: 26px; font-size: var(--fs-sm); opacity: 0.6; }
.menu-sep { height: 1px; background: var(--panel-border); margin: 4px 6px; }
/* T2.7: メニュー内の群見出し (クリック不可)。ファイルメニューを
   プロジェクト / データ / エクスポート の 3 群に視覚的に分ける。 */
.menu-header {
  padding: 5px 12px 2px;
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  color: var(--muted);
  text-transform: none;
  pointer-events: none;
  user-select: none;
}

/* ============ ツールバー ============ */
/* R9-M5: 表示メニューからアプリツールバー (機能の第 1 層) を畳む。
   高さごと消す = 作業スペースがそのぶん広がる。中身は消さないので戻すと同じ並びで戻る。 */
#toolbar.collapsed { display: none; }
#toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-start;  /* 左揃え (作業スペース上端左詰め) */
  gap: 0;
  height: var(--toolbar-h);
  width: 100%;
  padding: 0 16px;
  /* トークンの定義どおり「パネル / ツールバー」の面。--bg は筐体 (メニューバー /
     ステータスバー) の面で、ここに使うとツールバーだけが背後のワークスペースより
     沈み、「手前ほど明るい」という面階層が逆転する。 */
  background: var(--panel-2);
  border-bottom: 1px solid var(--panel-border);
  user-select: none;
  /* 横はみ出しはクリップしてページ全体の横スクロールを防ぐ。縦は visible のまま
     (clip+visible は Chromium で縦に伝播しない) なので下方向のフライアウトは切れない。 */
  overflow-x: clip;
  overflow-y: visible;
}
.tb-group { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.tb-group-end { gap: 4px; padding-left: 12px; border-left: 1px solid var(--panel-border); }
.tb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 30px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  cursor: var(--cur-pointer, pointer);
}
/* R9-H2: 有効なボタンは本文と同じインク。旧実装は `--muted` で、
   第 1 層ツールバーだけが**メニューバー (--text) と第 2 層 (--text) に挟まれた
   二次色の行**になり、階層が逆転していた。加えて有効 (--muted) と
   無効 (--text-disabled) の差が 1.2:1 しかなく、履歴の有無で undo/redo の
   見た目が変わらなかった。`.wt-btn` が同じ理由で --muted を退けている。 */
.tb-btn:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--panel-border); color: var(--text); }
.tb-btn:active:not(:disabled) { transform: translateY(1px); }
.tb-btn:focus-visible { box-shadow: var(--focus-ring); outline: none; }
.tb-btn:disabled { color: var(--text-disabled); cursor: var(--cur-arrow, default); }
/* ラベル/ショートカット付きのボタンは幅を自動に。
   アイコン単独を許すのは意味が世界的に定着した操作 (保存 / 元に戻す / やり直し) だけで、
   ドメイン固有の「ブック / 行列 / 取込」は短いラベルを併記する (design.md「アイコンとラベル」)。 */
.tb-btn.tb-wide { width: auto; gap: var(--icon-gap); padding: 0 9px; font-size: var(--fs-base); }
.tb-lbl { white-space: nowrap; }
.tb-command-trigger { min-width: 205px; justify-content: flex-start; }
.tb-command-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-align: left; white-space: nowrap; color: var(--muted); }
.tb-sep { width: 1px; height: 20px; background: var(--panel-border); margin: 0 14px; flex: none; }
.tb-spacer { flex: 1 1 auto; min-width: 0; }

/* 狭い画面でも上部クロームを壊さない。情報を隠す順番を決め、横スクロールを
   画面全体へ伝播させない。アイコンとツールチップは残し、発見性を落とさない。 */
@media (max-width: 760px) {
  #menubar-row { padding: 0 8px; }
  .brand { min-width: 28px; }
  .brand-name, .chrome-divider { display: none; }
  .menu-label { padding: 0 9px; }
  #toolbar { padding: 0 8px; overflow-x: auto; scrollbar-width: none; }
  #toolbar::-webkit-scrollbar { display: none; }
  .tb-group-project .tb-btn { width: 32px; padding: 0; }
  .tb-group-data #tb-new-book { width: 32px; padding: 0; }
  .tb-group-data #tb-new-book .tb-lbl { display: none; }
  .tb-group-data #tb-import { width: 32px; padding: 0; }
  .tb-group-data #tb-import .tb-lbl { display: none; }
  .tb-command-trigger { width: 32px; min-width: 32px; padding: 0; }
  .tb-command-label, .tb-command-trigger .tb-kbd { display: none; }
  .tb-sep { margin: 0 8px; }
}

/* プロット種類のフライアウト */
.tb-flyout { position: relative; }
.tb-flyout-main { width: auto; padding: 0 5px; gap: 3px; }
.tb-caret { opacity: 0.6; }
.tb-flyout-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  z-index: var(--z-menu);   /* ツールバーは #workspace 外。メニュー群としてモーダルより前面へ */
  min-width: 190px;
  background: var(--panel-2);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlay);
  padding: 4px;
}
.tb-flyout:hover .tb-flyout-menu { display: block; }
.tb-flyout-menu button {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 6px 10px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font-size: var(--fs-md);
  cursor: var(--cur-pointer, pointer);
  text-align: left;
}
.tb-flyout-menu button:hover { background: var(--surface-hover); color: var(--text); }
.tb-flyout-menu svg { flex: none; }

/* スクリーンリーダー専用テキスト。視覚的には消えるが読み上げには残る。
   連結文字列を避けて i18n の DOM 翻訳を効かせる目的でも使う (wintoolbar.js の作用対象)。 */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============ 共通パネル見出し (D-47) ============
   4 系統 (Explorer h2 / プロパティパネル / ダイアログタイトル / フィット窓ポップオーバー) に
   分裂していた見出しタイポを 1 つの仕様に統一する。パディングは親要素が持つ (この class は文字だけ)。
   1 段下の「節見出し」(.fit-sec-title / .an-sec-title / .pp-sec-head) は --fs-sm / 700 / --text、
   さらに 1 段下の「小群見出し」(.fit-subsec-head / .pp-grouphead) は --fs-xs / 700 / --muted。
   役割ごとの一覧は design.md「タイポグラフィの役割」の表を正典とする (D-70)。 */
/* パネル見出しは**その下に並ぶ内容より上位**に見えなければならない。
   旧実装は 11px / --muted で、13px / --text のツリー項目より小さく淡く、
   見出しのほうが埋もれていた (階層が逆転していた)。
   本文と同じ字送り (--fs-md) に置き、weight と主色で上位であることを示す。
   ここで大きくしすぎない (「大きな見出しを多用しない」規約) 代わりに、
   下のヘアラインと帯の余白で区切りを作る。 */
.panel-title {
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  text-transform: none;
  color: var(--text);
  line-height: var(--lh-tight);
}

/* ============ ボタン ============ */
/* D-01/D-02: 高さは --control-h、角丸は --radius-ctl。padding で高さを作らない
   (input/select と同じトークンに揃うため、同一行で背が揃う)。 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-inline);
  height: var(--control-h);
  padding: 0 10px;
  border-radius: var(--radius-ctl);
  border: 1px solid var(--control-border);   /* R9-H3: 輪郭だけで「押せる」と分かる (3:1) */
  background: var(--panel-2);
  color: var(--text);
  /* D-51: コントロールの文字サイズは input / select と同一 (--fs-base)。
     旧実装だけ --fs-md (13px) だったため、同じ行に 13/12/11px が混在していた。 */
  font-size: var(--fs-base);
  cursor: var(--cur-pointer, pointer);
  white-space: nowrap;
  user-select: none;
  /* D-52: ボタンは横方向に潰れない (flex: none)。潰れると nowrap のラベルが枠外へ溢れるため、
     溢れは「ボタン列側の折返し / 横スクロール」で受ける (下の .btn-row / .fit-comp-ops)。 */
  flex: none;
}
/* D-52: ボタンが横に並ぶ行の共通挙動。幅が足りなければ次の行へ送る (ボタン自体は縮めない)。 */
.btn-row { display: flex; flex-wrap: wrap; gap: var(--gap-inline); align-items: center; }
.btn:hover:not(:disabled) { background: var(--surface-hover); }
.btn:disabled { opacity: 0.45; cursor: var(--cur-arrow, default); }
/* Primary は「その操作領域で最も重要な実行操作」。塗りは --accent-solid (--accent は
   フォーカス/選択の**指示線**用で、塗りに使うと信号と装飾の区別が消える)。
   1 つの操作領域に 1 つだけ置く。 */
.btn.primary { background: var(--accent-solid); border-color: transparent; color: var(--accent-text); font-weight: 600; }
.btn.primary:hover:not(:disabled) { background: var(--accent-solid-hover); }
/* E-1: ghost も背景/境界を持つ明確なボタンに (テキストに見えていた問題)。hover/active/focus は .btn 共通。 */
/* R9-H3: ghost は「控えめな二次操作」であって「地に溶ける」ではない。
   旧実装は background:--panel で、--panel のツールバー/フッタに置くと
   塗りの差がゼロになり、1.4:1 の枠だけが残って浮いた文字列に見えていた
   (フィット窓の Preview / ステップ / 保存)。面は必ず地より一段持ち上げる。 */
.btn.ghost { background: var(--panel-2); border-color: var(--control-border); }
.btn.ghost:hover:not(:disabled) { background: var(--surface-hover); }
.btn.danger { background: transparent; border-color: var(--bad); color: var(--bad); }   /* U.2: 破壊操作(意味色) */
/* Destructive: 常時赤く塗らず、境界と文字だけで危険性を示す。塗りが出るのはホバー時のみ。 */
.btn.danger:hover:not(:disabled) { background: color-mix(in srgb, var(--bad) 12%, transparent); }
.btn:focus-visible { box-shadow: var(--focus-ring); outline: none; }                     /* U.2: フォーカス1系統 */
.btn:active:not(:disabled) { transform: translateY(1px); }                               /* 押下キュー (transform のみ) */
.btn.icon-only { padding: 0 5px; }
.btn.mini { height: var(--control-h-sm); padding: 0 8px; font-size: var(--fs-sm); }

/* ============ レイアウト ============ */
#layout {
  position: relative;   /* #sidebar-split / #pp-split (absolute) の基準 */
  flex: 1;
  display: grid;
  /* サイドバー幅は実効変数(--sidebar-w-eff)を使う。clampDocks() が狭幅時に縮小して設定し、
     未設定時(JS前)はユーザー設定幅(--sidebar-w)→既定値にフォールバック。
     中央は minmax(0,1fr) で 0 まで縮められるようにし、固定列が画面外へ押し出すのを防ぐ。
     右端はプロパティパネル: 収納時は 32px の縦見出しレール、展開時は --pp-w-eff。 */
  grid-template-columns: var(--sidebar-w-eff, var(--sidebar-w, 244px)) minmax(0, 1fr) 32px;   /* 左サイドバー | 作業スペース | プロパティ(右ドック) */
  min-height: 0;
  /* D-48: パネルの表示/収納をイージング付きで遷移させる (Chromium は grid-template-columns を補間する。
     非対応環境では瞬間切替に劣化するだけで破綻しない)。スプリッタのドラッグ中は .dock-dragging で無効化。 */
  transition: grid-template-columns var(--dur-med) var(--ease-out);
}
/* スプリッタのドラッグ中 (body.col-resizing) は追従が鈍るので遷移を切る。 */
body.col-resizing #layout { transition: none; }
/* R9-M5: 表示メニューからサイドバーを畳む。列を 0 にし、境界のハンドルも一緒に消す
   (残すと掴めるのに動かせないハンドルになる)。幅そのものは --sidebar-w に残るので、
   もう一度出したときは同じ幅で戻る。 */
#layout.sidebar-hidden { grid-template-columns: 0 minmax(0, 1fr) 32px; }
#layout.sidebar-hidden.pp-open { grid-template-columns: 0 minmax(0, 1fr) var(--pp-w-eff, var(--pp-w, 320px)); }
#layout.sidebar-hidden #sidebar { display: none; }
#layout.sidebar-hidden #sidebar-split { display: none; }
.pp-host { transition: opacity var(--dur-short) var(--ease-out); }
/* 展開時はプロパティ列を可変幅に。clampDocks() が --pp-w-eff を書き込む (狭幅で縮小)。 */
#layout.pp-open {
  grid-template-columns: var(--sidebar-w-eff, var(--sidebar-w, 244px)) minmax(0, 1fr) var(--pp-w-eff, var(--pp-w, 320px));
}

/* サイドバー幅の調整ハンドル: サイドバー/作業スペースの境界に重ねて配置。
   left を --sidebar-w に合わせるので幅変更に追従する。当たり判定 6px・見た目は中央 2px。 */
#sidebar-split {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--sidebar-w-eff, var(--sidebar-w, 244px));
  width: 6px;
  transform: translateX(-3px);   /* 境界線(border-right)の中心に重ねる */
  cursor: col-resize;
  z-index: 6;
  background: transparent;
}
#sidebar-split:hover { background: color-mix(in srgb, var(--accent) 40%, transparent); }
#sidebar-split:focus-visible { outline: none; background: var(--accent); }
/* ドラッグ中は全体で col-resize カーソルを維持し、テキスト選択を抑止する */
body.col-resizing { cursor: col-resize; user-select: none; }
body.col-resizing * { cursor: col-resize !important; }

/* ===== MDI フィット窓 (kind:"fit") — 4行レイアウト (#8/#9) ===== */
/* (1) topbar モード / (2) tabbar 横タブ / (3) win-mid 左グラフ|スプリッタ|右body / (4) footbar 実行系。
   コンテンツ根は縦積み。win-mid だけが横並び (左右分割) を担う。 */
.mdi-window.fit-window .mdi-content.fit-win-content {
  display: flex; flex-direction: column; min-height: 0; min-width: 0; overflow: hidden;
  background: var(--panel);
}
/* (3) 中段: 左プレビュー / 縦スプリッタ / 右 body の横並び。上下の bar を除いた残り全部 (flex:1)。 */
.fit-win-mid { flex: 1 1 auto; min-height: 0; min-width: 0; display: flex; flex-direction: row; overflow: hidden; }
/* プレビュー列 (左): 主プロット + 残差ストリップ を縦積み。幅は残り全部 (flex:1) */
.fit-preview-col { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 280px; min-height: 0; border-right: 1px solid var(--panel-border); }
/* M6: プレビュー上端の常設ツールストリップ (左=グラフ操作, 右=残差トグル)。
   canvas 上の absolute パレット/トグルを廃し、Y 軸タイトル/凡例の遮蔽をゼロにする。 */
.fit-toolstrip { flex: none; display: flex; align-items: center; gap: var(--gap-inline); height: 26px; padding: 0 var(--pad-ctl-x-sm); background: var(--panel); border-bottom: 1px solid var(--panel-border); }
.fit-preview-pane { position: relative; flex: 1 1 auto; min-width: 0; min-height: 0; overflow: hidden; background: var(--panel-2); }
.fit-preview-canvas { display: block; width: 100%; height: 100%; }
/* 残差ストリップ (要件17): 主プロット下段・高さ ~22%・上境界線で区切り */
/* F13 (2026-08-05): 主図と残差は**1 枚の図の上下段**として読ませる。
   旧実装は器のヘアライン + 両者それぞれの四辺フレーム = 境目に線が 3 本あり、
   X を共有していることが「左右がたまたま揃っている」ようにしか見えなかった。
   器の線を外し、残差側の上辺も描かない (residAxisConfig) ことで、主図の下辺が
   そのまま残差の天井になる。 */
.fit-resid-strip { position: relative; flex: 0 0 24%; min-height: 72px; overflow: hidden; background: var(--panel-2); }
.fit-resid-strip[hidden] { display: none; }
/* D-14: 除外域を追加するモード中であることをプレビュー枠でも示す (ツールボタンの active と二重表示)。 */
.fit-preview-pane.excluding { box-shadow: inset 0 0 0 1px var(--accent); }
.fit-resid-canvas { display: block; width: 100%; height: 100%; }
/* C4: 回転 Y タイトル「残差」の代替。ストリップ左肩に小さく載せる (fs-xs・muted)。 */
/* D-36: Y 目盛りラベルはプロットの左マージンに描かれるので、DOM ラベルは **右上**へ置く。
   背景を不透明 + 1px 枠にして、下の描画が透けて読みにくくなるのも防ぐ。 */
/* F4 (2026-08-05): この**図のラベルは残す** (図に名前を付けるのは科学プロットの
   正しい作法で、R12-6 が枠の内側へ正しく置いている)。重複はトグル側を
   アイコンのみにして解消した。 */
.fit-resid-label { position: absolute; top: 3px; right: 6px; left: auto; z-index: var(--z-float); pointer-events: none;
  font-size: var(--fs-xs); color: var(--muted); background: var(--panel-2); border: 1px solid var(--panel-border);
  padding: 0 4px; border-radius: var(--radius-ctl); }
/* M6: 残差トグルは toolstrip 右端へ (旧 absolute 右上を廃止)。 */
/* F4: アイコンのみのトグル (名前は図のラベルが持つ)。正方形にしてターゲットサイズを保つ。 */
.fit-resid-toggle { flex: none; margin-left: auto; width: var(--control-h); padding: 0; }
.fit-resid-toggle svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.fit-resid-toggle.active { background: color-mix(in srgb, var(--accent) 14%, var(--panel-2)); border-color: var(--accent); color: var(--accent); }
/* 左右スプリッタ */
.fit-win-hsplit { flex: none; width: 6px; cursor: col-resize; background: transparent; }
.fit-win-hsplit:hover { background: color-mix(in srgb, var(--accent) 40%, transparent); }
.fit-win-hsplit:focus-visible { outline: none; background: var(--accent); }
/* 右パネル本体: 幅は JS が可変 (_bodyW)。アクティブタブの1節のみを描画する縦スクロール領域。 */
.fit-win-body {
  flex: none; min-height: 0; min-width: 0;
  overflow-y: auto; overflow-x: hidden;
  padding: 6px 10px 12px; background: var(--panel); font-size: var(--fs-base);
}
/* データピッカー (D3) */
/* §14: データソース節は「範囲」節 (.fit-kv) と同じ縦リズム。旧実装はここだけ gap を持たず、
   同じ形のフォーム行なのに行間が 24px / 30px と食い違っていた。節の区切りは
   subsecHead の上境界線が担うので、ここの破線は不要 (二重の区切りを作らない)。 */
.fit-picker { display: flex; flex-direction: column; gap: var(--gap-stack); padding: 2px 0 var(--gap-inline); }

/* §27: 直接選択の 3 つ道具。
   「実物をクリックして決める」操作は、名前を読んでセレクトから選ぶ操作より先に置く。
   平文のボタンではなく **道具のタイル** として、いま何が入っているか (val) と
   いま構えているか (armed) を、押す前から読めるようにする。
   armed の表現は 面 + アイコンのアクセント + 状態行の 3 手掛かり
   (一辺のアクセント線は使わない = 絶対規約)。 */
/* F1 (2026-08-05): 直接指定の道具は**節見出しの右肩**に置くアイコンボタン。
   旧実装は 3 枚の大きな瓦を独立した節に並べていたが、瓦は armed 時以外まったく
   無表情なので、画面上は「同じ状態への 2 つの操作系」が縦積みされているように
   しか見えなかった。見出しへ移すと操作と値の従属関係が位置で表れ、Data タブの
   上 1/3 を占めていた面積がそのまま値の表示へ回る。
   armed は 面 + アクセントのアイコン + 案内帯の 3 手掛かり (一辺の線は使わない)。 */
.fit-sechd-tools { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; }
.fit-sechd-tool {
  display: inline-flex; align-items: center; justify-content: center;
  /* WCAG 2.2 SC 2.5.8 — 見出しの中でもターゲットサイズは落とさない。 */
  width: var(--control-h); height: var(--control-h);
  padding: 0; cursor: var(--cur-pointer, pointer);
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-ctl);
  color: var(--muted);
  transition: background var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out);
}
.fit-sechd-tool svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.fit-sechd-tool:hover { background: var(--surface-hover); color: var(--text); }
.fit-sechd-tool:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
.fit-sechd-tool.armed { background: var(--sel-bg); border-color: var(--accent); color: var(--accent); }
/* 複数モードで「いま割り当てる対象」の行。面 + 左のインデントで示す (一辺の線は使わない)。 */
.fit-ds-row.current { background: var(--sel-bg); }
.fit-ds-row.current .fit-ds-num { color: var(--accent); font-weight: 700; }
/* ===== 4行 chrome (topbar / tabbar / footbar・すべてフル幅を左右に通す) ===== */
/* (1) 最上部: モードセグメント (左) + Fit名/状態 (右) */
.fit-topbar { flex: none; display: flex; align-items: center; gap: var(--space-2); padding: 5px 10px; border-bottom: 1px solid var(--panel-border); }
/* D-05: 2 段セグメント。第1階層 [単一|複数] のすぐ右に、複数選択時のみ第2階層 [バッチ|グローバル]。 */
.fit-topbar .fit-fitmodeseg, .fit-topbar .fit-multikindseg { flex: none; }
/* D-06: 各モードボタンは 16px 線画アイコン + 短ラベル。 */
.fit-modebtn { display: inline-flex; align-items: center; gap: 5px; }
.fit-modebtn svg { flex: none; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
/* 第2階層は「第1階層で複数を選んだ結果」なので、出現をフェードで結び付ける (瞬間出現にしない)。 */
.fit-multikindseg { animation: fit-seg-in var(--dur-short) var(--ease-out); }
@keyframes fit-seg-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .fit-multikindseg { animation: none; } }
.fit-topbar-meta { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
/* (2) 横テキストタブ: 溢れたら横スクロール。アクティブは下線 + アクセント色。 */
/* C1: タブバー wrap = 溢れ時のみ端フェード + スクロールシェブロンを重ねる (溢れ無しなら何も出さずレイアウト不変)。 */
.fit-tabbar-wrap { position: relative; flex: none; min-width: 0; }
.fit-tabbar { display: flex; align-items: stretch; gap: 0; padding: 0 6px; border-bottom: 1px solid var(--panel-border); overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.fit-tabbar::-webkit-scrollbar { display: none; }   /* C1: 常時表示の巨大スクロールバーを隠す (Chromium) */
/* 端フェード: 溢れた側のみ opacity で出す (絶対配置=レイアウトに影響しない)。 */
.fit-tab-fade { position: absolute; top: 0; bottom: 1px; width: 34px; pointer-events: none; z-index: 1; opacity: 0; transition: opacity var(--dur-short) var(--ease-out); }
.fit-tab-fade-l { left: 0; background: linear-gradient(to right, var(--panel), transparent); }
.fit-tab-fade-r { right: 0; background: linear-gradient(to left, var(--panel), transparent); }
.fit-tabbar-wrap.ovl-l .fit-tab-fade-l, .fit-tabbar-wrap.ovl-r .fit-tab-fade-r { opacity: 1; }
/* スクロールシェブロン: 溢れた側のみ display で出す (マウス操作用・タブナビは既存の ←→ roving)。 */
.fit-tab-scroll { position: absolute; top: 0; bottom: 1px; width: 24px; display: none; align-items: center; justify-content: center; z-index: 2; padding: 0; border: none; background: var(--panel); color: var(--muted); cursor: var(--cur-pointer, pointer); }
.fit-tab-scroll:hover { color: var(--text); background: var(--surface-hover); }
.fit-tab-scroll-l { left: 0; box-shadow: 5px 0 6px -4px rgba(9, 17, 19, 0.16); }
.fit-tab-scroll-r { right: 0; box-shadow: -5px 0 6px -4px rgba(9, 17, 19, 0.16); }
.fit-tabbar-wrap.ovl-l .fit-tab-scroll-l, .fit-tabbar-wrap.ovl-r .fit-tab-scroll-r { display: flex; }
.fit-tab-scroll svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: reduce) { .fit-tab-fade { transition: none; } }

/* ===== T1.8 OverflowBar: 上のパターンを 1 行バー全般で使えるようにした共通クラス =====
   フィット窓のタブバー (.fit-tabbar-wrap) と同じ見た目/挙動を、ページタブ・リンクバーにも
   適用する (計画 7.1 / 7.2: 折り返しをやめて 1 行を維持し、溢れはシェブロンで辿る)。 */
.ovl-wrap { position: relative; min-width: 0; }
.ovl-bar { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; flex-wrap: nowrap !important; }
.ovl-bar::-webkit-scrollbar { display: none; }
.ovl-fade { position: absolute; top: 0; bottom: 0; width: 28px; pointer-events: none; z-index: 1; opacity: 0; transition: opacity var(--dur-short) var(--ease-out); }
.ovl-fade-l { left: 0; background: linear-gradient(to right, var(--panel), transparent); }
.ovl-fade-r { right: 0; background: linear-gradient(to left, var(--panel), transparent); }
.ovl-wrap.ovl-l .ovl-fade-l, .ovl-wrap.ovl-r .ovl-fade-r { opacity: 1; }
.ovl-scroll { position: absolute; top: 0; bottom: 0; width: 20px; display: none; align-items: center; justify-content: center; z-index: 2; padding: 0; border: none; background: var(--panel); color: var(--muted); cursor: var(--cur-pointer, pointer); }
.ovl-scroll:hover { color: var(--text); background: var(--surface-hover); }
.ovl-scroll-l { left: 0; box-shadow: 5px 0 6px -4px rgba(9, 17, 19, 0.16); }
.ovl-scroll-r { right: 0; box-shadow: -5px 0 6px -4px rgba(9, 17, 19, 0.16); }
.ovl-wrap.ovl-l .ovl-scroll-l, .ovl-wrap.ovl-r .ovl-scroll-r { display: flex; }
@media (prefers-reduced-motion: reduce) { .ovl-fade { transition: none; } }
/* D-08: タブとカテゴリ (eyebrow) の階層を font-size / weight / color の 3 軸で分ける。
   タブ = fs-base(12px)/500、active は 600 + --surface-active の面。全高 ≤26px。
   **一辺だけのアクセント線は使わない** (規約。タブの下線も例外にしない)。
   選択は「面 + 太さ + 主色の文字」= .pp-seg-btn.active と同じ語彙で示す。 */
/* F2 (2026-08-05): タブのターゲットサイズを 24px 以上にする。
   旧実装は padding 4px + 12px×1.2 = 実効 22.4px で、同じ製品が `.wt-btn` に対して
   「WCAG 2.2 SC 2.5.8 のため 24px」と明記して直した基準を、同等頻度で押される
   要素が割っていた (自分で決めた基準の内と外に同種の要素が分かれていた)。
   min-height をトークンで固定し、padding の微調整で崩れないようにする。 */
.fit-tab { position: relative; flex: none; border: none; background: transparent; color: var(--muted); cursor: var(--cur-pointer, pointer); font: inherit; font-size: var(--fs-base); font-weight: 500; line-height: 1.2; white-space: nowrap; padding: 5px 10px; min-height: var(--control-h); border-radius: var(--radius-ctl) var(--radius-ctl) 0 0; }
.fit-tab:hover { color: var(--text); background: var(--surface-hover); }
.fit-tab.active { color: var(--text); font-weight: 600; background: var(--surface-active); }
.fit-tab:disabled, .fit-tab[aria-disabled="true"] { color: var(--text-disabled); pointer-events: none; }
.fit-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius-ctl); }
/* Phase 1: stage (Setup/Configure/Evaluate) を eyebrow で可視化。グループ = ラベル (上) + タブ行 (下)。
   グループ境界は左ヘアライン (旧 .fit-tab-div を置換)。eyebrow はタブの上に載るため横幅を増やさず、全高 ≤44px に収まる。 */
.fit-tabgrp { flex: none; display: flex; flex-direction: column; justify-content: flex-end; padding: 0 7px; }
.fit-tabgrp + .fit-tabgrp { border-left: 1px solid var(--panel-border); }
/* eyebrow (準備 / 調整 / 評価) はタブより一段弱く。非インタラクティブ。
   F7 (2026-08-05): 2 点修正。
     ・**色**: --text-disabled は「無効化された要素専用」(design.md) で、読ませたい
       文字に使ってはいけない。読み取りコストに見合わない淡さになっていたので --muted へ。
       段はサイズ (10px vs 12px) と太さが作るので、色まで落とす必要は無い。
     ・**コメントの嘘**: 旧コメントは「letter-spacing 0.08em」と述べていたが実装は
       --tracking-tight (0.01em)。全大文字を廃した以上、正のトラッキングは使わない
       (D-70) ので**実装が正**。文書が人を誤った実装へ送るのを止める。 */
.fit-tabgrp-lbl { font-size: var(--fs-xs); font-weight: 400; line-height: 1.2; color: var(--muted); padding: 2px 4px 0; letter-spacing: var(--tracking-tight); white-space: nowrap; pointer-events: none; user-select: none; }
.fit-tab-row { display: flex; align-items: stretch; gap: 1px; }
.fit-tab-badge { display: inline-block; width: 7px; height: 7px; margin-left: 5px; border-radius: 50%; vertical-align: 1px; }
.fit-tab-badge.warn { background: var(--warn); }
.fit-tab-badge.err { background: var(--bad); }
.fit-tab-badge.unsaved { background: var(--accent); }
.fit-tab-badge.notif { background: var(--accent); animation: fit-pulse var(--dur-med) var(--ease-out) infinite; }
/* m8: バッジ意味の 1 行凡例 (色のみに依存しない)。Results 節頭に表示。 */
/* 役割: メタ (--fs-xs / 400 / muted)。R6-H1: 旧実装は未定義のユーティリティクラス
   `fs-xs` に頼っており、実測 12px で段階スケールから外れていた。 */
.fit-badge-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 0 0 8px;
  font-size: var(--fs-xs); color: var(--muted); }
.fit-blg { display: inline-flex; align-items: center; gap: 4px; }
.fit-blg .fit-tab-badge { margin-left: 0; vertical-align: 0; animation: none; }
/* (4) 最下部: 実行系。中身のレイアウトは .fit-dock-foot が担当。 */
.fit-footbar { flex: none; }
.fit-target-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* T3.2: .fit-lock / .fit-target-line (対象ロック表示) は廃止した。 */
/* D-07: フィット名は「編集できる値」の視覚言語 = 1px 破線下線 + ✎ 常時表示 + hover で面。 */
.fit-name { flex: 1; min-width: 0; display: flex; align-items: center; gap: 5px; font-size: var(--fs-base); font-weight: 600;
  cursor: var(--cur-pointer, pointer); padding: 1px 4px; border-radius: var(--radius-ctl); }
.fit-name:hover { background: var(--surface-hover); }
.fit-name:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
.fit-name-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border-bottom: 1px dashed var(--border-strong); }
.fit-name:hover .fit-name-txt { border-bottom-color: var(--text); }   /* 一辺アクセント線は使わない */
.fit-name-pencil { flex: none; border: none; background: transparent; color: var(--muted); cursor: var(--cur-pointer, pointer); font-size: var(--fs-sm); padding: 0 3px; opacity: 0.55; }
.fit-name-pencil svg { display: block; width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.fit-name:hover .fit-name-pencil { opacity: 1; color: var(--accent); }
.fit-name-input { flex: 1; min-width: 0; font-size: var(--fs-base); }
/* F11 (2026-08-05): 状態の点は**要素**にする (文字リテラルの "●" ではなく)。
   旧実装は `● ラベル` と文字で書いていたので、字形の大きさも位置も書体任せで、
   未実行 (muted) では点と文字が同色 = 点が何の情報も運んでいなかった。
   未実行は「まだ何も無い」ので**中空のリング**にし、状態を色だけでなく形でも
   区別する (D-110「状態は形で示す」と同じ規律。窓の .mdi-dot も同じ語彙)。 */
.fit-status { flex: none; display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; }
.fit-status-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.fit-status-muted .fit-status-dot { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }
.fit-status-run { color: var(--accent); }

@keyframes fit-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }

/* .fit-scroll: フォントサイズ段階の基準クラス (アクティブ節本文の文脈で --fs-base に解決)。 */
.fit-scroll { overflow-y: auto; overflow-x: hidden; padding: 0 10px 12px; font-size: var(--fs-base); }
/* アクティブタブの1節 (ページ)。折りたたみは廃止し、小見出しは sticky で本文スクロール中も残す。 */
.fit-sec { padding: 2px 0; }
.fit-sec-page { border-top: none; }
.fit-sec-head { position: sticky; top: 0; z-index: 2; display: flex; width: 100%; align-items: baseline; gap: 6px; padding: 5px 0 6px; background: var(--panel); border: none; text-align: left; font: inherit; color: var(--text); }
.fit-sec-pagehd { cursor: default; }
.fit-sec-title { flex: none; font-size: var(--fs-base); font-weight: 700; text-transform: none; letter-spacing: var(--tracking-tight); color: var(--text); }
.fit-sec-body { padding: 2px 0 var(--gap-inline); }
/* Phase 1: 統合タブ内のサブ見出し (非 sticky・.fit-sec-title と同タイポ + 上余白で旧セクションを区切る)。
   §14: 節と節の間隔は --gap-section 1 本に統一し、境界のヘアラインで塊を分ける。
   旧実装は上余白だけだったため、データタブで「データセット」の一覧と「範囲」の入力が
   地続きに見え、どこまでが 1 つの設定なのか分からなかった。 */
.fit-subsec-head {
  /* F1: 見出しは右肩に道具 (.fit-sechd-tools) を載せるので 1 行の flex にする。
     道具のぶん (24px) 行が高くなるが、独立した「ワークシートから選ぶ」節
     (瓦 3 枚 + 見出し + ⓘ ≈ 90px) が丸ごと消えるので差し引きで縮む。 */
  display: flex;
  align-items: center;
  gap: var(--gap-inline);
  min-height: var(--control-h);
  margin: var(--gap-section) 0 var(--space-1);
  padding-top: var(--gap-inline);
  border-top: 1px solid var(--panel-border);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  color: var(--muted);
}
/* タブ本文の最上位見出しは「節見出し」の仕様 (D-70)。小群見出しのままだと
   直下のコントロールラベルと同色・ほぼ同太さで、見出しとして読めない。 */
.fit-subsec-head.is-sec { font-size: var(--fs-base); color: var(--text); }
/* 本文の先頭に来る小見出しは、上に区切る相手がいないので線と余白を持たない。 */
.fit-sec-body > .fit-subsec-head:first-child { margin-top: 0; padding-top: 0; border-top: none; }
/* §7: モデル種別セグメント (一般関数 / ピーク) と、その下の「モデル種別」行の間隔。
   セグメントは「何を選んでいるか」を決める塊なので、次のグループと --gap-group ぶん離す。 */
.fit-modelkindseg { margin-bottom: var(--gap-group); }
/* aria-labelledby を保ちつつタブ名の視覚的反復を消すためのユーティリティ (視覚非表示・AT には読める)。 */
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
@media (prefers-reduced-motion: reduce) { .fit-tab-badge.notif { animation: none; } }

/* key-value 行 (各セクション共通: 弱枠・余白で階層) */
/* 縦リズム統一 (#10): 全行 min-height 26px・gap 一定。ラベルは折返し禁止 (行高のばらつきを排除)。 */
.fit-kv { display: flex; flex-direction: column; gap: var(--gap-stack); }
.fit-kv-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; min-height: var(--control-h); }   /* D-01: 行の基準高さをトークンへ */
.fit-kv-row.top { align-items: flex-start; }
/* #2/C1: ラベル列は 130px 幅・省略 (main 採用)。入力/select は内容量に見合う自然幅。 */
/* §24: フォームのラベルは全画面共通で --fs-sm / weight 600 / --muted。 */
.fit-kv-k { flex: none; width: 130px; font-size: var(--fs-sm); font-weight: 600; line-height: 1.35; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* M8 (自ブランチ固有): 単位ラッパ (.pp-inwrap) も行幅にフィット。global .pp-inwrap は display:block なので
   flex 参加を維持しないと From/To の単位付き入力が潰れる。 */
/* §14: 値カラムの幅は 1 つ。行ごとに内容量で決めない (縦に並んだとき右端が揃う)。 */
.fit-kv-row > select, .fit-kv-row > input, .fit-kv-row > .pp-inwrap, .fit-kv-v { flex: 1 1 auto; width: auto; min-width: 0; }
.fit-kv-row > input[type="text"], .fit-kv-row > input[type="number"] { text-align: right; font-variant-numeric: tabular-nums; }
/* 値カラムに 1 つだけ置くボタン/ボタン列も同じ左端から始める (ラベル列へはみ出さない)。 */
.fit-kv-row > .btn-row { flex: 1 1 auto; min-width: 0; }
.fit-kv-v.mono, .mono { font-family: var(--font-mono); font-size: var(--fs-sm); }
/* m5: 式表示は入力欄でなく「面なし mono テキスト + コピー」のコードチップ (旧 .fit-kv-v.mono の panel-2 面/角丸は廃止し
   入力欄との誤認を断つ。他の .mono 利用箇所の見た目は変えない=式行専用クラスに分離)。 */
.fit-formula-row { align-items: flex-start; gap: 6px; }
/* T3.17: 式は切り詰めず折り返して全文を出す (長い組込み式・任意長 UDF)。
   title 属性の全文表示は保険として残す。 */
.fit-formula { flex: 1; min-width: 0; font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text); background: transparent; padding: 0; overflow: visible; white-space: pre-wrap; word-break: break-all; line-height: 1.5; }
.fit-formula-copy { flex: none; align-self: flex-start; }
/* T3.17: 記号 | 説明 | 初期値 | 制約 の 4 列表 (式の直下)。 */
/* §8: 記号 | 説明 の 2 列表 (式の直下)。
   これは「結果の表」ではなく設定パネルの参照表なので、.log-table の語彙
   (13px / 塗りつぶしヘッダ帯 / 全面罫線 / tabular-nums) は使わない。
   design.md のパネル階層に従い、見出し = 節見出しと同じ --fs-xs/700/muted、
   本文 = --fs-base、区切りは行下のヘアラインだけ (箱で囲まない)。 */
.fit-paramlegend {
  width: 100%;
  margin: var(--gap-inline) 0 var(--gap-group);
  border-collapse: collapse;
  font-size: var(--fs-base);
  table-layout: fixed;
}
.fit-paramlegend thead th {
  padding: 0 0 var(--space-1);
  border-bottom: 1px solid var(--panel-border);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  color: var(--muted);
  text-align: left;
  background: transparent;
}
.fit-paramlegend tbody td {
  height: var(--control-h);            /* 行の基準高さ = 1 行コントロールと同じリズム */
  padding: 0 var(--gap-inline) 0 0;
  border-bottom: 1px solid var(--panel-border);
  text-align: left;
  vertical-align: middle;
}
.fit-paramlegend tbody tr:last-child td { border-bottom: none; }
.fit-paramlegend thead th:first-child { width: 7em; }
.fit-paramlegend .fit-pl-sym { white-space: nowrap; }
.fit-paramlegend .fit-pl-sym code { font-family: var(--font-mono); color: var(--text); }
.fit-paramlegend .fit-pl-desc { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* m4: モデルのパラメータ凡例 (式の下・2 列)。空洞だった Model 節を意味で埋める。 */
/* D-18: モデルプレビュー (図 + 数学表記の式 + 記号凡例)。文章は含まない。 */
.fit-mprev { margin-top: var(--space-3); padding-top: var(--space-2); border-top: 1px solid var(--panel-border); }
.fit-mprev-canvas { display: block; max-width: 100%; background: var(--panel-2); border: 1px solid var(--panel-border); border-radius: var(--radius-ctl); }
.fit-mprev-eq { margin: var(--space-2) 0 0; font-size: var(--fs-base); color: var(--text); text-align: center; overflow-x: auto; white-space: nowrap; }
/* §8: 旧「プレビュー下の記号凡例」(.fit-model-legend / .fit-mleg*) は式直下の記号表と重複するため撤去。 */
/* M4: Compact パラメータ表直下の凡例 (✓ の意味を 1 行で補う)。 */
/* C3: ヒントは脚注スタイル (小さめ・減光・左罫線) */
.fit-sub { margin: 0; }
/* インライン SVG アイコン (C6): 絵文字/ダイングバットを置換した線画 */
.fit-ic svg, .fit-pbadge svg, .fit-name-pencil svg, .fit-sec-caret svg, .fit-save-caret svg, .fit-warn svg, .fit-btn-caret svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; vertical-align: -2px; }
/* m1: ボタン内の SVG キャレット (旧 ▾ グリフ置換)。ボタン文字の右に少し離して配置。 */
.fit-btn-caret { display: inline-flex; align-items: center; margin-left: 2px; color: var(--muted); }
.fit-sec-caret svg { width: 11px; height: 11px; }
/* C5: 成分名は 1 行省略 (型セレクトを押し出さない) */
.fit-comp-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A1: Initialization ラジオ — グローバル fieldset label の縦積み/太字継承を断つ */
.fit-initfrom { display: flex; flex-direction: column; gap: 1px; margin-bottom: var(--gap-inline); padding: var(--space-2) var(--pad-panel); border: 1px solid var(--panel-border); border-radius: var(--radius-md); }
.fit-initfrom-legend { font-size: var(--fs-sm); font-weight: 700; text-transform: none; letter-spacing: var(--tracking-tight); color: var(--muted); margin-bottom: 4px; }
.fit-initfrom .fit-radio { display: flex; flex-direction: row; align-items: center; gap: 6px; font-size: var(--fs-base); font-weight: 400; color: var(--text); padding: 3px 5px; border-radius: var(--radius-sm); }
.fit-initfrom .fit-radio:hover { background: var(--surface-hover); }
/* C2: Fit scope セグメント */
.fit-scopeseg { display: inline-flex; }
/* C7: フッタ Preview/Step をボタンらしく */
/* §15: フッターのボタンは .btn の共通トークン (高さ/角丸/フォント) をそのまま使う。
   旧実装はここで padding と font-size を上書きしていたため、同じ行の Run/Save と背丈が揃わなかった。
   ここが持つのは「フッター内では最小幅を揃える」ことだけ。 */
.fit-run-row .fit-foot-btn { min-width: 84px; }
/* F8 (2026-08-05): 主操作だけ左右に呼吸を持たせる。旧実装は "Run to convergence" が
   二次ボタン (Preview / Step) と同じ 10px で、視覚重量 (accent 塗り + 600) はあるのに
   余白では階層が付いていなかった。主操作は塗りと余白の**両方**で一段上に置く。
   高さ・角丸・文字サイズは共通トークンのまま (§15 の統一を崩さない)。 */
.fit-run-row .btn.primary { padding: 0 16px; }

/* Model: ピーク成分 (C2: General/Peaks セグメント .fit-modeseg は撤去。モードは topbar 一本化) */
.fit-comps { display: flex; flex-direction: column; gap: 2px; margin-bottom: 6px; }
.fit-comp { display: flex; align-items: center; gap: 5px; padding: 2px 0; }
.fit-comp-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fit-comp-type { flex: none; max-width: 104px; }
.fit-ic { flex: none; border: none; background: transparent; color: var(--muted); cursor: var(--cur-pointer, pointer); font-size: var(--fs-base); padding: 1px 4px; border-radius: var(--radius-sm); }
.fit-ic:hover { color: var(--text); background: var(--surface-hover); }
.fit-ic:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; color: var(--text); }
.fit-comp-ops { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0; }
.fit-comp-ops .armed { background: var(--accent-solid); color: var(--accent-text); }

/* フィットモードセグメント (要件13) — topbar 左に自動幅で配置 (右に Fit名/状態)。4ボタンは等幅。 */
.fit-fitmodeseg .pp-seg-btn { flex: 1; }

/* ユーザー定義式エディタ (要件25 / R9) */
.fit-udf { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.fit-udf-row { display: flex; align-items: center; gap: 6px; }
.fit-udf-row input { flex: 1; min-width: 0; }
.fit-udf-ok { font-size: var(--fs-sm); color: var(--accent); }
.fit-udf-err { font-size: var(--fs-sm); color: var(--bad); }
.fit-udf-save { display: flex; gap: 6px; align-items: center; }
.fit-udf-save input { flex: 1; min-width: 0; }
.fit-udf-list { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.fit-udf-list select { flex: 1; min-width: 0; }

/* Batch / Global データセット一覧 (要件26) */
.fit-ds-hd, .fit-gp-hd { display: flex; align-items: center; gap: var(--space-1); font-size: var(--fs-base); font-weight: 700; letter-spacing: var(--tracking-tight); color: var(--text); margin: 6px 0 3px; }
.fit-ds-count { flex: none; font-weight: 400; font-size: var(--fs-xs); }
/* D-12: 参照切れ (ブック消滅・列不足) の行。⚠ + 左辺の警告色で識別する。 */
.fit-ds-row.unresolved { background: color-mix(in srgb, var(--warn) 12%, transparent); }
.fit-ds-warn { flex: none; color: var(--warn); }
.fit-ds-ops { display: flex; align-items: center; gap: var(--space-1); flex: none; margin-left: auto; }
.fit-ds-up, .fit-ds-down { flex: none; }
.fit-ds-up:disabled, .fit-ds-down:disabled { opacity: 0.35; pointer-events: none; }
/* D-12: ワークスペース選択ポップオーバーのツリー。 */
.fit-dspick { display: flex; flex-direction: column; gap: var(--space-2); }
.fit-dspick-b { display: flex; flex-direction: column; gap: 2px; }
.fit-dspick-bn { font-size: var(--fs-sm); font-weight: 700; letter-spacing: var(--tracking-tight); color: var(--muted); }
.fit-dspick-p { display: flex; align-items: center; gap: 6px; font-size: var(--fs-sm); padding: 2px 4px; border-radius: var(--radius-ctl); cursor: var(--cur-pointer, pointer); }
.fit-dspick-p:hover { background: var(--surface-hover); }
/* D-13: 列配置プリセットのセグメントは 5 つ並ぶので折り返しを許す。 */
.fit-dslayoutseg { flex-wrap: wrap; }
.fit-dslayoutseg .pp-seg-btn { font-size: var(--fs-xs); padding: 0 5px; }
.fit-ds-list { display: flex; flex-direction: column; gap: 4px; }
/* §26: データセット行は **1 行**。4 つのセレクトが等分で幅を分け合い、溢れは省略記号 +
   title (全文) で読ませる。並べ替え/削除は ⋮ の行メニューに畳んであるので、
   アイコンは ◎ (割り当て) と ⋮ の 2 つだけ = セレクトに読める幅が残る。 */
.fit-ds-row { display: flex; gap: var(--space-1); align-items: center; flex-wrap: nowrap; min-width: 0; }
.fit-ds-row select { flex: 1 1 0; min-width: 0; }
.fit-ds-row .fit-ic { flex: none; }
/* 行ごとに読み込み元が違うときだけ出すシート名バッジ (全文は title)。 */
.fit-ds-src { flex: none; max-width: 84px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-xs); color: var(--muted); background: var(--panel); border: 1px solid var(--panel-border);
  border-radius: var(--radius-ctl); padding: 0 4px; }
/* σ 列を指定済みの行は ◎ をアクセント色にして、指定があることを色でも示す。 */
.fit-ds-row.has-sigma .fit-ds-assign { color: var(--accent); }
.fit-batch-tab td, .fit-batch-tab th { white-space: nowrap; }

/* Parameters 表 (#10 再設計): ヘッダ下線・行区切り・hover・枠付き入力・内容基準の列幅。
   compact は幅を張らず (max-width) 列が寄り添うテーブルにして中央の死んだ空白を無くす。 */
.fit-ptab { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; table-layout: fixed; }
/* §24: 表ヘッダは節見出しと同じ語彙 (--fs-xs / 700 / 0.06em / --muted)。
   行の高さは 1 行コントロールと同じ --control-h、区切りは --panel-far のヘアライン 1 本。
   旧実装は weight 600・26px・一点物の color-mix 罫線で、他の表と声が揃っていなかった。 */
.fit-ptab th { font-size: var(--fs-xs); font-weight: 700; letter-spacing: var(--tracking-tight); color: var(--muted); text-align: left; padding: 0 var(--gap-inline) var(--space-1) 0; position: sticky; top: 0; background: var(--panel); z-index: 3; border-bottom: 1px solid var(--panel-border); }
.fit-ptab td { padding: 0 var(--gap-inline) 0 0; vertical-align: middle; height: var(--control-h); border-bottom: 1px solid var(--panel-border); }
.fit-ptab tbody tr:last-child > td { border-bottom: none; }
.fit-ptab tbody tr:hover > td { background: var(--surface-hover); }
.fit-ptab td:last-child, .fit-ptab th:last-child { padding-right: 0; }
.fit-ptab th.r, .fit-ptab td.r { text-align: right; }
/* D-26: チェック列のヘッダは文字「固定 / Fixed」。ラベルが入る幅を確保する (旧 24px では隣の
   「パラメータ」見出しと文字が繋がって読めなかった)。 */
.fit-ptab th.c, .fit-ptab td.c { text-align: center; width: 46px; padding-right: var(--space-1); }
.fit-ptab th.c { white-space: nowrap; }
/* 列幅 (table-layout:fixed): 値/境界は内容基準の固定幅・名前が残りを取る */
/* D-25: 単一の 6 列 (固定/パラメータ/値/標準誤差/最小/最大)。狭い右ペイン (最小 340px) でも収まるよう
   数値列を固定幅、パラメータ列だけを可変にする。table-layout:fixed は継続。 */
.fit-ptab.full th:nth-child(2), .fit-ptab.full td:nth-child(2) { width: auto; min-width: 56px; }
.fit-ptab.full th:nth-child(3), .fit-ptab.full td:nth-child(3) { width: 76px; }
.fit-ptab.full th:nth-child(4), .fit-ptab.full td:nth-child(4) { width: 64px; }
.fit-ptab.full th:nth-child(5), .fit-ptab.full td:nth-child(5),
.fit-ptab.full th:nth-child(6), .fit-ptab.full td:nth-child(6) { width: 64px; }
.fit-perrcell { color: var(--muted); font-size: var(--fs-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* D-28: パラメータ節の見出し行 (タイトル + 右端の ⋮ 一括操作)。 */
.fit-psec-hd { display: flex; align-items: center; gap: var(--space-1); margin: 2px 0 4px; }
.fit-psec-sp { flex: 1; }
.fit-pkebab { flex: none; }
/* 数値フィールド: 常時 1px 枠で「編集可能な入力欄」だと分かる (M2 のアフォーダンスを main の枠で担保)。
   focus は枠色のみ (box-shadow リング禁止・#1 と同方針)。 */
/* 表内の数値入力もアプリ共通のコントロール寸法へ (高さ sm / 角丸 ctl / 文字は本文サイズ)。 */
/* D-111: 表内の入力も「操作できる輪郭 3:1」の契約から外さない (旧 --panel-border は 1.3:1 =
   枠があるのに操作の信号として機能しない、いちばん無駄なインクだった)。 */
.fit-ptab .num-field { width: 100%; min-width: 0; height: var(--control-h-sm); padding: 0 var(--pad-ctl-x-sm); text-align: right; color: var(--text); background: var(--panel-2); border: 1px solid var(--field-border); border-radius: var(--radius-ctl); font-variant-numeric: tabular-nums; font-size: var(--fs-base); }
.fit-ptab .num-field:hover { background: var(--surface-hover); }
.fit-ptab .num-field:focus { border-color: var(--accent); background: var(--panel); outline: none; box-shadow: none; }
.fit-ptab .num-field:disabled { background: transparent; border-color: transparent; color: var(--muted); }
/* D-24: 行クリックの詳細展開は廃止したのでポインタ/フォーカス表現も外す (ただの値ラベル)。 */
.fit-ptab .fit-pname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-base); }
.fit-pbadge { margin-left: 4px; font-size: var(--fs-xs); opacity: 0.85; }
.fit-ptab tr.fit-pfixed .fit-pname, .fit-ptab tr.fit-pfixed .num-field { color: var(--muted); }
/* 成分グループ見出し (Background / Peak n) */
.fit-pgroup > td { padding: 9px 0 4px; border-bottom: 1px solid var(--panel-border); font-size: var(--fs-sm); }
.fit-pgroup:first-child > td { padding-top: 2px; }
.fit-pgroup b { font-weight: 600; }
.fit-pdot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 6px; vertical-align: baseline; }
/* 値セル: 値 + 控えめな ±誤差 */
.fit-pvalcell { white-space: nowrap; }
.fit-perr { display: block; font-size: var(--fs-xs); color: var(--muted); text-align: right; margin-top: 1px; }
/* 境界チップ */
/* M4: 無制約チップは「操作できる」ことが伝わる破線ピル + セル hover で面 + 鉛筆 (クリック挙動は不変)。 */
.fit-plink { width: 100%; min-width: 0; padding: 2px 5px; font-size: var(--fs-sm); color: var(--text); background: var(--panel-2); border: 1px solid transparent; border-radius: var(--radius-sm); }
.fit-plink:focus { border-color: var(--accent); background: var(--panel); outline: none; }
.fit-plink.invalid { border-color: var(--bad); }
.fit-plinked .num-field[data-f="value"] { opacity: 0.7; }
.fit-warn { color: var(--warn); cursor: help; }

/* Data & weighting */
.fit-basisseg { display: inline-flex; }
.fit-range-btns { display: flex; flex-wrap: wrap; gap: 4px; }
.fit-pick-banner { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 4px 0; padding: 4px 8px; font-size: var(--fs-sm); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--panel-2)); border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent); border-radius: var(--radius-md); }
.fit-ex-row { display: flex; align-items: center; gap: 6px; margin: 2px 0; }
.fit-ex-in { width: 62px; min-width: 0; }
.fit-ex-dash { color: var(--muted); }
.fit-ex-row .fit-ic { margin-left: auto; }
.fit-ex-add { display: flex; gap: 4px; margin-top: 4px; }
.fit-ex-add input { width: 60px; min-width: 0; }

/* Fit settings */
.fit-adv { margin-top: 8px; }
.fit-adv summary { cursor: var(--cur-pointer, pointer); color: var(--muted); font-size: var(--fs-sm); padding: 4px 0; }
.fit-adv .fit-kv { margin-top: 6px; }

/* Result & diagnostics */
.fit-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(86px, 1fr)); gap: 8px; }
.fit-metric { display: flex; flex-direction: column; gap: 1px; padding: 6px 8px; background: var(--panel-2); border-radius: var(--radius-md); }
/* A2: text-transform:uppercase は χ(U+03C7) を Χ(U+03A7, 見た目 X) に化けさせるため使わない。
   ラベルは JS 側で適切な大小文字 (例: "Reduced χ²") を出す。 */
.fit-metric-k { font-size: var(--fs-xs); color: var(--muted); letter-spacing: var(--tracking-tight); }
.fit-metric-v { font-size: var(--fs-lg); font-weight: 700; font-variant-numeric: tabular-nums; }
.fit-res-warn { color: var(--warn); font-size: var(--fs-sm); margin: 8px 0 0; }
.fit-fulldiag { margin-top: 8px; }
.fit-fulldiag summary { cursor: var(--cur-pointer, pointer); color: var(--accent); font-size: var(--fs-sm); padding: 4px 0; }
.fit-stats-table { width: 100%; font-variant-numeric: tabular-nums; }
.fit-stats-table td { padding: 2px 8px 2px 0; }
.fit-stats-table td.r { text-align: right; }

/* 固定フッタ (M1/#10): 単一 flex 行 = 左 progress (flex:1) / 右 実行系。自然幅ボタン・全幅 teal 帯は廃止 (main 採用)。
   狭幅では flex-wrap で折り返す。 */
.fit-dock-foot { flex: none; padding: 8px 12px; border-top: 1px solid var(--panel-border); display: flex; flex-direction: row; align-items: center; gap: 8px; flex-wrap: wrap; }
.fit-progress { flex: 1 1 auto; min-width: 180px; }
.fit-run-row { flex: none; display: flex; align-items: center; gap: 6px; }
.fit-save-row { flex: none; }
.fit-progress { font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; }
.fit-progress b { color: var(--text); }
.fit-prog-sep { color: var(--muted); }   /* m2: 進捗行の中黒区切り (自ブランチ固有・footerHtml が使用) */
/* ボタンは自然幅 (#10: 全幅 teal 帯に引き伸ばさない)。狭幅では行が折り返す。 */
.fit-run-row .btn.primary, .fit-run-row .btn.danger { flex: none; }
/* キャレットの区切り線 (specificity で .btn.primary の border-color に勝つ) */
.fit-save-split { flex: none; display: flex; }
.fit-save-split .btn:first-child { flex: none; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.fit-save-caret { flex: none; min-width: 0; padding: 0 6px; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.fit-save-split .fit-save-caret { border-left: 1px solid var(--panel-border); }
.fit-save-split.emph .fit-save-caret { border-left-color: rgba(255, 255, 255, 0.32); }
.fit-save-split.emph .btn { background: var(--accent-solid); color: var(--accent-text); border-color: var(--accent-solid); }
.fit-prog-run { color: var(--accent); font-weight: 600; }

/* Popover / menu (Target詳細・Bounds・Actions・Run/Save メニュー) */
.fit-pop { position: fixed; z-index: 80; min-width: 180px; max-width: 280px; background: var(--panel); border: 1px solid var(--panel-border); border-radius: var(--radius-md); box-shadow: 0 8px 24px rgba(0,0,0,0.28); padding: 8px; font-size: var(--fs-base); }
.fit-pop-h { margin-bottom: 6px; }
.fit-pop-tab { width: 100%; }
.fit-pop-tab td { padding: 2px 8px 2px 0; }
.fit-pop-tab td:first-child { color: var(--muted); }
.fit-pop-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 4px 0; }
.fit-pop-row input { width: 110px; }
.fit-pop-btns { display: flex; gap: 6px; justify-content: flex-end; margin-top: 8px; }
/* D-21: リファレンス表示用の広いポップオーバー。内容が長くても内側でスクロールし、はみ出さない。 */
.fit-pop.pop-rich { min-width: 300px; max-width: 360px; max-height: 320px; overflow-y: auto; overscroll-behavior: contain; }
.pop-rich-list { display: flex; flex-direction: column; }
.pop-rich-cat { position: sticky; top: -8px; z-index: 1; background: var(--panel); padding: 6px 2px 3px; }
.pop-rich-row { display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left; border: none; background: transparent; color: var(--text); cursor: var(--cur-pointer, pointer); font: inherit; font-size: var(--fs-sm); padding: 3px 6px; border-radius: var(--radius-ctl); }
.pop-rich-row:hover { background: var(--surface-hover); }
.pop-rich-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pop-rich-sig { flex: none; font-family: var(--font-mono); color: var(--accent); }
.pop-rich-desc { flex: 1; min-width: 0; color: var(--muted); }
.fit-menu { display: flex; flex-direction: column; gap: 1px; }
.fit-menu-item { text-align: left; border: none; background: transparent; color: var(--text); cursor: var(--cur-pointer, pointer); font-size: var(--fs-base); padding: 5px 8px; border-radius: var(--radius-sm); }
.fit-menu-item:hover:not(:disabled) { background: var(--surface-hover); }
.fit-menu-item:disabled { color: var(--muted); cursor: default; }

/* ===== T3.8 PickMode: ワークスペースから拾うモード =====
   起点ウィンドウを半透明にして裏を見せ、対象をホバーでハイライト、上端にバナーを出す。 */
.mdi-window.pick-ghost { opacity: 0.28; pointer-events: none; }
.mdi-window.pick-target-hl { outline: 2px solid var(--accent); outline-offset: -1px; }
.mdi-window.pick-picked { outline: 2px solid var(--accent); outline-offset: -1px; box-shadow: inset 0 0 0 9999px color-mix(in srgb, var(--accent) 10%, transparent); }
.pick-banner {
  position: absolute; left: 50%; top: 8px; transform: translateX(-50%);
  z-index: var(--z-float); display: flex; align-items: center; gap: 8px;
  padding: 6px 12px; border-radius: var(--radius-md);
  background: var(--panel-2); border: 1px solid var(--accent);
  box-shadow: var(--shadow-modal); font-size: var(--fs-base); white-space: nowrap;
}
.pick-banner-text { color: var(--text); }
.pick-banner-count { color: var(--muted); font-family: var(--font-mono); font-size: var(--fs-sm); }
/* 2026-08-05: 拾うモード中、**候補は淡く / カーソルが乗っている窓だけ不透明**。
   窓が重なっていると輪郭だけでは隣に隠れて読み取れず、「どれが選ばれるのか」が
   クリックするまで確定しなかった。濃度で対象を示し、輪郭 (.pick-target-hl) は
   併用する (濃度を読み取れない環境でも手掛かりを残す)。
   これは**操作中だけの過渡状態**で、読ませたい対象は常に不透明側にある。 */
.mdi-window.pick-dim { opacity: 0.45; transition: opacity var(--dur-short) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .mdi-window.pick-dim { transition: none; } }

/* 列ピック中の worksheet: ヘッダをホバーで強調し、列全体を薄く示す。 */
.worksheet.ws-pick th[data-col] { cursor: var(--cur-pointer, pointer); }
.worksheet.ws-pick th[data-col]:hover { background: color-mix(in srgb, var(--accent) 18%, var(--panel-2)); outline: 1px solid var(--accent); }
/* 範囲ピック中の worksheet: 操作する場所は**行**なので、行番号側を手掛かりにする
   (列ピックの .ws-pick と対になる表現。どちらも「いまここを操作する」を面で言う)。 */
.worksheet.ws-pick-rows td, .worksheet.ws-pick-rows th[data-row] { cursor: var(--cur-pointer, pointer); }
.worksheet.ws-pick-rows th[data-row]:hover { background: color-mix(in srgb, var(--accent) 18%, var(--panel-2)); outline: 1px solid var(--accent); }

/* T9.2: 復元中の初フレームに前回のスナップショットを出す (初回 draw 完了で即除去)。
   「更新中」を併記して、古い内容を最新と誤認させない。 */
.graph-restoring { position: absolute; inset: 0; z-index: 2; pointer-events: none; background: var(--panel); }
.graph-restoring img { width: 100%; height: 100%; object-fit: contain; opacity: 0.55; }
.graph-restoring-note {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  padding: 3px 10px; border-radius: var(--radius-md);
  background: var(--panel-2); border: 1px solid var(--panel-border);
  color: var(--muted); font-size: var(--fs-sm);
}

/* ===== T7.3: 解析列の見た目 (通常列と即座に区別する) =====
   色だけに依存しないよう、錠前アイコン + ヘッダのティント + ツールチップの 3 点で示す。 */
.worksheet th.an-col { background: color-mix(in srgb, var(--accent) 10%, var(--panel-2)); }
.worksheet th.an-col.sel { background: color-mix(in srgb, var(--accent) 26%, var(--panel-2)); }
.worksheet td.an-cell { background: color-mix(in srgb, var(--accent) 4%, transparent); }
/* §2: 解析列の ƒ(x) ボタン。クリック領域を確保しつつ、ヘッダ行の高さは変えない。 */
.ws-an-fn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  margin-left: 3px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--accent);
  vertical-align: -3px;
}
.ws-an-fn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.ws-an-fn:hover { background: var(--sel-bg); color: var(--accent-hover); }
.ws-an-fn:focus-visible { box-shadow: var(--focus-ring); outline: none; }

/* T7.4: 入力列ハイライト (第2レイヤー)。extHighlight (.exthl) とは別色で重ねられる。 */
.worksheet th.srchl { background: color-mix(in srgb, var(--good) 16%, transparent); }
.worksheet td.srchl { background: color-mix(in srgb, var(--good, #188038) 10%, transparent); }

/* T3.10: 役割ハイライト (X / Y / σ)。PickMode の列割当中だけ出る。 */
.worksheet th.role-x { background: color-mix(in srgb, var(--accent) 20%, var(--panel-2)); }
.worksheet th.role-y { background: color-mix(in srgb, var(--good, #188038) 18%, var(--panel-2)); }
.worksheet th.role-err { background: color-mix(in srgb, var(--muted) 22%, var(--panel-2)); }
.ws-role-badge {
  display: inline-block; margin-right: 3px; padding: 0 3px; border-radius: var(--radius-ctl);
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 600;
  background: var(--panel); color: var(--text);
}

/* T3.11: データセット行の連番 + ドラッグ並べ替え。 */
.fit-ds-num {
  flex: none; min-width: 22px; font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--muted); cursor: var(--cur-grab, grab); user-select: none;
}
.fit-ds-row.dragging { opacity: 0.5; }
/* 並べ替えの落下位置。**一辺のアクセント線は使わない** (アプリ全体の規約) ので、
   行の外形を全周 1px のアクセント枠で示し、入る向きは「隙間を開ける」ことで伝える。 */
.fit-ds-row.drop-before, .fit-ds-row.drop-after {
  outline: 1px solid var(--accent); outline-offset: -1px; background: var(--sel-bg);
}
.fit-ds-row.drop-before { margin-top: 6px; }
.fit-ds-row.drop-after  { margin-bottom: 6px; }

/* T3.9: 列配置プリセットの並びミニ図。選択中プリセットの列並びを実物として見せる。 */
/* §26: 列の配置は「読み込むとき」に選ぶポップオーバー。名前 + 列並びミニ図の縦リスト。 */
.fit-layoutmenu { min-width: 230px; }
.fit-layout-item { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; }
.fit-layout-item.active .fit-layout-name { color: var(--accent); font-weight: 600; }
.fit-layout-name { display: inline-flex; align-items: center; gap: var(--space-1); }
.fit-dslayout-demo { display: flex; gap: 3px; padding: 2px 0 0; flex-wrap: wrap; }
.fit-dsdemo-col {
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted);
  background: var(--panel); border: 1px solid var(--panel-border);
  border-radius: var(--radius-ctl); padding: 1px 5px;
}

/* T1.2 DialogService: prompt / confirm の置き換え (ブラウザ標準ダイアログ全廃・背景は暗転しない)。 */
.fit-pop .pop-form { display: flex; flex-direction: column; gap: 8px; min-width: 220px; }
.pop-form-title { font-weight: 600; }
.pop-form-msg { color: var(--text); line-height: 1.5; white-space: pre-wrap; }
.pop-form-input { width: 100%; }
.pop-form-input.invalid { border-color: var(--bad); }
.pop-form-err { color: var(--bad); font-size: var(--fs-sm); }
.pop-form-btns { display: flex; gap: 6px; justify-content: flex-end; }

/* ===== Phase 6: 情報ツールチップ (要件23) ===== */
.fit-info { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; margin-left: 4px; color: var(--muted); cursor: help; border-radius: var(--radius-pill); vertical-align: -3px; }
.fit-info:hover, .fit-info:focus-visible { color: var(--accent); background: var(--surface-hover); outline: none; }
.fit-info:focus-visible { box-shadow: 0 0 0 2px var(--accent); }
.fit-info svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
/* position:fixed で .fit-scroll のクリップを回避。JS が座標を設定し .show でトグル。 */
/* D-31/P10: 親 (.fit-kv-k 等) の nowrap を継承して横にはみ出していたのを断つ。
   white-space:normal + word-break で折返し、max-height + overflow-y で縦もクランプする。 */
.fit-tip { position: fixed; z-index: var(--z-menu); max-width: 240px; max-height: 260px; overflow-y: auto; overscroll-behavior: contain; display: none; padding: 7px 9px; font-size: var(--fs-sm); line-height: var(--lh-normal); font-weight: 400; text-align: left; text-transform: none; letter-spacing: normal; white-space: normal; word-break: normal; overflow-wrap: anywhere; color: var(--text); background: var(--panel-2); border: 1px solid var(--panel-border); border-radius: var(--radius-md); box-shadow: var(--shadow-overlay); }
.fit-tip.show { display: block; }
.fit-tip .mono { font-family: var(--font-mono); }

/* ===== 構造化ツールチップ (D-62) =====
   専門機能は「名前だけ」では、いつ使えるのか・何に効くのかが分からない。
   機能名 / 説明 / 作用対象 / ショートカット / 無効の理由 を段で分けて出す。
   段の区別は size・weight・color の 3 軸で付ける (色だけに頼らない)。 */
.wt-tip { max-width: 280px; }
.wt-tip-name { font-size: var(--fs-base); font-weight: 600; color: var(--text); }
.wt-tip-desc { margin-top: 3px; color: var(--muted); max-width: var(--measure-help); }
.wt-tip-meta { margin-top: 6px; padding-top: 5px; border-top: 1px solid var(--panel-border); font-size: var(--fs-xs); color: var(--muted); }
.wt-tip-meta .wt-tip-k { display: inline-block; min-width: 6.5em; color: var(--muted); }
.wt-tip-meta kbd { font-family: var(--font-mono); font-size: var(--fs-xs); padding: 0 3px; border: 1px solid var(--panel-border); border-radius: var(--radius-ctl); background: var(--panel); color: var(--text); }
/* 無効の理由: 色 (warn) だけでなく、上のヘアラインと専用の段で「これは説明である」と示す。 */
.wt-tip-why { margin-top: 6px; padding-top: 5px; border-top: 1px solid var(--panel-border); color: var(--warn); }
.wt-tip-why::before { content: "! "; font-weight: 700; }
/* hover/focus のみで CSS フォールバック表示も許可 (JS 座標が未設定でも見えるよう相対配置は避け、JS 側で fixed 座標を必ず設定) */
.fit-info:hover .fit-tip, .fit-info:focus-visible .fit-tip { display: block; }

/* ===== Phase 6: 数値ステッパー (要件27) ===== */
.fit-stepper { display: inline-flex; align-items: stretch; gap: 0; width: 110px; }
.fit-stepper .fit-step-in { flex: 1; min-width: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.fit-step-btns { flex: none; display: flex; flex-direction: column; width: 16px; }
.fit-step-btns button { flex: 1; display: flex; align-items: center; justify-content: center; padding: 0; border: 1px solid var(--panel-border); background: var(--panel-2); color: var(--muted); cursor: var(--cur-pointer, pointer); }
.fit-step-btns button:first-child { border-bottom: none; border-top-right-radius: var(--radius-sm); }
.fit-step-btns button:last-child { border-bottom-right-radius: var(--radius-sm); }
.fit-step-btns button:hover { background: var(--surface-hover); color: var(--text); }
.fit-step-btns svg { width: 9px; height: 9px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* ===== Phase 6: 制約モードセグメント + 境界検証 (要件27) ===== */
.fit-cmseg { display: flex; flex-wrap: wrap; margin-bottom: 8px; }
.fit-cmseg .pp-seg-btn { font-size: var(--fs-xs); padding: 3px 7px; }
.fit-pop-err { color: var(--bad); font-size: var(--fs-sm); margin: 4px 0 0; }
.fit-pop .num-field.invalid, .fit-ptab .num-field.invalid { border-color: var(--bad); background: color-mix(in srgb, var(--bad) 8%, var(--panel-2)); }
.fit-pop-btns .btn:disabled { opacity: 0.5; cursor: default; }

/* ===== Phase 6: セクション見出し (Data source / Links) ===== */
.fit-picker-hd, .fit-constr-hd { display: flex; align-items: center; font-size: var(--fs-base); font-weight: 700; text-transform: none; letter-spacing: var(--tracking-tight); color: var(--text); margin: 2px 0 5px; }
/* D-10(b): 「対象」の独立行を廃し、ロックボタンだけを見出しの右端へ寄せる。 */
/* D-34: 検証は結果タブ内の折りたたみ節。warn/err があると open で開く。 */
.fit-validation { margin: var(--space-2) 0; }
.fit-validation > summary { cursor: var(--cur-pointer, pointer); font-size: var(--fs-base); font-weight: 700; letter-spacing: var(--tracking-tight); color: var(--text); padding: 3px 0; }
.fit-validation > summary::marker { color: var(--muted); }
.fit-validation > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ===== 3段フロー: 追加セクション ===== */
/* Components: Baseline / Peaks のグループ */
.fit-comp-group { margin-bottom: 8px; }
.fit-comp-grouphd { font-size: var(--fs-sm); font-weight: 700; text-transform: none; letter-spacing: var(--tracking-tight); color: var(--muted); margin: 4px 0 3px; }
.fit-comp .fit-pdot { flex: none; }
/* Preprocessing */
/* Initialization */
.fit-initfrom { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--gap-inline); }
.fit-radio { display: flex; align-items: center; gap: 6px; font-size: var(--fs-base); }
.fit-preset-add { display: flex; gap: var(--space-1); margin-bottom: var(--space-1); }
.fit-preset-add input { flex: 1; min-width: 0; }
/* Constraints */
.fit-constr { display: flex; flex-direction: column; gap: 3px; }
.fit-constr-row { display: flex; align-items: center; gap: 8px; }
.fit-constr-name { flex: none; width: 116px; font-size: var(--fs-sm); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fit-constr-link { flex: 1; min-width: 0; }
/* Validation checklist: 文字は --text(可読), 状態はアイコン形状+色で示す (色だけに頼らない) */
.fit-checklist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.fit-checklist li { display: flex; align-items: baseline; gap: 7px; font-size: var(--fs-base); color: var(--text); }
.fit-check-i { flex: none; font-weight: 700; width: 12px; text-align: center; }
/* D-34: 検証行から全診断 (相関行列) へのアンカー。相関の実体は診断側に一本化した。 */
.fit-check-link { flex: none; border: none; background: transparent; color: var(--accent); cursor: var(--cur-pointer, pointer); font: inherit; font-size: var(--fs-xs); text-decoration: underline; padding: 0 2px; }
.fit-check-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.fit-check-t { min-width: 0; }
.fit-check-ok .fit-check-i { color: var(--good); }
.fit-check-warn .fit-check-i { color: var(--warn); }
.fit-check-warn .fit-check-t { font-weight: 600; }
.fit-check-err .fit-check-i { color: var(--bad); }
.fit-check-err .fit-check-t { font-weight: 600; }
.fit-check-muted { color: var(--muted); }
/* Uncertainty / Output */
.fit-unc { margin-top: 10px; }
.fit-scope { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.fit-scope-cur { font-size: var(--fs-sm); }

/* ===== Fit結果タブ (再編集可能ビュー §12-16) ===== */
.fit-res { padding: 10px 14px; font-size: var(--fs-md); }
.fit-res-row1 { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.fit-res-name { font-weight: 700; }
/* m3: .fit-status の二重定義を廃止 → topbar 側 (fs-sm / weight600・上部で定義) を単一の基準にする。色クラスのみ維持。 */
.fit-status-ok { color: var(--good); }
.fit-status-warn { color: var(--warn); }
.fit-status-err { color: var(--bad); }
.fit-status-muted { color: var(--muted); }
.fit-res-srcwarn { color: var(--warn); font-size: var(--fs-base); margin: 5px 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fit-res-meta, .fit-res-stats1 { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: var(--fs-base); color: var(--muted); margin: 3px 0; }
.fit-res-stats1 b { color: var(--text); }
.fit-res-revsel select { margin-left: 4px; }
.fit-res-actions { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.btn.xs { height: var(--control-h-sm); padding: 0 8px; font-size: var(--fs-sm); }
/* P05(G-3): サブタブはタブバー直下 (警告バナーの下)。Summary が既定。 */
.fit-subtabs { display: flex; gap: 2px; border-bottom: 1px solid var(--panel-border); margin: 8px 0; flex-wrap: wrap; }
.fit-subtab { border: none; background: transparent; color: var(--muted); padding: 5px 12px; cursor: var(--cur-pointer, pointer); font-size: var(--fs-sm); font-weight: 500; border-radius: var(--radius-ctl) var(--radius-ctl) 0 0; }
.fit-subtab:hover { color: var(--text); background: var(--surface-hover); }
.fit-subtab.active { color: var(--text); background: var(--surface-active); font-weight: 600; }
.fit-res-body { overflow: auto; }
/* Summary の重ねグラフ (G-2) */
/* T4.2: 結果タブのサマリーグラフ。上端にツールストリップ、右下にホバー読み出し。 */
.fit-res-plotwrap { position: relative; margin-top: 10px; height: 330px; min-height: 220px; border: 1px solid var(--panel-border); border-radius: var(--radius-md); overflow: hidden; background: var(--panel); display: flex; flex-direction: column; }
/* §18: プレビュー上端 (.fit-toolstrip) と同じ器にする。中身の解除は .graph-tools.gt-strip が担う。 */
.fit-res-tools {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--gap-inline);
  height: 26px;
  padding: 0 var(--pad-ctl-x-sm);
  background: var(--panel);
  border-bottom: 1px solid var(--panel-border);
}
.fit-res-readout { position: absolute; right: 6px; bottom: 6px; }
.fit-res-plot { display: block; width: 100%; flex: 1; min-height: 0; }
/* F-3: 結果テーブルの列選択/コピー (RTable)。選択トークンはワークシート (P03) と統一。 */
.rtable { outline: none; }
.rtable thead th { cursor: var(--cur-pointer, pointer); user-select: none; position: relative; }
/* §19: 結果テーブルの列幅ドラッグ。ワークシート (.col-resize) と同じ操作語彙・同じ見た目にする。 */
.rtable thead th .rt-resize {
  position: absolute;
  top: 0;
  right: 0;
  width: 6px;
  height: 100%;
  cursor: col-resize;
}
.rtable thead th .rt-resize:hover { background: color-mix(in srgb, var(--accent) 45%, transparent); }
/* 幅を固定したあとはセル内容を切り詰める (隣の列へはみ出させない)。 */
.rtable[style*="table-layout"] th, .rtable[style*="table-layout"] td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-resize-guide {
  position: fixed;
  width: 2px;
  background: var(--accent);
  z-index: var(--z-toast);
  pointer-events: none;
}
body.rt-col-resizing, body.rt-col-resizing * { cursor: col-resize !important; }
.rtable thead th.sel { background: var(--surface-active); color: var(--text); font-weight: 600; }
.rtable tbody td.sel { background: var(--sel-bg); }
.rtable:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.fit-param-table td, .fit-stats-table td { padding: 3px 10px 3px 0; }
/* 計算データの仮想スクロール (§32) */
.fit-calc-scroll { max-height: 360px; overflow-y: auto; border: 1px solid var(--panel-border); border-radius: var(--radius-sm); }
.fit-calc-tab { width: 100%; }
.fit-calc-tab thead th { position: sticky; top: 0; background: var(--panel); z-index: 1; padding: 4px 10px 4px 0; }
.fit-calc-tab td { padding: 0 10px 0 0; }
.fit-warn { color: var(--warn); cursor: help; }
.fit-warnings { margin-top: 10px; font-size: var(--fs-base); }
.fit-warnings ul { margin: 4px 0 0; padding-left: 18px; }
.fit-setup h4 { margin: 6px 0 4px; font-size: var(--fs-base); }
.fit-setup-comps { margin: 0 0 8px; padding-left: 18px; font-size: var(--fs-base); }
.fit-setup-kv { display: flex; gap: 10px; font-size: var(--fs-base); margin: 2px 0; }
.fit-setup-kv .k { color: var(--muted); min-width: 150px; }
.fit-corr { margin-top: 8px; font-size: var(--fs-base); }
.fit-corr ul { margin: 4px 0 0; padding-left: 18px; }
.fit-corr-d { margin-top: 6px; font-size: var(--fs-base); }
.fit-corr-d summary { cursor: var(--cur-pointer, pointer); color: var(--muted); }
.fit-corr-tab { margin-top: 4px; font-variant-numeric: tabular-nums; }
.fit-corr-tab th, .fit-corr-tab td { padding: 2px 8px 2px 0; }
.fit-corr-hi { color: var(--bad); font-weight: 700; }
.fit-revhist tr.cur { background: var(--surface-active); }
.fit-rev-label { min-width: 120px; outline: none; }
.fit-rev-label:focus { background: var(--panel-2); }

/* 左サイドバー: エクスプローラ専有カラム (プロパティパネルは右ドックへ移設) */
#sidebar {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel);
  border-right: 1px solid var(--panel-border);
}

#explorer {
  flex: 1 1 auto;
  min-height: 48px;          /* パネルを高くしてもツリーは最低限残す */
  display: flex;
  flex-direction: column;
  overflow: hidden;          /* 要件9: ヘッダは上部固定、スクロールは #explorer-tree 側だけに任せる */
  user-select: none;
}
/* ツリーはキーボード操作のため tabindex=0 だが、UA 既定のフォーカス枠(全体を囲む箱)は出さない。
   フォーカス中の項目は選択ハイライト(.is-sel)で示す (§4.1)。overflow-y:auto でツリーだけがスクロールする。 */
#explorer-tree { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 0 10px 10px; outline: none; }
/* キーボードでツリーへ入ったことが分かるようにする (a11y)。
   旧実装は outline:none だけで、選択項目が無いとフォーカスの所在が完全に不可視だった。
   UA 既定の「全体を囲む太枠」は使わず、内側 1px のアクセント枠にとどめる。 */
#explorer-tree:focus-visible { box-shadow: inset 0 0 0 1px var(--accent); border-radius: var(--radius-ctl); }

/* Cloud namespace (remote metadata only; file bytes are fetched on Open).
   It is a storage location, so Explorer renders it above local Projects. */
.cloud-section { min-width: 0; margin: 0 0 12px; padding: 0 0 10px; border-bottom: 1px solid var(--panel-border); }
.cloud-heading, .cloud-provider-row, .cloud-row, .cloud-disconnected { min-width: 0; min-height: 25px; display: flex; flex-wrap: nowrap; align-items: center; gap: 5px; overflow: hidden; white-space: nowrap; border-radius: var(--radius-ctl); color: var(--text); }
.cloud-heading { width: 100%; padding: 5px 5px 4px; border: 0; background: transparent; text-align: left; font: inherit; font-size: var(--fs-sm); font-weight: 700; letter-spacing: var(--tracking-tight); color: var(--muted); cursor: var(--cur-pointer, pointer); }
.cloud-heading:hover { background: var(--surface-hover); color: var(--text); }
.cloud-section-caret { position: relative; width: 16px; height: 18px; flex: none; }
.cloud-section-caret::before { content: ""; position: absolute; left: 4px; top: 5px; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); transition: transform 160ms ease; }
.cloud-section.is-open .cloud-section-caret::before { transform: rotate(45deg); }
.cloud-heading-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--text); }
.cloud-provider-row, .cloud-row, .cloud-disconnected { padding-right: 3px; cursor: pointer; }
.cloud-provider-row:hover, .cloud-row:hover, .cloud-disconnected:hover, .cloud-row.is-sel { background: var(--surface-hover); }
.cloud-provider-row.is-open { color: var(--text); }
.cloud-provider-row .exp-name, .cloud-row .exp-name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cloud-tw { width: 16px; height: 18px; padding: 0; border: 0; background: transparent; color: currentColor; cursor: pointer; }
.cloud-tw.ph { display: inline-block; }
.cloud-icon { width: 16px; text-align: center; color: var(--accent); flex: none; }
.cloud-status, .cloud-meta { margin-left: auto; color: var(--muted); font-size: 10px; white-space: nowrap; }
.cloud-refresh, .cloud-reconnect, .cloud-open, .cloud-add { display: inline-flex; flex: none; align-items: center; justify-content: center; min-width: 24px; min-height: 22px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--muted); cursor: pointer; padding: 1px 4px; }
.cloud-refresh:hover, .cloud-reconnect:hover, .cloud-open:hover, .cloud-add:hover { color: var(--accent); }
.cloud-heading:focus-visible, .cloud-refresh:focus-visible, .cloud-reconnect:focus-visible, .cloud-open:focus-visible, .cloud-add:focus-visible, .cloud-tw:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.cloud-open { margin-left: 4px; }
.cloud-disconnected { padding: 3px 8px 3px 14px; color: var(--muted); }
.cloud-disconnected > span:not(.cloud-icon) { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cloud-disconnected button, .cloud-hint button { flex: none; margin-left: auto; border: 1px solid var(--panel-border); border-radius: var(--radius-ctl); background: var(--panel-2); color: var(--text); cursor: pointer; padding: 2px 6px; white-space: nowrap; }
.cloud-hint { padding: 4px 8px 4px 28px; color: var(--muted); font-size: 11px; }
.cloud-more { padding: 4px 8px 4px 28px; }
.cloud-more button { border: 1px solid var(--panel-border); border-radius: var(--radius-ctl); background: var(--panel-2); color: var(--text); cursor: pointer; padding: 2px 6px; }
.cloud-error { color: var(--bad); }
.cloud-settings-block { margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--panel-border); }
.cloud-settings-title { color: var(--text); }
/* Explorer ヘッダ: タイトル + 新規作成ボタン (プロジェクト / フォルダ)。ツリーの外側で上部に固定される。 */
.exp-header { display: flex; align-items: center; gap: 6px; flex: none; padding: 10px 10px 8px; }
.exp-hactions { display: flex; align-items: center; gap: 2px; flex: none; }
.exp-hbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0;
  border: 1px solid transparent; border-radius: var(--radius-sm);
  background: transparent; color: var(--muted); cursor: var(--cur-pointer, pointer);
}
.exp-hbtn:hover { background: var(--surface-hover); border-color: var(--panel-border); color: var(--text); }
.exp-hbtn svg { flex: none; }
#explorer h2 {
  flex: 1; min-width: 0;
  margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.exp-folder {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  padding: 3px 4px;
}
.exp-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 4px 3px 20px;
  border-radius: var(--radius-sm);
  cursor: var(--cur-pointer, pointer);
}
.exp-item:hover { background: var(--surface-hover); }
/* ホバー / 選択 / アクティブ文書は**別のチャンネル**で示す (D-86)。
   旧実装はホバーと選択がどちらも --surface-hover の同じ面で、差は名前の weight だけ。
   その weight はアクティブ文書でも使うので、3 状態が事実上 2 通りの見た目に潰れていた。
     ホバー     … 中立の面だけ (一過性)
     選択       … 中立の面 + **枠** + 文字を主色へ + weight 600 (accent は使わない)
     アクティブ … accent 面 (--sel-bg) + アイコンを accent + weight 600
   同時に成り立つ場合は両方見える (accent 面の上に枠が乗る)。 */
.exp-item.is-sel, .exp-folder.sub.is-sel, .exp-project.is-sel {
  background: var(--surface-hover); color: var(--text);
  box-shadow: inset 0 0 0 1px var(--border-strong);
}
/* 選択中はホバーしていても選択色を維持する */
.exp-item.is-sel:hover, .exp-folder.sub.is-sel:hover, .exp-project.is-sel:hover { background: var(--surface-hover); }
.exp-item.is-sel .exp-name, .exp-folder.sub.is-sel .exp-name, .exp-project.is-sel .exp-name { font-weight: 600; }
/* 前面の子ウィンドウ: Properties の対象でもあるので、ここだけは accent を使う (操作信号)。
   左 2px のルールは行の外形を変えないので、選択の面塗りと重ねても崩れない。 */
/* 前面の子ウィンドウ = Properties の対象。**一辺のアクセント線は使わない**ので、
   面 (--sel-bg) + アイコンのアクセント + 名前の weight の 3 点で示す。
   選択 (--surface-hover の中立面) とは面の色みで区別できる。 */
.exp-item.is-activedoc { background: var(--sel-bg); }
.exp-item.is-activedoc > svg { color: var(--accent); }
.exp-item.is-activedoc.is-sel { background: var(--surface-active); }
.exp-item.is-activedoc .exp-name { font-weight: 600; color: var(--text); }
/* ツリー項目にポインタを置くと、対応する子ウィンドウの輪郭が光る (D-67)。
   「その文書の窓がワークスペースのどこにあるか」を、クリックせずに特定できるようにする。 */
.mdi-window.exp-locate { outline: 1px solid var(--accent); outline-offset: 1px; }
.exp-item.is-sel .exp-eye { color: var(--muted); }
.exp-item svg, .exp-folder svg { flex: none; }
/* Explorer の全行で「トグル → アイコン → 名前」の左端を同じグリッドに置く。
   旧実装は SVG の固有幅 (13/16px) と、結果行の文字グリフ幅に任せていたため、
   同じ階層でも名前の左端が行種別ごとにずれて見えた。階層のインデントは
   inline の padding-left に任せ、行の内側だけを固定幅にする。 */
#explorer-tree .exp-project > .exp-tw,
#explorer-tree .exp-folder > .exp-tw,
#explorer-tree .exp-item > .exp-tw,
#explorer-tree .exp-page > .exp-tw,
#explorer-tree .exp-result > .exp-tw { flex: 0 0 16px; width: 16px; }
#explorer-tree .exp-project > svg,
#explorer-tree .exp-folder > svg,
#explorer-tree .exp-item > svg,
#explorer-tree .exp-page-kind,
#explorer-tree .exp-result > .rt-icon {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 16px; width: 16px; height: 16px;
}
#explorer-tree .exp-page-kind svg { width: 13px; height: 13px; }
#explorer-tree .exp-result > .rt-icon { line-height: 1; }

#workspace-wrap {
  position: relative;   /* P.1 overlay(#pp-overlay)/タブ(#pp-tab)の absolute 基準。無いと top:0 がビューポート基準になりツールバーを覆う */
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
#workspace {
  position: relative;
  flex: 1;
  overflow: auto;   /* 作業スペース外にウィンドウがはみ出したらスクロールバーで辿れるようにする */
  background: var(--bg-deep);
  /* MDI 窓の focus() が振る大きなインライン z-index をこのコンテキスト内へ閉じ込める。
     これで窓の z は body 直下のメニュー(--z-menu)/モーダル(--z-modal)と二度と競合しない。 */
  isolation: isolate;
}
/* 最大化中は #workspace のスクロール領域を無効化し、最大化窓 (100%×100%) の外側に
   他窓のはみ出しに由来する余白/スクロールバーが残らないようにする (R6)。 */
#workspace.has-maximized { overflow: hidden; }

/* ============ MDIウィンドウ (Modern MDI・改善案 §7/§9) ============ */
.mdi-window {
  position: absolute;
  display: flex;
  flex-direction: column;
  background: var(--panel-2);
  /* R9-C1: 窓の外形は**線が担う**。旧実装は --panel-border (紙に対し 1.3:1) で、
     同じ大きさの窓が重なると 2 枚の表が 1 枚の壊れた表に見えた
     (影は薄く、ダークではほとんど効かないので影だけには任せられない)。
     コントロールの輪郭と同じ 3:1 の線を使い、必ず「別の窓」と読めるようにする。 */
  border: 1px solid var(--control-border);
  border-radius: var(--radius-sm);                 /* 3px — 業務機器の輪郭。カード化しない */
  box-shadow: var(--shadow-win);
  overflow: hidden;
  min-width: 260px;
  min-height: 160px;
}
/* 非アクティブ窓は影をさらに弱く (内容は読めるまま・暗くしない)。
   前後関係は「影の強さ」ではなく、主に**タイトルバーの明度差と境界線**が担う
   (暗いテーマでは影がほとんど効かないため、影だけに依存させない)。 */
.mdi-window:not(.active):not(.maximized) {
  box-shadow: var(--shadow);
}
.mdi-window.maximized {
  left: 0 !important;
  top: 0 !important;
  width: 100% !important;
  height: 100% !important;
  border-radius: 0;
}

.mdi-titlebar {
  display: flex;
  align-items: center;
  gap: var(--gap-inline);
  padding: 0 var(--gap-inline) 0 var(--pad-panel);
  min-height: var(--titlebar-h);
  background: var(--titlebar);
  /* 非アクティブでも**読める**灰色を使う。標高の差はタイトルバーの面色が担うので、
     文字までコントラストを落とすと 4.5:1 を割ってしまう (audit-a11y)。 */
  color: var(--muted);
  font-size: var(--fs-base);
  cursor: var(--cur-arrow, default);
  user-select: none;
  flex: none;
  /* 下辺のヘアラインで、タイトルバーと内容 (紙面) の境目を必ず引く。
     面差だけに頼ると、ダークで両者が溶ける。 */
  border-bottom: 1px solid var(--panel-border);
}
/* アクティブ窓は 4 つの手掛かりを**同時に**動かす。色だけ・影だけに依存させない:
     1. タイトルバーの明度が持ち上がる (--titlebar → --titlebar-active)
     2. タイトル文字が --text-disabled → --text へ (weight も 500 → 600)
     3. 窓の外周境界が --control-border → --border-active (必ず**強くなる**方向)
     4. 影がひと段強くなる
   一辺だけにアクセント線を引く表現 (side-stripe) は使わない。アクセントは
   キーボードフォーカス・オブジェクト選択・スナップ先といった局所状態のために温存する。 */
.mdi-window.active {
  /* R10-C2: --border-strong はライトでは紙より薄く、ダークでは地に近いので、
     ここに使うとアクティブ窓の輪郭が画面上もっとも弱くなっていた (手掛かりが逆向き)。 */
  border-color: var(--border-active);
  box-shadow: var(--shadow-win-active);
}
.mdi-window.active .mdi-titlebar {
  background: var(--titlebar-active);
  color: var(--text);
  border-bottom-color: var(--border-active);
}
/* クロームの帯 (タイトルバー + 専用ツールバー) は**ひとかたまり**で動く。
   タイトルバーだけを動かすと、窓の上端が 2 段に割れて標高が読みにくい。
   アクティブ・非アクティブの**両方**を指定しないと片側だけ割れる。 */
.mdi-window.active .mdi-wintoolbar { background: var(--titlebar-active); }
.mdi-window:not(.active) .mdi-wintoolbar { background: var(--titlebar); }
/* D-110 (2026-08-05): 帽は**1 枚**に見せる。面色は既に共有していたが、その間に
   ヘアラインが 1 本残っていたため、窓の上端が 2 段に割れて読めていた。
   4 窓を並べると窓 1 つあたり横線 3 本 (帽の中 / 帽の下 / チップ帯の上) × 4 = 12 本が
   画面を横切り、目がデータより先に線の格子を読む。ツールバーを持つ窓では
   帽の**中**の線を消し、帽の**下端**の 1 本だけを境界として残す。
   `[hidden]` で判定するのは、ツールバーを持たない窓 (mdi.js は常に空の箱を作り
   wintoolbar.js:build が hidden を外す) では従来どおり線が要るため。
   セレクタは `.mdi-window` を足して `.mdi-window.active .mdi-titlebar` (0,3,0) に
   詳細度で勝たせる — 同点だと記述順に依存し、アクティブ窓だけ線が残る。 */
.mdi-window .mdi-titlebar:has(+ .mdi-wintoolbar:not([hidden])) { border-bottom: 0; }
/* 非アクティブ窓のツールバーは**面**だけを沈める。文字を沈めると読めなくなる。 */
.mdi-window.active .mdi-title { font-weight: 600; color: var(--text); }
.mdi-window.active .mdi-icon { color: var(--muted); }
/* タイトルは**内容ぶんの幅**しか取らない (flex:0 1 auto)。旧実装は flex:1 で、
   タイトルの箱が残り幅を全部吸い、その後ろに置いた種別ラベルと状態バッジが
   タイトルバーの中央付近まで押し出されていた。広い窓では名前から数百 px 離れ、
   「どの文書が未保存なのか」を読み取れない (名前の直後に置くという設計の意図が
   CSS で打ち消されていた)。余白は後ろの .spacer が受け持つ。 */
.mdi-title { flex: 0 1 auto; min-width: 0; color: var(--titlebar-ink); font-weight: 500; font-size: var(--fs-base); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 種類ラベル: タイトルの後ろに置く小さな種別表示 (Workbook / Graph / Matrix …)。
   OriginPro の利用者が「いま何を触っているか」を、アイコンの解読なしに読めるようにする。
   非インタラクティブ。狭い窓では省略される (.mdi-kind は幅が足りなければ消える)。 */
.mdi-kind {
  flex: none;
  font-size: var(--fs-xs);
  font-weight: 400;
  letter-spacing: var(--tracking-tight);   /* 全大文字をやめたので字間も詰める (広い字間は大文字組の作法) */
  /* 全大文字は使わない (アプリ全体の規約)。種別は語形そのままで、
     サイズ・色・字間で本体のタイトルと階層を分ける。 */
  color: var(--titlebar-ink);
  padding-left: 2px;
}
.mdi-window.active .mdi-kind { color: var(--text); }

/* 窓の状態バッジ (未保存 / 処理中 / 読み取り専用)。
   色だけで区別しない — 形状と文字を必ず伴わせる。 */
.mdi-state { flex: none; display: inline-flex; align-items: center; gap: 4px; }
.mdi-state .mdi-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--muted);
}
.mdi-state[data-state="dirty"] .mdi-dot { background: var(--warn); }
/* 未保存はプロジェクト単位で扱うため、Book/Graph の窓には表示しない。 */
.mdi-state[data-state="dirty"] { display: none; }
.mdi-state[data-state="busy"] .mdi-dot { background: var(--accent); animation: mdi-busy 1.1s var(--ease-in-out) infinite; }
.mdi-state[data-state="readonly"] .mdi-dot { background: transparent; box-shadow: inset 0 0 0 1px var(--muted); }
.mdi-state .mdi-state-lbl { font-size: var(--fs-xs); color: var(--titlebar-ink); letter-spacing: var(--tracking-tight); }
/* R10-C3: アクティブ窓のタイトルバーは面が一段上がるので、副テキスト色のままだと
   ダークで 4.12:1 になる。タイトル・種別と同じく本文色へ切り替える
   (title / kind は既にそうしており、状態ラベルだけが取り残されていた)。 */
.mdi-window.active .mdi-state .mdi-state-lbl { color: var(--text); }
/* D-110: 非アクティブ窓の状態は**点だけ**にする。4 窓を並べると「● 未保存」が
   4 つ同時に主張し、常時警告されている画面になっていた。点は残るので状態は
   失われず (色 = 種別)、語が要るときはアクティブにすれば読める。
   `visibility` ではなく `display` にするのは、語のぶんの幅も返して
   タイトルを長く見せるため。 */
.mdi-window:not(.active) .mdi-state .mdi-state-lbl { display: none; }
@keyframes mdi-busy { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.mdi-icon { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 18px; height: 18px; }
/* T3.19: タイトルバーアイコンは 16px で描く (旧: インライン 13px で 18px 枠に対して滲んでいた)。
   線画の見た目は他のアイコンと同じボイス (stroke=currentColor / 1.2〜1.5px)。 */
.mdi-icon svg { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.mdi-btn {
  border: none;
  background: transparent;
  color: inherit;
  width: 24px;
  height: 20px;
  border-radius: var(--radius-ctl);
  cursor: var(--cur-pointer, pointer);
  font-size: var(--fs-base);
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  position: relative;   /* リサイズ角ハンドルより前面に出して □ × を常にクリック可能に */
  z-index: 9;
}
.mdi-btn:hover { background: var(--surface-hover); color: var(--text); }
.mdi-btn:focus-visible { box-shadow: var(--focus-ring); outline: none; }
.mdi-close:hover { background: var(--bad); color: var(--on-scrim); }

/* 畳んだ窓 (= 最小化): タイトルバーの高さに固定し、中身をレイアウトから外す。
   窓自体は消えないので、位置・名前・種類が見えたまま残る = 見失わない。 */
/* 畳んだ窓 (= 最小化)。**幅も内容に合わせて縮める** (D-89)。
   高さだけ縮めると作業スペース全幅の帯になり、タイトルと操作ボタンが 1300px 離れて
   「窓」ではなくセクション見出しに見える。窓であることを保つため幅も詰める。 */
.mdi-window.shaded {
  height: var(--titlebar-h) !important;
  min-height: 0;
  width: auto !important;
  min-width: 240px;
  max-width: 420px;
  resize: none;
}
.mdi-window.shaded .mdi-content,
.mdi-window.shaded .mdi-wintoolbar,
.mdi-window.shaded .mdi-links,
.mdi-window.shaded .mdi-rz:not(.mdi-rz-e):not(.mdi-rz-w) { display: none; }

/* スナップ先プレビュー: 輪郭 + ごく薄い塗り。ドラッグ中だけ出て、掴めない面を作らない。
   ここはアクセントを使ってよい場所 (= ドラッグ先という操作信号)。 */
.mdi-snap-preview {
  position: absolute;
  /* z は mdi.js が **そのつど zCounter から**設定する (CSS に固定値を書かない)。
     窓の z は focus のたびに増えるので、固定値だとしばらく操作した後にプレビューが
     窓の下へ潜る — スナップを一番使う「窓が何枚もある」状況で見えなくなる。 */
  pointer-events: none;
  border: 2px solid var(--accent);
  background: var(--surface-active);
  border-radius: var(--radius-sm);
  transition: left var(--dur-short) var(--ease-out), top var(--dur-short) var(--ease-out),
              width var(--dur-short) var(--ease-out), height var(--dur-short) var(--ease-out);
}

/* ============ 子ウィンドウ専用ツールバー (第 2 層) ============
   タイトルバーの直下に置くことで、「このツールはこの窓に効く」を**空間的に**示す。
   アプリ共通ツールバー (第 1 層) とは面と位置で区別され、Properties (第 3 層) とは
   役割で区別される (ツールバー = 何を実行するか / Properties = どう設定するか)。 */
.mdi-wintoolbar {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: none;
  min-height: var(--wintoolbar-h);
  padding: 0 var(--gap-inline);
  background: var(--panel);
  border-bottom: 1px solid var(--panel-border);
  overflow: hidden;
  user-select: none;
}
.wt-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--icon-gap);
  /* WCAG 2.2 SC 2.5.8 (ターゲットサイズ 24×24)。第 2 層は日常操作の主要導線なので、
     20px だと手の震え・トラックパッド・タッチで押し損ねが増える。
     バー高 --wintoolbar-h(26px) は 24 + 上下 1px で収まる。 */
  height: var(--control-h);
  padding: 0 var(--pad-ctl-x-sm);
  border: 1px solid transparent;
  border-radius: var(--radius-ctl);
  background: transparent;             /* 通常時はツールバーの面と同化させる */
  /* 有効な操作は主テキスト色で描く。既定を --muted にすると、無効との差が
     1.4:1 しか無くなり「この窓の操作は全部使えない」ように見えてしまう。 */
  color: var(--text);
  font-size: var(--fs-sm);
  white-space: nowrap;
  flex: none;
  cursor: var(--cur-pointer, pointer);
}
.wt-btn:hover:not(.is-disabled) { background: var(--surface-hover); color: var(--text); }
.wt-btn:active:not(.is-disabled) { background: var(--surface-hover); transform: translateY(1px); }
.wt-btn:focus-visible { box-shadow: var(--focus-ring); outline: none; }
/* 無効は「位置を保ったまま」落とす (機能の場所が動かないことが最優先)。
   理由はツールチップが述べる — 色と濃度だけで説明を終わらせない。
   `disabled` 属性ではなく `.is-disabled` を使うのは、無効なボタンにも hover を届かせて
   「なぜ押せないか」を読ませるため (wintoolbar.js: setDisabled)。 */
/* 無効の見た目は **--text-disabled 単独**で作る。opacity を重ねると合成後の
   コントラストが 2.1:1 まで落ち、しかもツールチップ (子要素) まで半透明になる。
   --text-disabled は両テーマとも 4.7:1 以上で設計してある (design.md)。 */
.wt-btn.is-disabled { color: var(--text-disabled); cursor: var(--cur-arrow, default); }
.wt-btn.is-disabled svg { opacity: 0.7; }   /* アイコンだけは一段落とす (文字は落とさない) */
.wt-btn.is-disabled:hover { background: transparent; }
/* 選択中のツール = 面 + weight。アイコンだけ accent (文字を accent にすると読みにくい)。 */
.wt-btn.active { background: var(--surface-active); color: var(--text); font-weight: 600; }
.wt-btn.active svg { color: var(--accent); }
.wt-btn svg { flex: none; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.wt-btn.icon-only { padding: 0 4px; }
/* 読み取り専用の表示 (行列サイズなど)。ボタンではないので枠もホバーも持たず、
   ただし**本文と同じ濃さで読める**。無効ボタンで代用すると薄くなって読めなくなる。 */
.wt-readonly {
  display: inline-flex; align-items: center; flex: none;
  height: var(--control-h-sm); padding: 0 var(--pad-ctl-x-sm);
  /* R10-C3: 第 2 層は非アクティブ窓では --titlebar の面に乗るので、
     --muted (その面で 4.19:1) では本文基準を割る。面に合った副テキスト色を使う。 */
  color: var(--titlebar-ink); font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.wt-sep { width: 1px; height: 14px; background: var(--panel-border); margin: 0 4px; flex: none; }
.wt-spacer { flex: 1 1 auto; min-width: 0; }
/* 溢れた機能はオーバーフローメニューへ (常時露出を 5〜9 個に保つための逃がし先)。
   ⋯ は常に右端に居座り、幅が変わってもここだけは動かない。 */
.wt-more { flex: none; margin-left: auto; }
.mdi-wintoolbar .wt-spacer ~ .wt-more { margin-left: 0; }
.wt-hidden, .wt-sep-hidden { display: none !important; }
.wt-lbl { overflow: hidden; text-overflow: ellipsis; }

.mdi-content {
  flex: 1;
  min-height: 0;
  position: relative;
  overflow: hidden;
}
.kind-book .mdi-content { overflow: hidden; background: var(--panel-2); }

/* T1.4 ウィンドウブート: 中身の組み立てが終わるまで内容を隠す (レイアウトは行われるので
   実測に基づく余白計算・ResizeObserver はそのまま働く)。win.ready() で .booting が外れる。
   窓の枠とタイトルバーは最初から見えるので「何かが開いた」ことは分かる。 */
.mdi-window.booting .mdi-content,
.mdi-window.booting .mdi-links { visibility: hidden; }

/* ブックのコンテンツ = ページタブ + ワークシート */
.book-content { display: flex; flex-direction: column; position: relative; }
.ws-host { flex: 1; min-height: 0; overflow: auto; }
/* R9-C1: ワークシートの端の掃き寄せ。行列シート (.mx-wrap) と同じ規則。
   旧実装はワークシートだけこれが無く、窓の高さが行の高さの倍数でないときに
   **最後の行が字の途中で断ち切られた**まま終わっていた。その真下に別の窓の
   同じ幅の表が覗くと、行番号が飛び高さが半分の 1 枚の壊れた表に見える
   (第 9 ラウンド C1 の直接の原因)。掃き寄せがあれば「まだ先がある」と読める。 */
.book-content::after, .book-content::before {
  content: ""; position: absolute; pointer-events: none; opacity: 0; z-index: 2;
  transition: opacity var(--dur-short) var(--ease-out);
}
.book-content::after  { top: 0; right: 0; width: 20px; bottom: 0;
  background: linear-gradient(to right, transparent, var(--scrim-edge)); }
.book-content::before { left: 0; bottom: 0; height: 20px; width: 100%;
  background: linear-gradient(to bottom, transparent, var(--scrim-edge)); }
.book-content.can-x::after  { opacity: 1; }
.book-content.can-y::before { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .book-content::after, .book-content::before { transition: none; } }

/* T4.4: ページタブは折り返さず 1 行を維持 (溢れは OverflowBar のシェブロンで辿る)。
   行が増えて作業領域を食う問題を解消する。高さは常に 1 行ぶんで一定。 */
.page-tabs-wrap { position: relative; flex: none; background: var(--panel); border-bottom: 1px solid var(--panel-border); }
.page-tabs {
  display: flex;
  align-items: flex-end;
  flex-wrap: nowrap;
  gap: 2px;
  padding: 4px 6px 0;
  flex: none;
  user-select: none;
}
.page-tabs > * { flex: none; }
.page-tab {
  padding: 3px 14px;
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--muted);
  /* D-110: ページタブは**窓の中**にあるので、筐体 (--bg) を借りてはいけない。
     旧実装は --bg を使っており、筐体が --panel と近かったあいだは破綻しなかったが、
     筐体を沈めた瞬間に「窓の中にアプリの外枠と同じ暗い面がある」ことになる。
     面の役割で選び直す: 非選択タブは沈んだ面 (--surface-sunken)、
     選択タブは紙 (下の .page-tab.active) = ページの中身と地続き。 */
  background: var(--surface-sunken);
  border: 1px solid var(--panel-border);
  border-bottom: none;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  cursor: var(--cur-pointer, pointer);
}
.page-tab:hover { background: var(--surface-hover); }
/* シートの種別 (ワークシート / 行列シート) は**シートを選ぶ場所**が持つ。
   窓の名札 (.mdi-kind) は入れ物 = ワークブック で固定なので、種別はここで読む。
   アイコンだけに頼らず title 属性で「行列シート: Matrix2」と全文を出す。 */
.page-tab { display: inline-flex; align-items: center; gap: 5px; }
.page-tab .pt-kind { flex: none; display: inline-flex; color: var(--muted); }
.page-tab .pt-kind svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.3; }
.page-tab.active .pt-kind { color: var(--accent); }
.page-tab.active {
  background: var(--panel-2);
  font-weight: 600;
  color: var(--accent);
  margin-bottom: -1px;
  padding-bottom: 4px;
}
.page-tab.page-add { appearance: none; padding: 3px 10px; font: inherit; font-weight: 600; }
.page-tab.page-add .pt-add-label { font-size: var(--fs-sm); white-space: nowrap; }
.page-rename {
  width: 80px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  font: inherit;
  padding: 0 4px;
  outline: none;
}
/* T2.2: 空 / 同一スコープの重複は確定を拒否し、入力欄を赤枠にする (入力は開いたまま)。 */
.page-rename.invalid { border-color: var(--bad); background: color-mix(in srgb, var(--bad) 8%, var(--panel-2)); }
/* Explorer 内での改名はツリー幅いっぱいを使う (窓名は長いことが多い)。 */
.exp-name .page-rename { width: 100%; min-width: 60px; }

/* ウィンドウ下部のリンクバー (ブック ⇔ グラフ) */
.mdi-links-wrap { position: relative; flex: none; }
/* T4.4: リンクバーも折り返さず 1 行。溢れは OverflowBar が扱う。 */
.mdi-links {
  flex: none;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--gap-inline);
  padding: var(--space-1) var(--pad-ctl-x);
  min-height: calc(var(--control-h-sm) + var(--space-2));   /* チップ有無で高さが動かない */
  background: var(--panel);
  border-top: 1px solid var(--panel-border);
  user-select: none;
}
/* D-110: 窓の足 (リンクバー) は帽と**同じクロームの面**に乗せる。旧実装は --panel
   固定で、ライトでは帽 (--titlebar L*87.9) と足 (--panel L*94.7) が別の面に見え、
   1 つの窓が 3 種類の面 (帽 / 紙 / 足) で構成されていた。窓は「クロームに挟まれた紙」
   として読ませたいので、帽と足はアクティブ状態も含めて同じ面を共有する。 */
.mdi-window.active .mdi-links { background: var(--titlebar-active); }
.mdi-window:not(.active) .mdi-links { background: var(--titlebar); }
/* D-53: チップは「1 行・高さ固定・縮まない」。旧実装は nowrap も flex:none も無かったため、
   窓を狭めると flex が各チップを縮め、チップ内でラベルが折り返して 2 行になり、
   チップごとに高さが変わってバーが崩れていた。溢れは OverflowBar の横スクロールで受ける。 */
.link-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline);
  padding: 0 var(--pad-ctl-x);
  height: var(--control-h-sm);
  flex: none;
  white-space: nowrap;
  max-width: 320px;
  overflow: hidden;
  font-size: var(--fs-sm);
  font-weight: 600;
  background: var(--panel-2);
  /* D-111: チップは操作できる (クリックでジャンプ / 表示切替)。旧 --panel-border (1.3:1) は
     操作の信号にならない装飾枠だった。チップはクロームの帽 (--titlebar) に乗るので、
     その面でも 3:1 を満たす --control-border を使う (--field-border は帽の上で 2.6:1 と足りない)。 */
  border: 1px solid var(--control-border);
  border-radius: var(--radius-ctl);
  cursor: var(--cur-pointer, pointer);
}
/* チップ内のラベルだけが省略記号を担う (アイコン/👁 は常に見える)。 */
.link-chip .chip-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.link-chip:hover { background: var(--surface-hover); border-color: var(--accent); }
.link-chip.off { opacity: 0.5; }
.link-chip svg { flex: none; }
.chip-eye {
  display: inline-flex;
  border: none;
  background: transparent;
  color: var(--muted);
  padding: 1px;
  border-radius: var(--radius-sm);
}
/* D-110: ホバーの面は無彩色の面差 (--surface-hover) を使う。旧実装は筐体色 (--bg) を
   借りていたので、筐体を沈めた瞬間にチップ内へ暗い塊が出ることになる。 */
.chip-eye:hover { color: var(--accent); background: var(--surface-hover); }

/* グラフ側: データセット表示トグルチップ */
.ds-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline);
  padding: 0 var(--pad-ctl-x);
  height: var(--control-h-sm);   /* D-53: 中身によらず高さ一定 */
  flex: none;
  white-space: nowrap;
  max-width: 320px;
  overflow: hidden;
  font-size: var(--fs-sm);
  font-weight: 600;
  background: var(--panel-2);
  border: 1px solid var(--control-border);   /* D-111: link-chip と同じ理由 (操作の輪郭 3:1) */
  border-radius: var(--radius-ctl);
  cursor: var(--cur-pointer, pointer);
}
/* 展開中 (出所の長い説明を出す) だけは広げてよい — 展開は明示操作なので幅を取ることが意図。 */
.ds-chip.expanded { max-width: none; }
.ds-chip { position: relative; }
.ds-chip:hover { border-color: var(--accent); }
.ds-chip.off { opacity: 0.6; }
.ds-chip.off .ds-label { text-decoration: line-through; }
.ds-chip.dragging { opacity: 0.45; }
/* 並べ替えの挿入位置 (R6-H9)。
   **一辺のアクセント線は使わない** (絶対規約 1)。3px の縦棒は「片側だけの線」なので、
   落下位置は **全周の枠 + どちら側に入るかの面** で示す
   (design.md「落下位置のような『線でしか表せない』ものも、全周の枠と隙間で表す」)。 */
.ds-chip.drop-before,
.ds-chip.drop-after {
  box-shadow: inset 0 0 0 2px var(--accent);
  background: var(--sel-bg);
}
/* どちら側に入るかは、外側の余白 (chip がその方向へ寄る) で示す。 */
.ds-chip.drop-before { margin-left: 8px; }
.ds-chip.drop-after { margin-right: 8px; }
.ds-label { display: inline-flex; align-items: center; gap: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ds-label svg { flex: none; }

/* データセット表示トグル: 省スペースの色ドット (ON=塗り / OFF=輪郭のみ) */
.ds-dot2 {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--c, var(--accent));
  border: 2px solid var(--c, var(--accent));
  flex: none;
  transition: transform 0.12s, box-shadow 0.12s, background 0.15s;
}
.ds-dot2.off { background: transparent; }
.ds-dot2:hover {
  transform: scale(1.3);
  box-shadow: 0 0 0 2px var(--sel-bg);   /* U.4: 強グローを弱化(テーマ追従) */
}

/* チップ詳細の展開トグル */
.links-expand {
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-base);
  padding: 1px 5px;
  border-radius: var(--radius-sm);
  flex: none;
}
.links-expand:hover { background: var(--surface-hover); color: var(--accent); }

/* 複数パネル並列モード */
/* 窓の**中**の余白。ワークスペース (--bg-deep) と同色にすると窓に穴が開いて見える。
   紙 (--panel-2) の 1 段下 = パネル面に置き、窓の中であることを保つ。 */
.panels-content { display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--panel); }
.panel-host {
  display: flex;
  flex-direction: column;
  align-items: center;
  box-shadow: var(--shadow);
}
.panel-canvas { box-shadow: none; display: block; }

/* プロジェクト (ワークスペース分離) */
.mdi-window.proj-hidden { display: none !important; }
.exp-project {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 4px;
  margin-top: 4px;
  font-weight: 700;
  border-radius: var(--radius-sm);
  color: var(--muted);
  cursor: var(--cur-pointer, pointer);
  border-bottom: 1px solid var(--panel-border);
}
.exp-project:hover { background: var(--surface-hover); }
/* R9-M18: アクティブなプロジェクトも、文書と**同じ手掛かり**で示す
   (面 + 太さ)。旧実装はここだけ名前をアクセント色に染めており、
   1 つのツリーに「アクティブ」の表現が 2 つ存在した。加えて accent は
   操作信号の予約色なので、名前の着色は装飾的な使用にあたる。 */
.exp-project.active { color: var(--text); background: var(--sel-bg); }
.exp-project.active > svg { color: var(--accent); }   /* アイコンだけがアクセントを持つ (文書と同じ) */

/* Explorer のフォルダ (サブディレクトリ) */
.exp-folder.sub {
  border-radius: var(--radius-sm);
  cursor: var(--cur-pointer, pointer);
}
.exp-folder.sub:hover { background: var(--surface-hover); }
/* クリックで選択中のフォルダ (アイテムの active と同様の淡色選択) */
.exp-folder.sub.is-sel .exp-eye { color: var(--muted); }
.exp-folder.sub.is-sel .exp-tw { color: var(--muted); }
.exp-folder.drop-folder, .exp-folder.exp-root.drop-folder {
  background: var(--accent-solid);
  color: var(--accent-text);
}
.exp-dragging, .exp-dragging * { cursor: var(--cur-grab, grabbing) !important; }
.exp-item .exp-name, .exp-folder .exp-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Explorer の目玉 (ブック/グラフ表示切替、チップと同期) */
.exp-eye {
  display: inline-flex;
  margin-left: auto;
  border: none;
  background: transparent;
  color: var(--muted);
  padding: 1px 3px;
  border-radius: var(--radius-sm);
}
.exp-eye:hover { color: var(--accent); }
/* D-110 (2026-08-05): 目玉は**例外のときだけ**出す。
   ツリーは実測で 20 行を超え、全行の右端に同じ印が縦一列に並ぶ。この列自体が
   視覚ノイズになり、名前を読む速度を落としていた (周縁を静かにする)。出す条件は 3 つ:
     ・その行にポインタが乗っている  = これから操作する行
     ・その行の中にキーボードフォーカスがある = ポインタを持たない利用者
     ・非表示になっている (.off)      = 例外状態なので常に見えていなければならない
   `visibility: hidden` ではなく `opacity: 0` を使うのは、**要素をフォーカス可能な
   まま**残すため (visibility を切ると Tab で到達できず、キーボードから隠せなくなる)。
   `opacity: 0` は audit-a11y が「描かれていない」として除外する一方、
   出ている状態は --muted (パネル上 5.9:1) で測られる。
   ポインタが無い環境のために、同じ操作を右クリックメニューにも出してある
   (explorer.js: expToggleHidden)。 */
.exp-eye { opacity: 0; transition: opacity var(--dur-short) var(--ease-out); }
.exp-item:hover .exp-eye,
.exp-folder:hover .exp-eye,
.exp-item:focus-within .exp-eye,
.exp-folder:focus-within .exp-eye,
#explorer-tree:focus-visible .exp-item.is-sel .exp-eye,
.exp-eye:focus-visible,
.exp-eye.off { opacity: 1; }
/* 非表示は**形** (斜線入りの目 = EYE_OFF_SVG) が担うので、濃度は落とさない。
   旧実装の `opacity: .4` は、状態の違いを濃度だけに委ねたうえ実効 2.5:1 まで沈めていた。 */
.exp-item.active .exp-eye { color: var(--muted); }

/* 展開された階層の左側に表示する縦のガイド線 */
.exp-children {
  position: relative;
}
/* §4.1: ツリー階層の接続線(縦線/L字/括弧)は表示しない。階層はインデントのみで表現する */

/* プロジェクト/フォルダ/ブックの開閉トグル (▾/▸) */
.exp-tw {
  flex: none;
  width: 16px;
  text-align: center;
  font-size: var(--fs-md);
  line-height: 1;
  color: var(--muted);
  cursor: var(--cur-pointer, pointer);
  user-select: none;
}
.exp-tw:hover { color: var(--accent); }
.exp-tw.ph { visibility: hidden; cursor: default; }

/* 選択中の Book を含むフォルダ名は太字 */
.exp-folder.sub { font-weight: 400; }   /* 既定は通常ウェイト。選択/アクティブ時の太字(700)を際立たせる */
.exp-folder.sub.contains-active { font-weight: 700; }

/* Book 内のページ行と解析結果行 */
.exp-page {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 4px;
  color: var(--muted);
  border-radius: var(--radius-sm);
  cursor: var(--cur-pointer, pointer);
}
.exp-page:hover { background: var(--surface-hover); }
.exp-page.current { color: var(--accent); font-weight: 600; }   /* 現在ページは控えめに(文字のみ・常時の塗りつぶしハイライトにしない) */
.exp-result {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 1px 4px;
  color: var(--result-ink);
  border-radius: var(--radius-sm);
  cursor: var(--cur-pointer, pointer);
}
.exp-result:hover { background: var(--result-hover); }
.exp-result.sel { color: var(--accent); font-weight: 600; }
.exp-result .rt-icon { font-size: var(--fs-sm); }   /* アイコン用グリフのみ 1 段小さく (文字は行と同寸) */
.exp-page .exp-name, .exp-result .exp-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.exp-page-kind { display: inline-flex; flex: none; color: var(--muted); }
.exp-page-kind svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.3; }
.exp-page.current .exp-page-kind { color: var(--accent); }

/* 列ヘッダ上部の移動グリップ: 常時確保された専用スペース
   (.ws-table th の padding ショートハンドより詳細度を上げる) */
.ws-table .ws-colhead th {
  position: sticky;   /* 縦スクロールで固定。sticky 自体が col-grip(absolute) の配置基準にもなる */
  top: 0;
  z-index: 3;
  padding-top: 13px; /* グリップ分の高さを確保 */
  height: 34px;
  cursor: var(--cur-pointer, pointer); /* 選択スペースは人差し指 */
}
.ws-table .ws-colhead th.ws-corner { padding-top: 2px; left: 0; z-index: 6; }   /* 左上交差 = 最前面 (§3) */
.ws-an-mark { margin-left: 3px; font-size: var(--fs-xs); color: var(--accent); font-style: italic; }
.ws-an-mark.ws-an-err { color: var(--bad); font-style: normal; }
.ws-an-mark.ws-an-fn { font-style: normal; }
.col-grip {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 11px;
  /* ヘッダ面そのもの。最背面の面 (--bg) を紙の手前に敷くと面階層が逆転し、
     列ごとに独立した帯が並んで破れた罫線のように見えていた。 */
  background: transparent;
  border-bottom: 1px solid transparent;
  cursor: var(--cur-hand, grab); /* 移動スペースはパンの手 */
}
/* グリップ中央のつまみドット */
/* つまみは**ホバー時だけ**。列数ぶん反復する常時のピルは、ラベルも説明も無いまま
   データ表の最上部 11px を占め、データより UI が目立つ状態を作っていた。 */
.col-grip::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 50%;
  width: 22px;
  height: 3px;
  transform: translateX(-50%);
  border-radius: var(--radius-sm);
  background: var(--panel-border);
  opacity: 0;
  transition: opacity var(--dur-short) var(--ease-out);
}
.col-grip:hover { background: var(--surface-hover); border-bottom-color: var(--panel-border); }
.col-grip:hover::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .col-grip::after { transition: none; } }
.col-grip:hover::after { background: var(--accent); }
/* 選択列のグリップは th.sel の背景に同化させる (過剰な塗りを避ける・A-3) */
.ws-colhead th.sel .col-grip { background: transparent; }
.ws-colhead th.sel .col-grip::after { background: var(--panel-border); }

/* グラフウィンドウへのドロップ先ハイライト */
.mdi-window.drop-graph {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
/* §16.4: ドロップ先のプロット領域を淡くハイライトし「ここにドロップ」を中央表示 */
.mdi-window.drop-graph .mdi-content::after {
  content: "ここにドロップしてプロット";
  position: absolute; inset: 0; z-index: 8;
  display: flex; align-items: center; justify-content: center;
  background: var(--sel-bg);
  color: var(--accent); font-weight: 600; font-size: var(--fs-lg);
  pointer-events: none;
}
/* §16.5: カーソル追従のドラッグプレビュー */
.column-drag-preview {
  position: fixed; z-index: 10000; pointer-events: none;
  padding: 3px 10px; border-radius: var(--radius-md);
  background: var(--accent-solid); color: var(--accent-text);
  font-size: var(--fs-base); font-weight: 600;
  box-shadow: var(--shadow-overlay);
}

/* 8方向リサイズの透明ヒット領域 (角を辺より優先・見た目には出さない)。§13 */
.mdi-rz { position: absolute; z-index: 6; }
.mdi-window.maximized .mdi-rz { display: none; }   /* 最大化中はリサイズ無効 */
.mdi-rz-n { top: 0; left: 0; right: 0; height: 6px; cursor: ns-resize; }
.mdi-rz-s { bottom: 0; left: 0; right: 0; height: 6px; cursor: ns-resize; }
.mdi-rz-e { top: 0; bottom: 0; right: 0; width: 6px; cursor: ew-resize; }
.mdi-rz-w { top: 0; bottom: 0; left: 0; width: 6px; cursor: ew-resize; }
.mdi-rz-nw { top: 0; left: 0; width: 12px; height: 12px; cursor: nwse-resize; z-index: 7; }
.mdi-rz-ne { top: 0; right: 0; width: 12px; height: 12px; cursor: nesw-resize; z-index: 7; }
.mdi-rz-sw { bottom: 0; left: 0; width: 12px; height: 12px; cursor: nesw-resize; z-index: 7; }
.mdi-rz-se { bottom: 0; right: 0; width: 12px; height: 12px; cursor: nwse-resize; z-index: 7; }
.mdi-resizing, .mdi-resizing * { transition: none !important; }   /* リサイズ中はトランジション無効 */

/* §16.2: 列→Graph ドラッグ中はアプリ全体で grabbing を維持 (Book 窓外/Graph/Canvas/空白でも) */
html.is-dragging-columns,
html.is-dragging-columns body,
html.is-dragging-columns body * { cursor: grabbing !important; }

/* ============ ワークシート ============ */
/* ゴースト列 = 「まだ存在しない、入力すれば生える」列。旧実装は `.ghost` クラスを
   出しているのに**スタイルが 1 つも無く**、実在する列と見分けが付かなかった。
   その結果、ヘッダは A(X) B(Y) C D E F と 6 列に見えるのにステータスバーは「列 2」と出て、
   2 つの権威ある表示が食い違っていた。面と文字を落として「まだ空の枠」だと示す。 */
.ws-table th.ghost { color: var(--text-disabled); background: var(--panel); font-weight: 400; }
.ws-table td.ghost { background: color-mix(in srgb, var(--panel) 55%, transparent); }
.ws-table th.ghost .ws-grip, .ws-table th.ghost .ws-an-fn { display: none; }
.worksheet { outline: none; }
.ws-table {
  /* collapse だと罫線がテーブル側に属し sticky ヘッダに付いてこないため、
     separate にして各セルが右・下罫線を持つ (ヘッダ行の罫線も一緒に固定される) */
  border-collapse: separate;
  border-spacing: 0;
  /* Keep the table at the sum of the explicit colgroup widths. Without an explicit
     width, an auto-sized fixed-layout table shrinks every column to the viewport,
     so the pointer delta and the committed model width no longer describe the
     same boundary (and neighboring columns appear to move). */
  width: max-content;
  min-width: 100%;
  /* §20: 列幅は colgroup が唯一の指定元。fixed でないと <col> の幅が「希望値」扱いになり、
     長い値を持つ列がドラッグ幅を無視して広がってしまう。 */
  table-layout: fixed;
  font-size: var(--fs-md);
  font-variant-numeric: tabular-nums;
  user-select: none;
}
/* D-41: セル編集で行高が変わらないよう、行ボックスの高さを **常時固定**する。
   全値が nowrap の単一行なので明示的な Auto-Fit は導入しない。高さ/行間はセルのフォントサイズ
   (--fs-md) から導出し、.ws-edit も同じ行間に合わせる (下の .ws-edit を参照)。 */
.ws-table th, .ws-table td {
  border: 0;
  border-right: 1px solid var(--panel-border);
  border-bottom: 1px solid var(--panel-border);
  padding: 2px var(--pad-ctl-x);
  height: calc(var(--fs-md) + 8px);
  line-height: calc(var(--fs-md) + 3px);
  vertical-align: middle;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;            /* §20: 幅より長い値は切って隣へはみ出させない */
  text-overflow: ellipsis;
}
.ws-table tr > :first-child { border-left: 1px solid var(--panel-border); }
.ws-colhead > th { border-top: 1px solid var(--panel-border); }
.ws-table thead th, .ws-table thead td { background: var(--panel); }
/* ヘッダ 4 行 (列名 / ロングネーム / 単位 / F(x)=) はスクロールしても固定 */
.ws-table thead th, .ws-table thead td {
  position: sticky;
  z-index: 2;
  height: 25px;
  background: var(--panel);
}
/* 4 行のヘッダを正しい高さで積む (列ヘッダ=34px, メタ各行=25px)。ずれると行が隙間から覗く */
.ws-colhead th { top: 0; }
.ws-row-long th, .ws-row-long td { top: 34px; }
.ws-row-units th, .ws-row-units td { top: 59px; }
.ws-row-formula th, .ws-row-formula td { top: 84px; }

.ws-colhead th {
  text-align: center;
  font-weight: 600;
  color: var(--text);
  cursor: var(--cur-pointer, pointer);
  z-index: 3;
}
/* sticky ヘッダのため選択背景は不透明面に重ねて実効不透明化する (半透明のままだと
   縦スクロール時にデータセルが透けて見える・F-2)。装飾は下線のみに絞る (A-3)。 */
.ws-colhead th.sel {
  background: linear-gradient(var(--surface-active), var(--surface-active)), var(--panel);
  color: var(--text);
  font-weight: 700;
}
.ws-corner { left: 0; z-index: 6; }   /* 左上交差 = 最前面 (§3)。幅は colgroup が決める */
/* §20: 列ヘッダ右端の幅ドラッグゾーン。ヘッダ本体 (列選択・列移動グリップ) とは領域で分離する。
   th は sticky = 位置指定済みなので、そのまま absolute の基準になる。th は overflow:hidden なので
   right:0 の内側に置く (はみ出すと切れて掴めない)。 */
.col-resize {
  position: absolute;
  top: 0;
  right: 0;
  width: 6px;
  height: 100%;
  z-index: 2;
  cursor: col-resize;
}
.col-resize:hover { background: color-mix(in srgb, var(--accent) 45%, transparent); }
/* ホバー中は列番号行からWorksheetの表示領域全体へ境界線を延長する。 */
.ws-col-hover-guide {
  position: fixed;
  width: 2px;
  background: color-mix(in srgb, var(--accent) 55%, transparent);
  z-index: var(--z-toast);
  pointer-events: none;
}
/* ドラッグ中の縦ガイド線 (どこまで広げるかを実測で見せる)。 */
.ws-resize-guide {
  position: fixed;
  width: 2px;
  background: var(--accent);
  z-index: var(--z-toast);
  pointer-events: none;
}
body.ws-col-resizing, body.ws-col-resizing * { cursor: col-resize !important; }
.ws-meta th, .ws-rowhead {
  font-weight: 400;
  font-size: var(--fs-sm);
  color: var(--muted);
  text-align: center;
  background: var(--panel);
  min-width: 42px;
  position: sticky;   /* §3: 行ラベル列(ロングネーム/単位/F(x)=)と行番号を左に固定 */
  left: 0;
}
/* z-index は specificity を thead 既定(0,1,2)より上げて確実に勝たせる (フリーズペインの重なり順) */
.ws-table .ws-meta th { z-index: 5; }     /* メタラベル列: データ・行番号より前面 */
.ws-rowhead { z-index: 4; background: var(--panel); }  /* 行番号: 横スクロールで左固定 (不透明) */
/* sticky 行のため、選択/ホバーは必ず不透明色を使う (半透明だと下のセルが透ける) */
.ws-meta td { text-align: left; color: var(--muted); font-size: var(--fs-base); cursor: var(--cur-text, text); }
.ws-meta td:hover { background: var(--surface-hover); }
/* R6: 選択面の上では文字を `--text` に上げる。
   `--muted` のままだと選択面 (--surface-active) との合成でダークが 4.43:1 になり、
   本文基準 (4.5:1) をわずかに割る。選択されている = 注目している行なので、
   コントラストを上げる方が意味的にも正しい。 */
.ws-meta td.sel {
  /* Sticky meta rows must be opaque: otherwise scrolled data rows show through
     the selected Long name / Unit / F(x) cells. */
  background: linear-gradient(var(--surface-active), var(--surface-active)), var(--panel);
  color: var(--text);
}
.ws-meta td.meta-active {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  background: linear-gradient(var(--surface-active), var(--surface-active)), var(--panel);
}
.ws-formula td { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--accent); }

/* 列ドラッグ移動 */
.ws-dragging { cursor: var(--cur-grab, grabbing) !important; }
.ws-dragging * { cursor: var(--cur-grab, grabbing) !important; }
/* R6-H8: 文字を載せる塗りは `--accent-solid` (操作信号の `--accent` はダークで
   `--accent-text` と 2.45:1 しか出ない)。 */
.ws-table th.drop-target {
  background: var(--accent-solid) !important;
  color: var(--accent-text) !important;
}

/* プロットで選択中のデータポイント行 */
.ws-table tbody tr.hl td { background: var(--sel-bg); }
.ws-table tbody tr.hl th { color: var(--accent); font-weight: 700; }

/* フィット対象の外部ハイライト (要件19): 通常選択とは別レイヤーの淡い teal 面。 */
.ws-table td.exthl { background: color-mix(in srgb, var(--accent) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 24%, transparent); }
.ws-table th.exthl { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.ws-table td.exthl.sel, .ws-table td.exthl.active { background: var(--sel-bg); }
/* External highlight also participates in the sticky header. Keep its meta
   cells opaque so an analysis highlight cannot reveal the rows underneath. */
.ws-table thead .ws-meta td.exthl { background: color-mix(in srgb, var(--accent) 12%, var(--panel)); }
.ws-table thead .ws-meta td.exthl.sel, .ws-table thead .ws-meta td.exthl.active {
  background: linear-gradient(var(--surface-active), var(--surface-active)), var(--panel);
}

/* 行選択 (行番号ヘッダのクリック): 列選択と同じ視覚言語。行番号は sticky-left のため
   不透明面に選択色を重ね (透け防止)、内側=データ側に accent の帯を出す (列ヘッダの下線に対応)。 */
.ws-rowhead.sel {
  background: linear-gradient(var(--surface-active), var(--surface-active)), var(--panel);
  color: var(--text);
  font-weight: 700;
}

/* ============ グラフ内ツールストリップ ============ */
.graph-tools {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlay);
  padding: 3px;
}
.graph-tools button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 24px;
  /* R5-C1: アイコンだけのボタンは左右パディングを持たない。
     汎用の button 規則から `1px 6px` を継いでいたため、24px の箱に 16px のアイコン +
     12px のパディングが入らず、中身が箱をはみ出していた (overflow の指定も無かったので
     隣のボタンの上に描かれる)。ラベル付きは .gt-labeled 側で改めて与える。 */
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  cursor: var(--cur-pointer, pointer);
}
/* §18: 横並びストリップ変種。浮遊パレットの装飾 (絶対配置/影/枠/縦並び) をここで一括解除する。
   フィットのプレビュー上端と結果タブのグラフが同じ 1 系統を通る (旧: 片方だけ完全上書き)。 */
.graph-tools.gt-strip {
  position: static;
  flex-direction: row;
  align-items: center;
  gap: 1px;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}
.graph-tools.gt-strip .gt-sep { width: 1px; height: 16px; margin: 0 3px; background: var(--panel-border); }
.graph-tools.gt-strip .gt-sub { flex-direction: row; }
/* 子ウィンドウ専用ツールバーへ埋め込んだとき (D-63): サブメニューはボタンの**下**へ出す。
   横並びのままだと左隣のボタンを覆ってしまう。 */
.graph-tools.gt-inbar { flex: none; }
/* R5-C1: 正方形にするのは **ラベルの無いボタンだけ**。
   旧実装は `.graph-tools.gt-inbar button`(詳細度 0-2-1) が全ボタンを 24px に固定し、
   後段の `.graph-tools .gt-labeled`(0-2-0) が負けていた。overflow も無かったので
   「読取」「注釈」のラベルが箱の外へ溢れ、隣のボタンの上に重なって描かれていた
   (見えている文字と当たり判定が食い違う)。 */
.graph-tools.gt-inbar button:not(.gt-labeled) { width: var(--control-h); height: var(--control-h); }
/* R6-C3: 休止色は隣に並ぶ `.wt-btn` と同じ `--text`。
   旧実装だけ `--muted` だったため、**同じツールバーの中で「読取」「注釈」が
   無効に見え、隣の「Add plot」「Axes」は有効に見える**という状態だった
   (`.wt-btn` 側のコメントは「既定を --muted にすると無効との差が付かない」と
   自ら書いている)。 */
.graph-tools.gt-inbar button { color: var(--text); overflow: hidden; }
.graph-tools.gt-inbar button:hover:not(:disabled) { color: var(--text); background: var(--surface-hover); }
.graph-tools.gt-inbar .gt-sub { left: 0; top: 100%; margin-left: 0; margin-top: 4px; }
.graph-tools.gt-inbar .gt-sub::before { left: 0; right: 0; top: -6px; bottom: auto; width: auto; height: 6px; }
.graph-tools button:hover { background: var(--surface-hover); }
/* 選択中のツール = 面 + accent のアイコン。一辺の線という形は使わない。 */
/* R6-C3 / R6-M1: 選択中は **面 + 太さ + アイコンの accent**。
   文字を accent にすると選択面の上で 4.0:1 前後にしかならず、
   `.wt-btn.active` (面 + 600 + アイコン accent) と語彙も食い違っていた。 */
.graph-tools button.active { background: var(--surface-active); color: var(--text); font-weight: 600; }
.graph-tools button.active svg { color: var(--accent); }
/* アイコンの寸法と線幅は 1 か所で決める (同一バー内でサイズ・線幅を混ぜない)。
   旧実装は markup 側のインライン width/height と、アイコンごとに違う viewBox 内容に
   任せていたため、実測で 12px と 13px が混在していた。 */
.graph-tools button svg {
  width: var(--icon-md); height: var(--icon-md); flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.4;
  stroke-linecap: round; stroke-linejoin: round;
}
/* 選択中は線を一段太くする (色だけに頼らない状態表現)。 */
.graph-tools button.active svg { stroke-width: 1.8; }
.graph-tools button:disabled { color: var(--text-disabled); background: transparent; cursor: var(--cur-arrow, default); }
.graph-tools button:focus-visible { box-shadow: var(--focus-ring); outline: none; }
.graph-tools .gt-sep { height: 1px; background: var(--panel-border); margin: 2px 2px; }
.graph-tools .gt-item { position: relative; }
.graph-tools .gt-sub {
  display: none;
  position: absolute;
  left: 100%;
  top: 0;
  margin-left: 5px;
  flex-direction: row;
  gap: 2px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlay);
  padding: 3px;
  z-index: 11;
}
/* ボタンとサブメニューの隙間を透明ブリッジで埋めて、ホバーが途切れないようにする */
.graph-tools .gt-sub::before {
  content: "";
  position: absolute;
  left: -8px;
  top: -4px;
  bottom: -4px;
  width: 8px;
}
/* D-85: 注釈ツールは 1 つの入口にまとめ、中身はラベル付きの縦リストにする。
   専門機能をアイコン単独で表さないための最低条件。 */
.graph-tools .gt-labeled { width: auto; height: var(--control-h); padding: 0 var(--pad-ctl-x-sm); gap: var(--icon-gap); flex: none; white-space: nowrap; }
.graph-tools .gt-lbl { font-size: var(--fs-sm); white-space: nowrap; }
.graph-tools .gt-anno-sub { flex-direction: column; align-items: stretch; min-width: 148px; }
.graph-tools .gt-anno-sub > .gt-item { position: relative; }
.graph-tools .gt-anno-sub > .gt-item > button {
  width: 100%; justify-content: flex-start; gap: var(--icon-gap);
  padding: 0 var(--pad-ctl-x-sm); height: var(--control-h);
}
/* 2 段目のフライアウト (線の種類・記号の形状・図形・整列) は右へ開く。 */
.graph-tools .gt-anno-sub .gt-sub {
  left: 100%; top: 0; margin: 0 0 0 4px; flex-direction: row; min-width: 0;
}
.graph-tools .gt-anno-sub .gt-sub::before { left: -6px; top: 0; bottom: 0; right: auto; width: 6px; height: auto; }

/* サブメニューはホバー**だけ**にしない。中の 21 コマンド (線種/記号/図形/整列/均等配置) が
   キーボードから到達不能になり、しかもメニューバーにもコマンド検索にも載っていないため、
   マウス以外に実行経路が無くなる。:focus-within で Tab / 矢印からも開く。 */
.graph-tools .gt-item:hover .gt-sub,
.graph-tools .gt-item:focus-within .gt-sub { display: flex; }
/* 整列フライアウトは 4 列でグリッド折返し (8 ボタン → 2 行) */
.graph-tools .gt-sub.gt-align { flex-wrap: wrap; width: 124px; }
/* R6-C3: 無効は **色だけ**で示す。opacity を重ねると合成後のコントラストが
   1.51:1 まで落ち、`.wt-btn.is-disabled` (4.69:1) と二重基準になっていた。
   a11y 監査は無効要素を対象外にするので、ここは監査の死角でもあった。 */
.graph-tools button:disabled { cursor: var(--cur-arrow, default); }
.graph-tools button:disabled svg { opacity: 0.7; }   /* アイコンだけ一段落とす (.wt-btn と同じ) */
.graph-tools button:disabled:hover { background: transparent; }

/* テキストアノテーションのインライン入力 */
.anno-input {
  position: absolute;
  z-index: 20;
  min-width: 120px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 3px 6px;
  font-size: var(--fs-md);
  outline: none;
  box-shadow: var(--shadow-overlay);
}
.ws-table tbody td { background: var(--panel-2); cursor: var(--cur-text, text); }
.ws-table tbody td.sel { background: var(--sel-bg); }
.ws-table tbody td.active {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.ws-table tbody td.sel-anchor { outline: none; }
/* Excel-style selection geometry: the fill belongs to every selected cell,
   while the accent frame belongs only to the outside of the contiguous
   selection. The active cell stays readable inside a multi-cell selection. */
.ws-table .sel-edge-top,
.ws-table .sel-edge-right,
.ws-table .sel-edge-bottom,
.ws-table .sel-edge-left {
  --ws-sel-top: 0 0 0 transparent;
  --ws-sel-right: 0 0 0 transparent;
  --ws-sel-bottom: 0 0 0 transparent;
  --ws-sel-left: 0 0 0 transparent;
}
.ws-table .sel-edge-top { --ws-sel-top: inset 0 2px 0 var(--accent); }
.ws-table .sel-edge-right { --ws-sel-right: inset -2px 0 0 var(--accent); }
.ws-table .sel-edge-bottom { --ws-sel-bottom: inset 0 -2px 0 var(--accent); }
.ws-table .sel-edge-left { --ws-sel-left: inset 2px 0 0 var(--accent); }
.ws-table .sel-edge-top,
.ws-table .sel-edge-right,
.ws-table .sel-edge-bottom,
.ws-table .sel-edge-left {
  box-shadow: var(--ws-sel-top), var(--ws-sel-right),
    var(--ws-sel-bottom), var(--ws-sel-left);
}
.ws-table tbody td.sel.active { background: var(--panel-2); }
.worksheet.grid-copying .sel-edge-top,
.worksheet.grid-copying .sel-edge-right,
.worksheet.grid-copying .sel-edge-bottom,
.worksheet.grid-copying .sel-edge-left {
  border-color: var(--accent) !important;
  outline: 1px dashed var(--accent);
  outline-offset: -2px;
}
/* マスク (解析から除外) されたセル。
   状態を**色だけ**で伝えない: 斜線ハッチ (非色の手掛かり) を重ねる。
   色は状態色 (--warn) を使う。--fit-color は「フィット曲線」に予約した
   データシグナル色で、役割を使い回すと「赤い = フィット関連」という学習が壊れる。
   旧実装はトークン外の生 rgb(217,48,37) を直書きしており --fit-color とも不一致だった。 */
.ws-table tbody td.masked {
  color: var(--warn);
  background:
    repeating-linear-gradient(135deg,
      transparent 0 5px,
      color-mix(in srgb, var(--warn) 22%, transparent) 5px 6px),
    color-mix(in srgb, var(--warn) 8%, transparent);
}
/* 欠損値 (実データ範囲内の null) は「空欄」ではなく「値が無い」と読めるようにする。
   ステータスバーは欠損数を数えるのに、表の上ではどこが欠損か辿れなかった。 */
.ws-table tbody td.missing::after { content: "—"; color: var(--text-disabled); }
/* 編集中は欠損記号を疑似要素ごと隠す。空の `—` セルに入力を始めても、
   記号と入力値が重なって 2 行に見えないようにする。 */
.ws-table td.editing-cell::after { content: none !important; }
.ws-cell-dragging, .ws-cell-dragging * { user-select: none; cursor: cell; }

/* 行列(Matrix)シートのグリッド */
.matrix-host { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.matrix-view { display: flex; flex-direction: column; height: 100%; }
.mx-tools { display: flex; align-items: center; gap: 6px; padding: 3px 6px; border-bottom: 1px solid var(--panel-border); }
.mx-tools button { font-size: var(--fs-sm); padding: 1px 7px; }
.mx-tools .mx-dim { color: var(--muted); font-size: var(--fs-sm); margin-left: auto; }
/* N9: 「まだ右/下に続く」ことを面で示す。オーバーレイ式のスクロールバーは操作するまで
   現れず、静止状態では表がどこで終わるのか分からなかった。
   セルは不透明なので、スクローラの**外側**に重ねた scrim で示す (親の inset 影は
   セル背景の下に潜って見えない)。JS が実列/実行の隠れ具合を測ってクラスを付ける。
   accent は使わない中立の諧調で、装飾の線ではない (一辺アクセント線の規約に触れない)。 */
.mx-wrap { position: relative; flex: 1; min-height: 0; display: flex; }
.mx-scroll { flex: 1; min-width: 0; overflow: auto; }
.mx-wrap::after, .mx-wrap::before {
  content: ""; position: absolute; pointer-events: none; opacity: 0;
  transition: opacity var(--dur-short) var(--ease-out);
}
/* R9-M9: 右の掃き寄せは**ヘッダ行も含めて**上端から下端まで。旧実装はセルの
   スクローラ基準の height:100% だったので、sticky なヘッダ行がその外に出て、
   セルは丁寧にフェードするのにヘッダの数字だけが断ち切られていた。 */
.mx-wrap::after  { top: 0; right: 0; width: 20px; bottom: 0; height: auto;
  z-index: 2;
  background: linear-gradient(to right, transparent, var(--scrim-edge)); }
.mx-wrap::before { left: 0; bottom: 0; height: 20px; width: 100%; z-index: 1;
  background: linear-gradient(to bottom, transparent, var(--scrim-edge)); }
.mx-wrap.can-x::after  { opacity: 1; }
.mx-wrap.can-y::before { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .mx-wrap::after, .mx-wrap::before { transition: none; } }
.mx-table { border-collapse: separate; border-spacing: 0; font-size: var(--fs-md); }
.mx-table th, .mx-table td {
  border: 0; border-right: 1px solid var(--panel-border); border-bottom: 1px solid var(--panel-border);
  min-width: 58px; height: 22px; padding: 1px 6px;
}
.mx-table tr:first-child > * { border-top: 1px solid var(--panel-border); }
.mx-table tr > *:first-child { border-left: 1px solid var(--panel-border); }
/* 面はワークシートと同じ並び: ヘッダ = --panel (器) / セル = --panel-2 (紙)。
   旧実装は逆でヘッダが白くデータ面が沈み、面階層の規約に反していた。 */
.mx-table th { background: var(--panel); color: var(--text); text-align: center; font-weight: 600; position: sticky; }
.mx-table thead th {
  top: 0; z-index: 3; background-clip: padding-box;
  /* border-collapse: separate だけでは sticky 面と本文の境界が薄くなるため、
     ヘッダー自身に下罫線を焼き付ける。スクロールしてもこの線はヘッダーと一緒に動かない。 */
  box-shadow: inset 0 -1px 0 var(--panel-border);
}
/* 行番号は横スクロールで左に固定する。left が無いと position:sticky は効かない
   (ワークシート側は style.css の .ws-rowhead で left:0 を持っている)。 */
.mx-table .mx-rowhead { left: 0; z-index: 2; }
.mx-table thead th.mx-corner { left: 0; z-index: 4; }
/* 数値は桁位置を揃える (ワークシートのセルと同じ扱い)。 */
.mx-table td { background: var(--panel-2); color: var(--text); text-align: right; cursor: cell;
  font-variant-numeric: tabular-nums; }
/* N9: ゴースト行/列 = 「行列の外側」。ワークシートの .ghost と同じ語彙 (淡い面 + 淡い番号) で、
   表がどこで終わるのかを面で示す。クリック対象ではない (data-r/data-c を持たない)。 */
.mx-table th.ghost { color: var(--text-disabled); font-weight: 400; }
.mx-table td.ghost { background: color-mix(in srgb, var(--panel) 55%, transparent); cursor: default; }
/* R7-HIGH11: 行列シートの選択表現。ワークシートと同じ語彙で揃える
   (範囲 = --sel-bg の面 / カーソル = 全周のリング)。旧実装は `.mx-cur` を DOM に
   付けていたのに **CSS が 1 行も無く**、キーボードで動かしてもどのセルにいるのか
   画面から分からなかった。一辺だけの線は使わない (絶対規約 1)。 */
.mx-table tbody td.mx-sel { background: var(--sel-bg); }
.mx-table thead th.mx-col-sel,
.mx-table tbody tr.mx-row-sel > th.mx-rowhead { background: var(--surface-active); color: var(--text); }
.mx-table tbody td.mx-sel { background: var(--sel-bg); color: var(--text); }
.mx-table tbody tr.mx-row-sel > td { background: var(--sel-bg); }
/* Sticky headers must be opaque even in the selected state. `--surface-active` is
   intentionally translucent for ordinary selection surfaces; on a fixed header it
   would reveal scrolled cells underneath (the same failure as the Worksheet header). */
.mx-table thead th.mx-col-sel {
  background: linear-gradient(var(--surface-active), var(--surface-active)), var(--panel);
  font-weight: 700;
}
.mx-table tbody tr.mx-row-sel > th.mx-rowhead {
  background: linear-gradient(var(--surface-active), var(--surface-active)), var(--panel);
}
.mx-table tbody td.mx-cur {
  outline: none;
}
.mx-table tbody td.mx-cur.mx-single-cur {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
/* Match Worksheet/Excel selection geometry in Matrix sheets. Heatmap/image
   modes keep their data colors; these inset shadows add only the outside
   frame, with no per-cell accent boxes inside the selected rectangle. */
.mx-table .mx-edge-top,
.mx-table .mx-edge-right,
.mx-table .mx-edge-bottom,
.mx-table .mx-edge-left {
  --mx-sel-top: 0 0 0 transparent;
  --mx-sel-right: 0 0 0 transparent;
  --mx-sel-bottom: 0 0 0 transparent;
  --mx-sel-left: 0 0 0 transparent;
}
.mx-table .mx-edge-top { --mx-sel-top: inset 0 2px 0 var(--accent); }
.mx-table .mx-edge-right { --mx-sel-right: inset -2px 0 0 var(--accent); }
.mx-table .mx-edge-bottom { --mx-sel-bottom: inset 0 -2px 0 var(--accent); }
.mx-table .mx-edge-left { --mx-sel-left: inset 2px 0 0 var(--accent); }
.mx-table .mx-edge-top,
.mx-table .mx-edge-right,
.mx-table .mx-edge-bottom,
.mx-table .mx-edge-left {
  box-shadow: var(--mx-sel-top), var(--mx-sel-right),
    var(--mx-sel-bottom), var(--mx-sel-left);
}
.mx-mode-value .mx-table tbody td.mx-sel.mx-cur,
.mx-mode-value .mx-table tbody td.mx-cur { background: var(--panel-2); }
.mx-dragging, .mx-dragging * { user-select: none; cursor: cell; }
.matrix-view.grid-copying .mx-edge-top,
.matrix-view.grid-copying .mx-edge-right,
.matrix-view.grid-copying .mx-edge-bottom,
.matrix-view.grid-copying .mx-edge-left {
  outline: 1px dashed var(--accent);
  outline-offset: -2px;
}

/* ============ R12-1: 行列シートの表示モード (数値 / ヒートマップ / 画像) ============
   行列は**面としてのデータ**なので、桁を読む用途 (value) と分布の形を掴む用途
   (heatmap / image) は別物。数値しか出せないと「読みにくいワークシート」で終わる。
   色は viridis (知覚的にほぼ均等・単調・色覚多様性でも順序が保たれる)。 */

/* 欠損は塗らない。0 と同じ色にすると「測っていない」と「0 だった」が区別できない。 */
.mx-table tbody td.mx-na {
  background:
    repeating-linear-gradient(45deg,
      transparent 0 3px,
      color-mix(in srgb, var(--muted) 26%, transparent) 3px 4px),
    var(--panel-2);
}

/* 画像モード: 格子も数値も出さず、色だけの面にする (全体像を掴む)。
   **table-layout: fixed が要る** — 既定の auto では、幅の広い窓で列が引き伸ばされ
   セル幅の指定が効かない (実測 58px のまま = 画像として全体を見る目的を果たさない)。 */
.mx-mode-image .mx-table { table-layout: fixed; width: auto; }
.mx-mode-image .mx-table td,
.mx-mode-image .mx-table th { min-width: 0; width: 12px; height: 12px; padding: 0; }
.mx-mode-image .mx-table td { border-color: transparent; }
.mx-mode-image .mx-table th { font-size: var(--fs-xs); overflow: hidden; }
.mx-mode-image .mx-table th.mx-rowhead, .mx-mode-image .mx-table th.mx-corner { width: 40px; min-width: 40px; }

/* カーソルは **どの値の上でも読める二重リング**にする。
   カラーマップは面全体がデータなので、accent 1 色だと viridis の中間 (青緑) に
   埋もれる。全周のリングなので絶対規約 1 (一辺だけのアクセント線) には触れない。 */
.mx-mode-heatmap .mx-table tbody td.mx-cur,
.mx-mode-image .mx-table tbody td.mx-cur {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--ondata-hi), inset 0 0 0 4px var(--ondata-lo);
}
/* 選択範囲も同様に、面ではなく**縁**で示す (面で示すと値の色を壊す)。 */
.mx-mode-heatmap .mx-table tbody td.mx-sel,
.mx-mode-image .mx-table tbody td.mx-sel {
  background-image: linear-gradient(color-mix(in srgb, var(--ondata-hi) 26%, transparent),
                                    color-mix(in srgb, var(--ondata-hi) 26%, transparent));
}

/* 色の目盛り。値域が読めないヒートマップは装飾でしかないので必ず添える。 */
.mx-legend {
  display: flex; align-items: center; gap: var(--gap-inline);
  flex: none; padding: 4px var(--pad-panel);
  background: var(--panel); border-top: 1px solid var(--panel-border);
  font-size: var(--fs-xs); color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.mx-legend-bar { flex: 1; min-width: 60px; max-width: 220px; height: 8px; border-radius: var(--radius-ctl);
  border: 1px solid var(--panel-border); }
.mx-legend-na::before {
  content: ""; display: inline-block; width: 9px; height: 9px; margin-right: 4px; vertical-align: -1px;
  border: 1px solid var(--panel-border);
  background: repeating-linear-gradient(45deg, transparent 0 3px,
    color-mix(in srgb, var(--muted) 26%, transparent) 3px 4px), var(--panel-2);
}
/* 目盛りを出すぶん、表の器は縦積みにする。 */
.mx-wrap.mx-mode-heatmap, .mx-wrap.mx-mode-image { flex-direction: column; }
/* D-41: セルに差し込む入力。inline-block/baseline だと行ボックス高が変動するため block + 固定高に。
   高さと行間はセル (.ws-table td) と同一の導出式にして、編集開始/入力中/確定で行高が動かないようにする。
   グローバルの input 高さ (--control-h) はここで上書きする。 */
.ws-edit {
  display: block;
  width: 100%;
  height: calc(var(--fs-md) + 3px);
  line-height: calc(var(--fs-md) + 3px);
  border: none;
  border-radius: 0;
  outline: none;
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: right;
  padding: 0;
}
/* Metadata rows use the same in-cell editor as numeric cells, but inherit
   their left-aligned header-cell typography and surface. */
.ws-meta .ws-edit {
  background: transparent;
  text-align: left;
  color: inherit;
  font-size: inherit;
}
/* 行の窓のページャ (1000 行を超えるシート)。「いまどこを見ているか」と移動手段を 1 行で。 */
.ws-pager { display: flex; align-items: center; gap: var(--gap-inline); padding: var(--space-1) var(--gap-inline); }
.ws-pager span { font-variant-numeric: tabular-nums; }
/* R12-3: 任意の行へ 1 操作で飛ぶ入力。ページャは「前へ / 次へ」だけだと
   5 万行で末尾まで 49 クリック掛かる (実測)。 */
.ws-goto { display: inline-flex; align-items: center; gap: var(--gap-inline); margin-left: auto; }
.ws-goto-in {
  width: 7ch; height: var(--control-h-sm); padding: 0 var(--pad-ctl-x-sm);
  text-align: right; font-variant-numeric: tabular-nums;
  color: var(--text); background: var(--panel-2);
  border: 1px solid var(--control-border); border-radius: var(--radius-ctl);
  font-size: var(--fs-base);
}
.ws-goto-in:focus-visible { box-shadow: var(--focus-ring); outline: none; }

.ws-note { color: var(--muted); text-align: center; font-size: var(--fs-sm); }

/* ============ グラフ ============ */
/* ページ (固定論理サイズのキャンバス) をアスペクト比固定で中央表示 */
.graph-content {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--bg-deep);
}
.graph-canvas {
  display: block;
  cursor: var(--cur-cross, crosshair);
  background: var(--panel-2);
  box-shadow: var(--shadow);
  flex: none;
}
/* 背景が透明のキャンバスは市松模様で可視化 (出力には含まれない) */
.graph-canvas.bg-transparent {
  background:
    repeating-conic-gradient(rgba(127, 127, 127, 0.18) 0% 25%, transparent 0% 50%) 0 0 / 16px 16px,
    var(--panel-2);
}
.graph-readout {
  position: absolute;
  pointer-events: none;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlay);
  padding: 3px 8px;
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  z-index: 5;
}
.graph-readout .pt-name { color: var(--accent); font-weight: 600; }

/* ============ 解析結果タブ (各ページタブに収納・入れ子表示) ============ */

/* 収納状態: ページタブの右に少しずつズレて重なったタブの束。枚数 = 結果の件数 */
.result-stack {
  display: inline-flex;
  align-items: flex-end;
  margin-left: -6px; /* 先頭の1枚はページタブの下に少し潜り込む */
  cursor: var(--cur-pointer, pointer);
  flex: none;
}
.rs-stub {
  width: 24px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--result-ink);
  background: var(--result-bg);
  border: 1px solid var(--result-border);
  border-bottom: none;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  margin-left: -9px; /* 前の1枚に重なり、アイコンが見える分だけズレる */
}
.rs-stub:first-child { margin-left: 0; }
.result-stack:hover .rs-stub { background: var(--result-hover); }
/* ページタブが束の上に重なって見えるように */
.page-tab[data-i] { position: relative; z-index: 1; }
.result-stack { position: relative; z-index: 0; }

/* 結果タブ: ページタブと同列に並ぶが、収納元が分かるよう色味を変える */
.page-tab.result-tab {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 220px;
  font-weight: 600;
  color: var(--result-ink);
  background: var(--result-bg);
  border-color: var(--result-border);
  white-space: nowrap;
  position: relative;
}
.page-tab.result-tab:hover { background: var(--result-hover); }
.page-tab.result-tab.active {
  color: var(--accent);
  background: var(--panel-2);
  border-color: var(--panel-border);
}
.result-tab .rt-icon {
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  flex: none;
}
.result-tab .rt-label { overflow: hidden; text-overflow: ellipsis; }

/* 展開された結果タブ群の右端の収納ボタン */
.result-fold {
  display: inline-flex;
  align-items: center;
  margin-bottom: 2px;
  padding: 2px 7px;
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--result-ink);
  background: var(--result-bg);
  border: 1px solid var(--result-border);
  border-radius: var(--radius-ctl);
  cursor: var(--cur-pointer, pointer);
  flex: none;
  user-select: none;
}
.result-fold:hover { background: var(--result-hover); color: var(--accent); }

/* シート領域に表示する結果ビュー (データグリッドと切り替え) */
.result-host {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 6px 14px 12px;
  font-size: var(--fs-base);
  background: var(--panel-2);
}

.log-entry {
  border-bottom: 1px dashed var(--panel-border);
  padding: 8px 0;
}
.log-head { margin-bottom: 5px; }
.log-eq { margin-left: 12px; color: var(--muted); font-family: var(--font-mono); font-size: var(--fs-sm); }
/* T4.1: 結果テーブルはワークシートと同じ見た目に揃える。
   ・フォントは --fs-md + tabular-nums (数値の桁が縦に揃う)
   ・罫線は「セルの右下 1px」方式 (worksheet と同じ = 二重線にならない)
   ・ヘッダは背景付きで sticky (縦に長い結果表でも列名が残る)
   ・行番号ヘッダは付けない (結果表に行番号の意味は無い) */
.log-table {
  border-collapse: separate; border-spacing: 0;
  font-variant-numeric: tabular-nums; font-size: var(--fs-md);
  border-top: 1px solid var(--panel-border);
  border-left: 1px solid var(--panel-border);
}
.log-table th, .log-table td {
  border-right: 1px solid var(--panel-border);
  border-bottom: 1px solid var(--panel-border);
  padding: 3px 10px;
  text-align: right;
  font-size: inherit;
}
.log-table th {
  position: sticky; top: 0; z-index: 1;
  background: var(--titlebar); color: var(--text); font-weight: 600; text-align: center;
}
.log-table td:first-child { font-family: var(--font-mono); text-align: left; }
/* T4.1: セル / 範囲選択 (RTable)。列選択 (.rt-selcol) と重ねて使える。 */
.log-table td.rt-cellsel, .rtable td.rt-cellsel { background: var(--sel-bg); box-shadow: inset 0 0 0 1px var(--accent); }
.log-stats { margin-top: 5px; color: var(--muted); }
.log-stats b { color: var(--text); }

/* ============ コマンド検索 (command.js) ============
   全画面の暗幕は張らない (背後の状態を隠さない)。面としての手前感は、枠 + 影 + わずかな
   背景の後退だけで作る。行は「名称 / 説明 / 無効の理由」を左、「作用対象 / ショートカット」を
   右に置き、視線が 2 列で済むようにする。 */
#cmdpal {
  position: fixed;
  /* 中央寄せの基準は**作業スペース**。ビューポート中央にすると、左サイドバーと
     右レールのぶん (実測 106px) 左へずれて見える。
     実際の inset は open() が #workspace を実測して書く (パネルの開閉・収納で
     幅が変わるうえ、収納時のレール幅はトークンに出ていないため)。 */
  top: 0; bottom: 0; left: 0; right: 0;
  z-index: var(--z-modal);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  /* 縦位置はスケール上の固定値。vh だと窓の高さで動き、子ウィンドウの
     タイトルバーに重なる位置まで下がることがある。 */
  padding-top: calc(var(--space-6) * 3);
  /* 背景は暗転させない (design.md: --scrim は全廃)。手前感は枠 + 影だけで作る。
     背後の窓・データが読めたまま残るので、「いま何を対象に検索しているか」が消えない。 */
  background: transparent;
}
.cp-box {
  width: min(720px, calc(100vw - 32px));
  max-height: 66vh;
  display: flex;
  flex-direction: column;
  background: var(--panel-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-modal);
  overflow: hidden;
}
.cp-inwrap {
  display: flex;
  align-items: center;
  gap: var(--gap-inline);
  padding: 0 var(--pad-panel);
  height: 38px;
  border-bottom: 1px solid var(--panel-border);
  flex: none;
}
.cp-inwrap svg { width: var(--icon-md); height: var(--icon-md); flex: none; fill: none; stroke: var(--muted); stroke-width: 1.3; stroke-linecap: round; }
#cp-input {
  flex: 1; min-width: 0;
  height: 100%;
  border: none; background: transparent; outline: none;
  color: var(--text); font-size: var(--fs-md); font-family: var(--font-ui);
}
#cp-input::placeholder { color: var(--text-disabled); }
/* 入力欄そのものには枠が無いので、フォーカスは**行全体**で示す
   (キーボードだけで開いたとき、どこに入力されるのかが分からなくならないように)。 */
.cp-inwrap:focus-within { box-shadow: inset 0 0 0 1px var(--accent); }
#cp-input:focus-visible { outline: none; }
.cp-esc, .cp-kbd, .cp-foot kbd, .tb-kbd {
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted);
  padding: 1px 4px; border: 1px solid var(--panel-border); border-radius: var(--radius-ctl);
  background: var(--panel); flex: none;
}
.cp-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; list-style: none; margin: 0; padding: 4px; }
.cp-row {
  display: flex; align-items: center; gap: var(--gap-group);
  padding: 4px var(--pad-ctl-x);
  min-height: 28px;
  border-radius: var(--radius-ctl);
  cursor: var(--cur-pointer, pointer);
}
/* 選択行は「面 + 左 2px のアクセント」。全面アクセント塗りにはしない。 */
/* 選択行 = 面 + 文字の weight。一辺のアクセント線は使わない。 */
.cp-row.sel { background: var(--surface-active); }
/* R7-M: 実行できない行で Enter を押したときの手応え。理由はステータスバーにも出る。
   一辺の線でなく**全周のリング**で示す (絶対規約 1)。 */
.cp-row.cp-nope { animation: cp-nope var(--dur-med) var(--ease-out); }
@keyframes cp-nope {
  0%, 100% { box-shadow: none; }
  40% { box-shadow: inset 0 0 0 1px var(--bad); }
}
.cp-row.sel .cp-title { font-weight: 600; }
/* R7-M: 選択行は面が明るくなるぶん `--muted` では 4.5:1 を割る (dark 実測 4.43:1)。
   選択行だけ本文色へ上げる (面と文字の組み合わせで判定するのが正しい)。 */
.cp-row.sel .cp-desc, .cp-row.sel .cp-target, .cp-row.sel .cp-path { color: var(--text); }
.cp-row.disabled { cursor: var(--cur-arrow, default); }
.cp-row.disabled .cp-title { color: var(--text-disabled); }
.cp-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cp-title { font-size: var(--fs-base); color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cp-desc { font-size: var(--fs-sm); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: var(--measure-help); }
/* 無効の理由は「!」+ warn 色 + 専用行。色だけで無効を伝えない。 */
.cp-why { font-size: var(--fs-xs); color: var(--warn); }
.cp-why::before { content: "! "; font-weight: 700; }
.cp-right { flex: none; display: flex; align-items: center; gap: var(--gap-inline); }
.cp-target { font-size: var(--fs-xs); color: var(--muted); letter-spacing: var(--tracking-tight); }
.cp-row.sel .cp-target, .cp-row.sel .cp-path { color: var(--text); }
.cp-path { font-size: var(--fs-xs); color: var(--muted); }
.cp-empty { padding: 14px var(--pad-panel); font-size: var(--fs-base); color: var(--muted); text-align: center; }
.cp-foot {
  flex: none; display: flex; align-items: center; gap: var(--gap-group);
  padding: 5px var(--pad-panel);
  border-top: 1px solid var(--panel-border);
  background: var(--panel);
  font-size: var(--fs-xs); color: var(--muted);
}
.cp-foot kbd { margin-right: 2px; }
.cp-foot-note { margin-left: auto; color: var(--muted); }

/* ============ ステータスバー ============ */
#statusbar {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;            /* 文字が長くても 2 行にしない */
  white-space: nowrap;
  height: var(--statusbar-h);
  padding: 0 var(--pad-panel);
  background: var(--chrome-bg);
  border-top: 1px solid var(--chrome-border);
  font-size: var(--fs-base);
  /* D-110: 筐体 (--bg) を沈めたので、その上の副テキストは面専用の色を使う
     (--muted は新しい筐体の上で 4.08:1 と本文基準を割る)。 */
  color: var(--chrome-ink);
  flex: none;
  overflow: hidden;
}
/* 長文ステータスは 1 行で省略 (… )。flex で縮小可にして溢れさせない */
#status { min-width: 0; flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; outline: none; }
#status.error { color: var(--bad); }
#status:focus-visible { box-shadow: var(--focus-ring); border-radius: var(--radius-ctl); }
/* 一過性メッセージは時間で引く。消さずに薄くするのは、直前に何が起きたかを
   目の端で追えるようにするため (完全に消すと「見逃した」が起きる)。 */
#status.faded { color: var(--chrome-ink-muted); transition: color var(--dur-med) var(--ease-out); }

/* ---- 読み取り値セグメント (statusbar.js) ----
   右側は「いまの状態」だけを置く。ラベルは補足 (--fs-xs / disabled)、値は本文 (--fs-base /
   tabular-nums) と、サイズ・太さ・色の 3 軸で階層を付ける。区切りは 1px のヘアラインだけ。 */
#status-segs { flex: none; display: flex; align-items: center; gap: 0; white-space: nowrap; }
.sb-seg {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding: 0 10px;
  border-left: 1px solid var(--chrome-border);
  min-height: 14px;
}
.sb-seg:first-child { border-left: none; }
.sb-seg:last-child { padding-right: 0; }
/* D-110: 読み取り値のラベルも筐体面の上に載るので --chrome-ink。
   --muted のままだと 10px の文字が新しい筐体の上で 3.7:1 になる (audit-a11y が検出)。 */
.sb-k { font-size: var(--fs-xs); color: var(--chrome-ink); letter-spacing: var(--tracking-tight); }
.sb-v { font-size: var(--fs-base); color: var(--chrome-ink); font-variant-numeric: tabular-nums; }
/* D-88: 読み取り値も本文と同じ書体 (--font-ui) + tabular-nums。
   実データ (セル・軸ラベル) が --font-ui なのに、補助的なステータスの数値だけ
   等幅にすると重要度が逆に見え、1 行の中で 2 書体が混植される。
   等幅は座標・式・列名など「文字として同定する」用途に限定する。 */
.sb-v.mono { font-family: inherit; }
/* 実行中のセグメントは点滅ではなく「文字色 = アクセント」で示す (視界の端で疲れない)。 */
.sb-seg.busy .sb-v { color: var(--accent); }
.coords { flex: none; font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-size: var(--fs-sm); white-space: nowrap; }

/* 設定ボタン(statusbar 右の歯車)。テーマ/フォント/言語は設定画面に集約 */
.statusbar-btn {
  flex: none;
  margin-left: 12px;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--panel-border);
  background: var(--panel-2);
  color: var(--muted);
  border-radius: var(--radius-ctl);
  padding: 1px 9px;
  font-size: var(--fs-sm);
  line-height: 1.4;
  cursor: var(--cur-pointer, pointer);
}
.statusbar-btn:hover { color: var(--accent); border-color: var(--accent); }
.statusbar-btn:focus-visible { box-shadow: var(--focus-ring); outline: none; }

/* 設定ダイアログ */
/* §24: 設定画面もフィット窓/解析ダイアログと同じ行モデル (ラベル列 + コントロール)。
   旧実装だけ 120px グリッド・--fs-base・行間 14px と独自で、別画面のように見えていた。 */
.settings-grid { display: flex; flex-direction: column; gap: var(--gap-stack); min-width: 320px; }
.settings-row { display: flex; align-items: center; gap: var(--gap-inline); min-height: var(--control-h); }
.settings-row > label { flex: none; width: 130px; color: var(--muted); font-size: var(--fs-sm); font-weight: 600; }
.settings-row select { flex: 0 1 auto; width: auto; min-width: 180px; max-width: 240px; }

/* ============ モーダル ============ */
/* 背景の暗転は行わない (計画 10.1)。
   オーバーレイは「入力のブロック + 中央寄せ」だけを担い、背後のワークスペース・ブック・グラフ・
   Explorer は常に読める状態に保つ。ダイアログ自体の視認性は #modal の枠 + shadow で確保する
   (暗幕を別の場所へ移すのではなく、暗幕そのものを廃止する)。 */
#modal-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
}
#modal {
  position: relative;   /* .dlg-resize の absolute アンカー */
  width: 480px;
  max-width: 92vw;
  max-height: 84vh;
  display: flex;
  flex-direction: column;
  background: var(--panel-2);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-modal);   /* 暗幕を使わないぶん、影と枠で手前感を作る (10.1) */
  overflow: hidden;
}
.dlg-titlebar {
  display: flex;
  align-items: center;
  gap: var(--gap-inline);
  /* §24: MDI ウィンドウのタイトルバー (.mdi-titlebar) と同じ高さ・同じ内側余白にする。 */
  padding: 3px var(--pad-panel);
  min-height: 32px;
  background: var(--panel);
  color: var(--text);
  border-bottom: 1px solid var(--panel-border);
  font-weight: 600;
  flex: none;
  cursor: move;              /* タイトルバードラッグで移動可 */
  touch-action: none;        /* Pointer ドラッグ中のスクロール/ジェスチャを抑止 */
}
.dlg-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dlg-close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  cursor: var(--cur-pointer, pointer);
}
.dlg-close:hover { background: var(--surface-hover); color: var(--text); }
.dlg-close svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.dlg-body { padding: var(--pad-panel); overflow: auto; flex: 1 1 auto; min-height: 0; }  /* 長い内容は内部スクロール */
/* 右下リサイズハンドル (opts.resizable のダイアログのみ表示) */
.dlg-resize { display: none; }
#modal.resizable .dlg-resize {
  display: block;
  position: absolute;
  right: 0; bottom: 0;
  width: 16px; height: 16px;
  cursor: nwse-resize;
  touch-action: none;
  background:
    linear-gradient(135deg, transparent 50%, var(--border-strong) 50%, var(--border-strong) 62%, transparent 62%,
      transparent 74%, var(--border-strong) 74%, var(--border-strong) 86%, transparent 86%);
}
/* §24: フォームの縦積み。行間は --gap-stack (フィット窓の .fit-kv と同じ)。 */
.dlg-grid { display: flex; flex-direction: column; gap: var(--gap-stack); }
.dlg-grid label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--muted);
}
.dlg-result { margin-top: 12px; }
.dlg-error { color: var(--bad); margin-top: 8px; }

/* 詳細インポート ダイアログ */
.imp-wrap { display: flex; flex-direction: column; gap: 10px; min-width: 560px; }
.imp-opts { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: flex-end; }
.imp-destination { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 8px 10px; border: 1px solid var(--panel-border); border-radius: var(--radius-md); background: var(--panel-2); }
.imp-destination label { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; }
.imp-destination select { max-width: 190px; }
.imp-dest-title { flex: 0 0 100%; font-size: var(--fs-sm); font-weight: 700; color: var(--text); }
.imp-field { display: flex; flex-direction: column; gap: 3px; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.imp-field > span { white-space: nowrap; }
.imp-field input[type="checkbox"] { align-self: flex-start; width: 16px; height: 16px; margin: 3px 0; }
.imp-preview-wrap { max-height: 46vh; overflow: auto; border: 1px solid var(--panel-border); border-radius: var(--radius-md); }
.imp-table { border-collapse: collapse; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; white-space: nowrap; }
.imp-table th, .imp-table td { border: 1px solid var(--panel-border); padding: 2px 8px; text-align: left; }
.imp-table thead th { position: sticky; top: 0; background: var(--panel-2); z-index: 1; }
.imp-table .imp-corner { color: var(--muted); font-weight: 600; text-align: right; background: var(--surface-hover); position: sticky; left: 0; z-index: 2; }
.imp-colsel { font-size: var(--fs-sm); padding: 1px 2px; min-width: 78px; }
.imp-name { font-weight: 700; color: var(--text); }
.imp-rownum { color: var(--muted); text-align: right; background: var(--surface-hover); position: sticky; left: 0; }
.imp-rowhdr td:not(.imp-rownum) { background: var(--sel-bg); color: var(--accent); font-weight: 700; }
.imp-rowunits td:not(.imp-rownum) { background: var(--surface-hover); font-style: italic; }
.imp-rowskip td:not(.imp-rownum) { color: var(--muted); opacity: 0.55; }
.imp-skip { opacity: 0.4; }

/* バッチインポート キューパネル */
.imp-queue { border: 1px solid var(--panel-border); border-radius: var(--radius-md); background: var(--panel); }
.imp-queue-progress { padding: 6px 10px; font-size: var(--fs-sm); font-weight: 700; color: var(--muted); border-bottom: 1px solid var(--panel-border); }
.imp-queue-list { list-style: none; margin: 0; padding: 0; max-height: 22vh; overflow: auto; }
.imp-q-item { display: flex; align-items: baseline; gap: 8px; padding: 4px 10px; font-size: var(--fs-sm); border-bottom: 1px solid var(--panel-border); }
.imp-q-item:last-child { border-bottom: none; }
.imp-q-item.imp-q-current { background: var(--sel-bg); }
.imp-q-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.imp-q-status { flex: 0 0 auto; font-weight: 700; color: var(--muted); }
.imp-q-item.imp-q-active .imp-q-status { color: var(--accent); }
.imp-q-item.imp-q-done .imp-q-status { color: var(--good); }
.imp-q-item.imp-q-failed .imp-q-status { color: var(--bad); }
.imp-q-item.imp-q-cancelled .imp-q-status, .imp-q-item.imp-q-skipped .imp-q-status { color: var(--text-disabled); }
.imp-q-reason { flex-basis: 100%; color: var(--bad); font-size: var(--fs-sm); opacity: 0.85; }
.imp-summary-text { margin: 0 0 8px; font-weight: 700; }
@media (max-width: 680px) {
  .imp-wrap { min-width: 0; }
  .imp-destination { align-items: stretch; }
  .imp-destination label { flex: 1 1 100%; }
  .imp-destination select { flex: 1 1 auto; max-width: none; min-width: 0; }
}
/* 確認ダイアログで「何を消すのか」を名前で並べる短いリスト。 */
.dlg-list { margin: var(--gap-stack) 0; padding-left: 1.4em; max-height: 30vh; overflow: auto; }
.dlg-list li { font-size: var(--fs-base); color: var(--text); line-height: 1.5; }

.dlg-hint { color: var(--muted); font-size: var(--fs-sm); font-weight: 400; margin: 4px 0 0; }
.dlg-row { display: flex; gap: 10px; }
.dlg-row > label { flex: 1; }
.dlg-row > label input { width: 100%; min-width: 0; }

#dlg-init-params {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 8px;
}
#dlg-init-params:empty { display: none; }
#dlg-init-params input { width: 100%; min-width: 0; }
.dlg-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }

#modal.wide { width: 720px; }

/* ============ 解析共通ダイアログ (P06) ============ */
.an-dialog { display: flex; gap: 16px; min-height: 380px; }
.an-form { flex: 1 1 300px; min-width: 260px; display: flex; flex-direction: column; gap: 12px; }
.an-sec { display: flex; flex-direction: column; gap: 8px; }
.an-params { border-top: 1px solid var(--panel-border); padding-top: 10px; }
.an-row { display: flex; gap: 10px; flex-wrap: wrap; }
.an-row > label, .an-field { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); flex: 1; min-width: 0; }
.an-row select, .an-field select, .an-field input[type="number"] { width: 100%; min-width: 0; }
.an-field.check-label { flex-direction: row; align-items: center; gap: 6px; }
.an-yrow { flex-direction: column; }
.an-ylab { font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.an-ychecks { display: flex; flex-direction: column; gap: 3px; max-height: 140px; overflow-y: auto; border: 1px solid var(--panel-border); border-radius: var(--radius-sm); padding: 6px; }
.an-unit { font-weight: 400; color: var(--muted); margin-left: 4px; }
.an-preview { flex: 0 0 360px; display: flex; flex-direction: column; gap: 6px; }
.an-pv-title { font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.an-preview canvas { width: 360px; max-width: 100%; height: auto; border: 1px solid var(--panel-border); border-radius: var(--radius-sm); background: var(--panel); }
.an-legend { display: flex; flex-wrap: wrap; gap: 10px; font-size: var(--fs-sm); color: var(--text); }
.an-leg-item { display: inline-flex; align-items: center; gap: 4px; }
.an-leg-sw { width: 14px; height: 3px; border-radius: 2px; display: inline-block; }
/* 段見出し (Fitting の .fit-sec-title と同ボイス) */
.an-sec-title { font-size: var(--fs-base); font-weight: 700; text-transform: none; letter-spacing: var(--tracking-tight); color: var(--text); margin-bottom: 2px; }
.an-params { display: flex; flex-direction: column; gap: 8px; }
.an-flab { display: inline-flex; align-items: center; gap: 2px; }
.an-stepper { width: 96px; }
/* 情報/警告バナー (要件28: 高次微分の注意など。常時表示可の重要警告) */
.an-note { font-size: var(--fs-sm); font-weight: 400; line-height: var(--lh-normal); color: var(--muted); background: var(--panel-2); border: 1px solid var(--panel-border); border-radius: var(--radius-md); padding: 6px 9px; }
.an-note.warn { color: var(--text); background: color-mix(in srgb, var(--warn) 12%, var(--panel-2)); border-color: color-mix(in srgb, var(--warn) 40%, var(--panel-border)); }
/* Analysisの複数列ピッカー: 縦並び + スクロール */
.mv-col-list { display: flex; flex-direction: column; gap: 3px; max-height: 200px; overflow-y: auto; }

/* ============ Analysis chrome (FitPanel visual language) ============
   All analysis operations share the same information hierarchy as Fitting:
   panel surface, hairline section dividers, compact controls, and a quiet
   preview surface.  The body is opt-in via openAnalysisModal so unrelated
   utility dialogs keep their existing layout. */
#modal.analysis-modal {
  width: 920px;
  max-width: min(94vw, 980px);
  height: min(570px, 84vh);
  min-height: 440px;
  background: var(--panel);
  border-color: var(--border-strong);
}
#modal.analysis-modal .dlg-titlebar {
  min-height: 32px;
  padding: 3px 10px;
  background: var(--panel);
  border-bottom-color: var(--panel-border);
}
#modal.analysis-modal .dlg-title {
  font-size: var(--fs-base);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
}
#modal.analysis-modal .dlg-body.analysis-modal-body {
  padding: 0;
  overflow: auto;
  min-height: 0;
  background: var(--panel);
}
#modal.analysis-modal .dlg-buttons {
  min-height: 42px;
  padding: 8px 12px;
  background: var(--panel);
  border-top-color: var(--panel-border);
}
#modal.analysis-modal .dlg-buttons .btn.primary { min-width: 84px; }

/* Two-column signal-operation shell: form on the right of the graph, like
   FitPanel's preview/body split, without adding another window chrome. */
#modal.analysis-modal .an-dialog {
  display: grid;
  grid-template-columns: minmax(300px, 1.08fr) minmax(300px, .92fr);
  gap: 0;
  height: 100%;
  min-height: 0;
  background: var(--panel);
}
#modal.analysis-modal .an-preview { order: 0; }
#modal.analysis-modal .an-form { order: 1; min-height: 0; overflow-y: auto; }
#modal.analysis-modal .an-form {
  min-width: 0;
  padding: 0 14px 14px;
  gap: 0;
  background: var(--panel);
}
#modal.analysis-modal .an-sec {
  gap: var(--gap-stack);
  padding: 10px 0;
  border-top: 1px solid var(--panel-border);
}
#modal.analysis-modal .an-sec:first-child { border-top: none; }
#modal.analysis-modal .an-sec-title {
  display: flex;
  align-items: center;
  min-height: var(--control-h);
  margin: 0;
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--text);
  letter-spacing: var(--tracking-tight);
}
#modal.analysis-modal .an-row {
  display: grid;
  gap: var(--gap-stack);
  min-width: 0;
}
#modal.analysis-modal .an-row.an-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
#modal.analysis-modal .an-row.an-single { grid-template-columns: minmax(0, 1fr); }
#modal.analysis-modal .an-row > label,
#modal.analysis-modal .an-field {
  min-width: 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 600;
}
#modal.analysis-modal .an-row.an-single > label,
#modal.analysis-modal .an-field:not(.check-label) {
  display: grid;
  grid-template-columns: minmax(84px, 96px) minmax(0, 1fr);
  align-items: center;
  gap: var(--gap-inline);
}
#modal.analysis-modal .an-pick-row { display: flex; align-items: center; gap: 8px; margin-top: 6px; color: var(--muted); font-size: var(--fs-xs); line-height: var(--lh-normal); }
#modal.analysis-modal .an-pick-row .btn { min-height: var(--control-h-sm); padding: 2px 8px; font-size: var(--fs-xs); }
#modal.analysis-modal .an-row.an-pair > label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
#modal.analysis-modal .an-yrow {
  grid-template-columns: minmax(84px, 96px) minmax(0, 1fr);
  align-items: start;
}
#modal.analysis-modal .an-yrow .an-ylab { padding-top: 5px; }
#modal.analysis-modal .an-row select,
#modal.analysis-modal .an-field select,
#modal.analysis-modal .an-field input[type="number"] { width: 100%; min-width: 0; }
#modal.analysis-modal .an-field.check-label {
  display: flex;
  align-items: center;
  gap: var(--gap-inline);
  min-height: var(--control-h);
  color: var(--text);
  font-weight: 500;
}
#modal.analysis-modal .an-field-error { display: block; color: var(--bad); font-size: var(--fs-xs); line-height: var(--lh-tight); }
#modal.analysis-modal .an-field-error[hidden] { display: none; }
#modal.analysis-modal .an-params {
  display: flex;
  flex-direction: column;
  gap: var(--gap-stack);
  padding-top: 10px;
}
#modal.analysis-modal .an-ychecks {
  max-height: 160px;
  padding: var(--space-1) var(--gap-inline);
  border-color: var(--field-border);
  border-radius: var(--radius-ctl);
  background: var(--panel-2);
}
#modal.analysis-modal .an-ychecks .check-label {
  min-height: var(--control-h-sm);
  padding: 2px 4px;
  border-radius: var(--radius-sm);
}
#modal.analysis-modal .an-ychecks .check-label:hover { background: var(--surface-hover); }
#modal.analysis-modal .an-preview {
  min-width: 0;
  padding: 10px 14px 14px;
  gap: var(--gap-stack);
  border-right: 1px solid var(--panel-border);
  background: var(--panel-2);
}
#modal.analysis-modal .an-preview-canvas-wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 220px;
  display: flex;
  align-items: stretch;
}
#modal.analysis-modal .an-preview-status {
  margin-left: auto;
  padding: 2px 7px;
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
}
#modal.analysis-modal .an-preview-status.is-ready { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--panel-border)); }
#modal.analysis-modal .an-preview-status.is-error { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, var(--panel-border)); }
#modal.analysis-modal .an-preview-head {
  display: flex;
  align-items: center;
  min-height: var(--control-h);
}
#modal.analysis-modal .an-pv-title {
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--text);
  letter-spacing: var(--tracking-tight);
}
#modal.analysis-modal .an-preview canvas {
  display: block;
  width: 100%;
  height: auto;
  min-height: 220px;
  height: 100%;
  border: 0;
  border-radius: var(--radius-ctl);
  background: var(--panel-2);
}
#modal.analysis-modal .an-summary {
  display: flex;
  gap: var(--gap-inline);
  align-items: baseline;
  min-height: var(--control-h-sm);
  padding: 5px 0 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
}
#modal.analysis-modal .an-summary-label {
  flex: none;
  color: var(--text);
  font-weight: 700;
}
#modal.analysis-modal .an-run-hint { color: var(--muted); font-size: var(--fs-sm); line-height: var(--lh-normal); }
#modal.analysis-modal .an-run-status {
  min-height: var(--control-h-sm);
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
}
#modal.analysis-modal .an-run-status.is-success { color: var(--good); font-weight: 600; }
#modal.analysis-modal .an-run-status.is-error { color: var(--bad); font-weight: 600; }
#modal.analysis-modal .an-run-status.is-pending { color: var(--muted); }
#modal.analysis-modal .an-output { gap: var(--space-1); margin-top: auto; }
#modal.analysis-modal .an-output-info { color: var(--muted); font-size: var(--fs-xs); line-height: var(--lh-normal); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#modal.analysis-modal .an-go-output { align-self: flex-start; min-height: var(--control-h-sm); padding: 2px 9px; font-size: var(--fs-xs); }
#modal.analysis-modal .an-stats-preview {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gap-stack);
  overflow: auto;
}
#modal.analysis-modal .an-preview-meta { color: var(--muted); font-size: var(--fs-sm); }
#modal.analysis-modal .an-stats-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-1);
}
#modal.analysis-modal .an-kpi {
  min-width: 0;
  padding: 7px 8px 6px;
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-ctl);
  background: var(--panel);
}
#modal.analysis-modal .an-kpi span,
#modal.analysis-modal .an-kpi strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#modal.analysis-modal .an-kpi span { color: var(--muted); font-size: var(--fs-xs); line-height: var(--lh-tight); }
#modal.analysis-modal .an-kpi strong { margin-top: 2px; color: var(--text); font-size: var(--fs-base); line-height: var(--lh-tight); font-variant-numeric: tabular-nums; }
#modal.analysis-modal .an-table-wrap { min-width: 0; overflow: auto; border: 1px solid var(--panel-border); border-radius: var(--radius-ctl); background: var(--panel); }
#modal.analysis-modal .an-preview-table { width: 100%; min-width: 0; table-layout: fixed; margin: 0; }
#modal.analysis-modal .an-preview-table th, #modal.analysis-modal .an-preview-table td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 5px 6px; }
#modal.analysis-modal .an-preview-table th:first-child, #modal.analysis-modal .an-preview-table td:first-child { width: 32%; }
#modal.analysis-modal .an-preview-more { color: var(--muted); font-size: var(--fs-xs); }
#modal.analysis-modal .an-empty-state { display: grid; place-items: center; min-height: 180px; color: var(--muted); border: 1px dashed var(--panel-border); border-radius: var(--radius-ctl); font-size: var(--fs-sm); }
#modal.analysis-modal .an-stats-empty { flex: 1 1 auto; align-content: center; justify-items: center; gap: var(--space-1); padding: var(--space-4); text-align: center; }
#modal.analysis-modal .an-stats-empty strong { color: var(--text); font-size: var(--fs-base); }
#modal.analysis-modal .an-stats-empty span { max-width: 34em; line-height: var(--lh-normal); }
#modal.analysis-modal .an-stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 8px; }
#modal.analysis-modal .an-picker-actions { display: flex; gap: 6px; margin: 0 0 6px; }
#modal.analysis-modal .an-picker-actions .btn { min-height: var(--control-h-sm); padding: 2px 8px; font-size: var(--fs-xs); }
#modal.analysis-modal .an-legend {
  padding-top: var(--space-2);
  border-top: 1px solid var(--panel-border);
  gap: var(--gap-inline);
  color: var(--muted);
  font-size: var(--fs-sm);
}
#modal.analysis-modal .an-leg-muted { opacity: .7; font-style: italic; }
@media (max-width: 720px) {
  #modal.analysis-modal .an-stats-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Non-preview analysis dialogs (stats and signal processing) use the same
   form rhythm and section treatment as FitPanel's right-hand body. */
#modal.analysis-modal .analysis-modal-body > .dlg-grid {
  max-width: 720px;
  padding: 12px 14px 14px;
  gap: var(--gap-section);
}
#modal.analysis-modal .analysis-modal-body > .dlg-grid > label,
#modal.analysis-modal .analysis-modal-body .dlg-row > label {
  display: grid;
  grid-template-columns: minmax(112px, 130px) minmax(0, 1fr);
  align-items: center;
  gap: var(--gap-inline);
  min-height: var(--control-h);
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 600;
}
#modal.analysis-modal .analysis-modal-body .dlg-row {
  display: flex;
  gap: var(--gap-inline);
  flex-wrap: wrap;
}
#modal.analysis-modal .analysis-modal-body .dlg-row > label { flex: 1 1 220px; }
#modal.analysis-modal .analysis-modal-body fieldset {
  margin: 0;
  padding: 10px 0 0;
  border: 0;
  border-top: 1px solid var(--panel-border);
  border-radius: 0;
  gap: var(--gap-stack);
}
#modal.analysis-modal .analysis-modal-body fieldset:first-child {
  padding-top: 2px;
  border-top: 0;
}
#modal.analysis-modal .analysis-modal-body legend {
  padding: 0;
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--text);
  letter-spacing: var(--tracking-tight);
}
#modal.analysis-modal .analysis-modal-body .check-label {
  color: var(--text);
  font-weight: 500;
}
#modal.analysis-modal .analysis-modal-body .mv-col-list {
  max-height: 180px;
  padding: var(--space-1) var(--gap-inline);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-ctl);
  background: var(--panel-2);
}
#modal.analysis-modal .analysis-modal-body .dlg-hint {
  margin: 0;
  padding-left: 8px;
  border-left: 2px solid var(--panel-border);
  line-height: var(--lh-normal);
}
#modal.analysis-modal .analysis-modal-body .dlg-error {
  min-height: var(--control-h-sm);
  margin-top: 0;
  padding: 4px 8px;
  border-left: 2px solid transparent;
}
#modal.analysis-modal .analysis-modal-body .dlg-error:not(:empty) {
  border-left-color: var(--bad);
  background: color-mix(in srgb, var(--bad) 8%, transparent);
}

@media (max-width: 700px) {
  #modal.analysis-modal { width: 94vw; height: auto; min-height: 0; }
  #modal.analysis-modal .an-dialog { grid-template-columns: 1fr; }
  #modal.analysis-modal .an-preview {
    border-top: 1px solid var(--panel-border);
    border-right: 0;
  }
  #modal.analysis-modal .an-row.an-pair { grid-template-columns: 1fr; }
}

/* ============ 軸ダイアログ ============ */
.axis-dlg {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 12px;
  min-height: 340px;
}
.axis-side {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border-right: 1px solid var(--panel-border);
  padding-right: 10px;
}
.axis-side-item {
  padding: 8px 10px;
  border-radius: var(--radius-md);
  font-size: var(--fs-base);
  font-weight: 500;
  text-align: center;
  cursor: var(--cur-pointer, pointer);
  border: 1px solid var(--panel-border);
  background: var(--panel);
  user-select: none;
}
.axis-side-item:hover { background: var(--sel-bg); }
.axis-side-item.active { background: var(--surface-active); border-color: var(--border-strong); color: var(--text); font-weight: 600; }

.axis-main { min-width: 0; display: flex; flex-direction: column; }
.dlg-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  border-bottom: 1px solid var(--panel-border);
  margin-bottom: 12px;
  user-select: none;
}
.dlg-tab {
  padding: 5px 10px;
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--muted);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  cursor: var(--cur-pointer, pointer);
  border: 1px solid transparent;
  border-bottom: none;
}
.dlg-tab:hover { background: var(--sel-bg); }
.dlg-tab.active {
  font-weight: 600;
  color: var(--accent);
  background: var(--panel-2);
  border-color: var(--panel-border);
  margin-bottom: -1px;
  padding-bottom: 6px;
}
.axis-tab-body { flex: 1; overflow-y: auto; max-height: 56vh; }

.dlg-subtabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--panel-border);
  margin: 2px 0 8px;
  user-select: none;
}
.dlg-subtab {
  padding: 3px 9px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--muted);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  cursor: var(--cur-pointer, pointer);
}
.dlg-subtab:hover { background: var(--sel-bg); }
.dlg-subtab.active { font-weight: 600; color: var(--accent); background: var(--sel-bg); }

.ref-details { background: var(--panel); }
.br-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.br-chip {
  padding: 3px 12px;
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-ctl);
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--muted);
  cursor: var(--cur-pointer, pointer);
  user-select: none;
}
.br-chip:hover { background: var(--sel-bg); }
.br-chip.active { background: var(--surface-active); border-color: var(--border-strong); color: var(--text); font-weight: 600; }
tr.sel-row td { background: var(--sel-bg); }
.rl-name { font-weight: 600; white-space: nowrap; cursor: var(--cur-pointer, pointer); }
.axis-table-wrap { overflow-x: auto; }
.ref-table input[type="color"] { width: 30px; height: 22px; }
.ref-table select { padding: 3px 4px; font-size: var(--fs-base); }
.ref-table th { white-space: nowrap; }

fieldset {
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  margin: 0 0 4px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.dlg-grid fieldset { margin-top: 2px; }
legend {
  font-size: var(--fs-base);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  color: var(--text);
  padding: 0 5px;
}
fieldset label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--muted);
}
.check-label {
  flex-direction: row !important;
  align-items: center;
  gap: 6px !important;
  font-weight: 600;
  cursor: var(--cur-pointer, pointer);
}

input[type="text"], input[type="number"], textarea {
  background: var(--panel-2);
  color: var(--text);
  /* D-111: 枠線は 3 段階 — 安静 --field-border (3.2:1) → hover --control-border → focus --accent。
     契約 (R9-H3: 操作できる輪郭は 3:1 以上) は安静時でも守る。全部を常時 4.5:1 にすると
     入力が 10 個並ぶパネルで 10 個の濃い矩形が等しく主張する (階調の無さが安っぽさの源)。 */
  border: 1px solid var(--field-border);
  border-radius: var(--radius-ctl);   /* D-02: コントロールは 3px */
  padding: 0 8px;
  font-size: var(--fs-base);   /* body / input value = 12px。UI テキストと統一(以前は 13px で大きすぎた) */
  font-weight: 400;
  font-family: inherit;        /* IBM Plex Sans (--font-ui) を継承 */
  line-height: 1.4;
  outline: none;
}
/* D-01: 1行コントロールは高さトークンに揃える (textarea は複数行なので対象外)。 */
input[type="text"], input[type="number"] { height: var(--control-h); }
textarea { padding: 4px 8px; }
/* D-111: hover = 1 段濃く (これから触る予告)。focus 中は下の accent 規則が勝つよう :not で除外。 */
input[type="text"]:hover:not(:focus-visible), input[type="number"]:hover:not(:focus-visible),
textarea:hover:not(:focus-visible), select:hover:not(:focus-visible) {
  border-color: var(--control-border);
}
/* U.2: 入力欄のフォーカスは「枠色が accent に変わる + 背景がわずかに明るくなる」のみ。
   リング(box-shadow)は 1 本でも枠と同心の 2 重角丸に見える(要件3 の実測)ため一切使わない。 */
input[type="text"]:focus-visible, input[type="number"]:focus-visible, textarea:focus-visible {
  border-color: var(--accent);
  background: var(--panel);
  box-shadow: none;
  outline: none;
}
/* ============ 数値の組版 (D-110 / 2026-08-05) ============
   計測器らしさは装飾ではなく**数字の組版**に宿る。桁が縦に揃い、値が変わっても
   数字が横に踊らない画面は、それだけで精密機器として読める。契約は 2 つ:
     ・数値は等幅数字 (tabular-nums) で組む
     ・数値**入力**は右揃え (桁位置が固定され、小数点が縦に並ぶ)
   旧実装は `.num-field` を付けた入力にだけ明示適用する方式で、
   `.num-field` を持たない `input[type="number"]` が analysis / formula / macro /
   nodegraph / multilayer の各ダイアログに散在し、同じ「数値入力」が
   画面によって別の組版で出ていた。**型そのものが数値だと言っている**要素に
   役割を宣言させるのが単一の出所として正しい。
   注意: `type="text"` の数値入力は自動判定できないので `.num-field` を明示する
   (この規則が両方を拾う)。 */
input[type="number"], .num-field {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* 結果表は「読む数値」の面。RTable が付ける .rtable は汎用なので、
   .log-table を経由しない結果表 (統計・フィット結果) でも桁が揃うようにする。 */
.rtable { font-variant-numeric: tabular-nums; }
textarea { resize: vertical; font-family: var(--font-mono); }
input[type="color"] {
  width: 40px;
  height: var(--control-h);
  padding: 1px;
  /* D-111: これも操作できるコントロール。1.3:1 の装飾枠 (--panel-border) は
     「操作の輪郭」の契約 (3:1) を満たさないので入力と同じ安静段に揃える。 */
  border: 1px solid var(--field-border);
  border-radius: var(--radius-ctl);
  background: var(--panel-2);
  cursor: var(--cur-pointer, pointer);
}
input[type="checkbox"] { accent-color: var(--accent); }

.series-table { border-collapse: collapse; width: 100%; }
.series-table th {
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
  text-transform: none;
  letter-spacing: var(--tracking-tight);
  text-align: left;
  padding: 2px 8px 4px 0;
}
.series-table td { padding: 3px 8px 3px 0; vertical-align: middle; }
.series-table .ser-name {
  font-weight: 600;
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dlg-buttons {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 10px 14px;
  border-top: 1px solid var(--panel-border);
  flex: none;
}

select {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--field-border);   /* D-111: 安静は入力と同じ段 (hover/focus で上がる) */
  border-radius: var(--radius-ctl);   /* D-02 */
  height: var(--control-h);           /* D-01 */
  /* D-50: 右は矢印ぶんを必ず空ける。旧実装は左右とも 6px だったため、選択値が長いと
     ネイティブの ▼ の下に文字が潜り込んで読めなかった。溢れは省略記号で示す
     (全文は各所が title 属性で持つ)。 */
  padding: 0 var(--select-arrow-w) 0 var(--pad-ctl-x);
  font-size: var(--fs-base);   /* input と同一。UI テキストと統一 */
  font-weight: 400;
  font-family: inherit;        /* ブラウザ既定でなく IBM Plex Sans (--font-ui) に統一 */
  line-height: 1.4;
  outline: none;
  text-overflow: ellipsis;
}
/* select も input と同じ単層ハロー(2 層 --focus-ring は二重枠に見えるため使わない) */
select:focus-visible { border-color: var(--accent); background: var(--panel); box-shadow: none; outline: none; }

/* ============ ドロップオーバーレイ ============
   暗幕は使わない (計画 10.1)。作業スペースの縁をアクセントの破線枠で囲い、上端にバナーを出す。
   pointer-events:none なので、下のワークスペースの内容は最後まで見えたまま。 */
#drop-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-toast);
  background: transparent;
  pointer-events: none;
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
/* ワークスペースの縁を示すアクセント枠 (内側に描くので枠がはみ出さない) */
#drop-overlay::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: 2px dashed var(--accent);
  border-radius: var(--radius-lg);
}
.drop-box {
  margin-top: 14px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  padding: 10px 22px;
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--accent);
  background: var(--panel-2);
  box-shadow: var(--shadow-modal);
}

/* ============ ライブラリビュー (計画 D-20/D-22) ============
   数式ライブラリ (formulalib.js) とテンプレートライブラリ (templates.js) が共有するリスト表示。
   1 行 = [サムネイル?] [名前 + 補足] [操作ボタン群]。 */
/* ライブラリ行は [サムネ] [名前+式+メタ] [操作 4 つ] を横に並べるため、既定の 480px モーダルでは
   メタ行が省略されてしまう。ライブラリを含むモーダルだけ広げる (max-width は #modal 側の 92vw)。 */
#modal:has(.lib) { width: 680px; }
.lib { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.lib-toolbar { display: flex; align-items: center; gap: var(--space-2); }
.lib-toolbar > input[type="text"] { flex: 1; min-width: 0; }
.lib-list { display: flex; flex-direction: column; gap: var(--space-1); max-height: 46vh; overflow-y: auto; }
.lib-sechd { margin-top: var(--space-2); }
.lib-empty { margin: var(--space-2) 0; }
/* D-111: リスト行は「枠 + 塗り + hover 塗り」の三重表現だった。行はリストという文脈が
   境界を与えるので、枠を捨てて塗りと余白に任せる (Explorer 行 / .pp-dsrow と同じ語彙)。
   透明 1px はレイアウトを動かさないための座布団。 */
.lib-row { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2);
  border: 1px solid transparent; border-radius: var(--radius-ctl); background: var(--panel-2); min-width: 0; }
.lib-row:hover { background: var(--surface-hover); }
.lib-row-slim { padding: 2px var(--space-2); }
.lib-thumb { flex: none; width: 96px; height: 64px; object-fit: contain;
  background: var(--panel); border: 1px solid var(--panel-border); border-radius: var(--radius-ctl); }
.lib-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.lib-name { font-size: var(--fs-base); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lib-sub { font-size: var(--fs-sm); color: var(--text); font-family: var(--font-mono);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lib-meta { font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lib-acts { flex: none; display: flex; align-items: center; gap: var(--space-1); }
/* T5.2: 数式の説明 + インライン編集フォーム (新規作成せず既存を更新する導線)。 */
.lib-desc { font-size: var(--fs-sm); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* テンプレート一覧の種別テキスト (未記録の旧テンプレは muted で淡く出す)。 */
.lib-type { font-weight: 600; color: var(--text); }
.lib-type.muted { font-weight: 400; color: var(--muted); }

/* T5.4: プロパティパネル内の注記 (軸ダイアログから移した優先順位の説明など)。 */
.pp-hint { font-size: var(--fs-sm); color: var(--muted); margin: 0 0 var(--space-1) 0;
  padding-left: 72px; line-height: 1.4; }
.lib-edit { display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-2); border: 1px solid var(--accent); border-radius: var(--radius-md);
  background: var(--panel-2); }
.lib-edit .lib-acts { justify-content: flex-end; margin-top: var(--space-1); }
.lib-f { display: flex; align-items: center; gap: var(--space-2); }
.lib-f > span { flex: 0 0 84px; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); text-align: right; }
.lib-f > input { flex: 1; min-width: 0; height: var(--control-h); padding: 0 6px;
  border: 1px solid var(--panel-border); border-radius: var(--radius-ctl);
  background: var(--panel); color: var(--text); font-size: var(--fs-base); }
.lib-f > input:focus { outline: none; border-color: var(--accent); }
.lib-f-narrow { max-width: 96px; flex: 0 0 96px; }
.lib-edit-status { font-size: var(--fs-xs); min-height: 14px; padding-left: 92px; }
.lib-edit-status.ok { color: var(--muted); }
.lib-edit-status.err { color: var(--bad); }

/* ============ スクロールバー ============ */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--panel-border); border-radius: var(--radius-md); border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--muted); border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* スクリプトコンソール (Phase E.2) */
.console-wrap { display: flex; flex-direction: column; height: 100%; }
.con-out { flex: 1; overflow-y: auto; font-family: var(--font-mono); font-size: var(--fs-base); padding: 8px; background: var(--panel-2); }
.con-line { white-space: pre-wrap; word-break: break-word; padding: 1px 0; }
.con-in { color: var(--accent); }
.con-res { color: var(--text); }
.con-err { color: var(--bad); }
.con-hint, .con-line.con-hint { color: var(--muted); font-style: italic; }
.con-input-row { display: flex; gap: 6px; padding: 6px; border-top: 1px solid var(--panel-border); }
.con-input { flex: 1; min-height: 46px; resize: vertical; font-family: var(--font-mono); font-size: var(--fs-base); padding: 6px; }
.con-run { align-self: stretch; padding: 0 14px; }

/* ============ P.1: コンテキスト型プロパティパネル (器・画面右側の縦長ドック) ============ */
/* 収納時は 32px の縦見出しレール (ヘッダのみ・クリックで展開)。展開時は --pp-w 幅を占有。
   幅はグリッド列 (#layout の3列目) が制御するので、ホスト自身は列を満たすだけ。 */
.pp-host {
  display: flex; flex-direction: column; min-width: 0;
  background: var(--panel); border-left: 1px solid var(--panel-border); overflow: hidden;
}
body.col-resizing { cursor: col-resize; user-select: none; }
body.col-resizing * { cursor: col-resize !important; }

/* 作業スペース / パネル境界の幅リサイズハンドル (#sidebar-split と同じ「境界に重ねた縦ハンドル」方式)。
   right をパネル幅に合わせるので幅変更に追従する。当たり判定 6px・見た目は中央 2px。展開時のみ表示。 */
#pp-split {
  position: absolute; top: 0; bottom: 0;
  right: var(--pp-w-eff, var(--pp-w, 320px));
  width: 6px;
  transform: translateX(3px);   /* 境界線(border-left)の中心に重ねる */
  cursor: col-resize;
  z-index: 6;
  background: transparent;
}
#pp-split:hover { background: color-mix(in srgb, var(--accent) 40%, transparent); }
#pp-split:focus-visible { outline: none; background: var(--accent); }
#layout:not(.pp-open) #pp-split { display: none; }

.pp-frame  { display: flex; flex-direction: column; height: 100%; min-height: 0; min-width: 0; }
/* ヘッダ全体がクリックで開閉トグル */
.pp-header {
  display: flex; align-items: center; gap: 6px; padding: 7px 10px; flex: none;
  background: var(--panel); border-bottom: 1px solid transparent;
  font-weight: 600; user-select: none; cursor: var(--cur-pointer, pointer);
}
#layout.pp-open .pp-header { border-bottom-color: var(--panel-border); }
.pp-header:hover .pp-collapse { color: var(--accent); }
.pp-title  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-spacer { flex: 1; }

/* ---- 編集対象のパンくず (D-66) ----
   `Graph3 › Layer1 › Data Plot2`。段は本文サイズ、区切りは無彩色の小さい ›、
   **最後の段だけ**を主色 + 600 にして「いま設定しているのはこれ」を立てる。
   1 行に収め、溢れは先頭から省略する (末尾 = 当のものが常に見えるように)。 */
.pp-crumb {
  flex: none;
  display: flex; align-items: center; gap: 4px;
  padding: 4px var(--pad-panel) 6px;
  background: var(--panel);
  border-bottom: 1px solid var(--panel-border);
  font-size: var(--fs-sm);
  white-space: nowrap;
  overflow: hidden;
}
/* 溢れたときに切るのは**先頭の段**。末尾 (= いま設定している当のもの) は必ず読めるようにする。
   先頭側だけを縮められるようにし、末尾と区切りは flex:none で固定する。 */
.pp-crumb-part {
  color: var(--muted); min-width: 0; overflow: hidden; text-overflow: ellipsis;
  font: inherit; background: none; border: none; padding: 0; text-align: left;
}
.pp-crumb-part.cur { color: var(--text); font-weight: 600; flex: none; }
/* 段が階層への移動ボタンになっているとき (グラフ)。押せることを下線ではなく
   ホバーの面で示す (一辺の線はアプリ全体で禁止)。 */
.pp-crumb-part.nav { cursor: var(--cur-pointer, pointer); border-radius: var(--radius-ctl); padding: 0 3px; }
.pp-crumb-part.nav:hover { background: var(--surface-hover); color: var(--text); }
.pp-crumb-part.nav:focus-visible { box-shadow: var(--focus-ring); outline: none; }
/* いま編集しているレベル = 面 + 主色 (レールのレベル強調と対応させる) */
.pp-crumb-part.nav.at { background: var(--surface-active); color: var(--text); font-weight: 600; }
.pp-crumb-sep { color: var(--muted); flex: none; }
/* D-111: インスタンス切替メニューを持つ段のキャレット。段の文字より一段弱く。 */
.pp-crumb-part .pp-crumb-caret { margin-left: 3px; font-size: 9px; color: var(--muted); }
.pp-crumb-part.has-menu:hover .pp-crumb-caret { color: var(--text); }
#layout:not(.pp-open) .pp-crumb { display: none; }
/* 収納時 (32px レール): ヘッダを縦向きに。タイトルを縦書き、本体は隠す (クリックで展開)。 */
#layout:not(.pp-open) .pp-host { cursor: var(--cur-pointer, pointer); }
/* 収納レール全体にホバー強調 (開閉が直感的に伝わるように) */
#layout:not(.pp-open) .pp-host:hover .pp-header { background: var(--surface-hover); }
#layout:not(.pp-open) .pp-host:hover .pp-collapse { color: var(--accent); }
#layout:not(.pp-open) .pp-header { flex-direction: column; padding: 10px 4px; gap: 10px; height: 100%; justify-content: flex-start; }
#layout:not(.pp-open) .pp-title { writing-mode: vertical-rl; text-orientation: mixed; letter-spacing: var(--tracking-tight); color: var(--muted); }
#layout:not(.pp-open) .pp-spacer { display: none; }
#layout:not(.pp-open) .pp-main { display: none; }
.pp-collapse {
  border: none; background: transparent; color: var(--muted);
  padding: 2px 4px; border-radius: var(--radius-sm); cursor: var(--cur-pointer, pointer); line-height: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.pp-collapse:hover { background: var(--surface-hover); color: var(--accent); }
.pp-collapse svg {
  width: 14px; height: 14px; display: block; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  transition: transform var(--dur-med) var(--ease-out);
}
/* 開: › (右向き=収納方向) / 収納時: 180°回転で ‹ (左向き=クリックで展開) */
#layout:not(.pp-open) .pp-collapse svg { transform: rotate(180deg); }
.pp-empty  { color: var(--muted); padding: 16px; font-size: var(--fs-base); }
/* T2.5: Explorer 選択 (プロジェクト/フォルダ/ブック/グラフ) のプロパティ表示。 */
.pp-ro { color: var(--muted); font-size: var(--fs-base); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-actions { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px 8px 2px; }
/* T7.4: 解析列の入力列リンク (クリックでその列を選択)。 */
.pp-anlinks { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
.pp-anlink {
  border: 1px solid var(--panel-border); background: var(--panel); color: var(--accent);
  border-radius: var(--radius-ctl); font: inherit; font-size: var(--fs-sm);
  padding: 0 6px; cursor: var(--cur-pointer, pointer);
}
.pp-anlink:hover:not(:disabled) { background: var(--surface-hover); }
.pp-anlink.missing { color: var(--bad); cursor: default; }

/* 本体 = 左端の縦アイコンレール + スクロール本文 (Blender プロパティエディタ風) */
.pp-main   { flex: 1; min-height: 0; display: flex; }
/* 横スクロールバーは絶対に出さない (overflow-x:hidden)。値入力は min-width:0 でセル内に収める。 */
.pp-scroll { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 8px 10px; }
/* 縦アイコンレール: 横スクロールバーは絶対に出さない (overflow-x:hidden) + アイコンは中央寄せ */
/* ---- D-101: プロパティのナビゲーションは本文の先頭に 2 段で置く ----
   縦アイコンレール (56px・16px アイコン + 10px の 2 行ラベル) を置き換える。
   * 第 1 段 = レベル (ページ / レイヤー / データ)。**階層そのものを操作の軸**にする。
   * 第 2 段 = そのレベルの中身。文字が主で、アイコンは先頭に添える手掛かり。
   レールを畳んだぶん (56px = 320px ドックの 17%) は設定欄の幅へ回る。
   選択表現は面 + 太さ (+ アイコンの accent)。一辺のアクセント線は使わない。 */
.pp-nav { display: flex; flex-direction: column; gap: var(--gap-inline); padding: 0 0 var(--gap-stack); }
.pp-levelsel { width: 100%; }
.pp-levtabs { display: flex; flex-wrap: wrap; gap: 2px; }
.pp-levtab {
  display: inline-flex; align-items: center; gap: 4px;
  height: var(--control-h); padding: 0 var(--pad-ctl-x-sm);
  border: none; border-radius: var(--radius-ctl);
  background: transparent; color: var(--muted);
  /* 役割: タブ (--fs-base / 500、選択で 600) */
  font-size: var(--fs-base); font-weight: 500; line-height: 1;
  white-space: nowrap; cursor: var(--cur-pointer, pointer);
}
.pp-levtab:hover { background: var(--surface-hover); color: var(--text); }
.pp-levtab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pp-levtab.active { background: var(--surface-active); color: var(--text); font-weight: 600; }
.pp-levtab.active svg { color: var(--accent); }
.pp-levtab svg { flex: none;
  fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.pp-levtab-lbl { overflow: hidden; text-overflow: ellipsis; }

.pp-rail {
  flex: none; width: 38px; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 6px 4px; border-right: 1px solid var(--panel-border);
  overflow-y: auto; overflow-x: hidden;
}
.pp-rail::-webkit-scrollbar { width: 0; }
.pp-rail-btn {
  flex: none; width: 28px; height: 28px; display: grid; place-items: center;
  border: none; background: transparent; color: var(--muted); border-radius: var(--radius-md);
  cursor: var(--cur-pointer, pointer);
}
.pp-rail-btn:hover  { background: var(--surface-hover); color: var(--text); }
/* 選択は「面 + 文字を主色へ + weight」で示す。accent 面の上に accent 文字を載せると
   4.06:1 までしか出ず、9〜10px のラベルでは読みにくい (audit-a11y)。
   アイコン側だけを accent にして、操作信号としての意味は残す。 */
.pp-rail-btn.active { background: var(--surface-active); color: var(--text); font-weight: 600; }
.pp-rail-btn.active svg { color: var(--accent); }
.pp-rail-btn svg {
  width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}

/* T8.2: 48px レール = アイコン + ラベルの縦積み。
   初見でもタブの中身が予測できるようにラベルを常設し、窓が低いときはアイコンのみへ落とす。
   2026-07-26: ラベルを生 9px から段階スケールの --fs-xs(10px) へ寄せた
   (「style.css に font-size の生 px を書かない」規約と、9/10/11px が同じ階層に
    3 種類混在していた問題の解消)。 */
/* 48px だと英語の 1 語ラベル ("Reference") が語の途中で折れる。ラベルを常設する以上、
   語が読める幅を与えるのが筋なので 56px にする (パネル 320px に対し 8px の増分)。 */
.pp-rail.pp-rail-wide { width: 56px; gap: 1px; }
.pp-rail-wide .pp-rail-btn {
  width: 50px; height: auto; min-height: 38px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1px; padding: 4px 2px 3px;
  position: relative;   /* ツールチップの基準 */
}
/* ラベルは**2 行まで折り返す**。1 行 + 省略記号だと、英語の長いタブ名
   (Axis line / Reference line) が "Axis li…" "Refer…" となり、レールを常設している
   意味 (初見でタブの中身が予測できる) が失われる。3 行以上は clamp で切り、
   全文はホバーの説明 (Popover.attachTip) が持つ。 */
.pp-rail-lbl {
  font-size: var(--fs-xs); line-height: 1.15; text-align: center; letter-spacing: var(--tracking-tight);
  max-width: 100%;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; overflow-wrap: normal; word-break: normal; hyphens: auto;
}
.pp-rail-wide .pp-rail-btn svg { }
/* グループ区切り (fit-rail-div と同型) */
.pp-rail-div { flex: none; width: 24px; height: 1px; margin: 4px 0; background: var(--panel-border); }
/* ---- レベル見出し (D-69) ----
   ページ / レイヤー / データ の 3 階層をレール上で明示する。ヘアラインだけだと
   「何の区切りか」が読み取れず、階層が存在することに気づけない。
   全大文字は使わない (アプリ全体の規約)。上の罫線と余白で段を作る。 */
.pp-rail-level {
  flex: none; width: 100%; text-align: center;
  margin: 8px 0 2px; padding-top: 6px;
  border-top: 1px solid var(--panel-border);
  font-size: var(--fs-sm); font-weight: 700; color: var(--muted);
  letter-spacing: var(--tracking-tight); line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  cursor: default; user-select: none;
}
.pp-rail-level:first-child { margin-top: 0; padding-top: 0; border-top: none; }
/* 窓が低いとき (アイコンのみ表示) はレベル名も畳んでヘアラインだけにする */
@media (max-height: 620px) {
  .pp-rail-level { font-size: 0; padding-top: 5px; margin: 5px 0 0; }
}
/* 窓が低いときはラベルを畳んでアイコンだけにする (溢れたらレールを縦スクロール) */
@media (max-height: 620px) {
  .pp-rail.pp-rail-wide { width: 38px; }
  .pp-rail-wide .pp-rail-btn { width: 28px; min-height: 28px; padding: 2px; }
  .pp-rail-lbl { display: none; }
}

/* データセットリスト (データ タブ) */
.pp-dslist { display: flex; flex-direction: column; gap: 1px; }
.pp-dsrow {
  display: flex; align-items: center; gap: 8px; padding: 5px 6px; border-radius: var(--radius-md);
  cursor: var(--cur-pointer, pointer);
}
.pp-dsrow:hover { background: var(--surface-hover); }
.pp-dsrow.sel { background: var(--surface-active); }
.pp-ds-swatch { flex: none; width: 12px; height: 12px; border-radius: var(--radius-sm); border: 1px solid var(--panel-border); }
.pp-ds-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-base); }
.pp-dsrow.sel .pp-ds-name { font-weight: 600; }
.pp-ds-vis { flex: none; }
.pp-ds-del {
  flex: none; border: none; background: transparent; color: var(--muted);
  cursor: var(--cur-pointer, pointer); font-size: var(--fs-sm); line-height: 1; padding: 2px 4px; border-radius: var(--radius-sm);
}
.pp-ds-del:hover:not(:disabled) { color: var(--bad); background: var(--surface-hover); }
.pp-ds-del:disabled { opacity: 0.3; cursor: default; }
.pp-ds-add { display: flex; gap: 6px; margin-top: 8px; align-items: center; }
.pp-ds-add select { flex: 1; min-width: 0; }
.pp-ds-addbtn { flex: none; white-space: nowrap; }
/* Figure（複合図）: パネル一覧のラベルタグ / ラベルプレビュー / グラフ追加ピッカー */
.fig-panel-tag {
  width: auto; min-width: 18px; height: 16px; padding: 0 4px; border-radius: var(--radius-sm);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-active); color: var(--text);
  font-size: var(--fs-sm); font-weight: 700; line-height: 1;
}
.fig-label-preview { margin-top: 8px; padding: 6px 8px; border-radius: var(--radius-md); background: var(--surface-hover); color: var(--muted); font-size: var(--fs-base); }
.fig-pick-list { display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow: auto; margin-top: 6px; }
.fig-pick-row { display: flex; align-items: center; gap: 8px; padding: 5px 6px; border-radius: var(--radius-md); cursor: var(--cur-pointer, pointer); }
.fig-pick-row:hover { background: var(--surface-hover); }
.fig-pick-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fig-pick-type { flex: none; color: var(--muted); font-size: var(--fs-sm); }
/* ブレーク範囲の行 (開始 / 終了 / 削除) */
.pp-break-row { display: flex; gap: 6px; align-items: center; margin: 4px 0; }
.pp-break-row input { flex: 1; min-width: 0; }

/* セクション / フィールド (中身は P.2+ で生成) */
.pp-sec      { padding: 2px 0 7px; border-bottom: 1px solid var(--panel-border); }
/* 折りたたみ可能なセクションヘッダ (▾/▸ クリックで本体を畳む)。
   スクロール中も見出しが上端に固定されるよう sticky (本体は背景の下を流れる) */
.pp-sec-head { position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; gap: 6px; width: 100%; text-align: left;
  border: none; background: var(--panel); cursor: var(--cur-pointer, pointer);
  font-size: var(--fs-base); font-weight: 700; text-transform: none; letter-spacing: var(--tracking-tight);
  color: var(--text); margin: 0 0 4px; padding: 6px 0 4px;
  box-shadow: 0 1px 0 var(--panel-border); }
/* D-70: 見出しは既定で主色。hover は面で示す (色を上げる余地がもう無い)。 */
.pp-sec-head:hover { background: var(--surface-hover); }
.pp-sec-caret { flex: none; width: 9px; font-size: var(--fs-xs); color: var(--muted); transition: transform var(--dur-med) var(--ease-out); }
.pp-sec.collapsed .pp-sec-caret { transform: rotate(-90deg); }   /* ▾ → ▸ */
.pp-sec-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 折りたたみアニメ: body を grid 1fr↔0fr で高さ補間、inner を overflow:hidden + opacity で隠す */
.pp-sec-body  { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--dur-med) var(--ease-out); }
.pp-sec.collapsed .pp-sec-body { grid-template-rows: 0fr; }
.pp-sec-inner { overflow: hidden; min-height: 0; transition: opacity var(--dur-short) var(--ease-out); }
.pp-sec.collapsed .pp-sec-inner { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  #layout, .pp-host, .pp-collapse, .pp-collapse svg, .pp-sec-body, .pp-sec-inner, .pp-sec-caret { transition: none; }
}
/* ラベル + 値 (コンパクト設計)。行間/パディング/フォントを密にし、ラベル列は狭め + 省略表示。
   値カラムは minmax(0,1fr) で 0 まで縮められる (input の内在 min-width による横はみ出しを防ぐ) */
/* 縦に積むフォーム 1 行の間隔は --gap-stack 1 本 (D-83)。
   旧実装はプロパティ 2px・フィット 6px と 3 倍違い、白い入力ボックスが縦に並ぶと
   1 枚の縞板に見えて行として読めなかった。 */
.pp-field    { display: grid; grid-template-columns: 66px minmax(0, 1fr); align-items: center; gap: var(--space-gap-row); margin: var(--gap-stack) 0; min-height: var(--control-h); }   /* D-01 */
.pp-field > label {
  font-size: var(--fs-sm); font-weight: 600; color: var(--muted); line-height: 1.25; text-align: right;   /* ラベルは右揃え */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;   /* 2行にしない: … + title 属性で全文 */
}
/* 値入力 (テキスト/数値/ドロップダウン/単位ラッパ) はセル幅にフィット → パネル幅に追従して自動で伸縮。
   min-width:0 が肝 (これが無いと input 既定の size 由来の幅でセルを押し広げ、パネル外へはみ出す)。 */
.pp-field > :is(input[type="text"], input[type="number"], select, textarea, .pp-inwrap) {
  width: 100%; min-width: 0;
}
/* パネル内の入力は左右パディングだけ一段コンパクトに。高さ/角丸はアプリ共通トークン (D-01/D-02)。 */
.pp-frame :is(.pp-field input[type="text"], .pp-field input[type="number"], .pp-field select, .pp-field textarea) {
  padding: 0 6px; font-size: var(--fs-base); border-radius: var(--radius-ctl);
}
.pp-frame .pp-field textarea { padding: 4px 6px; }
/* R5-M6: **数値入力は内容ぶんの幅で止める。** 値カラム一杯に伸ばすと、
   ラベル ("Size") と値 ("3.4") の間に 180px 前後の空白ができ、視線が渡れない。
   桁数の要る欄 (単位付き = .pp-inwrap) は従来どおり伸ばす。 */
.pp-field > input[type="number"] { width: auto; max-width: 96px; justify-self: start; }
/* R5-M6: チェック行のラベルも、他の行と同じラベル列に載せて右端を揃える。
   旧実装はチェック行だけ左揃えの flex で、ラベル列の右端が崩れていた。 */
.pp-field-check.pp-aligned { display: grid; grid-template-columns: 66px minmax(0, 1fr);
  align-items: center; gap: var(--space-gap-row); }
.pp-field-check.pp-aligned > input[type="checkbox"] { order: 1; justify-self: start; }
.pp-field-check.pp-aligned > label { order: 0; text-align: right; flex: none;
  font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
/* D-01: 同一行で背が違う状態を作らない。色入力だけ --control-h-sm (20px) で、
   隣の select / number (24px) と揃っていなかった。 */
/* R9-H6: 値カラムの左端に、共通の高さで揃える。旧実装は色見本 32px・チェック 14px と
   固有寸法で、同じ 1 列に 4 種類の背丈と 4 つの右端が並んでいた。数値入力
   (R5-M6 で意図的に内容幅) と同じ「左寄せ・共通高さ」の規則へ寄せる。 */
.pp-frame .pp-field input[type="color"] { width: 44px; height: var(--control-h); justify-self: start; }
.pp-field-check.pp-aligned > input[type="checkbox"] { width: 14px; height: 14px; margin: 0; }
/* 単位をボックス内に表示 (ラベルからは単位を省く)。入力の右に小さな単位を重ね、右余白を確保。 */
.pp-inwrap { position: relative; display: block; }
.pp-inwrap > input.has-unit { width: 100%; padding-right: 22px; }
.pp-unit { position: absolute; right: 7px; top: 50%; transform: translateY(-50%);
  font-size: var(--fs-xs); color: var(--muted); pointer-events: none; }
/* 未確定(入力中)→確定(反映) の視覚フィードバック (Apply ボタン廃止の代替)。
   入力中=琥珀の枠+薄い塗り(未反映)、change で反映され緑に一瞬パルス(applied)。 */
.pp-frame .pp-dirty { border-color: var(--warn) !important;
  background: color-mix(in srgb, var(--warn) 13%, var(--panel-2)) !important; }
@keyframes pp-applied-kf {
  0%   { border-color: var(--good); box-shadow: 0 0 0 2px color-mix(in srgb, var(--good) 45%, transparent); }
  100% { border-color: var(--panel-border); box-shadow: 0 0 0 2px transparent; }
}
.pp-frame .pp-applied { animation: pp-applied-kf var(--dur-med) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .pp-frame .pp-applied { animation-duration: 0.001ms; } }
/* チェックボックス行: [✓] ラベル を1行 flex に。チェックは文頭、ラベルは左揃え・1行(省略)。 */
.pp-field-check { display: flex; align-items: center; gap: 7px; margin: 2px 0; }
.pp-field-check > input[type="checkbox"] { order: 0; flex: none; }
.pp-field-check > label { order: 1; flex: 1; min-width: 0; cursor: var(--cur-pointer, pointer);
  text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 軸/辺セレクタ (セグメントボタン)。軸タブの先頭に表示し、X/Y・上下左右をここで切替。 */
.pp-axissel { display: flex; flex-direction: column; gap: 5px; margin: 0 0 9px; }
/* D-01: セグメントの外形も 1 行コントロールと同じ高さ (枠の 1px を内側で吸収する)。
   旧実装は枠のぶん 26px になり、同じフォーム内でこの行だけ背が高かった。 */
.pp-seg { display: flex; height: var(--control-h); box-sizing: border-box; border: 1px solid var(--panel-border); border-radius: var(--radius-ctl); overflow: hidden; }
.pp-seg-btn { box-sizing: border-box; }
.pp-seg-btn { flex: 1; height: var(--control-h); padding: 0 6px; border: none; border-right: 1px solid var(--panel-border);
  background: var(--panel-2); color: var(--muted); font-size: var(--fs-sm); font-weight: 500;
  cursor: var(--cur-pointer, pointer); white-space: nowrap; }
.pp-seg-btn:last-child { border-right: none; }
.pp-seg-btn:hover { color: var(--text); background: var(--surface-hover); }
.pp-seg-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pp-seg-btn:active:not(:disabled) { background: var(--surface-active); }
/* 選択 = 面 + 主色の文字 + weight 600。ink 全塗りも一辺の線も使わない。
   文字を accent にすると accent 面の上で 4.0:1 前後しか出ないため、
   文字は --text、accent は小面積のアイコン側だけに使う。 */
.pp-seg-btn.active { background: var(--surface-active); color: var(--text); font-weight: 600; }
.pp-seg-btn.active svg { color: var(--accent); }
/* 辺セレクタ + 「同じ」チェックを横並び (同じはセレクタのすぐ隣)。same のとき辺ボタンはグレーアウト。 */
.pp-sidesel-row { display: flex; align-items: center; gap: 8px; }
.pp-sidesel-row .pp-seg { flex: 1; min-width: 0; }
.pp-same { flex: none; display: flex; align-items: center; gap: 5px; white-space: nowrap;
  font-size: var(--fs-sm); font-weight: 600; color: var(--muted); cursor: var(--cur-pointer, pointer); }
.pp-same input { flex: none; }
.pp-seg.disabled { opacity: 0.45; }
.pp-seg.disabled .pp-seg-btn, .pp-seg-btn:disabled { cursor: default; }
.pp-seg.disabled .pp-seg-btn:hover { background: var(--panel-2); color: var(--muted); }
.pp-seg.disabled .pp-seg-btn.active { background: var(--surface-active); color: var(--muted); box-shadow: none; }
/* グループ小見出し (主目盛り/副目盛り/軸線/主グリッド…): 同じ語の繰り返しを避けるための区切り見出し */
.pp-grouphead {
  font-size: var(--fs-sm); font-weight: 700; letter-spacing: var(--tracking-tight); text-transform: none;
  color: var(--muted); margin: 8px 0 3px; padding-top: 5px; border-top: 1px solid var(--panel-border);
}
.pp-grouphead:first-child { border-top: none; padding-top: 0; margin-top: 2px; }
.pp-adv > summary { cursor: var(--cur-pointer, pointer); color: var(--muted); font-size: var(--fs-base); }
.pp-more     { margin-top: 8px; width: 100%; }
/* ---- D-110: 対になる数値を 1 行に (幅×高さ / X,Y) ---- */
.pp-pair { display: flex; align-items: center; gap: var(--gap-inline); min-width: 0; }
/* グリッドの値セル幅を 2 分割する。`.pp-field > input[type=number]` の
   max-width:96px / justify-self:start は直接の子だけが対象なので、ここには効かない。 */
.pp-pair > input[type="number"] { flex: 1 1 0; min-width: 0; width: auto; }
/* 区切りの "×" / "," は補助 (helper: --fs-sm / 400 / --muted)。
   単位は箱の中の単位 (.pp-unit) と同じメタ (meta: --fs-xs / 400 / --muted) に揃える
   — 同じ「単位」という役割が場所によって別の仕様になるのを防ぐ (D-70)。 */
.pp-pair-sep { flex: none; color: var(--muted); font-size: var(--fs-sm); }
.pp-pair-unit { flex: none; color: var(--muted); font-size: var(--fs-xs); }
/* ---- D-110: リセット系は三次操作 (小さく・右端・テキスト) ---- */
.pp-resetrow { display: flex; justify-content: flex-end; margin-top: var(--gap-stack); }
.pp-reset {
  height: var(--control-h-sm);
  padding: 0 var(--pad-ctl-x-sm);
  border: 1px solid transparent;
  border-radius: var(--radius-ctl);
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-family: inherit;
  cursor: var(--cur-pointer, pointer);
}
.pp-reset:hover { color: var(--text); background: var(--surface-hover); }
.pp-reset:focus-visible { box-shadow: var(--focus-ring); outline: none; }
/* E-2: パネル/ダイアログのボタンは最小幅を確保し、狭幅でも文字を省略記号にせず折返しで対応。
   横並びのボタン行 (.pp-ds-add 等) は wrap して潰れないようにする。 */
.pp-frame .btn, .dlg-buttons .btn { min-width: 72px; white-space: nowrap; text-overflow: clip; }
.pp-frame .pp-more { min-width: 0; }   /* 全幅ボタンは最小幅の制約から除外 (常にセル幅にフィット) */
.pp-ds-add, .dlg-buttons { flex-wrap: wrap; }

/* リングはボタン/サマリのみ。input/select は「枠色 accent 1 本」(#1: リングは枠と同心の二重枠に見える) */
.pp-frame :is(button, summary):focus-visible { box-shadow: var(--focus-ring); outline: none; }
.pp-frame :is(select, input):focus-visible { box-shadow: none; border-color: var(--accent); background: var(--panel); outline: none; }
.pp-grip:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; background: var(--sel-bg); }
/* ダブルクリック→jumpTo で該当セクションを一瞬強調 */
@keyframes pp-flash-kf { from { background: var(--sel-bg); } to { background: transparent; } }
.pp-sec.pp-flash { animation: pp-flash-kf var(--dur-med) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .pp-sec.pp-flash { animation-duration: 0.001ms; } }

/* ============ U.4: アクセシビリティ & モーション ============ */
/* フォーカスは :focus-visible 1系統に統一(キーボード操作で可視・マウスクリックでは出さない)。
   .btn / input / select / textarea は U.2 で個別指定済み。残りの操作要素をここでまとめて指定。 */
.tb-btn:focus-visible,
.menu-label:focus-visible,
.menu-item:focus-visible,
.exp-item:focus-visible,
.exp-folder:focus-visible,
.page-tab:focus-visible,
.dlg-tab:focus-visible,
.dlg-subtab:focus-visible,
.axis-side-item:focus-visible,
.br-chip:focus-visible,
.mdi-btn:focus-visible,
.link-chip:focus-visible,
.ds-chip:focus-visible,
.theme-toggle:focus-visible,
.graph-tools button:focus-visible,
.tb-flyout-menu button:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

/* 装飾トランジション(主要操作要素のみ)。レイアウトには付けない。 */
.btn, .tb-btn, .menu-label, .menu-item, .exp-item, .page-tab, .dlg-tab,
.link-chip, .ds-chip, .theme-toggle {
  /* box-shadow は含めない: フォーカスリング (--focus-ring) は即時に出す (アニメ禁止) */
  transition: background var(--dur-short) var(--ease-out), border-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out);
}

/* 無効要素は色だけでなく不透明度でも示す */
select:disabled, input:disabled, textarea:disabled { opacity: 0.5; cursor: var(--cur-arrow, default); }

/* 数値テーブルは等幅数字(桁揃え)。一律 input には当てず .num-field 限定(U.2)。 */
.ws-table tbody td { font-variant-numeric: tabular-nums; }

/* reduced-motion: 全域 !important では消さず、装飾トランジションを持つクラスに限定。
   (マクロ実行アニメ/ノードグラフのエッジ/プログレス等は残す) */
@media (prefers-reduced-motion: reduce) {
  .btn, .tb-btn, .menu-label, .menu-item, .exp-item, .page-tab, .dlg-tab,
  .link-chip, .ds-chip, .ds-dot2, .theme-toggle {
    transition-duration: 0.001ms !important;
  }
}

/* ============ 共通アイコン (icons.js の線画 SVG) のサイズ ============ */
.mdi-btn svg { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; display: block; }
.exp-tw svg { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; vertical-align: -1px; }
.menu-item .check svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; vertical-align: -2px; }
.pp-ds-del svg { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; display: block; margin: auto; }
.pp-sec-caret svg { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; display: block; }
.fit-res-srcwarn svg, .fit-res-warns svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; vertical-align: -2px; }

/* ===== プロットギャラリー (plotcatalog.js) ===== */
/* 本文を縦 flex にして、ツールバー固定 + 一覧だけスクロール = スクロールバー 1 本 (T5.1)。 */
.dlg-body.pg-body { display: flex; flex-direction: column; overflow: hidden; }
/* 上部のカテゴリチップ (絞り込みツールバー)。flex の固定行なので sticky は要らない。 */
.pg-toolbar { flex: 0 0 auto; display: flex; flex-direction: column; gap: var(--space-2);
  padding-bottom: var(--space-2); margin-bottom: var(--space-2);
  background: var(--panel); border-bottom: 1px solid var(--panel-border); }
.pg-chips { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.pg-chip { display: inline-flex; align-items: center; font-size: var(--fs-sm); font-weight: 500; height: var(--control-h-sm); padding: 0 10px; border-radius: var(--radius-ctl);
  border: 1px solid var(--panel-border); background: var(--panel-2); color: var(--muted);
  cursor: var(--cur-pointer, pointer); }
.pg-chip:hover { background: var(--surface-hover); color: var(--text); }
.pg-chip.active { background: var(--surface-active); border-color: var(--surface-active); color: var(--text); font-weight: 600; }
.pg-wrap { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding-right: var(--space-2); }
.pg-cat[hidden] { display: none; }
.pg-cat-title { font-size: var(--fs-base); font-weight: 700; text-transform: none; letter-spacing: var(--tracking-tight);
  color: var(--text); margin: var(--space-3) 0 var(--space-2);
  border-bottom: 1px solid var(--panel-border); padding-bottom: 4px; }
/* カード幅を縮めて列数を増やす (一画面でより多くの型を見渡せる) */
.pg-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: var(--space-2); }
.pg-card { position: relative; border: 1px solid var(--panel-border); border-radius: var(--radius-md);
  background: var(--panel-2); padding: var(--space-2); display: flex; flex-direction: column; gap: 5px; }
.pg-card[hidden] { display: none; }
.pg-card:hover { border-color: var(--accent); }
.pg-card:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.pg-thumb { align-self: center; width: 100%; max-width: 132px; height: auto; background: var(--panel-2); }
.pg-name { font-weight: 600; font-size: var(--fs-base); }
/* 説明は2行にクランプ (全文は title 属性 + ホバー見本で補う) */
.pg-req { font-size: var(--fs-xs); color: var(--muted); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* 見本テーブルは常時表示をやめ、ホバー/フォーカス時にカード右上へポップ表示する */
.pg-sketch-pop { position: absolute; top: 6px; right: 6px; z-index: 3;
  background: var(--panel); border: 1px solid var(--panel-border); border-radius: var(--radius-md);
  padding: 6px; box-shadow: var(--shadow-overlay);
  opacity: 0; visibility: hidden; transform: translateY(-2px); pointer-events: none;
  transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out); }
.pg-card:hover .pg-sketch-pop, .pg-card:focus-within .pg-sketch-pop { opacity: 1; visibility: visible; transform: translateY(0); }
.pg-sketch { border-collapse: collapse; font-size: var(--fs-xs); }
.pg-sketch th, .pg-sketch td { border: 1px solid var(--panel-border); padding: 1px 6px; text-align: center; }
.pg-sketch th { background: var(--panel); color: var(--muted); font-weight: 500; }
.pg-actions { display: flex; flex-wrap: wrap; gap: var(--space-1); margin-top: auto; }
/* §24: ギャラリーのボタンも共通の .btn 寸法のまま (独自の font-size / padding を持たない)。 */
.pg-actions .btn { min-width: 0; }
.pg-empty { color: var(--muted); padding: var(--space-4); text-align: center; font-size: var(--fs-base); }
@media (prefers-reduced-motion: reduce) { .pg-sketch-pop { transition: none; } }

/* ===== メニューのサブメニュー (プロットのカテゴリツリー) ===== */
.menu-item.has-sub { position: relative; }
.menu-item .sub-arrow { margin-left: auto; padding-left: var(--space-3); color: var(--muted); }
.menu-drop.sub { position: fixed; z-index: var(--z-float); }

/* ===== ツールバーのプロット群サムネ (plotcatalog.js から生成) ===== */
/* T5.5: プロット種別アイコンは 16px の線画 SVG。寸法・線幅はここで一括指定する
   (canvas 縮小をやめたので DPR に依存せず、全種別で線幅が揃う)。 */
.tb-mini { display: inline-flex; vertical-align: middle; align-items: center; }
.tb-mini svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.3;
  stroke-linecap: round; stroke-linejoin: round; display: block; }
.tb-flyout-menu button .tb-mini { margin-right: var(--space-2); }

/* ============ Analysis MDI panels ============ */
/* Analysis and Fitting share one child-window contract: MDI title/state chrome,
   a persistent preview tool strip, a left preview/right properties split, and
   a fixed action footer.  The selectors intentionally live outside the legacy
   #modal.analysis-modal block above so the old headless dialog harness keeps
   working while the application uses real MDI children. */
.mdi-window.analysis-window {
  min-width: 620px;
  min-height: 360px;
  background: var(--panel);
}
.mdi-window.analysis-window .analysis-toolbar {
  min-height: var(--wintoolbar-h);
  background: var(--titlebar);
  border-bottom: 1px solid var(--panel-border);
  padding: 0 var(--gap-inline);
}
.mdi-window.analysis-window.active .analysis-toolbar { background: var(--titlebar-active); }
.analysis-tool-label {
  flex: none;
  color: var(--titlebar-ink);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  padding-right: var(--space-2);
}
.analysis-preview-tools { display: inline-flex; align-items: center; gap: 2px; min-width: 0; }
.analysis-preview-tools .wt-btn { min-width: var(--control-h); }
.analysis-preview-tools .wt-btn.active { background: var(--surface-active); color: var(--text); font-weight: 600; }
.analysis-preview-tools .wt-btn.active svg { color: var(--accent); }
.analysis-toolbar-state {
  margin-left: auto;
  flex: none;
  color: var(--titlebar-ink);
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
}
.mdi-window.analysis-window.active .analysis-toolbar-state { color: var(--text); }
.analysis-preview-tools svg {
  width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.3;
}
.analysis-win-content {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background: var(--panel);
}
.analysis-stagebar {
  flex: none;
  min-height: 42px;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px 10px;
  border-bottom: 1px solid var(--panel-border);
  background: var(--panel);
  color: var(--text);
  font-size: var(--fs-sm);
}
.analysis-stage-group {
  display: inline-flex;
  flex-direction: column;
  align-items: baseline;
  align-items: flex-start;
  gap: 0;
  min-width: 0;
  padding: 2px 5px;
  border: 0;
  border-radius: var(--radius-ctl);
  background: transparent;
  color: var(--muted);
  font: inherit;
  cursor: var(--cur-pointer, pointer);
}
.analysis-stage-group:hover { background: var(--surface-hover); color: var(--text); }
.analysis-stage-group.active { background: var(--surface-active); color: var(--text); font-weight: 600; }
.analysis-stage-group:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
.analysis-stage-eyebrow {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 400;
  letter-spacing: var(--tracking-tight);
}
.analysis-stage-name { font-weight: 600; white-space: nowrap; }
.analysis-stage-arrow { color: var(--muted); font-size: var(--fs-lg); line-height: 1; }
.analysis-stage-state {
  margin-left: auto;
  flex: none;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
}
.mdi-window.analysis-window.active .analysis-stage-state { color: var(--text); }
.analysis-win-body {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background: var(--panel);
}
.analysis-win-body > .an-dialog {
  display: grid;
  grid-template-columns: minmax(300px, 1.08fr) minmax(300px, .92fr);
  gap: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  background: var(--panel);
}
.analysis-win-body > .an-dialog.analysis-split {
  grid-template-columns: minmax(280px, 1fr) 6px minmax(280px, var(--analysis-prop-w, 380px));
}
.analysis-win-hsplit {
  width: 6px;
  min-width: 6px;
  cursor: col-resize;
  background: transparent;
}
.analysis-win-hsplit:hover { background: color-mix(in srgb, var(--accent) 40%, transparent); }
.analysis-win-hsplit:focus-visible { outline: none; background: var(--accent); }
.analysis-win-body .an-preview {
  order: 0;
  min-width: 0;
  min-height: 0;
  padding: 10px 14px 14px;
  border-right: 1px solid var(--panel-border);
  background: var(--panel-2);
  overflow: hidden;
}
.analysis-win-body .an-form {
  order: 1;
  min-width: 0;
  min-height: 0;
  padding: 0 14px 14px;
  gap: 0;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--panel);
}
.analysis-win-body .an-sec {
  gap: var(--gap-stack);
  padding: 10px 0;
  border-top: 1px solid var(--panel-border);
}
.analysis-win-body .an-sec:first-child { border-top: 0; }
.analysis-win-body .an-sec-title {
  display: flex;
  align-items: center;
  min-height: var(--control-h);
  margin: 0;
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
}
.analysis-win-body .an-row {
  display: grid;
  gap: var(--gap-stack);
  min-width: 0;
}
.analysis-win-body .an-row.an-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.analysis-win-body .an-row.an-single { grid-template-columns: minmax(0, 1fr); }
.analysis-win-body .an-row > label,
.analysis-win-body .an-field {
  min-width: 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 600;
}
.analysis-win-body .an-row.an-single > label,
.analysis-win-body .an-field:not(.check-label) {
  display: grid;
  grid-template-columns: minmax(84px, 96px) minmax(0, 1fr);
  align-items: center;
  gap: var(--gap-inline);
}
.analysis-win-body .an-row.an-pair > label { display: flex; flex-direction: column; gap: var(--space-1); }
.analysis-win-body .an-yrow { grid-template-columns: minmax(84px, 96px) minmax(0, 1fr); align-items: start; }
.analysis-win-body .an-yrow .an-ylab { padding-top: 5px; }
.analysis-win-body .an-row select,
.analysis-win-body .an-field select,
.analysis-win-body .an-field input[type="number"] { width: 100%; min-width: 0; }
.analysis-win-body .an-field.check-label {
  display: flex;
  align-items: center;
  gap: var(--gap-inline);
  min-height: var(--control-h);
  color: var(--text);
  font-weight: 500;
}
.analysis-win-body .an-params {
  display: flex;
  flex-direction: column;
  gap: var(--gap-stack);
  padding-top: 10px;
}
.analysis-win-body .an-preview-head { display: flex; align-items: center; min-height: var(--control-h); }
.analysis-win-body .an-pv-title { color: var(--text); font-size: var(--fs-base); font-weight: 700; letter-spacing: var(--tracking-tight); }
.analysis-win-body .an-preview-canvas-wrap {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 220px;
  display: flex;
  align-items: stretch;
  overflow: hidden;
}
.analysis-win-body .an-preview canvas {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 220px;
  border: 0;
  border-radius: var(--radius-ctl);
  background: var(--panel-2);
  transition: transform var(--dur-short) var(--ease-out);
}
.analysis-win-body .an-preview-canvas-wrap.is-analysis-pan { cursor: grab; }
.analysis-win-body .an-preview-canvas-wrap.is-analysis-pan:active { cursor: grabbing; }
.analysis-selection-marker {
  position: absolute;
  width: 9px;
  height: 9px;
  margin: -5px 0 0 -5px;
  border: 2px solid var(--accent);
  border-radius: 50%;
  box-sizing: border-box;
  pointer-events: none;
  z-index: 2;
}
.analysis-win-body .an-preview-status {
  margin-left: auto;
  padding: 2px 7px;
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
}
.analysis-win-body .an-preview-status.is-ready { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--panel-border)); }
.analysis-win-body .an-preview-status.is-error { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, var(--panel-border)); }
.analysis-win-body .an-summary { min-height: var(--control-h-sm); padding: 5px 0 0; }
.analysis-win-body .an-summary-label { color: var(--text); font-weight: 700; }
.analysis-win-body .an-run-status { min-height: var(--control-h-sm); }
.analysis-win-body .an-output { gap: var(--space-1); margin-top: auto; }
.analysis-win-body .an-stats-preview { flex: 1 1 auto; min-height: 0; overflow: auto; }
.analysis-win-body .an-table-wrap { min-width: 0; overflow: auto; }
.analysis-win-body .an-stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 8px; }
.analysis-win-body .an-picker-actions { display: flex; gap: 6px; margin: 0 0 6px; }
.analysis-win-body .an-empty-state { min-height: 180px; }
.analysis-win-body .dlg-grid { min-width: 0; }
.analysis-win-body fieldset { margin: 0; padding: 10px 0 0; border: 0; border-top: 1px solid var(--panel-border); }
.analysis-win-body fieldset:first-child { padding-top: 2px; border-top: 0; }
.analysis-win-body legend { padding: 0; color: var(--text); font-size: var(--fs-base); font-weight: 700; letter-spacing: var(--tracking-tight); }
.analysis-win-body .dlg-error { min-height: var(--control-h-sm); margin-top: 0; padding: 4px 8px; }
.analysis-win-content[data-analysis-stage="data"] .analysis-win-body > .an-dialog,
.analysis-win-content[data-analysis-stage="parameters"] .analysis-win-body > .an-dialog,
.analysis-win-content[data-analysis-stage="preview"] .analysis-win-body > .an-dialog,
.analysis-win-content[data-analysis-stage="results"] .analysis-win-body > .an-dialog {
  grid-template-columns: minmax(0, 1fr);
}
.analysis-win-content[data-analysis-stage="data"] .analysis-win-hsplit,
.analysis-win-content[data-analysis-stage="parameters"] .analysis-win-hsplit,
.analysis-win-content[data-analysis-stage="preview"] .analysis-win-hsplit,
.analysis-win-content[data-analysis-stage="results"] .analysis-win-hsplit { display: none; }
/* Preview keeps the Fitting-style preview | properties split.  The other
   stages intentionally focus one real panel and hide the splitter. */
.analysis-win-content[data-analysis-stage="preview"] .analysis-win-body > .an-dialog {
  grid-template-columns: minmax(300px, 1.08fr) 6px minmax(300px, .92fr);
}
.analysis-win-content[data-analysis-stage="preview"] .analysis-win-hsplit { display: block; }
.analysis-stage-panel { min-width: 0; }
.analysis-parameters-panel { display: flex; flex-direction: column; gap: var(--gap-stack); min-height: 0; overflow: auto; }
/* In the one-column stages the form is the only grid item.  Explicitly
   stretch both it and the real tabpanel: an MDI grid item otherwise keeps
   the flex-basis inherited from .an-form and some engines resolve that
   nested panel to zero width. */
.analysis-win-content[data-analysis-stage="data"] .analysis-win-body > .an-dialog > .an-form,
.analysis-win-content[data-analysis-stage="parameters"] .analysis-win-body > .an-dialog > .an-form,
.analysis-win-content[data-analysis-stage="results"] .analysis-win-body > .an-dialog > .an-form {
  width: 100%;
  min-width: 0;
  max-width: none;
  justify-self: stretch;
  align-self: stretch;
  box-sizing: border-box;
}
.analysis-win-content[data-analysis-stage="data"] .analysis-stage-panel,
.analysis-win-content[data-analysis-stage="parameters"] .analysis-stage-panel,
.analysis-win-content[data-analysis-stage="results"] .analysis-stage-panel {
  width: 100%;
  min-width: 0;
  max-width: none;
  box-sizing: border-box;
  flex: 0 0 auto;
}
.analysis-footbar {
  flex: none;
  min-height: 42px;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--gap-inline);
  border-top: 1px solid var(--panel-border);
  background: var(--panel);
}
.analysis-footbar .dlg-buttons { display: flex; flex: none; align-items: center; justify-content: flex-end; gap: var(--gap-inline); }
.analysis-footbar .dlg-buttons { padding: 0; border-top: 0; }
.analysis-footbar .dlg-buttons .btn.primary { min-width: 84px; }
@media (max-width: 820px) {
  .mdi-window.analysis-window { min-width: 520px; }
  .analysis-win-body > .an-dialog { grid-template-columns: 1fr; overflow-y: auto; }
  .analysis-win-body > .an-dialog.analysis-split { grid-template-columns: 1fr; }
  .analysis-win-hsplit { display: none; }
  .analysis-win-body .an-preview { min-height: 280px; border-right: 0; border-bottom: 1px solid var(--panel-border); }
}
