/* =====================================================================
   クルカナ 共用スタイル（mockups/assets/app.css のデザイントークンを実装へ移植）
   ---------------------------------------------------------------------
   ・方針：ビューは素のセマンティックHTML（h1/section/ul/form等）のため、
     要素セレクタへの基本スタイルで全画面を一括で整え、細部はモック由来の
     クラス（.btn / .badge / .card 等）でオプトインする2層構成とする。
   ・スマホファースト。中央に最大幅560pxのカラムを置く（8. UX設計方針）。
   ・色・角丸・余白は :root のトークンを差し替えるだけで全画面に反映される。
   ---------------------------------------------------------------------
   【このファイルは2つのブロックでできている。新しい規則を書く前に読むこと】

   前半＝素マークアップ向けの基本スタイル、後半（「モック同期コンポーネント」の見出し以降）＝
   `mockups/assets/app.css` を丸ごと写したブロックで、**後勝ちさせるために末尾に置いてある**。
   そのため同じセレクタが2回定義されている箇所が31ある（`.app` `.appbar` `.btn-*` `.badge-*`
   `.note` 等）。これは事故ではなく意図した構成。

   ★ **新しい規則は原則としてモック同期ブロック（後半）へ、`mockups/assets/app.css` と
     同じ相対位置に書く。** 前半へ足すと、**宣言していないプロパティだけが後半から漏れてくる**。
     詳細度で勝っていても防げない（合成クラスを前半に置き、`box-shadow` を書かなかったために
     平らなはずのボタンが「浮いた白いボタン」に見えた実例がある。2026-08-10・部品別レビュー2周目）。

   ★ **前半の重複定義を「死んでいるから」と消さないこと。** 2026-08-10に全31セレクタを機械的に
     調べたところ、**7セレクタは前半だけがプロパティを宣言していた**（`.app`の`box-shadow`、
     `.appbar`の`min-height`、`.meter`の`max-width`、`.btn-lg`の`min-height`、
     `.choice .t`の`font-size`/`font-weight`等）。一括削除は見た目を変える。
     残り24は完全に上書きされているが、選り分けの手間に見合う利益が無いため触っていない。
   ===================================================================== */

/* ---------- Webフォント ----------
   【ステップ20d・docs/95 §2-1】@font-faceの宣言は`public/css/fonts.css`へ移した（自動生成）。
   分割前はNoto Sans JPを1ファイル（各988.7KB）で配信しており、LPの初期表示2,310KBのうち
   1,997KB（86%）がフォントだった。`unicode-range`で4層（core/常用/人名用/その他）へ分け、
   **公開ページはcoreの431.4KBだけ**を取りに行くようにした（78%削減）。
   4層の和集合は元フォントの収録範囲と完全に一致するので**見え方は変わらない**。
   ここに@font-faceを書き足さないこと——生成物と手書きに分かれると、フォントを触る人が
   どちらを直すか迷う。変えるなら`scripts/build-font-subsets.py`を直して再生成する。 */

/* ---------- デザイントークン（mockups準拠） ---------- */
:root {

  /* ブランド（青系） */
  --brand-700: #164fb0;
  --brand-600: #1f63d6;
  --brand-500: #3d7bec;
  --brand-100: #d7e4fb;
  --brand-50:  #eef4fe;

  /* 文字・面 */
  --ink:    #182233;
  --ink-2:  #445064;
  /* 補助テキスト（説明文・キャプション・フォーム補足等）に多用する色。白・surface-2 背景で
     コントラスト比 4.5:1 以上（WCAG AA・本文）を満たすよう #78849b から一段暗くした。 */
  --muted:  #646f86;
  --line:   #e6eaf1;
  /* 【GM-1・第93回ウォークスルー】**操作できるUI部品の境界**に使う枠線色。`--line`（#e6eaf1）は
     白背景に対して 1.21:1 しかなく、WCAG 1.4.11「非テキストのコントラスト 3:1」を大きく下回る。
     入力欄・セレクト・選択カード・チェック行・トグルは「意味を伝えるUI部品」でこの基準の対象
     （カード・リストの区切り線のような純粋な装飾は対象外のため`--line`のまま残す）。
     #828b9c は白で 3.43:1・--surface-2 で 3.25:1 と、両方の背景で基準を満たす。 */
  --control-border: #828b9c;
  --line-2: #f0f3f8;
  --bg:     #eef1f6;
  --surface:#ffffff;
  --surface-2:#f7f9fc;

  /* 状態色（出欠のセマンティクス）。文字色は淡色背景バッジ（12px太字）で AA 本文 4.5:1 を
     満たすよう一段暗くした（present/absent/warn とも旧値ではバッジで 3:1 前後だった）。
     --warn は警告・注意・キャンセル待ち等の琥珀。旧「出る希望(hope)」は廃止し警告色へ転用。 */
  --present:#0f7c54;
  --present-bg:#e4f5ee;
  --absent: #b6452c;
  --absent-bg:#fbe9e4;
  /* 破壊操作のボタンの枠線。旧値は白カード上で1.51:1しかなく、**枠線が「押せるもの」の
     輪郭として機能していなかった**（WCAG 1.4.11の非テキスト3:1未達）。JC-9（第201回）が
     `.btn-outline`を`--control-border`へ揃えたとき、すぐ下の`.btn-danger`が同じ理由で
     取り残されていた兄弟である。`--absent`と同じ色相（10.9度）・同じ彩度のまま明度だけ上げて
     3.28:1へ到達させた値（スクショレビューSR1F-2） */
  --danger-border: #d7715b;
  --warn:   #9b5f0c;
  --warn-bg:#fbf1de;
  --info:   var(--brand-600);
  --info-bg:var(--brand-50);

  /* 文字サイズ（タイプスケール）
     ------------------------------------------------------------------
     【第134回デザインレビュー §1-A】以前は17種類・101宣言（`12.5` `13.5` `15.5` `17` `26` など
     0.5px刻みや1px差が根拠なく混在）に散らばっていた。同じ役割が違うサイズで書かれ、
     新しい画面を足すたびに種類が増える状態だったため、**9段**へ集約する。
     ここ以外に px を直接書かない（インラインで書くときも下記のいずれかの値にそろえる）。

     ロゴのロックアップだけは例外で 9.5px / 11px を使う。読ませる本文ではなくブランド識別の
     一部であり、補助テキストの下限（12px）の対象外と整理した（GM-7・2026-08-05決着）。 */
  --fs-xs:   12px;  /* 補助テキスト・キャプション・バッジ（§1-Aの下限） */
  --fs-sm:   13px;  /* 小さめの本文・フォームのラベル・表 */
  --fs-md:   14px;  /* ボタン・やや小さめの本文 */
  --fs-base: 16px;  /* 本文・入力欄（16px未満はiOS Safariがフォーカス時に自動ズームする） */
  --fs-lg:   18px;  /* 小見出し・ワードマーク・ダイアログの見出し */
  --fs-xl:   20px;  /* 画面見出し（h1） */
  --fs-2xl:  24px;  /* 数値の強調（金額・人数）・LPのセクション見出し */
  --fs-3xl:  30px;  /* LPのヒーロー見出し */
  --fs-4xl:  40px;  /* LPのロゴ（ワードマーク） */

  /* アイコンサイズ（アイコンスケール）
     ------------------------------------------------------------------
     【第135回デザインレビュー §1-E】実測で 15 / 16 / 18 / 20 / 22 / 24 / 26 / 27 / 28 の
     9段に散らばっていた（27 と 26、15 と 16、20 と 22 のように1〜2pxしか違わない値が並存し、
     同じ役割のアイコンが画面ごとに違う大きさで出ていた）。**5段**へ集約する。
     ここ以外に px を直接書かない（Blade の width/height 属性も下記のいずれかにそろえる）。

     【第9周デザインレビュー・2026-08-11】--ic-nav を追加した。PR #421 が appbar の戻るを
     24px にしたとき、この注記（4段・ここ以外に px を書かない）に反して CSS と Blade 25箇所へ
     px を直書きしていたため、段として引き上げて名前を与えた。値は変えていない。

     QRコードのイラスト（.mini-qr 62px）だけは例外で、アイコンではなく図版のため対象外。 */
  --ic-sm: 16px;  /* 文中・バッジの中の小さなアイコン */
  --ic-md: 18px;  /* 既定：ボタン・矢印（chev）・注記・ブランドマーク */
  --ic-lg: 22px;  /* アイコンボタン・下部タブ・選択肢・特徴リスト */
  --ic-nav: 24px; /* appbar の戻る。全サブ画面で最も押される操作のため --ic-lg より1段大きい */
  --ic-xl: 26px;  /* 円形の大きな容器の中（空状態・お休みカード・役割カード・LPロゴ） */

  /* 形 */
  --radius:   14px;
  --radius-sm:10px;
  /* 【P-12・第17回デザインレビュー】操作できる部品の角丸が8/9/10pxの3値に割れており、
     文字サイズ・アイコンが段に集約されているのに角丸だけスケールが無かった。`.btn`(10px)と
     `.btn-sm`(9px)の1px差の理由はコード・コメントのどこにも書かれていない。小さい操作部品を
     `--radius-sm`へ寄せ、生値は最小段のこれ1つだけ残して3段（8=最小・10=操作・14=カード）に畳む */
  --radius-xs: 8px;
  --radius-pill:999px;
  --gap: 14px;

  --shadow: 0 1px 2px rgba(24,34,51,.05), 0 6px 20px rgba(24,34,51,.06);
  --shadow-sm: 0 1px 2px rgba(24,34,51,.06);

  /* 自己ホストの Noto Sans JP を最優先。取得前・サブセット範囲外の字はシステムフォントで補う */
  --font: "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Hiragino Sans",
          "Yu Gothic", Meiryo, system-ui, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* 【HX-1・第175回ウォークスルー】固定ヘッダー（.appbar・sticky）と固定フッター（.tabbar・fixed）は
   ページ全体のスクロールの上に重なるため、ブラウザが「フォーカスした要素を見せる」ために行う
   自動スクロールが、要素を**バーの裏に置いたまま**止まることがある（WCAG 2.4.11 Focus Not
   Obscured）。実測（390×760・home.html／event-detail.html）で、欠席のひとこと入力欄・
   イベント案内カード・**主要CTAの「申し込む」ボタン**がタブバーの裏に入った。
   スクロールコンテナ（＝この画面群ではページ全体＝html）にバーの高さぶんの余白を宣言し、
   自動スクロールがバーを避けるようにする。個々の画面・要素に手当てを足さなくても全画面に効く。
   .tabbarを持たない画面では下側の余白が使われないだけで害はない。 */
html {
  scroll-padding-top: 54px;    /* .appbar の min-height */
  scroll-padding-bottom: 84px; /* .tabbar の高さ（約74px）＋余白。.app.has-tabbar .scroll の padding-bottom と同値 */
}
/* 【ID-1・第181回ウォークスルー】上のHX-1は「個々の画面・要素に手当てを足さなくても全画面に効く」と
   書いたが**偽だった**。上部に重なるバーは1本ではない——管理者画面は`.appbar`（54px）の下に
   `.tabs`（sticky・top:54px・実測49.09px）が重なり、遮蔽帯は0〜103pxになる。54pxしか避けないため、
   ブラウザが上方向へスクロールして要素を見せるとき（上端合わせ）の着地点が遮蔽帯の中に入る。
   実測（admin-dashboard.html・390×760・最下部から各要素へfocus）：27要素中7要素の着地点が
   54px指定と104px指定で25pxずれる＝この指定は現に効いている。高さ49px以下の要素が上端合わせで
   着地すれば完全に埋没するため、`.tabs`を持つ画面だけ遮蔽帯ぶんへ広げる
   （`.tabs`は`partials/admin-nav.blade.php`の1箇所のみ＝この1指定で全管理者画面に及ぶ）。

   **この指定で直らない残りがある（誇張しないために明記する）**：要素が既にスクロールポート内に
   ある場合、ブラウザは「見えている」と判断して**スクロールを一切行わない**。スクロールが起きない
   以上scroll-paddingは介入できず、sticky/fixedの裏にいても放置される。実測：admin-dashboard.html
   の最下部（scrollY=1179＝最大スクロール）で「来ました」ボタンがtop 66〜102pxに留まり、
   54px指定でも104px指定でも同じ（＝この残りはCSSでは解けない）。ただし**実キーボード操作では
   到達しない**——Tab・Shift+Tabを各90回歩いた実測で完全に隠れた要素は両方向とも0件だった
   （順送りは隣の要素から来るためスクロール位置が変わる）。focusinを監視して遮蔽を検知する
   JSを足す手はあるが、キーボードで到達しない事象のために新しい仕組みを持ち込む代償に
   見合わないと判断した（`walkthrough.md` §5.1の2問目）。 */
html:has(.tabs) {
  scroll-padding-top: 104px;   /* .appbar 54px ＋ .tabs 49px ＋ 1px */
}

/* ---------- フォーカス表示（キーボード操作） ----------
   従来はフォーカスの見せ方が3系統に割れていた：①入力欄＝`outline:none`＋`--brand-50`の
   3pxハロー（面に対して1.05〜1.10:1でほぼ不可視）②`.switch`/`.choice`＝2pxのブランド色
   リング ③ボタン・リンク・summary＝指定なし（UA既定まかせ）。②の見せ方に一本化する。
   WCAG 2.4.7（フォーカスの可視性）／2.4.13（背景に対し3:1以上・2px相当以上）。
   `--brand-600`は白地5.51:1・`--surface-2`地5.24:1で基準を満たす。
   `:focus-visible`なのでマウス操作では出ない（第134回デザインレビュー） */
:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 2px;
}

body {
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
  /* 日本語本文として読みやすい基本サイズ・行間（16px / 1.7）。個別指定のない本文・
     箇条書き・<small> はここを基準に相対的に決まる。 */
  line-height: 1.7;
  /* 【AH-2・第148回ウォークスルー】日本語の折り返し規則を**継承で全テキストへ効かせる**。
     これらは純粋な組版プロパティ（`overflow-wrap: anywhere`と違いmin-content幅を変えない）
     ため、全体に掛けても既存のレイアウトを動かさない。
     以前は対象セレクタを列挙していたが、**新しいテキスト要素を足すたびに列挙から漏れる**
     という同じ事故を3回起こした（CA-8→DA-4で横展開→XA-1で`.row .name`の漏れ→AH-2で
     `.feature .f-ttl`・`.date-badge .dow`の漏れ）。列挙し直す運用ではなく、列挙が要らない
     形にする（walkthrough.md §5.5）。見出しの`text-wrap: balance`は直接指定が継承に勝つため
     そのまま効く。 */
  line-break: strict; word-break: auto-phrase; text-wrap: pretty;
  -webkit-font-smoothing: antialiased;
  font-size: var(--fs-base);
}

/* ---------- レイアウト（layouts/guest.blade.php） ---------- */
.app {
  max-width: 560px;
  min-height: 100vh;
  margin: 0 auto;
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  box-shadow: 0 0 0 1px var(--line);
}

.appbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 54px;
  padding: 0 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  /* コンテンツとの境界を少しだけ立たせる控えめな影（固定ヘッダーの浮き） */
  box-shadow: 0 2px 6px rgba(24, 34, 51, .05);
}
.appbar .brand {
  display: flex; align-items: center; gap: 9px;
  text-decoration: none; color: var(--ink);
}
/* ロゴマークの9pxは操作部品のスケール（--radius-xs/-sm/--radius）に**乗せない**。ブランド資産の
   固有の形で、変えるとロゴの見え方が変わるため（P-12は「操作できる部品」の統一が対象）。 */
.appbar .brand .mark {
  width: 30px; height: 30px; border-radius: 9px;
  background: var(--brand-600);
  display: grid; place-items: center;
  color: #fff; flex: none;
}
.appbar .brand .mark svg { width: var(--ic-md); height: var(--ic-md); }
/* ローマ字ワードマーク＋小さな読み仮名の縦積みロックアップ */
.appbar .brand .lockup { display: flex; flex-direction: column; line-height: 1; }
/* ワードマークはロゴ用フォント Poppins（ラテンのみ）。取得前・環境差はシステムフォントで補う */
.appbar .brand .word { font-family: 'Poppins', var(--font); font-weight: 700; font-size: var(--fs-lg); letter-spacing: -.01em; color: var(--ink); }
/* 先頭の「k」だけブランド色にしてロゴのアクセントにする（マークのチェックマークと同色） */
.appbar .brand .word .mk { color: var(--brand-600); }
/* 【GM-7・第93回／2026-08-05に決着】ロゴのふりがな「クルカナ」は9.5pxで、design-review §1-A の
   「補助テキストは12pxを下回らない」を満たさない。**ロゴのロックアップは読ませる本文ではなく
   ブランド識別の一部**であり、同基準の対象外として9.5pxのまま維持すると決めた（ユーザー判断）。
   ワードマーク18pxとの比率でこのサイズが成り立っており、12pxまで上げると主従が崩れる。
   本文・キャプション側の12px下限はこれとは別に全件で守る。同じ扱いをするのは
   `.lp-brand-reading`（LPの大ロゴ・11px）と`.brand .reading`のみ。 */
.appbar .brand .reading { font-size: 9.5px; font-weight: 700; letter-spacing: .16em; color: var(--muted); margin-top: 3px; }

main {
  flex: 1;
  padding: 16px;
}

/* ---------- 見出し・テキスト（素のマークアップへの基本スタイル） ----------
   ステップ15（モック＝実装のUI一致化）で全画面がモック由来のクラスベース・コンポーネントへ
   移行済み。以下の要素セレクタ群は、クラス指定のない残存マークアップ（部分的な段落・
   ヘルプ本文・エラーページの素テキスト等）への後方互換フォールバックとして残置している。
   末尾の「モック同期コンポーネント」ブロックが同名プロパティでは常に優先されるため実害はない。
   新規画面はクラスベースで書くこと（この節に依存しない）。 */
main h1 { font-size: var(--fs-xl); font-weight: 800; margin: 4px 0 10px; line-height: 1.4; }
/* 【P-11・部品別デザインレビュー】以前はここで`color: var(--muted);`も宣言していたが、
   「h1の直後に置かれている」という位置だけで文字色が決まってしまい、間に要素（フラッシュ・
   バッジ等）が1つ挟まると無言で濃い色（ink）へ戻る問題があった（design-review.md §2.1
   「前提つきの指定は、前提そのものをセレクタで表す」）。位置に依存させず、色が必要な段落には
   `.muted`クラスを明示する運用へ変更した（該当箇所はCLAUDE.mdの節ではなく各Bladeビュー側で対応）。 */
main h1 + p { font-size: var(--fs-sm); margin: -6px 0 14px; }
main h2 { font-size: var(--fs-base); font-weight: 700; margin: 22px 0 8px; }
main h3 { font-size: var(--fs-sm); font-weight: 700; margin: 16px 0 6px; }
main p { margin: 8px 0; }
main a { color: var(--brand-700); }
main hr { border: none; height: 1px; background: var(--line); margin: 16px 0; }
.muted, main small { color: var(--muted); }
/* 日本語の折り返しを読みやすく：本文は文節区切り（対応ブラウザ）＋孤立行の回避、
   見出しは行長を均す。末尾1文字・語中での見づらい改行を抑える（他ブラウザは従来どおり）。
   【AH-2・第148回】要素を列挙する形はやめ、`body`からの継承で全テキストへ効かせている
   （下の`body`の宣言を参照）。ここは見出しの`balance`だけを残す */
