feat(support): unify Donate + Commercial License behind one toggle (#234)

* feat(support): unify Donate + Commercial License behind one toggle

The donate page and the commercial-license (enterprise) page were two separate
full-screen modes reached from different places. Merge them into a single
SupportPage with a charming segmented toggle:

- Segmented "💛 Support ⇄ 🏢 Commercial License" control with a sliding active
  pill that carries each panel's accent hue (pink for Support, teal for
  License) and an icon that pops on selection.
- Switching cross-fades the panel (key remount replays the hero/card entry
  animations) over the shared Launchpad aurora + a single Back button.
- Both legacy modes still work: 'donate' opens the Support tab, 'enterprise'
  opens the Commercial License tab — so the footer heart and the dub/export
  "commercial license" links land on the right tab unchanged.

Reuses the existing donate/enterprise chrome (DonatePage.css + EnterprisePage.css
kept and imported); SupportPage.css only owns the toggle + transitions. Both
views share one 640px container width so the frame doesn't jump on toggle.
DonatePage.jsx + EnterprisePage.jsx removed (content folded in).

3 new support.* i18n keys, backfilled across 21 locales.
Verified: tsc clean, build OK (SupportPage chunk replaces the two old ones),
vitest 167/167, CJK guard passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(support): add 'Other ways to help' chips + FSL hero_note fix + i18n backfill

- SupportPage: add Star GitHub / Join Discord chips below donation methods
- SupportPage CSS: vertically center short Support panel, single-column
  donation grid, ghost-pill chip styles
- Fix FSL hero_note wording across all 21 locales to accurately reflect
  the license (internal use at any scale is free; only competing
  product/service triggers commercial license)
- New i18n keys: support.other_ways, support.star_github, support.join_discord

* feat(support): polish Support panel + correct Commercial License wording

Support panel (from screenshot feedback):
- Donation methods now stack in a single clean column — no orphaned PayPal
  card floating in a half-empty second row.
