/* ============================================================================
   Portal - コアスタイル（全案件共通）
   見た目は :root のデザイントークンに集約している。案件側は
   static/css/theme.css でトークンを上書きするだけで印象を変えられる。

   カスケードレイヤーの優先順位は core < feature < theme。
   theme は詳細度に関係なく必ず勝つため、案件側は低い詳細度のまま上書きできる。

   このファイルは直接編集しないこと（rd-lab から subtree で取り込む）
   ========================================================================== */

@layer core, feature, theme;

@layer core {
:root {
  /* ---- 色：アクセント（案件のブランドカラー） ---- */
  --accent: #4a5568;
  --accent-soft: #eef0f3;
  --accent-line: #c8cdd4;
  --accent-ink: #ffffff;          /* アクセント背景の上に置く文字色 */

  /* ---- 色：文字 ---- */
  --ink: #1c1f23;
  --ink-mid: #565e68;
  --ink-weak: #8b939d;

  /* ---- 色：面 ---- */
  --bg: #f5f6f8;
  --surface: #ffffff;
  --line: #e2e5ea;
  --line-soft: #eef0f3;
  --surface-muted: #fafbfc;        /* テーブル見出し・行ラベルの面 */

  /* ---- 色：トップバー ---- */
  --nav-bg: #1b1f25;
  --nav-ink: #c9ced6;
  --nav-ink-weak: #7c8492;
  --nav-ink-strong: #ffffff;       /* ブランド名・選択中のタブ */
  --nav-hover: rgba(255, 255, 255, 0.08);
  --nav-border: rgba(255, 255, 255, 0.10);

  /* ---- 色：暗い面（トップバー以外でも使う汎用） ---- */
  --surface-dark: #1b1f25;
  --surface-dark-ink: #ffffff;

  /* ---- 色：状態 ---- */
  --ok: #1a7f4b;
  --ok-bg: #e7f5ed;
  --ok-line: #bfe3ce;
  --warn: #a8620b;
  --warn-bg: #fdf1e0;
  --warn-line: #f0d6ae;
  --danger: #b3261e;
  --danger-bg: #fdecea;
  --danger-line: #f0c4c1;

  /* ---- 書体 ---- */
  --font: -apple-system, BlinkMacSystemFont, "Hiragino Sans", "Noto Sans JP",
          "Yu Gothic", Meiryo, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* ---- 文字サイズ（eu-phoria 基準：rem・偶数梯子・最小 12px）----
     単位は rem（ルート 16px）に統一し、px 換算が偶数梯子
     12 / 14 / 16 / 18 / 20 / 24 / 28 / 32 / 36 に乗るようにしている。
     既存の 3 つ（--font-size / -sm / -xs）は案件側の theme.css から
     参照されうるため、名前は変えずに値だけ基準へ寄せた。
     新しくスタイルを足すときも px を直書きせず、このトークンを使うこと。 */
  --font-size-xs: 0.75rem;        /* 12px  ラベル・補助・バッジ（下限） */
  --font-size-sm: 0.875rem;       /* 14px  テーブル・フォーム・ボタン・タブ */
  --font-size: 1rem;              /* 16px  本文 */
  --font-size-lg: 1.125rem;       /* 18px  小見出し */
  --font-size-xl: 1.25rem;        /* 20px  ページタイトル */
  --line-height: 1.65;            /* 本文 160〜180% */
  --line-height-ui: 1.3;          /* ボタン・ラベル等 120〜140% */
  --heading-weight: 700;

  /* ---- 形 ---- */
  --radius: 8px;                  /* カード・パネル */
  --radius-sm: 6px;               /* ボタン・入力欄 */
  --radius-pill: 999px;           /* チップ・バッジ */

  /* ---- 密度・寸法 ---- */
  --appbar-height: 56px;
  --tab-padding-x: 14px;
  --menu-width: 240px;
  --content-padding: 24px;
  --cell-padding-y: 10px;         /* テーブルの行の高さ */
  --cell-padding-x: 12px;
  --control-padding-y: 8px;       /* ボタン・入力欄 */
  --control-padding-x: 16px;
}


* { box-sizing: border-box; }

/* hidden 属性は必ず効かせる。display を持つクラス（.btn など）に負けないよう
   !important を付ける。カスケードレイヤーでは !important が下の層ほど強いため、
   案件側の theme からも覆されない */
[hidden] { display: none !important; }

/* ---------------------------------------------------------- フォーカスの見え方 */
/* キーボードで操作する人が「いまどこにいるか」を必ず見えるようにする。
   ブラウザ既定の輪郭は濃い面（トップバー）の上では見えないことがあるため自前で引く。

   :where() で包んで詳細度を 0 にしているので、個別の指定（下の [data-href] など）が
   そのまま勝つ。マウスでのクリックには出さない（:focus-visible）。 */
:where(a[href], button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* 濃色のバーの上ではアクセント色のリングが沈むため、明るい色に替える */
.appbar :where(a[href], button):focus-visible {
  outline-color: var(--nav-ink-strong);
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--font-size);
  line-height: var(--line-height);
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); }

