@hyperframes/studio 0.7.6 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/assets/{index-B_NnmU6q.js → index-B2YXvFxf.js} +1 -1
  2. package/dist/assets/index-BSkUuN8g.css +1 -0
  3. package/dist/assets/{index-ysftPins.js → index-BeRh2hMe.js} +195 -194
  4. package/dist/assets/{index-DsBhGFPe.js → index-BoASKOeE.js} +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.html +2 -2
  7. package/dist/index.js +1765 -1193
  8. package/dist/index.js.map +1 -1
  9. package/package.json +5 -5
  10. package/src/components/StudioRightPanel.tsx +2 -0
  11. package/src/components/editor/AnimationCard.tsx +6 -0
  12. package/src/components/editor/EaseCurveSection.tsx +175 -99
  13. package/src/components/editor/GsapAnimationSection.tsx +2 -0
  14. package/src/components/editor/KeyframeEaseList.tsx +67 -3
  15. package/src/components/editor/PropertyPanel.tsx +11 -2
  16. package/src/components/editor/gsapAnimationCallbacks.ts +2 -0
  17. package/src/components/editor/gsapAnimationConstants.ts +6 -35
  18. package/src/components/editor/gsapAnimationHelpers.test.ts +1 -1
  19. package/src/components/editor/propertyPanelHelpers.ts +6 -0
  20. package/src/components/editor/propertyPanelTimingSection.tsx +35 -2
  21. package/src/components/editor/useMotionPathData.ts +2 -1
  22. package/src/components/sidebar/AssetContextMenu.tsx +97 -0
  23. package/src/components/sidebar/AssetsTab.tsx +542 -254
  24. package/src/components/sidebar/assetHelpers.ts +40 -0
  25. package/src/contexts/DomEditContext.tsx +4 -0
  26. package/src/hooks/gsapDragCommit.ts +101 -0
  27. package/src/hooks/gsapRuntimeBridge.ts +22 -0
  28. package/src/hooks/gsapRuntimeKeyframes.test.ts +47 -0
  29. package/src/hooks/gsapRuntimeKeyframes.ts +13 -0
  30. package/src/hooks/useDomEditSession.ts +20 -0
  31. package/src/hooks/useDomEditWiring.ts +3 -0
  32. package/src/hooks/useGestureCommit.ts +0 -4
  33. package/src/hooks/useGsapAwareEditing.ts +0 -4
  34. package/src/hooks/useGsapScriptCommits.ts +0 -12
  35. package/src/hooks/useGsapTweenCache.test.ts +45 -1
  36. package/src/hooks/useGsapTweenCache.ts +119 -38
  37. package/src/hooks/useMusicBeatAnalysis.ts +36 -21
  38. package/src/hooks/useRazorSplit.ts +0 -3
  39. package/dist/assets/index-wJZf6FK3.css +0 -1
  40. package/src/utils/editDebugLog.ts +0 -9
@@ -69,6 +69,41 @@ function extractIdFromSelector(selector: string): string | null {
69
69
  return match ? match[1] : null;
70
70
  }
71
71
 
