/* ==========================================================================
   共通コンポーネント
   すべての寸法・色はトークン（tokens.css）経由で参照する。
   ========================================================================== */

/* --------------------------------------------------------------------------
   ボタン
   -------------------------------------------------------------------------- */
.lms-btn {
  border-radius: var(--r-8);
  font-weight: var(--fw-medium);
  font-size: var(--fs-14);
  font-family: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: background var(--dur-card), border-color var(--dur-card);
}

.lms-btn--primary {
  background: var(--c-blue-600);
  color: var(--c-white);
  border: none;
  padding: 9px 18px;
}

.lms-btn--primary:hover {
  background: var(--c-blue-700);
}

.lms-btn--ghost {
  background: var(--c-white);
  color: var(--c-gray-700);
  /* 部品を識別する唯一の視覚情報なので装飾罫線 --c-border(1.24:1) ではなく
     --c-border-input を使う（WCAG 1.4.11 の 3:1。統合レポート §6） */
  border: 1px solid var(--c-border-input);
  padding: 9px 16px;
}

.lms-btn--ghost:hover {
  background: var(--c-gray-50);
}

.lms-btn--danger {
  background: var(--c-white);
  /* hover で背景が --c-red-50 になるため、hover 時も 4.5:1 を満たす --c-red-700 に統一する（部品 #1） */
  color: var(--c-red-700);
  border: 1px solid var(--c-red-200);
  padding: 9px 16px;
}

.lms-btn--danger:hover {
  background: var(--c-red-50);
}

.lms-btn--danger-solid {
  background: var(--c-red-600);
  color: var(--c-white);
  border: none;
  padding: 9px 18px;
}

.lms-btn--danger-solid:hover {
  background: var(--c-red-700);
}

/* サイズ・幅のバリアント */
.lms-btn--block {
  width: 100%;
}

/* 角丸を最大にしたピル型（ログインの「Log in」ボタン。試作サイト rounded-full） */
.lms-btn--pill {
  border-radius: var(--r-pill);
}

.lms-btn--sm {
  padding: 6px 12px;
  font-size: var(--fs-12-5);
}

.lms-btn--xs {
  padding: 4px 10px;
  font-size: var(--fs-12);
}

.lms-btn:disabled,
.lms-btn.is-disabled,
.lms-btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
}

/* 表の操作列で使う正方形アイコンボタン */
.lms-icon-btn {
  background: none;
  /* .lms-btn--ghost と同じ理由で --c-border-input（WCAG 1.4.11。統合レポート §6） */
  border: 1px solid var(--c-border-input);
  border-radius: var(--r-7);
  width: 32px;
  height: 32px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--c-gray-700);
}

.lms-icon-btn:hover {
  background: var(--c-gray-50);
}

.lms-icon-btn--danger {
  /* hover 背景が --c-red-50 になるため --c-red-700（部品 #1） */
  color: var(--c-red-700);
}

.lms-icon-btn--danger:hover {
  background: var(--c-red-50);
  border-color: var(--c-red-200);
}

/* --------------------------------------------------------------------------
   カード
   -------------------------------------------------------------------------- */
.lms-card {
  background: var(--c-bg-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-12);
  padding: 24px;
}

/* テーブルを収めるとき: 内側余白をなくし角を丸く抜く */
.lms-card--flush {
  padding: 0;
  overflow: hidden;
}

.lms-card--tight {
  padding: 18px;
}

.lms-card--login {
  padding: 28px;
}

/* クリックできるカード（ホームのチャプターカード） */
.lms-card--clickable {
  cursor: pointer;
  transition: box-shadow var(--dur-card), transform var(--dur-card);
  display: block;
  color: inherit;
}

.lms-card--clickable:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   フォーム
   -------------------------------------------------------------------------- */
.lms-input,
.lms-select,
.lms-textarea {
  width: 100%;
  border: 1px solid var(--c-border-input);
  border-radius: var(--r-8);
  padding: 9px 12px;
  font-size: var(--fs-14);
  font-family: inherit;
  color: var(--c-text);
  background: var(--c-white);
}

.lms-input:focus,
.lms-select:focus,
.lms-textarea:focus {
  outline: none;
  border-color: var(--c-blue-600);
  box-shadow: 0 0 0 3px var(--c-blue-50);
}

.lms-select,
.lms-input[type="date"] {
  cursor: pointer;
}

.lms-select--min {
  min-width: 160px;
}

.lms-textarea {
  min-height: 110px;
  resize: vertical;
}

.lms-input.is-invalid,
.lms-textarea.is-invalid {
  border-color: var(--c-red-200);
}

.lms-field {
  margin-bottom: 16px;
}

.lms-field > label {
  display: block;
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  color: var(--c-gray-700);
  margin-bottom: 6px;
}

.lms-field-error {
  color: var(--c-red-600);
  font-size: var(--fs-12-5);
  margin-top: 6px;
}

/* ヒント（8文字以上で入力してください 等。パスワード系フォームの常時表示） */
.lms-hint {
  font-size: var(--fs-12-5);
  color: var(--c-text-faint);
  margin-top: 6px;
}

/* ログイン画面上部の全体エラー（auth / tasks 2.2） */
.lms-login-error {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--c-red-50);
  border: 1px solid var(--c-red-200);
  color: var(--c-red-700);
  border-radius: var(--r-8);
  padding: 10px 12px;
  font-size: var(--fs-13);
  margin-bottom: 16px;
}

/* 入力欄下の文字数カウンタ */
.lms-counter {
  font-size: var(--fs-11);
  color: var(--c-text-faint);
  text-align: right;
  margin-top: 4px;
}

.lms-counter.is-over {
  color: var(--c-red-600);
}

.lms-check-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-14);
  /* WCAG 2.2 の 2.5.8（24×24 CSS px）。実測 22px に対し行高の下限を直接固定する
     （UI/UX レビュー 2026-07-27 部品 #27）。cursor: pointer は既存。 */
  min-height: 24px;
  cursor: pointer;
  margin-bottom: 18px;
}

.lms-check-row input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--c-blue-600);
}

/* カード状のラジオ（ステータス変更モーダル） */
.lms-radio-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--c-border);
  border-radius: var(--r-8);
  cursor: pointer;
  background: var(--c-white);
}

.lms-radio-card input[type="radio"] {
  accent-color: var(--c-blue-600);
}

/* .is-selected は status-modal.ts が JS で付ける（進捗のステータス変更モーダル）。
   :has() は JS なしで同じ見た目を得るための追加経路で、本 change の
   ロール選択ラジオ（発行フォーム・権限変更モーダル・昇格確認モーダル）が使う
   （add-instructor-and-root-roles 05_ui.md §4。画面ごとの個別 JS は書かない方針
   ＝ design.md D4 / CLAUDE.md「TS の UI 部品は data 属性駆動の共通初期化」）。
   ステータス変更モーダル側にも同時に効くが、JS が付ける .is-selected と
   同じ宣言なので見た目は変わらない。 */
.lms-radio-card.is-selected,
.lms-radio-card:has(input[type="radio"]:checked) {
  border-color: var(--c-blue-600);
  background: #f8fbff;
}

.lms-radio-card__label {
  font-size: var(--fs-13-5);
  font-weight: var(--fw-medium);
}

.lms-radio-card__current {
  font-size: var(--fs-11);
  color: var(--c-text-faint);
  margin-left: auto;
}

/* --------------------------------------------------------------------------
   テーブル
   -------------------------------------------------------------------------- */
.lms-table {
  width: 100%;
  border-collapse: collapse;
}