main h1, main h2, .hero h1 { text-wrap: balance; }

/* ---------- セクション＝カード ---------- */
main section {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 16px;
  margin-bottom: var(--gap);
}
main section > h2:first-child { margin-top: 0; }
main details {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: var(--gap);
}
/* ただし**一覧行の中の`<details>`は行の一部**であって独立したカードではない。上のカード装飾が
   行の中にも効き、カードの入れ子に見えるうえ行が極端に高くなっていた。
   【2026-08-10・部品別レビュー5周目（最大規模）】組織の設定を30グループで描画して実測：
   1グループの行が173pxで、**うち約110pxがこの枠と余白**。20件のページで枠だけに800pxを使い、
   ページ全体は8.0画面ぶんになっていた。実際の情報（グループ名＋人数）は60pxしかない。
   `.lp-hero`の負マージンと同じで、**「自分が置かれる文脈」を仮定した指定**が別の文脈で破れた例 */
.row details, .choice details {
  background: none; border: 0; border-radius: 0; padding: 0; margin-bottom: 0; box-shadow: none;
}
/* 折りたたみの開閉トリガー。<summary>は操作要素なのでWCAG 2.5.8（AA・24px）の対象だが、
   この画面群では`.tiny`（12px）・`.sub`を重ねて使うため、素のままだと行高だけの
   20.4〜22.1pxにしかならない（実DOMで約100箇所を実測。第134回デザインレビュー）。
   縦のpaddingで最小24pxを確保する。`.summary-btn`（padding:14px 6px）や
   `summary.btn`（min-height:40px）はクラス側の詳細度が勝つため影響を受けない。 */
main summary { font-weight: 700; cursor: pointer; padding: 4px 0; min-height: 24px; }

/* ---------- リスト（トップレベルのulをカード化・行区切り） ---------- */
main > ul, main section > ul {
  list-style: none;
  margin: 0 0 var(--gap);
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
main > ul > li, main section > ul > li {
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-2);
}
main > ul > li:last-child, main section > ul > li:last-child { border-bottom: none; }
/* 入れ子のulは通常の箇条書きに戻す */
main li ul { list-style: disc; padding-left: 20px; background: transparent; border: none; box-shadow: none; }
main li ul li { padding: 2px 0; border: none; }
/* section内のカード化はsectionが既にカードのため面を消す */
main section > ul { box-shadow: none; border-color: var(--line-2); border-radius: var(--radius-sm); }

/* ---------- ナビゲーション（partials/*-nav） ---------- */
main nav.appnav {
  display: flex; flex-wrap: wrap; gap: 8px;
  align-items: center;
  margin: 0 0 16px;
}
main nav.appnav a {
  text-decoration: none;
  padding: 7px 13px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm); font-weight: 700;
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--line);
  white-space: nowrap;
}
main nav.appnav a:hover { background: var(--brand-50); color: var(--brand-700); }
main nav.appnav form { display: inline; margin-left: auto; }
main nav.appnav form button {
  height: auto; padding: 7px 13px;
  background: transparent; color: var(--muted);
  border: 1px solid transparent; border-radius: var(--radius-pill);
  font-size: var(--fs-sm); font-weight: 700; box-shadow: none;
}
main nav.appnav form button:hover { background: var(--surface); color: var(--ink-2); }

/* ---------- グループ切替タブ（partials/group-switcher） ----------
   グループ名は管理者が登録する自由文で長くなり得る。多数のグループは横スクロールで、
   1件が極端に長い場合は各タブを省略表示（…）して行が崩れないようにする。表示中の
   グループのフルネームは見出し（h1）で読める。 */
main nav.pill-tabs {
  display: flex; gap: 8px;
  margin: 0 0 16px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
main nav.pill-tabs::-webkit-scrollbar { display: none; }
/* 【JC-13・第201回ウォークスルー】position: relativeが無いと、内部の.sr-only（position:
   absolute）の containing block が最も近い position 祖先（.app）まで飛び、white-space:nowrapで
   計算される「切り詰め前の仮想行幅」の位置へ配置されて.appごとページを右へはみ出させる
   （195px幅で実測：はみ出し110px＝.sr-onlyの静的位置とほぼ一致）。overflow:hiddenは
   このリンク自身が position の基準になっていないと.sr-onlyを閉じ込められないため、
   position: relativeでこの<a>自身をcontaining blockにする（見た目・タップ領域への影響なし）。 */
main nav.pill-tabs a {
  position: relative;
  flex: none; max-width: 62%;
  text-decoration: none;
  padding: 7px 14px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm); font-weight: 700;
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--line);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
main nav.pill-tabs a:hover { background: var(--brand-50); color: var(--brand-700); }
main nav.pill-tabs a.on,
main nav.pill-tabs a.on:hover {
  background: var(--brand-600); color: #fff; border-color: var(--brand-600);
}
/* 今日にactiveな予定がある非選択グループの気づきドット（第7回W-12・opt-outモデルには
   「未連絡」状態がないため、タブの奥の開催に気づく契機として付ける）。
   非テキストコントラスト3:1（WCAG 1.4.11）を満たすbrand-600を、白系タブ背景に使う */
main nav.pill-tabs a .today-dot {
  display: inline-block; width: 8px; height: 8px; margin-left: 4px;
  border-radius: 50%; background: var(--brand-600); vertical-align: middle;
}

/* ---------- スクリーンリーダー専用（視覚的に隠すが読み上げは維持） ---------- */
/* 【HM-2・第164回ウォークスルー】ページ内アンカー（#visibility-settings 等）へ飛ぶと、
   着地点がsticky（appbar 54px＋tabs 49px）の裏に隠れて「どこへ来たか分からない」状態に
   なっていた（実測：見出しの上端が34.6pxで、sticky領域は103px）。個別のidに足すと
   新しいアンカーを作るたびに漏れるため、スクロール領域内の全idへ一律で持たせる。 */
.scroll [id] { scroll-margin-top: 112px; }

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

/* ---------- フォーム ---------- */
main label {
  display: block;
  font-weight: 700;
  font-size: var(--fs-sm);
  margin: 12px 0 6px;
}
/* チェックボックス・ラジオを内包するlabelは通常の行にする。
   【X-2・横展開レビュー】`:where()`で包んで詳細度を0に落とす。素の`:has(input[type="…"])`は
   引数の詳細度(0,1,1)を取り込むためルール全体が(0,1,3)になり、`.switch-row`(0,1,0)などの
   コンポーネントクラスに**勝って**いた。実測では`.check-row`の`align-items:flex-start`が
   `center`に、`.switch-row`の`gap:12px`が`8px`に、`.choice`の`gap:13px`が`8px`に潰され、
   87要素が自分のクラスに書いた値を受け取れていなかった（同意チェックのように文言が複数行に
   なる`.check-row`では、チェックボックスが縦中央に浮く）。
   以前のコメントは「他のクラスとの兼ね合い次第でこの詳細度が必要な場面がある」として
   `.tiny`だけを個別に救済していたが、実測するとこの詳細度で**得をしている要素は0件**で、
   損をしているものだけが87件だった（P-9は事例だけを直しており、これはその一般形の是正）。 */
main label:where(:has(input[type="checkbox"]), :has(input[type="radio"])) {
  /* font-size と margin は**上の`main label`（太字のフォームラベル用）を打ち消すだけ**にして、
     具体的な値はコンポーネント側（`.switch-row`・`.check-row`・`.choice`…）に委ねる。
     ここで具体値を書くと、クラスが宣言していない値だけがこちらから漏れてモックと食い違う
     （実測：文字が14px対16px、余白が8px対0）。この形のlabelは実測で**全70箇所がクラス付き**
     （素のものは0件）なので、寸法はクラスが持つのが筋 */
  font-weight: 400; font-size: inherit; margin: 0;
  display: flex; align-items: center; gap: 8px;
}
/* 【X-2】P-9で置いていた`main label.tiny:has(...)`の個別救済は不要になったので外した。
   上のルールを`:where()`で(0,0,2)に落としたことで、`.tiny`(0,1,0)が普通に勝つ。
   P-9は「`.tiny`という事例」だけを直しており、同じ原因を共有する他の6クラス（実測87要素）が
   残っていた——事例ではなくクラスで直す、の実例。 */
/* 同意チェック等の視認性・タップしやすさのため一回り大きく（タップ領域はlabel全体で確保）。
   【P-8・部品別デザインレビュー】以前は20pxで、`.check-row`だけが22pxへ個別に上げていたため
   サイズが2通り存在した。`.check-row`に合わせて22pxへ統一する（Material Designの48dp目安に
   近い。タップ領域自体は<label>側で確保されており実測26〜55pxでWCAG 2.5.8を満たすため、
   この変更では触れない）。 */
input[type="checkbox"], input[type="radio"] { accent-color: var(--brand-600); width: 22px; height: 22px; }

input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="date"], input[type="time"], input[type="search"], input[type="url"],
select, textarea {
  width: 100%;
  max-width: 420px;
  /* 【P-1・P-2／第17回デザインレビュー】枠線と高さは、下のモック同期ブロックの`.input`と
     **同じ値**にしておくこと。ここは要素セレクタ（詳細度0,1,1）なので、`class="input"`が
     付いていても**こちらが勝つ**——値がずれていると、クラスを書いたのに効かない状態になる。
     実際、枠線が`--line`（白背景で1.21:1）のままで、WCAG 1.4.11の非テキスト3:1を満たす
     `--control-border`（3.43:1）が入力欄140箇所へ届いていなかった（モックは--control-border
     だったので、実装とモックも食い違っていた）。高さも44/46pxで割れ、同じフォームの中で
     テキスト欄とセレクトに2pxの段差が出ていた */
  height: 46px;
  padding: 0 13px;
  /* 16px未満だとiOS Safariがフォーカス時に自動ズームしてしまうため16pxを下限にする */
  font-family: inherit; font-size: var(--fs-base); color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-sm);
  transition: border-color .12s, box-shadow .12s;
}
textarea { height: auto; padding: 11px 13px; resize: vertical; min-height: 84px; }
/* `outline:none`＋`--brand-50`の3pxハローという組み合わせをやめた。ハローは面に対して
   1.05〜1.10:1しかなく実質見えないのに、UA既定のフォーカスリングだけを消していた。
   枠線の色替えは残し、リング自体は冒頭の共通`:focus-visible`に任せる（第134回デザインレビュー） */
input:focus, select:focus, textarea:focus {
  border-color: var(--brand-500);
}
main form { margin: 10px 0; }
main section form { margin: 6px 0; }

/* ---------- ボタン ---------- */
/* 【X-1・横展開レビュー】対象は「`.btn`を持たない素の`<button>`」に限る。
   以前は `button, a.btn` で、`a.btn`が詳細度(0,1,1)になり後半の`.btn`(0,1,0)に**勝って**いた。
   その結果、同じ`.btn`でも`<a>`と`<button>`で見た目が変わっていた（実測：11修飾すべてで
   font-size 14/16px・padding 16/18px が食い違い、`a.btn-sm`は13px→14px・36px→40pxと
   「小さいボタン」の指定が丸ごと死に、`.btn-lg`の16pxも無効、`.btn-outline`の軽い影も
   出ていなかった）。モックは`<a>`と`<button>`で差が無く、実装だけがずれていた。
   なお下の `.btn-outline` 等の`a.btn.*`版（詳細度0,2,1）は、この基底に勝つためだけの
   打ち消しだったので不要になる（P-1と同じ「前半の要素セレクタが後半のクラスに勝つ」型） */
/* 【SR2A-16・第2周スクショレビューA-19】`:not(.choice)`を足した理由：この規則は
   「クラスを持たない素のbutton」への基底スタイルだが、詳細度(0,1,1)が`.choice`(0,1,0)に
   勝つため、`<button class="choice">`のbackground・colorまで奪っていた（メンバー選択画面
   だけが青く塗り潰され、所属名のコントラストが1.09:1＝AA大幅未達になっていた）。
   既存コメント（`.choice`の定義側）は同じ上書きの`font-weight`・`white-space`だけを
   打ち消しており、色の奪取を見落としていた。素のbuttonに付く実装済みのクラスは
   `.btn*`と`.choice`だけ（`no-print`・`right`は常に`.btn`と併用）で、
   `ButtonBaseStyleExclusionTest`が新しいクラスの追加を検出する */
button:not(.btn):not(.choice) {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 40px; padding: 0 16px;
  border-radius: var(--radius-sm);
  font-family: inherit; font-size: var(--fs-md); font-weight: 700;
  border: 1px solid transparent; cursor: pointer;
  transition: background .12s, border-color .12s, box-shadow .12s, opacity .12s;
  text-decoration: none; white-space: nowrap;
  background: var(--brand-600); color: #fff;
  /* 押せる感（アフォーダンス）を高める2層のソフトシャドウ（中立色。白背景の補助ボタンでも青く
     見えないように。重くならない範囲で一段強め） */
  box-shadow: 0 1px 2px rgba(24, 34, 51, .14), 0 3px 8px rgba(24, 34, 51, .12);
}
/* 【SR2F-17・第2周スクショレビューF-8】`a.btn:hover`（詳細度0,2,1）は、下のトーンダウン
   （`.btn-outline:hover`／`.btn-danger:hover`／`.btn-ghost:hover`＝いずれも0,2,0）に**勝って**
   いた。その結果`<a class="btn btn-ghost">`等はホバーで**背景だけがbrand-700の濃紺になり、
   文字色は暗いink-2のまま**＝コントラストが崩れていた（実測：やめるボタンが
   背景rgb(22,79,176)・文字rgb(68,80,100)）。X-1（基底`button, a.btn`を
   `button:not(.btn):not(.choice)`へ絞った）と**同じ型がホバー側に取り残されていた**もので、
   `.btn`（0,2,0・修飾子の規則より前に置く）へ直せば、後ろのトーンダウンが順序で勝つ。
   `<a>`版と`<button>`版で見た目が変わらなくなる点もX-1と同じ狙い。
   **`button:hover`側にも同じ除外が要る**（独立レビューの指摘）。SR2A-16は基底`button {}`を
   `button:not(.btn):not(.choice)`へ絞ったが**ホバーは絞らないまま残していた**ため、
   `button:hover`(0,1,1)が`.choice`(0,1,0)に勝ち、`<button class="choice">`
   （`members/select.blade.php`のメンバー選択カード）が**ホバーで濃紺に塗り潰されていた**
   （実測：背景`rgb(22,79,176)`・文字`rgb(24,34,51)`と`rgb(100,111,134)`＝2.11:1と1.50:1）。
   `.choice:hover`は`border-color`しか宣言しておらず`background`の勝負に参加しない。
   `.choice`が明示している`box-shadow: none`（DS-2）もホバー時だけ復活していた。
   **`.btn`側だけ直して`.choice`側を素通りしていた**（`self-review.md`「同じ原因を共有する
   兄弟を、名前が違っても一緒に直したか」）ので、基底と同じ除外を掛ける。 */
button:not(.btn):not(.choice):hover, .btn:hover { background: var(--brand-700); box-shadow: 0 2px 4px rgba(24, 34, 51, .16), 0 6px 16px rgba(24, 34, 51, .16); }
button:disabled {
  background: var(--line); color: var(--muted);
  border-color: var(--line); cursor: not-allowed; box-shadow: none;
}
/* 補助的なボタン（クラス指定でトーンダウン） */
/* 【JC-9・第201回ウォークスルー】枠線は白カード上で1.28:1（WCAG 1.4.11の3:1未達）だった。
   GM-1（第93回）で`.input`・`.choice`・`.choice .radio`へ入れた`--control-border`
   （白地3.43:1）が取り残されていたので揃える */
.btn-outline { background: var(--surface); color: var(--brand-700); border-color: var(--control-border); }
.btn-outline:hover { background: var(--brand-50); }
.btn-danger { background: var(--surface); color: var(--absent); border-color: var(--danger-border); }
.btn-danger:hover { background: var(--absent-bg); }
.btn-ghost { background: var(--surface); color: var(--ink-2); border-color: var(--control-border); box-shadow: none; }
.btn-ghost:hover { background: var(--surface-2); box-shadow: none; }
/* aタグの補助ボタン：基底の`a.btn`（詳細度0,1,1）に勝たせ、リンクでもトーンダウンを効かせる */
/* LINE連携・友だち追加のブランドボタン（LINE公式アカウントの緑）。ユーザーがLINEを期待する
   機能接点でのみ使い、装飾には使わない。白文字はLINE公式ボタンの慣例に合わせる（一般テキストの
   AA基準の例外）。公開前にLINEヤフーの公式ブランドガイドライン（色・ロゴ・呼称）を要確認。 */
.btn-line, a.btn.btn-line { background: #06c755; color: #fff; border-color: #06c755; }
.btn-line:hover, a.btn.btn-line:hover { background: #05b34c; border-color: #05b34c; }
/* インラインフォーム（テーブル・リスト内の操作ボタン）は小さく */
li button, td button, .btn-sm { min-height: 32px; padding: 0 11px; font-size: var(--fs-xs); border-radius: var(--radius-sm); }

/* ---------- テーブル ---------- */
main table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--gap);
  display: block;
  overflow-x: auto;
}
main table th, main table td {
  padding: 11px 12px; text-align: left;
  border-bottom: 1px solid var(--line-2);
  white-space: nowrap;
}
main table th { background: var(--surface-2); color: var(--muted); font-weight: 700; font-size: var(--fs-xs); }
main table tr:last-child td { border-bottom: none; }