code {
  font-family: var(--mono);
  font-size: var(--font-size-sm);
  background: var(--line-soft);
  padding: 1px 5px;
  border-radius: 4px;
}

/* ---------------------------------------------------------------- レイアウト */
/* トップバー（ブランド＋ページタブ＋アカウント）＋その下に本文、の2段構成 */

.appbar {
  display: flex;
  align-items: stretch;
  gap: 4px;
  height: var(--appbar-height);
  padding: 0 16px;
  background: var(--nav-bg);
  color: var(--nav-ink);
  position: sticky;
  top: 0;
  z-index: 20;
}

.appbar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-right: 20px;
  margin-right: 4px;
  border-right: 1px solid var(--nav-border);
  text-decoration: none;
  flex: 0 0 auto;
}

.brand-mark {
  width: 6px;
  height: 20px;
  border-radius: 2px;
  background: var(--accent);
  flex: 0 0 auto;
}

.brand-text {
  font-weight: var(--heading-weight);
  color: var(--nav-ink-strong);
  font-size: var(--font-size-sm);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* ---- ページタブ ---- */
.appbar-tabs { flex: 1 1 auto; min-width: 0; }

.appbar-nav {
  display: flex;
  align-items: stretch;
  gap: 2px;
}

.tab {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 0 var(--tab-padding-x);
  color: var(--nav-ink);
  text-decoration: none;
  font-size: var(--font-size-sm);
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}

.tab:hover { background: var(--nav-hover); color: var(--nav-ink-strong); }

.tab.is-active {
  color: var(--nav-ink-strong);
  font-weight: 600;
  border-bottom-color: var(--accent);
}

/* 外部リンクの印。読ませる文字ではない装飾記号なので、基準の非読了要素の
   例外（10px まで可）を当てている */
.tab-ext { font-size: 0.625rem; opacity: 0.7; }

/* ---- アカウントメニュー ---- */
.usermenu { position: relative; display: flex; align-items: center; flex: 0 0 auto; margin-left: 8px; }

.usermenu-trigger {
  display: flex;
  align-items: center;
  padding: 4px;
  background: none;
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  line-height: 0;
}
.usermenu-trigger:hover { background: var(--nav-hover); }
.usermenu-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.avatar { width: 28px; height: 28px; border-radius: 50%; display: block; }

.avatar-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: var(--font-size-xs);
  font-weight: 600;
  line-height: 1;
}

.usermenu-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  width: var(--menu-width);
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
  overflow: hidden;
}

.usermenu-head { padding: 12px 14px; border-bottom: 1px solid var(--line-soft); }
.usermenu-name { font-weight: 600; font-size: var(--font-size-sm); }
.usermenu-mail { font-size: var(--font-size-xs); color: var(--ink-weak); word-break: break-all; }

.usermenu-items { padding: 4px; }

.usermenu-item {
  display: block;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--ink);
  text-decoration: none;
  font-size: var(--font-size-sm);
}
.usermenu-item:hover { background: var(--accent-soft); color: var(--accent); }

/* ---- 本文 ---- */
.content { padding: var(--content-padding); }

.page-title { font-size: var(--font-size-xl); font-weight: var(--heading-weight); margin: 0 0 16px; }

/* ---- サブナビ（管理画面などの第2階層） ---- */
.subnav-wrap { margin-bottom: 18px; }

.subnav {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--line);
}

