/* 見た目(issue #769 の骨組み + #770 の作り込み)。**森の工房**。
   色・線・影・丸みの正は `.claude/rules/orugoru-koubou/design/mitame.md`
   (配置と寸法は heya.md と `.claude/rules/orugoru-koubou/design/` の要素別設計書が持つ)。

   掟(要素別設計 pads.md / menu.md / score.md の帰結。崩すときは設計書の側を直す):

   - **寸法の持ち主は `js/layout.js` 1か所。** ここは `--pad` `--gap` `--side` `--grid` …
     を読むだけで、px を焼き込まない(焼き込むと2か所が食い違う ← coding/layout.md)
   - **箱(`.pad` / `.tile` / `.cell` …)の大きさを状態で変えない。**
     状態の大きさは `.face`、押下の縮みは `.pict` ——
     **1要素に2つの `transform` は乗らない**(後に書いたほうしか効かない ← coding/input.md)。
     `:active` で箱を縮めると当たり判定まで縮む(マウスだけが落ちる)
   - **明るさ・不透明度を「振る」演出を作らない**(1秒3回。UX原則3)。
     発音の応え・運びの動きは **`transform` だけ**
   - **文字は絵の下に小さく添えるだけ**(絵が主 ← heya.md 6.2)。文は「ひとこと帯」だけ
   - **見えない要素は指に透明にする**(`pointer-events: none`)← coding/layout.md
   - **光らせない**(mitame.md 9章)。外側の影は `x = 0 / y > 0 / spread 0 / 色は墨` の1種だけで、
     `0 0` の影・行の色の影・`filter: drop-shadow` の光を作らない。
     **黒(`#000`)を焼き込まない** —— 影も縁も `--deep`(墨)から作る
   - **色リテラルは `:root` の外に書かない**(テーマを増やす日の受け口 ← mitame.md 11章)
   - **`@media (prefers-reduced-motion: reduce)` はこのファイルの最後の塊**
     (同じ特異性なら後勝ちなので、下に規則を足すと止める行が効かなくなる ← coding/testing.md) */

:root {
  /* 地と字 */
  --bg: hsl(44 34% 94%);        /* もり(朝の森)← score.md 3.6 */
  --ink: #3a2f22;               /* 字と、行の色を持たない的の色 */
  /* **`--ink` と同じ墨だが、行の色で上書きしない**(下の `[data-row]` が `--ink` を
     差し替えるため)。くしの歯のオクターブ3段(`pads.js` の `combArt`)が、
     行の色をこの墨へ混ぜて「ひくいほど濃い」を作る ← oto-kaidan.md 3.2 */
  --deep: #3a2f22;

  /* 4つの層の色(**最終。mitame.md 3.1**)。決め方は
     (1) 色相を離したまま彩度を落とす →(2) 明度(L*)を等間隔の階段に並べ直す、の順。
     **隣り合う行の ΔL* ≥ 7**(7.7 / 7.0 / 8.7)—— 色相だけに頼ると、
     赤緑の色覚多様性で 土 と こけ が混同する(仮の配色は ΔL* 0.2 だった)。
     **地に対しては4行とも 3:1 以上**(7.91 / 5.96 / 4.60 / 3.38)。
     **こもれびはこれ以上明るくできない**(3.38 が線のいちばん近く)ので、
     主役であることは色ではなく**大きさ・形**で言う(mitame.md 3.1 の「守った線」1) */
  --row0: hsl(16 22% 30%);      /* 土      くすんだ赤茶・いちばん暗い(L* 31.5) */
  --row1: hsl(156 22% 32%);     /* こけ    深い緑              (L* 39.2) */
  --row2: hsl(94 24% 37%);      /* わかば  明るい黄緑           (L* 46.2) */
  --row3: hsl(46 40% 42%);      /* こもれび やわらかい山吹・いちばん明るい(L* 54.9) */

  /* 旋律の高さの色(ド〜たかい ド。2026-09-22 の作り直し)。**森のトーン・彩度控えめ**で
     色相だけを 8 つに回す(明度は L* 40〜46 にそろえ、どれかが浮かないようにする)。
     **地に対しては 8 つとも 3:1 以上**(5.66 / 5.10 / 4.60 / 4.69 / 5.32 / 5.72 / 4.86 / 5.14)。
     色だけで高さを言わない —— 譜面では**縦の位置**、鍵盤では**左右の位置と板の長さ**が言う */
  --d0: hsl(6 40% 42%);         /* ど      れんが */
  --d1: hsl(26 46% 38%);        /* れ      かきの実 */
  --d2: hsl(44 50% 34%);        /* み      山吹の実 */
  --d3: hsl(78 32% 34%);        /* ふぁ    オリーブ */
  --d4: hsl(140 26% 34%);       /* そ      こけ */
  --d5: hsl(178 30% 31%);       /* ら      みずべ */
  --d6: hsl(208 28% 42%);       /* し      ゆうぐれの空 */
  --d7: hsl(262 20% 46%);       /* たかい ど すみれ */

  /* 線画のインク(mitame.md 3.2)。**絵は面の上に載る**ので、`currentColor` のままだと
     明るい行ほど絵と面の差が縮む(こもれびの絵 対 「ある」の面が 2.46:1 で 3:1 を割る)。
     **行の色に墨を 20% 混ぜる**と 3.10〜5.24 に戻る。色相は動かないので
     「この絵はこの行のもの」は読めたまま。**面・縁・下地は `currentColor` のまま。** */
  --art-ink: color-mix(in srgb, currentColor 80%, var(--deep));

  /* 絵の線の太さ。`vector-effect: non-scaling-stroke` なので**拡縮しても太くならない**。
     **正の持ち主は `layout.js` の `apply()`**(S ≥ 80 で 2.5 / 2 と 3.3 / 2.8)——
     ここに書いてあるのは、印がまだ配られていないときのフォールバックだけ(mitame.md 4.1)。
     `--art-w-lg` は**段1 の候補タイルの絵1か所だけ**に当たる(絵が約 70px と大きいので) */
  --art-w: 2.5;
  --art-w-lg: 3.3;

  /* 影(mitame.md 5.1)。**やわらかい影・下向き1つだけ**。
     x = 0(光源は真上)/ y > 0 / ぼかしは y の3倍 / spread は書かない(正の spread は光彩) /
     **色は `--deep` の 9〜13%**(黒を焼き込まない。テーマを替えても影が付いてくる)。
     **`transition` を掛けない**(押した瞬間の応えが遅れる ← mitame.md 9章) */
  --lift:    0 2px  6px color-mix(in srgb, var(--deep) 10%, transparent);  /* 置いてある面 */
  --lift-on: 0 3px 10px color-mix(in srgb, var(--deep) 13%, transparent);  /* 「ある」の面 */
  --lift-sm: 0 1px  3px color-mix(in srgb, var(--deep)  9%, transparent);  /* 小さい面 */

  /* 角の丸み(mitame.md 6.1)。`--bevel` は**有機の角**(4隅の差は最大 3px)で、
     **全部の面が同じ1つの値を共有する**(要素ごとに違う丸みを配らない = 崩れに見える)。
     **4値のリストなので `calc()` から割れない** —— 割り算が要る所は `--r` を使う */
  --r: 15px;
  --r-sm: 7px;
  --bevel: 15px 13px 16px 14px;

  /* #773(仮)= ゆうやけ。**地を決めたら mitame.md 3.1 の手順で4行の L* を解き直す**
     (色相を回すだけでは 3:1 も ΔL* 7 も静かに割れる。初版は「もり」1つ ← mitame.md 11章) */
  /* :root[data-theme="yuuyake"] { --bg: …; --row0: …; … } */

  /* 古い 端末(color-mix が 無い: Safari 16.1・Chrome 110 まで)の 下書きが 読む 値(#1621)。上の 色と 同じ 3 つ組と、
     color-mix を 手で 解いた 色。下書きは color-mix を 書いた 規則の すぐ 後ろの `@supports not (color: color-mix(…))` に 置く
     (var() を 含む 宣言は 古い 端末で unset に なるので、直前に 並べても 効かない) */
  --bg-rgb: 245, 242, 234; --ink-rgb: 58, 47, 34; --deep-rgb: 58, 47, 34;
  --row0-rgb: 93, 69, 60; --row1-rgb: 64, 100, 85; --row2-rgb: 91, 117, 72; --row3-rgb: 150, 130, 64;
  --d0-rgb: 150, 73, 64; --d1-rgb: 141, 91, 52; --d2-rgb: 130, 107, 43; --d3-rgb: 98, 114, 59; --d4-rgb: 64, 109, 79; --d5-rgb: 55, 103, 101; --d6-rgb: 77, 109, 137; --d7-rgb: 111, 94, 141;
  --deep-12-bg: #dedbd2; --deep-14-bg: #dbd7ce; --deep-18-bg: #d3cfc6; --deep-30-bg: #bdb8ae; --deep-45-bg: #a19a90; --deep-55-bg: #8e877c; --deep-70-bg: #726a5e; --deep-80-bg: #5f564a;   /* = color-mix(--deep N%, --bg) */
  --row0-art: #564037; --row1-art: #3f594b; --row2-art: #556740; --row3-art: #84713a;   /* = --art-ink(行の色 80% + 墨) */
  --comb0: #56482b; --comb1: #635430; --comb2: #716134;   /* = pads.js の くしの歯(行3 の 色 COMB_MIX% + 墨) */
  --cc-rgb: var(--ink-rgb);   /* = color の 3 つ組(currentColor の 代わり)。**color を 書く 規則は 同じ 所で これも 書く** */
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { :root { --art-ink: currentColor; --lift: 0 2px  6px rgba(var(--deep-rgb), .1); --lift-on: 0 3px 10px rgba(var(--deep-rgb), .13); --lift-sm: 0 1px  3px rgba(var(--deep-rgb), .09); } }
@supports not (color: color-mix(in srgb, red 50%, blue)) { [data-row="0"] { --art-ink: var(--row0-art); } [data-row="1"] { --art-ink: var(--row1-art); } [data-row="2"] { --art-ink: var(--row2-art); } [data-row="3"] { --art-ink: var(--row3-art); } }

/* 行の色は `--ink` を差し替えて配る。**`currentColor` が絵の線と下地の素になる** */
[data-row="0"] { --ink: var(--row0); --ink-rgb: var(--row0-rgb); }
[data-row="1"] { --ink: var(--row1); --ink-rgb: var(--row1-rgb); }
[data-row="2"] { --ink: var(--row2); --ink-rgb: var(--row2-rgb); }
[data-row="3"] { --ink: var(--row3); --ink-rgb: var(--row3-rgb); }
/* `color` は計算値を継ぐので、`--ink` を持つ要素は自分で引き直す */
[data-row] { color: var(--ink); --cc-rgb: var(--ink-rgb); }

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  --cc-rgb: var(--ink-rgb);
  font-family: system-ui, sans-serif;
  overscroll-behavior: none;
  touch-action: none;                 /* 送りは自分で読む(端末ごとの慣性を式から消す) */
  -webkit-text-size-adjust: 100%;
}

/* 押せるものの素。**縮みは中の絵だけ**(下の `.pict`) */
button {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
}

:focus { outline: none; }
/* 焦点は「行の意味」ではなく**システムの合図**なので、行の色を着せない(mitame.md 3.5)。
   **`--ink` は `[data-row]` が行の色へ差し替える**ので、そこから作ると
   わかば 2.68 / こもれび 2.23 と 3:1 を割る。**上書きされない `--deep` から作る**と
   4行とも 6.43(「ある」の濃い面の上でも 3.93〜4.68)で消えない */
:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--deep) 80%, var(--bg));
  outline-offset: 2px;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { :focus-visible { outline: 3px solid var(--deep-80-bg); } }

/* 絵は全部**行の色の線画**。塗る部分は art 側が `fill="currentColor"` を持つ。
   **線は `--art-ink`(行の色 + 墨 20%)**で引く ← mitame.md 3.2。
   面・縁・下地は `currentColor` のまま(「行 = 色」の文法を弱らせない) */
