/* fjDashboard 共通スタイル（素のCSS・ビルドなし）
   sienDashboard の style.css を土台に、稼働可視化用のコンポーネントを足したもの。
   ライト/ダーク両対応（OS設定に追従。JSトグルは持たない）。

   部署色は config.json の departments.colors が正で、
   要素には JS が inline style で色を当てる（ここには重複定義しない）。

   ── デザインの狙い（2026-07-23 刷新 / ★追記19）─────────────────────
   参照元は static/image/office.png（/office.html の背景アイソメ図）。
   「白基調・強い角丸・水色LEDの発光ライン・半透明ガラス・やわらかい影」で、
   黒背景＋ネオンのサイバーパンクには寄せない（明るい近未来）。
   ダークは廃止せず「夜のオフィス」＝照明を落とした同じ部屋として再調整する
   （ライトの単純な色反転にはしない。深いネイビー＋水色の発光が灯る）。

   色は必ずこの :root のトークン経由で使う（各所にハードコードしない）。
     --accent  … 文字にも使える濃さの青（コントラスト確保用）
     --glow    … 発光・装飾専用の水色（文字色には使わない）
   ------------------------------------------------------------------ */

:root {
  /* 面 */
  --bg: #eef3f9;
  --bg-tint-a: #ffffff;          /* 背景グラデの明部（斜めから差す光） */
  --bg-tint-b: #dfeaf5;          /* 背景グラデの暗部 */
  --panel: #ffffff;
  --panel-2: #eff4fa;
  /* ガラス（半透明パネル。会議室の仕切りのイメージ） */
  --glass: rgba(255, 255, 255, 0.72);
  --glass-border: rgba(255, 255, 255, 0.9);
  --glass-blur: saturate(1.35) blur(14px);

  /* 文字（本文は白面上で 4.5:1 以上） */
  --text: #1d2a3a;               /* on #fff → 13.6:1 */
  --text-muted: #5a6b80;         /* on #fff →  5.3:1 */

  /* 線 */
  --border: #d9e5f1;
  --border-strong: #bed2e6;

  /* 発光・アクセント */
  --accent: #0d7cb5;             /* on #fff → 4.7:1（文字にも使える） */
  --accent-soft: rgba(13, 124, 181, 0.10);
  --glow: #3fc3f0;               /* 装飾専用のLED水色 */
  --glow-soft: rgba(63, 195, 240, 0.45);
  --glow-line: linear-gradient(90deg,
      transparent 0%,
      var(--glow-soft) 18%,
      var(--glow) 50%,
      var(--glow-soft) 82%,
      transparent 100%);

  /* 状態色（.health.active など小さな文字にも載るので、白面で 4.5:1 以上を実測で確保）
       --ok     on #fff → 5.0:1
       --warn   on #fff → 4.6:1
       --danger on #fff → 5.3:1 */
  --ok: #0b7f5e;
  --warn: #a2681a;
  --danger: #c03d2e;

  /* 値動き専用トークン（2026-08-01 方針転換。日本式＝上昇=赤/下落=緑）。
     --danger/--ok とは意味を分離するため独立トークンとして持つ
     （--dangerはツール側の異常表示、--okは稼働健全性の意味で既に使われているため、
     同じ変数を値動きに流用すると「エラー」か「値動き」かコード上で判別できなくなる）。
     詳細は docs/architecture.md §4-E・fin-bar/fin-num--up/down 参照。 */
  --stock-up:   #c0392b;   /* 上昇=赤。on #fff → 約5.4:1 */
  --stock-down: #1f7a5c;   /* 下落=緑。on #fff → 約5.1:1 */
  --stock-up-soft:   rgba(192, 57, 43, 0.16);
  --stock-down-soft: rgba(31, 122, 92, 0.16);

  /* 角丸スケール（オフィスの什器はほぼピル型・大R） */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-pill: 999px;

  /* 影（ハードな影は作らない。多段のやわらかい影） */
  --shadow: 0 1px 2px rgba(23, 54, 88, 0.05), 0 10px 26px -14px rgba(23, 54, 88, 0.30);
  --shadow-lg: 0 2px 4px rgba(23, 54, 88, 0.05), 0 20px 44px -20px rgba(23, 54, 88, 0.35);
  --shadow-glow: 0 0 0 1px rgba(63, 195, 240, 0.22), 0 6px 20px -8px rgba(63, 195, 240, 0.45);

  /* ブランド識別色（利用枠バーのサービスアイコン専用。UIの状態色とは別枠なので
     ライト/ダークで変えない＝各サービスのロゴ色をそのまま固定値として持つ）。 */
  --brand-claude: #d97757;
  --brand-codex: #7897f7;
  --brand-higgsfield: #e6fe15;
  --brand-higgsfield-ink: #1d2a3a;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* 夜のオフィス：照明を落とした同じ部屋。黒ではなく深いネイビー */
    --bg: #0b131f;
    --bg-tint-a: #16243a;
    --bg-tint-b: #080e17;
    --panel: #131e2e;
    --panel-2: #0f1826;
    --glass: rgba(22, 35, 54, 0.66);
    --glass-border: rgba(120, 170, 210, 0.20);
    --glass-blur: saturate(1.2) blur(14px);

    --text: #e9f1f9;             /* on #131e2e → 13.9:1 */
    --text-muted: #94a8c0;       /* on #131e2e →  6.2:1 */

    --border: #24344b;
    --border-strong: #354966;

    --accent: #55b9e8;           /* on #131e2e → 7.3:1 */
    --accent-soft: rgba(85, 185, 232, 0.14);
    --glow: #62d6ff;
    --glow-soft: rgba(98, 214, 255, 0.40);

    --ok: #3fc79a;
    --warn: #dfa64f;
    --danger: #ef7f6c;

    --stock-up:   #f0836f;   /* on #131e2e → 約6.0:1 */
    --stock-down: #4bd1a0;   /* on #131e2e → 約7.5:1 */
    --stock-up-soft:   rgba(240, 131, 111, 0.20);
    --stock-down-soft: rgba(75, 209, 160, 0.20);

    --shadow: 0 1px 2px rgba(0, 0, 0, 0.40), 0 12px 30px -16px rgba(0, 0, 0, 0.70);
    --shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.45), 0 24px 50px -22px rgba(0, 0, 0, 0.80);
    --shadow-glow: 0 0 0 1px rgba(98, 214, 255, 0.28), 0 6px 22px -8px rgba(98, 214, 255, 0.40);
  }
}

/* 選択中のピル（塗りつぶし）の文字色。
   ライトは濃い --accent なので白でよいが、ダークの --accent は明るい水色なので
   白文字だと 2.2:1 しか出ない。ダークでは逆に暗い文字を載せる（8.5:1）。 */
:root { --on-accent: #ffffff; }
@media (prefers-color-scheme: dark) {
  :root { --on-accent: #0b131f; }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Segoe UI", "Hiragino Sans", "Yu Gothic UI", Meiryo, system-ui, sans-serif;
  /* 斜めから差す自然光。背景は固定して、スクロールしても光の向きが変わらない */
  background:
    radial-gradient(1200px 700px at 12% -10%, var(--bg-tint-a) 0%, transparent 62%),
    radial-gradient(1000px 800px at 100% 110%, var(--bg-tint-b) 0%, transparent 70%),
    var(--bg);
  background-attachment: fixed;
  color: var(--text);
  line-height: 1.6;
}

/* ヘッダ：ガラスのパーティション。下端に水色のLEDラインを1本通す
   （オフィス画像の壁の巾木・什器の縁に走っている発光と同じ役割） */
/* ★ 2026-08-30: 縦を詰めた。F11の全画面でスクロールが出ないようにするため、
   説明文（p.lede）とサブタイトル（h1 > .subtle）を全ページから外し、
   上下パディングと h1 の行高もあわせて縮めてある。中身（main）の高さは触らない。 */
header.app-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px 16px;
  padding: 8px 24px 9px;
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow);
}

/* 巾木のLED。下端いっぱいに引いて、両端でフェードさせる */
header.app-header::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--glow-line);
  opacity: 0.85;
  pointer-events: none;
}

header.app-header h1 {
  margin: 0;
  font-size: 1.15rem;
  line-height: 1.35;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* h1 と（稼働パネルだけに残した）稼働ランプを1行に並べる。
   縦積みにすると、それだけでヘッダーが 24px 高くなるため。 */
.app-header-left {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}

header.app-header .subtitle {
  color: var(--text-muted);
  font-size: 0.85rem;
}

/* nav とリロードボタンをまとめる右側ブロック。header自体はdiv(タイトル)とここの
   2要素でspace-betweenするので、ここにflexで並べる分には従来のレイアウトを崩さない */
.app-header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

nav.app-nav {
  display: flex;
  gap: 4px;
  padding: 3px;
  border-radius: var(--r-pill);
  background: var(--panel-2);
  border: 1px solid var(--border);
}

/* ヘッダー右端の小さなアイコンボタン（オーナー指定で控えめな存在感）。
   - .header-reload-btn: ページ再読み込み。VS Code内プレビュー等、ブラウザの
     更新ボタンが使えない環境向け。
   - 使い方（?）: 2026-08-30に nav から降ろし、「困った時に押す」位置づけに変えた。
     <a> なので text-decoration を消し、現在地は aria-current="page" で示す。
   絵文字は使わない（docs/architecture.md §4-E）のでどちらもインラインSVG。 */
.header-icon-btn,
.header-reload-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  flex: none;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}
.header-icon-btn:hover,
.header-reload-btn:hover {
  color: var(--accent);
  background: var(--panel-2);
  border-color: var(--border);
}
.header-icon-btn:focus-visible,
.header-reload-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.header-icon-btn svg,
.header-reload-btn svg { display: block; pointer-events: none; }
.header-icon-btn { text-decoration: none; }
.header-icon-btn[aria-current="page"] {
  color: var(--accent);
  background: var(--panel);
  border-color: var(--border);
  box-shadow: var(--shadow-glow);
}
.header-reload-btn.is-spinning svg { animation: fjReloadSpin 0.6s linear; }
@keyframes fjReloadSpin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* 更新ボタンの同期結果を知らせるトースト通知（2026-08-06追加）。
   画面下中央に数秒だけ出て自動的に消える。全画面共通（common.jsから注入）なので
   ここでも各HTMLの複製と同様、専用の親要素は無くbody直下に生成する想定。 */
.fj-toast-stack {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}
.fj-toast {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--r-pill);
  background: var(--panel);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  color: var(--text);
  font-size: 0.85rem;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.fj-toast.is-visible { opacity: 1; transform: translateY(0); }
.fj-toast.is-error { border-color: var(--danger); }
.fj-toast-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
  background: var(--ok, var(--accent));
}
.fj-toast.is-error .fj-toast-dot { background: var(--danger); }
@media (prefers-reduced-motion: reduce) {
  .fj-toast { transition: opacity 0.01s linear; transform: none; }
}

nav.app-nav a {
  position: relative;
  text-decoration: none;
  color: var(--text-muted);
  padding: 4px 14px;
  border-radius: var(--r-pill);
  font-size: 0.85rem;
  border: 1px solid transparent;
  transition: color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}

nav.app-nav a:hover {
  color: var(--accent);
  background: var(--panel);
}

/* 現在地：白いピルが浮いて、下辺に細いLEDが灯る */
nav.app-nav a.active {
  color: var(--accent);
  background: var(--panel);
  border-color: var(--border);
  box-shadow: var(--shadow-glow);
}
nav.app-nav a.active::after {
  content: "";
  position: absolute;
  left: 22%; right: 22%; bottom: 2px;
  height: 2px;
  border-radius: 2px;
  background: var(--glow);
  box-shadow: 0 0 6px var(--glow-soft);
}

main { padding: 20px 24px 48px; max-width: 1200px; margin: 0 auto; }

.toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}

.toolbar .label { color: var(--text-muted); font-size: 0.85rem; }

button.pill {
  font: inherit;
  font-size: 0.85rem;
  padding: 6px 18px;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  border-radius: var(--r-pill);
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}

button.pill:hover { background: var(--panel-2); border-color: var(--border-strong); }
button.pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

button.pill.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--shadow-glow);
}

/* ---- グラフグリッド ---- */
.chart-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 18px;
}

.chart-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 14px 16px 18px;
  box-shadow: var(--shadow);
}

.chart-card h2 {
  margin: 0 0 10px;
  font-size: 0.95rem;
  font-weight: 600;
}

.chart-card .canvas-wrap { position: relative; height: 240px; }

.empty-note {
  color: var(--text-muted);
  font-size: 0.9rem;
  padding: 40px 0;
  text-align: center;
}

