@onjmin/dtm 2.1.12 → 2.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { PhonemeEntry, UtauTTSPlan } from '@onjmin/koe';
2
+
1
3
  /**
2
4
  * オーディオ設定とSoundFont管理
3
5
  * Audio Context初期化、SoundFont読み込み、ノート再生等
@@ -1398,6 +1400,106 @@ declare const resolveComposeKey: (choice?: string, rnd?: () => number) => Resolv
1398
1400
  */
1399
1401
  declare const getComposeKeyDescription: (choice: string) => string;
1400
1402
 
1403
+ /**
1404
+ * MusicXML の入出力。
1405
+ *
1406
+ * ## MIDI と何が違うか
1407
+ *
1408
+ * MIDI は「いつ・どの高さの音を鳴らすか」しか持たない。MusicXML は**楽譜**なので、
1409
+ * パートの名前・声部・歌詞・調号・拍子・音符の綴り(ファ♯かソ♭か)まで持つ。
1410
+ * このライブラリにとって効くのは主に2つ。
1411
+ *
1412
+ * - **主旋律がどれか分かる。** MIDI からの取り込みはチャンネルを見て推定するしか
1413
+ * なく、ハモリや対旋律を主旋律と取り違える(`scripts/calibrate-corpus.ts` の
1414
+ * 主旋律選択が長い注釈を必要としているのはそのため)。MusicXML はパートが
1415
+ * 明示されている。
1416
+ * - **歌詞が音符に紐づいている。** 歌声合成へそのまま渡せる。MIDI では歌詞と
1417
+ * 音符の対応が失われる。
1418
+ *
1419
+ * ## 音律について
1420
+ *
1421
+ * 31平均律({@link file://./tuning.ts})の音は MusicXML の `<alter>` に小数を書けば
1422
+ * 表現できる(仕様上は許されている)。ただし**読める相手は限られる**ので、
1423
+ * 書き出しでは12平均律へ丸めた整数を使い、微分音は捨てる。31平均律の曲を
1424
+ * 往復させたいときは MML を使うこと。
1425
+ *
1426
+ * ## 対応範囲
1427
+ *
1428
+ * 読み込みは `score-partwise`(一般的なほう)のみ。`score-timewise` は実物が
1429
+ * ほぼ流通していないので見ない。和音(`<chord>`)・タイ・声部・複数パートは扱う。
1430
+ * 繰り返し記号(`<repeat>`)は**展開しない**——展開すると小節番号がずれて、
1431
+ * 取り込んだ後の編集で位置を見失う。
1432
+ */
1433
+
1434
+ /** 取り込んだ1音。 */
1435
+ type MusicXmlNotePlacement = {
1436
+ /** 何番目のパートから来たか(0始まり)。 */
1437
+ partIndex: number;
1438
+ startStep: number;
1439
+ /** MIDIノート番号。 */
1440
+ pitch: number;
1441
+ durationSteps: number;
1442
+ /** 音符に紐づいた歌詞(`<lyric><text>`)。無ければ空。 */
1443
+ lyric: string;
1444
+ };
1445
+ type MusicXmlPart = {
1446
+ index: number;
1447
+ /** `<part-name>`。無ければ `Part 1` のような既定名。 */
1448
+ name: string;
1449
+ noteCount: number;
1450
+ /** このパートに歌詞が付いているか。歌トラックの候補を見分けるのに使う。 */
1451
+ hasLyrics: boolean;
1452
+ /** 平均音高(MIDIノート番号)。主旋律の目安。 */
1453
+ avgPitch: number;
1454
+ };
1455
+ type MusicXmlExtraction = {
1456
+ parts: MusicXmlPart[];
1457
+ placements: MusicXmlNotePlacement[];
1458
+ bpm: number;
1459
+ };
1460
+ /**
1461
+ * MusicXML を読んで、音符・パート情報・テンポを返す。
1462
+ *
1463
+ * @param xml `.musicxml` / `.xml` のテキスト。圧縮形式(`.mxl`)は呼び出し側で
1464
+ * 展開してから渡すこと(ZIP の展開をこのライブラリへ持ち込まない)。
1465
+ */
1466
+ declare const parseMusicXML: (xml: string) => MusicXmlExtraction;
1467
+ type ExportMusicXmlPart = {
1468
+ /** パート名。楽譜ソフトの左端に出る。 */
1469
+ name: string;
1470
+ notes: Note[];
1471
+ /** 音符に付ける歌詞。`notes` と同じ並び順で対応させる。短ければ足りないぶんは付かない。 */
1472
+ lyrics?: string[];
1473
+ };
1474
+ type ExportMusicXmlOptions = {
1475
+ parts: ExportMusicXmlPart[];
1476
+ bpm: number;
1477
+ stepsPerBar: number;
1478
+ /** 曲名。`<work-title>` に入る。 */
1479
+ title?: string;
1480
+ };
1481
+ /**
1482
+ * トラック群から MusicXML(`score-partwise`)を作る。
1483
+ *
1484
+ * **同時刻に始まる音は `<chord>` でまとめる。** ここを素直に並べて書くと、重なって
1485
+ * いた音が後ろへずれて**曲が変わる**(実測で 384/67 の音が 432 へ動いた)。
1486
+ * `<chord>` は声部の概念ではなく「直前の音と同時に鳴る」という意味なので、
1487
+ * 声部を持たないピアノロールでもそのまま使える。
1488
+ *
1489
+ * 声部は分けない。開始位置が違うまま重なる音(`<backup>` が要る形)は、
1490
+ * **次の音までで切る**——位置は保たれ、音価だけが短くなる。小節をまたぐ音を
1491
+ * 小節の終わりで切るのと同じ扱いで、鳴りの開始と高さは変えない。
1492
+ */
1493
+ declare const exportMusicXML: (options: ExportMusicXmlOptions) => string;
1494
+ /**
1495
+ * 取り込んだ音を、このライブラリのノート表現へ写す。
1496
+ *
1497
+ * `id` は付けない——採番はピアノロール側(`addNote`)の仕事で、ここで振ると
1498
+ * 既存のノートと衝突する。MIDI 取り込みが `MidiNotePlacement` を返して
1499
+ * 呼び出し側に置かせているのと同じ形。
1500
+ */
1501
+ declare const musicXmlToNotes: (placements: MusicXmlNotePlacement[], partIndex: number) => Omit<Note, "id">[];
1502
+
1401
1503
  /**
1402
1504
  * UST(UTAU Sequence Text)入出力ユーティリティ。
1403
1505
  *
@@ -1759,6 +1861,96 @@ type PitchSegment = {
1759
1861
  portamento: boolean;
1760
1862
  };
1761
1863
 
1864
+ /**
1865
+ * 語り(読み上げ)の前段 — テキストから UtauTTS の合成計画を作る。
1866
+ *
1867
+ * 歌詞の `「…」`({@link file://./lyrics.ts} の `kind: "speak"`)は、歌唱の
1868
+ * 「1文字=1ノート」とは別の経路で音になる:
1869
+ *
1870
+ * 本文 → jpreprocess(読み・アクセント・ポーズ)→ HTS 音声モデル(モーラ長・F0)
1871
+ * → UtauTTS プランナー(ユニット選択・配置・F0 曲線)→ worldline(合成)
1872
+ *
1873
+ * このファイルは最後の合成を除く**計画まで**を担う。計画は Wasm(Go)と
1874
+ * jpreprocess(Rust)をメインスレッドで動かす(koe のデモと同じ構成。合成と違い
1875
+ * 1文あたり数十 ms なので UI を塞がない)。合成そのものは音源 PCM と WORLD を持つ
1876
+ * バックエンド(voice-worker / ローカル)が計画を受け取って行う。
1877
+ *
1878
+ * 必要なアセット(約 45MB。Cache API に保存され 2 回目以降はネットワークを使わない):
1879
+ * - `utautts.wasm` + `wasm_exec.js` … UtauTTS プランナー(Go)
1880
+ * - `jpreprocess_wasm/` + `naist-jdic/*.gz` … OpenJTalk 互換の読み解析と辞書
1881
+ * - `frame-intonation-v8.json` … TCN イントネーションモデル(HTS 整列失敗時の保険)
1882
+ * - `hts/tohoku-f01-neutral.htsvoice` … HTS 音声モデル(音素長と F0 だけを移植する)
1883
+ */
1884
+
1885
+ /**
1886
+ * TTS アセットの既定の配信元(koe のデモと同じ配置)。`createDtmStudio` の
1887
+ * `ttsBaseUrl` / `createSingingVoices` の `ttsBaseUrl` で差し替えられる。
1888
+ */
1889
+ declare const DEFAULT_TTS_BASE_URL = "https://onjmin.github.io/koe/demo/utautts/";
1890
+ /** 読み上げの計画に必要な音源の見え方(マニフェストの音素表だけ。PCM は要らない)。 */
1891
+ type SpeechBank = {
1892
+ manifest: {
1893
+ phonemes: Record<string, PhonemeEntry>;
1894
+ };
1895
+ };
1896
+ type SpeechPlanOptions = {
1897
+ /** prefix.map 用の音名(多音階音源の収録セット名。省略時 "C4")。 */
1898
+ tone?: string;
1899
+ /** イントネーションの強さ 0..4(既定 1)。 */
1900
+ intonationStrength?: number;
1901
+ };
1902
+ type SpeechPlannerOptions = {
1903
+ /** アセットのベース URL(末尾 `/` は無くてもよい)。既定 {@link DEFAULT_TTS_BASE_URL}。 */
1904
+ baseUrl?: string;
1905
+ /** ダウンロード進捗(全アセット合算のバイト数)。 */
1906
+ onProgress?: (loadedBytes: number, totalBytes: number) => void;
1907
+ };
1908
+ type SpeechPlanner = {
1909
+ /** アセットをすべて読み込む(初回のみ実際にダウンロード。以降は即解決)。 */
1910
+ ready: () => Promise<void>;
1911
+ /** {@link ready} が完了しているか。 */
1912
+ isReady: () => boolean;
1913
+ /**
1914
+ * 本文の合成計画を作る。{@link ready} 完了後に呼ぶこと。
1915
+ * 読みが取れない本文(記号だけ等)は例外を投げる。
1916
+ */
1917
+ plan: (bank: SpeechBank, text: string, options?: SpeechPlanOptions) => UtauTTSPlan;
1918
+ };
1919
+ /**
1920
+ * 語りの計画器を取得する。Wasm(Go / jpreprocess)はページにつき 1 インスタンスなので、
1921
+ * ベース URL が違っても最初に作られたものを使い回す(警告を出す)。
1922
+ */
1923
+ declare const getSpeechPlanner: (options?: SpeechPlannerOptions) => SpeechPlanner;
1924
+ /**
1925
+ * 語りの計画器を作る(通常は {@link getSpeechPlanner} を使う)。
1926
+ * 読み込みは {@link SpeechPlanner.ready} を呼んだときに始まる(作っただけでは何も取りに行かない)。
1927
+ */
1928
+ declare const createSpeechPlanner: (options?: SpeechPlannerOptions) => SpeechPlanner;
1929
+ /**
1930
+ * 計画のピッチ曲線を比率で平行移動し、ユニットのエイリアスを実在の名前へ写した
1931
+ * 合成用の複製を返す(元の計画は変えない)。
1932
+ *
1933
+ * - `ratio` … ノートの音高 ÷ 計画の基準ピッチ(`timeline.reference_hz`)。
1934
+ * 1 で音源の素の声、2 で 1 オクターブ上。韻律の起伏は保たれる。
1935
+ * - `toReal` … 多音階音源の「音名接尾辞を剥がした見え方」で計画したエイリアスを、
1936
+ * 音源に実在する名前(`あ` → `あ_G4`)へ戻す。
1937
+ */
1938
+ declare const prepareSpeechPlan: (plan: UtauTTSPlan, ratio: number, toReal?: (alias: string) => string) => UtauTTSPlan;
1939
+ /**
1940
+ * 語りの先頭余白(秒)。タイムラインの 0 は最初のモーラより `leading_ms` だけ前
1941
+ * (先行発声ぶんの余白)にあるので、ノートの位置にはタイムラインのこの時刻を合わせる
1942
+ * (歌唱が母音オンセットを拍頭に合わせるのと同じ考え方)。
1943
+ */
1944
+ declare const speechPlanLeadingSec: (plan: UtauTTSPlan) => number;
1945
+ /**
1946
+ * 語りが実際に音を占める長さ(秒)。ノートの位置({@link speechPlanLeadingSec} 後)から
1947
+ * 最後のユニットの終わりまで。`timeline.duration_ms` は語尾のリリースや句点の間まで
1948
+ * 含む計画上の長さで、鳴る音より長いので帯には使わない。
1949
+ */
1950
+ declare const speechPlanDurationSec: (plan: UtauTTSPlan) => number;
1951
+ /** 音素表の収録ピッチ(Hz)の中央値。0(未検出)は無視する。無ければ undefined。 */
1952
+ declare const medianRecordedPitchHz: (phonemes: Record<string, PhonemeEntry>) => number | undefined;
1953
+
1762
1954
  /**
1763
1955
  * 自動ビブラート(ロングトーンに自動で掛けるピッチLFO)の定数と曲線生成。
1764
1956
  *
@@ -1825,6 +2017,15 @@ declare const FADE_OUT_MARK = "\u2193";
1825
2017
  * 歌いながら声量を上げていく。{@link FADE_OUT_MARK} と併用するとスウェルになる。
1826
2018
  */
1827
2019
  declare const FADE_IN_MARK = "\u2191";
2020
+ /**
2021
+ * 語り(読み上げ)の開き括弧。`「こんにちは」` のように囲んだ部分は歌わずに
2022
+ * UtauTTS で読み上げる。括弧ひとかたまりでノートを1つ消費し、そのノートの位置から
2023
+ * 話し始める。中身は漢字・数字・句読点を含んでよい(読みは jpreprocess が決める)。
2024
+ * 閉じ括弧が無ければ行末までを語りとみなす。
2025
+ */
2026
+ declare const SPEAK_OPEN = "\u300C";
2027
+ /** 語りの閉じ括弧({@link SPEAK_OPEN} の対)。対応する開き括弧が無ければ無視する。 */
2028
+ declare const SPEAK_CLOSE = "\u300D";
1828
2029
  /**
1829
2030
  * 歌詞文字列(かな+制御記号)を正規化済み音節列へ変換する。
1830
2031
  *
@@ -1838,6 +2039,9 @@ declare const FADE_IN_MARK = "\u2191";
1838
2039
  * - 促音(`っ`)は母音の文脈を切らない(語中の詰まりなので直前母音を保つ)。
1839
2040
  * - 休符(`_`)は歌わず、ブレス(`、`)ともども母音の文脈を切る。次の音節は語頭として歌われる。
1840
2041
  * - 引き継ぐ母音が無い継続(行頭・ブレス直後)は意味を持たないので捨てる。
2042
+ * - `「…」` は語り({@link SPEAK_OPEN})。ひとかたまりで `kind: "speak"` の1音節になり、
2043
+ * 中身は {@link LyricSyllable.text} に生のまま残る(かな以外も捨てない)。
2044
+ * 語りのあとは母音の文脈が切れる。
1841
2045
  */
1842
2046
  declare const normalizeLyrics: (text: string) => LyricSyllable[];
1843
2047
  /**
@@ -2006,6 +2210,35 @@ type VoiceModel = {
2006
2210
  durationSec?: number) => void;
2007
2211
  /** スケジュール済みの発音をすべて即停止する(停止・一時停止・シーク時)。 */
2008
2212
  stopAll?: () => void;
2213
+ /**
2214
+ * 語り(`「…」`)を合成してキャッシュへ積み、再生に使うキャッシュキーを返す。
2215
+ * 計画(読み・韻律・ユニット選択)が出来た時点で返り、合成はチャンクごとに裏で続く
2216
+ * ({@link scheduleSpeech} は届いたチャンクから順に置く)。`awaitRender` を立てると
2217
+ * 全チャンクの合成完了まで待つ(頭出しの貯金用)。
2218
+ * `pitch` は話す基準ピッチ(units)。計画不能(読みが取れない・アセット取得失敗)なら null。
2219
+ * koe 音源専用。klatt 等は未実装でよい(その場合は語りは鳴らない)。
2220
+ */
2221
+ speakToCache?: (text: string, pitch: number, expr?: VoiceExpression, awaitRender?: boolean) => Promise<string | null>;
2222
+ /**
2223
+ * {@link speakToCache} 済みの語りを絶対時刻 t0(AudioContext クロック秒)へスケジュールする。
2224
+ * まだ合成中のチャンクは届き次第、同じ t0 基準で置く。t0 を過ぎてから届いた分は
2225
+ * 途中から(遅れたぶんを飛ばして)鳴らし、後続との同期を保つ。
2226
+ */
2227
+ scheduleSpeech?: (key: string, t0: number, peak: number, pan: number, reverbSend?: number, delaySend?: number, destination?: AudioNode) => void;
2228
+ /** {@link speakToCache} 済みの語りが占める長さ(秒)。未計画なら undefined。 */
2229
+ speechDurationSec?: (key: string) => number | undefined;
2230
+ /**
2231
+ * 語りの計画だけを行い、占める長さ(秒)を返す(ピアノロールの帯表示用)。
2232
+ * 長さは基準ピッチに依らないので本文だけで引ける。アセット未取得なら取得から始める。
2233
+ */
2234
+ planSpeech?: (text: string) => Promise<number | null>;
2235
+ /** 計画済みの語りの長さ(秒)を同期で引く(描画ループ用。未計画なら undefined)。 */
2236
+ peekSpeechDurationSec?: (text: string) => number | undefined;
2237
+ /**
2238
+ * 語りの基準ピッチ(units)。この行にノートを置くと音源の素の声の高さで話す。
2239
+ * 音源の収録ピッチの中央値(多音階音源では収録セットの中央値)。
2240
+ */
2241
+ speechReferenceUnits?: () => number | undefined;
2009
2242
  };
2010
2243
  /**
2011
2244
  * klatt風フォルマント合成モデルを生成する。
@@ -2053,6 +2286,23 @@ type PitchToken = {
2053
2286
  * その場合は目標ノートに最も近いトークンを base に付与しないと解決できない。
2054
2287
  */
2055
2288
  declare const collectPitchTokens: (aliases: Iterable<string>) => PitchToken[];
2289
+ /**
2290
+ * 語り(UtauTTS)の計画に渡す「音源の見え方」。
2291
+ *
2292
+ * UtauTTS のユニット選択は prefix.map 前提で、音名接尾辞つきのエイリアス
2293
+ * (`- あ_G4`)を素の名前では引けない。多音階音源では**収録セットを1つ選び**、
2294
+ * その接尾辞を剥がした音素表を計画に見せ、出来た計画のエイリアスを {@link toReal} で
2295
+ * 実在の名前へ戻す。接尾辞の無いエイリアスはそのまま残す(接尾辞つきと重複したら
2296
+ * 接尾辞つき=選んだセットを優先)。単独音・連続音バンク(`token` null)は素通し。
2297
+ */
2298
+ type SpeechToneView = {
2299
+ view: SpeechBank;
2300
+ /** 計画上のエイリアス → 音源に実在するエイリアス。 */
2301
+ toReal: (alias: string) => string;
2302
+ /** この見え方での収録ピッチの中央値(Hz)。基準ピッチのガイドに使う。 */
2303
+ referenceHz: number | undefined;
2304
+ };
2305
+ declare const createSpeechToneView: (phonemes: Record<string, PhonemeEntry>, token: string | null) => SpeechToneView;
2056
2306
  /** koe音源の生成オプション */
2057
2307
  type KoeVoiceOptions = {
2058
2308
  /** .koe アーカイブのURL、または Blob/File */
@@ -2084,6 +2334,12 @@ type KoeVoiceOptions = {
2084
2334
  * ドライ経路とは別にこのノードへ送る。未指定ならディレイ送りは常にスキップされる。
2085
2335
  */
2086
2336
  delayBus?: AudioNode;
2337
+ /**
2338
+ * 語り(`「…」`)用の TTS アセットのベース URL({@link file://./speech.ts})。
2339
+ * 省略時は koe のデモと同じ GitHub Pages のホストを使う。アセットはページにつき
2340
+ * 一度だけ読み込まれ、最初の語りを合成するときに取得が始まる。
2341
+ */
2342
+ ttsBaseUrl?: string;
2087
2343
  };
2088
2344
  /**
2089
2345
  * @onjmin/koe の音源(UTAU由来 .koe)で1音節を歌う {@link VoiceModel} を生成する。
@@ -2303,6 +2559,19 @@ type SingingVoices = {
2303
2559
  * 常時ライブ反映できるようにする。
2304
2560
  */
2305
2561
  setVolume: (gain: number) => void;
2562
+ /**
2563
+ * 語り(`「…」`)の計画だけを行い、占める長さ(秒)を返す(ピアノロールの帯表示用)。
2564
+ * 音源が未ロードならロードし、TTS アセットが未取得なら取得から始める(初回は重い)。
2565
+ * klatt 等の語りに対応しないモデルや、計画できない本文では null。省略可能。
2566
+ */
2567
+ planSpeech?: (model: string, text: string) => Promise<number | null>;
2568
+ /** 計画済みの語りの長さ(秒)を同期で引く(描画ループ用。未計画なら undefined)。 */
2569
+ peekSpeechDurationSec?: (model: string, text: string) => number | undefined;
2570
+ /**
2571
+ * 語りの基準ピッチ(units)。この行にノートを置くと音源の素の声の高さで話す。
2572
+ * 音源がロード済みのときだけ返る(ロード前・klatt は undefined)。
2573
+ */
2574
+ getSpeechReferenceUnits?: (model: string) => number | undefined;
2306
2575
  };
2307
2576
  /** {@link SingingVoices.warm} の既定先合成数(各トラック先頭からの音数)。 */
2308
2577
  declare const PREWARM_NOTES = 3;
@@ -2339,6 +2608,11 @@ type SingingVoicesOptions = {
2339
2608
  * 未指定または戻り値が undefined のトラックは共有の `destination` へそのまま流れる。
2340
2609
  */
2341
2610
  getTrackDestination?: (trackId: string) => AudioNode | undefined;
2611
+ /**
2612
+ * 語り(`「…」`)用の TTS アセットのベース URL({@link createKoeVoice} に渡す)。
2613
+ * 省略時は koe のデモと同じ GitHub Pages のホスト({@link DEFAULT_TTS_BASE_URL})。
2614
+ */
2615
+ ttsBaseUrl?: string;
2342
2616
  };
2343
2617
  /**
2344
2618
  * klatt と koe音源を一括で扱う {@link SingingVoices} を生成する。
@@ -2621,15 +2895,25 @@ type PlayNoteEvent = {
2621
2895
  * - `"rest"` : 明示的な休符(`_`)。ノートを消費するが歌わない(そのノートは無音)。
2622
2896
  * 歌詞トラックは楽器音も鳴らさないので、`_` はそのまま「歌の休み」になる。
2623
2897
  * 直前母音の文脈もここで切れる(次の音節は語頭として扱われる)。
2898
+ * - `"speak"`: 語り(`「…」`)。括弧ひとかたまりでノートを1つ消費し、そのノートの
2899
+ * 位置から中身のテキストを読み上げる(UtauTTS)。長さは読み上げが決めるので
2900
+ * ノートの音価は使わない。音高は話す基準ピッチになる。中身は漢字混じりでよく、
2901
+ * 読みとアクセントは jpreprocess(OpenJTalk 互換)が決める。
2902
+ * 直前母音の文脈は切れる(次の音節は語頭として歌われる)。
2624
2903
  */
