/*
 * B-RIO 共通スタイル
 *
 * 設計方針:
 *   - 全画面で共通のレイアウト・タイポグラフィ・色を CSS 変数で一元管理
 *   - インラインCSS禁止（絶対ルール）のため、全てここに集約
 *   - サイドバー幅・カラー・スペーシングは --* 変数で統一
 *   - shadcn/ui 風ニュートラルパレット + 機能色アクセント
 *   - ライトテーマのみ（テーマ切替は採用しない）
 *
 * 改訂履歴:
 *   - v1.0 初版
 *   - v1.1 2026-05-15 ナビゲーションをサイドメニュー化（左縦並び）
 *   - v1.2 2026-05-15 モダンレイアウトに刷新
 *   - v1.3 2026-05-15 maintenance_new.html プロトタイプに合わせて
 *                     デザイントークンを shadcn 風に刷新
 *                     - 変数名は維持（後方互換: dashboard.css 等が参照中）
 *                     - サイドバーをダーク→ライト系に変更（アクセントバー方式）
 *                     - フォントスタック / 角丸 / 影 / カラーを更新
 *                     - 既存クラス（.app-layout / .app-sidebar / .card 等）は維持
 */

/* ============================================================
 * 1. CSS 変数（デザイントークン）
 *    shadcn/ui 風のニュートラル + 機能色
 * ============================================================ */
:root {
  /* ---- レイアウト ---- */
  --sidebar-width:       240px;
  --content-max-width:   1600px;
  --page-padding-x:      32px;
  --page-padding-y:      32px;
  --header-height:       56px;

  /* ---- カラーパレット（ベース） ---- */
  --color-bg:            #FAFAF9;
  --color-bg-card:       #FFFFFF;
  --color-bg-soft:       #F4F4F2;
  --color-bg-hover:      #F0EFEC;

  /* ---- サイドバー（ライト基調＋アクセントバー） ---- */
  --color-sidebar-bg:    #FFFFFF;
  --color-sidebar-bg-2:  #FAFAF9;      /* footer 部 */
  --color-sidebar-fg:    #1A1A18;
  --color-sidebar-nav:   #57544C;
  --color-sidebar-hover-bg: #F0EFEC;
  --color-sidebar-hover-fg: #1A1A18;
  --color-sidebar-current-bg: #F4F4F2;
  --color-sidebar-current-fg: #1A1A18;
  --color-sidebar-accent: #1F1F1F;     /* アクティブ項目の縦バー */

  /* ---- テキスト ---- */
  --color-text:          #1A1A18;
  --color-text-muted:    #6E6A61;   /* S-2: 旧 #8A867C は白背景 3.63:1 で AA 未達。5.08:1 に是正 */
  --color-text-secondary:#57544C;

  /* ---- 罫線 ---- */
  --color-hairline:      #E7E5E0;
  --color-hairline-dark: #D4D2CC;
  --color-border:        #E7E5E0;

  /* ---- 機能色 ---- */
  --color-primary:       #1F1F1F;      /* shadcn 風: プライマリは黒 */
  --color-primary-hover: #000000;
  --color-primary-soft:  #F4F4F2;
  /* プライマリの淡色。スピナーのリング等、地の上に置く薄い面に使う。
     2026-07-16 追加: 従来 .brio-loading__spinner が参照していたが未定義で、
     フォールバック値 #e3f2fd（水色）で描画されパレットから浮いていた。 */
  --color-primary-light: #E7E5E0;
  --color-info:          #2563EB;
  --color-info-soft:     #DBEAFE;
  --color-success:       #047857;   /* S-2: 旧 #059669 は白背景 3.77:1 で AA 未達。5.48:1 に是正。
                                       白文字を載せる背景としても 5.48:1 を確保する。 */
  --color-success-bg:    #ECFDF5;
  --color-success-border:#A7F3D0;
  --color-warning:       #B45309;   /* S-2: 旧 #D97706 は --color-bg-soft 上 2.89:1 で G8 必須3:1 未達。5.02:1 に是正（--color-pri-mid-fg と同値のため色数を増やさない） */
  --color-warning-bg:    #FFFBEB;
  --color-warning-border:#FDE68A;
  --color-danger:        #C81E1E;   /* S-2: 旧 #DC2626 は --color-danger-bg 上 4.41:1 で AA 未達。5.24:1 に是正 */
  --color-danger-bg:     #FEF2F2;
  --color-danger-border: #FECACA;
  /* ---- データ可視化トークン（S-1 / 2026-08-21 追加） -------------------
   * なぜ機能色と分けるか:
   *   UI用トークン（--color-primary-light 等）は「地の上に置く薄い面」を
   *   目的とし、意図的に低コントラストである。これをグラフに流用すると
   *   デジタル庁ガイドブック 4.3 が必須とする「背景色とグラフ色面の
   *   コントラスト比 3:1 以上」を満たせない。用途で名前空間を分ける。
   * 値の出典:
   *   デジタル庁デザインシステム カラーパレット。すべて #FFFFFF に対し 3:1 以上。
   * 適用規約:
   *   - グラフの fill/stroke に hex 直書きを禁止。必ず本トークンを参照する。
   *   - 1グラフの系列色は5色まで。6系列以上は上位5＋「その他」に集約する。
   *   - 色以外の識別手段（線種・データ点形状・値ラベル・ハッチング）を必ず併記する。
   * -------------------------------------------------------------------- */
  --series-1:            #0017C1;   /* Blue 900      白比 11.1:1 */
  --series-2:            #AC3E00;   /* Orange 900    白比  6.0:1 */
  --series-3:            #006F83;   /* Cyan 900      白比  6.1:1 */
  --series-4:            #115A36;   /* Green 900     白比  7.9:1 */
  --series-5:            #4D4D4D;   /* SolidGray 700 白比  8.6:1 */

  /* 意味付き系列（乗降は全画面でこの2色に統一する） */
  --series-boarding:     var(--series-1);
  --series-alighting:    var(--series-2);

  /* グラフ部品 */
  --chart-bar-muted:     #767676;   /* 非強調の棒     白比 4.5:1 */
  --chart-grid:          #D4D2CC;   /* 目盛線。最小限に使う */
  --chart-axis:          #57544C;   /* 軸線          白比 7.6:1 */
  --chart-tick:          #57544C;   /* 目盛文字。12px 未満にしない（S-2 の下限に合わせる） */

  /* 連続スケール（ヒートマップ等）。5段階すべて白背景比 3:1 以上。
     デジタル庁パレットの Blue は 400 以下（#7096F8 で 2.84:1）が
     3:1 を満たさないため、500 以上の濃い側だけで段階を作る。
     淡い側を使わない分、段階間の差は明度で確保する。 */
  --chart-scale-1:       #4979F5;   /* Blue 500      白比  3.9:1 */
  --chart-scale-2:       #3460FB;   /* Blue 600      白比  5.0:1 */
  --chart-scale-3:       #1E3FDD;   /* Blue 700 相当 白比  7.5:1 */
  --chart-scale-4:       #0017C1;   /* Blue 900      白比 11.1:1 */
  --chart-scale-5:       #000060;   /* Blue 1200     白比 18.0:1 */

  /* P3-3: 紫（#7C3AED / #EDE9FE）はデジタル庁カラーパレットの 7 系統に存在しない。
     用途はメンテナンス画面のカテゴリ識別のみだったため、同パレットの Cyan 系へ寄せる。
     --series-3 は既にデータ可視化トークンとして定義済みの Cyan 900（白比 6.1:1）。
     ここでは面（背景）用に淡色のみ追加し、前景は --series-3 を再利用する。 */
  --color-accent-soft:   #E0F2F6;   /* Cyan 100 相当。--series-3 の文字を載せて 5.4:1 */

  /* ---- 優先度カラー（バッジ用、maintenance_new.html 準拠） ---- */
  --color-pri-high-bg:        #FEF2F2;
  --color-pri-high-fg:        #B91C1C;
  --color-pri-high-border:    #FECACA;
  --color-pri-mid-need-bg:    #FFF7ED;
  --color-pri-mid-need-fg:    #C2410C;
  --color-pri-mid-need-border:#FED7AA;
  --color-pri-mid-bg:         #FFFBEB;
  --color-pri-mid-fg:         #B45309;
  --color-pri-mid-border:     #FDE68A;
  --color-pri-none-bg:        #ECFDF5;
  --color-pri-none-fg:        #047857;
  --color-pri-none-border:    #A7F3D0;
  --color-pri-unset-bg:       #F5F5F4;
  --color-pri-unset-fg:       #57544C;
  --color-pri-unset-border:   #D4D2CC;

  /* ---- タイポグラフィ ---- */
  --font-sans: 'Inter', 'Hiragino Sans', 'Noto Sans JP',
               -apple-system, BlinkMacSystemFont,
               "Hiragino Kaku Gothic ProN", "Yu Gothic", "Meiryo",
               system-ui, sans-serif;
  --font-display: 'Instrument Serif', 'Hiragino Mincho ProN',
                  "Yu Mincho", "YuMincho", serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular,
               Menlo, Consolas, monospace;

  /* ---- スペーシング（8px ベース） ---- */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-lg: 16px;
  --space-xl: 24px;
  --space-2xl: 32px;
  --space-3xl: 48px;

  /* ---- 角丸 ---- */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;

  /* ---- シャドウ（落ち着いた目立たない影） ---- */
  --shadow-xs: 0 1px 2px rgba(20, 20, 18, 0.04);
  --shadow-sm: 0 1px 3px rgba(20, 20, 18, 0.06),
               0 1px 2px rgba(20, 20, 18, 0.04);
  --shadow-md: 0 4px 12px rgba(20, 20, 18, 0.06),
               0 2px 4px rgba(20, 20, 18, 0.04);
  --shadow-lg: 0 12px 32px rgba(20, 20, 18, 0.08);

  /* ---- トランジション ---- */
  --transition-fast: 0.12s ease;
  --transition-base: 0.18s ease;
}