/* ==========================================================================
   ここから下は fjDashboard 固有（稼働可視化）のコンポーネント
   ========================================================================== */

.wrap {
  max-width: 1180px;
  margin: 0 auto;
  /* 下端 48px → 28px（2026-08-30）。「← 稼働パネルに戻る」フッターを外した4ページでは
     ここが丸ごと死に余白になるため。最後のカードが画面下端に貼り付かない分は残す。 */
  padding: 20px 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* カード：什器の天板。大きめの角丸＋やわらかい影＋上端に淡いLEDのハイライト。
   ::before は「縁に光が回り込んでいる」表現なので、中身の上には出さない。 */
.card {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  padding: 16px 18px;
}

.card::before {
  content: "";
  position: absolute;
  left: 16px; right: 16px; top: -1px;
  height: 1px;
  background: var(--glow-line);
  opacity: 0.5;
  pointer-events: none;
}

.card > h2 {
  margin: 0 0 12px;
  font-size: 0.95rem;
  letter-spacing: 0.03em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.card > h2 .h2-right {
  font-weight: 400;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.lede { margin: 2px 0 0; color: var(--text-muted); font-size: 0.85rem; }
/* 2026-08-30: 説明文としての .lede は全ページ廃止。稼働パネルだけ、稼働ランプの
   置き場として h1 と同じ行に残しているので、行を増やさないよう余白を殺す。 */
header.app-header .lede { margin: 0; white-space: nowrap; }
/* .subtle は h1 のサブタイトル用だったが 2026-08-30 に全ページから外した
   （汎用の弱色クラスとして他所で使えるよう定義自体は残す） */
.subtle { color: var(--text-muted); font-weight: 400; font-size: 0.9rem; }

/* ---- ヘッダの稼働インジケータ ----
   稼働中は「呼吸」だけさせる（点滅させない＝ちらつきで目が疲れないように）。
   更新が届いた瞬間だけ fjpulse が1回走って波紋が出る（既存の挙動を維持）。 */
.live-dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--ok);
  margin-right: 6px;
  vertical-align: middle;
  box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 60%, transparent);
  animation: fjbreathe 3.2s ease-in-out infinite;
}
.live-dot.stale {
  background: var(--text-muted);
  box-shadow: none;
  animation: none;
}
.live-dot.pulse { animation: fjpulse 1.1s ease-out 1, fjbreathe 3.2s ease-in-out infinite; }
@keyframes fjpulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 60%, transparent); }
  100% { box-shadow: 0 0 0 10px transparent; }
}
@keyframes fjbreathe {
  0%, 100% { box-shadow: 0 0 6px color-mix(in srgb, var(--ok) 45%, transparent); }
  50%      { box-shadow: 0 0 12px color-mix(in srgb, var(--ok) 85%, transparent); }
}

/* ==========================================================================
   利用枠バー（Claude Design案。2026-07-27 じゅんの追加フィードバックで
   header.app-header から分離し、main.wrap 先頭の独立ブロックへ移動した。
   .card を流用して他セクションと同じ角丸・背景・LEDラインに揃え、通常の
   スクロールコンテンツになる（sticky にはしない）。
   Claude/Codex/Higgsfieldの各グループはアイコン＋縦積みのバー行（.limits-row-wrap）。
   「利用枠」ラベルは常に非表示（2026-07-27）＝各グループが左端から揃って並ぶ。
   クリック展開は持たない（詳細はホバーの title 属性のみ）。
   ========================================================================== */
.limits-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px 26px;
}

.limits-group {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  /* カードの余りスペースを各グループが均等に埋める（2026-07-27・じゅん指摘の
     「右の余白」対策）。flex-basis はおおよそ .limits-row-wrap の min-width に
     揃えてある。min-width: 0 を付けないと、内容（バー等）が縮まずカードから
     はみ出す＝グループ数が増えたときに横スクロールの原因になる。 */
  flex: 1 1 220px;
  min-width: 0;
}

/* サービスのロゴ色。UIの状態色（--ok/--warn/--danger）とは別の「アイデンティティ色」
   なのでブランド用トークンとして:rootに分けてある（ライト/ダーク共通・固定）。 */
.limits-icon {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: var(--r-xs);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  color: #fff;
}
.limits-icon-claude { background: var(--brand-claude); }
.limits-icon-codex {
  background: var(--brand-codex);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 9px;
}
.limits-icon-higgsfield { background: var(--brand-higgsfield); color: var(--brand-higgsfield-ink); }

.limits-rows {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1 1 auto;
  min-width: 0;
}

.limits-row-wrap {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 220px;   /* サブキャプションが極端に潰れて省略されないための最低幅 */
  width: 100%;        /* .limits-group の余りスペースまで実際に広がる */
}

.limits-row {
  display: grid;
  /* バー列は可変（余りスペースを実際に使う）、数値列はコンテンツ幅ぴったりに。
     以前は末尾列が auto で、CSS Grid の stretch により auto トラックが
     コンテナの余り幅を吸収して伸び、text-align: right の数値がその伸びた
     列の右端に寄る＝バーと数値の間に不自然な余白ができるバグがあった
     （2026-07-27修正。詳細は memory/knowledge/ 参照）。 */
  grid-template-columns: 1.6em minmax(56px, 1fr) max-content;
  align-items: center;
  gap: 7px;
  cursor: help;
}

.limits-row-label {
  font-size: 11px;
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
}
a.limits-row-label:hover { color: var(--accent); text-decoration: underline; }

/* 純CSSの細いバー（Chart.js を使わない）。トラックは薄いグレー、塗りは
   状態色（--ok/--warn/--danger）。Claude/Codexは使用率、Higgsfieldは残量率で
   塗る向きが逆になるが、それはJS側（fillRatioの渡し方）の話でCSSは共通でよい。 */
.limits-row-bar {
  position: relative;
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--panel-2);
  border: 1px solid var(--border);
}
.limits-row-fill {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--ok);
  transform-origin: left;
  animation: limitsBarGrow 0.9s ease-out;
}
.limits-row-bar.warn .limits-row-fill { background: var(--warn); }
.limits-row-bar.danger .limits-row-fill { background: var(--danger); }
@keyframes limitsBarGrow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* ペースマーカー（週/月の経過割合の目安。既存の .meter-tick-today と同じ考え方の
   ミニ版）。リングを --panel 色にすることで、ライトでは白いリング、ダークでは
   濃紺のリングに自動で切り替わる（ハードコードしない）。 */
.limits-row-tick {
  position: absolute;
  top: 50%;
  width: 2px;
  height: 12px;
  transform: translate(-50%, -50%);
  border-radius: 1px;
  background: var(--text-muted);
  box-shadow: 0 0 0 2px var(--panel);
  cursor: help;
}

