@nice2dev/ui-audio 1.3.13 → 1.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/index.cjs +31 -31
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.mjs +5635 -5524
  5. package/dist/karaoke/PitchMeter.d.ts +45 -0
  6. package/dist/ui-audio.css +1 -1
  7. package/dist/utils/pitchMath.d.ts +9 -0
  8. package/package.json +3 -3
  9. package/dist/__benchmarks__/audio-latency.bench.d.ts +0 -1
  10. package/dist/assets/scoringWorker-B1PkYu_m.js +0 -1
  11. package/dist/constants/index.d.ts +0 -5
  12. package/dist/constants/ui.d.ts +0 -2
  13. package/dist/editor/AudioClipBox.d.ts +0 -8
  14. package/dist/editor/AudioClipInfo.d.ts +0 -6
  15. package/dist/editor/AudioEditorPianoRoll.d.ts +0 -19
  16. package/dist/editor/AudioEditorPianoRollContainer.d.ts +0 -19
  17. package/dist/editor/AudioLayerDetails.d.ts +0 -9
  18. package/dist/editor/AudioLayerDetailsContainer.d.ts +0 -9
  19. package/dist/editor/AudioLayersNavContainer.d.ts +0 -8
  20. package/dist/editor/AudioMiniMap.d.ts +0 -10
  21. package/dist/editor/AudioMiniMapContainer.d.ts +0 -9
  22. package/dist/editor/AudioSourceDetails.d.ts +0 -11
  23. package/dist/editor/AudioTimelineContainer.d.ts +0 -17
  24. package/dist/editor/AudioTimelineNavContainer.d.ts +0 -13
  25. package/dist/editor/CCLaneSelector.d.ts +0 -13
  26. package/dist/editor/editorDisplayModes.d.ts +0 -36
  27. package/dist/editor/editorIO.d.ts +0 -10
  28. package/dist/editor/nav/AudioLayersNav.d.ts +0 -8
  29. package/dist/editor/nav/AudioProjectSectionNav.d.ts +0 -11
  30. package/dist/editor/nav/AudioTimelineNav.d.ts +0 -13
  31. package/dist/editor/nav/SaveLoadControls.d.ts +0 -8
  32. package/dist/editor/panels/AdvancedEditingPanel.d.ts +0 -29
  33. package/dist/editor/panels/DisplayModeSelector.d.ts +0 -8
  34. package/dist/editor/panels/LayerTrack.d.ts +0 -16
  35. package/dist/editor/panels/ProjectPanel.d.ts +0 -22
  36. package/dist/editor/panels/SectionPanel.d.ts +0 -10
  37. package/dist/editor/useEditorRecording.d.ts +0 -44
  38. package/dist/engine/NiceAudioWorklet.d.ts +0 -183
  39. package/dist/engine/NiceMultitrackExport.d.ts +0 -164
  40. package/dist/engine/audioKeyboard.d.ts +0 -27
  41. package/dist/engine/audioLayerDetails.d.ts +0 -12
  42. package/dist/engine/audioProject.d.ts +0 -9
  43. package/dist/engine/audioUtils.d.ts +0 -2
  44. package/dist/engine/generate-pitch-points.d.ts +0 -1
  45. package/dist/engine/pitch-worklet-processor.d.ts +0 -10
  46. package/dist/engine/pitch_client.d.ts +0 -15
  47. package/dist/models/game/modelsGame.d.ts +0 -11
  48. package/dist/models/index.d.ts +0 -15
  49. package/dist/models/modelsAiAudio.d.ts +0 -120
  50. package/dist/models/modelsAiVideo.d.ts +0 -74
  51. package/dist/models/modelsPlatforms.d.ts +0 -51
  52. package/dist/player/GenericPlayerStageVisualizer.d.ts +0 -31
  53. package/dist/player/GenericPlayerTrackList.d.ts +0 -9
  54. package/dist/player/nowPlayingAdapter.d.ts +0 -18
  55. package/dist/utils/articulationEngine.d.ts +0 -68
  56. package/dist/utils/chordScale.d.ts +0 -46
  57. package/dist/utils/clipLauncher.d.ts +0 -96
  58. package/dist/utils/envelopeFollower.d.ts +0 -45
  59. package/dist/utils/gameAudio.d.ts +0 -236
  60. package/dist/utils/index.d.ts +0 -39
  61. package/dist/utils/macroSystem.d.ts +0 -96
  62. package/dist/utils/padKaraokeSession.d.ts +0 -49
  63. package/dist/utils/songDataHelpers.d.ts +0 -58
