/** * Shared typography math for dashboard preview ↔ FFmpeg output parity. * Preview container uses a fixed reference width; scale from target encode resolution. */ import type { WatermarkFontKey } from "./fonts"; import { CURATED_FONTS } from "./fonts"; /** Matches LayoutStudio max preview width (tailwind max-w-xl ≈ 576px; use 576 for scaling). */ export const PREVIEW_REFERENCE_WIDTH = 576; export function titleFontSizeForWidth(width: number): number { return Math.max(22, Math.round(width * 0.032)); } export function artistFontSizeForWidth(width: number): number { return Math.max(16, Math.round(width * 0.02)); } export function watermarkFontSizeForWidth(width: number): number { return Math.max(16, Math.round(width * 0.018)); } /** Scale encode-resolution px to preview container px. */ export function scaleFontToPreview(fontPx: number, encodeWidth: number): number { const ref = encodeWidth > 0 ? encodeWidth : 1280; return Math.max(8, Math.round((fontPx * PREVIEW_REFERENCE_WIDTH) / ref)); } export function previewFontFamilyCss(fontKey: WatermarkFontKey | undefined): string { if (!fontKey || fontKey === "system") { return "Arial, Helvetica, sans-serif"; } if (fontKey === "custom") { return "'S2VIDCustomWm', Arial, sans-serif"; } const meta = CURATED_FONTS.find((f) => f.key === fontKey); return meta ? `'S2VIDPreview-${meta.key}', Arial, sans-serif` : "Arial, sans-serif"; } export function curatedFontApiUrl(key: string): string { return `/api/fonts/${key}`; } /** Watermark overlay width as fraction of frame (matches encode.ts). */ export const WATERMARK_WIDTH_FRACTION = 0.32;