.subtab {
  padding: 8px 14px;
  color: var(--ink-mid);
  text-decoration: none;
  font-size: var(--font-size-sm);
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.subtab:hover { color: var(--ink); }
.subtab.is-active { color: var(--accent); font-weight: 600; border-bottom-color: var(--accent); }

/* -------------------------------------------------- 横スクロールするナビゲーション */
/* ページが増えるとタブは1行に収まらなくなる。スクロールバーは意匠上隠しているため、
   端のぼかしと矢印で「続きがある」ことを示す。

   ぼかしも矢印も、実際にはみ出したときだけ portal.js が出す。
   収まっているうちは何も足されない。

   ぼかしの色と矢印の色は、載せる場所ごとに局所トークンで差し替える
   （トップバーは濃色、本文は明るい面）。 */

.hscroll {
  --hscroll-fade: var(--bg);
  --hscroll-arrow-bg: var(--surface);
  --hscroll-arrow-ink: var(--ink-mid);
  --hscroll-arrow-line: var(--line);

  position: relative;
  display: flex;
  min-width: 0;
}

.appbar-tabs {
  --hscroll-fade: var(--nav-bg);
  --hscroll-arrow-bg: var(--nav-bg);
  --hscroll-arrow-ink: var(--nav-ink);
  --hscroll-arrow-line: var(--nav-border);
}

.hscroll-track {
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.hscroll-track::-webkit-scrollbar { display: none; }

.hscroll::before,
.hscroll::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 28px;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.hscroll::before { left: 0; background: linear-gradient(to right, var(--hscroll-fade), transparent); }
.hscroll::after { right: 0; background: linear-gradient(to left, var(--hscroll-fade), transparent); }

.hscroll.can-scroll-left::before { opacity: 1; }
.hscroll.can-scroll-right::after { opacity: 1; }

.hscroll-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  display: none;                  /* 指で流せる端末には出さない（下の hover で復帰） */
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--hscroll-arrow-line);
  border-radius: 50%;
  background: var(--hscroll-arrow-bg);
  color: var(--hscroll-arrow-ink);
  font-size: var(--font-size-sm);
  line-height: 1;
  cursor: pointer;
}

/* ポインタで操作する環境だけ矢印を出す */
@media (hover: hover) {
  .hscroll-arrow { display: block; }
}

/* はみ出していないときは portal.js が hidden を立てる（効かせるのは上の [hidden]） */

.hscroll-arrow:hover { color: var(--hscroll-arrow-ink); filter: brightness(1.25); }
.hscroll-arrow:disabled { opacity: 0.3; cursor: default; }

.hscroll-prev { left: 2px; }
.hscroll-next { right: 2px; }

/* ---------------------------------------------------------------- 処理中の表示 */
/* 遷移はすべてフルページロードで、裏の BigQuery 次第で数秒かかる。
   押した直後に「効いている」ことが分かるよう、画面上端のバーと
   押した要素自身の待機表示を出す。制御は portal.js が一括で行う。
   色は --accent に追従するため、案件側で改めて指定する必要はない。 */

.progressbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 100;              /* .appbar（20）より前に出す */
  background: var(--accent-soft);
  overflow: hidden;
}

.progressbar::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 40%;
  background: var(--accent);
  animation: portal-progress 1.1s ease-in-out infinite;
}

@keyframes portal-progress {
  from { left: -40%; }
  to   { left: 100%; }
}

body.is-navigating,
body.is-navigating a,
body.is-navigating button { cursor: progress; }

/* 押した本人が「どれを押したか」を見失わないよう、その要素だけ沈ませる。
   応答待ちの間に同じ要素を押し直せないようにもする */
.is-busy {
  opacity: 0.55;
  pointer-events: none;
}

/* data-href の要素は tabindex="0" を添えるとキーボードからも開ける。
   その際に現在位置が分かるようフォーカスリングを用意する（行の内側に引く） */
[data-href]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* ------------------------------------------------------------------- 共通部品 */
.badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  background: var(--line-soft);
  color: var(--ink-mid);
  font-size: var(--font-size-xs);
  font-family: var(--mono);
}


.status {
  display: inline-block;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: 600;
  white-space: nowrap;
}

.status-ongoing { background: var(--accent-soft); color: var(--accent); }
.status-returned { background: var(--ok-bg); color: var(--ok); }
.status-warn { background: var(--warn-bg); color: var(--warn); }

.hint {
  display: inline-block;
  font-size: var(--font-size-xs);
  color: var(--warn);
  background: var(--warn-bg);
  padding: 0 6px;
  border-radius: 4px;
  white-space: nowrap;
}

.muted { color: var(--ink-weak); }

.page-desc { color: var(--ink-mid); margin: 0 0 18px; font-size: var(--font-size-sm); }

.sub-head { font-size: var(--font-size-lg); margin: 32px 0 10px; }

