From dfeb358bb8e466ced9eefbdd08bef40668d33463 Mon Sep 17 00:00:00 2001 From: SnapOtter Date: Fri, 8 May 2026 16:11:57 +0800 Subject: [PATCH] feat(videos): add motion design system, colors, fonts, and tools data --- apps/videos/src/lib/colors.ts | 48 +++++++++++++++++++++++++ apps/videos/src/lib/fonts.ts | 67 ++++++++++++++++++++++++++++++++++ apps/videos/src/lib/motion.ts | 30 ++++++++++++++++ apps/videos/src/lib/tools.ts | 68 +++++++++++++++++++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 apps/videos/src/lib/colors.ts create mode 100644 apps/videos/src/lib/fonts.ts create mode 100644 apps/videos/src/lib/motion.ts create mode 100644 apps/videos/src/lib/tools.ts diff --git a/apps/videos/src/lib/colors.ts b/apps/videos/src/lib/colors.ts new file mode 100644 index 00000000..59aadbdd --- /dev/null +++ b/apps/videos/src/lib/colors.ts @@ -0,0 +1,48 @@ +export const COLOR = { + accent: "#f59e0b", + accentHover: "#d97706", + dark: "#0c0a09", + darkAlt: "#1a1a2e", + light: "#ffffff", + lightAlt: "#fafaf9", + warmGradientFrom: "#f59e0b", + warmGradientVia: "#f97316", + warmGradientTo: "#ef4444", + category: { + essentials: "#3B82F6", + optimization: "#10B981", + adjustments: "#8B5CF6", + watermark: "#EF4444", + utilities: "#6366F1", + layout: "#EC4899", + format: "#14B8A6", + ai: "#F59E0B", + } as Record, + safe: "#22c55e", + danger: "#ef4444", + muted: "#737373", + cloudRed: "#fef2f2", + localGreen: "#f0fdf4", +}; + +export const CATEGORY_ORDER = [ + "essentials", + "optimization", + "adjustments", + "ai", + "watermark", + "utilities", + "layout", + "format", +] as const; + +export const CATEGORY_LABELS: Record = { + essentials: "Essentials", + optimization: "Optimization", + adjustments: "Adjustments", + ai: "AI Tools", + watermark: "Watermark", + utilities: "Utilities", + layout: "Layout", + format: "Format", +}; diff --git a/apps/videos/src/lib/fonts.ts b/apps/videos/src/lib/fonts.ts new file mode 100644 index 00000000..ba1f3097 --- /dev/null +++ b/apps/videos/src/lib/fonts.ts @@ -0,0 +1,67 @@ +import { loadFont as loadInter } from "@remotion/google-fonts/Inter"; +import { loadFont as loadJetBrainsMono } from "@remotion/google-fonts/JetBrainsMono"; +import { loadFont as loadNunito } from "@remotion/google-fonts/Nunito"; + +const { fontFamily: nunito } = loadNunito(); +const { fontFamily: inter } = loadInter(); +const { fontFamily: mono } = loadJetBrainsMono(); + +export const FONT = { heading: nunito, body: inter, mono }; + +export const TEXT = { + heroHeadline: { + fontFamily: nunito, + fontWeight: 800, + fontSize: 72, + letterSpacing: "-0.02em", + lineHeight: 1.1, + color: "white", + }, + heroSub: { + fontFamily: inter, + fontWeight: 500, + fontSize: 28, + letterSpacing: "0em", + lineHeight: 1.4, + color: "white", + }, + sectionTitle: { + fontFamily: nunito, + fontWeight: 700, + fontSize: 48, + letterSpacing: "-0.01em", + color: "white", + }, + label: { + fontFamily: inter, + fontWeight: 600, + fontSize: 18, + letterSpacing: "0.04em", + textTransform: "uppercase" as const, + }, + body: { + fontFamily: inter, + fontWeight: 400, + fontSize: 20, + lineHeight: 1.5, + }, + mono: { + fontFamily: mono, + fontWeight: 400, + fontSize: 16, + lineHeight: 1.6, + }, + toolPill: { + fontFamily: inter, + fontWeight: 600, + fontSize: 14, + letterSpacing: "0.01em", + }, + counter: { + fontFamily: nunito, + fontWeight: 800, + fontSize: 96, + letterSpacing: "-0.03em", + color: "white", + }, +} as const; diff --git a/apps/videos/src/lib/motion.ts b/apps/videos/src/lib/motion.ts new file mode 100644 index 00000000..eb8a0206 --- /dev/null +++ b/apps/videos/src/lib/motion.ts @@ -0,0 +1,30 @@ +import { Easing } from "remotion"; + +export const EASE = { + enter: Easing.bezier(0.16, 1, 0.3, 1), + exit: Easing.bezier(0.55, 0, 1, 0.45), + emphasis: Easing.bezier(0.34, 1.56, 0.64, 1), + smooth: Easing.bezier(0.37, 0, 0.63, 1), + snap: Easing.bezier(0.22, 1, 0.36, 1), +}; + +export const SPRING = { + snappy: { damping: 200, stiffness: 100, mass: 0.5 }, + natural: { damping: 15, stiffness: 80, mass: 1 }, + popIn: { damping: 12, stiffness: 200, mass: 0.6 }, + heavy: { damping: 20, stiffness: 60, mass: 2 }, + settle: { damping: 18, stiffness: 150, mass: 0.8 }, +}; + +export const TIMING = { + fps: 30, + staggerFrames: 2, + holdShort: 30, + holdMedium: 60, + holdLong: 90, + fadeIn: 12, + fadeOut: 8, + wipe: 18, + sectionGap: 12, + anticipation: 3, +}; diff --git a/apps/videos/src/lib/tools.ts b/apps/videos/src/lib/tools.ts new file mode 100644 index 00000000..bd9f3117 --- /dev/null +++ b/apps/videos/src/lib/tools.ts @@ -0,0 +1,68 @@ +export interface ToolDef { + name: string; + category: string; +} + +export const TOOLS: ToolDef[] = [ + // Essentials + { name: "Resize", category: "essentials" }, + { name: "Crop", category: "essentials" }, + { name: "Rotate & Flip", category: "essentials" }, + { name: "Convert", category: "essentials" }, + { name: "Compress", category: "essentials" }, + // Optimization + { name: "Optimize for Web", category: "optimization" }, + { name: "Remove Metadata", category: "optimization" }, + { name: "Edit Metadata", category: "optimization" }, + { name: "Bulk Rename", category: "optimization" }, + { name: "Image to PDF", category: "optimization" }, + { name: "Favicon Generator", category: "optimization" }, + // Adjustments + { name: "Adjust Colors", category: "adjustments" }, + { name: "Sharpening", category: "adjustments" }, + { name: "Replace & Invert Color", category: "adjustments" }, + { name: "Color Blindness Simulation", category: "adjustments" }, + // AI Tools + { name: "Remove Background", category: "ai" }, + { name: "Image Upscaling", category: "ai" }, + { name: "Object Eraser", category: "ai" }, + { name: "OCR / Text Extraction", category: "ai" }, + { name: "Face / PII Blur", category: "ai" }, + { name: "Smart Crop", category: "ai" }, + { name: "Image Enhancement", category: "ai" }, + { name: "Face Enhancement", category: "ai" }, + { name: "AI Colorization", category: "ai" }, + { name: "Noise Removal", category: "ai" }, + { name: "Red Eye Removal", category: "ai" }, + { name: "Photo Restoration", category: "ai" }, + { name: "Passport Photo", category: "ai" }, + { name: "Content-Aware Resize", category: "ai" }, + { name: "PNG Transparency Fixer", category: "ai" }, + // Watermark & Overlay + { name: "Text Watermark", category: "watermark" }, + { name: "Image Watermark", category: "watermark" }, + { name: "Text Overlay", category: "watermark" }, + { name: "Image Composition", category: "watermark" }, + // Utilities + { name: "Image Info", category: "utilities" }, + { name: "Image Compare", category: "utilities" }, + { name: "Find Duplicates", category: "utilities" }, + { name: "Color Palette", category: "utilities" }, + { name: "QR Code Generator", category: "utilities" }, + { name: "Barcode Reader", category: "utilities" }, + { name: "Image to Base64", category: "utilities" }, + // Layout & Composition + { name: "Collage / Grid", category: "layout" }, + { name: "Stitch / Combine", category: "layout" }, + { name: "Image Splitting", category: "layout" }, + { name: "Border & Frame", category: "layout" }, + // Format & Conversion + { name: "SVG to Raster", category: "format" }, + { name: "Image to SVG", category: "format" }, + { name: "GIF Tools", category: "format" }, + { name: "PDF to Image", category: "format" }, +]; + +export function getToolsByCategory(category: string): ToolDef[] { + return TOOLS.filter((t) => t.category === category); +}