@onjmin/dtm 1.0.7 → 2.0.2

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.ts CHANGED
@@ -67,21 +67,24 @@ declare const mountChordPlayer: (target: HTMLElement, chords: string, options?:
67
67
  type ChordPatternType = "block" | "arpeggio" | "arpeggio-fast" | "offbeat" | "yatsume" | "alternating";
68
68
  type ChordPlacement = {
69
69
  startStep: number;
70
- pitch: number;
70
+ /**
71
+ * 1/372オクターブ単位。chord-parser が返すのは12平均律の半音なので、
72
+ * ここへ入れる時点で音律に応じた格子へ写している。
73
+ */
74
+ pitchUnits: number;
71
75
  durationSteps: number;
72
76
  velocity: number;
73
77
  };
74
78
  type ApplyChordOptions = {
75
79
  chordStr: string;
80
+ /** 曲の音律(1オクターブの分割数)。省略時は12平均律。 */
81
+ edo?: number;
76
82
  patternType: ChordPatternType;
77
83
  /** ルートのセミトーンシフト(0-11) */
78
84
  rootShift: number;
79
85
  bpm: number;
80
86
  stepsPerBar: number;
81
87
  };
82
- /**
83
- * コード進行 → 伴奏ノート配置。
84
- */
85
88
  declare const buildChordPlacements: (options: ApplyChordOptions) => ChordPlacement[];
86
89
 
87
90
  type SongDrumInstruction = {
@@ -412,7 +415,10 @@ declare const createKoeVoice: (ctx: AudioContext, destination: AudioNode, option
412
415
  /** ストリーミング再生する歌唱ノート1つ(絶対時刻ベース)。 */
413
416
  type StreamVoiceNote = {
414
417
  syllable: LyricSyllable;
415
- /** MIDIノート番号 */
418
+ /**
419
+ * ピッチ。単位は units(1/372オクターブ)。koe は Hz を受けるので、
420
+ * ここから直接 Hz へ変換して歌わせる(整数MIDIノートに丸めない)。
421
+ */
416
422
  pitch: number;
417
423
  /** アンカー(再生開始時刻)からの相対秒。実発音時刻 = anchorTime + startSec。 */
418
424
  startSec: number;
@@ -650,19 +656,55 @@ declare const DEFAULT_VELOCITY = 100;
650
656
  declare const DEFAULT_PLAYBACK_VELOCITY = 127;
651
657
  declare const DEFAULT_STEPS_PER_BAR = 192;
652
658
  declare const MML_END_MARKER = "#end;";
659
+ /**
660
+ * ピアノロールが扱う音域の下端・上端(両端含む)。音律に依らず固定で、MIDI 0-127 に相当する。
661
+ * 「音律を変えても鳴らせる音の高さの範囲は変わらない」を保証するための不変条件。
662
+ */
663
+ declare const PITCH_RANGE_START = 0;
664
+ /** MIDI 127 相当。単位は 1/372オクターブ(127 × 31)。 */
665
+ declare const PITCH_RANGE_END = 3937;
666
+ /**
667
+ * 1行が受け持つピッチ幅(units)。12平均律は1半音 = 31、31平均律は1度 = 12。
668
+ * 行数はここから導出されるので、12平均律で128行・31平均律で328行になる。
669
+ */
670
+ declare const unitsPerRow: (edo: number) => number;
671
+ /** その音律での行数。音域と1行あたりのピッチ幅から導出する(直接指定しないこと)。 */
672
+ declare const keyCountFor: (edo: number) => number;
673
+ /** 12平均律の行数(従来と同じ128)。 */
674
+ declare const KEY_COUNT: number;
653
675
  type Note = {
654
676
  id: number;
655
677
  startStep: number;
656
678
  durationSteps: number;
657
- pitch: number;
679
+ /**
680
+ * ピッチ。単位は **1/372オクターブの整数**(`tuning.ts` 参照)。
681
+ * 12平均律の1半音 = 31、31平均律の1度 = 12。MIDIノート番号ではないので注意。
682
+ * dtm 1.x の `pitch`(半音)から意味が変わっている。
683
+ */
684
+ pitchUnits: number;
658
685
  velocity?: number;
659
686
  };
660
687
  type RenderConfig = {
661
688
  stepsPerBar: number;
689
+ /**
690
+ * 行数。{@link KEY_COUNT} のように「音域 ÷ 1行あたりのピッチ幅」から導出した値を渡す。
691
+ * 音律ごとに直接指定しないこと(31平均律で音域が勝手に縮む)。
692
+ */
662
693
  keyCount: number;
694
+ /** 音域の下端。単位は units(1/372オクターブ)。 */
663
695
  pitchRangeStart: number;
696
+ /** 1行が受け持つ units。{@link unitsPerRow} から導出した値を渡す。省略時は31(12平均律)。 */
697
+ unitsPerRow?: number;
664
698
  keyHeight: number;
665
699
  stepWidth: number;
700
+ /**
701
+ * 曲全体の音律(1オクターブの分割数)。省略時は12(12平均律)。
702
+ *
703
+ * 音律はデータにも音声経路にも入らず、格子・記譜・表示だけに効く編集上の概念なので、
704
+ * 描画設定と同じ場所に置く。MMLCore も `getConfig()` 経由でここから音律を読み、
705
+ * 綴り(`#`=2度 / `+`=1度 など)を切り替える。
706
+ */
707
+ edo?: number;
666
708
  };
667
709
  type CoreEventHandlers = {
668
710
  onMMLGenerated: (mml: string) => void;
@@ -693,14 +735,16 @@ type LyricSyncData = {
693
735
  /** パッチ送受信用ノートデータ(ローカルIDを持たない)。 */
694
736
  type NoteData = {
695
737
  startStep: number;
696
- pitch: number;
738
+ /** 1/372オクターブ単位。{@link Note.pitchUnits} と同じ。 */
739
+ pitchUnits: number;
697
740
  durationSteps: number;
698
741
  velocity?: number;
699
742
  };
700
- /** パッチ削除指定(startStep + pitch で音符を特定)。 */
743
+ /** パッチ削除指定(startStep + pitchUnits で音符を特定)。 */
701
744
  type NoteRemove = {
702
745
  startStep: number;
703
- pitch: number;
746
+ /** 1/372オクターブ単位。{@link Note.pitchUnits} と同じ。 */
747
+ pitchUnits: number;
704
748
  };
705
749
  type PianoRollOptions = {
706
750
  mountTarget: HTMLElement;
@@ -740,7 +784,13 @@ type TrackConfig = {
740
784
  };
741
785
  type PlayNoteEvent = {
742
786
  trackId: string;
743
- pitch: number;
787
+ /**
788
+ * ピッチ。単位は 1/372オクターブの整数({@link Note.pitchUnits} と同じ)。
789
+ * 周波数へは `tuning.ts` の `unitsToHz`、SoundFont のような整数ゾーンの音源へは
790
+ * `unitsToMidiDetune` を使う。{@link PlayDrumEvent.pitch} はGM打楽器のキー番号で
791
+ * 音高ではないため、こちらとは別物。
792
+ */
793
+ pitchUnits: number;
744
794
  /** 元ノートのvelocity (0-127) */
745
795
  velocity: number;
746
796
  /** トラックvolume×velocityを反映した 0-1 程度の音量係数 */
@@ -822,7 +872,7 @@ type LyricTrack = {
822
872
  */
823
873
  pan: number;
824
874
  /**
825
- * オクターブシフト -2〜+2(半音換算で octave×12 だけ歌唱ピッチを上下する)。既定0。
875
+ * オクターブシフト -2〜+2octave×372 units = octave オクターブぶん歌唱ピッチを上下する)。既定0。
826
876
  * 音源ごとに得意な音域が異なるため、演奏ノート(@n)のピッチをそのまま使わず
827
877
  * オクターブ単位でずらして歌わせるための合成専用パラメータ。
828
878
  * MMLでは `@@n klatt o-1 …` のように o トークンで付与する。
@@ -1195,7 +1245,8 @@ type DawInstance = {
1195
1245
  */
1196
1246
  setTrackAudible: (trackId: string, audible: boolean) => void;
1197
1247
  /**
1198
- * 指定ノート位置(step, pitch)のキャンバス上のピクセル座標を返す。
1248
+ * 指定ノート位置(step, pitchUnits)のキャンバス上のピクセル座標を返す。
1249
+ * `pitch` の単位は units(1/372オクターブ)。
1199
1250
  * 画面外の場合は onScreen=false と方角 side を返す。
1200
1251
  * 協力DAWでのカーソル表示に使う。
1201
1252
  */
@@ -1353,7 +1404,7 @@ declare const playPlacements: (placements: Array<{
1353
1404
  trackIndex: number;
1354
1405
  startStep: number;
1355
1406
  durationSteps: number;
1356
- pitch: number;
1407
+ pitchUnits: number;
1357
1408
  velocity: number;
1358
1409
  }>, options: PlayPlacementsOptions) => MmlPlayback;
1359
1410
  /**
@@ -1364,7 +1415,7 @@ declare const playMML: (mml: string, options?: PlayMmlOptions) => MmlPlayback;
1364
1415
  type PlayNoteOptions = {
1365
1416
  audioContext?: AudioContext;
1366
1417
  destination?: AudioNode;
1367
- pitch: number;
1418
+ pitchUnits: number;
1368
1419
  volume?: number;
1369
1420
  duration?: number;
1370
1421
  };
@@ -1475,6 +1526,15 @@ declare class LinkedList<T> {
1475
1526
  }
1476
1527
 
1477
1528
  declare const PITCH_MAP: string[];
1529
+ /**
1530
+ * 31平均律の綴り表(度数0〜30)。
1531
+ *
1532
+ * 五度連鎖の伝統的綴りを基本にしつつ、重複臨時記号(`##`/`--`)を要する度数だけ
1533
+ * 微分音記号(`+`/`_`)の短縮形を採る。結果として全31度が2文字以内に収まる。
1534
+ * どの綴りもオクターブを跨がないものを選んであるので、`o<n>` の直後に置ける
1535
+ * (たとえば29度は `c-` ではなく `b+`。`c-` はCの2度下=前オクターブになってしまう)。
1536
+ */
1537
+ declare const EDO31_NAMES: string[];
1478
1538
  /**
1479
1539
  * ノートデータ管理とMML生成の責務を持つDOM非依存のコアロジック
1480
1540
  */
@@ -1491,7 +1551,9 @@ declare class MMLCore {
1491
1551
  private lastUndoTime;
1492
1552
  private static readonly UNDO_DEBOUNCE_MS;
1493
1553
  private toolMode;
1494
- constructor(handlers: CoreEventHandlers, volume?: number);
1554
+ /** グリッド寸法の供給元(描画器ではなく呼び出し側が持つ設定を読む) */
1555
+ private getConfig;
1556
+ constructor(handlers: CoreEventHandlers, volume: number | undefined, getConfig: () => RenderConfig);
1495
1557
  beginBatch(): void;
1496
1558
  endBatch(): void;
1497
1559
  saveHistory(): void;
@@ -1533,6 +1595,8 @@ declare class MMLCore {
1533
1595
  * ギャップに収まる最大の音符を探す(減算アルゴリズム用)
1534
1596
  */
1535
1597
  private findBestFitDuration;
1598
+ /** ピッチ(units) → その音律での「オクターブ番号」と「音名」。 */
1599
+ private spell;
1536
1600
  /**
1537
1601
  * ピッチからオクターブ最適化のある音名を取得
1538
1602
  */
@@ -1577,13 +1641,12 @@ declare const isChordHeavyTrack: (notes: Note[], threshold?: number) => boolean;
1577
1641
  * applyMonophonicMacro / shiftAllNotes を移植・整理したもの。
1578
1642
  */
1579
1643
 
1580
- /**
1581
- * アクティブトラックにスケールに沿ったランダムなノートを8小節分配置する。
1582
- */
1583
1644
  declare const generateRandomPattern: (core: MMLCore, options: {
1584
1645
  stepsPerBar: number;
1585
1646
  startStep: number;
1586
1647
  pitchRangeStart: number;
1648
+ /** 曲の音律。省略時は12平均律。 */
1649
+ edo?: number;
1587
1650
  }) => void;
1588
1651
  /**
1589
1652
  * 半小節ごとに伴奏トラックの構成音(pitch class)に合致しない音を削除する。
@@ -1602,11 +1665,16 @@ declare const applyMonophonic: (targetCore: MMLCore, chordCore: MMLCore, options
1602
1665
  */
1603
1666
  declare const shiftNotes: (cores: MMLCore[], shiftSteps: number) => void;
1604
1667
  /**
1605
- * 全トラックのノートを一括で移調する(半音単位)。歌唱ピッチもノート由来なので、
1606
- * 歌詞トラックの歌声も一緒に移調される。MIDI範囲(0-127)を超える場合はクランプする
1607
- * (音域外に飛んで無音・破綻するのを防ぐ)。
1668
+ * 全トラックのノートを一括で移調する。歌唱ピッチもノート由来なので、歌詞トラックの
1669
+ * 歌声も一緒に移調される。音域({@link PITCH_RANGE_START}〜{@link PITCH_RANGE_END})を
1670
+ * 超える場合はクランプする(音域外に飛んで無音・破綻するのを防ぐ)。
1671
+ *
1672
+ * 単位は「半音」ではなく**格子1ステップ**。12平均律では1ステップ=1半音だが、
1673
+ * 31平均律では1ステップ=1度(≒38.7セント)になる。31平均律で「半音」は
1674
+ * クロマチック半音(2度)とダイアトニック半音(3度)に分岐して一意に定まらないため、
1675
+ * 画面の「移調」操作と同じ格子基準に揃えてある。
1608
1676
  */
1609
- declare const transposeNotes: (cores: MMLCore[], semitones: number) => void;
1677
+ declare const transposeNotes: (cores: MMLCore[], steps: number) => void;
1610
1678
 
1611
1679
  type MidiTrackAnalysis = {
1612
1680
  index: number;
@@ -1752,6 +1820,11 @@ type MmlMeta = {
1752
1820
  fadeOut?: number;
1753
1821
  /** DAWの動作モード(simple | advanced) */
1754
1822
  mode?: "simple" | "advanced";
1823
+ /**
1824
+ * 曲全体の音律(1オクターブの分割数)。`#edo=31` で埋め込む。省略時は12(12平均律)。
1825
+ * 12と31のみ対応。音律は曲単位で、トラックや小節では変えられない。
1826
+ */
1827
+ edo?: number;
1755
1828
  /**
1756
1829
  * トラックごとの個別楽器名(GM楽器名)。`#t<n>inst=<名前>` で埋め込む。
1757
1830
  * 省略されたトラックはプリセットが適用される。
@@ -1801,7 +1874,8 @@ type MMLNotePlacement = {
1801
1874
  /** 0:melody 1:submelody 2:bass 3:chord */
1802
1875
  trackIndex: number;
1803
1876
  startStep: number;
1804
- pitch: number;
1877
+ /** 1/372オクターブ単位({@link Note.pitchUnits} と同じ)。 */
1878
+ pitchUnits: number;
1805
1879
  durationSteps: number;
1806
1880
  /** v コマンドで指定されたベロシティ(0-127、既定100) */
1807
1881
  velocity: number;
@@ -1961,84 +2035,54 @@ type PianoRollInstance = {
1961
2035
  };
1962
2036
  declare const createPianoRoll: (options: PianoRollOptions, handlers: CoreEventHandlers) => PianoRollInstance;
1963
2037
 
1964
- declare const getRenderConfig: () => RenderConfig;
1965
- /**
1966
- * カスタム背景画像の有無を設定します。
1967
- * 有効時はグリッド/ヘッダーの塗りつぶしを半透明にし、背景を透過させます。
1968
- */
1969
- declare const setBackgroundActive: (active: boolean) => void;
1970
- declare const getDrawOffset: () => {
1971
- x: number;
1972
- y: number;
1973
- };
1974
- declare const getGridCanvas: () => HTMLCanvasElement;
1975
- declare const getGridContext: () => CanvasRenderingContext2D;
1976
- declare const getHeaderCanvas: () => HTMLCanvasElement;
1977
- /**
1978
- * Canvasを初期化し、指定されたターゲット要素にマウントします。
1979
- * ヘッダー用、鍵盤用、ノート用の3つのCanvasを作成します。
1980
- */
1981
- declare const init: (mountTarget: HTMLElement, width: number | undefined, height: number | undefined, config: RenderConfig) => void;
1982
- /**
1983
- * 鍵盤を描画します。
1984
- * - 白鍵: クリーム色、全幅
1985
- * - 黒鍵: 左 62% を黒塗り、右 38% は白鍵色(奥に伸びて見える)
1986
- * - E→F / C→B(下オクターブ) の白白境界に区切り線
1987
- */
1988
- declare const drawKeyboard: () => void;
1989
- declare const drawHeader: () => void;
1990
2038
  /**
1991
- * グリッドと背景を描画します。(グリッドCanvasと鍵盤/ヘッダー描画の呼び出し)
1992
- * @param noteLengthSteps ノート長ステップ数(この値ごとに縦線を表示)
1993
- */
1994
- declare const drawGrid: (noteLengthSteps?: number) => void;
1995
- /**
1996
- * 指定されたノートの配列を描画します。
1997
- */
1998
- declare const drawNotes: (notes: Note[], color?: number[]) => void;
1999
- /**
2000
- * ノートの上に歌詞(かな)を重ねて描画します。
2001
- *
2002
- * 音節の割り当ては発音側(StreamVoiceTrack の組み立て)と同じ規則で、
2003
- * startStep 昇順に並べたノートの i 番目へ syllables[i] を対応させます。
2004
- * 音節が足りないぶんのノートには何も描きません。
2039
+ * 1つのピアノロール描画面(ヘッダー/鍵盤/グリッドの3枚のCanvas)を表す描画器。
2005
2040
  *
2006
- * 文字はノート矩形でクリップするため、隣のノートへはみ出しません。
2007
- */
2008
- declare const drawNoteLyrics: (notes: Note[], syllables: string[]) => void;
2009
- /**
2010
- * 選択範囲の四角形を描画します。
2011
- */
2012
- declare const drawSelectionRect: (rect: {
2013
- x: number;
2014
- y: number;
2015
- width: number;
2016
- height: number;
2017
- } | null) => void;
2018
- /**
2019
- * 選択されたノートをハイライト描画します。(濃い色で描画、枠なし)
2020
- */
2021
- declare const drawSelectedNotes: (notes: Note[], selectedIds: Set<number>, baseColor?: number[]) => void;
2022
- /**
2023
- * カーソルの座標取得
2024
- * (グリッドCanvasの相対座標を取得)
2025
- */
2026
- declare const getXY: (e: MouseEvent | PointerEvent) => [number, number, number];
2027
- declare const getGridPosition: (e: MouseEvent | PointerEvent) => {
2028
- step: number;
2029
- pitch: number;
2030
- x: number;
2031
- y: number;
2041
+ * 以前はモジュールグローバル(`g_config` / 各Canvas / 描画オフセット)を直に触る
2042
+ * 関数群だったが、それだと1ページに2つ以上のエディタをマウントしたとき後からマウント
2043
+ * した側がグローバルを奪い、先にマウントした側の描画が相手のCanvasへ流れ込んでいた。
2044
+ * 曲ごとに音律(12平均律 / 31平均律)が違うと格子まで食い違うため、描画状態は
2045
+ * インスタンスに閉じ込める。
2046
+ */
2047
+ type Renderer = {
2048
+ getRenderConfig: () => RenderConfig;
2049
+ setBackgroundActive: (active: boolean) => void;
2050
+ getDrawOffset: () => {
2051
+ x: number;
2052
+ y: number;
2053
+ };
2054
+ getGridCanvas: () => HTMLCanvasElement;
2055
+ getGridContext: () => CanvasRenderingContext2D;
2056
+ getHeaderCanvas: () => HTMLCanvasElement;
2057
+ drawKeyboard: () => void;
2058
+ drawHeader: () => void;
2059
+ drawGrid: (noteLengthSteps?: number) => void;
2060
+ drawNotes: (notes: Note[], color?: number[], isActive?: boolean) => void;
2061
+ drawNoteLyrics: (notes: Note[], syllables: string[]) => void;
2062
+ drawSelectionRect: (rect: {
2063
+ x: number;
2064
+ y: number;
2065
+ width: number;
2066
+ height: number;
2067
+ } | null) => void;
2068
+ drawSelectedNotes: (notes: Note[], selectedIds: Set<number>, baseColor?: number[]) => void;
2069
+ getXY: (e: MouseEvent | PointerEvent) => [number, number, number];
2070
+ getGridPosition: (e: MouseEvent | PointerEvent) => {
2071
+ step: number;
2072
+ pitch: number;
2073
+ x: number;
2074
+ y: number;
2075
+ };
2076
+ onClick: (callback: (step: number, pitch: number) => void) => void;
2077
+ setDrawOffset: (x: number, y: number) => void;
2078
+ /** Canvasをマウント先から取り外す。 */
2079
+ destroy: () => void;
2032
2080
  };
2033
2081
  /**
2034
- * ユーザーのクリックイベントを抽象化し、グリッド座標をコールバックに渡します。
2035
- * イベントリスナーをグリッドCanvasにのみ追加します。
2036
- */
2037
- declare const onClick: (callback: (step: number, pitch: number) => void) => void;
2038
- /**
2039
- * 描画オフセット(描画開始ピクセル位置)を設定します。
2082
+ * Canvasを生成してマウントし、そのマウント面専用の描画器を返す。
2083
+ * 同じページに複数生成しても互いの状態を踏まない。
2040
2084
  */
2041
- declare const setDrawOffset: (x: number, y: number) => void;
2085
+ declare const createRenderer: (mountTarget: HTMLElement, width: number | undefined, height: number | undefined, config: RenderConfig) => Renderer;
2042
2086
 
2043
2087
  /**
2044
2088
  * 再生シーケンサ。タイムライン計算と先読みスケジューリングを担い、
@@ -2094,10 +2138,13 @@ type SoundFontInstance = {
2094
2138
  play: (o: {
2095
2139
  ctx: AudioContext;
2096
2140
  destination: AudioNode;
2141
+ /** 最寄りの整数MIDIノート番号(ゾーン選択用)。 */
2097
2142
  pitch: number;
2098
2143
  volume: number;
2099
2144
  /** 元ノートのvelocity(0-127)。音量ではなく音色の明るさにだけ効く。 */
2100
2145
  velocity?: number;
2146
+ /** pitch からの微調整(セント)。31平均律など整数ノートに乗らない音高用。 */
2147
+ detuneCents?: number;
2101
2148
  when: number;
2102
2149
  duration: number;
2103
2150
  }) => void;
@@ -2349,7 +2396,8 @@ type DtmStudio = {
2349
2396
  playDrumEvent: (e: PlayDrumEvent) => void;
2350
2397
  /** SoundFontを用いた単音再生を行う */
2351
2398
  playNote: (options: {
2352
- pitch: number;
2399
+ /** ピッチ。単位は units(1/372オクターブ)。`pitchV1ToUnits` でMIDI番号から変換できる。 */
2400
+ pitchUnits: number;
2353
2401
  volume?: number;
2354
2402
  duration?: number;
2355
2403
  instrument?: string;
@@ -2410,7 +2458,7 @@ declare const createDtmStudio: (options?: DtmStudioOptions) => Promise<DtmStudio
2410
2458
  * ドット絵・レトロゲーム風ピクセルアートデザイン(美咲フォント・角なし・ハードシャドウ)。
2411
2459
  * モバイルファースト(狭幅基準)で設計し、min-width メディアクエリで広幅に拡張する。
2412
2460
  */
2413
- 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 \u306F document.body \u76F4\u4E0B\u3078\u91CD\u306D\u308B\u305F\u3081\u3001.dtm-daw \u306E\u5916\u306B\u51FA\u308B\u3002\u3053\u308C\u3089\u3082\u540C\u69D8\u306B\u30C8\u30FC\u30AF\u30F3\u3092\n \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 /* 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.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.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: 3px;\n}\n.dtm-pill {\n --dtm-pill-color: var(--dtm-primary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 1 1 0;\n min-width: 0;\n height: 26px;\n padding: 0;\n border: 2px solid var(--c-black);\n background: color-mix(in srgb, var(--dtm-pill-color) 40%, black);\n color: var(--c-white);\n font-family: var(--dtm-font);\n font-size: 11px;\n font-weight: bold;\n cursor: pointer;\n box-shadow: 2px 2px 0 var(--c-black);\n opacity: 0.7;\n}\n/* \u30A2\u30AF\u30C6\u30A3\u30D6\u9078\u629E = \u4E0D\u900F\u660E + \u91D1\u67A0 */\n.dtm-pill--active {\n opacity: 1;\n border-color: var(--dtm-gold);\n box-shadow: 0 0 0 1px var(--dtm-gold), 2px 2px 0 var(--c-black);\n}\n.dtm-pill:not(.dtm-pill--active):active { transform: translate(2px,2px); box-shadow: none; }\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 background: color-mix(in srgb, var(--dtm-pill-color) 85%, white);\n transition: background 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 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.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.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\u63A7\u3048\u3081\u306A\u4ED5\u5207\u308A\u7DDA\uFF0B\u5C0F\u3055\u3044\u25B6\u30DE\u30FC\u30AB\u30FC\u3060\u3051\u4ED8\u3051\u308B\u3002 */\n.dtm-advanced {\n border-top: 1px dashed var(--dtm-border2);\n padding-top: 6px;\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-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.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";
2461
+ 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 \u306F document.body \u76F4\u4E0B\u3078\u91CD\u306D\u308B\u305F\u3081\u3001.dtm-daw \u306E\u5916\u306B\u51FA\u308B\u3002\u3053\u308C\u3089\u3082\u540C\u69D8\u306B\u30C8\u30FC\u30AF\u30F3\u3092\n \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 /* 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.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.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/* \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 \u30A2\u30AF\u30C6\u30A3\u30D6\u30C8\u30E9\u30C3\u30AF\u60C5\u5831\u30D0\u30CA\u30FC \u2500\u2500\u2500 */\n.dtm-active-track-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 10px;\n background: color-mix(in srgb, var(--dtm-track-color, var(--dtm-primary)) 16%, var(--dtm-deep));\n border: 2px solid var(--c-black);\n border-left: 5px solid var(--dtm-track-color, var(--dtm-primary));\n box-shadow: 2px 2px 0 var(--c-black);\n margin-bottom: 2px;\n}\n.dtm-active-track-badge {\n font-family: var(--dtm-font);\n font-size: 11px;\n font-weight: bold;\n background: var(--dtm-track-color, var(--dtm-primary));\n color: #ffffff;\n text-shadow: 1px 1px 0 #000, -1px -1px 0 #000;\n padding: 2px 6px;\n border: 1px solid var(--c-black);\n border-radius: 2px;\n letter-spacing: .06em;\n}\n.dtm-active-track-name {\n font-family: var(--dtm-font);\n font-size: 12px;\n font-weight: bold;\n color: var(--c-white);\n flex: 1 1 auto;\n}\n.dtm-active-track-pill {\n font-family: var(--dtm-font);\n font-size: 9px;\n font-weight: bold;\n letter-spacing: .08em;\n padding: 2px 5px;\n color: var(--dtm-gold);\n border: 1px solid var(--dtm-gold);\n background: rgba(0, 0, 0, 0.45);\n border-radius: 2px;\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.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.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\u63A7\u3048\u3081\u306A\u4ED5\u5207\u308A\u7DDA\uFF0B\u5C0F\u3055\u3044\u25B6\u30DE\u30FC\u30AB\u30FC\u3060\u3051\u4ED8\u3051\u308B\u3002 */\n.dtm-advanced {\n border-top: 1px dashed var(--dtm-border2);\n padding-top: 6px;\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-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.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";
2414
2462
  /**
2415
2463
  * スタイルを document.head に一度だけ注入する。
2416
2464
  */
@@ -2441,8 +2489,11 @@ declare const showLoadingOverlay: (container: HTMLElement, options?: {
2441
2489
  * ミキサーへルーティングしたり、SE と AudioContext を共有したりできるようにするため。
2442
2490
  */
2443
2491
 
2444
- /** MIDIピッチ番号 → 周波数(Hz)。A4(69)=440Hz 基準。 */
2445
- declare const freqFromPitch: (pitch: number) => number;
2492
+ /**
2493
+ * ピッチ(units) → 周波数(Hz)。A4 = 2139 units = 440Hz 基準。
2494
+ * 単位は 1/372オクターブの整数(`tuning.ts` 参照)。12平均律・31平均律とも同じ式で鳴る。
2495
+ */
2496
+ declare const freqFromPitch: (pitchUnits: number) => number;
2446
2497
  type Synth = {
2447
2498
  /** メロディックノートを発音する(PlayNoteEvent.when は ctx.currentTime からの相対秒) */
2448
2499
  playNote: (e: PlayNoteEvent) => void;
@@ -2468,6 +2519,122 @@ type SynthTone = {
2468
2519
  */
2469
2520
  declare const createSynth: (ctx: AudioContext, destination?: AudioNode, tone?: SynthTone) => Synth;
2470
2521
 
2522
+ /**
2523
+ * 音律(12平均律 / 31平均律)と、ピッチの内部表現。
2524
+ *
2525
+ * ## 単位
2526
+ *
2527
+ * ノートのピッチは **1/372オクターブの整数** で持つ。372 = 12 × 31 で、12と31は
2528
+ * 互いに素なので最小公倍数がこれになり、**12平均律と31平均律の両方が誤差ゼロで
2529
+ * 同じ数直線に乗る**。
2530
+ *
2531
+ * 12平均律 1半音 = 31 units
2532
+ * 31平均律 1度 = 12 units
2533
+ * 1 unit = 1200/372 ≒ 3.2258 セント
2534
+ *
2535
+ * 整数のままなので `a.pitchUnits === b.pitchUnits` の同値判定が全部生き残る
2536
+ * (重複判定・当たり判定・協調編集の (startStep, pitchUnits) キー)。小数にすると
2537
+ * ここが軒並み壊れるため、細かい整数単位を選んでいる。
2538
+ *
2539
+ * ## 音律は音声経路に入らない
2540
+ *
2541
+ * ピッチが絶対値なので、シーケンサも発音器も音律を知らなくてよい。音律は
2542
+ * 「格子・記譜・表示」だけに効く編集上の概念で、`RenderConfig.edo` に置く。
2543
+ */
2544
+ /** 1オクターブあたりの units。12 × 31。 */
2545
+ declare const UNITS_PER_OCTAVE = 372;
2546
+ /** 12平均律の1半音あたりの units。 */
2547
+ declare const UNITS_PER_SEMITONE: number;
2548
+ /** 31平均律の1度あたりの units。 */
2549
+ declare const UNITS_PER_EDO31_DEGREE: number;
2550
+ /** 1 unit のセント値。 */
2551
+ declare const CENTS_PER_UNIT: number;
2552
+ /** A4 (MIDI 69) の units。周波数計算の基準。 */
2553
+ declare const A4_UNITS: number;
2554
+ /** A4 の周波数(Hz)。 */
2555
+ declare const A4_HZ = 440;
2556
+ /** 対応する音律(1オクターブの分割数)。 */
2557
+ type Edo = 12 | 31;
2558
+ /** 既定の音律。宣言のない曲はすべてこれ(=既存データは素通り)。 */
2559
+ declare const DEFAULT_EDO: Edo;
2560
+ /** その音律の1格子ステップが何 units か。 */
2561
+ declare const unitsPerStep: (edo: Edo) => number;
2562
+ /** MIDIノート番号 → units。 */
2563
+ declare const midiToUnits: (midi: number) => number;
2564
+ /**
2565
+ * units → MIDIノート番号(小数)。
2566
+ * 歌声合成(koe)は Hz を受けるためこの小数値をそのまま渡してよい。
2567
+ * SoundFont のように整数ゾーンしか持たない発音器は {@link unitsToMidiDetune} を使う。
2568
+ */
2569
+ declare const unitsToMidi: (units: number) => number;
2570
+ /** units → 周波数(Hz)。 */
2571
+ declare const unitsToHz: (units: number) => number;
2572
+ /**
2573
+ * units → 「最寄りの整数MIDIノート番号 + セント補正」。
2574
+ *
2575
+ * SoundFont は音高ごとに整数キーでゾーンを持つため小数ピッチを直接鳴らせない。
2576
+ * 最寄りのゾーンを鳴らして残差を `AudioBufferSourceNode.detune` で補正する。
2577
+ * 31平均律での残差は最大 ±48.4 セントで、detune の可動域に十分収まる。
2578
+ */
2579
+ declare const unitsToMidiDetune: (units: number) => {
2580
+ midi: number;
2581
+ detuneCents: number;
2582
+ };
2583
+ /**
2584
+ * 臨時記号1つあたりの格子ステップ数。
2585
+ *
2586
+ * - `#` / `+`(12平均律) … クロマチック半音上げ
2587
+ * - `-` … クロマチック半音下げ
2588
+ * - `+`(31平均律) … 格子1ステップ上げ(微分音)
2589
+ * - `_` … 格子1ステップ下げ(微分音)
2590
+ *
2591
+ * 12平均律ではクロマチック半音=1格子ステップなので4記号すべてが従来の意味に潰れ、
2592
+ * 既存MMLの解釈は1文字も変わらない。31平均律でのみ `#`/`-`(±2度)と
2593
+ * `+`/`_`(±1度)が分岐する。
2594
+ */
2595
+ declare const chromaticStep: (edo: Edo) => number;
2596
+ /** 微分音記号 `+` / `_` 1つあたりの格子ステップ数。常に1。 */
2597
+ declare const MICRO_STEP = 1;
2598
+ /** 幹音の文字か。 */
2599
+ declare const isNaturalLetter: (ch: string) => boolean;
2600
+ /** 幹音の文字 → オクターブ内の格子ステップ。未知の文字は null。 */
2601
+ declare const naturalStep: (ch: string, edo: Edo) => number | null;
2602
+ /**
2603
+ * 音名・オクターブ・臨時記号から units を組み立てる。
2604
+ *
2605
+ * `octave` はMMLの `o` 指定(MIDI慣習で o4 の c が中央ド = MIDI 60)。
2606
+ * 臨時記号でオクターブを跨ぐ綴り(`b##` が次オクターブへ、`c--` が前オクターブへ)も
2607
+ * そのまま加算されるので、度数を 0〜edo-1 にクランプしてはいけない。
2608
+ */
2609
+ declare const spellingToUnits: (letter: string, octave: number, chromatic: number, micro: number, edo: Edo) => number | null;
2610
+ /**
2611
+ * 五度圏インデックス(C=0, G=1, F=-1, C#=7, Db=-5)→ オクターブ内の格子ステップ。
2612
+ *
2613
+ * ミーントーン系の音律はすべて「五度を何ステップとするか」だけで決まるため、
2614
+ * 綴りを持つ音(chord-parser の `rootFifth` / `noteFifths` など)はこの一本で
2615
+ * どちらの音律へも正確に写せる。12平均律では C# と Db が同じ値に潰れ、
2616
+ * 31平均律では 2 と 3 に分かれる。
2617
+ */
2618
+ declare const fifthToStep: (fifthIndex: number, edo: Edo) => number;
2619
+ /** 五度圏インデックス → オクターブ内の units。 */
2620
+ declare const fifthToUnits: (fifthIndex: number, edo: Edo) => number;
2621
+ /**
2622
+ * ピッチ表現のバージョン。
2623
+ *
2624
+ * - v1 … `pitch` が半音(MIDIノート番号)。dtm 1.x
2625
+ * - v2 … `pitchUnits` が 1/372オクターブ単位。dtm 2.x
2626
+ *
2627
+ * dtm 自身は通信路を持たず `onNotesPatch` / `applyPatch` のフックを出すだけなので、
2628
+ * バージョンの突き合わせは利用側アプリのハンドシェイクの責務になる。変換の知識だけを
2629
+ * ここに置く。v1→v2 は無損失だが、**v2→v1 は12平均律の曲でしか成立しない**
2630
+ * (31平均律を半音へ丸めると最大48.4セント動く)。
2631
+ */
2632
+ declare const PITCH_ENCODING_VERSION = 2;
2633
+ /** v1(半音)→ v2(units)。無損失。 */
2634
+ declare const pitchV1ToUnits: (pitch: number) => number;
2635
+ /** v2(units)→ v1(半音)。12平均律の曲でのみ無損失。 */
2636
+ declare const unitsToPitchV1: (units: number) => number;
2637
+
2471
2638
  declare const VOICE_IMAGES: Record<string, string>;
2472
2639
 
2473
2640
  /**
@@ -2483,4 +2650,4 @@ declare const encodeWavPCM16: (channels: Float32Array[], sampleRate: number) =>
2483
2650
  /** Float32Array のチャンクを1本へ連結する。 */
2484
2651
  declare const concatFloat32: (chunks: Float32Array[]) => Float32Array;
2485
2652
 
2486
- export { type AddNoteOptions, type AnyDrumPattern, type ApplyChordOptions, type ChordPatternType, type ChordPlacement, type ChordPlayerInstance, type ConsumedSyllable, type CoreEventHandlers, type CustomVocalDef, DAW_CSS, DEFAULT_BPM, DEFAULT_GATE, DEFAULT_PAN, DEFAULT_PLAYBACK_VELOCITY, DEFAULT_STEPS_PER_BAR, DEFAULT_VELOCITY, DEFAULT_VOCAL_VOLUME, DRUM_FONT, DRUM_KEYS, DRUM_PATTERNS, type DawInstance, type DawMode, type DawOptions, type DawViewState, type DrumPattern, type DrumPatternDef, type DtmStudio, type DtmStudioEngines, type DtmStudioOptions, type ExportMidiOptions, type FadeScheduleParams, GM_INSTRUMENT_NAMES, INSTRUMENT_PRESETS, type InstrumentPreset, KOE_BASE_URL, KOE_VOICEBANKS, KOE_VOICEBANK_LABELS, KOE_VOICEBANK_TERMS, type KoeVoiceOptions, LinkedList, type LoopConfig, type LoopPoint, type LyricSyllable, type LyricSyncData, type LyricTrack, type LyricsConductor, MAX_VOCAL_VOLUME, MMLCore, type MMLDisplayToken, type MMLNotePlacement, MML_END_MARKER, type MidiExtraction, 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 Note, type NoteData, type NoteRemove, type OctaveUnisonMode, PITCH_MAP, PREWARM_NOTES, type ParseMMLOptions, type ParseMidiFn, type ParsedMML, type PianoRollInstance, type PianoRollOptions, type PicotuneSearchParams, type PicotuneSong, type PitchToken, type PlayChordsOptions, type PlayDrumEvent, type PlayMmlOptions, type PlayNoteEvent, type PlayNoteOptions, type PlayPlacementsOptions, type PlaySingingMmlOptions, type PlaybackCue, type PlaybackState, type PresetSelectInstance, type PresetSelectOptions, type PreviewSoundCallback, type RenderConfig, type Sequencer, type SequencerOptions, type SequencerTrack, type SingingVoices, type SingingVoicesOptions, type StreamPlaybackOptions, type StreamVoiceNote, type StreamVoiceTrack, type Synth, TRACKS_ADVANCED, TRACKS_SIMPLE, type ToolMode, type TrackConfig, VIBRATO_MIN_SEC, VOICE_IMAGES, VOICE_IMAGE_KEY, type VoiceExpression, type VoiceModel, type VoiceRegistry, analyzeMidiTracks, applyHarmonicFilter, applyMonophonic, buildChordPlacements, buildDrumPatternJson, buildNameToKeyMapping, collectPitchTokens, concatFloat32, createAudioContext, createDtmStudio, createKlattVoice, createKoeVoice, createLyricsConductor, createPianoRoll, createSequencer, createSingingVoices, createSynth, createVoiceRegistry, decodeMml, decomposeToMonophonic, drawGrid, drawHeader, drawKeyboard, drawNoteLyrics, drawNotes, drawSelectedNotes, drawSelectionRect, encodeMml, encodeWavPCM16, exportMIDI, extractDrumPatternFromNotes, extractMidiDrumPattern, extractMidiPlacements, extractMidiPlacementsByTrack, formatMmlMeta, freqFromPitch, generateRandomPattern, getDrawOffset, getDrumPatternKeys, getGridCanvas, getGridContext, getGridPosition, getHeaderCanvas, getMidiBPM, getRenderConfig, getXY, icon, init, injectStyles, isChordHeavyTrack, isPlausibleMidiTranscription, isValidHttpUrl, koeUrl, mountChordPlayer, mountDAW, mountMmlPlayer, normalizeDrumPatterns, normalizeLyrics, onClick, panToStereo, parseCustomVocals, parseLyrics, parseMML, parseMmlMeta, playChords, playMML, playNote, playPlacements, playSingingMML, resolveDrumPattern, resolveLoopPoint, setBackgroundActive, setDrawOffset, shiftNotes, showLoadingOverlay, stripCustomVocals, stripLyrics, stripMmlMeta, transposeNotes, vocalVolumeToGain };
2653
+ export { A4_HZ, A4_UNITS, type AddNoteOptions, type AnyDrumPattern, type ApplyChordOptions, CENTS_PER_UNIT, type ChordPatternType, type ChordPlacement, type ChordPlayerInstance, type ConsumedSyllable, type CoreEventHandlers, type CustomVocalDef, DAW_CSS, DEFAULT_BPM, DEFAULT_EDO, DEFAULT_GATE, DEFAULT_PAN, DEFAULT_PLAYBACK_VELOCITY, DEFAULT_STEPS_PER_BAR, DEFAULT_VELOCITY, DEFAULT_VOCAL_VOLUME, DRUM_FONT, DRUM_KEYS, DRUM_PATTERNS, 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 FadeScheduleParams, GM_INSTRUMENT_NAMES, INSTRUMENT_PRESETS, type InstrumentPreset, KEY_COUNT, KOE_BASE_URL, KOE_VOICEBANKS, KOE_VOICEBANK_LABELS, KOE_VOICEBANK_TERMS, type KoeVoiceOptions, LinkedList, type LoopConfig, type LoopPoint, type LyricSyllable, type LyricSyncData, type LyricTrack, type LyricsConductor, MAX_VOCAL_VOLUME, MICRO_STEP, MMLCore, type MMLDisplayToken, type MMLNotePlacement, MML_END_MARKER, type MidiExtraction, 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 Note, type NoteData, type NoteRemove, type OctaveUnisonMode, PITCH_ENCODING_VERSION, PITCH_MAP, PITCH_RANGE_END, PITCH_RANGE_START, PREWARM_NOTES, type ParseMMLOptions, type ParseMidiFn, type ParsedMML, type PianoRollInstance, type PianoRollOptions, type PicotuneSearchParams, type PicotuneSong, type PitchToken, type PlayChordsOptions, type PlayDrumEvent, type PlayMmlOptions, type PlayNoteEvent, type PlayNoteOptions, type PlayPlacementsOptions, type PlaySingingMmlOptions, type PlaybackCue, type PlaybackState, type PresetSelectInstance, type PresetSelectOptions, type PreviewSoundCallback, type RenderConfig, type Renderer, type Sequencer, type SequencerOptions, type SequencerTrack, type SingingVoices, type SingingVoicesOptions, type StreamPlaybackOptions, type StreamVoiceNote, type StreamVoiceTrack, type Synth, TRACKS_ADVANCED, TRACKS_SIMPLE, type ToolMode, type TrackConfig, UNITS_PER_EDO31_DEGREE, UNITS_PER_OCTAVE, UNITS_PER_SEMITONE, VIBRATO_MIN_SEC, VOICE_IMAGES, VOICE_IMAGE_KEY, type VoiceExpression, type VoiceModel, type VoiceRegistry, analyzeMidiTracks, applyHarmonicFilter, applyMonophonic, buildChordPlacements, buildDrumPatternJson, buildNameToKeyMapping, chromaticStep, collectPitchTokens, concatFloat32, createAudioContext, createDtmStudio, createKlattVoice, createKoeVoice, createLyricsConductor, createPianoRoll, createRenderer, createSequencer, createSingingVoices, createSynth, createVoiceRegistry, decodeMml, decomposeToMonophonic, encodeMml, encodeWavPCM16, exportMIDI, extractDrumPatternFromNotes, extractMidiDrumPattern, extractMidiPlacements, extractMidiPlacementsByTrack, fifthToStep, fifthToUnits, formatMmlMeta, freqFromPitch, generateRandomPattern, getDrumPatternKeys, getMidiBPM, icon, injectStyles, isChordHeavyTrack, isNaturalLetter, isPlausibleMidiTranscription, isValidHttpUrl, keyCountFor, koeUrl, midiToUnits, mountChordPlayer, mountDAW, mountMmlPlayer, naturalStep, normalizeDrumPatterns, normalizeLyrics, panToStereo, parseCustomVocals, parseLyrics, parseMML, parseMmlMeta, pitchV1ToUnits, playChords, playMML, playNote, playPlacements, playSingingMML, resolveDrumPattern, resolveLoopPoint, shiftNotes, showLoadingOverlay, spellingToUnits, stripCustomVocals, stripLyrics, stripMmlMeta, transposeNotes, unitsPerRow, unitsPerStep, unitsToHz, unitsToMidi, unitsToMidiDetune, unitsToPitchV1, vocalVolumeToGain };