/* ============================================================
 * 2. リセット & ベース
 * ============================================================ */
*, *::before, *::after {
  box-sizing: border-box;
}

/*
 * HTML 標準の hidden 属性は本来 `display:none` 相当だが、
 * 後続クラスで `display:flex` 等を指定すると上書きされてしまう。
 * 全画面の JS が `el.hidden = true` / `setAttribute('hidden','')` で
 * 隠す前提なので、ここで一括して強制する。
 * （絶対ルール「同じ判断ロジックを複数箇所に書かない」: 個別クラスごとに
 *  &[hidden]{display:none} を書かず、共通CSSで一度だけ宣言）
 */
[hidden] {
  display: none !important;
}

/* P3-9: html に font-size を指定すると、利用者がブラウザで設定した
   文字サイズが完全に無視される。ルートは既定（多くは 16px、利用者が
   変更していればその値）に任せ、本文だけを rem で 13px 相当に置く。
   以降の font-size はすべて rem なので、ルートに追随して拡大縮小する。 */
html, body {
  margin: 0;
  padding: 0;
  font-family: var(--font-sans);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-size: 0.8125rem;   /* 既定 16px 環境で 13px 相当 */
}

a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  color: var(--color-text);
  font-weight: 600;
}

button {
  font-family: inherit;
  cursor: pointer;
}

/* ============================================================
 * 3. アプリ全体レイアウト（サイドバー + メイン）
 * ============================================================ */
.app-layout {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  min-height: 100vh;
}