.limits-row-pct {
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.limits-row-unit {
  font-size: 10px;
  font-weight: 400;
  color: var(--text-muted);
  margin-left: 1px;
}

.limits-row-caption {
  padding-left: calc(1.6em + 7px);   /* バー列の開始位置に揃える */
  font-size: 10px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 260px;
}

/* FJ.inlineMd() が組み立てるリンク（Markdownリンク・生URLの共通スタイル）。 */
a.md-link { color: var(--accent); text-decoration: none; }
a.md-link:hover { text-decoration: underline; }

.note {
  color: var(--text-muted);
  font-size: 0.78rem;
  margin: 2px 2px 0;
}

/* 公式値の取り込みボタン（手動のみ。自動では絶対に押さない） */
.pill-btn {
  font: inherit;
  font-size: 0.72rem;
  padding: 2px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.pill-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.pill-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pill-btn:disabled { opacity: 0.5; cursor: default; }

/* ---- 部署別の横棒（Chart.js を使わず CSS で描く） ---- */
.dept-row {
  display: grid;
  grid-template-columns: minmax(11em, 12em) 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
}
.dept-name {
  font-size: 0.85rem;
  display: flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dept-swatch {
  width: 10px; height: 10px;
  border-radius: var(--r-xs);
  flex: none;
}
.dept-bar {
  height: 12px;
  border-radius: var(--r-pill);
  background: var(--panel-2);
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(23, 54, 88, 0.06);
}
/* 塗り色は JS が inline style で当てる（部署色は config.json が正）。
   ここでは形と、色に追従する発光だけを持つ。 */
.dept-bar > span {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  transition: width 0.4s ease;
  filter: saturate(1.05) drop-shadow(0 0 4px rgba(63, 195, 240, 0.25));
}
.dept-num { font-variant-numeric: tabular-nums; font-size: 0.85rem; min-width: 5.5em; text-align: right; }
.dept-chars {
  color: var(--text-muted);
  font-size: 0.72rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- 組織図（経営者→秘書室→3部署のツリー＋秘書室--点線-->顧問室。数字は持たない） ---- */
.org-top {
  display: flex;
  justify-content: center;
  margin-bottom: 0;
}
.org-top .org-box.org-owner {
  min-width: 220px;
  max-width: 320px;
  width: 100%;
}
.org-box {
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 14px;
}
.org-box-label {
  color: var(--text-muted);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}
.org-box-name { font-weight: 600; font-size: 1rem; margin-top: 2px; }
.org-box-desc { color: var(--text-muted); font-size: 0.82rem; margin-top: 4px; }
.org-box-note { color: var(--text-muted); font-size: 0.72rem; margin-top: 6px; }

/* ツリー全体。コンテナクエリで「3部署が1列に積み重なるほど狭い」かどうかを実測して
   分岐線を出し分ける（ビューポート幅ではなくこの領域自体の幅で判定するのが正確）。 */
.org-tree {
  container-type: inline-size;
  container-name: org-tree;
}

/* じゅん → 秘書室（実線、中央固定の短い縦棒） */
.org-root-line {
  width: 1.5px;
  height: 22px;
  background: var(--text-muted);
  margin: 0 auto;
}

/* 秘書室カード＋（点線）顧問室ボックスの行。顧問室は指揮系統の外＝オンデマンドの相談先なので
   実線ツリーとは見た目を区別する（点線）。接続元は秘書室（窓口経由で相談しに行くイメージ）。 */
.org-secretary-row {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0;
}
.org-secretary-row .dept-card {
  max-width: 300px;
  width: 100%;
}
.org-advisors-connector {
  flex: none;
  align-self: center;
  width: 36px;
  height: 0;
  border-top: 1.5px dashed var(--text-muted);
}
.org-secretary-row .org-box.org-advisors {
  flex: none;
  min-width: 170px;
  max-width: 230px;
  padding: 10px 12px;
}

/* 秘書室 → 開発・Zわーく・就職対策（実線、縦棒→横棒→3本の縦棒に分岐） */
.org-branch {
  position: relative;
  height: 26px;
}
.org-branch-stem {
  position: absolute;
  top: 0;
  left: 50%;
  width: 1.5px;
  height: 13px;
  background: var(--text-muted);
  transform: translateX(-50%);
}
.org-branch-bar {
  position: absolute;
  top: 13px;
  left: 16.6667%;
  right: 16.6667%;
  height: 1.5px;
  background: var(--text-muted);
}
.org-branch-drop {
  position: absolute;
  top: 13px;
  bottom: 0;
  width: 1.5px;
  background: var(--text-muted);
}
.org-branch-drop-1 { left: 16.6667%; }
.org-branch-drop-2 { left: 50%; }
.org-branch-drop-3 { left: 83.3333%; }

/* 狭い幅（実測でdept-card-gridが1列に積み重なる想定）: 横棒・分岐を消し、
   縦の1本線だけ残す。斜めの線が変な位置に残るような崩れ方を避けるため。 */
@container org-tree (max-width: 639.98px) {
  .org-branch-bar, .org-branch-drop { display: none; }
  .org-branch-stem { height: 100%; }
  .org-secretary-row { flex-direction: column; gap: 6px; }
  .org-advisors-connector {
    width: 0;
    height: 18px;
    border-top: none;
    border-left: 1.5px dashed var(--text-muted);
  }
  .org-secretary-row .dept-card,
  .org-secretary-row .org-box.org-advisors { max-width: 100%; width: 100%; }
}

.dept-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}
.dept-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 14px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  min-height: 150px;
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.dept-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.dept-card-body { min-width: 0; flex: 1 1 auto; }
.dept-card-head {
  display: flex;
  align-items: center;
  gap: 6px;
}
.dept-card-name { font-weight: 600; font-size: 0.92rem; }
.dept-card-chars { color: var(--text-muted); font-size: 0.76rem; margin-top: 4px; }
.dept-card-concern { font-size: 0.82rem; margin-top: 8px; }

/* 右＝立ち絵。height固定＋width固定＋object-fit: cover で、表示ボックス自体の横幅を
   キャラのシルエット程度に絞っている。元PNGの左右の透明余白が多くても、ボックスから
   はみ出た余白側が自然にクロップされるだけで、テキスト側（.dept-card-body）の幅は
   常に確保される。今後じゅんが画像側の余白をトリミングし直しても、単に「クロップ量が
   減る」だけで破綻しないよう、object-position は center 基準にしてある（決め打ちしすぎない）。 */
.dept-card-avatar {
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: 4px;
}
.dept-card-char-img {
  height: 140px;
  width: 76px;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* Zわーく（ミライ・つむぎ・りん）＝複数人を「主従」ではなく対等なグループとして
   横に並べ、少し重ねて1枚のカードに収める。個々の画像は1人分のカードより小さくなる。 */
.dept-card-avatar.multi {
  gap: 0;
  align-items: flex-end;
}
.dept-card-avatar.multi .dept-card-char-img {
  height: 104px;
  width: 56px;
}
.dept-card-avatar.multi .dept-card-char-img:not(:first-child) {
  margin-left: -18px;
}

/* ---- ツールランキング ---- */
.tool-row {
  display: grid;
  grid-template-columns: minmax(9em, 15em) 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 3px 0;
}
.tool-name {
  font-size: 0.82rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tool-name .mcp-tag {
  font-size: 0.66rem;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 4px;
  margin-right: 5px;
}
.tool-bar {
  height: 10px;
  border-radius: var(--r-pill);
  background: var(--panel-2);
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(23, 54, 88, 0.06);
}
.tool-bar > span {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--accent), var(--glow));
  box-shadow: 0 0 7px var(--glow-soft);
}
.tool-num { font-variant-numeric: tabular-nums; font-size: 0.82rem; min-width: 4.5em; text-align: right; }
.err-tag { color: var(--danger); font-size: 0.7rem; margin-left: 5px; }

/* ---- 統計タイル ---- */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 12px;
}
/* 統計タイル：左端に縦のLEDを立てて計器らしく見せる（数字の可読性は落とさない） */
.tile {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 10px 14px 10px 16px;
  box-shadow: var(--shadow);
  overflow: hidden;
}
.tile::before {
  content: "";
  position: absolute;
  left: 0; top: 18%; bottom: 18%;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--glow);
  box-shadow: 0 0 8px var(--glow-soft);
  opacity: 0.85;
}
.tile .tile-num { font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.tile .tile-num .tile-unit { font-size: 0.74rem; font-weight: 400; color: var(--text-muted); margin-left: 3px; }
.tile .tile-label { color: var(--text-muted); font-size: 0.74rem; }
.tile .tile-sub { color: var(--text-muted); font-size: 0.7rem; margin-top: 2px; }

/* ---- 案内板（行動が必要な項目だけaccentで縁取り、完了はtext-mutedへ沈める） ---- */
.board-tiles { margin: 8px 0 14px; }
.board-tile-badge {
  display: inline-block;
  font-size: 0.92rem;
  font-weight: 700;
  padding: 2px 12px;
  border-radius: var(--r-pill);
  margin-bottom: 4px;
}
.board-tile--attn::before {
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent-soft);
}
.board-tile--attn .board-tile-badge {
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid var(--accent);
}
.board-tile--ok { opacity: 0.72; }
.board-tile--ok::before { background: var(--text-muted); opacity: 0.35; }
.board-tile--ok .board-tile-badge {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.board-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin: 10px 0 4px;
}

/* ---- 案内板「気になるWeb」（fjc-app中継。読み取り専用・削除操作は持たない） ---- */
.web-bookmark-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 12px;
  margin: 4px 0 4px;
}
.web-bookmark-card {
  display: block;
  color: inherit;
  text-decoration: none;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: box-shadow .15s ease, transform .15s ease;
}
.web-bookmark-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.web-bookmark-thumb {
  aspect-ratio: 1.9 / 1;
  background: var(--panel-2);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.web-bookmark-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.web-bookmark-thumb--placeholder { color: var(--text-muted); font-size: 0.78rem; }
.web-bookmark-title {
  padding: 6px 9px 8px;
  font-size: 0.8rem;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* ---- 顧問室（Agency Agents カタログ） ---- */
.advisor-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 8px 0 10px;
}
.advisor-catalog-status { display: flex; align-items: center; gap: 8px; color: var(--text-muted); font-size: .76rem; }
.catalog-state-badge, .advisor-employment {
  display: inline-block;
  padding: 2px 9px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--panel-2);
  color: var(--text-muted);
  font-size: .68rem;
  white-space: nowrap;
}
.catalog-state-badge.is-present, .advisor-employment.is-active { color: var(--ok); border-color: var(--ok); }
.catalog-state-badge.is-stale { color: var(--warn); border-color: var(--warn); }
.catalog-state-badge.is-broken { color: var(--danger); border-color: var(--danger); }
.advisor-employment.is-inactive { color: var(--warn); border-color: var(--warn); }
button.advisor-employment { appearance: none; font: inherit; }
.advisor-employment.is-clickable { cursor: pointer; }
.advisor-employment.is-clickable:hover:not(:disabled) { filter: brightness(1.2); }
.advisor-employment.is-clickable:disabled { opacity: .6; cursor: default; }
.advisor-warn-banner {
  margin: 8px 0;
  padding: 9px 12px;
  border: 1px solid var(--warn);
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--warn) 8%, var(--panel));
  color: var(--warn);
  font-size: .78rem;
}
.advisor-warn-banner.is-error { color: var(--danger); border-color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, var(--panel)); }
.advisor-operation-message { margin: 8px 2px; color: var(--ok); font-size: .78rem; }
.advisor-machine-note { color: var(--text-muted); font-size: .78rem; line-height: 1.55; }
.advisor-filter-bar { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; margin: 14px 0 8px; }
.advisor-search, .advisor-domain-filter {
  font: inherit;
  font-size: .8rem;
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--panel-2);
  color: var(--text);
}
.advisor-search { flex: 1 1 15em; max-width: 25em; }
.advisor-search:focus, .advisor-domain-filter:focus { outline: none; border-color: var(--accent); box-shadow: var(--shadow-glow); }
.advisor-hired-toggle { display: inline-flex; align-items: center; gap: 5px; color: var(--text-muted); font-size: .78rem; cursor: pointer; }
.advisor-result-count { margin: 0 2px 7px; color: var(--text-muted); font-size: .72rem; text-align: right; }
.advisor-empty { padding: 22px; border: 1px dashed var(--border); border-radius: var(--r-md); color: var(--text-muted); text-align: center; font-size: .82rem; }
.advisor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
  margin: 10px 0 20px;
}
.advisor-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 14px 16px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.advisor-card.is-active { border-color: color-mix(in srgb, var(--ok) 45%, var(--border)); }
.advisor-card.is-inactive { border-color: color-mix(in srgb, var(--warn) 35%, var(--border)); }
.advisor-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.advisor-card-names { min-width: 0; }
.advisor-card-name { font-weight: 600; font-size: 0.95rem; }
.advisor-card-name-en { margin-top: 2px; color: var(--text-muted); font-size: .68rem; overflow-wrap: anywhere; }
.advisor-card-domain { color: var(--text-muted); font-size: 0.78rem; margin-top: 2px; }
.advisor-card-desc { font-size: 0.84rem; margin-top: 10px; line-height: 1.5; }
.advisor-original { margin-top: 9px; color: var(--text-muted); font-size: .72rem; }
.advisor-original summary { cursor: pointer; }
.advisor-original p { margin: 6px 0 0; line-height: 1.5; }
.advisor-call-name { margin-top: 9px; color: var(--text-muted); font-family: monospace; font-size: .72rem; overflow-wrap: anywhere; }
.advisor-card-actions { display: flex; align-items: center; justify-content: flex-end; min-height: 27px; margin-top: auto; padding-top: 12px; }
.advisor-card-source {
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  overflow-wrap: anywhere;
}

/* ---- 社員名簿（社員／道具の二軸） ---- */
.axis-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin: 16px 0 4px; }
.axis-tabs button {
  font: inherit;
  font-size: 0.84rem;
  padding: 5px 16px;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-muted);
  border-radius: var(--r-pill) var(--r-pill) 0 0;
  border-bottom: none;
  cursor: pointer;
}
.axis-tabs button.active {
  background: var(--panel);
  color: var(--text);
  font-weight: 600;
  box-shadow: inset 0 3px 0 var(--glow), 0 -4px 12px -6px var(--glow-soft);
}

.roster-filters {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  margin: 10px 0 14px;
}
.dept-tabs { display: flex; gap: 5px; flex-wrap: wrap; }
.dept-tabs button {
  font: inherit;
  font-size: 0.75rem;
  padding: 2px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-muted);
  cursor: pointer;
}
.dept-tabs button:hover { color: var(--accent); border-color: var(--accent); }
.dept-tabs button.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--shadow-glow);
}

.roster-search {
  font: inherit;
  font-size: 0.8rem;
  padding: 4px 12px;
  min-width: 12em;
  flex: 1 1 12em;
  max-width: 22em;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--panel-2);
  color: var(--text);
}
.roster-search:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--shadow-glow);
}

.staff-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 12px;
}
/* 社員名簿（roster-grid）は「列を増やすより立ち絵を大きく」優先で最大2列に固定
   （じゅんのフィードバック 2026-07-23）。道具タブは数が多く列を増やしたいケースが
   あるため .staff-grid 自体は auto-fill のまま変えず、社員名簿の描画時だけ
   このクラスを足して上書きする。
   auto-fit + 各列 minmax(max(340px, 50%弱), 1fr) で「列は必ずコンテナ幅の約半分以上」
   にし、構造的に3列目が入り込めないようにしている。50%ちょうどをminにすると
   浮動小数点の丸めでブラウザが3列と判定するリスクがあるため、gap(12px)より広い
   10pxを引いて安全マージンを確保した（2列合計は100%-8pxに収まり、3列分の幅は
   必ずコンテナ幅を超える）。340pxは画面が狭いときに1列へ落ちる下限（既存の
   .staff-card-avatar 用560pxブレークポイントの縮小挙動と両立する）。 */
.roster-grid {
  grid-template-columns: repeat(auto-fit, minmax(max(340px, 50% - 10px), 1fr));
}
.staff-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 14px 10px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: stretch;
  gap: 10px;
  min-width: 0;
  transition: box-shadow 0.18s ease, border-color 0.18s ease;
}
.staff-card:hover { box-shadow: var(--shadow-lg); border-color: var(--border-strong); }
.staff-card.retired, .staff-card.never { opacity: 0.62; }

.staff-card-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  flex: 1 1 auto;
}

/* 右＝立ち絵（smile.png 優先・無ければ sd.png）。avatarUrl が無い社員（ツール・キャラなし
   スキル）は右カラムごと出さない。
   ★ 固定px幅＋object-fit: cover だと、.staff-grid が auto-fill/minmax で列数に応じて
   カード幅が伸縮するとき「同じ列数の範囲内では伸びるがクロップ量は固定のまま」→
   「列が増えた瞬間にカード幅が戻ってまたクロップされる」を繰り返し、2列⇔3列の境界
   付近でキャラの頭や手足が切れる不具合が出た（実機フィードバックで発覚）。
   → 「なるべく大きく」より「絶対に切れない」を優先し、表示エリア幅を固定pxではなく
   flex-basis の割合（カードの約40%）にしてカード幅の変化に比率で追従させ、
   画像は object-fit: contain で幅・高さどちらの制約でも必ず全身が収まるようにした。
   透明余白は表示エリア内で吸収されるだけなので、テキスト側の幅（.staff-card-body の
   残り約60%）は列数が変わっても圧迫されない。 */
.staff-card-avatar {
  flex: 0 0 40%;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  align-self: stretch;
}
.staff-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  display: block;
}

.staff-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.staff-name {
  font-weight: 600;
  font-size: 0.95rem;
  min-width: 0;
  overflow-wrap: anywhere;
}
.kind-badge {
  flex: none;
  font-size: 0.65rem;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  padding: 0 7px;
  white-space: nowrap;
}
.health {
  font-size: 0.64rem;
  border-radius: var(--r-pill);
  padding: 1px 7px;
  margin-left: 6px;
  border: 1px solid var(--border);
  color: var(--text-muted);
  white-space: nowrap;
  font-weight: 400;
  vertical-align: middle;
}
.health.active {
  color: var(--ok);
  border-color: var(--ok);
  background: color-mix(in srgb, var(--ok) 10%, transparent);
}
.health.retired { color: var(--text-muted); }