- Short Support panel is vertically centered so it no longer clings to the top
  of an empty page (License stays top-aligned; it's tall enough to fill).
- New "Other ways to help" row: Star on GitHub + Join Discord ghost chips, so
  people who can't donate still have a real way to support — and it balances
  the layout.

Commercial License wording:
- Fixed enterprise.hero_note: it implied "deploying at scale (pay-per-use API)"
  triggers a commercial license. Per the actual FSL-1.1-ALv2, scale does NOT
  trigger licensing — internal use is free at any scale; the trigger is
  offering OmniVoice to others as a competing product/service. Reworded to say
  exactly that, and re-translated across all 21 locales.

3 new support.* keys. Verified: tsc clean, build OK, vitest 167/167, CJK guard
passes, 21 locales at parity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: drop stray stories-editor plan doc that slipped into the branch

This planning artifact (with CJK i18n examples) was accidentally swept into
an earlier commit on this branch; it isn't part of the Support-page feature
and isn't on main. Removing it so the CJK guard passes — the committed tree
no longer carries hardcoded CJK outside the translation layer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Palash Debnath
2026-06-01 19:32:22 +05:30
committed by GitHub
co-authored by Claude Opus 4.8
parent dc453cf9da
commit 07479be04f
26 changed files with 627 additions and 317 deletions
+3 -4
View File
@@ -21,8 +21,7 @@ const VoicePreview = lazy(() => import('./components/VoicePreview'));
const LogsFooter = lazy(() => import('./components/LogsFooter'));
const ProjectsPage = lazy(() => import('./pages/Projects'));
const VoiceGallery = lazy(() => import('./pages/VoiceGallery'));
const DonatePage = lazy(() => import('./pages/DonatePage'));
const EnterprisePage = lazy(() => import('./pages/EnterprisePage'));
const SupportPage = lazy(() => import('./pages/SupportPage'));
const TranscriptionsPage = lazy(() => import('./pages/Transcriptions'));
const StoriesEditor = lazy(() => import('./components/StoriesEditor'));
@@ -940,13 +939,13 @@ function App() {
) : mode === 'donate' ? (
<ErrorBoundary name="donate">
<Suspense fallback={<LazyFallback />}>
<DonatePage onBack={() => setMode('launchpad')} onEnterprise={() => setMode('enterprise')} />
<SupportPage initialView="support" onBack={() => setMode('launchpad')} />
</Suspense>
</ErrorBoundary>
) : mode === 'enterprise' ? (
<ErrorBoundary name="enterprise">
<Suspense fallback={<LazyFallback />}>
<EnterprisePage onBack={() => setMode('launchpad')} />
<SupportPage initialView="license" onBack={() => setMode('launchpad')} />
</Suspense>
</ErrorBoundary>
) : mode === 'launchpad' ? (
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "رخصة تجارية",
"hero_title": "شحن أصوات الذكاء الاصطناعي في الإنتاج",
"hero_desc": "OmniVoice Studio متاح المصدر بموجب ترخيص المصدر الوظيفي (FSL). يمكن لمعظم المستخدمين التقييم وإنشاء نماذج أولية وحتى النشر داخليًا بدون اتفاقية تجارية. لا تحتاج إلى ترخيص تجاري إلا إذا كنت تقوم ببناء منتج أو خدمة منافسة، أو إذا كانت حالة الاستخدام الخاصة بك تقع خارج حدود FSL.",
"hero_note": "يتطلب إنشاء منتج أو خدمة منافسة أو نشرها على نطاق واسع (على سبيل المثال، خدمة واجهة برمجة تطبيقات الدفع لكل استخدام) ترخيصًا تجاريًا. ستتوفر مستويات التسعير قريبًا - تواصل معنا في هذه الأثناء.",
"why_title": "لماذا تختار الشركات OmniVoice",
"pricing_title": "التسعير",
"faq_title": "الأسئلة الشائعة",
@@ -993,7 +992,8 @@
"benefit_source": "مصدر متاح الأساسية",
"benefit_source_desc": "الرؤية الكاملة في المكدس. التدقيق والشوكة والتكيف ضمن شروط الترخيص.",
"benefit_lang": "646 لغة",
"benefit_lang_desc": "قم بالنسخ والترجمة والدبلجة عبر 646 لغة بجودة تضاهي المستوى البشري."
"benefit_lang_desc": "قم بالنسخ والترجمة والدبلجة عبر 646 لغة بجودة تضاهي المستوى البشري.",
"hero_note": "الاستخدام الداخلي - حتى على نطاق واسع - مجاني بموجب قانون FSL؛ الترخيص التجاري مطلوب فقط لتقديم OmniVoice للآخرين كمنتج أو خدمة منافسة (واجهة برمجة تطبيقات مستضافة أو الدفع لكل استخدام، أو تطبيق مُعاد بيعه أو ذو علامة بيضاء). ستتوفر مستويات التسعير قريبًا - تواصل معنا في هذه الأثناء."
},
"exportModal": {
"export": "تصدير",
@@ -1572,5 +1572,13 @@
"facet_accent": "لهجة",
"facet_lang": "اللغة",
"facet_whisper": "الهمس"
},
"support": {
"tab_support": "الدعم",
"tab_license": "رخصة تجارية",
"toggle_label": "الدعم أو الترخيص التجاري",
"other_ways": "طرق أخرى للمساعدة",
"star_github": "نجمة على جيثب",
"join_discord": "انضم إلى الفتنة"
}
}
+10 -2
View File
@@ -974,7 +974,6 @@
"badge": "Kommerzielle Lizenz",
"hero_title": "Versenden Sie KI-Stimmen in der Produktion",
"hero_desc": "OmniVoice Studio ist als Quelle unter der Functional Source License (FSL) verfügbar. Die meisten Benutzer können ohne kommerzielle Vereinbarung evaluieren, Prototypen erstellen und sogar intern bereitstellen. Sie benötigen eine kommerzielle Lizenz nur, wenn Sie ein konkurrierendes Produkt oder eine konkurrierende Dienstleistung entwickeln oder wenn Ihr Anwendungsfall außerhalb der FSL-Grenzen liegt.",
"hero_note": "Für den Aufbau eines Konkurrenzprodukts oder -dienstes oder für die Bereitstellung in großem Maßstab (z. B. Bereitstellung einer Pay-per-Use-API) ist eine kommerzielle Lizenz erforderlich. Die Preisstufen folgen in Kürze nehmen Sie in der Zwischenzeit Kontakt mit uns auf.",
"why_title": "Warum Unternehmen sich für OmniVoice entscheiden",
"pricing_title": "Preise",
"faq_title": "Häufige Fragen",
@@ -994,7 +993,8 @@
"benefit_source": "Quellverfügbarer Kern",
"benefit_source_desc": "Volle Sicht auf den Stapel. Prüfen, forken und anpassen Sie innerhalb der Lizenzbedingungen.",
"benefit_lang": "646 Sprachen",
"benefit_lang_desc": "Transkribieren, übersetzen und synchronisieren Sie in 646 Sprachen mit menschlicher Qualität."
"benefit_lang_desc": "Transkribieren, übersetzen und synchronisieren Sie in 646 Sprachen mit menschlicher Qualität.",
"hero_note": "Die interne Nutzung auch in großem Umfang ist im Rahmen der FSL kostenlos; Eine kommerzielle Lizenz ist nur erforderlich, um OmniVoice anderen als Konkurrenzprodukt oder -dienst anzubieten (eine gehostete oder Pay-per-Use-API, eine weiterverkaufte oder White-Label-App). Die Preisstufen folgen bald nehmen Sie in der Zwischenzeit Kontakt mit uns auf."
},
"exportModal": {
"export": "Exportieren",
@@ -1573,5 +1573,13 @@
"facet_accent": "Akzent",
"facet_lang": "Sprache",
"facet_whisper": "Flüstern"
},
"support": {
"tab_support": "Unterstützung",
"tab_license": "Kommerzielle Lizenz",
"toggle_label": "Support oder kommerzielle Lizenz",
"other_ways": "Andere Möglichkeiten zu helfen",
"star_github": "Stern auf GitHub",
"join_discord": "Treten Sie Discord bei"
}
}
+9 -1
View File
@@ -861,7 +861,7 @@
"badge": "Commercial License",
"hero_title": "Ship AI voices in production",
"hero_desc": "OmniVoice Studio is source-available under the Functional Source License (FSL). Most users can evaluate, prototype, and even deploy internally without a commercial agreement. You need a commercial license only if you are building a competing product or service, or if your use case falls outside the FSLs boundaries.",
"hero_note": "Building a competing product or service or deploying at scale (e.g., serving pay-per-use API) requires a commercial license. Pricing tiers coming soon — get in touch in the meantime.",
"hero_note": "Internal use — even at scale — is free under the FSL; a commercial license is only required to offer OmniVoice to others as a competing product or service (a hosted or pay-per-use API, a resold or white-labelled app). Pricing tiers are coming soon — get in touch in the meantime.",
"why_title": "Why businesses choose OmniVoice",
"pricing_title": "Pricing",
"faq_title": "Common questions",
@@ -1564,5 +1564,13 @@
"toast_flush_failed": "Flush failed: {{message}}",
"toast_project_saved": "Project saved",
"toast_project_created": "Project created"
},
"support": {
"tab_support": "Support",
"tab_license": "Commercial License",
"toggle_label": "Support or commercial license",
"other_ways": "Other ways to help",
"star_github": "Star on GitHub",
"join_discord": "Join Discord"
}
}
+10 -2
View File
@@ -974,7 +974,6 @@
"badge": "Licencia Comercial",
"hero_title": "Enviar voces de IA en producción",
"hero_desc": "OmniVoice Studio está disponible bajo la Licencia de fuente funcional (FSL). La mayoría de los usuarios pueden evaluar, crear prototipos e incluso implementar internamente sin un acuerdo comercial. Necesita una licencia comercial sólo si está creando un producto o servicio de la competencia, o si su caso de uso queda fuera de los límites de la FSL.",
"hero_note": "Para crear un producto o servicio competitivo o implementarlo a escala (por ejemplo, ofrecer API de pago por uso) se requiere una licencia comercial. Próximamente niveles de precios; póngase en contacto mientras tanto.",
"why_title": "Por qué las empresas eligen OmniVoice",
"pricing_title": "Precios",
"faq_title": "Preguntas comunes",
@@ -994,7 +993,8 @@
"benefit_source": "Núcleo disponible en la fuente",
"benefit_source_desc": "Visibilidad total de la pila. Audite, bifurque y adapte dentro de los términos de la licencia.",
"benefit_lang": "646 idiomas",
"benefit_lang_desc": "Transcribe, traduce y dobla en 646 idiomas con calidad de nivel humano."
"benefit_lang_desc": "Transcribe, traduce y dobla en 646 idiomas con calidad de nivel humano.",
"hero_note": "El uso interno, incluso a escala, es gratuito según la FSL; solo se requiere una licencia comercial para ofrecer OmniVoice a otros como un producto o servicio de la competencia (una API alojada o de pago por uso, una aplicación revendida o de marca blanca). Los niveles de precios estarán disponibles pronto; póngase en contacto mientras tanto."
},
"exportModal": {
"export": "Exportar",
@@ -1573,5 +1573,13 @@
"facet_accent": "acento",
"facet_lang": "Idioma",
"facet_whisper": "susurro"
},
"support": {
"tab_support": "Soporte",
"tab_license": "Licencia Comercial",
"toggle_label": "Soporte o licencia comercial",
"other_ways": "Otras formas de ayudar",
"star_github": "Estrella en GitHub",
"join_discord": "Únete a la discordia"
}
}
+10 -2
View File
@@ -974,7 +974,6 @@
"badge": "Licence commerciale",
"hero_title": "Expédier les voix de l'IA en production",
"hero_desc": "OmniVoice Studio est disponible sous la licence Functional Source (FSL). La plupart des utilisateurs peuvent évaluer, prototyper et même déployer en interne sans accord commercial. Vous navez besoin dune licence commerciale que si vous créez un produit ou un service concurrent, ou si votre cas dutilisation dépasse les limites du FSL.",
"hero_note": "La création d'un produit ou d'un service concurrent ou son déploiement à grande échelle (par exemple, la fourniture d'une API payante à l'utilisation) nécessite une licence commerciale. Niveaux de tarification à venir contactez-nous en attendant.",
"why_title": "Pourquoi les entreprises choisissent OmniVoice",
"pricing_title": "Tarifs",
"faq_title": "Questions courantes",
@@ -994,7 +993,8 @@
"benefit_source": "Noyau disponible à la source",
"benefit_source_desc": "Visibilité totale sur la pile. Auditez, forkez et adaptez selon les termes de la licence.",
"benefit_lang": "646 langues",
"benefit_lang_desc": "Transcrivez, traduisez et doublez dans 646 langues avec une qualité humaine."
"benefit_lang_desc": "Transcrivez, traduisez et doublez dans 646 langues avec une qualité humaine.",
"hero_note": "Lutilisation interne même à grande échelle est gratuite dans le cadre du FSL ; une licence commerciale n'est requise que pour proposer OmniVoice à des tiers en tant que produit ou service concurrent (une API hébergée ou payante à l'utilisation, une application revendue ou en marque blanche). Les niveaux de tarification arriveront bientôt contactez-nous en attendant."
},
"exportModal": {
"export": "Exporter",
@@ -1573,5 +1573,13 @@
"facet_accent": "Accent",
"facet_lang": "Langue",
"facet_whisper": "Chuchoter"
},
"support": {
"tab_support": "Assistance",
"tab_license": "Licence commerciale",
"toggle_label": "Support ou licence commerciale",
"other_ways": "Autres moyens d'aider",
"star_github": "Étoile sur GitHub",
"join_discord": "Rejoignez Discorde"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "वाणिज्यिक लाइसेंस",
"hero_title": "उत्पादन में एआई आवाजें भेजें",
"hero_desc": "ओमनीवॉइस स्टूडियो फंक्शनल सोर्स लाइसेंस (एफएसएल) के तहत स्रोत-उपलब्ध है। अधिकांश उपयोगकर्ता व्यावसायिक समझौते के बिना मूल्यांकन, प्रोटोटाइप और यहां तक ​​कि आंतरिक रूप से तैनात भी कर सकते हैं। आपको वाणिज्यिक लाइसेंस की आवश्यकता केवल तभी होती है जब आप कोई प्रतिस्पर्धी उत्पाद या सेवा बना रहे हों, या यदि आपका उपयोग मामला एफएसएल की सीमाओं से बाहर हो।",
"hero_note": "एक प्रतिस्पर्धी उत्पाद या सेवा का निर्माण या बड़े पैमाने पर तैनाती (उदाहरण के लिए, भुगतान-प्रति-उपयोग एपीआई की सेवा) के लिए एक वाणिज्यिक लाइसेंस की आवश्यकता होती है। मूल्य निर्धारण स्तर जल्द ही आ रहे हैं - इस बीच संपर्क करें।",
"why_title": "व्यवसाय ओमनीवॉइस क्यों चुनते हैं?",
"pricing_title": "मूल्य निर्धारण",
"faq_title": "सामान्य प्रश्न",
@@ -993,7 +992,8 @@
"benefit_source": "स्रोत-उपलब्ध कोर",
"benefit_source_desc": "स्टैक में पूर्ण दृश्यता. लाइसेंस शर्तों के भीतर ऑडिट, फोर्क और अनुकूलन करें।",
"benefit_lang": "646 भाषाएँ",
"benefit_lang_desc": "मानव-स्तरीय गुणवत्ता के साथ 646 भाषाओं में प्रतिलेखन, अनुवाद और डब करें।"
"benefit_lang_desc": "मानव-स्तरीय गुणवत्ता के साथ 646 भाषाओं में प्रतिलेखन, अनुवाद और डब करें।",
"hero_note": "आंतरिक उपयोग - यहां तक ​​कि बड़े पैमाने पर - एफएसएल के तहत मुफ़्त है; एक वाणिज्यिक लाइसेंस की आवश्यकता केवल दूसरों को एक प्रतिस्पर्धी उत्पाद या सेवा (एक होस्टेड या भुगतान-प्रति-उपयोग एपीआई, एक पुनर्विक्रय या व्हाइट-लेबल ऐप) के रूप में ओमनीवॉइस की पेशकश करने के लिए आवश्यक है। मूल्य निर्धारण स्तर जल्द ही आ रहे हैं - इस बीच संपर्क करें।"
},
"exportModal": {
"export": "निर्यात करें",
@@ -1572,5 +1572,13 @@
"facet_accent": "उच्चारण",
"facet_lang": "भाषा",
"facet_whisper": "कानाफूसी"
},
"support": {
"tab_support": "समर्थन",
"tab_license": "वाणिज्यिक लाइसेंस",
"toggle_label": "समर्थन या वाणिज्यिक लाइसेंस",
"other_ways": "मदद करने के अन्य तरीके",
"star_github": "GitHub पर स्टार लगाएं",
"join_discord": "कलह में शामिल हों"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Lisensi Komersial",
"hero_title": "Kirimkan suara AI dalam produksi",
"hero_desc": "OmniVoice Studio tersedia sumbernya di bawah Lisensi Sumber Fungsional (FSL). Sebagian besar pengguna dapat mengevaluasi, membuat prototipe, dan bahkan menerapkan secara internal tanpa perjanjian komersial. Anda memerlukan lisensi komersial hanya jika Anda membuat produk atau layanan pesaing, atau jika kasus penggunaan Anda berada di luar batasan FSL.",
"hero_note": "Membangun produk atau layanan pesaing atau menerapkannya dalam skala besar (misalnya, menyajikan API bayar per penggunaan) memerlukan lisensi komersial. Tingkatan harga akan segera hadir — hubungi kami sementara itu.",
"why_title": "Mengapa bisnis memilih OmniVoice",
"pricing_title": "Harga",
"faq_title": "Pertanyaan umum",
@@ -993,7 +992,8 @@
"benefit_source": "Inti yang tersedia sumber",
"benefit_source_desc": "Visibilitas penuh ke dalam tumpukan. Audit, fork, dan adaptasi sesuai ketentuan lisensi.",
"benefit_lang": "646 bahasa",
"benefit_lang_desc": "Transkripsikan, terjemahkan, dan sulih suara dalam 646 bahasa dengan kualitas setingkat manusia."
"benefit_lang_desc": "Transkripsikan, terjemahkan, dan sulih suara dalam 646 bahasa dengan kualitas setingkat manusia.",
"hero_note": "Penggunaan internal — bahkan dalam skala besar — gratis di bawah FSL; lisensi komersial hanya diperlukan untuk menawarkan OmniVoice kepada orang lain sebagai produk atau layanan pesaing (API yang dihosting atau bayar per penggunaan, aplikasi yang dijual kembali atau diberi label putih). Tingkatan harga akan segera hadir — hubungi kami sementara ini."
},
"exportModal": {
"export": "Ekspor",
@@ -1572,5 +1572,13 @@
"facet_accent": "Aksen",
"facet_lang": "Bahasa",
"facet_whisper": "Bisikan"
},
"support": {
"tab_support": "Dukungan",
"tab_license": "Lisensi Komersial",
"toggle_label": "Dukungan atau lisensi komersial",
"other_ways": "Cara lain untuk membantu",
"star_github": "Bintangi di GitHub",
"join_discord": "Bergabunglah dengan Perselisihan"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Licenza commerciale",
"hero_title": "Spedisci voci AI in produzione",
"hero_desc": "OmniVoice Studio è disponibile come codice sorgente sotto la Functional Source License (FSL). La maggior parte degli utenti può valutare, prototipare e persino implementare internamente senza un accordo commerciale. Hai bisogno di una licenza commerciale solo se stai creando un prodotto o servizio concorrente o se il tuo caso d'uso non rientra nei confini dell'FSL.",
"hero_note": "La creazione di un prodotto o servizio concorrente o la distribuzione su larga scala (ad esempio, la fornitura di API pay-per-use) richiede una licenza commerciale. Livelli di prezzo in arrivo: contattaci nel frattempo.",
"why_title": "Perché le aziende scelgono OmniVoice",
"pricing_title": "Prezzi",
"faq_title": "Domande comuni",
@@ -993,7 +992,8 @@
"benefit_source": "Nucleo disponibile alla fonte",
"benefit_source_desc": "Visibilità completa nello stack. Controlla, effettua il fork e adatta entro i termini della licenza.",
"benefit_lang": "646 lingue",
"benefit_lang_desc": "Trascrivi, traduci e doppia in 646 lingue con una qualità a livello umano."
"benefit_lang_desc": "Trascrivi, traduci e doppia in 646 lingue con una qualità a livello umano.",
"hero_note": "Luso interno anche su larga scala è gratuito secondo lFSL; è necessaria una licenza commerciale solo per offrire OmniVoice ad altri come prodotto o servizio concorrente (un'API ospitata o a pagamento, un'app rivenduta o con etichetta bianca). I livelli di prezzo arriveranno presto: contattaci nel frattempo."
},
"exportModal": {
"export": "Esportazione",
@@ -1572,5 +1572,13 @@
"facet_accent": "Accento",
"facet_lang": "Lingua",
"facet_whisper": "Sussurrare"
},
"support": {
"tab_support": "Supporto",
"tab_license": "Licenza commerciale",
"toggle_label": "Supporto o licenza commerciale",
"other_ways": "Altri modi per aiutare",
"star_github": "Stella su GitHub",
"join_discord": "Unisciti a Discord"
}
}
+10 -2
View File
@@ -974,7 +974,6 @@
"badge": "商用ライセンス",
"hero_title": "本番環境で AI 音声を出荷",
"hero_desc": "OmniVoice Studio は、Functional Source License (FSL) に基づいてソース提供されています。ほとんどのユーザーは、商業契約なしで評価、プロトタイプを作成し、さらには社内で導入することができます。商用ライセンスが必要になるのは、競合する製品やサービスを構築している場合、またはユースケースが FSL の境界外にある場合のみです。",
"hero_note": "競合する製品やサービスを構築したり、大規模に展開したりする場合 (従量課金制 API の提供など)、商用ライセンスが必要です。価格帯は近日公開予定です。それまでにお問い合わせください。",
"why_title": "企業が OmniVoice を選ぶ理由",
"pricing_title": "価格設定",
"faq_title": "よくある質問",
@@ -994,7 +993,8 @@
"benefit_source": "ソースが利用可能なコア",
"benefit_source_desc": "スタックを完全に可視化します。ライセンス条項内で監査、フォーク、適応を行います。",
"benefit_lang": "646の言語",
"benefit_lang_desc": "人間レベルの品質で 646 言語の文字起こし、翻訳、吹き替えを行います。"
"benefit_lang_desc": "人間レベルの品質で 646 言語の文字起こし、翻訳、吹き替えを行います。",
"hero_note": "FSL では、内部使用は大規模であっても無料です。商用ライセンスは、OmniVoice を競合製品またはサービス (ホスト型 API または従量制 API、再販またはホワイトラベル アプリ) として他者に提供する場合にのみ必要です。価格帯は近日中に公開される予定です。それまでにお問い合わせください。"
},
"exportModal": {
"export": "エクスポート",
@@ -1573,5 +1573,13 @@
"facet_accent": "アクセント",
"facet_lang": "言語",
"facet_whisper": "ささやき"
},
"support": {
"tab_support": "サポート",
"tab_license": "商用ライセンス",
"toggle_label": "サポートまたは商用ライセンス",
"other_ways": "その他の支援方法",
"star_github": "GitHub でスターを付ける",
"join_discord": "Discordに参加する"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "상업용 라이센스",
"hero_title": "프로덕션에 AI 음성 전달",
"hero_desc": "OmniVoice Studio는 FSL(Functional Source License)에 따라 소스를 사용할 수 있습니다. 대부분의 사용자는 상업적 계약 없이 내부적으로 평가, 프로토타입 작성 및 배포까지 할 수 있습니다. 경쟁 제품이나 서비스를 구축하는 경우 또는 사용 사례가 FSL의 경계를 벗어나는 경우에만 상업용 라이선스가 필요합니다.",
"hero_note": "경쟁 제품이나 서비스를 구축하거나 대규모 배포(예: 종량제 API 제공)에는 상용 라이선스가 필요합니다. 가격 책정 단계가 곧 제공될 예정입니다. 그동안 연락해 주세요.",
"why_title": "기업이 OmniVoice를 선택하는 이유",
"pricing_title": "가격",
"faq_title": "일반적인 질문",
@@ -993,7 +992,8 @@
"benefit_source": "소스 사용 가능한 코어",
"benefit_source_desc": "스택에 대한 완전한 가시성. 라이선스 조건 내에서 감사, 분기 및 조정합니다.",
"benefit_lang": "646개 언어",
"benefit_lang_desc": "인간 수준의 품질로 646개 언어로 전사, 번역, 더빙하세요."
"benefit_lang_desc": "인간 수준의 품질로 646개 언어로 전사, 번역, 더빙하세요.",
"hero_note": "내부 사용은 규모에 상관없이 FSL에 따라 무료입니다. 상업용 라이선스는 OmniVoice를 경쟁 제품이나 서비스(호스팅 또는 종량제 API, 재판매 또는 화이트 라벨 앱)로 다른 사람에게 제공하는 데만 필요합니다. 가격 등급이 곧 제공될 예정입니다. 그동안 연락해 주세요."
},
"exportModal": {
"export": "수출",
@@ -1572,5 +1572,13 @@
"facet_accent": "악센트",
"facet_lang": "언어",
"facet_whisper": "속삭임"
},
"support": {
"tab_support": "지원",
"tab_license": "상업용 라이센스",
"toggle_label": "지원 또는 상업용 라이센스",
"other_ways": "도움을 줄 수 있는 다른 방법",
"star_github": "GitHub의 스타",
"join_discord": "디스코드에 참여하세요"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Commerciële licentie",
"hero_title": "Verzend AI-stemmen in productie",
"hero_desc": "OmniVoice Studio is bron-beschikbaar onder de Functionele Bronlicentie (FSL). De meeste gebruikers kunnen zonder commerciële overeenkomst evalueren, prototypen maken en zelfs intern implementeren. U heeft alleen een commerciële licentie nodig als u een concurrerend product of dienst bouwt, of als uw gebruiksscenario buiten de grenzen van de FSL valt.",
"hero_note": "Voor het bouwen van een concurrerend product of dienst of het op grote schaal implementeren (bijvoorbeeld het aanbieden van een pay-per-use API) is een commerciële licentie vereist. Prijsniveaus volgen binnenkort. Neem in de tussentijd contact met ons op.",
"why_title": "Waarom bedrijven voor OmniVoice kiezen",
"pricing_title": "Prijzen",
"faq_title": "Veelgestelde vragen",
@@ -993,7 +992,8 @@
"benefit_source": "Bronbeschikbare kern",
"benefit_source_desc": "Volledig zicht op de stapel. Audit, fork en pas aan binnen de licentievoorwaarden.",
"benefit_lang": "646 talen",
"benefit_lang_desc": "Transcribeer, vertaal en kopieer in 646 talen met kwaliteit op menselijk niveau."
"benefit_lang_desc": "Transcribeer, vertaal en kopieer in 646 talen met kwaliteit op menselijk niveau.",
"hero_note": "Intern gebruik zelfs op grote schaal is gratis onder de FSL; een commerciële licentie is alleen vereist om OmniVoice aan anderen aan te bieden als een concurrerend product of dienst (een gehoste of pay-per-use API, een doorverkochte of white-labeled app). Prijsniveaus volgen binnenkort. Neem in de tussentijd contact met ons op."
},
"exportModal": {
"export": "Exporteren",
@@ -1572,5 +1572,13 @@
"facet_accent": "Accent",
"facet_lang": "Taal",
"facet_whisper": "Fluister"
},
"support": {
"tab_support": "Ondersteuning",
"tab_license": "Commerciële licentie",
"toggle_label": "Ondersteuning of commerciële licentie",
"other_ways": "Andere manieren om te helpen",
"star_github": "Ster op GitHub",
"join_discord": "Sluit je aan bij Discord"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Licencja komercyjna",
"hero_title": "Wysyłaj głosy AI w produkcji",
"hero_desc": "OmniVoice Studio jest dostępne w formie źródłowej na podstawie licencji Functional Source License (FSL). Większość użytkowników może oceniać, tworzyć prototypy, a nawet wdrażać wewnętrznie bez umowy komercyjnej. Licencja komercyjna jest Ci potrzebna tylko wtedy, gdy budujesz konkurencyjny produkt lub usługę lub jeśli Twój przypadek użycia wykracza poza granice FSL.",
"hero_note": "Tworzenie konkurencyjnego produktu lub usługi lub wdrażanie na dużą skalę (np. obsługa interfejsu API płatności za użycie) wymaga licencji komercyjnej. Poziomy cenowe już wkrótce — skontaktuj się z nami w międzyczasie.",
"why_title": "Dlaczego firmy wybierają OmniVoice",
"pricing_title": "Ceny",
"faq_title": "Często zadawane pytania",
@@ -993,7 +992,8 @@
"benefit_source": "Rdzeń dostępny ze źródła",
"benefit_source_desc": "Pełna widoczność stosu. Audytuj, rozwidlaj i dostosowuj zgodnie z warunkami licencji.",
"benefit_lang": "646 języków",
"benefit_lang_desc": "Transkrypcja, tłumaczenie i kopiowanie w 646 językach z jakością na poziomie ludzkim."
"benefit_lang_desc": "Transkrypcja, tłumaczenie i kopiowanie w 646 językach z jakością na poziomie ludzkim.",
"hero_note": "Do użytku wewnętrznego — nawet na dużą skalę — jest bezpłatne w ramach FSL; licencja komercyjna jest wymagana jedynie do oferowania OmniVoice innym jako konkurencyjny produkt lub usługa (interfejs API hostowany lub płatny za użycie, aplikacja odsprzedawana lub z białą etykietą). Poziomy cenowe już wkrótce — skontaktuj się z nami w międzyczasie."
},
"exportModal": {
"export": "Eksportuj",
@@ -1572,5 +1572,13 @@
"facet_accent": "Akcent",
"facet_lang": "Język",
"facet_whisper": "Szeptać"
},
"support": {
"tab_support": "Wsparcie",
"tab_license": "Licencja komercyjna",
"toggle_label": "Wsparcie lub licencja komercyjna",
"other_ways": "Inne sposoby pomocy",
"star_github": "Gwiazda na GitHubie",
"join_discord": "Dołącz do Discorda"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Licença Comercial",
"hero_title": "Envie vozes de IA em produção",
"hero_desc": "OmniVoice Studio está disponível sob a Licença de Fonte Funcional (FSL). A maioria dos usuários pode avaliar, criar protótipos e até implantar internamente sem um acordo comercial. Você só precisa de uma licença comercial se estiver construindo um produto ou serviço concorrente ou se seu caso de uso estiver fora dos limites do FSL.",
"hero_note": "Construir um produto ou serviço concorrente ou implantá-lo em escala (por exemplo, servir API paga conforme o uso) requer uma licença comercial. Os níveis de preços estarão disponíveis em breve. Entre em contato enquanto isso.",
"why_title": "Por que as empresas escolhem OmniVoice",
"pricing_title": "Preços",
"faq_title": "Perguntas comuns",
@@ -993,7 +992,8 @@
"benefit_source": "Núcleo disponível na fonte",
"benefit_source_desc": "Visibilidade total da pilha. Audite, bifurque e adapte-se aos termos da licença.",
"benefit_lang": "646 idiomas",
"benefit_lang_desc": "Transcreva, traduza e duble em 646 idiomas com qualidade de nível humano."
"benefit_lang_desc": "Transcreva, traduza e duble em 646 idiomas com qualidade de nível humano.",
"hero_note": "O uso interno mesmo em grande escala é gratuito sob o FSL; uma licença comercial só é necessária para oferecer o OmniVoice a terceiros como um produto ou serviço concorrente (uma API hospedada ou paga por uso, um aplicativo revendido ou com etiqueta branca). Os níveis de preços estarão disponíveis em breve. Entre em contato enquanto isso."
},
"exportModal": {
"export": "Exportar",
@@ -1572,5 +1572,13 @@
"facet_accent": "Sotaque",
"facet_lang": "Idioma",
"facet_whisper": "Sussurro"
},
"support": {
"tab_support": "Suporte",
"tab_license": "Licença Comercial",
"toggle_label": "Suporte ou licença comercial",
"other_ways": "Outras maneiras de ajudar",
"star_github": "Estrela no GitHub",
"join_discord": "Junte-se à discórdia"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Коммерческая лицензия",
"hero_title": "Запуск голосов ИИ в производство",
"hero_desc": "Исходный код OmniVoice Studio доступен по лицензии Functional Source License (FSL). Большинство пользователей могут оценить, создать прототип и даже развернуть внутри компании без коммерческого соглашения. Коммерческая лицензия вам понадобится только в том случае, если вы создаете конкурирующий продукт или услугу или если ваш вариант использования выходит за рамки FSL.",
"hero_note": "Для создания конкурирующего продукта или услуги или масштабного развертывания (например, предоставления API с оплатой по факту использования) требуется коммерческая лицензия. Скоро появятся ценовые уровни, а пока свяжитесь с нами.",
"why_title": "Почему компании выбирают OmniVoice",
"pricing_title": "Цены",
"faq_title": "Общие вопросы",
@@ -993,7 +992,8 @@
"benefit_source": "Ядро, доступное в исходном коде",
"benefit_source_desc": "Полная видимость стека. Аудит, форк и адаптация в рамках условий лицензии.",
"benefit_lang": "646 языков",
"benefit_lang_desc": "Транскрибируйте, переводите и дублируйте на 646 языках с качеством человеческого уровня."
"benefit_lang_desc": "Транскрибируйте, переводите и дублируйте на 646 языках с качеством человеческого уровня.",
"hero_note": "Внутреннее использование — даже в больших масштабах — бесплатно в соответствии с FSL; Коммерческая лицензия требуется только для предложения OmniVoice другим лицам в качестве конкурирующего продукта или услуги (размещенный API или API с оплатой по факту использования, перепродаваемое приложение или приложение с белой маркировкой). Ценовые уровни будут объявлены в ближайшее время — свяжитесь с нами."
},
"exportModal": {
"export": "Экспорт",
@@ -1572,5 +1572,13 @@
"facet_accent": "Акцент",
"facet_lang": "Язык",
"facet_whisper": "Шепот"
},
"support": {
"tab_support": "Поддерживать",
"tab_license": "Коммерческая лицензия",
"toggle_label": "Поддержка или коммерческая лицензия",
"other_ways": "Другие способы помочь",
"star_github": "Звезда на GitHub",
"join_discord": "Присоединяйтесь к Discord"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Kommersiell licens",
"hero_title": "Ship AI-röster i produktion",
"hero_desc": "OmniVoice Studio är källtillgänglig under Functional Source License (FSL). De flesta användare kan utvärdera, prototyper och till och med distribuera internt utan ett kommersiellt avtal. Du behöver endast en kommersiell licens om du bygger en konkurrerande produkt eller tjänst, eller om ditt användningsfall faller utanför FSL:s gränser.",
"hero_note": "Att bygga en konkurrerande produkt eller tjänst eller distribuera i stor skala (t.ex. betjäna pay-per-use API) kräver en kommersiell licens. Prisnivåer kommer snart hör av dig under tiden.",
"why_title": "Varför företag väljer OmniVoice",
"pricing_title": "Prissättning",
"faq_title": "Vanliga frågor",
@@ -993,7 +992,8 @@
"benefit_source": "Källa-tillgänglig kärna",
"benefit_source_desc": "Full insyn i stapeln. Granska, fördela och anpassa inom licensvillkoren.",
"benefit_lang": "646 språk",
"benefit_lang_desc": "Transkribera, översätt och dubba på 646 språk med kvalitet på mänsklig nivå."
"benefit_lang_desc": "Transkribera, översätt och dubba på 646 språk med kvalitet på mänsklig nivå.",
"hero_note": "Intern användning även i stor skala är gratis enligt FSL; en kommersiell licens krävs endast för att erbjuda OmniVoice till andra som en konkurrerande produkt eller tjänst (ett värd- eller pay-per-use API, en vidaresåld eller vitmärkt app). Prisnivåer kommer snart - hör av dig under tiden."
},
"exportModal": {
"export": "Exportera",
@@ -1572,5 +1572,13 @@
"facet_accent": "Accent",
"facet_lang": "Språk",
"facet_whisper": "Viska"
},
"support": {
"tab_support": "Support",
"tab_license": "Kommersiell licens",
"toggle_label": "Support eller kommersiell licens",
"other_ways": "Andra sätt att hjälpa till",
"star_github": "Stjärna på GitHub",
"join_discord": "Gå med i Discord"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "ใบอนุญาตการค้า",
"hero_title": "จัดส่งเสียง AI ในการผลิต",
"hero_desc": "OmniVoice Studio มีแหล่งที่มาภายใต้ Functional Source License (FSL) ผู้ใช้ส่วนใหญ่สามารถประเมิน สร้างต้นแบบ และแม้แต่ปรับใช้ภายในโดยไม่ต้องมีข้อตกลงทางการค้า คุณต้องมีใบอนุญาตเชิงพาณิชย์เฉพาะในกรณีที่คุณกำลังสร้างผลิตภัณฑ์หรือบริการของคู่แข่ง หรือหากกรณีการใช้งานของคุณอยู่นอกขอบเขตของ FSL",
"hero_note": "การสร้างผลิตภัณฑ์หรือบริการที่แข่งขันกัน หรือการปรับใช้ในวงกว้าง (เช่น การให้บริการ API แบบจ่ายตามการใช้งาน) จำเป็นต้องมีใบอนุญาตเชิงพาณิชย์ ระดับราคาจะมาเร็วๆ นี้ โปรดติดต่อในระหว่างนี้",
"why_title": "เหตุใดธุรกิจจึงเลือก OmniVoice",
"pricing_title": "ราคา",
"faq_title": "คำถามทั่วไป",
@@ -993,7 +992,8 @@
"benefit_source": "แกนหลักที่มีแหล่งที่มา",
"benefit_source_desc": "มองเห็นสแต็กได้เต็มรูปแบบ ตรวจสอบ แยก และปรับเปลี่ยนภายในข้อกำหนดสิทธิ์การใช้งาน",
"benefit_lang": "646 ภาษา",
"benefit_lang_desc": "ถอดเสียง แปล และพากย์ใน 646 ภาษาด้วยคุณภาพระดับมนุษย์"
"benefit_lang_desc": "ถอดเสียง แปล และพากย์ใน 646 ภาษาด้วยคุณภาพระดับมนุษย์",
"hero_note": "การใช้งานภายใน — แม้ในปริมาณมาก — ไม่มีค่าใช้จ่ายภายใต้ FSL; จำเป็นต้องมีใบอนุญาตเชิงพาณิชย์เพื่อเสนอ OmniVoice ให้กับผู้อื่นในฐานะผลิตภัณฑ์หรือบริการของคู่แข่งเท่านั้น (API ที่โฮสต์หรือแบบจ่ายตามการใช้งาน แอปที่ขายต่อหรือมีป้ายกำกับสีขาว) ระดับราคากำลังจะมาในเร็วๆ นี้ โปรดติดต่อในระหว่างนี้"
},
"exportModal": {
"export": "ส่งออก",
@@ -1572,5 +1572,13 @@
"facet_accent": "สำเนียง",
"facet_lang": "ภาษา",
"facet_whisper": "กระซิบ"
},
"support": {
"tab_support": "สนับสนุน",
"tab_license": "ใบอนุญาตการค้า",
"toggle_label": "การสนับสนุนหรือใบอนุญาตทางการค้า",
"other_ways": "วิธีอื่นในการช่วยเหลือ",
"star_github": "ติดดาวบน GitHub",
"join_discord": "เข้าร่วมความไม่ลงรอยกัน"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Ticari Lisans",
"hero_title": "Üretimde yapay zeka seslerini gönderin",
"hero_desc": "OmniVoice Studio, İşlevsel Kaynak Lisansı (FSL) kapsamında kaynak olarak mevcuttur. Çoğu kullanıcı ticari bir anlaşma olmadan dahili olarak değerlendirebilir, prototip oluşturabilir ve hatta dağıtabilir. Ticari lisansa yalnızca rakip bir ürün veya hizmet geliştiriyorsanız ya da kullanım alanınız FSL sınırlarının dışında kalıyorsa ihtiyacınız vardır.",
"hero_note": "Rakip bir ürün veya hizmet oluşturmak ya da geniş ölçekte dağıtmak (ör. kullanım başına ödeme API'si sunmak) ticari bir lisans gerektirir. Fiyatlandırma katmanları yakında gelecek; bu arada bizimle iletişime geçin.",
"why_title": "İşletmeler neden OmniVoice'u seçiyor?",
"pricing_title": "Fiyatlandırma",
"faq_title": "Sık sorulan sorular",
@@ -993,7 +992,8 @@
"benefit_source": "Kaynakta mevcut çekirdek",
"benefit_source_desc": "Yığına tam görünürlük. Lisans koşulları dahilinde denetleyin, çatallayın ve uyarlayın.",
"benefit_lang": "646 dil",
"benefit_lang_desc": "646 dilde insan düzeyinde kaliteyle metne dönüştürün, tercüme edin ve dublaj yapın."
"benefit_lang_desc": "646 dilde insan düzeyinde kaliteyle metne dönüştürün, tercüme edin ve dublaj yapın.",
"hero_note": "FSL kapsamında dahili kullanım - geniş ölçekte bile - ücretsizdir; ticari lisans yalnızca OmniVoice'u başkalarına rakip bir ürün veya hizmet (barındırılan veya kullanım başına ödemeli API, yeniden satılan veya beyaz etiketli bir uygulama) olarak sunmak için gereklidir. Fiyatlandırma katmanları yakında gelecek; bu arada bizimle iletişime geçin."
},
"exportModal": {
"export": "İhracat",
@@ -1572,5 +1572,13 @@
"facet_accent": "Aksan",
"facet_lang": "Dil",
"facet_whisper": "Fısıltı"
},
"support": {
"tab_support": "Destek",
"tab_license": "Ticari Lisans",
"toggle_label": "Destek veya ticari lisans",
"other_ways": "Yardım etmenin diğer yolları",
"star_github": "GitHub'da yıldız",
"join_discord": "Discord'a Katılın"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Комерційна ліцензія",
"hero_title": "Надішліть голоси AI у виробництво",
"hero_desc": "OmniVoice Studio доступний із джерелом відповідно до ліцензії на функціональне джерело (FSL). Більшість користувачів можуть оцінювати, прототипувати та навіть розгортати всередині країни без комерційної угоди. Вам потрібна комерційна ліцензія, лише якщо ви створюєте конкуруючий продукт чи послугу або якщо ваш варіант використання виходить за межі FSL.",
"hero_note": "Створення конкуруючого продукту чи послуги або масштабне розгортання (наприклад, обслуговування API з оплатою за використання) вимагає комерційної ліцензії. Рівні цін незабаром — поки зв’яжіться з нами.",
"why_title": "Чому компанії обирають OmniVoice",
"pricing_title": "Ціноутворення",
"faq_title": "Загальні запитання",
@@ -993,7 +992,8 @@
"benefit_source": "Доступне джерело ядра",
"benefit_source_desc": "Повна видимість стека. Аудит, розгалуження та адаптація в рамках умов ліцензії.",
"benefit_lang": "646 мов",
"benefit_lang_desc": "Транскрибуйте, перекладайте та дублюйте 646 мовами з якістю людського рівня."
"benefit_lang_desc": "Транскрибуйте, перекладайте та дублюйте 646 мовами з якістю людського рівня.",
"hero_note": "Внутрішнє використання — навіть у великих масштабах — є безкоштовним відповідно до FSL; комерційна ліцензія потрібна лише для того, щоб пропонувати OmniVoice іншим як конкуруючий продукт або послугу (розміщений API або API з оплатою за використання, програма, що перепродається або має мітку «білий»). Незабаром з’являться рівні цін — поки зв’яжіться з нами."
},
"exportModal": {
"export": "Експорт",
@@ -1572,5 +1572,13 @@
"facet_accent": "Акцент",
"facet_lang": "Мова",
"facet_whisper": "Шепіт"
},
"support": {
"tab_support": "Підтримка",
"tab_license": "Комерційна ліцензія",
"toggle_label": "Підтримка або комерційна ліцензія",
"other_ways": "Інші способи допомоги",
"star_github": "Зірка на GitHub",
"join_discord": "Приєднуйтесь до Discord"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "Giấy phép thương mại",
"hero_title": "Vận chuyển giọng nói AI trong quá trình sản xuất",
"hero_desc": "OmniVoice Studio có sẵn nguồn theo Giấy phép Nguồn Chức năng (FSL). Hầu hết người dùng có thể đánh giá, tạo nguyên mẫu và thậm chí triển khai nội bộ mà không cần thỏa thuận thương mại. Bạn chỉ cần giấy phép thương mại nếu bạn đang xây dựng một sản phẩm hoặc dịch vụ cạnh tranh hoặc nếu trường hợp sử dụng của bạn nằm ngoài ranh giới của FSL.",
"hero_note": "Việc xây dựng một sản phẩm hoặc dịch vụ cạnh tranh hoặc triển khai trên quy mô lớn (ví dụ: cung cấp API trả tiền cho mỗi lần sử dụng) cần có giấy phép thương mại. Sắp có mức giá — hãy liên hệ trong thời gian chờ đợi.",
"why_title": "Tại sao doanh nghiệp chọn OmniVoice",
"pricing_title": "Định giá",
"faq_title": "Câu hỏi thường gặp",
@@ -993,7 +992,8 @@
"benefit_source": "Lõi có sẵn nguồn",
"benefit_source_desc": "Hiển thị đầy đủ vào ngăn xếp. Kiểm tra, phân nhánh và điều chỉnh theo các điều khoản cấp phép.",
"benefit_lang": "646 ngôn ngữ",
"benefit_lang_desc": "Phiên âm, dịch và lồng tiếng trên 646 ngôn ngữ với chất lượng ngang tầm con người."
"benefit_lang_desc": "Phiên âm, dịch và lồng tiếng trên 646 ngôn ngữ với chất lượng ngang tầm con người.",
"hero_note": "Việc sử dụng nội bộ — ngay cả ở quy mô lớn — đều miễn phí theo FSL; giấy phép thương mại chỉ được yêu cầu để cung cấp OmniVoice cho người khác dưới dạng sản phẩm hoặc dịch vụ cạnh tranh (API được lưu trữ hoặc trả tiền cho mỗi lần sử dụng, ứng dụng được bán lại hoặc được gắn nhãn trắng). Sắp có mức giá - hãy liên hệ trong thời gian chờ đợi."
},
"exportModal": {
"export": "Xuất khẩu",
@@ -1572,5 +1572,13 @@
"facet_accent": "Giọng",
"facet_lang": "Ngôn ngữ",
"facet_whisper": "Thì thầm"
},
"support": {
"tab_support": "Hỗ trợ",
"tab_license": "Giấy phép thương mại",
"toggle_label": "Hỗ trợ hoặc giấy phép thương mại",
"other_ways": "Những cách khác để giúp đỡ",
"star_github": "Sao trên GitHub",
"join_discord": "Tham gia bất hòa"
}
}
+10 -2
View File
@@ -943,7 +943,6 @@
"badge": "商业许可",
"hero_title": "在生产环境中部署 AI 语音",
"hero_desc": "OmniVoice Studio 采用功能性源代码许可(FSL)。大多数用户可以在无需商业协议的情况下评估、原型开发甚至内部部署。只有在构建竞争产品或服务,或您的使用场景超出 FSL 范围时,才需要商业许可。",
"hero_note": "构建竞争产品或服务,或大规模部署(例如提供按量付费 API)需要商业许可。定价层级即将推出 — 在此期间请与我们联系。",
"why_title": "为什么企业选择 OmniVoice",
"pricing_title": "定价",
"faq_title": "常见问题",
@@ -963,7 +962,8 @@
"benefit_source": "源码可用",
"benefit_source_desc": "完全可见的技术栈。在许可条款内审计、分叉和适配。",
"benefit_lang": "646 种语言",
"benefit_lang_desc": "以人类级质量转录、翻译和配音 646 种语言。"
"benefit_lang_desc": "以人类级质量转录、翻译和配音 646 种语言。",
"hero_note": "根据 FSL,内部使用(即使是大规模使用)也是免费的;仅需要商业许可证才能将 OmniVoice 作为竞争产品或服务(托管或按使用付费的 API、转售或白标应用程序)提供给其他人。定价等级即将推出 - 请同时联系我们。"
},
"exportModal": {
"export": "导出",
@@ -1572,5 +1572,13 @@
"facet_accent": "口音",
"facet_lang": "语言",
"facet_whisper": "耳语"
},
"support": {
"tab_support": "支持",
"tab_license": "商业许可",
"toggle_label": "支持或商业许可",
"other_ways": "其他帮助方法",
"star_github": "在 GitHub 上加星标",
"join_discord": "加入不和谐"
}
}
+10 -2
View File
@@ -973,7 +973,6 @@
"badge": "商業許可",
"hero_title": "在生產中傳送人工智慧聲音",
"hero_desc": "OmniVoice Studio 可根據功能來源許可證 (FSL) 取得原始碼。大多數用戶可以在沒有商業協議的情況下進行評估、原型設計甚至內部部署。只有當您正在建立競爭產品或服務,或您的用例超出 FSL 範圍時,您才需要商業許可證。",
"hero_note": "建立競爭產品或服務或大規模部署(例如,提供按使用付費的 API)需要商業許可證。定價等級即將推出 - 請同時聯絡我們。",
"why_title": "為什麼企業選擇 OmniVoice",
"pricing_title": "定價",
"faq_title": "常見問題",
@@ -993,7 +992,8 @@
"benefit_source": "可用原始碼核心",
"benefit_source_desc": "對堆疊的完全可見性。在許可條款範圍內進行審核、分叉和調整。",
"benefit_lang": "646 種語言",
"benefit_lang_desc": "以人類層次的品質轉錄、翻譯和配音 646 種語言。"
"benefit_lang_desc": "以人類層次的品質轉錄、翻譯和配音 646 種語言。",
"hero_note": "根據 FSL,內部使用(即使是大規模使用)也是免費的;僅需要商業許可證才能將 OmniVoice 作為競爭產品或服務(託管或按使用付費的 API、轉售或白標應用程式)提供給其他人。定價等級即將推出 - 請同時聯絡我們。"
},
"exportModal": {
"export": "出口",
@@ -1572,5 +1572,13 @@
"facet_accent": "口音",
"facet_lang": "語言",
"facet_whisper": "耳語"
},
"support": {
"tab_support": "支援",
"tab_license": "商業許可",
"toggle_label": "支持或商業許可",
"other_ways": "其他幫助方法",
"star_github": "在 GitHub 上加星標",
"join_discord": "加入不和諧"
}
}
-125
View File
@@ -1,125 +0,0 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Heart, ExternalLink, ArrowLeft, Building2 } from 'lucide-react';
import { Button } from '../ui';
import { openExternal } from '../api/external';
import './DonatePage.css';
const METHODS = [
{
id: 'github',
label: 'GitHub Sponsors',
descriptionKey: 'donate.github_desc',
url: 'https://github.com/debpalash',
icon: '🐙',
},
{
id: 'kofi',
label: 'Ko-fi',
descriptionKey: 'donate.coffee_desc',
url: 'https://ko-fi.com/debpalash',
icon: '☕',
},
{
id: 'paypal',
label: 'PayPal',
descriptionKey: 'donate.paypal_desc',
url: 'https://paypal.me/palashCoder',
icon: '💳',
},
];
function LinkCard({ method, style }) {
const { t } = useTranslation();
return (
<button
type="button"
className="donate-card donate-card--link lp-glow-card"
style={style}
onClick={() => openExternal(method.url)}
>
<span className="donate-card__glow" aria-hidden="true" />
<div className="donate-card__icon">{method.icon}</div>
<div className="donate-card__body">
<div className="donate-card__label">{method.label}</div>
<div className="donate-card__desc">{t(method.descriptionKey)}</div>
</div>
<div className="donate-card__arrow">
<ExternalLink size={14} />
</div>
</button>
);
}
export default function DonatePage({ onBack, onEnterprise }) {
const { t } = useTranslation();
return (
<div className="donate-page">
{/* Aurora backdrop — same as Launchpad */}
<div className="lp-aurora" aria-hidden="true">
<span className="lp-aurora__blob lp-aurora__blob--pink" />
<span className="lp-aurora__blob lp-aurora__blob--green" />
<span className="lp-aurora__blob lp-aurora__blob--amber" />
</div>
{/* Top bar: Back (left) + Commercial License (right) */}
<div className="donate-page__topbar">
<Button
variant="subtle"
size="sm"
onClick={onBack}
leading={<ArrowLeft size={14} />}
>
{t('donate.back')}
</Button>
{onEnterprise && (
<Button
variant="subtle"
size="sm"
onClick={onEnterprise}
leading={<Building2 size={14} />}
trailing={<ExternalLink size={12} />}
>
{t('donate.commercial')}
</Button>
)}
</div>
<div className="donate-page__content">
{/* Hero */}
<div className="donate-hero">
<div className="donate-hero__icon-wrap">
<Heart size={24} className="donate-hero__heart" />
</div>
<h2 className="donate-hero__title">
{t('donate.hero_title')}
<span className="lp-hero__sweep" aria-hidden="true" />
</h2>
<p className="donate-hero__subtitle">
{t('donate.hero_desc')}
</p>
</div>
{/* Platforms */}
<section className="donate-section">
<div className="donate-section__title">
<span>{t('donate.platforms')}</span>
</div>
<div className="donate-grid donate-grid--links">
{METHODS.map((m, i) => (
<LinkCard
key={m.id}
method={m}
style={{ '--anim-i': i, '--card-hue': '#d3869b' }}
/>
))}
</div>
</section>
<div className="donate-footer">
{t('donate.footer')}
</div>
</div>
</div>
);
}
-147
View File
@@ -1,147 +0,0 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import {
ArrowLeft, Shield, Zap, Users, Headphones, Code, Globe,
Building2, Mail,
} from 'lucide-react';
import { Button } from '../ui';
import { openExternal } from '../api/external';
import './EnterprisePage.css';
export default function EnterprisePage({ onBack }) {
const { t } = useTranslation();
const WHY_ITEMS = [
{ icon: Shield, label: t('enterprise.benefit_ip'), desc: t('enterprise.benefit_ip_desc') },
{ icon: Zap, label: t('enterprise.benefit_cost'), desc: t('enterprise.benefit_cost_desc') },
{ icon: Users, label: t('enterprise.benefit_team'), desc: t('enterprise.benefit_team_desc') },
{ icon: Headphones, label: t('enterprise.benefit_support'), desc: t('enterprise.benefit_support_desc') },
{ icon: Code, label: t('enterprise.benefit_source'), desc: t('enterprise.benefit_source_desc') },
{ icon: Globe, label: t('enterprise.benefit_lang'), desc: t('enterprise.benefit_lang_desc') },
];
return (
<div className="enterprise-page">
{/* Aurora backdrop — same as Launchpad */}
<div className="lp-aurora" aria-hidden="true">
<span className="lp-aurora__blob lp-aurora__blob--pink" />
<span className="lp-aurora__blob lp-aurora__blob--green" />
<span className="lp-aurora__blob lp-aurora__blob--amber" />
</div>
<div className="enterprise-page__back">
<Button
variant="subtle"
size="sm"
onClick={onBack}
leading={<ArrowLeft size={14} />}
>
{t('enterprise.back')}
</Button>
</div>
<div className="enterprise-page__content">
{/* Hero */}
<div className="ent-hero">
<span className="ent-hero__kicker">{t('enterprise.badge')}</span>
<h2 className="ent-hero__title">
{t('enterprise.hero_title')}
<span className="lp-hero__sweep" aria-hidden="true" />
</h2>
<p className="ent-hero__subtitle">
{t('enterprise.hero_desc')}
</p>
<p className="ent-hero__subtitle">
{t('enterprise.hero_note')}
</p>
</div>
{/* Why Businesses Choose OmniVoice */}
<section className="ent-why">
<div className="ent-section-title">
<span>{t('enterprise.why_title')}</span>
</div>
<div className="ent-why__grid">
{WHY_ITEMS.map(({ icon: Icon, label, desc }) => (
<div key={label} className="ent-why__card">
<div className="ent-why__icon"><Icon size={16} /></div>
<div className="ent-why__label">{label}</div>
<div className="ent-why__desc">{desc}</div>
</div>
))}
</div>
</section>
{/* Pricing — coming soon */}
<section className="ent-tiers-section">
<div className="ent-section-title">
<span>{t('enterprise.pricing_title')}</span>
</div>
<div className="ent-coming-soon">
<p>
<strong>{t('enterprise.pricing_desc')}</strong>{' '}
{t('enterprise.pricing_detail')}
</p>
<button
type="button"
className="ent-coming-soon__cta"
onClick={() => openExternal('mailto:OmniVoice@palash.dev?subject=OmniVoice Commercial License Inquiry&body=Hi Palash,%0A%0AI%27d like to talk about a commercial license for OmniVoice Studio.%0A%0AOrganization:%0ATeam size:%0AUse case:%0A')}
>
<Mail size={13} />
{t('enterprise.request_quote')}
</button>
</div>
</section>
{/* FAQ */}
<section className="ent-faq">
<div className="ent-section-title">
<span>{t('enterprise.faq_title')}</span>
</div>
<div className="ent-faq__list">
<details className="ent-faq__item">
<summary>{t('enterprise_faq.q_internal_tools')}</summary>
<p>{t('enterprise_faq.a_internal_tools')}</p>
</details>
<details className="ent-faq__item">
<summary>{t('enterprise_faq.q_try_before')}</summary>
<p>{t('enterprise_faq.a_try_before')}</p>
</details>
<details className="ent-faq__item">
<summary>{t('enterprise_faq.q_watermark')}</summary>
<p>{t('enterprise_faq.a_watermark')}</p>
</details>
<details className="ent-faq__item">
<summary>{t('enterprise_faq.q_apache')}</summary>
<p>{t('enterprise_faq.a_apache')}</p>
</details>
</div>
</section>
{/* CTA footer */}
<div className="ent-cta-footer">
<p>
<button
type="button"
className="ent-cta-footer__link"
onClick={() => openExternal('mailto:OmniVoice@palash.dev')}
title="OmniVoice@palash.dev"
>
{t('enterprise.footer_email')}
</button>
</p>
<p className="ent-cta-footer__sub">
<button
type="button"
className="ent-cta-footer__link"
onClick={() => openExternal('https://discord.gg/bzQavDfVV9')}
title="discord.gg/bzQavDfVV9"
>
{t('enterprise.footer_discord')}
</button>
</p>
</div>
</div>
</div>
);
}
+159
View File
@@ -0,0 +1,159 @@
/* SupportPage unifies the donate + commercial-license panels behind one
segmented toggle. Reuses the donate/enterprise chrome (DonatePage.css,
EnterprisePage.css); this file only owns the toggle + panel transitions. */
/* Top bar: Back · toggle (centered) · spacer */
.support-page__topbar {
padding: 16px 44px 0;
position: relative;
z-index: 2;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
/* Mirrors the Back button's footprint so the toggle sits visually centered. */
.support-page__spacer { width: 96px; flex-shrink: 0; }
/* ── Segmented toggle ─────────────────────────────────────────────────── */
.support-toggle {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr;
padding: 3px;
border-radius: var(--chrome-radius-pill);
background: color-mix(in srgb, var(--chrome-fg) 5%, transparent);
border: 1px solid var(--chrome-border);
isolation: isolate;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.25);
}
/* The sliding active background. Carries the panel's accent hue so the toggle
itself signals which world you're in pink for Support, teal for License. */
.support-toggle__pill {
position: absolute;
top: 3px;
bottom: 3px;
left: 3px;
width: calc(50% - 3px);
border-radius: var(--chrome-radius-pill);
background: color-mix(in srgb, #d3869b 18%, transparent);
border: 1px solid color-mix(in srgb, #d3869b 38%, transparent);
box-shadow: 0 2px 14px -5px rgba(211, 134, 155, 0.55);
z-index: 0;
transition:
transform 0.36s cubic-bezier(0.16, 1, 0.3, 1),
background 0.36s ease,
border-color 0.36s ease,
box-shadow 0.36s ease;
}
.support-toggle__pill[data-view="license"] {
transform: translateX(100%);
background: color-mix(in srgb, #83a598 18%, transparent);
border-color: color-mix(in srgb, #83a598 40%, transparent);
box-shadow: 0 2px 14px -5px rgba(131, 165, 152, 0.55);
}
.support-toggle__opt {
position: relative;
z-index: 1;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 6px 18px;
border: none;
background: transparent;
font-family: var(--chrome-font-mono);
font-size: 0.72rem;
font-weight: 600;
letter-spacing: var(--chrome-label-track);
text-transform: uppercase;
white-space: nowrap;
color: var(--chrome-fg-muted);
cursor: pointer;
border-radius: var(--chrome-radius-pill);
transition: color 0.22s ease;
}
.support-toggle__opt svg { transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1); }
.support-toggle__opt.is-active { color: var(--chrome-fg); }
.support-toggle__opt.is-active svg { transform: scale(1.12); }
.support-toggle__opt:hover:not(.is-active) { color: var(--chrome-fg); }
.support-toggle__opt:focus-visible {
outline: 2px solid color-mix(in srgb, var(--chrome-accent) 60%, transparent);
outline-offset: 2px;
}
/* Panel cross-fade the content remounts on toggle (key={view}), which
replays the inner hero/card entry animations; this adds a soft lift over
the whole panel so the swap feels intentional, not jumpy. */
.support-view {
animation: supportViewIn 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes supportViewIn {
0% { opacity: 0; transform: translateY(10px); }
100% { opacity: 1; transform: translateY(0); }
}
/* Support panel layout
The Support panel is short, so center it vertically in the available space
instead of letting it cling to the top of an empty page. License is tall
enough to fill on its own, so it stays top-aligned and scrolls normally. */
.support-page__content--support {
flex: 1 1 auto;
justify-content: center;
}
/* Donation methods stack in a single clean column three full-width rows,
no orphaned card in a half-empty second row. */
.support-methods {
display: grid;
grid-template-columns: 1fr;
gap: 10px;
}
/* "Other ways to help" chips
Non-monetary support (star, Discord) as quiet ghost pills, centered. */
.support-chips {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
}
.support-chip {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
border: 1px solid var(--chrome-border);
border-radius: var(--chrome-radius-pill);
background: color-mix(in srgb, var(--chrome-fg) 4%, transparent);
color: var(--chrome-fg-muted);
font-family: var(--chrome-font-mono);
font-size: 0.72rem;
font-weight: 600;
letter-spacing: var(--chrome-label-track);
text-transform: uppercase;
cursor: pointer;
transition: color var(--dur-fast), border-color var(--dur-fast),
background var(--dur-fast), transform var(--dur-base);
}
.support-chip:hover {
color: var(--chrome-fg);
border-color: color-mix(in srgb, #d3869b 42%, transparent);
background: color-mix(in srgb, #d3869b 8%, transparent);
transform: translateY(-1px);
}
.support-chip svg { color: #d3869b; }
@media (max-width: 540px) {
.support-page__topbar { padding: 14px 18px 0; }
.support-page__spacer { display: none; }
.support-toggle__opt { padding: 6px 12px; }
}
@media (prefers-reduced-motion: reduce) {
.support-toggle__pill,
.support-toggle__opt svg { transition: none; }
.support-view { animation: none; }
}
+256
View File
@@ -0,0 +1,256 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
Heart, ExternalLink, ArrowLeft, Building2,
Shield, Zap, Users, Headphones, Code, Globe, Mail,
Star, MessageCircle,
} from 'lucide-react';
import { Button } from '../ui';
import { openExternal } from '../api/external';
import './DonatePage.css';
import './EnterprisePage.css';
import './SupportPage.css';
const METHODS = [
{ id: 'github', label: 'GitHub Sponsors', descriptionKey: 'donate.github_desc', url: 'https://github.com/debpalash', icon: '🐙' },
{ id: 'kofi', label: 'Ko-fi', descriptionKey: 'donate.coffee_desc', url: 'https://ko-fi.com/debpalash', icon: '☕' },
{ id: 'paypal', label: 'PayPal', descriptionKey: 'donate.paypal_desc', url: 'https://paypal.me/palashCoder', icon: '💳' },
];
function LinkCard({ method, style }) {
const { t } = useTranslation();
return (
<button
type="button"
className="donate-card donate-card--link lp-glow-card"
style={style}
onClick={() => openExternal(method.url)}
>
<span className="donate-card__glow" aria-hidden="true" />
<div className="donate-card__icon">{method.icon}</div>
<div className="donate-card__body">
<div className="donate-card__label">{method.label}</div>
<div className="donate-card__desc">{t(method.descriptionKey)}</div>
</div>
<div className="donate-card__arrow">
<ExternalLink size={14} />
</div>
</button>
);
}
/* ── Support (donate) panel ───────────────────────────────────────────── */
function SupportView() {
const { t } = useTranslation();
return (
<div className="support-view">
<div className="donate-hero">
<div className="donate-hero__icon-wrap">
<Heart size={24} className="donate-hero__heart" />
</div>
<h2 className="donate-hero__title">
{t('donate.hero_title')}
<span className="lp-hero__sweep" aria-hidden="true" />
</h2>
<p className="donate-hero__subtitle">{t('donate.hero_desc')}</p>
</div>
<section className="donate-section">
<div className="donate-section__title"><span>{t('donate.platforms')}</span></div>
<div className="donate-grid support-methods">
{METHODS.map((m, i) => (
<LinkCard key={m.id} method={m} style={{ '--anim-i': i, '--card-hue': '#d3869b' }} />
))}
</div>
</section>
{/* Non-monetary ways to help gives people who can't (or don't want to)
donate a real way to support, and balances out the panel. */}
<section className="donate-section">
<div className="donate-section__title"><span>{t('support.other_ways')}</span></div>
<div className="support-chips">
<button
type="button"
className="support-chip"
onClick={() => openExternal('https://github.com/debpalash/OmniVoice-Studio')}
>
<Star size={14} /> {t('support.star_github')}
</button>
<button
type="button"
className="support-chip"
onClick={() => openExternal('https://discord.gg/bzQavDfVV9')}
>
<MessageCircle size={14} /> {t('support.join_discord')}
</button>
</div>
</section>
<div className="donate-footer">{t('donate.footer')}</div>
</div>
);
}
/* ── Commercial License panel ─────────────────────────────────────────── */
function LicenseView() {
const { t } = useTranslation();
const WHY_ITEMS = [
{ icon: Shield, label: t('enterprise.benefit_ip'), desc: t('enterprise.benefit_ip_desc') },
{ icon: Zap, label: t('enterprise.benefit_cost'), desc: t('enterprise.benefit_cost_desc') },
{ icon: Users, label: t('enterprise.benefit_team'), desc: t('enterprise.benefit_team_desc') },
{ icon: Headphones, label: t('enterprise.benefit_support'), desc: t('enterprise.benefit_support_desc') },
{ icon: Code, label: t('enterprise.benefit_source'), desc: t('enterprise.benefit_source_desc') },
{ icon: Globe, label: t('enterprise.benefit_lang'), desc: t('enterprise.benefit_lang_desc') },
];
return (
<div className="support-view">
<div className="ent-hero">
<span className="ent-hero__kicker">{t('enterprise.badge')}</span>
<h2 className="ent-hero__title">
{t('enterprise.hero_title')}
<span className="lp-hero__sweep" aria-hidden="true" />
</h2>
<p className="ent-hero__subtitle">{t('enterprise.hero_desc')}</p>
<p className="ent-hero__subtitle">{t('enterprise.hero_note')}</p>
</div>
<section className="ent-why">
<div className="ent-section-title"><span>{t('enterprise.why_title')}</span></div>
<div className="ent-why__grid">
{WHY_ITEMS.map(({ icon: Icon, label, desc }) => (
<div key={label} className="ent-why__card">
<div className="ent-why__icon"><Icon size={16} /></div>
<div className="ent-why__label">{label}</div>
<div className="ent-why__desc">{desc}</div>
</div>
))}
</div>
</section>
<section className="ent-tiers-section">
<div className="ent-section-title"><span>{t('enterprise.pricing_title')}</span></div>
<div className="ent-coming-soon">
<p>
<strong>{t('enterprise.pricing_desc')}</strong>{' '}
{t('enterprise.pricing_detail')}
</p>
<button
type="button"
className="ent-coming-soon__cta"
onClick={() => openExternal('mailto:OmniVoice@palash.dev?subject=OmniVoice Commercial License Inquiry&body=Hi Palash,%0A%0AI%27d like to talk about a commercial license for OmniVoice Studio.%0A%0AOrganization:%0ATeam size:%0AUse case:%0A')}
>
<Mail size={13} />
{t('enterprise.request_quote')}
</button>
</div>
</section>
<section className="ent-faq">
<div className="ent-section-title"><span>{t('enterprise.faq_title')}</span></div>
<div className="ent-faq__list">
<details className="ent-faq__item">
<summary>{t('enterprise_faq.q_internal_tools')}</summary>
<p>{t('enterprise_faq.a_internal_tools')}</p>
</details>
<details className="ent-faq__item">
<summary>{t('enterprise_faq.q_try_before')}</summary>
<p>{t('enterprise_faq.a_try_before')}</p>
</details>
<details className="ent-faq__item">
<summary>{t('enterprise_faq.q_watermark')}</summary>
<p>{t('enterprise_faq.a_watermark')}</p>
</details>
<details className="ent-faq__item">
<summary>{t('enterprise_faq.q_apache')}</summary>
<p>{t('enterprise_faq.a_apache')}</p>
</details>
</div>
</section>
<div className="ent-cta-footer">
<p>
<button
type="button"
className="ent-cta-footer__link"
onClick={() => openExternal('mailto:OmniVoice@palash.dev')}
title="OmniVoice@palash.dev"
>
{t('enterprise.footer_email')}
</button>
</p>
<p className="ent-cta-footer__sub">
<button
type="button"
className="ent-cta-footer__link"
onClick={() => openExternal('https://discord.gg/bzQavDfVV9')}
title="discord.gg/bzQavDfVV9"
>
{t('enterprise.footer_discord')}
</button>
</p>
</div>
</div>
);
}
/**
* SupportPage unifies the donate ("Support") and commercial-license panels
* behind a single charming segmented toggle. Both legacy modes ('donate',
* 'enterprise') route here with the matching initialView, so every existing
* entry point (footer heart, dub/export "commercial license" links) still
* works they just land on the right tab.
*/
export default function SupportPage({ onBack, initialView = 'support' }) {
const { t } = useTranslation();
const [view, setView] = useState(initialView === 'license' ? 'license' : 'support');
return (
<div className="support-page donate-page">
{/* Aurora backdrop — shared with the Launchpad */}
<div className="lp-aurora" aria-hidden="true">
<span className="lp-aurora__blob lp-aurora__blob--pink" />
<span className="lp-aurora__blob lp-aurora__blob--green" />
<span className="lp-aurora__blob lp-aurora__blob--amber" />
</div>
{/* Top bar: Back (left) · toggle (center) · spacer (right, balances Back) */}
<div className="support-page__topbar">
<Button variant="subtle" size="sm" onClick={onBack} leading={<ArrowLeft size={14} />}>
{t('donate.back')}
</Button>
<div className="support-toggle" role="tablist" aria-label={t('support.toggle_label')}>
<span className="support-toggle__pill" data-view={view} aria-hidden="true" />
<button
type="button"
role="tab"
aria-selected={view === 'support'}
className={`support-toggle__opt ${view === 'support' ? 'is-active' : ''}`}
onClick={() => setView('support')}
>
<Heart size={13} /> {t('support.tab_support')}
</button>
<button
type="button"
role="tab"
aria-selected={view === 'license'}
className={`support-toggle__opt ${view === 'license' ? 'is-active' : ''}`}
onClick={() => setView('license')}
>
<Building2 size={13} /> {t('support.tab_license')}
</button>
</div>
<span className="support-page__spacer" aria-hidden="true" />
</div>
{/* key={view} remounts the panel so its entry animations replay on toggle.
The --support modifier vertically centers the (short) Support panel so
it doesn't float at the top of an empty page; License stays top-aligned
since it's tall enough to fill on its own. */}
<div className={`support-page__content donate-page__content support-page__content--${view}`} key={view}>
{view === 'support' ? <SupportView /> : <LicenseView />}
</div>
</div>
);
}