.alert { padding: 11px 14px; border-radius: var(--radius); margin-bottom: 16px; font-size: var(--font-size-sm); }
.alert-error { background: var(--danger-bg); color: var(--danger); border: 1px solid var(--danger-line); }
.alert-warn { background: var(--warn-bg); color: var(--warn); border: 1px solid var(--warn-line); }
.alert-success { background: var(--ok-bg); color: var(--ok); border: 1px solid var(--ok-line); }

/* 直前の操作の結果。操作を止めないよう帯で出す（モーダルは使わない）。
   成功のものだけ portal.js が数秒で引っ込める */
.flash { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.flash-message { flex: 1 1 auto; }

.flash-close {
  flex: 0 0 auto;
  padding: 0 2px;
  border: 0;
  background: none;
  color: inherit;
  font-size: var(--font-size);
  line-height: 1.2;
  cursor: pointer;
  opacity: 0.6;
}
.flash-close:hover { opacity: 1; }

/* 代理ログイン中の帯。全ページの最上部に出す。
   **色だけで状態を伝えない**ので、文言で「代理ログイン中」と明示している
   （色が見えない環境でも、なりきったままだと気づけないため） */
.impersonation-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding: 8px var(--content-padding);
  background: var(--warn-bg);
  color: var(--warn);
  border-bottom: 1px solid var(--warn-line);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-ui);
}

.impersonation-text { flex: 1 1 auto; }
.impersonation-stop { flex: 0 0 auto; }

.btn {
  display: inline-block;
  padding: var(--control-padding-y) var(--control-padding-x);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: var(--font-size-sm);
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  line-height: var(--line-height-ui);
}

.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { filter: brightness(0.88); }

.btn-ghost { background: var(--surface); color: var(--ink-mid); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--ink-weak); color: var(--ink); }

.btn-danger { background: var(--surface); color: var(--danger); border-color: var(--danger-line); margin-top: 8px; }
.btn-danger:hover { background: var(--danger-bg); }

.empty-state { text-align: center; padding: 60px 20px; color: var(--ink-mid); }
.empty-note { font-size: var(--font-size-sm); color: var(--ink-weak); }
/* 404 等の数字だけを大きく見せる装飾。梯子の上限（36px）の外だが
   8 の倍数で偶数なのでこの値のまま rem に直した */
.error-code { font-size: 2.5rem; font-weight: 700; color: var(--line); }

/* ------------------------------------------------------------ 確認ダイアログ */
/* ブラウザ標準の confirm()/alert() は使わない（配色も文言も揃えられないため）。
   <dialog> に寄せることで、焦点の閉じ込め・Escape・背景の暗転は標準の挙動に任せる。 */

.modal {
  width: min(420px, calc(100vw - 32px));
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22);
}

.modal::backdrop { background: rgba(15, 18, 22, 0.45); }

.modal-form { margin: 0; padding: 20px 22px 16px; }

.modal-title { font-size: var(--font-size-lg); font-weight: var(--heading-weight); margin: 0 0 8px; }

.modal-text {
  font-size: var(--font-size-sm);
  color: var(--ink-mid);
  line-height: 1.7;
  margin: 0 0 18px;
  white-space: pre-line;           /* 改行入りの文面をそのまま出せる */
}

.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.modal-actions .btn { margin-top: 0; }

/* ---- サーバの画面をモーダルで出す入れ物（data-modal）------------------------ */
/* 確認ダイアログ（上）とは寸法の要件が違う。編集フォームや表が入るので幅を取り、
   画面より高くなったら中身だけを縦スクロールさせる（見出しと閉じるは残す）。
   幅は 720px 止まり。これ以上広げると背後の一覧が隠れて、
   「どの行を直しているか」を確かめられなくなる */
.modal-panel {
  width: min(720px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
}

/* ★display を無条件に書かないこと。
   <dialog> はブラウザ既定の `dialog:not([open]) { display: none }` で隠れている。
   .modal-panel に display: flex を素で書くとその既定を上書きしてしまい、
   **閉じているあいだも空の箱がページに居座る**（実際に踏んだ）。
   縦に積む指定は開いているときだけ当てる */
.modal-panel[open] {
  display: flex;
  flex-direction: column;
}

.modal-panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-muted);
  border-radius: var(--radius) var(--radius) 0 0;
}

.modal-panel-title { margin: 0; flex: 1 1 auto; }

/* モーダルに収まらないときの逃げ道。取得元をそのまま開く */
.modal-panel-full {
  font-size: var(--font-size-xs);
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}
.modal-panel-full:hover { text-decoration: underline; }