.staff-meta {
  font-size: 0.75rem;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
.staff-desc { font-size: 0.8rem; }

.trigger-box { display: flex; flex-wrap: wrap; gap: 4px; align-items: baseline; }
.trigger-label {
  font-size: 0.68rem;
  color: var(--text-muted);
  margin-right: 2px;
  flex: none;
}
.trigger-tag {
  font-size: 0.72rem;
  border: 1px solid var(--border);
  background: var(--panel-2);
  border-radius: var(--r-xs);
  padding: 0 6px;
  overflow-wrap: anywhere;
}

.staff-activity {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  border-top: 1px solid var(--border);
  padding-top: 8px;
}
.spark-wrap { min-width: 0; flex: 1 1 120px; }
.spark { width: 100%; height: 28px; display: block; }
.spark rect { fill: var(--accent); rx: 1.5px; }
.spark-cap { color: var(--text-muted); font-size: 0.66rem; margin-top: 2px; }
.staff-nums {
  font-size: 0.78rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
  flex: none;
}
.staff-nums .note { margin: 0; }

.recent-box { border-top: 1px solid var(--border); padding-top: 6px; }
.recent-label { font-size: 0.68rem; color: var(--text-muted); margin-bottom: 2px; }
.recent-row {
  display: grid;
  grid-template-columns: 5.6em 1fr auto;
  gap: 6px;
  font-size: 0.74rem;
  padding: 1px 0;
  align-items: baseline;
}
.recent-when { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.recent-what { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recent-num { color: var(--text-muted); font-variant-numeric: tabular-nums; }

.staff-foot {
  font-size: 0.7rem;
  color: var(--text-muted);
  border-top: 1px solid var(--border);
  padding-top: 6px;
  margin-top: auto;
}
.staff-foot .note { margin: 2px 0 0; }

/* ---- 司書室カード ---- */
.rooms-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}
.room-card {
  position: relative;
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 14px;
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
/* ホバーで下端のLEDが灯る（＝押せることの合図） */
.room-card::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--glow-line);
  opacity: 0;
  transition: opacity 0.18s ease;
}
.room-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}
.room-card:hover::after { opacity: 1; }
.room-card.disabled { opacity: 0.55; pointer-events: none; }
.room-card .room-name { font-weight: 600; font-size: 0.9rem; }
.room-card .room-desc { color: var(--text-muted); font-size: 0.76rem; margin-top: 2px; }

/* ==========================================================================
   アイソメ図オフィス（/office.html）
   ★ 部署色はここに書かない。JS が --zone-color として注入する（冒頭の規約）。
   ★ ステージ内は全部 % 配置。JS でのリサイズ計算を持たないため、横スクロールが
      構造的に発生しない。ステージ幅の 1% は cqw（container-type: size）で取れる。
   ========================================================================== */
.office-card { padding: 10px; }

.office-stage-wrap {
  position: relative;
}

/* JSが中身を作り直さない「額縁」。アスペクト比の計算はここに集約し、
   .office-stage は常にこの100%を占めるだけにする（通常表示・全画面共通）。
   ★ Fullscreen API の仕様上、フルスクリーンにした要素（office-stage-wrap）
     自身の width/height/margin はブラウザに強制上書きされ、CSSでは縮小できない
     （inline style + !important でも上書き不可なことを実機で確認済み）。
     だからレターボックスのサイズ計算は「フルスクリーン要素の子」である
     office-stage-frame 側で行う。 */
.office-stage-frame {
  position: relative;
  width: 100%;
  --stage-w: 1672;   /* JSが背景の実寸（config.jsonのbackground）で上書きする */
  --stage-h: 941;
  aspect-ratio: var(--stage-w) / var(--stage-h);
}
.office-stage-frame .office-stage { width: 100%; height: 100%; }

/* ステージ：背景画像が主役なので、枠は「絵の縁に光が回っている」程度に留める。
   角丸を大きめ（--r-md）に取って、絵の中の什器のRと揃える。 */
.office-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 1672 / 941;      /* JS が背景の実寸で上書きする（index.html埋め込み用のフォールバック） */
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--panel-2);
  container-type: size;
  box-shadow:
    inset 0 0 0 1px var(--glass-border),
    inset 0 0 24px -12px rgba(63, 195, 240, 0.55);
}