/* 一覧テーブルの横スクロールラッパー。.lms-card--flush の「内側」に置く。
   カード自身を overflow: auto にしないのは、(1) 複数画面で共用されている、
   (2) overflow-x を auto にすると overflow-y の計算値も auto になり角丸のクリップと
   競合する、という 2 点による（fix-user-table-overflow design.md D2）。
   使う側は tabindex="0" + role="region" + aria-label を必ず付ける（同 D4。
   スクロール領域へキーボードで到達できるようにするため / WCAG 2.1.1）。
   min-width は折り返し（.is-wrap）有効時に狭幅で列が 1 文字幅まで潰れるのを防ぐ下限
   （GitHub issue #5）。

   background の 4 レイヤーは「横スクロールできる／続きの列がある」ことを示す手掛かり
   （unify-admin-table-scroll-layout design.md D4）。JS を一切使わない:
   - 前半 2 レイヤー = 端のマスク。background-attachment: local なので「内容と一緒に」動く
   - 後半 2 レイヤー = 影。background-attachment: scroll なのでコンテナに固定される
   先に書いたレイヤーが上に来るので、マスクが影を覆う。左端にいるときは左マスクが左影の
   真上にあって影が見えず、右へスクロールするとマスクだけが左へ流れて影が現れる。
   右端に到達すると右マスクが右影を覆って右の影が消える。=「両端では該当側の手掛かりが
   出ない」という要件がこれだけで成立する。
   ★ 前提: マスク色に --c-bg-surface（白）を使うため、.lms-table-scroll は白地
   （.lms-card--flush = .lms-card の背景）の上にあること。現在の利用箇所 3 つ
   （user-list.html / checkpoints.html / submissions.html）は全てこれを満たす。
   別の背景色のカードに置く場合はマスク色の参照先を見直すこと。
   ★ 既知の見え方: .lms-table th は不透明な背景（--c-bg-subtle）を持つため、影は
   ヘッダー行の帯では見えず、データ行の高さでのみ見える。tr.is-orphan / tr.lms-row-detail も
   不透明背景なので同様。仕様どおりで不具合ではない。
   ★ メディアクエリで囲まないこと。PC 幅ではテーブルが収まるので両端のマスクが両方の影を
   覆い、手掛かりは自動的に見えなくなる（要件「収まっているときは出さない」）。 */
.lms-table-scroll {
  overflow-x: auto;
  background:
    linear-gradient(to right, var(--c-bg-surface) 30%, transparent) left / 24px 100% no-repeat
      local,
    linear-gradient(to left, var(--c-bg-surface) 30%, transparent) right / 24px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, var(--c-shadow-scroll-edge), transparent) left / 12px
      100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, var(--c-shadow-scroll-edge), transparent) right /
      12px 100% no-repeat scroll;
}

.lms-table-scroll > .lms-table {
  min-width: var(--table-min-w);
}

.lms-table th {
  text-align: left;
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--c-text-muted);
  padding: 10px 14px;
  border-bottom: 1px solid var(--c-border);
  background: var(--c-bg-subtle);
  white-space: nowrap;
}

.lms-table td {
  font-size: var(--fs-13-5);
  padding: 12px 14px;
  border-bottom: 1px solid var(--c-border-soft);
  vertical-align: middle;
}

/* プロトタイプに zebra ストライプ・行 hover の指定は無い。
   行全体がクリック可能な場合のみ、対象と分かるよう hover を付ける。 */
.lms-table tr.is-clickable {
  cursor: pointer;
}

.lms-table tr.is-clickable:hover > td {
  background: var(--c-gray-50);
}

.lms-table .is-center {
  text-align: center;
}

.lms-table .is-right {
  text-align: right;
}

.lms-table .is-strong {
  font-weight: var(--fw-semibold);
}

.lms-table .is-muted {
  color: var(--c-text-muted);
}

.lms-table .is-faint {
  color: var(--c-text-faint);
}

.lms-table .is-mono {
  font-family: var(--font-mono);
}

/* 一覧セルの補足行（ユーザー ID 等）。従来 admin/submissions.html が
   style="font-size: var(--fs-11-5)" と直書きしていた指定をクラス化した
   （randomize-user-id 05_ui.md §3。CLAUDE.md「CSS の色・寸法はコンポーネント CSS に
   直書きせず tokens.css の CSS カスタムプロパティ経由」）。 */
.lms-table .is-meta {
  font-size: var(--fs-11-5);
}

/* 空白を含まない長い連続文字列（正規化後の半角 ASCII 100 文字のユーザー名・メモ等）を
   折り返すセル。自由入力の列にだけ付ける。
   word-break: break-all ではなく overflow-wrap: anywhere を使う理由:
   前者は空白を含む通常の日本語・英文でも文節を無視して割るのに対し、後者は
   「収まらない場合にのみ」任意位置で折り返すため通常データの見た目が変わらない。
   また anywhere は min-content 幅の計算にも効くのでテーブル自体が縮められる
   （fix-user-table-overflow design.md D1・GitHub issue #5）。 */
.lms-table .is-wrap {
  overflow-wrap: anywhere;
}

/* 迷子チェックポイント（contentId が content/ に存在しない行）の警告表示 */
.lms-table tr.is-orphan > td {
  background: var(--c-amber-50);
  /* 同じ「淡い橙地に橙文字」の他 3 箇所（.lms-alert--warning / .lms-md-callout--warning /
     article.css:581）はいずれも --c-amber-800。ここだけ 600 で浮いていた（部品 #2） */
  color: var(--c-amber-800);
}

/* テーブル内の展開行 */
.lms-table tr.lms-row-detail > td {
  background: var(--c-bg-subtle);
  padding: 8px 16px 16px;
}

.lms-table tr.lms-row-detail .lms-row-detail__inner {
  animation: lmsAcc var(--dur-acc);
}

/* --------------------------------------------------------------------------
   狭幅（1023px 以下）の一覧テーブル: 列幅を明示する
   （unify-admin-table-scroll-layout design.md D2・D5）

   経緯: table-layout の既定 auto は、min-width の余剰幅を各列の max-content 比で
   配分する。ユーザー一覧では自由入力 2 列（ユーザー名・メモ）がテーブル幅の 76% を
   占め、375px で 379px（53%）が画面外にあった（2026-07-29 実測）。列幅を制御するには
   table-layout: fixed が必要で、.is-wrap を強めても効かない。

   ★ 適用は狭幅（1023px 以下）に限定する。PC（1024px 以上）は従来どおり table-layout: auto
   のままで見た目を変えない（design.md D2 の Goal）。この @media の外に列幅を書かないこと。

   ★ セレクタが .lms-table-scroll > .lms-table--xxx になっている理由:
   上の .lms-table-scroll > .lms-table { min-width: var(--table-min-w) } は詳細度 (0,2,0)。
   .lms-table--users だけだと (0,1,0) で負けて min-width が 720px のままになる。
   同じ (0,2,0) に揃えたうえで後ろに書くことで、記述順で勝たせている。

   ★ 列幅は th:nth-child(n) で与える。n は <thead> の <tr> 内での位置なので、
   テンプレート側で列順を変えたらこの CSS も直すこと（各テンプレートにも同趣旨のコメントあり）。

   ★ 課題提出一覧（.lms-table--submissions）には table-layout: fixed を適用しない。
   (1) assignment-submission の spec に列幅の要件が無い（要求は共通方式・手掛かり・全列到達・
   ページ非溢れの 4 点のみ）、(2) 列が 6 本あり 560px には収まらない、(3) fixed にすると
   空白を含まない長いファイル名（上限 50 文字）が列幅を超えてセル外へ描画され、隣の列に
   重なる（td に overflow 指定が無く overflow-wrap も既定 normal のため折り返し機会が無い）。
   回避には .is-wrap の付与が必要だが、それは spec に無い要件の追加になる。
   現行の auto + var(--table-min-w)（720px）を維持し、クラス lms-table--submissions は
   「共通方式に従っている」ことをテストで機械検出するためのフックとしてのみ使う。
   -------------------------------------------------------------------------- */
@media (max-width: 1023px) {
  .lms-table-scroll > .lms-table--users,
  .lms-table-scroll > .lms-table--checkpoints {
    table-layout: fixed;
    min-width: var(--table-min-w-compact);
  }

  /* /admin/users: ユーザー名 190 + メモ 170 + 登録日 100 + 操作 100 = 560px
     ユーザー名 190px は content box 162px = 13.5px（--fs-13-5）× 日本語 12 文字。
     ユーザー名 + メモ = 360px は 560px の 64.3%（要件: 70% を超えないこと）。 */
  .lms-table--users th:nth-child(1) {
    width: 190px;
  }
  .lms-table--users th:nth-child(2) {
    width: 170px;
  }
  .lms-table--users th:nth-child(3) {
    width: 100px;
  }
  .lms-table--users th:nth-child(4) {
    width: 100px;
  }

  /* /admin/checkpoints: # 56 + チャプター/セクション 200 + contentId 140
     + 課題提出 88 + 操作 76 = 560px（users と合計を揃える） */
  .lms-table--checkpoints th:nth-child(1) {
    width: 56px;
  }
  .lms-table--checkpoints th:nth-child(2) {
    width: 200px;
  }
  .lms-table--checkpoints th:nth-child(3) {
    width: 140px;
  }
  .lms-table--checkpoints th:nth-child(4) {
    width: 88px;
  }
  .lms-table--checkpoints th:nth-child(5) {
    width: 76px;
  }
}