.modal-panel-close {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-mid);
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
}
.modal-panel-close:hover { background: var(--surface); border-color: var(--line); color: var(--ink); }

.modal-panel-body {
  padding: 16px 18px 18px;
  overflow-y: auto;
}

/* 差し込んだ画面の先頭・末尾の余白は入れ物側で持つ。二重に空くのを防ぐ */
.modal-panel-body > [data-modal-body] > :first-child { margin-top: 0; }
.modal-panel-body > [data-modal-body] > :last-child { margin-bottom: 0; }

@media (max-width: 600px) {
  /* 狭い画面では画面いっぱいに使う。中央に小さく浮かせると入力欄が窮屈になる */
  .modal-panel {
    width: calc(100vw - 16px);
    max-height: calc(100vh - 16px);
  }
}

/* --------------------------------------------------------------------- ログイン */
.login-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: var(--surface-dark);
}

.login-card {
  width: 360px;
  background: var(--surface);
  border-radius: 12px;
  padding: 32px;
  text-align: center;
}

.login-brand { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 22px; }
.login-brand .brand-text { color: var(--ink); font-size: var(--font-size); }

.login-lead { color: var(--ink-mid); font-size: var(--font-size-sm); margin-bottom: 18px; }

.btn-google {
  display: block;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 11px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-weight: 600;
}
.btn-google:hover { filter: brightness(0.88); }

.login-note { margin-top: 20px; font-size: var(--font-size-xs); color: var(--ink-weak); line-height: 1.7; }

/* ------------------------------------ 確認コード（Google を持たない人のログイン） */
/* 「または」で区切る。Google が主、確認コードが従であることを見た目でも保つ */
.login-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 22px 0 18px;
  color: var(--ink-weak);
  font-size: var(--font-size-xs);
}
.login-divider::before,
.login-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.login-form { text-align: left; }
.login-label { display: block; font-size: var(--font-size-xs); color: var(--ink-mid); margin-bottom: 6px; }
/* 入力欄の文字は 16px（--font-size）以上にする。iOS Safari は font-size が
   16px 未満の input にフォーカスするとページ全体を勝手に拡大し、拡大したまま
   戻らないためレイアウトがずれる。タブレットで使う画面があるので下げない。
   同じ理由で .otp-input / .form-row の input・select・textarea / .filter-field の
   select・input も 16px 以上にしてある */
.login-input {
  width: 100%;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--font-size);
  color: var(--ink);
  background: var(--surface);
}
.login-input:focus { outline: 2px solid var(--accent-line); outline-offset: -1px; }

/* コードは1文字ずつ拾って読む。字を大きく、間隔を空ける */
.otp-input {
  width: 100%;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--mono);
  font-size: 1.75rem;
  letter-spacing: 0.4em;
  text-align: center;
  text-indent: 0.4em;  /* letter-spacing は最後の字の後ろにも入るので、その分だけ寄せ戻す */
  color: var(--ink);
  background: var(--surface);
}
.otp-input:focus { outline: 2px solid var(--accent-line); outline-offset: -1px; }

.btn-block { display: block; width: 100%; margin-top: 10px; padding: 11px; font-weight: 600; }

/* ------------------------------------------------------------------ カード一覧 */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }

.page-card {
  display: block;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
  text-decoration: none;
  color: inherit;
}
.page-card:hover { border-color: var(--accent); }

.page-card-group { font-size: var(--font-size-xs); color: var(--ink-weak); letter-spacing: 0.04em; }
.page-card-name { font-size: var(--font-size); font-weight: 700; margin-top: 4px; }
.page-card-desc { font-size: var(--font-size-sm); color: var(--ink-mid); margin-top: 6px; }

/* ------------------------------------------------------------------- テーブル */
/* 横に長い表は縮めずに、この箱の中で横スクロールさせる（狭い画面の基本方針） */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.data-table { width: 100%; border-collapse: collapse; font-size: var(--font-size-sm); }

.data-table th,
.data-table td {
  padding: var(--cell-padding-y) var(--cell-padding-x);
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}

.data-table thead th {
  background: var(--surface-muted);
  font-size: var(--font-size-xs);
  color: var(--ink-mid);
  font-weight: 600;
  white-space: nowrap;
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
}