svg { display: block; width: 100%; height: 100%; overflow: visible; }
svg * { vector-effect: non-scaling-stroke; }
.pict svg {
  fill: none;
  stroke: var(--art-ink);
  stroke-width: var(--art-w);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* パッドの絵の型(`<symbol>`)。**見せない・測らない・指に当たらない**。
   `display: none` にすると `<use>` の参照が消える実装があるので、幅0で畳む */
#pad-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}

/* 旋律の絵(`melody.js` の `melodyArt`)。**線の太さは絵の単位(viewBox)で決める** ——
   `svg *` の `non-scaling-stroke` を外さないと、絵を縮めたチップでも太さが画面の px のままで
   棒どうしがつぶれる。色は高さの色。`svg .mdot` は `svg *`(0,0,1)より強い */
svg .mdot { vector-effect: none; fill: none; }
.mdot[data-deg="0"], .rpmark[data-deg="0"], .mtooth[data-deg="0"], .rnote[data-deg="0"], .rkey[data-deg="0"], .xkey[data-deg="0"], .mname[data-deg="0"], .rfly[data-deg="0"] { --deg: var(--d0); --deg-rgb: var(--d0-rgb); }
.mdot[data-deg="1"], .rpmark[data-deg="1"], .mtooth[data-deg="1"], .rnote[data-deg="1"], .rkey[data-deg="1"], .xkey[data-deg="1"], .mname[data-deg="1"], .rfly[data-deg="1"] { --deg: var(--d1); --deg-rgb: var(--d1-rgb); }
.mdot[data-deg="2"], .rpmark[data-deg="2"], .mtooth[data-deg="2"], .rnote[data-deg="2"], .rkey[data-deg="2"], .xkey[data-deg="2"], .mname[data-deg="2"], .rfly[data-deg="2"] { --deg: var(--d2); --deg-rgb: var(--d2-rgb); }
.mdot[data-deg="3"], .rpmark[data-deg="3"], .mtooth[data-deg="3"], .rnote[data-deg="3"], .rkey[data-deg="3"], .xkey[data-deg="3"], .mname[data-deg="3"], .rfly[data-deg="3"] { --deg: var(--d3); --deg-rgb: var(--d3-rgb); }
.mdot[data-deg="4"], .rpmark[data-deg="4"], .mtooth[data-deg="4"], .rnote[data-deg="4"], .rkey[data-deg="4"], .xkey[data-deg="4"], .mname[data-deg="4"], .rfly[data-deg="4"] { --deg: var(--d4); --deg-rgb: var(--d4-rgb); }
.mdot[data-deg="5"], .rpmark[data-deg="5"], .mtooth[data-deg="5"], .rnote[data-deg="5"], .rkey[data-deg="5"], .xkey[data-deg="5"], .mname[data-deg="5"], .rfly[data-deg="5"] { --deg: var(--d5); --deg-rgb: var(--d5-rgb); }
.mdot[data-deg="6"], .rpmark[data-deg="6"], .mtooth[data-deg="6"], .rnote[data-deg="6"], .rkey[data-deg="6"], .xkey[data-deg="6"], .mname[data-deg="6"], .rfly[data-deg="6"] { --deg: var(--d6); --deg-rgb: var(--d6-rgb); }
.mdot[data-deg="7"], .rpmark[data-deg="7"], .mtooth[data-deg="7"], .rnote[data-deg="7"], .rkey[data-deg="7"], .xkey[data-deg="7"], .mname[data-deg="7"], .rfly[data-deg="7"] { --deg: var(--d7); --deg-rgb: var(--d7-rgb); }
.rlane[data-deg="0"] { --deg: var(--d0); --deg-rgb: var(--d0-rgb); }
.rlane[data-deg="1"] { --deg: var(--d1); --deg-rgb: var(--d1-rgb); }
.rlane[data-deg="2"] { --deg: var(--d2); --deg-rgb: var(--d2-rgb); }
.rlane[data-deg="3"] { --deg: var(--d3); --deg-rgb: var(--d3-rgb); }
.rlane[data-deg="4"] { --deg: var(--d4); --deg-rgb: var(--d4-rgb); }
.rlane[data-deg="5"] { --deg: var(--d5); --deg-rgb: var(--d5-rgb); }
.rlane[data-deg="6"] { --deg: var(--d6); --deg-rgb: var(--d6-rgb); }
.rlane[data-deg="7"] { --deg: var(--d7); --deg-rgb: var(--d7-rgb); }
svg .mdot { stroke: var(--deg); }
/* 根の板(bansou.md 3.3 / 3.4 / 3.5)。**鍵盤の板と同じ色**(`--d0/d3/d4/d5`)。ばんそう ボタン・根のタイル・チップの足 */
.aplate[data-deg="0"], .rroot[data-deg="0"] { --deg: var(--d0); --deg-rgb: var(--d0-rgb); }
.aplate[data-deg="3"], .rroot[data-deg="3"] { --deg: var(--d3); --deg-rgb: var(--d3-rgb); }
.aplate[data-deg="4"], .rroot[data-deg="4"] { --deg: var(--d4); --deg-rgb: var(--d4-rgb); }
.aplate[data-deg="5"], .rroot[data-deg="5"] { --deg: var(--d5); --deg-rgb: var(--d5-rgb); }
svg .aplate { fill: var(--deg); stroke: none; }
/* しおり(先が V に切れた細い帯)。**墨**(色の意味を足さない) */
svg .aribbon { fill: var(--art-ink); stroke: none; }
/* くしの歯(横長のボタンの絵)。**機構の絵**なので傾けない。レールは墨、歯は高さの色 */
.mtooth { fill: var(--deg); stroke: none; }
.mrail { fill: color-mix(in srgb, var(--deep) 70%, var(--bg)); stroke: none; }
@supports not (color: color-mix(in srgb, red 50%, blue)) { .mrail { fill: var(--deep-70-bg); } }
/* 音色の絵(`timbreArt`。neiro.md 3.3)。**どこに置いても同じ線**になるよう自分で持つ
   (横長のボタンの中は `.pict` の規則が当たらない)。塗らない・光らせない */
svg .tart { fill: none; stroke: var(--art-ink); stroke-width: var(--art-w); stroke-linecap: round; stroke-linejoin: round; }
svg .tart.thin { stroke-width: calc(var(--art-w) * 0.7); }

/* ---------------------------------------------------------------- 画面 */

.screen {
  position: fixed;
  inset: 0;
}

.screen:not(.show) { display: none; }

/* はじまりの画面(字は `paintBoot()` が `t()` を通して入れる)。
   `.screen:not(.show)` は2クラスぶんの詳細度(0,2,0)しか無く、id セレクタ(1,0,0)の
   `#boot { display: flex }` に必ず負ける ── `.show` を対で持たせないと、スタジオへ入った
   あとも #boot が `display: flex` のまま残り、デッキの隙間から字が透けて見える
   (対象者視点レビュー #769 重大1) */
#boot.show {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 16px;
  text-align: center;
}

.boot-title { font-size: clamp(20px, 6vw, 28px); }
.boot-text { font-size: 14px; opacity: 0.7; }
/* はじめる(2026-10-02)。**画面でいちばん大きく、いちばん濃い的**(字が読めなくても ▶ の形で「ここ」と分かる)。
   押せるのは `#boot` 全体のまま(ボタンは押す場所を見せるだけ)。**押下で縮めない**(押した瞬間にスタジオへ入る) */
