diff --git a/apps/chat/apps/landing/src/components/Footer.astro b/apps/chat/apps/landing/src/components/Footer.astro index 2ec6b09b6..2db077b3f 100644 --- a/apps/chat/apps/landing/src/components/Footer.astro +++ b/apps/chat/apps/landing/src/components/Footer.astro @@ -8,6 +8,7 @@ const footerLinks = { legal: [ { href: '/privacy', label: 'Datenschutz' }, { href: '/terms', label: 'AGB' }, + { href: '/cookies', label: 'Cookies' }, { href: '/imprint', label: 'Impressum' }, ], }; diff --git a/apps/chat/apps/landing/src/pages/cookies.astro b/apps/chat/apps/landing/src/pages/cookies.astro new file mode 100644 index 000000000..9252e5f57 --- /dev/null +++ b/apps/chat/apps/landing/src/pages/cookies.astro @@ -0,0 +1,67 @@ +--- +import Layout from '../layouts/Layout.astro'; +import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; +--- + + + +

1. Was sind Cookies?

+

+ Cookies sind kleine Textdateien, die auf Ihrem Gerät gespeichert werden. Sie helfen uns, die + Funktionalität unserer Website zu verbessern und Ihre Nutzererfahrung zu personalisieren. +

+ +

2. Welche Cookies verwenden wir?

+ +

Notwendige Cookies

+

Diese Cookies sind für den Betrieb der Website unerlässlich:

+ + +

Funktionale Cookies

+

Diese Cookies verbessern Ihre Nutzererfahrung:

+ + +

Analyse-Cookies

+

Wir verwenden Umami Analytics, eine datenschutzfreundliche Alternative:

+ + +

3. Cookies von Drittanbietern

+

+ Wir verwenden keine Tracking-Cookies von Drittanbietern wie Google Analytics oder Facebook. +

+ +

4. Ihre Cookie-Einstellungen

+

Sie können Cookies in Ihren Browser-Einstellungen verwalten:

+ + +

5. Auswirkungen der Cookie-Deaktivierung

+

+ Wenn Sie notwendige Cookies deaktivieren, funktionieren einige Funktionen der App + möglicherweise nicht mehr korrekt, z.B. das automatische Einloggen oder die Speicherung Ihrer + Chat-Einstellungen. +

+ +

6. Kontakt

+

Bei Fragen zu unserer Cookie-Richtlinie kontaktieren Sie uns unter: privacy@mana.how

+
+
diff --git a/apps/chat/apps/landing/src/pages/imprint.astro b/apps/chat/apps/landing/src/pages/imprint.astro new file mode 100644 index 000000000..613b64185 --- /dev/null +++ b/apps/chat/apps/landing/src/pages/imprint.astro @@ -0,0 +1,90 @@ +--- +import Layout from '../layouts/Layout.astro'; +import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; +--- + + + +

Angaben gemäß § 5 TMG

+

+ Mana Technologies
+ Musterstraße 1
+ 12345 Musterstadt
+ Deutschland +

+ +

Kontakt

+

+ E-Mail: contact@mana.how
+ Telefon: +49 (0) 123 456789 +

+ +

Vertreten durch

+

Geschäftsführer: Max Mustermann

+ +

Handelsregister

+

+ Registergericht: Amtsgericht Musterstadt
+ Registernummer: HRB 12345 +

+ +

Umsatzsteuer-ID

+

+ Umsatzsteuer-Identifikationsnummer gemäß § 27a Umsatzsteuergesetz:
+ DE123456789 +

+ +

Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV

+

+ Max Mustermann
+ Musterstraße 1
+ 12345 Musterstadt +

+ +

Streitschlichtung

+

+ Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: + https://ec.europa.eu/consumers/odr +

+

+ Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer + Verbraucherschlichtungsstelle teilzunehmen. +

+ +

Haftungsausschluss

+ +

Haftung für Inhalte

+

+ Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den + allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch + nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen. +

+ +

Haftung für KI-generierte Inhalte

+

+ Die von der KI generierten Antworten sind keine rechtsverbindlichen Aussagen. Die Nutzung + erfolgt auf eigene Verantwortung. +

+ +

Haftung für Links

+

+ Unser Angebot enthält Links zu externen Websites Dritter, auf deren Inhalte wir keinen + Einfluss haben. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter + verantwortlich. +

+ +

Urheberrecht

+

+ Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem + deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der + Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung. +

+
+
diff --git a/apps/chat/apps/landing/src/pages/privacy.astro b/apps/chat/apps/landing/src/pages/privacy.astro new file mode 100644 index 000000000..d666f0fb2 --- /dev/null +++ b/apps/chat/apps/landing/src/pages/privacy.astro @@ -0,0 +1,72 @@ +--- +import Layout from '../layouts/Layout.astro'; +import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; +--- + + + +

1. Einleitung

+

+ Diese Datenschutzerklärung informiert Sie über die Art, den Umfang und den Zweck der + Verarbeitung personenbezogener Daten innerhalb unserer ManaChat-Anwendung. +

+ +

2. Verantwortlicher

+

+ Verantwortlich für die Datenverarbeitung ist:
+ Mana Technologies
+ Musterstraße 1
+ 12345 Musterstadt
+ Deutschland
+ E-Mail: privacy@mana.how +

+ +

3. Erhobene Daten

+

Wir erheben folgende Daten:

+ + +

4. Zweck der Datenverarbeitung

+

Ihre Daten werden verwendet für:

+ + +

5. KI-Datenverarbeitung

+

+ Ihre Chat-Nachrichten werden an KI-Dienste (OpenRouter) zur Verarbeitung übermittelt. Diese + Dienste nutzen Ihre Daten nicht für das Training ihrer Modelle. +

+ +

6. Datenspeicherung

+

+ Ihre Daten werden auf sicheren Servern in der Europäischen Union gespeichert. Wir verwenden + Verschlüsselung für alle übertragenen und gespeicherten Daten. +

+ +

7. Ihre Rechte

+

Sie haben folgende Rechte:

+ + +

8. Kontakt

+

Bei Fragen zum Datenschutz kontaktieren Sie uns unter: privacy@mana.how

