feat(remotion): premium CharacterStory template (13 flexible scenes) + fix detail-page SSR

- CharacterStory: refined flat-illustration character (gradient-shaded sweater,
  modern hair, calm minimal face), muted editorial palette (coral/teal/sand/navy),
  abstract environment (soft depth blobs, ground "stage", sparse particles,
  vignette + grain), scene-number kicker. Verified in 16:9/1:1/9:16 and all poses.
- seed: 13 editable scene cards (c1..c13, keys s{N}_title/s{N}_text) via new
  MULTISCENE path; per-aspect previews; muted defaults.
- assets: 3 thumbnails + 4 preview MP4s vendored into public/template-media.
- fix: load BrandedVideoPlayer (plyr-react) client-only via next/dynamic
  (ssr:false) — plyr touches `document` at import, which was 500-ing every
  template detail page during SSR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-22 16:58:48 +03:30
parent 863b9503b3
commit a3152ee84f
11 changed files with 319 additions and 12 deletions
@@ -10,7 +10,14 @@ import {
getVideoTemplateImageSrc,
} from "@/lib/video-templates-catalog";
import { cn } from "@/lib/utils";
import { BrandedVideoPlayer } from "@/components/templates/BrandedVideoPlayer";
import dynamic from "next/dynamic";
// plyr-react references `document` at import time, which crashes server rendering
// (Next still SSRs client components for the initial HTML). Load it client-only.
const BrandedVideoPlayer = dynamic(
() => import("@/components/templates/BrandedVideoPlayer").then((m) => m.BrandedVideoPlayer),
{ ssr: false }
);
interface TemplateDetailPreviewProps {
template: VideoCatalogTemplate;