style: drop all type weight from medium (500) to normal (400)

DM Sans at weight 400 is clean and readable — hierarchy now comes
entirely from size, not weight. Lighter overall feel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Simeon.Schecter 2026-03-09 22:44:32 -04:00
parent 0093b6dc92
commit c5002b8c6b
8 changed files with 112 additions and 112 deletions

View file

@ -98,7 +98,7 @@ function AppContent() {
<div className="flex flex-col items-end gap-1">
{activeProjectName && (
<div className="text-sm text-slate-400">
Working in: <span className="text-cinema-gold font-medium">{activeProjectName}</span>
Working in: <span className="text-cinema-gold font-normal">{activeProjectName}</span>
</div>
)}
<div className="text-xs text-slate-500">

View file

@ -1419,14 +1419,14 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Left Column: Controls */}
<div className="lg:col-span-4">
<div className="bg-slate-900/50 border border-slate-800 rounded p-6 space-y-6">
<h2 className="text-lg font-medium text-slate-200 flex items-center space-x-2">
<h2 className="text-lg font-normal text-slate-200 flex items-center space-x-2">
<Camera className="w-5 h-5 text-cinema-gold" />
<span>Technical Specs</span>
</h2>
{/* Application/Lighting Preset */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400 flex items-center gap-2">
<label className="text-xs font-normal text-slate-400 flex items-center gap-2">
Preset
<span className="text-xs font-normal normal-case text-slate-500">Lighting / application presets + Styles</span>
{customPresets.length > 0 && (
@ -1538,7 +1538,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Camera Body */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Camera Body
</label>
<select
@ -1557,7 +1557,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Lens Kit */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Lens Kit
</label>
<select
@ -1576,7 +1576,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Aspect Ratio */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Aspect Ratio
</label>
<div className="flex flex-wrap gap-2">
@ -1584,7 +1584,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<button
key={ratio}
onClick={() => setAspectRatio(ratio)}
className={`px-4 py-2 rounded font-medium transition-all ${
className={`px-4 py-2 rounded font-normal transition-all ${
aspectRatio === ratio
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1609,7 +1609,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Creative Freedom Slider - Moved to left column */}
<div className="space-y-3 pt-4 border-t border-slate-800">
<div className="flex items-center justify-between">
<label className="text-xs font-medium text-slate-400 flex items-center gap-2">
<label className="text-xs font-normal text-slate-400 flex items-center gap-2">
<Sliders className="w-4 h-4" />
Creative Freedom
</label>
@ -1636,7 +1636,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Scene Description - Moved to left column */}
<div className="space-y-3">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Scene Description
</label>
<textarea
@ -1651,7 +1651,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<button
onClick={generateOptimizedPrompt}
disabled={isGenerating}
className="flex items-center justify-center space-x-2 w-full px-4 py-3 bg-slate-200 hover:bg-slate-300 text-slate-900 font-medium rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
className="flex items-center justify-center space-x-2 w-full px-4 py-3 bg-slate-200 hover:bg-slate-300 text-slate-900 font-normal rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
>
{isGenerating ? (
<>
@ -1668,7 +1668,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<button
onClick={generateSimplePrompt}
className="w-full px-4 py-3 bg-slate-800 hover:bg-slate-700 text-slate-300 font-medium rounded transition-all"
className="w-full px-4 py-3 bg-slate-800 hover:bg-slate-700 text-slate-300 font-normal rounded transition-all"
>
Simple Generate
</button>
@ -1688,7 +1688,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Generated Prompt Output */}
<div className="relative bg-slate-900 border border-slate-800 rounded overflow-hidden">
<div className="p-6 space-y-4">
<h3 className="text-xs font-medium text-slate-400">
<h3 className="text-xs font-normal text-slate-400">
Optimized Prompt
</h3>
<div className="flex items-center gap-1.5 text-xs text-emerald-400/70 mt-1">
@ -1709,7 +1709,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<div className="flex items-center justify-between pt-4 border-t border-slate-800">
<button
onClick={copyToClipboard}
className="flex items-center space-x-2 px-5 py-2.5 bg-white hover:bg-slate-100 text-slate-950 font-medium rounded transition-all"
className="flex items-center space-x-2 px-5 py-2.5 bg-white hover:bg-slate-100 text-slate-950 font-normal rounded transition-all"
>
{copied ? (
<>
@ -1735,7 +1735,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Image Generation Panel */}
<div className="bg-slate-900/50 border border-slate-800 rounded p-6 space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium text-slate-200 flex items-center gap-2">
<h3 className="text-lg font-normal text-slate-200 flex items-center gap-2">
<Image className="w-5 h-5 text-cinema-gold" />
Generated Image
</h3>
@ -1758,7 +1758,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Reference Images Upload */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-xs font-medium text-slate-400">Reference Images (Optional)</label>
<label className="text-xs font-normal text-slate-400">Reference Images (Optional)</label>
<span className="text-xs text-slate-500">{referenceImages.length}/14</span>
</div>
<div className="flex flex-wrap gap-2">
@ -1812,7 +1812,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{showProjectPicker && projectImages.length > 0 && (
<div className="bg-slate-800 border border-slate-700 rounded p-3">
<div className="flex items-center justify-between mb-2">
<span className="text-xs font-medium text-slate-400">From Project</span>
<span className="text-xs font-normal text-slate-400">From Project</span>
<button
onClick={() => setShowProjectPicker(false)}
className="text-slate-500 hover:text-slate-300"
@ -1850,13 +1850,13 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Model Selector */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Model</label>
<label className="text-xs font-normal text-slate-400">Model</label>
<div className="flex gap-2">
{imageModelOptions.map((opt) => (
<button
key={opt.value}
onClick={() => setImageModelType(opt.value)}
className={`flex-1 px-3 py-2 rounded font-medium transition-all text-sm ${
className={`flex-1 px-3 py-2 rounded font-normal transition-all text-sm ${
imageModelType === opt.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1871,13 +1871,13 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{/* Resolution Selector */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Output Resolution</label>
<label className="text-xs font-normal text-slate-400">Output Resolution</label>
<div className="flex gap-2">
{['1K', '2K', '4K'].map((res) => (
<button
key={res}
onClick={() => setImageResolution(res)}
className={`px-4 py-2 rounded text-sm font-medium transition-all ${
className={`px-4 py-2 rounded text-sm font-normal transition-all ${
imageResolution === res
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1948,7 +1948,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<button
onClick={generateImage}
disabled={!generatedPrompt || isGeneratingImage}
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-medium rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-normal rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
>
{isGeneratingImage ? (
<>
@ -2032,7 +2032,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<div className="fixed inset-0 bg-black/60 z-50 flex items-center justify-center p-4">
<div className="bg-slate-900 border border-slate-700 rounded w-full max-w-md p-6 space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium text-slate-200">
<h3 className="text-lg font-normal text-slate-200">
{editingPreset ? 'Edit Preset' : 'Create New Preset'}
</h3>
<button onClick={() => setShowPresetModal(false)} className="text-slate-500 hover:text-slate-300">
@ -2042,7 +2042,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<div className="space-y-3">
<div>
<label className="text-xs font-medium text-slate-400">Preset Name *</label>
<label className="text-xs font-normal text-slate-400">Preset Name *</label>
<input
type="text"
value={presetForm.name}
@ -2053,7 +2053,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
</div>
<div>
<label className="text-xs font-medium text-slate-400">Lighting Description *</label>
<label className="text-xs font-normal text-slate-400">Lighting Description *</label>
<textarea
value={presetForm.lighting}
onChange={(e) => setPresetForm({ ...presetForm, lighting: e.target.value })}
@ -2065,7 +2065,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<div className="grid grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-slate-400">Default Camera</label>
<label className="text-xs font-normal text-slate-400">Default Camera</label>
<select
value={presetForm.defaultCamera}
onChange={(e) => setPresetForm({ ...presetForm, defaultCamera: e.target.value })}
@ -2078,7 +2078,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-400">Default Lens</label>
<label className="text-xs font-normal text-slate-400">Default Lens</label>
<select
value={presetForm.defaultLens}
onChange={(e) => setPresetForm({ ...presetForm, defaultLens: e.target.value })}
@ -2094,7 +2094,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
<label className="text-xs font-medium text-slate-400">Focus Mode</label>
<label className="text-xs font-normal text-slate-400">Focus Mode</label>
<select
value={presetForm.focusType}
onChange={(e) => setPresetForm({ ...presetForm, focusType: e.target.value })}
@ -2126,7 +2126,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<button
onClick={handleSavePreset}
disabled={!presetForm.name.trim() || !presetForm.lighting.trim()}
className="px-4 py-2 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-medium rounded text-sm transition-all disabled:opacity-50 disabled:cursor-not-allowed"
className="px-4 py-2 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-normal rounded text-sm transition-all disabled:opacity-50 disabled:cursor-not-allowed"
>
{editingPreset ? 'Save Changes' : 'Create Preset'}
</button>
@ -2140,7 +2140,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<div className="fixed inset-0 bg-black/60 z-50 flex items-center justify-center p-4">
<div className="bg-slate-900 border border-slate-700 rounded w-full max-w-lg p-6 space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium text-slate-200">Manage Custom Presets</h3>
<h3 className="text-lg font-normal text-slate-200">Manage Custom Presets</h3>
<button onClick={() => setShowManagePresetsModal(false)} className="text-slate-500 hover:text-slate-300">
<X className="w-5 h-5" />
</button>
@ -2153,7 +2153,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
{customPresets.map((p) => (
<div key={p.id} className="flex items-center justify-between bg-slate-800 rounded px-4 py-3">
<div>
<div className="text-sm text-slate-200 font-medium">{p.name}</div>
<div className="text-sm text-slate-200 font-normal">{p.name}</div>
<div className="text-xs text-slate-500 truncate max-w-xs">{p.lighting}</div>
</div>
<div className="flex items-center gap-2">
@ -2186,7 +2186,7 @@ Return ONLY the final prompt text. No markdown, no preamble, no "Here is your pr
<div className="flex items-center gap-2 pt-2 border-t border-slate-800">
<button
onClick={openCreatePresetModal}
className="flex items-center gap-1.5 px-3 py-2 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-medium rounded text-sm transition-all"
className="flex items-center gap-1.5 px-3 py-2 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-normal rounded text-sm transition-all"
>
<Plus className="w-4 h-4" />
New Preset

View file

@ -22,7 +22,7 @@ const LoginPage = () => {
alt="Lux Studio"
className="h-16 w-auto mx-auto mb-6"
/>
<h1 className="text-3xl font-medium text-slate-100 mb-2">
<h1 className="text-3xl font-normal text-slate-100 mb-2">
Welcome to Lux Studio
</h1>
<p className="text-slate-400">
@ -33,7 +33,7 @@ const LoginPage = () => {
<div className="bg-slate-900 rounded p-8 shadow-sm border border-slate-800">
<button
onClick={handleLogin}
className="w-full bg-cinema-gold hover:bg-yellow-500 text-slate-950 font-medium py-3 px-6 rounded transition-colors flex items-center justify-center gap-3"
className="w-full bg-cinema-gold hover:bg-yellow-500 text-slate-950 font-normal py-3 px-6 rounded transition-colors flex items-center justify-center gap-3"
>
<svg className="w-5 h-5" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h10v10H0V0z" fill="#f25022"/>

View file

@ -577,7 +577,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
<div className="lg:col-span-4">
<div className="bg-slate-900/50 border border-slate-800 rounded p-6 space-y-4">
<div className="flex items-center justify-between">
<h2 className="text-lg font-medium text-slate-200 flex items-center space-x-2">
<h2 className="text-lg font-normal text-slate-200 flex items-center space-x-2">
<FolderOpen className="w-5 h-5 text-cinema-gold" />
<span>Projects</span>
</h2>
@ -683,7 +683,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
) : (
<>
<div className="flex items-center justify-between">
<h3 className="font-medium text-slate-200 truncate">{project.name}</h3>
<h3 className="font-normal text-slate-200 truncate">{project.name}</h3>
<div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
<button
onClick={(e) => {
@ -729,7 +729,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
{/* Project Header */}
<div className="flex items-center justify-between pb-4 border-b border-slate-800">
<div>
<h2 className="text-xl font-medium text-slate-200">{selectedProject.name}</h2>
<h2 className="text-xl font-normal text-slate-200">{selectedProject.name}</h2>
<p className="text-xs text-slate-500 mt-1">
Created {formatDate(selectedProject.createdAt)} · {selectedProjectItems.length} items
</p>
@ -802,7 +802,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
<div className="flex items-center gap-2">
<button
onClick={handleUpdateStoryboardFrames}
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-medium transition-all"
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-normal transition-all"
>
<Check className="w-4 h-4" />
Update Frames
@ -822,7 +822,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
) : (
<button
onClick={() => setIsCreatingStoryboard(true)}
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-medium transition-all"
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-normal transition-all"
>
<Layers className="w-4 h-4" />
Create Storyboard
@ -895,7 +895,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
{/* Create Storyboard Modal */}
{isCreatingStoryboard && (
<div className="bg-slate-800/80 border border-slate-700 rounded p-4">
<h3 className="text-sm font-medium text-slate-200 mb-2">Name your storyboard</h3>
<h3 className="text-sm font-normal text-slate-200 mb-2">Name your storyboard</h3>
<div className="flex gap-2">
<input
type="text"
@ -909,7 +909,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
<button
onClick={handleCreateStoryboard}
disabled={!newStoryboardName.trim()}
className="px-4 py-2 bg-cinema-gold hover:bg-amber-400 disabled:bg-slate-700 disabled:text-slate-500 text-slate-950 rounded text-sm font-medium transition-all"
className="px-4 py-2 bg-cinema-gold hover:bg-amber-400 disabled:bg-slate-700 disabled:text-slate-500 text-slate-950 rounded text-sm font-normal transition-all"
>
Create
</button>
@ -931,7 +931,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
<div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4">
<div className="bg-slate-900 border border-slate-700 rounded p-6 max-w-4xl w-full max-h-[80vh] overflow-y-auto">
<div className="flex items-center justify-between mb-4">
<h2 className="text-xl font-medium text-slate-200">Import from Backend</h2>
<h2 className="text-xl font-normal text-slate-200">Import from Backend</h2>
<button
onClick={() => setShowImportModal(false)}
className="p-2 hover:bg-slate-800 rounded transition-colors"
@ -963,7 +963,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
{availableSessions.map((session) => (
<div key={session.session_id} className="bg-slate-800/50 border border-slate-700 rounded p-4">
<div className="flex items-center justify-between mb-3">
<h3 className="text-sm font-medium text-slate-300">
<h3 className="text-sm font-normal text-slate-300">
Session: {session.session_id.substring(0, 8)}...
</h3>
<span className="text-xs text-slate-500">
@ -974,7 +974,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
{/* Images */}
{session.images.length > 0 && (
<div className="space-y-2">
<h4 className="text-xs font-medium text-slate-400">Images</h4>
<h4 className="text-xs font-normal text-slate-400">Images</h4>
<div className="grid grid-cols-2 md:grid-cols-4 gap-2">
{session.images.map((img) => {
const fileKey = `${session.session_id}:image:${img.filename}`;
@ -1013,7 +1013,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
{/* Videos - Hidden for now since import not supported */}
{false && session.videos.length > 0 && (
<div className="space-y-2 mt-4">
<h4 className="text-xs font-medium text-slate-400">Videos (Import Not Supported)</h4>
<h4 className="text-xs font-normal text-slate-400">Videos (Import Not Supported)</h4>
<div className="grid grid-cols-2 md:grid-cols-4 gap-2">
{session.videos.map((vid) => {
const expiresIn = Math.floor(vid.time_remaining / 3600);
@ -1055,7 +1055,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
<button
onClick={handleImportFiles}
disabled={selectedFiles.length === 0 || importing}
className="flex items-center gap-2 px-4 py-2 bg-cinema-gold hover:bg-amber-400 disabled:bg-slate-700 disabled:text-slate-500 text-slate-950 rounded text-sm font-medium transition-all"
className="flex items-center gap-2 px-4 py-2 bg-cinema-gold hover:bg-amber-400 disabled:bg-slate-700 disabled:text-slate-500 text-slate-950 rounded text-sm font-normal transition-all"
>
{importing ? (
<>
@ -1161,7 +1161,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
})()}
{/* Type Badge */}
<div className={`absolute top-2 left-2 px-2 py-1 rounded text-xs font-medium ${
<div className={`absolute top-2 left-2 px-2 py-1 rounded text-xs font-normal ${
item.type === 'image'
? 'bg-blue-900/80 text-blue-300'
: item.settings?.engine === 'kling'
@ -1275,7 +1275,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
<div className="absolute right-0 top-full mt-1 z-20 bg-slate-800 border border-slate-700 rounded py-1 min-w-[180px]"
onClick={(e) => e.stopPropagation()}
>
<div className="px-3 py-1.5 text-xs font-medium text-slate-500 uppercase tracking-wider">Move to...</div>
<div className="px-3 py-1.5 text-xs font-normal text-slate-500 uppercase tracking-wider">Move to...</div>
{projects
.filter(p => p.id !== selectedProject?.id)
.map(p => (
@ -1339,7 +1339,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
setActiveSubTab('library');
setIsSelecting(true);
}}
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-medium transition-all"
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-normal transition-all"
>
<Plus className="w-4 h-4" />
New Storyboard
@ -1357,7 +1357,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
setActiveSubTab('library');
setIsSelecting(true);
}}
className="mt-4 px-4 py-2 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-medium transition-all"
className="mt-4 px-4 py-2 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-normal transition-all"
>
Select Images
</button>
@ -1371,7 +1371,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
className="group p-4 bg-slate-800/50 rounded border border-slate-700 hover:border-cinema-gold transition-all cursor-pointer"
>
<div className="flex items-center justify-between mb-3">
<h3 className="font-medium text-slate-200">{board.name}</h3>
<h3 className="font-normal text-slate-200">{board.name}</h3>
<span className="text-xs text-slate-500">{board.frames?.length || 0} frames</span>
</div>
{/* Frame thumbnails preview */}
@ -1496,7 +1496,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
)}
{previewItem.type === 'video' && (
<div className="mt-2 flex gap-1.5">
<span className={`text-xs px-2 py-0.5 rounded-full font-medium ${
<span className={`text-xs px-2 py-0.5 rounded-full font-normal ${
previewItem.settings?.engine === 'kling'
? 'bg-indigo-900/50 text-indigo-300 border border-indigo-700'
: 'bg-emerald-900/50 text-emerald-300 border border-emerald-700'
@ -1528,7 +1528,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
});
setPreviewItem(null);
}}
className="flex items-center gap-2 px-3 py-1.5 bg-slate-200 hover:bg-slate-300 text-slate-900 rounded text-sm font-medium transition-colors"
className="flex items-center gap-2 px-3 py-1.5 bg-slate-200 hover:bg-slate-300 text-slate-900 rounded text-sm font-normal transition-colors"
>
<Wand2 className="w-4 h-4" />
Edit in Image Gen
@ -1548,7 +1548,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
});
setPreviewItem(null);
}}
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-medium transition-colors"
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-normal transition-colors"
>
<Video className="w-4 h-4" />
Generate Video
@ -1565,7 +1565,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
});
setPreviewItem(null);
}}
className="flex items-center gap-2 px-3 py-1.5 bg-slate-200 hover:bg-slate-300 text-slate-900 rounded text-sm font-medium transition-colors"
className="flex items-center gap-2 px-3 py-1.5 bg-slate-200 hover:bg-slate-300 text-slate-900 rounded text-sm font-normal transition-colors"
>
<RefreshCw className="w-4 h-4" />
Re-run
@ -1576,7 +1576,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
<div className="relative">
<button
onClick={() => setMovingItemId(movingItemId === previewItem.id ? null : previewItem.id)}
className={`flex items-center gap-2 px-3 py-1.5 rounded text-sm font-medium transition-colors ${
className={`flex items-center gap-2 px-3 py-1.5 rounded text-sm font-normal transition-colors ${
movingItemId === previewItem.id
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-700 hover:bg-slate-600 text-slate-300'
@ -1615,7 +1615,7 @@ const ProjectsTab = ({ onProjectSelect, activeProjectId, onRerunVideo, onEditInI
)}
<button
onClick={() => downloadItem(previewItem)}
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-medium transition-colors"
className="flex items-center gap-2 px-3 py-1.5 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-normal transition-colors"
>
<Download className="w-4 h-4" />
Download

View file

@ -76,7 +76,7 @@ const SortableFrame = ({ frame, frameItem, index, onAnnotationChange, onDelete,
>
<GripVertical className="w-4 h-4 text-slate-500" />
</button>
<span className="text-xs font-medium text-slate-400">Frame {index + 1}</span>
<span className="text-xs font-normal text-slate-400">Frame {index + 1}</span>
</div>
<button
onClick={() => onDelete(frame.imageId)}
@ -153,7 +153,7 @@ const SortableFrame = ({ frame, frameItem, index, onAnnotationChange, onDelete,
<div className="px-3 pb-3">
<button
onClick={() => onGenerateVideo(frame, frameItem)}
className="w-full flex items-center justify-center gap-2 px-3 py-2 bg-slate-200 hover:bg-slate-300 text-slate-900 rounded text-sm font-medium transition-colors"
className="w-full flex items-center justify-center gap-2 px-3 py-2 bg-slate-200 hover:bg-slate-300 text-slate-900 rounded text-sm font-normal transition-colors"
>
<Video className="w-4 h-4" />
Generate Video
@ -586,7 +586,7 @@ const StoryboardEditor = ({
</div>
) : (
<div className="flex items-center gap-2">
<h2 className="text-xl font-medium text-slate-200">{name}</h2>
<h2 className="text-xl font-normal text-slate-200">{name}</h2>
<button
onClick={() => setIsEditingName(true)}
className="p-1 hover:bg-slate-700 rounded"
@ -609,7 +609,7 @@ const StoryboardEditor = ({
<div className="flex items-center gap-2">
<button
onClick={() => onEditFrames(storyboard.id, frames.map(f => f.imageId))}
className="flex items-center gap-2 px-3 py-2 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-medium transition-colors"
className="flex items-center gap-2 px-3 py-2 bg-cinema-gold hover:bg-amber-400 text-slate-950 rounded text-sm font-normal transition-colors"
>
<Plus className="w-4 h-4" />
Edit Frames

View file

@ -22,7 +22,7 @@ const TabNavigation = ({ activeTab, onTabChange, activeProjectId }) => {
onClick={() => !isDisabled && onTabChange(tab.id)}
disabled={isDisabled}
title={isDisabled ? 'Select a project first' : tab.label}
className={`relative flex items-center gap-2 px-1 py-2 font-medium transition-all ${
className={`relative flex items-center gap-2 px-1 py-2 font-normal transition-all ${
isDisabled
? 'text-slate-600 cursor-not-allowed'
: isActive

View file

@ -1031,14 +1031,14 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<div className="lg:col-span-4 space-y-6">
{/* Video Settings */}
<div className="bg-slate-900/50 border border-slate-800 rounded p-6 space-y-6">
<h2 className="text-lg font-medium text-slate-200 flex items-center space-x-2">
<h2 className="text-lg font-normal text-slate-200 flex items-center space-x-2">
<Video className="w-5 h-5 text-cinema-gold" />
<span>Video Settings</span>
</h2>
{/* Engine Selector */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Engine
</label>
<div className="flex gap-2">
@ -1046,7 +1046,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<button
key={opt.value}
onClick={() => setEngine(opt.value)}
className={`flex-1 px-3 py-2 rounded font-medium transition-all text-sm ${
className={`flex-1 px-3 py-2 rounded font-normal transition-all text-sm ${
engine === opt.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1066,7 +1066,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<>
{/* Model */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Model
</label>
<div className="flex gap-2">
@ -1074,7 +1074,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<button
key={opt.value}
onClick={() => setModelType(opt.value)}
className={`flex-1 px-3 py-2 rounded font-medium transition-all text-sm ${
className={`flex-1 px-3 py-2 rounded font-normal transition-all text-sm ${
modelType === opt.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1089,7 +1089,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Duration */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Duration
</label>
<div className="flex gap-2">
@ -1100,7 +1100,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
key={opt.value}
onClick={() => !isDisabledByInterpolation && setDuration(opt.value)}
disabled={isDisabledByInterpolation}
className={`flex-1 px-3 py-2 rounded font-medium transition-all text-sm ${
className={`flex-1 px-3 py-2 rounded font-normal transition-all text-sm ${
duration === opt.value
? 'bg-cinema-gold text-slate-950'
: isDisabledByInterpolation
@ -1123,7 +1123,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Aspect Ratio */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Aspect Ratio
</label>
<div className="flex gap-2">
@ -1131,7 +1131,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<button
key={ratio}
onClick={() => setAspectRatio(ratio)}
className={`flex-1 px-4 py-2 rounded font-medium transition-all ${
className={`flex-1 px-4 py-2 rounded font-normal transition-all ${
aspectRatio === ratio
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1145,7 +1145,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Resolution */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Resolution
</label>
<div className="flex gap-2">
@ -1156,7 +1156,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
key={res}
onClick={() => !isHighResDisabled && setResolution(res)}
disabled={isHighResDisabled}
className={`flex-1 px-4 py-2 rounded font-medium transition-all ${
className={`flex-1 px-4 py-2 rounded font-normal transition-all ${
resolution === res
? 'bg-cinema-gold text-slate-950'
: isHighResDisabled
@ -1180,12 +1180,12 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Audio Toggle */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Audio
</label>
<button
onClick={() => setGenerateAudio(!generateAudio)}
className={`w-full flex items-center justify-between px-4 py-2.5 rounded font-medium transition-all text-sm ${
className={`w-full flex items-center justify-between px-4 py-2.5 rounded font-normal transition-all text-sm ${
generateAudio
? 'bg-green-900/50 text-green-400 border border-green-800'
: 'bg-slate-800 text-slate-400 border border-slate-700'
@ -1208,7 +1208,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<>
{/* Kling Workflow Selector */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Workflow
</label>
<div className="flex gap-1.5">
@ -1216,7 +1216,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<button
key={opt.value}
onClick={() => setKlingWorkflow(opt.value)}
className={`flex-1 px-2 py-1.5 rounded font-medium transition-all text-sm ${
className={`flex-1 px-2 py-1.5 rounded font-normal transition-all text-sm ${
klingWorkflow === opt.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1235,13 +1235,13 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<>
{/* Kling Model */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Model</label>
<label className="text-xs font-normal text-slate-400">Model</label>
<div className="grid grid-cols-2 gap-2">
{klingModelOptions.map((opt) => (
<button
key={opt.value}
onClick={() => setKlingModel(opt.value)}
className={`px-2 py-1.5 rounded font-medium transition-all text-sm ${
className={`px-2 py-1.5 rounded font-normal transition-all text-sm ${
klingModel === opt.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1256,13 +1256,13 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Duration */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Duration</label>
<label className="text-xs font-normal text-slate-400">Duration</label>
<div className="flex gap-2">
{[5, 10].map((d) => (
<button
key={d}
onClick={() => setDuration(d)}
className={`flex-1 px-3 py-2 rounded font-medium transition-all text-sm ${
className={`flex-1 px-3 py-2 rounded font-normal transition-all text-sm ${
duration === d
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1276,13 +1276,13 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Aspect Ratio */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Aspect Ratio</label>
<label className="text-xs font-normal text-slate-400">Aspect Ratio</label>
<div className="flex gap-2">
{['16:9', '9:16', '1:1'].map((ratio) => (
<button
key={ratio}
onClick={() => setAspectRatio(ratio)}
className={`flex-1 px-3 py-2 rounded font-medium transition-all text-sm ${
className={`flex-1 px-3 py-2 rounded font-normal transition-all text-sm ${
aspectRatio === ratio
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1296,13 +1296,13 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Mode (Std/Pro) */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Quality Mode</label>
<label className="text-xs font-normal text-slate-400">Quality Mode</label>
<div className="flex gap-2">
{[{ value: 'std', label: 'Standard' }, { value: 'pro', label: 'Pro' }].map((opt) => (
<button
key={opt.value}
onClick={() => setKlingMode(opt.value)}
className={`flex-1 px-3 py-2 rounded font-medium transition-all text-sm ${
className={`flex-1 px-3 py-2 rounded font-normal transition-all text-sm ${
klingMode === opt.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1316,10 +1316,10 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Sound Toggle */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Sound</label>
<label className="text-xs font-normal text-slate-400">Sound</label>
<button
onClick={() => setKlingSound(!klingSound)}
className={`w-full flex items-center justify-between px-4 py-2.5 rounded font-medium transition-all text-sm ${
className={`w-full flex items-center justify-between px-4 py-2.5 rounded font-normal transition-all text-sm ${
klingSound
? 'bg-green-900/50 text-green-400 border border-green-800'
: 'bg-slate-800 text-slate-400 border border-slate-700'
@ -1335,7 +1335,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* CFG Scale Slider */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400 flex items-center justify-between">
<label className="text-xs font-normal text-slate-400 flex items-center justify-between">
<span>CFG Scale</span>
<span className="text-cinema-gold font-mono">{klingCfgScale.toFixed(1)}</span>
</label>
@ -1356,13 +1356,13 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Camera Control */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Camera Control</label>
<label className="text-xs font-normal text-slate-400">Camera Control</label>
<div className="grid grid-cols-3 gap-1.5">
{cameraPresets.map((preset) => (
<button
key={preset.value}
onClick={() => setKlingCameraControl(preset.value)}
className={`px-2 py-1.5 rounded font-medium transition-all text-xs ${
className={`px-2 py-1.5 rounded font-normal transition-all text-xs ${
klingCameraControl === preset.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1383,7 +1383,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<>
{/* Video ID */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Video ID
</label>
<input
@ -1405,7 +1405,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Extension Prompt */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Extension Prompt (Optional)
</label>
<textarea
@ -1418,7 +1418,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* CFG Scale */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400 flex items-center justify-between">
<label className="text-xs font-normal text-slate-400 flex items-center justify-between">
<span>CFG Scale</span>
<span className="text-cinema-gold font-mono">{klingCfgScale.toFixed(1)}</span>
</label>
@ -1446,7 +1446,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<>
{/* Face Image Upload */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Face Image
</label>
{klingLipSyncImage ? (
@ -1480,7 +1480,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Audio File Upload */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Audio File
</label>
{klingAudioFile ? (
@ -1510,7 +1510,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Lip Sync Prompt */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Action/Emotion Prompt (Optional)
</label>
<textarea
@ -1523,13 +1523,13 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Lip Sync Mode */}
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400">Quality Mode</label>
<label className="text-xs font-normal text-slate-400">Quality Mode</label>
<div className="flex gap-2">
{[{ value: 'std', label: 'Standard' }, { value: 'pro', label: 'Pro' }].map((opt) => (
<button
key={opt.value}
onClick={() => setKlingLipSyncMode(opt.value)}
className={`flex-1 px-3 py-2 rounded font-medium transition-all text-sm ${
className={`flex-1 px-3 py-2 rounded font-normal transition-all text-sm ${
klingLipSyncMode === opt.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
@ -1549,7 +1549,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Scene Description & Inputs — shown for Veo always, and Kling Generate */}
{(engine === 'veo' || (engine === 'kling' && klingWorkflow === 'generate')) && (
<div className="bg-slate-900/50 border border-slate-800 rounded p-6 space-y-4">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Scene Description {engine === 'veo' || referenceImages.length === 0 ? <span className="text-cinema-gold">*</span> : null}
</label>
<textarea
@ -1566,7 +1566,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Dialogue (optional) — Veo only (Kling uses sound/lip sync instead) */}
{engine === 'veo' && (
<div className="space-y-2">
<label className="text-xs font-medium text-slate-400 flex items-center gap-2">
<label className="text-xs font-normal text-slate-400 flex items-center gap-2">
<MessageSquare className="w-3 h-3" />
Dialogue (optional)
</label>
@ -1589,7 +1589,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<button
onClick={generateOptimizedVideoPrompt}
disabled={isOptimizing || isGenerating || !sceneDescription.trim()}
className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-slate-200 hover:bg-slate-300 text-slate-900 font-medium rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-slate-200 hover:bg-slate-300 text-slate-900 font-normal rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
>
{isOptimizing ? (
<>
@ -1613,7 +1613,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<button
onClick={() => generateVideo(true)}
disabled={isGenerating || (klingWorkflow === 'extend' && !klingVideoId.trim()) || (klingWorkflow === 'lipsync' && (!klingLipSyncImage || !klingAudioFile))}
className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-medium rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-normal rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
>
{isGenerating ? (
<>
@ -1637,7 +1637,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<div className="relative bg-slate-900 border border-slate-800 rounded overflow-hidden">
<div className="p-6 space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-xs font-medium text-slate-400">
<h3 className="text-xs font-normal text-slate-400">
Optimized Prompt
</h3>
{optimizedPrompt && (
@ -1657,7 +1657,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<div className="border-t border-slate-800 pt-3">
<button
onClick={() => setShowNegativePrompt(!showNegativePrompt)}
className="flex items-center gap-1.5 text-xs font-medium text-slate-400 hover:text-slate-300 transition-colors"
className="flex items-center gap-1.5 text-xs font-normal text-slate-400 hover:text-slate-300 transition-colors"
>
{showNegativePrompt ? <ChevronDown className="w-3 h-3" /> : <ChevronRight className="w-3 h-3" />}
Negative Prompt
@ -1678,7 +1678,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
<button
onClick={() => generateVideo(false)}
disabled={isGenerating}
className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-medium rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-normal rounded transition-all disabled:opacity-50 disabled:cursor-not-allowed"
>
{isGenerating ? (
<>
@ -1700,7 +1700,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{(engine === 'veo' || (engine === 'kling' && klingWorkflow === 'generate')) && (
<div className="bg-slate-900/50 border border-slate-800 rounded p-6 space-y-4">
<div className="flex items-center justify-between">
<label className="text-xs font-medium text-slate-400">
<label className="text-xs font-normal text-slate-400">
Reference Frames (Optional)
</label>
<span className="text-xs text-slate-500">
@ -1742,7 +1742,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{showProjectPicker && projectImages.length > 0 && (
<div className="bg-slate-800 border border-slate-700 rounded p-3">
<div className="flex items-center justify-between mb-2">
<span className="text-xs font-medium text-slate-400">From Project</span>
<span className="text-xs font-normal text-slate-400">From Project</span>
<button
onClick={() => setShowProjectPicker(false)}
className="text-slate-500 hover:text-slate-300"
@ -1817,7 +1817,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
{/* Generated Video */}
<div className="bg-slate-900/50 border border-slate-800 rounded p-6 space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium text-slate-200 flex items-center gap-2">
<h3 className="text-lg font-normal text-slate-200 flex items-center gap-2">
<Video className="w-5 h-5 text-cinema-gold" />
Generated Video
</h3>
@ -1903,7 +1903,7 @@ OUTPUT: Two sections separated by --- only. No explanations or labels.`;
link.download = generatedVideo.filename || `lux-studio-video-${Date.now()}.mp4`;
link.click();
}}
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-medium rounded transition-all"
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-cinema-gold hover:bg-amber-400 text-slate-950 font-normal rounded transition-all"
>
<Download className="w-5 h-5" />
<span>Download</span>

View file

@ -416,7 +416,7 @@ const VideoPlayer = ({ src, onFrameExtract, onSaveToProject, className = '', aut
{showFramePreview && extractedFrame && (
<div className="fixed inset-0 bg-black/80 flex items-center justify-center z-50 p-8" onClick={() => setShowFramePreview(false)}>
<div className="bg-slate-900 rounded p-6 max-w-2xl w-full" onClick={(e) => e.stopPropagation()}>
<h3 className="text-lg font-medium text-slate-200 mb-4 flex items-center gap-2">
<h3 className="text-lg font-normal text-slate-200 mb-4 flex items-center gap-2">
<Image className="w-5 h-5 text-cinema-gold" />
Extracted Frame
</h3>
@ -437,7 +437,7 @@ const VideoPlayer = ({ src, onFrameExtract, onSaveToProject, className = '', aut
<div className="flex gap-3">
<button
onClick={downloadFrame}
className="flex-1 flex items-center justify-center gap-2 px-4 py-2 bg-slate-800 hover:bg-slate-700 text-slate-200 font-medium rounded transition-colors"
className="flex-1 flex items-center justify-center gap-2 px-4 py-2 bg-slate-800 hover:bg-slate-700 text-slate-200 font-normal rounded transition-colors"
>
<Download className="w-4 h-4" />
Download
@ -455,7 +455,7 @@ const VideoPlayer = ({ src, onFrameExtract, onSaveToProject, className = '', aut
});
setSavedToProject(true);
}}
className={`flex-1 flex items-center justify-center gap-2 px-4 py-2 font-medium rounded transition-colors ${
className={`flex-1 flex items-center justify-center gap-2 px-4 py-2 font-normal rounded transition-colors ${
savedToProject
? 'bg-green-600 text-white cursor-default'
: 'bg-cinema-gold hover:bg-amber-400 text-slate-950'
@ -476,7 +476,7 @@ const VideoPlayer = ({ src, onFrameExtract, onSaveToProject, className = '', aut
) : (
<button
onClick={() => setShowFramePreview(false)}
className="flex-1 flex items-center justify-center gap-2 px-4 py-2 bg-slate-700 hover:bg-slate-600 text-slate-200 font-medium rounded transition-colors"
className="flex-1 flex items-center justify-center gap-2 px-4 py-2 bg-slate-700 hover:bg-slate-600 text-slate-200 font-normal rounded transition-colors"
>
Close
</button>