From b2f8637a6be613000a8df7f035fd76cc5fdabd24 Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Sat, 10 Oct 2026 01:00:06 -0700 Subject: [PATCH 1/5] fix(studio): text in Studio reads without em or en dashes --- package.json | 5 +- .../captions/components/CaptionOverlay.tsx | 2 +- .../src/captions/hooks/useCaptionSync.ts | 2 +- .../src/components/LinkedSelectionToggle.tsx | 4 +- packages/studio/src/components/LintModal.tsx | 6 +- .../studio/src/components/MediaPreview.tsx | 4 +- .../components/ProjectUnreachableBanner.tsx | 2 +- .../src/components/StudioRightPanels.tsx | 2 +- .../src/components/TimelineToolbar.test.tsx | 4 +- .../studio/src/components/TimelineToolbar.tsx | 12 ++-- .../src/components/editor/AnimationCard.tsx | 6 +- .../components/editor/AnimationCardParts.tsx | 2 +- .../components/editor/BlockParamsPanel.tsx | 6 +- .../components/editor/ComputedTweenNotice.tsx | 4 +- .../studio/src/components/editor/FileTree.tsx | 2 +- .../components/editor/GsapAnimationList.tsx | 2 +- .../editor/GsapAnimationSection.tsx | 4 +- .../components/editor/OffCanvasIndicators.tsx | 2 +- .../components/editor/PromotableControl.tsx | 2 +- .../src/components/editor/PropertyPanel.tsx | 4 +- .../src/components/editor/SnapToolbar.tsx | 4 +- .../src/components/editor/Transform3DCube.tsx | 2 +- .../editor/gsapAnimationConstants.ts | 4 +- .../editor/gsapAnimationHelpers.test.ts | 2 +- .../components/editor/gsapAnimationHelpers.ts | 2 +- .../propertyPanelColorGradingControls.tsx | 2 +- .../components/editor/propertyPanelFill.tsx | 2 +- .../editor/propertyPanelFlatMotionSection.tsx | 6 +- .../editor/propertyPanelFlatPrimitives.tsx | 4 +- .../editor/propertyPanelFlatSelectRow.tsx | 2 +- .../editor/propertyPanelFlatTextSection.tsx | 2 +- .../components/editor/propertyPanelFont.tsx | 6 +- .../editor/propertyPanelFxBandRuler.tsx | 4 +- .../editor/propertyPanelFxNodeOpenBody.tsx | 4 +- .../editor/propertyPanelTimingSection.tsx | 2 +- .../editor/propertyPanelTransformCommit.ts | 6 +- .../editor/useColorGradingController.ts | 2 +- .../components/panels/SlideshowSubPanels.tsx | 4 +- .../panels/VariablesBindElement.tsx | 2 +- .../src/components/panels/VariablesPanel.tsx | 6 +- .../src/components/renders/RenderQueue.tsx | 4 +- .../src/components/renders/useRenderQueue.ts | 6 +- .../src/components/sidebar/AssetCard.tsx | 4 +- .../src/components/sidebar/AudioRow.tsx | 2 +- .../src/components/sidebar/BlocksTab.tsx | 4 +- .../components/sidebar/CompositionsTab.tsx | 4 +- .../components/sidebar/PromptPreviewModal.tsx | 2 +- .../src/hooks/timelineAudioGroupCreate.ts | 2 +- .../src/hooks/timelineEditingHelpers.ts | 2 +- packages/studio/src/hooks/useBlockHandlers.ts | 2 +- .../studio/src/hooks/useDomEditSession.ts | 2 +- packages/studio/src/hooks/useEditorSave.ts | 2 +- packages/studio/src/hooks/useFrameCapture.ts | 2 +- packages/studio/src/hooks/useGestureCommit.ts | 8 +-- .../studio/src/hooks/useGsapScriptCommits.ts | 2 +- .../components/AudioGainDialog.test.tsx | 2 +- .../src/player/components/AudioGainDialog.tsx | 3 +- .../src/player/components/EditModal.tsx | 4 +- .../components/KeyframeDiamondContextMenu.tsx | 2 +- .../src/player/components/OutOfSyncBadge.tsx | 2 +- .../studio/src/player/components/Player.tsx | 2 +- .../src/player/components/ShortcutsPanel.tsx | 4 +- .../Timeline.virtualization.test.tsx | 2 +- .../components/TimelineAutomationLaneSlot.tsx | 2 +- .../src/player/components/TimelineClip.tsx | 2 +- .../player/components/TimelineFxButton.tsx | 4 +- .../components/TimelineTrackHeader.test.tsx | 6 +- .../components/timelineClipDragCommit.ts | 4 +- .../components/trackHeaderLabelRows.tsx | 2 +- .../studio/src/player/lib/playbackAdapter.ts | 2 +- packages/studio/src/utils/hmrStableContext.ts | 2 +- scripts/check-studio-copy-dashes.mjs | 62 +++++++++++++++++++ scripts/check-studio-copy-dashes.test.mjs | 28 +++++++++ 73 files changed, 208 insertions(+), 120 deletions(-) create mode 100644 scripts/check-studio-copy-dashes.mjs create mode 100644 scripts/check-studio-copy-dashes.test.mjs diff --git a/package.json b/package.json index 80650a6db35..83c843361c1 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "sync-schemas:check": "tsx scripts/sync-schemas.ts --check", "sync:package-subpaths": "node scripts/package-subpaths.mjs --write", "check:package-subpaths": "node scripts/package-subpaths.mjs", - "lint": "bun run check:docs-snippet-motion && bun run check:tracked-artifacts && bun run check:workspace-contracts && bun run check:gcp-cloud-run-dockerfile && bun run check:package-cycles && bun run check:package-subpaths && bun run check:cli-process-ownership && oxlint . && tsx scripts/lint-skills.ts && node scripts/check-skill-mirror.mjs", + "lint": "bun run check:docs-snippet-motion && bun run check:studio-copy-dashes && bun run check:tracked-artifacts && bun run check:workspace-contracts && bun run check:gcp-cloud-run-dockerfile && bun run check:package-cycles && bun run check:package-subpaths && bun run check:cli-process-ownership && oxlint . && tsx scripts/lint-skills.ts && node scripts/check-skill-mirror.mjs", "check:gcp-cloud-run-dockerfile": "bun run --cwd packages/gcp-cloud-run test:dockerfile-workspaces", "lint:skills": "tsx scripts/lint-skills.ts", "check:skill-mirror": "node scripts/check-skill-mirror.mjs", @@ -40,6 +40,7 @@ "check:workspace-contracts": "node scripts/check-workspace-contracts.mjs", "check:package-cycles": "node scripts/check-package-cycles.mjs", "check:cli-process-ownership": "node scripts/check-cli-process-ownership.mjs", + "check:studio-copy-dashes": "node scripts/check-studio-copy-dashes.mjs", "format": "oxfmt .", "test": "bun run test:unit", "test:unit": "bun run --filter '*' test", @@ -52,7 +53,7 @@ "player:perf": "bun run --filter @hyperframes/player perf", "format:check": "oxfmt --check .", "knip": "knip", - "test:scripts": "node --import tsx --test scripts/animejs-v4-guidance.test.mjs scripts/check-tracked-artifacts.test.mjs scripts/check-registry-set-delta.test.mjs scripts/check-no-main-deletions.test.mjs scripts/check-pr-captures.test.mjs scripts/check-comment-citations.test.mjs scripts/comments-workflow.test.mjs scripts/comment-ratchet.test.mjs scripts/check-docs-snippet-motion.test.mjs scripts/registry-target-paths.test.mjs scripts/check-workspace-contracts.test.mjs scripts/check-media-use-copy-parity.test.mjs scripts/check-svg-sanitize-parity.test.mjs scripts/check-media-use-svg-sanitize-generated.test.mjs scripts/check-package-cycles.test.mjs scripts/check-cli-process-ownership.test.mjs scripts/check-large-files.test.mjs scripts/prune-fallow-audit-caches.test.mjs scripts/package-subpaths.test.mjs scripts/validate-release-channel.test.mjs scripts/clawhub-sync.test.mjs scripts/publish-workflow.test.mjs scripts/pr-edit-concurrency.test.mjs scripts/merge-queue-workflows.test.mjs scripts/install-workspace-dependencies.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/catalog-payload-assets.test.ts scripts/host-registry-assets.test.ts scripts/catalog-preview-temp.test.ts scripts/backfill-block-previews.test.ts scripts/catalog-hosted-files.test.ts scripts/player-cdn-pin.test.ts scripts/studio-runtime-smoke.test.mjs scripts/verify-packed-manifests.test.mjs scripts/lint-skills.test.mjs scripts/creator-editing-recipes.test.mjs packages/gcp-cloud-run/check-dockerfile-workspaces.test.mjs packages/core/scripts/writeGeneratedFile.test.ts scripts/catalog-publication.test.mjs scripts/ci/resolve-workflow-pr.test.mjs scripts/ci/base-file.test.mjs scripts/check-catalog-source-pr.test.mjs scripts/generate-registry-items.test.ts scripts/catalog-drift.test.ts scripts/catalog-fetch-mirror.test.ts scripts/catalog-script-inlining.test.ts scripts/catalog-detail.test.ts scripts/generate-catalog-pages.test.ts scripts/verify-catalog-payloads.test.ts scripts/registry-skill-files.test.ts scripts/creator-editing-capabilities.test.mjs scripts/generate-catalog-previews.test.ts scripts/registry-primitive-payloads.test.ts registry/components/pan-stations/pan-stations.test.mjs && vitest run scripts/catalog/ scripts/contrastRatchet.test.ts scripts/generate-catalog-payloads.test.ts", + "test:scripts": "node --import tsx --test scripts/animejs-v4-guidance.test.mjs scripts/check-tracked-artifacts.test.mjs scripts/check-registry-set-delta.test.mjs scripts/check-no-main-deletions.test.mjs scripts/check-pr-captures.test.mjs scripts/check-comment-citations.test.mjs scripts/comments-workflow.test.mjs scripts/comment-ratchet.test.mjs scripts/check-docs-snippet-motion.test.mjs scripts/registry-target-paths.test.mjs scripts/check-workspace-contracts.test.mjs scripts/check-media-use-copy-parity.test.mjs scripts/check-svg-sanitize-parity.test.mjs scripts/check-media-use-svg-sanitize-generated.test.mjs scripts/check-package-cycles.test.mjs scripts/check-cli-process-ownership.test.mjs scripts/check-studio-copy-dashes.test.mjs scripts/check-large-files.test.mjs scripts/prune-fallow-audit-caches.test.mjs scripts/package-subpaths.test.mjs scripts/validate-release-channel.test.mjs scripts/clawhub-sync.test.mjs scripts/publish-workflow.test.mjs scripts/pr-edit-concurrency.test.mjs scripts/merge-queue-workflows.test.mjs scripts/install-workspace-dependencies.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/catalog-payload-assets.test.ts scripts/host-registry-assets.test.ts scripts/catalog-preview-temp.test.ts scripts/backfill-block-previews.test.ts scripts/catalog-hosted-files.test.ts scripts/player-cdn-pin.test.ts scripts/studio-runtime-smoke.test.mjs scripts/verify-packed-manifests.test.mjs scripts/lint-skills.test.mjs scripts/creator-editing-recipes.test.mjs packages/gcp-cloud-run/check-dockerfile-workspaces.test.mjs packages/core/scripts/writeGeneratedFile.test.ts scripts/catalog-publication.test.mjs scripts/ci/resolve-workflow-pr.test.mjs scripts/ci/base-file.test.mjs scripts/check-catalog-source-pr.test.mjs scripts/generate-registry-items.test.ts scripts/catalog-drift.test.ts scripts/catalog-fetch-mirror.test.ts scripts/catalog-script-inlining.test.ts scripts/catalog-detail.test.ts scripts/generate-catalog-pages.test.ts scripts/verify-catalog-payloads.test.ts scripts/registry-skill-files.test.ts scripts/creator-editing-capabilities.test.mjs scripts/generate-catalog-previews.test.ts scripts/registry-primitive-payloads.test.ts registry/components/pan-stations/pan-stations.test.mjs && vitest run scripts/catalog/ scripts/contrastRatchet.test.ts scripts/generate-catalog-payloads.test.ts", "typecheck:scripts": "tsc --noEmit -p scripts/tsconfig.json", "test:skills": "HYPERFRAMES_MEDIA_HOME_REQUIRED=1 node --import ./packages/cli/scripts/test-home.mjs --test 'skills/**/*.test.mjs' 'packages/cli/src/media-use/**/*.test.mjs'", "generate:previews": "tsx scripts/generate-template-previews.ts", diff --git a/packages/studio/src/captions/components/CaptionOverlay.tsx b/packages/studio/src/captions/components/CaptionOverlay.tsx index 072fc102013..1b30bff8c81 100644 --- a/packages/studio/src/captions/components/CaptionOverlay.tsx +++ b/packages/studio/src/captions/components/CaptionOverlay.tsx @@ -408,7 +408,7 @@ export const CaptionOverlay = memo(function CaptionOverlay({ iframeRef }: Captio {wordBoxes.length === 0 && model && model.segments.size > 0 && (
- No captions visible at this frame — scrub to a caption, or select one in the track below + No captions visible at this frame. Scrub to a caption, or select one in the track below
)} diff --git a/packages/studio/src/captions/hooks/useCaptionSync.ts b/packages/studio/src/captions/hooks/useCaptionSync.ts index 1c9c44b58e3..20424d953e6 100644 --- a/packages/studio/src/captions/hooks/useCaptionSync.ts +++ b/packages/studio/src/captions/hooks/useCaptionSync.ts @@ -235,7 +235,7 @@ export function useCaptionSync(projectId: string | null) { // File exists but is unreadable — previous edits would silently not load. useCaptionStore .getState() - .setSyncError("caption-overrides.json is corrupt — earlier caption edits didn't load"); + .setSyncError("caption-overrides.json is corrupt, so earlier caption edits didn't load"); } }, []); diff --git a/packages/studio/src/components/LinkedSelectionToggle.tsx b/packages/studio/src/components/LinkedSelectionToggle.tsx index 59f7e32a09c..b2b4871d917 100644 --- a/packages/studio/src/components/LinkedSelectionToggle.tsx +++ b/packages/studio/src/components/LinkedSelectionToggle.tsx @@ -50,8 +50,8 @@ export function LinkedSelectionToggle() { )} diff --git a/packages/studio/src/components/MediaPreview.tsx b/packages/studio/src/components/MediaPreview.tsx index edd4cac93ed..2a8c0130031 100644 --- a/packages/studio/src/components/MediaPreview.tsx +++ b/packages/studio/src/components/MediaPreview.tsx @@ -23,7 +23,7 @@ function MediaErrorPanel({ name, filePath }: { name: string; filePath: string }) {name} {filePath} - Couldn't load this file — it may be missing or corrupt + Couldn't load this file. It may be missing or corrupt ); @@ -110,7 +110,7 @@ export function MediaPreview({ projectId, filePath }: { projectId: string; fileP {name} {filePath} - Binary file — preview not available + Binary file: preview not available ); } diff --git a/packages/studio/src/components/ProjectUnreachableBanner.tsx b/packages/studio/src/components/ProjectUnreachableBanner.tsx index dd7eaeb21af..a491b28e045 100644 --- a/packages/studio/src/components/ProjectUnreachableBanner.tsx +++ b/packages/studio/src/components/ProjectUnreachableBanner.tsx @@ -82,7 +82,7 @@ export function ProjectUnreachableBanner({ projectId }: ProjectUnreachableBanner ) : ( - Couldn't open this project — it may have been renamed, moved, or deleted. + Couldn't open this project. It may have been renamed, moved, or deleted. )} ); diff --git a/packages/studio/src/components/StudioRightPanels.tsx b/packages/studio/src/components/StudioRightPanels.tsx index 7c907a3ebd9..6055d9eec7c 100644 --- a/packages/studio/src/components/StudioRightPanels.tsx +++ b/packages/studio/src/components/StudioRightPanels.tsx @@ -174,7 +174,7 @@ export const StudioRightPanels = memo(function StudioRightPanels({ // timeline offers that write as a mute. Checked here as well as in the panel // because the button is not the only caller. if (!canHideSelections(domEditGroupSelections)) { - showToast("Audio can't be hidden — use the group's own controls", "info"); + showToast("Audio can't be hidden. Use the group's own controls", "info"); return; } const { elements } = usePlayerStore.getState(); diff --git a/packages/studio/src/components/TimelineToolbar.test.tsx b/packages/studio/src/components/TimelineToolbar.test.tsx index 57abdb229fd..6469b390eb6 100644 --- a/packages/studio/src/components/TimelineToolbar.test.tsx +++ b/packages/studio/src/components/TimelineToolbar.test.tsx @@ -82,7 +82,7 @@ describe("TimelineToolbar — adaptive thumbnails", () => { it("keeps a user-controlled hidden mode as the rollback path", () => { const { host, root } = renderToolbar(); const button = host.querySelector( - 'button[aria-label="Hide thumbnails — labels only"]', + 'button[aria-label="Hide thumbnails: labels only"]', ); if (!button) throw new Error("thumbnail toggle not rendered"); @@ -90,7 +90,7 @@ describe("TimelineToolbar — adaptive thumbnails", () => { expect(usePlayerStore.getState().thumbnailMode).toBe("hidden"); expect(button.getAttribute("aria-label")).toBe( - "Show thumbnails — posters stay visible; richer previews appear on interaction", + "Show thumbnails: posters stay visible; richer previews appear on interaction", ); act(() => root.unmount()); }); diff --git a/packages/studio/src/components/TimelineToolbar.tsx b/packages/studio/src/components/TimelineToolbar.tsx index 3cfd9258033..71ce9117a75 100644 --- a/packages/studio/src/components/TimelineToolbar.tsx +++ b/packages/studio/src/components/TimelineToolbar.tsx @@ -235,8 +235,8 @@ export const TimelineToolbar = memo(function TimelineToolbar({ diff --git a/packages/studio/src/components/editor/AnimationCardParts.tsx b/packages/studio/src/components/editor/AnimationCardParts.tsx index d557ff96823..e06c94c077e 100644 --- a/packages/studio/src/components/editor/AnimationCardParts.tsx +++ b/packages/studio/src/components/editor/AnimationCardParts.tsx @@ -93,7 +93,7 @@ export function PropertyRow({ onClick={() => onCommit(isVisible ? "hidden" : "visible")} className="shrink-0 rounded-full transition-colors duration-200 relative" style={{ width: 28, height: 16, background: isVisible ? P.accent : P.borderInput }} - title={isVisible ? "Visible — click to hide" : "Hidden — click to show"} + title={isVisible ? "Visible: click to hide" : "Hidden: click to show"} > 1) { setCommitState({ tone: "error", - message: `"${previous}" appears ${matches}× in ${compositionPath} — the panel can't tell which one belongs to this parameter, so it won't risk changing unrelated content. Edit the file directly to disambiguate.`, + message: `"${previous}" appears ${matches}× in ${compositionPath}. The panel can't tell which one belongs to this parameter, so it won't risk changing unrelated content. Edit the file directly to disambiguate.`, }); trackBlockParamCommit({ tone: "error", blockName, key }); return; @@ -171,7 +171,7 @@ export const BlockParamsPanel = memo(function BlockParamsPanel({ )} {!fileManager && params.length > 0 && (
- Block params can't be edited here — no project file access. + Block params can't be edited here: no project file access.
)} {params.map((param) => ( diff --git a/packages/studio/src/components/editor/ComputedTweenNotice.tsx b/packages/studio/src/components/editor/ComputedTweenNotice.tsx index e2c59054d36..7aaaf1c5620 100644 --- a/packages/studio/src/components/editor/ComputedTweenNotice.tsx +++ b/packages/studio/src/components/editor/ComputedTweenNotice.tsx @@ -17,14 +17,14 @@ export function ComputedTweenNotice({ if (editability === "source") { return (
- Computed value — edit it in the Code tab. + Computed value. Edit it in the Code tab.
); } const source = provenance?.fn ? `${provenance.fn}()` : "a loop"; return (
- Generated by {source} — not directly editable. + Generated by {source}, not directly editable. {onUnroll && (
)} {children.map((child) => diff --git a/packages/studio/src/components/editor/GsapAnimationList.tsx b/packages/studio/src/components/editor/GsapAnimationList.tsx index ecfb37ba639..e1b3ef6ab38 100644 --- a/packages/studio/src/components/editor/GsapAnimationList.tsx +++ b/packages/studio/src/components/editor/GsapAnimationList.tsx @@ -63,7 +63,7 @@ export function GsapAnimationList({
{animations.length === 0 && (

- No animations on this element yet — add an effect below to animate it. + No animations on this element yet. Add an effect below to animate it.

)} {animations.map((animation, index) => ( diff --git a/packages/studio/src/components/editor/GsapAnimationSection.tsx b/packages/studio/src/components/editor/GsapAnimationSection.tsx index 146d05e3c03..19cb8e98a9c 100644 --- a/packages/studio/src/components/editor/GsapAnimationSection.tsx +++ b/packages/studio/src/components/editor/GsapAnimationSection.tsx @@ -25,8 +25,8 @@ export const GsapAnimationSection = memo(function GsapAnimationSection({
}> {multipleTimelines && (

- This file has multiple GSAP timelines. Animation editing is disabled to prevent data loss - — consolidate into a single timeline to enable editing. + This file has multiple GSAP timelines. Animation editing is disabled to prevent data loss. + Consolidate into a single timeline to enable editing.

)} {unsupportedTimelinePattern && ( diff --git a/packages/studio/src/components/editor/OffCanvasIndicators.tsx b/packages/studio/src/components/editor/OffCanvasIndicators.tsx index 475e57585c5..a24be763725 100644 --- a/packages/studio/src/components/editor/OffCanvasIndicators.tsx +++ b/packages/studio/src/components/editor/OffCanvasIndicators.tsx @@ -127,7 +127,7 @@ export function OffCanvasIndicators({ aria-label={`Select off-canvas element ${r.key}`} className="pointer-events-auto absolute inset-0 border-2 border-dashed border-studio-accent/10 rounded-md cursor-pointer hover:border-studio-accent hover:bg-studio-accent/10 transition-colors" style={clipOutside ? { clipPath: clipOutside } : undefined} - title={`Off-canvas: ${r.key} — click to select`} + title={`Off-canvas: ${r.key}. Click to select`} onClick={handleClick} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { diff --git a/packages/studio/src/components/editor/PromotableControl.tsx b/packages/studio/src/components/editor/PromotableControl.tsx index 37dd15af039..552382ca2ca 100644 --- a/packages/studio/src/components/editor/PromotableControl.tsx +++ b/packages/studio/src/components/editor/PromotableControl.tsx @@ -50,7 +50,7 @@ export function PromotableControl({ useEffect(() => { if (danglingId != null) { console.warn( - `[hyperframes] Control is bound to variable "${danglingId}", but no such declaration exists. The element still carries the binding on disk — re-declare the variable or unbind the element.`, + `[hyperframes] Control is bound to variable "${danglingId}", but no such declaration exists. The element still carries the binding on disk. Re-declare the variable or unbind the element.`, ); } }, [danglingId]); diff --git a/packages/studio/src/components/editor/PropertyPanel.tsx b/packages/studio/src/components/editor/PropertyPanel.tsx index 1cf6688798b..957606ffa5c 100644 --- a/packages/studio/src/components/editor/PropertyPanel.tsx +++ b/packages/studio/src/components/editor/PropertyPanel.tsx @@ -240,13 +240,13 @@ export const PropertyPanel = memo(function PropertyPanel(props: PropertyPanelPro navigator.clipboard .writeText(text) .then(() => { - showToast(`Copied element info for ${element.label} — paste into any AI agent`, "info"); + showToast(`Copied element info for ${element.label}. Paste it into any AI agent`, "info"); setClipboardCopied(true); clearTimeout(clipboardTimerRef.current); clipboardTimerRef.current = setTimeout(() => setClipboardCopied(false), 1500); }) .catch(() => { - showToast("Couldn't copy to the clipboard — check browser permissions", "error"); + showToast("Couldn't copy to the clipboard. Check browser permissions", "error"); }); }; diff --git a/packages/studio/src/components/editor/SnapToolbar.tsx b/packages/studio/src/components/editor/SnapToolbar.tsx index a91995d3e94..511f2901edc 100644 --- a/packages/studio/src/components/editor/SnapToolbar.tsx +++ b/packages/studio/src/components/editor/SnapToolbar.tsx @@ -160,8 +160,8 @@ export const SnapToolbar = memo(function SnapToolbar() { }} title={ prefs.gridVisible - ? "Grid visible (G) — right-click for spacing options" - : "Grid hidden (G) — right-click for spacing options" + ? "Grid visible (G). Right-click for spacing options" + : "Grid hidden (G). Right-click for spacing options" } aria-label="Toggle grid" > diff --git a/packages/studio/src/components/editor/Transform3DCube.tsx b/packages/studio/src/components/editor/Transform3DCube.tsx index b512598d012..335e4c1e751 100644 --- a/packages/studio/src/components/editor/Transform3DCube.tsx +++ b/packages/studio/src/components/editor/Transform3DCube.tsx @@ -308,7 +308,7 @@ export function Transform3DCube({ onClick={onKeyframe} title={ keyframed - ? "3D transform is keyframed — click a field diamond to add keyframes" + ? "3D transform is keyframed. Click a field diamond to add keyframes" : "Keyframe the 3D transform (animate it over time)" } aria-label="Keyframe 3D transform" diff --git a/packages/studio/src/components/editor/gsapAnimationConstants.ts b/packages/studio/src/components/editor/gsapAnimationConstants.ts index 5fa44e90060..778f642dbc5 100644 --- a/packages/studio/src/components/editor/gsapAnimationConstants.ts +++ b/packages/studio/src/components/editor/gsapAnimationConstants.ts @@ -8,7 +8,7 @@ export const METHOD_LABELS: Record = { }; export const METHOD_TOOLTIPS: Record = { - set: "Instantly snap to these values — no transition", + set: "Instantly snap to these values, no transition", to: "Smoothly animate the element to these target values", from: "Element starts at these values and transitions to its normal state", fromTo: "Animate from one state to another", @@ -83,7 +83,7 @@ export const PROP_TOOLTIPS: Record = { perspective: "3D depth context for child elements; set it on a parent when rotating children in 3D", transformPerspective: - "3D depth for THIS element's own X/Y rotation — lower = stronger perspective (try 600–1000)", + "3D depth for THIS element's own X/Y rotation: lower = stronger perspective (try 600 to 1000)", transformOrigin: "Pivot point for transforms, for example center center or 50% 50%", width: "Element width", height: "Element height", diff --git a/packages/studio/src/components/editor/gsapAnimationHelpers.test.ts b/packages/studio/src/components/editor/gsapAnimationHelpers.test.ts index da97d94a3c6..f03fa32326a 100644 --- a/packages/studio/src/components/editor/gsapAnimationHelpers.test.ts +++ b/packages/studio/src/components/editor/gsapAnimationHelpers.test.ts @@ -109,7 +109,7 @@ describe("buildTweenSummary", () => { const s = buildTweenSummary( anim({ method: "fromTo", fromProperties: {}, properties: { scale: 2 } }), ); - expect(s).toContain("from [—]"); + expect(s).toContain("from [none]"); }); it("handles no properties", () => { diff --git a/packages/studio/src/components/editor/gsapAnimationHelpers.ts b/packages/studio/src/components/editor/gsapAnimationHelpers.ts index b0f059ac0a3..3b507af726b 100644 --- a/packages/studio/src/components/editor/gsapAnimationHelpers.ts +++ b/packages/studio/src/components/editor/gsapAnimationHelpers.ts @@ -64,7 +64,7 @@ export function buildTweenSummary(animation: GsapAnimation): string { const label = (PROP_LABELS[p] ?? p).toLowerCase(); return `${label} ${formatPropValue(p, v)}`; }); - const fromText = fromDescs.length > 0 ? fromDescs.join(", ") : "—"; + const fromText = fromDescs.length > 0 ? fromDescs.join(", ") : "none"; return `Starting at ${pos}s, over ${dur}s, ${target} animates from [${fromText}] to [${propText}] using a ${ease.toLowerCase()} curve.`; } return `Starting at ${pos}s, over ${dur}s, animate ${target}'s ${propText} using a ${ease.toLowerCase()} curve.`; diff --git a/packages/studio/src/components/editor/propertyPanelColorGradingControls.tsx b/packages/studio/src/components/editor/propertyPanelColorGradingControls.tsx index 465db9a4b95..94ee565af89 100644 --- a/packages/studio/src/components/editor/propertyPanelColorGradingControls.tsx +++ b/packages/studio/src/components/editor/propertyPanelColorGradingControls.tsx @@ -423,7 +423,7 @@ export function ColorGradingControls({ void actions .importLut(files, onImportAssets, () => track("button", "Import LUT")) .catch(() => - setLutImportError("LUT import failed — check the .cube file and try again."), + setLutImportError("LUT import failed. Check the .cube file and try again."), ) .finally(() => setLutImporting(false)); event.currentTarget.value = ""; diff --git a/packages/studio/src/components/editor/propertyPanelFill.tsx b/packages/studio/src/components/editor/propertyPanelFill.tsx index 735411988ef..eb7c9da6cfe 100644 --- a/packages/studio/src/components/editor/propertyPanelFill.tsx +++ b/packages/studio/src/components/editor/propertyPanelFill.tsx @@ -135,7 +135,7 @@ export function ImageFillField({ commitImage(toProjectRootAssetPath(nextImage), true); } } catch { - setUploadError("Upload failed — check the file and try again."); + setUploadError("Upload failed. Check the file and try again."); } finally { setUploading(false); } diff --git a/packages/studio/src/components/editor/propertyPanelFlatMotionSection.tsx b/packages/studio/src/components/editor/propertyPanelFlatMotionSection.tsx index 599b5b95f7f..6fefd85e4bf 100644 --- a/packages/studio/src/components/editor/propertyPanelFlatMotionSection.tsx +++ b/packages/studio/src/components/editor/propertyPanelFlatMotionSection.tsx @@ -100,7 +100,7 @@ export function FlatTimingRow({ {cell("Duration", formatTimingValue(duration), commitDuration)} {derived && (

- Inferred from this element's animation — edit to pin an explicit clip range. + Inferred from this element's animation. Edit to pin an explicit clip range.

)}
@@ -150,7 +150,7 @@ export function FlatMotionSection({ {multipleTimelines && (

This file has multiple GSAP timelines. Animation editing is disabled to prevent data - loss — consolidate into a single timeline to enable editing. + loss. Consolidate into a single timeline to enable editing.

)} {unsupportedTimelinePattern && ( @@ -195,7 +195,7 @@ export function motionSectionLabel(args: { if (args.timingOnly) { return { title: "Timing", - summary: `${formatTimingValue(args.start)} – ${formatTimingValue(args.start + args.duration)}`, + summary: `${formatTimingValue(args.start)} to ${formatTimingValue(args.start + args.duration)}`, }; } return { diff --git a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx index 800583b88b7..b93ca69fe6d 100644 --- a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx +++ b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx @@ -72,7 +72,7 @@ export function FlatRow({ ) : (

- Details — {registryDef.label} + Details: {registryDef.label}

)} {details || !oneKnob ? ( diff --git a/packages/studio/src/components/editor/propertyPanelTimingSection.tsx b/packages/studio/src/components/editor/propertyPanelTimingSection.tsx index 0b71bc55144..f0448c6be51 100644 --- a/packages/studio/src/components/editor/propertyPanelTimingSection.tsx +++ b/packages/studio/src/components/editor/propertyPanelTimingSection.tsx @@ -84,7 +84,7 @@ export function TimingSection({ {derived && (

- Inferred from this element’s animation — edit to pin an explicit clip range. + Inferred from this element’s animation. Edit to pin an explicit clip range.

)} diff --git a/packages/studio/src/components/editor/propertyPanelTransformCommit.ts b/packages/studio/src/components/editor/propertyPanelTransformCommit.ts index e8949c5230d..c3793920683 100644 --- a/packages/studio/src/components/editor/propertyPanelTransformCommit.ts +++ b/packages/studio/src/components/editor/propertyPanelTransformCommit.ts @@ -71,7 +71,7 @@ export function createTransformCommitHandlers({ await commitAnimatedTransformValue( axis, parsed, - "This element's position can't be edited here yet — it is driven by its animation", + "This element's position can't be edited here yet: its animation drives it", ) ) return; @@ -97,7 +97,7 @@ export function createTransformCommitHandlers({ return; } if (hasGsapAnimation) { - showToast?.("This element's size can't be edited here yet — it is driven by its animation"); + showToast?.("This element's size can't be edited here yet: its animation drives it"); return; } const current = readStudioBoxSize(element.element); @@ -124,7 +124,7 @@ export function createTransformCommitHandlers({ await commitAnimatedTransformValue( "rotation", parsed, - "This element's rotation can't be edited here yet — it is driven by its animation", + "This element's rotation can't be edited here yet: its animation drives it", ) ) return; diff --git a/packages/studio/src/components/editor/useColorGradingController.ts b/packages/studio/src/components/editor/useColorGradingController.ts index 132e0bffffb..084991808a7 100644 --- a/packages/studio/src/components/editor/useColorGradingController.ts +++ b/packages/studio/src/components/editor/useColorGradingController.ts @@ -352,7 +352,7 @@ export function useColorGradingController({ const reverted = confirmedGradingRef.current; latestGradingRef.current = reverted; setGrading(reverted); - setRuntimeStatus({ state: "unavailable", message: "Save failed — reverted" }); + setRuntimeStatus({ state: "unavailable", message: "Save failed, changes reverted" }); }; // The callback is the primary result signal; the rejection path supports // other setAttributeLive implementations. diff --git a/packages/studio/src/components/panels/SlideshowSubPanels.tsx b/packages/studio/src/components/panels/SlideshowSubPanels.tsx index fda688f18b2..dbac96adc04 100644 --- a/packages/studio/src/components/panels/SlideshowSubPanels.tsx +++ b/packages/studio/src/components/panels/SlideshowSubPanels.tsx @@ -489,7 +489,7 @@ export function HotspotTool({ )} {sequences.length === 0 && (

- Create a branch in the Branches section first — hotspots jump to a branch. + Create a branch in the Branches section first. Hotspots jump to a branch.

)} @@ -508,7 +508,7 @@ export function HotspotTool({ onChange={(e) => setTargetSequenceId(e.target.value)} aria-label="Target branch sequence" > - + {sequences.map((seq) => (