/* 空状態: テーブル内 */
.lms-table td.lms-empty {
  text-align: center;
  color: var(--c-text-faint);
  padding: 32px;
}

/* 空状態: カード全体 */
.lms-empty-card {
  text-align: center;
  color: var(--c-text-faint);
  padding: 48px 20px;
  font-size: var(--fs-14);
}

/* --------------------------------------------------------------------------
   エラーページ（403 / 404 / 500 / 503 / 400 共通。tasks 9.0）
   -------------------------------------------------------------------------- */
.lms-error-page {
  padding: 56px 24px;
}

.lms-error-page__code {
  font-size: var(--fs-56);
  font-weight: var(--fw-bold);
  color: var(--c-gray-200);
  line-height: 1;
  margin: 0 0 8px;
}

.lms-error-page__title {
  font-size: var(--fs-24);
  font-weight: var(--fw-bold);
  color: var(--c-text-strong);
  margin: 0 0 12px;
}

.lms-error-page__desc {
  color: var(--c-text-muted);
  margin: 0 0 24px;
}

/* --------------------------------------------------------------------------
   バッジ・ピル
   -------------------------------------------------------------------------- */
.lms-badge {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-11);
  font-weight: var(--fw-bold);
  border-radius: var(--r-pill);
  padding: 3px 10px;
  flex: none;
}

.lms-badge--blue {
  color: var(--c-blue-700);
  background: var(--c-blue-50);
}

.lms-badge--green {
  color: var(--c-green-700);
  background: var(--c-green-50);
}

.lms-badge--gray {
  /* --c-text-muted を経由していないためトークン変更では直らない（統合レポート §4.5・§6）。
     11px 通常文字なので 4.5:1 が必要 */
  color: var(--c-gray-600);
  background: var(--c-gray-100);
}

.lms-badge--red {
  color: var(--c-red-700);
  background: var(--c-red-50);
}

/* 章の解放バッジ（進捗管理・chapter-unlock CU-R5） */
.lms-unlock-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  font-size: var(--fs-11);
  font-weight: var(--fw-bold);
}
.lms-unlock-badge--auto {
  color: var(--c-badge-unlock-auto-fg);
  background: var(--c-badge-unlock-auto-bg);
}
.lms-unlock-badge--individual {
  color: var(--c-badge-unlock-individual-fg);
  background: var(--c-badge-unlock-individual-bg);
}

/* チェックポイント進捗の 3 状態（未完了 / 実施中 / 完了済み） */
.lms-status-pill {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-11);
  font-weight: var(--fw-bold);
  background: var(--c-white);
  border-radius: var(--r-pill);
  padding: 2px 9px;
  border: 1px solid var(--c-border);
  color: var(--c-text-muted);
}

.lms-status-pill--completed {
  color: var(--c-blue-700);
  border-color: var(--c-blue-200);
}

.lms-status-pill--in-progress {
  color: var(--c-green-700);
  border-color: var(--c-green-200);
}

.lms-status-pill--not-started {
  color: var(--c-gray-500);
  border-color: var(--c-border);
}

/* 面塗り版（進捗ツリーの行背景に使う） */
.lms-status-fill--completed {
  background: var(--c-blue-50);
  border: 1px solid var(--c-blue-200);
}

.lms-status-fill--in-progress {
  background: var(--c-green-50);
  border: 1px solid var(--c-green-200);
}

.lms-status-fill--not-started {
  background: var(--c-gray-50);
  border: 1px solid var(--c-border);
}

/* 「送信済み」ピル */
.lms-pill-sent {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-11);
  font-weight: var(--fw-medium);
  color: var(--c-green-700);
  background: var(--c-green-50);
  border: 1px solid var(--c-green-200);
  border-radius: var(--r-pill);
  padding: 2px 9px;
}

/* チェックポイント ID タグ（角丸小） */
.lms-cp-tag {
  display: inline-flex;
  font-size: var(--fs-11);
  font-weight: var(--fw-bold);
  color: var(--c-primary);
  background: var(--c-blue-50);
  border-radius: var(--r-4);
  padding: 2px 7px;
}

/* --------------------------------------------------------------------------
   タブ
   -------------------------------------------------------------------------- */
/* セグメント型（ユーザー一覧の 3 タブ） */
.lms-segmented {
  display: flex;
  gap: 4px;
  background: var(--c-gray-100);
  border-radius: 9px;
  padding: 3px;
}

.lms-segmented > button,
.lms-segmented > a {
  border: none;
  border-radius: var(--r-7);
  padding: 7px 16px;
  cursor: pointer;
  font-size: var(--fs-13-5);
  font-family: inherit;
  font-weight: var(--fw-normal);
  background: transparent;
  color: var(--c-text-muted);
  box-shadow: none;
}

/* 選択中はリンクの aria-current="page" で表す（role="tablist" + aria-selected は
   ARIA 不正のため 2026-07-27 に廃止。UI/UX レビュー 管理 #7 / 部品 #5） */
.lms-segmented > [aria-current="page"] {
  font-weight: var(--fw-semibold);
  background: var(--c-white);
  color: var(--c-gray-900);
  box-shadow: var(--shadow-segment);
  text-decoration: none;
}

/* 下線型（教材の Tabs） */
.lms-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--c-border);
}

.lms-tabs > button {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--c-text-muted);
  font-weight: var(--fw-medium);
  padding: 8px 14px;
  cursor: pointer;
  font-size: var(--fs-13-5);
  font-family: inherit;
  margin-bottom: -1px;
}

.lms-tabs > [aria-selected="true"] {
  border-bottom-color: var(--c-blue-600);
  color: var(--c-blue-600);
  font-weight: var(--fw-bold);
}

/* --------------------------------------------------------------------------
   トグルスイッチ
   -------------------------------------------------------------------------- */
.lms-toggle {
  width: 40px;
  height: 23px;
  border-radius: var(--r-pill);
  border: none;
  cursor: pointer;
  padding: 2px;
  background: var(--c-gray-300);
  transition: background var(--dur-acc);
  display: flex;
  flex: none;
}

.lms-toggle[aria-checked="true"] {
  background: var(--c-blue-600);
}

.lms-toggle__knob {
  width: 19px;
  height: 19px;
  border-radius: var(--r-full);
  background: var(--c-white);
  transition: transform var(--dur-acc);
  box-shadow: var(--shadow-toggle-knob);
}

.lms-toggle[aria-checked="true"] .lms-toggle__knob {
  transform: translateX(17px);
}

/* --------------------------------------------------------------------------
   アコーディオン（汎用）
   -------------------------------------------------------------------------- */
.lms-accordion {
  border: 1px solid var(--c-border);
  border-radius: var(--r-8);
  overflow: hidden;
}

.lms-accordion__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 14px;
  cursor: pointer;
  font-weight: var(--fw-semibold);
  font-size: var(--fs-14);
  width: 100%;
  background: none;
  border: none;
  font-family: inherit;
  text-align: left;
  color: inherit;
}

.lms-accordion__head:hover {
  background: var(--c-gray-50);
}

.lms-accordion__chevron {
  display: flex;
  flex: none;
  color: var(--c-gray-400);
  transition: transform var(--dur-acc);
}

[data-open] > .lms-accordion__head .lms-accordion__chevron {
  transform: rotate(90deg);
}

.lms-accordion__body {
  padding: 0 14px 12px 36px;
  font-size: var(--fs-13-5);
  color: var(--c-gray-600);
  line-height: var(--lh-relaxed);
  animation: lmsAcc var(--dur-acc);
}

.lms-accordion-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* タイトルテキスト（教材本文中の :::accordion が使う） */
.lms-accordion__title {
  flex: 1 1 auto;
}

/* --------------------------------------------------------------------------
   モーダル
   -------------------------------------------------------------------------- */