/* ---- 左サイドバー ---- */
.app-sidebar {
  background: var(--color-sidebar-bg);
  color: var(--color-sidebar-fg);
  border-right: 1px solid var(--color-hairline);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  overflow-y: auto;
}

/* ロゴ／システム名 */
.app-sidebar__brand {
  padding: 20px 20px 16px;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  border-bottom: 1px solid var(--color-hairline);
}

.app-sidebar__brand-mark {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md);
  background: var(--color-primary);
  color: var(--color-bg-card);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  flex-shrink: 0;
}

.app-sidebar__brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.app-sidebar__brand-name {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--color-text);
  display: block;
}

.app-sidebar__brand-sub {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  margin-top: 2px;
  display: block;
  font-weight: 500;
  letter-spacing: 0.04em;
}

/* 旧クラス（後方互換） */
.app-sidebar__title {
  font-size: 0.8531rem;
  font-weight: 700;
  color: var(--color-sidebar-fg);
  padding: 0 var(--space-xl);
  margin-bottom: var(--space-xl);
  letter-spacing: 0.02em;
}

/* ナビゲーション本体 */
.app-sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  padding: var(--space-md) var(--space-md);
}

.app-sidebar__nav-section {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding: var(--space-lg) var(--space-md) var(--space-sm);
}

.app-sidebar__nav-section:first-child {
  padding-top: var(--space-sm);
}

.app-sidebar__nav a {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  color: var(--color-sidebar-nav);
  font-size: 0.8125rem;
  font-weight: 500;
  position: relative;
  transition: background-color var(--transition-base),
              color var(--transition-base);
  text-decoration: none;
}

.app-sidebar__nav a:hover {
  background: var(--color-sidebar-hover-bg);
  color: var(--color-sidebar-hover-fg);
  text-decoration: none;
}

.app-sidebar__nav a.is-current {
  background: var(--color-sidebar-current-bg);
  color: var(--color-sidebar-current-fg);
  font-weight: 600;
}

/* アクティブ項目の左側アクセントバー */
.app-sidebar__nav a.is-current::before {
  content: '';
  position: absolute;
  left: -3px;
  top: 8px;
  bottom: 8px;
  width: 2px;
  background: var(--color-sidebar-accent);
  border-radius: 2px;
}

.app-sidebar__nav-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* サイドバー下部のユーザー情報 */
.app-sidebar__user {
  padding: var(--space-md) var(--space-lg);
  border-top: 1px solid var(--color-hairline);
  display: flex;
  align-items: center;
  gap: var(--space-md);
  background: var(--color-sidebar-bg-2);
}

.app-sidebar__user-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  /* S-1/S-2: グラデーション上の白文字が明側で 3.68:1、
     自動検査では親背景 #FAFAF9 に対し 1.04:1 と判定されていた。
     単色のプライマリ（#1F1F1F）にすれば白文字で 16.5:1 になり、
     デジタル庁パレット外の #5B7CFA / #7C3AED も同時に排除できる。 */
  background: var(--color-primary);
  color: var(--color-bg-card);
  display: grid;
  place-items: center;
  font-size: 0.75rem;
  font-weight: 600;
  flex-shrink: 0;
}

.app-sidebar__user-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

.app-sidebar__user-label {
  display: none; /* 新デザインではロール直下に表示するため不要 */
}

.app-sidebar__user-name {
  display: block;
  color: var(--color-text);
  font-weight: 600;
  font-size: 0.75rem;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-sidebar__user-role {
  display: block;
  color: var(--color-text-muted);
  font-size: 0.75rem;
  margin-top: 2px;
  line-height: 1.2;
}

/* ---- メインエリア ---- */
.app-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--color-bg);
}

/* ページ内側の共通余白 */
.app-main__inner {
  max-width: var(--content-max-width);
  width: 100%;
  margin: 0 auto;
  padding: var(--page-padding-y) var(--page-padding-x);
}

/* ============================================================
 * 4. ページヘッダー（共通）
 *    全画面共通のページ見出し。サンセリフ 20px / 600 に統一。
 *    タイトルとアクション（日付選択等）を 1 行に並べ、
 *    サブタイトル（__desc）は flex の独立行へ折り返す。
 *    旧称（page-head 系）は本コンポーネントへ統合し重複を排除。
 * ============================================================ */
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-lg);
  flex-wrap: wrap;
  margin-bottom: var(--space-xl);
  padding-bottom: var(--space-md);
  border-bottom: 1px solid var(--color-hairline);
}

.page-header__title {
  font-family: var(--font-sans);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--color-text);
  margin: 0;
  line-height: 1.3;
}

/* サブタイトル：flex の独立行へ落とすため basis:100%。
   ヘッダー外に兄弟配置した場合も block として同じ見た目になる */
.page-header__desc {
  flex-basis: 100%;
  margin: 4px 0 0;
  color: var(--color-text-muted);
  font-size: 0.8125rem;
  line-height: 1.65;
}

.page-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

/* ============================================================
 * 5. カード
 * ============================================================ */
.card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-xl);
  margin-bottom: var(--space-lg);
}

.card__title {
  font-size: 0.875rem;
  font-weight: 600;
  margin: 0 0 var(--space-md);
  color: var(--color-text);
}

.card__lead {
  margin: 0 0 var(--space-lg);
  color: var(--color-text-muted);
  font-size: 0.8125rem;
}

/* カード内のタイトル + 操作行（同じ高さで横並び） */
.card__head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  flex-wrap: wrap;
  margin-bottom: var(--space-lg);
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--color-hairline);
}

/* ============================================================
 * 6. 共通フォーム要素
 * ============================================================ */
.form-row {
  margin-bottom: var(--space-lg);
}

.form-label {
  display: block;
  font-weight: 600;
  font-size: 0.75rem;
  color: var(--color-text-secondary);
  margin-bottom: 6px;
}

.form-label__required {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  background: var(--color-danger-bg);
  color: var(--color-danger);
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 10px;
  vertical-align: middle;
}