.boot-go {
  margin: 18px 0 6px;
  min-width: 200px;
  min-height: 76px;
  padding: 0 32px 0 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  border: 0;
  border-radius: 38px;
  background: var(--deep);
  color: var(--bg);
  --cc-rgb: var(--bg-rgb);
  font: inherit;
  font-size: 22px;
  font-weight: 700;
  box-shadow: var(--lift-on);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.boot-go .lbl { color: inherit; font-size: inherit; font-weight: inherit; }
/* 「さわると はじまります」を絵で言う指さしの手(#1812 ← otehon-kyoku.md 3章)。はじめる の右上の縁に指先が触れる。
   **押せない**(下の はじめる が受ける ← #787)。動きは `transform` だけ(はじめの ゆび と同じ `hint-press` を 4 回 → 止まって残る) */
.boot-go { position: relative; }
.boot-hint {
  position: absolute;
  right: 4px;
  top: -22px;
  width: 40px;
  height: 48px;
  pointer-events: none;
  animation: hint-press 1400ms ease-in-out 600ms 4 both;
}
.boot-hint svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: var(--deep);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.boot-hint svg .hhand { fill: var(--bg); }
.boot-go .art { width: 34px; height: 34px; display: block; }
.boot-go .art svg { width: 100%; height: 100%; fill: currentColor; stroke: currentColor; stroke-width: 3; stroke-linejoin: round; }
/* おてほん の きく / おてほんで つくる(#1395 ← otehon-kyoku.md 3章)。**はじめる の脇役**(#1798): **絵が上・字が下の小さな升**、
   面は地と同じ(塗らない)・縁 2px 墨 30%・影 `--lift-sm`。2つは**いつも横に並ぶ**(折らない。字は升の中で折る)。
   面は棚の `.sbtn` と同じ語彙(`box-shadow` は1か所)。押した手ごたえは中身だけ(箱 = 当たり判定は縮めない)。
   きく ⇄ とめる で**色も明るさも替えない**(絵とことばだけ) */
.boot-more {
  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: stretch;
  gap: 12px;
  margin-top: 10px;
  max-width: 100%;
}
.boot-ote {
  min-height: 64px;
  min-width: 64px;
  width: 128px;
  max-width: min(168px, calc(50vw - 22px));
  padding: 6px 8px;
  border: 0;
  font: inherit;
  color: var(--ink);
  --cc-rgb: var(--ink-rgb);
  --edge-w: 2px;
  --edge-c: color-mix(in srgb, currentColor 30%, var(--bg));
  --lift-cur: var(--lift-sm);
  border-radius: var(--bevel);
  background-color: var(--bg);
  box-shadow: var(--lift-cur), inset 0 0 0 var(--edge-w) var(--edge-c);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .boot-ote { --edge-c: rgba(var(--cc-rgb), .3); } }
.boot-ote .ink { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.boot-ote[data-press] .ink { transform: scale(0.94); }
.boot-ote .art { width: 40px; height: 40px; }
.boot-ote .art svg { width: 100%; height: 100%; }
.boot-ote .lbl { display: grid; justify-items: center; text-align: center; font-size: 13px; font-weight: 700; line-height: 1.2; color: var(--deep); --cc-rgb: var(--deep-rgb); overflow-wrap: anywhere; }
/* きく と とめる / つくる と あそぶ を同じ升に重ねる(幅は長いほうで決まる = 押している間に箱が縮まない) */
.boot-ote .lbl > span { grid-area: 1 / 1; }
.boot-ote[data-playing="1"] [data-l="listen"],
.boot-ote:not([data-playing="1"]) [data-l="stop"] { visibility: hidden; }
.boot-ote[data-next="1"] [data-l="make"],
.boot-ote:not([data-next="1"]) [data-l="next"] { visibility: hidden; }
/* きく のあとの つくる =「この きょくで あそぶ」(#1798)。**縁 3px 墨**(「えらんでいる」の語彙)・初めの1回だけ絵が弾む。面・明るさは替えない */
.boot-ote[data-next="1"] { --edge-w: 3px; --edge-c: var(--deep); }
.boot-ote[data-bump] .art { animation: play-nudge 420ms ease-out; }

/* 入口ページへ戻る口(site-home.md)。はじまりの画面の右上だけ。面は棚の `.sbtn` と同じ文法・押下は中の絵だけを縮める */
#site-home {
  position: absolute;
  top: max(8px, env(safe-area-inset-top));
  right: max(8px, env(safe-area-inset-right));
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  --cc-rgb: var(--ink-rgb);
  --edge-w: 2px;
  --edge-c: color-mix(in srgb, currentColor 40%, var(--bg));
  --lift-cur: var(--lift);
  border-radius: var(--bevel);
  background-color: color-mix(in srgb, currentColor 10%, var(--bg));
  box-shadow: var(--lift-cur), inset 0 0 0 var(--edge-w) var(--edge-c);
  -webkit-tap-highlight-color: transparent;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { #site-home { --edge-c: rgba(var(--cc-rgb), .4); background-color: rgba(var(--cc-rgb), .1); } }
#site-home > svg { width: 30px; height: 30px; display: block; fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linejoin: round; }
#site-home:active > svg { transform: scale(0.94); }
/* ことば(#1838 ← heya.md「わかる 6」)= はじまりの画面の左上(`#site-home` の鏡)。面は棚の `.sbtn` のまま・56 x 56。
   押下は中の絵だけを縮める(箱 = 当たり判定は動かさない)。一覧(`.lang-menu`)は `#boot` の中に出る */
#boot-lang {
  position: absolute;
  top: max(8px, env(safe-area-inset-top));
  left: max(8px, env(safe-area-inset-left));
  width: 56px;
  height: 56px;
  padding: 0;
  border: 0;
  font: inherit;
  color: var(--ink);
  --cc-rgb: var(--ink-rgb);
  --gap: 0px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#boot-lang:active > svg { transform: scale(0.94); }

/* ---------------------------------------------------- スタジオ(3 つの部屋。heya.md)

   **寸法の持ち主は `js/heya-layout.js` 1 か所**(`applyHeya()` が `--top-x/y/w/h` …を流す)。
   ここは読むだけで px を焼き込まない。塊(上の帯・ひとこと帯・曲の帯・タブ・部屋)は
   **`#main` の中に絶対配置**で置く —— 縦も横も同じ規則で、横(`:root[data-hl="1"]`)だけ
   部屋を左右の列(`.pl` / `.pr`)に割る。

   **`#app` も `#boot` と同じ罠を踏んでいた**(id セレクタ `#app`(1,0,0)が
   `.screen:not(.show)`(0,2,0)に勝ち、`.show` が無くても常に表示のままだった ← lessons.md 12)。
   **`.show` を対で持たせる。** `position` は `.screen` の `fixed; inset: 0` のまま触らない
   (← lessons.md 2)。

   掟(heya.md 6 章・8 章):
   - **的の箱は隙間なく並べ、見た目の隙間は中の面(`.ink`)の内側で作る**(死んだ帯を作らない)
   - **押した手ごたえは `.ink` の縮みだけ**(箱は 1px も動かない ← coding/input.md)
   - **状態は縁の太さ(`--edge-w`)で言う**。明るさ・不透明度を振らない。**押せない見た目を半透明で作らない**
   - **`box-shadow` は要素につき 1 か所**(`--lift-cur` / `--edge-w` / `--edge-c` だけを書き換える ← mitame.md 5.3) */

#app.show { display: block; }

/* 隠す属性はどの規則より強く(部屋・一覧・一覧の添え書き) */
[hidden] { display: none !important; }

.main {
  position: absolute;
  inset: 0;
}

.top, .song, .tabs, .room, .say {
  position: absolute;
}
.top  { left: var(--top-x);  top: var(--top-y);  width: var(--top-w);  height: var(--top-h); }
.song { left: var(--song-x); top: var(--song-y); width: var(--song-w); height: var(--song-h-all, auto); }
.tabs { left: var(--tabs-x); top: var(--tabs-y); width: var(--tabs-w); height: var(--tabs-h); }
.room { left: var(--room-x); top: var(--room-y); width: var(--room-w); height: var(--room-h); }

/* ---- 押せる物の素(上の帯・曲の帯・タブ・部屋・一覧。`ui.js` の `makeButton`)
   箱 = 的・`.ink` = 見える面(縮む)・`.art` = 絵・`.lbl` = ことば */
.tbtn, .tab, .sbar, .hbtn, .rlen, .lart, .ditem, .rplate, .aribbonb, .ftimbre, .sh-item {
  position: relative;
  min-width: 0;
  min-height: 0;
  --s-press: 1;
}
.tbtn .ink, .tab .ink, .sbar .ink, .hbtn .ink, .rlen .ink, .lart .ink, .ditem .ink,
.rplate .ink, .aribbonb .ink, .ftimbre .ink, .sh-item .ink {
  position: absolute;
  inset: 3px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  --edge-w: 2px;
  --edge-c: color-mix(in srgb, currentColor 40%, var(--bg));
  --lift-cur: var(--lift-sm);
  border-radius: var(--r-sm);
  background-color: color-mix(in srgb, currentColor 8%, var(--bg));
  box-shadow: var(--lift-cur), inset 0 0 0 var(--edge-w) var(--edge-c);
  transform: scale(var(--s-press));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .tbtn .ink, .tab .ink, .sbar .ink, .hbtn .ink, .rlen .ink, .lart .ink, .ditem .ink, .rplate .ink, .aribbonb .ink, .ftimbre .ink, .sh-item .ink { --edge-c: rgba(var(--cc-rgb), .4); background-color: rgba(var(--cc-rgb), .08); } }
[data-press] { --s-press: 0.94; }

.art { display: block; flex: 0 0 auto; }
.art svg {
  fill: none;
  stroke: var(--art-ink);
  stroke-width: var(--art-w);
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* ことばは**絵の下に小さく**(絵が主 ← heya.md 6.2)。**墨**(行の色で書かない = 4.5:1 を割らない) */
.lbl {
  display: block;
  max-width: 100%;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
  color: var(--deep);
  --cc-rgb: var(--deep-rgb);
  overflow-wrap: anywhere;
}
.lbl small { display: block; font-size: 0.75em; }

/* 選んでいる = 縁 3px(長さ・ひびきの板・音色・一覧の中) */
[data-sel="1"] > .ink { --edge-w: 3px; --edge-c: currentColor; --lift-cur: var(--lift); }

/* 箱の外周がぴったり隣と接する的は、焦点の輪を内向きに描く(外へ出す輪は隣の面に隠れる) */
.sbar:focus-visible, .tab:focus-visible, .xkey:focus-visible, .rlen:focus-visible,
.rplate:focus-visible, .ftimbre:focus-visible, .sh-item:focus-visible { outline-offset: -3px; }

/* ---- ひとこと帯(3.2)。**字だけ・押せない**。1 行に入らない文は下へ重ねて伸びる(省略記号で切らない) */
.say {
  left: var(--say-x);
  top: var(--say-y);
  width: var(--say-w);
  min-height: var(--say-h);
  z-index: 3;
  padding: 1px 4px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.5;
  text-align: center;
  color: var(--deep);
  --cc-rgb: var(--deep-rgb);
  pointer-events: none;
  overflow-wrap: anywhere;
}
.say:not(:empty) { background: var(--bg); }

/* ---- 上の帯(3.1)。メニュー / もどす / たな(空いた所)/ きく(右寄せ・いちばん大きい) */
.top {
  display: flex;
  gap: 0;
  align-items: stretch;
}
.tbtn { flex: 0 0 auto; height: 100%; }
#menubtn { width: var(--tb-menu); }
#undo { width: var(--tb-undo); }
#redo { width: var(--tb-redo); }
/* すすむ は もどす より一段弱く(縁を薄く。影は残す = 押せる ← mitame.md 5.2。年齢適合レビューの軽微) */
#redo .ink { --edge-c: color-mix(in srgb, currentColor 22%, var(--bg)); }
@supports not (color: color-mix(in srgb, red 50%, blue)) { #redo .ink { --edge-c: rgba(var(--cc-rgb), .22); } }
#play { width: var(--tb-listen); margin-left: auto; }
/* 縦の画面(heya.md「わかる 5」): **きく は下の帯の右**(#1826。DOM は上の帯のまま = 焦点の順は変えない)・
   **おてほん は上の帯**(#1827。roll.js の同じ要素を heya.js が移す)・見出しの行は持たない */
:root[data-mhead="0"] #play {
  position: absolute;
  left: calc(var(--play-x) - var(--top-x));
  top: calc(var(--play-y) - var(--top-y));
  width: var(--play-w);
  height: var(--play-h);
  margin-left: 0;
}
:root[data-mhead="0"] #play .lbl { font-size: 15px; }
:root[data-mhead="0"] .mhead { display: none; }
#top .otehon { flex: 0 0 auto; width: var(--tb-otehon); height: 100%; }
#top .otehon .ink { flex-direction: column; gap: 2px; padding: 0; }
#top .otehon .art { width: 26px; height: 26px; }
#top .otehon .lbl { font-size: 11px; }
/* 下の帯のタブ(縦)は狭い(375 で 79)= 絵の下に字 */
:root[data-mhead="0"] .tab .ink { flex-direction: column; gap: 2px; }
:root[data-mhead="0"] .tab .lbl { font-size: 12px; }
.tbtn .art { width: 26px; height: 26px; }
.tbtn .lbl { font-size: 11px; }
/* きく: 絵とことばを横に並べる(字は大きめ)。**色は替えない**(▶ ⇄ ■ と ことば だけ ← 11 章 7) */
#play .ink { flex-direction: row; gap: 8px; --edge-w: 3px; --edge-c: currentColor; }
#play .art { width: 26px; height: 26px; }
#play .art svg { fill: var(--art-ink); }
#play .lbl { font-size: 16px; }
/* 主役と補助の強さ(mitame.md 6.3。#1836): きく = 面 こもれび色 30%(「ある」の面)+ 影 `--lift-on`。▶ ⇄ ■ では替えない。
   補助(メニュー・もどす・おてほん)= 面に色を敷かない(紙の地のまま)。縁と影は残す(影がある = 押せる ← mitame.md 5.2)。
   **`box-shadow` は書かない**(変数だけ ← mitame.md 5.3) */
#play .ink { background-color: color-mix(in srgb, var(--row3) 30%, var(--bg)); --lift-cur: var(--lift-on); }
#menubtn .ink, #undo .ink, #redo .ink, .otehon .ink { background-color: var(--bg); }
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  #play .ink { background-color: rgba(var(--row3-rgb), .3); }
  #menubtn .ink, #undo .ink, #redo .ink, .otehon .ink { background-color: var(--bg); }
}
/* 16 小節目の終わりで木琴を押した合図(roll.md 9 章): **きく の絵が 1 回だけ弾む**(`transform` だけ) */
#play[data-nudge] .art { animation: play-nudge 420ms ease-out; }
@keyframes play-nudge {
  0% { transform: none; }
  35% { transform: translateY(-10%) scale(1.18); }
  70% { transform: translateY(2%) scale(0.97); }
  100% { transform: none; }
}
@keyframes play-nudge-still { from, to { transform: scale(1.18); } }
/* たな(heya.md 末尾「わかる 2」。#1813)= オルゴールの絵(#1797)+「たな」。もどす と きく の間の空いた所いっぱい(最小は heya-layout.js の `SHELF_MIN`)。
   鳴っている間だけ つつのピンが流れ・ハンドルが回る(`transform` だけ・等速)。止めたらその場で止まる(`paused`) */
/* きく より広くしない(きく が帯でいちばん大きい ← heya.md 3.1)。余りは きく の前の空き */
#shelfbtn { flex: 1 1 0; min-width: 0; max-width: calc(var(--tb-listen) - 12px); }
#shelfbtn .ink { gap: 1px; padding: 0; }
#shelfbtn .art.mbox {
  width: 100%;
  height: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.mbox svg {
  width: 100%;
  height: calc(var(--top-h) - 28px);
  max-width: calc((var(--top-h) - 28px) * 108 / 64);
  fill: none;
  stroke: var(--art-ink);
  stroke-width: var(--art-w);
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}
.mbox .mroll { animation: mbox-roll 3600ms linear infinite paused; }
.mbox .mcrank { transform-box: view-box; transform-origin: 84px 19px; animation: mbox-crank 3600ms linear infinite paused; }
.mbox[data-turn="1"] .mroll, .mbox[data-turn="1"] .mcrank { animation-play-state: running; }
@keyframes mbox-roll { from { transform: none; } to { transform: translateY(-26px); } }
@keyframes mbox-crank { from { transform: none; } to { transform: rotate(360deg); } }
/* ふた(#1835)。ふだんは左の ちょうつがいで後ろへ開いて絵の外(`#mbox-lidclip` で切る)。最後まで鳴ったら 900ms で閉じる(`transform` だけ・1 回)。
   面の色で塗る(下の つつ と くし を隠す)。次の きく で同じ遷移で開く */
.mbox .mlid {
  transform-box: view-box;
  transform-origin: 7px 50.5px;
  transform: rotate(-104deg);
  transition: transform 900ms ease-in-out;
}
.mbox[data-lid="1"] .mlid { transform: none; }
.mbox .mlid path:first-child { fill: color-mix(in srgb, currentColor 8%, var(--bg)); }
@supports not (color: color-mix(in srgb, red 50%, blue)) { .mbox .mlid path:first-child { fill: var(--bg); } }
/* たなに おく を押した知らせ(2026-10-02 動線 10)。ボタンの絵が1回だけ弾む(同じ弾み・`transform` だけ) */
.fkeepb[data-bump] .art { animation: play-nudge 420ms ease-out; }
/* ぜんぶ けす のあとの もどす(もどせる #1814)・つつが入った たな(#1816 → #1813)・メロディに音が入った ばんそう のタブ(#1804)も同じ弾み */
#undo[data-nudge] .art, #menubtn[data-nudge] .art, #shelfbtn[data-nudge] .art, .tab[data-nudge] .art { animation: play-nudge 420ms ease-out; }
/* しあげの部屋の たなに おく から たな へ飛ぶ つつ(heya.md 6.1。#1816)。**押せない**・動きは `app.js` の `transform` だけ */
.ftube {
  position: fixed;
  z-index: 30;
  pointer-events: none;
  padding: 2px 4px;
  box-sizing: border-box;
  border-radius: var(--r-sm);
  background-color: var(--bg);
  box-shadow: var(--lift-sm);
  color: var(--ink);
}
.ftube svg { display: block; width: 100%; height: 100%; }

/* ---- 曲の帯(3.3)。16 小節を全部見せる(**送らない**)。縦 = 2 段 x 8 / 横の狭い左の列 = 4 段 x 4 */
.song {
  display: grid;
  grid-template-columns: repeat(var(--song-cols, 8), minmax(0, 1fr));
  grid-auto-rows: var(--song-h, 44px);
  row-gap: 4px;
}
.sbar .ink { inset: 2px; justify-content: flex-start; padding-top: 3px; }
.sbar .art { width: 100%; flex: 1 1 auto; min-height: 0; padding: 0 2px; }
.sbar .num {
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: 700;
  line-height: 12px;
  color: var(--deep);
  --cc-rgb: var(--deep-rgb);
  font-variant-numeric: tabular-nums;
}
.sbar[data-feet="1"] .num { margin-bottom: 6px; }
/* 旋律が入っている小節 = 「ある」の語彙(#1801 ← heya.md 3.3 / mitame.md 6.2): 面 こもれび色 26%・縁 こもれび色 50%・影 `--lift-on`。
   **`box-shadow` は書かない**(変数だけ ← mitame.md 5.3)。開いている小節の縁(下の規則)が勝つよう、こちらを先に置く */
.sbar[data-full="1"] .ink {
  --edge-c: color-mix(in srgb, var(--row3) 50%, var(--bg));
  --lift-cur: var(--lift-on);
  background-color: color-mix(in srgb, var(--row3) 26%, var(--bg));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .sbar[data-full="1"] .ink { --edge-c: rgba(var(--row3-rgb), .5); background-color: rgba(var(--row3-rgb), .26); } }
/* 開いている小節 = 縁 3px(墨) */
.sbar[data-edit="1"] .ink { --edge-w: 3px; --edge-c: var(--deep); }
/* 再生中の小節 = 上辺の短い横棒(**静かな印**。点けたり消したりを繰り返さない) */
.rplay {
  position: absolute;
  left: 30%;
  right: 30%;
  top: 0;
  height: 3px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--deep) 70%, var(--bg));
  visibility: hidden;
  pointer-events: none;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .rplay { background: var(--deep-70-bg); } }
.sbar[data-play="1"] .rplay { visibility: visible; }
/* しおり = 左の縁の外側に墨の縦帯 3px(下は V の切れ込み)。根の足 = 番号の下に根の色 */
.rribbon {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--deep);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% calc(100% - 3px), 0 100%);
  pointer-events: none;
}
.rroot {
  position: absolute;
  left: var(--edge-w);
  right: var(--edge-w);
  bottom: var(--edge-w);
  height: 5px;
  border-radius: 0 0 calc(var(--r-sm) - var(--edge-w)) calc(var(--r-sm) - var(--edge-w));
  background: var(--deg);
  pointer-events: none;
}

