/* plive 管理ページ共通スタイル
 *
 * 管理は4ページに分かれている（admin.html＝ハブ / admin-users / admin-servers / admin-output）。
 * ページ毎に <style> を持つと同じ 200 行を4重に抱えることになるので、ここに集約する。
 * テーマ変数（--bg 等）は index.html / monitor.html のインライン定義と同じ値。
 * ※ FOUC 防止のテーマ適用スクリプトだけは各ページの <head> にインラインで置く（描画前に走らせる必要があるため）。
 */

/* ★配色トークン（--bg / --link / --idle …）の定義は **public/theme.css** に移した
   （2026-08-16）。このファイルより**先に**読み込むこと。同じ値を4箇所に写していたのを
   1箇所にするための移動で、ライトの実測値を入れるときにずれないようにする。 */

*{box-sizing:border-box}
body{
  margin:0; min-height:100vh; font-family:var(--sans); font-size:15px; line-height:1.6; color:var(--text);
  -webkit-font-smoothing:antialiased;
  /* ★平らな地にする。コンソールは装飾で階層を作らず、線と余白で作る。 */
  background:var(--bg);
}
.wrap{ max-width:1080px; margin:0 auto; padding:0 18px 48px; }
body[data-auth="pending"] .wrap{ visibility:hidden; }

.topbar{ display:flex; align-items:center; justify-content:space-between; gap:14px; padding:16px 0; border-bottom:1px solid var(--line); flex-wrap:wrap; }
.brand{ display:flex; align-items:center; gap:12px; text-decoration:none; color:inherit; }
/* ★ロゴは横長（文字＋矢印）を高さで置く。幅は viewBox 比で決まる。
   文字は currentColor＝ライトでもダークでもこの1つで足りる。 */
.brand .logo{ height:24px; width:auto; flex:none; }
.brand-name{ font-family:var(--display); font-weight:700; letter-spacing:.04em; font-size:16px; }
/* ★ロゴは design/logo/plive-logo.svg（文字をパス化したもの）に置き換える。
   この規則は差し替えが済むまでの繋ぎ。 */
