- camera_control: only kling-v1 and kling-v1-5 support it (not v3)
- For preset types (down_back etc.), config must be absent — only
'simple' type uses config fields
- camera_control and image_tail are mutually exclusive in I2V
- cfg_scale not supported by kling-v2.x models — now skipped
- duration sent as string to match API examples
- v3/v3-omni removed from camera control UI list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Camera/motion control is only supported by kling-v1, kling-v1-5,
kling-v3, kling-v3-omni. Backend silently drops the camera_control
field for all other models. Frontend hides the camera control UI
and auto-clears the selection when switching to an unsupported model.
New models added: kling-v3-omni, kling-video-o1, kling-v1 (cam ctrl),
kling-v2-master. Duration validation loosened for v3/v3-omni (3-15s).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Client-side Gemini calls were hitting the frontend API key's rate limits
and exposing the key in the browser. The optimizer now POSTs to
video_api.php (action=optimize_prompt) which calls Gemini server-side
using the backend key.
Rate-limited responses (429) silently fall back to the simple prompt
generator without showing an error.
Removes the @google/generative-ai import from VideoGenTab.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kling image2video endpoint expects:
image: "<base64>" (no data URI prefix)
image_tail: "<base64>" (optional, for interpolation)
Not image_url/image_tail_url with data URIs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Veo predictLongRunning endpoint is a predict-style API (not
generateContent) and expects image data as:
{ "bytesBase64Encoded": "...", "mimeType": "image/jpeg" }
The previous session switched it to inlineData (generateContent format),
causing the API to reject it with:
"inlineData isn't supported by this model"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nginx inside the Docker container defaults to 1MB body limit —
base64 image payloads exceed this and return a 413 HTML page,
causing the "Unexpected token '<'" JSON parse error on video_api.php.
Gemini 429 rate limit errors on prompt optimization now fall back
silently instead of surfacing an error to the user.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Old: `up -d --build` stops old container before building → if build fails, service is down
New:
1. `build --no-cache` — full rebuild, fails without touching running container
2. `up -d --force-recreate` — only runs if build succeeded
3. health check after start to catch silent failures
--no-cache ensures PHP/JS file changes are always picked up (no stale layer cache)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gemini-2.0-flash-lite has lower RPM limits even on paid plans.
gemini-2.0-flash has higher quotas and better quality optimization.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kling:
- camera_control.type: use preset name directly (down_back etc.), not 'predefined'
- camera_control.config: all 6 integer fields required even for preset types
- duration: cast to integer (API rejects strings)
- I2V images: use image_url/image_tail_url with data URI prefix (not plain base64 in image/image_tail)
Veo:
- image/lastFrame: use inlineData format (Gemini API), not bytesBase64Encoded (Vertex AI)
- durationSeconds: send as string "4"/"6"/"8", not integer
Docker:
- Add uploads.ini: post_max_size=100M, upload_max_filesize=100M, memory_limit=512M
(ini_set cannot override these at runtime in php-fpm)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After changing the video URL prefix to /lux-studio/api/generated_videos/,
the old /generated_videos/ check caused a false-positive validation error.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All backend PHP files require config.php as their first include.
It was gitignored and missing, causing PHP fatal errors that produced
empty responses — breaking JSON parsing in the frontend.
The new config.php has no hardcoded secrets; it reads all values
(GEMINI_API_KEY, KLING_ACCESS_KEY, KLING_SECRET_KEY, SSO_*) from
the .env file via env_loader.php.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Vite loads .env.production with higher priority than .env in production
mode — optical URLs were being overridden by ai-sandbox values.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
git pull → docker compose up --build → Apache include (idempotent) → reload.
No longer assumes PHP/Node on host; runs without sudo except Apache steps.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Multi-stage Dockerfile (node:20 builder + php:8.2-fpm-alpine runtime),
nginx serving frontend SPA + PHP-FPM backend at /lux-studio/, supervisord
managing both processes. docker-compose.prod.yml on port 8085, .env.optical
mounted read-only, uploads in a named volume.
Apache include at deploy/apache-lux-studio.conf proxies /lux-studio/ → :8085.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace old SSO Client IDs with new IT-provisioned ID (a321d54f) across
all env templates and CLAUDE.md. Add frontend/.env.optical, backend/.env.optical,
and deploy-optical.sh targeting optical-prod.oliver.solutions/lux-studio/.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kling video generation:
- Full T2V, I2V, extend, and lip sync workflows via Kling API
- V3, V2.6, V2.5 Turbo, V2.1 Master, V1.6 model support
- Resolution selector (720p std / 1080p pro) with model constraints
- Native audio toggle with dialogue input for Kling
- Video ID tracking for extend and lip sync chains
- Camera control presets (pan, tilt, arc)
Prompt optimizer rework:
- Intent-preserving refinement (camera, action, mood are sacred)
- Mode-aware: T2V adds subject/environment detail, I2V describes only motion
- Reference images analyzed for content, not re-described
- Platform-specific quality anchors woven into positive prompt
- Negative prompts removed from optimizer (positive-only approach)
- 15-60 word target for concise, effective prompts
Backend fixes:
- Gemini responseModalities: ['TEXT', 'IMAGE'] for Flash model compatibility
- Veo first-frame resize to exact target dimensions (prevents letterboxing)
- Session directory re-creation in saveImage (auto-cleanup race condition)
- Kling API error logging with HTTP codes and payload details
- Lip sync endpoint updated to /v1/videos/lip-sync with video_id
Frontend stability:
- Tab persistence via CSS hidden (generation survives tab switches)
- Project switch protection (confirm dialog when generation in progress)
- Retina thumbnails (480px/q0.8) for library grid — prevents OOM crashes
- Thumbnail backfill migration for existing project items
- Project items refresh on tab visibility and after save
- 1:1 aspect ratio container for Kling videos
- Expanded video view matches library modal behavior
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PNG: Remove card backgrounds, borders, header bars, and empty
annotation text. Just images in a grid with a small frame number.
PDF: Reduce margins and label reservation to maximize image size.
Frame number and annotation condensed to one small line below.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tabs now float between logo and user info via justify-between,
giving the logo more breathing room.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Matched sans+mono from same family. More Univers-like, technical.
Previous commit (6c47a79) has Space Grotesk for comparison.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Geometric grotesque with equipment personality. Keeps JetBrains Mono
for data text. Base size stays 12px.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Slate-925 panels are nearly invisible against black/60 overlays.
Modals need to be clearly visible, so they use slate-800.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Custom slate-925 (#080d1b) sits just one shade above the 950 ground,
making panels barely visible. The content is the interface, not the
chrome. Reverts the inverted-depth experiment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Page ground from bg-slate-950 to bg-slate-800. Content panels stay
bg-slate-900, creating inset wells rather than floating cards.
Like a Braun control panel with recessed dark areas.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zone markers (Preset, Camera Body, Lens Kit, Duration, etc.) get
uppercase + wide tracking like Braun hi-fi category labels. Modal
form labels and interactive toggles stay sentence case.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Second typographic voice for timestamps, dimensions, file sizes,
session IDs, costs, word counts, resolution specs, and version number.
Like lens barrel markings — the data speaks in mono, the UI in sans.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove all opacity variants (bg-slate-900/50, bg-slate-800/50, etc.) in
favor of opaque tones. Inputs standardized to bg-slate-800 (Elevated).
hover:bg-slate-800 promoted to hover:bg-slate-700 (Interactive tier).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Active tab is already distinguished by gold text color. The
underline was redundant decoration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Off-white toggles did not improve things -- gold selected state
was already working well. Reverts 4c4c857.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace bg-cinema-gold with bg-slate-200 on all 21 toggle/selector
buttons. Gold now reserved exclusively for primary CTA buttons
(Generate Image, Generate Video). Creates quieter UI that lets
generated images and video stand out.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip panel/card wrapper borders, section separator borders, tooltip
borders, and modal borders. Remaining borders are all functional:
input fields, focus states, status indicators (green/red/amber),
dashed upload zones, active selection states, and type badges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Thin font weights, tighten border radii, remove dropdown shadows,
strip uppercase from section headers, flatten video placeholder
gradient, replace indigo/purple action buttons with neutral slate,
consolidate move/select toggles to cinema-gold. Keep type badges
(IMG/VID/KLING) as functional color indicators.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip uppercase+tracking from all labels, thin font weights to medium,
tighten all border radii, replace indigo-to-purple gradient with neutral
slate button, flatten container gradient, consolidate indigo workflow
selector to cinema-gold, remove all indigo color references.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip uppercase+tracking from all labels, thin font-bold to font-medium,
tighten all border radii, replace indigo-to-purple gradient with neutral
slate button, remove tooltip shadow, consolidate purple focus mode badge
to slate, remove decorative hover:scale on copy button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tighten border radius (rounded-xl/lg→rounded), remove decorative
shadows, replace indigo Generate Video button with neutral slate,
thin heading font weights to medium.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Thin font weights (bold→medium, semibold→medium), tighten border
radius (rounded-lg→rounded), reduce shadow (xl→sm) on login card.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch from system font stack to DM Sans (Google Fonts, variable weight)
and reduce base font-size to 14px for a more compact, professional feel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add kling-v3 and kling-v3-omni to model selector and backend validation
- Set V3 as the new default model (was V2.6)
- V3 Omni includes built-in audio generation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integrates Kling AI as a second video engine in the Video Gen tab with
three cinema-relevant workflows: Generate (T2V/I2V with camera control),
Extend (video extension up to 3 min), and Lip Sync (image + audio).
Backend: New kling_api.php with pure PHP JWT auth, all workflows, async
status polling, and CDN video download. Env files updated with Kling
credential placeholders.
Frontend: Engine selector toggle, workflow-specific settings panels,
Kling polling, engine badges in ProjectsTab, rerun support.
Also includes image model toggle changes (Gemini Pro/Flash).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>