/* ---- 部屋のタブ(3 つ)。選んでいる部屋 = 縁 3px + 面を少し濃く(**替わりは床 520ms** ← heya.js) */
.tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.tab .ink { flex-direction: row; gap: 6px; }
/* 絵は 30(#1804)。タブ 1 枚が狭い画面(320 = 101)と低いタブ(44)は 24(字の幅・石の居場所を食わない) */
.tab .art { --tab-art: clamp(24px, min(calc(var(--tabs-w) / 3 - 80px), calc(var(--tabs-h) - 20px)), 30px); position: relative; width: var(--tab-art); height: var(--tab-art); }
/* 順番の石 1 / 2 / 3(#1804)。絵の左上に重ねる小さな墨の丸(**読み上げない**・押下は箱が受ける) */
.tstep {
  position: absolute;
  left: -9px;
  top: -5px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--deep);
  color: var(--bg);
  font-size: 11px;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.tab .lbl { font-size: 13px; }
.tab[aria-selected="true"] .ink {
  --edge-w: 3px;
  --edge-c: var(--deep);
  --lift-cur: var(--lift);
  background-color: color-mix(in srgb, var(--deep) 12%, var(--bg));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .tab[aria-selected="true"] .ink { background-color: var(--deep-12-bg); } }

/* ---- 部屋(縦 = 1 列に積む。`.pl` / `.pr` は箱を持たない) */
.room {
  display: flex;
  flex-direction: column;
  gap: var(--h-gap, 8px);
}
.room > * > *, .room > * { flex: 0 0 auto; }
/* ばんそうの部屋の隙は**縮める順が決める**(`ACC_FITS[i].gap` → `--a-gap`)。`--h-gap` を読むと式と画面がずれる */
#room-acc { gap: var(--a-gap, 8px); }
.pl, .pr { display: contents; }

/* 小さな見出し(**押せない = 枠も影も付けない**) */
.mtitle, .ascope, .arhead, .fhead {
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--deep);
  --cc-rgb: var(--deep-rgb);
}

/* 字の的(おてほん・かえる・とじる・くりかえし ±・たなに おく / わたす)。絵 + ことば を横に */
.hbtn { height: 44px; }
.hbtn .ink { flex-direction: row; gap: 6px; padding: 0 10px; }
.hbtn .art { width: 24px; height: 24px; }
.hbtn .lbl { font-size: 13px; }

/* ---- メロディの部屋(3.4) */
.mhead {
  height: var(--m-head, 44px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.otehon { width: 120px; flex: 0 1 120px; min-width: 0; }
/* この しょうせつを きく(#1803)。▶ の葉 + 「{n} しょうせつめ」。字は見出しの `.mtitle` のまま(折らない・残りの幅に収まる) */
.mhead { container-type: inline-size; }
/* 面(`.ink`)は絶対配置なので箱は字の幅に育たない = 空いた幅へ伸ばす(最大 200)。`0 1 auto` のままだと 60 に留まり、
   812x375 / 667x375 で「1 しょうせつめ」が箱の外へ 60px はみ出して、はみ出た字の上の押下が的に当たらなかった(わかる 6 デザイナーレビュー 重大) */
.mplay { flex: 1 1 auto; min-width: 60px; max-width: 200px; }
.mplay .ink { justify-content: flex-start; gap: 4px; padding: 0 8px; }
.mplay .art { flex: none; width: 20px; height: 20px; }
.mplay .lbl { min-width: 0; text-align: left; line-height: 1.15; white-space: nowrap; }
.mplay .mtitle { display: inline-block; }
.mplay .mnum { display: none; font-size: 16px; }
.mplay .art svg { fill: var(--art-ink); }
/* 見出しの行が狭い(低い横の左の列 176〜204)= 「{n} しょうせつめ」が入らない → 番号だけ(読み上げは全文のまま) */
@container (max-width: 290px) {
  .mplay { min-width: 56px; }
  .mplay .ink { padding: 0 5px; gap: 3px; }
  .mplay .mtitle { display: none; }
  .mplay .mnum { display: inline-block; }
}

.mscore {
  height: var(--m-grid);
  display: grid;
  grid-template-columns: var(--m-name, 40px) minmax(0, 1fr);
  gap: 4px;
}
/* 名前札(高さの色の地に字。**押せない**) */
.mnames {
  display: grid;
  grid-template-rows: repeat(8, minmax(0, 1fr));
  gap: 1px;
  min-height: 0;
  overflow: hidden;                 /* 低い画面で札が長さの段へはみ出さない */
  overflow: clip;                   /* ふくらむ札(#1808)は 6px まで外へ出してよい(clip の無いブラウザは hidden のまま = 縁で切れるだけ) */
  overflow-clip-margin: 6px;
  pointer-events: none;
}
.mname {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-height: 0;
  overflow: hidden;
  border-radius: 4px;
  background: var(--deg);
  color: var(--bg);
  --cc-rgb: var(--bg-rgb);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
}
/* たかい ど の しるし = 小さな山の影絵(#1829)。字は ほかの札と同じ大きさ。字の色で塗り、字の行より上へ上げる(線の山は「へ」に読めた) */
.khigh {
  display: inline-block;
  flex: 0 0 auto;
  width: 0.85em;
  height: 0.6em;
  margin-right: 1px;
  fill: currentColor;
  stroke: none;
  vertical-align: 0.45em;
}
/* 名前札は低い(320x568 で 10.6px・568x320 で 6.9px)ので上げると札の縁で切れる = 字の高さの真ん中に置く(塗った影絵なので「へ」には読めない)。
   2 段の木琴(幅 360 未満)は板が低く、上げると板の穴(`.plate`)に重なる = 字の下の側へ下げて左へ離す */
:root[data-xrows="2"] .xkey .khigh { vertical-align: -0.05em; margin-right: 3px; }
/* 2 段の板は低い(320x568 で約 33px)。穴を上へ・字を下へ寄せて、穴と字(と山)を重ねない(#1829 デザイナーレビュー) */
:root[data-xrows="2"] .xkey .plate { top: 5px; }
:root[data-xrows="2"] .xkey .ink { padding-bottom: 3px; }
/* 色だけで高さを言わない(#1830)。**奇数の高さ(れ・ふぁ・ら・たかい ど)は斜めの細い縞**・偶数は無地 =
   隣り合う高さ(色の近い み と ふぁ・そ と ら)は必ず模様が替わる。木琴の板・名前札・譜面の棒・とぶ音で同じ。
   **静止**(動かさない)・地の色と字の色は変えない(`background-image` だけ) */
.xkey[data-deg="1"] .ink, .xkey[data-deg="3"] .ink, .xkey[data-deg="5"] .ink, .xkey[data-deg="7"] .ink,
.mname[data-deg="1"], .mname[data-deg="3"], .mname[data-deg="5"], .mname[data-deg="7"],
.rnote[data-deg="1"], .rnote[data-deg="3"], .rnote[data-deg="5"], .rnote[data-deg="7"],
.rfly[data-deg="1"], .rfly[data-deg="3"], .rfly[data-deg="5"], .rfly[data-deg="7"] {
  background-image: repeating-linear-gradient(135deg, rgba(var(--deep-rgb), .14) 0 3px, transparent 3px 7px);
}

/* 譜面(ピアノロール)。8 マス x 8 高さ。**押すとカーソルが動くだけ**(roll.md 5.3。判定は指の座標) */
.rgrid {
  position: relative;
  min-width: 0;
  overflow: hidden;
  border-radius: var(--r-sm);
  background: var(--bg);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, currentColor 40%, var(--bg));
  touch-action: none;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .rgrid { box-shadow: inset 0 0 0 2px rgba(var(--cc-rgb), .4); } }
.rlanes {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  pointer-events: none;
}
.rlane {
  flex: 1 1 0;
  min-height: 0;
  background: color-mix(in srgb, var(--deg) 10%, var(--bg));
  border-top: 1px solid color-mix(in srgb, var(--deg) 22%, var(--bg));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .rlane { background: linear-gradient(rgba(var(--deg-rgb), .1), rgba(var(--deg-rgb), .1)) var(--bg); border-top: 1px solid rgba(var(--deg-rgb), .22); } }
.rlane:first-child { border-top: 0; }
.rbeat {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: color-mix(in srgb, var(--deep) 18%, var(--bg));
  pointer-events: none;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .rbeat { background: var(--deep-18-bg); } }
.rbeat-mid { width: 2px; margin-left: -0.5px; background: color-mix(in srgb, var(--deep) 30%, var(--bg)); }
@supports not (color: color-mix(in srgb, red 50%, blue)) { .rbeat-mid { background: var(--deep-30-bg); } }
.rnotes { position: absolute; inset: 0; pointer-events: none; }
.rnote {
  position: absolute;
  border: 2px solid transparent;
  border-width: 1px 2px;
  background-clip: padding-box;
  background-color: var(--deg);
  border-radius: 6px;
}
.rnote.rcont { border-top-left-radius: 0; border-bottom-left-radius: 0; border-left-width: 0; }
/* 選んでいる音(#1793。もう一度押すと消える)= 長さの「選んでいる」と同じ墨の縁。光らせない */
.rnote[data-sel="1"] { outline: 3px solid var(--deep); outline-offset: 1px; z-index: 1; }
.rcursor {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 3px;
  margin-left: -1.5px;
  border-radius: 2px;
  background: var(--deep);
  pointer-events: none;
}
.rcursor[data-end="1"] { margin-left: -3px; }
.rghost {
  position: absolute;
  top: 0;
  bottom: 0;
  box-sizing: border-box;
  /* つぎに置く所の枠(roll.md 4.7。#1794): 縁 3px の墨(下だけ 5px)。**点滅させない・影を付けない** */
  border: 3px solid var(--deep);
  border-bottom-width: 5px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--deep) 9%, transparent);
  pointer-events: none;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .rghost { background: rgba(var(--deep-rgb), .09); } }
/* 上の辺の真ん中の下向きの三角(「ここへ入る」) */
.rghost::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  width: 10px;
  height: 6px;
  margin-left: -5px;
  background: var(--deep);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.rghost[data-end="1"] { visibility: hidden; }
/* 置いた音が板から譜面へ飛ぶ(roll.md 5.4。#1795)。着く場所に在って、`transform` だけで飛んでくる(roll.js が動かす) */
.rfly {
  position: fixed;
  z-index: 4;
  box-sizing: border-box;
  border: 2px solid transparent;
  border-width: 1px 2px;
  background-clip: padding-box;
  background-color: var(--deg);
  border-radius: 6px;
  pointer-events: none;
}
.rneedle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: color-mix(in srgb, var(--deep) 45%, var(--bg));
  pointer-events: none;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .rneedle { background: var(--deep-45-bg); } }
