.canvas-wrap { position: relative; width: 100%; height: 100%; overflow: hidden; }
#plot { width: 100%; height: 100%; background: var(--bg); touch-action: none; }

.timebar {
  position: absolute;
  bottom: 1.2rem; left: 1.2rem;
  right: 220px;
  background: var(--legend-bg);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 0.5rem 0.85rem;
  backdrop-filter: blur(10px);
  z-index: 40;
  display: flex; align-items: center; gap: 0.6rem;
  box-shadow: 0 2px 12px rgba(0,0,0,0.2);
  /* 開閉は `right` の伸縮で見せる (owner 指示 2026-09-07「タップしたら開く (伸びるような
     感じに)」)。⚠ 閉じ幅を `width: auto` にすると **animatable でなくなる** ので、
     `right` を calc の長さで与える (下の `.is-collapsed`)。 */
  transition: right 0.22s ease, padding 0.22s ease;
}
/* 中身 (help / 年代 / range / play / ALL) の器。閉じている間は display:none = tab 順にも
   支援技術にも出ない (`aria-expanded` の disclosure と対)。
   ⚠ gap は親から継承する — mobile.css が `.timebar` 側の gap を 0.4rem へ落とすため。 */
.timebar-body {
  display: flex; align-items: center; gap: inherit;
  flex: 1; min-width: 0;
}
.timebar.is-collapsed .timebar-body { display: none; }
/* 閉じ = 端に寄せたボタン 1 つぶんの箱。
   🔴 **既定は中身の実測幅ちょうど** (owner 指示 2026-09-08「閉じた状態の右側の余白を削って」)。
   実測 = ボタンの自然幅 **48.6px** に対し箱が 104px (6.5rem) で **約 55px が空いていた**。
   ⇒ 既定を **3.6rem (57.6px)** = 自然幅 48.6 + 箱の padding 8 + 余り 1 へ詰める。
   ⚠ **絞り込み中だけ 6.5rem に戻す** — ラベルが `1930〜2023` (10 字) まで伸びるため
     (`Timebar.tsx` の `yearLabel`)。`:has()` 非対応の環境では既定の 3.6rem のままで、
     溢れた分はラベル側の ellipsis が受ける = **機能は落ちない**。
   ⚠ **固定長のままにするのは伸縮のため** — 開閉は `right` の 2 値間の transition で
     見せる (owner 逐語「伸びるような感じに」) ので、`width: max-content` にはしない。 */
.timebar.is-collapsed {
  right: calc(100% - 1.2rem - 3.6rem);
  padding: 0.25rem;
  gap: 0;
}
.timebar.is-collapsed:has(.timebar-toggle.is-filtered) {
  right: calc(100% - 1.2rem - 6.5rem);
}
/* 閉じている間は外枠 (この glass の箱) が pill そのもの — 内側の button の枠を消して
   二重枠にしない。⚠ 絞り込み中 (`.is-filtered`) の accent 枠だけは残す。 */
.timebar.is-collapsed .timebar-toggle:not(.is-filtered) { border-color: transparent; }
/* 開閉ボタン。⚠ font-size を明示する — `.timebar` は desktop で font-size を持たず
   (mobile だけ 0.6rem)、継承のままだと閉じ幅から溢れる。 */
/* 🔴 **可視の箱は小さく・当たり判定 44 は透明な `::before`** (owner 指示 2026-09-08
   「年代スライダーをもう少し縦幅狭めて」)。`min-height: 44` を可視の箱に当てると
   **開いた時の帯が 57px になり盤面を食う** (実測)。⇒ `.dm-domain-trigger` と同じ型
   (`ui/domain/domain-map.css` / 元は `components/help.css` の #748) を横展開する。
   ⚠ 裁定 1-① の 32 例外 (`.axis-slot` / `.sb-toggle`) を広げるのではなく、
     **可視と当たり判定を分ける**ことで 44 床と縦幅の両立を保つ。
   ⚠ `::after` は chevron が使用中なので `::before` を当たり判定に使う。 */
.timebar-toggle {
  flex: 0 1 auto;
  position: relative;
  display: flex; align-items: center; justify-content: center; gap: 0.3rem;
  min-height: 1.5rem;
  padding: 0 0.5rem;
  background: transparent;
  border: 1px solid var(--t-border-strong);
  border-radius: 6px;
  color: var(--t-fg-soft);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.62rem; font-weight: 700;
  cursor: pointer;
  /* 🔴 **`overflow: hidden` を置かない** — 置くと下の `::before` (44 の当たり判定) が
     ボタンの箱に**切り取られて無効化**される (実測で当たり帯が 44 → 25px になっていた)。
     ラベルの ellipsis は `.timebar-toggle-label` 側が自前で持つので、ここでは不要。 */
}
/* 一次動作の tap 床 (44) を**当たり判定だけ**で満たす (上のコメント)。 */
.timebar-toggle::before {
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: 100%; height: var(--t-tap-min, 44px);
  min-width: var(--t-tap-min, 44px);
  transform: translate(-50%, -50%);
}
.timebar-toggle:hover { color: var(--t-fg); border-color: var(--t-border-hover); }
.timebar-toggle-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 開いている間はラベルを畳む — 同じ年代表示を `#timebar-year` が持つ (二重に出さない)。 */
.timebar.is-open .timebar-toggle-label { display: none; }
/* 絞り込み中は閉じていても分かるように枠を accent へ (文字色は据え置き — light で
   accent text が surface 上の contrast を落とす)。 */