/* ---- 全画面表示ボタン（office.html固有。ステージ右下に薄い半透明で常時表示） ---- */
.office-fullscreen-btn {
  position: absolute;
  right: 10px;
  bottom: 10px;
  z-index: 5;
  width: 32px;
  height: 32px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 背景が白い1枚絵なので、ボタン側も白ガラスにして絵から浮かせない
     （旧: 濃いグレーの半透明。白基調のオフィスの上では黒い染みに見えた） */
  border-radius: var(--r-sm);
  border: 1px solid rgba(255, 255, 255, 0.85);
  background: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: #1d2a3a;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
.office-fullscreen-btn:hover,
.office-fullscreen-btn:focus-visible {
  opacity: 1;
  background: rgba(255, 255, 255, 0.85);
  box-shadow: 0 0 0 1px rgba(63, 195, 240, 0.55), 0 4px 14px -6px rgba(63, 195, 240, 0.8);
}
.office-fullscreen-btn svg { display: block; pointer-events: none; }

/* ミュートボタン：全画面ボタンと同じ見た目（.office-fullscreen-btn）を共有し、
   位置だけ「そのすぐ左」にずらす（32px幅 + 10px間隔）。 */
.office-mute-btn { right: 52px; }

/* 全画面中: office-stage-wrap 自体は上記の理由でブラウザに画面いっぱいへ強制される
   ので、黒い額縁として使うだけにする。実際のレターボックス（アスペクト比維持）は
   子の office-stage-frame に対して絶対配置＋margin:autoの中央寄せで行う。
   ★ % 座標が背景画像と1:1で対応する前提（★追記15）を崩さないよう、
     stretch/coverでの歪みは避け、アスペクト比維持のレターボックス方式にする。 */
.office-stage-wrap:fullscreen,
.office-stage-wrap:-webkit-full-screen {
  background: #000;
}
.office-stage-wrap:fullscreen::backdrop { background: #000; }

.office-stage-wrap:fullscreen .office-stage-frame,
.office-stage-wrap:-webkit-full-screen .office-stage-frame {
  position: absolute;
  inset: 0;
  margin: auto;
  width: min(100vw, calc(100vh * var(--stage-w) / var(--stage-h)));
  height: min(100vh, calc(100vw * var(--stage-h) / var(--stage-w)));
}
.office-stage-wrap:fullscreen .office-stage,
.office-stage-wrap:-webkit-full-screen .office-stage {
  border-radius: 0;
}
.office-stage-wrap:fullscreen .office-fullscreen-btn,
.office-stage-wrap:-webkit-full-screen .office-fullscreen-btn {
  right: 18px;
  bottom: 18px;
}
.office-stage-wrap:fullscreen .office-mute-btn,
.office-stage-wrap:-webkit-full-screen .office-mute-btn {
  right: 60px;
  bottom: 18px;
}

/* 絶対配置にして、背景画像の実寸がステージの高さに影響しないようにする
   （aspect-ratio だけだと中身の高さに引きずられて縦に伸びる） */
.office-bg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  user-select: none;
  -webkit-user-drag: none;
}

.office-zone { position: absolute; inset: 0; pointer-events: none; }

/* ---- ゾーン看板（絵には焼き込まない。部署名が変わっても config だけで済む） ---- */
.office-sign {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
  padding: 2px 11px;
  border-radius: var(--r-pill);
  /* ★ 看板の色はテーマ変数を使わず固定にする。
     背景の office.png は常に明るい白基調なので、ダークテーマで --panel を
     使うと「白い絵の上に濃紺のピル」になって絵から浮く。看板が載る面は
     テーマではなく画像で決まるため、白ガラス＋濃い文字で固定する
     （この面に限りコントラストは常に確保される）。 */
  border: 1px solid rgba(255, 255, 255, 0.9);
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: saturate(1.3) blur(6px);
  backdrop-filter: saturate(1.3) blur(6px);
  color: #1d2a3a;
  box-shadow: 0 1px 6px rgba(30, 45, 70, 0.22);
  font-size: clamp(9px, 1.02cqw, 13px);
  line-height: 1.7;
  cursor: help;
}
.office-sign-dot {
  width: 0.62em; height: 0.62em;
  border-radius: 50%;
  flex: none;
  background: var(--zone-color);
}
.office-sign-label { font-weight: 600; }
/* 看板の面が固定色（白ガラス）なので、副次テキストの色も固定にする
   ＝ --text-muted をダークで拾って白地に薄灰が載る事故を防ぐ */
.office-sign-state { color: #5a6b80; font-size: 0.86em; }
.office-sign-sub { color: #5a6b80; font-size: 0.8em; }

/* ステージが狭いと看板同士が重なる。担当キャラ名（副題）から先に落とす
   （部署名と状態は落とさない＝この画面の要件そのものなので） */
@container (max-width: 620px) {
  .office-sign-sub { display: none; }
  .office-sign { padding: 1px 6px; gap: 3px; }
}

/* 稼働中：看板を部署色で縁取りして光らせる。
   既存の @keyframes fjpulse（稼働パネルのドット）は書き換えずに別名で足す。 */
.office-zone[data-state="active"] .office-sign {
  border-color: var(--zone-color);
  animation: office-glow 2.6s ease-out infinite;
}
.office-zone[data-state="active"] .office-sign-state {
  color: var(--zone-color);
  font-weight: 600;
}
.office-zone[data-state="active"] .office-sign-dot {
  box-shadow: 0 0 6px var(--zone-color);
}
/* 波紋（元からの表現）に、什器のLEDと同じ「にじむ光」を重ねる。
   影の1段目は看板を絵から浮かせるための固定の落ち影で、これは残す。 */
@keyframes office-glow {
  0%   { box-shadow: 0 1px 6px rgba(30, 45, 70, 0.22), 0 0 6px 0 transparent,   0 0 0 0 var(--zone-color); }
  70%  { box-shadow: 0 1px 6px rgba(30, 45, 70, 0.22), 0 0 12px 0 var(--zone-color), 0 0 0 7px transparent; }
  100% { box-shadow: 0 1px 6px rgba(30, 45, 70, 0.22), 0 0 6px 0 transparent,   0 0 0 0 transparent; }
}

/* 待機：色は残すが光らない */
.office-zone[data-state="idle"] .office-sign-dot { opacity: 0.45; }

/* 計測なし：idle と見た目を分ける。破線＋灰ドットで「取っていない」ことを示す
   （取れないデータを取れているように見せない） */
.office-zone[data-state="nodata"] .office-sign {
  border-style: dashed;
  opacity: 0.8;
}
.office-zone[data-state="nodata"] .office-sign-dot {
  background: transparent;
  border: 1px dashed #5a6b80;
}
.office-zone[data-state="nodata"] .office-sign-label { color: #5a6b80; font-weight: 400; }

/* ---- キャラ ----
   2階層に分けて変形の責務を混ぜない:
     .office-char      … 徘徊（transform / translateX）
     .office-char-body … 浮遊（translate）＋ 左右反転（scale）
   translate / scale は transform とは別プロパティなので、同じ要素で
   2つのアニメを重ねても打ち消し合わない。 */

/* ★ --wander-x を型登録（<length>）して transition 対象にする。
   理由: office-wander の 0%/100%（静止区間）は両方とも
   calc(-50% - var(--wander-x)) という「同じ式」を参照しているだけで、
   ブラウザは各フレームで --wander-x の"現在値"を都度読みに行く（キーフレーム間の
   補間値としてキャッシュされない）。そのため office.js が周回終了時
   （animationiteration）に --wander-x を書き換えると、書き換えの前後で
   同じ式の解決結果が瞬時に変わり、位置が一瞬でジャンプする（実機で確認済み。
   NEXT-SESSION.md ★追記13参照）。
   型登録してこの transition を効かせると、--wander-x 自体の値がなめらかに
   遷移するようになり、office-wander 側のキーフレーム（0%/8%/42%/58%/92%/100%の
   タイミング・duration・delay）は一切変更せずに済む（office-face と共有している
   ため、ここは変えられない）。 */
@property --wander-x {
  syntax: "<length>";
  inherits: false;
  /* initial-value は "computationally independent" でなければならない仕様上の制約により、
     cqw 等の相対単位は使えない（実機で CSS.registerProperty が
     "not computationally independent" で拒否されることを確認済み）。
     実際の値は office.js が buildChar() で必ず即座に上書きするので、
     ここは固定の絶対単位（0px）でよい。 */
  initial-value: 0px;
}
.office-char {
  position: absolute;
  /* アンカー（left/top）は待機中の徘徊帯が基準。稼働中は --seat-left/--seat-top
     （config.json の chars[].seat）に切り替わる。座っていることが未設定のキャラは
     待機時のアンカーのまま（フォールバック）。 */
  left: var(--idle-left, 50%);
  top: var(--idle-top, 50%);
  /* data-state の切り替え（＝椅子に座る/離れる）だけは滑らかに動かす。
     徘徊アニメ本体（transform）とは別プロパティなので打ち消し合わない。
     --wander-x の transition は上の @property registration とセットで、
     周回ごとの再抽選をジャンプさせずに反映するための仕組み（★追記13）。 */
  transition: left 0.6s ease, top 0.6s ease, transform 0.6s ease, --wander-x 0.6s ease-in-out;
  /* 足元（画像下端の透明余白 --foot ぶん押し下げ）を rect の中心線に合わせる */
  transform: translate(-50%, calc(-100% + var(--foot, 0%)));
  will-change: transform;
  /* 待機中は帯の中を歩き回る。JSのタイマーは使わない（止めるのが1行で済む・
     タブ非表示中はブラウザが間引く・setInterval が積み上がる事故が起きない）
     ★ X（左右）と Y（上下）を別アニメ・別プロパティに分離している。
       X は transform（office-wander）で、office-face（向きの反転）と
       duration/delay を共有する ＝ 進行方向と向きが原理的にズレない仕組み（追記11で検証済み）
       なので形・速さとも変えない。
       Y は translate（transform とは別プロパティなので打ち消し合わない）で、
       X とは完全に独立した周期・遅延・経路パターン（--wander-y-anim）を持つ。
       単純な往復に見えないようにするための分離で、JS（office.js buildChar）が
       キャラごとに --wander-x/-y の振幅・--wander-dur/-y-dur を rand() で散らし、
       さらに周回終了（animationiteration）のたびに再抽選する（DOM再構築はしない）。 */
  animation-name: office-wander, var(--wander-y-anim, office-wander-y);
  animation-duration: var(--wander-dur, 12s), var(--wander-y-dur, 10s);
  animation-timing-function: ease-in-out, ease-in-out;
  animation-delay: var(--wander-delay, 0s), var(--wander-y-delay, 0s);
  animation-iteration-count: infinite, infinite;
}
.office-char-body {
  display: block;
  height: 100%;
  width: auto;
  user-select: none;
  -webkit-user-drag: none;
  filter: drop-shadow(0 3px 4px rgba(30, 45, 70, 0.28));
  /* translate / scale は transform とは別プロパティなので、
     浮遊と左右反転を同じ要素に重ねても打ち消し合わない */
  animation:
    office-float var(--float-dur, 2.8s) ease-in-out var(--float-delay, 0s) infinite,
    office-face var(--wander-dur, 12s) step-end var(--wander-delay, 0s) infinite;
  animation-play-state: paused, running;   /* 既定（待機）は浮遊しない */
}

/* 台形の徘徊（X＝左右のみ）: 進む → 止まる → 戻る → 止まる。
   office-face と同じ breakpoints（8/42/58/92%）・duration・delay を共有するので、
   向きの反転タイミングと移動方向が必ず一致する（このアニメの形・速さは変えないこと）。
   移動幅は cqw（ステージ幅の1%）なので、画面のサイズが変わっても比率が崩れない。 */
@keyframes office-wander {
  0%, 8%    { transform: translate(calc(-50% - var(--wander-x, 2cqw)), calc(-100% + var(--foot, 0%))); }
  42%, 58%  { transform: translate(calc(-50% + var(--wander-x, 2cqw)), calc(-100% + var(--foot, 0%))); }
  92%, 100% { transform: translate(calc(-50% - var(--wander-x, 2cqw)), calc(-100% + var(--foot, 0%))); }
}
/* Y（上下）専用。X（office-wander）とは無関係な duration/delay で回るので、
   単純な左右往復＋固定の上下往復には見えない。translate プロパティなので
   transform（office-wander）を打ち消さずに重なる。
   2パターン用意し、JS（office.js）がキャラごと・周回ごとにどちらを使うか
   （--wander-y-anim）を抽選する。
   ★ 境界（0%/100%、および静止区間）は必ず固定値 `0`（--wander-y を一切参照しない）。
   周回終了時に animation-name（パターンA⇄B）と --wander-y の値を同時に再抽選しても、
   両パターンとも境界は「0」で一致するため、パターンが変わっても・振幅が変わっても
   境界をまたぐ位置は不連続にならない（実測でジャンプを確認したので、この形にした。
   NEXT-SESSION.md ★追記13参照）。振幅（--wander-y）は中間キーフレームだけで使う。 */
@keyframes office-wander-y {
  0%, 15%   { translate: 0 0; }
  50%, 65%  { translate: 0 var(--wander-y, 0cqh); }
  100%      { translate: 0 0; }
}
@keyframes office-wander-y-b {
  0%, 20%   { translate: 0 0; }
  55%, 75%  { translate: 0 calc(-1 * var(--wander-y, 0cqh)); }
  100%      { translate: 0 0; }
}
/* 向き。徘徊と同じ duration / delay で回すので、移動と向きが原理的にズレない。
   元絵は左向きなので、右へ進む区間（wanderの0-42%寄り）で反転させて進行方向を向かせる。 */
@keyframes office-face {
  0%   { scale: -1 1; }
  50%  { scale: 1 1; }
  100% { scale: -1 1; }
}
@keyframes office-float {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -6%; }
}

/* 稼働中: 徘徊アニメを止め、椅子の位置（--seat-left/--seat-top。無ければ待機時の
   アンカーのまま）にぴったり止まらせてから、その場で上下にふわふわさせる。
   animation: none にしているのは「動きを止める」ボタンの一時停止とは別の話で、
   ここは意図して椅子の定位置へワープさせる（＝待機中の徘徊とは別の状態への遷移）ため。 */
.office-zone[data-state="active"] .office-char {
  left: var(--seat-left, var(--idle-left, 50%));
  top: var(--seat-top, var(--idle-top, 50%));
  animation: none;
  transform: translate(-50%, calc(-100% + var(--foot, 0%)));
  translate: none;   /* Y徘徊（office-wander-y系）のtranslate残留を明示的にクリア */
}
.office-zone[data-state="active"] .office-char-body { animation-play-state: running, paused; }

/* 「動きを止める」。animation: none にはしない（全員が原点にワープして
   リセットに見えるため）。paused なら今いる場所で止まる。 */
.office-stage[data-motion="off"] .office-char,
.office-stage[data-motion="off"] .office-char-body,
.office-stage[data-motion="off"] .office-sign {
  animation-play-state: paused !important;
}

/* OSの「視差効果を減らす」が有効なら既定で止める。
   明示的に「動きを再開」した場合（data-motion="on"）だけ動かす。 */
@media (prefers-reduced-motion: reduce) {
  .office-stage:not([data-motion="on"]) .office-char,
  .office-stage:not([data-motion="on"]) .office-char-body,
  .office-stage:not([data-motion="on"]) .office-sign {
    animation-play-state: paused !important;
  }
}
/* 接地感（足元の影）。床に立っているように見せるためだけの飾り */
.office-char::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: var(--foot, 0%);
  width: 62%;
  height: 8%;
  transform: translate(-50%, 40%);
  background: radial-gradient(ellipse at center, rgba(30, 45, 70, 0.42), rgba(30, 45, 70, 0) 68%);
}

/* ---- 発言の吹き出し（直近の一言。config.json の office.speech_window_minutes 以内だけ表示） ----
   .office-char（wrap）の子にしているので、待機中の徘徊・稼働中の椅子アンカーへの追従は
   wrap 自体の transition/transform に自動で乗る（ここで座標計算はしない）。
   ★ .office-sign と同じ理由で固定色にする。背景の office.png は常に明るい白基調なので、
     テーマ変数（--panel 等）を使うとダークで「白い絵の上に濃紺の吹き出し」になって浮く。 */
.office-bubble {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translate(-50%, -8px);
  max-width: min(150px, 34cqw);
  width: max-content;
  padding: 5px 9px;
  border-radius: var(--r-sm);
  border: 1px solid rgba(255, 255, 255, 0.9);
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: saturate(1.3) blur(6px);
  backdrop-filter: saturate(1.3) blur(6px);
  color: #1d2a3a;
  box-shadow: 0 2px 8px rgba(30, 45, 70, 0.28);
  font-size: clamp(9px, 0.98cqw, 12px);
  line-height: 1.4;
  text-align: left;
  overflow-wrap: anywhere;
  pointer-events: none;
  z-index: 4;
}
.office-bubble[hidden] { display: none; }
/* 吹き出しの尻尾（キャラを指す小さい三角） */
.office-bubble::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: rgba(255, 255, 255, 0.92);
  filter: drop-shadow(0 1px 1px rgba(30, 45, 70, 0.15));
}

/* ==========================================================================
   座標編集モード（/office.html?cal=1 のときだけ）
   ★ ここのセレクタは全部 .office-cal* / .office-edit* で始まる。これらの要素は
      JS が CAL のときしか生成しないので、通常の /office.html・/（index.html埋め込み）
      には一切影響しない。
   ★ .office-zone は pointer-events: none なので、掴ませたい要素だけ auto に戻す。
   ========================================================================== */
.office-cal-rect {
  position: absolute;
  border: 1px dashed var(--zone-color);
  background: color-mix(in srgb, var(--zone-color) 12%, transparent);
  pointer-events: auto;
  cursor: move;
  touch-action: none;      /* ドラッグ中にスクロール/ズームへ取られないように */
}
.office-cal-rect:hover { background: color-mix(in srgb, var(--zone-color) 22%, transparent); }
.office-cal-tag {
  position: absolute;
  top: -1.2em;
  left: 0;
  font-size: 10px;
  color: var(--zone-color);
  background: var(--panel);
  padding: 0 3px;
  border-radius: 3px;
  pointer-events: none;
}
.office-cal-cross {
  position: absolute;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  background:
    linear-gradient(var(--zone-color), var(--zone-color)) center/100% 1px no-repeat,
    linear-gradient(var(--zone-color), var(--zone-color)) center/1px 100% no-repeat;
  pointer-events: auto;
  cursor: move;
  touch-action: none;
  /* 見た目は十字のままで、掴める範囲だけ広げる */
  outline: 6px solid transparent;
}

/* 椅子（稼働中にキャラが座る位置）のマーカー */
.office-cal-seat {
  position: absolute;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  border: 2px solid var(--zone-color);
  background: color-mix(in srgb, var(--zone-color) 35%, transparent);
  pointer-events: auto;
  cursor: move;
  touch-action: none;
  z-index: 3;
}
.office-cal-seat-tag {
  position: absolute;
  left: 50%;
  top: -1.35em;
  transform: translateX(-50%);
  font-size: 10px;
  white-space: nowrap;
  color: var(--zone-color);
  background: var(--panel);
  padding: 0 3px;
  border-radius: 3px;
  pointer-events: none;
}

/* 角・辺のリサイズハンドル（8個。dir で位置とカーソルを出し分ける） */
.office-cal-h {
  position: absolute;
  width: 9px;
  height: 9px;
  margin: -5px 0 0 -5px;
  border: 1px solid var(--panel);
  background: var(--zone-color);
  border-radius: 2px;
  pointer-events: auto;
  touch-action: none;
  z-index: 2;
}
.office-cal-h[data-dir="nw"] { left: 0;    top: 0;    cursor: nwse-resize; }
.office-cal-h[data-dir="n"]  { left: 50%;  top: 0;    cursor: ns-resize; }
.office-cal-h[data-dir="ne"] { left: 100%; top: 0;    cursor: nesw-resize; }
.office-cal-h[data-dir="w"]  { left: 0;    top: 50%;  cursor: ew-resize; }
.office-cal-h[data-dir="e"]  { left: 100%; top: 50%;  cursor: ew-resize; }
.office-cal-h[data-dir="sw"] { left: 0;    top: 100%; cursor: nesw-resize; }
.office-cal-h[data-dir="s"]  { left: 50%;  top: 100%; cursor: ns-resize; }
.office-cal-h[data-dir="se"] { left: 100%; top: 100%; cursor: nwse-resize; }

/* 選択中・ドラッグ中がひと目で分かるように */
.office-cal-rect.is-sel { border-style: solid; border-width: 2px; }
.office-cal-cross.is-sel,
.office-cal-seat.is-sel { box-shadow: 0 0 0 3px color-mix(in srgb, var(--zone-color) 45%, transparent); }
.office-cal-rect.is-drag,
.office-cal-cross.is-drag,
.office-cal-seat.is-drag { opacity: 0.75; }

/* ---- 編集バー（ステージの上）---- */
.office-edit { margin-bottom: 8px; }
.office-edit-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 1px solid var(--accent);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--accent) 10%, var(--panel));
  font-size: 0.78rem;
}
.office-edit-badge {
  font-weight: 700;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--r-pill);
  padding: 1px 9px;
  white-space: nowrap;
}
.office-edit-sel {
  font-variant-numeric: tabular-nums;
  color: var(--text);
  flex: 1 1 260px;
  min-width: 0;
}
.office-edit-dirty {
  color: var(--danger);
  font-weight: 600;
  white-space: nowrap;
}
.office-edit-msg { color: var(--text-muted); flex-basis: 100%; }
.office-edit-msg.is-err { color: var(--danger); }
.office-edit-hint {
  margin-top: 4px;
  color: var(--text-muted);
  font-size: 0.72rem;
  line-height: 1.6;
}
.pill-btn.is-primary { border-color: var(--accent); color: var(--accent); }
.pill-btn.is-danger { border-color: var(--danger); color: var(--danger); }
.pill-btn.is-danger:hover:not(:disabled) {
  border-color: var(--danger);
  color: var(--danger);
  background: color-mix(in srgb, var(--danger) 9%, var(--panel));
}
.office-cal-readout {
  position: absolute;
  left: 8px;
  top: 8px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 4px 8px;
}

