feat(frontend): add brand kit management UI and project binding

Add a brand kit domain model, repository, and dedicated page/route for
managing brand kits, plus a BrandKitSelector used on the home page and
canvas workspace. Home project creation and the workspace can attach a
brand kit to a project, with new i18n strings and a side-nav entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-10 20:59:05 +08:00
parent 789f51b29e
commit 2df9ae6581
24 changed files with 4885 additions and 10 deletions
+188
View File
@@ -80,6 +80,194 @@
"likes": "likes",
"home": "Home",
"projects": "Projects",
"brandKit": "Brand Kit",
"brandKitAbout": "About Brand Kits",
"brandKitAddColor": "Add color",
"brandKitAddColorGroup": "Add color group",
"brandKitAddFirstColor": "Add first color",
"brandKitAddTypography": "Add type group",
"brandKitApplied": "Brand Kit applied to this canvas",
"brandKitApplyNewProjects": "Apply to new projects",
"brandKitBindingError": "The Brand Kit could not be applied to this canvas.",
"brandKitAssetsDescription": "Keep logos, a library cover, and visual references together as reusable source material for generation.",
"brandKitAssetsNav": "Assets",
"brandKitAssetsTitle": "Assets",
"brandKitAudience": "Core audience",
"brandKitAudiencePlaceholder": "Who are they, what situation are they in, and what matters most?",
"brandKitBoardMessage": "Ideas, kept in motion.",
"brandKitBoardType": "Brand type",
"brandKitBrandName": "Brand name",
"brandKitBrandNamePlaceholder": "For example: Moteva",
"brandKitCancel": "Cancel",
"brandKitColorDescription": "Give every color a role so generated work uses the palette intentionally.",
"brandKitColorCount": "{count} colors",
"brandKitColorGroupName": "Color group name",
"brandKitColorGroupNamePlaceholder": "For example: Primary",
"brandKitColorHex": "Hex color",
"brandKitColorName": "Color name",
"brandKitColorNav": "Color",
"brandKitColorPicker": "Choose color",
"brandKitColorTitle": "Color system",
"brandKitColorUsage": "Color usage",
"brandKitColorUsagePlaceholder": "Primary text, background, or key action",
"brandKitCleared": "Brand Kit removed from this canvas",
"brandKitCompletion": "{count}% complete",
"brandKitComposition": "Composition principles",
"brandKitCompositionPlaceholder": "Describe visual focus, grid, negative space, and hierarchy.",
"brandKitCopySuffix": "Copy",
"brandKitCreateProject": "Create project with this kit",
"brandKitCreateRequirement": "Add a brand name, summary, and audience or positioning before creating a project",
"brandKitCreate": "Create Brand Kit",
"brandKitCreatingProject": "Creating project...",
"brandKitCoverDescription": "The identifying image used for this Brand Kit in the library.",
"brandKitCoverReadError": "This cover image could not be read.",
"brandKitCoverReady": "Brand Kit cover",
"brandKitCoverSizeError": "Cover images must be under 1 MB.",
"brandKitCoverTitle": "Cover image",
"brandKitCoverTypeError": "Upload a PNG, JPG, WebP, or SVG cover.",
"brandKitCoverUploaded": "Cover image added",
"brandKitDefault": "Default",
"brandKitDelete": "Delete",
"brandKitDeleteDescription": "“{name}” will be removed from your account. Canvases using it will switch to no Brand Kit.",
"brandKitDeleteTitle": "Delete this Brand Kit?",
"brandKitDeleted": "Brand Kit deleted",
"brandKitDonts": "Avoid",
"brandKitDontsPlaceholder": "List colors, compositions, imagery, or language that weaken recognition.",
"brandKitDos": "Use",
"brandKitDosPlaceholder": "List the visual habits and brand moves that must stay consistent.",
"brandKitDuplicate": "Duplicate",
"brandKitDuplicated": "Copy created",
"brandKitEditorEyebrow": "Brand system",
"brandKitEmptyDescription": "Keep positioning, voice, logos, colors, and type in one place so every generation carries the same brand decisions forward.",
"brandKitEmptyShort": "No Brand Kits yet",
"brandKitEmptyTitle": "Make every generation feel like the same brand",
"brandKitExampleBadge": "Example",
"brandKitExampleDescription": "See how a complete set of brand inputs guides both visual and verbal expression.",
"brandKitExampleEyebrow": "Moteva example kit",
"brandKitExampleFooter": "The example is not saved to your library",
"brandKitExampleTemplateName": "Moteva Brand Template",
"brandKitFontFamily": "Font family",
"brandKitFontDescription": "Description",
"brandKitFontDescriptionPlaceholder": "Optional: hierarchy, context, and usage limits",
"brandKitFontReadError": "This font file could not be read.",
"brandKitFontSizeError": "Font files must be under 1 MB.",
"brandKitFontSizes": "Sizes",
"brandKitFontSizesPlaceholder": "Optional: 12 / 16 / 24",
"brandKitFontTypeError": "Upload a WOFF, WOFF2, TTF, or OTF font file.",
"brandKitFontUploaded": "Font uploaded and applied to the preview",
"brandKitFontUsage": "Font usage",
"brandKitFontUsagePlaceholder": "Hierarchy, sizes, and intended contexts",
"brandKitFontWeight": "Weight",
"brandKitFoundationDescription": "State who the brand is and the value it provides in the fewest useful words.",
"brandKitFoundationNav": "Foundation",
"brandKitFoundationTitle": "Brand foundation",
"brandKitImagery": "Image direction",
"brandKitImageryPlaceholder": "Describe subject, light, background, material, and finishing.",
"brandKitLibraryTitle": "My Brand Kits",
"brandKitLoadError": "Your Brand Kits could not be loaded.",
"brandKitLoading": "Loading Brand Kits",
"brandKitLogoDescription": "Upload the logo variants you use and define the boundaries for each one.",
"brandKitLogoLimitError": "Each Brand Kit can store up to 4 logos.",
"brandKitLogoMark": "Mark",
"brandKitLogoName": "Logo name",
"brandKitLogoNav": "Logo",
"brandKitLogoPrimary": "Primary",
"brandKitLogoReadError": "This logo file could not be read.",
"brandKitLogoSecondary": "Secondary",
"brandKitLogoSizeError": "Logo files must be under 1 MB.",
"brandKitLogoTitle": "Logo",
"brandKitLogoTypeError": "Upload a PNG, JPG, WebP, or SVG file.",
"brandKitLogoUsage": "Logo usage",
"brandKitLogoUsagePlaceholder": "Backgrounds, clear space, and prohibited uses",
"brandKitLogoVariant": "Logo variant",
"brandKitMoreActions": "More Brand Kit actions",
"brandKitNameLabel": "Brand Kit name",
"brandKitNew": "New",
"brandKitNewColorGroup": "New color group",
"brandKitNewTypography": "New type group",
"brandKitNone": "None",
"brandKitNoneDescription": "Use only this canvas and prompt",
"brandKitOptional": "Optional",
"brandKitPersonality": "Brand personality",
"brandKitPersonalityPlaceholder": "For example: clear, perceptive, restrained, collaborative",
"brandKitPositioning": "Positioning",
"brandKitPositioningPlaceholder": "How should people understand this brand relative to alternatives?",
"brandKitPreviewLabel": "Moteva Brand Kit preview",
"brandKitProjectInstruction": "Create an editable brand visual project from the system above. Establish one clear direction first and keep the key brand decisions visible on the canvas.",
"brandKitProjectTitle": "{name} Brand Project",
"brandKitPrompt": "Reusable generation direction",
"brandKitPromptPlaceholder": "Turn the most important brand constraints into a direction ready for generation.",
"brandKitReady": "readiness",
"brandKitReferenceDescription": "Upload visual samples that express the brand's composition, photography, material, or mood, then note what to carry forward.",
"brandKitReferenceGuidance": "Reference guidance",
"brandKitReferenceGuidancePlaceholder": "Optional: note the composition, color, texture, or treatment to inherit.",
"brandKitReferenceLimitError": "Each Brand Kit can store up to 6 reference images.",
"brandKitReferenceName": "Reference name",
"brandKitReferenceNamePlaceholder": "For example: Product photography direction",
"brandKitReferenceReadError": "This reference image could not be read.",
"brandKitReferenceSizeError": "Reference images must be under 1 MB.",
"brandKitReferenceTitle": "Reference images",
"brandKitReferenceTypeError": "Upload a PNG, JPG, WebP, or SVG reference image.",
"brandKitReferenceUploaded": "Reference image added",
"brandKitRemoveColor": "Remove color",
"brandKitRemoveColorGroup": "Remove color group",
"brandKitRemoveCover": "Remove cover image",
"brandKitRemoveFont": "Remove font file",
"brandKitRemoveLogo": "Remove logo",
"brandKitRemoveReference": "Remove reference image",
"brandKitRemoveTypography": "Remove type group",
"brandKitReplaceCover": "Replace cover",
"brandKitReplaceFont": "Replace",
"brandKitSaveError": "The Brand Kit could not be saved to your account.",
"brandKitSaveFailed": "Save failed",
"brandKitSaved": "Saved",
"brandKitSaving": "Saving",
"brandKitSectionNavLabel": "Brand Kit sections",
"brandKitSelect": "Choose Brand Kit",
"brandKitStartDescription": "Capture the decisions that shape creative work first, then add the visual assets.",
"brandKitStartTitle": "Make the brand decisions explicit",
"brandKitStrategyDescription": "Define who you are designing for and the position the brand should own.",
"brandKitStrategyNav": "Audience & position",
"brandKitStrategyTitle": "Audience and positioning",
"brandKitSummary": "Brand summary",
"brandKitSummaryPlaceholder": "Describe the brand, product, and core value in one or two sentences.",
"brandKitTagline": "Tagline",
"brandKitTaglinePlaceholder": "A short line that can represent the brand",
"brandKitTemplateAdded": "Example added to your Brand Kit library",
"brandKitTypographyAccent": "Accent type",
"brandKitTypographyBody": "Body type",
"brandKitTypographyDescription": "Upload brand fonts, create custom groups, and optionally define weight, sizes, and usage guidance.",
"brandKitTypographyHeading": "Heading type",
"brandKitTypographyNav": "Typography",
"brandKitTypographyTitle": "Typography system",
"brandKitTypographyName": "Type group name",
"brandKitTypographyNamePlaceholder": "For example: Heading type",
"brandKitUntitled": "Untitled Brand Kit",
"brandKitUnnamedBrand": "Brand name not set",
"brandKitUploadLogo": "Upload logo",
"brandKitUploadLogoHint": "PNG, JPG, WebP, or SVG up to 1 MB",
"brandKitUploadCover": "Upload cover image",
"brandKitUploadCoverHint": "Optional, 16:9 recommended, up to 1 MB",
"brandKitUploadFont": "Upload font",
"brandKitUploadFontHint": "WOFF / WOFF2 / TTF / OTF up to 1 MB",
"brandKitUploadReference": "Upload reference image",
"brandKitUploadReferenceHint": "Optional, PNG, JPG, WebP, or SVG up to 1 MB",
"brandKitUseTemplate": "Use this template",
"brandKitViewExample": "View example",
"brandKitVisualDescription": "Translate an abstract tone into reusable composition, image, and generation rules.",
"brandKitVisualKeywords": "Style keywords",
"brandKitVisualKeywordsPlaceholder": "For example: precise, natural, restrained, energetic",
"brandKitVisualNav": "Visual direction",
"brandKitVisualTitle": "Visual direction",
"brandKitVoiceDescription": "Define how the brand speaks and provide one line that makes the voice concrete.",
"brandKitVoiceGuidance": "Voice guidance",
"brandKitVoiceGuidancePlaceholder": "Describe sentence shape, vocabulary, information order, and language to avoid.",
"brandKitVoiceNav": "Voice",
"brandKitVoiceSample": "Sample line",
"brandKitVoiceSamplePlaceholder": "Write one line that sounds unmistakably like this brand.",
"brandKitVoiceTitle": "Brand voice",
"brandKitVoiceTraits": "Voice traits",
"brandKitVoiceTraitsPlaceholder": "For example: direct, never abrupt; expert, never showy",
"personalProjects": "Personal Projects",
"projectLibrarySubtitle": "Recent projects only shows three. Manage every personal canvas here.",
"editProjects": "Edit",