.form-label__optional {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  background: var(--color-bg-soft);
  color: var(--color-text-muted);
  font-size: 0.75rem;
  font-weight: 500;
  border-radius: 10px;
  vertical-align: middle;
}

.form-input,
.form-select,
.form-textarea {
  width: 100%;
  padding: 8px 12px;
  font-size: 0.8125rem;
  font-family: inherit;
  color: var(--color-text);
  background: var(--color-bg-card);
  border: 1px solid var(--color-hairline-dark);
  border-radius: var(--radius-sm);
  transition: border-color var(--transition-fast),
              box-shadow var(--transition-fast);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
  border-color: var(--color-text);
  box-shadow: 0 0 0 3px rgba(20, 20, 18, 0.08);
}

/* S-5: キーボード操作時は必ず輪郭を出す。
   旧実装は :focus で outline:none にし box-shadow だけに頼っていたが、
   input[type=date] のようにブラウザ側UIを持つ要素では影が視認しにくく、
   フォーカス位置が分からなくなる場合があった。 */
.form-input:focus-visible,
.form-select:focus-visible,
.form-textarea:focus-visible {
  outline: 2px solid var(--color-info);
  outline-offset: 2px;
}

.form-input[readonly],
.form-textarea[readonly] {
  background: var(--color-bg-soft);
  color: var(--color-text-muted);
  cursor: not-allowed;
}

.form-input--narrow { max-width: 200px; }
.form-input--medium { max-width: 320px; }

.form-help {
  margin: 4px 0 0;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.form-error {
  margin: 4px 0 0;
  font-size: 0.75rem;
  color: var(--color-danger);
  min-height: 1em;
}

.form-actions {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-top: var(--space-xl);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-hairline);
}

.form-preview {
  display: inline-block;
  padding: 8px 14px;
  background: var(--color-bg-soft);
  border: 1px dashed var(--color-hairline-dark);
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  color: var(--color-text-secondary);
  margin-top: 6px;
}

/* ============================================================
 * 7. ボタン（共通）
 * ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: 8px 16px;
  font-size: 0.75rem;
  font-weight: 600;
  font-family: inherit;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background-color var(--transition-fast),
              border-color var(--transition-fast),
              color var(--transition-fast),
              opacity var(--transition-fast),
              transform 80ms;
  text-decoration: none;
  white-space: nowrap;
}

.btn:active:not(:disabled) {
  transform: scale(0.98);
}

.btn:disabled,
.btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn--primary {
  background: var(--color-primary);
  color: var(--color-bg-card);
  border-color: var(--color-primary);
}

.btn--primary:hover:not(:disabled) {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
  text-decoration: none;
  color: var(--color-bg-card);
}

.btn--secondary {
  background: var(--color-bg-card);
  color: var(--color-text);
  border-color: var(--color-hairline-dark);
}

.btn--secondary:hover:not(:disabled) {
  background: var(--color-bg-hover);
  border-color: var(--color-hairline-dark);
  text-decoration: none;
}

.btn--ghost {
  background: transparent;
  color: var(--color-text-secondary);
  border-color: transparent;
}

.btn--ghost:hover:not(:disabled) {
  background: var(--color-bg-hover);
  color: var(--color-text);
  text-decoration: none;
}

.btn--danger {
  background: var(--color-danger);
  color: var(--color-bg-card);
  border-color: var(--color-danger);
}

.btn--danger:hover:not(:disabled) {
  background: var(--color-pri-high-fg);
  border-color: var(--color-pri-high-fg);
  text-decoration: none;
  color: var(--color-bg-card);
}

/* CSV エクスポートボタン（ガイドブック チェックリスト #26 / P3-1）。
   表やパネルの見出し右端に置く。0 件のときは共通処理が disabled にする。 */
.btn--csv { flex: 0 0 auto; white-space: nowrap; }
.btn--csv::before {
  content: '\2913';           /* ⤓ 下向き矢印。文字なのでアイコン資産を増やさない */
  margin-right: 4px;
  font-size: 1.05em;
  line-height: 1;
}

.btn--sm {
  padding: 5px 12px;
  font-size: 0.75rem;
}

/* ============================================================
 * 8. 通知・エラー・状態表示
 * ============================================================ */
.alert {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 0.8125rem;
  margin-bottom: var(--space-lg);
  border: 1px solid transparent;
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  line-height: 1.6;
}

.alert::before {
  content: '';
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex: 0 0 auto;
  margin-top: 3px;
}

.alert--error {
  background: var(--color-danger-bg);
  border-color: var(--color-danger-border);
  color: #991B1B;
}
.alert--error::before { background: var(--color-danger); }

.alert--success {
  background: var(--color-success-bg);
  border-color: var(--color-success-border);
  color: #14532D;
}
.alert--success::before { background: var(--color-success); }

.alert--warning {
  background: var(--color-warning-bg);
  border-color: var(--color-warning-border);
  color: #78350F;
}
.alert--warning::before { background: var(--color-warning); }

.alert--info {
  background: var(--color-info-soft);
  border-color: #93C5FD;
  color: #1E40AF;
}
.alert--info::before { background: var(--color-info); }

.status-msg {
  font-size: 0.75rem;
  color: var(--color-success);
  min-height: 1em;
}

.status-msg.is-error { color: var(--color-danger); }

.loading {
  padding: var(--space-xl);
  text-align: center;
  color: var(--color-text-muted);
  font-size: 0.8125rem;
}

/* ============================================================
 * 9. テーブル（共通）
 * ============================================================ */
.table {
  width: 100%;
  border-collapse: collapse;
  background: var(--color-bg-card);
  font-size: 0.75rem;
}

