feat: AI SEO generator, full admin panel, i18n sweep, new logo + auth/RTL fixes
Build backend images / build content-svc (push) Failing after 3m39s
Build backend images / build file-svc (push) Failing after 52s
Build backend images / build gateway (push) Failing after 58s
Build backend images / build identity-svc (push) Failing after 1m21s
Build backend images / build notification-svc (push) Failing after 1m0s
Build backend images / build render-svc (push) Failing after 58s
Build backend images / build studio-svc (push) Failing after 55s

AI SEO content generator
- content-svc: per-tenant OpenAI config (ai_settings) + /v1/ai endpoints
  (settings GET/PUT, seo-post) with SEO-expert prompt → structured article
- admin UI to configure token/base-url/model and generate + save as blog
- configurable base URL for restricted networks

Full data-driven admin panel
- generic /api/admin/resource proxy + reusable AdminResource component
- categories/tags/fonts/blogs (CRUD), users (list + ban), plans/slides
- AI content section; nav + i18n

i18n localization sweep
- localized 116 user-facing + studio/editor components to next-intl (fa+en)
  under the auto.* namespace; merge tooling in scripts/merge-i18n.js

Branding + assets
- Monoline F logo (LogoMark + favicon)
- offline SVG placeholder generator (/api/placeholder), dropped picsum.photos