/* ---- キャンバス（時間帯の波） ---- */
.canvas-wrap { position: relative; height: 210px; }

/* ---- エラー表示（画面は空にしない） ---- */
.inline-error {
  color: var(--danger);
  font-size: 0.78rem;
  margin-top: 6px;
}

/* 稼働パネルとオフィスにだけ残っている集計メタ表示用。
   「← 稼働パネルに戻る」だけのフッターは 2026-08-30 に4ページから削除した
   （ヘッダーnavの「稼働」と重複していたため）。下の余白も詰めてある。 */
.app-footer {
  color: var(--text-muted);
  font-size: 0.75rem;
  text-align: center;
  padding: 6px 24px 12px;
}
.app-footer a { color: var(--text-muted); text-decoration: none; }
.app-footer a:hover { color: var(--accent); text-decoration: underline; }

.toggle-group {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border-radius: var(--r-pill);
  background: var(--panel-2);
  border: 1px solid var(--border);
}
.toggle-group button {
  font: inherit;
  font-size: 0.76rem;
  padding: 2px 12px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
.toggle-group button:hover { color: var(--accent); background: var(--panel); }
.toggle-group button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.toggle-group button.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--shadow-glow);
}

/* ==========================================================================
   狭い幅（VS Code のサイドバー webview / iframe 埋め込み）
   ★ 横スクロールを出さないことを最優先にする。ナビのピル群は折り返す。
   ========================================================================== */
@media (max-width: 560px) {
  header.app-header { padding: 7px 14px 8px; }
  header.app-header h1 { font-size: 1rem; }
  nav.app-nav { flex-wrap: wrap; row-gap: 3px; }
  /* 狭い幅では nav のピルを詰めて、折り返す前に収まる幅を稼ぐ */
  nav.app-nav a { padding: 4px 9px; font-size: 0.8rem; }
  main, .wrap { padding-left: 12px; padding-right: 12px; }
  .card { padding: 13px 13px; border-radius: var(--r-md); }
  .card::before { left: 12px; right: 12px; }
  /* 1カラムに落とす（minmax の下限が効いて溢れるのを防ぐ） */
  .chart-grid { grid-template-columns: 1fr; }
  .dept-row { grid-template-columns: minmax(7em, 9em) 1fr auto; gap: 8px; }
  .tool-row { grid-template-columns: minmax(6em, 10em) 1fr auto; gap: 8px; }
  /* 狭い幅ではカードが窮屈になるので立ち絵も一回り縮める */
  .dept-card { min-height: 0; }
  .dept-card-char-img { height: 92px; width: 52px; }
  .dept-card-avatar.multi .dept-card-char-img { height: 68px; width: 40px; }
  .dept-card-avatar.multi .dept-card-char-img:not(:first-child) { margin-left: -12px; }
  /* 狭い幅（.staff-grid が1列に落ちてカード幅が広くなる）では40%だと立ち絵が
     大きくなりすぎるので比率を少し下げる。contain なので上限を超えても切れはしない。 */
  .staff-card-avatar { flex-basis: 32%; }
}

/* ==========================================================================
   中間幅（VS Code パネルの実利用幅。実測で狭くても500〜800px程度と判明）。
   利用枠バーは各グループが flex-wrap で自然に2段へ折り返るので、ここでは
   間隔を少し詰めるだけでよい（720px程度で2グループ目以降が折り返る）。
   ========================================================================== */
@media (max-width: 860px) {
  .limits-bar { gap: 6px 18px; }
  .limits-row { grid-template-columns: 1.6em minmax(48px, 1fr) max-content; }
}

/* ==========================================================================
   さらに狭い幅（スマホ相当・480px以下）
   ★ 利用枠バーは「1グループ1行の縦積み」に組み替え、グループ間を区切り線で
      分ける（横並びのままだと数値・キャプションが窮屈になるため）。
   ========================================================================== */
@media (max-width: 480px) {
  .limits-bar { flex-direction: column; align-items: stretch; gap: 0; }
  .limits-group {
    /* .limits-bar が column 方向になるので、基本ルールの flex-basis(220px) が
       高さ側に効いてしまわないよう明示的に打ち消す（幅は width:100% で確定済み）。 */
    flex: none;
    width: 100%;
    padding: 7px 0;
    border-top: 1px solid var(--border);
  }
  .limits-group:first-of-type { border-top: none; padding-top: 0; }
  .limits-row { grid-template-columns: 1.6em minmax(0, 1fr) max-content; }
  .limits-row-wrap { min-width: 0; width: 100%; }
}

/* ==========================================================================
   動きの抑制（OSの「視差効果を減らす」）
   ★ office.js が使う data-motion の仕組み（.office-stage 側）は別に定義済みで、
      ここでは「装飾のためだけの常時アニメーション」を止める。
      稼働中かどうかは色と発光の有無で読めるので、止めても情報は失われない。
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .live-dot,
  .live-dot.pulse { animation: none; }
  .limits-row-fill { animation: none; }
  .dept-card:hover,
  .room-card:hover { transform: none; }
  .header-reload-btn.is-spinning svg { animation: none; }
  * { scroll-behavior: auto; }
}

/* ==========================================================================
   支援会議再生（static/js/meeting-player.js）
   ★ 実キャラ（ミライ・つむぎ・りん）を支援会議ゾーンへ一時的に移動させるだけで、
      DOMの再構築・専用の立ち絵パネルは持たない（office.js側の「DOM初回1回構築」
      規約を守るため。詳細は NEXT-SESSION.md ★追記42）。
   ========================================================================== */

/* 会議再生中、実キャラの座標を支援会議ゾーンへ一時的に上書きする。
   .office-zone[data-state="active"] .office-char（通常の稼働中スタイル）より
   優先させる必要があるため !important を使う（UIモードの明示的な一時上書きという
   狭いスコープなので許容する）。meeting-player.js が data-meeting 属性と
   --meeting-left/--meeting-top を出し入れするだけで、DOM要素そのものは動かさない。 */
.office-char[data-meeting="1"] {
  left: var(--meeting-left, var(--seat-left, var(--idle-left, 50%))) !important;
  top: var(--meeting-top, var(--seat-top, var(--idle-top, 50%))) !important;
  transform: translate(-50%, calc(-100% + var(--foot, 0%))) !important;
  translate: none !important;
  animation: none !important;
}
.office-char[data-meeting="1"] .office-char-body { animation-play-state: paused !important; }

/* 会議再生パネル。看板クリックで開く軽量なオーバーレイ（office.html / index.html 共通・
   両画面のDOM構造差に依存しないよう position: fixed にしてある）。 */
.meeting-panel {
  position: fixed;
  top: 74px;
  right: 18px;
  z-index: 60;
  width: 290px;
  max-width: calc(100vw - 28px);
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  padding: 12px 14px 14px;
}
.meeting-panel[hidden] { display: none; }

.meeting-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 9px;
}
.meeting-panel-title { font-weight: 600; font-size: 0.85rem; }
.meeting-panel-close {
  font: inherit;
  line-height: 1;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-muted);
  cursor: pointer;
}
.meeting-panel-close:hover { color: var(--accent); border-color: var(--accent); }

.meeting-panel-select {
  width: 100%;
  font: inherit;
  font-size: 0.82rem;
  padding: 5px 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text);
  margin-bottom: 10px;
}
.meeting-panel-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.meeting-panel-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 9px;
}
.meeting-panel-speed { display: flex; gap: 4px; }
.meeting-panel-speed button.pill-btn.active {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
}

.meeting-panel-status {
  font-size: 0.72rem;
  color: var(--text-muted);
  min-height: 1.3em;
  line-height: 1.4;
}
.meeting-panel-status.is-err { color: var(--danger); }

/* ==========================================================================
   ファイナンス（/finance.html）
   ★ 色規約（2026-08-01 方針転換。本人の明示指示により「値動きに赤/緑を使わない」
     規約は撤回）: 銘柄の値動き（含み損益・損益率・前日比・対指数のpt）には
     --stock-up/--stock-down を使う。日本式＝上昇=赤（--stock-up）、下落=緑
     （--stock-down）。--danger/--ok とは独立トークンなので混同しない
     （--dangerはツール側の異常＝データ品質・schemaVersion不整合・ruleset不一致・
     取得失敗専用のまま）。severityの強度（注視/強めの注視）は方向とは別軸なので
     --warn（既存の状態色トークン）を使う。詳細は docs/architecture.md §4-E。
   ========================================================================== */

/* フォントサイズトークン（2026-08-01 可読性改善）。:root ではなく .fin-scope に
   閉じる（finance.html専用。他画面への波及を防ぐ）。CSSカスタムプロパティは
   子孫要素に継承されるので、以下の各セレクタは .fin-scope 配下にある前提で
   var(--fin-fs-*) を参照する（セレクタ自体を .fin-scope 配下にネストする必要はない）。 */
.fin-scope {
  --fin-fs-hero: 1.75rem;  /* 28.0px  KPIタイルの数字・合計含み損益 */
  --fin-fs-num:  1.30rem;  /* 20.8px  サマリータイルの副数値 */
  --fin-fs-h:    1.05rem;  /* 16.8px  節見出し・保有カード見出し */
  --fin-fs-base: 0.95rem;  /* 15.2px  本文・シグナル散文 */
  --fin-fs-tbl:  0.92rem;  /* 14.7px  テーブル数値 */
  --fin-fs-sub:  0.85rem;  /* 13.6px  発火頻度・保有日数・muted note */
  --fin-fs-xs:   0.80rem;  /* 12.8px  severityバッジ・機械生成物行・免責 */
}

/* ほぼゼロコストで効く2点。数字の桁がガタつかない・長文の行間を広げて読みやすくする。 */
.fin-table, .fin-num, .fin-kpi-value { font-variant-numeric: tabular-nums; }
.fin-signal-statement { line-height: 1.75; }
.fin-disclaimer-full  { line-height: 1.8; }

/* 過去日バナー。警告ではなく「今どの時点を見ているか」の案内なので
   --danger/--warn ではなく --accent 系（案内板の attn と同じトーン）を使う。 */
.fin-past-banner {
  position: sticky;
  top: 0;
  z-index: 15;
  margin-bottom: 14px;
  padding: 9px 14px;
  border: 1px solid var(--accent);
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--accent) 10%, var(--panel));
  color: var(--accent);
  font-size: var(--fin-fs-sub);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.fin-past-banner a { color: inherit; font-weight: 600; }

.fin-machine-line {
  color: var(--text-muted);
  font-size: var(--fin-fs-xs);
  margin: 0 0 10px;
}

.fin-version-note {
  color: var(--text-muted);
  font-size: var(--fin-fs-sub);
  margin: 0 0 10px;
}

.fin-section-title {
  margin: 20px 0 8px;
  font-size: var(--fin-fs-h);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
}
.fin-section-title:first-child { margin-top: 0; }
.fin-section-icon { display: inline-flex; color: var(--text-muted); flex: none; }
.fin-section-icon svg { display: block; }