.table thead th {
  background: var(--color-bg-soft);
  padding: var(--space-md) var(--space-lg);
  text-align: left;
  font-weight: 600;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.table tbody td {
  padding: var(--space-md) var(--space-lg);
  border-bottom: 1px solid var(--color-hairline);
  color: var(--color-text);
}

.table tbody tr:last-child td {
  border-bottom: none;
}

.table tbody tr {
  transition: background-color var(--transition-fast);
}

.table tbody tr:hover {
  background: var(--color-bg-soft);
}

.table__num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
}

.table-wrap {
  overflow-x: auto;
  border-radius: var(--radius-sm);
}

/* ============================================================
 * 10. ユーティリティ
 * ============================================================ */
.is-hidden {
  display: none !important;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.text-muted { color: var(--color-text-muted); }
.text-center { text-align: center; }
.text-right { text-align: right; }

.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }

/* ============================================================
 * 10-A. アクセシビリティ共通（S-5 / S-6 / 2026-08-21 追加）
 * ============================================================ */

/* スクリーンリーダー専用テキスト。
   表の <caption> など、視覚的には不要だが読み上げには必要な情報に使う。 */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* S-5: フォーカスリングの共通定義。
   なぜ :where() を使うか:
     詳細度を 0 にすることで、各画面の既存 :focus 定義を上書きせず、
     「定義が無い要素にだけ」フォーカスリングを与えられる。
     実測でフォーカスリング欠落が 46/517 あり、その大半は
     .btn と JS 生成の擬似ボタンだった。 */
:where(a, button, select, input, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--color-info);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* S-5: JS 生成の擬似ボタン。Brio.bindPseudoButton() が付与する。 */
.is-interactive {
  cursor: pointer;
}

/* ============================================================
 * 10-B. メタ帯（S-3 / 2026-08-21 追加）
 *
 * 用途:
 *   「このデータはいつ時点のものか」「対象期間」「出典」「注記」を
 *   画面上部に一貫した形で示す共通部品。
 * なぜ共通化するか:
 *   デジタル庁ガイドブック 4.4「データを定義する」「メタ情報を記載する」は
 *   全ダッシュボードに課される要件であり、画面ごとに実装すると
 *   表記ゆれと実装漏れが必ず起きる（監査時点で17画面すべてが欠落していた）。
 * 配置規約:
 *   page-header の直下、フィルター群より上。
 *   ガイドブック 3.4「フィルターの影響を受ける情報はその下か右」に従い、
 *   メタ帯は対象データの範囲を宣言する位置に置く。
 * ============================================================ */
.brio-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm) var(--space-lg);
  padding: var(--space-sm) 0 var(--space-md);
  margin-bottom: var(--space-md);
  border-bottom: 1px solid var(--color-hairline);
  font-size: 0.75rem;
  color: var(--color-text-secondary);
}

.brio-meta__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

.brio-meta__label {
  color: var(--color-text-muted);
}

.brio-meta__value {
  color: var(--color-text-secondary);
}

.brio-meta__item:empty {
  display: none;
}

/* 鮮度切れ。色だけに依存しないよう ::before で記号を併記する（G10）。 */
.brio-meta--stale .brio-meta__item[data-meta="as-of"] {
  color: var(--color-danger);
  font-weight: 600;
}

.brio-meta--stale .brio-meta__item[data-meta="as-of"]::after {
  content: "（更新が滞っています）";
  font-weight: 400;
}

.brio-meta__notes-toggle {
  background: none;
  border: 1px solid var(--color-hairline-dark);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-sm);
  font-size: 0.75rem;
  color: var(--color-text-secondary);
  cursor: pointer;
  min-height: 24px;
}

.brio-meta__notes {
  flex-basis: 100%;
  margin: var(--space-xs) 0 0;
  padding-left: 1.4em;
  font-size: 0.75rem;
  color: var(--color-text-secondary);
}

/* ============================================================
 * 10-C. KPI 比較（デルタ）（S-4 / 2026-08-21 追加）
 *
 * 用途:
 *   KPI カードに「前日比 +12.3%」のような比較行を描画する共通部品。
 * なぜ共通化するか:
 *   ガイドブック 3.3「比較対象を提供する」は全KPIに課される要件。
 *   画面ごとに実装すると記号・色・文言がばらつき、
 *   「何との比較か分からない数値」が生まれる。
 * 原型:
 *   assets/js/operation_analysis_business.js の前期間比実装を昇格させたもの。
 * 表示規約:
 *   - 記号（▲▼＝）を必ず付ける。色のみに依存しない（G10）。
 *   - 比較対象名を必ず併記する。
 *   - 比較対象が無い場合は「—（比較対象なし）」と明示し、
 *     0 扱いにして ▼100% を出してはならない。
 * ============================================================ */
.kpi-delta {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 2px var(--space-xs);
  margin-top: var(--space-xs);
  font-size: 0.75rem;
  line-height: 1.4;
}

.kpi-delta__mark {
  font-weight: 700;
}

.kpi-delta__value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.kpi-delta__label {
  color: var(--color-text-muted);
}

.kpi-delta--good  .kpi-delta__mark,
.kpi-delta--good  .kpi-delta__value { color: var(--color-success); }
.kpi-delta--bad   .kpi-delta__mark,
.kpi-delta--bad   .kpi-delta__value { color: var(--color-danger); }
.kpi-delta--flat  .kpi-delta__mark,
.kpi-delta--flat  .kpi-delta__value { color: var(--color-text-secondary); }
.kpi-delta--none  { color: var(--color-text-muted); }

/* 分母併記（mode: 'share'）。'19 / 22台' のような表示。 */
.kpi-delta__share {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-secondary);
}

/* KPI ラベル直下のデータ定義注記。
   ガイドブック 4.4「データを定義する」への対応。 */
.kpi-hint {
  margin-top: 2px;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--color-text-muted);
}

/* ============================================================
 * 11. 旧トップヘッダー互換クラス（後方互換のみ。新規利用禁止）
 * ============================================================ */