.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tr.clickable { cursor: pointer; }
.data-table tr.clickable:hover { background: var(--accent-soft); }
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table .date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.data-table .player { font-weight: 600; }
.data-table .empty-cell { text-align: center; color: var(--ink-weak); padding: 30px; }
.data-table .actions { white-space: nowrap; }
.url-cell { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-inactive { opacity: 0.55; }


/* ------------------------------------------------------ 並べ替えとページ送り */
.data-table thead th.is-sorted { color: var(--accent); }

.sort-link {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}
.sort-link:hover { color: var(--accent); }

/* 印の幅を先に確保しておき、並べ替えを切り替えても列幅が動かないようにする */
/* 並べ替えの▲▼。読ませる文字ではない装飾記号なので非読了要素の例外を当てる */
.sort-mark { display: inline-block; width: 0.9em; font-size: 0.625rem; }

.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
  font-size: var(--font-size-sm);
  color: var(--ink-mid);
}

.pager-controls { display: flex; align-items: center; gap: 8px; }
.pager-pos { font-variant-numeric: tabular-nums; }

.pager-btn {
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-mid);
  text-decoration: none;
}
.pager-btn:hover { border-color: var(--accent); color: var(--accent); }
.pager-btn.is-disabled { opacity: 0.4; border-color: var(--line-soft); }

/* -------------------------------------------------------------------- フィルタ */
/* 項目が1〜2個の軽い絞り込み。3つ以上あるなら .filter-panel を使う */
.filter-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }

/* 絞り込みが増えると、素の並びでは表と地続きに見えて境目が分からない。
   カードに載せて「ここまでが条件、ここからが結果」を面で示す */
.filter-panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 14px;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px 18px;
}

.filter-field { display: flex; flex-direction: column; gap: 4px; min-width: 132px; }

.filter-field label {
  font-size: var(--font-size-xs);
  color: var(--ink-weak);
  letter-spacing: 0.03em;
}

.filter-field select,
.filter-field input[type="date"],
.filter-field input[type="text"],
.filter-field input[type="email"],
.filter-field input[type="search"] {
  font-family: inherit;
  font-size: var(--font-size);   /* iOS の自動ズーム対策。上の .login-input のコメント参照 */
  padding: 6px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
}

.filter-field input[type="date"] { font-variant-numeric: tabular-nums; }

.filter-field select:hover,
.filter-field input[type="date"]:hover { border-color: var(--ink-weak); }

/* 期間は「開始 〜 終了」で1つの意味なので、間に区切りを置いて対にして見せる */
.filter-range { display: flex; align-items: flex-end; gap: 8px; }
.filter-range .range-sep { color: var(--ink-weak); padding-bottom: 7px; }

.filter-actions { display: flex; gap: 8px; margin-left: auto; }

/* 画面には出さず、読み上げにだけ残す（対になる入力のラベルなど） */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 13px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-mid);
  text-decoration: none;
  font-size: var(--font-size-sm);
}
.chip:hover { border-color: var(--accent); }
.chip.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.chip-count { font-variant-numeric: tabular-nums; opacity: 0.75; font-size: var(--font-size-xs); }

.inline-label { font-size: var(--font-size-sm); color: var(--ink-mid); display: flex; align-items: center; gap: 8px; }

/* ------------------------------------------------------------------ フォーム */
.form-panel { margin-bottom: 18px; }
.form-panel > summary { display: inline-block; list-style: none; }
.form-panel > summary::-webkit-details-marker { display: none; }

.edit-form {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
  margin-top: 10px;
}

.form-row { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 12px; }

.form-row label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--font-size-xs);
  color: var(--ink-mid);
}

.form-row label.check { flex-direction: row; align-items: center; gap: 6px; align-self: flex-end; padding-bottom: 8px; }

.form-row input[type="text"],
.form-row input[type="email"],
.form-row input[type="url"],
.form-row input[type="number"],
.form-row select,
.form-row textarea {
  padding: 6px 9px;
  border: 1px solid var(--line);
  border-radius: 5px;
  font-family: inherit;
  font-size: var(--font-size);   /* iOS の自動ズーム対策。上の .login-input のコメント参照 */
  min-width: 180px;
  color: var(--ink);
  background: var(--surface);
}

.form-row input:focus,
.form-row select:focus,
.form-row textarea:focus { outline: 2px solid var(--accent-line); border-color: var(--accent); }

/* 読み取り専用の欄。作ったあとに変えられないキー（ロールID・ページIDなど）に付く。
   押せそうに見えると「変えたのに保存されない」と受け取られるので、面で示す */
.form-row input[readonly] {
  background: var(--surface-muted);
  color: var(--ink-mid);
}

