diff --git a/.gitignore b/.gitignore index 00349cae8..62fba393e 100644 --- a/.gitignore +++ b/.gitignore @@ -62,7 +62,8 @@ tmp/ packages/core/src/generated/ packages/producer/src/services/fontData.generated.ts -# Test artifacts +# Local proof / test artifacts +qa-artifacts/ my-video/ examples/ packages/studio/data/ diff --git a/docs/packages/cli.mdx b/docs/packages/cli.mdx index 120bd7fc9..f2f6cc8bf 100644 --- a/docs/packages/cli.mdx +++ b/docs/packages/cli.mdx @@ -162,7 +162,7 @@ This is suppressed in CI environments, non-TTY shells, and when `HYPERFRAMES_NO_ | Flag | Description | |------|-------------| | `--example, -e` | Example to scaffold (required in default mode, interactive in `--human-friendly`) | - | `--resolution` | Canvas preset: `landscape` (1920×1080), `portrait` (1080×1920), `landscape-4k` (3840×2160), `portrait-4k` (2160×3840). Aliases: `1080p`, `4k`, `uhd`. Default: keep template dimensions. | + | `--resolution` | Canvas preset: `landscape` (1920×1080), `portrait` (1080×1920), `landscape-4k` (3840×2160), `portrait-4k` (2160×3840), `square` (1080×1080), `square-4k` (2160×2160). Aliases: `1080p`, `4k`, `uhd`, `1080p-square`, `square-1080p`, `4k-square`. Default: keep template dimensions. | | `--video, -V` | Path to a video file (MP4, WebM, MOV) | | `--audio, -a` | Path to an audio file (MP3, WAV, M4A) | | `--tailwind` | Add Tailwind CSS browser-runtime support to scaffolded HTML | @@ -610,7 +610,7 @@ This is suppressed in CI environments, non-TTY shells, and when `HYPERFRAMES_NO_ | `--quality` | draft, standard, high | standard | Encoding quality preset (drives CRF/bitrate) | | `--crf` | 0-51 | — | Override encoder CRF (lower = higher quality). Mutually exclusive with `--video-bitrate` | | `--video-bitrate` | e.g. `10M`, `5000k` | — | Target video bitrate. Mutually exclusive with `--crf` | - | `--resolution` | landscape, portrait, landscape-4k, portrait-4k (aliases: `1080p`, `4k`, `uhd`) | — | Output resolution preset. Supersamples a smaller composition via Chrome `deviceScaleFactor` so the screenshot lands at the requested dimensions. Aspect ratio must match the composition; the scale must be an integer multiple. Not supported with `--hdr`. See [4K Rendering](/guides/4k-rendering) | + | `--resolution` | landscape, portrait, landscape-4k, portrait-4k, square, square-4k (aliases: `1080p`, `4k`, `uhd`, `1080p-square`, `square-1080p`, `4k-square`) | — | Output resolution preset. Supersamples a smaller composition via Chrome `deviceScaleFactor` so the screenshot lands at the requested dimensions. Aspect ratio must match the composition; the scale must be an integer multiple. Not supported with `--hdr`. See [4K Rendering](/guides/4k-rendering) | | `--hdr` | — | off | Force HDR output even if no HDR sources are detected. MP4 only. See [HDR Rendering](/guides/hdr) | | `--sdr` | — | off | Force SDR output even if HDR sources are detected | | `--workers` | 1-8 | 4 | Parallel render workers | diff --git a/docs/packages/core.mdx b/docs/packages/core.mdx index 56c32b4cd..22e41c798 100644 --- a/docs/packages/core.mdx +++ b/docs/packages/core.mdx @@ -51,7 +51,7 @@ import type { TimelineElementType, // "video" | "image" | "text" | "audio" | "composition" CompositionSpec, CompositionVariable, - CanvasResolution, // "landscape" | "portrait" + CanvasResolution, // "landscape" | "portrait" | "landscape-4k" | "portrait-4k" | "square" | "square-4k" Orientation, // "16:9" | "9:16" FrameAdapter, FrameAdapterContext, diff --git a/packages/cli/src/commands/init.test.ts b/packages/cli/src/commands/init.test.ts index 59cfa7ca4..16ebc8391 100644 --- a/packages/cli/src/commands/init.test.ts +++ b/packages/cli/src/commands/init.test.ts @@ -207,6 +207,38 @@ describe("applyResolutionPreset", () => { }); }); + it("swaps to square dimensions for square", () => { + withFixture((dir) => { + const file = join(dir, "index.html"); + writeFileSync(file, sampleHtml, "utf-8"); + + applyResolutionPreset(dir, "square"); + const out = readFileSync(file, "utf-8"); + + expect(out).toContain('data-width="1080"'); + expect(out).toContain('data-height="1080"'); + expect(out).toContain('data-resolution="square"'); + expect(out).toContain("width: 1080px"); + expect(out).toContain("height: 1080px"); + }); + }); + + it("swaps to square-4k dimensions", () => { + withFixture((dir) => { + const file = join(dir, "index.html"); + writeFileSync(file, sampleHtml, "utf-8"); + + applyResolutionPreset(dir, "square-4k"); + const out = readFileSync(file, "utf-8"); + + expect(out).toContain('data-width="2160"'); + expect(out).toContain('data-height="2160"'); + expect(out).toContain('data-resolution="square-4k"'); + expect(out).toContain("width: 2160px"); + expect(out).toContain("height: 2160px"); + }); + }); + it("scaffolds a 4k project end-to-end via --resolution 4k", () => { const dir = mkdtempSync(join(tmpdir(), "hf-init-test-")); const target = join(dir, "proj"); diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 196820aee..8e48104da 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -626,7 +626,7 @@ export default defineCommand({ resolution: { type: "string", description: - "Canvas resolution preset: landscape (1920x1080), portrait (1080x1920), landscape-4k (3840x2160), portrait-4k (2160x3840). Aliases: 1080p, 4k, uhd. Default: keep template dimensions (typically 1920x1080).", + "Canvas resolution preset: landscape (1920x1080), portrait (1080x1920), landscape-4k (3840x2160), portrait-4k (2160x3840), square (1080x1080), square-4k (2160x2160). Aliases: 1080p, 4k, uhd, 1080p-square, square-1080p, 4k-square. Default: keep template dimensions (typically 1920x1080).", }, }, async run({ args }) { @@ -658,7 +658,8 @@ export default defineCommand({ console.error( c.error( `Invalid --resolution: "${args.resolution}". ` + - `Use one of: landscape, portrait, landscape-4k, portrait-4k (or aliases 1080p, 4k, uhd).`, + `Use one of: landscape, portrait, landscape-4k, portrait-4k, square, square-4k ` + + `(or aliases 1080p, 4k, uhd, 1080p-square, square-1080p, 4k-square).`, ), ); process.exit(1); diff --git a/packages/cli/src/commands/render.ts b/packages/cli/src/commands/render.ts index 56536dc8e..4df0b0d81 100644 --- a/packages/cli/src/commands/render.ts +++ b/packages/cli/src/commands/render.ts @@ -186,7 +186,7 @@ export default defineCommand({ resolution: { type: "string", description: - "Output resolution preset: landscape (1920x1080), portrait (1080x1920), landscape-4k (3840x2160), portrait-4k (2160x3840). Aliases: 1080p, 4k, uhd. The composition is unchanged — Chrome renders at higher DPR (deviceScaleFactor) so the captured screenshot lands at the requested dimensions. Aspect ratio must match the composition; the scale must be an integer multiple. Not yet supported with --hdr.", + "Output resolution preset: landscape (1920x1080), portrait (1080x1920), landscape-4k (3840x2160), portrait-4k (2160x3840), square (1080x1080), square-4k (2160x2160). Aliases: 1080p, 4k, uhd, 1080p-square, square-1080p, 4k-square. The composition is unchanged — Chrome renders at higher DPR (deviceScaleFactor) so the captured screenshot lands at the requested dimensions. Aspect ratio must match the composition; the scale must be an integer multiple. Not yet supported with --hdr.", }, }, async run({ args }) { @@ -224,7 +224,8 @@ export default defineCommand({ if (!outputResolution) { errorBox( "Invalid resolution", - `Got "${args.resolution}". Must be one of: landscape, portrait, landscape-4k, portrait-4k (or aliases 1080p, 4k, uhd).`, + `Got "${args.resolution}". Must be one of: landscape, portrait, landscape-4k, portrait-4k, square, square-4k ` + + `(or aliases 1080p, 4k, uhd, 1080p-square, square-1080p, 4k-square).`, ); process.exit(1); } diff --git a/packages/core/src/core.types.ts b/packages/core/src/core.types.ts index c3d069d31..e123b33dd 100644 --- a/packages/core/src/core.types.ts +++ b/packages/core/src/core.types.ts @@ -24,6 +24,8 @@ export const CANVAS_DIMENSIONS = { portrait: { width: 1080, height: 1920 }, "landscape-4k": { width: 3840, height: 2160 }, "portrait-4k": { width: 2160, height: 3840 }, + square: { width: 1080, height: 1080 }, + "square-4k": { width: 2160, height: 2160 }, } as const; // Single source of truth: derive the type from the table so adding a preset @@ -47,6 +49,9 @@ const RESOLUTION_ALIASES: Record = { "4k": "landscape-4k", uhd: "landscape-4k", "4k-portrait": "portrait-4k", + "1080p-square": "square", + "square-1080p": "square", + "4k-square": "square-4k", }; /** diff --git a/packages/core/src/index.test.ts b/packages/core/src/index.test.ts index bae8a15aa..2e406b5c2 100644 --- a/packages/core/src/index.test.ts +++ b/packages/core/src/index.test.ts @@ -10,6 +10,8 @@ describe("@hyperframes/core public API exports", () => { expect(core.CANVAS_DIMENSIONS.portrait).toEqual({ width: 1080, height: 1920 }); expect(core.CANVAS_DIMENSIONS["landscape-4k"]).toEqual({ width: 3840, height: 2160 }); expect(core.CANVAS_DIMENSIONS["portrait-4k"]).toEqual({ width: 2160, height: 3840 }); + expect(core.CANVAS_DIMENSIONS.square).toEqual({ width: 1080, height: 1080 }); + expect(core.CANVAS_DIMENSIONS["square-4k"]).toEqual({ width: 2160, height: 2160 }); }); it("exports VALID_CANVAS_RESOLUTIONS derived from CANVAS_DIMENSIONS", () => { @@ -18,6 +20,8 @@ describe("@hyperframes/core public API exports", () => { "portrait", "landscape-4k", "portrait-4k", + "square", + "square-4k", ]); }); @@ -27,6 +31,10 @@ describe("@hyperframes/core public API exports", () => { expect(core.normalizeResolutionFlag("1080p")).toBe("landscape"); expect(core.normalizeResolutionFlag("landscape-4k")).toBe("landscape-4k"); expect(core.normalizeResolutionFlag("UHD")).toBe("landscape-4k"); + expect(core.normalizeResolutionFlag("square")).toBe("square"); + expect(core.normalizeResolutionFlag("square-4k")).toBe("square-4k"); + expect(core.normalizeResolutionFlag("1080p-square")).toBe("square"); + expect(core.normalizeResolutionFlag("4k-square")).toBe("square-4k"); expect(core.normalizeResolutionFlag("8k")).toBeUndefined(); expect(core.normalizeResolutionFlag(undefined)).toBeUndefined(); }); diff --git a/packages/core/src/parsers/htmlParser.test.ts b/packages/core/src/parsers/htmlParser.test.ts index b913deb5b..841d26006 100644 --- a/packages/core/src/parsers/htmlParser.test.ts +++ b/packages/core/src/parsers/htmlParser.test.ts @@ -197,6 +197,21 @@ describe("parseHtml", () => { expect(result.resolution).toBe("portrait"); }); + it("keeps explicit portrait resolution even when dimensions are square", () => { + const html = ` + + +
+
Hello
+
+ + + `; + const result = parseHtml(html); + + expect(result.resolution).toBe("portrait"); + }); + it("defaults to portrait when no resolution info is available", () => { const html = ` @@ -275,10 +290,7 @@ describe("parseHtml", () => { expect(result.resolution).toBe("landscape"); }); - it("classifies square compositions as portrait by convention", () => { - // 1080×1080 has no obvious orientation. The parser collapses the tie to - // portrait — same bias the prior `w > h ? landscape : portrait` ternary - // had. Pinning so a future refactor doesn't silently flip it. + it("infers square resolution from equal width/height", () => { const html = ` @@ -290,7 +302,22 @@ describe("parseHtml", () => { `; const result = parseHtml(html); - expect(result.resolution).toBe("portrait"); + expect(result.resolution).toBe("square"); + }); + + it("infers square-4k from equal width/height >= 2160", () => { + const html = ` + + +
+
Hello
+
+ + + `; + const result = parseHtml(html); + + expect(result.resolution).toBe("square-4k"); }); it("extracts x, y, scale, opacity from data attributes", () => { diff --git a/packages/core/src/parsers/htmlParser.ts b/packages/core/src/parsers/htmlParser.ts index ba4c65ffb..f7d906349 100644 --- a/packages/core/src/parsers/htmlParser.ts +++ b/packages/core/src/parsers/htmlParser.ts @@ -124,7 +124,9 @@ function parseResolutionFromHtml(doc: Document): CanvasResolution | null { resolutionAttr === "landscape" || resolutionAttr === "portrait" || resolutionAttr === "landscape-4k" || - resolutionAttr === "portrait-4k" + resolutionAttr === "portrait-4k" || + resolutionAttr === "square" || + resolutionAttr === "square-4k" ) { return resolutionAttr; } @@ -143,17 +145,17 @@ function parseResolutionFromHtml(doc: Document): CanvasResolution | null { } function resolveResolutionFromDimensions(width: number, height: number): CanvasResolution { - // `width === height` (square) falls into the portrait branch by convention — - // the same bias the previous `w > h ? landscape : portrait` ternary used. - // Square compositions are rare; pick portrait-as-default so we don't surprise - // the existing call sites that depend on this behavior. - const isLandscape = width > height; const longSide = Math.max(width, height); - // UHD cutoff is the long side of `landscape-4k` / `portrait-4k` (3840). A - // looser threshold (e.g. ≥ 2560) would silently misclassify QHD/1440p - // (2560×1440) as 4K, which is the wrong default for a common authoring - // resolution closer to 1080p than to UHD. Authors who genuinely want the - // 4K preset can still set `data-resolution="landscape-4k"` explicitly. + // UHD cutoff is the long side of the 4K presets (3840 for `landscape-4k` / + // `portrait-4k`, 2160 for `square-4k`). A looser threshold (e.g. >= 2560) + // would silently misclassify QHD/1440p (2560x1440) as 4K, which is the + // wrong default for a common authoring resolution closer to 1080p than to + // UHD. Authors who genuinely want the 4K preset can still set + // `data-resolution="..."` explicitly. + if (width === height) { + return longSide >= 2160 ? "square-4k" : "square"; + } + const isLandscape = width > height; const isUhd = longSide >= 3840; if (isLandscape) return isUhd ? "landscape-4k" : "landscape"; return isUhd ? "portrait-4k" : "portrait"; diff --git a/packages/core/src/studio-api/routes/render.test.ts b/packages/core/src/studio-api/routes/render.test.ts index bb702cf92..035a4660d 100644 --- a/packages/core/src/studio-api/routes/render.test.ts +++ b/packages/core/src/studio-api/routes/render.test.ts @@ -3,6 +3,7 @@ import { Hono } from "hono"; import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; +import { VALID_CANVAS_RESOLUTIONS } from "../../core.types"; import { registerRenderRoutes } from "./render"; import type { StudioApiAdapter } from "../types"; @@ -98,8 +99,8 @@ describe("POST /projects/:id/render — outputResolution forwarding", () => { } }); - it("accepts each of the four canonical preset values", async () => { - for (const preset of ["landscape", "portrait", "landscape-4k", "portrait-4k"] as const) { + it("accepts each canonical preset value", async () => { + for (const preset of VALID_CANVAS_RESOLUTIONS) { const spy = vi.fn(); const { app, cleanup } = buildApp(spy); try { diff --git a/packages/producer/src/services/renderOrchestrator.test.ts b/packages/producer/src/services/renderOrchestrator.test.ts index 3dc0b6d59..b0a2f9eab 100644 --- a/packages/producer/src/services/renderOrchestrator.test.ts +++ b/packages/producer/src/services/renderOrchestrator.test.ts @@ -778,6 +778,17 @@ describe("resolveDeviceScaleFactor", () => { ).toBe(2); }); + it("returns 2 for square 1080p → square-4k", () => { + expect( + resolveDeviceScaleFactor({ + ...defaults, + compositionWidth: 1080, + compositionHeight: 1080, + outputResolution: "square-4k", + }), + ).toBe(2); + }); + it("returns 1 when the composition already matches the requested resolution", () => { expect( resolveDeviceScaleFactor({ @@ -815,6 +826,25 @@ describe("resolveDeviceScaleFactor", () => { ).toThrow(/aspect ratio/); }); + it("rejects square comp → non-square 4K presets", () => { + for (const outputResolution of ["landscape-4k", "portrait-4k"] as const) { + expect(() => + resolveDeviceScaleFactor({ + ...defaults, + compositionWidth: 1080, + compositionHeight: 1080, + outputResolution, + }), + ).toThrow(/aspect ratio/); + } + }); + + it("rejects landscape comp → square-4k", () => { + expect(() => resolveDeviceScaleFactor({ ...defaults, outputResolution: "square-4k" })).toThrow( + /aspect ratio/, + ); + }); + it("rejects downsampling (4K composition → 1080p output)", () => { expect(() => resolveDeviceScaleFactor({ diff --git a/packages/studio/src/App.tsx b/packages/studio/src/App.tsx index 311924df3..7eabb4b6e 100644 --- a/packages/studio/src/App.tsx +++ b/packages/studio/src/App.tsx @@ -157,6 +157,12 @@ function getTimelineElementLabel(element: TimelineElement): string { return element.label || element.id || element.tag; } +function confirmElementDelete(label: string, kind: "timeline clip" | "element"): boolean { + return window.confirm( + `Delete ${kind} "${label}"?\n\nThis removes it from the project source. You can use Undo to restore it.`, + ); +} + type RightPanelTab = "design" | "motion" | "renders"; const GENERIC_FONT_FAMILIES = new Set([ @@ -1780,6 +1786,8 @@ export function StudioApp() { async (element: TimelineElement) => { const pid = projectIdRef.current; if (!pid) throw new Error("No active project"); + const label = getTimelineElementLabel(element); + if (!confirmElementDelete(label, "timeline clip")) return; const targetPath = element.sourceFile || activeCompPath || "index.html"; try { @@ -1877,6 +1885,7 @@ export function StudioApp() { ); usePlayerStore.getState().setSelectedElementId(null); setRefreshKey((k) => k + 1); + showToast(`Deleted ${label}. Use Undo to restore it.`, "info"); } catch (error) { const message = error instanceof Error ? error.message : "Failed to delete timeline clip"; showToast(message); @@ -1889,6 +1898,8 @@ export function StudioApp() { async (selection: DomEditSelection) => { const pid = projectIdRef.current; if (!pid) return; + const label = selection.label || selection.id || selection.selector || selection.tagName; + if (!confirmElementDelete(label, "element")) return; const targetPath = selection.sourceFile || activeCompPath || "index.html"; try { @@ -1946,6 +1957,7 @@ export function StudioApp() { setDomEditGroupSelections([]); usePlayerStore.getState().setSelectedElementId(null); setRefreshKey((k) => k + 1); + showToast(`Deleted ${label}. Use Undo to restore it.`, "info"); } catch (error) { const message = error instanceof Error ? error.message : "Failed to delete element"; showToast(message); diff --git a/packages/studio/src/components/editor/PropertyPanel.test.ts b/packages/studio/src/components/editor/PropertyPanel.test.ts index 47301a21f..d3c2939fa 100644 --- a/packages/studio/src/components/editor/PropertyPanel.test.ts +++ b/packages/studio/src/components/editor/PropertyPanel.test.ts @@ -4,10 +4,8 @@ import { buildStrokeWidthStyleUpdates, getClipPathInsetPx, getCssFilterFunctionPx, - getPropertyPanelVisibleSections, inferBoxShadowPreset, inferClipPathPreset, - isPropertyPanelMediaLikeSelection, normalizePanelPxValue, setCssFilterFunctionPx, } from "./PropertyPanel"; @@ -66,51 +64,4 @@ describe("PropertyPanel style helpers", () => { expect(buildStrokeStyleUpdates("none", "4px")).toEqual([["border-style", "none"]]); expect(buildStrokeStyleUpdates("solid", "4px")).toEqual([["border-style", "solid"]]); }); - - it("orders the simplified default inspector sections around high-confidence edits", () => { - expect( - getPropertyPanelVisibleSections({ - hasSelection: true, - canEditStyles: true, - hasTextControls: true, - hasColorControls: true, - }), - ).toEqual(["Text", "Layout", "Colors", "Radius", "Shadow"]); - - expect( - getPropertyPanelVisibleSections({ - hasSelection: true, - canEditStyles: true, - hasTextControls: false, - hasColorControls: false, - }), - ).toEqual(["Layout", "Radius", "Shadow"]); - }); - - it("treats media tags and background-image layers as image-like controls", () => { - expect( - isPropertyPanelMediaLikeSelection({ - tagName: "img", - styles: {}, - }), - ).toBe(true); - - expect( - isPropertyPanelMediaLikeSelection({ - tagName: "div", - styles: { - "background-image": "url(/assets/studio.png)", - }, - }), - ).toBe(true); - - expect( - isPropertyPanelMediaLikeSelection({ - tagName: "div", - styles: { - "background-image": "none", - }, - }), - ).toBe(false); - }); }); diff --git a/packages/studio/src/components/renders/useRenderQueue.ts b/packages/studio/src/components/renders/useRenderQueue.ts index d3c0aa446..4a65b20b8 100644 --- a/packages/studio/src/components/renders/useRenderQueue.ts +++ b/packages/studio/src/components/renders/useRenderQueue.ts @@ -14,8 +14,14 @@ export interface RenderJob { // Mirrors `CanvasResolution` from @hyperframes/core. Kept local because // studio's tsconfig doesn't include node types, and the core barrel // transitively pulls in modules with `node:fs` imports. Drift risk is -// low (4 string literals tied to a stable enum). -export type ResolutionPreset = "landscape" | "portrait" | "landscape-4k" | "portrait-4k"; +// low (6 string literals kept in sync manually with CANVAS_DIMENSIONS). +export type ResolutionPreset = + | "landscape" + | "portrait" + | "landscape-4k" + | "portrait-4k" + | "square" + | "square-4k"; export interface StartRenderOptions { fps?: number; diff --git a/qa-artifacts/studio-inspector-selection-ux/deep-text-leaf-selection.png b/qa-artifacts/studio-inspector-selection-ux/deep-text-leaf-selection.png deleted file mode 100644 index a9aa2ff05..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/deep-text-leaf-selection.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/layer-list-escape-hatch.png b/qa-artifacts/studio-inspector-selection-ux/layer-list-escape-hatch.png deleted file mode 100644 index c6649b342..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/layer-list-escape-hatch.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/manual-drag-disabled.png b/qa-artifacts/studio-inspector-selection-ux/manual-drag-disabled.png deleted file mode 100644 index 1e8a01283..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/manual-drag-disabled.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/image-selection.png b/qa-artifacts/studio-inspector-selection-ux/notion-showcase/image-selection.png deleted file mode 100644 index a30829433..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/image-selection.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/play-button-after.png b/qa-artifacts/studio-inspector-selection-ux/notion-showcase/play-button-after.png deleted file mode 100644 index 69a5749c5..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/play-button-after.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/raster-text-ask-agent-fallback.png b/qa-artifacts/studio-inspector-selection-ux/notion-showcase/raster-text-ask-agent-fallback.png deleted file mode 100644 index c82c10c95..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/raster-text-ask-agent-fallback.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/raster-text-ask-agent-fallback.webm b/qa-artifacts/studio-inspector-selection-ux/notion-showcase/raster-text-ask-agent-fallback.webm deleted file mode 100644 index 87a60a9bd..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/raster-text-ask-agent-fallback.webm and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/text-selection.png b/qa-artifacts/studio-inspector-selection-ux/notion-showcase/text-selection.png deleted file mode 100644 index 02dfb4f6f..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/notion-showcase/text-selection.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/selection-flow.webm b/qa-artifacts/studio-inspector-selection-ux/selection-flow.webm deleted file mode 100644 index f4bac0c24..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/selection-flow.webm and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/text-selection.png b/qa-artifacts/studio-inspector-selection-ux/text-selection.png deleted file mode 100644 index 854f26050..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/text-selection.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/timeline-default-thumbnails.png b/qa-artifacts/studio-inspector-selection-ux/timeline-default-thumbnails.png deleted file mode 100644 index 1e8a01283..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/timeline-default-thumbnails.png and /dev/null differ diff --git a/qa-artifacts/studio-inspector-selection-ux/video-selection.png b/qa-artifacts/studio-inspector-selection-ux/video-selection.png deleted file mode 100644 index 185d26abe..000000000 Binary files a/qa-artifacts/studio-inspector-selection-ux/video-selection.png and /dev/null differ