.rneedle[data-on="0"] { visibility: hidden; }

/* 長さ 3 + やすみ(やすみは隙間で分ける) */
.rlens {
  height: var(--m-len);
  display: flex;
}
.rlen { flex: 1 1 0; height: 100%; }
.rlen.rrest { margin-left: 12px; }
.rlen .art { width: 70%; height: 48%; }
.rlen svg .rbar { fill: var(--art-ink); stroke: none; }
.rlen svg .rhollow { fill: none; stroke: var(--art-ink); stroke-width: 3; }
.rlen svg .rarrow { fill: none; stroke: var(--art-ink); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }

/* 木琴(8 本 1 段・左 = ど・左ほど板が長い)。**押す的は列ぜんぶ**(板が短い右の音も上から下まで押せる) */
.xylo {
  height: var(--m-xy);
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  grid-template-rows: minmax(0, 1fr);
  border-radius: var(--r);
  background: color-mix(in srgb, var(--deep) 14%, var(--bg));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .xylo { background: var(--deep-14-bg); } }
.xkey { position: relative; min-width: 0; min-height: 0; --s-press: 1; }
.xkey .ink {
  position: absolute;
  left: 3px;
  right: 3px;
  top: calc((100% - var(--plate)) / 2);
  height: var(--plate);
  max-height: 200px;
  margin: auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding-bottom: 8px;
  border-radius: var(--r-sm);
  background-color: var(--deg);
  box-shadow: var(--lift-sm);
  transform: scale(var(--s-press));
}
.xkey .plate {
  position: absolute;
  top: 12px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--bg) 60%, var(--deg));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .xkey .plate { background: rgba(var(--bg-rgb), .6); } }
.xkey .lbl { color: var(--bg); --cc-rgb: var(--bg-rgb); font-size: 14px; font-weight: 800; }
/* 木琴は主役(mitame.md 6.3。#1836)= 影を 1 段強く(`--lift-sm` → `--lift-on`。いつも同じ・状態で替えない) */
.xkey .ink { box-shadow: var(--lift-on); }
/* きく の間は いっしょに ひく(roll.md 5.9。#1824): 板の面の内側に点線(おてほんの ためし と同じ「曲は変わらない」)・つぎの枠と縦線を隠す。
   印は `#room-mel[data-along]`(きく の絵と同じ床)。**`outline` だけ**(`box-shadow` は影の1か所 ← mitame.md 5.3)・的の箱は覆わない */
#room-mel[data-along="1"] .xkey .ink { outline: 2px dashed var(--deep); outline-offset: -5px; }
#room-mel[data-along="1"] .rghost, #room-mel[data-along="1"] .rcursor { display: none; }
.xkey[data-deg="0"] { --plate: calc(100% - 6px); }
.xkey[data-deg="1"] { --plate: calc(95% - 6px); }
.xkey[data-deg="2"] { --plate: calc(90% - 6px); }
.xkey[data-deg="3"] { --plate: calc(85% - 6px); }
.xkey[data-deg="4"] { --plate: calc(80% - 6px); }
.xkey[data-deg="5"] { --plate: calc(75% - 6px); }
.xkey[data-deg="6"] { --plate: calc(70% - 6px); }
.xkey[data-deg="7"] { --plate: calc(65% - 6px); }
/* 狭い縦(W < 360)は 2 段(下 = ど〜ふぁ / 上 = そ〜たかい ど)。板の長さの比は段ごとに同じ */
/* はじめの ゆび(roll.md 5.5。#1796)。ど の列の上の方で、板を押す動きを 4 回してから止まって残る。
   **押せない**(下の木琴が受ける ← #787)。動きは `transform` だけ */
.mhint {
  --hw: min(48px, 90%);
  position: absolute;
  left: 50%;
  top: 8%;
  width: var(--hw);
  margin-left: calc(var(--hw) / -2);
  aspect-ratio: 40 / 48;
  pointer-events: none;
  animation: hint-press 1400ms ease-in-out 600ms 4 both;
}
.mhint svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: var(--deep);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mhint svg .hhand { fill: var(--bg); }
.mbox svg .mcomb { fill: var(--art-ink); stroke: none; }
@keyframes hint-press {
  0% { transform: translateY(-8px); }
  35% { transform: none; }
  45% { transform: translateY(2px) scale(0.92); }
  60% { transform: none; }
  100% { transform: translateY(-8px); }
}
:root[data-xrows="2"] .xylo {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
}
:root[data-xrows="2"] .xkey[data-deg="0"], :root[data-xrows="2"] .xkey[data-deg="1"],
:root[data-xrows="2"] .xkey[data-deg="2"], :root[data-xrows="2"] .xkey[data-deg="3"] { grid-row: 2; }
:root[data-xrows="2"] .xkey[data-deg="4"], :root[data-xrows="2"] .xkey[data-deg="5"],
:root[data-xrows="2"] .xkey[data-deg="6"], :root[data-xrows="2"] .xkey[data-deg="7"] { grid-row: 1; }

/* ---- ばんそうの部屋(3.5)。縦の並び = 範囲 → 段 3 つ(+ たいこの項目)→ ひびきの もと → しおり
   (DOM は 段 → 範囲・板・しおり の順 = 焦点の順。縦は `order` で見た目だけ並べ直す) */
.ascope { order: 0; height: 20px; display: flex; align-items: center; gap: 6px; }
/* 範囲の絵(#1820)= 曲の帯と同じ 2 x 8 の小さな角丸。流れる小節を塗る(押せない・読み上げない) */
.ascope .sart { flex: 0 0 auto; width: 58px; height: 16px; }
.ascope .sart .son { fill: var(--art-ink); stroke: none; }
.ascope .sart .soff { fill: none; stroke: var(--art-ink); stroke-width: 1px; }
.ascope .stxt { min-width: 0; }
.lane, .ditems { order: 1; }
.aroots { order: 2; }
.aribbonb { order: 3; }
/* もっと(#1821 #1822 ← heya.md「わかる 4」)= 板と しおりを たたんだ口 1 つ。高さは しおりと同じ(寸法の式は開いた姿のまま = 必ず入る)。
   補助の強さ(面に色を敷かない ← mitame.md 6.3)。絵 = 下向きの かぎ(線) */
.amore { order: 2; height: var(--a-ribbon, 52px); }
.amore .ink { background-color: var(--bg); }
.amore .art { width: 24px; height: 24px; }
@supports not (color: color-mix(in srgb, red 50%, blue)) { .amore .ink { background-color: var(--bg); } }
:root[data-accscope="0"] .ascope { display: none; }
:root[data-accroothead="0"] .arhead { display: none; }

.lane {
  height: var(--a-card, 64px);
  display: grid;
  grid-template-columns: var(--a-card, 64px) minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  border-radius: var(--r);
  background: color-mix(in srgb, currentColor 6%, var(--bg));
  box-shadow: inset 0 0 0 2px color-mix(in srgb, currentColor 25%, var(--bg));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .lane { background: linear-gradient(rgba(var(--cc-rgb), .06), rgba(var(--cc-rgb), .06)) var(--bg); box-shadow: inset 0 0 0 2px rgba(var(--cc-rgb), .25); } }
.lart { width: var(--a-card, 64px); height: var(--a-card, 64px); }
.lart .art { width: 62%; height: 62%; }
/* 空の段 = 点線の枠 + 「+」 */
.lart[data-empty="1"] .ink {
  --edge-w: 0px;
  background-color: var(--bg);
  border: 2px dashed color-mix(in srgb, currentColor 60%, var(--bg));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .lart[data-empty="1"] .ink { border: 2px dashed rgba(var(--cc-rgb), .6); } }
.lname { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; text-align: left; }
.lname .lt { font-size: 14px; font-weight: 800; line-height: 1.2; color: var(--deep); --cc-rgb: var(--deep-rgb); }
.lname .ln { font-size: 12px; font-weight: 700; line-height: 1.2; color: var(--deep); --cc-rgb: var(--deep-rgb); overflow-wrap: anywhere; }
/* 段の説明は **段に入る行数** で切る(`--a-ln` = `heya-layout.js` の `lnLinesOf`。カード 64 = 3 行・56 / 52 / 48 = 2 行)。
   たいこ 4 つの古い曲の「A と B と C と D」が 3 行になり、段の枠の下へはみ出して項目に重なった
   (#833: 4 列に畳む低い横 = de 568x320 で下端 173 > 160 ← デザイナーレビュー 重大1。
    #851: 375x667 の es / fr / de / pt で下端 321 > 312・項目に 25px²、812x375 の fr / pt、480x280 の fr たいこ 2 つ、320x568 の de は 4 行)。
   入る行数以内の説明は高さが 1px も変わらない(clamp は溢れる行があるときだけ効く。基準 375x812 の 3 行は切らない)。
   字は DOM に全部残る(読み上げは全文)。切れた楽器の名前は、画面では項目の絵で読め、字ではうちかたの一覧を開けば読める */
.lname .ln {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--a-ln, 2);
  line-clamp: var(--a-ln, 2);
  overflow: hidden;
}
/* 名前 + かえる = 1 つの口(#1819)。**面は段のカードそのもの**(口の面を重ねない = 2 つ目のボタンに見せない)。
   内へ 3px 入れると 48 の段で説明 2 行(46.6)が入らない → 面の内側いっぱい(`inset: 0`) */
.lchg { grid-column: 2; height: 100%; min-width: 0; }
.lchg .ink {
  inset: 0;
  justify-content: flex-start;
  gap: 4px;
  padding: 0 6px 0 0;
  --edge-w: 0px;
  --lift-cur: 0 0 0 0 transparent;
  background-color: transparent;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .lchg .ink { background-color: transparent; } }
.lchg .lbl { flex: 0 0 auto; font-size: 13px; overflow-wrap: normal; white-space: nowrap; }
.lchg .lgo { width: 16px; height: 16px; flex: 0 0 auto; }
.lchg .lplus { display: none; }
/* 空の段 = 段ぜんぶが 1 つの口。左に点線の枠 + 「+」(`.lart[data-empty]` と同じ言葉) */
.lane[data-empty="1"] .lchg { grid-column: 1 / -1; }
.lane[data-empty="1"] .lchg .lplus {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: var(--a-card, 64px);
  height: 100%;
  margin-right: 4px;
  box-sizing: border-box;
  border-radius: var(--r-sm);
  border: 2px dashed color-mix(in srgb, currentColor 60%, var(--bg));
  background-color: var(--bg);
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .lane[data-empty="1"] .lchg .lplus { border: 2px dashed rgba(var(--cc-rgb), .6); } }
.lchg .lplus .art { width: 62%; height: 62%; }

/* たいこの項目(2 列)。入っている たいこ 1 つずつの うちかた */
.ditems {
  display: grid;
  grid-template-columns: repeat(var(--a-item-cols, 2), minmax(0, 1fr));
  grid-auto-rows: var(--a-item, 48px);
  row-gap: 4px;
  color: var(--row0);
  --cc-rgb: var(--row0-rgb);
}
.ditems[data-n="0"] { display: none; }
.ditem .ink { flex-direction: row; justify-content: flex-start; gap: 5px; padding: 0 5px; }
/* 左 = 楽器の絵の下に うちかたの点(ことばの列に幅を渡す。320 幅で名前が 1 行に入る) */
.ditem .dleft { flex: 0 0 34px; display: flex; flex-direction: column; align-items: center; gap: 1px; }
.ditem .art { width: 22px; height: 22px; }
.ditem .dpat { width: 34px; height: 12px; }
/* `patternArt` は線だけの絵(塗りにすると透明になる ← デザイナーレビュー) */
.ditem .dpat svg { fill: none; stroke: var(--art-ink); }
/* ことば: 名前の行 / うちかたの行。**語の途中で割らない**(空白でだけ折る)。区切りの字は隠す */
.ditem .lbl { flex: 1 1 auto; min-width: 0; text-align: left; font-size: 11px; overflow-wrap: normal; word-break: keep-all; }
.ditem .lbl .dn, .ditem .lbl .dr { display: block; }
.ditem .lbl .dn:empty, .ditem .lbl .ds { display: none; }
/* 4 列 1 段(低い横 568x320 で たいこ 3〜4 つの古い曲だけ。`solveHeya` が 2 列で右の列に入らないときに選ぶ ← #833)。
   1 つ 89 x 44 には 絵 + 点 と 名前 2 行が並ばない(名前 34px 幅)ので、**絵と うちかたの点だけ**を横に並べる。
   名前と うちかたは読み上げ(`aria-label`)と、押して開く一覧の見出しが言う */