+
+
diff --git a/apps/chat/apps/landing/src/pages/terms.astro b/apps/chat/apps/landing/src/pages/terms.astro new file mode 100644 index 000000000..dd9d49e1a --- /dev/null +++ b/apps/chat/apps/landing/src/pages/terms.astro @@ -0,0 +1,84 @@ +--- +import Layout from '../layouts/Layout.astro'; +import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; +--- + + + +

1. Geltungsbereich

+

+ Diese Nutzungsbedingungen gelten für die Nutzung der ManaChat-Anwendung, einschließlich der + mobilen Apps, der Web-Version und aller zugehörigen Dienste. +

+ +

2. Leistungsbeschreibung

+

ManaChat bietet:

+ + +

3. Registrierung

+

+ Zur Nutzung ist eine Registrierung erforderlich. Sie sind für die Geheimhaltung Ihrer + Zugangsdaten verantwortlich. +

+ +

4. Kostenfreie und kostenpflichtige Funktionen

+

ManaChat bietet sowohl kostenfreie als auch Premium-Funktionen:

+ + +

5. Nutzerverhalten

+

Sie verpflichten sich:

+ + +

6. KI-generierte Inhalte

+

+ KI-generierte Antworten können fehlerhaft sein. Sie sind für die Überprüfung und Nutzung der + generierten Inhalte selbst verantwortlich. +

+ +

7. Verfügbarkeit

+

+ Wir bemühen uns um eine hohe Verfügbarkeit. Die Verfügbarkeit kann jedoch von Drittanbietern + (KI-Dienste) abhängen und ist nicht garantiert. +

+ +

8. Kündigung

+

+ Sie können Ihr Konto jederzeit kündigen. Bei Premium-Abonnements gilt die Kündigung zum Ende + des Abrechnungszeitraums. +

+ +

9. Haftung

+

+ Die Haftung für KI-generierte Inhalte ist ausgeschlossen. Wir haften nur für Vorsatz und grobe + Fahrlässigkeit. +

+ +

10. Änderungen

+

+ Wir behalten uns vor, diese Nutzungsbedingungen zu ändern. Wesentliche Änderungen werden Ihnen + rechtzeitig mitgeteilt. +

+ +

11. Anwendbares Recht

+

Es gilt deutsches Recht. Gerichtsstand ist, soweit zulässig, der Sitz des Anbieters.

+
+
diff --git a/apps/manadeck/apps/landing/src/components/Footer.astro b/apps/manadeck/apps/landing/src/components/Footer.astro index 9ca90ce50..7c3bf65c9 100644 --- a/apps/manadeck/apps/landing/src/components/Footer.astro +++ b/apps/manadeck/apps/landing/src/components/Footer.astro @@ -8,6 +8,7 @@ const footerLinks = { legal: [ { href: '/privacy', label: 'Datenschutz' }, { href: '/terms', label: 'AGB' }, + { href: '/cookies', label: 'Cookies' }, { href: '/imprint', label: 'Impressum' }, ], }; diff --git a/apps/manadeck/apps/landing/src/pages/cookies.astro b/apps/manadeck/apps/landing/src/pages/cookies.astro new file mode 100644 index 000000000..d3c770acd --- /dev/null +++ b/apps/manadeck/apps/landing/src/pages/cookies.astro @@ -0,0 +1,67 @@ +--- +import Layout from '../layouts/Layout.astro'; +import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; +--- + + + +

1. Was sind Cookies?

+

+ Cookies sind kleine Textdateien, die auf Ihrem Gerät gespeichert werden. Sie helfen uns, die + Funktionalität unserer Website zu verbessern und Ihre Nutzererfahrung zu personalisieren. +

+ +

2. Welche Cookies verwenden wir?

+ +

Notwendige Cookies

+

Diese Cookies sind für den Betrieb der Website unerlässlich:

+ + +

Funktionale Cookies

+

Diese Cookies verbessern Ihre Nutzererfahrung:

+ + +

Analyse-Cookies

+

+ Wir verwenden Umami Analytics, eine datenschutzfreundliche Alternative zu Google Analytics: +

+ + +

3. Cookies von Drittanbietern

+

+ Wir verwenden keine Tracking-Cookies von Drittanbietern wie Google Analytics oder Facebook. +

+ +

4. Ihre Cookie-Einstellungen

+

Sie können Cookies in Ihren Browser-Einstellungen verwalten:

+ + +

5. Auswirkungen der Cookie-Deaktivierung

+

+ Wenn Sie notwendige Cookies deaktivieren, funktionieren einige Funktionen der App + möglicherweise nicht mehr korrekt, z.B. das automatische Einloggen. +

+ +

6. Kontakt

+

Bei Fragen zu unserer Cookie-Richtlinie kontaktieren Sie uns unter: privacy@mana.how

+
+
diff --git a/apps/manadeck/apps/landing/src/pages/imprint.astro b/apps/manadeck/apps/landing/src/pages/imprint.astro new file mode 100644 index 000000000..ebc58a3a1 --- /dev/null +++ b/apps/manadeck/apps/landing/src/pages/imprint.astro @@ -0,0 +1,84 @@ +--- +import Layout from '../layouts/Layout.astro'; +import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; +--- + + + +

Angaben gemäß § 5 TMG

+

+ Mana Technologies
+ Musterstraße 1
+ 12345 Musterstadt
+ Deutschland +

+ +

Kontakt

+

+ E-Mail: contact@mana.how
+ Telefon: +49 (0) 123 456789 +

+ +

Vertreten durch

+

Geschäftsführer: Max Mustermann

+ +

Handelsregister

+

+ Registergericht: Amtsgericht Musterstadt
+ Registernummer: HRB 12345 +

+ +

Umsatzsteuer-ID

+

+ Umsatzsteuer-Identifikationsnummer gemäß § 27a Umsatzsteuergesetz:
+ DE123456789 +

+ +

Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV

+

+ Max Mustermann
+ Musterstraße 1
+ 12345 Musterstadt +

+ +

Streitschlichtung

+

+ Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: + https://ec.europa.eu/consumers/odr +

+

+ Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer + Verbraucherschlichtungsstelle teilzunehmen. +

+ +

Haftungsausschluss

+ +

Haftung für Inhalte

+

+ Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den + allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch + nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen. +

+ +

Haftung für Links

+

+ Unser Angebot enthält Links zu externen Websites Dritter, auf deren Inhalte wir keinen + Einfluss haben. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter + verantwortlich. +

+ +