@@ -0,0 +1,45 @@
1
+ import { NiceBaseProps } from '@nice2dev/ui-core';
2
+ import { default as React } from 'react';
3
+ /** Props for {@link NicePitchMeter}. */
4
+ export interface NicePitchMeterProps extends NiceBaseProps {
5
+ /** The pitch sung now, in Hz; `null` / `0` — silence. */
6
+ pitch?: number | null;
7
+ /** The note to hit, as a MIDI note number (60 = C4, 69 = A4); `null` — no target. */
8
+ target?: number | null;
9
+ /**
10
+ * The recent pitches in Hz, oldest first (`null` / `0` — silence). Without it the meter keeps the
11
+ * last `historyLength` values of `pitch` itself.
12
+ */
13
+ history?: readonly (number | null)[];
14
+ /** Draw the band around the target. Default `true`. */
15
+ showTarget?: boolean;
16
+ /** Draw the trace of the recent pitches. Default `true`. */
17
+ showHistory?: boolean;
18
+ /** How many recent pitches the trace holds. Default 100. */
19
+ historyLength?: number;
20
+ /** Semitones from the target that still count as a hit. Default 1. */
21
+ tolerance?: number;
22
+ /** Semitones shown above and below the middle. Default 6. */
23
+ range?: number;
24
+ /** Colour of a pitch on target. Default the theme's success colour. */
25
+ hitColor?: string;
26
+ /** Colour of a pitch off target. Default the theme's error colour. */
27
+ missColor?: string;
28
+ /** Colour of the target band. Default the theme's primary colour. */
29
+ targetColor?: string;
30
+ /** Height in px. Default 120. */
31
+ height?: number;
32
+ /** The waiting state's text. Default "Waiting for a voice…". */
33
+ idleText?: React.ReactNode;
34
+ 'aria-label'?: string;
35
+ }
36
+ /**
37
+ * {@link NicePitchMeter} — a live pitch meter: target band, history trace, current pitch.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * <NicePitchMeter pitch={hz} target={note.midi} showHistory historyLength={100} height={120} />
42
+ * ```
43
+ */
44
+ export declare const NicePitchMeter: React.FC<NicePitchMeterProps>;
45
+ export default NicePitchMeter;
package/dist/ui-audio.css CHANGED
@@ -1 +1 @@
1
- .nice-audio-error-boundary{display:flex;align-items:center;justify-content:center;min-height:160px;padding:var(--nice-space-6, 24px) var(--nice-space-4, 16px);color:var(--nice-text-primary, inherit);background:var(--nice-danger-bg, #fef2f2);border:1px solid color-mix(in srgb,var(--nice-color-danger, #ef4444) 30%,transparent);border-radius:var(--nice-radius-lg, 8px)}.nice-audio-error-boundary__content{display:flex;flex-direction:column;align-items:center;gap:var(--nice-space-2, 8px);max-width:60ch;text-align:center}.nice-audio-error-boundary__title{margin:0;font-size:var(--nice-font-size-lg, 1rem);font-weight:var(--nice-font-weight-semibold, 600)}.nice-audio-error-boundary__message{margin:0;color:var(--nice-text-secondary, #64748b);font-size:var(--nice-font-size-sm, .8125rem);overflow-wrap:anywhere}.nice-audio-error-boundary__retry{margin-top:var(--nice-space-1, 4px);padding:var(--nice-space-1-5, 6px) var(--nice-space-4, 16px);border:1px solid var(--nice-border-color, #e2e8f0);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #fff);color:var(--nice-text-primary, inherit);font:inherit;font-size:var(--nice-font-size-sm, .8125rem);cursor:pointer}.nice-audio-error-boundary__retry:hover{background:var(--nice-bg-secondary, #f8fafc)}.nice-audio-error-boundary__retry:focus-visible{outline:none;box-shadow:var(--nice-focus-ring, 0 0 0 2px var(--nice-color-primary, #3b82f6))}._panel_3bj7x_3{margin-bottom:var(--nice-space-3, 12px);padding:var(--nice-space-3, 12px);border:1px solid var(--nice-border-color, #e5e7eb);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #ffffff);color:var(--nice-text-primary, #0f172a)}._panelCompact_3bj7x_19{padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px)}._panelNarrow_3bj7x_25{max-width:520px}._panelWide_3bj7x_31{max-width:820px}._heading_3bj7x_37{margin:0 0 var(--nice-space-2, 8px);font-size:var(--nice-font-size-md, 14px);font-weight:var(--nice-font-weight-semibold, 600)}._row_3bj7x_53{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--nice-space-2, 8px) var(--nice-space-3, 12px)}._field_3bj7x_65{margin-bottom:var(--nice-space-2, 8px)}._buttonRow_3bj7x_71{display:flex;gap:var(--nice-space-2, 8px)}._sliderW200_3bj7x_83{width:200px}._sliderW240_3bj7x_89{width:240px}._selectW160_3bj7x_95{width:160px}._inputW120_3bj7x_101{width:120px}._inputW160_3bj7x_107{width:160px}._inputW200_3bj7x_113{width:200px}._noteText_3bj7x_123{font-size:13px;color:var(--nice-text-secondary, #888)}._noteTextMargin_3bj7x_131{font-size:13px;color:var(--nice-text-secondary, #888);margin-top:var(--nice-space-1, 4px)}._presetDivider_3bj7x_145{display:grid;gap:var(--nice-space-2, 8px);margin-top:var(--nice-space-2, 8px);padding-top:var(--nice-space-2, 8px);border-top:1px solid var(--nice-border-color, #444)}._presetLabel_3bj7x_159{font-size:11px;font-weight:600;color:var(--nice-text-muted, #aaa)}._countInAlert_3bj7x_173{font-size:12px;color:var(--nice-warning, #f57c00)}._levelLabel_3bj7x_181{font-size:12px;color:var(--nice-text-secondary, #555)}._levelMeter_3bj7x_189{position:relative;background:var(--nice-bg-secondary, #f1f1f1);height:12px;border-radius:var(--nice-radius-md, 6px);overflow:hidden;width:80px}._levelBar_3bj7x_205{position:absolute;left:0;top:0;bottom:0;transition:width 80ms linear}._panelInactive_3bj7x_225{opacity:.6}._header_3bj7x_231{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-2, 8px);margin-bottom:var(--nice-space-2, 8px)}._title_3bj7x_245{margin:0;font-size:var(--nice-font-size-md, 14px);font-weight:var(--nice-font-weight-semibold, 600);color:var(--nice-color-primary, #2563eb)}._grid2_3bj7x_257{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--nice-space-2, 8px) var(--nice-space-3, 12px)}._full_3bj7x_267{grid-column:1 / -1}._label_3bj7x_275{display:block;margin-bottom:var(--nice-space-1, 4px);font-size:var(--nice-font-size-sm, .8125rem);font-weight:var(--nice-font-weight-medium, 500);line-height:var(--nice-line-height, 1.5);color:var(--nice-text-primary, #0f172a)}._grow_3bj7x_291{flex:1 1 auto;min-width:0}._pushRight_3bj7x_299{margin-left:auto}._alignStart_3bj7x_305{align-items:flex-start}._toolbar_3bj7x_311{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-1, 4px);margin-bottom:var(--nice-space-2, 8px)}._subPanel_3bj7x_325{margin-bottom:var(--nice-space-2, 8px);padding:var(--nice-space-2, 8px);border:1px solid var(--nice-border-color, #e5e7eb);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary, #f8fafc)}.nice-sample-browser{display:flex;height:100%;min-height:400px;background:linear-gradient(to bottom,var(--nice-bg, #1a1a2e),var(--nice-bg, #0f0f1a));border-radius:var(--nice-radius-lg, 8px);overflow:hidden;color:var(--nice-text-secondary, #e0e0e0);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px}.nice-sample-browser__sidebar{width:220px;min-width:180px;max-width:300px;background:var(--nice-overlay-20, rgba(0, 0, 0, .2));border-right:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));overflow-y:auto}.nice-sample-browser__folders{padding:var(--nice-space-2, 8px) 0}.nice-sample-folder{-webkit-user-select:none;user-select:none}.nice-sample-folder__btn{display:flex;align-items:center;gap:var(--nice-space-2, 8px);width:100%;padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);background:none;border:none;color:var(--nice-text-secondary, #e0e0e0);cursor:pointer;text-align:left;transition:background .15s}.nice-sample-folder__btn:hover{background:var(--nice-accent-tint-15, rgba(139, 92, 246, .15))}.nice-sample-folder__btn--selected{background:var(--nice-accent-tint-20, rgba(139, 92, 246, .25));border-left:3px solid var(--nice-accent, #8b5cf6)}.nice-sample-folder__icon{font-size:14px}.nice-sample-folder__name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-sample-folder__count{font-size:11px;color:var(--nice-text-secondary, #888);background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));padding:var(--nice-space-0-5, 2px) var(--nice-space-1-5, 6px);border-radius:var(--nice-radius-lg, 10px)}.nice-sample-browser__main{flex:1;display:flex;flex-direction:column;overflow:hidden}.nice-sample-browser__header{display:flex;align-items:center;padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);background:var(--nice-overlay-30, rgba(0, 0, 0, .3));border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--nice-text-secondary, #888)}.nice-sample-browser__col{padding:0 var(--nice-space-1, 4px)}.nice-sample-browser__col--play{width:32px}.nice-sample-browser__col--fav{width:28px}.nice-sample-browser__col--name{flex:1;min-width:120px}.nice-sample-browser__col--waveform{width:200px}.nice-sample-browser__col--duration{width:70px;text-align:right}.nice-sample-browser__col--bpm{width:70px;text-align:center}.nice-sample-browser__col--key{width:50px;text-align:center}.nice-sample-browser__col--size{width:70px;text-align:right}.nice-sample-browser__col--tags{width:100px}.nice-sample-browser__list{flex:1;overflow-y:auto}.nice-sample-browser__empty{display:flex;align-items:center;justify-content:center;height:200px;color:var(--nice-text-secondary, #666);font-style:italic}.nice-sample-row{display:flex;align-items:center;padding:var(--nice-space-1-5, 6px) var(--nice-space-3, 12px);border-bottom:1px solid var(--nice-overlay-light-5, rgba(255, 255, 255, .05));cursor:pointer;transition:background .15s}.nice-sample-row:hover{background:var(--nice-accent-tint-10, rgba(139, 92, 246, .1))}.nice-sample-row--selected{background:var(--nice-accent-tint-20, rgba(139, 92, 246, .2))}.nice-sample-row--playing{background:var(--nice-success-tint-15, rgba(34, 197, 94, .15))}.nice-sample-row__play{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3));border:none;border-radius:var(--nice-radius-full, 50%);color:var(--nice-color-white, #fff);cursor:pointer;transition:all .15s;font-size:10px}.nice-sample-row__play:hover{background:var(--nice-accent-tint-50, rgba(139, 92, 246, .5));transform:scale(1.1)}.nice-sample-row--playing .nice-sample-row__play{background:var(--nice-success-tint-50, rgba(34, 197, 94, .5));animation:pulse-play 1s infinite}@keyframes pulse-play{0%,to{box-shadow:0 0 0 0 var(--nice-success-tint-40, rgba(34, 197, 94, .4))}50%{box-shadow:0 0 0 6px transparent}}.nice-sample-row__fav{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:none;border:none;color:var(--nice-text-secondary, #666);cursor:pointer;font-size:14px;transition:color .15s,transform .15s}.nice-sample-row__fav:hover{color:var(--nice-warning-light, #fbbf24);transform:scale(1.2)}.nice-sample-row__fav--active{color:var(--nice-warning-light, #fbbf24)}.nice-sample-row__name{flex:1;min-width:120px;padding:0 var(--nice-space-2, 8px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}.nice-sample-row__waveform{width:200px;padding:0 var(--nice-space-2, 8px)}.nice-sample-waveform{display:block;cursor:pointer;border-radius:var(--nice-radius-sm, 4px);background:var(--nice-overlay-20, rgba(0, 0, 0, .2))}.nice-sample-row__duration{width:70px;text-align:right;color:var(--nice-text-muted, #aaa);font-variant-numeric:tabular-nums}.nice-sample-row__bpm{width:70px;text-align:center;color:var(--nice-info, #22d3ee);font-weight:500;font-variant-numeric:tabular-nums}.nice-sample-row__key{width:50px;text-align:center;color:var(--nice-color-accent-pink, #f472b6);font-weight:500}.nice-sample-row__size{width:70px;text-align:right;color:var(--nice-text-secondary, #888);font-size:11px}.nice-sample-row__tags{width:100px;display:flex;gap:var(--nice-space-1, 4px);flex-wrap:wrap}.nice-sample-row__tag{font-size:10px;padding:var(--nice-space-0-5, 2px) var(--nice-space-1-5, 6px);background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3));color:var(--nice-accent, #c4b5fd);border-radius:var(--nice-radius-lg, 10px);white-space:nowrap}.nice-sample-browser__preview{width:320px;min-width:280px;background:var(--nice-overlay-20, rgba(0, 0, 0, .2));border-left:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));padding:var(--nice-space-4, 16px);display:flex;flex-direction:column;gap:var(--nice-space-4, 16px)}.nice-sample-browser__preview-title{margin:0;font-size:14px;font-weight:600;color:var(--nice-text-primary, #fff);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-sample-browser__preview canvas{border-radius:var(--nice-radius-lg, 8px);background:var(--nice-overlay-30, rgba(0, 0, 0, .3))}.nice-sample-browser__preview-info{display:flex;flex-direction:column;gap:var(--nice-space-2, 8px);font-size:12px;color:var(--nice-text-muted, #aaa)}.nice-sample-browser__preview-info>div{display:flex;justify-content:space-between}.nice-sample-browser__list::-webkit-scrollbar,.nice-sample-browser__sidebar::-webkit-scrollbar{width:8px}.nice-sample-browser__list::-webkit-scrollbar-track,.nice-sample-browser__sidebar::-webkit-scrollbar-track{background:transparent}.nice-sample-browser__list::-webkit-scrollbar-thumb,.nice-sample-browser__sidebar::-webkit-scrollbar-thumb{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2));border-radius:var(--nice-radius-sm, 4px)}.nice-sample-browser__list::-webkit-scrollbar-thumb:hover,.nice-sample-browser__sidebar::-webkit-scrollbar-thumb:hover{background:var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}@media(max-width:900px){.nice-sample-browser{flex-direction:column}.nice-sample-browser__sidebar{width:100%;max-width:none;max-height:150px;border-right:none;border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1))}.nice-sample-browser__preview{width:100%;border-left:none;border-top:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));flex-direction:row;flex-wrap:wrap;padding:var(--nice-space-3, 12px)}.nice-sample-browser__preview-title{width:100%}.nice-sample-browser__col--waveform,.nice-sample-row__waveform,.nice-sample-browser__col--tags,.nice-sample-row__tags{display:none}}@media(max-width:600px){.nice-sample-browser__col--bpm,.nice-sample-browser__col--key,.nice-sample-row__bpm,.nice-sample-row__key,.nice-sample-browser__col--size,.nice-sample-row__size{display:none}}.nice-karaoke-summary{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;background:var(--nice-overlay-80, rgba(0, 0, 0, .8));padding:var(--nice-space-6, 24px);z-index:1000;color:var(--nice-color-white, #fff)}.nice-karaoke-summary__card{background:linear-gradient(180deg,var(--nice-bg-tertiary) 0%,var(--nice-bg-secondary) 100%);border-radius:var(--nice-radius-2xl, 16px);padding:var(--nice-space-7, 28px);width:min(700px,95vw);max-height:90vh;overflow-y:auto;box-shadow:0 12px 40px var(--nice-overlay-50, rgba(0, 0, 0, .5));display:flex;flex-direction:column;gap:var(--nice-space-4-5, 18px)}.nice-karaoke-summary__title{margin:0;font-size:1.4rem;font-weight:700;text-align:center;color:var(--nice-text, #e2e8f0)}.nice-karaoke-summary__bars{display:flex;flex-direction:column;gap:var(--nice-space-2-5, 10px)}.nice-karaoke-summary__bar{display:flex;align-items:center;gap:var(--nice-space-2-5, 10px);width:100%}.nice-karaoke-summary__bar-rank{width:32px;flex-shrink:0;text-align:center;font-size:18px}.nice-karaoke-summary__bar-name{width:100px;flex-shrink:0;font-weight:600;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-karaoke-summary__bar-track{position:relative;flex:1;height:28px;border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary);overflow:hidden}.nice-karaoke-summary__bar-fill-bonus,.nice-karaoke-summary__bar-fill-classic{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:var(--nice-radius-md, 6px)}.nice-karaoke-summary__bar-text{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:flex-end;padding-right:var(--nice-space-2, 8px);font-size:13px;font-weight:700;color:var(--nice-text-primary, #fff);text-shadow:0 1px 3px var(--nice-overlay-70, rgba(0, 0, 0, .7))}.nice-karaoke-summary__bar-text-bonus{margin-left:var(--nice-space-1, 4px);font-size:11px}.nice-karaoke-summary__bar-total{width:70px;flex-shrink:0;text-align:right;font-weight:700;font-size:15px;color:var(--nice-warning-light, #fbbf24)}.nice-karaoke-summary__ranks{display:flex;gap:var(--nice-space-4, 16px);flex-wrap:wrap}.nice-karaoke-summary__rank{flex:1;min-width:200px}.nice-karaoke-summary__rank-title{margin:0 0 var(--nice-space-1-5, 6px);font-size:14px;color:var(--nice-text-muted, #94a3b8)}.nice-karaoke-summary__rank-table{width:100%;border-collapse:collapse;font-size:13px}.nice-karaoke-summary__rank-row{border-bottom:1px solid var(--nice-border, #1e293b)}.nice-karaoke-summary__rank-row--hl{background:var(--nice-warning-tint-10, rgba(251, 191, 36, .1))}.nice-karaoke-summary__rank-pos{width:24px;padding:var(--nice-space-0-75, 3px) var(--nice-space-1-5, 6px);color:var(--nice-text-dim, #64748b)}.nice-karaoke-summary__rank-pos--top{color:var(--nice-warning-light, #fbbf24);font-weight:700}.nice-karaoke-summary__rank-name{padding:var(--nice-space-0-75, 3px) var(--nice-space-1-5, 6px);color:var(--nice-text, #cbd5e1)}.nice-karaoke-summary__rank-row--hl .nice-karaoke-summary__rank-name{font-weight:700}.nice-karaoke-summary__rank-score{padding:var(--nice-space-0-75, 3px) var(--nice-space-1-5, 6px);text-align:right;color:var(--nice-text-muted, #94a3b8)}.nice-karaoke-summary__rank-row--hl .nice-karaoke-summary__rank-score{color:var(--nice-warning-light, #fbbf24)}.nice-karaoke-summary__empty{text-align:center;color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));font-size:1rem;padding:2rem}.nice-karaoke-summary__actions{display:flex;gap:var(--nice-space-3, 12px);justify-content:flex-end;margin-top:var(--nice-space-1, 4px)}.nice-karaoke-summary__btn{min-width:120px;padding:.7rem 1.5rem;font-size:.95rem;font-weight:700;border:none;border-radius:var(--nice-radius-lg, 8px);cursor:pointer;transition:all .2s ease}.nice-karaoke-summary__btn--report{background:var(--nice-accent, #6366f1);color:var(--nice-text-on-primary, #fff)}.nice-karaoke-summary__btn--restart{background:var(--nice-success, #22c55e);color:var(--nice-text-on-primary, #fff)}.nice-karaoke-summary__btn--continue{background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));color:var(--nice-color-white, #fff);border:1px solid var(--nice-overlay-light-20, rgba(255, 255, 255, .2))}.nice-karaoke-summary__btn:hover{filter:brightness(1.08);transform:translateY(-1px)}@media(max-width:600px){.nice-karaoke-summary__card{padding:var(--nice-space-4-5, 18px)}.nice-karaoke-summary__bar-name{width:72px}.nice-karaoke-summary__actions{flex-direction:column}.nice-karaoke-summary__btn{width:100%}}.nice-ksb{display:flex;gap:var(--nice-space-4, 16px);width:100%;color:var(--nice-text, #e2e8f0);font-size:14px}.nice-ksb__sidebar{flex:0 0 200px;display:flex;flex-direction:column;gap:var(--nice-space-1, 4px);max-height:600px;overflow-y:auto}.nice-ksb__facet{margin-top:var(--nice-space-2-5, 10px)}.nice-ksb__facet-title{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--nice-text-muted, #94a3b8);margin:var(--nice-space-1, 4px) var(--nice-space-1-5, 6px)}.nice-ksb__node{display:block;width:100%;text-align:left;padding:var(--nice-space-1-75, 7px) var(--nice-space-2-5, 10px);border:none;border-radius:var(--nice-radius-md, 6px);background:transparent;color:var(--nice-text, #cbd5e1);cursor:pointer;font-size:13px}.nice-ksb__node:hover{background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05))}.nice-ksb__node--active{background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2));color:var(--nice-color-accent, #a5b4fc);font-weight:600}.nice-ksb__main{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--nice-space-2-5, 10px)}.nice-ksb__toolbar{display:flex;gap:var(--nice-space-2-5, 10px);align-items:center;flex-wrap:wrap}.nice-ksb__search{flex:1;min-width:180px;padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);border-radius:var(--nice-radius-md, 6px);border:1px solid var(--nice-border, #334155);background:var(--nice-bg-secondary);color:var(--nice-text, #e2e8f0);font-size:14px}.nice-ksb__sort{display:flex;gap:var(--nice-space-1, 4px);flex-wrap:wrap}.nice-ksb__sort-btn{padding:var(--nice-space-1-5, 6px) var(--nice-space-2-5, 10px);border:1px solid var(--nice-border, #334155);border-radius:var(--nice-radius-md, 6px);background:transparent;color:var(--nice-text-muted, #94a3b8);cursor:pointer;font-size:12px;text-transform:capitalize}.nice-ksb__sort-btn--active{background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2));color:var(--nice-color-accent, #a5b4fc);border-color:var(--nice-accent, #6366f1)}.nice-ksb__navhint{display:inline-flex;align-items:center;gap:var(--nice-space-1, 4px);margin-left:auto;padding:var(--nice-space-1, 4px) var(--nice-space-2, 8px);border-radius:var(--nice-radius-md, 6px);color:var(--nice-text-muted, #94a3b8);font-size:12px;white-space:nowrap}.nice-ksb__navhint--pad{color:var(--nice-accent-light, #a5b4fc);background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2))}.nice-ksb__navhint-keys{font-variant-numeric:tabular-nums}.nice-ksb__disabled{padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);border-radius:var(--nice-radius-md, 6px);background:var(--nice-warning-tint-10, rgba(251, 191, 36, .1));color:var(--nice-warning-light, #fbbf24);font-size:13px}.nice-ksb__list{display:flex;flex-direction:column;gap:var(--nice-space-1, 4px);max-height:560px;overflow-y:auto}.nice-ksb__empty{text-align:center;padding:var(--nice-space-8, 32px);color:var(--nice-text-muted, #94a3b8)}.nice-ksb-row{display:flex;align-items:center;gap:var(--nice-space-2-5, 10px);padding:var(--nice-space-1-5, 6px) var(--nice-space-2, 8px);border-radius:var(--nice-radius-md, 8px);cursor:pointer}.nice-ksb-row:hover{background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05))}.nice-ksb-row--selected{background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2))}.nice-ksb-row--active{box-shadow:inset 0 0 0 2px var(--nice-accent, #6366f1);background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05))}.nice-ksb-row:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--nice-accent, #6366f1),var(--nice-focus-ring, 0 0 0 2px var(--nice-accent, #6366f1))}.nice-ksb-row__check{flex:0 0 auto;width:16px;height:16px}.nice-ksb-row__cover{flex:0 0 auto;width:44px;height:44px;border-radius:var(--nice-radius-md, 6px);object-fit:cover;background:var(--nice-bg-tertiary)}.nice-ksb-row__main{flex:1;min-width:0}.nice-ksb-row__title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nice-ksb-row__artist{font-size:12px;color:var(--nice-text-muted, #94a3b8);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nice-ksb-row__meta{display:flex;gap:var(--nice-space-1, 4px);flex-wrap:wrap;justify-content:flex-end;max-width:50%}.nice-ksb-badge{font-size:11px;padding:var(--nice-space-0-5, 2px) var(--nice-space-1-75, 7px);border-radius:var(--nice-radius-full, 999px);background:var(--nice-bg-tertiary);color:var(--nice-text-muted, #94a3b8);white-space:nowrap}.nice-ksb-badge--src{background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2));color:var(--nice-color-accent, #a5b4fc)}.nice-ksb-badge--score{background:var(--nice-warning-bg, rgba(251, 191, 36, .12));color:var(--nice-warning-text, #fbbf24)}.nice-ksb-row__play{flex:0 0 auto;padding:var(--nice-space-1-5, 6px) var(--nice-space-3-5, 14px);border:none;border-radius:var(--nice-radius-md, 6px);background:var(--nice-accent, #6366f1);color:var(--nice-text-on-primary, #fff);cursor:pointer;font-weight:600;font-size:13px}.nice-ksb-row__play:disabled{opacity:.5;cursor:not-allowed}.nice-ksb__footer{display:flex;align-items:center;justify-content:space-between;gap:var(--nice-space-3, 12px);padding-top:var(--nice-space-2, 8px);border-top:1px solid var(--nice-border, #1e293b);color:var(--nice-text-muted, #94a3b8);font-size:13px}.nice-ksb__confirm{padding:var(--nice-space-2, 8px) 18px;border:none;border-radius:var(--nice-radius-md, 6px);background:var(--nice-success, #22c55e);color:var(--nice-text-on-primary, #fff);cursor:pointer;font-weight:700}.nice-ksb__confirm:disabled{opacity:.5;cursor:not-allowed}@media(max-width:640px){.nice-ksb{flex-direction:column}.nice-ksb__sidebar{flex-basis:auto;flex-direction:row;flex-wrap:wrap;max-height:none}.nice-ksb-row__meta{display:none}}._editor_qz5p3_5{padding:var(--nice-space-3, 12px);border:1px solid var(--nice-border-color, #e5e7eb);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #ffffff);color:var(--nice-text-primary, #0f172a)}._heading_qz5p3_19{display:flex;align-items:center;gap:var(--nice-space-1, 4px);margin:0 0 var(--nice-space-1, 4px);font-size:var(--nice-font-size-md, 14px);font-weight:var(--nice-font-weight-semibold, 600)}._hint_qz5p3_35{margin:0 0 var(--nice-space-3, 12px);font-size:var(--nice-font-size-sm, .8125rem);color:var(--nice-text-secondary, #475569)}._group_qz5p3_49{margin-bottom:var(--nice-space-2, 8px);padding:var(--nice-space-2, 8px);border-left:3px solid var(--nice-color-primary, #2563eb);border-radius:var(--nice-radius-sm, 4px)}._groupOr_qz5p3_61{border-left-color:var(--nice-color-warning, #f59e0b)}._groupShaded_qz5p3_67{background:var(--nice-bg-secondary, #f8fafc)}._groupHeader_qz5p3_73{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-2, 8px);margin-bottom:var(--nice-space-2, 8px)}._groupHint_qz5p3_87{font-size:var(--nice-font-size-sm, .8125rem);color:var(--nice-text-secondary, #475569)}._groupActions_qz5p3_95{display:flex;gap:var(--nice-space-1, 4px);margin-left:auto}._rule_qz5p3_107{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-2, 8px);margin-bottom:var(--nice-space-2, 8px)}._value_qz5p3_121{width:180px}._value2_qz5p3_127{width:140px}._dash_qz5p3_133{color:var(--nice-text-secondary, #475569)}._limit_qz5p3_141{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--nice-space-2, 8px);margin-top:var(--nice-space-3, 12px);padding-top:var(--nice-space-2, 8px);border-top:1px solid var(--nice-border-color, #e5e7eb)}._limitInput_qz5p3_159{width:140px}.nice-fx-rack{display:flex;flex-direction:column;gap:1rem;padding:1rem;background:linear-gradient(180deg,var(--nice-bg, #1a1a2e),var(--nice-bg, #16213e));border-radius:var(--nice-radius-xl, 12px);border:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));font-family:system-ui,-apple-system,sans-serif}.nice-fx-rack--compact{padding:.75rem;gap:.5rem}.nice-fx-rack__header{display:flex;justify-content:space-between;align-items:center;padding-bottom:.5rem;border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1))}.nice-fx-rack__title{margin:0;font-size:1rem;font-weight:600;color:var(--nice-text-primary, #fff)}.nice-fx-rack__count{font-size:.75rem;color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));padding:.25rem .5rem;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-sm, 4px)}.nice-fx-rack__chain{display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-start;min-height:120px}.nice-fx-rack__slot{display:flex;align-items:center;gap:.5rem}.nice-fx-rack__connector{display:inline-flex;align-items:center;color:var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}.nice-fx-rack__empty{display:flex;align-items:center;justify-content:center;width:100%;min-height:100px;color:var(--nice-overlay-light-30, rgba(255, 255, 255, .3));font-size:.875rem;border:2px dashed var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-lg, 8px)}.nice-fx-card{display:flex;flex-direction:column;min-width:180px;background:var(--nice-overlay-30, rgba(0, 0, 0, .3));border-radius:var(--nice-radius-lg, 8px);border:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));overflow:hidden;cursor:grab;transition:all .2s ease}.nice-fx-card:hover{border-color:var(--nice-accent-tint-50, rgba(139, 92, 246, .5));box-shadow:0 4px 12px var(--nice-overlay-30, rgba(0, 0, 0, .3))}.nice-fx-card:active{cursor:grabbing}.nice-fx-card--disabled{opacity:.5}.nice-fx-card--drop-target{border-color:var(--nice-success, #22c55e);box-shadow:0 0 0 2px var(--nice-success-tint-30, rgba(34, 197, 94, .3))}.nice-fx-card--compact{min-width:140px}.nice-fx-card__header{display:flex;align-items:center;gap:.5rem;padding:.5rem;background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05));border-bottom:1px solid var(--nice-overlay-light-5, rgba(255, 255, 255, .05))}.nice-fx-card__icon{font-size:1rem}.nice-fx-card__title{flex:1;font-size:.75rem;font-weight:600;color:var(--nice-text-primary, #fff);text-transform:uppercase;letter-spacing:.05em}.nice-fx-card__toggle{width:20px;height:20px;padding:0;border:none;display:inline-flex;align-items:center;justify-content:center;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-full, 50%);color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));font-size:.75rem;cursor:pointer;transition:all .2s ease}.nice-fx-card__toggle-dot{width:8px;height:8px;border-radius:var(--nice-radius-circle, 50%);border:1.5px solid currentColor;background:transparent}.nice-fx-card__toggle--active .nice-fx-card__toggle-dot{background:currentColor}.nice-fx-card__toggle:hover{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2))}.nice-fx-card__toggle--active{background:var(--nice-success, #22c55e);color:var(--nice-text-on-primary, #fff)}.nice-fx-card__presets{position:relative}.nice-fx-card__preset-btn{width:24px;height:20px;padding:0;border:none;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-sm, 4px);color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));font-size:.625rem;cursor:pointer}.nice-fx-card__preset-btn:hover{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2))}.nice-fx-card__preset-menu{position:absolute;top:100%;right:0;z-index:100;min-width:120px;margin-top:var(--nice-space-1, 4px);padding:.25rem;background:var(--nice-bg, #1a1a2e);border:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-md, 6px);box-shadow:0 4px 12px var(--nice-overlay-50, rgba(0, 0, 0, .5))}.nice-fx-card__preset-item{display:block;width:100%;padding:.375rem .5rem;border:none;background:none;color:var(--nice-overlay-light-80, rgba(255, 255, 255, .8));font-size:.75rem;text-align:left;text-transform:capitalize;cursor:pointer;border-radius:var(--nice-radius-sm, 4px)}.nice-fx-card__preset-item:hover{background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3))}.nice-fx-card__remove{width:20px;height:20px;padding:0;border:none;background:none;color:var(--nice-overlay-light-30, rgba(255, 255, 255, .3));font-size:1rem;cursor:pointer;transition:all .2s ease}.nice-fx-card__remove:hover{color:var(--nice-danger, #ef4444)}.nice-fx-card__body{padding:.75rem}.nice-fx-card__controls{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center}.nice-fx-card__generic{display:flex;justify-content:center}.nice-fx-knob{display:flex;flex-direction:column;align-items:center;gap:.25rem;min-width:44px}.nice-fx-knob--disabled{opacity:.4;pointer-events:none}.nice-fx-knob__dial{position:relative;width:36px;height:36px;background:linear-gradient(145deg,var(--nice-bg-secondary, #2a2a4a),var(--nice-bg, #1a1a2e));border-radius:var(--nice-radius-full, 50%);border:2px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));cursor:pointer;-webkit-user-select:none;user-select:none;box-shadow:0 2px 8px var(--nice-overlay-30, rgba(0, 0, 0, .3));transition:border-color .2s ease}.nice-fx-knob__dial:hover{border-color:var(--nice-accent-tint-50, rgba(139, 92, 246, .5))}.nice-fx-knob__dial--active{border-color:var(--nice-accent, #8b5cf6)}.nice-fx-knob__indicator{position:absolute;top:4px;left:50%;width:2px;height:8px;background:var(--nice-accent, #8b5cf6);border-radius:var(--nice-radius-xs, 1px);transform:translate(-50%)}.nice-fx-knob__label{font-size:.625rem;color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));text-transform:uppercase;letter-spacing:.05em;text-align:center}.nice-fx-knob__value{font-size:.625rem;color:var(--nice-overlay-light-80, rgba(255, 255, 255, .8));font-weight:500;text-align:center}.nice-fx-rack__add{position:relative}.nice-fx-rack__add-btn{display:flex;align-items:center;justify-content:center;width:100%;padding:.75rem;border:2px dashed var(--nice-overlay-light-20, rgba(255, 255, 255, .2));border-radius:var(--nice-radius-lg, 8px);background:none;color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.nice-fx-rack__add-btn:hover{border-color:var(--nice-accent-tint-50, rgba(139, 92, 246, .5));color:var(--nice-overlay-light-80, rgba(255, 255, 255, .8));background:var(--nice-accent-tint-10, rgba(139, 92, 246, .1))}.nice-fx-rack__add-menu{position:absolute;bottom:100%;left:0;right:0;z-index:100;display:grid;grid-template-columns:repeat(2,1fr);gap:.25rem;margin-bottom:var(--nice-space-2, 8px);padding:.5rem;background:var(--nice-bg, #1a1a2e);border:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-lg, 8px);box-shadow:0 -4px 12px var(--nice-overlay-30, rgba(0, 0, 0, .3))}.nice-fx-rack__add-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;border:none;background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05));border-radius:var(--nice-radius-md, 6px);color:var(--nice-overlay-light-80, rgba(255, 255, 255, .8));font-size:.75rem;cursor:pointer;transition:all .2s ease}.nice-fx-rack__add-item:hover{background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3))}.nice-fx-rack__add-icon{font-size:1rem}.nice-fx-rack__add-label{text-align:left}@media(max-width:600px){.nice-fx-rack{padding:.75rem}.nice-fx-card{min-width:100%}.nice-fx-rack__add-menu{grid-template-columns:1fr}}.nice-dmx-timeline{display:flex;flex-direction:column;height:100%;min-height:300px;background:linear-gradient(to bottom,var(--nice-bg, #1a1a2e),var(--nice-bg, #0f0f1a));border-radius:var(--nice-radius-lg, 8px);overflow:hidden;color:var(--nice-text-secondary, #e0e0e0);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px}.nice-dmx-timeline__toolbar{display:flex;align-items:center;gap:var(--nice-space-4, 16px);padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);background:var(--nice-overlay-30, rgba(0, 0, 0, .3));border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1))}.nice-dmx-timeline__transport{display:flex;gap:var(--nice-space-1, 4px)}.nice-dmx-timeline__transport button{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3));border:none;border-radius:var(--nice-radius-sm, 4px);color:var(--nice-color-white, #fff);cursor:pointer;font-size:14px;transition:all .15s}.nice-dmx-timeline__transport button:hover{background:var(--nice-accent-tint-50, rgba(139, 92, 246, .5))}.nice-dmx-timeline__transport button:active{transform:scale(.95)}.nice-dmx-timeline__time{font-family:Consolas,Monaco,monospace;font-size:18px;font-weight:600;color:var(--nice-info, #22d3ee);min-width:100px}.nice-dmx-timeline__tools{display:flex;align-items:center;gap:var(--nice-space-1, 4px)}.nice-dmx-timeline__tools button{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border:none;border-radius:var(--nice-radius-sm, 4px);color:var(--nice-text-muted, #aaa);cursor:pointer;transition:all .15s}.nice-dmx-timeline__tools button:hover{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2));color:var(--nice-color-white, #fff)}.nice-dmx-timeline__tools button.nice-dmx-timeline__tool--active{background:var(--nice-accent-tint-40, rgba(139, 92, 246, .4));color:var(--nice-color-white, #fff)}.nice-dmx-timeline__zoom{font-size:11px;color:var(--nice-text-secondary, #888);min-width:40px;text-align:center}.nice-dmx-timeline__bpm{display:flex;align-items:center;gap:var(--nice-space-1-5, 6px);font-size:12px;color:var(--nice-text-secondary, #888)}.nice-dmx-timeline__bpm span{color:var(--nice-color-accent-pink, #f472b6);font-weight:600}.nice-dmx-timeline__blackout{margin-left:auto;padding:var(--nice-space-1-5, 6px) var(--nice-space-3, 12px);background:var(--nice-danger-tint-30, rgba(239, 68, 68, .3));border:none;border-radius:var(--nice-radius-sm, 4px);color:var(--nice-color-white, #fff);cursor:pointer;font-size:14px;transition:all .15s}.nice-dmx-timeline__blackout:hover{background:color-mix(in srgb,var(--nice-color-danger, #ef4444) 50%,transparent)}.nice-dmx-timeline__content{flex:1;display:flex;overflow:hidden}.nice-dmx-timeline__headers{width:180px;min-width:150px;background:var(--nice-overlay-20, rgba(0, 0, 0, .2));border-right:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));overflow-y:auto;padding-top:var(--nice-space-8, 32px)}.nice-dmx-timeline__header{display:flex;align-items:center;gap:var(--nice-space-2, 8px);height:48px;padding:0 var(--nice-space-3, 12px);border-bottom:1px solid var(--nice-overlay-light-5, rgba(255, 255, 255, .05));cursor:pointer;transition:background .15s}.nice-dmx-timeline__header:hover{background:var(--nice-accent-tint-10, rgba(139, 92, 246, .1))}.nice-dmx-timeline__header--selected{background:var(--nice-accent-tint-20, rgba(139, 92, 246, .2))}.nice-dmx-timeline__track-color{width:8px;height:8px;border-radius:var(--nice-radius-full, 50%)}.nice-dmx-timeline__track-name{flex:1;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-dmx-timeline__track-controls{display:flex;gap:var(--nice-space-1, 4px)}.nice-dmx-timeline__track-controls button{width:20px;height:20px;display:flex;align-items:center;justify-content:center;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border:none;border-radius:var(--nice-radius-sm, 3px);color:var(--nice-text-secondary, #888);cursor:pointer;font-size:10px;transition:all .15s}.nice-dmx-timeline__track-controls button:hover{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2));color:var(--nice-color-white, #fff)}.nice-dmx-timeline__track-controls button.nice-dmx-timeline__track-toggle--active{background:var(--nice-danger-tint-40, rgba(239, 68, 68, .4));color:var(--nice-color-white, #fff)}.nice-dmx-timeline__add-track{width:100%;padding:var(--nice-space-3, 12px);background:none;border:none;border-top:1px dashed var(--nice-overlay-light-10, rgba(255, 255, 255, .1));color:var(--nice-text-secondary, #666);cursor:pointer;text-align:center;transition:all .15s}.nice-dmx-timeline__add-track:hover{background:var(--nice-accent-tint-10, rgba(139, 92, 246, .1));color:var(--nice-accent, #8b5cf6)}.nice-dmx-timeline__tracks{flex:1;overflow:auto;position:relative}.nice-dmx-timeline__ruler{position:sticky;top:0;height:32px;background:var(--nice-overlay-40, rgba(0, 0, 0, .4));border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));z-index:10}.nice-dmx-timeline__beat{position:absolute;top:0;bottom:0;width:1px;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1))}.nice-dmx-timeline__beat--measure{background:var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}.nice-dmx-timeline__beat-label{position:absolute;top:4px;left:4px;font-size:10px;color:var(--nice-text-secondary, #888)}.nice-dmx-timeline__track{position:relative;height:48px;border-bottom:1px solid var(--nice-overlay-light-5, rgba(255, 255, 255, .05));background:linear-gradient(90deg,var(--nice-overlay-light-2, rgba(255, 255, 255, .02)) 0%,transparent 1px,transparent 100%);background-size:100px 100%}.nice-dmx-timeline__track--muted{opacity:.4}.nice-dmx-timeline__cue{position:absolute;top:4px;height:calc(100% - 8px);border-radius:var(--nice-radius-sm, 4px);cursor:pointer;overflow:hidden;transition:box-shadow .15s}.nice-dmx-timeline__cue:hover{box-shadow:0 0 0 2px var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}.nice-dmx-timeline__cue--selected{box-shadow:0 0 0 2px var(--nice-bg, #fff)}.nice-dmx-timeline__cue-name{position:absolute;top:4px;left:6px;right:6px;font-size:11px;font-weight:500;color:var(--nice-text-primary, #fff);text-shadow:0 1px 2px var(--nice-overlay-50, rgba(0, 0, 0, .5));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-dmx-timeline__cue-fade{position:absolute;top:0;bottom:0;background:linear-gradient(to right,var(--nice-overlay-80, rgba(0, 0, 0, .8)),transparent)}.nice-dmx-timeline__cue-fade--in{left:0}.nice-dmx-timeline__cue-fade--out{right:0;transform:scaleX(-1)}.nice-dmx-timeline__playhead{position:absolute;top:0;bottom:0;width:2px;background:var(--nice-danger, #ef4444);z-index:20;pointer-events:none}.nice-dmx-timeline__playhead:before{content:"";position:absolute;top:0;left:50%;transform:translate(-50%);width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:8px solid var(--nice-danger, #ef4444)}.nice-dmx-timeline__tracks::-webkit-scrollbar,.nice-dmx-timeline__headers::-webkit-scrollbar{width:8px;height:8px}.nice-dmx-timeline__tracks::-webkit-scrollbar-track,.nice-dmx-timeline__headers::-webkit-scrollbar-track{background:transparent}.nice-dmx-timeline__tracks::-webkit-scrollbar-thumb,.nice-dmx-timeline__headers::-webkit-scrollbar-thumb{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2));border-radius:var(--nice-radius-sm, 4px)}.nice-dmx-timeline__tracks::-webkit-scrollbar-thumb:hover,.nice-dmx-timeline__headers::-webkit-scrollbar-thumb:hover{background:var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}@media(max-width:768px){.nice-dmx-timeline__toolbar{flex-wrap:wrap;gap:var(--nice-space-2, 8px)}.nice-dmx-timeline__headers{width:120px;min-width:100px}.nice-dmx-timeline__track-controls,.nice-dmx-timeline__bpm{display:none}}.nice-radio-player{display:flex;flex-direction:column;gap:var(--nice-space-3, 12px);min-width:0;padding:var(--nice-space-4, 16px);background:var(--nice-bg-elevated, var(--nice-bg-primary, #fff));border:1px solid var(--nice-border-color, #e2e8f0);border-radius:var(--nice-radius-lg, 8px);color:var(--nice-text-primary, inherit);font-size:var(--nice-font-size-sm, .8125rem)}.nice-radio-player__now-playing{display:flex;align-items:center;gap:var(--nice-space-3, 12px);min-height:64px;min-width:0}.nice-radio-player__cover{flex-shrink:0;width:64px;height:64px;border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary, #f1f5f9);object-fit:cover}.nice-radio-player__info{display:flex;flex-direction:column;gap:var(--nice-space-0-5, 2px);min-width:0}.nice-radio-player__station-name{overflow:hidden;font-size:var(--nice-font-size-lg, 1rem);font-weight:var(--nice-font-weight-semibold, 600);text-overflow:ellipsis;white-space:nowrap}.nice-radio-player__track{overflow:hidden;color:var(--nice-text-secondary, #64748b);text-overflow:ellipsis;white-space:nowrap}.nice-radio-player__genre,.nice-radio-player__buffering{color:var(--nice-text-muted, #94a3b8);font-size:var(--nice-font-size-xs, .75rem)}.nice-radio-player__buffering{font-style:italic}.nice-radio-player__placeholder{color:var(--nice-text-muted, #94a3b8)}.nice-radio-player__controls{display:flex;align-items:center;gap:var(--nice-space-3, 12px)}.nice-radio-player__play-btn{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:0;border-radius:var(--nice-radius-circle, 50%);background:var(--nice-color-primary, #3b82f6);color:var(--nice-text-on-primary, #fff);cursor:pointer}.nice-radio-player__play-btn:hover:not(:disabled){filter:brightness(1.08)}.nice-radio-player__play-btn:disabled{opacity:.5;cursor:not-allowed}.nice-radio-player__volume{display:flex;flex:1 1 auto;align-items:center;gap:var(--nice-space-2, 8px);min-width:0}.nice-radio-player__volume-icon{display:inline-flex;color:var(--nice-text-secondary, #64748b)}.nice-radio-player__volume-slider{flex:1 1 auto;min-width:60px;max-width:200px;accent-color:var(--nice-color-primary, #3b82f6)}.nice-radio-player__eq-btn,.nice-radio-player__eq-preset{padding:var(--nice-space-1, 4px) var(--nice-space-2-5, 10px);border:1px solid var(--nice-border-color, #e2e8f0);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #fff);color:var(--nice-text-secondary, #64748b);font:inherit;font-size:var(--nice-font-size-xs, .75rem);font-weight:var(--nice-font-weight-semibold, 600);cursor:pointer}.nice-radio-player__eq-btn:hover,.nice-radio-player__eq-preset:hover{border-color:var(--nice-border-strong, #cbd5e1);color:var(--nice-text-primary, inherit)}.nice-radio-player__eq-btn--active,.nice-radio-player__eq-preset--active{border-color:var(--nice-color-primary, #3b82f6);background:color-mix(in srgb,var(--nice-color-primary, #3b82f6) 12%,transparent);color:var(--nice-color-primary, #3b82f6)}.nice-radio-player__play-btn:focus-visible,.nice-radio-player__eq-btn:focus-visible,.nice-radio-player__eq-preset:focus-visible{outline:none;box-shadow:var(--nice-focus-ring, 0 0 0 2px var(--nice-color-primary, #3b82f6))}.nice-radio-player__error{padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);border-radius:var(--nice-radius-md, 6px);background:color-mix(in srgb,var(--nice-color-danger, #ef4444) 12%,transparent);color:var(--nice-color-danger, #dc2626)}.nice-radio-player__equalizer{padding:var(--nice-space-2, 8px);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary, #f8fafc)}.nice-radio-player__eq-presets{display:flex;flex-wrap:wrap;gap:var(--nice-space-1, 4px)}.nice-station-browser{display:flex;flex-direction:column;gap:var(--nice-space-2, 8px);min-width:0}.nice-station-browser__toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-2, 8px)}.nice-station-browser__search,.nice-station-browser__genre-filter{box-sizing:border-box;padding:var(--nice-space-1-5, 6px) var(--nice-space-2-5, 10px);border:1px solid var(--nice-border-color, #e2e8f0);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #fff);color:var(--nice-text-primary, inherit);font:inherit}.nice-station-browser__search{flex:1 1 180px;min-width:0}.nice-station-browser__fav-toggle,.nice-station-browser__fav{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;padding:var(--nice-space-1-5, 6px);border:1px solid transparent;border-radius:var(--nice-radius-md, 6px);background:transparent;cursor:pointer}.nice-station-browser__fav-toggle{border-color:var(--nice-border-color, #e2e8f0)}.nice-station-browser__fav-toggle--active{border-color:var(--nice-color-warning, #f59e0b);background:color-mix(in srgb,var(--nice-color-warning, #f59e0b) 14%,transparent)}.nice-station-browser__fav:hover{background:var(--nice-bg-tertiary, #e2e8f0)}.nice-station-browser__list{display:flex;flex-direction:column;gap:var(--nice-space-px, 1px);max-height:320px;overflow-y:auto}.nice-station-browser__item{display:flex;align-items:center;gap:var(--nice-space-2-5, 10px);padding:var(--nice-space-1-5, 6px) var(--nice-space-2, 8px);border-radius:var(--nice-radius-md, 6px);cursor:pointer}.nice-station-browser__item:hover{background:var(--nice-bg-secondary, #f8fafc)}.nice-station-browser__item--active,.nice-station-browser__item--active:hover{background:color-mix(in srgb,var(--nice-color-primary, #3b82f6) 12%,transparent)}.nice-station-browser__item:focus-visible,.nice-station-browser__fav-toggle:focus-visible,.nice-station-browser__fav:focus-visible{outline:none;box-shadow:var(--nice-focus-ring, 0 0 0 2px var(--nice-color-primary, #3b82f6))}.nice-station-browser__logo{flex-shrink:0;width:36px;height:36px;border-radius:var(--nice-radius-sm, 4px);object-fit:cover}.nice-station-browser__info{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:baseline;gap:var(--nice-space-0-5, 2px) var(--nice-space-2, 8px);min-width:0}.nice-station-browser__name{flex-basis:100%;overflow:hidden;font-weight:var(--nice-font-weight-medium, 500);text-overflow:ellipsis;white-space:nowrap}.nice-station-browser__genre,.nice-station-browser__country{color:var(--nice-text-muted, #94a3b8);font-size:var(--nice-font-size-xs, .75rem)}.nice-station-browser__bitrate{flex-shrink:0;padding:0 var(--nice-space-1-5, 6px);border-radius:var(--nice-radius-full, 9999px);background:var(--nice-bg-tertiary, #e2e8f0);color:var(--nice-text-secondary, #64748b);font-size:var(--nice-font-size-xxs, .625rem);font-variant-numeric:tabular-nums}.nice-station-browser__empty{padding:var(--nice-space-4, 16px);color:var(--nice-text-muted, #94a3b8);text-align:center}
1
+ .nice-audio-error-boundary{display:flex;align-items:center;justify-content:center;min-height:160px;padding:var(--nice-space-6, 24px) var(--nice-space-4, 16px);color:var(--nice-text-primary, inherit);background:var(--nice-danger-bg, #fef2f2);border:1px solid color-mix(in srgb,var(--nice-color-danger, #ef4444) 30%,transparent);border-radius:var(--nice-radius-lg, 8px)}.nice-audio-error-boundary__content{display:flex;flex-direction:column;align-items:center;gap:var(--nice-space-2, 8px);max-width:60ch;text-align:center}.nice-audio-error-boundary__title{margin:0;font-size:var(--nice-font-size-lg, 1rem);font-weight:var(--nice-font-weight-semibold, 600)}.nice-audio-error-boundary__message{margin:0;color:var(--nice-text-secondary, #64748b);font-size:var(--nice-font-size-sm, .8125rem);overflow-wrap:anywhere}.nice-audio-error-boundary__retry{margin-top:var(--nice-space-1, 4px);padding:var(--nice-space-1-5, 6px) var(--nice-space-4, 16px);border:1px solid var(--nice-border-color, #e2e8f0);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #fff);color:var(--nice-text-primary, inherit);font:inherit;font-size:var(--nice-font-size-sm, .8125rem);cursor:pointer}.nice-audio-error-boundary__retry:hover{background:var(--nice-bg-secondary, #f8fafc)}.nice-audio-error-boundary__retry:focus-visible{outline:none;box-shadow:var(--nice-focus-ring, 0 0 0 2px var(--nice-color-primary, #3b82f6))}._panel_3bj7x_3{margin-bottom:var(--nice-space-3, 12px);padding:var(--nice-space-3, 12px);border:1px solid var(--nice-border-color, #e5e7eb);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #ffffff);color:var(--nice-text-primary, #0f172a)}._panelCompact_3bj7x_19{padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px)}._panelNarrow_3bj7x_25{max-width:520px}._panelWide_3bj7x_31{max-width:820px}._heading_3bj7x_37{margin:0 0 var(--nice-space-2, 8px);font-size:var(--nice-font-size-md, 14px);font-weight:var(--nice-font-weight-semibold, 600)}._row_3bj7x_53{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--nice-space-2, 8px) var(--nice-space-3, 12px)}._field_3bj7x_65{margin-bottom:var(--nice-space-2, 8px)}._buttonRow_3bj7x_71{display:flex;gap:var(--nice-space-2, 8px)}._sliderW200_3bj7x_83{width:200px}._sliderW240_3bj7x_89{width:240px}._selectW160_3bj7x_95{width:160px}._inputW120_3bj7x_101{width:120px}._inputW160_3bj7x_107{width:160px}._inputW200_3bj7x_113{width:200px}._noteText_3bj7x_123{font-size:13px;color:var(--nice-text-secondary, #888)}._noteTextMargin_3bj7x_131{font-size:13px;color:var(--nice-text-secondary, #888);margin-top:var(--nice-space-1, 4px)}._presetDivider_3bj7x_145{display:grid;gap:var(--nice-space-2, 8px);margin-top:var(--nice-space-2, 8px);padding-top:var(--nice-space-2, 8px);border-top:1px solid var(--nice-border-color, #444)}._presetLabel_3bj7x_159{font-size:11px;font-weight:600;color:var(--nice-text-muted, #aaa)}._countInAlert_3bj7x_173{font-size:12px;color:var(--nice-warning, #f57c00)}._levelLabel_3bj7x_181{font-size:12px;color:var(--nice-text-secondary, #555)}._levelMeter_3bj7x_189{position:relative;background:var(--nice-bg-secondary, #f1f1f1);height:12px;border-radius:var(--nice-radius-md, 6px);overflow:hidden;width:80px}._levelBar_3bj7x_205{position:absolute;left:0;top:0;bottom:0;transition:width 80ms linear}._panelInactive_3bj7x_225{opacity:.6}._header_3bj7x_231{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-2, 8px);margin-bottom:var(--nice-space-2, 8px)}._title_3bj7x_245{margin:0;font-size:var(--nice-font-size-md, 14px);font-weight:var(--nice-font-weight-semibold, 600);color:var(--nice-color-primary, #2563eb)}._grid2_3bj7x_257{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--nice-space-2, 8px) var(--nice-space-3, 12px)}._full_3bj7x_267{grid-column:1 / -1}._label_3bj7x_275{display:block;margin-bottom:var(--nice-space-1, 4px);font-size:var(--nice-font-size-sm, .8125rem);font-weight:var(--nice-font-weight-medium, 500);line-height:var(--nice-line-height, 1.5);color:var(--nice-text-primary, #0f172a)}._grow_3bj7x_291{flex:1 1 auto;min-width:0}._pushRight_3bj7x_299{margin-left:auto}._alignStart_3bj7x_305{align-items:flex-start}._toolbar_3bj7x_311{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-1, 4px);margin-bottom:var(--nice-space-2, 8px)}._subPanel_3bj7x_325{margin-bottom:var(--nice-space-2, 8px);padding:var(--nice-space-2, 8px);border:1px solid var(--nice-border-color, #e5e7eb);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary, #f8fafc)}.nice-sample-browser{display:flex;height:100%;min-height:400px;background:linear-gradient(to bottom,var(--nice-bg, #1a1a2e),var(--nice-bg, #0f0f1a));border-radius:var(--nice-radius-lg, 8px);overflow:hidden;color:var(--nice-text-secondary, #e0e0e0);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px}.nice-sample-browser__sidebar{width:220px;min-width:180px;max-width:300px;background:var(--nice-overlay-20, rgba(0, 0, 0, .2));border-right:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));overflow-y:auto}.nice-sample-browser__folders{padding:var(--nice-space-2, 8px) 0}.nice-sample-folder{-webkit-user-select:none;user-select:none}.nice-sample-folder__btn{display:flex;align-items:center;gap:var(--nice-space-2, 8px);width:100%;padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);background:none;border:none;color:var(--nice-text-secondary, #e0e0e0);cursor:pointer;text-align:left;transition:background .15s}.nice-sample-folder__btn:hover{background:var(--nice-accent-tint-15, rgba(139, 92, 246, .15))}.nice-sample-folder__btn--selected{background:var(--nice-accent-tint-20, rgba(139, 92, 246, .25));border-left:3px solid var(--nice-accent, #8b5cf6)}.nice-sample-folder__icon{font-size:14px}.nice-sample-folder__name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-sample-folder__count{font-size:11px;color:var(--nice-text-secondary, #888);background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));padding:var(--nice-space-0-5, 2px) var(--nice-space-1-5, 6px);border-radius:var(--nice-radius-lg, 10px)}.nice-sample-browser__main{flex:1;display:flex;flex-direction:column;overflow:hidden}.nice-sample-browser__header{display:flex;align-items:center;padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);background:var(--nice-overlay-30, rgba(0, 0, 0, .3));border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--nice-text-secondary, #888)}.nice-sample-browser__col{padding:0 var(--nice-space-1, 4px)}.nice-sample-browser__col--play{width:32px}.nice-sample-browser__col--fav{width:28px}.nice-sample-browser__col--name{flex:1;min-width:120px}.nice-sample-browser__col--waveform{width:200px}.nice-sample-browser__col--duration{width:70px;text-align:right}.nice-sample-browser__col--bpm{width:70px;text-align:center}.nice-sample-browser__col--key{width:50px;text-align:center}.nice-sample-browser__col--size{width:70px;text-align:right}.nice-sample-browser__col--tags{width:100px}.nice-sample-browser__list{flex:1;overflow-y:auto}.nice-sample-browser__empty{display:flex;align-items:center;justify-content:center;height:200px;color:var(--nice-text-secondary, #666);font-style:italic}.nice-sample-row{display:flex;align-items:center;padding:var(--nice-space-1-5, 6px) var(--nice-space-3, 12px);border-bottom:1px solid var(--nice-overlay-light-5, rgba(255, 255, 255, .05));cursor:pointer;transition:background .15s}.nice-sample-row:hover{background:var(--nice-accent-tint-10, rgba(139, 92, 246, .1))}.nice-sample-row--selected{background:var(--nice-accent-tint-20, rgba(139, 92, 246, .2))}.nice-sample-row--playing{background:var(--nice-success-tint-15, rgba(34, 197, 94, .15))}.nice-sample-row__play{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3));border:none;border-radius:var(--nice-radius-full, 50%);color:var(--nice-color-white, #fff);cursor:pointer;transition:all .15s;font-size:10px}.nice-sample-row__play:hover{background:var(--nice-accent-tint-50, rgba(139, 92, 246, .5));transform:scale(1.1)}.nice-sample-row--playing .nice-sample-row__play{background:var(--nice-success-tint-50, rgba(34, 197, 94, .5));animation:pulse-play 1s infinite}@keyframes pulse-play{0%,to{box-shadow:0 0 0 0 var(--nice-success-tint-40, rgba(34, 197, 94, .4))}50%{box-shadow:0 0 0 6px transparent}}.nice-sample-row__fav{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:none;border:none;color:var(--nice-text-secondary, #666);cursor:pointer;font-size:14px;transition:color .15s,transform .15s}.nice-sample-row__fav:hover{color:var(--nice-warning-light, #fbbf24);transform:scale(1.2)}.nice-sample-row__fav--active{color:var(--nice-warning-light, #fbbf24)}.nice-sample-row__name{flex:1;min-width:120px;padding:0 var(--nice-space-2, 8px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}.nice-sample-row__waveform{width:200px;padding:0 var(--nice-space-2, 8px)}.nice-sample-waveform{display:block;cursor:pointer;border-radius:var(--nice-radius-sm, 4px);background:var(--nice-overlay-20, rgba(0, 0, 0, .2))}.nice-sample-row__duration{width:70px;text-align:right;color:var(--nice-text-muted, #aaa);font-variant-numeric:tabular-nums}.nice-sample-row__bpm{width:70px;text-align:center;color:var(--nice-info, #22d3ee);font-weight:500;font-variant-numeric:tabular-nums}.nice-sample-row__key{width:50px;text-align:center;color:var(--nice-color-accent-pink, #f472b6);font-weight:500}.nice-sample-row__size{width:70px;text-align:right;color:var(--nice-text-secondary, #888);font-size:11px}.nice-sample-row__tags{width:100px;display:flex;gap:var(--nice-space-1, 4px);flex-wrap:wrap}.nice-sample-row__tag{font-size:10px;padding:var(--nice-space-0-5, 2px) var(--nice-space-1-5, 6px);background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3));color:var(--nice-accent, #c4b5fd);border-radius:var(--nice-radius-lg, 10px);white-space:nowrap}.nice-sample-browser__preview{width:320px;min-width:280px;background:var(--nice-overlay-20, rgba(0, 0, 0, .2));border-left:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));padding:var(--nice-space-4, 16px);display:flex;flex-direction:column;gap:var(--nice-space-4, 16px)}.nice-sample-browser__preview-title{margin:0;font-size:14px;font-weight:600;color:var(--nice-text-primary, #fff);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-sample-browser__preview canvas{border-radius:var(--nice-radius-lg, 8px);background:var(--nice-overlay-30, rgba(0, 0, 0, .3))}.nice-sample-browser__preview-info{display:flex;flex-direction:column;gap:var(--nice-space-2, 8px);font-size:12px;color:var(--nice-text-muted, #aaa)}.nice-sample-browser__preview-info>div{display:flex;justify-content:space-between}.nice-sample-browser__list::-webkit-scrollbar,.nice-sample-browser__sidebar::-webkit-scrollbar{width:8px}.nice-sample-browser__list::-webkit-scrollbar-track,.nice-sample-browser__sidebar::-webkit-scrollbar-track{background:transparent}.nice-sample-browser__list::-webkit-scrollbar-thumb,.nice-sample-browser__sidebar::-webkit-scrollbar-thumb{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2));border-radius:var(--nice-radius-sm, 4px)}.nice-sample-browser__list::-webkit-scrollbar-thumb:hover,.nice-sample-browser__sidebar::-webkit-scrollbar-thumb:hover{background:var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}@media(max-width:900px){.nice-sample-browser{flex-direction:column}.nice-sample-browser__sidebar{width:100%;max-width:none;max-height:150px;border-right:none;border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1))}.nice-sample-browser__preview{width:100%;border-left:none;border-top:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));flex-direction:row;flex-wrap:wrap;padding:var(--nice-space-3, 12px)}.nice-sample-browser__preview-title{width:100%}.nice-sample-browser__col--waveform,.nice-sample-row__waveform,.nice-sample-browser__col--tags,.nice-sample-row__tags{display:none}}@media(max-width:600px){.nice-sample-browser__col--bpm,.nice-sample-browser__col--key,.nice-sample-row__bpm,.nice-sample-row__key,.nice-sample-browser__col--size,.nice-sample-row__size{display:none}}.nice-pitch-meter{position:relative;width:100%;overflow:hidden;box-sizing:border-box;border:1px solid var(--nice-border-color, rgba(127, 127, 127, .25));border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary, transparent)}.nice-pitch-meter canvas{display:block}.nice-pitch-meter--idle{display:flex;align-items:center;justify-content:center;gap:var(--nice-space-2, 8px);color:var(--karaoke-waiting-text, var(--nice-text-secondary, #999));font-size:var(--nice-font-size-sm, 13px)}.nice-karaoke-summary{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;background:var(--nice-overlay-80, rgba(0, 0, 0, .8));padding:var(--nice-space-6, 24px);z-index:1000;color:var(--nice-color-white, #fff)}.nice-karaoke-summary__card{background:linear-gradient(180deg,var(--nice-bg-tertiary) 0%,var(--nice-bg-secondary) 100%);border-radius:var(--nice-radius-2xl, 16px);padding:var(--nice-space-7, 28px);width:min(700px,95vw);max-height:90vh;overflow-y:auto;box-shadow:0 12px 40px var(--nice-overlay-50, rgba(0, 0, 0, .5));display:flex;flex-direction:column;gap:var(--nice-space-4-5, 18px)}.nice-karaoke-summary__title{margin:0;font-size:1.4rem;font-weight:700;text-align:center;color:var(--nice-text, #e2e8f0)}.nice-karaoke-summary__bars{display:flex;flex-direction:column;gap:var(--nice-space-2-5, 10px)}.nice-karaoke-summary__bar{display:flex;align-items:center;gap:var(--nice-space-2-5, 10px);width:100%}.nice-karaoke-summary__bar-rank{width:32px;flex-shrink:0;text-align:center;font-size:18px}.nice-karaoke-summary__bar-name{width:100px;flex-shrink:0;font-weight:600;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-karaoke-summary__bar-track{position:relative;flex:1;height:28px;border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary);overflow:hidden}.nice-karaoke-summary__bar-fill-bonus,.nice-karaoke-summary__bar-fill-classic{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:var(--nice-radius-md, 6px)}.nice-karaoke-summary__bar-text{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:flex-end;padding-right:var(--nice-space-2, 8px);font-size:13px;font-weight:700;color:var(--nice-text-primary, #fff);text-shadow:0 1px 3px var(--nice-overlay-70, rgba(0, 0, 0, .7))}.nice-karaoke-summary__bar-text-bonus{margin-left:var(--nice-space-1, 4px);font-size:11px}.nice-karaoke-summary__bar-total{width:70px;flex-shrink:0;text-align:right;font-weight:700;font-size:15px;color:var(--nice-warning-light, #fbbf24)}.nice-karaoke-summary__ranks{display:flex;gap:var(--nice-space-4, 16px);flex-wrap:wrap}.nice-karaoke-summary__rank{flex:1;min-width:200px}.nice-karaoke-summary__rank-title{margin:0 0 var(--nice-space-1-5, 6px);font-size:14px;color:var(--nice-text-muted, #94a3b8)}.nice-karaoke-summary__rank-table{width:100%;border-collapse:collapse;font-size:13px}.nice-karaoke-summary__rank-row{border-bottom:1px solid var(--nice-border, #1e293b)}.nice-karaoke-summary__rank-row--hl{background:var(--nice-warning-tint-10, rgba(251, 191, 36, .1))}.nice-karaoke-summary__rank-pos{width:24px;padding:var(--nice-space-0-75, 3px) var(--nice-space-1-5, 6px);color:var(--nice-text-dim, #64748b)}.nice-karaoke-summary__rank-pos--top{color:var(--nice-warning-light, #fbbf24);font-weight:700}.nice-karaoke-summary__rank-name{padding:var(--nice-space-0-75, 3px) var(--nice-space-1-5, 6px);color:var(--nice-text, #cbd5e1)}.nice-karaoke-summary__rank-row--hl .nice-karaoke-summary__rank-name{font-weight:700}.nice-karaoke-summary__rank-score{padding:var(--nice-space-0-75, 3px) var(--nice-space-1-5, 6px);text-align:right;color:var(--nice-text-muted, #94a3b8)}.nice-karaoke-summary__rank-row--hl .nice-karaoke-summary__rank-score{color:var(--nice-warning-light, #fbbf24)}.nice-karaoke-summary__empty{text-align:center;color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));font-size:1rem;padding:2rem}.nice-karaoke-summary__actions{display:flex;gap:var(--nice-space-3, 12px);justify-content:flex-end;margin-top:var(--nice-space-1, 4px)}.nice-karaoke-summary__btn{min-width:120px;padding:.7rem 1.5rem;font-size:.95rem;font-weight:700;border:none;border-radius:var(--nice-radius-lg, 8px);cursor:pointer;transition:all .2s ease}.nice-karaoke-summary__btn--report{background:var(--nice-accent, #6366f1);color:var(--nice-text-on-primary, #fff)}.nice-karaoke-summary__btn--restart{background:var(--nice-success, #22c55e);color:var(--nice-text-on-primary, #fff)}.nice-karaoke-summary__btn--continue{background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));color:var(--nice-color-white, #fff);border:1px solid var(--nice-overlay-light-20, rgba(255, 255, 255, .2))}.nice-karaoke-summary__btn:hover{filter:brightness(1.08);transform:translateY(-1px)}@media(max-width:600px){.nice-karaoke-summary__card{padding:var(--nice-space-4-5, 18px)}.nice-karaoke-summary__bar-name{width:72px}.nice-karaoke-summary__actions{flex-direction:column}.nice-karaoke-summary__btn{width:100%}}.nice-ksb{display:flex;gap:var(--nice-space-4, 16px);width:100%;color:var(--nice-text, #e2e8f0);font-size:14px}.nice-ksb__sidebar{flex:0 0 200px;display:flex;flex-direction:column;gap:var(--nice-space-1, 4px);max-height:600px;overflow-y:auto}.nice-ksb__facet{margin-top:var(--nice-space-2-5, 10px)}.nice-ksb__facet-title{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--nice-text-muted, #94a3b8);margin:var(--nice-space-1, 4px) var(--nice-space-1-5, 6px)}.nice-ksb__node{display:block;width:100%;text-align:left;padding:var(--nice-space-1-75, 7px) var(--nice-space-2-5, 10px);border:none;border-radius:var(--nice-radius-md, 6px);background:transparent;color:var(--nice-text, #cbd5e1);cursor:pointer;font-size:13px}.nice-ksb__node:hover{background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05))}.nice-ksb__node--active{background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2));color:var(--nice-color-accent, #a5b4fc);font-weight:600}.nice-ksb__main{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--nice-space-2-5, 10px)}.nice-ksb__toolbar{display:flex;gap:var(--nice-space-2-5, 10px);align-items:center;flex-wrap:wrap}.nice-ksb__search{flex:1;min-width:180px;padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);border-radius:var(--nice-radius-md, 6px);border:1px solid var(--nice-border, #334155);background:var(--nice-bg-secondary);color:var(--nice-text, #e2e8f0);font-size:14px}.nice-ksb__sort{display:flex;gap:var(--nice-space-1, 4px);flex-wrap:wrap}.nice-ksb__sort-btn{padding:var(--nice-space-1-5, 6px) var(--nice-space-2-5, 10px);border:1px solid var(--nice-border, #334155);border-radius:var(--nice-radius-md, 6px);background:transparent;color:var(--nice-text-muted, #94a3b8);cursor:pointer;font-size:12px;text-transform:capitalize}.nice-ksb__sort-btn--active{background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2));color:var(--nice-color-accent, #a5b4fc);border-color:var(--nice-accent, #6366f1)}.nice-ksb__navhint{display:inline-flex;align-items:center;gap:var(--nice-space-1, 4px);margin-left:auto;padding:var(--nice-space-1, 4px) var(--nice-space-2, 8px);border-radius:var(--nice-radius-md, 6px);color:var(--nice-text-muted, #94a3b8);font-size:12px;white-space:nowrap}.nice-ksb__navhint--pad{color:var(--nice-accent-light, #a5b4fc);background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2))}.nice-ksb__navhint-keys{font-variant-numeric:tabular-nums}.nice-ksb__disabled{padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);border-radius:var(--nice-radius-md, 6px);background:var(--nice-warning-tint-10, rgba(251, 191, 36, .1));color:var(--nice-warning-light, #fbbf24);font-size:13px}.nice-ksb__list{display:flex;flex-direction:column;gap:var(--nice-space-1, 4px);max-height:560px;overflow-y:auto}.nice-ksb__empty{text-align:center;padding:var(--nice-space-8, 32px);color:var(--nice-text-muted, #94a3b8)}.nice-ksb-row{display:flex;align-items:center;gap:var(--nice-space-2-5, 10px);padding:var(--nice-space-1-5, 6px) var(--nice-space-2, 8px);border-radius:var(--nice-radius-md, 8px);cursor:pointer}.nice-ksb-row:hover{background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05))}.nice-ksb-row--selected{background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2))}.nice-ksb-row--active{box-shadow:inset 0 0 0 2px var(--nice-accent, #6366f1);background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05))}.nice-ksb-row:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--nice-accent, #6366f1),var(--nice-focus-ring, 0 0 0 2px var(--nice-accent, #6366f1))}.nice-ksb-row__check{flex:0 0 auto;width:16px;height:16px}.nice-ksb-row__cover{flex:0 0 auto;width:44px;height:44px;border-radius:var(--nice-radius-md, 6px);object-fit:cover;background:var(--nice-bg-tertiary)}.nice-ksb-row__main{flex:1;min-width:0}.nice-ksb-row__title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nice-ksb-row__artist{font-size:12px;color:var(--nice-text-muted, #94a3b8);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nice-ksb-row__meta{display:flex;gap:var(--nice-space-1, 4px);flex-wrap:wrap;justify-content:flex-end;max-width:50%}.nice-ksb-badge{font-size:11px;padding:var(--nice-space-0-5, 2px) var(--nice-space-1-75, 7px);border-radius:var(--nice-radius-full, 999px);background:var(--nice-bg-tertiary);color:var(--nice-text-muted, #94a3b8);white-space:nowrap}.nice-ksb-badge--src{background:var(--nice-accent-tint-20, rgba(99, 102, 241, .2));color:var(--nice-color-accent, #a5b4fc)}.nice-ksb-badge--score{background:var(--nice-warning-bg, rgba(251, 191, 36, .12));color:var(--nice-warning-text, #fbbf24)}.nice-ksb-row__play{flex:0 0 auto;padding:var(--nice-space-1-5, 6px) var(--nice-space-3-5, 14px);border:none;border-radius:var(--nice-radius-md, 6px);background:var(--nice-accent, #6366f1);color:var(--nice-text-on-primary, #fff);cursor:pointer;font-weight:600;font-size:13px}.nice-ksb-row__play:disabled{opacity:.5;cursor:not-allowed}.nice-ksb__footer{display:flex;align-items:center;justify-content:space-between;gap:var(--nice-space-3, 12px);padding-top:var(--nice-space-2, 8px);border-top:1px solid var(--nice-border, #1e293b);color:var(--nice-text-muted, #94a3b8);font-size:13px}.nice-ksb__confirm{padding:var(--nice-space-2, 8px) 18px;border:none;border-radius:var(--nice-radius-md, 6px);background:var(--nice-success, #22c55e);color:var(--nice-text-on-primary, #fff);cursor:pointer;font-weight:700}.nice-ksb__confirm:disabled{opacity:.5;cursor:not-allowed}@media(max-width:640px){.nice-ksb{flex-direction:column}.nice-ksb__sidebar{flex-basis:auto;flex-direction:row;flex-wrap:wrap;max-height:none}.nice-ksb-row__meta{display:none}}._editor_qz5p3_5{padding:var(--nice-space-3, 12px);border:1px solid var(--nice-border-color, #e5e7eb);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #ffffff);color:var(--nice-text-primary, #0f172a)}._heading_qz5p3_19{display:flex;align-items:center;gap:var(--nice-space-1, 4px);margin:0 0 var(--nice-space-1, 4px);font-size:var(--nice-font-size-md, 14px);font-weight:var(--nice-font-weight-semibold, 600)}._hint_qz5p3_35{margin:0 0 var(--nice-space-3, 12px);font-size:var(--nice-font-size-sm, .8125rem);color:var(--nice-text-secondary, #475569)}._group_qz5p3_49{margin-bottom:var(--nice-space-2, 8px);padding:var(--nice-space-2, 8px);border-left:3px solid var(--nice-color-primary, #2563eb);border-radius:var(--nice-radius-sm, 4px)}._groupOr_qz5p3_61{border-left-color:var(--nice-color-warning, #f59e0b)}._groupShaded_qz5p3_67{background:var(--nice-bg-secondary, #f8fafc)}._groupHeader_qz5p3_73{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-2, 8px);margin-bottom:var(--nice-space-2, 8px)}._groupHint_qz5p3_87{font-size:var(--nice-font-size-sm, .8125rem);color:var(--nice-text-secondary, #475569)}._groupActions_qz5p3_95{display:flex;gap:var(--nice-space-1, 4px);margin-left:auto}._rule_qz5p3_107{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-2, 8px);margin-bottom:var(--nice-space-2, 8px)}._value_qz5p3_121{width:180px}._value2_qz5p3_127{width:140px}._dash_qz5p3_133{color:var(--nice-text-secondary, #475569)}._limit_qz5p3_141{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--nice-space-2, 8px);margin-top:var(--nice-space-3, 12px);padding-top:var(--nice-space-2, 8px);border-top:1px solid var(--nice-border-color, #e5e7eb)}._limitInput_qz5p3_159{width:140px}.nice-fx-rack{display:flex;flex-direction:column;gap:1rem;padding:1rem;background:linear-gradient(180deg,var(--nice-bg, #1a1a2e),var(--nice-bg, #16213e));border-radius:var(--nice-radius-xl, 12px);border:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));font-family:system-ui,-apple-system,sans-serif}.nice-fx-rack--compact{padding:.75rem;gap:.5rem}.nice-fx-rack__header{display:flex;justify-content:space-between;align-items:center;padding-bottom:.5rem;border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1))}.nice-fx-rack__title{margin:0;font-size:1rem;font-weight:600;color:var(--nice-text-primary, #fff)}.nice-fx-rack__count{font-size:.75rem;color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));padding:.25rem .5rem;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-sm, 4px)}.nice-fx-rack__chain{display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-start;min-height:120px}.nice-fx-rack__slot{display:flex;align-items:center;gap:.5rem}.nice-fx-rack__connector{display:inline-flex;align-items:center;color:var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}.nice-fx-rack__empty{display:flex;align-items:center;justify-content:center;width:100%;min-height:100px;color:var(--nice-overlay-light-30, rgba(255, 255, 255, .3));font-size:.875rem;border:2px dashed var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-lg, 8px)}.nice-fx-card{display:flex;flex-direction:column;min-width:180px;background:var(--nice-overlay-30, rgba(0, 0, 0, .3));border-radius:var(--nice-radius-lg, 8px);border:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));overflow:hidden;cursor:grab;transition:all .2s ease}.nice-fx-card:hover{border-color:var(--nice-accent-tint-50, rgba(139, 92, 246, .5));box-shadow:0 4px 12px var(--nice-overlay-30, rgba(0, 0, 0, .3))}.nice-fx-card:active{cursor:grabbing}.nice-fx-card--disabled{opacity:.5}.nice-fx-card--drop-target{border-color:var(--nice-success, #22c55e);box-shadow:0 0 0 2px var(--nice-success-tint-30, rgba(34, 197, 94, .3))}.nice-fx-card--compact{min-width:140px}.nice-fx-card__header{display:flex;align-items:center;gap:.5rem;padding:.5rem;background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05));border-bottom:1px solid var(--nice-overlay-light-5, rgba(255, 255, 255, .05))}.nice-fx-card__icon{font-size:1rem}.nice-fx-card__title{flex:1;font-size:.75rem;font-weight:600;color:var(--nice-text-primary, #fff);text-transform:uppercase;letter-spacing:.05em}.nice-fx-card__toggle{width:20px;height:20px;padding:0;border:none;display:inline-flex;align-items:center;justify-content:center;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-full, 50%);color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));font-size:.75rem;cursor:pointer;transition:all .2s ease}.nice-fx-card__toggle-dot{width:8px;height:8px;border-radius:var(--nice-radius-circle, 50%);border:1.5px solid currentColor;background:transparent}.nice-fx-card__toggle--active .nice-fx-card__toggle-dot{background:currentColor}.nice-fx-card__toggle:hover{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2))}.nice-fx-card__toggle--active{background:var(--nice-success, #22c55e);color:var(--nice-text-on-primary, #fff)}.nice-fx-card__presets{position:relative}.nice-fx-card__preset-btn{width:24px;height:20px;padding:0;border:none;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-sm, 4px);color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));font-size:.625rem;cursor:pointer}.nice-fx-card__preset-btn:hover{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2))}.nice-fx-card__preset-menu{position:absolute;top:100%;right:0;z-index:100;min-width:120px;margin-top:var(--nice-space-1, 4px);padding:.25rem;background:var(--nice-bg, #1a1a2e);border:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-md, 6px);box-shadow:0 4px 12px var(--nice-overlay-50, rgba(0, 0, 0, .5))}.nice-fx-card__preset-item{display:block;width:100%;padding:.375rem .5rem;border:none;background:none;color:var(--nice-overlay-light-80, rgba(255, 255, 255, .8));font-size:.75rem;text-align:left;text-transform:capitalize;cursor:pointer;border-radius:var(--nice-radius-sm, 4px)}.nice-fx-card__preset-item:hover{background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3))}.nice-fx-card__remove{width:20px;height:20px;padding:0;border:none;background:none;color:var(--nice-overlay-light-30, rgba(255, 255, 255, .3));font-size:1rem;cursor:pointer;transition:all .2s ease}.nice-fx-card__remove:hover{color:var(--nice-danger, #ef4444)}.nice-fx-card__body{padding:.75rem}.nice-fx-card__controls{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center}.nice-fx-card__generic{display:flex;justify-content:center}.nice-fx-knob{display:flex;flex-direction:column;align-items:center;gap:.25rem;min-width:44px}.nice-fx-knob--disabled{opacity:.4;pointer-events:none}.nice-fx-knob__dial{position:relative;width:36px;height:36px;background:linear-gradient(145deg,var(--nice-bg-secondary, #2a2a4a),var(--nice-bg, #1a1a2e));border-radius:var(--nice-radius-full, 50%);border:2px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));cursor:pointer;-webkit-user-select:none;user-select:none;box-shadow:0 2px 8px var(--nice-overlay-30, rgba(0, 0, 0, .3));transition:border-color .2s ease}.nice-fx-knob__dial:hover{border-color:var(--nice-accent-tint-50, rgba(139, 92, 246, .5))}.nice-fx-knob__dial--active{border-color:var(--nice-accent, #8b5cf6)}.nice-fx-knob__indicator{position:absolute;top:4px;left:50%;width:2px;height:8px;background:var(--nice-accent, #8b5cf6);border-radius:var(--nice-radius-xs, 1px);transform:translate(-50%)}.nice-fx-knob__label{font-size:.625rem;color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));text-transform:uppercase;letter-spacing:.05em;text-align:center}.nice-fx-knob__value{font-size:.625rem;color:var(--nice-overlay-light-80, rgba(255, 255, 255, .8));font-weight:500;text-align:center}.nice-fx-rack__add{position:relative}.nice-fx-rack__add-btn{display:flex;align-items:center;justify-content:center;width:100%;padding:.75rem;border:2px dashed var(--nice-overlay-light-20, rgba(255, 255, 255, .2));border-radius:var(--nice-radius-lg, 8px);background:none;color:var(--nice-overlay-light-50, rgba(255, 255, 255, .5));font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.nice-fx-rack__add-btn:hover{border-color:var(--nice-accent-tint-50, rgba(139, 92, 246, .5));color:var(--nice-overlay-light-80, rgba(255, 255, 255, .8));background:var(--nice-accent-tint-10, rgba(139, 92, 246, .1))}.nice-fx-rack__add-menu{position:absolute;bottom:100%;left:0;right:0;z-index:100;display:grid;grid-template-columns:repeat(2,1fr);gap:.25rem;margin-bottom:var(--nice-space-2, 8px);padding:.5rem;background:var(--nice-bg, #1a1a2e);border:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border-radius:var(--nice-radius-lg, 8px);box-shadow:0 -4px 12px var(--nice-overlay-30, rgba(0, 0, 0, .3))}.nice-fx-rack__add-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;border:none;background:var(--nice-overlay-light-5, rgba(255, 255, 255, .05));border-radius:var(--nice-radius-md, 6px);color:var(--nice-overlay-light-80, rgba(255, 255, 255, .8));font-size:.75rem;cursor:pointer;transition:all .2s ease}.nice-fx-rack__add-item:hover{background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3))}.nice-fx-rack__add-icon{font-size:1rem}.nice-fx-rack__add-label{text-align:left}@media(max-width:600px){.nice-fx-rack{padding:.75rem}.nice-fx-card{min-width:100%}.nice-fx-rack__add-menu{grid-template-columns:1fr}}.nice-dmx-timeline{display:flex;flex-direction:column;height:100%;min-height:300px;background:linear-gradient(to bottom,var(--nice-bg, #1a1a2e),var(--nice-bg, #0f0f1a));border-radius:var(--nice-radius-lg, 8px);overflow:hidden;color:var(--nice-text-secondary, #e0e0e0);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px}.nice-dmx-timeline__toolbar{display:flex;align-items:center;gap:var(--nice-space-4, 16px);padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);background:var(--nice-overlay-30, rgba(0, 0, 0, .3));border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1))}.nice-dmx-timeline__transport{display:flex;gap:var(--nice-space-1, 4px)}.nice-dmx-timeline__transport button{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background:var(--nice-accent-tint-30, rgba(139, 92, 246, .3));border:none;border-radius:var(--nice-radius-sm, 4px);color:var(--nice-color-white, #fff);cursor:pointer;font-size:14px;transition:all .15s}.nice-dmx-timeline__transport button:hover{background:var(--nice-accent-tint-50, rgba(139, 92, 246, .5))}.nice-dmx-timeline__transport button:active{transform:scale(.95)}.nice-dmx-timeline__time{font-family:Consolas,Monaco,monospace;font-size:18px;font-weight:600;color:var(--nice-info, #22d3ee);min-width:100px}.nice-dmx-timeline__tools{display:flex;align-items:center;gap:var(--nice-space-1, 4px)}.nice-dmx-timeline__tools button{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border:none;border-radius:var(--nice-radius-sm, 4px);color:var(--nice-text-muted, #aaa);cursor:pointer;transition:all .15s}.nice-dmx-timeline__tools button:hover{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2));color:var(--nice-color-white, #fff)}.nice-dmx-timeline__tools button.nice-dmx-timeline__tool--active{background:var(--nice-accent-tint-40, rgba(139, 92, 246, .4));color:var(--nice-color-white, #fff)}.nice-dmx-timeline__zoom{font-size:11px;color:var(--nice-text-secondary, #888);min-width:40px;text-align:center}.nice-dmx-timeline__bpm{display:flex;align-items:center;gap:var(--nice-space-1-5, 6px);font-size:12px;color:var(--nice-text-secondary, #888)}.nice-dmx-timeline__bpm span{color:var(--nice-color-accent-pink, #f472b6);font-weight:600}.nice-dmx-timeline__blackout{margin-left:auto;padding:var(--nice-space-1-5, 6px) var(--nice-space-3, 12px);background:var(--nice-danger-tint-30, rgba(239, 68, 68, .3));border:none;border-radius:var(--nice-radius-sm, 4px);color:var(--nice-color-white, #fff);cursor:pointer;font-size:14px;transition:all .15s}.nice-dmx-timeline__blackout:hover{background:color-mix(in srgb,var(--nice-color-danger, #ef4444) 50%,transparent)}.nice-dmx-timeline__content{flex:1;display:flex;overflow:hidden}.nice-dmx-timeline__headers{width:180px;min-width:150px;background:var(--nice-overlay-20, rgba(0, 0, 0, .2));border-right:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));overflow-y:auto;padding-top:var(--nice-space-8, 32px)}.nice-dmx-timeline__header{display:flex;align-items:center;gap:var(--nice-space-2, 8px);height:48px;padding:0 var(--nice-space-3, 12px);border-bottom:1px solid var(--nice-overlay-light-5, rgba(255, 255, 255, .05));cursor:pointer;transition:background .15s}.nice-dmx-timeline__header:hover{background:var(--nice-accent-tint-10, rgba(139, 92, 246, .1))}.nice-dmx-timeline__header--selected{background:var(--nice-accent-tint-20, rgba(139, 92, 246, .2))}.nice-dmx-timeline__track-color{width:8px;height:8px;border-radius:var(--nice-radius-full, 50%)}.nice-dmx-timeline__track-name{flex:1;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-dmx-timeline__track-controls{display:flex;gap:var(--nice-space-1, 4px)}.nice-dmx-timeline__track-controls button{width:20px;height:20px;display:flex;align-items:center;justify-content:center;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1));border:none;border-radius:var(--nice-radius-sm, 3px);color:var(--nice-text-secondary, #888);cursor:pointer;font-size:10px;transition:all .15s}.nice-dmx-timeline__track-controls button:hover{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2));color:var(--nice-color-white, #fff)}.nice-dmx-timeline__track-controls button.nice-dmx-timeline__track-toggle--active{background:var(--nice-danger-tint-40, rgba(239, 68, 68, .4));color:var(--nice-color-white, #fff)}.nice-dmx-timeline__add-track{width:100%;padding:var(--nice-space-3, 12px);background:none;border:none;border-top:1px dashed var(--nice-overlay-light-10, rgba(255, 255, 255, .1));color:var(--nice-text-secondary, #666);cursor:pointer;text-align:center;transition:all .15s}.nice-dmx-timeline__add-track:hover{background:var(--nice-accent-tint-10, rgba(139, 92, 246, .1));color:var(--nice-accent, #8b5cf6)}.nice-dmx-timeline__tracks{flex:1;overflow:auto;position:relative}.nice-dmx-timeline__ruler{position:sticky;top:0;height:32px;background:var(--nice-overlay-40, rgba(0, 0, 0, .4));border-bottom:1px solid var(--nice-overlay-light-10, rgba(255, 255, 255, .1));z-index:10}.nice-dmx-timeline__beat{position:absolute;top:0;bottom:0;width:1px;background:var(--nice-overlay-light-10, rgba(255, 255, 255, .1))}.nice-dmx-timeline__beat--measure{background:var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}.nice-dmx-timeline__beat-label{position:absolute;top:4px;left:4px;font-size:10px;color:var(--nice-text-secondary, #888)}.nice-dmx-timeline__track{position:relative;height:48px;border-bottom:1px solid var(--nice-overlay-light-5, rgba(255, 255, 255, .05));background:linear-gradient(90deg,var(--nice-overlay-light-2, rgba(255, 255, 255, .02)) 0%,transparent 1px,transparent 100%);background-size:100px 100%}.nice-dmx-timeline__track--muted{opacity:.4}.nice-dmx-timeline__cue{position:absolute;top:4px;height:calc(100% - 8px);border-radius:var(--nice-radius-sm, 4px);cursor:pointer;overflow:hidden;transition:box-shadow .15s}.nice-dmx-timeline__cue:hover{box-shadow:0 0 0 2px var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}.nice-dmx-timeline__cue--selected{box-shadow:0 0 0 2px var(--nice-bg, #fff)}.nice-dmx-timeline__cue-name{position:absolute;top:4px;left:6px;right:6px;font-size:11px;font-weight:500;color:var(--nice-text-primary, #fff);text-shadow:0 1px 2px var(--nice-overlay-50, rgba(0, 0, 0, .5));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-dmx-timeline__cue-fade{position:absolute;top:0;bottom:0;background:linear-gradient(to right,var(--nice-overlay-80, rgba(0, 0, 0, .8)),transparent)}.nice-dmx-timeline__cue-fade--in{left:0}.nice-dmx-timeline__cue-fade--out{right:0;transform:scaleX(-1)}.nice-dmx-timeline__playhead{position:absolute;top:0;bottom:0;width:2px;background:var(--nice-danger, #ef4444);z-index:20;pointer-events:none}.nice-dmx-timeline__playhead:before{content:"";position:absolute;top:0;left:50%;transform:translate(-50%);width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:8px solid var(--nice-danger, #ef4444)}.nice-dmx-timeline__tracks::-webkit-scrollbar,.nice-dmx-timeline__headers::-webkit-scrollbar{width:8px;height:8px}.nice-dmx-timeline__tracks::-webkit-scrollbar-track,.nice-dmx-timeline__headers::-webkit-scrollbar-track{background:transparent}.nice-dmx-timeline__tracks::-webkit-scrollbar-thumb,.nice-dmx-timeline__headers::-webkit-scrollbar-thumb{background:var(--nice-overlay-light-20, rgba(255, 255, 255, .2));border-radius:var(--nice-radius-sm, 4px)}.nice-dmx-timeline__tracks::-webkit-scrollbar-thumb:hover,.nice-dmx-timeline__headers::-webkit-scrollbar-thumb:hover{background:var(--nice-overlay-light-30, rgba(255, 255, 255, .3))}@media(max-width:768px){.nice-dmx-timeline__toolbar{flex-wrap:wrap;gap:var(--nice-space-2, 8px)}.nice-dmx-timeline__headers{width:120px;min-width:100px}.nice-dmx-timeline__track-controls,.nice-dmx-timeline__bpm{display:none}}.nice-radio-player{display:flex;flex-direction:column;gap:var(--nice-space-3, 12px);min-width:0;padding:var(--nice-space-4, 16px);background:var(--nice-bg-elevated, var(--nice-bg-primary, #fff));border:1px solid var(--nice-border-color, #e2e8f0);border-radius:var(--nice-radius-lg, 8px);color:var(--nice-text-primary, inherit);font-size:var(--nice-font-size-sm, .8125rem)}.nice-radio-player__now-playing{display:flex;align-items:center;gap:var(--nice-space-3, 12px);min-height:64px;min-width:0}.nice-radio-player__cover{flex-shrink:0;width:64px;height:64px;border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary, #f1f5f9);object-fit:cover}.nice-radio-player__info{display:flex;flex-direction:column;gap:var(--nice-space-0-5, 2px);min-width:0}.nice-radio-player__station-name{overflow:hidden;font-size:var(--nice-font-size-lg, 1rem);font-weight:var(--nice-font-weight-semibold, 600);text-overflow:ellipsis;white-space:nowrap}.nice-radio-player__track{overflow:hidden;color:var(--nice-text-secondary, #64748b);text-overflow:ellipsis;white-space:nowrap}.nice-radio-player__genre,.nice-radio-player__buffering{color:var(--nice-text-muted, #94a3b8);font-size:var(--nice-font-size-xs, .75rem)}.nice-radio-player__buffering{font-style:italic}.nice-radio-player__placeholder{color:var(--nice-text-muted, #94a3b8)}.nice-radio-player__controls{display:flex;align-items:center;gap:var(--nice-space-3, 12px)}.nice-radio-player__play-btn{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:0;border-radius:var(--nice-radius-circle, 50%);background:var(--nice-color-primary, #3b82f6);color:var(--nice-text-on-primary, #fff);cursor:pointer}.nice-radio-player__play-btn:hover:not(:disabled){filter:brightness(1.08)}.nice-radio-player__play-btn:disabled{opacity:.5;cursor:not-allowed}.nice-radio-player__volume{display:flex;flex:1 1 auto;align-items:center;gap:var(--nice-space-2, 8px);min-width:0}.nice-radio-player__volume-icon{display:inline-flex;color:var(--nice-text-secondary, #64748b)}.nice-radio-player__volume-slider{flex:1 1 auto;min-width:60px;max-width:200px;accent-color:var(--nice-color-primary, #3b82f6)}.nice-radio-player__eq-btn,.nice-radio-player__eq-preset{padding:var(--nice-space-1, 4px) var(--nice-space-2-5, 10px);border:1px solid var(--nice-border-color, #e2e8f0);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #fff);color:var(--nice-text-secondary, #64748b);font:inherit;font-size:var(--nice-font-size-xs, .75rem);font-weight:var(--nice-font-weight-semibold, 600);cursor:pointer}.nice-radio-player__eq-btn:hover,.nice-radio-player__eq-preset:hover{border-color:var(--nice-border-strong, #cbd5e1);color:var(--nice-text-primary, inherit)}.nice-radio-player__eq-btn--active,.nice-radio-player__eq-preset--active{border-color:var(--nice-color-primary, #3b82f6);background:color-mix(in srgb,var(--nice-color-primary, #3b82f6) 12%,transparent);color:var(--nice-color-primary, #3b82f6)}.nice-radio-player__play-btn:focus-visible,.nice-radio-player__eq-btn:focus-visible,.nice-radio-player__eq-preset:focus-visible{outline:none;box-shadow:var(--nice-focus-ring, 0 0 0 2px var(--nice-color-primary, #3b82f6))}.nice-radio-player__error{padding:var(--nice-space-2, 8px) var(--nice-space-3, 12px);border-radius:var(--nice-radius-md, 6px);background:color-mix(in srgb,var(--nice-color-danger, #ef4444) 12%,transparent);color:var(--nice-color-danger, #dc2626)}.nice-radio-player__equalizer{padding:var(--nice-space-2, 8px);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-secondary, #f8fafc)}.nice-radio-player__eq-presets{display:flex;flex-wrap:wrap;gap:var(--nice-space-1, 4px)}.nice-station-browser{display:flex;flex-direction:column;gap:var(--nice-space-2, 8px);min-width:0}.nice-station-browser__toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--nice-space-2, 8px)}.nice-station-browser__search,.nice-station-browser__genre-filter{box-sizing:border-box;padding:var(--nice-space-1-5, 6px) var(--nice-space-2-5, 10px);border:1px solid var(--nice-border-color, #e2e8f0);border-radius:var(--nice-radius-md, 6px);background:var(--nice-bg-primary, #fff);color:var(--nice-text-primary, inherit);font:inherit}.nice-station-browser__search{flex:1 1 180px;min-width:0}.nice-station-browser__fav-toggle,.nice-station-browser__fav{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;padding:var(--nice-space-1-5, 6px);border:1px solid transparent;border-radius:var(--nice-radius-md, 6px);background:transparent;cursor:pointer}.nice-station-browser__fav-toggle{border-color:var(--nice-border-color, #e2e8f0)}.nice-station-browser__fav-toggle--active{border-color:var(--nice-color-warning, #f59e0b);background:color-mix(in srgb,var(--nice-color-warning, #f59e0b) 14%,transparent)}.nice-station-browser__fav:hover{background:var(--nice-bg-tertiary, #e2e8f0)}.nice-station-browser__list{display:flex;flex-direction:column;gap:var(--nice-space-px, 1px);max-height:320px;overflow-y:auto}.nice-station-browser__item{display:flex;align-items:center;gap:var(--nice-space-2-5, 10px);padding:var(--nice-space-1-5, 6px) var(--nice-space-2, 8px);border-radius:var(--nice-radius-md, 6px);cursor:pointer}.nice-station-browser__item:hover{background:var(--nice-bg-secondary, #f8fafc)}.nice-station-browser__item--active,.nice-station-browser__item--active:hover{background:color-mix(in srgb,var(--nice-color-primary, #3b82f6) 12%,transparent)}.nice-station-browser__item:focus-visible,.nice-station-browser__fav-toggle:focus-visible,.nice-station-browser__fav:focus-visible{outline:none;box-shadow:var(--nice-focus-ring, 0 0 0 2px var(--nice-color-primary, #3b82f6))}.nice-station-browser__logo{flex-shrink:0;width:36px;height:36px;border-radius:var(--nice-radius-sm, 4px);object-fit:cover}.nice-station-browser__info{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:baseline;gap:var(--nice-space-0-5, 2px) var(--nice-space-2, 8px);min-width:0}.nice-station-browser__name{flex-basis:100%;overflow:hidden;font-weight:var(--nice-font-weight-medium, 500);text-overflow:ellipsis;white-space:nowrap}.nice-station-browser__genre,.nice-station-browser__country{color:var(--nice-text-muted, #94a3b8);font-size:var(--nice-font-size-xs, .75rem)}.nice-station-browser__bitrate{flex-shrink:0;padding:0 var(--nice-space-1-5, 6px);border-radius:var(--nice-radius-full, 9999px);background:var(--nice-bg-tertiary, #e2e8f0);color:var(--nice-text-secondary, #64748b);font-size:var(--nice-font-size-xxs, .625rem);font-variant-numeric:tabular-nums}.nice-station-browser__empty{padding:var(--nice-space-4, 16px);color:var(--nice-text-muted, #94a3b8);text-align:center}
@@ -0,0 +1,9 @@
1
+ /** A frequency (Hz) as a MIDI note number, fractional between notes (A4 = 440 Hz = 69). */
2
+ export declare function hzToMidi(hz: number): number;
3
+ /** The name of the nearest note, with its octave: 60 → `C4`, 69 → `A4`. */
4
+ export declare function midiToNoteName(midi: number): string;
5
+ /**
6
+ * Semitones from `target`, octave-independent like the scoring (`karaokeScoring.ts`): a singer an
7
+ * octave below the melody is on pitch. The result lies within ±6.
8
+ */
9
+ export declare function semitoneOffset(midi: number, target: number): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nice2dev/ui-audio",
3
- "version": "1.3.13",
3
+ "version": "1.3.14",
4
4
  "description": "Nice2Dev Audio UI — DAW editor, karaoke engine, player, playlist, DMX, music visualizers for React",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -75,8 +75,8 @@
75
75
  "react-dom": ">=17.0.0"
76
76
  },
77
77
  "devDependencies": {
78
- "@nice2dev/ui": "^1.3.13",
79
- "@nice2dev/ui-core": "^1.3.13",
78
+ "@nice2dev/ui": "^1.3.14",
79
+ "@nice2dev/ui-core": "^1.3.14",
80
80
  "@testing-library/jest-dom": "^7.0.1",
81
81
  "@testing-library/react": "^16.3.3",
82
82
  "@types/node": "^22.10.0",
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- (function(){"use strict";function k(t){return t>=.95?"Perfect":t>=.8?"Great":t>=.6?"Good":t>=.4?"OK":t>=.2?"Bad":"Awful"}function O(t){return t>=50?3:t>=30?2.5:t>=20?2:t>=10?1.5:1}function V(t,s,n){const{semitoneTolerance:c,preWindow:a,postExtra:l}=n,S=n.segMs??.25,G=typeof n.completionBonusFactor=="number"?n.completionBonusFactor:.15,H=typeof n.goldFullBonusFactor=="number"?n.goldFullBonusFactor:.3,N=typeof n.difficultyMult=="number"?n.difficultyMult:1,v=!!n.disableGoldNotes;let B=0,z=0,A=0;const W=[];let u=0,E=0,T=0;const x=new Map;t.forEach((o,h)=>{const d=o.startTime,Q=o.startTime+o.duration,U=d-a,X=Q+l,K=s.filter(e=>e.t>=U&&e.t<=X&&e.hz>0);if(!K||K.length===0)return;const m=Math.max(1,Math.ceil((o.duration||.25)/S)),Y=Math.max(10,Math.round(100*(o.duration||1))),Z=Math.max(1,Math.round(Y/m));let F=0;const y=[];for(let e=0;e<m;e++){const M=d+e*(o.duration/m),p=d+(e+1)*(o.duration/m),R=Math.min(.06,o.duration/m*.2),f=M-R,g=p+R,r=s.filter(i=>i.t>=f&&i.t<=g&&i.hz>0);if(!r||r.length===0)continue;let L=0;r.forEach(i=>{const ot=12*Math.log2(i.hz/440)+69,nt=Math.abs(ot-o.pitch);L+=nt});const $=L/r.length;let b=0;if(c<=0)b=$===0?1:0;else{const i=c*2;b=Math.max(0,1-Math.min($/i,1))}if(b<=0)continue;const tt=!v&&o.isGold?2:1,w=Math.round(Z*tt*b);w>0&&(B+=w,F+=w,y.push({segIndex:e,frac:b,add:w,segStart:f,segEnd:g,visualStart:M,visualEnd:p}))}const P=o.line??0;x.has(P)||x.set(P,{total:0,hit:0,comboBonus:0});const C=x.get(P);if(C.total++,F>0){u++,u>E&&(E=u),C.hit++;const e=O(u),M=e>1?Math.round(F*(e-1)):0;T+=M,C.comboBonus+=M;const p=Math.max(1,Math.ceil((o.duration||.25)/S)),f=y.length>=p,g=f?Math.round(Math.max(10,Math.round(100*(o.duration||1)))*G*(!v&&o.isGold?1.5:1)*N):0,r=f&&!v&&o.isGold?Math.round(Math.max(10,Math.round(100*(o.duration||1)))*H*N):0;z+=g,A+=r,W.push({noteKey:`${o.line??0}-${o.idx??0}`,segments:y,totalAdded:F,completed:f,completionBonus:g,goldFullBonus:r})}else u=0});const D=[];for(const[o,h]of x.entries()){const d=h.total>0?h.hit/h.total:0;D.push({verseIndex:o,hitFraction:d,label:k(d),comboBonus:h.comboBonus})}const J={maxCombo:E,currentCombo:u,totalComboBonus:T},I=T+z+A;return{classicScore:B,bonusScore:I,totalScore:B+I,total:B,perNote:W,combo:J,verseRatings:D}}function _(t,s){let n=0;for(const c of t){const a=Math.max(10,Math.round(100*(c.duration||1))),l=!s&&c.isGold?2:1;n+=a*l}return n}function j(t,s){return s<=0?0:Math.min(1e4,Math.round(t/s*1e4))}function q(t,s,n){const c=_(s,n);if(c<=0)return{...t,classicScore:0,bonusScore:0,totalScore:0,total:0};const a=j(t.classicScore,c),l=Math.round(t.bonusScore/c*1e4);return{...t,classicScore:a,bonusScore:l,totalScore:a+l,total:a}}self.onmessage=t=>{const{id:s,notes:n,points:c,params:a}=t.data,l=V(n,c,a),S=q(l,n,a.disableGoldNotes),G={id:s,result:S};self.postMessage(G)}})();
@@ -1,5 +0,0 @@
1
- export * from './audioColors';
2
- export * from './debugKaraoke';
3
- export * from './karaokeScoringConfig';
4
- export * from './playerColors';
5
- export * from './ui';
@@ -1,2 +0,0 @@
1
- export declare const THEME_KEY = "nice2dev_theme";
2
- export declare const gripStyle: React.CSSProperties;
@@ -1,8 +0,0 @@
1
- import { default as React } from 'react';
2
- import { AudioClip } from '../models/modelsEditor';
3
- interface Props {
4
- clip: AudioClip;
5
- onSelect?: (clip: AudioClip) => void;
6
- }
7
- declare const _default: React.NamedExoticComponent<Props>;
8
- export default _default;
@@ -1,6 +0,0 @@
1
- import { default as React } from 'react';
2
- declare const _default: React.NamedExoticComponent<{
3
- file: File;
4
- duration?: number;
5
- }>;
6
- export default _default;
@@ -1,19 +0,0 @@
1
- import { default as React } from 'react';
2
- import { MidiNote } from '../models/editor/midiTypes';
3
- import { CCLaneEvent } from './CCLane';
4
- interface AudioEditorPianoRollProps {
5
- notes: MidiNote[];
6
- onAddNote: (pitch: number, start: number, duration: number) => void;
7
- onRemoveNote: (noteId: number) => void;
8
- selectedNoteId?: number | null;
9
- setSelectedNoteId?: (id: number | null) => void;
10
- duration?: number;
11
- zoom?: number;
12
- ccEvents?: CCLaneEvent[];
13
- onAddCCEvent?: (cc: number, value: number, time: number) => void;
14
- onUpdateCCEvent?: (id: number, value: number, time: number, handleType?: 'linear' | 'step' | 'exp') => void;
15
- onRemoveCCEvent?: (id: number) => void;
16
- ccType?: number;
17
- }
18
- declare const AudioEditorPianoRoll: React.FC<AudioEditorPianoRollProps>;
19
- export default AudioEditorPianoRoll;
@@ -1,19 +0,0 @@
1
- import { default as React } from 'react';
2
- import { MidiNote } from '../models/editor/midiTypes';
3
- import { CCLaneEvent } from './CCLane';
4
- interface AudioEditorPianoRollContainerProps {
5
- notes: MidiNote[];
6
- onAddNote: (pitch: number, start: number, duration: number) => void;
7
- onRemoveNote: (noteId: number) => void;
8
- selectedNoteId?: number | null;
9
- setSelectedNoteId?: (id: number | null) => void;
10
- duration?: number;
11
- zoom?: number;
12
- ccEvents?: CCLaneEvent[];
13
- onAddCCEvent?: (cc: number, value: number, time: number) => void;
14
- onUpdateCCEvent?: (id: number, value: number, time: number, handleType?: 'linear' | 'step' | 'exp') => void;
15
- onRemoveCCEvent?: (id: number) => void;
16
- ccType?: number;
17
- }
18
- declare const AudioEditorPianoRollContainer: React.FC<AudioEditorPianoRollContainerProps>;
19
- export default AudioEditorPianoRollContainer;
@@ -1,9 +0,0 @@
1
- import { default as React } from 'react';
2
- import { AudioLayer } from '../models/modelsEditor';
3
- interface Props {
4
- layer: AudioLayer;
5
- onLayerChange: (layer: AudioLayer) => void;
6
- onSave?: (layer: AudioLayer) => void;
7
- }
8
- declare const AudioLayerDetailsComponent: React.FC<Props>;
9
- export default AudioLayerDetailsComponent;
@@ -1,9 +0,0 @@
1
- import { default as React } from 'react';
2
- import { AudioLayer } from '../models/modelsEditor';
3
- interface AudioLayerDetailsContainerProps {
4
- layer: AudioLayer;
5
- onLayerChange: (layer: AudioLayer) => void;
6
- onSave?: (layer: AudioLayer) => void;
7
- }
8
- declare const AudioLayerDetailsContainer: React.FC<AudioLayerDetailsContainerProps>;
9
- export default AudioLayerDetailsContainer;
@@ -1,8 +0,0 @@
1
- import { default as React } from 'react';
2
- interface AudioLayersNavContainerProps {
3
- onAddLayer: () => void;
4
- onLoadPreset: () => void;
5
- onSavePreset: () => void;
6
- }
7
- declare const AudioLayersNavContainer: React.FC<AudioLayersNavContainerProps>;
8
- export default AudioLayersNavContainer;
@@ -1,10 +0,0 @@
1
- import { default as React } from 'react';
2
- import { WaveformData } from '../engine/audioTimeline';
3
- interface AudioMiniMapProps {
4
- duration: number;
5
- currentTime: number;
6
- bpm: number;
7
- waveform: WaveformData;
8
- }
9
- declare const _default: React.NamedExoticComponent<AudioMiniMapProps>;
10
- export default _default;
@@ -1,9 +0,0 @@
1
- import { default as React } from 'react';
2
- interface AudioMiniMapContainerProps {
3
- duration: number;
4
- currentTime: number;
5
- bpm: number;
6
- waveform: number[];
7
- }
8
- declare const AudioMiniMapContainer: React.FC<AudioMiniMapContainerProps>;
9
- export default AudioMiniMapContainer;
@@ -1,11 +0,0 @@
1
- import { default as React } from 'react';
2
- import { AudioSourceType } from '../engine/audioSource';
3
- type Params = Record<string, unknown>;
4
- interface Props {
5
- selectedSource?: string;
6
- params: Params;
7
- onSelectSource: (source: AudioSourceType, defaultParams?: Params) => void;
8
- onParamsChange: (next: Params) => void;
9
- }
10
- declare const AudioSourceDetailsComponent: React.FC<Props>;
11
- export default AudioSourceDetailsComponent;
@@ -1,17 +0,0 @@
1
- import { default as React } from 'react';
2
- interface AudioTimelineContainerProps {
3
- zoom: number;
4
- duration: number;
5
- isPlaying: boolean;
6
- isRecording: boolean;
7
- currentTime: number;
8
- bpm: number;
9
- snapEnabled: boolean;
10
- snapMode: 'beat' | 'bar' | 'second' | 'sub-beat';
11
- waveform: number[];
12
- waveformColor: string;
13
- onCurrentTimeChange: (value: number) => void;
14
- onZoomChange: (value: number) => void;
15
- }
16
- declare const AudioTimelineContainer: React.FC<AudioTimelineContainerProps>;
17
- export default AudioTimelineContainer;
@@ -1,13 +0,0 @@
1
- import { default as React } from 'react';
2
- interface AudioTimelineNavContainerProps {
3
- isPlaying: boolean;
4
- isLooping: boolean;
5
- currentTime: number;
6
- duration: number;
7
- onPlayPause: () => void;
8
- onRecord: () => void;
9
- onLoop: () => void;
10
- onAdjustDuration: (amount: number) => void;
11
- }
12
- declare const AudioTimelineNavContainer: React.FC<AudioTimelineNavContainerProps>;
13
- export default AudioTimelineNavContainer;
@@ -1,13 +0,0 @@
1
- import { default as React } from 'react';
2
- export interface CCLaneEvent {
3
- id: number;
4
- cc: number;
5
- value: number;
6
- time: number;
7
- }
8
- interface CCLaneSelectorProps {
9
- ccType: number;
10
- onChange: (cc: number) => void;
11
- }
12
- declare const _default: React.NamedExoticComponent<CCLaneSelectorProps>;
13
- export default _default;
@@ -1,36 +0,0 @@
1
- /**
2
- * AudioEditor display modes — progressive complexity levels.
3
- *
4
- * Fun – Minimal playback & layers (explore mode)
5
- * Beginner – Adds auto-save, undo/redo, zoom/snap
6
- * Mid – Adds recording, clip editing, project settings
7
- * Expert – Adds Master FX, effects chain, MIDI
8
- * Master – Everything visible (full DAW mode)
9
- */
10
- export type EditorDisplayMode = 'fun' | 'beginner' | 'mid' | 'expert' | 'master';
11
- export interface DisplayModeConfig {
12
- label: string;
13
- description: string;
14
- /** Sidebar panel visibility flags */
15
- showAutoSave: boolean;
16
- showUndoRedo: boolean;
17
- showSaveLoad: boolean;
18
- showProjectSettings: boolean;
19
- showSectionSettings: boolean;
20
- showZoomSnap: boolean;
21
- showMasterFX: boolean;
22
- showAdvancedEditing: boolean;
23
- showRecordingOptions: boolean;
24
- showClipOperations: boolean;
25
- showMiniMap: boolean;
26
- showLayerEffects: boolean;
27
- showMidiPianoRoll: boolean;
28
- showTemplateButtons: boolean;
29
- showImportExport: boolean;
30
- showLayerDragReorder: boolean;
31
- showMidiAutomation: boolean;
32
- }
33
- export declare const DISPLAY_MODES: Record<EditorDisplayMode, DisplayModeConfig>;
34
- export declare const DISPLAY_MODE_ORDER: EditorDisplayMode[];
35
- export declare function loadDisplayMode(): EditorDisplayMode;
36
- export declare function saveDisplayMode(mode: EditorDisplayMode): void;
@@ -1,10 +0,0 @@
1
- import { ChangeEvent, Dispatch, SetStateAction } from 'react';
2
- import { NiceTranslateFn } from '../core/i18n';
3
- import { AudioProject } from '../models/modelsEditor';
4
- type StatusSetter = Dispatch<SetStateAction<string>>;
5
- type StatusTypeSetter = Dispatch<SetStateAction<'success' | 'error' | ''>>;
6
- export declare function exportProject(project: AudioProject | null, projectName: string): void;
7
- export declare function importProject(e: ChangeEvent<HTMLInputElement>, project: AudioProject | null, setUndoStack: Dispatch<SetStateAction<AudioProject[]>>, setRedoStack: Dispatch<SetStateAction<AudioProject[]>>, setProject: Dispatch<SetStateAction<AudioProject | null>>, setStatusMessage: StatusSetter, setStatusType: StatusTypeSetter, t: NiceTranslateFn): void;
8
- export declare function saveTemplate(project: AudioProject | null, setStatusMessage: StatusSetter, setStatusType: StatusTypeSetter, t: NiceTranslateFn): void;
9
- export declare function loadTemplate(project: AudioProject | null, setUndoStack: Dispatch<SetStateAction<AudioProject[]>>, setRedoStack: Dispatch<SetStateAction<AudioProject[]>>, setProject: Dispatch<SetStateAction<AudioProject | null>>, setStatusMessage: StatusSetter, setStatusType: StatusTypeSetter, t: NiceTranslateFn): void;
10
- export {};
@@ -1,8 +0,0 @@
1
- import { default as React } from 'react';
2
- interface Props {
3
- onAddLayer: () => void;
4
- onLoadPreset: () => void;
5
- onSavePreset: () => void;
6
- }
7
- declare const _default: React.NamedExoticComponent<Props>;
8
- export default _default;
@@ -1,11 +0,0 @@
1
- import { default as React } from 'react';
2
- import { AudioProject, AudioSection } from '../../models/modelsEditor';
3
- interface AudioProjectSectionNavProps {
4
- activeProject: AudioProject;
5
- activeSection: AudioSection | null;
6
- onSelectSection: (section: AudioSection) => void;
7
- onAddSection: () => void;
8
- onDeleteSection?: (sectionId: number) => void;
9
- }
10
- declare const AudioProjectSectionNav: React.FC<AudioProjectSectionNavProps>;
11
- export default AudioProjectSectionNav;
@@ -1,13 +0,0 @@
1
- import { default as React } from 'react';
2
- interface AudioTimelineNavProps {
3
- isPlaying: boolean;
4
- isLooping: boolean;
5
- currentTime: number;
6
- duration: number;
7
- onPlayPause: () => void;
8
- onRecord: () => void;
9
- onLoop: () => void;
10
- onAdjustDuration: (amount: number) => void;
11
- }
12
- declare const AudioTimelineNav: React.FC<AudioTimelineNavProps>;
13
- export default AudioTimelineNav;
@@ -1,8 +0,0 @@
1
- import { default as React } from 'react';
2
- import { AudioProject } from '../../models/modelsEditor';
3
- interface SaveLoadControlsProps {
4
- project: AudioProject | null;
5
- onLoadProject: (project: AudioProject) => void;
6
- }
7
- declare const _default: React.NamedExoticComponent<SaveLoadControlsProps>;
8
- export default _default;
@@ -1,29 +0,0 @@
1
- import { default as React } from 'react';
2
- import { ClipRegion, ClipId } from '../../models/editor/audioTypes';
3
- interface AdvancedEditingPanelProps {
4
- selectedClips: Set<string>;
5
- clearSelection: () => void;
6
- rippleMode: boolean;
7
- setRippleMode: (v: boolean) => void;
8
- quantizeSelectedClips: () => void;
9
- deleteSelectedClips: () => void;
10
- applyTimeStretch: (factor: number) => void;
11
- }
12
- export declare const AdvancedEditingPanel: React.FC<AdvancedEditingPanelProps>;
13
- interface ClipOperationsPanelProps {
14
- selectedClip: {
15
- layerId: number;
16
- clipId: ClipId;
17
- } | null;
18
- clipboardClip: ClipRegion | null;
19
- activeLayerId: number | undefined;
20
- layerClips: Record<number, ClipRegion[]>;
21
- handleSplitClip: () => void;
22
- handleDeleteClip: () => void;
23
- handleCopyClip: () => void;
24
- handlePasteClip: () => void;
25
- handleToggleReverse: () => void;
26
- handleFadeChange: (type: 'in' | 'out', value: number) => void;
27
- }
28
- export declare const ClipOperationsPanel: React.FC<ClipOperationsPanelProps>;
29
- export {};