72
+ /**
73
+ * Resolve a tween's target selector to the ids of the element(s) it animates.
74
+ * A bare `#id` resolves directly; anything else (a class like `.dot`, a group
75
+ * `.a, .b`, or a descendant selector) is matched against the live preview DOM so
76
+ * class/selector tweens (e.g. `gsap.from(".dot", {stagger})`) attribute to every
77
+ * element they animate — not just one parsed from the string. Falls back to a
78
+ * leading `#id` when there's no DOM (so the cache still populates pre-iframe).
79
+ */
80
+ // fallow-ignore-next-line complexity
81
+ export function resolveSelectorElementIds(
82
+ selector: string,
83
+ doc: Document | null | undefined,
84
+ ): string[] {
85
+ const bareId = selector.match(/^#([\w-]+)$/);
86
+ if (bareId) return [bareId[1]];
87
+ if (!doc) {
88
+ const lead = extractIdFromSelector(selector);
89
+ return lead ? [lead] : [];
90
+ }
91
+ const ids = new Set<string>();
92
+ for (const part of selector.split(",")) {
93
+ const sel = part.trim();
94
+ if (!sel) continue;
95
+ try {
96
+ for (const el of Array.from(doc.querySelectorAll(sel))) {
97
+ if (el.id) ids.add(el.id);
98
+ }
99
+ } catch {
100
+ const lead = extractIdFromSelector(sel);
101
+ if (lead) ids.add(lead);
102
+ }
103
+ }
104
+ return Array.from(ids);
105
+ }
106
+
72
107
  /** The selected element's identity for matching tweens to it. */
73
108
  export interface GsapElementTarget {
74
109
  id?: string | null;
@@ -82,21 +117,37 @@ export interface GsapElementTarget {
82
117
  * (`.clock-face, .clock-hand`, emitted for array/`toArray` targets). Real
83
118
  * compositions target tweens by class via `querySelector`, so id-only matching
84
119
  * misses them.
120
+ *
121
+ * When the live DOM `element` is supplied, each comma-part of a tween's selector
122
+ * is also tested with `element.matches(part)` — true CSS semantics — so a
123
+ * class/descendant tween shared across elements (e.g. `gsap.from(".dot", {stagger})`)
124
+ * is attributed to *every* matching element, not just the one whose exact
125
+ * selector string happens to equal the tween's.
85
126
  */
86
127
  export function getAnimationsForElement(
87
128
  animations: GsapAnimation[],
88
129
  target: GsapElementTarget,
130
+ element?: Element | null,
89
131
  ): GsapAnimation[] {
90
132
  const matchers = new Set<string>();
91
133
  if (target.id) matchers.add(`#${target.id}`);
92
134
  if (target.selector) matchers.add(target.selector);
93
- if (matchers.size === 0) return [];
135
+ if (matchers.size === 0 && !element) return [];
94
136
  return animations.filter((a) =>
95
137
  a.targetSelector.split(",").some((part) => {
96
138
  const trimmed = part.trim();
139
+ if (!trimmed) return false;
97
140
  if (matchers.has(trimmed)) return true;
98
141
  const lastSimple = trimmed.split(/\s+/).pop();
99
- return lastSimple ? matchers.has(lastSimple) : false;
142
+ if (lastSimple && matchers.has(lastSimple)) return true;
143
+ if (element) {
144
+ try {
145
+ if (element.matches(trimmed)) return true;
146
+ } catch {
147
+ /* tween selector isn't a valid CSS selector for matches() — skip */
148
+ }
149
+ }
150
+ return false;
100
151
  }),
101
152
  );
102
153
  }
@@ -199,13 +250,30 @@ export function useGsapAnimationsForElement(
199
250
 
200
251
  const targetId = target?.id ?? null;
201
252
  const targetSelector = target?.selector ?? null;
202
- const rawAnimations = useMemo(
203
- () =>
204
- targetId || targetSelector
205
- ? getAnimationsForElement(allAnimations, { id: targetId, selector: targetSelector })
206
- : [],
207
- [allAnimations, targetId, targetSelector],
208
- );
253
+ const rawAnimations = useMemo(() => {
254
+ if (!targetId && !targetSelector) return [];
255
+ // Resolve the live element so class / descendant tweens (e.g.
256
+ // gsap.from(".dot", {stagger})) attribute to every matching element, not
257
+ // just the one whose exact selector equals the tween's. `version` re-runs
258
+ // this after composition reloads.
259
+ let element: Element | null = null;
260
+ const doc = iframeRef?.current?.contentDocument;
261
+ if (doc) {
262
+ try {
263
+ element =
264
+ (targetId ? doc.getElementById(targetId) : null) ??
265
+ (targetSelector ? doc.querySelector(targetSelector) : null);
266
+ } catch {
267
+ element = null;
268
+ }
269
+ }
270
+ return getAnimationsForElement(
271
+ allAnimations,
272
+ { id: targetId, selector: targetSelector },
273
+ element,
274
+ );
275
+ // eslint-disable-next-line react-hooks/exhaustive-deps
276
+ }, [allAnimations, targetId, targetSelector, version, iframeRef]);
209
277
 
210
278
  // fallow-ignore-next-line complexity
211
279
  const animations = useMemo(() => {
@@ -327,7 +395,14 @@ export function useGsapAnimationsForElement(
327
395
  if (kf.easeEach) easeEach = kf.easeEach;
328
396
  }
329
397
  if (allKeyframes.length === 0) {
330
- clearKeyframeCacheForElement(sourceFile, elementId);
398
+ // The per-element parsed-animation match can transiently miss class /
399
+ // selector tweens (e.g. `.dot`) that the file-wide populate or runtime
400
+ // scan already cached. Only clear when no source cached this element —
401
+ // otherwise selecting it would wipe its diamonds.
402
+ const { keyframeCache } = usePlayerStore.getState();
403
+ const hasCached =
404
+ keyframeCache.has(`${sourceFile}#${elementId}`) || keyframeCache.has(elementId);
405
+ if (!hasCached) clearKeyframeCacheForElement(sourceFile, elementId);
331
406
  return;
332
407
  }
333
408
  const dedupedKeyframes = deduplicateKeyframes(allKeyframes);
@@ -385,10 +460,9 @@ export function usePopulateKeyframeCacheForFile(
385
460
  const { setKeyframeCache } = usePlayerStore.getState();
386
461
  clearKeyframeCacheForFile(sf);
387
462
  const { elements } = usePlayerStore.getState();
463
+ const doc = iframeRef?.current?.contentDocument;
388
464
  const mergedByElement = new Map<string, GsapKeyframesData>();
389
465
  for (const anim of parsed.animations) {
390
- const id = extractIdFromSelector(anim.targetSelector);
391
- if (!id) continue;
392
466
  if (anim.hasUnresolvedKeyframes) continue;
393
467
  // Position-only set tweens are static holds (created by drag), not
394
468
  // keyframed animations — skip them so they don't show timeline diamonds.
@@ -403,32 +477,36 @@ export function usePopulateKeyframeCacheForFile(
403
477
  const tweenPos =
404
478
  anim.resolvedStart ?? (typeof anim.position === "number" ? anim.position : 0);
405
479
  const tweenDur = anim.duration ?? 1;
406
- const timelineEl = elements.find(
407
- (el) => el.domId === id || (el.key ?? el.id) === `${sf}#${id}`,
408
- );
409
- const elStart = timelineEl?.start ?? 0;
410
- const elDuration = timelineEl?.duration ?? 1;
411
- const clipKeyframes = kfData.keyframes.map((kf) => {
412
- const absTime = toAbsoluteTime(tweenPos, tweenDur, kf.percentage);
413
- // 0.001% precision (matching useGsapAnimationsForElement above) so a
414
- // beat-snapped keyframe centers exactly on the beat dot and the two
415
- // caches agree on a keyframe's percentage.
416
- const clipPct =
417
- elDuration > 0
418
- ? Math.round(((absTime - elStart) / elDuration) * 100000) / 1000
419
- : kf.percentage;
420
- return {
421
- ...kf,
422
- percentage: clipPct,
423
- tweenPercentage: kf.percentage,
424
- propertyGroup: anim.propertyGroup,
425
- };
426
- });
427
- const existing = mergedByElement.get(id);
428
- if (existing) {
429
- existing.keyframes = deduplicateKeyframes([...existing.keyframes, ...clipKeyframes]);
430
- } else {
431
- mergedByElement.set(id, { ...kfData, keyframes: clipKeyframes });
480
+ // Attribute the tween to every element it animates (handles class /
481
+ // group / descendant selectors, not just `#id`).
482
+ for (const id of resolveSelectorElementIds(anim.targetSelector, doc)) {
483
+ const timelineEl = elements.find(
484
+ (el) => el.domId === id || (el.key ?? el.id) === `${sf}#${id}`,
485
+ );
486
+ const elStart = timelineEl?.start ?? 0;
487
+ const elDuration = timelineEl?.duration ?? 1;
488
+ const clipKeyframes = kfData.keyframes.map((kf) => {
489
+ const absTime = toAbsoluteTime(tweenPos, tweenDur, kf.percentage);
490
+ // 0.001% precision (matching useGsapAnimationsForElement above) so a
491
+ // beat-snapped keyframe centers exactly on the beat dot and the two
492
+ // caches agree on a keyframe's percentage.
493
+ const clipPct =
494
+ elDuration > 0
495
+ ? Math.round(((absTime - elStart) / elDuration) * 100000) / 1000
496
+ : kf.percentage;
497
+ return {
498
+ ...kf,
499
+ percentage: clipPct,
500
+ tweenPercentage: kf.percentage,
501
+ propertyGroup: anim.propertyGroup,
502
+ };
503
+ });
504
+ const existing = mergedByElement.get(id);
505
+ if (existing) {
506
+ existing.keyframes = deduplicateKeyframes([...existing.keyframes, ...clipKeyframes]);
507
+ } else {
508
+ mergedByElement.set(id, { ...kfData, keyframes: clipKeyframes });
509
+ }
432
510
  }
433
511
  }
434
512
  for (const [id, kfData] of mergedByElement) {
@@ -441,6 +519,9 @@ export function usePopulateKeyframeCacheForFile(
441
519
  // elementCount is in the deps because new timeline elements (e.g. after a
442
520
  // sub-composition expand) need their keyframe cache populated immediately;
443
521
  // without it the effect won't re-run when elements appear/disappear.
522
+ // iframeRef is read for DOM selector resolution but intentionally not a dep
523
+ // (it's a stable ref; the separate runtime-scan effect owns iframe timing).
524
+ // eslint-disable-next-line react-hooks/exhaustive-deps
444
525
  }, [projectId, sourceFile, version, elementCount]);
445
526
 
446
527
  // Separate effect for runtime keyframe discovery — polls until the iframe
@@ -92,33 +92,48 @@ export function useMusicBeatAnalysis(): void {
92
92
  return;
93
93
  }
94
94
  let cancelled = false;
95
-
96
- let promise = analysisCache.get(musicSrc);
97
- if (!promise) {
98
- promise = analyzeMusicFromUrl(musicSrc);
99
- cacheAnalysis(musicSrc, promise);
100
- }
101
-
102
95
  const beatPath = beatFilePathForSrc(musicSrc);
103
- promise
104
- .then(async (analysis) => {
96
+ const io = ioRef.current;
97
+
98
+ // Only run expensive audio decode + beat analysis when the user has an
99
+ // explicit beats file saved. Without one, skip entirely — no surprise
100
+ // green lines on the timeline after dragging unrelated assets.
101
+ (async () => {
102
+ if (!beatPath || !io) return;
103
+ let hasSavedBeats = false;
104
+ try {
105
+ const content = await io.readOptionalProjectFile(beatPath);
106
+ const parsed = content ? parseBeats(content) : null;
107
+ hasSavedBeats = !!(parsed && parsed.times.length > 0);
108
+ } catch {
109
+ /* no file */
110
+ }
111
+ if (cancelled) return;
112
+ if (!hasSavedBeats) {
113
+ setBeatAnalysis(null);
114
+ return;
115
+ }
116
+
117
+ let promise = analysisCache.get(musicSrc);
118
+ if (!promise) {
119
+ promise = analyzeMusicFromUrl(musicSrc);
120
+ cacheAnalysis(musicSrc, promise);
121
+ }
122
+ try {
123
+ const analysis = await promise;
105
124
  const detected = { times: analysis.beatTimes, strengths: analysis.beatStrengths };
106
- const io = ioRef.current;
107
- if (!io) return;
108
- const { times, strengths, hasFile } = await resolveBeats(beatPath, detected, io);
125
+ const { times, strengths } = await resolveBeats(beatPath, detected, io);
109
126
  if (cancelled) return;
110
127
  setBeatEdits(null);
111
128
  resetBeatHistory();
112
129
  setBeatAnalysis({ ...analysis, beatTimes: times, beatStrengths: strengths });
113
- // Seed a missing file through the SAME debounced writer the edits use, so
114
- // the initial write can't race a near-simultaneous edit's persist.
115
- if (beatPath && !hasFile && times.length > 0) usePlayerStore.getState().beatPersist?.();
116
- })
117
- .catch(() => {
118
- if (cancelled) return;
119
- setBeatAnalysis(null);
120
- analysisCache.delete(musicSrc);
121
- });
130
+ } catch {
131
+ if (!cancelled) {
132
+ setBeatAnalysis(null);
133
+ analysisCache.delete(musicSrc);
134
+ }
135
+ }
136
+ })();
122
137
 
123
138
  return () => {
124
139
  cancelled = true;
@@ -1,5 +1,4 @@
1
1
  import { useCallback, useRef } from "react";
2
- import { editLog } from "../utils/editDebugLog";
3
2
  import type { TimelineElement } from "../player";
4
3
  import { usePlayerStore } from "../player";
5
4
  import { saveProjectFilesWithHistory } from "../utils/studioFileHistory";
@@ -120,7 +119,6 @@ async function executeSplit(
120
119
  if (!patchTarget) throw new Error("Clip is missing a patchable target.");
121
120
 
122
121
  const targetPath = element.sourceFile || activeCompPath || "index.html";
123
- editLog("razor-split", { id: element.domId ?? element.id, splitTime, file: targetPath });
124
122
  const originalContent = await readFileContent(pid, targetPath);
125
123
  const newId = generateSplitId(collectHtmlIds(originalContent), element.domId || "clip");
126
124
 
@@ -134,7 +132,6 @@ async function executeSplit(
134
132
  element.duration,
135
133
  );
136
134
  if (!splitResult.ok) throw new Error("Failed to split clip.");
137
- editLog("razor-split:done", { changed: splitResult.changed, newId });
138
135
  if (!splitResult.changed) {
139
136
  return { targetPath, originalContent, patchedContent: originalContent, changed: false };
140
137
  }
@@ -1 +0,0 @@
1
- *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.\!visible{visibility:visible!important}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.inset-2{top:.5rem;right:.5rem;bottom:.5rem;left:.5rem}.inset-y-0{top:0;bottom:0}.-bottom-1\.5{bottom:-.375rem}.-right-1\.5{right:-.375rem}.bottom-0{bottom:0}.bottom-1{bottom:.25rem}.bottom-2{bottom:.5rem}.bottom-3{bottom:.75rem}.bottom-6{bottom:1.5rem}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.left-2{left:.5rem}.left-3{left:.75rem}.right-0{right:0}.right-1{right:.25rem}.right-2{right:.5rem}.right-3{right:.75rem}.right-6{right:1.5rem}.top-0{top:0}.top-1{top:.25rem}.top-1\/2{top:50%}.top-14{top:3.5rem}.top-2{top:.5rem}.top-3{top:.75rem}.top-\[2px\]{top:2px}.top-\[calc\(100\%\+6px\)\]{top:calc(100% + 6px)}.top-full{top:100%}.isolate{isolation:isolate}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.z-\[1\]{z-index:1}.z-\[200\]{z-index:200}.z-\[3\]{z-index:3}.z-\[4\]{z-index:4}.z-\[90\]{z-index:90}.z-\[91\]{z-index:91}.z-\[92\]{z-index:92}.z-\[9999\]{z-index:9999}.col-span-2{grid-column:span 2 / span 2}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.-mt-\[72px\]{margin-top:-72px}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-1\.5{margin-left:.375rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-10{margin-top:2.5rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-8{margin-top:2rem}.mt-\[22px\]{margin-top:22px}.mt-\[5px\]{margin-top:5px}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.\!block{display:block!important}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.contents{display:contents}.hidden{display:none}.aspect-video{aspect-ratio:16 / 9}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-2{height:.5rem}.h-24{height:6rem}.h-28{height:7rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-36{height:9rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[3px\]{height:3px}.h-\[45px\]{height:45px}.h-\[52px\]{height:52px}.h-\[5px\]{height:5px}.h-full{height:100%}.h-px{height:1px}.max-h-24{max-height:6rem}.max-h-40{max-height:10rem}.max-h-64{max-height:16rem}.max-h-\[420px\]{max-height:420px}.max-h-\[70\%\]{max-height:70%}.max-h-\[80vh\]{max-height:80vh}.max-h-full{max-height:100%}.min-h-0{min-height:0px}.min-h-7{min-height:1.75rem}.min-h-8{min-height:2rem}.min-h-9{min-height:2.25rem}.min-h-\[120px\]{min-height:120px}.min-h-\[240px\]{min-height:240px}.w-1\.5{width:.375rem}.w-1\/2{width:50%}.w-10{width:2.5rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\/5{width:40%}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/5{width:60%}.w-4{width:1rem}.w-5{width:1.25rem}.w-52{width:13rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[118px\]{width:118px}.w-\[160px\]{width:160px}.w-\[292px\]{width:292px}.w-\[38px\]{width:38px}.w-\[480px\]{width:480px}.w-\[560px\]{width:560px}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-6{min-width:1.5rem}.min-w-7{min-width:1.75rem}.min-w-8{min-width:2rem}.min-w-9{min-width:2.25rem}.min-w-\[140px\]{min-width:140px}.min-w-\[160px\]{min-width:160px}.min-w-\[16px\]{min-width:16px}.min-w-\[180px\]{min-width:180px}.min-w-\[20px\]{min-width:20px}.min-w-\[220px\]{min-width:220px}.min-w-\[36px\]{min-width:36px}.min-w-\[44px\]{min-width:44px}.min-w-\[56px\]{min-width:56px}.min-w-\[58px\]{min-width:58px}.min-w-\[96px\]{min-width:96px}.max-w-\[1400px\]{max-width:1400px}.max-w-\[260px\]{max-width:260px}.max-w-\[280px\]{max-width:280px}.max-w-\[900px\]{max-width:900px}.max-w-\[calc\(100vw-32px\)\]{max-width:calc(100vw - 32px)}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-2{--tw-translate-y: .5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\!transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-col-resize{cursor:col-resize}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-ew-resize{cursor:ew-resize}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-row-resize{cursor:row-resize}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.\!resize{resize:both!important}.resize{resize:both}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\[minmax\(0\,1fr\)_28px\]{grid-template-columns:minmax(0,1fr) 28px}.grid-cols-\[minmax\(0\,1fr\)_68px_28px\]{grid-template-columns:minmax(0,1fr) 68px 28px}.grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.grid-cols-\[minmax\(0\,1fr\)_auto_auto\]{grid-template-columns:minmax(0,1fr) auto auto}.grid-cols-\[repeat\(auto-fit\,minmax\(118px\,1fr\)\)\]{grid-template-columns:repeat(auto-fit,minmax(118px,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-\[2px\]{gap:2px}.gap-px{gap:1px}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-x-8{-moz-column-gap:2rem;column-gap:2rem}.gap-y-1{row-gap:.25rem}.gap-y-1\.5{row-gap:.375rem}.gap-y-2{row-gap:.5rem}.gap-y-8{row-gap:2rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[14px\]{border-radius:14px}.rounded-\[18px\]{border-radius:18px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-green-500\/30{border-color:#22c55e4d}.border-neutral-600{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.border-neutral-700{--tw-border-opacity: 1;border-color:rgb(64 64 64 / var(--tw-border-opacity, 1))}.border-neutral-700\/40{border-color:#40404066}.border-neutral-700\/50{border-color:#40404080}.border-neutral-700\/60{border-color:#40404099}.border-neutral-800{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.border-neutral-800\/30{border-color:#2626264d}.border-neutral-800\/40{border-color:#26262666}.border-neutral-800\/50{border-color:#26262680}.border-neutral-800\/60{border-color:#26262699}.border-panel-border{--tw-border-opacity: 1;border-color:rgb(30 30 30 / var(--tw-border-opacity, 1))}.border-purple-500\/20{border-color:#a855f733}.border-red-300\/20{border-color:#fca5a533}.border-red-400\/60{border-color:#f8717199}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-red-500\/30{border-color:#ef44444d}.border-studio-accent{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.border-studio-accent\/25{border-color:#3ce6ac40}.border-studio-accent\/30{border-color:#3ce6ac4d}.border-studio-accent\/50{border-color:#3ce6ac80}.border-studio-accent\/60{border-color:#3ce6ac99}.border-studio-accent\/70{border-color:#3ce6acb3}.border-studio-accent\/80{border-color:#3ce6accc}.border-transparent{border-color:transparent}.border-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity, 1))}.border-white\/20{border-color:#fff3}.border-white\/90{border-color:#ffffffe6}.border-t-neutral-500{--tw-border-opacity: 1;border-top-color:rgb(115 115 115 / var(--tw-border-opacity, 1))}.bg-\[\#0a0a0b\]{--tw-bg-opacity: 1;background-color:rgb(10 10 11 / var(--tw-bg-opacity, 1))}.bg-\[\#3CE6AC\]\/10{background-color:#3ce6ac1a}.bg-\[\#3CE6AC\]\/5{background-color:#3ce6ac0d}.bg-amber-300{--tw-bg-opacity: 1;background-color:rgb(252 211 77 / var(--tw-bg-opacity, 1))}.bg-amber-400{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-amber-500\/15{background-color:#f59e0b26}.bg-amber-500\/20{background-color:#f59e0b33}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/40{background-color:#0006}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-black\/70{background-color:#000000b3}.bg-blue-400{--tw-bg-opacity: 1;background-color:rgb(96 165 250 / var(--tw-bg-opacity, 1))}.bg-blue-500\/15{background-color:#3b82f626}.bg-cyan-400{--tw-bg-opacity: 1;background-color:rgb(34 211 238 / var(--tw-bg-opacity, 1))}.bg-cyan-500\/15{background-color:#06b6d426}.bg-emerald-400{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity, 1))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-500\/15{background-color:#10b98126}.bg-emerald-500\/20{background-color:#10b98133}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity, 1))}.bg-green-400{--tw-bg-opacity: 1;background-color:rgb(74 222 128 / var(--tw-bg-opacity, 1))}.bg-green-500\/15{background-color:#22c55e26}.bg-green-500\/20{background-color:#22c55e33}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-neutral-200{--tw-bg-opacity: 1;background-color:rgb(229 229 229 / var(--tw-bg-opacity, 1))}.bg-neutral-500{--tw-bg-opacity: 1;background-color:rgb(115 115 115 / var(--tw-bg-opacity, 1))}.bg-neutral-600{--tw-bg-opacity: 1;background-color:rgb(82 82 82 / var(--tw-bg-opacity, 1))}.bg-neutral-700{--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity, 1))}.bg-neutral-700\/40{background-color:#40404066}.bg-neutral-800{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity, 1))}.bg-neutral-800\/50{background-color:#26262680}.bg-neutral-800\/60{background-color:#26262699}.bg-neutral-800\/70{background-color:#262626b3}.bg-neutral-900{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity, 1))}.bg-neutral-900\/40{background-color:#17171766}.bg-neutral-900\/50{background-color:#17171780}.bg-neutral-900\/60{background-color:#17171799}.bg-neutral-900\/80{background-color:#171717cc}.bg-neutral-950{--tw-bg-opacity: 1;background-color:rgb(10 10 10 / var(--tw-bg-opacity, 1))}.bg-neutral-950\/80{background-color:#0a0a0acc}.bg-panel-accent{--tw-bg-opacity: 1;background-color:rgb(60 230 172 / var(--tw-bg-opacity, 1))}.bg-panel-accent\/10{background-color:#3ce6ac1a}.bg-panel-accent\/40{background-color:#3ce6ac66}.bg-panel-bg{--tw-bg-opacity: 1;background-color:rgb(12 12 14 / var(--tw-bg-opacity, 1))}.bg-panel-border{--tw-bg-opacity: 1;background-color:rgb(30 30 30 / var(--tw-bg-opacity, 1))}.bg-panel-hover{--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.bg-panel-input{--tw-bg-opacity: 1;background-color:rgb(22 22 24 / var(--tw-bg-opacity, 1))}.bg-panel-input\/30{background-color:#1616184d}.bg-panel-text-3{--tw-bg-opacity: 1;background-color:rgb(113 113 122 / var(--tw-bg-opacity, 1))}.bg-panel-text-5{--tw-bg-opacity: 1;background-color:rgb(63 63 70 / var(--tw-bg-opacity, 1))}.bg-pink-400{--tw-bg-opacity: 1;background-color:rgb(244 114 182 / var(--tw-bg-opacity, 1))}.bg-pink-500\/15{background-color:#ec489926}.bg-purple-400{--tw-bg-opacity: 1;background-color:rgb(192 132 252 / var(--tw-bg-opacity, 1))}.bg-purple-500\/10{background-color:#a855f71a}.bg-purple-500\/15{background-color:#a855f726}.bg-purple-900\/70{background-color:#581c87b3}.bg-red-400{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-500\/15{background-color:#ef444426}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-red-900\/60{background-color:#7f1d1d99}.bg-red-950\/30{background-color:#450a0a4d}.bg-red-950\/85{background-color:#450a0ad9}.bg-rose-400{--tw-bg-opacity: 1;background-color:rgb(251 113 133 / var(--tw-bg-opacity, 1))}.bg-rose-500\/15{background-color:#f43f5e26}.bg-sky-400{--tw-bg-opacity: 1;background-color:rgb(56 189 248 / var(--tw-bg-opacity, 1))}.bg-sky-500\/20{background-color:#0ea5e933}.bg-studio-accent{--tw-bg-opacity: 1;background-color:rgb(60 230 172 / var(--tw-bg-opacity, 1))}.bg-studio-accent\/10{background-color:#3ce6ac1a}.bg-studio-accent\/15{background-color:#3ce6ac26}.bg-studio-accent\/20{background-color:#3ce6ac33}.bg-studio-accent\/5{background-color:#3ce6ac0d}.bg-studio-accent\/60{background-color:#3ce6ac99}.bg-studio-accent\/80{background-color:#3ce6accc}.bg-studio-accent\/90{background-color:#3ce6ace6}.bg-studio-accent\/\[0\.03\]{background-color:#3ce6ac08}.bg-studio-accent\/\[0\.04\]{background-color:#3ce6ac0a}.bg-studio-accent\/\[0\.05\]{background-color:#3ce6ac0d}.bg-studio-accent\/\[0\.06\]{background-color:#3ce6ac0f}.bg-transparent{background-color:transparent}.bg-violet-400{--tw-bg-opacity: 1;background-color:rgb(167 139 250 / var(--tw-bg-opacity, 1))}.bg-violet-500\/15{background-color:#8b5cf626}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/10{background-color:#ffffff1a}.bg-white\/15{background-color:#ffffff26}.bg-white\/5{background-color:#ffffff0d}.bg-white\/70{background-color:#ffffffb3}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.from-black{--tw-gradient-from: #000 var(--tw-gradient-from-position);--tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-white{--tw-gradient-from: #fff var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.fill-neutral-600{fill:#525252}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-8{padding:2rem}.p-\[2px\]{padding:2px}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.py-\[5px\]{padding-top:5px;padding-bottom:5px}.py-\[7px\]{padding-top:7px;padding-bottom:7px}.py-px{padding-top:1px;padding-bottom:1px}.pb-0\.5{padding-bottom:.125rem}.pb-1{padding-bottom:.25rem}.pb-2{padding-bottom:.5rem}.pb-2\.5{padding-bottom:.625rem}.pb-3{padding-bottom:.75rem}.pb-5{padding-bottom:1.25rem}.pl-1{padding-left:.25rem}.pl-2{padding-left:.5rem}.pl-4{padding-left:1rem}.pl-7{padding-left:1.75rem}.pr-2{padding-right:.5rem}.pt-0\.5{padding-top:.125rem}.pt-1{padding-top:.25rem}.pt-1\.5{padding-top:.375rem}.pt-2{padding-top:.5rem}.pt-2\.5{padding-top:.625rem}.pt-3{padding-top:.75rem}.pt-\[72px\]{padding-top:72px}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[7px\]{font-size:7px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.normal-case{text-transform:none}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-\[0\.14em\]{letter-spacing:.14em}.tracking-\[0\.16em\]{letter-spacing:.16em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-\[\#09090B\]{--tw-text-opacity: 1;color:rgb(9 9 11 / var(--tw-text-opacity, 1))}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-cyan-400{--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-neutral-100{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.text-neutral-200{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.text-neutral-300{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}.text-neutral-400{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.text-neutral-50{--tw-text-opacity: 1;color:rgb(250 250 250 / var(--tw-text-opacity, 1))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-neutral-600{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.text-neutral-700{--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1))}.text-neutral-900{--tw-text-opacity: 1;color:rgb(23 23 23 / var(--tw-text-opacity, 1))}.text-neutral-950{--tw-text-opacity: 1;color:rgb(10 10 10 / var(--tw-text-opacity, 1))}.text-orange-400\/70{color:#fb923cb3}.text-panel-accent{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.text-panel-accent\/70{color:#3ce6acb3}.text-panel-text-1{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.text-panel-text-2{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.text-panel-text-3{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.text-panel-text-4{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.text-panel-text-5{--tw-text-opacity: 1;color:rgb(63 63 70 / var(--tw-text-opacity, 1))}.text-panel-text-5\/30{color:#3f3f464d}.text-pink-400{--tw-text-opacity: 1;color:rgb(244 114 182 / var(--tw-text-opacity, 1))}.text-purple-200{--tw-text-opacity: 1;color:rgb(233 213 255 / var(--tw-text-opacity, 1))}.text-purple-300{--tw-text-opacity: 1;color:rgb(216 180 254 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-red-100{--tw-text-opacity: 1;color:rgb(254 226 226 / var(--tw-text-opacity, 1))}.text-red-200{--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-rose-400{--tw-text-opacity: 1;color:rgb(251 113 133 / var(--tw-text-opacity, 1))}.text-sky-300{--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity, 1))}.text-studio-accent{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.text-studio-accent\/50{color:#3ce6ac80}.text-studio-accent\/80{color:#3ce6accc}.text-violet-400{--tw-text-opacity: 1;color:rgb(167 139 250 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/60{color:#fff9}.text-white\/80{color:#fffc}.text-white\/90{color:#ffffffe6}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.placeholder-neutral-600::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(82 82 82 / var(--tw-placeholder-opacity, 1))}.placeholder-neutral-600::placeholder{--tw-placeholder-opacity: 1;color:rgb(82 82 82 / var(--tw-placeholder-opacity, 1))}.accent-studio-accent{accent-color:#3CE6AC}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-25{opacity:.25}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.mix-blend-difference{mix-blend-mode:difference}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(0\,0\,0\,0\.35\)\]{--tw-shadow: 0 0 0 1px rgba(0,0,0,.35);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(0\,0\,0\,0\.45\)\]{--tw-shadow: 0 0 0 1px rgba(0,0,0,.45);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(0\,0\,0\,0\.85\)\,0_6px_14px_rgba\(0\,0\,0\,0\.5\)\]{--tw-shadow: 0 0 0 1px rgba(0,0,0,.85),0 6px 14px rgba(0,0,0,.5);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color), 0 6px 14px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(0\,0\,0\,0\.85\)\,0_8px_18px_rgba\(0\,0\,0\,0\.45\)\]{--tw-shadow: 0 0 0 1px rgba(0,0,0,.85),0 8px 18px rgba(0,0,0,.45);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color), 0 8px 18px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(60\,230\,172\,0\.25\)\]{--tw-shadow: 0 0 0 1px rgba(60,230,172,.25);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(60\,230\,172\,0\.3\)\]{--tw-shadow: 0 0 0 1px rgba(60,230,172,.3);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_2px_rgba\(60\,230\,172\,0\.18\)\]{--tw-shadow: 0 0 0 2px rgba(60,230,172,.18);--tw-shadow-colored: 0 0 0 2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_0_0_1px_rgba\(255\,255\,255\,0\.06\)\]{--tw-shadow: inset 0 0 0 1px rgba(255,255,255,.06);--tw-shadow-colored: inset 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_0_0_2px_rgba\(60\,230\,172\,0\.6\)\]{--tw-shadow: inset 0 0 0 2px rgba(60,230,172,.6);--tw-shadow-colored: inset 0 0 0 2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_1px_0_rgba\(255\,255\,255\,0\.03\)\]{--tw-shadow: inset 0 1px 0 rgba(255,255,255,.03);--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_1px_0_rgba\(255\,255\,255\,0\.04\)\]{--tw-shadow: inset 0 1px 0 rgba(255,255,255,.04);--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_1px_0_rgba\(255\,255\,255\,0\.08\)\]{--tw-shadow: inset 0 1px 0 rgba(255,255,255,.08);--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_1px_2px_rgba\(0\,0\,0\,0\.55\)\]{--tw-shadow: inset 0 1px 2px rgba(0,0,0,.55);--tw-shadow-colored: inset 0 1px 2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-black\/30{--tw-shadow-color: rgb(0 0 0 / .3);--tw-shadow: var(--tw-shadow-colored)}.shadow-black\/40{--tw-shadow-color: rgb(0 0 0 / .4);--tw-shadow: var(--tw-shadow-colored)}.shadow-black\/50{--tw-shadow-color: rgb(0 0 0 / .5);--tw-shadow: var(--tw-shadow-colored)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.outline-1{outline-width:1px}.-outline-offset-1{outline-offset:-1px}.outline-\[\#3CE6AC\]\/30{outline-color:#3ce6ac4d}.outline-\[\#3CE6AC\]\/40{outline-color:#3ce6ac66}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-panel-accent\/30{--tw-ring-color: rgb(60 230 172 / .3)}.ring-studio-accent{--tw-ring-opacity: 1;--tw-ring-color: rgb(60 230 172 / var(--tw-ring-opacity, 1))}.ring-white\/50{--tw-ring-color: rgb(255 255 255 / .5)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow{--tw-drop-shadow: drop-shadow(0 1px 2px rgb(0 0 0 / .1)) drop-shadow(0 1px 1px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale: grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.sepia{--tw-sepia: sepia(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-150{transition-duration:.15s}.duration-300{transition-duration:.3s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.\[grid-template-columns\:repeat\(auto-fill\,minmax\(300px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}.\[hf-edit\:\<scope\>\]{hf-edit:<scope>}:root{color-scheme:dark}body{margin:0;padding:0;background:#0a0a0a;color:#e5e5e5;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;overflow:hidden}.hf-color-grading-number::-webkit-outer-spin-button,.hf-color-grading-number::-webkit-inner-spin-button{margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.hf-color-grading-number{-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}.hf-color-grading-range{height:1.5rem;cursor:default;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent}.hf-color-grading-range:disabled{cursor:not-allowed;opacity:.5}.hf-color-grading-range::-webkit-slider-runnable-track{height:1.25rem;border:0;background:transparent}.hf-color-grading-range::-webkit-slider-thumb{width:.625rem;height:1rem;margin-top:.125rem;border:0;border-radius:999px;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff;box-shadow:0 0 0 2px #0c0c0e,0 1px 4px #0000008c;cursor:default}.hf-color-grading-range::-moz-range-track{height:1.25rem;border:0;background:transparent}.hf-color-grading-range::-moz-range-thumb{width:.625rem;height:1rem;border:0;border-radius:999px;background:#fff;box-shadow:0 0 0 2px #0c0c0e,0 1px 4px #0000008c;cursor:default}.hf-color-grading-range:focus-visible{outline:none}.hf-color-grading-range:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 2px #0c0c0e,0 0 0 4px #3ce6ac38,0 1px 4px #0000008c}.hf-color-grading-range:focus-visible::-moz-range-thumb{box-shadow:0 0 0 2px #0c0c0e,0 0 0 4px #3ce6ac38,0 1px 4px #0000008c}#root{width:100vw;height:100vh;height:100dvh}.cm-editor{height:100%;font-size:13px}.cm-editor .cm-scroller{font-family:JetBrains Mono,Fira Code,SF Mono,monospace}.cm-editor.cm-focused{outline:none}.hf-loader{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:min(34rem,100%);padding:1.5rem;box-sizing:border-box;text-align:center;cursor:default;-moz-user-select:none;user-select:none;-webkit-user-select:none;-webkit-user-drag:none}.hf-frame{display:grid;place-items:center;width:100%;height:100%;min-height:12rem;border:1px solid rgba(255,255,255,.08);background:#00000085}.hf-loader-mark-frame{display:grid;place-items:center;overflow:visible;transform-origin:50% 50%;-moz-user-select:none;user-select:none;-webkit-user-select:none;-webkit-user-drag:none}.hf-loader-mark{display:block;overflow:visible;filter:drop-shadow(0 0 7px rgba(79,219,94,.2));-moz-user-select:none;user-select:none;-webkit-user-select:none;-webkit-user-drag:none}.hf-loader-title{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:1rem;font-weight:600;letter-spacing:0;color:var(--hf-heading, #f4f4f5);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hf-loader-detail{max-width:32rem;min-height:2.5rem;overflow:hidden;color:var(--hf-text-secondary, rgba(244, 244, 245, .68));font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:.82rem;line-height:1.6}.hf-loader-mono{width:min(36rem,100%);min-height:1.5rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--hf-text-tertiary, rgba(244, 244, 245, .46));font-family:IBM Plex Mono,SF Mono,Fira Code,monospace;font-size:.75rem;letter-spacing:0;font-variant-numeric:tabular-nums}.hf-loader-progress{width:min(18rem,72vw);height:.375rem;overflow:hidden;border-radius:999px;background:#ffffff1a}@keyframes hf-thumb-fade{0%{opacity:0}to{opacity:1}}.hf-loader-progress__fill{width:100%;height:100%;transform:scaleX(0);transform-origin:left center;border-radius:inherit;background:linear-gradient(90deg,#06e3fa,#4fdb5e);transition:transform .16s ease}.placeholder\:text-neutral-600::-moz-placeholder{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.placeholder\:text-neutral-600::placeholder{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.last\:border-0:last-child{border-width:0px}.focus-within\:ring-1:focus-within{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-within\:ring-panel-accent\/30:focus-within{--tw-ring-color: rgb(60 230 172 / .3)}.hover\:border-neutral-500:hover{--tw-border-opacity: 1;border-color:rgb(115 115 115 / var(--tw-border-opacity, 1))}.hover\:border-neutral-600:hover{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.hover\:border-neutral-700:hover{--tw-border-opacity: 1;border-color:rgb(64 64 64 / var(--tw-border-opacity, 1))}.hover\:border-neutral-800:hover{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.hover\:border-studio-accent:hover{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.hover\:border-studio-accent\/50:hover{border-color:#3ce6ac80}.hover\:bg-black\/60:hover{background-color:#0009}.hover\:bg-black\/70:hover{background-color:#000000b3}.hover\:bg-neutral-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 229 229 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-600:hover{--tw-bg-opacity: 1;background-color:rgb(82 82 82 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-700\/50:hover{background-color:#40404080}.hover\:bg-neutral-800:hover{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-800\/30:hover{background-color:#2626264d}.hover\:bg-neutral-800\/50:hover{background-color:#26262680}.hover\:bg-neutral-800\/60:hover{background-color:#26262699}.hover\:bg-neutral-800\/70:hover{background-color:#262626b3}.hover\:bg-neutral-900:hover{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity, 1))}.hover\:bg-panel-accent\/10:hover{background-color:#3ce6ac1a}.hover\:bg-panel-hover:hover{--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.hover\:bg-panel-hover\/30:hover{background-color:#27272a4d}.hover\:bg-panel-hover\/40:hover{background-color:#27272a66}.hover\:bg-red-400\/10:hover{background-color:#f871711a}.hover\:bg-red-500:hover{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.hover\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-red-800\/60:hover{background-color:#991b1b99}.hover\:bg-red-900\/30:hover{background-color:#7f1d1d4d}.hover\:bg-studio-accent:hover{--tw-bg-opacity: 1;background-color:rgb(60 230 172 / var(--tw-bg-opacity, 1))}.hover\:bg-studio-accent\/10:hover{background-color:#3ce6ac1a}.hover\:bg-studio-accent\/25:hover{background-color:#3ce6ac40}.hover\:bg-studio-accent\/80:hover{background-color:#3ce6accc}.hover\:bg-white\/10:hover{background-color:#ffffff1a}.hover\:bg-white\/25:hover{background-color:#ffffff40}.hover\:text-\[\#22c55e\]:hover{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.hover\:text-amber-300:hover{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.hover\:text-neutral-100:hover{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.hover\:text-neutral-200:hover{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.hover\:text-neutral-300:hover{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}.hover\:text-neutral-400:hover{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.hover\:text-orange-300:hover{--tw-text-opacity: 1;color:rgb(253 186 116 / var(--tw-text-opacity, 1))}.hover\:text-panel-accent:hover{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.hover\:text-panel-text-1:hover{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.hover\:text-panel-text-2:hover{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.hover\:text-panel-text-3:hover{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.hover\:text-red-300:hover{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.hover\:text-red-400:hover{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.hover\:text-studio-accent:hover{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:text-white\/80:hover{color:#fffc}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.hover\:ring-1:hover{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.hover\:ring-white\/30:hover{--tw-ring-color: rgb(255 255 255 / .3)}.hover\:brightness-110:hover{--tw-brightness: brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:border-\[\#3CE6AC\]:focus{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.focus\:border-neutral-600:focus{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.focus\:border-neutral-700:focus{--tw-border-opacity: 1;border-color:rgb(64 64 64 / var(--tw-border-opacity, 1))}.focus\:border-panel-accent:focus{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.focus\:border-studio-accent:focus{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.focus\:border-studio-accent\/40:focus{border-color:#3ce6ac66}.focus\:border-studio-accent\/60:focus{border-color:#3ce6ac99}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-panel-accent:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(60 230 172 / var(--tw-ring-opacity, 1))}.focus\:ring-panel-accent\/40:focus{--tw-ring-color: rgb(60 230 172 / .4)}.focus\:ring-studio-accent\/30:focus{--tw-ring-color: rgb(60 230 172 / .3)}.focus\:ring-studio-accent\/40:focus{--tw-ring-color: rgb(60 230 172 / .4)}.focus-visible\:rounded:focus-visible{border-radius:.25rem}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-white\/30:focus-visible{--tw-ring-color: rgb(255 255 255 / .3)}.active\:scale-\[0\.97\]:active{--tw-scale-x: .97;--tw-scale-y: .97;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-\[0\.98\]:active{--tw-scale-x: .98;--tw-scale-y: .98;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-default:disabled{cursor:default}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:text-neutral-600:disabled{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.disabled\:text-neutral-700:disabled{--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1))}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:scale-125{--tw-scale-x: 1.25;--tw-scale-y: 1.25;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group\/card:hover .group-hover\/card\:opacity-100{opacity:1}.group:active .group-active\:bg-studio-accent\/70{background-color:#3ce6acb3}@media(min-width:640px){.sm\:inline{display:inline}}.\[\&\:\:-webkit-slider-runnable-track\]\:h-\[2px\]::-webkit-slider-runnable-track{height:2px}.\[\&\:\:-webkit-slider-runnable-track\]\:rounded-full::-webkit-slider-runnable-track{border-radius:9999px}.\[\&\:\:-webkit-slider-runnable-track\]\:bg-panel-border::-webkit-slider-runnable-track{--tw-bg-opacity: 1;background-color:rgb(30 30 30 / var(--tw-bg-opacity, 1))}.\[\&\:\:-webkit-slider-thumb\:active\]\:cursor-grabbing::-webkit-slider-thumb:active{cursor:grabbing}.\[\&\:\:-webkit-slider-thumb\]\:-mt-1::-webkit-slider-thumb{margin-top:-.25rem}.\[\&\:\:-webkit-slider-thumb\]\:h-\[10px\]::-webkit-slider-thumb{height:10px}.\[\&\:\:-webkit-slider-thumb\]\:w-\[10px\]::-webkit-slider-thumb{width:10px}.\[\&\:\:-webkit-slider-thumb\]\:cursor-grab::-webkit-slider-thumb{cursor:grab}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{border-radius:9999px}.\[\&\:\:-webkit-slider-thumb\]\:bg-white::-webkit-slider-thumb{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.\[\&\:\:-webkit-slider-thumb\]\:shadow-\[0_0_0_2px_\#0C0C0E\,0_1px_3px_rgba\(0\,0\,0\,0\.5\)\]::-webkit-slider-thumb{--tw-shadow: 0 0 0 2px #0C0C0E,0 1px 3px rgba(0,0,0,.5);--tw-shadow-colored: 0 0 0 2px var(--tw-shadow-color), 0 1px 3px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.\[\&_a\]\:text-sky-400 a{--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}.\[\&_code\]\:rounded code{border-radius:.25rem}.\[\&_code\]\:bg-neutral-800 code{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity, 1))}.\[\&_code\]\:px-1 code{padding-left:.25rem;padding-right:.25rem}.\[\&_code\]\:text-\[0\.85em\] code{font-size:.85em}.\[\&_code\]\:text-neutral-200 code{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.\[\&_h1\]\:mb-2 h1{margin-bottom:.5rem}.\[\&_h1\]\:mt-5 h1{margin-top:1.25rem}.\[\&_h1\]\:text-xl h1{font-size:1.25rem;line-height:1.75rem}.\[\&_h1\]\:font-semibold h1{font-weight:600}.\[\&_h1\]\:text-neutral-100 h1{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.\[\&_h2\]\:mb-1\.5 h2{margin-bottom:.375rem}.\[\&_h2\]\:mt-5 h2{margin-top:1.25rem}.\[\&_h2\]\:text-base h2{font-size:1rem;line-height:1.5rem}.\[\&_h2\]\:font-semibold h2{font-weight:600}.\[\&_h2\]\:text-neutral-100 h2{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.\[\&_h3\]\:mt-4 h3{margin-top:1rem}.\[\&_h3\]\:font-semibold h3{font-weight:600}.\[\&_h3\]\:text-neutral-200 h3{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.\[\&_hr\]\:my-4 hr{margin-top:1rem;margin-bottom:1rem}.\[\&_hr\]\:border-neutral-800 hr{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.\[\&_img\]\:my-2 img{margin-top:.5rem;margin-bottom:.5rem}.\[\&_img\]\:h-auto img{height:auto}.\[\&_img\]\:max-w-full img{max-width:100%}.\[\&_img\]\:rounded img{border-radius:.25rem}.\[\&_ol\]\:my-2 ol{margin-top:.5rem;margin-bottom:.5rem}.\[\&_ol\]\:list-decimal ol{list-style-type:decimal}.\[\&_ol\]\:pl-5 ol{padding-left:1.25rem}.\[\&_p\]\:my-2 p{margin-top:.5rem;margin-bottom:.5rem}.\[\&_pre\]\:my-3 pre{margin-top:.75rem;margin-bottom:.75rem}.\[\&_pre\]\:overflow-auto pre{overflow:auto}.\[\&_pre\]\:rounded pre{border-radius:.25rem}.\[\&_pre\]\:bg-neutral-900 pre{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity, 1))}.\[\&_pre\]\:p-3 pre{padding:.75rem}.\[\&_pre_code\]\:bg-transparent pre code{background-color:transparent}.\[\&_pre_code\]\:p-0 pre code{padding:0}.\[\&_strong\]\:text-neutral-100 strong{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.\[\&_table\]\:my-3 table{margin-top:.75rem;margin-bottom:.75rem}.\[\&_td\]\:border td{border-width:1px}.\[\&_td\]\:border-neutral-800 td{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.\[\&_td\]\:px-2 td{padding-left:.5rem;padding-right:.5rem}.\[\&_td\]\:py-1 td{padding-top:.25rem;padding-bottom:.25rem}.\[\&_th\]\:border th{border-width:1px}.\[\&_th\]\:border-neutral-800 th{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.\[\&_th\]\:px-2 th{padding-left:.5rem;padding-right:.5rem}.\[\&_th\]\:py-1 th{padding-top:.25rem;padding-bottom:.25rem}.\[\&_ul\]\:my-2 ul{margin-top:.5rem;margin-bottom:.5rem}.\[\&_ul\]\:list-disc ul{list-style-type:disc}.\[\&_ul\]\:pl-5 ul{padding-left:1.25rem}
@@ -1,9 +0,0 @@
1
- // Gated strategic logging for the GSAP keyframe / manual-drag / gesture / razor
2
- // edit flows. Silent in production; on in dev builds, or anywhere once you set
3
- // `window.__hfDebug = true` in the console. Single `[hf-edit:<scope>]` prefix so
4
- // the whole edit pipeline is greppable. Fires only at commit boundaries (user
5
- // actions), never in render/raf loops, so it doesn't spam.
6
- export function editLog(_scope: string, ..._args: unknown[]): void {
7
- // ponytail: body removed — all console.* stripped from studio.
8
- // Restore with: console.log(`[hf-edit:${_scope}]`, ..._args);
9
- }