Urheberrecht

+

+ Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem + deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der + Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung. +

+
+
diff --git a/apps/manadeck/apps/landing/src/pages/privacy.astro b/apps/manadeck/apps/landing/src/pages/privacy.astro new file mode 100644 index 000000000..1eb04346e --- /dev/null +++ b/apps/manadeck/apps/landing/src/pages/privacy.astro @@ -0,0 +1,72 @@ +--- +import Layout from '../layouts/Layout.astro'; +import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; +--- + + + +

1. Einleitung

+

+ Diese Datenschutzerklärung informiert Sie über die Art, den Umfang und den Zweck der + Verarbeitung personenbezogener Daten innerhalb unserer ManaDeck-Anwendung. +

+ +

2. Verantwortlicher

+

+ Verantwortlich für die Datenverarbeitung ist:
+ Mana Technologies
+ Musterstraße 1
+ 12345 Musterstadt
+ Deutschland
+ E-Mail: privacy@mana.how +

+ +

3. Erhobene Daten

+

Wir erheben folgende Daten:

+ + +

4. Zweck der Datenverarbeitung

+

Ihre Daten werden verwendet für:

+ + +

5. Datenspeicherung

+

+ Ihre Daten werden auf sicheren Servern in der Europäischen Union gespeichert. Wir verwenden + Verschlüsselung für alle übertragenen und gespeicherten Daten. +

+ +

6. Ihre Rechte

+

Sie haben folgende Rechte:

+ + +

7. KI-Datenverarbeitung

+

+ Bei der KI-gestützten Karteikarten-Generierung werden Ihre Texte an KI-Dienste übermittelt. + Diese Daten werden nur zur Verarbeitung verwendet und nicht dauerhaft gespeichert. +

+ +

8. Kontakt

+

Bei Fragen zum Datenschutz kontaktieren Sie uns unter: privacy@mana.how

+
+
diff --git a/apps/manadeck/apps/landing/src/pages/terms.astro b/apps/manadeck/apps/landing/src/pages/terms.astro new file mode 100644 index 000000000..a063ffd22 --- /dev/null +++ b/apps/manadeck/apps/landing/src/pages/terms.astro @@ -0,0 +1,83 @@ +--- +import Layout from '../layouts/Layout.astro'; +import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; +--- + + + +

1. Geltungsbereich

+

+ Diese Nutzungsbedingungen gelten für die Nutzung der ManaDeck-Anwendung, einschließlich der + mobilen Apps und der Web-Version. +

+ +

2. Leistungsbeschreibung

+

ManaDeck bietet:

+ + +

3. Registrierung

+

+ Zur Nutzung ist eine Registrierung erforderlich. Sie sind für die Geheimhaltung Ihrer + Zugangsdaten verantwortlich. +

+ +

4. Kostenfreie und kostenpflichtige Funktionen

+

ManaDeck bietet sowohl kostenfreie als auch Premium-Funktionen:

+ + +

5. Nutzerverhalten

+

Sie verpflichten sich:

+ + +

6. Geistiges Eigentum

+

+ Die von Ihnen erstellten oder generierten Karteikarten gehören Ihnen. ManaDeck behält die + Rechte an der Software und dem Design. +

+ +

7. Verfügbarkeit

+

+ Wir bemühen uns um eine hohe Verfügbarkeit, können jedoch keine 100%ige Verfügbarkeit + garantieren. Wartungsarbeiten werden nach Möglichkeit vorab angekündigt. +

+ +

8. Kündigung

+

+ Sie können Ihr Konto jederzeit kündigen. Bei Premium-Abonnements gilt die Kündigung zum Ende + des Abrechnungszeitraums. +

+ +

9. Haftung

+

+ Die Haftung ist auf Vorsatz und grobe Fahrlässigkeit beschränkt. Dies gilt nicht für Schäden + aus der Verletzung von Leben, Körper oder Gesundheit. +

+ +

10. Änderungen

+

+ Wir behalten uns vor, diese Nutzungsbedingungen zu ändern. Wesentliche Änderungen werden Ihnen + rechtzeitig mitgeteilt. +

+ +

11. Anwendbares Recht

+

Es gilt deutsches Recht. Gerichtsstand ist, soweit zulässig, der Sitz des Anbieters.

