diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index fb1168c04..4b66009eb 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -47,6 +47,8 @@ jobs:
args: "style-13-prod style-15-prod style-16-prod"
- shard: styles-f
args: "style-17-prod style-18-prod"
+ - shard: styles-g
+ args: "overlay-montage-prod"
steps:
- name: Checkout (with LFS)
uses: actions/checkout@v4
diff --git a/.prettierignore b/.prettierignore
index 682b55f89..c9f8cfdbb 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,2 +1,3 @@
docs/
DOCS_GUIDELINES.md
+packages/producer/tests/
diff --git a/packages/core/src/lint/hyperframeLinter.ts b/packages/core/src/lint/hyperframeLinter.ts
index bc3700ff8..fdbe739e1 100644
--- a/packages/core/src/lint/hyperframeLinter.ts
+++ b/packages/core/src/lint/hyperframeLinter.ts
@@ -391,27 +391,22 @@ export function lintHyperframeHtml(
}
}
- // #3.7: Fabricated inline base64 media — CRITICAL
- // Inline base64 audio/video data is almost always fabricated garbage that
- // won't play. Real audio files are 100KB+ when base64-encoded.
+ // #3.7: Inline base64 audio/video — PROHIBITED
+ // Base64 audio/video bloats file size and breaks rendering. Use URLs or relative paths.
{
const base64MediaRe =
- /src\s*=\s*["'](data:(?:audio|video)\/[^;]+;base64,([A-Za-z0-9+/=]{100,}))["']/gi;
+ /src\s*=\s*["'](data:(?:audio|video)\/[^;]+;base64,([A-Za-z0-9+/=]{20,}))["']/gi;
let b64Match: RegExpExecArray | null;
while ((b64Match = base64MediaRe.exec(source)) !== null) {
- // Check if it's suspiciously repetitive (fake data has long runs of repeated chars)
const sample = (b64Match[2] || "").slice(0, 200);
const uniqueChars = new Set(sample.replace(/[A-Za-z0-9+/=]/g, (c) => c)).size;
const dataSize = Math.round(((b64Match[2] || "").length * 3) / 4);
const isSuspicious = uniqueChars < 15 || (dataSize > 1000 && dataSize < 50000);
- // Any embedded base64 audio is suspicious — real audio should be a file
pushFinding({
- code: "fabricated_inline_media",
- severity: isSuspicious ? "error" : "warning",
- message: isSuspicious
- ? `Fabricated base64 media detected (${(dataSize / 1024).toFixed(0)} KB). This is almost certainly fake data that won't play.`
- : `Embedded base64 audio/video detected (${(dataSize / 1024).toFixed(0)} KB). Consider using a file URL instead.`,
- fixHint: "Remove the data: URI and use a real media file URL instead.",
+ code: "base64_media_prohibited",
+ severity: "error",
+ message: `Inline base64 audio/video detected (${(dataSize / 1024).toFixed(0)} KB)${isSuspicious ? " — likely fabricated data" : ""}. Base64 media is prohibited — it bloats file size and breaks rendering.`,
+ fixHint: "Use a relative path (assets/music.mp3) or HTTPS URL for the audio/video src. Never embed media as base64.",
snippet: truncateSnippet((b64Match[1] ?? "").slice(0, 80) + "..."),
});
}
diff --git a/packages/producer/tests/overlay-montage-prod/meta.json b/packages/producer/tests/overlay-montage-prod/meta.json
new file mode 100644
index 000000000..4c2f1e8b4
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/meta.json
@@ -0,0 +1,12 @@
+{
+ "name": "overlay-montage-prod",
+ "description": "Multi-composition montage with overlays, GSAP timelines, and data-end attributes. Tests preview/render parity for composition visibility.",
+ "tags": ["style-regression", "prod-style", "slow"],
+ "minPsnr": 30,
+ "maxFrameFailures": 0,
+ "minAudioCorrelation": 0.9,
+ "maxAudioLagWindows": 120,
+ "renderConfig": {
+ "fps": 30
+ }
+}
diff --git a/packages/producer/tests/overlay-montage-prod/output/compiled.html b/packages/producer/tests/overlay-montage-prod/output/compiled.html
new file mode 100644
index 000000000..4ce6248c5
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/output/compiled.html
@@ -0,0 +1,1064 @@
+
+
+
+
+
+ Basel Form Video
+
+
+
+
+
+
+
+
+
+
+
+
+
+
activate accounts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
compliance training
+
+
+
+
+
+
+
+
+
+
+
+
+
schedule 1:1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
first week
+
+
onboarding guide
+
+
+
+
+
+
+
+
+
+
+
get started
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/producer/tests/overlay-montage-prod/output/output.mp4 b/packages/producer/tests/overlay-montage-prod/output/output.mp4
new file mode 100644
index 000000000..d92100b48
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/output/output.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9be0476841134b2be51bd21231aee86e4bbf4eaecaa2f55b3b397d3c621889fd
+size 15000289
diff --git a/packages/producer/tests/overlay-montage-prod/src/assets/branch.svg b/packages/producer/tests/overlay-montage-prod/src/assets/branch.svg
new file mode 100644
index 000000000..619488c6c
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/src/assets/branch.svg
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/packages/producer/tests/overlay-montage-prod/src/assets/column.svg b/packages/producer/tests/overlay-montage-prod/src/assets/column.svg
new file mode 100644
index 000000000..0b09802e3
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/src/assets/column.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/packages/producer/tests/overlay-montage-prod/src/assets/notch.svg b/packages/producer/tests/overlay-montage-prod/src/assets/notch.svg
new file mode 100644
index 000000000..ad330591e
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/src/assets/notch.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/packages/producer/tests/overlay-montage-prod/src/assets/scatter.svg b/packages/producer/tests/overlay-montage-prod/src/assets/scatter.svg
new file mode 100644
index 000000000..8ed40995c
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/src/assets/scatter.svg
@@ -0,0 +1,20 @@
+
\ No newline at end of file
diff --git a/packages/producer/tests/overlay-montage-prod/src/assets/splat.svg b/packages/producer/tests/overlay-montage-prod/src/assets/splat.svg
new file mode 100644
index 000000000..5b3e5427e
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/src/assets/splat.svg
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/packages/producer/tests/overlay-montage-prod/src/compositions/intro_outro.html b/packages/producer/tests/overlay-montage-prod/src/compositions/intro_outro.html
new file mode 100644
index 000000000..9379562d9
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/src/compositions/intro_outro.html
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
+
+
first week
+
+
onboarding guide
+
+
+
+
+
+
+
+
+
+
+
get started
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/producer/tests/overlay-montage-prod/src/compositions/persistent_overlays.html b/packages/producer/tests/overlay-montage-prod/src/compositions/persistent_overlays.html
new file mode 100644
index 000000000..2c1fac797
--- /dev/null
+++ b/packages/producer/tests/overlay-montage-prod/src/compositions/persistent_overlays.html
@@ -0,0 +1,109 @@
+
+