Fixes
- JWT issuer mismatch on content/studio (flatrender → flatrender-identity)
- missing role claim → [Authorize(Roles="Admin")] now works (RBAC)
- Secure cookies broke HTTP sessions → gated behind AUTH_COOKIE_SECURE
- Radix RTL via DirectionProvider (right-aligned menus in fa)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-02 09:35:14 +03:30
parent bcc69f0a2e
commit 3fc7bf2b97
160 changed files with 4397 additions and 767 deletions
+900
View File
@@ -305,5 +305,905 @@
"all": "All",
"popular": "Popular",
"new": "New"
},
"auto": {
"appAdminLayout": {
"brand": "FlatRender Admin",
"nodes": "Nodes",
"renderQueue": "Render Queue",
"backToDashboard": "← Back to Dashboard",
"aiContent": "AI Content",
"categories": "Categories",
"tags": "Tags",
"fonts": "Fonts",
"blogs": "Blog",
"slides": "Slides",
"users": "Users",
"plans": "Plans"
},
"appAdminNodesPage": {
"title": "Render Nodes",
"registered": "{count, plural, one {# node registered} other {# nodes registered}}"
},
"appAdminRendersPage": {
"title": "Render Queue",
"totalJobs": "{total} total jobs",
"filterAll": "All",
"stepQueued": "Queued",
"stepPreparing": "Preparing",
"stepRendering": "Rendering",
"stepUploading": "Uploading",
"stepDone": "Done",
"stepFailed": "Failed",
"stepCancelled": "Cancelled"
},
"appAuthPage": {
"metaTitle": "Sign In",
"metaDescription": "Sign in or create your CreatorStudio account.",
"loading": "Loading..."
},
"appDashboardSettingsPage": {
"title": "Settings",
"subtitle": "Manage your account, security, and notification preferences.",
"dangerZoneTitle": "Danger zone",
"dangerZoneDescription": "Permanently delete your account and all your projects. This cannot be undone.",
"deleteAccount": "Delete account"
},
"appError": {
"title": "Something went wrong",
"description": "An unexpected error occurred. Try reloading the page.",
"reloadButton": "Reload page"
},
"appNotFound": {
"title": "Page not found",
"description": "The page you are looking for does not exist or may have been moved.",
"goHome": "Go home"
},
"appStudioImageProjectIdPage": {
"loadingEditor": "Loading editor…"
},
"appStudioTrimmerPage": {
"back": "Back",
"title": "Video Trimmer & Cropper",
"ffmpegLoadError": "Failed to load FFmpeg. Check your connection and try again.",
"processingError": "Processing failed. Try a shorter clip or different format."
},
"appStudioVideoProjectIdPage": {
"loading": "Loading studio…"
},
"appVideoMakerPage": {
"metaTitle": "AI Video Maker",
"metaDescription": "Create stunning videos in minutes with AI scripts, auto-subtitles, 500+ templates, and 1-click export."
},
"componentsAdminNodesTable": {
"emptyState": "No nodes registered. Start the node agent on a render machine to see it here.",
"colNode": "Node",
"colStatus": "Status",
"colSlots": "Slots",
"colHeartbeat": "Heartbeat",
"colActiveJob": "Active Job",
"colTags": "Tags",
"colActions": "Actions",
"actionDrain": "Drain",
"actionRelease": "Release"
},
"componentsAdminRenderQueueTable": {
"emptyState": "No render jobs found for the selected filter.",
"colJobId": "Job ID",
"colProject": "Project",
"colStep": "Step",
"colProgress": "Progress",
"colQuality": "Quality",
"colNode": "Node",
"colCreated": "Created",
"colActions": "Actions",
"actionRetry": "Retry",
"actionCancel": "Cancel"
},
"componentsAuthAuthPageContent": {
"genericError": "Something went wrong. Please try again.",
"accountCreatedVerify": "Account created. Check your email to verify, then sign in.",
"accountCreatedSignIn": "Account created. Please sign in.",
"networkError": "Network error. Please try again.",
"resetCodeSent": "If that email is registered, we sent a reset code.",
"invalidCode": "Invalid or expired code.",
"passwordUpdated": "Password updated. You can now sign in.",
"checkingAuth": "Checking authentication...",
"resetTitle": "Reset your password",
"enterCodeTitle": "Enter reset code",
"resetSubtitle": "We'll send a one-time code to your email.",
"enterCodeSubtitle": "Check your email for the code sent to {email}",
"emailAddressLabel": "Email address",
"sendResetCode": "Send reset code",
"resetCodeLabel": "Reset code",
"resetCodePlaceholder": "6-digit code",
"newPasswordLabel": "New password",
"setNewPassword": "Set new password",
"backToSignIn": "Back to sign in",
"welcomeTitle": "Welcome to FlatRender",
"signInSubtitle": "Sign in to continue to your dashboard",
"signUpSubtitle": "Create a free account to get started",
"signInTab": "Sign In",
"signUpTab": "Sign Up",
"emailLabel": "Email",
"passwordLabel": "Password",
"forgotPassword": "Forgot password?",
"createAccount": "Create Account",
"legalNotice": "By continuing, you agree to our <terms>Terms</terms> and <privacy>Privacy Policy</privacy>."
},
"componentsAuthSupabaseSetupNotice": {
"title": "Supabase not configured",
"instructions": "Copy <envExample></envExample> to <envLocal></envLocal> and set <supabaseUrl></supabaseUrl> and <supabaseAnonKey></supabaseAnonKey>, then restart the dev server.",
"continueDev": "Continue without signing in (dev only)",
"backToHome": "Back to home"
},
"componentsDashboardDashboardEmptyState": {
"title": "No projects yet",
"description": "Create a video, image, or trim project to see it here. Everything you save appears in this workspace.",
"createFirstProject": "Create your first project"
},
"componentsDashboardDashboardPlanBadge": {
"upgradePlan": "Upgrade plan"
},
"componentsDashboardDashboardProjectsSection": {
"recentProjects": "Recent Projects",
"noResultsTitle": "No projects match your search",
"noResultsDescription": "Try a different keyword or clear the search bar."
},
"componentsDashboardSettingsSettingsBilling": {
"title": "Billing & Plan",
"subtitle": "Manage your subscription and payment method.",
"currentPlan": "Current plan",
"planFree": "Free",
"planPro": "Pro",
"planBusiness": "Business",
"statusCancelsAtPeriodEnd": "Cancels at period end",
"statusActive": "Active",
"statusFreeTier": "Free tier",
"upgrade": "Upgrade",
"changePlan": "Change plan",
"cancelPlan": "Cancel plan",
"cancelling": "Cancelling…",
"cancelConfirm": "Cancel your plan? You'll keep access until the current period ends.",
"cancelFailed": "Failed to cancel plan. Please try again.",
"networkError": "Network error. Please try again.",
"cancelledNotice": "Your plan has been cancelled. You'll keep access until the end of your billing period.",
"upgradeHint": "Upgrade to unlock unlimited projects, 4K export, and premium templates.",
"featureFree5Projects": "5 projects",
"featureFree720pExport": "720p export",
"featureFreeCommunityTemplates": "Community templates",
"featureProUnlimitedProjects": "Unlimited projects",
"featurePro4kExport": "4K export",
"featureProAllTemplates": "All templates",
"featureProPriorityRenderQueue": "Priority render queue",
"featureProCustomFonts": "Custom fonts",
"featureBusinessEverythingInPro": "Everything in Pro",
"featureBusinessTeamSeats": "Team seats",
"featureBusinessWhiteLabelExport": "White-label export",
"featureBusinessApiAccess": "API access",
"featureBusinessDedicatedSupport": "Dedicated support"
},
"componentsDashboardSettingsSettingsNotifications": {
"title": "Notifications",
"subtitle": "Choose which emails you receive from FlatRender.",
"savePreferences": "Save preferences",
"saved": "Saved!",
"renderCompleteLabel": "Render complete",
"renderCompleteDescription": "Get notified when your video export finishes.",
"projectSharedLabel": "Project shared with you",
"projectSharedDescription": "When a team member shares a project.",
"weeklyDigestLabel": "Weekly digest",
"weeklyDigestDescription": "Summary of new templates and platform updates.",
"productNewsLabel": "Product news",
"productNewsDescription": "New features, tips, and announcements."
},
"componentsDashboardSettingsSettingsProfile": {
"title": "Profile",
"subtitle": "Your public name and account email.",
"displayNameLabel": "Display name",
"displayNamePlaceholder": "Your name",
"emailLabel": "Email",
"emailHint": "Email cannot be changed here. Contact support.",
"saving": "Saving…",
"saveChanges": "Save changes",
"updateFailed": "Could not update profile.",
"updateSuccess": "Profile updated successfully.",
"networkError": "Network error. Please try again."
},
"componentsDashboardSettingsSettingsSecurity": {
"title": "Security",
"subtitle": "Change your account password.",
"currentPasswordLabel": "Current password",
"newPasswordLabel": "New password",
"confirmPasswordLabel": "Confirm new password",
"showPassword": "Show password",
"hidePassword": "Hide password",
"saving": "Saving…",
"changePassword": "Change password",
"errorMinLength": "New password must be at least 8 characters.",
"errorMismatch": "Passwords do not match.",
"errorChangeFailed": "Could not change password.",
"changeSuccess": "Password changed successfully.",
"networkError": "Network error. Please try again."
},
"componentsImageMakerImageMakerBeforeAfter": {
"beforeAlt": "Before editing",
"afterAlt": "After editing with AI",
"beforeLabel": "Before",
"afterLabel": "After",
"caption": "AI-enhanced color, layout, and brand styling applied in one click"
},
"componentsImageMakerImageMakerGallery": {
"title": "Example outputs from creators",
"subtitle": "Real-world layouts and styles you can recreate—or use as inspiration for your next project."
},
"componentsLayoutNavbarMenuDropdown": {
"learn": "Learn"
},
"componentsLayoutNavbarMobileMenu": {
"videoMaker": "Video Maker",
"imageMaker": "Image Maker",
"pricing": "Pricing",
"learn": "Learn"
},
"componentsSectionsHeroPreviewCards": {
"heading": "Made by world-class motion designers",
"previewAriaLabel": "{label} preview",
"template3dTitle": "Factory of 3D Animations",
"templateWhiteboardTitle": "Whiteboard Animation Toolkit",
"templateExplainerTitle": "3D Explainer Video Toolkit",
"templateTrendyTitle": "Trendy Explainer Toolkit"
},
"componentsSectionsPricingAnimatedPrice": {
"perMonth": "/ month"
},
"componentsSectionsPricingBillingToggle": {
"monthly": "Monthly",
"yearly": "Yearly",
"savePercent": "Save {percent}%",
"switchToYearly": "Switch to Yearly to save more"
},
"componentsSectionsPricingCard": {
"mostPopular": "Most Popular"
},
"componentsTemplatesTemplateDetailExamples": {
"heading": "Videos created using this template"
},
"componentsTemplatesTemplateDetailInfo": {
"sceneCount": "{count} scenes",
"durationFlexible": "Flexible",
"durationFixed": "Fixed",
"fallbackDescription": "Create stunning videos with this professional template. Choose scenes, customize text, and export in minutes.",
"availableStyles": "Available styles ({count})",
"styleClassic": "Classic",
"styleModern": "Modern",
"styleBold": "Bold",
"styleMinimal": "Minimal",
"createNow": "Create Now",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
"createError": "Could not create project: {error}"
},
"componentsTemplatesTemplateDetailPreview": {
"posterAlt": "{name} preview",
"playPreview": "Play template preview"
},
"componentsTemplatesTemplateDetailRating": {
"starsAriaLabel": "{score} out of 5 stars",
"ratingsCount": "({count} Ratings)"
},
"componentsTemplatesTemplatesActiveFilters": {
"removeFilter": "Remove filter: {label}",
"searchLabel": "Search: \"{query}\""
},
"componentsTemplatesVideoVideoTemplatesHero": {
"breadcrumbHome": "Home",
"breadcrumbTemplates": "Templates",
"title": "Video Templates for All Your Needs",
"subtitle": "Find customizable video templates. Create animated promos, logo reveals, slideshows, and more with FlatRender's online video maker."
},
"componentsTemplatesVideoVideoTemplatesPageContent": {
"openTemplateError": "Could not open template: {error}",
"emptyStateTitle": "No templates match your filters",
"emptyStateDescription": "Try a different size, category, or search term."
},
"componentsTemplatesVideoVideoTemplatesToolbar": {
"searchPlaceholder": "Search thousands of templates",
"sortByLabel": "Sort by:",
"sortAriaLabel": "Sort templates",
"sortTrending": "Trending",
"sortNewest": "Newest",
"sortPopular": "Most Popular"
},
"componentsTrimmerTrimmerExportSection": {
"heading": "Export",
"processing": "Processing…",
"trimAndCrop": "Trim & Crop",
"loadingEngine": "Loading FFmpeg engine…",
"progress": "Progress",
"download": "Download {format}"
},
"componentsTrimmerTrimmerStrip": {
"heading": "Trim",
"trimStart": "Trim start",
"trimEnd": "Trim end"
},
"componentsTrimmerTrimmerUploadZone": {
"dropPrompt": "Drag & drop a video, or click to browse",
"supportedFormats": "MP4, WebM, MOV and other video formats"
},
"componentsDashboardDashboardSidebar": {
"currentPlan": "Current plan",
"signOut": "Sign out"
},
"componentsDashboardDashboardSidebarNav": {
"myProjects": "My Projects",
"templates": "Templates",
"upgrade": "Upgrade",
"settings": "Settings",
"navLabel": "Dashboard"
},
"componentsDashboardDashboardTopBar": {
"searchPlaceholder": "Search projects..."
},
"componentsSectionsPricingCompareTable": {
"mostPopular": "Most Popular",
"compareHeading": "Compare Plans & Features",
"saveUpTo": "Save up to {percent}%"
},
"componentsSectionsPricingCreditsBanner": {
"refillCredits": "You can refill AI credits anytime with an active plan"
},
"componentsSectionsPricingFeatureList": {
"moreInformation": "More information"
},
"componentsSectionsPricingFreeBanner": {
"title": "Always Free to Try",
"description": "Explore CreatorStudio with a Free plan — create HD videos with a watermark, try basic features, and experiment before you subscribe.",
"ctaLabel": "Get Started"
},
"componentsSectionsTemplateCard": {
"useTemplateLabel": "Use Template",
"openingLabel": "Opening…",
"viewTemplateAriaLabel": "View {name} template"
},
"componentsSectionsTestimonialCard": {
"ratingLabel": "Rated 5 out of 5 stars"
},
"componentsTemplatesTemplateDetailBreadcrumb": {
"breadcrumbAriaLabel": "Breadcrumb",
"home": "Home",
"templates": "Templates"
},
"appImageMakerPage": {
"metaTitle": "AI Image Maker",
"metaDescription": "Design professional visuals instantly with AI generation, templates, brand kits, and batch export."
},
"appPage": {
"metaTitle": "Create Pro Videos & Images with AI",
"metaDescription": "FlatRender helps creators and brands make professional videos and images with AI templates, editors, and one-click export."
},
"componentsDashboardNewProjectMenu": {
"newProject": "New Project",
"creating": "Creating…",
"videoProject": "Video Project",
"imageProject": "Image Project",
"trimCropVideo": "Trim/Crop Video"
},
"componentsDashboardProjectCard": {
"openInStudio": "Open in Studio",
"download": "Download",
"rename": "Rename",
"duplicate": "Duplicate",
"delete": "Delete",
"statusRendering": "Rendering",
"statusReady": "Ready",
"statusDraft": "Draft",
"actionsFor": "Actions for {name}"
},
"componentsSectionsPricingCheckoutButton": {
"checkoutFailed": "Checkout failed.",
"noCheckoutUrl": "No checkout URL returned."
},
"componentsTemplatesTemplatesSidebar": {
"categoryHeading": "Category",
"styleHeading": "Style",
"colorHeading": "Color"
},
"componentsTemplatesVideoVideoTemplateCompactCard": {
"viewTemplateAria": "View {name} template",
"opening": "Opening…",
"useTemplate": "Use Template",
"sceneCount": "{count} scenes"
},
"componentsTemplatesVideoVideoTemplatesCarouselRow": {
"seeAll": "See all",
"scrollLeftAria": "Scroll {title} left",
"scrollRightAria": "Scroll {title} right"
},
"componentsTemplatesVideoVideoTemplatesCategorySidebar": {
"categoriesNavLabel": "Template categories",
"categoryAll": "All Templates",
"categoryAnimation": "Animation Videos",
"categoryIntros": "Intros and Logos",
"categoryEditing": "Video Editing",
"categoryInvitation": "Invitation Videos",
"categoryHoliday": "Holiday Videos",
"categorySlideshow": "Slideshow",
"categoryPresentations": "Presentations",
"categorySocial": "Social Media Videos",
"categoryAds": "Video Ad Templates",
"categorySales": "Sales Videos",
"categoryMusic": "Music Visualization",
"filters": "Filters",
"sizeLabel": "Size"
},
"componentsTemplatesVideoVideoTemplatesFilterControls": {
"premiumOnly": "Premium Only",
"premiumOnlyAriaLabel": "Premium only",
"sizeAriaLabel": "Template size",
"sizePlaceholder": "All Sizes"
},
"componentsTrimmerTrimmerVideoPreview": {
"previewAndCrop": "Preview & crop",
"aspectFree": "Free",
"aspect16x9": "16:9",
"aspect9x16": "9:16",
"aspect1x1": "1:1",
"aspect4x3": "4:3"
},
"componentsVideoMakerVideoMakerEditorPreview": {
"appBarTitle": "CreatorStudio — Video Editor",
"sceneCaption": "Scene 2 · Product reveal · 00:12",
"layersHeading": "Layers",
"layerIntroTitle": "Intro title",
"layerBrollClip": "B-roll clip",
"layerBackgroundMusic": "Background music",
"layerCaptions": "Captions"
},
"componentsVideoMakerVideoMakerTemplateCarousel": {
"title": "Video templates for every story",
"subtitle": "Start from a proven layout and customize scenes, text, and music in minutes.",
"templatePromo": "Product Promo",
"templateYoutube": "YouTube Intro",
"templateReel": "Reel Hook",
"templateCorporate": "Corporate Update",
"templateAd": "Ad Spotlight",
"templateTutorial": "Tutorial",
"templateEvent": "Event Recap",
"templateTestimonial": "Customer Story"
},
"componentsImageEditorAiRemoveBgModal": {
"openImageFirst": "Open an image first.",
"removalFailed": "Background removal failed.",
"backgroundRemoved": "Background removed!",
"serviceUnreachable": "Could not reach background removal service.",
"title": "AI Background Removal",
"description": "Remove the background from your base image. The result replaces the background layer with a transparent PNG.",
"processing": "Processing…",
"removeBackground": "Remove Background"
},
"componentsImageEditorImageCropControls": {
"aspectFree": "Free",
"cancel": "Cancel",
"applying": "Applying…",
"applyCrop": "Apply Crop"
},
"componentsImageEditorImageEditorRightPanel": {
"tabAdjust": "Adjust",
"tabFilters": "Filters",
"tabLayers": "Layers"
},
"componentsImageEditorImageEditorToolbar": {
"toolSelect": "Select",
"toolCrop": "Crop",
"toolText": "Text",
"toolShape": "Shape",
"toolDraw": "Draw",
"toolAi": "AI",
"shapeRectangle": "Rectangle",
"shapeCircle": "Circle",
"shapeLine": "Line",
"shapeArrow": "Arrow"
},
"componentsImageEditorImageEditorTopBar": {
"defaultProjectName": "Image Editor",
"open": "Open",
"export": "Export",
"format": "Format",
"quality": "Quality",
"download": "Download",
"canvasNotReady": "Canvas not ready.",
"exportStarted": "Export started"
},
"componentsImageEditorPanelsAdjustPanel": {
"emptyState": "Open an image to use adjustments.",
"brightness": "Brightness",
"contrast": "Contrast",
"saturation": "Saturation",
"hue": "Hue",
"blur": "Blur",
"sharpen": "Sharpen",
"vignette": "Vignette"
},
"componentsImageEditorPanelsFiltersPanel": {
"emptyState": "Open an image to apply filters."
},
"componentsImageEditorPanelsLayersPanel": {
"reorderLayer": "Reorder {name}",
"hideLayer": "Hide layer",
"showLayer": "Show layer",
"deleteLayer": "Delete {name}",
"emptyState": "No layers yet."
},
"componentsStudioAddSceneMenu": {
"addScene": "Add Scene",
"blankScene": "Blank Scene",
"fromTemplate": "From Template"
},
"componentsStudioDraggableSceneItem": {
"dragScene": "Drag scene {name}",
"sceneNameLabel": "Scene name"
},
"componentsStudioProjectSaveIndicator": {
"saving": "Saving…",
"saved": "Saved",
"localSave": "Local save",
"saveFailed": "Save failed",
"retry": "Retry"
},
"componentsStudioPropertiesPanel": {
"title": "Properties",
"emptyState": "Select a layer to edit properties",
"layerLabel": "{type} layer"
},
"componentsStudioRenderModal": {
"dialogTitle": "Export",
"dialogDescription": "Export your project as MP4 via the nexrender pipeline.",
"videoReady": "Your video is ready.",
"downloadMp4": "Download MP4",
"shareLink": "Share link",
"close": "Close",
"errorGeneric": "Something went wrong.",
"retry": "Retry",
"previewAlt": "Render preview",
"rendering": "Rendering…",
"progress": "Progress",
"resolution": "Resolution",
"format": "Format",
"fps": "FPS",
"startRendering": "Start Rendering",
"errorFetchStatus": "Could not fetch render status.",
"renderingProgress": "Rendering… {progress}%",
"errorRenderFailed": "Render failed.",
"errorNetworkPolling": "Network error while polling status.",
"errorStartRender": "Failed to start render.",
"queued": "Queued for rendering…",
"errorReachApi": "Could not reach render API."
},
"componentsStudioSceneBrowserCard": {
"selectCta": "Select"
},
"componentsStudioSceneBrowserModal": {
"title": "Select Scenes",
"closeAriaLabel": "Close",
"filterAll": "All",
"filterVideo": "Video",
"filterPhoto": "Photo",
"searchPlaceholder": "Search scenes...",
"emptyState": "No scenes match your filters.",
"selectedSuffix": "{count, plural, one {scene selected} other {scenes selected}}",
"deselectAll": "Deselect All",
"cancel": "Cancel",
"addToVideo": "Add to Video",
"addToVideoCount": "Add to Video ({count})"
},
"componentsStudioSceneItemActions": {
"duplicate": "Duplicate {sceneName}",
"delete": "Delete {sceneName}"
},
"componentsStudioSceneTransitionPicker": {
"transition": "Transition"
},
"componentsStudioStudioMobileGate": {
"titleVideo": "The Video Studio requires a desktop browser.",
"titleImage": "The Image Editor requires a desktop browser.",
"description": "Please open this project on a desktop or laptop.",
"dashboardCta": "Go to Dashboard"
},
"componentsStudioStudioToolbar": {
"defaultText": "Edit this text",
"addText": "Add text",
"addImage": "Add image",
"addVideoClip": "Add video clip",
"addShape": "Add shape",
"shapeRectangle": "Rectangle",
"shapeCircle": "Circle",
"shapeLine": "Line",
"shapeArrow": "Arrow"
},
"componentsStudioCanvasVideoLayerNode": {
"defaultFileName": "Video",
"placeholder": "Video clip"
},
"componentsStudioPropertiesCommonLayerControls": {
"transformTitle": "Transform",
"widthLabel": "Width",
"heightLabel": "Height",
"rotationLabel": "Rotation (°)",
"layerOrderTitle": "Layer order",
"toFront": "To front",
"toBack": "To back",
"deleteLayer": "Delete layer"
},
"componentsStudioPropertiesImageLayerProperties": {
"sectionTitle": "Image",
"opacity": "Opacity",
"flipHorizontal": "Flip H",
"flipVertical": "Flip V",
"replaceImage": "Replace image",
"borderRadius": "Border radius"
},
"componentsStudioPropertiesPropertyControls": {
"lockAspectRatio": "Lock aspect ratio",
"unlockAspectRatio": "Unlock aspect ratio"
},
"componentsStudioPropertiesShapeLayerProperties": {
"sectionTitle": "Shape",
"fillColor": "Fill color",
"strokeColor": "Stroke color",
"strokeWidth": "Stroke width",
"borderRadius": "Border radius",
"opacity": "Opacity"
},
"componentsStudioPropertiesTextLayerProperties": {
"sectionTitle": "Text",
"fontFamily": "Font family",
"fontSize": "Font size",
"bold": "Bold",
"italic": "Italic",
"underline": "Underline",
"textColor": "Text color",
"alignment": "Alignment",
"alignLeft": "Left",
"alignCenter": "Center",
"alignRight": "Right",
"letterSpacing": "Letter spacing",
"lineHeight": "Line height",
"opacity": "Opacity",
"animation": "Animation"
},
"componentsStudioSidebarAudioSidebarContent": {
"musicTab": "Music",
"voiceoverTab": "Voiceover"
},
"componentsStudioSidebarAudioSidebarMusicTab": {
"upload": "Upload",
"includeTemplateSfx": "Include template sound effect",
"searchPlaceholder": "Search music",
"musicLibrary": "Music library",
"myMusic": "My music",
"uploadOwnMusic": "Upload your own music"
},
"componentsStudioSidebarAudioSidebarVoiceoverPane": {
"comingSoon": "Coming soon",
"description": "Generate voiceovers from your script directly in the studio."
},
"componentsStudioSidebarColorsCustomTab": {
"mainColor": "Main Color",
"additionalColor": "Additional Color",
"applyToAllScenes": "Apply to all scenes"
},
"componentsStudioSidebarColorsPalettesTab": {
"paletteFallback": "Palette {number}",
"applyPaletteAriaLabel": "Apply {name} palette"
},
"componentsStudioSidebarColorsSidebarContent": {
"palettesTab": "Palettes",
"customTab": "Custom"
},
"componentsStudioSidebarColorsTemplatePreviewCard": {
"mainColor": "Main Color",
"additional": "Additional",
"paletteFallback": "Palette {number}"
},
"componentsStudioSidebarFontSidebarContent": {
"title": "Font",
"fontFamily": "Font family",
"applyToAll": "Apply to all text layers"
},
"componentsStudioSidebarSceneEditSidebarContent": {
"panelTitle": "Edit Scene",
"titleLabel": "Title",
"subtitleLabel": "Subtitle",
"textLabel": "Text {index}",
"textPlaceholder": "Type here…",
"imageLabel": "Image {index}",
"emptyStateTitle": "This scene has no content yet.",
"emptyStateHint": "Add a text layer to start editing.",
"addTextLayer": "Add Text Layer",
"defaultText": "Your text here",
"replaceImage": "Replace image",
"uploadImage": "Upload image"
},
"componentsStudioSidebarTransitionsSidebarContent": {
"heading": "Transitions",
"randomTransition": "Random Transition",
"noTransition": "No Transition",
"exportNote": "Applied transitions will be visible on all scenes after export."
},
"componentsStudioSidebarTtsSidebarContent": {
"title": "Text to Speech",
"comingSoon": "Coming soon",
"description": "Generate voiceovers from your script directly in the studio."
},
"componentsStudioSidebarWatermarkSidebarContent": {
"title": "My Watermark",
"applyToAllScenes": "Apply to all scenes",
"uploadLogo": "Upload your watermark logo",
"uploadHint": "PNG or SVG, max 2MB",
"position": "Position",
"positionTopLeft": "Top left",
"positionTopCenter": "Top center",
"positionTopRight": "Top right",
"positionMiddleLeft": "Middle left",
"positionCenter": "Center",
"positionMiddleRight": "Middle right",
"positionBottomLeft": "Bottom left",
"positionBottomCenter": "Bottom center",
"positionBottomRight": "Bottom right",
"opacity": "Opacity",
"opacityAriaLabel": "Watermark opacity"
},
"componentsStudioTimelineAudioTrack": {
"emptyState": "No audio — click to add"
},
"componentsStudioTimelineSceneBlock": {
"resizeDuration": "Resize {name} duration"
},
"componentsStudioTimelineSceneThumbnailBlock": {
"duplicateScene": "Duplicate {name}",
"deleteScene": "Delete {name}",
"resizeSceneDuration": "Resize {name} duration",
"sceneNameLabel": "Scene name",
"doubleClickToRename": "Double-click to rename"
},
"componentsStudioTimelineSceneThumbnailStrip": {
"browseScenes": "Browse scenes",
"addScene": "Add scene"
},
"componentsStudioTimelineTimeRuler": {
"rulerAriaLabel": "Timeline ruler — click to seek"
},
"componentsStudioTimelineTimelineActionRow": {
"addTextToSpeech": "Add text to speech",
"addAudio": "Add audio"
},
"componentsStudioTimelineTimelineControlBar": {
"copyLayer": "Copy layer",
"deleteLayer": "Delete layer",
"stop": "Stop",
"preview": "Preview",
"previewFromStart": "Preview from start",
"seekToStart": "Seek to start",
"zoomOut": "Zoom out",
"zoomIn": "Zoom in",
"timelineZoom": "Timeline zoom"
},
"componentsStudioTimelineTimelineQuickActions": {
"addTextToSpeech": "Add text to speech",
"addAudio": "Add audio"
},
"componentsStudioVideoCanvasArea": {
"loading": "Loading canvas…",
"editingNotice": "You're in editing mode — visuals may look different. Press <preview>Preview</preview> to see the final result."
},
"componentsStudioVideoStudioSidebarDock": {
"scenes": "Scenes",
"audio": "Audio",
"textToSpeech": "Text to Speech",
"colors": "Colors",
"transitions": "Transitions",
"font": "Font",
"myWatermark": "My Watermark",
"toolsNavLabel": "Studio tools",
"guideMe": "Guide me",
"guideComingSoon": "👋 Guide coming soon!",
"keyboardShortcuts": "Keyboard shortcuts",
"keyboardShortcutsComingSoon": "Keyboard shortcuts coming soon!"
},
"componentsStudioVideoStudioTopBar": {
"snapshotSaved": "Snapshot saved!",
"canvasNotReady": "Canvas not ready. Try again.",
"homeLink": "FlatRender home",
"breadcrumb": "Breadcrumb",
"myProjects": "My Projects",
"projectName": "Project name",
"undo": "Undo",
"redo": "Redo",
"stop": "Stop",
"preview": "Preview",
"takeSnapshot": "Take snapshot",
"export": "Export"
},
"componentsStudioVideoStudioTopBarSaveBadge": {
"savingTitle": "Saving…",
"savingLabel": "Saving",
"errorTitle": "Save failed",
"errorLabel": "Save failed",
"local": "Local",
"saved": "Saved ✓"
},
"componentsStudioVideoStudioTopBarTextControls": {
"groupLabel": "Text layer properties",
"fontFamily": "Font family",
"fontSize": "Font size",
"bold": "Bold",
"italic": "Italic",
"textColor": "Text color"
},
"componentsStudioVideoVideoNewPresetCard": {
"useTemplate": "Use Template"
},
"componentsStudioVideoVideoProjectNewContent": {
"breadcrumbCreate": "Create new video",
"heading": "Select one of the options to start creating",
"selectScenesTitle": "Select Scenes",
"selectScenesDescription": "Browse scenes and build your project from scratch",
"createWithAiTitle": "Create with AI",
"createWithAiDescription": "Transform your ideas or script into AI-generated videos effortlessly",
"aiProjectName": "AI Video Project",
"or": "OR",
"startWithPresets": "Start with Presets",
"searchPresetsPlaceholder": "Search presets...",
"newVideoName": "New Video"
},
"adminAi": {
"pageTitle": "AI SEO Content",
"pageDesc": "Configure OpenAI and generate SEO-optimized articles from a description.",
"settingsTitle": "OpenAI configuration",
"settingsDesc": "Your API key is stored securely and never shown in full. Point Base URL at a reachable OpenAI-compatible endpoint if needed.",
"apiKeyLabel": "API key",
"apiKeyPlaceholder": "sk-… (leave blank to keep current)",
"baseUrlLabel": "Base URL",
"modelLabel": "Model",
"enabledLabel": "Enable AI generation",
"saveSettings": "Save settings",
"saving": "Saving…",
"settingsSaved": "Settings saved",
"settingsError": "Could not save settings",
"keyConfigured": "API key configured",
"noKey": "No API key set",
"generateTitle": "Generate SEO article",
"generateDesc": "Describe the topic and metadata — the AI writes an SEO-ready post.",
"descriptionLabel": "Description / brief",
"descriptionPlaceholder": "What is this page/product about? Key points, tone, goals…",
"titleLabel": "Working title (optional)",
"typeLabel": "Content type (optional)",
"typePlaceholder": "e.g. video template",
"tagsLabel": "Tags (comma separated, optional)",
"keywordLabel": "Primary keyword (optional)",
"audienceLabel": "Audience (optional)",
"localeLabel": "Language",
"localeFa": "Persian",
"localeEn": "English",
"generate": "Generate",
"generating": "Generating…",
"generateError": "Generation failed",
"resultTitle": "Generated article",
"fTitle": "Title",
"fSlug": "Slug",
"fMetaTitle": "Meta title",
"fMetaDesc": "Meta description",
"fKeywords": "Keywords",
"fShortDesc": "Short description",
"fContent": "Content (HTML)",
"preview": "Preview",
"publishNow": "Publish immediately",
"saveAsBlog": "Save as blog post",
"savedAsBlog": "Saved as blog post",
"saveError": "Could not save post",
"mustConfigure": "Configure and enable OpenAI above before generating."
}
}
}