/* まとめて貼り付ける欄（メールアドレスなど）。1行の入力欄と混ぜない */
.form-row textarea {
  min-width: 320px;
  width: 100%;
  resize: vertical;
  line-height: 1.6;
  font-family: var(--mono);
}

.form-row label.field-wide { flex: 1 1 100%; }

/* 一覧の上に置く操作ボタンの並び。モーダルを開くための入口 */
.toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
}

/* フォームの下端。**保存とキャンセルを必ず並べる。**
   以前は <details> に畳んでいて「やめる」手段が無く、閉じ方が分からなかった */
.form-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}

.form-actions .btn { margin-top: 0; }

/* 削除のように、開かないと押せないようにしておきたい操作 */
.form-note {
  margin-top: 14px;
  font-size: var(--font-size-sm);
}

.form-note > summary {
  cursor: pointer;
  color: var(--danger);
}

.form-note .empty-note { margin: 8px 0; }

/* ロールの複数選択。数が増えると縦に伸びるので、箱の中で折り返して流す。
   1人に複数のロールを持たせられる（選んだものの和が権限になる） */
.role-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 8px 12px 10px;
  margin: 0 0 12px;
  max-height: 168px;
  overflow-y: auto;
}

.role-picker legend { font-size: var(--font-size-xs); color: var(--ink-mid); padding: 0 4px; }

/* 想定外の例外の内容（create_app(show_error_detail=True) の案件のみ）。
   読ませるものではなく、そのまま選択して開発者や Claude に渡すためのもの */
.error-detail {
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  line-height: 1.6;
  color: var(--ink-mid);
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--danger);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  margin: 0;
  max-height: 60vh;
  overflow: auto;        /* 縦も横も箱の中で流す。ページ本体は横スクロールさせない */
  white-space: pre;
  -webkit-user-select: all;
  user-select: all;      /* ひと押しで全選択できる */
}

.role-picker label.check {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  font-size: var(--font-size-sm);
  color: var(--ink);
}


.inline-edit > summary { cursor: pointer; list-style: none; }
.inline-edit > summary::-webkit-details-marker { display: none; }
.link { color: var(--accent); font-size: var(--font-size-sm); }
.link:hover { text-decoration: underline; }

.matrix-table .check-col { text-align: center; width: 70px; }
.matrix-table input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); }

/* 列見出しの「すべて」はラベルの下に敷く（横幅を広げないため） */
.matrix-table .check-col .link-btn { display: block; margin: 2px auto 0; }

/* 文字だけのボタン。見た目はリンクだが、押しても遷移しないので button で出す */
.link-btn {
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
  font-size: var(--font-size-xs);
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
}
.link-btn:hover { filter: brightness(0.8); }

.btn-sm { padding: 3px 8px; font-size: var(--font-size-xs); }

/* 表の操作列に POST のフォームを並べるとき用。form は既定でブロックなので、
   隣のリンクと同じ行に収まらない */
.inline-form { display: inline; }
.data-table .actions .link-btn { font-size: var(--font-size-sm); }

/* ---- 行の操作メニュー（三点リーダ） ----
   見た目と項目の作りはアカウントメニュー（.usermenu）に揃えてある。違うのは
   <details> で組んであることで、**JavaScript が動かなくても開ける**。
   ここが開けないと編集も削除もできなくなるため（コアは「JS が無くても機能を
   失わない」を守る）。portal.js が足しているのは閉じる振る舞いだけ。

   ★パネルは**セルの中に流し込む**（position: absolute にしない）。表は
     .table-scroll が横スクロールするので、浮かせると切れるか、表に縦スクロールが
     生まれて壊れて見える。開いているあいだ行が伸びる代わりに、狭い画面でも
     表からはみ出さない。 */
.rowmenu { display: inline-block; }

.rowmenu-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  color: var(--ink-mid);
  font-size: var(--font-size);
  line-height: 1;
  cursor: pointer;
  user-select: none;
  list-style: none;          /* 既定の三角マーカーを消す */
}
.rowmenu-trigger::-webkit-details-marker { display: none; }
.rowmenu-trigger::marker { content: ""; }
.rowmenu-trigger:hover { background: var(--accent-soft); color: var(--accent); }
.rowmenu-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.rowmenu[open] > .rowmenu-trigger { background: var(--accent-soft); color: var(--accent); }

.rowmenu-panel {
  margin-top: 4px;
  padding: 4px;
  min-width: 200px;
  max-width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
  /* 操作列は white-space: nowrap なので、項目が1行に伸び切らないよう戻す */
  white-space: normal;
  text-align: left;
}

.rowmenu-panel form { margin: 0; }