.fin-line { margin: 3px 0; font-size: var(--fin-fs-base); }
.fin-line strong { font-weight: 600; }
.fin-narrative-verdict {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: var(--fin-fs-xs);
  font-weight: 700;
  line-height: 1.45;
  vertical-align: middle;
}
.fin-narrative-verdict--hit { color: var(--stock-up); background: color-mix(in srgb, var(--stock-up) 12%, var(--panel)); }
.fin-narrative-verdict--miss { color: var(--stock-down); background: color-mix(in srgb, var(--stock-down) 12%, var(--panel)); }

/* JS側のインラインfont-sizeを廃止した簡易リスト（継続中の内訳・ウォッチリスト共用）。 */
.fin-sublist { margin: 4px 0; padding-left: 1.2em; font-size: var(--fin-fs-sub); }

/* ---- シグナル（色は使わず太さだけで強度を表す） ---- */
.fin-signal {
  padding: 8px 12px;
  margin: 8px 0;
  border-left: 2px solid var(--border);
  background: var(--panel-2);
  border-radius: 0 var(--r-xs) var(--r-xs) 0;
  font-size: var(--fin-fs-base);
}
.fin-signal--alert { border-left-width: 4px; border-left-color: var(--border-strong); }
.fin-signal-head { font-weight: 600; margin-bottom: 2px; }
.fin-signal-sev {
  display: inline-block;
  font-size: var(--fin-fs-xs);
  font-weight: 700;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: var(--r-xs);
  padding: 0 6px;
  margin-right: 6px;
  vertical-align: middle;
}
/* 強めの注視＝--warnを使った塗りバッジ（2026-08-01〜。「注意を強める」という
   意味が--warnの既存の意味と一致するため。方向を示す--stock-up/--stock-downとは
   軸が違うので混同しない）。.advisor-warn-banner と同じ配色パターンを踏襲。 */
.fin-signal-sev--alert {
  background: color-mix(in srgb, var(--warn) 15%, var(--panel));
  border-color: var(--warn);
  color: var(--warn);
}
.fin-signal-freq, .fin-signal-holding {
  color: var(--text-muted);
  font-size: var(--fin-fs-sub);
  margin-top: 3px;
}
.fin-signal-holding a { color: var(--accent); text-decoration: none; display: inline-flex; align-items: center; gap: 3px; }
.fin-signal-holding a:hover { text-decoration: underline; }
.fin-link-icon { display: inline-flex; }
.fin-link-icon svg { display: block; }

/* ---- テーブル（ポートフォリオ・指標・対指数） ---- */
.fin-table-wrap { overflow-x: auto; margin: 8px 0; }
.fin-table { width: 100%; border-collapse: collapse; font-size: var(--fin-fs-tbl); }
.fin-table th, .fin-table td {
  padding: 5px 8px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  text-align: right;
}
.fin-table th:first-child, .fin-table td:first-child { text-align: left; }
.fin-table th {
  color: var(--text-muted);
  font-weight: 600;
  white-space: nowrap;
}
.fin-table td.fin-stale { color: var(--text-muted); }
.fin-table a { color: var(--accent); text-decoration: none; }
.fin-table a:hover { text-decoration: underline; }

/* ---- ゼロ基線ダイバージング横棒（銘柄の値動きの方向を位置＋色で示す） ----
   伸びる棒は --stock-up/--stock-down（日本式＝上昇=赤/下落=緑）で色分けする
   （2026-08-01方針転換）。中央の0基線（::before）は据え置きで --border-strong
   のまま＝基線まで着色すると常に色がある印象になりノイズが増えるため。
   --accent は既にリンク・操作系の意味を持つため値動きには使わない（混線防止）。
   JSは正規化した比率(0〜1)を style="--v:0.62" として、方向を fin-bar--up/--down
   クラスで渡す。 */
.fin-bar {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 10px;
  margin-left: 8px;
  vertical-align: middle;
}
.fin-bar::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--border-strong);
}
.fin-bar::after {
  content: "";
  position: absolute;
  top: 2px;
  bottom: 2px;
  width: calc(var(--v, 0) * 50%);
}
.fin-bar--up::after { left: 50%; background: var(--stock-up); }
.fin-bar--down::after { right: 50%; background: var(--stock-down); }

/* ---- 値動きの符号に応じた数値の文字色（ポートフォリオ表・対指数テーブル・
   サマリーバンドの含み損益/損益率タイルで共用）。ゼロはどちらも使わず
   --text-muted のまま。評価額など元々色のいらない列には適用しない。 */
.fin-num--up { color: var(--stock-up); }
.fin-num--down { color: var(--stock-down); }
.fin-num--zero { color: var(--text-muted); }

/* ---- 保有銘柄カード ---- */
.fin-holding-card {
  scroll-margin-top: 70px; /* アンカー着地時に固定バナー・ヘッダの下に隠れないように */
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 14px;
  margin: 10px 0;
}
.fin-holding-card h3 { margin: 0 0 6px; font-size: var(--fin-fs-h); }
.fin-holding-card .fin-line { margin: 4px 0; }
.fin-holding-thesis {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- 通知・鮮度 ---- */
.fin-update-notice {
  color: var(--accent);
  font-size: var(--fin-fs-sub);
}
.fin-update-notice button {
  font: inherit;
  font-size: var(--fin-fs-xs);
  margin-left: 6px;
  padding: 1px 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  cursor: pointer;
}

/* ---- 免責全文 ---- */
.fin-disclaimer-full {
  font-size: var(--fin-fs-xs);
  color: var(--text-muted);
  line-height: 1.8;
  white-space: pre-wrap;
}

/* ---- details/summary の開閉シェブロン（継続・解消・指標で使い回す）。
   .fin-scope に閉じて他画面の<details>に波及しないようにする。 ---- */
.fin-scope details > summary {
  cursor: pointer;
  list-style: none;
}
.fin-scope details > summary::-webkit-details-marker { display: none; }
.fin-scope details > summary::marker { content: ""; }
.fin-scope .fin-chevron {
  display: inline-flex;
  margin-right: 6px;
  color: var(--text-muted);
  vertical-align: middle;
  transition: transform 0.15s ease;
}
.fin-scope .fin-chevron svg { display: block; }
.fin-scope details[open] > summary .fin-chevron { transform: rotate(90deg); }

/* ---- サマリーバンド（今日の変化 ＋ ポートフォリオ合計。2026-08-01新設） ---- */
.fin-summary-band {
  display: flex;
  flex-wrap: wrap;
  gap: 18px 32px;
  margin: 10px 0 8px;
}
.fin-summary-group {
  display: flex;
  flex-wrap: wrap;
  gap: 18px 28px;
}
.fin-tile { min-width: 64px; }
.fin-tile-value {
  font-size: var(--fin-fs-num);
  font-weight: 700;
  line-height: 1.15;
}
.fin-tile-value--hero { font-size: var(--fin-fs-hero); }
.fin-tile-label { color: var(--text-muted); font-size: var(--fin-fs-sub); margin-top: 2px; }
.fin-tile-sub { color: var(--text-muted); font-size: var(--fin-fs-xs); margin-top: 1px; }

/* ==========================================================================
   デザインエディタ（design.html / js/design.js）。2026-08-28 新設。
   設計の正本は docs/design-editor.md。

   ★ このページだけ「見る画面」ではなく「作る画面」なので、他ページと違い
     キャンバスの高さを最優先する（利用枠バーを置かない・.wrap より広い
     .design-wrap を使う）。
   ★ 図形の色はドキュメント（JSON）が持つ具体値をJSがインラインで当てる。
     ここでテーマ変数を当てるのは**エディタの什器（枠・ハンドル・パネル）だけ**。
     アートボードの中身にテーマ色を混ぜると、ライト/ダークで保存内容の見え方が
     変わってしまい「JSONが正」という前提が崩れる。
   ========================================================================== */

.design-wrap {
  max-width: 1640px;
  margin: 0 auto;
  padding: 16px 20px 32px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.dsg-toolbar-card { padding: 12px 16px; }

.dsg-toolbar {
  display: flex;
  align-items: center;
  gap: 10px 18px;
  flex-wrap: wrap;
}
.dsg-toolbar--file { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }

/* 「JSONをコピー」がクリップボードAPIを使えなかったときだけ出る退避欄（既定は hidden）。
   ★ 色は必ずトークン経由（ライト/ダークの両方で読めること）。 */
.dsg-copy-fallback { margin-top: 8px; }
.dsg-copy-text {
  display: block;
  width: 100%;
  /* ★ .roster-search が付けている max-width を打ち消す。ここは全文を読ませたい欄。 */
  max-width: none;
  box-sizing: border-box;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.78rem;
  line-height: 1.45;
  resize: vertical;
  white-space: pre;
  overflow: auto;
}

.dsg-tool-group { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dsg-tool-group .label { color: var(--text-muted); font-size: 0.8rem; margin-right: 2px; }

.dsg-select { flex: none; min-width: 10em; max-width: 18em; }
.dsg-input { flex: none; min-width: 8em; max-width: 14em; }

/* アートボードの任意サイズ入力（幅 × 高さ）。数値2つが並ぶので細く固定する。 */
.dsg-num { flex: none; width: 5.5em; min-width: 0; text-align: right; }
.dsg-times { color: var(--text-muted); font-size: 0.8rem; }
/* テンプレート名。ファイル名欄（.dsg-input）より短くてよい。 */
.dsg-input--short { min-width: 6em; max-width: 9em; }

.dsg-check {
  font-size: 0.8rem;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
}

/* ---- 3カラム（レイヤー / キャンバス / プロパティ） ---- */
.dsg-layout {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr) 268px;
  gap: 14px;
  align-items: start;
}
@media (max-width: 1100px) {
  .dsg-layout { grid-template-columns: 1fr; }
}

.dsg-panel { max-height: calc(100vh - 300px); overflow: auto; }
.dsg-stage-card { padding: 10px; }

/* ★★ ビューポート方式（2026-08-30 に移行。それ以前はネイティブスクロール方式）。
     .dsg-stage は「のぞき窓」で、**スクロールしない**（overflow: hidden）。
     見えている場所は .dsg-artboard の transform: translate(offset) scale(zoom) だけが決める。
     - スクロールバーは出ない。パンは中ボタン（ホイールクリック）ドラッグ、復帰は「全体」ボタン
     - かつての `.dsg-canvas { margin: 0 auto }`（拡大後の実寸を持ちスクロールバーを出す箱）は
       **廃止した**。理由と経緯は docs/design-editor.md「表示モデル」
     - padding は持たない。position:absolute の子はパディングボックス基準なので効かず、
       「Fit のときの余白」は JS 側の FIT_MARGIN_PX 1箇所が正になった
       （box-sizing:border-box なので padding を外しても要素の高さは変わらない
        ＝F11 でスクロールが出ない状態はそのまま維持される） */
.dsg-stage {
  position: relative;   /* ★ .dsg-artboard（position:absolute）の基準。外すと画面外へ飛ぶ */
  overflow: hidden;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  height: calc(100vh - 320px);
  min-height: 420px;
}
.dsg-stage.is-drawing { cursor: crosshair; }
/* パン中は掴んでいる見た目にする。子孫にも当てないと要素の上でカーソルが戻る
   （`.dsg-stage.is-panning *` は `.dsg-el` より詳細度が高いので !important は不要）。 */
.dsg-stage.is-panning,
.dsg-stage.is-panning * { cursor: grabbing; }

.dsg-artboard {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;   /* ★ 座標変換ヘルパの前提。ここを変えると toCanvasPoint が壊れる */
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  background-image: none;
  touch-action: none;
}
/* 8pxグリッド（スナップONのときだけ）。アートボード座標で描くので拡大すれば一緒に広がる。 */
.dsg-artboard.is-grid {
  background-image:
    linear-gradient(to right, rgba(120, 140, 165, 0.16) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(120, 140, 165, 0.16) 1px, transparent 1px);
}

.dsg-el {
  position: absolute;
  overflow: hidden;
  user-select: none;
}
/* ★ テキスト要素は縦方向の揃え（verticalAlign）のため flex カラムにしてある。
     - 縦（top/middle/bottom）は **主軸** の justify-content で制御する（JSがインラインで当てる）
     - 横（textAlign）は従来どおり text-align のまま効かせる。align-items は既定の
       stretch のままにしておくこと（触ると匿名フロー行の幅が縮んで text-align が死ぬ）。 */
.dsg-el--text {
  display: flex;
  flex-direction: column;
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.35;
  font-family: "Segoe UI", "Hiragino Sans", "Yu Gothic UI", Meiryo, system-ui, sans-serif;
}
.dsg-el--text[contenteditable="true"] { outline: 1px dashed var(--accent); user-select: text; }

/* 選択枠。線幅はJSが toCanvasLength() で逆補正した値をインラインで入れる */
.dsg-overlay {
  position: absolute;
  pointer-events: none;
  outline-style: solid;
  outline-color: var(--accent);
}
.dsg-handle {
  position: absolute;
  pointer-events: auto;
  background: var(--panel);
  border-style: solid;
  border-color: var(--accent);
  box-sizing: border-box;
}
/* 複数選択（2026-08-30・束3）。
   ★ 外接枠は**破線**にして、単一選択の実線＋ハンドルと一目で区別できるようにする
     （複数選択のときはリサイズできない、という事実が見た目に出ている）。 */
.dsg-overlay--multi { outline-style: dashed; }
/* 選択された個々の要素を示す細い枠。★ border ではなく outline を使う
   （border は要素の寸法計算に影響する。線幅はJSがズーム逆補正して入れる）。 */
.dsg-el.is-selected { outline-style: solid; outline-color: var(--accent); }
/* ラバーバンド（空きスペースからのドラッグで出る選択範囲）。線幅はJSが入れる。 */
.dsg-band {
  position: absolute;
  pointer-events: none;
  border-style: dashed;
  border-color: var(--accent);
  background: var(--accent-soft);
  box-sizing: border-box;
}
.dsg-handle--nw { left: 0;    top: 0; }
.dsg-handle--n  { left: 50%;  top: 0; }
.dsg-handle--ne { left: 100%; top: 0; }
.dsg-handle--e  { left: 100%; top: 50%; }
.dsg-handle--se { left: 100%; top: 100%; }
.dsg-handle--s  { left: 50%;  top: 100%; }
.dsg-handle--sw { left: 0;    top: 100%; }
.dsg-handle--w  { left: 0;    top: 50%; }

/* ---- アイコン（インラインSVG。定義は static/js/design-icons.js の1箇所） ----
   ★ 色は必ず currentColor 経由でトークンを拾う。ここで色を書かないこと
     （ダーク/ライトの追従が壊れる）。絵文字は使わない＝docs/architecture.md §4-E。 */
.dsg-scope .dsg-icon { display: block; flex: none; pointer-events: none; }

/* ラベル・ボタンの「頭に付くアイコン」。テキストと一緒に並ぶので inline-flex にする。 */
.dsg-scope .label,
.dsg-scope button.pill,
.dsg-scope .pill-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.dsg-scope .label .dsg-icon { opacity: 0.85; }

/* アイコンのみのボタン（元に戻す／やり直し等）。必ず aria-label と title を持つ。 */
.dsg-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  flex: none;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--panel-2);
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}
.dsg-icon-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.dsg-icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dsg-icon-btn:disabled { opacity: 0.4; cursor: default; }