:root[data-accitems="4"] .ditem .ink { justify-content: center; padding: 0 4px; }
:root[data-accitems="4"] .ditem .dleft { flex: 0 0 auto; flex-direction: row; gap: 6px; }
:root[data-accitems="4"] .ditem .art { width: 24px; height: 24px; }
:root[data-accitems="4"] .ditem .dpat { width: 40px; height: 14px; }
:root[data-accitems="4"] .ditem .lbl { display: none; }

/* ひびきの もと(板 4 枚 = ど / ふぁ / そ / ら)。選んでいる根 = 縁 3px(**替わりは床 500ms** ← accroom.js) */
.aroots { display: flex; flex-direction: column; gap: 4px; }
.arhead { height: 16px; font-size: 12px; }
.aplates {
  height: var(--a-root, 76px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.rplate .art { width: 84%; height: 42%; }
.rplate .lbl { font-size: 13px; }

/* しおり(リボン + 字。点線の枠 = 「曲を区切る」)。小節 1 でも押せる見た目のまま(半透明にしない) */
.aribbonb { height: var(--a-ribbon, 52px); }
.aribbonb .ink {
  flex-direction: row;
  justify-content: flex-start;
  gap: 10px;
  padding: 0 12px;
  --edge-w: 0px;
  border: 2px dashed color-mix(in srgb, var(--deep) 55%, var(--bg));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .aribbonb .ink { border: 2px dashed var(--deep-55-bg); } }
.aribbonb .art { width: 28px; height: 28px; }
.aribbonb .lbl { text-align: left; font-size: 13px; }
/* 低い横(568x320)は しおりの列が細い(176)。字を 2 行に収める */
:root[data-hl="1"][data-sayover="1"] .aribbonb .ink { gap: 6px; padding: 0 8px; }
:root[data-hl="1"][data-sayover="1"] .aribbonb .lbl { font-size: 12px; }

/* ---- しあげの部屋(3.6) */
.fhead { height: 20px; display: flex; align-items: flex-end; }
.ftimbres {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: var(--f-timbre, 76px);
}
/* 絵の高さは、名前 2 行(12px x 1.15 x 2)+ 隙 2 + 字形の上下のはみ出しを面に残す分まで(`100% - 32px`)。
   面の高さ 53(568x320・667x375)で 46% のままだと 絵 24.4 + 2 + 字 27.6 = 54 が面を越え、2 行の名前(es「Láminas que vibran」)が面の下へ出た(#1617)。
   面が 59.3 以上の画面では 46% が小さいほうなので変わらない */
.ftimbre .art { width: 46%; height: min(46%, 100% - 32px); }
.fturns {
  height: var(--f-row, 64px);
  display: flex;
  align-items: center;
  gap: 8px;
}
.fstep { width: var(--f-step, 64px); height: var(--f-row, 64px); }
.fstep .art { width: 30px; height: 30px; }
/* 数の欄は行の高さいっぱいに取り、字は真ん中へ(`stretch` + `justify-content`)。中身の高さで包むと、line-height 1.2 の行の箱より
   字形の箱(フォントの ascent + descent)が上下に約 1px 出て「面からはみ出す」(#1617。568x320 の「3 かい」が上へ 1px) */
.fnum { flex: 1 1 auto; min-width: 0; align-self: stretch; display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--deep); --cc-rgb: var(--deep-rgb); }
.fnum .fn { font-size: 18px; font-weight: 800; line-height: 1.2; }
.fnum .fm { font-size: 12px; font-weight: 700; line-height: 1.2; }
.fkeep {
  height: var(--f-keep, var(--f-row, 64px));
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.fkeepb { height: var(--f-keep, var(--f-row, 64px)); }
.fkeepb .art { width: 30px; height: 30px; }
/* おくる の絵は横長(つつ → おうち。viewBox 100 x 50 ← shelf.js `SHARE_VB`) */
.fkeepb[data-act="share"] .art { width: 48px; height: 24px; }
/* 低い横(568x320)の しあげ(#833。`FinRoom.arrange`): 左 = くりかえし / 右 = 音色 + とっておく。
   左の 176 に [−] 56・数の字 56・[+] 56(隙 4)。右の とっておく は 1 段 48(`.hbtn` なので絵が左・字が右のまま)。見出し「とっておく」は隠す */
:root[data-finswap="1"] .fturns { gap: 4px; }
/* [−][+] は 56 のまま縮めない(`flex: none`)。数の欄は `min-width: 0` で中身の字の幅に引きずられて 56 を削っていた
   (ja 52.9・en 48.7・pt 44.5 ← #833 デザイナーレビュー 重大2)。数の欄は残りの幅(568x320 で 56)で字を折る */
:root[data-finswap="1"] .fstep { flex: none; }
/* 数の字の列は 56 しか無い。「やく 3 ぷん」を空白でだけ折る(語の途中の「ぷ/ん」にしない)。
   回数(de「3-mal」)は折らない(ハイフンでも折れる = 「3-/mal」)。18px のままでは de 57.1 が 56 を越えるので 16px(de 50.8) */
:root[data-finswap="1"] .fnum .fm { word-break: keep-all; overflow-wrap: normal; text-align: center; }
:root[data-finswap="1"] .fnum .fn { white-space: nowrap; font-size: 16px; }
:root[data-finswap="1"] .fkh { display: none; }
/* 音色の段と とっておく の間を 10 に(列の隙 6 + 4。`KEEP_SEP_SWAP` ← heya-layout.js) */
:root[data-finswap="1"] .fkeep { margin-top: var(--f-keep-mt, 0px); }

/* ---- 横(4.4)。部屋を左右の列に割る(左 = 小節の道具・譜面 / 右 = 段・長さ・木琴) */
:root[data-hl="1"] .room:not([hidden]) { display: contents; }
:root[data-hl="1"] .pl,
:root[data-hl="1"] .pr {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: var(--h-gap, 6px);
}
:root[data-hl="1"] .pl { left: var(--pl-x); top: var(--pl-y); width: var(--pl-w); height: var(--pl-h); }
:root[data-hl="1"] .pr { left: var(--pr-x); top: var(--pr-y); width: var(--pr-w); height: var(--pr-h); }
:root[data-hl="1"] #room-acc .pl, :root[data-hl="1"] #room-acc .pr { gap: var(--a-gap, 6px); }
:root[data-hl="1"] .ascope { height: 18px; }
:root[data-hl="1"] .fhead { height: 18px; }
:root[data-hl="1"] .mscore { flex: 1 1 auto; min-height: 0; height: auto; }
/* 長さの段が隠れている間(#1807)も木琴は右の列の下端に付く = 段が出ても木琴は 1px も動かない(デザイナーレビュー 重大) */
:root[data-hl="1"][data-lens="0"] .pr.mel-r { justify-content: flex-end; }
/* 横で木琴が 120 以上残るときは、見出しの行(この しょうせつを きく + おてほん)を右の列の上へ(#1828 ← heya.md「わかる 6」)。
   譜面が左の列の高さぜんぶを取る(844x390 で 1 行 18.5 → 24.8px)。**DOM は左の列のまま**(焦点の順は前と同じ)・場所だけ移す。
   右の列は上を見出しのぶん空ける(木琴の箱は長さの段が出ても動かない ← #1807) */
:root[data-hl="1"][data-mheadr="1"] .pl.mel-l > .mhead {
  position: absolute;
  left: calc(var(--pr-x) - var(--pl-x));
  top: calc(var(--pr-y) - var(--pl-y));
  width: var(--pr-w);
  z-index: 1;                       /* 右の列(`.pr` は DOM で後 = 上に重なる)の空けた上端より上に居る。無いと指が `.pr` に当たる */
}
:root[data-hl="1"][data-mheadr="1"] .pr.mel-r { padding-top: calc(var(--m-head) + var(--h-gap)); }

/* ---- 一覧の板(3.7)。**下から出る 1 枚**(横は右の列に重なる)。後ろは `inert`(sheet.js) */
.sheet {
  position: absolute;
  inset: 0;
  z-index: 5;
}
/* 幕は**静止した濃さ**(不透明度を振る動きにしない) */
.sh-scrim {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--deep) 32%, transparent);
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .sh-scrim { background: rgba(var(--deep-rgb), .32); } }
.sh-panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: var(--sh-max);
  display: flex;
  flex-direction: column;
  padding: 0 var(--sh-px, 8px) var(--sh-px, 8px);
  border-radius: var(--r) var(--r) 0 0;
  background: var(--bg);
  box-shadow: var(--lift-on);
}
/* 指で開いたときの焦点の置き場(板そのもの)。輪は出さない ← heya.md 3.7 */
.sh-panel:focus { outline: none; }
/* 上がる(`transform` だけ・180ms)。`sheet.js` が印を外して付け直す(続けて開いても頭から) */
.sh-panel[data-rise] { animation: sh-rise 180ms ease-out; }
@keyframes sh-rise { from { transform: translateY(100%); } to { transform: none; } }
:root[data-hl="1"] .sh-panel {
  left: var(--sh-x);
  right: auto;
  width: var(--sh-w);
  top: 8px;
  bottom: 8px;
  max-height: none;
  border-radius: var(--r);
}
.sh-head {
  flex: 0 0 auto;
  min-height: 52px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.sh-words { flex: 1 1 auto; min-width: 0; }
.sh-title { font-size: 15px; font-weight: 800; line-height: 1.25; color: var(--deep); --cc-rgb: var(--deep-rgb); }
.sh-hint { font-size: 12px; font-weight: 700; line-height: 1.3; color: var(--deep); --cc-rgb: var(--deep-rgb); }
.sh-close { flex: 0 0 84px; height: auto; min-height: 48px; align-self: stretch; }   /* 的は見出しの高さ(52 以上)x 84 */
.sh-close .ink { flex-direction: column; gap: 0; padding: 0 2px; }
.sh-close .art { width: 20px; height: 20px; }
.sh-body {
  flex: 0 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(var(--sh-cols, 3), minmax(0, 1fr));
  grid-auto-rows: var(--sh-cell, 76px);
}
.sh-body[data-kind="lane"] {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: var(--sh-pick, 96px);
}
.sh-body[data-kind="menu"] {
  display: flex;
  flex-direction: column;
}
.sh-body[data-kind="menu"] .sh-item { flex: 0 0 var(--sh-menu, 64px); }
.sh-body[data-kind="menu"] .sh-item .ink { flex-direction: row; justify-content: flex-start; gap: 14px; padding: 0 16px; }
.sh-body[data-kind="menu"] .sh-item .art { width: 32px; height: 32px; }
.sh-body[data-kind="menu"] .sh-item .lbl { text-align: left; font-size: 14px; }
.sh-gap { flex: 0 0 16px; }
.sh-item .art { width: 64%; height: 52%; }
.sh-body[data-kind="lane"] .sh-item .art { width: 56%; height: 56%; }
/* #1811: 字の残りの高さぜんぶ(1 行の名前の型ほど絵が大きい)。粒は鳴る音と同じ時刻に跳ねる(`sheet.js` の `hopPattern`。粒の真ん中を軸に) */
.sh-body[data-kind="otehon"] .sh-item:not(.danger) .ink { padding: 3px 4px 2px; }
.sh-body[data-kind="otehon"] .sh-item:not(.danger) .art { width: 92%; height: auto; flex: 1 1 0; min-height: 0; }
.sh-body[data-kind="otehon"] .mdot { transform-box: fill-box; transform-origin: center; }
.sh-body[data-kind="lane"] .art svg { stroke-width: var(--art-w-lg); }
/* 消す口(赤茶の縁 + ごみ箱)。ぜんぶ けす の 1 回目 = 面を赤茶に(**色の替わりは 1 回**) */
.sh-item.danger { color: var(--d0); --cc-rgb: var(--d0-rgb); }
.sh-item.danger .ink { --edge-c: currentColor; }
.sh-item[data-sure="1"] .ink { --edge-w: 3px; background-color: color-mix(in srgb, currentColor 22%, var(--bg)); }
@supports not (color: color-mix(in srgb, red 50%, blue)) { .sh-item[data-sure="1"] .ink { background-color: rgba(var(--cc-rgb), .22); } }
/* 同じ楽器が 2 つ(古い曲)= 右上に重なった札の印 */
.sh-two { position: absolute; top: 4px; right: 4px; width: 24px; height: 24px; }
.sh-two svg { fill: var(--bg); stroke: var(--art-ink); stroke-width: 2; }
.sh-two svg .n { fill: none; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
/* なし = 空の段と同じ点線の枠(`.lart[data-empty]` と同じ言葉) */
.sh-item svg .dash { stroke-dasharray: 5 5; }
/* おてほんの型の ためし(heya.md 3.7 の注。#1809)= **点線の縁**(もう一度で入る)。面・明るさは替えない・焦点の輪(outline)とは別の線 */
.sh-item[data-try="1"] .ink::after {
  content: '';
  position: absolute;
  inset: 0;                       /* 縁の上に引く(内へ入れると低い横で型の名前の字を横切る) */
  border: 3px dashed var(--deep);
  border-radius: inherit;
  pointer-events: none;
}

/* ---- 棚のビュー(#780)。スタジオの塊は絶対配置だが、棚は**前の流し込みのまま**
   (ひとこと帯 → 棚)。`position` は `.screen` の `fixed; inset: 0` のまま触らない */
#app.show[data-view="shelf"] {
  display: flex;
  flex-direction: column;
  gap: var(--gap, 8px);
  padding: 0 var(--side, 12px) var(--bottom, 12px);
}
#app[data-view="shelf"] .say {
  position: static;
  flex: 0 0 auto;
  width: auto;
  min-height: 0;
  height: var(--bar-h, 48px);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(13px, 3.8vw, 17px);
  line-height: 1.2;
  background: none;
  overflow: hidden;
}