.app-header {
  background: var(--color-sidebar-bg);
  color: var(--color-sidebar-fg);
  padding: 12px 0;
  border-bottom: 1px solid var(--color-hairline);
}

.app-header__inner {
  max-width: var(--content-max-width);
  margin: 0 auto;
  padding: 0 var(--space-lg);
  display: flex;
  align-items: center;
  gap: var(--space-xl);
}

.app-header__title {
  font-size: 1rem;
  margin: 0;
}

.app-header__nav {
  flex: 1;
  display: flex;
  gap: var(--space-lg);
}

.app-header__nav a {
  color: var(--color-sidebar-nav);
  text-decoration: none;
  font-size: 0.8125rem;
}

.app-header__nav a.is-current {
  color: var(--color-sidebar-current-fg);
  font-weight: 600;
  border-bottom: 2px solid var(--color-sidebar-accent);
}

.app-header__user {
  font-size: 0.75rem;
  color: var(--color-sidebar-nav);
}

/* ============================================================
 * 12. レスポンシブ
 * ============================================================ */
@media (max-width: 1280px) {
  :root {
    --content-max-width: 1100px;
    --page-padding-x: 24px;
  }
}

@media (max-width: 960px) {
  :root {
    --sidebar-width: 64px;
    --page-padding-x: 20px;
  }
  .app-sidebar__brand-text,
  .app-sidebar__nav a span:not(.app-sidebar__nav-badge),
  .app-sidebar__nav-section,
  .app-sidebar__user-body {
    display: none;
  }
  .app-sidebar__brand {
    padding: 20px 12px 16px;
    justify-content: center;
  }
  .app-sidebar__nav a {
    justify-content: center;
    padding: var(--space-md);
  }
  .app-sidebar__user {
    justify-content: center;
    padding: var(--space-md);
  }
  .page-header {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 640px) {
  :root {
    --page-padding-x: 16px;
    --page-padding-y: 20px;
  }
}

/* ------------------------------------------------------------
 * S-8: スマートフォン幅（2026-08-21 追加）
 *
 * 監査実測（390px）:
 *   横スクロール 3画面 / タップ領域 24px 未満 149個 /
 *   12px 未満フォント 最大 1,127要素 / 実測最小 8.94px
 *
 * 規約:
 *   1. body に横スクロールを発生させない。広いコンテンツは
 *      自身の overflow-x コンテナ内でスクロールさせる。
 *   2. フォントサイズ下限 12px（= 0.75rem）。
 *      2026-08-22 P3-9: html への font-size 固定を撤去したため、
 *      ルートは利用者のブラウザ設定（既定 16px）に従う。
 *      以降 font-size は rem で書く（0.75rem = 既定環境で 12px）。
 *   3. タップ領域は最小 44x44px。
 *   4. フィルタ群は狭幅で折り返すか1列にする。
 * ------------------------------------------------------------ */
@media (max-width: 480px) {
  :root {
    --page-padding-x: 12px;
    --page-padding-y: 16px;
  }

  /* 規約1: ページ本体は横スクロールしない */
  body {
    overflow-x: hidden;
  }

  /* 規約1: 表は自身のラッパ内でスクロールさせる */
  .table-scroll,
  .card > table,
  .panel > table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* 規約4: ページヘッダの操作群を縦積みにする */
  .page-header__actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: var(--space-sm);
  }

  .page-header__actions .form-input,
  .page-header__actions .form-select {
    width: 100%;
    min-width: 0;
  }

  /* 規約3: 操作要素のタップ領域を確保する */
  .btn,
  .page-header__actions .form-input,
  .page-header__actions .form-select {
    min-height: 44px;
  }

  /* 規約2: 補助テキストの下限 */
  .form-help,
  .text-muted,
  .brio-meta,
  .kpi-hint,
  .kpi-delta {
    font-size: 0.75rem;
  }

  /* グラフは幅に合わせて縮小されるため、狭幅では軸ラベルが判読不能になる。
     ページ本体を横スクロールさせず、グラフ自身のコンテナ内でスクロールさせて
     最低限の描画幅を確保する（S-8 規約1 / ガイドブック 4.4「わかりやすく表記する」）。 */
  .chart-wrap,
  .dash-chart-wrap,
  .od-chart-wrap {
    /* width/max-width を固定しないと、min-width を持つ子 SVG が
       ラッパ自身を押し広げ、結局ページ本体が横スクロールする。 */
    width: 100%;
    max-width: 100%;
    min-width: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .two-col,
  .two-col > * { min-width: 0; max-width: 100%; }
  .chart-wrap > svg,
  .dash-chart-wrap > svg,
  .od-chart-wrap > svg {
    min-width: 560px;
  }

  /* 規約3: 本文中のリンクもタップ対象になる。
     行内配置を壊さないよう inline-flex で縦の当たり判定だけを広げる。 */
  main a[href]:not(.btn) {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ------------------------------------------------------------
 * S-8 規約1（全幅共通）: 表の横スクロールラッパ。
 * 広い表は .table-scroll で包むことで、ページ本体ではなく
 * 表自身がスクロールする。
 * ------------------------------------------------------------ */
.table-scroll {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ------------------------------------------------------------
 * S-6: ソート可能な表見出し。
 * <th scope="col" aria-sort="none"><button data-sort="key">…</button></th>
 * の構造で、キーボード操作とスクリーンリーダー対応を両立する。
 * ------------------------------------------------------------ */
th > button[data-sort] {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  min-height: 24px;
}

th[aria-sort="ascending"]  > button[data-sort]::after { content: "\25B2"; font-size: 0.75rem; }
th[aria-sort="descending"] > button[data-sort]::after { content: "\25BC"; font-size: 0.75rem; }
th[aria-sort="none"]       > button[data-sort]::after { content: "\21C5"; font-size: 0.75rem; opacity: 0.45; }

/* ============================================================
 * 13. サイドバー下部のログアウトボタン（2026-05-20 追加）
 *
 * sidebar.php v1.9 で追加された .app-sidebar__user-logout ボタン用。
 *
 * 設計判断:
 *   - ボタン本体は .btn.btn--ghost.btn--sm を流用（既存コードの再利用）
 *   - 既存 .app-sidebar__user (display:flex, gap, padding) は変更しない
 *   - ボタンは末尾に flex 配置されているため、追加ルールはアイコン枠の
 *     寸法調整と狭幅レスポンス時の挙動のみ
 *   - 既存ロゴ／ナビアイコンと同じ stroke 表現で視覚的に統一
 * ============================================================ */
.app-sidebar__user-logout {
  flex-shrink: 0;
  /* アイコン1個分の最小ボタンサイズ。.btn--sm の padding を上書き */
  padding: 6px;
  /* btn のデフォルトに含まれる gap を打ち消す（アイコンのみのため） */
  gap: 0;
  color: var(--color-text-muted);
}

.app-sidebar__user-logout:hover:not(:disabled) {
  /* 既存 .btn--ghost:hover は --color-bg-hover に変えるが、
     サイドバー上では --color-sidebar-hover-bg の方が背景と調和する */
  background: var(--color-sidebar-hover-bg);
  color: var(--color-danger);
}

.app-sidebar__user-logout .app-sidebar__nav-icon {
  /* ナビアイコン (16px) と同寸 */
  width: 16px;
  height: 16px;
}

/* 狭幅時はアバターのみ表示・ユーザー名/ロール非表示の規則が
 * 既存 @media (max-width:960px) に存在する。ログアウトボタンは
 * その時も維持する（小さいので邪魔にならない）。
 * justify-content:center が当たっているため特に追加CSS不要。 */


/* ============================================================
 * 14. KPI サマリカード（2026-05-21 追加）
 *
 * 用途:
 *   - 各マスタ画面の上部サマリ（カード4〜5枚並び）の共通スタイル。
 *   - 車両マスタ（vehicles.php）と停留所マスタ（stop_master.php）で
 *     同一のカード見た目を使うため、共通化（絶対ルール「同じ処理を
 *     複数箇所に書かない」）。
 *
 * 設計判断:
 *   - 既存 stop_master.css に書かれていた .sm-kpi*（停留所マスタ専用）
 *     を本ブロックに昇格・改名し、汎用化した（クラス名 kpi-summary*）。
 *   - 色は CSS 変数（--color-primary / --color-success / --color-info /
 *     --color-warning / --color-danger）を参照し、ハードコーディング
 *     しない（stop_master.css の旧版は #4caf50 等の直書きだったが、
 *     共通化に伴いトークン準拠へ刷新）。
 *   - モディファイア命名はセマンティック方式:
 *       (デフォルト)              … プライマリ（黒系）
 *       .kpi-summary__card--success … 緑（多数派・正常）
 *       .kpi-summary__card--info    … 青（中間情報）
 *       .kpi-summary__card--accent  … 橙（注意・少数派）
 *       .kpi-summary__card--danger  … 赤（警告・要対応）
 *
 * 旧クラスとの対応（stop_master.css からの移行表）:
 *   .sm-kpi               → .kpi-summary
 *   .sm-kpi__card         → .kpi-summary__card
 *   .sm-kpi__card--master → .kpi-summary__card--success
 *   .sm-kpi__card--auto   → .kpi-summary__card--accent
 *   .sm-kpi__card--warn   → .kpi-summary__card--danger
 *   .sm-kpi__label        → .kpi-summary__label
 *   .sm-kpi__value        → .kpi-summary__value
 *   .sm-kpi__unit         → .kpi-summary__unit
 *
 * 注: stop_master.css 側の .sm-kpi* 定義は本追加に伴い削除済。
 *     stop_master.php / vehicles.php の HTML も新クラス名に置換済。
 * ============================================================ */
.kpi-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-md);
  margin-bottom: var(--space-xl);
}

.kpi-summary__card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  /* 左側のアクセントバーが本カードの識別シグナル */
  border-left: 4px solid var(--color-primary);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.kpi-summary__card--success { border-left-color: var(--color-success); }
.kpi-summary__card--info    { border-left-color: var(--color-info); }
.kpi-summary__card--accent  { border-left-color: var(--color-warning); }
.kpi-summary__card--danger  { border-left-color: var(--color-danger); }

.kpi-summary__label {
  font-size: 0.75rem;
  color: var(--color-text-secondary);
  font-weight: 600;
}

.kpi-summary__value {
  font-size: 1.4219rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--color-text);
  /* 数字を表組み桁揃え（タブナム）にして桁ジャンプを防ぐ */
  font-variant-numeric: tabular-nums;
}

.kpi-summary__unit {
  font-size: 0.75rem;
  color: var(--color-text-secondary);
}

/* ============================================================
 * 15. 無操作タイムアウト警告モーダル (F-AU02 / v1.3 追加 / 2026-05-21)
 *
 * sidebar.php v2.0 で </aside> 直後に配置される #brio-idle-modal 用。
 * 制御は assets/js/common.js v1.3 の Brio.idleTimer。
 *
 * 設計判断:
 *   - 全画面の最前面に被せるため z-index は 10000（他のモーダルより上）。
 *   - 既存 .card / .btn / .form-* と同じデザイントークン（CSS 変数）を使用し
 *     ハードコーディングを避ける（絶対ルール「マジックナンバー禁止」）。
 *   - position: fixed + flex センタリングで画面中央へ固定。
 *   - hidden 属性で初期非表示。idleTimer が hidden 属性で開閉する。
 *   - 背景クリック/ESC で閉じない仕様のためバックドロップにはイベント無し
 *     （HTML/JS 側でも data-close 系の属性を意図的に付けていない）。
 *   - フォントサイズ・余白は既存 .card 周辺の体感と揃える。
 *   - prefers-reduced-motion で透過アニメーションを抑制（アクセシビリティ）。
 * ============================================================ */
.brio-idle-modal {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
}

.brio-idle-modal[hidden] {
  /* hidden 属性の効きをブラウザ既定に任せず明示的に指定し、上書きに強くする */
  display: none;
}

.brio-idle-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
}