/* ---------- バッジ・状態表示（クラスでオプトイン） ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-xs); font-weight: 700; line-height: 1;
  padding: 5px 10px; border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--ink-2);
}
.badge-present { background: var(--present-bg); color: var(--present); }
.badge-absent  { background: var(--absent-bg);  color: var(--absent); }
.badge-warn    { background: var(--warn-bg);    color: var(--warn); }
.badge-info    { background: var(--info-bg);    color: var(--info); }
.badge-muted   { background: var(--surface-2);  color: var(--muted); }

/* お知らせ帯 */
.note {
  display: block; padding: 12px 14px; border-radius: var(--radius);
  background: var(--info-bg); color: var(--brand-700);
  font-size: var(--fs-sm); margin-bottom: var(--gap); border: 1px solid var(--brand-100);
}
.note.warn { background: var(--warn-bg); color: #8a5a10; border-color: #f0dcae; }

/* サマリー数値（管理者ダッシュボード用・クラスでオプトイン） */
.stat-row { display: flex; gap: 10px; margin-bottom: var(--gap); }
.stat {
  flex: 1; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 14px 12px; text-align: center;
  box-shadow: var(--shadow-sm);
}
.stat .num { font-size: var(--fs-2xl); font-weight: 800; line-height: 1.1; }
.stat .lbl { font-size: var(--fs-xs); color: var(--muted); margin-top: 3px; }
.stat.is-absent .num { color: var(--absent); }
.stat.is-present .num { color: var(--present); }

/* メーター（LINE枠・無料枠） */
.meter { height: 10px; border-radius: var(--radius-pill); background: var(--line-2);
  overflow: hidden; margin: 8px 0 6px; max-width: 420px; }
.meter > i { display: block; height: 100%; border-radius: inherit; background: var(--brand-600); }
.meter.warn > i { background: var(--warn); }

/* フッター（公開ページ） */
footer, .footer { padding: 24px 16px 34px; text-align: center; color: var(--muted); font-size: var(--fs-xs); }
/* フッターのリンクは文中リンクではなく単独の導線なので、WCAG 2.5.8（AA・24px）の
   インライン例外に当たらない。12pxの裸のリンクは高さ17px前後しかないため縦paddingで
   タップ領域を確保する（第134回デザインレビューで実DOM測定により検出） */
footer a, .footer a { display: inline-block; padding: 6px 0; color: var(--muted); margin: 0 8px; }

/* =====================================================================
   LP・ガイド（welcome / guide）
   ---------------------------------------------------------------------
   ・LPは「まず役割（管理者／メンバー）を選ばせ→説明→登録」の導線（04参照）。
   ・ガイドは縦スクロールの1ページ説明（「こんなことができる」→はじめ方→料金→登録）。
     カードを縦に読み進める構成（旧スライドショーは、カードごとの高さの差で前後ナビの
     位置がずれ操作感が悪かったため廃止）。
   ===================================================================== */

/* ---------- ヒーロー ---------- */
.hero {
  background: linear-gradient(165deg, var(--brand-50), var(--surface) 70%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 30px 20px 26px;
  text-align: center;
  margin-bottom: var(--gap);
}
.hero .eyebrow {
  display: inline-block; font-size: var(--fs-xs); font-weight: 700;
  color: var(--brand-700); background: var(--brand-100);
  padding: 5px 12px; border-radius: var(--radius-pill); margin-bottom: 14px;
}
.hero h1 { font-size: var(--fs-2xl); line-height: 1.42; margin: 0 0 12px; letter-spacing: .01em; text-wrap: balance; }
/* 見出しの一部をブランド色で受ける（LPのヒーローが `.lp-hero h1 .accent` で行っているのと同じ扱い）。
   宣伝側のページ（機能ガイド・役割ガイド）で、装飾を増やさずにブランドの気配だけを足すため。 */
.hero h1 .accent { color: var(--brand-600); }
.hero .lead { color: var(--ink-2); font-size: var(--fs-md); margin: 0; }

/* ヒーロー内の実画面ミニプレビュー（少し浮かせて注目させる） */

/* =====================================================================
   LP（welcome.blade.php）の演出。ページ内 .lp 配下だけに閉じ、他画面へは影響させない。
   ・ヒーローはほぼ全画面・全幅（main の内側余白を打ち消して端まで）。見出しは語ごとに
     立ち上げ、スクロールで薄れながら上へ閉じる（welcome の inline script）。
   ・以降のセクションはスクロールで下から現れる（IntersectionObserver）。
   ・prefers-reduced-motion では全アニメーションを無効化して即表示する。
   ===================================================================== */
.lp-hero {
  /* 既定の main section のカード装飾（枠・角丸）は打ち消し、全幅で端まで届かせる */
  border: 0; border-radius: 0; box-shadow: none;
  margin: 0 -16px 0;                  /* main の padding を左右だけ打ち消して全幅にする */
  /* 【2026-08-25・観点O（既定値との距離）】以前は`100dvh - 54px`＝画面を丸ごと占有していた。
     実測（390x844）でヒーロー全高790pxのうち**上下258px（33%）が空**で、次のセクションが
     1pxも見えないため、スクロール誘導の矢印を別途置く必要があった（その矢印は無限アニメーション
     `lpBob`だった）。§1-OのO-5「中央寄せの大見出しヒーローという最頻出の型」とO-8「意味の
     ない動き」に同時該当し、しかも**矢印はヒーローが高すぎることの代償**でしかなかった。
     次セクションの先頭が約90px覗く高さへ改め、「下に続く」ことはコンテンツ自身に語らせる
     （誘導の矢印は同じ変更で削除した）。画面が低い端末では`min-height`なので内容なりに伸びる。 */
  min-height: calc(100vh - 150px);
  min-height: calc(100dvh - 150px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 40px 24px 34px;
  /* 先頭（トップ）のグラデーションを少しだけ濃く：上部の発光を一段強め、ベースの起点も深くする */
  background:
    radial-gradient(120% 82% at 50% -8%, rgba(31, 99, 214, .16), transparent 58%),
    linear-gradient(176deg, var(--brand-100), var(--surface-2) 84%);
}
/* 【2026-08-10・部品別レビュー】上端まで届かせる負のマージンは**ヒーローがmainの先頭にある
   ときだけ**当てる。以前は無条件に`margin-top:-16px`を掛けており、上にフラッシュ
   （「組織を削除しました。」等）やログイン後のナビが入ると、ヒーローが16px迫り上がって
   **その文字に覆いかぶさっていた**（組織削除という最も重い操作の直後の着地で、描画バグに
   見える状態だった）。負のマージンは「自分が先頭である」という前提つきの指定なので、
   前提そのものをセレクタで表す。 */
main > .lp:first-child > .lp-hero { margin-top: -16px; }

.lp-hero-inner { width: 100%; max-width: 360px; will-change: transform, opacity; }

/* ブランド（サービス名を大きく提示。スクロールで薄れてもヘッダーの小ワードマークが残るため
   継続性は保てる）。ロックアップ＝ロゴマーク＋「kurukana」＋読み仮名。 */
.lp-brand { display: inline-flex; align-items: center; gap: 12px; opacity: 0; animation: lpFadeUp .6s ease .04s forwards; }
.lp-brand .m {
  width: 46px; height: 46px; border-radius: var(--radius); flex: none;
  background: var(--brand-600); color: #fff; display: grid; place-items: center; box-shadow: var(--shadow-sm);
}
.lp-brand .m svg { width: var(--ic-xl); height: var(--ic-xl); }
/* 大ロゴもワードマークはロゴ用フォント Poppins。先頭「k」だけブランド色（appbar と同じ扱い） */
.lp-brand .w { font-family: 'Poppins', var(--font); font-size: var(--fs-4xl); font-weight: 700; letter-spacing: -.02em; line-height: 1; color: var(--ink); }
.lp-brand .w .mk { color: var(--brand-600); }
.lp-brand-reading {
  display: block; margin: 11px 0 0; padding-left: .34em;
  font-size: 11px; font-weight: 800; letter-spacing: .34em;
  /* 【第151回の判断待ち→第152回で決定】読み仮名は初見の認知を補う＝読ませるための要素なので、
     ロゴタイプのコントラスト除外を援用しない。ヒーローのグラデーション上でmuted（3.86:1）は
     AA未達のためink-2へ（実背景rgb(213,226,249)に対し計算6.2:1・AA充足） */
  color: var(--ink-2);
  opacity: 0; animation: lpFadeUp .6s ease .13s forwards;
}

.lp-eyebrow {
  display: inline-block; font-size: var(--fs-xs); font-weight: 700;
  color: var(--brand-700); background: var(--brand-50);
  padding: 5px 12px; border-radius: var(--radius-pill); margin: 22px 0 20px;
  opacity: 0; animation: lpFadeUp .6s ease .22s forwards;
}

.lp-hero h1 { font-size: var(--fs-3xl); font-weight: 800; line-height: 1.32; letter-spacing: -.01em; margin: 0 0 18px; color: var(--ink); }
/* 見出しの語を1つずつ：ブラー＋わずかな持ち上げからスッと定位置へ */
.lp-hero h1 .w { display: inline-block; opacity: 0; filter: blur(10px); transform: translateY(.42em); animation: lpWordIn .72s cubic-bezier(.2,.75,.25,1) both; }
.lp-hero h1 .accent { color: var(--brand-600); }
@keyframes lpWordIn { to { opacity: 1; filter: blur(0); transform: none; } }

.lp-sub { margin: 0 auto; max-width: 22em; color: var(--ink-2); font-size: var(--fs-base); line-height: 1.8; opacity: 0; animation: lpFadeUp .7s ease .58s forwards; }
.lp-cta { margin-top: 24px; opacity: 0; animation: lpFadeUp .7s ease .78s forwards; }
@keyframes lpFadeUp { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* LP各セクションの縦リズム。既定の main section のカード装飾（背景・枠・影）は打ち消し、
   モックと同じく連続スクロールのフラットな見せ方にする（フルブリードのヒーローに続く一続きの流れ）。 */
.lp .lp-sec {
  background: none; border: 0; box-shadow: none; border-radius: 0;
  padding: 56px 0 8px; margin-bottom: 0;
}
/* 節の最後の要素が持つ下マージンぶんだけ、セクション間の間隔が広がってしまう
   （実測で64/74/64pxとばらついていた）。間隔はpaddingだけで決める */
.lp .lp-sec > *:last-child { margin-bottom: 0; }
.lp-h { text-align: center; margin: 0 0 6px; }
/* オーバーライン（セクションの小ラベル）。**この記述はかつて「角丸ピル・brand-700×brand-50」と
   書かれていたが、実装は当時すでに背景も角丸も持たない素のテキスト（--ink-2）になっており、
   記述だけが取り残されていた**（2026-08-25に実物と突き合わせて訂正）。
   現在は背景も角丸も持たない素のラベルで、色は`--ink-2`。
   【2026-08-25】差し色（アクセント）をここへ当てる案を実装したが、7案を並べて比較した結果
   **アクセントを入れない現状が最も自然**というユーザー判断で差し戻した（docs/18 §3.40）。
   ここを何色かにしたくなったら、まずその判断を読み直すこと。 */
.lp-h .kicker {
  display: inline-block;
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: .18em;
  color: var(--ink-2);
  margin-bottom: 12px;
}
.lp-h h2 { font-size: var(--fs-xl); font-weight: 800; line-height: 1.5; letter-spacing: -.01em; margin: 0; color: var(--ink); }

/* LP統一タイプスケール（px）：Display30／XL24／L20／M15／Base13.5／S12／Chip11.5。
   中〜小サイズ帯の near-duplicate（15/15.5/16・13/13.5/14・12/12.5）を M15／Base13.5／S12 の
   3段へ集約し、「階層ではなく不揃い」に見える違和感を排する。セクションのプローズ（導入文・
   注記）は中央寄せ・行間広め・最大幅を揃える。リスト行・カード内部の文は左寄せのまま。 */
.lp-intro { text-align: left; font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.9; margin: 8px 0 16px; max-width: 34em; }
/* 景表法の打消し表示（「30日間無料」→自動課金の併記）を後景化させないよう、
   薄いmutedではなく本文寄りのink-2で視認性を確保する */
.lp-fine  { text-align: left; font-size: var(--fs-xs);   color: var(--ink-2); line-height: 1.8; margin: 0 0 12px; max-width: 34em; }
/* ヒーローだけは中央揃えの塊（ロゴ・バッジ・見出し・CTAが縦に中央で積まれた1枚の面）として
   保つ。ここで本文だけ左に寄せると、ポスター的な構成が崩れる */
.lp-hero .lp-fine, .lp-hero .lp-sub { text-align: center; margin-left: auto; margin-right: auto; }
/* 料金セクションの主役＝「基本は無料。」を一段大きく見せる（表は出さず一言で価値を立てる） */
.lp-price-lead { text-align: center; font-size: var(--fs-xl); font-weight: 800; color: var(--brand-700); line-height: 1.5; margin: 2px auto 10px; }
/* 料金：見出し(h2 21px)と価格リード(19px)が近接サイズでガタつくため、価格情報を1枚のカードへ
   まとめて塊として分離する。カード内の主役「基本は、無料。」を一段大きく（26px）して、サイズ差を
   意味（＝価格の主役）と結びつけ、近接サイズの微妙な差をなくす。 */
.lp-price-card {
  text-align: center; padding: 26px 20px; margin: 4px auto 0;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.lp-price-card .lp-price-lead { font-size: var(--fs-2xl); margin: 0 0 8px; }
/* 料金の主役＝2つの数字（無料枠と単価）。散文に埋めず行として立てる。左に条件・右に金額の
   2列で、拾い読みでも「10人まで無料」「11人目から10人ごとに月200円」が取れるようにする。 */
.lp-price-rows { margin: 0 0 12px; padding: 0; }
.lp-price-rows > div {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 9px 0; border-top: 1px solid var(--line-2);
}
.lp-price-rows > div:first-child { border-top: 0; }
.lp-price-rows dt { font-size: var(--fs-sm); color: var(--ink-2); }
/* 【独立レビュー】`white-space: nowrap` は狭幅でカードの外へ金額を押し出し、240px（480px端末の
   ズーム200%相当・AH-2が対象にしている条件）では「円」が画面外へ消えていた。折り返しを許し、
   右揃えにして条件（dt）と金額（dd）の対を保つ。 */
.lp-price-rows dd { margin: 0; font-size: var(--fs-base); font-weight: 800; color: var(--ink); text-align: right; }
.lp-price-rows dd b { font-weight: 800; }
.lp-price-card .lp-price-desc { text-align: left; font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.85; margin: 0; }
/* 但し書きとして一段下げるのは、上に「条件＝金額」の対（.lp-price-rows）があるときだけ。
   /features は対を持たずこの文が唯一の価格説明なので、そちらは本文サイズのままにする */
.lp-price-rows + .lp-price-desc { font-size: var(--fs-xs); line-height: 1.8; }
/* 「30日間無料」の注記は、価格カードから少しだけ余白を空ける（塊の分離を明確にする） */
.lp-price-card + .lp-fine { margin-top: 12px; }
/* 料金セクションの最終CTA：全幅ブロックは短い文言に対して横に広すぎ、ヒーローCTA（内容幅）との
   非対称も生む。本文コラム幅（最大300px）に合わせて中央寄せにし、押しやすさは保ちつつ幅を締める。 */
.lp-cta-final { max-width: 300px; margin: 4px auto 0; }

/* つかいかた：メンバーの「休むだけ」→（締切で自動集計）→管理者に「まとめが届く」の流れを見せる。
   役割ラベル・下向き矢印のつなぎ・管理者向けのまとめ通知カードで価値のループを可視化する。 */
.lp-role-label { text-align: center; font-weight: 700; font-size: var(--fs-sm); letter-spacing: .04em; color: var(--muted); margin: 0 0 8px; }
.lp-flow { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 16px auto 4px; }
/* つなぎの下向き矢印は「文字っぽい細線」ではなく、丸バッジ入りの太めアイコンにして
   design感（意図した連結要素）を出す。brand-50は背景（surface-2）と同化し、brand-600の塗りは
   印象が強すぎるため、中間の brand-100 地＋brand-600 矢印にする（同化せず・柔らかい）。
   線幅は他のアイコンと同じ 1.8（以前は 2.6 で、この矢印だけ明らかに太く見えていた）。 */
.lp-flow .flow-ic { width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand-100); color: var(--brand-600); }
.lp-flow .flow-ic svg { width: var(--ic-lg); height: var(--ic-lg); stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.lp-flow span { font-size: var(--fs-sm); color: var(--muted); }
.lp-notify .n-title { font-weight: 800; font-size: var(--fs-sm); margin: 0 0 8px; color: var(--ink); }

/* スクロールで現れるセクション。
   【第151回デザインレビュー】隠す指定は`.lp-anim`（出現スクリプトが冒頭で付けるクラス）が
   あるときだけ効かせる。以前は`.lp .reveal`が無条件に`opacity: 0`で、**JSが無効・失敗した
   環境ではヒーローより下の全セクション（つかいかた・できること・役割選択・料金）が
   永久に不可視**だった（JS無効のChromiumで実測：4/4セクションがopacity 0のまま）。
   既定は表示＝コンテンツが読めることを最優先し、アニメは上乗せ（プログレッシブ
   エンハンスメント）とする。`.in`側の指定はクラス数が同じで後勝ちのため変更不要 */
.lp.lp-anim .reveal { opacity: 0; transform: translateY(22px); transition: opacity .6s ease, transform .6s cubic-bezier(.2,.7,.25,1); }
.lp .reveal.in { opacity: 1; transform: none; }
/* セクション内の行・カードは少しずつ遅らせて出す */
.lp.lp-anim .reveal .features > .feature, .lp.lp-anim .reveal .role-cards > .role-card, .lp.lp-anim .reveal .lp-stagger > * {
  opacity: 0; transform: translateY(12px); transition: opacity .5s ease, transform .5s ease;
}
.lp .reveal.in .features > .feature, .lp .reveal.in .role-cards > .role-card, .lp .reveal.in .lp-stagger > * { opacity: 1; transform: none; }
.lp .reveal.in .features > .feature:nth-child(1), .lp .reveal.in .role-cards > .role-card:nth-child(1), .lp .reveal.in .lp-stagger > *:nth-child(1) { transition-delay: .06s; }
.lp .reveal.in .features > .feature:nth-child(2), .lp .reveal.in .role-cards > .role-card:nth-child(2), .lp .reveal.in .lp-stagger > *:nth-child(2) { transition-delay: .12s; }
.lp .reveal.in .features > .feature:nth-child(3), .lp .reveal.in .lp-stagger > *:nth-child(3) { transition-delay: .18s; }
.lp .reveal.in .features > .feature:nth-child(4) { transition-delay: .24s; }
.lp .reveal.in .features > .feature:nth-child(5) { transition-delay: .30s; }
.lp .reveal.in .features > .feature:nth-child(6) { transition-delay: .36s; }
/* つかいかた：上から順に出し、つなぎ（下向き矢印＋「締切になると…」）は直前のメンバーカードより
   少し遅らせて「それから流れる」感を出す。結果（＝管理者に届く）はさらにその後に続ける。
   汎用 .lp-stagger の nth-child 既定より後に置き、同一詳細度を発生順で上書きする。 */
.lp .reveal.in .lp-usage > *:nth-child(1) { transition-delay: .06s; } /* メンバー側ラベル */
.lp .reveal.in .lp-usage > *:nth-child(2) { transition-delay: .14s; } /* メンバーカード */
.lp .reveal.in .lp-usage > *:nth-child(3) { transition-delay: .40s; } /* つなぎ（矢印）＝少し遅れて */
.lp .reveal.in .lp-usage > *:nth-child(4) { transition-delay: .52s; } /* 管理者側ラベル */
.lp .reveal.in .lp-usage > *:nth-child(5) { transition-delay: .60s; } /* まとめ通知カード */

@media (prefers-reduced-motion: reduce) {
  .lp-brand, .lp-brand-reading, .lp-eyebrow, .lp-hero h1 .w, .lp-sub, .lp-cta,
  .lp .reveal, .lp .reveal .features > .feature, .lp .reveal .role-cards > .role-card, .lp .reveal .lp-stagger > * {
    animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important;
  }
}

/* ---------- 役割選択カード（LPの主役） ---------- */
.pick { padding-top: 2px; }
/* 役割セクションの見出しも他セクションの h2 と同じ大きさ（21px）に揃える */
.pick-lead { font-weight: 800; text-align: center; margin: 0 0 14px; font-size: var(--fs-xl); line-height: 1.5; color: var(--ink); }
.pick-note { text-align: center; color: var(--muted); font-size: var(--fs-sm); margin: 4px 0 0; }
.role-cards { display: flex; flex-direction: column; gap: 12px; margin: 0 0 var(--gap); }
.role-card {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 18px 16px; text-decoration: none; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color .12s, box-shadow .12s, transform .06s;
}
.role-card:hover { background: var(--surface); border-color: var(--brand-500); box-shadow: var(--shadow); }
.role-card:active { transform: translateY(1px); }
.role-card .role-ic {
  width: var(--ic-xl); height: var(--ic-xl); flex: none; margin-top: 1px;
  display: grid; place-items: center; color: var(--brand-600);
}
.role-card .role-ic svg { width: var(--ic-xl); height: var(--ic-xl); }
.role-card.is-member .role-ic { color: var(--present); }
.role-card .role-body { flex: 1; min-width: 0; }
.role-card .role-ttl { display: block; font-weight: 800; font-size: var(--fs-base); }
.role-card .role-sub { display: block; color: var(--muted); font-size: var(--fs-xs); margin-top: 3px; line-height: 1.5; }
.role-card .role-arrow { flex: none; color: var(--muted); display: grid; place-items: center; align-self: center; }

/* ---------- 特長リスト（アイコン＋見出し＋補足） ----------
   フラットな下線リストだと、中央寄せの見出し群に対して内容だけが左に浮いて見える
   （整列規則の不一致）。1枚のカードに載せて「見出し（中央）→カード（左寄せの中身）」に揃え、
   アイコンも一回り大きくして存在感を出す（38→44px・svg 22px）。カード内部は左寄せでよい。 */
.features {
  margin: 6px 0 2px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px 18px;
}
.feature { display: flex; align-items: flex-start; gap: 14px; padding: 15px 0; border-bottom: 1px solid var(--line-2); }
.feature:first-child { padding-top: 4px; }
.feature:last-child { border-bottom: none; padding-bottom: 4px; }
/* 特長カードを機能ガイド（/features）への入口にする（docs/94 §4）。新しいボタンを増やさず、
   既にある行そのものをタップ領域にする。`.row`と同じく色・下線は継承させ、
   右端に矢印を出して「押せる」ことを示す（design-review §1-D アフォーダンス）。 */
a.feature { text-decoration: none; color: inherit; }
a.feature:hover { background: var(--surface-2); }
a.feature > div { flex: 1; min-width: 0; }
.feature .f-arrow { color: var(--muted); flex: none; align-self: center; }
.feature .f-arrow svg { width: var(--ic-sm); height: var(--ic-sm); }
.feature .f-ic {
  width: var(--ic-lg); height: var(--ic-lg); flex: none; margin-top: 2px;
  display: grid; place-items: center; color: var(--brand-600);
}
.feature .f-ic svg { width: var(--ic-lg); height: var(--ic-lg); }
.feature .f-ttl { font-weight: 700; font-size: var(--fs-base); margin: 0; }
.feature .f-sub { color: var(--muted); font-size: var(--fs-sm); line-height: 1.75; margin: 3px 0 0; }
/* 【AH-2・第148回ウォークスルー】文字を大きくして使う人（小画面スマホ＋ページズーム200%）では
   実効幅が200px前後まで縮む。かつては44pxの色付きアイコンタイルが見出しの列を潰していたため
   280px以下でアイコンを隠していたが、2026-08-11にタイルを廃止して22pxの裸アイコンにしたので
   幅を圧迫しなくなった（240pxでも見出しは折り返しの範囲に収まることを実測）。ルールごと外す。 */

/* ---------- 料金ミニ ----------
   プランは縦積みの1行カード（名称＝左・価格＝右、補足＝下段に全幅）。横3列だと
   スマホ幅で「メール通知グループ」等が語中で改行されて読みにくいため、各プランへ横幅を
   与えて改行を防ぐ。 */
.plan-mini { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 10px; }
.plan-mini .plan {
  display: grid; grid-template-columns: 1fr auto; align-items: baseline; column-gap: 12px;
  text-align: left; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 16px;
}
/* 強調は「主役」の1枚（無料枠）に付ける見た目クラス。旧is-paidから改称
  （LPの「基本は、無料。」と視覚優先度を揃えるため、強調対象を有料2枚→無料枠へ変更） */
.plan-mini .plan.is-hero { border-color: var(--brand-500); background: var(--brand-50); }
.plan-mini .plan .p-name { font-weight: 700; margin: 0; }
.plan-mini .plan.is-hero .p-name { color: var(--brand-700); }
.plan-mini .plan .p-price { font-size: var(--fs-xl); font-weight: 800; margin: 0; text-align: right; white-space: nowrap; }
.plan-mini .plan .p-price small { font-size: var(--fs-xs); color: var(--muted); font-weight: 700; }
/* 補足は名称・価格の下段に全幅で置く */
.plan-mini .plan .p-note { grid-column: 1 / -1; font-size: var(--fs-xs); color: var(--muted); margin: 3px 0 0; line-height: 1.5; }

/* ---------- CTAブロック・幅いっぱいボタン ---------- */
.cta-block { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.btn-block { width: 100%; }
.btn-lg { min-height: 48px; font-size: var(--fs-base); }

/* ---------- ガイド（縦スクロール説明のカード） ---------- */
.slide {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
  padding: 22px 20px; margin-bottom: var(--gap);
}
.slide .step-no {
  display: inline-block; font-size: var(--fs-xs); font-weight: 700;
  color: var(--brand-700); background: var(--brand-50);
  padding: 3px 9px; border-radius: var(--radius-pill);
}
.slide h2 { margin: 10px 0 8px; font-size: var(--fs-lg); }
.slide h2:first-child { margin-top: 0; }
.slide p { color: var(--ink-2); }
/* ステップに添える実画面風ミニプレビュー（LPのミニカードと同じ思想）を載せる枠。
   以前は絵文字だけを幅広の箱に置いて「広い領域にアイコンがポツン」という見え方だったため、
   各ステップの内容に対応する実画面風のミニカードを見せる形へ変更した。 */
.slide .slide-art {
  background: linear-gradient(165deg, var(--brand-50), var(--surface-2));
  border: 1px solid var(--line-2); border-radius: var(--radius);
  padding: 18px; margin: 14px 0 4px; text-align: center;
}
/* ミニプレビュー内の小部品（用途えらぶ・QR・お知らせ等） */
.mini-card .mini-label { font-size: var(--fs-xs); color: var(--muted); margin: 0 0 8px; text-align: left; }
.mini-card .mini-note-title { font-weight: 800; font-size: var(--fs-sm); margin: 0 0 6px; color: var(--ink); text-align: left; }
.mini-choices { display: flex; flex-direction: column; gap: 6px; }
.mini-choice {
  display: block; padding: 8px 12px; border-radius: var(--radius-sm); font-size: var(--fs-xs); font-weight: 700;
  color: var(--ink-2); background: var(--surface-2); border: 1px solid var(--line); text-align: left;
}
.mini-choice.is-on { color: var(--brand-700); background: var(--brand-50); border-color: var(--brand-500); }
.mini-qr {
  display: inline-grid; place-items: center; width: 82px; height: 82px;
  border-radius: var(--radius-sm); background: #fff; border: 1px solid var(--line); color: var(--ink);
}
/* ガイド内の「QRっぽい図版」。アイコンではなく図なのでアイコンスケールの対象外 */
.mini-qr svg { width: 62px; height: 62px; }

/* 実物のQRコード（招待・引き取り）。QrCode::size(n) は svg に幅を固定で持たせるため、
   狭い画面・印刷の狭い列では容器からはみ出す。外側の div に max-width を掛けても
   svg には効かないので、中身側に掛ける（第135回デザインレビュー IC-5）。 */
.qr-img { max-width: 100%; margin: 0 auto; }
.qr-img svg, .qr-img img { max-width: 100%; height: auto; display: block; margin: 0 auto; }
/* スライド内のミニ・モック（出欠カード等） */
.mini-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); padding: 12px 14px; text-align: left; max-width: 300px; margin: 0 auto;
}
.mini-card .mini-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.mini-card .mini-btns { display: flex; gap: 8px; }
/* ミニ・モック内の装飾ボタン（実操作ではないためspanで表現し、CSSでボタン風に見せる） */
.mini-card .mini-btns span {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 7px 16px; font-size: var(--fs-xs); font-weight: 700;
  color: var(--brand-700); background: var(--surface);
  border: 1px solid var(--brand-100); border-radius: var(--radius-sm);
}

/* ---------- 印刷（QR一括印刷・予約名簿の印刷ビュー） ---------- */

/* =====================================================================
   モック同期コンポーネント（mockups/assets/app.css と同一・design.md 同期）
   ---------------------------------------------------------------------
   ・ステップ15「モック＝実装のUI一致化」の土台。モックのクラスベース
     コンポーネント（card / list / row / choice / switch / seg / tabs /
     tabbar / field / sheet 等）をそのまま移植する（フォント・トークン・
     ガイド/LPブロックは上部の既存定義を正とし重複させない）。
   ・ファイル末尾に置くことで、同名プロパティは既存の素マークアップ向け
     基本スタイルより優先される（同一詳細度は後勝ち・クラスは要素に勝つ）。
   ・モック側と内容がずれたら本ブロックを丸ごと差し替えて同期すること。
   ===================================================================== */

/* ---------- 端末フレーム ---------- */
.app {
  position: relative;
  max-width: 480px;
  min-height: 100vh;
  margin: 0 auto;
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
}
/* 下部ナビ／固定フッターと重ならないための余白 */
.app.has-tabbar .scroll { padding-bottom: 84px; }

.scroll {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
}
.scroll.flush { padding: 0; }

/* ---------- アプリバー（上部） ---------- */
.appbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 54px;
  padding: 0 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  /* コンテンツとの境界を少しだけ立たせる控えめな影（固定ヘッダーの浮き） */
  box-shadow: 0 2px 6px rgba(24, 34, 51, .05);
}
/* appbarのタイトル。`.appbar`は`min-height:54px`の1行想定だが、タイトルは
   `overflow-wrap:anywhere`（.page-title系の既定）と競合するとflexの中で潰され、
   「ユーザー照会」のような6文字でも2行に割れて54pxの枠から溢れていた
   （運営コンソールで実測：他画面のタイトルが高さ27pxのところ54px。第134回デザインレビューW4-2）。
   縮まないようにして、それでも入らないときは末尾を省略する（折り返して枠を壊さない）。 */
.appbar .title {
  font-size: var(--fs-base);
  font-weight: 700;
  letter-spacing: .01em;
  flex: 0 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 運営コンソールのappbarだけは「戻る＋タイトル＋お知らせ管理＋操作ログ」の4つが並び、
   375pxではタイトルを削らないと収まらない。タイトルは画面の身元なので削らせず、
   二次的なナビの方を次の行へ折り返す（`.ops`にはadmin上部タブ（.tabs・top:54px）が無いため
   appbarが高くなってもstickyの基準は壊れない。第134回デザインレビューW4-2） */
.ops .appbar { flex-wrap: wrap; height: auto; min-height: 54px; row-gap: 2px; padding-top: 6px; padding-bottom: 6px; }
.ops .appbar .title { flex: 0 0 auto; }
.appbar .spacer { flex: 1; }
/* アイコンだけのボタン／リンク。従来は`.appbar .iconbtn`にしか寸法が無く、appbarの外で
   使うと中身のsvg幅（18px）しか持たずWCAG 2.5.8の24pxを下回っていた
   （`coach/board.blade.php:157`の各グループ行「管理へ」が実測27.2×18px。
   第134回デザインレビュー）。基底クラス側で寸法を持たせ、置き場所に依存させない。 */
/* 【DS-2・第136回】素の `button` ルール（背景・影・min-height:40px・padding:0 16px）は
   `.btn` を付けない独自ボタン部品にも当たる。`<a class="iconbtn">` は `a.btn` に一致しないため
   影が出ず、`<button class="iconbtn">` にだけ影が付いて高さも 38→40px にずれていた
   （同じ戻る矢印が、リンクかボタンかで見た目が変わっていた）。ここで打ち消す。 */
.iconbtn {
  width: 38px; height: 38px; min-height: 0; padding: 0;
  display: grid; place-items: center;
  border-radius: var(--radius-pill);
  color: var(--ink-2);
  background: transparent;
  border: none;
  box-shadow: none;
  cursor: pointer;
  flex: none;
}
/* appbarの戻る（上位階層へ）。**この画面群でいちばん押される操作**なので、一覧行の
   装飾矢印（`.chev`）とは意図的に差をつける。
   【2026-08-10・デザインレビュー】以前は`.chev`とまったく同じchevron（`15 6 9 12 15 18`）の
   左右反転を22px・線1.8で置いていた。字形も線幅も行末の装飾記号と同一で、太字のタイトル
   （16px/700）と視覚的な重量が釣り合わず「置いただけ」に見えていた。尾のある`arrow-left`へ
   替え、24pxに上げて釣り合わせる。 */
.appbar .iconbtn {
  width: 44px; height: 44px; min-height: 0; padding: 0;
  display: grid; place-items: center;
  border-radius: var(--radius-pill);
  color: var(--ink-2);
  background: transparent;
  border: none;
  box-shadow: none;
  cursor: pointer;
}
/* 本文（`.scroll`の左余白16px）との光学整列。`.appbar`の左余白は12pxで、そこに44pxの
   タップ領域を置くとアイコンの箱は12+10=22pxから始まり、本文より6px内側で浮いて見える。
   負のマージンでアイコンの箱の左端を16pxへ寄せる（タップ領域は44pxのまま画面端まで広がり、
   端に近いほど押しやすいFittsの利点も残る）。
   **第一子のときだけ**に限定するのは、ブランドロゴ始まりのappbar（LP・機能ガイド）や
   右側に並ぶアイコンを動かさないため。 */
.appbar > .iconbtn:first-child { margin-left: -6px; }
.appbar .iconbtn:hover { background: var(--surface-2); }
.iconbtn svg { width: var(--ic-lg); height: var(--ic-lg); }
.appbar .iconbtn svg { width: var(--ic-nav); height: var(--ic-nav); }

/* アイコン容器の中の svg の大きさ。
   幅／高さ属性を持たない svg は、容器側で指定しないと 0 サイズに潰れて「空の箱」に見える。
   【第135回デザインレビュー IC-1】`.ic` には .note / .choice / .empty の
   4文脈にしか指定が無く、それ以外で `.ic` を使うと svg が 0×0 になっていた
   （組織削除の前提条件の ✓／✗ が3つとも不可視だった）。基底の `.ic svg` を先に置き、
   文脈ごとの指定は上書きとして続ける。 */
.ic svg { width: var(--ic-md); height: var(--ic-md); }
.chev svg { width: var(--ic-md); height: var(--ic-md); }
.note .ic svg { width: var(--ic-md); height: var(--ic-md); }
.choice .ic svg { width: var(--ic-lg); height: var(--ic-lg); }
.empty .ic svg { width: var(--ic-xl); height: var(--ic-xl); }
/* アイコンは flex 行の中で潰さない（ラベルが長いと縮んで縦横比が崩れる）。
   クラスを並べると取り残すので「リンク・ボタン・アイコン容器の中の svg」で取る。
   QR（.qr-img svg）は逆に縮ませたいので除く。 */
a svg, button svg, summary svg, .badge svg, .ic svg, .chev svg { flex: none; }
.qr-img svg { flex: 0 1 auto; }

/* ブランドマーク */
.brand { display: flex; align-items: center; gap: 9px; }
.brand .mark {
  width: 30px; height: 30px; border-radius: 9px;
  background: var(--brand-600);
  display: grid; place-items: center;
  color: #fff; flex: none;
}
.brand .mark svg { width: var(--ic-md); height: var(--ic-md); }
/* ローマ字ワードマーク「kurukana」＋小さな読み仮名「クルカナ」の縦積みロックアップ
   （CLAUDE.md「ロゴ／URL等は小文字のkurukana」に準拠。本文コピーは日本語のまま） */
.brand .lockup { display: flex; flex-direction: column; line-height: 1; }
.brand .word { font-family: 'Poppins', var(--font); font-weight: 700; font-size: var(--fs-lg); letter-spacing: -.01em; color: var(--ink); }
/* 先頭の「k」だけブランド色にしてロゴのアクセントにする（マークのチェックマークと同色） */
.brand .word .mk { color: var(--brand-600); }
.brand .word small { font-weight: 600; color: var(--muted); font-size: var(--fs-xs); margin-left: 2px; }
.brand .reading { font-size: 9.5px; font-weight: 700; letter-spacing: .16em; color: var(--muted); margin-top: 3px; }

/* ---------- 見出し・テキスト ---------- */
.page-title { font-size: var(--fs-xl); font-weight: 800; margin: 4px 0 2px; overflow-wrap: anywhere; }
.page-sub { color: var(--muted); font-size: var(--fs-sm); margin: 0 0 14px; }
.section-title {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em;
  color: var(--muted); text-transform: none;
  /* 【P-7・第17回デザインレビュー】水平マージンは0にして、本文・カード・注記と同じ左端
     （`main.scroll`のpadding-left＝16px）に揃える。以前は`22px 2px 8px`で、**見出しが自分の
     見出している箱より2px内側に立って**いた。2pxインセットの根拠を示すコメントはCSS・モック・
     docsのどこにも無く、147箇所がクラス既定の18px・12箇所がインラインの`margin:0`で16pxと
     割れていた（規則ではなく惰性）。`.appbar .iconbtn:first-child`の`margin-left:-6px`には
     「本文（`.scroll`の左余白16px）との光学整列」という明示のコメントがあり、**16pxに揃える
     という方針が言語化されているのはそちらだけ**だったので、それに合わせる */
  margin: 22px 0 8px;
  display: flex; align-items: center; gap: 8px;
}
.section-title:first-child { margin-top: 4px; }
.muted { color: var(--muted); }
.small { font-size: var(--fs-sm); }
.tiny  { font-size: var(--fs-xs); }
/* 【AQ-1・AQ-3・第128回ウォークスルー】単独で操作を担うテキストリンク（<p>や<span>の
   唯一の中身がリンクである導線。文中に埋め込まれた参照リンクは対象外＝WCAG 2.5.8の
   「文中」除外に該当するため据え置く）のタップ領域確保（WCAG 2.5.8 AA・24×24px以上・
   design-review.md §D）。ログイン画面が個別に持っていた
   `style="display:block;padding:6px 0"`のアドホックな繰り返しをやめ、この画面群共通の
   慣習としてクラス化する（自己点検 §5.1「クラスで直したか」）。
   .link-tap：単独行として縦に置かれるリンク（既定）。
   .link-tap-inline：「／」区切りで横に並ぶ複数リンク（組織の引き継ぎ・削除等）向けに、
   ブロック化せず高さのみ確保する */
.link-tap { display: block; padding: 6px 0; }
.link-tap-inline { display: inline-block; padding: 6px 4px; }

/* パンくず（LPから入る説明系ページ＝`/features`・`/guide/{role}`）。
   【2026-08-10・デザインレビュー】以前はここに`.link-tap`の「← ◯◯にもどる」を1行置いていた
   （docs/94 §2.4）。配置の判断は妥当だったが、**矢印がフォントの「←」文字**でアイコン体系
   （Lucide）から外れ、下線つきの素のリンクと相まって手打ちのHTMLに見えていた。
   読者は「まだ使うと決めていない検討中の人」（docs/94 §2.4）で、必要なのは「1つ前に戻る」より
   **今どこを読んでいて他に何があるか**なので、戻り先と現在地を同時に示すパンくずへ替える。
   セパレータは装飾なので`aria-hidden`。最後の項目はリンクにせず`aria-current="page"`。 */
.crumbs { margin: 0 0 12px; padding: 0; list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; font-size: var(--fs-xs); }
.crumbs li { display: flex; align-items: center; gap: 6px; }
.crumbs a { color: var(--brand-700); text-decoration: none; display: inline-block; padding: 6px 0; }
.crumbs a:hover { text-decoration: underline; }
.crumbs [aria-current="page"] { color: var(--ink-2); padding: 6px 0; }
.crumbs .sep { color: var(--muted); }
/* 日本語の折り返しを読みやすく（実装 public/css と同一方針）：本文は文節区切り
   （対応ブラウザ）＋孤立行の回避、見出しは行長を均す。末尾1文字・語中での
   見づらい改行を抑える（他ブラウザは従来どおり） */
/* 【第45回ウォークスルーDA-4】CA-8で`.row .name`/`.row .sub`にだけ入れた折り返しを、
   同じ壊れ方をする残りのテキスト要素へ横展開する。`word-break: auto-phrase`はCJKの文節
   改行用でスペースを含まない英数字トークンには効かないため、`overflow-wrap: anywhere`が要る
   （375px幅で`main.scroll`のscrollWidthが1440pxまで伸び、画面全体が横スクロールする実測あり） */
/* 【XA-1・第117回ウォークスルー】この一覧から`.row .name`が抜け落ちていた。上のDA-4のコメントは
   「CA-8で`.row .name`/`.row .sub`にだけ入れた折り返しを横展開する」と書いており、
   `.row .name`には既に入っている前提で読めるが、実際にはこの一覧から漏れ、
   下の`.row .name`には`overflow-wrap`しか無い（`word-break: auto-phrase`も`text-wrap: pretty`も無い）。
   実測：375px幅で「メールアドレスを変更する」が「…変更す」＋孤立1文字「る」に割れる。
   `.row .name`は行の主要ラベルで`resources/views`内に119箇所あり、影響は全row系リンクに及ぶ */
/* 【AH-2・第148回】組版側（line-break/word-break/text-wrap）は`body`へ移し継承で効かせた。
   ここに残すのは`overflow-wrap: anywhere`だけ——これはmin-content幅を変えるため
   （`.appbar .title`が2行に割れた第134回W4-2の原因）、全体へ掛けずに、長い連続文字列が
   はみ出す実害が確認された要素にだけ当てる */
p, li, .small, .tiny, .row .name, .row .sub, .seg .opt { overflow-wrap: anywhere; }
h1, h2, .lp-h h2, .section-title { text-wrap: balance; }
.center { text-align: center; }
.strong { font-weight: 700; }
/* 改行を含みうる自由記述（連絡事項note等）の表示用。生HTML出力（nl2br）を増やさず
   CSSのみで改行を保持する（第20回ウォークスルーAG-6）。CSVはfputcsvが改行を保持しており、
   画面表示とCSVの扱いを揃える */
.pre-wrap { white-space: pre-wrap; }
/* 【部品別デザインレビューP-5・2026-08-12】操作結果を1回だけ伝えるフラッシュメッセージ
   （@if (session(...)) 直後等の一時的な状態通知）が、専用クラスを持たず「small center muted」
   等の綴りの書き写しで99箇所・9通りに割れていた（詳細はdesign-review.md §2.3・実施結果参照）。
   font-size/color/text-align/marginをクラス側で固定し、既存の綴りをこの2クラスへ寄せる。
   marginは多数派の値を既定にし、文脈で異なる余白が要る箇所は従来どおりstyle属性で上書きする
   （上書きは崩さない・新規に増やさない）。この時点では「成功メッセージをmutedで出す」
   house styleには手を付けず、綴りの統一だけに絞った。
   【JC-10・第201回ウォークスルーで上のP-5の判断を更新】--mutedは補助テキストと同色で、
   エラー側.flash-error（赤で強い）と比べ「休む」を送った完了合図が注記と見分けがつかず、
   CLAUDE.mdが無くそうとしている「電話での二重確認」を誘発していた。.flash-errorに倣い
   （font-size/text-align/margin/太字なし・アイコンなしは揃え、色だけ切り替える設計を踏襲）、
   既存のセマンティック色--present（.badge-presentと同じ「出席予定＝良い状態」の緑）へ変える。
   .flashは33箇所のBladeで素の<p class="flash">として使われアイコン用マークアップを追加
   できないため、CSSの色だけで完了を伝える。--surface-2上で4.94:1・白上で5.21:1（AA 4.5:1）を満たす */
.flash { font-size: var(--fs-sm); text-align: center; color: var(--present); margin: 0 0 16px; }
.flash-error { font-size: var(--fs-sm); text-align: center; color: var(--absent); margin: 0 0 16px; }
/* 【部品別デザインレビューP-6・2026-08-12】18px見出し（インラインfont-size:18px）が33箇所・
   6通りに割れ、h1版とp版で行間が5.4px（25.2px対14px×1.7=30.6px）ずれていた。line-heightを
   明示して統一し、色の重複指定（color:var(--ink)、bodyの既定と同値で無効）を削る。marginは
   多数派（0 0 8px）を既定にし、カード内の名称表示等で使う異なる余白はstyle属性で上書きする */
.card-title { font-size: var(--fs-lg); font-weight: 700; line-height: 1.4; margin: 0 0 8px; }

/* ---------- カード ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 16px;
  margin-bottom: var(--gap);
}
/* 【ZCR-3是正・第334回ウォークスルー消化】`.card.pad-0`（padding:0でカードを詰めるための
   モディファイア）は追加以来、実装・モックとも使用0件だった。代わりに`.card`へ直接
   `style="padding:..."`を書く箇所が32件・8通りに分散しており、このクラス自体が誰にも
   使われていなかった（`walkthrough.md`§5.5「一覧を手で持つなら、ドリフトが安全側へ倒れる方を
   持つ」＝定義があるのに使われないクラスを残すと「これを使えばよい」という誤った手がかりに
   なるため削除する。32件のインラインを一斉にクラス化する変更は別スライスとする）。 */
/* 【ZCR-1是正・第334回ウォークスルー消化】`.card`全体を`<a>`にした「タップできるカード」
   （home.blade.php・more/index.blade.php・events/index.blade.php）に、ホバー・押下の
   フィードバックが一切定義されていなかった（`cursor:pointer`のみ）。しかも`text-decoration:none;
   color:inherit`で`<a>`既定のホバー変化も自分で消しているため、マウス操作では「押せる」ことが
   一切伝わらない状態だった。倣った先は`.role-card`（同じ「独立した枠線付きカードがまるごと
   リンク」という構造）：border-color・box-shadowの変化まで倣うと`.role-card`が担う「複数の
   選択肢から選ぶ」文脈の強調になってしまうため、単一の遷移リンクである`.card.tappable`には
   `.row.tappable`と同じ「背景色だけを変える」軽さを採用する（`design-review.md`§1-D）。 */
.card.tappable { transition: background-color .12s; }
.card.tappable:hover { background: var(--surface-2); }
.card.tappable:active { background: var(--surface-2); }
/* 【HM-3・第164回ウォークスルー】バッジの文言は動的判定（Event::acceptanceLabel()）で
   「キャンセル待ち受付中」のように長くなる。折り返しが無いと、文字を大きくして使う人
   （200%ズーム＝実効195px幅）で右端が切れて判読できなくなる（実測 overflow 81px）。 */
.card-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 10px; }
.card-head .ttl { font-weight: 700; font-size: var(--fs-base); overflow-wrap: anywhere; }
.card-head .spacer { flex: 1; }
.card + .section-title { margin-top: 22px; }

/* 日付見出し（予定カードの上帯） */
.date-badge {
  display: inline-flex; align-items: baseline; gap: 6px;
  color: var(--brand-700); font-weight: 800;
}
.date-badge .dow { overflow-wrap: anywhere; font-size: var(--fs-xs); padding: 1px 7px; border-radius: var(--radius-pill);
  background: var(--brand-50); color: var(--brand-700); font-weight: 700; }

/* ---------- ボタン ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 44px; padding: 0 18px;
  border-radius: var(--radius-sm);
  font-family: inherit; font-size: var(--fs-base); font-weight: 700;
  border: 1px solid transparent; cursor: pointer;
  transition: background .12s, border-color .12s, box-shadow .12s, opacity .12s;
  /* 修飾子を付けない`.btn`の既定。以前は前半の`button, a.btn`が供給しており、
     `.btn`自体は背景も文字色も宣言していなかった（そのためモックでは灰色で出ていた）。
     基底の対象を絞る（X-1）と失われるので、既定としてここへ移す。
     `.btn-primary`／`.btn-outline`／`.btn-ghost`／`.btn-danger`は下でこれを上書きする */
  background: var(--brand-600); color: #fff;
  text-decoration: none; white-space: nowrap;
}
.btn svg { width: var(--ic-md); height: var(--ic-md); }
/* 【SR1I-20・第1周スクショレビュー】`.btn`は`white-space: nowrap`かつ`height: 44px`固定なので、
   ラベルが幅を超えると**必ず文字が枠の外へはみ出す**（390pxの実測：緊急引き継ぎの
   「引き継ぎに異議を申し立てる（手続きを中止する）」が+4px、メール認証の
   「別のアカウントで登録し直す（最初の画面にもどる）」が+12px）。
   `.btn-block`は幅が行いっぱいに確定しているので、**折り返して縦に伸ばす**方が安全＝
   はみ出す代わりに2行になる。インラインの`.btn`は行の中で幅が決まらないため`nowrap`のまま
   （折り返すと隣の要素との関係が壊れる）。
   **`.btn`より後ろに置く**：`height: 44px`は同じ詳細度なので、前に置くと後方の宣言に負ける。
   `.btn-lg`（48px）・`.btn-sm`（32px）は`.btn-block`より前にあり、こちらの`min-height: 44px`に
   負けるため、詳細度を1つ上げて元の高さへ戻す。1行のボタンの見た目は変わらない
   （内容19px＋上下padding12px＝31px < min-height 44px）。 */
.btn-block { white-space: normal; height: auto; min-height: 44px; padding-top: 6px; padding-bottom: 6px; }
.btn-block.btn-lg { min-height: 48px; }
.btn-block.btn-sm { min-height: 32px; }
/* 押せる感を高める2層のソフトシャドウ（中立色。ghost＝透明のみ平ら） */
.btn-primary { background: var(--brand-600); color: #fff; box-shadow: 0 1px 2px rgba(24, 34, 51, .14), 0 3px 8px rgba(24, 34, 51, .12); }
.btn-primary:hover { background: var(--brand-700); box-shadow: 0 2px 4px rgba(24, 34, 51, .16), 0 6px 16px rgba(24, 34, 51, .16); }
/* 【JC-9・第201回ウォークスルー】枠線は白カード上で1.28:1（WCAG 1.4.11の3:1未達）だった。
   GM-1（第93回）で`.input`・`.choice`・`.choice .radio`へ入れた`--control-border`
   （白地3.43:1）が取り残されていたので揃える */
.btn-outline { background: var(--surface); color: var(--brand-700); border-color: var(--control-border); box-shadow: 0 1px 2px rgba(24, 34, 51, .10), 0 2px 6px rgba(24, 34, 51, .08); }
.btn-outline:hover { background: var(--brand-50); }
/* 【SR1F-2・スクショレビュー第1周】枠も面も影も無いため、白い行の上では**ただの色つき文字**に
   見えて押せると分からなかった（実測：行内の「来なかった」「取り消し」が本文と区別できない）。
   design-review.md §1-D「リンクとテキストが区別できるか・押せる感」への未達。面（`--surface`）と
   枠線（白地3.43:1の`--control-border`）を与えて輪郭を出す。影は付けない——`.btn-primary`との
   階層（主操作＝影あり／副操作＝枠のみ）は保つため、`box-shadow: none`の明示は従来どおり残す。
   **暗い運営appbarに乗る`.btn-ghost`はこの面・枠を打ち消す**（下の`.ops .appbar .btn-ghost`）。 */
.btn-ghost { background: var(--surface); color: var(--ink-2); border-color: var(--control-border); box-shadow: none; }
.btn-ghost:hover { background: var(--surface-2); box-shadow: none; }
/* 行内の小さな破壊操作（削除・取りやめ・外す・失効）。画面下部の主操作は`.btn-danger`（枠つき）で
   出すが、一覧の行に並ぶ操作にまで枠を付けると行が騒がしくなるため、枠と背景を落とした
   ゴースト版を用意する。**この見た目は従来12箇所で`style="color:var(--absent)"`と手書きされていた**
   （クラスが無いので増えるたびに書き写すしかなく、画面ごとに微妙に揺れる温床だった）。
   **`box-shadow: none`を明示するのは必須。** 直後の`.btn-danger`が影を付け直すため、
   詳細度で勝っていても**宣言していないプロパティは漏れてくる**（実際に「浮いた白いボタン」に
   見えて気づいた）。2026-08-10・部品別レビュー（2周目：ボタン） */
.btn-ghost.btn-danger { background: var(--surface); border-color: var(--danger-border); color: var(--absent); box-shadow: none; }
.btn-ghost.btn-danger:hover { background: var(--absent-bg); box-shadow: none; }
/* `<a>`版。上にある`a.btn.btn-danger`（詳細度0,2,1）は`.btn-ghost.btn-danger`（0,2,0）に
   勝つため、リンクで合成すると枠つきに化ける。**現時点の利用は全て`<button>`だが、
   「grepで確認したから大丈夫」を前提としてコードに残さない**（既存の`a.btn.btn-ghost`群と同じ流儀）。 */
a.btn.btn-ghost.btn-danger { background: var(--surface); border-color: var(--danger-border); color: var(--absent); box-shadow: none; }
a.btn.btn-ghost.btn-danger:hover { background: var(--absent-bg); box-shadow: none; }
.btn-danger { background: var(--surface); color: var(--absent); border-color: var(--danger-border); box-shadow: 0 1px 2px rgba(24, 34, 51, .10), 0 2px 6px rgba(24, 34, 51, .08); }
.btn-danger:hover { background: var(--absent-bg); }
/* LINE連携・友だち追加のブランドボタン（LINE公式アカウントの緑）。機能接点のみで使用。
   公開前にLINE公式のブランドガイドライン（色・ロゴ・呼称）を要確認。 */
.btn-line { background: #06c755; color: #fff; box-shadow: 0 1px 2px rgba(24, 34, 51, .14), 0 3px 8px rgba(24, 34, 51, .12); }
.btn-line:hover { background: #05b34c; }
.btn-block { display: flex; width: 100%; }
.btn-sm { height: 36px; padding: 0 13px; font-size: var(--fs-sm); border-radius: var(--radius-sm); }
.btn-lg { height: 50px; font-size: var(--fs-base); }
/* 【SR2G-7】面は`--surface-2`ではなく`--line`にする。本文の地が`--surface-2`なので、
   同色だと非活性のボタンが輪郭ごと地に溶けて「ボタンがある」ことが分からない
   （実測で面1.00・枠1.14）。送信中の一瞬しか出ない状態だったため潜在化していた */
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--line); color: var(--muted);
  border-color: var(--line); cursor: not-allowed; pointer-events: none; box-shadow: none;
}
.btn-row { display: flex; gap: 10px; }
.btn-row .btn { flex: 1; }

/* ---------- バッジ・チップ ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-xs); font-weight: 700; line-height: 1;
  padding: 5px 10px; border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--ink-2);
}
.badge .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.badge-present { background: var(--present-bg); color: var(--present); }
.badge-absent  { background: var(--absent-bg);  color: var(--absent); }
.badge-warn    { background: var(--warn-bg);    color: var(--warn); }
.badge-info    { background: var(--info-bg);    color: var(--info); }
.badge-muted   { background: var(--surface-2);  color: var(--muted); }

/* ---------- リスト行 ---------- */
.list { background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-sm);
  margin-bottom: var(--gap); }
.row {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 16px; border-bottom: 1px solid var(--line-2);
  text-decoration: none; color: inherit;
}
.row:last-child { border-bottom: none; }
/* 【P-8・部品別デザインレビュー】.row（フレックスコンテナ）に実チェックボックスを直接置く
   一覧行（電話対応時の候補選択・振替対象者選択等）。既定のflex-shrinkで縮まないよう固定する
   （サイズ自体は前半の`input[type="checkbox"]`既定で22pxに揃う。以前はここをインラインstyleで
   個別に複写していた）。 */
.row > input[type="checkbox"] { flex: none; }
/* 【P-8・部品別デザインレビュー】一覧の「すべて選択／解除」チェックボックス（メンバー一括削除・
   一括で元に戻す）。親labelがflexコンテナのため、既定のflex-shrinkで縮まないよう固定する
   （サイズ自体は前半の`input[type="checkbox"]`既定で22pxに揃う。以前はここをインラインstyleで
   個別に複写していた）。 */
input[type="checkbox"][data-bulk-select-all] { flex: none; }
a.row:hover, .row.tappable:hover { background: var(--surface-2); }
.row .grow { flex: 1; min-width: 0; }
/* 長い連続文字列（スペースを含まない英数字・URL等）が一覧行から無言ではみ出す問題への対処
   （第42回ウォークスルーCA-8・ヘッドレスChromiumでの実測により確認：375px幅でscrollWidth
   567px vs clientWidth 257pxの溢れ）。上記の`word-break: auto-phrase`はCJKの文節単位の
   改行用で、スペースを含まない英数字トークンには効かない（実測で不発を確認済み）。
   `word-break: break-word`ではなく`overflow-wrap: anywhere`を使う：break-wordは仕様上
   「他に改行点が無い場合のみ」という緩い扱いのため挙動がブラウザ依存になりがちだが、
   anywhereは常に最後の手段として単語内改行を許可しつつレイアウト計算（min-content幅）にも
   確実に反映される。`.list { overflow: hidden; }`（角丸のため）がページスクロールへの波及は
   防いでいたが、代わりに省略記号なしで右端を唐突に切り捨てていたため、はみ出し自体を折り返しで
   解消する */
.row .name { font-weight: 600; overflow-wrap: anywhere; }
.row .sub { font-size: var(--fs-xs); color: var(--muted); overflow-wrap: anywhere; }
.row .chev { color: var(--muted); flex: none; }
/* 名前欄が横並びの操作ボタン群に押し潰される問題への対処（第28回ウォークスルーAX-1/AX-2等・
   ヘッドレスChromiumでの実測により確認）。.rowは既定でflex-wrapを持たないため、.growの
   min-width:0と相まって、幅の狭い画面ではボタン群の分だけ.growが数pxまで縮み、日本語1文字
   ごとに折り返って行の高さが暴走する（mockups/admin-invites.html・admin-dashboard.htmlで実測：
   .grow幅が6.97px/59.97pxまで潰れ、行の高さが348px/144pxに達していた）。
   .row直下に名前(.grow)と横並びの操作ボタン群（フォーム・複数ボタン）を持つ行には
   .has-actionsを付与し、操作ボタン群には.row-actionsを付与する。
   .growに読める最小幅を確保したうえでflex-wrapを許可し、.row-actionsはflex-basisを
   auto（内容依存）のままにする。これにより：
   ・広い画面では現状どおり1行に収まる（.growがavatarと.row-actionsの残り幅を取るだけで、
     不要な折り返しは起きない＝既存の見た目を変えない）
   ・収まらない幅でだけ.row-actionsが名前の下の新しい行へ丸ごと折り返す
   （mockups/admin-members.htmlの「操作ボタンを名前の下に置く」既存の正解パターンと
   同じ見え方を、DOM構造を変えずCSSだけで再現する）
   .row-actionsは幅（flex-basis）だけを制御する。ボタンが複数ある行は既存の.flexクラスを
   併用して横並びにする（例：class="flex row-actions"）。1個だけの行（<form>単体等）に
   直接付ける場合は内部のdisplayを変えない（displayを上書きするとlabel+button等の
   既存の縦積みレイアウトまで崩れてしまうため）。 */
.row.has-actions { flex-wrap: wrap; row-gap: 6px; }
.row.has-actions .grow { min-width: 150px; }
.row.has-actions > .row-actions { flex: 0 1 auto; }
/* 【ZCJ-2・docs/18_issues.md・2026-09-06】一覧行のボタン間隔は`class="flex row-actions"
   style="gap:6px;..."`のようにインラインで指定しており（`.row-actions`自体はflex-basisしか
   持たないため）、実測で17ファイル35箇所に`gap:6px`が使われている（うち`.row-actions`＝
   ボタン行は5箇所）。Material Designの推奨（8dp）をやや下回るが、誤タップの報告は無く、
   横断で変える利益が薄いため値は据え置く（`self-review.md`のタップ領域24px以上は
   `.btn`の`height:44px`・`.btn-sm`の`height:36px`〈1331行・第1ブロックの`min-height:32px`より
   後にあるため後勝ちで効く〉で満たしている）。`admin/events/index.blade.php`・`organizations/events/index.blade.php`
   の2箇所だけ`gap:8px`になっており揃っていないが、これも同じ理由で今回は追随しない
   （次にこの領域へ触るときに8pxへ揃えるか、この6pxへ合わせるかを決める）。 */
/* アバターの色（2026-08-13・暗黙のまま運用されていたので現状を書き出す）。
   **規範ではなく実測**：82箇所を数えた結果、次の2つが支配的な書き方だった。
     ・アイコン（svg）を入れる  → `background: var(--brand-50); color: var(--brand-600)`（38件）
     ・頭文字（文字）を入れる    → この既定のまま（13件）
   文字のほうが濃いのは理にかなっている（brand-700はbrand-50に対し6.84:1、brand-600は4.98:1。
   どちらもAAは満たすが、読ませる文字に濃いほうを当てている）。
   状態を表すときは badge と同じトークン対（warn / absent / present / muted）を使う（24件）。
   ほかに、塗りつぶし（`background: var(--brand-600); color: #fff`・白文字で5.51:1）が管理者と
   グループの強調に2件、`surface-2 / ink-2`の中立が1件ある。**少数の例外は残っている**ので、
   「全部がこの規則に従っている」とは読まないこと。迷ったら多数派の2つに寄せる */
.avatar {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-weight: 700; font-size: var(--fs-base);
  background: var(--brand-50); color: var(--brand-700);
}
.avatar.sq { border-radius: 11px; }
.avatar svg { width: var(--ic-md); height: var(--ic-md); }
/* リスト・カード内の名前/補足は縦に積む */
.grow > .name, .grow > .sub { display: block; }

/* ---------- ログフィード（横スクロール表の代替・1件1ブロック縦積み） ----------
   【SR1H-10・第1周スクショレビュー】組織の操作ログ（organizations/audit-logs/index.blade.php）
   専用。`.tbl`の列を横に並べる表現は、列数が多い割に表示幅が狭い端末（390px）では
   実測で内容幅が表示幅の2倍を超え、目的の列（この画面なら「操作」「対象」）が初期表示から
   完全に外へ出た。`.list`＋`.row`（上のリスト行）は1行1エントリを前提に横並び（flex）で
   組んでいるが、ここでは1エントリの中身自体を「操作（主）→対象→実行者・日時」の3段に
   縦積みしたいため、`.row`は使わず専用クラスを起こす。枠・区切り線・背景は`.list`をそのまま
   借りる（二重定義しない）。今のところこの画面専用で、運営コンソール側の7表（`docs/18_issues.md`
   へ申し送り済み）には適用しない。 */
.log-feed-item { padding: 13px 16px; border-bottom: 1px solid var(--line-2); }
.log-feed-item:last-child { border-bottom: none; }
.log-feed-action { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.log-feed-target { margin: 3px 0 0; font-size: var(--fs-sm); color: var(--ink-2); overflow-wrap: anywhere; }
.log-feed-meta { margin: 4px 0 0; font-size: var(--fs-xs); color: var(--muted); overflow-wrap: anywhere; }

/* ---------- 出欠サマリー（管理者ダッシュボード） ---------- */
.stat-row { display: flex; gap: 10px; margin-bottom: var(--gap); }
.stat {
  flex: 1; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 14px 12px; text-align: center;
  box-shadow: var(--shadow-sm);
}
.stat .num { font-size: var(--fs-2xl); font-weight: 800; line-height: 1.1; letter-spacing: .02em; }
.stat .lbl { font-size: var(--fs-xs); color: var(--muted); margin-top: 3px; }
.stat.is-absent .num { color: var(--absent); }
.stat.is-present .num { color: var(--present); }

/* ---------- フォーム ---------- */
.field { margin-bottom: 16px; }
.label { display: block; font-weight: 700; font-size: var(--fs-sm); margin-bottom: 6px; }
.label .req { color: var(--absent); font-size: var(--fs-xs); margin-left: 4px; }
.hint { font-size: var(--fs-xs); color: var(--muted); margin-top: 6px; }
/* 入力エラーの1行。役割にクラスが無く、`class="hint" style="color:var(--absent);"`という
   インラインの写しが141箇所へ複製されていた（X-4）。同型の事故（フラッシュ84箇所のうち1つが
   クラスを落として素の<p>になっていた）が既に起きているため、役割をクラスにする。
   見た目は`.hint`と同一で色だけが違う（余白まで同じにして置換で描画が変わらないようにした）。 */
.field-error { font-size: var(--fs-xs); color: var(--absent); margin-top: 6px; }
.input, .select, textarea.input {
  /* max-widthはモック側（mockups/assets/app.css）が持っているのにこちらだけ落ちていた。
     そのため上の要素セレクタの列挙に無い型（datetime-local）だけが上限なしで伸び、
     同じフォーム内で420pxの欄と448pxの欄が縦に並んでいた（P-2） */
  width: 100%; max-width: 420px; height: 46px; padding: 0 13px;
  /* 16px未満だとiOS Safariがフォーカス時に自動ズームしてしまうため16pxを下限にする */
  font-family: inherit; font-size: var(--fs-base); color: var(--ink);
  background: var(--surface); border: 1px solid var(--control-border); border-radius: var(--radius-sm);
  transition: border-color .12s, box-shadow .12s;
}
textarea.input { height: auto; padding: 11px 13px; resize: vertical; min-height: 84px; }
/* 素の input/select/textarea と同じ理由で `outline:none` と不可視のハローをやめた
   （冒頭の共通 :focus-visible がリングを担う・第134回デザインレビュー） */
.input:focus, .select:focus, textarea.input:focus {
  border-color: var(--brand-500);
}
.select { appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' stroke='%23646f86' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: right 12px center; padding-right: 38px; }
/* 【JC-11・第201回ウォークスルー】折り返しを許可する。195px幅（375px端末の200%拡大）では
   開始日・終了日の2つの.fieldが並んだまま横に押しつぶされ、日付の文字が入るスペースが
   約50pxしか残らなかった（WCAG 1.4.10）。子の.fieldはinlineでflex:1／固定widthを持つため、
   折り返しても縦積みで読める幅を確保できる */
.input-group { display: flex; gap: 10px; flex-wrap: wrap; }
.input-group .input { flex: 1; }

/* トグルスイッチ */
.switch-row {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 0; border-bottom: 1px solid var(--line-2);
}
.switch-row:last-child { border-bottom: none; }
/* 【JC-4・第201回ウォークスルー】.row .grow / .choice .grow と同じ「.grow」でも
   min-width:0が無く取り残されていた（同じ原因を共有する兄弟）。長い設定名・グループ名で
   .switchが押し出される */
.switch-row .grow { flex: 1; min-width: 0; }
.switch-row .t { font-weight: 600; }
.switch-row .d { font-size: var(--fs-xs); color: var(--muted); margin-top: 2px; }
/* .t（タイトル）と.d（説明）がinline要素のまま連結描画されるのを防ぎ、確実に改行させる */
.switch-row .t, .switch-row .d { display: block; }
/* 【P-8・部品別デザインレビュー】.switch-rowは本来トグル用（実チェックボックスは.switch-input
   sr-onlyで隠し、見た目は下の.switchが担う）。イベント対象選択（メンバー・グループ）では
   .switch-rowのレイアウトだけを流用し、実際に見えるチェックボックスを置く用途があるため、
   .switch-input（隠しトグル）は除外して既定のflex-shrinkで縮まないよう固定する（サイズ自体は
   前半の`input[type="checkbox"]`既定で22pxに揃う。以前はここをインラインstyleで個別に複写していた）。 */
.switch-row input[type="checkbox"]:not(.switch-input) { flex: none; }
.switch {
  position: relative; width: 48px; height: 28px; flex: none;
  /* OFF時のトラックも「状態を伝えるUI部品」のため3:1を満たす色にする（GM-1） */
  background: var(--control-border); border-radius: var(--radius-pill);
  cursor: pointer; transition: background .15s;
}
.switch::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 22px; height: 22px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.2); transition: transform .15s;
}
.switch.on { background: var(--brand-600); }
.switch.on::after { transform: translateX(20px); }

/* 実フォームのcheckbox（.switch-input・.sr-onlyで視覚的に隠す）で.switchの見た目を駆動する
   （ステップ15d）。モックの.switchはJSでクリックをトグルする純粋な装飾spanだが、実装では
   ネイティブ<input type="checkbox">をlabel（.switch-row）で包み、キーボード操作・
   スクリーンリーダーに対応したまま同じ見た目を再現する（JS不要）。 */
.switch-input:checked ~ .switch { background: var(--brand-600); }
.switch-input:checked ~ .switch::after { transform: translateX(20px); }
.switch-input:focus-visible ~ .switch { outline: 2px solid var(--brand-600); outline-offset: 2px; }

/* セグメント（ラジオ的な選択） */
.seg { display: flex; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 3px; gap: 3px; }
.seg button, .seg .opt {
  /* ラベルが折り返してもクリップされないよう固定heightではなくmin-heightにし、
     縦paddingと余裕あるline-heightで2行になっても収まるようにする */
  flex: 1; min-height: 38px; padding: 4px 6px; border: none; background: transparent; box-shadow: none;
  border-radius: var(--radius-xs); font-family: inherit; font-size: var(--fs-md); font-weight: 700; line-height: 1.3;
  color: var(--ink-2); cursor: pointer; text-align: center; text-decoration: none;
}
/* リンクとして使う.opt（サーバ側の状態フィルタ等）もボタンと同じ中央寄せ・下線なしにする */
.seg a.opt { display: flex; align-items: center; justify-content: center; }
.seg .opt.on { background: var(--surface); color: var(--brand-700); box-shadow: var(--shadow-sm); }
/* 実フォームのradio（.seg .optをlabelにしsr-onlyのinputを内包）で.seg .opt.onと同じ見た目を
   駆動する（ステップ15e・.choiceと同じ:has()の考え方）。通知種別（メール／LINE）等の
   セグメント風ラジオ選択に使う */
.seg label.opt { display: flex; align-items: center; justify-content: center; }
.seg .opt:has(input:checked) { background: var(--surface); color: var(--brand-700); box-shadow: var(--shadow-sm); }

/* 選択カード（用途プリセット等） */
/* 選択肢カードは「枠線で選択状態を示す」部品なので、素の button の押せる感の影は打ち消す
   （モックは枠線のみ。実装だけ 0 1px 2px/0 3px 8px の2層シャドウが乗っていた・DS-2） */
.choice { display: flex; align-items: center; gap: 13px; width: 100%; min-height: 0;
  /* 素の button は font-weight:700 / white-space:nowrap を持つ。`<button class="choice">`
     だけ説明（.d）が太字・折り返し不可になり、`<label class="choice">` の30箇所と
     見た目が食い違っていた（DS-2）。見出し（.t）はクラス側で700を指定している */
  font-weight: 400; white-space: normal;
  text-align: left; padding: 15px; margin-bottom: 10px; cursor: pointer;
  background: var(--surface); border: 1.5px solid var(--control-border); border-radius: var(--radius);
  box-shadow: none; color: inherit; font-family: inherit; }
/* 【SR2A-17b・第2周スクショレビューA-18】hoverで`--brand-100`(#d7e4fb)へ変えていたが、
   これは面（白）に対して**1.28:1**で、既定の`--control-border`(#828b9c・3.43:1)より
   **薄い**。つまりカーソルを載せると操作できる部品の境界がほぼ消えていた
   （WCAG 1.4.11は「UIコンポーネントの境界」に3:1を求め、状態ごとに満たす必要がある。
   GR-2でラジオの輪郭を直したときと同じ型の取り残し）。
   色は**ブランド色ではなく中立の濃色`--ink-2`(#445064・白地に8.15:1)**を使う：
   `--brand-500`にすると選択済み（`:has(.choice-input:checked)`）と同じ枠線色になり、
   見比べている間**選択済みと今カーソルがあるカードの2枚が同じ枠**になる。区別は背景
   `--brand-50`と白の1.06:1とラジオの塗りだけに痩せるので、**この修正で消したかった
   「どれを選ぼうとしているのか分からない」を hover 側へ持ち込むことになる**。
   「ブランド色＝選択」を守り、hoverは既定の枠線を濃くするだけに留める */
.choice:hover { border-color: var(--ink-2); }
.choice.on { border-color: var(--brand-500); background: var(--brand-50); }
.choice .ic { width: 42px; height: 42px; border-radius: 11px; flex: none;
  display: grid; place-items: center; background: var(--brand-50); color: var(--brand-600); }
.choice.on .ic { background: var(--brand-100); }
/* 宿主が <button> か <label> かでフォントの継承元が変わり、実装14px・モック13.33pxに
   割れていた。継承に頼らず明示する（DS-4・第136回） */
.choice .t { font-weight: 700; font-size: var(--fs-md); }
.choice .d { font-size: var(--fs-xs); color: var(--muted); }
/* .t（タイトル）と.d（説明）がinline要素のまま連結描画されるのを防ぎ、確実に改行させる */
.choice .t, .choice .d { display: block; }
/* 長い文字列（メンバー選択の所属「◯◯・◯◯ ほかn件」等）でレイアウトが横に破綻するのを防ぐ。
   flexアイテムの既定は min-width:auto で内容幅より縮まないため、min-width:0 を明示しないと
   アバターが押し出され、テキストがカード外へはみ出す（.row .grow には既に指定済み）。
   所属は1行に収める方針のため、収まらない場合は末尾を省略記号にする */
.choice .grow { flex: 1; min-width: 0; }
/* 【第134回デザインレビューW3-3】タイトル（.t）は短いラベルなので1行に収めて
   カードの高さを揃える。説明（.d）は**読ませる文**なので折り返す。
   もとは両方を1行に丸めていたが、初期設定のプリセット選択で
   「振替（休んだ回を別日で埋め合わせら…」のように、用語を初見の人へ説明するための
   定義そのものが切れていた（説明のために書いた文が説明を果たせない状態）。
   メンバー選択の所属（.d）が2行になる分には破綻しない（`.grow`に min-width:0 済み）。 */
.choice .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.choice .d { overflow-wrap: anywhere; }
/* 【GR-2・第96回ウォークスルー】未選択のラジオの輪郭は「操作できるUI部品の境界」そのもの
   （WCAG 1.4.11の典型例）。GM-1で`.choice`の外枠は`--control-border`へ直したのに、
   その中のラジオだけ`--line`（1.21:1）のまま残っていた＝枠線色の全出現を列挙せずに
   「選択カードを直した」と宣言した結果の取り残し。
   なお同じ`--line`でも次は対象外と判定した：`button:disabled`/`.btn:disabled`（WCAG 1.4.11は
   無効な部品を明示的に除外）、`.stat`・`.mini-qr`（表示専用で操作しない）、
   `.seg`の外枠・`.pill-tabs a`（選択状態は内側の背景色・テキストが担い、外枠は装飾） */
.choice .radio { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--control-border);
  flex: none; margin-left: auto; display: grid; place-items: center; }
.choice.on .radio { border-color: var(--brand-600); }
.choice.on .radio::after { content: ""; width: 11px; height: 11px; border-radius: 50%; background: var(--brand-600); }

/* 実フォームのradio（.choice-input・.sr-onlyで視覚的に隠す）で.choiceの見た目を駆動する
   （ステップ15e）。.switch-inputと同じプログレッシブ・エンハンスメントの考え方だが、.choiceは
   input自身が.choiceの子（兄弟ではなく祖先方向）にあるstyle対象（.ic/.radio）を持つため、
   隣接兄弟結合子（~）ではなく:has()を使う（main label:has(input...)で既に使用実績あり） */
.choice:has(.choice-input:checked) { border-color: var(--brand-500); background: var(--brand-50); }
.choice:has(.choice-input:checked) .ic { background: var(--brand-100); }
.choice:has(.choice-input:checked) .radio { border-color: var(--brand-600); }
.choice:has(.choice-input:checked) .radio::after { content: ""; width: 11px; height: 11px; border-radius: 50%; background: var(--brand-600); }
/* 【SR2A-17b・第2周スクショレビューA-18】キーボードのフォーカス位置。以前は右端の
   ラジオ（22px）だけに輪郭を出していたが、**実際に押せるのはカード全体**（`<label
   class="choice">`）で、幅390pxの画面ではラベル文字から300px以上離れた小さな丸が光る
   だけだった。押せる範囲とフォーカス表示が食い違うと、どれを選ぼうとしているのかが
   分からない。カード全体を囲う。
   `:has()`非対応ブラウザでは`.choice`側が効かないため、従来のラジオへの輪郭を
   フォールバックとして残す（両方効く環境で二重にならないよう、カード側が効くときは
   ラジオ側を打ち消す） */
.choice-input:focus-visible ~ .radio { outline: 2px solid var(--brand-600); outline-offset: 2px; }
.choice:has(.choice-input:focus-visible) { outline: 2px solid var(--brand-600); outline-offset: 2px; }
.choice:has(.choice-input:focus-visible) .choice-input:focus-visible ~ .radio { outline: none; }

/* 【SR1I-12b・第2周スクショレビュー カテゴリI（繰り越し）】.choiceに依存する入力欄（例：
   「期限を決めて付与する」を選んだときだけ使う終了日）は、それが属する.choiceの直後に置き
   `.choice-detail`クラスを付ける。以前は「期限を決めて付与する」と「無期限で付与する」の
   間に終了日欄が浮いており、選ばれていない側でも常時入力できてしまっていた
   （CLAUDE.md 8「条件表示：使わない機能のUIはそもそも出さない」）。
   バリデーションエラー（`aria-invalid="true"`または`.field-error`）があるときは、
   選ばれていない側でも隠さない——隠れたままエラーが出ると直せない場所にエラーが出る
   沈黙の失敗になるため。:has()非対応ブラウザは常時表示にデグレードするが、選ばれていない側の
   値はController側が無視するため送信結果は変わらない
   （GrantCompAccessRequest::rules()のrequired_if・OrganizationCompAccessController::store()の
   duration_type分岐、ApplyBillingDiscountRequest::prepareForValidation()のmonths_mode分岐）。 */
.choice:not(:has(.choice-input:checked)) + .choice-detail:not(:has([aria-invalid="true"], .field-error)) {
  display: none;
}

/* ---------- タブ（管理者 上部固定タブ） ---------- */
.tabs {
  display: flex; background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 54px; z-index: 15;
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs a {
  flex: 1 0 auto; text-align: center; padding: 12px 16px;
  font-size: var(--fs-sm); font-weight: 700; color: var(--muted);
  text-decoration: none; border-bottom: 2.5px solid transparent; white-space: nowrap;
}
.tabs a.on { color: var(--brand-700); border-bottom-color: var(--brand-600); }

/* サブ導線（予定タブ内など） */
.subnav { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.subnav a { text-decoration: none; }
/* 【ZCR-1是正・第334回ウォークスルー消化】`.subnav`（admin/schedules/index.blade.php「予定」
   タブ内の振替・お休み・イベントへの導線）は`<a>`が`.badge`をそのまま包むだけで、`<a>`自身は
   背景を持たないため`.card.tappable`と同型（ホバー・押下のフィードバック無し）。バッジ自身の
   背景トークンから1段濃い色へ変える（`.btn-outline:hover`が`--surface`→`--brand-50`、
   `a.row:hover`が`--surface`→`--surface-2`と1段変えるのと同じ考え方）。 */
.subnav a:hover .badge-info { background: var(--brand-100); }
.subnav a:hover .badge-muted { background: var(--line); }

/* ---------- 下部タブバー（ユーザー） ---------- */
/* 【HV-1・第173回ウォークスルー】`position: absolute`＋`bottom: 0`は、基準となる`.app`が
   `min-height: 100vh`しか持たない（＝内容が長ければ`.app`ごと伸びる）ため、**1画面に収まらない
   ページでは画面下端ではなく文書の末尾に置かれる**。実測：`home.html`（390×760）で文書高1746px・
   タブバーのtopが1672pxとなり、開いた時点では完全に画面外にあった。下部タブバーは常時見えて
   いなければ主要導線として機能しない（Material Designの下部ナビ・design-review §1-H）。
   これは第134回デザインレビューW3-1（`.tabs`のstickyが`.scroll`の非スクロールにより効かず
   画面外へ流れていた）と**同じ原因の兄弟**で、そのとき`.tabs`だけが手当てされていた。
   ビューポート基準の`fixed`に変え、`.app`と同じ幅（max-width 480px）で中央に置く
   （`left/right: 0`のままだと広い画面でアプリ幅を超えて広がるため）。
   下端に隠れる分は既存の`.app.has-tabbar .scroll { padding-bottom: 84px }`が確保済み。 */
.tabbar {
  position: fixed; bottom: 0; z-index: 20;
  left: 50%; transform: translateX(-50%);
  width: 100%; max-width: 480px;
  display: flex; background: var(--surface);
  border-top: 1px solid var(--line);
  padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
}
.tabbar a {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 5px 0; text-decoration: none; color: var(--muted);
  font-size: var(--fs-xs); font-weight: 700; position: relative;
}
.tabbar a svg { width: var(--ic-lg); height: var(--ic-lg); }
/* 現在地は色だけに頼らない（WCAG 1.4.1）：ラベルの太さ（他タブも700のためさらに強い800へ）と、
   タブ上端の小さなインジケータ（絶対配置のため文書内の高さには影響しない）を併用する。
   .tabbar a は既にposition:relativeを持つため追加不要 */
.tabbar a.on { color: var(--brand-600); font-weight: 800; }
.tabbar a.on::before {
  content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 24px; height: 2.5px; border-radius: 2px; background: currentColor;
}

/* ---------- 通知・お知らせ帯 ---------- */
.note {
  display: flex; gap: 10px; padding: 12px 14px; border-radius: var(--radius);
  background: var(--info-bg); color: var(--brand-700);
  font-size: var(--fs-sm); margin-bottom: var(--gap); border: 1px solid var(--brand-100);
}
.note.warn { background: var(--warn-bg); color: #8a5a10; border-color: #f0dcae; }
.note.plain { background: var(--surface-2); color: var(--ink-2); border-color: var(--line); }
.note .ic { flex: none; margin-top: 1px; }
/* 既定はインライン（文中の強調を改行させない）。注記の先頭に置く要約だけ note-lead を付けて改行させる（SR1G-3） */
.note strong.note-lead { display: block; }

/* メーター（LINE枠・無料枠） */
.meter { height: 10px; border-radius: var(--radius-pill); background: var(--line-2);
  overflow: hidden; margin: 8px 0 6px; }
.meter > i { display: block; height: 100%; border-radius: inherit; background: var(--brand-600); }
.meter.warn > i { background: var(--warn); }

/* ---------- テーブル（管理・名簿・運営） ---------- */
/* 【SR1I-21是正】背景色は`background-color`のlonghandで持たせる（`background:`shorthandで
   持たせると、下の「横スクロールできることの手がかり」がbackground-imageを足すときに
   省略した副プロパティが既定値へ戻り、この色が消えるため）。 */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius);
  background-color: var(--surface); box-shadow: var(--shadow-sm); margin-bottom: var(--gap); }
/* 【DS-1・第136回】`.tbl` は `.table-wrap`（枠・影・横スクロール）の中に置く前提の表。
   素マークアップ向けの `main table`（Markdown由来の表を横スクロールさせるため
   `display:block` にしている）がここにも当たると、`display:block` で `width:100%` が効かず
   **見出し行の背景が内容幅で切れ、列が潰れ、`.table-wrap` の横スクロールも働かなくなる**
   （実測：モックは 593px で横スクロール、実装は 341px に潰れて scrollWidth 339px）。
   枠・影・余白は `.table-wrap` が持つので、ここで素マークアップ向けの既定を打ち消す。 */
table.tbl {
  display: table;
  width: 100%; border-collapse: collapse; font-size: var(--fs-sm); min-width: 100%;
  background: transparent; border: none; border-radius: 0; box-shadow: none; margin-bottom: 0;
  overflow: visible;
}
table.tbl th, table.tbl td { padding: 11px 12px; text-align: left; border-bottom: 1px solid var(--line-2); white-space: nowrap; }
table.tbl th { background: var(--surface-2); color: var(--muted); font-weight: 700; font-size: var(--fs-xs); }
table.tbl tr:last-child td { border-bottom: none; }

/* ---------- ステップ（ウィザード） ---------- */
.stepbar { display: flex; align-items: center; gap: 6px; margin-bottom: 20px; }
.stepbar .s { flex: 1; height: 5px; border-radius: 3px; background: var(--line); }
.stepbar .s.done, .stepbar .s.cur { background: var(--brand-600); }
.step-label { font-size: var(--fs-xs); color: var(--muted); font-weight: 700; margin-bottom: 4px; }

/* ---------- ダイアログ（確認） ---------- */
.dim { position: absolute; inset: 0; background: rgba(24,34,51,.4); z-index: 40;
  display: flex; align-items: flex-end; }
.sheet { background: var(--surface); width: 100%; border-radius: 18px 18px 0 0;
  padding: 20px 18px calc(20px + env(safe-area-inset-bottom)); box-shadow: var(--shadow); }
.sheet .grip { width: 38px; height: 4px; border-radius: 3px; background: var(--line);
  margin: -6px auto 14px; }
.sheet h3 { margin: 0 0 6px; font-size: var(--fs-lg); }

/* ---------- 汎用ユーティリティ ---------- */
.stack > * + * { margin-top: 10px; }
.divider { height: 1px; background: var(--line); margin: 16px 0; }
.spacer-sm { height: 8px; }
.spacer { height: 16px; }
.spacer-lg { height: 28px; }
.flex { display: flex; align-items: center; gap: 10px; }
/* 【JC-4・第201回ウォークスルー】flexアイテムの既定min-width:autoのため、min-width:0が
   無いと内容幅より縮まず、はみ出してページが横スクロールする（.row .grow・.choice .grow
   には既に指定済み。1527行のコメントと同じ理由）。195px幅（375px端末の200%拡大）で
   SPAN.chevが枠外へ押し出される実測があった */
.flex .grow { flex: 1; min-width: 0; }
.wrap { flex-wrap: wrap; }
.right { margin-left: auto; }
/* 【第271回ウォークスルーZG-2/ZG-3/ZG-4】運営コンソールの「内訳（状態・種類ごとの件数）」の
   各行を、その値で明細を絞り込むリンクにする共通の見た目。数字が並ぶだけの.flex行は押せそうに
   見えないため、リンク化とあわせてホバー・現在の絞り込み中（aria-current="page"）の状態を示す。
   .seg .opt.onと同じ「背景の塗り＋太字」で示し、色だけに頼らない（WCAG 1.4.1）。 */
a.count-link { display: flex; color: inherit; text-decoration: none; border-radius: 6px;
  margin: 0 -6px; padding: 3px 6px; }
a.count-link:hover { background: var(--surface-2); }
a.count-link[aria-current="page"] { background: var(--brand-50); }
a.count-link[aria-current="page"] .grow { color: var(--brand-700); font-weight: 700; }
/* `.grow`のflex:1は`.row`・`.flex`等の親クラスに紐付いて定義されているため、`a.count-link`の
   中では効かず、種類名と件数が詰まって「◯◯◯9件」と読めてしまう（第341回デザインレビュー）。
   この行の役割は「左に名前・右に件数」なので、ここでも同じ`flex:1`を与える。 */
a.count-link .grow { flex: 1; min-width: 0; }
/* 【SR1I-18の独立レビュー】`a.count-link`は`color: inherit; text-decoration: none;`で、
   非ホバー・非aria-current時はプレーンな行と**見た目が完全に同一**だった。届かなかったお知らせに
   「押せない行」（いつ起きたか・届いていない宛先）を同じ`.card`の書式で足したことで、
   押せる行と押せない行が同一の見た目で並び、ホバーの無いタッチでは判別できなくなった
   （design-review §1-D「リンクとテキストが区別できるか」）。`.row`が既に使っている`.chev`で
   「押せる」を示す（新しい表現を発明せず既存の流儀に合わせる）。振替枠の台帳・イベントの台帳の
   同クラスにも同時に効く——3画面とも同じ問題を持っていた */
a.count-link .chev { color: var(--muted); flex: none; display: flex; align-items: center; margin-left: 6px; }
/* margin-bottomは、前半の`main nav.pill-tabs`（0,1,2）が詳細度で勝つため、ここに14pxと
   書いても実際には16pxで描画されていた（モック側も16px）。宣言が嘘にならないよう16pxへ揃える */
.pill-tabs { display: flex; gap: 8px; margin-bottom: 16px; overflow-x: auto; scrollbar-width: none; }
.pill-tabs::-webkit-scrollbar { display: none; }
/* 【JC-13・第201回ウォークスルー】position: relativeが無いと、内部の.sr-only（position:
   absolute）の containing block が最も近い position 祖先（.app）まで飛び、white-space:nowrapで
   計算される「切り詰め前の仮想行幅」の位置へ配置されて.appごとページを右へはみ出させる
   （195px幅で実測：はみ出し110px＝.sr-onlyの静的位置とほぼ一致）。overflow:hiddenは
   このリンク自身が position の基準になっていないと.sr-onlyを閉じ込められないため、
   position: relativeでこの<a>自身をcontaining blockにする（見た目・タップ領域への影響なし）。 */
.pill-tabs a { position: relative; flex: none; max-width: 62%; text-decoration: none; padding: 7px 14px; border-radius: var(--radius-pill);
  font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); background: var(--surface); border: 1px solid var(--line);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pill-tabs a.on { background: var(--brand-600); color: #fff; border-color: var(--brand-600); }

/* カードの中に置く<details>は、カードの見た目（枠・影・余白）を重ねない。
   `main details`は単体で置かれる折りたたみをカード化するためのものだが、
   `.card`の中で使うと二重の箱になる（予定一覧の各行に「休む連絡をする」を畳んだ
   W2-1の対応で、全行に二重枠が並ぶことになったため用意した）。 */
.card > details, details.plain {
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
  margin-bottom: 0;
}

/* ---------- 横スクロールできることの手がかり（JSなし） ----------
   `overflow-x:auto`の領域は、スクロールできること自体が伝わらないと「文字が画面端で
   切れている＝レイアウト崩れ」に見える。特に特商法・プライバシーポリシーの表は法定表示なので
   読み飛ばされると困る（W1-4・第134回デザインレビュー）。
   `background-attachment`の local と scroll を組み合わせ、**まだ続きがある側にだけ**影を出す
   CSSのみの手法（新しいJS基盤は増やさない・design.md）。
   【SR1I-21是正】`.table-wrap`（運営コンソールに限らず管理画面全体の表を囲む箱）も
   `overflow-x: auto`だが、この手がかりが無かった。`.scroll-x-hint`クラスを画面ごとに
   手で併記させず、`.table-wrap`自体に同じ手がかりを取り込む一般形にする
   （`background-image`のlonghandで足すため、`.table-wrap`の`background-color`を
   shorthandで消さない）。既存の`.scroll-x-hint`クラス自体は印刷用の`.roster-scroll`が
   引き続き使うので残す。 */
.table-wrap, .scroll-x-hint {
  background-image:
    linear-gradient(to right, var(--surface) 30%, rgba(255, 255, 255, 0)),
    linear-gradient(to left, var(--surface) 30%, rgba(255, 255, 255, 0)),
    radial-gradient(farthest-side at 0 50%, rgba(24, 34, 51, .16), rgba(24, 34, 51, 0)),
    radial-gradient(farthest-side at 100% 50%, rgba(24, 34, 51, .16), rgba(24, 34, 51, 0));
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 30px 100%, 30px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}
/* 紙には影を出さない（画面専用の手がかり） */
@media print {
  .table-wrap, .scroll-x-hint { background-image: none; }
}

/* フッター（公開ページ） */
.footer { padding: 24px 16px 34px; text-align: center; color: var(--muted); font-size: var(--fs-xs); }
.footer a { display: inline-block; padding: 6px 0; color: var(--muted); text-decoration: none; margin: 0 8px; }

/* 同意・オプトインのチェック行。法的同意を情報バナー（.note）の見た目に紛れさせず、
   通常のフォーム部品として見せる（チェックボックスは22pxでタップしやすく・label全体が可動域） */
.check-row { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px;
  margin-bottom: var(--gap); background: var(--surface); border: 1px solid var(--control-border);
  border-radius: var(--radius); cursor: pointer; }
/* 【P-8・部品別デザインレビュー】登録方法の選択（メール／ログインID）のように、.check-rowを
   ラジオボタンで使う画面がある。従来はcheckboxしか対象にしておらず、radioは同じ22pxに揃えるため
   インラインstyleで宣言を手で複写していた（auth/register.blade.php）。セレクタにradioも加えて
   クラス側へ吸収する。 */
.check-row input[type="checkbox"], .check-row input[type="radio"] { width: 22px; height: 22px; margin: 0; flex: none;
  accent-color: var(--brand-600); }
.check-row .txt { font-size: var(--fs-sm); line-height: 1.6; }

/* 空状態 */
.empty { text-align: center; padding: 40px 20px; color: var(--muted); }
.empty .ic { width: 60px; height: 60px; border-radius: 50%; margin: 0 auto 14px;
  display: grid; place-items: center; background: var(--surface-2); }

/* 折りたたみトリガー（<summary>）を .btn.btn-ghost.btn-block 風のボタンに見せる（ステップ15d）。
   モックの data-collapse ボタン（詳細設定・出欠まとめの通知タイミング等）はJS依存のため、
   実装ではJS基盤を増やさずネイティブ<details>/<summary>で同じ折りたたみを実現する
   （design.md「JS基盤が要るUIは新設せず通常表示に展開」）。既定のディスクロージャー三角は消し、
   開閉状態に応じてシェブロンをCSSのみで回転させる（JS不要）。 */
.summary-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; padding: 14px 6px; margin: 6px 0 0;
  background: transparent; border: none; border-radius: var(--radius-sm);
  font-family: inherit; font-size: var(--fs-md); font-weight: 700; color: var(--ink);
  cursor: pointer; list-style: none;
}
.summary-btn::-webkit-details-marker { display: none; }
.summary-btn:hover { background: var(--surface-2); }
.summary-btn .chev { transition: transform .15s; transform: rotate(90deg); }
details[open] > .summary-btn .chev { transform: rotate(-90deg); }
/* <summary>に.btn系クラスをそのまま重ねて使う場合（例：.btn.btn-primary.btn-block）の
   ディスクロージャー三角の抑制（上のsummary-btnと同じ理由） */
summary.btn { list-style: none; }

/* 【ZCR-1是正・第334回ウォークスルー消化】admin/schedules/_rule-row.blade.phpの「参加する人を
   編集」リンクは、`.summary-btn`と同じ箱の見た目（全幅・両端揃え・シェブロン）に揃えるコメントが
   付きながら、実体はインラインstyleで背景・枠線を都度書いていた（唯一の使用箇所）。
   `.summary-btn`は<details>の開閉トリガー用（背景透明・枠なし）でそのまま流用できないため
   （このリンクは折りたたみではなく別画面への遷移で、枠付きの箱にして区別している）、
   独立クラスとして定義する。インラインstyleのままだと`background`が常に効き続け
   （インライン宣言はどんな`:hover`セレクタより優先されるため）ホバーの背景変化が
   `:hover`規則を足しても一切表示されない。クラス化して初めてホバーが効くようになる。 */
.box-link {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; margin: 2px 0 var(--gap); padding: 12px 16px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--brand-700); text-decoration: none; font-weight: 700;
}
.box-link:hover { background: var(--surface-2); }

/* 大規模リストのサーバ側ページャ（resources/views/vendor/pagination/app.blade.php）。
   モバイルファーストの前へ/次へ＋件数表示。design-review「スケール」対応 */
.pager { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 14px 0 4px; }
.pager-info { margin: 0; }
.pager-btns { display: flex; align-items: center; gap: 12px; }
.pager-current { min-width: 56px; text-align: center; }
.pager-disabled { opacity: .45; pointer-events: none; }
summary.btn::-webkit-details-marker { display: none; }

/* 運営コンソール（素朴・実用UI・意図的にトーンを落とす） */
.ops {
  --surface: #fff;
  /* 【P-3・第17回デザインレビュー】`.ops .scroll`が本文の面を`#eef0f3`へ塗り替えるため、
     既定の`--muted`(#646f86)は**4.4217:1**しかなくAA(4.5:1)に届かない。`--muted`のトークン
     定義は「白・surface-2でAA本文4.5:1以上を満たすよう暗化」と書いており、運営画面の
     **第3の面はその想定に入っていなかった**。運営画面のトーンを落とす意図（`.scroll`の
     背景）は保ったまま、この配下だけ`--muted`を暗くして基準を満たす。
     実測：#5f6a80 は #eef0f3 上で 4.7653:1、白（カード内）で 5.4406:1。 */
  --muted: #5f6a80;
}
.ops .appbar { background: #1f2734; border-bottom-color: #2c3543; }
/* 暗い運営appbarに乗る前景（画面名・戻る・補助リンク）の色は**ここだけ**で決める。
   【2026-08-10・部品別レビュー（2周目）】従来は title と iconbtn だけがここにあり、
   同じヘッダ行に並ぶ`.btn-ghost`（お知らせ管理・操作ログ）8箇所は`style="color:#cdd4de;"`と
   インラインで**別の色**を指定していた。直前のPRで戻るボタン13箇所をここへ寄せたときに、
   **すぐ隣に並ぶこの8箇所を取り残していた**（事例で直してクラスで直さなかった例）。
   色は明るい方（title と同じ #dfe4ec）に統一する——押せるものが画面名より暗い理由が無い。 */
/* 暗い運営appbar（#1f2734）の上では、`.btn-ghost`に与えた白い面と`--control-border`の枠線が
   そのまま乗ると「白い箱に淡色文字」という読めない組み合わせになる。ここでは面と枠を打ち消し、
   ヘッダ内のテキスト導線としての従来の見た目を保つ（SR1F-2の対の側の手当て）。 */
.ops .appbar .title,
.ops .appbar .iconbtn { color: #dfe4ec; }
.ops .appbar .btn-ghost { color: #dfe4ec; background: transparent; border-color: transparent; }
/* 暗い運営appbar上のホバー：既定の --surface-2（ほぼ白）だと淡色文字（#cdd4de/#dfe4ec）が
   読めなくなるため、暗い半透明にして視認性を保つ（戻る・お知らせ管理・操作ログの各導線） */
.ops .appbar .iconbtn:hover,
.ops .appbar .btn-ghost:hover { background: rgba(255, 255, 255, .10); }
.ops .scroll { background: #eef0f3; }
.ops-tag { display: inline-block; font-size: var(--fs-xs); font-weight: 700; color: #b23; letter-spacing: .05em; }

/* 機能ガイド（/features）の実画面キャプチャ枠（docs/94 §5.1 S5）。
   前半の`.slide-art`と役割は同じ（見出し直下に載せる画面イメージ）だが、中身が擬似UIではなく
   実際のスクリーンショット（<img>）のため専用クラスにした。**モック側（mockups/assets/app.css）にも
   同じ規則を置く**（2026-08-26。以前は「モックは擬似UIのまま」という docs/94 §5.1.1 の設計に従って
   意図的に置いていなかったが、実装がS5で実画面へ移ったあともモックだけ擬似UIのままで、
   派生成果物が実装より古い状態が残っていた。mockups/features-category.html も実画像を参照する）。
   新しい規則を前半へ足さない
   規約（docs/18 §3.9・AppCssMockSyncBlockTest）に従い後半ブロックに置く。 */
.feature-shots { display: flex; flex-direction: column; align-items: center; gap: 14px; margin: 14px 0 20px; }
.feature-shot {
  max-width: 300px; width: 100%; height: auto; display: block;
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm);
}

/* 補助リンク（アイコン＋短いラベル）。不具合報告・ヘルプへの導線を、説明の1文ではなく
   「アイコン＋2〜7字」で置くための共通部品（2026-08-24・ユーザー指摘「細かい説明が多く
   ごちゃごちゃしている。ヘルプへリンクするアイコンに変えるなどシンプルにできないか」）。
   アイコンだけにはしない：この画面群の利用者（60代の指導者・急ぐ保護者）はアイコンの
   語彙を共有していないため、ラベルは必ず併記する（CLAUDE.md 8「用語は日常語」）。
   `display:inline-flex`＋縦paddingでタップ領域を確保する（TA-1・WCAG 2.5.8の24px）。
   色は呼び出し側で決める（最下部の不具合報告は`--muted`、本文中のヘルプは`--brand-700`）。 */
.support-link { display: inline-flex; align-items: center; gap: 5px; padding: 8px 6px; }
.support-link svg { width: var(--ic-sm); height: var(--ic-sm); flex: none; }

/* 【YD-1・第247回ウォークスルー】上の規則は本来この位置（印刷ブロックの直前）に置く。
   印刷ブロックはファイル末尾でなければならない（下のEE-1のコメント参照）が、
   `.feature-shots`が**印刷ブロックより後ろ**に足されており、その不変条件が既に破れていた。
   今回は`.app`を再定義する規則ではなかったため実害は出ていなかったが、
   **破れていること自体を誰も検知できなかった**（テストは緑・画面も無傷）のが問題。
   以後は`AppCssPrintBlockIsLastTest`が機械的に守る。 */

/* ---------- 送信中の視覚的フィードバック ---------- */
/* 【ZBQ-1消化・第309回ウォークスルー】`public/js/app.js`（FI-7）は二重送信防止のため送信中の
   ボタンへ`disabled`＋`aria-busy="true"`を付与するが、見た目は`.btn:disabled`（グレーアウト）に
   委ねていたため、**入力不備で最初から押せないdisabled**と**今まさに処理中のdisabled**が
   見分けられなかった（design-review.md §L「システム状態の可視性：処理中…のフィードバックが
   設計されているか」。app.js側のコメントは同§Dを参照していたが、§Dは逆にローディング表示を
   要求する側で、参照が根拠になっていなかった＝§5.5「他所を参照する正当化コメントは前提が
   同じか確かめる」）。
   `aria-busy="true"`をCSSの手がかりに、回転する円弧を`::before`疑似要素で足す。`.btn`・
   素の`button`はどちらも`display:inline-flex; gap`済み（前半のbutton基本スタイル・後半の
   `.btn`）のため、生成した`::before`はフレックスアイテムとして自動的に並び、`order:-1`で
   先頭へ、`gap`がそのまま余白になる（新しいラップ要素・JS基盤を増やさない・design.md。
   JSは既に付与済みの属性を読むだけで、表示はCSSアニメーションのみで完結する）。
   色は`currentcolor`を使い、`.btn-primary`／`.btn-line`等どのボタン種でも
   （実際には`.btn:disabled`が一律`var(--muted)`へ落とすため）自動的に馴染む。
   支援技術には`aria-busy="true"`自体が状態として伝わる（色だけに頼らない・design-review.md
   §C。疑似要素の内容はスクリーンリーダーに読まれないため装飾専用でよい）。
   低速回線ほど`BUSY_TIMEOUT_MS`（20秒）到達前にこの表示が長く見える場面が増えるため、
   `prefers-reduced-motion: reduce`では回転を大きく緩める（停止はしない——「処理中」という
   意味そのものを運ぶアニメーションのため、完全停止すると情報が消える）。 */
.btn[aria-busy="true"]::before, button[aria-busy="true"]::before {
  content: ""; order: -1; flex: none;
  width: 15px; height: 15px; margin: 0;
  border-radius: 50%;
  border: 2px solid currentcolor; border-top-color: transparent;
  opacity: .7;
  animation: kurukana-spin .7s linear infinite;
}
@keyframes kurukana-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .btn[aria-busy="true"]::before, button[aria-busy="true"]::before { animation-duration: 2.2s; }
}

/* 運営からのお知らせの本文（会員ホーム・管理者ダッシュボードのカードの中）。
   Markdownが返す段落・箇条書き・リンクを、カードに収まる余白へ整える
   （SR1I-5・第1周スクショレビュー）。記事ページの`.article`は見出し・表を伴う
   長文向けで余白が大きく、カードの中では過剰になるため流用しない。 */
.announcement-body > :first-child { margin-top: 0; }
.announcement-body > :last-child { margin-bottom: 0; }
.announcement-body p { margin: 0 0 8px; }
.announcement-body ul, .announcement-body ol { margin: 0 0 8px; padding-left: 1.4em; }
.announcement-body li + li { margin-top: 2px; }
.announcement-body a { color: var(--brand-700); }
/* ---------- 記事カード（画像＋タイトル。SR1A-12・スクショレビュー第1周A-7消化） ----------
   ユーザー指摘「記事には画像も付けたい。LPも下の方に記事の画像とタイトルが並んでいる感じに
   したほうが訴求力が高まるのでは」への対応。既存の`.feature`（アイコン＋説明文の横並び）とは
   別の骨格にする——LPは既に「.lp-h（中央寄せ見出し）＋.features（アイコン横並びカード群）」
   という並びを複数セクション持ち（design-review.md §1-O較正診断で指摘済み）、記事セクションに
   同じ骨格をもう1つ重ねると「全セクションが同じ骨格」の問題を1つ増やすため、画像を主役にした
   縦積みのメディアカード（画像を上・タイトルを下）という別の見せ方にする。
   `/blog`のピックアップにも同じ部品を使う（記事一覧・LPの両方で「画像＋タイトル」を
   同じ見た目に揃える）。画像が未生成の記事は<img>を出さず、タイトルだけの帯として成立する
   （呼び出し側の`@if`で個別に判定・`BlogController::imageUrl()`参照）。 */
.article-cards { display: flex; flex-direction: column; gap: 14px; margin: 14px 0 2px; }
.article-card {
  display: block; overflow: hidden; text-decoration: none; color: inherit;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.article-card:hover { box-shadow: var(--shadow); }
.article-card img {
  /* height:auto は必須。<img width height>属性がCSSの提示ヒントとして扱われ、
     width/heightの両方が「定まった値」になるとaspect-ratioが無視される
     （実測：height属性740→630がそのまま固定表示され、width:100%で縮めても
     縦だけ元の630pxのままになるバグを引き起こした）。heightをautoに戻し、
     aspect-ratioに実際の比率計算を委ねる。 */
  display: block; width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover;
  background: var(--surface-2);
}
.article-card-body { display: block; padding: 12px 16px 14px; }
.article-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.article-card-ttl { font-weight: 700; font-size: var(--fs-base); line-height: 1.5; }
.article-card-lead { display: block; margin-top: 6px; color: var(--muted); font-size: var(--fs-sm); line-height: 1.7; }
.article-card-arrow { color: var(--muted); flex: none; }
.article-card-arrow svg { width: var(--ic-sm); height: var(--ic-sm); display: block; }

/* 新着一覧（.list .row）の先頭に付ける小さなサムネイル。.rowは119箇所超で共有する
   部品のため.row自体は変更せず、修飾用のクラスだけを足す。
   `object-position: right center`：アイキャッチ画像（1200x630）を1:1へcoverすると
   常に中央630px幅（1200x630画像を1:1へcoverするときの等倍crop幅）が写る。タイトル文字は
   画像の左半分（`generate-blog-eyecatch.mjs`の`.title`がwidth:460pxで確保）に収まる設計の
   ため、右寄せでcropすると文字を切らずに背景とアイコンだけを見せられる（中央基準の既定値
   （50% 50%）のままだとタイトル文字の右端が中途半端に切れて表示されることを実測で確認）。 */
.row-thumb { width: 48px; height: 48px; flex: none; border-radius: var(--radius-xs); object-fit: cover; object-position: right center; background: var(--surface-2); }

/* 記事詳細（/blog/{slug}）のアイキャッチ画像。見出し直下・本文の前に全幅で置く。 */
.article-hero-img {
  /* height:autoが必須の理由は.article-card imgと同じ（<img width height>属性との
     組み合わせでaspect-ratioが無効化される問題）。 */
  display: block; width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover;
  border-radius: var(--radius); margin: 14px 0 4px; background: var(--surface-2);
}

/* LP末尾の記事セクションの見出し行。.lp-h（中央寄せkicker＋h2）とは別の骨格にする
   （左寄せの見出し＋「記事一覧」への導線を横並びにする）ための意図的な差。 */
.lp-articles-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0 0 10px; }
.lp-articles-head h2 { font-size: var(--fs-xl); font-weight: 800; letter-spacing: -.01em; color: var(--ink); margin: 0; }

/* ---------- 公開ページの視覚的な強弱（LP・できること・記事） ----------
   写真は利用場面、実画面は製品の根拠、アイコンは索引という役割を混ぜない。
   LPヒーローでは生成した場面写真に実キャプチャをHTMLで重ね、架空UIを見せない。 */
.lp-hero-visual {
  position: relative; width: 100%; margin: 24px auto 0; aspect-ratio: 3 / 2; overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .72); border-radius: calc(var(--radius) + 4px);
  background: var(--surface-2); box-shadow: var(--shadow);
}
.lp-hero-scene { display: block; width: 100%; height: 100%; object-fit: cover; }
.lp-hero-device {
  position: absolute; right: 14px; bottom: 12px; width: 31%; min-width: 92px; max-width: 112px;
  height: auto; aspect-ratio: 112 / 190; overflow: hidden;
  border: 3px solid rgba(255, 255, 255, .94); border-radius: 14px;
  background: var(--surface); box-shadow: 0 12px 28px rgba(20, 38, 68, .22);
  transform: rotate(1.5deg); text-align: left;
}
.lp-hero-device-label {
  display: block; padding: 5px 8px; color: var(--brand-700); background: var(--brand-50);
  font-size: var(--fs-xs); font-weight: 800; line-height: 1.3; letter-spacing: .04em;
}
/* 縦長の実画面は、判断材料になる「今日・次の予定」がある上端を意図的に見せる。 */
.lp-hero-device img { display: block; width: 100%; height: auto; }

/* 9機能を定義順のまま3群に分け、同じ強さのカードが長く続く状態を抑える。 */
.feature-groups { display: flex; flex-direction: column; gap: 22px; margin-top: 14px; }
.feature-group > .feature-group-label {
  margin: 0 0 8px; color: var(--ink-2); font-size: var(--fs-sm); font-weight: 800;
  line-height: 1.5; letter-spacing: .06em;
}
.feature-group .features { margin: 0; }

/* ピックアップは1本目だけ写真を大きく見せ、2・3本目は横長にして一覧までの高さを抑える。
   画像が無い差し替え中は.has-imageが付かず、従来どおり本文だけのカードとして成立する。 */
.article-card.is-compact.has-image {
  display: grid; grid-template-columns: 112px minmax(0, 1fr); align-items: stretch;
}
.article-card.is-compact.has-image > img {
  width: 112px; height: 100%; min-height: 132px; aspect-ratio: auto; object-fit: cover;
}
.article-card.is-compact .article-card-body { align-self: center; padding: 12px 14px; }
.article-card.is-compact .article-card-lead {
  display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
}


/* =====================================================================
   印刷（@media print）
   【第54回ウォークスルーEE-1】このブロックは**必ずファイル末尾に置くこと**。
   以前は中ほど（.appの再定義より前）にあったため、`.app { max-width: none }` が
   後方の `.app { max-width: 480px }`（同一詳細度）に上書きされ、**印刷時も画面幅の
   ままだった**。結果、出欠印刷名簿の「確認」欄（手書きチェック）と、イベント申込者
   名簿の「お知らせ（届くか）」「連絡事項」列が用紙の右端でクリップされ紙に出ていなかった
   （`overflow-x:auto` は画面ではスクロールできるが紙では切り捨てになる）。
   CLAUDE.mdが求める「お知らせが届くか の可視化」が、最も必要な紙の上で機能していなかった。
   ===================================================================== */
@media print {
  /* 【SR1F-26・スクショレビュー第1周】用紙の余白を宣言する。従来はどの印刷ビューにも
     `@page`が無く、余白はブラウザの既定（Chrome約10mm・他は別値）任せだった。紙に出る
     帳票の左右が環境ごとに変わるうえ、印刷ダイアログの余白セレクタの初期値もブラウザが
     決めることになる。12mmは一般的なプリンタの非印字領域（3〜5mm程度）に対して十分な
     余裕がある（design-review §N「非印字領域で行・列が欠けない余白設計か」）。
     **用紙サイズ（size: A4）は宣言しない**：レイアウトは幅に追随する組み方
     （2列グリッドは minmax(0, 1fr)）なのでLetter・B5でも崩れず、宣言すると印刷ダイアログの
     用紙選択を縛りうるため。なお利用者がダイアログで余白「なし」を選んだ場合はそちらが
     優先される（@pageが決めるのは既定値であって強制ではない）。
     ページ番号（@pageのマージンボックス）は主要ブラウザが未対応のため入れない。必要なら
     ブラウザの印刷ダイアログのヘッダー/フッター設定で出せる */
  @page { margin: 12mm; }
  body { background: #fff; font-size: var(--fs-xs); }
  .app { max-width: none; box-shadow: none; background: #fff; }
  .appbar, nav.appnav, .tabbar { display: none !important; }
  /* 画面いっぱいに広げる指定が印刷にも残ると、内容が短くても1ページ分の余白が出る（EE-4） */
  .app { min-height: 0; }
  /* .cardは印刷ビュー（個人QR一括印刷・共通QR印刷）でもそのまま使われるが、box-shadowの
     解除対象に含まれていなかった（第28回ウォークスルーAX-5）。モック（mockups/join-print.html等）
     は独自の.paperクラスで印刷時にbox-shadow:noneを明示しているが、実装はlayouts.guestの
     .app内で.cardをそのまま流用するため、この既定ルールに含めないと印刷時も影が残る。 */
  main section, main > ul, main table, main .card { box-shadow: none; }
  /* 画面専用要素（印刷ボタン・不具合報告への導線等）は紙に出さない。従来この宣言は
     印刷ビュー個別の<style>（イベント申込者名簿・出欠印刷名簿）にしか無く、同じ`.no-print`を
     使っているQR印刷ビュー（個人QR一括印刷・共通QR印刷）では効いていなかった（＝印刷ボタンが
     紙に出ていた）。共通ルールとしてここへ引き上げる（design-review §N「画面専用要素は
     no-printで印刷から除外」） */
  .no-print { display: none !important; }
}