2625
- type LyricSyllableKind = "tie" | "stop" | "rest";
2904
+ type LyricSyllableKind = "tie" | "stop" | "rest" | "speak";
2626
2905
  type LyricSyllable = {
2627
2906
  /** 表示用かな("きょ" 等。長音は置換後の母音かな) */
2628
2907
  kana: string;
2629
2908
  /** ローマ字子音("k" "sh" 等。母音始まり・撥音は ""/"N"、促音は "Q") */
2630
2909
  consonant: string;
2631
- /** 母音 "a"|"i"|"u"|"e"|"o"、撥音 "N"、促音 "" */
2910
+ /** 母音 "a"|"i"|"u"|"e"|"o"、撥音 "N"、促音・語り "" */
2632
2911
  vowel: string;
2912
+ /**
2913
+ * `kind === "speak"` のとき、読み上げる本文(`「…」` の中身、漢字混じり可)。
2914
+ * 歌唱の音節では付かない。
2915
+ */
2916
+ text?: string;
2633
2917
  /**
2634
2918
  * 音節の種別。省略時は通常のかな音節。
2635
2919
  * 発音・表示・MMLへの書き戻しの分岐に使う({@link LyricSyllableKind})。
@@ -3069,6 +3353,8 @@ type DawInstance = {
3069
3353
  loadMML: (mml: string) => void;
3070
3354
  loadMIDI: (bytes: Uint8Array) => void | Promise<void>;
3071
3355
  exportMIDI: () => Blob;
3356
+ /** 全トラックをMusicXML(楽譜)テキストのBlobで返す。 */
3357
+ exportMusicXML: () => Blob;
3072
3358
  /** 選択中のトラック1本をUST(UTAU)テキストのBlobで返す。 */
3073
3359
  exportUST: () => Blob;
3074
3360
  setBpm: (bpm: number) => void;
@@ -3139,6 +3425,8 @@ type DawInstance = {
3139
3425
  * (上級者モード切替後の再ロード用。省略時は選択中のトラックから)。
3140
3426
  */
3141
3427
  applyUstParsed?: (ustTracks: UstTrackData[], startIndex?: number) => void;
3428
+ /** 解析済みMusicXMLの選択パートを適用する(上級者モード切替後の再ロード用)。 */
3429
+ applyMusicXmlParsed?: (xml: MusicXmlExtraction, selectedIndices: number[]) => void;
3142
3430
  /**
3143
3431
  * ガイドツアーを開始する(自動再生の設定に関わらず、いつでも呼べる)。
3144
3432
  * ヘルプボタンの「ガイドツアーを見る」と同じ入口。
@@ -3377,6 +3665,11 @@ type PlaySingingMmlOptions = PlayMmlOptions & {
3377
3665
  * 省略時はメインスレッド合成へフォールバック(BGM用途では worker 推奨)。
3378
3666
  */
3379
3667
  voiceWorkerUrl?: string;
3668
+ /**
3669
+ * 語り(歌詞の `「…」`)用の TTS アセットのベース URL。省略時は koe のデモと同じ
3670
+ * GitHub Pages のホスト。`singingVoices` を注入した場合は無視される。
3671
+ */
3672
+ ttsBaseUrl?: string;
3380
3673
  /**
3381
3674
  * 既存の歌唱合成ヘルパを注入する(createDtmStudio と同様の配線を流用したい場合)。
3382
3675
  * 指定時は voiceWorkerUrl より優先し、内部で createSingingVoices しない。
@@ -3544,10 +3837,11 @@ declare class LinkedList<T> {
3544
3837
  }
3545
3838
 
3546
3839
  /**
3547
- * マクロアコーディオン内で選択された設定値の localStorage 永続化
3840
+ * 自動作曲・一括編集アコーディオン内で選択された設定値の localStorage 永続化
3548
3841
  *
3549
- * 構成プリセット、作る部分(セクション)、ベース調、音階、全体シフト、移調の
3550
- * 選択状態を保持し、次回ロード時に復元できるようにする。
3842
+ * 構成プリセット、作る部分(セクション)、ベース調、音階(自動作曲パネル)と、
3843
+ * 全体シフト、移調(一括編集パネル)の選択状態を保持し、次回ロード時に復元できる
3844
+ * ようにする。キーの `dtm-macro:` 接頭辞は、両パネルが1枚だった頃の名残。
3551
3845
  */
3552
3846
  declare const MACRO_STORAGE_KEYS: {
3553
3847
  readonly template: "dtm-macro:template";
@@ -3560,12 +3854,12 @@ declare const MACRO_STORAGE_KEYS: {
3560
3854
  };
3561
3855
  type MacroStorageKey = keyof typeof MACRO_STORAGE_KEYS;
3562
3856
  /**
3563
- * マクロアコーディオンの単一項目を localStorage から取得する。
3857
+ * 単一項目を localStorage から取得する。
3564
3858
  * 未設定または localStorage にアクセスできない場合は null を返す。
3565
3859
  */
3566
3860
  declare const readMacroSetting: (key: MacroStorageKey) => string | null;
3567
3861
  /**
3568
- * マクロアコーディオンの単一項目を localStorage に保存する。
3862
+ * 単一項目を localStorage に保存する。
3569
3863
  * localStorage にアクセスできない環境や容量制限等は無視する。
3570
3864
  */
3571
3865
  declare const writeMacroSetting: (key: MacroStorageKey, value: string) => void;
@@ -3578,6 +3872,33 @@ declare const readMacroSections: () => string[] | null;
3578
3872
  * 作る部分(セクション選択)の配列を JSON 文字列として localStorage に保存する。
3579
3873
  */
3580
3874
  declare const writeMacroSections: (sections: string[]) => void;
3875
+ /**
3876
+ * 自動作曲の「キープ」に取っておいた曲。
3877
+ *
3878
+ * 中身は `generateMML` が出す MML そのもの(トラック・楽器・ドラム・テンポ・歌詞・
3879
+ * エフェクトまで全部入り)と、キープした時点の再生開始位置。再生位置も一緒に
3880
+ * 持つのは、キープした曲を呼び出したときに**同じ場所(サビの頭)から**聴き比べたい
3881
+ * ため——MML には曲の設計図(どこがサビか)が残らないので、位置だけ別に控える。
3882
+ */
3883
+ type KeptSong = {
3884
+ mml: string;
3885
+ /** キープした時点の再生開始位置(ステップ)。 */
3886
+ startStep: number;
3887
+ };
3888
+ /**
3889
+ * キープ枠を localStorage から読む。無い・壊れている・読めない場合は null。
3890
+ *
3891
+ * **リロードをまたいで残す**のは、スマホでは「別アプリを見て戻ったらタブが
3892
+ * 再読み込みされていた」が日常的に起きるため。メモリだけに持つと、取っておいた
3893
+ * つもりの曲がそこで消える。
3894
+ */
3895
+ declare const readKeptSong: () => KeptSong | null;
3896
+ /**
3897
+ * キープ枠を localStorage へ書く。null で枠を空にする。
3898
+ * 容量超過や private モードなど、書けない環境では黙って諦める
3899
+ * (その場合もメモリ上の枠は生きているので、リロードまでは使える)。
3900
+ */
3901
+ declare const writeKeptSong: (kept: KeptSong | null) => void;
3581
3902
 
3582
3903
  declare const PITCH_MAP: string[];
3583
3904
  /**
@@ -3943,6 +4264,17 @@ type MmlMeta = {
3943
4264
  * 省略時はオフ。
3944
4265
  */
3945
4266
  loop?: boolean;
4267
+ /**
4268
+ * 自動作曲の乱数種(`#seed=`)。同じ種・同じ設定({@link MmlMeta.compose})で
4269
+ * `composeSong` を呼ぶと**同じ曲が出る**。読み込み側は使わない——気に入った曲が
4270
+ * 貼られたとき、どの抽選から出たかを後から再現・分析するための記録。
4271
+ */
4272
+ seed?: number;
4273
+ /**
4274
+ * 自動作曲の設定(`#compose=`)。`テンプレート:調:音階:セクション` を `:` 区切りで
4275
+ * 持つ(セクションは `-` 区切り)。{@link MmlMeta.seed} と組で曲を再現する。
4276
+ */
4277
+ compose?: string;
3946
4278
  /**
3947
4279
  * 同時再生する伴奏音源のURL(mp3 / wav / YouTube)。`#audio=` で埋め込む。
3948
4280
  *
@@ -4111,106 +4443,6 @@ declare const decodeMml: (payload: string) => Promise<string>;
4111
4443
  */
4112
4444
  declare const mountMmlPlayer: (target: HTMLElement, mml: string, options?: MmlPlayerOptions) => MmlPlayerInstance;
4113
4445
 
4114
- /**
4115
- * MusicXML の入出力。
4116
- *
4117
- * ## MIDI と何が違うか
4118
- *
4119
- * MIDI は「いつ・どの高さの音を鳴らすか」しか持たない。MusicXML は**楽譜**なので、
4120
- * パートの名前・声部・歌詞・調号・拍子・音符の綴り(ファ♯かソ♭か)まで持つ。
4121
- * このライブラリにとって効くのは主に2つ。
4122
- *
4123
- * - **主旋律がどれか分かる。** MIDI からの取り込みはチャンネルを見て推定するしか
4124
- * なく、ハモリや対旋律を主旋律と取り違える(`scripts/calibrate-corpus.ts` の
4125
- * 主旋律選択が長い注釈を必要としているのはそのため)。MusicXML はパートが
4126
- * 明示されている。
4127
- * - **歌詞が音符に紐づいている。** 歌声合成へそのまま渡せる。MIDI では歌詞と
4128
- * 音符の対応が失われる。
4129
- *
4130
- * ## 音律について
4131
- *
4132
- * 31平均律({@link file://./tuning.ts})の音は MusicXML の `<alter>` に小数を書けば
4133
- * 表現できる(仕様上は許されている)。ただし**読める相手は限られる**ので、
4134
- * 書き出しでは12平均律へ丸めた整数を使い、微分音は捨てる。31平均律の曲を
4135
- * 往復させたいときは MML を使うこと。
4136
- *
4137
- * ## 対応範囲
4138
- *
4139
- * 読み込みは `score-partwise`(一般的なほう)のみ。`score-timewise` は実物が
4140
- * ほぼ流通していないので見ない。和音(`<chord>`)・タイ・声部・複数パートは扱う。
4141
- * 繰り返し記号(`<repeat>`)は**展開しない**——展開すると小節番号がずれて、
4142
- * 取り込んだ後の編集で位置を見失う。
4143
- */
4144
-
4145
- /** 取り込んだ1音。 */
4146
- type MusicXmlNotePlacement = {
4147
- /** 何番目のパートから来たか(0始まり)。 */
4148
- partIndex: number;
4149
- startStep: number;
4150
- /** MIDIノート番号。 */
4151
- pitch: number;
4152
- durationSteps: number;
4153
- /** 音符に紐づいた歌詞(`<lyric><text>`)。無ければ空。 */
4154
- lyric: string;
4155
- };
4156
- type MusicXmlPart = {
4157
- index: number;
4158
- /** `<part-name>`。無ければ `Part 1` のような既定名。 */
4159
- name: string;
4160
- noteCount: number;
4161
- /** このパートに歌詞が付いているか。歌トラックの候補を見分けるのに使う。 */
4162
- hasLyrics: boolean;
4163
- /** 平均音高(MIDIノート番号)。主旋律の目安。 */
4164
- avgPitch: number;
4165
- };
4166
- type MusicXmlExtraction = {
4167
- parts: MusicXmlPart[];
4168
- placements: MusicXmlNotePlacement[];
4169
- bpm: number;
4170
- };
4171
- /**
4172
- * MusicXML を読んで、音符・パート情報・テンポを返す。
4173
- *
4174
- * @param xml `.musicxml` / `.xml` のテキスト。圧縮形式(`.mxl`)は呼び出し側で
4175
- * 展開してから渡すこと(ZIP の展開をこのライブラリへ持ち込まない)。
4176
- */
4177
- declare const parseMusicXML: (xml: string) => MusicXmlExtraction;
4178
- type ExportMusicXmlPart = {
4179
- /** パート名。楽譜ソフトの左端に出る。 */
4180
- name: string;
4181
- notes: Note[];
4182
- /** 音符に付ける歌詞。`notes` と同じ並び順で対応させる。短ければ足りないぶんは付かない。 */
4183
- lyrics?: string[];
4184
- };
4185
- type ExportMusicXmlOptions = {
4186
- parts: ExportMusicXmlPart[];
4187
- bpm: number;
4188
- stepsPerBar: number;
4189
- /** 曲名。`<work-title>` に入る。 */
4190
- title?: string;
4191
- };
4192
- /**
4193
- * トラック群から MusicXML(`score-partwise`)を作る。
4194
- *
4195
- * **同時刻に始まる音は `<chord>` でまとめる。** ここを素直に並べて書くと、重なって
4196
- * いた音が後ろへずれて**曲が変わる**(実測で 384/67 の音が 432 へ動いた)。
4197
- * `<chord>` は声部の概念ではなく「直前の音と同時に鳴る」という意味なので、
4198
- * 声部を持たないピアノロールでもそのまま使える。
4199
- *
4200
- * 声部は分けない。開始位置が違うまま重なる音(`<backup>` が要る形)は、
4201
- * **次の音までで切る**——位置は保たれ、音価だけが短くなる。小節をまたぐ音を
4202
- * 小節の終わりで切るのと同じ扱いで、鳴りの開始と高さは変えない。
4203
- */
4204
- declare const exportMusicXML: (options: ExportMusicXmlOptions) => string;
4205
- /**
4206
- * 取り込んだ音を、このライブラリのノート表現へ写す。
4207
- *
4208
- * `id` は付けない——採番はピアノロール側(`addNote`)の仕事で、ここで振ると
4209
- * 既存のノートと衝突する。MIDI 取り込みが `MidiNotePlacement` を返して
4210
- * 呼び出し側に置かせているのと同じ形。
4211
- */
4212
- declare const musicXmlToNotes: (placements: MusicXmlNotePlacement[], partIndex: number) => Omit<Note, "id">[];
4213
-
4214
4446
  type PianoRollInstance = {
4215
4447
  core: MMLCore;
4216
4448
  getNotes: () => Note[];
@@ -4286,6 +4518,20 @@ type Renderer = {
4286
4518
  drawGrid: (noteLengthSteps?: number) => void;
4287
4519
  drawNotes: (notes: Note[], color?: number[], isActive?: boolean) => void;
4288
4520
  drawNoteLyrics: (notes: Note[], syllables: string[]) => void;
4521
+ /**
4522
+ * 語り(`「…」`)が実際に占める長さを、ノートの行に薄い帯で重ねる(プレビュー)。
4523
+ * 語りの長さは読み上げが決めるのでノートの音価とは一致しない。帯を見れば
4524
+ * 次の歌い出しと重なるかが分かる。
4525
+ */
4526
+ drawSpeechSpans: (spans: {
4527
+ note: Note;
4528
+ durationSteps: number;
4529
+ }[], color?: number[]) => void;
4530
+ /**
4531
+ * 語りの基準ピッチの行にガイドを引く。この行にノートを置くと音源の素の声の高さで話す。
4532
+ * ラベルは行の左端に出す。
4533
+ */
4534
+ drawPitchGuide: (pitchUnits: number, label: string) => void;
4289
4535
  drawSelectionRect: (rect: {
4290
4536
  x: number;
4291
4537
  y: number;
@@ -4504,6 +4750,13 @@ type DtmStudioOptions = {
4504
4750
  * を渡すと worker 内の importScripts も同オリジン経由になり CSP を通過できる。
4505
4751
  */
4506
4752
  worldlineScriptUrl?: string;
4753
+ /**
4754
+ * 語り(歌詞の `「…」`)用の TTS アセット(UtauTTS の Wasm・jpreprocess 辞書・
4755
+ * HTS 音声モデル、合計約 45MB)のベース URL。省略時は koe のデモと同じ
4756
+ * `https://onjmin.github.io/koe/demo/utautts/`。最初の語りを鳴らすときに取得し、
4757
+ * Cache API に保存する。CSP 制限下では同オリジンのプロキシを渡す。
4758
+ */
4759
+ ttsBaseUrl?: string;
4507
4760
  /** 有効化する機能。既定はすべて true。 */
4508
4761
  features?: {
4509
4762
  /** MIDIファイル読み込み。 */
@@ -4739,7 +4992,7 @@ declare const createDtmStudio: (options?: DtmStudioOptions) => Promise<DtmStudio
4739
4992
  * ドット絵・レトロゲーム風ピクセルアートデザイン(美咲フォント・角なし・ハードシャドウ)。
4740
4993
  * モバイルファースト(狭幅基準)で設計し、min-width メディアクエリで広幅に拡張する。
4741
4994
  */
4742
- declare const DAW_CSS = "\n@font-face {\n font-family: 'k8x12';\n src: url('https://db.onlinewebfonts.com/t/777630d46640dc5a928ea833c2fcb875.woff2') format('woff2'),\n url('https://db.onlinewebfonts.com/t/777630d46640dc5a928ea833c2fcb875.woff') format('woff'),\n url('https://db.onlinewebfonts.com/t/777630d46640dc5a928ea833c2fcb875.ttf') format('truetype');\n font-weight: normal;\n font-style: normal;\n}\n\n/* ====================================================\n PIXEL MUSIC STUDIO \u2014 \u30C9\u30C3\u30C8\u7D75UI\u30B7\u30B9\u30C6\u30E0\n PICO-8\u30AB\u30E9\u30FC\u30D1\u30EC\u30C3\u30C8\u30FB\u7F8E\u54B2\u30D5\u30A9\u30F3\u30C8\u30FB\u30B2\u30FC\u30E0\u30A6\u30A3\u30F3\u30C9\u30A6\u67A0\n ==================================================== */\n\n/* \u30C7\u30B6\u30A4\u30F3\u30C8\u30FC\u30AF\u30F3\u306F\u7DE8\u96C6UI\u672C\u4F53\uFF08.dtm-daw\uFF09\u306B\u52A0\u3048\u3001\u305D\u306E\u5916\u5074\u306B\u5DEE\u3057\u8FBC\u307E\u308C\u308B\n \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC\uFF08.dtm-controlbar\uFF09\u306B\u3082\u4F9B\u7D66\u3059\u308B\u3002mountPresetSelect /\n mountModeSwitch \u306EUI\u306F .dtm-daw \u306E\u5144\u5F1F\u3068\u3057\u3066\u7F6E\u304B\u308C\u308B\u305F\u3081\u3001\u3053\u3053\u3067\u914D\u3089\u306A\u3044\u3068\n var(--dtm-*) \u304C\u89E3\u6C7A\u3067\u304D\u305A\u7121\u88C5\u98FE\uFF08\u767D\u5730\u30FB\u65E2\u5B9A\u30D5\u30A9\u30F3\u30C8\uFF09\u306B\u306A\u3063\u3066\u3057\u307E\u3046\u3002\n \u518D\u751F\u5C02\u7528\u30D3\u30E5\u30FC\u306E\u30E2\u30FC\u30C0\u30EB\uFF0F\u5229\u7528\u898F\u7D04\u30AB\u30D0\u30FC\u3001\u6B4C\u58F0\u30E2\u30C7\u30EB\u540D\u306E\u5439\u304D\u51FA\u3057(.dtm-player-balloon)\n \u30AC\u30A4\u30C9\u30C4\u30A2\u30FC\u306E\u6697\u5E55(.dtm-tour)\u306F document.body \u76F4\u4E0B\u3078\u91CD\u306D\u308B\u305F\u3081\u3001.dtm-daw \u306E\u5916\u306B\u51FA\u308B\u3002\n \u3053\u308C\u3089\u3082\u540C\u69D8\u306B\u30C8\u30FC\u30AF\u30F3\u3092\u4F9B\u7D66\u3057\u306A\u3044\u3068\u7121\u88C5\u98FE\uFF08\u67A0\u7DDA\u306A\u3057\u30FB\u6587\u5B57\u8272\u4E0D\u660E\u306E\u767D\u3044\u7BB1\uFF09\u306B\u306A\u308B\u3002 */\n.dtm-daw,\n.dtm-controlbar,\n.dtm-modal-overlay,\n.dtm-consent-overlay,\n.dtm-chord-player,\n.dtm-player-balloon,\n.dtm-tour {\n /* PICO-8 16\u8272\u30D1\u30EC\u30C3\u30C8\u3088\u308A */\n --c-black: #000000;\n --c-navy: #1d2b53;\n --c-purple: #7e2553;\n --c-dkgreen: #008751;\n --c-brown: #ab5236;\n --c-dkgray: #5f574f;\n --c-gray: #c2c3c7;\n --c-white: #fff1e8;\n --c-red: #ff004d;\n --c-orange: #ffa300;\n --c-yellow: #ffec27;\n --c-green: #00e436;\n --c-cyan: #29adff;\n --c-lavend: #83769c;\n --c-pink: #ff77a8;\n --c-peach: #ffccaa;\n\n /* \u30BB\u30DE\u30F3\u30C6\u30A3\u30C3\u30AF\u30C8\u30FC\u30AF\u30F3 */\n --dtm-bg: var(--c-black);\n --dtm-surface: var(--c-navy);\n --dtm-deep: #0a0f1f;\n --dtm-border: var(--c-cyan);\n --dtm-border2: var(--c-dkgray);\n --dtm-text: var(--c-white);\n --dtm-muted: var(--c-lavend);\n --dtm-primary: var(--c-cyan);\n --dtm-pfg: var(--c-black);\n --dtm-danger: var(--c-red);\n --dtm-success: var(--c-green);\n --dtm-accent: var(--c-pink);\n --dtm-gold: var(--c-yellow);\n --dtm-warn: var(--c-orange);\n --dtm-tap: 40px;\n --dtm-gap: 6px;\n --dtm-font: 'k8x12',ui-monospace,monospace;\n}\n\n.dtm-daw {\n box-sizing: border-box;\n font-family: var(--dtm-font);\n font-size: 14px;\n line-height: 1.6;\n letter-spacing: .06em;\n color: var(--dtm-text);\n background: var(--dtm-bg);\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n padding: 0;\n image-rendering: pixelated;\n -webkit-font-smoothing: none;\n -moz-osx-font-smoothing: unset;\n font-smooth: never;\n -webkit-tap-highlight-color: transparent;\n}\n.dtm-daw *,\n.dtm-daw *::before,\n.dtm-daw *::after { box-sizing: border-box; }\n\n/* \u2500\u2500\u2500 \u30B2\u30FC\u30E0\u30A6\u30A3\u30F3\u30C9\u30A6\u5171\u901A\u67A0 \u2500\u2500\u2500 */\n/* \u5916\u67A0(\u9ED22px) \u2192 \u8272\u4ED8\u304D2px border \u2192 \u5185\u67A0(\u9ED2inset2px) \u306E3\u91CD\u69CB\u9020 */\n.dtm-win {\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n background: var(--dtm-surface);\n}\n\n/* \u2500\u2500\u2500 \u5171\u901A\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */\n.dtm-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n min-height: var(--dtm-tap);\n min-width: var(--dtm-tap);\n padding: 0 10px;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-surface);\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 13px;\n text-transform: uppercase;\n letter-spacing: .12em;\n cursor: pointer;\n user-select: none;\n white-space: nowrap;\n box-shadow: 3px 3px 0 var(--c-black);\n transition: none;\n}\n.dtm-btn:active { transform: translate(3px,3px); box-shadow: none; }\n.dtm-btn:disabled { opacity: .3; cursor: default; box-shadow: none; }\n.dtm-btn--ghost { background: transparent; border-color: var(--dtm-border2); }\n.dtm-btn--primary { border-color: var(--dtm-primary); background: var(--dtm-primary); color: var(--dtm-pfg); }\n.dtm-btn--success { border-color: var(--dtm-success); background: var(--dtm-success); color: var(--c-black); }\n.dtm-btn--danger { border-color: var(--dtm-danger); background: var(--dtm-danger); color: var(--c-white); }\n.dtm-btn--accent { border-color: var(--dtm-accent); background: var(--dtm-accent); color: var(--c-black); }\n.dtm-btn--icon { padding: 0; }\n\n/* \u2500\u2500\u2500 \u30A2\u30A4\u30B3\u30F3\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */\n.dtm-iconbtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--dtm-tap);\n height: var(--dtm-tap);\n flex: 0 0 auto;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-surface);\n color: var(--dtm-text);\n font-size: 16px;\n cursor: pointer;\n box-shadow: 3px 3px 0 var(--c-black);\n}\n.dtm-iconbtn:active { transform: translate(3px,3px); box-shadow: none; }\n.dtm-iconbtn:disabled { opacity: .3; cursor: default; box-shadow: none; }\n\n/* \u2500\u2500\u2500 \u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u30D0\u30FC\uFF08HUD\u30B9\u30BF\u30A4\u30EB\uFF09 \u2500\u2500\u2500 */\n.dtm-topbar {\n position: sticky;\n top: 0;\n z-index: 20;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--dtm-gap);\n padding: 6px;\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-success),\n 4px 4px 0 var(--c-black);\n}\n.dtm-topbar-row1 {\n display: flex;\n align-items: center;\n gap: var(--dtm-gap);\n flex-basis: 100%;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n.dtm-topbar-row1::-webkit-scrollbar { display: none; }\n.dtm-topbar-row1 > * { flex-shrink: 0; }\n.dtm-topbar-row1 > .dtm-grow { flex-shrink: 1; }\n\n/* PLAY\u30DC\u30BF\u30F3 \u2014 \u30B2\u30FC\u30E0\u306E\u300C\u6C7A\u5B9A\u30DC\u30BF\u30F3\u300D\u7684\u5B58\u5728\u611F */\n.dtm-play {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--dtm-tap);\n height: var(--dtm-tap);\n flex: 0 0 auto;\n border: 2px solid var(--c-black);\n background: var(--dtm-success);\n color: var(--c-black);\n cursor: pointer;\n box-shadow: 0 0 0 2px var(--dtm-success), 4px 4px 0 var(--c-black);\n}\n.dtm-play:active { transform: translate(4px,4px); box-shadow: none; }\n.dtm-play:disabled { opacity: .35; cursor: default; box-shadow: none; }\n.dtm-play--stop {\n background: var(--dtm-danger);\n box-shadow: 0 0 0 2px var(--dtm-danger), 4px 4px 0 var(--c-black);\n}\n.dtm-rec { color: var(--dtm-danger); }\n\n/* BPM \u2014 \u30C7\u30B8\u30BF\u30EB\u30AB\u30A6\u30F3\u30BF\u30FC\u98A8 */\n.dtm-label {\n font-family: var(--dtm-font);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .14em;\n color: var(--dtm-muted);\n white-space: nowrap;\n}\n.dtm-checkbox-label {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: var(--dtm-font);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .12em;\n color: var(--dtm-muted);\n cursor: pointer;\n user-select: none;\n margin-top: 4px;\n}\n.dtm-checkbox-label:hover { color: var(--dtm-text); }\n\n/* \u2500\u2500\u2500 \u4F5C\u66F2\u3059\u308B\u30BB\u30AF\u30B7\u30E7\u30F3\u306E\u9078\u629E\uFF08\u30A4\u30F3\u30C8\u30ED\u30FBA\u30E1\u30ED\u2026\u306E\u30C1\u30A7\u30C3\u30AF\uFF09 \u2500\u2500\u2500 */\n.dtm-checks {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 10px;\n align-items: center;\n}\n.dtm-check {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-family: var(--dtm-font);\n font-size: 11px;\n color: var(--dtm-muted);\n cursor: pointer;\n user-select: none;\n white-space: nowrap;\n}\n.dtm-check:hover { color: var(--dtm-text); }\n.dtm-check input {\n width: 13px;\n height: 13px;\n accent-color: var(--dtm-success);\n cursor: pointer;\n flex-shrink: 0;\n}\n.dtm-info-table {\n border-collapse: collapse;\n margin: 6px 0;\n font-size: 11px;\n width: 100%;\n}\n.dtm-info-table th,\n.dtm-info-table td {\n border: 1px solid var(--dtm-border);\n padding: 3px 6px;\n text-align: left;\n white-space: nowrap;\n}\n.dtm-info-table th { color: var(--dtm-muted); font-weight: normal; }\n.dtm-hint {\n font-family: var(--dtm-font);\n font-size: 10px;\n color: var(--dtm-muted);\n white-space: nowrap;\n}\n.dtm-checkbox-label--sub { margin-left: 20px; font-size: 10px; }\n.dtm-checkbox {\n width: 14px;\n height: 14px;\n accent-color: var(--dtm-success);\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.dtm-toggle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: var(--dtm-font);\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: .1em;\n color: var(--dtm-muted);\n cursor: pointer;\n}\n.dtm-toggle input { width: 16px; height: 16px; accent-color: var(--dtm-accent); }\n\n/* \u2500\u2500\u2500 \u30C4\u30FC\u30EB\u30C9\u30C3\u30AF\uFF08\u88C5\u5099\u30B9\u30ED\u30C3\u30C8\u98A8\uFF09 \u2500\u2500\u2500 */\n.dtm-tooldock {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--dtm-gap);\n padding: 6px;\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-border2),\n 4px 4px 0 var(--c-black);\n}\n.dtm-sep {\n width: 2px; align-self: stretch;\n background: var(--dtm-border2); margin: 2px;\n}\n.dtm-row .dtm-label[data-dtm] { min-width: 48px; text-align: center; }\n\n/* \u2500\u2500\u2500 \u30BB\u30B0\u30E1\u30F3\u30C8\uFF08\u30A2\u30A4\u30C6\u30E0\u30B9\u30ED\u30C3\u30C8\uFF09 \u2500\u2500\u2500 */\n.dtm-seg {\n display: inline-flex;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-deep);\n box-shadow: 3px 3px 0 var(--c-black);\n}\n.dtm-segbtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--dtm-tap);\n height: var(--dtm-tap);\n border: none;\n border-right: 2px solid var(--dtm-border2);\n background: transparent;\n color: var(--dtm-muted);\n cursor: pointer;\n}\n.dtm-segbtn:last-child { border-right: none; }\n.dtm-segbtn--active {\n background: var(--dtm-gold);\n color: var(--c-black);\n}\n.dtm-segbtn:not(.dtm-segbtn--active):active { background: var(--dtm-border2); }\n\n/* \u2500\u2500\u2500 \u30D5\u30A9\u30FC\u30E0\u8981\u7D20 \u2500\u2500\u2500 */\n.dtm-select, .dtm-input, .dtm-textarea {\n min-height: var(--dtm-tap);\n padding: 4px 8px;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-deep);\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 13px;\n letter-spacing: .06em;\n box-shadow: inset 2px 2px 0 var(--c-black);\n}\n.dtm-select:focus, .dtm-input:focus, .dtm-textarea:focus {\n outline: none;\n border-color: var(--dtm-primary);\n}\n.dtm-input--num { width: 64px; text-align: center; font-size: 16px; }\n/* \u4ED6\u306E\u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u3068\u540C\u3058\u884C\u306B\u7F6E\u304F\u30D7\u30EB\u30C0\u30A6\u30F3\uFF08\u697D\u5668\u30FB\u6B4C\u5531\u30E2\u30C7\u30EB\uFF09 */\n.dtm-select--half { flex: 1 1 120px; min-width: 0; max-width: 200px; }\n.dtm-textarea { width: 100%; min-height: 56px; resize: vertical; line-height: 1.7; }\n.dtm-textarea.dtm-grow { width: 0; }\n.dtm-range { height: var(--dtm-tap); accent-color: var(--dtm-primary); }\n.dtm-range:disabled { opacity: .35; cursor: default; }\n\n/* \u2500\u2500\u2500 \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC\uFF08\u697D\u5668\u30D7\u30EA\u30BB\u30C3\u30C8 / \u30E2\u30FC\u30C9\u5207\u66FF\u306A\u3069\u306E\u5DEE\u3057\u8FBC\u307FUI\uFF09 \u2500\u2500\u2500 */\n.dtm-controlbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--dtm-gap);\n padding: 6px 8px;\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-border2),\n 4px 4px 0 var(--c-black);\n margin-bottom: var(--dtm-gap);\n}\n.dtm-controlbar-label {\n font-family: var(--dtm-font);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .14em;\n color: var(--dtm-accent);\n white-space: nowrap;\n flex-shrink: 0;\n}\n.dtm-controlbar .dtm-select { flex: 1 1 160px; }\n\n/* \u30E2\u30FC\u30C9\u5207\u66FF\uFF08\u30C6\u30AD\u30B9\u30C8\u7248\u30BB\u30B0\u30E1\u30F3\u30C8\uFF09 */\n.dtm-modeseg {\n display: inline-flex;\n border: 2px solid var(--dtm-border2);\n box-shadow: 3px 3px 0 var(--c-black);\n}\n.dtm-modebtn {\n min-height: var(--dtm-tap);\n padding: 0 14px;\n border: none;\n border-right: 2px solid var(--dtm-border2);\n background: var(--dtm-deep);\n color: var(--dtm-muted);\n font-family: var(--dtm-font);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .12em;\n cursor: pointer;\n}\n.dtm-modebtn:last-child { border-right: none; }\n.dtm-modebtn--active { background: var(--dtm-primary); color: var(--dtm-pfg); }\n.dtm-modebtn:not(.dtm-modebtn--active):active { background: var(--dtm-border2); }\n\n/* \u2500\u2500\u2500 \u30C8\u30E9\u30C3\u30AF\u30D4\u30EB\uFF08\u756A\u53F7\u30DC\u30BF\u30F3\u3001\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u30D0\u30FC2\u884C\u76EE\uFF09 \u2500\u2500\u2500 */\n.dtm-tracks {\n flex-basis: 100%;\n display: flex;\n flex-wrap: nowrap;\n gap: 4px;\n align-items: flex-end;\n}\n.dtm-pill {\n --dtm-pill-color: var(--dtm-primary);\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 1 1 0;\n min-width: 0;\n height: 24px;\n padding: 0;\n border: 2px solid var(--c-black);\n background: color-mix(in srgb, var(--dtm-pill-color) 22%, #0e121e);\n color: color-mix(in srgb, var(--c-white) 60%, transparent);\n font-family: var(--dtm-font);\n font-size: 11px;\n font-weight: bold;\n cursor: pointer;\n box-shadow: 1px 1px 0 var(--c-black);\n opacity: 0.55;\n transition: opacity 120ms ease, background 120ms ease, transform 120ms ease;\n}\n.dtm-pill:hover:not(.dtm-pill--active) {\n opacity: 0.85;\n background: color-mix(in srgb, var(--dtm-pill-color) 45%, #0e121e);\n color: var(--c-white);\n}\n/* \u30A2\u30AF\u30C6\u30A3\u30D6\u9078\u629E = \u9BAE\u660E\u306A\u30C8\u30E9\u30C3\u30AF\u8272 + \u30B4\u30FC\u30EB\u30C9\u67A0 + \u30B0\u30ED\u30FC + \u4E0A\u6607\u7ACB\u4F53\u30BF\u30D6\u8868\u73FE */\n.dtm-pill--active {\n opacity: 1;\n height: 28px;\n background: var(--dtm-pill-color);\n color: #ffffff;\n text-shadow: 1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000;\n border-color: var(--dtm-gold);\n box-shadow:\n 0 0 0 1.5px var(--dtm-gold),\n 0 0 10px color-mix(in srgb, var(--dtm-pill-color) 70%, transparent),\n 2px 2px 0 var(--c-black);\n z-index: 1;\n transform: translateY(-2px);\n}\n.dtm-pill--active::before {\n content: '';\n position: absolute;\n top: -2px;\n left: 2px;\n right: 2px;\n height: 2px;\n background: #ffffff;\n border-radius: 1px;\n opacity: 0.85;\n}\n.dtm-pill:not(.dtm-pill--active):active { transform: translate(1px,1px); box-shadow: none; }\n/* \u30DC\u30FC\u30AB\u30EB\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u308B\u30C8\u30E9\u30C3\u30AF\u306E\u30BF\u30D6\u306B\u3001\u3046\u3063\u3059\u3089\u58F0\u306E\u30A2\u30A4\u30B3\u30F3\u3092\u91CD\u306D\u308B\uFF08\u80CC\u666F\u8272\u30FB\u30B5\u30A4\u30BA\u306F\u5909\u3048\u306A\u3044\uFF09 */\n.dtm-pill--vocal::after {\n content: '';\n position: absolute;\n inset: 0;\n background-image: var(--dtm-pill-icon);\n background-size: contain;\n background-repeat: no-repeat;\n background-position: right center;\n opacity: 0.4;\n pointer-events: none;\n}\n.dtm-pill__label {\n position: relative;\n z-index: 1;\n}\n/* \u518D\u751F\u4E2D\u3001\u5B9F\u969B\u306B\u767A\u97F3\u3057\u305F\u77AC\u9593\u3060\u3051\u70B9\u706F\uFF08\u3069\u306E\u30BF\u30D6\u304C\u4ECA\u9CF4\u3063\u3066\u3044\u308B\u304B\u8996\u899A\u7684\u306B\u5206\u304B\u308B\u3088\u3046\u306B\uFF09 */\n.dtm-pill--sounding {\n filter: brightness(1.6);\n transition: filter 30ms linear;\n}\n\n/* \u2500\u2500\u2500 \u30D4\u30A2\u30CE\u30ED\u30FC\u30EB\uFF08\u30C8\u30E9\u30C3\u30AB\u30FC\u98A8\uFF09 \u2500\u2500\u2500 */\n.dtm-roll-wrap { display: flex; gap: var(--dtm-gap); }\n.dtm-roll {\n position: relative;\n flex: 1 1 auto;\n height: 32vh;\n max-height: 32vh;\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-border2),\n 4px 4px 0 var(--c-black);\n overflow: hidden;\n}\n/* \u30AB\u30B9\u30BF\u30E0\u80CC\u666F\u753B\u50CF\u30EC\u30A4\u30E4\u30FC\uFF08\u753B\u50CF\u81EA\u4F53\u3092\u534A\u900F\u660E\u5316\u3057\u3001\u30AD\u30E3\u30F3\u30D0\u30B9\u5074\u306E\u5857\u308A\u306F\u7DAD\u6301\uFF09 */\n.dtm-roll::before {\n content: '';\n position: absolute;\n inset: 0;\n background-image: var(--dtm-roll-bg-image, none);\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n opacity: var(--dtm-roll-bg-opacity, 0.4);\n pointer-events: none;\n}\n.dtm-vscroll {\n position: relative;\n width: 20px;\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n cursor: pointer;\n flex: 0 0 auto;\n touch-action: none;\n}\n.dtm-vscroll-thumb, .dtm-hscroll-thumb {\n position: absolute;\n background: var(--dtm-primary);\n min-width: 20px;\n min-height: 20px;\n}\n.dtm-vscroll-thumb { left: 0; width: 100%; }\n.dtm-hscroll {\n position: relative;\n width: 100%; height: 20px;\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n cursor: pointer;\n touch-action: none;\n}\n.dtm-hscroll-thumb { top: 0; height: 100%; }\n\n/* \u2500\u2500\u2500 \u30D1\u30CD\u30EB\uFF08RPG\u30C0\u30A4\u30A2\u30ED\u30B0\u30A6\u30A3\u30F3\u30C9\u30A6\uFF09 \u2500\u2500\u2500 */\n.dtm-panel {\n background: var(--dtm-surface);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n overflow: hidden;\n}\n.dtm-panel > summary {\n list-style: none;\n cursor: pointer;\n padding: 0 12px;\n font-family: var(--dtm-font);\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: .14em;\n display: flex;\n align-items: center;\n min-height: var(--dtm-tap);\n background: var(--dtm-deep);\n border-bottom: 2px solid var(--dtm-border2);\n color: var(--dtm-primary);\n gap: 8px;\n}\n.dtm-panel:not([open]) > summary { border-bottom: none; }\n.dtm-panel > summary::-webkit-details-marker { display: none; }\n/* \u5DE6\u7AEF\u30E9\u30A4\u30F3\uFF08\u30B2\u30FC\u30E0UI\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u8272\u5206\u3051\uFF09 */\n.dtm-panel > summary::before {\n content: '';\n display: block;\n width: 4px;\n height: 20px;\n background: var(--dtm-accent);\n flex: 0 0 auto;\n}\n.dtm-panel[open] > summary::before { background: var(--dtm-primary); }\n/* \u6298\u308A\u305F\u305F\u307F\u77E2\u5370 */\n.dtm-panel > summary::after {\n content: \"\u25B6\";\n margin-left: auto;\n color: var(--dtm-muted);\n font-size: 10px;\n}\n.dtm-panel[open] > summary::after { content: \"\u25BC\"; }\n.dtm-panel-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 10px; }\n.dtm-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }\n.dtm-track-body { display: flex; flex-direction: column; gap: 10px; }\n\n/* \u2500\u2500\u2500 \u81EA\u52D5\u4F5C\u66F2\u30B3\u30F3\u30C6\u30CA\uFF08\u30DE\u30AF\u30ED\u30D1\u30CD\u30EB\u5185\u306E\u5C02\u7528\u30AB\u30FC\u30C9\u98A8\u30B0\u30EB\u30FC\u30D7\u67A0\uFF09 \u2500\u2500\u2500 */\n.dtm-compose-container {\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 1px var(--dtm-border2),\n 0 0 0 1px var(--dtm-success),\n 3px 3px 0 var(--c-black);\n padding: 10px 12px 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n margin-bottom: 6px;\n}\n\n/* \u2500\u2500\u2500 \u30A2\u30AF\u30C6\u30A3\u30D6\u30C8\u30E9\u30C3\u30AF\u8272\uFF08\u500B\u5225\u30C8\u30E9\u30C3\u30AF\u8A2D\u5B9A\u30D1\u30CD\u30EB\u306E\u5DE6\u7AEF\u30E9\u30A4\u30F3\uFF09 \u2500\u2500\u2500 */\n.dtm-panel--track > summary::before,\n.dtm-panel--track[open] > summary::before {\n background: var(--dtm-track-color, var(--dtm-primary));\n}\n\n/* \u2500\u2500\u2500 MML\u51FA\u529B\uFF08CRT\u30BF\u30FC\u30DF\u30CA\u30EB\uFF09 \u2500\u2500\u2500 */\n.dtm-output {\n background: var(--c-black);\n color: var(--dtm-success);\n border: 2px solid var(--dtm-success);\n padding: 10px;\n box-shadow: 0 0 0 2px var(--c-black), 4px 4px 0 var(--c-black);\n}\n.dtm-output::before {\n content: \"C:\\> MML OUTPUT\";\n display: block;\n font-size: 11px;\n color: var(--dtm-muted);\n letter-spacing: .14em;\n margin-bottom: 6px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--dtm-border2);\n}\n.dtm-output pre {\n margin: 0;\n background: transparent;\n padding: 0;\n overflow-x: auto;\n font-family: var(--dtm-font);\n font-size: 12px;\n line-height: 1.8;\n color: var(--dtm-success);\n}\n.dtm-output-label {\n font-size: 11px;\n color: var(--dtm-muted);\n font-family: var(--dtm-font);\n margin-top: 10px;\n}\n.dtm-output-label:first-of-type {\n margin-top: 0;\n}\n.dtm-output-row { display: flex; gap: 8px; align-items: flex-start; margin-top: 6px; }\n.dtm-output-row pre { flex: 1; }\n.dtm-output-scroll { max-height: 240px; overflow-y: auto; }\n\n/* \u2500\u2500\u2500 \u30ED\u30FC\u30C7\u30A3\u30F3\u30B0\u30AA\u30FC\u30D0\u30FC\u30EC\u30A4 \u2500\u2500\u2500 */\n.dtm-overlay {\n position: absolute; inset: 0; z-index: 10;\n background: rgba(0,0,0,.92);\n display: flex; align-items: center; justify-content: center;\n flex-direction: column; gap: 14px;\n pointer-events: auto;\n cursor: wait;\n}\n.dtm-overlay[hidden] { display: none; }\n.dtm-overlay::before {\n content: '\u30ED\u30FC\u30C9\u4E2D';\n font-family: var(--dtm-font);\n font-size: 13px;\n color: var(--dtm-primary);\n text-transform: uppercase;\n letter-spacing: .25em;\n animation: dtm-blink 1s steps(1) infinite;\n}\n/* 8\u30D6\u30ED\u30C3\u30AF\u523B\u307F\u3067\u57CB\u307E\u308B\u30D4\u30AF\u30BB\u30EB\u30D0\u30FC */\n.dtm-spinner {\n width: 96px; height: 12px;\n position: relative;\n background: var(--c-navy);\n border: 2px solid var(--dtm-primary);\n box-shadow: 0 0 0 2px var(--c-black), 4px 4px 0 var(--c-black);\n}\n.dtm-spinner::after {\n content: '';\n position: absolute;\n left: 0; top: 0; height: 100%;\n background: var(--dtm-primary);\n animation: dtm-load 1.6s steps(8) infinite;\n}\n@keyframes dtm-load { 0%{width:0} 100%{width:100%} }\n/* \u9032\u6357\u304C\u78BA\u5B9A\u3057\u305F\u3089\u7121\u9650\u30EB\u30FC\u30D7\u6F14\u51FA\u3092\u6B62\u3081\u3001\u5B9F\u6E2C\u5024\u3067\u5857\u308A\u3064\u3076\u3059 */\n.dtm-spinner--determinate::after { display: none; }\n.dtm-spinner-fill {\n position: absolute;\n left: 0; top: 0; height: 100%;\n width: 0;\n background: var(--dtm-primary);\n transition: width .12s steps(8);\n}\n.dtm-loading-label {\n font-family: var(--dtm-font);\n font-size: 11px;\n color: var(--dtm-primary);\n letter-spacing: .15em;\n min-height: 1em;\n}\n.dtm-overlay-skip-btn {\n margin-top: 12px;\n min-height: 32px;\n font-size: 11px;\n font-family: var(--dtm-font);\n padding: 0 12px;\n background: var(--dtm-surface);\n border: 2px solid var(--dtm-border2);\n color: var(--dtm-muted);\n box-shadow: 2px 2px 0 var(--c-black);\n cursor: pointer;\n pointer-events: auto;\n}\n.dtm-overlay-skip-btn:hover {\n color: var(--dtm-text);\n border-color: var(--dtm-primary);\n}\n.dtm-overlay-skip-btn:active {\n transform: translate(2px, 2px);\n box-shadow: none;\n}\n.dtm-overlay-skip-btn:disabled {\n opacity: .3;\n cursor: default;\n box-shadow: none;\n transform: none;\n}\n.dtm-topbar-loading {\n display: none;\n font-family: var(--dtm-font);\n font-size: 11px;\n color: var(--dtm-primary);\n margin-left: 12px;\n letter-spacing: .15em;\n align-self: center;\n}\n.dtm-topbar.is-loading .dtm-topbar-loading {\n display: inline-block;\n}\n.dtm-topbar.is-loading {\n pointer-events: none;\n opacity: 0.7;\n}\n\n@keyframes dtm-blink { 0%,100%{opacity:1} 50%{opacity:0} }\n.dtm-blink { animation: dtm-blink 1s steps(1) infinite; }\n\n/* \u2500\u2500\u2500 \u97F3\u5272\u308C\u691C\u77E5\u30D0\u30C3\u30B8 \u2500\u2500\u2500 \u30AF\u30EA\u30C3\u30D7\u767A\u751F\u4E2D\u3060\u3051\u8868\u793A\u3055\u308C\u308B\u8B66\u544A\u30DC\u30BF\u30F3\u3002\u30AF\u30EA\u30C3\u30AF\u3067\u6D88\u305B\u308B\u3002 */\n.dtm-clip-badge {\n flex: 0 0 auto;\n min-height: 24px;\n padding: 0 8px;\n border: 2px solid var(--c-black);\n background: var(--dtm-danger);\n color: var(--c-white);\n font-family: var(--dtm-font);\n font-size: 10px;\n letter-spacing: .1em;\n cursor: pointer;\n box-shadow: 0 0 0 2px var(--dtm-danger), 2px 2px 0 var(--c-black);\n animation: dtm-blink .5s steps(1) infinite;\n}\n.dtm-clip-badge:active { transform: translate(2px,2px); box-shadow: none; }\n\n/* \u2500\u2500\u2500 \u30A4\u30F3\u30D5\u30A9\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */\n.dtm-infobtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex: 0 0 auto;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-surface);\n color: var(--dtm-muted);\n cursor: pointer;\n box-shadow: 1px 1px 0 var(--c-black);\n padding: 0;\n margin: 0;\n}\n.dtm-infobtn:hover {\n color: var(--dtm-primary);\n border-color: var(--dtm-primary);\n}\n.dtm-infobtn:active {\n transform: translate(1px, 1px);\n box-shadow: none;\n}\n\n/* \u2500\u2500\u2500 \u89E3\u8AAC\u30E2\u30FC\u30C0\u30EB \u2500\u2500\u2500 */\n.dtm-modal-overlay {\n position: fixed;\n inset: 0;\n z-index: 10000;\n background: rgba(0, 0, 0, 0.7);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n backdrop-filter: blur(2px);\n /* body\u76F4\u4E0B\u306B\u91CD\u306D\u305F\u5834\u5408\uFF08\u518D\u751F\u5C02\u7528\u30D3\u30E5\u30FC\uFF09\u3067\u3082\u6587\u5B57\u8272\u30FB\u30D5\u30A9\u30F3\u30C8\u304C\n .dtm-daw \u304B\u3089\u7D99\u627F\u3067\u304D\u306A\u3044\u305F\u3081\u3001\u3053\u3053\u3067\u660E\u793A\u3059\u308B\u3002 */\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n}\n.dtm-modal-overlay[hidden] {\n display: none !important;\n}\n\n/* \u2500\u2500\u2500 \u5229\u7528\u898F\u7D04\u540C\u610F\u30AB\u30D0\u30FC \u2500\u2500\u2500 */\n.dtm-consent-overlay {\n position: fixed;\n inset: 0;\n z-index: 10100;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n backdrop-filter: blur(2px);\n /* body\u76F4\u4E0B\u306B\u91CD\u306D\u308B\u305F\u3081 .dtm-daw \u304B\u3089\u7D99\u627F\u3067\u304D\u306A\u3044\u6587\u5B57\u8272\u30FB\u30D5\u30A9\u30F3\u30C8\u3092\u660E\u793A\u3002 */\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n}\n.dtm-consent-overlay[hidden] {\n display: none !important;\n}\n.dtm-consent-modal {\n max-width: 450px;\n width: 100%;\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n background: var(--dtm-surface);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n overflow-y: auto;\n}\n.dtm-consent-header {\n background: var(--dtm-deep);\n color: var(--dtm-text);\n padding: 8px 12px;\n border-bottom: 2px solid var(--c-black);\n font-weight: bold;\n text-align: center;\n font-size: 14px;\n}\n.dtm-consent-body {\n padding: 12px 16px;\n font-size: 13px;\n line-height: 1.6;\n}\n.dtm-consent-body a {\n color: var(--dtm-primary);\n text-decoration: underline;\n}\n.dtm-consent-body a:hover {\n color: var(--dtm-accent);\n}\n.dtm-consent-footer {\n padding: 8px;\n border-top: 2px solid var(--c-black);\n background: var(--dtm-deep);\n display: flex;\n justify-content: center;\n}\n\n.dtm-confirm-footer {\n padding: 8px 12px;\n border-top: 2px solid var(--c-black);\n background: var(--dtm-deep);\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.dtm-modal {\n max-width: 500px;\n width: 100%;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n background: var(--dtm-surface);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n overflow: hidden;\n}\n.dtm-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--dtm-deep);\n padding: 8px 12px;\n border-bottom: 2px solid var(--c-black);\n}\n.dtm-modal-title {\n font-family: var(--dtm-font);\n font-size: 14px;\n color: var(--dtm-gold);\n font-weight: bold;\n}\n.dtm-modal-close {\n background: transparent;\n border: none;\n color: var(--dtm-text);\n font-size: 20px;\n cursor: pointer;\n padding: 0;\n line-height: 1;\n}\n.dtm-modal-close:hover {\n color: var(--dtm-danger);\n}\n.dtm-modal-body {\n padding: 12px;\n overflow-y: auto;\n overflow-x: hidden;\n font-size: 13px;\n line-height: 1.6;\n}\n.dtm-modal-body * {\n max-width: 100%;\n box-sizing: border-box;\n}\n.dtm-modal-body a {\n color: var(--dtm-primary);\n text-decoration: underline;\n}\n.dtm-modal-body a:hover {\n color: var(--dtm-accent);\n}\n.dtm-modal-body h4 {\n margin: 12px 0 6px 0;\n color: var(--dtm-primary);\n font-size: 13px;\n}\n.dtm-modal-body h4:first-child {\n margin-top: 0;\n}\n.dtm-modal-body p {\n margin: 0 0 8px 0;\n}\n.dtm-modal-body ul {\n margin: 0 0 8px 0;\n padding-left: 16px;\n}\n.dtm-modal-body li {\n margin-bottom: 4px;\n}\n.dtm-modal-body code {\n background: var(--dtm-deep);\n color: var(--dtm-accent);\n padding: 1px 4px;\n font-family: var(--dtm-font);\n font-size: 12px;\n}\n.dtm-modal-body pre {\n background: var(--dtm-deep);\n color: var(--dtm-success);\n padding: 8px;\n border: 1px solid var(--dtm-border2);\n margin: 6px 0;\n overflow-x: auto;\n font-family: var(--dtm-font);\n font-size: 12px;\n}\n\n.dtm-modal-sample-box {\n background: var(--dtm-deep);\n border: 1px solid var(--dtm-border2);\n border-radius: 4px;\n padding: 8px 10px;\n margin-bottom: 12px;\n}\n.dtm-modal-sample-box:last-child {\n margin-bottom: 0;\n}\n.dtm-modal-sample-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n.dtm-modal-sample-tag {\n font-family: var(--dtm-font);\n font-size: 11px;\n font-weight: bold;\n color: var(--dtm-accent);\n}\n.dtm-modal-sample-desc {\n margin: 6px 0 0 0;\n font-size: 11px;\n color: var(--dtm-muted);\n}\n.dtm-modal-sample-player-container {\n margin-top: 8px;\n}\n.dtm-modal-sample-player-container:empty {\n margin-top: 0;\n}\n.dtm-modal-sample-player-container .dtm-player {\n border: 1px solid var(--dtm-border2);\n box-shadow: none;\n background: rgba(0, 0, 0, 0.3);\n}\n.dtm-modal-sample-player-container .dtm-player-body {\n max-height: 100px;\n overflow-y: auto;\n}\n\n/* \u2500\u2500\u2500 \u30AC\u30A4\u30C9\u30C4\u30A2\u30FC\uFF08\u30B9\u30DD\u30C3\u30C8\u30E9\u30A4\u30C8\u578B\u30A6\u30A9\u30FC\u30AF\u30B9\u30EB\u30FC\uFF09 \u2500\u2500\u2500 */\n/* \u6697\u5E55\u306F .dtm-tour-spot \u306E\u5DE8\u5927\u306A box-shadow \u3067\u63CF\u304F\u3002box-shadow \u306F\u5F53\u305F\u308A\u5224\u5B9A\u3092\n \u6301\u305F\u306A\u3044\u306E\u3067\u3001\u7D20\u901A\u308A\u3092\u9632\u3050\u906E\u853D\u306F .dtm-tour\uFF08\u5168\u753B\u9762\uFF09\u5074\u304C\u62C5\u5F53\u3059\u308B\u3002 */\n.dtm-tour {\n position: fixed;\n inset: 0;\n z-index: 10050;\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 13px;\n line-height: 1.6;\n letter-spacing: .04em;\n -webkit-font-smoothing: none;\n font-smooth: never;\n -webkit-tap-highlight-color: transparent;\n}\n.dtm-tour * { box-sizing: border-box; max-width: 100%; }\n.dtm-tour-spot {\n position: fixed;\n left: 0;\n top: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n border: 2px solid var(--dtm-gold);\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.74);\n transition: left .18s ease, top .18s ease, width .18s ease, height .18s ease;\n}\n.dtm-tour-bubble {\n position: fixed;\n left: 0;\n top: 0;\n display: flex;\n flex-direction: column;\n background: var(--dtm-surface);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n transition: left .18s ease, top .18s ease;\n}\n.dtm-tour-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--dtm-deep);\n padding: 4px 8px;\n border-bottom: 2px solid var(--c-black);\n}\n.dtm-tour-progress {\n font-size: 11px;\n color: var(--dtm-muted);\n}\n.dtm-tour-close {\n background: transparent;\n border: none;\n color: var(--dtm-text);\n font-size: 18px;\n line-height: 1;\n padding: 0 2px;\n cursor: pointer;\n}\n.dtm-tour-close:hover { color: var(--dtm-danger); }\n.dtm-tour-title {\n padding: 8px 10px 0;\n color: var(--dtm-gold);\n font-size: 14px;\n font-weight: bold;\n}\n.dtm-tour-body {\n padding: 6px 10px 8px;\n max-height: 40vh;\n overflow-y: auto;\n}\n.dtm-tour-body p { margin: 0 0 6px; }\n.dtm-tour-body p:last-child { margin-bottom: 0; }\n.dtm-tour-body ul { margin: 0 0 6px; padding-left: 16px; }\n.dtm-tour-body li { margin-bottom: 3px; }\n.dtm-tour-body b { color: var(--dtm-primary); }\n.dtm-tour-foot {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 8px;\n border-top: 2px solid var(--c-black);\n background: var(--dtm-deep);\n}\n.dtm-tour-spacer { flex: 1; }\n.dtm-tour-btn {\n min-height: 32px;\n padding: 0 10px;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-surface);\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 12px;\n letter-spacing: .04em;\n cursor: pointer;\n box-shadow: 2px 2px 0 var(--c-black);\n}\n.dtm-tour-btn:active { transform: translate(2px, 2px); box-shadow: none; }\n.dtm-tour-btn--ghost { background: transparent; }\n.dtm-tour-btn--primary {\n border-color: var(--dtm-primary);\n background: var(--dtm-primary);\n color: var(--dtm-pfg);\n}\n\n/* \u76EE\u7684\u5225\u306E\u5206\u5C90\uFF08\u30C4\u30A2\u30FC\u5192\u982D\u306E\u300C\u4F55\u3092\u3057\u3066\u307F\u305F\u3044\uFF1F\u300D\uFF09\u3002 */\n.dtm-tour-branches {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 8px;\n}\n.dtm-tour-branch {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n width: 100%;\n min-height: var(--dtm-tap);\n padding: 6px 10px;\n border: 2px solid var(--dtm-primary);\n background: var(--dtm-surface);\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 13px;\n letter-spacing: .04em;\n text-align: left;\n cursor: pointer;\n box-shadow: 2px 2px 0 var(--c-black);\n}\n.dtm-tour-branch:active { transform: translate(2px, 2px); box-shadow: none; }\n.dtm-tour-branch-label { color: var(--dtm-primary); }\n.dtm-tour-branch-hint { font-size: 11px; color: var(--dtm-muted); }\n\n/* \u2500\u2500\u2500 \u30D8\u30EB\u30D7\u306E\u30CF\u30D6\uFF08\u300C?\u300D\u30DC\u30BF\u30F3\u306E\u30E2\u30FC\u30C0\u30EB\uFF09 \u2500\u2500\u2500 */\n.dtm-help-goals {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 6px 0 4px;\n}\n/* \u76EE\u7684\u30DC\u30BF\u30F3\u306F\u898B\u51FA\u3057\u3068\u88DC\u8DB3\u306E2\u6BB5\u7D44\u307F\u306B\u3059\u308B\u3002.dtm-btn \u306F1\u884C\u524D\u63D0\u306E\n inline-flex \u306A\u306E\u3067\u3001\u3053\u3053\u3060\u3051\u7E26\u4E26\u3073\u30FB\u5DE6\u5BC4\u305B\u30FB\u9AD8\u3055\u81EA\u52D5\u306B\u4E0A\u66F8\u304D\u3059\u308B\u3002 */\n.dtm-help-goals .dtm-btn {\n flex-direction: column;\n align-items: flex-start;\n gap: 1px;\n width: 100%;\n height: auto;\n padding: 6px 10px;\n text-align: left;\n white-space: normal;\n}\n.dtm-help-goals .dtm-btn small {\n font-size: 11px;\n opacity: .8;\n font-weight: normal;\n}\n.dtm-help-topics {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n.dtm-help-topics .dtm-btn {\n min-height: 32px;\n padding: 0 8px;\n font-size: 12px;\n}\n\n.dtm-hidden { display: none !important; }\n/* \u8AAD\u8FBC\u6642\u306E\u8B66\u544A\u304A\u77E5\u3089\u305B\uFF08\u4F8B: \u30B7\u30F3\u30D7\u30EB\u30E2\u30FC\u30C9\u3067\u306E\u30C8\u30E9\u30C3\u30AF\u5408\u7B97\uFF09\u3002 */\n.dtm-load-note {\n margin: 6px 0 0;\n padding: 0 2px;\n font-family: var(--dtm-font);\n font-size: 11px;\n line-height: 1.5;\n letter-spacing: .04em;\n color: var(--dtm-warn); /* \u8B66\u544A\u8272\uFF08\u30AA\u30EC\u30F3\u30B8\uFF09 */\n font-weight: bold;\n opacity: 1.0;\n}\n.dtm-load-note::before { content: \"\u26A0 \"; }\n/* \u4F34\u594F\u97F3\u6E90\uFF08mp3/wav/YouTube\uFF09\u306E\u72B6\u614B\u8868\u793A\u3002\u8AAD\u307F\u8FBC\u307F\u7D50\u679C\u306E\u5831\u544A\u306A\u306E\u3067\u8B66\u544A\u8272\u306B\u306F\u3057\u306A\u3044\u3002 */\n.dtm-audio-note {\n margin: 6px 0 0;\n padding: 0 2px;\n font-family: var(--dtm-font);\n font-size: 11px;\n line-height: 1.5;\n letter-spacing: .04em;\n color: var(--dtm-muted);\n}\n.dtm-audio-note--warn { color: var(--dtm-warn); font-weight: bold; }\n/* YouTube\u30D7\u30EC\u30A4\u30E4\u30FC\u306E\u67A0\u3002API\u304C\u4E2D\u306E\u8981\u7D20\u3092 iframe \u3078\u5DEE\u3057\u66FF\u3048\u308B\u306E\u3067\u3001\u67A0\u5074\u3067\u5BF8\u6CD5\u3092\u6C7A\u3081\u308B\u3002 */\n.dtm-audio-yt { width: 100%; max-width: 320px; aspect-ratio: 16 / 9; }\n.dtm-audio-yt iframe { display: block; width: 100%; height: 100%; border: 0; }\n.dtm-grow { flex: 1 1 auto; }\n.dtm-lyric-icon {\n flex: 0 0 auto;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n object-fit: cover;\n image-rendering: pixelated;\n}\n/* \u6B4C\u8A5E\u30C8\u30E9\u30C3\u30AF\u306E\u300C\u8A73\u7D30\u8A2D\u5B9A\u300D\u2014 \u5E38\u7528\u3057\u306A\u3044\u30D1\u30E9\u30E1\u30FC\u30BF\uFF08\u30AA\u30AF\u30BF\u30FC\u30D6/\u5B9A\u4F4D/\u30EA\u30D0\u30FC\u30D6\u9001\u308A/\n \u30B8\u30A7\u30F3\u30C0\u30FC/\u30D6\u30EC\u30B7\u30CD\u30B9/\u30D3\u30D6\u30E9\u30FC\u30C8\uFF09\u3092\u7573\u3093\u3067\u304A\u304F\u8EFD\u91CF\u306A details\u3002dtm-panel \u307B\u3069\n \u4EF0\u3005\u3057\u304F\u305B\u305A\u3001\u5C0F\u3055\u3044\u25B6\u30DE\u30FC\u30AB\u30FC\u3060\u3051\u4ED8\u3051\u308B\uFF08\u4ED5\u5207\u308A\u7DDA\u306F\u9AD8\u3055\u3092\u98DF\u3046\u306E\u3067\u7F6E\u304B\u306A\u3044\uFF09\u3002 */\n.dtm-advanced {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.dtm-advanced > summary {\n list-style: none;\n cursor: pointer;\n font-size: 11px;\n letter-spacing: .08em;\n color: var(--dtm-text);\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 28px;\n padding: 0 8px;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-deep);\n box-shadow: 2px 2px 0 var(--c-black);\n width: fit-content;\n}\n.dtm-advanced > summary:active { transform: translate(2px,2px); box-shadow: none; }\n.dtm-advanced > summary::-webkit-details-marker { display: none; }\n.dtm-advanced > summary::before { content: \"\u25B6\"; font-size: 9px; color: var(--dtm-accent); }\n.dtm-advanced[open] > summary::before { content: \"\u25BC\"; }\n.dtm-advanced[open] > summary { border-color: var(--dtm-primary); color: var(--dtm-primary); }\n\n/* \u2500\u2500\u2500 \u5E83\u5E45\u62E1\u5F35 \u2500\u2500\u2500 */\n@media (min-width: 768px) {\n .dtm-daw { gap: 8px; padding: 10px; }\n .dtm-roll { height: 420px; }\n}\n\n/* ====================================================\n MML PLAYER \u2014 \u518D\u751F\u5C02\u7528\u30D3\u30E5\u30FC\uFF08mountMmlPlayer\uFF09\n ==================================================== */\n.dtm-player {\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n padding: var(--dtm-gap);\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n box-shadow: 4px 4px 0 var(--c-black);\n}\n.dtm-player-message {\n padding: 4px 8px;\n background: var(--c-purple);\n color: var(--c-yellow);\n font-size: 11px;\n border: 2px solid var(--c-black);\n box-shadow: inset 0 -2px 0 rgba(0,0,0,0.2);\n font-family: var(--dtm-font);\n text-align: center;\n width: 100%;\n box-sizing: border-box;\n}\n.dtm-player-head {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n.dtm-player-play {\n flex: 0 0 auto;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--dtm-primary);\n color: var(--dtm-pfg);\n border: 2px solid var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n cursor: pointer;\n padding: 0;\n}\n.dtm-player-play:active { transform: translate(2px, 2px); box-shadow: none; }\n.dtm-player-play--stop { background: var(--dtm-danger); }\n.dtm-player-play:disabled { opacity: 0.4; cursor: default; }\n.dtm-player-loop {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-bg);\n color: var(--dtm-muted);\n cursor: pointer;\n flex: 0 0 auto;\n}\n.dtm-player-loop:active { transform: translate(1px, 1px); }\n.dtm-player-loop--on {\n border-color: var(--c-black);\n background: var(--dtm-gold);\n color: var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n}\n.dtm-player-loop:disabled { opacity: 0.4; cursor: default; }\n.dtm-player-beat-row {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.dtm-player-beat-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--dtm-border2);\n transition: background 0.06s;\n}\n.dtm-player-beat-dot--on { background: var(--dtm-primary); }\n.dtm-player-bar {\n font-family: 'k8x12', monospace;\n font-size: 11px;\n color: var(--dtm-text);\n min-width: 2em;\n margin-left: 4px;\n}\n.dtm-player-chord {\n font-family: 'k8x12', monospace;\n font-size: 11px;\n color: var(--dtm-accent);\n min-width: 4em;\n margin-left: 8px;\n font-weight: bold;\n}\n.dtm-player-seek-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dtm-player-seek {\n --fill: 0%;\n flex: 1 1 auto;\n min-width: 0;\n height: 12px;\n margin: 0;\n background: transparent;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n.dtm-player-seek:disabled { cursor: default; opacity: 0.4; }\n/* \u518D\u751F\u6E08\u307F\u533A\u9593\u3092YouTube\u98A8\u306B\u8272\u5857\u308A\u3059\u308B\uFF08--fill \u306F\u518D\u751F\u4F4D\u7F6E\u306B\u5FDC\u3058\u3066JS\u304B\u3089\u8A2D\u5B9A\uFF09 */\n.dtm-player-seek::-webkit-slider-runnable-track {\n height: 6px;\n background: linear-gradient(\n to right,\n var(--dtm-primary) var(--fill),\n var(--dtm-border2) var(--fill)\n );\n border: 2px solid var(--c-black);\n}\n.dtm-player-seek::-moz-range-track {\n height: 6px;\n background: var(--dtm-border2);\n border: 2px solid var(--c-black);\n}\n.dtm-player-seek::-moz-range-progress {\n height: 6px;\n background: var(--dtm-primary);\n border: 2px solid var(--c-black);\n border-right: none;\n}\n.dtm-player-seek::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 12px;\n height: 16px;\n margin-top: -7px;\n background: var(--dtm-primary);\n border: 2px solid var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n cursor: pointer;\n}\n.dtm-player-seek::-moz-range-thumb {\n width: 12px;\n height: 16px;\n background: var(--dtm-primary);\n border: 2px solid var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n cursor: pointer;\n border-radius: 0;\n}\n.dtm-player-time {\n flex: 0 0 auto;\n font-family: 'k8x12', monospace;\n font-size: 11px;\n color: var(--dtm-text);\n white-space: nowrap;\n}\n.dtm-player-dots {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.dtm-player-dot { width: 8px; height: 8px; display: inline-block; }\n.dtm-player-mml-header {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.dtm-player-mml-link {\n font-family: 'k8x12', monospace;\n font-size: 10px;\n color: var(--dtm-muted);\n text-decoration: none;\n white-space: nowrap;\n}\n.dtm-player-mml-link:hover { color: var(--dtm-primary); }\n.dtm-player-more-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n}\n.dtm-player-more-btn {\n background: transparent;\n border: none;\n color: var(--dtm-muted);\n cursor: pointer;\n padding: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n width: 24px;\n height: 24px;\n transition: color 0.15s, background-color 0.15s;\n}\n.dtm-player-more-btn:hover,\n.dtm-player-more-btn.is-active {\n color: var(--dtm-text);\n background: var(--dtm-border2);\n}\n.dtm-player-menu {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n box-shadow: 4px 4px 0 var(--c-black);\n z-index: 200;\n display: flex;\n flex-direction: column;\n padding: 4px 0;\n min-width: 130px;\n font-family: var(--dtm-font);\n}\n.dtm-player-menu-item {\n background: transparent;\n border: none;\n color: var(--dtm-text);\n padding: 6px 12px;\n text-align: left;\n cursor: pointer;\n font-size: 11px;\n font-family: inherit;\n white-space: nowrap;\n width: 100%;\n box-sizing: border-box;\n transition: background-color 0.1s, color 0.1s;\n}\n.dtm-player-menu-item:hover {\n background: var(--dtm-primary);\n color: var(--dtm-pfg);\n}\n.dtm-player-emoji {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n font-size: 18px;\n line-height: 1;\n user-select: none;\n}\n.dtm-player-balloon {\n /* body \u76F4\u4E0B\u306B\u751F\u6210\u3055\u308C\u3001JS(positionBalloon)\u304C\u6BCE\u56DE left/top \u3092\u30A2\u30F3\u30AB\u30FC\u306E\u753B\u9762\u5EA7\u6A19\u3067\n \u8A2D\u5B9A\u3059\u308B\u3002overflow:hidden \u306A\u7956\u5148\uFF08\u6295\u7A3F\u30AB\u30FC\u30C9\u7B49\uFF09\u306B\u30AF\u30EA\u30C3\u30D7\u3055\u308C\u306A\u3044\u3088\u3046 fixed \u3067\u6D6E\u304B\u305B\u308B\u3002\n top \u306F\u30A2\u30F3\u30AB\u30FC\u4E0A\u7AEF-6px\u3001transform \u3067\u81EA\u8EAB\u306E\u5DE6\u4E0B\u89D2\u3092\u305D\u306E\u70B9\u306B\u5408\u308F\u305B\u308B\u3002 */\n position: fixed;\n left: 0;\n top: 0;\n transform: translate(-50%, -100%);\n z-index: 1000;\n display: none;\n pointer-events: none;\n font-family: var(--dtm-font);\n font-size: 9px;\n color: var(--c-black);\n background: var(--c-white);\n border: 2px solid var(--c-black);\n padding: 2px 4px;\n white-space: nowrap;\n box-shadow: 2px 2px 0 var(--c-black);\n}\n.dtm-player-balloon::after {\n content: \"\";\n position: absolute;\n bottom: -6px;\n left: 50%;\n transform: translateX(-50%) rotate(45deg);\n width: 8px;\n height: 8px;\n background: var(--c-white);\n border-right: 2px solid var(--c-black);\n border-bottom: 2px solid var(--c-black);\n}\n/* \u30A2\u30A4\u30B3\u30F3\u304C\u753B\u9762\u4E0A\u7AEF\u306B\u8FD1\u304F\u4E0A\u306B\u51FA\u3059\u4F59\u767D\u304C\u7121\u3044\u5834\u5408\u306F\u4E0B\u306B\u53CD\u8EE2\u8868\u793A\u3059\u308B\uFF08positionBalloon \u304C\u4ED8\u4E0E\uFF09 */\n.dtm-player-balloon--below {\n transform: translate(-50%, 0);\n}\n.dtm-player-balloon--below::after {\n bottom: auto;\n top: -6px;\n border-right: none;\n border-bottom: none;\n border-left: 2px solid var(--c-black);\n border-top: 2px solid var(--c-black);\n}\n.dtm-player-balloon--visible {\n display: block;\n animation: dtm-balloon-fade-in 0.1s steps(2);\n}\n.dtm-player-balloon--below.dtm-player-balloon--visible {\n animation-name: dtm-balloon-fade-in-below;\n}\n@keyframes dtm-balloon-fade-in {\n from { opacity: 0; transform: translate(-50%, -100%) translateY(4px); }\n to { opacity: 1; transform: translate(-50%, -100%) translateY(0); }\n}\n@keyframes dtm-balloon-fade-in-below {\n from { opacity: 0; transform: translate(-50%, 0) translateY(-4px); }\n to { opacity: 1; transform: translate(-50%, 0) translateY(0); }\n}\n@keyframes dtm-emoji-jump {\n 0% { transform: translateY(0); }\n 35% { transform: translateY(-5px); }\n 65% { transform: translateY(-5px); }\n 100% { transform: translateY(0); }\n}\n.dtm-player-emoji--jump {\n animation: dtm-emoji-jump 0.18s ease-out forwards;\n}\n.dtm-player-chip {\n font-family: 'k8x12', monospace;\n font-size: 9px;\n color: var(--dtm-text);\n background: var(--dtm-border2);\n padding: 2px 6px;\n white-space: nowrap;\n}\n.dtm-player-body {\n position: relative; /* \u30ED\u30FC\u30C7\u30A3\u30F3\u30B0\u30AA\u30FC\u30D0\u30FC\u30EC\u30A4\u306E\u57FA\u6E96\u3002\u30EC\u30FC\u30F3\u7FA4\u3060\u3051\u3092\u8986\u3046 */\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n}\n.dtm-player-lane-row {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: 6px;\n}\n.dtm-player-lane-label {\n position: relative;\n flex: 0 0 auto;\n width: 16px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n}\n.dtm-player-lane-label--btn {\n cursor: pointer;\n user-select: none;\n}\n.dtm-player-lane-label--btn:hover { opacity: 0.7; }\n.dtm-player-lane-label--muted { opacity: 0.3; }\n\n/* \u2500\u2500\u2500 \u30DF\u30E5\u30FC\u30C8\u8868\u793A\uFF08\u6392\u4ED6\u540C\u671F\uFF09 \u2500\u2500\u2500 */\n.dtm-player-emoji.is-muted,\n.dtm-player-lane-label.is-muted {\n position: relative;\n}\n\n/* \u30DF\u30E5\u30FC\u30C8\u6642\u306E\u300C\u00D7\u300D\u30DE\u30FC\u30AF\u91CD\u306D\u63CF\u304D */\n.dtm-player-emoji.is-muted::before,\n.dtm-player-lane-label.is-muted::before {\n content: \"\u00D7\";\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--dtm-danger);\n font-family: var(--dtm-font);\n font-size: 16px;\n font-weight: bold;\n z-index: 10;\n pointer-events: none;\n text-shadow: 1px 1px 0 var(--c-black);\n}\n\n.dtm-player-lane-label.is-muted::before {\n font-size: 14px;\n}\n\n/* \u30DF\u30E5\u30FC\u30C8\u6642\u306E\u30A2\u30A4\u30B3\u30F3\u3084\u8981\u7D20\u306E\u8584\u6697\u5316\uFF08\u5439\u304D\u51FA\u3057\u306F\u9664\u5916\uFF09 */\n.dtm-player-emoji.is-muted > img,\n.dtm-player-emoji.is-muted > span:not(.dtm-player-balloon) {\n opacity: 0.25;\n filter: grayscale(80%);\n}\n\n.dtm-player-lane-label.is-muted {\n opacity: 0.25;\n}\n\n/* \u30DF\u30E5\u30FC\u30C8\u6642\u306E\u30C8\u30E9\u30C3\u30AF\u30EC\u30FC\u30F3\uFF08\u30B9\u30AF\u30ED\u30FC\u30EB\u90E8\uFF09\u306E\u8584\u6697\u5316\u3068\u30C7\u30AB\u00D7\u30DE\u30FC\u30AF\uFF08\u8272\u5F31\u5BFE\u5FDC\uFF09 */\n.dtm-player-lane-row.is-muted::after {\n content: \"\u00D7\";\n position: absolute;\n top: 0;\n bottom: 0;\n left: 22px; /* label width (16px) + gap (6px) */\n right: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--dtm-danger);\n font-family: var(--dtm-font);\n font-size: 24px;\n font-weight: bold;\n background: rgba(0, 0, 0, 0.45);\n z-index: 10;\n pointer-events: none;\n text-shadow: 1px 1px 0 var(--c-black);\n}\n.dtm-player-lane-no {\n font-family: 'k8x12', monospace;\n font-size: 9px;\n color: var(--dtm-muted);\n}\n.dtm-player-lane {\n position: relative; /* \u30C8\u30FC\u30AF\u30F3\u306E offsetParent \u3092\u30EC\u30FC\u30F3\u306B\u56FA\u5B9A\u3057\u3001\u4E2D\u592E\u5BC4\u305B\u8A08\u7B97\u3092\u6B63\u3059 */\n flex: 1 1 auto;\n overflow-x: auto;\n overflow-y: hidden;\n white-space: nowrap;\n background: var(--c-black);\n border: none;\n padding: 0 6px;\n scrollbar-width: none;\n display: flex;\n align-items: center;\n}\n.dtm-player-lane::-webkit-scrollbar { display: none; }\n.dtm-tk {\n font-family: 'k8x12', monospace;\n font-size: 12px;\n color: var(--dtm-text);\n flex: 0 0 auto;\n}\n.dtm-tk--rest { color: var(--dtm-muted); }\n.dtm-tk--octave,\n.dtm-tk--shift,\n.dtm-tk--length,\n.dtm-tk--ctrl { color: var(--dtm-border2); }\n.dtm-tk--lyric { color: var(--dtm-text); letter-spacing: 1px; }\n/* \u7D99\u7D9A\uFF08\u30FC / \u301C\uFF09\u306F\u300C\u8A00\u3044\u76F4\u3055\u306A\u3044\u300D\u97F3\u3002\u304B\u306A\u3088\u308A\u6DE1\u304F\u3057\u3066\u97F3\u7BC0\u306E\u5207\u308C\u76EE\u3092\u76EE\u3067\u8FFD\u3048\u308B\u3088\u3046\u306B\u3059\u308B */\n.dtm-tk--lyric-tie { color: var(--dtm-muted); }\n/* \u4FC3\u97F3\uFF08\u3063\uFF09\u30FB\u4F11\u7B26\uFF08_\uFF09\u306F\u6B4C\u308F\u306A\u3044\u30CE\u30FC\u30C8\u3002\u3055\u3089\u306B\u843D\u3068\u3057\u3066\u7121\u97F3\u3067\u3042\u308B\u3053\u3068\u3092\u793A\u3059 */\n.dtm-tk--lyric-stop,\n.dtm-tk--lyric-rest { color: var(--dtm-border2); }\n.dtm-tk--break { color: var(--dtm-muted); opacity: 0.7; margin: 0 2px; }\n.dtm-tk--meta { color: var(--dtm-border2); margin-right: 4px; }\n.dtm-tk.is-active {\n background: var(--tk, var(--dtm-primary));\n color: var(--c-black);\n font-weight: bold;\n}\n\n/* \u2500\u2500\u2500 \u30B3\u30FC\u30C9\u9032\u884C\u30D7\u30EC\u30A4\u30E4\u30FC \u2500\u2500\u2500 */\n/* MML\u518D\u751F\u5C02\u7528\u30D7\u30EC\u30A4\u30E4\u30FC\uFF08.dtm-player\uFF09\u3068\u67A0\u30C7\u30B6\u30A4\u30F3\u3092\u63C3\u3048\u308B */\n.dtm-chord-player {\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n padding: var(--dtm-gap);\n font-family: var(--dtm-font);\n font-size: 13px;\n letter-spacing: .06em;\n color: var(--dtm-text);\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n box-shadow: 4px 4px 0 var(--c-black);\n image-rendering: pixelated;\n -webkit-font-smoothing: none;\n}\n.dtm-chord-player *,\n.dtm-chord-player *::before,\n.dtm-chord-player *::after { box-sizing: border-box; }\n\n/* \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC \u2014 MML\u518D\u751F\u5C02\u7528\u30D7\u30EC\u30A4\u30E4\u30FC\u306E .dtm-player-head \u3068\u63C3\u3048\u308B */\n.dtm-cp-ctrl {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n}\n.dtm-cp-ctrl .dtm-player-more-container {\n margin-left: auto;\n}\n\n/* \u30EB\u30FC\u30D7\u5207\u66FF\u30DC\u30BF\u30F3 */\n.dtm-cp-loop {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-bg);\n color: var(--dtm-muted);\n cursor: pointer;\n flex: 0 0 auto;\n}\n.dtm-cp-loop:active { transform: translate(1px,1px); }\n.dtm-cp-loop--on {\n border-color: var(--c-black);\n background: var(--dtm-gold);\n color: var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n}\n\n/* \u30E1\u30BF\u60C5\u5831 (BPM) */\n.dtm-cp-meta {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .12em;\n color: var(--dtm-muted);\n}\n\n/* \u30B9\u30AF\u30ED\u30FC\u30EB\u30A8\u30EA\u30A2 */\n.dtm-cp-scroll {\n position: relative;\n max-height: 180px;\n overflow-y: auto;\n padding: 8px 10px 10px;\n scrollbar-width: none;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n.dtm-cp-scroll::-webkit-scrollbar { display: none; }\n\n/* \u30BB\u30AF\u30B7\u30E7\u30F3\u898B\u51FA\u3057 \u2014 \u30BB\u30AF\u30B7\u30E7\u30F3\u8272\u306E\u5E2F\u3068\u30D4\u30AF\u30BB\u30EB\u30DE\u30FC\u30AB\u30FC */\n.dtm-cp-section {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .14em;\n margin-top: 8px;\n padding: 1px 8px 1px 5px;\n color: var(--cp-fg, var(--dtm-text));\n border-left: 4px solid var(--cp-fg, var(--dtm-text));\n background: linear-gradient(90deg, var(--cp-bg, transparent), transparent);\n align-self: flex-start;\n}\n.dtm-cp-section::before {\n content: \"\u25A0\";\n margin-right: 5px;\n}\n\n/* \u5C0F\u7BC0\u884C */\n.dtm-cp-bar {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 2px;\n margin-top: 2px;\n}\n\n/* \u5C0F\u7BC0\u533A\u5207\u308A\u30D1\u30A4\u30D7 */\n.dtm-cp-pipe {\n font-size: 13px;\n color: rgba(255, 255, 255, 0.35);\n font-family: var(--dtm-font);\n font-weight: bold;\n margin: 0 4px;\n user-select: none;\n}\n\n/* \u30B3\u30FC\u30C9\u30BB\u30EB \u2014 \u30B2\u30FC\u30E0\u306E\u30DC\u30BF\u30F3\u98A8\u30C1\u30C3\u30D7\uFF08\u30BF\u30C3\u30D7\u3067\u305D\u3053\u304B\u3089\u518D\u751F\uFF09 */\n.dtm-cp-chord {\n display: inline-block;\n font-family: var(--dtm-font);\n font-size: 12px;\n padding: 2px 5px;\n border: 2px solid transparent;\n color: var(--cp-fg, var(--dtm-text));\n background: var(--cp-bg, transparent);\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n}\n.dtm-cp-chord:not(.dtm-cp-chord--dead):hover {\n border-color: var(--cp-fg, var(--dtm-text));\n}\n.dtm-cp-chord:not(.dtm-cp-chord--dead):active {\n transform: translate(1px,1px);\n}\n.dtm-cp-chord:focus-visible {\n outline: 2px solid var(--c-white);\n outline-offset: 0;\n}\n.dtm-cp-chord--dead { cursor: default; }\n.dtm-cp-chord--played { opacity: .45; }\n.dtm-cp-chord--active {\n border-color: var(--c-black);\n color: var(--c-black);\n background: var(--cp-fg, var(--dtm-primary));\n box-shadow: 2px 2px 0 var(--c-black);\n opacity: 1;\n}\n";
4995
+ declare const DAW_CSS = "\n@font-face {\n font-family: 'k8x12';\n src: url('https://db.onlinewebfonts.com/t/777630d46640dc5a928ea833c2fcb875.woff2') format('woff2'),\n url('https://db.onlinewebfonts.com/t/777630d46640dc5a928ea833c2fcb875.woff') format('woff'),\n url('https://db.onlinewebfonts.com/t/777630d46640dc5a928ea833c2fcb875.ttf') format('truetype');\n font-weight: normal;\n font-style: normal;\n}\n\n/* ====================================================\n PIXEL MUSIC STUDIO \u2014 \u30C9\u30C3\u30C8\u7D75UI\u30B7\u30B9\u30C6\u30E0\n PICO-8\u30AB\u30E9\u30FC\u30D1\u30EC\u30C3\u30C8\u30FB\u7F8E\u54B2\u30D5\u30A9\u30F3\u30C8\u30FB\u30B2\u30FC\u30E0\u30A6\u30A3\u30F3\u30C9\u30A6\u67A0\n ==================================================== */\n\n/* \u30C7\u30B6\u30A4\u30F3\u30C8\u30FC\u30AF\u30F3\u306F\u7DE8\u96C6UI\u672C\u4F53\uFF08.dtm-daw\uFF09\u306B\u52A0\u3048\u3001\u305D\u306E\u5916\u5074\u306B\u5DEE\u3057\u8FBC\u307E\u308C\u308B\n \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC\uFF08.dtm-controlbar\uFF09\u306B\u3082\u4F9B\u7D66\u3059\u308B\u3002mountPresetSelect /\n mountModeSwitch \u306EUI\u306F .dtm-daw \u306E\u5144\u5F1F\u3068\u3057\u3066\u7F6E\u304B\u308C\u308B\u305F\u3081\u3001\u3053\u3053\u3067\u914D\u3089\u306A\u3044\u3068\n var(--dtm-*) \u304C\u89E3\u6C7A\u3067\u304D\u305A\u7121\u88C5\u98FE\uFF08\u767D\u5730\u30FB\u65E2\u5B9A\u30D5\u30A9\u30F3\u30C8\uFF09\u306B\u306A\u3063\u3066\u3057\u307E\u3046\u3002\n \u518D\u751F\u5C02\u7528\u30D3\u30E5\u30FC\u306E\u30E2\u30FC\u30C0\u30EB\uFF0F\u5229\u7528\u898F\u7D04\u30AB\u30D0\u30FC\u3001\u6B4C\u58F0\u30E2\u30C7\u30EB\u540D\u306E\u5439\u304D\u51FA\u3057(.dtm-player-balloon)\n \u30AC\u30A4\u30C9\u30C4\u30A2\u30FC\u306E\u6697\u5E55(.dtm-tour)\u306F document.body \u76F4\u4E0B\u3078\u91CD\u306D\u308B\u305F\u3081\u3001.dtm-daw \u306E\u5916\u306B\u51FA\u308B\u3002\n \u3053\u308C\u3089\u3082\u540C\u69D8\u306B\u30C8\u30FC\u30AF\u30F3\u3092\u4F9B\u7D66\u3057\u306A\u3044\u3068\u7121\u88C5\u98FE\uFF08\u67A0\u7DDA\u306A\u3057\u30FB\u6587\u5B57\u8272\u4E0D\u660E\u306E\u767D\u3044\u7BB1\uFF09\u306B\u306A\u308B\u3002 */\n.dtm-daw,\n.dtm-controlbar,\n.dtm-modal-overlay,\n.dtm-consent-overlay,\n.dtm-chord-player,\n.dtm-player-balloon,\n.dtm-tour {\n /* PICO-8 16\u8272\u30D1\u30EC\u30C3\u30C8\u3088\u308A */\n --c-black: #000000;\n --c-navy: #1d2b53;\n --c-purple: #7e2553;\n --c-dkgreen: #008751;\n --c-brown: #ab5236;\n --c-dkgray: #5f574f;\n --c-gray: #c2c3c7;\n --c-white: #fff1e8;\n --c-red: #ff004d;\n --c-orange: #ffa300;\n --c-yellow: #ffec27;\n --c-green: #00e436;\n --c-cyan: #29adff;\n --c-lavend: #83769c;\n --c-pink: #ff77a8;\n --c-peach: #ffccaa;\n\n /* \u30BB\u30DE\u30F3\u30C6\u30A3\u30C3\u30AF\u30C8\u30FC\u30AF\u30F3 */\n --dtm-bg: var(--c-black);\n --dtm-surface: var(--c-navy);\n --dtm-deep: #0a0f1f;\n --dtm-border: var(--c-cyan);\n --dtm-border2: var(--c-dkgray);\n --dtm-text: var(--c-white);\n --dtm-muted: var(--c-lavend);\n --dtm-primary: var(--c-cyan);\n --dtm-pfg: var(--c-black);\n --dtm-danger: var(--c-red);\n --dtm-success: var(--c-green);\n --dtm-accent: var(--c-pink);\n --dtm-gold: var(--c-yellow);\n --dtm-warn: var(--c-orange);\n --dtm-tap: 40px;\n --dtm-gap: 6px;\n --dtm-font: 'k8x12',ui-monospace,monospace;\n}\n\n.dtm-daw {\n box-sizing: border-box;\n font-family: var(--dtm-font);\n font-size: 14px;\n line-height: 1.6;\n letter-spacing: .06em;\n color: var(--dtm-text);\n background: var(--dtm-bg);\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n padding: 0;\n image-rendering: pixelated;\n -webkit-font-smoothing: none;\n -moz-osx-font-smoothing: unset;\n font-smooth: never;\n -webkit-tap-highlight-color: transparent;\n}\n.dtm-daw *,\n.dtm-daw *::before,\n.dtm-daw *::after { box-sizing: border-box; }\n\n/* \u2500\u2500\u2500 \u30EC\u30A4\u30A2\u30A6\u30C8\uFF08\u7DE8\u96C6\u30D8\u30C3\u30C9\u306E\u8CBC\u308A\u4ED8\u3051\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n \u30D1\u30CD\u30EB\u306F\u7E26\u306B\u7A4D\u3080\u3057\u304B\u306A\u3044\u306E\u3067\u3001\u958B\u304F\u307B\u3069\u30D4\u30A2\u30CE\u30ED\u30FC\u30EB\u304C\u753B\u9762\u5916\u3078\u6D41\u308C\u3066\u3044\u304F\u3002\n \u30D8\u30C3\u30C9\uFF08\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u30FB\u30C4\u30FC\u30EB\u30FB\u30ED\u30FC\u30EB\uFF09\u3092 sticky \u3067\u753B\u9762\u4E0A\u90E8\u306B\u7559\u3081\u308C\u3070\u3001\n \u4F55\u679A\u958B\u3044\u3066\u3082\u30ED\u30FC\u30EB\u3068\u306E\u8DDD\u96E2\u306F0\u306E\u307E\u307E\u306B\u306A\u308B\u3002\n\n \u305F\u3060\u30571\u30AB\u30E9\u30E0\u306E\u3042\u3044\u3060\u3001\u8CBC\u3063\u305F\u30D8\u30C3\u30C9\u306F\u305D\u306E\u9AD8\u3055\u3076\u3093\u753B\u9762\u3092\u5360\u6709\u3057\u7D9A\u3051\u308B\u3002\n \u30D8\u30C3\u30C9\u306E\u9AD8\u3055\u306F\u300C\u56FA\u5B9A\u90E8\u304A\u3088\u305D194px \uFF0B \u30ED\u30FC\u30EB32vh\u300D\u306A\u306E\u3067\u3001\u753B\u9762\u304C\u4F4E\u3044\u307B\u3069\n \u5360\u6709\u7387\u304C\u4E0A\u304C\u308B\uFF08844px\u306755%\u3001667px\u306764%\uFF09\u3002\u5360\u6709\u7387\u304C6\u5272\u3092\u5207\u308B\u7E26760px\u4EE5\u4E0A\u3067\n \u3060\u3051\u8CBC\u308A\u3001\u305D\u308C\u672A\u6E80\u306F\u5F93\u6765\u3069\u304A\u308A\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u3060\u3051\u3092\u8CBC\u308B\u3002\n \uFF08\u6A2A\u306B\u5272\u3063\u3066\u7E26\u306E\u53D6\u308A\u5408\u3044\u3092\u7121\u304F\u30592\u30AB\u30E9\u30E0\u6848\u306F\u3001\u30C7\u30E2\u306E #app \u304C max-w-4xl \u306E\n \u305F\u3081\u4ECA\u306E\u307E\u307E\u3060\u3068\u30ED\u30FC\u30EB\u304C\u7D30\u304F\u306A\u308B\u306E\u3067\u898B\u9001\u3063\u3066\u3044\u308B\u3002\uFF09 */\n.dtm-daw-panels {\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n min-width: 0;\n}\n/* \u8CBC\u3089\u306A\u3044\u753B\u9762\u3067\u306F\u7BB1\u3054\u3068\u7573\u3080\u3002display:contents \u306A\u3089\u4E2D\u8EAB\u304C .dtm-daw \u306E\u76F4\u63A5\u306E\n \u5B50\u306B\u623B\u308B\u306E\u3067\u3001\u4F59\u767D\u3082\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u306E sticky \u57FA\u6E96\u3082\u5F93\u6765\u306E\u307E\u307E\u5909\u308F\u3089\u306A\u3044\u3002 */\n.dtm-daw-head { display: contents; }\n.dtm-topbar {\n position: sticky;\n top: 0;\n z-index: 20;\n}\n@media (min-height: 760px) {\n .dtm-daw-head {\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n min-width: 0;\n position: sticky;\n top: 0;\n z-index: 20;\n /* \u4E0B\u3092\u304F\u3050\u308B\u30D1\u30CD\u30EB\u3092\u900F\u304B\u3055\u306A\u3044\u305F\u3081\u306E\u4E0D\u900F\u660E\u306A\u4E0B\u6577\u304D\u3002\n .dtm-daw \u306E gap \u3076\u3093\u3092 padding \u3067\u57CB\u3081\u3001\u9699\u9593\u304B\u3089\u4E2D\u8EAB\u3092\u898B\u305B\u306A\u3044\u3002 */\n background: var(--dtm-bg);\n padding-bottom: var(--dtm-gap);\n }\n}\n\n/* \u30A8\u30C7\u30A3\u30BF\u81EA\u8EAB\u304C\u5341\u5206\u306B\u5E83\u3044\u3068\u304D\u306F\u3001\u30D8\u30C3\u30C9\u3068\u30D1\u30CD\u30EB\u3092\u5DE6\u53F3\u306B\u4E26\u3079\u3066\u3001\u7E26\u306E\n \u7A4D\u307F\u4E0A\u304C\u308A\u3092\u6A2A\u3078\u9003\u304C\u3059\u3002\u3053\u3046\u306A\u308B\u3068\u30D8\u30C3\u30C9\u306F\u30D1\u30CD\u30EB\u304B\u3089\u7E26\u3092\u596A\u308F\u306A\u3044\u306E\u3067\u3001\n \u753B\u9762\u306E\u9AD8\u3055\u306B\u95A2\u4FC2\u306A\u304F\u8CBC\u308C\u308B\u3057\u3001\u30ED\u30FC\u30EB\u3082\u5E83\u304F\u4F7F\u3048\u308B\n \uFF08.dtm-daw--wide \u306F daw.ts \u306E ResizeObserver \u304C\u4ED8\u3051\u308B\uFF09\u3002 */\n.dtm-daw--wide {\n flex-direction: row;\n align-items: flex-start;\n}\n.dtm-daw--wide .dtm-daw-head {\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n min-width: 0;\n flex: 1 1 auto;\n position: sticky;\n top: 0;\n z-index: 20;\n background: var(--dtm-bg);\n padding-bottom: 0;\n}\n.dtm-daw--wide .dtm-daw-panels {\n flex: 0 0 360px;\n}\n/* 768px \u6642\u70B9\u306E height:420px \u306F max-height:32vh \u306B\u982D\u6253\u3061\u306B\u3055\u308C\u3066\u3044\u305F\u3002\n 2\u30AB\u30E9\u30E0\u3067\u306F\u7E26\u3092\u53D6\u308A\u5408\u308F\u306A\u3044\u306E\u3067\u3001\u305D\u306E\u610F\u56F3\u3069\u304A\u308A\u306E\u9AD8\u3055\u3092\u89E3\u7981\u3059\u308B\n \uFF08\u4F4E\u3044\u753B\u9762\u3067\u306F 45vh \u3067\u982D\u6253\u3061\u306B\u3057\u3066\u753B\u9762\u3092\u98DF\u3044\u6F70\u3055\u306A\u3044\u3088\u3046\u306B\u3059\u308B\uFF09\u3002 */\n.dtm-daw--wide .dtm-roll {\n height: min(420px, 45vh);\n max-height: none;\n}\n\n/* \u2500\u2500\u2500 \u30B2\u30FC\u30E0\u30A6\u30A3\u30F3\u30C9\u30A6\u5171\u901A\u67A0 \u2500\u2500\u2500 */\n/* \u5916\u67A0(\u9ED22px) \u2192 \u8272\u4ED8\u304D2px border \u2192 \u5185\u67A0(\u9ED2inset2px) \u306E3\u91CD\u69CB\u9020 */\n.dtm-win {\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n background: var(--dtm-surface);\n}\n\n/* \u2500\u2500\u2500 \u5171\u901A\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */\n.dtm-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n min-height: var(--dtm-tap);\n min-width: var(--dtm-tap);\n padding: 0 10px;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-surface);\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 13px;\n text-transform: uppercase;\n letter-spacing: .12em;\n cursor: pointer;\n user-select: none;\n white-space: nowrap;\n box-shadow: 3px 3px 0 var(--c-black);\n transition: none;\n}\n.dtm-btn:active { transform: translate(3px,3px); box-shadow: none; }\n.dtm-btn:disabled { opacity: .3; cursor: default; box-shadow: none; }\n.dtm-btn--ghost { background: transparent; border-color: var(--dtm-border2); }\n.dtm-btn--primary { border-color: var(--dtm-primary); background: var(--dtm-primary); color: var(--dtm-pfg); }\n.dtm-btn--success { border-color: var(--dtm-success); background: var(--dtm-success); color: var(--c-black); }\n.dtm-btn--danger { border-color: var(--dtm-danger); background: var(--dtm-danger); color: var(--c-white); }\n.dtm-btn--accent { border-color: var(--dtm-accent); background: var(--dtm-accent); color: var(--c-black); }\n.dtm-btn--icon { padding: 0; }\n\n/* \u2500\u2500\u2500 \u30A2\u30A4\u30B3\u30F3\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */\n.dtm-iconbtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--dtm-tap);\n height: var(--dtm-tap);\n flex: 0 0 auto;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-surface);\n color: var(--dtm-text);\n font-size: 16px;\n cursor: pointer;\n box-shadow: 3px 3px 0 var(--c-black);\n}\n.dtm-iconbtn:active { transform: translate(3px,3px); box-shadow: none; }\n.dtm-iconbtn:disabled { opacity: .3; cursor: default; box-shadow: none; }\n\n/* \u2500\u2500\u2500 \u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u30D0\u30FC\uFF08HUD\u30B9\u30BF\u30A4\u30EB\uFF09 \u2500\u2500\u2500 */\n.dtm-topbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--dtm-gap);\n padding: 6px;\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-success),\n 4px 4px 0 var(--c-black);\n}\n.dtm-topbar-row1 {\n display: flex;\n align-items: center;\n gap: var(--dtm-gap);\n flex-basis: 100%;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n.dtm-topbar-row1::-webkit-scrollbar { display: none; }\n.dtm-topbar-row1 > * { flex-shrink: 0; }\n.dtm-topbar-row1 > .dtm-grow { flex-shrink: 1; }\n\n/* PLAY\u30DC\u30BF\u30F3 \u2014 \u30B2\u30FC\u30E0\u306E\u300C\u6C7A\u5B9A\u30DC\u30BF\u30F3\u300D\u7684\u5B58\u5728\u611F */\n.dtm-play {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--dtm-tap);\n height: var(--dtm-tap);\n flex: 0 0 auto;\n border: 2px solid var(--c-black);\n background: var(--dtm-success);\n color: var(--c-black);\n cursor: pointer;\n box-shadow: 0 0 0 2px var(--dtm-success), 4px 4px 0 var(--c-black);\n}\n.dtm-play:active { transform: translate(4px,4px); box-shadow: none; }\n.dtm-play:disabled { opacity: .35; cursor: default; box-shadow: none; }\n.dtm-play--stop {\n background: var(--dtm-danger);\n box-shadow: 0 0 0 2px var(--dtm-danger), 4px 4px 0 var(--c-black);\n}\n.dtm-rec { color: var(--dtm-danger); }\n\n/* BPM \u2014 \u30C7\u30B8\u30BF\u30EB\u30AB\u30A6\u30F3\u30BF\u30FC\u98A8 */\n.dtm-label {\n font-family: var(--dtm-font);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .14em;\n color: var(--dtm-muted);\n white-space: nowrap;\n}\n.dtm-checkbox-label {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: var(--dtm-font);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .12em;\n color: var(--dtm-muted);\n cursor: pointer;\n user-select: none;\n margin-top: 4px;\n}\n.dtm-checkbox-label:hover { color: var(--dtm-text); }\n\n/* \u2500\u2500\u2500 \u4F5C\u66F2\u3059\u308B\u30BB\u30AF\u30B7\u30E7\u30F3\u306E\u9078\u629E\uFF08\u30A4\u30F3\u30C8\u30ED\u30FBA\u30E1\u30ED\u2026\u306E\u30C1\u30A7\u30C3\u30AF\uFF09 \u2500\u2500\u2500 */\n.dtm-checks {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 10px;\n align-items: center;\n}\n.dtm-check {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-family: var(--dtm-font);\n font-size: 11px;\n color: var(--dtm-muted);\n cursor: pointer;\n user-select: none;\n white-space: nowrap;\n}\n.dtm-check:hover { color: var(--dtm-text); }\n.dtm-check input {\n width: 13px;\n height: 13px;\n accent-color: var(--dtm-success);\n cursor: pointer;\n flex-shrink: 0;\n}\n.dtm-info-table {\n border-collapse: collapse;\n margin: 6px 0;\n font-size: 11px;\n width: 100%;\n}\n.dtm-info-table th,\n.dtm-info-table td {\n border: 1px solid var(--dtm-border);\n padding: 3px 6px;\n text-align: left;\n white-space: nowrap;\n}\n.dtm-info-table th { color: var(--dtm-muted); font-weight: normal; }\n.dtm-hint {\n font-family: var(--dtm-font);\n font-size: 10px;\n color: var(--dtm-muted);\n white-space: nowrap;\n}\n.dtm-checkbox-label--sub { margin-left: 20px; font-size: 10px; }\n.dtm-checkbox {\n width: 14px;\n height: 14px;\n accent-color: var(--dtm-success);\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.dtm-toggle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: var(--dtm-font);\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: .1em;\n color: var(--dtm-muted);\n cursor: pointer;\n}\n.dtm-toggle input { width: 16px; height: 16px; accent-color: var(--dtm-accent); }\n\n/* \u2500\u2500\u2500 \u30C4\u30FC\u30EB\u30C9\u30C3\u30AF\uFF08\u88C5\u5099\u30B9\u30ED\u30C3\u30C8\u98A8\uFF09 \u2500\u2500\u2500 */\n.dtm-tooldock {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--dtm-gap);\n padding: 6px;\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-border2),\n 4px 4px 0 var(--c-black);\n}\n.dtm-sep {\n width: 2px; align-self: stretch;\n background: var(--dtm-border2); margin: 2px;\n}\n.dtm-row .dtm-label[data-dtm] { min-width: 48px; text-align: center; }\n\n/* \u2500\u2500\u2500 \u30BB\u30B0\u30E1\u30F3\u30C8\uFF08\u30A2\u30A4\u30C6\u30E0\u30B9\u30ED\u30C3\u30C8\uFF09 \u2500\u2500\u2500 */\n.dtm-seg {\n display: inline-flex;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-deep);\n box-shadow: 3px 3px 0 var(--c-black);\n}\n.dtm-segbtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--dtm-tap);\n height: var(--dtm-tap);\n border: none;\n border-right: 2px solid var(--dtm-border2);\n background: transparent;\n color: var(--dtm-muted);\n cursor: pointer;\n}\n.dtm-segbtn:last-child { border-right: none; }\n.dtm-segbtn--active {\n background: var(--dtm-gold);\n color: var(--c-black);\n}\n.dtm-segbtn:not(.dtm-segbtn--active):active { background: var(--dtm-border2); }\n\n/* \u2500\u2500\u2500 \u30D5\u30A9\u30FC\u30E0\u8981\u7D20 \u2500\u2500\u2500 */\n.dtm-select, .dtm-input, .dtm-textarea {\n min-height: var(--dtm-tap);\n padding: 4px 8px;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-deep);\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 13px;\n letter-spacing: .06em;\n box-shadow: inset 2px 2px 0 var(--c-black);\n}\n.dtm-select:focus, .dtm-input:focus, .dtm-textarea:focus {\n outline: none;\n border-color: var(--dtm-primary);\n}\n.dtm-input--num { width: 64px; text-align: center; font-size: 16px; }\n/* \u4ED6\u306E\u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u3068\u540C\u3058\u884C\u306B\u7F6E\u304F\u30D7\u30EB\u30C0\u30A6\u30F3\uFF08\u697D\u5668\u30FB\u6B4C\u5531\u30E2\u30C7\u30EB\uFF09 */\n.dtm-select--half { flex: 1 1 120px; min-width: 0; max-width: 200px; }\n.dtm-textarea { width: 100%; min-height: 56px; resize: vertical; line-height: 1.7; }\n.dtm-textarea.dtm-grow { width: 0; }\n.dtm-range { height: var(--dtm-tap); accent-color: var(--dtm-primary); }\n.dtm-range:disabled { opacity: .35; cursor: default; }\n\n/* \u2500\u2500\u2500 \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC\uFF08\u697D\u5668\u30D7\u30EA\u30BB\u30C3\u30C8 / \u30E2\u30FC\u30C9\u5207\u66FF\u306A\u3069\u306E\u5DEE\u3057\u8FBC\u307FUI\uFF09 \u2500\u2500\u2500 */\n.dtm-controlbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--dtm-gap);\n padding: 6px 8px;\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-border2),\n 4px 4px 0 var(--c-black);\n margin-bottom: var(--dtm-gap);\n}\n.dtm-controlbar-label {\n font-family: var(--dtm-font);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .14em;\n color: var(--dtm-accent);\n white-space: nowrap;\n flex-shrink: 0;\n}\n.dtm-controlbar .dtm-select { flex: 1 1 160px; }\n\n/* \u30E2\u30FC\u30C9\u5207\u66FF\uFF08\u30C6\u30AD\u30B9\u30C8\u7248\u30BB\u30B0\u30E1\u30F3\u30C8\uFF09 */\n.dtm-modeseg {\n display: inline-flex;\n border: 2px solid var(--dtm-border2);\n box-shadow: 3px 3px 0 var(--c-black);\n}\n.dtm-modebtn {\n min-height: var(--dtm-tap);\n padding: 0 14px;\n border: none;\n border-right: 2px solid var(--dtm-border2);\n background: var(--dtm-deep);\n color: var(--dtm-muted);\n font-family: var(--dtm-font);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .12em;\n cursor: pointer;\n}\n.dtm-modebtn:last-child { border-right: none; }\n.dtm-modebtn--active { background: var(--dtm-primary); color: var(--dtm-pfg); }\n.dtm-modebtn:not(.dtm-modebtn--active):active { background: var(--dtm-border2); }\n\n/* \u2500\u2500\u2500 \u30C8\u30E9\u30C3\u30AF\u30D4\u30EB\uFF08\u756A\u53F7\u30DC\u30BF\u30F3\u3001\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u30D0\u30FC2\u884C\u76EE\uFF09 \u2500\u2500\u2500 */\n.dtm-tracks {\n flex-basis: 100%;\n display: flex;\n flex-wrap: nowrap;\n gap: 4px;\n align-items: flex-end;\n}\n.dtm-pill {\n --dtm-pill-color: var(--dtm-primary);\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 1 1 0;\n min-width: 0;\n height: 24px;\n padding: 0;\n border: 2px solid var(--c-black);\n background: color-mix(in srgb, var(--dtm-pill-color) 22%, #0e121e);\n color: color-mix(in srgb, var(--c-white) 60%, transparent);\n font-family: var(--dtm-font);\n font-size: 11px;\n font-weight: bold;\n cursor: pointer;\n box-shadow: 1px 1px 0 var(--c-black);\n opacity: 0.55;\n transition: opacity 120ms ease, background 120ms ease, transform 120ms ease;\n}\n.dtm-pill:hover:not(.dtm-pill--active) {\n opacity: 0.85;\n background: color-mix(in srgb, var(--dtm-pill-color) 45%, #0e121e);\n color: var(--c-white);\n}\n/* \u30A2\u30AF\u30C6\u30A3\u30D6\u9078\u629E = \u9BAE\u660E\u306A\u30C8\u30E9\u30C3\u30AF\u8272 + \u30B4\u30FC\u30EB\u30C9\u67A0 + \u30B0\u30ED\u30FC + \u4E0A\u6607\u7ACB\u4F53\u30BF\u30D6\u8868\u73FE */\n.dtm-pill--active {\n opacity: 1;\n height: 28px;\n background: var(--dtm-pill-color);\n color: #ffffff;\n text-shadow: 1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000;\n border-color: var(--dtm-gold);\n box-shadow:\n 0 0 0 1.5px var(--dtm-gold),\n 0 0 10px color-mix(in srgb, var(--dtm-pill-color) 70%, transparent),\n 2px 2px 0 var(--c-black);\n z-index: 1;\n transform: translateY(-2px);\n}\n.dtm-pill--active::before {\n content: '';\n position: absolute;\n top: -2px;\n left: 2px;\n right: 2px;\n height: 2px;\n background: #ffffff;\n border-radius: 1px;\n opacity: 0.85;\n}\n.dtm-pill:not(.dtm-pill--active):active { transform: translate(1px,1px); box-shadow: none; }\n/* \u30DC\u30FC\u30AB\u30EB\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u308B\u30C8\u30E9\u30C3\u30AF\u306E\u30BF\u30D6\u306B\u3001\u3046\u3063\u3059\u3089\u58F0\u306E\u30A2\u30A4\u30B3\u30F3\u3092\u91CD\u306D\u308B\uFF08\u80CC\u666F\u8272\u30FB\u30B5\u30A4\u30BA\u306F\u5909\u3048\u306A\u3044\uFF09 */\n.dtm-pill--vocal::after {\n content: '';\n position: absolute;\n inset: 0;\n background-image: var(--dtm-pill-icon);\n background-size: contain;\n background-repeat: no-repeat;\n background-position: right center;\n opacity: 0.4;\n pointer-events: none;\n}\n.dtm-pill__label {\n position: relative;\n z-index: 1;\n}\n/* \u518D\u751F\u4E2D\u3001\u5B9F\u969B\u306B\u767A\u97F3\u3057\u305F\u77AC\u9593\u3060\u3051\u70B9\u706F\uFF08\u3069\u306E\u30BF\u30D6\u304C\u4ECA\u9CF4\u3063\u3066\u3044\u308B\u304B\u8996\u899A\u7684\u306B\u5206\u304B\u308B\u3088\u3046\u306B\uFF09 */\n.dtm-pill--sounding {\n filter: brightness(1.6);\n transition: filter 30ms linear;\n}\n\n/* \u2500\u2500\u2500 \u30D4\u30A2\u30CE\u30ED\u30FC\u30EB\uFF08\u30C8\u30E9\u30C3\u30AB\u30FC\u98A8\uFF09 \u2500\u2500\u2500 */\n.dtm-roll-wrap { display: flex; gap: var(--dtm-gap); }\n.dtm-roll {\n position: relative;\n flex: 1 1 auto;\n height: 32vh;\n max-height: 32vh;\n background: var(--dtm-deep);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-border2),\n 4px 4px 0 var(--c-black);\n overflow: hidden;\n}\n/* \u30AB\u30B9\u30BF\u30E0\u80CC\u666F\u753B\u50CF\u30EC\u30A4\u30E4\u30FC\uFF08\u753B\u50CF\u81EA\u4F53\u3092\u534A\u900F\u660E\u5316\u3057\u3001\u30AD\u30E3\u30F3\u30D0\u30B9\u5074\u306E\u5857\u308A\u306F\u7DAD\u6301\uFF09 */\n.dtm-roll::before {\n content: '';\n position: absolute;\n inset: 0;\n background-image: var(--dtm-roll-bg-image, none);\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n opacity: var(--dtm-roll-bg-opacity, 0.4);\n pointer-events: none;\n}\n.dtm-vscroll {\n position: relative;\n width: 20px;\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n cursor: pointer;\n flex: 0 0 auto;\n touch-action: none;\n}\n.dtm-vscroll-thumb, .dtm-hscroll-thumb {\n position: absolute;\n background: var(--dtm-primary);\n min-width: 20px;\n min-height: 20px;\n}\n.dtm-vscroll-thumb { left: 0; width: 100%; }\n.dtm-hscroll {\n position: relative;\n width: 100%; height: 20px;\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n cursor: pointer;\n touch-action: none;\n}\n.dtm-hscroll-thumb { top: 0; height: 100%; }\n\n/* \u2500\u2500\u2500 \u30D1\u30CD\u30EB\uFF08RPG\u30C0\u30A4\u30A2\u30ED\u30B0\u30A6\u30A3\u30F3\u30C9\u30A6\uFF09 \u2500\u2500\u2500 */\n.dtm-panel {\n background: var(--dtm-surface);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n overflow: hidden;\n}\n.dtm-panel > summary {\n list-style: none;\n cursor: pointer;\n padding: 0 12px;\n font-family: var(--dtm-font);\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: .14em;\n display: flex;\n align-items: center;\n min-height: var(--dtm-tap);\n background: var(--dtm-deep);\n border-bottom: 2px solid var(--dtm-border2);\n color: var(--dtm-primary);\n gap: 8px;\n}\n.dtm-panel:not([open]) > summary { border-bottom: none; }\n.dtm-panel > summary::-webkit-details-marker { display: none; }\n/* \u5DE6\u7AEF\u30E9\u30A4\u30F3\uFF08\u30B2\u30FC\u30E0UI\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u8272\u5206\u3051\uFF09 */\n.dtm-panel > summary::before {\n content: '';\n display: block;\n width: 4px;\n height: 20px;\n background: var(--dtm-accent);\n flex: 0 0 auto;\n}\n.dtm-panel[open] > summary::before { background: var(--dtm-primary); }\n/* \u6298\u308A\u305F\u305F\u307F\u77E2\u5370 */\n.dtm-panel > summary::after {\n content: \"\u25B6\";\n margin-left: auto;\n color: var(--dtm-muted);\n font-size: 10px;\n}\n.dtm-panel[open] > summary::after { content: \"\u25BC\"; }\n.dtm-panel-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 10px; }\n.dtm-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }\n.dtm-track-body { display: flex; flex-direction: column; gap: 10px; }\n\n/* \u2500\u2500\u2500 \u81EA\u52D5\u4F5C\u66F2\u30D1\u30CD\u30EB\uFF08\u770B\u677F\u6A5F\u80FD\u306A\u306E\u3067\u67A0\u3068\u898B\u51FA\u3057\u3092 success \u8272\u3067\u5DEE\u5225\u5316\u3059\u308B\uFF09 \u2500\u2500\u2500 */\n.dtm-panel--compose {\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-success),\n 4px 4px 0 var(--c-black);\n}\n.dtm-panel--compose > summary { color: var(--dtm-success); }\n.dtm-panel--compose > summary::before,\n.dtm-panel--compose[open] > summary::before {\n background: var(--dtm-success);\n}\n\n/* \u2500\u2500\u2500 \u30A2\u30AF\u30C6\u30A3\u30D6\u30C8\u30E9\u30C3\u30AF\u8272\uFF08\u500B\u5225\u30C8\u30E9\u30C3\u30AF\u8A2D\u5B9A\u30D1\u30CD\u30EB\u306E\u5DE6\u7AEF\u30E9\u30A4\u30F3\uFF09 \u2500\u2500\u2500 */\n.dtm-panel--track > summary::before,\n.dtm-panel--track[open] > summary::before {\n background: var(--dtm-track-color, var(--dtm-primary));\n}\n\n/* \u2500\u2500\u2500 MML\u51FA\u529B\uFF08CRT\u30BF\u30FC\u30DF\u30CA\u30EB\uFF09 \u2500\u2500\u2500 */\n.dtm-output {\n background: var(--c-black);\n color: var(--dtm-success);\n border: 2px solid var(--dtm-success);\n padding: 10px;\n box-shadow: 0 0 0 2px var(--c-black), 4px 4px 0 var(--c-black);\n}\n.dtm-output::before {\n content: \"C:\\> MML OUTPUT\";\n display: block;\n font-size: 11px;\n color: var(--dtm-muted);\n letter-spacing: .14em;\n margin-bottom: 6px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--dtm-border2);\n}\n.dtm-output pre {\n margin: 0;\n background: transparent;\n padding: 0;\n overflow-x: auto;\n font-family: var(--dtm-font);\n font-size: 12px;\n line-height: 1.8;\n color: var(--dtm-success);\n}\n.dtm-output-label {\n font-size: 11px;\n color: var(--dtm-muted);\n font-family: var(--dtm-font);\n margin-top: 10px;\n}\n.dtm-output-label:first-of-type {\n margin-top: 0;\n}\n.dtm-output-row { display: flex; gap: 8px; align-items: flex-start; margin-top: 6px; }\n.dtm-output-row pre { flex: 1; }\n.dtm-output-scroll { max-height: 240px; overflow-y: auto; }\n\n/* \u2500\u2500\u2500 \u30ED\u30FC\u30C7\u30A3\u30F3\u30B0\u30AA\u30FC\u30D0\u30FC\u30EC\u30A4 \u2500\u2500\u2500 */\n.dtm-overlay {\n position: absolute; inset: 0; z-index: 10;\n background: rgba(0,0,0,.92);\n display: flex; align-items: center; justify-content: center;\n flex-direction: column; gap: 14px;\n pointer-events: auto;\n cursor: wait;\n}\n.dtm-overlay[hidden] { display: none; }\n.dtm-overlay::before {\n content: '\u30ED\u30FC\u30C9\u4E2D';\n font-family: var(--dtm-font);\n font-size: 13px;\n color: var(--dtm-primary);\n text-transform: uppercase;\n letter-spacing: .25em;\n animation: dtm-blink 1s steps(1) infinite;\n}\n/* 8\u30D6\u30ED\u30C3\u30AF\u523B\u307F\u3067\u57CB\u307E\u308B\u30D4\u30AF\u30BB\u30EB\u30D0\u30FC */\n.dtm-spinner {\n width: 96px; height: 12px;\n position: relative;\n background: var(--c-navy);\n border: 2px solid var(--dtm-primary);\n box-shadow: 0 0 0 2px var(--c-black), 4px 4px 0 var(--c-black);\n}\n.dtm-spinner::after {\n content: '';\n position: absolute;\n left: 0; top: 0; height: 100%;\n background: var(--dtm-primary);\n animation: dtm-load 1.6s steps(8) infinite;\n}\n@keyframes dtm-load { 0%{width:0} 100%{width:100%} }\n/* \u9032\u6357\u304C\u78BA\u5B9A\u3057\u305F\u3089\u7121\u9650\u30EB\u30FC\u30D7\u6F14\u51FA\u3092\u6B62\u3081\u3001\u5B9F\u6E2C\u5024\u3067\u5857\u308A\u3064\u3076\u3059 */\n.dtm-spinner--determinate::after { display: none; }\n.dtm-spinner-fill {\n position: absolute;\n left: 0; top: 0; height: 100%;\n width: 0;\n background: var(--dtm-primary);\n transition: width .12s steps(8);\n}\n.dtm-loading-label {\n font-family: var(--dtm-font);\n font-size: 11px;\n color: var(--dtm-primary);\n letter-spacing: .15em;\n min-height: 1em;\n}\n.dtm-overlay-skip-btn {\n margin-top: 12px;\n min-height: 32px;\n font-size: 11px;\n font-family: var(--dtm-font);\n padding: 0 12px;\n background: var(--dtm-surface);\n border: 2px solid var(--dtm-border2);\n color: var(--dtm-muted);\n box-shadow: 2px 2px 0 var(--c-black);\n cursor: pointer;\n pointer-events: auto;\n}\n.dtm-overlay-skip-btn:hover {\n color: var(--dtm-text);\n border-color: var(--dtm-primary);\n}\n.dtm-overlay-skip-btn:active {\n transform: translate(2px, 2px);\n box-shadow: none;\n}\n.dtm-overlay-skip-btn:disabled {\n opacity: .3;\n cursor: default;\n box-shadow: none;\n transform: none;\n}\n.dtm-topbar-loading {\n display: none;\n font-family: var(--dtm-font);\n font-size: 11px;\n color: var(--dtm-primary);\n margin-left: 12px;\n letter-spacing: .15em;\n align-self: center;\n}\n.dtm-topbar.is-loading .dtm-topbar-loading {\n display: inline-block;\n}\n.dtm-topbar.is-loading {\n pointer-events: none;\n opacity: 0.7;\n}\n\n@keyframes dtm-blink { 0%,100%{opacity:1} 50%{opacity:0} }\n.dtm-blink { animation: dtm-blink 1s steps(1) infinite; }\n\n/* \u2500\u2500\u2500 \u97F3\u5272\u308C\u691C\u77E5\u30D0\u30C3\u30B8 \u2500\u2500\u2500 \u30AF\u30EA\u30C3\u30D7\u767A\u751F\u4E2D\u3060\u3051\u8868\u793A\u3055\u308C\u308B\u8B66\u544A\u30DC\u30BF\u30F3\u3002\u30AF\u30EA\u30C3\u30AF\u3067\u6D88\u305B\u308B\u3002 */\n.dtm-clip-badge {\n flex: 0 0 auto;\n min-height: 24px;\n padding: 0 8px;\n border: 2px solid var(--c-black);\n background: var(--dtm-danger);\n color: var(--c-white);\n font-family: var(--dtm-font);\n font-size: 10px;\n letter-spacing: .1em;\n cursor: pointer;\n box-shadow: 0 0 0 2px var(--dtm-danger), 2px 2px 0 var(--c-black);\n animation: dtm-blink .5s steps(1) infinite;\n}\n.dtm-clip-badge:active { transform: translate(2px,2px); box-shadow: none; }\n\n/* \u2500\u2500\u2500 \u30A4\u30F3\u30D5\u30A9\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */\n.dtm-infobtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex: 0 0 auto;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-surface);\n color: var(--dtm-muted);\n cursor: pointer;\n box-shadow: 1px 1px 0 var(--c-black);\n padding: 0;\n margin: 0;\n}\n.dtm-infobtn:hover {\n color: var(--dtm-primary);\n border-color: var(--dtm-primary);\n}\n.dtm-infobtn:active {\n transform: translate(1px, 1px);\n box-shadow: none;\n}\n\n/* \u2500\u2500\u2500 \u89E3\u8AAC\u30E2\u30FC\u30C0\u30EB \u2500\u2500\u2500 */\n.dtm-modal-overlay {\n position: fixed;\n inset: 0;\n z-index: 10000;\n background: rgba(0, 0, 0, 0.7);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n backdrop-filter: blur(2px);\n /* body\u76F4\u4E0B\u306B\u91CD\u306D\u305F\u5834\u5408\uFF08\u518D\u751F\u5C02\u7528\u30D3\u30E5\u30FC\uFF09\u3067\u3082\u6587\u5B57\u8272\u30FB\u30D5\u30A9\u30F3\u30C8\u304C\n .dtm-daw \u304B\u3089\u7D99\u627F\u3067\u304D\u306A\u3044\u305F\u3081\u3001\u3053\u3053\u3067\u660E\u793A\u3059\u308B\u3002 */\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n}\n.dtm-modal-overlay[hidden] {\n display: none !important;\n}\n\n/* \u2500\u2500\u2500 \u5229\u7528\u898F\u7D04\u540C\u610F\u30AB\u30D0\u30FC \u2500\u2500\u2500 */\n.dtm-consent-overlay {\n position: fixed;\n inset: 0;\n z-index: 10100;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n backdrop-filter: blur(2px);\n /* body\u76F4\u4E0B\u306B\u91CD\u306D\u308B\u305F\u3081 .dtm-daw \u304B\u3089\u7D99\u627F\u3067\u304D\u306A\u3044\u6587\u5B57\u8272\u30FB\u30D5\u30A9\u30F3\u30C8\u3092\u660E\u793A\u3002 */\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n}\n.dtm-consent-overlay[hidden] {\n display: none !important;\n}\n.dtm-consent-modal {\n max-width: 450px;\n width: 100%;\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n background: var(--dtm-surface);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n overflow-y: auto;\n}\n.dtm-consent-header {\n background: var(--dtm-deep);\n color: var(--dtm-text);\n padding: 8px 12px;\n border-bottom: 2px solid var(--c-black);\n font-weight: bold;\n text-align: center;\n font-size: 14px;\n}\n.dtm-consent-body {\n padding: 12px 16px;\n font-size: 13px;\n line-height: 1.6;\n}\n.dtm-consent-body a {\n color: var(--dtm-primary);\n text-decoration: underline;\n}\n.dtm-consent-body a:hover {\n color: var(--dtm-accent);\n}\n.dtm-consent-footer {\n padding: 8px;\n border-top: 2px solid var(--c-black);\n background: var(--dtm-deep);\n display: flex;\n justify-content: center;\n}\n\n.dtm-confirm-footer {\n padding: 8px 12px;\n border-top: 2px solid var(--c-black);\n background: var(--dtm-deep);\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.dtm-modal {\n max-width: 500px;\n width: 100%;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n background: var(--dtm-surface);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n overflow: hidden;\n}\n.dtm-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--dtm-deep);\n padding: 8px 12px;\n border-bottom: 2px solid var(--c-black);\n}\n.dtm-modal-title {\n font-family: var(--dtm-font);\n font-size: 14px;\n color: var(--dtm-gold);\n font-weight: bold;\n}\n.dtm-modal-close {\n background: transparent;\n border: none;\n color: var(--dtm-text);\n font-size: 20px;\n cursor: pointer;\n padding: 0;\n line-height: 1;\n}\n.dtm-modal-close:hover {\n color: var(--dtm-danger);\n}\n.dtm-modal-body {\n padding: 12px;\n overflow-y: auto;\n overflow-x: hidden;\n font-size: 13px;\n line-height: 1.6;\n}\n.dtm-modal-body * {\n max-width: 100%;\n box-sizing: border-box;\n}\n.dtm-modal-body a {\n color: var(--dtm-primary);\n text-decoration: underline;\n}\n.dtm-modal-body a:hover {\n color: var(--dtm-accent);\n}\n.dtm-modal-body h4 {\n margin: 12px 0 6px 0;\n color: var(--dtm-primary);\n font-size: 13px;\n}\n.dtm-modal-body h4:first-child {\n margin-top: 0;\n}\n.dtm-modal-body p {\n margin: 0 0 8px 0;\n}\n.dtm-modal-body ul {\n margin: 0 0 8px 0;\n padding-left: 16px;\n}\n.dtm-modal-body li {\n margin-bottom: 4px;\n}\n.dtm-modal-body code {\n background: var(--dtm-deep);\n color: var(--dtm-accent);\n padding: 1px 4px;\n font-family: var(--dtm-font);\n font-size: 12px;\n}\n.dtm-modal-body pre {\n background: var(--dtm-deep);\n color: var(--dtm-success);\n padding: 8px;\n border: 1px solid var(--dtm-border2);\n margin: 6px 0;\n overflow-x: auto;\n font-family: var(--dtm-font);\n font-size: 12px;\n}\n\n.dtm-modal-sample-box {\n background: var(--dtm-deep);\n border: 1px solid var(--dtm-border2);\n border-radius: 4px;\n padding: 8px 10px;\n margin-bottom: 12px;\n}\n.dtm-modal-sample-box:last-child {\n margin-bottom: 0;\n}\n.dtm-modal-sample-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n.dtm-modal-sample-tag {\n font-family: var(--dtm-font);\n font-size: 11px;\n font-weight: bold;\n color: var(--dtm-accent);\n}\n.dtm-modal-sample-desc {\n margin: 6px 0 0 0;\n font-size: 11px;\n color: var(--dtm-muted);\n}\n.dtm-modal-sample-player-container {\n margin-top: 8px;\n}\n.dtm-modal-sample-player-container:empty {\n margin-top: 0;\n}\n.dtm-modal-sample-player-container .dtm-player {\n border: 1px solid var(--dtm-border2);\n box-shadow: none;\n background: rgba(0, 0, 0, 0.3);\n}\n.dtm-modal-sample-player-container .dtm-player-body {\n max-height: 100px;\n overflow-y: auto;\n}\n\n/* \u2500\u2500\u2500 \u30AC\u30A4\u30C9\u30C4\u30A2\u30FC\uFF08\u30B9\u30DD\u30C3\u30C8\u30E9\u30A4\u30C8\u578B\u30A6\u30A9\u30FC\u30AF\u30B9\u30EB\u30FC\uFF09 \u2500\u2500\u2500 */\n/* \u6697\u5E55\u306F .dtm-tour-spot \u306E\u5DE8\u5927\u306A box-shadow \u3067\u63CF\u304F\u3002box-shadow \u306F\u5F53\u305F\u308A\u5224\u5B9A\u3092\n \u6301\u305F\u306A\u3044\u306E\u3067\u3001\u7D20\u901A\u308A\u3092\u9632\u3050\u906E\u853D\u306F .dtm-tour\uFF08\u5168\u753B\u9762\uFF09\u5074\u304C\u62C5\u5F53\u3059\u308B\u3002 */\n.dtm-tour {\n position: fixed;\n inset: 0;\n z-index: 10050;\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 13px;\n line-height: 1.6;\n letter-spacing: .04em;\n -webkit-font-smoothing: none;\n font-smooth: never;\n -webkit-tap-highlight-color: transparent;\n}\n.dtm-tour * { box-sizing: border-box; max-width: 100%; }\n.dtm-tour-spot {\n position: fixed;\n left: 0;\n top: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n border: 2px solid var(--dtm-gold);\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.74);\n transition: left .18s ease, top .18s ease, width .18s ease, height .18s ease;\n}\n.dtm-tour-bubble {\n position: fixed;\n left: 0;\n top: 0;\n display: flex;\n flex-direction: column;\n background: var(--dtm-surface);\n border: 2px solid var(--c-black);\n box-shadow:\n inset 0 0 0 2px var(--c-black),\n 0 0 0 2px var(--dtm-primary),\n 4px 4px 0 var(--c-black);\n transition: left .18s ease, top .18s ease;\n}\n.dtm-tour-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--dtm-deep);\n padding: 4px 8px;\n border-bottom: 2px solid var(--c-black);\n}\n.dtm-tour-progress {\n font-size: 11px;\n color: var(--dtm-muted);\n}\n.dtm-tour-close {\n background: transparent;\n border: none;\n color: var(--dtm-text);\n font-size: 18px;\n line-height: 1;\n padding: 0 2px;\n cursor: pointer;\n}\n.dtm-tour-close:hover { color: var(--dtm-danger); }\n.dtm-tour-title {\n padding: 8px 10px 0;\n color: var(--dtm-gold);\n font-size: 14px;\n font-weight: bold;\n}\n.dtm-tour-body {\n padding: 6px 10px 8px;\n max-height: 40vh;\n overflow-y: auto;\n}\n.dtm-tour-body p { margin: 0 0 6px; }\n.dtm-tour-body p:last-child { margin-bottom: 0; }\n.dtm-tour-body ul { margin: 0 0 6px; padding-left: 16px; }\n.dtm-tour-body li { margin-bottom: 3px; }\n.dtm-tour-body b { color: var(--dtm-primary); }\n.dtm-tour-foot {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 8px;\n border-top: 2px solid var(--c-black);\n background: var(--dtm-deep);\n}\n.dtm-tour-spacer { flex: 1; }\n.dtm-tour-btn {\n min-height: 32px;\n padding: 0 10px;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-surface);\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 12px;\n letter-spacing: .04em;\n cursor: pointer;\n box-shadow: 2px 2px 0 var(--c-black);\n}\n.dtm-tour-btn:active { transform: translate(2px, 2px); box-shadow: none; }\n.dtm-tour-btn--ghost { background: transparent; }\n.dtm-tour-btn--primary {\n border-color: var(--dtm-primary);\n background: var(--dtm-primary);\n color: var(--dtm-pfg);\n}\n\n/* \u76EE\u7684\u5225\u306E\u5206\u5C90\uFF08\u30C4\u30A2\u30FC\u5192\u982D\u306E\u300C\u4F55\u3092\u3057\u3066\u307F\u305F\u3044\uFF1F\u300D\uFF09\u3002 */\n.dtm-tour-branches {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 8px;\n}\n.dtm-tour-branch {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n width: 100%;\n min-height: var(--dtm-tap);\n padding: 6px 10px;\n border: 2px solid var(--dtm-primary);\n background: var(--dtm-surface);\n color: var(--dtm-text);\n font-family: var(--dtm-font);\n font-size: 13px;\n letter-spacing: .04em;\n text-align: left;\n cursor: pointer;\n box-shadow: 2px 2px 0 var(--c-black);\n}\n.dtm-tour-branch:active { transform: translate(2px, 2px); box-shadow: none; }\n.dtm-tour-branch-label { color: var(--dtm-primary); }\n.dtm-tour-branch-hint { font-size: 11px; color: var(--dtm-muted); }\n\n/* \u2500\u2500\u2500 \u30D8\u30EB\u30D7\u306E\u30CF\u30D6\uFF08\u300C?\u300D\u30DC\u30BF\u30F3\u306E\u30E2\u30FC\u30C0\u30EB\uFF09 \u2500\u2500\u2500 */\n.dtm-help-goals {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 6px 0 4px;\n}\n/* \u76EE\u7684\u30DC\u30BF\u30F3\u306F\u898B\u51FA\u3057\u3068\u88DC\u8DB3\u306E2\u6BB5\u7D44\u307F\u306B\u3059\u308B\u3002.dtm-btn \u306F1\u884C\u524D\u63D0\u306E\n inline-flex \u306A\u306E\u3067\u3001\u3053\u3053\u3060\u3051\u7E26\u4E26\u3073\u30FB\u5DE6\u5BC4\u305B\u30FB\u9AD8\u3055\u81EA\u52D5\u306B\u4E0A\u66F8\u304D\u3059\u308B\u3002 */\n.dtm-help-goals .dtm-btn {\n flex-direction: column;\n align-items: flex-start;\n gap: 1px;\n width: 100%;\n height: auto;\n padding: 6px 10px;\n text-align: left;\n white-space: normal;\n}\n.dtm-help-goals .dtm-btn small {\n font-size: 11px;\n opacity: .8;\n font-weight: normal;\n}\n.dtm-help-topics {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n.dtm-help-topics .dtm-btn {\n min-height: 32px;\n padding: 0 8px;\n font-size: 12px;\n}\n\n.dtm-hidden { display: none !important; }\n/* \u8AAD\u8FBC\u6642\u306E\u8B66\u544A\u304A\u77E5\u3089\u305B\uFF08\u4F8B: \u30B7\u30F3\u30D7\u30EB\u30E2\u30FC\u30C9\u3067\u306E\u30C8\u30E9\u30C3\u30AF\u5408\u7B97\uFF09\u3002 */\n.dtm-load-note {\n margin: 6px 0 0;\n padding: 0 2px;\n font-family: var(--dtm-font);\n font-size: 11px;\n line-height: 1.5;\n letter-spacing: .04em;\n color: var(--dtm-warn); /* \u8B66\u544A\u8272\uFF08\u30AA\u30EC\u30F3\u30B8\uFF09 */\n font-weight: bold;\n opacity: 1.0;\n}\n.dtm-load-note::before { content: \"\u26A0 \"; }\n/* \u4F34\u594F\u97F3\u6E90\uFF08mp3/wav/YouTube\uFF09\u306E\u72B6\u614B\u8868\u793A\u3002\u8AAD\u307F\u8FBC\u307F\u7D50\u679C\u306E\u5831\u544A\u306A\u306E\u3067\u8B66\u544A\u8272\u306B\u306F\u3057\u306A\u3044\u3002 */\n.dtm-audio-note {\n margin: 6px 0 0;\n padding: 0 2px;\n font-family: var(--dtm-font);\n font-size: 11px;\n line-height: 1.5;\n letter-spacing: .04em;\n color: var(--dtm-muted);\n}\n.dtm-audio-note--warn { color: var(--dtm-warn); font-weight: bold; }\n/* YouTube\u30D7\u30EC\u30A4\u30E4\u30FC\u306E\u67A0\u3002API\u304C\u4E2D\u306E\u8981\u7D20\u3092 iframe \u3078\u5DEE\u3057\u66FF\u3048\u308B\u306E\u3067\u3001\u67A0\u5074\u3067\u5BF8\u6CD5\u3092\u6C7A\u3081\u308B\u3002 */\n.dtm-audio-yt { width: 100%; max-width: 320px; aspect-ratio: 16 / 9; }\n.dtm-audio-yt iframe { display: block; width: 100%; height: 100%; border: 0; }\n.dtm-grow { flex: 1 1 auto; }\n.dtm-lyric-icon {\n flex: 0 0 auto;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n object-fit: cover;\n image-rendering: pixelated;\n}\n/* \u6B4C\u8A5E\u30C8\u30E9\u30C3\u30AF\u306E\u300C\u8A73\u7D30\u8A2D\u5B9A\u300D\u2014 \u5E38\u7528\u3057\u306A\u3044\u30D1\u30E9\u30E1\u30FC\u30BF\uFF08\u30AA\u30AF\u30BF\u30FC\u30D6/\u5B9A\u4F4D/\u30EA\u30D0\u30FC\u30D6\u9001\u308A/\n \u30B8\u30A7\u30F3\u30C0\u30FC/\u30D6\u30EC\u30B7\u30CD\u30B9/\u30D3\u30D6\u30E9\u30FC\u30C8\uFF09\u3092\u7573\u3093\u3067\u304A\u304F\u8EFD\u91CF\u306A details\u3002dtm-panel \u307B\u3069\n \u4EF0\u3005\u3057\u304F\u305B\u305A\u3001\u5C0F\u3055\u3044\u25B6\u30DE\u30FC\u30AB\u30FC\u3060\u3051\u4ED8\u3051\u308B\uFF08\u4ED5\u5207\u308A\u7DDA\u306F\u9AD8\u3055\u3092\u98DF\u3046\u306E\u3067\u7F6E\u304B\u306A\u3044\uFF09\u3002 */\n.dtm-advanced {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.dtm-advanced > summary {\n list-style: none;\n cursor: pointer;\n font-size: 11px;\n letter-spacing: .08em;\n color: var(--dtm-text);\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 28px;\n padding: 0 8px;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-deep);\n box-shadow: 2px 2px 0 var(--c-black);\n width: fit-content;\n}\n.dtm-advanced > summary:active { transform: translate(2px,2px); box-shadow: none; }\n.dtm-advanced > summary::-webkit-details-marker { display: none; }\n.dtm-advanced > summary::before { content: \"\u25B6\"; font-size: 9px; color: var(--dtm-accent); }\n.dtm-advanced[open] > summary::before { content: \"\u25BC\"; }\n.dtm-advanced[open] > summary { border-color: var(--dtm-primary); color: var(--dtm-primary); }\n\n/* \u2500\u2500\u2500 \u5E83\u5E45\u62E1\u5F35 \u2500\u2500\u2500 */\n@media (min-width: 768px) {\n .dtm-daw { gap: 8px; padding: 10px; }\n .dtm-roll { height: 420px; }\n}\n\n/* ====================================================\n MML PLAYER \u2014 \u518D\u751F\u5C02\u7528\u30D3\u30E5\u30FC\uFF08mountMmlPlayer\uFF09\n ==================================================== */\n.dtm-player {\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n padding: var(--dtm-gap);\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n box-shadow: 4px 4px 0 var(--c-black);\n}\n.dtm-player-message {\n padding: 4px 8px;\n background: var(--c-purple);\n color: var(--c-yellow);\n font-size: 11px;\n border: 2px solid var(--c-black);\n box-shadow: inset 0 -2px 0 rgba(0,0,0,0.2);\n font-family: var(--dtm-font);\n text-align: center;\n width: 100%;\n box-sizing: border-box;\n}\n.dtm-player-head {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n.dtm-player-play {\n flex: 0 0 auto;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--dtm-primary);\n color: var(--dtm-pfg);\n border: 2px solid var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n cursor: pointer;\n padding: 0;\n}\n.dtm-player-play:active { transform: translate(2px, 2px); box-shadow: none; }\n.dtm-player-play--stop { background: var(--dtm-danger); }\n.dtm-player-play:disabled { opacity: 0.4; cursor: default; }\n.dtm-player-loop {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-bg);\n color: var(--dtm-muted);\n cursor: pointer;\n flex: 0 0 auto;\n}\n.dtm-player-loop:active { transform: translate(1px, 1px); }\n.dtm-player-loop--on {\n border-color: var(--c-black);\n background: var(--dtm-gold);\n color: var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n}\n.dtm-player-loop:disabled { opacity: 0.4; cursor: default; }\n.dtm-player-beat-row {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.dtm-player-beat-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--dtm-border2);\n transition: background 0.06s;\n}\n.dtm-player-beat-dot--on { background: var(--dtm-primary); }\n.dtm-player-bar {\n font-family: 'k8x12', monospace;\n font-size: 11px;\n color: var(--dtm-text);\n min-width: 2em;\n margin-left: 4px;\n}\n.dtm-player-chord {\n font-family: 'k8x12', monospace;\n font-size: 11px;\n color: var(--dtm-accent);\n min-width: 4em;\n margin-left: 8px;\n font-weight: bold;\n}\n.dtm-player-seek-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dtm-player-seek {\n --fill: 0%;\n flex: 1 1 auto;\n min-width: 0;\n height: 12px;\n margin: 0;\n background: transparent;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n.dtm-player-seek:disabled { cursor: default; opacity: 0.4; }\n/* \u518D\u751F\u6E08\u307F\u533A\u9593\u3092YouTube\u98A8\u306B\u8272\u5857\u308A\u3059\u308B\uFF08--fill \u306F\u518D\u751F\u4F4D\u7F6E\u306B\u5FDC\u3058\u3066JS\u304B\u3089\u8A2D\u5B9A\uFF09 */\n.dtm-player-seek::-webkit-slider-runnable-track {\n height: 6px;\n background: linear-gradient(\n to right,\n var(--dtm-primary) var(--fill),\n var(--dtm-border2) var(--fill)\n );\n border: 2px solid var(--c-black);\n}\n.dtm-player-seek::-moz-range-track {\n height: 6px;\n background: var(--dtm-border2);\n border: 2px solid var(--c-black);\n}\n.dtm-player-seek::-moz-range-progress {\n height: 6px;\n background: var(--dtm-primary);\n border: 2px solid var(--c-black);\n border-right: none;\n}\n.dtm-player-seek::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 12px;\n height: 16px;\n margin-top: -7px;\n background: var(--dtm-primary);\n border: 2px solid var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n cursor: pointer;\n}\n.dtm-player-seek::-moz-range-thumb {\n width: 12px;\n height: 16px;\n background: var(--dtm-primary);\n border: 2px solid var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n cursor: pointer;\n border-radius: 0;\n}\n.dtm-player-time {\n flex: 0 0 auto;\n font-family: 'k8x12', monospace;\n font-size: 11px;\n color: var(--dtm-text);\n white-space: nowrap;\n}\n.dtm-player-dots {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.dtm-player-dot { width: 8px; height: 8px; display: inline-block; }\n.dtm-player-mml-header {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.dtm-player-mml-link {\n font-family: 'k8x12', monospace;\n font-size: 10px;\n color: var(--dtm-muted);\n text-decoration: none;\n white-space: nowrap;\n}\n.dtm-player-mml-link:hover { color: var(--dtm-primary); }\n.dtm-player-more-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n}\n.dtm-player-more-btn {\n background: transparent;\n border: none;\n color: var(--dtm-muted);\n cursor: pointer;\n padding: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n width: 24px;\n height: 24px;\n transition: color 0.15s, background-color 0.15s;\n}\n.dtm-player-more-btn:hover,\n.dtm-player-more-btn.is-active {\n color: var(--dtm-text);\n background: var(--dtm-border2);\n}\n.dtm-player-menu {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n box-shadow: 4px 4px 0 var(--c-black);\n z-index: 200;\n display: flex;\n flex-direction: column;\n padding: 4px 0;\n min-width: 130px;\n font-family: var(--dtm-font);\n}\n.dtm-player-menu-item {\n background: transparent;\n border: none;\n color: var(--dtm-text);\n padding: 6px 12px;\n text-align: left;\n cursor: pointer;\n font-size: 11px;\n font-family: inherit;\n white-space: nowrap;\n width: 100%;\n box-sizing: border-box;\n transition: background-color 0.1s, color 0.1s;\n}\n.dtm-player-menu-item:hover {\n background: var(--dtm-primary);\n color: var(--dtm-pfg);\n}\n.dtm-player-emoji {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n font-size: 18px;\n line-height: 1;\n user-select: none;\n}\n.dtm-player-balloon {\n /* body \u76F4\u4E0B\u306B\u751F\u6210\u3055\u308C\u3001JS(positionBalloon)\u304C\u6BCE\u56DE left/top \u3092\u30A2\u30F3\u30AB\u30FC\u306E\u753B\u9762\u5EA7\u6A19\u3067\n \u8A2D\u5B9A\u3059\u308B\u3002overflow:hidden \u306A\u7956\u5148\uFF08\u6295\u7A3F\u30AB\u30FC\u30C9\u7B49\uFF09\u306B\u30AF\u30EA\u30C3\u30D7\u3055\u308C\u306A\u3044\u3088\u3046 fixed \u3067\u6D6E\u304B\u305B\u308B\u3002\n top \u306F\u30A2\u30F3\u30AB\u30FC\u4E0A\u7AEF-6px\u3001transform \u3067\u81EA\u8EAB\u306E\u5DE6\u4E0B\u89D2\u3092\u305D\u306E\u70B9\u306B\u5408\u308F\u305B\u308B\u3002 */\n position: fixed;\n left: 0;\n top: 0;\n transform: translate(-50%, -100%);\n z-index: 1000;\n display: none;\n pointer-events: none;\n font-family: var(--dtm-font);\n font-size: 9px;\n color: var(--c-black);\n background: var(--c-white);\n border: 2px solid var(--c-black);\n padding: 2px 4px;\n white-space: nowrap;\n box-shadow: 2px 2px 0 var(--c-black);\n}\n.dtm-player-balloon::after {\n content: \"\";\n position: absolute;\n bottom: -6px;\n left: 50%;\n transform: translateX(-50%) rotate(45deg);\n width: 8px;\n height: 8px;\n background: var(--c-white);\n border-right: 2px solid var(--c-black);\n border-bottom: 2px solid var(--c-black);\n}\n/* \u30A2\u30A4\u30B3\u30F3\u304C\u753B\u9762\u4E0A\u7AEF\u306B\u8FD1\u304F\u4E0A\u306B\u51FA\u3059\u4F59\u767D\u304C\u7121\u3044\u5834\u5408\u306F\u4E0B\u306B\u53CD\u8EE2\u8868\u793A\u3059\u308B\uFF08positionBalloon \u304C\u4ED8\u4E0E\uFF09 */\n.dtm-player-balloon--below {\n transform: translate(-50%, 0);\n}\n.dtm-player-balloon--below::after {\n bottom: auto;\n top: -6px;\n border-right: none;\n border-bottom: none;\n border-left: 2px solid var(--c-black);\n border-top: 2px solid var(--c-black);\n}\n.dtm-player-balloon--visible {\n display: block;\n animation: dtm-balloon-fade-in 0.1s steps(2);\n}\n.dtm-player-balloon--below.dtm-player-balloon--visible {\n animation-name: dtm-balloon-fade-in-below;\n}\n@keyframes dtm-balloon-fade-in {\n from { opacity: 0; transform: translate(-50%, -100%) translateY(4px); }\n to { opacity: 1; transform: translate(-50%, -100%) translateY(0); }\n}\n@keyframes dtm-balloon-fade-in-below {\n from { opacity: 0; transform: translate(-50%, 0) translateY(-4px); }\n to { opacity: 1; transform: translate(-50%, 0) translateY(0); }\n}\n@keyframes dtm-emoji-jump {\n 0% { transform: translateY(0); }\n 35% { transform: translateY(-5px); }\n 65% { transform: translateY(-5px); }\n 100% { transform: translateY(0); }\n}\n.dtm-player-emoji--jump {\n animation: dtm-emoji-jump 0.18s ease-out forwards;\n}\n.dtm-player-chip {\n font-family: 'k8x12', monospace;\n font-size: 9px;\n color: var(--dtm-text);\n background: var(--dtm-border2);\n padding: 2px 6px;\n white-space: nowrap;\n}\n.dtm-player-body {\n position: relative; /* \u30ED\u30FC\u30C7\u30A3\u30F3\u30B0\u30AA\u30FC\u30D0\u30FC\u30EC\u30A4\u306E\u57FA\u6E96\u3002\u30EC\u30FC\u30F3\u7FA4\u3060\u3051\u3092\u8986\u3046 */\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n}\n.dtm-player-lane-row {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: 6px;\n}\n.dtm-player-lane-label {\n position: relative;\n flex: 0 0 auto;\n width: 16px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n}\n.dtm-player-lane-label--btn {\n cursor: pointer;\n user-select: none;\n}\n.dtm-player-lane-label--btn:hover { opacity: 0.7; }\n.dtm-player-lane-label--muted { opacity: 0.3; }\n\n/* \u2500\u2500\u2500 \u30DF\u30E5\u30FC\u30C8\u8868\u793A\uFF08\u6392\u4ED6\u540C\u671F\uFF09 \u2500\u2500\u2500 */\n.dtm-player-emoji.is-muted,\n.dtm-player-lane-label.is-muted {\n position: relative;\n}\n\n/* \u30DF\u30E5\u30FC\u30C8\u6642\u306E\u300C\u00D7\u300D\u30DE\u30FC\u30AF\u91CD\u306D\u63CF\u304D */\n.dtm-player-emoji.is-muted::before,\n.dtm-player-lane-label.is-muted::before {\n content: \"\u00D7\";\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--dtm-danger);\n font-family: var(--dtm-font);\n font-size: 16px;\n font-weight: bold;\n z-index: 10;\n pointer-events: none;\n text-shadow: 1px 1px 0 var(--c-black);\n}\n\n.dtm-player-lane-label.is-muted::before {\n font-size: 14px;\n}\n\n/* \u30DF\u30E5\u30FC\u30C8\u6642\u306E\u30A2\u30A4\u30B3\u30F3\u3084\u8981\u7D20\u306E\u8584\u6697\u5316\uFF08\u5439\u304D\u51FA\u3057\u306F\u9664\u5916\uFF09 */\n.dtm-player-emoji.is-muted > img,\n.dtm-player-emoji.is-muted > span:not(.dtm-player-balloon) {\n opacity: 0.25;\n filter: grayscale(80%);\n}\n\n.dtm-player-lane-label.is-muted {\n opacity: 0.25;\n}\n\n/* \u30DF\u30E5\u30FC\u30C8\u6642\u306E\u30C8\u30E9\u30C3\u30AF\u30EC\u30FC\u30F3\uFF08\u30B9\u30AF\u30ED\u30FC\u30EB\u90E8\uFF09\u306E\u8584\u6697\u5316\u3068\u30C7\u30AB\u00D7\u30DE\u30FC\u30AF\uFF08\u8272\u5F31\u5BFE\u5FDC\uFF09 */\n.dtm-player-lane-row.is-muted::after {\n content: \"\u00D7\";\n position: absolute;\n top: 0;\n bottom: 0;\n left: 22px; /* label width (16px) + gap (6px) */\n right: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--dtm-danger);\n font-family: var(--dtm-font);\n font-size: 24px;\n font-weight: bold;\n background: rgba(0, 0, 0, 0.45);\n z-index: 10;\n pointer-events: none;\n text-shadow: 1px 1px 0 var(--c-black);\n}\n.dtm-player-lane-no {\n font-family: 'k8x12', monospace;\n font-size: 9px;\n color: var(--dtm-muted);\n}\n.dtm-player-lane {\n position: relative; /* \u30C8\u30FC\u30AF\u30F3\u306E offsetParent \u3092\u30EC\u30FC\u30F3\u306B\u56FA\u5B9A\u3057\u3001\u4E2D\u592E\u5BC4\u305B\u8A08\u7B97\u3092\u6B63\u3059 */\n flex: 1 1 auto;\n overflow-x: auto;\n overflow-y: hidden;\n white-space: nowrap;\n background: var(--c-black);\n border: none;\n padding: 0 6px;\n scrollbar-width: none;\n display: flex;\n align-items: center;\n}\n.dtm-player-lane::-webkit-scrollbar { display: none; }\n.dtm-tk {\n font-family: 'k8x12', monospace;\n font-size: 12px;\n color: var(--dtm-text);\n flex: 0 0 auto;\n}\n.dtm-tk--rest { color: var(--dtm-muted); }\n.dtm-tk--octave,\n.dtm-tk--shift,\n.dtm-tk--length,\n.dtm-tk--ctrl { color: var(--dtm-border2); }\n.dtm-tk--lyric { color: var(--dtm-text); letter-spacing: 1px; }\n/* \u7D99\u7D9A\uFF08\u30FC / \u301C\uFF09\u306F\u300C\u8A00\u3044\u76F4\u3055\u306A\u3044\u300D\u97F3\u3002\u304B\u306A\u3088\u308A\u6DE1\u304F\u3057\u3066\u97F3\u7BC0\u306E\u5207\u308C\u76EE\u3092\u76EE\u3067\u8FFD\u3048\u308B\u3088\u3046\u306B\u3059\u308B */\n.dtm-tk--lyric-tie { color: var(--dtm-muted); }\n/* \u4FC3\u97F3\uFF08\u3063\uFF09\u30FB\u4F11\u7B26\uFF08_\uFF09\u306F\u6B4C\u308F\u306A\u3044\u30CE\u30FC\u30C8\u3002\u3055\u3089\u306B\u843D\u3068\u3057\u3066\u7121\u97F3\u3067\u3042\u308B\u3053\u3068\u3092\u793A\u3059 */\n.dtm-tk--lyric-stop,\n.dtm-tk--lyric-rest { color: var(--dtm-border2); }\n/* \u8A9E\u308A\uFF08\u300C\u2026\u300D\uFF09\u306F\u6B4C\u308F\u305A\u306B\u8AAD\u307F\u4E0A\u3052\u308B 1 \u30CE\u30FC\u30C8\u3002\u6B4C\u8A5E\u3068\u533A\u5225\u3067\u304D\u308B\u3088\u3046\u5F37\u8ABF\u8272\u306B\u3059\u308B */\n.dtm-tk--lyric-speak { color: var(--dtm-primary); letter-spacing: 0; }\n.dtm-tk--break { color: var(--dtm-muted); opacity: 0.7; margin: 0 2px; }\n.dtm-tk--meta { color: var(--dtm-border2); margin-right: 4px; }\n.dtm-tk.is-active {\n background: var(--tk, var(--dtm-primary));\n color: var(--c-black);\n font-weight: bold;\n}\n\n/* \u2500\u2500\u2500 \u30B3\u30FC\u30C9\u9032\u884C\u30D7\u30EC\u30A4\u30E4\u30FC \u2500\u2500\u2500 */\n/* MML\u518D\u751F\u5C02\u7528\u30D7\u30EC\u30A4\u30E4\u30FC\uFF08.dtm-player\uFF09\u3068\u67A0\u30C7\u30B6\u30A4\u30F3\u3092\u63C3\u3048\u308B */\n.dtm-chord-player {\n display: flex;\n flex-direction: column;\n gap: var(--dtm-gap);\n padding: var(--dtm-gap);\n font-family: var(--dtm-font);\n font-size: 13px;\n letter-spacing: .06em;\n color: var(--dtm-text);\n background: var(--dtm-deep);\n border: 2px solid var(--dtm-border2);\n box-shadow: 4px 4px 0 var(--c-black);\n image-rendering: pixelated;\n -webkit-font-smoothing: none;\n}\n.dtm-chord-player *,\n.dtm-chord-player *::before,\n.dtm-chord-player *::after { box-sizing: border-box; }\n\n/* \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC \u2014 MML\u518D\u751F\u5C02\u7528\u30D7\u30EC\u30A4\u30E4\u30FC\u306E .dtm-player-head \u3068\u63C3\u3048\u308B */\n.dtm-cp-ctrl {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n}\n.dtm-cp-ctrl .dtm-player-more-container {\n margin-left: auto;\n}\n\n/* \u30EB\u30FC\u30D7\u5207\u66FF\u30DC\u30BF\u30F3 */\n.dtm-cp-loop {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 2px solid var(--dtm-border2);\n background: var(--dtm-bg);\n color: var(--dtm-muted);\n cursor: pointer;\n flex: 0 0 auto;\n}\n.dtm-cp-loop:active { transform: translate(1px,1px); }\n.dtm-cp-loop--on {\n border-color: var(--c-black);\n background: var(--dtm-gold);\n color: var(--c-black);\n box-shadow: 2px 2px 0 var(--c-black);\n}\n\n/* \u30E1\u30BF\u60C5\u5831 (BPM) */\n.dtm-cp-meta {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .12em;\n color: var(--dtm-muted);\n}\n\n/* \u30B9\u30AF\u30ED\u30FC\u30EB\u30A8\u30EA\u30A2 */\n.dtm-cp-scroll {\n position: relative;\n max-height: 180px;\n overflow-y: auto;\n padding: 8px 10px 10px;\n scrollbar-width: none;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n.dtm-cp-scroll::-webkit-scrollbar { display: none; }\n\n/* \u30BB\u30AF\u30B7\u30E7\u30F3\u898B\u51FA\u3057 \u2014 \u30BB\u30AF\u30B7\u30E7\u30F3\u8272\u306E\u5E2F\u3068\u30D4\u30AF\u30BB\u30EB\u30DE\u30FC\u30AB\u30FC */\n.dtm-cp-section {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .14em;\n margin-top: 8px;\n padding: 1px 8px 1px 5px;\n color: var(--cp-fg, var(--dtm-text));\n border-left: 4px solid var(--cp-fg, var(--dtm-text));\n background: linear-gradient(90deg, var(--cp-bg, transparent), transparent);\n align-self: flex-start;\n}\n.dtm-cp-section::before {\n content: \"\u25A0\";\n margin-right: 5px;\n}\n\n/* \u5C0F\u7BC0\u884C */\n.dtm-cp-bar {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 2px;\n margin-top: 2px;\n}\n\n/* \u5C0F\u7BC0\u533A\u5207\u308A\u30D1\u30A4\u30D7 */\n.dtm-cp-pipe {\n font-size: 13px;\n color: rgba(255, 255, 255, 0.35);\n font-family: var(--dtm-font);\n font-weight: bold;\n margin: 0 4px;\n user-select: none;\n}\n\n/* \u30B3\u30FC\u30C9\u30BB\u30EB \u2014 \u30B2\u30FC\u30E0\u306E\u30DC\u30BF\u30F3\u98A8\u30C1\u30C3\u30D7\uFF08\u30BF\u30C3\u30D7\u3067\u305D\u3053\u304B\u3089\u518D\u751F\uFF09 */\n.dtm-cp-chord {\n display: inline-block;\n font-family: var(--dtm-font);\n font-size: 12px;\n padding: 2px 5px;\n border: 2px solid transparent;\n color: var(--cp-fg, var(--dtm-text));\n background: var(--cp-bg, transparent);\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n}\n.dtm-cp-chord:not(.dtm-cp-chord--dead):hover {\n border-color: var(--cp-fg, var(--dtm-text));\n}\n.dtm-cp-chord:not(.dtm-cp-chord--dead):active {\n transform: translate(1px,1px);\n}\n.dtm-cp-chord:focus-visible {\n outline: 2px solid var(--c-white);\n outline-offset: 0;\n}\n.dtm-cp-chord--dead { cursor: default; }\n.dtm-cp-chord--played { opacity: .45; }\n.dtm-cp-chord--active {\n border-color: var(--c-black);\n color: var(--c-black);\n background: var(--cp-fg, var(--dtm-primary));\n box-shadow: 2px 2px 0 var(--c-black);\n opacity: 1;\n}\n";
4743
4996
  /**
4744
4997
  * スタイルを document.head に一度だけ注入する。
4745
4998
  */
@@ -4819,7 +5072,7 @@ declare const createSynth: (ctx: AudioContext, destination?: AudioNode, tone?: S
4819
5072
  * ブラウザ向けのバンドルに `package.json` を読ませたくないので定数で持つ。
4820
5073
  * ずれると埋め込む値が嘘になるので、`scripts/check-version.ts` が一致を検算する。
4821
5074
  */
4822
- declare const DTM_VERSION = "2.1.12";
5075
+ declare const DTM_VERSION = "2.1.14";
4823
5076
 
4824
5077
  declare const VOICE_IMAGES: Record<string, string>;
4825
5078
 
@@ -4836,4 +5089,4 @@ declare const encodeWavPCM16: (channels: Float32Array[], sampleRate: number) =>
4836
5089
  /** Float32Array のチャンクを1本へ連結する。 */
4837
5090
  declare const concatFloat32: (chunks: Float32Array[]) => Float32Array;
4838
5091
 
4839
- export { A4_HZ, A4_UNITS, type AddNoteOptions, type AnyDrumPattern, type ApplyChordOptions, BLUES_SCALE, BREATH_MARK, type BackingAudio, type BackingAudioOptions, type BackingLoaded, type BackingMode, type BackingStartOptions, type Band, type BuildUstOptions, CENTS_PER_UNIT, COMPOSE_KEYS, COMPOSE_MOOD_GROUPS, COMPOSE_SCALES, COMPOSE_SCALE_IDS, CORPUS_BANDS, CORPUS_SIZE, type ChordPatternType, type ChordPlacement, type ChordPlayerInstance, type ComposeKeyTarget, type ComposeMoodGroup, type ComposeMoodId, type ComposeOptions, type ComposeResult, type ComposeScale, type ComposeScaleId, type ComposeStats, type ComposedNote, type ConsumedSyllable, type CoreEventHandlers, type CustomVocalDef, DAW_CSS, DAW_TOUR_BRANCHES, DAW_TOUR_STEPS, DEFAULT_BPM, DEFAULT_EDO, DEFAULT_GATE, DEFAULT_PAN, DEFAULT_PLAYBACK_VELOCITY, DEFAULT_SECTIONS, DEFAULT_STEPS_PER_BAR, DEFAULT_UST_LYRIC, DEFAULT_VELOCITY, DEFAULT_VOCAL_VOLUME, DRUM_FONT, DRUM_KEYS, DRUM_PATTERNS, DTM_VERSION, type DawInstance, type DawMode, type DawOptions, type DawViewState, type DrumPattern, type DrumPatternDef, type DtmStudio, type DtmStudioEngines, type DtmStudioOptions, EDO31_NAMES, type Edo, type ExportMidiOptions, type ExportMidiTrack, type ExportMusicXmlOptions, type ExportMusicXmlPart, FADE_IN_MARK, FADE_OUT_MARK, type FadeScheduleParams, type FadeStop, GLOBAL_STORAGE_KEYS, GM_BRIGHT_CEILING, GM_INSTRUMENT_NAMES, GM_INSTRUMENT_RANGE, type GlobalStorageKey, HARMONIC_MINOR_SCALE, HUNGARIAN_SCALE, INSTRUMENT_PRESETS, type InstrumentPreset, KEY_COUNT, KOE_BASE_URL, KOE_VOICEBANKS, KOE_VOICEBANK_LABELS, KOE_VOICEBANK_TERMS, type KeyMode, type KoeVoiceOptions, LinkedList, type LoopConfig, type LoopPoint, type LyricSyllable, type LyricSyllableKind, type LyricSyncData, type LyricTrack, type LyricsConductor, MACRO_STORAGE_KEYS, MAJOR_KEY_IDS, MAJOR_SCALE, MAX_VOCAL_VOLUME, MICRO_STEP, MINOR_KEY_IDS, MMLCore, type MMLDisplayToken, type MMLNotePlacement, MML_END_MARKER, type MacroStorageKey, type MelodyForm, type MetricNote, type MetricOptions, type MidiExtraction, type MidiNote, type MidiNotePlacement, MidiSearchClient, type MidiSearchConfig, type MidiTrackAnalysis, type MmlMeta, type MmlPlayback, type MmlPlayerInstance, type MmlPlayerOptions, type ModeSwitchInstance, type ModeSwitchOptions, type MountChordPlayerOptions, type MountEditorOptions, type MountPlayerOptions, type MusicXmlExtraction, type MusicXmlNotePlacement, type MusicXmlPart, type Note, type NoteData, type NoteRemove, type OctaveUnisonMode, PITCH_ENCODING_VERSION, PITCH_MAP, PITCH_RANGE_END, PITCH_RANGE_START, PORTAMENTO_MARK, PREWARM_NOTES, type ParseMMLOptions, type ParseMidiFn, type ParsedMML, type PianoRollInstance, type PianoRollOptions, type PicotuneSearchParams, type PicotuneSong, type PitchSegment, type PitchToken, type PlacedSection, type PlayChordsOptions, type PlayDrumEvent, type PlayMmlOptions, type PlayNoteEvent, type PlayNoteOptions, type PlayPlacementsOptions, type PlaySingingMmlOptions, type PlaybackCue, type PlaybackState, type PresetSelectInstance, type PresetSelectOptions, type PreviewSoundCallback, REST_MARK, type RenderConfig, type Renderer, type ResolvedComposeKey, SECTION_LABELS, SECTION_ORDER, SECTION_SPECS, SEQUENCER_START_DELAY, STOP_MARK, type ScaleDegree, type SectionKind, type SectionSpec, type Sequencer, type SequencerOptions, type SequencerTrack, type SingingVoices, type SingingVoicesOptions, type StreamPlaybackOptions, type StreamVoiceNote, type StreamVoiceNoteOptions, type StreamVoiceTrack, type StructureFeatures, type Synth, TIE_MARK, TIE_MERGE_MAX_SEC, TOUR_STORAGE_KEY, TRACKS_ADVANCED, TRACKS_SIMPLE, type TensionFeatures, type TieSourceNote, type TonicCenter, type TonicDegree, type ToolMode, type TourBranch, type TourInstance, type TourLabels, type TourOptions, type TourStep, type TrackConfig, UNITS_PER_EDO31_DEGREE, UNITS_PER_OCTAVE, UNITS_PER_SEMITONE, UST_TICKS_PER_BEAT, type Units, type UstNotePlacement, type UstTrackData, VIBRATO_MIN_SEC, VOICE_IMAGES, VOICE_IMAGE_KEY, type VoiceExpression, type VoiceModel, type VoiceRegistry, addUnits, analyzeMidiTracks, applyHarmonicFilter, applyMonophonic, backingMediaSec, band, buildChordPlacements, buildDrumPatternJson, buildNameToKeyMapping, buildSectionPlan, buildStreamVoiceNotes, buildUst, chromaticStep, clearTourSeen, collectPitchTokens, complementarity, composeSong, concatFloat32, createAudioContext, createBackingAudio, createDtmStudio, createKlattVoice, createKoeVoice, createLyricsConductor, createPianoRoll, createRenderer, createSequencer, createSingingVoices, createSynth, createVoiceRegistry, decodeMml, decodeUstText, decomposeToMonophonic, displayKana, durationEntropy, encodeMml, encodeWavPCM16, exportMIDI, exportMusicXML, extractDrumPatternFromNotes, extractMidiDrumPattern, extractMidiPlacements, extractMidiPlacementsByTrack, featureDistance, featureVector, fifthToStep, fifthToUnits, fitInstrumentOctave, formatMmlMeta, formatTimeSec, freqFromPitch, generateRandomPattern, getComposeKeyDescription, getComposeScaleDescription, getDrumPatternKeys, getMidiBPM, hasSeenTour, icon, injectStyles, isChordHeavyTrack, isNaturalLetter, isPlausibleMidiTranscription, isTourTargetVisible, isValidHttpUrl, isYoutubeUrl, keyCountFor, koeUrl, looksLikePinyin, lyricToSyllable, markTourSeen, midiNote, midiToUnits, mountChordPlayer, mountDAW, mountMmlPlayer, musicXmlToNotes, naturalStep, normalizeDrumPatterns, normalizeLyrics, panToStereo, parseCustomVocals, parseLyrics, parseMML, parseMmlMeta, parseMusicXML, parseTimeSec, parseUst, parseYoutubeId, pinyinToMoras, pitchV1ToUnits, playChords, playMML, playNote, playPlacements, playSingingMML, programOfInstrumentName, readGlobalBool, readGlobalNumber, readGlobalSetting, readMacroSections, readMacroSetting, resolveCenter, resolveComposeKey, resolveComposeScale, resolveDrumPattern, resolveLoopPoint, resolveYoutubeThumbnail, scaleDegrees, scaleSize, sectionPlanBarRange, semitonesToUnits, shiftNotes, showLoadingOverlay, spelledToUnits, spellingToUnits, startTour, stripCustomVocals, stripLyrics, stripMmlMeta, structureFeatures, syllablesToText, tensionFeatures, transposeNotes, units, unitsPerRow, unitsPerStep, unitsToHz, unitsToMidi, unitsToMidiDetune, unitsToPitchV1, vocalVolumeToGain, writeGlobalSetting, writeMacroSections, writeMacroSetting };
5092
+ export { A4_HZ, A4_UNITS, type AddNoteOptions, type AnyDrumPattern, type ApplyChordOptions, BLUES_SCALE, BREATH_MARK, type BackingAudio, type BackingAudioOptions, type BackingLoaded, type BackingMode, type BackingStartOptions, type Band, type BuildUstOptions, CENTS_PER_UNIT, COMPOSE_KEYS, COMPOSE_MOOD_GROUPS, COMPOSE_SCALES, COMPOSE_SCALE_IDS, CORPUS_BANDS, CORPUS_SIZE, type ChordPatternType, type ChordPlacement, type ChordPlayerInstance, type ComposeKeyTarget, type ComposeMoodGroup, type ComposeMoodId, type ComposeOptions, type ComposeResult, type ComposeScale, type ComposeScaleId, type ComposeStats, type ComposedNote, type ConsumedSyllable, type CoreEventHandlers, type CustomVocalDef, DAW_CSS, DAW_TOUR_BRANCHES, DAW_TOUR_STEPS, DEFAULT_BPM, DEFAULT_EDO, DEFAULT_GATE, DEFAULT_PAN, DEFAULT_PLAYBACK_VELOCITY, DEFAULT_SECTIONS, DEFAULT_STEPS_PER_BAR, DEFAULT_TTS_BASE_URL, DEFAULT_UST_LYRIC, DEFAULT_VELOCITY, DEFAULT_VOCAL_VOLUME, DRUM_FONT, DRUM_KEYS, DRUM_PATTERNS, DTM_VERSION, type DawInstance, type DawMode, type DawOptions, type DawViewState, type DrumPattern, type DrumPatternDef, type DtmStudio, type DtmStudioEngines, type DtmStudioOptions, EDO31_NAMES, type Edo, type ExportMidiOptions, type ExportMidiTrack, type ExportMusicXmlOptions, type ExportMusicXmlPart, FADE_IN_MARK, FADE_OUT_MARK, type FadeScheduleParams, type FadeStop, GLOBAL_STORAGE_KEYS, GM_BRIGHT_CEILING, GM_INSTRUMENT_NAMES, GM_INSTRUMENT_RANGE, type GlobalStorageKey, HARMONIC_MINOR_SCALE, HUNGARIAN_SCALE, INSTRUMENT_PRESETS, type InstrumentPreset, KEY_COUNT, KOE_BASE_URL, KOE_VOICEBANKS, KOE_VOICEBANK_LABELS, KOE_VOICEBANK_TERMS, type KeptSong, type KeyMode, type KoeVoiceOptions, LinkedList, type LoopConfig, type LoopPoint, type LyricSyllable, type LyricSyllableKind, type LyricSyncData, type LyricTrack, type LyricsConductor, MACRO_STORAGE_KEYS, MAJOR_KEY_IDS, MAJOR_SCALE, MAX_VOCAL_VOLUME, MICRO_STEP, MINOR_KEY_IDS, MMLCore, type MMLDisplayToken, type MMLNotePlacement, MML_END_MARKER, type MacroStorageKey, type MelodyForm, type MetricNote, type MetricOptions, type MidiExtraction, type MidiNote, type MidiNotePlacement, MidiSearchClient, type MidiSearchConfig, type MidiTrackAnalysis, type MmlMeta, type MmlPlayback, type MmlPlayerInstance, type MmlPlayerOptions, type ModeSwitchInstance, type ModeSwitchOptions, type MountChordPlayerOptions, type MountEditorOptions, type MountPlayerOptions, type MusicXmlExtraction, type MusicXmlNotePlacement, type MusicXmlPart, type Note, type NoteData, type NoteRemove, type OctaveUnisonMode, PITCH_ENCODING_VERSION, PITCH_MAP, PITCH_RANGE_END, PITCH_RANGE_START, PORTAMENTO_MARK, PREWARM_NOTES, type ParseMMLOptions, type ParseMidiFn, type ParsedMML, type PianoRollInstance, type PianoRollOptions, type PicotuneSearchParams, type PicotuneSong, type PitchSegment, type PitchToken, type PlacedSection, type PlayChordsOptions, type PlayDrumEvent, type PlayMmlOptions, type PlayNoteEvent, type PlayNoteOptions, type PlayPlacementsOptions, type PlaySingingMmlOptions, type PlaybackCue, type PlaybackState, type PresetSelectInstance, type PresetSelectOptions, type PreviewSoundCallback, REST_MARK, type RenderConfig, type Renderer, type ResolvedComposeKey, SECTION_LABELS, SECTION_ORDER, SECTION_SPECS, SEQUENCER_START_DELAY, SPEAK_CLOSE, SPEAK_OPEN, STOP_MARK, type ScaleDegree, type SectionKind, type SectionSpec, type Sequencer, type SequencerOptions, type SequencerTrack, type SingingVoices, type SingingVoicesOptions, type SpeechBank, type SpeechPlanOptions, type SpeechPlanner, type SpeechPlannerOptions, type SpeechToneView, type StreamPlaybackOptions, type StreamVoiceNote, type StreamVoiceNoteOptions, type StreamVoiceTrack, type StructureFeatures, type Synth, TIE_MARK, TIE_MERGE_MAX_SEC, TOUR_STORAGE_KEY, TRACKS_ADVANCED, TRACKS_SIMPLE, type TensionFeatures, type TieSourceNote, type TonicCenter, type TonicDegree, type ToolMode, type TourBranch, type TourInstance, type TourLabels, type TourOptions, type TourStep, type TrackConfig, UNITS_PER_EDO31_DEGREE, UNITS_PER_OCTAVE, UNITS_PER_SEMITONE, UST_TICKS_PER_BEAT, type Units, type UstNotePlacement, type UstTrackData, VIBRATO_MIN_SEC, VOICE_IMAGES, VOICE_IMAGE_KEY, type VoiceExpression, type VoiceModel, type VoiceRegistry, addUnits, analyzeMidiTracks, applyHarmonicFilter, applyMonophonic, backingMediaSec, band, buildChordPlacements, buildDrumPatternJson, buildNameToKeyMapping, buildSectionPlan, buildStreamVoiceNotes, buildUst, chromaticStep, clearTourSeen, collectPitchTokens, complementarity, composeSong, concatFloat32, createAudioContext, createBackingAudio, createDtmStudio, createKlattVoice, createKoeVoice, createLyricsConductor, createPianoRoll, createRenderer, createSequencer, createSingingVoices, createSpeechPlanner, createSpeechToneView, createSynth, createVoiceRegistry, decodeMml, decodeUstText, decomposeToMonophonic, displayKana, durationEntropy, encodeMml, encodeWavPCM16, exportMIDI, exportMusicXML, extractDrumPatternFromNotes, extractMidiDrumPattern, extractMidiPlacements, extractMidiPlacementsByTrack, featureDistance, featureVector, fifthToStep, fifthToUnits, fitInstrumentOctave, formatMmlMeta, formatTimeSec, freqFromPitch, generateRandomPattern, getComposeKeyDescription, getComposeScaleDescription, getDrumPatternKeys, getMidiBPM, getSpeechPlanner, hasSeenTour, icon, injectStyles, isChordHeavyTrack, isNaturalLetter, isPlausibleMidiTranscription, isTourTargetVisible, isValidHttpUrl, isYoutubeUrl, keyCountFor, koeUrl, looksLikePinyin, lyricToSyllable, markTourSeen, medianRecordedPitchHz, midiNote, midiToUnits, mountChordPlayer, mountDAW, mountMmlPlayer, musicXmlToNotes, naturalStep, normalizeDrumPatterns, normalizeLyrics, panToStereo, parseCustomVocals, parseLyrics, parseMML, parseMmlMeta, parseMusicXML, parseTimeSec, parseUst, parseYoutubeId, pinyinToMoras, pitchV1ToUnits, playChords, playMML, playNote, playPlacements, playSingingMML, prepareSpeechPlan, programOfInstrumentName, readGlobalBool, readGlobalNumber, readGlobalSetting, readKeptSong, readMacroSections, readMacroSetting, resolveCenter, resolveComposeKey, resolveComposeScale, resolveDrumPattern, resolveLoopPoint, resolveYoutubeThumbnail, scaleDegrees, scaleSize, sectionPlanBarRange, semitonesToUnits, shiftNotes, showLoadingOverlay, speechPlanDurationSec, speechPlanLeadingSec, spelledToUnits, spellingToUnits, startTour, stripCustomVocals, stripLyrics, stripMmlMeta, structureFeatures, syllablesToText, tensionFeatures, transposeNotes, units, unitsPerRow, unitsPerStep, unitsToHz, unitsToMidi, unitsToMidiDetune, unitsToPitchV1, vocalVolumeToGain, writeGlobalSetting, writeKeptSong, writeMacroSections, writeMacroSetting };