.brio-idle-modal__panel {
  position: relative;
  width: min(420px, 100%);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.brio-idle-modal__header {
  /* タイトル単独。タイトル下に細い区切りで本文と分離 */
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 12px;
}

.brio-idle-modal__title {
  margin: 0;
  font-size: 0.8531rem;
  font-weight: 700;
  color: var(--color-text);
}

.brio-idle-modal__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.brio-idle-modal__desc {
  margin: 0;
  color: var(--color-text-secondary);
  font-size: 0.75rem;
  line-height: 1.6;
}

.brio-idle-modal__countdown-wrap {
  margin: 0;
  color: var(--color-text-secondary);
  font-size: 0.75rem;
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.brio-idle-modal__countdown {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--color-danger);
  /* 数字桁が揺れないように表組み桁揃え */
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.brio-idle-modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  border-top: 1px solid var(--color-border);
  padding-top: 12px;
}

/* アクセシビリティ: 動作減速設定でも違和感がないように */
@media (prefers-reduced-motion: reduce) {
  .brio-idle-modal,
  .brio-idle-modal__panel,
  .brio-idle-modal__backdrop {
    transition: none;
    animation: none;
  }
}

/* 狭幅画面（モバイル）でも内側余白を確保 */
@media (max-width: 480px) {
  .brio-idle-modal__panel {
    padding: 20px;
  }
  .brio-idle-modal__countdown {
    font-size: 1.1375rem;
  }
}

/* ============================================================
 * 16. パネル（2026-07-15 追加 / operation_analysis.css より移動）
 *
 * 用途:
 *   画面内をセクション分割する枠。見出し（.panel__title）＋本体。
 *   .panel__title は flex のため、右寄せしたい補助要素は
 *   margin-left: auto を付けるだけで揃う（例: optimization.css .ro-export）。
 *
 * 設計判断:
 *   - 元は operation_analysis.css のローカル定義だったが、optimization.php
 *     など「operation_analysis.css を読まない画面」が .panel を使用しており、
 *     枠線・余白・タイトルの flex 配置が一切効かない不具合が出ていた。
 *     全画面が読む common.css へ昇格させ、定義を1箇所に集約して根本解決する。
 *   - common.css は各画面固有 CSS より先に読み込まれるため、画面側で
 *     .panel を上書きしたい場合は従来どおり後勝ちで上書きできる。
 *   - 値は移動前の定義から不変（既存画面の見た目を変えないため）。
 * ============================================================ */
.panel {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  margin-bottom: 0.6094rem;
}

.panel__title {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text-secondary);
  margin: 0 0 10px 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* .panel__title は space-between のため、要素が 3 つになると補助テキストが
   中央へ流れる。CSV ボタンだけを右端へ寄せ、見出しと補助テキストは左に保つ。 */
.panel__title > .btn--csv { margin-left: auto; }

.panel__title-aux {
  font-size: 0.75rem;
  color: var(--color-text-muted, #999);
  font-weight: 400;
}

/* ============================================================
 * 17. ローディングオーバーレイ（2026-07-16 追加 /
 *     operation_analysis.css の .oa-loading より移動・改称）
 *
 * 用途:
 *   重い同期処理の実行中に画面全体を覆い「処理中」を明示する。
 *   制御は common.js の Brio.Loading（表示遅延・最低表示時間・保険タイマ）。
 *   DOM は各画面が持つ。id は画面ごと、class は本共通コンポーネントを指す。
 *
 * 設計判断:
 *   - 元は運行分析・業務画面のローカル定義（.oa-loading）だったが、
 *     路線最適化提案画面でも同じものが必要になった。複製は
 *     「同じ処理を複数箇所に書かない」に反するため common.css へ昇格し、
 *     画面非依存であることが分かる .brio-loading へ改称した。
 *   - 既定は display:none。JS が .is-active を付与して開く。
 *   - 進捗 % は出さない（同期処理のため算出不能）。不定スピナーのみ。
 *   - z-index は 2000。#brio-idle-modal（10000）より下に置き、
 *     セッション切れ警告は集計中でも必ず前面に出るようにする。
 *   - prefers-reduced-motion では回転を緩めるが、停止はしない
 *     （「処理中である」という情報が失われるため）。
 * ============================================================ */
.brio-loading {
  position: fixed;
  inset: 0;
  z-index: 2000;                 /* サイドバー等より前面 / アイドルモーダルより背面 */
  display: none;                 /* 既定は非表示。JS が .is-active で開く */
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.62);
  -webkit-backdrop-filter: blur(1.5px);
  backdrop-filter: blur(1.5px);
  cursor: progress;
}

.brio-loading.is-active { display: flex; }

.brio-loading__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 22px 30px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
}

.brio-loading__spinner {
  width: 34px;
  height: 34px;
  border: 3px solid var(--color-primary-light);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: brio-loading-spin 0.8s linear infinite;
}

.brio-loading__text {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text);
}

/* 長時間実行（BUG-049）。閉じずに「まだ動いている」ことを伝えるため、
   補助文を強調して静止画面との区別をつける。 */
.brio-loading.is-slow .brio-loading__sub {
  color: var(--color-warning, #D97706);
  font-weight: 600;
}
.brio-loading__sub {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

@keyframes brio-loading-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .brio-loading__spinner { animation-duration: 2.4s; } /* 回転を緩め、目的は維持 */
}