/* ---------------------------------------------------------------- 木目

   **模様は1つだけ持ち、操作と関係の無い面にだけ敷く**(mitame.md 4.3):
   はじまりの画面(`#boot`)と 見出し帯(`.head`)の2か所。

   - **押せる面(`.pad` / `.tile` / `.cell` / `.chip` / `.dbtn`)に敷かない** ——
     絵と喧嘩して的の読みが落ちるうえ、「同色同径の丸」を見る契約テストの走査に混ざる
   - **地(`body` / `#app`)にも敷かない** —— 実画素で色を測る検査の下に模様が来る
   - **指に透明・読み上げに出さない**(`pointer-events: none` / `aria-hidden`)
   - 弧は互いに平行にせず、間隔も等しくしない(y = 8 / 19 / 33 → 間隔 11 と 14)。
     **両端は viewBox の外へ出し、枠で切り落とす**(端で切れているほうが板らしい)
   - `svg * { vector-effect: non-scaling-stroke }` が効くので、**伸ばしても 1.5px のまま** */

.grain {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.grain path {
  fill: none;
  stroke: currentColor;
  stroke-opacity: 0.16;
  stroke-width: 1.5;
}

/* はじまりの画面は**墨**で、いちばん薄く(第一印象を決める面 ← mitame.md 4.3 の表) */
#boot .grain { color: var(--ink); --cc-rgb: var(--ink-rgb); }
#boot .grain path { stroke-opacity: 0.10; }

/* ------------------------------------------------------------------ 棚

   #780(shelf-share.md)。**棚は3枚目の `.screen` ではなく `#app` の中のビュー**:
   ひとこと帯(`aria-live`)を2つ作らない / スタジオの DOM を捨てない
   (捨てると `pointerup` が届かなくなった指の記録が残り、戻ってきたときに
   その的が二度と発火しない ← coding/lifecycle.md)/ 寸法の持ち主が1つで済む。

   **出ていないほうは `display: none`**(`visibility: hidden` にしない ——
   焦点の順路からも `elementFromPoint` からも消えるのは `display: none` だけ)。

   **詳細度の罠**(shelf-share.md 3.1): 横向きの規則は
   `:root[data-orient="land"] #app`(**1,2,0**)なので、`#app[data-view="shelf"]`(1,1,0)では
   上書きできない。棚のビューで「パッドのぶん空けてある右の余白」を戻すには
   **`:root[data-orient="land"] #app[data-view="shelf"]`(1,3,0)と書く**。 */

#app[data-view="studio"] .shelf { display: none; }
#app[data-view="shelf"] .main { display: none; }

/* 縦: [もどる | いまの つつ] / 棚 8 枠 / [たなに おく | わたす]。
   **棚は縦にも横にも送らない**(8 枠が必ず全部見える ← NN/g「子供はスクロールに気づかない」) */
.shelf {
  position: relative;                 /* 長押しの帯(`.sarc`)とアドレスの帯の基準。
                                         **`.screen` ではない**ので `fixed; inset: 0` を奪わない */
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  display: grid;
  grid-template-rows: var(--act, 56px) 1fr var(--act, 56px);
  gap: var(--gap, 8px);
  /* つつの中身の線(胴と軸は `--art-w`)。`vector-effect: non-scaling-stroke` なので
     **拡縮しても太さは画面 px のまま** ← shelf-share.md 3.7 */
  --tube-w: 1.5;
}

.sact, .sfoot {
  display: flex;
  gap: var(--gap, 8px);
  min-width: 0;
  min-height: 0;
}

/* 縦: もどる は `act` 角の正方・見出し帯が残りを取る / おく と わたす は半分ずつ */
.sact > .sbtn { flex: 0 0 var(--act, 56px); }
.shead { flex: 1 1 auto; }
.sfoot > .sbtn { flex: 1 1 0; }

/* **`.face` / `.tile` と同じ語彙**(丸み・影・面・縁)。**`box-shadow` は1か所**
   (状態の規則が書き直すと外側の影が黙って消える ← mitame.md 5.3) */
.sbtn {
  position: relative;
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  --edge-w: 2px;
  --edge-c: color-mix(in srgb, currentColor 40%, var(--bg));
  --lift-cur: var(--lift);
  border-radius: var(--bevel);
  background-color: color-mix(in srgb, currentColor 10%, var(--bg));
  box-shadow: var(--lift-cur), inset 0 0 0 var(--edge-w) var(--edge-c);
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .sbtn { --edge-c: rgba(var(--cc-rgb), .4); background-color: rgba(var(--cc-rgb), .1); } }

/* 的の判定も同じ文法(格子・帯に死んだ帯を作らない) */
.sbtn::before {
  content: '';
  position: absolute;
  inset: calc(var(--gap, 8px) / -2);
}

.sbtn > svg {
  width: 56%;
  height: 56%;
  fill: none;
  stroke: var(--art-ink);
  stroke-width: var(--art-w);
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* おくる の絵は横長(viewBox 100 x 50 ← shelf.js `SHARE_VB`)= 幅を広く取る */
.sbtn[data-act="share"] > svg { width: 76%; }

/* 押した手ごたえは**中の絵だけ**(箱は 1px も動かない = 当たり判定が縮まない) */
.sbtn[data-press] > svg { transform: scale(0.94); }

/* 棚の格子。**段(`role="row"`)は `display: contents`** なので、
   ARIA の構造(grid / row / gridcell)と CSS の格子1枚が両立する。
   **送らない**(`overflow: hidden` は「はみ出したら気づく」ための保険で、
   `solveShelf` が 8 枠を必ず収める)。
   **`align-self` / `justify-self` を `center` にして、格子の実寸(`--slot-w/h` から
   計算した大きさ)より箱を大きくしない**(既定は `stretch`)——
   `--slot-h` が `SLOT_MAX_H` で頭打ちになる画面(375x812 等)では、`.shelf` の
   `1fr` 行のほうが格子より大きいので、`stretch` のままだと `.rack` の箱だけが
   広がり、`align-content: center` がその余りを**格子の外側**(上下)へ逃がす ——
   `.rack` の中にどの `.slot` も無い帯ができて S9 が落ちる */
.rack {
  display: grid;
  grid-template-columns: repeat(var(--rack-cols, 2), var(--slot-w, 76px));
  grid-auto-rows: var(--slot-h, 76px);
  gap: var(--gap, 8px);
  justify-content: center;
  align-content: center;
  align-self: center;
  justify-self: center;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

/* 段(`role="row"`)は箱を持たない —— 格子1枚に 8 枠を並べるため。
   **`.srow`(外した譜面の行)と綴りが近いので、譜面の CSS を消すときに巻き込まない**
   (2026-09-22 に1度消して、棚の 8 枠が 2 段に潰れた ← lessons.md 13) */
.srow-rack { display: contents; }

.slot {
  position: relative;
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  --edge-w: 2px;
  --edge-c: color-mix(in srgb, currentColor 45%, var(--bg));
  --lift-cur: var(--lift);
  border-radius: var(--bevel);
  background-color: color-mix(in srgb, currentColor 10%, var(--bg));
  box-shadow: var(--lift-cur), inset 0 0 0 var(--edge-w) var(--edge-c);
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .slot { --edge-c: rgba(var(--cc-rgb), .45); background-color: rgba(var(--cc-rgb), .1); } }

/* 枠の当たり判定も**半分割り**(pads.md 3.4 と同じ。格子に死んだ帯を作らない ← S9)。
   **`.rack` には `#pads` のような外周の余白(`--side`)が無い**ので、外周の辺を
   `#pads` と同じに `-gap/2` へ広げると `.rack` 自身の箱の外へ出る ——
   `overflow: hidden` の下で `scrollWidth/Height` が `clientWidth/Height` を超える
   (S7)。外周の辺だけ `shelf.js` が付ける `data-edge` で 0 へ止める ← coding/layout.md */
.slot::before {
  content: '';
  position: absolute;
  top: calc(var(--gap, 8px) / -2);
  right: calc(var(--gap, 8px) / -2);
  bottom: calc(var(--gap, 8px) / -2);
  left: calc(var(--gap, 8px) / -2);
}
.slot[data-edge~="top"]::before { top: 0; }
.slot[data-edge~="right"]::before { right: 0; }
.slot[data-edge~="bottom"]::before { bottom: 0; }
.slot[data-edge~="left"]::before { left: 0; }

/* **いま のっている**(作業台の曲と符号が一致)= 縁 3px。
   パッドのペン列・チップの `data-edit` と**同じ語彙**(画面をまたいで揺らさない)。
   **「はずした」枠には使わない** —— あれは「押すと戻る」であって「いま書くところ」ではない */
.slot[data-kind="now"] { --edge-w: 3px; --edge-c: currentColor; }

/* つつの絵。**箱いっぱいに伸ばさない**(viewBox の `preserveAspectRatio` が中で寄せる) */
.tube {
  display: block;
  width: 86%;
  height: 64%;
  pointer-events: none;
}

.tube svg { width: 100%; height: 100%; }

/* 胴と軸は**機構の絵**(傾けない・歪ませない ← mitame.md 4.2 の機構の表) */
.tbody, .taxis, .tboard {
  fill: none;
  stroke: var(--art-ink);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tbody, .taxis { stroke-width: var(--art-w); }
/* から の枠は**棚板の線1本**(破線の輪郭にしない ← `stroke-dasharray` を増やさない) */
.tboard { stroke-width: var(--tube-w, 1.5); }

/* 小節の罫。**6px より密になったら `shelf.js` が引かない**(等間隔の点の列に見せない) */
.trule {
  fill: none;
  stroke: currentColor;
  stroke-opacity: 0.2;
  stroke-width: 1;
}

/* 中身は**行の色**(`.tin` が `data-row` を持つので `--ink` がその行に差し替わる) */
.tin path {
  fill: none;
  stroke: var(--art-ink);
  stroke-width: var(--tube-w, 1.5);
  stroke-linecap: round;
}

/* **はずした(もどせる)**= 墨1色・薄く(3.8)。行の色を落として「いまは棚に無い」を言う */
.slot[data-kind="back"] .tin { color: var(--deep); --cc-rgb: var(--deep-rgb); }
.slot[data-kind="back"] .tube svg * { stroke-opacity: 0.35; }
/* はじめての棚の おてほん(shelf-share.md 3.9。#1834)= おてほんの曲の つつ + 右下の小さな ▶ / ■(きく と同じ絵)。
   押せない飾り・読み上げない。枠の見た目は つつ と同じ(縁・面・影は替えない) */
.slot .sbadge {
  position: absolute;
  right: 8%;
  bottom: 8%;
  width: 18px;
  height: 18px;
  pointer-events: none;
}
.slot .sbadge svg { width: 100%; height: 100%; fill: var(--art-ink); stroke: var(--art-ink); stroke-width: 4; stroke-linejoin: round; }

/* 見出し帯(いま作業台に載っている つつ)。**押せない面**なので縁も影も持たない
   (押せる物と押せない物を画面をまたいで同じ見た目で分ける ← Norman / mitame.md 5.2)。
   `.head` の面 18% と木目3本は既存の規則がそのまま当たる */
.shead { position: relative; }
.shead .tube { width: 78%; height: 58%; }

/* 応え。**`transform` だけ**(明るさ・不透明度を1つも振らない ← UX原則3)。
   **`animation` は後勝ち**なので、育つ → 落ちる → ゆれる の順に書く */
.slot[data-press] .tube { transform: scale(0.94); }
.slot[data-grow] .tube { animation: tube-grow 260ms ease-out; }
.slot[data-fall] .tube { animation: leaf-fall 600ms ease-in; }
/* いっぱい: **8 枠が1回ゆれる**。印は1秒残るが、ゆれるのは最初の 460ms だけ */
.slot[data-shake] .tube { animation: shelf-shake 460ms ease-in-out; }

@keyframes tube-grow {
  0% { transform: scale(0.2); }
  70% { transform: scale(1.06); }
  100% { transform: scale(1); }
}

@keyframes shelf-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4%); }
  50% { transform: translateX(4%); }
  80% { transform: translateX(-2%); }
}

/* アドレスの帯(わたす の3段目)。**`<input readonly>` を作らない** ——
   この製品は「入力フォームが存在しない」契約を持つ(`contenteditable` も作らない)。
   `<div>` に文字を置いて `Range` で全選択し、**長押しで端末のコピーができる**形にする */
.urlbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: none;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  background-color: color-mix(in srgb, currentColor 10%, var(--bg));
  box-shadow: var(--lift-sm), inset 0 0 0 2px color-mix(in srgb, currentColor 45%, var(--bg));
  font-size: 13px;
  line-height: 1.3;
  word-break: break-all;
  max-height: 40%;
  overflow: auto;
  user-select: text;
  -webkit-user-select: text;
  touch-action: auto;                 /* 長押しで端末のコピーが出せるように */
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .urlbar { background-color: rgba(var(--cc-rgb), .1); box-shadow: var(--lift-sm), inset 0 0 0 2px rgba(var(--cc-rgb), .45); } }