.lms-overlay {
  position: fixed;
  inset: 0;
  background: var(--c-overlay-modal);
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  animation: lmsFade var(--dur-fade);
}

.lms-overlay[hidden] {
  display: none;
}

.lms-modal {
  background: var(--c-bg-surface);
  border-radius: var(--r-14);
  width: 100%;
  max-width: 440px;
  box-shadow: var(--shadow-modal);
  animation: lmsToast var(--dur-modal);
  max-height: 88vh;
  overflow-y: auto;
}

/* プロトタイプで使われている幅のバリエーション */
.lms-modal--xs {
  max-width: 300px;
} /* ユーザーメニュー */
.lms-modal--sm {
  max-width: 400px;
} /* 確認ダイアログ・管理者追加・ステータス変更 */
.lms-modal--md {
  max-width: 420px;
} /* パスワード設定 / 変更 */

.lms-modal__inner {
  padding: 24px;
}

.lms-modal__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 18px;
}

.lms-modal__header h2,
.lms-modal__header h3 {
  margin: 0;
  font-size: var(--fs-17);
  font-weight: var(--fw-bold);
}

.lms-modal__close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--c-text-faint);
  display: flex;
  padding: 2px;
}

.lms-modal__close:hover {
  color: var(--c-gray-700);
}

.lms-modal__footer {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}

/* 確認ダイアログ */
.lms-confirm h2,
.lms-confirm h3 {
  margin: 0 0 8px;
  font-size: var(--fs-16-5);
  font-weight: var(--fw-bold);
}

.lms-confirm p {
  margin: 0 0 22px;
  font-size: var(--fs-13-5);
  color: var(--c-gray-600);
  line-height: var(--lh-relaxed);
}

/* ユーザーメニュー（プロトタイプでは中央モーダル） */
.lms-menu {
  padding: 10px 8px;
}

/* ユーザーメニューの見出しブロック（ユーザー名 + ユーザー ID）。
   randomize-user-id で 2 行構成になったため、余白・区切り線はブロック側、
   文字装飾は .lms-menu__name 側へ分けた。 */
.lms-menu__head {
  padding: 10px 14px;
  border-bottom: 1px solid var(--c-border-soft);
  margin-bottom: 6px;
}

.lms-menu__name {
  font-weight: var(--fw-semibold);
  font-size: var(--fs-15);
}

/* ユーザーメニューの所属グループ表示（auth spec.md「所属グループの表示」/ introduce-groups）。
   「{ユーザー名} さん」と id: 表示の間に置く。ID 行（等幅・11.5px）より 1 段強く、
   ユーザー名（15px・semibold）より弱い階層にする。 */
.lms-menu__group {
  margin-top: 2px;
  color: var(--c-text-muted);
  font-size: var(--fs-12-5);
}

/* 「{ユーザー名} さん」の直下に出す 0 埋め 8 桁のユーザー ID（auth spec.md）。
   桁の読み違いを防ぐため等幅フォントにする。 */
.lms-menu__id {
  margin-top: 2px;
  color: var(--c-text-muted);
  font-family: var(--font-mono);
  font-size: var(--fs-11-5);
}

.lms-menu__item {
  display: block;
  width: 100%;
  padding: 10px 14px;
  border-radius: var(--r-8);
  cursor: pointer;
  font-size: var(--fs-14);
  color: var(--c-gray-700);
  font-weight: var(--fw-normal);
  background: transparent;
  border: none;
  text-align: left;
  font-family: inherit;
}

.lms-menu__item:hover {
  background: var(--c-gray-50);
  text-decoration: none;
}

.lms-menu__item--danger {
  color: var(--c-red-600);
  font-weight: var(--fw-medium);
}

/* --------------------------------------------------------------------------
   トースト
   -------------------------------------------------------------------------- */
/* 全トースト共通の共有スタック（unify-study-toast-stacking）。
   汎用トースト（.lms-toast）と学習中確認トースト（.lms-study-toast）を到着順に縦積みする。
   ARIA ロールは持たない純粋なレイアウト要素で、読み上げは視覚非表示のアナウンサー
   （[data-lms-toast-announcer] / role="status"）が別に担当する（design.md D1）。 */
.lms-toast-host {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%); /* 上中央に固定 */
  z-index: var(--z-toast); /* 全トーストで 1 本に統一（--z-study-toast は休止） */
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center; /* 各トーストを中央そろえ。新しいものは下に積む */
  width: max-content;
  max-width: calc(100vw - 32px);
  pointer-events: none; /* 背後のページ操作を妨げない。クリックは各ピルが auto で受ける */
}

.lms-toast {
  /* モック(260724 ToastHost L495)準拠の完全な丸ピル。既存 999px トークン --r-capsule を流用 */
  border-radius: var(--r-capsule);
  padding: 11px 22px;
  font-size: var(--fs-13-5);
  font-weight: var(--fw-medium);
  box-shadow: var(--shadow-toast);
  /* 入場：移動・拡大・不透明化を別々の時間配分で進める（スライドイン維持。モックの雫バウンドは不採用）。
     - 移動   : 0.3s かけて 80px 上から等速で降りてくる。減速カーブだと前半で距離を使い切り、
                点が動いて見えないため linear にしている
     - 拡大   : 0.1s は点のまま → 残る 0.2s で等倍まで
                （拡大区間のカーブは keyframes 側で指定するため、ここは linear のまま）
     - 不透明化: 降りている 0.1s の間は 0.15 まで → 膨らみながら 0.3s で 1.0 */
  animation:
    lmsToastIn var(--dur-toast) linear,
    lmsToastInScale var(--dur-toast) linear,
    lmsToastInFade var(--dur-toast) linear;
  min-width: 160px;
  max-width: 100%;
  text-align: center;
  pointer-events: auto;
}

/* 退場：拡大＋ぼかしで弾けて消える（JS が自動消去時に is-leaving を付与） */
.lms-toast.is-leaving {
  animation: lmsToastBurst var(--dur-toast) cubic-bezier(0.34, 1.2, 0.64, 1) forwards;
}

.lms-toast--success {
  background: var(--c-green-50);
  border: 1px solid var(--c-green-200);
  color: var(--c-green-700);
}

.lms-toast--error {
  background: var(--c-red-50);
  border: 1px solid var(--c-red-200);
  color: var(--c-red-700);
}

.lms-toast--info {
  background: var(--c-blue-50);
  border: 1px solid var(--c-blue-200);
  color: var(--c-blue-700);
}

/* 学習中確認トースト（雫・上中央ピル・閉じるボタンなし）
   2026-08-03 unify-study-toast-stacking（design.md D2）で専用の位置決めラッパーを廃止し、
   ピル本体を汎用トーストと同じ共有スタック（.lms-toast-host）へ直接積む方式に変更した。
   TS（learning-log/dom.ts）は .lms-study-toast-host を生成しなくなったため、以下の位置規則は
   参照元が無い。復活させる場合は共有スタック方式の見直しとセットで判断すること。 */
/* .lms-study-toast-host {
  position: fixed;
  top: 56px;
  left: 0;
  right: 0;
  z-index: var(--z-study-toast);
  display: flex;
  justify-content: center;
  pointer-events: none;
} */

/* ピル本体。共有スタック（.lms-toast-host）の直接の子として上中央に積まれ、
   雫が落ちるように出現して退場時は弾けて消える（unify-study-toast-stacking design.md D2・D3）。 */
.lms-study-toast {
  /* スタックは pointer-events: none なので、ピル自身で受け直す。
     これを削ると「はい」ボタンが押せなくなる（learning-log spec「はい」押下）。 */
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--c-bg-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-capsule);
  padding: 9px 10px 9px 22px;
  box-shadow: var(--shadow-study-toast);
  /* スタックの max-width: calc(100vw - 32px) に収める（.lms-toast と同じ様式）。
     これにより従来のモバイル用メディアクエリが不要になった（同値のため。§2.5） */
  max-width: 100%;
  transform-origin: top center;
  will-change: transform, opacity;
  animation: lmsDrop var(--dur-study-drop) cubic-bezier(0.5, 1.4, 0.5, 1);
}

