@import url('https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@700;800&display=swap');

:root {
  --C: 10mm;
  --accent: #3a7bd5;
  --border: #bbb;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
  font-family: 'Hiragino Kaku Gothic Pro', 'Meiryo', sans-serif;
  background: #FBF8F1; color: #222; /* つくしひろばのクリーム */
}

/* ===== アプリレイアウト ===== */
.app { display: flex; height: 100vh; overflow: hidden; }

.panel {
  width: 270px; min-width: 230px;
  background: #fff; border-right: 1px solid #ddd;
  padding: 16px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 12px;
}
.panel h2 { font-size: 14px; font-weight: 700; color: #555; letter-spacing: .05em; }
.panel-section { display: flex; flex-direction: column; gap: 6px; }
/* **[hidden] は display:flex に負ける。** 明示的に消さないと、
   使わない設定欄（モードごとに出し分ける欄）が出たままになる */
.panel-section[hidden] { display: none !important; }
.panel-section label { font-size: 13px; font-weight: 600; color: #333; }
.panel-section input[type=number] {
  width: 100%; padding: 6px 8px;
  border: 1px solid #ccc; border-radius: 6px;
  font-size: 13px; background: #fafafa;
}
.panel-section input:focus { outline: none; border-color: var(--accent); }
.hint-note { font-size: 11px; color: #999; font-weight: 400; white-space: pre-line; }

/* 複数えらべる欄はチェックにする（札だと1つだけ選ぶように見える）。
   作りは既存単元（kaku/style.css）と同じにそろえてある */
.check-group { display: flex; flex-direction: column; gap: 5px; }
.check-row {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; cursor: pointer; user-select: none;
}
/* その単位を習う学年。**設定の画面にだけ出す**（紙には出さない）。
   どれが2年でどれが3年かが分かると、先生が選びまちがえない */
.check-grade { color: #999; font-size: 11px; margin-left: 2px; }
.check-row input[type=checkbox] {
  width: 15px; height: 15px; cursor: pointer;
  accent-color: var(--accent); flex-shrink: 0;
}
/* 作れない組み合わせ。押せないことを見せる */
.check-row.disabled { opacity: .35; cursor: not-allowed; }
.check-row.disabled input { cursor: not-allowed; }

.toggle-row { display: flex; align-items: center; justify-content: space-between; }
.toggle-row span { font-size: 13px; }
.toggle-row.locked { opacity: .4; }
.toggle-row.locked .slider { cursor: not-allowed; }
/* **flex-shrink: 0 を必ず付ける。** ラベルが長いとスイッチが押し潰され、
   他のトグルと大きさがそろわなくなる（BACKLOG・全単元に横展開ずみ） */
.toggle { position: relative; width: 40px; height: 22px; flex-shrink: 0; }
.toggle input { opacity: 0; width: 0; height: 0; }
.slider { position: absolute; inset: 0; background: #ccc; border-radius: 22px; cursor: pointer; transition: background .2s; }
.slider::before { content: ''; position: absolute; left: 3px; top: 3px; width: 16px; height: 16px; background: #fff; border-radius: 50%; transition: transform .2s; }
.toggle input:checked + .slider { background: var(--accent); }
.toggle input:checked + .slider::before { transform: translateX(18px); }

.btn { width: 100%; padding: 9px; border: none; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer; transition: opacity .15s; }
.btn:hover { opacity: .85; }
.btn-primary { background: var(--accent); color: #fff; }

.divider { border: none; border-top: 1px solid #eee; }

/* ── 選択ピル ── */
.group-pills { display: flex; flex-wrap: wrap; gap: 5px; }
.group-pill {
  padding: 6px 12px; border: 1.5px solid #ddd; border-radius: 20px;
  background: #fff; color: #555; font-size: 13px; font-weight: 600;
  cursor: pointer; transition: all .15s;
}
.group-pill:hover { border-color: var(--accent); color: var(--accent); }
/* 札の中身を、たて・よことも中央にそろえる */
.group-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.group-pill.active {
  background: var(--accent); border-color: var(--accent);
  color: #fff; box-shadow: 0 1px 4px rgba(58,123,213,.3);
}
/* 作れない倍率（patternsFor が返さなかったもの）。押せないことを見せる */
.group-pill:disabled { opacity: .35; cursor: not-allowed; }
.group-pill:disabled:hover { border-color: #ddd; color: #555; }

/* 検査（check:layout）から問い方を切り替えるための、見えない札。
   **この指定は `.group-pill` の指定より後に置く。** 前に置いたら、
   あとから来る `.group-pill { display: inline-flex }` に上書きされて、
   空の札が画面に並んだ（重なり合う指定は後ろが勝つ）。
   画面から消えていても JS の click() は届く（tanni.html の check-probe） */
.group-pill.check-probe { display: none; }

/* ── 右上ナビ ── */
.top-btns { position: fixed; top: 16px; right: 20px; z-index: 200; display: flex; gap: 8px; }
.top-btn { padding: 8px 18px; border: none; border-radius: 8px; font-size: 13px; font-weight: 600; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,.18); transition: opacity .15s, transform .1s; }
.top-btn:hover   { opacity: .88; }
.top-btn:active  { transform: translateY(1px); }
.top-btn:disabled { opacity: .4; cursor: default; transform: none; }
.top-btn-settings { background: #fff; color: #333; }
/* 目次へ戻る。単元に入ったあと帰り道がブラウザの戻るしか無かったので足した
   （つくしひろばに同梱するにあたっての追加。UI_RULES.md にも入れてある） */
.top-btn-back { background: #fff; color: #333; text-decoration: none; display: inline-flex; align-items: center; }
.top-btn-preview  { background: #e67e22; color: #fff; }
.top-btn-print    { background: #27ae60; color: #fff; }
.top-btn-answer   { background: #f0f2f5; color: #333; }
.top-btn-answer.active { background: #2ecc71; color: #fff; }
@media print { .top-btns { display: none; } }

/* ── プレビューエリア ── */
.preview-area { flex: 1; overflow: auto; padding: 24px; display: flex; flex-direction: column; align-items: center; }
.sheet-wrapper { flex-shrink: 0; }
#sheetsContainer { display: flex; flex-direction: column; align-items: center; gap: 20px; }

.print-sheet {
  background: #fff; width: 210mm; height: 297mm; overflow: hidden;
  padding: 12mm 16mm;
  box-shadow: 0 8px 24px -8px rgba(92,68,51,.35); /* クリーム地で紙の縁が出る濃さ */
  transform-origin: top left;
  position: relative; /* 出どころ表示を紙の左下に置くため */
}

.sheet-header { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 5mm; }
.sheet-title {
  flex: 1; min-width: 40mm; outline: none;
  font-family: 'M PLUS Rounded 1c', 'Hiragino Maru Gothic Pro', sans-serif;
  font-size: 32px; font-weight: 800;
  /* **題は1行に収める。** 折り返すと名前欄が押し下がり、問題を並べる高さも減る。
     入りきらないときは JS（fitTitle）が字を小さくする */
  white-space: nowrap;
  overflow: hidden;
}
.sheet-title[contenteditable="true"]:empty::before { content: attr(data-placeholder); color: #ccc; }
.header-field { display: flex; align-items: flex-end; gap: 4px; font-size: 18px; white-space: nowrap; }
.header-field .line { display: inline-block; width: 60px; border-bottom: 1px solid #333; }
.header-field .name-line { width: 70mm; }

.sheet-instruction {
  min-height: 6mm; margin-bottom: 5mm;
  /* JS の _instructionSize と必ずそろえること */
  font-size: 15px; line-height: 1.7; color: #222;
  outline: none; white-space: pre-wrap;
}
.sheet-instruction:empty::before { content: attr(data-placeholder); color: #bbb; }
.sheet-instruction[contenteditable="true"] { border-bottom: 1px dashed #ccc; padding-bottom: 2px; cursor: text; }
.instruction-toolbar { display: flex; align-items: center; gap: 6px; margin-bottom: 3px; font-size: 11px; color: #999; }
.inst-size-btn { width: 20px; height: 20px; padding: 0; border: 1px solid #ddd; border-radius: 4px; background: #f5f5f5; color: #555; font-size: 13px; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.inst-size-btn:hover { background: #e8e8e8; }
#instSizeDisplay { font-size: 12px; color: #555; min-width: 18px; text-align: center; }
@media print { .no-print { display: none !important; } }

/* ── 問題グリッド ── */
.problems-grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols, 1), 1fr);
  column-gap: var(--col-gap, 6mm);
  row-gap: var(--row-gap, 8mm);
  justify-items: start;
  align-items: start;
}
/* ヒントを右上に置くための基準。中身は絶対配置なので高さに効かない */
#problemsOutput { position: relative; }

.print-sheet .problems-grid {
  min-height: var(--grid-min-h, 240mm);
  align-content: space-evenly;
  /* **問題だけ、左の余白を詰める。** 紙の余白は 16mm（題名と指示文はそのまま）。
     問題は番号から始まるので、そこからさらに右に寄って見えていた */
  margin-left: -8mm;
  /* **右端には余裕を残す。** 答えを書く線は列の余りをすべて吸って伸びるので、
     放っておくと紙の内側ぴったりで終わる。0mm の紙は、字の出方が少し違う
     環境（フォント・OS・拡大率）でそのまま外に出る（check:layout が知らせる）。
     使わない余白を先に取っておく */
  padding-right: 4mm;
}

/* 列の幅いっぱいに広げ、余った横幅は答えの線に吸わせる */
.prob-wrap {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: calc(var(--C) * 0.2);
  width: 100%;
  position: relative;   /* ヒントを下にぶら下げるため */
}

.prob-label {
  /* **番号の幅もそろえる。**（1）と（10）で幅が違うと、そのぶん式全体が右へずれ、
     数の幅をそろえても答えの線がそろわない。幅は描いたあとに実測して入れる */
  width: var(--label-w, auto);
  flex: 0 0 auto;
  font-size: min(calc(var(--C) * 0.6), 6mm);
  font-weight: 600;
  color: #555;
  white-space: nowrap;
  min-width: calc(var(--C) * 1.5);
  text-align: right;
}

/* ── 式：「3 km ＝ ＿＿ m」 ── */
.tn-formula {
  display: flex;
  /* **書き込む線は数字の足もと（ベースライン）にそろえる。**
     center だと線が数字の下へ下がって見える（がい数・小数の10倍で確かめた） */
  align-items: baseline;
  gap: calc(var(--C) * 0.25);
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
/* 問題の側。**幅をそろえる**（そろえないと「＝」から先がぎざぎざになる）。
   幅は描いたあとに実測して --ask-w に入れる（書体で字の幅が違うので、
   字数×係数で見積もるとずれる） */
.tn-ask {
  flex: 0 0 auto;
  width: var(--ask-w, auto);
  text-align: right;
}
/* 答えの側。**幅をそろえる**（BACKLOG「異なる出題パターンを同じシートに混在
   させると、flex:1 で伸びる答え欄の幅がパターンごとに不揃いになる」）。
   問い方を混ぜると「＿＿ m」と「＿＿ km ＿＿ m」が同じ紙に並ぶので、
   いちばん広いものに合わせて箱の幅を決め、線はその中で伸びる。
   幅は描いたあとに実測して --out-w に入れる */
.tn-out {
  display: inline-flex;
  align-items: baseline;
  flex: 0 0 auto;
  width: var(--out-w, auto);
  min-width: 0;
}

.tn-num {
  font-size: calc(var(--C) * 1.05);
  font-weight: 700;
  color: #222;
  line-height: 1.15;
}
/* 単位は数より小さく、少しだけ離す（「3km」とくっつけない） */
.tn-unit {
  font-size: calc(var(--C) * 0.62);
  font-weight: 700;
  color: #222;
  line-height: 1.15;
  margin-left: calc(var(--C) * 0.12);
  margin-right: calc(var(--C) * 0.3);
}
.tn-eq {
  font-size: calc(var(--C) * 0.8);
  font-weight: 700;
  color: #444;
  line-height: 1.15;
  flex: 0 0 auto;
}

/* **書き込む場所は1本の線として最後まで引く**（BACKLOG の決まり）。
   **幅は固定にする。** ふだんは `flex: 1` で列の余りを吸わせる作りだが、
   この単元は問い方を1枚に混ぜられるので、伸びる作りだと
   「＿＿ m」と「＿＿ km ＿＿ m」で行ごとに右端がばらつく
   （BACKLOG「異なる出題パターンを混在させるなら、答え欄を固定幅にする」）。

   マスの大きさに比例させつつ、小さい紙でも書けるよう mm の下限を持たせる */
.tn-ans {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  /* 「複名数にする」の線。書くのは 1けた と 3けた までなので、これで足りる。
     26mm にしていたときは、行が長くなって右上のヒントに食い込んだ（実測） */
  width: max(calc(var(--C) * 2.2), 20mm);
  height: calc(var(--C) * 1.15);
  border-bottom: 1.5px solid #666;
}
/* 書き込む線が1本だけの問い方（大きい→小さい／単名数にする）は長めに取る。
   「複名数にする」だけは線が2本あるので、上の狭いほうを使う */
.tn-ans-wide { width: max(calc(var(--C) * 4.6), 44mm); }
.tn-ans-val {
  font-size: calc(var(--C) * 1.05);
  font-weight: 700;
  color: #c0392b;
  line-height: 1.15;
}

/* ── ヒント：単位の関係を紙の上に並べる（利用者の指定・2026-09-26）──
   「1 cm ＝ 10 mm」のように、その紙に要る関係だけを出す。
   **枠線と文字だけで描く**（背景で塗ると、背景を刷らない設定で紙から消える。
   BACKLOG「塗りつぶしは background で描かない」）。

   **問題を並べる箱の外に置く**（tanni.html の #hintBar）。
   中に入れると、帯のぶんの高さが「問題を並べられる高さ」から引かれず、
   紙の下がはみ出す */
.tn-hintbar {
  /* **1問目と同じ行の右上に置く**（利用者の指定・2026-09-26）。
     問題は紙の左 2/3 ほどで終わるので、右の空きに収まる。
     絶対配置なので、問題を並べられる高さを減らさない */
  position: absolute;
  top: 0;
  /* **右端は名前欄の線と同じところまで使う**（利用者の指定・2026-09-26）。
     名前欄の線は紙の中身の右はしで終わっているので、ここも 0 に近づける */
  right: 0.5mm;
  display: flex;
  flex-direction: column;
  gap: 1.6mm;
  padding: 2.2mm 3mm;
  border: 0.3mm solid #999;
  border-radius: 1.5mm;
  background: #fff;
  /* **問題の行に重ならない幅に収める。** 行がいちばん長くなるのは
     「複名数にする」（線が2本＋単位が2つ）で、そのとき右に空くのは 45mm ほど。
     **行を詰めても解決しない。** 1マスの大きさは高さで決まっているので、
     幅を空けたぶんだけ組み直しでマスが大きくなり、行の長さが戻る（実測）。
     そこで**大きめを上限にしておき、入らない紙だけ JS（fitHint）が詰める**。
     余裕のある紙では大きいまま出る */
  max-width: 70mm;
}
.tn-rel {
  /* 上限は JS（fitHint）が詰める。組む前の見積もりでは当たらないため */
  font-size: min(calc(var(--C) * 0.62), var(--rel-size, 5.6mm));
  font-weight: 700;
  color: #222;
  white-space: nowrap;
}

/* 設定画面で押して直せる場所。印刷には出ない見た目 */
.tn-editable { cursor: pointer; border-radius: 2px; }
.tn-editable:hover { background: #eef4fd; }
@media print { .tn-editable:hover { background: none; } }

/* ── 印刷 ── */
@page { size: A4 portrait; margin: 0; }
@media print {
  body { background: #fff; }
  .app { display: block; height: auto; }
  .panel { display: none; }
  .preview-area { padding: 0; overflow: visible; }
  .sheet-wrapper { width: auto !important; height: auto !important; }
  .print-sheet {
    box-shadow: none; transform: none !important; margin: 0;
    width: 210mm; height: 297mm; overflow: visible;
    page-break-after: always;
  }
  #sheetsContainer { gap: 0; }
  .print-sheet:last-child { page-break-after: avoid; }
  .sheet-instruction { border: none; padding: 0; }
}

/* ── ズームバー ── */
.zoom-bar {
  position: fixed; bottom: 20px; right: 24px; z-index: 150;
  display: flex; align-items: center; gap: 1px;
  background: rgba(255,255,255,.88);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(0,0,0,.10);
  border-radius: 20px; padding: 3px 5px;
  box-shadow: 0 2px 10px rgba(0,0,0,.10);
  opacity: .55; transition: opacity .2s; user-select: none;
}
.zoom-bar:hover { opacity: 1; }
.zoom-btn {
  width: 26px; height: 26px; border: none; border-radius: 13px;
  background: transparent; font-size: 15px; font-weight: 700;
  color: #444; cursor: pointer; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: background .12s;
}
.zoom-btn:hover { background: rgba(0,0,0,.07); }
.zoom-reset {
  min-width: 42px; border: none; border-radius: 4px;
  background: transparent; font-size: 12px; font-weight: 600;
  color: #555; cursor: pointer; padding: 2px 4px;
  transition: background .12s; border-left: 1px solid rgba(0,0,0,.09);
  margin-left: 2px; padding-left: 7px;
}
.zoom-reset:hover { background: rgba(0,0,0,.07); }
.zoom-slider {
  -webkit-appearance: none; appearance: none;
  width: 90px; height: 3px;
  background: rgba(0,0,0,.18); border-radius: 2px;
  outline: none; cursor: pointer; margin: 0 2px;
}
.zoom-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 13px; height: 13px; border-radius: 50%;
  background: #3a7bd5; box-shadow: 0 1px 3px rgba(58,123,213,.4);
  transition: transform .1s;
}
.zoom-slider::-webkit-slider-thumb:hover { transform: scale(1.2); }
.zoom-slider::-moz-range-thumb {
  width: 13px; height: 13px; border-radius: 50%; border: none;
  background: #3a7bd5; box-shadow: 0 1px 3px rgba(58,123,213,.4);
}
@media print { .zoom-bar { display: none; } }

/* 印刷では拡大縮小を戻す。画面の zoom をそのまま持ち込むと紙の寸法が狂う */
@media print {
  .print-sheet { zoom: 1 !important; transform: none !important; }
}

/* ── 印刷で白紙のページが出るのを直す（2026-08-31・全単元） ──────────
   **この節は必ずスタイルシートの末尾に置く。** 途中に置くと、後ろにある
   `.print-sheet` の指定（overflow: visible など）に上書きされて効かなくなる。

   1. **改ページは包む箱（.sheet-wrapper）に付ける。**
      `.print-sheet:last-child` は「箱の中のただ一つの子」なのですべての紙に当たり、
      page-break-after を avoid に上書きしてしまう（＝2枚目以降が白紙）
   2. **印刷は block で流す。** flex のままだと紙まるごと次のページへ送られる
   3. **紙面ちょうど（297mm）だと高さが整数pxへ切り上がり**、
      わずかにはみ出して中身の無いページが挟まる。少しだけ低くする */
@media print {
  .print-sheet {
    height: 296.8mm !important;
    overflow: hidden !important;
    page-break-after: auto !important;
    break-after: auto !important;
  }
  /* **画面の部品は必ず消す。** block で流すと、消し忘れた部品が紙の「上」に
     積まれて紙を押し下げ、下がはみ出して2ページ目ができる */
  .panel, .top-btns, .zoom-bar, .instruction-toolbar, .no-print { display: none !important; }
  html, body, .app, .preview-area, #sheetsContainer {
    display: block !important;
    height: auto !important;
    overflow: visible !important;
    padding: 0 !important;
    margin: 0 !important;
    gap: 0 !important;
  }
  .sheet-wrapper { break-after: page; page-break-after: always; }
  .sheet-wrapper:last-child { break-after: auto; page-break-after: auto; }
}

/* ── 出どころ表示（刷った紙だけを見ても、どこの教材か分かるように）──
   **no-print を付けない。** 画面の飾りではなく、紙に残すためのもの。
   位置と大きさはドリルのPDFと同じ（高さ3.5mm・左8mm・下5mm）。
   決めごとは docs/backlog.md「5.（実装ずみ）」 */
.sheet-credit {
  position: absolute; left: 8mm; bottom: 5mm; height: 3.5mm;
  pointer-events: none; user-select: none;
}
.sheet-credit img { height: 100%; width: auto; display: block; }