/* ---- 揃え（Word 風のアイコンのみセグメントボタン。横3つ＋縦3つ） ---- */
.dsg-align-row { display: flex; gap: 10px; flex-wrap: wrap; }
.dsg-seg { display: inline-flex; }
.dsg-seg-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 26px;
  padding: 0;
  flex: none;
  border: 1px solid var(--border);
  border-radius: 0;
  margin-left: -1px;            /* 隣同士の枠線を重ねて1本にする */
  background: var(--panel-2);
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}
.dsg-seg-btn:first-child { margin-left: 0; border-radius: var(--r-xs) 0 0 var(--r-xs); }
.dsg-seg-btn:last-child { border-radius: 0 var(--r-xs) var(--r-xs) 0; }
.dsg-seg-btn:hover { color: var(--accent); }
.dsg-seg-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; z-index: 1; }
.dsg-seg-btn.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
  z-index: 1;                   /* 重ねた枠線より前面に出す */
}

/* ---- ズーム（倍率表示＋全体） ----
   倍率表示チップは「今の倍率」と「100%に戻すボタン」を兼ねる1部品。
   高さは隣の .dsg-icon-btn と揃えて 28px。 */
.dsg-zoom-value {
  height: 28px;
  width: 56px;                     /* min-width ではなく固定。25%〜400%の桁変動で揺れない */
  padding: 0;
  flex: none;
  border: 1px solid var(--border);
  border-radius: var(--r-xs);
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;   /* ホイールで数字が高速に変わるときのチラつき防止 */
  font-feature-settings: "tnum" 1;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;            /* 連続操作中に数字がドラッグ選択されるのを防ぐ */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color .18s ease, background .18s ease, border-color .18s ease;
}
.dsg-zoom-value:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.dsg-zoom-value:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ホイールで倍率が変わったときの一瞬のハイライト（350ms、JSで .is-live を付け外し）。
   ★ ライトモードの --accent-soft は alpha 0.10 で背景変化がほぼ見えないため、
     背景ではなく枠線と文字色で表現する。ここは間違えやすい。 */
.dsg-zoom-value.is-live { color: var(--accent); border-color: var(--accent); }

/* ---- レイヤー一覧（上が前面＝配列の後ろ） ---- */
.dsg-layers { list-style: none; margin: 6px 0 0; padding: 0; position: relative; }
.dsg-layer {
  display: flex;
  align-items: center;
  gap: 4px;
  border-radius: var(--r-xs);
  padding: 1px 2px;
}
.dsg-layer.is-selected { background: var(--accent-soft); }

/* グループ番号のバッジ（2026-08-30・束3）。どの行が同じグループかを一目で分かるようにする。
   ★ 絵文字は使わない（docs/architecture.md §4-E）。文字のバッジ1個で足りる。 */
.dsg-layer-group {
  flex: none;
  font-size: 10px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: var(--r-xs);
  border: 1px solid var(--border);
  color: var(--text-muted);
  white-space: nowrap;
}

/* 複数選択時のプロパティパネルの「まとめて操作」ボタン列。 */
.dsg-group-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }

/* ドラッグ用グリップ（≡）。★ 行全体ではなくここだけを掴んで並べ替える。
   マウスが使えない場面のフォールバックとして、フォーカスして ↑↓ キーでも動く。 */
.dsg-layer-grip {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 22px;
  flex: none;
  padding: 0;
  border: none;
  background: none;
  color: var(--text-muted);
  opacity: 0.55;
  cursor: grab;
  touch-action: none;           /* ポインタドラッグをブラウザのスクロールに取られない */
}
.dsg-layer-grip:hover { opacity: 1; color: var(--accent); }
.dsg-layer-grip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; opacity: 1; }
.dsg-layers.is-reordering .dsg-layer-grip { cursor: grabbing; }
.dsg-layer.is-dragging { opacity: 0.45; }

/* ドロップ位置を示す挿入線。これが無いと「どこに入るか分からないドラッグ」になる。 */
.dsg-drop-line {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  margin-top: -1px;
  background: var(--accent);
  border-radius: 1px;
  pointer-events: none;
}
.dsg-layer-name {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: 0.8rem;
  text-align: left;
  background: none;
  border: none;
  color: var(--text);
  padding: 4px 4px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dsg-layer-name:hover { color: var(--accent); }
.dsg-layer-swatch {
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  border: 1px solid var(--border-strong);
}
.dsg-layer-actions { display: flex; gap: 2px; flex: none; }
.dsg-layer-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: inherit;
  font-size: 0.72rem;
  line-height: 1;
  padding: 4px 5px;
  border: 1px solid var(--border);
  border-radius: var(--r-xs);
  background: var(--panel-2);
  color: var(--text-muted);
  cursor: pointer;
}
.dsg-layer-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
.dsg-layer-btn:disabled { opacity: 0.35; cursor: default; }

/* ---- プロパティパネル ---- */
.dsg-field { margin: 6px 0; }
.dsg-field-label {
  display: flex;              /* 頭のアイコンとラベル文字を並べる */
  align-items: center;
  gap: 4px;
  font-size: 0.72rem;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.dsg-field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 8px; }
.dsg-field-input {
  font: inherit;
  font-size: 0.8rem;
  width: 100%;
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-xs);
  background: var(--panel-2);
  color: var(--text);
}
.dsg-field-input:focus { outline: none; border-color: var(--accent); }
.dsg-field-textarea { min-height: 54px; resize: vertical; }
.dsg-color-row { display: flex; align-items: center; gap: 6px; }
.dsg-field-color {
  flex: none;
  width: 34px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-xs);
  background: var(--panel-2);
  cursor: pointer;
}
.dsg-field-hex { flex: 1 1 auto; }
.dsg-field-strokew { flex: 0 0 4.5em; }

/* ---- 「開く」モーダル ---- */
.dsg-modal { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; }
.dsg-modal[hidden] { display: none; }
.dsg-modal-backdrop { position: absolute; inset: 0; background: rgba(10, 20, 34, 0.45); }
.dsg-modal-body {
  position: relative;
  width: min(680px, calc(100vw - 40px));
  max-height: min(72vh, 700px);
  overflow: auto;
  box-shadow: var(--shadow-lg);
}
.dsg-list-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 11em) 9.5em;
  gap: 10px;
  align-items: center;
  width: 100%;
  font: inherit;
  font-size: 0.82rem;
  text-align: left;
  padding: 7px 8px;
  border: none;
  border-bottom: 1px solid var(--border);
  background: none;
  color: var(--text);
  cursor: pointer;
}
.dsg-list-row:hover { background: var(--accent-soft); }
.dsg-list-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dsg-list-project { color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dsg-list-date { color: var(--text-muted); font-size: 0.75rem; text-align: right; }

/* ---- アートボードのサイズ設定モーダル（2026-08-30・束4）----
   原典は designs/サイズ変更設定案.json（本人が描いた案。493×320）。
   ★ z-index は「開く」(60) より上・確認 (70) より下。ここからゴミ箱→確認を重ねるため。 */
.dsg-size-modal { z-index: 65; }
.dsg-size-body { width: min(480px, calc(100vw - 40px)); max-height: none; }

/* テンプレート行・サイズ行。左のラベル幅を揃えて縦に整列させる（GIMP風）。 */
.dsg-size-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
}
.dsg-size-label {
  flex: none;
  width: 7em;
  color: var(--text-muted);
  font-size: 0.8rem;
}
.dsg-size-modal .dsg-select { flex: 1 1 auto; min-width: 8em; max-width: none; }

/* 下段のボタン列。「テンプレートとして保存」は左、OK / キャンセルは右に寄せる。
   ★ 並び順（OK → キャンセル）は原典どおり。 */
.dsg-size-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 16px;
}
.dsg-size-spacer { flex: 1 1 auto; }
/* .dsg-scope（<main>）の外にあるので、アイコン付きボタンの並びをここで面倒を見る。 */
.dsg-size-actions .pill-btn,
.dsg-size-row .pill-btn { display: inline-flex; align-items: center; gap: 6px; }
.dsg-size-modal .inline-error,
.dsg-name-prompt .inline-error { margin-top: 10px; }

/* テンプレート名の入力ポップアップ。サイズ設定 (65) の上・確認 (70) の下。 */
.dsg-name-prompt { z-index: 68; }
.dsg-name-body { width: min(440px, calc(100vw - 40px)); max-height: none; }
.dsg-name-prompt .dsg-input { flex: 1 1 auto; max-width: none; }

/* ヘッダーに残す現在サイズの表示（原典 el-2「1440 x 900 (PC)」）。
   ★ ここは表示専用。操作は全部モーダルへ移した。 */
.dsg-ab-summary {
  font-size: 0.8rem;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  white-space: nowrap;
}

/* ---- 確認ダイアログ（window.confirm の代替）----
   ★ z-index は「開く」モーダル(60)より上。未保存のまま一覧から開こうとしたとき、
     確認が「開く」モーダルの下に隠れると操作不能になるため。 */
.dsg-confirm { z-index: 70; }
.dsg-confirm-body { width: min(420px, calc(100vw - 40px)); max-height: none; }
.dsg-confirm-msg { margin: 10px 0 16px; font-size: 0.85rem; line-height: 1.7; color: var(--text); }
.dsg-confirm-actions { display: flex; justify-content: flex-end; gap: 8px; }
.dsg-confirm-actions .pill-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* オフィス画面のツールバーに同居させた一行の注記（2026-08-30）。
   縦を増やさないため独立した行にはしない。狭い幅では折り返して構わない。 */
.office-hint { margin-left: auto; text-align: right; }
.office-hint a { color: var(--text-muted); }
.office-hint a:hover { color: var(--accent); }
@media (max-width: 860px) { .office-hint { margin-left: 0; text-align: left; } }