/* 退場：弾けてぼやけ消える（JS が非表示化時に is-leaving を付与し、再生後に DOM から除去する） */
.lms-study-toast.is-leaving {
  animation: lmsBurst var(--dur-study-burst) cubic-bezier(0.34, 1.2, 0.64, 1) forwards;
}

.lms-study-toast__title {
  margin: 0; /* p の既定余白を打ち消し、ピル内で縦中央にそろえる */
  font-size: var(--fs-14);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

/* ピル内の「はい」ボタンは丸みの強いカプセル形にする */
.lms-study-toast .lms-btn {
  padding: 7px 20px;
  border-radius: var(--r-capsule);
}

/* モバイル（1023px 以下）の幅制限は、2026-08-03 unify-study-toast-stacking で
   共有スタック（.lms-toast-host の max-width: calc(100vw - 32px)）＋ ピルの max-width: 100%
   に一本化したため休止した。--main-pad-x-sp は 16px なので calc(100vw - 2 * 16px) と同値であり、
   同じ上限を 2 箇所で持たない（README.md §5 決定 7）。 */
/* @media (max-width: 1023px) {
  .lms-study-toast {
    max-width: calc(100vw - 2 * var(--main-pad-x-sp));
  }
} */

/* --------------------------------------------------------------------------
   ホーム画面（checkpoint-progress 05_ui.md §3）
   実装時の訂正（2026-07-26）: add-learning-calendar（CPRG-M1）により進捗サークル
  （.lms-progress-ring__*）・ホーム 2 カラムレイアウト（.lms-home-top）・
   「ここから再開」（.lms-resume-card*）を削除した。学習カレンダーは下記「学習カレンダー」節を参照。
   -------------------------------------------------------------------------- */
.lms-home-section-title {
  font-size: var(--fs-16);
  font-weight: var(--fw-bold);
  margin: 0 0 14px;
}

.lms-chapter-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

@media (max-width: 1023px) {
  .lms-chapter-grid {
    grid-template-columns: 1fr;
  }
}

.lms-chapter-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 20px;
}

.lms-chapter-card__title {
  font-size: var(--fs-15);
  font-weight: var(--fw-semibold);
  color: var(--c-text-strong);
}

/* 未解放章のホームカード（chapter-unlock CU-R4） */
.lms-chapter-card--locked {
  color: var(--c-nav-locked);
  background: var(--c-nav-locked-bg);
  cursor: default;
}
.lms-chapter-card--locked .lms-chapter-card__title {
  color: var(--c-nav-locked);
}
.lms-chapter-card__lock {
  /* SVG のベースライン余白を消して span のボックスを SVG（16px 正方）に一致させ、
     親 .lms-chapter-card（flex + align-items: center）でタイトルと上下中央を揃える。
     きっかけ: 2026-07-31 実機レビューの横展開点検（change: unify-icon-vertical-centering / design D1・D4）。 */
  display: inline-flex;
  margin-left: auto;
  color: var(--c-nav-locked);
}

/* --------------------------------------------------------------------------
   進捗管理画面（checkpoint-progress 05_ui.md §2）
   -------------------------------------------------------------------------- */
/* 受講者行のリスト（縦積みの外枠）。
   もとは admin/progress.html のインライン style（display: flex; flex-direction: column;
   gap: 10px）だったものをクラス化した。構造をインラインで書くとメディアクエリで
   上書きできず、狭幅対応のたびに手戻りが発生する
   （fix-progress-row-mobile-overflow design.md D5）。 */
.lms-progress-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lms-progress-row {
  display: flex;
  align-items: center;
  /* 狭幅で 2 段組みにするための折り返し許可。同一ファイルの .lms-cp-row と同じパターン。
     gap は「行間 4px / 列間 10px」で、列間は従来値 10px を据え置くため
     折り返しが起きない PC の見た目は変わらない
     （fix-progress-row-mobile-overflow design.md D1）。 */
  flex-wrap: wrap;
  gap: 4px 10px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--c-border);
  border-radius: var(--r-8);
  background: var(--c-white);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--fs-13-5);
  text-align: left;
}

.lms-progress-row:hover {
  background: var(--c-gray-50);
}

.lms-progress-row__name {
  font-weight: var(--fw-semibold);
  /* フレックスアイテム既定の min-width: auto（= min-content 幅）を解除する。
     日本語は文字単位で改行できるため min-content が 1 文字幅（実測 18px）まで下がり、
     氏名が「研 / 修 / 太 / 郎」と縦積みになっていた。
     overflow-wrap は break-word ではなく anywhere を使う。anywhere だけが
     min-content 幅の計算に算入され、100 文字の連続文字列でも行そのものを縮められる
     （fix-progress-row-mobile-overflow design.md D2 / .lms-table .is-wrap と同じ根拠）。
     ユーザー ID（.lms-progress-row__id）は 0 埋め 8 桁の固定長なので、これらの指定は不要。
     flex-grow はここに置かない。基底に置くと自由空間の分配が
     .lms-progress-row__count の margin-left: auto より先に行われ、PC でユーザー ID の
     位置が変わる（詳細は本ファイル §6.2。狭幅用の flex は §3.5 のメディアクエリ内）。 */
  min-width: 0;
  overflow-wrap: anywhere;
}

/* 一覧行のユーザー ID（0 埋め 8 桁）。randomize-user-id でメールアドレス表示を
   置き換えたのに伴い __email から改名した（tasks 4.7）。桁の読み違いを防ぐため等幅。 */
.lms-progress-row__id {
  color: var(--c-text-muted);
  font-family: var(--font-mono);
}

.lms-progress-row__count {
  margin-left: auto;
  font-family: var(--font-mono);
}

.lms-progress-row__current {
  min-width: 120px;
  text-align: right;
}

/* 実施中セクションが無いとき（「—」表示）だけ淡色にする。
   仕様は checkpoint-progress/detailed-design/05_ui.md §2.2 の「空のとき」列にだけ
   --c-text-faint を指定しており、値があるときは既定色（管理 #6 は実装の読み違い） */
.lms-progress-row__current.is-empty {
  color: var(--c-text-faint);
}

/* 受講者行の狭幅レイアウト（1023px 以下）。
   狭幅では行の固定分（シェブロン + gap + 進捗件数 + 現在のセクション 120px +
   padding/border）が幅の大半を占め、氏名に残る幅がほとんど無い。flex-wrap 未指定
   （= nowrap）のままだと収まらない分が行を横に押し広げ、ページ全体が横に溢れる。
   ページが横に溢れるとモバイルではレイアウトビューポートが拡張され、position: fixed の
   ヘッダーが拡張後の幅で描画されてバーガーメニュー・アバターが画面外に出る
   （2026-07-29 実測: 375px で scrollWidth 579px・バーガー left 538px）
   （fix-progress-row-mobile-overflow design.md D1〜D3 / app-shell
   「ヘッダー操作部品の可視領域内保持」）。

   1 行目 = シェブロン + 氏名 + 進捗件数 / 2 行目 = ユーザー ID + 現在のセクション（右寄せ）。
   改行位置は ::before の強制改行で確定させる（自然折り返しに任せると視口幅とデータ長で
   行ごとに改行位置がばらつき、一覧の拾い読みを妨げるため。design.md D1）。
   order で並び順だけを変え、DOM は変更しない（Thymeleaf・htmx 部分更新に影響させないため）。
   項目は 1 つも隠さない（display: none / text-overflow: ellipsis を使わない）。同姓同名の
   受講者を識別する唯一の手掛かりがユーザー ID であるため（design.md D1 の却下案 B・C）。

   PC（1024px 以上）の見た目は変えない。この @media の外側に flex-grow を出さないこと。 */
@media (max-width: 1023px) {
  .lms-progress-row__name {
    flex: 1 1 auto;
  }

  .lms-progress-row__count {
    order: 2;
  }

  /* 強制改行。flex-basis: 100% で 1 行を占有し、後続アイテムを次の行へ落とす。
     高さ 0 なので視覚的な行にはならない（row-gap 4px が 1 本ぶん余分に入るだけ）。
     order は __id と同じ 3 にする。同値グループ内は文書順で解決され、擬似要素 ::before は
     要素の先頭の子になるため __id より前に来る。__count（order 2）との相対順を保つため、
     この値をずらさないこと（design.md D1 / 詳細設計 README 決定 N-2）。 */
  .lms-progress-row::before {
    content: "";
    flex-basis: 100%;
    height: 0;
    order: 3;
  }

  /* 2 行目の先頭。8 桁 0 埋めの固定長（≈ 65px）なので min-width / overflow-wrap は不要
     （design.md D2 は対象を氏名のみに限定している）。 */
  .lms-progress-row__id {
    order: 3;
  }

  /* PC の右寄せ幅 min-width: 120px を狭幅でだけ解除する（design.md D3）。
     margin-left: auto で 2 行目の右端に寄せる。 */
  .lms-progress-row__current {
    order: 4;
    min-width: 0;
    margin-left: auto;
  }
}

