PageSourceSearch

https://www.hamienet.com/assets/SouthparkStageDesigner-D3wJTqgo.js

js hamienet.com collected 2026-09-24 19:00:53 UTC 144,369 bytes, 2,482 lines download raw bytes

1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js";
2import { a as defaultBackgroundPresets, d as defaultBackgroundConfig, B as BackgroundParticlesCanvas } from "./StagePuppetEngine-BtPqoUG7.js";
3import { B as BASE_ANIMALS, g as getInstrumentDef, S as SouthparkCharacter } from "./SouthparkCharacter-BNwA9Wd0.js";
4import { d as defaultSouthparkStageConfig, g as getSouthparkStageAlignment, c as calculateEnsemblePlacement, r as resolveLightingProfile, S as SouthparkStageBanner, a as SouthparkStageLighting } from "./SouthparkStageBanner-BCxT9awg.js";
5import { bi as Sparkles, c3 as RotateCcw, c1 as Copy, bo as Monitor, bZ as Pause, bU as Play, bA as Eye, bz as EyeOff, bO as Compass, cj as Layers, f_ as Lightbulb, c6 as Shuffle, dK as Move, cB as ChevronDown, bE as ChevronRight, dN as Users, d7 as Image, bf as Search, b2 as Upload, b7 as Check, b5 as Trash2, df as SlidersVertical, bF as CircleQuestionMark } from "./vendor-dVNaLJx_.js";
6import "./synth-BE1TSTD4.js";
7import "./vendor-react-three-MDLA5jog.js";
8import "./wasm-synth-adapter-BrqgBX1y.js";
9import "./vendor-spessasynth-DH8n6o_V.js";
10import "./vendor-audio-DH3w0BzW.js";
11import "./IkMath-D6fi1ppd.js";
12import "./vendor-gsap-50Lx19ak.js";
13import "./vendor-framer-C8eEgkdL.js";
14import "./vendor-i18n-R-bMoYp_.js";
15const PARTICLE_OPTIONS = [
16  { id: "stars", label: "Twinkling Stars", icon: "🌟" },
17  { id: "notes", label: "Musical Notes", icon: "🎵" },
18  { id: "snow", label: "Falling Snow", icon: "❄️" },
19  { id: "bubbles", label: "Floating Bubbles", icon: "🫧" },
20  { id: "rain", label: "Raindrops", icon: "🌧️" },
21  { id: "confetti", label: "Celebration Confetti", icon: "🎊" },
22  { id: "fireflies", label: "Glowing Fireflies", icon: "✨" },
23  { id: "hearts", label: "Floating Hearts", icon: "💖" },
24  { id: "autumn_leaves", label: "Autumn Leaves", icon: "🍂" },
25  { id: "matrix", label: "Matrix Code Rain", icon: "💻" },
26  { id: "dust", label: "Atmospheric Dust", icon: "🌫️" },
27  { id: "sparkles", label: "Glittering Sparkles", icon: "✨" },
28  { id: "floating_orbs", label: "Floating Orbs", icon: "🔮" },
29  { id: "laser_lines", label: "Laser Lines", icon: "⚡" }
30];
31const POPULAR_SIMULATION_GENRES = [
32  { label: "Anime & Animation", tag: "anime" },
33  { label: "Classical & Orchestral", tag: "classical" },
34  { label: "Rock & Metal", tag: "rock" },
35  { label: "Jazz & Blues", tag: "jazz" },
36  { label: "Game Music & Chiptune", tag: "game music" },
37  { label: "Hip Hop & Rap", tag: "hip hop" },
38  { label: "EDM & Techno", tag: "techno" },
39  { label: "Folk & Acoustic", tag: "folk" },
40  { label: "Latin & Salsa", tag: "latin" },
41  { label: "Pop & Dance", tag: "pop" },
42  { label: "Country & Western", tag: "country" },
43  { label: "Synth & Sci-Fi", tag: "electronic" }
44];
45const DEFAULT_STAGE_IMAGE = {
46  url: "",
47  size: "cover",
48  position: "center center",
49  repeat: "no-repeat",
50  blur: 0
51};
52const DEFAULT_STAGE_OVERLAY = {
53  enabled: true,
54  color: "#000000",
55  opacity: 0.15
56};
57const DEFAULT_STAGE_PARTICLES = {
58  enabled: false,
59  type: "stars",
60  count: 50,
61  speed: 1,
62  color: "#ffffff",
63  size: 2
64};
65const SAMPLE_ENSEMBLE_POOL = [
66  // 1 to 5: Quintet (Rhythm + Melodic Core)
67  { id: "fox_gtr", animalId: "fox", program: 25, isPercussion: false, familyIndex: 3, tier: "Front · Acoustic Guitar" },
68  { id: "bear_drums", animalId: "bear", program: 0, isPercussion: true, familyIndex: -1, percRole: "drums", tier: "Back · Drum Kit" },
69  { id: "wolf_cello", animalId: "wolf", program: 42, isPercussion: false, familyIndex: 5, tier: "Middle · Cello" },
70  { id: "lion_trpt", animalId: "lion", program: 56, isPercussion: false, familyIndex: 7, tier: "Middle · Trumpet" },
71  { id: "rabbit_vln", animalId: "rabbit", program: 40, isPercussion: false, familyIndex: 5, tier: "Front · Violin" },
72  // 6 to 8: Chamber Octet
73  { id: "hamster_pno", animalId: "hamster", program: 0, isPercussion: false, familyIndex: 0, tier: "Back · Grand Piano" },
74  { id: "wolf_bass", animalId: "wolf", program: 33, isPercussion: false, familyIndex: 4, tier: "Front · Electric Bass" },
75  { id: "owl_flute", animalId: "owl", program: 73, isPercussion: false, familyIndex: 9, tier: "Middle · Flute" },
76  // 9 to 12: Big Band
77  { id: "badger_sax", animalId: "badger", program: 65, isPercussion: false, familyIndex: 8, tier: "Middle · Alto Sax" },
78  { id: "penguin_syn", animalId: "penguin", program: 81, isPercussion: false, familyIndex: 10, tier: "Back · Synth Lead" },
79  { id: "deer_egtr", animalId: "deer", program: 29, isPercussion: false, familyIndex: 3, tier: "Front · Overdrive Guitar" },
80  { id: "lion_tbne", animalId: "lion", program: 57, isPercussion: false, familyIndex: 7, tier: "Middle · Trombone" },
81  // 13 to 18: Concert Orchestra
82  { id: "otter_harp", animalId: "otter", program: 46, isPercussion: false, familyIndex: 5, tier: "Middle · Concert Harp" },
83  { id: "gorilla_conga", animalId: "gorilla", program: 0, isPercussion: true, familyIndex: -1, percRole: "congas", tier: "Back · Congas" },
84  { id: "raccoon_tamb", animalId: "raccoon", program: 0, isPercussion: true, familyIndex: -1, percRole: "tambourine", tier: "Back · Tambourine" },
85  { id: "llama_pan", animalId: "llama", program: 75, isPercussion: false, familyIndex: 9, tier: "Middle · Pan Flute" },
86  { id: "koala_pad", animalId: "koala", program: 88, isPercussion: false, familyIndex: 11, tier: "Back · Warm Pad" },
87  { id: "fox_solo", animalId: "fox", program: 27, isPercussion: false, familyIndex: 3, tier: "Front · Electric Solo" },
88  // 19 to 24: Grand Symphony
89  { id: "bat_fx", animalId: "bat", program: 98, isPercussion: false, familyIndex: 12, tier: "Back · Crystal FX" },
90  { id: "parrot_horn", animalId: "parrot", program: 60, isPercussion: false, familyIndex: 7, tier: "Middle · French Horn" },
91  { id: "rabbit_viola", animalId: "rabbit", program: 41, isPercussion: false, familyIndex: 5, tier: "Front · Viola" },
92  { id: "deer_tuba", animalId: "deer", program: 58, isPercussion: false, familyIndex: 7, tier: "Middle · Tuba" },
93  { id: "bear_timp", animalId: "bear", program: 47, isPercussion: false, familyIndex: 1, tier: "Back · Timpani" },
94  { id: "badger_clari", animalId: "badger", program: 71, isPercussion: false, familyIndex: 8, tier: "Middle · Clarinet" }
95];
96const SouthparkStageDesigner = ({
97  stageConfig,
98  setStageConfig,
99  spBackgroundConfig,
100  setSpBackgroundConfig,
101  spBackgroundPresets,
102  setSpBackgroundPresets,
103  sharedBackgroundConfig,
104  sharedBackgroundPresets,
105  customBackgrounds,
106  setCustomBackgrounds,
107  charactersConfig,
108  costumesConfig
109}) => {
110  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V;
111  const [selectedPresetId, setSelectedPresetId] = reactExports.useState(null);
112  const [shufflePreviewIndex, setShufflePreviewIndex] = reactExports.useState(0);
113  const [galleryFilter, setGalleryFilter] = reactExports.useState("all");
114  const [searchQuery, setSearchQuery] = reactExports.useState("");
115  const [isParticlesPlaying, setIsParticlesPlaying] = reactExports.useState(true);
116  const [showSampleMusicians, setShowSampleMusicians] = reactExports.useState(true);
117  const [sampleMusicianCount, setSampleMusicianCount] = reactExports.useState(5);
118  const [enableDensityScaling, setEnableDensityScaling] = reactExports.useState(true);
119  const [showArcGuides, setShowArcGuides] = reactExports.useState(false);
120  const [showDepthGuides, setShowDepthGuides] = reactExports.useState(false);
121  const [previewPhysics, setPreviewPhysics] = reactExports.useState("snappy");
122  const [previewLighting, setPreviewLighting] = reactExports.useState("dynamic");
123  const [isDraggingStage, setIsDraggingStage] = reactExports.useState(false);
124  const dragStartRef = reactExports.useRef(null);
125  const [activeDepthDrag, setActiveDepthDrag] = reactExports.useState(null);
126  const svgViewportRef = reactExports.useRef(null);
127  const [openSections, setOpenSections] = reactExports.useState({
128    depth: true,
129    // 3D Depth & Perspective - expanded by default
130    camera: true,
131    // Stage Camera & Pan/Zoom - expanded by default
132    geometry: false,
133    // Musicians & Seating Geometry
134    atmosphere: false
135    // Stage Lighting & Atmosphere
136  });
137  const toggleSection = (key) => {
138    setOpenSections((prev) => ({ ...prev, [key]: !prev[key] }));
139  };
140  const [simulationTagInput, setSimulationTagInput] = reactExports.useState("classical");
141  const [uploadError, setUploadError] = reactExports.useState(null);
142  const [isUploading, setIsUploading] = reactExports.useState(false);
143  const fileInputRef = reactExports.useRef(null);
144  const mergedPresets = reactExports.useMemo(() => {
145    const basePool = defaultBackgroundPresets.filter((p) => {
146      var _a2, _b2, _c2;
147      return !((_c2 = (_b2 = (_a2 = p.config) == null ? void 0 : _a2.image) == null ? void 0 : _b2.url) == null ? void 0 : _c2.includes("background-forest"));
148    });
149    return basePool.map((base) => {
150      const spOverride = spBackgroundPresets.find((p) => p.id === base.id);
151      return {
152        id: base.id,
153        name: spOverride ? spOverride.name : base.name,
154        tags: spOverride ? spOverride.tags : base.tags,
155        config: spOverride ? spOverride.config : base.config,
156        isSpOverride: !!spOverride
157      };
158    });
159  }, [spBackgroundPresets]);
160  const activeConfig = reactExports.useMemo(() => {
161    if (selectedPresetId === null) {
162      if (mergedPresets.length > 0) {
163        const previewPreset = mergedPresets[shufflePreviewIndex % mergedPresets.length];
164        return (previewPreset == null ? void 0 : previewPreset.config) || defaultSouthparkStageConfig;
165      }
166      return defaultSouthparkStageConfig;
167    }
168    const preset = mergedPresets.find((p) => p.id === selectedPresetId);
169    return (preset == null ? void 0 : preset.config) || defaultSouthparkStageConfig;
170  }, [selectedPresetId, mergedPresets, shufflePreviewIndex]);
171  const isCurrentSelectedSpOverride = reactExports.useMemo(() => {
172    var _a2;
173    if (selectedPresetId === null) {
174      const targetId = (_a2 = mergedPresets[shufflePreviewIndex % mergedPresets.length]) == null ? void 0 : _a2.id;
175      return targetId ? spBackgroundPresets.some((p) => p.id === targetId) : false;
176    }
177    return spBackgroundPresets.some((p) => p.id === selectedPresetId);
178  }, [selectedPresetId, spBackgroundPresets, mergedPresets, shufflePreviewIndex]);
179  const activePresetMeta = reactExports.useMemo(() => {
180    if (selectedPresetId === null) {
181      const previewPreset = mergedPresets[shufflePreviewIndex % mergedPresets.length];
182      return {
183        id: "__random__",
184        name: `Dynamic Stage Shuffle (${(previewPreset == null ? void 0 : previewPreset.name) || "Random Stage"})`,
185        tags: ["(Untagged songs randomly select from all active stage presets)"],
186        isSpOverride: false
187      };
188    }
189    return mergedPresets.find((p) => p.id === selectedPresetId) || {
190      id: selectedPresetId,
191      name: "Custom Preset",
192      tags: [],
193      isSpOverride: isCurrentSelectedSpOverride
194    };
195  }, [selectedPresetId, mergedPresets, isCurrentSelectedSpOverride, shufflePreviewIndex]);
196  const updateActiveConfig = (updater) => {
197    var _a2;
198    const targetId = selectedPresetId === null ? (_a2 = mergedPresets[shufflePreviewIndex % mergedPresets.length]) == null ? void 0 : _a2.id : selectedPresetId;
199    if (!targetId) return;
200    setSpBackgroundPresets((prevPresets) => {
201      var _a3;
202      const existingIdx = prevPresets.findIndex((p) => p.id === targetId);
203      const basePreset = defaultBackgroundPresets.find((p) => p.id === targetId);
204      const currentConf = existingIdx >= 0 && ((_a3 = prevPresets[existingIdx]) == null ? void 0 : _a3.config) ? prevPresets[existingIdx].config : (basePreset == null ? void 0 : basePreset.config) || defaultSouthparkStageConfig;
205      const newConf = updater(currentConf);
206      if (existingIdx >= 0) {
207        const next = [...prevPresets];
208        next[existingIdx] = { ...next[existingIdx], config: newConf };
209        return next;
210      } else {
211        return [
212          ...prevPresets,
213          {
214            id: targetId,
215            name: (basePreset == null ? void 0 : basePreset.name) || "Custom Preset",
216            tags: (basePreset == null ? void 0 : basePreset.tags) || [],
217            config: newConf
218          }
219        ];
220      }
221    });
222  };
223  const updatePresetMeta = (name, tags) => {
224    var _a2;
225    const targetId = selectedPresetId === null ? (_a2 = mergedPresets[shufflePreviewIndex % mergedPresets.length]) == null ? void 0 : _a2.id : selectedPresetId;
226    if (!targetId) return;
227    setSpBackgroundPresets((prevPresets) => {
228      const existingIdx = prevPresets.findIndex((p) => p.id === targetId);
229      const currentPreset = mergedPresets.find((p) => p.id === targetId);
230      const baseName = name !== void 0 ? name : (currentPreset == null ? void 0 : currentPreset.name) || "Preset";
231      const baseTags = tags !== void 0 ? tags : (currentPreset == null ? void 0 : currentPreset.tags) || [];
232      const baseConf = (currentPreset == null ? void 0 : currentPreset.config) || defaultBackgroundConfig;
233      if (existingIdx >= 0) {
234        const next = [...prevPresets];
235        next[existingIdx] = {
236          ...next[existingIdx],
237          name: baseName,
238          tags: baseTags
239        };
240        return next;
241      } else {
242        return [
243          ...prevPresets,
244          {
245            id: targetId,
246            name: baseName,
247            tags: baseTags,
248            config: baseConf
249          }
250        ];
251      }
252    });
253  };
254  const handleRevertToShared = () => {
255    var _a2;
256    const targetId = selectedPresetId === null ? (_a2 = mergedPresets[shufflePreviewIndex % mergedPresets.length]) == null ? void 0 : _a2.id : selectedPresetId;
257    if (targetId) {
258      setSpBackgroundPresets((prev) => prev.filter((p) => p.id !== targetId));
259    }
260  };
261  const handleUploadBackground = async (e) => {
262    var _a2;
263    const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
264    if (!file) return;
265    setIsUploading(true);
266    setUploadError(null);
267    const formData = new FormData();
268    formData.append("background", file);
269    try {
270      const res = await fetch("/api/admin/upload-global-background", {
271        method: "POST",
272        headers: { "Authorization": "Bearer " + localStorage.getItem("admin_token") },
273        body: formData
274      });
275      if (!res.ok) {
276        const errData = await res.json();
277        throw new Error(errData.error || "Upload failed");
278      }
279      const data = await res.json();
280      setCustomBackgrounds((prev) => [...prev, data.url]);
281      updateActiveConfig((prev) => ({
282        ...prev,
283        type: "image",
284        image: {
285          ...prev.image || DEFAULT_STAGE_IMAGE,
286          url: data.url
287        }
288      }));
289    } catch (err) {
290      setUploadError(err.message || "Failed to upload background");
291    } finally {
292      setIsUploading(false);
293      if (fileInputRef.current) fileInputRef.current.value = "";
294    }
295  };
296  const handleDeleteCustomBackground = async (bgUrl) => {
297    if (!confirm("Are you sure you want to delete this custom background from the gallery?")) return;
298    const filename = bgUrl.split("/").pop();
299    if (!filename) return;
300    try {
301      const res = await fetch(`/api/admin/backgrounds/${filename}`, {
302        method: "DELETE",
303        headers: { "Authorization": "Bearer " + localStorage.getItem("admin_token") }
304      });
305      if (!res.ok) {
306        const err = await res.json();
307        throw new Error(err.error || "Delete failed");
308      }
309      setCustomBackgrounds((prev) => prev.filter((url) => url !== bgUrl));
310    } catch (err) {
311      alert(err.message || "Failed to delete");
312    }
313  };
314  const simulationResult = reactExports.useMemo(() => {
315    const query = simulationTagInput.toLowerCase().trim();
316    if (!query) return null;
317    const spMatch = spBackgroundPresets.find(
318      (p) => p.tags && p.tags.some((t) => t.toLowerCase().includes(query) || query.includes(t.toLowerCase()))
319    );
320    if (spMatch) {
321      return {
322        presetId: spMatch.id,
323        presetName: spMatch.name,
324        reason: `Direct South Park Tag Match on "${query}"`,
325        isSp: true,
326        config: spMatch.config
327      };
328    }
329    const sharedPool = sharedBackgroundPresets && sharedBackgroundPresets.length > 0 ? sharedBackgroundPresets : defaultBackgroundPresets;
330    const sharedMatch = sharedPool.find(
331      (p) => p.tags && p.tags.some((t) => t.toLowerCase().includes(query) || query.includes(t.toLowerCase()))
332    );
333    if (sharedMatch) {
334      return {
335        presetId: sharedMatch.id,
336        presetName: sharedMatch.name,
337        reason: `Shared Orchestra Tag Match on "${query}"`,
338        isSp: false,
339        config: sharedMatch.config
340      };
341    }
342    let hash = 0;
343    for (let i = 0; i < query.length; i++) {
344      hash = query.charCodeAt(i) + ((hash << 5) - hash);
345    }
346    const fallbackIdx = Math.abs(hash) % sharedPool.length;
347    const fallbackPreset = sharedPool[fallbackIdx];
348    return {
349      presetId: (fallbackPreset == null ? void 0 : fallbackPreset.id) || "classical",
350      presetName: (fallbackPreset == null ? void 0 : fallbackPreset.name) || "Default",
351      reason: `Dynamic Stage Pool Fallback (unmatched songs randomly select across stage pool)`,
352      isSp: false,
353      config: (fallbackPreset == null ? void 0 : fallbackPreset.config) || defaultBackgroundConfig
354    };
355  }, [simulationTagInput, spBackgroundPresets, sharedBackgroundPresets]);
356  const stageBackgroundStyle = reactExports.useMemo(() => {
357    var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2;
358    const bg = activeConfig;
359    if (!bg) return { backgroundColor: "#0c0c14" };
360    if (bg.type === "color") {
361      return { backgroundColor: bg.color || "#0c0c14" };
362    } else if (bg.type === "gradient" && ((_a2 = bg.gradient) == null ? void 0 : _a2.stops)) {
363      const { type, angle, stops } = bg.gradient;
364      const stopStr = stops.map((s) => `${s.color} ${s.offset}%`).join(", ");
365      return {
366        background: type === "radial" ? `radial-gradient(circle, ${stopStr})` : `linear-gradient(${angle ?? 180}deg, ${stopStr})`
367      };
368    } else {
369      const stageCalib = getSouthparkStageAlignment((_b2 = bg.image) == null ? void 0 : _b2.url);
370      const scale = ((_c2 = bg.image) == null ? void 0 : _c2.scale) !== void 0 ? bg.image.scale : stageCalib.scale;
371      const offsetX = ((_d2 = bg.image) == null ? void 0 : _d2.offsetX) !== void 0 ? bg.image.offsetX : stageCalib.offsetX || 0;
372      const offsetY = ((_e2 = bg.image) == null ? void 0 : _e2.offsetY) !== void 0 ? bg.image.offsetY : stageCalib.offsetY;
373      return {
374        backgroundColor: bg.color || "#050505",
375        backgroundImage: ((_f2 = bg.image) == null ? void 0 : _f2.url) ? `url("${bg.image.url}")` : void 0,
376        backgroundSize: ((_g2 = bg.image) == null ? void 0 : _g2.size) || "cover",
377        backgroundPosition: ((_h2 = bg.image) == null ? void 0 : _h2.position) || "center",
378        backgroundRepeat: ((_i2 = bg.image) == null ? void 0 : _i2.repeat) || "no-repeat",
379        filter: ((_j2 = bg.image) == null ? void 0 : _j2.blur) ? `blur(${bg.image.blur}px)` : void 0,
380        transform: `scale(${scale}) translate(${offsetX}%, ${offsetY}%)`,
381        transformOrigin: stageCalib.origin || "50% 50%",
382        transition: isDraggingStage ? "none" : "transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), background-image 0.3s ease"
383      };
384    }
385  }, [activeConfig, isDraggingStage]);
386  const activeStageCalib = reactExports.useMemo(() => {
387    var _a2;
388    return getSouthparkStageAlignment((_a2 = activeConfig.image) == null ? void 0 : _a2.url);
389  }, [(_a = activeConfig.image) == null ? void 0 : _a.url]);
390  const effectiveScale = ((_b = activeConfig.image) == null ? void 0 : _b.scale) !== void 0 ? activeConfig.image.scale : activeStageCalib.scale;
391  const effectiveOffsetX = ((_c = activeConfig.image) == null ? void 0 : _c.offsetX) !== void 0 ? activeConfig.image.offsetX : activeStageCalib.offsetX || 0;
392  const effectiveOffsetY = ((_d = activeConfig.image) == null ? void 0 : _d.offsetY) !== void 0 ? activeConfig.image.offsetY : activeStageCalib.offsetY;
393  const effectiveBackY = ((_e = activeConfig.image) == null ? void 0 : _e.backY) !== void 0 ? activeConfig.image.backY : activeStageCalib.backY;
394  const effectiveFrontY = ((_f = activeConfig.image) == null ? void 0 : _f.frontY) !== void 0 ? activeConfig.image.frontY : activeStageCalib.frontY;
395  const effectiveBackScale = ((_g = activeConfig.image) == null ? void 0 : _g.backScale) !== void 0 ? activeConfig.image.backScale : activeStageCalib.backScale;
396  const effectiveFrontScale = ((_h = activeConfig.image) == null ? void 0 : _h.frontScale) !== void 0 ? activeConfig.image.frontScale : activeStageCalib.frontScale;
397  const effectiveHorizonY = ((_i = activeConfig.image) == null ? void 0 : _i.horizonY) !== void 0 ? activeConfig.image.horizonY : activeStageCalib.horizonY;
398  const DEPTH_PRESETS = [
399    { label: "Dramatic 3D", bScale: 0.52, fScale: 1 },
400    { label: "Natural Amphitheater", bScale: 0.58, fScale: 0.98 },
401    { label: "Subtle Depth", bScale: 0.72, fScale: 0.98 },
402    { label: "Flat", bScale: 0.9, fScale: 1 }
403  ];
404  const applyDepthPreset = (bScale, fScale) => {
405    updateActiveConfig((prev) => ({
406      ...prev,
407      image: {
408        ...prev.image || DEFAULT_STAGE_IMAGE,
409        backScale: bScale,
410        frontScale: fScale
411      }
412    }));
413  };
414  const resetDepthToDefaults = () => {
415    var _a2;
416    const defaultCalib = getSouthparkStageAlignment((_a2 = activeConfig.image) == null ? void 0 : _a2.url);
417    updateActiveConfig((prev) => ({
418      ...prev,
419      image: {
420        ...prev.image || DEFAULT_STAGE_IMAGE,
421        backY: defaultCalib.backY,
422        frontY: defaultCalib.frontY,
423        backScale: defaultCalib.backScale,
424        frontScale: defaultCalib.frontScale,
425        horizonY: defaultCalib.horizonY
426      }
427    }));
428  };
429  const resetStageAlignment = () => {
430    var _a2;
431    const defaultCalib = getSouthparkStageAlignment((_a2 = activeConfig.image) == null ? void 0 : _a2.url);
432    updateActiveConfig((prev) => ({
433      ...prev,
434      image: {
435        ...prev.image || DEFAULT_STAGE_IMAGE,
436        scale: defaultCalib.scale,
437        offsetX: defaultCalib.offsetX || 0,
438        offsetY: defaultCalib.offsetY
439      }
440    }));
441  };
442  const handleDepthLinePointerDown = (type, e) => {
443    e.stopPropagation();
444    try {
445      e.currentTarget.setPointerCapture(e.pointerId);
446    } catch {
447    }
448    setActiveDepthDrag(type);
449  };
450  const handleDepthLinePointerMove = (type, e) => {
451    if (activeDepthDrag !== type) return;
452    e.stopPropagation();
453    if (!svgViewportRef.current) return;
454    const rect = svgViewportRef.current.getBoundingClientRect();
455    if (!rect.height) return;
456    const relativeY = Math.round((e.clientY - rect.top) / rect.height * 650);
457    if (type === "backY") {
458      const minBound = 240;
459      const maxBound = effectiveFrontY - 30;
460      const clamped = Math.max(minBound, Math.min(maxBound, relativeY));
461      updateActiveConfig((prev) => ({
462        ...prev,
463        image: { ...prev.image || DEFAULT_STAGE_IMAGE, backY: clamped }
464      }));
465    } else if (type === "frontY") {
466      const minBound = effectiveBackY + 30;
467      const clamped = Math.max(minBound, Math.min(505, relativeY));
468      updateActiveConfig((prev) => ({
469        ...prev,
470        image: { ...prev.image || DEFAULT_STAGE_IMAGE, frontY: clamped }
471      }));
472    }
473  };
474  const handleDepthLinePointerUp = (e) => {
475    e.stopPropagation();
476    try {
477      e.currentTarget.releasePointerCapture(e.pointerId);
478    } catch {
479    }
480    setActiveDepthDrag(null);
481  };
482  const handleStagePointerDown = (e) => {
483    if (e.button !== 0 || activeDepthDrag) return;
484    const target = e.currentTarget;
485    try {
486      target.setPointerCapture(e.pointerId);
487    } catch {
488    }
489    const rect = target.getBoundingClientRect();
490    dragStartRef.current = {
491      clientX: e.clientX,
492      clientY: e.clientY,
493      startOffsetX: effectiveOffsetX,
494      startOffsetY: effectiveOffsetY,
495      width: rect.width || 1,
496      height: rect.height || 1
497    };
498    setIsDraggingStage(true);
499  };
500  const handleStagePointerMove = (e) => {
501    if (!isDraggingStage || !dragStartRef.current) return;
502    const dx = e.clientX - dragStartRef.current.clientX;
503    const dy = e.clientY - dragStartRef.current.clientY;
504    const deltaXPercent = dx / dragStartRef.current.width * 100;
505    const deltaYPercent = dy / dragStartRef.current.height * 100;
506    const nextOffsetX = Math.max(-50, Math.min(50, Math.round(dragStartRef.current.startOffsetX + deltaXPercent)));
507    const nextOffsetY = Math.max(-40, Math.min(50, Math.round(dragStartRef.current.startOffsetY + deltaYPercent)));
508    updateActiveConfig((prev) => ({
509      ...prev,
510      image: {
511        ...prev.image || DEFAULT_STAGE_IMAGE,
512        offsetX: nextOffsetX,
513        offsetY: nextOffsetY
514      }
515    }));
516  };
517  const handleStagePointerUp = (e) => {
518    if (isDraggingStage) {
519      setIsDraggingStage(false);
520      dragStartRef.current = null;
521      try {
522        e.currentTarget.releasePointerCapture(e.pointerId);
523      } catch {
524      }
525    }
526  };
527  const handleStageWheel = (e) => {
528    e.preventDefault();
529    const zoomDelta = e.deltaY < 0 ? 0.04 : -0.04;
530    const nextScale = Math.min(2.5, Math.max(1, Number((effectiveScale + zoomDelta).toFixed(2))));
531    updateActiveConfig((prev) => ({
532      ...prev,
533      image: {
534        ...prev.image || DEFAULT_STAGE_IMAGE,
535        scale: nextScale
536      }
537    }));
538  };
539  const effectiveStageConfig = reactExports.useMemo(() => ({
540    ...stageConfig,
541    backY: effectiveBackY,
542    frontY: effectiveFrontY,
543    backScale: effectiveBackScale,
544    frontScale: effectiveFrontScale,
545    horizonY: effectiveHorizonY
546  }), [stageConfig, effectiveBackY, effectiveFrontY, effectiveBackScale, effectiveFrontScale, effectiveHorizonY]);
547  const sampleMusicians = reactExports.useMemo(() => {
548    const activeEnsemble = SAMPLE_ENSEMBLE_POOL.slice(0, Math.max(1, Math.min(24, sampleMusicianCount)));
549    const placed = calculateEnsemblePlacement(activeEnsemble, {
550      stageConfig: effectiveStageConfig,
551      enableDensityScaling,
552      stageWidth: 1200,
553      stageHeight: 650
554    });
555    return placed.map((p) => {
556      var _a2;
557      return {
558        id: p.m.id,
559        animalId: p.m.animalId,
560        program: p.m.program,
561        isPercussion: p.m.isPercussion,
562        percRole: p.m.percRole,
563        x: p.posX,
564        y: p.posY,
565        scale: p.musicianScale,
566        tier: `${p.rowName === "back" ? "Back" : p.rowName === "middle" ? "Middle" : "Front"} · ${p.m.tier ? ((_a2 = p.m.tier.split("·")[1]) == null ? void 0 : _a2.trim()) || p.m.id : p.m.id}`
567      };
568    });
569  }, [effectiveStageConfig, sampleMusicianCount, enableDensityScaling]);
570  const filteredPresets = reactExports.useMemo(() => {
571    return mergedPresets.filter((p) => {
572      if (galleryFilter === "sp_overrides" && !p.isSpOverride) return false;
573      if (galleryFilter === "shared" && p.isSpOverride) return false;
574      if (searchQuery.trim()) {
575        const q = searchQuery.toLowerCase().trim();
576        const matchName = p.name.toLowerCase().includes(q);
577        const matchTag = p.tags.some((t) => t.toLowerCase().includes(q));
578        if (!matchName && !matchTag) return false;
579      }
580      return true;
581    });
582  }, [mergedPresets, galleryFilter, searchQuery]);
583  const activeParticleMeta = PARTICLE_OPTIONS.find((p) => {
584    var _a2;
585    return p.id === ((_a2 = activeConfig.particles) == null ? void 0 : _a2.type);
586  }) || PARTICLE_OPTIONS[0];
587  const activeLightingProfile = resolveLightingProfile(activeConfig, activePresetMeta.tags);
588  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-8 animate-fadeIn", children: [
589    /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gradient-to-r from-zinc-900 via-indigo-950/40 to-zinc-900 border border-indigo-500/30 rounded-2xl p-5 shadow-2xl relative overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col lg:flex-row items-start lg:items-center justify-between gap-4 relative z-10", children: [
590      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4", children: [
591        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-16 h-12 rounded-lg border border-indigo-400/40 overflow-hidden bg-black shadow-md shrink-0 relative", children: [
592          activeConfig.type === "image" && ((_j = activeConfig.image) == null ? void 0 : _j.url) ? /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: activeConfig.image.url, alt: "Active preview", className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full h-full", style: stageBackgroundStyle }),
593          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute bottom-0 right-0 bg-black/80 text-[10px] px-1 rounded-tl text-zinc-300", children: activeParticleMeta.icon })
594        ] }),
595        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
596          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2.5 flex-wrap", children: [
597            /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-bold text-white flex items-center gap-2", children: activePresetMeta.name }),
598            isCurrentSelectedSpOverride ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-2.5 py-0.5 rounded-full text-[11px] font-bold bg-amber-500/20 text-amber-300 border border-amber-500/30 flex items-center gap-1", children: [
599              /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 12 }),
600              " South Park Custom Override"
601            ] }) : selectedPresetId === null ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2.5 py-0.5 rounded-full text-[11px] font-bold bg-purple-500/20 text-purple-300 border border-purple-500/30 flex items-center gap-1", children: "🎲 Dynamic Shuffle (Untagged MIDIs)" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2.5 py-0.5 rounded-full text-[11px] font-bold bg-blue-500/20 text-blue-300 border border-blue-500/30 flex items-center gap-1", children: "🎻 Shared Orchestra Preset" })
602          ] }),
603          /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-zinc-400 mt-1 flex items-center gap-2 flex-wrap", children: [
604            /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
605              "Lighting: ",
606              /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "text-amber-400 font-semibold", children: activeLightingProfile.name })
607            ] }),
608            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-600", children: "•" }),
609            /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
610              "Particles: ",
611              /* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { className: "text-zinc-200", children: [
612                activeParticleMeta.label,
613                " (",
614                ((_k = activeConfig.particles) == null ? void 0 : _k.count) ?? 50,
615                ")"
616              ] })
617            ] }),
618            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-600", children: "•" }),
619            /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
620              "Type: ",
621              /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "text-zinc-200 capitalize", children: activeConfig.type })
622            ] }),
623            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-600", children: "•" }),
624            /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
625              "Tags: ",
626              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-300 font-mono text-[11px]", children: activePresetMeta.tags.join(", ") || "none" })
627            ] })
628          ] })
629        ] })
630      ] }),
631      /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 shrink-0 self-end lg:self-center", children: isCurrentSelectedSpOverride ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
632        "button",
633        {
634          onClick: handleRevertToShared,
635          className: "px-3 py-1.5 rounded-lg text-xs font-semibold bg-zinc-800 hover:bg-zinc-700 text-zinc-300 border border-zinc-700 flex items-center gap-1.5 transition-colors",
636          title: "Revert to inherited shared orchestra configuration",
637          children: [
638            /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 14 }),
639            " Revert to Orchestra Preset"
640          ]
641        }
642      ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
643        "button",
644        {
645          onClick: () => {
646            updateActiveConfig((prev) => ({ ...prev }));
647          },
648          className: "px-3 py-1.5 rounded-lg text-xs font-semibold bg-indigo-600 hover:bg-indigo-500 text-white shadow-md flex items-center gap-1.5 transition-colors",
649          title: "Create an independent South Park override for this background",
650          children: [
651            /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 14 }),
652            " Customize for South Park"
653          ]
654        }
655      ) })
656    ] }) }),
657    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 xl:grid-cols-12 gap-6 items-start", children: [
658      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "xl:col-span-7 2xl:col-span-8 bg-zinc-950 border border-zinc-800/90 rounded-2xl p-4 shadow-xl space-y-3", children: [
659        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between flex-wrap gap-3 pb-2 border-b border-zinc-800/80", children: [
660          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
661            /* @__PURE__ */ jsxRuntimeExports.jsx(Monitor, { size: 16, className: "text-indigo-400" }),
662            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-bold text-white tracking-wide", children: "Live Stage Composite Canvas" }),
663            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-zinc-500", children: "(1200 x 650 Virtual Stage)" })
664          ] }),
665          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
666            /* @__PURE__ */ jsxRuntimeExports.jsxs(
667              "button",
668              {
669                onClick: () => setIsParticlesPlaying(!isParticlesPlaying),
670                className: `px-2.5 py-1 rounded-md text-xs font-medium border flex items-center gap-1.5 transition-colors ${isParticlesPlaying ? "bg-indigo-500/20 text-indigo-300 border-indigo-500/40" : "bg-zinc-900 text-zinc-400 border-zinc-800 hover:text-white"}`,
671                children: [
672                  isParticlesPlaying ? /* @__PURE__ */ jsxRuntimeExports.jsx(Pause, { size: 13 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Play, { size: 13 }),
673                  isParticlesPlaying ? "Particles Active" : "Particles Paused"
674                ]
675              }
676            ),
677            /* @__PURE__ */ jsxRuntimeExports.jsxs(
678              "button",
679              {
680                onClick: () => setShowSampleMusicians(!showSampleMusicians),
681                className: `px-2.5 py-1 rounded-md text-xs font-medium border flex items-center gap-1.5 transition-colors ${showSampleMusicians ? "bg-amber-500/20 text-amber-300 border-amber-500/40" : "bg-zinc-900 text-zinc-500 border-zinc-800"}`,
682                children: [
683                  showSampleMusicians ? /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 13 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { size: 13 }),
684                  showSampleMusicians ? "Musicians Visible" : "Musicians Hidden"
685                ]
686              }
687            ),
688            /* @__P
688URE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 bg-zinc-900 px-2 py-1 rounded-md border border-zinc-800 text-xs", children: [
689              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 font-medium", children: "Musicians:" }),
690              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono font-bold text-amber-400", children: sampleMusicianCount }),
691              /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-0.5 ml-1", children: [1, 3, 5, 8, 12, 18, 24].map((num) => /* @__PURE__ */ jsxRuntimeExports.jsx(
692                "button",
693                {
694                  type: "button",
695                  onClick: () => setSampleMusicianCount(num),
696                  className: `px-1.5 py-0.5 rounded text-[10px] font-semibold transition-all ${sampleMusicianCount === num ? "bg-amber-500 text-black shadow-sm" : "text-zinc-400 hover:text-white bg-zinc-800 hover:bg-zinc-700"}`,
697                  children: num
698                },
699                num
700              )) })
701            ] }),
702            /* @__PURE__ */ jsxRuntimeExports.jsxs(
703              "button",
704              {
705                onClick: () => setShowArcGuides(!showArcGuides),
706                className: `px-2.5 py-1 rounded-md text-xs font-medium border flex items-center gap-1.5 transition-colors ${showArcGuides ? "bg-indigo-500/20 text-indigo-300 border-indigo-500/40" : "bg-zinc-900 text-zinc-500 border-zinc-800 hover:text-white"}`,
707                children: [
708                  /* @__PURE__ */ jsxRuntimeExports.jsx(Compass, { size: 13 }),
709                  " Arc Guides"
710                ]
711              }
712            ),
713            /* @__PURE__ */ jsxRuntimeExports.jsxs(
714              "button",
715              {
716                onClick: () => setShowDepthGuides(!showDepthGuides),
717                className: `px-2.5 py-1 rounded-md text-xs font-medium border flex items-center gap-1.5 transition-colors ${showDepthGuides ? "bg-cyan-500/20 text-cyan-300 border-cyan-500/40" : "bg-zinc-900 text-zinc-500 border-zinc-800 hover:text-white"}`,
718                children: [
719                  /* @__PURE__ */ jsxRuntimeExports.jsx(Layers, { size: 13 }),
720                  " 3D Depth Lines"
721                ]
722              }
723            ),
724            /* @__PURE__ */ jsxRuntimeExports.jsxs(
725              "button",
726              {
727                onClick: () => setPreviewPhysics((p) => p === "snappy" ? "smooth" : "snappy"),
728                className: "px-2.5 py-1 rounded-md text-xs font-medium bg-zinc-900 hover:bg-zinc-800 text-zinc-300 border border-zinc-800 transition-colors capitalize",
729                children: [
730                  "Physics: ",
731                  previewPhysics
732                ]
733              }
734            ),
735            /* @__PURE__ */ jsxRuntimeExports.jsxs(
736              "button",
737              {
738                onClick: () => {
739                  const modes = ["dynamic", "subtle", "off"];
740                  const next = modes[(modes.indexOf(previewLighting) + 1) % modes.length];
741                  setPreviewLighting(next);
742                },
743                className: `px-2.5 py-1 rounded-md text-xs font-medium border flex items-center gap-1.5 transition-colors ${previewLighting !== "off" ? "bg-amber-500/20 text-amber-300 border-amber-500/40" : "bg-zinc-900 text-zinc-500 border-zinc-800 hover:text-white"}`,
744                title: "Toggle preview stage lighting effects",
745                children: [
746                  /* @__PURE__ */ jsxRuntimeExports.jsx(Lightbulb, { size: 13 }),
747                  " Lighting: ",
748                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "capitalize", children: previewLighting })
749                ]
750              }
751            ),
752            selectedPresetId === null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
753              "button",
754              {
755                onClick: () => setShufflePreviewIndex((prev) => (prev + 1) % Math.max(1, mergedPresets.length)),
756                className: "px-2.5 py-1 rounded-md text-xs font-semibold bg-purple-600/30 text-purple-200 border border-purple-500/40 hover:bg-purple-600/50 flex items-center gap-1.5 transition-colors shadow-sm",
757                title: "Cycle random stage preview on the canvas",
758                children: [
759                  /* @__PURE__ */ jsxRuntimeExports.jsx(Shuffle, { size: 13 }),
760                  " Shuffle Stage"
761                ]
762              }
763            )
764          ] })
765        ] }),
766        /* @__PURE__ */ jsxRuntimeExports.jsxs(
767          "div",
768          {
769            className: `w-full relative rounded-xl overflow-hidden border border-zinc-800 shadow-inner select-none touch-none ${isDraggingStage ? "cursor-grabbing" : "cursor-grab"}`,
770            style: { aspectRatio: "1200 / 650", minHeight: "380px" },
771            onPointerDown: handleStagePointerDown,
772            onPointerMove: handleStagePointerMove,
773            onPointerUp: handleStagePointerUp,
774            onPointerCancel: handleStagePointerUp,
775            onWheel: handleStageWheel,
776            children: [
777              /* @__PURE__ */ jsxRuntimeExports.jsx(
778                "div",
779                {
780                  className: "absolute inset-0 pointer-events-none",
781                  style: stageBackgroundStyle
782                }
783              ),
784              ((_l = activeConfig.overlay) == null ? void 0 : _l.enabled) && /* @__PURE__ */ jsxRuntimeExports.jsx(
785                "div",
786                {
787                  className: "absolute inset-0 pointer-events-none transition-opacity duration-300",
788                  style: {
789                    backgroundColor: activeConfig.overlay.color || "#000000",
790                    opacity: activeConfig.overlay.opacity ?? 0.15
791                  }
792                }
793              ),
794              ((_m = activeConfig.particles) == null ? void 0 : _m.enabled) && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 pointer-events-none z-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
795                BackgroundParticlesCanvas,
796                {
797                  config: activeConfig.particles,
798                  isPlaying: isParticlesPlaying
799                }
800              ) }),
801              /* @__PURE__ */ jsxRuntimeExports.jsx(
802                "div",
803                {
804                  className: "absolute inset-0 pointer-events-none z-20",
805                  style: {
806                    background: "linear-gradient(to top, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.2) 40%, transparent 100%)"
807                  }
808                }
809              ),
810              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute bottom-3 left-3 z-40 flex items-center gap-2 bg-black/75 backdrop-blur-md px-3 py-1.5 rounded-full border border-white/10 text-[11px] shadow-lg pointer-events-none transition-opacity duration-200", children: [
811                /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1.5 text-amber-300 font-medium", children: [
812                  /* @__PURE__ */ jsxRuntimeExports.jsx(Move, { size: 12, className: isDraggingStage ? "animate-pulse text-amber-400" : "" }),
813                  isDraggingStage ? "Repositioning Stage..." : "Drag stage to pan"
814                ] }),
815                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-600", children: "•" }),
816                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400", children: "Scroll to zoom" }),
817                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-600", children: "•" }),
818                /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-zinc-300 text-[10px]", children: [
819                  "X: ",
820                  /* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { className: "text-amber-400", children: [
821                    effectiveOffsetX > 0 ? `+${effectiveOffsetX}` : effectiveOffsetX,
822                    "%"
823                  ] }),
824                  ", Y: ",
825                  /* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { className: "text-amber-400", children: [
826                    effectiveOffsetY > 0 ? `+${effectiveOffsetY}` : effectiveOffsetY,
827                    "%"
828                  ] }),
829                  ", Zoom: ",
830                  /* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { className: "text-amber-400", children: [
831                    effectiveScale.toFixed(2),
832                    "x"
833                  ] })
834                ] })
835              ] }),
836              /* @__PURE__ */ jsxRuntimeExports.jsxs(
837                "svg",
838                {
839                  ref: svgViewportRef,
840                  className: "absolute inset-0 w-full h-full z-30 pointer-events-none",
841                  viewBox: "0 0 1200 650",
842                  preserveAspectRatio: "xMidYMid meet",
843                  children: [
844                    /* @__PURE__ */ jsxRuntimeExports.jsxs("defs", { children: [
845                      /* @__PURE__ */ jsxRuntimeExports.jsxs("radialGradient", { id: "shadowGrad", cx: "50%", cy: "50%", r: "50%", children: [
846                        /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "0%", stopColor: "#000000", stopOpacity: "0.65" }),
847                        /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "45%", stopColor: "#000000", stopOpacity: "0.30" }),
848                        /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "75%", stopColor: "#000000", stopOpacity: "0.10" }),
849                        /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "92%", stopColor: "#000000", stopOpacity: "0.02" }),
850                        /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "100%", stopColor: "#000000", stopOpacity: "0" })
851                      ] }),
852                      /* @__PURE__ */ jsxRuntimeExports.jsxs("linearGradient", { id: "arcLineGrad", x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
853                        /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "0%", stopColor: "#818cf8", stopOpacity: "0.2" }),
854                        /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "50%", stopColor: "#818cf8", stopOpacity: "0.9" }),
855                        /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "100%", stopColor: "#818cf8", stopOpacity: "0.2" })
856                      ] })
857                    ] }),
858                    showArcGuides && (() => {
859                      const yOff = stageConfig.yOffset ?? 0;
860                      const arcStr = stageConfig.arcFactor ?? 1;
861                      return /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { className: "arc-guides", stroke: "url(#arcLineGrad)", strokeWidth: "2", strokeDasharray: "6 4", fill: "none", children: [
862                        /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: `M 180 ${390 + yOff} Q 600 ${390 + yOff - 25 * arcStr} 1020 ${390 + yOff}` }),
863                        /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: `M 180 ${465 + yOff} Q 600 ${465 + yOff - 25 * arcStr} 1020 ${465 + yOff}` }),
864                        /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: `M 180 ${535 + yOff} Q 600 ${535 + yOff - 25 * arcStr} 1020 ${535 + yOff}` }),
865                        /* @__PURE__ */ jsxRuntimeExports.jsxs("text", { x: "600", y: 370 + yOff, fill: "#a5b4fc", fontSize: "12", textAnchor: "middle", fontWeight: "bold", children: [
866                          "Seating Arc (Curvature: ",
867                          arcStr.toFixed(2),
868                          "x)"
869                        ] })
870                      ] });
871                    })(),
872                    showDepthGuides && (() => {
873                      const bY = effectiveBackY;
874                      const fY = effectiveFrontY;
875                      const mY = Math.round((bY + fY) / 2);
876                      return /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { className: "depth-guides", children: [
877                        /* @__PURE__ */ jsxRuntimeExports.jsx(
878                          "polygon",
879                          {
880                            points: `160,${bY} 1040,${bY} 1120,${fY} 80,${fY}`,
881                            fill: "rgba(14, 165, 233, 0.05)",
882                            stroke: "rgba(14, 165, 233, 0.3)",
883                            strokeWidth: "1.5",
884                            strokeDasharray: "4 4"
885                          }
886                        ),
887                        /* @__PURE__ */ jsxRuntimeExports.jsx(
888                          "line",
889                          {
890                            x1: "110",
891                            y1: mY,
892                            x2: "1090",
893                            y2: mY,
894                            stroke: "#818cf8",
895                            strokeWidth: "1",
896                            strokeDasharray: "3 3",
897                            opacity: "0.6"
898                          }
899                        ),
900                        /* @__P
900URE__ */ jsxRuntimeExports.jsxs("text", { x: "180", y: mY - 5, fill: "#a5b4fc", fontSize: "10", opacity: "0.8", children: [
901                          "Mid Tier Reference (Y: ",
902                          mY,
903                          ")"
904                        ] }),
905                        /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { className: "back-ground-guide-group", children: [
906                          /* @__PURE__ */ jsxRuntimeExports.jsx(
907                            "rect",
908                            {
909                              x: "120",
910                              y: bY - 14,
911                              width: "960",
912                              height: "28",
913                              fill: "transparent",
914                              className: "cursor-ns-resize pointer-events-auto",
915                              onPointerDown: (e) => handleDepthLinePointerDown("backY", e),
916                              onPointerMove: (e) => handleDepthLinePointerMove("backY", e),
917                              onPointerUp: handleDepthLinePointerUp,
918                              onPointerCancel: handleDepthLinePointerUp
919                            }
920                          ),
921                          /* @__PURE__ */ jsxRuntimeExports.jsx(
922                            "line",
923                            {
924                              x1: "140",
925                              y1: bY,
926                              x2: "1060",
927                              y2: bY,
928                              stroke: "#38bdf8",
929                              strokeWidth: activeDepthDrag === "backY" ? 4 : 2.5,
930                              strokeDasharray: "6 4"
931                            }
932                          ),
933                          /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "140", cy: bY, r: activeDepthDrag === "backY" ? 7 : 5, fill: "#38bdf8", stroke: "#0284c7", strokeWidth: "2" }),
934                          /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "1060", cy: bY, r: activeDepthDrag === "backY" ? 7 : 5, fill: "#38bdf8", stroke: "#0284c7", strokeWidth: "2" }),
935                          /* @__PURE__ */ jsxRuntimeExports.jsxs(
936                            "g",
937                            {
938                              className: "cursor-ns-resize pointer-events-auto",
939                              onPointerDown: (e) => handleDepthLinePointerDown("backY", e),
940                              onPointerMove: (e) => handleDepthLinePointerMove("backY", e),
941                              onPointerUp: handleDepthLinePointerUp,
942                              onPointerCancel: handleDepthLinePointerUp,
943                              children: [
944                                /* @__PURE__ */ jsxRuntimeExports.jsx(
945                                  "rect",
946                                  {
947                                    x: "410",
948                                    y: bY - 14,
949                                    width: "380",
950                                    height: "28",
951                                    rx: "14",
952                                    fill: activeDepthDrag === "backY" ? "#0369a1" : "rgba(24, 24, 27, 0.92)",
953                                    stroke: "#38bdf8",
954                                    strokeWidth: activeDepthDrag === "backY" ? 2 : 1.5,
955                                    className: "transition-colors filter drop-shadow-md"
956                                  }
957                                ),
958                                /* @__PURE__ */ jsxRuntimeExports.jsxs("text", { x: "600", y: bY + 4, fill: activeDepthDrag === "backY" ? "#ffffff" : "#38bdf8", fontSize: "11", textAnchor: "middle", fontWeight: "bold", children: [
959                                  "↕ BACK ROW GROUND (Y: ",
960                                  bY,
961                                  ", Scale: ",
962                                  effectiveBackScale.toFixed(2),
963                                  "x)"
964                                ] })
965                              ]
966                            }
967                          )
968                        ] }),
969                        /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { className: "front-ground-guide-group", children: [
970                          /* @__PURE__ */ jsxRuntimeExports.jsx(
971                            "rect",
972                            {
973                              x: "50",
974                              y: fY - 14,
975                              width: "1100",
976                              height: "28",
977                              fill: "transparent",
978                              className: "cursor-ns-resize pointer-events-auto",
979                              onPointerDown: (e) => handleDepthLinePointerDown("frontY", e),
980                              onPointerMove: (e) => handleDepthLinePointerMove("frontY", e),
981                              onPointerUp: handleDepthLinePointerUp,
982                              onPointerCancel: handleDepthLinePointerUp
983                            }
984                          ),
985                          /* @__PURE__ */ jsxRuntimeExports.jsx(
986                            "line",
987                            {
988                              x1: "60",
989                              y1: fY,
990                              x2: "1140",
991                              y2: fY,
992                              stroke: "#10b981",
993                              strokeWidth: activeDepthDrag === "frontY" ? 4 : 2.5,
994                              strokeDasharray: "6 4"
995                            }
996                          ),
997                          /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "60", cy: fY, r: activeDepthDrag === "frontY" ? 7 : 5, fill: "#10b981", stroke: "#059669", strokeWidth: "2" }),
998                          /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "1140", cy: fY, r: activeDepthDrag === "frontY" ? 7 : 5, fill: "#10b981", stroke: "#059669", strokeWidth: "2" }),
999                          /* @__PURE__ */ jsxRuntimeExports.jsxs(
1000                            "g",
1001                            {
1002                              className: "cursor-ns-resize pointer-events-auto",
1003                              onPointerDown: (e) => handleDepthLinePointerDown("frontY", e),
1004                              onPointerMove: (e) => handleDepthLinePointerMove("frontY", e),
1005                              onPointerUp: handleDepthLinePointerUp,
1006                              onPointerCancel: handleDepthLinePointerUp,
1007                              children: [
1008                                /* @__PURE__ */ jsxRuntimeExports.jsx(
1009                                  "rect",
1010                                  {
1011                                    x: "400",
1012                                    y: fY - 14,
1013                                    width: "400",
1014                                    height: "28",
1015                                    rx: "14",
1016                                    fill: activeDepthDrag === "frontY" ? "#047857" : "rgba(24, 24, 27, 0.92)",
1017                                    stroke: "#10b981",
1018                                    strokeWidth: activeDepthDrag === "frontY" ? 2 : 1.5,
1019                                    className: "transition-colors filter drop-shadow-md"
1020                                  }
1021                                ),
1022                                /* @__PURE__ */ jsxRuntimeExports.jsxs("text", { x: "600", y: fY + 4, fill: activeDepthDrag === "frontY" ? "#ffffff" : "#34d399", fontSize: "11", textAnchor: "middle", fontWeight: "bold", children: [
1023                                  "↕ FRONT ROW GROUND (Y: ",
1024                                  fY,
1025                                  ", Scale: ",
1026                                  effectiveFrontScale.toFixed(2),
1027                                  "x)"
1028                                ] })
1029                              ]
1030                            }
1031                          )
1032                        ] })
1033                      ] });
1034                    })(),
1035                    /* @__PURE__ */ jsxRuntimeExports.jsx(
1036                      SouthparkStageBanner,
1037                      {
1038                        track: {
1039                          id: "designer-preview",
1040                          title: (activePresetMeta == null ? void 0 : activePresetMeta.name) || "HamieNET Orchestra",
1041                          artist: "South Park Stage"
1042                        },
1043                        backgroundUrl: (_n = activeConfig.image) == null ? void 0 : _n.url,
1044                        currentTime: isParticlesPlaying ? Date.now() / 1e3 : 0,
1045                        bpm: 120,
1046                        isPlaying: isParticlesPlaying,
1047                        globalIntensity: 0.65,
1048                        showBanner: true
1049                      }
1050                    ),
1051                    /* @__PURE__ */ jsxRuntimeExports.jsx(
1052                      SouthparkStageLighting,
1053                      {
1054                        currentTime: isParticlesPlaying ? Date.now() / 1e3 : 0,
1055                        isPlaying: isParticlesPlaying,
1056                        bpm: 120,
1057                        bps: 2,
1058                        backgroundConfig: activeConfig,
1059                        lightingMode: previewLighting,
1060                        musicians: sampleMusicians.map((m, idx) => ({
1061                          uniqueName: m.id,
1062                          baseName: m.tier,
1063                          index: idx,
1064                          program: m.program,
1065                          isPercussion: m.isPercussion
1066                        })),
1067                        musicianPositions: sampleMusicians.reduce((acc, m) => {
1068                          const colors = ["#ef4444", "#10b981", "#a855f7", "#eab308", "#06b6d4", "#f97316"];
1069                          acc[m.id] = {
1070                            posX: m.x,
1071                            posY: m.y,
1072                            scale: m.scale,
1073                            trackColor: colors[m.id.charCodeAt(0) % colors.length],
1074                            isPercussion: m.isPercussion
1075                          };
1076                          return acc;
1077                        }, {}),
1078                        activeNotes: sampleMusicians.reduce((acc, m, idx) => {
1079                          if (idx < Math.min(3, sampleMusicians.length)) {
1080                            acc[m.id] = { velocity: 105, pitch: 64 };
1081                          }
1082                          return acc;
1083                        }, {}),
1084                        soloedIndex: null,
1085                        selectedTrackIndex: null,
1086                        globalIntensity: 0.65,
1087                        stageWidth: 1200,
1088                        stageHeight: 650
1089                      }
1090                    ),
1091                    showSampleMusicians && sampleMusicians.map((m) => {
1092                      const animal = BASE_ANIMALS[m.animalId] || BASE_ANIMALS["fox"];
1093                      const inst = getInstrumentDef(m.program, m.isPercussion, m.percRole);
1094                      const customCfg = charactersConfig == null ? void 0 : charactersConfig[m.animalId];
1095                      return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1096                        "g",
1097                        {
1098                          transform: `translate(${m.x}, ${m.y})`,
1099                          className: "transition-transform duration-200",
1100                          children: [
1101                            /* @__PURE__ */ jsxRuntimeExports.jsx(
1102                              "ellipse",
1103                              {
1104                                cx: "0",
1105                                cy: 78 * m.scale,
1106                                rx: 44 * m.scale,
1107                                ry: 12 * m.scale,
1108                                fill: "url(#shadowGrad)"
1109                              }
1110                            ),
1111                            /* @__PURE__ */ jsxRuntimeExports.jsx("g", { transform: `scale(${m.scale})`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1112                              SouthparkCharacter,
1113                              {
1114                                animal,
1115                                instrument: inst,
1116                                isActive: isParticlesPlaying,
1117                                velocity: 100,
1118                                physicsMode: previewPhysics,
1119                                customConfig: customCfg,
1120                                costumes: costumesConfig ? [] : []
1121                              }
1122                            ) }),
1123                            /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { transform: `translate(0, ${70 * m.scale + 8})`, className: "pointer-events-none select-none", children: [
1124                              /* @__PURE__ */ jsxRuntimeExports.jsx(
1125                                "rect",
1126                                {
1127                                  x: "-45",
1128                                  y: "0",
1129                                  width: "90",
1130                                  height: "20",
1131                                  rx: "10",
1132                                  fill: "rgba(9, 9, 11, 0.9)",
1133                                  stroke: "rgba(168, 85, 247, 0.6)",
1134                                  strokeWidth: "1.2"
1135                                }
1136                              ),
1137                              /* @__PURE__ */ jsxRuntimeExports.jsx(
1138                                "text",
1139                                {
1140                                  x: "0",
1141                                  y: "13",
1142                                  fill: "#e4e4e7",
1143                                  fontSize: "9",
1144                                  textAnchor: "middle",
1145                                  fontWeight: "bold",
1146                                  className: "font-mono",
1147                                  children: m.tier
1148                                }
1149                              )
1150                            ] })
1151                          ]
1152                        },
1153                        m.id
1154                      );
1155                    })
1156                  ]
1157                }
1158              )
1159            ]
1160          }
1161        )
1162      ] }),
1163      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "xl:col-span-5 2xl:col-span-4 space-y-3 sticky top-4 max-h-[calc(100vh-5rem)] overflow-y-auto pr-1 custom-scrollbar", children: [
1164        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900/80 border border-zinc-800 rounded-xl overflow-hidden shadow-lg transition-all", children: [
1165          /* @__PURE__ */ jsxRuntimeExports.jsxs(
1166            "button",
1167            {
1168              type: "button",
1169              onClick: () => toggleSection("depth"),
1170              className: "w-full px-4 py-3 flex items-center justify-between bg-zinc-900 hover:bg-zinc-850 transition-colors text-left select-none",
1171              children: [
1172                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1173                  /* @__PURE__ */ jsxRuntimeExports.jsx(Layers, { size: 16, className: "text-cyan-400" }),
1174                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-bold text-white", children: "3D Stage Depth & Perspective" })
1175                ] }),
1176                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1177                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[11px] font-mono text-cyan-300 font-semibold bg-cyan-500/10 border border-cyan-500/20 px-2 py-0.5 rounded-full", children: [
1178                    "-",
1179                    Math.round((1 - effectiveBackScale / effectiveFrontScale) * 100),
1180                    "% depth"
1181                  ] }),
1182                  openSections.depth ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 15, className: "text-zinc-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 15, className: "text-zinc-400" })
1183                ] })
1184              ]
1185            }
1186          ),
1187          openSections.depth && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-t border-zinc-800/80 space-y-4 bg-zinc-950/40", children: [
1188            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-950/80 p-2.5 rounded-lg border border-cyan-500/20 text-xs flex items-center justify-between", children: [
1189              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400", children: "Back Row Reduction:" }),
1190              /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-bold text-cyan-300", children: [
1191                "-",
1192                Math.round((1 - effectiveBackScale / effectiveFrontScale) * 100),
1193                "% (",
1194                effectiveBackScale.toFixed(2),
1195                "x vs ",
1196                effectiveFrontScale.toFixed(2),
1197                "x)"
1198              ] })
1199            ] }),
1200            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [
1201              /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-[10px] font-bold text-zinc-400 uppercase tracking-wider block", children: "Perspective Presets" }),
1202              /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-1.5", children: DEPTH_PRESETS.map((preset) => {
1203                const isMatch = Math.abs(effectiveBackScale - preset.bScale) < 0.03 && Math.abs(effectiveFrontScale - preset.fScale) < 0.03;
1204                return /* @__PURE__ */ jsxRuntimeExports.jsx(
1205                  "button",
1206                  {
1207                    type: "button",
1208                    onClick: () => applyDepthPreset(preset.bScale, preset.fScale),
1209                    className: `px-2 py-1.5 rounded-lg text-xs font-medium border transition-all truncate ${isMatch ? "bg-cyan-500/20 text-cyan-200 border-cyan-400 font-semibold" : "bg-zinc-900 hover:bg-zinc-800 text-zinc-300 border-zinc-800 hover:border-zinc-700"}`,
1210                    children: preset.label
1211                  },
1212                  preset.label
1213                );
1214              }) })
1215            ] }),
1216            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3 pt-1 border-t border-zinc-800/80", children: [
1217              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1218                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1219                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-300 font-medium", children: "Back Scale" }),
1220                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-cyan-400 font-bold", children: [
1221                    effectiveBackScale.toFixed(2),
1222                    "x"
1223                  ] })
1224                ] }),
1225                /* @__PURE__ */ jsxRuntimeExports.jsx(
1226                  "input",
1227                  {
1228                    type: "range",
1229                    min: "0.35",
1230                    max: "0.90",
1231                    step: "0.02",
1232                    value: effectiveBackScale,
1233                    onChange: (e) => {
1234                      const val = parseFloat(e.target.value);
1235                      updateActiveConfig((prev) => ({
1236                        ...prev,
1237                        image: { ...prev.image || DEFAULT_STAGE_IMAGE, backScale: val }
1238                      }));
1239                    },
1240                    className: "w-full accent-cyan-500 cursor-pointer"
1241                  }
1242                )
1243              ] }),
1244              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1245                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1246                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-300 font-medium", children: "Front Scale" }),
1247                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-emerald-400 font-bold", children: [
1248                    effectiveFrontScale.toFixed(2),
1249                    "x"
1250                  ] })
1251                ] }),
1252                /* @__PURE__ */ jsxRuntimeExports.jsx(
1253                  "input",
1254                  {
1255                    type: "range",
1256                    min: "0.70",
1257                    max: "1.30",
1258                    step: "0.02",
1259                    value: effectiveFrontScale,
1260                    onChange: (e) => {
1261                      const val = parseFloat(e.target.value);
1262                      updateActiveConfig((prev) => ({
1263                        ...prev,
1264                        image: { ...prev.image || DEFAULT_STAGE_IMAGE, frontScale: val }
1265                      }));
1266                    },
1267                    className: "w-full accent-emerald-500 cursor-pointer"
1268                  }
1269                )
1270              ] })
1271            ] }),
1272            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2.5 pt-1 border-t border-zinc-800/80 text-xs", children: [
1273              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1274                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1", children: [
1275                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-cyan-400 font-medium", children: "Back Row Ground Line (Y)" }),
1276                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
1277                    /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-bold text-zinc-200 mr-1", children: [
1278                      effectiveBackY,
1279                      "px"
1280                    ] }),
1281                    /* @__PURE__ */ jsxRuntimeExports.jsx(
1282                      "button",
1283                      {
1284                        type: "button",
1285                        onClick: () => updateActiveConfig((prev) => ({
1286                          ...prev,
1287                          image: { ...prev.image || DEFAULT_STAGE_IMAGE, backY: Math.max(240, effectiveBackY - 5) }
1288                        })),
1289                        className: "px-1.5 py-0.5 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded text-[10px] font-mono border border-zinc-700",
1290                        children: "-5"
1291                      }
1292                    ),
1293                    /* @__PURE__ */ jsxRuntimeExports.jsx(
1294                      "button",
1295                      {
1296                        type: "button",
1297                        onClick: () => updateActiveConfig((prev) => ({
1298                          ...prev,
1299                          image: { ...prev.image || DEFAULT_STAGE_IMAGE, backY: Math.min(effectiveFrontY - 30, effectiveBackY + 5) }
1300                        })),
1301                        className: "px-1.5 py-0.5 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded text-[10px] font-mono border border-zinc-700",
1302                        children: "+5"
1303                      }
1304                    )
1305                  ] })
1306                ] }),
1307                /* @__PURE__ */ jsxRuntimeExports.jsx(
1308                  "input",
1309                  {
1310                    type: "range",
1311                    min: "250",
1312                    max: "450",
1313                    step: "5",
1314                    value: effectiveBackY,
1315                    onChange: (e) => {
1316                      const val = parseInt(e.target.value);
1317                      updateActiveConfig((prev) => ({
1318                        ...prev,
1319                        image: { ...prev.image || DEFAULT_STAGE_IMAGE, backY: val }
1320                      }));
1321                    },
1322                    className: "w-full accent-cyan-500 cursor-pointer"
1323                  }
1324                )
1325              ] }),
1326              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1327                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1", children: [
1328                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-emerald-400 font-medium", children: "Front Row Ground Line (Y)" }),
1329                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
1330                    /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-bold text-zinc-200 mr-1", children: [
1331                      effectiveFrontY,
1332                      "px"
1333                    ] }),
1334                    /* @__PURE__ */ jsxRuntimeExports.jsx(
1335                      "button",
1336                      {
1337                        type: "button",
1338                        onClick: () => updateActiveConfig((prev) => ({
1339                          ...prev,
1340                          image: { ...prev.image || DEFAULT_STAGE_IMAGE, frontY: Math.max(effectiveBackY + 30, effectiveFrontY - 5) }
1341                        })),
1342                        className: "px-1.5 py-0.5 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded text-[10px] font-mono border border-zinc-700",
1343                        children: "-5"
1344                      }
1345                    ),
1346                    /* @__PURE__ */ jsxRuntimeExports.jsx(
1347                      "button",
1348                      {
1349                        type: "button",
1350                        onClick: () => updateActiveConfig((prev) => ({
1351                          ...prev,
1352                          image: { ...prev.image || DEFAULT_STAGE_IMAGE, frontY: Math.min(620, effectiveFrontY + 5) }
1353                        })),
1354                        className: "px-1.5 py-0.5 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded text-[10px] font-mono border border-zinc-700",
1355                        children: "+5"
1356                      }
1357                    )
1358                  ] })
1359                ] }),
1360                /* @__PURE__ */ jsxRuntimeExports.jsx(
1361                  "input",
1362                  {
1363                    type: "range",
1364                    min: "400",
1365                    max: "600",
1366                    step: "5",
1367                    value: effectiveFrontY,
1368                    onChange: (e) => {
1369                      const val = parseInt(e.target.value);
1370                      updateActiveConfig((prev) => ({
1371                        ...prev,
1372                        image: { ...prev.image || DEFAULT_STAGE_IMAGE, frontY: val }
1373                      }));
1374                    },
1375                    className: "w-full accent-emerald-500 cursor-pointer"
1376                  }
1377                )
1378              ] })
1379            ] }),
1380            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-2 border-t border-zinc-800/80 flex items-center justify-between text-xs", children: [
1381              /* @__PURE__ */ jsxRuntimeExports.jsxs(
1382                "button",
1383                {
1384                  type: "button",
1385                  onClick: resetDepthToDefaults,
1386                  className: "text-zinc-400 hover:text-cyan-300 flex items-center gap-1 transition-colors underline",
1387                  children: [
1388                    /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 12 }),
1389                    " Reset Depth"
1390                  ]
1391                }
1392              ),
1393              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] text-zinc-500", children: "Drag lines directly on stage ↕" })
1394            ] })
1395          ] })
1396        ] }),
1397        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900/80 border border-zinc-800 rounded-xl overflow-hidden shadow-lg transition-all", children: [
1398          /* @__PURE__ */ jsxRuntimeExports.jsxs(
1399            "button",
1400            {
1401              type: "button",
1402              onClick: () => toggleSection("camera"),
1403              className: "w-full px-4 py-3 flex items-center justify-between bg-zinc-900 hover:bg-zinc-850 transition-colors text-left select-none",
1404              children: [
1405                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1406                  /* @__PURE__ */ jsxRuntimeExports.jsx(Compass, { size: 16, className: "text-amber-400" }),
1407                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-bold text-white", children: "Stage Camera (Pan & Zoom)" })
1408                ] }),
1409                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1410                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[11px] font-mono text-amber-300 font-semibold bg-amber-500/10 border border-amber-500/20 px-2 py-0.5 rounded-full", children: [
1411                    effectiveScale.toFixed(2),
1412                    "x • ",
1413                    effectiveOffsetX > 0 ? `+${effectiveOffsetX}` : effectiveOffsetX,
1414                    "%, ",
1415                    effectiveOffsetY > 0 ? `+${effectiveOffsetY}` : effectiveOffsetY,
1416                    "%"
1417                  ] }),
1418                  openSections.camera ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 15, className: "text-zinc-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 15, className: "text-zinc-400" })
1419                ] })
1420              ]
1421            }
1422          ),
1423          openSections.camera && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-t border-zinc-800/80 space-y-4 bg-zinc-950/40", children: [
1424            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [
1425              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-zinc-400", children: "Position & Framing:" }),
1426              /* @__PURE__ */ jsxRuntimeExports.jsxs(
1427                "button",
1428                {
1429                  type: "button",
1430                  onClick: resetStageAlignment,
1431                  className: "text-xs text-zinc-400 hover:text-amber-300 flex items-center gap-1 transition-colors px-2 py-1 rounded bg-zinc-900 hover:bg-zinc-850 border border-zinc-800",
1432                  children: [
1433                    /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 12 }),
1434                    " Reset Alignment"
1435                  ]
1436                }
1437              )
1438            ] }),
1439            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1440              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1441                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-300 font-medium", children: "Stage Zoom (Scale)" }),
1442                /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-amber-400 font-bold", children: [
1443                  effectiveScale.toFixed(2),
1444                  "x"
1445                ] })
1446              ] }),
1447              /* @__PURE__ */ jsxRuntimeExports.jsx(
1448                "input",
1449                {
1450                  type: "range",
1451                  min: "1.00",
1452                  max: "2.50",
1453                  step: "0.01",
1454                  value: effectiveScale,
1455                  onChange: (e) => {
1456                    const val = parseFloat(e.target.value);
1457                    updateActiveConfig((prev) => ({
1458                      ...prev,
1459                      image: { ...prev.image || DEFAULT_STAGE_IMAGE, scale: val }
1460                    }));
1461                  },
1462                  className: "w-full accent-amber-500 cursor-pointer"
1463                }
1464              ),
1465              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-[10px] text-zinc-500 mt-0.5", children: [
1466                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "1.00x (Wide)" }),
1467                /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
1468                  "Default: ",
1469                  activeStageCalib.scale.toFixed(2),
1470                  "x"
1471                ] }),
1472                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "2.50x (Close)" })
1473              ] })
1474            ] }),
1475            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1476              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1477                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-300 font-medium", children: "Horizontal Shift (X Offset)" }),
1478                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1479                  effectiveOffsetX !== 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
1480                    "button",
1481                    {
1482                      type: "button",
1483                      onClick: () => {
1484                        updateActiveConfig((prev) => ({
1485                          ...prev,
1486                          image: { ...prev.image || DEFAULT_STAGE_IMAGE, offsetX: 0 }
1487                        }));
1488                      },
1489                      className: "text-[10px] text-zinc-400 hover:text-amber-300 transition-colors underline",
1490                      children: "Center X"
1491                    }
1492                  ),
1493                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-amber-400 font-bold", children: [
1494                    effectiveOffsetX > 0 ? `+${effectiveOffsetX}` : effectiveOffsetX,
1495                    "%"
1496                  ] })
1497                ] })
1498              ] }),
1499              /* @__PURE__ */ jsxRuntimeExports.jsx(
1500                "input",
1501                {
1502                  type: "range",
1503                  min: "-35",
1504                  max: "35",
1505                  step: "1",
1506                  value: effectiveOffsetX,
1507                  onChange: (e) => {
1508                    const val = parseInt(e.target.value);
1509                    updateActiveConfig((prev) => ({
1510                      ...prev,
1511                      image: { ...prev.image || DEFAULT_STAGE_IMAGE, offsetX: val }
1512                    }));
1513                  },
1514                  className: "w-full accent-amber-500 cursor-pointer"
1515                }
1516              ),
1517              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-[10px] text-zinc-500 mt-0.5", children: [
1518                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "-35% (Left)" }),
1519                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Center: 0%" }),
1520                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "+35% (Right)" })
1521              ] })
1522            ] }),
1523            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1524              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1525                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-300 font-medium", children: "Vertical Shift (Y Offset)" }),
1526                /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-amber-400 font-bold", children: [
1527                  effectiveOffsetY > 0 ? `+${effectiveOffsetY}` : effectiveOffsetY,
1528                  "%"
1529                ] })
1530              ] }),
1531              /* @__PURE__ */ jsxRuntimeExports.jsx(
1532                "input",
1533                {
1534                  type: "range",
1535                  min: "-25",
1536                  max: "35",
1537                  step: "1",
1538                  value: effectiveOffsetY,
1539                  onChange: (e) => {
1540                    const val = parseInt(e.target.value);
1541                    updateActiveConfig((prev) => ({
1542                      ...prev,
1543                      image: { ...prev.image || DEFAULT_STAGE_IMAGE, offsetY: val }
1544                    }));
1545                  },
1546                  className: "w-full accent-amber-500 cursor-pointer"
1547                }
1548              ),
1549              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-[10px] text-zinc-500 mt-0.5", children: [
1550                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "-25% (Up)" }),
1551                /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
1552                  "Default: ",
1553                  activeStageCalib.offsetY > 0 ? `+${activeStageCalib.offsetY}` : activeStageCalib.offsetY,
1554                  "%"
1555                ] }),
1556                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "+35% (Down)" })
1557              ] })
1558            ] }),
1559            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-2 border-t border-zinc-800/80 text-[11px] text-zinc-500 flex items-center gap-1.5", children: [
1560              /* @__PURE__ */ jsxRuntimeExports.jsx(Move, { size: 12, className: "text-amber-400" }),
1561              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Tip: Drag stage canvas directly to pan • Scroll mouse wheel to zoom" })
1562            ] })
1563          ] })
1564        ] }),
1565        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900/80 border border-zinc-800 rounded-xl overflow-hidden shadow-lg transition-all", children: [
1566          /* @__PURE__ */ jsxRuntimeExports.jsxs(
1567            "button",
1568            {
1569              type: "button",
1570              onClick: () => toggleSection("geometry"),
1571              className: "w-full px-4 py-3 flex items-center justify-between bg-zinc-900 hover:bg-zinc-850 transition-colors text-left select-none",
1572              children: [
1573                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1574                  /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { size: 16, className: "text-indigo-400" }),
1575                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-bold text-white", children: "Musicians & Seating Geometry" })
1576                ] }),
1577                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1578                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[11px] font-mono text-indigo-300 font-semibold bg-indigo-500/10 border border-indigo-500/20 px-2 py-0.5 rounded-full", children: [
1579                    sampleMusicianCount,
1580                    " musicians • ",
1581                    stageConfig.baseScale.toFixed(2),
1582                    "x scale"
1583                  ] }),
1584                  openSections.geometry ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 15, className: "text-zinc-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 15, className: "text-zinc-400" })
1585                ] })
1586              ]
1587            }
1588          ),
1589          openSections.geometry && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-t border-zinc-800/80 space-y-4 bg-zinc-950/40", children: [
1590            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1591              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-xs", children: [
1592                /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-zinc-300 font-medium", children: [
1593                  "Musicians on Stage: ",
1594                  /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "text-amber-400 font-mono", children: sampleMusicianCount })
1595                ] }),
1596                /* @__PURE__ */ jsxRuntimeExports.jsx(
1597                  "button",
1598                  {
1599                    type: "button",
1600                    onClick: () => setEnableDensityScaling(!enableDensityScaling),
1601                    className: `text-[10px] px-2 py-0.5 rounded border transition-colors ${enableDensityScaling ? "bg-indigo-500/20 text-indigo-300 border-indigo-500/40" : "bg-zinc-800 text-zinc-400 border-zinc-700"}`,
1602                    children: enableDensityScaling ? "Crowd Scale: Auto" : "Crowd Scale: Off"
1603                  }
1604                )
1605              ] }),
1606              /* @__PURE__ */ jsxRuntimeExports.jsx(
1607                "input",
1608                {
1609                  type: "range",
1610                  min: "1",
1611                  max: "24",
1612                  step: "1",
1613                  value: sampleMusicianCount,
1614                  onChange: (e) => setSampleMusicianCount(parseInt(e.target.value)),
1615                  className: "w-full accent-amber-500 cursor-pointer"
1616                }
1617              ),
1618              /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1 flex-wrap", children: [
1619                { count: 1, label: "1 Solo" },
1620                { count: 3, label: "3 Trio" },
1621                { count: 5, label: "5 Band" },
1622                { count: 8, label: "8 Chamber" },
1623                { count: 12, label: "12 Big Band" },
1624                { count: 18, label: "18 Orchestra" },
1625                { count: 24, label: "24 Symphony" }
1626              ].map((preset) => /* @__PURE__ */ jsxRuntimeExports.jsx(
1627                "button",
1628                {
1629                  type: "button",
1630                  onClick: () => setSampleMusicianCount(preset.count),
1631                  className: `px-2 py-1 rounded text-[10px] font-semibold border transition-all ${sampleMusicianCount === preset.count ? "bg-amber-500 text-black border-amber-400 shadow-sm" : "bg-zinc-900 hover:bg-zinc-800 text-zinc-400 hover:text-white border-zinc-800"}`,
1632                  children: preset.label
1633                },
1634                preset.count
1635              )) })
1636            ] }),
1637            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3 pt-2 border-t border-zinc-800/80", children: [
1638              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1639                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1640                  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "font-semibold text-zinc-200", children: "Puppet Scale" }),
1641                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-bold text-amber-400", children: [
1642                    stageConfig.baseScale.toFixed(2),
1643                    "x"
1644                  ] })
1645                ] }),
1646                /* @__PURE__ */ jsxRuntimeExports.jsx(
1647                  "input",
1648                  {
1649                    type: "range",
1650                    min: "0.5",
1651                    max: "2.0",
1652                    step: "0.05",
1653                    value: stageConfig.baseScale,
1654                    onChange: (e) => setStageConfig({ ...stageConfig, baseScale: parseFloat(e.target.value) }),
1655                    className: "w-full accent-amber-500 cursor-pointer"
1656                  }
1657                )
1658              ] }),
1659              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1660                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1661                  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "font-semibold text-zinc-200", children: "Row Multiplier" }),
1662                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-bold text-indigo-400", children: [
1663                    stageConfig.rowScaleMultiplier.toFixed(2),
1664                    "x"
1665                  ] })
1666                ] }),
1667                /* @__PURE__ */ jsxRuntimeExports.jsx(
1668                  "input",
1669                  {
1670                    type: "range",
1671                    min: "0.6",
1672                    max: "1.2",
1673                    step: "0.02",
1674                    value: stageConfig.rowScaleMultiplier,
1675                    onChange: (e) => setStageConfig({ ...stageConfig, rowScaleMultiplier: parseFloat(e.target.value) }),
1676                    className: "w-full accent-indigo-500 cursor-pointer"
1677                  }
1678                )
1679              ] }),
1680              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1681                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1682                  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "font-semibold text-zinc-200", children: "Global Y Offset" }),
1683                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-bold text-emerald-400", children: [
1684                    stageConfig.yOffset,
1685                    "px"
1686                  ] })
1687                ] }),
1688                /* @__PURE__ */ jsxRuntimeExports.jsx(
1689                  "input",
1690                  {
1691                    type: "range",
1692                    min: "-120",
1693                    max: "120",
1694                    step: "5",
1695                    value: stageConfig.yOffset,
1696                    onChange: (e) => setStageConfig({ ...stageConfig, yOffset: parseInt(e.target.value) }),
1697                    className: "w-full accent-emerald-500 cursor-pointer"
1698                  }
1699                )
1700              ] }),
1701              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1702                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1 text-xs", children: [
1703                  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "font-semibold text-zinc-200", children: "Arc Curvature" }),
1704                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-bold text-rose-400", children: [
1705                    (stageConfig.arcFactor ?? 1).toFixed(2),
1706                    "x"
1707                  ] })
1708                ] }),
1709                /* @__PURE__ */ jsxRuntimeExports.jsx(
1710                  "input",
1711                  {
1712                    type: "range",
1713                    min: "0.0",
1714                    max: "2.5",
1715                    step: "0.1",
1716                    value: stageConfig.arcFactor ?? 1,
1717                    onChange: (e) => setStageConfig({ ...stageConfig, arcFactor: parseFloat(e.target.value) }),
1718                    className: "w-full accent-rose-500 cursor-pointer"
1719                  }
1720                )
1721              ] })
1722            ] }),
1723            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-2 border-t border-zinc-800/80 flex justify-between items-center", children: [
1724              /* @__PURE__ */ jsxRuntimeExports.jsxs(
1725                "button",
1726                {
1727                  type: "button",
1728                  onClick: () => setShowArcGuides(!showArcGuides),
1729                  className: `px-2.5 py-1 rounded text-xs font-medium border flex items-center gap-1.5 transition-colors ${showArcGuides ? "bg-indigo-500/20 text-indigo-300 border-indigo-500/40" : "bg-zinc-900 text-zinc-500 border-zinc-800 hover:text-white"}`,
1730                  children: [
1731                    /* @__PURE__ */ jsxRuntimeExports.jsx(Compass, { size: 12 }),
1732                    " ",
1733                    showArcGuides ? "Hide Arc Guides" : "Show Arc Guides"
1734                  ]
1735                }
1736              ),
1737              /* @__PURE__ */ jsxRuntimeExports.jsxs(
1738                "button",
1739                {
1740                  type: "button",
1741                  onClick: () => setStageConfig({
1742                    rows: 4,
1743                    spacingX: 80,
1744                    spacingY: 60,
1745                    baseScale: 1,
1746                    rowScaleMultiplier: 0.9,
1747                    yOffset: 0,
1748                    arcFactor: 1
1749                  }),
1750                  className: "text-xs text-zinc-400 hover:text-white flex items-center gap-1 transition-colors",
1751                  children: [
1752                    /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 12 }),
1753                    " Reset Geometry"
1754                  ]
1755                }
1756              )
1757            ] })
1758          ] })
1759        ] }),
1760        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900/80 border border-zinc-800 rounded-xl overflow-hidden shadow-lg transition-all", children: [
1761          /* @__PURE__ */ jsxRuntimeExports.jsxs(
1762            "button",
1763            {
1764              type: "button",
1765              onClick: () => toggleSection("atmosphere"),
1766              className: "w-full px-4 py-3 flex items-center justify-between bg-zinc-900 hover:bg-zinc-850 transition-colors text-left select-none",
1767              children: [
1768                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1769                  /* @__PURE__ */ jsxRuntimeExports.jsx(Lightbulb, { size: 16, className: "text-amber-400" }),
1770                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-bold text-white", children: "Stage Lighting & Atmosphere" })
1771                ] }),
1772                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1773                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[11px] font-mono text-amber-300 font-semibold bg-amber-500/10 border border-amber-500/20 px-2 py-0.5 rounded-full capitalize", children: [
1774                    previewLighting,
1775                    " • ",
1776                    previewPhysics
1777                  ] }),
1778                  openSections.atmosphere ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 15, className: "text-zinc-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 15, className: "text-zinc-400" })
1779                ] })
1780              ]
1781            }
1782          ),
1783          openSections.atmosphere && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-t border-zinc-800/80 space-y-4 bg-zinc-950/40", children: [
1784            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [
1785              /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-300 block", children: "Lighting Mode" }),
1786              /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-3 gap-1.5", children: ["dynamic", "subtle", "off"].map((mode) => /* @__PURE__ */ jsxRuntimeExports.jsx(
1787                "button",
1788                {
1789                  type: "button",
1790                  onClick: () => setPreviewLighting(mode),
1791                  className: `py-1.5 text-xs font-semibold rounded-lg capitalize border transition-all ${previewLighting === mode ? "bg-amber-500/20 text-amber-300 border-amber-500/40 shadow-sm" : "bg-zinc-900 text-zinc-400 border-zinc-800 hover:text-white"}`,
1792                  children: mode
1793                },
1794                mode
1795              )) })
1796            ] }),
1797            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3 pt-2 border-t border-zinc-800/80", children: [
1798              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1799                /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-300 block mb-1", children: "Character Physics" }),
1800                /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-1", children: ["snappy", "smooth"].map((p) => /* @__PURE__ */ jsxRuntimeExports.jsx(
1801                  "button",
1802                  {
1803                    type: "button",
1804                    onClick: () => setPreviewPhysics(p),
1805                    className: `py-1 text-xs rounded border capitalize font-medium ${previewPhysics === p ? "bg-indigo-600 text-white border-indigo-500" : "bg-zinc-900 text-zinc-400 border-zinc-800"}`,
1806                    children: p
1807                  },
1808                  p
1809                )) })
1810              ] }),
1811              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1812                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1", children: [
1813                  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-300", children: "Background Blur" }),
1814                  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-mono text-zinc-400", children: [
1815                    ((_o = activeConfig.image) == null ? void 0 : _o.blur) ?? 0,
1816                    "px"
1817                  ] })
1818                ] }),
1819                /* @__PURE__ */ jsxRuntimeExports.jsx(
1820                  "input",
1821                  {
1822                    type: "range",
1823                    min: "0",
1824                    max: "20",
1825                    step: "1",
1826                    value: ((_p = activeConfig.image) == null ? void 0 : _p.blur) ?? 0,
1827                    onChange: (e) => updateActiveConfig((prev) => ({
1828                      ...prev,
1829                      image: { ...prev.image || DEFAULT_STAGE_IMAGE, blur: parseInt(e.target.value) }
1830                    })),
1831                    className: "w-full accent-indigo-500 cursor-pointer"
1832                  }
1833                )
1834              ] })
1835            ] }),
1836            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-2 border-t border-zinc-800/80 space-y-2.5", children: [
1837              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
1838                /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-200", children: "Atmospheric Tint Overlay" }),
1839                /* @__PURE__ */ jsxRuntimeExports.jsx(
1840                  "input",
1841                  {
1842                    type: "checkbox",
1843                    checked: ((_q = activeConfig.overlay) == null ? void 0 : _q.enabled) ?? false,
1844                    onChange: (e) => updateActiveConfig((prev) => ({
1845                      ...prev,
1846                      overlay: { ...prev.overlay || DEFAULT_STAGE_OVERLAY, enabled: e.target.checked }
1847                    })),
1848                    className: "w-4 h-4 accent-indigo-600 rounded cursor-pointer"
1849                  }
1850                )
1851              ] }),
1852              ((_r = activeConfig.overlay) == null ? void 0 : _r.enabled) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3 bg-zinc-950 p-2.5 rounded-lg border border-zinc-800", children: [
1853                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1854                  /* @__PURE__ */ jsxRuntimeExports.jsx(
1855                    "input",
1856                    {
1857                      type: "color",
1858                      value: ((_s = activeConfig.overlay) == null ? void 0 : _s.color) || "#000000",
1859                      onChange: (e) => updateActiveConfig((prev) => ({
1860                        ...prev,
1861                        overlay: { ...prev.overlay || DEFAULT_STAGE_OVERLAY, color: e.target.value }
1862                      })),
1863                      className: "w-6 h-6 rounded border border-zinc-700 bg-transparent cursor-pointer"
1864                    }
1865                  ),
1866                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-mono text-zinc-300", children: (_t = activeConfig.overlay) == null ? void 0 : _t.color })
1867                ] }),
1868                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1869                  /* @__P
1869URE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-0.5", children: [
1870                    /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] text-zinc-400", children: "Opacity" }),
1871                    /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[11px] font-mono text-indigo-400", children: [
1872                      Math.round((((_u = activeConfig.overlay) == null ? void 0 : _u.opacity) ?? 0.15) * 100),
1873                      "%"
1874                    ] })
1875                  ] }),
1876                  /* @__PURE__ */ jsxRuntimeExports.jsx(
1877                    "input",
1878                    {
1879                      type: "range",
1880                      min: "0",
1881                      max: "1",
1882                      step: "0.05",
1883                      value: ((_v = activeConfig.overlay) == null ? void 0 : _v.opacity) ?? 0.15,
1884                      onChange: (e) => updateActiveConfig((prev) => ({
1885                        ...prev,
1886                        overlay: { ...prev.overlay || DEFAULT_STAGE_OVERLAY, opacity: parseFloat(e.target.value) }
1887                      })),
1888                      className: "w-full accent-indigo-500 cursor-pointer h-1.5"
1889                    }
1890                  )
1891                ] })
1892              ] })
1893            ] }),
1894            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-2 border-t border-zinc-800/80 space-y-2.5", children: [
1895              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
1896                /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-semibold text-zinc-200 flex items-center gap-1.5", children: [
1897                  /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 13, className: "text-indigo-400" }),
1898                  " Particle System"
1899                ] }),
1900                /* @__PURE__ */ jsxRuntimeExports.jsx(
1901                  "input",
1902                  {
1903                    type: "checkbox",
1904                    checked: ((_w = activeConfig.particles) == null ? void 0 : _w.enabled) ?? false,
1905                    onChange: (e) => updateActiveConfig((prev) => ({
1906                      ...prev,
1907                      particles: { ...prev.particles || DEFAULT_STAGE_PARTICLES, enabled: e.target.checked }
1908                    })),
1909                    className: "w-4 h-4 accent-indigo-600 rounded cursor-pointer"
1910                  }
1911                )
1912              ] }),
1913              ((_x = activeConfig.particles) == null ? void 0 : _x.enabled) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 bg-zinc-950 p-2.5 rounded-lg border border-zinc-800", children: [
1914                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1915                  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-[11px] text-zinc-400 block mb-1", children: "Style" }),
1916                  /* @__PURE__ */ jsxRuntimeExports.jsx(
1917                    "select",
1918                    {
1919                      value: ((_y = activeConfig.particles) == null ? void 0 : _y.type) || "stars",
1920                      onChange: (e) => updateActiveConfig((prev) => ({
1921                        ...prev,
1922                        particles: { ...prev.particles || DEFAULT_STAGE_PARTICLES, type: e.target.value }
1923                      })),
1924                      className: "w-full bg-zinc-900 border border-zinc-700 text-zinc-100 text-xs px-2 py-1 rounded-lg focus:outline-none",
1925                      children: PARTICLE_OPTIONS.map((opt) => /* @__PURE__ */ jsxRuntimeExports.jsxs("option", { value: opt.id, className: "bg-zinc-900 text-white", children: [
1926                        opt.icon,
1927                        " ",
1928                        opt.label
1929                      ] }, opt.id))
1930                    }
1931                  )
1932                ] }),
1933                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1934                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1935                    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-[11px] text-zinc-400 mb-0.5", children: [
1936                      /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Count" }),
1937                      /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-zinc-300", children: ((_z = activeConfig.particles) == null ? void 0 : _z.count) ?? 50 })
1938                    ] }),
1939                    /* @__PURE__ */ jsxRuntimeExports.jsx(
1940                      "input",
1941                      {
1942                        type: "range",
1943                        min: "10",
1944                        max: "150",
1945                        step: "5",
1946                        value: ((_A = activeConfig.particles) == null ? void 0 : _A.count) ?? 50,
1947                        onChange: (e) => updateActiveConfig((prev) => ({
1948                          ...prev,
1949                          particles: { ...prev.particles || DEFAULT_STAGE_PARTICLES, count: parseInt(e.target.value) }
1950                        })),
1951                        className: "w-full accent-indigo-500 cursor-pointer h-1.5"
1952                      }
1953                    )
1954                  ] }),
1955                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1956                    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-[11px] text-zinc-400 mb-0.5", children: [
1957                      /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Speed" }),
1958                      /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-zinc-300", children: [
1959                        (((_B = activeConfig.particles) == null ? void 0 : _B.speed) ?? 1).toFixed(1),
1960                        "x"
1961                      ] })
1962                    ] }),
1963                    /* @__PURE__ */ jsxRuntimeExports.jsx(
1964                      "input",
1965                      {
1966                        type: "range",
1967                        min: "0.2",
1968                        max: "3.0",
1969                        step: "0.1",
1970                        value: ((_C = activeConfig.particles) == null ? void 0 : _C.speed) ?? 1,
1971                        onChange: (e) => updateActiveConfig((prev) => ({
1972                          ...prev,
1973                          particles: { ...prev.particles || DEFAULT_STAGE_PARTICLES, speed: parseFloat(e.target.value) }
1974                        })),
1975                        className: "w-full accent-indigo-500 cursor-pointer h-1.5"
1976                      }
1977                    )
1978                  ] })
1979                ] })
1980              ] })
1981            ] })
1982          ] })
1983        ] })
1984      ] })
1985    ] }),
1986    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 xl:grid-cols-12 gap-8 items-start pt-4 border-t border-zinc-800/80", children: [
1987      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "xl:col-span-7 space-y-4", children: [
1988        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 border-b border-zinc-800 pb-3", children: [
1989          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1990            /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { size: 18, className: "text-indigo-400" }),
1991            /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-base font-bold text-white", children: "Stage Backgrounds Gallery" }),
1992            /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-zinc-500 font-mono", children: [
1993              "(",
1994              filteredPresets.length + 1,
1995              " stages)"
1996            ] })
1997          ] }),
1998          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 bg-zinc-950 p-1 rounded-xl border border-zinc-800 text-xs", children: [
1999            /* @__PURE__ */ jsxRuntimeExports.jsx(
2000              "button",
2001              {
2002                onClick: () => setGalleryFilter("all"),
2003                className: `px-2.5 py-1 rounded-lg font-medium transition-colors ${galleryFilter === "all" ? "bg-indigo-600 text-white shadow" : "text-zinc-400 hover:text-white"}`,
2004                children: "All"
2005              }
2006            ),
2007            /* @__PURE__ */ jsxRuntimeExports.jsxs(
2008              "button",
2009              {
2010                onClick: () => setGalleryFilter("sp_overrides"),
2011                className: `px-2.5 py-1 rounded-lg font-medium transition-colors ${galleryFilter === "sp_overrides" ? "bg-indigo-600 text-white shadow" : "text-zinc-400 hover:text-white"}`,
2012                children: [
2013                  "SP Overrides (",
2014                  spBackgroundPresets.length,
2015                  ")"
2016                ]
2017              }
2018            ),
2019            /* @__PURE__ */ jsxRuntimeExports.jsx(
2020              "button",
2021              {
2022                onClick: () => setGalleryFilter("shared"),
2023                className: `px-2.5 py-1 rounded-lg font-medium transition-colors ${galleryFilter === "shared" ? "bg-indigo-600 text-white shadow" : "text-zinc-400 hover:text-white"}`,
2024                children: "Orchestra"
2025              }
2026            ),
2027            /* @__PURE__ */ jsxRuntimeExports.jsxs(
2028              "button",
2029              {
2030                onClick: () => setGalleryFilter("custom"),
2031                className: `px-2.5 py-1 rounded-lg font-medium transition-colors ${galleryFilter === "custom" ? "bg-indigo-600 text-white shadow" : "text-zinc-400 hover:text-white"}`,
2032                children: [
2033                  "Uploads (",
2034                  customBackgrounds.length,
2035                  ")"
2036                ]
2037              }
2038            )
2039          ] })
2040        ] }),
2041        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
2042          /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { size: 14, className: "absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500" }),
2043          /* @__PURE__ */ jsxRuntimeExports.jsx(
2044            "input",
2045            {
2046              type: "text",
2047              value: searchQuery,
2048              onChange: (e) => setSearchQuery(e.target.value),
2049              placeholder: "Filter presets by name or matching tags...",
2050              className: "w-full bg-zinc-950 border border-zinc-800 rounded-xl pl-8 pr-3 py-1.5 text-xs text-white placeholder-zinc-500 focus:outline-none focus:border-indigo-500"
2051            }
2052          )
2053        ] }),
2054        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-3 max-h-[640px] overflow-y-auto pr-1 custom-scrollbar", children: [
2055          (galleryFilter === "all" || galleryFilter === "shared") && /* @__PURE__ */ jsxRuntimeExports.jsxs(
2056            "div",
2057            {
2058              onClick: () => setSelectedPresetId(null),
2059              className: `group relative rounded-xl border overflow-hidden cursor-pointer transition-all duration-200 shadow-md ${selectedPresetId === null ? "border-purple-500 ring-2 ring-purple-500/50 scale-[1.02]" : "border-zinc-800 hover:border-zinc-700 bg-zinc-900/60"}`,
2060              children: [
2061                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "aspect-video w-full bg-gradient-to-br from-purple-950 via-zinc-900 to-indigo-950 relative overflow-hidden flex items-center justify-center", children: [
2062                  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 opacity-30 mix-blend-overlay", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
2063                    "img",
2064                    {
2065                      src: ((_F = (_E = (_D = mergedPresets[shufflePreviewIndex % Math.max(1, mergedPresets.length)]) == null ? void 0 : _D.config) == null ? void 0 : _E.image) == null ? void 0 : _F.url) || "/assets/visualizers/orchestra/bkg/anime.jpg",
2066                      alt: "Shuffle Preview",
2067                      className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
2068                    }
2069                  ) }),
2070                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative z-10 text-center p-3", children: [
2071                    /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl block mb-1", children: "🎲" }),
2072                    /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] font-bold text-purple-200 tracking-wide block", children: "Stage Randomizer" }),
2073                    /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[9px] text-purple-300/80 font-mono", children: [
2074                      mergedPresets.length,
2075                      " Stages Pool"
2076                    ] })
2077                  ] }),
2078                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute top-1.5 left-1.5 bg-black/80 backdrop-blur-sm text-[10px] font-bold text-purple-400 px-2 py-0.5 rounded-full border border-purple-500/30 flex items-center gap-1", children: "🎲 Dynamic Shuffle" }),
2079                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute top-1.5 right-1.5 bg-purple-600 text-white text-[9px] font-extrabold px-1.5 py-0.5 rounded shadow", children: "Untagged Songs" })
2080                ] }),
2081                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-2.5 bg-zinc-950/90", children: [
2082                  /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-xs font-bold text-white truncate", children: "Dynamic Stage Shuffle" }),
2083                  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-zinc-400 truncate mt-0.5", children: "Random stage when no genre matches" })
2084                ] })
2085              ]
2086            }
2087          ),
2088          filteredPresets.map((preset) => {
2089            var _a2, _b2;
2090            const isSelected = selectedPresetId === preset.id;
2091            const partMeta = PARTICLE_OPTIONS.find((p) => {
2092              var _a3, _b3;
2093              return p.id === ((_b3 = (_a3 = preset.config) == null ? void 0 : _a3.particles) == null ? void 0 : _b3.type);
2094            }) || PARTICLE_OPTIONS[0];
2095            return /* @__PURE__ */ jsxRuntimeExports.jsxs(
2096              "div",
2097              {
2098                onClick: () => setSelectedPresetId(preset.id),
2099                className: `group relative rounded-xl border overflow-hidden cursor-pointer transition-all duration-200 shadow-md ${isSelected ? "border-indigo-500 ring-2 ring-indigo-500/50 scale-[1.02]" : "border-zinc-800 hover:border-zinc-700 bg-zinc-900/60"}`,
2100                children: [
2101                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "aspect-video w-full bg-zinc-950 relative overflow-hidden", children: [
2102                    ((_b2 = (_a2 = preset.config) == null ? void 0 : _a2.image) == null ? void 0 : _b2.url) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
2103                      "img",
2104                      {
2105                        src: preset.config.image.url,
2106                        alt: preset.name,
2107                        className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
2108                      }
2109                    ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full h-full flex items-center justify-center bg-zinc-900 text-zinc-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { size: 24 }) }),
2110                    /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "absolute top-1.5 left-1.5 bg-black/80 backdrop-blur-sm text-[10px] font-medium text-zinc-300 px-1.5 py-0.5 rounded border border-zinc-700", children: [
2111                      partMeta.icon,
2112                      " ",
2113                      partMeta.label.split(" ")[0]
2114                    ] }),
2115                    preset.isSpOverride && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute top-1.5 right-1.5 bg-amber-500 text-black text-[9px] font-extrabold px-1.5 py-0.5 rounded shadow", children: "SP Override" })
2116                  ] }),
2117                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-2.5 bg-zinc-950/90", children: [
2118                    /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-xs font-bold text-white truncate", children: preset.name }),
2119                    /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-zinc-400 truncate mt-0.5", children: preset.tags.length > 0 ? preset.tags.join(", ") : "no tags" })
2120                  ] })
2121                ]
2122              },
2123              preset.id
2124            );
2125          })
2126        ] }),
2127        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900/60 border border-dashed border-zinc-800 rounded-xl p-4 space-y-3", children: [
2128          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between flex-wrap gap-2", children: [
2129            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2130              /* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "text-xs font-bold text-white flex items-center gap-1.5", children: [
2131                /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { size: 14, className: "text-indigo-400" }),
2132                " Upload Custom Stage Background"
2133              ] }),
2134              /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] text-zinc-400 mt-0.5", children: "Upload full HD 1920x1080 stage backgrounds (WebP, PNG, JPG)." })
2135            ] }),
2136            /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: `px-3 py-1.5 rounded-lg text-xs font-semibold bg-indigo-600 hover:bg-indigo-500 text-white cursor-pointer shadow transition-colors flex items-center gap-1.5 ${isUploading ? "opacity-50 pointer-events-none" : ""}`, children: [
2137              /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { size: 13 }),
2138              " ",
2139              isUploading ? "Uploading..." : "Choose File",
2140              /* @__PURE__ */ jsxRuntimeExports.jsx(
2141                "input",
2142                {
2143                  ref: fileInputRef,
2144                  type: "file",
2145                  accept: "image/*",
2146                  onChange: handleUploadBackground,
2147                  className: "hidden"
2148                }
2149              )
2150            ] })
2151          ] }),
2152          uploadError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-rose-400 bg-rose-500/10 border border-rose-500/20 px-3 py-1.5 rounded-lg", children: uploadError }),
2153          customBackgrounds.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-2 border-t border-zinc-800", children: [
2154            /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] font-bold uppercase tracking-wider text-zinc-500 block mb-2", children: [
2155              "Your Custom Uploaded Stages (",
2156              customBackgrounds.length,
2157              ")"
2158            ] }),
2159            /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-3 sm:grid-cols-4 gap-2", children: customBackgrounds.map((url) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "group relative rounded-lg border border-zinc-800 overflow-hidden bg-black aspect-video", children: [
2160              /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: url, alt: "Uploaded custom", className: "w-full h-full object-cover" }),
2161              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2", children: [
2162                /* @__PURE__ */ jsxRuntimeExports.jsx(
2163                  "button",
2164                  {
2165                    onClick: () => updateActiveConfig((prev) => ({
2166                      ...prev,
2167                      type: "image",
2168                      image: { ...prev.image || DEFAULT_STAGE_IMAGE, url }
2169                    })),
2170                    className: "p-1.5 rounded bg-indigo-600 text-white hover:bg-indigo-500",
2171                    title: "Apply to active background",
2172                    children: /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 12 })
2173                  }
2174                ),
2175                /* @__PURE__ */ jsxRuntimeExports.jsx(
2176                  "button",
2177                  {
2178                    onClick: () => handleDeleteCustomBackground(url),
2179                    className: "p-1.5 rounded bg-rose-600 text-white hover:bg-rose-500",
2180                    title: "Delete this background",
2181                    children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { size: 12 })
2182                  }
2183                )
2184              ] })
2185            ] }, url)) })
2186          ] })
2187        ] })
2188      ] }),
2189      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "xl:col-span-5 bg-zinc-900/90 border border-zinc-800 rounded-2xl p-6 shadow-2xl space-y-6", children: [
2190        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between border-b border-zinc-800 pb-3", children: [
2191          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2192            /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-base font-bold text-white flex items-center gap-2", children: [
2193              /* @__PURE__ */ jsxRuntimeExports.jsx(SlidersVertical, { size: 16, className: "text-indigo-400" }),
2194              " Background Inspector"
2195            ] }),
2196            /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-zinc-400", children: [
2197              "Editing: ",
2198              /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "text-indigo-300", children: activePresetMeta.name })
2199            ] })
2200          ] }),
2201          selectedPresetId !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(
2202            "button",
2203            {
2204              onClick: () => {
2205                const newName = prompt("Enter new preset name:", activePresetMeta.name);
2206                if (newName) updatePresetMeta(newName);
2207              },
2208              className: "text-xs text-zinc-400 hover:text-white underline",
2209              children: "Rename"
2210            }
2211          )
2212        ] }),
2213        selectedPresetId === null ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 bg-purple-950/40 border border-purple-500/40 rounded-xl p-4 shadow-md", children: [
2214          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-purple-300", children: [
2215            /* @__PURE__ */ jsxRuntimeExports.jsx(Shuffle, { size: 16 }),
2216            /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-xs font-bold text-white uppercase tracking-wider", children: "Automatic Stage Randomization" })
2217          ] }),
2218          /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-zinc-300 leading-relaxed", children: [
2219            "Any song without matching genre tags automatically selects a random background from the pool of all ",
2220            /* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
2221              mergedPresets.length,
2222              " illustrated & custom backdrops"
2223            ] }),
2224            "."
2225          ] }),
2226          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-2 border-t border-purple-500/20 flex items-center justify-between gap-2 flex-wrap", children: [
2227            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] text-purple-300 font-medium", children: "Workshop Preview:" }),
2228            /* @__PURE__ */ jsxRuntimeExports.jsxs(
2229              "button",
2230              {
2231                type: "button",
2232                onClick: () => setShufflePreviewIndex((prev) => (prev + 1) % Math.max(1, mergedPresets.length)),
2233                className: "px-2.5 py-1 rounded bg-purple-600 hover:bg-purple-500 text-white text-[11px] font-bold flex items-center gap-1.5 transition-colors shadow",
2234                children: [
2235                  /* @__PURE__ */ jsxRuntimeExports.jsx(Shuffle, { size: 11 }),
2236                  " Next Random Stage (",
2237                  shufflePreviewIndex + 1,
2238                  "/",
2239                  mergedPresets.length,
2240                  ")"
2241                ]
2242              }
2243            )
2244          ] })
2245        ] }) : (
2246          /* Tag Binding (for presets) */
2247          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5 bg-zinc-950 p-3.5 rounded-xl border border-zinc-800", children: [
2248            /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-bold text-zinc-300 uppercase tracking-wider block", children: "Matching Genre Tags" }),
2249            /* @__PURE__ */ jsxRuntimeExports.jsx(
2250              "input",
2251              {
2252                type: "text",
2253                value: activePresetMeta.tags.join(", "),
2254                onChange: (e) => {
2255                  const tags = e.target.value.split(",").map((t) => t.trim()).filter(Boolean);
2256                  updatePresetMeta(void 0, tags);
2257                },
2258                placeholder: "e.g. classical, soundtrack, orchestra, piano",
2259                className: "w-full bg-zinc-900 border border-zinc-700 text-white text-xs px-3 py-2 rounded-lg focus:outline-none focus:border-indigo-500"
2260              }
2261            ),
2262            /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] text-zinc-500", children: "Songs containing any of these tags automatically activate this stage." })
2263          ] })
2264        ),
2265        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
2266          /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-bold text-zinc-400 uppercase tracking-wider block", children: "Background Type" }),
2267          /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-3 gap-1.5 bg-zinc-950 p-1 rounded-xl border border-zinc-800", children: ["image", "gradient", "color"].map((type) => /* @__PURE__ */ jsxRuntimeExports.jsx(
2268            "button",
2269            {
2270              onClick: () => updateActiveConfig((prev) => ({ ...prev, type })),
2271              className: `py-1.5 text-xs font-bold rounded-lg capitalize transition-all ${activeConfig.type === type ? "bg-indigo-600 text-white shadow" : "text-zinc-400 hover:text-white"}`,
2272              children: type
2273            },
2274            type
2275          )) })
2276        ] }),
2277        activeConfig.type === "image" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 bg-zinc-950 p-4 rounded-xl border border-zinc-800", children: [
2278          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [
2279            /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-300", children: "Image Asset URL" }),
2280            /* @__PURE__ */ jsxRuntimeExports.jsx(
2281              "input",
2282              {
2283                type: "text",
2284                value: ((_G = activeConfig.image) == null ? void 0 : _G.url) || "",
2285                onChange: (e) => updateActiveConfig((prev) => ({
2286                  ...prev,
2287                  image: { ...prev.image || DEFAULT_STAGE_IMAGE, url: e.target.value }
2288                })),
2289                placeholder: "/assets/visualizers/orchestra/bkg/classical.jpg",
2290                className: "w-full bg-zinc-900 border border-zinc-700 text-white text-xs px-3 py-2 rounded-lg font-mono"
2291              }
2292            )
2293          ] }),
2294          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
2295            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2296              /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-300 block mb-1", children: "Image Fit" }),
2297              /* @__PURE__ */ jsxRuntimeExports.jsxs(
2298                "select",
2299                {
2300                  value: ((_H = activeConfig.image) == null ? void 0 : _H.size) || "cover",
2301                  onChange: (e) => updateActiveConfig((prev) => ({
2302                    ...prev,
2303                    image: { ...prev.image || DEFAULT_STAGE_IMAGE, size: e.target.value }
2304                  })),
2305                  className: "w-full bg-zinc-900 border border-zinc-700 text-zinc-200 text-xs px-2.5 py-1.5 rounded-lg focus:outline-none",
2306                  children: [
2307                    /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "cover", className: "bg-zinc-900 text-white", children: "Cover (Full Stage)" }),
2308                    /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "contain", className: "bg-zinc-900 text-white", children: "Contain (Letterbox)" })
2309                  ]
2310                }
2311              )
2312            ] }),
2313            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2314              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-1", children: [
2315                /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-300", children: "Blur" }),
2316                /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-mono text-zinc-400", children: [
2317                  ((_I = activeConfig.image) == null ? void 0 : _I.blur) ?? 0,
2318                  "px"
2319                ] })
2320              ] }),
2321              /* @__PURE__ */ jsxRuntimeExports.jsx(
2322                "input",
2323                {
2324                  type: "range",
2325                  min: "0",
2326                  max: "20",
2327                  step: "1",
2328                  value: ((_J = activeConfig.image) == null ? void 0 : _J.blur) ?? 0,
2329                  onChange: (e) => updateActiveConfig((prev) => ({
2330                    ...prev,
2331                    image: { ...prev.image || DEFAULT_STAGE_IMAGE, blur: parseInt(e.target.value) }
2332                  })),
2333                  className: "w-full accent-indigo-500 cursor-pointer"
2334                }
2335              )
2336            ] })
2337          ] })
2338        ] }),
2339        activeConfig.type === "color" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 bg-zinc-950 p-4 rounded-xl border border-zinc-800", children: [
2340          /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-300 block", children: "Solid Background Color" }),
2341          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
2342            /* @__PURE__ */ jsxRuntimeExports.jsx(
2343              "input",
2344              {
2345                type: "color",
2346                value: activeConfig.color || "#1e1b4b",
2347                onChange: (e) => updateActiveConfig((prev) => ({ ...prev, color: e.target.value })),
2348                className: "w-8 h-8 rounded border border-zinc-700 bg-transparent cursor-pointer"
2349              }
2350            ),
2351            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-mono text-zinc-200", children: activeConfig.color || "#1e1b4b" })
2352          ] })
2353        ] }),
2354        activeConfig.type === "gradient" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 bg-zinc-950 p-4 rounded-xl border border-zinc-800", children: [
2355          /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-semibold text-zinc-300 block", children: "Gradient Background Colors" }),
2356          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
2357            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2358              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] text-zinc-400 block mb-1", children: "Color 1 (Top)" }),
2359              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
2360                /* @__PURE__ */ jsxRuntimeExports.jsx(
2361                  "input",
2362                  {
2363                    type: "color",
2364                    value: ((_M = (_L = (_K = activeConfig.gradient) == null ? void 0 : _K.stops) == null ? void 0 : _L[0]) == null ? void 0 : _M.color) || "#0f172a",
2365                    onChange: (e) => {
2366                      var _a2, _b2, _c2;
2367                      const c2 = ((_c2 = (_b2 = (_a2 = activeConfig.gradient) == null ? void 0 : _a2.stops) == null ? void 0 : _b2[1]) == null ? void 0 : _c2.color) || "#1e1b4b";
2368                      updateActiveConfig((prev) => {
2369                        var _a3, _b3;
2370                        return {
2371                          ...prev,
2372                          gradient: {
2373                            type: ((_a3 = prev.gradient) == null ? void 0 : _a3.type) || "linear",
2374                            angle: ((_b3 = prev.gradient) == null ? void 0 : _b3.angle) ?? 180,
2375                            stops: [
2376                              { color: e.target.value, offset: 0 },
2377                              { color: c2, offset: 100 }
2378                            ]
2379                          }
2380                        };
2381                      });
2382                    },
2383                    className: "w-7 h-7 rounded border border-zinc-700 bg-transparent cursor-pointer"
2384                  }
2385                ),
2386                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-mono text-zinc-300", children: ((_P = (_O = (_N = activeConfig.gradient) == null ? void 0 : _N.stops) == null ? void 0 : _O[0]) == null ? void 0 : _P.color) || "#0f172a" })
2387              ] })
2388            ] }),
2389            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2390              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] text-zinc-400 block mb-1", children: "Color 2 (Bottom)" }),
2391              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
2392                /* @__PURE__ */ jsxRuntimeExports.jsx(
2393                  "input",
2394                  {
2395                    type: "color",
2396                    value: ((_S = (_R = (_Q = activeConfig.gradient) == null ? void 0 : _Q.stops) == null ? void 0 : _R[1]) == null ? void 0 : _S.color) || "#1e1b4b",
2397                    onChange: (e) => {
2398                      var _a2, _b2, _c2;
2399                      const c1 = ((_c2 = (_b2 = (_a2 = activeConfig.gradient) == null ? void 0 : _a2.stops) == null ? void 0 : _b2[0]) == null ? void 0 : _c2.color) || "#0f172a";
2400                      updateActiveConfig((prev) => {
2401                        var _a3, _b3;
2402                        return {
2403                          ...prev,
2404                          gradient: {
2405                            type: ((_a3 = prev.gradient) == null ? void 0 : _a3.type) || "linear",
2406                            angle: ((_b3 = prev.gradient) == null ? void 0 : _b3.angle) ?? 180,
2407                            stops: [
2408                              { color: c1, offset: 0 },
2409                              { color: e.target.value, offset: 100 }
2410                            ]
2411                          }
2412                        };
2413                      });
2414                    },
2415                    className: "w-7 h-7 rounded border border-zinc-700 bg-transparent cursor-pointer"
2416                  }
2417                ),
2418                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-mono text-zinc-300", children: ((_V = (_U = (_T = activeConfig.gradient) == null ? void 0 : _T.stops) == null ? void 0 : _U[1]) == null ? void 0 : _V.color) || "#1e1b4b" })
2419              ] })
2420            ] })
2421          ] })
2422        ] }),
2423        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 bg-zinc-950 p-4 rounded-xl border border-zinc-800", children: [
2424          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
2425            /* @__PURE__ */ jsxRuntimeExports.jsx(CircleQuestionMark, { size: 15, className: "text-indigo-400" }),
2426            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2427              /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-xs font-bold text-zinc-200", children: "Simulate Track Genre / Tag Match" }),
2428              /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] text-zinc-400", children: "Test which stage background is automatically loaded for a given genre or tag." })
2429            ] })
2430          ] }),
2431          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
2432            /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { size: 14, className: "absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500" }),
2433            /* @__PURE__ */ jsxRuntimeExports.jsx(
2434              "input",
2435              {
2436                type: "text",
2437                value: simulationTagInput,
2438                onChange: (e) => setSimulationTagInput(e.target.value),
2439                placeholder: "Type tag or genre (e.g. anime, 8-bit, rock, piano)...",
2440                className: "w-full bg-zinc-900 border border-zinc-700 rounded-lg pl-8 pr-3 py-1.5 text-xs text-white focus:outline-none focus:border-indigo-500 font-medium"
2441              }
2442            )
2443          ] }),
2444          /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap items-center gap-1.5", children: POPULAR_SIMULATION_GENRES.slice(0, 8).map((g) => /* @__PURE__ */ jsxRuntimeExports.jsx(
2445            "button",
2446            {
2447              type: "button",
2448              onClick: () => setSimulationTagInput(g.tag),
2449              className: `px-2 py-0.5 rounded text-[10px] transition-colors border ${simulationTagInput.toLowerCase() === g.tag.toLowerCase() ? "bg-indigo-600 text-white border-indigo-500 font-semibold" : "bg-zinc-900 text-zinc-400 border-zinc-800 hover:text-white"}`,
2450              children: g.label
2451            },
2452            g.tag
2453          )) }),
2454          simulationResult && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 rounded-lg p-2.5 flex items-center justify-between gap-3", children: [
2455            /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2456              /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-zinc-400 block", children: simulationResult.reason }),
2457              /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-bold text-indigo-300 flex items-center gap-1.5", children: [
2458                "🎯 ",
2459                simulationResult.presetName,
2460                simulationResult.isSp && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] bg-amber-500/20 text-amber-300 px-1 py-0.2 rounded font-semibold", children: "SP Override" })
2461              ] })
2462            ] }),
2463            /* @__PURE__ */ jsxRuntimeExports.jsx(
2464              "button",
2465              {
2466                type: "button",
2467                onClick: () => setSelectedPresetId(simulationResult.presetId),
2468                className: "px-2.5 py-1 rounded text-[11px] font-semibold bg-indigo-600/30 hover:bg-indigo-600 text-indigo-200 hover:text-white border border-indigo-500/40 transition-colors shrink-0",
2469                children: "Inspect Stage"
2470              }
2471            )
2472          ] })
2473        ] })
2474      ] })
2475    ] })
2476  ] });
2477};
2478export {
2479  PARTICLE_OPTIONS,
2480  POPULAR_SIMULATION_GENRES,
2481  SouthparkStageDesigner
2482};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.