Skip to main content
Glama
generate_preview.py9.47 kB
#!/usr/bin/env python3 """ Generate Static HTML Previews Creates an HTML page showcasing all themes and components for easy visual exploration without rendering videos. """ import sys from pathlib import Path # Add parent directory to path sys.path.insert(0, str(Path(__file__).parent.parent / "src")) from chuk_motion import COLOR_TOKENS, COMPONENT_REGISTRY, YOUTUBE_THEMES def generate_theme_preview_html() -> str: """Generate HTML preview of all themes.""" html_parts = [] html_parts.append(""" <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Remotion Design System Preview</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0a0e1a; color: #ffffff; padding: 40px 20px; } .container { max-width: 1400px; margin: 0 auto; } h1 { font-size: 48px; margin-bottom: 20px; text-align: center; } .subtitle { text-align: center; color: #8b92a4; margin-bottom: 60px; font-size: 18px; } .section { margin-bottom: 80px; } .section-title { font-size: 32px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #1e2535; } .theme-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 30px; } .theme-card { background: #1a1f2e; border-radius: 12px; padding: 25px; border: 1px solid #2a3142; transition: transform 0.2s, box-shadow 0.2s; } .theme-card:hover { transform: translateY(-4px); box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); } .theme-name { font-size: 24px; font-weight: 700; margin-bottom: 10px; } .theme-desc { color: #8b92a4; font-size: 14px; margin-bottom: 20px; line-height: 1.5; } .color-swatches { display: flex; gap: 10px; margin-bottom: 15px; } .color-swatch { width: 60px; height: 60px; border-radius: 8px; border: 2px solid rgba(255, 255, 255, 0.1); } .gradient-preview { height: 80px; border-radius: 8px; margin-bottom: 15px; } .use-cases { list-style: none; margin-top: 15px; } .use-cases li { padding: 6px 0; color: #a0a8b8; font-size: 13px; } .use-cases li:before { content: "→ "; color: #00d9ff; font-weight: bold; } .component-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 25px; } .component-card { background: #1a1f2e; border-radius: 12px; padding: 25px; border: 1px solid #2a3142; } .component-name { font-size: 20px; font-weight: 700; margin-bottom: 8px; color: #00d9ff; } .component-category { display: inline-block; padding: 4px 12px; background: rgba(0, 217, 255, 0.1); color: #00d9ff; border-radius: 4px; font-size: 11px; text-transform: uppercase; margin-bottom: 12px; font-weight: 600; } .component-desc { color: #8b92a4; font-size: 14px; margin-bottom: 15px; line-height: 1.5; } .variants { margin-top: 15px; } .variants-title { font-size: 13px; color: #a0a8b8; margin-bottom: 8px; text-transform: uppercase; font-weight: 600; } .variant-tags { display: flex; flex-wrap: wrap; gap: 8px; } .variant-tag { padding: 6px 12px; background: #2a3142; border-radius: 6px; font-size: 12px; color: #ffffff; } .stats { display: flex; justify-content: center; gap: 60px; margin: 60px 0; padding: 40px; background: linear-gradient(135deg, #1a1f2e 0%, #0f1419 100%); border-radius: 12px; } .stat { text-align: center; } .stat-number { font-size: 48px; font-weight: 900; background: linear-gradient(135deg, #0066FF 0%, #00D9FF 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .stat-label { color: #8b92a4; font-size: 14px; margin-top: 8px; text-transform: uppercase; letter-spacing: 1px; } </style> </head> <body> <div class="container"> <h1>🎬 Remotion Design System</h1> <p class="subtitle">Explore themes, components, and design tokens for AI-powered video generation</p> <div class="stats"> <div class="stat"> <div class="stat-number">7</div> <div class="stat-label">Themes</div> </div> <div class="stat"> <div class="stat-number">7</div> <div class="stat-label">Components</div> </div> <div class="stat"> <div class="stat-number">20+</div> <div class="stat-label">Variants</div> </div> </div> """) # Generate theme previews html_parts.append('<div class="section"><h2 class="section-title">🎨 YouTube Themes</h2><div class="theme-grid">') for theme_name, theme in YOUTUBE_THEMES.items(): colors = theme.colors primary = colors.primary[0] if isinstance(colors.primary, list) else colors.primary accent = colors.accent[0] if isinstance(colors.accent, list) else colors.accent use_cases_html = "\n".join( f'<li>{uc}</li>' for uc in theme.use_cases[:4] ) html_parts.append(f''' <div class="theme-card"> <div class="theme-name">{theme.name}</div> <div class="theme-desc">{theme.description}</div> <div class="color-swatches"> <div class="color-swatch" style="background: {primary};" title="Primary"></div> <div class="color-swatch" style="background: {accent};" title="Accent"></div> </div> <div class="gradient-preview" style="background: {colors.gradient};"></div> <ul class="use-cases"> {use_cases_html} </ul> </div> ''') html_parts.append('</div></div>') # Generate component previews html_parts.append('<div class="section"><h2 class="section-title">🎬 Component Library</h2><div class="component-grid">') for comp_name, component in COMPONENT_REGISTRY.items(): variants = component.get('variants', {}) animations = component.get('animations', {}) variant_tags = "\n".join( f'<span class="variant-tag">{v}</span>' for v in list(variants.keys())[:5] ) animation_tags = "\n".join( f'<span class="variant-tag">✨ {a}</span>' for a in list(animations.keys())[:5] ) html_parts.append(f''' <div class="component-card"> <div class="component-category">{component['category']}</div> <div class="component-name">{comp_name}</div> <div class="component-desc">{component['description']}</div> {f'<div class="variants"><div class="variants-title">Variants</div><div class="variant-tags">{variant_tags}</div></div>' if variants else ''} {f'<div class="variants"><div class="variants-title">Animations</div><div class="variant-tags">{animation_tags}</div></div>' if animations else ''} </div> ''') html_parts.append('</div></div>') html_parts.append(""" <div style="text-align: center; margin-top: 80px; padding: 40px; color: #8b92a4;"> <p>Built with ❤️ using <strong>chuk-motion</strong></p> <p style="margin-top: 10px;">AI-powered video generation for YouTube</p> </div> </div> </body> </html> """) return "\n".join(html_parts) def main(): """Generate and save the preview HTML.""" print("Generating design system preview...") html = generate_theme_preview_html() output_path = Path("design-system-preview.html") output_path.write_text(html) print(f"\n✅ Preview generated: {output_path.absolute()}") print(f"\n📂 Open in browser: file://{output_path.absolute()}") print("\n💡 Tip: You can also run:") print(f" open {output_path.name} # macOS") print(f" xdg-open {output_path.name} # Linux") print(f" start {output_path.name} # Windows") if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chrishayuk/chuk-mcp-remotion'

If you have feedback or need assistance with the MCP directory API, please join our Discord server