.lms-progress-panel {
  background: var(--c-bg-subtle);
  border: 1px solid var(--c-border-soft);
  border-top: none;
  border-radius: 0 0 var(--r-8) var(--r-8);
  padding: 12px var(--main-pad-x-sp, 16px);
  animation: lmsAcc var(--dur-acc);
}

.lms-tree-chapter {
  font-size: var(--fs-14);
  font-weight: var(--fw-semibold);
  color: var(--c-text-strong);
  margin: 10px 0 6px;
}

/* 章見出し + 解放バッジ/操作ボタンの横並び（chapter-unlock CU-R5） */
.lms-tree-chapter-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.lms-tree-chapter-head .lms-tree-chapter {
  margin: 0;
}

.lms-tree-sub {
  font-size: var(--fs-13-5);
  font-weight: var(--fw-medium);
  color: var(--c-text-body);
  margin: 8px 0 6px 14px;
}

.lms-tree-section {
  font-size: var(--fs-13);
  color: var(--c-text-muted);
  padding: 6px 0 6px 14px;
}

.lms-cp-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  padding: 10px 12px;
  border-radius: var(--r-8);
  margin: 6px 0 6px 14px;
  scroll-margin-top: var(--scroll-offset);
}

.lms-cp-row__title {
  font-size: var(--fs-13-5);
  font-weight: var(--fw-medium);
  flex: 1 1 auto;
}

.lms-cp-row__meta {
  flex-basis: 100%;
  font-size: var(--fs-11-5);
  color: var(--c-text-muted);
}

.lms-cp-modal__subject {
  font-size: var(--fs-13-5);
  color: var(--c-text-muted);
  margin: 0 0 14px;
}

/* --------------------------------------------------------------------------
   注意バナー（迷子チェックポイントの警告）
   -------------------------------------------------------------------------- */
.lms-alert {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid transparent;
  border-radius: var(--r-8);
  font-size: var(--fs-13);
  margin-bottom: 16px;
}

.lms-alert--warning {
  background: var(--c-amber-50);
  border-color: var(--c-amber-200);
  color: var(--c-amber-800);
}

.lms-alert__link {
  margin-left: auto;
  white-space: nowrap;
  font-weight: var(--fw-medium);
  color: inherit;
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   絞り込みフォーム（課題提出一覧 / 05_ui.md §3.4）
   -------------------------------------------------------------------------- */
.lms-filter-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}

/* .lms-field の margin-bottom: 16px は縦積みフォーム（ログイン・パスワード変更等）の
   フィールド間隔用の汎用スタイル。横並びの絞り込みフォームでは不要なうえ、
   align-items: flex-end がマージンボックスの下端で揃えるため select だけが 16px
   浮いて見える。フォームスコープで打ち消す（汎用 .lms-field 自体は変更しない。
   fix-filter-form-alignment design.md D1）。 */
.lms-filter-form .lms-field {
  margin-bottom: 0;
}

/* select（padding 9px / --fs-14）とボタン（.lms-btn--sm: padding 6px / --fs-12-5）は
   自然高さが異なるため、下端を揃えても上下中心がずれる。両方に同じ高さを与えて中心を
   一致させる（fix-filter-form-alignment design.md D2）。.lms-btn は display: inline-flex +
   align-items: center 済みなので、高さを増やしてもラベルは枠内で中央に保たれる。 */
.lms-filter-form .lms-select,
.lms-filter-form .lms-btn {
  height: var(--filter-control-h);
}

/* --------------------------------------------------------------------------
   課題提出（fragments/submission.html / 05_ui.md §5）
   -------------------------------------------------------------------------- */
.lms-submission {
  padding: var(--main-pad-y) var(--main-pad-x);
  border-radius: var(--r-12);
  background: var(--c-bg-surface);
  border: 1px solid var(--c-border);
}

.lms-submission__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.lms-submission__title {
  font-size: var(--fs-17);
  font-weight: var(--fw-semibold);
  color: var(--c-text-strong);
  margin: 0;
}

.lms-submission__note {
  font-size: var(--fs-13);
  color: var(--c-text-muted);
  line-height: var(--lh-relaxed);
  margin: 0 0 12px;
}

.lms-submission__latest {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  background: var(--c-bg-subtle);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--r-8);
  padding: 12px 14px;
  margin-bottom: 12px;
}

.lms-submission__file {
  font-size: var(--fs-14);
  font-weight: var(--fw-medium);
  color: var(--c-text-strong);
}

.lms-submission__meta {
  font-size: var(--fs-12-5);
  color: var(--c-text-muted);
}

.lms-submission__download {
  color: var(--c-primary);
  font-size: var(--fs-12-5);
  margin-left: auto;
}

.lms-submission__form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* ファイル選択ボタン。中の input は .lms-visually-hidden で隠すため、
   フォーカスリングは親のラベルに出す（UI/UX レビュー 2026-07-27 受講者 #1）。 */
.lms-submission__picker {
  position: relative;
}

.lms-submission__picker:focus-within {
  outline: 2px solid var(--c-blue-600);
  outline-offset: 2px;
}

.lms-submission__filename {
  font-size: var(--fs-13-5);
  color: var(--c-text-body);
}

.lms-submission__filename.is-empty {
  color: var(--c-text-faint);
}

.lms-submission__submit {
  margin-left: auto;
}

@media (max-width: 1023px) {
  .lms-submission {
    padding: var(--main-pad-y-sp) var(--main-pad-x-sp);
  }

  .lms-submission__submit {
    width: 100%;
    margin-left: 0;
  }
}

/* --------------------------------------------------------------------------
   提出履歴フラグメント（admin/fragments/submission-history.html / 05_ui.md §5）
   -------------------------------------------------------------------------- */
.lms-history__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--c-border-soft);
}

.lms-history__row:last-child {
  border-bottom: none;
}

.lms-history__file {
  font-size: var(--fs-13-5);
  color: var(--c-text-strong);
}

.lms-history__meta {
  font-size: var(--fs-12-5);
  color: var(--c-text-muted);
}

.lms-history__download {
  color: var(--c-primary);
  font-size: var(--fs-12-5);
  margin-left: auto;
}

.lms-history__empty {
  font-size: var(--fs-13);
  color: var(--c-text-muted);
}

/* --------------------------------------------------------------------------
   ご意見箱アコーディオン（fragments/feedback-box.html / curriculum-feedback 05_ui.md §2.7）
   -------------------------------------------------------------------------- */
.lms-fb {
  border: 1px solid var(--c-border);
  border-radius: var(--r-12);
  background: var(--c-bg-surface);
  margin: var(--main-pad-y) 0;
}

.lms-fb__head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 14px 16px;
  font-size: var(--fs-14);
  font-weight: var(--fw-semibold);
  color: var(--c-text-strong);
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
}

.lms-fb__head:hover {
  background: var(--c-gray-50);
}

.lms-fb__title {
  flex: 1;
}

.lms-fb__chevron {
  display: inline-flex;
  color: var(--c-text-faint);
  transition: transform var(--dur-acc);
}

.lms-fb[data-open] .lms-fb__chevron {
  transform: rotate(90deg);
}

.lms-fb__body {
  padding: 16px;
  border-top: 1px solid var(--c-border-soft);
}

.lms-fb__desc {
  font-size: var(--fs-13);
  color: var(--c-text-muted);
  margin: 0 0 12px;
}

.lms-fb__actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}

/* --------------------------------------------------------------------------
   管理者フィードバック一覧（templates/admin/feedback.html / curriculum-feedback 05_ui.md §3.7）
   -------------------------------------------------------------------------- */