.brand-name .accent{ color:var(--accent); }
.brand-sub{ font-family:var(--sans); font-size:12px; line-height:16px; letter-spacing:normal; color:var(--text-faint); margin-top:2px; }
.brand-ver{ font-family:var(--mono); font-size:9px; color:var(--text-faint); opacity:.7; }
.brand-ver:empty{ display:none; }
.topbar-right{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.nav-link{ display:inline-flex; align-items:center; gap:7px; text-decoration:none; font-family:var(--sans); font-size:13px; line-height:20px; font-weight:600;
  color:var(--text-dim); padding:3px 11px; border-radius:var(--radius); border:1px solid var(--line-2); background:transparent;
  transition:color .15s, border-color .15s; }
.nav-link:hover{ color:var(--text); border-color:var(--text-dim); }
.nav-link svg{ width:14px; height:14px; }
/* ログアウトは <button> だが、隣の「‹ 管理」と同じ見た目にする（探させない）。 */
button.nav-link{ cursor:pointer; font-family:var(--sans); }
.role-pill{ font-family:var(--sans); font-size:12.5px; line-height:20px; letter-spacing:normal; color:var(--text-dim); font-weight:600;
  padding:3px 11px; border-radius:var(--radius); border:1px solid var(--line-2); background:transparent;
  max-width:260px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.role-pill[hidden]{ display:none; }
/* リージョン。★AWS のコンソールと同じ位置（ナビとテーマ切替の間）に、枠を付けずに置く。
   ★見た目もコンソールに合わせて**太字＋▼**（2026-08-15・要望）。ただし固定文字列で
   選べない（このシステムは ap-northeast-1 だけで動く）ので、カーソルも下線も変えない。 */
.region{ font-family:var(--sans); font-size:13px; line-height:20px; font-weight:700;
  color:var(--text); white-space:nowrap; cursor:default; }
.region .caret{ width:10px; height:10px; margin-left:7px; vertical-align:baseline; color:var(--text-dim); }
.theme-toggle{ display:inline-grid; place-items:center; width:34px; height:34px; flex:none; cursor:pointer; color:var(--text-dim);
  border-radius:var(--radius); border:1px solid var(--line-2); background:transparent; transition:color .15s, border-color .15s; }
.theme-toggle:hover{ color:var(--text); border-color:var(--text-dim); }
.theme-toggle svg{ width:18px; height:18px; }
.theme-toggle .ico-moon{ display:none; }
:root[data-theme="light"] .theme-toggle .ico-sun{ display:none; }
:root[data-theme="light"] .theme-toggle .ico-moon{ display:block; }

h1{ font-family:var(--display); font-weight:700; font-size:22px; margin:26px 0 3px; letter-spacing:-.01em; color:var(--text); }
.lede{ color:var(--text-dim); font-size:14px; margin:0 0 20px; }

/* ★管理ページ間のタブ（`.subnav`）は 2026-08-16 に廃止した。左ナビ（NAV）と
   **同じものの2つ目の定義**で、項目も食い違っていた。狭い画面での行き来は
   下の「狭い画面」の引き出し（同じ NAV を出す）が担う。 */

.panel{ border-radius:var(--radius-box); border:1px solid var(--line); background:var(--panel);
  padding:20px 22px; margin-bottom:18px; }
.panel h2{ font-family:var(--display); font-size:16px; font-weight:700; margin:0 0 4px; }
.panel .hint{ color:var(--text-dim); font-size:12.5px; margin:0 0 18px; }
/* ★注意書き（守らないと本番が止まる類）は薄い文字に埋もれさせない。issue #17 */
.panel .hint[data-tone="warn"]{ color:var(--text); border-left:3px solid var(--warn);
  padding:8px 12px; background:color-mix(in srgb, var(--warn) 8%, transparent); border-radius:0 6px 6px 0; }
.panel.muted{ opacity:.62; }

/* --- コンテナ（AWS のコンソールと同じ作り・2026-08-14 第3ステップ）--------------------
   組み立ては admin-common.js の upgradePanels()。★見出しの行に操作が**右揃え**で載り、
   線で本体と分かれる。旧版は「見出し → 説明 → 中身 → 一番下にボタン」で、パネルが
   長いとスクロールしないと操作に辿り着けなかった（それが「前のまま」の中身）。
   ★組み立て前（data-box が無い）のパネルは旧来の padding のまま＝壊さない。 */
.panel[data-box="1"]{ padding:0; }
.p-head{ display:flex; align-items:flex-start; gap:16px; padding:12px 20px;
  border-bottom:1px solid var(--line); }
.p-ttl{ flex:1; min-width:0; }
/* ★見出しは 18px/22px（コンソールの Container header）。h2 の既定 16px より一段大きい。 */
.p-head h2{ font-size:18px; line-height:22px; margin:0; }
/* 件数。「いくつあるか」を表を読む前に言う。数そのものは色を付けない。 */
.p-head h2 .cnt{ margin-left:7px; font-size:15px; font-weight:400; color:var(--text-faint); }
.p-head h2 .cnt:empty{ display:none; }
.p-head .hint{ margin:3px 0 0; }
/* ★上下は**見出しの上端に揃える**（実物のスクリーンショットを測ったらそうなっていた:
   アイコンの上端 63px / 見出しの上端 63px）。中心合わせにすると 3px 上がって実物とずれる。 */
.p-acts{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; flex:none; }
/* アイコンだけの操作（更新など）。コンテナ見出しの右端。
   ★実物のスクリーンショットを画素で測って合わせた（2026-08-16・利用者の指摘2回目）:
     ・**丸い枠**（角丸四角でも、枠なしでもない）… 外径 28px・線 1px
     ・中のアイコンは 15px、枠と同じ色
     ・色は #43b4ff ＝ `--link` そのもの（実測で一致した）
     ・並べるときの間隔は 8px（`.p-acts` の gap）
   ★上下は `.p-acts` が見出しの上端に揃える（実物も同じ）。 */
/* ★`padding:0` が要る（2026-08-16・利用者の指摘「ずれています」）。<button> には
   ブラウザ既定の padding（左右 6px）があり、中身の升目が**内側の箱より広くなる**と
   はみ出しが右だけに出る＝アイコンが 2px 右へずれる。place-items:center は
   「升目の中で中央」なので、これでは直らない。 */
.act-icon{ display:inline-grid; place-items:center; padding:0; width:28px; height:28px; flex:none; cursor:pointer;
  color:var(--link); border-radius:999px; border:1px solid var(--link); background:transparent;
  transition:color .15s, border-color .15s, background .15s; }
.act-icon:hover{ color:var(--link-h); border-color:var(--link-h); background:color-mix(in srgb, var(--link) 12%, transparent); }
.act-icon:disabled{ cursor:default; opacity:.6; }
.act-icon svg{ width:20px; height:20px; }   /* 本家と同じ「28px の枠に 16px の絵」（2026-08-16 に合わせ直した） */
/* 取得中は回す（押したのに何も起きない時間を作らない）。★spin は下で定義済みのものを使う。 */
.act-icon[data-busy="1"] svg{ animation:spin 1s linear infinite; }
.p-body{ padding:16px 20px 18px; }
/* 中身が無いのに余白だけの帯が残らないようにする（空の説明・未表示のメッセージを畳む）。 */
.p-body:empty{ display:none; }
.panel .hint:empty{ display:none; }
/* 保険: 組み立ての後にページ側が直接足した要素にも余白を付ける。 */
.panel[data-box="1"] > :not(.p-head):not(.p-body){ padding-left:20px; padding-right:20px; }
/* ★表はコンテナの端まで伸ばす（コンソールの表は本文の余白より外まで線が引かれる）。 */
.p-body > .table-scroll{ margin:0 -20px; padding:0; }
.p-body > .table-scroll:first-child{ margin-top:-16px; }
.p-body > .msg:not([data-kind]){ display:none; }

/* 見出しの行（ページの操作は右端）。★AWS の資源ページと同じ並び。 */
.pagehead{ display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap; }
.ph-l{ flex:1; min-width:0; }
.ph-acts{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; flex:none; padding-bottom:20px; }

/* ハブ（admin.html）のカード */
.menu{ display:grid; gap:14px; }
.card{ display:flex; align-items:center; gap:16px; padding:20px 22px; border-radius:var(--radius-box); text-decoration:none; color:inherit;
  border:1px solid var(--line); background:var(--panel);
  transition:border-color .15s, background .15s; width:100%; text-align:left; font-family:var(--sans); font-size:15px; cursor:pointer; }
/* ★浮かせない（transform / 大きな影を使わない）。コンソールは面を動かさない。 */
.card:hover{ border-color:var(--link); background:var(--surface); }
.card .ico{ flex:none; display:grid; place-items:center; width:46px; height:46px; border-radius:12px;
  color:var(--link); background:color-mix(in srgb, var(--link) 10%, transparent); border:1px solid color-mix(in srgb, var(--link) 26%, transparent); }
.card[data-kind="servers"] .ico{ color:var(--accent); background:color-mix(in srgb, var(--accent) 10%, transparent); border-color:color-mix(in srgb, var(--accent) 24%, transparent); }
.card[data-kind="output"] .ico{ color:var(--text-dim); background:var(--surface); border-color:var(--line); }
.card[data-kind="status"] .ico{ color:var(--live); background:color-mix(in srgb, var(--live) 10%, transparent); border-color:color-mix(in srgb, var(--live) 24%, transparent); }
.card[data-kind="overlay"] .ico{ color:var(--warn); background:color-mix(in srgb, var(--warn) 10%, transparent); border-color:color-mix(in srgb, var(--warn) 26%, transparent); }
.card .body{ flex:1; min-width:0; }
/* title/desc は span なので block 化しないと 1 行に並んでしまう */
.card .title{ display:block; font-family:var(--display); font-weight:700; font-size:16px; margin-bottom:2px; }
.card .desc{ display:block; color:var(--text-dim); font-size:13px; }
.card .arrow{ flex:none; color:var(--text-faint); }
.card:hover .arrow{ color:var(--text-dim); }
.card .badge{ margin-left:10px; font-family:var(--mono); font-size:10.5px; font-weight:600; letter-spacing:.04em;
  color:var(--warn); border:1px solid color-mix(in srgb, var(--warn) 40%, transparent); border-radius:999px; padding:2px 9px; vertical-align:middle; white-space:nowrap; }

/* 追加フォーム */
.form-row{ display:flex; gap:10px; flex-wrap:wrap; align-items:flex-end; }
.field{ display:flex; flex-direction:column; gap:6px; }
/* 伏せ字の入力＋［表示］（2026-08-16・ステップ4-6）。入力欄は伸ばし、ボタンは縮めない。 */
.key-row{ display:flex; align-items:center; gap:8px; }
.key-row input{ flex:1 1 auto; min-width:0; }
.key-row .btn{ flex:none; }

/* ゲストリンクの「視聴中」（2026-08-16・ステップ4-9）。数字は等幅、見ている間だけ色を付ける。 */
.gv{ font-family:var(--mono); font-size:12.5px; color:var(--text-faint); }
.gv[data-on="1"]{ color:var(--live); font-weight:700; }
/* ★項目名は**普通の文（太字）**。旧版の「等幅・大文字・字間広げ」は AWS のコンソールには
   無い書き方で、日本語（受けるサーバー・有効期間）だと字間が空くだけで読みにくかった。
   等幅は**データ**（IP・ID・URL）にだけ使う。 */
.field label{ font-family:var(--sans); font-size:12.5px; line-height:18px; letter-spacing:normal;
  text-transform:none; font-weight:700; color:var(--text-dim); }
input[type="email"], input[type="text"], select{
  font-family:var(--sans); font-size:14px; color:var(--text); background:var(--surface);
  border:1px solid var(--line-2); border-radius:var(--radius); padding:8px 11px; min-width:0;
}
input[type="email"]{ width:290px; max-width:100%; font-family:var(--mono); font-size:13px; }
input[type="email"]:focus, input[type="text"]:focus, select:focus{ outline:2px solid var(--link); outline-offset:1px; }
.mono-in{ font-family:var(--mono); font-size:13px; width:100%; }
.check{ display:inline-flex; align-items:center; gap:8px; font-size:13.5px; color:var(--text-dim); padding-bottom:10px; }
/* ボタン（Cloudscape の丸ピル）。★主ボタンはオレンジ、通常は青の枠線。
   実物のコンソールが主 CTA（インスタンスを起動）をオレンジにしているのに合わせる。
   ★浮かせない・影を落とさない。 */
/* ★寸法は実物を測って合わせた（2026-08-14・AWS コンソールのスクリーンショットを画素で計測）。
   ボタンの高さ **28px** = 行の高さ20 + 上下の余白2 + 枠2。
   line-height を body の 1.5 に任せない（21px になって 8px 高くなる）。 */
.btn{ font-family:var(--sans); font-size:14px; line-height:20px; font-weight:700; cursor:pointer;
  padding:2px 20px; border-radius:20px;
  border:2px solid var(--accent); background:var(--accent); color:var(--on-accent);
  transition:filter .15s, background .15s, border-color .15s, color .15s; }
.btn:hover{ filter:brightness(1.08); }
.btn:active{ filter:brightness(.94); }
.btn:disabled{ opacity:.35; cursor:not-allowed; filter:none; }
/* 通常ボタン＝青の枠線（コンソールの既定の見た目）。 */
.btn-ghost{ background:transparent; color:var(--link); border-color:var(--link); }
.btn-ghost:hover{ background:color-mix(in srgb, var(--link) 8%, transparent); border-color:var(--link-h); color:var(--link-h); filter:none; }
.btn-danger{ background:transparent; color:var(--error); border-color:var(--error); }
.btn-danger:hover{ background:color-mix(in srgb, var(--error) 10%, transparent); filter:none; }
.btn-sm{ font-size:13px; line-height:18px; padding:1px 14px; border-radius:20px; }   /* 24px */

/* 発行したゲスト閲覧リンク（D-5／P25）。★平文が出るのはここだけ・1回だけなので、
 * 見落とさない見た目にして、閉じるまで残す（コピーし損ねたら再発行しかない）。 */
.issued{ margin-top:14px; padding:14px 16px; border-radius:12px;
  background:color-mix(in srgb, var(--live) 8%, transparent); border:1px solid color-mix(in srgb, var(--live) 36%, transparent); }
.issued[hidden]{ display:none; }
.issued-head{ display:flex; align-items:center; gap:12px; justify-content:space-between; margin-bottom:10px; }
.issued-head b{ color:var(--live); font-size:13.5px; }
.issued-row{ display:flex; gap:8px; align-items:center; }
.issued-row input{ flex:1; }
/* 招待の文面（ステップ4-8）。★読むだけ。編集させないが、選んでコピーはできる。 */
.invite-text{ width:100%; box-sizing:border-box; font-family:var(--mono); font-size:12.5px;
  line-height:1.7; color:var(--text-dim); background:var(--surface); border:1px solid var(--line);
  border-radius:8px; padding:10px 12px; resize:vertical; margin-bottom:10px; }
/* ゲストリンクの QR（ステップ4-8）。★地は必ず白（暗い地の上では読み取り機が枠を見つけられない）。 */
.qr-wrap{ display:flex; align-items:center; gap:14px; margin-top:12px; }
.qr-wrap[hidden]{ display:none; }
.qr-box{ width:148px; height:148px; flex:none; background:#fff; border-radius:8px; padding:0; }
.qr-box svg{ display:block; width:100%; height:100%; }
/* 画像で持ち出す口（issue #13）。QR の右に縦に積む。 */
.qr-side{ display:flex; flex-direction:column; align-items:flex-start; gap:8px; }
.qr-acts{ display:flex; gap:8px; flex-wrap:wrap; }

/* メッセージ */
.msg{ display:none; margin-top:14px; padding:11px 14px; border-radius:10px; font-size:13.5px; }
.msg[data-kind="error"]{ display:block; background:color-mix(in srgb, var(--error) 10%, transparent); border:1px solid color-mix(in srgb, var(--error) 34%, transparent); color:var(--text); }
.msg[data-kind="ok"]{ display:block; background:color-mix(in srgb, var(--live) 10%, transparent); border:1px solid color-mix(in srgb, var(--live) 32%, transparent); color:var(--text); }

/* 制御面との接続が切れている間の共通バナー（全管理ページで同じ場所・同じ文言）。
   ★出ている間は画面の値が古いので、パネル全体を薄くして「今の値ではない」と分かるようにする。 */
.connbar{ margin-top:14px; padding:11px 14px; border-radius:10px; font-size:13.5px; color:var(--text);
  background:color-mix(in srgb, var(--warn) 10%, transparent); border:1px solid color-mix(in srgb, var(--warn) 40%, transparent); }
.connbar[hidden]{ display:none; }
.connbar b{ color:var(--warn); }
body[data-conn="lost"] .card{ opacity:.62; }
body[data-conn="lost"] .connbar{ opacity:1; }
/* サービス時間外（issue #5）。★**故障ではない**ので警告色にしない — 予定どおり止まっている、
   と読めるように青（--idle）で出す。中身が古いことは同じなので薄くするのは変えない。 */
body[data-conn="offhours"] .connbar{ opacity:1;
  background:color-mix(in srgb, var(--idle) 10%, transparent);
  border-color:color-mix(in srgb, var(--idle) 40%, transparent); }
body[data-conn="offhours"] .connbar b{ color:var(--idle); }
body[data-conn="offhours"] .card{ opacity:.62; }

/* 直近のジョブ結果（起動に失敗した理由など）。行のそばに残す＝ログ窓を閉じても消えない。 */
.jobnote{ margin-top:6px; font-size:12px; line-height:1.5; color:var(--text-dim); }
.jobnote[data-tone="error"] b{ color:var(--error); }

/* ヘッダーの全体ヘルス。どのページからでも1手でサーバー状態ページへ行ける。 */
.health-pill{ display:inline-flex; align-items:center; gap:7px; text-decoration:none;
  font-family:var(--sans); font-size:12.5px; line-height:20px; color:var(--text-dim);
  padding:3px 11px; border-radius:var(--radius); border:1px solid var(--line-2); background:transparent;
  transition:color .15s, border-color .15s; }
.health-pill:hover{ color:var(--text); border-color:var(--text-dim); }
.health-pill .dot{ width:8px; height:8px; border-radius:50%; flex:none; background:var(--text-faint); }
.health-pill[data-s="ok"] .dot{ background:var(--live); }
.health-pill[data-s="bad"]{ color:var(--error); border-color:color-mix(in srgb, var(--error) 45%, transparent); }
.health-pill[data-s="bad"] .dot{ background:var(--error); }
/* サービス時間外（issue #5）。★異常ではないので赤にしない — 毎晩赤が出ると、
   本当の異常が読み飛ばされるようになる。 */
.health-pill[data-s="off"]{ color:var(--idle); border-color:color-mix(in srgb, var(--idle) 45%, transparent); }
.health-pill[data-s="off"] .dot{ background:var(--idle); }

/* 記号と色の意味の凡例（全ページ共通）。★表の中と**同じ記号・同じ色**で描く
   （凡例だけ別の描き方にすると、見比べても対応が取れない）。 */
.legend{ display:flex; flex-wrap:wrap; gap:8px 20px; margin:12px 0 18px;
  font-family:var(--sans); font-size:12.5px; color:var(--text-faint); }
.legend .lg{ display:inline-flex; align-items:center; gap:7px; }
.legend .dot{ width:auto; height:auto; border-radius:0; flex:none; background:none;
  font-size:12px; line-height:18px; }
.legend .dot::before{ content:'\2014'; }
.legend .lg[data-s="ok"] .dot{ color:var(--live); } .legend .lg[data-s="ok"] .dot::before{ content:'\2713'; }
.legend .lg[data-s="busy"] .dot{ color:var(--warn); } .legend .lg[data-s="busy"] .dot::before{ content:'\25D4'; }
.legend .lg[data-s="bad"] .dot{ color:var(--error); } .legend .lg[data-s="bad"] .dot::before{ content:'\2715'; }
.legend .lg[data-s="idle"] .dot{ color:var(--idle); } .legend .lg[data-s="idle"] .dot::before{ content:'\2298'; }

/* 表。★AWS のコンソールの表に合わせた（2026-08-14 第3ステップ）:
   ・見出しは**普通の文（太字）**。旧版の「等幅・大文字・字間広げ」はコンソールには無く、
     日本語の列名（受けるサーバー・実状態）だと字間だけが広がって読みにくかった。
   ・行に触れると薄く色が付く（どの行を見ているかを見失わない）。
   ・先頭・末尾の桁はコンテナの余白（20px）に揃える＝表だけが浮かない。 */
.table-scroll{ overflow-x:auto; margin:0 -6px; padding:0 6px; }
table{ width:100%; border-collapse:collapse; font-size:13.5px; min-width:640px; }
th, td{ text-align:left; padding:11px 16px; border-bottom:1px solid var(--line); vertical-align:middle; }
th:first-child, td:first-child{ padding-left:20px; }
th:last-child, td:last-child{ padding-right:20px; }
th{ font-family:var(--sans); font-size:12.5px; line-height:18px; letter-spacing:normal;
  text-transform:none; color:var(--text-dim); font-weight:700;
  border-bottom-color:var(--line-2); white-space:nowrap; }
tbody tr{ transition:background .12s; }
tbody tr:hover{ background:var(--surface); }
tbody tr:last-child td{ border-bottom:0; }
td.email, td.mono{ font-family:var(--mono); font-size:12.5px; word-break:break-all; }
td.actions{ text-align:right; white-space:nowrap; }
/* 「あなた」バッジはメール列だけ。登録者列は td.mono にして巻き添えを防ぐ。 */
tr[data-self="1"] td.email::after{ content:'あなた'; margin-left:8px; font-family:var(--sans); font-size:11px; font-weight:600;
  color:var(--text-faint); border:1px solid var(--line-2); border-radius:4px; padding:1px 6px; }
html[lang="en"] tr[data-self="1"] td.email::after{ content:'you'; }
.tag{ display:inline-block; font-family:var(--sans); font-size:12px; line-height:16px; letter-spacing:normal; padding:2px 8px; border-radius:4px;
  border:1px solid var(--line-2); color:var(--text-dim); }
.tag[data-status="active"]{ color:var(--live); border-color:color-mix(in srgb, var(--live) 40%, transparent); }
.tag[data-status="invited"]{ color:var(--warn); border-color:color-mix(in srgb, var(--warn) 40%, transparent); }
select.role-sel{ padding:6px 10px; font-size:12.5px; border-radius:9px; }
.empty{ color:var(--text-faint); font-family:var(--mono); font-size:12.5px; padding:28px 4px; text-align:center; }

/* --- 状態の表示（★全ページで同じ形・2026-08-14 第3ステップ）------------------------
   AWS のコンソールは状態を「**記号 ＋ 色つきの文字**」で書く。光らせない・枠で囲まない。
   ★記号を足したのは飾りではない。色だけで区別させると、色が分かりにくい人には
     「稼働中」と「停止」が同じに見える。記号があれば色が読めなくても判別できる。
   ★意味は STATE_LEGEND（admin-common.js）と同じ5つ。凡例も同じ記号で描く。
       ✓ 正常   ⊘ 停止（起動すれば戻る）   — 未作成・未設定   ✕ 要対応   ◍(回転) 遷移中 */
.srv-state{ display:inline-flex; align-items:center; gap:7px; font-family:var(--sans); font-size:13.5px; }
.srv-state .dot{ width:auto; height:auto; border-radius:0; background:none; flex:none;
  font-size:12px; line-height:20px; }
.srv-state .dot::before{ content:'\25CB'; }
.srv-state[data-s="RUNNING"]{ color:var(--live); }
.srv-state[data-s="RUNNING"] .dot::before{ content:'\2713'; }
/* ★停止は青、未作成は灰（2026-08-12）。同じ灰だと「起動すれば使える」ものと
   「まだ何も無い」ものが見分けられず、一覧から次の操作を判断できなかった。 */
.srv-state[data-s="TERMINATED"]{ color:var(--idle); }
.srv-state[data-s="TERMINATED"] .dot::before{ content:'\2298'; }
.srv-state[data-s="NOT_FOUND"]{ color:var(--text-faint); }
.srv-state[data-s="NOT_FOUND"] .dot::before{ content:'\2014'; }
.srv-state[data-s="PROVISIONING"],.srv-state[data-s="STAGING"],.srv-state[data-s="STOPPING"]{ color:var(--warn); }
/* 遷移中は**回るしるし**にする（コンソールの in-progress と同じ）。止まっている状態と
   見分けが付き、「待てばいい」ことが動きで分かる。 */
.srv-state[data-s="PROVISIONING"] .dot,.srv-state[data-s="STAGING"] .dot,.srv-state[data-s="STOPPING"] .dot{
  width:11px; height:11px; border:2px solid var(--line-2); border-top-color:var(--warn);
  border-radius:50%; animation:spin .8s linear infinite; }
.srv-state[data-s="PROVISIONING"] .dot::before,.srv-state[data-s="STAGING"] .dot::before,
.srv-state[data-s="STOPPING"] .dot::before{ content:''; }
@keyframes pulse{ 0%,100%{opacity:1} 50%{opacity:.35} }
.cpu-bar{ display:inline-block; width:90px; height:8px; border-radius:999px; background:var(--surface); border:1px solid var(--line); overflow:hidden; vertical-align:middle; }
/* ★グラデーションに戻した（2026-08-15・要望／GCP 版と同じ）。塗った部分が
   緑→黄へ流れるので、%を読まなくても詰まり具合が分かる。 */
.cpu-bar > i{ display:block; height:100%; width:0;
  background:linear-gradient(90deg, var(--live), var(--warn)); }
.cpu-txt{ font-family:var(--mono); font-size:11.5px; color:var(--text-dim); margin-left:8px; }
/* サーバー表の「タイプ」の下に出す、この台に入れている本数（と実測の CPU）。
   ★3段階（2026-08-15）: 推奨内は色を付けず、推奨超〜上限内は黄、上限超だけ赤。
     以前は推奨を1本でも超えたら赤で、実測 CPU 50% でも赤が出ていた
     ＝「要対応」の意味が薄れる（表示の5原則）。 */
.srv-cap{ margin-left:0; }
.srv-cap[data-level="warn"]{ color:var(--warn); }
.srv-cap[data-level="error"]{ color:var(--error); }
td.srv-actions{ text-align:right; white-space:nowrap; }
td.srv-actions .btn{ margin-left:6px; }

/* VM の名前の前に置く EC2 のアイコン（2026-08-17・利用者の指定）。
   ★描くのは admin-common.js の ec2Icon()（AWS 公式アイコンの写し）1箇所だけ。
   ★大きさは 16px 固定にする。VM の名前は 13.5px と 15px（表とカードで違う）ので、
     文字に追従させると場所ごとに大きさが変わって「別の絵」に見える。 */
.vm-ico{ width:16px; height:16px; flex:none; border-radius:2px; display:block; }
/* 表（サーバー管理・配信管理）: 2行目（インスタンス名）もアイコンの右へ揃える。 */
.vm-name{ display:flex; align-items:flex-start; gap:8px; }
.vm-name > .vm-ico{ margin-top:2px; }
/* カード（サーバー状態）: 見出しは baseline 揃えなので、アイコンだけ中心に置き直す。 */
.vmcard .hd > .vm-ico{ align-self:center; }

/* 操作ログウィンドウ（作成中／タイプ切替中／完了 などをポーリングで表示） */
.logwin{ display:none; margin-top:16px; border:1px solid var(--line-2); border-radius:12px; overflow:hidden; background:var(--bg); }
.logwin[data-open="1"]{ display:block; }
.logwin .head{ display:flex; align-items:center; gap:10px; padding:10px 14px; border-bottom:1px solid var(--line);
  background:var(--panel-2); font-family:var(--mono); font-size:12px; color:var(--text-dim); }
.logwin .head .spin{ width:12px; height:12px; border-radius:50%; border:2px solid var(--line-2); border-top-color:var(--accent);
  animation:spin .8s linear infinite; flex:none; }
.logwin[data-state="done"] .head .spin{ border-top-color:var(--live); animation:none; border-color:var(--live); }
.logwin[data-state="error"] .head .spin{ border-top-color:var(--error); animation:none; border-color:var(--error); }
@keyframes spin{ to{ transform:rotate(360deg) } }
.logwin .head .ttl{ flex:1; color:var(--text); font-weight:600; }
.logwin .head .x{ cursor:pointer; color:var(--text-faint); border:none; background:none; font-size:16px; padding:2px 6px; }
.logwin .head .x:hover{ color:var(--text); }
.logwin .body{ max-height:220px; overflow-y:auto; padding:12px 14px; font-family:var(--mono); font-size:12px; line-height:1.9; }
.logwin .body .line{ display:flex; gap:10px; }
.logwin .body .line .ts{ color:var(--text-faint); flex:none; }
.logwin .body .line .tx{ color:var(--text-dim); white-space:pre-wrap; word-break:break-word; }
.logwin .body .line.ok .tx{ color:var(--live); }
.logwin .body .line.err .tx{ color:var(--error); }

/* SRT 入力 / テストソース パネル
   ★書き込む操作（適用・保存）はコンテナの**下端の帯**に置く（コンソールのフォームと同じ）。
     読むだけの操作（更新・JSON）は見出しの行へ移してある＝どちらを押すのか迷わない。 */
.toolbar{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  margin:18px -20px -18px; padding:14px 20px; border-top:1px solid var(--line); background:var(--surface); }
.toolbar .spacer{ flex:1 1 auto; }
.dirty{ font-family:var(--mono); font-size:11.5px; color:var(--warn); }
.gen-head{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:12px 14px; margin-top:6px;
  border:1px solid var(--line); border-radius:12px; background:var(--surface); }
.gen-head .spacer{ flex:1 1 auto; }
.gen-head .btn{ margin-left:6px; }
/* 「今どの段階か」を1行で説明する。VM の状態（稼働中）だけでは
   「起動したのに映像が来ない」の理由が分からないため、次にすることまで書く。 */
.gen-hint{ display:flex; align-items:flex-start; gap:8px; margin-top:8px; padding:0 4px;
  font-size:12.5px; line-height:1.7; color:var(--text-dim); }
.gen-hint:empty{ display:none; }
.gen-hint::before{ content:''; flex:none; width:6px; height:6px; margin-top:8px; border-radius:50%;
  background:var(--text-faint); }
.gen-hint[data-tone="busy"]{ color:var(--warn); }
.gen-hint[data-tone="busy"]::before{ background:var(--warn); animation:pulse 1.2s infinite; }
.gen-hint[data-tone="live"]{ color:var(--live); }
.gen-hint[data-tone="live"]::before{ background:var(--live); }
.gen-hint[data-tone="error"]{ color:var(--error); }
.gen-hint[data-tone="error"]::before{ background:var(--error); }

/* SRT パラメータ（issue #22）。共通の欄は一段沈めて「表全体に効く設定」だと分かる形にする。 */
.srt-common{ margin-top:16px; padding:12px 14px; border:1px solid var(--line); border-radius:12px;
  background:var(--surface); }
.srt-common-ttl{ font-family:var(--sans); font-size:12.5px; font-weight:700; color:var(--text-dim);
  margin-bottom:12px; }
.srt-common .hint{ margin:10px 0 0; }
/* ★項目名の高さを揃える。既定の flex-end だと、［表示］ボタンを抱えた passphrase の欄だけ
   背が高くなり、その欄の項目名だけ下にずれる。 */
.srt-common .form-row, .srt-sub .form-row{ align-items:flex-start; }
/* 行ごとの上書きは、その行の真下にぶら下げる（どの行の設定かを迷わせない）。 */
.srt-sub > td{ padding-top:0; background:var(--surface); border-top:0;
  box-shadow:inset 3px 0 0 var(--line-2); }
.srt-sub .form-row{ padding:2px 0 10px 12px; }

/* --- 段階表示（どこで止まっているかを一目で分かるようにする）-----------------
   映像が出ない時、利用者は「どの工程まで進んでいるのか」が分からず迷子になる。
   送信VM → 送信プログラム → テスト映像 → SRT 送出 → 受信 の各段を並べ、
   ✓ 済み / ● 進行中 / ✕ ここで止まっている を色で示す。 */
.flow{ display:flex; align-items:stretch; flex-wrap:wrap; gap:0; margin:14px 0 4px;
  border:1px solid var(--line); border-radius:10px; overflow:hidden; background:var(--panel-2); }
.flow-step{ flex:1 1 130px; min-width:130px; padding:9px 12px; border-right:1px solid var(--line); }
.flow-step:last-child{ border-right:0; }
.flow-step .k{ display:flex; align-items:center; gap:6px; font-family:var(--sans); font-size:12px;
  line-height:18px; font-weight:700; letter-spacing:normal; color:var(--text-dim); text-transform:none; }
.flow-step .k::before{ content:''; flex:none; width:7px; height:7px; border-radius:50%; background:var(--text-faint); }
.flow-step .v{ margin-top:3px; font-size:12.5px; font-weight:600; color:var(--text-dim); }
.flow-step[data-s="ok"] .k::before{ background:var(--live); }
.flow-step[data-s="ok"] .v{ color:var(--live); }
.flow-step[data-s="busy"] .k::before{ background:var(--warn); animation:pulse 1.2s infinite; }
.flow-step[data-s="busy"] .v{ color:var(--warn); }
/* ★止まっている段だけを赤で強調する（それ以降は淡いまま＝視線がここに集まる） */
.flow-step[data-s="stop"]{ background:color-mix(in srgb, var(--error) 8%, transparent); }
.flow-step[data-s="stop"] .k::before{ background:var(--error); }
.flow-step[data-s="stop"] .v{ color:var(--error); }
.flow-step[data-s="idle"] .v{ color:var(--text-faint); }
/* 次の一手。ここに「押すべきボタン」を1行で書く。 */
.flow-next{ margin:8px 0 0; padding:10px 13px; border-radius:9px; font-size:12.5px; line-height:1.65;
  background:color-mix(in srgb, var(--warn) 10%, transparent); border:1px solid color-mix(in srgb, var(--warn) 32%, transparent); color:var(--text); }
.flow-next[hidden]{ display:none; }
.flow-next b{ color:var(--warn); }
/* 打ち上げ（P14）の状態。ing-st と同じ見た目を使い回す。 */
.ing-st[data-s="STREAMING"]{ color:var(--live); } .ing-st[data-s="STREAMING"]::before{ content:'\2713'; }
.ing-st[data-s="STARTING"]{ color:var(--warn); } .ing-st[data-s="STARTING"]::before{ content:'\25D4'; }
.ing-st[data-s="STOPPED"]{ color:var(--idle); } .ing-st[data-s="STOPPED"]::before{ content:'\2298'; }
.ing-st[data-s="FAILED"]{ color:var(--error); } .ing-st[data-s="FAILED"]::before{ content:'\2715'; }
.clip-row{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:10px; }
.tag[data-ready="1"]{ color:var(--live); border-color:color-mix(in srgb, var(--live) 40%, transparent); }
.tag[data-ready="0"]{ color:var(--warn); border-color:color-mix(in srgb, var(--warn) 40%, transparent); }
/* Ingress の実状態（LiveKit 上の state.status）。★これも「記号＋文字」に統一する。 */
.ing-st{ display:inline-flex; align-items:center; gap:6px; font-family:var(--sans); font-size:13px;
  letter-spacing:normal; padding:0; border:0; border-radius:0; color:var(--text-dim); white-space:nowrap; }
.ing-st::before{ content:'\25CB'; font-size:12px; }
.ing-st[data-s="ENDPOINT_PUBLISHING"]{ color:var(--live); }
.ing-st[data-s="ENDPOINT_PUBLISHING"]::before{ content:'\2713'; }
.ing-st[data-s="ENDPOINT_BUFFERING"]{ color:var(--warn); }
.ing-st[data-s="ENDPOINT_BUFFERING"]::before{ content:'\25D4'; }
.ing-st[data-s="ENDPOINT_ERROR"]{ color:var(--error); }
.ing-st[data-s="ENDPOINT_ERROR"]::before{ content:'\2715'; }
.ing-st[data-s="ENDPOINT_INACTIVE"]::before{ content:'\2298'; }
/* 入力そのものの実測（解像度 / fps / ビットレート・D-3②）。判定ではなく確認用の数字なので
 * 小さく添えるだけ。取れないときは空＝行の高さも変わらない。 */
.ing-in{ margin-top:4px; font-family:var(--mono); font-size:10.5px; color:var(--text-faint);
  font-variant-numeric:tabular-nums; white-space:nowrap; }
.ing-in:empty{ display:none; }
td.tight{ padding:7px 8px; }
td.tight input[type="text"], td.tight select{ padding:7px 9px; font-size:13px; border-radius:8px; }
/* JSON ビュー（読むだけ）。ダウンロードして別のアプリで開かなくても、
 * 「いま何が保存されているか」と「各項目が何を意味するか」をその場で確かめられるようにする。
 * 編集は上の表で行う＝ここはテキストを選択してコピーできるだけの表示面。 */
.jsonview{ display:none; margin-top:16px; border:1px solid var(--line-2); border-radius:12px; overflow:hidden; background:var(--bg); }
.jsonview[data-open="1"]{ display:block; }
.jsonview .head{ display:flex; align-items:center; gap:10px; padding:10px 14px; border-bottom:1px solid var(--line); background:var(--surface); }
.jsonview .head .ttl{ flex:1; color:var(--text); font-weight:600; font-size:13.5px; }
.jsonview .head .x{ cursor:pointer; color:var(--text-faint); border:none; background:none; font-size:16px; padding:2px 6px; }
.jsonview .head .x:hover{ color:var(--text); }
.jsonview pre{ margin:0; max-height:340px; overflow:auto; padding:12px 14px;
  font-family:var(--mono); font-size:12px; line-height:1.75; color:var(--text-dim); }
.jsonview .keys{ border-top:1px solid var(--line); padding:12px 14px 14px; background:var(--panel); }
.jsonview .keys h3{ margin:0 0 10px; font-family:var(--sans); font-size:12.5px; line-height:18px; letter-spacing:normal;
  text-transform:none; color:var(--text-dim); font-weight:700; }
.jsonview .keys dl{ display:grid; grid-template-columns:auto 1fr; gap:7px 14px; margin:0; font-size:12.5px; line-height:1.65; }
.jsonview .keys dt{ font-family:var(--mono); font-size:12px; color:var(--text); white-space:nowrap; }
.jsonview .keys dd{ margin:0; color:var(--text-dim); }
.jsonview .keys dd b{ color:var(--text); }
@media (max-width:640px){
  .jsonview .keys dl{ grid-template-columns:1fr; gap:2px; }
  .jsonview .keys dd{ margin:0 0 8px; }
}
.hint code, .jsonview .keys code{ font-family:var(--mono); font-size:11.5px; padding:1px 5px; border-radius:5px;
  background:var(--surface); border:1px solid var(--line); color:var(--text-dim); }
.copy-cell{ display:flex; align-items:center; gap:8px; }
.copy-cell code{ font-family:var(--mono); font-size:12px; color:var(--text-dim); word-break:break-all; flex:1; }
/* ★これは「コピー」など**文字入りの小さいボタン**（サーバー状態の表の中）。
   コンテナ見出しの丸いアイコンは `.act-icon`（上の方）で別物。
   2026-08-16 に同じ名前を付けてしまい、後に出てくるこちらが勝って
   「丸いはずのボタンが角丸の灰色」になった。名前は用途で分ける。 */
.icon-btn{ flex:none; cursor:pointer; border:1px solid var(--line-2); background:transparent; color:var(--text-dim);
  border-radius:8px; padding:4px 8px; font-size:11px; font-family:var(--mono); }
.icon-btn:hover{ color:var(--text); border-color:var(--text-dim); }

/* ===== サーバー状態ページ（/admin-status.html・読むだけ）===================
 * 操作ボタンは置かない。ここは「いま何がどうなっているか」を一目で見る面。
 * 表ではなくカードにするのは、VM ごとに見せたい項目の数がまったく違うため
 * （LiveKit は SRT 一覧、送信VMはクリップと listener、配信VMは systemd ユニット）。 */
.stat-row{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; margin:0 0 22px; }
.stat{ padding:14px 16px; border-radius:12px; border:1px solid var(--line); background:var(--panel); }
.stat .k{ font-family:var(--sans); font-size:12.5px; line-height:18px; letter-spacing:normal; text-transform:none; font-weight:700; color:var(--text-dim); }
.stat .v{ font-family:var(--display); font-size:26px; font-weight:700; line-height:1.15; margin-top:6px; }
.stat .v small{ font-size:13px; font-weight:600; color:var(--text-dim); margin-left:3px; }
.stat .s{ font-size:11.5px; color:var(--text-dim); margin-top:3px; }
.stat[data-tone="live"] .v{ color:var(--live); }
.stat[data-tone="warn"] .v{ color:var(--warn); }
.stat[data-tone="error"] .v{ color:var(--error); }
.stat[data-tone="off"] .v{ color:var(--text-faint); }

.cards{ display:grid; grid-template-columns:repeat(auto-fill,minmax(330px,1fr)); gap:14px; }
/* 1枚しか無いカード（制御VM／送信VM／配信VM）は横幅いっぱいに広げ、中身を段組みにする。
   1列のまま置くと右半分が丸ごと空いて、情報量の割に読みづらい。 */
.cards[data-wide="1"]{ grid-template-columns:1fr; }
.vmcard .grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(250px,1fr)); gap:10px 22px; align-items:start; }
/* SRT の一覧だけは升目に押し込めない（URL が切れて読めなくなる）。 */
.vmcard .grid > .sec.full{ grid-column:1 / -1; }
/* ★枠は **2px**（2026-08-16・利用者の指摘「稼働中の緑枠が細すぎて見えない」）。
   ★太さは全状態そろえる（1px と 2px が混ざると、状態が変わるたびに中身が1px動く）。
     `box-sizing:border-box` なので外側の大きさは変わらない。
   ★色の濃さも上げた（28% では 2px にしても地に溶ける）。細さと薄さの両方が原因だった。 */
.vmcard{ border-radius:12px; border:2px solid var(--line); background:var(--panel);
  padding:13px 15px 14px; display:flex; flex-direction:column; gap:10px; }
.vmcard[data-s="RUNNING"]{ border-color:color-mix(in srgb, var(--live) 55%, transparent); }
/* 停止は「起動すれば戻る」＝薄くするだけでなく青で示す（未作成とは意味が違う）。 */
.vmcard[data-s="TERMINATED"]{ border-color:rgba(90,160,255,.45); opacity:.85; }
.vmcard[data-s="NOT_FOUND"]{ opacity:.72; }
.vmcard .hd{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.vmcard .hd .nm{ font-family:var(--display); font-weight:700; font-size:15px; }
.vmcard .hd .sub{ font-family:var(--mono); font-size:10.5px; color:var(--text-faint); }
.vmcard .hd .sp{ flex:1 1 auto; }
.kv{ display:grid; grid-template-columns:auto 1fr; gap:4px 12px; font-size:12.5px; }
.kv dt{ font-family:var(--mono); font-size:10.5px; letter-spacing:.06em; color:var(--text-faint); white-space:nowrap; padding-top:1px; }
.kv dd{ margin:0; color:var(--text-dim); word-break:break-all; }
.kv dd.mono{ font-family:var(--mono); font-size:11.5px; }
.sec{ border-top:1px solid var(--line); padding-top:9px; }
.sec > .t{ font-family:var(--sans); font-size:12.5px; line-height:18px; letter-spacing:normal; text-transform:none; font-weight:700;
  color:var(--text-dim); margin-bottom:6px; display:flex; gap:8px; align-items:center; }
.sec > .t .n{ color:var(--text-dim); }
/* 依存先・ユニットの状態。★枠付きの丸い札をやめ、srv-state と同じ「記号＋文字」にする
   （同じ意味のものが画面によって違う形で出ていた）。 */
.chips{ display:flex; gap:7px 18px; flex-wrap:wrap; }
.chip{ display:inline-flex; align-items:center; gap:6px; font-family:var(--sans); font-size:13px;
  padding:0; border:0; border-radius:0; color:var(--text-dim); white-space:nowrap; }
.chip::before{ content:'\2014'; font-size:12px; color:var(--text-faint); }
.chip[data-s="ok"]{ color:var(--live); } .chip[data-s="ok"]::before{ content:'\2713'; color:inherit; }
.chip[data-s="warn"]{ color:var(--warn); } .chip[data-s="warn"]::before{ content:'\26A0'; color:inherit; }
.chip[data-s="bad"]{ color:var(--error); } .chip[data-s="bad"]::before{ content:'\2715'; color:inherit; }
.srt{ display:flex; flex-direction:column; gap:6px; }
.srt .row{ display:flex; align-items:center; gap:8px; font-size:12px; }
/* ★表と同じ記号にする（同じ意味を2通りの形で描かない）。 */
.srt .row .dot{ width:auto; height:auto; border-radius:0; background:none; flex:none;
  font-size:11px; line-height:16px; color:var(--text-faint); }
.srt .row .dot::before{ content:'\25CB'; }
.srt .row[data-s="ENDPOINT_PUBLISHING"] .dot{ color:var(--live); }
.srt .row[data-s="ENDPOINT_PUBLISHING"] .dot::before{ content:'\2713'; }
.srt .row[data-s="ENDPOINT_BUFFERING"] .dot{ color:var(--warn); }
.srt .row[data-s="ENDPOINT_BUFFERING"] .dot::before{ content:'\25D4'; }
.srt .row[data-s="ENDPOINT_ERROR"] .dot{ color:var(--error); }
.srt .row[data-s="ENDPOINT_ERROR"] .dot::before{ content:'\2715'; }
.srt .row .nm{ flex:none; max-width:38%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.srt .row .u{ flex:1 1 auto; font-family:var(--mono); font-size:10.5px; color:var(--text-faint);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.srt .row .st{ flex:none; font-family:var(--mono); font-size:10.5px; color:var(--text-dim); }
.srt .row[data-off="1"]{ opacity:.5; }
.srt .none{ font-family:var(--mono); font-size:11px; color:var(--text-faint); }
/* カードの CPU 欄。描画は renderCpuInto（サーバー管理の表と同じ実装）で、
   ここではカード幅いっぱいに伸ばす指定だけを足す。★色や値の出し方はここに書かない。 */
.cpu-row{ display:flex; align-items:center; margin-top:6px; }
.cpu-row .cpu-bar{ flex:1 1 auto; width:auto; min-width:60px; height:8px; }
.cpu-row .cpu-txt{ flex:none; min-width:50px; text-align:right; }
/* データの流れ（送信 → 受信 → 出口）。台数と本数だけの簡易図。 */
.flowmap{ display:flex; align-items:stretch; gap:0; flex-wrap:wrap; margin:0 0 22px;
  border:1px solid var(--line); border-radius:12px; background:var(--panel); overflow:hidden; }
.flowmap .node{ flex:1 1 160px; min-width:150px; padding:12px 14px; border-right:1px solid var(--line); }
.flowmap .node:last-child{ border-right:0; }
.flowmap .node .k{ font-family:var(--sans); font-size:12.5px; line-height:18px; letter-spacing:normal; text-transform:none; font-weight:700; color:var(--text-dim); }
.flowmap .node .v{ font-size:14px; font-weight:600; margin-top:4px; }
.flowmap .node .s{ font-size:11.5px; color:var(--text-dim); margin-top:2px; }
.flowmap .node[data-s="live"] .v{ color:var(--live); }
.flowmap .node[data-s="off"] .v{ color:var(--text-faint); }
.asof{ font-family:var(--mono); font-size:11px; color:var(--text-faint); margin:18px 0 0; }

footer{ margin-top:34px; padding-top:16px; border-top:1px solid var(--line); font-family:var(--mono); font-size:11px;
  letter-spacing:.06em; color:var(--text-faint); }
@media (prefers-reduced-motion: reduce){ *{ animation:none !important; transition:none !important } }

/* --- 開発中モード（アクセス制限・2026-08-06）--------------------------------
   ★見落とすと「誰も入れない」だけが残るので、ON のときは面で目立たせる。 */
#maint-panel[data-on="1"]{ border-color:color-mix(in srgb, var(--warn) 55%, transparent);
  background:repeating-linear-gradient(135deg, color-mix(in srgb, var(--warn) 10%, transparent), color-mix(in srgb, var(--warn) 10%, transparent) 14px,
    color-mix(in srgb, var(--warn) 4%, transparent) 14px, color-mix(in srgb, var(--warn) 4%, transparent) 28px); }
.maint-row{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:6px; }
.maint-state{ font-family:var(--mono); font-size:13px; font-weight:700; padding:7px 14px;
  border-radius:999px; border:1px solid var(--line-2); color:var(--text-dim); }
#maint-panel[data-on="1"] .maint-state{ color:var(--warn); border-color:color-mix(in srgb, var(--warn) 60%, transparent);
  background:color-mix(in srgb, var(--warn) 14%, transparent); }

/* --- サービスタイム（issue #5・2026-08-17）------------------------------------
   ★有効のときは面で目立たせる（開発中モードと同じ理由 — 気づかないまま夜に止まると
     「昨日まで動いていたのに」になる）。ただし色は青（--idle）: 故障ではなく予定。 */
#sched-panel[data-on="1"]{ border-color:color-mix(in srgb, var(--idle) 50%, transparent); }
#sched-panel[data-on="1"] .maint-state{ color:var(--idle); border-color:color-mix(in srgb, var(--idle) 60%, transparent);
  background:color-mix(in srgb, var(--idle) 14%, transparent); }
/* ★2列固定（auto-fit にしない）。曜日と時刻は**対**なので、幅によって
   「起動の曜日／起動の時刻／停止の曜日」で改行されると、どれがどの組か読めなくなる。 */
.sched-grid{ display:grid; grid-template-columns:minmax(0,auto) minmax(0,1fr); gap:14px 26px; margin-top:16px; }
@media(max-width:720px){ .sched-grid{ grid-template-columns:minmax(0,1fr); } }
.sched-grid .hint{ margin:0; max-width:46ch; }
/* 時刻の欄は中身に合わせる（欄いっぱいに伸ばすと、何を入れる欄なのか分かりにくい）。 */
.sched-grid input[type="time"]{ width:9.5em; }
/* 曜日のトグル。★チェックボックスを7個並べるより、押せる四角の方が「どの曜日か」を
   一目で数えられる（本番の曜日を間違えると丸一日止まる）。 */
.dow-row{ display:flex; gap:5px; flex-wrap:wrap; }
.dow{ font-family:var(--sans); font-size:12.5px; line-height:20px; width:34px; text-align:center;
  padding:3px 0; border-radius:8px; cursor:pointer; color:var(--text-dim);
  border:1px solid var(--line-2); background:transparent; transition:color .12s, border-color .12s, background .12s; }
.dow:hover{ color:var(--text); border-color:var(--text-dim); }
.dow[aria-pressed="true"]{ color:var(--on-accent); background:var(--accent); border-color:var(--accent); font-weight:700; }
.dow:disabled{ opacity:.5; cursor:default; }

/* --- 画面の骨格（左のサービスナビ）--------------------------------------------
   ★組み立ては admin-common.js の mountShell()。HTML は触らない（6ページ同じなので）。
   上部バーを画面幅いっぱいに出し、その下を「左ナビ｜本文」の2列にする。 */
/* ★行と列は**必ず両方**書く（2026-08-14 に踏んだ）。列だけ指定して行を自動配置に任せると、
   `<body>` に**他人が要素を差し込んだ瞬間に崩れる**。実際、翻訳拡張（DeepL）が body 直下へ
   1個足していたため升目が1つずれ、「使い方」のパネルが画面のはるか下（y≈1289）に置かれ、
   押しても何も出ないように見えていた。★`<script>` は display:none なので升目を取らないが、
   拡張が足す独自要素は inline＝**升目を取る**。こちらの4つを固定すれば、何を差し込まれても
   ずれない（余計な要素は3行目以降へ流れる）。 */
body[data-shell="1"]{ display:grid; grid-template-columns:250px minmax(0,1fr); grid-template-rows:auto 1fr; }
body[data-shell="1"] > .topbar{ grid-column:1 / -1; grid-row:1; }
body[data-shell="1"] .topbar{ padding:0 18px; height:44px; border-bottom:1px solid var(--line); background:var(--panel);
  position:sticky; top:0; z-index:40; }
.sidenav{ grid-column:1; grid-row:2; background:var(--panel); border-right:1px solid var(--line);
  padding:16px 0; position:sticky; top:44px; align-self:stretch;
  min-height:calc(100vh - 44px); max-height:calc(100vh - 44px); overflow:auto; }
.sidenav-head{ display:block; padding:0 18px 14px; text-decoration:none; color:inherit; }
.sidenav-head b{ display:block; font-size:15px; color:var(--text); }
.sidenav-head span{ display:block; font-size:12px; color:var(--text-dim); margin-top:2px; }
/* --- グループ（折り畳める）2026-08-16・要望 --------------------------------------
   ★見出しは**押せる**ので <button>。ブラウザ既定の見た目（枠・背景・中央寄せ・font）を
     全部消してから組み直す。★`padding` は必ず自分で書く — 既定の左右 6px が残ると
     中身が升目より広くなって右へずれる（同じ穴を更新アイコンで踏んだ）。
   ★三角は**形を1つだけ**持ち、畳んだときに 90 度回す。▶ と ▼ の2つの図形を持つと、
     いつか片方だけ直して食い違う。 */
.sidenav .grp{ display:flex; align-items:center; gap:6px; width:100%; box-sizing:border-box;
  margin:0; border:0; background:transparent; text-align:left; cursor:pointer;
  padding:12px 18px 4px; font-family:var(--sans); font-size:14px; line-height:20px; font-weight:400;
  letter-spacing:normal; text-transform:none; color:var(--text); }
/* ★グループ名は項目より**明るい**（AWS コンソールの左ナビと同じ）。以前は逆で、
   一番暗い色の小さな見出しだった＝畳めるように見えない。押せるものは目に入る濃さで出す。 */
.sidenav .grp:hover{ color:var(--link); }
.sidenav .grp .caret{ width:10px; height:10px; flex:none; transition:transform .12s ease; }
.sidenav .grp[aria-expanded="false"] .caret{ transform:rotate(-90deg); }
/* 畳んだ中身。★JS が `hidden` を付ける（読み上げにも Tab 移動にも出さないため）。
   この1行が無いと、後ろの display 指定に負けて畳んでも消えないことがある。 */
.sidenav .nav-items[hidden]{ display:none; }
/* ★1行 **26px** = 20 + 上下3。body の line-height 1.5 のままだと 35px になり、間延びする。 */
/* ★左の余白 34px（＝枠2＋padding32）は、上の三角のぶんグループ名がずれた位置と**同じ**。
   項目がグループ名の真下に並んで、どれがどのグループの中身か線を引かずに分かる。 */
.sidenav a:not(.sidenav-head){ display:flex; align-items:center; gap:10px; padding:3px 18px 3px 32px;
  color:var(--text-dim); text-decoration:none; font-size:14px; line-height:20px;
  border-left:2px solid transparent; }
.sidenav a:not(.sidenav-head):hover{ background:var(--surface); color:var(--link); }
.sidenav a[aria-current="page"]{ border-left-color:var(--link); color:var(--link); font-weight:700; background:var(--surface); }
/* ★画面がまだ無い項目（名前だけ）。<a> ではないので押せない＝リンク切れにならない。
   並びの中の位置だけ先に決めておくためのもので、色を落として「今は行けない」と示す。 */
.sidenav .nav-soon{ display:flex; align-items:center; gap:10px; padding:3px 18px 3px 32px;
  color:var(--text-faint); font-size:14px; line-height:20px; border-left:2px solid transparent;
  cursor:default; }
.sidenav svg{ width:16px; height:16px; flex:none; }
body[data-shell="1"] > .wrap{ grid-column:2; grid-row:2; max-width:1120px; margin:0; padding:0 24px 56px; }
/* パンくず。今どこかを上から順に言う。 */
.crumb{ font-size:12px; color:var(--text-dim); margin:16px 0 0; }
.crumb a{ color:var(--link); text-decoration:none; }
.crumb a:hover{ text-decoration:underline; }
.crumb span{ margin:0 7px; color:var(--text-faint); }
.crumb + h1{ margin-top:10px; }
/* --- 狭い画面（2026-08-16 に作り直し）----------------------------------------
   ★以前は左ナビを隠して各ページの `.subnav`（タブ）を出していた。あれは**2つ目の定義**で、
     管理ページにしか無く、項目も左ナビと一致していなかった（サイト設定も映像モニターも
     出ない）。トップ画面には `.subnav` が無いので、狭い画面では行き来の手段が消えていた。
   ★いまは NAV 一本。狭い画面では左ナビを**引き出し**にして、同じ物を出す。 */
.navtoggle{ display:none; align-items:center; justify-content:center; width:34px; height:34px; flex:none;
  margin-right:6px; cursor:pointer; color:var(--text-dim); border-radius:6px;
  border:1px solid var(--line-2); background:transparent; }
.navtoggle:hover{ color:var(--text); border-color:var(--text-dim); }
.navtoggle svg{ width:18px; height:18px; }
.navscrim{ display:none; position:fixed; inset:44px 0 0; z-index:44; background:rgba(0,0,0,.45); }

/* 本文へのスキップリンク（2026-08-16・ステップ4-5）。★見えるのはフォーカスが当たったときだけ。
   position:fixed ＝ body の升目を取らない（static にすると骨格が1つずれる）。 */
.skiplink{ position:fixed; left:10px; top:-64px; z-index:60; padding:7px 14px; border-radius:6px;
  background:var(--panel); border:1px solid var(--link); color:var(--link);
  font-size:13px; line-height:20px; text-decoration:none; transition:top .12s ease; }
.skiplink:focus{ top:8px; }
.wrap:focus{ outline:none; }
@media(max-width:900px){
  body[data-shell="1"]{ grid-template-columns:minmax(0,1fr); }
  body[data-shell="1"] > .wrap{ grid-column:1; }
  .navtoggle{ display:inline-flex; }
  /* 引き出し。★閉じているときは display:none（画面の外に置くと、はみ出しの検査に映る）。 */
  .sidenav{ display:none; position:fixed; top:44px; left:0; bottom:0; width:250px; z-index:45;
    box-shadow:8px 0 26px rgba(0,0,0,.4); min-height:0; max-height:none; }
  body[data-nav="1"] .sidenav{ display:block; }
  body[data-nav="1"] .navscrim{ display:block; }
}

/* --- 管理トップのダッシュボード -----------------------------------------------
   ★2026-08-16 に1列へ変えた（利用者の指摘「右に無駄に配置されている」）。
   以前は右に 360px の列を常時空けて「注意が必要なもの」を置いていたが、
   **正常なとき（＝ほとんどの時間）は1行しか入らない**ので、画面の3分の1が空いていた。
   いまは整合性の監視を**本文の一番上の帯**にして、無いときは1行に畳む。 */
.dash{ display:grid; grid-template-columns:minmax(0,1fr); gap:0; align-items:start; margin-top:18px; }

/* 整合性の監視の帯。★色は severity（制御面が付ける）で決める＝画面は色に変えるだけ。
   ★消さない。正常時も1行で「いま食い違いはない」と言い切る（空欄だと、問題が無いのか
   監視が止まっているのか区別できない）。 */
.consist-band{ border:1px solid var(--line); border-radius:var(--radius-box); background:var(--panel);
  padding:10px 16px; margin-bottom:18px; }
.consist-band[data-sev="error"]{ border-color:color-mix(in srgb, var(--error) 55%, transparent);
  background:color-mix(in srgb, var(--error) 7%, var(--panel)); }
.consist-band[data-sev="warn"]{ border-color:color-mix(in srgb, var(--warn) 55%, transparent);
  background:color-mix(in srgb, var(--warn) 7%, var(--panel)); }
.cb-head{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
/* ★見出しは記号＋色つきの文字（枠で囲まない・光らせない）。表と同じ作法。 */
.cb-ttl{ font-size:14px; font-weight:700; color:var(--text); }
.cb-ttl::before{ margin-right:7px; }
.consist-band[data-sev="ok"] .cb-ttl::before{ content:'\2713'; color:var(--live); }
.consist-band[data-sev="warn"] .cb-ttl::before{ content:'\26A0'; color:var(--warn); }
.consist-band[data-sev="error"] .cb-ttl::before{ content:'\2715'; color:var(--error); }
.consist-band[data-sev="unknown"] .cb-ttl::before{ content:'\2014'; color:var(--text-faint); }
.consist-band[data-sev="warn"] .cb-ttl{ color:var(--warn); }
.consist-band[data-sev="error"] .cb-ttl{ color:var(--error); }
.cb-sub{ flex:1; min-width:0; font-size:12.5px; color:var(--text-dim); }
.cb-more{ flex:none; font-size:12.5px; color:var(--link); text-decoration:none; }
.cb-more:hover{ text-decoration:underline; }
.cb-list{ margin-top:10px; }

/* リソース。★AWS のコンソールの「リソース」欄と同じ作り（実物を測って合わせた）:
   枠付きのセルを2列、列の間だけ空ける、上下のセルは枠を重ねて線を1本に見せる。
   ラベルは青いリンク、数は右端で**色を付けない**（数える欄であって状態の欄ではない）。 */
.res-grid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:0 18px; margin-top:14px; }
@media(max-width:640px){ .res-grid{ grid-template-columns:minmax(0,1fr); } }
/* ★1セルの高さ **38px** = 20 + 上下8 + 枠2。角は 3px で丸める（真四角ではない）。
   ★セルは**独立した枠**として隣り合う（枠を重ねない）＝行の境目に線が2本見えるのが実物。 */
.res-row{ display:flex; align-items:center; gap:12px; padding:8px 12px;
  border:1px solid var(--line); border-radius:3px;
  text-decoration:none; color:var(--link); font-size:14px; line-height:20px; }
.res-row:hover{ background:var(--surface); }
a.res-row:hover .l{ text-decoration:underline; }
.res-row .l{ flex:1; min-width:0; }
/* ★数もラベルと同じ青（2026-08-16・利用者の指定）。実物のコンソールがそうなっており、
   セル全体が1つのリンクなので、数だけ色を落とすと「押せない部分」に見える。 */
.res-row .v{ color:var(--link); white-space:nowrap; font-variant-numeric:tabular-nums; }
/* リンクでないセル（行き先が無いもの）は青くしない＝押せるものと見分けられる。 */
div.res-row{ color:var(--text-dim); }
div.res-row .v{ color:var(--text-dim); }
/* 稼働中の VM の1時間あたりの概算（2026-08-16）。★リソースの表の外＝数える欄と混ぜない。
   ★色は付けない（「いくらか」は状態ではない）。動いているときだけ数字を本文色にする。 */
.res-cost{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  margin:12px 2px 0; font-size:13.5px; color:var(--text-dim); }
.res-cost .v{ color:var(--text-dim); font-variant-numeric:tabular-nums; }
.res-cost .v[data-on="1"]{ color:var(--text); font-weight:600; }
.res-cost .hint{ margin:0; }

/* 本番前の手順（2026-08-16）。★状態は「記号＋色つきの文字」の約束に合わせる
   （✓＝済み・・＝これから・—＝人が見る）。枠で囲まない・光らせない。 */
.chk{ list-style:none; margin:12px 0 0; padding:0; }
.chk-item{ display:flex; align-items:baseline; gap:10px; padding:7px 0;
  border-top:1px solid var(--line); font-size:14px; line-height:20px; }
.chk-item:first-child{ border-top:0; }
.chk-item::before{ flex:none; width:1.2em; text-align:center; font-weight:700; }
.chk-item[data-s="ok"]::before{ content:'\2713'; color:var(--live); }
.chk-item[data-s="todo"]::before{ content:'\00B7'; color:var(--text-faint); }
.chk-item[data-s="manual"]::before{ content:'\2014'; color:var(--text-faint); }
.chk-item .l{ flex:1; min-width:0; color:var(--link); text-decoration:none; }
.chk-item .l:hover{ text-decoration:underline; }
.chk-item[data-s="ok"] .l{ color:var(--text-dim); }
.chk-item .n{ color:var(--text-faint); font-size:13px; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; max-width:46%; }

/* 配信: 一番よくする操作 */
.out-state{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin:2px 0 14px; }
.out-state b{ font-size:20px; color:var(--text); }
.out-state b[data-tone="live"]{ color:var(--live); }
.out-state b[data-tone="error"]{ color:var(--error); }
.out-state b[data-tone="busy"]{ color:var(--warn); }
.out-state .hint{ margin:0; }
.dash-out .form-row{ margin-top:0; }

/* 注意が必要なもの。★枠の色は severity（制御面が付ける）で決める＝サーバー状態の
   整合性パネルと同じ見え方にする（2026-08-15）。 */
.warn-item{ padding:10px 12px; border-radius:var(--radius); margin-bottom:8px;
  border:1px solid color-mix(in srgb, var(--error) 34%, transparent);
  background:color-mix(in srgb, var(--error) 8%, transparent); }
.warn-item[data-sev="warn"]{ border-color:color-mix(in srgb, var(--warn) 40%, transparent);
  background:color-mix(in srgb, var(--warn) 9%, transparent); }
.warn-item .ttl{ font-size:13.5px; font-weight:600; color:var(--text); }
.warn-item .hint2{ font-size:12.5px; color:var(--text-dim); margin-top:3px; }
.cb-list .warn-item:last-child{ margin-bottom:0; }

/* --- ヘルプパネル（右から出す）------------------------------------------------
   ★AWS コンソールと同じ作法。長い説明の置き場で、開いても**本文は動かない**
   （本文の幅が縮むだけ）。畳む形（details）だと開いた分だけ本文が押し下がり、
   読みながら表を見る、ができない。 */
body[data-shell="1"][data-help="1"]{ grid-template-columns:250px minmax(0,1fr) 320px; }
.helppanel{ display:none; grid-column:3; grid-row:2; background:var(--panel); border-left:1px solid var(--line);
  position:sticky; top:44px; align-self:stretch; min-height:calc(100vh - 44px);
  max-height:calc(100vh - 44px); overflow:auto; }
body[data-help="1"] .helppanel{ display:block; }
@media(max-width:1200px){
  body[data-shell="1"][data-help="1"]{ grid-template-columns:250px minmax(0,1fr); }
  body[data-help="1"] .helppanel{ position:fixed; right:0; top:44px; width:320px; z-index:35;
    height:calc(100vh - 44px); box-shadow:-8px 0 24px rgba(0,0,0,.35); }
}
.hp-head{ display:flex; align-items:center; padding:14px 18px 8px; }
.hp-head h2{ margin:0; font-size:16px; font-weight:700; color:var(--text); }
.hp-x{ margin-left:auto; background:none; border:0; color:var(--text-dim); cursor:pointer;
  font-size:15px; line-height:20px; padding:2px 5px; border-radius:var(--radius); }
.hp-x:hover{ color:var(--text); background:var(--surface); }
.hp-body{ padding:0 18px 28px; font-size:14px; line-height:20px; color:var(--text-dim); }
.hp-body h3{ font-size:14px; line-height:20px; margin:18px 0 6px; color:var(--text); }
.hp-body p{ margin:0 0 10px; }
.hp-body ul{ margin:0 0 10px; padding-left:20px; }
.hp-body li{ margin-bottom:4px; }
.hp-warn{ border-left:3px solid var(--warn); padding:2px 0 2px 11px; margin:0 0 10px; color:var(--text-2, var(--text-dim)); }
/* 状態の凡例。★.srv-state をそのまま置くので、記号も色も表と必ず一致する。 */
.hp-body .hp-states{ list-style:none; padding-left:0; }
.hp-body .hp-states li{ margin-bottom:6px; }
.hp-body .hp-states .srv-state{ font-size:13.5px; }
/* 「どのサイズに何本入るか」。★幅 320px の中に収める（3列・数字は等幅）。
   ★table-layout:fixed が要る。既定の auto だと中身の幅で列が広がり、
     3列目（1080p）がパネルの外へ出る（＝出したはずの情報が読めない）。 */
/* ★min-width を打ち消す。上の `table{ min-width:640px }` はデータの表（横スクロールさせる）
     のためのもので、320px のパネルに入れると 3列目が枠の外へ出て**読めなく**なる。 */
.hp-table{ width:100%; min-width:0; table-layout:fixed; border-collapse:collapse; margin:0 0 10px;
  font-size:12.5px; line-height:16px; }
.hp-table th{ text-align:left; font-weight:600; color:var(--text-dim); padding:0 4px 5px 0;
  border-bottom:1px solid var(--line); }
.hp-table th:first-child{ width:37%; }
.hp-table td{ padding:6px 4px 6px 0; border-bottom:1px solid var(--line); vertical-align:top;
  font-family:var(--mono); font-size:11.5px; word-break:break-word; }
.hp-table td b{ display:block; font-family:var(--sans); font-size:12.5px; color:var(--text); }
.hp-table .hp-mt, .hp-table .hp-lim{ color:var(--text-faint); }
/* 見出し横の「使い方」。★ボタンだがリンクに見せる（AWS の Info と同じ役割）。 */
.info-link{ font-size:14px; line-height:20px; font-weight:400; color:var(--link);
  background:none; border:0; cursor:pointer; padding:0; text-decoration:underline;
  vertical-align:middle; font-family:var(--sans); }
.info-link:hover{ color:var(--link-h); }