.rowmenu-item {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--ink);
  font-family: inherit;
  font-size: var(--font-size-sm);
  line-height: var(--line-height-ui);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.rowmenu-item:hover { background: var(--accent-soft); color: var(--accent); }

.rowmenu-item-danger { color: var(--danger); }
.rowmenu-item-danger:hover { background: var(--danger-bg); color: var(--danger); }

/* ------------------------------------------------- ロールごとの権限マトリクス */
/* ロールを縦に積む。1枚のカードが1ロールぶんの設定と保存ボタンを持つ */
.role-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
  margin-bottom: 20px;
  /* アンカーで飛んだときに見出しがアプリバーの下へ潜らないようにする */
  scroll-margin-top: calc(var(--appbar-height) + 12px);
}
.role-card.is-inactive { background: var(--surface-muted); }

.role-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.role-card-title { font-size: var(--font-size-lg); margin: 0 0 2px; }
.role-card-actions { margin-top: 12px; }

.role-jump { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 18px; }

/* ------------------------------------------------------------------- 埋め込み */
.embed-frame {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  height: calc(100vh - 190px);
  min-height: 480px;
}
.embed-frame iframe { width: 100%; height: 100%; border: 0; display: block; }

/* --------------------------------------------------------------- レスポンシブ */
/* 段は 900px（タブレット）と 600px（スマートフォン）の2つ。
   メディアクエリの条件にはカスタムプロパティを使えないため、この2つの数値だけは
   コアが直値で持つ。

   狭い画面での詰め方は「トークンを上書きする」形で書いてある。
   注意: 案件側の theme.css で同じトークンを上書きすると theme レイヤーが必ず勝つため、
   ここでの詰めが効かなくなる。密度のトークン（--content-padding など）を
   theme.css で変える場合は、theme.css 側にもメディアクエリを書くこと。 */

@media (max-width: 900px) {
  :root {
    --content-padding: 16px;
    --cell-padding-x: 10px;
  }

  .embed-frame { height: calc(100vh - 160px); }

  /* 絞り込みの操作ボタンを右端に張るのをやめる（折り返しで浮くため） */
  .filter-actions { margin-left: 0; }
}

@media (max-width: 600px) {
  :root {
    --content-padding: 12px;
    --cell-padding-x: 8px;
    --tab-padding-x: 11px;
  }

  /* 絞り込みは最小幅を捨てて詰める。期間は対を崩さず1行を占める */
  .filter-panel { padding: 12px; gap: 10px 12px; }
  .filter-field { min-width: 0; flex: 1 1 8rem; }
  .filter-range { flex: 1 1 100%; }

  /* 限られた幅はタブに回す。ブランドは印だけ残して名前を伏せる */
  .appbar { padding: 0 10px; }
  .appbar-brand { padding-right: 10px; margin-right: 2px; }
  .brand-text { display: none; }

  .usermenu { margin-left: 4px; }
  .usermenu-panel { width: min(var(--menu-width), calc(100vw - 20px)); }

  .page-title { font-size: var(--font-size-lg); }

  .filter-bar { flex-wrap: wrap; gap: 6px; }
  .card-grid { grid-template-columns: 1fr; }

  /* 入力欄は最小幅を解いて1行1項目にする */
  .form-row { gap: 10px; }
  .form-row label { flex: 1 1 100%; }
  .form-row input[type="text"],
  .form-row input[type="email"],
  .form-row input[type="url"],
  .form-row input[type="number"],
  .form-row select { min-width: 0; width: 100%; }

  .login-card { width: auto; max-width: 360px; margin: 0 16px; padding: 24px; }

  .embed-frame { height: calc(100vh - 130px); min-height: 320px; }
}

/* 視差や点滅が苦手な利用者には動きを弱める */
@media (prefers-reduced-motion: reduce) {
  .progressbar::before { animation-duration: 2.6s; }
}

/* --------------------------------------------------------------------- 印刷 */
@media print {
  /* 印刷では画面用の配色を使わず、白地・濃い罫線に固定する（トークン化しない） */
  .appbar, .subnav-wrap, .progressbar { display: none !important; }
  /* 印刷は画面とは別文脈（紙は近くで読む・拡大できない代わりに解像度が高い）。
     画面側の最小 12px は当てず、枚数が増えないようこの値のままにする */
  body { background: #fff; font-size: 10px; }
  .content { padding: 0; }
  .table-scroll { border-color: #999; break-inside: avoid; overflow: visible; }
}
}