.lms-fb-admin__row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 16px;
  font-size: var(--fs-13-5);
  border-bottom: 1px solid var(--c-border-soft);
  background: none;
  border-left: none;
  border-right: none;
  border-top: none;
  text-align: left;
  cursor: pointer;
}

.lms-fb-admin__row:hover {
  background: var(--c-gray-50);
}

.lms-fb-admin__row--chapter {
  font-weight: var(--fw-semibold);
  color: var(--c-text-strong);
  padding-left: 12px;
}

.lms-fb-admin__row--sub {
  padding-left: 28px;
}

.lms-fb-admin__row--section {
  padding-left: 44px;
}

.lms-fb-admin__row--empty {
  color: var(--c-text-muted);
  cursor: default;
}

.lms-fb-admin__chevron {
  display: inline-flex;
  color: var(--c-text-faint);
  transition: transform var(--dur-acc);
}

[data-lms-accordion][data-open] > .lms-fb-admin__row .lms-fb-admin__chevron,
[data-lms-accordion][data-open] > .lms-fb-admin__row--section .lms-fb-admin__chevron {
  transform: rotate(90deg);
}

.lms-fb-admin__count {
  margin-left: auto;
  color: var(--c-blue-600);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
}

.lms-fb-admin__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 16px 10px 60px;
  font-size: var(--fs-13-5);
  background: var(--c-bg-subtle);
  border: none;
  border-bottom: 1px solid var(--c-border-soft);
  text-align: left;
  cursor: pointer;
}

.lms-fb-admin__item-title {
  flex: 1;
  color: var(--c-text-body);
}

.lms-fb-admin__date {
  font-size: var(--fs-11-5);
  color: var(--c-text-faint);
}

.lms-fb-admin__content {
  white-space: pre-wrap;
  font-size: var(--fs-13-5);
  color: var(--c-text-body);
  line-height: var(--lh-relaxed);
  background: var(--c-white);
  padding: 12px 16px 16px 60px;
}

@media (max-width: 1023px) {
  .lms-fb-admin__row--sub {
    padding-left: 20px;
  }

  .lms-fb-admin__row--section {
    padding-left: 28px;
  }

  .lms-fb-admin__item {
    padding-left: 36px;
  }

  .lms-fb-admin__content {
    padding-left: 36px;
  }
}

/* --------------------------------------------------------------------------
   ユーザー発行結果カード（user-admin 05_ui.md §5）
   -------------------------------------------------------------------------- */
.lms-issued {
  background: var(--c-blue-50);
  border: 1px solid var(--c-blue-200);
  border-radius: var(--r-12);
  padding: 20px;
  /* 発行完了カードはフォームの「上」に置く（管理 #2）。カードとフォームの間隔なので margin-bottom */
  margin-bottom: 16px;
}

.lms-issued__label {
  display: block;
  font-size: var(--fs-12);
  color: var(--c-text-muted);
}

/* 汎用の小さな薄色フィールド見出し（add-instructor-and-root-roles）。.lms-issued__label と
   見た目は同一だが、発行結果カード専用クラスとの文字列衝突を避けるために分離した
   （新規ユーザー発行画面のロール選択見出し「権限」に使う）。 */
.lms-field__label {
  display: block;
  font-size: var(--fs-12);
  color: var(--c-text-muted);
}

.lms-issued__value {
  font-family: var(--font-mono);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-15);
  color: var(--c-text-strong);
  letter-spacing: 1px;
  margin-bottom: 12px;
}

/* セットアップ URL は 60 文字を超えるため、等幅の字間指定を打ち消し、任意位置で折り返す。
   打ち消さないとカード幅（--page-narrow-max-w）を超えて横溢れする
   （introduce-password-setup-url 05_ui.md §5.2） */
.lms-issued__value--url {
  letter-spacing: normal;
  font-size: var(--fs-13);
  overflow-wrap: anywhere;
}

.lms-issued__note {
  font-size: var(--fs-12);
  color: var(--c-amber-700);
  margin: 12px 0 0;
}

/* --------------------------------------------------------------------------
   学習カレンダー（learning-calendar 05_ui.md §5 / 260724 モック StudyCalendar）
   2026-07-29 のユーザーレビュー（change: match-mock-calendar-metrics）で
   (1) カード幅をモック準拠の固定幅にする (2) 表示範囲切替タブを休止する
   (3) 記録なし（level 0）のマスを透明にする、の 3 点を反映した。
   休止したブロックは削除せず CSS コメントで囲んである（復活時はコメントを外す）。
   -------------------------------------------------------------------------- */
.lms-cal {
  background: var(--c-cal-card-bg);
  border: 1px solid var(--c-border);
  border-radius: var(--r-14);
  padding: 20px;
  margin-bottom: 28px;
  /* モック準拠の固定幅（match-mock-calendar-metrics MCM-R1 / design.md D1）。
     max-width: 100% との併用で、親幅が 569px 未満のときは親幅に収まる
     （モックの width:auto + maxWidth:100% と同じ見え方になる）。 */
  width: var(--cal-card-w);
  max-width: 100%;
}

.lms-cal__stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* PC 3 列 */
  gap: 10px;
  margin-bottom: 18px;
}
@media (max-width: 1023px) {
  .lms-cal__stats {
    grid-template-columns: repeat(2, 1fr); /* SP 2 列 */
  }
}

.lms-cal__stat {
  background: var(--c-cal-stat-bg);
  border-radius: var(--r-10);
  padding: 12px 14px;
}
.lms-cal__stat-label {
  font-size: var(--fs-12);
  color: var(--c-text-muted);
  margin-bottom: 6px;
}
.lms-cal__stat-value {
  font-size: var(--fs-18);
  font-weight: var(--fw-bold);
  color: var(--c-gray-900);
}

.lms-cal__badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  font-size: var(--fs-11);
  font-weight: var(--fw-semibold);
  background: var(--c-green-50);
  color: var(--c-green-700);
}

/* 表示範囲タブの外枠。切替タブ休止中（match-mock-calendar-metrics）はグリッドの単なる
   包み要素だが、復活時に中の .lms-cal__radio が .lms-visually-hidden で position: absolute
   になるため、包含ブロックとして position: relative を残す
   （UI/UX レビュー 2026-07-27 受講者 #2）。 */
.lms-cal__range {
  position: relative;
}

/* 休止（match-mock-calendar-metrics 2026-07-29 のユーザーレビュー）: 表示範囲切替の
   セグメントピル。テンプレート側のラジオ 3 本 + .lms-cal__seg も Thymeleaf パーサー
   コメントで休止している。復活時はここのコメントを外し、learning-log 仕様
   「学習記録セクションの表示範囲切替のキーボード操作」要件もあわせて復活させること。
.lms-cal__seg {
  display: inline-flex;
  gap: 2px;
  background: var(--c-cal-seg-bg);
  border-radius: var(--r-10);
  padding: 3px;
  margin-bottom: 16px;
}
.lms-cal__seg-pill {
  border: none;
  border-radius: var(--r-8);
  padding: 6px 14px;
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  color: var(--c-text-muted);
  background: transparent;
  cursor: pointer;
}
*/

/* マス（共通）。記録なし（level 0）は塗りなし = 透明
   （match-mock-calendar-metrics MCM-R3。従来のグレー #edeff2 から変更）。
   これにより記録なしマスと is-hidden マス（未来・作成日前）は視覚上区別できなくなるが、
   ホバーの日付表示（data-lms-cal-date 属性。fix-calendar-tooltip-delay）は記録なしマスにのみ
   付くので機能上は区別できる。 */
.lms-cal__cell {
  border-radius: var(--r-3);
  aspect-ratio: 1 / 1;
  background: transparent;
}
.lms-cal__cell--l0 {
  background: transparent;
}
.lms-cal__cell--l1 {
  background: var(--c-cal-l1);
}
.lms-cal__cell--l2 {
  background: var(--c-cal-l2);
}
.lms-cal__cell--l3 {
  background: var(--c-cal-l3);
}
.lms-cal__cell--l4 {
  background: var(--c-cal-l4);
}
/* 未来・作成日前は塗り・枠なし（位置は占有） */
.lms-cal__cell.is-hidden {
  background: transparent;
}
/* 選択日（緑枠）。塗り色は level のまま */
.lms-cal__cell.is-selected {
  outline: 2px solid var(--c-cal-selected);
  outline-offset: -1px;
}