.timebar-toggle.is-filtered { border-color: var(--t-accent); }
/* chevron は border 描画 (`.axis-slot::after` と同じ機構) — icon registry を増やさない。
   ⚠ button が flex なので ::after も flex item — `flex: 0 0 auto` が無いと潰れる。 */
.timebar-toggle::after {
  content: '';
  flex: 0 0 auto;
  width: 5px; height: 5px;
  border-top: 1.5px solid currentColor;
  border-right: 1.5px solid currentColor;
  transform: translateX(-1px) rotate(45deg);
  transition: transform 0.15s;
}
.timebar.is-open .timebar-toggle::after { transform: translateX(1px) rotate(-135deg); }
.timebar-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem; color: var(--mid);
  text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;
}
.timebar-year {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem; font-weight: 700; color: var(--accent);
  min-width: 5em;
}
/* v=66: light で accent on white は 3.01 contrast → dark fg に */
:where(html, body)[data-theme="light"] .timebar-year { color: var(--t-fg); }
.timebar-range {
  position: relative;
  flex: 1; min-width: 0; height: 18px;
  --start-pct: 0%;
  --end-pct: 100%;
}
.timebar-range::before {
  /* 全レール */
  content: '';
  position: absolute;
  top: 50%; left: 0; right: 0; height: 4px;
  transform: translateY(-50%);
  background: var(--border); border-radius: 2px;
  pointer-events: none;
}
.timebar-range::after {
  /* 選択範囲ハイライト */
  content: '';
  position: absolute;
  top: 50%; height: 4px;
  transform: translateY(-50%);
  background: var(--accent); border-radius: 2px;
  pointer-events: none;
  left: var(--start-pct);
  right: calc(100% - var(--end-pct));
}
.timebar-range input[type=range] {
  position: absolute;
  top: 0; left: 0; width: 100%; height: 18px;
  background: transparent;
  pointer-events: none;
  appearance: none; -webkit-appearance: none;
  outline: none;
  margin: 0;
}
.timebar-range input[type=range]::-webkit-slider-thumb {
  pointer-events: auto;
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
  border: 2px solid var(--surface);
  box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
.timebar-range input[type=range]::-moz-range-thumb {
  pointer-events: auto;
  width: 14px; height: 14px;
  border: 2px solid var(--surface);
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
}
.timebar-range input[type=range]::-webkit-slider-runnable-track {
  height: 4px; background: transparent;
}
.timebar-range input[type=range]::-moz-range-track {
  height: 4px; background: transparent;
}
.timebar-help {
  background: transparent; border: 1px solid var(--border);
  color: var(--mid);
  width: 1.5em; height: 1.5em;
  border-radius: 50%;
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.timebar-help:hover { color: var(--accent); border-color: var(--accent); }
.timebar-help-popup {
  position: absolute;
  bottom: 4rem; right: 1.2rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 0.7rem 0.9rem;
  box-shadow: 0 4px 16px rgba(0,0,0,0.3);
  z-index: 50;
  display: none;
  font-size: 0.72rem;
  max-width: 22em;
  line-height: 1.5;
  color: var(--text);
}
.timebar-help-popup.visible { display: block; }
.timebar-help-popup b { color: var(--accent); }
.timebar-play {
  background: var(--accent); color: var(--bg);
  border: none; border-radius: 99px;
  width: 1.8em; height: 1.8em;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.7rem;
}
:where(html, body)[data-theme="light"] .timebar-play { color: var(--t-on-accent); }
.timebar-reset {
  background: transparent; border: 1px solid var(--border);
  color: var(--mid);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem; font-weight: 700;
  padding: 0.15rem 0.5rem; border-radius: 4px;
  cursor: pointer;
}
.timebar-reset:hover { color: var(--text); border-color: var(--border-strong); }

/* 色ガイド (点の色) — caption + カプセル select の縦積み。caption / select は
   軸プリセット caption・.axis-slot と同族の様式 (2026-08-17 owner 指示 —
   カプセル本体の定義の正 = apps/web/src/ui/domain/domain-map.css)。 */
.legend {
  position: absolute; bottom: 1.2rem; right: 1.2rem;
  background: var(--t-legend-bg); border: 1px solid var(--t-border-strong);
  border-radius: 8px; padding: 0.7rem 0.85rem;
  backdrop-filter: blur(10px);
  z-index: 50; min-width: 180px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.2);
}
.legend-label {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--t-dim);
  margin-bottom: 0.35rem;
}
.legend-slot {
  display: flex;
  margin-bottom: 0.45rem;
  /* 🔴 **箱を超えない + 縮める側を開ける** (2026-09-11 実測)。`.axis-slot` は inline-flex で
     shrink-to-fit するため、中の select が既定の min-width auto で「最長 option の幅」より
     縮まないと、legend の箱 (mobile.css が `.legend` に与える max-width 50vw) を
     **はみ出して描かれる** — `.legend` に overflow 指定が無いので枠の外へ出て、320 では
     viewport の外まで行く。実測 = 4 幅 × 3 面 × 2 言語 の 24 点で 11.84px は 0 点 /
     16px は 10 点が溢れた。⚠ **select 側の min-width 0 だけでは直らない** (実測で 1px も
     動かなかった) — slot 自身を container で頭打ちにする側が要る。 */
  min-width: 0;
  max-width: 100%;
}
/* 🔴 **16px 床 = iOS の focus zoom 防止** (2026-09-11)。`domain-map.css` の
   `.axis-slot-select` の font-size 0.74rem は **(0,1,0)**、`mobile.css` の
   `@media (max-width:768px)` 内の `select` への font-size 16px は **(0,0,1)** なので、
   矯正側が特異度で負けて **legend の色セレクタだけ zoom 防止が効かない**状態だった
   (#757 は `.domain-map__controls` 配下だけを直し、legend を残件として預けていた)。
   この規則は (0,2,0) なので勝つ。
   ⚠ `field-sizing: content` と `flex: 0 0 auto` は **採らない** — legend は帯ではなく
     単独 1 本で `flex: 1` が意図、かつ `field-sizing` は非対応ブラウザで「最長 option 幅」
     に化ける経路が未実測 (#757 の注記) なので、未実測経路を 9 面へ増やさない。
   line-height を明示するのは UA 既定 (`normal`) への依存を外して高さの内訳を固定するため
   (`.domain-map__controls .axis-slot-select` と同じ理由)。 */
