/* SCHOOL Manager — Blue design system（承認済みモック classroom-system-concept.html v3 準拠） 2026-08-13 */
:root{
  --bg:#e9f1f7; --surface:#ffffff; --surface-2:#dceaf5; --surface-3:#c4dced;
  --border:#b4d3e6; --border-soft:#d3e5f1;
  /* 文字の濃さの階段（2026-08-17 見直し）。
     旧 --text-faint(#94b0c4) は白地でコントラスト2.27:1 しかなく、一覧の学校名・件数・
     kvのラベル・note など「読ませたい文字」がほぼ全画面で薄すぎた。現場のスタッフは
     幅広い年齢層なので、読めない文字は無いのと同じ。
     直し方は「階段を1段ずつ濃い方へずらす」。新しい色は1つも足していない
     （--text-dim には既存の --text-quiet の値を、--text-faint には旧 --text-dim の値を充てた）。
       --text       #20364a … 12.4:1（本文）
       --text-dim   #4e6d85 …  5.4:1（見出し・ラベル。AA達成）
       --text-faint #5f7f97 …  4.2:1（補助。旧2.27:1 → 目安の3:1を大きく上回る）
     色相は3段とも従来のままなので、青系の落ち着いた見た目は変わらない */
  --text:#20364a; --text-dim:#4e6d85; --text-faint:#5f7f97;
  --accent:#2bacf0; --accent-ink:#ffffff; --accent-dim:#7cc8f5; --accent-soft:#dcf0fd; --accent-2:#ff9baf;
  --lesson:#2fae68; --lesson-bg:#e2f6ea; --ticket:#f08a1f; --ticket-bg:#fdead2;
  --extra:#7c5cc4; --extra-bg:#f0e9fb;
  --study:#3d7fc4; --study-bg:#e1eefb; --absent:#e6564f; --absent-bg:#fde3e1;
  --warn:#e6564f; --warn-bg:#fde3e1;
  --shadow:0 2px 10px rgba(40,110,160,.08); --shadow-hover:0 8px 22px rgba(43,172,240,.2);
  --radius:16px; --radius-sm:10px;
  /* --- 売上管理の積み上げグラフで足した色（2026-08-17）。既存トークンは1つも書き換えていない ---
     費目の色は現行の対応（青／濃い青／緑／橙／グレー）を変えていないが、
     積み上げで色が直に隣り合うようになったため、隣同士が溶けない濃さまで詰めた：
       入塾金       #3d7fc4 → #1f5289（授業料の青とRGB距離65しかなく帯が溶けていた）
       追加授業・調整 #94b0c4 → #7e868d（白地で2.27しかなく棒も凡例も見えなかった） */
  --fee-tuition:#2bacf0; --fee-entrance:#1f5289; --fee-material:#2fae68;
  --fee-season:#f08a1f; --fee-other:#7e868d;
  /* 薄い地の上に文字を載せるための濃い版。意味を持つ色（出席=緑／遅刻=橙／欠席=赤）は変えない。
     --accent-2(#ff9baf) に白文字はコントラスト1.99で字が消える。
     --accent(#2bacf0) を --accent-soft の上に置くと2.17で、合計行の金額が飛ぶ。
     ※ --text-quiet は 2026-08-17 の見直しで --text-dim と同じ値（#4e6d85）になっていたが、
       2026-08-29 のコントラスト強化で --surface-2 が濃くなり（#dceaf5）、その上では
       4.45:1 と AA（4.5:1）に0.05だけ届かなくなった。淡い地の上に置く前提のトークンなので
       一段だけ濃くする（#47657c＝濃くなった --surface-2 の上で 5.01:1、白地で 5.90:1）。
       色相は変えていない。--text-dim とは再び別の値になったが、それがこのトークンを
       残している理由そのもの（淡い地の上だから濃くしたい、が使っている側の意図） */
  --accent-2-deep:#c93f69; --accent-deep:#0f6b9e; --text-quiet:#47657c;
  --lesson-deep:#1d7a48; --absent-deep:#b7392f;
  /* 定員設定のマス目で足した濃い版（2026-08-17）。淡い地（--study-bg / --ticket-bg）の上に
     --study(#3d7fc4)・--ticket(#f08a1f) をそのまま置くと字がかすんで読めないため。
     面の色（意味を持つ色）は変えていない */
  --study-deep:#1f6ea8; --ticket-deep:#a24e14;
  /* 体験授業（無料）のティール。もともと .badge-trial が直値で持っていた色を
     トークンにしただけで、値は1ミリも変えていない。生徒数の推移のグラフでも
     同じ色を使うため、2か所に同じ数値を書かなくて済むようにした（2026-08-17） */
  --trial:#0d8577; --trial-bg:#d9f3ef;
  /* カテゴリバッジの文字用に足した濃い版（2026-08-18 遼様の実機指摘
     「振替管理のコントラストが弱く読みづらい」）。実機で測ると、淡い地に基底色を
     そのまま置いたバッジは 2.5〜4.2:1 しかなかった（AAの4.5:1に届かない）。
     値は当時の振替バッジ（.badge-*-mk。2026-09-18 に廃止）が使っていたものと同じで、
     **面の色（意味を持つ色）は1つも変えていない**。文字だけを濃い版に差し替えている */
  --extra-deep:#63469f; --trial-deep:#0a6b60; --service:#c2367d; --service-deep:#a02a67;
}
* { box-sizing: border-box; }
/* ===== 文字の大きさ（2026-08-29 遼様のご指摘で全体を見直し） =====
   遼様「全体的に文字が小さいです。あと20%くらいベースを大きくし、
   大きいものと小さいもののメリハリをもう少しつけたい。」

   スタッフアプリと同じ階段で一括して上げた：
     ・基準 14.5 → 17.5px（＋21%）
     ・大きいもの（16px以上）は ×1.24〜1.30 でより大きく（例：画面名 20→26、KPI 29→37）
     ・小さいものは ×1.12〜1.14。ただし 13px を下限にして、それ以上は下げない
       （11.5px以下だった補助・バッジ類はすべて 13px に着地）
   文字を入れる固定寸の器（バッジの高さ・列幅・ポップアップの幅）は同じ患部なので
   一緒に広げてある。例外は .cap-lockchip i（Font Awesomeの鍵アイコンの字形で、文字ではない）
   だけ。共有部品（assets/schedule-calendar.css）の帯も 13px 基準へ上がったので、
   以前あった .sc-cal-bar の狭幅用の上書き（8.5px）は 2026-08-30 に撤去した */
body {
  margin: 0;
  font-family: 'Zen Maru Gothic','BIZ UDPGothic','Yu Gothic UI','Meiryo UI','Hiragino Kaku Gothic ProN',sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 17.5px;
}
.hidden { display: none !important; }

/* 保存中・通信中の覆い（2026-09-10 遼様のご指摘「固定時間割の保存に時間がかかり、
   保存できたか不安になる」）。保護者アプリ（#mah-overlay）・スタッフアプリ（#tea-overlay）と
   同じ形にしてある。ポップアップ（z-index:1000）より手前に出さないと、
   生徒編集ポップアップの上に覆いがかからず、そのまま操作できてしまう。
   進捗バーは 95% で止める（100% にすると「終わったのに動かない」と読まれる）。 */
#adm-overlay {
  position: fixed; inset: 0; background: rgba(233,241,247,.95); z-index: 2000;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.adm-hidden { display: none !important; }
.adm-progress-container { width: 80%; max-width: 250px; height: 8px; background-color: var(--surface-3); border-radius: 10px; overflow: hidden; }
.adm-progress-bar { width: 0%; height: 100%; background-color: var(--accent); border-radius: 10px; animation: adm-fake-progress 10s cubic-bezier(0.1, 0.5, 0.05, 1) forwards; }
@keyframes adm-fake-progress { 0%{width:0%;} 10%{width:30%;} 40%{width:70%;} 100%{width:95%;} }
.adm-loading-text { margin-top: 15px; font-weight: 800; font-size: 17px; color: var(--text); }

/* ログイン画面 */
.auth-screen {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(ellipse 900px 500px at 50% -10%, var(--accent-soft), transparent 60%), var(--bg);
}
.auth-box { width: 380px; text-align: center; }
.auth-box h1 { font-size: 27px; margin: 0 0 8px; color: var(--text); font-weight: 800; }
.auth-box .note { font-size: 14px; color: var(--text-faint); margin: 0 0 26px; }
/* 見出しの下の校舎名（2026-09-11 遼様指示）。掛け持ちのスタッフが、どの校舎の
   SCHOOL Manager を開いているかを取り違えないための表示なので、長くても途中で切らない */
.auth-box .school-line { display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 0 0 8px; font-size: 14px; font-weight: 800; color: var(--accent); line-height: 1.35;
  overflow-wrap: anywhere; }
.auth-box .field { text-align: left; }
.auth-box .field label { font-size: 13px; }
.auth-box .field input { padding: 12px 14px; }
.auth-box #login-btn { width: 100%; padding: 13px; margin-top: 6px; }

/* 共通フォーム部品 */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.field label { font-size: 13px; font-weight: 700; color: var(--text-dim); }
.field input, .field select {
  padding: 10px 13px; border: 1.5px solid var(--border); border-radius: var(--radius-sm); font-size: 16px;
  font-family: inherit; color: var(--text); background: var(--surface); transition: .15s;
}
.field input:focus, .field select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.btn { display: inline-flex; align-items: center; gap: 7px; border: 1px solid transparent; border-radius: 10px; padding: 10px 18px; font-weight: 700; cursor: pointer; font-size: 15.5px; transition: transform .12s, box-shadow .12s; font-family: inherit; }
.btn:active { transform: scale(.96); }
/* 主ボタンの面（2026-09-11 トンマナ合わせ）。
   もとは --accent(#2bacf0)＋白文字で、実測 2.54:1。本文の 4.5:1 どころか
   大きな文字の 3:1 も割っていた（この規則はページ内のほぼ全ボタンに効く）。
   このファイルは既に「白文字を載せる面は同じ青の濃い版（--accent-deep）」を
   .act-decide（2.34:1 → 5.8:1）と .seg-btn.is-on（2.54:1 → 5.80:1）で決めており、
   主ボタンだけがその規則から取り残されていた。色相は変えず濃さだけを規則どおりにする（5.81:1）。
   スタッフアプリの主ボタンも同じ --accent-deep なので、2つのアプリで
   「いちばん押すボタン」が同じ見た目になる（遼様「統一感を出したい」2026-09-11） */
.btn-primary { background: var(--accent-deep); color: var(--accent-ink); box-shadow: var(--shadow); }
.btn-primary:hover { box-shadow: var(--shadow-hover); }
/* 押せないときの主ボタン。UI指示書 4-5：
   「薄い主色＋白抜き文字」にすると文字が背景に溶けて消える。
   実際 --accent-dim(#7cc8f5) の上に白文字で 1.84:1 しかなく、
   「この内容で確定する」が押せない間だけ**文字が読めない**状態だった。
   淡い面（--accent-soft）＋濃い文字（--accent-deep）＝4.96:1 にして、
   押せるようになった瞬間に主色（濃い面＋白文字）へ変わるのが見えるようにする。
   このルールは本部の全画面の .btn-primary が共有している（1か所直せば全部直る）。
   枠線を1本足すのは、淡い面が白いカードの上で「面がある」と読めるようにするため */