/* --------------------------------------------------------------------------
   マスのホバー日付ツールチップ（fix-calendar-tooltip-delay D2〜D4）

   HTML の title 属性によるネイティブツールチップは表示までに約 1 秒の固定遅延があり、
   CSS からも JS からも制御できない。日付を data-lms-cal-date に持たせ、:hover のときだけ
   ::after を生成して即座に描画する。生成と同時に表示されるため遅延ゼロが構造的に保証される。
   transition / animation は付けないこと（付けると遅延が復活する）。
   -------------------------------------------------------------------------- */

/* 日付を持つマスだけを絶対配置の基準にする（不可視マスは基準を持つ必要がない） */
.lms-cal__cell[data-lms-cal-date] {
  position: relative;
}

/* グリッドアイテムは DOM 順で重なるため、右隣以降のマスの下にツールチップが潜る。
   ホバー中のマスだけ前面に出す。 */
.lms-cal__cell[data-lms-cal-date]:hover {
  z-index: var(--z-cal-tip);
}

/* 既定はマス中央の上（GitHub の contribution graph に倣った、利用者が予期する位置） */
.lms-cal__cell[data-lms-cal-date]:hover::after {
  content: attr(data-lms-cal-date);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  padding: 4px 8px;
  border-radius: var(--r-6);
  background: var(--c-cal-tip-bg);
  color: var(--c-cal-tip-fg);
  font-size: var(--fs-11-5);
  line-height: var(--lh-snug);
  white-space: nowrap;
  box-shadow: var(--shadow-card-hover);
  /* 疑似要素が隣のマスに重なった状態でホバー移動するとちらつくため、ポインタイベントを通す */
  pointer-events: none;
}

/* 左右端の列だけ配置を補正する（design.md D3）。
   日付ラベルは「2026年07月18日」の固定長で --fs-11-5 なら約 130px あり、マス幅
   （現状 約 31px / match-mock-calendar-metrics 適用後 約 16.5px）よりはるかに広い。
   中央揃えのままだと端の列でカレンダーカードの外へはみ出す。

   nth-child の数値の根拠（列 × 行。マスは column-major = 列ごとに月曜→日曜の順に並ぶ）:
     .lms-cal__grid--all  26 列 × 7 行 = 182 マス → 左端の列 = 1〜7 / 右端の列 = 176〜182
     .lms-cal__grid--d30   5 列 × 7 行 =  35 マス → 左端の列 = 1〜7 / 右端の列 =  29〜35
     .lms-cal__grid--d7    7 列 × 1 行 =   7 マス → 左端 = :first-child / 右端 = :last-child
   列数・行数を変更する change を入れるときは、必ずこの数値も同時に見直すこと。 */
.lms-cal__grid--all .lms-cal__cell[data-lms-cal-date]:nth-child(-n + 7):hover::after,
.lms-cal__grid--d30 .lms-cal__cell[data-lms-cal-date]:nth-child(-n + 7):hover::after,
.lms-cal__grid--d7 .lms-cal__cell[data-lms-cal-date]:first-child:hover::after {
  left: 0;
  transform: none;
}
.lms-cal__grid--all .lms-cal__cell[data-lms-cal-date]:nth-child(n + 176):hover::after,
.lms-cal__grid--d30 .lms-cal__cell[data-lms-cal-date]:nth-child(n + 29):hover::after,
.lms-cal__grid--d7 .lms-cal__cell[data-lms-cal-date]:last-child:hover::after {
  left: auto;
  right: 0;
  transform: none;
}

/* 凡例 */
.lms-cal__legend {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
  margin-top: 12px;
  font-size: var(--fs-11-5);
  color: var(--c-text-faint);
}
.lms-cal__legend-swatch {
  width: 11px;
  height: 11px;
  border-radius: var(--r-2);
}
/* 凡例の「少ない」側（level 0）スウォッチだけは、透明のままでは見えないので枠線で表す
   （match-mock-calendar-metrics MCM-R3）。塗りは透明のまま。
   base.css の * { box-sizing: border-box } により、枠線を足しても外形は 11px 角のまま
   変わらず、他の 4 枚と高さ・間隔が揃う。 */
.lms-cal__legend-swatch.lms-cal__cell--l0 {
  border: 1px solid var(--c-border-input);
}

/* グリッド。表示範囲切替が休止中のため「すべて」を常時表示する
   （match-mock-calendar-metrics MCM-R2 / design.md D2）。 */
.lms-cal__grid {
  display: none;
  grid-auto-flow: column;
  grid-template-rows: repeat(7, 1fr);
  gap: 4px;
}

/* 休止（match-mock-calendar-metrics）: ラジオの :checked による範囲切替。
   復活時はこのコメントを外し、下の .lms-cal__grid--all の display: grid の 1 行を削除する。
.lms-cal__radio[value="all"]:checked ~ .lms-cal__grid--all {
  display: grid;
}
.lms-cal__radio[value="d30"]:checked ~ .lms-cal__grid--d30 {
  display: grid;
}
.lms-cal__radio[value="d7"]:checked ~ .lms-cal__grid--d7 {
  display: grid;
}
*/

.lms-cal__grid--all {
  /* 切替タブ休止中の常時表示（match-mock-calendar-metrics MCM-R2）。復活時はこの 1 行を削除する。
     .lms-cal__grid の display: none と詳細度が同じ (0,1,0) なので、後に書いたこちらが勝つ。
     → この規則は必ず .lms-cal__grid の規則より後ろに置くこと。 */
  display: grid;
  grid-template-columns: repeat(26, 1fr);
}
/* --d30 / --d7 のグリッド定義は、対応する要素がテンプレート側で休止中のため配信 HTML に
   マッチする要素が無く無害。復活時にそのまま使えるよう残す（match-mock-calendar-metrics）。
   「7日」は直近 7 日を横 1 行（7 列 × 1 行。左が古い→右が today）で描く。 */
.lms-cal__grid--d30 {
  grid-template-columns: repeat(5, 1fr);
}
.lms-cal__grid--d7 {
  grid-auto-flow: column;
  grid-template-rows: 1fr;
  grid-template-columns: repeat(7, 1fr);
  max-width: 220px;
}

/* 休止（match-mock-calendar-metrics）: セグメントピルのアクティブ強調（白ピル + 影）と、
   キーボードフォーカス時に選択中のピルへ出すフォーカスリング（:focus-visible）。
   復活時は learning-log 仕様「学習記録セクションの表示範囲切替のキーボード操作」要件と
   セットで戻すこと（UI/UX レビュー 2026-07-27 受講者 #2 で追加したもの）。
.lms-cal__radio[value="all"]:checked ~ .lms-cal__seg [for$="-all"],
.lms-cal__radio[value="d30"]:checked ~ .lms-cal__seg [for$="-d30"],
.lms-cal__radio[value="d7"]:checked ~ .lms-cal__seg [for$="-d7"] {
  background: var(--c-white);
  color: var(--c-gray-900);
  font-weight: var(--fw-semibold);
  box-shadow: var(--shadow-segment);
}
.lms-cal__radio[value="all"]:focus-visible ~ .lms-cal__seg [for$="-all"],
.lms-cal__radio[value="d30"]:focus-visible ~ .lms-cal__seg [for$="-d30"],
.lms-cal__radio[value="d7"]:focus-visible ~ .lms-cal__seg [for$="-d7"] {
  outline: 2px solid var(--c-blue-600);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   グループ別カリキュラム設定（group-curriculum-access / 05_ui.md §5）
   -------------------------------------------------------------------------- */

/* 章チェックボックスの縦並び。汎用 .lms-check-row の下マージン（18px）は
   フォーム項目間の間隔として設計されており、同種項目の連続には広すぎるため
   このスコープ内でのみ打ち消し、行間は gap で与える
   （.lms-filter-form が .lms-field の下マージンを打ち消すのと同じ手法）。 */
.lms-chapter-access-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.lms-chapter-access-list .lms-check-row {
  margin-bottom: 0;
  padding: 6px 0;
}

/* カード内フォームの操作行（右寄せ）。モーダル外で使うため .lms-modal__footer は使えない。 */
.lms-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--c-border-soft);
}
*/