.urlbar[data-on] { display: block; }

/* -------------------------------------------------- 棚(横・低い横)

   横は左の列(`--sact` = デッキ列と同じ 96px)に操作を縦に積み、棚は右に 4 列 x 2 段。
   **画面をまたいで同じ場所に同じ役**(スタジオで左の列だったものが、棚でも左の列)。

   **`:root[data-orient=…] #app[data-view="shelf"]`(1,3,0)と書くこと** ——
   `:root[data-orient="land"] #app`(1,2,0)の余白(パッドのぶん)を戻すため */

:root[data-orient="land"] #app[data-view="shelf"],
:root[data-orient="low"] #app[data-view="shelf"] {
  padding: 0 var(--side, 12px) var(--bottom, 12px);
}

:root[data-orient="land"] #app[data-view="shelf"] .shelf,
:root[data-orient="low"] #app[data-view="shelf"] .shelf {
  grid-template-columns: var(--sact, 96px) 1fr;
  grid-template-rows: calc(var(--act, 56px) * 2 + var(--gap, 8px)) 1fr;
}

:root[data-orient="land"] #app[data-view="shelf"] .sact,
:root[data-orient="low"] #app[data-view="shelf"] .sact {
  grid-area: 1 / 1;
  flex-direction: column;
}

:root[data-orient="land"] #app[data-view="shelf"] .sfoot,
:root[data-orient="low"] #app[data-view="shelf"] .sfoot {
  grid-area: 2 / 1;
  flex-direction: column;
}

:root[data-orient="land"] #app[data-view="shelf"] .rack,
:root[data-orient="low"] #app[data-view="shelf"] .rack {
  grid-area: 1 / 2 / 3 / 3;
}

:root[data-orient="land"] #app[data-view="shelf"] .sact > .sbtn,
:root[data-orient="low"] #app[data-view="shelf"] .sact > .sbtn,
:root[data-orient="land"] #app[data-view="shelf"] .shead {
  flex: 1 1 0;
}

/* **低い横では見出し帯を畳む**(畳むのは表示だけで、的は1つも減らない ← 3.4)。
   畳まないと 4 つで割った短辺が 48.5 まで落ちる */
:root[data-orient="low"] #app[data-view="shelf"] .shead { display: none; }

:root[data-orient="low"] #app[data-view="shelf"] .shelf {
  grid-template-rows: var(--act, 48px) 1fr;
}

/* ---------------------------------------------------------------- ことば(#772)

   「ことば」ボタンは**棚の `.sfoot` の3つ目**(持ち主は `js/core/lang-button.js` 1か所)。
   ボタン自身は `.sbtn` の語彙(丸み・影・面・縁・押したら中の絵だけ縮む)をそのまま使うので、
   ここで足すのは**一覧(幕)**だけである。

   - **開いているあいだだけ DOM に在る**(`lang-button.js` が作って捨てる)——
     置きっぱなしにすると「画面に文字が出ていない」を見る契約テストの走査に
     14言語ぶんの名前が常時載る
   - **幕は `#app` の子**(`.sfoot` に入れると帯の高さで切り落とされる)。
     `#app` は `.screen` = `position: fixed` なので、`absolute; inset: 0` で画面いっぱいになる
   - **国旗を使わない・名前はその言語自身の表記**(`i18n.js` の `LANG_NAMES`)
   - **選択中の印は色だけでなく形(チェック)でも示す**
   - **`align-items: safe center`** —— 言語が増えて一覧が画面より高くなった日に、
     中央ぞろえだと**上端が画面の外へ出て届かなくなる**(`safe` は端へ寄せる) */

.lang-menu {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: safe center;
  justify-content: center;
  padding: var(--gap, 8px);
  overflow-y: auto;
  color: var(--deep);                 /* 行の色を着せない(システムの面。← mitame.md 3.5 と同じ線) */
  --cc-rgb: var(--deep-rgb);
  background-color: color-mix(in srgb, var(--deep) 45%, transparent);
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .lang-menu { background-color: rgba(var(--deep-rgb), .45); } }

.lang-list {
  flex: 0 0 auto;
  width: min(100%, 336px);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap, 8px);
  /* **内余白は隙間の半分。** 札の `::before` が `--gap / 2` ずつ外へ出るので、
     ここを `--gap` にすると**内余白の外半分が死んだ帯になる**(下の `::before` と対) */
  padding: calc(var(--gap, 8px) / 2);
  border-radius: var(--bevel);
  background-color: var(--bg);
  box-shadow: var(--lift-on);
  animation: menu-grow 180ms ease-out;
}

/* **閉じるボタンは言語カードと同じ大きさ**(逃げ道を小さくしない)。
   `.sbtn` と同じ `box-shadow` 1か所の形(状態の規則が影を黙って消さない ← mitame.md 5.3) */
.lang-item,
.lang-close {
  position: relative;
  min-width: 0;
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px 8px;
  --edge-w: 2px;
  --edge-c: color-mix(in srgb, currentColor 40%, var(--bg));
  border-radius: var(--bevel);
  background-color: color-mix(in srgb, currentColor 8%, var(--bg));
  box-shadow: var(--lift), inset 0 0 0 var(--edge-w) var(--edge-c);
  font-size: 15px;
  line-height: 1.2;
  text-align: center;
  /* **分割できない長い1語**(`Português` 等)が列を押し広げて格子ごと画面の外へ出ないように
     ← coding/i18n-impl.md。`minmax(0, 1fr)` と**対で**入れる */
  overflow-wrap: anywhere;
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .lang-item, .lang-close { --edge-c: rgba(var(--cc-rgb), .4); background-color: rgba(var(--cc-rgb), .08); } }

/* **指の判定を隙間の半分ずつ広げる**(`.sbtn::before` / `.slot::before` と同じ語彙)。
   入れないと、札のあいだの隙間(`--gap`)と盤の内余白が**選びも閉じもしない死んだ帯**になる
   —— #772 のデザイナーレビューの実測で **375x812 の 21.3% / 736x260 の 19.0%**。
   `.lang-list` の内余白を `--gap / 2` にしてあるので、**隙間はちょうど半分ずつに割れ、
   盤の内余白は端の札が丸ごと引き受ける**(重なりも、覆われない輪も残らない)。
   **見えない要素なので色も影も持たない** ← coding/layout.md */
.lang-item::before,
.lang-close::before {
  content: '';
  position: absolute;
  inset: calc(var(--gap, 8px) / -2);
}

/* 選んでいる印は**縁の太さ**(色だけで意味を運ばない)+ チェック */
.lang-item.on { --edge-w: 3px; --edge-c: currentColor; }

/* **枠は常に取る**(選ぶと札の幅が変わって格子が跳ねるのを防ぐ) */
.lang-check {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--art-w, 2.5);
  stroke-linecap: round;
  stroke-linejoin: round;
  visibility: hidden;
}

.lang-item.on .lang-check { visibility: visible; }

.lang-close {
  grid-column: 1 / -1;
}

.lang-close > svg {
  width: 26px;
  height: 26px;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--art-w, 2.5);
  stroke-linecap: round;
}

/* **低い画面は 4 列に組み替える**(#772 の実測で入れた)。
   2 列のままだと 8 枚 + とじる = 5 段 = 316px で、**736x260 では
   とじるが画面の外 56px**(8言語とも。beat-kouba が #666 で踏んだのと同じ形)。
   送れば届くが、**「送らずに枠の中」で見張る**のがこの製品の線なので列で直す。
   4 列にすると 8 枚 = 2 段 + とじる = 3 段。**札を 48px に詰める**のは
   段が 3 つ要るためで、`.sbtn` の低い横(47〜49px)と同じ帯に収まる。
   字と印も一緒に詰めないと、480x280 で `Português` が語の途中で折れる
   (列の幅 106px に対して字だけで 72.7px 要る) */
@media (max-height: 460px) {
  .lang-list {
    width: min(100%, 560px);
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .lang-item,
  .lang-close {
    min-height: 48px;
    gap: 4px;
    padding: 4px 6px;
    font-size: 13px;
  }

  .lang-check { width: 14px; height: 14px; }

  .lang-close > svg { width: 22px; height: 22px; }

  /* **14 言語(2026-10-02)では とじるを最後の段の空きへ入れる。** 14 枚 = 4 列で 4 段(最後の段は 2 枚)。
     とじるに1段を丸ごと渡すと 5 段 = 292px になり、**736x260 で とじるが画面の外**へ出る。
     残り 2 列ぶんを持たせれば 4 段 = 240px で収まり、札より大きいまま(閉じる ≧ 札の約束) */
  .lang-close { grid-column: span 2; }
}

/* **14 言語(2026-10-02)の縦の低い画面**(高さ 461〜540px。296x520 など)。
   2 列 x 7 段 + とじる = 8 段で、札 56px のままだと 528px 要り、**とじるが画面の外**へ出る。
   札だけを 50px に詰める(字・印の大きさは変えない。下限 44px の上) */
@media (min-height: 461px) and (max-height: 540px) {
  .lang-item,
  .lang-close { min-height: 50px; }
}

/* ------------------------------------------------------------------------
   **動きをへらす設定。このファイルのいちばん下の塊**(後勝ちなので下に足さない)。

   止めるのは「補間」だけ。**結果は残す** ——
   - 押した手ごたえ(`.ink` の縮み)は遷移を持たないので、そのまま即座に出る
   - 一覧の板は せり上がるのをやめるだけ(在って押せる ← M26 と同じ線)
   - 8 小節目の終わりの合図(きく の ゆれ)は**合図そのもの**なので消さない                */

@media (prefers-reduced-motion: reduce) {
  /* ことばの一覧も育つのをやめるだけ(在って押せる ← M26 と同じ線。#772) */
  .lang-list { animation: none; }

  /* 一覧の板(heya.md 3.7)も せり上がらずに 在る */
  .sh-panel[data-rise] { animation: none; }

  /* 棚(#780。shelf-share.md 5.1)。**つつが育つ / 落ちるは遷移なしで即座に在る / 無い**
     (1回の変化なので情報は消えない)。**進みの帯は出す**(情報。上の行がそのまま効く) */
  .slot[data-grow] .tube,
  .slot[data-fall] .tube,
  .slot[data-shake] .tube { animation: none; }

  /* いっぱいの「ゆれ」は出さない。代わりに **8 枠の縁を 1 秒だけ 3px**(太さの語彙。
     **明るさを振らない**)。ひとことは変わらず出る */
  .slot[data-shake] { --edge-w: 3px; }

  /* 8 小節目の終わりの合図(roll.md 9章)は**合図そのもの**なので消さない(字の読めない子への
     唯一の絵の応え)。補間を捨てて**大きくなった姿のまま静止**させる ← coding/layout.md
     「止めた版も transform だけで書く」 */
  #play[data-nudge] .art { animation: play-nudge-still 420ms steps(1, end); }
  .fkeepb[data-bump] .art { animation: play-nudge-still 420ms steps(1, end); }
  .boot-ote[data-bump] .art { animation: play-nudge-still 420ms steps(1, end); }
  #undo[data-nudge] .art, #menubtn[data-nudge] .art, #shelfbtn[data-nudge] .art, .tab[data-nudge] .art { animation: play-nudge-still 420ms steps(1, end); }

  /* オルゴールの絵は回らない(絵は在る)/ はじめの ゆび は動かない(手は在る = 情報は残す)。
     飛ぶ音・めくりは roll.js が JS で出さない(`stillMotion`)ので、ここに行は要らない */
  .mbox .mroll, .mbox .mcrank { animation: none; }
  .mbox .mlid { transition: none; }   /* ふたは閉じた姿へすぐ替わる(閉じたことは残す) */
  .mhint { animation: none; }
  .boot-hint { animation: none; }
}