.btn-primary:disabled {
  background: var(--accent-soft); color: var(--accent-deep);
  border-color: var(--accent-dim); cursor: default; box-shadow: none;
}
.btn-danger { background: var(--absent); color: #fff; }
.btn-danger:hover { background: #cf453e; }
.btn-link { background: none; border: none; color: var(--text-dim); text-decoration: underline; padding: 4px 8px; }
.btn-ghost { background: var(--surface-2); color: var(--text-dim); border-color: var(--border); }
.btn-ghost:hover { background: var(--surface-3); }
.btn-sm { padding: 6px 13px; font-size: 13.5px; border-radius: 8px; }
/* 画面でいちばん使う「追加」の入口（2026-08-18 遼様指示「新規追加をもっと大きく目立つように・今の2倍程度」）。
   btn-sm（93×26px＝2,400px²）に対して 44px 高・面積で約2.2倍にしている。
   数字を直接書かず btn-sm と対で置いてあるのは、片方だけ触ったときに差が消えないようにするため */
.btn-hero { padding: 11px 20px; font-size: 17.5px; font-weight: 800; border-radius: 12px; }
.btn-hero i { font-size: 18px; }
.error { color: var(--absent); font-size: 15.5px; margin-top: 8px; }
.msg { font-size: 15.5px; margin-top: 8px; padding: 8px 12px; border-radius: var(--radius-sm); }
.msg.ok { background: var(--lesson-bg); color: #1d7a48; }
.msg.error { background: var(--absent-bg); color: #b7392f; }
/* 入力欄ごとの誤り（2026-09-11 生徒の追加：どの欄の何が悪いかを、その欄のすぐ下に出す） */
.field-err { color: #b7392f; font-size: 14px; margin-top: 4px; line-height: 1.5; }
.field.has-err input, .field.has-err select { border-color: #b7392f; }
/* 生徒一覧の先頭の案内（退塾済みを伏せているときに、何名伏せているかと出し方を書く） */
.list-pane-hint { padding: 8px 14px; font-size: 14px; color: var(--text-dim); background: var(--surface-2); border-bottom: 1px solid var(--border); }
.note { color: var(--text-faint); font-size: 15.5px; }

/* アプリ全体レイアウト（トップバーは持たず、ブランド表示とユーザー情報はサイドバーに集約） */
.app-shell { min-height: 100vh; }
.layout { display: flex; min-height: 100vh; }

/* 本文を下にスクロールしてもメニューは画面に残す。
   メニューが画面の高さに収まらない場合は「項目の一覧（.nav-list）の中だけ」スクロールさせる。
   サイドバー全体をスクロールさせると、項目が増えたときに足元のログアウトが
   画面の下に押し出されて見えなくなる（開閉ボタンを足したときに実際に起きた） */
.sidenav {
  width: 220px; flex: 0 0 220px; background: var(--surface); border-right: 1px solid var(--border-soft);
  display: flex; flex-direction: column; padding: 20px 12px;
  /* flexの子は既定で高さいっぱいに伸びてしまい sticky が効かないため align-self で止める */
  position: sticky; top: 0; align-self: flex-start; height: 100vh; overflow: hidden;
  /* 重なりの順番（2026-09-17 遼様のご指摘「子階層タブとタブの中身でレイヤーの順序がおかしい」）。
     position:sticky は z-index を書かなくても“重なりの層”を1つ作る。そのため、
     小項目のパネルに z-index:900 と書いても、その900は**サイドバーの層の中だけ**の順番になり、
     本文の中で貼り付く見出し（生徒一覧の学年の帯 z-index:2、画面名の帯 40 など）に負けていた。
     ＝実際に、開いたパネルの上に学年の帯が重なって見えていた。
     直し方は「パネルの数字を上げる」ではなく「サイドバーの層そのものを本文より上へ置く」。
     100 … 本文の中で貼り付くもの（いちばん大きいもので45）より上、
           ポップアップ（.modal-overlay 1000、body直下）より下。
           ポップアップがメニューを覆う関係は今までどおり変わらない */
  z-index: 100;
}
/* min-height:0 が無いと、flexの子は中身の高さより縮まずスクロールが起きない */
.nav-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; }
/* スクロールバーは細めにするが、色は薄くしない。
   以前は thumb が --border(#c7e4fa) で、白地に対して約1.3:1 ＝ 事実上見えなかった。
   「下にまだ項目がある」ことに気づく最後の手がかりなので、4:1 以上の濃さにする */
.nav-list { scrollbar-width: thin; scrollbar-color: var(--text-faint) transparent; }
.nav-list::-webkit-scrollbar { width: 8px; }
.nav-list::-webkit-scrollbar-track { background: transparent; }
.nav-list::-webkit-scrollbar-thumb { background: var(--text-faint); border-radius: 99px; border: 2px solid var(--surface); }

/* =====================================================================
   2階層のメニュー：帯（大分類）とパネル（小項目）（2026-09-16 遼様指示）

   【なぜ2階層にしたか】タブが21個まで増え、1列に並べると1366×768のノートPCでは
   下の項目が画面の外に出ていた（「売上管理というタブが存在しない」ように見えていた）。
   帯に出すのは大分類7つだけにして、押したときだけ小項目のパネルを開く。

   【なぜ帯を横並び（アイコン＋文字を1行）のままにしたか】
   アイコンの下に文字を積む形も検討したが、「ダッシュボード」「お知らせ配信」
   「スケジュール」は13pxでも90px前後の幅がある。細い縦帯に収めるには折り返すか
   文字を13px未満にするしかなく、どちらも読みにくくなる。横並びなら今までの
   .nav-item とまったく同じ見え方のままで済み、参考にされた「細い縦帯」の見た目は
   既にある「畳んだ状態」（64px・アイコンだけ）がそのまま受け持つ。
   ===================================================================== */

/* 大分類のボタン。見た目の土台は小項目（.nav-item）にそろえてある。
   クラスを分けているのは、.nav-item が「タブを開くボタン」という意味を持っていて、
   役職ごとの出し分けと校舎未選択の無効化がその集合をそのまま数えているため */
.nav-cat {
  border: none; background: none; width: 100%; text-align: left; padding: 10px 11px; font-size: 16px;
  color: var(--text-dim); cursor: pointer; display: flex; align-items: center; gap: 10px;
  border-radius: 10px; transition: background .12s, color .12s; font-family: inherit; font-weight: 600;
  margin-bottom: 2px; position: relative;
}
.nav-cat > i:first-child { width: 19px; text-align: center; color: var(--text-faint); transition: .15s; font-size: 15.5px; }
.nav-cat:hover { background: var(--surface-2); color: var(--text); }
.nav-cat:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* いま開いているタブを含む大分類は、小項目と同じ塗りつぶしで示す（現在地が帯だけで分かる） */
.nav-cat.active { background: var(--accent); color: var(--accent-ink); }
.nav-cat.active > i { color: var(--accent-ink); }
/* パネルを開いている間の印。「選択中」とは別の状態なので、薄い面で区別する */
.nav-cat.is-open { background: var(--accent-soft); color: var(--accent-deep); }
.nav-cat.is-open.active { background: var(--accent); color: var(--accent-ink); }
/* 文字に余白を全部吸わせて、件数と矢印を右端にそろえる */
.nav-cat .nav-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 「右に開く」ことを矢印で予告する。畳んだ幅では入らないので消す */
.nav-cat-caret { order: 4; margin-left: 2px; font-size: 13px; opacity: .55; }
/* 未処理の件数（勤怠の承認待ちなど）は、小項目がパネルの中に入っても帯に出す。
   ここに出さないと「押して開くまで気づけない」＝合図として働かなくなる */
.nav-cat .count { order: 3; margin-left: auto; font-size: 13px; font-weight: 800; background: var(--absent); color: #fff; padding: 2px 9px; border-radius: 99px; }
.nav-cat.active .count { background: rgba(255,255,255,.35); color: var(--accent-ink); }
.nav-cat .count.is-warn { background: var(--ticket); color: var(--text); }

/* 小項目のパネル（第2階層）。HTMLでは大分類のすぐ下（.nav-list の中）に置いてあるが、
   PCでは position:fixed で帯の右に浮かせる。fixed の位置の基準は画面そのものなので、
   サイドバーの overflow（.sidenav は hidden・.nav-list は auto）に切り取られない。
   実際の左上の位置は、大分類のボタンの位置から script.js が測って入れる。
   スマホ（640px以下）では position:static に戻して、そのまま下に開く一覧にする */
.nav-panel {
  /* z-index はサイドバーの層（.sidenav の 100）の中での順番。帯のボタンより手前に出す。
     900 にしてあるのは、ポップアップ（1000）より小さい＝メニューが
     ポップアップを覆うことは無い、と数字だけで読み取れるようにするため */
  position: fixed; z-index: 900; width: 236px; max-height: 84vh; overflow-y: auto;
  padding: 10px; border: 1px solid var(--border-soft); border-radius: 14px;
  background: var(--surface); box-shadow: 0 14px 34px rgba(15, 23, 42, .18);
}
.nav-panel-title {
  font-size: 13px; font-weight: 800; letter-spacing: .04em; color: var(--accent-deep);
  padding: 2px 10px 4px;
}
/* 大分類の「できること」1〜2行（2026-09-17 遼様指示）。
   ホバーで子階層が開くようになったので、大分類の説明を吹き出しで出すと
   開いたパネルの真上に重なり、見せたい小項目のほうを隠してしまう。
   ＝説明はパネルの見出しの下に置く。文言は script.js の NAV_CAT_DESC から入る */
.nav-panel-desc {
  font-size: 13px; line-height: 1.5; color: var(--text-faint);
  padding: 0 10px 8px; margin-bottom: 6px; border-bottom: 1px solid var(--border-soft);
}
.nav-panel .nav-item { margin-bottom: 1px; }
.nav-panel .nav-item:hover { transform: none; }   /* 浮いた箱の中で横にずれると落ち着かない */

/* スマホのハンバーガー。PCでは帯がそのまま見えているので出さない
   （出すと「メニューを開く場所」が2つあることになり、どちらを押すのか迷わせる） */
.nav-burger { display: none; }

/* 画面が低いノートPC（1366×768 など）ではメニューの余白を詰める。
   1項目あたり 8px、グループ見出し 9px を削るだけで 200px 以上が浮き、
   16項目＋見出し5本が768pxの画面にそのまま収まる */
@media (min-width: 641px) and (max-height: 900px) {
  .sidenav { padding: 12px 12px; }
  .brand { padding: 4px 10px 10px; }
  .school-switcher { margin: 0 4px 7px; padding: 7px 10px; }
  .nav-item { padding: 6px 11px; margin-bottom: 1px; }
  .nav-cat { padding: 6px 11px; margin-bottom: 1px; }
  .nav-collapse { margin-top: 3px; padding: 6px 11px; }
  .side-foot { padding-top: 9px; }
}
.brand { display: flex; align-items: center; gap: 10px; padding: 6px 10px 20px; }
/* システム名そのものをバッジにする。丸アイコン＋2行テキストをやめ、1つの塊にした */
.brand-badge {
  display: inline-block; padding: 7px 12px; border-radius: 10px;
  background: var(--accent); color: var(--accent-ink);
  font-size: 16px; font-weight: 800; letter-spacing: .02em; line-height: 1.2;
  white-space: nowrap;
}

.nav-item {
  border: none; background: none; width: 100%; text-align: left; padding: 10px 11px; font-size: 16px;
  color: var(--text-dim); cursor: pointer; display: flex; align-items: center; gap: 10px;
  border-radius: 10px; transition: background .12s, transform .12s, color .12s; font-family: inherit; font-weight: 600;
  margin-bottom: 2px;
}
.nav-item i { width: 19px; text-align: center; color: var(--text-faint); transition: .15s; font-size: 15.5px; }
.nav-item:hover { background: var(--surface-2); color: var(--text); transform: translateX(2px); }
.nav-item.active { background: var(--accent); color: var(--accent-ink); }
.nav-item.active i { color: var(--accent-ink); }
.nav-item .count { margin-left: auto; font-size: 13px; font-weight: 800; background: var(--absent); color: #fff; padding: 2px 9px; border-radius: 99px; }
.nav-item.active .count { background: rgba(255,255,255,.35); color: var(--accent-ink); }
/* 「まだ片付いていない」ことを表す件数（勤怠の承認待ち）。
   赤（--absent）は欠席・危険の意味で使っているので、ここでは同じ画面のKPI・カードの縁と
   同じオレンジに揃える。白抜きだと 2.5:1 しか出ないので、地に濃い文字を載せる。
   .nav-item.active .count より後ろに置いて、選択中でも意味の色が残るようにしている */
.nav-item .count.is-warn { background: var(--ticket); color: var(--text); }

.side-foot { margin-top: auto; display: flex; align-items: center; gap: 9px; padding-top: 14px; border-top: 1px solid var(--border-soft); }
.side-foot .av { width: 33px; height: 33px; border-radius: 50%; background: var(--accent-soft); display: flex; align-items: center; justify-content: center; font-size: 13.5px; font-weight: 800; color: var(--accent); flex: 0 0 auto; }
.side-foot .who-wrap { flex: 1; min-width: 0; }
.side-foot .who { font-size: 14px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-foot .role { font-size: 13px; color: var(--text-faint); }
.side-foot .logout-btn { flex: 0 0 auto; color: var(--text-faint); font-size: 13.5px; text-decoration: none; padding: 4px 6px; }

/* =====================================================================
   左メニューの開閉（2026-08-17 遼様指示：WordPress管理画面と同じ考え方）

   ラベルを畳んでアイコンだけの細い縦バーにできるようにする。既定は「開いた状態」。
   畳んでも現在地を見失わないよう、次の3つは必ず残す：
     1. 選択中の項目の塗りつぶし（.nav-item.active は開いていても畳んでいても同じ色）
     2. 名前の吹き出し（script.js が body 直下に1つだけ作る .nav-tip。
        項目の一覧 .nav-list はスクロールする箱なので、中に置いた吹き出しは横に切られる）
     3. 未読などの件数バッジ（アイコンの右肩に小さく載せ替える）
   ===================================================================== */

/* 畳んだときだけ出る要素。既定（開いた状態・横並びメニュー）では出さない */
.brand-mark { display: none; }
.school-collapsed { display: none; }

/* 開閉ボタン自体は、縦のサイドバーになる幅でだけ出す（下の @media 参照）。
   横並びメニューの幅では畳んでも本文は1pxも広がらないので、押せてしまう方が有害 */
.nav-collapse { display: none; }

/* 縦のサイドバーになる幅の下限を 901px → 641px に下げた（2026-08-18）。
   1366pxの画面を左右2分割すると片側683px。そこで横並びの帯に化けると、
   19項目が1行に並んで**横スクロールしないとメニューが探せない**状態になっていた。
   PCで2画面に並べる使い方（遼様のご指示の到達点）では、縦のままアイコンだけに
   畳んだほうが速い。横並びの帯は、指で操作するスマホ幅（640px以下）に残す。 */
@media (min-width: 641px) {
  .nav-collapse {
    display: flex; align-items: center; gap: 10px;
    border: none; background: none; width: 100%; text-align: left;
    margin-top: 6px; padding: 9px 11px; border-radius: 10px;
    font-family: inherit; font-size: 14px; font-weight: 600; color: var(--text-faint);
    cursor: pointer; transition: background .12s, color .12s;
  }
  .nav-collapse i { width: 19px; text-align: center; font-size: 15.5px; }
  .nav-collapse:hover { background: var(--surface-2); color: var(--text-dim); }
  .nav-collapse:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

  /* 幅の変化だけをなめらかに。中身（アイコン）は動かさない */
  .sidenav { transition: width .16s ease, flex-basis .16s ease; }

  .layout.is-nav-collapsed .sidenav { width: 64px; flex: 0 0 64px; padding: 20px 8px; }

  /* 文字は display:none にせず「見えないだけ」にする。
     display:none にすると読み上げソフトからもボタンの名前が消え、
     アイコンだけのボタンが「ボタン」としか読まれなくなる */
  .layout.is-nav-collapsed .nav-label,
  .layout.is-nav-collapsed .brand-full {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }

  /* ブランドバッジ：水色の四角は残したまま、中身を文字から目印の絵に入れ替える */
  .layout.is-nav-collapsed .brand { padding: 6px 0 16px; justify-content: center; }
  .layout.is-nav-collapsed .brand-badge {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 40px; padding: 0; border-radius: 11px; font-size: 22px;
  }
  .layout.is-nav-collapsed .brand-mark { display: inline-block; }

  /* 操作中の校舎：校舎名は入らないので建物アイコンのボタンだけにする。
     押すとメニューが開くので、全権管理者は畳んだ状態からでも切替にたどり着ける */
  .layout.is-nav-collapsed .school-switcher { margin: 0 0 8px; padding: 0; background: none; display: flex; justify-content: center; }
  .layout.is-nav-collapsed .school-switcher label,
  .layout.is-nav-collapsed .school-switcher select,
  .layout.is-nav-collapsed .school-fixed { display: none; }
  .layout.is-nav-collapsed .school-collapsed {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 40px; border: none; border-radius: 11px;
    background: var(--accent-soft); color: var(--accent); font-size: 18px; cursor: pointer;
  }
  .layout.is-nav-collapsed .school-collapsed:hover { background: var(--surface-3); }
  .layout.is-nav-collapsed .school-collapsed:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* 大分類も、小項目と同じアイコンだけの縦線上に並べる。
     矢印は幅が無いので消す（押せば右にパネルが開く、という動きは変わらない） */
  .layout.is-nav-collapsed .nav-cat { justify-content: center; padding: 10px 0; gap: 0; }
  .layout.is-nav-collapsed .nav-cat > i:first-child { width: auto; font-size: 18px; }
  .layout.is-nav-collapsed .nav-cat-caret { display: none; }
  .layout.is-nav-collapsed .nav-cat .nav-label { flex: none; }
  /* 件数は畳んでも消さない。アイコンの右肩に載せ替える */
  .layout.is-nav-collapsed .nav-cat .count {
    position: absolute; top: -2px; right: 1px; margin: 0; padding: 0 5px; font-size: 13px; line-height: 1.5;
  }

  /* パネルの中だけは、畳んでいても今までどおり「アイコン＋文字」で出す。
     パネルは帯の外に浮いていて幅があるので、文字を隠す理由が無い。
     下の「.nav-label を見えなくする」を、ここで元に戻している */
  .layout.is-nav-collapsed .nav-panel .nav-label {
    position: static; width: auto; height: auto; padding: 0; margin: 0;
    overflow: visible; clip: auto; white-space: nowrap; border: 0;
  }
  .layout.is-nav-collapsed .nav-panel .nav-item { justify-content: flex-start; padding: 10px 11px; gap: 10px; }
  .layout.is-nav-collapsed .nav-panel .nav-item i { width: 19px; font-size: 15.5px; }
  .layout.is-nav-collapsed .nav-panel .nav-item .count {
    position: static; top: auto; right: auto; margin-left: auto; padding: 2px 9px;
  }

  .layout.is-nav-collapsed .nav-item { justify-content: center; padding: 10px 0; gap: 0; position: relative; }
  .layout.is-nav-collapsed .nav-item i { width: auto; font-size: 18px; }
  /* 中央に置いたアイコンが横にずれると落ち着かないので、ホバーの移動だけ止める */
  .layout.is-nav-collapsed .nav-item:hover { transform: none; }
  /* 件数バッジ（未読など）は畳んでも消さない。気づいてもらえないと困るものなので、
     ラベルの右端からアイコンの右肩へ載せ替える */
  .layout.is-nav-collapsed .nav-item .count {
    position: absolute; top: -2px; right: 1px; margin: 0; padding: 0 5px; font-size: 13px; line-height: 1.5;
  }

  /* 開閉ボタンも他のアイコンと同じ縦線上に並べる（1つだけ左にずれると目に付く） */
  .layout.is-nav-collapsed .nav-collapse { justify-content: center; padding: 9px 0; gap: 0; }

  .layout.is-nav-collapsed .side-foot { flex-direction: column; gap: 7px; }
  .layout.is-nav-collapsed .side-foot .who-wrap { display: none; }

  /* 畳んだ 156px（220→64）ぶん、本文の上限も広げる。
     ここを本文の上限（1720px）のままにすると広い画面では本文が頭打ちになり、
     「畳んだのに表が広がらない」＝畳む意味が無い状態になる。
     1720 + 156 = 1876px（2026-08-18、本文の上限を 1300→1720px にしたのに合わせて更新） */
  .layout.is-nav-collapsed .content { max-width: 1876px; }
}

/* =====================================================================
   大分類はマウスを載せるだけで子階層が開く（2026-09-17 遼様指示）
   「親階層は、クリックしなくてもホバーで子階層が表示されるようにして、
     無駄な操作を減らすこと」

   指で操作する端末（スマホ・タブレット）では効かせない。タッチでは「載せる」が
   そのまま「押す」になるので、通りすがりにパネルが開いてしまう。
   開くまでの遅れ（120ms）と、離れてから閉じるまでの猶予（250ms）は
   script.js の NAV_HOVER_OPEN_MS / NAV_HOVER_CLOSE_MS に1か所だけ置いてある。
   ===================================================================== */
@media (min-width: 641px) and (hover: hover) {
  /* 帯とパネルの間の8pxを、パネル側の当たり判定に含める。
     ここが空いていると、マウスが横切った瞬間に「帯からもパネルからも離れた」ことになり、
     手を止めていないのにパネルが閉じる */
  .nav-panel::before {
    content: ''; position: absolute; left: -14px; top: 0; width: 14px; height: 100%;
  }
}

/* 名前の吹き出し（畳んでいるときだけ、アイコンの右に出す）。
   項目の一覧（.nav-list）はスクロールする箱なので、その中に置くと右にはみ出た分が切られる。
   body 直下に1つだけ作り、位置だけ script.js が付け替える（assets/tooltip.js と同じ作り方） */
.nav-tip {
  position: fixed; z-index: 1200; left: 0; top: 0;
  max-width: 272px; padding: 8px 11px; border-radius: 9px;
  background: var(--text); color: #fff; font-size: 13.5px; font-weight: 600; line-height: 1.55;
  box-shadow: 0 6px 18px rgba(15, 23, 42, .22);
  opacity: 0; pointer-events: none; transform: translateX(-4px);
  transition: opacity .12s ease, transform .12s ease;
}
/* 畳んでいるときは「名前＋説明」の2段。開いているときは説明だけを出す
   （名前は帯にそのまま見えているので、繰り返すと読む量が増えるだけ） */
.nav-tip-name { font-size: 14px; font-weight: 800; margin-bottom: 2px; }
.nav-tip.is-open { opacity: 1; transform: translateX(0); }

/* 端末側で「動きを減らす」設定にしている人には、幅の変化も吹き出しも動かさない */
@media (prefers-reduced-motion: reduce) {
  .sidenav, .nav-tip { transition: none; }
  .nav-tip { transform: none; }
}

/* 器の余白（2026-08-18 遼様のご指摘「縦（下）と右に無駄な余白が多い」）。
   実測してから詰めた。上30→22px／左右36→24px／下44→24px。
   下は最後のパネルの margin-bottom 20px が重なって実測64pxあったので、
   下だけ .tab-panel > *:last-child の余白も落として 24px にそろえている。
   これ以上詰めるとカードの影が切れて窮屈に見えるので、ここで止める。
   max-width も 1300→1720px。1920pxの画面では右に400pxの何も無い帯ができていた
   （＝「右に無駄な余白」の正体）。読み幅が伸びすぎないよう上限自体は残す */
/* 2026-08-18 レスポンシブ化に伴う2点の変更：

   (1) overflow-x:hidden をやめた。
       横に長い中身を「切って無かったことにする」ので、講習集計のヒートマップのように
       器より広いものは右端が読めないまま気づけなかった。正しくは「はみ出す器の中だけで
       横スクロールさせる」ことなので、そちら（.table-wrap / .rev-chart など）で受ける。
       ※ overflow-x を指定していると overflow-y が auto に計算され、.content 自身が
         スクロールの箱になる。すると中の position:sticky は画面ではなく .content に対して
         効くようになり、**画面名の固定ヘッダーが動かなくなる**。これも外す理由。
   (2) min-width:0 … flexの子は既定で中身の最小幅より縮まない。
       これが無いと、広い表が1枚あるだけでページ全体が横に伸びる。

   (3) container-type … 「画面の幅」ではなく「本文の器の幅」でレイアウトを畳むため。
       サイドバーを畳むと本文は156px広がる。画面幅だけで判断すると、
       同じ1366pxの画面でも畳んだときに余っている幅を使えない（逆も然り）。 */
.content {
  flex: 1; min-width: 0; padding: 22px 24px 24px; max-width: 1720px;
  container-type: inline-size; container-name: mainc;
}
/* 最後のカードの下の余白は、器の padding-bottom と二重になるので落とす */
.tab-panel > *:last-child { margin-bottom: 0; }

/* タブを開いた瞬間の「読み込んでいます」（2026-09-11 の点検で追加）。
   起動時に全タブぶんを読むのをやめたため、押してから中身が出るまでの間ができる。
   何も出さないと「押しても反応しない」と受け取られ、二度押しや再読み込みを招く。
   画面は覆わない（覆うと読み込み中に他のタブへ移れなくなる）。
   画面名の帯（.content-head, z-index 40）より手前・ポップアップ（1000）より奥に置く。
   文字は 14px（この画面の下限は 13px） */
.tab-loading {
  position: sticky; top: calc(var(--sticky-top, 0px) + 8px); z-index: 45;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: fit-content; margin: 0 auto -34px; padding: 8px 18px;
  background: var(--surface); border: 1px solid var(--border-soft);
  border-radius: 999px; box-shadow: 0 4px 14px rgba(0, 0, 0, .10);
  font-size: 14px; font-weight: 700; color: var(--text-dim);
}
.tab-loading i { color: var(--accent-deep, var(--accent)); font-size: 14px; }

/* =====================================================================
   画面名を固定ヘッダーにする（2026-08-18 遼様指示）

   > 左メニューだけだと今自分がどこにいるかわからなくなる場合がある。
   > 特にカレンダータイプのUIがいくつかあるため、疲れているときなどは
   > 何を操作しているのか一瞬わからなくなる恐れがある。

   → スクロールしても画面名が消えないことが最優先。
   左右の負の margin は器の padding を打ち消すためのもの。これが無いと帯の左右に
   本文が透けて見える隙間ができ、スクロールした文字がそこを通り抜けてしまう。
   top は var(--sticky-top)。横並びメニュー（幅の狭い画面）ではメニューの帯が上にあるので、
   その高さぶん下げる（値は script.js が実測して入れる。CSSの閾値と食い違わないように、
   幅ではなく .layout の flex-direction を見て決めている）。
   z-index 40 … ポップアップ（1000）より下、パネル内の小さな重なり（〜70）より上 */
.content-head {
  position: sticky; top: var(--sticky-top, 0px); z-index: 40;
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 10px 16px; flex-wrap: wrap;
  margin: -22px -24px 16px; padding: 18px 24px 12px;
  background: var(--bg);
  border-bottom: 1px solid transparent;
  transition: box-shadow .15s ease, border-color .15s ease,
              padding .16s ease, row-gap .16s ease;
}
/* スクロールしていることが分かる合図。色だけでなく線という「形」も足す */
body.is-scrolled .content-head { border-bottom-color: var(--border-soft); box-shadow: 0 5px 14px rgba(40,110,160,.09); }
.content-head h2 { font-size: 26px; margin: 0; color: var(--text); font-weight: 800; letter-spacing: -.01em; }
.content-head p { margin: 4px 0 0; font-size: 15.5px; color: var(--text-faint); }

/* --- スクロール中は帯を薄くする（2026-08-18 追加） -------------------
   当初は「高さはスクロールしても変えない」としていた。理由は
   「縮めると下の中身が動いて読む位置を見失う」。これは帯が53pxのときの話で、
   実測したら成り立っていなかった：

     | 幅683px（1366pxのノートPCを左右2分割した片側）| 帯の高さ |
     |---|---|
     | ダッシュボード・振替管理など（ボタンなし）| 53px |
     | お知らせ・自習・チケット・売上 | 89px |
     | 勤怠の承認 | 95px |
     | 給与計算 | 93〜128px |
     | 生徒管理・講師管理 | 102px |

   狭い幅ではボタンが画面名の下の行に回り込むので、帯だけで画面の13〜17%を
   食い続けていた。2画面レイアウトで使うのが到達点である以上、これは払えない。

   縮めるのは上下の余白・行の間・いちばん背の高いボタン（.btn-hero）だけ。
   **画面名（h2）は文字の大きさも変えない**（読めることが最優先というご指示）。
   ボタンも消さない（「生徒追加を大きく目立たせる」というご指示を打ち消さないため）。
   切り替えの境目は script.js 側で上下にずらしてあるので、境目で
   パタパタと伸び縮みすることはない。 */
body.is-head-compact .content-head { padding-top: 9px; padding-bottom: 8px; row-gap: 5px; }
body.is-head-compact .content-head .btn-hero { padding: 7px 16px; font-size: 16px; }
body.is-head-compact .content-head .btn-hero i { font-size: 17px; }
/* 端末側で「動きを減らす」設定にしている人には、伸び縮みのアニメーションだけ止める
   （縮むこと自体は情報量の話なので残す） */
@media (prefers-reduced-motion: reduce) {
  .content-head { transition: none; }
}

/* scrollIntoView の着地点が固定ヘッダーの下に潜らないようにする
   （振替管理の「振替先を選ぶ」や、生徒管理の節へのジャンプで実際に潜っていた）。
   --head-h は script.js が「いま開いているタブの帯」を実測して入れる。
   ここに固定値（以前は 86px）を書いていると、102px ある生徒管理では
   16px ぶん潜り、逆に53pxの画面では余計に上へ飛ぶ。+12px は帯と着地点の間の隙間 */
html { scroll-padding-top: calc(var(--sticky-top, 0px) + var(--head-h, 86px) + 12px); }

/* カード同士の間隔 20→16px。詰めるのは間隔だけで、中身の余白（padding）は触らない。
   中身まで詰めると文字が枠に近づいて読みづらくなる（遼様「詰めすぎて窮屈にしない」） */
.panel { background: var(--surface); border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 20px 22px; margin-bottom: 16px; box-shadow: var(--shadow); }
.panel h3 { margin: 0 0 14px; font-size: 17px; color: var(--text); font-weight: 800; display: flex; align-items: center; gap: 8px; }
/* 見出し1行＋ボタンだけの薄い帯。中身をポップアップに畳んだ機能の入口に使う */
/* パネルの見出し行。左に見出し、右に年度の選択や切替を置く */
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.panel-head h3 { margin: 0; }
.panel-head .sim-row { margin-bottom: 0; }
.panel-slim { padding: 14px 18px; margin-bottom: 14px; }
.panel-slim .note { margin: 4px 0 0; font-size: 13.5px; }
.form-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; }
.form-row .field { min-width: 150px; margin-bottom: 0; }
.form-row .btn { height: 44px; }

/* 2カラムレイアウト。
   minmax(0, …) を必ず付ける。grid の 1fr は既定で「中身の最小幅より縮まない」ため、
   中に横スクロールできる表を1枚置いただけで列が器より広がり、ページ全体が横に伸びる
   （2026-08-18 に 683px で実際に起きた） */
.two-col { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 18px; align-items: start; }
@media (max-width: 980px) { .two-col { grid-template-columns: minmax(0, 1fr); } }

/* =====================================================================
   横に長い表を「自分の器の中だけ」で横スクロールさせる（2026-08-18）

   これが無いと、広い表がページ全体を横に伸ばし、左メニューまで一緒に流れて
   操作できなくなる。以前は .content の overflow-x:hidden で切っていたが、
   切ると右端が読めないまま気づけない（講習集計のヒートマップで実際に起きていた）。
   inline style の overflow-x:auto をあちこちに書くのもやめ、この1クラスに寄せる。 */
.table-wrap { width: 100%; overflow-x: auto; }

/* =====================================================================
   KPI（縦積み）とグラフを 1 : 2 で横に並べる（2026-08-18 遼様指示）

   > 上の4カラム（KPI）を縦に並べて「1」、グラフを「2」の比率で横に並べる。
   > すぐ下に分析（内訳）が来るようにしたい

   列は 1fr と 2fr。下限（minmax の左側）は置かない。置くと幅が足りなくなったときに
   下限のほうが先に効いて、比率が 1:2.18（器1157px）・1:2.74（器1083px）と勝手に崩れる。
   2026-08-18 の実装は minmax(248px,1fr) minmax(782px,2fr) だったため、
   ご指示どおりの 1:2 になるのは器が約1550px以上のときだけで、
   ふだん使う幅では一度も 1:2 になっていなかった（2026-08-19 の点検で判明）。

   比率を守るために、代わりに **2カラムで出す下限のほうを上げた**（1060px → 1190px）。
   グラフのSVGは文字を潰さずに描くのに 736px、カードの左右余白と枠で +46px、
   合わせて 782px 要る。1:2 でグラフ側に 782px を割り当てるには
   782 × 1.5 ＋ gap 16 = 1189px の器が必要なので、そこを畳む閾値にしている。
   つまり「1:2 を守れる幅では必ず 1:2 で横に並べ、守れない幅ではねじれた比率を見せずに縦へ畳む」。
   畳んだ側ではグラフが器の幅いっぱいを使えるので、狭いほうが読みやすいという逆転も起きない */
.kpi-chart-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 16px; align-items: stretch; margin-bottom: 16px; }
/* 中のカード・パネルは、この器が下余白を持つので二重にしない */
.kpi-chart-split > * { margin-bottom: 0; }
/* 縦積みのKPI。グラフの高さに合わせて4枚が伸びるので、隣と天地がそろう */
.stat-grid.is-stack { display: flex; flex-direction: column; gap: 14px; height: 100%; margin-bottom: 0; }
.stat-grid.is-stack .stat-card { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; }
/* 縦に積むと1枚あたりの高さが余るので、数字を少しだけ大きくして読みやすくする */
.stat-grid.is-stack .stat-card .lbl { margin-bottom: 7px; }

/* 一覧テーブル（生徒・講師・チケット・監査ログなど） */
.data-table { width: 100%; border-collapse: collapse; font-size: 15.5px; }
.data-table th, .data-table td { text-align: left; padding: 11px 10px; border-bottom: 1px solid var(--border-soft); }
.data-table th { color: var(--text-faint); font-weight: 700; font-size: 13px; letter-spacing: .03em; background: transparent; border-bottom: 1.5px solid var(--border); }
.data-table tr:hover td { background: var(--surface-2); }
.data-table td.mono, .data-table td.id-col { font-variant-numeric: tabular-nums; }
.data-table td.id-col { color: var(--text-faint); font-size: 13px; }
/* 表の中に「頭文字の丸＋氏名＋ロール」を出す部品は、講師管理を2カラムにした
   2026-08-18 に使われなくなったので削除した（残すと、次に表を作る人が
   「表のままでよい」と受け取ってしまう）。一覧＋詳細の型は .list-row を使う */

.tag { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 99px; font-size: 13px; font-weight: 700; }
/* 文字は濃い版。淡い地に基底色を置くと 2.5〜3.0:1 しかなく、実機で読みづらかった
   （2026-08-18 遼様の指摘を受けて全カテゴリを測り直した）。地の色は変えていない */
.tag-active { background: var(--lesson-bg); color: var(--lesson-deep); }
.tag-inactive { background: var(--surface-2); color: var(--text-quiet); }
.tag-suspended { background: var(--ticket-bg); color: var(--ticket-deep); }
/* 体験中（手動の印）。在籍状況のチップとは別に並べて出す。色はチケットの体験色と同じ */
.tag-trial { background: var(--trial-bg); color: var(--trial-deep); }
.tag-sibling { background: var(--study-bg); color: var(--study-deep); }
/* --surface-3 は --surface-2 より濃いので、--text-quiet だと 4.47:1 で AA に0.03届かない。
   ここだけ本文と同じ濃さにする（形＝淡い水色のチップ、は変えていない） */
.tag-withdrawn { background: var(--surface-3); color: var(--text); }
.tag-warn { background: var(--warn-bg); color: var(--absent-deep); }
/* お知らせの「予約中」（配信日時になるまで相手に見えていない）。取り下げ済みの灰色と見分ける（WP9） */
.tag-scheduled { background: var(--study-bg); color: var(--study-deep); }

/* 統計カード */
/* KPIカードの下も 22→16px（パネル同士の間隔と同じにして、縦の間隔を1種類にそろえる） */
.stat-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; margin-bottom: 16px; }
/* 金額を出すカードだけは幅の下限を広く取る（2026-08-17）。
   190px だと 1366px 以下で「12,290,000」と「円」が分断され、カードの高さまで不揃いになった。
   桁数の多い金額は必ず1行に収める＝単位が数字から離れないようにする */
.stat-grid-money .num { white-space: nowrap; }

/* KPIカードの列数に auto-fit を使わない（2026-08-18 遼様のご指摘「右に無駄な余白が多い」の正体）。
   auto-fit は幅が許すだけ列を作るので、カードの枚数で割り切れない列数になると
   最後の行に1〜2枚だけ残り、その右が丸ごと空白になる。実測：
     ・6枚のダッシュボード … 1366px で 5＋1。2行目の81%が空白
     ・4枚の給与計算       … 960px（1920pxの左右2分割）で 3＋1
   → 枚数を割り切れる列数だけを通す（4枚なら 4/2/1、6枚なら 6/3/2/1）。
   畳む判断は画面幅ではなく本文の器の幅（container-name: mainc）で行う。
   左メニューの開閉で同じ画面幅でも器が156px変わるため */

/* 4枚のカード（既定）。4列に要る幅＝190*4+16*3=808 */
@container mainc (min-width: 520px) { .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@container mainc (min-width: 840px) { .stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* 金額カードは1枚あたり296px要る（桁の多い金額と「円」を切り離さないため。
   2026-08-29 に数字を 29→37px へ上げたので 232px から増えた：296×4＋gap48＝1232）。
   4列に足りない幅では2列のままにして、3＋1を作らない */
@container mainc (max-width: 1240px) { .stat-grid-money { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* 縦積み（.is-stack）の金額カードにも1列を効かせる。下の「畳む」ブロック（1190px以下）が
   .stat-grid.is-stack（詳細度0,2,0）で2列を当てるため、こちらは3クラスで上回らせる。
   これが無いと器481〜620pxで金額カードだけ2列に残り、数字が枠からはみ出す */
@container mainc (max-width: 620px)  { .stat-grid-money, .stat-grid.stat-grid-money.is-stack { grid-template-columns: minmax(0, 1fr); } }

/* 6枚のカード（ダッシュボード） */
@container mainc (min-width: 420px)  { .stat-grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@container mainc (min-width: 640px)  { .stat-grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@container mainc (min-width: 1240px) { .stat-grid-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.stat-card { background: var(--surface); border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow); transition: transform .15s, box-shadow .15s; }
.stat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); }
.stat-card .lbl { font-size: 13px; font-weight: 700; color: var(--text-faint); letter-spacing: .02em; margin-bottom: 10px; }
.stat-card .num { font-size: 37px; font-weight: 800; color: var(--text); line-height: 1; font-variant-numeric: tabular-nums; }
.stat-card .num small { font-size: 15.5px; color: var(--text-faint); font-weight: 600; margin-left: 2px; }
.stat-card .delta { margin-top: 9px; font-size: 13px; font-weight: 700; }
.stat-card.warn .num { color: var(--absent); }
/* ダッシュボードの数字から、下の一覧へ移る（2026-09-12 スタッフテスト No.123/124）。
   押せる枠だけ指の形と縁の色を変え、キーボードで選んだときも枠が見えるようにする。
   着地点が画面名の帯に潜らないのは html の scroll-padding-top（--head-h の実測値）が受け持つ */
.stat-card.is-jump { cursor: pointer; }
.stat-card.is-jump:hover { border-color: var(--accent); }
.stat-card.is-jump:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* 移った先の一覧を2回だけ縁取り、どこに着いたかを目で追えるようにする（光らせ続けない） */
.panel.is-jump-target { animation: dash-jump-ring 900ms ease-out 2; }
@keyframes dash-jump-ring {
  0%   { box-shadow: 0 0 0 0 rgba(40, 110, 160, .45), var(--shadow); }
  100% { box-shadow: 0 0 0 12px rgba(40, 110, 160, 0), var(--shadow); }
}
@media (prefers-reduced-motion: reduce) {
  .panel.is-jump-target { animation: none; outline: 3px solid var(--accent); outline-offset: 2px; }
}
.delta.up { color: var(--lesson); }
.delta.warn { color: var(--absent); }
.delta.flat { color: var(--text-faint); }

/* 要対応・お知らせ的なミニリスト */
.mini-list { display: flex; flex-direction: column; }
.mini-list-item { display: flex; align-items: center; gap: 12px; padding: 11px 2px; border-bottom: 1px solid var(--border-soft); }
.mini-list-item:last-child { border-bottom: none; }
.mini-list-item .ic { width: 34px; height: 34px; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; font-weight: 800; font-size: 13.5px; }
.mini-list-item .t { font-size: 15.5px; font-weight: 700; color: var(--text); }
.mini-list-item .s { font-size: 13px; color: var(--text-faint); }
.mini-list-item .time-tag { margin-left: auto; font-size: 13px; color: var(--text-faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* 行の右端に置くボタン（「売上管理をひらく」「この一覧へ移る」）。
   .mini-list-item は flex なので、説明文が長い行ではボタンが縮められ、
   「売／上／管／理／を／…」と縦1文字ずつに潰れていた（2026-09-17 最終レビューの実測）。
   折り返さない・縮めない、の2つで止める */
.mini-list-item .btn { white-space: nowrap; flex-shrink: 0; }
.empty-note { color: var(--text-faint); font-size: 15.5px; padding: 8px 2px; }
/* 「まだ何も選んでいない」ときに出す案内（2026-08-17）。
   空にして黙っていると「押しても何も起きない＝壊れている」と受け取られる。
   次にすべき操作を1文で言い切り、補足を1行だけ添える */
.empty-guide { text-align: center; padding: 34px 16px; }
.empty-guide i { font-size: 31px; color: var(--accent-dim); }
.empty-guide .t { margin: 12px 0 6px; font-size: 17px; font-weight: 800; color: var(--text); }
.empty-guide .s { margin: 0 auto; max-width: 460px; font-size: 14px; line-height: 1.75; color: var(--text-dim); }

/* カレンダー（休館日・振替先・自習予約のすべてで共通利用） */
.cal-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.cal-nav .cal-month-label { font-size: 16px; font-weight: 700; color: var(--text); }
/* 「前月」「次月」の文字を入れたので、幅は中身に合わせる（28px固定だと「前／月」で折り返した）。
   高さだけ揃えて、5つのカレンダーで見た目を統一する */
.cal-nav button.btn-link { background: var(--surface-2); border: 1px solid var(--border); color: var(--text-dim); height: 32px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 700; padding: 0 11px; white-space: nowrap; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: 5px; }
.cal-nav button.btn-link:hover { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-dim); }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.cal-dow { text-align: center; font-size: 13px; font-weight: 700; color: var(--text-faint); padding: 4px 0 8px; }
.cal-day {
  aspect-ratio: 1; border-radius: 10px; background: var(--surface-2); border: 1.5px solid transparent;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  font-size: 14px; font-weight: 600; color: var(--text-dim); cursor: pointer; position: relative;
  transition: transform .12s, box-shadow .12s;
}
.cal-day.empty { visibility: hidden; cursor: default; }
.cal-day:hover { transform: scale(1.08); box-shadow: var(--shadow); z-index: 2; }
.cal-day.today { border-color: var(--accent-dim); color: var(--text); font-weight: 800; }
/* 保護者が自分で予約できる受付期間の色分け（2026-09-11 No.294、自習予約状況カレンダー）。
   本部はどちらの日も選べるままなので disabled にはしない（見た目だけの違い）。
   受付期間外は縞模様にして、色だけに頼らず伝わるようにする（.cal-mark と同じ考え方）。
   .selected / .disabled はこのあとに定義しているので、重なったときはそちらが勝つ */
.cal-day.cal-day-in-reception { background: var(--accent-soft); }
.cal-day.cal-day-out-reception {
  background: repeating-linear-gradient(135deg, var(--surface) 0 6px, var(--border-soft) 6px 12px);
  color: var(--text-faint);
}
/* 選んだ日は白抜き。--accent(#2bacf0) の上では白文字が 2.54:1 で沈むので、
   .btn-primary / .act-decide と同じ濃い青にする（5.81:1）。
   スタッフアプリの .tea-cal-day.selected と同じ見た目（2026-09-11 トンマナ合わせ） */
.cal-day.selected { background: var(--accent-deep); border-color: var(--accent-deep); color: var(--accent-ink); transform: scale(1.06); box-shadow: var(--shadow-hover); }
.cal-day.disabled { opacity: .35; cursor: default; }
.cal-day.disabled:hover { transform: none; box-shadow: none; }
/* 日付に付ける印。色だけの点（.dot）は廃止し、必ず1文字を伴わせる（2026-08-18）。
   「臨時座席あり（橙）」と「休み（赤）」が並ぶ臨時座席設定のカレンダーでは、
   色しか手がかりが無いと色覚に特性のある方が区別できなかった。
   意味を持つ色（橙＝臨時座席／赤＝休み）はそのまま、形と文字を足しただけ */
.cal-marks { display: flex; gap: 3px; }
.cal-mark {
  min-width: 20px; height: 20px; padding: 0 2px; border-radius: 4px; border: 1px solid transparent;
  font-size: 13px; font-weight: 800; line-height: 18px; text-align: center; font-style: normal;
  display: inline-flex; align-items: center; justify-content: center;
}
.cal-mark-ticket { background: var(--ticket-bg); border-color: var(--ticket); color: var(--ticket-deep); }
.cal-mark-absent { background: var(--absent-bg); border-color: var(--absent); color: var(--absent-deep); }
/* 選択中の日は地が濃い青になる。印の地は白のままにして、文字が沈まないようにする */
.cal-day.selected .cal-mark { background: var(--surface); }
.cal-legend { display: flex; gap: 14px; margin-top: 16px; flex-wrap: wrap; }
.cal-legend span { display: flex; align-items: center; gap: 5px; font-size: 13px; color: var(--text-faint); font-weight: 600; }

.cal-slot-list { display: flex; flex-direction: column; gap: 8px; }
.cal-slot-toggle {
  display: flex; justify-content: space-between; align-items: center; padding: 13px 16px;
  border: 1.5px solid var(--border-soft); border-radius: var(--radius-sm); cursor: pointer; font-size: 17px; font-weight: 700; transition: .15s;
  background: var(--surface);
}
.cal-slot-toggle:hover { border-color: var(--accent-dim); }
.cal-slot-toggle.closed { background: var(--absent-bg); border-color: #f0a8a3; color: #b7392f; }
.cal-slot-toggle.pending { border-color: var(--ticket); box-shadow: 0 0 0 2px var(--ticket-bg); }
.cal-slot-toggle .status { font-size: 13.5px; font-weight: 700; }
/* 閲覧のみのときは、押せそうな見た目（カーソル・ホバー）をやめる */
.cal-slot-toggle.read-only { cursor: default; }
.cal-slot-toggle.read-only:hover { border-color: var(--border-soft); }
.cal-slot-toggle.read-only.closed:hover { border-color: #f0a8a3; }

/* 予定の詳細カード（振替管理・出欠修正など、テーブルではなくカードで見せる） */
.detail-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; }
.detail-head .d { font-size: 18px; font-weight: 800; color: var(--text); }
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 99px; font-size: 13px; font-weight: 700; border: 1px solid transparent; }
/* 文字は濃い版（*-deep）を使う。地の色＝そのカテゴリの意味を持つ色は変えていない。
   基底のバッジだけ淡い文字のまま取り残されており（振替のバッジは既に濃い版だった）、
   実機で 2.52:1 しか無かった（2026-08-18 遼様の指摘「読みづらい」を実測して確認） */
.badge-lesson { background: var(--lesson-bg); color: var(--lesson-deep); }
.badge-ticket { background: var(--ticket-bg); color: var(--ticket-deep); }
.badge-extra  { background: var(--extra-bg); color: var(--extra-deep); }
.badge-absent { background: var(--absent-bg); color: var(--absent-deep); }
.badge-study { background: var(--study-bg); color: var(--study-deep); }
.badge-trial  { background:var(--trial-bg); color:var(--trial-deep); }   /* 体験授業=ティール（無料） */
.badge-service{ background:#fbe7f0; color:var(--service-deep); }   /* サービス=ピンク（無料） */
/* 振替は**元の種別と同じ色**で出す（2026-09-18 遼様指示）。
   「通常授業」と「通常授業（振替）」、「季節講習」と「季節講習（振替）」…が同じ色になり、
   振替かどうかは文字の「（振替）」だけで見分ける。
   以前あった振替専用の色（.badge-*-mk＝淡い地＋枠線）は廃止した */

.slot-card { border: 1px solid var(--border-soft); background: var(--surface-2); border-radius: 14px; padding: 15px 16px; margin-top: 12px; }
.slot-card .time { font-size: 20px; font-weight: 800; color: var(--text); margin-bottom: 11px; font-variant-numeric: tabular-nums; }
.slot-actions { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 10px; }
.act-btn { flex: 1; min-width: 110px; padding: 10px 11px; border-radius: 10px; font-size: 14px; font-weight: 700; text-align: center; cursor: pointer; border: 1.5px solid; transition: transform .12s; }
.act-btn:active { transform: scale(.96); }
/* 2026-08-18 遼様の指摘「振替管理はコントラストが弱く読みづらい」。実機で測ったところ
   振替=2.52:1／欠席=2.97:1 しかなかった（AAの4.5:1に届かない）。
   文字を濃い版に差し替え、枠線も地と同じ色をやめて輪郭が出るようにした。
   意味を持つ色（振替＝緑／欠席＝赤）は変えていない */
.act-makeup { color: var(--lesson-deep); border-color: var(--lesson); background: var(--lesson-bg); }
.act-absent { color: var(--absent-deep); border-color: var(--absent); background: var(--absent-bg); }
/* 「振替先を決める」は白抜き。--accent(#2bacf0) の上だと白文字が 2.34:1 で沈むため、
   同じ青の濃い版に置き換えた（5.8:1）。色相は変えていない */
.act-decide { color: var(--accent-ink); background: var(--accent-deep); border-color: var(--accent-deep); }

/* 生徒選択（振替管理・自習代行予約など） */
.student-picker { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
.student-picker select {
  flex: 1; min-width: 200px; padding: 10px 13px; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  font-size: 16px; font-family: inherit; color: var(--text); background: var(--surface);
}
.student-picker select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* 生徒の複数選択グリッド（一括付与など） */
.student-check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px; max-height: 260px; overflow-y: auto; padding: 12px; border: 1.5px solid var(--border-soft); border-radius: var(--radius-sm); background: var(--surface-2); }
.student-check-item { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1.5px solid var(--border); border-radius: 8px; cursor: pointer; font-size: 15.5px; background: var(--surface); }
.student-check-item.checked { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: bold; }
.student-check-item input { pointer-events: none; }

/* ===== 定員設定（2026-08-17 タスク指向に刷新） =====
   「何をなさいますか？」のカードから入り、選んだ作業に必要なものだけを出す。
   マス目は1コマ1マスにまとめ、「22席（授 18／自 4）」と読める形にした。 */

/* 入口の一行まとめ */
.cap-now { display: flex; flex-wrap: wrap; gap: 9px 30px; }
.cap-now-i { display: flex; align-items: baseline; gap: 9px; }
.cap-now-i .lb { font-size: 13px; font-weight: 800; color: var(--text-dim); white-space: nowrap; }
.cap-now-i .vl { font-size: 14px; font-weight: 700; color: var(--text); }
.cap-lead { font-size: 18px; font-weight: 800; color: var(--text); margin: 22px 0 14px; }

/* やりたいことのカード */
.cap-group { margin-bottom: 22px; }
.cap-group-label { font-size: 13px; font-weight: 800; color: var(--text-dim); letter-spacing: .06em; margin: 0 0 10px; display: flex; align-items: center; gap: 7px; }
.cap-group-label i { color: var(--text-faint); font-size: 13.5px; }
.cap-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 14px; }
.cap-card {
  display: flex; align-items: flex-start; gap: 14px; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: 16px 18px; box-shadow: var(--shadow); cursor: pointer; font-family: inherit; color: inherit;
  transition: transform .15s, box-shadow .15s, border-color .15s;
}
.cap-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); border-color: var(--accent-dim); }
.cap-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cap-card .ic {
  width: 42px; height: 42px; border-radius: 12px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center; font-size: 20px;
  background: var(--accent-soft); color: var(--accent);
}
.cap-card.is-season .ic { background: var(--ticket-bg); color: var(--ticket-deep); }
.cap-card.is-lock .ic { background: var(--surface-3); color: var(--text-quiet); }
.cap-card .tx { flex: 1; min-width: 0; }
.cap-card .ttl { display: block; font-size: 17px; font-weight: 800; color: var(--text); line-height: 1.5; }
.cap-card .ds { display: block; font-size: 14px; color: var(--text-dim); margin-top: 4px; line-height: 1.65; }
.cap-card .st { display: block; font-size: 13px; color: var(--text-dim); margin-top: 8px; font-weight: 700; }
.cap-card .ar { color: var(--text-faint); margin-top: 13px; flex: 0 0 auto; font-size: 15.5px; }
/* 手順の番号。橙地に白抜きは 2.51:1 しか出ないので濃い文字を載せる */
.cap-card .stepnum {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%; background: var(--ticket); color: var(--text);
  font-size: 13px; font-weight: 800; margin-right: 7px; vertical-align: 1px;
}
.cap-lockchip {
  display: inline-flex; align-items: center; gap: 4px; background: var(--surface-3); color: var(--text);
  border-radius: 99px; padding: 2px 8px; font-size: 13px; font-weight: 800; margin-left: 8px; vertical-align: 1px;
}
.cap-lockchip i { font-size: 11px; }

/* 戻る・作業の見出し */
.cap-back {
  display: inline-flex; align-items: center; gap: 7px; background: none; border: none;
  padding: 4px 0; margin: 0 0 12px; color: var(--text-dim); font-size: 14px; font-weight: 700;
  cursor: pointer; font-family: inherit;
}
.cap-back:hover { color: var(--accent); }
.cap-back i { font-size: 13px; }
.cap-task-hd { display: flex; align-items: center; gap: 11px; margin: 0 0 16px; flex-wrap: wrap; }
.cap-task-hd .ic {
  width: 38px; height: 38px; border-radius: 11px; flex: 0 0 auto; font-size: 18px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.cap-task-hd .ic.is-season { background: var(--ticket-bg); color: var(--ticket-deep); }
.cap-task-hd h3 { margin: 0; font-size: 20px; font-weight: 800; }
.panel.is-season { border-color: #f6d3a8; }

/* マス目の読み方（見本のマスと並べて置き、凡例を探させない） */
.cap-read {
  display: flex; gap: 20px; align-items: center; flex-wrap: wrap;
  background: var(--surface-2); border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm); padding: 14px 16px; margin-bottom: 18px;
}
.cap-read-sample { width: 126px; flex: 0 0 auto; display: flex; }
.cap-read-list { flex: 1; min-width: 280px; display: flex; flex-direction: column; gap: 6px; list-style: none; margin: 0; padding: 0; }
.cap-read-list li { display: flex; align-items: baseline; gap: 10px; }
.cap-read-list .rd { font-size: 14px; color: var(--text-dim); line-height: 1.65; }
.cap-read-list b { color: var(--text); font-weight: 800; }
.cap-read-list .k { flex: 0 0 auto; min-width: 62px; text-align: center; border-radius: 99px; padding: 2px 8px; font-size: 13px; font-weight: 800; }
.k-total { background: var(--accent-soft); color: var(--accent-deep); }
.k-lesson { background: var(--lesson-bg); color: var(--lesson-deep); }
.k-study { background: var(--study-bg); color: var(--study-deep); }
.k-zero { background: transparent; border: 1px dashed var(--border); color: var(--text-dim); }
/* 短い版（講習期の画面はこちら） */
.cap-minilegend { display: flex; gap: 8px 18px; flex-wrap: wrap; align-items: center; font-size: 13px; font-weight: 700; color: var(--text-dim); margin-bottom: 12px; }
.cap-minilegend > span { display: inline-flex; align-items: center; gap: 6px; }
.cap-minilegend .k { min-width: 56px; text-align: center; border-radius: 99px; padding: 2px 7px; font-size: 13px; font-weight: 800; }

/* コマ×曜日のマス目。列幅の下限は96px（112pxにすると1366pxのノートPCで日曜が切れる） */
.cap-grid-wrap { overflow-x: auto; }
/* 下限は「1100px の窓でも日曜の列まで初期表示に入る」ところまで詰めた（2026-08-17）。
   112 + 82×7 + 6×8 = 734px。以前の 840px だと 1180px 以下で日曜だけが右に隠れ、
   横スクロールに気づかないと「日曜は設定できない」と読めてしまっていた。
   広い画面では列は 1fr で伸びるので、見た目は今までどおり */
.cap-grid { display: grid; grid-template-columns: 112px repeat(7, minmax(82px, 1fr)); gap: 6px; min-width: 734px; align-items: stretch; }
/* 曜日とコマ時刻は「どの枠を見ているか」を決める見出しなので薄くしない */
.cap-hd { font-size: 13px; font-weight: 800; color: var(--text); text-align: center; padding: 0 0 4px; }
.cap-hd.is-sat { color: var(--study-deep); }
.cap-hd.is-sun { color: var(--absent-deep); }
.cap-hd-slot { text-align: left; }
.cap-slot { display: flex; flex-direction: column; justify-content: center; padding: 0 10px 0 2px; }
/* 行見出しは時刻そのもの（記号は出さない）。1行に収めるため 112px の列幅に合わせて詰める */
.cap-slot .stt { font-size: 14px; font-weight: 800; color: var(--text); white-space: nowrap; font-variant-numeric: tabular-nums; }
.cap-cw { display: flex; }
.cap-cell {
  flex: 1; min-width: 0; min-height: 66px; padding: 8px 4px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  border: 1.5px solid var(--border); border-radius: 12px; background: var(--surface-2); cursor: pointer;
  font-family: inherit; color: var(--text);
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.cap-cell:hover { border-color: var(--accent); background: var(--surface); box-shadow: 0 0 0 3px var(--accent-soft); }
.cap-cell:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cap-cell .tt { font-size: 24px; font-weight: 800; color: var(--text); line-height: 1; font-variant-numeric: tabular-nums; }
.cap-cell .tt .u { font-size: 13px; font-weight: 700; color: var(--text); margin-left: 1px; }
.cap-cell .sp { display: flex; gap: 4px; flex-wrap: wrap; justify-content: center; }
.cap-cell .pl, .cap-cell .ps { font-size: 13px; font-weight: 800; border-radius: 99px; padding: 1px 6px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cap-cell .pl { background: var(--lesson-bg); color: var(--lesson-deep); }
.cap-cell .ps { background: var(--study-bg); color: var(--study-deep); }
/* 0席は「開けていない枠」。意図的に沈めるが、読めなくはしない */
.cap-cell.is-zero { background: transparent; border-style: dashed; border-color: var(--border-soft); }
.cap-cell.is-zero .tt { font-size: 18px; font-weight: 700; color: var(--text-dim); }
.cap-cell.is-changed { border-color: var(--ticket); background: var(--ticket-bg); }
.cap-cell.is-changed:hover { border-color: var(--ticket); background: var(--ticket-bg); box-shadow: 0 0 0 3px rgba(240,138,31,.18); }
/* 見本と、閲覧しかできない人のマス。押せる余地が無いことを見た目でも示す */
.cap-cell.is-demo, .cap-cell.is-static { cursor: default; }
.cap-cell.is-demo:hover, .cap-cell.is-static:hover { border-color: var(--border); background: var(--surface-2); box-shadow: none; }
.cap-cell.is-static.is-zero:hover { border-color: var(--border-soft); background: transparent; }

/* 押したマスだけが入力欄に変わる */
.cap-edit {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px;
  border: 1.5px solid var(--accent); border-radius: 12px; background: var(--surface);
  box-shadow: 0 0 0 3px var(--accent-soft); padding: 7px 8px 8px;
}
.cap-edit .ce-hd { font-size: 13px; font-weight: 800; color: var(--accent-deep); text-align: center; }
/* 曜日と時刻を必ず2行に割る。マスの幅（82px）では「月曜17:50 - 19:10」が中途半端に折り返す */
.cap-edit .ce-hd-t { display: block; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cap-edit .ce-r { display: flex; align-items: center; gap: 6px; }
.cap-edit .ce-r > span { font-size: 13px; font-weight: 800; color: var(--text-dim); width: 32px; flex: 0 0 auto; }
.cap-edit .ce-in {
  flex: 1; min-width: 0; width: 100%; padding: 4px; text-align: center;
  border: 1.5px solid var(--border); border-radius: 8px; background: var(--surface);
  font-family: inherit; font-size: 15.5px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums;
}
.cap-edit .ce-in:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.cap-edit .ce-calc { font-size: 13px; font-weight: 700; color: var(--text-dim); text-align: center; }
.cap-edit .ce-calc b { color: var(--lesson-deep); font-size: 14px; }
.cap-edit .ce-act { display: flex; gap: 5px; }
.cap-edit .ce-btn {
  flex: 1; border: 1px solid var(--border); background: var(--surface-2); color: var(--text-dim);
  border-radius: 8px; padding: 4px 0; font-size: 13px; font-weight: 800; cursor: pointer; font-family: inherit;
}
.cap-edit .ce-btn.is-ok { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* 保存できたときの帯 */
.cap-saved {
  display: flex; align-items: center; gap: 9px; background: var(--lesson-bg);
  border: 1px solid #a8e0c1; border-radius: var(--radius-sm);
  padding: 11px 14px; font-size: 14px; font-weight: 700; color: var(--lesson-deep); margin-top: 14px;
}

/* 変更の履歴と「直前の保存を取り消す」（2026-09-26 取り消し機能 第2弾） */
.cap-history { margin-top: 18px; }
.cap-history:empty { display: none; }
.cap-hist-hd { font-size: 15px; font-weight: 800; color: var(--text); margin-bottom: 8px; }
.cap-hist-sub { font-size: 13px; font-weight: 600; color: var(--text-dim); margin-left: 10px; }
.cap-hist-item { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 10px 13px; margin-bottom: 8px; background: var(--surface); }
.cap-hist-item.is-undone { background: var(--surface-2); color: var(--text-dim); }
.cap-hist-meta { font-size: 13px; font-weight: 700; color: var(--text-dim); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cap-hist-cells { margin: 6px 0 0; padding-left: 1.2em; font-size: 14px; line-height: 1.6; }
.cap-hist-undo-note { font-size: 13px; margin-top: 6px; }
.cap-hist-undo-btn { margin-top: 8px; }

/* 手順（1→2→3） */
.cap-steps { display: flex; align-items: center; gap: 0; margin: 0 0 18px; flex-wrap: wrap; }
.cap-stepdot { display: flex; align-items: center; gap: 9px; }
/* まだ通っていない手順は白抜きの丸。淡い面に淡い字を置くと数字が消える */
.cap-stepdot .n {
  width: 29px; height: 29px; border-radius: 50%; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 800;
  background: var(--surface); border: 1.5px solid var(--border); color: var(--text-dim);
}
.cap-stepdot .l { font-size: 14px; font-weight: 700; color: var(--text-dim); white-space: nowrap; }
.cap-stepdot.is-on .n { background: var(--ticket); border-color: var(--ticket); color: var(--text); }
.cap-stepdot.is-on .l { color: var(--text); }
.cap-stepdot.is-done .n { background: var(--lesson-bg); border-color: var(--lesson-bg); color: var(--lesson-deep); }
.cap-steparrow { flex: 1 1 24px; min-width: 20px; height: 2px; background: var(--border); margin: 0 12px; border-radius: 2px; }
.cap-stepbox { background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 16px 18px; }
/* 手順の箱は薄い水色なので、その上のマスは白にしないと席のあるマスが背景に溶ける */
.cap-stepbox .cap-cell { background: var(--surface); }
.cap-stepbox .cap-cell.is-zero { background: transparent; }
.cap-stepbox .cap-cell.is-changed { background: var(--ticket-bg); }
.cap-stepnote { font-size: 15.5px; color: var(--text-dim); line-height: 1.75; margin: 0 0 14px; }
.cap-stepnote b { color: var(--text); font-weight: 800; }
.cap-hint { display: flex; align-items: center; gap: 8px; margin: 14px 0 0; font-size: 14px; font-weight: 700; color: var(--ticket-deep); }
.cap-stepact { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.cap-stepact.is-center { justify-content: center; }
.cap-toolrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.cap-confirm { grid-template-columns: 110px minmax(0, 1fr); margin-bottom: 16px; }

/* 登録できたときの画面 */
.cap-done { text-align: center; padding: 26px 16px 8px; }
.cap-done .ck {
  width: 58px; height: 58px; border-radius: 50%; background: var(--lesson-bg); color: var(--lesson);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 14px; font-size: 28px;
}
.cap-done h4 { font-size: 20px; font-weight: 800; margin: 0 0 10px; }
.cap-done p { font-size: 15.5px; color: var(--text-dim); line-height: 1.9; margin: 0; }
.cap-done b { color: var(--text); font-weight: 800; }

/* 期間と座席数の関係を示す帯 */
.cap-link {
  display: flex; align-items: flex-start; gap: 9px; background: var(--ticket-bg);
  border: 1px solid #f3cfa0; border-radius: var(--radius-sm);
  padding: 11px 14px; font-size: 14px; color: var(--ticket-deep); line-height: 1.75; margin-bottom: 16px;
}
.cap-link i { margin-top: 4px; flex: 0 0 auto; }
.cap-link b { font-weight: 800; }
.cap-link .btn-link { color: var(--ticket-deep); font-weight: 700; }

/* 定員設定と臨時座席設定のちがい */
.cap-compare { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
.cap-compare .cc { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 14px 16px; background: var(--surface-2); }
.cap-compare .cc.is-here { background: var(--accent-soft); border-color: var(--accent-dim); }
.cap-compare .cc h5 { margin: 0 0 8px; font-size: 15.5px; font-weight: 800; color: var(--text); display: flex; align-items: center; gap: 7px; }
.cap-compare .cc h5 i { color: var(--accent); font-size: 13.5px; }
.cap-compare .cc p { font-size: 14px; color: var(--text); line-height: 1.75; margin: 0; }
.cap-compare .cc b { font-weight: 800; }

/* 講習期間の状態チップ。共通の .tag-active/.tag-withdrawn は「生徒の在籍状況」の色で
   意味が違ううえ、淡色どうしの重なりで字が消える（終了=1.86:1）ため専用に持つ */
.cap-tag { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 99px; font-size: 13px; font-weight: 700; white-space: nowrap; margin-left: auto; }
.cap-tag-now { background: var(--lesson-bg); color: var(--lesson-deep); }
.cap-tag-next { background: var(--ticket-bg); color: var(--ticket-deep); }
.cap-tag-past { background: var(--surface-2); border: 1px solid var(--border); color: var(--text-quiet); }
.cap-tag + .btn-link { margin-left: 4px; }
.cap-badge-season { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 99px; font-size: 13px; font-weight: 700; background: var(--ticket-bg); color: var(--ticket-deep); }
/* 講習期間の日付は読ませたい実データなので、共通の薄いグレーにしない */
#season-list .s, #cap-all-periods .s { color: var(--text-dim); }
#season-list .rw, #cap-all-periods .rw { flex: 1; min-width: 0; }

@media (max-width: 1100px) {
  .cap-cards { grid-template-columns: minmax(0, 1fr); }
  .cap-read-sample { width: 110px; }
}

.legend-inline { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; font-size: 13px; color: var(--text-faint); }
.legend-inline span { display: flex; align-items: center; gap: 6px; }
.legend-inline .sw { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

/* 臨時座席設定：1コマ分の編集カード */
.sp-slot { border: 1.5px solid var(--border-soft); border-radius: var(--radius-sm); padding: 12px 14px; background: var(--surface); }
.sp-slot.is-closed { background: var(--absent-bg); border-color: #f0a8a3; }
.sp-slot.is-special { border-color: var(--ticket); box-shadow: 0 0 0 2px var(--ticket-bg); }
.sp-slot-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sp-slot-time { font-size: 17px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
/* 「ふだんは何席か」（2026-09-11 遼様のご要望）。
   入力欄の数字が「もとの数」なのか「これから設定する数」なのかを取り違えないよう、
   ふだんの数は入力欄の上に、文章として置く（入力欄と同じ形の数字を並べると見分けが付かない）。
   ふつうの文章として折り返させる——flex にすると「ふだんは」と「合計14席」が
   別々の箱になり、狭いときに変なところで改行する（ブラウザで見て直した） */
.sp-usual { margin: 10px 0 0; font-size: 14px; color: var(--text-dim); line-height: 1.7; }
.sp-usual strong { font-weight: 800; color: var(--text); }
.sp-usual i { margin-right: 6px; color: var(--text-faint); }
.sp-usual-none { color: var(--absent-deep); }
.sp-usual-none strong { color: var(--absent-deep); }
/* 入力欄が何を決める欄なのかの見出し。「ふだん」との言い分けをここで付ける */
.sp-setting-lbl { margin: 12px 0 0; font-size: 13.5px; font-weight: 800; color: var(--text-dim); }
.sp-slot-body { display: flex; align-items: flex-end; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.sp-num { display: flex; flex-direction: column; gap: 4px; }
.sp-num label { font-size: 13px; font-weight: 700; color: var(--text-faint); }
.sp-num input {
  width: 62px; padding: 8px; text-align: center; border: 1.5px solid var(--border); border-radius: 8px;
  font-family: inherit; font-size: 15.5px; font-weight: 700; color: var(--text); background: var(--surface);
  font-variant-numeric: tabular-nums;
}
.sp-num input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.sp-num .derived { width: 62px; padding: 8px; text-align: center; border: 1.5px dashed var(--border); border-radius: 8px; color: var(--text-dim); font-size: 15.5px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* 日別パネル内の追加ボックス（自習の代行予約など） */
.add-box { margin-top: 18px; padding-top: 16px; border-top: 1px dashed var(--border); }
.add-box h4 { margin: 0 0 12px; font-size: 14px; font-weight: 800; color: var(--text-dim); display: flex; align-items: center; gap: 7px; }

/* カレンダーのマス目に出す件数バッジ */
.cal-count {
  position: absolute; top: 2px; right: 2px; min-width: 20px; height: 20px; padding: 0 4px;
  border-radius: 99px; background: var(--study); color: #fff; font-size: 13px; font-weight: 800;
  display: flex; align-items: center; justify-content: center; line-height: 1;
}
.cal-day.selected .cal-count { background: var(--accent-ink); color: var(--accent-deep); }

/* 操作ログ */
.audit-table td { vertical-align: top; }
.audit-when { font-size: 13.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.audit-who { display: flex; align-items: center; gap: 8px; }
.audit-what { font-weight: 700; color: var(--text); }
.audit-detail { font-size: 13.5px; color: var(--text-dim); margin-top: 3px; }
.audit-cat { display: inline-block; width: 27px; height: 27px; border-radius: 8px; text-align: center; line-height: 27px; font-size: 13px; flex: 0 0 auto; }

/* 保存バー（休館日タブなどの一括保存） */
.save-bar {
  position: sticky; bottom: 0; margin-top: 16px; padding: 14px 18px; background: var(--surface);
  border: 1.5px solid var(--accent-dim); border-radius: var(--radius-sm); box-shadow: var(--shadow-hover);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.save-bar .pending-count { font-size: 15.5px; color: var(--accent-deep); font-weight: bold; }
.save-bar .btns { display: flex; gap: 9px; }
/* 1つの画面に保存バーが2つ並ぶ場所（定員設定「すべての設定をまとめて見る」）用。
   両方を画面下に貼り付けると重なって読めなくなるので、表の直下に置く */
.save-bar.is-inline { position: static; }
/* 出欠：まだ送っていない指定であることを名前の横にも書く（枠線の点線だけだと見落とす） */
.ov-pending-tag { display: inline-block; margin-left: 4px; padding: 1px 6px; border-radius: 999px; background: var(--ticket); color: #fff; font-size: 13px; font-weight: 800; }

/* 休館日設定：まとめて設定バー・営業していない枠 */
.bulk-bar { display: flex; align-items: center; gap: 8px; padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-sm); margin-bottom: 4px; flex-wrap: wrap; }
.bulk-bar .bulk-label { font-size: 13px; font-weight: 700; color: var(--text-faint); margin-right: 2px; }
.cal-slot-toggle.not-operating { opacity: .5; cursor: default; background: repeating-linear-gradient(45deg, var(--surface-2), var(--surface-2) 6px, var(--surface) 6px, var(--surface) 12px); }
.cal-slot-toggle.not-operating:hover { border-color: var(--border-soft); }
.cal-slot-toggle.not-operating .status { color: var(--text-faint); font-weight: 600; }

/* 定員削減の影響確認モーダル。
   高さの縛りは .modal-xwide と同じ作法にする（2026-09-17 最終レビュー）。
   .modal-overlay は position:fixed・overflow-y:visible なので、中身が縦に長いと
   ポップアップが画面からはみ出しても**どこもスクロールしない**。
   「未来の授業をお休みにする」（overtaken.js）が 885px になり、1366×768・1024×768 では
   題名と×が画面の上に消え、実行ボタンが12pxしか見えなかった（実測）。
   90vh で切って、中身のほうをスクロールさせる */
.modal-box.modal-wide { width: 520px; max-width: 92vw; max-height: 90vh; overflow-y: auto; }
.impact-list { max-height: 240px; overflow-y: auto; margin: 12px 0; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); }
.impact-item { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--border-soft); font-size: 14px; }
.impact-item:last-child { border-bottom: none; }
.impact-date { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.impact-num { color: var(--absent); font-weight: 700; font-variant-numeric: tabular-nums; }
/* 休館日の影響確認（2026-08-31 WP7）：コマの横に休みの種類、下に取り消される自習予約の生徒、
   期限まで14日未満の振替（決定13）は赤い枠で名指し */
.impact-kind { font-size: 13px; font-weight: 700; color: var(--text-dim); margin-left: 6px; }
.impact-sub { padding: 4px 12px 9px; font-size: 13.5px; color: var(--text-dim); border-bottom: 1px solid var(--border-soft); }
.impact-urgent { margin-top: 12px; padding: 10px 12px; background: var(--absent-bg); border: 1px solid #f0a8a3; border-radius: var(--radius-sm); color: var(--absent-deep); font-size: 14px; }
.impact-urgent p { margin: 0 0 6px; }
.impact-urgent ul { margin: 0; padding-left: 20px; }
.impact-urgent li { font-variant-numeric: tabular-nums; }

/* 休館日設定：1コマ＝1行。営業／授業のみ休講／完全休館の3択（2026-08-31 WP7）。
   行そのものは押さない（3択のボタンを押す）ので、行のカーソル・ホバーは消す */
.cal-slot-toggle.hol-row { flex-direction: column; align-items: stretch; gap: 10px; cursor: default; }
.cal-slot-toggle.hol-row:hover { border-color: var(--border-soft); }
.cal-slot-toggle.hol-row.closed:hover { border-color: #f0a8a3; }
.cal-slot-toggle.hol-row.pending:hover { border-color: var(--ticket); }
/* 授業のみ休講は「休み」だが自習室は開いている＝赤ではなく橙（臨時座席と同じ「例外の色」） */
.cal-slot-toggle.hol-row.lesson-only { background: var(--ticket-bg); border-color: #f0c48f; color: var(--ticket-deep); }
.cal-slot-toggle.hol-row.lesson-only:hover { border-color: #f0c48f; }
.hol-row-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.hol-row .hol-seg { align-self: flex-start; }
.hol-row .hol-seg .seg-btn { font-size: 14px; padding: 7px 12px; }
.hol-study { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 14px; font-weight: 700; }
.hol-study label { font-size: 13.5px; color: var(--text-dim); }
.hol-study input { width: 84px; padding: 8px 10px; border: 1.5px solid var(--border); border-radius: 8px; font-size: 16px; font-family: inherit; text-align: center; font-variant-numeric: tabular-nums; background: var(--surface); color: var(--text); }
.hol-study input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.hol-study .note { font-size: 13px; font-weight: 600; color: var(--text-faint); }
#impact-modal .modal-box p { margin: 0; }

/* 固定時間割の編集 */
.modal-box.modal-xwide { width: 780px; max-width: 94vw; max-height: 90vh; overflow-y: auto; }
.sched-grid-wrap { overflow-x: auto; margin: 14px 0 8px; }
.sched-grid { border-collapse: separate; border-spacing: 5px; width: 100%; }
.sched-grid th { font-size: 13px; font-weight: 700; color: var(--text-faint); padding-bottom: 4px; }
.sched-grid th.slot-head { text-align: left; }
/* 行見出しはコマの呼び名＝時刻そのもの（記号は現場の語彙ではないので出さない） */
.sched-grid td.slot-label { font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; text-align: left; padding-right: 8px; font-variant-numeric: tabular-nums; }
.sched-cell {
  width: 100%; min-width: 46px; height: 38px; border: 1.5px solid var(--border-soft); border-radius: 9px;
  background: var(--surface-2); cursor: pointer; transition: .12s; font-family: inherit; font-size: 13px; color: var(--text-faint);
}
.sched-cell:hover { border-color: var(--accent-dim); transform: translateY(-1px); }
.sched-cell.on { background: var(--lesson); border-color: var(--lesson); color: #fff; font-weight: 800; }
.sched-cell.closed { background: repeating-linear-gradient(45deg, var(--surface-2), var(--surface-2) 5px, var(--surface) 5px, var(--surface) 10px); cursor: default; opacity: .5; }
.sched-cell.closed:hover { border-color: var(--border-soft); transform: none; }
/* 押せないマス（体験中／授業席が0）。押せるマスと同じ見た目のまま disabled にすると、
   静止画では押せる・押せないの区別が付かない。指の形と浮き上がりをここでまとめて外す
   （JS側でインラインstyleを当てていたのを、CSSを読めば分かる形に戻した 2026-08-22） */
.sched-cell.is-locked { cursor: default; }
.sched-cell.is-locked:hover { border-color: var(--border-soft); transform: none; }
/* 「かよう」が入ったまま押せないマス（体験中）。UI指示書4-5「押せないボタンは淡い面＋濃い文字」。
   主色べた塗り＋白抜きのまま disabled にすると、押せるマスと1ピクセルも変わらない。
   面を淡い緑・文字を濃い緑にし（#1d7a48 on #e2f6ea = 4.73:1。白抜きの2.85:1より読める）、
   枠を破線にして色以外でも違いが出るようにする（同4-1 色だけで情報を伝えない）。
   意味の色（授業＝緑）は変えず、既存トークンだけで組んでいる。チェックの印は濃い緑に変わるが
   印そのものは残るので、何コマ入っているかは読める */
.sched-cell.on.is-locked {
  background: var(--lesson-bg); border-color: var(--lesson); border-style: dashed; color: var(--lesson-deep);
}
.sched-cell.on.is-locked:hover { border-color: var(--lesson); transform: none; }
.future-note { background: var(--ticket-bg); border: 1px solid #f3cfa0; border-radius: var(--radius-sm); padding: 11px 14px; font-size: 14px; color: #b3630f; margin-bottom: 14px; }
.future-note .btn-link { color: #b3630f; }
/* 旧「保存するとこうなります」の予告（.future-note.is-pending / .pending-mark）は削除した。
   切替予定の取り消しと申し送りの対応済みを、押した時点の確認モーダル＋即時反映に戻したため、
   「保存を待っている状態」そのものが無くなった（2026-08-18 遼様ご指示）。
   効いていないクラスを残すと、次に読む人が「どこで付くのか」を探すことになる */

/* 権限で更新系を隠したタブの先頭に1行だけ置く注意書き（なぜ操作できないかを伝える）。
   「できないこと」の説明なので、警告色ではなく落ち着いた見た目にして視線を奪わない */
.readonly-note {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface-2); border: 1px solid var(--border-soft); border-left: 3px solid var(--text-faint);
  border-radius: var(--radius-sm); padding: 10px 14px; font-size: 14px; color: var(--text-dim); margin-bottom: 16px;
}
.readonly-note i { color: var(--text-faint); font-size: 13.5px; }
/* 見た目は readonly-note と同じ、権限とは関係のない補足。
   markTabReadOnly が「.readonly-note が既にあるか」で置き場所を判断するため、別クラスにしてある */
.cap-note {
  display: flex; align-items: center; gap: 8px; margin: 16px 0 0;
  background: var(--surface-2); border: 1px solid var(--border-soft); border-left: 3px solid var(--text-faint);
  border-radius: var(--radius-sm); padding: 10px 14px; font-size: 14px; color: var(--text-dim);
}
.cap-note i { color: var(--text-faint); font-size: 13.5px; }

/* メンテナンス中に本部画面の上へ出しっぱなしにする帯（2026-09-12）。
   全権管理者はメンテナンス中も操作できてしまうので、これが無いと解除を忘れる。
   「気づかせる」ためのものなので、注意書き（readonly-note）とは違い警告色で出す */
.maint-banner {
  display: flex; align-items: center; gap: 8px;
  background: var(--absent-bg); border: 1px solid #b7392f; border-left: 3px solid #b7392f;
  border-radius: var(--radius-sm); padding: 10px 14px; margin-bottom: 16px;
  font-size: 15px; font-weight: 800; color: #b7392f;
}
.maint-banner i { font-size: 15px; }
/* 止める画面のチェック（3つ縦に並べる。押す場所を文字まで広げる） */
.maint-check { display: flex; align-items: center; gap: 8px; font-size: 15px; cursor: pointer; padding: 2px 0; }
.maint-check input { width: 18px; height: 18px; }
/* 「この内容で切り替える」の確認。押した瞬間に全画面が止まるので、その場で一度受け止める */
.maint-confirm {
  margin-top: 14px; padding: 12px 14px; border-radius: var(--radius-sm);
  background: var(--absent-bg); border: 1px solid #b7392f;
}
.maint-confirm p { margin: 0 0 10px; font-size: 15px; font-weight: 700; color: #b7392f; }
.maint-confirm div { display: flex; gap: 8px; justify-content: flex-end; }
/* ボタンを消した箇所に残す、押せないことが分かる文字（—やコマ数など） */
.cell-plain { font-size: 14px; color: var(--text-dim); }
/* 取り返しのつかない変更の前に置く注意書き（定員設定の手順3・コマの時間帯のポップアップ） */
.warn-note {
  display: flex; align-items: flex-start; gap: 9px; background: var(--warn-bg);
  border: 1px solid #f0a8a3; border-radius: var(--radius-sm);
  padding: 11px 14px; font-size: 14px; color: var(--absent-deep); line-height: 1.7;
}
.warn-note i { margin-top: 3px; flex: 0 0 auto; }
.warn-note strong { font-weight: 800; }
.sched-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 700; color: var(--ticket); background: var(--ticket-bg); padding: 2px 8px; border-radius: 99px; margin-left: 6px; }

/* 誤タップ防止 / 未保存確認 モーダル */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(32,54,74,.4); display: flex; align-items: center; justify-content: center;
  z-index: 1000;
}
.modal-box { position: relative; background: var(--surface); border-radius: var(--radius); padding: 26px; width: 400px; box-shadow: var(--shadow-hover);
  animation: adm-modal-pop .28s cubic-bezier(.2,1.4,.4,1) both; }
/* 保護者アプリ・スタッフアプリと同じ登場の動き（2026-08-19 追加。それまで管理画面だけ
   アニメーションが無く、同じ「ポップアップが出る」操作が別物に感じる状態だった）。
   1.4 がわずかに行き過ぎて戻る動きを作り、これで「出てきた」感触が生まれる。
   .28s より長いと待たされた感じになる。動かすのは transform と opacity だけなので
   レイアウトは1pxも動かない */
@keyframes adm-modal-pop { 0%{transform: scale(.85); opacity: 0} 100%{transform: scale(1); opacity: 1} }
@media (prefers-reduced-motion: reduce) {
  /* 登場の動きは装飾なので完全に止める（中身は情報ではないため消しても失われない） */
  .modal-box { animation: none; }
}
/* 右上の×（2026-08-17）。ESC・背景クリックと合わせて、どのポップアップも同じ3つで閉じられる。
   JS（initModalDismiss）が全ポップアップに同じものを差し込むので、画面ごとに作法が違うことは起きない。
   見出しの文字と重ならないよう、h4 の右側に幅を空けてある */
.modal-x {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: 9px; background: none;
  color: var(--text-dim); font-size: 18px; cursor: pointer; font-family: inherit; line-height: 1;
}
.modal-x:hover { background: var(--surface-2); color: var(--text); border-color: var(--border); }
.modal-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.modal-box h4 { margin: 0 0 10px; padding-right: 36px; font-size: 20px; font-weight: 900; color: var(--text); display: flex; align-items: center; gap: 8px; }
.modal-box h4 i { color: var(--ticket); }
.modal-box p { font-size: 15.5px; color: var(--text-dim); line-height: 1.6; margin: 0 0 20px; }
/* 入力の誤りは赤で出す。共通の .error（1クラス）だけだと上の .modal-box p（クラス＋要素）に
   負けて本文と同じ色になり、「押したのに何も起きない」ように見えていた（2026-08-17 に確認） */
.modal-box p.error { color: var(--absent); font-weight: 700; margin-bottom: 0; }
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; }

/* ===== 売上管理（2026-08-17 積み上げグラフ化） =====
   グラフは外部ライブラリを使わず素のSVGで描く。CDNへの依存を増やさないため。 */
/* 左の余白 10px は縦軸のラベルのため。ラベルは viewBox の左端から 57px の幅に右寄せで
   置かれる（padL 66 − 9。revenue.js）が、文字を13pxに上げた（M-4b）ことで「1000万円」
   「200万円」のような太字が 4〜5px 左へはみ出し、svg の既定（overflow: hidden）で
   左端が欠けていた。svg のはみ出しを見せ、器の余白で受ける（横スクロールの器は
   余白の内側まで見せるので、ここに置いた文字は欠けない）。JS の padL を広げる直し方も
   あるが、グラフの描画は revenue.js／student-stats.js の2か所にあり、CSS 1か所で受けるほうが
   食い違わない */
.rev-chart { width: 100%; overflow-x: auto; padding-left: 10px; }
/* 下限は「1100px の窓でも3月まで初期表示に入る」ところまで詰めた（2026-08-17）。
   以前の 860px だと 1100px で3月だけが右に隠れ、
   「年度の着地見込み」を見る画面なのに年度末の月が最初から見えなかった。
   これ以上詰めると棒も月名も潰れるので、下限を下回る幅では横スクロールに任せる */
.rev-chart svg { display: block; width: 100%; height: auto; min-width: 736px; overflow: visible; }
.rev-grid { stroke: var(--border-soft); stroke-width: 1; }
.rev-base { stroke: var(--border); stroke-width: 1.5; }
/* SVGは viewBox(幅980)を横幅いっぱいに縮めて描くので、狭い画面では文字も一緒に縮む。
   最小幅を 736px まで下げた（12ヶ月を1100pxの窓に収めるため）ぶん、
   縮んだときに 8px台まで落ちないよう、指定の文字サイズを1段上げてある（2026-08-17） */
.rev-axis-label { fill: var(--text-quiet); font-size: 13px; font-weight: 700; }
/* 実績と見込みは「濃さ」で差をつける。ただし見込み側も必ず読める濃さにする
   （--text-faint は白地でコントラスト2.27しかなく、金額も月名も飛ぶ） */
.rev-val { fill: var(--text); font-size: 14px; font-weight: 800; }
.rev-val-fut { fill: var(--text-quiet); font-size: 14px; font-weight: 700; }
.rev-mlbl { fill: var(--text); font-size: 15.5px; font-weight: 800; }
.rev-mlbl-fut { fill: var(--text-quiet); font-size: 15.5px; font-weight: 700; }
.rev-mlbl-cur { fill: var(--accent-ink); font-size: 15.5px; font-weight: 800; }
.rev-badge-cur { fill: var(--accent-2-deep); }
.rev-curline { fill: none; stroke: var(--accent-2-deep); stroke-width: 2.4; }
/* いま内訳を出している月の帯と、月名の下の印 */
.rev-selbg { fill: var(--accent-soft); }
.rev-selmark { fill: var(--accent); }
.rev-hit { fill: transparent; cursor: pointer; }
.rev-hit:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* 積み上げの各段。白い細線で区切ると、隣り合う色が溶けずに段として読める */
.rev-seg { stroke: #ffffff; stroke-width: 1; }
.rev-seg-tuition { fill: var(--fee-tuition); }
.rev-seg-entrance { fill: var(--fee-entrance); }
.rev-seg-material { fill: var(--fee-material); }
.rev-seg-season { fill: var(--fee-season); }
.rev-seg-other { fill: var(--fee-other); }
/* これからの月は塗らず、枠線と斜線だけにする（design-brief「未来は色を付けない」） */
.rev-fut { stroke-width: 1.1; }
.rev-fut-tuition { fill: url(#rev-hatch-tuition); stroke: var(--fee-tuition); }
.rev-fut-entrance { fill: url(#rev-hatch-entrance); stroke: var(--fee-entrance); }
.rev-fut-material { fill: url(#rev-hatch-material); stroke: var(--fee-material); }
.rev-fut-season { fill: url(#rev-hatch-season); stroke: var(--fee-season); }
.rev-fut-other { fill: url(#rev-hatch-other); stroke: var(--fee-other); }
.rev-chart-note { margin-top: 12px; color: var(--text-quiet); }

/* 年度の選択とグラフの凡例 */
.rev-fy { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--text-quiet); white-space: nowrap; }
.rev-fy select {
  padding: 7px 11px; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  font-size: 14px; font-family: inherit; background: var(--surface); font-weight: 700; color: var(--text);
}
.rev-fy select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.rev-legend { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; margin-top: 12px; }
.rev-legend span { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-faint); font-weight: 700; }
.rev-legend i { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.rev-legend-row {
  display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 8px;
  background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
}
/* 凡例はグラフを読むための鍵なので、この帯の中だけは飾り扱いの薄いグレーにしない */
.rev-legend-row .rev-legend { margin-top: 0; color: var(--text-quiet); }
.rev-legend-row .rev-legend span { color: var(--text-quiet); }
.rev-legend .rev-key { width: 15px; height: 15px; border-radius: 3px; }
/* 実績の見本は「積み上がったまま塗ってある」ことが伝わるよう3色の縞にする */
.rev-key-past {
  background: linear-gradient(to top,
    var(--fee-tuition) 0 56%, var(--fee-material) 56% 78%, var(--fee-season) 78% 100%);
}
.rev-key-cur { background: var(--surface); border: 2.5px solid var(--accent-2-deep); }
.rev-key-fut {
  background: repeating-linear-gradient(45deg, var(--accent-soft) 0 3px, var(--surface) 3px 6px);
  border: 1.2px solid var(--accent-dim);
}

/* 選んだ月の状態（今月／実績／見込み）。今月はピンク地に白抜き */
.rev-state-cur { background: var(--accent-2-deep); color: var(--accent-ink); }
.rev-state-past { background: var(--accent-soft); color: var(--accent-deep); }
.rev-state-fut { background: var(--surface-2); color: var(--text-quiet); }

/* 費目の内訳カード。
   3列だと季節講習の行が折り返して読みにくいので最大2列に留める。
   min() を挟まないと、画面が460pxより狭いときに列がはみ出してページ全体が横スクロールする */
.fee-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(460px, 100%), 1fr)); gap: 14px; }
.fee-block { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 13px 15px 11px; background: var(--surface); }
.fee-block.is-wide { grid-column: 1 / -1; }
.fee-head { display: flex; align-items: center; gap: 9px; padding-bottom: 9px; border-bottom: 1.5px solid var(--border); }
.fee-sw { width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto; }
.fee-name { font-size: 16px; font-weight: 800; color: var(--text); }
.fee-share { font-size: 13px; font-weight: 800; color: var(--text-quiet); background: var(--surface-2); border-radius: 99px; padding: 2px 8px; }
.fee-amt { margin-left: auto; font-size: 18px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.fee-rows { display: flex; flex-direction: column; }
/* 狭い画面では「品名／数量／金額」が1行に収まらないので折り返させる。
   折り返しても金額が右端に揃うよう .v にも margin-left:auto を持たせる */
.fee-row {
  display: flex; align-items: baseline; gap: 4px 10px; padding: 7px 2px; flex-wrap: wrap;
  border-bottom: 1px dashed var(--border-soft); font-size: 14px;
}
.fee-row:last-child { border-bottom: none; }
/* まだチケットを配っていないぶんの「見込み」。実績と見分けがつかないと、
   確定した売上だと誤解される（銀行への提出にも使う画面なので特に大事）。
   色だけに頼らず、行頭に「見込み」の文字を出す */
.fee-row.is-forecast { background: var(--ticket-bg); }
.fee-row.is-forecast .t::before {
  content: '見込み'; display: inline-block; margin-right: 7px; padding: 1px 7px;
  border-radius: 999px; background: var(--ticket); color: #fff; font-size: 13px; font-weight: 800;
}
.rev-fee-note {
  padding: 9px 12px; font-size: 13.5px; line-height: 1.7; color: var(--text-dim);
  background: var(--surface-2); border-radius: var(--radius-sm); margin-top: 8px;
}
.rev-fee-note.is-warn { background: var(--warn-bg); color: #b7392f; font-weight: 700; }
.fee-row .t { color: var(--text); font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
/* 「21名 × 14,000円」は飾りではなく中身なので、読める濃さにする */
.fee-row .q { color: var(--text-quiet); font-size: 13px; margin-left: auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
.fee-row .v { width: 128px; flex: 0 0 auto; margin-left: auto; text-align: right; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
/* 割引・返金のマイナス行。--absent は水色地でコントラスト3.09しかなく引き算が読み取れない */
.fee-row.is-minus .t { color: var(--absent-deep); font-weight: 700; }
.fee-row.is-minus .v { color: var(--absent-deep); }
.fee-row.is-sub { border-top: 1.5px solid var(--border); border-bottom: none; margin-top: 4px; padding-top: 9px; }
.fee-row.is-sub .t { font-weight: 800; }
.fee-row.is-total { background: var(--accent-soft); border-radius: 9px; border-bottom: none; margin-top: 7px; padding: 10px 11px; }
/* 合計行はこのカードで一番読ませたい数字なので、水色地でも沈まない濃さにする */
.fee-row.is-total .t { font-weight: 800; color: var(--accent-deep); }
.fee-row.is-total .v { color: var(--accent-deep); font-size: 17.5px; font-weight: 800; }
.fee-empty { color: var(--text-quiet); font-size: 14px; padding: 12px 2px; }

/* 月の合計 */
.rev-sum {
  display: flex; align-items: baseline; justify-content: flex-end; gap: 14px; flex-wrap: wrap;
  margin-top: 16px; padding: 14px 18px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.rev-sum .lb { font-size: 13.5px; font-weight: 800; color: var(--text-quiet); }
.rev-sum .big { font-size: 31px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.rev-sum .sub { font-size: 14px; font-weight: 700; color: var(--text-quiet); font-variant-numeric: tabular-nums; }

/* 生徒別の一覧の右端に出すその月の金額 */
.rev-stu-amt { font-size: 15.5px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* 生徒別の一覧：その月に追加の費用（季節講習・追加授業・入塾金・教材費・調整）が起きた生徒のバッジ
   （2026-08-31 要望D5）。意味は文字で伝え、色はグラフの凡例と同じ費目の色を小さな点で添えるだけ
   （色だけに意味を載せない）。押すと内訳の吹き出し（tooltip.js の .tipx）が開くので、
   「？」ボタン用の .tipx の丸い形と薄い色を、ここでピル型に戻している */
.list-row .rev-ev.tipx {
  display: inline-flex; align-items: center; gap: 5px;
  width: auto; height: auto; margin: 0; padding: 2px 8px;
  border-radius: 99px; border: 1px solid var(--border);
  background: var(--surface); color: var(--text-dim);
  font-size: 13px; font-weight: 800; line-height: 1.3; white-space: nowrap;
}
.list-row .rev-ev.tipx:hover, .list-row .rev-ev.tipx[aria-expanded="true"] {
  color: var(--accent-deep); border-color: var(--accent); background: var(--accent-soft);
}
.rev-ev-sw { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
/* バッジが2つ3つ並ぶと名前の欄が潰れるので、右側は行幅の6割強までにして、
   入り切らないバッジは金額の上の段に回り込ませる（横にはみ出させない） */
#rev-stu-list .list-row .rt { flex-wrap: wrap; justify-content: flex-end; row-gap: 4px; max-width: 64%; }

/* 費目の内訳の行の左に付く三角と、押したときに開く対象の生徒の一覧（2026-08-31 要望D6）。
   人数が0の行には三角を出さず、位置をそろえるための余白（.fee-acc-pad）だけ置く */
.fee-acc-btn, .fee-acc-pad { width: 22px; height: 22px; flex: 0 0 auto; align-self: center; }
.fee-acc-btn {
  border: none; background: none; padding: 0; margin: 0; cursor: pointer;
  border-radius: 6px; color: var(--text-quiet); font-size: 15px; line-height: 1; font-family: inherit;
}
.fee-acc-btn:hover, .fee-acc-btn[aria-expanded="true"] { color: var(--accent-deep); background: var(--accent-soft); }
.fee-acc-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.fee-acc-list {
  display: flex; flex-direction: column; margin: 0 0 6px 30px; padding: 4px 10px;
  background: var(--surface-2); border-radius: 8px;
}
.fee-acc-item { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 13.5px; border-bottom: 1px dashed var(--border-soft); }
.fee-acc-item:last-child { border-bottom: none; }
.fee-acc-item .nm { font-weight: 700; color: var(--text); min-width: 0; overflow-wrap: anywhere; }
.fee-acc-item .amt { margin-left: auto; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.fee-acc-item.is-minus .amt { color: var(--absent-deep); }

/* ===== 生徒数の推移・分析（2026-08-17） =====
   グラフ・凡例・内訳カードは売上管理の部品（.rev-chart / .rev-legend / .fee-*）を
   そのまま使う。ここで足すのは「人数ならではの見せ方」だけ：
     ・積み上げ3色（通塾中=緑／休会中=橙／体験中=ティール）
     ・学年別・学校別の横棒
     ・学年×学校のヒートマップ（濃いほど多い。講習集計と同じ読み方） */
.sts-seg-active { fill: var(--lesson); }
.sts-seg-suspended { fill: var(--ticket); }
.sts-seg-trial { fill: var(--trial); }
/* 実績の見本は「積み上がったまま塗ってある」ことが伝わるよう3色の縞にする */
.rev-legend .sts-key-past {
  background: linear-gradient(to top,
    var(--lesson) 0 64%, var(--ticket) 64% 84%, var(--trial) 84% 100%);
}
/* これからの月は棒を描かない。見本も「空の枠」にして、斜線（＝見込み）と区別する */
.rev-legend .sts-key-fut { background: var(--surface); border: 1.2px dashed var(--border); }

/* 増減の名簿は、移行の月や年度替わりに数十人ぶん並ぶ。そのまま伸ばすと
   1枚のカードだけが画面3つぶんの高さになり、隣の「退塾0名」まで遠くなって読めない。
   件数は見出しに出ているので、名簿はカードの中だけでスクロールさせる
   （生徒管理の一覧（.list-pane-body）と同じ扱い） */
#sts-move-grid .fee-rows { max-height: 328px; overflow-y: auto; }

/* 月の合計に添える増減。増＝緑・減＝赤だが、色だけに頼らず必ず ＋／− の記号を付ける */
.rev-sum .sts-net { font-weight: 800; }
.rev-sum .sts-net.up { color: var(--lesson-deep); }
.rev-sum .sts-net.down { color: var(--absent-deep); }

/* 学年別・学校別の横棒。数字だけを縦に並べるより、どこが厚いかが一目で分かる。
   列の位置は行ごとに変えず格子で固定する。名前や補足の長さで棒の始まりがずれると、
   長さを見比べるという横棒の唯一の役目が成り立たなくなる */
.sts-count-row {
  display: grid;
  grid-template-columns: minmax(86px, 190px) minmax(0, 130px) minmax(60px, 1fr) 96px;
  align-items: center; column-gap: 12px;
}
.sts-count-row .t { overflow-wrap: anywhere; }
.sts-count-row .q { margin-left: 0; text-align: left; white-space: normal; }
.sts-count-row .v { width: auto; margin-left: 0; }
/* 狭い画面では棒の列を落とす。数字は残るので情報は欠けない */
@media (max-width: 820px) {
  .sts-count-row { grid-template-columns: minmax(70px, 1fr) minmax(0, 120px) 0 90px; }
  .sts-bar-cell { display: none; }
}
.sts-bar-cell { display: flex; align-items: center; min-width: 0; }
.sts-bar { display: block; width: 100%; height: 9px; border-radius: 99px; background: var(--surface-2); overflow: hidden; }
.sts-bar > span { display: block; height: 100%; border-radius: 99px; background: var(--accent); }
/* 学校名が入っていない生徒の行。名簿の穴なので、学校名の一つとして読ませない */
.fee-row.sts-unset .t, .sts-cross-head.sts-unset { color: var(--text-faint); font-style: normal; }

/* 学年×学校。横に長くなるので、この表の中だけで横スクロールさせる
   （ページ全体が横に伸びると、左メニューまで一緒に流れて操作できなくなる） */
.sts-cross-wrap { width: 100%; overflow-x: auto; }
.sts-cross { min-width: 640px; font-variant-numeric: tabular-nums; }
.sts-cross th.sts-cross-head { text-align: left; color: var(--text); font-size: 14px; font-weight: 700; white-space: nowrap; }
.sts-cross thead th { white-space: nowrap; }
.sts-cross td { text-align: right; }
.sts-cross-total { font-weight: 800; color: var(--text); }
.sts-cross-foot th, .sts-cross-foot td { font-weight: 800; background: var(--surface-2); }
/* 濃さの4段。0名は白のまま（空欄）。いちばん濃いマスがこの校舎の中心の層 */
.sts-h0 { color: var(--text-faint); }
.sts-h1 { background: var(--accent-soft); }
.sts-h2 { background: var(--surface-3); font-weight: 700; }
.sts-h3 { background: var(--accent); color: var(--accent-ink); font-weight: 800; }
.legend-inline .sts-sw-0 { background: var(--surface); border: 1px solid var(--border); }
.legend-inline .sts-sw-1 { background: var(--accent-soft); border: 1px solid var(--border); }
.legend-inline .sts-sw-2 { background: var(--surface-3); border: 1px solid var(--accent-dim); }
.legend-inline .sts-sw-3 { background: var(--accent); border: 1px solid var(--accent-deep); }

/* ダッシュボードの「今年度の生徒数の増減」。表の代わりに置いた要約 */
.dash-flow { margin-bottom: 14px; }
.dash-flow-row { display: flex; align-items: baseline; gap: 6px 14px; flex-wrap: wrap; padding-bottom: 12px; }
.dash-flow-row .k { font-size: 13px; font-weight: 800; color: var(--text-quiet); }
.dash-flow-row .v { font-size: 18px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; margin-right: 8px; }
.dash-flow-row .k.up, .dash-flow-row .v.up { color: var(--lesson-deep); }
.dash-flow-row .k.down, .dash-flow-row .v.down { color: var(--absent-deep); }
.dash-flow-net {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 12px 14px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.dash-flow-net .lb { font-size: 13px; font-weight: 800; color: var(--text-quiet); }
.dash-flow-net .big { font-size: 28px; font-weight: 800; font-variant-numeric: tabular-nums; }
.dash-flow-net .big.up { color: var(--lesson-deep); }
.dash-flow-net .big.down { color: var(--absent-deep); }
.dash-flow-net .sub { font-size: 13.5px; font-weight: 700; color: var(--text-quiet); }

/* ポップアップの補助表示（どの月を触っているか・確定する金額） */
/* 480px（modal-wide の既定）だと form-grid が1列に落ちて縦に長くなり、
   下の「登録済みの調整」までスクロールしないと見えない。2列に収まる幅にする */
#rev-adj-modal .modal-box, #rev-mat-modal .modal-box { width: 620px; }
.rev-modal-ctx {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 10px 13px; margin-bottom: 16px;
  background: var(--accent-soft); border-radius: var(--radius-sm);
}
.rev-modal-ctx .lb { font-size: 13px; font-weight: 800; color: var(--accent-deep); }
.rev-modal-ctx strong { font-size: 17px; font-weight: 800; color: var(--text); }
.rev-modal-ctx .note { color: var(--text-quiet); font-size: 13.5px; }
/* 金額調整の対象の切り替え（1人／複数を選ぶ／在籍中の全員）と、複数を選ぶ名簿（2026-09-24）。
   名簿はお知らせの宛先・チケットの一括付与と同じ部品（.stu-pick-list）。ポップアップの中なので少し低くする */
.rev-adj-target { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.rev-adj-target .lb { font-size: 13px; font-weight: 800; color: var(--text-dim); }
.rev-adj-pick { margin-bottom: 14px; }
.rev-adj-pick .list-toolbar { margin-bottom: 8px; }
.rev-adj-pick .stu-pick-list { max-height: 260px; }
.rev-adj-pick .note { margin: 6px 0 0; font-size: 13px; color: var(--text-quiet); }
.rev-adj-all {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 10px 13px; margin-bottom: 14px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.rev-adj-all strong { font-size: 17px; font-weight: 800; color: var(--text); }
.rev-adj-all .note { font-size: 13.5px; color: var(--text-quiet); }
/* 理由は長い文になるので、項目・金額の下に1行まるごと使う（2列の片方に押し込まない） */
.rev-adj-wide { grid-column: 1 / -1; }
/* 登録済みの一覧：行の右に「取り消す」。一括で入れた組は見出しでまとめ、その下に人ごとの行。
   「いつ・誰が」は行の本文の下に置く（横に詰めると、理由が長いときにボタンと押し合う） */
.rev-adj-entry { display: flex; align-items: center; gap: 10px; border-bottom: 1px dashed var(--border-soft); }
.rev-adj-entry-main { flex: 1 1 auto; min-width: 0; }
.rev-adj-entry .fee-row { border-bottom: none; }
.rev-adj-entry .rev-adj-del { flex: 0 0 auto; white-space: nowrap; }
.rev-adj-entry:last-child { border-bottom: none; }
.rev-adj-meta { font-size: 13px; color: var(--text-quiet); padding: 0 2px 7px 26px; }
.rev-adj-batch { margin: 6px 0; border: 1.5px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.rev-adj-batch-head {
  display: flex; align-items: center; gap: 6px 12px; flex-wrap: wrap;
  padding: 8px 11px; background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.rev-adj-batch-head .t { font-size: 14px; font-weight: 800; color: var(--text); min-width: 0; overflow-wrap: anywhere; }
.rev-adj-batch-head .meta { font-size: 13px; color: var(--text-quiet); }
.rev-adj-batch-head .rev-adj-batch-del { margin-left: auto; }
.rev-adj-batch-rows { padding: 0 11px; }
.rev-calc {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 12px 15px; margin-top: 6px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 14px; color: var(--text-quiet); font-weight: 700;
}
.rev-calc .big { font-size: 26px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }

/* 試算 */
.sim-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.sim-row .btn.is-on { background: var(--accent-soft); color: var(--accent-deep); border-color: var(--accent-dim); }
.sim-result {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  padding: 12px 15px; background: var(--surface-2); border-radius: var(--radius-sm);
  font-size: 15.5px; color: var(--text-quiet);
}
.sim-result .note { color: var(--text-quiet); font-size: 13.5px; }
.sim-result .big { font-size: 28px; font-weight: 800; font-variant-numeric: tabular-nums; }
.sim-result .up { color: var(--lesson-deep); }
.sim-result .down { color: var(--absent-deep); }

/* ===== 一覧の検索・並べ替えツールバー ===== */
.list-toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.search-box { position: relative; flex: 1; min-width: 220px; }
.search-box > i { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); color: var(--text-faint); font-size: 15.5px; pointer-events: none; }
.search-box input {
  width: 100%; padding: 10px 38px 10px 40px; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  font-size: 16px; font-family: inherit; color: var(--text); background: var(--surface); transition: .15s;
}
.search-box input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.search-clear { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--text-faint); cursor: pointer; padding: 4px 6px; font-size: 15.5px; }
.search-clear:hover { color: var(--text); }
/* 件数・ふりがな・一覧の副見出しは「読ませたい文字」なので --text-dim（白地5.45:1）に上げる。
   --text-faint は白地 4.23:1（AAに0.27不足）、選択行 --accent-soft の上では 3.61:1 まで落ちていた。
   色相は同じ青系のままなので見た目の印象は変わらない（2026-08-19） */
.list-count { font-size: 13.5px; color: var(--text-dim); font-weight: 700; white-space: nowrap; margin-left: auto; }
.list-group-head { background: var(--surface-2); font-size: 13px; font-weight: 800; color: var(--text-dim); }
.list-group-head td { padding: 7px 12px !important; }

/* ===== 検索できる生徒選択（コンボボックス） =====
   一覧から探すのは人数が増えるほど大変になるため、カタカナを打って絞り込めるようにする。
   内部の生徒IDは人に見せず、選ぶだけで済ませる（UI/UX原則） */
.student-picker-box { position: relative; flex: 1; min-width: 220px; }
.student-picker-box input {
  width: 100%; padding: 10px 38px 10px 14px; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  font-size: 16px; font-family: inherit; color: var(--text); background: var(--surface);
}
.student-picker-box input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.student-picker-box .picker-caret { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); color: var(--text-faint); font-size: 13.5px; pointer-events: none; }
.picker-menu {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 60; max-height: 280px; overflow-y: auto;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-hover);
}
.picker-item { padding: 9px 13px; cursor: pointer; font-size: 15.5px; display: flex; align-items: center; gap: 9px; }
.picker-item:hover, .picker-item.active { background: var(--accent-soft); }
.picker-item .g { font-size: 13px; color: var(--text-faint); font-weight: 700; flex: 0 0 auto; }
.picker-item .kana { font-size: 13px; color: var(--text-faint); margin-left: auto; }
.picker-empty { padding: 12px 13px; font-size: 14px; color: var(--text-faint); }
.picker-group { padding: 6px 13px; font-size: 13px; font-weight: 800; color: var(--text-faint); background: var(--surface-2); }

/* ===== 学年バッジ =====
   スタッフアプリと同じ色分け規則にそろえる（受験学年の中3を赤で目立たせる）。
   「セイメイ（小6）」のような括弧書きをやめ、バッジで示す */
.grade-badge { display: inline-flex; align-items: center; padding: 2px 9px; border-radius: 99px; font-size: 13px; font-weight: 800; white-space: nowrap; }
/* 文字だけを濃い版に差し替えた（2026-08-19。遼様の実機指摘「コントラストが弱く読みづらい」の残り）。
   淡い地に基底色をそのまま置いていたため 2.52〜3.00:1 しかなく、
   振替管理・生徒管理・コマチケット・生徒数の推移の全行でこのバッジが読めなかった。
   **面の色（意味を持つ色＝小学生の水色／中1中2の緑／中3の赤／高校の紫）は1つも変えていない。**
   値は当時の振替バッジ（.badge-*-mk。2026-09-18 に廃止）や定員設定のマス目が使っている *-deep と同じで、新しい色は足していない。
     小学生 #1f6ea8 on #e1f0fb = 4.69:1（選択行 --accent-soft の上でも 4.65:1）
     中1中2 #1d7a48 on #e2f6ea = 4.73:1
     中3   #b7392f on #fde3e1 = 4.74:1
     高校  #63469f on #f0e9fb = 6.11:1
     その他 --text-dim on --surface-2 = 4.88:1（旧 --text-faint は 3.78:1） */
.grade-elem   { background: #e1f0fb; color: var(--study-deep); }   /* 小学生 */
.grade-jh12   { background: #e2f6ea; color: var(--lesson-deep); }  /* 中1・中2 */
.grade-jh3    { background: #fde3e1; color: var(--absent-deep); }  /* 中3（受験学年） */
.grade-high   { background: #f0e9fb; color: var(--extra-deep); }   /* 高校生 */
.grade-etc    { background: var(--surface-2); color: var(--text-quiet); }
/* きょうだい（2026-09-11 遼様指示。2026-09-16 に学年バッジと同じ形へ）。
   学年と同じ「その子の属性」なので同じ形・同じ並びで出す。
   色は小さな印だったころと同じ青系（--study）をそのまま使い、
   休/卒/退（橙・紫・グレー）・体験（ティール）と混ざらないようにしている */
.grade-sibling { background: var(--study-bg); color: var(--study-deep); }

/* ===== 性別の選択（未回答=緑・男=青・女=ピンク） =====
   選択式のプルダウンだと色分けがブラウザによって効かないため、
   タップで選ぶボタン方式にする（「選ぶだけで使える」原則にも合う） */
.gender-pills { display: flex; gap: 8px; }
.gender-pill {
  flex: 1; padding: 9px 6px; border-radius: 10px; border: 1.5px solid var(--border);
  background: var(--surface); color: var(--text-dim); font-size: 14px; font-weight: 800;
  cursor: pointer; text-align: center; font-family: inherit; transition: .12s;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.gender-pill:hover { border-color: var(--accent-dim); }
.gender-pill.on-none { background: #e2f6ea; border-color: #2fae68; color: #1d7a48; }
.gender-pill.on-male { background: #e1f0fb; border-color: #2f8fd6; color: #1f6ea8; }
.gender-pill.on-female { background: #ffe9ef; border-color: #ff6f9c; color: #c94a75; }
/* 体験トグル（生徒編集の在籍状況の節）。部品は性別と同じピルを使い回す（新しい部品を発明しない）。
   「体験中」は授業カテゴリの体験色（ティール）、「体験ではない」は無彩色。
   どちらを選んでいても“選んでいる方”が必ず塗られる＝現在の状態が読める */
.gender-pill.on-trial { background: var(--trial-bg); border-color: var(--trial); color: var(--trial-deep); }
.gender-pill.on-plain { background: var(--surface-3); border-color: var(--text-faint); color: var(--text); }
/* 「体験ではない」が2行に折れると読みにくい。ピルの中では折り返さない
   （中身に合わせて幅が伸びる。親の .field 側が余白を吸収する） */
#sted-trial-pills .gender-pill { white-space: nowrap; }

/* ===== 全権管理者の校舎切替（2026-08-13 フェーズ1） ===== */
.school-switcher { margin: 0 4px 10px; padding: 10px 12px; background: var(--accent-soft); border-radius: 12px; }
.school-switcher label { display: block; font-size: 13px; font-weight: 800; color: var(--accent); margin-bottom: 6px; letter-spacing: .04em; }
.school-switcher select { width: 100%; padding: 8px 10px; border: 1.5px solid var(--accent-dim); border-radius: 8px; font-size: 14px; font-family: inherit; color: var(--text); background: var(--surface); font-weight: 700; }
/* 切替権限のないロール向け。<select>と同じ位置・同じ大きさで、押せないことが見て分かる形にする */
.school-fixed { line-height: 1.35; }
.school-fixed-prefix { display: block; font-size: 13px; font-weight: 700; color: var(--text-faint); }
.school-fixed-main { display: block; font-size: 16px; font-weight: 800; color: var(--text); }

/* =====================================================================
   一覧＋詳細の2カラム（メールソフト型）
   =====================================================================
   design-brief「テーブル型（表がずらっと下に並ぶ）レイアウトを避ける」への土台。
   生徒管理で先に作り、お知らせ配信・チケット・売上の生徒別内訳にも同じ形を使う想定なので、
   画面名を含まない汎用のクラス名にしてある。
   左320px固定＋右は残り全部。1100px以下では1カラムに畳む（スマホでも情報を落とさない）。 */
/* 左の一覧は 320→360px（2026-08-29 遼様「氏名を縦横とも広く」。17.5pxの氏名＋
   学年バッジ＋在籍の印が1行に収まる幅）。右のカードはそのぶん詰める（.detail-pane 側） */
.split-2col { display: grid; grid-template-columns: 360px minmax(0, 1fr); gap: 18px; align-items: start; }
@media (max-width: 1100px) { .split-2col { grid-template-columns: minmax(0, 1fr); } }

.list-pane { background: var(--surface); border: 1px solid var(--border-soft); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; }
.list-pane-head { padding: 12px 14px; border-bottom: 1px solid var(--border-soft); display: flex; flex-direction: column; gap: 9px; }
/* 検索・並べ替えの帯は、この中では縦に積むので下余白を持たせない */
.list-pane-head .list-toolbar { margin-bottom: 0; }
.list-pane-head .search-box { min-width: 0; }
/* 一覧だけが縦にスクロールする。右の詳細はページと一緒に動く（メールソフトと同じ感覚）。

   高さは画面の高さに追従させる（2026-08-19。遼様のご指摘「下に無駄な余白」の残り）。
   560px 固定だったため、1920×1040 では 56名の名簿を高さ560pxの箱でスクロールさせながら、
   その下に 262px の空白が残っていた（振替管理 308px／コマチケット 275px）。
   268px は「一覧の箱の上端 ＋ 下に残す余白」。文字を約2割大きくした 2026-08-29 に
   上の帯・検索も高くなったため、244px から 24px ぶん深くした。
   max() にしてあるので、1366×728 のような背の低い画面では計算値が560pxを下回り、
   これまでとまったく同じ高さのまま変わらない（狭い画面で潰れない）。
   ※ 振替管理も以前はこの値で予定の箱の高さをそろえていたが、2026-08-22 に右ペインを
     カレンダーへ変えたので、そちらは高さを固定していない（1日ぶんしか出ないため） */
:root { --list-pane-h: max(560px, calc(100vh - 268px)); }
.list-pane-body { max-height: var(--list-pane-h); overflow-y: auto; }
/* 学年（または学校）の切り替わりに挟む見出し。スクロールしても上端に貼り付く */
.list-pane-group {
  position: sticky; top: 0; z-index: 2; background: var(--surface-2); color: var(--text-dim);
  font-size: 13px; font-weight: 800; letter-spacing: .06em; padding: 7px 14px;
  border-bottom: 1px solid var(--border-soft);
}
/* 一覧の途中に挟む切れ目（振替管理の「期限が近い順」で、残っていない人の手前に入れる）。
   見出し（.list-pane-group）と違って貼り付かない＝ここから下は見なくてよい、の1回だけの合図 */
.list-pane-divider {
  background: var(--surface); color: var(--text-quiet); font-size: 13px; font-weight: 700;
  padding: 9px 14px; border-top: 1px dashed var(--border); border-bottom: 1px solid var(--border-soft);
}
.list-row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 13px 14px; border: none; background: none; border-bottom: 1px solid var(--border-soft);
  cursor: pointer; transition: background .12s; font-family: inherit;
}
.list-row:hover { background: var(--surface-2); }
.list-row.is-active { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.list-row .rw { min-width: 0; flex: 1; }
.list-row .nm, .list-row .sub { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 氏名は一覧でいちばん読ませたい文字。17px以上の太字（2026-08-29 遼様のご指摘） */
.list-row .nm { font-size: 17.5px; font-weight: 700; color: var(--text); }
/* 選択行（--accent-soft）の上では --text-faint が 3.61:1 まで落ちる。--text-dim なら 4.66:1 */
.list-row .sub { font-size: 13px; color: var(--text-dim); margin-top: 3px; }
.list-row .rt { margin-left: auto; flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
/* 在籍中以外だけに小さな印を付ける。一覧を色まみれにせず、例外だけが目に入るようにする。
   色だけの点にすると色覚異常のある方には3状態が区別できないので、
   「休／卒／退」の文字と枠線を必ず添える（保護者アプリで点を帯＋文言に変えたのと同じ理由） */
.state-mark {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 21px; height: 20px; padding: 0 5px; border-radius: 5px; border: 1px solid;
  font-size: 13px; font-weight: 800; line-height: 1; flex: 0 0 auto;
}
.state-mark.st-suspended { background: var(--ticket-bg); color: var(--ticket-deep); border-color: var(--ticket); }
.state-mark.st-graduated { background: var(--extra-bg); color: var(--extra); border-color: var(--extra); }
.state-mark.st-withdrawn { background: var(--surface); color: var(--text-quiet); border-color: var(--text-faint); }
/* 体験中（手動の印。2026-08-19）。授業カテゴリの「体験授業」と同じティールで、
   1文字略号では「休」等と並んだとき意味が取れないので「体験」の2文字を出す */
.state-mark.st-trial { background: var(--trial-bg); color: var(--trial-deep); border-color: var(--trial); }
/* 選択中の行（--accent-soft #dcf0fd）と小学生の学年バッジ（#e1f0fb）はほぼ同じ明るさで、
   選んだ瞬間だけ学年が読めなくなる。色は変えず、輪郭を1本足して形で分かるようにする */
.list-row.is-active .grade-badge { box-shadow: inset 0 0 0 1px currentColor; }
.list-pane-empty { padding: 40px 16px; text-align: center; color: var(--text-faint); font-size: 15.5px; }

.detail-pane { display: flex; flex-direction: column; gap: 16px; }
.detail-pane-empty { color: var(--text-faint); font-size: 15.5px; text-align: center; padding: 60px 0; }
/* 振替管理は「予定が縦に並ぶ一覧」をやめ、保護者アプリと同じカレンダーにした（2026-08-22）。
   したがって #mk-timeline（高さを固定して中でスクロールさせる箱）は無くなっている。
   2026-08-29 の3カラム化（#mk-3col。定義は下の「振替管理の3カラム」）で、いまの並びは
     #mk-who（誰の。②③の上に渡す。サブ画面が入れ替わっても消えない）
     → #mk-cal-view（②カレンダー。出しっぱなし）
     → #mk-detail（③操作パネル：その日の予定 ⇔ 振替先を選ぶ ⇔ 自習を予約）
   で、どれも箱の中でスクロールさせない。押した日の予定は1日ぶんしか出ないので、
   以前のように「毎週の授業が先の月まで20枚以上並んでページが数千px伸びる」ことが起きない。
   箱の中でスクロールさせると、狭い幅で「下が読めないのに何もできない」状態を作るほうが害が大きい */
#mk-who:empty { display: none; }
#mk-empty:empty { display: none; }
/* 「誰の・いつの・どの時間の授業を操作しているか」を、右ペインの上に貼り付けておく。
   カレンダーも振替先のパネルも縦に長いので、貼り付けないとスクロールした先で
   生徒名も元のコマも画面の外へ出る。この画面は押した瞬間に予約が動くので、
   ここが消えると隣の子のコマを付け替える事故になる（狭い幅で実際に起きている）。

   貼り付ける位置は2段重ね：
     1段目 #mk-who       … 画面名の帯（--sticky-top ＋ --head-h。script.js が実測して入れる）の下
     2段目 #mk-dst-title … さらに #mk-who の高さ（--mk-who-h。同じく実測）の下
   固定値で書くと、メニューの開閉・画面ごとの帯の高さ・生徒名の折り返しでずれる。

   sticky は「親の箱の中」でしか効かない。#mk-who を .detail-pane（背の高い箱）の直下に
   置いてあるのはそのため。中の .mk-who-head に付けても、親が見出しと同じ高さしか無いので
   1pxも貼り付かない（2026-08-22 683pxで実測して気づいた） */
#mk-who {
  position: sticky; top: calc(var(--sticky-top, 0px) + var(--head-h, 53px)); z-index: 6;
}
.mk-who-head {
  background: var(--surface); border: 1px solid var(--border-soft); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 12px 18px; margin-bottom: 0;
}
.mk-dst-title {
  position: sticky; top: calc(var(--sticky-top, 0px) + var(--head-h, 53px) + var(--mk-who-h, 86px)); z-index: 5;
  background: var(--accent-soft); border: 1px solid var(--accent-dim); border-radius: var(--radius-sm);
  color: var(--accent-deep); padding: 9px 14px; margin: 0 0 14px;
  font-size: 16px; font-weight: 800; line-height: 1.4;
  /* 3カラムの幅（1440pxで約400px）では「生徒名＋登録/変更＋日付＋時刻」が1行に入らず
     2行になる（13px未満に落とさない限り、CSSだけでは1行に収まらない）。
     切れ目を「…22:10 / の分」のような端切れにせず、2行を同じくらいの長さで割る。
     対応していないブラウザでは今までどおり普通に折り返すだけ */
  text-wrap: balance;
}

/* カレンダーの上の3枚。以前は3列に固定していたが、3カラム化（2026-08-29）でカレンダーの列が
   1280〜1440px幅では 290〜350px しか無く、1枚あたり 77px 以下になって
   「この月の授／業」と単語の途中で折れていた（2026-08-30 実画面で確認）。
   枚数は3のまま、入り切らない幅では最後の1枚を次の行へ回して全幅に伸ばす（flex）。
   1枚の幅の下限はラベル（6文字・13px＝下限なので落とさない）＋左右の余白で決まる。
   ラベルは keep-all＋nowrap にして、どの幅でも単語の途中では折らせない */
.mk-cal-summary { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 18px; }
.mk-sum-box { flex: 1 1 0; background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 11px 6px; text-align: center; }
.mk-sum-box .num { font-size: 27px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; line-height: 1.2; }
.mk-sum-box .lbl { font-size: 13px; font-weight: 700; color: var(--text-dim); margin-top: 3px; word-break: keep-all; white-space: nowrap; }
/* 振替先が未定が残っているときだけ、その1枚を赤くする。
   色だけで伝えないよう、ラベルの文字（「振替先が未定」）は色に関わらず出したまま。

   【2026-08-22】枠は --sc-danger-rgb（カレンダーの赤いリングと同じ値）から取る。
   直前まで --absent(#e6564f) で塗っていたため、**同じ「振替先が未定」を指す赤が
   1画面に2色**あった（カレンダーのリングは #dc2626）。同じ状態は同じ色で塗る。
   面（--absent-bg）と文字（--absent-deep）は動かさない：意味色のパレットそのものを
   どちらに寄せるかは design-audit-2026-08-16.md の A-2 で遼様の判断待ちのため、
   ここで揃えるのは「2つある赤」だけに留める。
   既定値を書いてあるのは #tab-makeup の外で使われたときの保険（値は同じ） */
.mk-sum-box.is-alert { background: var(--absent-bg); border-color: rgb(var(--sc-danger-rgb, 220 38 38)); }
.mk-sum-box.is-alert .num, .mk-sum-box.is-alert .lbl { color: var(--absent-deep); }

/* カレンダーの下の一行。ふだんは使い方、月を飛ばしたときは飛ばした理由、
   操作の直後は「何が起きたか」を出す（3つとも同じ場所に出す＝探す場所を1つにする） */
.mk-cal-note { margin: 12px 0 0; }
.mk-cal-note.is-alert { color: var(--absent-deep); font-weight: 700; }
/* 「◯を△へ振り替えました」。操作が通ったことを言い切る一行。
   意味を持つ色（振替＝緑）をそのまま使い、淡い地に濃い文字を載せる（--lesson-deep で 5.5:1）。
   以前はこの報告が **一度も画面に出ないまま消えていた**（パネルごと隠していたため） */
.mk-cal-note.is-done {
  color: var(--lesson-deep); font-weight: 700;
  background: var(--lesson-bg); border: 1px solid var(--lesson);
  border-radius: var(--radius-sm); padding: 10px 14px;
}

/* 押した日の予定。カレンダーとの切れ目が分かるよう、余白を広げて薄い線を引く
   （保護者アプリの「◯月◯日の予定」と同じ作法） */
.mk-day-detail { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border-soft); }
.mk-day-detail:empty { display: none; }
.mk-day-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.mk-day-head .d { font-size: 18px; font-weight: 800; color: var(--text); }
/* 振替先が未定のコマは、日別の予定の中でも見分けが付くようにする。
   カレンダーのリングと同じ赤にし、こちらは点滅させない
   （同じ画面で2か所が明滅すると、どちらを見ればよいか分からなくなる）。

   【2026-08-22】「同じ赤」と書いてあったのに実際は --absent(#e6564f) で、
   カレンダーのリング（#dc2626）と違う色だった。リングと同じ --sc-danger-rgb から取る
   （集計タイル .mk-sum-box.is-alert と同じ直し方。理由はそちらのコメントに書いてある）*/
.slot-card.is-pending { border-color: rgb(var(--sc-danger-rgb, 220 38 38)); background: var(--absent-bg); }
/* 「◯月◯日 17:50 - 19:10 の振替」。どのコマから移ってきたのかを1行で添える */
.mk-src-note { font-size: 13px; color: var(--text-dim); font-weight: 700; margin-top: 7px; }
.mk-src-note i { color: var(--text-faint); margin-right: 4px; }
/* チケット授業の「体験 2回目／全4回」（2026-10-10）。文字だけ・飾りのアイコンなし */
.mk-tkp { font-size: 13px; color: var(--text-dim); font-weight: 700; margin-top: 7px; font-variant-numeric: tabular-nums; }
/* 過ぎた日に操作ボタンを出さない代わりに、なぜ押せないのかを書く（黙って消さない） */
.mk-past-note { margin: 10px 0 0; }
/* 自習の予定に操作ボタンを出さない代わりに、どこで操作できるのかを書く（同じ考え方）。
   自習はこの画面の担当ではないが、**予定としては必ず見せる**（見えないと同じコマに振替が入る） */
.mk-study-note { margin: 10px 0 0; }
/* 現場で付いた出欠の記録。予定とは別物なので、バッジではなく本文の下に添える。
   意味を持つ色（出席=緑／欠席=赤）は変えず、必ずアイコンと文字を伴わせる */
.mk-att { display: flex; align-items: center; gap: 7px; margin-top: 9px; font-size: 13.5px; font-weight: 700; }
.mk-att.is-present { color: var(--lesson-deep); }
.mk-att.is-absent { color: var(--absent-deep); }
.mk-att-late { color: var(--ticket-deep); font-weight: 800; }

/* -----------------------------------------------------------------------------
   左の一覧の印（2026-09-12 遼様のご要望／見本 mock-makeup-list.html）
   -------------------------------------------------------------------------- */
/* 生徒名の行は、印が2行目に回るので上ぞろえにする（.list-row の既定は中央ぞろえ） */
#mk-list .list-row { align-items: flex-start; }
#mk-list .list-row .rt { padding-top: 2px; }
.mk-marks { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }

/* 赤い丸に白い数字＝振替先が未定の件数（期限切れも含む）。
   保護者アプリのお知らせのバッジ（.mah-nav-badge）とまったく同じ見た目にしてある。
   赤はカレンダーの「振替先が未定」のリングと同じ --sc-danger-rgb から取る
   （同じ状態を指す赤が1画面に2色あってはならない。.mk-sum-box.is-alert と同じ直し方）。
   跳ねる動きは付けない：同じ画面で何人ぶんも並ぶので、全部が明滅すると何も読めなくなる */
.mk-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 6px; border-radius: 999px;
  background: rgb(var(--sc-danger-rgb, 220 38 38)); color: #fff;
  font-size: 13px; font-weight: 900; line-height: 1;
  font-variant-numeric: tabular-nums; flex: 0 0 auto;
  box-shadow: 0 2px 8px rgb(var(--sc-danger-rgb, 220 38 38) / 45%);
}

/* 期限・予約ずみ・元の授業の月の印。色だけの点にせず、必ず文字と件数を出す */
.mk-mark {
  display: inline-flex; align-items: center; height: 21px; padding: 0 7px;
  border-radius: 5px; border: 1px solid;
  font-size: 13px; font-weight: 800; line-height: 1; white-space: nowrap; flex: 0 0 auto;
}
/* 未定のまま期限が近い（14日を切った） */
.mk-mark-soon { background: var(--absent-bg); color: var(--absent-deep); border-color: var(--absent); }
/* 未定のまま期限を過ぎた。放っておくと権利が消えるので、塗りつぶして残し続ける */
.mk-mark-over { background: var(--absent); color: #fff; border-color: var(--absent); }
/* 行き先が決まっていて未受講。対応が要らないので赤ではなく緑（授業＝緑の割り当てのまま） */
.mk-mark-booked { background: var(--lesson-bg); color: var(--lesson-deep); border-color: var(--lesson); }
/* 休んだ授業がいちばん古い月。順番の目印なので、意味を持つ色は使わない */
.mk-mark-month { background: var(--surface-2); color: var(--text-quiet); border-color: var(--border); }
/* 振替を予約した日に出席の記録が無い（来なかった振替。2026-09-17）。
   権利は期限まで残っているので、緑の「予約ずみ」ではなく期限と同じ赤の系統（--absent）で出す。
   期限が近い（.mk-mark-soon）より一段強い縁にして、同じ赤の中でも見分けが付くようにした。
   期限そのものを過ぎたら .is-over で塗りつぶし、未定のまま期限切れ（.mk-mark-over）と同じ重さにする */
.mk-mark-missed {
  background: var(--absent-bg); color: var(--absent-deep);
  border-color: var(--absent-deep); border-width: 2px;
}
.mk-mark-missed.is-over { background: var(--absent); color: #fff; border-color: var(--absent); }

/* =====================================================================
   振替管理の3カラム（2026-08-29 遼様指示）
   =====================================================================
   ①生徒一覧（.list-pane）②その生徒の小さめのカレンダー（#mk-cal-view）
   ③操作パネル（#mk-detail：その日の予定 ⇔ 振替先を選ぶ ⇔ 自習を予約）。
   「日付を押すと予定が下に出る→振替を押すとカレンダーごと入れ替わる」をやめ、
   ③の中身だけを入れ替える（遼様「インターフェースの切り替えが小さくて済む」）。

   ・.split-2col のクラスは残したまま id で上書きする。畳み判定（isSplitStacked）が
     closest('.split-2col') で器を探すため、クラスを替えると全一覧共通の
     「畳んだ幅で詳細へ運ぶ」が振替管理だけ効かなくなる。
   ・#mk-who（誰の帯）は②③の両方の上に渡す。③で操作している間も生徒名が
     視界から消えない（この画面は押した瞬間に予約が動く）。
   ・#mk-empty（生徒未選択の案内）は #mk-who と同じマスに置く。2つは同時に出ない
     （案内が出る＝生徒未選択＝帯は空）ので、行を分けると空行のぶん余白が二重になる */
#mk-3col {
  grid-template-columns: 360px minmax(0, 1fr) minmax(0, 1.15fr);
  grid-template-areas:
    "list who  who"
    "list main side";
}
#mk-3col > .list-pane { grid-area: list; }
#mk-who, #mk-empty { grid-area: who; min-width: 0; }
#mk-cal-view { grid-area: main; min-width: 0; align-self: start; }
#mk-detail { grid-area: side; min-width: 0; }

/* 器が狭いときは縦積みに畳む（他の split-2col と同じ 1060px。
   idの詳細度が @container の .split-2col の指定より強いので、自前で畳む） */
@container mainc (max-width: 1060px) {
  #mk-3col {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "list" "who" "main" "side";
  }
}
/* @container が効かないブラウザ向けの受け皿（下の @media (max-width:900px) と同じ方向） */
@media (max-width: 900px) {
  #mk-3col {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "list" "who" "main" "side";
  }
}

/* ③の中：サブ画面（振替先を選ぶ／自習を予約）は panel を縦に積む。
   以前の .two-col（横並び）は3カラム化で幅が無くなったのでやめた */
#mk-dst-panel, #mk-study-panel { display: grid; gap: 16px; }
/* 見出し（.mk-dst-title）との間隔は grid の gap が取る。margin と二重にしない */
#mk-detail .mk-dst-title { margin-bottom: 0; }
/* 振替先／自習のパネルへ scrollIntoView で運ぶときの着地点（2026-08-30）。
   html の scroll-padding-top は「画面名の帯」までしか見ていない。そのため着地した直後は
   見出しの本来の位置が貼り付き位置（帯＋#mk-who）より上にあり、見出しが #mk-who の
   高さぶん下へ押し出されて、直下のカレンダーの月ナビを覆っていた（1440px幅で実測。
   見出しが2行のときは月名まで隠れる）。#mk-who の高さぶん手前で着地させれば、
   見出しは本来の位置＝貼り付き位置に収まり、何も覆わない。
   script.js 側で着地位置を直す手当てとは独立に効く（どちらか片方だけでも直る） */
#mk-dst-panel, #mk-study-panel { scroll-margin-top: var(--mk-who-h, 86px); }
/* その日の予定は③の panel の中に出す。カレンダー直下時代の「切れ目の線」は不要 */
#mk-day-panel .mk-day-detail { margin-top: 0; padding-top: 0; border-top: none; }
/* 予定一覧の下の「この日に自習を予約」。予定への操作と混ざらないよう破線で区切る */
.mk-day-foot { margin-top: 16px; padding-top: 14px; border-top: 1px dashed var(--border-soft); }
.mk-day-foot .btn { width: 100%; justify-content: center; }
/* 絞り込みのボタン。押している間だけ塗る（いま絞っているかどうかを形と色の両方で出す） */
.chip-toggle {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 99px;
  border: 1.5px solid var(--border); background: var(--surface); color: var(--text-dim);
  font-family: inherit; font-size: 13px; font-weight: 800; cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.chip-toggle:hover:not(:disabled) { border-color: var(--absent); color: var(--absent-deep); }
.chip-toggle.is-on { background: var(--absent-bg); border-color: var(--absent); color: var(--absent-deep); }
.chip-toggle .n { font-variant-numeric: tabular-nums; background: var(--absent); color: #fff; border-radius: 99px; padding: 0 6px; font-size: 13px; line-height: 19px; }
/* 急ぎではない絞り込み（振替管理の「振替が残っている人だけ」）。赤は「期限」の意味に取っておき、
   こちらは主色の青にする。同じ形のボタンが2つ並ぶので、色で役割の重さを分ける */
.chip-toggle.is-soft:hover:not(:disabled) { border-color: var(--accent-dim); color: var(--accent-deep); }
.chip-toggle.is-soft.is-on { background: var(--accent-soft); border-color: var(--accent-dim); color: var(--accent-deep); }
.chip-toggle.is-soft .n { background: var(--accent-deep); }
/* 押せないときは「淡い面＋濃い文字」。薄い主色＋白抜きにすると文字が背景に溶ける */
.chip-toggle:disabled { background: var(--surface-2); color: var(--text-quiet); border-color: var(--border-soft); cursor: default; }
.chip-toggle:disabled .n { background: var(--text-faint); }

/* 月間カレンダーの共有部品（/assets/schedule-calendar.css）を、この画面の色に合わせる。
   意味の割り当て（授業=緑／自習=青／要対応=赤）は変えない。変えているのは濃さだけで、
   帯の中の白文字が読める値（緑 5.34:1／青 5.45:1）にしてある。
   マスの地はSCHOOL Managerの他の4つのカレンダー（.cal-day）と同じ --surface-2 にする。
   同じ画面の中でカレンダーの見え方が2種類あると、操作を2つ覚えることになるため */
#tab-makeup {
  --sc-lesson: var(--lesson-deep);
  --sc-study: var(--study-deep);
  /* 「振替先が未定」の赤いリングだけは、この画面の --absent(#e6564f) に寄せず
     共有部品の既定（#dc2626＝保護者アプリの要対応の赤）をそのまま使う。
     ・この画面の存在理由は「保護者アプリと同じものを本部でも代行できる」こと。
       電話中に保護者と本部が同じ赤を見ていないと、その一点だけ会話がずれる
     ・リングは2.5pxの線1本で、気づかせることが仕事。白地の上で
       #e6564f は 3.62:1、#dc2626 は 4.83:1（月送りの「未」の白文字も同じ差になり、
       #e6564f では 4.5:1 を切っていた）
     ・--absent そのものは動かさない。3アプリのどのパレットを正とするかは
       docs/design-audit-2026-08-16.md の A-2 で遼様の判断待ちのため
     値を書かずに指定を省いても既定が効くが、**あえて明示している**：
     省くと「揃えたのか、書き忘れたのか」が次に読む人に分からない */
  --sc-danger-rgb: 220 38 38;
  /* 選べる日はうっすら塗る。白地に白マスだと「押せる場所」が読み飛ばされる
     （保護者アプリで淡い緑にしたのと同じ理由。こちらの主色は水色）。
     押せない日は塗らずに沈める＝地の色そのもので違いが出る。
     #c9e8fb は --accent-soft(#dcf0fd) の1段濃い値（新しい色を足さない） */
  --sc-day-bg: var(--accent-soft);
  --sc-day-bg-hover: #c9e8fb;
  --sc-day-ink: var(--text);
  --sc-sel-bg: var(--accent-deep);
  --sc-sel-ink: #ffffff;
  --sc-today-bg: var(--accent-deep);
  --sc-today-ink: #ffffff;
  --sc-off-bg: var(--surface-2);
  --sc-off-ink: var(--text-faint);
  --sc-off-border: var(--border);
  --sc-dow-ink: var(--text-faint);
  /* たった今振替を入れた日のリング（820ms×3回で止まる）。
     保護者アプリと同じく「振替＝緑」にする。選択日はこの画面の主色（濃い水色）で
     塗られるので、同じ水色のリングを重ねると境目が消えて何も起きていないように見える */
  --sc-new: var(--lesson-deep);
  --sc-new-glow: rgba(29, 122, 72, .38);
}
/* 詳細カードの中のまとまり。ポップアップの中でも同じ部品を使う */
.detail-sec { border-top: 1px solid var(--border-soft); margin-top: 13px; padding-top: 11px; }
.detail-sec:first-child { border-top: none; margin-top: 0; padding-top: 0; }
.detail-sec h4 { font-size: 13px; font-weight: 800; color: var(--text-dim); letter-spacing: .04em; margin: 0 0 8px; display: flex; align-items: center; gap: 7px; }
.detail-sec h4 i { color: var(--accent); font-size: 13.5px; }
/* 行間 9→7px・列間 14→12px（2026-08-29 遼様「右のプロフィールカードは詰めてよい」。
   文字は大きくしたまま、間隔だけで詰める） */
.kv { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 7px 12px; font-size: 15.5px; align-items: baseline; margin: 0; }
.kv dt { color: var(--text-faint); font-size: 13px; font-weight: 700; margin: 0; }
.kv dd { color: var(--text); font-weight: 600; margin: 0; }

/* ===== 見出し行の右に置くアクションボタン ===== */
.head-actions { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; }
/* 年に数回しか使わない操作を畳むメニュー（ボタンを画面に散らさない） */
.more-menu { position: relative; }
.more-panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 70; min-width: 220px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-hover); padding: 6px; display: flex; flex-direction: column;
}
.more-item {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  padding: 9px 11px; border: none; background: none; border-radius: 8px;
  font-family: inherit; font-size: 14px; font-weight: 700; color: var(--text-dim);
  cursor: pointer; text-decoration: none; white-space: nowrap;
}
.more-item:hover { background: var(--surface-2); color: var(--text); }
.more-item i { width: 17px; text-align: center; color: var(--text-faint); }

/* ===== 並べ替えの切替・畳んだ絞り込み ===== */
.seg { display: inline-flex; background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; padding: 3px; gap: 2px; }
.seg-btn { border: none; background: none; padding: 6px 13px; border-radius: 8px; font-size: 14px; font-weight: 700; color: var(--text-dim); cursor: pointer; font-family: inherit; }
/* いま「学年順」なのか「50音順」なのかを示す唯一の印なので、いちばん薄い文字にはしない。
   --accent(#2bacf0) を白地に置くと 2.54:1 で、選ばれている側のほうが読みにくかった。
   --accent-deep なら 5.80:1（2026-08-19）。面の色は変えず、文字だけを濃くしている */
.seg-btn.is-on { background: var(--surface); color: var(--accent-deep); box-shadow: var(--shadow); }
.filter-toggle {
  display: inline-flex; align-items: center; gap: 5px; border: none; background: none; cursor: pointer;
  font-size: 13.5px; font-weight: 700; color: var(--text-dim); padding: 5px 4px; border-radius: 8px; font-family: inherit;
}
.filter-toggle:hover { color: var(--accent); }
.filter-toggle .caret { font-size: 13px; transition: transform .15s; }
.filter-toggle.is-open .caret { transform: rotate(180deg); }
.filter-body {
  display: flex; flex-direction: column; gap: 8px;
  padding: 9px 10px; background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
}
.filter-line { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }
.filter-lbl { font-size: 13px; font-weight: 800; color: var(--text-faint); letter-spacing: .04em; }
.chip {
  border: 1.5px solid var(--border); background: var(--surface); color: var(--text-dim);
  padding: 3px 11px; border-radius: 99px; font-size: 13px; font-weight: 700; cursor: pointer; font-family: inherit;
}
.chip.is-on { background: var(--accent-soft); border-color: var(--accent-dim); color: var(--accent); }
/* 「絞り込みをすべて解除する」。押せることが分かるよう下線を引き、右端に寄せる */
.filter-clear {
  background: none; border: none; color: var(--text-dim); text-decoration: underline;
  font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer; padding: 2px 4px; margin-left: auto;
}
.filter-clear:hover { color: var(--accent-deep); }
/* 絞り込みの中に置く小さなプルダウン（卒業年度） */
.mini-select {
  padding: 3px 8px; border: 1.5px solid var(--border); border-radius: 8px;
  font-family: inherit; font-size: 13px; font-weight: 700; color: var(--text); background: var(--surface);
}
.mini-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
/* 卒業年度は常に出す（在籍状況の印と同じ扱い）。まだ卒業生が1人もいない間は選べないので、
   押せないことが見て分かる濃さにしておく。文言のほうで理由も書いてある */
.mini-select:disabled { background: var(--surface-2); color: var(--text-faint); cursor: default; }

/* ===== 生徒のプロフィールカード ===== */
/* カードの内側の余白だけ基準（20px 22px）より詰める（2026-08-29 遼様「右側は詰めてよい」）。
   .panel 本体を触ると全画面が詰まってしまうので、詳細ペインの中に限定する */
.detail-pane .panel { padding: 16px 18px; }
.stu-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
  padding-bottom: 12px; margin-bottom: 13px; border-bottom: 1px solid var(--border-soft);
}
.stu-name { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-size: 24px; font-weight: 800; color: var(--text); line-height: 1.3; }
.stu-kana { display: block; margin-top: 4px; font-size: 13.5px; color: var(--text-dim); font-weight: 600; }
.detail-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 22px; }
.detail-grid > .detail-sec:nth-child(1), .detail-grid > .detail-sec:nth-child(2) { border-top: none; margin-top: 0; padding-top: 0; }
.detail-grid > .detail-sec.full { grid-column: 1 / -1; }
@media (max-width: 1100px) {
  .detail-grid { grid-template-columns: minmax(0, 1fr); }
  .detail-grid > .detail-sec:nth-child(2) { border-top: 1px solid var(--border-soft); margin-top: 16px; padding-top: 14px; }
}

/* 時間割の要約（週の形をコマ記号で見せる。記号が主・時刻は添えるだけ） */
.week-count { font-size: 15.5px; font-weight: 800; color: var(--text); margin-bottom: 9px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.slot-chips { display: flex; flex-wrap: wrap; gap: 7px; }
/* 「火曜 17:50 - 19:10」の1粒。曜日と時刻だけで、記号（A〜G）は出さない */
.slot-chip { display: inline-flex; align-items: baseline; gap: 6px; padding: 5px 11px; border-radius: 99px; background: var(--lesson-bg); color: var(--lesson); font-size: 13.5px; font-weight: 800; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* 割引・申し送りの要約 */
.disc-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px; border-radius: 99px; background: var(--accent-soft); color: var(--accent); font-size: 13.5px; font-weight: 700; margin: 0 6px 6px 0; }
.disc-none { font-size: 14px; color: var(--text-faint); }
.sign-row { display: flex; flex-wrap: wrap; gap: 7px; }
.note-list { display: flex; flex-direction: column; gap: 8px; }
.note-item { padding: 9px 12px; border: 1px solid var(--border-soft); border-radius: 10px; background: var(--surface-2); }
/* 対応済みは薄くして、まだ手を付けていない申し送りを目立たせる。
   薄いだけだと色（濃さ）しか手がかりが無いので、meta には必ず「対応済み」の文字も出す */
.note-item.is-resolved { opacity: .55; }
.note-item .meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; color: var(--text-faint); font-weight: 700; margin-bottom: 4px; font-variant-numeric: tabular-nums; }
.note-item .cat { padding: 1px 8px; border-radius: 99px; background: var(--surface); border: 1px solid var(--border-soft); }
.note-item .b { font-size: 14px; color: var(--text); line-height: 1.65; font-weight: 600; }
.note-item .meta .btn-link { margin-left: auto; padding: 0 2px; font-size: 13px; }
.note-more { font-size: 13px; color: var(--text-faint); margin-top: 8px; }

/* ===== 中身が長いポップアップ（生徒の一括編集） =====
   中だけスクロールさせ、保存ボタンは常に見える位置に固定する */
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 14px; }
/* 電話番号の区分（2026-08-31 決定21）。「誰の番号か」を番号の左に置く。
   区分の幅は「祖父携帯」（4文字）が折れずに入る分だけ取り、残りを番号に渡す。
   「その他」のときだけ、下に補足欄（.tel-note）が出る（JS: syncTelNoteField） */
.tel-row { display: flex; gap: 8px; align-items: stretch; }
.tel-row .tel-kind { flex: 0 0 auto; width: 132px; padding-left: 9px; padding-right: 6px; }
.tel-row input { flex: 1 1 auto; min-width: 0; }
.field .tel-note { margin-top: 2px; }
/* お友達紹介コード（2026-09-11）。
   ・探す欄 … 8文字を打って「探す」を押すと、上の紹介者の欄が決まる
   ・コード … 電話で聞かれたときに読み上げる。似た字を読み違えないよう等幅ぎみに広げて出す */
.ref-lookup-row { display: flex; gap: 8px; align-items: stretch; }
.ref-lookup-row input { flex: 1 1 auto; min-width: 0; }
.ref-lookup-row .btn { flex: 0 0 auto; }
.ref-lookup-msg { margin: 4px 0 0; font-size: 13px; color: var(--text-faint); line-height: 1.5; min-height: 18px; }
.ref-lookup-msg.is-ok { color: var(--accent); font-weight: 700; }
.ref-lookup-msg.is-ng { color: #b91c1c; font-weight: 700; }
.ref-code-row { display: flex; align-items: center; gap: 10px; min-height: 38px; }
.ref-code {
  font-size: 20px; font-weight: 800; letter-spacing: .16em; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
  padding: 6px 12px; font-variant-numeric: tabular-nums;
}
.ref-code.is-none { font-size: 14px; font-weight: 600; letter-spacing: 0; color: var(--text-faint); }
.modal-box.modal-tall { display: flex; flex-direction: column; max-height: 86vh; padding: 0; overflow: hidden; }
.modal-tall .modal-head { padding: 20px 24px 14px; border-bottom: 1px solid var(--border-soft); flex: 0 0 auto; }
.modal-tall .modal-head h4 { margin: 0; }
.modal-tall .modal-head h4 i { color: var(--accent); }
.modal-tall .modal-body { padding: 18px 24px 22px; overflow-y: auto; flex: 1 1 auto; }
.modal-tall .modal-foot {
  padding: 14px 24px; border-top: 1px solid var(--border-soft); background: var(--surface); flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  box-shadow: 0 -6px 16px rgba(40,110,160,.06); border-radius: 0 0 var(--radius) var(--radius);
}
.modal-foot .btns { display: flex; gap: 9px; flex: 0 0 auto; }
.foot-msg { font-size: 14px; color: var(--text-dim); line-height: 1.55; min-width: 0; }
.foot-msg strong { color: var(--accent); font-weight: 800; }
/* ポップアップの題名だけを大きくする。ここを子孫セレクタで書くと中の小見出しまで
   20px・900 になって崩れるため、.modal-body の中は明示的に元の大きさへ戻す */
.modal-box .detail-sec h4, .modal-body .detail-sec h4 { font-size: 14px; font-weight: 800; color: var(--text); margin: 0 0 10px; }
.modal-box .detail-sec h4 i, .modal-body .detail-sec h4 i { font-size: 13.5px; color: var(--accent); }
.modal-body .detail-sec { border-top: 1px solid var(--border-soft); margin-top: 20px; padding-top: 16px; }
/* 権限で節を隠したとき、先頭に来た節の上に区切り線と余白だけが残らないようにする */
.modal-body .detail-sec.is-first-visible { border-top: none; margin-top: 0; padding-top: 0; }
.modal-body .note { font-size: 13.5px; margin: 6px 0 0; }
/* 触ったセクションだけに印を付ける。保存されるのがどこかを、押す前に見て分かるようにする */
.sec-flag { margin-left: auto; padding: 2px 10px; border-radius: 99px; letter-spacing: 0; background: var(--surface-2); color: var(--text-faint); font-size: 13px; font-weight: 800; }
/* 「変更あり」はオレンジ（2026-08-18 遼様指示）。地は --ticket、文字は --text で 4.97:1。
   白抜きにすると 2.52:1 で字が飛ぶので、濃い文字を載せている。
   左のラインもバッジと同じ --ticket。以前は左から白へ抜けるグラデーションを敷いていたが、
   遼様のご指摘「グラデーションが来ると視認性が落ちる」により**廃止**した。
   面を塗らず、線1本だけで「ここが変わっている」を示す */
.detail-sec.is-dirty > h4 > .sec-flag { background: var(--ticket); color: var(--text); }
.detail-sec.is-dirty { border-left: 4px solid var(--ticket); margin-left: -14px; padding-left: 10px; border-radius: 0; background: none; }
.detail-sec.is-dirty > h4 { color: var(--ticket-deep); }
.sub-lbl { font-size: 13px; font-weight: 800; color: var(--text-faint); margin-bottom: 7px; display: flex; align-items: center; gap: 8px; }
.ro-mark { padding: 1px 8px; border-radius: 99px; background: var(--surface-2); color: var(--text-faint); font-size: 13px; font-weight: 800; }
.sched-count { font-size: 14px; font-weight: 800; color: var(--accent); white-space: nowrap; padding-bottom: 10px; }
.sw-closed { background: repeating-linear-gradient(45deg, var(--surface-2), var(--surface-2) 3px, var(--surface) 3px, var(--surface) 6px); border: 1px solid var(--border); }
.modal-body textarea {
  padding: 10px 13px; border: 1.5px solid var(--border); border-radius: var(--radius-sm); font-size: 16px;
  font-family: inherit; color: var(--text); background: var(--surface); transition: .15s; resize: vertical; line-height: 1.6; width: 100%;
}
.modal-body textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* 卒業（2026-08-17 追加）。退塾済みと同じ「在籍していない」扱いだが、
   円満に終わったケースなので灰色ではなく紫にして区別できるようにする */
.tag-graduated { background: var(--extra-bg); color: var(--extra); }

/* =====================================================================
   お知らせ配信の2カラム（2026-08-17）
   部品は生徒管理と共通（.split-2col / .list-pane / .detail-sec）。
   ここではお知らせ固有の見え方だけを足す
   ===================================================================== */
/* 取り下げ済みの行は薄く出す。消してしまうと「送ったはずのものが無い」と探すことになる */
.list-row.is-dim .nm, .list-row.is-dim .sub { color: var(--text-faint); }
/* 一覧の右端に出す既読の比率。未読が残っているものだけ色を付ける */
/* 新規作成の「配信日時」：日付欄と時刻欄を1行に並べる（WP9） */
.nt-publish-row { display: flex; gap: 8px; }
.nt-publish-row input { flex: 1 1 0; min-width: 0; }
.nt-read { font-size: 13px; font-weight: 800; color: var(--text-faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* 未読が残っているものだけ橙にする。ただし --ticket(#f08a1f) を選択中の行の地
   （--accent-soft #dcf0fd）に載せると 2.14:1 で数字が飛ぶため、濃い版を使う。
   意味の色（遅刻・注意＝橙）は変えていない */
.nt-read.has-unread { color: var(--ticket-deep); }
.nt-body {
  background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  padding: 13px 15px; font-size: 16px; line-height: 1.8; color: var(--text); white-space: normal;
}
.nt-link { margin-top: 10px; font-size: 14px; color: var(--text-dim); display: flex; align-items: center; gap: 8px; word-break: break-all; }
.nt-link i { color: var(--accent); }
.nt-read-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 7px; }
.nt-read-num { font-size: 15.5px; font-weight: 700; color: var(--text-dim); }
.nt-read-num b { font-size: 22px; color: var(--text); font-variant-numeric: tabular-nums; }
.nt-read-pct { font-size: 14px; font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
/* 名前は並べるだけ。人数が多いので1人1行にすると縦に伸びすぎる */
.nt-names { display: flex; flex-wrap: wrap; gap: 6px; }
.nt-name { display: inline-flex; align-items: baseline; gap: 6px; padding: 3px 10px; border-radius: 99px; font-size: 13.5px; font-weight: 700; }
.nt-name small { font-size: 13px; font-weight: 600; opacity: .75; font-variant-numeric: tabular-nums; }
.nt-name.is-read { background: var(--lesson-bg); color: var(--lesson); }
.nt-name.is-unread { background: var(--surface-2); color: var(--text-dim); }

/* =====================================================================
   コマチケット（2026-08-17 刷新）
   左＝生徒の一覧（残枚数つき）／右＝付与1件ごとの明細と使用履歴
   ===================================================================== */
.tk-remain {
  font-size: 13px; font-weight: 800; padding: 2px 8px; border-radius: 99px;
  background: var(--surface-2); color: var(--text-faint); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tk-remain.has { background: var(--ticket-bg); color: var(--ticket); }

/* 右カードの頭に置く3つの数（付与合計・使用ずみ・残り） */
.tk-sum { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 18px; }
.tk-sum-item {
  flex: 1; min-width: 120px; display: flex; align-items: baseline; gap: 8px;
  background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 10px 14px;
}
.tk-sum-item .l { font-size: 13px; font-weight: 700; color: var(--text-faint); }
.tk-sum-item .v { margin-left: auto; font-size: 26px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.tk-sum-item .v small { font-size: 13px; font-weight: 700; color: var(--text-faint); margin-left: 2px; }
.tk-sum-item .v.accent { color: var(--accent); }

/* 付与1件＝1枚のカード。中に使用履歴が並ぶ */
.tk-grant { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 13px 15px; margin-bottom: 12px; background: var(--surface); }
.tk-grant:last-child { margin-bottom: 0; }
.tk-grant.is-expired { background: var(--surface-2); opacity: .8; }
.tk-grant-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.tk-grant-name { font-size: 16px; font-weight: 800; color: var(--text); }
.tk-grant-count { margin-left: auto; font-size: 13.5px; font-weight: 700; color: var(--text-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tk-grant-count b { font-size: 20px; color: var(--accent); }
/* 消化のぐあいを1本の帯で。既読状況の帯と同じ部品を使い回す */
.tk-bar { height: 7px; border-radius: 99px; background: var(--surface-3); overflow: hidden; margin: 10px 0 8px; }
.tk-bar > span { display: block; height: 100%; background: var(--accent); border-radius: 99px; }
.tk-grant-meta { font-size: 13px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.tk-uses { margin-top: 10px; border-top: 1px dashed var(--border); padding-top: 8px; display: flex; flex-direction: column; }
.tk-use { display: flex; align-items: center; gap: 10px; padding: 6px 2px; font-size: 14px; border-bottom: 1px solid var(--border-soft); }
.tk-use:last-child { border-bottom: none; }
.tk-use .d { font-weight: 800; color: var(--text); min-width: 84px; font-variant-numeric: tabular-nums; }
.tk-use .s { color: var(--text-dim); font-weight: 700; font-variant-numeric: tabular-nums; }
.tk-use .c { color: var(--text-faint); font-size: 13px; }
.tk-use .a { margin-left: auto; }
.tk-use.is-empty { color: var(--text-faint); font-size: 14px; }
/* 「◯回目」（2026-10-10）。日付の左に、数字が揃うように */
.tk-use .n { font-weight: 800; color: var(--text-dim); min-width: 48px; font-variant-numeric: tabular-nums; }
/* 付与の見出しの「進行中：3回目（受けた2回／予約3回／全4回）」 */
.tk-progress { margin-top: 6px; font-size: 13.5px; font-weight: 700; color: var(--text-dim); font-variant-numeric: tabular-nums; }
/* 取り消し・訂正（2026-09-25）。付与カードの下に文字だけのボタンを並べる。使用履歴の各行の「取り消す」は右端 */
.tk-grant-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; padding-top: 9px; border-top: 1px dashed var(--border); }
.tk-grant-batch { font-size: 13px; font-weight: 700; color: var(--text-faint); margin-right: auto; }
.tk-grant-none { font-size: 13px; color: var(--text-faint); }
.tk-use-cancel { margin-left: 8px; padding: 4px 10px; font-size: 13px; }

/* 生徒を複数まとめて選ぶ名簿：学年ごとにまとめ、見出しを押すとその学年をまとめて選べる。
   コマチケットの一括付与・年度の更新の「卒業させる」・お知らせの宛先の3つで使い回す。
   クラス名を tk-（チケット）から stu-pick- に改めたのは、お知らせでも使うようになったため
   （2026-08-18。名前が実態と食い違うと、次に読む人が使ってよいか判断できない） */
.stu-pick-list {
  max-height: 320px; overflow-y: auto; padding: 12px;
  border: 1.5px solid var(--border-soft); border-radius: var(--radius-sm); background: var(--surface-2);
}
.stu-pick-group + .stu-pick-group { margin-top: 14px; }
.stu-pick-head {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: none; border: none; border-bottom: 1px solid var(--border); padding: 4px 2px 7px; margin-bottom: 8px;
  cursor: pointer; font-family: inherit;
}
.stu-pick-head .n { font-size: 13px; font-weight: 700; color: var(--text-faint); }
.stu-pick-head .pick { margin-left: auto; font-size: 13px; font-weight: 700; color: var(--accent); }
.stu-pick-head:hover .pick { text-decoration: underline; }
.stu-pick-head.is-on .pick { color: var(--text-faint); }
/* 学年の中の生徒はグリッドのまま。外枠は .stu-pick-list が持つので中では外す */
.stu-pick-list .student-check-grid { max-height: none; overflow: visible; border: none; padding: 0; background: transparent; }

/* 年度の更新の入口（2026-08-17）。①卒業 → ②進級 の順を、番号で目に見える形にする。
   順番を間違えると「中3で卒業」が「高1で卒業」として残り、卒業年度から辿れなくなる */
.year-end-steps { display: flex; flex-direction: column; gap: 10px; }
.year-end-step {
  display: flex; align-items: flex-start; gap: 11px; padding: 12px 14px;
  border: 1.5px solid var(--border-soft); border-radius: var(--radius-sm); background: var(--surface-2);
}
.year-end-step .no {
  flex: 0 0 auto; width: 25px; height: 25px; border-radius: 99px;
  background: var(--accent); color: #fff; font-size: 13.5px; font-weight: 900;
  display: inline-flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}
.year-end-step .t { font-size: 15.5px; font-weight: 800; color: var(--text); margin-bottom: 3px; }
.year-end-step .s { font-size: 13.5px; color: var(--text-dim); line-height: 1.6; }

/* =====================================================================
   申請ログ（2026-08-17 レイアウト改善）
   1件を1行の表に押し込まず、日付でまとめて「元のコマ → 振替先」を関係として描く
   ===================================================================== */
.log-list { display: flex; flex-direction: column; }
/* 日付の見出し。一覧の学年見出しと同じ部品（.list-pane-group）に件数だけ足す */
.log-day { display: flex; align-items: center; gap: 10px; border-radius: 8px; margin: 6px 0 2px; }
.log-day:first-child { margin-top: 0; }
.log-day-count { margin-left: auto; font-weight: 700; letter-spacing: 0; }
/* 種別の列は幅を固定する。中身に合わせると行ごとに生徒名の開始位置がずれて、
   縦に目で追えなくなる（表をやめた代わりに、列の頭だけは揃える） */
.log-item {
  display: grid; grid-template-columns: 56px 108px minmax(0, 1fr) auto;
  gap: 4px 12px; align-items: center; padding: 10px 4px; border-bottom: 1px solid var(--border-soft);
}
.log-item > .badge { justify-self: start; }
.log-item:last-child { border-bottom: none; }
.log-time { font-size: 13.5px; font-weight: 700; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.log-who { font-size: 15.5px; font-weight: 700; color: var(--text); display: flex; align-items: center; gap: 7px; min-width: 0; }
.log-actor { font-size: 13px; color: var(--text-faint); font-weight: 700; display: flex; align-items: center; gap: 5px; white-space: nowrap; }
/* 2行目。バッジの下に揃えると「その申請の中身」だと分かる */
.log-flow { grid-column: 2 / -1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.log-place {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 3px 11px; border-radius: 8px;
  background: var(--surface-2); color: var(--text-dim); font-size: 13.5px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.log-place b { font-weight: 800; color: var(--text); }
.log-place.is-to { background: var(--lesson-bg); color: var(--lesson); }
.log-place.is-to b { color: var(--lesson); }
/* 振替先が決まっていない欠席。放置すると振替が消えるので、ここだけは赤で目に入るようにする */
.log-place.is-todo { background: var(--absent-bg); color: var(--absent); font-weight: 800; gap: 6px; align-items: center; }
/* 取り消された行。淡い地（--surface-2）の上なので --text-faint だと 3.8:1 まで落ちる。
   取り消し線という「形」で既に区別できているので、文字自体はしっかり読める濃さにする */
.log-place.is-cancel { text-decoration: line-through; color: var(--text-quiet); }
.log-place.is-cancel b { color: var(--text-quiet); }
.log-arrow { color: var(--text-faint); font-size: 13px; }
/* 種別の印に添える件数 */
.chip-num { font-variant-numeric: tabular-nums; opacity: .75; font-weight: 800; }
.mini-date {
  padding: 5px 9px; border: 1.5px solid var(--border); border-radius: 8px;
  font-family: inherit; font-size: 13.5px; color: var(--text); background: var(--surface);
}
.mini-date:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* =====================================================================
   講習集計（2026-08-17 ツールチップ大量設置に伴う整理）
   ヒートマップの色は「白＝空きあり／橙＝7割以上／赤＝満席」。凡例と対で意味を持たせる
   ===================================================================== */
/* 統計カードの見出しに「？」を置くので、縦位置をそろえる */
.stat-card .lbl { display: flex; align-items: center; }
/* 列見出しはコマの呼び名（'17:50 - 19:10'）。他の画面と同じ形のまま1行で出す。
   幅の下限はHTMLの style="" ではなくここに置く（2026-08-18）。
   直書きの inline style はどのCSSより強いので、狭い画面用の 780px が一度も効いていなかった
   ＝「書いてあるのに効いていない」状態だった */
#ss-heatmap { min-width: 840px; }
.ss-slot-head { white-space: nowrap; font-variant-numeric: tabular-nums; }
.ss-cell { text-align: center; }
.ss-open { background: transparent; }
.ss-near { background: var(--ticket-bg); }
.ss-full { background: var(--absent-bg); color: #b7392f; font-weight: 800; }
.ss-closed { background: var(--surface-2); color: var(--text-faint); }
.legend-inline .ss-sw-open { background: var(--surface); border: 1px solid var(--border); }
.legend-inline .ss-sw-near { background: var(--ticket-bg); border: 1px solid var(--ticket); }
.legend-inline .ss-sw-full { background: var(--absent-bg); border: 1px solid var(--absent); }
.legend-inline .ss-sw-closed { background: var(--surface-2); border: 1px solid var(--border); }
/* 数字の列は右揃え（桁が揃って比べやすい） */
.data-table th.num, .data-table td.num { text-align: right; }
/* 警告でないポップアップの題名アイコンは青（既定の橙は確認・警告のとき用） */
.modal-box > h4.h-accent i { color: var(--accent); }

/* =====================================================================
   本文の器の幅で畳む（2026-08-18 遼様指示「PCで2画面レイアウトにしても読みやすく」）

   ここだけ @media ではなく @container を使う。理由：
   同じ1366pxの画面でも、左メニューを開いていれば本文は1098px、畳めば1254px。
   画面幅で判断すると「畳んで幅を空けたのにレイアウトが変わらない」ことになる。
   閾値は「その中身が成り立つ最小の器の幅」で決めてある。

   | 器の幅 | 何が変わるか |
   |---|---|
   | 1060px以下 | 一覧＋詳細・KPIとグラフの2カラムを縦に畳む |
   |  720px以下 | カードの余白を詰める／表は器の中で横スクロール／フォームは1列 |
   |  480px以下 | KPIカードを1列 |

   古いブラウザで @container が効かない場合は「畳まないまま」になるが、
   下の @media（画面幅）側でも同じ方向に畳むので、情報が欠けることはない。 */
@container mainc (max-width: 1060px) {
  .split-2col { grid-template-columns: minmax(0, 1fr); }
  .two-col { grid-template-columns: minmax(0, 1fr); }
  .detail-grid { grid-template-columns: minmax(0, 1fr); }
  .detail-grid > .detail-sec:nth-child(2) { border-top: 1px solid var(--border-soft); margin-top: 16px; padding-top: 14px; }
}
/* KPI＋グラフだけは、他の2カラムより早い 1190px で畳む（2026-08-19）。
   理由は .kpi-chart-split のコメントのとおりで、1:2 を保ったままグラフ側に 782px を
   確保できる器の下限が 1189px だから。これを割ったら、比率を崩した2カラムを見せずに縦へ畳む。
   畳んだら KPI は元どおり横並びのカードに戻す（縦一列の細長い帯にしない）。
   列数は auto-fit ではなく 2 で固定する（2026-08-18）。
   auto-fit だと器の幅しだいで 2列・3列・4列と変わり、カードが4枚なので
   3列のときだけ4枚目が1枚だけ次の行に残る。960px（1920pxの左右2分割）がちょうどそれで、
   4枚目の右に何も無い帯ができていた＝遼様のご指摘「右に無駄な余白が多い」そのもの。
   2列に固定すれば 2×2 になり、どの幅でも余りが出ない */
@container mainc (max-width: 1190px) {
  .kpi-chart-split { grid-template-columns: minmax(0, 1fr); }
  .stat-grid.is-stack { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; height: auto; }
  .stat-grid.is-stack .stat-card { display: block; }
}
@container mainc (max-width: 720px) {
  .panel { padding: 14px 14px; border-radius: 12px; }
  /* 表：自分の器の中で横スクロール（列を消さない）。
     .panel 自体に overflow を掛けると、中の生徒検索の候補メニューまで切られるので掛けない */
  .table-wrap .data-table { min-width: 560px; }
  .data-table th, .data-table td { padding: 9px 8px; font-size: 13.5px; white-space: nowrap; }
  /* 桁をそろえたい列（日時・金額・人数）は折り返さないが、
     **自由に書かれた文章の列は折り返す**（2026-08-18）。
     操作ログの「内容」は1セルが1148pxあり、683px（1366pxの左右2分割）では
     横に871pxスクロールしないと1行が読み終わらなかった。
     しかもオーバーレイのスクロールバーなので「横に動かせる」ことにも気づけない。
     文章は縦に伸びてよい。読めないより長いほうがよい */
  .data-table td.wrap-text, .audit-table td:last-child { white-space: normal; word-break: break-word; }
  .audit-table { min-width: 0; }
  .table-wrap .audit-table { min-width: 0; }
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  /* .stat-grid.is-stack はひとつ上の @container（1190px以下）で既に2列に固定してある。
     ここに同じ指定を並べると、片方だけ直したときに食い違うので置かない */
  .stat-card .num { font-size: 28px; }
  .form-row { gap: 10px; }
  .form-row .field { min-width: 100%; }
  .form-row .btn { width: 100%; justify-content: center; }
  .student-check-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .list-pane-body { max-height: 380px; }
  /* 振替管理（2026-08-22 にカレンダー型へ変更）。
     以前ここには「予定の箱の高さ上限を外す（#mk-timeline: max-height:none）」があった。
     縦に畳むと 一覧(380px)＋帯(53px) の下＝y=523 から始まる箱になり、683×700の画面では
     箱の下3分の2が画面の外に出るのに、中身が箱の中にあるのでページが伸びず
     **下が読めないのに何もできない**状態になっていたため。
     いまは右ペインに高さを固定した箱そのものが無い（押した日の予定は1日ぶんだけ）ので、
     打ち消しの指定も要らなくなった。代わりに、狭い幅ではマスと帯を1段小さくする。
     マスの外側に巻くリング（振替先が未定の赤い枠）は、隙間が詰まると隣のマスに削られるので
     はみ出し量も一緒に詰める。寸法は変数側だけで済ませてある */
  .sc-cal-grid { gap: 4px; }
  .sc-cal-day { --sc-ring-inset: -2px; --sc-ring-radius: 13px; min-height: 62px; padding: 4px; }
  /* 帯（.sc-cal-bar）の上書きは 2026-08-30 に撤去した。以前は共有部品の9px基準に合わせた
     8.5px の狭幅用の値だったが、共有側が 19px／13px へ上がった（遼様指摘1・下限13px）ので、
     ここで小さく戻すと狭い画面だけ読めない字に戻ってしまう。共有部品の値をそのまま使う */
  .mk-cal-summary { gap: 7px; }
  .head-actions { width: 100%; }
  .cal-grid { gap: 4px; }
  /* 申請ログ：狭いと1行に4つ並べると潰れるので、操作者と中身を下の行に落とす */
  .log-item { grid-template-columns: 54px 100px minmax(0, 1fr); gap: 4px 9px; }
  .log-actor { grid-column: 2 / -1; }
  .log-flow { grid-column: 1 / -1; }
  .tk-sum { flex-direction: column; }
  .tk-use { flex-wrap: wrap; }
  .qr-row { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .qr-row .qr-acts { justify-content: stretch; }
  .qr-row .qr-acts .btn { flex: 1 1 auto; justify-content: center; }
  .tc-card-head { gap: 7px; }
  .tc-acts .btn { flex: 1; justify-content: center; }
  .pr-rank-acts { margin-left: 0; width: 100%; }
  .pr-rank-acts .btn { flex: 1; justify-content: center; }
  .pr-sp .btn { width: 100%; justify-content: center; }
}
@container mainc (max-width: 480px) {
  /* 金額のカード（.stat-grid-money）も .stat-grid.is-stack に含まれるので別に書かない */
  .stat-grid, .stat-grid.is-stack { grid-template-columns: minmax(0, 1fr); }
  .student-check-grid { grid-template-columns: minmax(0, 1fr); }
}

/* =====================================================================
   スマホレスポンシブ（2026-08-13 遼様決定：全画面対応）
   90%以上はPC操作の想定だが、外出先などまれなスマホ操作でも全タブが使えるようにする。
   方針：
   - 640px以下でサイドナビを「上部の横スクロールバー」に変える（画面幅を全て本文に使う）
     ※ 2026-08-18 に 900px → 640px へ変更。1366pxを2分割した683pxでは、
       19項目が横1行に並ぶ帯よりアイコンだけの縦バーのほうが探しやすいため
   - 表はその器の中で横スクロール（PCのレイアウトを崩して情報を欠落させない）
   - フォームは1カラム落とし、モーダルは画面幅いっぱいに
   ===================================================================== */
@media (max-width: 640px) {
  .layout { flex-direction: column; }

  /* サイドナビ → 上に貼り付く帯。メニューの中身は右上のハンバーガーの中に畳む。
     以前は21項目を1行に並べて横スクロールさせていたが、指で横に送らないと
     右のほうのタブに辿り着けず、「どこまであるのか」も分からなかった（2026-09-16 遼様指示）。
     パネルを帯の真下に開くので、ここでは overflow を切らない（切ると開いた一覧が消える） */
  .sidenav {
    width: 100%; flex: 0 0 auto; height: auto; max-height: none;
    position: sticky; top: 0;   /* z-index は基本の .sidenav（100）のまま */
    flex-direction: row; align-items: center; gap: 6px;
    padding: 8px 10px; overflow: visible;
    border-right: none; border-bottom: 1px solid var(--border-soft);
  }
  /* 帯（大分類）とパネル（小項目）は、ハンバーガーを押したときだけ画面幅いっぱいに開く。
     位置の基準は .sidenav（position:sticky も「位置を指定した要素」なので基準になれる） */
  .nav-list {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    max-height: 78vh; overflow-y: auto;
    padding: 8px 10px 12px; background: var(--surface);
    border-bottom: 1px solid var(--border-soft); box-shadow: 0 12px 26px rgba(15, 23, 42, .16);
  }
  .sidenav.is-menu-open .nav-list { display: block; }
  /* 小項目は「大分類のすぐ下に開く」（アコーディオン）。指で押す幅では
     PCのように右へ浮かせる場所が無いので、字下げと縦線で親子を示す */
  .nav-panel {
    position: static; width: auto; max-height: none; overflow: visible;
    margin: 0 0 6px 14px; padding: 2px 0 2px 8px;
    border: none; border-left: 2px solid var(--accent-dim); border-radius: 0;
    background: none; box-shadow: none;
  }
  .nav-panel-title { display: none; }   /* すぐ上の大分類のボタンと同じ文字になるので省く */
  /* 説明もスマホでは出さない（2026-09-17 遼様「スマホは特に出なくてOK」）。
     指で操作する幅では、1行でも縦が伸びるほど小項目までの距離が遠くなる */
  .nav-panel-desc { display: none; }
  .nav-cat-caret { transition: transform .12s; }
  .nav-cat.is-open .nav-cat-caret { transform: rotate(90deg); }
  /* 右上のハンバーガー。開いている間は × に変わる（script.js が差し替える） */
  .nav-burger {
    display: flex; align-items: center; gap: 7px; order: 9; flex: 0 0 auto;
    margin-left: 6px; padding: 8px 11px;
    border: 1px solid var(--accent-dim); border-radius: 10px; background: var(--accent-soft);
    color: var(--accent-deep); font-family: inherit; font-size: 13.5px; font-weight: 800;
    cursor: pointer;
  }
  .nav-burger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .nav-burger i { font-size: 15px; }
  .brand { padding: 0 2px 0 0; flex: 0 0 auto; }
  /* バッジの中身を文字から目印の絵に入れ替える（消すと現在地が分からなくなるので、
     水色のバッジ自体は残す）。「SCHOOL Manager」の文字だけで105pxあり、
     校舎名・ハンバーガーと並べると右端が画面の外に出ていた（400px幅で実測） */
  .brand-badge {
    display: flex; align-items: center; justify-content: center;
    width: 38px; height: 34px; padding: 0; border-radius: 9px; font-size: 18px;
  }
  .brand-mark { display: inline-block; }
  /* 文字は消さずに「見えないだけ」にする（読み上げソフトからバッジの名前を消さない） */
  .brand-full {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  .school-switcher { margin: 0 4px; padding: 6px 8px; flex: 0 0 auto; }
  .school-switcher label { display: none; }
  .school-switcher select { width: auto; padding: 6px 8px; font-size: 13px; }
  /* 横並びメニューでは1行に詰める（縦に伸ばすとメニューの帯が厚くなる） */
  .school-fixed { display: flex; align-items: baseline; gap: 3px; white-space: nowrap; }
  .school-fixed-prefix { display: inline; font-size: 13px; }
  .school-fixed-main { display: inline; font-size: 13.5px; }
  /* 開いた一覧の中は縦積み。1行に詰めていた頃の white-space:nowrap は要らない */
  .nav-item, .nav-cat { width: 100%; padding: 10px 11px; font-size: 14.5px; margin-bottom: 1px; }
  .nav-item:hover { transform: none; }
  .side-foot { margin-top: 0; margin-left: auto; padding-top: 0; border-top: none; flex: 0 0 auto; order: 8; }
  .side-foot .who-wrap { display: none; }     /* 名前はスペースの都合で省略（アバターで判別） */

  /* 狭い幅では下に固定のメニューが無い（横並びの上バーになる）ので、
     40pxの下余白は行き場のない空白だった。上と同じ考え方で16pxにする。
     ※ .content は @container の器そのものなので、器自身の余白だけは
        @container では書けない（コンテナは自分自身を条件にできない）。ここに残す */
  .content { padding: 16px 12px 16px; max-width: none; }
  /* 上の横並びメニューぶんだけ下げて貼り付く（--sticky-top は script.js が実測して入れる）。
     幅ではなく .layout の flex-direction を見て決めているので、この閾値と食い違わない */
  .content-head { margin: -16px -12px 14px; padding: 12px 12px 10px; }
  .content-head h2 { font-size: 22px; }

  /* 講習集計のヒートマップなど、固定min-widthの表もスクロールに任せる。
     列見出しが '17:50 - 19:10' なので、狭い画面でも折り返さない幅までは確保する */
  #ss-heatmap { min-width: 780px; }
}

/* ポップアップは本文の器の外（body直下）にあるので、@container では届かない。
   大きさを決めているのは画面そのものなので、ここは今までどおり画面幅で見る。
   閾値を 900px のまま据え置いているのも同じ理由（メニューの形とは無関係） */
@media (max-width: 900px) {
  .modal-overlay { padding: 12px; align-items: flex-start; overflow-y: auto; }
  .modal-box { width: 100%; max-width: 560px; margin: 20px auto; padding: 18px; max-height: none; }
  /* 中身が長いポップアップだけは高さを縛ったままにする。
     ここで max-height:none を効かせると保存ボタンが画面外に出て見失う */
  .modal-box.modal-tall { max-height: 88vh; padding: 0; margin: 8px auto; }
  .modal-tall .modal-head { padding: 16px 16px 12px; }
  .modal-tall .modal-body { padding: 14px 16px 18px; }
  .modal-tall .modal-foot { padding: 12px 16px; flex-wrap: wrap; }

  /* @container が効かないブラウザ向けの受け皿（画面幅で同じ方向に畳む）。
     効くブラウザでは上の @container が先に条件を満たすので、二重に当たっても結果は同じ */
  .split-2col, .two-col, .detail-grid, .kpi-chart-split { grid-template-columns: minmax(0, 1fr); }
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  /* 縦積みのKPIも、畳んだら 2×2 の並びに戻す（@container が効く環境と同じ姿にする）。
     ここを書き忘れると、古いブラウザだけ4枚が縦一列に並んで異様に長い画面になる */
  .stat-grid.is-stack { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; height: auto; }
  .stat-grid.is-stack .stat-card { display: block; }
  .table-wrap .data-table { min-width: 560px; }
  /* 操作ログの表だけは下限を外す（2026-08-19）。
     上の @container 側では外してあったのに、この受け皿の .table-wrap .data-table が
     **後ろに書いてある＝同じ強さなら後勝ち**で 560px を復活させていた。
     683px（1366pxの左右2分割）では器が526pxなので、34pxぶん「内容」列の右端が
     横スクロールに隠れていた。受け皿は必ず対で書く（すぐ下の is-stack と同じ話） */
  .table-wrap .audit-table { min-width: 0; }
}
@media (max-width: 420px) {
  /* 上の @media (max-width: 900px) は @container より後ろに書いてあるので、
     そのままだと「器480px以下は1列」という @container の指定を上書きしてしまう。
     .stat-grid と同じように、is-stack もここで1列に戻す（受け皿は必ず対で書く） */
  .stat-grid, .stat-grid.is-stack { grid-template-columns: minmax(0, 1fr); }
  .student-check-grid { grid-template-columns: minmax(0, 1fr); }
}

/* 400px級の端末（2026-09-17 最終レビューの実測で横スクロールが72px出ていた）。
   はみ出していたのはハンバーガーの「メニュー」の文字で、
   バッジ・校舎名と1行に並べると帯が画面の幅を越えていた。
   ここでは文字を隠してアイコンだけにする。読み上げソフト向けの名前は
   ボタンの aria-label が持つ（script.js が「メニュー」「閉じる」を入れ替える）ので、
   .brand-full のような「見えないだけ」にはしない（同じ名前が2つ読み上げられるため） */
@media (max-width: 480px) {
  .nav-burger-label { display: none; }
  .nav-burger { gap: 0; padding: 8px 10px; }
}

/* ============================================================
   QRコードでログイン（生徒管理のプロフィールカード内）
   ============================================================ */
/* 保護者用・生徒用の2行。色はアプリのモード表示と揃える（保護者＝緑／生徒＝青紫）。
   「どちらの紙の話をしているか」が一目で分かることが、この機能の事故防止そのもの */
.qr-rows { display: flex; flex-direction: column; gap: 10px; }
.qr-row {
  display: grid; grid-template-columns: 116px minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
  padding: 11px 13px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  background: var(--surface);
}
.qr-row .qr-mode {
  display: inline-flex; align-items: center; gap: 6px; justify-self: start;
  padding: 4px 11px; border-radius: 999px; font-size: 14px; font-weight: 700;
}
.qr-row.is-parent .qr-mode { background: var(--lesson-bg); color: var(--lesson-deep); }
.qr-row.is-student .qr-mode { background: var(--extra-bg); color: var(--extra); }
.qr-row .qr-state { font-size: 14px; color: var(--text-dim); min-width: 0; }
.qr-row .qr-state .qr-issued { font-weight: 700; color: var(--text); }
.qr-row .qr-state .qr-none { color: var(--text-faint); }
.qr-row .qr-acts { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }

/* ============================================================
   QRコードのまとめて印刷（2026-08-19）：一覧の選択モード
   ============================================================ */
/* 「その他」→「QRコードをまとめて印刷」の間だけ、一覧の頭に出る帯。
   保護者用・生徒用の2つの印刷ボタンの色は、カード内のQRの行（.qr-row）の
   モード色とまったく同じ組み合わせにする（同じ意味の色を画面ごとに変えない） */
.qr-pick-bar {
  display: flex; flex-direction: column; gap: 6px;
  padding: 9px 10px; border-top: 1px dashed var(--border-soft);
  background: var(--surface-2);
}
.qr-pick-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.qr-pick-count { font-size: 14px; font-weight: 700; color: var(--text); }
.qr-pick-prints .qr-pick-print { flex: 1 1 auto; justify-content: center; }
.qr-pick-print.is-parent { background: var(--lesson-bg); color: var(--lesson-deep); border: 1px solid var(--lesson-deep); }
.qr-pick-print.is-student { background: var(--extra-bg); color: var(--extra); border: 1px solid var(--extra); }

/* 行頭の印。色ではなく形で見分ける（空の四角＝未選択／チェック入り＝選択済み／
   斜線＝発行できない）。在籍していない生徒は title でも理由を出している */
.list-row .pick-box { flex: 0 0 auto; width: 20px; text-align: center; font-size: 20px; }
.list-row .pick-box .fa-regular { color: var(--text-dim); }
.list-row .pick-box .fa-solid.fa-square-check { color: var(--accent); }
.list-row .pick-box.is-off { color: var(--text-faint); font-size: 15.5px; }
.list-row.is-picked { background: var(--accent-soft); }

/* 印刷前の確認に出す名簿。人数が多い日は長くなるので、確認文はそのままに名簿だけを送る */
.qr-pick-names {
  max-height: 160px; overflow-y: auto;
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  padding: 8px 10px; margin: 8px 0;
  font-size: 14px; line-height: 1.8; background: var(--surface-2);
}

/* 狭いときは横3列だと文字が2〜3行に折れて読めない。種別・状態・操作を縦に積む。
   2026-08-18：この畳み方は上の @container mainc (max-width: 720px) に移した
   （画面幅ではなく「カードが置かれている器の幅」で決めるため。
     左メニューを開いているかどうかで、同じ画面幅でもカードの幅は156px変わる） */

/* ============================================================
   QRコードの印刷用紙
   ============================================================ */
/* 画面には出さない。印刷のときだけ、この1枚“だけ”を出す。
   body 直下に置いてあるので、印刷時は body の直接の子を全部消してこれだけ残せばよい */
.qr-print-sheet { display: none; }
/* 配布チェックリスト（2026-10-11）。印刷のときだけ body に ck-printing が付き、この用紙だけが出る（students.js printStudentChecklist） */
.ck-print-sheet { display: none; }
@media print {
  body.ck-printing > * { display: none !important; }
  body.ck-printing > .ck-print-sheet { display: block !important; }
  body.ck-printing { background: #fff; }
  .ck-print-sheet { color: #000; font-family: "BIZ UDPGothic", "Zen Maru Gothic", sans-serif; }
  .ck-page { break-after: page; page-break-after: always; padding: 0; }
  .ck-page:last-child { break-after: auto; page-break-after: auto; }
  .ck-head { display: flex; justify-content: space-between; align-items: flex-end; border-bottom: 2px solid #000; padding-bottom: 2mm; margin-bottom: 3mm; }
  .ck-head h1 { font-size: 16pt; margin: 0; }
  .ck-head .ck-meta { font-size: 10.5pt; text-align: right; line-height: 1.6; }
  .ck-what { font-size: 11pt; margin: 0 0 3mm; }
  .ck-what span { display: inline-block; border-bottom: 1px solid #000; min-width: 95mm; }
  .ck-cols { display: flex; gap: 6mm; }
  .ck-tbl { flex: 1; border-collapse: collapse; font-size: 10.5pt; }
  .ck-tbl th, .ck-tbl td { border: 1px solid #555; padding: 0 1.5mm; height: 6.6mm; text-align: left; }
  .ck-tbl th { background: #eee; font-size: 9.5pt; height: 6mm; }
  .ck-tbl .c { width: 7mm; text-align: center; }
  .ck-tbl .g { width: 10mm; }
  .ck-tbl .m { width: 22mm; }
  .ck-tbl tr.sep td { border-top: 2px solid #000; }
  .ck-tbl .bx { display: inline-block; width: 3.6mm; height: 3.6mm; border: 1.2px solid #000; vertical-align: middle; }
  .ck-tbl .tr { font-size: 8.5pt; border: 1px solid #000; border-radius: 2px; padding: 0 1mm; margin-left: 1.5mm; }
  .ck-foot { font-size: 9pt; text-align: right; margin-top: 2mm; }
}

@media print {
  /* 印刷を始めた時だけ body に qr-printing が付く（students.js）。
     付いていない普通の印刷（Ctrl+P）では、これまでどおり画面がそのまま出る */
  body.qr-printing > * { display: none !important; }
  body.qr-printing > .qr-print-sheet { display: block !important; }
  body.qr-printing { background: #fff; }

  @page { size: A4 portrait; margin: 16mm; }

  /* 用紙は必ず1枚に1つ。2つ並べられない構造にしてある。
     色は指定せず必ず黒にする（薄い紺のまま印刷すると、かすれて読みにくくなる） */
  .qr-sheet, .qr-sheet * { color: #000; }
  .qr-sheet { font-size: 12pt; }
  .qr-sheet-band {
    border: 3pt solid #000; border-radius: 4mm; padding: 4mm 6mm; text-align: center;
    margin-bottom: 8mm;
  }
  /* 白黒で印刷しても離れた場所から見分けられるように、枠線の形を変える
     （保護者用＝実線／生徒用＝破線）。文字だけに頼らない */
  .qr-sheet.is-student .qr-sheet-band { border-style: dashed; }
  .qr-sheet-band .qr-sheet-mode { font-size: 22pt; font-weight: 700; display: block; letter-spacing: .1em; }
  .qr-sheet-band .qr-sheet-for { font-size: 11pt; margin-top: 1mm; }
  .qr-sheet-who { text-align: center; font-size: 16pt; font-weight: 700; margin-bottom: 6mm; }
  .qr-sheet-img { width: 62mm; margin: 0 auto 6mm; }
  .qr-sheet-img svg { display: block; width: 100%; height: auto; }
  .qr-sheet-steps { margin: 0 0 6mm; padding-left: 6mm; font-size: 11pt; line-height: 1.9; }
  .qr-sheet-warn {
    border: 1pt solid #000; border-radius: 2mm; padding: 3mm 4mm; font-size: 10.5pt; line-height: 1.8;
  }
  .qr-sheet-foot { margin-top: 6mm; font-size: 9.5pt; text-align: right; }

  /* まとめて印刷（2026-08-19）：1人1ページ。用紙ごとに必ず改ページする。
     最後の1枚の後ろでは改ページしない（白紙が1枚余計に出るプリンタがあるため） */
  .qr-print-sheet .qr-sheet { break-after: page; page-break-after: always; }
  .qr-print-sheet .qr-sheet:last-child { break-after: auto; page-break-after: auto; }
}

/* 印刷プレビューを開かずに中身を確かめたいとき用（開発時のみ。既定では効かない） */
body.qr-preview .qr-print-sheet { display: block; padding: 24px; background: #fff; }

/* ===== 勤怠の承認（2026-08-18） =====
   一覧をテーブルにしないのは、1件ごとに読む情報の量が多いため
   （出勤・退勤・休憩・実働・深夜・本人のメモ・差し戻しの理由）。
   横に伸びる表にすると、承認の判断に必要な情報が右端に押し出される。 */
.tc-card {
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  padding: 13px 15px; margin-bottom: 10px; background: var(--surface);
}
.tc-card.is-pending { border-color: var(--ticket); box-shadow: 0 0 0 2px var(--ticket-bg); }
.tc-card-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tc-pick { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; color: var(--text-dim); cursor: pointer; }
.tc-when { font-size: 16px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tc-who { font-size: 16px; font-weight: 700; color: var(--text); }
.tc-figs { display: flex; align-items: baseline; gap: 8px 18px; flex-wrap: wrap; margin-top: 10px; }
.tc-fig { font-size: 13px; font-weight: 700; color: var(--text-dim); white-space: nowrap; }
.tc-fig b { font-size: 18px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; margin-right: 3px; }
.tc-fig.is-sum b { color: var(--accent-deep); }
/* 深夜・日付またぎは「気づかないと給与を間違える」ので、文字だけでなく地色でも出す */
.tc-mark {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 6px;
  padding: 2px 8px; border-radius: 99px; font-size: 13px; font-weight: 800;
  background: var(--surface-3); color: var(--accent-deep);
}
.tc-mark.is-night { background: var(--extra-bg); color: var(--extra); }
.tc-slots { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 9px; }
.tc-slot {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 99px;
  font-size: 13px; font-weight: 700; background: var(--surface-2); color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.tc-slot.is-night { background: var(--extra-bg); color: var(--extra); }
.tc-note {
  display: flex; align-items: flex-start; gap: 7px; margin-top: 9px;
  font-size: 13.5px; color: var(--text-dim); line-height: 1.7;
}
.tc-note i { margin-top: 3px; flex: 0 0 auto; color: var(--text-faint); }
.tc-note.is-reject { color: var(--absent-deep); }
.tc-note.is-reject i { color: var(--absent); }
.tc-acts { display: flex; justify-content: flex-end; gap: 9px; margin-top: 12px; flex-wrap: wrap; }

/* 対象月の外に残っている承認待ち（2026-08-18）。
   未承認は給与に入らない＝そのまま払い漏れになるので、今月の画面を見ているだけで
   気づけないことを画面の側から知らせる。地はオレンジ（承認待ちの意味の色）に揃え、
   文字は濃い色を載せる（白抜きは 2.5:1 しか出ず読めない） */
.tc-other-months {
  display: flex; align-items: flex-start; gap: 9px; margin-bottom: 14px;
  padding: 11px 14px; border-radius: var(--radius-sm);
  background: var(--ticket-bg); border: 1px solid var(--ticket);
  font-size: 14px; line-height: 1.75; color: var(--text);
}
.tc-other-months i { margin-top: 3px; flex: 0 0 auto; color: var(--ticket-deep); }
.tc-other-months b { font-weight: 800; }

/* ===== 給与のマスター（ランク・講師ごとの設定・口座） ===== */
.pr-rank, .pr-sp {
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  padding: 12px 14px; margin-bottom: 9px; background: var(--surface);
}
.pr-rank.is-off, .pr-sp.is-off { background: var(--surface-2); opacity: .75; }
.pr-rank-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pr-rank-name { font-size: 18px; font-weight: 800; color: var(--text); }
.pr-rank-count { font-size: 13px; font-weight: 700; color: var(--text-faint); }
.pr-rank-acts { margin-left: auto; display: flex; gap: 7px; flex-wrap: wrap; }
.pr-rank-rates { display: flex; gap: 8px 16px; flex-wrap: wrap; margin-top: 9px; }
.pr-rate { font-size: 13.5px; font-weight: 700; padding: 3px 10px; border-radius: 99px; font-variant-numeric: tabular-nums; }
.pr-rate.is-now { background: var(--lesson-bg); color: var(--lesson-deep); }
.pr-rate.is-next { background: var(--ticket-bg); color: var(--ticket-deep); }
/* 単価が無いランクは金額が出せない＝設定漏れ。目立たせないと気づかれない */
.pr-rate.is-none { background: var(--absent-bg); color: var(--absent-deep); }

.pr-sp { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pr-sp-main { flex: 1; min-width: 240px; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.pr-sp-name { font-size: 17px; font-weight: 800; color: var(--text); }
.pr-sp-sum { font-size: 14px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.pr-sp-sum.is-none { color: var(--absent-deep); font-weight: 700; }
.pr-sp-next {
  flex: 1 1 100%; display: flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 700; color: var(--ticket-deep);
}

/* 狭いときは承認ボタンとカードの中身が横に潰れて読めなくなる。
   2026-08-18：この畳み方も @container mainc (max-width: 720px) に移した（上の qr-row と同じ理由） */

/* 暗証番号の伏せ字（2026-08-30）。type="password" にするとブラウザのパスワードマネージャーが
   「保存しますか？」と毎回聞いてくるので、文字欄のまま CSS で伏せる。見た目は同じ */
.pin-mask{-webkit-text-security:disc;text-security:disc;}

/* ============================================================
   生徒カルテ・成績の写真（2026-08-31 要望バッチ WP4。karte.js）
   編集ポップアップの「申し送り」の下に置いた2つの節と、写真を大きく見るポップアップ。
   文字は 13px を下限にする（M-4b）。
   ============================================================ */
.karte-block { margin-top: 14px; }
.karte-block:first-of-type { margin-top: 0; }
.karte-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.karte-chip { font-size: 13.5px; padding: 5px 12px; display: inline-flex; align-items: center; gap: 5px; }
.karte-chip.is-on { background: var(--lesson-bg); border-color: var(--lesson-deep); color: var(--lesson-deep); }
/* もう一方（得意⇔苦手）に入っている科目。押せないことと、その理由（どちらに入っているか）を文字で出す */
.karte-chip.is-blocked { opacity: .5; cursor: not-allowed; }
.karte-chip-why { font-size: 13px; font-weight: 700; color: var(--text-faint); }
.karte-chip-other { border-style: dashed; }
.karte-other { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.karte-other input, .karte-add-row input, .karte-add-row textarea, .karte-item.is-editing textarea {
  flex: 1; min-width: 220px; padding: 9px 12px; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  font-size: 15px; font-family: inherit; color: var(--text); background: var(--surface); transition: .15s;
}
.karte-other input:focus, .karte-add-row input:focus, .karte-add-row textarea:focus, .karte-item.is-editing textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.karte-add-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; margin-top: 8px; }
.karte-add-row .btn { height: 40px; }
.karte-list { display: flex; flex-direction: column; gap: 6px; }
.karte-item {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px 12px; padding: 8px 12px;
  border: 1px solid var(--border-soft); border-radius: 10px; background: var(--surface-2);
}
.karte-item-text { flex: 1; min-width: 200px; font-size: 14px; line-height: 1.6; color: var(--text); font-weight: 600; white-space: pre-wrap; word-break: break-word; }
.karte-item-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; color: var(--text-faint); font-weight: 700; font-variant-numeric: tabular-nums; }
.karte-item-meta .btn-link { padding: 0 4px; font-size: 13px; }
.karte-item.is-editing { flex-direction: column; align-items: stretch; }
.karte-item.is-editing textarea { width: 100%; min-width: 0; }
.karte-item-actions { display: flex; gap: 8px; justify-content: flex-end; }
.karte-summary { font-size: 15.5px; font-weight: 600; color: var(--text); }

.doc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; margin-bottom: 12px; }
.doc-card { border: 1px solid var(--border-soft); border-radius: 10px; background: var(--surface-2); padding: 8px; display: flex; flex-direction: column; gap: 4px; }
.doc-thumb-btn { border: none; padding: 0; background: var(--surface-3); border-radius: 8px; cursor: pointer; overflow: hidden; aspect-ratio: 4 / 3; display: block; width: 100%; }
.doc-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.doc-title { font-size: 14px; font-weight: 700; color: var(--text); line-height: 1.4; }
.doc-meta { font-size: 13px; color: var(--text-faint); font-weight: 700; }
.doc-card .btn-link { align-self: flex-start; padding: 2px 4px; font-size: 13px; }
.doc-form { padding: 10px 12px; border: 1px dashed var(--border); border-radius: 10px; }
.doc-form .field input[type="file"] { padding: 8px 10px; font-size: 14px; }

.sdoc-view-box { max-height: 92vh; }
.sdoc-view-meta { font-size: 13.5px; }
.sdoc-view-img { display: flex; justify-content: center; align-items: center; background: var(--surface-3); border-radius: 10px; overflow: auto; max-height: 68vh; }
.sdoc-view-img img { max-width: 100%; max-height: 68vh; object-fit: contain; display: block; }
.sdoc-view-foot { display: flex; justify-content: flex-end; margin-top: 14px; }

/* チケットの「使えない日時」（2026-08-31 WP5b、遼様の決定 4/24）。
   付与ポップアップの中の要約行と、2枚目のポップアップ（日付×コマの選択）。
   赤（absent）は「使えない・要対応」の意味なので、不可の印はそれに揃える */
.tk-blocks-field { grid-column: 1 / -1; }
.tk-blocks-row { display: flex; align-items: flex-start; gap: 10px; flex-wrap: wrap; }
.tk-blocks-summary { flex: 1 1 240px; font-size: 14px; font-weight: 600; color: var(--text-dim); line-height: 1.55; padding-top: 4px; }
.tk-blocks-summary.has-blocks { color: var(--absent-deep); font-weight: 700; }
/* 付与の明細（右カード）に出す一覧 */
.tk-grant-blocks { margin: 6px 0 8px; font-size: 13.5px; font-weight: 700; color: var(--absent-deep); line-height: 1.6; }
.tk-grant-blocks i { margin-right: 5px; }
/* 曜日一括の7ボタン。押してある曜日は不可の色（赤）で塗り、aria-pressed も立てる */
.tkblk-dow-row { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.tkblk-dow-btn.is-on { background: var(--absent-bg); border-color: #f0a8a3; color: #b7392f; }
.tkblk-dow-btn.is-on:hover { background: var(--absent-bg); color: #b7392f; }
/* 左＝カレンダー／右＝その日のコマ。狭いときは縦に並べる */
.tkblk-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; }
@media (max-width: 720px) { .tkblk-layout { grid-template-columns: minmax(0, 1fr); } }
.tkblk-day-btn { margin-bottom: 10px; }
.tkblk-day-btn.is-on { background: var(--absent-bg); border-color: #f0a8a3; color: #b7392f; }
#tkblk-slots .cal-slot-list { margin-top: 4px; }
#tkblk-slots .note { margin: 0 0 8px; font-size: 14px; }

/* =====================================================================
   コマ充足管理（2026-08-31 要望バッチ WP8、決定10）
   マス目は定員設定の .cap-grid / .cap-cell をそのまま使い、充足率の色は講習集計の
   ss-open / ss-near / ss-full と同じ凡例にそろえる。変更予約の印（.oc-up）は
   「これから変わる」の意味で追加授業の紫（--extra）を使う（振替の緑・欠席の赤と混ざらない色）
   ===================================================================== */
/* 左のマス目（734px）が入るときだけ2カラム。入らない器では縦に積む（横スクロールで日曜が隠れないように） */
#tab-occupancy .two-col { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
@container mainc (max-width: 1240px) { #tab-occupancy .two-col { grid-template-columns: minmax(0, 1fr); } }
.oc-asof { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.oc-asof-lbl { font-size: 13px; font-weight: 700; color: var(--text-dim); display: inline-flex; align-items: center; }
.oc-asof-label { font-size: 13.5px; font-weight: 700; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.oc-legend { margin-top: 12px; }
.oc-cell { gap: 4px; }
.oc-cell.ss-near, .oc-cell.ss-near:hover { background: var(--ticket-bg); border-color: var(--ticket); }
.oc-cell.ss-full, .oc-cell.ss-full:hover { background: var(--absent-bg); border-color: var(--absent); }
.oc-cell.ss-full .tt, .oc-cell.ss-full .tt .u { color: #b7392f; }
.oc-cell.is-on, .oc-cell.is-on:hover { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.oc-cell .oc-rate { font-size: 13px; font-weight: 700; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.oc-up {
  display: inline-flex; align-items: center; gap: 3px; white-space: nowrap;
  font-size: 13px; font-weight: 800; color: var(--extra-deep); background: var(--extra-bg);
  border-radius: 99px; padding: 1px 7px;
}
.oc-sum { font-size: 14px; color: var(--text-dim); margin: 0 0 10px; }
.oc-sum b { color: var(--text); font-size: 15.5px; }
.oc-row .rw { flex: 1; min-width: 0; }
.oc-row .oc-status { font-weight: 700; margin-top: 2px; }
.oc-row.is-starting, .oc-row.is-ending { border-radius: 10px; padding-left: 8px; padding-right: 8px; }
.oc-row.is-starting { background: var(--extra-bg); }
.oc-row.is-starting .oc-status { color: var(--extra-deep); }
.oc-row.is-ending { background: var(--absent-bg); }
.oc-row.is-ending .oc-status { color: var(--absent-deep); }
.oc-open-btn { flex: 0 0 auto; }

/* 出欠記録の修正の名簿に出す、保護者からの遅刻連絡の印（2026-09-18 遼様のご要望）。
   スタッフアプリの .tea-late と同じ意味・同じ色（注意のオレンジ＝--ticket 系）。
   送信待ちの札（.ov-pending-tag）と並ぶので、塗りつぶしではなく淡い地＋濃い文字にして役割を分ける */
.ov-late { display: inline-flex; align-items: center; gap: 4px; margin-left: 4px; padding: 1px 8px;
  border-radius: 999px; background: var(--ticket-bg); color: var(--ticket-deep);
  font-size: 13px; font-weight: 700; white-space: nowrap; }
/* 走る人のアイコンは 2026-09-19 遼様のご指示で外した（文字と色だけ）。アイコン用の指定（.ov-late i）も一緒に消した */

/* 振替を付けない休館の選択（2026-09-22 C-2）。休館日の1日の画面の、終日まとめての下に出る */
.hol-nomakeup { margin: 8px 0 4px; padding: 10px 12px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); background: var(--surface); }
.hol-nomakeup.is-on { border-color: var(--absent); background: var(--absent-bg); }
.hol-nomakeup-label { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 14.5px; cursor: pointer; }
.hol-nomakeup-label input { width: 18px; height: 18px; }
.hol-nomakeup .note { margin: 6px 0 0; }

/* 自動で届くお知らせの文面（2026-09-22 C-1。notice-templates.js） */
.ntpl-custom { font-size: 13px; font-weight: 700; color: var(--accent-deep, var(--accent)); white-space: nowrap; }
.ntpl-editor h3 { margin: 0 0 4px; }
.ntpl-editor .note { margin: 2px 0; }
.ntpl-editor .field { margin-top: 12px; }
.ntpl-editor .field label { display: block; font-size: 13.5px; font-weight: 700; margin-bottom: 4px; }
.ntpl-editor input[type="text"], .ntpl-editor textarea { width: 100%; box-sizing: border-box; font-size: 15px; line-height: 1.6; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); font-family: inherit; }
.ntpl-tokens { margin-top: 12px; }
.ntpl-token-btns { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.ntpl-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.ntpl-preview { margin-top: 12px; padding: 12px 14px; background: var(--surface-2); border-radius: var(--radius-sm); }
.ntpl-preview-title { margin: 6px 0; font-weight: 800; }
.ntpl-preview-body { margin: 0; font-size: 14.5px; line-height: 1.7; }
.ntpl-default { margin-top: 14px; font-size: 14px; }
.ntpl-default summary { cursor: pointer; font-weight: 700; color: var(--text-dim); }
.ntpl-default-body { margin: 6px 0; line-height: 1.7; color: var(--text-dim); }
.ntpl-switch { margin: 0 0 12px; }

/* きょうだい・紹介者の選択（2026-09-22）。裏の select は値を持つだけで見せず、打ち込んで絞り込める欄をかぶせる */
select.choice-picker-src { display: none; }
.choice-picker { display: flex; align-items: center; gap: 6px; }
.choice-picker input { flex: 1; }
.choice-picker-none { color: var(--text-dim); font-size: 14px; }
/* ===== 料金表（売上管理の1節。2026-09-26 取り消し・削除機能 第2弾）=====
   行＝項目、列＝世代。前の世代から変わった値だけ太字にして、何が変わったかを表の上で読めるようにする */
.pb-table th, .pb-table td { vertical-align: top; }
.pb-table tbody th { text-align: left; white-space: nowrap; }
.pb-table .pb-gen-head { min-width: 150px; }
.pb-gen-from { font-weight: 700; margin-top: 4px; }
.pb-table td.pb-changed { font-weight: 700; }
.pb-wide { grid-column: 1 / -1; }
.pb-months { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.pb-month { display: inline-flex; align-items: center; gap: 4px; font-size: 14px; }