.legend-slot .axis-slot-select {
  flex: 1;
  /* 🔴 **`min-width: 0` は 16px 床とセット** (2026-09-11 実測)。flex item の既定
     `min-width: auto` は「最長 option の幅」より縮まないので、16px にすると legend の
     箱 (`mobile.css` が `.legend` に与える max-width 50vw) を**はみ出して描かれる**
     (`.legend` に overflow 指定が無い)。実測 = 4 幅 × 3 面 × 2 言語 の 24 点で
     **11.84px では 0 点 / 16px では 10 点**が溢れ、320 では viewport の外へ出ていた。
     縮める側を開けると `.axis-slot-select` の `text-overflow: ellipsis` が受ける。 */
  min-width: 0;
  max-width: none;
  font-size: 16px;
  line-height: 1.2;
  padding-block: 0.25rem;
}

/* Safari 3D 操作推奨バナー */
#safari-3d-banner {
  position: absolute;
  top: 0.55rem; left: 50%; transform: translateX(-50%);
  z-index: 80;
  background: color-mix(in srgb, var(--t-surface) 96%, transparent);
  border: 1px solid var(--t-border);
  border-radius: 99px;
  padding: 0.3rem 0.55rem 0.3rem 0.7rem;
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.7rem; color: var(--t-fg);
  white-space: nowrap;
  box-shadow: 0 2px 10px rgba(0,0,0,0.22);
  backdrop-filter: blur(12px);
  pointer-events: auto;
  line-height: 1.3;
}
#safari-3d-banner-close {
  background: none; border: none;
  color: var(--t-muted);
  cursor: pointer; font-size: 1rem; line-height: 1;
  padding: 0 0.15rem; flex-shrink: 0;
}
#safari-3d-banner-close:hover { color: var(--t-fg); }
/* .legend-select / .legend-title / .legend-subtitle は 2026-08-17 に撤去 —
   select は .axis-slot カプセルへ一本化 (上の .legend-slot)、title/subtitle は使用ゼロ。 */
.legend-bar {
  height: 10px; border-radius: 5px;
  background: linear-gradient(to right,
    #5a4a8a, #4a5fa5, #3478b0, #246b96,
    #1f9e89, #35b779, #59c267, #a5d839, #b5de2b, #f4e542);
  margin-bottom: 0.3rem; border: 1px solid var(--t-legend-bar-border);
}
.legend-scale {
  display: flex; justify-content: space-between;
  font-size: 0.6rem; font-family: 'JetBrains Mono', monospace; font-weight: 600;
  color: var(--t-fg-soft);
}
.filter-err   { color: var(--t-negative); font-size: 0.7rem; padding: 0.5rem; white-space: pre-wrap; }
.filter-empty { color: var(--t-muted); font-size: 0.7rem; padding: 0.5rem; }