+
+
diff --git a/packages/shared-landing-ui/package.json b/packages/shared-landing-ui/package.json index d991e195d..57a804564 100644 --- a/packages/shared-landing-ui/package.json +++ b/packages/shared-landing-ui/package.json @@ -9,12 +9,17 @@ "./atoms/*": "./src/atoms/*", "./sections/*": "./src/sections/*", "./layouts/*": "./src/layouts/*", + "./templates/*": "./src/templates/*", "./utils": "./src/utils/index.ts", + "./i18n": "./src/i18n/index.ts", "./themes": "./src/themes/index.css", "./themes/memoro": "./src/themes/memoro.css", "./themes/manacore": "./src/themes/manacore.css", "./themes/maerchenzauber": "./src/themes/maerchenzauber.css", - "./themes/manadeck": "./src/themes/manadeck.css" + "./themes/manadeck": "./src/themes/manadeck.css", + "./themes/picture": "./src/themes/picture.css", + "./themes/chat": "./src/themes/chat.css", + "./themes/zitare": "./src/themes/zitare.css" }, "files": [ "src" diff --git a/packages/shared-landing-ui/src/atoms/GradientText.astro b/packages/shared-landing-ui/src/atoms/GradientText.astro new file mode 100644 index 000000000..f9370a516 --- /dev/null +++ b/packages/shared-landing-ui/src/atoms/GradientText.astro @@ -0,0 +1,82 @@ +--- +/** + * GradientText - Text with gradient color effect + * + * Usage: + * ```astro + * Highlighted Text + * Custom Gradient + * ``` + */ + +interface Props { + as?: 'span' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'div'; + gradient?: 'primary' | 'secondary' | 'accent' | 'rainbow'; + class?: string; +} + +const { as: Element = 'span', gradient = 'primary', class: className = '' } = Astro.props; +--- + + + + + + diff --git a/packages/shared-landing-ui/src/atoms/LanguageSwitcher.astro b/packages/shared-landing-ui/src/atoms/LanguageSwitcher.astro new file mode 100644 index 000000000..058ce2f39 --- /dev/null +++ b/packages/shared-landing-ui/src/atoms/LanguageSwitcher.astro @@ -0,0 +1,178 @@ +--- +/** + * LanguageSwitcher - Dropdown for language selection + * + * Usage: + * ```astro + * `/${lang}${currentPath}`} + * /> + * ``` + */ + +export interface LanguageOption { + code: string; + label: string; +} + +interface Props { + currentLang: string; + languages: Record; + getLocalizedPath?: (lang: string) => string; + class?: string; +} + +const { + currentLang, + languages, + getLocalizedPath = (lang) => `/${lang}`, + class: className = '', +} = Astro.props; + +const languageEntries = Object.entries(languages); +--- + +
+ + + +
+ + + + diff --git a/packages/shared-landing-ui/src/i18n/index.ts b/packages/shared-landing-ui/src/i18n/index.ts new file mode 100644 index 000000000..b4358cdde --- /dev/null +++ b/packages/shared-landing-ui/src/i18n/index.ts @@ -0,0 +1,175 @@ +/** + * Shared i18n utilities for landing pages + */ + +export * from './types'; + +import { + type Language, + type CommonTranslations, + type Translations, + languages, + defaultLang, + defaultCommonTranslations, +} from './types'; + +/** + * Get the language from a URL pathname + * Supports both /en/page and /page patterns + */ +export function getLangFromUrl(url: URL): Language { + const [, lang] = url.pathname.split('/'); + if (lang && lang in languages) { + return lang as Language; + } + return defaultLang; +} + +/** + * Get the route without the language prefix + */ +export function getRouteFromUrl(url: URL): string { + const pathname = url.pathname; + const [, lang, ...rest] = pathname.split('/'); + + if (lang && lang in languages) { + return '/' + rest.join('/') || '/'; + } + return pathname; +} + +/** + * Create a localized path + */ +export function localizePath(path: string, lang: Language): string { + // If the language is the default language, don't add a prefix + if (lang === defaultLang) { + return path; + } + // Ensure path starts with / + const normalizedPath = path.startsWith('/') ? path : `/${path}`; + return `/${lang}${normalizedPath}`; +} + +/** + * Create a translation function for a specific language + */ +export function useTranslations( + lang: Language, + translations: Translations +): (key: keyof T | string) => string { + return function t(key: keyof T | string): string { + const langTranslations = translations[lang]; + if (langTranslations && key in langTranslations) { + return langTranslations[key as keyof T] as string; + } + // Fallback to default language + const defaultTranslations = translations[defaultLang]; + if (defaultTranslations && key in defaultTranslations) { + return defaultTranslations[key as keyof T] as string; + } + // Return the key as fallback + return String(key); + }; +} + +/** + * Create a translation function with merged common translations + */ +export function createTranslations( + lang: Language, + appTranslations: Translations +): (key: keyof T | string) => string { + // Merge app translations with common translations + const mergedTranslations = {} as Translations; + + for (const l of Object.keys(languages) as Language[]) { + mergedTranslations[l] = { + ...defaultCommonTranslations[l], + ...appTranslations[l], + } as T; + } + + return useTranslations(lang, mergedTranslations); +} + +/** + * Get alternate language links for SEO (hreflang) + */ +export function getAlternateLinks(url: URL): Array<{ lang: Language; href: string }> { + const route = getRouteFromUrl(url); + const baseUrl = `${url.protocol}//${url.host}`; + + return (Object.keys(languages) as Language[]).map((lang) => ({ + lang, + href: `${baseUrl}${localizePath(route, lang)}`, + })); +} + +/** + * Detect browser language preference + */ +export function getBrowserLang(): Language { + if (typeof navigator === 'undefined') { + return defaultLang; + } + + const browserLang = navigator.language.split('-')[0]; + if (browserLang in languages) { + return browserLang as Language; + } + + return defaultLang; +} + +/** + * Format a date according to the locale + */ +export function formatDate(date: Date, lang: Language): string { + const localeMap: Record = { + de: 'de-DE', + en: 'en-US', + fr: 'fr-FR', + it: 'it-IT', + es: 'es-ES', + }; + + return date.toLocaleDateString(localeMap[lang], { + year: 'numeric', + month: 'long', + day: 'numeric', + }); +} + +/** + * Format a number according to the locale + */ +export function formatNumber(num: number, lang: Language): string { + const localeMap: Record = { + de: 'de-DE', + en: 'en-US', + fr: 'fr-FR', + it: 'it-IT', + es: 'es-ES', + }; + + return num.toLocaleString(localeMap[lang]); +} + +/** + * Format currency according to the locale + */ +export function formatCurrency(amount: number, lang: Language, currency = 'EUR'): string { + const localeMap: Record = { + de: 'de-DE', + en: 'en-US', + fr: 'fr-FR', + it: 'it-IT', + es: 'es-ES', + }; + + return new Intl.NumberFormat(localeMap[lang], { + style: 'currency', + currency, + }).format(amount); +} diff --git a/packages/shared-landing-ui/src/i18n/types.ts b/packages/shared-landing-ui/src/i18n/types.ts new file mode 100644 index 000000000..7770634fe --- /dev/null +++ b/packages/shared-landing-ui/src/i18n/types.ts @@ -0,0 +1,241 @@ +/** + * Shared i18n types for landing pages + */ + +export type Language = 'de' | 'en' | 'fr' | 'it' | 'es'; + +export const languages: Record = { + de: 'Deutsch', + en: 'English', + fr: 'Français', + it: 'Italiano', + es: 'Español', +}; + +export const defaultLang: Language = 'de'; + +/** + * Common translations interface that all apps should implement + * Apps can extend this with their own specific translations + */ +export interface CommonTranslations { + // Navigation + 'nav.home'?: string; + 'nav.features'?: string; + 'nav.pricing'?: string; + 'nav.about'?: string; + 'nav.contact'?: string; + 'nav.login'?: string; + 'nav.signup'?: string; + + // Buttons + 'button.getStarted'?: string; + 'button.learnMore'?: string; + 'button.tryFree'?: string; + 'button.signUp'?: string; + 'button.login'?: string; + 'button.back'?: string; + 'button.submit'?: string; + 'button.cancel'?: string; + + // Legal + 'legal.privacy'?: string; + 'legal.terms'?: string; + 'legal.cookies'?: string; + 'legal.imprint'?: string; + 'legal.backHome'?: string; + 'legal.lastUpdated'?: string; + + // Footer + 'footer.product'?: string; + 'footer.company'?: string; + 'footer.resources'?: string; + 'footer.legal'?: string; + 'footer.copyright'?: string; + + // Common + 'common.loading'?: string; + 'common.error'?: string; + 'common.success'?: string; + 'common.new'?: string; + 'common.comingSoon'?: string; + + // Allow any other string keys + [key: string]: string | undefined; +} + +/** + * Type for a translations object mapping languages to translations + */ +export type Translations = Record; + +/** + * Default common translations in all supported languages + */ +export const defaultCommonTranslations: Translations = { + de: { + 'nav.home': 'Startseite', + 'nav.features': 'Funktionen', + 'nav.pricing': 'Preise', + 'nav.about': 'Über uns', + 'nav.contact': 'Kontakt', + 'nav.login': 'Anmelden', + 'nav.signup': 'Registrieren', + 'button.getStarted': 'Jetzt starten', + 'button.learnMore': 'Mehr erfahren', + 'button.tryFree': 'Kostenlos testen', + 'button.signUp': 'Registrieren', + 'button.login': 'Anmelden', + 'button.back': 'Zurück', + 'button.submit': 'Absenden', + 'button.cancel': 'Abbrechen', + 'legal.privacy': 'Datenschutz', + 'legal.terms': 'AGB', + 'legal.cookies': 'Cookies', + 'legal.imprint': 'Impressum', + 'legal.backHome': 'Zurück zur Startseite', + 'legal.lastUpdated': 'Zuletzt aktualisiert', + 'footer.product': 'Produkt', + 'footer.company': 'Unternehmen', + 'footer.resources': 'Ressourcen', + 'footer.legal': 'Rechtliches', + 'footer.copyright': 'Alle Rechte vorbehalten.', + 'common.loading': 'Laden...', + 'common.error': 'Fehler', + 'common.success': 'Erfolg', + 'common.new': 'Neu', + 'common.comingSoon': 'Demnächst', + }, + en: { + 'nav.home': 'Home', + 'nav.features': 'Features', + 'nav.pricing': 'Pricing', + 'nav.about': 'About', + 'nav.contact': 'Contact', + 'nav.login': 'Login', + 'nav.signup': 'Sign Up', + 'button.getStarted': 'Get Started', + 'button.learnMore': 'Learn More', + 'button.tryFree': 'Try for Free', + 'button.signUp': 'Sign Up', + 'button.login': 'Login', + 'button.back': 'Back', + 'button.submit': 'Submit', + 'button.cancel': 'Cancel', + 'legal.privacy': 'Privacy Policy', + 'legal.terms': 'Terms of Service', + 'legal.cookies': 'Cookie Policy', + 'legal.imprint': 'Imprint', + 'legal.backHome': 'Back to Home', + 'legal.lastUpdated': 'Last Updated', + 'footer.product': 'Product', + 'footer.company': 'Company', + 'footer.resources': 'Resources', + 'footer.legal': 'Legal', + 'footer.copyright': 'All rights reserved.', + 'common.loading': 'Loading...', + 'common.error': 'Error', + 'common.success': 'Success', + 'common.new': 'New', + 'common.comingSoon': 'Coming Soon', + }, + fr: { + 'nav.home': 'Accueil', + 'nav.features': 'Fonctionnalités', + 'nav.pricing': 'Tarifs', + 'nav.about': 'À propos', + 'nav.contact': 'Contact', + 'nav.login': 'Connexion', + 'nav.signup': "S'inscrire", + 'button.getStarted': 'Commencer', + 'button.learnMore': 'En savoir plus', + 'button.tryFree': 'Essai gratuit', + 'button.signUp': "S'inscrire", + 'button.login': 'Connexion', + 'button.back': 'Retour', + 'button.submit': 'Envoyer', + 'button.cancel': 'Annuler', + 'legal.privacy': 'Confidentialité', + 'legal.terms': "Conditions d'utilisation", + 'legal.cookies': 'Politique de cookies', + 'legal.imprint': 'Mentions légales', + 'legal.backHome': "Retour à l'accueil", + 'legal.lastUpdated': 'Dernière mise à jour', + 'footer.product': 'Produit', + 'footer.company': 'Entreprise', + 'footer.resources': 'Ressources', + 'footer.legal': 'Mentions légales', + 'footer.copyright': 'Tous droits réservés.', + 'common.loading': 'Chargement...', + 'common.error': 'Erreur', + 'common.success': 'Succès', + 'common.new': 'Nouveau', + 'common.comingSoon': 'Bientôt disponible', + }, + it: { + 'nav.home': 'Home', + 'nav.features': 'Funzionalità', + 'nav.pricing': 'Prezzi', + 'nav.about': 'Chi siamo', + 'nav.contact': 'Contatti', + 'nav.login': 'Accedi', + 'nav.signup': 'Registrati', + 'button.getStarted': 'Inizia', + 'button.learnMore': 'Scopri di più', + 'button.tryFree': 'Prova gratuita', + 'button.signUp': 'Registrati', + 'button.login': 'Accedi', + 'button.back': 'Indietro', + 'button.submit': 'Invia', + 'button.cancel': 'Annulla', + 'legal.privacy': 'Privacy', + 'legal.terms': 'Termini di servizio', + 'legal.cookies': 'Cookie Policy', + 'legal.imprint': 'Imprint', + 'legal.backHome': 'Torna alla home', + 'legal.lastUpdated': 'Ultimo aggiornamento', + 'footer.product': 'Prodotto', + 'footer.company': 'Azienda', + 'footer.resources': 'Risorse', + 'footer.legal': 'Legale', + 'footer.copyright': 'Tutti i diritti riservati.', + 'common.loading': 'Caricamento...', + 'common.error': 'Errore', + 'common.success': 'Successo', + 'common.new': 'Nuovo', + 'common.comingSoon': 'Prossimamente', + }, + es: { + 'nav.home': 'Inicio', + 'nav.features': 'Características', + 'nav.pricing': 'Precios', + 'nav.about': 'Nosotros', + 'nav.contact': 'Contacto', + 'nav.login': 'Iniciar sesión', + 'nav.signup': 'Registrarse', + 'button.getStarted': 'Empezar', + 'button.learnMore': 'Saber más', + 'button.tryFree': 'Prueba gratis', + 'button.signUp': 'Registrarse', + 'button.login': 'Iniciar sesión', + 'button.back': 'Atrás', + 'button.submit': 'Enviar', + 'button.cancel': 'Cancelar', + 'legal.privacy': 'Privacidad', + 'legal.terms': 'Términos de servicio', + 'legal.cookies': 'Política de cookies', + 'legal.imprint': 'Aviso legal', + 'legal.backHome': 'Volver al inicio', + 'legal.lastUpdated': 'Última actualización', + 'footer.product': 'Producto', + 'footer.company': 'Empresa', + 'footer.resources': 'Recursos', + 'footer.legal': 'Legal', + 'footer.copyright': 'Todos los derechos reservados.', + 'common.loading': 'Cargando...', + 'common.error': 'Error', + 'common.success': 'Éxito', + 'common.new': 'Nuevo', + 'common.comingSoon': 'Próximamente', + }, +}; diff --git a/packages/shared-landing-ui/src/index.ts b/packages/shared-landing-ui/src/index.ts index 70ee41d9b..1c50d176b 100644 --- a/packages/shared-landing-ui/src/index.ts +++ b/packages/shared-landing-ui/src/index.ts @@ -8,8 +8,42 @@ * * ```astro * --- + * // Atoms * import Button from '@manacore/shared-landing-ui/atoms/Button.astro'; + * import Badge from '@manacore/shared-landing-ui/atoms/Badge.astro'; + * import Card from '@manacore/shared-landing-ui/atoms/Card.astro'; + * import Container from '@manacore/shared-landing-ui/atoms/Container.astro'; + * import SectionHeader from '@manacore/shared-landing-ui/atoms/SectionHeader.astro'; + * import GradientText from '@manacore/shared-landing-ui/atoms/GradientText.astro'; + * import LanguageSwitcher from '@manacore/shared-landing-ui/atoms/LanguageSwitcher.astro'; + * + * // Sections * import HeroSection from '@manacore/shared-landing-ui/sections/HeroSection.astro'; + * import FeatureSection from '@manacore/shared-landing-ui/sections/FeatureSection.astro'; + * import PricingSection from '@manacore/shared-landing-ui/sections/PricingSection.astro'; + * import FAQSection from '@manacore/shared-landing-ui/sections/FAQSection.astro'; + * import CTASection from '@manacore/shared-landing-ui/sections/CTASection.astro'; + * import TestimonialSection from '@manacore/shared-landing-ui/sections/TestimonialSection.astro'; + * import StepsSection from '@manacore/shared-landing-ui/sections/StepsSection.astro'; + * import AppScrollerSection from '@manacore/shared-landing-ui/sections/AppScrollerSection.astro'; + * import TimelineSection from '@manacore/shared-landing-ui/sections/TimelineSection.astro'; + * import MasonryGridSection from '@manacore/shared-landing-ui/sections/MasonryGridSection.astro'; + * import PrinciplesSection from '@manacore/shared-landing-ui/sections/PrinciplesSection.astro'; + * + * // Layouts + * import Footer from '@manacore/shared-landing-ui/layouts/Footer.astro'; + * import Navigation from '@manacore/shared-landing-ui/layouts/Navigation.astro'; + * + * // Templates + * import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro'; + * + * // i18n + * import { getLangFromUrl, useTranslations, localizePath } from '@manacore/shared-landing-ui/i18n'; + * + * // Themes (import as CSS) + * import '@manacore/shared-landing-ui/themes'; + * import '@manacore/shared-landing-ui/themes/manacore'; + * import '@manacore/shared-landing-ui/themes/picture'; * --- * ``` * @@ -18,3 +52,4 @@ */ export * from './utils/index'; +export * from './i18n/index'; diff --git a/packages/shared-landing-ui/src/layouts/Navigation.astro b/packages/shared-landing-ui/src/layouts/Navigation.astro new file mode 100644 index 000000000..444e546ab --- /dev/null +++ b/packages/shared-landing-ui/src/layouts/Navigation.astro @@ -0,0 +1,510 @@ +--- +/** + * Navigation - Shared header navigation component + * + * Usage: + * ```astro + * + * ``` + */ + +export interface NavLink { + label: string; + href: string; + external?: boolean; +} + +export interface Brand { + name: string; + logo?: string; + href?: string; +} + +export interface CtaButton { + text: string; + href: string; +} + +interface Props { + brand: Brand; + links?: NavLink[]; + ctaButton?: CtaButton; + showLanguageSwitcher?: boolean; + currentLang?: string; + languages?: Record; + getLocalizedPath?: (lang: string) => string; + class?: string; +} + +const { + brand, + links = [], + ctaButton, + showLanguageSwitcher = false, + currentLang = 'en', + languages = {}, + getLocalizedPath, + class: className = '', +} = Astro.props; +--- + +
+ + + + +
+ + + + diff --git a/packages/shared-landing-ui/src/sections/AppScrollerSection.astro b/packages/shared-landing-ui/src/sections/AppScrollerSection.astro new file mode 100644 index 000000000..04f72b860 --- /dev/null +++ b/packages/shared-landing-ui/src/sections/AppScrollerSection.astro @@ -0,0 +1,475 @@ +--- +/** + * AppScrollerSection - Horizontal scrolling app showcase + * + * Usage: + * ```astro + * + * ``` + */ + +export interface App { + name: string; + description: string; + logo: string; // URL starting with '/' or emoji string + category: string; + color: string; // Tailwind gradient classes e.g. 'from-blue-500 to-cyan-500' + href: string; +} + +interface Props { + title: string; + titleHighlight?: string; + subtitle?: string; + apps: App[]; + scrollHint?: string; + learnMoreText?: string; + class?: string; +} + +const { + title, + titleHighlight, + subtitle, + apps, + scrollHint, + learnMoreText = 'Learn more', + class: className = '', +} = Astro.props; +--- + +
+
+
+

+ {title} + {titleHighlight && {titleHighlight}} +

+ {subtitle &&

{subtitle}

} +
+ + +
+ + diff --git a/packages/shared-landing-ui/src/sections/MasonryGridSection.astro b/packages/shared-landing-ui/src/sections/MasonryGridSection.astro new file mode 100644 index 000000000..5e66a39dd --- /dev/null +++ b/packages/shared-landing-ui/src/sections/MasonryGridSection.astro @@ -0,0 +1,235 @@ +--- +/** + * MasonryGridSection - Grid layout with variable sized cards + * + * Usage: + * ```astro + * + * ``` + */ + +export interface MasonryItem { + number?: string; + title: string; + text: string; + size?: 'small' | 'medium' | 'large'; +} + +interface Props { + title: string; + subtitle?: string; + items: MasonryItem[]; + class?: string; +} + +const { title, subtitle, items, class: className = '' } = Astro.props; +--- + +
+
+ +
+
+

{title}

+ {subtitle &&

{subtitle}

} +
+ +
+ { + items.map((item) => ( +
+
+ {item.number && {item.number}} +

{item.title}

+

{item.text}

+
+
+ )) + } +
+
+
+ + diff --git a/packages/shared-landing-ui/src/sections/PrinciplesSection.astro b/packages/shared-landing-ui/src/sections/PrinciplesSection.astro new file mode 100644 index 000000000..d68ac08c1 --- /dev/null +++ b/packages/shared-landing-ui/src/sections/PrinciplesSection.astro @@ -0,0 +1,280 @@ +--- +/** + * PrinciplesSection - Horizontal cards with icons + * + * Usage: + * ```astro + * + * ``` + */ + +export interface Principle { + icon: + | 'lightning' + | 'chat' + | 'globe' + | 'heart' + | 'shield' + | 'star' + | 'code' + | 'users' + | 'rocket' + | 'check'; + title: string; + description: string; +} + +interface Props { + principles: Principle[]; + class?: string; +} + +const { principles, class: className = '' } = Astro.props; + +// SVG paths for icons +const iconPaths: Record = { + lightning: 'M13 10V3L4 14h7v7l9-11h-7z', + chat: 'M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z', + globe: + 'M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z', + heart: + 'M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z', + shield: + 'M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z', + star: 'M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z', + code: 'M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4', + users: + 'M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z', + rocket: + 'M15.59 14.37a6 6 0 01-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 006.16-12.12A14.98 14.98 0 009.631 8.41m5.96 5.96a14.926 14.926 0 01-5.841 2.58m-.119-8.54a6 6 0 00-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 00-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 01-2.448-2.448 14.9 14.9 0 01.06-.312m-2.24 2.39a4.493 4.493 0 00-1.757 4.306 4.493 4.493 0 004.306-1.758M16.5 9a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z', + check: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z', +}; +--- + +
+
+ +
+
+ { + principles.map((principle) => ( +
+
+
+ + + +
+
+

{principle.title}

+

{principle.description}

+
+
+
+ )) + } +
+
+
+ + diff --git a/packages/shared-landing-ui/src/sections/TimelineSection.astro b/packages/shared-landing-ui/src/sections/TimelineSection.astro new file mode 100644 index 000000000..c8e958bc0 --- /dev/null +++ b/packages/shared-landing-ui/src/sections/TimelineSection.astro @@ -0,0 +1,286 @@ +--- +/** + * TimelineSection - Alternating timeline layout + * + * Usage: + * ```astro + * + * ``` + */ + +export interface TimelineItem { + badge: string; + title: string; + text: string; +} + +interface Props { + title: string; + subtitle?: string; + items: TimelineItem[]; + class?: string; +} + +const { title, subtitle, items, class: className = '' } = Astro.props; +--- + +
+
+ +
+
+

{title}

+ {subtitle &&

{subtitle}

} +
+ +
+ { + items.map((item, index) => ( +
+
+
+ {item.badge} +

{item.title}

+

{item.text}

+
+
+ )) + } +
+
+
+ + diff --git a/packages/shared-landing-ui/src/templates/LegalPageTemplate.astro b/packages/shared-landing-ui/src/templates/LegalPageTemplate.astro new file mode 100644 index 000000000..c3c813738 --- /dev/null +++ b/packages/shared-landing-ui/src/templates/LegalPageTemplate.astro @@ -0,0 +1,225 @@ +--- +/** + * LegalPageTemplate - Base template for legal pages (Privacy, Terms, Cookies, Imprint) + * + * Usage: + * ```astro + * + *
+ * + * ``` + */ + +interface Props { + title: string; + backLink?: string; + backText?: string; + lastUpdatedText?: string; + lastUpdated?: Date; + class?: string; +} + +const { + title, + backLink = '/', + backText = 'Back to Home', + lastUpdatedText = 'Last Updated', + lastUpdated = new Date(), + class: className = '', +} = Astro.props; +--- + +
+ +
+ + diff --git a/packages/shared-landing-ui/src/themes/chat.css b/packages/shared-landing-ui/src/themes/chat.css new file mode 100644 index 000000000..36982aad2 --- /dev/null +++ b/packages/shared-landing-ui/src/themes/chat.css @@ -0,0 +1,80 @@ +/** + * Chat Theme - Blue + * AI chat application + */ +:root { + /* Primary colors - Vibrant Blue */ + --color-primary: #0ea5e9; + --color-primary-hover: #0284c7; + --color-primary-glow: rgba(14, 165, 233, 0.3); + + /* Text colors */ + --color-text-primary: #f8fafc; + --color-text-secondary: #cbd5e1; + --color-text-muted: #64748b; + + /* Background colors - Dark slate */ + --color-background-page: #0f172a; + --color-background-card: #1e293b; + --color-background-card-hover: #334155; + + /* Border colors */ + --color-border: rgba(14, 165, 233, 0.2); + --color-border-hover: rgba(14, 165, 233, 0.4); +} + +/* Light mode support */ +@media (prefers-color-scheme: light) { + :root { + --color-primary: #0284c7; + --color-primary-hover: #0369a1; + --color-primary-glow: rgba(2, 132, 199, 0.2); + + --color-text-primary: #0c4a6e; + --color-text-secondary: #0369a1; + --color-text-muted: #0ea5e9; + + --color-background-page: #f0f9ff; + --color-background-card: #ffffff; + --color-background-card-hover: #e0f2fe; + + --color-border: #bae6fd; + --color-border-hover: #7dd3fc; + } +} + +/* Force dark mode class */ +.dark { + --color-primary: #0ea5e9; + --color-primary-hover: #38bdf8; + --color-primary-glow: rgba(14, 165, 233, 0.3); + + --color-text-primary: #f8fafc; + --color-text-secondary: #cbd5e1; + --color-text-muted: #64748b; + + --color-background-page: #0f172a; + --color-background-card: #1e293b; + --color-background-card-hover: #334155; + + --color-border: rgba(14, 165, 233, 0.2); + --color-border-hover: rgba(14, 165, 233, 0.4); +} + +/* Force light mode class */ +.light { + --color-primary: #0284c7; + --color-primary-hover: #0369a1; + --color-primary-glow: rgba(2, 132, 199, 0.2); + + --color-text-primary: #0c4a6e; + --color-text-secondary: #0369a1; + --color-text-muted: #0ea5e9; + + --color-background-page: #f0f9ff; + --color-background-card: #ffffff; + --color-background-card-hover: #e0f2fe; + + --color-border: #bae6fd; + --color-border-hover: #7dd3fc; +} diff --git a/packages/shared-landing-ui/src/themes/picture.css b/packages/shared-landing-ui/src/themes/picture.css new file mode 100644 index 000000000..c9e527ff0 --- /dev/null +++ b/packages/shared-landing-ui/src/themes/picture.css @@ -0,0 +1,80 @@ +/** + * Picture Theme - Dark Indigo + * AI image generation app + */ +:root { + /* Primary colors - Indigo/Purple */ + --color-primary: #6366f1; + --color-primary-hover: #4f46e5; + --color-primary-glow: rgba(99, 102, 241, 0.3); + + /* Text colors */ + --color-text-primary: #f8fafc; + --color-text-secondary: #cbd5e1; + --color-text-muted: #64748b; + + /* Background colors - Deep dark */ + --color-background-page: #0c0a1d; + --color-background-card: #1a1833; + --color-background-card-hover: #252345; + + /* Border colors */ + --color-border: rgba(99, 102, 241, 0.2); + --color-border-hover: rgba(99, 102, 241, 0.4); +} + +/* Light mode support */ +@media (prefers-color-scheme: light) { + :root { + --color-primary: #4f46e5; + --color-primary-hover: #4338ca; + --color-primary-glow: rgba(79, 70, 229, 0.2); + + --color-text-primary: #1e1b4b; + --color-text-secondary: #4338ca; + --color-text-muted: #6366f1; + + --color-background-page: #fafafa; + --color-background-card: #ffffff; + --color-background-card-hover: #f5f3ff; + + --color-border: #e0e7ff; + --color-border-hover: #c7d2fe; + } +} + +/* Force dark mode class */ +.dark { + --color-primary: #6366f1; + --color-primary-hover: #818cf8; + --color-primary-glow: rgba(99, 102, 241, 0.3); + + --color-text-primary: #f8fafc; + --color-text-secondary: #cbd5e1; + --color-text-muted: #64748b; + + --color-background-page: #0c0a1d; + --color-background-card: #1a1833; + --color-background-card-hover: #252345; + + --color-border: rgba(99, 102, 241, 0.2); + --color-border-hover: rgba(99, 102, 241, 0.4); +} + +/* Force light mode class */ +.light { + --color-primary: #4f46e5; + --color-primary-hover: #4338ca; + --color-primary-glow: rgba(79, 70, 229, 0.2); + + --color-text-primary: #1e1b4b; + --color-text-secondary: #4338ca; + --color-text-muted: #6366f1; + + --color-background-page: #fafafa; + --color-background-card: #ffffff; + --color-background-card-hover: #f5f3ff; + + --color-border: #e0e7ff; + --color-border-hover: #c7d2fe; +} diff --git a/packages/shared-landing-ui/src/themes/zitare.css b/packages/shared-landing-ui/src/themes/zitare.css new file mode 100644 index 000000000..101141fa0 --- /dev/null +++ b/packages/shared-landing-ui/src/themes/zitare.css @@ -0,0 +1,80 @@ +/** + * Zitare Theme - Green/Teal + * Daily inspiration quotes app + */ +:root { + /* Primary colors - Teal/Emerald */ + --color-primary: #14b8a6; + --color-primary-hover: #0d9488; + --color-primary-glow: rgba(20, 184, 166, 0.3); + + /* Text colors */ + --color-text-primary: #f8fafc; + --color-text-secondary: #cbd5e1; + --color-text-muted: #64748b; + + /* Background colors - Dark with teal tint */ + --color-background-page: #0a1a18; + --color-background-card: #132d2a; + --color-background-card-hover: #1a3f3b; + + /* Border colors */ + --color-border: rgba(20, 184, 166, 0.2); + --color-border-hover: rgba(20, 184, 166, 0.4); +} + +/* Light mode support */ +@media (prefers-color-scheme: light) { + :root { + --color-primary: #0d9488; + --color-primary-hover: #0f766e; + --color-primary-glow: rgba(13, 148, 136, 0.2); + + --color-text-primary: #134e4a; + --color-text-secondary: #0f766e; + --color-text-muted: #14b8a6; + + --color-background-page: #f0fdfa; + --color-background-card: #ffffff; + --color-background-card-hover: #ccfbf1; + + --color-border: #99f6e4; + --color-border-hover: #5eead4; + } +} + +/* Force dark mode class */ +.dark { + --color-primary: #14b8a6; + --color-primary-hover: #2dd4bf; + --color-primary-glow: rgba(20, 184, 166, 0.3); + + --color-text-primary: #f8fafc; + --color-text-secondary: #cbd5e1; + --color-text-muted: #64748b; + + --color-background-page: #0a1a18; + --color-background-card: #132d2a; + --color-background-card-hover: #1a3f3b; + + --color-border: rgba(20, 184, 166, 0.2); + --color-border-hover: rgba(20, 184, 166, 0.4); +} + +/* Force light mode class */ +.light { + --color-primary: #0d9488; + --color-primary-hover: #0f766e; + --color-primary-glow: rgba(13, 148, 136, 0.2); + + --color-text-primary: #134e4a; + --color-text-secondary: #0f766e; + --color-text-muted: #14b8a6; + + --color-background-page: #f0fdfa; + --color-background-card: #ffffff; + --color-background-card-hover: #ccfbf1; + + --color-border: #99f6e4; + --color-border-hover: #5eead4; +}